diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2018-10-10 14:13:15 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2018-10-10 14:13:15 +0200 |
| commit | 4378f977c385f475826b9680ae4c705e5ebff910 (patch) | |
| tree | 175f671a01bb794f49ba6d8b2e1af4c8e26a732a | |
| parent | a64c4fa7e1913fe14124190086d0d5624445c808 (diff) | |
deploy
| -rw-r--r-- | bundle.js | 5503 | ||||
| -rw-r--r-- | bundle.js.map | 2 | ||||
| -rw-r--r-- | client/index.js | 4 | ||||
| -rw-r--r-- | client/lib/midi.js | 13 | ||||
| -rw-r--r-- | dist/index.js | 46284 | ||||
| -rw-r--r-- | index.html | 2 | ||||
| -rw-r--r-- | package-lock.json | 826 | ||||
| -rw-r--r-- | package.json | 10 | ||||
| -rw-r--r-- | webpack.config.dev.js | 63 | ||||
| -rw-r--r-- | webpack.config.prod.js | 46 |
10 files changed, 49881 insertions, 2872 deletions
@@ -63,15 +63,22 @@ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 76); +/******/ return __webpack_require__(__webpack_require__.s = 80); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ +/***/ (function(module, exports) { + +var core = module.exports = {version: '2.4.0'}; +if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef + +/***/ }), +/* 1 */ /***/ (function(module, exports, __webpack_require__) { -var store = __webpack_require__(39)('wks') - , uid = __webpack_require__(27) +var store = __webpack_require__(40)('wks') + , uid = __webpack_require__(29) , Symbol = __webpack_require__(2).Symbol , USE_SYMBOL = typeof Symbol == 'function'; @@ -83,13 +90,6 @@ var $exports = module.exports = function(name){ $exports.store = store; /***/ }), -/* 1 */ -/***/ (function(module, exports) { - -var core = module.exports = {version: '2.4.0'}; -if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef - -/***/ }), /* 2 */ /***/ (function(module, exports) { @@ -113,9 +113,9 @@ if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef -var base64 = __webpack_require__(88) -var ieee754 = __webpack_require__(134) -var isArray = __webpack_require__(65) +var base64 = __webpack_require__(92) +var ieee754 = __webpack_require__(139) +var isArray = __webpack_require__(71) exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer @@ -1893,13 +1893,13 @@ function isnan (val) { return val !== val // eslint-disable-line no-self-compare } -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(20))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(23))) /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { -var isObject = __webpack_require__(18); +var isObject = __webpack_require__(19); module.exports = function(it){ if(!isObject(it))throw TypeError(it + ' is not an object!'); return it; @@ -1909,13 +1909,100 @@ module.exports = function(it){ /* 5 */ /***/ (function(module, exports, __webpack_require__) { +var anObject = __webpack_require__(4) + , IE8_DOM_DEFINE = __webpack_require__(59) + , toPrimitive = __webpack_require__(43) + , dP = Object.defineProperty; + +exports.f = __webpack_require__(6) ? Object.defineProperty : function defineProperty(O, P, Attributes){ + anObject(O); + P = toPrimitive(P, true); + anObject(Attributes); + if(IE8_DOM_DEFINE)try { + return dP(O, P, Attributes); + } catch(e){ /* empty */ } + if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!'); + if('value' in Attributes)O[P] = Attributes.value; + return O; +}; + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + // Thank's IE8 for his funny defineProperty module.exports = !__webpack_require__(13)(function(){ return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7; }); /***/ }), -/* 6 */ +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +var global = __webpack_require__(2) + , core = __webpack_require__(0) + , ctx = __webpack_require__(18) + , hide = __webpack_require__(9) + , PROTOTYPE = 'prototype'; + +var $export = function(type, name, source){ + var IS_FORCED = type & $export.F + , IS_GLOBAL = type & $export.G + , IS_STATIC = type & $export.S + , IS_PROTO = type & $export.P + , IS_BIND = type & $export.B + , IS_WRAP = type & $export.W + , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) + , expProto = exports[PROTOTYPE] + , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] + , key, own, out; + if(IS_GLOBAL)source = name; + for(key in source){ + // contains in native + own = !IS_FORCED && target && target[key] !== undefined; + if(own && key in exports)continue; + // export native or passed + out = own ? target[key] : source[key]; + // prevent global pollution for namespaces + exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] + // bind timers to global for call from export context + : IS_BIND && own ? ctx(out, global) + // wrap global constructors for prevent change them in library + : IS_WRAP && target[key] == out ? (function(C){ + var F = function(a, b, c){ + if(this instanceof C){ + switch(arguments.length){ + case 0: return new C; + case 1: return new C(a); + case 2: return new C(a, b); + } return new C(a, b, c); + } return C.apply(this, arguments); + }; + F[PROTOTYPE] = C[PROTOTYPE]; + return F; + // make static versions for prototype methods + })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; + // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% + if(IS_PROTO){ + (exports.virtual || (exports.virtual = {}))[key] = out; + // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% + if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out); + } + } +}; +// type bitmap +$export.F = 1; // forced +$export.G = 2; // global +$export.S = 4; // static +$export.P = 8; // proto +$export.B = 16; // bind +$export.W = 32; // wrap +$export.U = 64; // safe +$export.R = 128; // real proto method for `library` +module.exports = $export; + +/***/ }), +/* 8 */ /***/ (function(module, exports) { var hasOwnProperty = {}.hasOwnProperty; @@ -1924,12 +2011,12 @@ module.exports = function(it, key){ }; /***/ }), -/* 7 */ +/* 9 */ /***/ (function(module, exports, __webpack_require__) { -var dP = __webpack_require__(8) - , createDesc = __webpack_require__(25); -module.exports = __webpack_require__(5) ? function(object, key, value){ +var dP = __webpack_require__(5) + , createDesc = __webpack_require__(20); +module.exports = __webpack_require__(6) ? function(object, key, value){ return dP.f(object, key, createDesc(1, value)); } : function(object, key, value){ object[key] = value; @@ -1937,39 +2024,18 @@ module.exports = __webpack_require__(5) ? function(object, key, value){ }; /***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -var anObject = __webpack_require__(4) - , IE8_DOM_DEFINE = __webpack_require__(54) - , toPrimitive = __webpack_require__(42) - , dP = Object.defineProperty; - -exports.f = __webpack_require__(5) ? Object.defineProperty : function defineProperty(O, P, Attributes){ - anObject(O); - P = toPrimitive(P, true); - anObject(Attributes); - if(IE8_DOM_DEFINE)try { - return dP(O, P, Attributes); - } catch(e){ /* empty */ } - if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!'); - if('value' in Attributes)O[P] = Attributes.value; - return O; -}; - -/***/ }), -/* 9 */ +/* 10 */ /***/ (function(module, exports, __webpack_require__) { // to indexed object, toObject with fallback for non-array-like ES3 strings -var IObject = __webpack_require__(55) - , defined = __webpack_require__(34); +var IObject = __webpack_require__(60) + , defined = __webpack_require__(35); module.exports = function(it){ return IObject(defined(it)); }; /***/ }), -/* 10 */ +/* 11 */ /***/ (function(module, exports) { // shim for using process in browser @@ -2155,7 +2221,7 @@ process.umask = function() { return 0; }; /***/ }), -/* 11 */ +/* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -2179,16 +2245,16 @@ var objectKeys = Object.keys || function (obj) { module.exports = Duplex; /*<replacement>*/ -var processNextTick = __webpack_require__(47); +var processNextTick = __webpack_require__(49); /*</replacement>*/ /*<replacement>*/ -var util = __webpack_require__(19); +var util = __webpack_require__(22); util.inherits = __webpack_require__(16); /*</replacement>*/ -var Readable = __webpack_require__(66); -var Writable = __webpack_require__(48); +var Readable = __webpack_require__(72); +var Writable = __webpack_require__(50); util.inherits(Duplex, Readable); @@ -2236,72 +2302,6 @@ function forEach(xs, f) { } /***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { - -var global = __webpack_require__(2) - , core = __webpack_require__(1) - , ctx = __webpack_require__(22) - , hide = __webpack_require__(7) - , PROTOTYPE = 'prototype'; - -var $export = function(type, name, source){ - var IS_FORCED = type & $export.F - , IS_GLOBAL = type & $export.G - , IS_STATIC = type & $export.S - , IS_PROTO = type & $export.P - , IS_BIND = type & $export.B - , IS_WRAP = type & $export.W - , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) - , expProto = exports[PROTOTYPE] - , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] - , key, own, out; - if(IS_GLOBAL)source = name; - for(key in source){ - // contains in native - own = !IS_FORCED && target && target[key] !== undefined; - if(own && key in exports)continue; - // export native or passed - out = own ? target[key] : source[key]; - // prevent global pollution for namespaces - exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] - // bind timers to global for call from export context - : IS_BIND && own ? ctx(out, global) - // wrap global constructors for prevent change them in library - : IS_WRAP && target[key] == out ? (function(C){ - var F = function(a, b, c){ - if(this instanceof C){ - switch(arguments.length){ - case 0: return new C; - case 1: return new C(a); - case 2: return new C(a, b); - } return new C(a, b, c); - } return C.apply(this, arguments); - }; - F[PROTOTYPE] = C[PROTOTYPE]; - return F; - // make static versions for prototype methods - })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; - // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% - if(IS_PROTO){ - (exports.virtual || (exports.virtual = {}))[key] = out; - // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% - if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out); - } - } -}; -// type bitmap -$export.F = 1; // forced -$export.G = 2; // global -$export.S = 4; // static -$export.P = 8; // proto -$export.B = 16; // bind -$export.W = 32; // wrap -$export.U = 64; // safe -$export.R = 128; // real proto method for `library` -module.exports = $export; - -/***/ }), /* 13 */ /***/ (function(module, exports) { @@ -2324,8 +2324,8 @@ module.exports = {}; /***/ (function(module, exports, __webpack_require__) { // 19.1.2.14 / 15.2.3.14 Object.keys(O) -var $keys = __webpack_require__(59) - , enumBugKeys = __webpack_require__(36); +var $keys = __webpack_require__(67) + , enumBugKeys = __webpack_require__(37); module.exports = Object.keys || function keys(O){ return $keys(O, enumBugKeys); @@ -2372,6 +2372,31 @@ module.exports = function(it){ /***/ }), /* 18 */ +/***/ (function(module, exports, __webpack_require__) { + +// optional / simple context binding +var aFunction = __webpack_require__(33); +module.exports = function(fn, that, length){ + aFunction(fn); + if(that === undefined)return fn; + switch(length){ + case 1: return function(a){ + return fn.call(that, a); + }; + case 2: return function(a, b){ + return fn.call(that, a, b); + }; + case 3: return function(a, b, c){ + return fn.call(that, a, b, c); + }; + } + return function(/* ...args */){ + return fn.apply(that, arguments); + }; +}; + +/***/ }), +/* 19 */ /***/ (function(module, exports) { module.exports = function(it){ @@ -2379,7 +2404,43 @@ module.exports = function(it){ }; /***/ }), -/* 19 */ +/* 20 */ +/***/ (function(module, exports) { + +module.exports = function(bitmap, value){ + return { + enumerable : !(bitmap & 1), + configurable: !(bitmap & 2), + writable : !(bitmap & 4), + value : value + }; +}; + +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $at = __webpack_require__(124)(true); + +// 21.1.3.27 String.prototype[@@iterator]() +__webpack_require__(63)(String, 'String', function(iterated){ + this._t = String(iterated); // target + this._i = 0; // next index +// 21.1.5.2.1 %StringIteratorPrototype%.next() +}, function(){ + var O = this._t + , index = this._i + , point; + if(index >= O.length)return {value: undefined, done: true}; + point = $at(O, index); + this._i += point.length; + return {value: point, done: false}; +}); + +/***/ }), +/* 22 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors. @@ -2493,7 +2554,7 @@ function objectToString(o) { /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3).Buffer)) /***/ }), -/* 20 */ +/* 23 */ /***/ (function(module, exports) { var g;
@@ -2520,7 +2581,7 @@ module.exports = g; /***/ }), -/* 21 */ +/* 24 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;(function(root, factory){ @@ -26908,69 +26969,41 @@ var __WEBPACK_AMD_DEFINE_RESULT__;(function(root, factory){ })); /***/ }), -/* 22 */ -/***/ (function(module, exports, __webpack_require__) { - -// optional / simple context binding -var aFunction = __webpack_require__(32); -module.exports = function(fn, that, length){ - aFunction(fn); - if(that === undefined)return fn; - switch(length){ - case 1: return function(a){ - return fn.call(that, a); - }; - case 2: return function(a, b){ - return fn.call(that, a, b); - }; - case 3: return function(a, b, c){ - return fn.call(that, a, b, c); - }; - } - return function(/* ...args */){ - return fn.apply(that, arguments); - }; -}; - -/***/ }), -/* 23 */ +/* 25 */ /***/ (function(module, exports) { module.exports = true; /***/ }), -/* 24 */ +/* 26 */ /***/ (function(module, exports) { exports.f = {}.propertyIsEnumerable; /***/ }), -/* 25 */ -/***/ (function(module, exports) { +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = function(bitmap, value){ - return { - enumerable : !(bitmap & 1), - configurable: !(bitmap & 2), - writable : !(bitmap & 4), - value : value - }; +var def = __webpack_require__(5).f + , has = __webpack_require__(8) + , TAG = __webpack_require__(1)('toStringTag'); + +module.exports = function(it, tag, stat){ + if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag}); }; /***/ }), -/* 26 */ +/* 28 */ /***/ (function(module, exports, __webpack_require__) { -var def = __webpack_require__(8).f - , has = __webpack_require__(6) - , TAG = __webpack_require__(0)('toStringTag'); - -module.exports = function(it, tag, stat){ - if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag}); +// 7.1.13 ToObject(argument) +var defined = __webpack_require__(35); +module.exports = function(it){ + return Object(defined(it)); }; /***/ }), -/* 27 */ +/* 29 */ /***/ (function(module, exports) { var id = 0 @@ -26980,37 +27013,14 @@ module.exports = function(key){ }; /***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var $at = __webpack_require__(121)(true); - -// 21.1.3.27 String.prototype[@@iterator]() -__webpack_require__(56)(String, 'String', function(iterated){ - this._t = String(iterated); // target - this._i = 0; // next index -// 21.1.5.2.1 %StringIteratorPrototype%.next() -}, function(){ - var O = this._t - , index = this._i - , point; - if(index >= O.length)return {value: undefined, done: true}; - point = $at(O, index); - this._i += point.length; - return {value: point, done: false}; -}); - -/***/ }), -/* 29 */ +/* 30 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(125); +__webpack_require__(129); var global = __webpack_require__(2) - , hide = __webpack_require__(7) + , hide = __webpack_require__(9) , Iterators = __webpack_require__(14) - , TO_STRING_TAG = __webpack_require__(0)('toStringTag'); + , TO_STRING_TAG = __webpack_require__(1)('toStringTag'); for(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){ var NAME = collections[i] @@ -27021,7 +27031,7 @@ for(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList' } /***/ }), -/* 30 */ +/* 31 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -27032,11 +27042,11 @@ Object.defineProperty(exports, "__esModule", { }); exports.browser = exports.isDesktop = exports.isMobile = exports.isAndroid = exports.isIpad = exports.isIphone = undefined; -var _log = __webpack_require__(82); +var _log = __webpack_require__(86); var _log2 = _interopRequireDefault(_log); -var _assign = __webpack_require__(52); +var _assign = __webpack_require__(57); var _assign2 = _interopRequireDefault(_assign); @@ -27052,11 +27062,11 @@ exports.get_diff_bounds = get_diff_bounds; exports.get_bounds = get_bounds; exports.transpose = transpose; -var _tone = __webpack_require__(21); +var _tone = __webpack_require__(24); var _tone2 = _interopRequireDefault(_tone); -var _startAudioContext = __webpack_require__(79); +var _startAudioContext = __webpack_require__(82); var _startAudioContext2 = _interopRequireDefault(_startAudioContext); @@ -27210,7 +27220,7 @@ function transpose(a) { } /***/ }), -/* 31 */ +/* 32 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -27323,10 +27333,10 @@ exports.allocUnsafeSlow = function allocUnsafeSlow(size) { return new SlowBuffer(size); } -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(20))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(23))) /***/ }), -/* 32 */ +/* 33 */ /***/ (function(module, exports) { module.exports = function(it){ @@ -27335,12 +27345,12 @@ module.exports = function(it){ }; /***/ }), -/* 33 */ +/* 34 */ /***/ (function(module, exports, __webpack_require__) { // getting tag from 19.1.3.6 Object.prototype.toString() var cof = __webpack_require__(17) - , TAG = __webpack_require__(0)('toStringTag') + , TAG = __webpack_require__(1)('toStringTag') // ES3 wrong here , ARG = cof(function(){ return arguments; }()) == 'Arguments'; @@ -27363,7 +27373,7 @@ module.exports = function(it){ }; /***/ }), -/* 34 */ +/* 35 */ /***/ (function(module, exports) { // 7.2.1 RequireObjectCoercible(argument) @@ -27373,10 +27383,10 @@ module.exports = function(it){ }; /***/ }), -/* 35 */ +/* 36 */ /***/ (function(module, exports, __webpack_require__) { -var isObject = __webpack_require__(18) +var isObject = __webpack_require__(19) , document = __webpack_require__(2).document // in old IE typeof document.createElement is 'object' , is = isObject(document) && isObject(document.createElement); @@ -27385,7 +27395,7 @@ module.exports = function(it){ }; /***/ }), -/* 36 */ +/* 37 */ /***/ (function(module, exports) { // IE 8- don't enum bug keys @@ -27394,23 +27404,23 @@ module.exports = ( ).split(','); /***/ }), -/* 37 */ +/* 38 */ /***/ (function(module, exports) { exports.f = Object.getOwnPropertySymbols; /***/ }), -/* 38 */ +/* 39 */ /***/ (function(module, exports, __webpack_require__) { -var shared = __webpack_require__(39)('keys') - , uid = __webpack_require__(27); +var shared = __webpack_require__(40)('keys') + , uid = __webpack_require__(29); module.exports = function(key){ return shared[key] || (shared[key] = uid(key)); }; /***/ }), -/* 39 */ +/* 40 */ /***/ (function(module, exports, __webpack_require__) { var global = __webpack_require__(2) @@ -27421,7 +27431,7 @@ module.exports = function(key){ }; /***/ }), -/* 40 */ +/* 41 */ /***/ (function(module, exports) { // 7.1.4 ToInteger @@ -27432,21 +27442,22 @@ module.exports = function(it){ }; /***/ }), -/* 41 */ +/* 42 */ /***/ (function(module, exports, __webpack_require__) { -// 7.1.13 ToObject(argument) -var defined = __webpack_require__(34); +// 7.1.15 ToLength +var toInteger = __webpack_require__(41) + , min = Math.min; module.exports = function(it){ - return Object(defined(it)); + return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 }; /***/ }), -/* 42 */ +/* 43 */ /***/ (function(module, exports, __webpack_require__) { // 7.1.1 ToPrimitive(input [, PreferredType]) -var isObject = __webpack_require__(18); +var isObject = __webpack_require__(19); // instead of the ES6 spec version, we didn't implement @@toPrimitive case // and the second argument - flag - preferred type is a string module.exports = function(it, S){ @@ -27459,27 +27470,40 @@ module.exports = function(it, S){ }; /***/ }), -/* 43 */ +/* 44 */ /***/ (function(module, exports, __webpack_require__) { var global = __webpack_require__(2) - , core = __webpack_require__(1) - , LIBRARY = __webpack_require__(23) - , wksExt = __webpack_require__(44) - , defineProperty = __webpack_require__(8).f; + , core = __webpack_require__(0) + , LIBRARY = __webpack_require__(25) + , wksExt = __webpack_require__(45) + , defineProperty = __webpack_require__(5).f; module.exports = function(name){ var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {}); if(name.charAt(0) != '_' && !(name in $Symbol))defineProperty($Symbol, name, {value: wksExt.f(name)}); }; /***/ }), -/* 44 */ +/* 45 */ /***/ (function(module, exports, __webpack_require__) { -exports.f = __webpack_require__(0); +exports.f = __webpack_require__(1); /***/ }), -/* 45 */ +/* 46 */ +/***/ (function(module, exports, __webpack_require__) { + +var classof = __webpack_require__(34) + , ITERATOR = __webpack_require__(1)('iterator') + , Iterators = __webpack_require__(14); +module.exports = __webpack_require__(0).getIteratorMethod = function(it){ + if(it != undefined)return it[ITERATOR] + || it['@@iterator'] + || Iterators[classof(it)]; +}; + +/***/ }), +/* 47 */ /***/ (function(module, exports) { // Copyright Joyent, Inc. and other Node contributors. @@ -27787,7 +27811,7 @@ function isUndefined(arg) { /***/ }), -/* 46 */ +/* 48 */ /***/ (function(module, exports, __webpack_require__) { // Copyright Joyent, Inc. and other Node contributors. @@ -28014,7 +28038,7 @@ function base64DetectIncompleteChar(buffer) { /***/ }), -/* 47 */ +/* 49 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -28062,10 +28086,10 @@ function nextTick(fn, arg1, arg2, arg3) { } } -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(10))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(11))) /***/ }), -/* 48 */ +/* 50 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -28078,7 +28102,7 @@ function nextTick(fn, arg1, arg2, arg3) { module.exports = Writable; /*<replacement>*/ -var processNextTick = __webpack_require__(47); +var processNextTick = __webpack_require__(49); /*</replacement>*/ /*<replacement>*/ @@ -28092,23 +28116,23 @@ var Duplex; Writable.WritableState = WritableState; /*<replacement>*/ -var util = __webpack_require__(19); +var util = __webpack_require__(22); util.inherits = __webpack_require__(16); /*</replacement>*/ /*<replacement>*/ var internalUtil = { - deprecate: __webpack_require__(146) + deprecate: __webpack_require__(151) }; /*</replacement>*/ /*<replacement>*/ -var Stream = __webpack_require__(68); +var Stream = __webpack_require__(74); /*</replacement>*/ var Buffer = __webpack_require__(3).Buffer; /*<replacement>*/ -var bufferShim = __webpack_require__(31); +var bufferShim = __webpack_require__(32); /*</replacement>*/ util.inherits(Writable, Stream); @@ -28123,7 +28147,7 @@ function WriteReq(chunk, encoding, cb) { } function WritableState(options, stream) { - Duplex = Duplex || __webpack_require__(11); + Duplex = Duplex || __webpack_require__(12); options = options || {}; @@ -28257,7 +28281,7 @@ if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.protot } function Writable(options) { - Duplex = Duplex || __webpack_require__(11); + Duplex = Duplex || __webpack_require__(12); // Writable ctor is applied to Duplexes, too. // `realHasInstance` is necessary because using plain `instanceof` @@ -28613,23 +28637,85 @@ function CorkedRequest(state) { } }; } -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(10), __webpack_require__(69).setImmediate)) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(11), __webpack_require__(75).setImmediate)) /***/ }), -/* 49 */ +/* 51 */ /***/ (function(module, exports, __webpack_require__) { -exports = module.exports = __webpack_require__(66); +exports = module.exports = __webpack_require__(72); exports.Stream = exports; exports.Readable = exports; -exports.Writable = __webpack_require__(48); -exports.Duplex = __webpack_require__(11); -exports.Transform = __webpack_require__(67); -exports.PassThrough = __webpack_require__(138); +exports.Writable = __webpack_require__(50); +exports.Duplex = __webpack_require__(12); +exports.Transform = __webpack_require__(73); +exports.PassThrough = __webpack_require__(143); /***/ }), -/* 50 */ +/* 52 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _tone = __webpack_require__(24); + +var _tone2 = _interopRequireDefault(_tone); + +var _util = __webpack_require__(31); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var player_count = 2; +var sample_index = 0; + +var compressor = new _tone2.default.Compressor(-30, 3).toMaster(); + +var samples = [{ root: 226, fn: 'samples/380737__cabled-mess__sansula-01-a-raw.mp3' }, { root: 267, fn: 'samples/380736__cabled-mess__sansula-02-c-raw.mp3' }, { root: 340, fn: 'samples/380735__cabled-mess__sansula-03-e-raw.mp3' }, { root: 452, fn: 'samples/380733__cabled-mess__sansula-06-a-02-raw.mp3' }]; + +samples.forEach(function (sample) { + sample.players = []; + sample.index = -1; + for (var i = 0; i < player_count; i++) { + var fn = sample.fn; + if (window.location.href.match(/asdf.us/)) { + fn = '//asdf.us/kalimba/' + fn; + } + var player = new _tone2.default.Player({ + url: fn, + retrigger: true, + playbackRate: 1 + }); + player.connect(compressor); + sample.players.push(player); + } +}); + +function play(freq) { + var volume = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.0; + + var best = { sample: samples[sample_index] }; + sample_index = (sample_index + 1) % samples.length; + best.sample.index = (best.sample.index + 1) % player_count; + + var player = best.sample.players[best.sample.index]; + player.playbackRate = freq / best.sample.root; + // console.log(player) + player.volume.value = volume; + setTimeout(function () { + player.start(); + }, 0); +} + +exports.default = { play: play }; + +/***/ }), +/* 53 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -28639,7 +28725,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); -var _intonation = __webpack_require__(77); +var _intonation = __webpack_require__(81); var _intonation2 = _interopRequireDefault(_intonation); @@ -28762,7 +28848,7 @@ function names() { exports.default = { scales: scales, current: current, build: build, build_options: build_options, pick: pick, names: names, onChange: onChange }; /***/ }), -/* 51 */ +/* 54 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -28773,7 +28859,7 @@ Object.defineProperty(exports, "__esModule", { }); exports.nx = undefined; -var _keys = __webpack_require__(83); +var _keys = __webpack_require__(87); var _keys2 = _interopRequireDefault(_keys); @@ -28781,7 +28867,7 @@ exports.update_value_on_change = update_value_on_change; exports.update_radio_value_on_change = update_radio_value_on_change; exports.build_options = build_options; -var _nexusui = __webpack_require__(75); +var _nexusui = __webpack_require__(56); var _nexusui2 = _interopRequireDefault(_nexusui); @@ -28837,1855 +28923,19 @@ function build_options(el, lists, fn) { } /***/ }), -/* 52 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = { "default": __webpack_require__(92), __esModule: true }; - -/***/ }), -/* 53 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(2).document && document.documentElement; - -/***/ }), -/* 54 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = !__webpack_require__(5) && !__webpack_require__(13)(function(){ - return Object.defineProperty(__webpack_require__(35)('div'), 'a', {get: function(){ return 7; }}).a != 7; -}); - -/***/ }), /* 55 */ /***/ (function(module, exports, __webpack_require__) { -// fallback for non-array-like ES3 and non-enumerable old V8 strings -var cof = __webpack_require__(17); -module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){ - return cof(it) == 'String' ? it.split('') : Object(it); -}; - -/***/ }), -/* 56 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var LIBRARY = __webpack_require__(23) - , $export = __webpack_require__(12) - , redefine = __webpack_require__(60) - , hide = __webpack_require__(7) - , has = __webpack_require__(6) - , Iterators = __webpack_require__(14) - , $iterCreate = __webpack_require__(106) - , setToStringTag = __webpack_require__(26) - , getPrototypeOf = __webpack_require__(116) - , ITERATOR = __webpack_require__(0)('iterator') - , BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next` - , FF_ITERATOR = '@@iterator' - , KEYS = 'keys' - , VALUES = 'values'; - -var returnThis = function(){ return this; }; - -module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){ - $iterCreate(Constructor, NAME, next); - var getMethod = function(kind){ - if(!BUGGY && kind in proto)return proto[kind]; - switch(kind){ - case KEYS: return function keys(){ return new Constructor(this, kind); }; - case VALUES: return function values(){ return new Constructor(this, kind); }; - } return function entries(){ return new Constructor(this, kind); }; - }; - var TAG = NAME + ' Iterator' - , DEF_VALUES = DEFAULT == VALUES - , VALUES_BUG = false - , proto = Base.prototype - , $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT] - , $default = $native || getMethod(DEFAULT) - , $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined - , $anyNative = NAME == 'Array' ? proto.entries || $native : $native - , methods, key, IteratorPrototype; - // Fix native - if($anyNative){ - IteratorPrototype = getPrototypeOf($anyNative.call(new Base)); - if(IteratorPrototype !== Object.prototype){ - // Set @@toStringTag to native iterators - setToStringTag(IteratorPrototype, TAG, true); - // fix for some old engines - if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis); - } - } - // fix Array#{values, @@iterator}.name in V8 / FF - if(DEF_VALUES && $native && $native.name !== VALUES){ - VALUES_BUG = true; - $default = function values(){ return $native.call(this); }; - } - // Define iterator - if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){ - hide(proto, ITERATOR, $default); - } - // Plug for library - Iterators[NAME] = $default; - Iterators[TAG] = returnThis; - if(DEFAULT){ - methods = { - values: DEF_VALUES ? $default : getMethod(VALUES), - keys: IS_SET ? $default : getMethod(KEYS), - entries: $entries - }; - if(FORCED)for(key in methods){ - if(!(key in proto))redefine(proto, key, methods[key]); - } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); - } - return methods; -}; - -/***/ }), -/* 57 */ -/***/ (function(module, exports, __webpack_require__) { - -// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) -var anObject = __webpack_require__(4) - , dPs = __webpack_require__(113) - , enumBugKeys = __webpack_require__(36) - , IE_PROTO = __webpack_require__(38)('IE_PROTO') - , Empty = function(){ /* empty */ } - , PROTOTYPE = 'prototype'; - -// Create object with fake `null` prototype: use iframe Object with cleared prototype -var createDict = function(){ - // Thrash, waste and sodomy: IE GC bug - var iframe = __webpack_require__(35)('iframe') - , i = enumBugKeys.length - , lt = '<' - , gt = '>' - , iframeDocument; - iframe.style.display = 'none'; - __webpack_require__(53).appendChild(iframe); - iframe.src = 'javascript:'; // eslint-disable-line no-script-url - // createDict = iframe.contentWindow.Object; - // html.removeChild(iframe); - iframeDocument = iframe.contentWindow.document; - iframeDocument.open(); - iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); - iframeDocument.close(); - createDict = iframeDocument.F; - while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]]; - return createDict(); -}; - -module.exports = Object.create || function create(O, Properties){ - var result; - if(O !== null){ - Empty[PROTOTYPE] = anObject(O); - result = new Empty; - Empty[PROTOTYPE] = null; - // add "__proto__" for Object.getPrototypeOf polyfill - result[IE_PROTO] = O; - } else result = createDict(); - return Properties === undefined ? result : dPs(result, Properties); -}; - - -/***/ }), -/* 58 */ -/***/ (function(module, exports, __webpack_require__) { - -// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O) -var $keys = __webpack_require__(59) - , hiddenKeys = __webpack_require__(36).concat('length', 'prototype'); - -exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O){ - return $keys(O, hiddenKeys); -}; - -/***/ }), -/* 59 */ -/***/ (function(module, exports, __webpack_require__) { - -var has = __webpack_require__(6) - , toIObject = __webpack_require__(9) - , arrayIndexOf = __webpack_require__(99)(false) - , IE_PROTO = __webpack_require__(38)('IE_PROTO'); - -module.exports = function(object, names){ - var O = toIObject(object) - , i = 0 - , result = [] - , key; - for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key); - // Don't enum bug & hidden keys - while(names.length > i)if(has(O, key = names[i++])){ - ~arrayIndexOf(result, key) || result.push(key); - } - return result; -}; - -/***/ }), -/* 60 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(7); - -/***/ }), -/* 61 */ -/***/ (function(module, exports, __webpack_require__) { - -var ctx = __webpack_require__(22) - , invoke = __webpack_require__(102) - , html = __webpack_require__(53) - , cel = __webpack_require__(35) - , global = __webpack_require__(2) - , process = global.process - , setTask = global.setImmediate - , clearTask = global.clearImmediate - , MessageChannel = global.MessageChannel - , counter = 0 - , queue = {} - , ONREADYSTATECHANGE = 'onreadystatechange' - , defer, channel, port; -var run = function(){ - var id = +this; - if(queue.hasOwnProperty(id)){ - var fn = queue[id]; - delete queue[id]; - fn(); - } -}; -var listener = function(event){ - run.call(event.data); -}; -// Node.js 0.9+ & IE10+ has setImmediate, otherwise: -if(!setTask || !clearTask){ - setTask = function setImmediate(fn){ - var args = [], i = 1; - while(arguments.length > i)args.push(arguments[i++]); - queue[++counter] = function(){ - invoke(typeof fn == 'function' ? fn : Function(fn), args); - }; - defer(counter); - return counter; - }; - clearTask = function clearImmediate(id){ - delete queue[id]; - }; - // Node.js 0.8- - if(__webpack_require__(17)(process) == 'process'){ - defer = function(id){ - process.nextTick(ctx(run, id, 1)); - }; - // Browsers with MessageChannel, includes WebWorkers - } else if(MessageChannel){ - channel = new MessageChannel; - port = channel.port2; - channel.port1.onmessage = listener; - defer = ctx(port.postMessage, port, 1); - // Browsers with postMessage, skip WebWorkers - // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' - } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){ - defer = function(id){ - global.postMessage(id + '', '*'); - }; - global.addEventListener('message', listener, false); - // IE8- - } else if(ONREADYSTATECHANGE in cel('script')){ - defer = function(id){ - html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){ - html.removeChild(this); - run.call(id); - }; - }; - // Rest old browsers - } else { - defer = function(id){ - setTimeout(ctx(run, id, 1), 0); - }; - } -} -module.exports = { - set: setTask, - clear: clearTask -}; - -/***/ }), -/* 62 */ -/***/ (function(module, exports, __webpack_require__) { - -// 7.1.15 ToLength -var toInteger = __webpack_require__(40) - , min = Math.min; -module.exports = function(it){ - return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 -}; - -/***/ }), -/* 63 */ -/***/ (function(module, exports, __webpack_require__) { - -var classof = __webpack_require__(33) - , ITERATOR = __webpack_require__(0)('iterator') - , Iterators = __webpack_require__(14); -module.exports = __webpack_require__(1).getIteratorMethod = function(it){ - if(it != undefined)return it[ITERATOR] - || it['@@iterator'] - || Iterators[classof(it)]; -}; - -/***/ }), -/* 64 */ -/***/ (function(module, exports) { - - - -/***/ }), -/* 65 */ -/***/ (function(module, exports) { - -var toString = {}.toString; - -module.exports = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; -}; - - -/***/ }), -/* 66 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -module.exports = Readable; - -/*<replacement>*/ -var processNextTick = __webpack_require__(47); -/*</replacement>*/ - -/*<replacement>*/ -var isArray = __webpack_require__(65); -/*</replacement>*/ - -/*<replacement>*/ -var Duplex; -/*</replacement>*/ - -Readable.ReadableState = ReadableState; - -/*<replacement>*/ -var EE = __webpack_require__(45).EventEmitter; - -var EElistenerCount = function (emitter, type) { - return emitter.listeners(type).length; -}; -/*</replacement>*/ - -/*<replacement>*/ -var Stream = __webpack_require__(68); -/*</replacement>*/ - -var Buffer = __webpack_require__(3).Buffer; -/*<replacement>*/ -var bufferShim = __webpack_require__(31); -/*</replacement>*/ - -/*<replacement>*/ -var util = __webpack_require__(19); -util.inherits = __webpack_require__(16); -/*</replacement>*/ - -/*<replacement>*/ -var debugUtil = __webpack_require__(153); -var debug = void 0; -if (debugUtil && debugUtil.debuglog) { - debug = debugUtil.debuglog('stream'); -} else { - debug = function () {}; -} -/*</replacement>*/ - -var BufferList = __webpack_require__(139); -var StringDecoder; - -util.inherits(Readable, Stream); - -var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; - -function prependListener(emitter, event, fn) { - // Sadly this is not cacheable as some libraries bundle their own - // event emitter implementation with them. - if (typeof emitter.prependListener === 'function') { - return emitter.prependListener(event, fn); - } else { - // This is a hack to make sure that our error handler is attached before any - // userland ones. NEVER DO THIS. This is here only because this code needs - // to continue to work with older versions of Node.js that do not include - // the prependListener() method. The goal is to eventually remove this hack. - if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; - } -} - -function ReadableState(options, stream) { - Duplex = Duplex || __webpack_require__(11); - - options = options || {}; - - // object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away - this.objectMode = !!options.objectMode; - - if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; - - // the point at which it stops calling _read() to fill the buffer - // Note: 0 is a valid value, means "don't call _read preemptively ever" - var hwm = options.highWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; - - // cast to ints. - this.highWaterMark = ~~this.highWaterMark; - - // A linked list is used to store data chunks instead of an array because the - // linked list can remove elements from the beginning faster than - // array.shift() - this.buffer = new BufferList(); - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = null; - this.ended = false; - this.endEmitted = false; - this.reading = false; - - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; - - // whenever we return null, then we set a flag to say - // that we're awaiting a 'readable' event emission. - this.needReadable = false; - this.emittedReadable = false; - this.readableListening = false; - this.resumeScheduled = false; - - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; - - // when piping, we only care about 'readable' events that happen - // after read()ing all the bytes and not getting any pushback. - this.ranOut = false; - - // the number of writers that are awaiting a drain event in .pipe()s - this.awaitDrain = 0; - - // if true, a maybeReadMore has been scheduled - this.readingMore = false; - - this.decoder = null; - this.encoding = null; - if (options.encoding) { - if (!StringDecoder) StringDecoder = __webpack_require__(46).StringDecoder; - this.decoder = new StringDecoder(options.encoding); - this.encoding = options.encoding; - } -} - -function Readable(options) { - Duplex = Duplex || __webpack_require__(11); - - if (!(this instanceof Readable)) return new Readable(options); - - this._readableState = new ReadableState(options, this); - - // legacy - this.readable = true; - - if (options && typeof options.read === 'function') this._read = options.read; - - Stream.call(this); -} - -// Manually shove something into the read() buffer. -// This returns true if the highWaterMark has not been hit yet, -// similar to how Writable.write() returns true if you should -// write() some more. -Readable.prototype.push = function (chunk, encoding) { - var state = this._readableState; - - if (!state.objectMode && typeof chunk === 'string') { - encoding = encoding || state.defaultEncoding; - if (encoding !== state.encoding) { - chunk = bufferShim.from(chunk, encoding); - encoding = ''; - } - } - - return readableAddChunk(this, state, chunk, encoding, false); -}; - -// Unshift should *always* be something directly out of read() -Readable.prototype.unshift = function (chunk) { - var state = this._readableState; - return readableAddChunk(this, state, chunk, '', true); -}; - -Readable.prototype.isPaused = function () { - return this._readableState.flowing === false; -}; - -function readableAddChunk(stream, state, chunk, encoding, addToFront) { - var er = chunkInvalid(state, chunk); - if (er) { - stream.emit('error', er); - } else if (chunk === null) { - state.reading = false; - onEofChunk(stream, state); - } else if (state.objectMode || chunk && chunk.length > 0) { - if (state.ended && !addToFront) { - var e = new Error('stream.push() after EOF'); - stream.emit('error', e); - } else if (state.endEmitted && addToFront) { - var _e = new Error('stream.unshift() after end event'); - stream.emit('error', _e); - } else { - var skipAdd; - if (state.decoder && !addToFront && !encoding) { - chunk = state.decoder.write(chunk); - skipAdd = !state.objectMode && chunk.length === 0; - } - - if (!addToFront) state.reading = false; - - // Don't add to the buffer if we've decoded to an empty string chunk and - // we're not in object mode - if (!skipAdd) { - // if we want the data now, just emit it. - if (state.flowing && state.length === 0 && !state.sync) { - stream.emit('data', chunk); - stream.read(0); - } else { - // update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); - - if (state.needReadable) emitReadable(stream); - } - } - - maybeReadMore(stream, state); - } - } else if (!addToFront) { - state.reading = false; - } - - return needMoreData(state); -} - -// if it's past the high water mark, we can push in some more. -// Also, if we have no data yet, we can stand some -// more bytes. This is to work around cases where hwm=0, -// such as the repl. Also, if the push() triggered a -// readable event, and the user called read(largeNumber) such that -// needReadable was set, then we ought to push more, so that another -// 'readable' event will be triggered. -function needMoreData(state) { - return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); -} - -// backwards compatibility. -Readable.prototype.setEncoding = function (enc) { - if (!StringDecoder) StringDecoder = __webpack_require__(46).StringDecoder; - this._readableState.decoder = new StringDecoder(enc); - this._readableState.encoding = enc; - return this; -}; - -// Don't raise the hwm > 8MB -var MAX_HWM = 0x800000; -function computeNewHighWaterMark(n) { - if (n >= MAX_HWM) { - n = MAX_HWM; - } else { - // Get the next highest power of 2 to prevent increasing hwm excessively in - // tiny amounts - n--; - n |= n >>> 1; - n |= n >>> 2; - n |= n >>> 4; - n |= n >>> 8; - n |= n >>> 16; - n++; - } - return n; -} - -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function howMuchToRead(n, state) { - if (n <= 0 || state.length === 0 && state.ended) return 0; - if (state.objectMode) return 1; - if (n !== n) { - // Only flow one buffer at a time - if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; - } - // If we're asking for more than the current hwm, then raise the hwm. - if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); - if (n <= state.length) return n; - // Don't have enough - if (!state.ended) { - state.needReadable = true; - return 0; - } - return state.length; -} - -// you can override either this method, or the async _read(n) below. -Readable.prototype.read = function (n) { - debug('read', n); - n = parseInt(n, 10); - var state = this._readableState; - var nOrig = n; - - if (n !== 0) state.emittedReadable = false; - - // if we're doing read(0) to trigger a readable event, but we - // already have a bunch of data in the buffer, then just trigger - // the 'readable' event and move on. - if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { - debug('read: emitReadable', state.length, state.ended); - if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); - return null; - } - - n = howMuchToRead(n, state); - - // if we've ended, and we're now clear, then finish it up. - if (n === 0 && state.ended) { - if (state.length === 0) endReadable(this); - return null; - } - - // All the actual chunk generation logic needs to be - // *below* the call to _read. The reason is that in certain - // synthetic stream cases, such as passthrough streams, _read - // may be a completely synchronous operation which may change - // the state of the read buffer, providing enough data when - // before there was *not* enough. - // - // So, the steps are: - // 1. Figure out what the state of things will be after we do - // a read from the buffer. - // - // 2. If that resulting state will trigger a _read, then call _read. - // Note that this may be asynchronous, or synchronous. Yes, it is - // deeply ugly to write APIs this way, but that still doesn't mean - // that the Readable class should behave improperly, as streams are - // designed to be sync/async agnostic. - // Take note if the _read call is sync or async (ie, if the read call - // has returned yet), so that we know whether or not it's safe to emit - // 'readable' etc. - // - // 3. Actually pull the requested chunks out of the buffer and return. - - // if we need a readable event, then we need to do some reading. - var doRead = state.needReadable; - debug('need readable', doRead); - - // if we currently have less than the highWaterMark, then also read some - if (state.length === 0 || state.length - n < state.highWaterMark) { - doRead = true; - debug('length less than watermark', doRead); - } - - // however, if we've ended, then there's no point, and if we're already - // reading, then it's unnecessary. - if (state.ended || state.reading) { - doRead = false; - debug('reading or ended', doRead); - } else if (doRead) { - debug('do read'); - state.reading = true; - state.sync = true; - // if the length is currently zero, then we *need* a readable event. - if (state.length === 0) state.needReadable = true; - // call internal read method - this._read(state.highWaterMark); - state.sync = false; - // If _read pushed data synchronously, then `reading` will be false, - // and we need to re-evaluate how much data we can return to the user. - if (!state.reading) n = howMuchToRead(nOrig, state); - } - - var ret; - if (n > 0) ret = fromList(n, state);else ret = null; - - if (ret === null) { - state.needReadable = true; - n = 0; - } else { - state.length -= n; - } - - if (state.length === 0) { - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (!state.ended) state.needReadable = true; - - // If we tried to read() past the EOF, then emit end on the next tick. - if (nOrig !== n && state.ended) endReadable(this); - } - - if (ret !== null) this.emit('data', ret); - - return ret; -}; - -function chunkInvalid(state, chunk) { - var er = null; - if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); - } - return er; -} - -function onEofChunk(stream, state) { - if (state.ended) return; - if (state.decoder) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) { - state.buffer.push(chunk); - state.length += state.objectMode ? 1 : chunk.length; - } - } - state.ended = true; - - // emit 'readable' now to make sure it gets picked up. - emitReadable(stream); -} - -// Don't emit readable right away in sync mode, because this can trigger -// another read() call => stack overflow. This way, it might trigger -// a nextTick recursion warning, but that's not so bad. -function emitReadable(stream) { - var state = stream._readableState; - state.needReadable = false; - if (!state.emittedReadable) { - debug('emitReadable', state.flowing); - state.emittedReadable = true; - if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); - } -} - -function emitReadable_(stream) { - debug('emit readable'); - stream.emit('readable'); - flow(stream); -} - -// at this point, the user has presumably seen the 'readable' event, -// and called read() to consume some data. that may have triggered -// in turn another _read(n) call, in which case reading = true if -// it's in progress. -// However, if we're not ended, or reading, and the length < hwm, -// then go ahead and try to read some more preemptively. -function maybeReadMore(stream, state) { - if (!state.readingMore) { - state.readingMore = true; - processNextTick(maybeReadMore_, stream, state); - } -} - -function maybeReadMore_(stream, state) { - var len = state.length; - while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { - debug('maybeReadMore read 0'); - stream.read(0); - if (len === state.length) - // didn't get any data, stop spinning. - break;else len = state.length; - } - state.readingMore = false; -} - -// abstract method. to be overridden in specific implementation classes. -// call cb(er, data) where data is <= n in length. -// for virtual (non-string, non-buffer) streams, "length" is somewhat -// arbitrary, and perhaps not very meaningful. -Readable.prototype._read = function (n) { - this.emit('error', new Error('_read() is not implemented')); -}; - -Readable.prototype.pipe = function (dest, pipeOpts) { - var src = this; - var state = this._readableState; - - switch (state.pipesCount) { - case 0: - state.pipes = dest; - break; - case 1: - state.pipes = [state.pipes, dest]; - break; - default: - state.pipes.push(dest); - break; - } - state.pipesCount += 1; - debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); - - var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; - - var endFn = doEnd ? onend : cleanup; - if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); - - dest.on('unpipe', onunpipe); - function onunpipe(readable) { - debug('onunpipe'); - if (readable === src) { - cleanup(); - } - } - - function onend() { - debug('onend'); - dest.end(); - } - - // when the dest drains, it reduces the awaitDrain counter - // on the source. This would be more elegant with a .once() - // handler in flow(), but adding and removing repeatedly is - // too slow. - var ondrain = pipeOnDrain(src); - dest.on('drain', ondrain); - - var cleanedUp = false; - function cleanup() { - debug('cleanup'); - // cleanup event handlers once the pipe is broken - dest.removeListener('close', onclose); - dest.removeListener('finish', onfinish); - dest.removeListener('drain', ondrain); - dest.removeListener('error', onerror); - dest.removeListener('unpipe', onunpipe); - src.removeListener('end', onend); - src.removeListener('end', cleanup); - src.removeListener('data', ondata); - - cleanedUp = true; - - // if the reader is waiting for a drain event from this - // specific writer, then it would cause it to never start - // flowing again. - // So, if this is awaiting a drain, then we just call it now. - // If we don't know, then assume that we are waiting for one. - if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); - } - - // If the user pushes more data while we're writing to dest then we'll end up - // in ondata again. However, we only want to increase awaitDrain once because - // dest will only emit one 'drain' event for the multiple writes. - // => Introduce a guard on increasing awaitDrain. - var increasedAwaitDrain = false; - src.on('data', ondata); - function ondata(chunk) { - debug('ondata'); - increasedAwaitDrain = false; - var ret = dest.write(chunk); - if (false === ret && !increasedAwaitDrain) { - // If the user unpiped during `dest.write()`, it is possible - // to get stuck in a permanently paused state if that write - // also returned false. - // => Check whether `dest` is still a piping destination. - if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { - debug('false write response, pause', src._readableState.awaitDrain); - src._readableState.awaitDrain++; - increasedAwaitDrain = true; - } - src.pause(); - } - } - - // if the dest has an error, then stop piping into it. - // however, don't suppress the throwing behavior for this. - function onerror(er) { - debug('onerror', er); - unpipe(); - dest.removeListener('error', onerror); - if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); - } - - // Make sure our error handler is attached before userland ones. - prependListener(dest, 'error', onerror); - - // Both close and finish should trigger unpipe, but only once. - function onclose() { - dest.removeListener('finish', onfinish); - unpipe(); - } - dest.once('close', onclose); - function onfinish() { - debug('onfinish'); - dest.removeListener('close', onclose); - unpipe(); - } - dest.once('finish', onfinish); - - function unpipe() { - debug('unpipe'); - src.unpipe(dest); - } - - // tell the dest that it's being piped to - dest.emit('pipe', src); - - // start the flow if it hasn't been started already. - if (!state.flowing) { - debug('pipe resume'); - src.resume(); - } - - return dest; -}; - -function pipeOnDrain(src) { - return function () { - var state = src._readableState; - debug('pipeOnDrain', state.awaitDrain); - if (state.awaitDrain) state.awaitDrain--; - if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { - state.flowing = true; - flow(src); - } - }; -} - -Readable.prototype.unpipe = function (dest) { - var state = this._readableState; - - // if we're not piping anywhere, then do nothing. - if (state.pipesCount === 0) return this; - - // just one destination. most common case. - if (state.pipesCount === 1) { - // passed in one, but it's not the right one. - if (dest && dest !== state.pipes) return this; - - if (!dest) dest = state.pipes; - - // got a match. - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - if (dest) dest.emit('unpipe', this); - return this; - } - - // slow case. multiple pipe destinations. - - if (!dest) { - // remove all. - var dests = state.pipes; - var len = state.pipesCount; - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - - for (var i = 0; i < len; i++) { - dests[i].emit('unpipe', this); - }return this; - } - - // try to find the right one. - var index = indexOf(state.pipes, dest); - if (index === -1) return this; - - state.pipes.splice(index, 1); - state.pipesCount -= 1; - if (state.pipesCount === 1) state.pipes = state.pipes[0]; - - dest.emit('unpipe', this); - - return this; -}; - -// set up data events if they are asked for -// Ensure readable listeners eventually get something -Readable.prototype.on = function (ev, fn) { - var res = Stream.prototype.on.call(this, ev, fn); - - if (ev === 'data') { - // Start flowing on next tick if stream isn't explicitly paused - if (this._readableState.flowing !== false) this.resume(); - } else if (ev === 'readable') { - var state = this._readableState; - if (!state.endEmitted && !state.readableListening) { - state.readableListening = state.needReadable = true; - state.emittedReadable = false; - if (!state.reading) { - processNextTick(nReadingNextTick, this); - } else if (state.length) { - emitReadable(this, state); - } - } - } - - return res; -}; -Readable.prototype.addListener = Readable.prototype.on; - -function nReadingNextTick(self) { - debug('readable nexttick read 0'); - self.read(0); -} - -// pause() and resume() are remnants of the legacy readable stream API -// If the user uses them, then switch into old mode. -Readable.prototype.resume = function () { - var state = this._readableState; - if (!state.flowing) { - debug('resume'); - state.flowing = true; - resume(this, state); - } - return this; -}; - -function resume(stream, state) { - if (!state.resumeScheduled) { - state.resumeScheduled = true; - processNextTick(resume_, stream, state); - } -} - -function resume_(stream, state) { - if (!state.reading) { - debug('resume read 0'); - stream.read(0); - } - - state.resumeScheduled = false; - state.awaitDrain = 0; - stream.emit('resume'); - flow(stream); - if (state.flowing && !state.reading) stream.read(0); -} - -Readable.prototype.pause = function () { - debug('call pause flowing=%j', this._readableState.flowing); - if (false !== this._readableState.flowing) { - debug('pause'); - this._readableState.flowing = false; - this.emit('pause'); - } - return this; -}; - -function flow(stream) { - var state = stream._readableState; - debug('flow', state.flowing); - while (state.flowing && stream.read() !== null) {} -} - -// wrap an old-style stream as the async data source. -// This is *not* part of the readable stream interface. -// It is an ugly unfortunate mess of history. -Readable.prototype.wrap = function (stream) { - var state = this._readableState; - var paused = false; - - var self = this; - stream.on('end', function () { - debug('wrapped end'); - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) self.push(chunk); - } - - self.push(null); - }); - - stream.on('data', function (chunk) { - debug('wrapped data'); - if (state.decoder) chunk = state.decoder.write(chunk); - - // don't skip over falsy values in objectMode - if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; - - var ret = self.push(chunk); - if (!ret) { - paused = true; - stream.pause(); - } - }); - - // proxy all the other methods. - // important when wrapping filters and duplexes. - for (var i in stream) { - if (this[i] === undefined && typeof stream[i] === 'function') { - this[i] = function (method) { - return function () { - return stream[method].apply(stream, arguments); - }; - }(i); - } - } - - // proxy certain important events. - for (var n = 0; n < kProxyEvents.length; n++) { - stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n])); - } - - // when we try to consume some more bytes, simply unpause the - // underlying stream. - self._read = function (n) { - debug('wrapped _read', n); - if (paused) { - paused = false; - stream.resume(); - } - }; - - return self; -}; - -// exposed for testing purposes only. -Readable._fromList = fromList; - -// Pluck off n bytes from an array of buffers. -// Length is the combined lengths of all the buffers in the list. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromList(n, state) { - // nothing buffered - if (state.length === 0) return null; - - var ret; - if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { - // read it all, truncate the list - if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); - state.buffer.clear(); - } else { - // read part of list - ret = fromListPartial(n, state.buffer, state.decoder); - } - - return ret; -} - -// Extracts only enough buffered data to satisfy the amount requested. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromListPartial(n, list, hasStrings) { - var ret; - if (n < list.head.data.length) { - // slice is the same for buffers and strings - ret = list.head.data.slice(0, n); - list.head.data = list.head.data.slice(n); - } else if (n === list.head.data.length) { - // first chunk is a perfect match - ret = list.shift(); - } else { - // result spans more than one buffer - ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); - } - return ret; -} - -// Copies a specified amount of characters from the list of buffered data -// chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBufferString(n, list) { - var p = list.head; - var c = 1; - var ret = p.data; - n -= ret.length; - while (p = p.next) { - var str = p.data; - var nb = n > str.length ? str.length : n; - if (nb === str.length) ret += str;else ret += str.slice(0, n); - n -= nb; - if (n === 0) { - if (nb === str.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = str.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -// Copies a specified amount of bytes from the list of buffered data chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBuffer(n, list) { - var ret = bufferShim.allocUnsafe(n); - var p = list.head; - var c = 1; - p.data.copy(ret); - n -= p.data.length; - while (p = p.next) { - var buf = p.data; - var nb = n > buf.length ? buf.length : n; - buf.copy(ret, ret.length - n, 0, nb); - n -= nb; - if (n === 0) { - if (nb === buf.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = buf.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -function endReadable(stream) { - var state = stream._readableState; - - // If we get here before consuming all the bytes, then that is a - // bug in node. Should never happen. - if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); - - if (!state.endEmitted) { - state.ended = true; - processNextTick(endReadableNT, state, stream); - } -} - -function endReadableNT(state, stream) { - // Check that we didn't get one last unshift. - if (!state.endEmitted && state.length === 0) { - state.endEmitted = true; - stream.readable = false; - stream.emit('end'); - } -} - -function forEach(xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); - } -} - -function indexOf(xs, x) { - for (var i = 0, l = xs.length; i < l; i++) { - if (xs[i] === x) return i; - } - return -1; -} -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(10))) - -/***/ }), -/* 67 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -// a transform stream is a readable/writable stream where you do -// something with the data. Sometimes it's called a "filter", -// but that's not a great name for it, since that implies a thing where -// some bits pass through, and others are simply ignored. (That would -// be a valid example of a transform, of course.) -// -// While the output is causally related to the input, it's not a -// necessarily symmetric or synchronous transformation. For example, -// a zlib stream might take multiple plain-text writes(), and then -// emit a single compressed chunk some time in the future. -// -// Here's how this works: -// -// The Transform stream has all the aspects of the readable and writable -// stream classes. When you write(chunk), that calls _write(chunk,cb) -// internally, and returns false if there's a lot of pending writes -// buffered up. When you call read(), that calls _read(n) until -// there's enough pending readable data buffered up. -// -// In a transform stream, the written data is placed in a buffer. When -// _read(n) is called, it transforms the queued up data, calling the -// buffered _write cb's as it consumes chunks. If consuming a single -// written chunk would result in multiple output chunks, then the first -// outputted bit calls the readcb, and subsequent chunks just go into -// the read buffer, and will cause it to emit 'readable' if necessary. -// -// This way, back-pressure is actually determined by the reading side, -// since _read has to be called to start processing a new chunk. However, -// a pathological inflate type of transform can cause excessive buffering -// here. For example, imagine a stream where every byte of input is -// interpreted as an integer from 0-255, and then results in that many -// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in -// 1kb of data being output. In this case, you could write a very small -// amount of input, and end up with a very large amount of output. In -// such a pathological inflating mechanism, there'd be no way to tell -// the system to stop doing the transform. A single 4MB write could -// cause the system to run out of memory. -// -// However, even in such a pathological case, only a single written chunk -// would be consumed, and then the rest would wait (un-transformed) until -// the results of the previous transformed chunk were consumed. - - - -module.exports = Transform; - -var Duplex = __webpack_require__(11); - -/*<replacement>*/ -var util = __webpack_require__(19); -util.inherits = __webpack_require__(16); -/*</replacement>*/ - -util.inherits(Transform, Duplex); - -function TransformState(stream) { - this.afterTransform = function (er, data) { - return afterTransform(stream, er, data); - }; - - this.needTransform = false; - this.transforming = false; - this.writecb = null; - this.writechunk = null; - this.writeencoding = null; -} - -function afterTransform(stream, er, data) { - var ts = stream._transformState; - ts.transforming = false; - - var cb = ts.writecb; - - if (!cb) return stream.emit('error', new Error('no writecb in Transform class')); - - ts.writechunk = null; - ts.writecb = null; - - if (data !== null && data !== undefined) stream.push(data); - - cb(er); - - var rs = stream._readableState; - rs.reading = false; - if (rs.needReadable || rs.length < rs.highWaterMark) { - stream._read(rs.highWaterMark); - } -} - -function Transform(options) { - if (!(this instanceof Transform)) return new Transform(options); - - Duplex.call(this, options); - - this._transformState = new TransformState(this); - - var stream = this; - - // start out asking for a readable event once data is transformed. - this._readableState.needReadable = true; - - // we have implemented the _read method, and done the other things - // that Readable wants before the first _read call, so unset the - // sync guard flag. - this._readableState.sync = false; - - if (options) { - if (typeof options.transform === 'function') this._transform = options.transform; - - if (typeof options.flush === 'function') this._flush = options.flush; - } - - // When the writable side finishes, then flush out anything remaining. - this.once('prefinish', function () { - if (typeof this._flush === 'function') this._flush(function (er, data) { - done(stream, er, data); - });else done(stream); - }); -} - -Transform.prototype.push = function (chunk, encoding) { - this._transformState.needTransform = false; - return Duplex.prototype.push.call(this, chunk, encoding); -}; - -// This is the part where you do stuff! -// override this function in implementation classes. -// 'chunk' is an input chunk. -// -// Call `push(newChunk)` to pass along transformed output -// to the readable side. You may call 'push' zero or more times. -// -// Call `cb(err)` when you are done with this chunk. If you pass -// an error, then that'll put the hurt on the whole operation. If you -// never call cb(), then you'll never get another chunk. -Transform.prototype._transform = function (chunk, encoding, cb) { - throw new Error('_transform() is not implemented'); -}; - -Transform.prototype._write = function (chunk, encoding, cb) { - var ts = this._transformState; - ts.writecb = cb; - ts.writechunk = chunk; - ts.writeencoding = encoding; - if (!ts.transforming) { - var rs = this._readableState; - if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); - } -}; - -// Doesn't matter what the args are here. -// _transform does all the work. -// That we got here means that the readable side wants more data. -Transform.prototype._read = function (n) { - var ts = this._transformState; - - if (ts.writechunk !== null && ts.writecb && !ts.transforming) { - ts.transforming = true; - this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); - } else { - // mark that we need a transform, so that any data that comes in - // will get processed, now that we've asked for it. - ts.needTransform = true; - } -}; - -function done(stream, er, data) { - if (er) return stream.emit('error', er); - - if (data !== null && data !== undefined) stream.push(data); - - // if there's nothing in the write buffer, then that means - // that nothing more will ever be provided - var ws = stream._writableState; - var ts = stream._transformState; - - if (ws.length) throw new Error('Calling transform done when ws.length != 0'); - - if (ts.transforming) throw new Error('Calling transform done when still transforming'); - - return stream.push(null); -} - -/***/ }), -/* 68 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(45).EventEmitter; - - -/***/ }), -/* 69 */ -/***/ (function(module, exports, __webpack_require__) { - -var apply = Function.prototype.apply; - -// DOM APIs, for completeness - -exports.setTimeout = function() { - return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout); -}; -exports.setInterval = function() { - return new Timeout(apply.call(setInterval, window, arguments), clearInterval); -}; -exports.clearTimeout = -exports.clearInterval = function(timeout) { - if (timeout) { - timeout.close(); - } -}; - -function Timeout(id, clearFn) { - this._id = id; - this._clearFn = clearFn; -} -Timeout.prototype.unref = Timeout.prototype.ref = function() {}; -Timeout.prototype.close = function() { - this._clearFn.call(window, this._id); -}; - -// Does not start the time, just sets up the members needed. -exports.enroll = function(item, msecs) { - clearTimeout(item._idleTimeoutId); - item._idleTimeout = msecs; -}; - -exports.unenroll = function(item) { - clearTimeout(item._idleTimeoutId); - item._idleTimeout = -1; -}; - -exports._unrefActive = exports.active = function(item) { - clearTimeout(item._idleTimeoutId); - - var msecs = item._idleTimeout; - if (msecs >= 0) { - item._idleTimeoutId = setTimeout(function onTimeout() { - if (item._onTimeout) - item._onTimeout(); - }, msecs); - } -}; - -// setimmediate attaches itself to the global object -__webpack_require__(143); -exports.setImmediate = setImmediate; -exports.clearImmediate = clearImmediate; - - -/***/ }), -/* 70 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = undefined; - -var _promise = __webpack_require__(84); - -var _promise2 = _interopRequireDefault(_promise); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var files = [ -// "gun_violence", -"mass_shootings_lite", "gun_violence_by_month"]; -var parse = __webpack_require__(133); - -var dataPromises = files.map(function (name) { - return fetch('./data/' + name + '.csv').then(function (rows) { - return rows.text(); - }).then(function (text) { - return new _promise2.default(function (resolve, reject) { - parse(text, {}, function (_, lines) { - return resolve(lines); - }); - }); - }).then(function (lines) { - // console.log(name, lines) - var h = lines.shift(); - return { - name: name, - h: h, - lines: lines.filter(function (s) { - return !!s; - }) - }; - }); -}); -var allPromises = _promise2.default.all(dataPromises).then(function (data) { - return data.reduce(function (a, b) { - // console.log(b) - a[b.name] = b; - return a; - }, {}); -}); -var load = function load() { - return allPromises; -}; - -exports.load = load; - -/***/ }), -/* 71 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var keys = {}; -var key_numbers = {}; -var letters = "zxcvbnmasdfghjklqwertyuiop"; -var numbers = "1234567890"; - -var callback = function callback() {}; - -letters.toUpperCase().split("").map(function (k, i) { - keys[k.charCodeAt(0)] = i; -}); - -numbers.split("").map(function (k, i) { - keys[k.charCodeAt(0)] = i + letters.length; - key_numbers[k.charCodeAt(0)] = true; -}); - -window.addEventListener("keydown", keydown, true); -function keydown(e) { - if (e.altKey || e.ctrlKey || e.metaKey) { - e.stopPropagation(); - return; - } - if (document.activeElement instanceof HTMLInputElement && e.keyCode in key_numbers) { - e.stopPropagation(); - return; - } - if (!(e.keyCode in keys)) return; - var index = keys[e.keyCode]; - if (e.shiftKey) index += letters.length; - index -= 7; - callback(index); -} - -function listen(fn) { - callback = fn; -} - -exports.default = { listen: listen }; - -/***/ }), -/* 72 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.note_values = exports.MidiWriter = undefined; - -var _slicedToArray2 = __webpack_require__(73); - -var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); - -exports.midi_init = midi_init; -exports.play_note = play_note; -exports.play_midi_note = play_midi_note; -exports.play_sequence = play_sequence; -exports.play_interval_sequence = play_interval_sequence; -exports.export_pattern_as_midi = export_pattern_as_midi; - -var _tone = __webpack_require__(21); - -var _tone2 = _interopRequireDefault(_tone); - -var _webmidi = __webpack_require__(150); - -var _webmidi2 = _interopRequireDefault(_webmidi); - -var _scales = __webpack_require__(50); - -var _scales2 = _interopRequireDefault(_scales); - -var _util = __webpack_require__(30); - -var _kalimba = __webpack_require__(78); - -var _kalimba2 = _interopRequireDefault(_kalimba); - -var _FileSaver = __webpack_require__(74); - -var _ui = __webpack_require__(51); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var midiDevice = void 0; -var sendPitchBend = false; - -var MidiWriter = exports.MidiWriter = __webpack_require__(135); - -var note_values = exports.note_values = [[8, '8 measures', 8 * 512], [4, '4 measures', 4 * 512], [2, '2 measures', 2 * 512], [1, 'whole note', 512], [1 / 2, 'half note', 256], [1 / 3, 'third note', [170, 170, 171]], [1 / 4, 'quarter note', 128], [1 / 5, 'fifth note', [51, 51, 51, 51, 52]], [1 / 6, 'sixth note', [85, 85, 86, 85, 85, 86]], [1 / 8, 'eighth note', 64], [1 / 10, 'tenth note', [25, 26, 26, 25, 26, 25, 26, 26, 25, 26]], [1 / 12, 'twelfth note', [21, 21, 22, 21, 21, 22, 21, 21, 22, 21, 21, 22]], [1 / 16, 'sixteenth note', 32], [1 / 32, 'thirtysecond note', 16]]; - -function midi_init() { - _webmidi2.default.enable(midi_ready); - function midi_ready(err) { - if (err) { - console.error('webmidi failed to initialize'); - return; - } - if (!_webmidi2.default.outputs.length) { - console.error('no MIDI output found'); - return; - } - console.log(_webmidi2.default.inputs); - console.log(_webmidi2.default.outputs); - if (_webmidi2.default.outputs.length > 1) { - var filtered = _webmidi2.default.outputs.filter(function (output) { - return output.name.match(/prodipe/i); - }); - if (filtered.length) { - // midiDevice = filtered[0] - } - } - // midiDevice = midiDevice || WebMidi.outputs[0] - // console.log(midiDevice.name) - } -} - -/* play a single note */ - -function play_note(index, duration) { - var channel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "all"; - var exporting = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - var rest = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; - var defer = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; - - // console.log(index) - var scale = _scales2.default.current(); - var freq = scale.index(index + Math.round(_ui.nx.offset.value), _ui.nx.octave.value); - var midi_note = (0, _util.ftom)(freq); - var cents = midi_note % 1; - if (cents > 0.5) { - midi_note += 1; - cents -= 1; - } - cents *= 2; - midi_note = Math.floor(midi_note); - if ((midiDevice || exporting) && midi_note > 127) return 0; - var note = _tone2.default.Frequency(Math.floor(midi_note), "midi").toNote(); - var defer_time = 30000 / _tone2.default.Transport.bpm.value * defer / 128; - console.log(defer, defer_time); - if (exporting || midiDevice) { - duration = duration || 60000 / _tone2.default.Transport.bpm.value; - if (!exporting) { - if (defer) { - setTimeout(function () { - play_midi_note(note, cents, channel, duration); - }, defer); - } else { - play_midi_note(note, cents, channel, duration); - } - } - } else if (defer) { - setTimeout(function () { - _kalimba2.default.play(freq); - }, defer_time); - } else { - _kalimba2.default.play(freq); - } - return note; -} - -function play_midi_note(note, cents, channel, duration) { - midiDevice.playNote(note, channel, { duration: duration }); - if (sendPitchBend) { - midiDevice.sendPitchBend(cents, channel); - } -} - -/* play the next note in sequence */ - -function play_sequence(i, bounds, diff, note_time) { - var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : "all"; - var exporting = arguments[5]; - var rows = bounds.rows, - min = bounds.min, - max = bounds.max; - - var count = rows.length * rows[0].length; - if (i >= count) i = 0; - var y = Math.floor(i / rows[0].length); - var x = i % rows[0].length; - // if (!x) console.log(y) - var n = rows[y][x]; - i += 1; - if (i >= count) i = 0; - var midi_note = play_note((0, _util.norm)(n, min, max) * _ui.nx.multiply.value, note_time, channel, exporting); - return [i, [midi_note]]; -} - -/* play the next row as an interval */ - -function play_interval_sequence(i, bounds, diff, note_time) { - var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : "all"; - var exporting = arguments[5]; - var rows = bounds.rows, - min = bounds.min, - max = bounds.max; - - var count = rows.length; - if (i >= count) i = 0; - var y = i % count; - var row = rows[y]; - if (!row) { - i = 0;return; - } - var row_min = Math.min.apply(Math, row); - // const row_max = Math.max.apply(Math, row) - var row_f0 = (0, _util.norm)(row_min, min, max); - var row_root = row_f0 * _ui.nx.multiply.value; - var notes = row.map(function (n) { - var note = row_root + (0, _util.norm)(n - row_min, diff.min, diff.max) * _ui.nx.interval.value; - play_note(note, note_time, channel, exporting); - }); - i += 1; - return [i, notes]; -} - -/* generate a 1-track midi file by calling the play function repeatedly */ - -function export_pattern_as_midi(datasetName, bounds, diff, tempo, timingIndex, play_fn) { - // const behavior = document.querySelector('#behavior').value - var rows = bounds.rows; - // let count = behavior === 'sequence' ? rows[0].length * rows.length : rows.length - - var count = rows[0].length; - var notes = void 0, - timings = void 0, - wait = void 0; - var note_time = void 0; - // let timing = note_values[timingIndex][2] - var midi_track = new MidiWriter.Track(); - midi_track.setTempo(tempo); - for (var i = 0, len = count; i < len; i++) { - // if (timing.length) { - // note_time = timing[i % timing.length] - // } else { - // note_time = timing - // } - // midi_track.addEvent(new MidiWriter.NoteEvent({ pitch: notes, duration: 't' + note_time })) - var _play_fn = play_fn(i, bounds, note_time, "all", true); - - var _play_fn2 = (0, _slicedToArray3.default)(_play_fn, 4); - - i = _play_fn2[0]; - notes = _play_fn2[1]; - timings = _play_fn2[2]; - wait = _play_fn2[3]; - console.log(i, notes, timings); - for (var j = 0; j < notes.length; j++) { - midi_track.addEvent(new MidiWriter.NoteEvent({ pitch: notes[j], duration: 't' + timings[j], wait: wait })); - } - } - var writer = new MidiWriter.Writer([midi_track]); - var blob = (0, _util.dataURItoBlob)(writer.dataUri()); - (0, _FileSaver.saveAs)(blob, 'Recording - ' + datasetName + '.mid'); -} - -/***/ }), -/* 73 */ -/***/ (function(module, exports, __webpack_require__) { - "use strict"; exports.__esModule = true; -var _isIterable2 = __webpack_require__(81); +var _isIterable2 = __webpack_require__(85); var _isIterable3 = _interopRequireDefault(_isIterable2); -var _getIterator2 = __webpack_require__(80); +var _getIterator2 = __webpack_require__(84); var _getIterator3 = _interopRequireDefault(_getIterator2); @@ -30730,202 +28980,7 @@ exports.default = function () { }(); /***/ }), -/* 74 */ -/***/ (function(module, exports, __webpack_require__) { - -var __WEBPACK_AMD_DEFINE_RESULT__;/* FileSaver.js - * A saveAs() FileSaver implementation. - * 1.3.2 - * 2016-06-16 18:25:19 - * - * By Eli Grey, http://eligrey.com - * License: MIT - * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md - */ - -/*global self */ -/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ - -/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ - -var saveAs = saveAs || (function(view) { - "use strict"; - // IE <10 is explicitly unsupported - if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { - return; - } - var - doc = view.document - // only get URL when necessary in case Blob.js hasn't overridden it yet - , get_URL = function() { - return view.URL || view.webkitURL || view; - } - , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") - , can_use_save_link = "download" in save_link - , click = function(node) { - var event = new MouseEvent("click"); - node.dispatchEvent(event); - } - , is_safari = /constructor/i.test(view.HTMLElement) || view.safari - , is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent) - , throw_outside = function(ex) { - (view.setImmediate || view.setTimeout)(function() { - throw ex; - }, 0); - } - , force_saveable_type = "application/octet-stream" - // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to - , arbitrary_revoke_timeout = 1000 * 40 // in ms - , revoke = function(file) { - var revoker = function() { - if (typeof file === "string") { // file is an object URL - get_URL().revokeObjectURL(file); - } else { // file is a File - file.remove(); - } - }; - setTimeout(revoker, arbitrary_revoke_timeout); - } - , dispatch = function(filesaver, event_types, event) { - event_types = [].concat(event_types); - var i = event_types.length; - while (i--) { - var listener = filesaver["on" + event_types[i]]; - if (typeof listener === "function") { - try { - listener.call(filesaver, event || filesaver); - } catch (ex) { - throw_outside(ex); - } - } - } - } - , auto_bom = function(blob) { - // prepend BOM for UTF-8 XML and text/* types (including HTML) - // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF - if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { - return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type}); - } - return blob; - } - , FileSaver = function(blob, name, no_auto_bom) { - if (!no_auto_bom) { - blob = auto_bom(blob); - } - // First try a.download, then web filesystem, then object URLs - var - filesaver = this - , type = blob.type - , force = type === force_saveable_type - , object_url - , dispatch_all = function() { - dispatch(filesaver, "writestart progress write writeend".split(" ")); - } - // on any filesys errors revert to saving with object URLs - , fs_error = function() { - if ((is_chrome_ios || (force && is_safari)) && view.FileReader) { - // Safari doesn't allow downloading of blob urls - var reader = new FileReader(); - reader.onloadend = function() { - var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;'); - var popup = view.open(url, '_blank'); - if(!popup) view.location.href = url; - url=undefined; // release reference before dispatching - filesaver.readyState = filesaver.DONE; - dispatch_all(); - }; - reader.readAsDataURL(blob); - filesaver.readyState = filesaver.INIT; - return; - } - // don't create more object URLs than needed - if (!object_url) { - object_url = get_URL().createObjectURL(blob); - } - if (force) { - view.location.href = object_url; - } else { - var opened = view.open(object_url, "_blank"); - if (!opened) { - // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html - view.location.href = object_url; - } - } - filesaver.readyState = filesaver.DONE; - dispatch_all(); - revoke(object_url); - } - ; - filesaver.readyState = filesaver.INIT; - - if (can_use_save_link) { - object_url = get_URL().createObjectURL(blob); - setTimeout(function() { - save_link.href = object_url; - save_link.download = name; - click(save_link); - dispatch_all(); - revoke(object_url); - filesaver.readyState = filesaver.DONE; - }); - return; - } - - fs_error(); - } - , FS_proto = FileSaver.prototype - , saveAs = function(blob, name, no_auto_bom) { - return new FileSaver(blob, name || blob.name || "download", no_auto_bom); - } - ; - // IE 10+ (native saveAs) - if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { - return function(blob, name, no_auto_bom) { - name = name || blob.name || "download"; - - if (!no_auto_bom) { - blob = auto_bom(blob); - } - return navigator.msSaveOrOpenBlob(blob, name); - }; - } - - FS_proto.abort = function(){}; - FS_proto.readyState = FS_proto.INIT = 0; - FS_proto.WRITING = 1; - FS_proto.DONE = 2; - - FS_proto.error = - FS_proto.onwritestart = - FS_proto.onprogress = - FS_proto.onwrite = - FS_proto.onabort = - FS_proto.onerror = - FS_proto.onwriteend = - null; - - return saveAs; -}( - typeof self !== "undefined" && self - || typeof window !== "undefined" && window - || this.content -)); -// `self` is undefined in Firefox for Android content script context -// while `this` is nsIContentFrameMessageManager -// with an attribute `content` that corresponds to the window - -if (typeof module !== "undefined" && module.exports) { - module.exports.saveAs = saveAs; -} else if (("function" !== "undefined" && __webpack_require__(151) !== null) && (__webpack_require__(152) !== null)) { - !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { - return saveAs; - }.call(exports, __webpack_require__, exports, module), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); -} - - -/***/ }), -/* 75 */ +/* 56 */ /***/ (function(module, exports, __webpack_require__) { (function webpackUniversalModuleDefinition(root, factory) { @@ -40547,47 +38602,1941 @@ return /******/ (function(modules) { // webpackBootstrap //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovLy93ZWJwYWNrL2Jvb3RzdHJhcCBiMjY5YWNlZjhjYWRhNzA4NDUwMiIsIndlYnBhY2s6Ly8vLi9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvbWFpbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9wb3NpdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC9zdmcuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwvbWF0aC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvY29yZS9pbnRlcmZhY2UuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwvZG9tLmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsL3V0aWwuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwvdG91Y2guanMiLCJ3ZWJwYWNrOi8vLy4vfi9ldmVudHMvZXZlbnRzLmpzIiwid2VicGFjazovLy8uL2xpYi9tb2RlbHMvc3RlcC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC9pbnRlcmFjdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvbW9kZWxzL3RvZ2dsZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zbGlkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2ludGVyZmFjZXMvdG9nZ2xlLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL2J1dHRvbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvY29tcG9uZW50cy9idXR0b250ZW1wbGF0ZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy90ZXh0YnV0dG9uLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL3JhZGlvYnV0dG9uLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL251bWJlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zZWxlY3QuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2ludGVyZmFjZXMvZGlhbC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9waWFuby5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zZXF1ZW5jZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21vZGVscy9tYXRyaXguanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21vZGVscy9zZXF1ZW5jZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvbW9kZWxzL2RydW5rLmpzIiwid2VicGFjazovLy8uL2xpYi9tb2RlbHMvY291bnRlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9wYW4yZC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy90aWx0LmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL211bHRpc2xpZGVyLmpzIiwid2VicGFjazovLy8uL2xpYi9jb21wb25lbnRzL3NsaWRlcnRlbXBsYXRlLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL3Bhbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9lbnZlbG9wZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zcGVjdHJvZ3JhbS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9tZXRlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9vc2NpbGxvc2NvcGUuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2NvcmUvcmFjay5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC90cmFuc2Zvcm0uanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3R1bmluZy90dW5pbmcuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21vZGVscy9yYWRpby5qcyIsIndlYnBhY2s6Ly8vLi9+L3dhYWNsb2NrL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vd2FhY2xvY2svbGliL1dBQUNsb2NrLmpzIiwid2VicGFjazovLy8uL34vcHJvY2Vzcy9icm93c2VyLmpzIiwid2VicGFjazovLy8uL2xpYi90aW1lL2ludGVydmFsLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRCxPO0FDVkE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQWU7QUFDZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7OztBQ3RDQSxhQUFZLENBQUM7Ozs7S0FFTixPQUFPLHVDQUFNLENBQVk7O2tCQUVqQixPQUFPLEM7Ozs7Ozs7Ozs7Ozs7Ozs7U0NtSE4sTUFBTSxHQUFOLE1BQU07U0FHTixPQUFPLEdBQVAsT0FBTztTQUdQLEtBQUssR0FBTCxLQUFLOzs7O0FBN0hyQixhQUFZLENBQUM7O0tBRU4sVUFBVSx1Q0FBTSxDQUFlOztLQUMvQixJQUFJLHVDQUFNLENBQWE7O0tBQ3ZCLElBQUksdUNBQU0sRUFBYTs7S0FDdkIsSUFBSSx1Q0FBTSxFQUFpQjs7S0FDdEIsU0FBUywrQ0FBTSxFQUFrQjs7QUFFN0MsS0FBSSxPQUFPLEdBQUcsbUJBQU8sQ0FBQyxFQUFrQixDQUFDLENBQUM7QUFDMUMsS0FBSSxLQUFLLEdBQUcsbUJBQU8sQ0FBQyxFQUFnQixDQUFDLENBQUM7QUFDdEMsS0FBSSxLQUFLLEdBQUcsbUJBQU8sQ0FBQyxFQUFnQixDQUFDLENBQUM7QUFDdEMsS0FBSSxRQUFRLEdBQUcsbUJBQU8sQ0FBQyxFQUFtQixDQUFDLENBQUM7QUFDNUMsS0FBSSxNQUFNLEdBQUcsbUJBQU8sQ0FBQyxFQUFpQixDQUFDLENBQUM7O0tBRWpDLFFBQVEsdUNBQU0sRUFBVTs7S0FDeEIsUUFBUSx1Q0FBTSxFQUFpQjs7Ozs7O0tBT2hDLE9BQU87QUFFRSxZQUZULE9BQU8s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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxnQkFBZSxTQUFTO0FBQ3hCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxJQUFHO0FBQ0gscUJBQW9CLFNBQVM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7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QUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNsRSxhQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7O0FBRWxFLGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN2QyxhQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDdkMsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDOztBQUV2QyxhQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDbkUsYUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ25FLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzs7QUFFbkUsYUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3hDLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN4QyxhQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7O0FBR3hDLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxJQUFJLENB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Q0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ25ELGVBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ25ELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1VBQ25ELE1BQU07QUFDTCxlQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDdEQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDNUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDNUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDNUQsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekQsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekQsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7VUFDekQ7UUFFRjs7QUFFRCxXQUFNO2NBQUEsZ0JBQUMsQ0FBQyxFQUFFO0FBQ1IsYUFBSSxJQUFJLENBQUMsT0FBTyxFQUFDOztBQUVmLGVBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDZixlQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ2hCLGVBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUM7OztBQUdoQixZQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFFLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixZQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFFLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixZQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLEdBQUcsRUFBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRzVCLGVBQUksWUFBWSxHQUFHO0FBQ2pCLGtCQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHO0FBQ2xCLGdCQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQyxDQUFDLEVBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxDQUFDLEVBQUcsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLENBQUU7WUFDekYsQ0FBQztBQUNGLGVBQUksYUFBYSxHQUFHO0FBQ2xCLGtCQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHO0FBQ2xCLGdCQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQyxHQUFHLEVBQUMsQ0FBQyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxDQUFDLEVBQUcsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLENBQUU7WUFDekYsQ0FBQzs7QUFFRixlQUFJLFVBQVUsR0FBRyxHQUFHLENBQUMsR0FB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QUFJLENBQUMsSUFBSSxDQUFDLEtBQUcsQ0FBQyxHQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDOztBQUVuQyxTQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBRSxDQUFDLEVBQUU7O0FBRXhDLFdBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBQyxDQUFDLENBQUM7QUFDcEQsV0FBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFDLENBQUMsQ0FBQzs7QUFFcEQsV0FBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDOUMsV0FBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7O0FBRTlDLFdBQUksSUFBSSxHQUFHLFNBQVMsSUFBSSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0MsV0FBSSxLQUFLLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7QUFFcEUsV0FBSSxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRTtBQUFFLGFBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQUU7QUFDckMsV0FBSSxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssRUFBRTtBQUFFLGFBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQUU7TUFFeEM7O0FBRUQsU0FBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDdEMsU0FBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFR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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQ0FBeUM7O0FBRXpDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsSUFBRztBQUNIO0FBQ0E7O0FBRUEsSUFBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBa0MsaUNBQWlDO0FBQ25FO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFxQyxlQUFlO0FBQ3BEO0FBQ0EsTUFBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEk7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7Ozs7QUN6T0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQSxFQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdCQUF1QixzQkFBc0I7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBcUI7QUFDckI7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNDQUFxQzs7QUFFckM7QUFDQTtBQUNBOztBQUVBLDRCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQSw2QkFBNEIsVUFBVTs7Ozs7OztBQ3ZMdEMsYUFBWSxDQUFDOzs7Ozs7S0FFSixLQUFLLHVCQUFRLENBQVMsRUFBdEIsS0FBSzs7S0FFTyxRQUFRO0FBRWhCLFlBRlEsUUFBUSxDQUVmLElBQUksRUFBQyxJQUFJLEVBQUMsRUFBRSxFQUFFOzJCQUZQLFFBQVE7O0FBSXpCLFNBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ2pCLFNBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2IsU0FBSSxDQUFDLEtBQUssR0FBRyxLQUFLLEVBQUUsQ0FBQzs7QUFFckIsU0FBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25CLFNBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDOztBQUVmLFNBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxZQUFXLEVBQUcsQ0FBQzs7QUFFMUMsU0FBSSxJQUFJLENBQUMsRUFBRSxFQUFFO0FBQ1gsV0FBSSxDQUFDLEtBQUssRUFBRSxDQUFDO01BQ2Q7SUFFRjs7Z0JBakJrQixRQUFRO0FBbUIzQixXQUFNO2NBQUEsZ0JBQUMsQ0FBQyxFQUFFOztBQUVOLGFBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRWhCLGFBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNkOztBQUVELFNBQUk7Y0FBQSxnQkFBRztBQUNMLGFBQUksQ0FBQyxFQUFFLEdBQUcsS0FBSyxDQUFDO0FBQ2hCLGFBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkI7O0FBRUQsVUFBSztjQUFBLGlCQUFHO0FBQ04sYUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDZixhQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7UUFDMUo7O0FBRUQsT0FBRTtjQUFBLFlBQUMsT0FBTyxFQUFFO0FBQ1YsYUFBSSxJQUFJLENBQUMsRUFBRSxFQUFFO0FBQ1gsZUFBSSxLQUFLLEdBQUcsT0FBTyxHQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDOUIsZUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7QUFDcEIsZUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1VBQ2hGLE1BQU07QUFDTCxlQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQztVQUNyQjtRQUNGOzs7O1VBNUNrQixRQUFROzs7a0JBQVIsUUFBUSxDIiwiZmlsZSI6Ii4vZGlzdC9OZXh1c1VJLmpzIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wiTmV4dXNcIl0gPSBmYWN0b3J5KCk7XG5cdGVsc2Vcblx0XHRyb290W1wiTmV4dXNcIl0gPSBmYWN0b3J5KCk7XG59KSh0aGlzLCBmdW5jdGlvbigpIHtcbnJldHVybiBcblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pXG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG5cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGV4cG9ydHM6IHt9LFxuIFx0XHRcdGlkOiBtb2R1bGVJZCxcbiBcdFx0XHRsb2FkZWQ6IGZhbHNlXG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oMCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay9ib290c3RyYXAgYjI2OWFjZWY4Y2FkYTcwODQ1MDIiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBOZXh1c1VJIGZyb20gJy4vbGliL21haW4nO1xuXG5leHBvcnQgZGVmYXVsdCBOZXh1c1VJO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vaW5kZXguanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBJbnRlcmZhY2VzIGZyb20gJy4vaW50ZXJmYWNlcy8nO1xuaW1wb3J0IG1hdGggZnJvbSAnLi91dGlsL21hdGgnO1xuaW1wb3J0IFJhY2sgZnJvbSAnLi9jb3JlL3JhY2snO1xuaW1wb3J0IFR1bmUgZnJvbSAnLi90dW5pbmcvdHVuaW5nJztcbmltcG9ydCAqIGFzIFRyYW5zZm9ybSBmcm9tICcuL3V0aWwvdHJhbnNmb3JtJztcblxubGV0IENvdW50ZXIgPSByZXF1aXJlKCcuL21vZGVscy9jb3VudGVyJyk7XG5sZXQgUmFkaW8gPSByZXF1aXJlKCcuL21vZGVscy9yYWRpbycpO1xubGV0IERydW5rID0gcmVxdWlyZSgnLi9tb2RlbHMvZHJ1bmsnKTtcbmxldCBTZXF1ZW5jZSA9IHJlcXVpcmUoJy4vbW9kZWxzL3NlcXVlbmNlJyk7XG5sZXQgTWF0cml4ID0gcmVxdWlyZSgnLi9tb2RlbHMvbWF0cml4Jyk7XG5cbmltcG9ydCBXQUFDbG9jayBmcm9tICd3YWFjbG9jayc7XG5pbXBvcnQgSW50ZXJ2YWwgZnJvbSAnLi90aW1lL2ludGVydmFsJztcblxuXG4vKipcbk5leHVzVUkgPT4gY3JlYXRlZCBhcyBOZXh1c1xuKi9cblxuY2xhc3MgTmV4dXNVSSB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0KSB7XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIEludGVyZmFjZXMpIHtcbiAgICAgICAgICAgIHRoaXNba2V5XSA9IEludGVyZmFjZXNba2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGtleSBpbiBtYXRoKSB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSBtYXRoW2tleV07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgQ29yZSA9IHtcbiAgICAgICAgICAnUmFjayc6IFJhY2tcbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgTW9kZWxzID0ge1xuICAgICAgICAgICdDb3VudGVyJzogQ291bnRlcixcbiAgICAgICAgICAnUmFkaW8nOiBSYWRpbyxcbiAgICAgICAgICAnRHJ1bmsnOiBEcnVuayxcbiAgICAgICAgICAnU2VxdWVuY2UnOiBTZXF1ZW5jZSxcbiAgICAgICAgICAnTWF0cml4JzogTWF0cml4XG4gICAgICAgIH07XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIE1vZGVscykge1xuICAgICAgICAgIHRoaXNba2V5XSA9IE1vZGVsc1trZXldO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIENvcmUpIHtcbiAgICAgICAgICB0aGlzW2tleV0gPSBDb3JlW2tleV07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgRGVmYXVsdENvbnRleHQgPSB3aW5kb3cuQXVkaW9Db250ZXh0IHx8IHdpbmRvdy53ZWJraXRBdWRpb0NvbnRleHQ7XG4gICAgICAgIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0IHx8IG5ldyBEZWZhdWx0Q29udGV4dCgpO1xuXG4gICAgICAgIHRoaXMudHVuZSA9IG5ldyBUdW5lKCk7XG4gICAgICAgIHRoaXMubm90ZSA9IHRoaXMudHVuZS5ub3RlLmJpbmQodGhpcy50dW5lKTtcblxuICAgICAgICB0aGlzLmNsb2NrID0gbmV3IFdBQUNsb2NrKHRoaXMuX2NvbnRleHQpO1xuICAgICAgICB0aGlzLmNsb2NrLnN0YXJ0KCk7XG4gICAgICAgIHRoaXMuSW50ZXJ2YWwgPSBJbnRlcnZhbDtcblxuICAgICAgICB0aGlzLmNvbG9ycyA9IHtcbiAgICAgICAgICBhY2NlbnQ6ICcjMmJiJyxcbiAgICAgICAgICBmaWxsOiAnI2VlZScsXG4gICAgICAgICAgbGlnaHQ6ICcjZmZmJyxcbiAgICAgICAgICBkYXJrOiAnIzMzMycsXG4gICAgICAgICAgbWVkaXVtTGlnaHQ6ICcjY2NjJyxcbiAgICAgICAgICBtZWRpdW1EYXJrOiAnIzY2NidcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnRyYW5zZm9ybSA9IFRyYW5zZm9ybTtcbiAgICAgICAgdGhpcy5hZGQgPSBUcmFuc2Zvcm0uYWRkO1xuXG5cbiAgICAgICAgdGhpcy5BZGQgPSB7fTtcbiAgICAgICAgZm9yIChsZXQga2V5IGluIEludGVyZmFjZXMpIHtcbiAgICAgICAgICB0aGlzLkFkZFtrZXldID0gVHJhbnNmb3JtLmFkZC5iaW5kKHRoaXMsa2V5KTtcbiAgICAgICAgfVxuXG5cblxuXG4gICAgICAgIC8qIGNyZWF0ZSBkZWZhdWx0IGNvbXBvbmVudCBzaXplICovXG4gICAgICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICAgICAgdmFyIGV4aXN0aW5nU3R5bGVzaGVldHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcInN0eWxlXCIpO1xuICAgICAgICB2YXIgZGVmYXVsdFNpemVEZWNsYXJhdGlvbiA9ICdbbmV4dXMtdWlde2hlaWdodDo1MDAwcHg7d2lkdGg6NTAwMHB4fSc7XG4gICAgICAgIHZhciBkZWZhdWx0U3R5bGVOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICAgICAgZGVmYXVsdFN0eWxlTm9kZS50eXBlID0gJ3RleHQvY3NzJztcbiAgICAgICAgZGVmYXVsdFN0eWxlTm9kZS5pbm5lckhUTUwgPSBkZWZhdWx0U2l6ZURlY2xhcmF0aW9uO1xuICAgICAgICBpZiAoZXhpc3RpbmdTdHlsZXNoZWV0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdmFyIHBhcmVudCA9IGV4aXN0aW5nU3R5bGVzaGVldHNbMF0ucGFyZW50Tm9kZVxuICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoIGRlZmF1bHRTdHlsZU5vZGUsIGV4aXN0aW5nU3R5bGVzaGVldHNbMF0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoJzxzdHlsZT4nK2RlZmF1bHRTaXplRGVjbGFyYXRpb24rJzxcXC9zdHlsZT4nKTtcbiAgICAgICAgfVxuICAgICAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG4gICAgfVxuXG4gICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY29udGV4dDtcbiAgICB9XG5cbiAgICBzZXQgY29udGV4dChjdHgpIHtcbiAgICAgIHRoaXMuY2xvY2suc3RvcCgpO1xuICAgICAgdGhpcy5fY29udGV4dCA9IGN0eDtcbiAgICAgIHRoaXMuY2xvY2sgPSBuZXcgV0FBQ2xvY2sodGhpcy5jb250ZXh0KTtcbiAgICAgIHRoaXMuY2xvY2suc3RhcnQoKTtcbiAgICB9XG5cblxuXG59XG5cbmxldCBOZXh1cyA9IG5ldyBOZXh1c1VJKCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBjb2xvcnMoKSB7XG4gICAgcmV0dXJuIE5leHVzLmNvbG9ycztcbn1cbmV4cG9ydCBmdW5jdGlvbiBjb250ZXh0KCkge1xuICAgIHJldHVybiBOZXh1cy5jb250ZXh0O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNsb2NrKCkge1xuICAgIHJldHVybiBOZXh1cy5jbG9jaztcbn1cblxuZXhwb3J0IGRlZmF1bHQgTmV4dXM7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbWFpbi5qcyIsImV4cG9ydCBkZWZhdWx0IHtcbiAgUG9zaXRpb246IHJlcXVpcmUoJy4vcG9zaXRpb24nKSxcbiAgU2xpZGVyOiByZXF1aXJlKCcuL3NsaWRlcicpLFxuICBUb2dnbGU6IHJlcXVpcmUoJy4vdG9nZ2xlJyksXG4vKiAgUmFuZ2U6IHJlcXVpcmUoJy4vcmFuZ2VzbGlkZXInKSxcbiAgV2F2ZWZvcm06IHJlcXVpcmUoJy4vd2F2ZWZvcm0nKSwgKi9cbiAgQnV0dG9uOiByZXF1aXJlKCcuL2J1dHRvbicpLFxuICBUZXh0QnV0dG9uOiByZXF1aXJlKCcuL3RleHRidXR0b24nKSxcbiAgUmFkaW9CdXR0b246IHJlcXVpcmUoJy4vcmFkaW9idXR0b24nKSxcbiAgTnVtYmVyOiByZXF1aXJlKCcuL251bWJlcicpLFxuICBTZWxlY3Q6IHJlcXVpcmUoJy4vc2VsZWN0JyksXG4gIERpYWw6IHJlcXVpcmUoJy4vZGlhbCcpLFxuICBQaWFubzogcmVxdWlyZSgnLi9waWFubycpLFxuICBTZXF1ZW5jZXI6IHJlcXVpcmUoJy4vc2VxdWVuY2VyJyksXG4gIFBhbjJEOiByZXF1aXJlKCcuL3BhbjJkJyksXG4gIFRpbHQ6IHJlcXVpcmUoJy4vdGlsdCcpLFxuICBNdWx0aXNsaWRlcjogcmVxdWlyZSgnLi9tdWx0aXNsaWRlcicpLFxuICBQYW46IHJlcXVpcmUoJy4vcGFuJyksXG4gIEVudmVsb3BlOiByZXF1aXJlKCcuL2VudmVsb3BlJyksXG4gIFNwZWN0cm9ncmFtOiByZXF1aXJlKCcuL3NwZWN0cm9ncmFtJyksXG4gIE1ldGVyOiByZXF1aXJlKCcuL21ldGVyJyksXG4gIE9zY2lsbG9zY29wZTogcmVxdWlyZSgnLi9vc2NpbGxvc2NvcGUnKVxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL2luZGV4LmpzIiwiXG4ndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgU3RlcCA9IHJlcXVpcmUoJy4uL21vZGVscy9zdGVwJyk7XG5pbXBvcnQgKiBhcyBJbnRlcmFjdGlvbiBmcm9tICcuLi91dGlsL2ludGVyYWN0aW9uJztcblxuLyoqXG4qIFBvc2l0aW9uXG4qXG4qIEBkZXNjcmlwdGlvbiBUd28tZGltZW5zaW9uYWwgdG91Y2ggc2xpZGVyLlxuKlxuKiBAZGVtbyA8c3BhbiBuZXh1cy11aT1cInBvc2l0aW9uXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcG9zaXRpb24gPSBuZXcgTmV4dXMuUG9zaXRpb24oJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcG9zaXRpb24gPSBuZXcgTmV4dXMuUG9zaXRpb24oJyN0YXJnZXQnLHtcbiogICAnc2l6ZSc6IFsyMDAsMjAwXSxcbiogICAnbW9kZSc6ICdhYnNvbHV0ZScsICAvLyBcImFic29sdXRlXCIgb3IgXCJyZWxhdGl2ZVwiXG4qICAgJ3gnOiAwLjUsICAvLyBpbml0aWFsIHggdmFsdWVcbiogICAnbWluWCc6IDAsXG4qICAgJ21heFgnOiAxLFxuKiAgICdzdGVwWCc6IDAsXG4qICAgJ3knOiAwLjUsICAvLyBpbml0aWFsIHkgdmFsdWVcbiogICAnbWluWSc6IDAsXG4qICAgJ21heFknOiAxLFxuKiAgICdzdGVwWSc6IDBcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgaXMgYW4gb2JqZWN0IHdpdGggeCBhbmQgeSBwcm9wZXJ0aWVzIGNvbnRhaW5pbmcgdGhlIHggYW5kIHkgdmFsdWVzIG9mIHRoZSBpbnRlcmZhY2UuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIHBvc2l0aW9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBvc2l0aW9uIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMjAwLDIwMF0sXG4gICAgICAnbW9kZSc6ICdhYnNvbHV0ZScsXG4gICAgICAnbWluWCc6IDAsXG4gICAgICAnbWF4WCc6IDEsXG4gICAgICAnc3RlcFgnOiAwLFxuICAgICAgJ3gnOiAwLjUsXG4gICAgICAnbWluWSc6IDAsXG4gICAgICAnbWF4WSc6IDEsXG4gICAgICAnc3RlcFknOiAwLFxuICAgICAgJ3knOiAwLjVcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG5cbiAgICB0aGlzLl94ID0gbmV3IFN0ZXAoIHRoaXMuc2V0dGluZ3MubWluWCwgdGhpcy5zZXR0aW5ncy5tYXhYLCB0aGlzLnNldHRpbmdzLnN0ZXBYLCB0aGlzLnNldHRpbmdzLnggKTtcbiAgICB0aGlzLl95ID0gbmV3IFN0ZXAoIHRoaXMuc2V0dGluZ3MubWluWSwgdGhpcy5zZXR0aW5ncy5tYXhZLCB0aGlzLnNldHRpbmdzLnN0ZXBZLCB0aGlzLnNldHRpbmdzLnkgKTtcblxuICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICB4OiBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMuc2V0dGluZ3MubW9kZSwnaG9yaXpvbnRhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKSxcbiAgICAgIHk6IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLCd2ZXJ0aWNhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKVxuICAgIH07XG4gICAgdGhpcy5wb3NpdGlvbi54LnZhbHVlID0gdGhpcy5feC5ub3JtYWxpemVkO1xuICAgIHRoaXMucG9zaXRpb24ueS52YWx1ZSA9IHRoaXMuX3kubm9ybWFsaXplZDtcblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG4gICAgXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgICB0aGlzLnBvc2l0aW9uLngucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG4gICAgICB0aGlzLnBvc2l0aW9uLnkucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG5cbiAgICAgIHRoaXMuX21pbkRpbWVuc2lvbiA9IE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpO1xuXG4gICAgICB0aGlzLmtub2JSYWRpdXMgPSB7XG4gICAgICAgIG9mZjogfn4odGhpcy5fbWluRGltZW5zaW9uLzEwMCkgKiA1ICsgNSxcbiAgICAgIH07XG4gICAgICB0aGlzLmtub2JSYWRpdXMub24gPSB0aGlzLmtub2JSYWRpdXMub2ZmICogMjtcblxuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMud2lkdGgvMik7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQvMik7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JSYWRpdXMub2ZmKTtcbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAodGhpcy5jbGlja2VkKSB7XG4gICAgLy8gIHRoaXMua25vYlJhZGl1cyA9IDMwO1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgncicsdGhpcy5rbm9iUmFkaXVzLm9uKTtcbiAgICB9IGVsc2Uge1xuICAgIC8vICB0aGlzLmtub2JSYWRpdXMgPSAxNTtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYlJhZGl1cy5vZmYpO1xuICAgIH1cblxuICAgIHRoaXMua25vYkNvb3JkaW5hdGVzID0ge1xuICAgICAgeDogdGhpcy5feC5ub3JtYWxpemVkICogdGhpcy53aWR0aCxcbiAgICAgIHk6IHRoaXMuaGVpZ2h0IC0gdGhpcy5feS5ub3JtYWxpemVkICogdGhpcy5oZWlnaHRcbiAgICB9O1xuXG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkNvb3JkaW5hdGVzLngpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmtub2JDb29yZGluYXRlcy55KTtcbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgdGhpcy5wb3NpdGlvbi54LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5wb3NpdGlvbi55LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMucG9zaXRpb24ueC51cGRhdGUodGhpcy5tb3VzZSk7XG4gICAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKHRoaXMubW91c2UpO1xuICAgICAgdGhpcy5feC51cGRhdGVOb3JtYWwoIHRoaXMucG9zaXRpb24ueC52YWx1ZSApO1xuICAgICAgdGhpcy5feS51cGRhdGVOb3JtYWwoIHRoaXMucG9zaXRpb24ueS52YWx1ZSApO1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgeDogdGhpcy5feC52YWx1ZSxcbiAgICAgICAgeTogdGhpcy5feS52YWx1ZVxuICAgICAgfSk7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFRoZSBpbnRlcmZhY2UncyB4IHZhbHVlLiBXaGVuIHNldCwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IGFkanVzdCB0byBmaXQgbWluL21heC9zdGVwIHNldHRpbmdzIG9mIHRoZSBpbnRlcmZhY2UuXG4gICogQHR5cGUge29iamVjdH1cbiAgKiBAZXhhbXBsZSBwb3NpdGlvbi54ID0gMC41O1xuICAqL1xuXG4gIGdldCB4KCkge1xuICAgIHJldHVybiB0aGlzLl94LnZhbHVlO1xuICB9XG5cbiAgc2V0IHgodmFsdWUpIHtcbiAgICB0aGlzLl94LnVwZGF0ZSh2YWx1ZSk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgIHg6IHRoaXMuX3gudmFsdWUsXG4gICAgICB5OiB0aGlzLl95LnZhbHVlXG4gICAgfSk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFRoZSBpbnRlcmZhY2UncyB5IHZhbHVlcy4gV2hlbiBzZXQsIGl0IHdpbGwgYXV0b21hdGljYWxseSBhZGp1c3QgdG8gZml0IG1pbi9tYXgvc3RlcCBzZXR0aW5ncyBvZiB0aGUgaW50ZXJmYWNlLlxuICAqIEB0eXBlIHtvYmplY3R9XG4gICogQGV4YW1wbGUgcG9zaXRpb24ueCA9IDAuNTtcbiAgKi9cblxuICBnZXQgeSgpIHtcbiAgICByZXR1cm4gdGhpcy5feS52YWx1ZTtcbiAgfVxuXG4gIHNldCB5KHZhbHVlKSB7XG4gICAgdGhpcy5feS51cGRhdGUodmFsdWUpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICB4OiB0aGlzLl94LnZhbHVlLFxuICAgICAgeTogdGhpcy5feS52YWx1ZVxuICAgIH0pO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuXG5cbiAgZ2V0IG5vcm1hbGl6ZWQoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHRoaXMuX3gubm9ybWFsaXplZCxcbiAgICAgIHk6IHRoaXMuX3kubm9ybWFsaXplZFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgKiBUaGUgbG93ZXIgbGltaXQgb2YgdmFsdWUgb24gdGhlIHggYXhpc1xuICAqIEB0eXBlIHtvYmplY3R9XG4gICovXG4gIGdldCBtaW5YKCkge1xuICAgIHJldHVybiB0aGlzLl94Lm1pbjtcbiAgfVxuXG4gIHNldCBtaW5YKHYpIHtcbiAgICB0aGlzLl94Lm1pbiA9IHY7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFRoZSBsb3dlciBsaW1pdCBvZiB2YWx1ZSBvbiB0aGUgeSBheGlzXG4gICogQHR5cGUge29iamVjdH1cbiAgKi9cbiAgZ2V0IG1pblkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3kubWluO1xuICB9XG5cbiAgc2V0IG1pblkodikge1xuICAgIHRoaXMuX3kubWluID0gdjtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgKiBUaGUgdXBwZXIgbGltaXQgb2YgdmFsdWUgb24gdGhlIHggYXhpc1xuICAqIEB0eXBlIHtvYmplY3R9XG4gICovXG4gIGdldCBtYXhYKCkge1xuICAgIHJldHVybiB0aGlzLl94Lm1heDtcbiAgfVxuXG4gIHNldCBtYXhYKHYpIHtcbiAgICB0aGlzLl94Lm1heCA9IHY7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gICogVGhlIHVwcGVyIGxpbWl0IG9mIHZhbHVlIG9uIHRoZSB5IGF4aXNcbiAgKiBAdHlwZSB7b2JqZWN0fVxuICAqL1xuICBnZXQgbWF4WSgpIHtcbiAgICByZXR1cm4gdGhpcy5feS5tYXg7XG4gIH1cblxuICBzZXQgbWF4WSh2KSB7XG4gICAgdGhpcy5feS5tYXggPSB2O1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuXG4gIC8qKlxuICAqIFRoZSBpbmNyZW1lbnRhbCBzdGVwIG9mIHZhbHVlcyBvbiB0aGUgeCBheGlzXG4gICogQHR5cGUge29iamVjdH1cbiAgKi9cbiAgZ2V0IHN0ZXBYKCkge1xuICAgIHJldHVybiB0aGlzLl94LnN0ZXA7XG4gIH1cblxuICBzZXQgc3RlcFgodikge1xuICAgIHRoaXMuX3guc3RlcCA9IHY7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gICogVGhlIGluY3JlbWVudGFsIHN0ZXAgb2YgdmFsdWVzIG9uIHRoZSB5IGF4aXNcbiAgKiBAdHlwZSB7b2JqZWN0fVxuICAqL1xuICBnZXQgc3RlcFkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3kuc3RlcDtcbiAgfVxuXG4gIHNldCBzdGVwWSh2KSB7XG4gICAgdGhpcy5feS5zdGVwID0gdjtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgQWJzb2x1dGUgbW9kZSAocG9zaXRpb24ncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJhYnNvbHV0ZVwiLlxuICBAdHlwZSB7c3RyaW5nfVxuICBAZXhhbXBsZSBwb3NpdGlvbi5tb2RlID0gXCJyZWxhdGl2ZVwiO1xuICAqL1xuICBnZXQgbW9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi54Lm1vZGU7XG4gIH1cbiAgc2V0IG1vZGUodikge1xuICAgIHRoaXMucG9zaXRpb24ueC5tb2RlID0gdjtcbiAgICB0aGlzLnBvc2l0aW9uLnkubW9kZSA9IHY7XG4gIH1cblxuXG5cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvcG9zaXRpb24uanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5cbmV4cG9ydCBkZWZhdWx0IHtcblxuICBjcmVhdGU6ICh0eXBlKSA9PiB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCB0eXBlKTtcbiAgfSxcblxuICBhcmM6ICh4LCB5LCByYWRpdXMsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlKSA9PiB7XG5cbiAgICB2YXIgc3RhcnQgPSBtYXRoLnRvQ2FydGVzaWFuKHJhZGl1cywgZW5kQW5nbGUpO1xuICAgIHZhciBlbmQgPSBtYXRoLnRvQ2FydGVzaWFuKHJhZGl1cywgc3RhcnRBbmdsZSk7XG5cbiAgICB2YXIgbGFyZ2VBcmNGbGFnID0gZW5kQW5nbGUgLSBzdGFydEFuZ2xlIDw9IDE4MCA/ICcwJyA6ICcxJztcblxuICAgIHZhciBkID0gW1xuICAgICAgICAnTScsIHN0YXJ0LngreCwgc3RhcnQueSt5LFxuICAgICAgICAnQScsIHJhZGl1cywgcmFkaXVzLCAwLCBsYXJnZUFyY0ZsYWcsIDAsIGVuZC54K3gsIGVuZC55K3lcbiAgICBdLmpvaW4oJyAnKTtcblxuICAgIHJldHVybiBkO1xuICB9LFxuXG4gIHJhZGlhbEdyYWRpZW50OiAoZGVmcyxudW1iZXJPZlN0b3BzKSA9PiB7XG5cbiAgICBsZXQgaWQgPSAnZ3JhZGllbnQnICsgbWF0aC5yaSgxMDAwMDAwMDAwMDApO1xuICAgIGxldCBzdG9wcyA9IFtdO1xuXG4gICAgbGV0IGdyYWRpZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsICdyYWRpYWxHcmFkaWVudCcpO1xuICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZSgnaWQnLCBpZCk7XG4gICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlKCdjeCcsICc1MCUnKTtcbiAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGUoJ2N5JywgJzUwJScpO1xuICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZSgncicsICc1MCUnKTtcblxuICAgIGRlZnMuYXBwZW5kQ2hpbGQoZ3JhZGllbnQpO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8bnVtYmVyT2ZTdG9wcztpKyspIHtcbiAgICAgIGxldCBzdG9wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsICdzdG9wJyk7XG4gICAgICBzdG9wLnNldEF0dHJpYnV0ZSgnaWQnLCAnc3RvcCcraSk7XG4gICAgICAvL3N0b3Auc2V0QXR0cmlidXRlKCdvZmZzZXQnLCAnNzAlJyk7XG4gICAgICAvL3N0b3Auc2V0QXR0cmlidXRlKCdzdG9wLWNvbG9yJywgJ1doaXRlJyk7XG4gICAgICBncmFkaWVudC5hcHBlbmRDaGlsZChzdG9wKTtcbiAgICAgIHN0b3BzLnB1c2goc3RvcCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBpZCxcbiAgICAgIHN0b3BzOiBzdG9wcyxcbiAgICAgIGVsZW1lbnQ6IGdyYWRpZW50XG4gICAgfTtcblxuICB9XG5cbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvdXRpbC9zdmcuanMiLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogTGltaXQgYSBudW1iZXIgdG8gd2l0aGluIGEgbWluaW11bSBhbmQgbWF4aW11bVxuICogQHBhcmFtICB7bnVtYmVyfSB2YWx1ZSBJbnB1dCB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBtaW4gICBMb3dlciBsaW1pdFxuICogQHBhcmFtICB7bnVtYmVyfSBtYXggICBVcHBlciBsaW1pdFxuICogQHJldHVybiB7bnVtYmVyfSAgICAgICBUaGUgaW5wdXQgdmFsdWUgY29uc3RyYWluZWQgd2l0aGluIHRoZSBsb3dlciBhbmQgdXBwZXIgbGltaXRzXG4gKiBAZXhhbXBsZVxuICogTmV4dXMuY2xpcCgxMSwwLDEwKSAgIC8vIHJldHVybnMgMTBcbiAqIE5leHVzLmNsaXAoLTEsMCwxMCkgICAvLyByZXR1cm5zIDBcbiAqIE5leHVzLmNsaXAoNSwwLDEwKSAgICAvLyByZXR1cm5zIDVcbiAqL1xuXG5leHBvcnRzLmNsaXAgPSAodmFsdWUsbWluLG1heCkgPT4ge1xuICByZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgodmFsdWUsbWluKSxtYXgpO1xufTtcblxuZXhwb3J0cy5ub3JtYWxpemUgPSAodmFsdWUsbWluLG1heCkgPT4ge1xuICByZXR1cm4gKCAodmFsdWUtbWluKSAvIChtYXgtbWluKSApO1xufTtcblxuLyoqXG4gKiBTY2FsZSBhIHZhbHVlIGZyb20gb25lIHJhbmdlIHRvIGFub3RoZXIgcmFuZ2UuXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGluTnVtICBJbnB1dCB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBpbk1pbiAgSW5wdXQgcmFuZ2UgbWluaW11bVxuICogQHBhcmFtICB7bnVtYmVyfSBpbk1heCAgSW5wdXQgcmFuZ2UgbWF4aW11bVxuICogQHBhcmFtICB7bnVtYmVyfSBvdXRNaW4gT3V0cHV0IHJhbmdlIG1pbmltdW1cbiAqIEBwYXJhbSAge251bWJlcn0gb3V0TWF4IE91dHB1dCByYW5nZSBtYXhpbXVtXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgICBUaGUgaW5wdXQgdmFsdWUgc2NhbGVkIHRvIGl0cyBuZXcgcmFuZ2VcbiAqIEBleGFtcGxlXG4gKiBOZXh1cy5zY2FsZSgwLjUsMCwxLDAsMTApICAgLy8gcmV0dXJucyA1XG4gKiBOZXh1cy5zY2FsZSgwLjksMCwxLDEsMCkgICAgLy8gcmV0dXJucyAwLjFcbiAqL1xuZXhwb3J0cy5zY2FsZSA9IChpbk51bSwgaW5NaW4sIGluTWF4LCBvdXRNaW4sIG91dE1heCkgPT4ge1xuICBpZiAoaW5NaW4gPT09IGluTWF4KSB7XG4gICAgcmV0dXJuIG91dE1pbjtcbiAgfVxuICByZXR1cm4gKCgoaW5OdW0gLSBpbk1pbikgKiAob3V0TWF4IC0gb3V0TWluKSkgLyAoaW5NYXggLSBpbk1pbikpICsgb3V0TWluO1xufTtcblxuZXhwb3J0cy50b1BvbGFyID0gKHgseSkgPT4ge1xuICB2YXIgciA9IE1hdGguc3FydCh4KnggKyB5KnkpO1xuXG4gIHZhciB0aGV0YSA9IE1hdGguYXRhbjIoeSx4KTtcbiAgaWYgKHRoZXRhIDwgMCkge1xuICAgIHRoZXRhID0gdGhldGEgKyAoMiAqIE1hdGguUEkpO1xuICB9XG4gIHJldHVybiB7cmFkaXVzOiByLCBhbmdsZTogdGhldGF9O1xufTtcblxuZXhwb3J0cy50b0NhcnRlc2lhbiA9IGZ1bmN0aW9uKHJhZGl1cywgYW5nbGUpe1xuICB2YXIgY29zID0gTWF0aC5jb3MoYW5nbGUpO1xuICB2YXIgc2luID0gTWF0aC5zaW4oYW5nbGUpO1xuICByZXR1cm4ge3g6IHJhZGl1cypjb3MsIHk6IHJhZGl1cypzaW4qLTF9O1xufTtcbi8qXG5leHBvcnRzLnBvbGFyVG9DYXJ0ZXNpYW4oY2VudGVyWCwgY2VudGVyWSwgcmFkaXVzLCBhbmdsZUluRGVncmVlcykge1xuICB2YXIgYW5nbGVJblJhZGlhbnMgPSAoYW5nbGVJbkRlZ3JlZXMtOTApICogTWF0aC5QSSAvIDE4MC4wO1xuXG4gIHJldHVybiB7XG4gICAgeDogY2VudGVyWCArIChyYWRpdXMgKiBNYXRoLmNvcyhhbmdsZUluUmFkaWFucykpLFxuICAgIHk6IGNlbnRlclkgKyAocmFkaXVzICogTWF0aC5zaW4oYW5nbGVJblJhZGlhbnMpKVxuICB9O1xufSAgKi9cblxuXG5cbmV4cG9ydHMucHJ1bmUgPSBmdW5jdGlvbihkYXRhLCBzY2FsZSkge1xuICByZXR1cm4gcGFyc2VGbG9hdChkYXRhLnRvRml4ZWQoc2NhbGUpKTtcbn07XG5cbmV4cG9ydHMuaW52ZXJ0ID0gZnVuY3Rpb24gKGluTnVtKSB7XG4gIHJldHVybiBleHBvcnRzLnNjYWxlKGluTnVtLCAxLCAwLCAwLCAxKTtcbn07XG5cbi8qKlxuICogQ29udmVydCBhIE1JRGkgbm90ZSBudW1iZXIgdG8gYSBmcmVxdWVuY3kgdmFsdWUgaW4gZXF1YWwgdGVtcGVyYW1lbnQuXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG1pZGkgTUlESSBub3RlIHZhbHVlXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgRnJlcXVlbmNlIHZhbHVlXG4gKiBAZXhhbXBsZVxuICogTmV4dXMubXRvZig2MCkgIC8vIHJldHVybnMgdGhlIGZyZXF1ZW5jeSBudW1iZXIgb2YgTWlkZGxlIENcbiAqL1xuZXhwb3J0cy5tdG9mID0gZnVuY3Rpb24obWlkaSkge1xuICByZXR1cm4gTWF0aC5wb3coMiwgKChtaWRpLTY5KS8xMikpICogNDQwO1xufTtcblxuLyoqXG4gKiBJbnRlcnBvbGF0ZSBiZXR3ZWVuIHR3byBudW1iZXJzXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGxvYyBJbnRlcnBvbGF0aW9uIGluZGV4ICgwLTEpXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG1pbiBMb3dlciB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBtYXggVXBwZXIgdmFsdWVcbiAqIEByZXR1cm4ge251bWJlcn0gICAgIEludGVycG9sYXRlZCB2YWx1ZVxuICogQGV4YW1wbGVcbiAqIE5leHVzLmludGVycCgwLjUsMiw0KSAgIC8vIHJldHVybnMgM1xuICogTmV4dXMuaW50ZXJwKDAuMSwwLDEwKSAgICAgLy8gcmV0dXJucyAxXG4gKi9cbmV4cG9ydHMuaW50ZXJwID0gZnVuY3Rpb24obG9jLG1pbixtYXgpIHtcbiAgcmV0dXJuIGxvYyAqIChtYXggLSBtaW4pICsgbWluO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYSByYW5kb20gY2hvaWNlIGZyb20gYSBsaXN0IG9mIGFyZ3VtZW50c1xuICogQHJldHVybiB7dmFyaW91c30gT25lIHJhbmRvbSBhcmd1bWVudFxuICogQGV4YW1wbGVcbiAqIE5leHVzLnBpY2soMSwyLDMsNCkgICAvLyByZXR1cm5zIDEsIDIsIDMsIG9yIDRcbiAqIE5leHVzLnBpY2soZnVuY3Rpb24xLGZ1bmN0aW9uMikgICAvLyByZXR1cm5zIGVpdGhlciBmdW5jdGlvbjEgb3IgZnVuY3Rpb24yXG4gKi9cbmV4cG9ydHMucGljayA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gYXJndW1lbnRzW35+KE1hdGgucmFuZG9tKCkqYXJndW1lbnRzLmxlbmd0aCldO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGFuIG9jdGF2ZSBtdWx0aXBsaWVyIGZvciBmcmVxdWVuY3kgdmFsdWVzXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG51bSBSZWxhdGl2ZSBvY3RhdmUgbnVtYmVyIChlLmcuIC0xIGZvciBvbmUgb2N0YXZlIGRvd24sIDEgZm9yIG9uZSBvY3RhdmUgdXApXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICBPY3RhdmUgbXVsdGlwbGllclxuICogQGV4YW1wbGVcbiAqIE5leHVzLm9jdGF2ZSgtMSkgIC8vIHJldHVybnMgMC41XG4gKiBOZXh1cy5vY3RhdmUoMCkgICAvLyByZXR1cm5zIDFcbiAqIE5leHVzLm9jdGF2ZSgxKSAgIC8vIHJldHVybnMgMlxuICogTmV4dXMub2N0YXZlKDIpICAgLy8gcmV0dXJucyA0XG4gKi9cbmV4cG9ydHMub2N0YXZlID0gZnVuY3Rpb24obnVtKSB7XG4gIHJldHVybiBNYXRoLnBvdygyLG51bSk7XG59O1xuXG4vKipcbiAqIFJhbmRvbSBpbnRlZ2VyIGdlbmVyYXRvci4gSWYgbm8gc2Vjb25kIGFyZ3VtZW50IGlzIGdpdmVuLCB3aWxsIHJldHVybiByYW5kb20gaW50ZWdlciBmcm9tIDAgdG8gYm91bmQxLlxuICogQHBhcmFtICB7bnVtYmVyfSBib3VuZDEgTWluaW11bSByYW5kb20gdmFsdWVcbiAqIEBwYXJhbSAge251bWJlcn0gYm91bmQyIE1heGltdW0gcmFuZG9tIHZhbHVlXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgICBSYW5kb20gaW50ZWdlciBiZXR3ZWVuIGxvd2VyIGFuZCB1cHBlciBib3VuZGFyeVxuICogQGV4YW1wbGVcbiAqIE5leHVzLnJpKDEwKSAgICAvLyByZXR1cm5zIHJhbmRvbSBpbnQgZnJvbSAwIHRvIDEwXG4gKiBOZXh1cy5yaSgyMCwyMDAwKSAvLyByZXR1cm5zIHJhbmRvbSBpbnQgZnJvbSAyMCB0byAyMDAwXG4gKi9cbmV4cG9ydHMucmkgPSBmdW5jdGlvbihib3VuZDEsYm91bmQyKSB7XG4gIGlmICghYm91bmQyKSB7XG4gICAgYm91bmQyID0gYm91bmQxO1xuICAgIGJvdW5kMSA9IDA7XG4gIH1cbiAgdmFyIGxvdyA9IE1hdGgubWluKGJvdW5kMSxib3VuZDIpO1xuICB2YXIgaGlnaCA9IE1hdGgubWF4KGJvdW5kMSxib3VuZDIpO1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpKihoaWdoLWxvdykrbG93KTtcbn07XG5cbi8qKlxuICogUmFuZG9tIGZsb2F0IG51bWJlciBnZW5lcmF0b3IuIElmIG5vIHNlY29uZCBhcmd1bWVudCBpcyBnaXZlbiwgd2lsbCByZXR1cm4gcmFuZG9tIGZsb2F0IGZyb20gMCB0byBib3VuZDEuXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGJvdW5kMSBNaW5pbXVtIHJhbmRvbSB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBib3VuZDIgTWF4aW11bSByYW5kb20gdmFsdWVcbiAqIEByZXR1cm4ge251bWJlcn0gICAgICAgIFJhbmRvbSBmbG9hdCBiZXR3ZWVuIGxvd2VyIGFuZCB1cHBlciBib3VuZGFyeVxuICogQGV4YW1wbGVcbiAqIE5leHVzLnJmKDEpICAgIC8vIHJldHVybnMgcmFuZG9tIGZsb2F0IGZyb20gMCB0byAxXG4gKiBOZXh1cy5yZigxLDIpIC8vIHJldHVybnMgcmFuZG9tIGZsb2F0IGZyb20gMSB0byAyXG4gKi9cbmV4cG9ydHMucmYgPSBmdW5jdGlvbihib3VuZDEsYm91bmQyKSB7XG4gIGlmICghYm91bmQyKSB7XG4gICAgYm91bmQyID0gYm91bmQxO1xuICAgIGJvdW5kMSA9IDA7XG4gIH1cbiAgdmFyIGxvdyA9IE1hdGgubWluKGJvdW5kMSxib3VuZDIpO1xuICB2YXIgaGlnaCA9IE1hdGgubWF4KGJvdW5kMSxib3VuZDIpO1xuICByZXR1cm4gTWF0aC5yYW5kb20oKSooaGlnaC1sb3cpK2xvdztcbn07XG5cblxuZXhwb3J0cy5jeWNsZSA9IGZ1bmN0aW9uKGlucHV0LG1pbixtYXgpIHtcbiAgaW5wdXQrKztcbiAgaWYgKGlucHV0ID49IG1heCkge1xuICAgIGlucHV0ID0gbWluO1xuICB9XG4gIHJldHVybiBpbnB1dDtcbn07XG5cbi8qKlxuICogQXZlcmFnZSBhbiBhcnJheSBvZiBudW1iZXJzXG4gKiBAcGFyYW0gIHtBcnJheX0gZGF0YSBBcnJheSBvZiBudW1iZXJzIHRvIGF2ZXJhZ2VcbiAqIEByZXR1cm4ge251bWJlcn0gICAgICBBdmVyYWdlIG9mIHRoZSBpbnB1dCBkYXRhXG4gKiBAZXhhbXBsZVxuICogTmV4dXMuYXZlcmFnZShbMCwyLDQsNiw4LDEwXSkgICAvLyByZXR1cm5zIDVcbiAqL1xuZXhwb3J0cy5hdmVyYWdlID0gZnVuY3Rpb24oZGF0YSkge1xuICBsZXQgdG90YWwgPSAwO1xuICBmb3IgKHZhciBpPTA7aTxkYXRhLmxlbmd0aDtpKyspIHtcbiAgICB0b3RhbCArPSBkYXRhW2ldO1xuICB9XG4gIHJldHVybiB0b3RhbCAvIGRhdGEubGVuZ3RoO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGRpc3RhbmNlIGZyb20gb25lICh4LHkpIHBvaW50IHRvIGFub3RoZXIgKHgseSkgcG9pbnRcbiAqIEBwYXJhbSAge251bWJlcn0geDEgeCBvZiBmaXJzdCBwb2ludFxuICogQHBhcmFtICB7bnVtYmVyfSB5MSB5IG9mIGZpcnN0IHBvaW50XG4gKiBAcGFyYW0gIHtudW1iZXJ9IHgyIHggb2Ygc2Vjb25kIHBvaW50XG4gKiBAcGFyYW0gIHtudW1iZXJ9IHkyIHkgb2Ygc2Vjb25kIHBvaW55XG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgIERpc3RhbmNlXG4gKiBAZXhhbXBsZVxuICogTmV4dXMuZGlzdGFuY2UoMCwwLDMsNCkgICAvLyByZXR1cm5zIDVcbiAqL1xuZXhwb3J0cy5kaXN0YW5jZSA9IGZ1bmN0aW9uKHgxLHkxLHgyLHkyKSB7XG4gIGxldCBhID0geDEgLSB4MjtcbiAgbGV0IGIgPSB5MSAtIHkyO1xuICByZXR1cm4gTWF0aC5zcXJ0KCBhKmEgKyBiKmIgKTtcbn07XG5cbmV4cG9ydHMuZ2FpblRvREIgPSBmdW5jdGlvbihnYWluKSB7XG4gIHJldHVybiAyMCAqIE1hdGgubG9nMTAoZ2Fpbik7XG59O1xuXG4vKipcbiAqIEZsaXAgYSBjb2luLCByZXR1cm5pbmcgZWl0aGVyIDAgb3IgMSBhY2NvcmRpbmcgdG8gYSBwcm9iYWJpbGl0eVxuICogQHBhcmFtICB7bnVtYmVyfSBbb2Rkcz0wLjVdIExpa2VsaWhvb2Qgb2YgcmV0dXJuaW5nIDFcbiAqIEByZXR1cm4ge251bWJlcn0gICAgICAgICAgICAxIG9yIDBcbiAqIEBleGFtcGxlXG4gKiBOZXh1cy5jb2luKDAuMSkgICAvLyByZXR1cm5zIDEgKDEwJSBvZiB0aGUgdGltZSkgb3IgMCAoOTAlIG9mIHRoZSB0aW1lKVxuICovXG5leHBvcnRzLmNvaW4gPSBmdW5jdGlvbihvZGRzPTAuNSkge1xuICBpZiAoZXhwb3J0cy5yZigwLDEpIDwgb2Rkcykge1xuICAgIHJldHVybiAxO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAwO1xuICB9XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3V0aWwvbWF0aC5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgZG9tID0gcmVxdWlyZSgnLi4vdXRpbC9kb20nKTtcbmxldCB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbC91dGlsJyk7XG5sZXQgdG91Y2ggPSByZXF1aXJlKCcuLi91dGlsL3RvdWNoJyk7XG5jb25zdCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKTtcblxuaW1wb3J0IHsgY29sb3JzIH0gZnJvbSAnLi4vbWFpbic7XG5cbi8qKlxuSW50ZXJmYWNlXG4qL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSW50ZXJmYWNlIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcblxuICBjb25zdHJ1Y3RvcihhcmdzLG9wdGlvbnMsZGVmYXVsdHMpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMudHlwZSA9IHRoaXMuY29uc3RydWN0b3IubmFtZTtcbiAgICB0aGlzLnNldHRpbmdzID0gdGhpcy5wYXJzZVNldHRpbmdzKGFyZ3Msb3B0aW9ucyxkZWZhdWx0cyk7XG4gICAgdGhpcy5tb3VzZSA9IHt9O1xuICAgIHRoaXMud2FpdCA9IGZhbHNlO1xuICAgIHRoaXMuY29sb3JzID0ge307XG4gICAgbGV0IGRlZmF1bHRDb2xvcnMgPSBjb2xvcnMoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gICAgdGhpcy5jb2xvcnMuYWNjZW50ID0gZGVmYXVsdENvbG9ycy5hY2NlbnQ7XG4gICAgdGhpcy5jb2xvcnMuZmlsbCA9IGRlZmF1bHRDb2xvcnMuZmlsbDtcbiAgICB0aGlzLmNvbG9ycy5saWdodCA9IGRlZmF1bHRDb2xvcnMubGlnaHQ7XG4gICAgdGhpcy5jb2xvcnMuZGFyayA9IGRlZmF1bHRDb2xvcnMuZGFyaztcbiAgICB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCA9IGRlZmF1bHRDb2xvcnMubWVkaXVtTGlnaHQ7XG4gICAgdGhpcy5jb2xvcnMubWVkaXVtRGFyayA9IGRlZmF1bHRDb2xvcnMubWVkaXVtRGFyaztcbiAgfVxuXG4gIHBhcnNlU2V0dGluZ3MoYXJncyxvcHRpb25zLGRlZmF1bHRzKSB7XG5cbiAgICBvcHRpb25zLnVuc2hpZnQoJ3RhcmdldCcpO1xuICAgIGRlZmF1bHRzLmRlZmF1bHRTaXplID0gZGVmYXVsdHMuc2l6ZS5zcGxpY2UoMCwyKTtcbiAgICBkZWZhdWx0cy5zaXplID0gZmFsc2U7XG5cbiAgICBsZXQgc2V0dGluZ3MgPSB7XG4gICAgICAndGFyZ2V0JzogZG9jdW1lbnQuYm9keSxcbiAgICAgICdjb2xvcnMnOiB7fSwgLy8gc2hvdWxkIGluaGVyaXQgZnJvbSBhIGNvbG9ycyBtb2R1bGUsXG4gICAgICAnc25hcFdpdGhQYXJlbnQnOiB0cnVlLFxuICAgICAgJ2V2ZW50JzogZnVuY3Rpb24oKSB7fSxcbiAgICAgICdjb21wb25lbnQnOiBmYWxzZVxuICAgIH07XG5cbiAgICBmb3IgKGxldCBrZXkgaW4gZGVmYXVsdHMpIHtcbiAgICAgIHNldHRpbmdzW2tleV0gPSBkZWZhdWx0c1trZXldO1xuICAgIH1cblxuICAgIGZvciAobGV0IGk9MDsgaTxhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBncmFicyB0aGUgbmV4dCBhcmd1bWVudFxuICAgICAgbGV0IHNldHRpbmcgPSBhcmdzW2ldO1xuICAgICAgLy8gaWYgaXQncyBhbiBvYmplY3QsIGl0IG11c3QgYmUgdGhlIHNldHRpbmdzIG9iamVjdFxuICAgICAgaWYgKCB1dGlsLmlzT2JqZWN0KHNldHRpbmcpICkge1xuICAgICAgICBmb3IgKCBsZXQga2V5IGluIHNldHRpbmcgKSB7XG4gICAgICAgICAgc2V0dGluZ3Nba2V5XSA9IHNldHRpbmdba2V5XTtcbiAgICAgICAgfVxuICAgICAgLy8gaWYgaXQncyBhIGZ1bmN0aW9uLCBpdCBtdXN0IGJlIHRoZSBldmVudCBzZXR0aW5nXG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXR0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHNldHRpbmdzLmV2ZW50ID0gc2V0dGluZztcbiAgICAgIC8vIG90aGVyd2lzZSwgY29uc2lkZXIgaXQgb25lIG9mIHRoZSB3aWRnZXQncyBjdXN0b20gb3B0aW9uc1xuICAgICAgfSBlbHNlIGlmIChvcHRpb25zLmxlbmd0aD49MSkge1xuICAgICAgICAvLyBncmFiIHRoZSBmaXJzdCBvcHRpb24gLS0gaS5lLiAndGFyZ2V0J1xuICAgICAgICBsZXQga2V5ID0gb3B0aW9ucy5zcGxpY2UoMCwxKVswXTtcbiAgICAgICAgc2V0dGluZ3Nba2V5XSA9IHNldHRpbmc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyogIGhhbmRsZSBjb21tb24gc2V0dGluZ3MgICovXG5cbiAgICAvLyB0YXJnZXRcbiAgICB0aGlzLnBhcmVudCA9IGRvbS5wYXJzZUVsZW1lbnQoc2V0dGluZ3MudGFyZ2V0KTtcblxuICAgIC8vIG5leHVzLXVpIGF0dHJpYnV0ZVxuICAgIGlmICh0aGlzLnBhcmVudCAmJiB0aGlzLnBhcmVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmICFzZXR0aW5ncy5jb21wb25lbnQpIHtcbiAgICAgIGlmICghdGhpcy5wYXJlbnQuaGFzQXR0cmlidXRlKCduZXh1cy11aScpKSB7XG4gICAgICAgIHRoaXMucGFyZW50LnNldEF0dHJpYnV0ZSgnbmV4dXMtdWknLCcnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzaXplXG5cbiAgICBpZiAoc2V0dGluZ3Muc2l6ZSAmJiBBcnJheS5pc0FycmF5KHNldHRpbmdzLnNpemUpICYmIHNldHRpbmdzLnNuYXBXaXRoUGFyZW50KSB7XG4gICAgICB0aGlzLndpZHRoID0gc2V0dGluZ3Muc2l6ZVswXTtcbiAgICAgIHRoaXMuaGVpZ2h0ID0gc2V0dGluZ3Muc2l6ZVsxXTtcbiAgICAgIHRoaXMucGFyZW50LnN0eWxlLndpZHRoID0gdGhpcy53aWR0aCArICdweCc7XG4gICAgICB0aGlzLnBhcmVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmhlaWdodCArICdweCc7XG4gICAgfSBlbHNlIGlmIChzZXR0aW5ncy5zbmFwV2l0aFBhcmVudCAmJiAhc2V0dGluZ3MuY29tcG9uZW50KSB7XG5cbiAgICAgIHRoaXMud2lkdGggPSBwYXJzZUZsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMucGFyZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCd3aWR0aCcpLnJlcGxhY2UoJ3B4JywnJykpO1xuICAgICAgdGhpcy5oZWlnaHQgPSBwYXJzZUZsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMucGFyZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCdoZWlnaHQnKS5yZXBsYWNlKCdweCcsJycpKTtcblxuICAgICAgaWYgKHRoaXMud2lkdGg9PTUwMDApIHtcbiAgICAgICAgdGhpcy53aWR0aCA9IHNldHRpbmdzLmRlZmF1bHRTaXplWzBdO1xuICAgICAgICB0aGlzLnBhcmVudC5zdHlsZS53aWR0aCA9IHRoaXMucGFyZW50LndpZHRoID0gdGhpcy53aWR0aCArICdweCc7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5oZWlnaHQ9PTUwMDApIHtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBzZXR0aW5ncy5kZWZhdWx0U2l6ZVsxXTtcbiAgICAgICAgdGhpcy5wYXJlbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5wYXJlbnQuaGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyAncHgnO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIHNldHRpbmdzLnNpemUgPSBzZXR0aW5ncy5kZWZhdWx0U2l6ZTtcbiAgICAgIHRoaXMud2lkdGggPSBzZXR0aW5ncy5zaXplWzBdO1xuICAgICAgdGhpcy5oZWlnaHQgPSBzZXR0aW5ncy5zaXplWzFdO1xuICAgIH1cblxuICAgIC8vIGV2ZW50XG4gICAgaWYgKHNldHRpbmdzLmV2ZW50KSB7XG4gICAgICB0aGlzLmV2ZW50ID0gdGhpcy5vbignY2hhbmdlJywgc2V0dGluZ3MuZXZlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmV2ZW50ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNldHRpbmdzO1xuXG4gIH1cblxuICBpbml0KCkge1xuICAgIHRoaXMuYnVpbGRGcmFtZSgpO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgICB0aGlzLnNpemVJbnRlcmZhY2UoKTtcbiAgICB0aGlzLmF0dGFjaExpc3RlbmVycygpO1xuICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcbiAgICB0aGlzLmZpbmFsVG91Y2hlcygpO1xuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge31cbiAgc2l6ZUludGVyZmFjZSgpIHt9XG4gIGNvbG9ySW50ZXJmYWNlKCkge31cblxuICBhdHRhY2hMaXN0ZW5lcnMoKSB7XG5cbiAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0ID0gdGhpcy5pbnRlcmFjdGlvblRhcmdldCB8fCB0aGlzLmVsZW1lbnQ7XG5cbiAgICAvLyBTZXR1cCBpbnRlcmFjdGlvblxuICAgIGlmICh0b3VjaC5leGlzdHMpIHtcbiAgICAgIHRoaXMuaW50ZXJhY3Rpb25UYXJnZXQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGV2dCA9PiB0aGlzLnByZVRvdWNoKGV2dCkpO1xuICAgICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCBldnQgPT4gdGhpcy5wcmVUb3VjaE1vdmUoZXZ0KSk7XG4gICAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgZXZ0ID0+IHRoaXMucHJlVG91Y2hSZWxlYXNlKGV2dCkpO1xuICAgIH1cbiAgICB0aGlzLmJvdW5kUHJlTW92ZSA9IGV2dCA9PiB0aGlzLnByZU1vdmUoZXZ0KTtcbiAgICB0aGlzLmJvdW5kUHJlUmVsZWFzZSA9IGV2dCA9PiB0aGlzLnByZVJlbGVhc2UoZXZ0KTtcbiAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGV2dCA9PiB0aGlzLnByZUNsaWNrKGV2dCkpO1xuICB9XG5cbiAgZmluYWxUb3VjaGVzKCkge1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5jdXJzb3IgPSAncG9pbnRlcic7XG4gIH1cblxuICBwcmVDbGljayhlKSB7XG4gICAgLy8gMTAwMDAgZ2V0Q29tcHV0ZWRTdHlsZSBjYWxscyB0YWtlcyAxMDAgbXMuXG4gICAgLy8gLjouIG9uZSB0YWtlcyBhYm91dCAuMDFtc1xuICAgIGlmICh0aGlzLmVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgdGhpcy53aWR0aCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuZWxlbWVudCwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZSgnd2lkdGgnKS5yZXBsYWNlKCdweCcsJycpO1xuICAgIH1cbiAgICAvLyAxMDAwMCBnZXRDb21wdXRlZFN0eWxlIGNhbGxzIHRha2VzIDQwIG1zLlxuICAgIC8vIC46LiBvbmUgdGFrZXMgYWJvdXQgLjAwNG1zXG4gICAgdGhpcy5vZmZzZXQgPSBkb20uZmluZFBvc2l0aW9uKHRoaXMuZWxlbWVudCk7XG4gICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVNb3VzZShlLHRoaXMub2Zmc2V0KTtcbiAgICB0aGlzLmNsaWNrZWQgPSB0cnVlO1xuICAgIHRoaXMuY2xpY2soKTtcbiAgICB0aGlzLm1vdmVFdmVudCA9IGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuYm91bmRQcmVNb3ZlKTtcbiAgICB0aGlzLnJlbGVhc2VFdmVudCA9IGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLmJvdW5kUHJlUmVsZWFzZSk7XG4gICAgdGhpcy5lbWl0KCdjbGljaycpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgcHJlTW92ZShlKSB7XG4gICAgaWYgKCF0aGlzLndhaXQpIHtcbiAgICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSx0aGlzLm9mZnNldCk7XG4gICAgICB0aGlzLm1vdmUoKTtcbiAgICAgIHRoaXMud2FpdCA9IHRydWU7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHsgdGhpcy53YWl0ID0gZmFsc2U7IH0sMjUpO1xuICAgIH1cbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHByZVJlbGVhc2UoZSkge1xuICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSx0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG4gICAgdGhpcy5yZWxlYXNlKCk7XG4gICAgdGhpcy5lbWl0KCdyZWxlYXNlJyk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJyx0aGlzLmJvdW5kUHJlTW92ZSk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsdGhpcy5ib3VuZFByZVJlbGVhc2UpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgY2xpY2soKSB7XG5cbiAgfVxuXG4gIG1vdmUoKSB7XG5cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG5cbiAgfVxuXG5cbiAgLyogdG91Y2ggKi9cblxuICBwcmVUb3VjaChlKSB7XG4gICAgaWYgKHRoaXMuZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICB0aGlzLndpZHRoID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbGVtZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCd3aWR0aCcpLnJlcGxhY2UoJ3B4JywnJyk7XG4gICAgfVxuICAgIHRoaXMub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbih0aGlzLmVsZW1lbnQpO1xuICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlVG91Y2goZSx0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5jbGlja2VkID0gdHJ1ZTtcbiAgICB0aGlzLnRvdWNoKGUpO1xuICAgIHRoaXMuZW1pdCgnY2xpY2snKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHByZVRvdWNoTW92ZShlKSB7XG4gICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVUb3VjaChlLHRoaXMub2Zmc2V0KTtcbiAgICAgIHRoaXMudG91Y2hNb3ZlKCk7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIHByZVRvdWNoUmVsZWFzZShlKSB7XG4gICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVUb3VjaChlLCB0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG4gICAgdGhpcy50b3VjaFJlbGVhc2UoKTtcbiAgICB0aGlzLmVtaXQoJ3JlbGVhc2UnKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHRvdWNoKCkge1xuICAgIHRoaXMuY2xpY2soKTtcbiAgfVxuXG4gIHRvdWNoTW92ZSgpIHtcbiAgICB0aGlzLm1vdmUoKTtcbiAgfVxuXG4gIHRvdWNoUmVsZWFzZSgpIHtcbiAgICB0aGlzLnJlbGVhc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFJlc2l6ZSB0aGUgaW50ZXJmYWNlXG4gICogQHBhcmFtIHdpZHRoIHtudW1iZXJ9IE5ldyB3aWR0aCBpbiBwaXhlbHNcbiAgKiBAcGFyYW0gaGVpZ2h0IHtudW1iZXJ9IE5ldyBoZWlnaHQgaW4gcGl4ZWxzXG4gICpcbiAgKiBAZXhhbXBsZVxuICAqIGJ1dHRvbi5yZXNpemUoMTAwLDEwMCk7XG4gICovXG4gIHJlc2l6ZSh3aWR0aCxoZWlnaHQpIHtcbiAgICB0aGlzLndpZHRoID0gd2lkdGg7XG4gICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgdGhpcy5wYXJlbnQuc3R5bGUud2lkdGggPSB0aGlzLndpZHRoKydweCc7XG4gICAgdGhpcy5wYXJlbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5oZWlnaHQrJ3B4JztcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG4gIH1cblxuICBlbXB0eSgpIHtcbiAgICB3aGlsZSAodGhpcy5lbGVtZW50Lmxhc3RDaGlsZCkge1xuICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudC5sYXN0Q2hpbGQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAqIFJlbW92ZSB0aGUgaW50ZXJmYWNlIGZyb20gdGhlIHBhZ2UgYW5kIGNhbmNlbCBpdHMgZXZlbnQgbGlzdGVuZXIocykuXG4gICpcbiAgKiBAZXhhbXBsZVxuICAqIGJ1dHRvbi5kZXN0cm95KCk7XG4gICovXG4gIGRlc3Ryb3koKSB7XG4gICAgdGhpcy5lbXB0eSgpO1xuICAgIHRoaXMucGFyZW50LnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudCk7XG4gICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICBpZiAodGhpcy5pbnN0cnVtZW50KSB7XG4gICAgICBkZWxldGUgdGhpcy5pbnN0cnVtZW50W3RoaXMuaWRdO1xuICAgIH1cbiAgICB0aGlzLmN1c3RvbURlc3Ryb3koKTtcbiAgfVxuXG4gIGN1c3RvbURlc3Ryb3koKSB7XG5cbiAgfVxuXG4gIGNvbG9yaXplKHR5cGUsY29sb3IpIHtcbiAgICB0aGlzLmNvbG9yc1t0eXBlXSA9IGNvbG9yO1xuICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvY29yZS9pbnRlcmZhY2UuanMiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuZmluZFBvc2l0aW9uID0gKGVsKSA9PiB7XG4gIGxldCB2aWV3cG9ydE9mZnNldCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBsZXQgdG9wID0gdmlld3BvcnRPZmZzZXQudG9wICsgd2luZG93LnNjcm9sbFk7XG4gIGxldCBsZWZ0ID0gdmlld3BvcnRPZmZzZXQubGVmdCArIHdpbmRvdy5zY3JvbGxYO1xuICByZXR1cm4ge3RvcCxsZWZ0fTtcbn07XG5cbmV4cG9ydHMucGFyc2VFbGVtZW50ID0gKHBhcmVudCkgPT4ge1xuICBpZiAodHlwZW9mIHBhcmVudCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChwYXJlbnQucmVwbGFjZSgnIycsJycpKTtcbiAgfVxuXG4gIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCB8fCBwYXJlbnQgaW5zdGFuY2VvZiBTVkdFbGVtZW50KXtcbiAgICByZXR1cm4gcGFyZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAnTm8gdmFsaWQgcGFyZW50IGFyZ3VtZW50JztcbiAgfVxufTtcblxuZXhwb3J0cy5sb2NhdGVNb3VzZSA9IChlLG9mZnNldCkgPT4ge1xuICByZXR1cm4ge1xuICAgIHg6IGUucGFnZVggLSBvZmZzZXQubGVmdCxcbiAgICB5OiBlLnBhZ2VZIC0gb2Zmc2V0LnRvcFxuICB9O1xufTtcblxuZXhwb3J0cy5sb2NhdGVUb3VjaCA9IChlLG9mZnNldCkgPT4ge1xuICByZXR1cm4ge1xuICAgIHg6IGUudGFyZ2V0VG91Y2hlcy5sZW5ndGggPyBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVggLSBvZmZzZXQubGVmdCA6IGZhbHNlLFxuICAgIHk6IGUudGFyZ2V0VG91Y2hlcy5sZW5ndGggPyBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVkgLSBvZmZzZXQudG9wIDogZmFsc2VcbiAgfTtcbn07XG5cbmV4cG9ydHMuU21hcnRDYW52YXMgPSBmdW5jdGlvbihwYXJlbnQpIHtcblxuICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgdGhpcy5jb250ZXh0ID0gdGhpcy5lbGVtZW50LmdldENvbnRleHQoJzJkJyk7XG4gIHBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXG4gIHRoaXMucmVzaXplID0gKHcsaCkgPT4ge1xuICAgIHRoaXMuZWxlbWVudC53aWR0aCA9IHcqMjtcbiAgICB0aGlzLmVsZW1lbnQuaGVpZ2h0ID0gaCoyO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9IHcrJ3B4JztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gaCsncHgnO1xuICB9O1xuXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3V0aWwvZG9tLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLmlzT2JqZWN0ID0gKG9iaikgPT4ge1xuICBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkob2JqKSAmJiBvYmogIT09IG51bGwgJiYgb2JqIGluc3RhbmNlb2YgU1ZHRWxlbWVudCA9PT0gZmFsc2UgJiYgb2JqIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgPT09IGZhbHNlICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi91dGlsL3V0aWwuanMiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuZXhpc3RzID0gKCdvbnRvdWNoc3RhcnQnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvdXRpbC90b3VjaC5qcyIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gIHRoaXMuX2V2ZW50cyA9IHRoaXMuX2V2ZW50cyB8fCB7fTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxuRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24obikge1xuICBpZiAoIWlzTnVtYmVyKG4pIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IFR5cGVFcnJvcignbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcbiAgICBpZiAoIXRoaXMuX2V2ZW50cy5lcnJvciB8fFxuICAgICAgICAoaXNPYmplY3QodGhpcy5fZXZlbnRzLmVycm9yKSAmJiAhdGhpcy5fZXZlbnRzLmVycm9yLmxlbmd0aCkpIHtcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuY2F1Z2h0LCB1bnNwZWNpZmllZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNVbmRlZmluZWQoaGFuZGxlcikpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgICBjYXNlIDE6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICBoYW5kbGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc09iamVjdChoYW5kbGVyKSkge1xuICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBtO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gIGlmICh0aGlzLl9ldmVudHMubmV3TGlzdGVuZXIpXG4gICAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG4gICAgICAgICAgICAgIGlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpID9cbiAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gIGVsc2UgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcbiAgZWxzZVxuICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFt0aGlzLl9ldmVudHNbdHlwZV0sIGxpc3RlbmVyXTtcblxuICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSAmJiAhdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCkge1xuICAgIGlmICghaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSkge1xuICAgICAgbSA9IHRoaXMuX21heExpc3RlbmVycztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGlmIChtICYmIG0gPiAwICYmIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGggPiBtKSB7XG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJyhub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5ICcgK1xuICAgICAgICAgICAgICAgICAgICAnbGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ1VzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO1xuICAgICAgaWYgKHR5cGVvZiBjb25zb2xlLnRyYWNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgaW4gSUUgMTBcbiAgICAgICAgY29uc29sZS50cmFjZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICB2YXIgZmlyZWQgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBnKCkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgZyk7XG5cbiAgICBpZiAoIWZpcmVkKSB7XG4gICAgICBmaXJlZCA9IHRydWU7XG4gICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfVxuXG4gIGcubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgdGhpcy5vbih0eXBlLCBnKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZmYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGxpc3QsIHBvc2l0aW9uLCBsZW5ndGgsIGk7XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgbGlzdCA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgbGVuZ3RoID0gbGlzdC5sZW5ndGg7XG4gIHBvc2l0aW9uID0gLTE7XG5cbiAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8XG4gICAgICAoaXNGdW5jdGlvbihsaXN0Lmxpc3RlbmVyKSAmJiBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuXG4gIH0gZWxzZSBpZiAoaXNPYmplY3QobGlzdCkpIHtcbiAgICBmb3IgKGkgPSBsZW5ndGg7IGktLSA+IDA7KSB7XG4gICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHxcbiAgICAgICAgICAobGlzdFtpXS5saXN0ZW5lciAmJiBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpc3Quc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBrZXksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gIGlmICghdGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChrZXkgaW4gdGhpcy5fZXZlbnRzKSB7XG4gICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGxpc3RlbmVycykpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gIH0gZWxzZSBpZiAobGlzdGVuZXJzKSB7XG4gICAgLy8gTElGTyBvcmRlclxuICAgIHdoaWxlIChsaXN0ZW5lcnMubGVuZ3RoKVxuICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbbGlzdGVuZXJzLmxlbmd0aCAtIDFdKTtcbiAgfVxuICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gW107XG4gIGVsc2UgaWYgKGlzRnVuY3Rpb24odGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICByZXQgPSBbdGhpcy5fZXZlbnRzW3R5cGVdXTtcbiAgZWxzZVxuICAgIHJldCA9IHRoaXMuX2V2ZW50c1t0eXBlXS5zbGljZSgpO1xuICByZXR1cm4gcmV0O1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24odHlwZSkge1xuICBpZiAodGhpcy5fZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgICBpZiAoaXNGdW5jdGlvbihldmxpc3RlbmVyKSlcbiAgICAgIHJldHVybiAxO1xuICAgIGVsc2UgaWYgKGV2bGlzdGVuZXIpXG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gIH1cbiAgcmV0dXJuIDA7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJDb3VudCh0eXBlKTtcbn07XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9ldmVudHMvZXZlbnRzLmpzXG4vLyBtb2R1bGUgaWQgPSAxMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG5cbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5cbi8qKlxuICBDcmVhdGVzIGEgc3RlcHBhYmxlIHZhbHVlIHdpdGggbWluaW11bSwgbWF4aW11bSwgYW5kIHN0ZXAgc2l6ZS4gVGhpcyBpcyB1c2VkIGluIG1hbnkgaW50ZXJmYWNlcyB0byBjb25zdHJpY3QgdGhlaXIgdmFsdWVzIHRvIGNlcnRhaW4gcmFuZ2VzLlxuICBAcGFyYW0ge251bWJlcn0gW21pbj0wXSBtaW5pbXVtXG4gIEBwYXJhbSB7bnVtYmVyfSBbbWF4PTFdIG1heGltdW1cbiAgQHBhcmFtIHtudW1iZXJ9IFtzdGVwPTBdXG4gIEBwYXJhbSB7bnVtYmVyfSBbdmFsdWU9MF0gaW5pdGlhbCB2YWx1ZVxuICBAcmV0dXJucyB7T2JqZWN0fSBTdGVwXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdGVwIHtcblxuICBjb25zdHJ1Y3RvcihtaW4gPSAwLG1heCA9IDEsc3RlcCA9IDAsdmFsdWUgPSAwKSB7XG4gICAgLy9PYmplY3QuYXNzaWduKHRoaXMse21pbixtYXgsc3RlcH0pO1xuICAgIC8vQ2Fubm90IHVzZSBPYmplY3QuYXNzaWduIGJlY2F1c2Ugbm90IHN1cHBvcnRlZCBpbiBTYWZhcmkuXG4gICAgLy9JIHdvdWxkIGV4cGVjdCBmb3IgQmFiZWwgdG8gdGFrZSBjYXJlIG9mIHRoaXMgYnV0IGl0IGlzIG5vdC5cbiAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICB0aGlzLm1heCA9IG1heDtcbiAgICB0aGlzLnN0ZXAgPSBzdGVwO1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmNoYW5nZWQgPSBmYWxzZTtcbiAgICB0aGlzLm9sZFZhbHVlID0gZmFsc2U7XG4gICAgdGhpcy51cGRhdGUodGhpcy52YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICBVcGRhdGUgd2l0aCBhIG5ldyB2YWx1ZS4gVGhlIHZhbHVlIHdpbGwgYmUgYXV0by1hZGp1c3RlZCB0byBmaXQgdGhlIG1pbi9tYXgvc3RlcC5cbiAgICBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAgKi9cblxuICB1cGRhdGUodmFsdWUpIHtcbiAgICBpZiAodGhpcy5zdGVwKSB7XG4gICAgICAvLyB0aGlzLnZhbHVlID0gbWF0aC5jbGlwKE1hdGgucm91bmQodmFsdWUgLyAodGhpcy5zdGVwKSkgKiB0aGlzLnN0ZXAsIHRoaXMubWluLHRoaXMubWF4KTtcbiAgICAgIHRoaXMudmFsdWUgPSBtYXRoLmNsaXAoTWF0aC5yb3VuZCgodmFsdWUtdGhpcy5taW4pIC8gKHRoaXMuc3RlcCkpICogdGhpcy5zdGVwICsgdGhpcy5taW4sIHRoaXMubWluLHRoaXMubWF4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52YWx1ZSA9IG1hdGguY2xpcCh2YWx1ZSx0aGlzLm1pbix0aGlzLm1heCk7XG4gICAgfVxuICAgIGlmICh0aGlzLm9sZFZhbHVlICE9PSB0aGlzLnZhbHVlKSB7XG4gICAgICB0aGlzLm9sZFZhbHVlID0gdGhpcy52YWx1ZTtcbiAgICAgIHRoaXMuY2hhbmdlZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hhbmdlZCA9IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgIFVwZGF0ZSB3aXRoIGEgbm9ybWFsaXplZCB2YWx1ZSAwLTEuXG4gICAgQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gICovXG4gIHVwZGF0ZU5vcm1hbCh2YWx1ZSkge1xuICAgIHRoaXMudmFsdWUgPSBtYXRoLnNjYWxlKHZhbHVlLDAsMSx0aGlzLm1pbix0aGlzLm1heCk7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlKHRoaXMudmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAgR2V0IGEgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIHRoaXMudmFsdWUgLiBOb3Qgc2V0dGFibGUuXG4gICovXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiBtYXRoLm5vcm1hbGl6ZSh0aGlzLnZhbHVlLHRoaXMubWluLHRoaXMubWF4KTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbW9kZWxzL3N0ZXAuanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5pbXBvcnQgVG9nZ2xlTW9kZWwgZnJvbSAnLi4vbW9kZWxzL3RvZ2dsZSc7XG5cblxuLypcbmhvdyB0byB1c2UgOlxuXG5kaWFsLmludGVyYWN0aW9uID0gbmV3IEhhbmRsZSgncmFkaWFsJywncmVsYXRpdmUnLHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpO1xuLy8gZGlhbC5pbnRlcmFjdGlvbi5tb2RlID0gJ3JlbGF0aXZlJ1xuLy8gZGlhbC5pbnRlcmFjdGlvbi5kaXJlY3Rpb24gPSAncmFkaWFsJ1xuXG5vbiBjbGljazpcbmRpYWwuaW50ZXJhY3Rpb24uYW5jaG9yID0gdGhpcy5tb3VzZTtcblxub24gbW92ZTpcbmRpYWwuaW50ZXJhY3Rpb24udXBkYXRlKHRoaXMubW91c2UpO1xuXG5jb25zb2xlLmxvZyggZGlhbC5pbnRlcmFjdGlvbi52YWx1ZSApOyBzaG91bGQgYmUgYSBub3JtYWxpemVkIHZhbHVlLlxuXG4qL1xuXG4vKlxuICBhYnNvbHV0ZS9yZWxhdGl2ZSBhcmUgcHJvcGVydHk6IG1vZGVcbiAgcmFkaWFsL3ZlcnRpY2FsL2hvcml6b250YWwvMmQgYXJlIHByb3BlcnR5OiBkaXJlY3Rpb25cblxuICBwbGFuIDpcblxuICBpZiByZWxhdGl2ZSAtLVxuICBOTyBvbiBjbGljaywgZ2V0IHZhbHVlIG9mZnNldCBiZXR3ZWVuIGN1cnJlbnQgdmFsdWUgYW5kIGNsaWNrIHZhbHVlLlxuICBOTyBvbiBtb3ZlLCB1c2UgY2xpY2sgdmFsdWUgLSBvZmZzZXRcbiAgSU5TVEVBRFxuICB1c2UgZGVsdGEgLS0gYmMgdmVydGljYWwgbW90aW9uIG9uIGRpYWwgaXMgaW1wb3NzaWJsZSBvdGhlcndpc2VcbiAgYWxzbyBhbGxvdyB0byBzZXQgc2Vuc2l0aXZpdHlcblxuKi9cblxuZXhwb3J0IGNsYXNzIEhhbmRsZSB7XG5cbiAgY29uc3RydWN0b3IobW9kZT0nYWJzb2x1dGUnLGRpcmVjdGlvbj0ndmVydGljYWwnLHhib3VuZD1bMCwxMDBdLHlib3VuZD1bMCwxMDBdKSB7XG4gICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICB0aGlzLmRpcmVjdGlvbiA9IGRpcmVjdGlvbjtcbiAgICB0aGlzLnByZXZpb3VzID0gMDtcbiAgICB0aGlzLnZhbHVlID0gMDtcbiAgICB0aGlzLnNlbnNpdGl2aXR5ID0gMTtcbiAgICB0aGlzLnJlc2l6ZSh4Ym91bmQseWJvdW5kKTtcbiAgfVxuXG4gIHJlc2l6ZSh4Ym91bmQseWJvdW5kKSB7XG4gICAgdGhpcy5ib3VuZGFyeSA9IHtcbiAgICAgIG1pbjoge1xuICAgICAgICB4OiB4Ym91bmRbMF0sXG4gICAgICAgIHk6IHlib3VuZFswXVxuICAgICAgfSxcbiAgICAgIG1heDoge1xuICAgICAgICB4OiB4Ym91bmRbMV0sXG4gICAgICAgIHk6IHlib3VuZFsxXVxuICAgICAgfSxcbiAgICAgIGNlbnRlcjoge1xuICAgICAgICB4OiAoeGJvdW5kWzFdIC0geGJvdW5kWzBdKS8yICsgeGJvdW5kWzBdLFxuICAgICAgICB5OiAoeWJvdW5kWzFdIC0geWJvdW5kWzBdKS8yICsgeWJvdW5kWzBdXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHNldCBhbmNob3IobW91c2UpIHtcbiAgICB0aGlzLl9hbmNob3IgPSB0aGlzLmNvbnZlcnRQb3NpdGlvblRvVmFsdWUobW91c2UpO1xuICB9XG5cbiAgZ2V0IGFuY2hvcigpIHtcbiAgICByZXR1cm4gdGhpcy5fYW5jaG9yO1xuICB9XG5cblxuICB1cGRhdGUobW91c2UpIHtcbiAgICBpZiAodGhpcy5tb2RlPT09J3JlbGF0aXZlJykge1xuICAgICAgbGV0IGluY3JlbWVudCA9IHRoaXMuY29udmVydFBvc2l0aW9uVG9WYWx1ZShtb3VzZSkgLSB0aGlzLmFuY2hvcjtcbiAgICAgIGlmIChNYXRoLmFicyhpbmNyZW1lbnQpID4gMC41KSB7IGluY3JlbWVudCA9IDA7IH1cbiAgICAgIHRoaXMuYW5jaG9yID0gbW91c2U7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy52YWx1ZSArIGluY3JlbWVudCAqIHRoaXMuc2Vuc2l0aXZpdHk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLmNvbnZlcnRQb3NpdGlvblRvVmFsdWUobW91c2UpO1xuICAgIH1cbiAgICB0aGlzLnZhbHVlID0gbWF0aC5jbGlwKHRoaXMudmFsdWUsMCwxKTtcbiAgfVxuXG4gIGNvbnZlcnRQb3NpdGlvblRvVmFsdWUoY3VycmVudCkge1xuICAgIHN3aXRjaCh0aGlzLmRpcmVjdGlvbikge1xuICAgICAgY2FzZSAncmFkaWFsJzpcbiAgICAgICAgbGV0IHBvc2l0aW9uID0gbWF0aC50b1BvbGFyKGN1cnJlbnQueCAtIHRoaXMuYm91bmRhcnkuY2VudGVyLngsIGN1cnJlbnQueSAtIHRoaXMuYm91bmRhcnkuY2VudGVyLnkpO1xuICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uLmFuZ2xlIC8gKE1hdGguUEkqMik7XG4gICAgICAgIHBvc2l0aW9uID0gKChwb3NpdGlvbiAtIDAuMjUpICsgMSkgJSAxO1xuICAgICAgICByZXR1cm4gcG9zaXRpb247XG4gICAgICBjYXNlICd2ZXJ0aWNhbCc6XG4gICAgICAgIHJldHVybiBtYXRoLnNjYWxlKGN1cnJlbnQueSx0aGlzLmJvdW5kYXJ5Lm1pbi55LHRoaXMuYm91bmRhcnkubWF4LnksMCwxKTtcbiAgICAgIGNhc2UgJ2hvcml6b250YWwnOlxuICAgICAgICByZXR1cm4gbWF0aC5zY2FsZShjdXJyZW50LngsdGhpcy5ib3VuZGFyeS5taW4ueCx0aGlzLmJvdW5kYXJ5Lm1heC54LDAsMSk7XG4gICAgfVxuICB9XG5cbn1cblxuXG5leHBvcnQgY2xhc3MgQnV0dG9uIHtcblxuICBjb25zdHJ1Y3Rvcihtb2RlPSdidXR0b24nKSB7XG4gICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICB0aGlzLnN0YXRlID0gbmV3IFRvZ2dsZU1vZGVsKCk7XG4gICAgdGhpcy5wYWludGJydXNoID0gZmFsc2U7XG4gIH1cblxuICBjbGljaygpIHtcbiAgICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuICAgICAgY2FzZSAnaW1wdWxzZSc6XG4gICAgICAgIHRoaXMuc3RhdGUub24oKTtcbiAgICAgICAgaWYgKHRoaXMudGltZW91dCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudGltZW91dCA9IHNldFRpbWVvdXQodGhpcy5zdGF0ZS5vZmYuYmluZCh0aGlzKSwzMCk7XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdidXR0b24nOlxuICAgICAgICB0aGlzLnR1cm5PbigpO1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgICB5OiBtYXRoLmNsaXAoMSAtIHRoaXMubW91c2UueSAvIHRoaXMuaGVpZ2h0LDAsMSlcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy50dXJuT24oKTtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG4gICAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd0b2dnbGUnOlxuICAgICAgICB0aGlzLmZsaXAoKTtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgfVxuXG4gIG1vdmUoKSB7XG4gICAgaWYgKHRoaXMubW9kZT09PSdhZnRlcnRvdWNoJykge1xuICAgICAgdGhpcy5wb3NpdGlvbiA9IHtcbiAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICB9O1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgc3dpdGNoICh0aGlzLm1vZGUpIHtcbiAgICAgIGNhc2UgJ2J1dHRvbic6XG4gICAgICAgIHRoaXMudHVybk9mZigpO1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMudHVybk9mZigpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uID0ge1xuICAgICAgICAgIHg6IHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsXG4gICAgICAgICAgeTogMSAtIHRoaXMubW91c2UueSAvIHRoaXMuaGVpZ2h0XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgICAgICAgIHk6IHRoaXMucG9zaXRpb24ueSxcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3V0aWwvaW50ZXJhY3Rpb24uanMiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRvZ2dsZSB7XG5cbiAgY29uc3RydWN0b3Ioc3RhdGUpIHtcbiAgICB0aGlzLnN0YXRlID0gc3RhdGUgfHwgZmFsc2U7XG4gIH1cblxuICBmbGlwKHN0YXRlKSB7XG4gICAgaWYgKHN0YXRlIHx8IHN0YXRlID09PSBmYWxzZSkge1xuICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0YXRlID0gIXRoaXMuc3RhdGU7XG4gICAgfVxuICB9XG5cbiAgb24oKSB7XG4gICAgdGhpcy5zdGF0ZSA9IHRydWU7XG4gIH1cblxuICBvZmYoKSB7XG4gICAgdGhpcy5zdGF0ZSA9IGZhbHNlO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9tb2RlbHMvdG9nZ2xlLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbi8qKlxuKiBTbGlkZXJcbipcbiogQGRlc2NyaXB0aW9uIEhvcml6b250YWwgb3IgdmVydGljYWwgc2xpZGVyIHdpdGggc2V0dGFibGUgaW50ZXJhY3Rpb24gbW9kZXMuXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwic2xpZGVyXCIgc3RlcD0wLjI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc2xpZGVyID0gbmV3IE5leHVzLlNsaWRlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBzbGlkZXIgPSBuZXcgTmV4dXMuU2xpZGVyKCcjdGFyZ2V0Jyx7XG4qICAgICAnc2l6ZSc6IFsxMjAsMjBdLFxuKiAgICAgJ21vZGUnOiAncmVsYXRpdmUnLCAgLy8gJ3JlbGF0aXZlJyBvciAnYWJzb2x1dGUnXG4qICAgICAnbWluJzogMCxcbiogICAgICdtYXgnOiAxLFxuKiAgICAgJ3N0ZXAnOiAwLFxuKiAgICAgJ3ZhbHVlJzogMFxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyB3aGVuIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIEV2ZW50IGRhdGE6IDxpPm51bWJlcjwvaT4gVGhlIG51bWJlciB2YWx1ZSBvZiB0aGUgaW50ZXJmYWNlLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiBzbGlkZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2xpZGVyIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWydtaW4nLCdtYXgnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMTIwLDIwXSxcbiAgICAgICdtb2RlJzogJ3JlbGF0aXZlJywgIC8vICdyZWxhdGl2ZScgb3IgJ2Fic29sdXRlJ1xuICAgICAgJ21pbic6IDAsXG4gICAgICAnbWF4JzogMSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDBcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5vcmllbnRhdGlvbiA9ICd2ZXJ0aWNhbCc7IC8vIFRoaXMgd2lsbCBjaGFuZ2UgYXV0b21hdGljYWxseSB0byAnaG9yaXpvbnRhbCdpZiB0aGUgaW50ZXJmYWNlIGlzIHdpZGVyIHRoYW4gaXQgaXMgdGFsbC5cblxuICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5taW4sIHRoaXMuc2V0dGluZ3MubWF4LCB0aGlzLnNldHRpbmdzLnN0ZXAsIHRoaXMuc2V0dGluZ3MudmFsdWUpO1xuXG4gICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLHRoaXMub3JpZW50YXRpb24sWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbi5kaXJlY3Rpb24gPSB0aGlzLm9yaWVudGF0aW9uO1xuXG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuXG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyID0gc3ZnLmNyZWF0ZSgncmVjdCcpO1xuICAgIHRoaXMuZmlsbGJhciA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmtub2IgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuZmlsbGJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBpZiAodGhpcy53aWR0aCA8IHRoaXMuaGVpZ2h0KSB7XG4gICAgICB0aGlzLm9yaWVudGF0aW9uID0gJ3ZlcnRpY2FsJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcmllbnRhdGlvbiA9ICdob3Jpem9udGFsJztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wb3NpdGlvbikge1xuICAgICAgdGhpcy5wb3NpdGlvbi5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB9XG5cbiAgICBsZXQgeCwgeSwgdywgaCwgYmFyT2Zmc2V0LCBjb3JuZXJSYWRpdXM7XG4gICAgdGhpcy5rbm9iRGF0YSA9IHtcbiAgICAgIGxldmVsOiAwLFxuICAgICAgcjogMFxuICAgIH07XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy50aGlja25lc3MgPSB0aGlzLndpZHRoIC8gMjtcbiAgICBcdHggPSB0aGlzLndpZHRoLzI7XG4gICAgXHR5ID0gMDtcbiAgICBcdHcgPSB0aGlzLnRoaWNrbmVzcztcbiAgICBcdGggPSB0aGlzLmhlaWdodDtcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IGgtdGhpcy5rbm9iRGF0YS5yLXRoaXMubm9ybWFsaXplZCooaC10aGlzLmtub2JEYXRhLnIqMik7XG4gICAgICBiYXJPZmZzZXQgPSAndHJhbnNsYXRlKCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycsMCknO1xuICAgICAgY29ybmVyUmFkaXVzID0gdy8yO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMuaGVpZ2h0IC8gMjtcbiAgICBcdHggPSAwO1xuICAgIFx0eSA9IHRoaXMuaGVpZ2h0LzI7XG4gICAgXHR3ID0gdGhpcy53aWR0aDtcbiAgICBcdGggPSB0aGlzLnRoaWNrbmVzcztcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IHRoaXMubm9ybWFsaXplZCoody10aGlzLmtub2JEYXRhLnIqMikrdGhpcy5rbm9iRGF0YS5yO1xuICAgICAgYmFyT2Zmc2V0ID0gJ3RyYW5zbGF0ZSgwLCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycpJztcbiAgICAgIGNvcm5lclJhZGl1cyA9IGgvMjtcbiAgICB9XG5cbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3gnLHgpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneScseSk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGJhck9mZnNldCk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsY29ybmVyUmFkaXVzKTsgLy8gY29ybmVyIHJhZGl1c1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgncnknLGNvcm5lclJhZGl1cyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3gnLHgpO1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneScsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdyk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgtdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3gnLDApO1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneScseSk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgpO1xuICAgIH1cbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGJhck9mZnNldCk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgncngnLGNvcm5lclJhZGl1cyk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgncnknLGNvcm5lclJhZGl1cyk7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHgpO1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScseSk7XG4gICAgfVxuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYkRhdGEucik7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICB9XG5cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKCF0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzKjAuNzU7XG4gICAgfVxuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYkRhdGEucik7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICBcdCAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLmtub2JEYXRhLnIrdGhpcy5fdmFsdWUubm9ybWFsaXplZCoodGhpcy5oZWlnaHQtdGhpcy5rbm9iRGF0YS5yKjIpO1xuICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmhlaWdodCAtIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3knLHRoaXMuaGVpZ2h0IC0gdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICBcdCAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkKih0aGlzLndpZHRoLXRoaXMua25vYkRhdGEucioyKSt0aGlzLmtub2JEYXRhLnI7XG4gICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3gnLDApO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9XG4gIH1cblxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzKjAuOTtcbiAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMucG9zaXRpb24udXBkYXRlKHRoaXMubW91c2UpO1xuICAgICAgdGhpcy5fdmFsdWUudXBkYXRlTm9ybWFsKCB0aGlzLnBvc2l0aW9uLnZhbHVlICk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5fdmFsdWUudmFsdWUpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuICB9XG5cbiAgLyoqXG4gIFRoZSBzbGlkZXIncyBjdXJyZW50IHZhbHVlLiBJZiBzZXQgbWFudWFsbHksIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgc2xpZGVyLnZhbHVlID0gMTA7XG4gICovXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHYpIHtcbiAgICB0aGlzLl92YWx1ZS51cGRhdGUodik7XG4gICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuX3ZhbHVlLnZhbHVlKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIExvd2VyIGxpbWl0IG9mIHRoZSBzbGlkZXJzJ3Mgb3V0cHV0IHJhbmdlXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNsaWRlci5taW4gPSAxMDAwO1xuICAqL1xuICBnZXQgbWluKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5taW47XG4gIH1cbiAgc2V0IG1pbih2KSB7XG4gICAgdGhpcy5fdmFsdWUubWluID0gdjtcbiAgfVxuXG4gIC8qKlxuICBVcHBlciBsaW1pdCBvZiB0aGUgc2xpZGVyJ3Mgb3V0cHV0IHJhbmdlXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNsaWRlci5tYXggPSAxMDAwO1xuICAqL1xuICBnZXQgbWF4KCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5tYXg7XG4gIH1cbiAgc2V0IG1heCh2KSB7XG4gICAgdGhpcy5fdmFsdWUubWF4ID0gdjtcbiAgfVxuXG4gIC8qKlxuICBUaGUgaW5jcmVtZW50IHRoYXQgdGhlIHNsaWRlcidzIHZhbHVlIGNoYW5nZXMgYnkuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNsaWRlci5zdGVwID0gNTtcbiAgKi9cbiAgZ2V0IHN0ZXAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnN0ZXA7XG4gIH1cbiAgc2V0IHN0ZXAodikge1xuICAgIHRoaXMuX3ZhbHVlLnN0ZXAgPSB2O1xuICB9XG5cbiAgLyoqXG4gIEFic29sdXRlIG1vZGUgKHNsaWRlcidzIHZhbHVlIGp1bXBzIHRvIG1vdXNlIGNsaWNrIHBvc2l0aW9uKSBvciByZWxhdGl2ZSBtb2RlIChtb3VzZSBkcmFnIGNoYW5nZXMgdmFsdWUgcmVsYXRpdmUgdG8gaXRzIGN1cnJlbnQgcG9zaXRpb24pLiBEZWZhdWx0OiBcInJlbGF0aXZlXCIuXG4gIEB0eXBlIHtzdHJpbmd9XG4gIEBleGFtcGxlIHNsaWRlci5tb2RlID0gXCJyZWxhdGl2ZVwiO1xuICAqL1xuICBnZXQgbW9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi5tb2RlO1xuICB9XG4gIHNldCBtb2RlKHYpIHtcbiAgICB0aGlzLnBvc2l0aW9uLm1vZGUgPSB2O1xuICB9XG5cblxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9zbGlkZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IFRvZ2dsZU1vZGVsID0gcmVxdWlyZSgnLi4vbW9kZWxzL3RvZ2dsZScpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5cbi8qKlxuKiBUb2dnbGVcbipcbiogQGRlc2NyaXB0aW9uIEJpbmFyeSBzd2l0Y2hcbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJ0b2dnbGVcIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciB0b2dnbGUgPSBuZXcgTmV4dXMuVG9nZ2xlKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHRvZ2dsZSA9IG5ldyBOZXh1cy5Ub2dnbGUoJyN0YXJnZXQnLHtcbiogICAgICdzaXplJzogWzQwLDIwXSxcbiogICAgICdzdGF0ZSc6IGZhbHNlXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIFBhcmFtZXRlcjogVGhlIGJvb2xlYW4gc3RhdGUgb2YgdGhlIGludGVyZmFjZS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogdG9nZ2xlLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbipcbiovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUb2dnbGUgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3ZhbHVlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFs0MCwyMF0sXG4gICAgICAndGFyZ2V0JzogZmFsc2UsXG4gICAgICAnc3RhdGUnOiBmYWxzZVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLl9zdGF0ZSA9IG5ldyBUb2dnbGVNb2RlbCh0aGlzLnNldHRpbmdzLnN0YXRlKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyID0gc3ZnLmNyZWF0ZSgncmVjdCcpO1xuICAgIHRoaXMua25vYiA9IHN2Zy5jcmVhdGUoJ2NpcmNsZScpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBpZiAodGhpcy5oZWlnaHQgPCB0aGlzLndpZHRoLzIpIHtcbiAgICAgIHRoaXMua25vYlNpemUgPSB0aGlzLmhlaWdodC8yO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmtub2JTaXplID0gdGhpcy53aWR0aC80O1xuICAgIH1cblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneCcsdGhpcy53aWR0aC8yIC0gdGhpcy5rbm9iU2l6ZSoxLjUpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneScsdGhpcy5oZWlnaHQvMiAtIHRoaXMua25vYlNpemUvMik7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsdGhpcy5rbm9iU2l6ZS8yKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3J5Jyx0aGlzLmtub2JTaXplLzIpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnd2lkdGgnLHRoaXMua25vYlNpemUqMyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLHRoaXMua25vYlNpemUpO1xuXG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMud2lkdGgvMiAtIHRoaXMua25vYlNpemUpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmhlaWdodC8yKTtcbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JTaXplKTtcblxuICB9XG5cbiAgY29sb3JJbnRlcmZhY2UoKSB7XG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIgLSB0aGlzLmtub2JTaXplKTtcbiAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeCcsdGhpcy53aWR0aC8yICsgdGhpcy5rbm9iU2l6ZSk7XG4gICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIH1cbiAgfVxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMuZmxpcCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICB9XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIHRvZ2dsZSBpcyBjdXJyZW50bHkgb24gb3Igb2ZmLiBTZXR0aW5nIHRoaXMgcHJvcGVydHkgd2lsbCB1cGRhdGUgdGhlIHRvZ2dsZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge2Jvb2xlYW59XG4gIEBleGFtcGxlIHRvZ2dsZS5zdGF0ZSA9IGZhbHNlO1xuICAqL1xuICBnZXQgc3RhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlLnN0YXRlO1xuICB9XG4gIHNldCBzdGF0ZSh2YWx1ZSkge1xuICAgIHRoaXMuX3N0YXRlLmZsaXAodmFsdWUpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgKiBTd2l0Y2ggdGhlIHRvZ2dsZSBzdGF0ZSB0byBpdHMgb3Bwb3NpdGUgc3RhdGVcbiAgKiBAZXhhbXBsZVxuICAqIHRvZ2dsZS5mbGlwKCk7XG4gICovXG4gIGZsaXAoKSB7XG4gICAgdGhpcy5fc3RhdGUuZmxpcCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvdG9nZ2xlLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBCdXR0b25UZW1wbGF0ZSA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvYnV0dG9udGVtcGxhdGUnKTtcblxuLyoqXG4qIEJ1dHRvblxuKlxuKiBAZGVzY3JpcHRpb24gQ2lyY3VsYXIgYnV0dG9uIHdpdGggb3B0aW9uYWwgYWZ0ZXJ0b3VjaC5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJidXR0b25cIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBidXR0b24gPSBuZXcgTmV4dXMuQnV0dG9uKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIGJ1dHRvbiA9IG5ldyBOZXh1cy5CdXR0b24oJyN0YXJnZXQnLHtcbiogICAnc2l6ZSc6IFs4MCw4MF0sXG4qICAgJ21vZGUnOiAnYWZ0ZXJ0b3VjaCcsXG4qICAgJ3N0YXRlJzogZmFsc2VcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogSW4gPGI+YnV0dG9uIG1vZGU8L2I+LCA8Yj50b2dnbGUgbW9kZTwvYj4sIGFuZCA8Yj5pbXB1bHNlIG1vZGU8L2I+LCB0aGUgb3V0cHV0IGRhdGEgaXMgYSBib29sZWFuIGRlc2NyaWJpbmcgdGhlIHN0YXRlIG9mIHRoZSBidXR0b24uPGJyPlxuKiBJbiA8Yj5hZnRlcnRvdWNoIG1vZGU8L2I+LCB0aGUgb3V0cHV0IGRhdGEgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgeCAoMC0xKSBhbmQgeSAoMC0xKSBwb3NpdGlvbnMgb2YgYWZ0ZXJ0b3VjaC5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogYnV0dG9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICAvLyB2IGlzIHRoZSB2YWx1ZSBvZiB0aGUgYnV0dG9uXG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCdXR0b24gZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnbW9kZSddO1xuXG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFs4MCw4MF0sXG4gICAgICAnbW9kZSc6ICdhZnRlcnRvdWNoJywgLy8gYnV0dG9uLCBhZnRlcnRvdWNoLCBpbXB1bHNlLCB0b2dnbGVcbiAgICAgICdzdGF0ZSc6IGZhbHNlXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuXG4gICAgLyoqXG4gICAgKiBJbnRlcmFjdGlvbiBtb2RlOiBzdXBwb3J0cyBcImJ1dHRvblwiLCBcImFmdGVydG91Y2hcIiwgXCJpbXB1bHNlXCIsIG9yIFwidG9nZ2xlXCJcbiAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgKiBAZXhhbXBsZSBidXR0b24ubW9kZSA9ICd0b2dnbGUnO1xuICAgICovXG4gICAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG4gICAgdGhpcy5wYWQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wYWQpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXG4gICAgLy8gb25seSB1c2VkIGlmIGluICdhZnRlcnRvdWNoJyBtb2RlXG4gICAgdGhpcy5kZWZzID0gc3ZnLmNyZWF0ZSgnZGVmcycpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmRlZnMpO1xuXG4gICAgdGhpcy5ncmFkaWVudCA9IHN2Zy5yYWRpYWxHcmFkaWVudCh0aGlzLmRlZnMsMik7XG5cbiAgICB0aGlzLmdyYWRpZW50LnN0b3BzWzBdLnNldEF0dHJpYnV0ZSgnb2Zmc2V0JywgJzMwJScpO1xuXG4gICAgdGhpcy5ncmFkaWVudC5zdG9wc1sxXS5zZXRBdHRyaWJ1dGUoJ29mZnNldCcsICcxMDAlJyk7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMuaGVpZ2h0LzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgncicsIE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpIC8gMiAtIHRoaXMud2lkdGgvNDApO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJywgdGhpcy53aWR0aC8yMCk7XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuZ3JhZGllbnQuc3RvcHNbMF0uc2V0QXR0cmlidXRlKCdzdG9wLWNvbG9yJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB0aGlzLmdyYWRpZW50LnN0b3BzWzFdLnNldEF0dHJpYnV0ZSgnc3RvcC1jb2xvcicsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKlxuICAqIFVwZGF0ZSB0aGUgdmlzdWFsIGludGVyZmFjZSB1c2luZyBpdHMgY3VycmVudCBzdGF0ZVxuICAqXG4gICogQGV4YW1wbGVcbiAgKiBidXR0b24ucmVuZGVyKCk7XG4gICovXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2UnLCB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLm1vZGU9PT0nYWZ0ZXJ0b3VjaCcpIHtcbiAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2UnLCAndXJsKCMnK3RoaXMuZ3JhZGllbnQuaWQrJyknKTtcbiAgICAgICAgdGhpcy5ncmFkaWVudC5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3gnLCAodGhpcy5wb3NpdGlvbi54KjEwMCkrJyUnKTtcbiAgICAgICAgdGhpcy5ncmFkaWVudC5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3knLCAoKDEtdGhpcy5wb3NpdGlvbi55KSoxMDApKyclJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgICB9XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIH1cbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9idXR0b24uanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IG1hdGggPSByZXF1aXJlKCcuLi91dGlsL21hdGgnKTtcbmxldCBUb2dnbGVNb2RlbCA9IHJlcXVpcmUoJy4uL21vZGVscy90b2dnbGUnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xuXG4vKipcbkJ1dHRvbiBUZW1wbGF0ZVxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnV0dG9uVGVtcGxhdGUgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKGFyZ3Msb3B0aW9ucyxkZWZhdWx0cykge1xuXG4gICAgc3VwZXIoYXJncyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZSB8fCAnYnV0dG9uJztcblxuICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICB4OiAwLFxuICAgICAgeTogMFxuICAgIH07XG5cbiAgICB0aGlzLl9zdGF0ZSA9IG5ldyBUb2dnbGVNb2RlbCh0aGlzLnNldHRpbmdzLnN0YXRlKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG4gICAgdGhpcy5wYWQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAnI2QxOCcpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgJyNkMTgnKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsIDQpO1xuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMucGFkKTtcblxuICAgIHRoaXMuaW50ZXJhY3Rpb25UYXJnZXQgPSB0aGlzLnBhZDtcblxuICAgIHRoaXMuc2l6ZUludGVyZmFjZSgpO1xuICB9XG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMuaGVpZ2h0LzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgncicsIE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpIC8gMiAtIDIpO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5zdGF0ZSkge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuZmlsbCk7XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB9XG4gIH1cblxuICBkb3duKHBhaW50YnJ1c2gpIHtcbiAgICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuICAgICAgY2FzZSAnaW1wdWxzZSc6XG4gICAgICAgIHRoaXMudHVybk9uKCk7XG4gICAgICAgIGlmICh0aGlzLnRpbWVvdXQpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRpbWVvdXQgPSBzZXRUaW1lb3V0KHRoaXMudHVybk9mZi5iaW5kKHRoaXMpLDMwKTtcbiAgICAvLyAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYnV0dG9uJzpcbiAgICAgICAgdGhpcy50dXJuT24oKTtcbiAgICAvLyAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgICB5OiBtYXRoLmNsaXAoMS10aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMudHVybk9uKCk7XG4gICAgLy8gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAvLyAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgIC8vICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgIC8vICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgIC8vICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3RvZ2dsZSc6XG4gICAgICAgIHRoaXMuZmxpcChwYWludGJydXNoKTtcbiAgICAvLyAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICB9XG5cbiAgYmVuZChtb3VzZSkge1xuICAgIGlmICh0aGlzLm1vZGU9PT0nYWZ0ZXJ0b3VjaCcpIHtcbiAgICAgIHRoaXMubW91c2UgPSBtb3VzZSB8fCB0aGlzLm1vdXNlO1xuICAgICAgdGhpcy5wb3NpdGlvbiA9IHtcbiAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICB9O1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIHVwKCkge1xuICAgIHN3aXRjaCAodGhpcy5tb2RlKSB7XG4gICAgICBjYXNlICdidXR0b24nOlxuICAgICAgICB0aGlzLnR1cm5PZmYoKTtcbiAgICAgIC8vICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMudHVybk9mZigpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uID0ge1xuICAgICAgICAgIHg6IG1hdGguY2xpcCh0aGlzLm1vdXNlLnggLyB0aGlzLndpZHRoLDAsMSksXG4gICAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICAgIH07XG4gICAgICAvLyAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgIC8vICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgLy8gICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgICAgLy8gICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgLy8gIH0pO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvKiBvdmVyd3JpdGFibGUgaW50ZXJhY3Rpb24gaGFuZGxlcnMgKi9cblxuICBjbGljaygpIHtcbiAgICB0aGlzLmRvd24oKTtcbiAgfVxuICBtb3ZlKCkge1xuICAgIHRoaXMuYmVuZCgpO1xuICB9XG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy51cCgpO1xuICB9XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIGJ1dHRvbiBpcyBvbiAocHJlc3NlZCkgb3Igb2ZmIChub3QgcHJlc3NlZClcbiAgQHR5cGUge2Jvb2xlYW59XG4gIEBleGFtcGxlIGJ1dHRvbi5zdGF0ZSA9IHRydWU7XG4gICovXG4gIGdldCBzdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGUuc3RhdGU7XG4gIH1cbiAgc2V0IHN0YXRlKHZhbHVlKSB7XG4gICAgdGhpcy5fc3RhdGUuZmxpcCh2YWx1ZSk7XG4gICAgaWYgKHRoaXMubW9kZT09PSdhZnRlcnRvdWNoJykge1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICB9XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBDaGFuZ2UgdGhlIGJ1dHRvbiB0byBpdHMgYWx0ZXJuYXRlIHN0YXRlIChvZmY9Pm9uLCBvbj0+b2ZmKSwgb3IgZmxpcCBpdCB0byBhIHNwZWNpZmllZCBzdGF0ZS5cbiAgQHBhcmFtIHZhbHVlIHtib29sZWFufSAoT3B0aW9uYWwpIFN0YXRlIHRvIGZsaXAgdG8uXG4gIEBleGFtcGxlIGJ1dHRvbi5mbGlwKCk7XG4gICovXG4gIGZsaXAodmFsdWUpIHtcbiAgICB0aGlzLl9zdGF0ZS5mbGlwKHZhbHVlKTtcbiAgICBpZiAodGhpcy5tb2RlPT09J2FmdGVydG91Y2gnKSB7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgICAgICB5OiB0aGlzLnBvc2l0aW9uLnksXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICAgIH1cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIFR1cm4gdGhlIGJ1dHRvbidzIHN0YXRlIHRvIHRydWUuXG4gIEBleGFtcGxlIGJ1dHRvbi50dXJuT24oKTtcbiAgKi9cbiAgdHVybk9uKGVtaXR0aW5nKSB7XG4gICAgdGhpcy5fc3RhdGUub24oKTtcbiAgICBpZiAoZW1pdHRpbmchPT1mYWxzZSkge1xuICAgICAgaWYgKHRoaXMubW9kZT09PSdhZnRlcnRvdWNoJykge1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgICB5OiB0aGlzLnBvc2l0aW9uLnksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIFR1cm4gdGhlIGJ1dHRvbidzIHN0YXRlIHRvIGZhbHNlLlxuICBAZXhhbXBsZSBidXR0b24udHVybk9mZigpO1xuICAqL1xuICB0dXJuT2ZmKGVtaXR0aW5nKSB7XG4gICAgdGhpcy5fc3RhdGUub2ZmKCk7XG4gICAgaWYgKGVtaXR0aW5nIT09ZmFsc2UpIHtcbiAgICAgIGlmICh0aGlzLm1vZGU9PT0nYWZ0ZXJ0b3VjaCcpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG4gICAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvY29tcG9uZW50cy9idXR0b250ZW1wbGF0ZS5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IEJ1dHRvblRlbXBsYXRlID0gcmVxdWlyZSgnLi4vY29tcG9uZW50cy9idXR0b250ZW1wbGF0ZScpO1xuXG4vKipcbiogVGV4dEJ1dHRvblxuKlxuKiBAZGVzY3JpcHRpb24gVGV4dCBidXR0b25cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJ0ZXh0QnV0dG9uXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgdGV4dGJ1dHRvbiA9IG5ldyBOZXh1cy5UZXh0QnV0dG9uKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHRleHRidXR0b24gPSBuZXcgTmV4dXMuVGV4dEJ1dHRvbignI3RhcmdldCcse1xuKiAgICAgJ3NpemUnOiBbMTUwLDUwXSxcbiogICAgICdzdGF0ZSc6IGZhbHNlLFxuKiAgICAgJ3RleHQnOiAnUGxheScsXG4qICAgICAnYWx0ZXJuYXRlVGV4dCc6ICdTdG9wJ1xuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhIDxpPnN0cmluZzwvaT4gb2YgdGhlIHRleHQgb24gdGhlIGJ1dHRvbiBhdCB0aGUgbW9tZW50IGl0IHdhcyBjbGlja2VkLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiB0ZXh0YnV0dG9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRleHRCdXR0b24gZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzE1MCw1MF0sXG4gICAgICAnc3RhdGUnOiBmYWxzZSxcbiAgICAgICd0ZXh0JzogJ1BsYXknXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuX3RleHQgPSB0aGlzLnNldHRpbmdzLnRleHQ7XG5cbiAgICBpZih0aGlzLnNldHRpbmdzLmFsdGVybmF0ZSl7IC8vVE9ETzogUmVtb3ZlIHRoaXMgY29uZGl0aW9uYWwgaW4gYSBicmVha2luZy1jaGFuZ2VzIHJlbGVhc2VcbiAgICAgIHRoaXMuc2V0dGluZ3MuYWx0ZXJuYXRlVGV4dCA9IHRoaXMuc2V0dGluZ3MuYWx0ZXJuYXRlO1xuICAgICAgY29uc29sZS53YXJuKFwiJ2FsdGVybmF0ZScgaW5pdGlhdG9yIGlzIGRlcHJlY2F0ZWQuIFVzZSAnYWx0ZXJuYXRlVGV4dCcgaW5zdGVhZC5cIik7XG4gICAgfVxuICAgIHRoaXMuX2FsdGVybmF0ZVRleHQgPSB0aGlzLnNldHRpbmdzLmFsdGVybmF0ZVRleHQ7XG4gICAgdGhpcy5tb2RlID0gKHRoaXMuc2V0dGluZ3MuYWx0ZXJuYXRlVGV4dCkgPyAndG9nZ2xlJyA6ICdidXR0b24nO1xuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICB0aGlzLnN0YXRlID0gdGhpcy5zZXR0aW5ncy5zdGF0ZTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcblxuICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG5cbiAgICB0aGlzLnRleHRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl90ZXh0O1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnRleHRFbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY29sb3IgPSB0aGlzLmNvbG9ycy5kYXJrO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuICAgICAgbGV0IHRleHRzaXplID0gdGhpcy5oZWlnaHQvMztcbiAgICAgIGxldCB0ZXh0c2l6ZTIgPSAodGhpcy53aWR0aCAvICh0aGlzLl90ZXh0Lmxlbmd0aCArIDIpICk7XG4gICAgICB0ZXh0c2l6ZSA9IE1hdGgubWluKHRleHRzaXplLHRleHRzaXplMik7XG4gICAgICBpZiAodGhpcy5hbHRlcm5hdGVUZXh0KSB7XG4gICAgICAgIGxldCB0ZXh0c2l6ZTMgPSAodGhpcy53aWR0aCAvICh0aGlzLmFsdGVybmF0ZVRleHQubGVuZ3RoICsgMikgKTtcbiAgICAgICAgdGV4dHNpemUgPSBNYXRoLm1pbih0ZXh0c2l6ZSx0ZXh0c2l6ZTMpO1xuICAgICAgfVxuICAgICAgbGV0IHN0eWxlcyA9ICd3aWR0aDogJyArIHRoaXMud2lkdGggKyAncHg7JztcbiAgICAgIHN0eWxlcyArPSAnaGVpZ2h0OiAnICsgdGhpcy5oZWlnaHQgKyAncHg7JztcbiAgICAgIHN0eWxlcyArPSAncGFkZGluZzogJysodGhpcy5oZWlnaHQtdGV4dHNpemUpLzIrJ3B4IDBweDsnO1xuICAgICAgc3R5bGVzICs9ICdib3gtc2l6aW5nOiBib3JkZXItYm94Oyc7XG4gICAgICBzdHlsZXMgKz0gJ3RleHQtYWxpZ246IGNlbnRlcjsnO1xuICAgICAgc3R5bGVzICs9ICdmb250LWZhbWlseTogaW5oZXJpdDsnO1xuICAgICAgc3R5bGVzICs9ICdmb250LXdlaWdodDogNzAwOyc7XG4gICAgICBzdHlsZXMgKz0gJ29wYWNpdHk6IDE7JztcbiAgICAgIHN0eWxlcyArPSAnZm9udC1zaXplOicgKyB0ZXh0c2l6ZSArICdweDsnO1xuICAgICAgdGhpcy50ZXh0RWxlbWVudC5zdHlsZS5jc3NUZXh0ID0gc3R5bGVzO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5maWxsO1xuICAgICAgdGhpcy50ZXh0RWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG4gICAgICB0aGlzLnRleHRFbGVtZW50LmlubmVySFRNTCA9IHRoaXMuX3RleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG4gICAgICB0aGlzLnRleHRFbGVtZW50LnN0eWxlLmNvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICAgIGlmICh0aGlzLmFsdGVybmF0ZVRleHQpIHtcbiAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl9hbHRlcm5hdGVUZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl90ZXh0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICBUaGUgdGV4dCB0byBkaXNwbGF5IHdoZW4gdGhlIGJ1dHRvbiBpcyBpbiBpdHMgXCJvblwiIHN0YXRlLiBJZiBzZXQsIHRoaXMgcHV0cyB0aGUgYnV0dG9uIGluIFwidG9nZ2xlXCIgbW9kZS5cbiAgQHR5cGUge1N0cmluZ31cbiAgKi9cbiAgZ2V0IGFsdGVybmF0ZVRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsdGVybmF0ZVRleHQ7XG4gIH1cblxuICBzZXQgYWx0ZXJuYXRlVGV4dCh0ZXh0KSB7XG4gICAgaWYgKHRleHQpIHtcbiAgICAgIHRoaXMubW9kZSA9ICd0b2dnbGUnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1vZGUgPSAnYnV0dG9uJztcbiAgICB9XG4gICAgdGhpcy5fYWx0ZXJuYXRlVGV4dCA9IHRleHQ7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIFRoZSB0ZXh0IHRvIGRpc3BsYXkuIChJZiAuYWx0ZXJuYXRlVGV4dCBleGlzdHMsIHRoZW4gdGhpcyAudGV4dCB3aWxsIG9ubHkgYmUgZGlzcGxheWVkIHdoZW4gdGhlIGJ1dHRvbiBpcyBpbiBpdHMgXCJvZmZcIiBzdGF0ZS4pXG4gIEB0eXBlIHtTdHJpbmd9XG4gICovXG4gIGdldCB0ZXh0KCkge1xuICAgIHJldHVybiB0aGlzLl90ZXh0O1xuICB9XG5cbiAgc2V0IHRleHQodGV4dCkge1xuICAgIHRoaXMuX3RleHQgPSB0ZXh0O1xuICAgIHRoaXMuc2l6ZUludGVyZmFjZSgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy90ZXh0YnV0dG9uLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG4vL2xldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgQnV0dG9uID0gcmVxdWlyZSgnLi4vaW50ZXJmYWNlcy9idXR0b24nKTtcblxuLyoqXG4qIFJhZGlvQnV0dG9uXG4qXG4qIEBkZXNjcmlwdGlvbiBBbiBhcnJheSBvZiBidXR0b25zLiBCeSBkZWZhdWx0LCBzZWxlY3Rpbmcgb25lIGJ1dHRvbiB3aWxsIGRlc2VsZWN0IGFsbCBvdGhlciBidXR0b25zLCBidXQgdGhpcyBjYW4gYmUgY3VzdG9taXplZCB1c2luZyB0aGUgQVBJIGJlbG93LlxuKlxuKiBAZGVtbyA8ZGl2IG5leHVzLXVpPVwiUmFkaW9CdXR0b25cIj48L2Rpdj5cbipcbiogQGV4YW1wbGVcbiogdmFyIHJhZGlvYnV0dG9uID0gbmV3IE5leHVzLlJhZGlvQnV0dG9uKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHJhZGlvYnV0dG9uID0gbmV3IE5leHVzLlJhZGlvQnV0dG9uKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMTIwLDI1XSxcbiogICAnbnVtYmVyT2ZCdXR0b25zJzogNCxcbiogICAnYWN0aXZlJzogLTFcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgYW4gPGk+aW50ZWdlcjwvaT4sIHRoZSBpbmRleCBvZiB0aGUgYnV0dG9uIHRoYXQgaXMgY3VycmVudGx5IG9uLiBJZiBubyBidXR0b24gaXMgc2VsZWN0ZWQsIHRoZSB2YWx1ZSB3aWxsIGJlIC0xLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiByYWRpb2J1dHRvbi5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSYWRpb0J1dHRvbiBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzEyMCwyNV0sXG4gICAgICAnbnVtYmVyT2ZCdXR0b25zJzogNCxcbiAgICAgICdhY3RpdmUnOiAtMVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLmJ1dHRvbnMgPSBbXTtcbiAgICB0aGlzLl9udW1iZXJPZkJ1dHRvbnMgPSB0aGlzLnNldHRpbmdzLm51bWJlck9mQnV0dG9ucztcbiAgICB0aGlzLmFjdGl2ZSA9IHRoaXMuc2V0dGluZ3MuYWN0aXZlO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLl9udW1iZXJPZkJ1dHRvbnM7aSsrKSB7XG4gICAgICBsZXQgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuXG4gICAgICBsZXQgYnV0dG9uID0gbmV3IEJ1dHRvbihjb250YWluZXIsIHtcbiAgICAgICAgICBtb2RlOiAndG9nZ2xlJyxcbiAgICAgICAgICBjb21wb25lbnQ6IHRydWUsXG4gICAgICAgIH0sIHRoaXMudXBkYXRlLmJpbmQodGhpcyxpKSk7XG5cbiAgICAgIHRoaXMuYnV0dG9ucy5wdXNoKGJ1dHRvbik7XG4gICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgICB9XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBsZXQgYnV0dG9uV2lkdGggPSB0aGlzLndpZHRoIC8gdGhpcy5fbnVtYmVyT2ZCdXR0b25zO1xuICAgIGxldCBidXR0b25IZWlnaHQgPSB0aGlzLmhlaWdodDtcblxuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuX251bWJlck9mQnV0dG9ucztpKyspIHtcbiAgICAgIHRoaXMuYnV0dG9uc1tpXS5yZXNpemUoYnV0dG9uV2lkdGgsYnV0dG9uSGVpZ2h0KTtcbiAgICB9XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuX251bWJlck9mQnV0dG9ucztpKyspIHtcbiAgICAgIHRoaXMuYnV0dG9uc1tpXS5jb2xvcnMgPSB0aGlzLmNvbG9ycztcbiAgICAgIHRoaXMuYnV0dG9uc1tpXS5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGUoaW5kZXgpIHtcbiAgICBpZiAodGhpcy5idXR0b25zW2luZGV4XS5zdGF0ZSkge1xuICAgICAgdGhpcy5zZWxlY3QoaW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlc2VsZWN0KCk7XG4gICAgfVxuICAvLyAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLmJ1dHRvbnMubGVuZ3RoO2krKykge1xuICAgICAgaWYgKGk9PT10aGlzLmFjdGl2ZSkge1xuICAgICAgICB0aGlzLmJ1dHRvbnNbaV0udHVybk9uKGZhbHNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYnV0dG9uc1tpXS50dXJuT2ZmKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgU2VsZWN0IG9uZSBidXR0b24gYW5kIGRlc2VsZWN0IGFsbCBvdGhlciBidXR0b25zLlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBidXR0b24gdG8gc2VsZWN0XG4gICovXG4gIHNlbGVjdChpbmRleCkge1xuICAgIGlmIChpbmRleD49MCAmJiBpbmRleCA8IHRoaXMuYnV0dG9ucy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuYWN0aXZlID0gaW5kZXg7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5hY3RpdmUpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgRGVzZWxlY3QgYWxsIGJ1dHRvbnMuXG4gICovXG4gIGRlc2VsZWN0KCkge1xuICAgIHRoaXMuYWN0aXZlID0gLTE7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuYWN0aXZlKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgZ2V0IG51bWJlck9mQnV0dG9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5fbnVtYmVyT2ZCdXR0b25zO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBob3cgbWFueSBidXR0b25zIGFyZSBpbiB0aGUgaW50ZXJmYWNlXG4gICAqIEBwYXJhbSAge251bWJlcn0gYnV0dG9ucyBIb3cgbWFueSBidXR0b25zIGFyZSBpbiB0aGUgaW50ZXJmYWNlXG4gICAqL1xuICBzZXQgbnVtYmVyT2ZCdXR0b25zKGJ1dHRvbnMpIHtcbiAgICB0aGlzLl9udW1iZXJPZkJ1dHRvbnMgPSBidXR0b25zO1xuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuYnV0dG9ucy5sZW5ndGg7aSsrKSB7XG4gICAgICB0aGlzLmJ1dHRvbnNbaV0uZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLmJ1dHRvbnMgPSBbXTtcbiAgLy8gIGZvciAobGV0IGk9MDtpPHRoaXMuYnV0dG9ucy5sZW5ndGg7aSsrKSB7XG4gIC8vICAgIHRoaXMuYnV0dG9uc1tpXS5kZXN0cm95KCk7XG4gIC8vICB9XG4gICAgdGhpcy5lbXB0eSgpO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9yYWRpb2J1dHRvbi5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgU3RlcCA9IHJlcXVpcmUoJy4uL21vZGVscy9zdGVwJyk7XG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xuXG4vKipcbiogTnVtYmVyXG4qXG4qIEBkZXNjcmlwdGlvbiBOdW1iZXIgaW50ZXJmYWNlIHdoaWNoIGlzIGNvbnRyb2xsYWJsZSBieSBkcmFnZ2luZyBvciB0eXBpbmcuXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwibnVtYmVyXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgbnVtYmVyID0gbmV3IE5leHVzLk51bWJlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBudW1iZXIgPSBuZXcgTmV4dXMuTnVtYmVyKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbNjAsMzBdLFxuKiAgICd2YWx1ZSc6IDAsXG4qICAgJ21pbic6IDAsXG4qICAgJ21heCc6IDIwMDAwLFxuKiAgICdzdGVwJzogMVxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyB0aGUgbnVtYmVyIHZhbHVlIG9mIHRoZSBpbnRlcmZhY2UuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIG51bWJlci5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qXG4qL1xuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE51bWJlciBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzYwLDMwXSxcbiAgICAgICd2YWx1ZSc6IDAsXG4gICAgICAnbWluJzogMCxcbiAgICAgICdtYXgnOiAyMDAwMCxcbiAgICAgICdzdGVwJzogMVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLl92YWx1ZSA9IG5ldyBTdGVwKHRoaXMuc2V0dGluZ3MubWluLHRoaXMuc2V0dGluZ3MubWF4LHRoaXMuc2V0dGluZ3Muc3RlcCx0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIC8qXG4gICAgRGVmYXVsdDogMi4gSG93IG1hbnkgZGVjaW1hbCBwbGFjZXMgdG8gY2xpcCB0aGUgbnVtYmVyJ3MgdmlzdWFsIHJlbmRlcmluZyB0by4gVGhpcyBkb2VzIG5vdCBhZmZlY3QgbnVtYmVyJ3MgYWN0dWFsIHZhbHVlIG91dHB1dCAtLSBmb3IgdGhhdCwgc2V0IHRoZSBzdGVwIHByb3BlcnR5IHRvIC4wMSwgLjEsIG9yIDEuXG4gICAgQHR5cGUge251bWJlcn1cbiAgICBAZXhhbXBsZSBudW1iZXIuZGVjaW1hbFBsYWNlcyA9IDI7XG4gICAgKi9cbiAgICB0aGlzLmRlY2ltYWxQbGFjZXMgPSAyO1xuICAgIHRoaXMuYWN0dWFsID0gMDtcblxuICAgIHRoaXMubWF4ID0gdGhpcy5fdmFsdWUubWF4O1xuXG4gICAgdGhpcy5taW4gPSB0aGlzLl92YWx1ZS5taW47XG5cbiAgICB0aGlzLnN0ZXAgPSB0aGlzLl92YWx1ZS5zdGVwO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgIHRoaXMuZWxlbWVudC50eXBlID0gJ3RleHQnO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCBmdW5jdGlvbiAoKSB7XG4gIFx0ICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgXHQgIHRoaXMuZWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG4gIFx0ICBpZiAodGhpcy5lbGVtZW50LnZhbHVlICE9PSB0aGlzLnZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBwYXJzZUZsb2F0KHRoaXMuZWxlbWVudC52YWx1ZSk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gIFx0ICB9XG4gIFx0fS5iaW5kKHRoaXMpKTtcblxuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBmdW5jdGlvbiAoZSkge1xuICBcdCAgaWYgKGUud2hpY2ggPCA0OCB8fCBlLndoaWNoID4gNTcpIHtcbiAgXHQgIFx0aWYgKGUud2hpY2ggIT09IDE4OSAmJiBlLndoaWNoICE9PSAxOTAgJiYgZS53aGljaCAhPT0gOCkge1xuICBcdCAgXHRcdGUucHJldmVudERlZmF1bHQoKTtcbiAgXHQgIFx0fVxuICBcdCAgfVxuICBcdCAgaWYgKGUud2hpY2g9PT0xMykge1xuICBcdCAgXHR0aGlzLmVsZW1lbnQuYmx1cigpO1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5lbGVtZW50LnZhbHVlO1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gIFx0ICB9XG4gIFx0fS5iaW5kKHRoaXMpKTtcblxuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLl9taW5EaW1lbnNpb24gPSBNYXRoLm1pbih0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcblxuICAgIGxldCBzdHlsZXMgPSAnd2lkdGg6ICcgKyB0aGlzLndpZHRoICsgJ3B4Oyc7XG4gICAgc3R5bGVzICs9ICdoZWlnaHQ6ICcgKyB0aGlzLmhlaWdodCArICdweDsnO1xuICAgIHN0eWxlcyArPSAnYmFja2dyb3VuZC1jb2xvcjogI2U3ZTdlNzsnO1xuICAgIHN0eWxlcyArPSAnY29sb3I6ICMzMzM7JztcbiAgICBzdHlsZXMgKz0gJ2ZvbnQtZmFtaWx5OiBhcmlhbDsnO1xuICAgIHN0eWxlcyArPSAnZm9udC13ZWlnaHQ6IDUwMDsnO1xuICAgIHN0eWxlcyArPSAnZm9udC1zaXplOicgKyB0aGlzLl9taW5EaW1lbnNpb24vMiArICdweDsnO1xuICAvLyAgc3R5bGVzICs9ICdoaWdobGlnaHQ6ICNkMTg7JztcbiAgICBzdHlsZXMgKz0gJ2JvcmRlcjogbm9uZTsnO1xuICAgIHN0eWxlcyArPSAnb3V0bGluZTogbm9uZTsnO1xuICAgIHN0eWxlcyArPSAncGFkZGluZzogJyt0aGlzLl9taW5EaW1lbnNpb24vNCsncHggJyt0aGlzLl9taW5EaW1lbnNpb24vNCsncHg7JztcbiAgICBzdHlsZXMgKz0gJ2JveC1zaXppbmc6IGJvcmRlci1ib3g7JztcbiAgICBzdHlsZXMgKz0gJ3VzZXJTZWxlY3Q6IHRleHQ7JztcbiAgICBzdHlsZXMgKz0gJ21velVzZXJTZWxlY3Q6IHRleHQ7JztcbiAgICBzdHlsZXMgKz0gJ3dlYmtpdFVzZXJTZWxlY3Q6IHRleHQ7JztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY3NzVGV4dCArPSBzdHlsZXM7XG5cbiAgICAvLyB0byBhZGQgZXZlbnR1YWxseVxuICAgIC8vIHZhciBjc3MgPSAnIycrdGhpcy5lbGVtZW50SUQrJzo6c2VsZWN0aW9ueyBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudCB9JztcblxuICAgIHRoaXMuZWxlbWVudC52YWx1ZSA9IHRoaXMudmFsdWU7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY29sb3IgPSB0aGlzLmNvbG9ycy5kYXJrO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuXG4gICAgdGhpcy5lbGVtZW50LnZhbHVlID0gbWF0aC5wcnVuZSh0aGlzLnZhbHVlLHRoaXMuZGVjaW1hbFBsYWNlcyk7XG5cbiAgfVxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMuaGFzTW92ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmVsZW1lbnQucmVhZE9ubHkgPSB0cnVlO1xuXHQgIHRoaXMuYWN0dWFsID0gdGhpcy52YWx1ZTtcbiAgICB0aGlzLmluaXRpYWwgPSB7IHk6IHRoaXMubW91c2UueSB9O1xuICAgIHRoaXMuY2hhbmdlRmFjdG9yID0gbWF0aC5pbnZlcnQoIHRoaXMubW91c2UueCAvIHRoaXMud2lkdGggKTtcbiAgICBjb25zb2xlLmxvZyh0aGlzLmNoYW5nZUZhY3Rvcik7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIHRoaXMuaGFzTW92ZWQgPSB0cnVlO1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcblxuICAgICAgbGV0IG5ld3ZhbHVlID0gdGhpcy5hY3R1YWwgLSAodGhpcy5tb3VzZS55IC0gdGhpcy5pbml0aWFsLnkpICogKCBtYXRoLmNsaXAoIHRoaXMubWF4LXRoaXMubWluLCAwLCAxMDAwICkgLyAyMDAgKSAqIE1hdGgucG93KHRoaXMuY2hhbmdlRmFjdG9yLDIpO1xuICAgICAgdGhpcy52YWx1ZSA9IG5ld3ZhbHVlO1xuXG4gIFx0XHR0aGlzLnJlbmRlcigpO1xuICAgICAgaWYgKHRoaXMuX3ZhbHVlLmNoYW5nZWQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuICAgICAgfVxuXG4gIFx0fVxuICB9XG5cbiAgcmVsZWFzZSgpIHtcbiAgICBpZiAoIXRoaXMuaGFzTW92ZWQpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5yZWFkT25seSA9IGZhbHNlO1xuICBcdFx0dGhpcy5lbGVtZW50LmZvY3VzKCk7XG4gIFx0XHR0aGlzLmVsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UoMCwgdGhpcy5lbGVtZW50LnZhbHVlLmxlbmd0aCk7XG4gIFx0XHR0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuICBcdFx0dGhpcy5lbGVtZW50LnN0eWxlLmNvbG9yID0gdGhpcy5jb2xvcnMubGlnaHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRvY3VtZW50LmJvZHkuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgQ29ubmVjdCB0aGlzIG51bWJlciBpbnRlcmZhY2UgdG8gYSBkaWFsIG9yIHNsaWRlclxuICBAcGFyYW0ge0ludGVyZmFjZX0gZWxlbWVudCBFbGVtZW50IHRvIGNvbm5lY3QgdG8uXG4gIEBleGFtcGxlIG51bWJlci5saW5rKHNsaWRlcilcbiAgKi9cbiAgbGluayhkZXN0aW5hdGlvbikge1xuICAgIHRoaXMubWluID0gZGVzdGluYXRpb24ubWluO1xuICAgIHRoaXMubWF4ID0gZGVzdGluYXRpb24ubWF4O1xuICAgIHRoaXMuc3RlcCA9IGRlc3RpbmF0aW9uLnN0ZXA7XG4gICAgZGVzdGluYXRpb24ub24oJ2NoYW5nZScsKHYpID0+IHtcbiAgICAgIHRoaXMucGFzc2l2ZVVwZGF0ZSh2KTtcbiAgICB9KTtcbiAgICB0aGlzLm9uKCdjaGFuZ2UnLCh2KSA9PiB7XG4gICAgICBkZXN0aW5hdGlvbi52YWx1ZSA9IHY7XG4gICAgfSk7XG4gICAgdGhpcy52YWx1ZSA9IGRlc3RpbmF0aW9uLnZhbHVlO1xuICAvKiAgcmV0dXJuIHtcbiAgICAgIGxpc3RlbmVyMTogbGlzdGVuZXIxLFxuICAgICAgbGlzdGVuZXIyOiBsaXN0ZW5lcjIsXG4gICAgICBkZXN0cm95OiAoKSA9PiB7XG4gICAgICAgIGxpc3RlbmVyMS5yZW1vdmUoKSAob3Igc2ltaWxhcilcbiAgICAgICAgbGlzdGVuZXIyLnJlbW92ZSgpIChvciBzaW1pbGFyKVxuICAgICAgfVxuICAgIH0gKi9cbiAgfVxuXG4gIHBhc3NpdmVVcGRhdGUodikge1xuICAgIHRoaXMuX3ZhbHVlLnVwZGF0ZSh2KTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIFRoZSBpbnRlcmZhY2UncyBjdXJyZW50IHZhbHVlLiBJZiBzZXQgbWFudWFsbHksIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgbnVtYmVyLnZhbHVlID0gMTA7XG4gICovXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHYpIHtcbiAgICB0aGlzLl92YWx1ZS51cGRhdGUodik7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKipcbiAgTG93ZXIgbGltaXQgb2YgdGhlIG51bWJlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBudW1iZXIubWluID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1pbigpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWluO1xuICB9XG4gIHNldCBtaW4odikge1xuICAgIHRoaXMuX3ZhbHVlLm1pbiA9IHY7XG4gIH1cblxuICAvKipcbiAgVXBwZXIgbGltaXQgb2YgdGhlIG51bWJlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBudW1iZXIubWF4ID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWF4O1xuICB9XG4gIHNldCBtYXgodikge1xuICAgIHRoaXMuX3ZhbHVlLm1heCA9IHY7XG4gIH1cblxuICAvKipcbiAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBudW1iZXIncyB2YWx1ZSBjaGFuZ2VzIGJ5LlxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBudW1iZXIuc3RlcCA9IDU7XG4gICovXG4gIGdldCBzdGVwKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5zdGVwO1xuICB9XG4gIHNldCBzdGVwKHYpIHtcbiAgICB0aGlzLl92YWx1ZS5zdGVwID0gdjtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9udW1iZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xuXG4vKipcbiogU2VsZWN0XG4qXG4qIEBkZXNjcmlwdGlvbiBEcm9wZG93biBtZW51XG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwic2VsZWN0XCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc2VsZWN0ID0gbmV3IE5leHVzLlNlbGVjdCgnI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBzZWxlY3QgPSBuZXcgTmV4dXMuU2VsZWN0KCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMTAwLDMwXSxcbiogICAnb3B0aW9ucyc6IFsnZGVmYXVsdCcsJ29wdGlvbnMnXVxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgdGV4dCB2YWx1ZSBvZiB0aGUgc2VsZWN0ZWQgb3B0aW9uLCBhcyB3ZWxsIGFzIHRoZSBudW1lcmljIGluZGV4IG9mIHRoZSBzZWxlY3Rpb24uXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIHNlbGVjdC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qXG4qL1xuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNlbGVjdCBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICAnc2l6ZSc6IFsxMDAsMzBdLFxuICAgICAgICdvcHRpb25zJzogWydkZWZhdWx0Jywnb3B0aW9ucyddXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSAtMTtcbiAgICB0aGlzLl92YWx1ZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5fb3B0aW9ucyA9IHRoaXMuc2V0dGluZ3Mub3B0aW9ucztcblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2VsZWN0Jyk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmZvbnRTaXplID0gdGhpcy5oZWlnaHQvMisncHgnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5vdXRsaW5lID0gJ25vbmUnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5oaWdobGlnaHQgPSAnbm9uZSc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLndpZHRoID0gdGhpcy53aWR0aCsncHgnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmhlaWdodCsncHgnO1xuXG4gICAgdGhpcy5ib3VuZFJlbmRlciA9IHRoaXMucmVuZGVyLmJpbmQodGhpcyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5ib3VuZFJlbmRlcik7XG5cbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXG4gIH1cblxuICBhdHRhY2hMaXN0ZW5lcnMoKSB7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5kZWZpbmVPcHRpb25zKCk7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5maWxsO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmJvcmRlciA9ICdzb2xpZCAwcHggJyt0aGlzLmNvbG9ycy5tZWRpdW1MaWdodDtcbiAgfVxuXG4gIHJlbmRlcigpIHtcblxuICAgIHRoaXMuX3ZhbHVlID0gdGhpcy5lbGVtZW50Lm9wdGlvbnNbdGhpcy5lbGVtZW50LnNlbGVjdGVkSW5kZXhdLnRleHQ7XG4gICAgdGhpcy5fc2VsZWN0ZWRJbmRleCA9IHRoaXMuZWxlbWVudC5zZWxlY3RlZEluZGV4O1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICB2YWx1ZTogdGhpcy5fdmFsdWUsXG4gICAgICBpbmRleDogdGhpcy5fc2VsZWN0ZWRJbmRleFxuICAgIH0pO1xuXG4gIH1cblxuICBjbGljaygpIHtcblxuICB9XG5cbiAgbW92ZSgpIHtcblxuICB9XG5cbiAgcmVsZWFzZSgpIHtcblxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgbGlzdCBvZiBvcHRpb25zLiBUaGlzIHJlbW92ZXMgYWxsIGV4aXN0aW5nIG9wdGlvbnMgYW5kIGNyZWF0ZXMgYSBuZXcgbGlzdCBvZiBvcHRpb25zLlxuICAgKiBAcGFyYW0gIHthcnJheX0gb3B0aW9ucyBOZXcgYXJyYXkgb2Ygb3B0aW9uc1xuICAgKi9cblxuICBkZWZpbmVPcHRpb25zKG9wdGlvbnMpIHtcblxuICAvKiAgZnVuY3Rpb24gcmVtb3ZlT3B0aW9ucyhzZWxlY3Rib3gpXG4gICAge1xuICAgICAgICB2YXIgaTtcbiAgICAgICAgZm9yKGkgPSBzZWxlY3Rib3gub3B0aW9ucy5sZW5ndGggLSAxIDsgaSA+PSAwIDsgaS0tKVxuICAgICAgICB7XG4gICAgICAgICAgICBzZWxlY3Rib3gucmVtb3ZlKGkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vdXNpbmcgdGhlIGZ1bmN0aW9uOlxuICAgIHJlbW92ZU9wdGlvbnMoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJteVNlbGVjdE9iamVjdFwiKSk7ICovXG5cblxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcbiAgICB9XG5cbiAgICBmb3IobGV0IGk9dGhpcy5lbGVtZW50Lm9wdGlvbnMubGVuZ3RoLTE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB0aGlzLmVsZW1lbnQucmVtb3ZlKGkpO1xuICAgIH1cblxuICAgIGZvcihsZXQgaT0wO2k8dGhpcy5fb3B0aW9ucy5sZW5ndGg7aSsrKSB7XG4gICAgICB0aGlzLmVsZW1lbnQub3B0aW9ucy5hZGQobmV3IE9wdGlvbih0aGlzLl9vcHRpb25zW2ldLCBpKSk7XG4gICAgfVxuXG4gIH1cblxuXG4gIC8qKlxuICBUaGUgdGV4dCBvZiB0aGUgb3B0aW9uIHRoYXQgaXMgY3VycmVudGx5IHNlbGVjdGVkLiBJZiBzZXQsIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge1N0cmluZ31cbiAgQGV4YW1wbGUgc2VsZWN0LnZhbHVlID0gXCJzYXd0b290aFwiO1xuICAqL1xuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICB9XG4gIHNldCB2YWx1ZSh2KSB7XG4gICAgdGhpcy5fdmFsdWUgPSB2O1xuICAgIGZvcihsZXQgaT0wO2k8dGhpcy5lbGVtZW50Lm9wdGlvbnMubGVuZ3RoO2krKykge1xuICAgICAgaWYgKHYgPT09IHRoaXMuZWxlbWVudC5vcHRpb25zW2ldLnRleHQpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgVGhlIG51bWVyaWMgaW5kZXggb2YgdGhlIG9wdGlvbiB0aGF0IGlzIGN1cnJlbnRseSBzZWxlY3RlZC4gSWYgc2V0LCB3aWxsIHVwZGF0ZSB0aGUgaW50ZXJmYWNlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNlbGVjdC5zZWxlY3RlZEluZGV4ID0gMjtcbiAgKi9cbiAgZ2V0IHNlbGVjdGVkSW5kZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkSW5kZXg7XG4gIH1cbiAgc2V0IHNlbGVjdGVkSW5kZXgodikge1xuICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSB2O1xuICAgIHRoaXMuZWxlbWVudC5zZWxlY3RlZEluZGV4ID0gdjtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5ib3VuZFJlbmRlcik7XG4gIH1cblxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9zZWxlY3QuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IG1hdGggPSByZXF1aXJlKCcuLi91dGlsL21hdGgnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbi8qKlxuKiBEaWFsXG4qXG4qXG4qIEBkZXNjcmlwdGlvbiBEaWFsIHdpdGggcmFkaWFsIG9yIGxpbmVhciBpbnRlcmFjdGlvbi5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJkaWFsXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgZGlhbCA9IG5ldyBOZXh1cy5EaWFsKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIGRpYWwgPSBuZXcgTmV4dXMuRGlhbCgnI3RhcmdldCcse1xuKiAgICdzaXplJzogWzc1LDc1XSxcbiogICAnaW50ZXJhY3Rpb24nOiAncmFkaWFsJywgLy8gXCJyYWRpYWxcIiwgXCJ2ZXJ0aWNhbFwiLCBvciBcImhvcml6b250YWxcIlxuKiAgICdtb2RlJzogJ3JlbGF0aXZlJywgLy8gXCJhYnNvbHV0ZVwiIG9yIFwicmVsYXRpdmVcIlxuKiAgICdtaW4nOiAwLFxuKiAgICdtYXgnOiAxLFxuKiAgICdzdGVwJzogMCxcbiogICAndmFsdWUnOiAwXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIFRoZSBldmVudCBkYXRhIGlzIHRoZSBudW1iZXIgdmFsdWUgb2YgdGhlIGludGVyZmFjZS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogZGlhbC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qIEB0dXRvcmlhbFxuKiBEaWFsXG4qIHlnR014cVxuKlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGlhbCBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnbWluJywnbWF4JywndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzc1LDc1XSxcbiAgICAgICdpbnRlcmFjdGlvbic6ICdyYWRpYWwnLCAvLyByYWRpYWwsIHZlcnRpY2FsLCBob3Jpem9udGFsXG4gICAgICAnbW9kZSc6ICdyZWxhdGl2ZScsIC8vIGFic29sdXRlLCByZWxhdGl2ZVxuICAgICAgJ21pbic6IDAsXG4gICAgICAnbWF4JzogMSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDBcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvbiA9IHRoaXMuc2V0dGluZ3MuaW50ZXJhY3Rpb247XG5cbiAgICB0aGlzLl92YWx1ZSA9IG5ldyBTdGVwKHRoaXMuc2V0dGluZ3MubWluLCB0aGlzLnNldHRpbmdzLm1heCwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIHRoaXMucG9zaXRpb24gPSBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMuc2V0dGluZ3MubW9kZSx0aGlzLmludGVyYWN0aW9uLFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG5cbiAgICB0aGlzLmluaXQoKTtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblxuICAgIHRoaXMucG9zaXRpb24udmFsdWUgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXG4gICAgdGhpcy5wcmV2aW91c0FuZ2xlID0gZmFsc2U7XG5cbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5iYWNrZ3JvdW5kID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG4gICAgdGhpcy5zY3JldyA9IHN2Zy5jcmVhdGUoJ2NpcmNsZScpO1xuICAgIHRoaXMuaGFuZGxlID0gc3ZnLmNyZWF0ZSgncGF0aCcpO1xuICAgIHRoaXMuaGFuZGxlMiA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmhhbmRsZUZpbGwgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG4gICAgdGhpcy5oYW5kbGUyRmlsbCA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmhhbmRsZUxpbmUgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYWNrZ3JvdW5kKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5oYW5kbGUpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZTIpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZUZpbGwpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZTJGaWxsKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5oYW5kbGVMaW5lKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5zY3Jldyk7XG5cbiAgfVxuXG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcblxuICAgIHRoaXMucG9zaXRpb24ucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG5cbiAgICBsZXQgY2VudGVyID0ge1xuICAgICAgeDogdGhpcy53aWR0aC8yLFxuICAgICAgeTogdGhpcy5oZWlnaHQvMlxuICAgIH07XG5cbiAgICBsZXQgZGlhbWV0ZXIgPSBNYXRoLm1pbih0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcblxuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ2N4JywgY2VudGVyLngpO1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ2N5JywgY2VudGVyLnkpO1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ3InLCBkaWFtZXRlci8yLWRpYW1ldGVyLzQwKTtcblxuICAgIHRoaXMuc2NyZXcuc2V0QXR0cmlidXRlKCdjeCcsIGNlbnRlci54KTtcbiAgICB0aGlzLnNjcmV3LnNldEF0dHJpYnV0ZSgnY3knLCBjZW50ZXIueSk7XG4gICAgdGhpcy5zY3Jldy5zZXRBdHRyaWJ1dGUoJ3InLCBkaWFtZXRlci8xMik7XG5cbiAgICBsZXQgdmFsdWUgPSB0aGlzLnZhbHVlO1xuXG4gICAgbGV0IGhhbmRsZVBvaW50cyA9IHtcbiAgICAgIHN0YXJ0OiBNYXRoLlBJKjEuNSxcbiAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHZhbHVlLDAsMC41LE1hdGguUEkqMS41LE1hdGguUEkqMC41KSAsIE1hdGguUEkqMC41LCBNYXRoLlBJKjEuNSApXG4gICAgfTtcbiAgICBsZXQgaGFuZGxlMlBvaW50cyA9IHtcbiAgICAgIHN0YXJ0OiBNYXRoLlBJKjIuNSxcbiAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHZhbHVlLDAuNSwxLE1hdGguUEkqMi41LE1hdGguUEkqMS41KSAsIE1hdGguUEkqMS41LCBNYXRoLlBJKjIuNSApXG4gICAgfTtcblxuICAgIGxldCBoYW5kbGVQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZVBvaW50cy5zdGFydCwgaGFuZGxlUG9pbnRzLmVuZCk7XG4gICAgbGV0IGhhbmRsZTJQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgIHRoaXMuaGFuZGxlLnNldEF0dHJpYnV0ZSgnZCcsaGFuZGxlUGF0aCk7XG4gICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBkaWFtZXRlci8yMCk7XG4gICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcblxuICAgIHRoaXMuaGFuZGxlMi5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZTJQYXRoKTtcbiAgICB0aGlzLmhhbmRsZTIuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBkaWFtZXRlci8yMCk7XG4gICAgdGhpcy5oYW5kbGUyLnNldEF0dHJpYnV0ZSgnZmlsbCcsICdub25lJyk7XG5cbiAgICBoYW5kbGVQYXRoICs9ICcgTCAnK2NlbnRlci54KycgJytjZW50ZXIueTtcblxuICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZVBhdGgpO1xuICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwtb3BhY2l0eScsICcwLjMnKTtcblxuICAgIGhhbmRsZTJQYXRoICs9ICcgTCAnK2NlbnRlci54KycgJytjZW50ZXIueTtcblxuICAgIHRoaXMuaGFuZGxlMkZpbGwuc2V0QXR0cmlidXRlKCdkJyxoYW5kbGUyUGF0aCk7XG4gICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwtb3BhY2l0eScsICcwLjMnKTtcblxuICAgIGxldCBhcmNFbmRpbmdBO1xuICAgIGlmICh2YWx1ZSA8IDAuNSkge1xuICAgICAgYXJjRW5kaW5nQSA9IGhhbmRsZVBvaW50cy5lbmQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFyY0VuZGluZ0EgPSBoYW5kbGUyUG9pbnRzLmVuZDtcbiAgICB9XG5cbiAgICBsZXQgYXJjRW5kaW5nWCA9IGNlbnRlci54ICsgTWF0aC5jb3MoYXJjRW5kaW5nQSkgKiAoZGlhbWV0ZXIvMik7XG4gICAgbGV0IGFyY0VuZGluZ1kgPSBjZW50ZXIueSArIE1hdGguc2luKGFyY0VuZGluZ0EpICogKGRpYW1ldGVyLzIpICogLTE7XG5cbiAgICB0aGlzLmhhbmRsZUxpbmUuc2V0QXR0cmlidXRlKCdkJywnTSAnK2NlbnRlci54KycgJytjZW50ZXIueSsnIEwgJythcmNFbmRpbmdYKycgJythcmNFbmRpbmdZKTtcbiAgICB0aGlzLmhhbmRsZUxpbmUuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBkaWFtZXRlci8yMCk7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5maWxsKTtcbiAgICB0aGlzLnNjcmV3LnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKCdzdHJva2UnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMuaGFuZGxlMi5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5oYW5kbGVGaWxsLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMuaGFuZGxlTGluZS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXG4gICAgbGV0IGNlbnRlciA9IHtcbiAgICAgIHg6IHRoaXMud2lkdGgvMixcbiAgICAgIHk6IHRoaXMuaGVpZ2h0LzJcbiAgICB9O1xuXG4gICAgbGV0IGRpYW1ldGVyID0gTWF0aC5taW4odGhpcy53aWR0aCx0aGlzLmhlaWdodCk7XG5cbiAgICBsZXQgaGFuZGxlUG9pbnRzID0ge1xuICAgICAgc3RhcnQ6IE1hdGguUEkqMS41LFxuICAgICAgZW5kOiBtYXRoLmNsaXAoIG1hdGguc2NhbGUodmFsdWUsMCwwLjUsTWF0aC5QSSoxLjUsTWF0aC5QSSowLjUpICwgTWF0aC5QSSowLjUsIE1hdGguUEkqMS41IClcbiAgICB9O1xuICAgIGxldCBoYW5kbGUyUG9pbnRzID0ge1xuICAgICAgc3RhcnQ6IE1hdGguUEkgKjIuNSxcbiAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHZhbHVlLDAuNSwxLE1hdGguUEkqMi41LE1hdGguUEkqMS41KSAsIE1hdGguUEkqMS41LCBNYXRoLlBJKjIuNSApXG4gICAgfTtcblxuICAgIGxldCBoYW5kbGVQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZVBvaW50cy5zdGFydCwgaGFuZGxlUG9pbnRzLmVuZCk7XG4gICAgbGV0IGhhbmRsZTJQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgIHRoaXMuaGFuZGxlLnNldEF0dHJpYnV0ZSgnZCcsaGFuZGxlUGF0aCk7XG4gICAgdGhpcy5oYW5kbGUyLnNldEF0dHJpYnV0ZSgnZCcsaGFuZGxlMlBhdGgpO1xuXG5cbiAgICBoYW5kbGVQYXRoICs9ICcgTCAnK2NlbnRlci54KycgJytjZW50ZXIueTtcblxuICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZVBhdGgpO1xuXG4gICAgaGFuZGxlMlBhdGggKz0gJyBMICcrY2VudGVyLngrJyAnK2NlbnRlci55O1xuXG4gICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZTJQYXRoKTtcblxuICAgIGxldCBhcmNFbmRpbmdBO1xuICAgIGlmICh2YWx1ZSA8PSAwLjUpIHtcbiAgICAgIGFyY0VuZGluZ0EgPSBoYW5kbGVQb2ludHMuZW5kO1xuICAgIH0gZWxzZSB7XG4gICAgICBhcmNFbmRpbmdBID0gaGFuZGxlMlBvaW50cy5lbmQ7XG4gICAgfVxuXG4gICAgbGV0IGFyY0VuZGluZ1ggPSBjZW50ZXIueCArIE1hdGguY29zKGFyY0VuZGluZ0EpICogKGRpYW1ldGVyLzIpO1xuICAgIGxldCBhcmNFbmRpbmdZID0gY2VudGVyLnkgKyBNYXRoLnNpbihhcmNFbmRpbmdBKSAqIChkaWFtZXRlci8yKSAqIC0xO1xuXG4gICAgdGhpcy5oYW5kbGVMaW5lLnNldEF0dHJpYnV0ZSgnZCcsJ00gJytjZW50ZXIueCsnICcrY2VudGVyLnkrJyBMICcrYXJjRW5kaW5nWCsnICcrYXJjRW5kaW5nWSk7XG5cbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgaWYgKHRoaXMubW9kZT09PSdyZWxhdGl2ZScpIHtcbiAgICAgIHRoaXMucHJldmlvdXNBbmdsZSA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5tb3ZlKCk7XG4gICB9XG5cbiAgbW92ZSgpIHtcbiAgICBpZiAodGhpcy5jbGlja2VkKSB7XG5cbiAgICAgIHRoaXMucG9zaXRpb24udXBkYXRlKHRoaXMubW91c2UpO1xuXG4gICAgICBsZXQgYW5nbGUgPSB0aGlzLnBvc2l0aW9uLnZhbHVlKk1hdGguUEkqMjtcblxuICAgICAgaWYgKGFuZ2xlIDwgMCApIHsgYW5nbGUgKz0gKE1hdGguUEkqMik7IH1cblxuICAgICAgaWYgKHRoaXMubW9kZSA9PT0gJ3JlbGF0aXZlJykge1xuICAgICAgICBpZiAodGhpcy5wcmV2aW91c0FuZ2xlICE9PSBmYWxzZSAmJiBNYXRoLmFicyh0aGlzLnByZXZpb3VzQW5nbGUgLSBhbmdsZSkgPiAyKSB7XG4gICAgICAgICAgaWYgKHRoaXMucHJldmlvdXNBbmdsZSA+IDMpIHtcbiAgICAgICAgICAgIGFuZ2xlID0gTWF0aC5QSSoyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbmdsZSA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IC8qIGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5wcmV2aW91c0FuZ2xlICE9PSBmYWxzZSAmJiBNYXRoLmFicyh0aGlzLnByZXZpb3VzQW5nbGUgLSBhbmdsZSkgPiAyKSB7XG4gICAgICAgICAgaWYgKHRoaXMucHJldmlvdXNBbmdsZSA+IDMpIHtcbiAgICAgICAgICAgIGFuZ2xlID0gTWF0aC5QSSoyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbmdsZSA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9ICovXG4gICAgICB0aGlzLnByZXZpb3VzQW5nbGUgPSBhbmdsZTtcblxuICAgICAgbGV0IHJlYWxWYWx1ZSA9IGFuZ2xlIC8gKE1hdGguUEkqMik7XG5cbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS51cGRhdGVOb3JtYWwoIHJlYWxWYWx1ZSApO1xuXG4gICAgICBpZiAodGhpcy5tb2RlID09PSAncmVsYXRpdmUnKSB7XG4gICAgICAgIHRoaXMucG9zaXRpb24udmFsdWUgPSByZWFsVmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLl92YWx1ZS52YWx1ZSk7XG5cbiAgICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICB9XG4gIH1cblxuICByZWxlYXNlKCkge1xuICB9XG5cbiAgLypcbiAgRGlhbCdzIHZhbHVlLiBXaGVuIHNldCwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGFkanVzdCB0byBmaXQgbWluL21heC9zdGVwIHNldHRpbmdzIG9mIHRoZSBpbnRlcmZhY2UuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIGRpYWwudmFsdWUgPSAxMDtcblxuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuICB9XG5cbiAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgdGhpcy5fdmFsdWUudXBkYXRlKHZhbHVlKTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuKi9cblxuICAgIC8qKlxuICAgIERpYWwncyB2YWx1ZS4gV2hlbiBzZXQsIGl0IHdpbGwgYXV0b21hdGljYWxseSBiZSBhZGp1c3QgdG8gZml0IG1pbi9tYXgvc3RlcCBzZXR0aW5ncyBvZiB0aGUgaW50ZXJmYWNlLlxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC52YWx1ZSA9IDEwO1xuICAgICovXG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuICAgIH1cbiAgICBzZXQgdmFsdWUodikge1xuICAgICAgdGhpcy5fdmFsdWUudXBkYXRlKHYpO1xuICAgICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5fdmFsdWUudmFsdWUpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICBMb3dlciBsaW1pdCBvZiB0aGUgZGlhbCdzIG91dHB1dCByYW5nZVxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC5taW4gPSAxMDAwO1xuICAgICovXG4gICAgZ2V0IG1pbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5taW47XG4gICAgfVxuICAgIHNldCBtaW4odikge1xuICAgICAgdGhpcy5fdmFsdWUubWluID0gdjtcbiAgICB9XG5cbiAgICAvKipcbiAgICBVcHBlciBsaW1pdCBvZiB0aGUgZGlhbCdzIG91dHB1dCByYW5nZVxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC5tYXggPSAxMDAwO1xuICAgICovXG4gICAgZ2V0IG1heCgpIHtcbiAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5tYXg7XG4gICAgfVxuICAgIHNldCBtYXgodikge1xuICAgICAgdGhpcy5fdmFsdWUubWF4ID0gdjtcbiAgICB9XG5cbiAgICAvKipcbiAgICBUaGUgaW5jcmVtZW50IHRoYXQgdGhlIGRpYWwncyB2YWx1ZSBjaGFuZ2VzIGJ5LlxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC5zdGVwID0gNTtcbiAgICAqL1xuICAgIGdldCBzdGVwKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnN0ZXA7XG4gICAgfVxuICAgIHNldCBzdGVwKHYpIHtcbiAgICAgIHRoaXMuX3ZhbHVlLnN0ZXAgPSB2O1xuICAgIH1cblxuICAgIC8qKlxuICAgIEFic29sdXRlIG1vZGUgKGRpYWwncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJyZWxhdGl2ZVwiLlxuICAgIEB0eXBlIHtzdHJpbmd9XG4gICAgQGV4YW1wbGUgZGlhbC5tb2RlID0gXCJyZWxhdGl2ZVwiO1xuICAgICovXG4gICAgZ2V0IG1vZGUoKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi5tb2RlO1xuICAgIH1cbiAgICBzZXQgbW9kZSh2KSB7XG4gICAgICB0aGlzLnBvc2l0aW9uLm1vZGUgPSB2O1xuICAgIH1cblxuXG4gIC8qKlxuICBOb3JtYWxpemVkIHZhbHVlIG9mIHRoZSBkaWFsLlxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBkaWFsLm5vcm1hbGl6ZWQgPSAwLjU7XG4gICovXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuICB9XG5cbiAgc2V0IG5vcm1hbGl6ZWQodikge1xuICAgIHRoaXMuX3ZhbHVlLnVwZGF0ZU5vcm1hbCh2KTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvZGlhbC5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcbmxldCBCdXR0b25UZW1wbGF0ZSA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvYnV0dG9udGVtcGxhdGUnKTtcbmxldCB0b3VjaCA9IHJlcXVpcmUoJy4uL3V0aWwvdG91Y2gnKTtcblxuY2xhc3MgUGlhbm9LZXkgZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnLCdub3RlJywnY29sb3InXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzgwLDgwXSxcbiAgICAgICd0YXJnZXQnOiBmYWxzZSxcbiAgICAgICdtb2RlJzogJ2J1dHRvbicsXG4gICAgICAndmFsdWUnOiAwXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMubm90ZSA9IHRoaXMuc2V0dGluZ3Mubm90ZTtcbiAgICB0aGlzLmNvbG9yID0gdGhpcy5zZXR0aW5ncy5jb2xvcjtcblxuICAgIHRoaXMuY29sb3JzID0ge1xuICAgICAgJ3cnOiAnI2ZmZicsXG4gICAgICAnYic6ICcjNjY2JyxcbiAgICB9O1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5wYWQgPSBzdmcuY3JlYXRlKCdyZWN0Jyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wYWQpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXG4gICAgLyogZXZlbnRzICovXG5cbiAgICBpZiAoIXRvdWNoLmV4aXN0cykge1xuXG4gICAgICB0aGlzLmNsaWNrID0gKCkgPT4ge1xuICAgICAgLy8gIGNvbnNvbGUubG9nKCdjbGljaycpO1xuICAgICAgICB0aGlzLnBpYW5vLmludGVyYWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5waWFuby5wYWludGJydXNoID0gIXRoaXMuc3RhdGU7XG4gICAgICAgIHRoaXMuZG93bih0aGlzLnBpYW5vLnBhaW50YnJ1c2gpO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5waWFuby5pbnRlcmFjdGluZykge1xuICAgICAgLy8gICAgY29uc29sZS5sb2coJ21vdXNlb3ZlcicpO1xuICAgICAgICAgIHRoaXMuZG93bih0aGlzLnBpYW5vLnBhaW50YnJ1c2gpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuXG4gICAgICB0aGlzLm1vdmUgPSAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnBpYW5vLmludGVyYWN0aW5nKSB7XG4gICAgICAgIC8vICBjb25zb2xlLmxvZygnbW92ZScpO1xuICAgICAgICAgIHRoaXMuYmVuZCgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG5cbiAgICAgIHRoaXMucmVsZWFzZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5waWFuby5pbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgICAgLy8gIGNvbnNvbGUubG9nKCdyZWxlYXNlJyk7XG4gICAgICAvLyAgdGhpcy51cCgpO1xuICAgICAgfTtcbiAgICAgIHRoaXMucGFkLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnBpYW5vLmludGVyYWN0aW5nKSB7XG4gICAgICAgIC8vICBjb25zb2xlLmxvZygnbW91c2V1cCcpO1xuICAgICAgICAgIHRoaXMudXAoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLnBhZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMucGlhbm8uaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgLy8gIGNvbnNvbGUubG9nKCdtb3VzZW91dCcpO1xuICAgICAgICAgIHRoaXMudXAoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICB9XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICAgICAgLy9sZXQgcmFkaXVzID0gTWF0aC5taW4odGhpcy53aWR0aCx0aGlzLmhlaWdodCkgLyA1O1xuICAgICAgICBsZXQgcmFkaXVzID0gMDtcblxuICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3gnLDAuNSk7XG4gICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgneScsMC41KTtcbiAgICAgICAgaWYgKHRoaXMud2lkdGggPiAyKSB7XG4gICAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMud2lkdGggLSAxKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgdGhpcy53aWR0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaGVpZ2h0ID4gMikge1xuICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgncngnLCByYWRpdXMpO1xuICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3J5JywgcmFkaXVzKTtcblxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5zdGF0ZSkge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnNbdGhpcy5jb2xvcl0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIH1cbiAgfVxuXG59XG5cbi8qKlxuKiBQaWFub1xuKlxuKiBAZGVzY3JpcHRpb24gUGlhbm8ga2V5Ym9hcmQgaW50ZXJmYWNlXG4qXG4qIEBkZW1vIDxkaXYgbmV4dXMtdWk9XCJwaWFub1wiPjwvZGl2PlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcGlhbm8gPSBuZXcgTmV4dXMuUGlhbm8oJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcGlhbm8gPSBuZXcgTmV4dXMuUGlhbm8oJyN0YXJnZXQnLHtcbiogICAgICdzaXplJzogWzUwMCwxMjVdLFxuKiAgICAgJ21vZGUnOiAnYnV0dG9uJywgIC8vICdidXR0b24nLCAndG9nZ2xlJywgb3IgJ2ltcHVsc2UnXG4qICAgICAnbG93Tm90ZSc6IDI0LFxuKiAgICAgJ2hpZ2hOb3RlJzogNjBcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgYSBuZXcga2V5IGlzIHByZXNzZWQgb3IgcmVsZWFzZWQgPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyA8aT5ub3RlPC9pPiBhbmQgPGk+c3RhdGU8L2k+IHByb3BlcnRpZXMuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIHBpYW5vLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBpYW5vIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbNTAwLDEyNV0sXG4gICAgICAnbG93Tm90ZSc6IDI0LFxuICAgICAgJ2hpZ2hOb3RlJzogNjAsXG4gICAgICAnbW9kZSc6ICdidXR0b24nXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMua2V5UGF0dGVybiA9IFsndycsJ2InLCd3JywnYicsJ3cnLCd3JywnYicsJ3cnLCdiJywndycsJ2InLCd3J107XG5cbiAgICB0aGlzLnBhaW50YnJ1c2ggPSBmYWxzZTtcblxuICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZTtcblxuICAgIHRoaXMucmFuZ2UgPSB7XG4gICAgICBsb3c6IHRoaXMuc2V0dGluZ3MubG93Tm90ZSxcbiAgICAgIGhpZ2g6IHRoaXMuc2V0dGluZ3MuaGlnaE5vdGVcbiAgICB9O1xuXG4gICAgdGhpcy5yYW5nZS5zaXplID0gdGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7XG5cbiAgICB0aGlzLmtleXMgPSBbXTtcblxuICAgIHRoaXMudG9nZ2xlVG8gPSBmYWxzZTtcblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYm9yZGVyUmFkaXVzID0gJzBweCc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcblxuICAgIHRoaXMua2V5cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7aSsrKSB7XG5cbiAgICAgIGxldCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICBsZXQgc2NhbGVJbmRleCA9IChpK3RoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG5cbiAgICAgIGxldCBrZXkgPSBuZXcgUGlhbm9LZXkoY29udGFpbmVyLCB7XG4gICAgICAgICAgY29tcG9uZW50OiB0cnVlLFxuICAgICAgICAgIG5vdGU6IGkrdGhpcy5yYW5nZS5sb3csXG4gICAgICAgICAgY29sb3I6IHRoaXMua2V5UGF0dGVybltzY2FsZUluZGV4XSxcbiAgICAgICAgICBtb2RlOiB0aGlzLm1vZGVcbiAgICAgICAgfSwgdGhpcy5rZXlDaGFuZ2UuYmluZCh0aGlzLGkrdGhpcy5yYW5nZS5sb3cpKTtcblxuICAgICAga2V5LnBpYW5vID0gdGhpcztcblxuICAgICAgaWYgKHRvdWNoLmV4aXN0cykge1xuICAgICAgICBrZXkucGFkLmluZGV4ID0gaTtcbiAgICAgICAga2V5LnByZUNsaWNrID0ga2V5LnByZU1vdmUgPSBrZXkucHJlUmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgICBrZXkuY2xpY2sgPSBrZXkubW92ZSA9IGtleS5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgICAgIGtleS5wcmVUb3VjaCA9IGtleS5wcmVUb3VjaE1vdmUgPSBrZXkucHJlVG91Y2hSZWxlYXNlID0gKCkgPT4ge307XG4gICAgICAgIGtleS50b3VjaCA9IGtleS50b3VjaE1vdmUgPSBrZXkudG91Y2hSZWxlYXNlID0gKCkgPT4ge307XG4gICAgICB9XG5cbiAgICAgIHRoaXMua2V5cy5wdXNoKGtleSk7XG4gICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblxuICAgIH1cbiAgICBpZiAodG91Y2guZXhpc3RzKSB7XG4gICAgICB0aGlzLmFkZFRvdWNoTGlzdGVuZXJzKCk7XG4gICAgfVxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgbGV0IGtleVggPSAwO1xuXG4gICAgbGV0IGtleVBvc2l0aW9ucyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7aSsrKSB7XG5cbiAgICAgIGtleVBvc2l0aW9ucy5wdXNoKGtleVgpO1xuXG4gICAgICBsZXQgc2NhbGVJbmRleCA9IChpK3RoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG4gICAgICBsZXQgbmV4dFNjYWxlSW5kZXggPSAoaSsxK3RoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG4gICAgICBpZiAoaSsxK3RoaXMucmFuZ2UubG93ID49IHRoaXMucmFuZ2UuaGlnaCkge1xuICAgICAgICBrZXlYICs9IDE7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMua2V5UGF0dGVybltzY2FsZUluZGV4XSA9PT0gJ3cnICYmIHRoaXMua2V5UGF0dGVybltuZXh0U2NhbGVJbmRleF0gPT09ICd3Jykge1xuICAgICAgICBrZXlYICs9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBrZXlYICs9IDAuNTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IGtleXNXaWRlID0ga2V5WDtcblxuXG4gIC8vICBsZXQgcGFkZGluZyA9IHRoaXMud2lkdGggLyAxMjA7XG4gICAgbGV0IHBhZGRpbmcgPSAxO1xuICAgIGxldCBidXR0b25XaWR0aCA9ICh0aGlzLndpZHRoLXBhZGRpbmcqMikgLyBrZXlzV2lkZTtcbiAgICBsZXQgYnV0dG9uSGVpZ2h0ID0gKHRoaXMuaGVpZ2h0LXBhZGRpbmcqMikgLyAyO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5rZXlzLmxlbmd0aDtpKyspIHtcblxuICAgICAgbGV0IGNvbnRhaW5lciA9IHRoaXMua2V5c1tpXS5wYXJlbnQ7XG4gICAgICBjb250YWluZXIuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgY29udGFpbmVyLnN0eWxlLmxlZnQgPSAoa2V5UG9zaXRpb25zW2ldKmJ1dHRvbldpZHRoK3BhZGRpbmcpICsgJ3B4JztcbiAgICAgIGlmICh0aGlzLmtleXNbaV0uY29sb3IgPT09ICd3Jykge1xuICAgICAgICBjb250YWluZXIuc3R5bGUudG9wID0gKHBhZGRpbmcpICsgJ3B4JztcbiAgICAgICAgdGhpcy5rZXlzW2ldLnJlc2l6ZShidXR0b25XaWR0aCwgYnV0dG9uSGVpZ2h0KjIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGFpbmVyLnN0eWxlLnpJbmRleCA9IDE7XG4gICAgICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSBwYWRkaW5nKydweCc7XG4gICAgICAgIHRoaXMua2V5c1tpXS5yZXNpemUoYnV0dG9uV2lkdGgsIGJ1dHRvbkhlaWdodCoxLjEpO1xuICAgICAgfVxuXG4gICAgfVxuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIC8vIFBpYW5vIGtleXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSBhIHN0cm9rZSBib3JkZXJcbiAgICAvLyBUaGV5IGhhdmUgc3BhY2UgYmV0d2VlbiB0aGVtLCB3aGljaCBzaG93cyB0aGUgUGlhbm8gYmcgY29sb3JcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQ7XG5cbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLmtleXMubGVuZ3RoO2krKykge1xuICAgICAgdGhpcy5rZXlzW2ldLmNvbG9ycyA9IHtcbiAgICAgICAgJ3cnOiB0aGlzLmNvbG9ycy5saWdodCxcbiAgICAgICAgJ2InOiB0aGlzLmNvbG9ycy5kYXJrLFxuICAgICAgICAnYWNjZW50JzogdGhpcy5jb2xvcnMuYWNjZW50LFxuICAgICAgICAnYm9yZGVyJzogdGhpcy5jb2xvcnMubWVkaXVtTGlnaHRcbiAgICAgIH07XG4gICAgICB0aGlzLmtleXNbaV0uY29sb3JJbnRlcmZhY2UoKTtcbiAgICAgIHRoaXMua2V5c1tpXS5yZW5kZXIoKTtcbiAgICB9XG5cblxuICB9XG5cbiAga2V5Q2hhbmdlKG5vdGUsb24pIHtcbiAgICAvLyBlbWl0IGRhdGEgZm9yIGFueSBrZXkgdHVybmluZyBvbi9vZmZcbiAgICAvLyBcIm5vdGVcIiBpcyB0aGUgbm90ZSB2YWx1ZVxuICAgIC8vIFwib25cIiBpcyBhIGJvb2xlYW4gd2hldGhlciBpdCBpcyBvbiBvciBvZmZcbiAgICAvLyBpbiBhZnRlcnRvdWNoIG1vZGUsIFwib246IGlzIGFuIG9iamVjdCB3aXRoIHN0YXRlL3gveSBwcm9wZXJ0aWVzXG4gICAgdmFyIGRhdGEgPSB7XG4gICAgICBub3RlOiBub3RlXG4gICAgfTtcbiAgICBpZiAodHlwZW9mIG9uID09PSAnb2JqZWN0Jykge1xuICAgICAgZGF0YS5zdGF0ZSA9IG9uLnN0YXRlO1xuICAgIC8vICBkYXRhLnggPSBvbi54XG4gICAgLy8gIGRhdGEueSA9IG9uLnlcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YS5zdGF0ZSA9IG9uO1xuICAgIH1cbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsZGF0YSk7XG4gIH1cblxuICAvKiBkcmFnKG5vdGUsb24pIHtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgbm90ZTogbm90ZSxcbiAgICAgIHN0YXRlOiBvblxuICAgIH0pO1xuICB9ICovXG5cbiAgcmVuZGVyKCkge1xuICAgIC8vIGxvb3AgdGhyb3VnaCBhbmQgcmVuZGVyIHRoZSBrZXlzP1xuICB9XG5cblxuICBhZGRUb3VjaExpc3RlbmVycygpIHtcblxuICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuXG4gICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGZhbHNlO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoZSkgPT4ge1xuICAgICAgY29uc29sZS5sb2coJ3RvdWNoc3RhcnQnKTtcbiAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCxlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG4gICAgICBsZXQga2V5ID0gdGhpcy5rZXlzW2VsZW1lbnQuaW5kZXhdO1xuICAgICAgdGhpcy5wYWludGJydXNoID0gIWtleS5zdGF0ZTtcbiAgICAgIGtleS5kb3duKHRoaXMucGFpbnRicnVzaCk7XG4gICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZWxlbWVudC5pbmRleDtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgKGUpID0+IHtcbiAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCxlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG4gICAgICBsZXQga2V5ID0gdGhpcy5rZXlzW2VsZW1lbnQuaW5kZXhdO1xuICAgICAgaWYgKGVsZW1lbnQuaW5kZXghPT10aGlzLmN1cnJlbnRFbGVtZW50KSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgbGV0IHBhc3RLZXkgPSB0aGlzLmtleXNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICAgICAgcGFzdEtleS51cCgpO1xuICAgICAgICB9XG4gICAgICAgIGtleS5kb3duKHRoaXMucGFpbnRicnVzaCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBrZXkuYmVuZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGVsZW1lbnQuaW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgKGUpID0+IHtcbiAgICAgIC8vIG5vIHRvdWNoZXMgdG8gY2FsY3VsYXRlIGJlY2F1c2Ugbm9uZSByZW1haW5pbmdcbiAgICAgIGxldCBrZXkgPSB0aGlzLmtleXNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICBrZXkudXAoKTtcbiAgICAgIHRoaXMuaW50ZXJhY3RpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBmYWxzZTtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIC8qKlxuICBEZWZpbmUgdGhlIHBpdGNoIHJhbmdlIChsb3dlc3QgYW5kIGhpZ2hlc3Qgbm90ZSkgb2YgdGhlIHBpYW5vIGtleWJvYXJkLlxuICBAcGFyYW0gbG93IHtudW1iZXJ9IE1JREkgbm90ZSB2YWx1ZSBvZiB0aGUgbG93ZXN0IG5vdGUgb24gdGhlIGtleWJvYXJkXG4gIEBwYXJhbSBoaWdoIHtudW1iZXJ9IE1JREkgbm90ZSB2YWx1ZSBvZiB0aGUgaGlnaGVzdCBub3RlIG9uIHRoZSBrZXlib2FyZFxuICAqL1xuICBzZXRSYW5nZShsb3csaGlnaCkge1xuICAgIHRoaXMucmFuZ2UubG93ID0gbG93O1xuICAgIHRoaXMucmFuZ2UuaGlnaCA9IGhpZ2g7XG4gICAgdGhpcy5lbXB0eSgpO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgfVxuXG4gIC8qKlxuICBUdXJuIGEga2V5IG9uIG9yIG9mZiB1c2luZyBpdHMgTUlESSBub3RlIHZhbHVlO1xuICBAcGFyYW0gbm90ZSB7bnVtYmVyfSBNSURJIG5vdGUgdmFsdWUgb2YgdGhlIGtleSB0byBjaGFuZ2VcbiAgQHBhcmFtIG9uIHtib29sZWFufSBXaGV0aGVyIHRoZSBub3RlIHNob3VsZCB0dXJuIG9uIG9yIG9mZlxuICAqL1xuICB0b2dnbGVLZXkobm90ZSwgb24pIHtcbiAgICB0aGlzLmtleXNbbm90ZS10aGlzLnJhbmdlLmxvd10uZmxpcChvbik7XG4gIH1cblxuICAvKipcbiAgVHVybiBhIGtleSBvbiBvciBvZmYgdXNpbmcgaXRzIGtleSBpbmRleCBvbiB0aGUgcGlhbm8gaW50ZXJmYWNlLlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gSW5kZXggb2YgdGhlIGtleSB0byBjaGFuZ2VcbiAgQHBhcmFtIG9uIHtib29sZWFufSBXaGV0aGVyIHRoZSBub3RlIHNob3VsZCB0dXJuIG9uIG9yIG9mZlxuICAqL1xuICB0b2dnbGVJbmRleChpbmRleCwgb24pIHtcbiAgICB0aGlzLmtleXNbaW5kZXhdLmZsaXAob24pO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL3BpYW5vLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBkb20gPSByZXF1aXJlKCcuLi91dGlsL2RvbScpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgQnV0dG9uVGVtcGxhdGUgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL2J1dHRvbnRlbXBsYXRlJyk7XG5sZXQgTWF0cml4TW9kZWwgPSByZXF1aXJlKCcuLi9tb2RlbHMvbWF0cml4Jyk7XG5sZXQgQ291bnRlck1vZGVsID0gcmVxdWlyZSgnLi4vbW9kZWxzL2NvdW50ZXInKTtcbmxldCB0b3VjaCA9IHJlcXVpcmUoJy4uL3V0aWwvdG91Y2gnKTtcblxuXG5cbmNsYXNzIE1hdHJpeENlbGwgZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnLF07XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFs4MCw4MF0sXG4gICAgICAndGFyZ2V0JzogZmFsc2UsXG4gICAgICAnbW9kZSc6ICd0b2dnbGUnLFxuICAgICAgJ3ZhbHVlJzogMFxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLmluZGV4ID0gdGhpcy5zZXR0aW5ncy5pbmRleDtcbiAgICB0aGlzLnJvdyA9IHRoaXMuc2V0dGluZ3Mucm93O1xuICAgIHRoaXMuY29sdW1uID0gdGhpcy5zZXR0aW5ncy5jb2x1bW47XG5cbiAgICB0aGlzLm1hdHJpeCA9IHRoaXMuc2V0dGluZ3MubWF0cml4O1xuXG4gICAgdGhpcy5pbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgIHRoaXMucGFpbnRicnVzaCA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnRvcCA9ICcwcHgnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5sZWZ0ID0gJzBweCc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLnBhZCA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wYWQpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXG4gICAgLyogZXZlbnRzICovXG5cbiAgICBpZiAoIXRvdWNoLmV4aXN0cykge1xuXG4gICAgICB0aGlzLmNsaWNrID0gKCkgPT4ge1xuICAgICAgICB0aGlzLm1hdHJpeC5pbnRlcmFjdGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMubWF0cml4LnBhaW50YnJ1c2ggPSAhdGhpcy5zdGF0ZTtcbiAgICAgICAgdGhpcy5kb3duKHRoaXMubWF0cml4LnBhaW50YnJ1c2gpO1xuICAgICAgfTtcbiAgICAgIHRoaXMucGFkLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3ZlcicsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubWF0cml4LmludGVyYWN0aW5nKSB7XG4gICAgICAgICAgdGhpcy5kb3duKHRoaXMubWF0cml4LnBhaW50YnJ1c2gpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuXG4gICAgICB0aGlzLm1vdmUgPSAoKSA9PiB7XG4gICAgICB9O1xuICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGUpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubWF0cml4LmludGVyYWN0aW5nKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLm9mZnNldCkge1xuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBkb20uZmluZFBvc2l0aW9uKHRoaXMuZWxlbWVudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSx0aGlzLm9mZnNldCk7XG4gICAgICAgICAgdGhpcy5iZW5kKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG5cbiAgICAgIHRoaXMucmVsZWFzZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5tYXRyaXguaW50ZXJhY3RpbmcgPSBmYWxzZTtcbiAgICAgIH07XG4gICAgICB0aGlzLnBhZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tYXRyaXguaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdXQnLCAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLm1hdHJpeC5pbnRlcmFjdGluZykge1xuICAgICAgICAgIHRoaXMudXAoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd4JywxKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3knLDEpO1xuICAgIGlmICh0aGlzLndpZHRoID4gMikge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMud2lkdGggLSAyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMud2lkdGgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5oZWlnaHQgPiAyKSB7XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIHRoaXMuaGVpZ2h0IC0gMik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQpO1xuICAgIH1cbiAgICAvL3RoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQgLSAyKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLm1hdHJpeC5jb2xvcnMuZmlsbCk7XG5cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMubWF0cml4LmNvbG9ycy5maWxsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5tYXRyaXguY29sb3JzLmFjY2VudCk7XG4gICAgfVxuICB9XG5cbn1cblxuLyoqXG4qIFNlcXVlbmNlclxuKlxuKiBAZGVzY3JpcHRpb24gR3JpZCBvZiBidXR0b25zIHdpdGggYnVpbHQtaW4gc3RlcCBzZXF1ZW5jZXIuXG4qXG4qIEBkZW1vIDxkaXYgbmV4dXMtdWk9XCJzZXF1ZW5jZXJcIiBzdHlsZT1cIndpZHRoOjQwMHB4O2hlaWdodDoyMDBweDtcIj48L2Rpdj5cbipcbiogQGV4YW1wbGVcbiogdmFyIHNlcXVlbmNlciA9IG5ldyBOZXh1cy5TZXF1ZW5jZXIoJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc2VxdWVuY2VyID0gbmV3IE5leHVzLlNlcXVlbmNlcignI3RhcmdldCcse1xuKiAgJ3NpemUnOiBbNDAwLDIwMF0sXG4qICAnbW9kZSc6ICd0b2dnbGUnLFxuKiAgJ3Jvd3MnOiA1LFxuKiAgJ2NvbHVtbnMnOiAxMFxuKn0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyBtYXRyaXggY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyA8aT5yb3c8L2k+IChudW1iZXIpLCA8aT5jb2x1bW48L2k+IChudW1iZXIpLCBhbmQgPGk+c3RhdGU8L2k+IChib29sZWFuKSBwcm9wZXJ0aWVzLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiBzZXF1ZW5jZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIHN0ZXBcbiogRmlyZXMgYW55IHRpbWUgdGhlIHNlcXVlbmNlciBzdGVwcyB0byB0aGUgbmV4dCBjb2x1bW4sIGluIHNlcXVlY2UgbW9kZS4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiA8aT5hcnJheTwvaT4gY29udGFpbmluZyBhbGwgdmFsdWVzIGluIHRoZSBjb2x1bW4sIDxpPmJvdHRvbSByb3cgZmlyc3Q8L2k+LlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiBzZXF1ZW5jZXIub24oJ3N0ZXAnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNlcXVlbmNlciBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzQwMCwyMDBdLFxuICAgICAgJ21vZGUnOiAndG9nZ2xlJyxcbiAgICAgICdyb3dzJzogNSxcbiAgICAgICdjb2x1bW5zJzogMTBcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5hY3RpdmUgPSAtMTtcblxuICAgIC8qKlxuICAgICogQnV0dG9uIGludGVyYWN0aW9uIG1vZGU6IHNlZSBCdXR0b25cbiAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgKiBAZXhhbXBsZSBidXR0b24ubW9kZSA9ICd0b2dnbGUnO1xuICAgICovXG4gICAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXG4gICAgLyoqXG4gICAgKiBUaGUgaW50ZXJ2YWwgb2JqZWN0IHdoaWNoIGNvbnRyb2xzIHRpbWluZyBhbmQgc2VxdWVuY2Ugc2NoZWR1bGluZy5cbiAgICAqIEB0eXBlIHtpbnRlcnZhbH1cbiAgICAqL1xuICAgIHRoaXMuaW50ZXJ2YWwgPSBuZXcgTmV4dXMuSW50ZXJ2YWwoMjAwLGZ1bmN0aW9uKCkge30sZmFsc2UpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuICAgIC8qKlxuICAgICogQSBNYXRyaXggbW9kZWwgY29udGFpbmluZyBtZXRob2RzIGZvciBtYW5pcHVsYXRpbmcgdGhlIHNlcXVlbmNlcidzIGFycmF5IG9mIHZhbHVlcy4gVG8gbGVhcm4gaG93IHRvIG1hbmlwdWxhdGUgdGhlIG1hdHJpeCwgcmVhZCBhYm91dCB0aGUgbWF0cml4IG1vZGVsLlxuICAgICogQHR5cGUge21hdHJpeH1cbiAgICAqL1xuICAgIHRoaXMubWF0cml4ID0gbmV3IE1hdHJpeE1vZGVsKHRoaXMuc2V0dGluZ3Mucm93cyx0aGlzLnNldHRpbmdzLmNvbHVtbnMpO1xuICAgIHRoaXMubWF0cml4LnVpID0gdGhpcztcblxuICAgIC8qKlxuICAgICogQSBDb3VudGVyIG1vZGVsIHdoaWNoIHRoZSBzZXF1ZW5jZXIgc3RlcHMgdGhyb3VnaC4gRm9yIGV4YW1wbGUsIHlvdSBjb3VsZCB1c2UgdGhpcyBtb2RlbCB0byBzdGVwIHRocm91Z2ggdGhlIHNlcXVlbmNlciBpbiByZXZlcnNlLCByYW5kb21seSwgb3IgaW4gYSBkcnVuayB3YWxrLlxuICAgICogQHR5cGUge2NvdW50ZXJ9XG4gICAgKi9cbiAgICB0aGlzLnN0ZXBwZXIgPSBuZXcgQ291bnRlck1vZGVsKDAsdGhpcy5jb2x1bW5zKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gIH1cblxuICBidWlsZEZyYW1lKCkge1xuICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG4gICAgaWYgKHRvdWNoLmV4aXN0cykge1xuICAgICAgdGhpcy5hZGRUb3VjaExpc3RlbmVycygpO1xuICAgIH1cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5jZWxscyA9IFtdO1xuICAgIGZvciAobGV0IGk9MDtpPHRoaXMubWF0cml4Lmxlbmd0aDtpKyspIHtcblxuICAgICAgbGV0IGxvY2F0aW9uID0gdGhpcy5tYXRyaXgubG9jYXRlKGkpO1xuICAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJucyB7cm93LGNvbH1cblxuICAgICAgbGV0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgIGNvbnRhaW5lci5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG5cblxuICAgICAgbGV0IGNlbGwgPSBuZXcgTWF0cml4Q2VsbChjb250YWluZXIsIHtcbiAgICAgICAgICBjb21wb25lbnQ6IHRydWUsXG4gICAgICAgICAgaW5kZXg6IGksXG4gICAgICAgICAgcm93OiBsb2NhdGlvbi5yb3csXG4gICAgICAgICAgY29sdW1uOiBsb2NhdGlvbi5jb2x1bW4sXG4gICAgICAgICAgbW9kZTogdGhpcy5tb2RlLFxuICAgICAgICAgIG1hdHJpeDogdGhpc1xuICAgICAgICB9LCB0aGlzLmtleUNoYW5nZS5iaW5kKHRoaXMsaSkpO1xuXG4gICAgLy8gIGNlbGwubWF0cml4ID0gdGhpcztcbiAgICAgIGlmICh0b3VjaC5leGlzdHMpIHtcbiAgICAgICAgY2VsbC5wYWQuaW5kZXggPSBpO1xuICAgICAgICBjZWxsLnByZUNsaWNrID0gY2VsbC5wcmVNb3ZlID0gY2VsbC5wcmVSZWxlYXNlID0gKCkgPT4ge307XG4gICAgICAgIGNlbGwuY2xpY2sgPSBjZWxsLm1vdmUgPSBjZWxsLnJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgICAgY2VsbC5wcmVUb3VjaCA9IGNlbGwucHJlVG91Y2hNb3ZlID0gY2VsbC5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgICAgY2VsbC50b3VjaCA9IGNlbGwudG91Y2hNb3ZlID0gY2VsbC50b3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5jZWxscy5wdXNoKGNlbGwpO1xuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cbiAgICB9XG4gICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgbGV0IGNlbGxXaWR0aCA9IHRoaXMud2lkdGggLyB0aGlzLmNvbHVtbnM7XG4gICAgbGV0IGNlbGxIZWlnaHQgPSB0aGlzLmhlaWdodCAvIHRoaXMucm93cztcblxuICAgIGZvciAobGV0IGk9MDsgaTx0aGlzLmNlbGxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgY29udGFpbmVyID0gdGhpcy5jZWxsc1tpXS5wYXJlbnQ7XG4gICAgICBjb250YWluZXIuc3R5bGUubGVmdCA9IHRoaXMuY2VsbHNbaV0uY29sdW1uICogY2VsbFdpZHRoICsgJ3B4JztcbiAgICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSB0aGlzLmNlbGxzW2ldLnJvdyAqIGNlbGxIZWlnaHQgKyAncHgnO1xuICAgICAgdGhpcy5jZWxsc1tpXS5yZXNpemUoY2VsbFdpZHRoLGNlbGxIZWlnaHQpO1xuICAgIH1cblxuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICBmb3IgKHZhciBpPTA7IGk8dGhpcy5jZWxscy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5jZWxsc1tpXS5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGUoKSB7XG4gIC8vICBjb25zb2xlLmxvZyhcInVwZGF0aW5nLi4uXCIpXG4gICAgLy9vbiA9IG9uIHx8IGZhbHNlO1xuICAgIHRoaXMubWF0cml4Lml0ZXJhdGUoKHIsYyxpKSA9PiB7XG4gICAgICAvLyAgY29uc29sZS5sb2codGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSwgdGhpcy5jZWxsc1tpXS5zdGF0ZSk7XG4gICAgICBpZiAodGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSAhPT0gdGhpcy5jZWxsc1tpXS5zdGF0ZSkge1xuICAgICAgICBpZiAodGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSA+IDApIHtcbiAgICAgICAgICB0aGlzLmNlbGxzW2ldLnR1cm5PbigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuY2VsbHNbaV0udHVybk9mZigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuLy8gdXBkYXRlID0+IGNlbGwudHVybk9uID0+IGNlbGwuZW1pdCA9PiBrZXlDaGFuZ2UgKHNlcS5lbWl0KSA9PiBtYXRyaXguc2V0LmNlbGwgPT4gdXBkYXRlXG4vL1xuLy8gaW50ZXJhY3Rpb24gPT4ga2V5Q2hhbmdlID0+IG1hdHJpeC5zZXQuY2VsbCA9PiB1cGRhdGUgPT4gY2VsbC50dXJuT25cbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gZW1pdFxuLy9cbi8vIHNldC5jZWxsID0+IHVwZGF0ZSA9PiBuZWVkcyB0byBlbWl0LlxuXG4gIGtleUNoYW5nZShub3RlLG9uKSB7XG4gICAgLy8gZW1pdCBkYXRhIGZvciBhbnkga2V5IHR1cm5pbmcgb24vb2ZmXG4gICAgLy8gaSBpcyB0aGUgbm90ZSBpbmRleFxuICAgIC8vIHYgaXMgd2hldGhlciBpdCBpcyBvbiBvciBvZmZcbiAgICBsZXQgY2VsbCA9IHRoaXMubWF0cml4LmxvY2F0ZShub3RlKTtcbiAgLy8gIHRoaXMubWF0cml4LnNldC5jZWxsKGNlbGwuY29sdW1uLGNlbGwucm93LG9uKTtcbiAgICB0aGlzLm1hdHJpeC5wYXR0ZXJuW2NlbGwucm93XVtjZWxsLmNvbHVtbl0gPSBvbjtcbiAgICB2YXIgZGF0YSA9IHtcbiAgICAgIHJvdzogY2VsbC5yb3csXG4gICAgICBjb2x1bW46IGNlbGwuY29sdW1uLFxuICAgICAgc3RhdGU6IG9uXG4gICAgfTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsZGF0YSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKHRoaXMuc3RlcHBlci52YWx1ZSA+PSAwKSB7XG4gICAgICB0aGlzLm1hdHJpeC5pdGVyYXRlKChyLGMsaSkgPT4ge1xuICAgICAgICBpZiAoYz09PXRoaXMuc3RlcHBlci52YWx1ZSkge1xuICAgICAgICAgIHRoaXMuY2VsbHNbaV0ucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgICAgICAgdGhpcy5jZWxsc1tpXS5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCcxJyk7XG4gICAgICAgICAgdGhpcy5jZWxsc1tpXS5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2Utb3BhY2l0eScsJzEnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNlbGxzW2ldLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsJ25vbmUnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHNlcXVlbmNpbmdcbiAgICogQHBhcmFtICB7bnVtYmVyfSBtcyBCZWF0IHRlbXBvIGluIG1pbGxpc2Vjb25kc1xuICAgKi9cbiAgc3RhcnQobXMpIHtcbiAgICB0aGlzLmludGVydmFsLmV2ZW50ID0gdGhpcy5uZXh0LmJpbmQodGhpcyk7XG4gICAgaWYgKG1zKSB7XG4gICAgICB0aGlzLmludGVydmFsLm1zKG1zKTtcbiAgICB9XG4gICAgdGhpcy5pbnRlcnZhbC5zdGFydCgpO1xuICB9XG5cbiAgLyoqXG4gIFN0b3Agc2VxdWVuY2luZ1xuICAqL1xuICBzdG9wKCkge1xuICAgIHRoaXMuaW50ZXJ2YWwuc3RvcCgpO1xuICB9XG5cbiAgLyoqXG4gIE1hbnVhbGx5IGp1bXAgdG8gdGhlIG5leHQgY29sdW1uIGFuZCB0cmlnZ2VyIHRoZSAnY2hhbmdlJyBldmVudC4gVGhlIFwibmV4dFwiIGNvbHVtbiBpcyBkZXRlcm1pbmVkIGJ5IHlvdXIgbW9kZSBvZiBzZXF1ZW5jaW5nLlxuICAqL1xuICBuZXh0KCkge1xuICAgIHRoaXMuc3RlcHBlci5uZXh0KCk7XG4gICAgdGhpcy5lbWl0KCdzdGVwJyx0aGlzLm1hdHJpeC5jb2x1bW4odGhpcy5zdGVwcGVyLnZhbHVlKS5yZXZlcnNlKCkpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBhZGRUb3VjaExpc3RlbmVycygpIHtcblxuICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuXG4gICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGZhbHNlO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoZSkgPT4ge1xuICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRYLGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRZKTtcbiAgICAgIGxldCBjZWxsID0gdGhpcy5jZWxsc1tlbGVtZW50LmluZGV4XTtcbiAgICAgIHRoaXMucGFpbnRicnVzaCA9ICFjZWxsLnN0YXRlO1xuICAgICAgY2VsbC5kb3duKHRoaXMucGFpbnRicnVzaCk7XG4gICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZWxlbWVudC5pbmRleDtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgKGUpID0+IHtcbiAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCxlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG4gICAgICBsZXQgY2VsbCA9IHRoaXMuY2VsbHNbZWxlbWVudC5pbmRleF07XG4gICAgICBpZiAoZWxlbWVudC5pbmRleCE9PXRoaXMuY3VycmVudEVsZW1lbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEVsZW1lbnQgPj0gMCkge1xuICAgICAgICAgIGxldCBwYXN0Q2VsbCA9IHRoaXMuY2VsbHNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICAgICAgcGFzdENlbGwudXAoKTtcbiAgICAgICAgfVxuICAgICAgICBjZWxsLmRvd24odGhpcy5wYWludGJydXNoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNlbGwuYmVuZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGVsZW1lbnQuaW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgKGUpID0+IHtcbiAgICAgIC8vIG5vIHRvdWNoZXMgdG8gY2FsY3VsYXRlIGJlY2F1c2Ugbm9uZSByZW1haW5pbmdcbiAgICAgIGxldCBjZWxsID0gdGhpcy5jZWxsc1t0aGlzLmN1cnJlbnRFbGVtZW50XTtcbiAgICAgIGNlbGwudXAoKTtcbiAgICAgIHRoaXMuaW50ZXJhY3RpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBmYWxzZTtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIC8qKlxuICBOdW1iZXIgb2Ygcm93cyBpbiB0aGUgc2VxdWVuY2VyXG4gIEB0eXBlIHtudW1iZXJ9XG4gICovXG4gIGdldCByb3dzKCkge1xuICAgIHJldHVybiB0aGlzLm1hdHJpeC5yb3dzO1xuICB9XG5cbiAgc2V0IHJvd3Modikge1xuICAgIHRoaXMubWF0cml4LnJvd3MgPSB2O1xuICAgIHRoaXMuZW1wdHkoKTtcbiAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICBOdW1iZXIgb2YgY29sdW1ucyBpbiB0aGUgc2VxdWVuY2VyXG4gIEB0eXBlIHtudW1iZXJ9XG4gICovXG4gIGdldCBjb2x1bW5zKCkge1xuICAgIHJldHVybiB0aGlzLm1hdHJpeC5jb2x1bW5zO1xuICB9XG5cbiAgc2V0IGNvbHVtbnModikge1xuICAgIHRoaXMubWF0cml4LmNvbHVtbnMgPSB2O1xuICAgIHRoaXMuc3RlcHBlci5tYXggPSB2O1xuICAgIHRoaXMuZW1wdHkoKTtcbiAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9zZXF1ZW5jZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5pbXBvcnQgU2VxdWVuY2UgZnJvbSAnLi4vbW9kZWxzL3NlcXVlbmNlJztcblxuLy8gRm9yIHRoZSB0dXRvcmlhbCwgbG9va2luZyBhdFxuXG4vL1BhdHRlcm4gc2VjdGlvbjpcbi8vIC5jcmVhdGUoKSwgLnJvd3MsIC5jb2x1bW5zLFxuLy8gLnBhdHRlcm4sIC5sZW5ndGgsIC5mb3JtYXRBc1RleHQoKSwgLmxvZygpLFxuLy8gLmxvY2F0ZShpKSwgLmluZGV4T2YoYyxyKVxuLy8gcm93KCksIGNvbHVtbigpIChyZXR1cm5zIGNvbnRlbnRzIG9mIHJvdyBvciBjb2x1bSlcblxuLy9Db250cm9sIHNlY3Rpb246XG4vLyB0b2dnbGUgeDNcbi8vIHNldCB4NFxuLy8gcm90YXRlIHgzXG4vLyBwb3B1bGF0ZSB4M1xuLy8gZXJhc2UgeDNcblxuXG4vLyBzaG91bGQgc29tZSB2ZXJzaW9uIG9mIHRoaXMgaGF2ZSBhIGZsb2F0IHZhbHVlIGZvciBlYWNoIGNlbGw/XG4vLyBjb3VsZCBiZSBsaWtlIGEgbWlycm9yIC5wYXR0ZXJuIHRoYXQgaGFzIHZhbHVlcy4gYnkgZGVmYXVsdCwgZXZlcnl0aGluZyBpcyAxLCBidXQgY291bGQgYmUgc2V0Li4uXG4vLyBub3QgYSBnb29kIHdheSB0byBkbyB0aGF0IG9uIGludGVyZmFjZSwgYnV0IGFzIGEgbW9kZWwgaXQgd291bGQgYmUgbmljZS4uLlxuLy8gZm9yIC5mb3JtYXRBc1RleHQoKSwgY291bGQgbXVsdGlwbHkgYnkgMTAwIGFuZCBmbG9vciwgc28gZWFjaCBjZWxsIGlzIGFuIGludCBmcm9tIDAgdG8gOVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNYXRyaXgge1xuXG4gIGNvbnN0cnVjdG9yKHJvd3MsY29sdW1ucykge1xuICAgIC8vIHNob3VsZCBhbHNvIGhhdmUgYWJpbGl0eSB0byBjcmVhdGUgdXNpbmcgYW4gZXhpc3RpbmcgbWF0cml4ICgyZCBhcnJheSlcbiAgICB0aGlzLnBhdHRlcm4gPSBbXTtcbiAgICB0aGlzLmNyZWF0ZShyb3dzLGNvbHVtbnMpO1xuXG4gICAgdGhpcy50b2dnbGUgPSB7XG4gICAgICBjZWxsOiAoY29sdW1uLCByb3cpID0+IHtcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3Jvd11bY29sdW1uXSA9ICF0aGlzLnBhdHRlcm5bcm93XVtjb2x1bW5dOyAvLyBtYXRoLmludmVydCh0aGlzLnBhdHRlcm5bcm93XVtjb2x1bW5dKTtcbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgICByZXR1cm4gdGhpcy5wYXR0ZXJuW3Jvd11bY29sdW1uXTtcbiAgICAgIH0sXG4gICAgICBhbGw6ICgpID0+IHtcbiAgICAgICAgdGhpcy5pdGVyYXRlKChyLGMpID0+IHsgdGhpcy50b2dnbGUuY2VsbChjLHIpOyB9KTtcbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgfSxcbiAgICAgIHJvdzogKHJvdykgPT4ge1xuICAgICAgICBmb3IgKGxldCBpPTA7IGk8dGhpcy5jb2x1bW5zOyBpKyspIHtcbiAgICAgICAgICB0aGlzLnRvZ2dsZS5jZWxsKGkscm93KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9LFxuICAgICAgY29sdW1uOiAoY29sdW1uKSA9PiB7XG4gICAgICAgIGZvciAobGV0IGk9MDsgaTx0aGlzLnJvd3M7IGkrKykge1xuICAgICAgICAgIHRoaXMudG9nZ2xlLmNlbGwoY29sdW1uLGkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5zZXQgPSB7XG4gICAgICBjZWxsOiAoY29sdW1uLCByb3csIHZhbHVlKSA9PiB7XG4gICAgICAgIHRoaXMucGF0dGVybltyb3ddW2NvbHVtbl0gPSB2YWx1ZTtcbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgfSxcbiAgICAgIGFsbDogKHZhbHVlcykgPT4ge1xuICAgICAgICAvLyBzZXQgdGhlIHdob2xlIG1hdHJpeCB1c2luZyBhIDJkIGFycmF5IGFzIGlucHV0XG4gICAgICAgIC8vIHRoaXMgc2hvdWxkIGFsc28gcmVzaXplIHRoZSBhcnJheT9cbiAgICAgICAgdGhpcy5wYXR0ZXJuID0gdmFsdWVzO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9LFxuICAgICAgcm93OiAocm93LHZhbHVlcykgPT4ge1xuICAgICAgICAvLyBzZXQgYSByb3cgdXNpbmcgYW4gYXJyYXkgYXMgaW5wdXRcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3Jvd10gPSB2YWx1ZXM7XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH0sXG4gICAgICBjb2x1bW46IChjb2x1bW4sdmFsdWVzKSA9PiB7XG4gICAgICAgIC8vIHNldCBhIGNvbHVtbiB1c2luZyBhbiBhcnJheSBhcyBpbnB1dFxuICAgICAgICB0aGlzLnBhdHRlcm4uZm9yRWFjaCgocm93LGkpID0+IHtcbiAgICAgICAgICB0aGlzLnBhdHRlcm5baV1bY29sdW1uXSA9IHZhbHVlc1tpXTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5yb3RhdGUgPSB7XG4gICAgICAvL3Nob3VsZCBldmVudHVhbGx5IGRvIChhbW91bnRYLCBhbW91bnRZKSBoZXJlXG4gICAgICAvLyBjb3VsZCBqdXN0IHVzZSBhIGxvb3AgYW5kIHRoaXMucm90YXRlLnJvdyhpLGFtb3VudFgpO1xuICAgICAgYWxsOiAoYW1vdW50KSA9PiB7XG4gICAgICAgIGlmICghYW1vdW50ICYmIGFtb3VudCE9PTApIHtcbiAgICAgICAgICBhbW91bnQgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGFtb3VudCAlPSB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuICAgICAgICBpZiAoYW1vdW50IDwgMCkge1xuICAgICAgICAgIGFtb3VudCA9IHRoaXMucGF0dGVyblswXS5sZW5ndGggKyBhbW91bnQ7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaT0wOyBpPHRoaXMucm93czsgaSsrKSB7XG4gICAgICAgICAgbGV0IGN1dCA9IHRoaXMucGF0dGVybltpXS5zcGxpY2UoIHRoaXMucGF0dGVybltpXS5sZW5ndGggLSBhbW91bnQsIGFtb3VudCApO1xuICAgICAgICAgIHRoaXMucGF0dGVybltpXSA9IGN1dC5jb25jYXQoIHRoaXMucGF0dGVybltpXSApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH0sXG4gICAgICByb3c6IChyb3csYW1vdW50KSA9PiB7XG4gICAgICAgIGlmICghYW1vdW50ICYmIGFtb3VudCE9PTApIHtcbiAgICAgICAgICBhbW91bnQgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGFtb3VudCAlPSB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuICAgICAgICBpZiAoYW1vdW50IDwgMCkge1xuICAgICAgICAgIGFtb3VudCA9IHRoaXMucGF0dGVyblswXS5sZW5ndGggKyBhbW91bnQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGN1dCA9IHRoaXMucGF0dGVybltyb3ddLnNwbGljZSggdGhpcy5wYXR0ZXJuW3Jvd10ubGVuZ3RoIC0gYW1vdW50LCBhbW91bnQgKTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3Jvd10gPSBjdXQuY29uY2F0KCB0aGlzLnBhdHRlcm5bcm93XSApO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9LFxuICAgICAgY29sdW1uOiAoY29sdW1uLCBhbW91bnQpID0+IHtcbiAgICAgICAgaWYgKCFhbW91bnQgJiYgYW1vdW50IT09MCkge1xuICAgICAgICAgIGFtb3VudCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgYW1vdW50ICU9IHRoaXMucGF0dGVybi5sZW5ndGg7XG4gICAgICAgIGlmIChhbW91bnQgPCAwKSB7XG4gICAgICAgICAgYW1vdW50ID0gdGhpcy5wYXR0ZXJuLmxlbmd0aCArIGFtb3VudDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcHJveHkgPSBbXTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuLmZvckVhY2goKHJvdykgPT4ge1xuICAgICAgICAgIHByb3h5LnB1c2goIHJvd1tjb2x1bW5dICk7XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgY3V0ID0gcHJveHkuc3BsaWNlKCBwcm94eS5sZW5ndGggLSBhbW91bnQsIGFtb3VudCApO1xuICAgICAgICBwcm94eSA9IGN1dC5jb25jYXQoIHByb3h5ICk7XG4gICAgICAgIHRoaXMucGF0dGVybi5mb3JFYWNoKChyb3csaSkgPT4ge1xuICAgICAgICAgIHJvd1tjb2x1bW5dID0gcHJveHlbaV07XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIHRoZSBpZGVhIGJlaGluZCBwb3B1bGF0ZSBpcyB0byBiZSBhYmxlIHRvIHNldCBhIHdob2xlIHJvdyBvciBjb2x1bW4gdG8gMCBvciAxXG4gICAgLy8gSUYgdGhlIHZhbHVlIGlzIGEgZmxvYXQsIHN1Y2ggYXMgMC43LCB0aGVuIGl0IHdvdWxkIGJlY29tZSBhIHByb2JhYmlsaXR5XG4gICAgLy8gc28gcG9wdWxhdGUoMC43KSB3b3VsZCBnaXZlIGVhY2ggY2VsbCBhIDcwJSBjaGFuY2Ugb2YgYmVpbmcgMVxuICAgIHRoaXMucG9wdWxhdGUgPSB7XG4gICAgICBhbGw6IChvZGRzKSA9PiB7XG4gICAgICAgIGxldCBvZGRzU2VxdWVuY2UgPSBuZXcgU2VxdWVuY2Uob2Rkcyk7XG4gICAgICAgIHRoaXMuaXRlcmF0ZSgocixjKSA9PiB7XG4gICAgICAgICAgdGhpcy5wYXR0ZXJuW3JdW2NdID0gbWF0aC5jb2luKG9kZHNTZXF1ZW5jZS5uZXh0KCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gVGhpcyBjb3VsZCBiZSB1c2VkIHNvIHRoYXQgZWFjaCByb3cgaGFzIHNhbWUgb2RkcyBwYXR0ZXJuLCBldmVuIGlmIHJvdyBsZW5ndGggaXMgbm90IGRpdmlzaWJseSBieSBzZXF1ZW5jZSBsZW5ndGguXG4gICAgICAgIC8vLCgpID0+IHtcbiAgICAgICAgLy8gIG9kZHMucG9zID0gLTE7XG4gICAgICAgIC8vIH1cbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgfSxcbiAgICAgIHJvdzogKHJvdz0wLG9kZHM9MSkgPT4ge1xuICAgICAgICBsZXQgb2Rkc1NlcXVlbmNlID0gbmV3IFNlcXVlbmNlKG9kZHMpO1xuICAgICAgICB0aGlzLnBhdHRlcm5bcm93XS5mb3JFYWNoKChjZWxsLGkpID0+IHtcbiAgICAgICAgICB0aGlzLnBhdHRlcm5bcm93XVtpXSA9IG1hdGguY29pbihvZGRzU2VxdWVuY2UubmV4dCgpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH0sXG4gICAgICBjb2x1bW46IChjb2x1bW49MCxvZGRzPTEpID0+IHtcbiAgICAgICAgbGV0IG9kZHNTZXF1ZW5jZSA9IG5ldyBTZXF1ZW5jZShvZGRzKTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuLmZvckVhY2goKHJvdyxpKSA9PiB7XG4gICAgICAgICAgdGhpcy5wYXR0ZXJuW2ldW2NvbHVtbl0gPSBtYXRoLmNvaW4ob2Rkc1NlcXVlbmNlLm5leHQoKSk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIGVzc2VudGlhbGwgcG9wdWxhdGUoMCkgc28gaSdtIG5vdCBzdXJlIGlmIHRoaXMgaXMgbmVjZXNzYXJ5IGJ1dCBpcyBuaWNlXG4gICAgdGhpcy5lcmFzZSA9IHtcbiAgICAgIGFsbDogKCkgPT4ge1xuICAgICAgICB0aGlzLnNldC5hbGwoMCk7XG4gICAgICB9LFxuICAgICAgcm93OiAocm93KSA9PiB7XG4gICAgICAgIHRoaXMuc2V0LnJvdyhyb3csMCk7XG4gICAgICB9LFxuICAgICAgY29sdW1uOiAoY29sdW1uKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0LmNvbHVtbihjb2x1bW4sMCk7XG4gICAgICB9XG4gICAgfTtcblxuICAvLyBlbmQgY29uc3RydWN0b3JcbiAgfVxuXG5cbiAgY3JlYXRlKHJvd3MsY29sdW1ucykge1xuICAgIHRoaXMucGF0dGVybiA9IFtdO1xuICAgIGZvciAoIGxldCByb3c9MDsgcm93IDwgcm93czsgcm93KysgKSB7XG4gICAgICBsZXQgYXJyID0gbmV3IEFycmF5KGNvbHVtbnMpO1xuICAgICAgdGhpcy5wYXR0ZXJuLnB1c2goYXJyKTtcbiAgICB9XG4gICAgdGhpcy5pdGVyYXRlKChyLGMpID0+IHsgdGhpcy5wYXR0ZXJuW3JdW2NdID0gZmFsc2U7IH0pO1xuICB9XG5cbiAgaXRlcmF0ZShmLCBmMikge1xuICAgIGxldCBpID0gMDtcbiAgICBmb3IgKCBsZXQgcm93PTA7IHJvdyA8IHRoaXMucm93czsgcm93KysgKSB7XG4gICAgICBpZiAoZjIpIHsgZjIocm93KTsgfVxuICAgICAgZm9yICggbGV0IGNvbHVtbj0wOyBjb2x1bW4gPCB0aGlzLmNvbHVtbnM7IGNvbHVtbisrICkge1xuICAgICAgICBmKHJvdyxjb2x1bW4saSk7XG4gICAgICAgIGkrKztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3JtYXRBc1RleHQoKSB7XG4gICAgbGV0IHBhdHRlcm5TdHJpbmcgPSAnJztcbiAgICB0aGlzLml0ZXJhdGUoXG4gICAgICAocixjKSA9PiB7IHBhdHRlcm5TdHJpbmcgKz0gKHRoaXMucGF0dGVybltyXVtjXSA/IDEgOiAwKSArICcgJzsgfSxcbiAgICAgICgpID0+IHsgcGF0dGVyblN0cmluZyArPSAnXFxuJzsgfVxuICAgICk7XG4gICAgcmV0dXJuIHBhdHRlcm5TdHJpbmc7XG4gIH1cblxuICBsb2coKSB7XG4gICAgY29uc29sZS5sb2codGhpcy5mb3JtYXRBc1RleHQoKSk7XG4gIH1cblxuICB1cGRhdGUocGF0dGVybikge1xuICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm4gfHwgdGhpcy5wYXR0ZXJuO1xuICB9XG5cbiAgZ2V0IGxlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5yb3dzKnRoaXMuY29sdW1ucztcbiAgfVxuXG4gIGxvY2F0ZShpbmRleCkge1xuICAgIC8vIHJldHVybnMgcm93IGFuZCBjb2x1bW4gb2YgY2VsbCBieSBpbmRleFxuICAgIHJldHVybiB7XG4gICAgICByb3c6IH5+KCBpbmRleCAvIHRoaXMuY29sdW1ucyApLFxuICAgICAgY29sdW1uOiBpbmRleCAlIHRoaXMuY29sdW1uc1xuICAgIH07XG4gIH1cblxuICBpbmRleE9mKHJvdyxjb2x1bW4pIHtcbiAgICByZXR1cm4gY29sdW1uICsgcm93ICogdGhpcy5jb2x1bW5zO1xuICAgIC8vIHJldHVybnMgaW5kZXggb2YgY2VsbCBieSByb3cgYW5kIGNvbHVtblxuICB9XG5cbiAgcm93KHJvdykge1xuICAgIGxldCBkYXRhID0gW107XG4gICAgZm9yIChsZXQgaT0wOyBpPHRoaXMuY29sdW1uczsgaSsrKSB7XG4gICAgICBkYXRhLnB1c2godGhpcy5wYXR0ZXJuW3Jvd10gPyAxIDogMCk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgY29sdW1uKGNvbHVtbikge1xuICAgIGxldCBkYXRhID0gW107XG4gICAgZm9yIChsZXQgaT0wOyBpPHRoaXMucm93czsgaSsrKSB7XG4gICAgICBkYXRhLnB1c2godGhpcy5wYXR0ZXJuW2ldW2NvbHVtbl0gPyAxIDogMCk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgZ2V0IHJvd3MoKSB7XG4gICAgcmV0dXJuIHRoaXMucGF0dGVybi5sZW5ndGg7XG4gIH1cbiAgc2V0IHJvd3Modikge1xuICAgIGxldCBwcmV2aW91cyA9IHRoaXMucGF0dGVybi5zbGljZSgwKTtcbiAgICB0aGlzLmNyZWF0ZSh2LHRoaXMuY29sdW1ucyk7XG4gICAgdGhpcy5pdGVyYXRlKChyLGMpID0+IHtcbiAgICAgIGlmIChwcmV2aW91c1tyXSAmJiBwcmV2aW91c1tyXVtjXSkge1xuICAgICAgICB0aGlzLnBhdHRlcm5bcl1bY10gPSBwcmV2aW91c1tyXVtjXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGdldCBjb2x1bW5zKCkge1xuICAgIHJldHVybiB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuICB9XG4gIHNldCBjb2x1bW5zKHYpIHtcbiAgICBsZXQgcHJldmlvdXMgPSB0aGlzLnBhdHRlcm4uc2xpY2UoMCk7XG4gICAgdGhpcy5jcmVhdGUodGhpcy5yb3dzLHYpO1xuICAgIHRoaXMuaXRlcmF0ZSgocixjKSA9PiB7XG4gICAgICBpZiAocHJldmlvdXNbcl0gJiYgcHJldmlvdXNbcl1bY10pIHtcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3JdW2NdID0gcHJldmlvdXNbcl1bY107XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL21vZGVscy9tYXRyaXguanMiLCIndXNlIHN0cmljdCc7XHJcblxyXG5pbXBvcnQgbWF0aCBmcm9tICcuLi91dGlsL21hdGgnO1xyXG5pbXBvcnQgRHJ1bmsgZnJvbSAnLi9kcnVuayc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTZXF1ZW5jZSB7XHJcblxyXG4gICAgY29uc3RydWN0b3Ioc2VxdWVuY2UgPSBbMCwxMCwyMCwzMF0sIG1vZGU9J3VwJywgcG9zaXRpb249ZmFsc2UpIHtcclxuICAgICAgICB0aGlzLnZhbHVlcyA9IHNlcXVlbmNlO1xyXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLnZhbHVlcykpIHtcclxuICAgICAgICAgIHRoaXMudmFsdWVzID0gW3RoaXMudmFsdWVzXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fbW9kZSA9IG1vZGU7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xyXG5cclxuICAgICAgICB0aGlzLmRydW5rV2FsayA9IG5ldyBEcnVuaygwLCB0aGlzLnZhbHVlcy5sZW5ndGggLSAxKTtcclxuXHJcbiAgICAgICAgdGhpcy5zdGFydFZhbHVlcyA9IHtcclxuICAgICAgICAgICd1cCc6IDAsXHJcbiAgICAgICAgICAnZG93bic6IHRoaXMudmFsdWVzLmxlbmd0aCAtIDEsXHJcbiAgICAgICAgICAnZHJ1bmsnOiB+fih0aGlzLnZhbHVlcy5sZW5ndGgvMiksXHJcbiAgICAgICAgICAncmFuZG9tJzogbWF0aC5yaSh0aGlzLnZhbHVlcy5sZW5ndGgpXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMucG9zaXRpb24hPT1mYWxzZSkge1xyXG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpcy5maXJzdDtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgIH1cclxuXHJcbiAgICBnZXQgbW9kZSgpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX21vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IG1vZGUobW9kZSkge1xyXG4gICAgICAgIGlmICghKG1vZGUgPT09ICd1cCcgfHwgbW9kZSA9PT0gJ2Rvd24nIHx8IG1vZGUgPT09ICdyYW5kb20nIHx8IG1vZGUgPT09ICdkcnVuaycpKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBvbmx5IG1vZGVzIGN1cnJlbnRseSBhbGxvd2VkIGFyZTogdXAsIGRvd24sIHJhbmRvbSwgZHJ1bmsnKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9tb2RlID0gbW9kZTtcclxuICAgICAgICBpZiAodGhpcy5wb3NpdGlvbikge1xyXG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHZhbHVlKCkge1xyXG4gICAgICByZXR1cm4gdGhpcy52YWx1ZXNbdGhpcy5wb3NpdGlvbl07XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IHZhbHVlKHYpIHtcclxuICAgICAgdGhpcy5wb3NpdGlvbiA9IHRoaXMudmFsdWVzLmluZGV4T2Yodik7XHJcbiAgICB9XHJcblxyXG4gICAgZmlyc3QoKSB7XHJcbiAgICAgIGlmICh0aGlzLnBvc2l0aW9uIT09ZmFsc2UpIHtcclxuICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xyXG4gICAgICAgIHJldHVybiB0aGlzLm5leHQoKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLnBvc2l0aW9uID0gdGhpcy5zdGFydFZhbHVlc1t0aGlzLl9tb2RlXTtcclxuICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcclxuICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgdXAoKSB7XHJcbiAgICAgIHRoaXMucG9zaXRpb24rKztcclxuICAgICAgdGhpcy5wb3NpdGlvbiAlPSB0aGlzLnZhbHVlcy5sZW5ndGg7XHJcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGRvd24oKSB7XHJcbiAgICAgIHRoaXMucG9zaXRpb24tLTtcclxuICAgICAgaWYgKHRoaXMucG9zaXRpb24gPCAwKSB7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbiA9ICh0aGlzLnBvc2l0aW9uICsgdGhpcy52YWx1ZXMubGVuZ3RoKSAlIHRoaXMudmFsdWVzLmxlbmd0aDtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdGhpcy52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICByYW5kb20oKSB7XHJcbiAgICAgIHRoaXMucG9zaXRpb24gPSBtYXRoLnJpKDAsIHRoaXMudmFsdWVzLmxlbmd0aCk7XHJcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGRydW5rKCkge1xyXG4gICAgICB0aGlzLmRydW5rV2Fsay5tYXggPSB0aGlzLnZhbHVlcy5sZW5ndGg7XHJcbiAgICAgIHRoaXMuZHJ1bmtXYWxrLnZhbHVlID0gdGhpcy5wb3NpdGlvbjtcclxuICAgICAgdGhpcy5wb3NpdGlvbiA9IHRoaXMuZHJ1bmtXYWxrLm5leHQoKTtcclxuICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyogZnV0dXJlIG1ldGhvZHNcclxuICAgIC5ncm91cChzdGFydCxzdG9wKSAtLSBvdXRwdXRzIGEgZ3JvdXAgb2YgbiBpdGVtcyBmcm9tIHRoZSBsaXN0LCB3aXRoIHdyYXBwaW5nXHJcbiAgICAubG9vcChzdGFydCxzdG9wKSAtLSBjb25maW5lcyBzZXF1ZW5jaW5nIHRvIGEgc3Vic2V0IG9mIHRoZSB2YWx1ZXNcclxuICAgICAgICAoY291bGQgZXZlbiBoYXZlIGEgZGlzdGluY3Rpb24gYmV0d2VlbiAub3JpZ2luYWxWYWx1ZXMgYW5kIHRoZSBhcnJheSBvZiB2YWx1ZXMgYmVpbmcgdXNlZClcclxuICAgICovXHJcbn1cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL21vZGVscy9zZXF1ZW5jZS5qcyIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IG1hdGggZnJvbSAnLi4vdXRpbC9tYXRoJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRHJ1bmsge1xuXG4gICAgY29uc3RydWN0b3IobWluPTAsIG1heD05LCB2YWx1ZT0wLCBpbmNyZW1lbnQ9MSwgbG9vcD1mYWxzZSkge1xuICAgICAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5pbmNyZW1lbnQgPSBpbmNyZW1lbnQ7XG4gICAgICAgIHRoaXMubG9vcCA9IGxvb3A7XG4gICAgfVxuXG4gICAgbmV4dCgpIHtcbiAgICAgICAgdGhpcy52YWx1ZSArPSBtYXRoLnBpY2soLTEgKiB0aGlzLmluY3JlbWVudCwgdGhpcy5pbmNyZW1lbnQpO1xuICAgICAgICBpZiAodGhpcy52YWx1ZSA+IHRoaXMubWF4KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5sb29wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5tYXggLSB0aGlzLmluY3JlbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnZhbHVlIDwgdGhpcy5taW4pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5tYXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLm1pbiArIHRoaXMuaW5jcmVtZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9tb2RlbHMvZHJ1bmsuanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5pbXBvcnQgRHJ1bmsgZnJvbSAnLi9kcnVuayc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENvdW50ZXIge1xuXG4gICAgY29uc3RydWN0b3IobWluPTAsIG1heD0xMCwgbW9kZT0ndXAnLCB2YWx1ZT1mYWxzZSkge1xuICAgICAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICAgICAgdGhpcy5kcnVua1dhbGsgPSBuZXcgRHJ1bmsodGhpcy5taW4sIHRoaXMubWF4KTtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUhPT1mYWxzZSkge1xuICAgICAgICAgIHRoaXMubmV4dCA9IHRoaXNbdGhpcy5fbW9kZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpcy5maXJzdDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldCBtb2RlKG1vZGUpIHtcbiAgICAgICAgaWYgKCEobW9kZSA9PT0gJ3VwJyB8fCBtb2RlID09PSAnZG93bicgfHwgbW9kZSA9PT0gJ3JhbmRvbScgfHwgbW9kZSA9PT0gJ2RydW5rJykpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBvbmx5IG1vZGVzIGN1cnJlbnRseSBhbGxvd2VkIGFyZTogdXAsIGRvd24sIHJhbmRvbSwgZHJ1bmsnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9tb2RlID0gbW9kZTtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUpIHtcbiAgICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IG1vZGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb2RlO1xuICAgIH1cblxuICAgIGZpcnN0KCkge1xuICAgICAgaWYgKHRoaXMudmFsdWUhPT1mYWxzZSkge1xuICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xuICAgICAgICByZXR1cm4gdGhpcy5uZXh0KCk7XG4gICAgICB9XG4gICAgICB0aGlzLnN0YXJ0VmFsdWVzID0ge1xuICAgICAgICAndXAnOiB0aGlzLm1pbixcbiAgICAgICAgJ2Rvd24nOiB0aGlzLm1heCxcbiAgICAgICAgJ2RydW5rJzogfn5tYXRoLmF2ZXJhZ2UodGhpcy5taW4sdGhpcy5tYXgpLFxuICAgICAgICAncmFuZG9tJzogbWF0aC5yaSh0aGlzLm1pbix0aGlzLm1heClcbiAgICAgIH07XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5zdGFydFZhbHVlc1t0aGlzLl9tb2RlXTtcbiAgICAgIHRoaXMubmV4dCA9IHRoaXNbdGhpcy5fbW9kZV07XG4gICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG5cbiAgICB1cCgpIHtcbiAgICAgICAgdGhpcy52YWx1ZSsrO1xuICAgICAgICBpZiAodGhpcy52YWx1ZSA+PSB0aGlzLm1heCkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIGRvd24oKSB7XG4gICAgICAgIHRoaXMudmFsdWUtLTtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUgPCB0aGlzLm1pbikge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWF4O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIHJhbmRvbSgpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IG1hdGgucmkodGhpcy5taW4sIHRoaXMubWF4KTtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgZHJ1bmsoKSB7XG4gICAgICAgIHRoaXMuZHJ1bmtXYWxrLm1pbiA9IHRoaXMubWluO1xuICAgICAgICB0aGlzLmRydW5rV2Fsay5tYXggPSB0aGlzLm1heDtcbiAgICAgICAgdGhpcy5kcnVua1dhbGsudmFsdWUgPSB0aGlzLnZhbHVlO1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5kcnVua1dhbGsubmV4dCgpO1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbW9kZWxzL2NvdW50ZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IG1hdGggPSByZXF1aXJlKCcuLi91dGlsL21hdGgnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbi8qKlxuKiBQYW4yRFxuKlxuKiBAZGVzY3JpcHRpb24gSW50ZXJmYWNlIGZvciBtb3ZpbmcgYSBzb3VuZCBhcm91bmQgYW4gYXJyYXkgb2Ygc3BlYWtlcnMuIFNwZWFrZXIgbG9jYXRpb25zIGNhbiBiZSBjdXN0b21pemVkLiBUaGUgaW50ZXJmYWNlIGNhbGN1bGF0ZXMgdGhlIGNsb3NlbmVzcyBvZiB0aGUgc291bmQgc291cmNlIHRvIGVhY2ggc3BlYWtlciBhbmQgcmV0dXJucyB0aGF0IGRpc3RhbmNlIGFzIGEgbnVtZXJpYyB2YWx1ZS5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJwYW4yRFwiPjwvc3Bhbj5cbipcbiogQGV4YW1wbGVcbiogdmFyIHBhbjJkID0gbmV3IE5leHVzLlBhbjJkKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHBhbjJkID0gbmV3IE5leHVzLlBhbjJEKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMjAwLDIwMF0sXG4qICAgJ3JhbmdlJzogMC41LCAgLy8gZGV0ZWN0aW9uIHJhZGl1cyBvZiBlYWNoIHNwZWFrZXJcbiogICAnbW9kZSc6ICdhYnNvbHV0ZScsICAgLy8gJ2Fic29sdXRlJyBvciAncmVsYXRpdmUnIHNvdW5kIG1vdmVtZW50XG4qICAgJ3NwZWFrZXJzJzogWyAgLy8gdGhlIHNwZWFrZXIgW3gseV0gcG9zaXRpb25zXG4qICAgICAgIFswLjUsMC4yXSxcbiogICAgICAgWzAuNzUsMC4yNV0sXG4qICAgICAgIFswLjgsMC41XSxcbiogICAgICAgWzAuNzUsMC43NV0sXG4qICAgICAgIFswLjUsMC44XSxcbiogICAgICAgWzAuMjUsMC43NV1cbiogICAgICAgWzAuMiwwLjVdLFxuKiAgICAgICBbMC4yNSwwLjI1XVxuKiAgIF1cbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIFwic291cmNlXCIgbm9kZSdzIHBvc2l0aW9uIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgaXMgYW4gYXJyYXkgb2YgdGhlIGFtcGxpdHVkZXMgKDAtMSksIHJlcHJlc2VudGluZyB0aGUgbGV2ZWwgb2YgZWFjaCBzcGVha2VyIChhcyBjYWxjdWxhdGVkIGJ5IGl0cyBkaXN0YW5jZSB0byB0aGUgYXVkaW8gc291cmNlKS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogcGFuMmQub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUGFuMkQgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3JhbmdlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFsyMDAsMjAwXSxcbiAgICAgICdyYW5nZSc6IDAuNSxcbiAgICAgICdtb2RlJzogJ2Fic29sdXRlJyxcbiAgICAgICdzcGVha2Vycyc6IFtcbiAgICAgICAgWzAuNSwwLjJdLFxuICAgICAgICBbMC43NSwwLjI1XSxcbiAgICAgICAgWzAuOCwwLjVdLFxuICAgICAgICBbMC43NSwwLjc1XSxcbiAgICAgICAgWzAuNSwwLjhdLFxuICAgICAgICBbMC4yNSwwLjc1XSxcbiAgICAgICAgWzAuMiwwLjVdLFxuICAgICAgICBbMC4yNSwwLjI1XVxuICAgICAgXVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLnZhbHVlID0ge1xuICAgICAgeDogbmV3IFN0ZXAoMCwxLDAsMC41KSxcbiAgICAgIHk6IG5ldyBTdGVwKDAsMSwwLDAuNSlcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgQWJzb2x1dGUgb3IgcmVsYXRpdmUgbW91c2UgaW50ZXJhY3Rpb24uIEluIFwiYWJzb2x1dGVcIiBtb2RlLCB0aGUgc291cmNlIG5vZGUgd2lsbCBqdW1wIHRvIHlvdXIgbW91c2UgcG9zaXRpb24gb24gbW91c2UgY2xpY2suIEluIFwicmVsYXRpdmVcIiBtb2RlLCBpdCBkb2VzIG5vdC5cbiAgICAqL1xuICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZTtcblxuICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICB4OiBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMubW9kZSwnaG9yaXpvbnRhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKSxcbiAgICAgIHk6IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5tb2RlLCd2ZXJ0aWNhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKVxuICAgIH07XG4gICAgdGhpcy5wb3NpdGlvbi54LnZhbHVlID0gdGhpcy52YWx1ZS54Lm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5wb3NpdGlvbi55LnZhbHVlID0gdGhpcy52YWx1ZS55Lm5vcm1hbGl6ZWQ7XG5cbiAgICAvKipcbiAgICBBbiBhcnJheSBvZiBzcGVha2VyIGxvY2F0aW9ucy4gVXBkYXRlIHRoaXMgd2l0aCAubW92ZVNwZWFrZXIoKSBvciAubW92ZUFsbFNwZWFrZXJzKClcbiAgICAqL1xuICAgIHRoaXMuc3BlYWtlcnMgPSB0aGlzLnNldHRpbmdzLnNwZWFrZXJzO1xuXG4gICAgLyoqXG4gICAgUmV3cml0ZTogVGhlIG1heGltdW0gZGlzdGFuY2UgZnJvbSBhIHNwZWFrZXIgdGhhdCB0aGUgc291cmNlIG5vZGUgY2FuIGJlIGZvciBpdCB0byBiZSBoZWFyZCBmcm9tIHRoYXQgc3BlYWtlci4gQSBsb3cgcmFuZ2UgKDAuMSkgd2lsbCByZXN1bHQgaW4gc3BlYWtlcnMgb25seSBwbGF5aW5nIHdoZW4gdGhlIHNvdW5kIGlzIHZlcnkgY2xvc2UgaXQuIERlZmF1bHQgaXMgMC41IChoYWxmIG9mIHRoZSBpbnRlcmZhY2UpLlxuICAgICovXG4gICAgdGhpcy5yYW5nZSA9IHRoaXMuc2V0dGluZ3MucmFuZ2U7XG5cbiAgICAvKipcbiAgICBUaGUgY3VycmVudCBsZXZlbHMgZm9yIGVhY2ggc3BlYWtlci4gVGhpcyBpcyBjYWxjdWxhdGVkIHdoZW4gYSBzb3VyY2Ugbm9kZSBvciBzcGVha2VyIG5vZGUgaXMgbW92ZWQgdGhyb3VnaCBpbnRlcmFjdGlvbiBvciBwcm9ncmFtYXRpY2FsbHkuXG4gICAgKi9cbiAgICB0aGlzLmxldmVscyA9IFtdO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgICB0aGlzLmNhbGN1bGF0ZUxldmVscygpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG5cblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmtub2IpO1xuXG5cbiAgICAvLyBhZGQgc3BlYWtlcnNcbiAgICB0aGlzLnNwZWFrZXJFbGVtZW50cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5zcGVha2Vycy5sZW5ndGg7aSsrKSB7XG4gICAgICBsZXQgc3BlYWtlckVsZW1lbnQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHNwZWFrZXJFbGVtZW50KTtcblxuICAgICAgdGhpcy5zcGVha2VyRWxlbWVudHMucHVzaChzcGVha2VyRWxlbWVudCk7XG4gICAgfVxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgICAgIHRoaXMuX21pbkRpbWVuc2lvbiA9IE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpO1xuXG4gICAgICAgIHRoaXMua25vYlJhZGl1cyA9IHtcbiAgICAgICAgICBvZmY6IH5+KHRoaXMuX21pbkRpbWVuc2lvbi8xMDApICogMyArIDUsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMua25vYlJhZGl1cy5vbiA9IHRoaXMua25vYlJhZGl1cy5vZmYgKiAyO1xuXG4gICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIpO1xuICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQvMik7XG4gICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYlJhZGl1cy5vZmYpO1xuXG4gICAgICAgIGZvciAobGV0IGk9MDtpPHRoaXMuc3BlYWtlcnMubGVuZ3RoO2krKykge1xuICAgICAgICAgIGxldCBzcGVha2VyRWxlbWVudCA9IHRoaXMuc3BlYWtlckVsZW1lbnRzW2ldO1xuICAgICAgICAgIGxldCBzcGVha2VyID0gdGhpcy5zcGVha2Vyc1tpXTtcbiAgICAgICAgICBzcGVha2VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2N4JyxzcGVha2VyWzBdKnRoaXMud2lkdGgpO1xuICAgICAgICAgIHNwZWFrZXJFbGVtZW50LnNldEF0dHJpYnV0ZSgnY3knLHNwZWFrZXJbMV0qdGhpcy5oZWlnaHQpO1xuICAgICAgICAgIHNwZWFrZXJFbGVtZW50LnNldEF0dHJpYnV0ZSgncicsdGhpcy5fbWluRGltZW5zaW9uLzIwICsgNSk7XG4gICAgICAgICAgc3BlYWtlckVsZW1lbnQuc2V0QXR0cmlidXRlKCdmaWxsLW9wYWNpdHknLCAnMCcpO1xuICAgICAgICB9XG5cbiAgICAgIHRoaXMucG9zaXRpb24ueC5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICAgIHRoaXMucG9zaXRpb24ueS5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcblxuICAgICAgICAvLyBuZXh0LCBuZWVkIHRvXG4gICAgICAgIC8vIHJlc2l6ZSBwb3NpdGlvbnNcbiAgICAgICAgLy8gY2FsY3VsYXRlIHNwZWFrZXIgZGlzdGFuY2VzXG4gICAgICB0aGlzLmNhbGN1bGF0ZUxldmVscygpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgY29sb3JJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5zcGVha2Vycy5sZW5ndGg7aSsrKSB7XG4gICAgICBsZXQgc3BlYWtlckVsZW1lbnQgPSB0aGlzLnNwZWFrZXJFbGVtZW50c1tpXTtcbiAgICAgIHNwZWFrZXJFbGVtZW50LnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgICBzcGVha2VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgfVxuXG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgdGhpcy5rbm9iQ29vcmRpbmF0ZXMgPSB7XG4gICAgICB4OiB0aGlzLnZhbHVlLngubm9ybWFsaXplZCAqIHRoaXMud2lkdGgsXG4gICAgICB5OiB0aGlzLmhlaWdodCAtIHRoaXMudmFsdWUueS5ub3JtYWxpemVkICogdGhpcy5oZWlnaHRcbiAgICB9O1xuXG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkNvb3JkaW5hdGVzLngpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmtub2JDb29yZGluYXRlcy55KTtcbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgdGhpcy5wb3NpdGlvbi54LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5wb3NpdGlvbi55LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMucG9zaXRpb24ueC51cGRhdGUodGhpcy5tb3VzZSk7XG4gICAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKHRoaXMubW91c2UpO1xuICAgICAgLy8gcG9zaXRpb24ueCBhbmQgcG9zaXRpb24ueSBhcmUgbm9ybWFsaXplZFxuICAgICAgLy8gc28gYXJlIHRoZSBsZXZlbHNcbiAgICAgIC8vIGxpa2VseSBkb24ndCBuZWVkIHRoaXMudmFsdWUgYXQgYWxsIC0tIG9ubHkgdXNlZCBmb3IgZHJhd2luZ1xuICAgICAgLy8gbm90IGdvaW5nIHRvIGJlIGEgJ3N0ZXAnIG9yICdtaW4nIGFuZCAnbWF4JyBpbiB0aGlzIG9uZS5cbiAgICAgIHRoaXMuY2FsY3VsYXRlTGV2ZWxzKCk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5sZXZlbHMpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICByZWxlYXNlKCkge1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBnZXQgbm9ybWFsaXplZCgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogdGhpcy52YWx1ZS54Lm5vcm1hbGl6ZWQsXG4gICAgICB5OiB0aGlzLnZhbHVlLnkubm9ybWFsaXplZFxuICAgIH07XG4gIH1cblxuICBjYWxjdWxhdGVMZXZlbHMoKSB7XG4gICAgdGhpcy52YWx1ZS54LnVwZGF0ZU5vcm1hbCggdGhpcy5wb3NpdGlvbi54LnZhbHVlICk7XG4gICAgdGhpcy52YWx1ZS55LnVwZGF0ZU5vcm1hbCggdGhpcy5wb3NpdGlvbi55LnZhbHVlICk7XG4gICAgdGhpcy5sZXZlbHMgPSBbXTtcbiAgICB0aGlzLnNwZWFrZXJzLmZvckVhY2goKHMsaSkgPT4ge1xuICAgICAgbGV0IGRpc3RhbmNlID0gbWF0aC5kaXN0YW5jZShzWzBdKnRoaXMud2lkdGgsc1sxXSp0aGlzLmhlaWdodCx0aGlzLnBvc2l0aW9uLngudmFsdWUqdGhpcy53aWR0aCwoMS10aGlzLnBvc2l0aW9uLnkudmFsdWUpKnRoaXMuaGVpZ2h0KTtcbiAgICAgIGxldCBsZXZlbCA9IG1hdGguY2xpcCgxLWRpc3RhbmNlLyh0aGlzLnJhbmdlKnRoaXMud2lkdGgpLDAsMSk7XG4gICAgICB0aGlzLmxldmVscy5wdXNoKGxldmVsKTtcbiAgICAgIHRoaXMuc3BlYWtlckVsZW1lbnRzW2ldLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywgbGV2ZWwpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gIE1vdmUgdGhlIGF1ZGlvIHNvdXJjZSBub2RlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG4gIEBwYXJhbSB4IHtudW1iZXJ9IE5ldyB4IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuICBAcGFyYW0geSB7bnVtYmVyfSBOZXcgeSBsb2NhdGlvbiwgbm9ybWFsaXplZCAwLTFcbiAgKi9cbiAgbW92ZVNvdXJjZSh4LHkpIHtcbiAgICBsZXQgbG9jYXRpb24gPSB7XG4gICAgICB4OiB4KnRoaXMud2lkdGgsXG4gICAgICB5OiB5KnRoaXMuaGVpZ2h0XG4gICAgfTtcbiAgICB0aGlzLnBvc2l0aW9uLngudXBkYXRlKGxvY2F0aW9uKTtcbiAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKGxvY2F0aW9uKTtcbiAgICB0aGlzLmNhbGN1bGF0ZUxldmVscygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLmxldmVscyk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBNb3ZlIGEgc3BlYWtlciBub2RlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG4gIEBwYXJhbSBpbmRleCB7bnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlYWtlciB0byBtb3ZlXG4gIEBwYXJhbSB4IHtudW1iZXJ9IE5ldyB4IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuICBAcGFyYW0geSB7bnVtYmVyfSBOZXcgeSBsb2NhdGlvbiwgbm9ybWFsaXplZCAwLTFcbiAgKi9cbiAgbW92ZVNwZWFrZXIoaW5kZXgseCx5KSB7XG5cbiAgICB0aGlzLnNwZWFrZXJzW2luZGV4XSA9IFt4LHldO1xuICAgIHRoaXMuc3BlYWtlckVsZW1lbnRzW2luZGV4XS5zZXRBdHRyaWJ1dGUoJ2N4JywgeCp0aGlzLndpZHRoKTtcbiAgICB0aGlzLnNwZWFrZXJFbGVtZW50c1tpbmRleF0uc2V0QXR0cmlidXRlKCdjeScsIHkqdGhpcy5oZWlnaHQpO1xuICAgIHRoaXMuY2FsY3VsYXRlTGV2ZWxzKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMubGV2ZWxzKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuXG4gIH1cblxuICAvKipcbiAgU2V0IGFsbCBzcGVha2VyIGxvY2F0aW9uc1xuICBAcGFyYW0gbG9jYXRpb25zIHtBcnJheX0gQXJyYXkgb2Ygc3BlYWtlciBsb2NhdGlvbnMuIEVhY2ggaXRlbSBpbiB0aGUgYXJyYXkgc2hvdWxkIGJlIGFuIGFycmF5IG9mIG5vcm1hbGl6ZWQgeCBhbmQgeSBjb29yZGluYXRlcy5cblxuICBzZXRTcGVha2Vycyhsb2NhdGlvbnMpIHtcblxuICB9XG4gICovXG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL3BhbjJkLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcblxuLyoqXG4qIFRpbHRcbipcbiogQGRlc2NyaXB0aW9uIERldmljZSB0aWx0IHNlbnNvciB3aXRoIDIgb3IgMyBheGVzIChkZXBlbmRpbmcgb24geW91ciBkZXZpY2UgYW5kIGJyb3dzZXIpLlxuKlxuKiBAZGVtbyA8c3BhbiBuZXh1cy11aT0ndGlsdCc+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgdGlsdCA9IG5ldyBOZXh1cy5UaWx0KCcjdGFyZ2V0JylcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYXQgYSByZWd1bGFyIGludGVydmFsLCBhcyBsb25nIGFzIHRoaXMgaW50ZXJmYWNlIGlzIGFjdGl2ZSAoc2VlIHRoZSBpbnRlcmZhY2UncyA8aT4uYWN0aXZlPC9pPiBwcm9wZXJ0eSk8YnI+XG4qIFRoZSBldmVudCBkYXRhIGlzIGFuIDxpPm9iamVjdDwvaT4gY29udGFpbmluZyB4IChudW1iZXIpIGFuZCB5IChudW1iZXIpIHByb3BlcnRpZXMgd2hpY2ggcmVwcmVzZW50IHRoZSBjdXJyZW50IHRpbHQgc3RhdGUgb2YgdGhlIGRldmljZS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogdGlsdC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUaWx0IGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbODAsODBdXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuX2FjdGl2ZSA9IHRydWU7XG5cbiAgICB0aGlzLmluaXQoKTtcblxuICAgIC8vIGFkZCBldmVudCBsaXN0ZW5lciBmb3IgZGV2aWNlIG9yaWVudGF0aW9uXG5cbiAgXHR0aGlzLmJvdW5kVXBkYXRlID0gdGhpcy51cGRhdGUuYmluZCh0aGlzKTtcbiAgLy9cdHRoaXMuYm91bmRNb3pUaWx0ID0gdGhpcy5tb3pUaWx0LmJpbmQodGhpcylcblxuICBcdGlmICh3aW5kb3cuRGV2aWNlT3JpZW50YXRpb25FdmVudCkge1xuICBcdFx0dGhpcy5vcmllbnRhdGlvbkxpc3RlbmVyID0gd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2RldmljZW9yaWVudGF0aW9uJywgdGhpcy5ib3VuZFVwZGF0ZSwgZmFsc2UpO1xuICBcdH0gZWxzZSB7XG4gICAgICB0aGlzLl9hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcbiAgICB9XG5cblxuXG4gICAgICAvKmVsc2UgaWYgKHdpbmRvdy5PcmllbnRhdGlvbkV2ZW50KSB7XG4gIC8vXHQgIFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ01vek9yaWVudGF0aW9uJywgdGhpcy5ib3VuZE1velRpbHQsIGZhbHNlKTtcbiAgXHR9IGVsc2Uge1xuICBcdCAgXHRjb25zb2xlLmxvZygnTm90IHN1cHBvcnRlZCBvbiB5b3VyIGRldmljZSBvciBicm93c2VyLicpO1xuICBcdH0gKi9cblxuXG4gIH1cblxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy50aXRsZSA9IHN2Zy5jcmVhdGUoJ3RleHQnKTtcbiAgICB0aGlzLmNpcmNsZVggPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLmNpcmNsZVkgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLmNpcmNsZVogPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgIHRoaXMuYmFyWCA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmJhclkgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG4gICAgdGhpcy5iYXJaID0gc3ZnLmNyZWF0ZSgncGF0aCcpO1xuXG4gICAgdGhpcy5iYXJYMiA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmJhclkyID0gc3ZnLmNyZWF0ZSgncGF0aCcpO1xuICAgIHRoaXMuYmFyWjIgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG5cbiAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC44Jyk7XG4gICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScsJzAuOCcpO1xuICAgIHRoaXMuYmFyWi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLCcwLjgnKTtcbiAgICB0aGlzLmJhclgyLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScsJzAuOCcpO1xuICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC44Jyk7XG4gICAgdGhpcy5iYXJaMi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLCcwLjgnKTtcblxuICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoKjMvMTIpO1xuICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmhlaWdodCozLzQpO1xuICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMuaGVpZ2h0LzEwKTtcbiAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC40Jyk7XG5cbiAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdjeCcsdGhpcy53aWR0aCo2LzEyKTtcbiAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQqMy80KTtcbiAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmhlaWdodC8xMCk7XG4gICAgdGhpcy5jaXJjbGVZLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScsJzAuNCcpO1xuXG4gICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMud2lkdGgqOS8xMik7XG4gICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMuaGVpZ2h0KjMvNCk7XG4gICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgncicsdGhpcy5oZWlnaHQvMTApO1xuICAgIHRoaXMuY2lyY2xlWi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLCcwLjQnKTtcblxuXG4gICAgdGhpcy5iYXJYLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG4gICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG4gICAgdGhpcy5iYXJaLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG5cbiAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICB0aGlzLmJhclkuc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcblxuICAgIHRoaXMuYmFyWDIuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLE1hdGgucm91bmQodGhpcy5oZWlnaHQvMzApKTtcbiAgICB0aGlzLmJhclkyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG4gICAgdGhpcy5iYXJaMi5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsTWF0aC5yb3VuZCh0aGlzLmhlaWdodC8zMCkpO1xuXG4gICAgdGhpcy5iYXJYMi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAnbm9uZScpO1xuICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZSgnZmlsbCcsICdub25lJyk7XG5cblxuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCd4Jyx0aGlzLndpZHRoLzIpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCd5Jyx0aGlzLmhlaWdodC8zKzcpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdmb250LXNpemUnLCcxNXB4Jyk7XG4gICAgdGhpcy50aXRsZS5zZXRBdHRyaWJ1dGUoJ2ZvbnQtd2VpZ2h0JywnYm9sZCcpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdsZXR0ZXItc3BhY2luZycsJzJweCcpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC43Jyk7XG4gICAgdGhpcy50aXRsZS5zZXRBdHRyaWJ1dGUoJ3RleHQtYW5jaG9yJywnbWlkZGxlJyk7XG4gICAgdGhpcy50aXRsZS50ZXh0Q29udGVudCA9ICdUSUxUJztcblxuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2lyY2xlWCk7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2lyY2xlWSk7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2lyY2xlWik7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJYKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJZKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJaKTtcblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhclgyKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJZMik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuYmFyWjIpO1xuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudGl0bGUpO1xuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIGlmICh0aGlzLl9hY3RpdmUpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG4gICAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLmxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubGlnaHQpO1xuICAgICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLmxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubGlnaHQpO1xuICAgICAgdGhpcy5iYXJaLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhclgyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhclkyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLnRpdGxlLnNldEF0dHJpYnV0ZSgnZmlsbCcsdGhpcy5jb2xvcnMubGlnaHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuICAgICAgdGhpcy5jaXJjbGVZLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuICAgICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWDIuc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWjIuc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgfVxuXG4gIH1cblxuICB1cGRhdGUodikge1xuICAgIGlmICh0aGlzLl9hY3RpdmUpe1xuXG4gICAgICBsZXQgeSA9IHYuYmV0YTtcbiAgICAgIGxldCB4ID0gdi5nYW1tYTtcbiAgICAgIGxldCB6ID0gdi5hbHBoYTtcblxuICAgICAgLy8gdGFrZSB0aGUgb3JpZ2luYWwgLTkwIHRvIDkwIHNjYWxlIGFuZCBub3JtYWxpemUgaXQgMC0xXG4gICAgICB4ID0gbWF0aC5zY2FsZSh4LC05MCw5MCwwLDEpO1xuICAgICAgeSA9IG1hdGguc2NhbGUoeSwtOTAsOTAsMCwxKTtcbiAgICAgIHogPSBtYXRoLnNjYWxlKHosMCwzNjAsMCwxKTtcblxuXG4gICAgICBsZXQgaGFuZGxlUG9pbnRzID0ge1xuICAgICAgICBzdGFydDogTWF0aC5QSSoxLjUsXG4gICAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHgsMCwwLjUsTWF0aC5QSSoxLjUsTWF0aC5QSSowLjUpICwgTWF0aC5QSSowLjUsIE1hdGguUEkqMS41IClcbiAgICAgIH07XG4gICAgICBsZXQgaGFuZGxlMlBvaW50cyA9IHtcbiAgICAgICAgc3RhcnQ6IE1hdGguUEkqMi41LFxuICAgICAgICBlbmQ6IG1hdGguY2xpcCggbWF0aC5zY2FsZSh4LDAuNSwxLE1hdGguUEkqMi41LE1hdGguUEkqMS41KSAsIE1hdGguUEkqMS41LCBNYXRoLlBJKjIuNSApXG4gICAgICB9O1xuXG4gICAgICBsZXQgaGFuZGxlUGF0aCA9IHN2Zy5hcmModGhpcy5jaXJjbGVYLmN4LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWC5jeS5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVguci5iYXNlVmFsLnZhbHVlLCBoYW5kbGVQb2ludHMuc3RhcnQsIGhhbmRsZVBvaW50cy5lbmQpO1xuICAgICAgbGV0IGhhbmRsZTJQYXRoID0gc3ZnLmFyYyh0aGlzLmNpcmNsZVguY3guYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVYLmN5LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWC5yLmJhc2VWYWwudmFsdWUsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgICAgdGhpcy5iYXJYLnNldEF0dHJpYnV0ZSgnZCcsIGhhbmRsZVBhdGgpO1xuICAgICAgdGhpcy5iYXJYMi5zZXRBdHRyaWJ1dGUoJ2QnLCBoYW5kbGUyUGF0aCk7XG5cblxuXG5cblxuICAgICAgaGFuZGxlUG9pbnRzID0ge1xuICAgICAgICBzdGFydDogTWF0aC5QSSoxLjUsXG4gICAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHksMCwwLjUsTWF0aC5QSSoxLjUsTWF0aC5QSSowLjUpICwgTWF0aC5QSSowLjUsIE1hdGguUEkqMS41IClcbiAgICAgIH07XG4gICAgICBoYW5kbGUyUG9pbnRzID0ge1xuICAgICAgICBzdGFydDogTWF0aC5QSSoyLjUsXG4gICAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHksMC41LDEsTWF0aC5QSSoyLjUsTWF0aC5QSSoxLjUpICwgTWF0aC5QSSoxLjUsIE1hdGguUEkqMi41IClcbiAgICAgIH07XG5cbiAgICAgIGhhbmRsZVBhdGggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWS5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVkuY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVZLnIuYmFzZVZhbC52YWx1ZSwgaGFuZGxlUG9pbnRzLnN0YXJ0LCBoYW5kbGVQb2ludHMuZW5kKTtcbiAgICAgIGhhbmRsZTJQYXRoID0gc3ZnLmFyYyh0aGlzLmNpcmNsZVkuY3guYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVZLmN5LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWS5yLmJhc2VWYWwudmFsdWUsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnZCcsIGhhbmRsZVBhdGgpO1xuICAgICAgdGhpcy5iYXJZMi5zZXRBdHRyaWJ1dGUoJ2QnLCBoYW5kbGUyUGF0aCk7XG5cblxuXG5cblxuXG4gICAgICBoYW5kbGVQb2ludHMgPSB7XG4gICAgICAgIHN0YXJ0OiBNYXRoLlBJKjEuNSxcbiAgICAgICAgZW5kOiBtYXRoLmNsaXAoIG1hdGguc2NhbGUoeiwwLDAuNSxNYXRoLlBJKjEuNSxNYXRoLlBJKjAuNSkgLCBNYXRoLlBJKjAuNSwgTWF0aC5QSSoxLjUgKVxuICAgICAgfTtcbiAgICAgIGhhbmRsZTJQb2ludHMgPSB7XG4gICAgICAgIHN0YXJ0OiBNYXRoLlBJKjIuNSxcbiAgICAgICAgZW5kOiBtYXRoLmNsaXAoIG1hdGguc2NhbGUoeiwwLjUsMSxNYXRoLlBJKjIuNSxNYXRoLlBJKjEuNSkgLCBNYXRoLlBJKjEuNSwgTWF0aC5QSSoyLjUgKVxuICAgICAgfTtcblxuICAgICAgaGFuZGxlUGF0aCA9IHN2Zy5hcmModGhpcy5jaXJjbGVaLmN4LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWi5jeS5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVouci5iYXNlVmFsLnZhbHVlLCBoYW5kbGVQb2ludHMuc3RhcnQsIGhhbmRsZVBvaW50cy5lbmQpO1xuICAgICAgaGFuZGxlMlBhdGggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWi5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVouY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVaLnIuYmFzZVZhbC52YWx1ZSwgaGFuZGxlMlBvaW50cy5zdGFydCwgaGFuZGxlMlBvaW50cy5lbmQpO1xuXG4gICAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKCdkJywgaGFuZGxlUGF0aCk7XG4gICAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZSgnZCcsIGhhbmRsZTJQYXRoKTtcblxuXG4gICAgICAvKlxuXG4gICAgICBsZXQgcG9pbnRzWCA9IHtcbiAgICAgICAgc3RhcnQ6IDAsXG4gICAgICAgIGVuZDogbWF0aC5zY2FsZSggeCwgMCwgMSwgMCwgTWF0aC5QSSoyIClcbiAgICAgIH07XG5cbiAgICAvLyAgY29uc29sZS5sb2codGhpcy5jaXJjbGVYLmN4LmJhc2VWYWwudmFsdWUpO1xuXG4gICAgICBsZXQgcGF0aFggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWC5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVguY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVYLnIuYmFzZVZhbC52YWx1ZSoyLCBwb2ludHNYLnN0YXJ0LCBwb2ludHNYLmVuZCk7XG5cbiAgICAgIHRoaXMuYmFyWC5zZXRBdHRyaWJ1dGUoJ2QnLHBhdGhYKTsgKi9cblxuICAgICAgLy90aGlzLnRleHRILnRleHRDb250ZW50ID0gbWF0aC5wcnVuZSh4LDIpO1xuICAgICAgLy90aGlzLnRleHRWLnRleHRDb250ZW50ID0gbWF0aC5wcnVuZSh5LDIpO1xuICAgICAgLy9cbiAgICAvLyAgdGhpcy5jaXJjbGVYLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScseCk7XG4gICAgLy8gIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLHkpO1xuICAgIC8vICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKCdvcGFjaXR5Jyx6KTtcblxuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLCB7XG4gICAgICAgIHg6IHgsXG4gICAgICAgIHk6IHksXG4gICAgICAgIHo6IHpcbiAgICAgIH0pO1xuXG4gICAgfVxuXG4gIH1cblxuICBjbGljaygpIHtcbiAgICBpZiAod2luZG93LkRldmljZU9yaWVudGF0aW9uRXZlbnQpIHtcbiAgICAgIHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICBXaGV0aGVyIHRoZSBpbnRlcmZhY2UgaXMgb24gKGVtaXR0aW5nIHZhbHVlcykgb3Igb2ZmIChwYXVzZWQgJiBub3QgZW1pdHRpbmcgdmFsdWVzKS4gU2V0dGluZyB0aGlzIHByb3BlcnR5IHdpbGwgdXBkYXRlIGl0LlxuICBAdHlwZSB7Ym9vbGVhbn1cbiAgKi9cblxuICBnZXQgYWN0aXZlKCkge1xuICAgIHJldHVybiB0aGlzLl9hY3RpdmU7XG4gIH1cblxuICBzZXQgYWN0aXZlKG9uKSB7XG4gICAgdGhpcy5fYWN0aXZlID0gb247XG4gICAgdGhpcy5jb2xvckludGVyZmFjZSgpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGV2aWNlb3JpZW50YXRpb24nLCB0aGlzLmJvdW5kVXBkYXRlLCBmYWxzZSk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvdGlsdC5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IGRvbSA9IHJlcXVpcmUoJy4uL3V0aWwvZG9tJyk7XG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgU2xpZGVyVGVtcGxhdGUgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL3NsaWRlcnRlbXBsYXRlJyk7XG5sZXQgdG91Y2ggPSByZXF1aXJlKCcuLi91dGlsL3RvdWNoJyk7XG5cblxuXG5jbGFzcyBTaW5nbGVTbGlkZXIgZXh0ZW5kcyBTbGlkZXJUZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnc2NhbGUnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMTIwLDIwXSxcbiAgICAgICdvcmllbnRhdGlvbic6ICd2ZXJ0aWNhbCcsXG4gICAgICAnbW9kZSc6ICdhYnNvbHV0ZScsXG4gICAgICAnc2NhbGUnOiBbMCwxXSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDAsXG4gICAgICAnaGFzS25vYic6IHRydWVcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG5cbiAgICAvKiBldmVudHMgKi9cblxuICAgIGlmICghdG91Y2guZXhpc3RzKSB7XG5cbiAgICAgIHRoaXMuY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgIHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24gPSB7XG4gICAgICAgICAgaW5kZXg6IHRoaXMuaW5kZXgsXG4gICAgICAgICAgdmFsdWU6IHRoaXMudmFsdWVcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5kb3duKCk7XG4gICAgICAgIHRoaXMubXVsdGlzbGlkZXIudmFsdWVzW3RoaXMuaW5kZXhdID0gdGhpcy52YWx1ZTtcbiAgICAgIH07XG4gICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgKGUpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICBpZiAoIXRoaXMub2Zmc2V0KSB7XG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IGRvbS5maW5kUG9zaXRpb24odGhpcy5lbGVtZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVNb3VzZShlLHRoaXMub2Zmc2V0KTtcbiAgICAgICAgICB0aGlzLmRvd24oKTtcbiAgICAgICAgICB0aGlzLm11bHRpc2xpZGVyLnZhbHVlc1t0aGlzLmluZGV4XSA9IHRoaXMudmFsdWU7XG4gICAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJwb2xhdGlvbikge1xuICAgICAgICAgICAgbGV0IGRpc3RhbmNlID0gTWF0aC5hYnModGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uLmluZGV4LXRoaXMuaW5kZXgpO1xuICAgICAgICAgICAgaWYgKCBkaXN0YW5jZSA+IDEgKSB7XG4gICAgICAgICAgICAgIGxldCBsb3cgPSBNYXRoLm1pbih0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24uaW5kZXgsdGhpcy5pbmRleCk7XG4gICAgICAgICAgICAgIGxldCBoaWdoID0gTWF0aC5tYXgodGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uLmluZGV4LHRoaXMuaW5kZXgpO1xuICAgICAgICAgICAgICBsZXQgbG93VmFsdWUgPSB0aGlzLm11bHRpc2xpZGVyLnNsaWRlcnNbbG93XS52YWx1ZTtcbiAgICAgICAgICAgICAgbGV0IGhpZ2hWYWx1ZSA9IHRoaXMubXVsdGlzbGlkZXIuc2xpZGVyc1toaWdoXS52YWx1ZTtcbiAgICAgICAgICAgICAgZm9yIChsZXQgaT1sb3c7aTxoaWdoO2krKykge1xuICAgICAgICAgICAgICAgIHRoaXMubXVsdGlzbGlkZXIuc2xpZGVyc1tpXS52YWx1ZSA9IG1hdGguaW50ZXJwKCAoaS1sb3cpL2Rpc3RhbmNlLCBsb3dWYWx1ZSwgaGlnaFZhbHVlICk7XG4gICAgICAgICAgICAgICAgbGV0IHNtb290aGVkVmFsdWUgPSB0aGlzLm11bHRpc2xpZGVyLnNsaWRlcnNbaV0udmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbaV0gPSBzbW9vdGhlZFZhbHVlO1xuICAgICAgICAgICAgICAgIHRoaXMubXVsdGlzbGlkZXIudXBkYXRlKGksc21vb3RoZWRWYWx1ZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24gPSB7XG4gICAgICAgICAgICBpbmRleDogdGhpcy5pbmRleCxcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cblxuICAgICAgdGhpcy5tb3ZlID0gKCkgPT4ge1xuICAgICAgfTtcbiAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCAoZSkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tdWx0aXNsaWRlci5pbnRlcmFjdGluZykge1xuICAgICAgICAgIGlmICghdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbih0aGlzLmVsZW1lbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLm1vdXNlID0gZG9tLmxvY2F0ZU1vdXNlKGUsdGhpcy5vZmZzZXQpO1xuICAgICAgICAgIHRoaXMuc2xpZGUoKTtcbiAgICAgICAgICB0aGlzLm11bHRpc2xpZGVyLnZhbHVlc1t0aGlzLmluZGV4XSA9IHRoaXMudmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG5cbiAgICAgIHRoaXMucmVsZWFzZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5tdWx0aXNsaWRlci5pbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24gPSBmYWxzZTtcbiAgICAgIH07XG4gICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbdGhpcy5pbmRleF0gPSB0aGlzLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbdGhpcy5pbmRleF0gPSB0aGlzLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIH1cblxuICAgIHRoaXMuY3VzdG9tU3R5bGUoKTtcbiAgfVxuXG4gIGN1c3RvbVN0eWxlKCkge1xuXG4gICAgLyogc3R5bGUgY2hhbmdlcyAqL1xuXG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd4JywwKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsJ3RyYW5zbGF0ZSgwLDApJyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsMCk7IC8vIGNvcm5lciByYWRpdXNcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3J5JywwKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx0aGlzLndpZHRoKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsdGhpcy5oZWlnaHQpO1xuXG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneCcsMCk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywndHJhbnNsYXRlKDAsMCknKTtcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeCcsMCk7IC8vIGNvcm5lciByYWRpdXNcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeScsMCk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgnd2lkdGgnLHRoaXMud2lkdGgpO1xuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsdGhpcy5oZWlnaHQpO1xuXG4gIH1cblxufVxuXG4vKipcbiogTXVsdGlzbGlkZXJcbipcbiogQGRlc2NyaXB0aW9uIE11bHRpc2xpZGVyXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwibXVsdGlzbGlkZXJcIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBtdWx0aXNsaWRlciA9IG5ldyBOZXh1cy5NdWx0aXNsaWRlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBtdWx0aXNsaWRlciA9IG5ldyBOZXh1cy5NdWx0aXNsaWRlcignI3RhcmdldCcse1xuKiAgJ3NpemUnOiBbMjAwLDEwMF0sXG4qICAnbnVtYmVyT2ZTbGlkZXJzJzogNSxcbiogICdtaW4nOiAwLFxuKiAgJ21heCc6IDEsXG4qICAnc3RlcCc6IDAsXG4qICAndmFsdWVzJzogWzAuNywwLjcsMC43LDAuNywwLjddXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIFRoZSBldmVudCBkYXRhIGFuIG9iamVjdCBjb250YWluaW5nIDxpPmluZGV4PC9pPiBhbmQgPGk+dmFsdWU8L2k+IHByb3BlcnRpZXNcbipcbiogQG91dHB1dGV4YW1wbGVcbiogbXVsdGlzbGlkZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKi9cblxuLypcblByb3BlcnRpZXNcbi52YWx1ZXNcblxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTXVsdGlzbGlkZXIgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3ZhbHVlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFsyMDAsMTAwXSxcbiAgICAgICdudW1iZXJPZlNsaWRlcnMnOiA1LFxuICAgICAgJ21pbic6IDAsXG4gICAgICAnbWF4JzogMSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZXMnOiBbMC43LDAuNywwLjcsMC43LDAuN11cbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5fbnVtYmVyT2ZTbGlkZXJzID0gdGhpcy5zZXR0aW5ncy5udW1iZXJPZlNsaWRlcnM7XG4gICAgdGhpcy52YWx1ZXMgPSB0aGlzLnNldHRpbmdzLnZhbHVlcztcblxuICAgIHRoaXMuc2xpZGVycyA9IFtdO1xuXG4gICAgdGhpcy5pbnRlcmFjdGluZyA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgbGV0IG1pbiA9IHRoaXMuc2V0dGluZ3MubWluO1xuICAgIGxldCBtYXggPSB0aGlzLnNldHRpbmdzLm1heDtcbiAgICBsZXQgc3RlcCA9IHRoaXMuc2V0dGluZ3Muc3RlcDtcblxuICAgIGlmICh0aGlzLnNsaWRlcnMubGVuZ3RoKSB7XG4gICAgICBtaW4gPSB0aGlzLnNsaWRlcnNbMF0ubWluO1xuICAgICAgbWF4ID0gdGhpcy5zbGlkZXJzWzBdLm1heDtcbiAgICAgIHN0ZXAgPSB0aGlzLnNsaWRlcnNbMF0uc3RlcDtcbiAgICB9XG5cbiAgICB0aGlzLnNsaWRlcnMgPSBbXTtcblxuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuX251bWJlck9mU2xpZGVycztpKyspIHtcbiAgICAgIGxldCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG5cbiAgICAgIGxldCBzbGlkZXIgPSBuZXcgU2luZ2xlU2xpZGVyKGNvbnRhaW5lciwge1xuICAgICAgICAgIHNjYWxlOiBbbWluLG1heF0sXG4gICAgICAgICAgc3RlcDogc3RlcCxcbiAgICAgICAgICBtb2RlOiAnYWJzb2x1dGUnLFxuICAgICAgICAgIG9yaWVudGF0aW9uOiAndmVydGljYWwnLFxuICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlc1tpXSxcbiAgICAgICAgICBoYXNLbm9iOiBmYWxzZSxcbiAgICAgICAgICBjb21wb25lbnQ6IHRydWUsXG4gICAgICAgIH0sdGhpcy51cGRhdGUuYmluZCh0aGlzLGkpKTtcbiAgICAgIHNsaWRlci5tdWx0aXNsaWRlciA9IHRoaXM7XG5cbiAgICAgIHNsaWRlci5pbmRleCA9IGk7XG4gICAgICBpZiAodG91Y2guZXhpc3RzKSB7XG4gICAgICAgIHNsaWRlci5iYXIuaW5kZXggPSBpO1xuICAgICAgICBzbGlkZXIuZmlsbGJhci5pbmRleCA9IGk7XG4gICAgICAgIHNsaWRlci5wcmVDbGljayA9IHNsaWRlci5wcmVNb3ZlID0gc2xpZGVyLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgICAgc2xpZGVyLmNsaWNrID0gc2xpZGVyLm1vdmUgPSBzbGlkZXIucmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgICBzbGlkZXIucHJlVG91Y2ggPSBzbGlkZXIucHJlVG91Y2hNb3ZlID0gc2xpZGVyLnByZVRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgICBzbGlkZXIudG91Y2ggPSBzbGlkZXIudG91Y2hNb3ZlID0gc2xpZGVyLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNsaWRlcnMucHVzaChzbGlkZXIpO1xuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cbiAgICB9XG4gICAgaWYgKHRvdWNoLmV4aXN0cykge1xuICAgICAgdGhpcy5hZGRUb3VjaExpc3RlbmVycygpO1xuICAgIH1cblxuICB9XG5cbiAgY29sb3JJbnRlcmZhY2UoKSB7XG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5zbGlkZXJzLmxlbmd0aDtpKyspIHtcbiAgICAgIHRoaXMuc2xpZGVyc1tpXS5jb2xvcnMgPSB0aGlzLmNvbG9ycztcbiAgICAgIHRoaXMuc2xpZGVyc1tpXS5jb2xvckludGVyZmFjZSgpO1xuICAgIH1cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBsZXQgc2xpZGVyV2lkdGggPSB0aGlzLndpZHRoIC8gdGhpcy5zbGlkZXJzLmxlbmd0aDtcbiAgICBsZXQgc2xpZGVySGVpZ2h0ID0gdGhpcy5oZWlnaHQ7XG5cbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLnNsaWRlcnMubGVuZ3RoO2krKykge1xuICAgICAgdGhpcy5zbGlkZXJzW2ldLnJlc2l6ZShzbGlkZXJXaWR0aCxzbGlkZXJIZWlnaHQpO1xuICAgICAgdGhpcy5zbGlkZXJzW2ldLmN1c3RvbVN0eWxlKCk7XG4gICAgfVxuXG5cbiAgfVxuXG4gIHVwZGF0ZShpbmRleCx2YWx1ZSkge1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICAnaW5kZXgnOiBpbmRleCxcbiAgICAgICd2YWx1ZSc6IHZhbHVlXG4gICAgfSk7XG4gIH1cblxuICBhZGRUb3VjaExpc3RlbmVycygpIHtcblxuICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuXG4gICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGZhbHNlO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoZSkgPT4ge1xuICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRYLGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRZKTtcbiAgICAgIGxldCBzbGlkZXIgPSB0aGlzLnNsaWRlcnNbZWxlbWVudC5pbmRleF07XG4gICAgICBpZiAoIXNsaWRlci5vZmZzZXQpIHtcbiAgICAgICAgc2xpZGVyLm9mZnNldCA9IGRvbS5maW5kUG9zaXRpb24oc2xpZGVyLmVsZW1lbnQpO1xuICAgICAgfVxuICAgICAgc2xpZGVyLm1vdXNlID0gZG9tLmxvY2F0ZU1vdXNlKGUsc2xpZGVyLm9mZnNldCk7XG4gICAgICBzbGlkZXIuZG93bigpO1xuICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGVsZW1lbnQuaW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIChlKSA9PiB7XG4gICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFgsZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFkpO1xuICAgICAgbGV0IHNsaWRlciA9IHRoaXMuc2xpZGVyc1tlbGVtZW50LmluZGV4XTtcbiAgICAgIGlmICghc2xpZGVyLm9mZnNldCkge1xuICAgICAgICBzbGlkZXIub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbihzbGlkZXIuZWxlbWVudCk7XG4gICAgICB9XG4gICAgICBzbGlkZXIubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSxzbGlkZXIub2Zmc2V0KTtcbiAgICAgIGlmIChlbGVtZW50LmluZGV4IT09dGhpcy5jdXJyZW50RWxlbWVudCkge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50RWxlbWVudCA+PSAwKSB7XG4gICAgICAgICAgbGV0IHBhc3RzbGlkZXIgPSB0aGlzLnNsaWRlcnNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICAgICAgcGFzdHNsaWRlci51cCgpO1xuICAgICAgICB9XG4gICAgICAgIHNsaWRlci5kb3duKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzbGlkZXIuc2xpZGUoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBlbGVtZW50LmluZGV4O1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9KTtcblxuICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIChlKSA9PiB7XG4gICAgICAvLyBubyB0b3VjaGVzIHRvIGNhbGN1bGF0ZSBiZWNhdXNlIG5vbmUgcmVtYWluaW5nXG4gICAgICBsZXQgc2xpZGVyID0gdGhpcy5zbGlkZXJzW3RoaXMuY3VycmVudEVsZW1lbnRdO1xuICAgICAgc2xpZGVyLnVwKCk7XG4gICAgICB0aGlzLmludGVyYWN0aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZmFsc2U7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gIH1cblxuICAvKipcbiAgR2V0IG9yIHNldCB0aGUgbnVtYmVyIG9mIHNsaWRlcnNcbiAgQHR5cGUge051bWJlcn1cbiAgKi9cbiAgZ2V0IG51bWJlck9mU2xpZGVycygpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXJzLmxlbmd0aDtcbiAgfVxuXG4gIHNldCBudW1iZXJPZlNsaWRlcnModikge1xuICAgIGlmICh2PT09dGhpcy5zbGlkZXJzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNsaWRlcnMuZm9yRWFjaCgoc2xpZGVyKT0+e1xuICAgICAgc2xpZGVyLmRlc3Ryb3koKTtcbiAgICB9KTtcbiAgICB0aGlzLmVtcHR5KCk7XG4gICAgdGhpcy5fbnVtYmVyT2ZTbGlkZXJzID0gdjtcbiAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG4gIH1cblxuXG5cbiAgLyoqXG4gIExvd2VyIGxpbWl0IG9mIHRoZSBtdWx0aXNsaWRlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBtdWx0aXNsaWRlci5taW4gPSAxMDAwO1xuICAqL1xuICBnZXQgbWluKCkge1xuICAgIHJldHVybiB0aGlzLnNsaWRlcnNbMF0ubWluO1xuICB9XG4gIHNldCBtaW4odikge1xuICAgIHRoaXMuc2xpZGVycy5mb3JFYWNoKChzbGlkZXIpPT57XG4gICAgICBzbGlkZXIubWluID0gdjtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICBVcHBlciBsaW1pdCBvZiB0aGUgbXVsdGlzbGlkZXIncyBvdXRwdXQgcmFuZ2VcbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgbXVsdGlzbGlkZXIubWF4ID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXJzWzBdLm1heDtcbiAgfVxuICBzZXQgbWF4KHYpIHtcbiAgICB0aGlzLnNsaWRlcnMuZm9yRWFjaCgoc2xpZGVyKT0+e1xuICAgICAgc2xpZGVyLm1heCA9IHY7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBtdWx0aXNsaWRlcidzIHZhbHVlIGNoYW5nZXMgYnkuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIG11bHRpc2xpZGVyLnN0ZXAgPSA1O1xuICAqL1xuICBnZXQgc3RlcCgpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXJzWzBdLnN0ZXA7XG4gIH1cbiAgc2V0IHN0ZXAodikge1xuICAgIHRoaXMuc2xpZGVycy5mb3JFYWNoKChzbGlkZXIpPT57XG4gICAgICBzbGlkZXIuc3RlcCA9IHY7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgU2V0IHRoZSB2YWx1ZSBvZiBhbiBpbmRpdmlkdWFsIHNsaWRlclxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gU2xpZGVyIGluZGV4XG4gIEBwYXJhbSB2YWx1ZSB7bnVtYmVyfSBOZXcgc2xpZGVyIHZhbHVlXG4gIEBleGFtcGxlXG4gIC8vIFNldCB0aGUgZmlyc3Qgc2xpZGVyIHRvIHZhbHVlIDAuNVxuICBtdWx0aXNsaWRlci5zZXRTbGlkZXIoMCwwLjUpXG4gICovXG4gIHNldFNsaWRlcihpbmRleCx2YWx1ZSkge1xuICAgIHRoaXMuc2xpZGVyc1tpbmRleF0udmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgJ2luZGV4JzogaW5kZXgsXG4gICAgICAndmFsdWUnOiB2YWx1ZVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gIFNldCB0aGUgdmFsdWUgb2YgYWxsIHNsaWRlcnMgYXQgb25jZS4gSWYgdGhlIHNpemUgb2YgdGhlIGlucHV0IGFycmF5IGRvZXMgbm90IG1hdGNoIHRoZSBjdXJyZW50IG51bWJlciBvZiBzbGlkZXJzLCB0aGUgdmFsdWUgYXJyYXkgd2lsbCByZXBlYXQgdW50aWwgYWxsIHNsaWRlcnMgaGF2ZSBiZWVuIHNldC4gSS5lLiBhbiBpbnB1dCBhcnJheSBvZiBsZW5ndGggMSB3aWxsIHNldCBhbGwgc2xpZGVycyB0byB0aGF0IHZhbHVlLlxuICBAcGFyYW0gdmFsdWVzIHtBcnJheX0gQWxsIHNsaWRlciB2YWx1ZXNcbiAgQGV4YW1wbGVcbiAgbXVsdGlzbGlkZXIuc2V0QWxsU2xpZGVycyhbMC4yLDAuMywwLjQsMC41LDAuNl0pXG4gICovXG4gIHNldEFsbFNsaWRlcnModmFsdWVzKSB7XG4gICAgdGhpcy52YWx1ZXMgPSB2YWx1ZXM7XG4gICAgdGhpcy5zbGlkZXJzLmZvckVhY2goKHNsaWRlcixpKT0+e1xuICAgICAgc2xpZGVyLnZhbHVlID0gdmFsdWVzW2kldmFsdWVzLmxlbmd0aF07XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgICAnaW5kZXgnOiBpLFxuICAgICAgICAndmFsdWUnOiBzbGlkZXIudmFsdWVcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL211bHRpc2xpZGVyLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNsaWRlclRlbXBsYXRlIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcihhcmdzLG9wdGlvbnMsZGVmYXVsdHMpIHtcblxuICAgIHN1cGVyKGFyZ3Msb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLm9yaWVudGF0aW9uID0gdGhpcy5zZXR0aW5ncy5vcmllbnRhdGlvbjtcblxuICAvLyAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXG4gICAgdGhpcy5oYXNLbm9iID0gdGhpcy5zZXR0aW5ncy5oYXNLbm9iO1xuXG4gICAgLy8gdGhpcy5zdGVwIHNob3VsZCBldmVudHVhbGx5IGJlIGdldC9zZXRcbiAgICAvLyB1cGRhdGluZyBpdCB3aWxsIHVwZGF0ZSB0aGUgX3ZhbHVlIHN0ZXAgbW9kZWxcbiAgLy8gIHRoaXMuc3RlcCA9IHRoaXMuc2V0dGluZ3Muc3RlcDsgLy8gZmxvYXRcblxuICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5zY2FsZVswXSwgdGhpcy5zZXR0aW5ncy5zY2FsZVsxXSwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLHRoaXMub3JpZW50YXRpb24sWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblxuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnZhbHVlKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLmJhciA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmZpbGxiYXIgPSBzdmcuY3JlYXRlKCdyZWN0Jyk7XG4gICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXIpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmZpbGxiYXIpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmtub2IpO1xuXG4gICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG5cblxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG5cbiAgICBpZiAoIXRoaXMuc2V0dGluZ3Mub3JpZW50YXRpb24pIHtcbiAgICAgIGlmICh0aGlzLndpZHRoIDwgdGhpcy5oZWlnaHQpIHtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvbiA9ICd2ZXJ0aWNhbCc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uID0gJ2hvcml6b250YWwnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCB4LCB5LCB3LCBoLCBiYXJPZmZzZXQsIGNvcm5lclJhZGl1cztcbiAgICB0aGlzLmtub2JEYXRhID0ge1xuICAgICAgbGV2ZWw6IDAsXG4gICAgICByOiAwXG4gICAgfTtcblxuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAndmVydGljYWwnKSB7XG4gICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMud2lkdGggLyAyO1xuICAgIFx0eCA9IHRoaXMud2lkdGgvMjtcbiAgICBcdHkgPSAwO1xuICAgIFx0dyA9IHRoaXMudGhpY2tuZXNzO1xuICAgIFx0aCA9IHRoaXMuaGVpZ2h0O1xuICAgICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MgKiAwLjg7XG4gICAgXHR0aGlzLmtub2JEYXRhLmxldmVsID0gaC10aGlzLm5vcm1hbGl6ZWQqaDtcbiAgICAgIGJhck9mZnNldCA9ICd0cmFuc2xhdGUoJyt0aGlzLnRoaWNrbmVzcyooLTEpLzIrJywwKSc7XG4gICAgICBjb3JuZXJSYWRpdXMgPSB3LzI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGhpY2tuZXNzID0gdGhpcy5oZWlnaHQgLyAyO1xuICAgIFx0eCA9IDA7XG4gICAgXHR5ID0gdGhpcy5oZWlnaHQvMjtcbiAgICBcdHcgPSB0aGlzLndpZHRoO1xuICAgIFx0aCA9IHRoaXMudGhpY2tuZXNzO1xuICAgICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MgKiAwLjg7XG4gICAgXHR0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5ub3JtYWxpemVkKnc7XG4gICAgICBiYXJPZmZzZXQgPSAndHJhbnNsYXRlKDAsJyt0aGlzLnRoaWNrbmVzcyooLTEpLzIrJyknO1xuICAgICAgY29ybmVyUmFkaXVzID0gaC8yO1xuICAgIH1cblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneCcseCk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd5Jyx5KTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsYmFyT2Zmc2V0KTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3J4Jyxjb3JuZXJSYWRpdXMpOyAvLyBjb3JuZXIgcmFkaXVzXG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeScsY29ybmVyUmFkaXVzKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx3KTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsaCk7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneCcseCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd5Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx3KTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsaC10aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneCcsMCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd5Jyx5KTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsaCk7XG4gICAgfVxuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsYmFyT2Zmc2V0KTtcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeCcsY29ybmVyUmFkaXVzKTtcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeScsY29ybmVyUmFkaXVzKTtcblxuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAndmVydGljYWwnKSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeCcseCk7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx5KTtcbiAgICB9XG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgncicsdGhpcy5rbm9iRGF0YS5yKTtcblxuXG4gICAgaWYgKHRoaXMucG9zaXRpb24pIHtcbiAgICAgIHRoaXMucG9zaXRpb24ucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG4gICAgfVxuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIGlmICghdGhpcy5oYXNLbm9iKSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdmaWxsJywnbm9uZScpO1xuICAgIH1cblxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5jbGlja2VkKSB7XG4gICAgICB0aGlzLmtub2JEYXRhLnIgPSB0aGlzLnRoaWNrbmVzcyowLjc1O1xuICAgIH1cbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JEYXRhLnIpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZCp0aGlzLmhlaWdodDtcbiAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQgLSB0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd5Jyx0aGlzLmhlaWdodCAtIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZCp0aGlzLndpZHRoO1xuICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd4JywwKTtcbiAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfVxuICB9XG5cbiAgZG93bigpIHtcbiAgICB0aGlzLmNsaWNrZWQgPSB0cnVlO1xuICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzKjAuOTtcbiAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5zbGlkZSgpO1xuICB9XG5cbiAgc2xpZGUoKSB7XG4gICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5wb3NpdGlvbi51cGRhdGUodGhpcy5tb3VzZSk7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5fdmFsdWUudXBkYXRlTm9ybWFsKCB0aGlzLnBvc2l0aW9uLnZhbHVlICk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdXAoKSB7XG4gICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuICB9XG5cbiAgLyoqXG4gIFRoZSBzbGlkZXIncyBjdXJyZW50IHZhbHVlLiBJZiBzZXQgbWFudWFsbHksIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgc2xpZGVyLnZhbHVlID0gMTA7XG4gICovXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHYpIHtcbiAgICB0aGlzLl92YWx1ZS51cGRhdGUodik7XG4gICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBMb3dlciBsaW1pdCBvZiB0aGUgc2xpZGVycydzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBzbGlkZXIubWluID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1pbigpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWluO1xuICB9XG4gIHNldCBtaW4odikge1xuICAgIHRoaXMuX3ZhbHVlLm1pbiA9IHY7XG4gIH1cblxuICAvKipcbiAgVXBwZXIgbGltaXQgb2YgdGhlIHNsaWRlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBzbGlkZXIubWF4ID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWF4O1xuICB9XG4gIHNldCBtYXgodikge1xuICAgIHRoaXMuX3ZhbHVlLm1heCA9IHY7XG4gIH1cblxuICAvKipcbiAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBzbGlkZXIncyB2YWx1ZSBjaGFuZ2VzIGJ5LlxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBzbGlkZXIuc3RlcCA9IDU7XG4gICovXG4gIGdldCBzdGVwKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5zdGVwO1xuICB9XG4gIHNldCBzdGVwKHYpIHtcbiAgICB0aGlzLl92YWx1ZS5zdGVwID0gdjtcbiAgfVxuXG4gIC8qKlxuICBBYnNvbHV0ZSBtb2RlIChzbGlkZXIncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJyZWxhdGl2ZVwiLlxuICBAdHlwZSB7c3RyaW5nfVxuICBAZXhhbXBsZSBzbGlkZXIubW9kZSA9IFwicmVsYXRpdmVcIjtcbiAgKi9cbiAgZ2V0IG1vZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb24ubW9kZTtcbiAgfVxuICBzZXQgbW9kZSh2KSB7XG4gICAgdGhpcy5wb3NpdGlvbi5tb2RlID0gdjtcbiAgfVxuXG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9jb21wb25lbnRzL3NsaWRlcnRlbXBsYXRlLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcbmxldCBTdGVwID0gcmVxdWlyZSgnLi4vbW9kZWxzL3N0ZXAnKTtcbmltcG9ydCAqIGFzIEludGVyYWN0aW9uIGZyb20gJy4uL3V0aWwvaW50ZXJhY3Rpb24nO1xuXG4vKipcbiogUGFuXG4qXG4qIEBkZXNjcmlwdGlvbiBTdGVyZW8gY3Jvc3NmYWRlci5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJwYW5cIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBwYW4gPSBuZXcgTmV4dXMuUGFuKCcjdGFyZ2V0JylcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGludGVyZmFjZSdzIDxpPnZhbHVlPC9pPiAoLTEgdG8gMSksIGFzIHdlbGwgYXMgPGk+TDwvaT4gYW5kIDxpPlI8L2k+IGFtcGxpdHVkZSB2YWx1ZXMgKDAtMSkgZm9yIGxlZnQgYW5kIHJpZ2h0IHNwZWFrZXJzLCBjYWxjdWxhdGVkIGJ5IGEgc3F1YXJlLXJvb3QgY3Jvc3NmYWRlIGFsZ29yaXRobS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogcGFuLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhbiBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnc2NhbGUnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMTIwLDIwXSxcbiAgICAgICdvcmllbnRhdGlvbic6ICdob3Jpem9udGFsJyxcbiAgICAgICdtb2RlJzogJ3JlbGF0aXZlJyxcbiAgICAgICdzY2FsZSc6IFstMSwxXSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDAsXG4gICAgICAnaGFzS25vYic6IHRydWVcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5vcmllbnRhdGlvbiA9IHRoaXMuc2V0dGluZ3Mub3JpZW50YXRpb247XG5cbiAgICB0aGlzLm1vZGUgPSB0aGlzLnNldHRpbmdzLm1vZGU7XG5cbiAgICB0aGlzLmhhc0tub2IgPSB0aGlzLnNldHRpbmdzLmhhc0tub2I7XG5cbiAgICAvLyB0aGlzLnN0ZXAgc2hvdWxkIGV2ZW50dWFsbHkgYmUgZ2V0L3NldFxuICAgIC8vIHVwZGF0aW5nIGl0IHdpbGwgdXBkYXRlIHRoZSBfdmFsdWUgc3RlcCBtb2RlbFxuICAgIHRoaXMuc3RlcCA9IHRoaXMuc2V0dGluZ3Muc3RlcDsgLy8gZmxvYXRcblxuICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5zY2FsZVswXSwgdGhpcy5zZXR0aW5ncy5zY2FsZVsxXSwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5tb2RlLHRoaXMub3JpZW50YXRpb24sWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblxuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnZhbHVlKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLmJhciA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmtub2IgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBpZiAodGhpcy5wb3NpdGlvbikge1xuICAgICAgdGhpcy5wb3NpdGlvbi5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy53aWR0aCA8IHRoaXMuaGVpZ2h0KSB7XG4gICAgICB0aGlzLm9yaWVudGF0aW9uID0gJ3ZlcnRpY2FsJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcmllbnRhdGlvbiA9ICdob3Jpem9udGFsJztcbiAgICB9XG5cbiAgICBsZXQgeCwgeSwgdywgaCwgYmFyT2Zmc2V0LCBjb3JuZXJSYWRpdXM7XG4gICAgdGhpcy5rbm9iRGF0YSA9IHtcbiAgICAgIGxldmVsOiAwLFxuICAgICAgcjogMFxuICAgIH07XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy50aGlja25lc3MgPSB0aGlzLndpZHRoIC8gMjtcbiAgICBcdHggPSB0aGlzLndpZHRoLzI7XG4gICAgXHR5ID0gMDtcbiAgICBcdHcgPSB0aGlzLnRoaWNrbmVzcztcbiAgICBcdGggPSB0aGlzLmhlaWdodDtcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IGgtdGhpcy5rbm9iRGF0YS5yLXRoaXMubm9ybWFsaXplZCooaC10aGlzLmtub2JEYXRhLnIqMik7XG4gICAgICBiYXJPZmZzZXQgPSAndHJhbnNsYXRlKCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycsMCknO1xuICAgICAgY29ybmVyUmFkaXVzID0gdy8yO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMuaGVpZ2h0IC8gMjtcbiAgICBcdHggPSAwO1xuICAgIFx0eSA9IHRoaXMuaGVpZ2h0LzI7XG4gICAgXHR3ID0gdGhpcy53aWR0aDtcbiAgICBcdGggPSB0aGlzLnRoaWNrbmVzcztcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IHRoaXMubm9ybWFsaXplZCoody10aGlzLmtub2JEYXRhLnIqMikrdGhpcy5rbm9iRGF0YS5yO1xuICAgICAgYmFyT2Zmc2V0ID0gJ3RyYW5zbGF0ZSgwLCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycpJztcbiAgICAgIGNvcm5lclJhZGl1cyA9IGgvMjtcbiAgICB9XG5cbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3gnLHgpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneScseSk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGJhck9mZnNldCk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsY29ybmVyUmFkaXVzKTsgLy8gY29ybmVyIHJhZGl1c1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgncnknLGNvcm5lclJhZGl1cyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx4KTtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3knLHkpO1xuICAgIH1cbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JEYXRhLnIpO1xuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuXG4gICAgaWYgKCF0aGlzLmhhc0tub2IpIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCd0cmFuc3BhcmVudCcpO1xuICAgIH1cblxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5jbGlja2VkKSB7XG4gICAgICB0aGlzLmtub2JEYXRhLnIgPSB0aGlzLnRoaWNrbmVzcyowLjc1O1xuICAgIH1cbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JEYXRhLnIpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgXHQgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5rbm9iRGF0YS5yK3RoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQqKHRoaXMuaGVpZ2h0LXRoaXMua25vYkRhdGEucioyKTtcbiAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQgLSB0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICBcdCAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkKih0aGlzLndpZHRoLXRoaXMua25vYkRhdGEucioyKSt0aGlzLmtub2JEYXRhLnI7XG4gICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgIH1cbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MqMC45O1xuICAgIHRoaXMucG9zaXRpb24uYW5jaG9yID0gdGhpcy5tb3VzZTtcbiAgICB0aGlzLm1vdmUoKTtcbiAgfVxuXG4gIG1vdmUoKSB7XG4gICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5wb3NpdGlvbi51cGRhdGUodGhpcy5tb3VzZSk7XG5cbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS51cGRhdGVOb3JtYWwoIHRoaXMucG9zaXRpb24udmFsdWUgKTtcblxuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXG4gICAgICAgIEw6IE1hdGgucG93KCBtYXRoLnNjYWxlKHRoaXMudmFsdWUsLTEsMSwxLDApLCAyKSxcbiAgICAgICAgUjogTWF0aC5wb3coIG1hdGguc2NhbGUodGhpcy52YWx1ZSwtMSwxLDAsMSksIDIpXG4gICAgICB9KTtcblxuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBUaGUgcG9zaXRpb24gb2YgY3Jvc3NmYWRlciwgZnJvbSAtMSAobGVmdCkgdG8gMSAocmlnaHQpLiBTZXR0aW5nIHRoaXMgdmFsdWUgdXBkYXRlcyB0aGUgaW50ZXJmYWNlIGFuZCB0cmlnZ2VycyB0aGUgb3V0cHV0IGV2ZW50LlxuICBAdHlwZSB7bnVtYmVyfVxuICAqL1xuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuICB9XG5cbiAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgdGhpcy5fdmFsdWUudXBkYXRlKHZhbHVlKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXG4gICAgICBMOiBNYXRoLnBvdyggbWF0aC5zY2FsZSh0aGlzLnZhbHVlLC0xLDEsMSwwKSwgMiksXG4gICAgICBSOiBNYXRoLnBvdyggbWF0aC5zY2FsZSh0aGlzLnZhbHVlLC0xLDEsMCwxKSwgMilcbiAgICB9KTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgZ2V0IG5vcm1hbGl6ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvcGFuLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcblxuXG5sZXQgUG9pbnQgPSBmdW5jdGlvbihwb2ludCxlbnZlbG9wZSkge1xuXG4gIHRoaXMueCA9IHBvaW50Lng7XG4gIHRoaXMueSA9IHBvaW50Lnk7XG4gIHRoaXMuZW52ZWxvcGUgPSBlbnZlbG9wZTtcblxuICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnZmlsbCcsdGhpcy5lbnZlbG9wZS5jb2xvcnMuYWNjZW50KTtcblxuICB0aGlzLmVudmVsb3BlLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcblxuICB0aGlzLnJlc2l6ZSA9IGZ1bmN0aW9uKCkge1xuICAgIGxldCByID0gfn4oTWF0aC5taW4odGhpcy5lbnZlbG9wZS53aWR0aCx0aGlzLmVudmVsb3BlLmhlaWdodCkvNTApKzI7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgncicscik7XG4gIH07XG5cbiAgdGhpcy5tb3ZlID0gZnVuY3Rpb24oeCx5KSB7XG5cbiAgICB0aGlzLnggPSAoeCB8fCB4PT09MCkgPyB4IDogdGhpcy54O1xuICAgIHRoaXMueSA9ICh5IHx8IHk9PT0wKSA/IHkgOiB0aGlzLnk7XG5cbiAgICBpZiAodGhpcy5lbnZlbG9wZS5ub2Rlcy5pbmRleE9mKHRoaXMpPj0wKSB7XG5cbiAgICAgIGxldCBwcmV2SW5kZXggPSB0aGlzLmVudmVsb3BlLm5vZGVzLmluZGV4T2YodGhpcyktMTtcbiAgICAgIGxldCBuZXh0SW5kZXggPSB0aGlzLmVudmVsb3BlLm5vZGVzLmluZGV4T2YodGhpcykrMTtcblxuICAgICAgbGV0IHByZXZOb2RlID0gdGhpcy5lbnZlbG9wZS5ub2Rlc1twcmV2SW5kZXhdO1xuICAgICAgbGV0IG5leHROb2RlID0gdGhpcy5lbnZlbG9wZS5ub2Rlc1tuZXh0SW5kZXhdO1xuXG4gICAgICBsZXQgbG93WCA9IHByZXZJbmRleCA+PSAwID8gcHJldk5vZGUueCA6IDA7XG4gICAgICBsZXQgaGlnaFggPSBuZXh0SW5kZXggPCB0aGlzLmVudmVsb3BlLm5vZGVzLmxlbmd0aCA/IG5leHROb2RlLnggOiAxO1xuXG4gICAgICBpZiAodGhpcy54IDwgbG93WCkgeyB0aGlzLnggPSBsb3dYOyB9XG4gICAgICBpZiAodGhpcy54ID4gaGlnaFgpIHsgdGhpcy54ID0gaGlnaFg7IH1cblxuICAgIH1cblxuICAgIHRoaXMubG9jYXRpb24gPSB0aGlzLmdldENvb3JkaW5hdGVzKCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3gnLCB0aGlzLmxvY2F0aW9uLngpO1xuICAgIHRoaXMuZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2N5JywgdGhpcy5sb2NhdGlvbi55KTtcbiAgfTtcblxuICB0aGlzLmdldENvb3JkaW5hdGVzID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHRoaXMueCAqIHRoaXMuZW52ZWxvcGUud2lkdGgsXG4gICAgICB5OiAoMS10aGlzLnkpICogdGhpcy5lbnZlbG9wZS5oZWlnaHRcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMubW92ZSh0aGlzLngsdGhpcy55LHRydWUpO1xuICB0aGlzLnJlc2l6ZSgpO1xuXG4gIHRoaXMuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuZW52ZWxvcGUuZWxlbWVudC5yZW1vdmVDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICAgIHRoaXMuZW52ZWxvcGUubm9kZXMuc3BsaWNlKHRoaXMuZW52ZWxvcGUubm9kZXMuaW5kZXhPZih0aGlzKSwxKTtcbiAgfTtcblxuXG59O1xuXG5cbi8qKlxuKiBFbnZlbG9wZVxuKlxuKiBAZGVzY3JpcHRpb24gSW50ZXJhY3RpdmUgbGluZWFyIHJhbXAgdmlzdWFsaXphdGlvbi5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJlbnZlbG9wZVwiPjwvc3Bhbj5cbipcbiogQGV4YW1wbGVcbiogdmFyIGVudmVsb3BlID0gbmV3IE5leHVzLkVudmVsb3BlKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIGVudmVsb3BlID0gbmV3IE5leHVzLkVudmVsb3BlKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMzAwLDE1MF0sXG4qICAgJ3BvaW50cyc6IFtcbiogICAgIHtcbiogICAgICAgeDogMC4xLFxuKiAgICAgICB5OiAwLjRcbiogICAgIH0sXG4qICAgICB7XG4qICAgICAgIHg6IDAuMzUsXG4qICAgICAgIHk6IDAuNlxuKiAgICAgfSxcbiogICAgIHtcbiogICAgICAgeDogMC42NSxcbiogICAgICAgeTogMC4yXG4qICAgICB9LFxuKiAgICAge1xuKiAgICAgICB4OiAwLjksXG4qICAgICAgIHk6IDAuNFxuKiAgICAgfSxcbiogICBdXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIGEgbm9kZSBpcyBtb3ZlZC4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBhcnJheSBvZiBwb2ludCBsb2NhdGlvbnMuIEVhY2ggaXRlbSBpbiB0aGUgYXJyYXkgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgPGk+eDwvaT4gYW5kIDxpPnk8L2k+IHByb3BlcnRpZXMgZGVzY3JpYmluZyB0aGUgbG9jYXRpb24gb2YgYSBwb2ludCBvbiB0aGUgZW52ZWxvcGUuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIGVudmVsb3BlLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEVudmVsb3BlIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMzAwLDE1MF0sXG4gICAgICAncG9pbnRzJzogW1xuICBcdFx0XHR7XG4gIFx0XHRcdFx0eDogMC4xLFxuICBcdFx0XHRcdHk6IDAuNFxuICBcdFx0XHR9LFxuICBcdFx0XHR7XG4gIFx0XHRcdFx0eDogMC4zNSxcbiAgXHRcdFx0XHR5OiAwLjZcbiAgXHRcdFx0fSxcbiAgXHRcdFx0e1xuICBcdFx0XHRcdHg6IDAuNjUsXG4gIFx0XHRcdFx0eTogMC4yXG4gIFx0XHRcdH0sXG4gIFx0XHRcdHtcbiAgXHRcdFx0XHR4OiAwLjksXG4gIFx0XHRcdFx0eTogMC40XG4gIFx0XHRcdH1cbiAgXHRcdF1cbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5wb2ludHMgPSB0aGlzLnNldHRpbmdzLnBvaW50cztcblxuICAgIHRoaXMubm9kZXMgPSBbXTtcblxuICAgIHRoaXMuc2VsZWN0ZWQgPSBmYWxzZTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG5cbiAgICB0aGlzLnBvaW50cy5mb3JFYWNoKChwb2ludCkgPT4ge1xuICAgICAgbGV0IG5vZGUgPSBuZXcgUG9pbnQocG9pbnQsdGhpcyk7XG4gICAgICB0aGlzLm5vZGVzLnB1c2gobm9kZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNvcnRQb2ludHMoKTtcblxuICAgIHRoaXMubGluZSA9IHN2Zy5jcmVhdGUoJ3BvbHlsaW5lJyk7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJywgMik7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZSgnZmlsbCcsICdub25lJyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5saW5lKTtcblxuICAgIHRoaXMuZmlsbCA9IHN2Zy5jcmVhdGUoJ3BvbHlsaW5lJyk7XG4gICAgdGhpcy5maWxsLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywgJzAuMicpO1xuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuZmlsbCk7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBmb3IgKGxldCBpPTA7IGk8dGhpcy5ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5ub2Rlc1tpXS5yZXNpemUoKTtcbiAgICAgIHRoaXMubm9kZXNbaV0ubW92ZSgpO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB0aGlzLmZpbGwuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB0aGlzLm5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgIG5vZGUuZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgLy8gIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0ubW92ZSggdGhpcy5wb2ludHMgKVxuICAgIHRoaXMuY2FsY3VsYXRlUGF0aCgpO1xuICB9XG5cbiAgY2FsY3VsYXRlUG9pbnRzKCkge1xuICAgIHRoaXMucG9pbnRzID0gW107XG4gICAgdGhpcy5ub2Rlcy5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgICB0aGlzLnBvaW50cy5wdXNoKHsgeDogbm9kZS54LCB5OiBub2RlLnkgfSk7XG4gICAgfSk7XG4gIH1cblxuICBjYWxjdWxhdGVQYXRoKCkge1xuXG4gICAgLy9zdHJva2UgZGF0YVxuICAgIGxldCBkYXRhID0gJzAgJysgdGhpcy5ub2Rlc1swXS5sb2NhdGlvbi55KycsICc7XG5cbiAgICAvLyBkYXRhIHNob3VsZCBiZSByZS1vcmRlcmVkIGJhc2VkIG9uIHggbG9jYXRpb24uXG4gICAgLy8gd2hhdGV2ZXIgZnVuY3Rpb24gYWRkcyBhIG5vZGUgc2hvdWxkIGFkZCBpdCBhdCB0aGUgcmlnaHQgaW5kZXhcblxuICAgIHRoaXMubm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgIC8vICBsZXQgbG9jYXRpb24gPSBub2RlLmdldENvb3JkaW5hdGVzKCk7XG4gICAgICBkYXRhICs9IG5vZGUubG9jYXRpb24ueCArICcgJyArIG5vZGUubG9jYXRpb24ueSArICcsICc7XG4gICAgfSk7XG5cblxuICAvLyAgZGF0YSArPSBwb2ludC54KnRoaXMud2lkdGgrJyAnKyBwb2ludC55KnRoaXMuaGVpZ2h0KycsICc7XG4gICAgZGF0YSArPSB0aGlzLndpZHRoICsgJyAnKyB0aGlzLm5vZGVzW3RoaXMubm9kZXMubGVuZ3RoLTFdLmxvY2F0aW9uLnk7XG5cbiAgICB0aGlzLmxpbmUuc2V0QXR0cmlidXRlKCdwb2ludHMnLCBkYXRhKTtcblxuICAgIC8vIGZpbGwgZGF0YVxuICAgIC8vIGFkZCBib3R0b20gY29ybmVyc1xuXG4gICAgZGF0YSArPSAnLCAnK3RoaXMud2lkdGggKycgJyt0aGlzLmhlaWdodCsnLCAnO1xuICAgIGRhdGEgKz0gJzAgJyt0aGlzLmhlaWdodDtcblxuICAgIHRoaXMuZmlsbC5zZXRBdHRyaWJ1dGUoJ3BvaW50cycsIGRhdGEpO1xuXG4gIH1cblxuXG5cbiAgY2xpY2soKSB7XG4gIFx0Ly8gZmluZCBuZWFyZXN0IG5vZGUgYW5kIHNldCB0aGlzLnNlbGVjdGVkIChpbmRleClcbiAgICB0aGlzLmhhc01vdmVkID0gZmFsc2U7XG4gIFx0dGhpcy5zZWxlY3RlZCA9IHRoaXMuZmluZE5lYXJlc3ROb2RlKCk7XG5cbiAgICB0aGlzLm5vZGVzW3RoaXMuc2VsZWN0ZWRdLm1vdmUodGhpcy5tb3VzZS54L3RoaXMud2lkdGgsMS10aGlzLm1vdXNlLnkvdGhpcy5oZWlnaHQpO1xuICAgIHRoaXMuc2NhbGVOb2RlKHRoaXMuc2VsZWN0ZWQpO1xuXG4gICAgLy8gbXVzdCBkbyB0aGlzIGIvYyBuZXcgbm9kZSBtYXkgaGF2ZSBiZWVuIGNyZWF0ZWRcbiAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gIFx0dGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIG1vdmUoKSB7XG4gIFx0aWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5tb3VzZS54ID0gbWF0aC5jbGlwKHRoaXMubW91c2UueCwwLHRoaXMud2lkdGgpO1xuICAgICAgdGhpcy5oYXNNb3ZlZCA9IHRydWU7XG5cbiAgICAgIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0ubW92ZSh0aGlzLm1vdXNlLngvdGhpcy53aWR0aCwxLXRoaXMubW91c2UueS90aGlzLmhlaWdodCk7XG4gICAgXHR0aGlzLnNjYWxlTm9kZSh0aGlzLnNlbGVjdGVkKTtcblxuICAgICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcbiAgXHRcdHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gIFx0XHR0aGlzLnJlbmRlcigpO1xuICBcdH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG5cbiAgXHRpZiAoIXRoaXMuaGFzTW92ZWQpIHtcbiAgICAgIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0uZGVzdHJveSgpO1xuICBcdH1cblxuICAgIHRoaXMuY2FsY3VsYXRlUG9pbnRzKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMucG9pbnRzKTtcbiAgXHR0aGlzLnJlbmRlcigpO1xuXG4gIFx0Ly8gcmVzZXQgdGhpcy5zZWxlY3RlZFxuICBcdHRoaXMuc2VsZWN0ZWQgPSBudWxsO1xuICB9XG5cblxuICBmaW5kTmVhcmVzdE5vZGUoKSB7XG4gIFx0dmFyIG5lYXJlc3RJbmRleCA9IG51bGw7XG4gICAgLy8gc2V0IHRoaXMgdW5yZWFzb25hYmx5IGhpZ2ggc28gdGhhdCBldmVyeSBkaXN0YW5jZSB3aWxsIGJlIGxvd2VyIHRoYW4gaXQuXG4gIFx0dmFyIG5lYXJlc3REaXN0ID0gMTAwMDA7XG4gIFx0dmFyIGJlZm9yZSA9IGZhbHNlO1xuICAgIGxldCB4ID0gdGhpcy5tb3VzZS54L3RoaXMud2lkdGg7XG4gICAgbGV0IHkgPSAxLXRoaXMubW91c2UueS90aGlzLmhlaWdodDtcbiAgICBsZXQgbm9kZXMgPSB0aGlzLm5vZGVzO1xuICBcdGZvciAobGV0IGkgPSAwOyBpPG5vZGVzLmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgZGlzdGFuY2UgZnJvbSBtb3VzZSB0byB0aGlzIG5vZGUgdXNpbmcgcHl0aGFnb3JlYW4gdGhlb3JlbVxuICBcdFx0dmFyIGRpc3RhbmNlID0gTWF0aC5zcXJ0KCAgTWF0aC5wb3coIChub2Rlc1tpXS54IC0geCksIDIpICsgTWF0aC5wb3coKG5vZGVzW2ldLnkgLSB5KSwgMikgKTtcblxuICAgICAgLy8gaWYgdGhpcyBkaXN0YW5jZSBpcyBsZXNzIHRoYW4gdGhlIHByZXZpb3VzIHNob3J0ZXN0IGRpc3RhbmNlLCB1c2UgdGhpcyBpbmRleFxuICBcdFx0aWYgKGRpc3RhbmNlIDwgbmVhcmVzdERpc3QpIHtcbiAgXHRcdFx0bmVhcmVzdERpc3QgPSBkaXN0YW5jZTtcbiAgXHRcdFx0bmVhcmVzdEluZGV4ID0gaTtcbiAgXHRcdFx0YmVmb3JlID0geCA+IG5vZGVzW2ldLng7XG4gIFx0XHR9XG5cbiAgXHR9XG5cbiAgICAvLyBpZiBub3QgdmVyeSBjbG9zZSB0byBhbnkgbm9kZSwgY3JlYXRlIGEgbm9kZVxuICBcdGlmIChuZWFyZXN0RGlzdD4wLjA3KSB7XG5cbiAgICAgIG5lYXJlc3RJbmRleCA9IHRoaXMuZ2V0SW5kZXhGcm9tWCh0aGlzLm1vdXNlLngvdGhpcy53aWR0aCk7XG5cbiAgXHRcdHRoaXMubm9kZXMuc3BsaWNlKG5lYXJlc3RJbmRleCwwLCBuZXcgUG9pbnQoe1xuICBcdFx0XHR4OiB0aGlzLm1vdXNlLngvdGhpcy53aWR0aCxcbiAgXHRcdFx0eTogMS10aGlzLm1vdXNlLnkvdGhpcy5oZWlnaHRcbiAgXHRcdH0sIHRoaXMpKTtcbiAgICAgIHRoaXMuaGFzTW92ZWQgPSB0cnVlO1xuXG4gIFx0fVxuXG4gIFx0cmV0dXJuIG5lYXJlc3RJbmRleDtcbiAgfVxuXG4gIGdldEluZGV4RnJvbVgoeCkge1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgdGhpcy5ub2Rlcy5mb3JFYWNoKChub2RlLGkpID0+IHtcbiAgICAgIGlmICh0aGlzLm5vZGVzW2ldLnggPD0geCkge1xuICAgICAgICBpbmRleCA9IGkrMTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBzY2FsZU5vZGUoaSkge1xuXG4gIFx0bGV0IGNsaXBwZWRYID0gbWF0aC5jbGlwKHRoaXMubm9kZXNbaV0ueCwgMCwgMSk7XG4gIFx0bGV0IGNsaXBwZWRZID0gbWF0aC5jbGlwKHRoaXMubm9kZXNbaV0ueSwgMCwgMSk7XG5cbiAgICB0aGlzLm5vZGVzW2ldLm1vdmUoIGNsaXBwZWRYLCBjbGlwcGVkWSApO1xuXG4gIH1cblxuICAvKipcbiAgU29ydCB0aGUgdGhpcy5wb2ludHMgYXJyYXkgZnJvbSBsZWZ0LW1vc3QgcG9pbnQgdG8gcmlnaHQtbW9zdCBwb2ludC4gWW91IHNob3VsZCBub3QgcmVndWxhcmx5IG5lZWQgdG8gdXNlIHRoaXMsIGhvd2V2ZXIgaXQgbWF5IGJlIHVzZWZ1bCBpZiB0aGUgcG9pbnRzIGdldCB1bm9yZGVyZWQuXG4gICovXG4gIHNvcnRQb2ludHMoKSB7XG4gICAgdGhpcy5ub2Rlcy5zb3J0KGZ1bmN0aW9uKGEsIGIpe1xuICAgICAgcmV0dXJuIGEueCA+IGIueDtcbiAgICB9KTtcbiAgfVxuXG5cbiAgLyoqXG4gIEFkZCBhIGJyZWFrcG9pbnQgb24gdGhlIGVudmVsb3BlLlxuICBAcGFyYW0geCB7bnVtYmVyfSB4IGxvY2F0aW9uIG9mIHRoZSBwb2ludCwgbm9ybWFsaXplZCAoMC0xKVxuICBAcGFyYW0geSB7bnVtYmVyfSB5IGxvY2F0aW9uIG9mIHRoZSBwb2ludCwgbm9ybWFsaXplZCAoMC0xKVxuICAqL1xuICBhZGRQb2ludCh4LHkpIHtcbiAgICBsZXQgaW5kZXggPSB0aGlzLm5vZGVzLmxlbmd0aDtcblxuICAgIHRoaXMuc29ydFBvaW50cygpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGk8dGhpcy5ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHggPCB0aGlzLm5vZGVzW2ldLngpIHtcbiAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgXHR9XG5cbiAgICB0aGlzLm5vZGVzLnNwbGljZShpbmRleCwgMCwgbmV3IFBvaW50KHtcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5XG4gICAgfSwgdGhpcykpO1xuXG4gICAgdGhpcy5zY2FsZU5vZGUoaW5kZXgpO1xuXG4gICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5wb2ludHMpO1xuXG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIEZpbmQgdGhlIGxldmVsIGF0IGEgY2VydGFpbiB4IGxvY2F0aW9uIG9uIHRoZSBlbnZlbG9wZS5cbiAgQHBhcmFtIHgge251bWJlcn0gVGhlIHggbG9jYXRpb24gdG8gZmluZCB0aGUgbGV2ZWwgb2YsIG5vcm1hbGl6ZWQgMC0xXG4gICovXG4gIHNjYW4oeCkge1xuICAgIC8vIGZpbmQgc3Vycm91bmRpbmcgcG9pbnRzXG4gICAgbGV0IG5leHRJbmRleCA9IHRoaXMuZ2V0SW5kZXhGcm9tWCh4KTtcbiAgICBsZXQgcHJpb3JJbmRleCA9IG5leHRJbmRleC0xO1xuICAgIGlmIChwcmlvckluZGV4IDwgMCkge1xuICAgICAgcHJpb3JJbmRleCA9IDA7XG4gICAgfVxuICAgIGlmIChuZXh0SW5kZXggPj0gdGhpcy5ub2Rlcy5sZW5ndGgpIHtcbiAgICAgIG5leHRJbmRleCA9IHRoaXMubm9kZXMubGVuZ3RoLTE7XG4gICAgfVxuICAgIGxldCBwcmlvclBvaW50ID0gdGhpcy5ub2Rlc1twcmlvckluZGV4XTtcbiAgICBsZXQgbmV4dFBvaW50ID0gdGhpcy5ub2Rlc1tuZXh0SW5kZXhdO1xuICAgIGxldCBsb2MgPSBtYXRoLnNjYWxlKHgscHJpb3JQb2ludC54LCBuZXh0UG9pbnQueCwgMCwgMSk7XG4gICAgbGV0IHZhbHVlID0gbWF0aC5pbnRlcnAobG9jLHByaW9yUG9pbnQueSxuZXh0UG9pbnQueSk7XG4gICAgdGhpcy5lbWl0KCdzY2FuJyx2YWx1ZSk7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cblxuICAvKipcbiAgTW92ZSBhIGJyZWFrcG9pbnQgb24gdGhlIGVudmVsb3BlLlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBicmVha3BvaW50IHRvIG1vdmVcbiAgQHBhcmFtIHgge251bWJlcn0gTmV3IHggbG9jYXRpb24sIG5vcm1hbGl6ZWQgMC0xXG4gIEBwYXJhbSB5IHtudW1iZXJ9IE5ldyB5IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuICAqL1xuICBtb3ZlUG9pbnQoaW5kZXgseCx5KSB7XG4gICAgdGhpcy5ub2Rlc1tpbmRleF0ubW92ZSh4LHkpO1xuICAgIHRoaXMuc2NhbGVOb2RlKGluZGV4KTtcbiAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIE1vdmUgYSBicmVha3BvaW50IG9uIHRoZSBlbnZlbG9wZSBieSBhIGNlcnRhaW4gYW1vdW50LlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBicmVha3BvaW50IHRvIG1vdmVcbiAgQHBhcmFtIHhPZmZzZXQge251bWJlcn0gWCBkaXNwbGFjZW1lbnQsIG5vcm1hbGl6ZWQgMC0xXG4gIEBwYXJhbSB5T2Zmc2V0IHtudW1iZXJ9IFkgZGlzcGxhY2VtZW50LCBub3JtYWxpemVkIDAtMVxuICAqL1xuICBhZGp1c3RQb2ludChpbmRleCx4T2Zmc2V0LHlPZmZzZXQpIHtcbiAgICB0aGlzLm5vZGVzW2luZGV4XS5tb3ZlKHRoaXMubm9kZXNbaW5kZXhdLngreE9mZnNldCx0aGlzLm5vZGVzW2luZGV4XS55K3lPZmZzZXQpO1xuICAgIHRoaXMuc2NhbGVOb2RlKGluZGV4KTtcbiAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIFJlbW92ZSBhIGJyZWFrcG9pbnQgZnJvbSB0aGUgZW52ZWxvcGUuXG4gIEBwYXJhbSBpbmRleCB7bnVtYmVyfSBJbmRleCBvZiB0aGUgYnJlYWtwb2ludCB0byByZW1vdmVcbiAgKi9cbiAgZGVzdHJveVBvaW50KGluZGV4KSB7XG4gICAgdGhpcy5ub2Rlc1tpbmRleF0uZGVzdHJveSgpO1xuICAgIHRoaXMuY2FsY3VsYXRlUG9pbnRzKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMucG9pbnRzKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgUmVtb3ZlIGFsbCBleGlzdGluZyBicmVha3BvaW50cyBhbmQgYWRkIGFuIGVudGlyZWx5IG5ldyBzZXQgb2YgYnJlYWtwb2ludHMuXG4gIEBwYXJhbSBhbGxQb2ludHMge2FycmF5fSBBbiBhcnJheSBvZiBvYmplY3RzIHdpdGggeC95IHByb3BlcnRpZXMgKG5vcm1hbGl6ZWQgMC0xKS4gRWFjaCBvYmplY3QgaW4gdGhlIGFycmF5IHNwZWNpZmljZXMgdGhlIHgveSBsb2NhdGlvbiBvZiBhIG5ldyBicmVha3BvaW50IHRvIGJlIGFkZGVkLlxuICAqL1xuICBzZXRQb2ludHMoYWxsUG9pbnRzKSB7XG4gICAgd2hpbGUgKHRoaXMubm9kZXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLm5vZGVzWzBdLmRlc3Ryb3koKTtcbiAgICB9XG4gICAgYWxsUG9pbnRzLmZvckVhY2goKHBvaW50KSA9PiB7XG4gICAgICB0aGlzLmFkZFBvaW50KHBvaW50LngscG9pbnQueSk7XG4gICAgfSk7XG4gICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5wb2ludHMpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvZW52ZWxvcGUuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBkb20gPSByZXF1aXJlKCcuLi91dGlsL2RvbScpO1xuLy9sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5cbi8qKlxuKiBTcGVjdHJvZ3JhbVxuKlxuKiBAZGVzY3JpcHRpb24gQXVkaW8gc3BlY3RydW0gdmlzdWFsaXphdGlvblxuKlxuKiBAZGVtbyA8c3BhbiBuZXh1cy11aT1cInNwZWN0cm9ncmFtXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc3BlY3Ryb2dyYW0gPSBuZXcgTmV4dXMuU3BlY3Ryb2dyYW0oJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc3BlY3Ryb2dyYW0gPSBuZXcgTmV4dXMuU3BlY3Ryb2dyYW0oJyN0YXJnZXQnLHtcbiogICAnc2l6ZSc6IFszMDAsMTUwXVxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qICZuYnNwO1xuKiBObyBldmVudHNcbipcbiovXG5cbmltcG9ydCB7IGNvbnRleHQgfSBmcm9tICcuLi9tYWluJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3BlY3Ryb2dyYW0gZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3NjYWxlJywndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzMwMCwxNTBdXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgICB0aGlzLmFuYWx5c2VyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gICAgdGhpcy5hbmFseXNlci5mZnRTaXplID0gMjA0ODtcbiAgICB0aGlzLmJ1ZmZlckxlbmd0aCA9IHRoaXMuYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQ7XG4gICAgdGhpcy5kYXRhQXJyYXkgPSBuZXcgVWludDhBcnJheSh0aGlzLmJ1ZmZlckxlbmd0aCk7XG5cbiAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG5cbiAgICB0aGlzLnNvdXJjZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5jYW52YXMgPSBuZXcgZG9tLlNtYXJ0Q2FudmFzKHRoaXMucGFyZW50KTtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNhbnZhcy5lbGVtZW50O1xuICB9XG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5yZXNpemUodGhpcy53aWR0aCx0aGlzLmhlaWdodCk7XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gIH1cblxuICByZW5kZXIoKSB7XG5cbiAgICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlci5iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICB0aGlzLmFuYWx5c2VyLmdldEJ5dGVGcmVxdWVuY3lEYXRhKHRoaXMuZGF0YUFycmF5KTtcblxuICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KDAsIDAsIHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgsIHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0KTtcblxuICAgIGlmICh0aGlzLnNvdXJjZSAmJiB0aGlzLmRhdGFBcnJheSkge1xuXG4gICAgICAvL2NvbnNvbGUubG9nKHRoaXMuZGF0YUFycmF5KTtcblxuICAgICAgbGV0IGJhcldpZHRoID0gKHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGggLyB0aGlzLmJ1ZmZlckxlbmd0aCk7XG4gICAgICBsZXQgYmFySGVpZ2h0O1xuICAgICAgbGV0IHggPSAwO1xuXG4gICAgICBsZXQgZGVmaW5pdGlvbiA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgvNTA7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5idWZmZXJMZW5ndGg7IGkgPSBpK2RlZmluaXRpb24pIHtcbiAgICAgICAgYmFySGVpZ2h0ID0gTWF0aC5tYXguYXBwbHkobnVsbCwgdGhpcy5kYXRhQXJyYXkuc3ViYXJyYXkoaSxpK2RlZmluaXRpb24pKTtcbiAgICAgICAgYmFySGVpZ2h0IC89IDI1NTtcbiAgICAgICAgYmFySGVpZ2h0ICo9IHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0O1xuXG4gICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KHgsdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQtYmFySGVpZ2h0LGJhcldpZHRoKmRlZmluaXRpb24sYmFySGVpZ2h0KTtcblxuICAgICAgICB4ICs9IChiYXJXaWR0aCpkZWZpbml0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgRXF1aXZhbGVudCB0byBcInBhdGNoaW5nIGluXCIgYW4gYXVkaW8gbm9kZSB0byB2aXN1YWxpemUuIE5PVEU6IFlvdSBjYW5ub3QgY29ubmVjdCBhdWRpbyBub2RlcyBhY3Jvc3MgdHdvIGRpZmZlcmVudCBhdWRpbyBjb250ZXh0cy4gTmV4dXNVSSBydW5zIGl0cyBhdWRpbyBhbmFseXNpcyBvbiBpdHMgb3duIGF1ZGlvIGNvbnRleHQsIE5leHVzLmNvbnRleHQuIElmIHRoZSBhdWRpbyBub2RlIHlvdSBhcmUgdmlzdWFsaXppbmcgaXMgY3JlYXRlZCBvbiBhIGRpZmZlcmVudCBhdWRpbyBjb250ZXh0LCB5b3Ugd2lsbCBuZWVkIHRvIHRlbGwgTmV4dXNVSSB0byB1c2UgdGhhdCBjb250ZXh0IGluc3RlYWQ6IGkuZS4gTmV4dXMuY29udGV4dCA9IFlvdXJBdWRpb0NvbnRleHROYW1lLiBGb3IgZXhhbXBsZSwgaW4gVG9uZUpTIHByb2plY3RzLCB0aGUgbGluZSB3b3VsZCBiZTogTmV4dXMuY29udGV4dCA9IFRvbmUuY29udGV4dCAuIFdlIHJlY29tbWVuZCB0aGF0IHlvdSB3cml0ZSB0aGF0IGxpbmUgb2YgY29kZSBvbmx5IG9uY2UgYXQgdGhlIGJlZ2lubmluZyBvZiB5b3VyIHByb2plY3QuXG4gIEBwYXJhbSBub2RlIHtBdWRpb05vZGV9IFRoZSBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZVxuICBAZXhhbXBsZSBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC8vIG9yIGFub3RoZXIgYXVkaW8gY29udGV4dCB5b3UgaGF2ZSBjcmVhdGVkXG4gIHNwZWN0cm9ncmFtLmNvbm5lY3QoIFRvbmUuTWFzdGVyICk7XG4gICovXG4gIGNvbm5lY3Qobm9kZSkge1xuICAgIGlmICh0aGlzLnNvdXJjZSkge1xuICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgfVxuICAgIHRoaXMuc291cmNlID0gbm9kZTtcbiAgICB0aGlzLnNvdXJjZS5jb25uZWN0KHRoaXMuYW5hbHlzZXIpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKipcbiAgU3RvcCB2aXN1YWxpemluZyB0aGUgc291cmNlIG5vZGUgYW5kIGRpc2Nvbm5lY3QgaXQuXG4gICovXG4gIGRpc2Nvbm5lY3QoKSB7XG4gICAgdGhpcy5zb3VyY2UuZGlzY29ubmVjdCh0aGlzLmFuYWx5c2VyKTtcbiAgICB0aGlzLnNvdXJjZSA9IG51bGw7XG4gIH1cblxuICBjbGljaygpIHtcbiAgICB0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL3NwZWN0cm9ncmFtLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgZG9tID0gcmVxdWlyZSgnLi4vdXRpbC9kb20nKTtcbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcblxuXG4vKipcbiogTWV0ZXJcbipcbiogQGRlc2NyaXB0aW9uIFN0ZXJlbyBkZWNpYmVsIG1ldGVyXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwibWV0ZXJcIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBtZXRlciA9IG5ldyBOZXh1cy5NZXRlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBtZXRlciA9IG5ldyBOZXh1cy5NZXRlcignI3RhcmdldCcse1xuKiAgIHNpemU6IFs3NSw3NV1cbiogfSlcbipcbiogQG91dHB1dFxuKiAmbmJzcDtcbiogTm8gZXZlbnRzXG4qXG4qL1xuXG5pbXBvcnQgeyBjb250ZXh0IH0gZnJvbSAnLi4vbWFpbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1ldGVyIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWydzY2FsZScsJ3ZhbHVlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFszMCwxMDBdXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgICB0aGlzLmNoYW5uZWxzID0gMjtcblxuICAgIHRoaXMuc3BsaXR0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKCB0aGlzLmNoYW5uZWxzICk7XG5cbiAgICB0aGlzLmFuYWx5c2VycyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wOyBpPHRoaXMuY2hhbm5lbHM7IGkrKykge1xuICAgICAgbGV0IGFuYWx5c2VyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gICAgICB0aGlzLnNwbGl0dGVyLmNvbm5lY3QoYW5hbHlzZXIsaSk7XG4gICAgICBhbmFseXNlci5mZnRTaXplID0gMTAyNDtcbiAgICAgIGFuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IDE7XG4gICAgICB0aGlzLmFuYWx5c2Vycy5wdXNoKCBhbmFseXNlciApO1xuICAgIH1cbiAgICB0aGlzLmJ1ZmZlckxlbmd0aCA9IHRoaXMuYW5hbHlzZXJzWzBdLmZyZXF1ZW5jeUJpbkNvdW50O1xuICAgIHRoaXMuZGF0YUFycmF5ID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJ1ZmZlckxlbmd0aCk7XG5cbi8qXG4gICAgLy8gYWRkIGxpbmVhciBncmFkaWVudFxuICAgIHZhciBncmQgPSBjYW52YXNDdHguY3JlYXRlTGluZWFyR3JhZGllbnQoMCwgMCwgMCwgY2FudmFzLmhlaWdodCk7XG4gICAgLy8gbGlnaHQgYmx1ZVxuICAgIGdyZC5hZGRDb2xvclN0b3AoMCwgJyMwMDAnKTtcbiAgICBncmQuYWRkQ29sb3JTdG9wKDAuMiwgJyNiYmInKTtcbiAgICBncmQuYWRkQ29sb3JTdG9wKDAuNCwgJyNkMTgnKTtcbiAgICAvLyBkYXJrIGJsdWVcbiAgICBncmQuYWRkQ29sb3JTdG9wKDEsICcjZDE4Jyk7XG4gICAgY2FudmFzQ3R4LmZpbGxTdHlsZSA9IGdyZDsgKi9cblxuICAgIHRoaXMuYWN0aXZlID0gdHJ1ZTtcblxuICAgIHRoaXMuZGIgPSAtSW5maW5pdHk7XG5cbiAgICB0aGlzLmluaXQoKTtcblxuICAgIHRoaXMubWV0ZXJXaWR0aCA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgvdGhpcy5jaGFubmVscztcblxuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5jYW52YXMgPSBuZXcgZG9tLlNtYXJ0Q2FudmFzKHRoaXMucGFyZW50KTtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNhbnZhcy5lbGVtZW50O1xuICB9XG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5yZXNpemUodGhpcy53aWR0aCx0aGlzLmhlaWdodCk7XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gIH1cblxuICByZW5kZXIoKSB7XG5cbiAgICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlci5iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxTdHlsZSA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgdGhpcy5jYW52YXMuY29udGV4dC5maWxsUmVjdCgwLCAwLCB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoICwgdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQpO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5hbmFseXNlcnMubGVuZ3RoO2krKykge1xuXG4gICAgICBpZiAodGhpcy5zb3VyY2UpIHtcblxuICAgICAgICB0aGlzLmFuYWx5c2Vyc1tpXS5nZXRGbG9hdFRpbWVEb21haW5EYXRhKHRoaXMuZGF0YUFycmF5KTtcblxuICAgICAgICBsZXQgcm1zID0gMDtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZGF0YUFycmF5Lmxlbmd0aDsgaSsrKXtcbiAgICAgICAgICAgICBybXMgKz0gKHRoaXMuZGF0YUFycmF5W2ldICogdGhpcy5kYXRhQXJyYXlbaV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcm1zID0gTWF0aC5zcXJ0KHJtcyAvIHRoaXMuZGF0YUFycmF5Lmxlbmd0aCk7XG5cbiAgICAgICAgdGhpcy5kYiA9IDIwICogTWF0aC5sb2cxMChybXMpO1xuXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuZGIgPiAtMjAwICYmIHRoaXMuZGIgIT09IC1JbmZpbml0eSkge1xuICAgICAgICB0aGlzLmRiIC09IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRiID0gLUluZmluaXR5O1xuICAgICAgfVxuXG5cbiAgICAgIC8vY29uc29sZS5sb2coZGIpXG5cbiAgICAgIGlmICh0aGlzLmRiID4gLTcwKSB7XG5cbiAgICAgICAgbGV0IGxpbmVhciA9IG1hdGgubm9ybWFsaXplKHRoaXMuZGIsLTcwLDUpO1xuICAgICAgICBsZXQgZXhwID0gbGluZWFyICogbGluZWFyO1xuICAgICAgICBsZXQgeSA9IG1hdGguc2NhbGUoZXhwLDAsMSx0aGlzLmVsZW1lbnQuaGVpZ2h0LDApO1xuXG4gICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KHRoaXMubWV0ZXJXaWR0aCppLHksdGhpcy5tZXRlcldpZHRoLHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0IC0geSk7XG5cbiAgICAgICAgLy9jb25zb2xlLmxvZyhcInJlbmRlcmluZy4uLlwiKVxuXG4gICAgICB9XG5cbiAgICB9XG5cbiAgfVxuXG4gIC8qKlxuICBFcXVpdmFsZW50IHRvIFwicGF0Y2hpbmcgaW5cIiBhbiBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZS4gTk9URTogWW91IGNhbm5vdCBjb25uZWN0IGF1ZGlvIG5vZGVzIGFjcm9zcyB0d28gZGlmZmVyZW50IGF1ZGlvIGNvbnRleHRzLiBOZXh1c1VJIHJ1bnMgaXRzIGF1ZGlvIGFuYWx5c2lzIG9uIGl0cyBvd24gYXVkaW8gY29udGV4dCwgTmV4dXMuY29udGV4dC4gSWYgdGhlIGF1ZGlvIG5vZGUgeW91IGFyZSB2aXN1YWxpemluZyBpcyBjcmVhdGVkIG9uIGEgZGlmZmVyZW50IGF1ZGlvIGNvbnRleHQsIHlvdSB3aWxsIG5lZWQgdG8gdGVsbCBOZXh1c1VJIHRvIHVzZSB0aGF0IGNvbnRleHQgaW5zdGVhZDogaS5lLiBOZXh1cy5jb250ZXh0ID0gWW91ckF1ZGlvQ29udGV4dE5hbWUuIEZvciBleGFtcGxlLCBpbiBUb25lSlMgcHJvamVjdHMsIHRoZSBsaW5lIHdvdWxkIGJlOiBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC4gV2UgcmVjb21tZW5kIHRoYXQgeW91IHdyaXRlIHRoYXQgbGluZSBvZiBjb2RlIG9ubHkgb25jZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgcHJvamVjdC5cbiAgQHBhcmFtIG5vZGUge0F1ZGlvTm9kZX0gVGhlIGF1ZGlvIG5vZGUgdG8gdmlzdWFsaXplXG4gIEBwYXJhbSBjaGFubmVscyB7bnVtYmVyfSAob3B0aW9uYWwpIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIHNvdXJjZSBub2RlIHRvIHdhdGNoLiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgaW50ZXJmYWNlIHdpbGwgbG9vayBmb3IgYSAuY2hhbm5lbENvdW50IHByb3BlcnR5IG9uIHRoZSBpbnB1dCBub2RlLiBJZiBpdCBkb2VzIG5vdCBleGlzdCwgdGhlIGludGVyZmFjZSB3aWxsIGRlZmF1bHQgdG8gMSBjaGFubmVsLlxuICBAZXhhbXBsZSBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC8vIG9yIGFub3RoZXIgYXVkaW8gY29udGV4dCB5b3UgaGF2ZSBjcmVhdGVkXG4gIG1ldGVyLmNvbm5lY3QoIFRvbmUuTWFzdGVyLCAyICk7XG4gICovXG5cbiAgY29ubmVjdChub2RlLGNoYW5uZWxzKSB7XG4gICAgaWYgKHRoaXMuc291cmNlKSB7XG4gICAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG4gICAgLy90aGlzLmR1bW15LmRpc2Nvbm5lY3QodGhpcy5zcGxpdHRlcik7XG5cbiAgICBpZiAoY2hhbm5lbHMpIHtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVscztcbiAgICB9IGVsc2UgaWYgKG5vZGUuY2hhbm5lbENvdW50KSB7XG4gICAgICB0aGlzLmNoYW5uZWxzID0gbm9kZS5jaGFubmVsQ291bnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSAyO1xuICAgIH1cbiAgICB0aGlzLm1ldGVyV2lkdGggPSB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoL3RoaXMuY2hhbm5lbHM7XG5cbiAgICB0aGlzLnNvdXJjZSA9IG5vZGU7XG4gICAgdGhpcy5zb3VyY2UuY29ubmVjdCh0aGlzLnNwbGl0dGVyKTtcblxuICAvLyAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBTdG9wIHZpc3VhbGl6aW5nIHRoZSBzb3VyY2Ugbm9kZSBhbmQgZGlzY29ubmVjdCBpdC5cbiAgKi9cbiAgZGlzY29ubmVjdCgpIHtcblxuICAgIHRoaXMuc291cmNlLmRpc2Nvbm5lY3QodGhpcy5zcGxpdHRlcik7XG4gICAgdGhpcy5zb3VyY2UgPSBmYWxzZTtcbiAgLy8gIHRoaXMuZHVtbXkuY29ubmVjdCh0aGlzLnNwbGl0dGVyKTtcbiAgICB0aGlzLm1ldGVyV2lkdGggPSB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoL3RoaXMuY2hhbm5lbHM7XG5cbiAgfVxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBjdXN0b21EZXN0cm95KCkge1xuICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvbWV0ZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBkb20gPSByZXF1aXJlKCcuLi91dGlsL2RvbScpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5cbi8qKlxuKiBPc2NpbGxvc2NvcGVcbipcbiogQGRlc2NyaXB0aW9uIFZpc3VhbGl6ZXMgYSB3YXZlZm9ybSdzIHN0cmVhbSBvZiB2YWx1ZXMuXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwib3NjaWxsb3Njb3BlXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgb3NjaWxsb3Njb3BlID0gbmV3IE5leHVzLk9zY2lsbG9zY29wZSgnI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBvc2NpbGxvc2NvcGUgPSBuZXcgTmV4dXMuT3NjaWxsb3Njb3BlKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMzAwLDE1MF1cbiogfSlcbipcbiogQG91dHB1dFxuKiAmbmJzcDtcbiogTm8gZXZlbnRzXG4qXG4qL1xuXG5pbXBvcnQgeyBjb250ZXh0IH0gZnJvbSAnLi4vbWFpbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE9zY2lsbG9zY29wZSBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnc2NhbGUnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMzAwLDE1MF1cbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dCgpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuICAgIHRoaXMuYW5hbHlzZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgICB0aGlzLmFuYWx5c2VyLmZmdFNpemUgPSAyMDQ4O1xuICAgIHRoaXMuYnVmZmVyTGVuZ3RoID0gdGhpcy5hbmFseXNlci5mcmVxdWVuY3lCaW5Db3VudDtcbiAgICB0aGlzLmRhdGFBcnJheSA9IG5ldyBVaW50OEFycmF5KHRoaXMuYnVmZmVyTGVuZ3RoKTtcbiAgICB0aGlzLmFuYWx5c2VyLmdldEJ5dGVUaW1lRG9tYWluRGF0YSh0aGlzLmRhdGFBcnJheSk7XG5cbiAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG5cbiAgICB0aGlzLnNvdXJjZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmNhbnZhcyA9IG5ldyBkb20uU21hcnRDYW52YXModGhpcy5wYXJlbnQpO1xuICAgIHRoaXMuZWxlbWVudCA9IHRoaXMuY2FudmFzLmVsZW1lbnQ7XG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuICAgIHRoaXMuY2FudmFzLnJlc2l6ZSh0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuY2FudmFzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgfVxuXG4gIHJlbmRlcigpIHtcblxuICAgIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMucmVuZGVyLmJpbmQodGhpcykpO1xuICAgIH1cblxuICAgIHRoaXMuYW5hbHlzZXIuZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKHRoaXMuZGF0YUFycmF5KTtcblxuICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KDAsIDAsIHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgsIHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0KTtcblxuICAgIHRoaXMuY2FudmFzLmNvbnRleHQubGluZVdpZHRoID0gfn4odGhpcy5oZWlnaHQgLyAxMDAgKyAyKTtcbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LnN0cm9rZVN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuXG4gICAgdGhpcy5jYW52YXMuY29udGV4dC5iZWdpblBhdGgoKTtcblxuICAgIGlmICh0aGlzLnNvdXJjZSkge1xuXG4gICAgICB2YXIgc2xpY2VXaWR0aCA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGggKiAxLjAgLyB0aGlzLmJ1ZmZlckxlbmd0aDtcbiAgICAgIHZhciB4ID0gMDtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJ1ZmZlckxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgdmFyIHYgPSB0aGlzLmRhdGFBcnJheVtpXSAvIDEyOC4wO1xuICAgICAgICB2YXIgeSA9IHYgKiB0aGlzLmNhbnZhcy5lbGVtZW50LmhlaWdodCAvIDI7XG5cbiAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0Lm1vdmVUbyh4LCB5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmxpbmVUbyh4LCB5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHggKz0gc2xpY2VXaWR0aDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0Lm1vdmVUbygwLCB0aGlzLmNhbnZhcy5lbGVtZW50LmhlaWdodC8yKTtcbiAgICAgICAgdGhpcy5jYW52YXMuY29udGV4dC5saW5lVG8odGhpcy5jYW52YXMuZWxlbWVudC53aWR0aCwgdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQvMik7XG4gICAgfVxuXG4gICAgdGhpcy5jYW52YXMuY29udGV4dC5zdHJva2UoKTtcbiAgfVxuXG4gIC8qKlxuICBFcXVpdmFsZW50IHRvIFwicGF0Y2hpbmcgaW5cIiBhbiBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZS4gTk9URTogWW91IGNhbm5vdCBjb25uZWN0IGF1ZGlvIG5vZGVzIGFjcm9zcyB0d28gZGlmZmVyZW50IGF1ZGlvIGNvbnRleHRzLiBOZXh1c1VJIHJ1bnMgaXRzIGF1ZGlvIGFuYWx5c2lzIG9uIGl0cyBvd24gYXVkaW8gY29udGV4dCwgTmV4dXMuY29udGV4dC4gSWYgdGhlIGF1ZGlvIG5vZGUgeW91IGFyZSB2aXN1YWxpemluZyBpcyBjcmVhdGVkIG9uIGEgZGlmZmVyZW50IGF1ZGlvIGNvbnRleHQsIHlvdSB3aWxsIG5lZWQgdG8gdGVsbCBOZXh1c1VJIHRvIHVzZSB0aGF0IGNvbnRleHQgaW5zdGVhZDogaS5lLiBOZXh1cy5jb250ZXh0ID0gWW91ckF1ZGlvQ29udGV4dE5hbWUuIEZvciBleGFtcGxlLCBpbiBUb25lSlMgcHJvamVjdHMsIHRoZSBsaW5lIHdvdWxkIGJlOiBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC4gV2UgcmVjb21tZW5kIHRoYXQgeW91IHdyaXRlIHRoYXQgbGluZSBvZiBjb2RlIG9ubHkgb25jZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgcHJvamVjdC5cbiAgQHBhcmFtIG5vZGUge0F1ZGlvTm9kZX0gVGhlIGF1ZGlvIG5vZGUgdG8gdmlzdWFsaXplXG4gIEBleGFtcGxlIE5leHVzLmNvbnRleHQgPSBUb25lLmNvbnRleHQgLy8gb3IgYW5vdGhlciBhdWRpbyBjb250ZXh0IHlvdSBoYXZlIGNyZWF0ZWRcbiAgb3NjaWxsb3Njb3BlLmNvbm5lY3QoIFRvbmUuTWFzdGVyICk7XG4gICovXG5cbiAgY29ubmVjdChub2RlKSB7XG5cbiAgICBpZiAodGhpcy5zb3VyY2UpIHtcbiAgICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIH1cblxuICAgIHRoaXMuc291cmNlID0gbm9kZTtcbiAgICB0aGlzLnNvdXJjZS5jb25uZWN0KHRoaXMuYW5hbHlzZXIpO1xuXG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBTdG9wIHZpc3VhbGl6aW5nIHRoZSBzb3VyY2Ugbm9kZSBhbmQgZGlzY29ubmVjdCBpdC5cbiAgKi9cbiAgZGlzY29ubmVjdCgpIHtcbiAgICBpZiAodGhpcy5zb3VyY2UpIHtcbiAgICAgIHRoaXMuc291cmNlLmRpc2Nvbm5lY3QodGhpcy5hbmFseXNlcik7XG4gICAgICB0aGlzLnNvdXJjZSA9IG51bGw7XG4gICAgfVxuXG4gIH1cblxuICBjbGljaygpIHtcbiAgICB0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL29zY2lsbG9zY29wZS5qcyIsIi8qXG5NYWluIGNvbmNlcHQ6XG5zeW50aCA9IG5ldyBOZXh1cy5SYWNrKCdlbGVtZW50SUQnKTtcblxuVHJhbnNmb3JtIGFsbCBlbGVtZW50cyBpbnNpZGUgdGhlIGRpdlxuc3ludGguZWxlbWVudElEIHdpbGwgaG9sZCB0aGUgZmlyc3Qgc2xpZGVyIGludGVyZmFjZVxuXG4yKSBJbiBmdXR1cmUsIHBvdGVudGlhbGx5IHdyaXRpbmcgYSByYWNrIHRoYXQgaXMgcmUtdXNhYmxlP1xuQ291bGQgYWxzbyB0YWtlIEpTT05cblxubmV3IE5leHVzLlJhY2soJyN0YXJnZXQnLHtcbiAgcHJlOiAoKSA9PiB7XG4gICAgY3JlYXRlIHNvbWUgZGl2cyBoZXJlLCBvciBzb21lIGF1ZGlvIGNvZGVcbiAgfSxcbiAgaW50ZXJmYWNlOiB7XG4gICAgc2xpZGVyMTogTmV4dXMuYWRkLnNsaWRlcih7XG4gICAgICB0b3A6MTAsXG4gICAgICBsZWZ0OjEwLFxuICAgICAgd2lkdGg6NTAsXG4gICAgICBoZWlnaHQ6MTAwLFxuICAgICAgbWluOiAwLFxuICAgICAgbWF4OiAxMDAsXG4gICAgICBzdGVwOiAxXG4gICAgfSksXG4gICAgd2F2ZTE6IE5leHVzLmFkZC53YXZlZm9ybSh7XG4gICAgICBmaWxlOiAnLi9wYXRoL3RvL2ZpbGUubXAzJyxcbiAgICAgIHdpZHRoOjUwMCxcbiAgICAgIGhlaWdodDoxMDAsXG4gICAgICBtb2RlOiAncmFuZ2UnXG4gICAgfSlcbiAgfSxcbiAgaW5pdDogKCkgPT4ge1xuICAgIC8vIHNvbWUgYXVkaW8gaW5pdCBjb2RlIGdvZXMgaGVyZS4uLlxuICB9XG59KTtcblxuKi9cblxuaW1wb3J0ICogYXMgdHJhbnNmb3JtIGZyb20gJy4uL3V0aWwvdHJhbnNmb3JtJztcbmltcG9ydCBkb20gZnJvbSAnLi4vdXRpbC9kb20nO1xuXG5pbXBvcnQgeyBjb2xvcnMgfSBmcm9tICcuLi9tYWluJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmFjayB7XG5cbiAgY29uc3RydWN0b3IodGFyZ2V0LCBzZXR0aW5ncykge1xuXG4gICAgdGhpcy5tZXRhID0ge307XG4gICAgdGhpcy5tZXRhLnRhcmdldCA9IHRhcmdldDtcbiAgICB0aGlzLm1ldGEucGFyZW50ID0gZG9tLnBhcnNlRWxlbWVudCh0YXJnZXQpOyAvLyBzaG91bGQgYmUgYSBnZW5lcmljIGZ1bmN0aW9uIGZvciBwYXJzaW5nIGEgJ3RhcmdldCcgYXJndW1lbnQgdGhhdCBjaGVja3MgZm9yIHN0cmluZy9ET00valFVRVJZXG4gICAgdGhpcy5tZXRhLmNvbG9ycyA9IHt9O1xuXG4gICAgaWYgKHNldHRpbmdzKSB7XG4gICAgICB0aGlzLm1ldGEuYXR0cmlidXRlID0gc2V0dGluZ3MuYXR0cmlidXRlIHx8ICduZXh1cy11aSc7XG4gICAgICB0aGlzLm1ldGEudGl0bGUgPSBzZXR0aW5ncy5uYW1lIHx8IGZhbHNlO1xuICAgICAgdGhpcy5tZXRhLm9wZW4gPSBzZXR0aW5ncy5vcGVuIHx8IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1ldGEuYXR0cmlidXRlID0gJ25leHVzLXVpJztcbiAgICAgIHRoaXMubWV0YS50aXRsZSA9IGZhbHNlO1xuICAgICAgdGhpcy5tZXRhLm9wZW4gPSBmYWxzZTtcbiAgICB9XG5cbiAgICBsZXQgZGVmYXVsdENvbG9ycyA9IGNvbG9ycygpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgICB0aGlzLm1ldGEuY29sb3JzLmFjY2VudCA9IGRlZmF1bHRDb2xvcnMuYWNjZW50O1xuICAgIHRoaXMubWV0YS5jb2xvcnMuZmlsbCA9IGRlZmF1bHRDb2xvcnMuZmlsbDtcbiAgICB0aGlzLm1ldGEuY29sb3JzLmxpZ2h0ID0gZGVmYXVsdENvbG9ycy5saWdodDtcbiAgICB0aGlzLm1ldGEuY29sb3JzLmRhcmsgPSBkZWZhdWx0Q29sb3JzLmRhcms7XG4gICAgdGhpcy5tZXRhLmNvbG9ycy5tZWRpdW1MaWdodCA9IGRlZmF1bHRDb2xvcnMubWVkaXVtTGlnaHQ7XG4gICAgdGhpcy5tZXRhLmNvbG9ycy5tZWRpdW1EYXJrID0gZGVmYXVsdENvbG9ycy5tZWRpdW1EYXJrO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgICB0aGlzLmNvbG9ySW50ZXJmYWNlKCk7XG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcbiAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLmJveFNpemluZyA9ICdib3JkZXItYm94JztcbiAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLnVzZXJTZWxlY3QgPSAnbm9uZSc7XG4gICAgdGhpcy5tZXRhLnBhcmVudC5zdHlsZS5tb3pVc2VyU2VsZWN0ID0gJ25vbmUnO1xuICAgIHRoaXMubWV0YS5wYXJlbnQuc3R5bGUud2Via2l0VXNlclNlbGVjdCA9ICdub25lJztcblxuICAgIHRoaXMubWV0YS5jb250ZW50cyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG4gICAgd2hpbGUgKHRoaXMubWV0YS5wYXJlbnQuY2hpbGROb2Rlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMubWV0YS5jb250ZW50cy5hcHBlbmRDaGlsZCh0aGlzLm1ldGEucGFyZW50LmNoaWxkTm9kZXNbMF0pO1xuICAgIH1cblxuICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5wYWRkaW5nID0gJzBweCc7XG4gICAgdGhpcy5tZXRhLmNvbnRlbnRzLnN0eWxlLmJveFNpemluZyA9ICdib3JkZXItYm94JztcblxuICAgIGlmICh0aGlzLm1ldGEudGl0bGUpIHtcbiAgICAgIHRoaXMubWV0YS50aXRsZUJhciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLmlubmVySFRNTCA9IHRoaXMubWV0YS50aXRsZTtcbiAgICAgIHRoaXMubWV0YS50aXRsZUJhci5zdHlsZS5mb250RmFtaWx5ID0gJ2FyaWFsJztcbiAgICAgIHRoaXMubWV0YS50aXRsZUJhci5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgICB0aGlzLm1ldGEudGl0bGVCYXIuc3R5bGUuY29sb3IgPSAnIzg4OCc7XG4gICAgICB0aGlzLm1ldGEudGl0bGVCYXIuc3R5bGUucGFkZGluZyA9ICc3cHgnO1xuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLnN0eWxlLmZvbnRTaXplID0gJzEycHgnO1xuXG4gICAgICB0aGlzLm1ldGEuYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUudG9wID0gJzVweCcgO1xuICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5yaWdodCA9ICc1cHgnIDtcbiAgICAgIHRoaXMubWV0YS5idXR0b24uaW5uZXJIVE1MID0gJy0nO1xuICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5wYWRkaW5nID0gJzBweCA1cHggMnB4JztcbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUubGluZUhlaWdodCA9ICcxMnB4JztcbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUuZm9udFNpemUgPSAnMTVweCc7XG5cbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInO1xuXG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3ZlcicsICgpID0+IHtcbiAgICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLm1lZGl1bURhcms7XG4gICAgICB9KTtcbiAgICAgIHRoaXMubWV0YS5idXR0b24uYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLm1lZGl1bUxpZ2h0O1xuICAgICAgfSk7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tZXRhLm9wZW4pIHtcbiAgICAgICAgICB0aGlzLmhpZGUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNob3coKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cblxuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLmFwcGVuZENoaWxkKHRoaXMubWV0YS5idXR0b24pO1xuXG4gICAgICB0aGlzLm1ldGEucGFyZW50LmFwcGVuZENoaWxkKHRoaXMubWV0YS50aXRsZUJhcik7XG4gICAgfVxuICAgIHRoaXMubWV0YS5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5tZXRhLmNvbnRlbnRzKTtcblxuICAvLyAgdmFyIHdpZHRoID0gdGhpcy5tZXRhLnBhcmVudC5zdHlsZS53aWR0aCA9IGdldENvbXB1dGVkU3R5bGUodGhpcy5tZXRhLnBhcmVudCkuZ2V0UHJvcGVydHlWYWx1ZSgnd2lkdGgnKTtcbi8vICAgIHRoaXMubWV0YS5wYXJlbnQuc3R5bGUud2lkdGggPSB3aWR0aDtcblxuICAgIGxldCB1aSA9IHRyYW5zZm9ybS5zZWN0aW9uKHRoaXMubWV0YS50YXJnZXQsIHRoaXMubWV0YS5hdHRyaWJ1dGUpO1xuICAgIGZvciAodmFyIGtleSBpbiB1aSkge1xuICAgICAgdGhpc1trZXldID0gdWlba2V5XTtcbiAgICB9XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICBpZiAodGhpcy5tZXRhLnRpdGxlKSB7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMubWV0YS5jb2xvcnMubWVkaXVtTGlnaHQ7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLmJvcmRlciA9ICdzb2xpZCAwcHggJyt0aGlzLm1ldGEuY29sb3JzLmZpbGw7XG4gICAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLmJvcmRlciA9ICdzb2xpZCAxcHggJyt0aGlzLm1ldGEuY29sb3JzLm1lZGl1bUxpZ2h0O1xuICAgICAgdGhpcy5tZXRhLnBhcmVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLmxpZ2h0O1xuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMubWV0YS5jb2xvcnMuZmlsbDtcbiAgICB9XG4gIH1cblxuICBzaG93KCkge1xuICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICB0aGlzLm1ldGEub3BlbiA9IHRydWU7XG4gIH1cblxuICBoaWRlKCkge1xuICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHRoaXMubWV0YS5vcGVuID0gZmFsc2U7XG4gIH1cblxuICBjb2xvcml6ZSh0eXBlLGNvbG9yKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMpIHtcbiAgICAgIGlmICh0aGlzW2tleV0uY29sb3JpemUpIHtcbiAgICAgICAgdGhpc1trZXldLmNvbG9yaXplKHR5cGUsY29sb3IpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLm1ldGEuY29sb3JzW3R5cGVdID0gY29sb3I7XG4gICAgdGhpcy5jb2xvckludGVyZmFjZSgpO1xuICB9XG5cbiAgZW1wdHkoKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMpIHtcbiAgICAgIGlmICh0aGlzW2tleV0uZGVzdHJveSkge1xuICAgICAgICB0aGlzW2tleV0uZGVzdHJveSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvY29yZS9yYWNrLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgZG9tIGZyb20gJy4uL3V0aWwvZG9tJztcbmltcG9ydCBJbnRlcmZhY2VzIGZyb20gJy4uL2ludGVyZmFjZXMvJztcblxubGV0IGNyZWF0ZUludGVyZmFjZUlEID0gKHdpZGdldCxpbnRlcmZhY2VJRHMpID0+IHtcbiAgbGV0IHR5cGUgPSB3aWRnZXQudHlwZTtcbiAgaWYgKGludGVyZmFjZUlEc1t0eXBlXSkge1xuICAgIGludGVyZmFjZUlEc1t0eXBlXSsrO1xuICB9IGVsc2Uge1xuICAgIGludGVyZmFjZUlEc1t0eXBlXSA9IDE7XG4gIH1cbiAgcmV0dXJuICggdHlwZSArIGludGVyZmFjZUlEc1t0eXBlXSApO1xufTtcblxubGV0IGVsZW1lbnQgPSAoZWxlbWVudCx0eXBlLG9wdGlvbnMpID0+IHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudC5hdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKXtcbiAgICBsZXQgYXR0ID0gZWxlbWVudC5hdHRyaWJ1dGVzW2ldO1xuICAvLyAgdHJ5IHtcbiAgLy8gICAgb3B0aW9uc1thdHQubm9kZU5hbWVdID0gZXZhbChhdHQubm9kZVZhbHVlKTtcbiAgLy8gIH0gY2F0Y2goZSkge1xuICAgICAgb3B0aW9uc1thdHQubm9kZU5hbWVdID0gYXR0Lm5vZGVWYWx1ZTtcbiAgLy8gIH1cbiAgfVxuICB0eXBlID0gdHlwZVswXS50b1VwcGVyQ2FzZSgpICsgdHlwZS5zbGljZSgxKTtcbiAgbGV0IHdpZGdldCA9IG5ldyBJbnRlcmZhY2VzW3R5cGVdKGVsZW1lbnQsb3B0aW9ucyk7XG4gIHdpZGdldC5pZCA9IGVsZW1lbnQuaWQ7XG4gIHJldHVybiB3aWRnZXQ7XG59O1xuXG5cbmxldCBzZWN0aW9uID0gKHBhcmVudCxrZXl3b3JkKSA9PiB7XG5cbiAga2V5d29yZCA9IGtleXdvcmQgfHwgJ25leHVzLXVpJztcblxuICBsZXQgaW50ZXJmYWNlSURzID0ge307XG5cbiAgbGV0IGNvbnRhaW5lciA9IGRvbS5wYXJzZUVsZW1lbnQocGFyZW50KTtcblxuICBsZXQgdWkgPSB7fTtcblxuICBsZXQgaHRtbEVsZW1lbnRzID0gY29udGFpbmVyLmdldEVsZW1lbnRzQnlUYWdOYW1lKCcqJyk7XG4gIGxldCBlbGVtZW50cyA9IFtdO1xuICBmb3IgKGxldCBpPTA7IGk8aHRtbEVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgZWxlbWVudHMucHVzaChodG1sRWxlbWVudHNbaV0pO1xuICB9XG4gIGZvciAobGV0IGk9MDtpPGVsZW1lbnRzLmxlbmd0aDtpKyspIHtcbiAgICBsZXQgdHlwZSA9IGVsZW1lbnRzW2ldLmdldEF0dHJpYnV0ZShrZXl3b3JkKTtcbiAgICBpZiAodHlwZSkge1xuICAgICAgbGV0IGZvcm1hdHRlZFR5cGUgPSBmYWxzZTtcbiAgICAgIGZvciAobGV0IGtleSBpbiBJbnRlcmZhY2VzKSB7XG4gICAgICAgIGlmICh0eXBlLnRvTG93ZXJDYXNlKCk9PT1rZXkudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgIGZvcm1hdHRlZFR5cGUgPSBrZXk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnNvbGUubG9nKGZvcm1hdHRlZFR5cGUpO1xuICAgICAgbGV0IHdpZGdldCA9IGVsZW1lbnQoZWxlbWVudHNbaV0sZm9ybWF0dGVkVHlwZSk7XG4gICAgICBpZiAod2lkZ2V0LmlkKSB7XG4gICAgICAgIHVpW3dpZGdldC5pZF0gPSB3aWRnZXQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgaWQgPSBjcmVhdGVJbnRlcmZhY2VJRCh3aWRnZXQsaW50ZXJmYWNlSURzKTtcbiAgICAgICAgdWlbaWRdID0gd2lkZ2V0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1aTtcblxufTtcblxubGV0IGFkZCA9ICh0eXBlLHBhcmVudCxvcHRpb25zKSA9PiB7XG4gIGxldCB0YXJnZXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGlmIChwYXJlbnQpIHtcbiAgICBwYXJlbnQgPSBkb20ucGFyc2VFbGVtZW50KHBhcmVudCk7XG4gIH0gZWxzZSB7XG4gICAgcGFyZW50ID0gZG9jdW1lbnQuYm9keTtcbiAgfVxuICBwYXJlbnQuYXBwZW5kQ2hpbGQodGFyZ2V0KTtcbiAgb3B0aW9ucy50YXJnZXQgPSB0YXJnZXQ7XG4gIGlmIChvcHRpb25zLnNpemUpIHtcbiAgICB0YXJnZXQuc3R5bGUud2lkdGggPSBvcHRpb25zLnNpemVbMF0gKyAncHgnO1xuICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSBvcHRpb25zLnNpemVbMV0gKyAncHgnO1xuICB9XG4gIHJldHVybiBlbGVtZW50KHRhcmdldCx0eXBlLG9wdGlvbnMpO1xufTtcblxuZXhwb3J0IHsgZWxlbWVudCB9O1xuZXhwb3J0IHsgc2VjdGlvbiB9O1xuZXhwb3J0IHsgYWRkIH07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvdXRpbC90cmFuc2Zvcm0uanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFR1bmUge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gIFx0Ly8gdGhlIHNjYWxlIGFzIHJhdGlvc1xuICBcdHRoaXMuc2NhbGUgPSBbXTtcblxuICBcdC8vIGkvbyBtb2Rlc1xuICBcdHRoaXMubW9kZSA9IHtcbiAgXHRcdG91dHB1dDogJ2ZyZXF1ZW5jeScsXG4gIFx0XHRpbnB1dDogJ3N0ZXAnXG4gIFx0fTtcblxuICBcdC8vIEVUIG1ham9yXG4gIFx0dGhpcy5ldG1ham9yID0gWyAyNjEuNjI1NTgsXG4gIFx0XHQyOTMuNjY0NzY0LFxuICBcdFx0MzI5LjYyNzU2MyxcbiAgXHRcdDM0OS4yMjgyNDEsXG4gIFx0XHQzOTEuOTk1NDIyLFxuICBcdFx0NDQwLFxuICBcdFx0NDkzLjg4MzMwMSxcbiAgXHRcdDUyMy4yNTExNlxuICBcdF07XG5cbiAgXHQvLyBSb290IGZyZXF1ZW5jeS5cbiAgXHR0aGlzLnJvb3QgPSBtYXRoLm10b2YoNjApOyAgICAgLy8gKiBNYXRoLnBvdygyLCg2MC02OSkvMTIpO1xuXG4gICAgLy8gZGVmYXVsdCBpcyBhIG1ham9yIHNjYWxlXG4gICAgdGhpcy5jcmVhdGVTY2FsZSgwLDIsNCw1LDcsOSwxMSk7XG5cbiAgfVxuXG4gIC8qIFJldHVybiBkYXRhIGluIHRoZSBtb2RlIHlvdSBhcmUgaW4gKGZyZXEsIHJhdGlvLCBvciBtaWRpKSAqL1xuICBub3RlKGlucHV0LG9jdGF2ZSkge1xuXG4gIFx0bGV0IG5ld3ZhbHVlO1xuXG4gIFx0aWYgKHRoaXMubW9kZS5vdXRwdXQgPT09ICdmcmVxdWVuY3knKSB7XG4gIFx0XHRuZXd2YWx1ZSA9IHRoaXMuZnJlcXVlbmN5KGlucHV0LG9jdGF2ZSk7XG4gIFx0fSBlbHNlIGlmICh0aGlzLm1vZGUub3V0cHV0ID09PSAncmF0aW8nKSB7XG4gIFx0XHRuZXd2YWx1ZSA9IHRoaXMucmF0aW8oaW5wdXQsb2N0YXZlKTtcbiAgXHR9IGVsc2UgaWYgKHRoaXMubW9kZS5vdXRwdXQgPT09ICdNSURJJykge1xuICBcdFx0bmV3dmFsdWUgPSB0aGlzLk1JREkoaW5wdXQsb2N0YXZlKTtcbiAgXHR9IGVsc2Uge1xuICBcdFx0bmV3dmFsdWUgPSB0aGlzLmZyZXF1ZW5jeShpbnB1dCxvY3RhdmUpO1xuICBcdH1cblxuICBcdHJldHVybiBuZXd2YWx1ZTtcblxuICB9XG5cblxuICAvKiBSZXR1cm4gZnJlcSBkYXRhICovXG4gIGZyZXF1ZW5jeShzdGVwSW4sIG9jdGF2ZUluKSB7XG5cbiAgXHRpZiAodGhpcy5tb2RlLmlucHV0ID09PSAnbWlkaScgfHwgdGhpcy5tb2RlLmlucHV0ID09PSAnTUlESScgKSB7XG4gIFx0XHR0aGlzLnN0ZXBJbiArPSA2MDtcbiAgXHR9XG5cbiAgXHQvLyB3aGF0IG9jdGF2ZSBpcyBvdXIgaW5wdXRcbiAgXHRsZXQgb2N0YXZlID0gTWF0aC5mbG9vcihzdGVwSW4vdGhpcy5zY2FsZS5sZW5ndGgpO1xuXG4gIFx0aWYgKG9jdGF2ZUluKSB7XG4gIFx0XHRvY3RhdmUgKz0gb2N0YXZlSW47XG4gIFx0fVxuXG4gIFx0Ly8gd2hpY2ggc2NhbGUgZGVncmVlICgwIC0gc2NhbGUgbGVuZ3RoKSBpcyBvdXIgaW5wdXRcbiAgXHRsZXQgc2NhbGVEZWdyZWUgPSBzdGVwSW4gJSB0aGlzLnNjYWxlLmxlbmd0aDtcblxuICBcdHdoaWxlIChzY2FsZURlZ3JlZSA8IDApIHtcbiAgXHRcdHNjYWxlRGVncmVlICs9IHRoaXMuc2NhbGUubGVuZ3RoO1xuICBcdH1cblxuICAgIGxldCByYXRpbyA9IHRoaXMuc2NhbGVbc2NhbGVEZWdyZWVdO1xuXG4gIFx0bGV0IGZyZXEgPSB0aGlzLnJvb3QgKiByYXRpbztcblxuICBcdGZyZXEgPSBmcmVxKihNYXRoLnBvdygyLG9jdGF2ZSkpO1xuXG4gIFx0Ly8gdHJ1bmNhdGUgaXJyYXRpb25hbCBudW1iZXJzXG4gIFx0ZnJlcSA9IE1hdGguZmxvb3IoZnJlcSoxMDAwMDAwMDAwMDApLzEwMDAwMDAwMDAwMDtcblxuICBcdHJldHVybiBmcmVxO1xuXG4gIH1cblxuICAvKiBGb3JjZSByZXR1cm4gcmF0aW8gZGF0YSAqL1xuXG4gIHJhdGlvKHN0ZXBJbiwgb2N0YXZlSW4pIHtcblxuICBcdGlmICh0aGlzLm1vZGUuaW5wdXQgPT09ICdtaWRpJyB8fCB0aGlzLm1vZGUuaW5wdXQgPT09ICdNSURJJyApIHtcbiAgXHRcdHRoaXMuc3RlcEluICs9IDYwO1xuICBcdH1cblxuICBcdC8vIHdoYXQgb2N0YXZlIGlzIG91ciBpbnB1dFxuICBcdGxldCBvY3RhdmUgPSBNYXRoLmZsb29yKHN0ZXBJbi90aGlzLnNjYWxlLmxlbmd0aCk7XG5cbiAgXHRpZiAob2N0YXZlSW4pIHtcbiAgXHRcdG9jdGF2ZSArPSBvY3RhdmVJbjtcbiAgXHR9XG5cbiAgXHQvLyB3aGljaCBzY2FsZSBkZWdyZWUgKDAgLSBzY2FsZSBsZW5ndGgpIGlzIG91ciBpbnB1dFxuICBcdGxldCBzY2FsZURlZ3JlZSA9IHN0ZXBJbiAlIHRoaXMuc2NhbGUubGVuZ3RoO1xuXG4gIFx0Ly8gd2hhdCByYXRpbyBpcyBvdXIgaW5wdXQgdG8gb3VyIGtleVxuICBcdGxldCByYXRpbyA9IE1hdGgucG93KDIsb2N0YXZlKSp0aGlzLnNjYWxlW3NjYWxlRGVncmVlXTtcblxuICBcdHJhdGlvID0gTWF0aC5mbG9vcihyYXRpbyoxMDAwMDAwMDAwMDApLzEwMDAwMDAwMDAwMDtcblxuICBcdHJldHVybiByYXRpbztcblxuICB9XG5cbiAgLyogRm9yY2UgcmV0dXJuIGFkanVzdGVkIE1JREkgZGF0YSAqL1xuXG4gIE1JREkoc3RlcEluLG9jdGF2ZUluKSB7XG5cbiAgXHRsZXQgbmV3dmFsdWUgPSB0aGlzLmZyZXF1ZW5jeShzdGVwSW4sb2N0YXZlSW4pO1xuXG4gIFx0bGV0IG4gPSA2OSArIDEyKk1hdGgubG9nKG5ld3ZhbHVlLzQ0MCkvTWF0aC5sb2coMik7XG5cbiAgXHRuID0gTWF0aC5mbG9vcihuKjEwMDAwMDAwMDApLzEwMDAwMDAwMDA7XG5cbiAgXHRyZXR1cm4gbjtcblxuICB9XG5cbiAgY3JlYXRlU2NhbGUoKSB7XG4gICAgbGV0IG5ld1NjYWxlID0gW107XG4gICAgZm9yIChsZXQgaT0wO2k8YXJndW1lbnRzLmxlbmd0aDtpKyspIHtcbiAgICAgIG5ld1NjYWxlLnB1c2goIG1hdGgubXRvZiggNjAgKyBhcmd1bWVudHNbaV0gKSApO1xuICAgIH1cbiAgICB0aGlzLmxvYWRTY2FsZUZyb21GcmVxdWVuY2llcyhuZXdTY2FsZSk7XG4gIH1cblxuICBjcmVhdGVKSVNjYWxlKCkge1xuICAgIHRoaXMuc2NhbGUgPSBbXTtcbiAgICBmb3IgKGxldCBpPTA7aTxhcmd1bWVudHMubGVuZ3RoO2krKykge1xuICAgICAgdGhpcy5zY2FsZS5wdXNoKGFyZ3VtZW50c1tpXSk7XG4gICAgfVxuICB9XG5cbiAgbG9hZFNjYWxlRnJvbUZyZXF1ZW5jaWVzKGZyZXFzKSB7XG4gICAgdGhpcy5zY2FsZSA9IFtdO1xuICAgIGZvciAobGV0IGk9MDtpPGZyZXFzLmxlbmd0aC0xO2krKykge1xuICAgICAgdGhpcy5zY2FsZS5wdXNoKGZyZXFzW2ldL2ZyZXFzWzBdKTtcbiAgICB9XG4gIH1cblxuICAvKiBMb2FkIGEgbmV3IHNjYWxlICovXG5cbiAgbG9hZFNjYWxlKG5hbWUpe1xuXG4gIFx0LyogbG9hZCB0aGUgc2NhbGUgKi9cbiAgXHRsZXQgZnJlcXMgPSB0aGlzLnNjYWxlc1tuYW1lXS5mcmVxdWVuY2llcztcbiAgICB0aGlzLmxvYWRTY2FsZUZyb21GcmVxdWVuY2llcyhmcmVxcyk7XG5cbiAgfVxuXG4gIC8qIFNlYXJjaCB0aGUgbmFtZXMgb2YgdHVuaW5nc1xuICBcdCBSZXR1cm5zIGFuIGFycmF5IG9mIG5hbWVzIG9mIHR1bmluZ3MgKi9cblxuICBzZWFyY2gobGV0dGVycykge1xuICBcdGxldCBwb3NzaWJsZSA9IFtdO1xuICBcdGZvciAobGV0IGtleSBpbiB0aGlzLnNjYWxlcykge1xuICBcdFx0aWYgKGtleS50b0xvd2VyQ2FzZSgpLmluZGV4T2YobGV0dGVycy50b0xvd2VyQ2FzZSgpKSAhPT0gLTEpIHtcbiAgXHRcdFx0cG9zc2libGUucHVzaChrZXkpO1xuICBcdFx0fVxuICBcdH1cbiAgXHRyZXR1cm4gcG9zc2libGU7XG4gIH1cblxuICAvKiBSZXR1cm4gYSBjb2xsZWN0aW9uIG9mIG5vdGVzIGFzIGFuIGFycmF5ICovXG5cbiAgY2hvcmQobWlkaXMpIHtcbiAgXHRsZXQgb3V0cHV0ID0gW107XG4gIFx0Zm9yIChsZXQgaT0wO2k8bWlkaXMubGVuZ3RoO2krKykge1xuICBcdFx0b3V0cHV0LnB1c2godGhpcy5ub3RlKG1pZGlzW2ldKSk7XG4gIFx0fVxuICBcdHJldHVybiBvdXRwdXQ7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3R1bmluZy90dW5pbmcuanMiLCIndXNlIHN0cmljdCc7XG5cbi8vRGlzYWJsZSBqc2hpbnQgd2FybmluZyBjb25jZXJuaW5nIHRyYWlsaW5nIHJlZ3VsYXIgcGFyYW1zXG4vKmpzaGludCAtVzEzOCAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSYWRpbyB7XG4gICAgLy9pZiBub24tZXhpc3RlbnQgYnV0dG9ucyBhcmUgc3dpdGNoZWQsIHRoZXkgYXJlIGlnbm9yZWRcblxuICAgIGNvbnN0cnVjdG9yKGxlbmd0aCA9IDMsIC4uLm9uVmFscykge1xuICAgICAgICAvL2VhY2ggb3B0aW9uYWwgJ29uVmFscycgYXJndW1lbnQgc3dpdGNoZXMgb24gdGhhdCB2YWx1ZSBpbiB0aGUgUmFkaW8gaWYgaXQgZXhpc3RzXG4gICAgICAgIC8vSW4gdGhlIGV4YW1wbGUgYmVsb3csIGEgMy1idXR0b24gcmFkaW8gaXMgY3JlYXRlZCwgaW5kZXggMCBpcyBzd2l0Y2hlZCBvbiwgaW5kZXggMSBpcyBzd2l0Y2hlZCBvbiB0aGVuIHRoZW4gYXR0ZW1wdGVkIGFnYWluIHByb2R1Y2luZyBhbiB3YXJuaW5nLCBhbmQgdGhlIGZpbmFsIGFyZ3VtZW50IHByb2R1Y2VzIGEgd2FybmluZyBiZWNhdXNlIHRoZSBpbmRleCB2YWx1ZSBkb2VzIG5vdCBleGlzdC5cbiAgICAgICAgLy9FeGFtcGxlOlxuICAgICAgICAvL2AgIHJhZGlvID0gbmV3IFJhZGlvKDMsIDAsIDEsIDEsIDMpO1xuICAgICAgICAvL+KApiAgWzEsMSwwXVxuXG4gICAgICAgIGlmIChsZW5ndGggPCAwKSB7IGxlbmd0aCA9IDE7IH1cblxuICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcbiAgICAgICAgdGhpcy5vblZhbHMgPSBvblZhbHM7XG4gICAgICAgIHRoaXMuYXJyYXkgPSBuZXcgQXJyYXkobGVuZ3RoKS5maWxsKDApO1xuXG4gICAgICAgIGlmIChvblZhbHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5vbiguLi5vblZhbHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2VsZWN0KHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYXJyYXkuZmlsbCgwKTtcbiAgICAgICAgdGhpcy5hcnJheVt2YWx1ZV0gPSAxO1xuICAgICAgICByZXR1cm4gdGhpcy5hcnJheTtcbiAgICB9XG5cbiAgICBmbGlwKC4uLnZhbHVlcykge1xuICAgICAgICAvL2ZsaXBzIHRoZSBzcGVjaWZpZWQgdmFsdWVzLiBpZiBubyB2YWx1ZSBpcyBzcGVjaWZpZWQsIGZsaXBzIGFsbCBidXR0b25zXG4gICAgICAgIGxldCBhID0gdGhpcy5hcnJheTtcbiAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB2YWx1ZXMuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgICAgICAgICAgaWYgKHYgPiBhLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdXYXJuaW5nOiBBbm9uUmFkaW9bJyArIHYgKyAnXSBkb2VzIG5vdCBleGlzdCcpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFbdl0gPSAoYVt2XSA/IDAgOiAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGEuZm9yRWFjaChmdW5jdGlvbih2LCBpLCBhcnIpIHtcbiAgICAgICAgICAgICAgICBhcnJbaV0gPSAodiA/IDAgOiAxKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhO1xuICAgIH1cblxuICAgIG9uKC4uLnZhbHVlcykge1xuICAgICAgICAvL3N3aXRjaCBvbiB0aGUgc3BlY2lmaWVkIHZhbHVlcy4gaWYgbm8gdmFsdWUgc3BlY2lmaWVkLCBmbGlwcyBvbiBhbGwgYnV0dG9uc1xuICAgICAgICBsZXQgYSA9IHRoaXMuYXJyYXk7XG4gICAgICAgIGlmICh2YWx1ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdmFsdWVzLmZvckVhY2goZnVuY3Rpb24odikge1xuICAgICAgICAgICAgICAgIGlmICh2ID4gYS5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignV2FybmluZzogQW5vblJhZGlvWycgKyB2ICsgJ10gZXhjZWVkcyBzaXplIG9mIG9iamVjdCcpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhW3ZdID09PSAxKSB7IGNvbnNvbGUud2FybignV2FybmluZzogQW5vblJhZGlvWycgKyB2ICsgJ10gd2FzIGFscmVhZHkgb24uJyk7IH1cbiAgICAgICAgICAgICAgICAgICAgYVt2XSA9IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhLmZpbGwoMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgb2ZmKC4uLnZhbHVlcykge1xuICAgICAgICAvL3N3aXRjaCBvZmYgdGhlIHNwZWNpZmllZCB2YWx1ZXMuIGlmIG5vIHZhbHVlIHNwZWNpZmllZCwgZmxpcHMgb2ZmIGFsbCBidXR0b25zXG4gICAgICAgIGxldCBhID0gdGhpcy5hcnJheTtcbiAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB2YWx1ZXMuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgICAgICAgICAgYVt2XSA9IDA7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGEuZmlsbCgwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYTtcbiAgICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbW9kZWxzL3JhZGlvLmpzIiwidmFyIFdBQUNsb2NrID0gcmVxdWlyZSgnLi9saWIvV0FBQ2xvY2snKVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdBQUNsb2NrXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHdpbmRvdy5XQUFDbG9jayA9IFdBQUNsb2NrXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vd2FhY2xvY2svaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDQyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBpc0Jyb3dzZXIgPSAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpXG5cbnZhciBDTE9DS19ERUZBVUxUUyA9IHtcbiAgdG9sZXJhbmNlTGF0ZTogMC4xMCxcbiAgdG9sZXJhbmNlRWFybHk6IDAuMDAxXG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09IEV2ZW50ID09PT09PT09PT09PT09PT09PT09IC8vXG52YXIgRXZlbnQgPSBmdW5jdGlvbihjbG9jaywgZGVhZGxpbmUsIGZ1bmMpIHtcbiAgdGhpcy5jbG9jayA9IGNsb2NrXG4gIHRoaXMuZnVuYyA9IGZ1bmNcbiAgdGhpcy5fY2xlYXJlZCA9IGZhbHNlIC8vIEZsYWcgdXNlZCB0byBjbGVhciBhbiBldmVudCBpbnNpZGUgY2FsbGJhY2tcblxuICB0aGlzLnRvbGVyYW5jZUxhdGUgPSBjbG9jay50b2xlcmFuY2VMYXRlXG4gIHRoaXMudG9sZXJhbmNlRWFybHkgPSBjbG9jay50b2xlcmFuY2VFYXJseVxuICB0aGlzLl9sYXRlc3RUaW1lID0gbnVsbFxuICB0aGlzLl9lYXJsaWVzdFRpbWUgPSBudWxsXG4gIHRoaXMuZGVhZGxpbmUgPSBudWxsXG4gIHRoaXMucmVwZWF0VGltZSA9IG51bGxcblxuICB0aGlzLnNjaGVkdWxlKGRlYWRsaW5lKVxufVxuXG4vLyBVbnNjaGVkdWxlcyB0aGUgZXZlbnRcbkV2ZW50LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuICB0aGlzLl9jbGVhcmVkID0gdHJ1ZVxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBTZXRzIHRoZSBldmVudCB0byByZXBlYXQgZXZlcnkgYHRpbWVgIHNlY29uZHMuXG5FdmVudC5wcm90b3R5cGUucmVwZWF0ID0gZnVuY3Rpb24odGltZSkge1xuICBpZiAodGltZSA9PT0gMClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlbGF5IGNhbm5vdCBiZSAwJylcbiAgdGhpcy5yZXBlYXRUaW1lID0gdGltZVxuICBpZiAoIXRoaXMuY2xvY2suX2hhc0V2ZW50KHRoaXMpKVxuICAgIHRoaXMuc2NoZWR1bGUodGhpcy5kZWFkbGluZSArIHRoaXMucmVwZWF0VGltZSlcbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gU2V0cyB0aGUgdGltZSB0b2xlcmFuY2Ugb2YgdGhlIGV2ZW50LlxuLy8gVGhlIGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQgaW4gdGhlIGludGVydmFsIGBbZGVhZGxpbmUgLSBlYXJseSwgZGVhZGxpbmUgKyBsYXRlXWBcbi8vIElmIHRoZSBjbG9jayBmYWlscyB0byBleGVjdXRlIHRoZSBldmVudCBpbiB0aW1lLCB0aGUgZXZlbnQgd2lsbCBiZSBkcm9wcGVkLlxuRXZlbnQucHJvdG90eXBlLnRvbGVyYW5jZSA9IGZ1bmN0aW9uKHZhbHVlcykge1xuICBpZiAodHlwZW9mIHZhbHVlcy5sYXRlID09PSAnbnVtYmVyJylcbiAgICB0aGlzLnRvbGVyYW5jZUxhdGUgPSB2YWx1ZXMubGF0ZVxuICBpZiAodHlwZW9mIHZhbHVlcy5lYXJseSA9PT0gJ251bWJlcicpXG4gICAgdGhpcy50b2xlcmFuY2VFYXJseSA9IHZhbHVlcy5lYXJseVxuICB0aGlzLl9yZWZyZXNoRWFybHlMYXRlRGF0ZXMoKVxuICBpZiAodGhpcy5jbG9jay5faGFzRXZlbnQodGhpcykpIHtcbiAgICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuICAgIHRoaXMuY2xvY2suX2luc2VydEV2ZW50KHRoaXMpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBldmVudCBpcyByZXBlYXRlZCwgZmFsc2Ugb3RoZXJ3aXNlXG5FdmVudC5wcm90b3R5cGUuaXNSZXBlYXRlZCA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5yZXBlYXRUaW1lICE9PSBudWxsIH1cblxuLy8gU2NoZWR1bGVzIHRoZSBldmVudCB0byBiZSByYW4gYmVmb3JlIGBkZWFkbGluZWAuXG4vLyBJZiB0aGUgdGltZSBpcyB3aXRoaW4gdGhlIGV2ZW50IHRvbGVyYW5jZSwgd2UgaGFuZGxlIHRoZSBldmVudCBpbW1lZGlhdGVseS5cbi8vIElmIHRoZSBldmVudCB3YXMgYWxyZWFkeSBzY2hlZHVsZWQgYXQgYSBkaWZmZXJlbnQgdGltZSwgaXQgaXMgcmVzY2hlZHVsZWQuXG5FdmVudC5wcm90b3R5cGUuc2NoZWR1bGUgPSBmdW5jdGlvbihkZWFkbGluZSkge1xuICB0aGlzLl9jbGVhcmVkID0gZmFsc2VcbiAgdGhpcy5kZWFkbGluZSA9IGRlYWRsaW5lXG4gIHRoaXMuX3JlZnJlc2hFYXJseUxhdGVEYXRlcygpXG5cbiAgaWYgKHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSA+PSB0aGlzLl9lYXJsaWVzdFRpbWUpIHtcbiAgICB0aGlzLl9leGVjdXRlKClcbiAgXG4gIH0gZWxzZSBpZiAodGhpcy5jbG9jay5faGFzRXZlbnQodGhpcykpIHtcbiAgICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuICAgIHRoaXMuY2xvY2suX2luc2VydEV2ZW50KHRoaXMpXG4gIFxuICB9IGVsc2UgdGhpcy5jbG9jay5faW5zZXJ0RXZlbnQodGhpcylcbn1cblxuRXZlbnQucHJvdG90eXBlLnRpbWVTdHJldGNoID0gZnVuY3Rpb24odFJlZiwgcmF0aW8pIHtcbiAgaWYgKHRoaXMuaXNSZXBlYXRlZCgpKVxuICAgIHRoaXMucmVwZWF0VGltZSA9IHRoaXMucmVwZWF0VGltZSAqIHJhdGlvXG5cbiAgdmFyIGRlYWRsaW5lID0gdFJlZiArIHJhdGlvICogKHRoaXMuZGVhZGxpbmUgLSB0UmVmKVxuICAvLyBJZiB0aGUgZGVhZGxpbmUgaXMgdG9vIGNsb3NlIG9yIHBhc3QsIGFuZCB0aGUgZXZlbnQgaGFzIGEgcmVwZWF0LFxuICAvLyB3ZSBjYWxjdWxhdGUgdGhlIG5leHQgcmVwZWF0IHBvc3NpYmxlIGluIHRoZSBzdHJldGNoZWQgc3BhY2UuXG4gIGlmICh0aGlzLmlzUmVwZWF0ZWQoKSkge1xuICAgIHdoaWxlICh0aGlzLmNsb2NrLmNvbnRleHQuY3VycmVudFRpbWUgPj0gZGVhZGxpbmUgLSB0aGlzLnRvbGVyYW5jZUVhcmx5KVxuICAgICAgZGVhZGxpbmUgKz0gdGhpcy5yZXBlYXRUaW1lXG4gIH1cbiAgdGhpcy5zY2hlZHVsZShkZWFkbGluZSlcbn1cblxuLy8gRXhlY3V0ZXMgdGhlIGV2ZW50XG5FdmVudC5wcm90b3R5cGUuX2V4ZWN1dGUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuY2xvY2suX3N0YXJ0ZWQgPT09IGZhbHNlKSByZXR1cm5cbiAgdGhpcy5jbG9jay5fcmVtb3ZlRXZlbnQodGhpcylcblxuICBpZiAodGhpcy5jbG9jay5jb250ZXh0LmN1cnJlbnRUaW1lIDwgdGhpcy5fbGF0ZXN0VGltZSlcbiAgICB0aGlzLmZ1bmModGhpcylcbiAgZWxzZSB7XG4gICAgaWYgKHRoaXMub25leHBpcmVkKSB0aGlzLm9uZXhwaXJlZCh0aGlzKVxuICAgIGNvbnNvbGUud2FybignZXZlbnQgZXhwaXJlZCcpXG4gIH1cbiAgLy8gSW4gdGhlIGNhc2UgYHNjaGVkdWxlYCBpcyBjYWxsZWQgaW5zaWRlIGBmdW5jYCwgd2UgbmVlZCB0byBhdm9pZFxuICAvLyBvdmVycndyaXRpbmcgd2l0aCB5ZXQgYW5vdGhlciBgc2NoZWR1bGVgLlxuICBpZiAoIXRoaXMuY2xvY2suX2hhc0V2ZW50KHRoaXMpICYmIHRoaXMuaXNSZXBlYXRlZCgpICYmICF0aGlzLl9jbGVhcmVkKVxuICAgIHRoaXMuc2NoZWR1bGUodGhpcy5kZWFkbGluZSArIHRoaXMucmVwZWF0VGltZSkgXG59XG5cbi8vIFVwZGF0ZXMgY2FjaGVkIHRpbWVzXG5FdmVudC5wcm90b3R5cGUuX3JlZnJlc2hFYXJseUxhdGVEYXRlcyA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9sYXRlc3RUaW1lID0gdGhpcy5kZWFkbGluZSArIHRoaXMudG9sZXJhbmNlTGF0ZVxuICB0aGlzLl9lYXJsaWVzdFRpbWUgPSB0aGlzLmRlYWRsaW5lIC0gdGhpcy50b2xlcmFuY2VFYXJseVxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PSBXQUFDbG9jayA9PT09PT09PT09PT09PT09PT09PSAvL1xudmFyIFdBQUNsb2NrID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihjb250ZXh0LCBvcHRzKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBvcHRzID0gb3B0cyB8fCB7fVxuICB0aGlzLnRpY2tNZXRob2QgPSBvcHRzLnRpY2tNZXRob2QgfHwgJ1NjcmlwdFByb2Nlc3Nvck5vZGUnXG4gIHRoaXMudG9sZXJhbmNlRWFybHkgPSBvcHRzLnRvbGVyYW5jZUVhcmx5IHx8IENMT0NLX0RFRkFVTFRTLnRvbGVyYW5jZUVhcmx5XG4gIHRoaXMudG9sZXJhbmNlTGF0ZSA9IG9wdHMudG9sZXJhbmNlTGF0ZSB8fCBDTE9DS19ERUZBVUxUUy50b2xlcmFuY2VMYXRlXG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHRcbiAgdGhpcy5fZXZlbnRzID0gW11cbiAgdGhpcy5fc3RhcnRlZCA9IGZhbHNlXG59XG5cbi8vIC0tLS0tLS0tLS0gUHVibGljIEFQSSAtLS0tLS0tLS0tIC8vXG4vLyBTY2hlZHVsZXMgYGZ1bmNgIHRvIHJ1biBhZnRlciBgZGVsYXlgIHNlY29uZHMuXG5XQUFDbG9jay5wcm90b3R5cGUuc2V0VGltZW91dCA9IGZ1bmN0aW9uKGZ1bmMsIGRlbGF5KSB7XG4gIHJldHVybiB0aGlzLl9jcmVhdGVFdmVudChmdW5jLCB0aGlzLl9hYnNUaW1lKGRlbGF5KSlcbn1cblxuLy8gU2NoZWR1bGVzIGBmdW5jYCB0byBydW4gYmVmb3JlIGBkZWFkbGluZWAuXG5XQUFDbG9jay5wcm90b3R5cGUuY2FsbGJhY2tBdFRpbWUgPSBmdW5jdGlvbihmdW5jLCBkZWFkbGluZSkge1xuICByZXR1cm4gdGhpcy5fY3JlYXRlRXZlbnQoZnVuYywgZGVhZGxpbmUpXG59XG5cbi8vIFN0cmV0Y2hlcyBgZGVhZGxpbmVgIGFuZCBgcmVwZWF0YCBvZiBhbGwgc2NoZWR1bGVkIGBldmVudHNgIGJ5IGByYXRpb2AsIGtlZXBpbmdcbi8vIHRoZWlyIHJlbGF0aXZlIGRpc3RhbmNlIHRvIGB0UmVmYC4gSW4gZmFjdCB0aGlzIGlzIGVxdWl2YWxlbnQgdG8gY2hhbmdpbmcgdGhlIHRlbXBvLlxuV0FBQ2xvY2sucHJvdG90eXBlLnRpbWVTdHJldGNoID0gZnVuY3Rpb24odFJlZiwgZXZlbnRzLCByYXRpbykge1xuICBldmVudHMuZm9yRWFjaChmdW5jdGlvbihldmVudCkgeyBldmVudC50aW1lU3RyZXRjaCh0UmVmLCByYXRpbykgfSlcbiAgcmV0dXJuIGV2ZW50c1xufVxuXG4vLyBSZW1vdmVzIGFsbCBzY2hlZHVsZWQgZXZlbnRzIGFuZCBzdGFydHMgdGhlIGNsb2NrIFxuV0FBQ2xvY2sucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLl9zdGFydGVkID09PSBmYWxzZSkge1xuICAgIHZhciBzZWxmID0gdGhpc1xuICAgIHRoaXMuX3N0YXJ0ZWQgPSB0cnVlXG4gICAgdGhpcy5fZXZlbnRzID0gW11cblxuICAgIGlmICh0aGlzLnRpY2tNZXRob2QgPT09ICdTY3JpcHRQcm9jZXNzb3JOb2RlJykge1xuICAgICAgdmFyIGJ1ZmZlclNpemUgPSAyNTZcbiAgICAgIC8vIFdlIGhhdmUgdG8ga2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgbm9kZSB0byBhdm9pZCBnYXJiYWdlIGNvbGxlY3Rpb25cbiAgICAgIHRoaXMuX2Nsb2NrTm9kZSA9IHRoaXMuY29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IoYnVmZmVyU2l6ZSwgMSwgMSlcbiAgICAgIHRoaXMuX2Nsb2NrTm9kZS5jb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbilcbiAgICAgIHRoaXMuX2Nsb2NrTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbigpIHsgc2VsZi5fdGljaygpIH0pXG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0aGlzLnRpY2tNZXRob2QgPT09ICdtYW51YWwnKSBudWxsIC8vIF90aWNrIGlzIGNhbGxlZCBtYW51YWxseVxuXG4gICAgZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgdGlja01ldGhvZCAnICsgdGhpcy50aWNrTWV0aG9kKVxuICB9XG59XG5cbi8vIFN0b3BzIHRoZSBjbG9ja1xuV0FBQ2xvY2sucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuX3N0YXJ0ZWQgPT09IHRydWUpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2VcbiAgICB0aGlzLl9jbG9ja05vZGUuZGlzY29ubmVjdCgpXG4gIH0gIFxufVxuXG4vLyAtLS0tLS0tLS0tIFByaXZhdGUgLS0tLS0tLS0tLSAvL1xuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIHJhbiBwZXJpb2RpY2FsbHksIGFuZCBhdCBlYWNoIHRpY2sgaXQgZXhlY3V0ZXNcbi8vIGV2ZW50cyBmb3Igd2hpY2ggYGN1cnJlbnRUaW1lYCBpcyBpbmNsdWRlZCBpbiB0aGVpciB0b2xlcmFuY2UgaW50ZXJ2YWwuXG5XQUFDbG9jay5wcm90b3R5cGUuX3RpY2sgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGV2ZW50ID0gdGhpcy5fZXZlbnRzLnNoaWZ0KClcblxuICB3aGlsZShldmVudCAmJiBldmVudC5fZWFybGllc3RUaW1lIDw9IHRoaXMuY29udGV4dC5jdXJyZW50VGltZSkge1xuICAgIGV2ZW50Ll9leGVjdXRlKClcbiAgICBldmVudCA9IHRoaXMuX2V2ZW50cy5zaGlmdCgpXG4gIH1cblxuICAvLyBQdXQgYmFjayB0aGUgbGFzdCBldmVudFxuICBpZihldmVudCkgdGhpcy5fZXZlbnRzLnVuc2hpZnQoZXZlbnQpXG59XG5cbi8vIENyZWF0ZXMgYW4gZXZlbnQgYW5kIGluc2VydCBpdCB0byB0aGUgbGlzdFxuV0FBQ2xvY2sucHJvdG90eXBlLl9jcmVhdGVFdmVudCA9IGZ1bmN0aW9uKGZ1bmMsIGRlYWRsaW5lKSB7XG4gIHJldHVybiBuZXcgRXZlbnQodGhpcywgZGVhZGxpbmUsIGZ1bmMpXG59XG5cbi8vIEluc2VydHMgYW4gZXZlbnQgdG8gdGhlIGxpc3RcbldBQUNsb2NrLnByb3RvdHlwZS5faW5zZXJ0RXZlbnQgPSBmdW5jdGlvbihldmVudCkge1xuICB0aGlzLl9ldmVudHMuc3BsaWNlKHRoaXMuX2luZGV4QnlUaW1lKGV2ZW50Ll9lYXJsaWVzdFRpbWUpLCAwLCBldmVudClcbn1cblxuLy8gUmVtb3ZlcyBhbiBldmVudCBmcm9tIHRoZSBsaXN0XG5XQUFDbG9jay5wcm90b3R5cGUuX3JlbW92ZUV2ZW50ID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgdmFyIGluZCA9IHRoaXMuX2V2ZW50cy5pbmRleE9mKGV2ZW50KVxuICBpZiAoaW5kICE9PSAtMSkgdGhpcy5fZXZlbnRzLnNwbGljZShpbmQsIDEpXG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiBgZXZlbnRgIGlzIGluIHF1ZXVlLCBmYWxzZSBvdGhlcndpc2VcbldBQUNsb2NrLnByb3RvdHlwZS5faGFzRXZlbnQgPSBmdW5jdGlvbihldmVudCkge1xuIHJldHVybiB0aGlzLl9ldmVudHMuaW5kZXhPZihldmVudCkgIT09IC0xXG59XG5cbi8vIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBldmVudCB3aG9zZSBkZWFkbGluZSBpcyA+PSB0byBgZGVhZGxpbmVgXG5XQUFDbG9jay5wcm90b3R5cGUuX2luZGV4QnlUaW1lID0gZnVuY3Rpb24oZGVhZGxpbmUpIHtcbiAgLy8gcGVyZm9ybXMgYSBiaW5hcnkgc2VhcmNoXG4gIHZhciBsb3cgPSAwXG4gICAgLCBoaWdoID0gdGhpcy5fZXZlbnRzLmxlbmd0aFxuICAgICwgbWlkXG4gIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgbWlkID0gTWF0aC5mbG9vcigobG93ICsgaGlnaCkgLyAyKVxuICAgIGlmICh0aGlzLl9ldmVudHNbbWlkXS5fZWFybGllc3RUaW1lIDwgZGVhZGxpbmUpXG4gICAgICBsb3cgPSBtaWQgKyAxXG4gICAgZWxzZSBoaWdoID0gbWlkXG4gIH1cbiAgcmV0dXJuIGxvd1xufVxuXG4vLyBDb252ZXJ0cyBmcm9tIHJlbGF0aXZlIHRpbWUgdG8gYWJzb2x1dGUgdGltZVxuV0FBQ2xvY2sucHJvdG90eXBlLl9hYnNUaW1lID0gZnVuY3Rpb24ocmVsVGltZSkge1xuICByZXR1cm4gcmVsVGltZSArIHRoaXMuY29udGV4dC5jdXJyZW50VGltZVxufVxuXG4vLyBDb252ZXJ0cyBmcm9tIGFic29sdXRlIHRpbWUgdG8gcmVsYXRpdmUgdGltZSBcbldBQUNsb2NrLnByb3RvdHlwZS5fcmVsVGltZSA9IGZ1bmN0aW9uKGFic1RpbWUpIHtcbiAgcmV0dXJuIGFic1RpbWUgLSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWVcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vd2FhY2xvY2svbGliL1dBQUNsb2NrLmpzXG4vLyBtb2R1bGUgaWQgPSA0M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRPbmNlTGlzdGVuZXIgPSBub29wO1xuXG5wcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Byb2Nlc3MvYnJvd3Nlci5qc1xuLy8gbW9kdWxlIGlkID0gNDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBjbG9jayB9IGZyb20gJy4uL21haW4nO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJbnRlcnZhbCB7XG5cbiAgY29uc3RydWN0b3IocmF0ZSxmdW5jLG9uKSB7XG5cbiAgICB0aGlzLnJhdGUgPSByYXRlO1xuICAgIHRoaXMub24gPSBvbjtcbiAgICB0aGlzLmNsb2NrID0gY2xvY2soKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgICB0aGlzLnBhdHRlcm4gPSBbMV07XG4gICAgdGhpcy5pbmRleCA9IDA7XG5cbiAgICB0aGlzLmV2ZW50ID0gZnVuYyA/IGZ1bmMgOiBmdW5jdGlvbigpIHsgfTtcblxuICAgIGlmICh0aGlzLm9uKSB7XG4gICAgICB0aGlzLnN0YXJ0KCk7XG4gICAgfVxuXG4gIH1cblxuICBfZXZlbnQoZSkge1xuICAvLyAgaWYgKHRoaXMucGF0dGVyblt0aGlzLmluZGV4JXRoaXMucGF0dGVybi5sZW5ndGhdKSB7XG4gICAgICB0aGlzLmV2ZW50KGUpO1xuICAvLyAgfVxuICAgIHRoaXMuaW5kZXgrKztcbiAgfVxuXG4gIHN0b3AoKSB7XG4gICAgdGhpcy5vbiA9IGZhbHNlO1xuICAgIHRoaXMuaW50ZXJ2YWwuY2xlYXIoKTtcbiAgfVxuXG4gIHN0YXJ0KCkge1xuICAgIHRoaXMub24gPSB0cnVlO1xuICAgIHRoaXMuaW50ZXJ2YWwgPSB0aGlzLmNsb2NrLmNhbGxiYWNrQXRUaW1lKHRoaXMuX2V2ZW50LmJpbmQodGhpcyksIHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSkucmVwZWF0KHRoaXMucmF0ZS8xMDAwKS50b2xlcmFuY2Uoe2Vhcmx5OiAwLjEsIGxhdGU6MX0pO1xuICB9XG5cbiAgbXMobmV3cmF0ZSkge1xuICAgIGlmICh0aGlzLm9uKSB7XG4gICAgICB2YXIgcmF0aW8gPSBuZXdyYXRlL3RoaXMucmF0ZTtcbiAgICAgIHRoaXMucmF0ZSA9IG5ld3JhdGU7XG4gICAgICB0aGlzLmNsb2NrLnRpbWVTdHJldGNoKHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSwgW3RoaXMuaW50ZXJ2YWxdLCByYXRpbyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmF0ZSA9IG5ld3JhdGU7XG4gICAgfVxuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi90aW1lL2ludGVydmFsLmpzIl0sInNvdXJjZVJvb3QiOiIifQ== /***/ }), +/* 57 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(97), __esModule: true }; + +/***/ }), +/* 58 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(2).document && document.documentElement; + +/***/ }), +/* 59 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = !__webpack_require__(6) && !__webpack_require__(13)(function(){ + return Object.defineProperty(__webpack_require__(36)('div'), 'a', {get: function(){ return 7; }}).a != 7; +}); + +/***/ }), +/* 60 */ +/***/ (function(module, exports, __webpack_require__) { + +// fallback for non-array-like ES3 and non-enumerable old V8 strings +var cof = __webpack_require__(17); +module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){ + return cof(it) == 'String' ? it.split('') : Object(it); +}; + +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { + +// check on default Array iterator +var Iterators = __webpack_require__(14) + , ITERATOR = __webpack_require__(1)('iterator') + , ArrayProto = Array.prototype; + +module.exports = function(it){ + return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); +}; + +/***/ }), +/* 62 */ +/***/ (function(module, exports, __webpack_require__) { + +// call something on iterator step with safe closing on error +var anObject = __webpack_require__(4); +module.exports = function(iterator, fn, value, entries){ + try { + return entries ? fn(anObject(value)[0], value[1]) : fn(value); + // 7.4.6 IteratorClose(iterator, completion) + } catch(e){ + var ret = iterator['return']; + if(ret !== undefined)anObject(ret.call(iterator)); + throw e; + } +}; + +/***/ }), +/* 63 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var LIBRARY = __webpack_require__(25) + , $export = __webpack_require__(7) + , redefine = __webpack_require__(68) + , hide = __webpack_require__(9) + , has = __webpack_require__(8) + , Iterators = __webpack_require__(14) + , $iterCreate = __webpack_require__(110) + , setToStringTag = __webpack_require__(27) + , getPrototypeOf = __webpack_require__(119) + , ITERATOR = __webpack_require__(1)('iterator') + , BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next` + , FF_ITERATOR = '@@iterator' + , KEYS = 'keys' + , VALUES = 'values'; + +var returnThis = function(){ return this; }; + +module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){ + $iterCreate(Constructor, NAME, next); + var getMethod = function(kind){ + if(!BUGGY && kind in proto)return proto[kind]; + switch(kind){ + case KEYS: return function keys(){ return new Constructor(this, kind); }; + case VALUES: return function values(){ return new Constructor(this, kind); }; + } return function entries(){ return new Constructor(this, kind); }; + }; + var TAG = NAME + ' Iterator' + , DEF_VALUES = DEFAULT == VALUES + , VALUES_BUG = false + , proto = Base.prototype + , $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT] + , $default = $native || getMethod(DEFAULT) + , $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined + , $anyNative = NAME == 'Array' ? proto.entries || $native : $native + , methods, key, IteratorPrototype; + // Fix native + if($anyNative){ + IteratorPrototype = getPrototypeOf($anyNative.call(new Base)); + if(IteratorPrototype !== Object.prototype){ + // Set @@toStringTag to native iterators + setToStringTag(IteratorPrototype, TAG, true); + // fix for some old engines + if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis); + } + } + // fix Array#{values, @@iterator}.name in V8 / FF + if(DEF_VALUES && $native && $native.name !== VALUES){ + VALUES_BUG = true; + $default = function values(){ return $native.call(this); }; + } + // Define iterator + if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){ + hide(proto, ITERATOR, $default); + } + // Plug for library + Iterators[NAME] = $default; + Iterators[TAG] = returnThis; + if(DEFAULT){ + methods = { + values: DEF_VALUES ? $default : getMethod(VALUES), + keys: IS_SET ? $default : getMethod(KEYS), + entries: $entries + }; + if(FORCED)for(key in methods){ + if(!(key in proto))redefine(proto, key, methods[key]); + } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); + } + return methods; +}; + +/***/ }), +/* 64 */ +/***/ (function(module, exports, __webpack_require__) { + +var ITERATOR = __webpack_require__(1)('iterator') + , SAFE_CLOSING = false; + +try { + var riter = [7][ITERATOR](); + riter['return'] = function(){ SAFE_CLOSING = true; }; + Array.from(riter, function(){ throw 2; }); +} catch(e){ /* empty */ } + +module.exports = function(exec, skipClosing){ + if(!skipClosing && !SAFE_CLOSING)return false; + var safe = false; + try { + var arr = [7] + , iter = arr[ITERATOR](); + iter.next = function(){ return {done: safe = true}; }; + arr[ITERATOR] = function(){ return iter; }; + exec(arr); + } catch(e){ /* empty */ } + return safe; +}; + +/***/ }), +/* 65 */ +/***/ (function(module, exports, __webpack_require__) { + +// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) +var anObject = __webpack_require__(4) + , dPs = __webpack_require__(116) + , enumBugKeys = __webpack_require__(37) + , IE_PROTO = __webpack_require__(39)('IE_PROTO') + , Empty = function(){ /* empty */ } + , PROTOTYPE = 'prototype'; + +// Create object with fake `null` prototype: use iframe Object with cleared prototype +var createDict = function(){ + // Thrash, waste and sodomy: IE GC bug + var iframe = __webpack_require__(36)('iframe') + , i = enumBugKeys.length + , lt = '<' + , gt = '>' + , iframeDocument; + iframe.style.display = 'none'; + __webpack_require__(58).appendChild(iframe); + iframe.src = 'javascript:'; // eslint-disable-line no-script-url + // createDict = iframe.contentWindow.Object; + // html.removeChild(iframe); + iframeDocument = iframe.contentWindow.document; + iframeDocument.open(); + iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); + iframeDocument.close(); + createDict = iframeDocument.F; + while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]]; + return createDict(); +}; + +module.exports = Object.create || function create(O, Properties){ + var result; + if(O !== null){ + Empty[PROTOTYPE] = anObject(O); + result = new Empty; + Empty[PROTOTYPE] = null; + // add "__proto__" for Object.getPrototypeOf polyfill + result[IE_PROTO] = O; + } else result = createDict(); + return Properties === undefined ? result : dPs(result, Properties); +}; + + +/***/ }), +/* 66 */ +/***/ (function(module, exports, __webpack_require__) { + +// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O) +var $keys = __webpack_require__(67) + , hiddenKeys = __webpack_require__(37).concat('length', 'prototype'); + +exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O){ + return $keys(O, hiddenKeys); +}; + +/***/ }), +/* 67 */ +/***/ (function(module, exports, __webpack_require__) { + +var has = __webpack_require__(8) + , toIObject = __webpack_require__(10) + , arrayIndexOf = __webpack_require__(104)(false) + , IE_PROTO = __webpack_require__(39)('IE_PROTO'); + +module.exports = function(object, names){ + var O = toIObject(object) + , i = 0 + , result = [] + , key; + for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key); + // Don't enum bug & hidden keys + while(names.length > i)if(has(O, key = names[i++])){ + ~arrayIndexOf(result, key) || result.push(key); + } + return result; +}; + +/***/ }), +/* 68 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(9); + +/***/ }), +/* 69 */ +/***/ (function(module, exports, __webpack_require__) { + +var ctx = __webpack_require__(18) + , invoke = __webpack_require__(108) + , html = __webpack_require__(58) + , cel = __webpack_require__(36) + , global = __webpack_require__(2) + , process = global.process + , setTask = global.setImmediate + , clearTask = global.clearImmediate + , MessageChannel = global.MessageChannel + , counter = 0 + , queue = {} + , ONREADYSTATECHANGE = 'onreadystatechange' + , defer, channel, port; +var run = function(){ + var id = +this; + if(queue.hasOwnProperty(id)){ + var fn = queue[id]; + delete queue[id]; + fn(); + } +}; +var listener = function(event){ + run.call(event.data); +}; +// Node.js 0.9+ & IE10+ has setImmediate, otherwise: +if(!setTask || !clearTask){ + setTask = function setImmediate(fn){ + var args = [], i = 1; + while(arguments.length > i)args.push(arguments[i++]); + queue[++counter] = function(){ + invoke(typeof fn == 'function' ? fn : Function(fn), args); + }; + defer(counter); + return counter; + }; + clearTask = function clearImmediate(id){ + delete queue[id]; + }; + // Node.js 0.8- + if(__webpack_require__(17)(process) == 'process'){ + defer = function(id){ + process.nextTick(ctx(run, id, 1)); + }; + // Browsers with MessageChannel, includes WebWorkers + } else if(MessageChannel){ + channel = new MessageChannel; + port = channel.port2; + channel.port1.onmessage = listener; + defer = ctx(port.postMessage, port, 1); + // Browsers with postMessage, skip WebWorkers + // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' + } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){ + defer = function(id){ + global.postMessage(id + '', '*'); + }; + global.addEventListener('message', listener, false); + // IE8- + } else if(ONREADYSTATECHANGE in cel('script')){ + defer = function(id){ + html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){ + html.removeChild(this); + run.call(id); + }; + }; + // Rest old browsers + } else { + defer = function(id){ + setTimeout(ctx(run, id, 1), 0); + }; + } +} +module.exports = { + set: setTask, + clear: clearTask +}; + +/***/ }), +/* 70 */ +/***/ (function(module, exports) { + + + +/***/ }), +/* 71 */ +/***/ (function(module, exports) { + +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + + +/***/ }), +/* 72 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(process) { + +module.exports = Readable; + +/*<replacement>*/ +var processNextTick = __webpack_require__(49); +/*</replacement>*/ + +/*<replacement>*/ +var isArray = __webpack_require__(71); +/*</replacement>*/ + +/*<replacement>*/ +var Duplex; +/*</replacement>*/ + +Readable.ReadableState = ReadableState; + +/*<replacement>*/ +var EE = __webpack_require__(47).EventEmitter; + +var EElistenerCount = function (emitter, type) { + return emitter.listeners(type).length; +}; +/*</replacement>*/ + +/*<replacement>*/ +var Stream = __webpack_require__(74); +/*</replacement>*/ + +var Buffer = __webpack_require__(3).Buffer; +/*<replacement>*/ +var bufferShim = __webpack_require__(32); +/*</replacement>*/ + +/*<replacement>*/ +var util = __webpack_require__(22); +util.inherits = __webpack_require__(16); +/*</replacement>*/ + +/*<replacement>*/ +var debugUtil = __webpack_require__(158); +var debug = void 0; +if (debugUtil && debugUtil.debuglog) { + debug = debugUtil.debuglog('stream'); +} else { + debug = function () {}; +} +/*</replacement>*/ + +var BufferList = __webpack_require__(144); +var StringDecoder; + +util.inherits(Readable, Stream); + +var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; + +function prependListener(emitter, event, fn) { + // Sadly this is not cacheable as some libraries bundle their own + // event emitter implementation with them. + if (typeof emitter.prependListener === 'function') { + return emitter.prependListener(event, fn); + } else { + // This is a hack to make sure that our error handler is attached before any + // userland ones. NEVER DO THIS. This is here only because this code needs + // to continue to work with older versions of Node.js that do not include + // the prependListener() method. The goal is to eventually remove this hack. + if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; + } +} + +function ReadableState(options, stream) { + Duplex = Duplex || __webpack_require__(12); + + options = options || {}; + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + // A linked list is used to store data chunks instead of an array because the + // linked list can remove elements from the beginning faster than + // array.shift() + this.buffer = new BufferList(); + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + this.resumeScheduled = false; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) StringDecoder = __webpack_require__(48).StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } +} + +function Readable(options) { + Duplex = Duplex || __webpack_require__(12); + + if (!(this instanceof Readable)) return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + if (options && typeof options.read === 'function') this._read = options.read; + + Stream.call(this); +} + +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function (chunk, encoding) { + var state = this._readableState; + + if (!state.objectMode && typeof chunk === 'string') { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = bufferShim.from(chunk, encoding); + encoding = ''; + } + } + + return readableAddChunk(this, state, chunk, encoding, false); +}; + +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function (chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); +}; + +Readable.prototype.isPaused = function () { + return this._readableState.flowing === false; +}; + +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (chunk === null) { + state.reading = false; + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var _e = new Error('stream.unshift() after end event'); + stream.emit('error', _e); + } else { + var skipAdd; + if (state.decoder && !addToFront && !encoding) { + chunk = state.decoder.write(chunk); + skipAdd = !state.objectMode && chunk.length === 0; + } + + if (!addToFront) state.reading = false; + + // Don't add to the buffer if we've decoded to an empty string chunk and + // we're not in object mode + if (!skipAdd) { + // if we want the data now, just emit it. + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); + + if (state.needReadable) emitReadable(stream); + } + } + + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; + } + + return needMoreData(state); +} + +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); +} + +// backwards compatibility. +Readable.prototype.setEncoding = function (enc) { + if (!StringDecoder) StringDecoder = __webpack_require__(48).StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; +}; + +// Don't raise the hwm > 8MB +var MAX_HWM = 0x800000; +function computeNewHighWaterMark(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 to prevent increasing hwm excessively in + // tiny amounts + n--; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + n++; + } + return n; +} + +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function howMuchToRead(n, state) { + if (n <= 0 || state.length === 0 && state.ended) return 0; + if (state.objectMode) return 1; + if (n !== n) { + // Only flow one buffer at a time + if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; + } + // If we're asking for more than the current hwm, then raise the hwm. + if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); + if (n <= state.length) return n; + // Don't have enough + if (!state.ended) { + state.needReadable = true; + return 0; + } + return state.length; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function (n) { + debug('read', n); + n = parseInt(n, 10); + var state = this._readableState; + var nOrig = n; + + if (n !== 0) state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) endReadable(this); + return null; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } else if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (!state.reading) n = howMuchToRead(nOrig, state); + } + + var ret; + if (n > 0) ret = fromList(n, state);else ret = null; + + if (ret === null) { + state.needReadable = true; + n = 0; + } else { + state.length -= n; + } + + if (state.length === 0) { + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (!state.ended) state.needReadable = true; + + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended) endReadable(this); + } + + if (ret !== null) this.emit('data', ret); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + +function onEofChunk(stream, state) { + if (state.ended) return; + if (state.decoder) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); +} + +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); + } +} + +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); +} + +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + processNextTick(maybeReadMore_, stream, state); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break;else len = state.length; + } + state.readingMore = false; +} + +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function (n) { + this.emit('error', new Error('_read() is not implemented')); +}; + +Readable.prototype.pipe = function (dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + debug('onunpipe'); + if (readable === src) { + cleanup(); + } + } + + function onend() { + debug('onend'); + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + + var cleanedUp = false; + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', cleanup); + src.removeListener('data', ondata); + + cleanedUp = true; + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); + } + + // If the user pushes more data while we're writing to dest then we'll end up + // in ondata again. However, we only want to increase awaitDrain once because + // dest will only emit one 'drain' event for the multiple writes. + // => Introduce a guard on increasing awaitDrain. + var increasedAwaitDrain = false; + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + increasedAwaitDrain = false; + var ret = dest.write(chunk); + if (false === ret && !increasedAwaitDrain) { + // If the user unpiped during `dest.write()`, it is possible + // to get stuck in a permanently paused state if that write + // also returned false. + // => Check whether `dest` is still a piping destination. + if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { + debug('false write response, pause', src._readableState.awaitDrain); + src._readableState.awaitDrain++; + increasedAwaitDrain = true; + } + src.pause(); + } + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); + } + + // Make sure our error handler is attached before userland ones. + prependListener(dest, 'error', onerror); + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function () { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) state.awaitDrain--; + if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; +} + +Readable.prototype.unpipe = function (dest) { + var state = this._readableState; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) return this; + + if (!dest) dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) dest.emit('unpipe', this); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var i = 0; i < len; i++) { + dests[i].emit('unpipe', this); + }return this; + } + + // try to find the right one. + var index = indexOf(state.pipes, dest); + if (index === -1) return this; + + state.pipes.splice(index, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) state.pipes = state.pipes[0]; + + dest.emit('unpipe', this); + + return this; +}; + +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function (ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + if (ev === 'data') { + // Start flowing on next tick if stream isn't explicitly paused + if (this._readableState.flowing !== false) this.resume(); + } else if (ev === 'readable') { + var state = this._readableState; + if (!state.endEmitted && !state.readableListening) { + state.readableListening = state.needReadable = true; + state.emittedReadable = false; + if (!state.reading) { + processNextTick(nReadingNextTick, this); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +function nReadingNextTick(self) { + debug('readable nexttick read 0'); + self.read(0); +} + +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function () { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + resume(this, state); + } + return this; +}; + +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + processNextTick(resume_, stream, state); + } +} + +function resume_(stream, state) { + if (!state.reading) { + debug('resume read 0'); + stream.read(0); + } + + state.resumeScheduled = false; + state.awaitDrain = 0; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) stream.read(0); +} + +Readable.prototype.pause = function () { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + return this; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + while (state.flowing && stream.read() !== null) {} +} + +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function (stream) { + var state = this._readableState; + var paused = false; + + var self = this; + stream.on('end', function () { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) self.push(chunk); + } + + self.push(null); + }); + + stream.on('data', function (chunk) { + debug('wrapped data'); + if (state.decoder) chunk = state.decoder.write(chunk); + + // don't skip over falsy values in objectMode + if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; + + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (this[i] === undefined && typeof stream[i] === 'function') { + this[i] = function (method) { + return function () { + return stream[method].apply(stream, arguments); + }; + }(i); + } + } + + // proxy certain important events. + for (var n = 0; n < kProxyEvents.length; n++) { + stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n])); + } + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function (n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; +}; + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function fromList(n, state) { + // nothing buffered + if (state.length === 0) return null; + + var ret; + if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { + // read it all, truncate the list + if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); + state.buffer.clear(); + } else { + // read part of list + ret = fromListPartial(n, state.buffer, state.decoder); + } + + return ret; +} + +// Extracts only enough buffered data to satisfy the amount requested. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function fromListPartial(n, list, hasStrings) { + var ret; + if (n < list.head.data.length) { + // slice is the same for buffers and strings + ret = list.head.data.slice(0, n); + list.head.data = list.head.data.slice(n); + } else if (n === list.head.data.length) { + // first chunk is a perfect match + ret = list.shift(); + } else { + // result spans more than one buffer + ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); + } + return ret; +} + +// Copies a specified amount of characters from the list of buffered data +// chunks. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function copyFromBufferString(n, list) { + var p = list.head; + var c = 1; + var ret = p.data; + n -= ret.length; + while (p = p.next) { + var str = p.data; + var nb = n > str.length ? str.length : n; + if (nb === str.length) ret += str;else ret += str.slice(0, n); + n -= nb; + if (n === 0) { + if (nb === str.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = str.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; +} + +// Copies a specified amount of bytes from the list of buffered data chunks. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function copyFromBuffer(n, list) { + var ret = bufferShim.allocUnsafe(n); + var p = list.head; + var c = 1; + p.data.copy(ret); + n -= p.data.length; + while (p = p.next) { + var buf = p.data; + var nb = n > buf.length ? buf.length : n; + buf.copy(ret, ret.length - n, 0, nb); + n -= nb; + if (n === 0) { + if (nb === buf.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = buf.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); + + if (!state.endEmitted) { + state.ended = true; + processNextTick(endReadableNT, state, stream); + } +} + +function endReadableNT(state, stream) { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } +} + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +function indexOf(xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; +} +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(11))) + +/***/ }), +/* 73 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + + + +module.exports = Transform; + +var Duplex = __webpack_require__(12); + +/*<replacement>*/ +var util = __webpack_require__(22); +util.inherits = __webpack_require__(16); +/*</replacement>*/ + +util.inherits(Transform, Duplex); + +function TransformState(stream) { + this.afterTransform = function (er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; + this.writeencoding = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (data !== null && data !== undefined) stream.push(data); + + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + +function Transform(options) { + if (!(this instanceof Transform)) return new Transform(options); + + Duplex.call(this, options); + + this._transformState = new TransformState(this); + + var stream = this; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + if (options) { + if (typeof options.transform === 'function') this._transform = options.transform; + + if (typeof options.flush === 'function') this._flush = options.flush; + } + + // When the writable side finishes, then flush out anything remaining. + this.once('prefinish', function () { + if (typeof this._flush === 'function') this._flush(function (er, data) { + done(stream, er, data); + });else done(stream); + }); +} + +Transform.prototype.push = function (chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; + +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function (chunk, encoding, cb) { + throw new Error('_transform() is not implemented'); +}; + +Transform.prototype._write = function (chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); + } +}; + +// Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. +Transform.prototype._read = function (n) { + var ts = this._transformState; + + if (ts.writechunk !== null && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } +}; + +function done(stream, er, data) { + if (er) return stream.emit('error', er); + + if (data !== null && data !== undefined) stream.push(data); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var ts = stream._transformState; + + if (ws.length) throw new Error('Calling transform done when ws.length != 0'); + + if (ts.transforming) throw new Error('Calling transform done when still transforming'); + + return stream.push(null); +} + +/***/ }), +/* 74 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(47).EventEmitter; + + +/***/ }), +/* 75 */ +/***/ (function(module, exports, __webpack_require__) { + +var apply = Function.prototype.apply; + +// DOM APIs, for completeness + +exports.setTimeout = function() { + return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout); +}; +exports.setInterval = function() { + return new Timeout(apply.call(setInterval, window, arguments), clearInterval); +}; +exports.clearTimeout = +exports.clearInterval = function(timeout) { + if (timeout) { + timeout.close(); + } +}; + +function Timeout(id, clearFn) { + this._id = id; + this._clearFn = clearFn; +} +Timeout.prototype.unref = Timeout.prototype.ref = function() {}; +Timeout.prototype.close = function() { + this._clearFn.call(window, this._id); +}; + +// Does not start the time, just sets up the members needed. +exports.enroll = function(item, msecs) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = msecs; +}; + +exports.unenroll = function(item) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = -1; +}; + +exports._unrefActive = exports.active = function(item) { + clearTimeout(item._idleTimeoutId); + + var msecs = item._idleTimeout; + if (msecs >= 0) { + item._idleTimeoutId = setTimeout(function onTimeout() { + if (item._onTimeout) + item._onTimeout(); + }, msecs); + } +}; + +// setimmediate attaches itself to the global object +__webpack_require__(148); +exports.setImmediate = setImmediate; +exports.clearImmediate = clearImmediate; + + +/***/ }), /* 76 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var _slicedToArray2 = __webpack_require__(73); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = undefined; + +var _promise = __webpack_require__(88); + +var _promise2 = _interopRequireDefault(_promise); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var files = [ +// "gun_violence", +"mass_shootings_lite", "gun_violence_by_month"]; +var parse = __webpack_require__(137); + +var dataPromises = files.map(function (name) { + return fetch('./data/' + name + '.csv').then(function (rows) { + return rows.text(); + }).then(function (text) { + return new _promise2.default(function (resolve, reject) { + parse(text, {}, function (_, lines) { + return resolve(lines); + }); + }); + }).then(function (lines) { + // console.log(name, lines) + var h = lines.shift(); + return { + name: name, + h: h, + lines: lines.filter(function (s) { + return !!s; + }) + }; + }); +}); +var allPromises = _promise2.default.all(dataPromises).then(function (data) { + return data.reduce(function (a, b) { + // console.log(b) + a[b.name] = b; + return a; + }, {}); +}); +var load = function load() { + return allPromises; +}; + +exports.load = load; + +/***/ }), +/* 77 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var keys = {}; +var key_numbers = {}; +var letters = "zxcvbnmasdfghjklqwertyuiop"; +var numbers = "1234567890"; + +var callback = function callback() {}; + +letters.toUpperCase().split("").map(function (k, i) { + keys[k.charCodeAt(0)] = i; +}); + +numbers.split("").map(function (k, i) { + keys[k.charCodeAt(0)] = i + letters.length; + key_numbers[k.charCodeAt(0)] = true; +}); + +window.addEventListener("keydown", keydown, true); +function keydown(e) { + if (e.altKey || e.ctrlKey || e.metaKey) { + e.stopPropagation(); + return; + } + if (document.activeElement instanceof HTMLInputElement && e.keyCode in key_numbers) { + e.stopPropagation(); + return; + } + if (!(e.keyCode in keys)) return; + var index = keys[e.keyCode]; + if (e.shiftKey) index += letters.length; + index -= 7; + callback(index); +} + +function listen(fn) { + callback = fn; +} + +exports.default = { listen: listen }; + +/***/ }), +/* 78 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.note_values = exports.MidiWriter = undefined; + +var _slicedToArray2 = __webpack_require__(55); + +var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); + +exports.midi_init = midi_init; +exports.play_note = play_note; +exports.play_midi_note = play_midi_note; +exports.play_sequence = play_sequence; +exports.play_interval_sequence = play_interval_sequence; +exports.export_pattern_as_midi = export_pattern_as_midi; + +var _tone = __webpack_require__(24); + +var _tone2 = _interopRequireDefault(_tone); + +var _webmidi = __webpack_require__(155); + +var _webmidi2 = _interopRequireDefault(_webmidi); + +var _scales = __webpack_require__(53); + +var _scales2 = _interopRequireDefault(_scales); + +var _util = __webpack_require__(31); + +var _kalimba = __webpack_require__(52); + +var _kalimba2 = _interopRequireDefault(_kalimba); + +var _FileSaver = __webpack_require__(138); + +var _ui = __webpack_require__(54); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var midiDevice = void 0; +var sendPitchBend = false; + +var MidiWriter = exports.MidiWriter = __webpack_require__(140); + +var note_values = exports.note_values = [[8, '8 measures', 8 * 512], [4, '4 measures', 4 * 512], [2, '2 measures', 2 * 512], [1, 'whole note', 512], [1 / 2, 'half note', 256], [1 / 3, 'third note', [170, 170, 171]], [1 / 4, 'quarter note', 128], [1 / 5, 'fifth note', [51, 51, 51, 51, 52]], [1 / 6, 'sixth note', [85, 85, 86, 85, 85, 86]], [1 / 8, 'eighth note', 64], [1 / 10, 'tenth note', [25, 26, 26, 25, 26, 25, 26, 26, 25, 26]], [1 / 12, 'twelfth note', [21, 21, 22, 21, 21, 22, 21, 21, 22, 21, 21, 22]], [1 / 16, 'sixteenth note', 32], [1 / 32, 'thirtysecond note', 16]]; + +function midi_init() { + _webmidi2.default.enable(midi_ready); + function midi_ready(err) { + if (err) { + console.error('webmidi failed to initialize'); + return; + } + if (!_webmidi2.default.outputs.length) { + console.error('no MIDI output found'); + return; + } + console.log(_webmidi2.default.inputs); + console.log(_webmidi2.default.outputs); + if (_webmidi2.default.outputs.length > 1) { + var filtered = _webmidi2.default.outputs.filter(function (output) { + return output.name.match(/prodipe/i); + }); + if (filtered.length) { + // midiDevice = filtered[0] + } + } + // midiDevice = midiDevice || WebMidi.outputs[0] + // console.log(midiDevice.name) + } +} + +/* play a single note */ + +function play_note(index, duration) { + var channel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "all"; + var exporting = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + var rest = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; + var defer = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; + + // console.log(index) + var scale = _scales2.default.current(); + var freq = scale.index(index + Math.round(_ui.nx.offset.value), _ui.nx.octave.value); + var midi_note = (0, _util.ftom)(freq); + var cents = midi_note % 1; + if (cents > 0.5) { + midi_note += 1; + cents -= 1; + } + cents *= 2; + midi_note = Math.floor(midi_note); + if ((midiDevice || exporting) && midi_note > 127) return 0; + var note = _tone2.default.Frequency(Math.floor(midi_note), "midi").toNote(); + var defer_time = 30000 / _tone2.default.Transport.bpm.value * defer / 128; + console.log(defer, defer_time); + if (exporting) { + return note; + } + if (midiDevice) { + duration = duration || 60000 / _tone2.default.Transport.bpm.value; + if (!exporting) { + if (defer) { + setTimeout(function () { + play_midi_note(note, cents, channel, duration); + }, defer); + } else { + play_midi_note(note, cents, channel, duration); + } + } + } else if (defer) { + setTimeout(function () { + _kalimba2.default.play(freq); + }, defer_time); + } else { + _kalimba2.default.play(freq); + } + return note; +} + +function play_midi_note(note, cents, channel, duration) { + midiDevice.playNote(note, channel, { duration: duration }); + if (sendPitchBend) { + midiDevice.sendPitchBend(cents, channel); + } +} + +/* play the next note in sequence */ + +function play_sequence(i, bounds, diff, note_time) { + var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : "all"; + var exporting = arguments[5]; + var rows = bounds.rows, + min = bounds.min, + max = bounds.max; + + var count = rows.length * rows[0].length; + if (i >= count) i = 0; + var y = Math.floor(i / rows[0].length); + var x = i % rows[0].length; + // if (!x) console.log(y) + var n = rows[y][x]; + i += 1; + if (i >= count) i = 0; + var midi_note = play_note((0, _util.norm)(n, min, max) * _ui.nx.multiply.value, note_time, channel, exporting); + return [i, [midi_note]]; +} + +/* play the next row as an interval */ + +function play_interval_sequence(i, bounds, diff, note_time) { + var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : "all"; + var exporting = arguments[5]; + var rows = bounds.rows, + min = bounds.min, + max = bounds.max; + + var count = rows.length; + if (i >= count) i = 0; + var y = i % count; + var row = rows[y]; + if (!row) { + i = 0;return; + } + var row_min = Math.min.apply(Math, row); + // const row_max = Math.max.apply(Math, row) + var row_f0 = (0, _util.norm)(row_min, min, max); + var row_root = row_f0 * _ui.nx.multiply.value; + var notes = row.map(function (n) { + var note = row_root + (0, _util.norm)(n - row_min, diff.min, diff.max) * _ui.nx.interval.value; + play_note(note, note_time, channel, exporting); + }); + i += 1; + return [i, notes]; +} + +/* generate a 1-track midi file by calling the play function repeatedly */ + +function export_pattern_as_midi(datasetName, bounds, diff, tempo, timingIndex, play_fn) { + // const behavior = document.querySelector('#behavior').value + var rows = bounds.rows; + // let count = behavior === 'sequence' ? rows[0].length * rows.length : rows.length + + var count = rows[0].length; + var notes = void 0, + timings = void 0, + wait = void 0; + var note_time = void 0; + // let timing = note_values[timingIndex][2] + var midi_track = new MidiWriter.Track(); + midi_track.setTempo(tempo); + for (var i = 0, len = count; i < len; i++) { + // if (timing.length) { + // note_time = timing[i % timing.length] + // } else { + // note_time = timing + // } + // midi_track.addEvent(new MidiWriter.NoteEvent({ pitch: notes, duration: 't' + note_time })) + var _play_fn = play_fn(i, bounds, note_time, "all", true); + + var _play_fn2 = (0, _slicedToArray3.default)(_play_fn, 4); + + i = _play_fn2[0]; + notes = _play_fn2[1]; + timings = _play_fn2[2]; + wait = _play_fn2[3]; + console.log(i, notes, timings, wait); + for (var j = 0; j < notes.length; j++) { + midi_track.addEvent(new MidiWriter.NoteEvent({ + pitch: notes[j], + duration: 't' + timings[j], + wait: j === 0 ? wait : 0 + })); + } + } + var writer = new MidiWriter.Writer([midi_track]); + var blob = (0, _util.dataURItoBlob)(writer.dataUri()); + (0, _FileSaver.saveAs)(blob, 'Recording - ' + datasetName + '.mid'); +} + +/***/ }), +/* 79 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; + +var _from = __webpack_require__(83); + +var _from2 = _interopRequireDefault(_from); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = function (arr) { + return Array.isArray(arr) ? arr : (0, _from2.default)(arr); +}; + +/***/ }), +/* 80 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _slicedToArray2 = __webpack_require__(55); var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); -var _toArray2 = __webpack_require__(154); +var _toArray2 = __webpack_require__(79); var _toArray3 = _interopRequireDefault(_toArray2); -var _tone = __webpack_require__(21); +var _tone = __webpack_require__(24); var _tone2 = _interopRequireDefault(_tone); -var _nexusui = __webpack_require__(75); +var _nexusui = __webpack_require__(56); var _nexusui2 = _interopRequireDefault(_nexusui); -var _keys = __webpack_require__(71); +var _keys = __webpack_require__(77); var _keys2 = _interopRequireDefault(_keys); -var _scales = __webpack_require__(50); +var _scales = __webpack_require__(53); var _scales2 = _interopRequireDefault(_scales); -var _kalimba = __webpack_require__(78); +var _kalimba = __webpack_require__(52); var _kalimba2 = _interopRequireDefault(_kalimba); -var _midi = __webpack_require__(72); +var _midi = __webpack_require__(78); -var _util = __webpack_require__(30); +var _util = __webpack_require__(31); -var _ui = __webpack_require__(51); +var _ui = __webpack_require__(54); -var _data = __webpack_require__(70); +var _data = __webpack_require__(76); var data = _interopRequireWildcard(_data); @@ -40715,13 +40664,13 @@ function play_mass_shootings(i, bounds, diff, note_time) { timings = [64, 64]; break; case 3: - midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 43, channel, exporting, mass_rest)); + midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 43, channel, exporting, mass_rest, 0)); midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[1], min, max) * _ui.nx.multiply.value, 43, channel, exporting, 0, 43)); midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[2], min, max) * _ui.nx.multiply.value, 42, channel, exporting, 0, 85)); timings = [43, 43, 42]; break; case 4: - midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 32, channel, exporting, mass_rest)); + midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 32, channel, exporting, mass_rest, 0)); midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[1], min, max) * _ui.nx.multiply.value, 32, channel, exporting, 0, 32)); midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[2], min, max) * _ui.nx.multiply.value, 32, channel, exporting, 0, 64)); midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[3], min, max) * _ui.nx.multiply.value, 32, channel, exporting, 0, 96)); @@ -40894,13 +40843,13 @@ _keys2.default.listen(function (index) { }); /***/ }), -/* 77 */ +/* 81 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var _assign = __webpack_require__(52); +var _assign = __webpack_require__(57); var _assign2 = _interopRequireDefault(_assign); @@ -41070,75 +41019,13 @@ module.exports = function () { }(); /***/ }), -/* 78 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _tone = __webpack_require__(21); - -var _tone2 = _interopRequireDefault(_tone); - -var _util = __webpack_require__(30); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var player_count = 2; -var sample_index = 0; - -var compressor = new _tone2.default.Compressor(-30, 3).toMaster(); - -var samples = [{ root: 226, fn: 'samples/380737__cabled-mess__sansula-01-a-raw.mp3' }, { root: 267, fn: 'samples/380736__cabled-mess__sansula-02-c-raw.mp3' }, { root: 340, fn: 'samples/380735__cabled-mess__sansula-03-e-raw.mp3' }, { root: 452, fn: 'samples/380733__cabled-mess__sansula-06-a-02-raw.mp3' }]; - -samples.forEach(function (sample) { - sample.players = []; - sample.index = -1; - for (var i = 0; i < player_count; i++) { - var fn = sample.fn; - if (window.location.href.match(/asdf.us/)) { - fn = '//asdf.us/kalimba/' + fn; - } - var player = new _tone2.default.Player({ - url: fn, - retrigger: true, - playbackRate: 1 - }); - player.connect(compressor); - sample.players.push(player); - } -}); - -function play(freq) { - var volume = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.0; - - var best = { sample: samples[sample_index] }; - sample_index = (sample_index + 1) % samples.length; - best.sample.index = (best.sample.index + 1) % player_count; - - var player = best.sample.players[best.sample.index]; - player.playbackRate = freq / best.sample.root; - // console.log(player) - player.volume.value = volume; - setTimeout(function () { - player.start(); - }, 0); -} - -exports.default = { play: play }; - -/***/ }), -/* 79 */ +/* 82 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; -var _typeof2 = __webpack_require__(87); +var _typeof2 = __webpack_require__(91); var _typeof3 = _interopRequireDefault(_typeof2); @@ -41327,49 +41214,55 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de }); /***/ }), -/* 80 */ +/* 83 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = { "default": __webpack_require__(89), __esModule: true }; +module.exports = { "default": __webpack_require__(93), __esModule: true }; /***/ }), -/* 81 */ +/* 84 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = { "default": __webpack_require__(90), __esModule: true }; +module.exports = { "default": __webpack_require__(94), __esModule: true }; /***/ }), -/* 82 */ +/* 85 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = { "default": __webpack_require__(91), __esModule: true }; +module.exports = { "default": __webpack_require__(95), __esModule: true }; /***/ }), -/* 83 */ +/* 86 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = { "default": __webpack_require__(93), __esModule: true }; +module.exports = { "default": __webpack_require__(96), __esModule: true }; /***/ }), -/* 84 */ +/* 87 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = { "default": __webpack_require__(94), __esModule: true }; +module.exports = { "default": __webpack_require__(98), __esModule: true }; /***/ }), -/* 85 */ +/* 88 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = { "default": __webpack_require__(95), __esModule: true }; +module.exports = { "default": __webpack_require__(99), __esModule: true }; /***/ }), -/* 86 */ +/* 89 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = { "default": __webpack_require__(96), __esModule: true }; +module.exports = { "default": __webpack_require__(100), __esModule: true }; /***/ }), -/* 87 */ +/* 90 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(101), __esModule: true }; + +/***/ }), +/* 91 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41377,11 +41270,11 @@ module.exports = { "default": __webpack_require__(96), __esModule: true }; exports.__esModule = true; -var _iterator = __webpack_require__(86); +var _iterator = __webpack_require__(90); var _iterator2 = _interopRequireDefault(_iterator); -var _symbol = __webpack_require__(85); +var _symbol = __webpack_require__(89); var _symbol2 = _interopRequireDefault(_symbol); @@ -41396,7 +41289,7 @@ exports.default = typeof _symbol2.default === "function" && _typeof(_iterator2.d }; /***/ }), -/* 88 */ +/* 92 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41517,78 +41410,86 @@ function fromByteArray (uint8) { /***/ }), -/* 89 */ +/* 93 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(29); -__webpack_require__(28); -module.exports = __webpack_require__(123); +__webpack_require__(21); +__webpack_require__(128); +module.exports = __webpack_require__(0).Array.from; /***/ }), -/* 90 */ +/* 94 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(29); -__webpack_require__(28); -module.exports = __webpack_require__(124); +__webpack_require__(30); +__webpack_require__(21); +module.exports = __webpack_require__(126); /***/ }), -/* 91 */ +/* 95 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(126); -module.exports = __webpack_require__(1).Math.log2; +__webpack_require__(30); +__webpack_require__(21); +module.exports = __webpack_require__(127); /***/ }), -/* 92 */ +/* 96 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(127); -module.exports = __webpack_require__(1).Object.assign; +__webpack_require__(130); +module.exports = __webpack_require__(0).Math.log2; /***/ }), -/* 93 */ +/* 97 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(128); -module.exports = __webpack_require__(1).Object.keys; +__webpack_require__(131); +module.exports = __webpack_require__(0).Object.assign; /***/ }), -/* 94 */ +/* 98 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(64); -__webpack_require__(28); -__webpack_require__(29); -__webpack_require__(129); -module.exports = __webpack_require__(1).Promise; +__webpack_require__(132); +module.exports = __webpack_require__(0).Object.keys; /***/ }), -/* 95 */ +/* 99 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(130); -__webpack_require__(64); -__webpack_require__(131); -__webpack_require__(132); -module.exports = __webpack_require__(1).Symbol; +__webpack_require__(70); +__webpack_require__(21); +__webpack_require__(30); +__webpack_require__(133); +module.exports = __webpack_require__(0).Promise; /***/ }), -/* 96 */ +/* 100 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(28); -__webpack_require__(29); -module.exports = __webpack_require__(44).f('iterator'); +__webpack_require__(134); +__webpack_require__(70); +__webpack_require__(135); +__webpack_require__(136); +module.exports = __webpack_require__(0).Symbol; /***/ }), -/* 97 */ +/* 101 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(21); +__webpack_require__(30); +module.exports = __webpack_require__(45).f('iterator'); + +/***/ }), +/* 102 */ /***/ (function(module, exports) { module.exports = function(){ /* empty */ }; /***/ }), -/* 98 */ +/* 103 */ /***/ (function(module, exports) { module.exports = function(it, Constructor, name, forbiddenField){ @@ -41598,14 +41499,14 @@ module.exports = function(it, Constructor, name, forbiddenField){ }; /***/ }), -/* 99 */ +/* 104 */ /***/ (function(module, exports, __webpack_require__) { // false -> Array#indexOf // true -> Array#includes -var toIObject = __webpack_require__(9) - , toLength = __webpack_require__(62) - , toIndex = __webpack_require__(122); +var toIObject = __webpack_require__(10) + , toLength = __webpack_require__(42) + , toIndex = __webpack_require__(125); module.exports = function(IS_INCLUDES){ return function($this, el, fromIndex){ var O = toIObject($this) @@ -41624,13 +41525,27 @@ module.exports = function(IS_INCLUDES){ }; /***/ }), -/* 100 */ +/* 105 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $defineProperty = __webpack_require__(5) + , createDesc = __webpack_require__(20); + +module.exports = function(object, index, value){ + if(index in object)$defineProperty.f(object, index, createDesc(0, value)); + else object[index] = value; +}; + +/***/ }), +/* 106 */ /***/ (function(module, exports, __webpack_require__) { // all enumerable object keys, includes symbols var getKeys = __webpack_require__(15) - , gOPS = __webpack_require__(37) - , pIE = __webpack_require__(24); + , gOPS = __webpack_require__(38) + , pIE = __webpack_require__(26); module.exports = function(it){ var result = getKeys(it) , getSymbols = gOPS.f; @@ -41644,15 +41559,15 @@ module.exports = function(it){ }; /***/ }), -/* 101 */ +/* 107 */ /***/ (function(module, exports, __webpack_require__) { -var ctx = __webpack_require__(22) - , call = __webpack_require__(105) - , isArrayIter = __webpack_require__(103) +var ctx = __webpack_require__(18) + , call = __webpack_require__(62) + , isArrayIter = __webpack_require__(61) , anObject = __webpack_require__(4) - , toLength = __webpack_require__(62) - , getIterFn = __webpack_require__(63) + , toLength = __webpack_require__(42) + , getIterFn = __webpack_require__(46) , BREAK = {} , RETURN = {}; var exports = module.exports = function(iterable, entries, fn, that, ITERATOR){ @@ -41674,7 +41589,7 @@ exports.BREAK = BREAK; exports.RETURN = RETURN; /***/ }), -/* 102 */ +/* 108 */ /***/ (function(module, exports) { // fast apply, http://jsperf.lnkit.com/fast-apply/5 @@ -41695,20 +41610,7 @@ module.exports = function(fn, args, that){ }; /***/ }), -/* 103 */ -/***/ (function(module, exports, __webpack_require__) { - -// check on default Array iterator -var Iterators = __webpack_require__(14) - , ITERATOR = __webpack_require__(0)('iterator') - , ArrayProto = Array.prototype; - -module.exports = function(it){ - return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); -}; - -/***/ }), -/* 104 */ +/* 109 */ /***/ (function(module, exports, __webpack_require__) { // 7.2.2 IsArray(argument) @@ -41718,35 +41620,18 @@ module.exports = Array.isArray || function isArray(arg){ }; /***/ }), -/* 105 */ -/***/ (function(module, exports, __webpack_require__) { - -// call something on iterator step with safe closing on error -var anObject = __webpack_require__(4); -module.exports = function(iterator, fn, value, entries){ - try { - return entries ? fn(anObject(value)[0], value[1]) : fn(value); - // 7.4.6 IteratorClose(iterator, completion) - } catch(e){ - var ret = iterator['return']; - if(ret !== undefined)anObject(ret.call(iterator)); - throw e; - } -}; - -/***/ }), -/* 106 */ +/* 110 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var create = __webpack_require__(57) - , descriptor = __webpack_require__(25) - , setToStringTag = __webpack_require__(26) +var create = __webpack_require__(65) + , descriptor = __webpack_require__(20) + , setToStringTag = __webpack_require__(27) , IteratorPrototype = {}; // 25.1.2.1.1 %IteratorPrototype%[@@iterator]() -__webpack_require__(7)(IteratorPrototype, __webpack_require__(0)('iterator'), function(){ return this; }); +__webpack_require__(9)(IteratorPrototype, __webpack_require__(1)('iterator'), function(){ return this; }); module.exports = function(Constructor, NAME, next){ Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)}); @@ -41754,33 +41639,7 @@ module.exports = function(Constructor, NAME, next){ }; /***/ }), -/* 107 */ -/***/ (function(module, exports, __webpack_require__) { - -var ITERATOR = __webpack_require__(0)('iterator') - , SAFE_CLOSING = false; - -try { - var riter = [7][ITERATOR](); - riter['return'] = function(){ SAFE_CLOSING = true; }; - Array.from(riter, function(){ throw 2; }); -} catch(e){ /* empty */ } - -module.exports = function(exec, skipClosing){ - if(!skipClosing && !SAFE_CLOSING)return false; - var safe = false; - try { - var arr = [7] - , iter = arr[ITERATOR](); - iter.next = function(){ return {done: safe = true}; }; - arr[ITERATOR] = function(){ return iter; }; - exec(arr); - } catch(e){ /* empty */ } - return safe; -}; - -/***/ }), -/* 108 */ +/* 111 */ /***/ (function(module, exports) { module.exports = function(done, value){ @@ -41788,11 +41647,11 @@ module.exports = function(done, value){ }; /***/ }), -/* 109 */ +/* 112 */ /***/ (function(module, exports, __webpack_require__) { var getKeys = __webpack_require__(15) - , toIObject = __webpack_require__(9); + , toIObject = __webpack_require__(10); module.exports = function(object, el){ var O = toIObject(object) , keys = getKeys(O) @@ -41803,13 +41662,13 @@ module.exports = function(object, el){ }; /***/ }), -/* 110 */ +/* 113 */ /***/ (function(module, exports, __webpack_require__) { -var META = __webpack_require__(27)('meta') - , isObject = __webpack_require__(18) - , has = __webpack_require__(6) - , setDesc = __webpack_require__(8).f +var META = __webpack_require__(29)('meta') + , isObject = __webpack_require__(19) + , has = __webpack_require__(8) + , setDesc = __webpack_require__(5).f , id = 0; var isExtensible = Object.isExtensible || function(){ return true; @@ -41861,11 +41720,11 @@ var meta = module.exports = { }; /***/ }), -/* 111 */ +/* 114 */ /***/ (function(module, exports, __webpack_require__) { var global = __webpack_require__(2) - , macrotask = __webpack_require__(61).set + , macrotask = __webpack_require__(69).set , Observer = global.MutationObserver || global.WebKitMutationObserver , process = global.process , Promise = global.Promise @@ -41934,17 +41793,17 @@ module.exports = function(){ }; /***/ }), -/* 112 */ +/* 115 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // 19.1.2.1 Object.assign(target, source, ...) var getKeys = __webpack_require__(15) - , gOPS = __webpack_require__(37) - , pIE = __webpack_require__(24) - , toObject = __webpack_require__(41) - , IObject = __webpack_require__(55) + , gOPS = __webpack_require__(38) + , pIE = __webpack_require__(26) + , toObject = __webpack_require__(28) + , IObject = __webpack_require__(60) , $assign = Object.assign; // should work with symbols and should have deterministic property order (V8 bug) @@ -41973,14 +41832,14 @@ module.exports = !$assign || __webpack_require__(13)(function(){ } : $assign; /***/ }), -/* 113 */ +/* 116 */ /***/ (function(module, exports, __webpack_require__) { -var dP = __webpack_require__(8) +var dP = __webpack_require__(5) , anObject = __webpack_require__(4) , getKeys = __webpack_require__(15); -module.exports = __webpack_require__(5) ? Object.defineProperties : function defineProperties(O, Properties){ +module.exports = __webpack_require__(6) ? Object.defineProperties : function defineProperties(O, Properties){ anObject(O); var keys = getKeys(Properties) , length = keys.length @@ -41991,18 +41850,18 @@ module.exports = __webpack_require__(5) ? Object.defineProperties : function def }; /***/ }), -/* 114 */ +/* 117 */ /***/ (function(module, exports, __webpack_require__) { -var pIE = __webpack_require__(24) - , createDesc = __webpack_require__(25) - , toIObject = __webpack_require__(9) - , toPrimitive = __webpack_require__(42) - , has = __webpack_require__(6) - , IE8_DOM_DEFINE = __webpack_require__(54) +var pIE = __webpack_require__(26) + , createDesc = __webpack_require__(20) + , toIObject = __webpack_require__(10) + , toPrimitive = __webpack_require__(43) + , has = __webpack_require__(8) + , IE8_DOM_DEFINE = __webpack_require__(59) , gOPD = Object.getOwnPropertyDescriptor; -exports.f = __webpack_require__(5) ? gOPD : function getOwnPropertyDescriptor(O, P){ +exports.f = __webpack_require__(6) ? gOPD : function getOwnPropertyDescriptor(O, P){ O = toIObject(O); P = toPrimitive(P, true); if(IE8_DOM_DEFINE)try { @@ -42012,12 +41871,12 @@ exports.f = __webpack_require__(5) ? gOPD : function getOwnPropertyDescriptor(O, }; /***/ }), -/* 115 */ +/* 118 */ /***/ (function(module, exports, __webpack_require__) { // fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window -var toIObject = __webpack_require__(9) - , gOPN = __webpack_require__(58).f +var toIObject = __webpack_require__(10) + , gOPN = __webpack_require__(66).f , toString = {}.toString; var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames @@ -42037,13 +41896,13 @@ module.exports.f = function getOwnPropertyNames(it){ /***/ }), -/* 116 */ +/* 119 */ /***/ (function(module, exports, __webpack_require__) { // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) -var has = __webpack_require__(6) - , toObject = __webpack_require__(41) - , IE_PROTO = __webpack_require__(38)('IE_PROTO') +var has = __webpack_require__(8) + , toObject = __webpack_require__(28) + , IE_PROTO = __webpack_require__(39)('IE_PROTO') , ObjectProto = Object.prototype; module.exports = Object.getPrototypeOf || function(O){ @@ -42055,12 +41914,12 @@ module.exports = Object.getPrototypeOf || function(O){ }; /***/ }), -/* 117 */ +/* 120 */ /***/ (function(module, exports, __webpack_require__) { // most Object methods by ES6 should accept primitives -var $export = __webpack_require__(12) - , core = __webpack_require__(1) +var $export = __webpack_require__(7) + , core = __webpack_require__(0) , fails = __webpack_require__(13); module.exports = function(KEY, exec){ var fn = (core.Object || {})[KEY] || Object[KEY] @@ -42070,10 +41929,10 @@ module.exports = function(KEY, exec){ }; /***/ }), -/* 118 */ +/* 121 */ /***/ (function(module, exports, __webpack_require__) { -var hide = __webpack_require__(7); +var hide = __webpack_require__(9); module.exports = function(target, src, safe){ for(var key in src){ if(safe && target[key])target[key] = src[key]; @@ -42082,16 +41941,16 @@ module.exports = function(target, src, safe){ }; /***/ }), -/* 119 */ +/* 122 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var global = __webpack_require__(2) - , core = __webpack_require__(1) - , dP = __webpack_require__(8) - , DESCRIPTORS = __webpack_require__(5) - , SPECIES = __webpack_require__(0)('species'); + , core = __webpack_require__(0) + , dP = __webpack_require__(5) + , DESCRIPTORS = __webpack_require__(6) + , SPECIES = __webpack_require__(1)('species'); module.exports = function(KEY){ var C = typeof core[KEY] == 'function' ? core[KEY] : global[KEY]; @@ -42102,24 +41961,24 @@ module.exports = function(KEY){ }; /***/ }), -/* 120 */ +/* 123 */ /***/ (function(module, exports, __webpack_require__) { // 7.3.20 SpeciesConstructor(O, defaultConstructor) var anObject = __webpack_require__(4) - , aFunction = __webpack_require__(32) - , SPECIES = __webpack_require__(0)('species'); + , aFunction = __webpack_require__(33) + , SPECIES = __webpack_require__(1)('species'); module.exports = function(O, D){ var C = anObject(O).constructor, S; return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); }; /***/ }), -/* 121 */ +/* 124 */ /***/ (function(module, exports, __webpack_require__) { -var toInteger = __webpack_require__(40) - , defined = __webpack_require__(34); +var toInteger = __webpack_require__(41) + , defined = __webpack_require__(35); // true -> String#at // false -> String#codePointAt module.exports = function(TO_STRING){ @@ -42137,10 +41996,10 @@ module.exports = function(TO_STRING){ }; /***/ }), -/* 122 */ +/* 125 */ /***/ (function(module, exports, __webpack_require__) { -var toInteger = __webpack_require__(40) +var toInteger = __webpack_require__(41) , max = Math.max , min = Math.min; module.exports = function(index, length){ @@ -42149,25 +42008,25 @@ module.exports = function(index, length){ }; /***/ }), -/* 123 */ +/* 126 */ /***/ (function(module, exports, __webpack_require__) { var anObject = __webpack_require__(4) - , get = __webpack_require__(63); -module.exports = __webpack_require__(1).getIterator = function(it){ + , get = __webpack_require__(46); +module.exports = __webpack_require__(0).getIterator = function(it){ var iterFn = get(it); if(typeof iterFn != 'function')throw TypeError(it + ' is not iterable!'); return anObject(iterFn.call(it)); }; /***/ }), -/* 124 */ +/* 127 */ /***/ (function(module, exports, __webpack_require__) { -var classof = __webpack_require__(33) - , ITERATOR = __webpack_require__(0)('iterator') +var classof = __webpack_require__(34) + , ITERATOR = __webpack_require__(1)('iterator') , Iterators = __webpack_require__(14); -module.exports = __webpack_require__(1).isIterable = function(it){ +module.exports = __webpack_require__(0).isIterable = function(it){ var O = Object(it); return O[ITERATOR] !== undefined || '@@iterator' in O @@ -42175,21 +42034,65 @@ module.exports = __webpack_require__(1).isIterable = function(it){ }; /***/ }), -/* 125 */ +/* 128 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var addToUnscopables = __webpack_require__(97) - , step = __webpack_require__(108) +var ctx = __webpack_require__(18) + , $export = __webpack_require__(7) + , toObject = __webpack_require__(28) + , call = __webpack_require__(62) + , isArrayIter = __webpack_require__(61) + , toLength = __webpack_require__(42) + , createProperty = __webpack_require__(105) + , getIterFn = __webpack_require__(46); + +$export($export.S + $export.F * !__webpack_require__(64)(function(iter){ Array.from(iter); }), 'Array', { + // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined) + from: function from(arrayLike/*, mapfn = undefined, thisArg = undefined*/){ + var O = toObject(arrayLike) + , C = typeof this == 'function' ? this : Array + , aLen = arguments.length + , mapfn = aLen > 1 ? arguments[1] : undefined + , mapping = mapfn !== undefined + , index = 0 + , iterFn = getIterFn(O) + , length, result, step, iterator; + if(mapping)mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2); + // if object isn't iterable or it's array with default iterator - use simple case + if(iterFn != undefined && !(C == Array && isArrayIter(iterFn))){ + for(iterator = iterFn.call(O), result = new C; !(step = iterator.next()).done; index++){ + createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value); + } + } else { + length = toLength(O.length); + for(result = new C(length); length > index; index++){ + createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]); + } + } + result.length = index; + return result; + } +}); + + +/***/ }), +/* 129 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var addToUnscopables = __webpack_require__(102) + , step = __webpack_require__(111) , Iterators = __webpack_require__(14) - , toIObject = __webpack_require__(9); + , toIObject = __webpack_require__(10); // 22.1.3.4 Array.prototype.entries() // 22.1.3.13 Array.prototype.keys() // 22.1.3.29 Array.prototype.values() // 22.1.3.30 Array.prototype[@@iterator]() -module.exports = __webpack_require__(56)(Array, 'Array', function(iterated, kind){ +module.exports = __webpack_require__(63)(Array, 'Array', function(iterated, kind){ this._t = toIObject(iterated); // target this._i = 0; // next index this._k = kind; // kind @@ -42215,11 +42118,11 @@ addToUnscopables('values'); addToUnscopables('entries'); /***/ }), -/* 126 */ +/* 130 */ /***/ (function(module, exports, __webpack_require__) { // 20.2.2.22 Math.log2(x) -var $export = __webpack_require__(12); +var $export = __webpack_require__(7); $export($export.S, 'Math', { log2: function log2(x){ @@ -42228,46 +42131,46 @@ $export($export.S, 'Math', { }); /***/ }), -/* 127 */ +/* 131 */ /***/ (function(module, exports, __webpack_require__) { // 19.1.3.1 Object.assign(target, source) -var $export = __webpack_require__(12); +var $export = __webpack_require__(7); -$export($export.S + $export.F, 'Object', {assign: __webpack_require__(112)}); +$export($export.S + $export.F, 'Object', {assign: __webpack_require__(115)}); /***/ }), -/* 128 */ +/* 132 */ /***/ (function(module, exports, __webpack_require__) { // 19.1.2.14 Object.keys(O) -var toObject = __webpack_require__(41) +var toObject = __webpack_require__(28) , $keys = __webpack_require__(15); -__webpack_require__(117)('keys', function(){ +__webpack_require__(120)('keys', function(){ return function keys(it){ return $keys(toObject(it)); }; }); /***/ }), -/* 129 */ +/* 133 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var LIBRARY = __webpack_require__(23) +var LIBRARY = __webpack_require__(25) , global = __webpack_require__(2) - , ctx = __webpack_require__(22) - , classof = __webpack_require__(33) - , $export = __webpack_require__(12) - , isObject = __webpack_require__(18) - , aFunction = __webpack_require__(32) - , anInstance = __webpack_require__(98) - , forOf = __webpack_require__(101) - , speciesConstructor = __webpack_require__(120) - , task = __webpack_require__(61).set - , microtask = __webpack_require__(111)() + , ctx = __webpack_require__(18) + , classof = __webpack_require__(34) + , $export = __webpack_require__(7) + , isObject = __webpack_require__(19) + , aFunction = __webpack_require__(33) + , anInstance = __webpack_require__(103) + , forOf = __webpack_require__(107) + , speciesConstructor = __webpack_require__(123) + , task = __webpack_require__(69).set + , microtask = __webpack_require__(114)() , PROMISE = 'Promise' , TypeError = global.TypeError , process = global.process @@ -42281,7 +42184,7 @@ var USE_NATIVE = !!function(){ try { // correct subclassing with @@species support var promise = $Promise.resolve(1) - , FakePromise = (promise.constructor = {})[__webpack_require__(0)('species')] = function(exec){ exec(empty, empty); }; + , FakePromise = (promise.constructor = {})[__webpack_require__(1)('species')] = function(exec){ exec(empty, empty); }; // unhandled rejections tracking support, NodeJS Promise without it fails @@species test return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise; } catch(e){ /* empty */ } @@ -42459,7 +42362,7 @@ if(!USE_NATIVE){ this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled this._n = false; // <- notify }; - Internal.prototype = __webpack_require__(118)($Promise.prototype, { + Internal.prototype = __webpack_require__(121)($Promise.prototype, { // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) then: function then(onFulfilled, onRejected){ var reaction = newPromiseCapability(speciesConstructor(this, $Promise)); @@ -42485,9 +42388,9 @@ if(!USE_NATIVE){ } $export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: $Promise}); -__webpack_require__(26)($Promise, PROMISE); -__webpack_require__(119)(PROMISE); -Wrapper = __webpack_require__(1)[PROMISE]; +__webpack_require__(27)($Promise, PROMISE); +__webpack_require__(122)(PROMISE); +Wrapper = __webpack_require__(0)[PROMISE]; // statics $export($export.S + $export.F * !USE_NATIVE, PROMISE, { @@ -42510,7 +42413,7 @@ $export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, { return capability.promise; } }); -$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(107)(function(iter){ +$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(64)(function(iter){ $Promise.all(iter)['catch'](empty); })), PROMISE, { // 25.4.4.1 Promise.all(iterable) @@ -42556,36 +42459,36 @@ $export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(107)(functio }); /***/ }), -/* 130 */ +/* 134 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // ECMAScript 6 symbols shim var global = __webpack_require__(2) - , has = __webpack_require__(6) - , DESCRIPTORS = __webpack_require__(5) - , $export = __webpack_require__(12) - , redefine = __webpack_require__(60) - , META = __webpack_require__(110).KEY + , has = __webpack_require__(8) + , DESCRIPTORS = __webpack_require__(6) + , $export = __webpack_require__(7) + , redefine = __webpack_require__(68) + , META = __webpack_require__(113).KEY , $fails = __webpack_require__(13) - , shared = __webpack_require__(39) - , setToStringTag = __webpack_require__(26) - , uid = __webpack_require__(27) - , wks = __webpack_require__(0) - , wksExt = __webpack_require__(44) - , wksDefine = __webpack_require__(43) - , keyOf = __webpack_require__(109) - , enumKeys = __webpack_require__(100) - , isArray = __webpack_require__(104) + , shared = __webpack_require__(40) + , setToStringTag = __webpack_require__(27) + , uid = __webpack_require__(29) + , wks = __webpack_require__(1) + , wksExt = __webpack_require__(45) + , wksDefine = __webpack_require__(44) + , keyOf = __webpack_require__(112) + , enumKeys = __webpack_require__(106) + , isArray = __webpack_require__(109) , anObject = __webpack_require__(4) - , toIObject = __webpack_require__(9) - , toPrimitive = __webpack_require__(42) - , createDesc = __webpack_require__(25) - , _create = __webpack_require__(57) - , gOPNExt = __webpack_require__(115) - , $GOPD = __webpack_require__(114) - , $DP = __webpack_require__(8) + , toIObject = __webpack_require__(10) + , toPrimitive = __webpack_require__(43) + , createDesc = __webpack_require__(20) + , _create = __webpack_require__(65) + , gOPNExt = __webpack_require__(118) + , $GOPD = __webpack_require__(117) + , $DP = __webpack_require__(5) , $keys = __webpack_require__(15) , gOPD = $GOPD.f , dP = $DP.f @@ -42709,11 +42612,11 @@ if(!USE_NATIVE){ $GOPD.f = $getOwnPropertyDescriptor; $DP.f = $defineProperty; - __webpack_require__(58).f = gOPNExt.f = $getOwnPropertyNames; - __webpack_require__(24).f = $propertyIsEnumerable; - __webpack_require__(37).f = $getOwnPropertySymbols; + __webpack_require__(66).f = gOPNExt.f = $getOwnPropertyNames; + __webpack_require__(26).f = $propertyIsEnumerable; + __webpack_require__(38).f = $getOwnPropertySymbols; - if(DESCRIPTORS && !__webpack_require__(23)){ + if(DESCRIPTORS && !__webpack_require__(25)){ redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true); } @@ -42788,7 +42691,7 @@ $JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function(){ }); // 19.4.3.4 Symbol.prototype[@@toPrimitive](hint) -$Symbol[PROTOTYPE][TO_PRIMITIVE] || __webpack_require__(7)($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf); +$Symbol[PROTOTYPE][TO_PRIMITIVE] || __webpack_require__(9)($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf); // 19.4.3.5 Symbol.prototype[@@toStringTag] setToStringTag($Symbol, 'Symbol'); // 20.2.1.9 Math[@@toStringTag] @@ -42797,19 +42700,19 @@ setToStringTag(Math, 'Math', true); setToStringTag(global.JSON, 'JSON', true); /***/ }), -/* 131 */ +/* 135 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(43)('asyncIterator'); +__webpack_require__(44)('asyncIterator'); /***/ }), -/* 132 */ +/* 136 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(43)('observable'); +__webpack_require__(44)('observable'); /***/ }), -/* 133 */ +/* 137 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(Buffer, process, setImmediate) {// Generated by CoffeeScript 2.3.1 @@ -42822,11 +42725,11 @@ __webpack_require__(43)('observable'); // [tests] for additional information. var Parser, StringDecoder, isObjLiteral, stream, util; -stream = __webpack_require__(144); +stream = __webpack_require__(149); -util = __webpack_require__(149); +util = __webpack_require__(154); -StringDecoder = __webpack_require__(46).StringDecoder; +StringDecoder = __webpack_require__(48).StringDecoder; // ## Usage @@ -43542,10 +43445,205 @@ isObjLiteral = function(_obj) { // [stream]: (http://nodejs.org/api/stream.html // [transform]: (http://nodejs.org/api/stream.html#stream_class_stream_transform_1) -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3).Buffer, __webpack_require__(10), __webpack_require__(69).setImmediate)) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3).Buffer, __webpack_require__(11), __webpack_require__(75).setImmediate)) /***/ }), -/* 134 */ +/* 138 */ +/***/ (function(module, exports, __webpack_require__) { + +var __WEBPACK_AMD_DEFINE_RESULT__;/* FileSaver.js + * A saveAs() FileSaver implementation. + * 1.3.2 + * 2016-06-16 18:25:19 + * + * By Eli Grey, http://eligrey.com + * License: MIT + * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md + */ + +/*global self */ +/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ + +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ + +var saveAs = saveAs || (function(view) { + "use strict"; + // IE <10 is explicitly unsupported + if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { + return; + } + var + doc = view.document + // only get URL when necessary in case Blob.js hasn't overridden it yet + , get_URL = function() { + return view.URL || view.webkitURL || view; + } + , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") + , can_use_save_link = "download" in save_link + , click = function(node) { + var event = new MouseEvent("click"); + node.dispatchEvent(event); + } + , is_safari = /constructor/i.test(view.HTMLElement) || view.safari + , is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent) + , throw_outside = function(ex) { + (view.setImmediate || view.setTimeout)(function() { + throw ex; + }, 0); + } + , force_saveable_type = "application/octet-stream" + // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to + , arbitrary_revoke_timeout = 1000 * 40 // in ms + , revoke = function(file) { + var revoker = function() { + if (typeof file === "string") { // file is an object URL + get_URL().revokeObjectURL(file); + } else { // file is a File + file.remove(); + } + }; + setTimeout(revoker, arbitrary_revoke_timeout); + } + , dispatch = function(filesaver, event_types, event) { + event_types = [].concat(event_types); + var i = event_types.length; + while (i--) { + var listener = filesaver["on" + event_types[i]]; + if (typeof listener === "function") { + try { + listener.call(filesaver, event || filesaver); + } catch (ex) { + throw_outside(ex); + } + } + } + } + , auto_bom = function(blob) { + // prepend BOM for UTF-8 XML and text/* types (including HTML) + // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF + if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { + return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type}); + } + return blob; + } + , FileSaver = function(blob, name, no_auto_bom) { + if (!no_auto_bom) { + blob = auto_bom(blob); + } + // First try a.download, then web filesystem, then object URLs + var + filesaver = this + , type = blob.type + , force = type === force_saveable_type + , object_url + , dispatch_all = function() { + dispatch(filesaver, "writestart progress write writeend".split(" ")); + } + // on any filesys errors revert to saving with object URLs + , fs_error = function() { + if ((is_chrome_ios || (force && is_safari)) && view.FileReader) { + // Safari doesn't allow downloading of blob urls + var reader = new FileReader(); + reader.onloadend = function() { + var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;'); + var popup = view.open(url, '_blank'); + if(!popup) view.location.href = url; + url=undefined; // release reference before dispatching + filesaver.readyState = filesaver.DONE; + dispatch_all(); + }; + reader.readAsDataURL(blob); + filesaver.readyState = filesaver.INIT; + return; + } + // don't create more object URLs than needed + if (!object_url) { + object_url = get_URL().createObjectURL(blob); + } + if (force) { + view.location.href = object_url; + } else { + var opened = view.open(object_url, "_blank"); + if (!opened) { + // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html + view.location.href = object_url; + } + } + filesaver.readyState = filesaver.DONE; + dispatch_all(); + revoke(object_url); + } + ; + filesaver.readyState = filesaver.INIT; + + if (can_use_save_link) { + object_url = get_URL().createObjectURL(blob); + setTimeout(function() { + save_link.href = object_url; + save_link.download = name; + click(save_link); + dispatch_all(); + revoke(object_url); + filesaver.readyState = filesaver.DONE; + }); + return; + } + + fs_error(); + } + , FS_proto = FileSaver.prototype + , saveAs = function(blob, name, no_auto_bom) { + return new FileSaver(blob, name || blob.name || "download", no_auto_bom); + } + ; + // IE 10+ (native saveAs) + if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { + return function(blob, name, no_auto_bom) { + name = name || blob.name || "download"; + + if (!no_auto_bom) { + blob = auto_bom(blob); + } + return navigator.msSaveOrOpenBlob(blob, name); + }; + } + + FS_proto.abort = function(){}; + FS_proto.readyState = FS_proto.INIT = 0; + FS_proto.WRITING = 1; + FS_proto.DONE = 2; + + FS_proto.error = + FS_proto.onwritestart = + FS_proto.onprogress = + FS_proto.onwrite = + FS_proto.onabort = + FS_proto.onerror = + FS_proto.onwriteend = + null; + + return saveAs; +}( + typeof self !== "undefined" && self + || typeof window !== "undefined" && window + || this.content +)); +// `self` is undefined in Firefox for Android content script context +// while `this` is nsIContentFrameMessageManager +// with an attribute `content` that corresponds to the window + +if (typeof module !== "undefined" && module.exports) { + module.exports.saveAs = saveAs; +} else if (("function" !== "undefined" && __webpack_require__(156) !== null) && (__webpack_require__(157) !== null)) { + !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { + return saveAs; + }.call(exports, __webpack_require__, exports, module), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); +} + + +/***/ }), +/* 139 */ /***/ (function(module, exports) { exports.read = function (buffer, offset, isLE, mLen, nBytes) { @@ -43635,7 +43733,7 @@ exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { /***/ }), -/* 135 */ +/* 140 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -43650,7 +43748,7 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _tonalMidi = __webpack_require__(145); +var _tonalMidi = __webpack_require__(150); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } @@ -44671,10 +44769,10 @@ var Writer = function () { exports.Writer = Writer; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbIkNodW5rIiwiZmllbGRzIiwidHlwZSIsImRhdGEiLCJzaXplIiwibGVuZ3RoIiwiQ29uc3RhbnRzIiwiVkVSU0lPTiIsIkhFQURFUl9DSFVOS19UWVBFIiwiSEVBREVSX0NIVU5LX0xFTkdUSCIsIkhFQURFUl9DSFVOS19GT1JNQVQwIiwiSEVBREVSX0NIVU5LX0ZPUk1BVDEiLCJIRUFERVJfQ0hVTktfRElWSVNJT04iLCJUUkFDS19DSFVOS19UWVBFIiwiTUVUQV9FVkVOVF9JRCIsIk1FVEFfVEVYVF9JRCIsIk1FVEFfQ09QWVJJR0hUX0lEIiwiTUVUQV9UUkFDS19OQU1FX0lEIiwiTUVUQV9JTlNUUlVNRU5UX05BTUVfSUQiLCJNRVRBX0xZUklDX0lEIiwiTUVUQV9NQVJLRVJfSUQiLCJNRVRBX0NVRV9QT0lOVCIsIk1FVEFfVEVNUE9fSUQiLCJNRVRBX1NNVFBFX09GRlNFVCIsIk1FVEFfVElNRV9TSUdOQVRVUkVfSUQiLCJNRVRBX0tFWV9TSUdOQVRVUkVfSUQiLCJNRVRBX0VORF9PRl9UUkFDS19JRCIsIkNPTlRST0xMRVJfQ0hBTkdFX1NUQVRVUyIsIlBST0dSQU1fQ0hBTkdFX1NUQVRVUyIsIkNvbnRyb2xsZXJDaGFuZ2VFdmVudCIsIlV0aWxzIiwibnVtYmVyVG9WYXJpYWJsZUxlbmd0aCIsImNvbmNhdCIsImNvbnRyb2xsZXJOdW1iZXIiLCJjb250cm9sbGVyVmFsdWUiLCJNZXRhRXZlbnQiLCJOb3RlRXZlbnQiLCJwaXRjaCIsInRvQXJyYXkiLCJ3YWl0IiwiZHVyYXRpb24iLCJzZXF1ZW50aWFsIiwidmVsb2NpdHkiLCJjaGFubmVsIiwicmVwZWF0IiwiY29udmVydFZlbG9jaXR5IiwiZ3JhY2UiLCJidWlsZERhdGEiLCJ0aWNrRHVyYXRpb24iLCJnZXRUaWNrRHVyYXRpb24iLCJyZXN0RHVyYXRpb24iLCJncmFjZUR1cmF0aW9uIiwiZm9yRWFjaCIsIm5vdGVFdmVudCIsIm5vdGVPbiIsIm5vdGVPZmYiLCJBcnJheSIsImlzQXJyYXkiLCJqIiwicCIsImkiLCJOb3RlT25FdmVudCIsImdldE5vdGVPblN0YXR1cyIsImdldFBpdGNoIiwiTm90ZU9mZkV2ZW50IiwiZ2V0Tm90ZU9mZlN0YXR1cyIsInF1YXJ0ZXJUaWNrcyIsIm51bWJlckZyb21CeXRlcyIsIk1hdGgiLCJyb3VuZCIsIm1hcCIsInZhbHVlIiwicmVkdWNlIiwiYSIsImIiLCJ0b1N0cmluZyIsInRvTG93ZXJDYXNlIiwiY2hhckF0IiwicGFyc2VJbnQiLCJzdWJzdHJpbmciLCJnZXREdXJhdGlvbk11bHRpcGxpZXIiLCJQcm9ncmFtQ2hhbmdlRXZlbnQiLCJpbnN0cnVtZW50IiwiVHJhY2siLCJldmVudHMiLCJldmVudCIsIm1hcEZ1bmN0aW9uIiwiZSIsInByb3BlcnRpZXMiLCJudW1iZXJUb0J5dGVzIiwicHVzaCIsImJwbSIsInRlbXBvIiwiYWRkRXZlbnQiLCJudW1lcmF0b3IiLCJkZW5vbWluYXRvciIsIm1pZGljbG9ja3NwZXJ0aWNrIiwibm90ZXNwZXJtaWRpY2xvY2siLCJfZGVub21pbmF0b3IiLCJsb2cyIiwic2YiLCJtaSIsIm1vZGUiLCJmaWZ0aHMiLCJfc2ZsZW4iLCJub3RlIiwidG9VcHBlckNhc2UiLCJmaWZ0aGluZGV4IiwiaW5kZXhPZiIsInRleHQiLCJzdHJpbmdCeXRlcyIsInN0cmluZ1RvQnl0ZXMiLCJseXJpYyIsInN0cmluZyIsInNwbGl0IiwiY2hhciIsImNoYXJDb2RlQXQiLCJuIiwiaXNOYU4iLCJwYXJzZUZsb2F0IiwiaXNGaW5pdGUiLCJ0aWNrcyIsImJ1ZmZlciIsImJMaXN0IiwicyIsImVuY29kZVVSSSIsImJ5dGVzIiwiaGV4Iiwic3RyaW5nUmVzdWx0IiwiYnl0ZSIsIm51bWJlciIsImJ5dGVzTmVlZGVkIiwiaGV4U3RyaW5nIiwiaGV4QXJyYXkiLCJtYXRjaCIsIml0ZW0iLCJ1bnNoaWZ0IiwiVmV4RmxvdyIsInZvaWNlIiwidHJhY2siLCJwaXRjaGVzIiwidGlja2FibGVzIiwidGlja2FibGUiLCJub3RlVHlwZSIsImtleXMiLCJrZXkiLCJjb252ZXJ0UGl0Y2giLCJjb252ZXJ0RHVyYXRpb24iLCJyZXBsYWNlIiwiaXNEb3R0ZWQiLCJXcml0ZXIiLCJ0cmFja3MiLCJ0cmFja1R5cGUiLCJudW1iZXJPZlRyYWNrcyIsImJ1aWxkIiwiZCIsIlVpbnQ4QXJyYXkiLCJidG9hIiwiU3RyaW5nIiwiZnJvbUNoYXJDb2RlIiwiYXBwbHkiLCJidWlsZEZpbGUiLCJCdWZmZXIiLCJiYXNlNjQiLCJwcm9jZXNzIiwic3Rkb3V0Iiwid3JpdGUiLCJmaWxlbmFtZSIsImZzIiwid3JpdGVGaWxlIiwiZXJyIiwiY29uc29sZSIsImxvZyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFza0JBOzs7O0FBdGtCQTs7Ozs7SUFLTUEsSyxHQUNMLGVBQVlDLE1BQVosRUFBb0I7QUFBQTs7QUFDbkIsTUFBS0MsSUFBTCxHQUFZRCxPQUFPQyxJQUFuQjtBQUNBLE1BQUtDLElBQUwsR0FBWUYsT0FBT0UsSUFBbkI7QUFDQSxNQUFLQyxJQUFMLEdBQVksQ0FBQyxDQUFELEVBQUksQ0FBSixFQUFPLENBQVAsRUFBVUgsT0FBT0UsSUFBUCxDQUFZRSxNQUF0QixDQUFaO0FBQ0EsQzs7UUFHTUwsSyxHQUFBQSxLO0FBQ1I7Ozs7O0FBS0EsSUFBSU0sWUFBWTtBQUNmQyxVQUFjLE9BREM7QUFFZkMsb0JBQXVCLENBQUMsSUFBRCxFQUFPLElBQVAsRUFBYSxJQUFiLEVBQW1CLElBQW5CLENBRlIsRUFFa0M7QUFDakRDLHNCQUF3QixDQUFDLElBQUQsRUFBTyxJQUFQLEVBQWEsSUFBYixFQUFtQixJQUFuQixDQUhULEVBR21DO0FBQ2xEQyx1QkFBMEIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQUpYLEVBSXlCO0FBQ3hDQyx1QkFBMEIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQUxYLEVBS3lCO0FBQ3hDQyx3QkFBMEIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQU5YLEVBTXlCO0FBQ3hDQyxtQkFBb0IsQ0FBQyxJQUFELEVBQU8sSUFBUCxFQUFhLElBQWIsRUFBbUIsSUFBbkIsQ0FQTCxFQU8rQjtBQUM5Q0MsZ0JBQWtCLElBUkg7QUFTZkMsZUFBaUIsSUFURjtBQVVmQyxvQkFBcUIsSUFWTjtBQVdmQyxxQkFBc0IsSUFYUDtBQVlmQywwQkFBMEIsSUFaWDtBQWFmQyxnQkFBa0IsSUFiSDtBQWNmQyxpQkFBbUIsSUFkSjtBQWVmQyxpQkFBbUIsSUFmSjtBQWdCZkMsZ0JBQWtCLElBaEJIO0FBaUJmQyxvQkFBcUIsSUFqQk47QUFrQmZDLHlCQUF5QixJQWxCVjtBQW1CZkMsd0JBQXdCLElBbkJUO0FBb0JmQyx1QkFBdUIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQXBCUjtBQXFCZkMsMkJBQTBCLElBckJYLEVBcUJpQjtBQUNoQ0Msd0JBQXdCLElBdEJULENBc0JlO0FBdEJmLENBQWhCOztRQXlCUXRCLFMsR0FBQUEsUztBQUNSOzs7Ozs7SUFLTXVCLHFCLEdBQ0wsK0JBQVk1QixNQUFaLEVBQW9CO0FBQUE7O0FBQ25CLE1BQUtDLElBQUwsR0FBWSxZQUFaO0FBQ0E7QUFDQSxNQUFLQyxJQUFMLEdBQVkyQixNQUFNQyxzQkFBTixDQUE2QixJQUE3QixFQUFtQ0MsTUFBbkMsQ0FBMEMxQixVQUFVcUIsd0JBQXBELEVBQThFMUIsT0FBT2dDLGdCQUFyRixFQUF1R2hDLE9BQU9pQyxlQUE5RyxDQUFaO0FBQ0EsQzs7UUFHTUwscUIsR0FBQUEscUI7QUFDUjs7Ozs7O0lBS01NLFMsR0FDTCxtQkFBWWxDLE1BQVosRUFBb0I7QUFBQTs7QUFDbkIsTUFBS0MsSUFBTCxHQUFZLE1BQVo7QUFDQSxNQUFLQyxJQUFMLEdBQVkyQixNQUFNQyxzQkFBTixDQUE2QixJQUE3QixDQUFaLENBRm1CLENBRTRCO0FBQy9DLE1BQUs1QixJQUFMLEdBQVksS0FBS0EsSUFBTCxDQUFVNkIsTUFBVixDQUFpQjFCLFVBQVVRLGFBQTNCLEVBQTBDYixPQUFPRSxJQUFqRCxDQUFaO0FBQ0EsQzs7UUFHTWdDLFMsR0FBQUEsUztBQUNSOzs7Ozs7SUFLTUMsUztBQUNMLG9CQUFZbkMsTUFBWixFQUFvQjtBQUFBOztBQUNuQixPQUFLQyxJQUFMLEdBQWMsTUFBZDtBQUNBLE9BQUttQyxLQUFMLEdBQWVQLE1BQU1RLE9BQU4sQ0FBY3JDLE9BQU9vQyxLQUFyQixDQUFmO0FBQ0EsT0FBS0UsSUFBTCxHQUFjdEMsT0FBT3NDLElBQVAsSUFBZSxDQUE3QjtBQUNBLE9BQUtDLFFBQUwsR0FBaUJ2QyxPQUFPdUMsUUFBeEI7QUFDQSxPQUFLQyxVQUFMLEdBQWtCeEMsT0FBT3dDLFVBQVAsSUFBcUIsS0FBdkM7QUFDQSxPQUFLQyxRQUFMLEdBQWlCekMsT0FBT3lDLFFBQVAsSUFBbUIsRUFBcEM7QUFDQSxPQUFLQyxPQUFMLEdBQWdCMUMsT0FBTzBDLE9BQVAsSUFBa0IsQ0FBbEM7QUFDQSxPQUFLQyxNQUFMLEdBQWUzQyxPQUFPMkMsTUFBUCxJQUFpQixDQUFoQztBQUNBLE9BQUtGLFFBQUwsR0FBaUIsS0FBS0csZUFBTCxDQUFxQixLQUFLSCxRQUExQixDQUFqQjtBQUNBLE9BQUtJLEtBQUwsR0FBYzdDLE9BQU82QyxLQUFyQjtBQUNBLE9BQUtDLFNBQUw7QUFDQTs7QUFFRDs7Ozs7Ozs7OEJBSVk7QUFDWCxRQUFLNUMsSUFBTCxHQUFZLEVBQVo7O0FBRUEsT0FBSTZDLGVBQWUsS0FBS0MsZUFBTCxDQUFxQixLQUFLVCxRQUExQixFQUFvQyxNQUFwQyxDQUFuQjtBQUNBLE9BQUlVLGVBQWUsS0FBS0QsZUFBTCxDQUFxQixLQUFLVixJQUExQixFQUFnQyxNQUFoQyxDQUFuQjs7QUFFQTtBQUNBLE9BQUksS0FBS08sS0FBVCxFQUFnQjtBQUNmLFFBQUlLLGdCQUFnQixDQUFwQjtBQUNBLFNBQUtMLEtBQUwsR0FBYWhCLE1BQU1RLE9BQU4sQ0FBYyxLQUFLUSxLQUFuQixDQUFiO0FBQ0EsU0FBS0EsS0FBTCxDQUFXTSxPQUFYLENBQW1CLFVBQVNmLEtBQVQsRUFBZ0I7QUFDbEMsU0FBSWdCLFlBQVksSUFBSWpCLFNBQUosQ0FBYyxFQUFDQyxPQUFNLEtBQUtTLEtBQVosRUFBbUJOLFVBQVMsTUFBTVcsYUFBbEMsRUFBZCxDQUFoQjtBQUNBLFVBQUtoRCxJQUFMLEdBQVksS0FBS0EsSUFBTCxDQUFVNkIsTUFBVixDQUFpQnFCLFVBQVVsRCxJQUEzQixDQUFaOztBQUVBNkMscUJBQWdCRyxhQUFoQjtBQUNBLEtBTEQsRUFLRyxJQUxIO0FBTUE7O0FBRUQ7QUFDQTtBQUNBLE9BQUlHLE1BQUosRUFBWUMsT0FBWjtBQUNBLE9BQUlDLE1BQU1DLE9BQU4sQ0FBYyxLQUFLcEIsS0FBbkIsQ0FBSixFQUErQjtBQUM5QjtBQUNBO0FBQ0EsUUFBSyxDQUFFLEtBQUtJLFVBQVosRUFBd0I7QUFDdkI7QUFDQSxVQUFLLElBQUlpQixJQUFJLENBQWIsRUFBZ0JBLElBQUksS0FBS2QsTUFBekIsRUFBaUNjLEdBQWpDLEVBQXNDO0FBQ3JDO0FBQ0EsV0FBS3JCLEtBQUwsQ0FBV2UsT0FBWCxDQUFtQixVQUFTTyxDQUFULEVBQVlDLENBQVosRUFBZTtBQUNqQyxXQUFJQSxLQUFLLENBQVQsRUFBWTtBQUNYTixpQkFBUyxJQUFJTyxXQUFKLENBQWdCLEVBQUMxRCxNQUFNMkIsTUFBTUMsc0JBQU4sQ0FBNkJtQixZQUE3QixFQUEyQ2xCLE1BQTNDLENBQWtELEtBQUs4QixlQUFMLEVBQWxELEVBQTBFaEMsTUFBTWlDLFFBQU4sQ0FBZUosQ0FBZixDQUExRSxFQUE2RixLQUFLakIsUUFBbEcsQ0FBUCxFQUFoQixDQUFUO0FBRUEsUUFIRCxNQUdPO0FBQ047QUFDQVksaUJBQVMsSUFBSU8sV0FBSixDQUFnQixFQUFDMUQsTUFBTSxDQUFDLENBQUQsRUFBSTJCLE1BQU1pQyxRQUFOLENBQWVKLENBQWYsQ0FBSixFQUF1QixLQUFLakIsUUFBNUIsQ0FBUCxFQUFoQixDQUFUO0FBQ0E7O0FBRUQsWUFBS3ZDLElBQUwsR0FBWSxLQUFLQSxJQUFMLENBQVU2QixNQUFWLENBQWlCc0IsT0FBT25ELElBQXhCLENBQVo7QUFDQSxPQVZELEVBVUcsSUFWSDs7QUFZQTtBQUNBLFdBQUtrQyxLQUFMLENBQVdlLE9BQVgsQ0FBbUIsVUFBU08sQ0FBVCxFQUFZQyxDQUFaLEVBQWU7QUFDakMsV0FBSUEsS0FBSyxDQUFULEVBQVk7QUFDWEwsa0JBQVUsSUFBSVMsWUFBSixDQUFpQixFQUFDN0QsTUFBTTJCLE1BQU1DLHNCQUFOLENBQTZCaUIsWUFBN0IsRUFBMkNoQixNQUEzQyxDQUFrRCxLQUFLaUMsZ0JBQUwsRUFBbEQsRUFBMkVuQyxNQUFNaUMsUUFBTixDQUFlSixDQUFmLENBQTNFLEVBQThGLEtBQUtqQixRQUFuRyxDQUFQLEVBQWpCLENBQVY7QUFFQSxRQUhELE1BR087QUFDTjtBQUNBYSxrQkFBVSxJQUFJUyxZQUFKLENBQWlCLEVBQUM3RCxNQUFNLENBQUMsQ0FBRCxFQUFJMkIsTUFBTWlDLFFBQU4sQ0FBZUosQ0FBZixDQUFKLEVBQXVCLEtBQUtqQixRQUE1QixDQUFQLEVBQWpCLENBQVY7QUFDQTs7QUFFRCxZQUFLdkMsSUFBTCxHQUFZLEtBQUtBLElBQUwsQ0FBVTZCLE1BQVYsQ0FBaUJ1QixRQUFRcEQsSUFBekIsQ0FBWjtBQUNBLE9BVkQsRUFVRyxJQVZIO0FBV0E7QUFFRCxLQTlCRCxNQThCTztBQUNOO0FBQ0EsVUFBSyxJQUFJdUQsSUFBSSxDQUFiLEVBQWdCQSxJQUFJLEtBQUtkLE1BQXpCLEVBQWlDYyxHQUFqQyxFQUFzQztBQUNyQyxXQUFLckIsS0FBTCxDQUFXZSxPQUFYLENBQW1CLFVBQVNPLENBQVQsRUFBWUMsQ0FBWixFQUFlO0FBQ2pDO0FBQ0EsV0FBSUEsSUFBSSxDQUFSLEVBQVc7QUFDVlYsdUJBQWUsQ0FBZjtBQUNBOztBQUVEO0FBQ0E7QUFDQSxXQUFJLEtBQUtWLFFBQUwsS0FBa0IsSUFBbEIsSUFBMEJvQixLQUFLLEtBQUt2QixLQUFMLENBQVdoQyxNQUFYLEdBQW9CLENBQXZELEVBQTBEO0FBQ3pELFlBQUk2RCxlQUFlcEMsTUFBTXFDLGVBQU4sQ0FBc0I3RCxVQUFVTSxxQkFBaEMsQ0FBbkI7QUFDQW9DLHVCQUFla0IsZUFBZ0JsQixlQUFlLENBQTlDO0FBQ0E7O0FBRURNLGdCQUFTLElBQUlPLFdBQUosQ0FBZ0IsRUFBQzFELE1BQU0yQixNQUFNQyxzQkFBTixDQUE2Qm1CLFlBQTdCLEVBQTJDbEIsTUFBM0MsQ0FBa0QsQ0FBQyxLQUFLOEIsZUFBTCxFQUFELEVBQXlCaEMsTUFBTWlDLFFBQU4sQ0FBZUosQ0FBZixDQUF6QixFQUE0QyxLQUFLakIsUUFBakQsQ0FBbEQsQ0FBUCxFQUFoQixDQUFUO0FBQ0FhLGlCQUFVLElBQUlTLFlBQUosQ0FBaUIsRUFBQzdELE1BQU0yQixNQUFNQyxzQkFBTixDQUE2QmlCLFlBQTdCLEVBQTJDaEIsTUFBM0MsQ0FBa0QsQ0FBQyxLQUFLaUMsZ0JBQUwsRUFBRCxFQUEwQm5DLE1BQU1pQyxRQUFOLENBQWVKLENBQWYsQ0FBMUIsRUFBNkMsS0FBS2pCLFFBQWxELENBQWxELENBQVAsRUFBakIsQ0FBVjs7QUFFQSxZQUFLdkMsSUFBTCxHQUFZLEtBQUtBLElBQUwsQ0FBVTZCLE1BQVYsQ0FBaUJzQixPQUFPbkQsSUFBeEIsRUFBOEJvRCxRQUFRcEQsSUFBdEMsQ0FBWjtBQUNBLE9BakJELEVBaUJHLElBakJIO0FBa0JBO0FBQ0Q7O0FBRUQsV0FBTyxJQUFQO0FBQ0E7O0FBRUQsU0FBTSx5QkFBTjtBQUNBOzs7OztBQUVEOzs7OztrQ0FLZ0J1QyxRLEVBQVU7QUFDekI7QUFDQUEsY0FBV0EsV0FBVyxHQUFYLEdBQWlCLEdBQWpCLEdBQXVCQSxRQUFsQztBQUNBLFVBQU8wQixLQUFLQyxLQUFMLENBQVczQixXQUFXLEdBQVgsR0FBaUIsR0FBNUIsQ0FBUDtBQUNBOzs7OztBQUVEOzs7Ozs7O2tDQU9nQkYsUSxFQUFVdEMsSSxFQUFNO0FBQy9CLE9BQUlzRCxNQUFNQyxPQUFOLENBQWNqQixRQUFkLENBQUosRUFBNkI7QUFDNUI7QUFDQSxXQUFPQSxTQUFTOEIsR0FBVCxDQUFhLFVBQVNDLEtBQVQsRUFBZ0I7QUFDbkMsWUFBTyxLQUFLdEIsZUFBTCxDQUFxQnNCLEtBQXJCLEVBQTRCckUsSUFBNUIsQ0FBUDtBQUNBLEtBRk0sRUFFSixJQUZJLEVBRUVzRSxNQUZGLENBRVMsVUFBU0MsQ0FBVCxFQUFZQyxDQUFaLEVBQWU7QUFDOUIsWUFBT0QsSUFBSUMsQ0FBWDtBQUNBLEtBSk0sRUFJSixDQUpJLENBQVA7QUFLQTs7QUFFRGxDLGNBQVdBLFNBQVNtQyxRQUFULEVBQVg7O0FBRUEsT0FBSW5DLFNBQVNvQyxXQUFULEdBQXVCQyxNQUF2QixDQUE4QixDQUE5QixNQUFxQyxHQUF6QyxFQUE4QztBQUM3QztBQUNBLFdBQU9DLFNBQVN0QyxTQUFTdUMsU0FBVCxDQUFtQixDQUFuQixDQUFULENBQVA7QUFDQTs7QUFFRDtBQUNBO0FBQ0EsT0FBSWIsZUFBZXBDLE1BQU1xQyxlQUFOLENBQXNCN0QsVUFBVU0scUJBQWhDLENBQW5CO0FBQ0EsVUFBT3dELEtBQUtDLEtBQUwsQ0FBV0gsZUFBZSxLQUFLYyxxQkFBTCxDQUEyQnhDLFFBQTNCLEVBQXFDdEMsSUFBckMsQ0FBMUIsQ0FBUDtBQUNBOztBQUVEOzs7Ozs7Ozs7O3dDQU9zQnNDLFEsRUFBVXRDLEksRUFBTTtBQUNyQztBQUNBLFdBQVFzQyxRQUFSO0FBQ0MsU0FBSyxHQUFMO0FBQ0MsWUFBTyxDQUFQO0FBQ0QsU0FBSyxHQUFMO0FBQ0MsWUFBTyxDQUFQO0FBQ0QsU0FBSyxHQUFMO0FBQ0MsWUFBTyxDQUFQO0FBQ0QsU0FBSyxJQUFMO0FBQ0MsWUFBTyxDQUFQO0FBQ0QsU0FBSyxHQUFMO0FBQ0MsWUFBTyxDQUFQO0FBQ0QsU0FBSyxJQUFMO0FBQ0MsWUFBTyxLQUFQO0FBQ0QsU0FBSyxJQUFMO0FBQ0MsWUFBTyxHQUFQO0FBQ0QsU0FBSyxHQUFMO0FBQ0MsWUFBTyxHQUFQO0FBQ0QsU0FBSyxJQUFMO0FBQ0M7QUFDQSxZQUFPLElBQVA7QUFDRCxTQUFLLElBQUw7QUFDQyxZQUFPLElBQVA7QUFDRCxTQUFLLElBQUw7QUFDQyxZQUFPLElBQVA7QUFDRCxTQUFLLEtBQUw7QUFDQyxZQUFPLEtBQVA7QUFDRCxTQUFLLElBQUw7QUFDQyxZQUFPLEtBQVA7QUFDRCxTQUFLLElBQUw7QUFDQyxZQUFPLE1BQVA7QUFDRDtBQUNDO0FBQ0E7QUFoQ0Y7O0FBbUNBLFNBQU1BLFdBQVcsMkJBQWpCO0FBQ0E7Ozs7O0FBRUQ7Ozs7OztvQ0FNa0I7QUFBQyxVQUFPLE1BQU0sS0FBS0csT0FBWCxHQUFxQixDQUE1QjtBQUE4Qjs7QUFFakQ7Ozs7Ozs7OztxQ0FNbUI7QUFBQyxVQUFPLE1BQU0sS0FBS0EsT0FBWCxHQUFxQixDQUE1QjtBQUE4Qjs7Ozs7O1FBRzNDUCxTLEdBQUFBLFM7QUFDUjs7Ozs7O0lBS000QixZLEdBQ0wsc0JBQVkvRCxNQUFaLEVBQW9CO0FBQUE7O0FBQ25CLE1BQUtFLElBQUwsR0FBWUYsT0FBT0UsSUFBbkI7QUFDQSxDOztRQUdNNkQsWSxHQUFBQSxZO0FBQ1I7Ozs7OztJQUtNSCxXLEdBQ0wscUJBQVk1RCxNQUFaLEVBQW9CO0FBQUE7O0FBQ25CLE1BQUtFLElBQUwsR0FBWUYsT0FBT0UsSUFBbkI7QUFDQSxDOztRQUdNMEQsVyxHQUFBQSxXO0FBQ1I7Ozs7OztJQUtNb0Isa0IsR0FDTCw0QkFBWWhGLE1BQVosRUFBb0I7QUFBQTs7QUFDbkIsTUFBS0MsSUFBTCxHQUFZLFNBQVo7QUFDQTtBQUNBLE1BQUtDLElBQUwsR0FBWTJCLE1BQU1DLHNCQUFOLENBQTZCLElBQTdCLEVBQW1DQyxNQUFuQyxDQUEwQzFCLFVBQVVzQixxQkFBcEQsRUFBMkUzQixPQUFPaUYsVUFBbEYsQ0FBWjtBQUNBLEM7O1FBR01ELGtCLEdBQUFBLGtCO0FBQ1I7Ozs7OztJQUtNRSxLO0FBQ0wsa0JBQWM7QUFBQTs7QUFDYixPQUFLakYsSUFBTCxHQUFZSSxVQUFVTyxnQkFBdEI7QUFDQSxPQUFLVixJQUFMLEdBQVksRUFBWjtBQUNBLE9BQUtDLElBQUwsR0FBWSxFQUFaO0FBQ0EsT0FBS2dGLE1BQUwsR0FBYyxFQUFkO0FBQ0E7O0FBRUQ7Ozs7Ozs7Ozs7MkJBTVNDLEssRUFBT0MsVyxFQUFhO0FBQzVCLE9BQUk5QixNQUFNQyxPQUFOLENBQWM0QixLQUFkLENBQUosRUFBMEI7QUFDekJBLFVBQU1qQyxPQUFOLENBQWMsVUFBU21DLENBQVQsRUFBWTNCLENBQVosRUFBZTtBQUM1QjtBQUNBLFNBQUksT0FBTzBCLFdBQVAsS0FBdUIsVUFBdkIsSUFBcUNDLEVBQUVyRixJQUFGLEtBQVcsTUFBcEQsRUFBNEQ7QUFDM0QsVUFBSXNGLGFBQWFGLFlBQVkxQixDQUFaLEVBQWUyQixDQUFmLENBQWpCOztBQUVBLFVBQUksUUFBT0MsVUFBUCx5Q0FBT0EsVUFBUCxPQUFzQixRQUExQixFQUFvQztBQUNuQyxZQUFLLElBQUk5QixDQUFULElBQWM4QixVQUFkLEVBQTBCO0FBQ3pCLGdCQUFPOUIsQ0FBUDtBQUNDLGNBQUssVUFBTDtBQUNDNkIsWUFBRS9DLFFBQUYsR0FBYWdELFdBQVc5QixDQUFYLENBQWI7QUFDQTtBQUNELGNBQUssWUFBTDtBQUNDNkIsWUFBRTlDLFVBQUYsR0FBZStDLFdBQVc5QixDQUFYLENBQWY7QUFDQTtBQUNELGNBQUssVUFBTDtBQUNDNkIsWUFBRTdDLFFBQUYsR0FBYTZDLEVBQUUxQyxlQUFGLENBQWtCMkMsV0FBVzlCLENBQVgsQ0FBbEIsQ0FBYjtBQUNBO0FBVEY7QUFXQTs7QUFFRDtBQUNBNkIsU0FBRXhDLFNBQUY7QUFDQTtBQUNEOztBQUVELFVBQUs1QyxJQUFMLEdBQVksS0FBS0EsSUFBTCxDQUFVNkIsTUFBVixDQUFpQnVELEVBQUVwRixJQUFuQixDQUFaO0FBQ0EsVUFBS0MsSUFBTCxHQUFZMEIsTUFBTTJELGFBQU4sQ0FBb0IsS0FBS3RGLElBQUwsQ0FBVUUsTUFBOUIsRUFBc0MsQ0FBdEMsQ0FBWixDQTFCNEIsQ0EwQjBCO0FBQ3RELFVBQUsrRSxNQUFMLENBQVlNLElBQVosQ0FBaUJILENBQWpCO0FBQ0EsS0E1QkQsRUE0QkcsSUE1Qkg7QUE4QkEsSUEvQkQsTUErQk87QUFDTixTQUFLcEYsSUFBTCxHQUFZLEtBQUtBLElBQUwsQ0FBVTZCLE1BQVYsQ0FBaUJxRCxNQUFNbEYsSUFBdkIsQ0FBWjtBQUNBLFNBQUtDLElBQUwsR0FBWTBCLE1BQU0yRCxhQUFOLENBQW9CLEtBQUt0RixJQUFMLENBQVVFLE1BQTlCLEVBQXNDLENBQXRDLENBQVosQ0FGTSxDQUVnRDtBQUN0RCxTQUFLK0UsTUFBTCxDQUFZTSxJQUFaLENBQWlCTCxLQUFqQjtBQUNBOztBQUVELFVBQU8sSUFBUDtBQUNBOztBQUVEOzs7Ozs7OzsyQkFLU00sRyxFQUFLO0FBQ2IsT0FBSU4sUUFBUSxJQUFJbEQsU0FBSixDQUFjLEVBQUNoQyxNQUFNLENBQUNHLFVBQVVnQixhQUFYLENBQVAsRUFBZCxDQUFaO0FBQ0ErRCxTQUFNbEYsSUFBTixDQUFXdUYsSUFBWCxDQUFnQixJQUFoQixFQUZhLENBRVU7QUFDdkIsT0FBSUUsUUFBUXhCLEtBQUtDLEtBQUwsQ0FBVyxXQUFXc0IsR0FBdEIsQ0FBWjtBQUNBTixTQUFNbEYsSUFBTixHQUFha0YsTUFBTWxGLElBQU4sQ0FBVzZCLE1BQVgsQ0FBa0JGLE1BQU0yRCxhQUFOLENBQW9CRyxLQUFwQixFQUEyQixDQUEzQixDQUFsQixDQUFiLENBSmEsQ0FJa0Q7QUFDL0QsVUFBTyxLQUFLQyxRQUFMLENBQWNSLEtBQWQsQ0FBUDtBQUNBOztBQUVEOzs7Ozs7Ozs7OzttQ0FRaUJTLFMsRUFBV0MsVyxFQUFhQyxpQixFQUFtQkMsaUIsRUFBbUI7QUFDOUVELHVCQUFvQkEscUJBQXFCLEVBQXpDO0FBQ0FDLHVCQUFvQkEscUJBQXFCLENBQXpDOztBQUVBLE9BQUlaLFFBQVEsSUFBSWxELFNBQUosQ0FBYyxFQUFDaEMsTUFBTSxDQUFDRyxVQUFVa0Isc0JBQVgsQ0FBUCxFQUFkLENBQVo7QUFDQTZELFNBQU1sRixJQUFOLENBQVd1RixJQUFYLENBQWdCLElBQWhCLEVBTDhFLENBS3ZEO0FBQ3ZCTCxTQUFNbEYsSUFBTixHQUFha0YsTUFBTWxGLElBQU4sQ0FBVzZCLE1BQVgsQ0FBa0JGLE1BQU0yRCxhQUFOLENBQW9CSyxTQUFwQixFQUErQixDQUEvQixDQUFsQixDQUFiLENBTjhFLENBTVg7O0FBRW5FLE9BQUlJLGVBQWU5QixLQUFLK0IsSUFBTCxDQUFVSixXQUFWLENBQW5CLENBUjhFLENBUW5DO0FBQzNDVixTQUFNbEYsSUFBTixHQUFha0YsTUFBTWxGLElBQU4sQ0FBVzZCLE1BQVgsQ0FBa0JGLE1BQU0yRCxhQUFOLENBQW9CUyxZQUFwQixFQUFrQyxDQUFsQyxDQUFsQixDQUFiLENBVDhFLENBU1I7QUFDdEViLFNBQU1sRixJQUFOLEdBQWFrRixNQUFNbEYsSUFBTixDQUFXNkIsTUFBWCxDQUFrQkYsTUFBTTJELGFBQU4sQ0FBb0JPLGlCQUFwQixFQUF1QyxDQUF2QyxDQUFsQixDQUFiLENBVjhFLENBVUg7QUFDM0VYLFNBQU1sRixJQUFOLEdBQWFrRixNQUFNbEYsSUFBTixDQUFXNkIsTUFBWCxDQUFrQkYsTUFBTTJELGFBQU4sQ0FBb0JRLGlCQUFwQixFQUF1QyxDQUF2QyxDQUFsQixDQUFiLENBWDhFLENBV0g7QUFDM0UsVUFBTyxLQUFLSixRQUFMLENBQWNSLEtBQWQsQ0FBUDtBQUNBOztBQUVEOzs7Ozs7Ozs7a0NBTWdCZSxFLEVBQUlDLEUsRUFBSTtBQUN2QixPQUFJaEIsUUFBUSxJQUFJbEQsU0FBSixDQUFjLEVBQUNoQyxNQUFNLENBQUNHLFVBQVVtQixxQkFBWCxDQUFQLEVBQWQsQ0FBWjtBQUNBNEQsU0FBTWxGLElBQU4sQ0FBV3VGLElBQVgsQ0FBZ0IsSUFBaEIsRUFGdUIsQ0FFQTs7QUFFdkIsT0FBSVksT0FBT0QsTUFBTSxDQUFqQjtBQUNBRCxRQUFLQSxNQUFNLENBQVg7O0FBRUE7QUFDQSxPQUFJLE9BQU9DLEVBQVAsS0FBYyxXQUFsQixFQUErQjtBQUM5QixRQUFJRSxTQUFTLENBQ1osQ0FBQyxJQUFELEVBQU8sSUFBUCxFQUFhLElBQWIsRUFBbUIsSUFBbkIsRUFBeUIsSUFBekIsRUFBK0IsSUFBL0IsRUFBcUMsR0FBckMsRUFBMEMsR0FBMUMsRUFBK0MsR0FBL0MsRUFBb0QsR0FBcEQsRUFBeUQsR0FBekQsRUFBOEQsR0FBOUQsRUFBbUUsR0FBbkUsRUFBd0UsSUFBeEUsRUFBOEUsSUFBOUUsQ0FEWSxFQUVaLENBQUMsSUFBRCxFQUFPLElBQVAsRUFBYSxJQUFiLEVBQW1CLEdBQW5CLEVBQXdCLEdBQXhCLEVBQTZCLEdBQTdCLEVBQWtDLEdBQWxDLEVBQXVDLEdBQXZDLEVBQTRDLEdBQTVDLEVBQWlELEdBQWpELEVBQXNELElBQXRELEVBQTRELElBQTVELEVBQWtFLElBQWxFLEVBQXdFLElBQXhFLEVBQThFLElBQTlFLENBRlksQ0FBYjtBQUlBLFFBQUlDLFNBQVNKLEdBQUcvRixNQUFoQjtBQUNBLFFBQUlvRyxPQUFPTCxNQUFNLEdBQWpCOztBQUVBLFFBQUlBLEdBQUcsQ0FBSCxNQUFVQSxHQUFHLENBQUgsRUFBTXhCLFdBQU4sRUFBZCxFQUFtQzBCLE9BQU8sQ0FBUDs7QUFFbkMsUUFBSUUsU0FBUyxDQUFiLEVBQWdCO0FBQ2YsYUFBUUosR0FBR3ZCLE1BQUgsQ0FBVTJCLFNBQVMsQ0FBbkIsQ0FBUjtBQUNDLFdBQUssR0FBTDtBQUNDRixjQUFPLENBQVA7QUFDQUcsY0FBT0wsR0FBR3ZCLE1BQUgsQ0FBVSxDQUFWLEVBQWFELFdBQWIsRUFBUDtBQUNBNkIsY0FBT0EsS0FBS3pFLE1BQUwsQ0FBWW9FLEdBQUdyQixTQUFILENBQWEsQ0FBYixFQUFnQnlCLFNBQVMsQ0FBekIsQ0FBWixDQUFQO0FBQ0E7QUFDRCxXQUFLLEdBQUw7QUFDQ0YsY0FBTyxDQUFQO0FBQ0FHLGNBQU9MLEdBQUd2QixNQUFILENBQVUsQ0FBVixFQUFhRCxXQUFiLEVBQVA7QUFDQTZCLGNBQU9BLEtBQUt6RSxNQUFMLENBQVlvRSxHQUFHckIsU0FBSCxDQUFhLENBQWIsRUFBZ0J5QixTQUFTLENBQXpCLENBQVosQ0FBUDtBQUNBO0FBQ0QsV0FBSyxHQUFMO0FBQ0NGLGNBQU8sQ0FBUDtBQUNBRyxjQUFPTCxHQUFHdkIsTUFBSCxDQUFVLENBQVYsRUFBYTZCLFdBQWIsRUFBUDtBQUNBRCxjQUFPQSxLQUFLekUsTUFBTCxDQUFZb0UsR0FBR3JCLFNBQUgsQ0FBYSxDQUFiLEVBQWdCeUIsU0FBUyxDQUF6QixDQUFaLENBQVA7QUFDQTtBQUNELFdBQUssR0FBTDtBQUNDRixjQUFPLENBQVA7QUFDQUcsY0FBT0wsR0FBR3ZCLE1BQUgsQ0FBVSxDQUFWLEVBQWE2QixXQUFiLEVBQVA7QUFDQUQsY0FBT0EsS0FBS3pFLE1BQUwsQ0FBWW9FLEdBQUdyQixTQUFILENBQWEsQ0FBYixFQUFnQnlCLFNBQVMsQ0FBekIsQ0FBWixDQUFQO0FBQ0E7QUFwQkY7QUFzQkE7O0FBRUQsUUFBSUcsYUFBYUosT0FBT0QsSUFBUCxFQUFhTSxPQUFiLENBQXFCSCxJQUFyQixDQUFqQjtBQUNBTCxTQUFLTyxlQUFlLENBQUMsQ0FBaEIsR0FBb0IsQ0FBcEIsR0FBd0JBLGFBQWEsQ0FBMUM7QUFDQTs7QUFFRHRCLFNBQU1sRixJQUFOLEdBQWFrRixNQUFNbEYsSUFBTixDQUFXNkIsTUFBWCxDQUFrQkYsTUFBTTJELGFBQU4sQ0FBb0JXLEVBQXBCLEVBQXdCLENBQXhCLENBQWxCLENBQWIsQ0EvQ3VCLENBK0NxQztBQUM1RGYsU0FBTWxGLElBQU4sR0FBYWtGLE1BQU1sRixJQUFOLENBQVc2QixNQUFYLENBQWtCRixNQUFNMkQsYUFBTixDQUFvQmEsSUFBcEIsRUFBMEIsQ0FBMUIsQ0FBbEIsQ0FBYixDQWhEdUIsQ0FnRHVDO0FBQzlELFVBQU8sS0FBS1QsUUFBTCxDQUFjUixLQUFkLENBQVA7QUFDQTs7QUFFRDs7Ozs7Ozs7MEJBS1F3QixJLEVBQU07QUFDYixPQUFJeEIsUUFBUSxJQUFJbEQsU0FBSixDQUFjLEVBQUNoQyxNQUFNLENBQUNHLFVBQVVTLFlBQVgsQ0FBUCxFQUFkLENBQVo7QUFDQSxPQUFJK0YsY0FBY2hGLE1BQU1pRixhQUFOLENBQW9CRixJQUFwQixDQUFsQjtBQUNBeEIsU0FBTWxGLElBQU4sR0FBYWtGLE1BQU1sRixJQUFOLENBQVc2QixNQUFYLENBQWtCRixNQUFNQyxzQkFBTixDQUE2QitFLFlBQVl6RyxNQUF6QyxDQUFsQixDQUFiLENBSGEsQ0FHcUU7QUFDbEZnRixTQUFNbEYsSUFBTixHQUFha0YsTUFBTWxGLElBQU4sQ0FBVzZCLE1BQVgsQ0FBa0I4RSxXQUFsQixDQUFiLENBSmEsQ0FJZ0M7QUFDN0MsVUFBTyxLQUFLakIsUUFBTCxDQUFjUixLQUFkLENBQVA7QUFDQTs7QUFFRDs7Ozs7Ozs7K0JBS2F3QixJLEVBQU07QUFDbEIsT0FBSXhCLFFBQVEsSUFBSWxELFNBQUosQ0FBYyxFQUFDaEMsTUFBTSxDQUFDRyxVQUFVVSxpQkFBWCxDQUFQLEVBQWQsQ0FBWjtBQUNBLE9BQUk4RixjQUFjaEYsTUFBTWlGLGFBQU4sQ0FBb0JGLElBQXBCLENBQWxCO0FBQ0F4QixTQUFNbEYsSUFBTixHQUFha0YsTUFBTWxGLElBQU4sQ0FBVzZCLE1BQVgsQ0FBa0JGLE1BQU1DLHNCQUFOLENBQTZCK0UsWUFBWXpHLE1BQXpDLENBQWxCLENBQWIsQ0FIa0IsQ0FHZ0U7QUFDbEZnRixTQUFNbEYsSUFBTixHQUFha0YsTUFBTWxGLElBQU4sQ0FBVzZCLE1BQVgsQ0FBa0I4RSxXQUFsQixDQUFiLENBSmtCLENBSTJCO0FBQzdDLFVBQU8sS0FBS2pCLFFBQUwsQ0FBY1IsS0FBZCxDQUFQO0FBQ0E7O0FBRUQ7Ozs7Ozs7OytCQUthd0IsSSxFQUFNO0FBQ2xCLE9BQUl4QixRQUFRLElBQUlsRCxTQUFKLENBQWMsRUFBQ2hDLE1BQU0sQ0FBQ0csVUFBVVcsa0JBQVgsQ0FBUCxFQUFkLENBQVo7QUFDQSxPQUFJNkYsY0FBY2hGLE1BQU1pRixhQUFOLENBQW9CRixJQUFwQixDQUFsQjtBQUNBeEIsU0FBTWxGLElBQU4sR0FBYWtGLE1BQU1sRixJQUFOLENBQVc2QixNQUFYLENBQWtCRixNQUFNQyxzQkFBTixDQUE2QitFLFlBQVl6RyxNQUF6QyxDQUFsQixDQUFiLENBSGtCLENBR2dFO0FBQ2xGZ0YsU0FBTWxGLElBQU4sR0FBYWtGLE1BQU1sRixJQUFOLENBQVc2QixNQUFYLENBQWtCOEUsV0FBbEIsQ0FBYixDQUprQixDQUkyQjtBQUM3QyxVQUFPLEtBQUtqQixRQUFMLENBQWNSLEtBQWQsQ0FBUDtBQUNBOztBQUVEOzs7Ozs7OztvQ0FLa0J3QixJLEVBQU07QUFDdkIsT0FBSXhCLFFBQVEsSUFBSWxELFNBQUosQ0FBYyxFQUFDaEMsTUFBTSxDQUFDRyxVQUFVWSx1QkFBWCxDQUFQLEVBQWQsQ0FBWjtBQUNBLE9BQUk0RixjQUFjaEYsTUFBTWlGLGFBQU4sQ0FBb0JGLElBQXBCLENBQWxCO0FBQ0F4QixTQUFNbEYsSUFBTixHQUFha0YsTUFBTWxGLElBQU4sQ0FBVzZCLE1BQVgsQ0FBa0JGLE1BQU1DLHNCQUFOLENBQTZCK0UsWUFBWXpHLE1BQXpDLENBQWxCLENBQWIsQ0FIdUIsQ0FHMkQ7QUFDbEZnRixTQUFNbEYsSUFBTixHQUFha0YsTUFBTWxGLElBQU4sQ0FBVzZCLE1BQVgsQ0FBa0I4RSxXQUFsQixDQUFiLENBSnVCLENBSXNCO0FBQzdDLFVBQU8sS0FBS2pCLFFBQUwsQ0FBY1IsS0FBZCxDQUFQO0FBQ0E7O0FBRUQ7Ozs7Ozs7OzRCQUtVd0IsSSxFQUFNO0FBQ2YsT0FBSXhCLFFBQVEsSUFBSWxELFNBQUosQ0FBYyxFQUFDaEMsTUFBTSxDQUFDRyxVQUFVYyxjQUFYLENBQVAsRUFBZCxDQUFaO0FBQ0EsT0FBSTBGLGNBQWNoRixNQUFNaUYsYUFBTixDQUFvQkYsSUFBcEIsQ0FBbEI7QUFDQXhCLFNBQU1sRixJQUFOLEdBQWFrRixNQUFNbEYsSUFBTixDQUFXNkIsTUFBWCxDQUFrQkYsTUFBTUMsc0JBQU4sQ0FBNkIrRSxZQUFZekcsTUFBekMsQ0FBbEIsQ0FBYixDQUhlLENBR21FO0FBQ2xGZ0YsU0FBTWxGLElBQU4sR0FBYWtGLE1BQU1sRixJQUFOLENBQVc2QixNQUFYLENBQWtCOEUsV0FBbEIsQ0FBYixDQUplLENBSThCO0FBQzdDLFVBQU8sS0FBS2pCLFFBQUwsQ0FBY1IsS0FBZCxDQUFQO0FBQ0E7O0FBRUQ7Ozs7Ozs7OzhCQUtZd0IsSSxFQUFNO0FBQ2pCLE9BQUl4QixRQUFRLElBQUlsRCxTQUFKLENBQWMsRUFBQ2hDLE1BQU0sQ0FBQ0csVUFBVWUsY0FBWCxDQUFQLEVBQWQsQ0FBWjtBQUNBLE9BQUl5RixjQUFjaEYsTUFBTWlGLGFBQU4sQ0FBb0JGLElBQXBCLENBQWxCO0FBQ0F4QixTQUFNbEYsSUFBTixHQUFha0YsTUFBTWxGLElBQU4sQ0FBVzZCLE1BQVgsQ0FBa0JGLE1BQU1DLHNCQUFOLENBQTZCK0UsWUFBWXpHLE1BQXpDLENBQWxCLENBQWIsQ0FIaUIsQ0FHaUU7QUFDbEZnRixTQUFNbEYsSUFBTixHQUFha0YsTUFBTWxGLElBQU4sQ0FBVzZCLE1BQVgsQ0FBa0I4RSxXQUFsQixDQUFiLENBSmlCLENBSTRCO0FBQzdDLFVBQU8sS0FBS2pCLFFBQUwsQ0FBY1IsS0FBZCxDQUFQO0FBQ0E7O0FBRUQ7Ozs7Ozs7OzJCQUtTMkIsSyxFQUFPO0FBQ2YsT0FBSTNCLFFBQVEsSUFBSWxELFNBQUosQ0FBYyxFQUFDaEMsTUFBTSxDQUFDRyxVQUFVYSxhQUFYLENBQVAsRUFBZCxDQUFaO0FBQ0EsT0FBSTJGLGNBQWNoRixNQUFNaUYsYUFBTixDQUFvQkMsS0FBcEIsQ0FBbEI7QUFDQTNCLFNBQU1sRixJQUFOLEdBQWFrRixNQUFNbEYsSUFBTixDQUFXNkIsTUFBWCxDQUFrQkYsTUFBTUMsc0JBQU4sQ0FBNkIrRSxZQUFZekcsTUFBekMsQ0FBbEIsQ0FBYixDQUhlLENBR21FO0FBQ2xGZ0YsU0FBTWxGLElBQU4sR0FBYWtGLE1BQU1sRixJQUFOLENBQVc2QixNQUFYLENBQWtCOEUsV0FBbEIsQ0FBYixDQUplLENBSThCO0FBQzdDLFVBQU8sS0FBS2pCLFFBQUwsQ0FBY1IsS0FBZCxDQUFQO0FBQ0E7O0FBRUQ7Ozs7Ozs7K0JBSWE7QUFDWixPQUFJQSxRQUFRLElBQUl4QixXQUFKLENBQWdCLEVBQUMxRCxNQUFNLENBQUMsSUFBRCxFQUFPLElBQVAsRUFBYSxJQUFiLEVBQW1CLElBQW5CLENBQVAsRUFBaEIsQ0FBWjtBQUNBLFVBQU8sS0FBSzBGLFFBQUwsQ0FBY1IsS0FBZCxDQUFQO0FBQ0E7Ozs7OztRQUlNRixLLEdBQUFBLEs7O0FBR1I7OztJQUdNckQsSzs7Ozs7Ozs7O0FBRUw7Ozs7NEJBSWlCO0FBQ2hCLFVBQU94QixVQUFVQyxPQUFqQjtBQUNBOztBQUVEOzs7Ozs7OztnQ0FLcUIwRyxNLEVBQVE7QUFDNUIsVUFBT0EsT0FBT0MsS0FBUCxDQUFhLEVBQWIsRUFBaUI1QyxHQUFqQixDQUFxQjtBQUFBLFdBQVE2QyxLQUFLQyxVQUFMLEVBQVI7QUFBQSxJQUFyQixDQUFQO0FBQ0E7O0FBRUQ7Ozs7Ozs7OzRCQUtpQkMsQyxFQUFHO0FBQ25CLFVBQU8sQ0FBQ0MsTUFBTUMsV0FBV0YsQ0FBWCxDQUFOLENBQUQsSUFBeUJHLFNBQVNILENBQVQsQ0FBaEM7QUFDQTs7QUFFRDs7Ozs7Ozs7OzJCQU1vQmhGLEssRUFBTztBQUN0QixVQUFPLHVCQUFPQSxLQUFQLENBQVA7QUFDQTs7QUFFTDs7Ozs7Ozs7Ozs7O3lDQVM4Qm9GLEssRUFBTztBQUNqQyxPQUFJQyxTQUFTRCxRQUFRLElBQXJCOztBQUVBLFVBQU9BLFFBQVFBLFNBQVMsQ0FBeEIsRUFBMkI7QUFDdkJDLGVBQVcsQ0FBWDtBQUNBQSxjQUFZRCxRQUFRLElBQVQsR0FBaUIsSUFBNUI7QUFDSDs7QUFFRCxPQUFJRSxRQUFRLEVBQVo7QUFDQSxVQUFPLElBQVAsRUFBYTtBQUNUQSxVQUFNakMsSUFBTixDQUFXZ0MsU0FBUyxJQUFwQjs7QUFFQSxRQUFJQSxTQUFTLElBQWIsRUFBbUJBLFdBQVcsQ0FBWCxDQUFuQixLQUNLO0FBQUU7QUFBUTtBQUNsQjs7QUFFRCxVQUFPQyxLQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7O2tDQUt1QkMsQyxFQUFHO0FBQ3pCLFVBQU9DLFVBQVVELENBQVYsRUFBYVYsS0FBYixDQUFtQixPQUFuQixFQUE0QjdHLE1BQTVCLEdBQXFDLENBQTVDO0FBQ0E7O0FBRUQ7Ozs7Ozs7O2tDQUt1QnlILEssRUFBTztBQUM3QixPQUFJQyxNQUFNLEVBQVY7QUFDQSxPQUFJQyxZQUFKOztBQUVBRixTQUFNMUUsT0FBTixDQUFjLFVBQVM2RSxJQUFULEVBQWU7QUFDNUJELG1CQUFlQyxLQUFLdEQsUUFBTCxDQUFjLEVBQWQsQ0FBZjs7QUFFQTtBQUNBLFFBQUlxRCxhQUFhM0gsTUFBYixJQUF1QixDQUEzQixFQUE4QjJILGVBQWUsTUFBTUEsWUFBckI7O0FBRTlCRCxXQUFPQyxZQUFQO0FBQ0EsSUFQRDs7QUFTQSxVQUFPbEQsU0FBU2lELEdBQVQsRUFBYyxFQUFkLENBQVA7QUFDQTs7QUFFRDs7Ozs7Ozs7O2dDQU1xQkcsTSxFQUFRQyxXLEVBQWE7QUFDekNBLGlCQUFjQSxlQUFlLENBQTdCOztBQUVBLE9BQUlDLFlBQVlGLE9BQU92RCxRQUFQLENBQWdCLEVBQWhCLENBQWhCOztBQUVBLE9BQUl5RCxVQUFVL0gsTUFBVixHQUFtQixDQUF2QixFQUEwQjtBQUFFO0FBQzNCK0gsZ0JBQVksTUFBTUEsU0FBbEI7QUFDQTs7QUFFRDtBQUNBLE9BQUlDLFdBQVdELFVBQVVFLEtBQVYsQ0FBZ0IsT0FBaEIsQ0FBZjs7QUFFQTtBQUNBRCxjQUFXQSxTQUFTL0QsR0FBVCxDQUFhO0FBQUEsV0FBUVEsU0FBU3lELElBQVQsRUFBZSxFQUFmLENBQVI7QUFBQSxJQUFiLENBQVg7O0FBRUE7QUFDQSxPQUFJRixTQUFTaEksTUFBVCxHQUFrQjhILFdBQXRCLEVBQW1DO0FBQ2xDLFdBQU9BLGNBQWNFLFNBQVNoSSxNQUF2QixHQUFnQyxDQUF2QyxFQUEwQztBQUN6Q2dJLGNBQVNHLE9BQVQsQ0FBaUIsQ0FBakI7QUFDQTtBQUNEOztBQUVELFVBQU9ILFFBQVA7QUFDQTs7QUFFRDs7Ozs7Ozs7MEJBS2U5RCxLLEVBQU87QUFDckIsT0FBSWYsTUFBTUMsT0FBTixDQUFjYyxLQUFkLENBQUosRUFBMEIsT0FBT0EsS0FBUDtBQUMxQixVQUFPLENBQUNBLEtBQUQsQ0FBUDtBQUNBOzs7Ozs7UUFHTXpDLEssR0FBQUEsSzs7SUFDRjJHLE87QUFFTCxvQkFBYztBQUFBO0FBRWI7QUFEQTs7O0FBR0Q7Ozs7Ozs7O2lDQUllQyxLLEVBQU87QUFDckIsT0FBSUMsUUFBUSxJQUFJeEQsS0FBSixFQUFaO0FBQ0EsT0FBSTVDLElBQUo7QUFDQSxPQUFJcUcsVUFBVSxFQUFkOztBQUVBRixTQUFNRyxTQUFOLENBQWdCekYsT0FBaEIsQ0FBd0IsVUFBUzBGLFFBQVQsRUFBbUI7QUFDMUNGLGNBQVUsRUFBVjs7QUFFQSxRQUFJRSxTQUFTQyxRQUFULEtBQXNCLEdBQTFCLEVBQStCO0FBQzlCRCxjQUFTRSxJQUFULENBQWM1RixPQUFkLENBQXNCLFVBQVM2RixHQUFULEVBQWM7QUFDbkM7QUFDQUwsY0FBUWxELElBQVIsQ0FBYSxLQUFLd0QsWUFBTCxDQUFrQkQsR0FBbEIsQ0FBYjtBQUNBLE1BSEQ7QUFLQSxLQU5ELE1BTU8sSUFBSUgsU0FBU0MsUUFBVCxLQUFzQixHQUExQixFQUErQjtBQUNyQztBQUNBeEcsWUFBTyxLQUFLNEcsZUFBTCxDQUFxQkwsUUFBckIsQ0FBUDtBQUNBO0FBQ0E7O0FBRURILFVBQU05QyxRQUFOLENBQWUsSUFBSXpELFNBQUosQ0FBYyxFQUFDQyxPQUFPdUcsT0FBUixFQUFpQnBHLFVBQVUsS0FBSzJHLGVBQUwsQ0FBcUJMLFFBQXJCLENBQTNCLEVBQTJEdkcsTUFBTUEsSUFBakUsRUFBZCxDQUFmOztBQUVBO0FBQ0FBLFdBQU8sQ0FBUDtBQUNBLElBbkJEOztBQXFCQSxVQUFPb0csS0FBUDtBQUNBOztBQUdEOzs7Ozs7OytCQUlhdEcsSyxFQUFPO0FBQ25CLFVBQU9BLE1BQU0rRyxPQUFOLENBQWMsR0FBZCxFQUFtQixFQUFuQixDQUFQO0FBQ0E7O0FBR0Q7Ozs7Ozs7a0NBSWdCM0MsSSxFQUFNO0FBQ3JCLFdBQVFBLEtBQUtqRSxRQUFiO0FBQ0MsU0FBSyxHQUFMO0FBQ0MsWUFBTyxHQUFQO0FBQ0QsU0FBSyxHQUFMO0FBQ0MsWUFBT2lFLEtBQUs0QyxRQUFMLEtBQWtCLElBQWxCLEdBQXlCLEdBQWhDO0FBQ0QsU0FBSyxHQUFMO0FBQ0MsWUFBTzVDLEtBQUs0QyxRQUFMLEtBQWtCLElBQWxCLEdBQXlCLEdBQWhDO0FBQ0QsU0FBSyxHQUFMO0FBQ0MsWUFBTzVDLEtBQUs0QyxRQUFMLEtBQWtCLElBQWxCLEdBQXlCLEdBQWhDO0FBUkY7O0FBV0EsVUFBTzVDLEtBQUtqRSxRQUFaO0FBQ0E7Ozs7OztRQUdNaUcsTyxHQUFBQSxPO0FBQ1I7Ozs7OztJQUtNYSxNO0FBQ0wsaUJBQVlDLE1BQVosRUFBb0I7QUFBQTs7QUFDbkIsT0FBS3BKLElBQUwsR0FBWSxFQUFaOztBQUVBLE1BQUlxSixZQUFZRCxPQUFPbEosTUFBUCxHQUFnQixDQUFoQixHQUFvQkMsVUFBVUssb0JBQTlCLEdBQXFETCxVQUFVSSxvQkFBL0U7QUFDQSxNQUFJK0ksaUJBQWlCM0gsTUFBTTJELGFBQU4sQ0FBb0I4RCxPQUFPbEosTUFBM0IsRUFBbUMsQ0FBbkMsQ0FBckIsQ0FKbUIsQ0FJeUM7O0FBRTVEO0FBQ0EsT0FBS0YsSUFBTCxDQUFVdUYsSUFBVixDQUFlLElBQUkxRixLQUFKLENBQVU7QUFDbkJFLFNBQU1JLFVBQVVFLGlCQURHO0FBRW5CTCxTQUFNcUosVUFBVXhILE1BQVYsQ0FBaUJ5SCxjQUFqQixFQUFpQ25KLFVBQVVNLHFCQUEzQyxDQUZhLEVBQVYsQ0FBZjs7QUFJQTtBQUNBMkksU0FBT25HLE9BQVAsQ0FBZSxVQUFTdUYsS0FBVCxFQUFnQi9FLENBQWhCLEVBQW1CO0FBQ2pDK0UsU0FBTTlDLFFBQU4sQ0FBZSxJQUFJMUQsU0FBSixDQUFjLEVBQUNoQyxNQUFNRyxVQUFVb0Isb0JBQWpCLEVBQWQsQ0FBZjtBQUNBLFFBQUt2QixJQUFMLENBQVV1RixJQUFWLENBQWVpRCxLQUFmO0FBQ0EsR0FIRCxFQUdHLElBSEg7QUFJQTs7QUFFRDs7Ozs7Ozs7OEJBSVk7QUFDWCxPQUFJZSxRQUFRLEVBQVo7O0FBRUE7QUFDQSxRQUFLdkosSUFBTCxDQUFVaUQsT0FBVixDQUFrQixVQUFDdUcsQ0FBRDtBQUFBLFdBQU9ELFFBQVFBLE1BQU0xSCxNQUFOLENBQWEySCxFQUFFekosSUFBZixFQUFxQnlKLEVBQUV2SixJQUF2QixFQUE2QnVKLEVBQUV4SixJQUEvQixDQUFmO0FBQUEsSUFBbEI7O0FBRUEsVUFBTyxJQUFJeUosVUFBSixDQUFlRixLQUFmLENBQVA7QUFDQTs7QUFFRDs7Ozs7OzsyQkFJUztBQUNSLE9BQUksT0FBT0csSUFBUCxLQUFnQixVQUFwQixFQUFnQyxPQUFPQSxLQUFLQyxPQUFPQyxZQUFQLENBQW9CQyxLQUFwQixDQUEwQixJQUExQixFQUFnQyxLQUFLQyxTQUFMLEVBQWhDLENBQUwsQ0FBUDtBQUNoQyxVQUFPLElBQUlDLE1BQUosQ0FBVyxLQUFLRCxTQUFMLEVBQVgsRUFBNkJ0RixRQUE3QixDQUFzQyxRQUF0QyxDQUFQO0FBQ0E7O0FBRUU7Ozs7Ozs7NEJBSVU7QUFDVCxVQUFPLDRCQUE0QixLQUFLd0YsTUFBTCxFQUFuQztBQUNBOztBQUVKOzs7Ozs7OzJCQUlZO0FBQ1IsVUFBT0MsUUFBUUMsTUFBUixDQUFlQyxLQUFmLENBQXFCLElBQUlKLE1BQUosQ0FBVyxLQUFLRCxTQUFMLEVBQVgsQ0FBckIsQ0FBUDtBQUNBOztBQUVKOzs7Ozs7OzJCQUlTTSxRLEVBQVU7QUFDbEIsT0FBSTdDLFNBQVMsSUFBSXdDLE1BQUosQ0FBVyxLQUFLRCxTQUFMLEVBQVgsQ0FBYjtBQUNBTyxNQUFHQyxTQUFILENBQWFGLFdBQVcsTUFBeEIsRUFBZ0M3QyxNQUFoQyxFQUF3QyxVQUFVZ0QsR0FBVixFQUFlO0FBQ3RELFFBQUdBLEdBQUgsRUFBUSxPQUFPQyxRQUFRQyxHQUFSLENBQVlGLEdBQVosQ0FBUDtBQUNSLElBRkQ7QUFHQTs7Ozs7O1FBR01wQixNLEdBQUFBLE0iLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE9iamVjdCByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2h1bmsgc2VjdGlvbiBvZiBhIE1JREkgZmlsZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMgLSB7dHlwZTogbnVtYmVyLCBkYXRhOiBhcnJheSwgc2l6ZTogYXJyYXl9XG4gKiBAcmV0dXJuIHtDaHVua31cbiAqL1xuY2xhc3MgQ2h1bmsge1xuXHRjb25zdHJ1Y3RvcihmaWVsZHMpIHtcblx0XHR0aGlzLnR5cGUgPSBmaWVsZHMudHlwZTtcblx0XHR0aGlzLmRhdGEgPSBmaWVsZHMuZGF0YTtcblx0XHR0aGlzLnNpemUgPSBbMCwgMCwgMCwgZmllbGRzLmRhdGEubGVuZ3RoXTtcblx0fVxufVxuXG5leHBvcnQge0NodW5rfTtcbi8qKlxuICogTUlESSBmaWxlIGZvcm1hdCBjb25zdGFudHMsIGluY2x1ZGluZyBub3RlIC0+IE1JREkgbnVtYmVyIHRyYW5zbGF0aW9uLlxuICogQHJldHVybiB7Q29uc3RhbnRzfVxuICovXG5cbnZhciBDb25zdGFudHMgPSB7XG5cdFZFUlNJT05cdFx0XHRcdFx0OiAnMS41LjInLFxuXHRIRUFERVJfQ0hVTktfVFlQRSAgXHRcdDogWzB4NGQsIDB4NTQsIDB4NjgsIDB4NjRdLCAvLyBNdGhkXG5cdEhFQURFUl9DSFVOS19MRU5HVEggIFx0OiBbMHgwMCwgMHgwMCwgMHgwMCwgMHgwNl0sIC8vIEhlYWRlciBzaXplIGZvciBTTUZcblx0SEVBREVSX0NIVU5LX0ZPUk1BVDAgICAgOiBbMHgwMCwgMHgwMF0sIC8vIE1pZGkgVHlwZSAwIGlkXG5cdEhFQURFUl9DSFVOS19GT1JNQVQxICAgIDogWzB4MDAsIDB4MDFdLCAvLyBNaWRpIFR5cGUgMSBpZFxuXHRIRUFERVJfQ0hVTktfRElWSVNJT04gICA6IFsweDAwLCAweDgwXSwgLy8gRGVmYXVsdHMgdG8gMTI4IHRpY2tzIHBlciBiZWF0XG5cdFRSQUNLX0NIVU5LX1RZUEVcdFx0OiBbMHg0ZCwgMHg1NCwgMHg3MiwgMHg2Yl0sIC8vIE1UcmssXG5cdE1FVEFfRVZFTlRfSURcdFx0XHQ6IDB4RkYsXG5cdE1FVEFfVEVYVF9JRFx0XHRcdDogMHgwMSxcblx0TUVUQV9DT1BZUklHSFRfSURcdFx0OiAweDAyLFxuXHRNRVRBX1RSQUNLX05BTUVfSURcdFx0OiAweDAzLFxuXHRNRVRBX0lOU1RSVU1FTlRfTkFNRV9JRCA6IDB4MDQsXG5cdE1FVEFfTFlSSUNfSURcdFx0XHQ6IDB4MDUsXG5cdE1FVEFfTUFSS0VSX0lEXHRcdFx0OiAweDA2LFxuXHRNRVRBX0NVRV9QT0lOVFx0XHRcdDogMHgwNyxcblx0TUVUQV9URU1QT19JRFx0XHRcdDogMHg1MSxcblx0TUVUQV9TTVRQRV9PRkZTRVRcdFx0OiAweDU0LFxuXHRNRVRBX1RJTUVfU0lHTkFUVVJFX0lEXHQ6IDB4NTgsXG5cdE1FVEFfS0VZX1NJR05BVFVSRV9JRFx0OiAweDU5LFxuXHRNRVRBX0VORF9PRl9UUkFDS19JRFx0OiBbMHgyRiwgMHgwMF0sXG5cdENPTlRST0xMRVJfQ0hBTkdFX1NUQVRVUzogMHhCMCwgLy8gaW5jbHVkZXMgY2hhbm5lbCBudW1iZXIgKDApXG5cdFBST0dSQU1fQ0hBTkdFX1NUQVRVU1x0OiAweEMwLCAvLyBpbmNsdWRlcyBjaGFubmVsIG51bWJlciAoMClcbn07XG5cbmV4cG9ydCB7Q29uc3RhbnRzfTtcbi8qKlxuICogSG9sZHMgYWxsIGRhdGEgZm9yIGEgXCJjb250cm9sbGVyIGNoYW5nZVwiIE1JREkgZXZlbnRcbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMge2NvbnRyb2xsZXJOdW1iZXI6IGludGVnZXIsIGNvbnRyb2xsZXJWYWx1ZTogaW50ZWdlcn1cbiAqIEByZXR1cm4ge0NvbnRyb2xsZXJDaGFuZ2VFdmVudH1cbiAqL1xuY2xhc3MgQ29udHJvbGxlckNoYW5nZUV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy50eXBlID0gJ2NvbnRyb2xsZXInO1xuXHRcdC8vIGRlbHRhIHRpbWUgZGVmYXVsdHMgdG8gMC5cblx0XHR0aGlzLmRhdGEgPSBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKDB4MDApLmNvbmNhdChDb25zdGFudHMuQ09OVFJPTExFUl9DSEFOR0VfU1RBVFVTLCBmaWVsZHMuY29udHJvbGxlck51bWJlciwgZmllbGRzLmNvbnRyb2xsZXJWYWx1ZSk7XG5cdH1cbn1cblxuZXhwb3J0IHtDb250cm9sbGVyQ2hhbmdlRXZlbnR9O1xuLyoqXG4gKiBPYmplY3QgcmVwcmVzZW50YXRpb24gb2YgYSBtZXRhIGV2ZW50LlxuICogQHBhcmFtIHtvYmplY3R9IGZpZWxkcyAtIHR5cGUsIGRhdGFcbiAqIEByZXR1cm4ge01ldGFFdmVudH1cbiAqL1xuY2xhc3MgTWV0YUV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy50eXBlID0gJ21ldGEnO1xuXHRcdHRoaXMuZGF0YSA9IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoMHgwMCk7Ly8gU3RhcnQgd2l0aCB6ZXJvIHRpbWUgZGVsdGFcblx0XHR0aGlzLmRhdGEgPSB0aGlzLmRhdGEuY29uY2F0KENvbnN0YW50cy5NRVRBX0VWRU5UX0lELCBmaWVsZHMuZGF0YSk7XG5cdH1cbn1cblxuZXhwb3J0IHtNZXRhRXZlbnR9O1xuLyoqXG4gKiBXcmFwcGVyIGZvciBub3RlT25FdmVudC9ub3RlT2ZmRXZlbnQgb2JqZWN0cyB0aGF0IGJ1aWxkcyBib3RoIGV2ZW50cy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMgLSB7cGl0Y2g6ICdbQzRdJywgZHVyYXRpb246ICc0Jywgd2FpdDogJzQnLCB2ZWxvY2l0eTogMS0xMDB9XG4gKiBAcmV0dXJuIHtOb3RlRXZlbnR9XG4gKi9cbmNsYXNzIE5vdGVFdmVudCB7XG5cdGNvbnN0cnVjdG9yKGZpZWxkcykge1xuXHRcdHRoaXMudHlwZSBcdFx0PSAnbm90ZSc7XG5cdFx0dGhpcy5waXRjaCBcdFx0PSBVdGlscy50b0FycmF5KGZpZWxkcy5waXRjaCk7XG5cdFx0dGhpcy53YWl0IFx0XHQ9IGZpZWxkcy53YWl0IHx8IDA7XG5cdFx0dGhpcy5kdXJhdGlvbiBcdD0gZmllbGRzLmR1cmF0aW9uO1xuXHRcdHRoaXMuc2VxdWVudGlhbCA9IGZpZWxkcy5zZXF1ZW50aWFsIHx8IGZhbHNlO1xuXHRcdHRoaXMudmVsb2NpdHkgXHQ9IGZpZWxkcy52ZWxvY2l0eSB8fCA1MDtcblx0XHR0aGlzLmNoYW5uZWwgXHQ9IGZpZWxkcy5jaGFubmVsIHx8IDE7XG5cdFx0dGhpcy5yZXBlYXQgXHQ9IGZpZWxkcy5yZXBlYXQgfHwgMTtcblx0XHR0aGlzLnZlbG9jaXR5IFx0PSB0aGlzLmNvbnZlcnRWZWxvY2l0eSh0aGlzLnZlbG9jaXR5KTtcblx0XHR0aGlzLmdyYWNlXHRcdD0gZmllbGRzLmdyYWNlO1xuXHRcdHRoaXMuYnVpbGREYXRhKCk7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIGludCBhcnJheSBmb3IgdGhpcyBldmVudC5cblx0ICogQHJldHVybiB7Tm90ZUV2ZW50fVxuXHQgKi9cblx0YnVpbGREYXRhKCkge1xuXHRcdHRoaXMuZGF0YSA9IFtdO1xuXG5cdFx0dmFyIHRpY2tEdXJhdGlvbiA9IHRoaXMuZ2V0VGlja0R1cmF0aW9uKHRoaXMuZHVyYXRpb24sICdub3RlJyk7XG5cdFx0dmFyIHJlc3REdXJhdGlvbiA9IHRoaXMuZ2V0VGlja0R1cmF0aW9uKHRoaXMud2FpdCwgJ3Jlc3QnKTtcblxuXHRcdC8vIEFwcGx5IGdyYWNlIG5vdGUocykgYW5kIHN1YnRyYWN0IHRpY2tzIChjdXJyZW50bHkgMSB0aWNrIHBlciBncmFjZSBub3RlKSBmcm9tIHRpY2tEdXJhdGlvbiBzbyBuZXQgdmFsdWUgaXMgdGhlIHNhbWVcblx0XHRpZiAodGhpcy5ncmFjZSkge1xuXHRcdFx0bGV0IGdyYWNlRHVyYXRpb24gPSAxO1xuXHRcdFx0dGhpcy5ncmFjZSA9IFV0aWxzLnRvQXJyYXkodGhpcy5ncmFjZSk7XG5cdFx0XHR0aGlzLmdyYWNlLmZvckVhY2goZnVuY3Rpb24ocGl0Y2gpIHtcblx0XHRcdFx0bGV0IG5vdGVFdmVudCA9IG5ldyBOb3RlRXZlbnQoe3BpdGNoOnRoaXMuZ3JhY2UsIGR1cmF0aW9uOidUJyArIGdyYWNlRHVyYXRpb259KTtcblx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChub3RlRXZlbnQuZGF0YSlcblxuXHRcdFx0XHR0aWNrRHVyYXRpb24gLT0gZ3JhY2VEdXJhdGlvbjtcblx0XHRcdH0sIHRoaXMpO1xuXHRcdH1cblxuXHRcdC8vIGZpZWxkcy5waXRjaCBjb3VsZCBiZSBhbiBhcnJheSBvZiBwaXRjaGVzLlxuXHRcdC8vIElmIHNvIGNyZWF0ZSBub3RlIGV2ZW50cyBmb3IgZWFjaCBhbmQgYXBwbHkgdGhlIHNhbWUgZHVyYXRpb24uXG5cdFx0dmFyIG5vdGVPbiwgbm90ZU9mZjtcblx0XHRpZiAoQXJyYXkuaXNBcnJheSh0aGlzLnBpdGNoKSkge1xuXHRcdFx0Ly8gQnkgZGVmYXVsdCB0aGlzIGlzIGEgY2hvcmQgaWYgaXQncyBhbiBhcnJheSBvZiBub3RlcyB0aGF0IHJlcXVpcmVzIG9uZSBOb3RlT25FdmVudC5cblx0XHRcdC8vIElmIHRoaXMuc2VxdWVudGlhbCA9PT0gdHJ1ZSB0aGVuIGl0J3MgYSBzZXF1ZW50aWFsIHN0cmluZyBvZiBub3RlcyB0aGF0IHJlcXVpcmVzIHNlcGFyYXRlIE5vdGVPbkV2ZW50cy5cblx0XHRcdGlmICggISB0aGlzLnNlcXVlbnRpYWwpIHtcblx0XHRcdFx0Ly8gSGFuZGxlIHJlcGVhdFxuXHRcdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMucmVwZWF0OyBqKyspIHtcblx0XHRcdFx0XHQvLyBOb3RlIG9uXG5cdFx0XHRcdFx0dGhpcy5waXRjaC5mb3JFYWNoKGZ1bmN0aW9uKHAsIGkpIHtcblx0XHRcdFx0XHRcdGlmIChpID09IDApIHtcblx0XHRcdFx0XHRcdFx0bm90ZU9uID0gbmV3IE5vdGVPbkV2ZW50KHtkYXRhOiBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKHJlc3REdXJhdGlvbikuY29uY2F0KHRoaXMuZ2V0Tm90ZU9uU3RhdHVzKCksIFV0aWxzLmdldFBpdGNoKHApLCB0aGlzLnZlbG9jaXR5KX0pO1xuXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHQvLyBSdW5uaW5nIHN0YXR1cyAoY2FuIG9tbWl0IHRoZSBub3RlIG9uIHN0YXR1cylcblx0XHRcdFx0XHRcdFx0bm90ZU9uID0gbmV3IE5vdGVPbkV2ZW50KHtkYXRhOiBbMCwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHldfSk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQobm90ZU9uLmRhdGEpO1xuXHRcdFx0XHRcdH0sIHRoaXMpO1xuXG5cdFx0XHRcdFx0Ly8gTm90ZSBvZmZcblx0XHRcdFx0XHR0aGlzLnBpdGNoLmZvckVhY2goZnVuY3Rpb24ocCwgaSkge1xuXHRcdFx0XHRcdFx0aWYgKGkgPT0gMCkge1xuXHRcdFx0XHRcdFx0XHRub3RlT2ZmID0gbmV3IE5vdGVPZmZFdmVudCh7ZGF0YTogVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aCh0aWNrRHVyYXRpb24pLmNvbmNhdCh0aGlzLmdldE5vdGVPZmZTdGF0dXMoKSwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHkpfSk7XG5cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdC8vIFJ1bm5pbmcgc3RhdHVzIChjYW4gb21taXQgdGhlIG5vdGUgb2ZmIHN0YXR1cylcblx0XHRcdFx0XHRcdFx0bm90ZU9mZiA9IG5ldyBOb3RlT2ZmRXZlbnQoe2RhdGE6IFswLCBVdGlscy5nZXRQaXRjaChwKSwgdGhpcy52ZWxvY2l0eV19KTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChub3RlT2ZmLmRhdGEpO1xuXHRcdFx0XHRcdH0sIHRoaXMpO1xuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIEhhbmRsZSByZXBlYXRcblx0XHRcdFx0Zm9yICh2YXIgaiA9IDA7IGogPCB0aGlzLnJlcGVhdDsgaisrKSB7XG5cdFx0XHRcdFx0dGhpcy5waXRjaC5mb3JFYWNoKGZ1bmN0aW9uKHAsIGkpIHtcblx0XHRcdFx0XHRcdC8vIHJlc3REdXJhdGlvbiBvbmx5IGFwcGxpZXMgdG8gZmlyc3Qgbm90ZVxuXHRcdFx0XHRcdFx0aWYgKGkgPiAwKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3REdXJhdGlvbiA9IDA7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIElmIGR1cmF0aW9uIGlzIDh0aCB0cmlwbGV0cyB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSB0b3RhbCB0aWNrcyA9PSBxdWFydGVyIG5vdGUuXG5cdFx0XHRcdFx0XHQvLyBTbywgdGhlIGxhc3Qgb25lIHdpbGwgbmVlZCB0byBiZSB0aGUgcmVtYWluZGVyXG5cdFx0XHRcdFx0XHRpZiAodGhpcy5kdXJhdGlvbiA9PT0gJzh0JyAmJiBpID09IHRoaXMucGl0Y2gubGVuZ3RoIC0gMSkge1xuXHRcdFx0XHRcdFx0XHRsZXQgcXVhcnRlclRpY2tzID0gVXRpbHMubnVtYmVyRnJvbUJ5dGVzKENvbnN0YW50cy5IRUFERVJfQ0hVTktfRElWSVNJT04pO1xuXHRcdFx0XHRcdFx0XHR0aWNrRHVyYXRpb24gPSBxdWFydGVyVGlja3MgLSAodGlja0R1cmF0aW9uICogMik7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdG5vdGVPbiA9IG5ldyBOb3RlT25FdmVudCh7ZGF0YTogVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChyZXN0RHVyYXRpb24pLmNvbmNhdChbdGhpcy5nZXROb3RlT25TdGF0dXMoKSwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHldKX0pO1xuXHRcdFx0XHRcdFx0bm90ZU9mZiA9IG5ldyBOb3RlT2ZmRXZlbnQoe2RhdGE6IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgodGlja0R1cmF0aW9uKS5jb25jYXQoW3RoaXMuZ2V0Tm90ZU9mZlN0YXR1cygpLCBVdGlscy5nZXRQaXRjaChwKSwgdGhpcy52ZWxvY2l0eV0pfSk7XG5cblx0XHRcdFx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQobm90ZU9uLmRhdGEsIG5vdGVPZmYuZGF0YSk7XG5cdFx0XHRcdFx0fSwgdGhpcyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0dGhyb3cgJ3BpdGNoIG11c3QgYmUgYW4gYXJyYXkuJztcblx0fTtcblxuXHQvKipcblx0ICogQ29udmVydHMgdmVsb2NpdHkgdG8gdmFsdWUgMC0xMjdcblx0ICogQHBhcmFtIHtudW1iZXJ9IHZlbG9jaXR5IC0gVmVsb2NpdHkgdmFsdWUgMS0xMDBcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cblx0Y29udmVydFZlbG9jaXR5KHZlbG9jaXR5KSB7XG5cdFx0Ly8gTWF4IHBhc3NlZCB2YWx1ZSBsaW1pdGVkIHRvIDEwMFxuXHRcdHZlbG9jaXR5ID0gdmVsb2NpdHkgPiAxMDAgPyAxMDAgOiB2ZWxvY2l0eTtcblx0XHRyZXR1cm4gTWF0aC5yb3VuZCh2ZWxvY2l0eSAvIDEwMCAqIDEyNyk7XG5cdH07XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHRvdGFsIG51bWJlciBvZiB0aWNrcyBiYXNlZCBvbiBwYXNzZWQgZHVyYXRpb24uXG5cdCAqIE5vdGU6IHR5cGU9PSdub3RlJyBkZWZhdWx0cyB0byBxdWFydGVyIG5vdGUsIHR5cGU9PT0ncmVzdCcgZGVmYXVsdHMgdG8gMFxuXHQgKiBAcGFyYW0geyhzdHJpbmd8YXJyYXkpfSBkdXJhdGlvblxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBbJ25vdGUnLCAncmVzdCddXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdGdldFRpY2tEdXJhdGlvbihkdXJhdGlvbiwgdHlwZSkge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KGR1cmF0aW9uKSkge1xuXHRcdFx0Ly8gUmVjdXJzaXZlbHkgZXhlY3V0ZSB0aGlzIG1ldGhvZCBmb3IgZWFjaCBpdGVtIGluIHRoZSBhcnJheSBhbmQgcmV0dXJuIHRoZSBzdW0gb2YgdGljayBkdXJhdGlvbnMuXG5cdFx0XHRyZXR1cm4gZHVyYXRpb24ubWFwKGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLmdldFRpY2tEdXJhdGlvbih2YWx1ZSwgdHlwZSk7XG5cdFx0XHR9LCB0aGlzKS5yZWR1Y2UoZnVuY3Rpb24oYSwgYikge1xuXHRcdFx0XHRyZXR1cm4gYSArIGI7XG5cdFx0XHR9LCAwKTtcblx0XHR9XG5cblx0XHRkdXJhdGlvbiA9IGR1cmF0aW9uLnRvU3RyaW5nKCk7XG5cblx0XHRpZiAoZHVyYXRpb24udG9Mb3dlckNhc2UoKS5jaGFyQXQoMCkgPT09ICd0Jykge1xuXHRcdFx0Ly8gSWYgZHVyYXRpb24gc3RhcnRzIHdpdGggJ3QnIHRoZW4gdGhlIG51bWJlciB0aGF0IGZvbGxvd3MgaXMgYW4gZXhwbGljaXQgdGljayBjb3VudFxuXHRcdFx0cmV0dXJuIHBhcnNlSW50KGR1cmF0aW9uLnN1YnN0cmluZygxKSk7XG5cdFx0fVxuXG5cdFx0Ly8gTmVlZCB0byBhcHBseSBkdXJhdGlvbiBoZXJlLiAgUXVhcnRlciBub3RlID09IENvbnN0YW50cy5IRUFERVJfQ0hVTktfRElWSVNJT05cblx0XHQvLyBSb3VuZGluZyBvbmx5IGFwcGxpZXMgdG8gdHJpcGxldHMsIHdoaWNoIHRoZSByZW1haW5kZXIgaXMgaGFuZGxlZCBiZWxvd1xuXHRcdHZhciBxdWFydGVyVGlja3MgPSBVdGlscy5udW1iZXJGcm9tQnl0ZXMoQ29uc3RhbnRzLkhFQURFUl9DSFVOS19ESVZJU0lPTik7XG5cdFx0cmV0dXJuIE1hdGgucm91bmQocXVhcnRlclRpY2tzICogdGhpcy5nZXREdXJhdGlvbk11bHRpcGxpZXIoZHVyYXRpb24sIHR5cGUpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHdoYXQgdG8gbXVsdGlwbGUgdGlja3MvcXVhcnRlciBub3RlIGJ5IHRvIGdldCB0aGUgc3BlY2lmaWVkIGR1cmF0aW9uLlxuXHQgKiBOb3RlOiB0eXBlPT0nbm90ZScgZGVmYXVsdHMgdG8gcXVhcnRlciBub3RlLCB0eXBlPT09J3Jlc3QnIGRlZmF1bHRzIHRvIDBcblx0ICogQHBhcmFtIHtzdHJpbmd9IGR1cmF0aW9uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFsnbm90ZScsJ3Jlc3QnXVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXREdXJhdGlvbk11bHRpcGxpZXIoZHVyYXRpb24sIHR5cGUpIHtcblx0XHQvLyBOZWVkIHRvIGFwcGx5IGR1cmF0aW9uIGhlcmUuICBRdWFydGVyIG5vdGUgPT0gQ29uc3RhbnRzLkhFQURFUl9DSFVOS19ESVZJU0lPTlxuXHRcdHN3aXRjaCAoZHVyYXRpb24pIHtcblx0XHRcdGNhc2UgJzAnOlxuXHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdGNhc2UgJzEnOlxuXHRcdFx0XHRyZXR1cm4gNDtcblx0XHRcdGNhc2UgJzInOlxuXHRcdFx0XHRyZXR1cm4gMjtcblx0XHRcdGNhc2UgJ2QyJzpcblx0XHRcdFx0cmV0dXJuIDM7XG5cdFx0XHRjYXNlICc0Jzpcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHRjYXNlICc0dCc6XG5cdFx0XHRcdHJldHVybiAwLjY2Njtcblx0XHRcdGNhc2UgJ2Q0Jzpcblx0XHRcdFx0cmV0dXJuIDEuNTtcblx0XHRcdGNhc2UgJzgnOlxuXHRcdFx0XHRyZXR1cm4gMC41O1xuXHRcdFx0Y2FzZSAnOHQnOlxuXHRcdFx0XHQvLyBGb3IgOHRoIHRyaXBsZXRzLCBsZXQncyBkaXZpZGUgYSBxdWFydGVyIGJ5IDMsIHJvdW5kIHRvIHRoZSBuZWFyZXN0IGludCwgYW5kIHN1YnN0cmFjdCB0aGUgcmVtYWluZGVyIHRvIHRoZSBsYXN0IG9uZS5cblx0XHRcdFx0cmV0dXJuIDAuMzM7XG5cdFx0XHRjYXNlICdkOCc6XG5cdFx0XHRcdHJldHVybiAwLjc1O1xuXHRcdFx0Y2FzZSAnMTYnOlxuXHRcdFx0XHRyZXR1cm4gMC4yNTtcblx0XHRcdGNhc2UgJzE2dCc6XG5cdFx0XHRcdHJldHVybiAwLjE2Njtcblx0XHRcdGNhc2UgJzMyJzpcblx0XHRcdFx0cmV0dXJuIDAuMTI1O1xuXHRcdFx0Y2FzZSAnNjQnOlxuXHRcdFx0XHRyZXR1cm4gMC4wNjI1O1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0Ly8gTm90ZXMgZGVmYXVsdCB0byBhIHF1YXJ0ZXIsIHJlc3RzIGRlZmF1bHQgdG8gMFxuXHRcdFx0XHQvL3JldHVybiB0eXBlID09PSAnbm90ZScgPyAxIDogMDtcblx0XHR9XG5cblx0XHR0aHJvdyBkdXJhdGlvbiArICcgaXMgbm90IGEgdmFsaWQgZHVyYXRpb24uJztcblx0fTtcblxuXHQvKipcblx0ICogR2V0cyB0aGUgbm90ZSBvbiBzdGF0dXMgY29kZSBiYXNlZCBvbiB0aGUgc2VsZWN0ZWQgY2hhbm5lbC4gMHg5ezAtRn1cblx0ICogTm90ZSBvbiBhdCBjaGFubmVsIDAgaXMgMHg5MCAoMTQ0KVxuXHQgKiAwID0gQ2ggMVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXROb3RlT25TdGF0dXMoKSB7cmV0dXJuIDE0NCArIHRoaXMuY2hhbm5lbCAtIDF9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIG5vdGUgb2ZmIHN0YXR1cyBjb2RlIGJhc2VkIG9uIHRoZSBzZWxlY3RlZCBjaGFubmVsLiAweDh7MC1GfVxuXHQgKiBOb3RlIG9mZiBhdCBjaGFubmVsIDAgaXMgMHg4MCAoMTI4KVxuXHQgKiAwID0gQ2ggMVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXROb3RlT2ZmU3RhdHVzKCkge3JldHVybiAxMjggKyB0aGlzLmNoYW5uZWwgLSAxfVxufVxuXG5leHBvcnQge05vdGVFdmVudH07XG4vKipcbiAqIEhvbGRzIGFsbCBkYXRhIGZvciBhIFwibm90ZSBvZmZcIiBNSURJIGV2ZW50XG4gKiBAcGFyYW0ge29iamVjdH0gZmllbGRzIHtkYXRhOiBbXX1cbiAqIEByZXR1cm4ge05vdGVPZmZFdmVudH1cbiAqL1xuY2xhc3MgTm90ZU9mZkV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy5kYXRhID0gZmllbGRzLmRhdGE7XG5cdH1cbn1cblxuZXhwb3J0IHtOb3RlT2ZmRXZlbnR9O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSBcIm5vdGUgb25cIiBNSURJIGV2ZW50XG4gKiBAcGFyYW0ge29iamVjdH0gZmllbGRzIHtkYXRhOiBbXX1cbiAqIEByZXR1cm4ge05vdGVPbkV2ZW50fVxuICovXG5jbGFzcyBOb3RlT25FdmVudCB7XG5cdGNvbnN0cnVjdG9yKGZpZWxkcykge1xuXHRcdHRoaXMuZGF0YSA9IGZpZWxkcy5kYXRhO1xuXHR9XG59XG5cbmV4cG9ydCB7Tm90ZU9uRXZlbnR9O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSBcInByb2dyYW0gY2hhbmdlXCIgTUlESSBldmVudFxuICogQHBhcmFtIHtvYmplY3R9IGZpZWxkcyB7aW5zdHJ1bWVudDogaW50ZWdlcn1cbiAqIEByZXR1cm4ge1Byb2dyYW1DaGFuZ2VFdmVudH1cbiAqL1xuY2xhc3MgUHJvZ3JhbUNoYW5nZUV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy50eXBlID0gJ3Byb2dyYW0nO1xuXHRcdC8vIGRlbHRhIHRpbWUgZGVmYXVsdHMgdG8gMC5cblx0XHR0aGlzLmRhdGEgPSBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKDB4MDApLmNvbmNhdChDb25zdGFudHMuUFJPR1JBTV9DSEFOR0VfU1RBVFVTLCBmaWVsZHMuaW5zdHJ1bWVudCk7XG5cdH1cbn1cblxuZXhwb3J0IHtQcm9ncmFtQ2hhbmdlRXZlbnR9O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSB0cmFjay5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMge3R5cGU6IG51bWJlciwgZGF0YTogYXJyYXksIHNpemU6IGFycmF5LCBldmVudHM6IGFycmF5fVxuICogQHJldHVybiB7VHJhY2t9XG4gKi9cbmNsYXNzIFRyYWNrIHtcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0dGhpcy50eXBlID0gQ29uc3RhbnRzLlRSQUNLX0NIVU5LX1RZUEU7XG5cdFx0dGhpcy5kYXRhID0gW107XG5cdFx0dGhpcy5zaXplID0gW107XG5cdFx0dGhpcy5ldmVudHMgPSBbXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGFueSBldmVudCB0eXBlIHRvIHRoZSB0cmFjay5cblx0ICogQHBhcmFtIHsoTm90ZUV2ZW50fE1ldGFFdmVudHxQcm9ncmFtQ2hhbmdlRXZlbnQpfSBldmVudCAtIEV2ZW50IG9iamVjdC5cblx0ICogQHBhcmFtIHtmdW5jdGlvbn0gbWFwRnVuY3Rpb24gLSBDYWxsYmFjayB3aGljaCBjYW4gYmUgdXNlZCB0byBhcHBseSBzcGVjaWZpYyBwcm9wZXJ0aWVzIHRvIGFsbCBldmVudHMuIFxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZEV2ZW50KGV2ZW50LCBtYXBGdW5jdGlvbikge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KGV2ZW50KSkge1xuXHRcdFx0ZXZlbnQuZm9yRWFjaChmdW5jdGlvbihlLCBpKSB7XG5cdFx0XHRcdC8vIEhhbmRsZSBtYXAgZnVuY3Rpb24gaWYgcHJvdmlkZWRcblx0XHRcdFx0aWYgKHR5cGVvZiBtYXBGdW5jdGlvbiA9PT0gJ2Z1bmN0aW9uJyAmJiBlLnR5cGUgPT09ICdub3RlJykge1xuXHRcdFx0XHRcdHZhciBwcm9wZXJ0aWVzID0gbWFwRnVuY3Rpb24oaSwgZSk7XG5cblx0XHRcdFx0XHRpZiAodHlwZW9mIHByb3BlcnRpZXMgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdFx0XHRmb3IgKHZhciBqIGluIHByb3BlcnRpZXMpIHtcblx0XHRcdFx0XHRcdFx0c3dpdGNoKGopIHtcblx0XHRcdFx0XHRcdFx0XHRjYXNlICdkdXJhdGlvbic6XG5cdFx0XHRcdFx0XHRcdFx0XHRlLmR1cmF0aW9uID0gcHJvcGVydGllc1tqXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdGNhc2UgJ3NlcXVlbnRpYWwnOlxuXHRcdFx0XHRcdFx0XHRcdFx0ZS5zZXF1ZW50aWFsID0gcHJvcGVydGllc1tqXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdGNhc2UgJ3ZlbG9jaXR5Jzpcblx0XHRcdFx0XHRcdFx0XHRcdGUudmVsb2NpdHkgPSBlLmNvbnZlcnRWZWxvY2l0eShwcm9wZXJ0aWVzW2pdKTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XHRcdFxuXG5cdFx0XHRcdFx0XHQvLyBHb3R0YSBidWlsZCB0aGF0IGRhdGFcblx0XHRcdFx0XHRcdGUuYnVpbGREYXRhKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChlLmRhdGEpO1xuXHRcdFx0XHR0aGlzLnNpemUgPSBVdGlscy5udW1iZXJUb0J5dGVzKHRoaXMuZGF0YS5sZW5ndGgsIDQpOyAvLyA0IGJ5dGVzIGxvbmdcblx0XHRcdFx0dGhpcy5ldmVudHMucHVzaChlKTtcblx0XHRcdH0sIHRoaXMpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQoZXZlbnQuZGF0YSk7XG5cdFx0XHR0aGlzLnNpemUgPSBVdGlscy5udW1iZXJUb0J5dGVzKHRoaXMuZGF0YS5sZW5ndGgsIDQpOyAvLyA0IGJ5dGVzIGxvbmdcblx0XHRcdHRoaXMuZXZlbnRzLnB1c2goZXZlbnQpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGVtcG8gb2YgdGhlIE1JREkgZmlsZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGJwbSAtIFRlbXBvIGluIGJlYXRzIHBlciBtaW51dGUuXG5cdCAqIEByZXR1cm4ge1RyYWNrfVxuXHQgKi9cblx0c2V0VGVtcG8oYnBtKSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX1RFTVBPX0lEXX0pO1xuXHRcdGV2ZW50LmRhdGEucHVzaCgweDAzKTsgLy8gU2l6ZVxuXHRcdHZhciB0ZW1wbyA9IE1hdGgucm91bmQoNjAwMDAwMDAgLyBicG0pO1xuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKHRlbXBvLCAzKSk7IC8vIFRlbXBvLCAzIGJ5dGVzXG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGltZSBzaWduYXR1cmUuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBudW1lcmF0b3IgLSBUb3AgbnVtYmVyIG9mIHRoZSB0aW1lIHNpZ25hdHVyZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGRlbm9taW5hdG9yIC0gQm90dG9tIG51bWJlciBvZiB0aGUgdGltZSBzaWduYXR1cmUuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBtaWRpY2xvY2tzcGVydGljayAtIERlZmF1bHRzIHRvIDI0LlxuXHQgKiBAcGFyYW0ge251bWJlcn0gbm90ZXNwZXJtaWRpY2xvY2sgLSBEZWZhdWx0cyB0byA4LlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdHNldFRpbWVTaWduYXR1cmUobnVtZXJhdG9yLCBkZW5vbWluYXRvciwgbWlkaWNsb2Nrc3BlcnRpY2ssIG5vdGVzcGVybWlkaWNsb2NrKSB7XG5cdFx0bWlkaWNsb2Nrc3BlcnRpY2sgPSBtaWRpY2xvY2tzcGVydGljayB8fCAyNDtcblx0XHRub3Rlc3Blcm1pZGljbG9jayA9IG5vdGVzcGVybWlkaWNsb2NrIHx8IDg7XG5cdFx0XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX1RJTUVfU0lHTkFUVVJFX0lEXX0pO1xuXHRcdGV2ZW50LmRhdGEucHVzaCgweDA0KTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG51bWVyYXRvciwgMSkpOyAvLyBOdW1lcmF0b3IsIDEgYnl0ZXNcblx0XHRcblx0XHR2YXIgX2Rlbm9taW5hdG9yID0gTWF0aC5sb2cyKGRlbm9taW5hdG9yKTtcdC8vIERlbm9taW5hdG9yIGlzIGV4cHJlc3NlZCBhcyBwb3cgb2YgMlxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKF9kZW5vbWluYXRvciwgMSkpOyAvLyBEZW5vbWluYXRvciwgMSBieXRlc1xuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG1pZGljbG9ja3NwZXJ0aWNrLCAxKSk7IC8vIE1JREkgQ2xvY2tzIHBlciB0aWNrLCAxIGJ5dGVzXG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvQnl0ZXMobm90ZXNwZXJtaWRpY2xvY2ssIDEpKTsgLy8gTnVtYmVyIG9mIDEvMzIgbm90ZXMgcGVyIE1JREkgY2xvY2tzLCAxIGJ5dGVzXG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMga2V5IHNpZ25hdHVyZS5cblx0ICogQHBhcmFtIHsqfSBzZiAtIFxuXHQgKiBAcGFyYW0geyp9IG1pIC1cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRzZXRLZXlTaWduYXR1cmUoc2YsIG1pKSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX0tFWV9TSUdOQVRVUkVfSURdfSk7XG5cdFx0ZXZlbnQuZGF0YS5wdXNoKDB4MDIpOyAvLyBTaXplXG5cblx0XHR2YXIgbW9kZSA9IG1pIHx8IDA7XG5cdFx0c2YgPSBzZiB8fCAwO1xuXG5cdFx0Ly9cdEZ1bmN0aW9uIGNhbGxlZCB3aXRoIHN0cmluZyBub3RhdGlvblxuXHRcdGlmICh0eXBlb2YgbWkgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHR2YXIgZmlmdGhzID0gW1xuXHRcdFx0XHRbJ0NiJywgJ0diJywgJ0RiJywgJ0FiJywgJ0ViJywgJ0JiJywgJ0YnLCAnQycsICdHJywgJ0QnLCAnQScsICdFJywgJ0InLCAnRiMnLCAnQyMnXSxcblx0XHRcdFx0WydhYicsICdlYicsICdiYicsICdmJywgJ2MnLCAnZycsICdkJywgJ2EnLCAnZScsICdiJywgJ2YjJywgJ2MjJywgJ2cjJywgJ2QjJywgJ2EjJ11cblx0XHRcdF07XG5cdFx0XHR2YXIgX3NmbGVuID0gc2YubGVuZ3RoO1xuXHRcdFx0dmFyIG5vdGUgPSBzZiB8fCAnQyc7XG5cblx0XHRcdGlmIChzZlswXSA9PT0gc2ZbMF0udG9Mb3dlckNhc2UoKSkgbW9kZSA9IDFcblxuXHRcdFx0aWYgKF9zZmxlbiA+IDEpIHtcblx0XHRcdFx0c3dpdGNoIChzZi5jaGFyQXQoX3NmbGVuIC0gMSkpIHtcblx0XHRcdFx0XHRjYXNlICdtJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAxO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICctJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAxO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdNJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAwO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICcrJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAwO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgZmlmdGhpbmRleCA9IGZpZnRoc1ttb2RlXS5pbmRleE9mKG5vdGUpO1xuXHRcdFx0c2YgPSBmaWZ0aGluZGV4ID09PSAtMSA/IDAgOiBmaWZ0aGluZGV4IC0gNztcblx0XHR9XG5cblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9CeXRlcyhzZiwgMSkpOyAvLyBOdW1iZXIgb2Ygc2hhcnAgb3IgZmxhdHMgKCA8IDAgZmxhdDsgPiAwIHNoYXJwKVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG1vZGUsIDEpKTsgLy8gTW9kZTogMCBtYWpvciwgMSBtaW5vclxuXHRcdHJldHVybiB0aGlzLmFkZEV2ZW50KGV2ZW50KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIHRleHQgdG8gTUlESSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRleHQgdG8gYWRkLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZFRleHQodGV4dCkge1xuXHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoe2RhdGE6IFtDb25zdGFudHMuTUVUQV9URVhUX0lEXX0pO1xuXHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgY29weXJpZ2h0IHRvIE1JREkgZmlsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUZXh0IG9mIGNvcHlyaWdodCBsaW5lLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZENvcHlyaWdodCh0ZXh0KSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX0NPUFlSSUdIVF9JRF19KTtcblx0XHR2YXIgc3RyaW5nQnl0ZXMgPSBVdGlscy5zdHJpbmdUb0J5dGVzKHRleHQpO1xuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKHN0cmluZ0J5dGVzLmxlbmd0aCkpOyAvLyBTaXplXG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KHN0cmluZ0J5dGVzKTsgLy8gVGV4dFxuXHRcdHJldHVybiB0aGlzLmFkZEV2ZW50KGV2ZW50KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIFNlcXVlbmNlL1RyYWNrIE5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGV4dCBvZiB0cmFjayBuYW1lLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZFRyYWNrTmFtZSh0ZXh0KSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX1RSQUNLX05BTUVfSURdfSk7XG5cdFx0dmFyIHN0cmluZ0J5dGVzID0gVXRpbHMuc3RyaW5nVG9CeXRlcyh0ZXh0KTtcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIFRleHRcblx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBpbnN0cnVtZW50IG5hbWUgb2YgdHJhY2suXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gTmFtZSBvZiBpbnN0cnVtZW50LlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZEluc3RydW1lbnROYW1lKHRleHQpIHtcblx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHtkYXRhOiBbQ29uc3RhbnRzLk1FVEFfSU5TVFJVTUVOVF9OQU1FX0lEXX0pO1xuXHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgbWFya2VyIHRvIE1JREkgZmlsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBNYXJrZXIgdGV4dC5cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRhZGRNYXJrZXIodGV4dCkge1xuXHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoe2RhdGE6IFtDb25zdGFudHMuTUVUQV9NQVJLRVJfSURdfSk7XG5cdFx0dmFyIHN0cmluZ0J5dGVzID0gVXRpbHMuc3RyaW5nVG9CeXRlcyh0ZXh0KTtcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIFRleHRcblx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBjdWUgcG9pbnQgdG8gTUlESSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRleHQgb2YgY3VlIHBvaW50LlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZEN1ZVBvaW50KHRleHQpIHtcblx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHtkYXRhOiBbQ29uc3RhbnRzLk1FVEFfQ1VFX1BPSU5UXX0pO1xuXHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgbHlyaWMgdG8gTUlESSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbHlyaWMgLSBMeXJpYyB0ZXh0IHRvIGFkZC5cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRhZGRMeXJpYyhseXJpYykge1xuXHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoe2RhdGE6IFtDb25zdGFudHMuTUVUQV9MWVJJQ19JRF19KTtcblx0XHR2YXIgc3RyaW5nQnl0ZXMgPSBVdGlscy5zdHJpbmdUb0J5dGVzKGx5cmljKTtcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIEx5cmljXG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoYW5uZWwgbW9kZSBtZXNzYWdlc1xuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdHBvbHlNb2RlT24oKSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE5vdGVPbkV2ZW50KHtkYXRhOiBbMHgwMCwgMHhCMCwgMHg3RSwgMHgwMF19KTtcblx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdH1cblxufVxuXG5leHBvcnQge1RyYWNrfTtcbmltcG9ydCB7dG9NaWRpfSBmcm9tICd0b25hbC1taWRpJztcblxuLyoqXG4gKiBTdGF0aWMgdXRpbGl0eSBmdW5jdGlvbnMgdXNlZCB0aHJvdWdob3V0IHRoZSBsaWJyYXJ5LlxuICovXG5jbGFzcyBVdGlscyB7XG5cblx0LyoqXG5cdCAqIEdldHMgTWlkaVdyaXRlckpTIHZlcnNpb24gbnVtYmVyLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRzdGF0aWMgdmVyc2lvbigpIHtcblx0XHRyZXR1cm4gQ29uc3RhbnRzLlZFUlNJT047XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydCBhIHN0cmluZyB0byBhbiBhcnJheSBvZiBieXRlc1xuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG5cdCAqIEByZXR1cm4ge2FycmF5fVxuXHQgKi9cblx0c3RhdGljIHN0cmluZ1RvQnl0ZXMoc3RyaW5nKSB7XG5cdFx0cmV0dXJuIHN0cmluZy5zcGxpdCgnJykubWFwKGNoYXIgPT4gY2hhci5jaGFyQ29kZUF0KCkpXG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIGFyZ3VtZW50IGlzIGEgdmFsaWQgbnVtYmVyLlxuXHQgKiBAcGFyYW0geyp9IG4gLSBWYWx1ZSB0byBjaGVja1xuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0c3RhdGljIGlzTnVtZXJpYyhuKSB7XG5cdFx0cmV0dXJuICFpc05hTihwYXJzZUZsb2F0KG4pKSAmJiBpc0Zpbml0ZShuKVxuXHR9XG5cblx0LyoqXG4gICAgICogUmV0dXJucyB0aGUgY29ycmVjdCBNSURJIG51bWJlciBmb3IgdGhlIHNwZWNpZmllZCBwaXRjaC5cbiAgICAgKiBVc2VzIFRvbmFsIE1pZGkgLSBodHRwczovL2dpdGh1Yi5jb20vZGFuaWdiL3RvbmFsL3RyZWUvbWFzdGVyL3BhY2thZ2VzL21pZGlcbiAgICAgKiBAcGFyYW0geyhzdHJpbmd8bnVtYmVyKX0gcGl0Y2ggLSAnQyM0JyBvciBtaWRpIG5vdGUgY29kZVxuICAgICAqIEByZXR1cm4ge251bWJlcn1cbiAgICAgKi9cbiAgICAgc3RhdGljIGdldFBpdGNoKHBpdGNoKSB7XG4gICAgIFx0cmV0dXJuIHRvTWlkaShwaXRjaCk7XG4gICAgIH1cblxuXHQvKipcblx0ICogVHJhbnNsYXRlcyBudW1iZXIgb2YgdGlja3MgdG8gTUlESSB0aW1lc3RhbXAgZm9ybWF0LCByZXR1cm5pbmcgYW4gYXJyYXkgb2Zcblx0ICogaGV4IHN0cmluZ3Mgd2l0aCB0aGUgdGltZSB2YWx1ZXMuIE1pZGkgaGFzIGEgdmVyeSBwYXJ0aWN1bGFyIHRpbWUgdG8gZXhwcmVzcyB0aW1lLFxuXHQgKiB0YWtlIGEgZ29vZCBsb29rIGF0IHRoZSBzcGVjIGJlZm9yZSBldmVyIHRvdWNoaW5nIHRoaXMgZnVuY3Rpb24uXG5cdCAqIFRoYW5rcyB0byBodHRwczovL2dpdGh1Yi5jb20vc2VyZ2kvanNtaWRpXG5cdCAqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB0aWNrcyAtIE51bWJlciBvZiB0aWNrcyB0byBiZSB0cmFuc2xhdGVkXG5cdCAqIEByZXR1cm4ge2FycmF5fSAtIEJ5dGVzIHRoYXQgZm9ybSB0aGUgTUlESSB0aW1lIHZhbHVlXG5cdCAqL1xuXHRzdGF0aWMgbnVtYmVyVG9WYXJpYWJsZUxlbmd0aCh0aWNrcykge1xuXHQgICAgdmFyIGJ1ZmZlciA9IHRpY2tzICYgMHg3RjtcblxuXHQgICAgd2hpbGUgKHRpY2tzID0gdGlja3MgPj4gNykge1xuXHQgICAgICAgIGJ1ZmZlciA8PD0gODtcblx0ICAgICAgICBidWZmZXIgfD0gKCh0aWNrcyAmIDB4N0YpIHwgMHg4MCk7XG5cdCAgICB9XG5cblx0ICAgIHZhciBiTGlzdCA9IFtdO1xuXHQgICAgd2hpbGUgKHRydWUpIHtcblx0ICAgICAgICBiTGlzdC5wdXNoKGJ1ZmZlciAmIDB4ZmYpO1xuXG5cdCAgICAgICAgaWYgKGJ1ZmZlciAmIDB4ODApIGJ1ZmZlciA+Pj0gOFxuXHQgICAgICAgIGVsc2UgeyBicmVhazsgfVxuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gYkxpc3Q7XG5cdH1cblxuXHQvKipcblx0ICogQ291bnRzIG51bWJlciBvZiBieXRlcyBpbiBzdHJpbmdcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNcblx0ICogQHJldHVybiB7YXJyYXl9XG5cdCAqL1xuXHRzdGF0aWMgc3RyaW5nQnl0ZUNvdW50KHMpIHtcblx0XHRyZXR1cm4gZW5jb2RlVVJJKHMpLnNwbGl0KC8lLi58Li8pLmxlbmd0aCAtIDFcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgYW4gaW50IGZyb20gYW4gYXJyYXkgb2YgYnl0ZXMuXG5cdCAqIEBwYXJhbSB7YXJyYXl9IGJ5dGVzXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdHN0YXRpYyBudW1iZXJGcm9tQnl0ZXMoYnl0ZXMpIHtcblx0XHR2YXIgaGV4ID0gJyc7XG5cdFx0dmFyIHN0cmluZ1Jlc3VsdDtcblxuXHRcdGJ5dGVzLmZvckVhY2goZnVuY3Rpb24oYnl0ZSkge1xuXHRcdFx0c3RyaW5nUmVzdWx0ID0gYnl0ZS50b1N0cmluZygxNik7XG5cblx0XHRcdC8vIGVuc3VyZSBzdHJpbmcgaXMgMiBjaGFyc1xuXHRcdFx0aWYgKHN0cmluZ1Jlc3VsdC5sZW5ndGggPT0gMSkgc3RyaW5nUmVzdWx0ID0gXCIwXCIgKyBzdHJpbmdSZXN1bHRcblxuXHRcdFx0aGV4ICs9IHN0cmluZ1Jlc3VsdDtcblx0XHR9KTtcblxuXHRcdHJldHVybiBwYXJzZUludChoZXgsIDE2KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUYWtlcyBhIG51bWJlciBhbmQgc3BsaXRzIGl0IHVwIGludG8gYW4gYXJyYXkgb2YgYnl0ZXMuICBDYW4gYmUgcGFkZGVkIGJ5IHBhc3NpbmcgYSBudW1iZXIgdG8gYnl0ZXNOZWVkZWRcblx0ICogQHBhcmFtIHtudW1iZXJ9IG51bWJlclxuXHQgKiBAcGFyYW0ge251bWJlcn0gYnl0ZXNOZWVkZWRcblx0ICogQHJldHVybiB7YXJyYXl9IC0gQXJyYXkgb2YgYnl0ZXNcblx0ICovXG5cdHN0YXRpYyBudW1iZXJUb0J5dGVzKG51bWJlciwgYnl0ZXNOZWVkZWQpIHtcblx0XHRieXRlc05lZWRlZCA9IGJ5dGVzTmVlZGVkIHx8IDE7XG5cblx0XHR2YXIgaGV4U3RyaW5nID0gbnVtYmVyLnRvU3RyaW5nKDE2KTtcblxuXHRcdGlmIChoZXhTdHJpbmcubGVuZ3RoICYgMSkgeyAvLyBNYWtlIHN1cmUgaGV4IHN0cmluZyBpcyBldmVuIG51bWJlciBvZiBjaGFyc1xuXHRcdFx0aGV4U3RyaW5nID0gJzAnICsgaGV4U3RyaW5nO1xuXHRcdH1cblxuXHRcdC8vIFNwbGl0IGhleCBzdHJpbmcgaW50byBhbiBhcnJheSBvZiB0d28gY2hhciBlbGVtZW50c1xuXHRcdHZhciBoZXhBcnJheSA9IGhleFN0cmluZy5tYXRjaCgvLnsyfS9nKTtcblxuXHRcdC8vIE5vdyBwYXJzZSB0aGVtIG91dCBhcyBpbnRlZ2Vyc1xuXHRcdGhleEFycmF5ID0gaGV4QXJyYXkubWFwKGl0ZW0gPT4gcGFyc2VJbnQoaXRlbSwgMTYpKVxuXG5cdFx0Ly8gUHJlcGVuZCBlbXB0eSBieXRlcyBpZiB3ZSBkb24ndCBoYXZlIGVub3VnaFxuXHRcdGlmIChoZXhBcnJheS5sZW5ndGggPCBieXRlc05lZWRlZCkge1xuXHRcdFx0d2hpbGUgKGJ5dGVzTmVlZGVkIC0gaGV4QXJyYXkubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRoZXhBcnJheS51bnNoaWZ0KDApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBoZXhBcnJheTtcblx0fVxuXG5cdC8qKlx0XG5cdCAqIENvbnZlcnRzIHZhbHVlIHRvIGFycmF5IGlmIG5lZWRlZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG5cdCAqIEByZXR1cm4ge2FycmF5fVxuXHQgKi9cblx0c3RhdGljIHRvQXJyYXkodmFsdWUpIHtcblx0XHRpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB2YWx1ZTtcblx0XHRyZXR1cm4gW3ZhbHVlXTtcblx0fVxufVxuXG5leHBvcnQge1V0aWxzfTtcbmNsYXNzIFZleEZsb3cge1xuXHRcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0Ly8gY29kZS4uLlxuXHR9XG5cblx0LyoqXG5cdCAqIFN1cHBvcnQgZm9yIGNvbnZlcnRpbmcgVmV4RmxvdyB2b2ljZSBpbnRvIE1pZGlXcml0ZXJKUyB0cmFja1xuXHQgKiBAcmV0dXJuIE1pZGlXcml0aWVyLlRyYWNrIG9iamVjdFxuXHQgKi9cblx0dHJhY2tGcm9tVm9pY2Uodm9pY2UpIHtcblx0XHR2YXIgdHJhY2sgPSBuZXcgVHJhY2soKTtcblx0XHR2YXIgd2FpdDtcblx0XHR2YXIgcGl0Y2hlcyA9IFtdO1xuXG5cdFx0dm9pY2UudGlja2FibGVzLmZvckVhY2goZnVuY3Rpb24odGlja2FibGUpIHtcblx0XHRcdHBpdGNoZXMgPSBbXTtcblxuXHRcdFx0aWYgKHRpY2thYmxlLm5vdGVUeXBlID09PSAnbicpIHtcblx0XHRcdFx0dGlja2FibGUua2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuXHRcdFx0XHRcdC8vIGJ1aWxkIGFycmF5IG9mIHBpdGNoZXNcblx0XHRcdFx0XHRwaXRjaGVzLnB1c2godGhpcy5jb252ZXJ0UGl0Y2goa2V5KSk7XG5cdFx0XHRcdH0pO1xuXG5cdFx0XHR9IGVsc2UgaWYgKHRpY2thYmxlLm5vdGVUeXBlID09PSAncicpIHtcblx0XHRcdFx0Ly8gbW92ZSBvbiB0byB0aGUgbmV4dCB0aWNrYWJsZSBhbmQgdXNlIHRoaXMgcmVzdCBhcyBhIGB3YWl0YCBwcm9wZXJ0eSBmb3IgdGhlIG5leHQgZXZlbnRcblx0XHRcdFx0d2FpdCA9IHRoaXMuY29udmVydER1cmF0aW9uKHRpY2thYmxlKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR0cmFjay5hZGRFdmVudChuZXcgTm90ZUV2ZW50KHtwaXRjaDogcGl0Y2hlcywgZHVyYXRpb246IHRoaXMuY29udmVydER1cmF0aW9uKHRpY2thYmxlKSwgd2FpdDogd2FpdH0pKTtcblx0XHRcdFxuXHRcdFx0Ly8gcmVzZXQgd2FpdFxuXHRcdFx0d2FpdCA9IDA7XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gdHJhY2s7XG5cdH1cblxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBWZXhGbG93IHBpdGNoIHN5bnRheCB0byBNaWRpV3JpdGVySlMgc3ludGF4XG5cdCAqIEBwYXJhbSBwaXRjaCBzdHJpbmdcblx0ICovXG5cdGNvbnZlcnRQaXRjaChwaXRjaCkge1xuXHRcdHJldHVybiBwaXRjaC5yZXBsYWNlKCcvJywgJycpO1xuXHR9IFxuXG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIFZleEZsb3cgZHVyYXRpb24gc3ludGF4IHRvIE1pZGlXcml0ZXJKUyBzeW50YXhcblx0ICogQHBhcmFtIG5vdGUgc3RydWN0IGZyb20gVmV4Rmxvd1xuXHQgKi9cblx0Y29udmVydER1cmF0aW9uKG5vdGUpIHtcblx0XHRzd2l0Y2ggKG5vdGUuZHVyYXRpb24pIHtcblx0XHRcdGNhc2UgJ3cnOlxuXHRcdFx0XHRyZXR1cm4gJzEnO1xuXHRcdFx0Y2FzZSAnaCc6XG5cdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDInIDogJzInO1xuXHRcdFx0Y2FzZSAncSc6XG5cdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDQnIDogJzQnO1xuXHRcdFx0Y2FzZSAnOCc6XG5cdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDgnIDogJzgnO1xuXHRcdH1cblxuXHRcdHJldHVybiBub3RlLmR1cmF0aW9uO1xuXHR9O1xufVxuXG5leHBvcnQge1ZleEZsb3d9O1xuLyoqXG4gKiBPYmplY3QgdGhhdCBwdXRzIHRvZ2V0aGVyIHRyYWNrcyBhbmQgcHJvdmlkZXMgbWV0aG9kcyBmb3IgZmlsZSBvdXRwdXQuXG4gKiBAcGFyYW0ge2FycmF5fSB0cmFja3MgLSBBbiBhcnJheSBvZiB7VHJhY2t9IG9iamVjdHMuXG4gKiBAcmV0dXJuIHtXcml0ZXJ9XG4gKi9cbmNsYXNzIFdyaXRlciB7XG5cdGNvbnN0cnVjdG9yKHRyYWNrcykge1xuXHRcdHRoaXMuZGF0YSA9IFtdO1xuXG5cdFx0dmFyIHRyYWNrVHlwZSA9IHRyYWNrcy5sZW5ndGggPiAxID8gQ29uc3RhbnRzLkhFQURFUl9DSFVOS19GT1JNQVQxIDogQ29uc3RhbnRzLkhFQURFUl9DSFVOS19GT1JNQVQwO1xuXHRcdHZhciBudW1iZXJPZlRyYWNrcyA9IFV0aWxzLm51bWJlclRvQnl0ZXModHJhY2tzLmxlbmd0aCwgMik7IC8vIHR3byBieXRlcyBsb25nXG5cblx0XHQvLyBIZWFkZXIgY2h1bmtcblx0XHR0aGlzLmRhdGEucHVzaChuZXcgQ2h1bmsoe1xuXHRcdFx0XHRcdFx0XHRcdHR5cGU6IENvbnN0YW50cy5IRUFERVJfQ0hVTktfVFlQRSxcblx0XHRcdFx0XHRcdFx0XHRkYXRhOiB0cmFja1R5cGUuY29uY2F0KG51bWJlck9mVHJhY2tzLCBDb25zdGFudHMuSEVBREVSX0NIVU5LX0RJVklTSU9OKX0pKTtcblxuXHRcdC8vIFRyYWNrIGNodW5rc1xuXHRcdHRyYWNrcy5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrLCBpKSB7XG5cdFx0XHR0cmFjay5hZGRFdmVudChuZXcgTWV0YUV2ZW50KHtkYXRhOiBDb25zdGFudHMuTUVUQV9FTkRfT0ZfVFJBQ0tfSUR9KSk7XG5cdFx0XHR0aGlzLmRhdGEucHVzaCh0cmFjayk7XG5cdFx0fSwgdGhpcyk7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIHRoZSBmaWxlIGludG8gYSBVaW50OEFycmF5XG5cdCAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9XG5cdCAqL1xuXHRidWlsZEZpbGUoKSB7XG5cdFx0dmFyIGJ1aWxkID0gW107XG5cblx0XHQvLyBEYXRhIGNvbnNpc3RzIG9mIGNodW5rcyB3aGljaCBjb25zaXN0cyBvZiBkYXRhXG5cdFx0dGhpcy5kYXRhLmZvckVhY2goKGQpID0+IGJ1aWxkID0gYnVpbGQuY29uY2F0KGQudHlwZSwgZC5zaXplLCBkLmRhdGEpKTtcblxuXHRcdHJldHVybiBuZXcgVWludDhBcnJheShidWlsZCk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydCBmaWxlIGJ1ZmZlciB0byBhIGJhc2U2NCBzdHJpbmcuICBEaWZmZXJlbnQgbWV0aG9kcyBkZXBlbmRpbmcgb24gaWYgYnJvd3NlciBvciBub2RlLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRiYXNlNjQoKSB7XG5cdFx0aWYgKHR5cGVvZiBidG9hID09PSAnZnVuY3Rpb24nKSByZXR1cm4gYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIHRoaXMuYnVpbGRGaWxlKCkpKTtcblx0XHRyZXR1cm4gbmV3IEJ1ZmZlcih0aGlzLmJ1aWxkRmlsZSgpKS50b1N0cmluZygnYmFzZTY0Jyk7XG5cdH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZGF0YSBVUkkuXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqL1xuICAgIGRhdGFVcmkoKSB7XG4gICAgXHRyZXR1cm4gJ2RhdGE6YXVkaW8vbWlkaTtiYXNlNjQsJyArIHRoaXMuYmFzZTY0KCk7XG4gICAgfVxuXG5cdC8qKlxuXHQgKiBPdXRwdXQgdG8gc3Rkb3V0XG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG4gICAgc3Rkb3V0KCkge1xuICAgIFx0cmV0dXJuIHByb2Nlc3Muc3Rkb3V0LndyaXRlKG5ldyBCdWZmZXIodGhpcy5idWlsZEZpbGUoKSkpO1xuICAgIH1cblxuXHQvKipcblx0ICogU2F2ZSB0byBNSURJIGZpbGVcblx0ICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lXG5cdCAqL1xuXHRzYXZlTUlESShmaWxlbmFtZSkge1xuXHRcdHZhciBidWZmZXIgPSBuZXcgQnVmZmVyKHRoaXMuYnVpbGRGaWxlKCkpO1xuXHRcdGZzLndyaXRlRmlsZShmaWxlbmFtZSArICcubWlkJywgYnVmZmVyLCBmdW5jdGlvbiAoZXJyKSB7XG5cdFx0XHRpZihlcnIpIHJldHVybiBjb25zb2xlLmxvZyhlcnIpO1xuXHRcdH0pO1xuXHR9XG59XG5cbmV4cG9ydCB7V3JpdGVyfTtcbiJdfQ== -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3).Buffer, __webpack_require__(10))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3).Buffer, __webpack_require__(11))) /***/ }), -/* 136 */ +/* 141 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -44886,14 +44984,14 @@ function oct (src) { return (parse(src) || {}).oct } /***/ }), -/* 137 */ +/* 142 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = __webpack_require__(11); +module.exports = __webpack_require__(12); /***/ }), -/* 138 */ +/* 143 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44905,10 +45003,10 @@ module.exports = __webpack_require__(11); module.exports = PassThrough; -var Transform = __webpack_require__(67); +var Transform = __webpack_require__(73); /*<replacement>*/ -var util = __webpack_require__(19); +var util = __webpack_require__(22); util.inherits = __webpack_require__(16); /*</replacement>*/ @@ -44925,7 +45023,7 @@ PassThrough.prototype._transform = function (chunk, encoding, cb) { }; /***/ }), -/* 139 */ +/* 144 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44933,7 +45031,7 @@ PassThrough.prototype._transform = function (chunk, encoding, cb) { var Buffer = __webpack_require__(3).Buffer; /*<replacement>*/ -var bufferShim = __webpack_require__(31); +var bufferShim = __webpack_require__(32); /*</replacement>*/ module.exports = BufferList; @@ -44995,28 +45093,28 @@ BufferList.prototype.concat = function (n) { }; /***/ }), -/* 140 */ +/* 145 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = __webpack_require__(49).PassThrough +module.exports = __webpack_require__(51).PassThrough /***/ }), -/* 141 */ +/* 146 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = __webpack_require__(49).Transform +module.exports = __webpack_require__(51).Transform /***/ }), -/* 142 */ +/* 147 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = __webpack_require__(48); +module.exports = __webpack_require__(50); /***/ }), -/* 143 */ +/* 148 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) { @@ -45206,10 +45304,10 @@ module.exports = __webpack_require__(48); attachTo.clearImmediate = clearImmediate; }(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self)); -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(20), __webpack_require__(10))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(23), __webpack_require__(11))) /***/ }), -/* 144 */ +/* 149 */ /***/ (function(module, exports, __webpack_require__) { // Copyright Joyent, Inc. and other Node contributors. @@ -45235,15 +45333,15 @@ module.exports = __webpack_require__(48); module.exports = Stream; -var EE = __webpack_require__(45).EventEmitter; +var EE = __webpack_require__(47).EventEmitter; var inherits = __webpack_require__(16); inherits(Stream, EE); -Stream.Readable = __webpack_require__(49); -Stream.Writable = __webpack_require__(142); -Stream.Duplex = __webpack_require__(137); -Stream.Transform = __webpack_require__(141); -Stream.PassThrough = __webpack_require__(140); +Stream.Readable = __webpack_require__(51); +Stream.Writable = __webpack_require__(147); +Stream.Duplex = __webpack_require__(142); +Stream.Transform = __webpack_require__(146); +Stream.PassThrough = __webpack_require__(145); // Backwards-compat with node 0.4.x Stream.Stream = Stream; @@ -45342,12 +45440,12 @@ Stream.prototype.pipe = function(dest, options) { /***/ }), -/* 145 */ +/* 150 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_note_parser__ = __webpack_require__(136); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_note_parser__ = __webpack_require__(141); /* harmony export (immutable) */ __webpack_exports__["toMidi"] = toMidi; /* harmony export (immutable) */ __webpack_exports__["note"] = note; /** @@ -45414,7 +45512,7 @@ function note (num, sharps) { /***/ }), -/* 146 */ +/* 151 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global) { @@ -45485,10 +45583,10 @@ function config (name) { return String(val).toLowerCase() === 'true'; } -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(20))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(23))) /***/ }), -/* 147 */ +/* 152 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -45517,7 +45615,7 @@ if (typeof Object.create === 'function') { /***/ }), -/* 148 */ +/* 153 */ /***/ (function(module, exports) { module.exports = function isBuffer(arg) { @@ -45528,7 +45626,7 @@ module.exports = function isBuffer(arg) { } /***/ }), -/* 149 */ +/* 154 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors. @@ -46056,7 +46154,7 @@ function isPrimitive(arg) { } exports.isPrimitive = isPrimitive; -exports.isBuffer = __webpack_require__(148); +exports.isBuffer = __webpack_require__(153); function objectToString(o) { return Object.prototype.toString.call(o); @@ -46100,7 +46198,7 @@ exports.log = function() { * prototype. * @param {function} superCtor Constructor function to inherit prototype from. */ -exports.inherits = __webpack_require__(147); +exports.inherits = __webpack_require__(152); exports._extend = function(origin, add) { // Don't do anything if add isn't an object @@ -46118,10 +46216,10 @@ function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(20), __webpack_require__(10))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(23), __webpack_require__(11))) /***/ }), -/* 150 */ +/* 155 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* @@ -46158,7 +46256,7 @@ var that=this;if(options=options||{},program=Math.floor(program),isNaN(program)| __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):"undefined"!=typeof module&&module.exports?module.exports=wm:scope.WebMidi||(scope.WebMidi=wm)}(this); /***/ }), -/* 151 */ +/* 156 */ /***/ (function(module, exports) { module.exports = function() {
@@ -46167,7 +46265,7 @@ module.exports = function() { /***/ }), -/* 152 */ +/* 157 */ /***/ (function(module, exports) { /* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {/* globals __webpack_amd_options__ */
@@ -46176,102 +46274,11 @@ module.exports = __webpack_amd_options__; /* WEBPACK VAR INJECTION */}.call(exports, {})) /***/ }), -/* 153 */ +/* 158 */ /***/ (function(module, exports) { /* (ignored) */ -/***/ }), -/* 154 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _from = __webpack_require__(155); - -var _from2 = _interopRequireDefault(_from); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -exports.default = function (arr) { - return Array.isArray(arr) ? arr : (0, _from2.default)(arr); -}; - -/***/ }), -/* 155 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = { "default": __webpack_require__(156), __esModule: true }; - -/***/ }), -/* 156 */ -/***/ (function(module, exports, __webpack_require__) { - -__webpack_require__(28); -__webpack_require__(158); -module.exports = __webpack_require__(1).Array.from; - -/***/ }), -/* 157 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var $defineProperty = __webpack_require__(8) - , createDesc = __webpack_require__(25); - -module.exports = function(object, index, value){ - if(index in object)$defineProperty.f(object, index, createDesc(0, value)); - else object[index] = value; -}; - -/***/ }), -/* 158 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var ctx = __webpack_require__(22) - , $export = __webpack_require__(12) - , toObject = __webpack_require__(41) - , call = __webpack_require__(105) - , isArrayIter = __webpack_require__(103) - , toLength = __webpack_require__(62) - , createProperty = __webpack_require__(157) - , getIterFn = __webpack_require__(63); - -$export($export.S + $export.F * !__webpack_require__(107)(function(iter){ Array.from(iter); }), 'Array', { - // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined) - from: function from(arrayLike/*, mapfn = undefined, thisArg = undefined*/){ - var O = toObject(arrayLike) - , C = typeof this == 'function' ? this : Array - , aLen = arguments.length - , mapfn = aLen > 1 ? arguments[1] : undefined - , mapping = mapfn !== undefined - , index = 0 - , iterFn = getIterFn(O) - , length, result, step, iterator; - if(mapping)mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2); - // if object isn't iterable or it's array with default iterator - use simple case - if(iterFn != undefined && !(C == Array && isArrayIter(iterFn))){ - for(iterator = iterFn.call(O), result = new C; !(step = iterator.next()).done; index++){ - createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value); - } - } else { - length = toLength(O.length); - for(result = new C(length); length > index; index++){ - createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]); - } - } - result.length = index; - return result; - } -}); - - /***/ }) /******/ ]); //# sourceMappingURL=bundle.js.map
\ No newline at end of file diff --git a/bundle.js.map b/bundle.js.map index 0eca250..4b2a153 100644 --- a/bundle.js.map +++ b/bundle.js.map @@ -1 +1 @@ -{"version":3,"file":"./bundle.js","sources":["webpack:///webpack/bootstrap 3f67a584b1dc586b4445","webpack:///../inequality/~/core-js/library/modules/_wks.js","webpack:///../inequality/~/core-js/library/modules/_core.js","webpack:///../inequality/~/core-js/library/modules/_global.js","webpack:///../inequality/~/buffer/index.js","webpack:///../inequality/~/core-js/library/modules/_an-object.js","webpack:///../inequality/~/core-js/library/modules/_descriptors.js","webpack:///../inequality/~/core-js/library/modules/_has.js","webpack:///../inequality/~/core-js/library/modules/_hide.js","webpack:///../inequality/~/core-js/library/modules/_object-dp.js","webpack:///../inequality/~/core-js/library/modules/_to-iobject.js","webpack:///../inequality/~/process/browser.js","webpack:///../inequality/~/readable-stream/lib/_stream_duplex.js","webpack:///../inequality/~/core-js/library/modules/_export.js","webpack:///../inequality/~/core-js/library/modules/_fails.js","webpack:///../inequality/~/core-js/library/modules/_iterators.js","webpack:///../inequality/~/core-js/library/modules/_object-keys.js","webpack:///../inequality/~/inherits/inherits_browser.js","webpack:///../inequality/~/core-js/library/modules/_cof.js","webpack:///../inequality/~/core-js/library/modules/_is-object.js","webpack:///../inequality/~/core-util-is/lib/util.js","webpack:///../inequality/~/webpack/buildin/global.js","webpack:///../inequality/~/tone/build/Tone.js","webpack:///../inequality/~/core-js/library/modules/_ctx.js","webpack:///../inequality/~/core-js/library/modules/_library.js","webpack:///../inequality/~/core-js/library/modules/_object-pie.js","webpack:///../inequality/~/core-js/library/modules/_property-desc.js","webpack:///../inequality/~/core-js/library/modules/_set-to-string-tag.js","webpack:///../inequality/~/core-js/library/modules/_uid.js","webpack:///../inequality/~/core-js/library/modules/es6.string.iterator.js","webpack:///../inequality/~/core-js/library/modules/web.dom.iterable.js","webpack:///./client/lib/util.js","webpack:///../inequality/~/buffer-shims/index.js","webpack:///../inequality/~/core-js/library/modules/_a-function.js","webpack:///../inequality/~/core-js/library/modules/_classof.js","webpack:///../inequality/~/core-js/library/modules/_defined.js","webpack:///../inequality/~/core-js/library/modules/_dom-create.js","webpack:///../inequality/~/core-js/library/modules/_enum-bug-keys.js","webpack:///../inequality/~/core-js/library/modules/_object-gops.js","webpack:///../inequality/~/core-js/library/modules/_shared-key.js","webpack:///../inequality/~/core-js/library/modules/_shared.js","webpack:///../inequality/~/core-js/library/modules/_to-integer.js","webpack:///../inequality/~/core-js/library/modules/_to-object.js","webpack:///../inequality/~/core-js/library/modules/_to-primitive.js","webpack:///../inequality/~/core-js/library/modules/_wks-define.js","webpack:///../inequality/~/core-js/library/modules/_wks-ext.js","webpack:///../inequality/~/events/events.js","webpack:///../inequality/~/node-libs-browser/~/string_decoder/index.js","webpack:///../inequality/~/process-nextick-args/index.js","webpack:///../inequality/~/readable-stream/lib/_stream_writable.js","webpack:///../inequality/~/readable-stream/readable-browser.js","webpack:///./client/lib/scales.js","webpack:///./client/lib/ui.js","webpack:///../inequality/~/babel-runtime/core-js/object/assign.js","webpack:///../inequality/~/core-js/library/modules/_html.js","webpack:///../inequality/~/core-js/library/modules/_ie8-dom-define.js","webpack:///../inequality/~/core-js/library/modules/_iobject.js","webpack:///../inequality/~/core-js/library/modules/_iter-define.js","webpack:///../inequality/~/core-js/library/modules/_object-create.js","webpack:///../inequality/~/core-js/library/modules/_object-gopn.js","webpack:///../inequality/~/core-js/library/modules/_object-keys-internal.js","webpack:///../inequality/~/core-js/library/modules/_redefine.js","webpack:///../inequality/~/core-js/library/modules/_task.js","webpack:///../inequality/~/core-js/library/modules/_to-length.js","webpack:///../inequality/~/core-js/library/modules/core.get-iterator-method.js","webpack:///../inequality/~/isarray/index.js","webpack:///../inequality/~/readable-stream/lib/_stream_readable.js","webpack:///../inequality/~/readable-stream/lib/_stream_transform.js","webpack:///../inequality/~/readable-stream/lib/internal/streams/stream-browser.js","webpack:///../inequality/~/timers-browserify/main.js","webpack:///./client/data.js","webpack:///./client/lib/keys.js","webpack:///./client/lib/midi.js","webpack:///../inequality/~/babel-runtime/helpers/slicedToArray.js","webpack:///../inequality/~/file-saver/FileSaver.js","webpack:///../inequality/~/nexusui/dist/NexusUI.js","webpack:///./client/index.js","webpack:///./client/lib/intonation.js","webpack:///./client/lib/kalimba.js","webpack:///./client/lib/startAudioContext.js","webpack:///../inequality/~/babel-runtime/core-js/get-iterator.js","webpack:///../inequality/~/babel-runtime/core-js/is-iterable.js","webpack:///../inequality/~/babel-runtime/core-js/math/log2.js","webpack:///../inequality/~/babel-runtime/core-js/object/keys.js","webpack:///../inequality/~/babel-runtime/core-js/promise.js","webpack:///../inequality/~/babel-runtime/core-js/symbol.js","webpack:///../inequality/~/babel-runtime/core-js/symbol/iterator.js","webpack:///../inequality/~/babel-runtime/helpers/typeof.js","webpack:///../inequality/~/base64-js/index.js","webpack:///../inequality/~/core-js/library/fn/get-iterator.js","webpack:///../inequality/~/core-js/library/fn/is-iterable.js","webpack:///../inequality/~/core-js/library/fn/math/log2.js","webpack:///../inequality/~/core-js/library/fn/object/assign.js","webpack:///../inequality/~/core-js/library/fn/object/keys.js","webpack:///../inequality/~/core-js/library/fn/promise.js","webpack:///../inequality/~/core-js/library/fn/symbol/index.js","webpack:///../inequality/~/core-js/library/fn/symbol/iterator.js","webpack:///../inequality/~/core-js/library/modules/_add-to-unscopables.js","webpack:///../inequality/~/core-js/library/modules/_an-instance.js","webpack:///../inequality/~/core-js/library/modules/_array-includes.js","webpack:///../inequality/~/core-js/library/modules/_enum-keys.js","webpack:///../inequality/~/core-js/library/modules/_for-of.js","webpack:///../inequality/~/core-js/library/modules/_invoke.js","webpack:///../inequality/~/core-js/library/modules/_is-array-iter.js","webpack:///../inequality/~/core-js/library/modules/_is-array.js","webpack:///../inequality/~/core-js/library/modules/_iter-call.js","webpack:///../inequality/~/core-js/library/modules/_iter-create.js","webpack:///../inequality/~/core-js/library/modules/_iter-detect.js","webpack:///../inequality/~/core-js/library/modules/_iter-step.js","webpack:///../inequality/~/core-js/library/modules/_keyof.js","webpack:///../inequality/~/core-js/library/modules/_meta.js","webpack:///../inequality/~/core-js/library/modules/_microtask.js","webpack:///../inequality/~/core-js/library/modules/_object-assign.js","webpack:///../inequality/~/core-js/library/modules/_object-dps.js","webpack:///../inequality/~/core-js/library/modules/_object-gopd.js","webpack:///../inequality/~/core-js/library/modules/_object-gopn-ext.js","webpack:///../inequality/~/core-js/library/modules/_object-gpo.js","webpack:///../inequality/~/core-js/library/modules/_object-sap.js","webpack:///../inequality/~/core-js/library/modules/_redefine-all.js","webpack:///../inequality/~/core-js/library/modules/_set-species.js","webpack:///../inequality/~/core-js/library/modules/_species-constructor.js","webpack:///../inequality/~/core-js/library/modules/_string-at.js","webpack:///../inequality/~/core-js/library/modules/_to-index.js","webpack:///../inequality/~/core-js/library/modules/core.get-iterator.js","webpack:///../inequality/~/core-js/library/modules/core.is-iterable.js","webpack:///../inequality/~/core-js/library/modules/es6.array.iterator.js","webpack:///../inequality/~/core-js/library/modules/es6.math.log2.js","webpack:///../inequality/~/core-js/library/modules/es6.object.assign.js","webpack:///../inequality/~/core-js/library/modules/es6.object.keys.js","webpack:///../inequality/~/core-js/library/modules/es6.promise.js","webpack:///../inequality/~/core-js/library/modules/es6.symbol.js","webpack:///../inequality/~/core-js/library/modules/es7.symbol.async-iterator.js","webpack:///../inequality/~/core-js/library/modules/es7.symbol.observable.js","webpack:///../inequality/~/csv-parse/lib/index.js","webpack:///../inequality/~/ieee754/index.js","webpack:///../inequality/~/midi-writer-js/build/index.js","webpack:///../inequality/~/note-parser/index.js","webpack:///../inequality/~/readable-stream/duplex-browser.js","webpack:///../inequality/~/readable-stream/lib/_stream_passthrough.js","webpack:///../inequality/~/readable-stream/lib/internal/streams/BufferList.js","webpack:///../inequality/~/readable-stream/passthrough.js","webpack:///../inequality/~/readable-stream/transform.js","webpack:///../inequality/~/readable-stream/writable-browser.js","webpack:///../inequality/~/setimmediate/setImmediate.js","webpack:///../inequality/~/stream-browserify/index.js","webpack:///../inequality/~/tonal-midi/index.js","webpack:///../inequality/~/util-deprecate/browser.js","webpack:///../inequality/~/util/~/inherits/inherits_browser.js","webpack:///../inequality/~/util/support/isBufferBrowser.js","webpack:///../inequality/~/util/util.js","webpack:///../inequality/~/webmidi/webmidi.min.js","webpack:///../inequality/~/webpack/buildin/amd-define.js","webpack:///../inequality/~/webpack/buildin/amd-options.js","webpack:///../inequality/~/babel-runtime/helpers/toArray.js","webpack:///../inequality/~/babel-runtime/core-js/array/from.js","webpack:///../inequality/~/core-js/library/fn/array/from.js","webpack:///../inequality/~/core-js/library/modules/_create-property.js","webpack:///../inequality/~/core-js/library/modules/es6.array.from.js"],"sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 76);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 3f67a584b1dc586b4445","var store = require('./_shared')('wks')\n , uid = require('./_uid')\n , Symbol = require('./_global').Symbol\n , USE_SYMBOL = typeof Symbol == 'function';\n\nvar $exports = module.exports = function(name){\n return store[name] || (store[name] =\n USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n\n$exports.store = store;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_wks.js\n// module id = 0\n// module chunks = 0","var core = module.exports = {version: '2.4.0'};\nif(typeof __e == 'number')__e = core; // eslint-disable-line no-undef\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_core.js\n// module id = 1\n// module chunks = 0","// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();\nif(typeof __g == 'number')__g = global; // eslint-disable-line no-undef\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_global.js\n// module id = 2\n// module chunks = 0","/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n * incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n ? global.TYPED_ARRAY_SUPPORT\n : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n try {\n var arr = new Uint8Array(1)\n arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n return arr.foo() === 42 && // typed array instances can be augmented\n typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n } catch (e) {\n return false\n }\n}\n\nfunction kMaxLength () {\n return Buffer.TYPED_ARRAY_SUPPORT\n ? 0x7fffffff\n : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n if (kMaxLength() < length) {\n throw new RangeError('Invalid typed array length')\n }\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = new Uint8Array(length)\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n if (that === null) {\n that = new Buffer(length)\n }\n that.length = length\n }\n\n return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n return new Buffer(arg, encodingOrOffset, length)\n }\n\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new Error(\n 'If encoding is specified then the first argument must be a string'\n )\n }\n return allocUnsafe(this, arg)\n }\n return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n arr.__proto__ = Buffer.prototype\n return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number')\n }\n\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return fromArrayBuffer(that, value, encodingOrOffset, length)\n }\n\n if (typeof value === 'string') {\n return fromString(that, value, encodingOrOffset)\n }\n\n return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n Buffer.prototype.__proto__ = Uint8Array.prototype\n Buffer.__proto__ = Uint8Array\n if (typeof Symbol !== 'undefined' && Symbol.species &&\n Buffer[Symbol.species] === Buffer) {\n // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n Object.defineProperty(Buffer, Symbol.species, {\n value: null,\n configurable: true\n })\n }\n}\n\nfunction assertSize (size) {\n if (typeof size !== 'number') {\n throw new TypeError('\"size\" argument must be a number')\n } else if (size < 0) {\n throw new RangeError('\"size\" argument must not be negative')\n }\n}\n\nfunction alloc (that, size, fill, encoding) {\n assertSize(size)\n if (size <= 0) {\n return createBuffer(that, size)\n }\n if (fill !== undefined) {\n // Only pay attention to encoding if it's a string. This\n // prevents accidentally sending in a number that would\n // be interpretted as a start offset.\n return typeof encoding === 'string'\n ? createBuffer(that, size).fill(fill, encoding)\n : createBuffer(that, size).fill(fill)\n }\n return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n assertSize(size)\n that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) {\n for (var i = 0; i < size; ++i) {\n that[i] = 0\n }\n }\n return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n if (typeof encoding !== 'string' || encoding === '') {\n encoding = 'utf8'\n }\n\n if (!Buffer.isEncoding(encoding)) {\n throw new TypeError('\"encoding\" must be a valid string encoding')\n }\n\n var length = byteLength(string, encoding) | 0\n that = createBuffer(that, length)\n\n var actual = that.write(string, encoding)\n\n if (actual !== length) {\n // Writing a hex string, for example, that contains invalid characters will\n // cause everything after the first invalid character to be ignored. (e.g.\n // 'abxxcd' will be treated as 'ab')\n that = that.slice(0, actual)\n }\n\n return that\n}\n\nfunction fromArrayLike (that, array) {\n var length = array.length < 0 ? 0 : checked(array.length) | 0\n that = createBuffer(that, length)\n for (var i = 0; i < length; i += 1) {\n that[i] = array[i] & 255\n }\n return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n if (byteOffset < 0 || array.byteLength < byteOffset) {\n throw new RangeError('\\'offset\\' is out of bounds')\n }\n\n if (array.byteLength < byteOffset + (length || 0)) {\n throw new RangeError('\\'length\\' is out of bounds')\n }\n\n if (byteOffset === undefined && length === undefined) {\n array = new Uint8Array(array)\n } else if (length === undefined) {\n array = new Uint8Array(array, byteOffset)\n } else {\n array = new Uint8Array(array, byteOffset, length)\n }\n\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = array\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n that = fromArrayLike(that, array)\n }\n return that\n}\n\nfunction fromObject (that, obj) {\n if (Buffer.isBuffer(obj)) {\n var len = checked(obj.length) | 0\n that = createBuffer(that, len)\n\n if (that.length === 0) {\n return that\n }\n\n obj.copy(that, 0, 0, len)\n return that\n }\n\n if (obj) {\n if ((typeof ArrayBuffer !== 'undefined' &&\n obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n if (typeof obj.length !== 'number' || isnan(obj.length)) {\n return createBuffer(that, 0)\n }\n return fromArrayLike(that, obj)\n }\n\n if (obj.type === 'Buffer' && isArray(obj.data)) {\n return fromArrayLike(that, obj.data)\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n // Note: cannot use `length < kMaxLength()` here because that fails when\n // length is NaN (which is otherwise coerced to zero.)\n if (length >= kMaxLength()) {\n throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n 'size: 0x' + kMaxLength().toString(16) + ' bytes')\n }\n return length | 0\n}\n\nfunction SlowBuffer (length) {\n if (+length != length) { // eslint-disable-line eqeqeq\n length = 0\n }\n return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n throw new TypeError('Arguments must be Buffers')\n }\n\n if (a === b) return 0\n\n var x = a.length\n var y = b.length\n\n for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n if (a[i] !== b[i]) {\n x = a[i]\n y = b[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'latin1':\n case 'binary':\n case 'base64':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.concat = function concat (list, length) {\n if (!isArray(list)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n\n if (list.length === 0) {\n return Buffer.alloc(0)\n }\n\n var i\n if (length === undefined) {\n length = 0\n for (i = 0; i < list.length; ++i) {\n length += list[i].length\n }\n }\n\n var buffer = Buffer.allocUnsafe(length)\n var pos = 0\n for (i = 0; i < list.length; ++i) {\n var buf = list[i]\n if (!Buffer.isBuffer(buf)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n buf.copy(buffer, pos)\n pos += buf.length\n }\n return buffer\n}\n\nfunction byteLength (string, encoding) {\n if (Buffer.isBuffer(string)) {\n return string.length\n }\n if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n return string.byteLength\n }\n if (typeof string !== 'string') {\n string = '' + string\n }\n\n var len = string.length\n if (len === 0) return 0\n\n // Use a for loop to avoid recursion\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return len\n case 'utf8':\n case 'utf-8':\n case undefined:\n return utf8ToBytes(string).length\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return len * 2\n case 'hex':\n return len >>> 1\n case 'base64':\n return base64ToBytes(string).length\n default:\n if (loweredCase) return utf8ToBytes(string).length // assume utf8\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n var loweredCase = false\n\n // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n // property of a typed array.\n\n // This behaves neither like String nor Uint8Array in that we set start/end\n // to their upper/lower bounds if the value passed is out of range.\n // undefined is handled specially as per ECMA-262 6th Edition,\n // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n if (start === undefined || start < 0) {\n start = 0\n }\n // Return early if start > this.length. Done here to prevent potential uint32\n // coercion fail below.\n if (start > this.length) {\n return ''\n }\n\n if (end === undefined || end > this.length) {\n end = this.length\n }\n\n if (end <= 0) {\n return ''\n }\n\n // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n end >>>= 0\n start >>>= 0\n\n if (end <= start) {\n return ''\n }\n\n if (!encoding) encoding = 'utf8'\n\n while (true) {\n switch (encoding) {\n case 'hex':\n return hexSlice(this, start, end)\n\n case 'utf8':\n case 'utf-8':\n return utf8Slice(this, start, end)\n\n case 'ascii':\n return asciiSlice(this, start, end)\n\n case 'latin1':\n case 'binary':\n return latin1Slice(this, start, end)\n\n case 'base64':\n return base64Slice(this, start, end)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return utf16leSlice(this, start, end)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = (encoding + '').toLowerCase()\n loweredCase = true\n }\n }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n var i = b[n]\n b[n] = b[m]\n b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n var len = this.length\n if (len % 2 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 16-bits')\n }\n for (var i = 0; i < len; i += 2) {\n swap(this, i, i + 1)\n }\n return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n var len = this.length\n if (len % 4 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 32-bits')\n }\n for (var i = 0; i < len; i += 4) {\n swap(this, i, i + 3)\n swap(this, i + 1, i + 2)\n }\n return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n var len = this.length\n if (len % 8 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 64-bits')\n }\n for (var i = 0; i < len; i += 8) {\n swap(this, i, i + 7)\n swap(this, i + 1, i + 6)\n swap(this, i + 2, i + 5)\n swap(this, i + 3, i + 4)\n }\n return this\n}\n\nBuffer.prototype.toString = function toString () {\n var length = this.length | 0\n if (length === 0) return ''\n if (arguments.length === 0) return utf8Slice(this, 0, length)\n return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n if (this === b) return true\n return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n var str = ''\n var max = exports.INSPECT_MAX_BYTES\n if (this.length > 0) {\n str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n if (this.length > max) str += ' ... '\n }\n return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n if (!Buffer.isBuffer(target)) {\n throw new TypeError('Argument must be a Buffer')\n }\n\n if (start === undefined) {\n start = 0\n }\n if (end === undefined) {\n end = target ? target.length : 0\n }\n if (thisStart === undefined) {\n thisStart = 0\n }\n if (thisEnd === undefined) {\n thisEnd = this.length\n }\n\n if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n throw new RangeError('out of range index')\n }\n\n if (thisStart >= thisEnd && start >= end) {\n return 0\n }\n if (thisStart >= thisEnd) {\n return -1\n }\n if (start >= end) {\n return 1\n }\n\n start >>>= 0\n end >>>= 0\n thisStart >>>= 0\n thisEnd >>>= 0\n\n if (this === target) return 0\n\n var x = thisEnd - thisStart\n var y = end - start\n var len = Math.min(x, y)\n\n var thisCopy = this.slice(thisStart, thisEnd)\n var targetCopy = target.slice(start, end)\n\n for (var i = 0; i < len; ++i) {\n if (thisCopy[i] !== targetCopy[i]) {\n x = thisCopy[i]\n y = targetCopy[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n // Empty buffer means no match\n if (buffer.length === 0) return -1\n\n // Normalize byteOffset\n if (typeof byteOffset === 'string') {\n encoding = byteOffset\n byteOffset = 0\n } else if (byteOffset > 0x7fffffff) {\n byteOffset = 0x7fffffff\n } else if (byteOffset < -0x80000000) {\n byteOffset = -0x80000000\n }\n byteOffset = +byteOffset // Coerce to Number.\n if (isNaN(byteOffset)) {\n // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n byteOffset = dir ? 0 : (buffer.length - 1)\n }\n\n // Normalize byteOffset: negative offsets start from the end of the buffer\n if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n if (byteOffset >= buffer.length) {\n if (dir) return -1\n else byteOffset = buffer.length - 1\n } else if (byteOffset < 0) {\n if (dir) byteOffset = 0\n else return -1\n }\n\n // Normalize val\n if (typeof val === 'string') {\n val = Buffer.from(val, encoding)\n }\n\n // Finally, search either indexOf (if dir is true) or lastIndexOf\n if (Buffer.isBuffer(val)) {\n // Special case: looking for empty string/buffer always fails\n if (val.length === 0) {\n return -1\n }\n return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n } else if (typeof val === 'number') {\n val = val & 0xFF // Search for a byte value [0-255]\n if (Buffer.TYPED_ARRAY_SUPPORT &&\n typeof Uint8Array.prototype.indexOf === 'function') {\n if (dir) {\n return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n } else {\n return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n }\n }\n return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n }\n\n throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n var indexSize = 1\n var arrLength = arr.length\n var valLength = val.length\n\n if (encoding !== undefined) {\n encoding = String(encoding).toLowerCase()\n if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n encoding === 'utf16le' || encoding === 'utf-16le') {\n if (arr.length < 2 || val.length < 2) {\n return -1\n }\n indexSize = 2\n arrLength /= 2\n valLength /= 2\n byteOffset /= 2\n }\n }\n\n function read (buf, i) {\n if (indexSize === 1) {\n return buf[i]\n } else {\n return buf.readUInt16BE(i * indexSize)\n }\n }\n\n var i\n if (dir) {\n var foundIndex = -1\n for (i = byteOffset; i < arrLength; i++) {\n if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n if (foundIndex === -1) foundIndex = i\n if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n } else {\n if (foundIndex !== -1) i -= i - foundIndex\n foundIndex = -1\n }\n }\n } else {\n if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n for (i = byteOffset; i >= 0; i--) {\n var found = true\n for (var j = 0; j < valLength; j++) {\n if (read(arr, i + j) !== read(val, j)) {\n found = false\n break\n }\n }\n if (found) return i\n }\n }\n\n return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n // must be an even number of digits\n var strLen = string.length\n if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; ++i) {\n var parsed = parseInt(string.substr(i * 2, 2), 16)\n if (isNaN(parsed)) return i\n buf[offset + i] = parsed\n }\n return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n // Buffer#write(string)\n if (offset === undefined) {\n encoding = 'utf8'\n length = this.length\n offset = 0\n // Buffer#write(string, encoding)\n } else if (length === undefined && typeof offset === 'string') {\n encoding = offset\n length = this.length\n offset = 0\n // Buffer#write(string, offset[, length][, encoding])\n } else if (isFinite(offset)) {\n offset = offset | 0\n if (isFinite(length)) {\n length = length | 0\n if (encoding === undefined) encoding = 'utf8'\n } else {\n encoding = length\n length = undefined\n }\n // legacy write(string, encoding, offset, length) - remove in v0.13\n } else {\n throw new Error(\n 'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n )\n }\n\n var remaining = this.length - offset\n if (length === undefined || length > remaining) length = remaining\n\n if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n throw new RangeError('Attempt to write outside buffer bounds')\n }\n\n if (!encoding) encoding = 'utf8'\n\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'hex':\n return hexWrite(this, string, offset, length)\n\n case 'utf8':\n case 'utf-8':\n return utf8Write(this, string, offset, length)\n\n case 'ascii':\n return asciiWrite(this, string, offset, length)\n\n case 'latin1':\n case 'binary':\n return latin1Write(this, string, offset, length)\n\n case 'base64':\n // Warning: maxLength not taken into account in base64Write\n return base64Write(this, string, offset, length)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return ucs2Write(this, string, offset, length)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\nfunction base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction utf8Slice (buf, start, end) {\n end = Math.min(buf.length, end)\n var res = []\n\n var i = start\n while (i < end) {\n var firstByte = buf[i]\n var codePoint = null\n var bytesPerSequence = (firstByte > 0xEF) ? 4\n : (firstByte > 0xDF) ? 3\n : (firstByte > 0xBF) ? 2\n : 1\n\n if (i + bytesPerSequence <= end) {\n var secondByte, thirdByte, fourthByte, tempCodePoint\n\n switch (bytesPerSequence) {\n case 1:\n if (firstByte < 0x80) {\n codePoint = firstByte\n }\n break\n case 2:\n secondByte = buf[i + 1]\n if ((secondByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n if (tempCodePoint > 0x7F) {\n codePoint = tempCodePoint\n }\n }\n break\n case 3:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n codePoint = tempCodePoint\n }\n }\n break\n case 4:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n fourthByte = buf[i + 3]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n codePoint = tempCodePoint\n }\n }\n }\n }\n\n if (codePoint === null) {\n // we did not generate a valid codePoint so insert a\n // replacement char (U+FFFD) and advance only 1 byte\n codePoint = 0xFFFD\n bytesPerSequence = 1\n } else if (codePoint > 0xFFFF) {\n // encode to utf16 (surrogate pair dance)\n codePoint -= 0x10000\n res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n codePoint = 0xDC00 | codePoint & 0x3FF\n }\n\n res.push(codePoint)\n i += bytesPerSequence\n }\n\n return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n var len = codePoints.length\n if (len <= MAX_ARGUMENTS_LENGTH) {\n return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n }\n\n // Decode in chunks to avoid \"call stack size exceeded\".\n var res = ''\n var i = 0\n while (i < len) {\n res += String.fromCharCode.apply(\n String,\n codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n )\n }\n return res\n}\n\nfunction asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i] & 0x7F)\n }\n return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i])\n }\n return ret\n}\n\nfunction hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; ++i) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n }\n return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n var len = this.length\n start = ~~start\n end = end === undefined ? len : ~~end\n\n if (start < 0) {\n start += len\n if (start < 0) start = 0\n } else if (start > len) {\n start = len\n }\n\n if (end < 0) {\n end += len\n if (end < 0) end = 0\n } else if (end > len) {\n end = len\n }\n\n if (end < start) end = start\n\n var newBuf\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n newBuf = this.subarray(start, end)\n newBuf.__proto__ = Buffer.prototype\n } else {\n var sliceLen = end - start\n newBuf = new Buffer(sliceLen, undefined)\n for (var i = 0; i < sliceLen; ++i) {\n newBuf[i] = this[i + start]\n }\n }\n\n return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n checkOffset(offset, byteLength, this.length)\n }\n\n var val = this[offset + --byteLength]\n var mul = 1\n while (byteLength > 0 && (mul *= 0x100)) {\n val += this[offset + --byteLength] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return ((this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16)) +\n (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] * 0x1000000) +\n ((this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var i = byteLength\n var mul = 1\n var val = this[offset + --i]\n while (i > 0 && (mul *= 0x100)) {\n val += this[offset + --i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n if (!(this[offset] & 0x80)) return (this[offset])\n return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset] | (this[offset + 1] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset + 1] | (this[offset] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16) |\n (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] << 24) |\n (this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var mul = 1\n var i = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var i = byteLength - 1\n var mul = 1\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n (littleEndian ? i : 1 - i) * 8\n }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffffffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset + 3] = (value >>> 24)\n this[offset + 2] = (value >>> 16)\n this[offset + 1] = (value >>> 8)\n this[offset] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = 0\n var mul = 1\n var sub = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = byteLength - 1\n var mul = 1\n var sub = 0\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n if (value < 0) value = 0xff + value + 1\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n this[offset + 2] = (value >>> 16)\n this[offset + 3] = (value >>> 24)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (value < 0) value = 0xffffffff + value + 1\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (targetStart >= target.length) targetStart = target.length\n if (!targetStart) targetStart = 0\n if (end > 0 && end < start) end = start\n\n // Copy 0 bytes; we're done\n if (end === start) return 0\n if (target.length === 0 || this.length === 0) return 0\n\n // Fatal error conditions\n if (targetStart < 0) {\n throw new RangeError('targetStart out of bounds')\n }\n if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length) end = this.length\n if (target.length - targetStart < end - start) {\n end = target.length - targetStart + start\n }\n\n var len = end - start\n var i\n\n if (this === target && start < targetStart && targetStart < end) {\n // descending copy from end\n for (i = len - 1; i >= 0; --i) {\n target[i + targetStart] = this[i + start]\n }\n } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n // ascending copy from start\n for (i = 0; i < len; ++i) {\n target[i + targetStart] = this[i + start]\n }\n } else {\n Uint8Array.prototype.set.call(\n target,\n this.subarray(start, start + len),\n targetStart\n )\n }\n\n return len\n}\n\n// Usage:\n// buffer.fill(number[, offset[, end]])\n// buffer.fill(buffer[, offset[, end]])\n// buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n // Handle string cases:\n if (typeof val === 'string') {\n if (typeof start === 'string') {\n encoding = start\n start = 0\n end = this.length\n } else if (typeof end === 'string') {\n encoding = end\n end = this.length\n }\n if (val.length === 1) {\n var code = val.charCodeAt(0)\n if (code < 256) {\n val = code\n }\n }\n if (encoding !== undefined && typeof encoding !== 'string') {\n throw new TypeError('encoding must be a string')\n }\n if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n throw new TypeError('Unknown encoding: ' + encoding)\n }\n } else if (typeof val === 'number') {\n val = val & 255\n }\n\n // Invalid ranges are not set to a default, so can range check early.\n if (start < 0 || this.length < start || this.length < end) {\n throw new RangeError('Out of range index')\n }\n\n if (end <= start) {\n return this\n }\n\n start = start >>> 0\n end = end === undefined ? this.length : end >>> 0\n\n if (!val) val = 0\n\n var i\n if (typeof val === 'number') {\n for (i = start; i < end; ++i) {\n this[i] = val\n }\n } else {\n var bytes = Buffer.isBuffer(val)\n ? val\n : utf8ToBytes(new Buffer(val, encoding).toString())\n var len = bytes.length\n for (i = 0; i < end - start; ++i) {\n this[i + start] = bytes[i % len]\n }\n }\n\n return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n // Node converts strings with length < 2 to ''\n if (str.length < 2) return ''\n // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n while (str.length % 4 !== 0) {\n str = str + '='\n }\n return str\n}\n\nfunction stringtrim (str) {\n if (str.trim) return str.trim()\n return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n units = units || Infinity\n var codePoint\n var length = string.length\n var leadSurrogate = null\n var bytes = []\n\n for (var i = 0; i < length; ++i) {\n codePoint = string.charCodeAt(i)\n\n // is surrogate component\n if (codePoint > 0xD7FF && codePoint < 0xE000) {\n // last char was a lead\n if (!leadSurrogate) {\n // no lead yet\n if (codePoint > 0xDBFF) {\n // unexpected trail\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n } else if (i + 1 === length) {\n // unpaired lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n }\n\n // valid lead\n leadSurrogate = codePoint\n\n continue\n }\n\n // 2 leads in a row\n if (codePoint < 0xDC00) {\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n leadSurrogate = codePoint\n continue\n }\n\n // valid surrogate pair\n codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n } else if (leadSurrogate) {\n // valid bmp char, but last char was a lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n }\n\n leadSurrogate = null\n\n // encode utf8\n if (codePoint < 0x80) {\n if ((units -= 1) < 0) break\n bytes.push(codePoint)\n } else if (codePoint < 0x800) {\n if ((units -= 2) < 0) break\n bytes.push(\n codePoint >> 0x6 | 0xC0,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x10000) {\n if ((units -= 3) < 0) break\n bytes.push(\n codePoint >> 0xC | 0xE0,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x110000) {\n if ((units -= 4) < 0) break\n bytes.push(\n codePoint >> 0x12 | 0xF0,\n codePoint >> 0xC & 0x3F | 0x80,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else {\n throw new Error('Invalid code point')\n }\n }\n\n return bytes\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n if ((units -= 2) < 0) break\n\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n for (var i = 0; i < length; ++i) {\n if ((i + offset >= dst.length) || (i >= src.length)) break\n dst[i + offset] = src[i]\n }\n return i\n}\n\nfunction isnan (val) {\n return val !== val // eslint-disable-line no-self-compare\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/buffer/index.js\n// module id = 3\n// module chunks = 0","var isObject = require('./_is-object');\nmodule.exports = function(it){\n if(!isObject(it))throw TypeError(it + ' is not an object!');\n return it;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_an-object.js\n// module id = 4\n// module chunks = 0","// Thank's IE8 for his funny defineProperty\nmodule.exports = !require('./_fails')(function(){\n return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_descriptors.js\n// module id = 5\n// module chunks = 0","var hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function(it, key){\n return hasOwnProperty.call(it, key);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_has.js\n// module id = 6\n// module chunks = 0","var dP = require('./_object-dp')\n , createDesc = require('./_property-desc');\nmodule.exports = require('./_descriptors') ? function(object, key, value){\n return dP.f(object, key, createDesc(1, value));\n} : function(object, key, value){\n object[key] = value;\n return object;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_hide.js\n// module id = 7\n// module chunks = 0","var anObject = require('./_an-object')\n , IE8_DOM_DEFINE = require('./_ie8-dom-define')\n , toPrimitive = require('./_to-primitive')\n , dP = Object.defineProperty;\n\nexports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes){\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if(IE8_DOM_DEFINE)try {\n return dP(O, P, Attributes);\n } catch(e){ /* empty */ }\n if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');\n if('value' in Attributes)O[P] = Attributes.value;\n return O;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-dp.js\n// module id = 8\n// module chunks = 0","// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = require('./_iobject')\n , defined = require('./_defined');\nmodule.exports = function(it){\n return IObject(defined(it));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_to-iobject.js\n// module id = 9\n// module chunks = 0","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/process/browser.js\n// module id = 10\n// module chunks = 0","// a duplex stream is just a stream that is both readable and writable.\n// Since JS doesn't have multiple prototypal inheritance, this class\n// prototypally inherits from Readable, and then parasitically from\n// Writable.\n\n'use strict';\n\n/*<replacement>*/\n\nvar objectKeys = Object.keys || function (obj) {\n var keys = [];\n for (var key in obj) {\n keys.push(key);\n }return keys;\n};\n/*</replacement>*/\n\nmodule.exports = Duplex;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Readable = require('./_stream_readable');\nvar Writable = require('./_stream_writable');\n\nutil.inherits(Duplex, Readable);\n\nvar keys = objectKeys(Writable.prototype);\nfor (var v = 0; v < keys.length; v++) {\n var method = keys[v];\n if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];\n}\n\nfunction Duplex(options) {\n if (!(this instanceof Duplex)) return new Duplex(options);\n\n Readable.call(this, options);\n Writable.call(this, options);\n\n if (options && options.readable === false) this.readable = false;\n\n if (options && options.writable === false) this.writable = false;\n\n this.allowHalfOpen = true;\n if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;\n\n this.once('end', onend);\n}\n\n// the no-half-open enforcer\nfunction onend() {\n // if we allow half-open state, or if the writable side ended,\n // then we're ok.\n if (this.allowHalfOpen || this._writableState.ended) return;\n\n // no more data can be written.\n // But allow more writes to happen in this tick.\n processNextTick(onEndNT, this);\n}\n\nfunction onEndNT(self) {\n self.end();\n}\n\nfunction forEach(xs, f) {\n for (var i = 0, l = xs.length; i < l; i++) {\n f(xs[i], i);\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/readable-stream/lib/_stream_duplex.js\n// module id = 11\n// module chunks = 0","var global = require('./_global')\n , core = require('./_core')\n , ctx = require('./_ctx')\n , hide = require('./_hide')\n , PROTOTYPE = 'prototype';\n\nvar $export = function(type, name, source){\n var IS_FORCED = type & $export.F\n , IS_GLOBAL = type & $export.G\n , IS_STATIC = type & $export.S\n , IS_PROTO = type & $export.P\n , IS_BIND = type & $export.B\n , IS_WRAP = type & $export.W\n , exports = IS_GLOBAL ? core : core[name] || (core[name] = {})\n , expProto = exports[PROTOTYPE]\n , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]\n , key, own, out;\n if(IS_GLOBAL)source = name;\n for(key in source){\n // contains in native\n own = !IS_FORCED && target && target[key] !== undefined;\n if(own && key in exports)continue;\n // export native or passed\n out = own ? target[key] : source[key];\n // prevent global pollution for namespaces\n exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]\n // bind timers to global for call from export context\n : IS_BIND && own ? ctx(out, global)\n // wrap global constructors for prevent change them in library\n : IS_WRAP && target[key] == out ? (function(C){\n var F = function(a, b, c){\n if(this instanceof C){\n switch(arguments.length){\n case 0: return new C;\n case 1: return new C(a);\n case 2: return new C(a, b);\n } return new C(a, b, c);\n } return C.apply(this, arguments);\n };\n F[PROTOTYPE] = C[PROTOTYPE];\n return F;\n // make static versions for prototype methods\n })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%\n if(IS_PROTO){\n (exports.virtual || (exports.virtual = {}))[key] = out;\n // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%\n if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out);\n }\n }\n};\n// type bitmap\n$export.F = 1; // forced\n$export.G = 2; // global\n$export.S = 4; // static\n$export.P = 8; // proto\n$export.B = 16; // bind\n$export.W = 32; // wrap\n$export.U = 64; // safe\n$export.R = 128; // real proto method for `library` \nmodule.exports = $export;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_export.js\n// module id = 12\n// module chunks = 0","module.exports = function(exec){\n try {\n return !!exec();\n } catch(e){\n return true;\n }\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_fails.js\n// module id = 13\n// module chunks = 0","module.exports = {};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_iterators.js\n// module id = 14\n// module chunks = 0","// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = require('./_object-keys-internal')\n , enumBugKeys = require('./_enum-bug-keys');\n\nmodule.exports = Object.keys || function keys(O){\n return $keys(O, enumBugKeys);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-keys.js\n// module id = 15\n// module chunks = 0","if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/inherits/inherits_browser.js\n// module id = 16\n// module chunks = 0","var toString = {}.toString;\n\nmodule.exports = function(it){\n return toString.call(it).slice(8, -1);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_cof.js\n// module id = 17\n// module chunks = 0","module.exports = function(it){\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_is-object.js\n// module id = 18\n// module chunks = 0","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\n\nfunction isArray(arg) {\n if (Array.isArray) {\n return Array.isArray(arg);\n }\n return objectToString(arg) === '[object Array]';\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n return objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n return objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n return (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n return arg === null ||\n typeof arg === 'boolean' ||\n typeof arg === 'number' ||\n typeof arg === 'string' ||\n typeof arg === 'symbol' || // ES6 symbol\n typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = Buffer.isBuffer;\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-util-is/lib/util.js\n// module id = 19\n// module chunks = 0","var g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/webpack/buildin/global.js\n// module id = 20\n// module chunks = 0","(function(root, factory){\n\n\t//UMD\n\tif ( typeof define === \"function\" && define.amd ) {\n\t\tdefine(function() {\n\t\t\treturn factory();\n\t\t});\n\t} else if (typeof module === \"object\") {\n\t\tmodule.exports = factory();\n \t} else {\n\t\troot.Tone = factory();\n\t}\n\n}(this, function(){\n\n\t\"use strict\";\n\t\n\tvar Tone;\n\t//constructs the main Tone object\n\tfunction Main(func){\n\t\tTone = func();\n\t}\n\t//invokes each of the modules with the main Tone object as the argument\n\tfunction Module(func){\n\t\tfunc(Tone);\n\t}\t/**\n\t * Tone.js\n\t * @author Yotam Mann\n\t * @license http://opensource.org/licenses/MIT MIT License\n\t * @copyright 2014-2018 Yotam Mann\n\t */\n\tMain(function () {\n\t \n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tTONE\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * @class Tone is the base class of all other classes.\n\t\t * @constructor\n\t\t */\n\t var Tone = function () {\n\t if (!(this instanceof Tone)) {\n\t throw new Error('constructor needs to be called with the \\'new\\' keyword');\n\t }\n\t };\n\t /**\n\t\t * @memberOf Tone#\n\t\t * @returns {String} returns the name of the class as a string\n\t\t */\n\t Tone.prototype.toString = function () {\n\t for (var className in Tone) {\n\t var isLetter = className[0].match(/^[A-Z]$/);\n\t var sameConstructor = Tone[className] === this.constructor;\n\t if (Tone.isFunction(Tone[className]) && isLetter && sameConstructor) {\n\t return className;\n\t }\n\t }\n\t return 'Tone';\n\t };\n\t /**\n\t\t * @memberOf Tone#\n\t\t * disconnect and dispose\n\t\t * @returns {Tone} this\n\t\t */\n\t Tone.prototype.dispose = function () {\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tGET/SET\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Set the parameters at once. Either pass in an\n\t\t * object mapping parameters to values, or to set a\n\t\t * single parameter, by passing in a string and value.\n\t\t * The last argument is an optional ramp time which\n\t\t * will ramp any signal values to their destination value\n\t\t * over the duration of the rampTime.\n\t\t * @param {Object|String} params\n\t\t * @param {Number=} value\n\t\t * @param {Time=} rampTime\n\t\t * @returns {Tone} this\n\t\t * @memberOf Tone#\n\t\t * @example\n\t\t * //set values using an object\n\t\t * filter.set({\n\t\t * \t\"frequency\" : 300,\n\t\t * \t\"type\" : highpass\n\t\t * });\n\t\t * @example\n\t\t * filter.set(\"type\", \"highpass\");\n\t\t * @example\n\t\t * //ramp to the value 220 over 3 seconds.\n\t\t * oscillator.set({\n\t\t * \t\"frequency\" : 220\n\t\t * }, 3);\n\t\t */\n\t Tone.prototype.set = function (params, value, rampTime) {\n\t if (Tone.isObject(params)) {\n\t rampTime = value;\n\t } else if (Tone.isString(params)) {\n\t var tmpObj = {};\n\t tmpObj[params] = value;\n\t params = tmpObj;\n\t }\n\t paramLoop:\n\t for (var attr in params) {\n\t value = params[attr];\n\t var parent = this;\n\t if (attr.indexOf('.') !== -1) {\n\t var attrSplit = attr.split('.');\n\t for (var i = 0; i < attrSplit.length - 1; i++) {\n\t parent = parent[attrSplit[i]];\n\t if (parent instanceof Tone) {\n\t attrSplit.splice(0, i + 1);\n\t var innerParam = attrSplit.join('.');\n\t parent.set(innerParam, value);\n\t continue paramLoop;\n\t }\n\t }\n\t attr = attrSplit[attrSplit.length - 1];\n\t }\n\t var param = parent[attr];\n\t if (Tone.isUndef(param)) {\n\t continue;\n\t }\n\t if (Tone.Signal && param instanceof Tone.Signal || Tone.Param && param instanceof Tone.Param) {\n\t if (param.value !== value) {\n\t if (Tone.isUndef(rampTime)) {\n\t param.value = value;\n\t } else {\n\t param.rampTo(value, rampTime);\n\t }\n\t }\n\t } else if (param instanceof AudioParam) {\n\t if (param.value !== value) {\n\t param.value = value;\n\t }\n\t } else if (Tone.TimeBase && param instanceof Tone.TimeBase) {\n\t parent[attr] = value;\n\t } else if (param instanceof Tone) {\n\t param.set(value);\n\t } else if (param !== value) {\n\t parent[attr] = value;\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Get the object's attributes. Given no arguments get\n\t\t * will return all available object properties and their corresponding\n\t\t * values. Pass in a single attribute to retrieve or an array\n\t\t * of attributes. The attribute strings can also include a \".\"\n\t\t * to access deeper properties.\n\t\t * @memberOf Tone#\n\t\t * @example\n\t\t * osc.get();\n\t\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t\t * @example\n\t\t * osc.get(\"type\");\n\t\t * //returns { \"type\" : \"sine\"}\n\t\t * @example\n\t\t * //use dot notation to access deep properties\n\t\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return\n\t\t * \t\t\t\t\t all available.\n\t\t * @returns {Object}\n\t\t */\n\t Tone.prototype.get = function (params) {\n\t if (Tone.isUndef(params)) {\n\t params = this._collectDefaults(this.constructor);\n\t } else if (Tone.isString(params)) {\n\t params = [params];\n\t }\n\t var ret = {};\n\t for (var i = 0; i < params.length; i++) {\n\t var attr = params[i];\n\t var parent = this;\n\t var subRet = ret;\n\t if (attr.indexOf('.') !== -1) {\n\t var attrSplit = attr.split('.');\n\t for (var j = 0; j < attrSplit.length - 1; j++) {\n\t var subAttr = attrSplit[j];\n\t subRet[subAttr] = subRet[subAttr] || {};\n\t subRet = subRet[subAttr];\n\t parent = parent[subAttr];\n\t }\n\t attr = attrSplit[attrSplit.length - 1];\n\t }\n\t var param = parent[attr];\n\t if (Tone.isObject(params[attr])) {\n\t subRet[attr] = param.get();\n\t } else if (Tone.Signal && param instanceof Tone.Signal) {\n\t subRet[attr] = param.value;\n\t } else if (Tone.Param && param instanceof Tone.Param) {\n\t subRet[attr] = param.value;\n\t } else if (param instanceof AudioParam) {\n\t subRet[attr] = param.value;\n\t } else if (param instanceof Tone) {\n\t subRet[attr] = param.get();\n\t } else if (!Tone.isFunction(param) && Tone.isDefined(param)) {\n\t subRet[attr] = param;\n\t }\n\t }\n\t return ret;\n\t };\n\t /**\n\t\t * collect all of the default attributes in one\n\t\t * @private\n\t\t * @param {Function} constr the constructor to find the defaults from\n\t\t * @return {Array} all of the attributes which belong to the class\n\t\t */\n\t Tone.prototype._collectDefaults = function (constr) {\n\t var ret = [];\n\t if (Tone.isDefined(constr.defaults)) {\n\t ret = Object.keys(constr.defaults);\n\t }\n\t if (Tone.isDefined(constr._super)) {\n\t var superDefs = this._collectDefaults(constr._super);\n\t //filter out repeats\n\t for (var i = 0; i < superDefs.length; i++) {\n\t if (ret.indexOf(superDefs[i]) === -1) {\n\t ret.push(superDefs[i]);\n\t }\n\t }\n\t }\n\t return ret;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tDEFAULTS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * @memberOf Tone\n\t\t * @param {Array} values The arguments array\n\t\t * @param {Array} keys The names of the arguments\n\t\t * @param {Function|Object} constr The class constructor\n\t\t * @return {Object} An object composed of the defaults between the class' defaults\n\t\t * and the passed in arguments.\n\t\t */\n\t Tone.defaults = function (values, keys, constr) {\n\t var options = {};\n\t if (values.length === 1 && Tone.isObject(values[0])) {\n\t options = values[0];\n\t } else {\n\t for (var i = 0; i < keys.length; i++) {\n\t options[keys[i]] = values[i];\n\t }\n\t }\n\t if (Tone.isDefined(constr.defaults)) {\n\t return Tone.defaultArg(options, constr.defaults);\n\t } else if (Tone.isObject(constr)) {\n\t return Tone.defaultArg(options, constr);\n\t } else {\n\t return options;\n\t }\n\t };\n\t /**\n\t\t * If the `given` parameter is undefined, use the `fallback`.\n\t\t * If both `given` and `fallback` are object literals, it will\n\t\t * return a deep copy which includes all of the parameters from both\n\t\t * objects. If a parameter is undefined in given, it will return\n\t\t * the fallback property.\n\t\t * <br><br>\n\t\t * WARNING: if object is self referential, it will go into an an\n\t\t * infinite recursive loop.\n\t\t * @memberOf Tone\n\t\t * @param {*} given\n\t\t * @param {*} fallback\n\t\t * @return {*}\n\t\t */\n\t Tone.defaultArg = function (given, fallback) {\n\t if (Tone.isObject(given) && Tone.isObject(fallback)) {\n\t var ret = {};\n\t //make a deep copy of the given object\n\t for (var givenProp in given) {\n\t ret[givenProp] = Tone.defaultArg(fallback[givenProp], given[givenProp]);\n\t }\n\t for (var fallbackProp in fallback) {\n\t ret[fallbackProp] = Tone.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t }\n\t return ret;\n\t } else {\n\t return Tone.isUndef(given) ? fallback : given;\n\t }\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tCONNECTIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * connect together all of the arguments in series\n\t\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t\t * @returns {Tone}\n\t\t * @memberOf Tone\n\t\t * @static\n\t\t */\n\t Tone.connectSeries = function () {\n\t var currentUnit = arguments[0];\n\t for (var i = 1; i < arguments.length; i++) {\n\t var toUnit = arguments[i];\n\t currentUnit.connect(toUnit);\n\t currentUnit = toUnit;\n\t }\n\t return Tone;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t // TYPE CHECKING\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Test if the arg is undefined\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is undefined\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isUndef = function (val) {\n\t return typeof val === 'undefined';\n\t };\n\t /**\n\t\t * Test if the arg is not undefined\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is undefined\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isDefined = function (val) {\n\t return !Tone.isUndef(val);\n\t };\n\t /**\n\t\t * Test if the arg is a function\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is a function\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isFunction = function (val) {\n\t return typeof val === 'function';\n\t };\n\t /**\n\t\t * Test if the argument is a number.\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is a number\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isNumber = function (arg) {\n\t return typeof arg === 'number';\n\t };\n\t /**\n\t\t * Test if the given argument is an object literal (i.e. `{}`);\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is an object literal.\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isObject = function (arg) {\n\t return Object.prototype.toString.call(arg) === '[object Object]' && arg.constructor === Object;\n\t };\n\t /**\n\t\t * Test if the argument is a boolean.\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is a boolean\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isBoolean = function (arg) {\n\t return typeof arg === 'boolean';\n\t };\n\t /**\n\t\t * Test if the argument is an Array\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is an array\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isArray = function (arg) {\n\t return Array.isArray(arg);\n\t };\n\t /**\n\t\t * Test if the argument is a string.\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is a string\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isString = function (arg) {\n\t return typeof arg === 'string';\n\t };\n\t /**\n\t\t * Test if the argument is in the form of a note in scientific pitch notation.\n\t\t * e.g. \"C4\"\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is a string\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isNote = function (arg) {\n\t return Tone.isString(arg) && /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i.test(arg);\n\t };\n\t /**\n\t\t * An empty function.\n\t\t * @static\n\t\t */\n\t Tone.noOp = function () {\n\t };\n\t /**\n\t\t * Make the property not writable. Internal use only.\n\t\t * @private\n\t\t * @param {String} property the property to make not writable\n\t\t */\n\t Tone.prototype._readOnly = function (property) {\n\t if (Array.isArray(property)) {\n\t for (var i = 0; i < property.length; i++) {\n\t this._readOnly(property[i]);\n\t }\n\t } else {\n\t Object.defineProperty(this, property, {\n\t writable: false,\n\t enumerable: true\n\t });\n\t }\n\t };\n\t /**\n\t\t * Make an attribute writeable. Interal use only.\n\t\t * @private\n\t\t * @param {String} property the property to make writable\n\t\t */\n\t Tone.prototype._writable = function (property) {\n\t if (Array.isArray(property)) {\n\t for (var i = 0; i < property.length; i++) {\n\t this._writable(property[i]);\n\t }\n\t } else {\n\t Object.defineProperty(this, property, { writable: true });\n\t }\n\t };\n\t /**\n\t\t * Possible play states.\n\t\t * @enum {String}\n\t\t */\n\t Tone.State = {\n\t Started: 'started',\n\t Stopped: 'stopped',\n\t Paused: 'paused'\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t // CONVERSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Equal power gain scale. Good for cross-fading.\n\t\t * @param {NormalRange} percent (0-1)\n\t\t * @return {Number} output gain (0-1)\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.equalPowerScale = function (percent) {\n\t var piFactor = 0.5 * Math.PI;\n\t return Math.sin(percent * piFactor);\n\t };\n\t /**\n\t\t * Convert decibels into gain.\n\t\t * @param {Decibels} db\n\t\t * @return {Number}\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.dbToGain = function (db) {\n\t return Math.pow(10, db / 20);\n\t };\n\t /**\n\t\t * Convert gain to decibels.\n\t\t * @param {Number} gain (0-1)\n\t\t * @return {Decibels}\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.gainToDb = function (gain) {\n\t return 20 * (Math.log(gain) / Math.LN10);\n\t };\n\t /**\n\t\t * Convert an interval (in semitones) to a frequency ratio.\n\t\t * @param {Interval} interval the number of semitones above the base note\n\t\t * @return {Number} the frequency ratio\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t * @example\n\t\t * tone.intervalToFrequencyRatio(0); // 1\n\t\t * tone.intervalToFrequencyRatio(12); // 2\n\t\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t\t */\n\t Tone.intervalToFrequencyRatio = function (interval) {\n\t return Math.pow(2, interval / 12);\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tTIMING\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Return the current time of the AudioContext clock.\n\t\t * @return {Number} the currentTime from the AudioContext\n\t\t * @memberOf Tone#\n\t\t */\n\t Tone.prototype.now = function () {\n\t return Tone.context.now();\n\t };\n\t /**\n\t\t * Return the current time of the AudioContext clock.\n\t\t * @return {Number} the currentTime from the AudioContext\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.now = function () {\n\t return Tone.context.now();\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tINHERITANCE\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * have a child inherit all of Tone's (or a parent's) prototype\n\t\t * to inherit the parent's properties, make sure to call\n\t\t * Parent.call(this) in the child's constructor\n\t\t *\n\t\t * based on closure library's inherit function\n\t\t *\n\t\t * @memberOf Tone\n\t\t * @static\n\t\t * @param {Function} \tchild\n\t\t * @param {Function=} parent (optional) parent to inherit from\n\t\t * if no parent is supplied, the child\n\t\t * will inherit from Tone\n\t\t */\n\t Tone.extend = function (child, parent) {\n\t if (Tone.isUndef(parent)) {\n\t parent = Tone;\n\t }\n\t function TempConstructor() {\n\t }\n\t TempConstructor.prototype = parent.prototype;\n\t child.prototype = new TempConstructor();\n\t /** @override */\n\t child.prototype.constructor = child;\n\t child._super = parent;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tCONTEXT\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Private reference to the global AudioContext\n\t\t * @type {AudioContext}\n\t\t * @private\n\t\t */\n\t var audioContext = null;\n\t /**\n\t\t * A static pointer to the audio context accessible as Tone.context.\n\t\t * @type {Tone.Context}\n\t\t * @name context\n\t\t * @memberOf Tone\n\t\t */\n\t Object.defineProperty(Tone, 'context', {\n\t get: function () {\n\t return audioContext;\n\t },\n\t set: function (context) {\n\t if (Tone.Context && context instanceof Tone.Context) {\n\t audioContext = context;\n\t } else {\n\t audioContext = new Tone.Context(context);\n\t }\n\t //initialize the new audio context\n\t Tone.Context.emit('init', audioContext);\n\t }\n\t });\n\t /**\n\t\t * The AudioContext\n\t\t * @type {Tone.Context}\n\t\t * @name context\n\t\t * @memberOf Tone#\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.prototype, 'context', {\n\t get: function () {\n\t return Tone.context;\n\t }\n\t });\n\t /**\n\t\t * Tone automatically creates a context on init, but if you are working\n\t\t * with other libraries which also create an AudioContext, it can be\n\t\t * useful to set your own. If you are going to set your own context,\n\t\t * be sure to do it at the start of your code, before creating any objects.\n\t\t * @static\n\t\t * @param {AudioContext} ctx The new audio context to set\n\t\t */\n\t Tone.setContext = function (ctx) {\n\t Tone.context = ctx;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tATTRIBUTES\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * The number of seconds of 1 processing block (128 samples)\n\t\t * @type {Number}\n\t\t * @name blockTime\n\t\t * @memberOf Tone\n\t\t * @static\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.prototype, 'blockTime', {\n\t get: function () {\n\t return 128 / this.context.sampleRate;\n\t }\n\t });\n\t /**\n\t\t * The duration in seconds of one sample.\n\t\t * @type {Number}\n\t\t * @name sampleTime\n\t\t * @memberOf Tone\n\t\t * @static\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.prototype, 'sampleTime', {\n\t get: function () {\n\t return 1 / this.context.sampleRate;\n\t }\n\t });\n\t /**\n\t\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser.\n\t\t * @type {Boolean}\n\t\t * @name supported\n\t\t * @memberOf Tone\n\t\t * @readOnly\n\t\t * @static\n\t\t */\n\t Object.defineProperty(Tone, 'supported', {\n\t get: function () {\n\t var hasAudioContext = window.hasOwnProperty('AudioContext') || window.hasOwnProperty('webkitAudioContext');\n\t var hasPromises = window.hasOwnProperty('Promise');\n\t var hasWorkers = window.hasOwnProperty('Worker');\n\t return hasAudioContext && hasPromises && hasWorkers;\n\t }\n\t });\n\t /**\n\t\t * Boolean value if the audio context has been initialized.\n\t\t * @type {Boolean}\n\t\t * @memberOf Tone\n\t\t * @static\n\t\t * @name initialized\n\t\t */\n\t Object.defineProperty(Tone, 'initialized', {\n\t get: function () {\n\t return audioContext !== null;\n\t }\n\t });\n\t /**\n\t\t * Get the context when it becomes available\n\t\t * @param {Function} resolve Callback when the context is initialized\n\t\t * @return {Tone}\n\t\t */\n\t Tone.getContext = function (resolve) {\n\t if (Tone.initialized) {\n\t resolve(Tone.context);\n\t } else {\n\t var resCallback = function () {\n\t resolve(Tone.context);\n\t Tone.Context.off('init', resCallback);\n\t };\n\t Tone.Context.on('init', resCallback);\n\t }\n\t return Tone;\n\t };\n\t /**\n\t\t * The version number\n\t\t * @type {String}\n\t\t * @static\n\t\t */\n\t Tone.version = 'r12';\n\t return Tone;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Emitter gives classes which extend it\n\t\t * the ability to listen for and emit events.\n\t\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t\t * MIT (c) 2011 Jerome Etienne.\n\t\t *\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.Emitter = function () {\n\t Tone.call(this);\n\t /**\n\t\t\t * Contains all of the events.\n\t\t\t * @private\n\t\t\t * @type {Object}\n\t\t\t */\n\t this._events = {};\n\t };\n\t Tone.extend(Tone.Emitter);\n\t /**\n\t\t * Bind a callback to a specific event.\n\t\t * @param {String} event The name of the event to listen for.\n\t\t * @param {Function} callback The callback to invoke when the\n\t\t * event is emitted\n\t\t * @return {Tone.Emitter} this\n\t\t */\n\t Tone.Emitter.prototype.on = function (event, callback) {\n\t //split the event\n\t var events = event.split(/\\W+/);\n\t for (var i = 0; i < events.length; i++) {\n\t var eventName = events[i];\n\t if (!this._events.hasOwnProperty(eventName)) {\n\t this._events[eventName] = [];\n\t }\n\t this._events[eventName].push(callback);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Bind a callback which is only invoked once\n\t\t * @param {String} event The name of the event to listen for.\n\t\t * @param {Function} callback The callback to invoke when the\n\t\t * event is emitted\n\t\t * @return {Tone.Emitter} this\n\t\t */\n\t Tone.Emitter.prototype.once = function (event, callback) {\n\t var boundCallback = function () {\n\t //invoke the callback\n\t callback.apply(this, arguments);\n\t this.off(event, boundCallback);\n\t }.bind(this);\n\t this.on(event, boundCallback);\n\t return this;\n\t };\n\t /**\n\t\t * Remove the event listener.\n\t\t * @param {String} event The event to stop listening to.\n\t\t * @param {Function=} callback The callback which was bound to\n\t\t * the event with Tone.Emitter.on.\n\t\t * If no callback is given, all callbacks\n\t\t * events are removed.\n\t\t * @return {Tone.Emitter} this\n\t\t */\n\t Tone.Emitter.prototype.off = function (event, callback) {\n\t var events = event.split(/\\W+/);\n\t for (var ev = 0; ev < events.length; ev++) {\n\t event = events[ev];\n\t if (this._events.hasOwnProperty(event)) {\n\t if (Tone.isUndef(callback)) {\n\t this._events[event] = [];\n\t } else {\n\t var eventList = this._events[event];\n\t for (var i = 0; i < eventList.length; i++) {\n\t if (eventList[i] === callback) {\n\t eventList.splice(i, 1);\n\t }\n\t }\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Invoke all of the callbacks bound to the event\n\t\t * with any arguments passed in.\n\t\t * @param {String} event The name of the event.\n\t\t * @param {*} args... The arguments to pass to the functions listening.\n\t\t * @return {Tone.Emitter} this\n\t\t */\n\t Tone.Emitter.prototype.emit = function (event) {\n\t if (this._events) {\n\t var args = Array.apply(null, arguments).slice(1);\n\t if (this._events.hasOwnProperty(event)) {\n\t var eventList = this._events[event].slice(0);\n\t for (var i = 0, len = eventList.length; i < len; i++) {\n\t eventList[i].apply(this, args);\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Add Emitter functions (on/off/emit) to the object\n\t\t * @param {Object|Function} object The object or class to extend.\n\t\t * @returns {Tone.Emitter}\n\t\t */\n\t Tone.Emitter.mixin = function (object) {\n\t var functions = [\n\t 'on',\n\t 'once',\n\t 'off',\n\t 'emit'\n\t ];\n\t object._events = {};\n\t for (var i = 0; i < functions.length; i++) {\n\t var func = functions[i];\n\t var emitterFunc = Tone.Emitter.prototype[func];\n\t object[func] = emitterFunc;\n\t }\n\t return Tone.Emitter;\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Emitter} this\n\t\t */\n\t Tone.Emitter.prototype.dispose = function () {\n\t Tone.prototype.dispose.call(this);\n\t this._events = null;\n\t return this;\n\t };\n\t return Tone.Emitter;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A Timeline class for scheduling and maintaining state\n\t\t * along a timeline. All events must have a \"time\" property.\n\t\t * Internally, events are stored in time order for fast\n\t\t * retrieval.\n\t\t * @extends {Tone}\n\t\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t\t */\n\t Tone.Timeline = function () {\n\t var options = Tone.defaults(arguments, ['memory'], Tone.Timeline);\n\t Tone.call(this);\n\t /**\n\t\t\t * The array of scheduled timeline events\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._timeline = [];\n\t /**\n\t\t\t * The memory of the timeline, i.e.\n\t\t\t * how many events in the past it will retain\n\t\t\t * @type {Positive}\n\t\t\t */\n\t this.memory = options.memory;\n\t };\n\t Tone.extend(Tone.Timeline);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t * @const\n\t\t */\n\t Tone.Timeline.defaults = { 'memory': Infinity };\n\t /**\n\t\t * The number of items in the timeline.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Timeline#\n\t\t * @name length\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Timeline.prototype, 'length', {\n\t get: function () {\n\t return this._timeline.length;\n\t }\n\t });\n\t /**\n\t\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t\t * @param {Object} event The event object to insert into the\n\t\t * timeline.\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.add = function (event) {\n\t //the event needs to have a time attribute\n\t if (Tone.isUndef(event.time)) {\n\t throw new Error('Tone.Timeline: events must have a time attribute');\n\t }\n\t event.time = event.time.valueOf();\n\t var index = this._search(event.time);\n\t this._timeline.splice(index + 1, 0, event);\n\t //if the length is more than the memory, remove the previous ones\n\t if (this.length > this.memory) {\n\t var diff = this.length - this.memory;\n\t this._timeline.splice(0, diff);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Remove an event from the timeline.\n\t\t * @param {Object} event The event object to remove from the list.\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.remove = function (event) {\n\t var index = this._timeline.indexOf(event);\n\t if (index !== -1) {\n\t this._timeline.splice(index, 1);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Get the nearest event whose time is less than or equal to the given time.\n\t\t * @param {Number} time The time to query.\n\t\t * @param {String} comparator Which value in the object to compare\n\t\t * @returns {Object} The event object set after that time.\n\t\t */\n\t Tone.Timeline.prototype.get = function (time, comparator) {\n\t comparator = Tone.defaultArg(comparator, 'time');\n\t var index = this._search(time, comparator);\n\t if (index !== -1) {\n\t return this._timeline[index];\n\t } else {\n\t return null;\n\t }\n\t };\n\t /**\n\t\t * Return the first event in the timeline without removing it\n\t\t * @returns {Object} The first event object\n\t\t */\n\t Tone.Timeline.prototype.peek = function () {\n\t return this._timeline[0];\n\t };\n\t /**\n\t\t * Return the first event in the timeline and remove it\n\t\t * @returns {Object} The first event object\n\t\t */\n\t Tone.Timeline.prototype.shift = function () {\n\t return this._timeline.shift();\n\t };\n\t /**\n\t\t * Get the event which is scheduled after the given time.\n\t\t * @param {Number} time The time to query.\n\t\t * @param {String} comparator Which value in the object to compare\n\t\t * @returns {Object} The event object after the given time\n\t\t */\n\t Tone.Timeline.prototype.getAfter = function (time, comparator) {\n\t comparator = Tone.defaultArg(comparator, 'time');\n\t var index = this._search(time, comparator);\n\t if (index + 1 < this._timeline.length) {\n\t return this._timeline[index + 1];\n\t } else {\n\t return null;\n\t }\n\t };\n\t /**\n\t\t * Get the event before the event at the given time.\n\t\t * @param {Number} time The time to query.\n\t\t * @param {String} comparator Which value in the object to compare\n\t\t * @returns {Object} The event object before the given time\n\t\t */\n\t Tone.Timeline.prototype.getBefore = function (time, comparator) {\n\t comparator = Tone.defaultArg(comparator, 'time');\n\t var len = this._timeline.length;\n\t //if it's after the last item, return the last item\n\t if (len > 0 && this._timeline[len - 1][comparator] < time) {\n\t return this._timeline[len - 1];\n\t }\n\t var index = this._search(time, comparator);\n\t if (index - 1 >= 0) {\n\t return this._timeline[index - 1];\n\t } else {\n\t return null;\n\t }\n\t };\n\t /**\n\t\t * Cancel events after the given time\n\t\t * @param {Number} time The time to query.\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.cancel = function (after) {\n\t if (this._timeline.length > 1) {\n\t var index = this._search(after);\n\t if (index >= 0) {\n\t if (this._timeline[index].time === after) {\n\t //get the first item with that time\n\t for (var i = index; i >= 0; i--) {\n\t if (this._timeline[i].time === after) {\n\t index = i;\n\t } else {\n\t break;\n\t }\n\t }\n\t this._timeline = this._timeline.slice(0, index);\n\t } else {\n\t this._timeline = this._timeline.slice(0, index + 1);\n\t }\n\t } else {\n\t this._timeline = [];\n\t }\n\t } else if (this._timeline.length === 1) {\n\t //the first item's time\n\t if (this._timeline[0].time >= after) {\n\t this._timeline = [];\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Cancel events before or equal to the given time.\n\t\t * @param {Number} time The time to cancel before.\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.cancelBefore = function (time) {\n\t var index = this._search(time);\n\t if (index >= 0) {\n\t this._timeline = this._timeline.slice(index + 1);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Returns the previous event if there is one. null otherwise\n\t\t * @param {Object} event The event to find the previous one of\n\t\t * @return {Object} The event right before the given event\n\t\t */\n\t Tone.Timeline.prototype.previousEvent = function (event) {\n\t var index = this._timeline.indexOf(event);\n\t if (index > 0) {\n\t return this._timeline[index - 1];\n\t } else {\n\t return null;\n\t }\n\t };\n\t /**\n\t\t * Does a binary search on the timeline array and returns the\n\t\t * nearest event index whose time is after or equal to the given time.\n\t\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t\t * If the time is after the end, the index of the last item is returned.\n\t\t * @param {Number} time\n\t\t * @param {String} comparator Which value in the object to compare\n\t\t * @return {Number} the index in the timeline array\n\t\t * @private\n\t\t */\n\t Tone.Timeline.prototype._search = function (time, comparator) {\n\t if (this._timeline.length === 0) {\n\t return -1;\n\t }\n\t comparator = Tone.defaultArg(comparator, 'time');\n\t var beginning = 0;\n\t var len = this._timeline.length;\n\t var end = len;\n\t if (len > 0 && this._timeline[len - 1][comparator] <= time) {\n\t return len - 1;\n\t }\n\t while (beginning < end) {\n\t // calculate the midpoint for roughly equal partition\n\t var midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t var event = this._timeline[midPoint];\n\t var nextEvent = this._timeline[midPoint + 1];\n\t if (event[comparator] === time) {\n\t //choose the last one that has the same time\n\t for (var i = midPoint; i < this._timeline.length; i++) {\n\t var testEvent = this._timeline[i];\n\t if (testEvent[comparator] === time) {\n\t midPoint = i;\n\t }\n\t }\n\t return midPoint;\n\t } else if (event[comparator] < time && nextEvent[comparator] > time) {\n\t return midPoint;\n\t } else if (event[comparator] > time) {\n\t //search lower\n\t end = midPoint;\n\t } else {\n\t //search upper\n\t beginning = midPoint + 1;\n\t }\n\t }\n\t return -1;\n\t };\n\t /**\n\t\t * Internal iterator. Applies extra safety checks for\n\t\t * removing items from the array.\n\t\t * @param {Function} callback\n\t\t * @param {Number=} lowerBound\n\t\t * @param {Number=} upperBound\n\t\t * @private\n\t\t */\n\t Tone.Timeline.prototype._iterate = function (callback, lowerBound, upperBound) {\n\t lowerBound = Tone.defaultArg(lowerBound, 0);\n\t upperBound = Tone.defaultArg(upperBound, this._timeline.length - 1);\n\t this._timeline.slice(lowerBound, upperBound + 1).forEach(function (event) {\n\t callback.call(this, event);\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Iterate over everything in the array\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.forEach = function (callback) {\n\t this._iterate(callback);\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array at or before the given time.\n\t\t * @param {Number} time The time to check if items are before\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.forEachBefore = function (time, callback) {\n\t //iterate over the items in reverse so that removing an item doesn't break things\n\t var upperBound = this._search(time);\n\t if (upperBound !== -1) {\n\t this._iterate(callback, 0, upperBound);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array after the given time.\n\t\t * @param {Number} time The time to check if items are before\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.forEachAfter = function (time, callback) {\n\t //iterate over the items in reverse so that removing an item doesn't break things\n\t var lowerBound = this._search(time);\n\t this._iterate(callback, lowerBound + 1);\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array between the startTime and endTime. \n\t\t * The timerange is inclusive of the startTime, but exclusive of the endTime. \n\t\t * range = [startTime, endTime). \n\t\t * @param {Number} startTime The time to check if items are before\n\t\t * @param {Number} endTime The end of the test interval. \n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.forEachBetween = function (startTime, endTime, callback) {\n\t var lowerBound = this._search(startTime);\n\t var upperBound = this._search(endTime);\n\t if (lowerBound !== -1 && upperBound !== -1) {\n\t if (this._timeline[lowerBound].time !== startTime) {\n\t lowerBound += 1;\n\t }\n\t //exclusive of the end time\n\t if (this._timeline[upperBound].time === endTime) {\n\t upperBound -= 1;\n\t }\n\t this._iterate(callback, lowerBound, upperBound);\n\t } else if (lowerBound === -1) {\n\t this._iterate(callback, 0, upperBound);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array at or after the given time. Similar to\n\t\t * forEachAfter, but includes the item(s) at the given time.\n\t\t * @param {Number} time The time to check if items are before\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.forEachFrom = function (time, callback) {\n\t //iterate over the items in reverse so that removing an item doesn't break things\n\t var lowerBound = this._search(time);\n\t //work backwards until the event time is less than time\n\t while (lowerBound >= 0 && this._timeline[lowerBound].time >= time) {\n\t lowerBound--;\n\t }\n\t this._iterate(callback, lowerBound + 1);\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array at the given time\n\t\t * @param {Number} time The time to check if items are before\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.forEachAtTime = function (time, callback) {\n\t //iterate over the items in reverse so that removing an item doesn't break things\n\t var upperBound = this._search(time);\n\t if (upperBound !== -1) {\n\t this._iterate(function (event) {\n\t if (event.time === time) {\n\t callback.call(this, event);\n\t }\n\t }, 0, upperBound);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.dispose = function () {\n\t Tone.prototype.dispose.call(this);\n\t this._timeline = null;\n\t return this;\n\t };\n\t return Tone.Timeline;\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported) {\n\t if (!window.hasOwnProperty('OfflineAudioContext') && window.hasOwnProperty('webkitOfflineAudioContext')) {\n\t window.OfflineAudioContext = window.webkitOfflineAudioContext;\n\t }\n\t //returns promise?\n\t var context = new OfflineAudioContext(1, 1, 44100);\n\t var ret = context.startRendering();\n\t if (!(ret instanceof Promise)) {\n\t OfflineAudioContext.prototype._native_startRendering = OfflineAudioContext.prototype.startRendering;\n\t OfflineAudioContext.prototype.startRendering = function () {\n\t return new Promise(function (done) {\n\t this.oncomplete = function (e) {\n\t done(e.renderedBuffer);\n\t };\n\t this._native_startRendering();\n\t }.bind(this));\n\t };\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported) {\n\t if (!window.hasOwnProperty('AudioContext') && window.hasOwnProperty('webkitAudioContext')) {\n\t window.AudioContext = window.webkitAudioContext;\n\t }\n\t //not functionally equivalent, but only an API placeholder\n\t if (!AudioContext.prototype.close) {\n\t AudioContext.prototype.close = function () {\n\t if (Tone.isFunction(this.suspend)) {\n\t this.suspend();\n\t }\n\t return Promise.resolve();\n\t };\n\t }\n\t //not functionally equivalent\n\t if (!AudioContext.prototype.resume) {\n\t AudioContext.prototype.resume = function () {\n\t return Promise.resolve();\n\t };\n\t }\n\t //createGain\n\t if (!AudioContext.prototype.createGain && AudioContext.prototype.createGainNode) {\n\t AudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t }\n\t //createDelay\n\t if (!AudioContext.prototype.createDelay && AudioContext.prototype.createDelayNode) {\n\t AudioContext.prototype.createDelay = AudioContext.prototype.createDelayNode;\n\t }\n\t //test decodeAudioData returns a promise\n\t // https://github.com/mohayonao/web-audio-api-shim/blob/master/src/AudioContext.js\n\t // MIT License (c) 2015 @mohayonao\n\t var decodeAudioDataPromise = false;\n\t var offlineContext = new OfflineAudioContext(1, 1, 44100);\n\t var audioData = new Uint32Array([\n\t 1179011410,\n\t 48,\n\t 1163280727,\n\t 544501094,\n\t 16,\n\t 131073,\n\t 44100,\n\t 176400,\n\t 1048580,\n\t 1635017060,\n\t 8,\n\t 0,\n\t 0,\n\t 0,\n\t 0\n\t ]).buffer;\n\t try {\n\t var ret = offlineContext.decodeAudioData(audioData);\n\t if (ret instanceof Promise) {\n\t decodeAudioDataPromise = true;\n\t }\n\t } catch (e) {\n\t decodeAudioDataPromise = false;\n\t }\n\t if (!decodeAudioDataPromise) {\n\t AudioContext.prototype._native_decodeAudioData = AudioContext.prototype.decodeAudioData;\n\t AudioContext.prototype.decodeAudioData = function (audioData) {\n\t return new Promise(function (success, error) {\n\t this._native_decodeAudioData(audioData, success, error);\n\t }.bind(this));\n\t };\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Wrapper around the native AudioContext.\n\t\t * @extends {Tone.Emitter}\n\t\t * @param {AudioContext=} context optionally pass in a context\n\t\t */\n\t Tone.Context = function () {\n\t Tone.Emitter.call(this);\n\t var options = Tone.defaults(arguments, ['context'], Tone.Context);\n\t if (!options.context) {\n\t options.context = new window.AudioContext();\n\t if (!options.context) {\n\t throw new Error('could not create AudioContext. Possibly too many AudioContexts running already.');\n\t }\n\t }\n\t this._context = options.context;\n\t // extend all of the methods\n\t for (var prop in this._context) {\n\t this._defineProperty(this._context, prop);\n\t }\n\t /**\n\t\t\t * The default latency hint\n\t\t\t * @type {String}\n\t\t\t * @private\n\t\t\t */\n\t this._latencyHint = options.latencyHint;\n\t /**\n\t\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t\t * @type {Object}\n\t\t\t * @private\n\t\t\t */\n\t this._constants = {};\n\t ///////////////////////////////////////////////////////////////////////\n\t // WORKER\n\t ///////////////////////////////////////////////////////////////////////\n\t /**\n\t\t\t * The amount of time events are scheduled\n\t\t\t * into the future\n\t\t\t * @type {Number}\n\t\t\t */\n\t this.lookAhead = options.lookAhead;\n\t /**\n\t\t\t * A reference to the actual computed update interval\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._computedUpdateInterval = 0;\n\t /**\n\t\t\t * A reliable callback method\n\t\t\t * @private\n\t\t\t * @type {Ticker}\n\t\t\t */\n\t this._ticker = new Ticker(this.emit.bind(this, 'tick'), options.clockSource, options.updateInterval);\n\t ///////////////////////////////////////////////////////////////////////\n\t // TIMEOUTS\n\t ///////////////////////////////////////////////////////////////////////\n\t /**\n\t\t\t * All of the setTimeout events.\n\t\t\t * @type {Tone.Timeline}\n\t\t\t * @private\n\t\t\t */\n\t this._timeouts = new Tone.Timeline();\n\t /**\n\t\t\t * The timeout id counter\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._timeoutIds = 0;\n\t this.on('tick', this._timeoutLoop.bind(this));\n\t };\n\t Tone.extend(Tone.Context, Tone.Emitter);\n\t Tone.Emitter.mixin(Tone.Context);\n\t /**\n\t\t * defaults\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Context.defaults = {\n\t 'clockSource': 'worker',\n\t 'latencyHint': 'interactive',\n\t 'lookAhead': 0.1,\n\t 'updateInterval': 0.03\n\t };\n\t /**\n\t\t * Define a property on this Tone.Context.\n\t\t * This is used to extend the native AudioContext\n\t\t * @param {AudioContext} context\n\t\t * @param {String} prop\n\t\t * @private\n\t\t */\n\t Tone.Context.prototype._defineProperty = function (context, prop) {\n\t if (Tone.isUndef(this[prop])) {\n\t Object.defineProperty(this, prop, {\n\t get: function () {\n\t if (typeof context[prop] === 'function') {\n\t return context[prop].bind(context);\n\t } else {\n\t return context[prop];\n\t }\n\t },\n\t set: function (val) {\n\t context[prop] = val;\n\t }\n\t });\n\t }\n\t };\n\t /**\n\t\t * The current audio context time\n\t\t * @return {Number}\n\t\t */\n\t Tone.Context.prototype.now = function () {\n\t return this._context.currentTime + this.lookAhead;\n\t };\n\t /**\n\t\t * Promise which is invoked when the context is running.\n\t\t * Tries to resume the context if it's not started.\n\t\t * @return {Promise}\n\t\t */\n\t Tone.Context.prototype.ready = function () {\n\t return new Promise(function (done) {\n\t if (this._context.state === 'running') {\n\t done();\n\t } else {\n\t this._context.resume().then(function () {\n\t done();\n\t });\n\t }\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Promise which is invoked when the context is running.\n\t\t * Tries to resume the context if it's not started.\n\t\t * @return {Promise}\n\t\t */\n\t Tone.Context.prototype.close = function () {\n\t return this._context.close().then(function () {\n\t Tone.Context.emit('close', this);\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Generate a looped buffer at some constant value.\n\t\t * @param {Number} val\n\t\t * @return {BufferSourceNode}\n\t\t */\n\t Tone.Context.prototype.getConstant = function (val) {\n\t if (this._constants[val]) {\n\t return this._constants[val];\n\t } else {\n\t var buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t var arr = buffer.getChannelData(0);\n\t for (var i = 0; i < arr.length; i++) {\n\t arr[i] = val;\n\t }\n\t var constant = this._context.createBufferSource();\n\t constant.channelCount = 1;\n\t constant.channelCountMode = 'explicit';\n\t constant.buffer = buffer;\n\t constant.loop = true;\n\t constant.start(0);\n\t this._constants[val] = constant;\n\t return constant;\n\t }\n\t };\n\t /**\n\t\t * The private loop which keeps track of the context scheduled timeouts\n\t\t * Is invoked from the clock source\n\t\t * @private\n\t\t */\n\t Tone.Context.prototype._timeoutLoop = function () {\n\t var now = this.now();\n\t while (this._timeouts && this._timeouts.length && this._timeouts.peek().time <= now) {\n\t this._timeouts.shift().callback();\n\t }\n\t };\n\t /**\n\t\t * A setTimeout which is gaurenteed by the clock source.\n\t\t * Also runs in the offline context.\n\t\t * @param {Function} fn The callback to invoke\n\t\t * @param {Seconds} timeout The timeout in seconds\n\t\t * @returns {Number} ID to use when invoking Tone.Context.clearTimeout\n\t\t */\n\t Tone.Context.prototype.setTimeout = function (fn, timeout) {\n\t this._timeoutIds++;\n\t var now = this.now();\n\t this._timeouts.add({\n\t callback: fn,\n\t time: now + timeout,\n\t id: this._timeoutIds\n\t });\n\t return this._timeoutIds;\n\t };\n\t /**\n\t\t * Clears a previously scheduled timeout with Tone.context.setTimeout\n\t\t * @param {Number} id The ID returned from setTimeout\n\t\t * @return {Tone.Context} this\n\t\t */\n\t Tone.Context.prototype.clearTimeout = function (id) {\n\t this._timeouts.forEach(function (event) {\n\t if (event.id === id) {\n\t this.remove(event);\n\t }\n\t });\n\t return this;\n\t };\n\t /**\n\t\t * How often the Web Worker callback is invoked.\n\t\t * This number corresponds to how responsive the scheduling\n\t\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t\t * total latency between scheduling an event and hearing it.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Context#\n\t\t * @name updateInterval\n\t\t */\n\t Object.defineProperty(Tone.Context.prototype, 'updateInterval', {\n\t get: function () {\n\t return this._ticker.updateInterval;\n\t },\n\t set: function (interval) {\n\t this._ticker.updateInterval = interval;\n\t }\n\t });\n\t /**\n\t\t * What the source of the clock is, either \"worker\" (Web Worker [default]),\n\t\t * \"timeout\" (setTimeout), or \"offline\" (none).\n\t\t * @type {String}\n\t\t * @memberOf Tone.Context#\n\t\t * @name clockSource\n\t\t */\n\t Object.defineProperty(Tone.Context.prototype, 'clockSource', {\n\t get: function () {\n\t return this._ticker.type;\n\t },\n\t set: function (type) {\n\t this._ticker.type = type;\n\t }\n\t });\n\t /**\n\t\t * The type of playback, which affects tradeoffs between audio\n\t\t * output latency and responsiveness.\n\t\t *\n\t\t * In addition to setting the value in seconds, the latencyHint also\n\t\t * accepts the strings \"interactive\" (prioritizes low latency),\n\t\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often).\n\t\t * @type {String|Seconds}\n\t\t * @memberOf Tone.Context#\n\t\t * @name latencyHint\n\t\t * @example\n\t\t * //set the lookAhead to 0.3 seconds\n\t\t * Tone.context.latencyHint = 0.3;\n\t\t */\n\t Object.defineProperty(Tone.Context.prototype, 'latencyHint', {\n\t get: function () {\n\t return this._latencyHint;\n\t },\n\t set: function (hint) {\n\t var lookAhead = hint;\n\t this._latencyHint = hint;\n\t if (Tone.isString(hint)) {\n\t switch (hint) {\n\t case 'interactive':\n\t lookAhead = 0.1;\n\t this._context.latencyHint = hint;\n\t break;\n\t case 'playback':\n\t lookAhead = 0.8;\n\t this._context.latencyHint = hint;\n\t break;\n\t case 'balanced':\n\t lookAhead = 0.25;\n\t this._context.latencyHint = hint;\n\t break;\n\t case 'fastest':\n\t this._context.latencyHint = 'interactive';\n\t lookAhead = 0.01;\n\t break;\n\t }\n\t }\n\t this.lookAhead = lookAhead;\n\t this.updateInterval = lookAhead / 3;\n\t }\n\t });\n\t /**\n\t\t * Unlike other dispose methods, this returns a Promise\n\t\t * which executes when the context is closed and disposed\n\t\t * @returns {Promise} this\n\t\t */\n\t Tone.Context.prototype.dispose = function () {\n\t return this.close().then(function () {\n\t Tone.Emitter.prototype.dispose.call(this);\n\t this._ticker.dispose();\n\t this._ticker = null;\n\t this._timeouts.dispose();\n\t this._timeouts = null;\n\t for (var con in this._constants) {\n\t this._constants[con].disconnect();\n\t }\n\t this._constants = null;\n\t }.bind(this));\n\t };\n\t /**\n\t\t * @class A class which provides a reliable callback using either\n\t\t * a Web Worker, or if that isn't supported, falls back to setTimeout.\n\t\t * @private\n\t\t */\n\t var Ticker = function (callback, type, updateInterval) {\n\t /**\n\t\t\t * Either \"worker\" or \"timeout\"\n\t\t\t * @type {String}\n\t\t\t * @private\n\t\t\t */\n\t this._type = type;\n\t /**\n\t\t\t * The update interval of the worker\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._updateInterval = updateInterval;\n\t /**\n\t\t\t * The callback to invoke at regular intervals\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._callback = Tone.defaultArg(callback, Tone.noOp);\n\t //create the clock source for the first time\n\t this._createClock();\n\t };\n\t /**\n\t\t * The possible ticker types\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t Ticker.Type = {\n\t Worker: 'worker',\n\t Timeout: 'timeout',\n\t Offline: 'offline'\n\t };\n\t /**\n\t\t * Generate a web worker\n\t\t * @return {WebWorker}\n\t\t * @private\n\t\t */\n\t Ticker.prototype._createWorker = function () {\n\t //URL Shim\n\t window.URL = window.URL || window.webkitURL;\n\t var blob = new Blob([//the initial timeout time\n\t 'var timeoutTime = ' + (this._updateInterval * 1000).toFixed(1) + ';' + //onmessage callback\n\t 'self.onmessage = function(msg){' + '\\ttimeoutTime = parseInt(msg.data);' + '};' + //the tick function which posts a message\n\t //and schedules a new tick\n\t 'function tick(){' + '\\tsetTimeout(tick, timeoutTime);' + '\\tself.postMessage(\\'tick\\');' + '}' + //call tick initially\n\t 'tick();']);\n\t var blobUrl = URL.createObjectURL(blob);\n\t var worker = new Worker(blobUrl);\n\t worker.onmessage = this._callback.bind(this);\n\t this._worker = worker;\n\t };\n\t /**\n\t\t * Create a timeout loop\n\t\t * @private\n\t\t */\n\t Ticker.prototype._createTimeout = function () {\n\t this._timeout = setTimeout(function () {\n\t this._createTimeout();\n\t this._callback();\n\t }.bind(this), this._updateInterval * 1000);\n\t };\n\t /**\n\t\t * Create the clock source.\n\t\t * @private\n\t\t */\n\t Ticker.prototype._createClock = function () {\n\t if (this._type === Ticker.Type.Worker) {\n\t try {\n\t this._createWorker();\n\t } catch (e) {\n\t // workers not supported, fallback to timeout\n\t this._type = Ticker.Type.Timeout;\n\t this._createClock();\n\t }\n\t } else if (this._type === Ticker.Type.Timeout) {\n\t this._createTimeout();\n\t }\n\t };\n\t /**\n\t\t * @memberOf Ticker#\n\t\t * @type {Number}\n\t\t * @name updateInterval\n\t\t * @private\n\t\t */\n\t Object.defineProperty(Ticker.prototype, 'updateInterval', {\n\t get: function () {\n\t return this._updateInterval;\n\t },\n\t set: function (interval) {\n\t this._updateInterval = Math.max(interval, 128 / 44100);\n\t if (this._type === Ticker.Type.Worker) {\n\t this._worker.postMessage(Math.max(interval * 1000, 1));\n\t }\n\t }\n\t });\n\t /**\n\t\t * The type of the ticker, either a worker or a timeout\n\t\t * @memberOf Ticker#\n\t\t * @type {Number}\n\t\t * @name type\n\t\t * @private\n\t\t */\n\t Object.defineProperty(Ticker.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t this._disposeClock();\n\t this._type = type;\n\t this._createClock();\n\t }\n\t });\n\t /**\n\t\t * Clean up the current clock source\n\t\t * @private\n\t\t */\n\t Ticker.prototype._disposeClock = function () {\n\t if (this._timeout) {\n\t clearTimeout(this._timeout);\n\t this._timeout = null;\n\t }\n\t if (this._worker) {\n\t this._worker.terminate();\n\t this._worker.onmessage = null;\n\t this._worker = null;\n\t }\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @private\n\t\t */\n\t Ticker.prototype.dispose = function () {\n\t this._disposeClock();\n\t this._callback = null;\n\t };\n\t /**\n\t\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t\t * some older implementations.\n\t\t * @private\n\t\t */\n\t Tone.getContext(function () {\n\t var nativeConnect = AudioNode.prototype.connect;\n\t var nativeDisconnect = AudioNode.prototype.disconnect;\n\t //replace the old connect method\n\t function toneConnect(B, outNum, inNum) {\n\t if (B.input) {\n\t inNum = Tone.defaultArg(inNum, 0);\n\t if (Tone.isArray(B.input)) {\n\t return this.connect(B.input[inNum]);\n\t } else {\n\t return this.connect(B.input, outNum, inNum);\n\t }\n\t } else {\n\t try {\n\t if (B instanceof AudioNode) {\n\t nativeConnect.call(this, B, outNum, inNum);\n\t return B;\n\t } else {\n\t nativeConnect.call(this, B, outNum);\n\t return B;\n\t }\n\t } catch (e) {\n\t throw new Error('error connecting to node: ' + B + '\\n' + e);\n\t }\n\t }\n\t }\n\t //replace the old disconnect method\n\t function toneDisconnect(B, outNum, inNum) {\n\t if (B && B.input && Tone.isArray(B.input)) {\n\t inNum = Tone.defaultArg(inNum, 0);\n\t this.disconnect(B.input[inNum], outNum, 0);\n\t } else if (B && B.input) {\n\t this.disconnect(B.input, outNum, inNum);\n\t } else {\n\t try {\n\t nativeDisconnect.apply(this, arguments);\n\t } catch (e) {\n\t throw new Error('error disconnecting node: ' + B + '\\n' + e);\n\t }\n\t }\n\t }\n\t if (AudioNode.prototype.connect !== toneConnect) {\n\t AudioNode.prototype.connect = toneConnect;\n\t AudioNode.prototype.disconnect = toneDisconnect;\n\t }\n\t });\n\t // set the audio context initially, and if one is not already created\n\t if (Tone.supported && !Tone.initialized) {\n\t Tone.context = new Tone.Context();\n\t // log on first initialization\n\t // allow optional silencing of this log\n\t if (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t // eslint-disable-next-line no-console\n\t console.log('%c * Tone.js ' + Tone.version + ' * ', 'background: #000; color: #fff');\n\t }\n\t } else if (!Tone.supported) {\n\t // eslint-disable-next-line no-console\n\t console.warn('This browser does not support Tone.js');\n\t }\n\t return Tone.Context;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.AudioNode is the base class for classes which process audio.\n\t\t * AudioNodes have inputs and outputs.\n\t\t * @param\t{AudioContext=} context\tThe audio context to use with the class\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.AudioNode = function () {\n\t Tone.call(this);\n\t //use the default context if one is not passed in\n\t var options = Tone.defaults(arguments, ['context'], { 'context': Tone.context });\n\t /**\n\t\t\t * The AudioContext of this instance\n\t\t\t * @private\n\t\t\t * @type {AudioContext}\n\t\t\t */\n\t this._context = options.context;\n\t };\n\t Tone.extend(Tone.AudioNode);\n\t /**\n\t\t * Get the audio context belonging to this instance.\n\t\t * @type {Tone.Context}\n\t\t * @memberOf Tone.AudioNode#\n\t\t * @name context\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.AudioNode.prototype, 'context', {\n\t get: function () {\n\t return this._context;\n\t }\n\t });\n\t /**\n\t\t * Create input and outputs for this object.\n\t\t * @param {Number} [input=0] The number of inputs\n\t\t * @param {Number} [outputs=0] The number of outputs\n\t\t * @return {Tone.AudioNode} this\n\t\t * @private\n\t\t */\n\t Tone.AudioNode.prototype.createInsOuts = function (inputs, outputs) {\n\t if (inputs === 1) {\n\t this.input = this.context.createGain();\n\t } else if (inputs > 1) {\n\t this.input = new Array(inputs);\n\t }\n\t if (outputs === 1) {\n\t this.output = this.context.createGain();\n\t } else if (outputs > 1) {\n\t this.output = new Array(outputs);\n\t }\n\t };\n\t /**\n\t\t * channelCount is the number of channels used when up-mixing and down-mixing\n\t\t * connections to any inputs to the node. The default value is 2 except for\n\t\t * specific nodes where its value is specially determined.\n\t\t *\n\t\t * @memberof Tone.AudioNode#\n\t\t * @type {Number}\n\t\t * @name channelCount\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.AudioNode.prototype, 'channelCount', {\n\t get: function () {\n\t return this.output.channelCount;\n\t },\n\t set: function (c) {\n\t return this.output.channelCount = c;\n\t }\n\t });\n\t /**\n\t\t * channelCountMode determines how channels will be counted when up-mixing and\n\t\t * down-mixing connections to any inputs to the node.\n\t\t * The default value is \"max\". This attribute has no effect for nodes with no inputs.\n\t\t * @memberof Tone.AudioNode#\n\t\t * @type {String}\n\t\t * @name channelCountMode\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.AudioNode.prototype, 'channelCountMode', {\n\t get: function () {\n\t return this.output.channelCountMode;\n\t },\n\t set: function (m) {\n\t return this.output.channelCountMode = m;\n\t }\n\t });\n\t /**\n\t\t * channelInterpretation determines how individual channels will be treated\n\t\t * when up-mixing and down-mixing connections to any inputs to the node.\n\t\t * The default value is \"speakers\".\n\t\t * @memberof Tone.AudioNode#\n\t\t * @type {String}\n\t\t * @name channelInterpretation\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.AudioNode.prototype, 'channelInterpretation', {\n\t get: function () {\n\t return this.output.channelInterpretation;\n\t },\n\t set: function (i) {\n\t return this.output.channelInterpretation = i;\n\t }\n\t });\n\t /**\n\t\t * The number of inputs feeding into the AudioNode.\n\t\t * For source nodes, this will be 0.\n\t\t * @type {Number}\n\t\t * @name numberOfInputs\n\t\t * @memberof Tone.AudioNode#\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.AudioNode.prototype, 'numberOfInputs', {\n\t get: function () {\n\t if (this.input) {\n\t if (Tone.isArray(this.input)) {\n\t return this.input.length;\n\t } else {\n\t return 1;\n\t }\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The number of outputs coming out of the AudioNode.\n\t\t * @type {Number}\n\t\t * @name numberOfOutputs\n\t\t * @memberof Tone.AudioNode#\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.AudioNode.prototype, 'numberOfOutputs', {\n\t get: function () {\n\t if (this.output) {\n\t if (Tone.isArray(this.output)) {\n\t return this.output.length;\n\t } else {\n\t return 1;\n\t }\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Called when an audio param connects to this node\n\t\t * @private\n\t\t */\n\t Tone.AudioNode.prototype._onConnect = function () {\n\t };\n\t /**\n\t\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t\t * @param {Tone | AudioParam | AudioNode} unit\n\t\t * @param {number} [outputNum=0] optionally which output to connect from\n\t\t * @param {number} [inputNum=0] optionally which input to connect to\n\t\t * @returns {Tone.AudioNode} this\n\t\t */\n\t Tone.AudioNode.prototype.connect = function (unit, outputNum, inputNum) {\n\t if (unit._onConnect) {\n\t unit._onConnect(this);\n\t }\n\t if (Tone.isArray(this.output)) {\n\t outputNum = Tone.defaultArg(outputNum, 0);\n\t this.output[outputNum].connect(unit, 0, inputNum);\n\t } else {\n\t this.output.connect(unit, outputNum, inputNum);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * disconnect the output\n\t\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t\t * if the output is an array, or the\n\t\t * node to disconnect from.\n\t\t * @returns {Tone.AudioNode} this\n\t\t */\n\t Tone.AudioNode.prototype.disconnect = function (destination, outputNum, inputNum) {\n\t if (Tone.isArray(this.output)) {\n\t if (Tone.isNumber(destination)) {\n\t this.output[destination].disconnect();\n\t } else {\n\t outputNum = Tone.defaultArg(outputNum, 0);\n\t this.output[outputNum].disconnect(destination, 0, inputNum);\n\t }\n\t } else {\n\t this.output.disconnect.apply(this.output, arguments);\n\t }\n\t };\n\t /**\n\t\t * Connect the output of this node to the rest of the nodes in series.\n\t\t * @example\n\t\t * //connect a node to an effect, panVol and then to the master output\n\t\t * node.chain(effect, panVol, Tone.Master);\n\t\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t\t * @returns {Tone.AudioNode} this\n\t\t * @private\n\t\t */\n\t Tone.AudioNode.prototype.chain = function () {\n\t var currentUnit = this;\n\t for (var i = 0; i < arguments.length; i++) {\n\t var toUnit = arguments[i];\n\t currentUnit.connect(toUnit);\n\t currentUnit = toUnit;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * connect the output of this node to the rest of the nodes in parallel.\n\t\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t\t * @returns {Tone.AudioNode} this\n\t\t * @private\n\t\t */\n\t Tone.AudioNode.prototype.fan = function () {\n\t for (var i = 0; i < arguments.length; i++) {\n\t this.connect(arguments[i]);\n\t }\n\t return this;\n\t };\n\t if (window.AudioNode) {\n\t //give native nodes chain and fan methods\n\t AudioNode.prototype.chain = Tone.AudioNode.prototype.chain;\n\t AudioNode.prototype.fan = Tone.AudioNode.prototype.fan;\n\t }\n\t /**\n\t\t * Dispose and disconnect\n\t\t * @return {Tone.AudioNode} this\n\t\t */\n\t Tone.AudioNode.prototype.dispose = function () {\n\t if (Tone.isDefined(this.input)) {\n\t if (this.input instanceof AudioNode) {\n\t this.input.disconnect();\n\t }\n\t this.input = null;\n\t }\n\t if (Tone.isDefined(this.output)) {\n\t if (this.output instanceof AudioNode) {\n\t this.output.disconnect();\n\t }\n\t this.output = null;\n\t }\n\t this._context = null;\n\t return this;\n\t };\n\t return Tone.AudioNode;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Base class for all Signals. Used Internally.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.SignalBase = function () {\n\t Tone.AudioNode.call(this);\n\t };\n\t Tone.extend(Tone.SignalBase, Tone.AudioNode);\n\t /**\n\t\t * When signals connect to other signals or AudioParams,\n\t\t * they take over the output value of that signal or AudioParam.\n\t\t * For all other nodes, the behavior is the same as a default <code>connect</code>.\n\t\t *\n\t\t * @override\n\t\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node\n\t\t * @param {number} [outputNumber=0] The output number to connect from.\n\t\t * @param {number} [inputNumber=0] The input number to connect to.\n\t\t * @returns {Tone.SignalBase} this\n\t\t */\n\t Tone.SignalBase.prototype.connect = function (node, outputNumber, inputNumber) {\n\t //zero it out so that the signal can have full control\n\t if (Tone.Signal && Tone.Signal === node.constructor || Tone.Param && Tone.Param === node.constructor) {\n\t //cancel changes\n\t node._param.cancelScheduledValues(0);\n\t //reset the value\n\t node._param.value = 0;\n\t //mark the value as overridden\n\t node.overridden = true;\n\t } else if (node instanceof AudioParam) {\n\t node.cancelScheduledValues(0);\n\t node.value = 0;\n\t }\n\t Tone.AudioNode.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t return this;\n\t };\n\t return Tone.SignalBase;\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported) {\n\t //fixes safari only bug which is still present in 11\n\t var ua = navigator.userAgent.toLowerCase();\n\t var isSafari = ua.includes('safari') && !ua.includes('chrome');\n\t if (isSafari) {\n\t var WaveShaperNode = function (context) {\n\t this._internalNode = this.input = this.output = context._native_createWaveShaper();\n\t this._curve = null;\n\t for (var prop in this._internalNode) {\n\t this._defineProperty(this._internalNode, prop);\n\t }\n\t };\n\t Object.defineProperty(WaveShaperNode.prototype, 'curve', {\n\t get: function () {\n\t return this._curve;\n\t },\n\t set: function (curve) {\n\t this._curve = curve;\n\t var array = new Float32Array(curve.length + 1);\n\t array.set(curve, 1);\n\t array[0] = curve[0];\n\t this._internalNode.curve = array;\n\t }\n\t });\n\t WaveShaperNode.prototype._defineProperty = function (context, prop) {\n\t if (Tone.isUndef(this[prop])) {\n\t Object.defineProperty(this, prop, {\n\t get: function () {\n\t if (typeof context[prop] === 'function') {\n\t return context[prop].bind(context);\n\t } else {\n\t return context[prop];\n\t }\n\t },\n\t set: function (val) {\n\t context[prop] = val;\n\t }\n\t });\n\t }\n\t };\n\t AudioContext.prototype._native_createWaveShaper = AudioContext.prototype.createWaveShaper;\n\t AudioContext.prototype.createWaveShaper = function () {\n\t return new WaveShaperNode(this);\n\t };\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Wraps the native Web Audio API\n\t\t * [WaveShaperNode](http://webaudio.github.io/web-audio-api/#the-waveshapernode-interface).\n\t\t *\n\t\t * @extends {Tone.SignalBase}\n\t\t * @constructor\n\t\t * @param {function|Array|Number} mapping The function used to define the values.\n\t\t * The mapping function should take two arguments:\n\t\t * the first is the value at the current position\n\t\t * and the second is the array position.\n\t\t * If the argument is an array, that array will be\n\t\t * set as the wave shaping function. The input\n\t\t * signal is an AudioRange [-1, 1] value and the output\n\t\t * signal can take on any numerical values.\n\t\t *\n\t\t * @param {Number} [bufferLen=1024] The length of the WaveShaperNode buffer.\n\t\t * @example\n\t\t * var timesTwo = new Tone.WaveShaper(function(val){\n\t\t * \treturn val * 2;\n\t\t * }, 2048);\n\t\t * @example\n\t\t * //a waveshaper can also be constructed with an array of values\n\t\t * var invert = new Tone.WaveShaper([1, -1]);\n\t\t */\n\t Tone.WaveShaper = function (mapping, bufferLen) {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * the waveshaper\n\t\t\t * @type {WaveShaperNode}\n\t\t\t * @private\n\t\t\t */\n\t this._shaper = this.input = this.output = this.context.createWaveShaper();\n\t /**\n\t\t\t * the waveshapers curve\n\t\t\t * @type {Float32Array}\n\t\t\t * @private\n\t\t\t */\n\t this._curve = null;\n\t if (Array.isArray(mapping)) {\n\t this.curve = mapping;\n\t } else if (isFinite(mapping) || Tone.isUndef(mapping)) {\n\t this._curve = new Float32Array(Tone.defaultArg(mapping, 1024));\n\t } else if (Tone.isFunction(mapping)) {\n\t this._curve = new Float32Array(Tone.defaultArg(bufferLen, 1024));\n\t this.setMap(mapping);\n\t }\n\t };\n\t Tone.extend(Tone.WaveShaper, Tone.SignalBase);\n\t /**\n\t\t * Uses a mapping function to set the value of the curve.\n\t\t * @param {function} mapping The function used to define the values.\n\t\t * The mapping function take two arguments:\n\t\t * the first is the value at the current position\n\t\t * which goes from -1 to 1 over the number of elements\n\t\t * in the curve array. The second argument is the array position.\n\t\t * @returns {Tone.WaveShaper} this\n\t\t * @example\n\t\t * //map the input signal from [-1, 1] to [0, 10]\n\t\t * shaper.setMap(function(val, index){\n\t\t * \treturn (val + 1) * 5;\n\t\t * })\n\t\t */\n\t Tone.WaveShaper.prototype.setMap = function (mapping) {\n\t var array = new Array(this._curve.length);\n\t for (var i = 0, len = this._curve.length; i < len; i++) {\n\t var normalized = i / (len - 1) * 2 - 1;\n\t array[i] = mapping(normalized, i);\n\t }\n\t this.curve = array;\n\t return this;\n\t };\n\t /**\n\t\t * The array to set as the waveshaper curve. For linear curves\n\t\t * array length does not make much difference, but for complex curves\n\t\t * longer arrays will provide smoother interpolation.\n\t\t * @memberOf Tone.WaveShaper#\n\t\t * @type {Array}\n\t\t * @name curve\n\t\t */\n\t Object.defineProperty(Tone.WaveShaper.prototype, 'curve', {\n\t get: function () {\n\t return this._shaper.curve;\n\t },\n\t set: function (mapping) {\n\t this._curve = new Float32Array(mapping);\n\t this._shaper.curve = this._curve;\n\t }\n\t });\n\t /**\n\t\t * Specifies what type of oversampling (if any) should be used when\n\t\t * applying the shaping curve. Can either be \"none\", \"2x\" or \"4x\".\n\t\t * @memberOf Tone.WaveShaper#\n\t\t * @type {string}\n\t\t * @name oversample\n\t\t */\n\t Object.defineProperty(Tone.WaveShaper.prototype, 'oversample', {\n\t get: function () {\n\t return this._shaper.oversample;\n\t },\n\t set: function (oversampling) {\n\t if ([\n\t 'none',\n\t '2x',\n\t '4x'\n\t ].includes(oversampling)) {\n\t this._shaper.oversample = oversampling;\n\t } else {\n\t throw new RangeError('Tone.WaveShaper: oversampling must be either \\'none\\', \\'2x\\', or \\'4x\\'');\n\t }\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.WaveShaper} this\n\t\t */\n\t Tone.WaveShaper.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._shaper.disconnect();\n\t this._shaper = null;\n\t this._curve = null;\n\t return this;\n\t };\n\t return Tone.WaveShaper;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.TimeBase is a flexible encoding of time\n\t\t * which can be evaluated to and from a string.\n\t\t * @extends {Tone}\n\t\t * @param {Time} val The time value as a number or string\n\t\t * @param {String=} units Unit values\n\t\t * @example\n\t\t * Tone.TimeBase(4, \"n\")\n\t\t * Tone.TimeBase(2, \"t\")\n\t\t * Tone.TimeBase(\"2t\")\n\t\t * Tone.TimeBase(\"2t\") + Tone.TimeBase(\"4n\");\n\t\t */\n\t Tone.TimeBase = function (val, units) {\n\t //allows it to be constructed with or without 'new'\n\t if (this instanceof Tone.TimeBase) {\n\t /**\n\t\t\t\t * The value\n\t\t\t\t * @type {Number|String|Tone.TimeBase}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._val = val;\n\t /**\n\t\t\t\t * The units\n\t\t\t\t * @type {String?}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._units = units;\n\t //test if the value is a string representation of a number\n\t if (Tone.isUndef(this._units) && Tone.isString(this._val) && // eslint-disable-next-line eqeqeq\n\t parseFloat(this._val) == this._val && this._val.charAt(0) !== '+') {\n\t this._val = parseFloat(this._val);\n\t this._units = this._defaultUnits;\n\t } else if (val && val.constructor === this.constructor) {\n\t //if they're the same type, just copy values over\n\t this._val = val._val;\n\t this._units = val._units;\n\t } else if (val instanceof Tone.TimeBase) {\n\t switch (this._defaultUnits) {\n\t case 's':\n\t this._val = val.toSeconds();\n\t break;\n\t case 'i':\n\t this._val = val.toTicks();\n\t break;\n\t case 'hz':\n\t this._val = val.toFrequency();\n\t break;\n\t case 'midi':\n\t this._val = val.toMidi();\n\t break;\n\t default:\n\t throw new Error('Unrecognized default units ' + this._defaultUnits);\n\t }\n\t }\n\t } else {\n\t return new Tone.TimeBase(val, units);\n\t }\n\t };\n\t Tone.extend(Tone.TimeBase);\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tABSTRACT SYNTAX TREE PARSER\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * All the primary expressions.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t Tone.TimeBase.prototype._expressions = {\n\t 'n': {\n\t regexp: /^(\\d+)n(\\.?)$/i,\n\t method: function (value, dot) {\n\t value = parseInt(value);\n\t var scalar = dot === '.' ? 1.5 : 1;\n\t if (value === 1) {\n\t return this._beatsToUnits(this._getTimeSignature()) * scalar;\n\t } else {\n\t return this._beatsToUnits(4 / value) * scalar;\n\t }\n\t }\n\t },\n\t 't': {\n\t regexp: /^(\\d+)t$/i,\n\t method: function (value) {\n\t value = parseInt(value);\n\t return this._beatsToUnits(8 / (parseInt(value) * 3));\n\t }\n\t },\n\t 'm': {\n\t regexp: /^(\\d+)m$/i,\n\t method: function (value) {\n\t return this._beatsToUnits(parseInt(value) * this._getTimeSignature());\n\t }\n\t },\n\t 'i': {\n\t regexp: /^(\\d+)i$/i,\n\t method: function (value) {\n\t return this._ticksToUnits(parseInt(value));\n\t }\n\t },\n\t 'hz': {\n\t regexp: /^(\\d+(?:\\.\\d+)?)hz$/i,\n\t method: function (value) {\n\t return this._frequencyToUnits(parseFloat(value));\n\t }\n\t },\n\t 'tr': {\n\t regexp: /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?$/,\n\t method: function (m, q, s) {\n\t var total = 0;\n\t if (m && m !== '0') {\n\t total += this._beatsToUnits(this._getTimeSignature() * parseFloat(m));\n\t }\n\t if (q && q !== '0') {\n\t total += this._beatsToUnits(parseFloat(q));\n\t }\n\t if (s && s !== '0') {\n\t total += this._beatsToUnits(parseFloat(s) / 4);\n\t }\n\t return total;\n\t }\n\t },\n\t 's': {\n\t regexp: /^(\\d+(?:\\.\\d+)?)s$/,\n\t method: function (value) {\n\t return this._secondsToUnits(parseFloat(value));\n\t }\n\t },\n\t 'samples': {\n\t regexp: /^(\\d+)samples$/,\n\t method: function (value) {\n\t return parseInt(value) / this.context.sampleRate;\n\t }\n\t },\n\t 'default': {\n\t regexp: /^(\\d+(?:\\.\\d+)?)$/,\n\t method: function (value) {\n\t return this._expressions[this._defaultUnits].method.call(this, value);\n\t }\n\t }\n\t };\n\t /**\n\t\t * The default units if none are given.\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._defaultUnits = 's';\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tTRANSPORT FALLBACKS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Return the bpm, or 120 if Transport is not available\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._getBpm = function () {\n\t if (Tone.Transport) {\n\t return Tone.Transport.bpm.value;\n\t } else {\n\t return 120;\n\t }\n\t };\n\t /**\n\t\t * Return the timeSignature or 4 if Transport is not available\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._getTimeSignature = function () {\n\t if (Tone.Transport) {\n\t return Tone.Transport.timeSignature;\n\t } else {\n\t return 4;\n\t }\n\t };\n\t /**\n\t\t * Return the PPQ or 192 if Transport is not available\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._getPPQ = function () {\n\t if (Tone.Transport) {\n\t return Tone.Transport.PPQ;\n\t } else {\n\t return 192;\n\t }\n\t };\n\t /**\n\t\t * Return the current time in whichever context is relevant\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._now = function () {\n\t return this.now();\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tUNIT CONVERSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Returns the value of a frequency in the current units\n\t\t * @param {Frequency} freq\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._frequencyToUnits = function (freq) {\n\t return 1 / freq;\n\t };\n\t /**\n\t\t * Return the value of the beats in the current units\n\t\t * @param {Number} beats\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._beatsToUnits = function (beats) {\n\t return 60 / this._getBpm() * beats;\n\t };\n\t /**\n\t\t * Returns the value of a second in the current units\n\t\t * @param {Seconds} seconds\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._secondsToUnits = function (seconds) {\n\t return seconds;\n\t };\n\t /**\n\t\t * Returns the value of a tick in the current time units\n\t\t * @param {Ticks} ticks\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._ticksToUnits = function (ticks) {\n\t return ticks * (this._beatsToUnits(1) / this._getPPQ());\n\t };\n\t /**\n\t\t * With no arguments, return 'now'\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._noArg = function () {\n\t return this._now();\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tEXPRESSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Evaluate the time value. Returns the time\n\t\t * in seconds.\n\t\t * @return {Seconds}\n\t\t */\n\t Tone.TimeBase.prototype.valueOf = function () {\n\t if (Tone.isUndef(this._val)) {\n\t return this._noArg();\n\t } else if (Tone.isString(this._val) && Tone.isUndef(this._units)) {\n\t for (var units in this._expressions) {\n\t if (this._expressions[units].regexp.test(this._val.trim())) {\n\t this._units = units;\n\t break;\n\t }\n\t }\n\t }\n\t if (Tone.isDefined(this._units)) {\n\t var expr = this._expressions[this._units];\n\t var matching = this._val.toString().trim().match(expr.regexp);\n\t if (matching) {\n\t return expr.method.apply(this, matching.slice(1));\n\t } else {\n\t return expr.method.call(this, parseFloat(this._val));\n\t }\n\t } else {\n\t return this._val;\n\t }\n\t };\n\t /**\n\t\t * Return the value in seconds\n\t\t * @return {Seconds}\n\t\t */\n\t Tone.TimeBase.prototype.toSeconds = function () {\n\t return this.valueOf();\n\t };\n\t /**\n\t\t * Return the value in hertz\n\t\t * @return {Frequency}\n\t\t */\n\t Tone.TimeBase.prototype.toFrequency = function () {\n\t return 1 / this.toSeconds();\n\t };\n\t /**\n\t\t * Return the time in samples\n\t\t * @return {Samples}\n\t\t */\n\t Tone.TimeBase.prototype.toSamples = function () {\n\t return this.toSeconds() * this.context.sampleRate;\n\t };\n\t /**\n\t\t * Return the time in milliseconds.\n\t\t * @return {Milliseconds}\n\t\t */\n\t Tone.TimeBase.prototype.toMilliseconds = function () {\n\t return this.toSeconds() * 1000;\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.TimeBase} this\n\t\t */\n\t Tone.TimeBase.prototype.dispose = function () {\n\t this._val = null;\n\t this._units = null;\n\t };\n\t return Tone.TimeBase;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Frequency is a primitive type for encoding Frequency values.\n\t\t * Eventually all time values are evaluated to hertz\n\t\t * using the `eval` method.\n\t\t * @constructor\n\t\t * @extends {Tone.TimeBase}\n\t\t * @param {String|Number} val The time value.\n\t\t * @param {String=} units The units of the value.\n\t\t * @example\n\t\t * Tone.Frequency(\"C3\") // 261\n\t\t * Tone.Frequency(38, \"midi\") //\n\t\t * Tone.Frequency(\"C3\").transpose(4);\n\t\t */\n\t Tone.Frequency = function (val, units) {\n\t if (this instanceof Tone.Frequency) {\n\t Tone.TimeBase.call(this, val, units);\n\t } else {\n\t return new Tone.Frequency(val, units);\n\t }\n\t };\n\t Tone.extend(Tone.Frequency, Tone.TimeBase);\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tAUGMENT BASE EXPRESSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t Tone.Frequency.prototype._expressions = Object.assign({}, Tone.TimeBase.prototype._expressions, {\n\t 'midi': {\n\t regexp: /^(\\d+(?:\\.\\d+)?midi)/,\n\t method: function (value) {\n\t if (this._defaultUnits === 'midi') {\n\t return value;\n\t } else {\n\t return Tone.Frequency.mtof(value);\n\t }\n\t }\n\t },\n\t 'note': {\n\t regexp: /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t method: function (pitch, octave) {\n\t var index = noteToScaleIndex[pitch.toLowerCase()];\n\t var noteNumber = index + (parseInt(octave) + 1) * 12;\n\t if (this._defaultUnits === 'midi') {\n\t return noteNumber;\n\t } else {\n\t return Tone.Frequency.mtof(noteNumber);\n\t }\n\t }\n\t },\n\t 'tr': {\n\t regexp: /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t method: function (m, q, s) {\n\t var total = 1;\n\t if (m && m !== '0') {\n\t total *= this._beatsToUnits(this._getTimeSignature() * parseFloat(m));\n\t }\n\t if (q && q !== '0') {\n\t total *= this._beatsToUnits(parseFloat(q));\n\t }\n\t if (s && s !== '0') {\n\t total *= this._beatsToUnits(parseFloat(s) / 4);\n\t }\n\t return total;\n\t }\n\t }\n\t });\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tEXPRESSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Transposes the frequency by the given number of semitones.\n\t\t * @param {Interval} interval\n\t\t * @return {Tone.Frequency} A new transposed frequency\n\t\t * @example\n\t\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t\t */\n\t Tone.Frequency.prototype.transpose = function (interval) {\n\t return new this.constructor(this.valueOf() * Tone.intervalToFrequencyRatio(interval));\n\t };\n\t /**\n\t\t * Takes an array of semitone intervals and returns\n\t\t * an array of frequencies transposed by those intervals.\n\t\t * @param {Array} intervals\n\t\t * @return {Array<Tone.Frequency>} Returns an array of Frequencies\n\t\t * @example\n\t\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t\t */\n\t Tone.Frequency.prototype.harmonize = function (intervals) {\n\t return intervals.map(function (interval) {\n\t return this.transpose(interval);\n\t }.bind(this));\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tUNIT CONVERSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Return the value of the frequency as a MIDI note\n\t\t * @return {MIDI}\n\t\t * @example\n\t\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t\t */\n\t Tone.Frequency.prototype.toMidi = function () {\n\t return Tone.Frequency.ftom(this.valueOf());\n\t };\n\t /**\n\t\t * Return the value of the frequency in Scientific Pitch Notation\n\t\t * @return {Note}\n\t\t * @example\n\t\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t\t */\n\t Tone.Frequency.prototype.toNote = function () {\n\t var freq = this.toFrequency();\n\t var log = Math.log2(freq / Tone.Frequency.A4);\n\t var noteNumber = Math.round(12 * log) + 57;\n\t var octave = Math.floor(noteNumber / 12);\n\t if (octave < 0) {\n\t noteNumber += -12 * octave;\n\t }\n\t var noteName = scaleIndexToNote[noteNumber % 12];\n\t return noteName + octave.toString();\n\t };\n\t /**\n\t\t * Return the duration of one cycle in seconds.\n\t\t * @return {Seconds}\n\t\t */\n\t Tone.Frequency.prototype.toSeconds = function () {\n\t return 1 / Tone.TimeBase.prototype.toSeconds.call(this);\n\t };\n\t /**\n\t\t * Return the value in Hertz\n\t\t * @return {Frequency}\n\t\t */\n\t Tone.Frequency.prototype.toFrequency = function () {\n\t return Tone.TimeBase.prototype.toFrequency.call(this);\n\t };\n\t /**\n\t\t * Return the duration of one cycle in ticks\n\t\t * @return {Ticks}\n\t\t */\n\t Tone.Frequency.prototype.toTicks = function () {\n\t var quarterTime = this._beatsToUnits(1);\n\t var quarters = this.valueOf() / quarterTime;\n\t return Math.floor(quarters * Tone.Transport.PPQ);\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tUNIT CONVERSIONS HELPERS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * With no arguments, return 0\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Frequency.prototype._noArg = function () {\n\t return 0;\n\t };\n\t /**\n\t\t * Returns the value of a frequency in the current units\n\t\t * @param {Frequency} freq\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Frequency.prototype._frequencyToUnits = function (freq) {\n\t return freq;\n\t };\n\t /**\n\t\t * Returns the value of a tick in the current time units\n\t\t * @param {Ticks} ticks\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Frequency.prototype._ticksToUnits = function (ticks) {\n\t return 1 / (ticks * 60 / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t };\n\t /**\n\t\t * Return the value of the beats in the current units\n\t\t * @param {Number} beats\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Frequency.prototype._beatsToUnits = function (beats) {\n\t return 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t };\n\t /**\n\t\t * Returns the value of a second in the current units\n\t\t * @param {Seconds} seconds\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Frequency.prototype._secondsToUnits = function (seconds) {\n\t return 1 / seconds;\n\t };\n\t /**\n\t\t * The default units if none are given.\n\t\t * @private\n\t\t */\n\t Tone.Frequency.prototype._defaultUnits = 'hz';\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tFREQUENCY CONVERSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Note to scale index\n\t\t * @type {Object}\n\t\t */\n\t var noteToScaleIndex = {\n\t 'cbb': -2,\n\t 'cb': -1,\n\t 'c': 0,\n\t 'c#': 1,\n\t 'cx': 2,\n\t 'dbb': 0,\n\t 'db': 1,\n\t 'd': 2,\n\t 'd#': 3,\n\t 'dx': 4,\n\t 'ebb': 2,\n\t 'eb': 3,\n\t 'e': 4,\n\t 'e#': 5,\n\t 'ex': 6,\n\t 'fbb': 3,\n\t 'fb': 4,\n\t 'f': 5,\n\t 'f#': 6,\n\t 'fx': 7,\n\t 'gbb': 5,\n\t 'gb': 6,\n\t 'g': 7,\n\t 'g#': 8,\n\t 'gx': 9,\n\t 'abb': 7,\n\t 'ab': 8,\n\t 'a': 9,\n\t 'a#': 10,\n\t 'ax': 11,\n\t 'bbb': 9,\n\t 'bb': 10,\n\t 'b': 11,\n\t 'b#': 12,\n\t 'bx': 13\n\t };\n\t /**\n\t\t * scale index to note (sharps)\n\t\t * @type {Array}\n\t\t */\n\t var scaleIndexToNote = [\n\t 'C',\n\t 'C#',\n\t 'D',\n\t 'D#',\n\t 'E',\n\t 'F',\n\t 'F#',\n\t 'G',\n\t 'G#',\n\t 'A',\n\t 'A#',\n\t 'B'\n\t ];\n\t /**\n\t\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t\t * A4's values in Hertz.\n\t\t * @type {Frequency}\n\t\t * @static\n\t\t */\n\t Tone.Frequency.A4 = 440;\n\t /**\n\t\t * Convert a MIDI note to frequency value.\n\t\t * @param {MIDI} midi The midi number to convert.\n\t\t * @return {Frequency} the corresponding frequency value\n\t\t * @static\n\t\t * @example\n\t\t * Tone.Frequency.mtof(69); // returns 440\n\t\t */\n\t Tone.Frequency.mtof = function (midi) {\n\t return Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t };\n\t /**\n\t\t * Convert a frequency value to a MIDI note.\n\t\t * @param {Frequency} frequency The value to frequency value to convert.\n\t\t * @returns {MIDI}\n\t\t * @static\n\t\t * @example\n\t\t * Tone.Frequency.ftom(440); // returns 69\n\t\t */\n\t Tone.Frequency.ftom = function (frequency) {\n\t return 69 + Math.round(12 * Math.log2(frequency / Tone.Frequency.A4));\n\t };\n\t return Tone.Frequency;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Time is a primitive type for encoding Time values.\n\t\t * Tone.Time can be constructed with or without the `new` keyword. Tone.Time can be passed\n\t\t * into the parameter of any method which takes time as an argument.\n\t\t * @constructor\n\t\t * @extends {Tone.TimeBase}\n\t\t * @param {String|Number} val The time value.\n\t\t * @param {String=} units The units of the value.\n\t\t * @example\n\t\t * var t = Tone.Time(\"4n\");//a quarter note\n\t\t */\n\t Tone.Time = function (val, units) {\n\t if (this instanceof Tone.Time) {\n\t Tone.TimeBase.call(this, val, units);\n\t } else {\n\t return new Tone.Time(val, units);\n\t }\n\t };\n\t Tone.extend(Tone.Time, Tone.TimeBase);\n\t /**\n\t\t * Extend the base expressions\n\t\t */\n\t Tone.Time.prototype._expressions = Object.assign({}, Tone.TimeBase.prototype._expressions, {\n\t 'quantize': {\n\t regexp: /^@(.+)/,\n\t method: function (capture) {\n\t if (Tone.Transport) {\n\t var quantTo = new this.constructor(capture);\n\t return Tone.Transport.nextSubdivision(quantTo);\n\t } else {\n\t return 0;\n\t }\n\t }\n\t },\n\t 'now': {\n\t regexp: /^\\+(.+)/,\n\t method: function (capture) {\n\t return this._now() + new this.constructor(capture);\n\t }\n\t }\n\t });\n\t /**\n\t\t * Quantize the time by the given subdivision. Optionally add a\n\t\t * percentage which will move the time value towards the ideal\n\t\t * quantized value by that percentage.\n\t\t * @param {Number|Time} val The subdivision to quantize to\n\t\t * @param {NormalRange} [percent=1] Move the time value\n\t\t * towards the quantized value by\n\t\t * a percentage.\n\t\t * @return {Number} this\n\t\t * @example\n\t\t * Tone.Time(21).quantize(2) //returns 22\n\t\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t\t */\n\t Tone.Time.prototype.quantize = function (subdiv, percent) {\n\t percent = Tone.defaultArg(percent, 1);\n\t var subdivision = new this.constructor(subdiv);\n\t var value = this.valueOf();\n\t var multiple = Math.round(value / subdivision);\n\t var ideal = multiple * subdivision;\n\t var diff = ideal - value;\n\t return value + diff * percent;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t // CONVERSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Convert a Time to Notation. The notation values are will be the\n\t\t * closest representation between 1m to 128th note.\n\t\t * @return {Notation}\n\t\t * @example\n\t\t * //if the Transport is at 120bpm:\n\t\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t\t */\n\t Tone.Time.prototype.toNotation = function () {\n\t var time = this.toSeconds();\n\t var testNotations = ['1m'];\n\t for (var power = 1; power < 8; power++) {\n\t var subdiv = Math.pow(2, power);\n\t testNotations.push(subdiv + 'n.');\n\t testNotations.push(subdiv + 'n');\n\t testNotations.push(subdiv + 't');\n\t }\n\t testNotations.push('0');\n\t //find the closets notation representation\n\t var closest = testNotations[0];\n\t var closestSeconds = Tone.Time(testNotations[0]).toSeconds();\n\t testNotations.forEach(function (notation) {\n\t var notationSeconds = Tone.Time(notation).toSeconds();\n\t if (Math.abs(notationSeconds - time) < Math.abs(closestSeconds - time)) {\n\t closest = notation;\n\t closestSeconds = notationSeconds;\n\t }\n\t });\n\t return closest;\n\t };\n\t /**\n\t\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t\t * @return {BarsBeatsSixteenths}\n\t\t */\n\t Tone.Time.prototype.toBarsBeatsSixteenths = function () {\n\t var quarterTime = this._beatsToUnits(1);\n\t var quarters = this.valueOf() / quarterTime;\n\t var measures = Math.floor(quarters / this._getTimeSignature());\n\t var sixteenths = quarters % 1 * 4;\n\t quarters = Math.floor(quarters) % this._getTimeSignature();\n\t sixteenths = sixteenths.toString();\n\t if (sixteenths.length > 3) {\n\t // the additional parseFloat removes insignificant trailing zeroes\n\t sixteenths = parseFloat(parseFloat(sixteenths).toFixed(3));\n\t }\n\t var progress = [\n\t measures,\n\t quarters,\n\t sixteenths\n\t ];\n\t return progress.join(':');\n\t };\n\t /**\n\t\t * Return the time in ticks.\n\t\t * @return {Ticks}\n\t\t */\n\t Tone.Time.prototype.toTicks = function () {\n\t var quarterTime = this._beatsToUnits(1);\n\t var quarters = this.valueOf() / quarterTime;\n\t return Math.round(quarters * this._getPPQ());\n\t };\n\t /**\n\t\t * Return the time in seconds.\n\t\t * @return {Seconds}\n\t\t */\n\t Tone.Time.prototype.toSeconds = function () {\n\t return this.valueOf();\n\t };\n\t /**\n\t\t * Return the value as a midi note.\n\t\t * @return {Midi}\n\t\t */\n\t Tone.Time.prototype.toMidi = function () {\n\t return Tone.Frequency.ftom(this.toFrequency());\n\t };\n\t return Tone.Time;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.TransportTime is a the time along the Transport's\n\t\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t\t * against the AudioContext's clock, it is evaluated against\n\t\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t\t * @constructor\n\t\t * @param {Time} val The time value as a number or string\n\t\t * @param {String=} units Unit values\n\t\t * @extends {Tone.Time}\n\t\t */\n\t Tone.TransportTime = function (val, units) {\n\t if (this instanceof Tone.TransportTime) {\n\t Tone.Time.call(this, val, units);\n\t } else {\n\t return new Tone.TransportTime(val, units);\n\t }\n\t };\n\t Tone.extend(Tone.TransportTime, Tone.Time);\n\t /**\n\t\t * Return the current time in whichever context is relevant\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.TransportTime.prototype._now = function () {\n\t return Tone.Transport.seconds;\n\t };\n\t return Tone.TransportTime;\n\t});\n\tModule(function (Tone) {\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tTYPES\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Units which a value can take on.\n\t\t * @enum {String}\n\t\t */\n\t Tone.Type = {\n\t /**\n\t\t\t * Default units\n\t\t\t * @typedef {Default}\n\t\t\t */\n\t Default: 'number',\n\t /**\n\t\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t\t *\n\t\t\t * * Numbers, which will be taken literally as the time (in seconds).\n\t\t\t * * Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.\n\t\t\t * * TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times\n\t\t\t * in the form BARS:QUARTERS:SIXTEENTHS.\n\t\t\t * * Frequency, (\"8hz\") is converted to the length of the cycle in seconds.\n\t\t\t * * Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as\n\t\t\t * \"the current time plus whatever expression follows\".\n\t\t\t * * Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined\n\t\t\t * into a mathematical expression which will be evaluated to compute the desired time.\n\t\t\t * * No Argument, for methods which accept time, no argument will be interpreted as\n\t\t\t * \"now\" (i.e. the currentTime).\n\t\t\t *\n\t\t\t * @typedef {Time}\n\t\t\t */\n\t Time: 'time',\n\t /**\n\t\t\t * Frequency can be described similar to time, except ultimately the\n\t\t\t * values are converted to frequency instead of seconds. A number\n\t\t\t * is taken literally as the value in hertz. Additionally any of the\n\t\t\t * Time encodings can be used. Note names in the form\n\t\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t\t * frequency value.\n\t\t\t * @typedef {Frequency}\n\t\t\t */\n\t Frequency: 'frequency',\n\t /**\n\t\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable.\n\t\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t\t * @typedef {TransportTime}\n\t\t\t */\n\t TransportTime: 'transportTime',\n\t /**\n\t\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t\t * the smallest unit of time that the Transport supports.\n\t\t\t * @typedef {Ticks}\n\t\t\t */\n\t Ticks: 'ticks',\n\t /**\n\t\t\t * Normal values are within the range [0, 1].\n\t\t\t * @typedef {NormalRange}\n\t\t\t */\n\t NormalRange: 'normalRange',\n\t /**\n\t\t\t * AudioRange values are between [-1, 1].\n\t\t\t * @typedef {AudioRange}\n\t\t\t */\n\t AudioRange: 'audioRange',\n\t /**\n\t\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t\t * because of the logarithmic way that we perceive loudness. 0 decibels\n\t\t\t * means no change in volume. -10db is approximately half as loud and 10db\n\t\t\t * is twice is loud.\n\t\t\t * @typedef {Decibels}\n\t\t\t */\n\t Decibels: 'db',\n\t /**\n\t\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t\t * @typedef {Interval}\n\t\t\t */\n\t Interval: 'interval',\n\t /**\n\t\t\t * Beats per minute.\n\t\t\t * @typedef {BPM}\n\t\t\t */\n\t BPM: 'bpm',\n\t /**\n\t\t\t * The value must be greater than or equal to 0.\n\t\t\t * @typedef {Positive}\n\t\t\t */\n\t Positive: 'positive',\n\t /**\n\t\t\t * Gain is the ratio between input and output of a signal.\n\t\t\t * A gain of 0 is the same as silencing the signal. A gain of\n\t\t\t * 1, causes no change to the incoming signal.\n\t\t\t * @typedef {Gain}\n\t\t\t */\n\t Gain: 'gain',\n\t /**\n\t\t\t * A cent is a hundredth of a semitone.\n\t\t\t * @typedef {Cents}\n\t\t\t */\n\t Cents: 'cents',\n\t /**\n\t\t\t * Angle between 0 and 360.\n\t\t\t * @typedef {Degrees}\n\t\t\t */\n\t Degrees: 'degrees',\n\t /**\n\t\t\t * A number representing a midi note.\n\t\t\t * @typedef {MIDI}\n\t\t\t */\n\t MIDI: 'midi',\n\t /**\n\t\t\t * A colon-separated representation of time in the form of\n\t\t\t * Bars:Beats:Sixteenths.\n\t\t\t * @typedef {BarsBeatsSixteenths}\n\t\t\t */\n\t BarsBeatsSixteenths: 'barsBeatsSixteenths',\n\t /**\n\t\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t\t * Audio is typically sampled 44100 times per second.\n\t\t\t * @typedef {Samples}\n\t\t\t */\n\t Samples: 'samples',\n\t /**\n\t\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t\t * @typedef {Hertz}\n\t\t\t */\n\t Hertz: 'hertz',\n\t /**\n\t\t\t * A frequency represented by a letter name,\n\t\t\t * accidental and octave. This system is known as\n\t\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t\t * @typedef {Note}\n\t\t\t */\n\t Note: 'note',\n\t /**\n\t\t\t * One millisecond is a thousandth of a second.\n\t\t\t * @typedef {Milliseconds}\n\t\t\t */\n\t Milliseconds: 'milliseconds',\n\t /**\n\t\t\t * Seconds are the time unit of the AudioContext. In the end,\n\t\t\t * all values need to be evaluated to seconds.\n\t\t\t * @typedef {Seconds}\n\t\t\t */\n\t Seconds: 'seconds',\n\t /**\n\t\t\t * A string representing a duration relative to a measure.\n\t\t\t * * \"4n\" = quarter note\n\t\t\t * * \"2m\" = two measures\n\t\t\t * * \"8t\" = eighth-note triplet\n\t\t\t * @typedef {Notation}\n\t\t\t */\n\t Notation: 'notation'\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t // AUGMENT TONE's PROTOTYPE\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Convert Time into seconds.\n\t\t *\n\t\t * Unlike the method which it overrides, this takes into account\n\t\t * transporttime and musical notation.\n\t\t *\n\t\t * Time : 1.40\n\t\t * Notation: 4n or 1m or 2t\n\t\t * Now Relative: +3n\n\t\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t\t *\n\t\t * @param {Time} time\n\t\t * @return {Seconds}\n\t\t */\n\t Tone.prototype.toSeconds = function (time) {\n\t if (Tone.isNumber(time)) {\n\t return time;\n\t } else if (Tone.isUndef(time)) {\n\t return this.now();\n\t } else if (Tone.isString(time)) {\n\t return new Tone.Time(time).toSeconds();\n\t } else if (time instanceof Tone.TimeBase) {\n\t return time.toSeconds();\n\t }\n\t };\n\t /**\n\t\t * Convert a frequency representation into a number.\n\t\t * @param {Frequency} freq\n\t\t * @return {Hertz} the frequency in hertz\n\t\t */\n\t Tone.prototype.toFrequency = function (freq) {\n\t if (Tone.isNumber(freq)) {\n\t return freq;\n\t } else if (Tone.isString(freq) || Tone.isUndef(freq)) {\n\t return new Tone.Frequency(freq).valueOf();\n\t } else if (freq instanceof Tone.TimeBase) {\n\t return freq.toFrequency();\n\t }\n\t };\n\t /**\n\t\t * Convert a time representation into ticks.\n\t\t * @param {Time} time\n\t\t * @return {Ticks} the time in ticks\n\t\t */\n\t Tone.prototype.toTicks = function (time) {\n\t if (Tone.isNumber(time) || Tone.isString(time)) {\n\t return new Tone.TransportTime(time).toTicks();\n\t } else if (Tone.isUndef(time)) {\n\t return Tone.Transport.ticks;\n\t } else if (time instanceof Tone.TimeBase) {\n\t return time.toTicks();\n\t }\n\t };\n\t return Tone;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t\t * additional unit conversion functionality. It also\n\t\t * serves as a base-class for classes which have a single,\n\t\t * automatable parameter.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {AudioParam} param The parameter to wrap.\n\t\t * @param {Tone.Type} units The units of the audio param.\n\t\t * @param {Boolean} convert If the param should be converted.\n\t\t */\n\t Tone.Param = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'param',\n\t 'units',\n\t 'convert'\n\t ], Tone.Param);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The native parameter to control\n\t\t\t * @type {AudioParam}\n\t\t\t * @private\n\t\t\t */\n\t this._param = this.input = options.param;\n\t /**\n\t\t\t * The units of the parameter\n\t\t\t * @type {Tone.Type}\n\t\t\t */\n\t this.units = options.units;\n\t /**\n\t\t\t * If the value should be converted or not\n\t\t\t * @type {Boolean}\n\t\t\t */\n\t this.convert = options.convert;\n\t /**\n\t\t\t * True if the signal value is being overridden by\n\t\t\t * a connected signal.\n\t\t\t * @readOnly\n\t\t\t * @type {boolean}\n\t\t\t * @private\n\t\t\t */\n\t this.overridden = false;\n\t /**\n\t\t\t * The timeline which tracks all of the automations.\n\t\t\t * @type {Tone.Timeline}\n\t\t\t * @private\n\t\t\t */\n\t this._events = new Tone.Timeline(1000);\n\t if (Tone.isDefined(options.value) && this._param) {\n\t this.value = options.value;\n\t }\n\t };\n\t Tone.extend(Tone.Param, Tone.AudioNode);\n\t /**\n\t\t * Defaults\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Param.defaults = {\n\t 'units': Tone.Type.Default,\n\t 'convert': true,\n\t 'param': undefined\n\t };\n\t /**\n\t\t * The current value of the parameter.\n\t\t * @memberOf Tone.Param#\n\t\t * @type {Number}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.Param.prototype, 'value', {\n\t get: function () {\n\t var now = this.now();\n\t return this._toUnits(this.getValueAtTime(now));\n\t },\n\t set: function (value) {\n\t this._initialValue = this._fromUnits(value);\n\t this.cancelScheduledValues(this.context.currentTime);\n\t this.setValueAtTime(value, this.context.currentTime);\n\t }\n\t });\n\t /**\n\t\t * The minimum output value of the parameter\n\t\t * @memberOf Tone.Param#\n\t\t * @type {Number}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.Param.prototype, 'minValue', {\n\t get: function () {\n\t if (this.units === Tone.Type.Time || this.units === Tone.Type.Frequency || this.units === Tone.Type.NormalRange || this.units === Tone.Type.Positive || this.units === Tone.Type.BPM) {\n\t return 0;\n\t } else if (this.units === Tone.Type.AudioRange) {\n\t return -1;\n\t } else if (this.units === Tone.Type.Decibels) {\n\t return -Infinity;\n\t } else {\n\t return this._param.minValue;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The maximum output value of the parameter\n\t\t * @memberOf Tone.Param#\n\t\t * @type {Number}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.Param.prototype, 'maxValue', {\n\t get: function () {\n\t if (this.units === Tone.Type.NormalRange || this.units === Tone.Type.AudioRange) {\n\t return 1;\n\t } else {\n\t return this._param.maxValue;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Convert the given value from the type specified by Tone.Param.units\n\t\t * into the destination value (such as Gain or Frequency).\n\t\t * @private\n\t\t * @param {*} val the value to convert\n\t\t * @return {number} the number which the value should be set to\n\t\t */\n\t Tone.Param.prototype._fromUnits = function (val) {\n\t if ((this.convert || Tone.isUndef(this.convert)) && !this.overridden) {\n\t switch (this.units) {\n\t case Tone.Type.Time:\n\t return this.toSeconds(val);\n\t case Tone.Type.Frequency:\n\t return this.toFrequency(val);\n\t case Tone.Type.Decibels:\n\t return Tone.dbToGain(val);\n\t case Tone.Type.NormalRange:\n\t return Math.min(Math.max(val, 0), 1);\n\t case Tone.Type.AudioRange:\n\t return Math.min(Math.max(val, -1), 1);\n\t case Tone.Type.Positive:\n\t return Math.max(val, 0);\n\t default:\n\t return val;\n\t }\n\t } else {\n\t return val;\n\t }\n\t };\n\t /**\n\t\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t\t * @private\n\t\t * @param {number} val the value to convert\n\t\t * @return {number}\n\t\t */\n\t Tone.Param.prototype._toUnits = function (val) {\n\t if (this.convert || Tone.isUndef(this.convert)) {\n\t switch (this.units) {\n\t case Tone.Type.Decibels:\n\t return Tone.gainToDb(val);\n\t default:\n\t return val;\n\t }\n\t } else {\n\t return val;\n\t }\n\t };\n\t /**\n\t\t * the minimum output value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.Param.prototype._minOutput = 0.00001;\n\t /**\n\t\t * The event types\n\t\t * @enum {String}\n\t\t * @private\n\t\t */\n\t Tone.Param.AutomationType = {\n\t Linear: 'linearRampToValueAtTime',\n\t Exponential: 'exponentialRampToValueAtTime',\n\t Target: 'setTargetAtTime',\n\t SetValue: 'setValueAtTime'\n\t };\n\t /**\n\t\t * Schedules a parameter value change at the given time.\n\t\t * @param {*}\tvalue The value to set the signal.\n\t\t * @param {Time} time The time when the change should occur.\n\t\t * @returns {Tone.Param} this\n\t\t * @example\n\t\t * //set the frequency to \"G4\" in exactly 1 second from now.\n\t\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t\t */\n\t Tone.Param.prototype.setValueAtTime = function (value, time) {\n\t time = this.toSeconds(time);\n\t value = this._fromUnits(value);\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.SetValue,\n\t 'value': value,\n\t 'time': time\n\t });\n\t this._param.setValueAtTime(value, time);\n\t return this;\n\t };\n\t /**\n\t\t * Get the signals value at the given time. Subsequent scheduling\n\t\t * may invalidate the returned value.\n\t\t * @param {Time} time When to get the value\n\t\t * @returns {Number} The value at the given time\n\t\t */\n\t Tone.Param.prototype.getValueAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t var after = this._events.getAfter(time);\n\t var before = this._events.get(time);\n\t var initialValue = Tone.defaultArg(this._initialValue, this._param.defaultValue);\n\t var value = initialValue;\n\t //if it was set by\n\t if (before === null) {\n\t value = initialValue;\n\t } else if (before.type === Tone.Param.AutomationType.Target) {\n\t var previous = this._events.getBefore(before.time);\n\t var previousVal;\n\t if (previous === null) {\n\t previousVal = initialValue;\n\t } else {\n\t previousVal = previous.value;\n\t }\n\t value = this._exponentialApproach(before.time, previousVal, before.value, before.constant, time);\n\t } else if (after === null) {\n\t value = before.value;\n\t } else if (after.type === Tone.Param.AutomationType.Linear) {\n\t value = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t } else if (after.type === Tone.Param.AutomationType.Exponential) {\n\t value = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t } else {\n\t value = before.value;\n\t }\n\t return value;\n\t };\n\t /**\n\t\t * Creates a schedule point with the current value at the current time.\n\t\t * This is useful for creating an automation anchor point in order to\n\t\t * schedule changes from the current value.\n\t\t *\n\t\t * @param {number=} now (Optionally) pass the now value in.\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.setRampPoint = function (time) {\n\t time = this.toSeconds(time);\n\t var currentVal = this.getValueAtTime(time);\n\t this.cancelAndHoldAtTime(time);\n\t if (currentVal === 0) {\n\t currentVal = this._minOutput;\n\t }\n\t this.setValueAtTime(this._toUnits(currentVal), time);\n\t return this;\n\t };\n\t /**\n\t\t * Schedules a linear continuous change in parameter value from the\n\t\t * previous scheduled parameter value to the given value.\n\t\t *\n\t\t * @param {number} value\n\t\t * @param {Time} endTime\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t value = this._fromUnits(value);\n\t endTime = this.toSeconds(endTime);\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.Linear,\n\t 'value': value,\n\t 'time': endTime\n\t });\n\t this._param.linearRampToValueAtTime(value, endTime);\n\t return this;\n\t };\n\t /**\n\t\t * Schedules an exponential continuous change in parameter value from\n\t\t * the previous scheduled parameter value to the given value.\n\t\t *\n\t\t * @param {number} value\n\t\t * @param {Time} endTime\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t value = this._fromUnits(value);\n\t value = Math.max(this._minOutput, value);\n\t endTime = this.toSeconds(endTime);\n\t //store the event\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.Exponential,\n\t 'time': endTime,\n\t 'value': value\n\t });\n\t this._param.exponentialRampToValueAtTime(value, endTime);\n\t return this;\n\t };\n\t /**\n\t\t * Schedules an exponential continuous change in parameter value from\n\t\t * the current time and current value to the given value over the\n\t\t * duration of the rampTime.\n\t\t *\n\t\t * @param {number} value The value to ramp to.\n\t\t * @param {Time} rampTime the time that it takes the\n\t\t * value to ramp from it's current value\n\t\t * @param {Time}\t[startTime=now] \tWhen the ramp should start.\n\t\t * @returns {Tone.Param} this\n\t\t * @example\n\t\t * //exponentially ramp to the value 2 over 4 seconds.\n\t\t * signal.exponentialRampTo(2, 4);\n\t\t */\n\t Tone.Param.prototype.exponentialRampTo = function (value, rampTime, startTime) {\n\t startTime = this.toSeconds(startTime);\n\t this.setRampPoint(startTime);\n\t this.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t return this;\n\t };\n\t /**\n\t\t * Schedules an linear continuous change in parameter value from\n\t\t * the current time and current value to the given value over the\n\t\t * duration of the rampTime.\n\t\t *\n\t\t * @param {number} value The value to ramp to.\n\t\t * @param {Time} rampTime the time that it takes the\n\t\t * value to ramp from it's current value\n\t\t * @param {Time}\t[startTime=now] \tWhen the ramp should start.\n\t\t * @returns {Tone.Param} this\n\t\t * @example\n\t\t * //linearly ramp to the value 4 over 3 seconds.\n\t\t * signal.linearRampTo(4, 3);\n\t\t */\n\t Tone.Param.prototype.linearRampTo = function (value, rampTime, startTime) {\n\t startTime = this.toSeconds(startTime);\n\t this.setRampPoint(startTime);\n\t this.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t return this;\n\t };\n\t /**\n\t\t * Start exponentially approaching the target value at the given time. Since it\n\t\t * is an exponential approach it will continue approaching after the ramp duration. The\n\t\t * rampTime is the time that it takes to reach over 99% of the way towards the value.\n\t\t * @param {number} value The value to ramp to.\n\t\t * @param {Time} rampTime the time that it takes the\n\t\t * value to ramp from it's current value\n\t\t * @param {Time}\t[startTime=now] \tWhen the ramp should start.\n\t\t * @returns {Tone.Param} this\n\t\t * @example\n\t\t * //exponentially ramp to the value 2 over 4 seconds.\n\t\t * signal.exponentialRampTo(2, 4);\n\t\t */\n\t Tone.Param.prototype.targetRampTo = function (value, rampTime, startTime) {\n\t startTime = this.toSeconds(startTime);\n\t this.setRampPoint(startTime);\n\t this.exponentialApproachValueAtTime(value, startTime, rampTime);\n\t return this;\n\t };\n\t /**\n\t\t * Start exponentially approaching the target value at the given time. Since it\n\t\t * is an exponential approach it will continue approaching after the ramp duration. The\n\t\t * rampTime is the time that it takes to reach over 99% of the way towards the value. This methods\n\t\t * is similar to setTargetAtTime except the third argument is a time instead of a 'timeConstant'\n\t\t * @param {number} value The value to ramp to.\n\t\t * @param {Time}\ttime \tWhen the ramp should start.\n\t\t * @param {Time} rampTime the time that it takes the\n\t\t * value to ramp from it's current value\n\t\t * @returns {Tone.Param} this\n\t\t * @example\n\t\t * //exponentially ramp to the value 2 over 4 seconds.\n\t\t * signal.exponentialRampTo(2, 4);\n\t\t */\n\t Tone.Param.prototype.exponentialApproachValueAtTime = function (value, time, rampTime) {\n\t var timeConstant = Math.log(this.toSeconds(rampTime) + 1) / Math.log(200);\n\t time = this.toSeconds(time);\n\t return this.setTargetAtTime(value, time, timeConstant);\n\t };\n\t /**\n\t\t * Start exponentially approaching the target value at the given time with\n\t\t * a rate having the given time constant.\n\t\t * @param {number} value\n\t\t * @param {Time} startTime\n\t\t * @param {number} timeConstant\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t value = this._fromUnits(value);\n\t // The value will never be able to approach without timeConstant > 0.\n\t if (timeConstant <= 0) {\n\t throw new Error('timeConstant must be greater than 0');\n\t }\n\t startTime = this.toSeconds(startTime);\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.Target,\n\t 'value': value,\n\t 'time': startTime,\n\t 'constant': timeConstant\n\t });\n\t this._param.setTargetAtTime(value, startTime, timeConstant);\n\t return this;\n\t };\n\t /**\n\t\t * Sets an array of arbitrary parameter values starting at the given time\n\t\t * for the given duration.\n\t\t *\n\t\t * @param {Array} values\n\t\t * @param {Time} startTime\n\t\t * @param {Time} duration\n\t\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t scaling = Tone.defaultArg(scaling, 1);\n\t duration = this.toSeconds(duration);\n\t startTime = this.toSeconds(startTime);\n\t this.setValueAtTime(values[0] * scaling, startTime);\n\t var segTime = duration / (values.length - 1);\n\t for (var i = 1; i < values.length; i++) {\n\t this.linearRampToValueAtTime(values[i] * scaling, startTime + i * segTime);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Cancels all scheduled parameter changes with times greater than or\n\t\t * equal to startTime.\n\t\t *\n\t\t * @param {Time} time\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.cancelScheduledValues = function (time) {\n\t time = this.toSeconds(time);\n\t this._events.cancel(time);\n\t this._param.cancelScheduledValues(time);\n\t return this;\n\t };\n\t /**\n\t\t * This is similar to [cancelScheduledValues](#cancelScheduledValues) except\n\t\t * it holds the automated value at time until the next automated event.\n\t\t * @param {Time} time\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.cancelAndHoldAtTime = function (time) {\n\t var valueAtTime = this.getValueAtTime(time);\n\t //if there is an event at the given time\n\t //and that even is not a \"set\"\n\t var before = this._events.get(time);\n\t var after = this._events.getAfter(time);\n\t if (before && before.time === time) {\n\t //remove everything after\n\t if (after) {\n\t this._events.cancel(after.time);\n\t } else {\n\t this._events.cancel(time + 0.000001);\n\t }\n\t } else if (after) {\n\t //cancel the next event(s)\n\t this._events.cancel(after.time);\n\t if (!this._param.cancelAndHoldAtTime) {\n\t this._param.cancelScheduledValues(time);\n\t }\n\t if (after.type === Tone.Param.AutomationType.Linear) {\n\t if (!this._param.cancelAndHoldAtTime) {\n\t this.linearRampToValueAtTime(valueAtTime, time);\n\t } else {\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.Linear,\n\t 'value': valueAtTime,\n\t 'time': time\n\t });\n\t }\n\t } else if (after.type === Tone.Param.AutomationType.Exponential) {\n\t if (!this._param.cancelAndHoldAtTime) {\n\t this.exponentialRampToValueAtTime(valueAtTime, time);\n\t } else {\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.Exponential,\n\t 'value': valueAtTime,\n\t 'time': time\n\t });\n\t }\n\t }\n\t }\n\t //set the value at the given time\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.SetValue,\n\t 'value': valueAtTime,\n\t 'time': time\n\t });\n\t if (this._param.cancelAndHoldAtTime) {\n\t this._param.cancelAndHoldAtTime(time);\n\t } else {\n\t this._param.setValueAtTime(valueAtTime, time);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Ramps to the given value over the duration of the rampTime.\n\t\t * Automatically selects the best ramp type (exponential or linear)\n\t\t * depending on the `units` of the signal\n\t\t *\n\t\t * @param {number} value\n\t\t * @param {Time} rampTime \tThe time that it takes the\n\t\t * value to ramp from it's current value\n\t\t * @param {Time}\t[startTime=now] \tWhen the ramp should start.\n\t\t * @returns {Tone.Param} this\n\t\t * @example\n\t\t * //ramp to the value either linearly or exponentially\n\t\t * //depending on the \"units\" value of the signal\n\t\t * signal.rampTo(0, 10);\n\t\t * @example\n\t\t * //schedule it to ramp starting at a specific time\n\t\t * signal.rampTo(0, 10, 5)\n\t\t */\n\t Tone.Param.prototype.rampTo = function (value, rampTime, startTime) {\n\t rampTime = Tone.defaultArg(rampTime, 0.1);\n\t if (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels) {\n\t this.exponentialRampTo(value, rampTime, startTime);\n\t } else {\n\t this.linearRampTo(value, rampTime, startTime);\n\t }\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tAUTOMATION CURVE CALCULATIONS\n\t //\tMIT License, copyright (c) 2014 Jordan Santell\n\t ///////////////////////////////////////////////////////////////////////////\n\t // Calculates the the value along the curve produced by setTargetAtTime\n\t Tone.Param.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t };\n\t // Calculates the the value along the curve produced by linearRampToValueAtTime\n\t Tone.Param.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t };\n\t // Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t Tone.Param.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._param = null;\n\t this._events = null;\n\t return this;\n\t };\n\t return Tone.Param;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Wrapper around the OfflineAudioContext\n\t\t * @extends {Tone.Context}\n\t\t * @param {Number} channels The number of channels to render\n\t\t * @param {Number} duration The duration to render in samples\n\t\t * @param {Number} sampleRate the sample rate to render at\n\t\t */\n\t Tone.OfflineContext = function (channels, duration, sampleRate) {\n\t /**\n\t\t\t * The offline context\n\t\t\t * @private\n\t\t\t * @type {OfflineAudioContext}\n\t\t\t */\n\t var offlineContext = new OfflineAudioContext(channels, duration * sampleRate, sampleRate);\n\t //wrap the methods/members\n\t Tone.Context.call(this, {\n\t 'context': offlineContext,\n\t 'clockSource': 'offline',\n\t 'lookAhead': 0,\n\t 'updateInterval': 128 / sampleRate\n\t });\n\t /**\n\t\t\t * A private reference to the duration\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._duration = duration;\n\t /**\n\t\t\t * An artificial clock source\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._currentTime = 0;\n\t };\n\t Tone.extend(Tone.OfflineContext, Tone.Context);\n\t /**\n\t\t * Override the now method to point to the internal clock time\n\t\t * @return {Number}\n\t\t */\n\t Tone.OfflineContext.prototype.now = function () {\n\t return this._currentTime;\n\t };\n\t /**\n\t\t * Render the output of the OfflineContext\n\t\t * @return {Promise}\n\t\t */\n\t Tone.OfflineContext.prototype.render = function () {\n\t while (this._duration - this._currentTime >= 0) {\n\t //invoke all the callbacks on that time\n\t this.emit('tick');\n\t //increment the clock\n\t this._currentTime += this.blockTime;\n\t }\n\t return this._context.startRendering();\n\t };\n\t /**\n\t\t * Close the context\n\t\t * @return {Promise}\n\t\t */\n\t Tone.OfflineContext.prototype.close = function () {\n\t this._context = null;\n\t return Promise.resolve();\n\t };\n\t return Tone.OfflineContext;\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported) {\n\t var ua = navigator.userAgent.toLowerCase();\n\t var isMobileSafari = ua.includes('safari') && !ua.includes('chrome') && ua.includes('mobile');\n\t if (isMobileSafari) {\n\t //mobile safari has a bizarre bug with the offline context\n\t //when a BufferSourceNode is started, it starts the offline context\n\t //\n\t //deferring all BufferSource starts till the last possible moment\n\t //reduces the likelihood of this happening\n\t Tone.OfflineContext.prototype.createBufferSource = function () {\n\t var bufferSource = this._context.createBufferSource();\n\t var _native_start = bufferSource.start;\n\t bufferSource.start = function (time) {\n\t this.setTimeout(function () {\n\t _native_start.call(bufferSource, time);\n\t }.bind(this), 0);\n\t }.bind(this);\n\t return bufferSource;\n\t };\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t\t * The GainNode is a basic building block of the Web Audio\n\t\t * API and is useful for routing audio and adjusting gains.\n\t\t * @extends {Tone}\n\t\t * @param {Number=} gain The initial gain of the GainNode\n\t\t * @param {Tone.Type=} units The units of the gain parameter.\n\t\t */\n\t Tone.Gain = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'gain',\n\t 'units'\n\t ], Tone.Gain);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The GainNode\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.input = this.output = this._gainNode = this.context.createGain();\n\t /**\n\t\t\t * The gain parameter of the gain node.\n\t\t\t * @type {Gain}\n\t\t\t * @signal\n\t\t\t */\n\t this.gain = new Tone.Param({\n\t 'param': this._gainNode.gain,\n\t 'units': options.units,\n\t 'value': options.gain,\n\t 'convert': options.convert\n\t });\n\t this._readOnly('gain');\n\t };\n\t Tone.extend(Tone.Gain, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Gain.defaults = {\n\t 'gain': 1,\n\t 'convert': true\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Gain} this\n\t\t */\n\t Tone.Gain.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._gainNode.disconnect();\n\t this._gainNode = null;\n\t this._writable('gain');\n\t this.gain.dispose();\n\t this.gain = null;\n\t };\n\t return Tone.Gain;\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported && !AudioContext.prototype.createConstantSource) {\n\t var ConstantSourceNode = function (context) {\n\t this.context = context;\n\t var buffer = context.createBuffer(1, 128, context.sampleRate);\n\t var arr = buffer.getChannelData(0);\n\t for (var i = 0; i < arr.length; i++) {\n\t arr[i] = 1;\n\t }\n\t this._bufferSource = context.createBufferSource();\n\t this._bufferSource.channelCount = 1;\n\t this._bufferSource.channelCountMode = 'explicit';\n\t this._bufferSource.buffer = buffer;\n\t this._bufferSource.loop = true;\n\t var gainNode = this._output = context.createGain();\n\t this.offset = gainNode.gain;\n\t this._bufferSource.connect(gainNode);\n\t };\n\t ConstantSourceNode.prototype.start = function (time) {\n\t this._bufferSource.start(time);\n\t return this;\n\t };\n\t ConstantSourceNode.prototype.stop = function (time) {\n\t this._bufferSource.stop(time);\n\t return this;\n\t };\n\t ConstantSourceNode.prototype.connect = function () {\n\t this._output.connect.apply(this._output, arguments);\n\t return this;\n\t };\n\t ConstantSourceNode.prototype.disconnect = function () {\n\t this._output.disconnect.apply(this._output, arguments);\n\t return this;\n\t };\n\t AudioContext.prototype.createConstantSource = function () {\n\t return new ConstantSourceNode(this);\n\t };\n\t Tone.Context.prototype.createConstantSource = function () {\n\t return new ConstantSourceNode(this);\n\t };\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t\t * has all of the methods available to native Web Audio\n\t\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t\t * as well as additional conveniences. Read more about working with signals\n\t\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Param}\n\t\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t\t * is passed in, that parameter will be wrapped\n\t\t * and controlled by the Signal.\n\t\t * @param {string} [units=Number] unit The units the signal is in.\n\t\t * @example\n\t\t * var signal = new Tone.Signal(10);\n\t\t */\n\t Tone.Signal = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'value',\n\t 'units'\n\t ], Tone.Signal);\n\t Tone.Param.call(this, options);\n\t /**\n\t\t\t* When a signal is connected to another signal or audio param,\n\t\t\t* this signal becomes a proxy for it\n\t\t\t* @type {Array}\n\t\t\t* @private\n\t\t\t*/\n\t this._proxies = [];\n\t /**\n\t\t\t* Indicates if the constant source was started or not\n\t\t\t* @private\n\t\t\t* @type {Boolean}\n\t\t\t*/\n\t this._sourceStarted = false;\n\t /**\n\t\t\t * The constant source node which generates the signal\n\t\t\t * @type {ConstantSourceNode}\n\t\t\t * @private\n\t\t\t */\n\t this._constantSource = this.context.createConstantSource();\n\t this._param = this._constantSource.offset;\n\t this.value = options.value;\n\t /**\n\t\t\t * The node where the constant signal value is scaled.\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.output = this._constantSource;\n\t /**\n\t\t\t * The node where the value is set.\n\t\t\t * @type {Tone.Param}\n\t\t\t * @private\n\t\t\t */\n\t this.input = this._param = this.output.offset;\n\t };\n\t Tone.extend(Tone.Signal, Tone.Param);\n\t /**\n\t\t * The default values\n\t\t * @type {Object}\n\t\t * @static\n\t\t * @const\n\t\t */\n\t Tone.Signal.defaults = {\n\t 'value': 0,\n\t 'units': Tone.Type.Default,\n\t 'convert': true\n\t };\n\t /**\n\t\t * When signals connect to other signals or AudioParams,\n\t\t * they take over the output value of that signal or AudioParam.\n\t\t * For all other nodes, the behavior is the same as a default <code>connect</code>.\n\t\t *\n\t\t * @override\n\t\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node\n\t\t * @param {number} [outputNumber=0] The output number to connect from.\n\t\t * @param {number} [inputNumber=0] The input number to connect to.\n\t\t * @returns {Tone.Signal} this\n\t\t * @method\n\t\t */\n\t Tone.Signal.prototype.connect = function (node) {\n\t //this is an optimization where this node will forward automations\n\t //to connected nodes without any signal if possible.\n\t if (this._isParam(node) && !this._sourceStarted) {\n\t this._proxies.push(node);\n\t node.overridden = true;\n\t this._applyAutomations(node);\n\t } else {\n\t Tone.SignalBase.prototype.connect.apply(this, arguments);\n\t if (!this._sourceStarted) {\n\t this._sourceStarted = true;\n\t this._constantSource.start(0);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Takes a node as an argument and returns if it is a Param or AudioParam\n\t\t * @param {*} node The node to test\n\t\t * @return {Boolean}\n\t\t * @private\n\t\t */\n\t Tone.Signal.prototype._isParam = function (node) {\n\t return Tone.Param && Tone.Param === node.constructor || node instanceof AudioParam;\n\t };\n\t /**\n\t\t * Discard the optimization and connect all of the proxies\n\t\t * @private\n\t\t */\n\t Tone.Signal.prototype._connectProxies = function () {\n\t if (!this._sourceStarted) {\n\t this._sourceStarted = true;\n\t this._constantSource.start(0);\n\t }\n\t this._proxies.forEach(function (proxy) {\n\t Tone.SignalBase.prototype.connect.call(this, proxy);\n\t if (proxy._proxies) {\n\t proxy._connectProxies();\n\t }\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Invoked when a node is connected to this\n\t\t * @param {AudioNode} from\n\t\t * @private\n\t\t */\n\t Tone.Signal.prototype._onConnect = function (from) {\n\t if (!this._isParam(from)) {\n\t //connect all the proxies\n\t this._connectProxies();\n\t }\n\t };\n\t /**\n\t\t * Apply all the current automations to the given parameter\n\t\t * @param {AudioParam} param\n\t\t * @private\n\t\t */\n\t Tone.Signal.prototype._applyAutomations = function (param) {\n\t var now = this.context.currentTime;\n\t param.cancelScheduledValues(now);\n\t var currentVal = this.getValueAtTime(now);\n\t param.setValueAtTime(currentVal, now);\n\t this._events.forEachFrom(now, function (event) {\n\t param[event.type](event.value, event.time, event.constant);\n\t });\n\t };\n\t /**\n\t\t * Disconnect from the given node or all nodes if no param is given.\n\t\t * @param {AudioNode|AudioParam} node\n\t\t * @return {Tone.Signal} this\n\t\t */\n\t Tone.Signal.prototype.disconnect = function (node) {\n\t if (this._proxies.includes(node)) {\n\t var index = this._proxies.indexOf(node);\n\t this._proxies.splice(index, 1);\n\t } else if (!node) {\n\t //no argument, disconnect everything\n\t this._proxies = [];\n\t }\n\t return Tone.SignalBase.prototype.disconnect.apply(this, arguments);\n\t };\n\t /**\n\t\t * Return the current signal value at the given time.\n\t\t * @param {Time} time When to get the signal value\n\t\t * @return {Number}\n\t\t */\n\t Tone.Signal.prototype.getValueAtTime = function (time) {\n\t if (this._param.getValueAtTime) {\n\t return this._param.getValueAtTime(time);\n\t } else {\n\t return Tone.Param.prototype.getValueAtTime.call(this, time);\n\t }\n\t };\n\t //wrap all of the automation methods\n\t [\n\t 'setValueAtTime',\n\t 'linearRampToValueAtTime',\n\t 'exponentialRampToValueAtTime',\n\t 'setTargetAtTime'\n\t ].forEach(function (method) {\n\t var previousMethod = Tone.Signal.prototype[method];\n\t Tone.Signal.prototype[method] = function () {\n\t var args = arguments;\n\t previousMethod.apply(this, arguments);\n\t args[0] = this._fromUnits(args[0]);\n\t args[1] = this.toSeconds(args[1]);\n\t //apply it to the proxies\n\t this._proxies.forEach(function (signal) {\n\t signal[method].apply(signal, args);\n\t });\n\t };\n\t });\n\t [\n\t 'cancelScheduledValues',\n\t 'cancelAndHoldAtTime'\n\t ].forEach(function (method) {\n\t var previousMethod = Tone.Signal.prototype[method];\n\t Tone.Signal.prototype[method] = function () {\n\t var args = arguments;\n\t previousMethod.apply(this, arguments);\n\t args[0] = this.toSeconds(args[0]);\n\t //apply it to the proxies\n\t this._proxies.forEach(function (signal) {\n\t signal[method].apply(signal, args);\n\t });\n\t };\n\t });\n\t /**\n\t\t * dispose and disconnect\n\t\t * @returns {Tone.Signal} this\n\t\t */\n\t Tone.Signal.prototype.dispose = function () {\n\t Tone.Param.prototype.dispose.call(this);\n\t this._constantSource.disconnect();\n\t this._constantSource = null;\n\t this._proxies = null;\n\t return this;\n\t };\n\t return Tone.Signal;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t\t * must be AudioRange.\n\t\t *\n\t\t * @extends {Tone.SignalBase}\n\t\t * @constructor\n\t\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t\t * @example\n\t\t * var pow = new Tone.Pow(2);\n\t\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t\t * //output of pow is 0.25. \n\t\t */\n\t Tone.Pow = function (exp) {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * the exponent\n\t\t\t * @private\n\t\t\t * @type {number}\n\t\t\t */\n\t this._exp = Tone.defaultArg(exp, 1);\n\t /**\n\t\t\t * @type {WaveShaperNode}\n\t\t\t * @private\n\t\t\t */\n\t this._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t };\n\t Tone.extend(Tone.Pow, Tone.SignalBase);\n\t /**\n\t\t * The value of the exponent.\n\t\t * @memberOf Tone.Pow#\n\t\t * @type {number}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.Pow.prototype, 'value', {\n\t get: function () {\n\t return this._exp;\n\t },\n\t set: function (exp) {\n\t this._exp = exp;\n\t this._expScaler.setMap(this._expFunc(this._exp));\n\t }\n\t });\n\t /**\n\t\t * the function which maps the waveshaper\n\t\t * @param {number} exp\n\t\t * @return {function}\n\t\t * @private\n\t\t */\n\t Tone.Pow.prototype._expFunc = function (exp) {\n\t return function (val) {\n\t return Math.pow(Math.abs(val), exp);\n\t };\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Pow} this\n\t\t */\n\t Tone.Pow.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._expScaler.dispose();\n\t this._expScaler = null;\n\t return this;\n\t };\n\t return Tone.Pow;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Envelope is an [ADSR](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope)\n\t\t * envelope generator. Tone.Envelope outputs a signal which\n\t\t * can be connected to an AudioParam or Tone.Signal.\n\t\t * <img src=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Time} [attack] The amount of time it takes for the envelope to go from\n\t\t * 0 to it's maximum value.\n\t\t * @param {Time} [decay]\tThe period of time after the attack that it takes for the envelope\n\t\t * \tto fall to the sustain value.\n\t\t * @param {NormalRange} [sustain]\tThe percent of the maximum value that the envelope rests at until\n\t\t * \tthe release is triggered.\n\t\t * @param {Time} [release]\tThe amount of time after the release is triggered it takes to reach 0.\n\t\t * @example\n\t\t * //an amplitude envelope\n\t\t * var gainNode = Tone.context.createGain();\n\t\t * var env = new Tone.Envelope({\n\t\t * \t\"attack\" : 0.1,\n\t\t * \t\"decay\" : 0.2,\n\t\t * \t\"sustain\" : 1,\n\t\t * \t\"release\" : 0.8,\n\t\t * });\n\t\t * env.connect(gainNode.gain);\n\t\t */\n\t Tone.Envelope = function () {\n\t //get all of the defaults\n\t var options = Tone.defaults(arguments, [\n\t 'attack',\n\t 'decay',\n\t 'sustain',\n\t 'release'\n\t ], Tone.Envelope);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * When triggerAttack is called, the attack time is the amount of\n\t\t\t * time it takes for the envelope to reach it's maximum value.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.attack = options.attack;\n\t /**\n\t\t\t * After the attack portion of the envelope, the value will fall\n\t\t\t * over the duration of the decay time to it's sustain value.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.decay = options.decay;\n\t /**\n\t\t\t * \tThe sustain value is the value\n\t\t\t * \twhich the envelope rests at after triggerAttack is\n\t\t\t * \tcalled, but before triggerRelease is invoked.\n\t\t\t * @type {NormalRange}\n\t\t\t */\n\t this.sustain = options.sustain;\n\t /**\n\t\t\t * After triggerRelease is called, the envelope's\n\t\t\t * value will fall to it's miminum value over the\n\t\t\t * duration of the release time.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.release = options.release;\n\t /**\n\t\t\t * the next time the envelope is at standby\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._attackCurve = 'linear';\n\t /**\n\t\t\t * the next time the envelope is at standby\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._releaseCurve = 'exponential';\n\t /**\n\t\t\t * the signal\n\t\t\t * @type {Tone.Signal}\n\t\t\t * @private\n\t\t\t */\n\t this._sig = this.output = new Tone.Signal(0);\n\t //set the attackCurve initially\n\t this.attackCurve = options.attackCurve;\n\t this.releaseCurve = options.releaseCurve;\n\t };\n\t Tone.extend(Tone.Envelope, Tone.AudioNode);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t * @const\n\t\t */\n\t Tone.Envelope.defaults = {\n\t 'attack': 0.01,\n\t 'decay': 0.1,\n\t 'sustain': 0.5,\n\t 'release': 1,\n\t 'attackCurve': 'linear',\n\t 'releaseCurve': 'exponential'\n\t };\n\t /**\n\t\t * Read the current value of the envelope. Useful for\n\t\t * syncronizing visual output to the envelope.\n\t\t * @memberOf Tone.Envelope#\n\t\t * @type {Number}\n\t\t * @name value\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Envelope.prototype, 'value', {\n\t get: function () {\n\t return this.getValueAtTime(this.now());\n\t }\n\t });\n\t /**\n\t\t * The shape of the attack.\n\t\t * Can be any of these strings:\n\t\t * <ul>\n\t\t * <li>linear</li>\n\t\t * <li>exponential</li>\n\t\t * <li>sine</li>\n\t\t * <li>cosine</li>\n\t\t * <li>bounce</li>\n\t\t * <li>ripple</li>\n\t\t * <li>step</li>\n\t\t * </ul>\n\t\t * Can also be an array which describes the curve. Values\n\t\t * in the array are evenly subdivided and linearly\n\t\t * interpolated over the duration of the attack.\n\t\t * @memberOf Tone.Envelope#\n\t\t * @type {String|Array}\n\t\t * @name attackCurve\n\t\t * @example\n\t\t * env.attackCurve = \"linear\";\n\t\t * @example\n\t\t * //can also be an array\n\t\t * env.attackCurve = [0, 0.2, 0.3, 0.4, 1]\n\t\t */\n\t Object.defineProperty(Tone.Envelope.prototype, 'attackCurve', {\n\t get: function () {\n\t if (Tone.isString(this._attackCurve)) {\n\t return this._attackCurve;\n\t } else if (Tone.isArray(this._attackCurve)) {\n\t //look up the name in the curves array\n\t for (var type in Tone.Envelope.Type) {\n\t if (Tone.Envelope.Type[type].In === this._attackCurve) {\n\t return type;\n\t }\n\t }\n\t //otherwise just return the array\n\t return this._attackCurve;\n\t }\n\t },\n\t set: function (curve) {\n\t //check if it's a valid type\n\t if (Tone.Envelope.Type.hasOwnProperty(curve)) {\n\t var curveDef = Tone.Envelope.Type[curve];\n\t if (Tone.isObject(curveDef)) {\n\t this._attackCurve = curveDef.In;\n\t } else {\n\t this._attackCurve = curveDef;\n\t }\n\t } else if (Tone.isArray(curve)) {\n\t this._attackCurve = curve;\n\t } else {\n\t throw new Error('Tone.Envelope: invalid curve: ' + curve);\n\t }\n\t }\n\t });\n\t /**\n\t\t * The shape of the release. See the attack curve types.\n\t\t * @memberOf Tone.Envelope#\n\t\t * @type {String|Array}\n\t\t * @name releaseCurve\n\t\t * @example\n\t\t * env.releaseCurve = \"linear\";\n\t\t */\n\t Object.defineProperty(Tone.Envelope.prototype, 'releaseCurve', {\n\t get: function () {\n\t if (Tone.isString(this._releaseCurve)) {\n\t return this._releaseCurve;\n\t } else if (Tone.isArray(this._releaseCurve)) {\n\t //look up the name in the curves array\n\t for (var type in Tone.Envelope.Type) {\n\t if (Tone.Envelope.Type[type].Out === this._releaseCurve) {\n\t return type;\n\t }\n\t }\n\t //otherwise just return the array\n\t return this._releaseCurve;\n\t }\n\t },\n\t set: function (curve) {\n\t //check if it's a valid type\n\t if (Tone.Envelope.Type.hasOwnProperty(curve)) {\n\t var curveDef = Tone.Envelope.Type[curve];\n\t if (Tone.isObject(curveDef)) {\n\t this._releaseCurve = curveDef.Out;\n\t } else {\n\t this._releaseCurve = curveDef;\n\t }\n\t } else if (Tone.isArray(curve)) {\n\t this._releaseCurve = curve;\n\t } else {\n\t throw new Error('Tone.Envelope: invalid curve: ' + curve);\n\t }\n\t }\n\t });\n\t /**\n\t\t * Trigger the attack/decay portion of the ADSR envelope.\n\t\t * @param {Time} [time=now] When the attack should start.\n\t\t * @param {NormalRange} [velocity=1] The velocity of the envelope scales the vales.\n\t\t * number between 0-1\n\t\t * @returns {Tone.Envelope} this\n\t\t * @example\n\t\t * //trigger the attack 0.5 seconds from now with a velocity of 0.2\n\t\t * env.triggerAttack(\"+0.5\", 0.2);\n\t\t */\n\t Tone.Envelope.prototype.triggerAttack = function (time, velocity) {\n\t time = this.toSeconds(time);\n\t var originalAttack = this.toSeconds(this.attack);\n\t var attack = originalAttack;\n\t var decay = this.toSeconds(this.decay);\n\t velocity = Tone.defaultArg(velocity, 1);\n\t //check if it's not a complete attack\n\t var currentValue = this.getValueAtTime(time);\n\t if (currentValue > 0) {\n\t //subtract the current value from the attack time\n\t var attackRate = 1 / attack;\n\t var remainingDistance = 1 - currentValue;\n\t //the attack is now the remaining time\n\t attack = remainingDistance / attackRate;\n\t }\n\t //attack\n\t if (this._attackCurve === 'linear') {\n\t this._sig.linearRampTo(velocity, attack, time);\n\t } else if (this._attackCurve === 'exponential') {\n\t this._sig.targetRampTo(velocity, attack, time);\n\t } else if (attack > 0) {\n\t this._sig.cancelAndHoldAtTime(time);\n\t var curve = this._attackCurve;\n\t //take only a portion of the curve\n\t if (attack < originalAttack) {\n\t var percentComplete = 1 - attack / originalAttack;\n\t var sliceIndex = Math.floor(percentComplete * this._attackCurve.length);\n\t curve = this._attackCurve.slice(sliceIndex);\n\t //the first index is the current value\n\t curve[0] = currentValue;\n\t }\n\t this._sig.setValueCurveAtTime(curve, time, attack, velocity);\n\t }\n\t //decay\n\t if (decay) {\n\t this._sig.targetRampTo(velocity * this.sustain, decay, attack + time);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Triggers the release of the envelope.\n\t\t * @param {Time} [time=now] When the release portion of the envelope should start.\n\t\t * @returns {Tone.Envelope} this\n\t\t * @example\n\t\t * //trigger release immediately\n\t\t * env.triggerRelease();\n\t\t */\n\t Tone.Envelope.prototype.triggerRelease = function (time) {\n\t time = this.toSeconds(time);\n\t var currentValue = this.getValueAtTime(time);\n\t if (currentValue > 0) {\n\t var release = this.toSeconds(this.release);\n\t if (this._releaseCurve === 'linear') {\n\t this._sig.linearRampTo(0, release, time);\n\t } else if (this._releaseCurve === 'exponential') {\n\t this._sig.targetRampTo(0, release, time);\n\t } else {\n\t var curve = this._releaseCurve;\n\t if (Tone.isArray(curve)) {\n\t this._sig.cancelAndHoldAtTime(time);\n\t this._sig.setValueCurveAtTime(curve, time, release, currentValue);\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Get the scheduled value at the given time. This will\n\t\t * return the unconverted (raw) value.\n\t\t * @param {Number} time The time in seconds.\n\t\t * @return {Number} The scheduled value at the given time.\n\t\t */\n\t Tone.Envelope.prototype.getValueAtTime = function (time) {\n\t return this._sig.getValueAtTime(time);\n\t };\n\t /**\n\t\t * triggerAttackRelease is shorthand for triggerAttack, then waiting\n\t\t * some duration, then triggerRelease.\n\t\t * @param {Time} duration The duration of the sustain.\n\t\t * @param {Time} [time=now] When the attack should be triggered.\n\t\t * @param {number} [velocity=1] The velocity of the envelope.\n\t\t * @returns {Tone.Envelope} this\n\t\t * @example\n\t\t * //trigger the attack and then the release after 0.6 seconds.\n\t\t * env.triggerAttackRelease(0.6);\n\t\t */\n\t Tone.Envelope.prototype.triggerAttackRelease = function (duration, time, velocity) {\n\t time = this.toSeconds(time);\n\t this.triggerAttack(time, velocity);\n\t this.triggerRelease(time + this.toSeconds(duration));\n\t return this;\n\t };\n\t /**\n\t\t * Cancels all scheduled envelope changes after the given time.\n\t\t * @param {Time} after\n\t\t * @returns {Tone.Envelope} this\n\t\t */\n\t Tone.Envelope.prototype.cancel = function (after) {\n\t this._sig.cancelScheduledValues(after);\n\t return this;\n\t };\n\t /**\n\t\t * Borrows the connect method from Tone.Signal.\n\t\t * @function\n\t\t * @private\n\t\t */\n\t Tone.Envelope.prototype.connect = Tone.SignalBase.prototype.connect;\n\t /**\n\t \t * Generate some complex envelope curves.\n\t \t */\n\t (function _createCurves() {\n\t var curveLen = 128;\n\t var i, k;\n\t //cosine curve\n\t var cosineCurve = [];\n\t for (i = 0; i < curveLen; i++) {\n\t cosineCurve[i] = Math.sin(i / (curveLen - 1) * (Math.PI / 2));\n\t }\n\t //ripple curve\n\t var rippleCurve = [];\n\t var rippleCurveFreq = 6.4;\n\t for (i = 0; i < curveLen - 1; i++) {\n\t k = i / (curveLen - 1);\n\t var sineWave = Math.sin(k * (Math.PI * 2) * rippleCurveFreq - Math.PI / 2) + 1;\n\t rippleCurve[i] = sineWave / 10 + k * 0.83;\n\t }\n\t rippleCurve[curveLen - 1] = 1;\n\t //stairs curve\n\t var stairsCurve = [];\n\t var steps = 5;\n\t for (i = 0; i < curveLen; i++) {\n\t stairsCurve[i] = Math.ceil(i / (curveLen - 1) * steps) / steps;\n\t }\n\t //in-out easing curve\n\t var sineCurve = [];\n\t for (i = 0; i < curveLen; i++) {\n\t k = i / (curveLen - 1);\n\t sineCurve[i] = 0.5 * (1 - Math.cos(Math.PI * k));\n\t }\n\t //a bounce curve\n\t var bounceCurve = [];\n\t for (i = 0; i < curveLen; i++) {\n\t k = i / (curveLen - 1);\n\t var freq = Math.pow(k, 3) * 4 + 0.2;\n\t var val = Math.cos(freq * Math.PI * 2 * k);\n\t bounceCurve[i] = Math.abs(val * (1 - k));\n\t }\n\t /**\n\t\t\t * Invert a value curve to make it work for the release\n\t\t\t * @private\n\t\t\t */\n\t function invertCurve(curve) {\n\t var out = new Array(curve.length);\n\t for (var j = 0; j < curve.length; j++) {\n\t out[j] = 1 - curve[j];\n\t }\n\t return out;\n\t }\n\t /**\n\t\t\t * reverse the curve\n\t\t\t * @private\n\t\t\t */\n\t function reverseCurve(curve) {\n\t return curve.slice(0).reverse();\n\t }\n\t /**\n\t\t\t * attack and release curve arrays\n\t\t\t * @type {Object}\n\t\t\t * @private\n\t\t\t */\n\t Tone.Envelope.Type = {\n\t 'linear': 'linear',\n\t 'exponential': 'exponential',\n\t 'bounce': {\n\t In: invertCurve(bounceCurve),\n\t Out: bounceCurve\n\t },\n\t 'cosine': {\n\t In: cosineCurve,\n\t Out: reverseCurve(cosineCurve)\n\t },\n\t 'step': {\n\t In: stairsCurve,\n\t Out: invertCurve(stairsCurve)\n\t },\n\t 'ripple': {\n\t In: rippleCurve,\n\t Out: invertCurve(rippleCurve)\n\t },\n\t 'sine': {\n\t In: sineCurve,\n\t Out: invertCurve(sineCurve)\n\t }\n\t };\n\t }());\n\t /**\n\t\t * Disconnect and dispose.\n\t\t * @returns {Tone.Envelope} this\n\t\t */\n\t Tone.Envelope.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._sig.dispose();\n\t this._sig = null;\n\t this._attackCurve = null;\n\t this._releaseCurve = null;\n\t return this;\n\t };\n\t return Tone.Envelope;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.AmplitudeEnvelope is a Tone.Envelope connected to a gain node.\n\t\t * Unlike Tone.Envelope, which outputs the envelope's value, Tone.AmplitudeEnvelope accepts\n\t\t * an audio signal as the input and will apply the envelope to the amplitude\n\t\t * of the signal. Read more about ADSR Envelopes on [Wikipedia](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Envelope}\n\t\t * @param {Time|Object} [attack] The amount of time it takes for the envelope to go from\n\t\t * 0 to it's maximum value.\n\t\t * @param {Time} [decay]\tThe period of time after the attack that it takes for the envelope\n\t\t * \tto fall to the sustain value.\n\t\t * @param {NormalRange} [sustain]\tThe percent of the maximum value that the envelope rests at until\n\t\t * \tthe release is triggered.\n\t\t * @param {Time} [release]\tThe amount of time after the release is triggered it takes to reach 0.\n\t\t * @example\n\t\t * var ampEnv = new Tone.AmplitudeEnvelope({\n\t\t * \t\"attack\": 0.1,\n\t\t * \t\"decay\": 0.2,\n\t\t * \t\"sustain\": 1.0,\n\t\t * \t\"release\": 0.8\n\t\t * }).toMaster();\n\t\t * //create an oscillator and connect it\n\t\t * var osc = new Tone.Oscillator().connect(ampEnv).start();\n\t\t * //trigger the envelopes attack and release \"8t\" apart\n\t\t * ampEnv.triggerAttackRelease(\"8t\");\n\t\t */\n\t Tone.AmplitudeEnvelope = function () {\n\t Tone.Envelope.apply(this, arguments);\n\t /**\n\t\t\t * the input node\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.input = this.output = new Tone.Gain();\n\t this._sig.connect(this.output.gain);\n\t };\n\t Tone.extend(Tone.AmplitudeEnvelope, Tone.Envelope);\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.AmplitudeEnvelope} this\n\t\t */\n\t Tone.AmplitudeEnvelope.prototype.dispose = function () {\n\t Tone.Envelope.prototype.dispose.call(this);\n\t return this;\n\t };\n\t return Tone.AmplitudeEnvelope;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * AnalyserNode.getFloatTimeDomainData polyfill\n\t\t * @private\n\t\t */\n\t if (Tone.supported) {\n\t if (!AnalyserNode.prototype.getFloatTimeDomainData) {\n\t //referenced https://github.com/mohayonao/get-float-time-domain-data\n\t AnalyserNode.prototype.getFloatTimeDomainData = function (array) {\n\t var uint8 = new Uint8Array(array.length);\n\t this.getByteTimeDomainData(uint8);\n\t for (var i = 0; i < uint8.length; i++) {\n\t array[i] = (uint8[i] - 128) / 128;\n\t }\n\t };\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Wrapper around the native Web Audio's\n\t\t * [AnalyserNode](http://webaudio.github.io/web-audio-api/#idl-def-AnalyserNode).\n\t\t * Extracts FFT or Waveform data from the incoming signal.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {String=} type The return type of the analysis, either \"fft\", or \"waveform\".\n\t\t * @param {Number=} size The size of the FFT. Value must be a power of\n\t\t * two in the range 32 to 32768.\n\t\t */\n\t Tone.Analyser = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'type',\n\t 'size'\n\t ], Tone.Analyser);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The analyser node.\n\t\t\t * @private\n\t\t\t * @type {AnalyserNode}\n\t\t\t */\n\t this._analyser = this.input = this.output = this.context.createAnalyser();\n\t /**\n\t\t\t * The analysis type\n\t\t\t * @type {String}\n\t\t\t * @private\n\t\t\t */\n\t this._type = options.type;\n\t /**\n\t\t\t * The buffer that the FFT data is written to\n\t\t\t * @type {TypedArray}\n\t\t\t * @private\n\t\t\t */\n\t this._buffer = null;\n\t //set the values initially\n\t this.size = options.size;\n\t this.type = options.type;\n\t };\n\t Tone.extend(Tone.Analyser, Tone.AudioNode);\n\t /**\n\t\t * The default values.\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Analyser.defaults = {\n\t 'size': 1024,\n\t 'type': 'fft',\n\t 'smoothing': 0.8\n\t };\n\t /**\n\t\t * Possible return types of analyser.getValue()\n\t\t * @enum {String}\n\t\t */\n\t Tone.Analyser.Type = {\n\t Waveform: 'waveform',\n\t FFT: 'fft'\n\t };\n\t /**\n\t\t * Run the analysis given the current settings and return the\n\t\t * result as a TypedArray.\n\t\t * @returns {TypedArray}\n\t\t */\n\t Tone.Analyser.prototype.getValue = function () {\n\t if (this._type === Tone.Analyser.Type.FFT) {\n\t this._analyser.getFloatFrequencyData(this._buffer);\n\t } else if (this._type === Tone.Analyser.Type.Waveform) {\n\t this._analyser.getFloatTimeDomainData(this._buffer);\n\t }\n\t return this._buffer;\n\t };\n\t /**\n\t\t * The size of analysis. This must be a power of two in the range 32 to 32768.\n\t\t * @memberOf Tone.Analyser#\n\t\t * @type {Number}\n\t\t * @name size\n\t\t */\n\t Object.defineProperty(Tone.Analyser.prototype, 'size', {\n\t get: function () {\n\t return this._analyser.frequencyBinCount;\n\t },\n\t set: function (size) {\n\t this._analyser.fftSize = size * 2;\n\t this._buffer = new Float32Array(size);\n\t }\n\t });\n\t /**\n\t\t * The analysis function returned by analyser.getValue(), either \"fft\" or \"waveform\".\n\t\t * @memberOf Tone.Analyser#\n\t\t * @type {String}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.Analyser.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t if (type !== Tone.Analyser.Type.Waveform && type !== Tone.Analyser.Type.FFT) {\n\t throw new TypeError('Tone.Analyser: invalid type: ' + type);\n\t }\n\t this._type = type;\n\t }\n\t });\n\t /**\n\t\t * 0 represents no time averaging with the last analysis frame.\n\t\t * @memberOf Tone.Analyser#\n\t\t * @type {NormalRange}\n\t\t * @name smoothing\n\t\t */\n\t Object.defineProperty(Tone.Analyser.prototype, 'smoothing', {\n\t get: function () {\n\t return this._analyser.smoothingTimeConstant;\n\t },\n\t set: function (val) {\n\t this._analyser.smoothingTimeConstant = val;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Analyser} this\n\t\t */\n\t Tone.Analyser.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._analyser.disconnect();\n\t this._analyser = null;\n\t this._buffer = null;\n\t };\n\t return Tone.Analyser;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Compressor is a thin wrapper around the Web Audio\n\t\t * [DynamicsCompressorNode](http://webaudio.github.io/web-audio-api/#the-dynamicscompressornode-interface).\n\t\t * Compression reduces the volume of loud sounds or amplifies quiet sounds\n\t\t * by narrowing or \"compressing\" an audio signal's dynamic range.\n\t\t * Read more on [Wikipedia](https://en.wikipedia.org/wiki/Dynamic_range_compression).\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {Decibels|Object} [threshold] The value above which the compression starts to be applied.\n\t\t * @param {Positive} [ratio] The gain reduction ratio.\n\t\t * @example\n\t\t * var comp = new Tone.Compressor(-30, 3);\n\t\t */\n\t Tone.Compressor = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'threshold',\n\t 'ratio'\n\t ], Tone.Compressor);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * the compressor node\n\t\t\t * @type {DynamicsCompressorNode}\n\t\t\t * @private\n\t\t\t */\n\t this._compressor = this.input = this.output = this.context.createDynamicsCompressor();\n\t /**\n\t\t\t * the threshold vaue\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.threshold = new Tone.Param({\n\t 'param': this._compressor.threshold,\n\t 'units': Tone.Type.Decibels,\n\t 'convert': false\n\t });\n\t /**\n\t\t\t * The attack parameter\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.attack = new Tone.Param(this._compressor.attack, Tone.Type.Time);\n\t /**\n\t\t\t * The release parameter\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.release = new Tone.Param(this._compressor.release, Tone.Type.Time);\n\t /**\n\t\t\t * The knee parameter\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.knee = new Tone.Param({\n\t 'param': this._compressor.knee,\n\t 'units': Tone.Type.Decibels,\n\t 'convert': false\n\t });\n\t /**\n\t\t\t * The ratio value\n\t\t\t * @type {Number}\n\t\t\t * @signal\n\t\t\t */\n\t this.ratio = new Tone.Param({\n\t 'param': this._compressor.ratio,\n\t 'convert': false\n\t });\n\t //set the defaults\n\t this._readOnly([\n\t 'knee',\n\t 'release',\n\t 'attack',\n\t 'ratio',\n\t 'threshold'\n\t ]);\n\t this.set(options);\n\t };\n\t Tone.extend(Tone.Compressor, Tone.AudioNode);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Compressor.defaults = {\n\t 'ratio': 12,\n\t 'threshold': -24,\n\t 'release': 0.25,\n\t 'attack': 0.003,\n\t 'knee': 30\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Compressor} this\n\t\t */\n\t Tone.Compressor.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'knee',\n\t 'release',\n\t 'attack',\n\t 'ratio',\n\t 'threshold'\n\t ]);\n\t this._compressor.disconnect();\n\t this._compressor = null;\n\t this.attack.dispose();\n\t this.attack = null;\n\t this.release.dispose();\n\t this.release = null;\n\t this.threshold.dispose();\n\t this.threshold = null;\n\t this.ratio.dispose();\n\t this.ratio = null;\n\t this.knee.dispose();\n\t this.knee = null;\n\t return this;\n\t };\n\t return Tone.Compressor;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Add a signal and a number or two signals. When no value is\n\t\t * passed into the constructor, Tone.Add will sum <code>input[0]</code>\n\t\t * and <code>input[1]</code>. If a value is passed into the constructor, \n\t\t * the it will be added to the input.\n\t\t * \n\t\t * @constructor\n\t\t * @extends {Tone.Signal}\n\t\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t\t * and second inputs. \n\t\t * @example\n\t\t * var signal = new Tone.Signal(2);\n\t\t * var add = new Tone.Add(2);\n\t\t * signal.connect(add);\n\t\t * //the output of add equals 4\n\t\t * @example\n\t\t * //if constructed with no arguments\n\t\t * //it will add the first and second inputs\n\t\t * var add = new Tone.Add();\n\t\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t\t * //the output of add equals 7. \n\t\t */\n\t Tone.Add = function (value) {\n\t Tone.Signal.call(this);\n\t this.createInsOuts(2, 0);\n\t /**\n\t\t\t * the summing node\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\t /**\n\t\t\t * @private\n\t\t\t * @type {Tone.Signal}\n\t\t\t */\n\t this._param = this.input[1] = new Tone.Signal(value);\n\t this._param.connect(this._sum);\n\t };\n\t Tone.extend(Tone.Add, Tone.Signal);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Add} this\n\t\t */\n\t Tone.Add.prototype.dispose = function () {\n\t Tone.Signal.prototype.dispose.call(this);\n\t this._sum.dispose();\n\t this._sum = null;\n\t return this;\n\t };\n\t return Tone.Add;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Multiply two incoming signals. Or, if a number is given in the constructor,\n\t\t * multiplies the incoming signal by that value.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Signal}\n\t\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t\t * it will return the product of the first and second inputs\n\t\t * @example\n\t\t * var mult = new Tone.Multiply();\n\t\t * var sigA = new Tone.Signal(3);\n\t\t * var sigB = new Tone.Signal(4);\n\t\t * sigA.connect(mult, 0, 0);\n\t\t * sigB.connect(mult, 0, 1);\n\t\t * //output of mult is 12.\n\t\t * @example\n\t\t * var mult = new Tone.Multiply(10);\n\t\t * var sig = new Tone.Signal(2).connect(mult);\n\t\t * //the output of mult is 20.\n\t\t */\n\t Tone.Multiply = function (value) {\n\t Tone.Signal.call(this);\n\t this.createInsOuts(2, 0);\n\t /**\n\t\t\t * the input node is the same as the output node\n\t\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t\t *\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this._mult = this.input[0] = this.output = new Tone.Gain();\n\t /**\n\t\t\t * the scaling parameter\n\t\t\t * @type {AudioParam}\n\t\t\t * @private\n\t\t\t */\n\t this._param = this.input[1] = this.output.gain;\n\t this.value = Tone.defaultArg(value, 0);\n\t };\n\t Tone.extend(Tone.Multiply, Tone.Signal);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Multiply} this\n\t\t */\n\t Tone.Multiply.prototype.dispose = function () {\n\t Tone.Signal.prototype.dispose.call(this);\n\t this._mult.dispose();\n\t this._mult = null;\n\t this._param = null;\n\t return this;\n\t };\n\t return Tone.Multiply;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.SignalBase}\n\t\t * @example\n\t\t * var neg = new Tone.Negate();\n\t\t * var sig = new Tone.Signal(-2).connect(neg);\n\t\t * //output of neg is positive 2. \n\t\t */\n\t Tone.Negate = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * negation is done by multiplying by -1\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t };\n\t Tone.extend(Tone.Negate, Tone.SignalBase);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Negate} this\n\t\t */\n\t Tone.Negate.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._multiply.dispose();\n\t this._multiply = null;\n\t return this;\n\t };\n\t return Tone.Negate;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Subtract the signal connected to <code>input[1]</code> from the signal connected \n\t\t * to <code>input[0]</code>. If an argument is provided in the constructor, the \n\t\t * signals <code>.value</code> will be subtracted from the incoming signal.\n\t\t *\n\t\t * @extends {Tone.Signal}\n\t\t * @constructor\n\t\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t\t * is omitted, it will subtract the second signal from the first.\n\t\t * @example\n\t\t * var sub = new Tone.Subtract(1);\n\t\t * var sig = new Tone.Signal(4).connect(sub);\n\t\t * //the output of sub is 3. \n\t\t * @example\n\t\t * var sub = new Tone.Subtract();\n\t\t * var sigA = new Tone.Signal(10);\n\t\t * var sigB = new Tone.Signal(2.5);\n\t\t * sigA.connect(sub, 0, 0);\n\t\t * sigB.connect(sub, 0, 1);\n\t\t * //output of sub is 7.5\n\t\t */\n\t Tone.Subtract = function (value) {\n\t Tone.Signal.call(this);\n\t this.createInsOuts(2, 0);\n\t /**\n\t\t\t * the summing node\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this._sum = this.input[0] = this.output = new Tone.Gain();\n\t /**\n\t\t\t * negate the input of the second input before connecting it\n\t\t\t * to the summing node.\n\t\t\t * @type {Tone.Negate}\n\t\t\t * @private\n\t\t\t */\n\t this._neg = new Tone.Negate();\n\t /**\n\t\t\t * the node where the value is set\n\t\t\t * @private\n\t\t\t * @type {Tone.Signal}\n\t\t\t */\n\t this._param = this.input[1] = new Tone.Signal(value);\n\t this._param.chain(this._neg, this._sum);\n\t };\n\t Tone.extend(Tone.Subtract, Tone.Signal);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.SignalBase} this\n\t\t */\n\t Tone.Subtract.prototype.dispose = function () {\n\t Tone.Signal.prototype.dispose.call(this);\n\t this._neg.dispose();\n\t this._neg = null;\n\t this._sum.disconnect();\n\t this._sum = null;\n\t return this;\n\t };\n\t return Tone.Subtract;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t\t *\n\t\t * @extends {Tone.SignalBase}\n\t\t * @constructor\n\t\t * @example\n\t\t * var eqPowGain = new Tone.EqualPowerGain();\n\t\t */\n\t Tone.EqualPowerGain = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * @type {Tone.WaveShaper}\n\t\t\t * @private\n\t\t\t */\n\t this._eqPower = this.input = this.output = new Tone.WaveShaper(function (val) {\n\t if (Math.abs(val) < 0.001) {\n\t //should output 0 when input is 0\n\t return 0;\n\t } else {\n\t return Tone.equalPowerScale(val);\n\t }\n\t }.bind(this), 4096);\n\t };\n\t Tone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.EqualPowerGain} this\n\t\t */\n\t Tone.EqualPowerGain.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._eqPower.dispose();\n\t this._eqPower = null;\n\t return this;\n\t };\n\t return Tone.EqualPowerGain;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Crossfade provides equal power fading between two inputs.\n\t\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {NormalRange} [initialFade=0.5]\n\t\t * @example\n\t\t * var crossFade = new Tone.CrossFade(0.5);\n\t\t * //connect effect A to crossfade from\n\t\t * //effect output 0 to crossfade input 0\n\t\t * effectA.connect(crossFade, 0, 0);\n\t\t * //connect effect B to crossfade from\n\t\t * //effect output 0 to crossfade input 1\n\t\t * effectB.connect(crossFade, 0, 1);\n\t\t * crossFade.fade.value = 0;\n\t\t * // ^ only effectA is output\n\t\t * crossFade.fade.value = 1;\n\t\t * // ^ only effectB is output\n\t\t * crossFade.fade.value = 0.5;\n\t\t * // ^ the two signals are mixed equally.\n\t\t */\n\t Tone.CrossFade = function (initialFade) {\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(2, 1);\n\t /**\n\t\t\t * Alias for <code>input[0]</code>.\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.a = this.input[0] = new Tone.Gain();\n\t /**\n\t\t\t * Alias for <code>input[1]</code>.\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.b = this.input[1] = new Tone.Gain();\n\t /**\n\t\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t\t * \twill output 100% <code>input[0]</code> and\n\t\t\t * \ta value of 1 will output 100% <code>input[1]</code>.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.fade = new Tone.Signal(Tone.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\t /**\n\t\t\t * equal power gain cross fade\n\t\t\t * @private\n\t\t\t * @type {Tone.EqualPowerGain}\n\t\t\t */\n\t this._equalPowerA = new Tone.EqualPowerGain();\n\t /**\n\t\t\t * equal power gain cross fade\n\t\t\t * @private\n\t\t\t * @type {Tone.EqualPowerGain}\n\t\t\t */\n\t this._equalPowerB = new Tone.EqualPowerGain();\n\t /**\n\t\t\t * invert the incoming signal\n\t\t\t * @private\n\t\t\t * @type {Tone}\n\t\t\t */\n\t this._one = this.context.getConstant(1);\n\t /**\n\t\t\t * invert the incoming signal\n\t\t\t * @private\n\t\t\t * @type {Tone.Subtract}\n\t\t\t */\n\t this._invert = new Tone.Subtract();\n\t //connections\n\t this.a.connect(this.output);\n\t this.b.connect(this.output);\n\t this.fade.chain(this._equalPowerB, this.b.gain);\n\t this._one.connect(this._invert, 0, 0);\n\t this.fade.connect(this._invert, 0, 1);\n\t this._invert.chain(this._equalPowerA, this.a.gain);\n\t this._readOnly('fade');\n\t };\n\t Tone.extend(Tone.CrossFade, Tone.AudioNode);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.CrossFade} this\n\t\t */\n\t Tone.CrossFade.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable('fade');\n\t this._equalPowerA.dispose();\n\t this._equalPowerA = null;\n\t this._equalPowerB.dispose();\n\t this._equalPowerB = null;\n\t this.fade.dispose();\n\t this.fade = null;\n\t this._invert.dispose();\n\t this._invert = null;\n\t this._one = null;\n\t this.a.dispose();\n\t this.a = null;\n\t this.b.dispose();\n\t this.b = null;\n\t return this;\n\t };\n\t return Tone.CrossFade;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Filter is a filter which allows for all of the same native methods\n\t\t * as the [BiquadFilterNode](http://webaudio.github.io/web-audio-api/#the-biquadfilternode-interface).\n\t\t * Tone.Filter has the added ability to set the filter rolloff at -12\n\t\t * (default), -24 and -48.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Frequency|Object} [frequency] The cutoff frequency of the filter.\n\t\t * @param {string=} type The type of filter.\n\t\t * @param {number=} rolloff The drop in decibels per octave after the cutoff frequency.\n\t\t * 3 choices: -12, -24, and -48\n\t\t * @example\n\t\t * var filter = new Tone.Filter(200, \"highpass\");\n\t\t */\n\t Tone.Filter = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type',\n\t 'rolloff'\n\t ], Tone.Filter);\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(1, 1);\n\t /**\n\t\t\t * the filter(s)\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._filters = [];\n\t /**\n\t\t\t * The cutoff frequency of the filter.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune parameter\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(0, Tone.Type.Cents);\n\t /**\n\t\t\t * The gain of the filter, only used in certain filter types\n\t\t\t * @type {Number}\n\t\t\t * @signal\n\t\t\t */\n\t this.gain = new Tone.Signal({\n\t 'value': options.gain,\n\t 'convert': false\n\t });\n\t /**\n\t\t\t * The Q or Quality of the filter\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this.Q = new Tone.Signal(options.Q);\n\t /**\n\t\t\t * the type of the filter\n\t\t\t * @type {string}\n\t\t\t * @private\n\t\t\t */\n\t this._type = options.type;\n\t /**\n\t\t\t * the rolloff value of the filter\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._rolloff = options.rolloff;\n\t //set the rolloff;\n\t this.rolloff = options.rolloff;\n\t this._readOnly([\n\t 'detune',\n\t 'frequency',\n\t 'gain',\n\t 'Q'\n\t ]);\n\t };\n\t Tone.extend(Tone.Filter, Tone.AudioNode);\n\t /**\n\t\t * the default parameters\n\t\t *\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Filter.defaults = {\n\t 'type': 'lowpass',\n\t 'frequency': 350,\n\t 'rolloff': -12,\n\t 'Q': 1,\n\t 'gain': 0\n\t };\n\t /**\n\t\t * The type of the filter. Types: \"lowpass\", \"highpass\",\n\t\t * \"bandpass\", \"lowshelf\", \"highshelf\", \"notch\", \"allpass\", or \"peaking\".\n\t\t * @memberOf Tone.Filter#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.Filter.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t var types = [\n\t 'lowpass',\n\t 'highpass',\n\t 'bandpass',\n\t 'lowshelf',\n\t 'highshelf',\n\t 'notch',\n\t 'allpass',\n\t 'peaking'\n\t ];\n\t if (types.indexOf(type) === -1) {\n\t throw new TypeError('Tone.Filter: invalid type ' + type);\n\t }\n\t this._type = type;\n\t for (var i = 0; i < this._filters.length; i++) {\n\t this._filters[i].type = type;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The rolloff of the filter which is the drop in db\n\t\t * per octave. Implemented internally by cascading filters.\n\t\t * Only accepts the values -12, -24, -48 and -96.\n\t\t * @memberOf Tone.Filter#\n\t\t * @type {number}\n\t\t * @name rolloff\n\t\t */\n\t Object.defineProperty(Tone.Filter.prototype, 'rolloff', {\n\t get: function () {\n\t return this._rolloff;\n\t },\n\t set: function (rolloff) {\n\t rolloff = parseInt(rolloff, 10);\n\t var possibilities = [\n\t -12,\n\t -24,\n\t -48,\n\t -96\n\t ];\n\t var cascadingCount = possibilities.indexOf(rolloff);\n\t //check the rolloff is valid\n\t if (cascadingCount === -1) {\n\t throw new RangeError('Tone.Filter: rolloff can only be -12, -24, -48 or -96');\n\t }\n\t cascadingCount += 1;\n\t this._rolloff = rolloff;\n\t //first disconnect the filters and throw them away\n\t this.input.disconnect();\n\t for (var i = 0; i < this._filters.length; i++) {\n\t this._filters[i].disconnect();\n\t this._filters[i] = null;\n\t }\n\t this._filters = new Array(cascadingCount);\n\t for (var count = 0; count < cascadingCount; count++) {\n\t var filter = this.context.createBiquadFilter();\n\t filter.type = this._type;\n\t this.frequency.connect(filter.frequency);\n\t this.detune.connect(filter.detune);\n\t this.Q.connect(filter.Q);\n\t this.gain.connect(filter.gain);\n\t this._filters[count] = filter;\n\t }\n\t //connect them up\n\t var connectionChain = [this.input].concat(this._filters).concat([this.output]);\n\t Tone.connectSeries.apply(Tone, connectionChain);\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Filter} this\n\t\t */\n\t Tone.Filter.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t for (var i = 0; i < this._filters.length; i++) {\n\t this._filters[i].disconnect();\n\t this._filters[i] = null;\n\t }\n\t this._filters = null;\n\t this._writable([\n\t 'detune',\n\t 'frequency',\n\t 'gain',\n\t 'Q'\n\t ]);\n\t this.frequency.dispose();\n\t this.Q.dispose();\n\t this.frequency = null;\n\t this.Q = null;\n\t this.detune.dispose();\n\t this.detune = null;\n\t this.gain.dispose();\n\t this.gain = null;\n\t return this;\n\t };\n\t return Tone.Filter;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Split the incoming signal into three bands (low, mid, high)\n\t\t * with two crossover frequency controls.\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {Frequency|Object} [lowFrequency] the low/mid crossover frequency\n\t\t * @param {Frequency} [highFrequency] the mid/high crossover frequency\n\t\t */\n\t Tone.MultibandSplit = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'lowFrequency',\n\t 'highFrequency'\n\t ], Tone.MultibandSplit);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * the input\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this.input = new Tone.Gain();\n\t /**\n\t\t\t * the outputs\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this.output = new Array(3);\n\t /**\n\t\t\t * The low band. Alias for <code>output[0]</code>\n\t\t\t * @type {Tone.Filter}\n\t\t\t */\n\t this.low = this.output[0] = new Tone.Filter(0, 'lowpass');\n\t /**\n\t\t\t * the lower filter of the mid band\n\t\t\t * @type {Tone.Filter}\n\t\t\t * @private\n\t\t\t */\n\t this._lowMidFilter = new Tone.Filter(0, 'highpass');\n\t /**\n\t\t\t * The mid band output. Alias for <code>output[1]</code>\n\t\t\t * @type {Tone.Filter}\n\t\t\t */\n\t this.mid = this.output[1] = new Tone.Filter(0, 'lowpass');\n\t /**\n\t\t\t * The high band output. Alias for <code>output[2]</code>\n\t\t\t * @type {Tone.Filter}\n\t\t\t */\n\t this.high = this.output[2] = new Tone.Filter(0, 'highpass');\n\t /**\n\t\t\t * The low/mid crossover frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.lowFrequency = new Tone.Signal(options.lowFrequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The mid/high crossover frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.highFrequency = new Tone.Signal(options.highFrequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The quality of all the filters\n\t\t\t * @type {Number}\n\t\t\t * @signal\n\t\t\t */\n\t this.Q = new Tone.Signal(options.Q);\n\t this.input.fan(this.low, this.high);\n\t this.input.chain(this._lowMidFilter, this.mid);\n\t //the frequency control signal\n\t this.lowFrequency.connect(this.low.frequency);\n\t this.lowFrequency.connect(this._lowMidFilter.frequency);\n\t this.highFrequency.connect(this.mid.frequency);\n\t this.highFrequency.connect(this.high.frequency);\n\t //the Q value\n\t this.Q.connect(this.low.Q);\n\t this.Q.connect(this._lowMidFilter.Q);\n\t this.Q.connect(this.mid.Q);\n\t this.Q.connect(this.high.Q);\n\t this._readOnly([\n\t 'high',\n\t 'mid',\n\t 'low',\n\t 'highFrequency',\n\t 'lowFrequency'\n\t ]);\n\t };\n\t Tone.extend(Tone.MultibandSplit, Tone.AudioNode);\n\t /**\n\t\t * @private\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.MultibandSplit.defaults = {\n\t 'lowFrequency': 400,\n\t 'highFrequency': 2500,\n\t 'Q': 1\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.MultibandSplit} this\n\t\t */\n\t Tone.MultibandSplit.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'high',\n\t 'mid',\n\t 'low',\n\t 'highFrequency',\n\t 'lowFrequency'\n\t ]);\n\t this.low.dispose();\n\t this.low = null;\n\t this._lowMidFilter.dispose();\n\t this._lowMidFilter = null;\n\t this.mid.dispose();\n\t this.mid = null;\n\t this.high.dispose();\n\t this.high = null;\n\t this.lowFrequency.dispose();\n\t this.lowFrequency = null;\n\t this.highFrequency.dispose();\n\t this.highFrequency = null;\n\t this.Q.dispose();\n\t this.Q = null;\n\t return this;\n\t };\n\t return Tone.MultibandSplit;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.EQ3 is a three band EQ with control over low, mid, and high gain as\n\t\t * well as the low and high crossover frequencies.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t *\n\t\t * @param {Decibels|Object} [lowLevel] The gain applied to the lows.\n\t\t * @param {Decibels} [midLevel] The gain applied to the mid.\n\t\t * @param {Decibels} [highLevel] The gain applied to the high.\n\t\t * @example\n\t\t * var eq = new Tone.EQ3(-10, 3, -20);\n\t\t */\n\t Tone.EQ3 = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'low',\n\t 'mid',\n\t 'high'\n\t ], Tone.EQ3);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * the output node\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.output = new Tone.Gain();\n\t /**\n\t\t\t * the multiband split\n\t\t\t * @type {Tone.MultibandSplit}\n\t\t\t * @private\n\t\t\t */\n\t this._multibandSplit = this.input = new Tone.MultibandSplit({\n\t 'lowFrequency': options.lowFrequency,\n\t 'highFrequency': options.highFrequency\n\t });\n\t /**\n\t\t\t * The gain for the lower signals\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._lowGain = new Tone.Gain(options.low, Tone.Type.Decibels);\n\t /**\n\t\t\t * The gain for the mid signals\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._midGain = new Tone.Gain(options.mid, Tone.Type.Decibels);\n\t /**\n\t\t\t * The gain in decibels of the high part\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._highGain = new Tone.Gain(options.high, Tone.Type.Decibels);\n\t /**\n\t\t\t * The gain in decibels of the low part\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.low = this._lowGain.gain;\n\t /**\n\t\t\t * The gain in decibels of the mid part\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.mid = this._midGain.gain;\n\t /**\n\t\t\t * The gain in decibels of the high part\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.high = this._highGain.gain;\n\t /**\n\t\t\t * The Q value for all of the filters.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this.Q = this._multibandSplit.Q;\n\t /**\n\t\t\t * The low/mid crossover frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.lowFrequency = this._multibandSplit.lowFrequency;\n\t /**\n\t\t\t * The mid/high crossover frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.highFrequency = this._multibandSplit.highFrequency;\n\t //the frequency bands\n\t this._multibandSplit.low.chain(this._lowGain, this.output);\n\t this._multibandSplit.mid.chain(this._midGain, this.output);\n\t this._multibandSplit.high.chain(this._highGain, this.output);\n\t this._readOnly([\n\t 'low',\n\t 'mid',\n\t 'high',\n\t 'lowFrequency',\n\t 'highFrequency'\n\t ]);\n\t };\n\t Tone.extend(Tone.EQ3, Tone.AudioNode);\n\t /**\n\t\t * the default values\n\t\t */\n\t Tone.EQ3.defaults = {\n\t 'low': 0,\n\t 'mid': 0,\n\t 'high': 0,\n\t 'lowFrequency': 400,\n\t 'highFrequency': 2500\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.EQ3} this\n\t\t */\n\t Tone.EQ3.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'low',\n\t 'mid',\n\t 'high',\n\t 'lowFrequency',\n\t 'highFrequency'\n\t ]);\n\t this._multibandSplit.dispose();\n\t this._multibandSplit = null;\n\t this.lowFrequency = null;\n\t this.highFrequency = null;\n\t this._lowGain.dispose();\n\t this._lowGain = null;\n\t this._midGain.dispose();\n\t this._midGain = null;\n\t this._highGain.dispose();\n\t this._highGain = null;\n\t this.low = null;\n\t this.mid = null;\n\t this.high = null;\n\t this.Q = null;\n\t return this;\n\t };\n\t return Tone.EQ3;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Performs a linear scaling on an input signal.\n\t\t * Scales a NormalRange input to between\n\t\t * outputMin and outputMax.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.SignalBase}\n\t\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t\t * @example\n\t\t * var scale = new Tone.Scale(50, 100);\n\t\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t\t * //the output of scale equals 75\n\t\t */\n\t Tone.Scale = function (outputMin, outputMax) {\n\t Tone.SignalBase.call(this);\n\t /** \n\t\t\t * @private\n\t\t\t * @type {number}\n\t\t\t */\n\t this._outputMin = Tone.defaultArg(outputMin, 0);\n\t /** \n\t\t\t * @private\n\t\t\t * @type {number}\n\t\t\t */\n\t this._outputMax = Tone.defaultArg(outputMax, 1);\n\t /** \n\t\t\t * @private\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._scale = this.input = new Tone.Multiply(1);\n\t /** \n\t\t\t * @private\n\t\t\t * @type {Tone.Add}\n\t\t\t * @private\n\t\t\t */\n\t this._add = this.output = new Tone.Add(0);\n\t this._scale.connect(this._add);\n\t this._setRange();\n\t };\n\t Tone.extend(Tone.Scale, Tone.SignalBase);\n\t /**\n\t\t * The minimum output value. This number is output when \n\t\t * the value input value is 0. \n\t\t * @memberOf Tone.Scale#\n\t\t * @type {number}\n\t\t * @name min\n\t\t */\n\t Object.defineProperty(Tone.Scale.prototype, 'min', {\n\t get: function () {\n\t return this._outputMin;\n\t },\n\t set: function (min) {\n\t this._outputMin = min;\n\t this._setRange();\n\t }\n\t });\n\t /**\n\t\t * The maximum output value. This number is output when \n\t\t * the value input value is 1. \n\t\t * @memberOf Tone.Scale#\n\t\t * @type {number}\n\t\t * @name max\n\t\t */\n\t Object.defineProperty(Tone.Scale.prototype, 'max', {\n\t get: function () {\n\t return this._outputMax;\n\t },\n\t set: function (max) {\n\t this._outputMax = max;\n\t this._setRange();\n\t }\n\t });\n\t /**\n\t\t * set the values\n\t\t * @private\n\t\t */\n\t Tone.Scale.prototype._setRange = function () {\n\t this._add.value = this._outputMin;\n\t this._scale.value = this._outputMax - this._outputMin;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Scale} this\n\t\t */\n\t Tone.Scale.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._add.dispose();\n\t this._add = null;\n\t this._scale.dispose();\n\t this._scale = null;\n\t return this;\n\t };\n\t return Tone.Scale;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Performs an exponential scaling on an input signal.\n\t\t * Scales a NormalRange value [0,1] exponentially\n\t\t * to the output range of outputMin to outputMax.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.SignalBase}\n\t\t * @param {number} [outputMin=0] The output value when the input is 0.\n\t\t * @param {number} [outputMax=1]\tThe output value when the input is 1.\n\t\t * @param {number} [exponent=2] The exponent which scales the incoming signal.\n\t\t * @example\n\t\t * var scaleExp = new Tone.ScaleExp(0, 100, 2);\n\t\t * var signal = new Tone.Signal(0.5).connect(scaleExp);\n\t\t */\n\t Tone.ScaleExp = function (outputMin, outputMax, exponent) {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * scale the input to the output range\n\t\t\t * @type {Tone.Scale}\n\t\t\t * @private\n\t\t\t */\n\t this._scale = this.output = new Tone.Scale(outputMin, outputMax);\n\t /**\n\t\t\t * @private\n\t\t\t * @type {Tone.Pow}\n\t\t\t * @private\n\t\t\t */\n\t this._exp = this.input = new Tone.Pow(Tone.defaultArg(exponent, 2));\n\t this._exp.connect(this._scale);\n\t };\n\t Tone.extend(Tone.ScaleExp, Tone.SignalBase);\n\t /**\n\t\t * Instead of interpolating linearly between the <code>min</code> and\n\t\t * <code>max</code> values, setting the exponent will interpolate between\n\t\t * the two values with an exponential curve.\n\t\t * @memberOf Tone.ScaleExp#\n\t\t * @type {number}\n\t\t * @name exponent\n\t\t */\n\t Object.defineProperty(Tone.ScaleExp.prototype, 'exponent', {\n\t get: function () {\n\t return this._exp.value;\n\t },\n\t set: function (exp) {\n\t this._exp.value = exp;\n\t }\n\t });\n\t /**\n\t\t * The minimum output value. This number is output when\n\t\t * the value input value is 0.\n\t\t * @memberOf Tone.ScaleExp#\n\t\t * @type {number}\n\t\t * @name min\n\t\t */\n\t Object.defineProperty(Tone.ScaleExp.prototype, 'min', {\n\t get: function () {\n\t return this._scale.min;\n\t },\n\t set: function (min) {\n\t this._scale.min = min;\n\t }\n\t });\n\t /**\n\t\t * The maximum output value. This number is output when\n\t\t * the value input value is 1.\n\t\t * @memberOf Tone.ScaleExp#\n\t\t * @type {number}\n\t\t * @name max\n\t\t */\n\t Object.defineProperty(Tone.ScaleExp.prototype, 'max', {\n\t get: function () {\n\t return this._scale.max;\n\t },\n\t set: function (max) {\n\t this._scale.max = max;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.ScaleExp} this\n\t\t */\n\t Tone.ScaleExp.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._scale.dispose();\n\t this._scale = null;\n\t this._exp.dispose();\n\t this._exp = null;\n\t return this;\n\t };\n\t return Tone.ScaleExp;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Wrapper around Web Audio's native [DelayNode](http://webaudio.github.io/web-audio-api/#the-delaynode-interface).\n\t\t * @extends {Tone}\n\t\t * @param {Time=} delayTime The delay applied to the incoming signal.\n\t\t * @param {Time=} maxDelay The maximum delay time.\n\t\t */\n\t Tone.Delay = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'delayTime',\n\t 'maxDelay'\n\t ], Tone.Delay);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The maximum delay time initialized with the node\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._maxDelay = Math.max(this.toSeconds(options.maxDelay), this.toSeconds(options.delayTime));\n\t /**\n\t\t\t * The native delay node\n\t\t\t * @type {DelayNode}\n\t\t\t * @private\n\t\t\t */\n\t this._delayNode = this.input = this.output = this.context.createDelay(this._maxDelay);\n\t /**\n\t\t\t * The amount of time the incoming signal is\n\t\t\t * delayed.\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.delayTime = new Tone.Param({\n\t 'param': this._delayNode.delayTime,\n\t 'units': Tone.Type.Time,\n\t 'value': options.delayTime\n\t });\n\t this._readOnly('delayTime');\n\t };\n\t Tone.extend(Tone.Delay, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Delay.defaults = {\n\t 'maxDelay': 1,\n\t 'delayTime': 0\n\t };\n\t /**\n\t\t * The maximum delay time. This cannot be changed. The value is passed into the constructor.\n\t\t * @memberof Tone.Delay#\n\t\t * @type {Time}\n\t\t * @name maxDelay\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Delay.prototype, 'maxDelay', {\n\t get: function () {\n\t return this._maxDelay;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Delay} this\n\t\t */\n\t Tone.Delay.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._delayNode.disconnect();\n\t this._delayNode = null;\n\t this._writable('delayTime');\n\t this.delayTime = null;\n\t return this;\n\t };\n\t return Tone.Delay;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Comb filters are basic building blocks for physical modeling. Read more\n\t\t * about comb filters on [CCRMA's website](https://ccrma.stanford.edu/~jos/pasp/Feedback_Comb_Filters.html).\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {Time|Object} [delayTime] The delay time of the filter.\n\t\t * @param {NormalRange=} resonance The amount of feedback the filter has.\n\t\t */\n\t Tone.FeedbackCombFilter = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'delayTime',\n\t 'resonance'\n\t ], Tone.FeedbackCombFilter);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * the delay node\n\t\t\t * @type {DelayNode}\n\t\t\t * @private\n\t\t\t */\n\t this._delay = this.input = this.output = new Tone.Delay(options.delayTime);\n\t /**\n\t\t\t * The amount of delay of the comb filter.\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.delayTime = this._delay.delayTime;\n\t /**\n\t\t\t * the feedback node\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this._feedback = new Tone.Gain(options.resonance, Tone.Type.NormalRange);\n\t /**\n\t\t\t * The amount of feedback of the delayed signal.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.resonance = this._feedback.gain;\n\t this._delay.chain(this._feedback, this._delay);\n\t this._readOnly([\n\t 'resonance',\n\t 'delayTime'\n\t ]);\n\t };\n\t Tone.extend(Tone.FeedbackCombFilter, Tone.AudioNode);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.FeedbackCombFilter.defaults = {\n\t 'delayTime': 0.1,\n\t 'resonance': 0.5\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.FeedbackCombFilter} this\n\t\t */\n\t Tone.FeedbackCombFilter.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'resonance',\n\t 'delayTime'\n\t ]);\n\t this._delay.dispose();\n\t this._delay = null;\n\t this.delayTime = null;\n\t this._feedback.dispose();\n\t this._feedback = null;\n\t this.resonance = null;\n\t return this;\n\t };\n\t return Tone.FeedbackCombFilter;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Get the current waveform data of the connected audio source.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Number=} size The size of the FFT. Value must be a power of\n\t\t * two in the range 32 to 32768.\n\t\t */\n\t Tone.FFT = function () {\n\t var options = Tone.defaults(arguments, ['size'], Tone.FFT);\n\t options.type = Tone.Analyser.Type.FFT;\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The analyser node.\n\t\t\t * @private\n\t\t\t * @type {Tone.Analyser}\n\t\t\t */\n\t this._analyser = this.input = this.output = new Tone.Analyser(options);\n\t };\n\t Tone.extend(Tone.FFT, Tone.AudioNode);\n\t /**\n\t\t * The default values.\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.FFT.defaults = { 'size': 1024 };\n\t /**\n\t\t * Gets the waveform of the audio source. Returns the waveform data\n\t\t * of length [size](#size) as a Float32Array with values between -1 and 1.\n\t\t * @returns {TypedArray}\n\t\t */\n\t Tone.FFT.prototype.getValue = function () {\n\t return this._analyser.getValue();\n\t };\n\t /**\n\t\t * The size of analysis. This must be a power of two in the range 32 to 32768.\n\t\t * @memberOf Tone.FFT#\n\t\t * @type {Number}\n\t\t * @name size\n\t\t */\n\t Object.defineProperty(Tone.FFT.prototype, 'size', {\n\t get: function () {\n\t return this._analyser.size;\n\t },\n\t set: function (size) {\n\t this._analyser.size = size;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.FFT} this\n\t\t */\n\t Tone.FFT.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._analyser.dispose();\n\t this._analyser = null;\n\t };\n\t return Tone.FFT;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Return the absolute value of an incoming signal.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.SignalBase}\n\t\t * @example\n\t\t * var signal = new Tone.Signal(-1);\n\t\t * var abs = new Tone.Abs();\n\t\t * signal.connect(abs);\n\t\t * //the output of abs is 1.\n\t\t */\n\t Tone.Abs = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * @type {Tone.LessThan}\n\t\t\t * @private\n\t\t\t */\n\t this._abs = this.input = this.output = new Tone.WaveShaper(function (val) {\n\t if (Math.abs(val) < 0.001) {\n\t return 0;\n\t } else {\n\t return Math.abs(val);\n\t }\n\t }, 1024);\n\t };\n\t Tone.extend(Tone.Abs, Tone.SignalBase);\n\t /**\n\t\t * dispose method\n\t\t * @returns {Tone.Abs} this\n\t\t */\n\t Tone.Abs.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._abs.dispose();\n\t this._abs = null;\n\t return this;\n\t };\n\t return Tone.Abs;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Follower is a crude envelope follower which will follow\n\t\t * the amplitude of an incoming signal.\n\t\t * Take care with small (< 0.02) attack or decay values\n\t\t * as follower has some ripple which is exaggerated\n\t\t * at these values. Read more about envelope followers (also known\n\t\t * as envelope detectors) on [Wikipedia](https://en.wikipedia.org/wiki/Envelope_detector).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Time|Object} [attack] The rate at which the follower rises.\n\t\t * @param {Time=} release The rate at which the folower falls.\n\t\t * @example\n\t\t * var follower = new Tone.Follower(0.2, 0.4);\n\t\t */\n\t Tone.Follower = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'attack',\n\t 'release'\n\t ], Tone.Follower);\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(1, 1);\n\t /**\n\t\t\t * @type {Tone.Abs}\n\t\t\t * @private\n\t\t\t */\n\t this._abs = new Tone.Abs();\n\t /**\n\t\t\t * the lowpass filter which smooths the input\n\t\t\t * @type {BiquadFilterNode}\n\t\t\t * @private\n\t\t\t */\n\t this._filter = this.context.createBiquadFilter();\n\t this._filter.type = 'lowpass';\n\t this._filter.frequency.value = 0;\n\t this._filter.Q.value = -100;\n\t /**\n\t\t\t * @type {WaveShaperNode}\n\t\t\t * @private\n\t\t\t */\n\t this._frequencyValues = new Tone.WaveShaper();\n\t /**\n\t\t\t * @type {Tone.Subtract}\n\t\t\t * @private\n\t\t\t */\n\t this._sub = new Tone.Subtract();\n\t /**\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._delay = new Tone.Delay(this.blockTime);\n\t /**\n\t\t\t * this keeps it far from 0, even for very small differences\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._mult = new Tone.Multiply(10000);\n\t /**\n\t\t\t * @private\n\t\t\t * @type {number}\n\t\t\t */\n\t this._attack = options.attack;\n\t /**\n\t\t\t * @private\n\t\t\t * @type {number}\n\t\t\t */\n\t this._release = options.release;\n\t //the smoothed signal to get the values\n\t this.input.chain(this._abs, this._filter, this.output);\n\t //the difference path\n\t this._abs.connect(this._sub, 0, 1);\n\t this._filter.chain(this._delay, this._sub);\n\t //threshold the difference and use the thresh to set the frequency\n\t this._sub.chain(this._mult, this._frequencyValues, this._filter.frequency);\n\t //set the attack and release values in the table\n\t this._setAttackRelease(this._attack, this._release);\n\t };\n\t Tone.extend(Tone.Follower, Tone.AudioNode);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Follower.defaults = {\n\t 'attack': 0.05,\n\t 'release': 0.5\n\t };\n\t /**\n\t\t * sets the attack and release times in the wave shaper\n\t\t * @param {Time} attack\n\t\t * @param {Time} release\n\t\t * @private\n\t\t */\n\t Tone.Follower.prototype._setAttackRelease = function (attack, release) {\n\t var minTime = this.blockTime;\n\t attack = Tone.Time(attack).toFrequency();\n\t release = Tone.Time(release).toFrequency();\n\t attack = Math.max(attack, minTime);\n\t release = Math.max(release, minTime);\n\t this._frequencyValues.setMap(function (val) {\n\t if (val <= 0) {\n\t return attack;\n\t } else {\n\t return release;\n\t }\n\t });\n\t };\n\t /**\n\t\t * The attack time.\n\t\t * @memberOf Tone.Follower#\n\t\t * @type {Time}\n\t\t * @name attack\n\t\t */\n\t Object.defineProperty(Tone.Follower.prototype, 'attack', {\n\t get: function () {\n\t return this._attack;\n\t },\n\t set: function (attack) {\n\t this._attack = attack;\n\t this._setAttackRelease(this._attack, this._release);\n\t }\n\t });\n\t /**\n\t\t * The release time.\n\t\t * @memberOf Tone.Follower#\n\t\t * @type {Time}\n\t\t * @name release\n\t\t */\n\t Object.defineProperty(Tone.Follower.prototype, 'release', {\n\t get: function () {\n\t return this._release;\n\t },\n\t set: function (release) {\n\t this._release = release;\n\t this._setAttackRelease(this._attack, this._release);\n\t }\n\t });\n\t /**\n\t\t * Borrows the connect method from Signal so that the output can be used\n\t\t * as a Tone.Signal control signal.\n\t\t * @function\n\t\t */\n\t Tone.Follower.prototype.connect = Tone.SignalBase.prototype.connect;\n\t /**\n\t\t * dispose\n\t\t * @returns {Tone.Follower} this\n\t\t */\n\t Tone.Follower.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._filter.disconnect();\n\t this._filter = null;\n\t this._frequencyValues.disconnect();\n\t this._frequencyValues = null;\n\t this._delay.dispose();\n\t this._delay = null;\n\t this._sub.disconnect();\n\t this._sub = null;\n\t this._abs.dispose();\n\t this._abs = null;\n\t this._mult.dispose();\n\t this._mult = null;\n\t this._curve = null;\n\t return this;\n\t };\n\t return Tone.Follower;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.ScaledEnvelop is an envelope which can be scaled\n\t\t * to any range. It's useful for applying an envelope\n\t\t * to a frequency or any other non-NormalRange signal\n\t\t * parameter.\n\t\t *\n\t\t * @extends {Tone.Envelope}\n\t\t * @constructor\n\t\t * @param {Time|Object} [attack]\tthe attack time in seconds\n\t\t * @param {Time} [decay]\tthe decay time in seconds\n\t\t * @param {number} [sustain] \ta percentage (0-1) of the full amplitude\n\t\t * @param {Time} [release]\tthe release time in seconds\n\t\t * @example\n\t\t * var scaledEnv = new Tone.ScaledEnvelope({\n\t\t * \t\"attack\" : 0.2,\n\t\t * \t\"min\" : 200,\n\t\t * \t\"max\" : 2000\n\t\t * });\n\t\t * scaledEnv.connect(oscillator.frequency);\n\t\t */\n\t Tone.ScaledEnvelope = function () {\n\t //get all of the defaults\n\t var options = Tone.defaults(arguments, [\n\t 'attack',\n\t 'decay',\n\t 'sustain',\n\t 'release'\n\t ], Tone.Envelope);\n\t Tone.Envelope.call(this, options);\n\t options = Tone.defaultArg(options, Tone.ScaledEnvelope.defaults);\n\t /**\n\t\t\t * scale the incoming signal by an exponent\n\t\t\t * @type {Tone.Pow}\n\t\t\t * @private\n\t\t\t */\n\t this._exp = this.output = new Tone.Pow(options.exponent);\n\t /**\n\t\t\t * scale the signal to the desired range\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._scale = this.output = new Tone.Scale(options.min, options.max);\n\t this._sig.chain(this._exp, this._scale);\n\t };\n\t Tone.extend(Tone.ScaledEnvelope, Tone.Envelope);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t */\n\t Tone.ScaledEnvelope.defaults = {\n\t 'min': 0,\n\t 'max': 1,\n\t 'exponent': 1\n\t };\n\t /**\n\t\t * The envelope's min output value. This is the value which it\n\t\t * starts at.\n\t\t * @memberOf Tone.ScaledEnvelope#\n\t\t * @type {number}\n\t\t * @name min\n\t\t */\n\t Object.defineProperty(Tone.ScaledEnvelope.prototype, 'min', {\n\t get: function () {\n\t return this._scale.min;\n\t },\n\t set: function (min) {\n\t this._scale.min = min;\n\t }\n\t });\n\t /**\n\t\t * The envelope's max output value. In other words, the value\n\t\t * at the peak of the attack portion of the envelope.\n\t\t * @memberOf Tone.ScaledEnvelope#\n\t\t * @type {number}\n\t\t * @name max\n\t\t */\n\t Object.defineProperty(Tone.ScaledEnvelope.prototype, 'max', {\n\t get: function () {\n\t return this._scale.max;\n\t },\n\t set: function (max) {\n\t this._scale.max = max;\n\t }\n\t });\n\t /**\n\t\t * The envelope's exponent value.\n\t\t * @memberOf Tone.ScaledEnvelope#\n\t\t * @type {number}\n\t\t * @name exponent\n\t\t */\n\t Object.defineProperty(Tone.ScaledEnvelope.prototype, 'exponent', {\n\t get: function () {\n\t return this._exp.value;\n\t },\n\t set: function (exp) {\n\t this._exp.value = exp;\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.ScaledEnvelope} this\n\t\t */\n\t Tone.ScaledEnvelope.prototype.dispose = function () {\n\t Tone.Envelope.prototype.dispose.call(this);\n\t this._scale.dispose();\n\t this._scale = null;\n\t this._exp.dispose();\n\t this._exp = null;\n\t return this;\n\t };\n\t return Tone.ScaledEnvelope;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.FrequencyEnvelope is a Tone.ScaledEnvelope, but instead of `min` and `max`\n\t\t * it's got a `baseFrequency` and `octaves` parameter.\n\t\t *\n\t\t * @extends {Tone.Envelope}\n\t\t * @constructor\n\t\t * @param {Time|Object} [attack]\tthe attack time in seconds\n\t\t * @param {Time} [decay]\tthe decay time in seconds\n\t\t * @param {number} [sustain] \ta percentage (0-1) of the full amplitude\n\t\t * @param {Time} [release]\tthe release time in seconds\n\t\t * @example\n\t\t * var freqEnv = new Tone.FrequencyEnvelope({\n\t\t * \t\"attack\" : 0.2,\n\t\t * \t\"baseFrequency\" : \"C2\",\n\t\t * \t\"octaves\" : 4\n\t\t * });\n\t\t * freqEnv.connect(oscillator.frequency);\n\t\t */\n\t Tone.FrequencyEnvelope = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'attack',\n\t 'decay',\n\t 'sustain',\n\t 'release'\n\t ], Tone.Envelope);\n\t Tone.ScaledEnvelope.call(this, options);\n\t //merge it with the frequency envelope defaults\n\t options = Tone.defaultArg(options, Tone.FrequencyEnvelope.defaults);\n\t /**\n\t\t\t * Stores the octave value\n\t\t\t * @type {Positive}\n\t\t\t * @private\n\t\t\t */\n\t this._octaves = options.octaves;\n\t //setup\n\t this.baseFrequency = options.baseFrequency;\n\t this.octaves = options.octaves;\n\t };\n\t Tone.extend(Tone.FrequencyEnvelope, Tone.Envelope);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t */\n\t Tone.FrequencyEnvelope.defaults = {\n\t 'baseFrequency': 200,\n\t 'octaves': 4,\n\t 'exponent': 2\n\t };\n\t /**\n\t\t * The envelope's mininum output value. This is the value which it\n\t\t * starts at.\n\t\t * @memberOf Tone.FrequencyEnvelope#\n\t\t * @type {Frequency}\n\t\t * @name baseFrequency\n\t\t */\n\t Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'baseFrequency', {\n\t get: function () {\n\t return this._scale.min;\n\t },\n\t set: function (min) {\n\t this._scale.min = this.toFrequency(min);\n\t //also update the octaves\n\t this.octaves = this._octaves;\n\t }\n\t });\n\t /**\n\t\t * The number of octaves above the baseFrequency that the\n\t\t * envelope will scale to.\n\t\t * @memberOf Tone.FrequencyEnvelope#\n\t\t * @type {Positive}\n\t\t * @name octaves\n\t\t */\n\t Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'octaves', {\n\t get: function () {\n\t return this._octaves;\n\t },\n\t set: function (octaves) {\n\t this._octaves = octaves;\n\t this._scale.max = this.baseFrequency * Math.pow(2, octaves);\n\t }\n\t });\n\t /**\n\t\t * The envelope's exponent value.\n\t\t * @memberOf Tone.FrequencyEnvelope#\n\t\t * @type {number}\n\t\t * @name exponent\n\t\t */\n\t Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'exponent', {\n\t get: function () {\n\t return this._exp.value;\n\t },\n\t set: function (exp) {\n\t this._exp.value = exp;\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.FrequencyEnvelope} this\n\t\t */\n\t Tone.FrequencyEnvelope.prototype.dispose = function () {\n\t Tone.ScaledEnvelope.prototype.dispose.call(this);\n\t return this;\n\t };\n\t return Tone.FrequencyEnvelope;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.SignalBase}\n\t\t * @example\n\t\t * var gt0 = new Tone.GreaterThanZero();\n\t\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t\t * //the output of gt0 is 1.\n\t\t * sig.value = 0;\n\t\t * //the output of gt0 is 0.\n\t\t */\n\t Tone.GreaterThanZero = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * @type {Tone.WaveShaper}\n\t\t\t * @private\n\t\t\t */\n\t this._thresh = this.output = new Tone.WaveShaper(function (val) {\n\t if (val <= 0) {\n\t return 0;\n\t } else {\n\t return 1;\n\t }\n\t }, 127);\n\t /**\n\t\t\t * scale the first thresholded signal by a large value.\n\t\t\t * this will help with values which are very close to 0\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._scale = this.input = new Tone.Multiply(10000);\n\t //connections\n\t this._scale.connect(this._thresh);\n\t };\n\t Tone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\t /**\n\t\t * dispose method\n\t\t * @returns {Tone.GreaterThanZero} this\n\t\t */\n\t Tone.GreaterThanZero.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._scale.dispose();\n\t this._scale = null;\n\t this._thresh.dispose();\n\t this._thresh = null;\n\t return this;\n\t };\n\t return Tone.GreaterThanZero;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t\t * can compare two signals or a signal and a number.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Signal}\n\t\t * @param {number} [value=0] the value to compare to the incoming signal\n\t\t * @example\n\t\t * var gt = new Tone.GreaterThan(2);\n\t\t * var sig = new Tone.Signal(4).connect(gt);\n\t\t * //output of gt is equal 1.\n\t\t */\n\t Tone.GreaterThan = function (value) {\n\t Tone.Signal.call(this);\n\t this.createInsOuts(2, 0);\n\t /**\n\t\t\t * subtract the amount from the incoming signal\n\t\t\t * @type {Tone.Subtract}\n\t\t\t * @private\n\t\t\t */\n\t this._param = this.input[0] = new Tone.Subtract(value);\n\t this.input[1] = this._param.input[1];\n\t /**\n\t\t\t * compare that amount to zero\n\t\t\t * @type {Tone.GreaterThanZero}\n\t\t\t * @private\n\t\t\t */\n\t this._gtz = this.output = new Tone.GreaterThanZero();\n\t //connect\n\t this._param.connect(this._gtz);\n\t };\n\t Tone.extend(Tone.GreaterThan, Tone.Signal);\n\t /**\n\t\t * dispose method\n\t\t * @returns {Tone.GreaterThan} this\n\t\t */\n\t Tone.GreaterThan.prototype.dispose = function () {\n\t Tone.Signal.prototype.dispose.call(this);\n\t this._gtz.dispose();\n\t this._gtz = null;\n\t return this;\n\t };\n\t return Tone.GreaterThan;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Gate only passes a signal through when the incoming\n\t\t * signal exceeds a specified threshold. To do this, Gate uses\n\t\t * a Tone.Follower to follow the amplitude of the incoming signal.\n\t\t * A common implementation of this class is a [Noise Gate](https://en.wikipedia.org/wiki/Noise_gate).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Decibels|Object} [threshold] The threshold above which the gate will open.\n\t\t * @param {Time=} attack The follower's attack time\n\t\t * @param {Time=} release The follower's release time\n\t\t * @example\n\t\t * var gate = new Tone.Gate(-30, 0.2, 0.3).toMaster();\n\t\t * var mic = new Tone.UserMedia().connect(gate);\n\t\t * //the gate will only pass through the incoming\n\t\t * //signal when it's louder than -30db\n\t\t */\n\t Tone.Gate = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'threshold',\n\t 'attack',\n\t 'release'\n\t ], Tone.Gate);\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(1, 1);\n\t /**\n\t\t\t * @type {Tone.Follower}\n\t\t\t * @private\n\t\t\t */\n\t this._follower = new Tone.Follower(options.attack, options.release);\n\t /**\n\t\t\t * @type {Tone.GreaterThan}\n\t\t\t * @private\n\t\t\t */\n\t this._gt = new Tone.GreaterThan(Tone.dbToGain(options.threshold));\n\t //the connections\n\t this.input.connect(this.output);\n\t //the control signal\n\t this.input.chain(this._gt, this._follower, this.output.gain);\n\t };\n\t Tone.extend(Tone.Gate, Tone.AudioNode);\n\t /**\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Gate.defaults = {\n\t 'attack': 0.1,\n\t 'release': 0.1,\n\t 'threshold': -40\n\t };\n\t /**\n\t\t * The threshold of the gate in decibels\n\t\t * @memberOf Tone.Gate#\n\t\t * @type {Decibels}\n\t\t * @name threshold\n\t\t */\n\t Object.defineProperty(Tone.Gate.prototype, 'threshold', {\n\t get: function () {\n\t return Tone.gainToDb(this._gt.value);\n\t },\n\t set: function (thresh) {\n\t this._gt.value = Tone.dbToGain(thresh);\n\t }\n\t });\n\t /**\n\t\t * The attack speed of the gate\n\t\t * @memberOf Tone.Gate#\n\t\t * @type {Time}\n\t\t * @name attack\n\t\t */\n\t Object.defineProperty(Tone.Gate.prototype, 'attack', {\n\t get: function () {\n\t return this._follower.attack;\n\t },\n\t set: function (attackTime) {\n\t this._follower.attack = attackTime;\n\t }\n\t });\n\t /**\n\t\t * The release speed of the gate\n\t\t * @memberOf Tone.Gate#\n\t\t * @type {Time}\n\t\t * @name release\n\t\t */\n\t Object.defineProperty(Tone.Gate.prototype, 'release', {\n\t get: function () {\n\t return this._follower.release;\n\t },\n\t set: function (releaseTime) {\n\t this._follower.release = releaseTime;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Gate} this\n\t\t */\n\t Tone.Gate.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._follower.dispose();\n\t this._gt.dispose();\n\t this._follower = null;\n\t this._gt = null;\n\t return this;\n\t };\n\t return Tone.Gate;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.TickSignal extends Tone.Signal, but adds the capability\n\t\t * to calculate the number of elapsed ticks. exponential and target curves\n\t\t * are approximated with multiple linear ramps.\n\t\t *\n\t\t * Thank you Bruno Dias, H. Sofia Pinto, and David M. Matos, for your [WAC paper](https://smartech.gatech.edu/bitstream/handle/1853/54588/WAC2016-49.pdf)\n\t\t * describing integrating timing functions for tempo calculations.\n\t\t *\n\t\t * @param {Number} value The initial value of the signal\n\t\t * @extends {Tone.Signal}\n\t\t */\n\t Tone.TickSignal = function (value) {\n\t value = Tone.defaultArg(value, 1);\n\t Tone.Signal.call(this, {\n\t 'units': Tone.Type.Ticks,\n\t 'value': value\n\t });\n\t //extend the memory\n\t this._events.memory = Infinity;\n\t //clear the clock from the beginning\n\t this.cancelScheduledValues(0);\n\t //set an initial event\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.SetValue,\n\t 'time': 0,\n\t 'value': value\n\t });\n\t };\n\t Tone.extend(Tone.TickSignal, Tone.Signal);\n\t /**\n\t\t * Wraps Tone.Signal methods so that they also\n\t\t * record the ticks.\n\t\t * @param {Function} method\n\t\t * @return {Function}\n\t\t * @private\n\t\t */\n\t function _wrapScheduleMethods(method) {\n\t return function (value, time) {\n\t time = this.toSeconds(time);\n\t method.apply(this, arguments);\n\t var event = this._events.get(time);\n\t var previousEvent = this._events.previousEvent(event);\n\t var ticksUntilTime = this._getTicksUntilEvent(previousEvent, time);\n\t event.ticks = Math.max(ticksUntilTime, 0);\n\t return this;\n\t };\n\t }\n\t Tone.TickSignal.prototype.setValueAtTime = _wrapScheduleMethods(Tone.Signal.prototype.setValueAtTime);\n\t Tone.TickSignal.prototype.linearRampToValueAtTime = _wrapScheduleMethods(Tone.Signal.prototype.linearRampToValueAtTime);\n\t /**\n\t\t * Start exponentially approaching the target value at the given time with\n\t\t * a rate having the given time constant.\n\t\t * @param {number} value\n\t\t * @param {Time} startTime\n\t\t * @param {number} timeConstant\n\t\t * @returns {Tone.TickSignal} this\n\t\t */\n\t Tone.TickSignal.prototype.setTargetAtTime = function (value, time, constant) {\n\t //aproximate it with multiple linear ramps\n\t time = this.toSeconds(time);\n\t this.setRampPoint(time);\n\t value = this._fromUnits(value);\n\t //start from previously scheduled value\n\t var prevEvent = this._events.get(time);\n\t var segments = Math.round(Math.max(1 / constant, 1));\n\t for (var i = 0; i <= segments; i++) {\n\t var segTime = constant * i + time;\n\t var rampVal = this._exponentialApproach(prevEvent.time, prevEvent.value, value, constant, segTime);\n\t this.linearRampToValueAtTime(this._toUnits(rampVal), segTime);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Schedules an exponential continuous change in parameter value from\n\t\t * the previous scheduled parameter value to the given value.\n\t\t * @param {number} value\n\t\t * @param {Time} endTime\n\t\t * @returns {Tone.TickSignal} this\n\t\t */\n\t Tone.TickSignal.prototype.exponentialRampToValueAtTime = function (value, time) {\n\t //aproximate it with multiple linear ramps\n\t time = this.toSeconds(time);\n\t value = this._fromUnits(value);\n\t //start from previously scheduled value\n\t var prevEvent = this._events.get(time);\n\t if (prevEvent === null) {\n\t prevEvent = {\n\t 'value': this._initialValue,\n\t 'time': 0\n\t };\n\t }\n\t //approx 10 segments per second\n\t var segments = Math.round(Math.max((time - prevEvent.time) * 10, 1));\n\t var segmentDur = (time - prevEvent.time) / segments;\n\t for (var i = 0; i <= segments; i++) {\n\t var segTime = segmentDur * i + prevEvent.time;\n\t var rampVal = this._exponentialInterpolate(prevEvent.time, prevEvent.value, time, value, segTime);\n\t this.linearRampToValueAtTime(this._toUnits(rampVal), segTime);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Returns the tick value at the time. Takes into account\n\t\t * any automation curves scheduled on the signal.\n\t\t * @private\n\t\t * @param {Time} time The time to get the tick count at\n\t\t * @return {Ticks} The number of ticks which have elapsed at the time\n\t\t * given any automations.\n\t\t */\n\t Tone.TickSignal.prototype._getTicksUntilEvent = function (event, time) {\n\t if (event === null) {\n\t event = {\n\t 'ticks': 0,\n\t 'time': 0\n\t };\n\t } else if (Tone.isUndef(event.ticks)) {\n\t var previousEvent = this._events.previousEvent(event);\n\t event.ticks = this._getTicksUntilEvent(previousEvent, event.time);\n\t }\n\t var val0 = this.getValueAtTime(event.time);\n\t var val1 = this.getValueAtTime(time);\n\t //if it's right on the line, take the previous value\n\t if (this._events.get(time).time === time && this._events.get(time).type === Tone.Param.AutomationType.SetValue) {\n\t val1 = this.getValueAtTime(time - this.sampleTime);\n\t }\n\t return 0.5 * (time - event.time) * (val0 + val1) + event.ticks;\n\t };\n\t /**\n\t\t * Returns the tick value at the time. Takes into account\n\t\t * any automation curves scheduled on the signal.\n\t\t * @param {Time} time The time to get the tick count at\n\t\t * @return {Ticks} The number of ticks which have elapsed at the time\n\t\t * given any automations.\n\t\t */\n\t Tone.TickSignal.prototype.getTicksAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t var event = this._events.get(time);\n\t return Math.max(this._getTicksUntilEvent(event, time), 0);\n\t };\n\t /**\n\t\t * Return the elapsed time of the number of ticks from the given time\n\t\t * @param {Ticks} ticks The number of ticks to calculate\n\t\t * @param {Time} time The time to get the next tick from\n\t\t * @return {Seconds} The duration of the number of ticks from the given time in seconds\n\t\t */\n\t Tone.TickSignal.prototype.getDurationOfTicks = function (ticks, time) {\n\t time = this.toSeconds(time);\n\t var currentTick = this.getTicksAtTime(time);\n\t return this.getTimeOfTick(currentTick + ticks) - time;\n\t };\n\t /**\n\t\t * Given a tick, returns the time that tick occurs at.\n\t\t * @param {Ticks} tick\n\t\t * @return {Time} The time that the tick occurs.\n\t\t */\n\t Tone.TickSignal.prototype.getTimeOfTick = function (tick) {\n\t var before = this._events.get(tick, 'ticks');\n\t var after = this._events.getAfter(tick, 'ticks');\n\t if (before && before.ticks === tick) {\n\t return before.time;\n\t } else if (before && after && after.type === Tone.Param.AutomationType.Linear && before.value !== after.value) {\n\t var val0 = this.getValueAtTime(before.time);\n\t var val1 = this.getValueAtTime(after.time);\n\t var delta = (val1 - val0) / (after.time - before.time);\n\t var k = Math.sqrt(Math.pow(val0, 2) - 2 * delta * (before.ticks - tick));\n\t var sol1 = (-val0 + k) / delta;\n\t var sol2 = (-val0 - k) / delta;\n\t return (sol1 > 0 ? sol1 : sol2) + before.time;\n\t } else if (before) {\n\t if (before.value === 0) {\n\t return Infinity;\n\t } else {\n\t return before.time + (tick - before.ticks) / before.value;\n\t }\n\t } else {\n\t return tick / this._initialValue;\n\t }\n\t };\n\t /**\n\t\t * Convert some number of ticks their the duration in seconds accounting\n\t\t * for any automation curves starting at the given time.\n\t\t * @param {Ticks} ticks The number of ticks to convert to seconds.\n\t\t * @param {Time} [when=now] When along the automation timeline to convert the ticks.\n\t\t * @return {Tone.Time} The duration in seconds of the ticks.\n\t\t */\n\t Tone.TickSignal.prototype.ticksToTime = function (ticks, when) {\n\t when = this.toSeconds(when);\n\t return new Tone.Time(this.getDurationOfTicks(ticks, when));\n\t };\n\t /**\n\t\t * The inverse of [ticksToTime](#tickstotime). Convert a duration in\n\t\t * seconds to the corresponding number of ticks accounting for any\n\t\t * automation curves starting at the given time.\n\t\t * @param {Time} duration The time interval to convert to ticks.\n\t\t * @param {Time} [when=now] When along the automation timeline to convert the ticks.\n\t\t * @return {Tone.Ticks} The duration in ticks.\n\t\t */\n\t Tone.TickSignal.prototype.timeToTicks = function (duration, when) {\n\t when = this.toSeconds(when);\n\t duration = this.toSeconds(duration);\n\t var startTicks = this.getTicksAtTime(when);\n\t var endTicks = this.getTicksAtTime(when + duration);\n\t return new Tone.Ticks(endTicks - startTicks);\n\t };\n\t return Tone.TickSignal;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A Timeline State. Provides the methods: <code>setStateAtTime(\"state\", time)</code>\n\t\t * and <code>getValueAtTime(time)</code>.\n\t\t *\n\t\t * @extends {Tone.Timeline}\n\t\t * @param {String} initial The initial state of the TimelineState. \n\t\t * Defaults to <code>undefined</code>\n\t\t */\n\t Tone.TimelineState = function (initial) {\n\t Tone.Timeline.call(this);\n\t /**\n\t\t\t * The initial state\n\t\t\t * @private\n\t\t\t * @type {String}\n\t\t\t */\n\t this._initial = initial;\n\t };\n\t Tone.extend(Tone.TimelineState, Tone.Timeline);\n\t /**\n\t\t * Returns the scheduled state scheduled before or at\n\t\t * the given time.\n\t\t * @param {Number} time The time to query.\n\t\t * @return {String} The name of the state input in setStateAtTime.\n\t\t */\n\t Tone.TimelineState.prototype.getValueAtTime = function (time) {\n\t var event = this.get(time);\n\t if (event !== null) {\n\t return event.state;\n\t } else {\n\t return this._initial;\n\t }\n\t };\n\t /**\n\t\t * Add a state to the timeline.\n\t\t * @param {String} state The name of the state to set.\n\t\t * @param {Number} time The time to query.\n\t\t * @returns {Tone.TimelineState} this\n\t\t */\n\t Tone.TimelineState.prototype.setStateAtTime = function (state, time) {\n\t //all state changes need to be >= the previous state time\n\t //TODO throw error if time < the previous event time\n\t this.add({\n\t 'state': state,\n\t 'time': time\n\t });\n\t return this;\n\t };\n\t /**\n\t\t * Return the event before the time with the given state\n\t\t * @param {Tone.State} state The state to look for\n\t\t * @param {Time} time When to check before\t\t\t\n\t\t * @return {Object} The event with the given state before the time\n\t\t */\n\t Tone.TimelineState.prototype.getLastState = function (state, time) {\n\t time = this.toSeconds(time);\n\t var index = this._search(time);\n\t for (var i = index; i >= 0; i--) {\n\t var event = this._timeline[i];\n\t if (event.state === state) {\n\t return event;\n\t }\n\t }\n\t };\n\t /**\n\t\t * Return the event after the time with the given state\n\t\t * @param {Tone.State} state The state to look for\n\t\t * @param {Time} time When to check from\n\t\t * @return {Object} The event with the given state after the time\n\t\t */\n\t Tone.TimelineState.prototype.getNextState = function (state, time) {\n\t time = this.toSeconds(time);\n\t var index = this._search(time);\n\t if (index !== -1) {\n\t for (var i = index; i < this._timeline.length; i++) {\n\t var event = this._timeline[i];\n\t if (event.state === state) {\n\t return event;\n\t }\n\t }\n\t }\n\t };\n\t return Tone.TimelineState;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Uses [Tone.TickSignal](TickSignal) to track elapsed ticks with\n\t\t * \t\tcomplex automation curves.\n\t\t *\n\t\t * \t@constructor\n\t * @param {Frequency} frequency The initial frequency that the signal ticks at\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.TickSource = function () {\n\t var options = Tone.defaults(arguments, ['frequency'], Tone.TickSource);\n\t /**\n\t\t\t * The frequency the callback function should be invoked.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.TickSignal(options.frequency, Tone.Type.Frequency);\n\t this._readOnly('frequency');\n\t /**\n\t\t\t * The state timeline\n\t\t\t * @type {Tone.TimelineState}\n\t\t\t * @private\n\t\t\t */\n\t this._state = new Tone.TimelineState(Tone.State.Stopped);\n\t this._state.setStateAtTime(Tone.State.Stopped, 0);\n\t /**\n\t\t\t * The offset values of the ticks\n\t\t\t * @type {Tone.Timeline}\n\t\t\t * @private\n\t\t\t */\n\t this._tickOffset = new Tone.Timeline();\n\t //add the first event\n\t this.setTicksAtTime(0, 0);\n\t };\n\t Tone.extend(Tone.TickSource);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.TickSource.defaults = { 'frequency': 1 };\n\t /**\n\t\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.TickSource#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.TickSource.prototype, 'state', {\n\t get: function () {\n\t return this._state.getValueAtTime(this.now());\n\t }\n\t });\n\t /**\n\t\t * Start the clock at the given time. Optionally pass in an offset\n\t\t * of where to start the tick counter from.\n\t\t * @param {Time=} time The time the clock should start\n\t\t * @param {Ticks=0} offset The number of ticks to start the source at\n\t\t * @return {Tone.TickSource} this\n\t\t */\n\t Tone.TickSource.prototype.start = function (time, offset) {\n\t time = this.toSeconds(time);\n\t if (this._state.getValueAtTime(time) !== Tone.State.Started) {\n\t this._state.setStateAtTime(Tone.State.Started, time);\n\t if (Tone.isDefined(offset)) {\n\t this.setTicksAtTime(offset, time);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t\t * @param {Time} [time=now] The time when the clock should stop.\n\t\t * @returns {Tone.TickSource} this\n\t\t * @example\n\t\t * clock.stop();\n\t\t */\n\t Tone.TickSource.prototype.stop = function (time) {\n\t time = this.toSeconds(time);\n\t //cancel the previous stop\n\t if (this._state.getValueAtTime(time) === Tone.State.Stopped) {\n\t var event = this._state.get(time);\n\t if (event.time > 0) {\n\t this._tickOffset.cancel(event.time);\n\t this._state.cancel(event.time);\n\t }\n\t }\n\t this._state.cancel(time);\n\t this._state.setStateAtTime(Tone.State.Stopped, time);\n\t this.setTicksAtTime(0, time);\n\t return this;\n\t };\n\t /**\n\t\t * Pause the clock. Pausing does not reset the tick counter.\n\t\t * @param {Time} [time=now] The time when the clock should stop.\n\t\t * @returns {Tone.TickSource} this\n\t\t */\n\t Tone.TickSource.prototype.pause = function (time) {\n\t time = this.toSeconds(time);\n\t if (this._state.getValueAtTime(time) === Tone.State.Started) {\n\t this._state.setStateAtTime(Tone.State.Paused, time);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Cancel start/stop/pause and setTickAtTime events scheduled after the given time.\n\t\t * @param {Time} [time=now] When to clear the events after\n\t\t * @returns {Tone.TickSource} this\n\t\t */\n\t Tone.TickSource.prototype.cancel = function (time) {\n\t time = this.toSeconds(time);\n\t this._state.cancel(time);\n\t this._tickOffset.cancel(time);\n\t return this;\n\t };\n\t /**\n\t\t * Get the elapsed ticks at the given time\n\t\t * @param {Time} time When to get the tick value\n\t\t * @return {Ticks} The number of ticks\n\t\t */\n\t Tone.TickSource.prototype.getTicksAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t var stopEvent = this._state.getLastState(Tone.State.Stopped, time);\n\t //this event allows forEachBetween to iterate until the current time\n\t var tmpEvent = {\n\t state: Tone.State.Paused,\n\t time: time\n\t };\n\t this._state.add(tmpEvent);\n\t //keep track of the previous offset event\n\t var lastState = stopEvent;\n\t var elapsedTicks = 0;\n\t //iterate through all the events since the last stop\n\t this._state.forEachBetween(stopEvent.time, time + this.sampleTime, function (e) {\n\t var periodStartTime = lastState.time;\n\t //if there is an offset event in this period use that\n\t var offsetEvent = this._tickOffset.get(e.time);\n\t if (offsetEvent.time >= lastState.time) {\n\t elapsedTicks = offsetEvent.ticks;\n\t periodStartTime = offsetEvent.time;\n\t }\n\t if (lastState.state === Tone.State.Started && e.state !== Tone.State.Started) {\n\t elapsedTicks += this.frequency.getTicksAtTime(e.time) - this.frequency.getTicksAtTime(periodStartTime);\n\t }\n\t lastState = e;\n\t }.bind(this));\n\t //remove the temporary event\n\t this._state.remove(tmpEvent);\n\t //return the ticks\n\t return elapsedTicks;\n\t };\n\t /**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. Returns -1 when stopped.\n\t\t * @memberOf Tone.TickSource#\n\t\t * @name ticks\n\t\t * @type {Ticks}\n\t\t */\n\t Object.defineProperty(Tone.TickSource.prototype, 'ticks', {\n\t get: function () {\n\t return this.getTicksAtTime(this.now());\n\t },\n\t set: function (t) {\n\t this.setTicksAtTime(t, this.now());\n\t }\n\t });\n\t /**\n\t\t * The time since ticks=0 that the TickSource has been running. Accounts\n\t\t * for tempo curves\n\t\t * @memberOf Tone.TickSource#\n\t\t * @name seconds\n\t\t * @type {Seconds}\n\t\t */\n\t Object.defineProperty(Tone.TickSource.prototype, 'seconds', {\n\t get: function () {\n\t return this.getSecondsAtTime(this.now());\n\t },\n\t set: function (s) {\n\t var now = this.now();\n\t var ticks = this.frequency.timeToTicks(s, now);\n\t this.setTicksAtTime(ticks, now);\n\t }\n\t });\n\t /**\n\t\t * Return the elapsed seconds at the given time.\n\t\t * @param {Time} time When to get the elapsed seconds\n\t\t * @return {Seconds} The number of elapsed seconds\n\t\t */\n\t Tone.TickSource.prototype.getSecondsAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t var stopEvent = this._state.getLastState(Tone.State.Stopped, time);\n\t //this event allows forEachBetween to iterate until the current time\n\t var tmpEvent = {\n\t state: Tone.State.Paused,\n\t time: time\n\t };\n\t this._state.add(tmpEvent);\n\t //keep track of the previous offset event\n\t var lastState = stopEvent;\n\t var elapsedSeconds = 0;\n\t //iterate through all the events since the last stop\n\t this._state.forEachBetween(stopEvent.time, time + this.sampleTime, function (e) {\n\t var periodStartTime = lastState.time;\n\t //if there is an offset event in this period use that\n\t var offsetEvent = this._tickOffset.get(e.time);\n\t if (offsetEvent.time >= lastState.time) {\n\t elapsedSeconds = offsetEvent.seconds;\n\t periodStartTime = offsetEvent.time;\n\t }\n\t if (lastState.state === Tone.State.Started && e.state !== Tone.State.Started) {\n\t elapsedSeconds += e.time - periodStartTime;\n\t }\n\t lastState = e;\n\t }.bind(this));\n\t //remove the temporary event\n\t this._state.remove(tmpEvent);\n\t //return the ticks\n\t return elapsedSeconds;\n\t };\n\t /**\n\t\t * Set the clock's ticks at the given time.\n\t\t * @param {Ticks} ticks The tick value to set\n\t\t * @param {Time} time When to set the tick value\n\t\t * @return {Tone.TickSource} this\n\t\t */\n\t Tone.TickSource.prototype.setTicksAtTime = function (ticks, time) {\n\t time = this.toSeconds(time);\n\t this._tickOffset.cancel(time);\n\t this._tickOffset.add({\n\t 'time': time,\n\t 'ticks': ticks,\n\t 'seconds': this.frequency.getDurationOfTicks(ticks, time)\n\t });\n\t return this;\n\t };\n\t /**\n\t\t * Returns the scheduled state at the given time.\n\t\t * @param {Time} time The time to query.\n\t\t * @return {String} The name of the state input in setStateAtTime.\n\t\t * @example\n\t\t * source.start(\"+0.1\");\n\t\t * source.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t\t */\n\t Tone.TickSource.prototype.getStateAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t return this._state.getValueAtTime(time);\n\t };\n\t /**\n\t\t * Get the time of the given tick. The second argument\n\t\t * is when to test before. Since ticks can be set (with setTicksAtTime)\n\t\t * there may be multiple times for a given tick value. \n\t\t * @param {Ticks} ticks The tick number.\n\t\t * @param {Time=} before When to measure the tick value from. \n\t\t * @return {Time} The time of the tick\n\t\t */\n\t Tone.TickSource.prototype.getTimeOfTick = function (tick, before) {\n\t before = Tone.defaultArg(before, this.now());\n\t var offset = this._tickOffset.get(before);\n\t var event = this._state.get(before);\n\t var startTime = Math.max(offset.time, event.time);\n\t var absoluteTicks = this.frequency.getTicksAtTime(startTime) + tick - offset.ticks;\n\t return this.frequency.getTimeOfTick(absoluteTicks);\n\t };\n\t /**\n\t\t * Invoke the callback event at all scheduled ticks between the \n\t\t * start time and the end time\n\t\t * @param {Time} startTime The beginning of the search range\n\t\t * @param {Time} endTime The end of the search range\n\t\t * @param {Function<Time,Ticks>} callback The callback to invoke with each tick\n\t\t * @return {Tone.TickSource} this\n\t\t */\n\t Tone.TickSource.prototype.forEachTickBetween = function (startTime, endTime, callback) {\n\t //only iterate through the sections where it is \"started\"\n\t var lastStateEvent = this._state.get(startTime);\n\t this._state.forEachBetween(startTime, endTime, function (event) {\n\t if (lastStateEvent.state === Tone.State.Started && event.state !== Tone.State.Started) {\n\t this.forEachTickBetween(Math.max(lastStateEvent.time, startTime), event.time - this.sampleTime, callback);\n\t }\n\t lastStateEvent = event;\n\t }.bind(this));\n\t startTime = Math.max(lastStateEvent.time, startTime);\n\t if (lastStateEvent.state === Tone.State.Started && this._state) {\n\t //figure out the difference between the frequency ticks and the \n\t var startTicks = this.frequency.getTicksAtTime(startTime);\n\t var ticksAtStart = this.frequency.getTicksAtTime(lastStateEvent.time);\n\t var diff = startTicks - ticksAtStart;\n\t var offset = diff % 1;\n\t if (offset !== 0) {\n\t offset = 1 - offset;\n\t }\n\t var nextTickTime = this.frequency.getTimeOfTick(startTicks + offset);\n\t var error = null;\n\t while (nextTickTime < endTime && this._state) {\n\t try {\n\t callback(nextTickTime, Math.round(this.getTicksAtTime(nextTickTime)));\n\t } catch (e) {\n\t error = e;\n\t break;\n\t }\n\t if (this._state) {\n\t nextTickTime += this.frequency.getDurationOfTicks(1, nextTickTime);\n\t }\n\t }\n\t }\n\t if (error) {\n\t throw error;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @returns {Tone.TickSource} this\n\t\t */\n\t Tone.TickSource.prototype.dispose = function () {\n\t Tone.Param.prototype.dispose.call(this);\n\t this._state.dispose();\n\t this._state = null;\n\t this._tickOffset.dispose();\n\t this._tickOffset = null;\n\t this._writable('frequency');\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t return this;\n\t };\n\t return Tone.TickSource;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A sample accurate clock which provides a callback at the given rate.\n\t\t * While the callback is not sample-accurate (it is still susceptible to\n\t\t * loose JS timing), the time passed in as the argument to the callback\n\t\t * is precise. For most applications, it is better to use Tone.Transport\n\t\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t\t *\n\t\t * \t@constructor\n\t\t * @extends {Tone.Emitter}\n\t\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t\t * \t@param {Frequency} frequency The rate of the callback\n\t\t * \t@example\n\t\t * //the callback will be invoked approximately once a second\n\t\t * //and will print the time exactly once a second apart.\n\t\t * var clock = new Tone.Clock(function(time){\n\t\t * \tconsole.log(time);\n\t\t * }, 1);\n\t\t */\n\t Tone.Clock = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'callback',\n\t 'frequency'\n\t ], Tone.Clock);\n\t Tone.Emitter.call(this);\n\t /**\n\t\t\t * The callback function to invoke at the scheduled tick.\n\t\t\t * @type {Function}\n\t\t\t */\n\t this.callback = options.callback;\n\t /**\n\t\t\t * The next time the callback is scheduled.\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._nextTick = 0;\n\t /**\n\t\t\t * The tick counter\n\t\t\t * @type {Tone.TickSource}\n\t\t\t * @private\n\t\t\t */\n\t this._tickSource = new Tone.TickSource(options.frequency);\n\t /**\n\t\t\t * The last time the loop callback was invoked\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._lastUpdate = 0;\n\t /**\n\t\t\t * The rate the callback function should be invoked.\n\t\t\t * @type {BPM}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._tickSource.frequency;\n\t this._readOnly('frequency');\n\t /**\n\t\t\t * The state timeline\n\t\t\t * @type {Tone.TimelineState}\n\t\t\t * @private\n\t\t\t */\n\t this._state = new Tone.TimelineState(Tone.State.Stopped);\n\t //add an initial state\n\t this._state.setStateAtTime(Tone.State.Stopped, 0);\n\t /**\n\t\t\t * The loop function bound to its context.\n\t\t\t * This is necessary to remove the event in the end.\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._boundLoop = this._loop.bind(this);\n\t //bind a callback to the worker thread\n\t this.context.on('tick', this._boundLoop);\n\t };\n\t Tone.extend(Tone.Clock, Tone.Emitter);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Clock.defaults = {\n\t 'callback': Tone.noOp,\n\t 'frequency': 1\n\t };\n\t /**\n\t\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.Clock#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.Clock.prototype, 'state', {\n\t get: function () {\n\t return this._state.getValueAtTime(this.now());\n\t }\n\t });\n\t /**\n\t\t * Start the clock at the given time. Optionally pass in an offset\n\t\t * of where to start the tick counter from.\n\t\t * @param {Time=} time The time the clock should start\n\t\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t\t * @return {Tone.Clock} this\n\t\t */\n\t Tone.Clock.prototype.start = function (time, offset) {\n\t time = this.toSeconds(time);\n\t if (this._state.getValueAtTime(time) !== Tone.State.Started) {\n\t this._state.setStateAtTime(Tone.State.Started, time);\n\t this._tickSource.start(time, offset);\n\t if (time < this._lastUpdate) {\n\t this.emit('start', time, offset);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t\t * @param {Time} [time=now] The time when the clock should stop.\n\t\t * @returns {Tone.Clock} this\n\t\t * @example\n\t\t * clock.stop();\n\t\t */\n\t Tone.Clock.prototype.stop = function (time) {\n\t time = this.toSeconds(time);\n\t this._state.cancel(time);\n\t this._state.setStateAtTime(Tone.State.Stopped, time);\n\t this._tickSource.stop(time);\n\t if (time < this._lastUpdate) {\n\t this.emit('stop', time);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Pause the clock. Pausing does not reset the tick counter.\n\t\t * @param {Time} [time=now] The time when the clock should stop.\n\t\t * @returns {Tone.Clock} this\n\t\t */\n\t Tone.Clock.prototype.pause = function (time) {\n\t time = this.toSeconds(time);\n\t if (this._state.getValueAtTime(time) === Tone.State.Started) {\n\t this._state.setStateAtTime(Tone.State.Paused, time);\n\t this._tickSource.pause(time);\n\t if (time < this._lastUpdate) {\n\t this.emit('pause', time);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked.\n\t\t * @type {Ticks}\n\t\t */\n\t Object.defineProperty(Tone.Clock.prototype, 'ticks', {\n\t get: function () {\n\t return Math.ceil(this.getTicksAtTime(this.now()));\n\t },\n\t set: function (t) {\n\t this._tickSource.ticks = t;\n\t }\n\t });\n\t /**\n\t\t * The time since ticks=0 that the Clock has been running. Accounts\n\t\t * for tempo curves\n\t\t * @type {Seconds}\n\t\t */\n\t Object.defineProperty(Tone.Clock.prototype, 'seconds', {\n\t get: function () {\n\t return this._tickSource.seconds;\n\t },\n\t set: function (s) {\n\t this._tickSource.seconds = s;\n\t }\n\t });\n\t /**\n\t\t * Return the elapsed seconds at the given time.\n\t\t * @param {Time} time When to get the elapsed seconds\n\t\t * @return {Seconds} The number of elapsed seconds\n\t\t */\n\t Tone.Clock.prototype.getSecondsAtTime = function (time) {\n\t return this._tickSource.getSecondsAtTime(time);\n\t };\n\t /**\n\t\t * Set the clock's ticks at the given time.\n\t\t * @param {Ticks} ticks The tick value to set\n\t\t * @param {Time} time When to set the tick value\n\t\t * @return {Tone.Clock} this\n\t\t */\n\t Tone.Clock.prototype.setTicksAtTime = function (ticks, time) {\n\t this._tickSource.setTicksAtTime(ticks, time);\n\t return this;\n\t };\n\t /**\n\t\t * Get the clock's ticks at the given time.\n\t\t * @param {Time} time When to get the tick value\n\t\t * @return {Ticks} The tick value at the given time.\n\t\t */\n\t Tone.Clock.prototype.getTicksAtTime = function (time) {\n\t return this._tickSource.getTicksAtTime(time);\n\t };\n\t /**\n\t\t * Get the time of the next tick\n\t\t * @param {Ticks} ticks The tick number.\n\t\t * @param {Time} before \n\t\t * @return {Tone.Clock} this\n\t\t */\n\t Tone.Clock.prototype.nextTickTime = function (offset, when) {\n\t when = this.toSeconds(when);\n\t var currentTick = this.getTicksAtTime(when);\n\t return this._tickSource.getTimeOfTick(currentTick + offset, when);\n\t };\n\t /**\n\t\t * The scheduling loop.\n\t\t * @private\n\t\t */\n\t Tone.Clock.prototype._loop = function () {\n\t var startTime = this._lastUpdate;\n\t var endTime = this.now();\n\t this._lastUpdate = endTime;\n\t if (startTime !== endTime) {\n\t //the state change events\n\t this._state.forEachBetween(startTime, endTime, function (e) {\n\t switch (e.state) {\n\t case Tone.State.Started:\n\t var offset = this._tickSource.getTicksAtTime(e.time);\n\t this.emit('start', e.time, offset);\n\t break;\n\t case Tone.State.Stopped:\n\t if (e.time !== 0) {\n\t this.emit('stop', e.time);\n\t }\n\t break;\n\t case Tone.State.Paused:\n\t this.emit('pause', e.time);\n\t break;\n\t }\n\t }.bind(this));\n\t //the tick callbacks\n\t this._tickSource.forEachTickBetween(startTime, endTime, function (time, ticks) {\n\t this.callback(time, ticks);\n\t }.bind(this));\n\t }\n\t };\n\t /**\n\t\t * Returns the scheduled state at the given time.\n\t\t * @param {Time} time The time to query.\n\t\t * @return {String} The name of the state input in setStateAtTime.\n\t\t * @example\n\t\t * clock.start(\"+0.1\");\n\t\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t\t */\n\t Tone.Clock.prototype.getStateAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t return this._state.getValueAtTime(time);\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @returns {Tone.Clock} this\n\t\t */\n\t Tone.Clock.prototype.dispose = function () {\n\t Tone.Emitter.prototype.dispose.call(this);\n\t this.context.off('tick', this._boundLoop);\n\t this._writable('frequency');\n\t this._tickSource.dispose();\n\t this._tickSource = null;\n\t this.frequency = null;\n\t this._boundLoop = null;\n\t this._nextTick = Infinity;\n\t this.callback = null;\n\t this._state.dispose();\n\t this._state = null;\n\t };\n\t return Tone.Clock;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Similar to Tone.Timeline, but all events represent\n\t\t * intervals with both \"time\" and \"duration\" times. The\n\t\t * events are placed in a tree structure optimized\n\t\t * for querying an intersection point with the timeline\n\t\t * events. Internally uses an [Interval Tree](https://en.wikipedia.org/wiki/Interval_tree)\n\t\t * to represent the data.\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.IntervalTimeline = function () {\n\t Tone.call(this);\n\t /**\n\t\t\t * The root node of the inteval tree\n\t\t\t * @type {IntervalNode}\n\t\t\t * @private\n\t\t\t */\n\t this._root = null;\n\t /**\n\t\t\t * Keep track of the length of the timeline.\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._length = 0;\n\t };\n\t Tone.extend(Tone.IntervalTimeline);\n\t /**\n\t\t * The event to add to the timeline. All events must\n\t\t * have a time and duration value\n\t\t * @param {Object} event The event to add to the timeline\n\t\t * @return {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.add = function (event) {\n\t if (Tone.isUndef(event.time) || Tone.isUndef(event.duration)) {\n\t throw new Error('Tone.IntervalTimeline: events must have time and duration parameters');\n\t }\n\t event.time = event.time.valueOf();\n\t var node = new IntervalNode(event.time, event.time + event.duration, event);\n\t if (this._root === null) {\n\t this._root = node;\n\t } else {\n\t this._root.insert(node);\n\t }\n\t this._length++;\n\t // Restructure tree to be balanced\n\t while (node !== null) {\n\t node.updateHeight();\n\t node.updateMax();\n\t this._rebalance(node);\n\t node = node.parent;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Remove an event from the timeline.\n\t\t * @param {Object} event The event to remove from the timeline\n\t\t * @return {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.remove = function (event) {\n\t if (this._root !== null) {\n\t var results = [];\n\t this._root.search(event.time, results);\n\t for (var i = 0; i < results.length; i++) {\n\t var node = results[i];\n\t if (node.event === event) {\n\t this._removeNode(node);\n\t this._length--;\n\t break;\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * The number of items in the timeline.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.IntervalTimeline#\n\t\t * @name length\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.IntervalTimeline.prototype, 'length', {\n\t get: function () {\n\t return this._length;\n\t }\n\t });\n\t /**\n\t\t * Remove events whose time time is after the given time\n\t\t * @param {Number} time The time to query.\n\t\t * @returns {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.cancel = function (after) {\n\t this.forEachFrom(after, function (event) {\n\t this.remove(event);\n\t }.bind(this));\n\t return this;\n\t };\n\t /**\n\t\t * Set the root node as the given node\n\t\t * @param {IntervalNode} node\n\t\t * @private\n\t\t */\n\t Tone.IntervalTimeline.prototype._setRoot = function (node) {\n\t this._root = node;\n\t if (this._root !== null) {\n\t this._root.parent = null;\n\t }\n\t };\n\t /**\n\t\t * Replace the references to the node in the node's parent\n\t\t * with the replacement node.\n\t\t * @param {IntervalNode} node\n\t\t * @param {IntervalNode} replacement\n\t\t * @private\n\t\t */\n\t Tone.IntervalTimeline.prototype._replaceNodeInParent = function (node, replacement) {\n\t if (node.parent !== null) {\n\t if (node.isLeftChild()) {\n\t node.parent.left = replacement;\n\t } else {\n\t node.parent.right = replacement;\n\t }\n\t this._rebalance(node.parent);\n\t } else {\n\t this._setRoot(replacement);\n\t }\n\t };\n\t /**\n\t\t * Remove the node from the tree and replace it with\n\t\t * a successor which follows the schema.\n\t\t * @param {IntervalNode} node\n\t\t * @private\n\t\t */\n\t Tone.IntervalTimeline.prototype._removeNode = function (node) {\n\t if (node.left === null && node.right === null) {\n\t this._replaceNodeInParent(node, null);\n\t } else if (node.right === null) {\n\t this._replaceNodeInParent(node, node.left);\n\t } else if (node.left === null) {\n\t this._replaceNodeInParent(node, node.right);\n\t } else {\n\t var balance = node.getBalance();\n\t var replacement, temp;\n\t if (balance > 0) {\n\t if (node.left.right === null) {\n\t replacement = node.left;\n\t replacement.right = node.right;\n\t temp = replacement;\n\t } else {\n\t replacement = node.left.right;\n\t while (replacement.right !== null) {\n\t replacement = replacement.right;\n\t }\n\t replacement.parent.right = replacement.left;\n\t temp = replacement.parent;\n\t replacement.left = node.left;\n\t replacement.right = node.right;\n\t }\n\t } else if (node.right.left === null) {\n\t replacement = node.right;\n\t replacement.left = node.left;\n\t temp = replacement;\n\t } else {\n\t replacement = node.right.left;\n\t while (replacement.left !== null) {\n\t replacement = replacement.left;\n\t }\n\t replacement.parent = replacement.parent;\n\t replacement.parent.left = replacement.right;\n\t temp = replacement.parent;\n\t replacement.left = node.left;\n\t replacement.right = node.right;\n\t }\n\t if (node.parent !== null) {\n\t if (node.isLeftChild()) {\n\t node.parent.left = replacement;\n\t } else {\n\t node.parent.right = replacement;\n\t }\n\t } else {\n\t this._setRoot(replacement);\n\t }\n\t // this._replaceNodeInParent(node, replacement);\n\t this._rebalance(temp);\n\t }\n\t node.dispose();\n\t };\n\t /**\n\t\t * Rotate the tree to the left\n\t\t * @param {IntervalNode} node\n\t\t * @private\n\t\t */\n\t Tone.IntervalTimeline.prototype._rotateLeft = function (node) {\n\t var parent = node.parent;\n\t var isLeftChild = node.isLeftChild();\n\t // Make node.right the new root of this sub tree (instead of node)\n\t var pivotNode = node.right;\n\t node.right = pivotNode.left;\n\t pivotNode.left = node;\n\t if (parent !== null) {\n\t if (isLeftChild) {\n\t parent.left = pivotNode;\n\t } else {\n\t parent.right = pivotNode;\n\t }\n\t } else {\n\t this._setRoot(pivotNode);\n\t }\n\t };\n\t /**\n\t\t * Rotate the tree to the right\n\t\t * @param {IntervalNode} node\n\t\t * @private\n\t\t */\n\t Tone.IntervalTimeline.prototype._rotateRight = function (node) {\n\t var parent = node.parent;\n\t var isLeftChild = node.isLeftChild();\n\t // Make node.left the new root of this sub tree (instead of node)\n\t var pivotNode = node.left;\n\t node.left = pivotNode.right;\n\t pivotNode.right = node;\n\t if (parent !== null) {\n\t if (isLeftChild) {\n\t parent.left = pivotNode;\n\t } else {\n\t parent.right = pivotNode;\n\t }\n\t } else {\n\t this._setRoot(pivotNode);\n\t }\n\t };\n\t /**\n\t\t * Balance the BST\n\t\t * @param {IntervalNode} node\n\t\t * @private\n\t\t */\n\t Tone.IntervalTimeline.prototype._rebalance = function (node) {\n\t var balance = node.getBalance();\n\t if (balance > 1) {\n\t if (node.left.getBalance() < 0) {\n\t this._rotateLeft(node.left);\n\t } else {\n\t this._rotateRight(node);\n\t }\n\t } else if (balance < -1) {\n\t if (node.right.getBalance() > 0) {\n\t this._rotateRight(node.right);\n\t } else {\n\t this._rotateLeft(node);\n\t }\n\t }\n\t };\n\t /**\n\t\t * Get an event whose time and duration span the give time. Will\n\t\t * return the match whose \"time\" value is closest to the given time.\n\t\t * @param {Object} event The event to add to the timeline\n\t\t * @return {Object} The event which spans the desired time\n\t\t */\n\t Tone.IntervalTimeline.prototype.get = function (time) {\n\t if (this._root !== null) {\n\t var results = [];\n\t this._root.search(time, results);\n\t if (results.length > 0) {\n\t var max = results[0];\n\t for (var i = 1; i < results.length; i++) {\n\t if (results[i].low > max.low) {\n\t max = results[i];\n\t }\n\t }\n\t return max.event;\n\t }\n\t }\n\t return null;\n\t };\n\t /**\n\t\t * Iterate over everything in the timeline.\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.forEach = function (callback) {\n\t if (this._root !== null) {\n\t var allNodes = [];\n\t this._root.traverse(function (node) {\n\t allNodes.push(node);\n\t });\n\t for (var i = 0; i < allNodes.length; i++) {\n\t var ev = allNodes[i].event;\n\t if (ev) {\n\t callback(ev);\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array in which the given time\n\t\t * overlaps with the time and duration time of the event.\n\t\t * @param {Number} time The time to check if items are overlapping\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.forEachAtTime = function (time, callback) {\n\t if (this._root !== null) {\n\t var results = [];\n\t this._root.search(time, results);\n\t for (var i = results.length - 1; i >= 0; i--) {\n\t var ev = results[i].event;\n\t if (ev) {\n\t callback(ev);\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array in which the time is greater\n\t\t * than or equal to the given time.\n\t\t * @param {Number} time The time to check if items are before\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.forEachFrom = function (time, callback) {\n\t if (this._root !== null) {\n\t var results = [];\n\t this._root.searchAfter(time, results);\n\t for (var i = results.length - 1; i >= 0; i--) {\n\t var ev = results[i].event;\n\t callback(ev);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.dispose = function () {\n\t var allNodes = [];\n\t if (this._root !== null) {\n\t this._root.traverse(function (node) {\n\t allNodes.push(node);\n\t });\n\t }\n\t for (var i = 0; i < allNodes.length; i++) {\n\t allNodes[i].dispose();\n\t }\n\t allNodes = null;\n\t this._root = null;\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tINTERVAL NODE HELPER\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Represents a node in the binary search tree, with the addition\n\t\t * of a \"high\" value which keeps track of the highest value of\n\t\t * its children.\n\t\t * References:\n\t\t * https://brooknovak.wordpress.com/2013/12/07/augmented-interval-tree-in-c/\n\t\t * http://www.mif.vu.lt/~valdas/ALGORITMAI/LITERATURA/Cormen/Cormen.pdf\n\t\t * @param {Number} low\n\t\t * @param {Number} high\n\t\t * @private\n\t\t */\n\t var IntervalNode = function (low, high, event) {\n\t //the event container\n\t this.event = event;\n\t //the low value\n\t this.low = low;\n\t //the high value\n\t this.high = high;\n\t //the high value for this and all child nodes\n\t this.max = this.high;\n\t //the nodes to the left\n\t this._left = null;\n\t //the nodes to the right\n\t this._right = null;\n\t //the parent node\n\t this.parent = null;\n\t //the number of child nodes\n\t this.height = 0;\n\t };\n\t /**\n\t\t * Insert a node into the correct spot in the tree\n\t\t * @param {IntervalNode} node\n\t\t */\n\t IntervalNode.prototype.insert = function (node) {\n\t if (node.low <= this.low) {\n\t if (this.left === null) {\n\t this.left = node;\n\t } else {\n\t this.left.insert(node);\n\t }\n\t } else if (this.right === null) {\n\t this.right = node;\n\t } else {\n\t this.right.insert(node);\n\t }\n\t };\n\t /**\n\t\t * Search the tree for nodes which overlap\n\t\t * with the given point\n\t\t * @param {Number} point The point to query\n\t\t * @param {Array} results The array to put the results\n\t\t */\n\t IntervalNode.prototype.search = function (point, results) {\n\t // If p is to the right of the rightmost point of any interval\n\t // in this node and all children, there won't be any matches.\n\t if (point > this.max) {\n\t return;\n\t }\n\t // Search left children\n\t if (this.left !== null) {\n\t this.left.search(point, results);\n\t }\n\t // Check this node\n\t if (this.low <= point && this.high > point) {\n\t results.push(this);\n\t }\n\t // If p is to the left of the time of this interval,\n\t // then it can't be in any child to the right.\n\t if (this.low > point) {\n\t return;\n\t }\n\t // Search right children\n\t if (this.right !== null) {\n\t this.right.search(point, results);\n\t }\n\t };\n\t /**\n\t\t * Search the tree for nodes which are less\n\t\t * than the given point\n\t\t * @param {Number} point The point to query\n\t\t * @param {Array} results The array to put the results\n\t\t */\n\t IntervalNode.prototype.searchAfter = function (point, results) {\n\t // Check this node\n\t if (this.low >= point) {\n\t results.push(this);\n\t if (this.left !== null) {\n\t this.left.searchAfter(point, results);\n\t }\n\t }\n\t // search the right side\n\t if (this.right !== null) {\n\t this.right.searchAfter(point, results);\n\t }\n\t };\n\t /**\n\t\t * Invoke the callback on this element and both it's branches\n\t\t * @param {Function} callback\n\t\t */\n\t IntervalNode.prototype.traverse = function (callback) {\n\t callback(this);\n\t if (this.left !== null) {\n\t this.left.traverse(callback);\n\t }\n\t if (this.right !== null) {\n\t this.right.traverse(callback);\n\t }\n\t };\n\t /**\n\t\t * Update the height of the node\n\t\t */\n\t IntervalNode.prototype.updateHeight = function () {\n\t if (this.left !== null && this.right !== null) {\n\t this.height = Math.max(this.left.height, this.right.height) + 1;\n\t } else if (this.right !== null) {\n\t this.height = this.right.height + 1;\n\t } else if (this.left !== null) {\n\t this.height = this.left.height + 1;\n\t } else {\n\t this.height = 0;\n\t }\n\t };\n\t /**\n\t\t * Update the height of the node\n\t\t */\n\t IntervalNode.prototype.updateMax = function () {\n\t this.max = this.high;\n\t if (this.left !== null) {\n\t this.max = Math.max(this.max, this.left.max);\n\t }\n\t if (this.right !== null) {\n\t this.max = Math.max(this.max, this.right.max);\n\t }\n\t };\n\t /**\n\t\t * The balance is how the leafs are distributed on the node\n\t\t * @return {Number} Negative numbers are balanced to the right\n\t\t */\n\t IntervalNode.prototype.getBalance = function () {\n\t var balance = 0;\n\t if (this.left !== null && this.right !== null) {\n\t balance = this.left.height - this.right.height;\n\t } else if (this.left !== null) {\n\t balance = this.left.height + 1;\n\t } else if (this.right !== null) {\n\t balance = -(this.right.height + 1);\n\t }\n\t return balance;\n\t };\n\t /**\n\t\t * @returns {Boolean} true if this node is the left child\n\t\t * of its parent\n\t\t */\n\t IntervalNode.prototype.isLeftChild = function () {\n\t return this.parent !== null && this.parent.left === this;\n\t };\n\t /**\n\t\t * get/set the left node\n\t\t * @type {IntervalNode}\n\t\t */\n\t Object.defineProperty(IntervalNode.prototype, 'left', {\n\t get: function () {\n\t return this._left;\n\t },\n\t set: function (node) {\n\t this._left = node;\n\t if (node !== null) {\n\t node.parent = this;\n\t }\n\t this.updateHeight();\n\t this.updateMax();\n\t }\n\t });\n\t /**\n\t\t * get/set the right node\n\t\t * @type {IntervalNode}\n\t\t */\n\t Object.defineProperty(IntervalNode.prototype, 'right', {\n\t get: function () {\n\t return this._right;\n\t },\n\t set: function (node) {\n\t this._right = node;\n\t if (node !== null) {\n\t node.parent = this;\n\t }\n\t this.updateHeight();\n\t this.updateMax();\n\t }\n\t });\n\t /**\n\t\t * null out references.\n\t\t */\n\t IntervalNode.prototype.dispose = function () {\n\t this.parent = null;\n\t this._left = null;\n\t this._right = null;\n\t this.event = null;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tEND INTERVAL NODE HELPER\n\t ///////////////////////////////////////////////////////////////////////////\n\t return Tone.IntervalTimeline;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Ticks is a primitive type for encoding Time values.\n\t\t * Tone.Ticks can be constructed with or without the `new` keyword. Tone.Ticks can be passed\n\t\t * into the parameter of any method which takes time as an argument.\n\t\t * @constructor\n\t\t * @extends {Tone.TransportTime}\n\t\t * @param {String|Number} val The time value.\n\t\t * @param {String=} units The units of the value.\n\t\t * @example\n\t\t * var t = Tone.Ticks(\"4n\");//a quarter note\n\t\t */\n\t Tone.Ticks = function (val, units) {\n\t if (this instanceof Tone.Ticks) {\n\t Tone.TransportTime.call(this, val, units);\n\t } else {\n\t return new Tone.Ticks(val, units);\n\t }\n\t };\n\t Tone.extend(Tone.Ticks, Tone.TransportTime);\n\t /**\n\t\t * The default units if none are given.\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t Tone.Ticks.prototype._defaultUnits = 'i';\n\t /**\n\t\t * Get the current time in the given units\n\t\t * @return {Ticks}\n\t\t * @private\n\t\t */\n\t Tone.Ticks.prototype._now = function () {\n\t return Tone.Transport.ticks;\n\t };\n\t /**\n\t\t * Return the value of the beats in the current units\n\t\t * @param {Number} beats\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Ticks.prototype._beatsToUnits = function (beats) {\n\t return this._getPPQ() * beats;\n\t };\n\t /**\n\t\t * Returns the value of a second in the current units\n\t\t * @param {Seconds} seconds\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Ticks.prototype._secondsToUnits = function (seconds) {\n\t return seconds / (60 / this._getBpm()) * this._getPPQ();\n\t };\n\t /**\n\t\t * Returns the value of a tick in the current time units\n\t\t * @param {Ticks} ticks\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Ticks.prototype._ticksToUnits = function (ticks) {\n\t return ticks;\n\t };\n\t /**\n\t\t * Return the time in ticks\n\t\t * @return {Ticks}\n\t\t */\n\t Tone.Ticks.prototype.toTicks = function () {\n\t return this.valueOf();\n\t };\n\t /**\n\t\t * Return the time in ticks\n\t\t * @return {Ticks}\n\t\t */\n\t Tone.Ticks.prototype.toSeconds = function () {\n\t return this.valueOf() / this._getPPQ() * (60 / this._getBpm());\n\t };\n\t return Tone.Ticks;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.TransportEvent is an internal class used by (Tone.Transport)[Transport]\n\t\t * to schedule events. Do no invoke this class directly, it is\n\t\t * handled from within Tone.Transport.\n\t\t * @extends {Tone}\n\t\t * @param {Object} options\n\t\t */\n\t Tone.TransportEvent = function (Transport, options) {\n\t options = Tone.defaultArg(options, Tone.TransportEvent.defaults);\n\t Tone.call(this);\n\t /**\n\t\t\t * Reference to the Transport that created it\n\t\t\t * @type {Tone.Transport}\n\t\t\t */\n\t this.Transport = Transport;\n\t /**\n\t\t\t * The unique id of the event\n\t\t\t * @type {Number}\n\t\t\t */\n\t this.id = Tone.TransportEvent._eventId++;\n\t /**\n\t\t\t * The time the event starts\n\t\t\t * @type {Ticks}\n\t\t\t */\n\t this.time = Tone.Ticks(options.time);\n\t /**\n\t\t\t * The callback to invoke\n\t\t\t * @type {Function}\n\t\t\t */\n\t this.callback = options.callback;\n\t /**\n\t\t\t * If the event should be removed after being created.\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t this._once = options.once;\n\t };\n\t Tone.extend(Tone.TransportEvent);\n\t /**\n\t\t * The defaults\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.TransportEvent.defaults = {\n\t 'once': false,\n\t 'callback': Tone.noOp\n\t };\n\t /**\n\t\t * Current ID counter\n\t\t * @private\n\t\t * @static\n\t\t * @type {Number}\n\t\t */\n\t Tone.TransportEvent._eventId = 0;\n\t /**\n\t\t * Invoke the event callback.\n\t\t * @param {Time} time The AudioContext time in seconds of the event\n\t\t */\n\t Tone.TransportEvent.prototype.invoke = function (time) {\n\t if (this.callback) {\n\t this.callback(time);\n\t if (this._once && this.Transport) {\n\t this.Transport.clear(this.id);\n\t }\n\t }\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.TransportEvent} this\n\t\t */\n\t Tone.TransportEvent.prototype.dispose = function () {\n\t Tone.prototype.dispose.call(this);\n\t this.Transport = null;\n\t this.callback = null;\n\t this.time = null;\n\t return this;\n\t };\n\t return Tone.TransportEvent;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.TransportRepeatEvent is an internal class used by Tone.Transport\n\t\t * to schedule repeat events. This class should not be instantiated directly.\n\t\t * @extends {Tone.TransportEvent}\n\t\t * @param {Object} options\n\t\t */\n\t Tone.TransportRepeatEvent = function (Transport, options) {\n\t Tone.TransportEvent.call(this, Transport, options);\n\t options = Tone.defaultArg(options, Tone.TransportRepeatEvent.defaults);\n\t /**\n\t\t\t * When the event should stop repeating\n\t\t\t * @type {Ticks}\n\t\t\t * @private\n\t\t\t */\n\t this.duration = Tone.Ticks(options.duration);\n\t /**\n\t\t\t * The interval of the repeated event\n\t\t\t * @type {Ticks}\n\t\t\t * @private\n\t\t\t */\n\t this._interval = Tone.Ticks(options.interval);\n\t /**\n\t\t\t * The ID of the current timeline event\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._currentId = -1;\n\t /**\n\t\t\t * The ID of the next timeline event\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._nextId = -1;\n\t /**\n\t\t\t * The time of the next event\n\t\t\t * @type {Ticks}\n\t\t\t * @private\n\t\t\t */\n\t this._nextTick = this.time;\n\t /**\n\t\t\t * a reference to the bound start method\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._boundRestart = this._restart.bind(this);\n\t this.Transport.on('start loopStart', this._boundRestart);\n\t this._restart();\n\t };\n\t Tone.extend(Tone.TransportRepeatEvent, Tone.TransportEvent);\n\t /**\n\t\t * The defaults\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.TransportRepeatEvent.defaults = {\n\t 'duration': Infinity,\n\t 'interval': 1\n\t };\n\t /**\n\t\t * Invoke the callback. Returns the tick time which\n\t\t * the next event should be scheduled at.\n\t\t * @param {Number} time The AudioContext time in seconds of the event\n\t\t */\n\t Tone.TransportRepeatEvent.prototype.invoke = function (time) {\n\t //create more events if necessary\n\t this._createEvents(time);\n\t //call the super class\n\t Tone.TransportEvent.prototype.invoke.call(this, time);\n\t };\n\t /**\n\t\t * Push more events onto the timeline to keep up with the position of the timeline\n\t\t * @private\n\t\t */\n\t Tone.TransportRepeatEvent.prototype._createEvents = function (time) {\n\t // schedule the next event\n\t var ticks = this.Transport.getTicksAtTime(time);\n\t if (ticks >= this.time && ticks >= this._nextTick && this._nextTick + this._interval < this.time + this.duration) {\n\t this._nextTick += this._interval;\n\t this._currentId = this._nextId;\n\t this._nextId = this.Transport.scheduleOnce(this.invoke.bind(this), Tone.Ticks(this._nextTick));\n\t }\n\t };\n\t /**\n\t\t * Push more events onto the timeline to keep up with the position of the timeline\n\t\t * @private\n\t\t */\n\t Tone.TransportRepeatEvent.prototype._restart = function (time) {\n\t this.Transport.clear(this._currentId);\n\t this.Transport.clear(this._nextId);\n\t this._nextTick = this.time;\n\t var ticks = this.Transport.getTicksAtTime(time);\n\t if (ticks > this.time) {\n\t this._nextTick = this.time + Math.ceil((ticks - this.time) / this._interval) * this._interval;\n\t }\n\t this._currentId = this.Transport.scheduleOnce(this.invoke.bind(this), Tone.Ticks(this._nextTick));\n\t this._nextTick += this._interval;\n\t this._nextId = this.Transport.scheduleOnce(this.invoke.bind(this), Tone.Ticks(this._nextTick));\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.TransportRepeatEvent} this\n\t\t */\n\t Tone.TransportRepeatEvent.prototype.dispose = function () {\n\t this.Transport.clear(this._currentId);\n\t this.Transport.clear(this._nextId);\n\t this.Transport.off('start loopStart', this._boundRestart);\n\t this._boundCreateEvents = null;\n\t Tone.TransportEvent.prototype.dispose.call(this);\n\t this.duration = null;\n\t this._interval = null;\n\t return this;\n\t };\n\t return Tone.TransportRepeatEvent;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Transport for timing musical events.\n\t\t * Supports tempo curves and time changes. Unlike browser-based timing (setInterval, requestAnimationFrame)\n\t\t * Tone.Transport timing events pass in the exact time of the scheduled event\n\t\t * in the argument of the callback function. Pass that time value to the object\n\t\t * you're scheduling. <br><br>\n\t\t * A single transport is created for you when the library is initialized.\n\t\t * <br><br>\n\t\t * The transport emits the events: \"start\", \"stop\", \"pause\", and \"loop\" which are\n\t\t * called with the time of that event as the argument.\n\t\t *\n\t\t * @extends {Tone.Emitter}\n\t\t * @singleton\n\t\t * @example\n\t\t * //repeated event every 8th note\n\t\t * Tone.Transport.scheduleRepeat(function(time){\n\t\t * \t//do something with the time\n\t\t * }, \"8n\");\n\t\t * @example\n\t\t * //schedule an event on the 16th measure\n\t\t * Tone.Transport.schedule(function(time){\n\t\t * \t//do something with the time\n\t\t * }, \"16:0:0\");\n\t\t */\n\t Tone.Transport = function () {\n\t Tone.Emitter.call(this);\n\t Tone.getContext(function () {\n\t ///////////////////////////////////////////////////////////////////////\n\t //\tLOOPING\n\t //////////////////////////////////////////////////////////////////////\n\t /**\n\t\t\t\t * \tIf the transport loops or not.\n\t\t\t\t * @type {boolean}\n\t\t\t\t */\n\t this.loop = false;\n\t /**\n\t\t\t\t * \tThe loop start position in ticks\n\t\t\t\t * @type {Ticks}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._loopStart = 0;\n\t /**\n\t\t\t\t * \tThe loop end position in ticks\n\t\t\t\t * @type {Ticks}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._loopEnd = 0;\n\t ///////////////////////////////////////////////////////////////////////\n\t //\tCLOCK/TEMPO\n\t //////////////////////////////////////////////////////////////////////\n\t /**\n\t\t\t\t * Pulses per quarter is the number of ticks per quarter note.\n\t\t\t\t * @private\n\t\t\t\t * @type {Number}\n\t\t\t\t */\n\t this._ppq = TransportConstructor.defaults.PPQ;\n\t /**\n\t\t\t\t * watches the main oscillator for timing ticks\n\t\t\t\t * initially starts at 120bpm\n\t\t\t\t * @private\n\t\t\t\t * @type {Tone.Clock}\n\t\t\t\t */\n\t this._clock = new Tone.Clock({\n\t 'callback': this._processTick.bind(this),\n\t 'frequency': 0\n\t });\n\t this._bindClockEvents();\n\t /**\n\t\t\t\t * The Beats Per Minute of the Transport.\n\t\t\t\t * @type {BPM}\n\t\t\t\t * @signal\n\t\t\t\t * @example\n\t\t\t\t * Tone.Transport.bpm.value = 80;\n\t\t\t\t * //ramp the bpm to 120 over 10 seconds\n\t\t\t\t * Tone.Transport.bpm.rampTo(120, 10);\n\t\t\t\t */\n\t this.bpm = this._clock.frequency;\n\t this.bpm._toUnits = this._toUnits.bind(this);\n\t this.bpm._fromUnits = this._fromUnits.bind(this);\n\t this.bpm.units = Tone.Type.BPM;\n\t this.bpm.value = TransportConstructor.defaults.bpm;\n\t this._readOnly('bpm');\n\t /**\n\t\t\t\t * The time signature, or more accurately the numerator\n\t\t\t\t * of the time signature over a denominator of 4.\n\t\t\t\t * @type {Number}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._timeSignature = TransportConstructor.defaults.timeSignature;\n\t ///////////////////////////////////////////////////////////////////////\n\t //\tTIMELINE EVENTS\n\t //////////////////////////////////////////////////////////////////////\n\t /**\n\t\t\t\t * All the events in an object to keep track by ID\n\t\t\t\t * @type {Object}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._scheduledEvents = {};\n\t /**\n\t\t\t\t * \tThe scheduled events.\n\t\t\t\t * @type {Tone.Timeline}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._timeline = new Tone.Timeline();\n\t /**\n\t\t\t\t * Repeated events\n\t\t\t\t * @type {Array}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._repeatedEvents = new Tone.IntervalTimeline();\n\t /**\n\t\t\t\t * All of the synced Signals\n\t\t\t\t * @private\n\t\t\t\t * @type {Array}\n\t\t\t\t */\n\t this._syncedSignals = [];\n\t ///////////////////////////////////////////////////////////////////////\n\t //\tSWING\n\t //////////////////////////////////////////////////////////////////////\n\t /**\n\t\t\t\t * The subdivision of the swing\n\t\t\t\t * @type {Ticks}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._swingTicks = TransportConstructor.defaults.PPQ / 2;\n\t //8n\n\t /**\n\t\t\t\t * The swing amount\n\t\t\t\t * @type {NormalRange}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._swingAmount = 0;\n\t }.bind(this));\n\t };\n\t Tone.extend(Tone.Transport, Tone.Emitter);\n\t /**\n\t\t * the defaults\n\t\t * @type {Object}\n\t\t * @const\n\t\t * @static\n\t\t */\n\t Tone.Transport.defaults = {\n\t 'bpm': 120,\n\t 'swing': 0,\n\t 'swingSubdivision': '8n',\n\t 'timeSignature': 4,\n\t 'loopStart': 0,\n\t 'loopEnd': '4m',\n\t 'PPQ': 192\n\t };\n\t ///////////////////////////////////////////////////////////////////////////////\n\t //\tTICKS\n\t ///////////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * called on every tick\n\t\t * @param {number} tickTime clock relative tick time\n\t\t * @private\n\t\t */\n\t Tone.Transport.prototype._processTick = function (tickTime, ticks) {\n\t //handle swing\n\t if (this._swingAmount > 0 && ticks % this._ppq !== 0 && //not on a downbeat\n\t ticks % (this._swingTicks * 2) !== 0) {\n\t //add some swing\n\t var progress = ticks % (this._swingTicks * 2) / (this._swingTicks * 2);\n\t var amount = Math.sin(progress * Math.PI) * this._swingAmount;\n\t tickTime += Tone.Ticks(this._swingTicks * 2 / 3).toSeconds() * amount;\n\t }\n\t //do the loop test\n\t if (this.loop) {\n\t if (ticks >= this._loopEnd) {\n\t this.emit('loopEnd', tickTime);\n\t this._clock.setTicksAtTime(this._loopStart, tickTime);\n\t ticks = this._loopStart;\n\t this.emit('loopStart', tickTime, this._clock.getSecondsAtTime(tickTime));\n\t this.emit('loop', tickTime);\n\t }\n\t }\n\t //invoke the timeline events scheduled on this tick\n\t this._timeline.forEachAtTime(ticks, function (event) {\n\t event.invoke(tickTime);\n\t });\n\t };\n\t ///////////////////////////////////////////////////////////////////////////////\n\t //\tSCHEDULABLE EVENTS\n\t ///////////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Schedule an event along the timeline.\n\t\t * @param {Function} callback The callback to be invoked at the time.\n\t\t * @param {TransportTime} time The time to invoke the callback at.\n\t\t * @return {Number} The id of the event which can be used for canceling the event.\n\t\t * @example\n\t\t * //trigger the callback when the Transport reaches the desired time\n\t\t * Tone.Transport.schedule(function(time){\n\t\t * \tenvelope.triggerAttack(time);\n\t\t * }, \"128i\");\n\t\t */\n\t Tone.Transport.prototype.schedule = function (callback, time) {\n\t var event = new Tone.TransportEvent(this, {\n\t 'time': Tone.TransportTime(time),\n\t 'callback': callback\n\t });\n\t return this._addEvent(event, this._timeline);\n\t };\n\t /**\n\t\t * Schedule a repeated event along the timeline. The event will fire\n\t\t * at the `interval` starting at the `startTime` and for the specified\n\t\t * `duration`.\n\t\t * @param {Function} callback The callback to invoke.\n\t\t * @param {Time} interval The duration between successive\n\t\t * callbacks. Must be a positive number.\n\t\t * @param {TransportTime=} startTime When along the timeline the events should\n\t\t * start being invoked.\n\t\t * @param {Time} [duration=Infinity] How long the event should repeat.\n\t\t * @return {Number} The ID of the scheduled event. Use this to cancel\n\t\t * the event.\n\t\t * @example\n\t\t * //a callback invoked every eighth note after the first measure\n\t\t * Tone.Transport.scheduleRepeat(callback, \"8n\", \"1m\");\n\t\t */\n\t Tone.Transport.prototype.scheduleRepeat = function (callback, interval, startTime, duration) {\n\t var event = new Tone.TransportRepeatEvent(this, {\n\t 'callback': callback,\n\t 'interval': Tone.Time(interval),\n\t 'time': Tone.TransportTime(startTime),\n\t 'duration': Tone.Time(Tone.defaultArg(duration, Infinity))\n\t });\n\t //kick it off if the Transport is started\n\t return this._addEvent(event, this._repeatedEvents);\n\t };\n\t /**\n\t\t * Schedule an event that will be removed after it is invoked.\n\t\t * Note that if the given time is less than the current transport time,\n\t\t * the event will be invoked immediately.\n\t\t * @param {Function} callback The callback to invoke once.\n\t\t * @param {TransportTime} time The time the callback should be invoked.\n\t\t * @returns {Number} The ID of the scheduled event.\n\t\t */\n\t Tone.Transport.prototype.scheduleOnce = function (callback, time) {\n\t var event = new Tone.TransportEvent(this, {\n\t 'time': Tone.TransportTime(time),\n\t 'callback': callback,\n\t 'once': true\n\t });\n\t return this._addEvent(event, this._timeline);\n\t };\n\t /**\n\t\t * Clear the passed in event id from the timeline\n\t\t * @param {Number} eventId The id of the event.\n\t\t * @returns {Tone.Transport} this\n\t\t */\n\t Tone.Transport.prototype.clear = function (eventId) {\n\t if (this._scheduledEvents.hasOwnProperty(eventId)) {\n\t var item = this._scheduledEvents[eventId.toString()];\n\t item.timeline.remove(item.event);\n\t item.event.dispose();\n\t delete this._scheduledEvents[eventId.toString()];\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Add an event to the correct timeline. Keep track of the\n\t\t * timeline it was added to.\n\t\t * @param {Tone.TransportEvent}\tevent\n\t\t * @param {Tone.Timeline} timeline\n\t\t * @returns {Number} the event id which was just added\n\t\t * @private\n\t\t */\n\t Tone.Transport.prototype._addEvent = function (event, timeline) {\n\t this._scheduledEvents[event.id.toString()] = {\n\t 'event': event,\n\t 'timeline': timeline\n\t };\n\t timeline.add(event);\n\t return event.id;\n\t };\n\t /**\n\t\t * Remove scheduled events from the timeline after\n\t\t * the given time. Repeated events will be removed\n\t\t * if their startTime is after the given time\n\t\t * @param {TransportTime} [after=0] Clear all events after\n\t\t * this time.\n\t\t * @returns {Tone.Transport} this\n\t\t */\n\t Tone.Transport.prototype.cancel = function (after) {\n\t after = Tone.defaultArg(after, 0);\n\t after = this.toTicks(after);\n\t this._timeline.forEachFrom(after, function (event) {\n\t this.clear(event.id);\n\t }.bind(this));\n\t this._repeatedEvents.forEachFrom(after, function (event) {\n\t this.clear(event.id);\n\t }.bind(this));\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////////\n\t //\tSTART/STOP/PAUSE\n\t ///////////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Bind start/stop/pause events from the clock and emit them.\n\t\t * @private\n\t\t */\n\t Tone.Transport.prototype._bindClockEvents = function () {\n\t this._clock.on('start', function (time, offset) {\n\t offset = Tone.Ticks(offset).toSeconds();\n\t this.emit('start', time, offset);\n\t }.bind(this));\n\t this._clock.on('stop', function (time) {\n\t this.emit('stop', time);\n\t }.bind(this));\n\t this._clock.on('pause', function (time) {\n\t this.emit('pause', time);\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Returns the playback state of the source, either \"started\", \"stopped\", or \"paused\"\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.Transport#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'state', {\n\t get: function () {\n\t return this._clock.getStateAtTime(this.now());\n\t }\n\t });\n\t /**\n\t\t * Start the transport and all sources synced to the transport.\n\t\t * @param {Time} [time=now] The time when the transport should start.\n\t\t * @param {TransportTime=} offset The timeline offset to start the transport.\n\t\t * @returns {Tone.Transport} this\n\t\t * @example\n\t\t * //start the transport in one second starting at beginning of the 5th measure.\n\t\t * Tone.Transport.start(\"+1\", \"4:0:0\");\n\t\t */\n\t Tone.Transport.prototype.start = function (time, offset) {\n\t //start the clock\n\t if (Tone.isDefined(offset)) {\n\t offset = this.toTicks(offset);\n\t }\n\t this._clock.start(time, offset);\n\t return this;\n\t };\n\t /**\n\t\t * Stop the transport and all sources synced to the transport.\n\t\t * @param {Time} [time=now] The time when the transport should stop.\n\t\t * @returns {Tone.Transport} this\n\t\t * @example\n\t\t * Tone.Transport.stop();\n\t\t */\n\t Tone.Transport.prototype.stop = function (time) {\n\t this._clock.stop(time);\n\t return this;\n\t };\n\t /**\n\t\t * Pause the transport and all sources synced to the transport.\n\t\t * @param {Time} [time=now]\n\t\t * @returns {Tone.Transport} this\n\t\t */\n\t Tone.Transport.prototype.pause = function (time) {\n\t this._clock.pause(time);\n\t return this;\n\t };\n\t /**\n\t\t * Toggle the current state of the transport. If it is\n\t\t * started, it will stop it, otherwise it will start the Transport.\n\t\t * @param {Time=} time The time of the event\n\t\t * @return {Tone.Transport} this\n\t\t */\n\t Tone.Transport.prototype.toggle = function (time) {\n\t time = this.toSeconds(time);\n\t if (this._clock.getStateAtTime(time) !== Tone.State.Started) {\n\t this.start(time);\n\t } else {\n\t this.stop(time);\n\t }\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////////\n\t //\tSETTERS/GETTERS\n\t ///////////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * The time signature as just the numerator over 4.\n\t\t * For example 4/4 would be just 4 and 6/8 would be 3.\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Number|Array}\n\t\t * @name timeSignature\n\t\t * @example\n\t\t * //common time\n\t\t * Tone.Transport.timeSignature = 4;\n\t\t * // 7/8\n\t\t * Tone.Transport.timeSignature = [7, 8];\n\t\t * //this will be reduced to a single number\n\t\t * Tone.Transport.timeSignature; //returns 3.5\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'timeSignature', {\n\t get: function () {\n\t return this._timeSignature;\n\t },\n\t set: function (timeSig) {\n\t if (Tone.isArray(timeSig)) {\n\t timeSig = timeSig[0] / timeSig[1] * 4;\n\t }\n\t this._timeSignature = timeSig;\n\t }\n\t });\n\t /**\n\t\t * When the Tone.Transport.loop = true, this is the starting position of the loop.\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Time}\n\t\t * @name loopStart\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'loopStart', {\n\t get: function () {\n\t return Tone.Ticks(this._loopStart).toSeconds();\n\t },\n\t set: function (startPosition) {\n\t this._loopStart = this.toTicks(startPosition);\n\t }\n\t });\n\t /**\n\t\t * When the Tone.Transport.loop = true, this is the ending position of the loop.\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Time}\n\t\t * @name loopEnd\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'loopEnd', {\n\t get: function () {\n\t return Tone.Ticks(this._loopEnd).toSeconds();\n\t },\n\t set: function (endPosition) {\n\t this._loopEnd = this.toTicks(endPosition);\n\t }\n\t });\n\t /**\n\t\t * Set the loop start and stop at the same time.\n\t\t * @param {TransportTime} startPosition\n\t\t * @param {TransportTime} endPosition\n\t\t * @returns {Tone.Transport} this\n\t\t * @example\n\t\t * //loop over the first measure\n\t\t * Tone.Transport.setLoopPoints(0, \"1m\");\n\t\t * Tone.Transport.loop = true;\n\t\t */\n\t Tone.Transport.prototype.setLoopPoints = function (startPosition, endPosition) {\n\t this.loopStart = startPosition;\n\t this.loopEnd = endPosition;\n\t return this;\n\t };\n\t /**\n\t\t * The swing value. Between 0-1 where 1 equal to\n\t\t * the note + half the subdivision.\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {NormalRange}\n\t\t * @name swing\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'swing', {\n\t get: function () {\n\t return this._swingAmount;\n\t },\n\t set: function (amount) {\n\t //scale the values to a normal range\n\t this._swingAmount = amount;\n\t }\n\t });\n\t /**\n\t\t * Set the subdivision which the swing will be applied to.\n\t\t * The default value is an 8th note. Value must be less\n\t\t * than a quarter note.\n\t\t *\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Time}\n\t\t * @name swingSubdivision\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'swingSubdivision', {\n\t get: function () {\n\t return Tone.Ticks(this._swingTicks).toNotation();\n\t },\n\t set: function (subdivision) {\n\t this._swingTicks = this.toTicks(subdivision);\n\t }\n\t });\n\t /**\n\t\t * The Transport's position in Bars:Beats:Sixteenths.\n\t\t * Setting the value will jump to that position right away.\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {BarsBeatsSixteenths}\n\t\t * @name position\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'position', {\n\t get: function () {\n\t var now = this.now();\n\t var ticks = this._clock.getTicksAtTime(now);\n\t return Tone.Ticks(ticks).toBarsBeatsSixteenths();\n\t },\n\t set: function (progress) {\n\t var ticks = this.toTicks(progress);\n\t this.ticks = ticks;\n\t }\n\t });\n\t /**\n\t\t * The Transport's position in seconds\n\t\t * Setting the value will jump to that position right away.\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Seconds}\n\t\t * @name seconds\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'seconds', {\n\t get: function () {\n\t return this._clock.seconds;\n\t },\n\t set: function (s) {\n\t var now = this.now();\n\t var ticks = this.bpm.timeToTicks(s, now);\n\t this.ticks = ticks;\n\t }\n\t });\n\t /**\n\t\t * The Transport's loop position as a normalized value. Always\n\t\t * returns 0 if the transport if loop is not true.\n\t\t * @memberOf Tone.Transport#\n\t\t * @name progress\n\t\t * @type {NormalRange}\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'progress', {\n\t get: function () {\n\t if (this.loop) {\n\t var now = this.now();\n\t var ticks = this._clock.getTicksAtTime(now);\n\t return (ticks - this._loopStart) / (this._loopEnd - this._loopStart);\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The transports current tick position.\n\t\t *\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Ticks}\n\t\t * @name ticks\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'ticks', {\n\t get: function () {\n\t return this._clock.ticks;\n\t },\n\t set: function (t) {\n\t if (this._clock.ticks !== t) {\n\t var now = this.now();\n\t //stop everything synced to the transport\n\t if (this.state === Tone.State.Started) {\n\t this.emit('stop', now);\n\t this._clock.setTicksAtTime(t, now);\n\t //restart it with the new time\n\t this.emit('start', now, this.seconds);\n\t } else {\n\t this._clock.setTicksAtTime(t, now);\n\t }\n\t }\n\t }\n\t });\n\t /**\n\t\t * Get the clock's ticks at the given time.\n\t\t * @param {Time} time When to get the tick value\n\t\t * @return {Ticks} The tick value at the given time.\n\t\t */\n\t Tone.Transport.prototype.getTicksAtTime = function (time) {\n\t return Math.round(this._clock.getTicksAtTime(time));\n\t };\n\t /**\n\t\t * Return the elapsed seconds at the given time.\n\t\t * @param {Time} time When to get the elapsed seconds\n\t\t * @return {Seconds} The number of elapsed seconds\n\t\t */\n\t Tone.Transport.prototype.getSecondsAtTime = function (time) {\n\t return this._clock.getSecondsAtTime(time);\n\t };\n\t /**\n\t\t * Pulses Per Quarter note. This is the smallest resolution\n\t\t * the Transport timing supports. This should be set once\n\t\t * on initialization and not set again. Changing this value\n\t\t * after other objects have been created can cause problems.\n\t\t *\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Number}\n\t\t * @name PPQ\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'PPQ', {\n\t get: function () {\n\t return this._ppq;\n\t },\n\t set: function (ppq) {\n\t var bpm = this.bpm.value;\n\t this._ppq = ppq;\n\t this.bpm.value = bpm;\n\t }\n\t });\n\t /**\n\t\t * Convert from BPM to frequency (factoring in PPQ)\n\t\t * @param {BPM} bpm The BPM value to convert to frequency\n\t\t * @return {Frequency} The BPM as a frequency with PPQ factored in.\n\t\t * @private\n\t\t */\n\t Tone.Transport.prototype._fromUnits = function (bpm) {\n\t return 1 / (60 / bpm / this.PPQ);\n\t };\n\t /**\n\t\t * Convert from frequency (with PPQ) into BPM\n\t\t * @param {Frequency} freq The clocks frequency to convert to BPM\n\t\t * @return {BPM} The frequency value as BPM.\n\t\t * @private\n\t\t */\n\t Tone.Transport.prototype._toUnits = function (freq) {\n\t return freq / this.PPQ * 60;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////////\n\t //\tSYNCING\n\t ///////////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Returns the time aligned to the next subdivision\n\t\t * of the Transport. If the Transport is not started,\n\t\t * it will return 0.\n\t\t * Note: this will not work precisely during tempo ramps.\n\t\t * @param {Time} subdivision The subdivision to quantize to\n\t\t * @return {Number} The context time of the next subdivision.\n\t\t * @example\n\t\t * Tone.Transport.start(); //the transport must be started\n\t\t * Tone.Transport.nextSubdivision(\"4n\");\n\t\t */\n\t Tone.Transport.prototype.nextSubdivision = function (subdivision) {\n\t subdivision = this.toTicks(subdivision);\n\t if (this.state !== Tone.State.Started) {\n\t //if the transport's not started, return 0\n\t return 0;\n\t } else {\n\t var now = this.now();\n\t //the remainder of the current ticks and the subdivision\n\t var transportPos = this.getTicksAtTime(now);\n\t var remainingTicks = subdivision - transportPos % subdivision;\n\t return this._clock.nextTickTime(remainingTicks, now);\n\t }\n\t };\n\t /**\n\t\t * Attaches the signal to the tempo control signal so that\n\t\t * any changes in the tempo will change the signal in the same\n\t\t * ratio.\n\t\t *\n\t\t * @param {Tone.Signal} signal\n\t\t * @param {number=} ratio Optionally pass in the ratio between\n\t\t * the two signals. Otherwise it will be computed\n\t\t * based on their current values.\n\t\t * @returns {Tone.Transport} this\n\t\t */\n\t Tone.Transport.prototype.syncSignal = function (signal, ratio) {\n\t if (!ratio) {\n\t //get the sync ratio\n\t var now = this.now();\n\t if (signal.getValueAtTime(now) !== 0) {\n\t ratio = signal.getValueAtTime(now) / this.bpm.getValueAtTime(now);\n\t } else {\n\t ratio = 0;\n\t }\n\t }\n\t var ratioSignal = new Tone.Gain(ratio);\n\t this.bpm.chain(ratioSignal, signal._param);\n\t this._syncedSignals.push({\n\t 'ratio': ratioSignal,\n\t 'signal': signal,\n\t 'initial': signal.value\n\t });\n\t signal.value = 0;\n\t return this;\n\t };\n\t /**\n\t\t * Unsyncs a previously synced signal from the transport's control.\n\t\t * See Tone.Transport.syncSignal.\n\t\t * @param {Tone.Signal} signal\n\t\t * @returns {Tone.Transport} this\n\t\t */\n\t Tone.Transport.prototype.unsyncSignal = function (signal) {\n\t for (var i = this._syncedSignals.length - 1; i >= 0; i--) {\n\t var syncedSignal = this._syncedSignals[i];\n\t if (syncedSignal.signal === signal) {\n\t syncedSignal.ratio.dispose();\n\t syncedSignal.signal.value = syncedSignal.initial;\n\t this._syncedSignals.splice(i, 1);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Transport} this\n\t\t * @private\n\t\t */\n\t Tone.Transport.prototype.dispose = function () {\n\t Tone.Emitter.prototype.dispose.call(this);\n\t this._clock.dispose();\n\t this._clock = null;\n\t this._writable('bpm');\n\t this.bpm = null;\n\t this._timeline.dispose();\n\t this._timeline = null;\n\t this._repeatedEvents.dispose();\n\t this._repeatedEvents = null;\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////////\n\t //\tINITIALIZATION\n\t ///////////////////////////////////////////////////////////////////////////////\n\t var TransportConstructor = Tone.Transport;\n\t Tone.Transport = new TransportConstructor();\n\t Tone.Context.on('init', function (context) {\n\t if (context.Transport instanceof TransportConstructor) {\n\t Tone.Transport = context.Transport;\n\t } else {\n\t Tone.Transport = new TransportConstructor();\n\t }\n\t //store the Transport on the context so it can be retrieved later\n\t context.Transport = Tone.Transport;\n\t });\n\t Tone.Context.on('close', function (context) {\n\t if (context.Transport instanceof TransportConstructor) {\n\t context.Transport.dispose();\n\t }\n\t });\n\t return Tone.Transport;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Volume is a simple volume node, useful for creating a volume fader.\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {Decibels} [volume=0] the initial volume\n\t\t * @example\n\t\t * var vol = new Tone.Volume(-12);\n\t\t * instrument.chain(vol, Tone.Master);\n\t\t */\n\t Tone.Volume = function () {\n\t var options = Tone.defaults(arguments, ['volume'], Tone.Volume);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * the output node\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.output = this.input = new Tone.Gain(options.volume, Tone.Type.Decibels);\n\t /**\n\t\t\t * The unmuted volume\n\t\t\t * @type {Decibels}\n\t\t\t * @private\n\t\t\t */\n\t this._unmutedVolume = options.volume;\n\t /**\n\t\t\t * The volume control in decibels.\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.volume = this.output.gain;\n\t this._readOnly('volume');\n\t //set the mute initially\n\t this.mute = options.mute;\n\t };\n\t Tone.extend(Tone.Volume, Tone.AudioNode);\n\t /**\n\t\t * Defaults\n\t\t * @type {Object}\n\t\t * @const\n\t\t * @static\n\t\t */\n\t Tone.Volume.defaults = {\n\t 'volume': 0,\n\t 'mute': false\n\t };\n\t /**\n\t\t * Mute the output.\n\t\t * @memberOf Tone.Volume#\n\t\t * @type {boolean}\n\t\t * @name mute\n\t\t * @example\n\t\t * //mute the output\n\t\t * volume.mute = true;\n\t\t */\n\t Object.defineProperty(Tone.Volume.prototype, 'mute', {\n\t get: function () {\n\t return this.volume.value === -Infinity;\n\t },\n\t set: function (mute) {\n\t if (!this.mute && mute) {\n\t this._unmutedVolume = this.volume.value;\n\t //maybe it should ramp here?\n\t this.volume.value = -Infinity;\n\t } else if (this.mute && !mute) {\n\t this.volume.value = this._unmutedVolume;\n\t }\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Volume} this\n\t\t */\n\t Tone.Volume.prototype.dispose = function () {\n\t this.input.dispose();\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable('volume');\n\t this.volume.dispose();\n\t this.volume = null;\n\t return this;\n\t };\n\t return Tone.Volume;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A single master output which is connected to the\n\t\t * AudioDestinationNode (aka your speakers).\n\t\t * It provides useful conveniences such as the ability\n\t\t * to set the volume and mute the entire application.\n\t\t * It also gives you the ability to apply master effects to your application.\n\t\t * <br><br>\n\t\t * Like Tone.Transport, A single Tone.Master is created\n\t\t * on initialization and you do not need to explicitly construct one.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone}\n\t\t * @singleton\n\t\t * @example\n\t\t * //the audio will go from the oscillator to the speakers\n\t\t * oscillator.connect(Tone.Master);\n\t\t * //a convenience for connecting to the master output is also provided:\n\t\t * oscillator.toMaster();\n\t\t * //the above two examples are equivalent.\n\t\t */\n\t Tone.Master = function () {\n\t Tone.AudioNode.call(this);\n\t Tone.getContext(function () {\n\t this.createInsOuts(1, 0);\n\t /**\n\t\t\t\t * The private volume node\n\t\t\t\t * @type {Tone.Volume}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._volume = this.output = new Tone.Volume();\n\t /**\n\t\t\t\t * The volume of the master output.\n\t\t\t\t * @type {Decibels}\n\t\t\t\t * @signal\n\t\t\t\t */\n\t this.volume = this._volume.volume;\n\t this._readOnly('volume');\n\t //connections\n\t this.input.chain(this.output, this.context.destination);\n\t }.bind(this));\n\t };\n\t Tone.extend(Tone.Master, Tone.AudioNode);\n\t /**\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Master.defaults = {\n\t 'volume': 0,\n\t 'mute': false\n\t };\n\t /**\n\t\t * Mute the output.\n\t\t * @memberOf Tone.Master#\n\t\t * @type {boolean}\n\t\t * @name mute\n\t\t * @example\n\t\t * //mute the output\n\t\t * Tone.Master.mute = true;\n\t\t */\n\t Object.defineProperty(Tone.Master.prototype, 'mute', {\n\t get: function () {\n\t return this._volume.mute;\n\t },\n\t set: function (mute) {\n\t this._volume.mute = mute;\n\t }\n\t });\n\t /**\n\t\t * Add a master effects chain. NOTE: this will disconnect any nodes which were previously\n\t\t * chained in the master effects chain.\n\t\t * @param {AudioNode|Tone} args... All arguments will be connected in a row\n\t\t * and the Master will be routed through it.\n\t\t * @return {Tone.Master} this\n\t\t * @example\n\t\t * //some overall compression to keep the levels in check\n\t\t * var masterCompressor = new Tone.Compressor({\n\t\t * \t\"threshold\" : -6,\n\t\t * \t\"ratio\" : 3,\n\t\t * \t\"attack\" : 0.5,\n\t\t * \t\"release\" : 0.1\n\t\t * });\n\t\t * //give a little boost to the lows\n\t\t * var lowBump = new Tone.Filter(200, \"lowshelf\");\n\t\t * //route everything through the filter\n\t\t * //and compressor before going to the speakers\n\t\t * Tone.Master.chain(lowBump, masterCompressor);\n\t\t */\n\t Tone.Master.prototype.chain = function () {\n\t this.input.disconnect();\n\t this.input.chain.apply(this.input, arguments);\n\t arguments[arguments.length - 1].connect(this.output);\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Master} this\n\t\t */\n\t Tone.Master.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable('volume');\n\t this._volume.dispose();\n\t this._volume = null;\n\t this.volume = null;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tAUGMENT TONE's PROTOTYPE\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Connect 'this' to the master output. Shorthand for this.connect(Tone.Master)\n\t\t * @returns {Tone.AudioNode} this\n\t\t * @example\n\t\t * //connect an oscillator to the master output\n\t\t * var osc = new Tone.Oscillator().toMaster();\n\t\t */\n\t Tone.AudioNode.prototype.toMaster = function () {\n\t this.connect(Tone.Master);\n\t return this;\n\t };\n\t if (window.AudioNode) {\n\t // Also augment AudioNode's prototype to include toMaster as a convenience\n\t AudioNode.prototype.toMaster = function () {\n\t this.connect(Tone.Master);\n\t return this;\n\t };\n\t }\n\t /**\n\t\t * initialize the module and listen for new audio contexts\n\t\t */\n\t var MasterConstructor = Tone.Master;\n\t Tone.Master = new MasterConstructor();\n\t Tone.Context.on('init', function (context) {\n\t // if it already exists, just restore it\n\t if (context.Master instanceof MasterConstructor) {\n\t Tone.Master = context.Master;\n\t } else {\n\t Tone.Master = new MasterConstructor();\n\t }\n\t context.Master = Tone.Master;\n\t });\n\t Tone.Context.on('close', function (context) {\n\t if (context.Master instanceof MasterConstructor) {\n\t context.Master.dispose();\n\t }\n\t });\n\t return Tone.Master;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Base class for sources. Sources have start/stop methods\n\t\t * and the ability to be synced to the\n\t\t * start/stop of Tone.Transport.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @example\n\t\t * //Multiple state change events can be chained together,\n\t\t * //but must be set in the correct order and with ascending times\n\t\t *\n\t\t * // OK\n\t\t * state.start().stop(\"+0.2\");\n\t\t * // AND\n\t\t * state.start().stop(\"+0.2\").start(\"+0.4\").stop(\"+0.7\")\n\t\t *\n\t\t * // BAD\n\t\t * state.stop(\"+0.2\").start();\n\t\t * // OR\n\t\t * state.start(\"+0.3\").stop(\"+0.2\");\n\t\t *\n\t\t */\n\t Tone.Source = function (options) {\n\t options = Tone.defaultArg(options, Tone.Source.defaults);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The output volume node\n\t\t\t * @type {Tone.Volume}\n\t\t\t * @private\n\t\t\t */\n\t this._volume = this.output = new Tone.Volume(options.volume);\n\t /**\n\t\t\t * The volume of the output in decibels.\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * source.volume.value = -6;\n\t\t\t */\n\t this.volume = this._volume.volume;\n\t this._readOnly('volume');\n\t /**\n\t\t\t * \tKeep track of the scheduled state.\n\t\t\t * @type {Tone.TimelineState}\n\t\t\t * @private\n\t\t\t */\n\t this._state = new Tone.TimelineState(Tone.State.Stopped);\n\t this._state.memory = 100;\n\t /**\n\t\t\t * The synced `start` callback function from the transport\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._synced = false;\n\t /**\n\t\t\t * Keep track of all of the scheduled event ids\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._scheduled = [];\n\t //make the output explicitly stereo\n\t this._volume.output.output.channelCount = 2;\n\t this._volume.output.output.channelCountMode = 'explicit';\n\t //mute initially\n\t this.mute = options.mute;\n\t };\n\t Tone.extend(Tone.Source, Tone.AudioNode);\n\t /**\n\t\t * The default parameters\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Source.defaults = {\n\t 'volume': 0,\n\t 'mute': false\n\t };\n\t /**\n\t\t * Returns the playback state of the source, either \"started\" or \"stopped\".\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.Source#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.Source.prototype, 'state', {\n\t get: function () {\n\t if (this._synced) {\n\t if (Tone.Transport.state === Tone.State.Started) {\n\t return this._state.getValueAtTime(Tone.Transport.seconds);\n\t } else {\n\t return Tone.State.Stopped;\n\t }\n\t } else {\n\t return this._state.getValueAtTime(this.now());\n\t }\n\t }\n\t });\n\t /**\n\t\t * Mute the output.\n\t\t * @memberOf Tone.Source#\n\t\t * @type {boolean}\n\t\t * @name mute\n\t\t * @example\n\t\t * //mute the output\n\t\t * source.mute = true;\n\t\t */\n\t Object.defineProperty(Tone.Source.prototype, 'mute', {\n\t get: function () {\n\t return this._volume.mute;\n\t },\n\t set: function (mute) {\n\t this._volume.mute = mute;\n\t }\n\t });\n\t //overwrite these functions\n\t Tone.Source.prototype._start = Tone.noOp;\n\t Tone.Source.prototype.restart = Tone.noOp;\n\t Tone.Source.prototype._stop = Tone.noOp;\n\t /**\n\t\t * Start the source at the specified time. If no time is given,\n\t\t * start the source now.\n\t\t * @param {Time} [time=now] When the source should be started.\n\t\t * @returns {Tone.Source} this\n\t\t * @example\n\t\t * source.start(\"+0.5\"); //starts the source 0.5 seconds from now\n\t\t */\n\t Tone.Source.prototype.start = function (time, offset, duration) {\n\t if (Tone.isUndef(time) && this._synced) {\n\t time = Tone.Transport.seconds;\n\t } else {\n\t time = this.toSeconds(time);\n\t }\n\t //if it's started, stop it and restart it\n\t if (this._state.getValueAtTime(time) === Tone.State.Started) {\n\t this._state.cancel(time);\n\t this._state.setStateAtTime(Tone.State.Started, time);\n\t this.restart(time, offset, duration);\n\t } else {\n\t this._state.setStateAtTime(Tone.State.Started, time);\n\t if (this._synced) {\n\t // add the offset time to the event\n\t var event = this._state.get(time);\n\t event.offset = Tone.defaultArg(offset, 0);\n\t event.duration = duration;\n\t var sched = Tone.Transport.schedule(function (t) {\n\t this._start(t, offset, duration);\n\t }.bind(this), time);\n\t this._scheduled.push(sched);\n\t //if it's already started\n\t if (Tone.Transport.state === Tone.State.Started) {\n\t this._syncedStart(this.now(), Tone.Transport.seconds);\n\t }\n\t } else {\n\t this._start.apply(this, arguments);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Stop the source at the specified time. If no time is given,\n\t\t * stop the source now.\n\t\t * @param {Time} [time=now] When the source should be stopped.\n\t\t * @returns {Tone.Source} this\n\t\t * @example\n\t\t * source.stop(); // stops the source immediately\n\t\t */\n\t Tone.Source.prototype.stop = function (time) {\n\t if (Tone.isUndef(time) && this._synced) {\n\t time = Tone.Transport.seconds;\n\t } else {\n\t time = this.toSeconds(time);\n\t }\n\t if (!this._synced) {\n\t this._stop.apply(this, arguments);\n\t } else {\n\t var sched = Tone.Transport.schedule(this._stop.bind(this), time);\n\t this._scheduled.push(sched);\n\t }\n\t this._state.cancel(time);\n\t this._state.setStateAtTime(Tone.State.Stopped, time);\n\t return this;\n\t };\n\t /**\n\t\t * Sync the source to the Transport so that all subsequent\n\t\t * calls to `start` and `stop` are synced to the TransportTime\n\t\t * instead of the AudioContext time.\n\t\t *\n\t\t * @returns {Tone.Source} this\n\t\t * @example\n\t\t * //sync the source so that it plays between 0 and 0.3 on the Transport's timeline\n\t\t * source.sync().start(0).stop(0.3);\n\t\t * //start the transport.\n\t\t * Tone.Transport.start();\n\t\t *\n\t\t * @example\n\t\t * //start the transport with an offset and the sync'ed sources\n\t\t * //will start in the correct position\n\t\t * source.sync().start(0.1);\n\t\t * //the source will be invoked with an offset of 0.4\n\t\t * Tone.Transport.start(\"+0.5\", 0.5);\n\t\t */\n\t Tone.Source.prototype.sync = function () {\n\t this._synced = true;\n\t this._syncedStart = function (time, offset) {\n\t if (offset > 0) {\n\t // get the playback state at that time\n\t var stateEvent = this._state.get(offset);\n\t // listen for start events which may occur in the middle of the sync'ed time\n\t if (stateEvent && stateEvent.state === Tone.State.Started && stateEvent.time !== offset) {\n\t // get the offset\n\t var startOffset = offset - this.toSeconds(stateEvent.time);\n\t var duration;\n\t if (stateEvent.duration) {\n\t duration = this.toSeconds(stateEvent.duration) - startOffset;\n\t }\n\t this._start(time, this.toSeconds(stateEvent.offset) + startOffset, duration);\n\t }\n\t }\n\t }.bind(this);\n\t this._syncedStop = function (time) {\n\t var seconds = Tone.Transport.getSecondsAtTime(Math.max(time - this.sampleTime, 0));\n\t if (this._state.getValueAtTime(seconds) === Tone.State.Started) {\n\t this._stop(time);\n\t }\n\t }.bind(this);\n\t Tone.Transport.on('start loopStart', this._syncedStart);\n\t Tone.Transport.on('stop pause loopEnd', this._syncedStop);\n\t return this;\n\t };\n\t /**\n\t\t * Unsync the source to the Transport. See Tone.Source.sync\n\t\t * @returns {Tone.Source} this\n\t\t */\n\t Tone.Source.prototype.unsync = function () {\n\t if (this._synced) {\n\t Tone.Transport.off('stop pause loopEnd', this._syncedStop);\n\t Tone.Transport.off('start loopStart', this._syncedStart);\n\t }\n\t this._synced = false;\n\t // clear all of the scheduled ids\n\t for (var i = 0; i < this._scheduled.length; i++) {\n\t var id = this._scheduled[i];\n\t Tone.Transport.clear(id);\n\t }\n\t this._scheduled = [];\n\t this._state.cancel(0);\n\t return this;\n\t };\n\t /**\n\t\t *\tClean up.\n\t\t * @return {Tone.Source} this\n\t\t */\n\t Tone.Source.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.unsync();\n\t this._scheduled = null;\n\t this._writable('volume');\n\t this._volume.dispose();\n\t this._volume = null;\n\t this.volume = null;\n\t this._state.dispose();\n\t this._state = null;\n\t };\n\t return Tone.Source;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * AudioBuffer.copyTo/FromChannel polyfill\n\t\t * @private\n\t\t */\n\t if (Tone.supported) {\n\t if (!AudioBuffer.prototype.copyToChannel) {\n\t AudioBuffer.prototype.copyToChannel = function (src, chanNum, start) {\n\t var channel = this.getChannelData(chanNum);\n\t start = start || 0;\n\t for (var i = 0; i < channel.length; i++) {\n\t channel[i + start] = src[i];\n\t }\n\t };\n\t AudioBuffer.prototype.copyFromChannel = function (dest, chanNum, start) {\n\t var channel = this.getChannelData(chanNum);\n\t start = start || 0;\n\t for (var i = 0; i < dest.length; i++) {\n\t dest[i] = channel[i + start];\n\t }\n\t };\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Buffer loading and storage. Tone.Buffer is used internally by all\n\t\t * classes that make requests for audio files such as Tone.Player,\n\t\t * Tone.Sampler and Tone.Convolver.\n\t\t *\n\t\t * Aside from load callbacks from individual buffers, Tone.Buffer\n\t\t * \t\tprovides events which keep track of the loading progress\n\t\t * \t\tof _all_ of the buffers. These are Tone.Buffer.on(\"load\" / \"progress\" / \"error\")\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone}\n\t\t * @param {AudioBuffer|String} url The url to load, or the audio buffer to set.\n\t\t * @param {Function=} onload A callback which is invoked after the buffer is loaded.\n\t\t * It's recommended to use `Tone.Buffer.on('load', callback)` instead\n\t\t * since it will give you a callback when _all_ buffers are loaded.\n\t\t * @param {Function=} onerror The callback to invoke if there is an error\n\t\t * @example\n\t\t * var buffer = new Tone.Buffer(\"path/to/sound.mp3\", function(){\n\t\t * \t//the buffer is now available.\n\t\t * \tvar buff = buffer.get();\n\t\t * });\n\t\t * @example\n\t\t * //can load provide fallback extension types if the first type is not supported.\n\t\t * var buffer = new Tone.Buffer(\"path/to/sound.[mp3|ogg|wav]\");\n\t\t */\n\t Tone.Buffer = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'url',\n\t 'onload',\n\t 'onerror'\n\t ], Tone.Buffer);\n\t Tone.call(this);\n\t /**\n\t\t\t * stores the loaded AudioBuffer\n\t\t\t * @type {AudioBuffer}\n\t\t\t * @private\n\t\t\t */\n\t this._buffer = null;\n\t /**\n\t\t\t * indicates if the buffer should be reversed or not\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t this._reversed = options.reverse;\n\t /**\n\t\t\t * The XHR\n\t\t\t * @type {XMLHttpRequest}\n\t\t\t * @private\n\t\t\t */\n\t this._xhr = null;\n\t /**\n\t\t\t * Private callback when the buffer is loaded.\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._onload = Tone.noOp;\n\t if (options.url instanceof AudioBuffer || options.url instanceof Tone.Buffer) {\n\t this.set(options.url);\n\t // invoke the onload callback\n\t if (options.onload) {\n\t if (this.loaded) {\n\t options.onload(this);\n\t } else {\n\t this._onload = options.onload;\n\t }\n\t }\n\t } else if (Tone.isString(options.url)) {\n\t this.load(options.url).then(options.onload).catch(options.onerror);\n\t }\n\t };\n\t Tone.extend(Tone.Buffer);\n\t /**\n\t\t * the default parameters\n\t\t * @type {Object}\n\t\t */\n\t Tone.Buffer.defaults = {\n\t 'url': undefined,\n\t 'reverse': false,\n\t 'onload': Tone.noOp,\n\t 'onerror': Tone.noOp\n\t };\n\t /**\n\t\t * Pass in an AudioBuffer or Tone.Buffer to set the value\n\t\t * of this buffer.\n\t\t * @param {AudioBuffer|Tone.Buffer} buffer the buffer\n\t\t * @returns {Tone.Buffer} this\n\t\t */\n\t Tone.Buffer.prototype.set = function (buffer) {\n\t if (buffer instanceof Tone.Buffer) {\n\t if (buffer.loaded) {\n\t this._buffer = buffer.get();\n\t } else {\n\t buffer._onload = function () {\n\t this.set(buffer);\n\t this._onload(this);\n\t }.bind(this);\n\t }\n\t } else {\n\t this._buffer = buffer;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * @return {AudioBuffer} The audio buffer stored in the object.\n\t\t */\n\t Tone.Buffer.prototype.get = function () {\n\t return this._buffer;\n\t };\n\t /**\n\t\t * Makes an xhr reqest for the selected url then decodes\n\t\t * the file as an audio buffer. Invokes\n\t\t * the callback once the audio buffer loads.\n\t\t * @param {String} url The url of the buffer to load.\n\t\t * filetype support depends on the\n\t\t * browser.\n\t\t * @returns {Promise} returns a Promise which resolves with the Tone.Buffer\n\t\t */\n\t Tone.Buffer.prototype.load = function (url, onload, onerror) {\n\t var promise = new Promise(function (load, error) {\n\t this._xhr = Tone.Buffer.load(url, //success\n\t function (buff) {\n\t this._xhr = null;\n\t this.set(buff);\n\t load(this);\n\t this._onload(this);\n\t if (onload) {\n\t onload(this);\n\t }\n\t }.bind(this), //error\n\t function (err) {\n\t this._xhr = null;\n\t error(err);\n\t if (onerror) {\n\t onerror(err);\n\t }\n\t }.bind(this));\n\t }.bind(this));\n\t return promise;\n\t };\n\t /**\n\t\t * dispose and disconnect\n\t\t * @returns {Tone.Buffer} this\n\t\t */\n\t Tone.Buffer.prototype.dispose = function () {\n\t Tone.prototype.dispose.call(this);\n\t this._buffer = null;\n\t if (this._xhr) {\n\t Tone.Buffer._removeFromDownloadQueue(this._xhr);\n\t this._xhr.abort();\n\t this._xhr = null;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * If the buffer is loaded or not\n\t\t * @memberOf Tone.Buffer#\n\t\t * @type {Boolean}\n\t\t * @name loaded\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Buffer.prototype, 'loaded', {\n\t get: function () {\n\t return this.length > 0;\n\t }\n\t });\n\t /**\n\t\t * The duration of the buffer.\n\t\t * @memberOf Tone.Buffer#\n\t\t * @type {Number}\n\t\t * @name duration\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Buffer.prototype, 'duration', {\n\t get: function () {\n\t if (this._buffer) {\n\t return this._buffer.duration;\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The length of the buffer in samples\n\t\t * @memberOf Tone.Buffer#\n\t\t * @type {Number}\n\t\t * @name length\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Buffer.prototype, 'length', {\n\t get: function () {\n\t if (this._buffer) {\n\t return this._buffer.length;\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The number of discrete audio channels. Returns 0 if no buffer\n\t\t * is loaded.\n\t\t * @memberOf Tone.Buffer#\n\t\t * @type {Number}\n\t\t * @name numberOfChannels\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Buffer.prototype, 'numberOfChannels', {\n\t get: function () {\n\t if (this._buffer) {\n\t return this._buffer.numberOfChannels;\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Set the audio buffer from the array. To create a multichannel AudioBuffer,\n\t\t * pass in a multidimensional array.\n\t\t * @param {Float32Array} array The array to fill the audio buffer\n\t\t * @return {Tone.Buffer} this\n\t\t */\n\t Tone.Buffer.prototype.fromArray = function (array) {\n\t var isMultidimensional = array[0].length > 0;\n\t var channels = isMultidimensional ? array.length : 1;\n\t var len = isMultidimensional ? array[0].length : array.length;\n\t var buffer = this.context.createBuffer(channels, len, this.context.sampleRate);\n\t if (!isMultidimensional && channels === 1) {\n\t array = [array];\n\t }\n\t for (var c = 0; c < channels; c++) {\n\t buffer.copyToChannel(array[c], c);\n\t }\n\t this._buffer = buffer;\n\t return this;\n\t };\n\t /**\n\t\t * \tSums muliple channels into 1 channel\n\t\t * @param {Number=} channel Optionally only copy a single channel from the array.\n\t\t * @return {Array}\n\t\t */\n\t Tone.Buffer.prototype.toMono = function (chanNum) {\n\t if (Tone.isNumber(chanNum)) {\n\t this.fromArray(this.toArray(chanNum));\n\t } else {\n\t var outputArray = new Float32Array(this.length);\n\t var numChannels = this.numberOfChannels;\n\t for (var channel = 0; channel < numChannels; channel++) {\n\t var channelArray = this.toArray(channel);\n\t for (var i = 0; i < channelArray.length; i++) {\n\t outputArray[i] += channelArray[i];\n\t }\n\t }\n\t //divide by the number of channels\n\t outputArray = outputArray.map(function (sample) {\n\t return sample / numChannels;\n\t });\n\t this.fromArray(outputArray);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * \tGet the buffer as an array. Single channel buffers will return a 1-dimensional\n\t\t * \tFloat32Array, and multichannel buffers will return multidimensional arrays.\n\t\t * @param {Number=} channel Optionally only copy a single channel from the array.\n\t\t * @return {Array}\n\t\t */\n\t Tone.Buffer.prototype.toArray = function (channel) {\n\t if (Tone.isNumber(channel)) {\n\t return this.getChannelData(channel);\n\t } else if (this.numberOfChannels === 1) {\n\t return this.toArray(0);\n\t } else {\n\t var ret = [];\n\t for (var c = 0; c < this.numberOfChannels; c++) {\n\t ret[c] = this.getChannelData(c);\n\t }\n\t return ret;\n\t }\n\t };\n\t /**\n\t\t * Returns the Float32Array representing the PCM audio data for the specific channel.\n\t\t * @param {Number} channel The channel number to return\n\t\t * @return {Float32Array} The audio as a TypedArray\n\t\t */\n\t Tone.Buffer.prototype.getChannelData = function (channel) {\n\t return this._buffer.getChannelData(channel);\n\t };\n\t /**\n\t\t * Cut a subsection of the array and return a buffer of the\n\t\t * subsection. Does not modify the original buffer\n\t\t * @param {Time} start The time to start the slice\n\t\t * @param {Time=} end The end time to slice. If none is given\n\t\t * will default to the end of the buffer\n\t\t * @return {Tone.Buffer} this\n\t\t */\n\t Tone.Buffer.prototype.slice = function (start, end) {\n\t end = Tone.defaultArg(end, this.duration);\n\t var startSamples = Math.floor(this.context.sampleRate * this.toSeconds(start));\n\t var endSamples = Math.floor(this.context.sampleRate * this.toSeconds(end));\n\t var replacement = [];\n\t for (var i = 0; i < this.numberOfChannels; i++) {\n\t replacement[i] = this.toArray(i).slice(startSamples, endSamples);\n\t }\n\t var retBuffer = new Tone.Buffer().fromArray(replacement);\n\t return retBuffer;\n\t };\n\t /**\n\t\t * Reverse the buffer.\n\t\t * @private\n\t\t * @return {Tone.Buffer} this\n\t\t */\n\t Tone.Buffer.prototype._reverse = function () {\n\t if (this.loaded) {\n\t for (var i = 0; i < this.numberOfChannels; i++) {\n\t Array.prototype.reverse.call(this.getChannelData(i));\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Reverse the buffer.\n\t\t * @memberOf Tone.Buffer#\n\t\t * @type {Boolean}\n\t\t * @name reverse\n\t\t */\n\t Object.defineProperty(Tone.Buffer.prototype, 'reverse', {\n\t get: function () {\n\t return this._reversed;\n\t },\n\t set: function (rev) {\n\t if (this._reversed !== rev) {\n\t this._reversed = rev;\n\t this._reverse();\n\t }\n\t }\n\t });\n\t ///////////////////////////////////////////////////////////////////////////\n\t // STATIC METHODS\n\t ///////////////////////////////////////////////////////////////////////////\n\t //statically inherits Emitter methods\n\t Tone.Emitter.mixin(Tone.Buffer);\n\t /**\n\t\t * the static queue for all of the xhr requests\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t Tone.Buffer._downloadQueue = [];\n\t /**\n\t\t * A path which is prefixed before every url.\n\t\t * @type {String}\n\t\t * @static\n\t\t */\n\t Tone.Buffer.baseUrl = '';\n\t /**\n\t\t * Create a Tone.Buffer from the array. To create a multichannel AudioBuffer,\n\t\t * pass in a multidimensional array.\n\t\t * @param {Float32Array} array The array to fill the audio buffer\n\t\t * @return {Tone.Buffer} A Tone.Buffer created from the array\n\t\t */\n\t Tone.Buffer.fromArray = function (array) {\n\t return new Tone.Buffer().fromArray(array);\n\t };\n\t /**\n\t\t * Creates a Tone.Buffer from a URL, returns a promise\n\t\t * which resolves to a Tone.Buffer\n\t\t * @param {String} url The url to load.\n\t\t * @return {Promise<Tone.Buffer>} A promise which resolves to a Tone.Buffer\n\t\t */\n\t Tone.Buffer.fromUrl = function (url) {\n\t var buffer = new Tone.Buffer();\n\t return buffer.load(url).then(function () {\n\t return buffer;\n\t });\n\t };\n\t /**\n\t\t * Remove an xhr request from the download queue\n\t\t * @private\n\t\t */\n\t Tone.Buffer._removeFromDownloadQueue = function (request) {\n\t var index = Tone.Buffer._downloadQueue.indexOf(request);\n\t if (index !== -1) {\n\t Tone.Buffer._downloadQueue.splice(index, 1);\n\t }\n\t };\n\t /**\n\t\t * Loads a url using XMLHttpRequest.\n\t\t * @param {String} url\n\t\t * @param {Function} onload\n\t\t * @param {Function} onerror\n\t\t * @param {Function} onprogress\n\t\t * @return {XMLHttpRequest}\n\t\t */\n\t Tone.Buffer.load = function (url, onload, onerror) {\n\t //default\n\t onload = Tone.defaultArg(onload, Tone.noOp);\n\t // test if the url contains multiple extensions\n\t var matches = url.match(/\\[(.+\\|?)+\\]$/);\n\t if (matches) {\n\t var extensions = matches[1].split('|');\n\t var extension = extensions[0];\n\t for (var i = 0; i < extensions.length; i++) {\n\t if (Tone.Buffer.supportsType(extensions[i])) {\n\t extension = extensions[i];\n\t break;\n\t }\n\t }\n\t url = url.replace(matches[0], extension);\n\t }\n\t function onError(e) {\n\t Tone.Buffer._removeFromDownloadQueue(request);\n\t Tone.Buffer.emit('error', e);\n\t if (onerror) {\n\t onerror(e);\n\t } else {\n\t throw e;\n\t }\n\t }\n\t function onProgress() {\n\t //calculate the progress\n\t var totalProgress = 0;\n\t for (var i = 0; i < Tone.Buffer._downloadQueue.length; i++) {\n\t totalProgress += Tone.Buffer._downloadQueue[i].progress;\n\t }\n\t Tone.Buffer.emit('progress', totalProgress / Tone.Buffer._downloadQueue.length);\n\t }\n\t var request = new XMLHttpRequest();\n\t request.open('GET', Tone.Buffer.baseUrl + url, true);\n\t request.responseType = 'arraybuffer';\n\t //start out as 0\n\t request.progress = 0;\n\t Tone.Buffer._downloadQueue.push(request);\n\t request.addEventListener('load', function () {\n\t if (request.status === 200) {\n\t Tone.context.decodeAudioData(request.response).then(function (buff) {\n\t request.progress = 1;\n\t onProgress();\n\t onload(buff);\n\t Tone.Buffer._removeFromDownloadQueue(request);\n\t if (Tone.Buffer._downloadQueue.length === 0) {\n\t //emit the event at the end\n\t Tone.Buffer.emit('load');\n\t }\n\t }).catch(function () {\n\t Tone.Buffer._removeFromDownloadQueue(request);\n\t onError('Tone.Buffer: could not decode audio data: ' + url);\n\t });\n\t } else {\n\t onError('Tone.Buffer: could not locate file: ' + url);\n\t }\n\t });\n\t request.addEventListener('error', onError);\n\t request.addEventListener('progress', function (event) {\n\t if (event.lengthComputable) {\n\t //only go to 95%, the last 5% is when the audio is decoded\n\t request.progress = event.loaded / event.total * 0.95;\n\t onProgress();\n\t }\n\t });\n\t request.send();\n\t return request;\n\t };\n\t /**\n\t\t * Stop all of the downloads in progress\n\t\t * @return {Tone.Buffer}\n\t\t * @static\n\t\t */\n\t Tone.Buffer.cancelDownloads = function () {\n\t Tone.Buffer._downloadQueue.slice().forEach(function (request) {\n\t Tone.Buffer._removeFromDownloadQueue(request);\n\t request.abort();\n\t });\n\t return Tone.Buffer;\n\t };\n\t /**\n\t\t * Checks a url's extension to see if the current browser can play that file type.\n\t\t * @param {String} url The url/extension to test\n\t\t * @return {Boolean} If the file extension can be played\n\t\t * @static\n\t\t * @example\n\t\t * Tone.Buffer.supportsType(\"wav\"); //returns true\n\t\t * Tone.Buffer.supportsType(\"path/to/file.wav\"); //returns true\n\t\t */\n\t Tone.Buffer.supportsType = function (url) {\n\t var extension = url.split('.');\n\t extension = extension[extension.length - 1];\n\t var response = document.createElement('audio').canPlayType('audio/' + extension);\n\t return response !== '';\n\t };\n\t /**\n\t\t * Returns a Promise which resolves when all of the buffers have loaded\n\t\t * @return {Promise}\n\t\t */\n\t Tone.loaded = function () {\n\t var onload, onerror;\n\t function removeEvents() {\n\t //remove the events when it's resolved\n\t Tone.Buffer.off('load', onload);\n\t Tone.Buffer.off('error', onerror);\n\t }\n\t return new Promise(function (success, fail) {\n\t onload = function () {\n\t success();\n\t };\n\t onerror = function () {\n\t fail();\n\t };\n\t //add the event listeners\n\t Tone.Buffer.on('load', onload);\n\t Tone.Buffer.on('error', onerror);\n\t }).then(removeEvents).catch(function (e) {\n\t removeEvents();\n\t throw new Error(e);\n\t });\n\t };\n\t return Tone.Buffer;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Wrapper around the native fire-and-forget OscillatorNode. Adds the\n\t\t * ability to reschedule the stop method.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {AudioBuffer|Tone.Buffer} buffer The buffer to play\n\t\t * @param {Function} onload The callback to invoke when the\n\t\t * buffer is done playing.\n\t\t */\n\t Tone.OscillatorNode = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type'\n\t ], Tone.OscillatorNode);\n\t Tone.AudioNode.call(this, options);\n\t /**\n\t\t\t * The callback to invoke after the\n\t\t\t * buffer source is done playing.\n\t\t\t * @type {Function}\n\t\t\t */\n\t this.onended = options.onended;\n\t /**\n\t\t\t * The oscillator start time\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._startTime = -1;\n\t /**\n\t\t\t * The oscillator stop time\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._stopTime = -1;\n\t /**\n\t\t\t * The gain node which envelopes the OscillatorNode\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._gainNode = this.output = new Tone.Gain();\n\t this._gainNode.gain.setValueAtTime(0, this.context.currentTime);\n\t /**\n\t\t\t * The oscillator\n\t\t\t * @type {OscillatorNode}\n\t\t\t * @private\n\t\t\t */\n\t this._oscillator = this.context.createOscillator();\n\t this._oscillator.connect(this._gainNode);\n\t this.type = options.type;\n\t /**\n\t\t\t * The frequency of the oscillator\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Param(this._oscillator.frequency, Tone.Type.Frequency);\n\t this.frequency.value = options.frequency;\n\t /**\n\t\t\t * The detune of the oscillator\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Param(this._oscillator.detune, Tone.Type.Cents);\n\t this.detune.value = options.detune;\n\t /**\n\t\t\t * The value that the buffer ramps to\n\t\t\t * @type {Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._gain = 1;\n\t };\n\t Tone.extend(Tone.OscillatorNode, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.OscillatorNode.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'type': 'sine',\n\t 'onended': Tone.noOp\n\t };\n\t /**\n\t\t * Returns the playback state of the oscillator, either \"started\" or \"stopped\".\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.OscillatorNode#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.OscillatorNode.prototype, 'state', {\n\t get: function () {\n\t return this.getStateAtTime(this.now());\n\t }\n\t });\n\t /**\n\t\t * Get the playback state at the given time\n\t\t * @param {Time} time The time to test the state at\n\t\t * @return {Tone.State} The playback state. \n\t\t */\n\t Tone.OscillatorNode.prototype.getStateAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t if (this._startTime !== -1 && time >= this._startTime && (this._stopTime === -1 || time <= this._stopTime)) {\n\t return Tone.State.Started;\n\t } else {\n\t return Tone.State.Stopped;\n\t }\n\t };\n\t /**\n\t * Start the oscillator node at the given time\n\t * @param {Time=} time When to start the oscillator\n\t * @return {OscillatorNode} this\n\t */\n\t Tone.OscillatorNode.prototype.start = function (time) {\n\t if (this._startTime === -1) {\n\t this._startTime = this.toSeconds(time);\n\t this._oscillator.start(this._startTime);\n\t var now = this.context.currentTime;\n\t this._gainNode.gain.cancelScheduledValues(now);\n\t this._gainNode.gain.setValueAtTime(0, now);\n\t this._gainNode.gain.setValueAtTime(1, this._startTime);\n\t } else {\n\t throw new Error('cannot call OscillatorNode.start more than once');\n\t }\n\t return this;\n\t };\n\t /**\n\t * Sets an arbitrary custom periodic waveform given a PeriodicWave.\n\t * @param {PeriodicWave} periodicWave PeriodicWave should be created with context.createPeriodicWave\n\t * @return {OscillatorNode} this\n\t */\n\t Tone.OscillatorNode.prototype.setPeriodicWave = function (periodicWave) {\n\t this._oscillator.setPeriodicWave(periodicWave);\n\t return this;\n\t };\n\t /**\n\t * Stop the oscillator node at the given time\n\t * @param {Time=} time When to stop the oscillator\n\t * @return {OscillatorNode} this\n\t */\n\t Tone.OscillatorNode.prototype.stop = function (time) {\n\t //cancel the previous stop\n\t this.cancelStop();\n\t //reschedule it\n\t this._stopTime = this.toSeconds(time);\n\t this._gainNode.gain.setValueAtTime(0, this._stopTime);\n\t this.context.clearTimeout(this._timeout);\n\t this._timeout = this.context.setTimeout(function () {\n\t this._oscillator.stop(this.now());\n\t this.onended();\n\t }.bind(this), this._stopTime - this.now());\n\t return this;\n\t };\n\t /**\n\t\t * Cancel a scheduled stop event\n\t\t * @return {Tone.OscillatorNode} this\n\t\t */\n\t Tone.OscillatorNode.prototype.cancelStop = function () {\n\t if (this._startTime !== -1) {\n\t //cancel the stop envelope\n\t this._gainNode.gain.cancelScheduledValues(this._startTime + this.sampleTime);\n\t this._gainNode.gain.setValueAtTime(1, Math.max(this.now(), this._startTime));\n\t this.context.clearTimeout(this._timeout);\n\t this._stopTime = -1;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * The oscillator type. Either 'sine', 'sawtooth', 'square', or 'triangle'\n\t\t * @memberOf Tone.OscillatorNode#\n\t\t * @type {Time}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.OscillatorNode.prototype, 'type', {\n\t get: function () {\n\t return this._oscillator.type;\n\t },\n\t set: function (type) {\n\t this._oscillator.type = type;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.OscillatorNode} this\n\t\t */\n\t Tone.OscillatorNode.prototype.dispose = function () {\n\t this.context.clearTimeout(this._timeout);\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.onended = null;\n\t this._oscillator.disconnect();\n\t this._oscillator = null;\n\t this._gainNode.dispose();\n\t this._gainNode = null;\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this.detune.dispose();\n\t this.detune = null;\n\t return this;\n\t };\n\t return Tone.OscillatorNode;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Oscillator supports a number of features including\n\t\t * phase rotation, multiple oscillator types (see Tone.Oscillator.type),\n\t\t * and Transport syncing (see Tone.Oscillator.syncFrequency).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Source}\n\t\t * @param {Frequency} [frequency] Starting frequency\n\t\t * @param {string} [type] The oscillator type. Read more about type below.\n\t\t * @example\n\t\t * //make and start a 440hz sine tone\n\t\t * var osc = new Tone.Oscillator(440, \"sine\").toMaster().start();\n\t\t */\n\t Tone.Oscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type'\n\t ], Tone.Oscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * the main oscillator\n\t\t\t * @type {OscillatorNode}\n\t\t\t * @private\n\t\t\t */\n\t this._oscillator = null;\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune control signal.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(options.detune, Tone.Type.Cents);\n\t /**\n\t\t\t * the periodic wave\n\t\t\t * @type {PeriodicWave}\n\t\t\t * @private\n\t\t\t */\n\t this._wave = null;\n\t /**\n\t\t\t * The partials of the oscillator\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._partials = Tone.defaultArg(options.partials, [1]);\n\t /**\n\t\t\t * the phase of the oscillator\n\t\t\t * between 0 - 360\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._phase = options.phase;\n\t /**\n\t\t\t * the type of the oscillator\n\t\t\t * @type {string}\n\t\t\t * @private\n\t\t\t */\n\t this._type = null;\n\t //setup\n\t this.type = options.type;\n\t this.phase = this._phase;\n\t this._readOnly([\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t };\n\t Tone.extend(Tone.Oscillator, Tone.Source);\n\t /**\n\t\t * the default parameters\n\t\t * @type {Object}\n\t\t */\n\t Tone.Oscillator.defaults = {\n\t 'type': 'sine',\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'phase': 0,\n\t 'partials': []\n\t };\n\t /**\n\t\t * The Oscillator types\n\t\t * @enum {String}\n\t\t */\n\t Tone.Oscillator.Type = {\n\t Sine: 'sine',\n\t Triangle: 'triangle',\n\t Sawtooth: 'sawtooth',\n\t Square: 'square',\n\t Custom: 'custom'\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now]\n\t\t * @private\n\t\t */\n\t Tone.Oscillator.prototype._start = function (time) {\n\t //new oscillator with previous values\n\t this._oscillator = new Tone.OscillatorNode();\n\t if (this._wave) {\n\t this._oscillator.setPeriodicWave(this._wave);\n\t } else {\n\t this._oscillator.type = this._type;\n\t }\n\t //connect the control signal to the oscillator frequency & detune\n\t this._oscillator.connect(this.output);\n\t this.frequency.connect(this._oscillator.frequency);\n\t this.detune.connect(this._oscillator.detune);\n\t //start the oscillator\n\t time = this.toSeconds(time);\n\t this._oscillator.start(time);\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @private\n\t\t * @param {Time} [time=now] (optional) timing parameter\n\t\t * @returns {Tone.Oscillator} this\n\t\t */\n\t Tone.Oscillator.prototype._stop = function (time) {\n\t if (this._oscillator) {\n\t time = this.toSeconds(time);\n\t this._oscillator.stop(time);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Restart the oscillator. Does not stop the oscillator, but instead\n\t\t * just cancels any scheduled 'stop' from being invoked.\n\t\t * @param {Time=} time\n\t\t * @return {Tone.Oscillator} this\n\t\t */\n\t Tone.Oscillator.prototype.restart = function (time) {\n\t this._oscillator.cancelStop();\n\t this._state.cancel(this.toSeconds(time));\n\t return this;\n\t };\n\t /**\n\t\t * Sync the signal to the Transport's bpm. Any changes to the transports bpm,\n\t\t * will also affect the oscillators frequency.\n\t\t * @returns {Tone.Oscillator} this\n\t\t * @example\n\t\t * Tone.Transport.bpm.value = 120;\n\t\t * osc.frequency.value = 440;\n\t\t * //the ration between the bpm and the frequency will be maintained\n\t\t * osc.syncFrequency();\n\t\t * Tone.Transport.bpm.value = 240;\n\t\t * // the frequency of the oscillator is doubled to 880\n\t\t */\n\t Tone.Oscillator.prototype.syncFrequency = function () {\n\t Tone.Transport.syncSignal(this.frequency);\n\t return this;\n\t };\n\t /**\n\t\t * Unsync the oscillator's frequency from the Transport.\n\t\t * See Tone.Oscillator.syncFrequency\n\t\t * @returns {Tone.Oscillator} this\n\t\t */\n\t Tone.Oscillator.prototype.unsyncFrequency = function () {\n\t Tone.Transport.unsyncSignal(this.frequency);\n\t return this;\n\t };\n\t /**\n\t\t * The type of the oscillator: either sine, square, triangle, or sawtooth. Also capable of\n\t\t * setting the first x number of partials of the oscillator. For example: \"sine4\" would\n\t\t * set be the first 4 partials of the sine wave and \"triangle8\" would set the first\n\t\t * 8 partials of the triangle wave.\n\t\t * <br><br>\n\t\t * Uses PeriodicWave internally even for native types so that it can set the phase.\n\t\t * PeriodicWave equations are from the\n\t\t * [Webkit Web Audio implementation](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/modules/webaudio/PeriodicWave.cpp&sq=package:chromium).\n\t\t *\n\t\t * @memberOf Tone.Oscillator#\n\t\t * @type {string}\n\t\t * @name type\n\t\t * @example\n\t\t * //set it to a square wave\n\t\t * osc.type = \"square\";\n\t\t * @example\n\t\t * //set the first 6 partials of a sawtooth wave\n\t\t * osc.type = \"sawtooth6\";\n\t\t */\n\t Object.defineProperty(Tone.Oscillator.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t var isBasicType = [\n\t Tone.Oscillator.Type.Sine,\n\t Tone.Oscillator.Type.Square,\n\t Tone.Oscillator.Type.Triangle,\n\t Tone.Oscillator.Type.Sawtooth\n\t ].includes(type);\n\t if (this._phase === 0 && isBasicType) {\n\t this._wave = null;\n\t //just go with the basic approach\n\t if (this._oscillator !== null) {\n\t this._oscillator.type === type;\n\t }\n\t } else {\n\t var coefs = this._getRealImaginary(type, this._phase);\n\t var periodicWave = this.context.createPeriodicWave(coefs[0], coefs[1]);\n\t this._wave = periodicWave;\n\t if (this._oscillator !== null) {\n\t this._oscillator.setPeriodicWave(this._wave);\n\t }\n\t }\n\t this._type = type;\n\t }\n\t });\n\t /**\n\t\t * Returns the real and imaginary components based\n\t\t * on the oscillator type.\n\t\t * @returns {Array} [real, imaginary]\n\t\t * @private\n\t\t */\n\t Tone.Oscillator.prototype._getRealImaginary = function (type, phase) {\n\t var fftSize = 4096;\n\t var periodicWaveSize = fftSize / 2;\n\t var real = new Float32Array(periodicWaveSize);\n\t var imag = new Float32Array(periodicWaveSize);\n\t var partialCount = 1;\n\t if (type === Tone.Oscillator.Type.Custom) {\n\t partialCount = this._partials.length + 1;\n\t periodicWaveSize = partialCount;\n\t } else {\n\t var partial = /^(sine|triangle|square|sawtooth)(\\d+)$/.exec(type);\n\t if (partial) {\n\t partialCount = parseInt(partial[2]) + 1;\n\t type = partial[1];\n\t partialCount = Math.max(partialCount, 2);\n\t periodicWaveSize = partialCount;\n\t }\n\t }\n\t for (var n = 1; n < periodicWaveSize; ++n) {\n\t var piFactor = 2 / (n * Math.PI);\n\t var b;\n\t switch (type) {\n\t case Tone.Oscillator.Type.Sine:\n\t b = n <= partialCount ? 1 : 0;\n\t break;\n\t case Tone.Oscillator.Type.Square:\n\t b = n & 1 ? 2 * piFactor : 0;\n\t break;\n\t case Tone.Oscillator.Type.Sawtooth:\n\t b = piFactor * (n & 1 ? 1 : -1);\n\t break;\n\t case Tone.Oscillator.Type.Triangle:\n\t if (n & 1) {\n\t b = 2 * (piFactor * piFactor) * (n - 1 >> 1 & 1 ? -1 : 1);\n\t } else {\n\t b = 0;\n\t }\n\t break;\n\t case Tone.Oscillator.Type.Custom:\n\t b = this._partials[n - 1];\n\t break;\n\t default:\n\t throw new TypeError('Tone.Oscillator: invalid type: ' + type);\n\t }\n\t if (b !== 0) {\n\t real[n] = -b * Math.sin(phase * n);\n\t imag[n] = b * Math.cos(phase * n);\n\t } else {\n\t real[n] = 0;\n\t imag[n] = 0;\n\t }\n\t }\n\t return [\n\t real,\n\t imag\n\t ];\n\t };\n\t /**\n\t\t * Compute the inverse FFT for a given phase.\n\t\t * @param {Float32Array} real\n\t\t * @param {Float32Array} imag\n\t\t * @param {NormalRange} phase\n\t\t * @return {AudioRange}\n\t\t * @private\n\t\t */\n\t Tone.Oscillator.prototype._inverseFFT = function (real, imag, phase) {\n\t var sum = 0;\n\t var len = real.length;\n\t for (var i = 0; i < len; i++) {\n\t sum += real[i] * Math.cos(i * phase) + imag[i] * Math.sin(i * phase);\n\t }\n\t return sum;\n\t };\n\t /**\n\t\t * Returns the initial value of the oscillator.\n\t\t * @return {AudioRange}\n\t\t * @private\n\t\t */\n\t Tone.Oscillator.prototype._getInitialValue = function () {\n\t var coefs = this._getRealImaginary(this._type, 0);\n\t var real = coefs[0];\n\t var imag = coefs[1];\n\t var maxValue = 0;\n\t var twoPi = Math.PI * 2;\n\t //check for peaks in 8 places\n\t for (var i = 0; i < 8; i++) {\n\t maxValue = Math.max(this._inverseFFT(real, imag, i / 8 * twoPi), maxValue);\n\t }\n\t return -this._inverseFFT(real, imag, this._phase) / maxValue;\n\t };\n\t /**\n\t\t * The partials of the waveform. A partial represents\n\t\t * the amplitude at a harmonic. The first harmonic is the\n\t\t * fundamental frequency, the second is the octave and so on\n\t\t * following the harmonic series.\n\t\t * Setting this value will automatically set the type to \"custom\".\n\t\t * The value is an empty array when the type is not \"custom\".\n\t\t * @memberOf Tone.Oscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @example\n\t\t * osc.partials = [1, 0.2, 0.01];\n\t\t */\n\t Object.defineProperty(Tone.Oscillator.prototype, 'partials', {\n\t get: function () {\n\t if (this._type !== Tone.Oscillator.Type.Custom) {\n\t return [];\n\t } else {\n\t return this._partials;\n\t }\n\t },\n\t set: function (partials) {\n\t this._partials = partials;\n\t this.type = Tone.Oscillator.Type.Custom;\n\t }\n\t });\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.Oscillator#\n\t\t * @type {Degrees}\n\t\t * @name phase\n\t\t * @example\n\t\t * osc.phase = 180; //flips the phase of the oscillator\n\t\t */\n\t Object.defineProperty(Tone.Oscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._phase * (180 / Math.PI);\n\t },\n\t set: function (phase) {\n\t this._phase = phase * Math.PI / 180;\n\t //reset the type\n\t this.type = this._type;\n\t }\n\t });\n\t /**\n\t\t * Dispose and disconnect.\n\t\t * @return {Tone.Oscillator} this\n\t\t */\n\t Tone.Oscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t if (this._oscillator !== null) {\n\t this._oscillator.dispose();\n\t this._oscillator = null;\n\t }\n\t this._wave = null;\n\t this._writable([\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this.detune.dispose();\n\t this.detune = null;\n\t this._partials = null;\n\t return this;\n\t };\n\t return Tone.Oscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t\t * See Tone.GainToAudio.\n\t\t *\n\t\t * @extends {Tone.SignalBase}\n\t\t * @constructor\n\t\t * @example\n\t\t * var a2g = new Tone.AudioToGain();\n\t\t */\n\t Tone.AudioToGain = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * @type {WaveShaperNode}\n\t\t\t * @private\n\t\t\t */\n\t this._norm = this.input = this.output = new Tone.WaveShaper(function (x) {\n\t return (x + 1) / 2;\n\t });\n\t };\n\t Tone.extend(Tone.AudioToGain, Tone.SignalBase);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.AudioToGain} this\n\t\t */\n\t Tone.AudioToGain.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._norm.dispose();\n\t this._norm = null;\n\t return this;\n\t };\n\t return Tone.AudioToGain;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Zero outputs 0's at audio-rate. The reason this has to be\n\t\t * it's own class is that many browsers optimize out Tone.Signal\n\t\t * with a value of 0 and will not process nodes further down the graph.\n\t\t * @extends {Tone.SignalBase}\n\t\t */\n\t Tone.Zero = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * The gain node\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._gain = this.input = this.output = new Tone.Gain();\n\t this.context.getConstant(0).connect(this._gain);\n\t };\n\t Tone.extend(Tone.Zero, Tone.SignalBase);\n\t /**\n\t\t * clean up\n\t\t * @return {Tone.Zero} this\n\t\t */\n\t Tone.Zero.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._gain.dispose();\n\t this._gain = null;\n\t return this;\n\t };\n\t return Tone.Zero;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class LFO stands for low frequency oscillator. Tone.LFO produces an output signal\n\t\t * which can be attached to an AudioParam or Tone.Signal\n\t\t * in order to modulate that parameter with an oscillator. The LFO can\n\t\t * also be synced to the transport to start/stop and change when the tempo changes.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Frequency|Object} [frequency] The frequency of the oscillation. Typically, LFOs will be\n\t\t * in the frequency range of 0.1 to 10 hertz.\n\t\t * @param {number=} min The minimum output value of the LFO.\n\t\t * @param {number=} max The maximum value of the LFO.\n\t\t * @example\n\t\t * var lfo = new Tone.LFO(\"4n\", 400, 4000);\n\t\t * lfo.connect(filter.frequency);\n\t\t */\n\t Tone.LFO = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'min',\n\t 'max'\n\t ], Tone.LFO);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The oscillator.\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._oscillator = new Tone.Oscillator({\n\t 'frequency': options.frequency,\n\t 'type': options.type\n\t });\n\t /**\n\t\t\t * the lfo's frequency\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._oscillator.frequency;\n\t /**\n\t\t\t * The amplitude of the LFO, which controls the output range between\n\t\t\t * the min and max output. For example if the min is -10 and the max\n\t\t\t * is 10, setting the amplitude to 0.5 would make the LFO modulate\n\t\t\t * between -5 and 5.\n\t\t\t * @type {Number}\n\t\t\t * @signal\n\t\t\t */\n\t this.amplitude = this._oscillator.volume;\n\t this.amplitude.units = Tone.Type.NormalRange;\n\t this.amplitude.value = options.amplitude;\n\t /**\n\t\t\t * The signal which is output when the LFO is stopped\n\t\t\t * @type {Tone.Signal}\n\t\t\t * @private\n\t\t\t */\n\t this._stoppedSignal = new Tone.Signal(0, Tone.Type.AudioRange);\n\t /**\n\t\t\t * Just outputs zeros.\n\t\t\t * @type {Tone.Zero}\n\t\t\t * @private\n\t\t\t */\n\t this._zeros = new Tone.Zero();\n\t /**\n\t\t\t * The value that the LFO outputs when it's stopped\n\t\t\t * @type {AudioRange}\n\t\t\t * @private\n\t\t\t */\n\t this._stoppedValue = 0;\n\t /**\n\t\t\t * @type {Tone.AudioToGain}\n\t\t\t * @private\n\t\t\t */\n\t this._a2g = new Tone.AudioToGain();\n\t /**\n\t\t\t * @type {Tone.Scale}\n\t\t\t * @private\n\t\t\t */\n\t this._scaler = this.output = new Tone.Scale(options.min, options.max);\n\t /**\n\t\t\t * the units of the LFO (used for converting)\n\t\t\t * @type {Tone.Type}\n\t\t\t * @private\n\t\t\t */\n\t this._units = Tone.Type.Default;\n\t this.units = options.units;\n\t //connect it up\n\t this._oscillator.chain(this._a2g, this._scaler);\n\t this._zeros.connect(this._a2g);\n\t this._stoppedSignal.connect(this._a2g);\n\t this._readOnly([\n\t 'amplitude',\n\t 'frequency'\n\t ]);\n\t this.phase = options.phase;\n\t };\n\t Tone.extend(Tone.LFO, Tone.AudioNode);\n\t /**\n\t\t * the default parameters\n\t\t *\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.LFO.defaults = {\n\t 'type': 'sine',\n\t 'min': 0,\n\t 'max': 1,\n\t 'phase': 0,\n\t 'frequency': '4n',\n\t 'amplitude': 1,\n\t 'units': Tone.Type.Default\n\t };\n\t /**\n\t\t * Start the LFO.\n\t\t * @param {Time} [time=now] the time the LFO will start\n\t\t * @returns {Tone.LFO} this\n\t\t */\n\t Tone.LFO.prototype.start = function (time) {\n\t time = this.toSeconds(time);\n\t this._stoppedSignal.setValueAtTime(0, time);\n\t this._oscillator.start(time);\n\t return this;\n\t };\n\t /**\n\t\t * Stop the LFO.\n\t\t * @param {Time} [time=now] the time the LFO will stop\n\t\t * @returns {Tone.LFO} this\n\t\t */\n\t Tone.LFO.prototype.stop = function (time) {\n\t time = this.toSeconds(time);\n\t this._stoppedSignal.setValueAtTime(this._stoppedValue, time);\n\t this._oscillator.stop(time);\n\t return this;\n\t };\n\t /**\n\t\t * Sync the start/stop/pause to the transport\n\t\t * and the frequency to the bpm of the transport\n\t\t * @returns {Tone.LFO} this\n\t\t * @example\n\t\t * lfo.frequency.value = \"8n\";\n\t\t * lfo.sync().start(0)\n\t\t * //the rate of the LFO will always be an eighth note,\n\t\t * //even as the tempo changes\n\t\t */\n\t Tone.LFO.prototype.sync = function () {\n\t this._oscillator.sync();\n\t this._oscillator.syncFrequency();\n\t return this;\n\t };\n\t /**\n\t\t * unsync the LFO from transport control\n\t\t * @returns {Tone.LFO} this\n\t\t */\n\t Tone.LFO.prototype.unsync = function () {\n\t this._oscillator.unsync();\n\t this._oscillator.unsyncFrequency();\n\t return this;\n\t };\n\t /**\n\t\t * The miniumum output of the LFO.\n\t\t * @memberOf Tone.LFO#\n\t\t * @type {number}\n\t\t * @name min\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'min', {\n\t get: function () {\n\t return this._toUnits(this._scaler.min);\n\t },\n\t set: function (min) {\n\t min = this._fromUnits(min);\n\t this._scaler.min = min;\n\t }\n\t });\n\t /**\n\t\t * The maximum output of the LFO.\n\t\t * @memberOf Tone.LFO#\n\t\t * @type {number}\n\t\t * @name max\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'max', {\n\t get: function () {\n\t return this._toUnits(this._scaler.max);\n\t },\n\t set: function (max) {\n\t max = this._fromUnits(max);\n\t this._scaler.max = max;\n\t }\n\t });\n\t /**\n\t\t * The type of the oscillator: sine, square, sawtooth, triangle.\n\t\t * @memberOf Tone.LFO#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'type', {\n\t get: function () {\n\t return this._oscillator.type;\n\t },\n\t set: function (type) {\n\t this._oscillator.type = type;\n\t this._stoppedValue = this._oscillator._getInitialValue();\n\t this._stoppedSignal.value = this._stoppedValue;\n\t }\n\t });\n\t /**\n\t\t * The phase of the LFO.\n\t\t * @memberOf Tone.LFO#\n\t\t * @type {number}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'phase', {\n\t get: function () {\n\t return this._oscillator.phase;\n\t },\n\t set: function (phase) {\n\t this._oscillator.phase = phase;\n\t this._stoppedValue = this._oscillator._getInitialValue();\n\t this._stoppedSignal.value = this._stoppedValue;\n\t }\n\t });\n\t /**\n\t\t * The output units of the LFO.\n\t\t * @memberOf Tone.LFO#\n\t\t * @type {Tone.Type}\n\t\t * @name units\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'units', {\n\t get: function () {\n\t return this._units;\n\t },\n\t set: function (val) {\n\t var currentMin = this.min;\n\t var currentMax = this.max;\n\t //convert the min and the max\n\t this._units = val;\n\t this.min = currentMin;\n\t this.max = currentMax;\n\t }\n\t });\n\t /**\n\t\t * Mute the output.\n\t\t * @memberOf Tone.LFO#\n\t\t * @type {Boolean}\n\t\t * @name mute\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'mute', {\n\t get: function () {\n\t return this._oscillator.mute;\n\t },\n\t set: function (mute) {\n\t this._oscillator.mute = mute;\n\t }\n\t });\n\t /**\n\t\t * Returns the playback state of the source, either \"started\" or \"stopped\".\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.LFO#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'state', {\n\t get: function () {\n\t return this._oscillator.state;\n\t }\n\t });\n\t /**\n\t\t * Connect the output of the LFO to an AudioParam, AudioNode, or Tone Node.\n\t\t * Tone.LFO will automatically convert to the destination units of the\n\t\t * will get the units from the connected node.\n\t\t * @param {Tone | AudioParam | AudioNode} node\n\t\t * @param {number} [outputNum=0] optionally which output to connect from\n\t\t * @param {number} [inputNum=0] optionally which input to connect to\n\t\t * @returns {Tone.LFO} this\n\t\t * @private\n\t\t */\n\t Tone.LFO.prototype.connect = function (node) {\n\t if (node.constructor === Tone.Signal || node.constructor === Tone.Param) {\n\t this.convert = node.convert;\n\t this.units = node.units;\n\t }\n\t Tone.SignalBase.prototype.connect.apply(this, arguments);\n\t return this;\n\t };\n\t /**\n\t\t * private method borrowed from Param converts\n\t\t * units from their destination value\n\t\t * @function\n\t\t * @private\n\t\t */\n\t Tone.LFO.prototype._fromUnits = Tone.Param.prototype._fromUnits;\n\t /**\n\t\t * private method borrowed from Param converts\n\t\t * units to their destination value\n\t\t * @function\n\t\t * @private\n\t\t */\n\t Tone.LFO.prototype._toUnits = Tone.Param.prototype._toUnits;\n\t /**\n\t\t * disconnect and dispose\n\t\t * @returns {Tone.LFO} this\n\t\t */\n\t Tone.LFO.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'amplitude',\n\t 'frequency'\n\t ]);\n\t this._oscillator.dispose();\n\t this._oscillator = null;\n\t this._stoppedSignal.dispose();\n\t this._stoppedSignal = null;\n\t this._zeros.dispose();\n\t this._zeros = null;\n\t this._scaler.dispose();\n\t this._scaler = null;\n\t this._a2g.dispose();\n\t this._a2g = null;\n\t this.frequency = null;\n\t this.amplitude = null;\n\t return this;\n\t };\n\t return Tone.LFO;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Limiter will limit the loudness of an incoming signal.\n\t\t * It is composed of a Tone.Compressor with a fast attack\n\t\t * and release. Limiters are commonly used to safeguard against\n\t\t * signal clipping. Unlike a compressor, limiters do not provide\n\t\t * smooth gain reduction and almost completely prevent\n\t\t * additional gain above the threshold.\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {number} threshold The theshold above which the limiting is applied.\n\t\t * @example\n\t\t * var limiter = new Tone.Limiter(-6);\n\t\t */\n\t Tone.Limiter = function () {\n\t var options = Tone.defaults(arguments, ['threshold'], Tone.Limiter);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * the compressor\n\t\t\t * @private\n\t\t\t * @type {Tone.Compressor}\n\t\t\t */\n\t this._compressor = this.input = this.output = new Tone.Compressor({\n\t 'attack': 0.001,\n\t 'decay': 0.001,\n\t 'threshold': options.threshold\n\t });\n\t /**\n\t\t\t * The threshold of of the limiter\n\t\t\t * @type {Decibel}\n\t\t\t * @signal\n\t\t\t */\n\t this.threshold = this._compressor.threshold;\n\t this._readOnly('threshold');\n\t };\n\t Tone.extend(Tone.Limiter, Tone.AudioNode);\n\t /**\n\t\t * The default value\n\t\t * @type {Object}\n\t\t * @const\n\t\t * @static\n\t\t */\n\t Tone.Limiter.defaults = { 'threshold': -12 };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Limiter} this\n\t\t */\n\t Tone.Limiter.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._compressor.dispose();\n\t this._compressor = null;\n\t this._writable('threshold');\n\t this.threshold = null;\n\t return this;\n\t };\n\t return Tone.Limiter;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Lowpass is a lowpass feedback comb filter. It is similar to\n\t\t * Tone.FeedbackCombFilter, but includes a lowpass filter.\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {Time|Object} [delayTime] The delay time of the comb filter\n\t\t * @param {NormalRange=} resonance The resonance (feedback) of the comb filter\n\t\t * @param {Frequency=} dampening The cutoff of the lowpass filter dampens the\n\t\t * signal as it is fedback.\n\t\t */\n\t Tone.LowpassCombFilter = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'delayTime',\n\t 'resonance',\n\t 'dampening'\n\t ], Tone.LowpassCombFilter);\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(1, 1);\n\t /**\n\t\t\t * the delay node\n\t\t\t * @type {DelayNode}\n\t\t\t * @private\n\t\t\t */\n\t this._delay = this.input = new Tone.Delay(options.delayTime);\n\t /**\n\t\t\t * The delayTime of the comb filter.\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.delayTime = this._delay.delayTime;\n\t /**\n\t\t\t * the lowpass filter\n\t\t\t * @type {BiquadFilterNode}\n\t\t\t * @private\n\t\t\t */\n\t this._lowpass = this.output = this.context.createBiquadFilter();\n\t this._lowpass.Q.value = -3.0102999566398125;\n\t this._lowpass.type = 'lowpass';\n\t /**\n\t\t\t * The dampening control of the feedback\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.dampening = new Tone.Param({\n\t 'param': this._lowpass.frequency,\n\t 'units': Tone.Type.Frequency,\n\t 'value': options.dampening\n\t });\n\t /**\n\t\t\t * the feedback gain\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._feedback = new Tone.Gain(options.resonance, Tone.Type.NormalRange);\n\t /**\n\t\t\t * The amount of feedback of the delayed signal.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.resonance = this._feedback.gain;\n\t //connections\n\t this._delay.chain(this._lowpass, this._feedback, this._delay);\n\t this._readOnly([\n\t 'dampening',\n\t 'resonance',\n\t 'delayTime'\n\t ]);\n\t };\n\t Tone.extend(Tone.LowpassCombFilter, Tone.AudioNode);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.LowpassCombFilter.defaults = {\n\t 'delayTime': 0.1,\n\t 'resonance': 0.5,\n\t 'dampening': 3000\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.LowpassCombFilter} this\n\t\t */\n\t Tone.LowpassCombFilter.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'dampening',\n\t 'resonance',\n\t 'delayTime'\n\t ]);\n\t this.dampening.dispose();\n\t this.dampening = null;\n\t this.resonance.dispose();\n\t this.resonance = null;\n\t this._delay.dispose();\n\t this._delay = null;\n\t this.delayTime = null;\n\t this._lowpass.disconnect();\n\t this._lowpass = null;\n\t this._feedback.disconnect();\n\t this._feedback = null;\n\t return this;\n\t };\n\t return Tone.LowpassCombFilter;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Merge brings two signals into the left and right\n\t\t * channels of a single stereo channel.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @example\n\t\t * var merge = new Tone.Merge().toMaster();\n\t\t * //routing a sine tone in the left channel\n\t\t * //and noise in the right channel\n\t\t * var osc = new Tone.Oscillator().connect(merge.left);\n\t\t * var noise = new Tone.Noise().connect(merge.right);\n\t\t * //starting our oscillators\n\t\t * noise.start();\n\t\t * osc.start();\n\t\t */\n\t Tone.Merge = function () {\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(2, 0);\n\t /**\n\t\t\t * The left input channel.\n\t\t\t * Alias for <code>input[0]</code>\n\t\t\t * @type {GainNode}\n\t\t\t */\n\t this.left = this.input[0] = new Tone.Gain();\n\t /**\n\t\t\t * The right input channel.\n\t\t\t * Alias for <code>input[1]</code>.\n\t\t\t * @type {GainNode}\n\t\t\t */\n\t this.right = this.input[1] = new Tone.Gain();\n\t /**\n\t\t\t * the merger node for the two channels\n\t\t\t * @type {ChannelMergerNode}\n\t\t\t * @private\n\t\t\t */\n\t this._merger = this.output = this.context.createChannelMerger(2);\n\t //connections\n\t this.left.connect(this._merger, 0, 0);\n\t this.right.connect(this._merger, 0, 1);\n\t this.left.channelCount = 1;\n\t this.right.channelCount = 1;\n\t this.left.channelCountMode = 'explicit';\n\t this.right.channelCountMode = 'explicit';\n\t };\n\t Tone.extend(Tone.Merge, Tone.AudioNode);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Merge} this\n\t\t */\n\t Tone.Merge.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.left.dispose();\n\t this.left = null;\n\t this.right.dispose();\n\t this.right = null;\n\t this._merger.disconnect();\n\t this._merger = null;\n\t return this;\n\t };\n\t return Tone.Merge;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Meter gets the [RMS](https://en.wikipedia.org/wiki/Root_mean_square)\n\t\t * of an input signal with some averaging applied. It can also get the raw\n\t\t * value of the input signal.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Number} smoothing The amount of smoothing applied between frames.\n\t\t * @example\n\t\t * var meter = new Tone.Meter();\n\t\t * var mic = new Tone.UserMedia().open();\n\t\t * //connect mic to the meter\n\t\t * mic.connect(meter);\n\t\t * //the current level of the mic input in decibels\n\t\t * var level = meter.getValue();\n\t\t */\n\t Tone.Meter = function () {\n\t var options = Tone.defaults(arguments, ['smoothing'], Tone.Meter);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The analyser node which computes the levels.\n\t\t\t * @private\n\t\t\t * @type {Tone.Analyser}\n\t\t\t */\n\t this.input = this.output = this._analyser = new Tone.Analyser('waveform', 1024);\n\t /**\n\t\t\t * The amount of carryover between the current and last frame.\n\t\t\t * Only applied meter for \"level\" type.\n\t\t\t * @type {Number}\n\t\t\t */\n\t this.smoothing = options.smoothing;\n\t };\n\t Tone.extend(Tone.Meter, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @type {Object}\n\t\t * @static\n\t\t * @const\n\t\t */\n\t Tone.Meter.defaults = { 'smoothing': 0.8 };\n\t /**\n\t\t * Get the current decibel value of the incoming signal\n\t\t * @returns {Decibels}\n\t\t */\n\t Tone.Meter.prototype.getLevel = function () {\n\t this._analyser.type = 'fft';\n\t var values = this._analyser.getValue();\n\t var offset = 28;\n\t // normalizes most signal levels\n\t // TODO: compute loudness from FFT\n\t return Math.max.apply(this, values) + offset;\n\t };\n\t /**\n\t\t * Get the signal value of the incoming signal\n\t\t * @returns {Number}\n\t\t */\n\t Tone.Meter.prototype.getValue = function () {\n\t this._analyser.type = 'waveform';\n\t var value = this._analyser.getValue();\n\t return value[0];\n\t };\n\t /**\n\t\t * A value from 0 -> 1 where 0 represents no time averaging with the last analysis frame.\n\t\t * @memberOf Tone.Meter#\n\t\t * @type {Number}\n\t\t * @name smoothing\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Meter.prototype, 'smoothing', {\n\t get: function () {\n\t return this._analyser.smoothing;\n\t },\n\t set: function (val) {\n\t this._analyser.smoothing = val;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Meter} this\n\t\t */\n\t Tone.Meter.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._analyser.dispose();\n\t this._analyser = null;\n\t return this;\n\t };\n\t return Tone.Meter;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t *\t@class Tone.Split splits an incoming signal into left and right channels.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @example\n\t\t * var split = new Tone.Split();\n\t\t * stereoSignal.connect(split);\n\t\t */\n\t Tone.Split = function () {\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(0, 2);\n\t /**\n\t\t\t * @type {ChannelSplitterNode}\n\t\t\t * @private\n\t\t\t */\n\t this._splitter = this.input = this.context.createChannelSplitter(2);\n\t this._splitter.channelCount = 2;\n\t this._splitter.channelCountMode = 'explicit';\n\t /**\n\t\t\t * Left channel output.\n\t\t\t * Alias for <code>output[0]</code>\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.left = this.output[0] = new Tone.Gain();\n\t /**\n\t\t\t * Right channel output.\n\t\t\t * Alias for <code>output[1]</code>\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.right = this.output[1] = new Tone.Gain();\n\t //connections\n\t this._splitter.connect(this.left, 0, 0);\n\t this._splitter.connect(this.right, 1, 0);\n\t };\n\t Tone.extend(Tone.Split, Tone.AudioNode);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Split} this\n\t\t */\n\t Tone.Split.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._splitter.disconnect();\n\t this.left.dispose();\n\t this.left = null;\n\t this.right.dispose();\n\t this.right = null;\n\t this._splitter = null;\n\t return this;\n\t };\n\t return Tone.Split;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Mid/Side processing separates the the 'mid' signal\n\t\t * (which comes out of both the left and the right channel)\n\t\t * and the 'side' (which only comes out of the the side channels). <br><br>\n\t\t * <code>\n\t\t * Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right<br>\n\t\t * Side = (Left-Right)/sqrt(2); // obtain side-signal from left and righ<br>\n\t\t * </code>\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t */\n\t Tone.MidSideSplit = function () {\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(0, 2);\n\t /**\n\t\t\t * split the incoming signal into left and right channels\n\t\t\t * @type {Tone.Split}\n\t\t\t * @private\n\t\t\t */\n\t this._split = this.input = new Tone.Split();\n\t /**\n\t\t\t * The mid send. Connect to mid processing. Alias for\n\t\t\t * <code>output[0]</code>\n\t\t\t * @type {Tone.Add}\n\t\t\t */\n\t this._midAdd = new Tone.Add();\n\t /**\n\t\t\t * Multiply the _midAdd by sqrt(1/2)\n\t\t\t * @type {Tone.Multiply}\n\t\t\t */\n\t this.mid = this.output[0] = new Tone.Multiply(Math.SQRT1_2);\n\t /**\n\t\t\t * The side output. Connect to side processing. Also Output 1\n\t\t\t * @type {Tone.Subtract}\n\t\t\t */\n\t this._sideSubtract = new Tone.Subtract();\n\t /**\n\t\t\t * Multiply the _midAdd by sqrt(1/2)\n\t\t\t * @type {Tone.Multiply}\n\t\t\t */\n\t this.side = this.output[1] = new Tone.Multiply(Math.SQRT1_2);\n\t this._split.connect(this._midAdd, 0, 0);\n\t this._split.connect(this._midAdd, 1, 1);\n\t this._split.connect(this._sideSubtract, 0, 0);\n\t this._split.connect(this._sideSubtract, 1, 1);\n\t this._midAdd.connect(this.mid);\n\t this._sideSubtract.connect(this.side);\n\t };\n\t Tone.extend(Tone.MidSideSplit, Tone.AudioNode);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.MidSideSplit} this\n\t\t */\n\t Tone.MidSideSplit.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.mid.dispose();\n\t this.mid = null;\n\t this.side.dispose();\n\t this.side = null;\n\t this._midAdd.dispose();\n\t this._midAdd = null;\n\t this._sideSubtract.dispose();\n\t this._sideSubtract = null;\n\t this._split.dispose();\n\t this._split = null;\n\t return this;\n\t };\n\t return Tone.MidSideSplit;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Mid/Side processing separates the the 'mid' signal\n\t\t * (which comes out of both the left and the right channel)\n\t\t * and the 'side' (which only comes out of the the side channels).\n\t\t * MidSideMerge merges the mid and side signal after they've been seperated\n\t\t * by Tone.MidSideSplit.<br><br>\n\t\t * <code>\n\t\t * Left = (Mid+Side)/sqrt(2); // obtain left signal from mid and side<br>\n\t\t * Right = (Mid-Side)/sqrt(2); // obtain right signal from mid and side<br>\n\t\t * </code>\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t */\n\t Tone.MidSideMerge = function () {\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(2, 0);\n\t /**\n\t\t\t * The mid signal input. Alias for\n\t\t\t * <code>input[0]</code>\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.mid = this.input[0] = new Tone.Gain();\n\t /**\n\t\t\t * recombine the mid/side into Left\n\t\t\t * @type {Tone.Add}\n\t\t\t * @private\n\t\t\t */\n\t this._left = new Tone.Add();\n\t /**\n\t\t\t * Multiply the left by sqrt(1/2)\n\t\t\t * @type {Tone.Multiply}\n\t\t\t */\n\t this._timesTwoLeft = new Tone.Multiply(Math.SQRT1_2);\n\t /**\n\t\t\t * The side signal input. Alias for\n\t\t\t * <code>input[1]</code>\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.side = this.input[1] = new Tone.Gain();\n\t /**\n\t\t\t * recombine the mid/side into Right\n\t\t\t * @type {Tone.Subtract}\n\t\t\t * @private\n\t\t\t */\n\t this._right = new Tone.Subtract();\n\t /**\n\t\t\t * Multiply the right by sqrt(1/2)\n\t\t\t * @type {Tone.Multiply}\n\t\t\t */\n\t this._timesTwoRight = new Tone.Multiply(Math.SQRT1_2);\n\t /**\n\t\t\t * Merge the left/right signal back into a stereo signal.\n\t\t\t * @type {Tone.Merge}\n\t\t\t * @private\n\t\t\t */\n\t this._merge = this.output = new Tone.Merge();\n\t this.mid.connect(this._left, 0, 0);\n\t this.side.connect(this._left, 0, 1);\n\t this.mid.connect(this._right, 0, 0);\n\t this.side.connect(this._right, 0, 1);\n\t this._left.connect(this._timesTwoLeft);\n\t this._right.connect(this._timesTwoRight);\n\t this._timesTwoLeft.connect(this._merge, 0, 0);\n\t this._timesTwoRight.connect(this._merge, 0, 1);\n\t };\n\t Tone.extend(Tone.MidSideMerge, Tone.AudioNode);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.MidSideMerge} this\n\t\t */\n\t Tone.MidSideMerge.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.mid.dispose();\n\t this.mid = null;\n\t this.side.dispose();\n\t this.side = null;\n\t this._left.dispose();\n\t this._left = null;\n\t this._timesTwoLeft.dispose();\n\t this._timesTwoLeft = null;\n\t this._right.dispose();\n\t this._right = null;\n\t this._timesTwoRight.dispose();\n\t this._timesTwoRight = null;\n\t this._merge.dispose();\n\t this._merge = null;\n\t return this;\n\t };\n\t return Tone.MidSideMerge;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.MidSideCompressor applies two different compressors to the mid\n\t\t * and side signal components. See Tone.MidSideSplit.\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Object} options The options that are passed to the mid and side\n\t\t * compressors.\n\t\t * @constructor\n\t\t */\n\t Tone.MidSideCompressor = function (options) {\n\t Tone.AudioNode.call(this);\n\t options = Tone.defaultArg(options, Tone.MidSideCompressor.defaults);\n\t /**\n\t\t\t * the mid/side split\n\t\t\t * @type {Tone.MidSideSplit}\n\t\t\t * @private\n\t\t\t */\n\t this._midSideSplit = this.input = new Tone.MidSideSplit();\n\t /**\n\t\t\t * the mid/side recombination\n\t\t\t * @type {Tone.MidSideMerge}\n\t\t\t * @private\n\t\t\t */\n\t this._midSideMerge = this.output = new Tone.MidSideMerge();\n\t /**\n\t\t\t * The compressor applied to the mid signal\n\t\t\t * @type {Tone.Compressor}\n\t\t\t */\n\t this.mid = new Tone.Compressor(options.mid);\n\t /**\n\t\t\t * The compressor applied to the side signal\n\t\t\t * @type {Tone.Compressor}\n\t\t\t */\n\t this.side = new Tone.Compressor(options.side);\n\t this._midSideSplit.mid.chain(this.mid, this._midSideMerge.mid);\n\t this._midSideSplit.side.chain(this.side, this._midSideMerge.side);\n\t this._readOnly([\n\t 'mid',\n\t 'side'\n\t ]);\n\t };\n\t Tone.extend(Tone.MidSideCompressor, Tone.AudioNode);\n\t /**\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.MidSideCompressor.defaults = {\n\t 'mid': {\n\t 'ratio': 3,\n\t 'threshold': -24,\n\t 'release': 0.03,\n\t 'attack': 0.02,\n\t 'knee': 16\n\t },\n\t 'side': {\n\t 'ratio': 6,\n\t 'threshold': -30,\n\t 'release': 0.25,\n\t 'attack': 0.03,\n\t 'knee': 10\n\t }\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.MidSideCompressor} this\n\t\t */\n\t Tone.MidSideCompressor.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'mid',\n\t 'side'\n\t ]);\n\t this.mid.dispose();\n\t this.mid = null;\n\t this.side.dispose();\n\t this.side = null;\n\t this._midSideSplit.dispose();\n\t this._midSideSplit = null;\n\t this._midSideMerge.dispose();\n\t this._midSideMerge = null;\n\t return this;\n\t };\n\t return Tone.MidSideCompressor;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Mono coerces the incoming mono or stereo signal into a mono signal\n\t\t * where both left and right channels have the same value. This can be useful\n\t\t * for [stereo imaging](https://en.wikipedia.org/wiki/Stereo_imaging).\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t */\n\t Tone.Mono = function () {\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(1, 0);\n\t /**\n\t\t\t * merge the signal\n\t\t\t * @type {Tone.Merge}\n\t\t\t * @private\n\t\t\t */\n\t this._merge = this.output = new Tone.Merge();\n\t this.input.connect(this._merge, 0, 0);\n\t this.input.connect(this._merge, 0, 1);\n\t };\n\t Tone.extend(Tone.Mono, Tone.AudioNode);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Mono} this\n\t\t */\n\t Tone.Mono.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._merge.dispose();\n\t this._merge = null;\n\t return this;\n\t };\n\t return Tone.Mono;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A compressor with seperate controls over low/mid/high dynamics\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {Object} options The low/mid/high compressor settings.\n\t\t * @example\n\t\t * var multiband = new Tone.MultibandCompressor({\n\t\t * \t\"lowFrequency\" : 200,\n\t\t * \t\"highFrequency\" : 1300\n\t\t * \t\"low\" : {\n\t\t * \t\t\"threshold\" : -12\n\t\t * \t}\n\t\t * })\n\t\t */\n\t Tone.MultibandCompressor = function (options) {\n\t Tone.AudioNode.call(this);\n\t options = Tone.defaultArg(arguments, Tone.MultibandCompressor.defaults);\n\t /**\n\t\t\t * split the incoming signal into high/mid/low\n\t\t\t * @type {Tone.MultibandSplit}\n\t\t\t * @private\n\t\t\t */\n\t this._splitter = this.input = new Tone.MultibandSplit({\n\t 'lowFrequency': options.lowFrequency,\n\t 'highFrequency': options.highFrequency\n\t });\n\t /**\n\t\t\t * low/mid crossover frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.lowFrequency = this._splitter.lowFrequency;\n\t /**\n\t\t\t * mid/high crossover frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.highFrequency = this._splitter.highFrequency;\n\t /**\n\t\t\t * the output\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this.output = new Tone.Gain();\n\t /**\n\t\t\t * The compressor applied to the low frequencies.\n\t\t\t * @type {Tone.Compressor}\n\t\t\t */\n\t this.low = new Tone.Compressor(options.low);\n\t /**\n\t\t\t * The compressor applied to the mid frequencies.\n\t\t\t * @type {Tone.Compressor}\n\t\t\t */\n\t this.mid = new Tone.Compressor(options.mid);\n\t /**\n\t\t\t * The compressor applied to the high frequencies.\n\t\t\t * @type {Tone.Compressor}\n\t\t\t */\n\t this.high = new Tone.Compressor(options.high);\n\t //connect the compressor\n\t this._splitter.low.chain(this.low, this.output);\n\t this._splitter.mid.chain(this.mid, this.output);\n\t this._splitter.high.chain(this.high, this.output);\n\t this._readOnly([\n\t 'high',\n\t 'mid',\n\t 'low',\n\t 'highFrequency',\n\t 'lowFrequency'\n\t ]);\n\t };\n\t Tone.extend(Tone.MultibandCompressor, Tone.AudioNode);\n\t /**\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.MultibandCompressor.defaults = {\n\t 'low': Tone.Compressor.defaults,\n\t 'mid': Tone.Compressor.defaults,\n\t 'high': Tone.Compressor.defaults,\n\t 'lowFrequency': 250,\n\t 'highFrequency': 2000\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.MultibandCompressor} this\n\t\t */\n\t Tone.MultibandCompressor.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._splitter.dispose();\n\t this._writable([\n\t 'high',\n\t 'mid',\n\t 'low',\n\t 'highFrequency',\n\t 'lowFrequency'\n\t ]);\n\t this.low.dispose();\n\t this.mid.dispose();\n\t this.high.dispose();\n\t this._splitter = null;\n\t this.low = null;\n\t this.mid = null;\n\t this.high = null;\n\t this.lowFrequency = null;\n\t this.highFrequency = null;\n\t return this;\n\t };\n\t return Tone.MultibandCompressor;\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported && !window.StereoPannerNode) {\n\t /**\n\t\t\t * @class Shimmed StereoPannerNode\n\t\t\t * @param {AudioContext} context\n\t\t\t * @private\n\t\t\t */\n\t var StereoPannerNode = function (context) {\n\t /**\n\t\t\t\t * The audio context\n\t\t\t\t * @type {AudioContext}\n\t\t\t\t */\n\t this.context = context;\n\t /**\n\t\t\t\t * The left/right panning. [-1, 1]\n\t\t\t\t * @type {AudioRange}\n\t\t\t\t * @signal\n\t\t\t\t */\n\t this.pan = new Tone.Signal(0, Tone.Type.AudioRange);\n\t /**\n\t\t\t\t * Equal power scaling of the right gain\n\t\t\t\t * @type {Tone.WaveShaper}\n\t\t\t\t */\n\t var rightWaveShaper = new Tone.WaveShaper(function (val) {\n\t return Tone.equalPowerScale((val + 1) / 2);\n\t }, 4096);\n\t /**\n\t\t\t\t * Equal power scaling of the left gain\n\t\t\t\t * @type {Tone.WaveShaper}\n\t\t\t\t * @private\n\t\t\t\t */\n\t var leftWaveShaper = new Tone.WaveShaper(function (val) {\n\t return Tone.equalPowerScale(1 - (val + 1) / 2);\n\t }, 4096);\n\t /**\n\t\t\t\t * The left gain value\n\t\t\t\t * @type {Tone.Gain}\n\t\t\t\t * @private\n\t\t\t\t */\n\t var leftGain = new Tone.Gain();\n\t /**\n\t\t\t\t * The right gain value\n\t\t\t\t * @type {Tone.Gain}\n\t\t\t\t * @private\n\t\t\t\t */\n\t var rightGain = new Tone.Gain();\n\t /**\n\t\t\t\t * Split the incoming signal\n\t\t\t\t * @type {Tone.Split}\n\t\t\t\t * @private\n\t\t\t\t */\n\t var split = this.input = new Tone.Split();\n\t /**\n\t\t\t\t * Keeps the waveshapers from optimizing 0s\n\t\t\t\t * @type {Tone.Zero}\n\t\t\t\t * @private\n\t\t\t\t */\n\t var zero = new Tone.Zero();\n\t zero.fan(rightWaveShaper, leftWaveShaper);\n\t /**\n\t\t\t\t * Merge the outgoing signal\n\t\t\t\t * @type {Tone.Merge}\n\t\t\t\t * @private\n\t\t\t\t */\n\t var merge = this.output = new Tone.Merge();\n\t //connections\n\t split.left.chain(leftGain, merge.left);\n\t split.right.chain(rightGain, merge.right);\n\t this.pan.chain(leftWaveShaper, leftGain.gain);\n\t this.pan.chain(rightWaveShaper, rightGain.gain);\n\t };\n\t StereoPannerNode.prototype.disconnect = function () {\n\t this.output.disconnect.apply(this.output, arguments);\n\t };\n\t StereoPannerNode.prototype.connect = function () {\n\t this.output.connect.apply(this.output, arguments);\n\t };\n\t //add it to the AudioContext\n\t AudioContext.prototype.createStereoPanner = function () {\n\t return new StereoPannerNode(this);\n\t };\n\t Tone.Context.prototype.createStereoPanner = function () {\n\t return new StereoPannerNode(this);\n\t };\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Panner is an equal power Left/Right Panner and does not\n\t\t * support 3D. Panner uses the StereoPannerNode when available.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {NormalRange} [initialPan=0] The initail panner value (center).\n\t\t * @example\n\t\t * //pan the input signal hard right.\n\t\t * var panner = new Tone.Panner(1);\n\t\t */\n\t Tone.Panner = function (initialPan) {\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t* the panner node\n\t\t\t* @type {StereoPannerNode}\n\t\t\t* @private\n\t\t\t*/\n\t this._panner = this.input = this.output = this.context.createStereoPanner();\n\t /**\n\t\t\t* The pan control. -1 = hard left, 1 = hard right.\n\t\t\t* @type {AudioRange}\n\t\t\t* @signal\n\t\t\t*/\n\t this.pan = this._panner.pan;\n\t //initial value\n\t this.pan.value = Tone.defaultArg(initialPan, 0);\n\t this._readOnly('pan');\n\t };\n\t Tone.extend(Tone.Panner, Tone.AudioNode);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Panner} this\n\t\t */\n\t Tone.Panner.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable('pan');\n\t this._panner.disconnect();\n\t this._panner = null;\n\t this.pan = null;\n\t return this;\n\t };\n\t return Tone.Panner;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A spatialized panner node which supports equalpower or HRTF panning.\n\t\t * Tries to normalize the API across various browsers. See Tone.Listener\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Number} positionX The initial x position.\n\t\t * @param {Number} positionY The initial y position.\n\t\t * @param {Number} positionZ The initial z position.\n\t\t */\n\t Tone.Panner3D = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'positionX',\n\t 'positionY',\n\t 'positionZ'\n\t ], Tone.Panner3D);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The panner node\n\t\t\t * @type {PannerNode}\n\t\t\t * @private\n\t\t\t */\n\t this._panner = this.input = this.output = this.context.createPanner();\n\t //set some values\n\t this._panner.panningModel = options.panningModel;\n\t this._panner.maxDistance = options.maxDistance;\n\t this._panner.distanceModel = options.distanceModel;\n\t this._panner.coneOuterGain = options.coneOuterGain;\n\t this._panner.coneOuterAngle = options.coneOuterAngle;\n\t this._panner.coneInnerAngle = options.coneInnerAngle;\n\t this._panner.refDistance = options.refDistance;\n\t this._panner.rolloffFactor = options.rolloffFactor;\n\t /**\n\t\t\t * Holds the current orientation\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._orientation = [\n\t options.orientationX,\n\t options.orientationY,\n\t options.orientationZ\n\t ];\n\t /**\n\t\t\t * Holds the current position\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._position = [\n\t options.positionX,\n\t options.positionY,\n\t options.positionZ\n\t ];\n\t // set the default position/orientation\n\t this.orientationX = options.orientationX;\n\t this.orientationY = options.orientationY;\n\t this.orientationZ = options.orientationZ;\n\t this.positionX = options.positionX;\n\t this.positionY = options.positionY;\n\t this.positionZ = options.positionZ;\n\t };\n\t Tone.extend(Tone.Panner3D, Tone.AudioNode);\n\t /**\n\t\t * Defaults according to the specification\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Panner3D.defaults = {\n\t 'positionX': 0,\n\t 'positionY': 0,\n\t 'positionZ': 0,\n\t 'orientationX': 0,\n\t 'orientationY': 0,\n\t 'orientationZ': 0,\n\t 'panningModel': 'equalpower',\n\t 'maxDistance': 10000,\n\t 'distanceModel': 'inverse',\n\t 'coneOuterGain': 0,\n\t 'coneOuterAngle': 360,\n\t 'coneInnerAngle': 360,\n\t 'refDistance': 1,\n\t 'rolloffFactor': 1\n\t };\n\t /**\n\t\t * The ramp time which is applied to the setTargetAtTime\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.Panner3D.prototype._rampTimeConstant = 0.01;\n\t /**\n\t\t * Sets the position of the source in 3d space.\n\t\t * @param {Number} x\n\t\t * @param {Number} y\n\t\t * @param {Number} z\n\t\t * @return {Tone.Panner3D} this\n\t\t */\n\t Tone.Panner3D.prototype.setPosition = function (x, y, z) {\n\t if (this._panner.positionX) {\n\t var now = this.now();\n\t this._panner.positionX.setTargetAtTime(x, now, this._rampTimeConstant);\n\t this._panner.positionY.setTargetAtTime(y, now, this._rampTimeConstant);\n\t this._panner.positionZ.setTargetAtTime(z, now, this._rampTimeConstant);\n\t } else {\n\t this._panner.setPosition(x, y, z);\n\t }\n\t this._position = Array.prototype.slice.call(arguments);\n\t return this;\n\t };\n\t /**\n\t\t * Sets the orientation of the source in 3d space.\n\t\t * @param {Number} x\n\t\t * @param {Number} y\n\t\t * @param {Number} z\n\t\t * @return {Tone.Panner3D} this\n\t\t */\n\t Tone.Panner3D.prototype.setOrientation = function (x, y, z) {\n\t if (this._panner.orientationX) {\n\t var now = this.now();\n\t this._panner.orientationX.setTargetAtTime(x, now, this._rampTimeConstant);\n\t this._panner.orientationY.setTargetAtTime(y, now, this._rampTimeConstant);\n\t this._panner.orientationZ.setTargetAtTime(z, now, this._rampTimeConstant);\n\t } else {\n\t this._panner.setOrientation(x, y, z);\n\t }\n\t this._orientation = Array.prototype.slice.call(arguments);\n\t return this;\n\t };\n\t /**\n\t\t * The x position of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name positionX\n\t\t */\n\t Object.defineProperty(Tone.Panner3D.prototype, 'positionX', {\n\t set: function (pos) {\n\t this._position[0] = pos;\n\t this.setPosition.apply(this, this._position);\n\t },\n\t get: function () {\n\t return this._position[0];\n\t }\n\t });\n\t /**\n\t\t * The y position of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name positionY\n\t\t */\n\t Object.defineProperty(Tone.Panner3D.prototype, 'positionY', {\n\t set: function (pos) {\n\t this._position[1] = pos;\n\t this.setPosition.apply(this, this._position);\n\t },\n\t get: function () {\n\t return this._position[1];\n\t }\n\t });\n\t /**\n\t\t * The z position of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name positionZ\n\t\t */\n\t Object.defineProperty(Tone.Panner3D.prototype, 'positionZ', {\n\t set: function (pos) {\n\t this._position[2] = pos;\n\t this.setPosition.apply(this, this._position);\n\t },\n\t get: function () {\n\t return this._position[2];\n\t }\n\t });\n\t /**\n\t\t * The x orientation of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name orientationX\n\t\t */\n\t Object.defineProperty(Tone.Panner3D.prototype, 'orientationX', {\n\t set: function (pos) {\n\t this._orientation[0] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[0];\n\t }\n\t });\n\t /**\n\t\t * The y orientation of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name orientationY\n\t\t */\n\t Object.defineProperty(Tone.Panner3D.prototype, 'orientationY', {\n\t set: function (pos) {\n\t this._orientation[1] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[1];\n\t }\n\t });\n\t /**\n\t\t * The z orientation of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name orientationZ\n\t\t */\n\t Object.defineProperty(Tone.Panner3D.prototype, 'orientationZ', {\n\t set: function (pos) {\n\t this._orientation[2] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[2];\n\t }\n\t });\n\t /**\n\t\t * Proxy a property on the panner to an exposed public propery\n\t\t * @param {String} prop\n\t\t * @private\n\t\t */\n\t Tone.Panner3D._aliasProperty = function (prop) {\n\t Object.defineProperty(Tone.Panner3D.prototype, prop, {\n\t set: function (val) {\n\t this._panner[prop] = val;\n\t },\n\t get: function () {\n\t return this._panner[prop];\n\t }\n\t });\n\t };\n\t /**\n\t\t * The panning model. Either \"equalpower\" or \"HRTF\".\n\t\t * @type {String}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name panningModel\n\t\t */\n\t Tone.Panner3D._aliasProperty('panningModel');\n\t /**\n\t\t * A reference distance for reducing volume as source move further from the listener\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name refDistance\n\t\t */\n\t Tone.Panner3D._aliasProperty('refDistance');\n\t /**\n\t\t * Describes how quickly the volume is reduced as source moves away from listener.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name rolloffFactor\n\t\t */\n\t Tone.Panner3D._aliasProperty('rolloffFactor');\n\t /**\n\t\t * The distance model used by, \"linear\", \"inverse\", or \"exponential\".\n\t\t * @type {String}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name distanceModel\n\t\t */\n\t Tone.Panner3D._aliasProperty('distanceModel');\n\t /**\n\t\t * The angle, in degrees, inside of which there will be no volume reduction\n\t\t * @type {Degrees}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name coneInnerAngle\n\t\t */\n\t Tone.Panner3D._aliasProperty('coneInnerAngle');\n\t /**\n\t\t * The angle, in degrees, outside of which the volume will be reduced\n\t\t * to a constant value of coneOuterGain\n\t\t * @type {Degrees}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name coneOuterAngle\n\t\t */\n\t Tone.Panner3D._aliasProperty('coneOuterAngle');\n\t /**\n\t\t * The gain outside of the coneOuterAngle\n\t\t * @type {Gain}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name coneOuterGain\n\t\t */\n\t Tone.Panner3D._aliasProperty('coneOuterGain');\n\t /**\n\t\t * The maximum distance between source and listener,\n\t\t * after which the volume will not be reduced any further.\n\t\t * @type {Positive}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name maxDistance\n\t\t */\n\t Tone.Panner3D._aliasProperty('maxDistance');\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Panner3D} this\n\t\t */\n\t Tone.Panner3D.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._panner.disconnect();\n\t this._panner = null;\n\t this._orientation = null;\n\t this._position = null;\n\t return this;\n\t };\n\t return Tone.Panner3D;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.PanVol is a Tone.Panner and Tone.Volume in one.\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {AudioRange} pan the initial pan\n\t\t * @param {number} volume The output volume.\n\t\t * @example\n\t\t * //pan the incoming signal left and drop the volume\n\t\t * var panVol = new Tone.PanVol(-0.25, -12);\n\t\t */\n\t Tone.PanVol = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'pan',\n\t 'volume'\n\t ], Tone.PanVol);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The panning node\n\t\t\t * @type {Tone.Panner}\n\t\t\t * @private\n\t\t\t */\n\t this._panner = this.input = new Tone.Panner(options.pan);\n\t /**\n\t\t\t * The L/R panning control.\n\t\t\t * @type {AudioRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.pan = this._panner.pan;\n\t /**\n\t\t\t * The volume node\n\t\t\t * @type {Tone.Volume}\n\t\t\t * @private\n\t\t\t */\n\t this._volume = this.output = new Tone.Volume(options.volume);\n\t /**\n\t\t\t * The volume control in decibels.\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.volume = this._volume.volume;\n\t //connections\n\t this._panner.connect(this._volume);\n\t this.mute = options.mute;\n\t this._readOnly([\n\t 'pan',\n\t 'volume'\n\t ]);\n\t };\n\t Tone.extend(Tone.PanVol, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @type {Object}\n\t\t * @const\n\t\t * @static\n\t\t */\n\t Tone.PanVol.defaults = {\n\t 'pan': 0,\n\t 'volume': 0,\n\t 'mute': false\n\t };\n\t /**\n\t\t * Mute/unmute the volume\n\t\t * @memberOf Tone.PanVol#\n\t\t * @name mute\n\t\t * @type {Boolean}\n\t\t */\n\t Object.defineProperty(Tone.PanVol.prototype, 'mute', {\n\t get: function () {\n\t return this._volume.mute;\n\t },\n\t set: function (mute) {\n\t this._volume.mute = mute;\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.PanVol} this\n\t\t */\n\t Tone.PanVol.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'pan',\n\t 'volume'\n\t ]);\n\t this._panner.dispose();\n\t this._panner = null;\n\t this.pan = null;\n\t this._volume.dispose();\n\t this._volume = null;\n\t this.volume = null;\n\t return this;\n\t };\n\t return Tone.PanVol;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Solo lets you isolate a specific audio stream. When\n\t\t * an instance is set to `solo=true`, it will mute all other instances.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @example\n\t\t * var soloA = new Tone.Solo()\n\t\t * var soloB = new Tone.Solo()\n\t\t * soloA.solo = true\n\t\t * //no audio will pass through soloB\n\t\t */\n\t Tone.Solo = function () {\n\t var options = Tone.defaults(arguments, ['solo'], Tone.Solo);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The input and output node\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.input = this.output = new Tone.Gain();\n\t /**\n\t\t\t * A bound _soloed method\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._soloBind = this._soloed.bind(this);\n\t //listen for solo events class-wide.\n\t this.context.on('solo', this._soloBind);\n\t //set initially\n\t this.solo = options.solo;\n\t };\n\t Tone.extend(Tone.Solo, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @type {Object}\n\t\t * @static\n\t\t */\n\t Tone.Solo.defaults = { solo: false };\n\t /**\n\t\t * Isolates this instance and mutes all other instances of Tone.Solo.\n\t\t * Only one instance can be soloed at a time. A soloed\n\t\t * instance will report `solo=false` when another instance is soloed.\n\t\t * @memberOf Tone.Solo#\n\t\t * @type {Boolean}\n\t\t * @name solo\n\t\t */\n\t Object.defineProperty(Tone.Solo.prototype, 'solo', {\n\t get: function () {\n\t return this._isSoloed();\n\t },\n\t set: function (solo) {\n\t if (solo) {\n\t this._addSolo();\n\t } else {\n\t this._removeSolo();\n\t }\n\t this.context.emit('solo', this);\n\t }\n\t });\n\t /**\n\t\t * If the current instance is muted, i.e. another instance is soloed\n\t\t * @memberOf Tone.Solo#\n\t\t * @type {Boolean}\n\t\t * @name muted\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Solo.prototype, 'muted', {\n\t get: function () {\n\t return this.input.gain.value === 0;\n\t }\n\t });\n\t /**\n\t\t * Add this to the soloed array\n\t\t * @private\n\t\t */\n\t Tone.Solo.prototype._addSolo = function () {\n\t if (!Tone.isArray(this.context._currentSolo)) {\n\t this.context._currentSolo = [];\n\t }\n\t if (!this._isSoloed()) {\n\t this.context._currentSolo.push(this);\n\t }\n\t };\n\t /**\n\t\t * Remove this from the soloed array\n\t\t * @private\n\t\t */\n\t Tone.Solo.prototype._removeSolo = function () {\n\t if (this._isSoloed()) {\n\t var index = this.context._currentSolo.indexOf(this);\n\t this.context._currentSolo.splice(index, 1);\n\t }\n\t };\n\t /**\n\t\t * @return {Boolean} Is this on the soloed array\n\t\t * @private\n\t\t */\n\t Tone.Solo.prototype._isSoloed = function () {\n\t if (Tone.isArray(this.context._currentSolo)) {\n\t return this.context._currentSolo.length !== 0 && this.context._currentSolo.indexOf(this) !== -1;\n\t } else {\n\t return false;\n\t }\n\t };\n\t /**\n\t\t * @return {Boolean} Returns true if no one is soloed\n\t\t * @private\n\t\t */\n\t Tone.Solo.prototype._noSolos = function () {\n\t return !Tone.isArray(this.context._currentSolo) || this.context._currentSolo.length === 0;\n\t };\n\t /**\n\t\t * Solo the current instance and unsolo all other instances.\n\t\t * @param {Tone.Solo} instance The instance which is being soloed/unsoloed.\n\t\t * @private\n\t\t */\n\t Tone.Solo.prototype._soloed = function () {\n\t if (this._isSoloed()) {\n\t this.input.gain.value = 1;\n\t } else if (this._noSolos()) {\n\t //no one is soloed\n\t this.input.gain.value = 1;\n\t } else {\n\t this.input.gain.value = 0;\n\t }\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Solo} this\n\t\t */\n\t Tone.Solo.prototype.dispose = function () {\n\t this.context.off('solo', this._soloBind);\n\t this._removeSolo();\n\t this._soloBind = null;\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t return this;\n\t };\n\t return Tone.Solo;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Get the current waveform data of the connected audio source.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Number=} size The size of the FFT. Value must be a power of\n\t\t * two in the range 32 to 32768.\n\t\t */\n\t Tone.Waveform = function () {\n\t var options = Tone.defaults(arguments, ['size'], Tone.Waveform);\n\t options.type = Tone.Analyser.Type.Waveform;\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The analyser node.\n\t\t\t * @private\n\t\t\t * @type {Tone.Analyser}\n\t\t\t */\n\t this._analyser = this.input = this.output = new Tone.Analyser(options);\n\t };\n\t Tone.extend(Tone.Waveform, Tone.AudioNode);\n\t /**\n\t\t * The default values.\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Waveform.defaults = { 'size': 1024 };\n\t /**\n\t\t * Gets the waveform of the audio source. Returns the waveform data\n\t\t * of length [size](#size) as a Float32Array with values between -1 and 1.\n\t\t * @returns {TypedArray}\n\t\t */\n\t Tone.Waveform.prototype.getValue = function () {\n\t return this._analyser.getValue();\n\t };\n\t /**\n\t\t * The size of analysis. This must be a power of two in the range 32 to 32768.\n\t\t * @memberOf Tone.Waveform#\n\t\t * @type {Number}\n\t\t * @name size\n\t\t */\n\t Object.defineProperty(Tone.Waveform.prototype, 'size', {\n\t get: function () {\n\t return this._analyser.size;\n\t },\n\t set: function (size) {\n\t this._analyser.size = size;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Waveform} this\n\t\t */\n\t Tone.Waveform.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._analyser.dispose();\n\t this._analyser = null;\n\t };\n\t return Tone.Waveform;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.CtrlInterpolate will interpolate between given values based\n\t\t * on the \"index\" property. Passing in an array or object literal\n\t\t * will interpolate each of the parameters. Note (i.e. \"C3\")\n\t\t * and Time (i.e. \"4n + 2\") can be interpolated. All other values are\n\t\t * assumed to be numbers. \n\t\t * @example\n\t\t * var interp = new Tone.CtrlInterpolate([0, 2, 9, 4]);\n\t\t * interp.index = 0.75;\n\t\t * interp.value; //returns 1.5\n\t\t *\n\t\t * @example\n\t\t * var interp = new Tone.CtrlInterpolate([\n\t\t * \t[2, 4, 5],\n\t\t * \t[9, 3, 2],\n\t\t * ]);\n\t\t * @param {Array} values The array of values to interpolate over\n\t\t * @param {Positive} index The initial interpolation index.\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.CtrlInterpolate = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'values',\n\t 'index'\n\t ], Tone.CtrlInterpolate);\n\t Tone.call(this);\n\t /**\n\t\t\t * The values to interpolate between\n\t\t\t * @type {Array}\n\t\t\t */\n\t this.values = options.values;\n\t /**\n\t\t\t * The interpolated index between values. For example: a value of 1.5\n\t\t\t * would interpolate equally between the value at index 1\n\t\t\t * and the value at index 2. \n\t\t\t * @example\n\t\t\t * interp.index = 0; \n\t\t\t * interp.value; //returns the value at 0\n\t\t\t * interp.index = 0.5;\n\t\t\t * interp.value; //returns the value between indices 0 and 1. \n\t\t\t * @type {Positive}\n\t\t\t */\n\t this.index = options.index;\n\t };\n\t Tone.extend(Tone.CtrlInterpolate);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.CtrlInterpolate.defaults = {\n\t 'index': 0,\n\t 'values': []\n\t };\n\t /**\n\t\t * The current interpolated value based on the index\n\t\t * @readOnly\n\t\t * @memberOf Tone.CtrlInterpolate#\n\t\t * @type {*}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.CtrlInterpolate.prototype, 'value', {\n\t get: function () {\n\t var index = this.index;\n\t index = Math.min(index, this.values.length - 1);\n\t var lowerPosition = Math.floor(index);\n\t var lower = this.values[lowerPosition];\n\t var upper = this.values[Math.ceil(index)];\n\t return this._interpolate(index - lowerPosition, lower, upper);\n\t }\n\t });\n\t /**\n\t\t * Internal interpolation routine\n\t\t * @param {NormalRange} index The index between the lower and upper\n\t\t * @param {*} lower \n\t\t * @param {*} upper \n\t\t * @return {*} The interpolated value\n\t\t * @private\n\t\t */\n\t Tone.CtrlInterpolate.prototype._interpolate = function (index, lower, upper) {\n\t if (Tone.isArray(lower)) {\n\t var retArray = [];\n\t for (var i = 0; i < lower.length; i++) {\n\t retArray[i] = this._interpolate(index, lower[i], upper[i]);\n\t }\n\t return retArray;\n\t } else if (Tone.isObject(lower)) {\n\t var retObj = {};\n\t for (var attr in lower) {\n\t retObj[attr] = this._interpolate(index, lower[attr], upper[attr]);\n\t }\n\t return retObj;\n\t } else {\n\t lower = this._toNumber(lower);\n\t upper = this._toNumber(upper);\n\t return (1 - index) * lower + index * upper;\n\t }\n\t };\n\t /**\n\t\t * Convert from the given type into a number\n\t\t * @param {Number|String} value\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.CtrlInterpolate.prototype._toNumber = function (val) {\n\t if (Tone.isNumber(val)) {\n\t return val;\n\t } else {\n\t //otherwise assume that it's Time...\n\t return this.toSeconds(val);\n\t }\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.CtrlInterpolate} this\n\t\t */\n\t Tone.CtrlInterpolate.prototype.dispose = function () {\n\t this.values = null;\n\t };\n\t return Tone.CtrlInterpolate;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.CtrlMarkov represents a Markov Chain where each call\n\t\t * to Tone.CtrlMarkov.next will move to the next state. If the next\n\t\t * state choice is an array, the next state is chosen randomly with\n\t\t * even probability for all of the choices. For a weighted probability\n\t\t * of the next choices, pass in an object with \"state\" and \"probability\" attributes. \n\t\t * The probabilities will be normalized and then chosen. If no next options\n\t\t * are given for the current state, the state will stay there. \n\t\t * @extends {Tone}\n\t\t * @example\n\t\t * var chain = new Tone.CtrlMarkov({\n\t\t * \t\"beginning\" : [\"end\", \"middle\"],\n\t\t * \t\"middle\" : \"end\"\n\t\t * });\n\t\t * chain.value = \"beginning\";\n\t\t * chain.next(); //returns \"end\" or \"middle\" with 50% probability\n\t\t *\n\t\t * @example\n\t\t * var chain = new Tone.CtrlMarkov({\n\t\t * \t\"beginning\" : [{\"value\" : \"end\", \"probability\" : 0.8}, \n\t\t * \t\t\t\t\t{\"value\" : \"middle\", \"probability\" : 0.2}],\n\t\t * \t\"middle\" : \"end\"\n\t\t * });\n\t\t * chain.value = \"beginning\";\n\t\t * chain.next(); //returns \"end\" with 80% probability or \"middle\" with 20%.\n\t\t * @param {Object} values An object with the state names as the keys\n\t\t * and the next state(s) as the values. \n\t\t */\n\t Tone.CtrlMarkov = function (values, initial) {\n\t Tone.call(this);\n\t /**\n\t\t\t * The Markov values with states as the keys\n\t\t\t * and next state(s) as the values. \n\t\t\t * @type {Object}\n\t\t\t */\n\t this.values = Tone.defaultArg(values, {});\n\t /**\n\t\t\t * The current state of the Markov values. The next\n\t\t\t * state will be evaluated and returned when Tone.CtrlMarkov.next\n\t\t\t * is invoked.\n\t\t\t * @type {String}\n\t\t\t */\n\t this.value = Tone.defaultArg(initial, Object.keys(this.values)[0]);\n\t };\n\t Tone.extend(Tone.CtrlMarkov);\n\t /**\n\t\t * Returns the next state of the Markov values. \n\t\t * @return {String}\n\t\t */\n\t Tone.CtrlMarkov.prototype.next = function () {\n\t if (this.values.hasOwnProperty(this.value)) {\n\t var next = this.values[this.value];\n\t if (Tone.isArray(next)) {\n\t var distribution = this._getProbDistribution(next);\n\t var rand = Math.random();\n\t var total = 0;\n\t for (var i = 0; i < distribution.length; i++) {\n\t var dist = distribution[i];\n\t if (rand > total && rand < total + dist) {\n\t var chosen = next[i];\n\t if (Tone.isObject(chosen)) {\n\t this.value = chosen.value;\n\t } else {\n\t this.value = chosen;\n\t }\n\t }\n\t total += dist;\n\t }\n\t } else {\n\t this.value = next;\n\t }\n\t }\n\t return this.value;\n\t };\n\t /**\n\t\t * Choose randomly from an array weighted options in the form \n\t\t * {\"state\" : string, \"probability\" : number} or an array of values\n\t\t * @param {Array} options \n\t\t * @return {Array} The randomly selected choice\n\t\t * @private\n\t\t */\n\t Tone.CtrlMarkov.prototype._getProbDistribution = function (options) {\n\t var distribution = [];\n\t var total = 0;\n\t var needsNormalizing = false;\n\t for (var i = 0; i < options.length; i++) {\n\t var option = options[i];\n\t if (Tone.isObject(option)) {\n\t needsNormalizing = true;\n\t distribution[i] = option.probability;\n\t } else {\n\t distribution[i] = 1 / options.length;\n\t }\n\t total += distribution[i];\n\t }\n\t if (needsNormalizing) {\n\t //normalize the values\n\t for (var j = 0; j < distribution.length; j++) {\n\t distribution[j] = distribution[j] / total;\n\t }\n\t }\n\t return distribution;\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.CtrlMarkov} this\n\t\t */\n\t Tone.CtrlMarkov.prototype.dispose = function () {\n\t this.values = null;\n\t };\n\t return Tone.CtrlMarkov;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Generate patterns from an array of values.\n\t\t * Has a number of arpeggiation and randomized\n\t\t * selection patterns. \n\t\t * <ul>\n\t\t * \t <li>\"up\" - cycles upward</li>\n\t\t * \t\t\t<li>\"down\" - cycles downward</li>\n\t\t * \t\t\t<li>\"upDown\" - up then and down</li>\n\t\t * \t\t\t<li>\"downUp\" - cycles down then and up</li>\n\t\t * \t\t\t<li>\"alternateUp\" - jump up two and down one</li>\n\t\t * \t\t\t<li>\"alternateDown\" - jump down two and up one</li>\n\t\t * \t\t\t<li>\"random\" - randomly select an index</li>\n\t\t * \t\t\t<li>\"randomWalk\" - randomly moves one index away from the current position</li>\n\t\t * \t\t\t<li>\"randomOnce\" - randomly select an index without repeating until all values have been chosen.</li>\n\t\t * \t\t</ul>\n\t\t * @param {Array} values An array of options to choose from.\n\t\t * @param {Tone.CtrlPattern.Type=} type The name of the pattern.\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.CtrlPattern = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'values',\n\t 'type'\n\t ], Tone.CtrlPattern);\n\t Tone.call(this);\n\t /**\n\t\t\t * The array of values to arpeggiate over\n\t\t\t * @type {Array}\n\t\t\t */\n\t this.values = options.values;\n\t /**\n\t\t\t * The current position in the values array\n\t\t\t * @type {Number}\n\t\t\t */\n\t this.index = 0;\n\t /**\n\t\t\t * The type placeholder\n\t\t\t * @type {Tone.CtrlPattern.Type}\n\t\t\t * @private\n\t\t\t */\n\t this._type = null;\n\t /**\n\t\t\t * Shuffled values for the RandomOnce type\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._shuffled = null;\n\t /**\n\t\t\t * The direction of the movement\n\t\t\t * @type {String}\n\t\t\t * @private\n\t\t\t */\n\t this._direction = null;\n\t this.type = options.type;\n\t };\n\t Tone.extend(Tone.CtrlPattern);\n\t /**\n\t\t * The Control Patterns\n\t\t * @type {Object}\n\t\t * @static\n\t\t */\n\t Tone.CtrlPattern.Type = {\n\t Up: 'up',\n\t Down: 'down',\n\t UpDown: 'upDown',\n\t DownUp: 'downUp',\n\t AlternateUp: 'alternateUp',\n\t AlternateDown: 'alternateDown',\n\t Random: 'random',\n\t RandomWalk: 'randomWalk',\n\t RandomOnce: 'randomOnce'\n\t };\n\t /**\n\t\t * The default values. \n\t\t * @type {Object}\n\t\t */\n\t Tone.CtrlPattern.defaults = {\n\t 'type': Tone.CtrlPattern.Type.Up,\n\t 'values': []\n\t };\n\t /**\n\t\t * The value at the current index of the pattern.\n\t\t * @readOnly\n\t\t * @memberOf Tone.CtrlPattern#\n\t\t * @type {*}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.CtrlPattern.prototype, 'value', {\n\t get: function () {\n\t //some safeguards\n\t if (this.values.length === 0) {\n\t return;\n\t } else if (this.values.length === 1) {\n\t return this.values[0];\n\t }\n\t this.index = Math.min(this.index, this.values.length - 1);\n\t var val = this.values[this.index];\n\t if (this.type === Tone.CtrlPattern.Type.RandomOnce) {\n\t if (this.values.length !== this._shuffled.length) {\n\t this._shuffleValues();\n\t }\n\t val = this.values[this._shuffled[this.index]];\n\t }\n\t return val;\n\t }\n\t });\n\t /**\n\t\t * The pattern used to select the next\n\t\t * item from the values array\n\t\t * @memberOf Tone.CtrlPattern#\n\t\t * @type {Tone.CtrlPattern.Type}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.CtrlPattern.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t this._type = type;\n\t this._shuffled = null;\n\t //the first index\n\t if (this._type === Tone.CtrlPattern.Type.Up || this._type === Tone.CtrlPattern.Type.UpDown || this._type === Tone.CtrlPattern.Type.RandomOnce || this._type === Tone.CtrlPattern.Type.AlternateUp) {\n\t this.index = 0;\n\t } else if (this._type === Tone.CtrlPattern.Type.Down || this._type === Tone.CtrlPattern.Type.DownUp || this._type === Tone.CtrlPattern.Type.AlternateDown) {\n\t this.index = this.values.length - 1;\n\t }\n\t //the direction\n\t if (this._type === Tone.CtrlPattern.Type.UpDown || this._type === Tone.CtrlPattern.Type.AlternateUp) {\n\t this._direction = Tone.CtrlPattern.Type.Up;\n\t } else if (this._type === Tone.CtrlPattern.Type.DownUp || this._type === Tone.CtrlPattern.Type.AlternateDown) {\n\t this._direction = Tone.CtrlPattern.Type.Down;\n\t }\n\t //randoms\n\t if (this._type === Tone.CtrlPattern.Type.RandomOnce) {\n\t this._shuffleValues();\n\t } else if (this._type === Tone.CtrlPattern.Random) {\n\t this.index = Math.floor(Math.random() * this.values.length);\n\t }\n\t }\n\t });\n\t /**\n\t\t * Return the next value given the current position\n\t\t * and pattern.\n\t\t * @return {*} The next value\n\t\t */\n\t Tone.CtrlPattern.prototype.next = function () {\n\t var type = this.type;\n\t //choose the next index\n\t if (type === Tone.CtrlPattern.Type.Up) {\n\t this.index++;\n\t if (this.index >= this.values.length) {\n\t this.index = 0;\n\t }\n\t } else if (type === Tone.CtrlPattern.Type.Down) {\n\t this.index--;\n\t if (this.index < 0) {\n\t this.index = this.values.length - 1;\n\t }\n\t } else if (type === Tone.CtrlPattern.Type.UpDown || type === Tone.CtrlPattern.Type.DownUp) {\n\t if (this._direction === Tone.CtrlPattern.Type.Up) {\n\t this.index++;\n\t } else {\n\t this.index--;\n\t }\n\t if (this.index < 0) {\n\t this.index = 1;\n\t this._direction = Tone.CtrlPattern.Type.Up;\n\t } else if (this.index >= this.values.length) {\n\t this.index = this.values.length - 2;\n\t this._direction = Tone.CtrlPattern.Type.Down;\n\t }\n\t } else if (type === Tone.CtrlPattern.Type.Random) {\n\t this.index = Math.floor(Math.random() * this.values.length);\n\t } else if (type === Tone.CtrlPattern.Type.RandomWalk) {\n\t if (Math.random() < 0.5) {\n\t this.index--;\n\t this.index = Math.max(this.index, 0);\n\t } else {\n\t this.index++;\n\t this.index = Math.min(this.index, this.values.length - 1);\n\t }\n\t } else if (type === Tone.CtrlPattern.Type.RandomOnce) {\n\t this.index++;\n\t if (this.index >= this.values.length) {\n\t this.index = 0;\n\t //reshuffle the values for next time\n\t this._shuffleValues();\n\t }\n\t } else if (type === Tone.CtrlPattern.Type.AlternateUp) {\n\t if (this._direction === Tone.CtrlPattern.Type.Up) {\n\t this.index += 2;\n\t this._direction = Tone.CtrlPattern.Type.Down;\n\t } else {\n\t this.index -= 1;\n\t this._direction = Tone.CtrlPattern.Type.Up;\n\t }\n\t if (this.index >= this.values.length) {\n\t this.index = 0;\n\t this._direction = Tone.CtrlPattern.Type.Up;\n\t }\n\t } else if (type === Tone.CtrlPattern.Type.AlternateDown) {\n\t if (this._direction === Tone.CtrlPattern.Type.Up) {\n\t this.index += 1;\n\t this._direction = Tone.CtrlPattern.Type.Down;\n\t } else {\n\t this.index -= 2;\n\t this._direction = Tone.CtrlPattern.Type.Up;\n\t }\n\t if (this.index < 0) {\n\t this.index = this.values.length - 1;\n\t this._direction = Tone.CtrlPattern.Type.Down;\n\t }\n\t }\n\t return this.value;\n\t };\n\t /**\n\t\t * Shuffles the values and places the results into the _shuffled\n\t\t * @private\n\t\t */\n\t Tone.CtrlPattern.prototype._shuffleValues = function () {\n\t var copy = [];\n\t this._shuffled = [];\n\t for (var i = 0; i < this.values.length; i++) {\n\t copy[i] = i;\n\t }\n\t while (copy.length > 0) {\n\t var randVal = copy.splice(Math.floor(copy.length * Math.random()), 1);\n\t this._shuffled.push(randVal[0]);\n\t }\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @returns {Tone.CtrlPattern} this\n\t\t */\n\t Tone.CtrlPattern.prototype.dispose = function () {\n\t this._shuffled = null;\n\t this.values = null;\n\t };\n\t return Tone.CtrlPattern;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Choose a random value.\n\t\t * @extends {Tone}\n\t\t * @example\n\t\t * var randomWalk = new Tone.CtrlRandom({\n\t\t * \t\"min\" : 0,\n\t\t * \t\"max\" : 10,\n\t\t * \t\"integer\" : true\n\t\t * });\n\t\t * randomWalk.eval();\n\t\t *\n\t\t * @param {Number|Time=} min The minimum return value.\n\t\t * @param {Number|Time=} max The maximum return value.\n\t\t */\n\t Tone.CtrlRandom = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'min',\n\t 'max'\n\t ], Tone.CtrlRandom);\n\t Tone.call(this);\n\t /**\n\t\t\t * The minimum return value\n\t\t\t * @type {Number|Time}\n\t\t\t */\n\t this.min = options.min;\n\t /**\n\t\t\t * The maximum return value\n\t\t\t * @type {Number|Time}\n\t\t\t */\n\t this.max = options.max;\n\t /**\n\t\t\t * If the return value should be an integer\n\t\t\t * @type {Boolean}\n\t\t\t */\n\t this.integer = options.integer;\n\t };\n\t Tone.extend(Tone.CtrlRandom);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.CtrlRandom.defaults = {\n\t 'min': 0,\n\t 'max': 1,\n\t 'integer': false\n\t };\n\t /**\n\t\t * Return a random value between min and max. \n\t\t * @readOnly\n\t\t * @memberOf Tone.CtrlRandom#\n\t\t * @type {*}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.CtrlRandom.prototype, 'value', {\n\t get: function () {\n\t var min = this.toSeconds(this.min);\n\t var max = this.toSeconds(this.max);\n\t var rand = Math.random();\n\t var val = rand * min + (1 - rand) * max;\n\t if (this.integer) {\n\t val = Math.floor(val);\n\t }\n\t return val;\n\t }\n\t });\n\t return Tone.CtrlRandom;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class A data structure for holding multiple buffers.\n\t\t * \n\t\t * @param {Object|Array} urls An object literal or array\n\t\t * of urls to load.\n\t\t * @param {Function=} callback The callback to invoke when\n\t\t * the buffers are loaded. \n\t\t * @extends {Tone}\n\t\t * @example\n\t\t * //load a whole bank of piano samples\n\t\t * var pianoSamples = new Tone.Buffers({\n\t\t * \t\"C4\" : \"path/to/C4.mp3\"\n\t\t * \t\"C#4\" : \"path/to/C#4.mp3\"\n\t\t * \t\"D4\" : \"path/to/D4.mp3\"\n\t\t * \t\"D#4\" : \"path/to/D#4.mp3\"\n\t\t * \t...\n\t\t * }, function(){\n\t\t * \t//play one of the samples when they all load\n\t\t * \tplayer.buffer = pianoSamples.get(\"C4\");\n\t\t * \tplayer.start();\n\t\t * });\n\t\t * \t@example\n\t\t * //To pass in additional parameters in the second parameter\n\t\t * var buffers = new Tone.Buffers(urls, {\n\t\t * \t\"onload\" : callback,\n\t\t * \t\"baseUrl\" : \"../path/to/audio/\"\n\t\t * })\n\t\t */\n\t Tone.Buffers = function (urls) {\n\t //remove the urls from the options\n\t var args = Array.prototype.slice.call(arguments);\n\t args.shift();\n\t var options = Tone.defaults(args, [\n\t 'onload',\n\t 'baseUrl'\n\t ], Tone.Buffers);\n\t Tone.call(this);\n\t /**\n\t\t\t * All of the buffers\n\t\t\t * @type {Object}\n\t\t\t * @private\n\t\t\t */\n\t this._buffers = {};\n\t /**\n\t\t\t * A path which is prefixed before every url.\n\t\t\t * @type {String}\n\t\t\t */\n\t this.baseUrl = options.baseUrl;\n\t this._loadingCount = 0;\n\t //add each one\n\t for (var key in urls) {\n\t this._loadingCount++;\n\t this.add(key, urls[key], this._bufferLoaded.bind(this, options.onload));\n\t }\n\t };\n\t Tone.extend(Tone.Buffers);\n\t /**\n\t\t * Defaults\n\t\t * @type {Object}\n\t\t */\n\t Tone.Buffers.defaults = {\n\t 'onload': Tone.noOp,\n\t 'baseUrl': ''\n\t };\n\t /**\n\t\t * True if the buffers object has a buffer by that name.\n\t\t * @param {String|Number} name The key or index of the \n\t\t * buffer.\n\t\t * @return {Boolean}\n\t\t */\n\t Tone.Buffers.prototype.has = function (name) {\n\t return this._buffers.hasOwnProperty(name);\n\t };\n\t /**\n\t\t * Get a buffer by name. If an array was loaded, \n\t\t * then use the array index.\n\t\t * @param {String|Number} name The key or index of the \n\t\t * buffer.\n\t\t * @return {Tone.Buffer}\n\t\t */\n\t Tone.Buffers.prototype.get = function (name) {\n\t if (this.has(name)) {\n\t return this._buffers[name];\n\t } else {\n\t throw new Error('Tone.Buffers: no buffer named ' + name);\n\t }\n\t };\n\t /**\n\t\t * A buffer was loaded. decrement the counter.\n\t\t * @param {Function} callback \n\t\t * @private\n\t\t */\n\t Tone.Buffers.prototype._bufferLoaded = function (callback) {\n\t this._loadingCount--;\n\t if (this._loadingCount === 0 && callback) {\n\t callback(this);\n\t }\n\t };\n\t /**\n\t\t * If the buffers are loaded or not\n\t\t * @memberOf Tone.Buffers#\n\t\t * @type {Boolean}\n\t\t * @name loaded\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Buffers.prototype, 'loaded', {\n\t get: function () {\n\t var isLoaded = true;\n\t for (var buffName in this._buffers) {\n\t var buff = this.get(buffName);\n\t isLoaded = isLoaded && buff.loaded;\n\t }\n\t return isLoaded;\n\t }\n\t });\n\t /**\n\t\t * Add a buffer by name and url to the Buffers\n\t\t * @param {String} name A unique name to give\n\t\t * the buffer\n\t\t * @param {String|Tone.Buffer|Audiobuffer} url Either the url of the bufer, \n\t\t * or a buffer which will be added\n\t\t * with the given name.\n\t\t * @param {Function=} callback The callback to invoke \n\t\t * when the url is loaded.\n\t\t */\n\t Tone.Buffers.prototype.add = function (name, url, callback) {\n\t callback = Tone.defaultArg(callback, Tone.noOp);\n\t if (url instanceof Tone.Buffer) {\n\t this._buffers[name] = url;\n\t callback(this);\n\t } else if (url instanceof AudioBuffer) {\n\t this._buffers[name] = new Tone.Buffer(url);\n\t callback(this);\n\t } else if (Tone.isString(url)) {\n\t this._buffers[name] = new Tone.Buffer(this.baseUrl + url, callback);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Buffers} this\n\t\t */\n\t Tone.Buffers.prototype.dispose = function () {\n\t Tone.prototype.dispose.call(this);\n\t for (var name in this._buffers) {\n\t this._buffers[name].dispose();\n\t }\n\t this._buffers = null;\n\t return this;\n\t };\n\t return Tone.Buffers;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * buses are another way of routing audio\n\t\t *\n\t\t * augments Tone.prototype to include send and recieve\n\t\t */\n\t /**\n\t\t * All of the routes\n\t\t *\n\t\t * @type {Object}\n\t\t * @static\n\t\t * @private\n\t\t */\n\t var Buses = {};\n\t /**\n\t\t * Send this signal to the channel name.\n\t\t * @param {String} channelName A named channel to send the signal to.\n\t\t * @param {Decibels} amount The amount of the source to send to the bus.\n\t\t * @return {GainNode} The gain node which connects this node to the desired channel.\n\t\t * Can be used to adjust the levels of the send.\n\t\t * @example\n\t\t * source.send(\"reverb\", -12);\n\t\t */\n\t Tone.prototype.send = function (channelName, amount) {\n\t if (!Buses.hasOwnProperty(channelName)) {\n\t Buses[channelName] = this.context.createGain();\n\t }\n\t amount = Tone.defaultArg(amount, 0);\n\t var sendKnob = new Tone.Gain(amount, Tone.Type.Decibels);\n\t this.connect(sendKnob);\n\t sendKnob.connect(Buses[channelName]);\n\t return sendKnob;\n\t };\n\t /**\n\t\t * Recieve the input from the desired channelName to the input\n\t\t *\n\t\t * @param {String} channelName A named channel to send the signal to.\n\t\t * @param {Number=} channelNumber The channel to connect to\n\t\t * @returns {Tone} this\n\t\t * @example\n\t\t * reverbEffect.receive(\"reverb\");\n\t\t */\n\t Tone.prototype.receive = function (channelName, inputNum) {\n\t if (!Buses.hasOwnProperty(channelName)) {\n\t Buses[channelName] = this.context.createGain();\n\t }\n\t Buses[channelName].connect(this, 0, inputNum);\n\t return this;\n\t };\n\t //remove all the send/receives when a new audio context is passed in\n\t Tone.Context.on('init', function (context) {\n\t if (context.Buses) {\n\t Buses = context.Buses;\n\t } else {\n\t Buses = {};\n\t context.Buses = Buses;\n\t }\n\t });\n\t return Tone;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Draw is useful for synchronizing visuals and audio events.\n\t\t * Callbacks from Tone.Transport or any of the Tone.Event classes\n\t\t * always happen _before_ the scheduled time and are not synchronized\n\t\t * to the animation frame so they are not good for triggering tightly\n\t\t * synchronized visuals and sound. Tone.Draw makes it easy to schedule\n\t\t * callbacks using the AudioContext time and uses requestAnimationFrame.\n\t\t * \n\t\t * @singleton\n\t\t * @extends {Tone}\n\t\t * @example\n\t\t * Tone.Transport.schedule(function(time){\n\t\t * \t//use the time argument to schedule a callback with Tone.Draw\n\t\t * \tTone.Draw.schedule(function(){\n\t\t * \t\t//do drawing or DOM manipulation here\n\t\t * \t}, time)\n\t\t * }, \"+0.5\")\n\t\t */\n\t Tone.Draw = function () {\n\t Tone.call(this);\n\t /**\n\t\t\t * All of the events.\n\t\t\t * @type {Tone.Timeline}\n\t\t\t * @private\n\t\t\t */\n\t this._events = new Tone.Timeline();\n\t /**\n\t\t\t * The duration after which events are not invoked.\n\t\t\t * @type {Number}\n\t\t\t * @default 0.25\n\t\t\t */\n\t this.expiration = 0.25;\n\t /**\n\t\t\t * The amount of time before the scheduled time \n\t\t\t * that the callback can be invoked. Default is\n\t\t\t * half the time of an animation frame (0.008 seconds).\n\t\t\t * @type {Number}\n\t\t\t * @default 0.008\n\t\t\t */\n\t this.anticipation = 0.008;\n\t /**\n\t\t\t * The draw loop\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._boundDrawLoop = this._drawLoop.bind(this);\n\t };\n\t Tone.extend(Tone.Draw);\n\t /**\n\t\t * Schedule a function at the given time to be invoked\n\t\t * on the nearest animation frame.\n\t\t * @param {Function} callback Callback is invoked at the given time.\n\t\t * @param {Time} time The time relative to the AudioContext time\n\t\t * to invoke the callback.\n\t\t * @return {Tone.Draw} this\n\t\t */\n\t Tone.Draw.prototype.schedule = function (callback, time) {\n\t this._events.add({\n\t callback: callback,\n\t time: this.toSeconds(time)\n\t });\n\t //start the draw loop on the first event\n\t if (this._events.length === 1) {\n\t requestAnimationFrame(this._boundDrawLoop);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Cancel events scheduled after the given time\n\t\t * @param {Time=} after Time after which scheduled events will \n\t\t * be removed from the scheduling timeline.\n\t\t * @return {Tone.Draw} this\n\t\t */\n\t Tone.Draw.prototype.cancel = function (after) {\n\t this._events.cancel(this.toSeconds(after));\n\t return this;\n\t };\n\t /**\n\t\t * The draw loop\n\t\t * @private\n\t\t */\n\t Tone.Draw.prototype._drawLoop = function () {\n\t var now = Tone.now();\n\t while (this._events.length && this._events.peek().time - this.anticipation <= now) {\n\t var event = this._events.shift();\n\t if (now - event.time <= this.expiration) {\n\t event.callback();\n\t }\n\t }\n\t if (this._events.length > 0) {\n\t requestAnimationFrame(this._boundDrawLoop);\n\t }\n\t };\n\t //make a singleton\n\t Tone.Draw = new Tone.Draw();\n\t return Tone.Draw;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Both Tone.Panner3D and Tone.Listener have a position in 3D space\n\t\t * using a right-handed cartesian coordinate system.\n\t\t * The units used in the coordinate system are not defined;\n\t\t * these coordinates are independent/invariant of any particular\n\t\t * units such as meters or feet. Tone.Panner3D objects have an forward\n\t\t * vector representing the direction the sound is projecting. Additionally,\n\t\t * they have a sound cone representing how directional the sound is.\n\t\t * For example, the sound could be omnidirectional, in which case it would\n\t\t * be heard anywhere regardless of its forward, or it can be more directional\n\t\t * and heard only if it is facing the listener. Tone.Listener objects\n\t\t * (representing a person's ears) have an forward and up vector\n\t\t * representing in which direction the person is facing. Because both the\n\t\t * source stream and the listener can be moving, they both have a velocity\n\t\t * vector representing both the speed and direction of movement. Taken together,\n\t\t * these two velocities can be used to generate a doppler shift effect which changes the pitch.\n\t\t * <br><br>\n\t\t * Note: the position of the Listener will have no effect on nodes not connected to a Tone.Panner3D\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone}\n\t\t * @singleton\n\t\t */\n\t Tone.Listener = function () {\n\t Tone.call(this);\n\t /**\n\t\t\t * Holds the current forward orientation\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._orientation = [\n\t 0,\n\t 0,\n\t 0,\n\t 0,\n\t 0,\n\t 0\n\t ];\n\t /**\n\t\t\t * Holds the current position\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._position = [\n\t 0,\n\t 0,\n\t 0\n\t ];\n\t Tone.getContext(function () {\n\t // set the default position/forward\n\t this.set(ListenerConstructor.defaults);\n\t }.bind(this));\n\t };\n\t Tone.extend(Tone.Listener);\n\t /**\n\t\t * Defaults according to the specification\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Listener.defaults = {\n\t 'positionX': 0,\n\t 'positionY': 0,\n\t 'positionZ': 0,\n\t 'forwardX': 0,\n\t 'forwardY': 0,\n\t 'forwardZ': 1,\n\t 'upX': 0,\n\t 'upY': 1,\n\t 'upZ': 0\n\t };\n\t /**\n\t\t * The ramp time which is applied to the setTargetAtTime\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.Listener.prototype._rampTimeConstant = 0.01;\n\t /**\n\t\t * Sets the position of the listener in 3d space.\n\t\t * @param {Number} x\n\t\t * @param {Number} y\n\t\t * @param {Number} z\n\t\t * @return {Tone.Listener} this\n\t\t */\n\t Tone.Listener.prototype.setPosition = function (x, y, z) {\n\t if (this.context.listener.positionX) {\n\t var now = this.now();\n\t this.context.listener.positionX.setTargetAtTime(x, now, this._rampTimeConstant);\n\t this.context.listener.positionY.setTargetAtTime(y, now, this._rampTimeConstant);\n\t this.context.listener.positionZ.setTargetAtTime(z, now, this._rampTimeConstant);\n\t } else {\n\t this.context.listener.setPosition(x, y, z);\n\t }\n\t this._position = Array.prototype.slice.call(arguments);\n\t return this;\n\t };\n\t /**\n\t\t * Sets the orientation of the listener using two vectors, the forward\n\t\t * vector (which direction the listener is facing) and the up vector\n\t\t * (which the up direction of the listener). An up vector\n\t\t * of 0, 0, 1 is equivalent to the listener standing up in the Z direction.\n\t\t * @param {Number} x\n\t\t * @param {Number} y\n\t\t * @param {Number} z\n\t\t * @param {Number} upX\n\t\t * @param {Number} upY\n\t\t * @param {Number} upZ\n\t\t * @return {Tone.Listener} this\n\t\t */\n\t Tone.Listener.prototype.setOrientation = function (x, y, z, upX, upY, upZ) {\n\t if (this.context.listener.forwardX) {\n\t var now = this.now();\n\t this.context.listener.forwardX.setTargetAtTime(x, now, this._rampTimeConstant);\n\t this.context.listener.forwardY.setTargetAtTime(y, now, this._rampTimeConstant);\n\t this.context.listener.forwardZ.setTargetAtTime(z, now, this._rampTimeConstant);\n\t this.context.listener.upX.setTargetAtTime(upX, now, this._rampTimeConstant);\n\t this.context.listener.upY.setTargetAtTime(upY, now, this._rampTimeConstant);\n\t this.context.listener.upZ.setTargetAtTime(upZ, now, this._rampTimeConstant);\n\t } else {\n\t this.context.listener.setOrientation(x, y, z, upX, upY, upZ);\n\t }\n\t this._orientation = Array.prototype.slice.call(arguments);\n\t return this;\n\t };\n\t /**\n\t\t * The x position of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name positionX\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'positionX', {\n\t set: function (pos) {\n\t this._position[0] = pos;\n\t this.setPosition.apply(this, this._position);\n\t },\n\t get: function () {\n\t return this._position[0];\n\t }\n\t });\n\t /**\n\t\t * The y position of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name positionY\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'positionY', {\n\t set: function (pos) {\n\t this._position[1] = pos;\n\t this.setPosition.apply(this, this._position);\n\t },\n\t get: function () {\n\t return this._position[1];\n\t }\n\t });\n\t /**\n\t\t * The z position of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name positionZ\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'positionZ', {\n\t set: function (pos) {\n\t this._position[2] = pos;\n\t this.setPosition.apply(this, this._position);\n\t },\n\t get: function () {\n\t return this._position[2];\n\t }\n\t });\n\t /**\n\t\t * The x coordinate of the listeners front direction. i.e.\n\t\t * which way they are facing.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name forwardX\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'forwardX', {\n\t set: function (pos) {\n\t this._orientation[0] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[0];\n\t }\n\t });\n\t /**\n\t\t * The y coordinate of the listeners front direction. i.e.\n\t\t * which way they are facing.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name forwardY\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'forwardY', {\n\t set: function (pos) {\n\t this._orientation[1] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[1];\n\t }\n\t });\n\t /**\n\t\t * The z coordinate of the listeners front direction. i.e.\n\t\t * which way they are facing.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name forwardZ\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'forwardZ', {\n\t set: function (pos) {\n\t this._orientation[2] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[2];\n\t }\n\t });\n\t /**\n\t\t * The x coordinate of the listener's up direction. i.e.\n\t\t * the direction the listener is standing in.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name upX\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'upX', {\n\t set: function (pos) {\n\t this._orientation[3] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[3];\n\t }\n\t });\n\t /**\n\t\t * The y coordinate of the listener's up direction. i.e.\n\t\t * the direction the listener is standing in.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name upY\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'upY', {\n\t set: function (pos) {\n\t this._orientation[4] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[4];\n\t }\n\t });\n\t /**\n\t\t * The z coordinate of the listener's up direction. i.e.\n\t\t * the direction the listener is standing in.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name upZ\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'upZ', {\n\t set: function (pos) {\n\t this._orientation[5] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[5];\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Listener} this\n\t\t */\n\t Tone.Listener.prototype.dispose = function () {\n\t this._orientation = null;\n\t this._position = null;\n\t return this;\n\t };\n\t //SINGLETON SETUP\n\t var ListenerConstructor = Tone.Listener;\n\t Tone.Listener = new ListenerConstructor();\n\t Tone.Context.on('init', function (context) {\n\t if (context.Listener instanceof ListenerConstructor) {\n\t //a single listener object\n\t Tone.Listener = context.Listener;\n\t } else {\n\t //make new Listener insides\n\t Tone.Listener = new ListenerConstructor();\n\t }\n\t context.Listener = Tone.Listener;\n\t });\n\t //END SINGLETON SETUP\n\t return Tone.Listener;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * Because of a bug in iOS causing the currentTime to increment\n\t\t * before the rendering is started, sometimes it takes multiple\n\t\t * attempts to render the audio correctly.\n\t\t * @private\n\t\t */\n\t function attemptRender(callback, duration, sampleRate, tries) {\n\t tries = Tone.defaultArg(tries, 0);\n\t var context = new Tone.OfflineContext(2, duration, sampleRate);\n\t Tone.context = context;\n\t //invoke the callback/scheduling\n\t var response = callback(Tone.Transport);\n\t if (context.currentTime > 0 && tries < 1000) {\n\t return attemptRender(callback, duration, sampleRate, ++tries);\n\t } else {\n\t return {\n\t 'response': response,\n\t 'context': context\n\t };\n\t }\n\t }\n\t /**\n\t\t * Generate a buffer by rendering all of the Tone.js code within the callback using the OfflineAudioContext.\n\t\t * The OfflineAudioContext is capable of rendering much faster than real time in many cases.\n\t\t * The callback function also passes in an offline instance of Tone.Transport which can be used\n\t\t * to schedule events along the Transport. **NOTE** OfflineAudioContext has the same restrictions\n\t\t * as the AudioContext in that on certain platforms (like iOS) it must be invoked by an explicit\n\t\t * user action like a click or tap. \n\t\t * @param {Function} callback All Tone.js nodes which are created and scheduled within this callback are recorded into the output Buffer.\n\t\t * @param {Time} duration the amount of time to record for.\n\t\t * @return {Promise} The promise which is invoked with the Tone.Buffer of the recorded output.\n\t\t * @example\n\t\t * //render 2 seconds of the oscillator\n\t\t * Tone.Offline(function(){\n\t\t * \t//only nodes created in this callback will be recorded\n\t\t * \tvar oscillator = new Tone.Oscillator().toMaster().start(0)\n\t\t * \t//schedule their events\n\t\t * }, 2).then(function(buffer){\n\t\t * \t//do something with the output buffer\n\t\t * })\n\t\t * @example\n\t\t * //can also schedule events along the Transport\n\t\t * //using the passed in Offline Transport\n\t\t * Tone.Offline(function(Transport){\n\t\t * \tvar osc = new Tone.Oscillator().toMaster()\n\t\t * \tTransport.schedule(function(time){\n\t\t * \t\tosc.start(time).stop(time + 0.1)\n\t\t * \t}, 1)\n\t\t * \tTransport.start(0.2)\n\t\t * }, 4).then(function(buffer){\n\t\t * \t//do something with the output buffer\n\t\t * })\n\t\t */\n\t Tone.Offline = function (callback, duration) {\n\t //set the OfflineAudioContext\n\t var sampleRate = Tone.context.sampleRate;\n\t var originalContext = Tone.context;\n\t var renderRet = attemptRender(callback, duration, sampleRate);\n\t var response = renderRet.response;\n\t var context = renderRet.context;\n\t var ret;\n\t if (response instanceof Promise) {\n\t //wait for the promise to resolve\n\t ret = response.then(function () {\n\t //then render the audio\n\t return context.render();\n\t });\n\t } else {\n\t //process the audio\n\t ret = context.render();\n\t }\n\t //return the original AudioContext\n\t Tone.context = originalContext;\n\t //return the audio\n\t return ret.then(function (buffer) {\n\t //wrap it in a Tone.Buffer\n\t return new Tone.Buffer(buffer);\n\t });\n\t };\n\t return Tone.Offline;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * \t@class Tone.Effect is the base class for effects. Connect the effect between\n\t\t * \t the effectSend and effectReturn GainNodes, then control the amount of\n\t\t * \t effect which goes to the output using the wet control.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {NormalRange|Object} [wet] The starting wet value.\n\t\t */\n\t Tone.Effect = function () {\n\t var options = Tone.defaults(arguments, ['wet'], Tone.Effect);\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(1, 1);\n\t /**\n\t\t\t * the drywet knob to control the amount of effect\n\t\t\t * @type {Tone.CrossFade}\n\t\t\t * @private\n\t\t\t */\n\t this._dryWet = new Tone.CrossFade(options.wet);\n\t /**\n\t\t\t * The wet control is how much of the effected\n\t\t\t * will pass through to the output. 1 = 100% effected\n\t\t\t * signal, 0 = 100% dry signal.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.wet = this._dryWet.fade;\n\t /**\n\t\t\t * connect the effectSend to the input of hte effect\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this.effectSend = new Tone.Gain();\n\t /**\n\t\t\t * connect the output of the effect to the effectReturn\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this.effectReturn = new Tone.Gain();\n\t //connections\n\t this.input.connect(this._dryWet.a);\n\t this.input.connect(this.effectSend);\n\t this.effectReturn.connect(this._dryWet.b);\n\t this._dryWet.connect(this.output);\n\t this._readOnly(['wet']);\n\t };\n\t Tone.extend(Tone.Effect, Tone.AudioNode);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Effect.defaults = { 'wet': 1 };\n\t /**\n\t\t * chains the effect in between the effectSend and effectReturn\n\t\t * @param {Tone} effect\n\t\t * @private\n\t\t * @returns {Tone.Effect} this\n\t\t */\n\t Tone.Effect.prototype.connectEffect = function (effect) {\n\t this.effectSend.chain(effect, this.effectReturn);\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Effect} this\n\t\t */\n\t Tone.Effect.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._dryWet.dispose();\n\t this._dryWet = null;\n\t this.effectSend.dispose();\n\t this.effectSend = null;\n\t this.effectReturn.dispose();\n\t this.effectReturn = null;\n\t this._writable(['wet']);\n\t this.wet = null;\n\t return this;\n\t };\n\t return Tone.Effect;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.AutoFilter is a Tone.Filter with a Tone.LFO connected to the filter cutoff frequency.\n\t\t * Setting the LFO rate and depth allows for control over the filter modulation rate \n\t\t * and depth.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Effect}\n\t\t * @param {Time|Object} [frequency] The rate of the LFO.\n\t\t * @param {Frequency=} baseFrequency The lower value of the LFOs oscillation\n\t \t * @param {Frequency=} octaves The number of octaves above the baseFrequency\n\t\t * @example\n\t\t * //create an autofilter and start it's LFO\n\t\t * var autoFilter = new Tone.AutoFilter(\"4n\").toMaster().start();\n\t\t * //route an oscillator through the filter and start it\n\t\t * var oscillator = new Tone.Oscillator().connect(autoFilter).start();\n\t\t */\n\t Tone.AutoFilter = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'baseFrequency',\n\t 'octaves'\n\t ], Tone.AutoFilter);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * the lfo which drives the filter cutoff\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfo = new Tone.LFO({\n\t 'frequency': options.frequency,\n\t 'amplitude': options.depth\n\t });\n\t /**\n\t\t\t * The range of the filter modulating between the min and max frequency. \n\t\t\t * 0 = no modulation. 1 = full modulation.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.depth = this._lfo.amplitude;\n\t /**\n\t\t\t * How fast the filter modulates between min and max. \n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._lfo.frequency;\n\t /**\n\t\t\t * The filter node\n\t\t\t * @type {Tone.Filter}\n\t\t\t */\n\t this.filter = new Tone.Filter(options.filter);\n\t /**\n\t\t\t * The octaves placeholder\n\t\t\t * @type {Positive}\n\t\t\t * @private\n\t\t\t */\n\t this._octaves = 0;\n\t //connections\n\t this.connectEffect(this.filter);\n\t this._lfo.connect(this.filter.frequency);\n\t this.type = options.type;\n\t this._readOnly([\n\t 'frequency',\n\t 'depth'\n\t ]);\n\t this.octaves = options.octaves;\n\t this.baseFrequency = options.baseFrequency;\n\t };\n\t //extend Effect\n\t Tone.extend(Tone.AutoFilter, Tone.Effect);\n\t /**\n\t\t * defaults\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.AutoFilter.defaults = {\n\t 'frequency': 1,\n\t 'type': 'sine',\n\t 'depth': 1,\n\t 'baseFrequency': 200,\n\t 'octaves': 2.6,\n\t 'filter': {\n\t 'type': 'lowpass',\n\t 'rolloff': -12,\n\t 'Q': 1\n\t }\n\t };\n\t /**\n\t\t * Start the effect.\n\t\t * @param {Time} [time=now] When the LFO will start. \n\t\t * @returns {Tone.AutoFilter} this\n\t\t */\n\t Tone.AutoFilter.prototype.start = function (time) {\n\t this._lfo.start(time);\n\t return this;\n\t };\n\t /**\n\t\t * Stop the effect.\n\t\t * @param {Time} [time=now] When the LFO will stop. \n\t\t * @returns {Tone.AutoFilter} this\n\t\t */\n\t Tone.AutoFilter.prototype.stop = function (time) {\n\t this._lfo.stop(time);\n\t return this;\n\t };\n\t /**\n\t\t * Sync the filter to the transport.\n\t\t * @param {Time} [delay=0] Delay time before starting the effect after the\n\t\t * Transport has started. \n\t\t * @returns {Tone.AutoFilter} this\n\t\t */\n\t Tone.AutoFilter.prototype.sync = function (delay) {\n\t this._lfo.sync(delay);\n\t return this;\n\t };\n\t /**\n\t\t * Unsync the filter from the transport.\n\t\t * @returns {Tone.AutoFilter} this\n\t\t */\n\t Tone.AutoFilter.prototype.unsync = function () {\n\t this._lfo.unsync();\n\t return this;\n\t };\n\t /**\n\t\t * Type of oscillator attached to the AutoFilter. \n\t\t * Possible values: \"sine\", \"square\", \"triangle\", \"sawtooth\".\n\t\t * @memberOf Tone.AutoFilter#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.AutoFilter.prototype, 'type', {\n\t get: function () {\n\t return this._lfo.type;\n\t },\n\t set: function (type) {\n\t this._lfo.type = type;\n\t }\n\t });\n\t /**\n\t\t * The minimum value of the filter's cutoff frequency.\n\t\t * @memberOf Tone.AutoFilter#\n\t\t * @type {Frequency}\n\t\t * @name min\n\t\t */\n\t Object.defineProperty(Tone.AutoFilter.prototype, 'baseFrequency', {\n\t get: function () {\n\t return this._lfo.min;\n\t },\n\t set: function (freq) {\n\t this._lfo.min = this.toFrequency(freq);\n\t //and set the max\n\t this.octaves = this._octaves;\n\t }\n\t });\n\t /**\n\t\t * The maximum value of the filter's cutoff frequency. \n\t\t * @memberOf Tone.AutoFilter#\n\t\t * @type {Positive}\n\t\t * @name octaves\n\t\t */\n\t Object.defineProperty(Tone.AutoFilter.prototype, 'octaves', {\n\t get: function () {\n\t return this._octaves;\n\t },\n\t set: function (oct) {\n\t this._octaves = oct;\n\t this._lfo.max = this.baseFrequency * Math.pow(2, oct);\n\t }\n\t });\n\t /**\n\t\t * Clean up. \n\t\t * @returns {Tone.AutoFilter} this\n\t\t */\n\t Tone.AutoFilter.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._lfo.dispose();\n\t this._lfo = null;\n\t this.filter.dispose();\n\t this.filter = null;\n\t this._writable([\n\t 'frequency',\n\t 'depth'\n\t ]);\n\t this.frequency = null;\n\t this.depth = null;\n\t return this;\n\t };\n\t return Tone.AutoFilter;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.AutoPanner is a Tone.Panner with an LFO connected to the pan amount. \n\t\t * More on using autopanners [here](https://www.ableton.com/en/blog/autopan-chopper-effect-and-more-liveschool/).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Effect}\n\t\t * @param {Frequency|Object} [frequency] Rate of left-right oscillation. \n\t\t * @example\n\t\t * //create an autopanner and start it's LFO\n\t\t * var autoPanner = new Tone.AutoPanner(\"4n\").toMaster().start();\n\t\t * //route an oscillator through the panner and start it\n\t\t * var oscillator = new Tone.Oscillator().connect(autoPanner).start();\n\t\t */\n\t Tone.AutoPanner = function () {\n\t var options = Tone.defaults(arguments, ['frequency'], Tone.AutoPanner);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * the lfo which drives the panning\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfo = new Tone.LFO({\n\t 'frequency': options.frequency,\n\t 'amplitude': options.depth,\n\t 'min': -1,\n\t 'max': 1\n\t });\n\t /**\n\t\t\t * The amount of panning between left and right. \n\t\t\t * 0 = always center. 1 = full range between left and right. \n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.depth = this._lfo.amplitude;\n\t /**\n\t\t\t * the panner node which does the panning\n\t\t\t * @type {Tone.Panner}\n\t\t\t * @private\n\t\t\t */\n\t this._panner = new Tone.Panner();\n\t /**\n\t\t\t * How fast the panner modulates between left and right. \n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._lfo.frequency;\n\t //connections\n\t this.connectEffect(this._panner);\n\t this._lfo.connect(this._panner.pan);\n\t this.type = options.type;\n\t this._readOnly([\n\t 'depth',\n\t 'frequency'\n\t ]);\n\t };\n\t //extend Effect\n\t Tone.extend(Tone.AutoPanner, Tone.Effect);\n\t /**\n\t\t * defaults\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.AutoPanner.defaults = {\n\t 'frequency': 1,\n\t 'type': 'sine',\n\t 'depth': 1\n\t };\n\t /**\n\t\t * Start the effect.\n\t\t * @param {Time} [time=now] When the LFO will start. \n\t\t * @returns {Tone.AutoPanner} this\n\t\t */\n\t Tone.AutoPanner.prototype.start = function (time) {\n\t this._lfo.start(time);\n\t return this;\n\t };\n\t /**\n\t\t * Stop the effect.\n\t\t * @param {Time} [time=now] When the LFO will stop. \n\t\t * @returns {Tone.AutoPanner} this\n\t\t */\n\t Tone.AutoPanner.prototype.stop = function (time) {\n\t this._lfo.stop(time);\n\t return this;\n\t };\n\t /**\n\t\t * Sync the panner to the transport.\n\t\t * @param {Time} [delay=0] Delay time before starting the effect after the\n\t\t * Transport has started. \n\t\t * @returns {Tone.AutoPanner} this\n\t\t */\n\t Tone.AutoPanner.prototype.sync = function (delay) {\n\t this._lfo.sync(delay);\n\t return this;\n\t };\n\t /**\n\t\t * Unsync the panner from the transport\n\t\t * @returns {Tone.AutoPanner} this\n\t\t */\n\t Tone.AutoPanner.prototype.unsync = function () {\n\t this._lfo.unsync();\n\t return this;\n\t };\n\t /**\n\t\t * Type of oscillator attached to the AutoFilter. \n\t\t * Possible values: \"sine\", \"square\", \"triangle\", \"sawtooth\".\n\t\t * @memberOf Tone.AutoFilter#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.AutoPanner.prototype, 'type', {\n\t get: function () {\n\t return this._lfo.type;\n\t },\n\t set: function (type) {\n\t this._lfo.type = type;\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.AutoPanner} this\n\t\t */\n\t Tone.AutoPanner.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._lfo.dispose();\n\t this._lfo = null;\n\t this._panner.dispose();\n\t this._panner = null;\n\t this._writable([\n\t 'depth',\n\t 'frequency'\n\t ]);\n\t this.frequency = null;\n\t this.depth = null;\n\t return this;\n\t };\n\t return Tone.AutoPanner;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.AutoWah connects a Tone.Follower to a bandpass filter (Tone.Filter).\n\t\t * The frequency of the filter is adjusted proportionally to the\n\t\t * incoming signal's amplitude. Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Effect}\n\t\t * @param {Frequency|Object} [baseFrequency] The frequency the filter is set\n\t\t * to at the low point of the wah\n\t\t * @param {Positive} [octaves] The number of octaves above the baseFrequency\n\t\t * the filter will sweep to when fully open\n\t\t * @param {Decibels} [sensitivity] The decibel threshold sensitivity for\n\t\t * the incoming signal. Normal range of -40 to 0.\n\t\t * @example\n\t\t * var autoWah = new Tone.AutoWah(50, 6, -30).toMaster();\n\t\t * //initialize the synth and connect to autowah\n\t\t * var synth = new Synth.connect(autoWah);\n\t\t * //Q value influences the effect of the wah - default is 2\n\t\t * autoWah.Q.value = 6;\n\t\t * //more audible on higher notes\n\t\t * synth.triggerAttackRelease(\"C4\", \"8n\")\n\t\t */\n\t Tone.AutoWah = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'baseFrequency',\n\t 'octaves',\n\t 'sensitivity'\n\t ], Tone.AutoWah);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * The envelope follower. Set the attack/release\n\t\t\t * timing to adjust how the envelope is followed.\n\t\t\t * @type {Tone.Follower}\n\t\t\t * @private\n\t\t\t */\n\t this.follower = new Tone.Follower(options.follower);\n\t /**\n\t\t\t * scales the follower value to the frequency domain\n\t\t\t * @type {Tone}\n\t\t\t * @private\n\t\t\t */\n\t this._sweepRange = new Tone.ScaleExp(0, 1, 0.5);\n\t /**\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._baseFrequency = options.baseFrequency;\n\t /**\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._octaves = options.octaves;\n\t /**\n\t\t\t * the input gain to adjust the sensitivity\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._inputBoost = new Tone.Gain();\n\t /**\n\t\t\t * @type {BiquadFilterNode}\n\t\t\t * @private\n\t\t\t */\n\t this._bandpass = new Tone.Filter({\n\t 'rolloff': -48,\n\t 'frequency': 0,\n\t 'Q': options.Q\n\t });\n\t /**\n\t\t\t * @type {Tone.Filter}\n\t\t\t * @private\n\t\t\t */\n\t this._peaking = new Tone.Filter(0, 'peaking');\n\t this._peaking.gain.value = options.gain;\n\t /**\n\t\t\t * The gain of the filter.\n\t\t\t * @type {Number}\n\t\t\t * @signal\n\t\t\t */\n\t this.gain = this._peaking.gain;\n\t /**\n\t\t\t * The quality of the filter.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this.Q = this._bandpass.Q;\n\t //the control signal path\n\t this.effectSend.chain(this._inputBoost, this.follower, this._sweepRange);\n\t this._sweepRange.connect(this._bandpass.frequency);\n\t this._sweepRange.connect(this._peaking.frequency);\n\t //the filtered path\n\t this.effectSend.chain(this._bandpass, this._peaking, this.effectReturn);\n\t //set the initial value\n\t this._setSweepRange();\n\t this.sensitivity = options.sensitivity;\n\t this._readOnly([\n\t 'gain',\n\t 'Q'\n\t ]);\n\t };\n\t Tone.extend(Tone.AutoWah, Tone.Effect);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.AutoWah.defaults = {\n\t 'baseFrequency': 100,\n\t 'octaves': 6,\n\t 'sensitivity': 0,\n\t 'Q': 2,\n\t 'gain': 2,\n\t 'follower': {\n\t 'attack': 0.3,\n\t 'release': 0.5\n\t }\n\t };\n\t /**\n\t\t * The number of octaves that the filter will sweep above the\n\t\t * baseFrequency.\n\t\t * @memberOf Tone.AutoWah#\n\t\t * @type {Number}\n\t\t * @name octaves\n\t\t */\n\t Object.defineProperty(Tone.AutoWah.prototype, 'octaves', {\n\t get: function () {\n\t return this._octaves;\n\t },\n\t set: function (octaves) {\n\t this._octaves = octaves;\n\t this._setSweepRange();\n\t }\n\t });\n\t /**\n\t\t * The base frequency from which the sweep will start from.\n\t\t * @memberOf Tone.AutoWah#\n\t\t * @type {Frequency}\n\t\t * @name baseFrequency\n\t\t */\n\t Object.defineProperty(Tone.AutoWah.prototype, 'baseFrequency', {\n\t get: function () {\n\t return this._baseFrequency;\n\t },\n\t set: function (baseFreq) {\n\t this._baseFrequency = baseFreq;\n\t this._setSweepRange();\n\t }\n\t });\n\t /**\n\t\t * The sensitivity to control how responsive to the input signal the filter is.\n\t\t * @memberOf Tone.AutoWah#\n\t\t * @type {Decibels}\n\t\t * @name sensitivity\n\t\t */\n\t Object.defineProperty(Tone.AutoWah.prototype, 'sensitivity', {\n\t get: function () {\n\t return Tone.gainToDb(1 / this._inputBoost.gain.value);\n\t },\n\t set: function (sensitivy) {\n\t this._inputBoost.gain.value = 1 / Tone.dbToGain(sensitivy);\n\t }\n\t });\n\t /**\n\t\t * sets the sweep range of the scaler\n\t\t * @private\n\t\t */\n\t Tone.AutoWah.prototype._setSweepRange = function () {\n\t this._sweepRange.min = this._baseFrequency;\n\t this._sweepRange.max = Math.min(this._baseFrequency * Math.pow(2, this._octaves), this.context.sampleRate / 2);\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.AutoWah} this\n\t\t */\n\t Tone.AutoWah.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this.follower.dispose();\n\t this.follower = null;\n\t this._sweepRange.dispose();\n\t this._sweepRange = null;\n\t this._bandpass.dispose();\n\t this._bandpass = null;\n\t this._peaking.dispose();\n\t this._peaking = null;\n\t this._inputBoost.dispose();\n\t this._inputBoost = null;\n\t this._writable([\n\t 'gain',\n\t 'Q'\n\t ]);\n\t this.gain = null;\n\t this.Q = null;\n\t return this;\n\t };\n\t return Tone.AutoWah;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t\t * values in the NormalRange.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.SignalBase}\n\t\t * @param {NormalRange} modulus The modulus to apply.\n\t\t * @example\n\t\t * var mod = new Tone.Modulo(0.2)\n\t\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t\t * //mod outputs 0.1\n\t\t */\n\t Tone.Modulo = function (modulus) {\n\t Tone.SignalBase.call(this);\n\t this.createInsOuts(1, 0);\n\t /**\n\t\t\t * A waveshaper gets the integer multiple of\n\t\t\t * the input signal and the modulus.\n\t\t\t * @private\n\t\t\t * @type {Tone.WaveShaper}\n\t\t\t */\n\t this._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\t /**\n\t\t\t * the integer multiple is multiplied by the modulus\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._multiply = new Tone.Multiply();\n\t /**\n\t\t\t * and subtracted from the input signal\n\t\t\t * @type {Tone.Subtract}\n\t\t\t * @private\n\t\t\t */\n\t this._subtract = this.output = new Tone.Subtract();\n\t /**\n\t\t\t * the modulus signal\n\t\t\t * @type {Tone.Signal}\n\t\t\t * @private\n\t\t\t */\n\t this._modSignal = new Tone.Signal(modulus);\n\t //connections\n\t this.input.fan(this._shaper, this._subtract);\n\t this._modSignal.connect(this._multiply, 0, 0);\n\t this._shaper.connect(this._multiply, 0, 1);\n\t this._multiply.connect(this._subtract, 0, 1);\n\t this._setWaveShaper(modulus);\n\t };\n\t Tone.extend(Tone.Modulo, Tone.SignalBase);\n\t /**\n\t\t * @param {number} mod the modulus to apply\n\t\t * @private\n\t\t */\n\t Tone.Modulo.prototype._setWaveShaper = function (mod) {\n\t this._shaper.setMap(function (val) {\n\t var multiple = Math.floor((val + 0.0001) / mod);\n\t return multiple;\n\t });\n\t };\n\t /**\n\t\t * The modulus value.\n\t\t * @memberOf Tone.Modulo#\n\t\t * @type {NormalRange}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.Modulo.prototype, 'value', {\n\t get: function () {\n\t return this._modSignal.value;\n\t },\n\t set: function (mod) {\n\t this._modSignal.value = mod;\n\t this._setWaveShaper(mod);\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Modulo} this\n\t\t */\n\t Tone.Modulo.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._shaper.dispose();\n\t this._shaper = null;\n\t this._multiply.dispose();\n\t this._multiply = null;\n\t this._subtract.dispose();\n\t this._subtract = null;\n\t this._modSignal.dispose();\n\t this._modSignal = null;\n\t return this;\n\t };\n\t return Tone.Modulo;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Bitcrusher downsamples the incoming signal to a different bitdepth.\n\t\t * Lowering the bitdepth of the signal creates distortion. Read more about Bitcrushing\n\t\t * on [Wikipedia](https://en.wikipedia.org/wiki/Bitcrusher).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Effect}\n\t\t * @param {Number} bits The number of bits to downsample the signal. Nominal range\n\t\t * of 1 to 8.\n\t\t * @example\n\t\t * //initialize crusher and route a synth through it\n\t\t * var crusher = new Tone.BitCrusher(4).toMaster();\n\t\t * var synth = new Tone.MonoSynth().connect(crusher);\n\t\t */\n\t Tone.BitCrusher = function () {\n\t var options = Tone.defaults(arguments, ['bits'], Tone.BitCrusher);\n\t Tone.Effect.call(this, options);\n\t var invStepSize = 1 / Math.pow(2, options.bits - 1);\n\t /**\n\t\t\t * Subtract the input signal and the modulus of the input signal\n\t\t\t * @type {Tone.Subtract}\n\t\t\t * @private\n\t\t\t */\n\t this._subtract = new Tone.Subtract();\n\t /**\n\t\t\t * The mod function\n\t\t\t * @type {Tone.Modulo}\n\t\t\t * @private\n\t\t\t */\n\t this._modulo = new Tone.Modulo(invStepSize);\n\t /**\n\t\t\t * keeps track of the bits\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._bits = options.bits;\n\t //connect it up\n\t this.effectSend.fan(this._subtract, this._modulo);\n\t this._modulo.connect(this._subtract, 0, 1);\n\t this._subtract.connect(this.effectReturn);\n\t };\n\t Tone.extend(Tone.BitCrusher, Tone.Effect);\n\t /**\n\t\t * the default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.BitCrusher.defaults = { 'bits': 4 };\n\t /**\n\t\t * The bit depth of the effect. Nominal range of 1-8.\n\t\t * @memberOf Tone.BitCrusher#\n\t\t * @type {number}\n\t\t * @name bits\n\t\t */\n\t Object.defineProperty(Tone.BitCrusher.prototype, 'bits', {\n\t get: function () {\n\t return this._bits;\n\t },\n\t set: function (bits) {\n\t this._bits = bits;\n\t var invStepSize = 1 / Math.pow(2, bits - 1);\n\t this._modulo.value = invStepSize;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.BitCrusher} this\n\t\t */\n\t Tone.BitCrusher.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._subtract.dispose();\n\t this._subtract = null;\n\t this._modulo.dispose();\n\t this._modulo = null;\n\t return this;\n\t };\n\t return Tone.BitCrusher;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.ChebyShev is a Chebyshev waveshaper, an effect which is good \n\t\t * for making different types of distortion sounds.\n\t\t * Note that odd orders sound very different from even ones, \n\t\t * and order = 1 is no change. \n\t\t * Read more at [music.columbia.edu](http://music.columbia.edu/cmc/musicandcomputers/chapter4/04_06.php).\n\t\t *\n\t\t * @extends {Tone.Effect}\n\t\t * @constructor\n\t\t * @param {Positive|Object} [order] The order of the chebyshev polynomial. Normal range between 1-100. \n\t\t * @example\n\t\t * //create a new cheby\n\t\t * var cheby = new Tone.Chebyshev(50);\n\t\t * //create a monosynth connected to our cheby\n\t\t * synth = new Tone.MonoSynth().connect(cheby);\n\t\t */\n\t Tone.Chebyshev = function () {\n\t var options = Tone.defaults(arguments, ['order'], Tone.Chebyshev);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * @type {WaveShaperNode}\n\t\t\t * @private\n\t\t\t */\n\t this._shaper = new Tone.WaveShaper(4096);\n\t /**\n\t\t\t * holds onto the order of the filter\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._order = options.order;\n\t this.connectEffect(this._shaper);\n\t this.order = options.order;\n\t this.oversample = options.oversample;\n\t };\n\t Tone.extend(Tone.Chebyshev, Tone.Effect);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Chebyshev.defaults = {\n\t 'order': 1,\n\t 'oversample': 'none'\n\t };\n\t /**\n\t\t * get the coefficient for that degree\n\t\t * @param {number} x the x value\n\t\t * @param {number} degree \n\t\t * @param {Object} memo memoize the computed value. \n\t\t * this speeds up computation greatly. \n\t\t * @return {number} the coefficient \n\t\t * @private\n\t\t */\n\t Tone.Chebyshev.prototype._getCoefficient = function (x, degree, memo) {\n\t if (memo.hasOwnProperty(degree)) {\n\t return memo[degree];\n\t } else if (degree === 0) {\n\t memo[degree] = 0;\n\t } else if (degree === 1) {\n\t memo[degree] = x;\n\t } else {\n\t memo[degree] = 2 * x * this._getCoefficient(x, degree - 1, memo) - this._getCoefficient(x, degree - 2, memo);\n\t }\n\t return memo[degree];\n\t };\n\t /**\n\t\t * The order of the Chebyshev polynomial which creates\n\t\t * the equation which is applied to the incoming \n\t\t * signal through a Tone.WaveShaper. The equations\n\t\t * are in the form:<br>\n\t\t * order 2: 2x^2 + 1<br>\n\t\t * order 3: 4x^3 + 3x <br>\n\t\t * @memberOf Tone.Chebyshev#\n\t\t * @type {Positive}\n\t\t * @name order\n\t\t */\n\t Object.defineProperty(Tone.Chebyshev.prototype, 'order', {\n\t get: function () {\n\t return this._order;\n\t },\n\t set: function (order) {\n\t this._order = order;\n\t var curve = new Array(4096);\n\t var len = curve.length;\n\t for (var i = 0; i < len; ++i) {\n\t var x = i * 2 / len - 1;\n\t if (x === 0) {\n\t //should output 0 when input is 0\n\t curve[i] = 0;\n\t } else {\n\t curve[i] = this._getCoefficient(x, order, {});\n\t }\n\t }\n\t this._shaper.curve = curve;\n\t }\n\t });\n\t /**\n\t\t * The oversampling of the effect. Can either be \"none\", \"2x\" or \"4x\".\n\t\t * @memberOf Tone.Chebyshev#\n\t\t * @type {string}\n\t\t * @name oversample\n\t\t */\n\t Object.defineProperty(Tone.Chebyshev.prototype, 'oversample', {\n\t get: function () {\n\t return this._shaper.oversample;\n\t },\n\t set: function (oversampling) {\n\t this._shaper.oversample = oversampling;\n\t }\n\t });\n\t /**\n\t\t * Clean up. \n\t\t * @returns {Tone.Chebyshev} this\n\t\t */\n\t Tone.Chebyshev.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._shaper.dispose();\n\t this._shaper = null;\n\t return this;\n\t };\n\t return Tone.Chebyshev;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Base class for Stereo effects. Provides effectSendL/R and effectReturnL/R.\n\t\t *\n\t\t *\t@constructor\n\t\t *\t@extends {Tone.Effect}\n\t\t */\n\t Tone.StereoEffect = function () {\n\t //get the defaults\n\t Tone.AudioNode.call(this);\n\t var options = Tone.defaults(arguments, ['wet'], Tone.Effect);\n\t this.createInsOuts(1, 1);\n\t /**\n\t\t\t * the drywet knob to control the amount of effect\n\t\t\t * @type {Tone.CrossFade}\n\t\t\t * @private\n\t\t\t */\n\t this._dryWet = new Tone.CrossFade(options.wet);\n\t /**\n\t\t\t * The wet control, i.e. how much of the effected\n\t\t\t * will pass through to the output.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.wet = this._dryWet.fade;\n\t /**\n\t\t\t * then split it\n\t\t\t * @type {Tone.Split}\n\t\t\t * @private\n\t\t\t */\n\t this._split = new Tone.Split();\n\t /**\n\t\t\t * the effects send LEFT\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.effectSendL = this._split.left;\n\t /**\n\t\t\t * the effects send RIGHT\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.effectSendR = this._split.right;\n\t /**\n\t\t\t * the stereo effect merger\n\t\t\t * @type {Tone.Merge}\n\t\t\t * @private\n\t\t\t */\n\t this._merge = new Tone.Merge();\n\t /**\n\t\t\t * the effect return LEFT\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.effectReturnL = this._merge.left;\n\t /**\n\t\t\t * the effect return RIGHT\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.effectReturnR = this._merge.right;\n\t //connections\n\t this.input.connect(this._split);\n\t //dry wet connections\n\t this.input.connect(this._dryWet, 0, 0);\n\t this._merge.connect(this._dryWet, 0, 1);\n\t this._dryWet.connect(this.output);\n\t this._readOnly(['wet']);\n\t };\n\t Tone.extend(Tone.StereoEffect, Tone.Effect);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.StereoEffect} this\n\t\t */\n\t Tone.StereoEffect.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._dryWet.dispose();\n\t this._dryWet = null;\n\t this._split.dispose();\n\t this._split = null;\n\t this._merge.dispose();\n\t this._merge = null;\n\t this.effectSendL = null;\n\t this.effectSendR = null;\n\t this.effectReturnL = null;\n\t this.effectReturnR = null;\n\t this._writable(['wet']);\n\t this.wet = null;\n\t return this;\n\t };\n\t return Tone.StereoEffect;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Chorus is a stereo chorus effect composed of\n\t\t * a left and right delay with a Tone.LFO applied to the delayTime of each channel.\n\t\t * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna/blob/master/tuna.js).\n\t\t * Read more on the chorus effect on [SoundOnSound](http://www.soundonsound.com/sos/jun04/articles/synthsecrets.htm).\n\t\t *\n\t\t *\t@constructor\n\t\t *\t@extends {Tone.StereoEffect}\n\t\t *\t@param {Frequency|Object} [frequency] The frequency of the LFO.\n\t\t *\t@param {Milliseconds} [delayTime] The delay of the chorus effect in ms.\n\t\t *\t@param {NormalRange} [depth] The depth of the chorus.\n\t\t *\t@example\n\t\t * var chorus = new Tone.Chorus(4, 2.5, 0.5);\n\t\t * var synth = new Tone.PolySynth(4, Tone.MonoSynth).connect(chorus);\n\t\t * synth.triggerAttackRelease([\"C3\",\"E3\",\"G3\"], \"8n\");\n\t\t */\n\t Tone.Chorus = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'delayTime',\n\t 'depth'\n\t ], Tone.Chorus);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * the depth of the chorus\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._depth = options.depth;\n\t /**\n\t\t\t * the delayTime\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._delayTime = options.delayTime / 1000;\n\t /**\n\t\t\t * the lfo which controls the delayTime\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoL = new Tone.LFO({\n\t 'frequency': options.frequency,\n\t 'min': 0,\n\t 'max': 1\n\t });\n\t /**\n\t\t\t * another LFO for the right side with a 180 degree phase diff\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoR = new Tone.LFO({\n\t 'frequency': options.frequency,\n\t 'min': 0,\n\t 'max': 1,\n\t 'phase': 180\n\t });\n\t /**\n\t\t\t * delay for left\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._delayNodeL = new Tone.Delay();\n\t /**\n\t\t\t * delay for right\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._delayNodeR = new Tone.Delay();\n\t /**\n\t\t\t * The frequency of the LFO which modulates the delayTime.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._lfoL.frequency;\n\t //connections\n\t this.effectSendL.chain(this._delayNodeL, this.effectReturnL);\n\t this.effectSendR.chain(this._delayNodeR, this.effectReturnR);\n\t //and pass through to make the detune apparent\n\t this.effectSendL.connect(this.effectReturnL);\n\t this.effectSendR.connect(this.effectReturnR);\n\t //lfo setup\n\t this._lfoL.connect(this._delayNodeL.delayTime);\n\t this._lfoR.connect(this._delayNodeR.delayTime);\n\t //start the lfo\n\t this._lfoL.start();\n\t this._lfoR.start();\n\t //have one LFO frequency control the other\n\t this._lfoL.frequency.connect(this._lfoR.frequency);\n\t //set the initial values\n\t this.depth = this._depth;\n\t this.frequency.value = options.frequency;\n\t this.type = options.type;\n\t this._readOnly(['frequency']);\n\t this.spread = options.spread;\n\t };\n\t Tone.extend(Tone.Chorus, Tone.StereoEffect);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Chorus.defaults = {\n\t 'frequency': 1.5,\n\t 'delayTime': 3.5,\n\t 'depth': 0.7,\n\t 'type': 'sine',\n\t 'spread': 180\n\t };\n\t /**\n\t\t * The depth of the effect. A depth of 1 makes the delayTime\n\t\t * modulate between 0 and 2*delayTime (centered around the delayTime).\n\t\t * @memberOf Tone.Chorus#\n\t\t * @type {NormalRange}\n\t\t * @name depth\n\t\t */\n\t Object.defineProperty(Tone.Chorus.prototype, 'depth', {\n\t get: function () {\n\t return this._depth;\n\t },\n\t set: function (depth) {\n\t this._depth = depth;\n\t var deviation = this._delayTime * depth;\n\t this._lfoL.min = Math.max(this._delayTime - deviation, 0);\n\t this._lfoL.max = this._delayTime + deviation;\n\t this._lfoR.min = Math.max(this._delayTime - deviation, 0);\n\t this._lfoR.max = this._delayTime + deviation;\n\t }\n\t });\n\t /**\n\t\t * The delayTime in milliseconds of the chorus. A larger delayTime\n\t\t * will give a more pronounced effect. Nominal range a delayTime\n\t\t * is between 2 and 20ms.\n\t\t * @memberOf Tone.Chorus#\n\t\t * @type {Milliseconds}\n\t\t * @name delayTime\n\t\t */\n\t Object.defineProperty(Tone.Chorus.prototype, 'delayTime', {\n\t get: function () {\n\t return this._delayTime * 1000;\n\t },\n\t set: function (delayTime) {\n\t this._delayTime = delayTime / 1000;\n\t this.depth = this._depth;\n\t }\n\t });\n\t /**\n\t\t * The oscillator type of the LFO.\n\t\t * @memberOf Tone.Chorus#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.Chorus.prototype, 'type', {\n\t get: function () {\n\t return this._lfoL.type;\n\t },\n\t set: function (type) {\n\t this._lfoL.type = type;\n\t this._lfoR.type = type;\n\t }\n\t });\n\t /**\n\t\t * Amount of stereo spread. When set to 0, both LFO's will be panned centrally.\n\t\t * When set to 180, LFO's will be panned hard left and right respectively.\n\t\t * @memberOf Tone.Chorus#\n\t\t * @type {Degrees}\n\t\t * @name spread\n\t\t */\n\t Object.defineProperty(Tone.Chorus.prototype, 'spread', {\n\t get: function () {\n\t return this._lfoR.phase - this._lfoL.phase;\n\t },\n\t set: function (spread) {\n\t this._lfoL.phase = 90 - spread / 2;\n\t this._lfoR.phase = spread / 2 + 90;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Chorus} this\n\t\t */\n\t Tone.Chorus.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t this._lfoL.dispose();\n\t this._lfoL = null;\n\t this._lfoR.dispose();\n\t this._lfoR = null;\n\t this._delayNodeL.dispose();\n\t this._delayNodeL = null;\n\t this._delayNodeR.dispose();\n\t this._delayNodeR = null;\n\t this._writable('frequency');\n\t this.frequency = null;\n\t return this;\n\t };\n\t return Tone.Chorus;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Convolver is a wrapper around the Native Web Audio\n\t\t * [ConvolverNode](http://webaudio.github.io/web-audio-api/#the-convolvernode-interface).\n\t\t * Convolution is useful for reverb and filter emulation. Read more about convolution reverb on\n\t\t * [Wikipedia](https://en.wikipedia.org/wiki/Convolution_reverb).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Effect}\n\t\t * @param {string|Tone.Buffer|Object} [url] The URL of the impulse response or the Tone.Buffer\n\t\t * contianing the impulse response.\n\t\t * @param {Function=} onload The callback to invoke when the url is loaded.\n\t\t * @example\n\t\t * //initializing the convolver with an impulse response\n\t\t * var convolver = new Tone.Convolver(\"./path/to/ir.wav\").toMaster();\n\t\t */\n\t Tone.Convolver = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'url',\n\t 'onload'\n\t ], Tone.Convolver);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * convolver node\n\t\t\t * @type {ConvolverNode}\n\t\t\t * @private\n\t\t\t */\n\t this._convolver = this.context.createConvolver();\n\t /**\n\t\t\t * the convolution buffer\n\t\t\t * @type {Tone.Buffer}\n\t\t\t * @private\n\t\t\t */\n\t this._buffer = new Tone.Buffer(options.url, function (buffer) {\n\t this._convolver.buffer = buffer.get();\n\t options.onload();\n\t }.bind(this));\n\t this.connectEffect(this._convolver);\n\t };\n\t Tone.extend(Tone.Convolver, Tone.Effect);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Convolver.defaults = { 'onload': Tone.noOp };\n\t /**\n\t\t * The convolver's buffer\n\t\t * @memberOf Tone.Convolver#\n\t\t * @type {AudioBuffer}\n\t\t * @name buffer\n\t\t */\n\t Object.defineProperty(Tone.Convolver.prototype, 'buffer', {\n\t get: function () {\n\t return this._buffer.get();\n\t },\n\t set: function (buffer) {\n\t this._buffer.set(buffer);\n\t this._convolver.buffer = this._buffer.get();\n\t }\n\t });\n\t /**\n\t\t * Load an impulse response url as an audio buffer.\n\t\t * Decodes the audio asynchronously and invokes\n\t\t * the callback once the audio buffer loads.\n\t\t * @param {string} url The url of the buffer to load.\n\t\t * filetype support depends on the\n\t\t * browser.\n\t\t * @param {function=} callback\n\t\t * @returns {Promise}\n\t\t */\n\t Tone.Convolver.prototype.load = function (url, callback) {\n\t return this._buffer.load(url, function (buff) {\n\t this.buffer = buff;\n\t if (callback) {\n\t callback();\n\t }\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Convolver} this\n\t\t */\n\t Tone.Convolver.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._convolver.disconnect();\n\t this._convolver = null;\n\t this._buffer.dispose();\n\t this._buffer = null;\n\t return this;\n\t };\n\t return Tone.Convolver;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Distortion is a simple distortion effect using Tone.WaveShaper.\n\t\t * Algorithm from [a stackoverflow answer](http://stackoverflow.com/a/22313408).\n\t\t *\n\t\t * @extends {Tone.Effect}\n\t\t * @constructor\n\t\t * @param {Number|Object} [distortion] The amount of distortion (nominal range of 0-1)\n\t\t * @example\n\t\t * var dist = new Tone.Distortion(0.8).toMaster();\n\t\t * var fm = new Tone.SimpleFM().connect(dist);\n\t\t * //this sounds good on bass notes\n\t\t * fm.triggerAttackRelease(\"A1\", \"8n\");\n\t\t */\n\t Tone.Distortion = function () {\n\t var options = Tone.defaults(arguments, ['distortion'], Tone.Distortion);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * @type {Tone.WaveShaper}\n\t\t\t * @private\n\t\t\t */\n\t this._shaper = new Tone.WaveShaper(4096);\n\t /**\n\t\t\t * holds the distortion amount\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._distortion = options.distortion;\n\t this.connectEffect(this._shaper);\n\t this.distortion = options.distortion;\n\t this.oversample = options.oversample;\n\t };\n\t Tone.extend(Tone.Distortion, Tone.Effect);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Distortion.defaults = {\n\t 'distortion': 0.4,\n\t 'oversample': 'none'\n\t };\n\t /**\n\t\t * The amount of distortion.\n\t\t * @memberOf Tone.Distortion#\n\t\t * @type {NormalRange}\n\t\t * @name distortion\n\t\t */\n\t Object.defineProperty(Tone.Distortion.prototype, 'distortion', {\n\t get: function () {\n\t return this._distortion;\n\t },\n\t set: function (amount) {\n\t this._distortion = amount;\n\t var k = amount * 100;\n\t var deg = Math.PI / 180;\n\t this._shaper.setMap(function (x) {\n\t if (Math.abs(x) < 0.001) {\n\t //should output 0 when input is 0\n\t return 0;\n\t } else {\n\t return (3 + k) * x * 20 * deg / (Math.PI + k * Math.abs(x));\n\t }\n\t });\n\t }\n\t });\n\t /**\n\t\t * The oversampling of the effect. Can either be \"none\", \"2x\" or \"4x\".\n\t\t * @memberOf Tone.Distortion#\n\t\t * @type {string}\n\t\t * @name oversample\n\t\t */\n\t Object.defineProperty(Tone.Distortion.prototype, 'oversample', {\n\t get: function () {\n\t return this._shaper.oversample;\n\t },\n\t set: function (oversampling) {\n\t this._shaper.oversample = oversampling;\n\t }\n\t });\n\t /**\n\t\t * Clean up. \n\t\t * @returns {Tone.Distortion} this\n\t\t */\n\t Tone.Distortion.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._shaper.dispose();\n\t this._shaper = null;\n\t return this;\n\t };\n\t return Tone.Distortion;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * \t@class Tone.FeedbackEffect provides a loop between an \n\t\t * \t audio source and its own output. This is a base-class\n\t\t * \t for feedback effects. \n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Effect}\n\t\t * @param {NormalRange|Object} [feedback] The initial feedback value.\n\t\t */\n\t Tone.FeedbackEffect = function () {\n\t var options = Tone.defaults(arguments, ['feedback'], Tone.FeedbackEffect);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * the gain which controls the feedback\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackGain = new Tone.Gain(options.feedback, Tone.Type.NormalRange);\n\t /**\n\t\t\t * The amount of signal which is fed back into the effect input. \n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.feedback = this._feedbackGain.gain;\n\t //the feedback loop\n\t this.effectReturn.chain(this._feedbackGain, this.effectSend);\n\t this._readOnly(['feedback']);\n\t };\n\t Tone.extend(Tone.FeedbackEffect, Tone.Effect);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.FeedbackEffect.defaults = { 'feedback': 0.125 };\n\t /**\n\t\t * Clean up. \n\t\t * @returns {Tone.FeedbackEffect} this\n\t\t */\n\t Tone.FeedbackEffect.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._writable(['feedback']);\n\t this._feedbackGain.dispose();\n\t this._feedbackGain = null;\n\t this.feedback = null;\n\t return this;\n\t };\n\t return Tone.FeedbackEffect;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.FeedbackDelay is a DelayNode in which part of output\n\t\t * signal is fed back into the delay.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.FeedbackEffect}\n\t\t * @param {Time|Object} [delayTime] The delay applied to the incoming signal.\n\t\t * @param {NormalRange=} feedback The amount of the effected signal which\n\t\t * is fed back through the delay.\n\t\t * @example\n\t\t * var feedbackDelay = new Tone.FeedbackDelay(\"8n\", 0.5).toMaster();\n\t\t * var tom = new Tone.DrumSynth({\n\t\t * \t\"octaves\" : 4,\n\t\t * \t\"pitchDecay\" : 0.1\n\t\t * }).connect(feedbackDelay);\n\t\t * tom.triggerAttackRelease(\"A2\",\"32n\");\n\t\t */\n\t Tone.FeedbackDelay = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'delayTime',\n\t 'feedback'\n\t ], Tone.FeedbackDelay);\n\t Tone.FeedbackEffect.call(this, options);\n\t /**\n\t\t\t * the delay node\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._delayNode = new Tone.Delay(options.delayTime, options.maxDelay);\n\t /**\n\t\t\t * The delayTime of the DelayNode.\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.delayTime = this._delayNode.delayTime;\n\t // connect it up\n\t this.connectEffect(this._delayNode);\n\t this._readOnly(['delayTime']);\n\t };\n\t Tone.extend(Tone.FeedbackDelay, Tone.FeedbackEffect);\n\t /**\n\t\t * The default values.\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.FeedbackDelay.defaults = {\n\t 'delayTime': 0.25,\n\t 'maxDelay': 1\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.FeedbackDelay} this\n\t\t */\n\t Tone.FeedbackDelay.prototype.dispose = function () {\n\t Tone.FeedbackEffect.prototype.dispose.call(this);\n\t this._delayNode.dispose();\n\t this._delayNode = null;\n\t this._writable(['delayTime']);\n\t this.delayTime = null;\n\t return this;\n\t };\n\t return Tone.FeedbackDelay;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * an array of comb filter delay values from Freeverb implementation\n\t\t * @static\n\t\t * @private\n\t\t * @type {Array}\n\t\t */\n\t var combFilterTunings = [\n\t 1557 / 44100,\n\t 1617 / 44100,\n\t 1491 / 44100,\n\t 1422 / 44100,\n\t 1277 / 44100,\n\t 1356 / 44100,\n\t 1188 / 44100,\n\t 1116 / 44100\n\t ];\n\t /**\n\t\t * an array of allpass filter frequency values from Freeverb implementation\n\t\t * @private\n\t\t * @static\n\t\t * @type {Array}\n\t\t */\n\t var allpassFilterFrequencies = [\n\t 225,\n\t 556,\n\t 441,\n\t 341\n\t ];\n\t /**\n\t\t * @class Tone.Freeverb is a reverb based on [Freeverb](https://ccrma.stanford.edu/~jos/pasp/Freeverb.html).\n\t\t * Read more on reverb on [Sound On Sound](https://web.archive.org/web/20160404083902/http://www.soundonsound.com:80/sos/feb01/articles/synthsecrets.asp).\n\t\t *\n\t\t * @extends {Tone.Effect}\n\t\t * @constructor\n\t\t * @param {NormalRange|Object} [roomSize] Correlated to the decay time.\n\t\t * @param {Frequency} [dampening] The cutoff frequency of a lowpass filter as part\n\t\t * of the reverb.\n\t\t * @example\n\t\t * var freeverb = new Tone.Freeverb().toMaster();\n\t\t * freeverb.dampening.value = 1000;\n\t\t * //routing synth through the reverb\n\t\t * var synth = new Tone.AMSynth().connect(freeverb);\n\t\t */\n\t Tone.Freeverb = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'roomSize',\n\t 'dampening'\n\t ], Tone.Freeverb);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * The roomSize value between. A larger roomSize\n\t\t\t * will result in a longer decay.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.roomSize = new Tone.Signal(options.roomSize, Tone.Type.NormalRange);\n\t /**\n\t\t\t * The amount of dampening of the reverberant signal.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.dampening = new Tone.Signal(options.dampening, Tone.Type.Frequency);\n\t /**\n\t\t\t * the comb filters\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._combFilters = [];\n\t /**\n\t\t\t * the allpass filters on the left\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._allpassFiltersL = [];\n\t /**\n\t\t\t * the allpass filters on the right\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._allpassFiltersR = [];\n\t //make the allpass filters on the right\n\t for (var l = 0; l < allpassFilterFrequencies.length; l++) {\n\t var allpassL = this.context.createBiquadFilter();\n\t allpassL.type = 'allpass';\n\t allpassL.frequency.value = allpassFilterFrequencies[l];\n\t this._allpassFiltersL.push(allpassL);\n\t }\n\t //make the allpass filters on the left\n\t for (var r = 0; r < allpassFilterFrequencies.length; r++) {\n\t var allpassR = this.context.createBiquadFilter();\n\t allpassR.type = 'allpass';\n\t allpassR.frequency.value = allpassFilterFrequencies[r];\n\t this._allpassFiltersR.push(allpassR);\n\t }\n\t //make the comb filters\n\t for (var c = 0; c < combFilterTunings.length; c++) {\n\t var lfpf = new Tone.LowpassCombFilter(combFilterTunings[c]);\n\t if (c < combFilterTunings.length / 2) {\n\t this.effectSendL.chain(lfpf, this._allpassFiltersL[0]);\n\t } else {\n\t this.effectSendR.chain(lfpf, this._allpassFiltersR[0]);\n\t }\n\t this.roomSize.connect(lfpf.resonance);\n\t this.dampening.connect(lfpf.dampening);\n\t this._combFilters.push(lfpf);\n\t }\n\t //chain the allpass filters togetehr\n\t Tone.connectSeries.apply(Tone, this._allpassFiltersL);\n\t Tone.connectSeries.apply(Tone, this._allpassFiltersR);\n\t this._allpassFiltersL[this._allpassFiltersL.length - 1].connect(this.effectReturnL);\n\t this._allpassFiltersR[this._allpassFiltersR.length - 1].connect(this.effectReturnR);\n\t this._readOnly([\n\t 'roomSize',\n\t 'dampening'\n\t ]);\n\t };\n\t Tone.extend(Tone.Freeverb, Tone.StereoEffect);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Freeverb.defaults = {\n\t 'roomSize': 0.7,\n\t 'dampening': 3000\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Freeverb} this\n\t\t */\n\t Tone.Freeverb.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t for (var al = 0; al < this._allpassFiltersL.length; al++) {\n\t this._allpassFiltersL[al].disconnect();\n\t this._allpassFiltersL[al] = null;\n\t }\n\t this._allpassFiltersL = null;\n\t for (var ar = 0; ar < this._allpassFiltersR.length; ar++) {\n\t this._allpassFiltersR[ar].disconnect();\n\t this._allpassFiltersR[ar] = null;\n\t }\n\t this._allpassFiltersR = null;\n\t for (var cf = 0; cf < this._combFilters.length; cf++) {\n\t this._combFilters[cf].dispose();\n\t this._combFilters[cf] = null;\n\t }\n\t this._combFilters = null;\n\t this._writable([\n\t 'roomSize',\n\t 'dampening'\n\t ]);\n\t this.roomSize.dispose();\n\t this.roomSize = null;\n\t this.dampening.dispose();\n\t this.dampening = null;\n\t return this;\n\t };\n\t return Tone.Freeverb;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * an array of the comb filter delay time values\n\t\t * @private\n\t\t * @static\n\t\t * @type {Array}\n\t\t */\n\t var combFilterDelayTimes = [\n\t 1687 / 25000,\n\t 1601 / 25000,\n\t 2053 / 25000,\n\t 2251 / 25000\n\t ];\n\t /**\n\t\t * the resonances of each of the comb filters\n\t\t * @private\n\t\t * @static\n\t\t * @type {Array}\n\t\t */\n\t var combFilterResonances = [\n\t 0.773,\n\t 0.802,\n\t 0.753,\n\t 0.733\n\t ];\n\t /**\n\t\t * the allpass filter frequencies\n\t\t * @private\n\t\t * @static\n\t\t * @type {Array}\n\t\t */\n\t var allpassFilterFreqs = [\n\t 347,\n\t 113,\n\t 37\n\t ];\n\t /**\n\t\t * @class Tone.JCReverb is a simple [Schroeder Reverberator](https://ccrma.stanford.edu/~jos/pasp/Schroeder_Reverberators.html)\n\t\t * tuned by John Chowning in 1970.\n\t\t * It is made up of three allpass filters and four Tone.FeedbackCombFilter.\n\t\t *\n\t\t *\n\t\t * @extends {Tone.Effect}\n\t\t * @constructor\n\t\t * @param {NormalRange|Object} [roomSize] Coorelates to the decay time.\n\t\t * @example\n\t\t * var reverb = new Tone.JCReverb(0.4).connect(Tone.Master);\n\t\t * var delay = new Tone.FeedbackDelay(0.5);\n\t\t * //connecting the synth to reverb through delay\n\t\t * var synth = new Tone.DuoSynth().chain(delay, reverb);\n\t\t * synth.triggerAttackRelease(\"A4\",\"8n\");\n\t\t */\n\t Tone.JCReverb = function () {\n\t var options = Tone.defaults(arguments, ['roomSize'], Tone.JCReverb);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * room size control values between [0,1]\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.roomSize = new Tone.Signal(options.roomSize, Tone.Type.NormalRange);\n\t /**\n\t\t\t * scale the room size\n\t\t\t * @type {Tone.Scale}\n\t\t\t * @private\n\t\t\t */\n\t this._scaleRoomSize = new Tone.Scale(-0.733, 0.197);\n\t /**\n\t\t\t * a series of allpass filters\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._allpassFilters = [];\n\t /**\n\t\t\t * parallel feedback comb filters\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackCombFilters = [];\n\t //make the allpass filters\n\t for (var af = 0; af < allpassFilterFreqs.length; af++) {\n\t var allpass = this.context.createBiquadFilter();\n\t allpass.type = 'allpass';\n\t allpass.frequency.value = allpassFilterFreqs[af];\n\t this._allpassFilters.push(allpass);\n\t }\n\t //and the comb filters\n\t for (var cf = 0; cf < combFilterDelayTimes.length; cf++) {\n\t var fbcf = new Tone.FeedbackCombFilter(combFilterDelayTimes[cf], 0.1);\n\t this._scaleRoomSize.connect(fbcf.resonance);\n\t fbcf.resonance.value = combFilterResonances[cf];\n\t this._allpassFilters[this._allpassFilters.length - 1].connect(fbcf);\n\t if (cf < combFilterDelayTimes.length / 2) {\n\t fbcf.connect(this.effectReturnL);\n\t } else {\n\t fbcf.connect(this.effectReturnR);\n\t }\n\t this._feedbackCombFilters.push(fbcf);\n\t }\n\t //chain the allpass filters together\n\t this.roomSize.connect(this._scaleRoomSize);\n\t Tone.connectSeries.apply(Tone, this._allpassFilters);\n\t this.effectSendL.connect(this._allpassFilters[0]);\n\t this.effectSendR.connect(this._allpassFilters[0]);\n\t this._readOnly(['roomSize']);\n\t };\n\t Tone.extend(Tone.JCReverb, Tone.StereoEffect);\n\t /**\n\t\t * the default values\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.JCReverb.defaults = { 'roomSize': 0.5 };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.JCReverb} this\n\t\t */\n\t Tone.JCReverb.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t for (var apf = 0; apf < this._allpassFilters.length; apf++) {\n\t this._allpassFilters[apf].disconnect();\n\t this._allpassFilters[apf] = null;\n\t }\n\t this._allpassFilters = null;\n\t for (var fbcf = 0; fbcf < this._feedbackCombFilters.length; fbcf++) {\n\t this._feedbackCombFilters[fbcf].dispose();\n\t this._feedbackCombFilters[fbcf] = null;\n\t }\n\t this._feedbackCombFilters = null;\n\t this._writable(['roomSize']);\n\t this.roomSize.dispose();\n\t this.roomSize = null;\n\t this._scaleRoomSize.dispose();\n\t this._scaleRoomSize = null;\n\t return this;\n\t };\n\t return Tone.JCReverb;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Mid/Side processing separates the the 'mid' signal\n\t\t * (which comes out of both the left and the right channel)\n\t\t * and the 'side' (which only comes out of the the side channels)\n\t\t * and effects them separately before being recombined.\n\t\t * Applies a Mid/Side seperation and recombination.\n\t\t * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587).\n\t\t * <br><br>\n\t\t * This is a base-class for Mid/Side Effects.\n\t\t *\n\t\t * @extends {Tone.Effect}\n\t\t * @constructor\n\t\t */\n\t Tone.MidSideEffect = function () {\n\t Tone.Effect.apply(this, arguments);\n\t /**\n\t\t\t * The mid/side split\n\t\t\t * @type {Tone.MidSideSplit}\n\t\t\t * @private\n\t\t\t */\n\t this._midSideSplit = new Tone.MidSideSplit();\n\t /**\n\t\t\t * The mid/side merge\n\t\t\t * @type {Tone.MidSideMerge}\n\t\t\t * @private\n\t\t\t */\n\t this._midSideMerge = new Tone.MidSideMerge();\n\t /**\n\t\t\t * The mid send. Connect to mid processing\n\t\t\t * @type {Tone}\n\t\t\t * @private\n\t\t\t */\n\t this.midSend = this._midSideSplit.mid;\n\t /**\n\t\t\t * The side send. Connect to side processing\n\t\t\t * @type {Tone}\n\t\t\t * @private\n\t\t\t */\n\t this.sideSend = this._midSideSplit.side;\n\t /**\n\t\t\t * The mid return connection\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.midReturn = this._midSideMerge.mid;\n\t /**\n\t\t\t * The side return connection\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.sideReturn = this._midSideMerge.side;\n\t //the connections\n\t this.effectSend.connect(this._midSideSplit);\n\t this._midSideMerge.connect(this.effectReturn);\n\t };\n\t Tone.extend(Tone.MidSideEffect, Tone.Effect);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.MidSideEffect} this\n\t\t */\n\t Tone.MidSideEffect.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._midSideSplit.dispose();\n\t this._midSideSplit = null;\n\t this._midSideMerge.dispose();\n\t this._midSideMerge = null;\n\t this.midSend = null;\n\t this.sideSend = null;\n\t this.midReturn = null;\n\t this.sideReturn = null;\n\t return this;\n\t };\n\t return Tone.MidSideEffect;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Phaser is a phaser effect. Phasers work by changing the phase\n\t\t * of different frequency components of an incoming signal. Read more on\n\t\t * [Wikipedia](https://en.wikipedia.org/wiki/Phaser_(effect)).\n\t\t * Inspiration for this phaser comes from [Tuna.js](https://github.com/Dinahmoe/tuna/).\n\t\t *\n\t\t *\t@extends {Tone.StereoEffect}\n\t\t *\t@constructor\n\t\t *\t@param {Frequency|Object} [frequency] The speed of the phasing.\n\t\t *\t@param {number} [octaves] The octaves of the effect.\n\t\t *\t@param {Frequency} [baseFrequency] The base frequency of the filters.\n\t\t *\t@example\n\t\t * var phaser = new Tone.Phaser({\n\t\t * \t\"frequency\" : 15,\n\t\t * \t\"octaves\" : 5,\n\t\t * \t\"baseFrequency\" : 1000\n\t\t * }).toMaster();\n\t\t * var synth = new Tone.FMSynth().connect(phaser);\n\t\t * synth.triggerAttackRelease(\"E3\", \"2n\");\n\t\t */\n\t Tone.Phaser = function () {\n\t //set the defaults\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'octaves',\n\t 'baseFrequency'\n\t ], Tone.Phaser);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * the lfo which controls the frequency on the left side\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoL = new Tone.LFO(options.frequency, 0, 1);\n\t /**\n\t\t\t * the lfo which controls the frequency on the right side\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoR = new Tone.LFO(options.frequency, 0, 1);\n\t this._lfoR.phase = 180;\n\t /**\n\t\t\t * the base modulation frequency\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._baseFrequency = options.baseFrequency;\n\t /**\n\t\t\t * the octaves of the phasing\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._octaves = options.octaves;\n\t /**\n\t\t\t * The quality factor of the filters\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this.Q = new Tone.Signal(options.Q, Tone.Type.Positive);\n\t /**\n\t\t\t * the array of filters for the left side\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._filtersL = this._makeFilters(options.stages, this._lfoL, this.Q);\n\t /**\n\t\t\t * the array of filters for the left side\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._filtersR = this._makeFilters(options.stages, this._lfoR, this.Q);\n\t /**\n\t\t\t * the frequency of the effect\n\t\t\t * @type {Tone.Signal}\n\t\t\t */\n\t this.frequency = this._lfoL.frequency;\n\t this.frequency.value = options.frequency;\n\t //connect them up\n\t this.effectSendL.connect(this._filtersL[0]);\n\t this.effectSendR.connect(this._filtersR[0]);\n\t this._filtersL[options.stages - 1].connect(this.effectReturnL);\n\t this._filtersR[options.stages - 1].connect(this.effectReturnR);\n\t //control the frequency with one LFO\n\t this._lfoL.frequency.connect(this._lfoR.frequency);\n\t //set the options\n\t this.baseFrequency = options.baseFrequency;\n\t this.octaves = options.octaves;\n\t //start the lfo\n\t this._lfoL.start();\n\t this._lfoR.start();\n\t this._readOnly([\n\t 'frequency',\n\t 'Q'\n\t ]);\n\t };\n\t Tone.extend(Tone.Phaser, Tone.StereoEffect);\n\t /**\n\t\t * defaults\n\t\t * @static\n\t\t * @type {object}\n\t\t */\n\t Tone.Phaser.defaults = {\n\t 'frequency': 0.5,\n\t 'octaves': 3,\n\t 'stages': 10,\n\t 'Q': 10,\n\t 'baseFrequency': 350\n\t };\n\t /**\n\t\t * @param {number} stages\n\t\t * @returns {Array} the number of filters all connected together\n\t\t * @private\n\t\t */\n\t Tone.Phaser.prototype._makeFilters = function (stages, connectToFreq, Q) {\n\t var filters = new Array(stages);\n\t //make all the filters\n\t for (var i = 0; i < stages; i++) {\n\t var filter = this.context.createBiquadFilter();\n\t filter.type = 'allpass';\n\t Q.connect(filter.Q);\n\t connectToFreq.connect(filter.frequency);\n\t filters[i] = filter;\n\t }\n\t Tone.connectSeries.apply(Tone, filters);\n\t return filters;\n\t };\n\t /**\n\t\t * The number of octaves the phase goes above\n\t\t * the baseFrequency\n\t\t * @memberOf Tone.Phaser#\n\t\t * @type {Positive}\n\t\t * @name octaves\n\t\t */\n\t Object.defineProperty(Tone.Phaser.prototype, 'octaves', {\n\t get: function () {\n\t return this._octaves;\n\t },\n\t set: function (octaves) {\n\t this._octaves = octaves;\n\t var max = this._baseFrequency * Math.pow(2, octaves);\n\t this._lfoL.max = max;\n\t this._lfoR.max = max;\n\t }\n\t });\n\t /**\n\t\t * The the base frequency of the filters.\n\t\t * @memberOf Tone.Phaser#\n\t\t * @type {number}\n\t\t * @name baseFrequency\n\t\t */\n\t Object.defineProperty(Tone.Phaser.prototype, 'baseFrequency', {\n\t get: function () {\n\t return this._baseFrequency;\n\t },\n\t set: function (freq) {\n\t this._baseFrequency = freq;\n\t this._lfoL.min = freq;\n\t this._lfoR.min = freq;\n\t this.octaves = this._octaves;\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Phaser} this\n\t\t */\n\t Tone.Phaser.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'Q'\n\t ]);\n\t this.Q.dispose();\n\t this.Q = null;\n\t this._lfoL.dispose();\n\t this._lfoL = null;\n\t this._lfoR.dispose();\n\t this._lfoR = null;\n\t for (var i = 0; i < this._filtersL.length; i++) {\n\t this._filtersL[i].disconnect();\n\t this._filtersL[i] = null;\n\t }\n\t this._filtersL = null;\n\t for (var j = 0; j < this._filtersR.length; j++) {\n\t this._filtersR[j].disconnect();\n\t this._filtersR[j] = null;\n\t }\n\t this._filtersR = null;\n\t this.frequency = null;\n\t return this;\n\t };\n\t return Tone.Phaser;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Just like a stereo feedback effect, but the feedback is routed from left to right\n\t\t * and right to left instead of on the same channel.\n\t\t *\n\t\t *\t@constructor\n\t\t *\t@extends {Tone.StereoEffect}\n\t\t */\n\t Tone.StereoXFeedbackEffect = function () {\n\t var options = Tone.defaults(arguments, ['feedback'], Tone.FeedbackEffect);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * The amount of feedback from the output\n\t\t\t * back into the input of the effect (routed\n\t\t\t * across left and right channels).\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.feedback = new Tone.Signal(options.feedback, Tone.Type.NormalRange);\n\t /**\n\t\t\t * the left side feeback\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackLR = new Tone.Gain();\n\t /**\n\t\t\t * the right side feeback\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackRL = new Tone.Gain();\n\t //connect it up\n\t this.effectReturnL.chain(this._feedbackLR, this.effectSendR);\n\t this.effectReturnR.chain(this._feedbackRL, this.effectSendL);\n\t this.feedback.fan(this._feedbackLR.gain, this._feedbackRL.gain);\n\t this._readOnly(['feedback']);\n\t };\n\t Tone.extend(Tone.StereoXFeedbackEffect, Tone.StereoEffect);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.StereoXFeedbackEffect} this\n\t\t */\n\t Tone.StereoXFeedbackEffect.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t this._writable(['feedback']);\n\t this.feedback.dispose();\n\t this.feedback = null;\n\t this._feedbackLR.dispose();\n\t this._feedbackLR = null;\n\t this._feedbackRL.dispose();\n\t this._feedbackRL = null;\n\t return this;\n\t };\n\t return Tone.StereoXFeedbackEffect;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.PingPongDelay is a feedback delay effect where the echo is heard\n\t\t * first in one channel and next in the opposite channel. In a stereo\n\t\t * system these are the right and left channels.\n\t\t * PingPongDelay in more simplified terms is two Tone.FeedbackDelays\n\t\t * with independent delay values. Each delay is routed to one channel\n\t\t * (left or right), and the channel triggered second will always\n\t\t * trigger at the same interval after the first.\n\t\t *\n\t\t * \t@constructor\n\t\t * \t@extends {Tone.StereoXFeedbackEffect}\n\t\t * @param {Time|Object} [delayTime] The delayTime between consecutive echos.\n\t\t * @param {NormalRange=} feedback The amount of the effected signal which\n\t\t * is fed back through the delay.\n\t\t * @example\n\t\t * var pingPong = new Tone.PingPongDelay(\"4n\", 0.2).toMaster();\n\t\t * var drum = new Tone.DrumSynth().connect(pingPong);\n\t\t * drum.triggerAttackRelease(\"C4\", \"32n\");\n\t\t */\n\t Tone.PingPongDelay = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'delayTime',\n\t 'feedback'\n\t ], Tone.PingPongDelay);\n\t Tone.StereoXFeedbackEffect.call(this, options);\n\t /**\n\t\t\t * the delay node on the left side\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._leftDelay = new Tone.Delay(0, options.maxDelayTime);\n\t /**\n\t\t\t * the delay node on the right side\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._rightDelay = new Tone.Delay(0, options.maxDelayTime);\n\t /**\n\t\t\t * the predelay on the right side\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._rightPreDelay = new Tone.Delay(0, options.maxDelayTime);\n\t /**\n\t\t\t * the delay time signal\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.delayTime = new Tone.Signal(options.delayTime, Tone.Type.Time);\n\t //connect it up\n\t this.effectSendL.chain(this._leftDelay, this.effectReturnL);\n\t this.effectSendR.chain(this._rightPreDelay, this._rightDelay, this.effectReturnR);\n\t this.delayTime.fan(this._leftDelay.delayTime, this._rightDelay.delayTime, this._rightPreDelay.delayTime);\n\t //rearranged the feedback to be after the rightPreDelay\n\t this._feedbackLR.disconnect();\n\t this._feedbackLR.connect(this._rightDelay);\n\t this._readOnly(['delayTime']);\n\t };\n\t Tone.extend(Tone.PingPongDelay, Tone.StereoXFeedbackEffect);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.PingPongDelay.defaults = {\n\t 'delayTime': 0.25,\n\t 'maxDelayTime': 1\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.PingPongDelay} this\n\t\t */\n\t Tone.PingPongDelay.prototype.dispose = function () {\n\t Tone.StereoXFeedbackEffect.prototype.dispose.call(this);\n\t this._leftDelay.dispose();\n\t this._leftDelay = null;\n\t this._rightDelay.dispose();\n\t this._rightDelay = null;\n\t this._rightPreDelay.dispose();\n\t this._rightPreDelay = null;\n\t this._writable(['delayTime']);\n\t this.delayTime.dispose();\n\t this.delayTime = null;\n\t return this;\n\t };\n\t return Tone.PingPongDelay;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.PitchShift does near-realtime pitch shifting to the incoming signal.\n\t\t * The effect is achieved by speeding up or slowing down the delayTime\n\t\t * of a DelayNode using a sawtooth wave.\n\t\t * Algorithm found in [this pdf](http://dsp-book.narod.ru/soundproc.pdf).\n\t\t * Additional reference by [Miller Pucket](http://msp.ucsd.edu/techniques/v0.11/book-html/node115.html).\n\t\t *\n\t\t * @extends {Tone.FeedbackEffect}\n\t\t * @param {Interval=} pitch The interval to transpose the incoming signal by.\n\t\t */\n\t Tone.PitchShift = function () {\n\t var options = Tone.defaults(arguments, ['pitch'], Tone.PitchShift);\n\t Tone.FeedbackEffect.call(this, options);\n\t /**\n\t\t\t * The pitch signal\n\t\t\t * @type {Tone.Signal}\n\t\t\t * @private\n\t\t\t */\n\t this._frequency = new Tone.Signal(0);\n\t /**\n\t\t\t * Uses two DelayNodes to cover up the jump in\n\t\t\t * the sawtooth wave.\n\t\t\t * @type {DelayNode}\n\t\t\t * @private\n\t\t\t */\n\t this._delayA = new Tone.Delay(0, 1);\n\t /**\n\t\t\t * The first LFO.\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoA = new Tone.LFO({\n\t 'min': 0,\n\t 'max': 0.1,\n\t 'type': 'sawtooth'\n\t }).connect(this._delayA.delayTime);\n\t /**\n\t\t\t * The second DelayNode\n\t\t\t * @type {DelayNode}\n\t\t\t * @private\n\t\t\t */\n\t this._delayB = new Tone.Delay(0, 1);\n\t /**\n\t\t\t * The first LFO.\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoB = new Tone.LFO({\n\t 'min': 0,\n\t 'max': 0.1,\n\t 'type': 'sawtooth',\n\t 'phase': 180\n\t }).connect(this._delayB.delayTime);\n\t /**\n\t\t\t * Crossfade quickly between the two delay lines\n\t\t\t * to cover up the jump in the sawtooth wave\n\t\t\t * @type {Tone.CrossFade}\n\t\t\t * @private\n\t\t\t */\n\t this._crossFade = new Tone.CrossFade();\n\t /**\n\t\t\t * LFO which alternates between the two\n\t\t\t * delay lines to cover up the disparity in the\n\t\t\t * sawtooth wave.\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._crossFadeLFO = new Tone.LFO({\n\t 'min': 0,\n\t 'max': 1,\n\t 'type': 'triangle',\n\t 'phase': 90\n\t }).connect(this._crossFade.fade);\n\t /**\n\t\t\t * The delay node\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackDelay = new Tone.Delay(options.delayTime);\n\t /**\n\t\t\t * The amount of delay on the input signal\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.delayTime = this._feedbackDelay.delayTime;\n\t this._readOnly('delayTime');\n\t /**\n\t\t\t * Hold the current pitch\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._pitch = options.pitch;\n\t /**\n\t\t\t * Hold the current windowSize\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._windowSize = options.windowSize;\n\t //connect the two delay lines up\n\t this._delayA.connect(this._crossFade.a);\n\t this._delayB.connect(this._crossFade.b);\n\t //connect the frequency\n\t this._frequency.fan(this._lfoA.frequency, this._lfoB.frequency, this._crossFadeLFO.frequency);\n\t //route the input\n\t this.effectSend.fan(this._delayA, this._delayB);\n\t this._crossFade.chain(this._feedbackDelay, this.effectReturn);\n\t //start the LFOs at the same time\n\t var now = this.now();\n\t this._lfoA.start(now);\n\t this._lfoB.start(now);\n\t this._crossFadeLFO.start(now);\n\t //set the initial value\n\t this.windowSize = this._windowSize;\n\t };\n\t Tone.extend(Tone.PitchShift, Tone.FeedbackEffect);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.PitchShift.defaults = {\n\t 'pitch': 0,\n\t 'windowSize': 0.1,\n\t 'delayTime': 0,\n\t 'feedback': 0\n\t };\n\t /**\n\t\t * Repitch the incoming signal by some interval (measured\n\t\t * in semi-tones).\n\t\t * @memberOf Tone.PitchShift#\n\t\t * @type {Interval}\n\t\t * @name pitch\n\t\t * @example\n\t\t * pitchShift.pitch = -12; //down one octave\n\t\t * pitchShift.pitch = 7; //up a fifth\n\t\t */\n\t Object.defineProperty(Tone.PitchShift.prototype, 'pitch', {\n\t get: function () {\n\t return this._pitch;\n\t },\n\t set: function (interval) {\n\t this._pitch = interval;\n\t var factor = 0;\n\t if (interval < 0) {\n\t this._lfoA.min = 0;\n\t this._lfoA.max = this._windowSize;\n\t this._lfoB.min = 0;\n\t this._lfoB.max = this._windowSize;\n\t factor = Tone.intervalToFrequencyRatio(interval - 1) + 1;\n\t } else {\n\t this._lfoA.min = this._windowSize;\n\t this._lfoA.max = 0;\n\t this._lfoB.min = this._windowSize;\n\t this._lfoB.max = 0;\n\t factor = Tone.intervalToFrequencyRatio(interval) - 1;\n\t }\n\t this._frequency.value = factor * (1.2 / this._windowSize);\n\t }\n\t });\n\t /**\n\t\t * The window size corresponds roughly to the sample length in a looping sampler.\n\t\t * Smaller values are desirable for a less noticeable delay time of the pitch shifted\n\t\t * signal, but larger values will result in smoother pitch shifting for larger intervals.\n\t\t * A nominal range of 0.03 to 0.1 is recommended.\n\t\t * @memberOf Tone.PitchShift#\n\t\t * @type {Time}\n\t\t * @name windowSize\n\t\t * @example\n\t\t * pitchShift.windowSize = 0.1;\n\t\t */\n\t Object.defineProperty(Tone.PitchShift.prototype, 'windowSize', {\n\t get: function () {\n\t return this._windowSize;\n\t },\n\t set: function (size) {\n\t this._windowSize = this.toSeconds(size);\n\t this.pitch = this._pitch;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.PitchShift} this\n\t\t */\n\t Tone.PitchShift.prototype.dispose = function () {\n\t Tone.FeedbackEffect.prototype.dispose.call(this);\n\t this._frequency.dispose();\n\t this._frequency = null;\n\t this._delayA.disconnect();\n\t this._delayA = null;\n\t this._delayB.disconnect();\n\t this._delayB = null;\n\t this._lfoA.dispose();\n\t this._lfoA = null;\n\t this._lfoB.dispose();\n\t this._lfoB = null;\n\t this._crossFade.dispose();\n\t this._crossFade = null;\n\t this._crossFadeLFO.dispose();\n\t this._crossFadeLFO = null;\n\t this._writable('delayTime');\n\t this._feedbackDelay.dispose();\n\t this._feedbackDelay = null;\n\t this.delayTime = null;\n\t return this;\n\t };\n\t return Tone.PitchShift;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Wrapper around the native BufferSourceNode.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {AudioBuffer|Tone.Buffer} buffer The buffer to play\n\t\t * @param {Function} onload The callback to invoke when the\n\t\t * buffer is done playing.\n\t\t */\n\t Tone.BufferSource = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'buffer',\n\t 'onload'\n\t ], Tone.BufferSource);\n\t Tone.AudioNode.call(this, options);\n\t /**\n\t\t\t * The callback to invoke after the\n\t\t\t * buffer source is done playing.\n\t\t\t * @type {Function}\n\t\t\t */\n\t this.onended = options.onended;\n\t /**\n\t\t\t * The time that the buffer was started.\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._startTime = -1;\n\t /**\n\t\t\t * An additional flag if the actual BufferSourceNode\n\t\t\t * has been started. b/c stopping an unstarted buffer\n\t\t\t * will throw it into an invalid state\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t this._sourceStarted = false;\n\t /**\n\t\t\t * Flag if the source has already been stopped\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t this._sourceStopped = false;\n\t /**\n\t\t\t * The time that the buffer is scheduled to stop.\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._stopTime = -1;\n\t /**\n\t\t\t * The gain node which envelopes the BufferSource\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._gainNode = this.output = new Tone.Gain();\n\t /**\n\t\t\t * The buffer source\n\t\t\t * @type {AudioBufferSourceNode}\n\t\t\t * @private\n\t\t\t */\n\t this._source = this.context.createBufferSource();\n\t this._source.connect(this._gainNode);\n\t this._source.onended = this._onended.bind(this);\n\t /**\n\t\t\t * The private buffer instance\n\t\t\t * @type {Tone.Buffer}\n\t\t\t * @private\n\t\t\t */\n\t this._buffer = new Tone.Buffer(options.buffer, options.onload);\n\t /**\n\t\t\t * The playbackRate of the buffer\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this.playbackRate = new Tone.Param(this._source.playbackRate, Tone.Type.Positive);\n\t /**\n\t\t\t * The fadeIn time of the amplitude envelope.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.fadeIn = options.fadeIn;\n\t /**\n\t\t\t * The fadeOut time of the amplitude envelope.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.fadeOut = options.fadeOut;\n\t /**\n\t\t\t * The curve applied to the fades, either \"linear\" or \"exponential\"\n\t\t\t * @type {String}\n\t\t\t */\n\t this.curve = options.curve;\n\t /**\n\t\t\t * The value that the buffer ramps to\n\t\t\t * @type {Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._gain = 1;\n\t /**\n\t\t\t * The onended timeout\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._onendedTimeout = -1;\n\t //set some values initially\n\t this.loop = options.loop;\n\t this.loopStart = options.loopStart;\n\t this.loopEnd = options.loopEnd;\n\t this.playbackRate.value = options.playbackRate;\n\t };\n\t Tone.extend(Tone.BufferSource, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.BufferSource.defaults = {\n\t 'onended': Tone.noOp,\n\t 'onload': Tone.noOp,\n\t 'loop': false,\n\t 'loopStart': 0,\n\t 'loopEnd': 0,\n\t 'fadeIn': 0,\n\t 'fadeOut': 0,\n\t 'curve': 'linear',\n\t 'playbackRate': 1\n\t };\n\t /**\n\t\t * Returns the playback state of the source, either \"started\" or \"stopped\".\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.BufferSource#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.BufferSource.prototype, 'state', {\n\t get: function () {\n\t return this.getStateAtTime(this.now());\n\t }\n\t });\n\t /**\n\t\t * Get the playback state at the given time\n\t\t * @param {Time} time The time to test the state at\n\t\t * @return {Tone.State} The playback state. \n\t\t */\n\t Tone.BufferSource.prototype.getStateAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t if (this._startTime !== -1 && time >= this._startTime && !this._sourceStopped) {\n\t return Tone.State.Started;\n\t } else {\n\t return Tone.State.Stopped;\n\t }\n\t };\n\t /**\n\t\t * Start the buffer\n\t\t * @param {Time} [startTime=now] When the player should start.\n\t\t * @param {Time} [offset=0] The offset from the beginning of the sample\n\t\t * to start at.\n\t\t * @param {Time=} duration How long the sample should play. If no duration\n\t\t * is given, it will default to the full length\n\t\t * of the sample (minus any offset)\n\t\t * @param {Gain} [gain=1] The gain to play the buffer back at.\n\t\t * @param {Time=} fadeInTime The optional fadeIn ramp time.\n\t\t * @return {Tone.BufferSource} this\n\t\t */\n\t Tone.BufferSource.prototype.start = function (time, offset, duration, gain, fadeInTime) {\n\t if (this._startTime !== -1) {\n\t throw new Error('Tone.BufferSource can only be started once.');\n\t }\n\t if (!this.buffer.loaded) {\n\t throw new Error('Tone.BufferSource: buffer is either not set or not loaded.');\n\t }\n\t time = this.toSeconds(time);\n\t //if it's a loop the default offset is the loopstart point\n\t if (this.loop) {\n\t offset = Tone.defaultArg(offset, this.loopStart);\n\t } else {\n\t //otherwise the default offset is 0\n\t offset = Tone.defaultArg(offset, 0);\n\t }\n\t offset = this.toSeconds(offset);\n\t gain = Tone.defaultArg(gain, 1);\n\t this._gain = gain;\n\t fadeInTime = this.toSeconds(Tone.defaultArg(fadeInTime, this.fadeIn));\n\t this.fadeIn = fadeInTime;\n\t if (fadeInTime > 0) {\n\t this._gainNode.gain.setValueAtTime(0, time);\n\t if (this.curve === 'linear') {\n\t this._gainNode.gain.linearRampToValueAtTime(this._gain, time + fadeInTime);\n\t } else {\n\t this._gainNode.gain.exponentialApproachValueAtTime(this._gain, time, fadeInTime);\n\t }\n\t } else {\n\t this._gainNode.gain.setValueAtTime(gain, time);\n\t }\n\t this._startTime = time;\n\t var computedDur = this.toSeconds(Tone.defaultArg(duration, this.buffer.duration - offset % this.buffer.duration));\n\t computedDur = Math.max(computedDur, 0);\n\t if (Tone.isDefined(duration)) {\n\t //clip the duration when not looping\n\t if (!this.loop) {\n\t computedDur = Math.min(computedDur, this.buffer.duration - offset % this.buffer.duration);\n\t }\n\t this.stop(time + computedDur, this.fadeOut);\n\t }\n\t //start the buffer source\n\t if (this.loop) {\n\t //modify the offset if it's greater than the loop time\n\t var loopEnd = this.loopEnd || this.buffer.duration;\n\t var loopStart = this.loopStart;\n\t var loopDuration = loopEnd - loopStart;\n\t //move the offset back\n\t if (offset >= loopEnd) {\n\t offset = (offset - loopStart) % loopDuration + loopStart;\n\t }\n\t }\n\t this._source.buffer = this.buffer.get();\n\t this._source.loopEnd = this.loopEnd || this.buffer.duration;\n\t if (offset < this.buffer.duration) {\n\t this._sourceStarted = true;\n\t this._source.start(time, offset);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Stop the buffer. Optionally add a ramp time to fade the\n\t\t * buffer out.\n\t\t * @param {Time=} time The time the buffer should stop.\n\t\t * @param {Time=} fadeOutTime How long the gain should fade out for\n\t\t * @return {Tone.BufferSource} this\n\t\t */\n\t Tone.BufferSource.prototype.stop = function (time, fadeOutTime) {\n\t if (!this.buffer.loaded) {\n\t throw new Error('Tone.BufferSource: buffer is either not set or not loaded.');\n\t }\n\t if (this._sourceStopped) {\n\t return;\n\t }\n\t time = this.toSeconds(time);\n\t //if the event has already been scheduled, clear it\n\t if (this._stopTime !== -1) {\n\t this.cancelStop();\n\t }\n\t //stop if it's schedule before the start time\n\t if (time <= this._startTime) {\n\t this._gainNode.gain.cancelScheduledValues(time);\n\t this._gainNode.gain.value = 0;\n\t return this;\n\t }\n\t time = Math.max(this._startTime + this.fadeIn + this.sampleTime, time);\n\t //cancel the previous curve\n\t this._gainNode.gain.cancelScheduledValues(time);\n\t this._stopTime = time;\n\t //the fadeOut time\n\t fadeOutTime = this.toSeconds(Tone.defaultArg(fadeOutTime, this.fadeOut));\n\t var heldDuration = time - this._startTime - this.fadeIn - this.sampleTime;\n\t if (!this.loop) {\n\t //make sure the fade does not go beyond the length of the buffer\n\t heldDuration = Math.min(heldDuration, this.buffer.duration);\n\t }\n\t fadeOutTime = Math.min(heldDuration, fadeOutTime);\n\t var startFade = time - fadeOutTime;\n\t if (fadeOutTime > this.sampleTime) {\n\t this._gainNode.gain.setValueAtTime(this._gain, startFade);\n\t if (this.curve === 'linear') {\n\t this._gainNode.gain.linearRampToValueAtTime(0, time);\n\t } else {\n\t this._gainNode.gain.exponentialApproachValueAtTime(0, startFade, fadeOutTime);\n\t }\n\t } else {\n\t this._gainNode.gain.setValueAtTime(0, time);\n\t }\n\t Tone.context.clearTimeout(this._onendedTimeout);\n\t this._onendedTimeout = Tone.context.setTimeout(this._onended.bind(this), this._stopTime - this.now());\n\t return this;\n\t };\n\t /**\n\t\t * Cancel a scheduled stop event\n\t\t * @return {Tone.BufferSource} this\n\t\t */\n\t Tone.BufferSource.prototype.cancelStop = function () {\n\t if (this._startTime !== -1 && !this._sourceStopped) {\n\t //cancel the stop envelope\n\t var fadeInTime = this.toSeconds(this.fadeIn);\n\t this._gainNode.gain.cancelScheduledValues(this._startTime + fadeInTime + this.sampleTime);\n\t this._gainNode.gain.setValueAtTime(1, Math.max(this.now(), this._startTime + fadeInTime + this.sampleTime));\n\t this.context.clearTimeout(this._onendedTimeout);\n\t this._stopTime = -1;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Internal callback when the buffer is ended.\n\t\t * Invokes `onended` and disposes the node.\n\t\t * @private\n\t\t */\n\t Tone.BufferSource.prototype._onended = function () {\n\t if (!this._sourceStopped) {\n\t this._sourceStopped = true;\n\t //allow additional time for the exponential curve to fully decay\n\t var additionalTail = this.curve === 'exponential' ? this.fadeOut * 2 : 0;\n\t if (this._sourceStarted && this._stopTime !== -1) {\n\t this._source.stop(this._stopTime + additionalTail);\n\t }\n\t this.onended(this);\n\t }\n\t };\n\t /**\n\t\t * If loop is true, the loop will start at this position.\n\t\t * @memberOf Tone.BufferSource#\n\t\t * @type {Time}\n\t\t * @name loopStart\n\t\t */\n\t Object.defineProperty(Tone.BufferSource.prototype, 'loopStart', {\n\t get: function () {\n\t return this._source.loopStart;\n\t },\n\t set: function (loopStart) {\n\t this._source.loopStart = this.toSeconds(loopStart);\n\t }\n\t });\n\t /**\n\t\t * If loop is true, the loop will end at this position.\n\t\t * @memberOf Tone.BufferSource#\n\t\t * @type {Time}\n\t\t * @name loopEnd\n\t\t */\n\t Object.defineProperty(Tone.BufferSource.prototype, 'loopEnd', {\n\t get: function () {\n\t return this._source.loopEnd;\n\t },\n\t set: function (loopEnd) {\n\t this._source.loopEnd = this.toSeconds(loopEnd);\n\t }\n\t });\n\t /**\n\t\t * The audio buffer belonging to the player.\n\t\t * @memberOf Tone.BufferSource#\n\t\t * @type {Tone.Buffer}\n\t\t * @name buffer\n\t\t */\n\t Object.defineProperty(Tone.BufferSource.prototype, 'buffer', {\n\t get: function () {\n\t return this._buffer;\n\t },\n\t set: function (buffer) {\n\t this._buffer.set(buffer);\n\t }\n\t });\n\t /**\n\t\t * If the buffer should loop once it's over.\n\t\t * @memberOf Tone.BufferSource#\n\t\t * @type {Boolean}\n\t\t * @name loop\n\t\t */\n\t Object.defineProperty(Tone.BufferSource.prototype, 'loop', {\n\t get: function () {\n\t return this._source.loop;\n\t },\n\t set: function (loop) {\n\t this._source.loop = loop;\n\t this.cancelStop();\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.BufferSource} this\n\t\t */\n\t Tone.BufferSource.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.onended = null;\n\t this._source.onended = null;\n\t this._source.disconnect();\n\t this._source = null;\n\t this._gainNode.dispose();\n\t this._gainNode = null;\n\t this._buffer.dispose();\n\t this._buffer = null;\n\t this._startTime = -1;\n\t this.playbackRate = null;\n\t Tone.context.clearTimeout(this._onendedTimeout);\n\t return this;\n\t };\n\t return Tone.BufferSource;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Noise is a noise generator. It uses looped noise buffers to save on performance.\n\t\t * Tone.Noise supports the noise types: \"pink\", \"white\", and \"brown\". Read more about\n\t\t * colors of noise on [Wikipedia](https://en.wikipedia.org/wiki/Colors_of_noise).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Source}\n\t\t * @param {string} type the noise type (white|pink|brown)\n\t\t * @example\n\t\t * //initialize the noise and start\n\t\t * var noise = new Tone.Noise(\"pink\").start();\n\t\t *\n\t\t * //make an autofilter to shape the noise\n\t\t * var autoFilter = new Tone.AutoFilter({\n\t\t * \t\"frequency\" : \"8m\",\n\t\t * \t\"min\" : 800,\n\t\t * \t\"max\" : 15000\n\t\t * }).connect(Tone.Master);\n\t\t *\n\t\t * //connect the noise\n\t\t * noise.connect(autoFilter);\n\t\t * //start the autofilter LFO\n\t\t * autoFilter.start()\n\t\t */\n\t Tone.Noise = function () {\n\t var options = Tone.defaults(arguments, ['type'], Tone.Noise);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * @private\n\t\t\t * @type {AudioBufferSourceNode}\n\t\t\t */\n\t this._source = null;\n\t /**\n\t\t\t * the buffer\n\t\t\t * @private\n\t\t\t * @type {AudioBuffer}\n\t\t\t */\n\t this._type = options.type;\n\t /**\n\t\t\t * The playback rate of the noise. Affects\n\t\t\t * the \"frequency\" of the noise.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this._playbackRate = options.playbackRate;\n\t };\n\t Tone.extend(Tone.Noise, Tone.Source);\n\t /**\n\t\t * the default parameters\n\t\t *\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Noise.defaults = {\n\t 'type': 'white',\n\t 'playbackRate': 1\n\t };\n\t /**\n\t\t * The type of the noise. Can be \"white\", \"brown\", or \"pink\".\n\t\t * @memberOf Tone.Noise#\n\t\t * @type {string}\n\t\t * @name type\n\t\t * @example\n\t\t * noise.type = \"white\";\n\t\t */\n\t Object.defineProperty(Tone.Noise.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t if (this._type !== type) {\n\t if (type in _noiseBuffers) {\n\t this._type = type;\n\t //if it's playing, stop and restart it\n\t if (this.state === Tone.State.Started) {\n\t var now = this.now();\n\t this._stop(now);\n\t this._start(now);\n\t }\n\t } else {\n\t throw new TypeError('Tone.Noise: invalid type: ' + type);\n\t }\n\t }\n\t }\n\t });\n\t /**\n\t\t * The playback rate of the noise. Affects\n\t\t * the \"frequency\" of the noise.\n\t\t * @type {Positive}\n\t\t * @signal\n\t\t */\n\t Object.defineProperty(Tone.Noise.prototype, 'playbackRate', {\n\t get: function () {\n\t return this._playbackRate;\n\t },\n\t set: function (rate) {\n\t this._playbackRate = rate;\n\t if (this._source) {\n\t this._source.playbackRate.value = rate;\n\t }\n\t }\n\t });\n\t /**\n\t\t * internal start method\n\t\t *\n\t\t * @param {Time} time\n\t\t * @private\n\t\t */\n\t Tone.Noise.prototype._start = function (time) {\n\t var buffer = _noiseBuffers[this._type];\n\t this._source = new Tone.BufferSource(buffer).connect(this.output);\n\t this._source.loop = true;\n\t this._source.playbackRate.value = this._playbackRate;\n\t this._source.start(this.toSeconds(time), Math.random() * (buffer.duration - 0.001));\n\t };\n\t /**\n\t\t * internal stop method\n\t\t *\n\t\t * @param {Time} time\n\t\t * @private\n\t\t */\n\t Tone.Noise.prototype._stop = function (time) {\n\t if (this._source) {\n\t this._source.stop(this.toSeconds(time));\n\t this._source = null;\n\t }\n\t };\n\t /**\n\t\t * Restarts the noise.\n\t\t * @param {[type]} time [description]\n\t\t * @return {[type]} [description]\n\t\t */\n\t Tone.Noise.prototype.restart = function (time) {\n\t //TODO could be optimized by cancelling the buffer source 'stop'\n\t //stop and restart\n\t this._stop(time);\n\t this._start(time);\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Noise} this\n\t\t */\n\t Tone.Noise.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t if (this._source !== null) {\n\t this._source.disconnect();\n\t this._source = null;\n\t }\n\t this._buffer = null;\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t // THE BUFFERS\n\t ///////////////////////////////////////////////////////////////////////////\n\t //Noise buffer stats\n\t var bufferLength = 44100 * 5;\n\t var channels = 2;\n\t /**\n\t\t *\tThe noise arrays. Generated on initialization.\n\t\t * borrowed heavily from https://github.com/zacharydenton/noise.js\n\t\t * (c) 2013 Zach Denton (MIT)\n\t\t * @static\n\t\t * @private\n\t\t * @type {Array}\n\t\t */\n\t var _noiseArrays = {\n\t 'pink': function () {\n\t var buffer = [];\n\t for (var channelNum = 0; channelNum < channels; channelNum++) {\n\t var channel = new Float32Array(bufferLength);\n\t buffer[channelNum] = channel;\n\t var b0, b1, b2, b3, b4, b5, b6;\n\t b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0;\n\t for (var i = 0; i < bufferLength; i++) {\n\t var white = Math.random() * 2 - 1;\n\t b0 = 0.99886 * b0 + white * 0.0555179;\n\t b1 = 0.99332 * b1 + white * 0.0750759;\n\t b2 = 0.969 * b2 + white * 0.153852;\n\t b3 = 0.8665 * b3 + white * 0.3104856;\n\t b4 = 0.55 * b4 + white * 0.5329522;\n\t b5 = -0.7616 * b5 - white * 0.016898;\n\t channel[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;\n\t channel[i] *= 0.11;\n\t // (roughly) compensate for gain\n\t b6 = white * 0.115926;\n\t }\n\t }\n\t return buffer;\n\t }(),\n\t 'brown': function () {\n\t var buffer = [];\n\t for (var channelNum = 0; channelNum < channels; channelNum++) {\n\t var channel = new Float32Array(bufferLength);\n\t buffer[channelNum] = channel;\n\t var lastOut = 0;\n\t for (var i = 0; i < bufferLength; i++) {\n\t var white = Math.random() * 2 - 1;\n\t channel[i] = (lastOut + 0.02 * white) / 1.02;\n\t lastOut = channel[i];\n\t channel[i] *= 3.5; // (roughly) compensate for gain\n\t }\n\t }\n\t return buffer;\n\t }(),\n\t 'white': function () {\n\t var buffer = [];\n\t for (var channelNum = 0; channelNum < channels; channelNum++) {\n\t var channel = new Float32Array(bufferLength);\n\t buffer[channelNum] = channel;\n\t for (var i = 0; i < bufferLength; i++) {\n\t channel[i] = Math.random() * 2 - 1;\n\t }\n\t }\n\t return buffer;\n\t }()\n\t };\n\t /**\n\t\t *\tstatic noise buffers\n\t\t * @static\n\t\t * @private\n\t\t * @type {Tone.Buffer}\n\t\t */\n\t var _noiseBuffers = {};\n\t //create the Tone.Buffers\n\t function createBuffers() {\n\t for (var type in _noiseArrays) {\n\t _noiseBuffers[type] = new Tone.Buffer().fromArray(_noiseArrays[type]);\n\t }\n\t }\n\t //create the noise buffers\n\t Tone.getContext(createBuffers);\n\t Tone.Context.on('init', createBuffers);\n\t return Tone.Noise;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Simple convolution created with decaying noise.\n\t\t * \t\tGenerates an Impulse Response Buffer\n\t\t * \t\t\twith Tone.Offline then feeds the IR into ConvolverNode.\n\t\t * \t\t\tNote: the Reverb will not make any sound until [generate](#generate)\n\t\t * \t\t\thas been invoked and resolved.\n\t\t *\n\t\t * \t\t\tInspiration from [ReverbGen](https://github.com/adelespinasse/reverbGen).\n\t\t * \t\t\tCopyright (c) 2014 Alan deLespinasse Apache 2.0 License.\n\t\t *\n\t\t * @extends {Tone.Convolver}\n\t\t * @param {Time=} decay The amount of time it will reverberate for.\n\t\t */\n\t Tone.Reverb = function () {\n\t var options = Tone.defaults(arguments, ['decay'], Tone.Reverb);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * Convolver node\n\t\t\t * @type {ConvolverNode}\n\t\t\t * @private\n\t\t\t */\n\t this._convolver = this.context.createConvolver();\n\t /**\n\t\t\t * The duration of the reverb\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.decay = options.decay;\n\t /**\n\t\t\t * The amount of time before the reverb is fully\n\t\t\t * ramped in.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.preDelay = options.preDelay;\n\t this.connectEffect(this._convolver);\n\t };\n\t Tone.extend(Tone.Reverb, Tone.Effect);\n\t /**\n\t\t * The defaults\n\t\t * @type {Object}\n\t\t * @static\n\t\t */\n\t Tone.Reverb.defaults = {\n\t 'decay': 1.5,\n\t 'preDelay': 0.01\n\t };\n\t /**\n\t\t * Generate the Impulse Response. Returns a promise while the IR is being\n\t\t * generated.\n\t\t * @return {Promise<Tone.Reverb>} Promise which returns this object.\n\t\t */\n\t Tone.Reverb.prototype.generate = function () {\n\t return Tone.Offline(function () {\n\t //create a noise burst which decays over the duration\n\t var noiseL = new Tone.Noise();\n\t var noiseR = new Tone.Noise();\n\t var merge = new Tone.Merge();\n\t noiseL.connect(merge.left);\n\t noiseR.connect(merge.right);\n\t var gainNode = new Tone.Gain().toMaster();\n\t merge.connect(gainNode);\n\t noiseL.start(0);\n\t noiseR.start(0);\n\t //short fade in\n\t gainNode.gain.setValueAtTime(0, 0);\n\t gainNode.gain.linearRampToValueAtTime(1, this.preDelay);\n\t //decay\n\t gainNode.gain.exponentialApproachValueAtTime(0, this.preDelay, this.decay - this.preDelay);\n\t }.bind(this), this.decay).then(function (buffer) {\n\t this._convolver.buffer = buffer.get();\n\t return this;\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Reverb} this\n\t\t */\n\t Tone.Reverb.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._convolver.disconnect();\n\t this._convolver = null;\n\t return this;\n\t };\n\t return Tone.Reverb;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Base class for stereo feedback effects where the effectReturn\n\t\t * is fed back into the same channel.\n\t\t *\n\t\t *\t@constructor\n\t\t *\t@extends {Tone.StereoEffect}\n\t\t */\n\t Tone.StereoFeedbackEffect = function () {\n\t var options = Tone.defaults(arguments, ['feedback'], Tone.FeedbackEffect);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * controls the amount of feedback\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.feedback = new Tone.Signal(options.feedback, Tone.Type.NormalRange);\n\t /**\n\t\t\t * the left side feeback\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackL = new Tone.Gain();\n\t /**\n\t\t\t * the right side feeback\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackR = new Tone.Gain();\n\t //connect it up\n\t this.effectReturnL.chain(this._feedbackL, this.effectSendL);\n\t this.effectReturnR.chain(this._feedbackR, this.effectSendR);\n\t this.feedback.fan(this._feedbackL.gain, this._feedbackR.gain);\n\t this._readOnly(['feedback']);\n\t };\n\t Tone.extend(Tone.StereoFeedbackEffect, Tone.StereoEffect);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.StereoFeedbackEffect} this\n\t\t */\n\t Tone.StereoFeedbackEffect.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t this._writable(['feedback']);\n\t this.feedback.dispose();\n\t this.feedback = null;\n\t this._feedbackL.dispose();\n\t this._feedbackL = null;\n\t this._feedbackR.dispose();\n\t this._feedbackR = null;\n\t return this;\n\t };\n\t return Tone.StereoFeedbackEffect;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Applies a width factor to the mid/side seperation.\n\t\t * 0 is all mid and 1 is all side.\n\t\t * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587).\n\t\t * <br><br>\n\t\t * <code>\n\t\t * Mid *= 2*(1-width)<br>\n\t\t * Side *= 2*width\n\t\t * </code>\n\t\t *\n\t\t * @extends {Tone.MidSideEffect}\n\t\t * @constructor\n\t\t * @param {NormalRange|Object} [width] The stereo width. A width of 0 is mono and 1 is stereo. 0.5 is no change.\n\t\t */\n\t Tone.StereoWidener = function () {\n\t var options = Tone.defaults(arguments, ['width'], Tone.StereoWidener);\n\t Tone.MidSideEffect.call(this, options);\n\t /**\n\t\t\t * The width control. 0 = 100% mid. 1 = 100% side. 0.5 = no change.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.width = new Tone.Signal(options.width, Tone.Type.NormalRange);\n\t this._readOnly(['width']);\n\t /**\n\t\t\t * Two times the (1-width) for the mid channel\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._twoTimesWidthMid = new Tone.Multiply(2);\n\t /**\n\t\t\t * Two times the width for the side channel\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._twoTimesWidthSide = new Tone.Multiply(2);\n\t /**\n\t\t\t * Mid multiplier\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._midMult = new Tone.Multiply();\n\t this._twoTimesWidthMid.connect(this._midMult, 0, 1);\n\t this.midSend.chain(this._midMult, this.midReturn);\n\t /**\n\t\t\t * 1 - width\n\t\t\t * @type {Tone}\n\t\t\t */\n\t this._oneMinusWidth = new Tone.Subtract();\n\t this._oneMinusWidth.connect(this._twoTimesWidthMid);\n\t this.context.getConstant(1).connect(this._oneMinusWidth, 0, 0);\n\t this.width.connect(this._oneMinusWidth, 0, 1);\n\t /**\n\t\t\t * Side multiplier\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._sideMult = new Tone.Multiply();\n\t this.width.connect(this._twoTimesWidthSide);\n\t this._twoTimesWidthSide.connect(this._sideMult, 0, 1);\n\t this.sideSend.chain(this._sideMult, this.sideReturn);\n\t };\n\t Tone.extend(Tone.StereoWidener, Tone.MidSideEffect);\n\t /**\n\t\t * the default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.StereoWidener.defaults = { 'width': 0.5 };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.StereoWidener} this\n\t\t */\n\t Tone.StereoWidener.prototype.dispose = function () {\n\t Tone.MidSideEffect.prototype.dispose.call(this);\n\t this._writable(['width']);\n\t this.width.dispose();\n\t this.width = null;\n\t this._midMult.dispose();\n\t this._midMult = null;\n\t this._sideMult.dispose();\n\t this._sideMult = null;\n\t this._twoTimesWidthMid.dispose();\n\t this._twoTimesWidthMid = null;\n\t this._twoTimesWidthSide.dispose();\n\t this._twoTimesWidthSide = null;\n\t this._oneMinusWidth.dispose();\n\t this._oneMinusWidth = null;\n\t return this;\n\t };\n\t return Tone.StereoWidener;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Tremolo modulates the amplitude of an incoming signal using a Tone.LFO.\n\t\t * The type, frequency, and depth of the LFO is controllable.\n\t\t *\n\t\t * @extends {Tone.StereoEffect}\n\t\t * @constructor\n\t\t * @param {Frequency} [frequency] The rate of the effect.\n\t\t * @param {NormalRange} [depth] The depth of the effect.\n\t\t * @example\n\t\t * //create a tremolo and start it's LFO\n\t\t * var tremolo = new Tone.Tremolo(9, 0.75).toMaster().start();\n\t\t * //route an oscillator through the tremolo and start it\n\t\t * var oscillator = new Tone.Oscillator().connect(tremolo).start();\n\t\t */\n\t Tone.Tremolo = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'depth'\n\t ], Tone.Tremolo);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * The tremelo LFO in the left channel\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoL = new Tone.LFO({\n\t 'phase': options.spread,\n\t 'min': 1,\n\t 'max': 0\n\t });\n\t /**\n\t\t\t * The tremelo LFO in the left channel\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoR = new Tone.LFO({\n\t 'phase': options.spread,\n\t 'min': 1,\n\t 'max': 0\n\t });\n\t /**\n\t\t\t * Where the gain is multiplied\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._amplitudeL = new Tone.Gain();\n\t /**\n\t\t\t * Where the gain is multiplied\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._amplitudeR = new Tone.Gain();\n\t /**\n\t\t\t * The frequency of the tremolo.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The depth of the effect. A depth of 0, has no effect\n\t\t\t * on the amplitude, and a depth of 1 makes the amplitude\n\t\t\t * modulate fully between 0 and 1.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.depth = new Tone.Signal(options.depth, Tone.Type.NormalRange);\n\t this._readOnly([\n\t 'frequency',\n\t 'depth'\n\t ]);\n\t this.effectSendL.chain(this._amplitudeL, this.effectReturnL);\n\t this.effectSendR.chain(this._amplitudeR, this.effectReturnR);\n\t this._lfoL.connect(this._amplitudeL.gain);\n\t this._lfoR.connect(this._amplitudeR.gain);\n\t this.frequency.fan(this._lfoL.frequency, this._lfoR.frequency);\n\t this.depth.fan(this._lfoR.amplitude, this._lfoL.amplitude);\n\t this.type = options.type;\n\t this.spread = options.spread;\n\t };\n\t Tone.extend(Tone.Tremolo, Tone.StereoEffect);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Tremolo.defaults = {\n\t 'frequency': 10,\n\t 'type': 'sine',\n\t 'depth': 0.5,\n\t 'spread': 180\n\t };\n\t /**\n\t\t * Start the tremolo.\n\t\t * @param {Time} [time=now] When the tremolo begins.\n\t\t * @returns {Tone.Tremolo} this\n\t\t */\n\t Tone.Tremolo.prototype.start = function (time) {\n\t this._lfoL.start(time);\n\t this._lfoR.start(time);\n\t return this;\n\t };\n\t /**\n\t\t * Stop the tremolo.\n\t\t * @param {Time} [time=now] When the tremolo stops.\n\t\t * @returns {Tone.Tremolo} this\n\t\t */\n\t Tone.Tremolo.prototype.stop = function (time) {\n\t this._lfoL.stop(time);\n\t this._lfoR.stop(time);\n\t return this;\n\t };\n\t /**\n\t\t * Sync the effect to the transport.\n\t\t * @param {Time} [delay=0] Delay time before starting the effect after the\n\t\t * Transport has started.\n\t\t * @returns {Tone.AutoFilter} this\n\t\t */\n\t Tone.Tremolo.prototype.sync = function (delay) {\n\t this._lfoL.sync(delay);\n\t this._lfoR.sync(delay);\n\t Tone.Transport.syncSignal(this.frequency);\n\t return this;\n\t };\n\t /**\n\t\t * Unsync the filter from the transport\n\t\t * @returns {Tone.Tremolo} this\n\t\t */\n\t Tone.Tremolo.prototype.unsync = function () {\n\t this._lfoL.unsync();\n\t this._lfoR.unsync();\n\t Tone.Transport.unsyncSignal(this.frequency);\n\t return this;\n\t };\n\t /**\n\t\t * The Tremolo's oscillator type.\n\t\t * @memberOf Tone.Tremolo#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.Tremolo.prototype, 'type', {\n\t get: function () {\n\t return this._lfoL.type;\n\t },\n\t set: function (type) {\n\t this._lfoL.type = type;\n\t this._lfoR.type = type;\n\t }\n\t });\n\t /**\n\t\t * Amount of stereo spread. When set to 0, both LFO's will be panned centrally.\n\t\t * When set to 180, LFO's will be panned hard left and right respectively.\n\t\t * @memberOf Tone.Tremolo#\n\t\t * @type {Degrees}\n\t\t * @name spread\n\t\t */\n\t Object.defineProperty(Tone.Tremolo.prototype, 'spread', {\n\t get: function () {\n\t return this._lfoR.phase - this._lfoL.phase; //180\n\t },\n\t set: function (spread) {\n\t this._lfoL.phase = 90 - spread / 2;\n\t this._lfoR.phase = spread / 2 + 90;\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Tremolo} this\n\t\t */\n\t Tone.Tremolo.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'depth'\n\t ]);\n\t this._lfoL.dispose();\n\t this._lfoL = null;\n\t this._lfoR.dispose();\n\t this._lfoR = null;\n\t this._amplitudeL.dispose();\n\t this._amplitudeL = null;\n\t this._amplitudeR.dispose();\n\t this._amplitudeR = null;\n\t this.frequency = null;\n\t this.depth = null;\n\t return this;\n\t };\n\t return Tone.Tremolo;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A Vibrato effect composed of a Tone.Delay and a Tone.LFO. The LFO\n\t\t * modulates the delayTime of the delay, causing the pitch to rise\n\t\t * and fall. \n\t\t * @extends {Tone.Effect}\n\t\t * @param {Frequency} frequency The frequency of the vibrato.\n\t\t * @param {NormalRange} depth The amount the pitch is modulated.\n\t\t */\n\t Tone.Vibrato = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'depth'\n\t ], Tone.Vibrato);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * The delay node used for the vibrato effect\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._delayNode = new Tone.Delay(0, options.maxDelay);\n\t /**\n\t\t\t * The LFO used to control the vibrato\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfo = new Tone.LFO({\n\t 'type': options.type,\n\t 'min': 0,\n\t 'max': options.maxDelay,\n\t 'frequency': options.frequency,\n\t 'phase': -90 //offse the phase so the resting position is in the center\n\t }).start().connect(this._delayNode.delayTime);\n\t /**\n\t\t\t * The frequency of the vibrato\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._lfo.frequency;\n\t /**\n\t\t\t * The depth of the vibrato. \n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.depth = this._lfo.amplitude;\n\t this.depth.value = options.depth;\n\t this._readOnly([\n\t 'frequency',\n\t 'depth'\n\t ]);\n\t this.effectSend.chain(this._delayNode, this.effectReturn);\n\t };\n\t Tone.extend(Tone.Vibrato, Tone.Effect);\n\t /**\n\t\t * The defaults\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Vibrato.defaults = {\n\t 'maxDelay': 0.005,\n\t 'frequency': 5,\n\t 'depth': 0.1,\n\t 'type': 'sine'\n\t };\n\t /**\n\t\t * Type of oscillator attached to the Vibrato.\n\t\t * @memberOf Tone.Vibrato#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.Vibrato.prototype, 'type', {\n\t get: function () {\n\t return this._lfo.type;\n\t },\n\t set: function (type) {\n\t this._lfo.type = type;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Vibrato} this\n\t\t */\n\t Tone.Vibrato.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._delayNode.dispose();\n\t this._delayNode = null;\n\t this._lfo.dispose();\n\t this._lfo = null;\n\t this._writable([\n\t 'frequency',\n\t 'depth'\n\t ]);\n\t this.frequency = null;\n\t this.depth = null;\n\t };\n\t return Tone.Vibrato;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Event abstracts away Tone.Transport.schedule and provides a schedulable\n\t\t * callback for a single or repeatable events along the timeline.\n\t\t *\n\t\t * @extends {Tone}\n\t\t * @param {function} callback The callback to invoke at the time.\n\t\t * @param {*} value The value or values which should be passed to\n\t\t * the callback function on invocation.\n\t\t * @example\n\t\t * var chord = new Tone.Event(function(time, chord){\n\t\t * \t//the chord as well as the exact time of the event\n\t\t * \t//are passed in as arguments to the callback function\n\t\t * }, [\"D4\", \"E4\", \"F4\"]);\n\t\t * //start the chord at the beginning of the transport timeline\n\t\t * chord.start();\n\t\t * //loop it every measure for 8 measures\n\t\t * chord.loop = 8;\n\t\t * chord.loopEnd = \"1m\";\n\t\t */\n\t Tone.Event = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'callback',\n\t 'value'\n\t ], Tone.Event);\n\t Tone.call(this);\n\t /**\n\t\t\t * Loop value\n\t\t\t * @type {Boolean|Positive}\n\t\t\t * @private\n\t\t\t */\n\t this._loop = options.loop;\n\t /**\n\t\t\t * The callback to invoke.\n\t\t\t * @type {Function}\n\t\t\t */\n\t this.callback = options.callback;\n\t /**\n\t\t\t * The value which is passed to the\n\t\t\t * callback function.\n\t\t\t * @type {*}\n\t\t\t * @private\n\t\t\t */\n\t this.value = options.value;\n\t /**\n\t\t\t * When the note is scheduled to start.\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._loopStart = this.toTicks(options.loopStart);\n\t /**\n\t\t\t * When the note is scheduled to start.\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._loopEnd = this.toTicks(options.loopEnd);\n\t /**\n\t\t\t * Tracks the scheduled events\n\t\t\t * @type {Tone.TimelineState}\n\t\t\t * @private\n\t\t\t */\n\t this._state = new Tone.TimelineState(Tone.State.Stopped);\n\t /**\n\t\t\t * The playback speed of the note. A speed of 1\n\t\t\t * is no change.\n\t\t\t * @private\n\t\t\t * @type {Positive}\n\t\t\t */\n\t this._playbackRate = 1;\n\t /**\n\t\t\t * A delay time from when the event is scheduled to start\n\t\t\t * @type {Ticks}\n\t\t\t * @private\n\t\t\t */\n\t this._startOffset = 0;\n\t /**\n\t\t\t * private holder of probability value\n\t\t\t * @type {NormalRange}\n\t\t\t * @private\n\t\t\t */\n\t this._probability = options.probability;\n\t /**\n\t\t\t * the amount of variation from the\n\t\t\t * given time.\n\t\t\t * @type {Boolean|Time}\n\t\t\t * @private\n\t\t\t */\n\t this._humanize = options.humanize;\n\t /**\n\t\t\t * If mute is true, the callback won't be\n\t\t\t * invoked.\n\t\t\t * @type {Boolean}\n\t\t\t */\n\t this.mute = options.mute;\n\t //set the initial values\n\t this.playbackRate = options.playbackRate;\n\t };\n\t Tone.extend(Tone.Event);\n\t /**\n\t\t * The default values\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Event.defaults = {\n\t 'callback': Tone.noOp,\n\t 'loop': false,\n\t 'loopEnd': '1m',\n\t 'loopStart': 0,\n\t 'playbackRate': 1,\n\t 'value': null,\n\t 'probability': 1,\n\t 'mute': false,\n\t 'humanize': false\n\t };\n\t /**\n\t\t * Reschedule all of the events along the timeline\n\t\t * with the updated values.\n\t\t * @param {Time} after Only reschedules events after the given time.\n\t\t * @return {Tone.Event} this\n\t\t * @private\n\t\t */\n\t Tone.Event.prototype._rescheduleEvents = function (after) {\n\t //if no argument is given, schedules all of the events\n\t after = Tone.defaultArg(after, -1);\n\t this._state.forEachFrom(after, function (event) {\n\t var duration;\n\t if (event.state === Tone.State.Started) {\n\t if (Tone.isDefined(event.id)) {\n\t Tone.Transport.clear(event.id);\n\t }\n\t var startTick = event.time + Math.round(this.startOffset / this._playbackRate);\n\t if (this._loop) {\n\t duration = Infinity;\n\t if (Tone.isNumber(this._loop)) {\n\t duration = this._loop * this._getLoopDuration();\n\t }\n\t var nextEvent = this._state.getAfter(startTick);\n\t if (nextEvent !== null) {\n\t duration = Math.min(duration, nextEvent.time - startTick);\n\t }\n\t if (duration !== Infinity) {\n\t //schedule a stop since it's finite duration\n\t this._state.setStateAtTime(Tone.State.Stopped, startTick + duration + 1);\n\t duration = Tone.Ticks(duration);\n\t }\n\t var interval = Tone.Ticks(this._getLoopDuration());\n\t event.id = Tone.Transport.scheduleRepeat(this._tick.bind(this), interval, Tone.Ticks(startTick), duration);\n\t } else {\n\t event.id = Tone.Transport.schedule(this._tick.bind(this), Tone.Ticks(startTick));\n\t }\n\t }\n\t }.bind(this));\n\t return this;\n\t };\n\t /**\n\t\t * Returns the playback state of the note, either \"started\" or \"stopped\".\n\t\t * @type {String}\n\t\t * @readOnly\n\t\t * @memberOf Tone.Event#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'state', {\n\t get: function () {\n\t return this._state.getValueAtTime(Tone.Transport.ticks);\n\t }\n\t });\n\t /**\n\t\t * The start from the scheduled start time\n\t\t * @type {Ticks}\n\t\t * @memberOf Tone.Event#\n\t\t * @name startOffset\n\t\t * @private\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'startOffset', {\n\t get: function () {\n\t return this._startOffset;\n\t },\n\t set: function (offset) {\n\t this._startOffset = offset;\n\t }\n\t });\n\t /**\n\t\t * The probability of the notes being triggered.\n\t\t * @memberOf Tone.Event#\n\t\t * @type {NormalRange}\n\t\t * @name probability\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'probability', {\n\t get: function () {\n\t return this._probability;\n\t },\n\t set: function (prob) {\n\t this._probability = prob;\n\t }\n\t });\n\t /**\n\t\t * If set to true, will apply small random variation\n\t\t * to the callback time. If the value is given as a time, it will randomize\n\t\t * by that amount.\n\t\t * @example\n\t\t * event.humanize = true;\n\t\t * @type {Boolean|Time}\n\t\t * @name humanize\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'humanize', {\n\t get: function () {\n\t return this._humanize;\n\t },\n\t set: function (variation) {\n\t this._humanize = variation;\n\t }\n\t });\n\t /**\n\t\t * Start the note at the given time.\n\t\t * @param {TimelinePosition} time When the note should start.\n\t\t * @return {Tone.Event} this\n\t\t */\n\t Tone.Event.prototype.start = function (time) {\n\t time = this.toTicks(time);\n\t if (this._state.getValueAtTime(time) === Tone.State.Stopped) {\n\t this._state.add({\n\t 'state': Tone.State.Started,\n\t 'time': time,\n\t 'id': undefined\n\t });\n\t this._rescheduleEvents(time);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Stop the Event at the given time.\n\t\t * @param {TimelinePosition} time When the note should stop.\n\t\t * @return {Tone.Event} this\n\t\t */\n\t Tone.Event.prototype.stop = function (time) {\n\t this.cancel(time);\n\t time = this.toTicks(time);\n\t if (this._state.getValueAtTime(time) === Tone.State.Started) {\n\t this._state.setStateAtTime(Tone.State.Stopped, time);\n\t var previousEvent = this._state.getBefore(time);\n\t var reschedulTime = time;\n\t if (previousEvent !== null) {\n\t reschedulTime = previousEvent.time;\n\t }\n\t this._rescheduleEvents(reschedulTime);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Cancel all scheduled events greater than or equal to the given time\n\t\t * @param {TimelinePosition} [time=0] The time after which events will be cancel.\n\t\t * @return {Tone.Event} this\n\t\t */\n\t Tone.Event.prototype.cancel = function (time) {\n\t time = Tone.defaultArg(time, -Infinity);\n\t time = this.toTicks(time);\n\t this._state.forEachFrom(time, function (event) {\n\t Tone.Transport.clear(event.id);\n\t });\n\t this._state.cancel(time);\n\t return this;\n\t };\n\t /**\n\t\t * The callback function invoker. Also\n\t\t * checks if the Event is done playing\n\t\t * @param {Number} time The time of the event in seconds\n\t\t * @private\n\t\t */\n\t Tone.Event.prototype._tick = function (time) {\n\t var ticks = Tone.Transport.getTicksAtTime(time);\n\t if (!this.mute && this._state.getValueAtTime(ticks) === Tone.State.Started) {\n\t if (this.probability < 1 && Math.random() > this.probability) {\n\t return;\n\t }\n\t if (this.humanize) {\n\t var variation = 0.02;\n\t if (!Tone.isBoolean(this.humanize)) {\n\t variation = this.toSeconds(this.humanize);\n\t }\n\t time += (Math.random() * 2 - 1) * variation;\n\t }\n\t this.callback(time, this.value);\n\t }\n\t };\n\t /**\n\t\t * Get the duration of the loop.\n\t\t * @return {Ticks}\n\t\t * @private\n\t\t */\n\t Tone.Event.prototype._getLoopDuration = function () {\n\t return Math.round((this._loopEnd - this._loopStart) / this._playbackRate);\n\t };\n\t /**\n\t\t * If the note should loop or not\n\t\t * between Tone.Event.loopStart and\n\t\t * Tone.Event.loopEnd. An integer\n\t\t * value corresponds to the number of\n\t\t * loops the Event does after it starts.\n\t\t * @memberOf Tone.Event#\n\t\t * @type {Boolean|Positive}\n\t\t * @name loop\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'loop', {\n\t get: function () {\n\t return this._loop;\n\t },\n\t set: function (loop) {\n\t this._loop = loop;\n\t this._rescheduleEvents();\n\t }\n\t });\n\t /**\n\t\t * \tThe playback rate of the note. Defaults to 1.\n\t\t * @memberOf Tone.Event#\n\t\t * @type {Positive}\n\t\t * @name playbackRate\n\t\t * @example\n\t\t * note.loop = true;\n\t\t * //repeat the note twice as fast\n\t\t * note.playbackRate = 2;\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'playbackRate', {\n\t get: function () {\n\t return this._playbackRate;\n\t },\n\t set: function (rate) {\n\t this._playbackRate = rate;\n\t this._rescheduleEvents();\n\t }\n\t });\n\t /**\n\t\t * The loopEnd point is the time the event will loop\n\t\t * if Tone.Event.loop is true.\n\t\t * @memberOf Tone.Event#\n\t\t * @type {Time}\n\t\t * @name loopEnd\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'loopEnd', {\n\t get: function () {\n\t return Tone.Ticks(this._loopEnd).toSeconds();\n\t },\n\t set: function (loopEnd) {\n\t this._loopEnd = this.toTicks(loopEnd);\n\t if (this._loop) {\n\t this._rescheduleEvents();\n\t }\n\t }\n\t });\n\t /**\n\t\t * The time when the loop should start.\n\t\t * @memberOf Tone.Event#\n\t\t * @type {Time}\n\t\t * @name loopStart\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'loopStart', {\n\t get: function () {\n\t return Tone.Ticks(this._loopStart).toSeconds();\n\t },\n\t set: function (loopStart) {\n\t this._loopStart = this.toTicks(loopStart);\n\t if (this._loop) {\n\t this._rescheduleEvents();\n\t }\n\t }\n\t });\n\t /**\n\t\t * The current progress of the loop interval.\n\t\t * Returns 0 if the event is not started yet or\n\t\t * it is not set to loop.\n\t\t * @memberOf Tone.Event#\n\t\t * @type {NormalRange}\n\t\t * @name progress\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'progress', {\n\t get: function () {\n\t if (this._loop) {\n\t var ticks = Tone.Transport.ticks;\n\t var lastEvent = this._state.get(ticks);\n\t if (lastEvent !== null && lastEvent.state === Tone.State.Started) {\n\t var loopDuration = this._getLoopDuration();\n\t var progress = (ticks - lastEvent.time) % loopDuration;\n\t return progress / loopDuration;\n\t } else {\n\t return 0;\n\t }\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Event} this\n\t\t */\n\t Tone.Event.prototype.dispose = function () {\n\t this.cancel();\n\t this._state.dispose();\n\t this._state = null;\n\t this.callback = null;\n\t this.value = null;\n\t };\n\t return Tone.Event;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Loop creates a looped callback at the \n\t\t * specified interval. The callback can be \n\t\t * started, stopped and scheduled along\n\t\t * the Transport's timeline. \n\t\t * @example\n\t\t * var loop = new Tone.Loop(function(time){\n\t\t * \t//triggered every eighth note. \n\t\t * \tconsole.log(time);\n\t\t * }, \"8n\").start(0);\n\t\t * Tone.Transport.start();\n\t\t * @extends {Tone}\n\t\t * @param {Function} callback The callback to invoke with the event.\n\t\t * @param {Time} interval The time between successive callback calls. \n\t\t */\n\t Tone.Loop = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'callback',\n\t 'interval'\n\t ], Tone.Loop);\n\t Tone.call(this);\n\t /**\n\t\t\t * The event which produces the callbacks\n\t\t\t */\n\t this._event = new Tone.Event({\n\t 'callback': this._tick.bind(this),\n\t 'loop': true,\n\t 'loopEnd': options.interval,\n\t 'playbackRate': options.playbackRate,\n\t 'probability': options.probability\n\t });\n\t /**\n\t\t\t * The callback to invoke with the next event in the pattern\n\t\t\t * @type {Function}\n\t\t\t */\n\t this.callback = options.callback;\n\t //set the iterations\n\t this.iterations = options.iterations;\n\t };\n\t Tone.extend(Tone.Loop);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Loop.defaults = {\n\t 'interval': '4n',\n\t 'callback': Tone.noOp,\n\t 'playbackRate': 1,\n\t 'iterations': Infinity,\n\t 'probability': true,\n\t 'mute': false\n\t };\n\t /**\n\t\t * Start the loop at the specified time along the Transport's\n\t\t * timeline.\n\t\t * @param {TimelinePosition=} time When to start the Loop.\n\t\t * @return {Tone.Loop} this\n\t\t */\n\t Tone.Loop.prototype.start = function (time) {\n\t this._event.start(time);\n\t return this;\n\t };\n\t /**\n\t\t * Stop the loop at the given time.\n\t\t * @param {TimelinePosition=} time When to stop the Arpeggio\n\t\t * @return {Tone.Loop} this\n\t\t */\n\t Tone.Loop.prototype.stop = function (time) {\n\t this._event.stop(time);\n\t return this;\n\t };\n\t /**\n\t\t * Cancel all scheduled events greater than or equal to the given time\n\t\t * @param {TimelinePosition} [time=0] The time after which events will be cancel.\n\t\t * @return {Tone.Loop} this\n\t\t */\n\t Tone.Loop.prototype.cancel = function (time) {\n\t this._event.cancel(time);\n\t return this;\n\t };\n\t /**\n\t\t * Internal function called when the notes should be called\n\t\t * @param {Number} time The time the event occurs\n\t\t * @private\n\t\t */\n\t Tone.Loop.prototype._tick = function (time) {\n\t this.callback(time);\n\t };\n\t /**\n\t\t * The state of the Loop, either started or stopped.\n\t\t * @memberOf Tone.Loop#\n\t\t * @type {String}\n\t\t * @name state\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'state', {\n\t get: function () {\n\t return this._event.state;\n\t }\n\t });\n\t /**\n\t\t * The progress of the loop as a value between 0-1. 0, when\n\t\t * the loop is stopped or done iterating. \n\t\t * @memberOf Tone.Loop#\n\t\t * @type {NormalRange}\n\t\t * @name progress\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'progress', {\n\t get: function () {\n\t return this._event.progress;\n\t }\n\t });\n\t /**\n\t\t * The time between successive callbacks. \n\t\t * @example\n\t\t * loop.interval = \"8n\"; //loop every 8n\n\t\t * @memberOf Tone.Loop#\n\t\t * @type {Time}\n\t\t * @name interval\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'interval', {\n\t get: function () {\n\t return this._event.loopEnd;\n\t },\n\t set: function (interval) {\n\t this._event.loopEnd = interval;\n\t }\n\t });\n\t /**\n\t\t * The playback rate of the loop. The normal playback rate is 1 (no change). \n\t\t * A `playbackRate` of 2 would be twice as fast. \n\t\t * @memberOf Tone.Loop#\n\t\t * @type {Time}\n\t\t * @name playbackRate\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'playbackRate', {\n\t get: function () {\n\t return this._event.playbackRate;\n\t },\n\t set: function (rate) {\n\t this._event.playbackRate = rate;\n\t }\n\t });\n\t /**\n\t\t * Random variation +/-0.01s to the scheduled time. \n\t\t * Or give it a time value which it will randomize by.\n\t\t * @type {Boolean|Time}\n\t\t * @memberOf Tone.Loop#\n\t\t * @name humanize\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'humanize', {\n\t get: function () {\n\t return this._event.humanize;\n\t },\n\t set: function (variation) {\n\t this._event.humanize = variation;\n\t }\n\t });\n\t /**\n\t\t * The probably of the callback being invoked.\n\t\t * @memberOf Tone.Loop#\n\t\t * @type {NormalRange}\n\t\t * @name probability\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'probability', {\n\t get: function () {\n\t return this._event.probability;\n\t },\n\t set: function (prob) {\n\t this._event.probability = prob;\n\t }\n\t });\n\t /**\n\t\t * Muting the Loop means that no callbacks are invoked.\n\t\t * @memberOf Tone.Loop#\n\t\t * @type {Boolean}\n\t\t * @name mute\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'mute', {\n\t get: function () {\n\t return this._event.mute;\n\t },\n\t set: function (mute) {\n\t this._event.mute = mute;\n\t }\n\t });\n\t /**\n\t\t * The number of iterations of the loop. The default\n\t\t * value is Infinity (loop forever).\n\t\t * @memberOf Tone.Loop#\n\t\t * @type {Positive}\n\t\t * @name iterations\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'iterations', {\n\t get: function () {\n\t if (this._event.loop === true) {\n\t return Infinity;\n\t } else {\n\t return this._event.loop;\n\t }\n\t },\n\t set: function (iters) {\n\t if (iters === Infinity) {\n\t this._event.loop = true;\n\t } else {\n\t this._event.loop = iters;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Loop} this\n\t\t */\n\t Tone.Loop.prototype.dispose = function () {\n\t this._event.dispose();\n\t this._event = null;\n\t this.callback = null;\n\t };\n\t return Tone.Loop;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Part is a collection Tone.Events which can be\n\t\t * started/stopped and looped as a single unit.\n\t\t *\n\t\t * @extends {Tone.Event}\n\t\t * @param {Function} callback The callback to invoke on each event\n\t\t * @param {Array} events the array of events\n\t\t * @example\n\t\t * var part = new Tone.Part(function(time, note){\n\t\t * \t//the notes given as the second element in the array\n\t\t * \t//will be passed in as the second argument\n\t\t * \tsynth.triggerAttackRelease(note, \"8n\", time);\n\t\t * }, [[0, \"C2\"], [\"0:2\", \"C3\"], [\"0:3:2\", \"G2\"]]);\n\t\t * @example\n\t\t * //use an array of objects as long as the object has a \"time\" attribute\n\t\t * var part = new Tone.Part(function(time, value){\n\t\t * \t//the value is an object which contains both the note and the velocity\n\t\t * \tsynth.triggerAttackRelease(value.note, \"8n\", time, value.velocity);\n\t\t * }, [{\"time\" : 0, \"note\" : \"C3\", \"velocity\": 0.9},\n\t\t * \t {\"time\" : \"0:2\", \"note\" : \"C4\", \"velocity\": 0.5}\n\t\t * ]).start(0);\n\t\t */\n\t Tone.Part = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'callback',\n\t 'events'\n\t ], Tone.Part);\n\t Tone.Event.call(this, options);\n\t /**\n\t\t\t * An array of Objects.\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._events = [];\n\t //add the events\n\t for (var i = 0; i < options.events.length; i++) {\n\t if (Array.isArray(options.events[i])) {\n\t this.add(options.events[i][0], options.events[i][1]);\n\t } else {\n\t this.add(options.events[i]);\n\t }\n\t }\n\t };\n\t Tone.extend(Tone.Part, Tone.Event);\n\t /**\n\t\t * The default values\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Part.defaults = {\n\t 'callback': Tone.noOp,\n\t 'loop': false,\n\t 'loopEnd': '1m',\n\t 'loopStart': 0,\n\t 'playbackRate': 1,\n\t 'probability': 1,\n\t 'humanize': false,\n\t 'mute': false,\n\t 'events': []\n\t };\n\t /**\n\t\t * Start the part at the given time.\n\t\t * @param {TransportTime} time When to start the part.\n\t\t * @param {Time=} offset The offset from the start of the part\n\t\t * to begin playing at.\n\t\t * @return {Tone.Part} this\n\t\t */\n\t Tone.Part.prototype.start = function (time, offset) {\n\t var ticks = this.toTicks(time);\n\t if (this._state.getValueAtTime(ticks) !== Tone.State.Started) {\n\t if (this._loop) {\n\t offset = Tone.defaultArg(offset, this._loopStart);\n\t } else {\n\t offset = Tone.defaultArg(offset, 0);\n\t }\n\t offset = this.toTicks(offset);\n\t this._state.add({\n\t 'state': Tone.State.Started,\n\t 'time': ticks,\n\t 'offset': offset\n\t });\n\t this._forEach(function (event) {\n\t this._startNote(event, ticks, offset);\n\t });\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Start the event in the given event at the correct time given\n\t\t * the ticks and offset and looping.\n\t\t * @param {Tone.Event} event\n\t\t * @param {Ticks} ticks\n\t\t * @param {Ticks} offset\n\t\t * @private\n\t\t */\n\t Tone.Part.prototype._startNote = function (event, ticks, offset) {\n\t ticks -= offset;\n\t if (this._loop) {\n\t if (event.startOffset >= this._loopStart && event.startOffset < this._loopEnd) {\n\t if (event.startOffset < offset) {\n\t //start it on the next loop\n\t ticks += this._getLoopDuration();\n\t }\n\t event.start(Tone.Ticks(ticks));\n\t } else if (event.startOffset < this._loopStart && event.startOffset >= offset) {\n\t event.loop = false;\n\t event.start(Tone.Ticks(ticks));\n\t }\n\t } else if (event.startOffset >= offset) {\n\t event.start(Tone.Ticks(ticks));\n\t }\n\t };\n\t /**\n\t\t * The start from the scheduled start time\n\t\t * @type {Ticks}\n\t\t * @memberOf Tone.Part#\n\t\t * @name startOffset\n\t\t * @private\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'startOffset', {\n\t get: function () {\n\t return this._startOffset;\n\t },\n\t set: function (offset) {\n\t this._startOffset = offset;\n\t this._forEach(function (event) {\n\t event.startOffset += this._startOffset;\n\t });\n\t }\n\t });\n\t /**\n\t\t * Stop the part at the given time.\n\t\t * @param {TimelinePosition} time When to stop the part.\n\t\t * @return {Tone.Part} this\n\t\t */\n\t Tone.Part.prototype.stop = function (time) {\n\t var ticks = this.toTicks(time);\n\t this._state.cancel(ticks);\n\t this._state.setStateAtTime(Tone.State.Stopped, ticks);\n\t this._forEach(function (event) {\n\t event.stop(time);\n\t });\n\t return this;\n\t };\n\t /**\n\t\t * Get/Set an Event's value at the given time.\n\t\t * If a value is passed in and no event exists at\n\t\t * the given time, one will be created with that value.\n\t\t * If two events are at the same time, the first one will\n\t\t * be returned.\n\t\t * @example\n\t\t * part.at(\"1m\"); //returns the part at the first measure\n\t\t *\n\t\t * part.at(\"2m\", \"C2\"); //set the value at \"2m\" to C2.\n\t\t * //if an event didn't exist at that time, it will be created.\n\t\t * @param {TransportTime} time The time of the event to get or set.\n\t\t * @param {*=} value If a value is passed in, the value of the\n\t\t * event at the given time will be set to it.\n\t\t * @return {Tone.Event} the event at the time\n\t\t */\n\t Tone.Part.prototype.at = function (time, value) {\n\t time = Tone.TransportTime(time);\n\t var tickTime = Tone.Ticks(1).toSeconds();\n\t for (var i = 0; i < this._events.length; i++) {\n\t var event = this._events[i];\n\t if (Math.abs(time.toTicks() - event.startOffset) < tickTime) {\n\t if (Tone.isDefined(value)) {\n\t event.value = value;\n\t }\n\t return event;\n\t }\n\t }\n\t //if there was no event at that time, create one\n\t if (Tone.isDefined(value)) {\n\t this.add(time, value);\n\t //return the new event\n\t return this._events[this._events.length - 1];\n\t } else {\n\t return null;\n\t }\n\t };\n\t /**\n\t\t * Add a an event to the part.\n\t\t * @param {Time} time The time the note should start.\n\t\t * If an object is passed in, it should\n\t\t * have a 'time' attribute and the rest\n\t\t * of the object will be used as the 'value'.\n\t\t * @param {Tone.Event|*} value\n\t\t * @returns {Tone.Part} this\n\t\t * @example\n\t\t * part.add(\"1m\", \"C#+11\");\n\t\t */\n\t Tone.Part.prototype.add = function (time, value) {\n\t //extract the parameters\n\t if (time.hasOwnProperty('time')) {\n\t value = time;\n\t time = value.time;\n\t }\n\t time = this.toTicks(time);\n\t var event;\n\t if (value instanceof Tone.Event) {\n\t event = value;\n\t event.callback = this._tick.bind(this);\n\t } else {\n\t event = new Tone.Event({\n\t 'callback': this._tick.bind(this),\n\t 'value': value\n\t });\n\t }\n\t //the start offset\n\t event.startOffset = time;\n\t //initialize the values\n\t event.set({\n\t 'loopEnd': this.loopEnd,\n\t 'loopStart': this.loopStart,\n\t 'loop': this.loop,\n\t 'humanize': this.humanize,\n\t 'playbackRate': this.playbackRate,\n\t 'probability': this.probability\n\t });\n\t this._events.push(event);\n\t //start the note if it should be played right now\n\t this._restartEvent(event);\n\t return this;\n\t };\n\t /**\n\t\t * Restart the given event\n\t\t * @param {Tone.Event} event\n\t\t * @private\n\t\t */\n\t Tone.Part.prototype._restartEvent = function (event) {\n\t this._state.forEach(function (stateEvent) {\n\t if (stateEvent.state === Tone.State.Started) {\n\t this._startNote(event, stateEvent.time, stateEvent.offset);\n\t } else {\n\t //stop the note\n\t event.stop(Tone.Ticks(stateEvent.time));\n\t }\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Remove an event from the part. Will recursively iterate\n\t\t * into nested parts to find the event.\n\t\t * @param {Time} time The time of the event\n\t\t * @param {*} value Optionally select only a specific event value\n\t\t * @return {Tone.Part} this\n\t\t */\n\t Tone.Part.prototype.remove = function (time, value) {\n\t //extract the parameters\n\t if (time.hasOwnProperty('time')) {\n\t value = time;\n\t time = value.time;\n\t }\n\t time = this.toTicks(time);\n\t for (var i = this._events.length - 1; i >= 0; i--) {\n\t var event = this._events[i];\n\t if (event instanceof Tone.Part) {\n\t event.remove(time, value);\n\t } else if (event.startOffset === time) {\n\t if (Tone.isUndef(value) || Tone.isDefined(value) && event.value === value) {\n\t this._events.splice(i, 1);\n\t event.dispose();\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Remove all of the notes from the group.\n\t\t * @return {Tone.Part} this\n\t\t */\n\t Tone.Part.prototype.removeAll = function () {\n\t this._forEach(function (event) {\n\t event.dispose();\n\t });\n\t this._events = [];\n\t return this;\n\t };\n\t /**\n\t\t * Cancel scheduled state change events: i.e. \"start\" and \"stop\".\n\t\t * @param {TimelinePosition} after The time after which to cancel the scheduled events.\n\t\t * @return {Tone.Part} this\n\t\t */\n\t Tone.Part.prototype.cancel = function (after) {\n\t this._forEach(function (event) {\n\t event.cancel(after);\n\t });\n\t this._state.cancel(this.toTicks(after));\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over all of the events\n\t\t * @param {Function} callback\n\t\t * @param {Object} ctx The context\n\t\t * @private\n\t\t */\n\t Tone.Part.prototype._forEach = function (callback, ctx) {\n\t if (this._events) {\n\t ctx = Tone.defaultArg(ctx, this);\n\t for (var i = this._events.length - 1; i >= 0; i--) {\n\t var e = this._events[i];\n\t if (e instanceof Tone.Part) {\n\t e._forEach(callback, ctx);\n\t } else {\n\t callback.call(ctx, e);\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Set the attribute of all of the events\n\t\t * @param {String} attr the attribute to set\n\t\t * @param {*} value The value to set it to\n\t\t * @private\n\t\t */\n\t Tone.Part.prototype._setAll = function (attr, value) {\n\t this._forEach(function (event) {\n\t event[attr] = value;\n\t });\n\t };\n\t /**\n\t\t * Internal tick method\n\t\t * @param {Number} time The time of the event in seconds\n\t\t * @private\n\t\t */\n\t Tone.Part.prototype._tick = function (time, value) {\n\t if (!this.mute) {\n\t this.callback(time, value);\n\t }\n\t };\n\t /**\n\t\t * Determine if the event should be currently looping\n\t\t * given the loop boundries of this Part.\n\t\t * @param {Tone.Event} event The event to test\n\t\t * @private\n\t\t */\n\t Tone.Part.prototype._testLoopBoundries = function (event) {\n\t if (event.startOffset < this._loopStart || event.startOffset >= this._loopEnd) {\n\t event.cancel(0);\n\t } else if (event.state === Tone.State.Stopped) {\n\t //reschedule it if it's stopped\n\t this._restartEvent(event);\n\t }\n\t };\n\t /**\n\t\t * The probability of the notes being triggered.\n\t\t * @memberOf Tone.Part#\n\t\t * @type {NormalRange}\n\t\t * @name probability\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'probability', {\n\t get: function () {\n\t return this._probability;\n\t },\n\t set: function (prob) {\n\t this._probability = prob;\n\t this._setAll('probability', prob);\n\t }\n\t });\n\t /**\n\t\t * If set to true, will apply small random variation\n\t\t * to the callback time. If the value is given as a time, it will randomize\n\t\t * by that amount.\n\t\t * @example\n\t\t * event.humanize = true;\n\t\t * @type {Boolean|Time}\n\t\t * @name humanize\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'humanize', {\n\t get: function () {\n\t return this._humanize;\n\t },\n\t set: function (variation) {\n\t this._humanize = variation;\n\t this._setAll('humanize', variation);\n\t }\n\t });\n\t /**\n\t\t * If the part should loop or not\n\t\t * between Tone.Part.loopStart and\n\t\t * Tone.Part.loopEnd. An integer\n\t\t * value corresponds to the number of\n\t\t * loops the Part does after it starts.\n\t\t * @memberOf Tone.Part#\n\t\t * @type {Boolean|Positive}\n\t\t * @name loop\n\t\t * @example\n\t\t * //loop the part 8 times\n\t\t * part.loop = 8;\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'loop', {\n\t get: function () {\n\t return this._loop;\n\t },\n\t set: function (loop) {\n\t this._loop = loop;\n\t this._forEach(function (event) {\n\t event._loopStart = this._loopStart;\n\t event._loopEnd = this._loopEnd;\n\t event.loop = loop;\n\t this._testLoopBoundries(event);\n\t });\n\t }\n\t });\n\t /**\n\t\t * The loopEnd point determines when it will\n\t\t * loop if Tone.Part.loop is true.\n\t\t * @memberOf Tone.Part#\n\t\t * @type {Time}\n\t\t * @name loopEnd\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'loopEnd', {\n\t get: function () {\n\t return Tone.Ticks(this._loopEnd).toSeconds();\n\t },\n\t set: function (loopEnd) {\n\t this._loopEnd = this.toTicks(loopEnd);\n\t if (this._loop) {\n\t this._forEach(function (event) {\n\t event.loopEnd = loopEnd;\n\t this._testLoopBoundries(event);\n\t });\n\t }\n\t }\n\t });\n\t /**\n\t\t * The loopStart point determines when it will\n\t\t * loop if Tone.Part.loop is true.\n\t\t * @memberOf Tone.Part#\n\t\t * @type {Time}\n\t\t * @name loopStart\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'loopStart', {\n\t get: function () {\n\t return Tone.Ticks(this._loopStart).toSeconds();\n\t },\n\t set: function (loopStart) {\n\t this._loopStart = this.toTicks(loopStart);\n\t if (this._loop) {\n\t this._forEach(function (event) {\n\t event.loopStart = this.loopStart;\n\t this._testLoopBoundries(event);\n\t });\n\t }\n\t }\n\t });\n\t /**\n\t\t * \tThe playback rate of the part\n\t\t * @memberOf Tone.Part#\n\t\t * @type {Positive}\n\t\t * @name playbackRate\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'playbackRate', {\n\t get: function () {\n\t return this._playbackRate;\n\t },\n\t set: function (rate) {\n\t this._playbackRate = rate;\n\t this._setAll('playbackRate', rate);\n\t }\n\t });\n\t /**\n\t\t * \tThe number of scheduled notes in the part.\n\t\t * @memberOf Tone.Part#\n\t\t * @type {Positive}\n\t\t * @name length\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'length', {\n\t get: function () {\n\t return this._events.length;\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Part} this\n\t\t */\n\t Tone.Part.prototype.dispose = function () {\n\t this.removeAll();\n\t this._state.dispose();\n\t this._state = null;\n\t this.callback = null;\n\t this._events = null;\n\t return this;\n\t };\n\t return Tone.Part;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Pattern arpeggiates between the given notes\n\t\t * in a number of patterns. See Tone.CtrlPattern for\n\t\t * a full list of patterns.\n\t\t * @example\n\t\t * var pattern = new Tone.Pattern(function(time, note){\n\t\t * //the order of the notes passed in depends on the pattern\n\t\t * }, [\"C2\", \"D4\", \"E5\", \"A6\"], \"upDown\");\n\t\t * @extends {Tone.Loop}\n\t\t * @param {Function} callback The callback to invoke with the\n\t\t * event.\n\t\t * @param {Array} values The values to arpeggiate over.\n\t\t */\n\t Tone.Pattern = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'callback',\n\t 'values',\n\t 'pattern'\n\t ], Tone.Pattern);\n\t Tone.Loop.call(this, options);\n\t /**\n\t\t\t * The pattern manager\n\t\t\t * @type {Tone.CtrlPattern}\n\t\t\t * @private\n\t\t\t */\n\t this._pattern = new Tone.CtrlPattern({\n\t 'values': options.values,\n\t 'type': options.pattern,\n\t 'index': options.index\n\t });\n\t };\n\t Tone.extend(Tone.Pattern, Tone.Loop);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Pattern.defaults = {\n\t 'pattern': Tone.CtrlPattern.Type.Up,\n\t 'callback': Tone.noOp,\n\t 'values': []\n\t };\n\t /**\n\t\t * Internal function called when the notes should be called\n\t\t * @param {Number} time The time the event occurs\n\t\t * @private\n\t\t */\n\t Tone.Pattern.prototype._tick = function (time) {\n\t this.callback(time, this._pattern.value);\n\t this._pattern.next();\n\t };\n\t /**\n\t\t * The current index in the values array.\n\t\t * @memberOf Tone.Pattern#\n\t\t * @type {Positive}\n\t\t * @name index\n\t\t */\n\t Object.defineProperty(Tone.Pattern.prototype, 'index', {\n\t get: function () {\n\t return this._pattern.index;\n\t },\n\t set: function (i) {\n\t this._pattern.index = i;\n\t }\n\t });\n\t /**\n\t\t * The array of events.\n\t\t * @memberOf Tone.Pattern#\n\t\t * @type {Array}\n\t\t * @name values\n\t\t */\n\t Object.defineProperty(Tone.Pattern.prototype, 'values', {\n\t get: function () {\n\t return this._pattern.values;\n\t },\n\t set: function (vals) {\n\t this._pattern.values = vals;\n\t }\n\t });\n\t /**\n\t\t * The current value of the pattern.\n\t\t * @memberOf Tone.Pattern#\n\t\t * @type {*}\n\t\t * @name value\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Pattern.prototype, 'value', {\n\t get: function () {\n\t return this._pattern.value;\n\t }\n\t });\n\t /**\n\t\t * The pattern type. See Tone.CtrlPattern for the full list of patterns.\n\t\t * @memberOf Tone.Pattern#\n\t\t * @type {String}\n\t\t * @name pattern\n\t\t */\n\t Object.defineProperty(Tone.Pattern.prototype, 'pattern', {\n\t get: function () {\n\t return this._pattern.type;\n\t },\n\t set: function (pattern) {\n\t this._pattern.type = pattern;\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Pattern} this\n\t\t */\n\t Tone.Pattern.prototype.dispose = function () {\n\t Tone.Loop.prototype.dispose.call(this);\n\t this._pattern.dispose();\n\t this._pattern = null;\n\t };\n\t return Tone.Pattern;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A sequence is an alternate notation of a part. Instead\n\t\t * of passing in an array of [time, event] pairs, pass\n\t\t * in an array of events which will be spaced at the\n\t\t * given subdivision. Sub-arrays will subdivide that beat\n\t\t * by the number of items are in the array.\n\t\t * Sequence notation inspiration from [Tidal](http://yaxu.org/tidal/)\n\t\t * @param {Function} callback The callback to invoke with every note\n\t\t * @param {Array} events The sequence\n\t\t * @param {Time} subdivision The subdivision between which events are placed.\n\t\t * @extends {Tone.Part}\n\t\t * @example\n\t\t * var seq = new Tone.Sequence(function(time, note){\n\t\t * \tconsole.log(note);\n\t\t * //straight quater notes\n\t\t * }, [\"C4\", \"E4\", \"G4\", \"A4\"], \"4n\");\n\t\t * @example\n\t\t * var seq = new Tone.Sequence(function(time, note){\n\t\t * \tconsole.log(note);\n\t\t * //subdivisions are given as subarrays\n\t\t * }, [\"C4\", [\"E4\", \"D4\", \"E4\"], \"G4\", [\"A4\", \"G4\"]]);\n\t\t */\n\t Tone.Sequence = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'callback',\n\t 'events',\n\t 'subdivision'\n\t ], Tone.Sequence);\n\t //remove the events\n\t var events = options.events;\n\t delete options.events;\n\t Tone.Part.call(this, options);\n\t /**\n\t\t\t * The subdivison of each note\n\t\t\t * @type {Ticks}\n\t\t\t * @private\n\t\t\t */\n\t this._subdivision = this.toTicks(options.subdivision);\n\t //if no time was passed in, the loop end is the end of the cycle\n\t if (Tone.isUndef(options.loopEnd) && Tone.isDefined(events)) {\n\t this._loopEnd = events.length * this._subdivision;\n\t }\n\t //defaults to looping\n\t this._loop = true;\n\t //add all of the events\n\t if (Tone.isDefined(events)) {\n\t for (var i = 0; i < events.length; i++) {\n\t this.add(i, events[i]);\n\t }\n\t }\n\t };\n\t Tone.extend(Tone.Sequence, Tone.Part);\n\t /**\n\t\t * The default values.\n\t\t * @type {Object}\n\t\t */\n\t Tone.Sequence.defaults = { 'subdivision': '4n' };\n\t /**\n\t\t * The subdivision of the sequence. This can only be\n\t\t * set in the constructor. The subdivision is the\n\t\t * interval between successive steps.\n\t\t * @type {Time}\n\t\t * @memberOf Tone.Sequence#\n\t\t * @name subdivision\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Sequence.prototype, 'subdivision', {\n\t get: function () {\n\t return Tone.Ticks(this._subdivision).toSeconds();\n\t }\n\t });\n\t /**\n\t\t * Get/Set an index of the sequence. If the index contains a subarray,\n\t\t * a Tone.Sequence representing that sub-array will be returned.\n\t\t * @example\n\t\t * var sequence = new Tone.Sequence(playNote, [\"E4\", \"C4\", \"F#4\", [\"A4\", \"Bb3\"]])\n\t\t * sequence.at(0)// => returns \"E4\"\n\t\t * //set a value\n\t\t * sequence.at(0, \"G3\");\n\t\t * //get a nested sequence\n\t\t * sequence.at(3).at(1)// => returns \"Bb3\"\n\t\t * @param {Positive} index The index to get or set\n\t\t * @param {*} value Optionally pass in the value to set at the given index.\n\t\t */\n\t Tone.Sequence.prototype.at = function (index, value) {\n\t //if the value is an array,\n\t if (Tone.isArray(value)) {\n\t //remove the current event at that index\n\t this.remove(index);\n\t }\n\t //call the parent's method\n\t return Tone.Part.prototype.at.call(this, this._indexTime(index), value);\n\t };\n\t /**\n\t\t * Add an event at an index, if there's already something\n\t\t * at that index, overwrite it. If `value` is an array,\n\t\t * it will be parsed as a subsequence.\n\t\t * @param {Number} index The index to add the event to\n\t\t * @param {*} value The value to add at that index\n\t\t * @returns {Tone.Sequence} this\n\t\t */\n\t Tone.Sequence.prototype.add = function (index, value) {\n\t if (value === null) {\n\t return this;\n\t }\n\t if (Tone.isArray(value)) {\n\t //make a subsequence and add that to the sequence\n\t var subSubdivision = Math.round(this._subdivision / value.length);\n\t value = new Tone.Sequence(this._tick.bind(this), value, Tone.Ticks(subSubdivision));\n\t }\n\t Tone.Part.prototype.add.call(this, this._indexTime(index), value);\n\t return this;\n\t };\n\t /**\n\t\t * Remove a value from the sequence by index\n\t\t * @param {Number} index The index of the event to remove\n\t\t * @returns {Tone.Sequence} this\n\t\t */\n\t Tone.Sequence.prototype.remove = function (index, value) {\n\t Tone.Part.prototype.remove.call(this, this._indexTime(index), value);\n\t return this;\n\t };\n\t /**\n\t\t * Get the time of the index given the Sequence's subdivision\n\t\t * @param {Number} index\n\t\t * @return {Time} The time of that index\n\t\t * @private\n\t\t */\n\t Tone.Sequence.prototype._indexTime = function (index) {\n\t if (index instanceof Tone.TransportTime) {\n\t return index;\n\t } else {\n\t return Tone.Ticks(index * this._subdivision + this.startOffset).toSeconds();\n\t }\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Sequence} this\n\t\t */\n\t Tone.Sequence.prototype.dispose = function () {\n\t Tone.Part.prototype.dispose.call(this);\n\t return this;\n\t };\n\t return Tone.Sequence;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.PulseOscillator is a pulse oscillator with control over pulse width,\n\t\t * also known as the duty cycle. At 50% duty cycle (width = 0.5) the wave is\n\t\t * a square and only odd-numbered harmonics are present. At all other widths\n\t\t * even-numbered harmonics are present. Read more\n\t\t * [here](https://wigglewave.wordpress.com/2014/08/16/pulse-waveforms-and-harmonics/).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Source}\n\t\t * @param {Frequency} [frequency] The frequency of the oscillator\n\t\t * @param {NormalRange} [width] The width of the pulse\n\t\t * @example\n\t\t * var pulse = new Tone.PulseOscillator(\"E5\", 0.4).toMaster().start();\n\t\t */\n\t Tone.PulseOscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'width'\n\t ], Tone.Oscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * The width of the pulse.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.width = new Tone.Signal(options.width, Tone.Type.NormalRange);\n\t /**\n\t\t\t * gate the width amount\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._widthGate = new Tone.Gain();\n\t /**\n\t\t\t * the sawtooth oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._sawtooth = new Tone.Oscillator({\n\t frequency: options.frequency,\n\t detune: options.detune,\n\t type: 'sawtooth',\n\t phase: options.phase\n\t });\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._sawtooth.frequency;\n\t /**\n\t\t\t * The detune in cents.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = this._sawtooth.detune;\n\t /**\n\t\t\t * Threshold the signal to turn it into a square\n\t\t\t * @type {Tone.WaveShaper}\n\t\t\t * @private\n\t\t\t */\n\t this._thresh = new Tone.WaveShaper(function (val) {\n\t if (val < 0) {\n\t return -1;\n\t } else {\n\t return 1;\n\t }\n\t });\n\t //connections\n\t this._sawtooth.chain(this._thresh, this.output);\n\t this.width.chain(this._widthGate, this._thresh);\n\t this._readOnly([\n\t 'width',\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t };\n\t Tone.extend(Tone.PulseOscillator, Tone.Source);\n\t /**\n\t\t * The default parameters.\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.PulseOscillator.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'phase': 0,\n\t 'width': 0.2\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} time\n\t\t * @private\n\t\t */\n\t Tone.PulseOscillator.prototype._start = function (time) {\n\t time = this.toSeconds(time);\n\t this._sawtooth.start(time);\n\t this._widthGate.gain.setValueAtTime(1, time);\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @param {Time} time\n\t\t * @private\n\t\t */\n\t Tone.PulseOscillator.prototype._stop = function (time) {\n\t time = this.toSeconds(time);\n\t this._sawtooth.stop(time);\n\t //the width is still connected to the output.\n\t //that needs to be stopped also\n\t this._widthGate.gain.setValueAtTime(0, time);\n\t };\n\t /**\n\t\t * restart the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.PulseOscillator.prototype.restart = function (time) {\n\t this._sawtooth.restart(time);\n\t };\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.PulseOscillator#\n\t\t * @type {Degrees}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.PulseOscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._sawtooth.phase;\n\t },\n\t set: function (phase) {\n\t this._sawtooth.phase = phase;\n\t }\n\t });\n\t /**\n\t\t * The type of the oscillator. Always returns \"pulse\".\n\t\t * @readOnly\n\t\t * @memberOf Tone.PulseOscillator#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.PulseOscillator.prototype, 'type', {\n\t get: function () {\n\t return 'pulse';\n\t }\n\t });\n\t /**\n\t\t * The partials of the waveform. Cannot set partials for this waveform type\n\t\t * @memberOf Tone.PulseOscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @private\n\t\t */\n\t Object.defineProperty(Tone.PulseOscillator.prototype, 'partials', {\n\t get: function () {\n\t return [];\n\t }\n\t });\n\t /**\n\t\t * Clean up method.\n\t\t * @return {Tone.PulseOscillator} this\n\t\t */\n\t Tone.PulseOscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this._sawtooth.dispose();\n\t this._sawtooth = null;\n\t this._writable([\n\t 'width',\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t this.width.dispose();\n\t this.width = null;\n\t this._widthGate.dispose();\n\t this._widthGate = null;\n\t this._thresh.dispose();\n\t this._thresh = null;\n\t this.frequency = null;\n\t this.detune = null;\n\t return this;\n\t };\n\t return Tone.PulseOscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.PWMOscillator modulates the width of a Tone.PulseOscillator\n\t\t * at the modulationFrequency. This has the effect of continuously\n\t\t * changing the timbre of the oscillator by altering the harmonics\n\t\t * generated.\n\t\t *\n\t\t * @extends {Tone.Source}\n\t\t * @constructor\n\t\t * @param {Frequency} frequency The starting frequency of the oscillator.\n\t\t * @param {Frequency} modulationFrequency The modulation frequency of the width of the pulse.\n\t\t * @example\n\t\t * var pwm = new Tone.PWMOscillator(\"Ab3\", 0.3).toMaster().start();\n\t\t */\n\t Tone.PWMOscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'modulationFrequency'\n\t ], Tone.PWMOscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * the pulse oscillator\n\t\t\t * @type {Tone.PulseOscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._pulse = new Tone.PulseOscillator(options.modulationFrequency);\n\t //change the pulse oscillator type\n\t this._pulse._sawtooth.type = 'sine';\n\t /**\n\t\t\t * the modulator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._modulator = new Tone.Oscillator({\n\t 'frequency': options.frequency,\n\t 'detune': options.detune,\n\t 'phase': options.phase\n\t });\n\t /**\n\t\t\t * Scale the oscillator so it doesn't go silent\n\t\t\t * at the extreme values.\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._scale = new Tone.Multiply(2);\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._modulator.frequency;\n\t /**\n\t\t\t * The detune of the oscillator.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = this._modulator.detune;\n\t /**\n\t\t\t * The modulation rate of the oscillator.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.modulationFrequency = this._pulse.frequency;\n\t //connections\n\t this._modulator.chain(this._scale, this._pulse.width);\n\t this._pulse.connect(this.output);\n\t this._readOnly([\n\t 'modulationFrequency',\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t };\n\t Tone.extend(Tone.PWMOscillator, Tone.Source);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.PWMOscillator.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'phase': 0,\n\t 'modulationFrequency': 0.4\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now]\n\t\t * @private\n\t\t */\n\t Tone.PWMOscillator.prototype._start = function (time) {\n\t time = this.toSeconds(time);\n\t this._modulator.start(time);\n\t this._pulse.start(time);\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.PWMOscillator.prototype._stop = function (time) {\n\t time = this.toSeconds(time);\n\t this._modulator.stop(time);\n\t this._pulse.stop(time);\n\t };\n\t /**\n\t\t * restart the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.PWMOscillator.prototype.restart = function (time) {\n\t this._modulator.restart(time);\n\t this._pulse.restart(time);\n\t };\n\t /**\n\t\t * The type of the oscillator. Always returns \"pwm\".\n\t\t * @readOnly\n\t\t * @memberOf Tone.PWMOscillator#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.PWMOscillator.prototype, 'type', {\n\t get: function () {\n\t return 'pwm';\n\t }\n\t });\n\t /**\n\t\t * The partials of the waveform. Cannot set partials for this waveform type\n\t\t * @memberOf Tone.PWMOscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @private\n\t\t */\n\t Object.defineProperty(Tone.PWMOscillator.prototype, 'partials', {\n\t get: function () {\n\t return [];\n\t }\n\t });\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.PWMOscillator#\n\t\t * @type {number}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.PWMOscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._modulator.phase;\n\t },\n\t set: function (phase) {\n\t this._modulator.phase = phase;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.PWMOscillator} this\n\t\t */\n\t Tone.PWMOscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this._pulse.dispose();\n\t this._pulse = null;\n\t this._scale.dispose();\n\t this._scale = null;\n\t this._modulator.dispose();\n\t this._modulator = null;\n\t this._writable([\n\t 'modulationFrequency',\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t this.frequency = null;\n\t this.detune = null;\n\t this.modulationFrequency = null;\n\t return this;\n\t };\n\t return Tone.PWMOscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.FMOscillator\n\t\t *\n\t\t * @extends {Tone.Source}\n\t\t * @constructor\n\t\t * @param {Frequency} frequency The starting frequency of the oscillator.\n\t\t * @param {String} type The type of the carrier oscillator.\n\t\t * @param {String} modulationType The type of the modulator oscillator.\n\t\t * @example\n\t\t * //a sine oscillator frequency-modulated by a square wave\n\t\t * var fmOsc = new Tone.FMOscillator(\"Ab3\", \"sine\", \"square\").toMaster().start();\n\t\t */\n\t Tone.FMOscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type',\n\t 'modulationType'\n\t ], Tone.FMOscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * The carrier oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._carrier = new Tone.Oscillator(options.frequency, options.type);\n\t /**\n\t\t\t * The oscillator's frequency\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune control signal.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = this._carrier.detune;\n\t this.detune.value = options.detune;\n\t /**\n\t\t\t * The modulation index which is in essence the depth or amount of the modulation. In other terms it is the\n\t\t\t * ratio of the frequency of the modulating signal (mf) to the amplitude of the\n\t\t\t * modulating signal (ma) -- as in ma/mf.\n\t\t\t *\t@type {Positive}\n\t\t\t *\t@signal\n\t\t\t */\n\t this.modulationIndex = new Tone.Multiply(options.modulationIndex);\n\t this.modulationIndex.units = Tone.Type.Positive;\n\t /**\n\t\t\t * The modulating oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._modulator = new Tone.Oscillator(options.frequency, options.modulationType);\n\t /**\n\t\t\t * Harmonicity is the frequency ratio between the carrier and the modulator oscillators.\n\t\t\t * A harmonicity of 1 gives both oscillators the same frequency.\n\t\t\t * Harmonicity = 2 means a change of an octave.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * //pitch the modulator an octave below carrier\n\t\t\t * synth.harmonicity.value = 0.5;\n\t\t\t */\n\t this.harmonicity = new Tone.Multiply(options.harmonicity);\n\t this.harmonicity.units = Tone.Type.Positive;\n\t /**\n\t\t\t * the node where the modulation happens\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._modulationNode = new Tone.Gain(0);\n\t //connections\n\t this.frequency.connect(this._carrier.frequency);\n\t this.frequency.chain(this.harmonicity, this._modulator.frequency);\n\t this.frequency.chain(this.modulationIndex, this._modulationNode);\n\t this._modulator.connect(this._modulationNode.gain);\n\t this._modulationNode.connect(this._carrier.frequency);\n\t this._carrier.connect(this.output);\n\t this.detune.connect(this._modulator.detune);\n\t this.phase = options.phase;\n\t this._readOnly([\n\t 'modulationIndex',\n\t 'frequency',\n\t 'detune',\n\t 'harmonicity'\n\t ]);\n\t };\n\t Tone.extend(Tone.FMOscillator, Tone.Source);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.FMOscillator.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'phase': 0,\n\t 'modulationIndex': 2,\n\t 'modulationType': 'square',\n\t 'harmonicity': 1\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now]\n\t\t * @private\n\t\t */\n\t Tone.FMOscillator.prototype._start = function (time) {\n\t this._modulator.start(time);\n\t this._carrier.start(time);\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.FMOscillator.prototype._stop = function (time) {\n\t this._modulator.stop(time);\n\t this._carrier.stop(time);\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.FMOscillator.prototype.restart = function (time) {\n\t this._modulator.restart(time);\n\t this._carrier.restart(time);\n\t };\n\t /**\n\t\t * The type of the carrier oscillator\n\t\t * @memberOf Tone.FMOscillator#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.FMOscillator.prototype, 'type', {\n\t get: function () {\n\t return this._carrier.type;\n\t },\n\t set: function (type) {\n\t this._carrier.type = type;\n\t }\n\t });\n\t /**\n\t\t * The type of the modulator oscillator\n\t\t * @memberOf Tone.FMOscillator#\n\t\t * @type {String}\n\t\t * @name modulationType\n\t\t */\n\t Object.defineProperty(Tone.FMOscillator.prototype, 'modulationType', {\n\t get: function () {\n\t return this._modulator.type;\n\t },\n\t set: function (type) {\n\t this._modulator.type = type;\n\t }\n\t });\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.FMOscillator#\n\t\t * @type {number}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.FMOscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._carrier.phase;\n\t },\n\t set: function (phase) {\n\t this._carrier.phase = phase;\n\t this._modulator.phase = phase;\n\t }\n\t });\n\t /**\n\t\t * The partials of the carrier waveform. A partial represents\n\t\t * the amplitude at a harmonic. The first harmonic is the\n\t\t * fundamental frequency, the second is the octave and so on\n\t\t * following the harmonic series.\n\t\t * Setting this value will automatically set the type to \"custom\".\n\t\t * The value is an empty array when the type is not \"custom\".\n\t\t * @memberOf Tone.FMOscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @example\n\t\t * osc.partials = [1, 0.2, 0.01];\n\t\t */\n\t Object.defineProperty(Tone.FMOscillator.prototype, 'partials', {\n\t get: function () {\n\t return this._carrier.partials;\n\t },\n\t set: function (partials) {\n\t this._carrier.partials = partials;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.FMOscillator} this\n\t\t */\n\t Tone.FMOscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this._writable([\n\t 'modulationIndex',\n\t 'frequency',\n\t 'detune',\n\t 'harmonicity'\n\t ]);\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this.detune = null;\n\t this.harmonicity.dispose();\n\t this.harmonicity = null;\n\t this._carrier.dispose();\n\t this._carrier = null;\n\t this._modulator.dispose();\n\t this._modulator = null;\n\t this._modulationNode.dispose();\n\t this._modulationNode = null;\n\t this.modulationIndex.dispose();\n\t this.modulationIndex = null;\n\t return this;\n\t };\n\t return Tone.FMOscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.AMOscillator\n\t\t *\n\t\t * @extends {Tone.Oscillator}\n\t\t * @constructor\n\t\t * @param {Frequency} frequency The starting frequency of the oscillator.\n\t\t * @param {String} type The type of the carrier oscillator.\n\t\t * @param {String} modulationType The type of the modulator oscillator.\n\t\t * @example\n\t\t * //a sine oscillator frequency-modulated by a square wave\n\t\t * var fmOsc = new Tone.AMOscillator(\"Ab3\", \"sine\", \"square\").toMaster().start();\n\t\t */\n\t Tone.AMOscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type',\n\t 'modulationType'\n\t ], Tone.AMOscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * The carrier oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._carrier = new Tone.Oscillator(options.frequency, options.type);\n\t /**\n\t\t\t * The oscillator's frequency\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._carrier.frequency;\n\t /**\n\t\t\t * The detune control signal.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = this._carrier.detune;\n\t this.detune.value = options.detune;\n\t /**\n\t\t\t * The modulating oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._modulator = new Tone.Oscillator(options.frequency, options.modulationType);\n\t /**\n\t\t\t * convert the -1,1 output to 0,1\n\t\t\t * @type {Tone.AudioToGain}\n\t\t\t * @private\n\t\t\t */\n\t this._modulationScale = new Tone.AudioToGain();\n\t /**\n\t\t\t * Harmonicity is the frequency ratio between the carrier and the modulator oscillators.\n\t\t\t * A harmonicity of 1 gives both oscillators the same frequency.\n\t\t\t * Harmonicity = 2 means a change of an octave.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * //pitch the modulator an octave below carrier\n\t\t\t * synth.harmonicity.value = 0.5;\n\t\t\t */\n\t this.harmonicity = new Tone.Multiply(options.harmonicity);\n\t this.harmonicity.units = Tone.Type.Positive;\n\t /**\n\t\t\t * the node where the modulation happens\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._modulationNode = new Tone.Gain(0);\n\t //connections\n\t this.frequency.chain(this.harmonicity, this._modulator.frequency);\n\t this.detune.connect(this._modulator.detune);\n\t this._modulator.chain(this._modulationScale, this._modulationNode.gain);\n\t this._carrier.chain(this._modulationNode, this.output);\n\t this.phase = options.phase;\n\t this._readOnly([\n\t 'frequency',\n\t 'detune',\n\t 'harmonicity'\n\t ]);\n\t };\n\t Tone.extend(Tone.AMOscillator, Tone.Oscillator);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.AMOscillator.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'phase': 0,\n\t 'modulationType': 'square',\n\t 'harmonicity': 1\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now]\n\t\t * @private\n\t\t */\n\t Tone.AMOscillator.prototype._start = function (time) {\n\t this._modulator.start(time);\n\t this._carrier.start(time);\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.AMOscillator.prototype._stop = function (time) {\n\t this._modulator.stop(time);\n\t this._carrier.stop(time);\n\t };\n\t /**\n\t\t * restart the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.AMOscillator.prototype.restart = function (time) {\n\t this._modulator.restart(time);\n\t this._carrier.restart(time);\n\t };\n\t /**\n\t\t * The type of the carrier oscillator\n\t\t * @memberOf Tone.AMOscillator#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.AMOscillator.prototype, 'type', {\n\t get: function () {\n\t return this._carrier.type;\n\t },\n\t set: function (type) {\n\t this._carrier.type = type;\n\t }\n\t });\n\t /**\n\t\t * The type of the modulator oscillator\n\t\t * @memberOf Tone.AMOscillator#\n\t\t * @type {string}\n\t\t * @name modulationType\n\t\t */\n\t Object.defineProperty(Tone.AMOscillator.prototype, 'modulationType', {\n\t get: function () {\n\t return this._modulator.type;\n\t },\n\t set: function (type) {\n\t this._modulator.type = type;\n\t }\n\t });\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.AMOscillator#\n\t\t * @type {number}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.AMOscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._carrier.phase;\n\t },\n\t set: function (phase) {\n\t this._carrier.phase = phase;\n\t this._modulator.phase = phase;\n\t }\n\t });\n\t /**\n\t\t * The partials of the carrier waveform. A partial represents\n\t\t * the amplitude at a harmonic. The first harmonic is the\n\t\t * fundamental frequency, the second is the octave and so on\n\t\t * following the harmonic series.\n\t\t * Setting this value will automatically set the type to \"custom\".\n\t\t * The value is an empty array when the type is not \"custom\".\n\t\t * @memberOf Tone.AMOscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @example\n\t\t * osc.partials = [1, 0.2, 0.01];\n\t\t */\n\t Object.defineProperty(Tone.AMOscillator.prototype, 'partials', {\n\t get: function () {\n\t return this._carrier.partials;\n\t },\n\t set: function (partials) {\n\t this._carrier.partials = partials;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.AMOscillator} this\n\t\t */\n\t Tone.AMOscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'detune',\n\t 'harmonicity'\n\t ]);\n\t this.frequency = null;\n\t this.detune = null;\n\t this.harmonicity.dispose();\n\t this.harmonicity = null;\n\t this._carrier.dispose();\n\t this._carrier = null;\n\t this._modulator.dispose();\n\t this._modulator = null;\n\t this._modulationNode.dispose();\n\t this._modulationNode = null;\n\t this._modulationScale.dispose();\n\t this._modulationScale = null;\n\t return this;\n\t };\n\t return Tone.AMOscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.FatOscillator\n\t\t *\n\t\t * @extends {Tone.Source}\n\t\t * @constructor\n\t\t * @param {Frequency} frequency The starting frequency of the oscillator.\n\t\t * @param {String} type The type of the carrier oscillator.\n\t\t * @param {String} modulationType The type of the modulator oscillator.\n\t\t * @example\n\t\t * //a sine oscillator frequency-modulated by a square wave\n\t\t * var fmOsc = new Tone.FatOscillator(\"Ab3\", \"sine\", \"square\").toMaster().start();\n\t\t */\n\t Tone.FatOscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type',\n\t 'spread'\n\t ], Tone.FatOscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * The oscillator's frequency\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune control signal.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(options.detune, Tone.Type.Cents);\n\t /**\n\t\t\t * The array of oscillators\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._oscillators = [];\n\t /**\n\t\t\t * The total spread of the oscillators\n\t\t\t * @type {Cents}\n\t\t\t * @private\n\t\t\t */\n\t this._spread = options.spread;\n\t /**\n\t\t\t * The type of the oscillator\n\t\t\t * @type {String}\n\t\t\t * @private\n\t\t\t */\n\t this._type = options.type;\n\t /**\n\t\t\t * The phase of the oscillators\n\t\t\t * @type {Degrees}\n\t\t\t * @private\n\t\t\t */\n\t this._phase = options.phase;\n\t /**\n\t\t\t * The partials array\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._partials = Tone.defaultArg(options.partials, []);\n\t //set the count initially\n\t this.count = options.count;\n\t this._readOnly([\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t };\n\t Tone.extend(Tone.FatOscillator, Tone.Source);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.FatOscillator.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'phase': 0,\n\t 'spread': 20,\n\t 'count': 3,\n\t 'type': 'sawtooth'\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now]\n\t\t * @private\n\t\t */\n\t Tone.FatOscillator.prototype._start = function (time) {\n\t time = this.toSeconds(time);\n\t this._forEach(function (osc) {\n\t osc.start(time);\n\t });\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @param {Time} [time=now]\n\t\t * @private\n\t\t */\n\t Tone.FatOscillator.prototype._stop = function (time) {\n\t time = this.toSeconds(time);\n\t this._forEach(function (osc) {\n\t osc.stop(time);\n\t });\n\t };\n\t /**\n\t\t * restart the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.FatOscillator.prototype.restart = function (time) {\n\t time = this.toSeconds(time);\n\t this._forEach(function (osc) {\n\t osc.restart(time);\n\t });\n\t };\n\t /**\n\t\t * Iterate over all of the oscillators\n\t\t * @param {Function} iterator The iterator function\n\t\t * @private\n\t\t */\n\t Tone.FatOscillator.prototype._forEach = function (iterator) {\n\t for (var i = 0; i < this._oscillators.length; i++) {\n\t iterator.call(this, this._oscillators[i], i);\n\t }\n\t };\n\t /**\n\t\t * The type of the carrier oscillator\n\t\t * @memberOf Tone.FatOscillator#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.FatOscillator.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t this._type = type;\n\t this._forEach(function (osc) {\n\t osc.type = type;\n\t });\n\t }\n\t });\n\t /**\n\t\t * The detune spread between the oscillators. If \"count\" is\n\t\t * set to 3 oscillators and the \"spread\" is set to 40,\n\t\t * the three oscillators would be detuned like this: [-20, 0, 20]\n\t\t * for a total detune spread of 40 cents.\n\t\t * @memberOf Tone.FatOscillator#\n\t\t * @type {Cents}\n\t\t * @name spread\n\t\t */\n\t Object.defineProperty(Tone.FatOscillator.prototype, 'spread', {\n\t get: function () {\n\t return this._spread;\n\t },\n\t set: function (spread) {\n\t this._spread = spread;\n\t if (this._oscillators.length > 1) {\n\t var start = -spread / 2;\n\t var step = spread / (this._oscillators.length - 1);\n\t this._forEach(function (osc, i) {\n\t osc.detune.value = start + step * i;\n\t });\n\t }\n\t }\n\t });\n\t /**\n\t\t * The number of detuned oscillators\n\t\t * @memberOf Tone.FatOscillator#\n\t\t * @type {Number}\n\t\t * @name count\n\t\t */\n\t Object.defineProperty(Tone.FatOscillator.prototype, 'count', {\n\t get: function () {\n\t return this._oscillators.length;\n\t },\n\t set: function (count) {\n\t count = Math.max(count, 1);\n\t if (this._oscillators.length !== count) {\n\t // var partials = this.partials;\n\t // var type = this.type;\n\t //dispose the previous oscillators\n\t this._forEach(function (osc) {\n\t osc.dispose();\n\t });\n\t this._oscillators = [];\n\t for (var i = 0; i < count; i++) {\n\t var osc = new Tone.Oscillator();\n\t if (this.type === Tone.Oscillator.Type.Custom) {\n\t osc.partials = this._partials;\n\t } else {\n\t osc.type = this._type;\n\t }\n\t osc.phase = this._phase;\n\t osc.volume.value = -6 - count * 1.1;\n\t this.frequency.connect(osc.frequency);\n\t this.detune.connect(osc.detune);\n\t osc.connect(this.output);\n\t this._oscillators[i] = osc;\n\t }\n\t //set the spread\n\t this.spread = this._spread;\n\t if (this.state === Tone.State.Started) {\n\t this._forEach(function (osc) {\n\t osc.start();\n\t });\n\t }\n\t }\n\t }\n\t });\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.FatOscillator#\n\t\t * @type {Number}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.FatOscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._phase;\n\t },\n\t set: function (phase) {\n\t this._phase = phase;\n\t this._forEach(function (osc) {\n\t osc.phase = phase;\n\t });\n\t }\n\t });\n\t /**\n\t\t * The partials of the carrier waveform. A partial represents\n\t\t * the amplitude at a harmonic. The first harmonic is the\n\t\t * fundamental frequency, the second is the octave and so on\n\t\t * following the harmonic series.\n\t\t * Setting this value will automatically set the type to \"custom\".\n\t\t * The value is an empty array when the type is not \"custom\".\n\t\t * @memberOf Tone.FatOscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @example\n\t\t * osc.partials = [1, 0.2, 0.01];\n\t\t */\n\t Object.defineProperty(Tone.FatOscillator.prototype, 'partials', {\n\t get: function () {\n\t return this._partials;\n\t },\n\t set: function (partials) {\n\t this._partials = partials;\n\t this._type = Tone.Oscillator.Type.Custom;\n\t this._forEach(function (osc) {\n\t osc.partials = partials;\n\t });\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.FatOscillator} this\n\t\t */\n\t Tone.FatOscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this.detune.dispose();\n\t this.detune = null;\n\t this._forEach(function (osc) {\n\t osc.dispose();\n\t });\n\t this._oscillators = null;\n\t this._partials = null;\n\t return this;\n\t };\n\t return Tone.FatOscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.OmniOscillator aggregates Tone.Oscillator, Tone.PulseOscillator,\n\t\t * Tone.PWMOscillator, Tone.FMOscillator, Tone.AMOscillator, and Tone.FatOscillator\n\t\t * into one class. The oscillator class can be changed by setting the `type`.\n\t\t * `omniOsc.type = \"pwm\"` will set it to the Tone.PWMOscillator. Prefixing\n\t\t * any of the basic types (\"sine\", \"square4\", etc.) with \"fm\", \"am\", or \"fat\"\n\t\t * will use the FMOscillator, AMOscillator or FatOscillator respectively.\n\t\t * For example: `omniOsc.type = \"fatsawtooth\"` will create set the oscillator\n\t\t * to a FatOscillator of type \"sawtooth\".\n\t\t *\n\t\t * @extends {Tone.Source}\n\t\t * @constructor\n\t\t * @param {Frequency} frequency The initial frequency of the oscillator.\n\t\t * @param {String} type The type of the oscillator.\n\t\t * @example\n\t\t * var omniOsc = new Tone.OmniOscillator(\"C#4\", \"pwm\");\n\t\t */\n\t Tone.OmniOscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type'\n\t ], Tone.OmniOscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune control\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(options.detune, Tone.Type.Cents);\n\t /**\n\t\t\t * the type of the oscillator source\n\t\t\t * @type {String}\n\t\t\t * @private\n\t\t\t */\n\t this._sourceType = undefined;\n\t /**\n\t\t\t * the oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._oscillator = null;\n\t //set the oscillator\n\t this.type = options.type;\n\t this._readOnly([\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t //set the options\n\t this.set(options);\n\t };\n\t Tone.extend(Tone.OmniOscillator, Tone.Source);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.OmniOscillator.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'type': 'sine',\n\t 'phase': 0\n\t };\n\t /**\n\t\t * @enum {String}\n\t\t * @private\n\t\t */\n\t var OmniOscType = {\n\t Pulse: 'PulseOscillator',\n\t PWM: 'PWMOscillator',\n\t Osc: 'Oscillator',\n\t FM: 'FMOscillator',\n\t AM: 'AMOscillator',\n\t Fat: 'FatOscillator'\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now] the time to start the oscillator\n\t\t * @private\n\t\t */\n\t Tone.OmniOscillator.prototype._start = function (time) {\n\t this._oscillator.start(time);\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now] the time to start the oscillator\n\t\t * @private\n\t\t */\n\t Tone.OmniOscillator.prototype._stop = function (time) {\n\t this._oscillator.stop(time);\n\t };\n\t Tone.OmniOscillator.prototype.restart = function (time) {\n\t this._oscillator.restart(time);\n\t };\n\t /**\n\t\t * The type of the oscillator. Can be any of the basic types: sine, square, triangle, sawtooth. Or\n\t\t * prefix the basic types with \"fm\", \"am\", or \"fat\" to use the FMOscillator, AMOscillator or FatOscillator\n\t\t * types. The oscillator could also be set to \"pwm\" or \"pulse\". All of the parameters of the\n\t\t * oscillator's class are accessible when the oscillator is set to that type, but throws an error\n\t\t * when it's not.\n\t\t *\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {String}\n\t\t * @name type\n\t\t * @example\n\t\t * omniOsc.type = \"pwm\";\n\t\t * //modulationFrequency is parameter which is available\n\t\t * //only when the type is \"pwm\".\n\t\t * omniOsc.modulationFrequency.value = 0.5;\n\t\t * @example\n\t\t * //an square wave frequency modulated by a sawtooth\n\t\t * omniOsc.type = \"fmsquare\";\n\t\t * omniOsc.modulationType = \"sawtooth\";\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'type', {\n\t get: function () {\n\t var prefix = '';\n\t if (this._sourceType === OmniOscType.FM) {\n\t prefix = 'fm';\n\t } else if (this._sourceType === OmniOscType.AM) {\n\t prefix = 'am';\n\t } else if (this._sourceType === OmniOscType.Fat) {\n\t prefix = 'fat';\n\t }\n\t return prefix + this._oscillator.type;\n\t },\n\t set: function (type) {\n\t if (type.substr(0, 2) === 'fm') {\n\t this._createNewOscillator(OmniOscType.FM);\n\t this._oscillator.type = type.substr(2);\n\t } else if (type.substr(0, 2) === 'am') {\n\t this._createNewOscillator(OmniOscType.AM);\n\t this._oscillator.type = type.substr(2);\n\t } else if (type.substr(0, 3) === 'fat') {\n\t this._createNewOscillator(OmniOscType.Fat);\n\t this._oscillator.type = type.substr(3);\n\t } else if (type === 'pwm') {\n\t this._createNewOscillator(OmniOscType.PWM);\n\t } else if (type === 'pulse') {\n\t this._createNewOscillator(OmniOscType.Pulse);\n\t } else {\n\t this._createNewOscillator(OmniOscType.Osc);\n\t this._oscillator.type = type;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The partials of the waveform. A partial represents\n\t\t * the amplitude at a harmonic. The first harmonic is the\n\t\t * fundamental frequency, the second is the octave and so on\n\t\t * following the harmonic series.\n\t\t * Setting this value will automatically set the type to \"custom\".\n\t\t * The value is an empty array when the type is not \"custom\".\n\t\t * This is not available on \"pwm\" and \"pulse\" oscillator types.\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @example\n\t\t * osc.partials = [1, 0.2, 0.01];\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'partials', {\n\t get: function () {\n\t return this._oscillator.partials;\n\t },\n\t set: function (partials) {\n\t this._oscillator.partials = partials;\n\t }\n\t });\n\t /**\n\t\t * Set a member/attribute of the oscillator.\n\t\t * @param {Object|String} params\n\t\t * @param {number=} value\n\t\t * @param {Time=} rampTime\n\t\t * @returns {Tone.OmniOscillator} this\n\t\t */\n\t Tone.OmniOscillator.prototype.set = function (params, value) {\n\t //make sure the type is set first\n\t if (params === 'type') {\n\t this.type = value;\n\t } else if (Tone.isObject(params) && params.hasOwnProperty('type')) {\n\t this.type = params.type;\n\t }\n\t //then set the rest\n\t Tone.prototype.set.apply(this, arguments);\n\t return this;\n\t };\n\t /**\n\t\t * connect the oscillator to the frequency and detune signals\n\t\t * @private\n\t\t */\n\t Tone.OmniOscillator.prototype._createNewOscillator = function (oscType) {\n\t if (oscType !== this._sourceType) {\n\t this._sourceType = oscType;\n\t var OscillatorConstructor = Tone[oscType];\n\t //short delay to avoid clicks on the change\n\t var now = this.now();\n\t if (this._oscillator !== null) {\n\t var oldOsc = this._oscillator;\n\t oldOsc.stop(now);\n\t //dispose the old one\n\t this.context.setTimeout(function () {\n\t oldOsc.dispose();\n\t oldOsc = null;\n\t }, this.blockTime);\n\t }\n\t this._oscillator = new OscillatorConstructor();\n\t this.frequency.connect(this._oscillator.frequency);\n\t this.detune.connect(this._oscillator.detune);\n\t this._oscillator.connect(this.output);\n\t if (this.state === Tone.State.Started) {\n\t this._oscillator.start(now);\n\t }\n\t }\n\t };\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {Degrees}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._oscillator.phase;\n\t },\n\t set: function (phase) {\n\t this._oscillator.phase = phase;\n\t }\n\t });\n\t /**\n\t\t * The width of the oscillator (only if the oscillator is set to \"pulse\")\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t * @name width\n\t\t * @example\n\t\t * var omniOsc = new Tone.OmniOscillator(440, \"pulse\");\n\t\t * //can access the width attribute only if type === \"pulse\"\n\t\t * omniOsc.width.value = 0.2;\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'width', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.Pulse) {\n\t return this._oscillator.width;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The number of detuned oscillators\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {Number}\n\t\t * @name count\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'count', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.Fat) {\n\t return this._oscillator.count;\n\t }\n\t },\n\t set: function (count) {\n\t if (this._sourceType === OmniOscType.Fat) {\n\t this._oscillator.count = count;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The detune spread between the oscillators. If \"count\" is\n\t\t * set to 3 oscillators and the \"spread\" is set to 40,\n\t\t * the three oscillators would be detuned like this: [-20, 0, 20]\n\t\t * for a total detune spread of 40 cents. See Tone.FatOscillator\n\t\t * for more info.\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {Cents}\n\t\t * @name spread\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'spread', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.Fat) {\n\t return this._oscillator.spread;\n\t }\n\t },\n\t set: function (spread) {\n\t if (this._sourceType === OmniOscType.Fat) {\n\t this._oscillator.spread = spread;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The type of the modulator oscillator. Only if the oscillator\n\t\t * is set to \"am\" or \"fm\" types. see. Tone.AMOscillator or Tone.FMOscillator\n\t\t * for more info.\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {String}\n\t\t * @name modulationType\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationType', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) {\n\t return this._oscillator.modulationType;\n\t }\n\t },\n\t set: function (mType) {\n\t if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) {\n\t this._oscillator.modulationType = mType;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The modulation index which is in essence the depth or amount of the modulation. In other terms it is the\n\t\t * ratio of the frequency of the modulating signal (mf) to the amplitude of the\n\t\t * modulating signal (ma) -- as in ma/mf.\n\t\t * See Tone.FMOscillator for more info.\n\t\t * @type {Positive}\n\t\t * @signal\n\t\t * @name modulationIndex\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationIndex', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.FM) {\n\t return this._oscillator.modulationIndex;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Harmonicity is the frequency ratio between the carrier and the modulator oscillators.\n\t\t * A harmonicity of 1 gives both oscillators the same frequency.\n\t\t * Harmonicity = 2 means a change of an octave. See Tone.AMOscillator or Tone.FMOscillator\n\t\t * for more info.\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @signal\n\t\t * @type {Positive}\n\t\t * @name harmonicity\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'harmonicity', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) {\n\t return this._oscillator.harmonicity;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The modulationFrequency Signal of the oscillator\n\t\t * (only if the oscillator type is set to pwm). See\n\t\t * Tone.PWMOscillator for more info.\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {Frequency}\n\t\t * @signal\n\t\t * @name modulationFrequency\n\t\t * @example\n\t\t * var omniOsc = new Tone.OmniOscillator(440, \"pwm\");\n\t\t * //can access the modulationFrequency attribute only if type === \"pwm\"\n\t\t * omniOsc.modulationFrequency.value = 0.2;\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationFrequency', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.PWM) {\n\t return this._oscillator.modulationFrequency;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.OmniOscillator} this\n\t\t */\n\t Tone.OmniOscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t this.detune.dispose();\n\t this.detune = null;\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this._oscillator.dispose();\n\t this._oscillator = null;\n\t this._sourceType = null;\n\t return this;\n\t };\n\t return Tone.OmniOscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Base-class for all instruments\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t */\n\t Tone.Instrument = function (options) {\n\t //get the defaults\n\t options = Tone.defaultArg(options, Tone.Instrument.defaults);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The output and volume triming node\n\t\t\t * @type {Tone.Volume}\n\t\t\t * @private\n\t\t\t */\n\t this._volume = this.output = new Tone.Volume(options.volume);\n\t /**\n\t\t\t * The volume of the output in decibels.\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * source.volume.value = -6;\n\t\t\t */\n\t this.volume = this._volume.volume;\n\t this._readOnly('volume');\n\t /**\n\t\t\t * Keep track of all events scheduled to the transport\n\t\t\t * when the instrument is 'synced'\n\t\t\t * @type {Array<Number>}\n\t\t\t * @private\n\t\t\t */\n\t this._scheduledEvents = [];\n\t };\n\t Tone.extend(Tone.Instrument, Tone.AudioNode);\n\t /**\n\t\t * the default attributes\n\t\t * @type {object}\n\t\t */\n\t Tone.Instrument.defaults = {\n\t /** the volume of the output in decibels */\n\t 'volume': 0\n\t };\n\t /**\n\t\t * @abstract\n\t\t * @param {string|number} note the note to trigger\n\t\t * @param {Time} [time=now] the time to trigger the ntoe\n\t\t * @param {number} [velocity=1] the velocity to trigger the note\n\t\t */\n\t Tone.Instrument.prototype.triggerAttack = Tone.noOp;\n\t /**\n\t\t * @abstract\n\t\t * @param {Time} [time=now] when to trigger the release\n\t\t */\n\t Tone.Instrument.prototype.triggerRelease = Tone.noOp;\n\t /**\n\t\t * Sync the instrument to the Transport. All subsequent calls of\n\t\t * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease)\n\t\t * will be scheduled along the transport.\n\t\t * @example\n\t\t * instrument.sync()\n\t\t * //schedule 3 notes when the transport first starts\n\t\t * instrument.triggerAttackRelease('C4', '8n', 0)\n\t\t * instrument.triggerAttackRelease('E4', '8n', '8n')\n\t\t * instrument.triggerAttackRelease('G4', '8n', '4n')\n\t\t * //start the transport to hear the notes\n\t\t * Transport.start()\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.Instrument.prototype.sync = function () {\n\t this._syncMethod('triggerAttack', 1);\n\t this._syncMethod('triggerRelease', 0);\n\t return this;\n\t };\n\t /**\n\t\t * Wrap the given method so that it can be synchronized\n\t\t * @param {String} method Which method to wrap and sync\n\t\t * @param {Number} timePosition What position the time argument appears in\n\t\t * @private\n\t\t */\n\t Tone.Instrument.prototype._syncMethod = function (method, timePosition) {\n\t var originalMethod = this['_original_' + method] = this[method];\n\t this[method] = function () {\n\t var args = Array.prototype.slice.call(arguments);\n\t var time = args[timePosition];\n\t var id = Tone.Transport.schedule(function (t) {\n\t args[timePosition] = t;\n\t originalMethod.apply(this, args);\n\t }.bind(this), time);\n\t this._scheduledEvents.push(id);\n\t }.bind(this);\n\t };\n\t /**\n\t\t * Unsync the instrument from the Transport\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.Instrument.prototype.unsync = function () {\n\t this._scheduledEvents.forEach(function (id) {\n\t Tone.Transport.clear(id);\n\t });\n\t this._scheduledEvents = [];\n\t if (this._original_triggerAttack) {\n\t this.triggerAttack = this._original_triggerAttack;\n\t this.triggerRelease = this._original_triggerRelease;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the attack and then the release after the duration.\n\t\t * @param {Frequency} note The note to trigger.\n\t\t * @param {Time} duration How long the note should be held for before\n\t\t * triggering the release. This value must be greater than 0.\n\t\t * @param {Time} [time=now] When the note should be triggered.\n\t\t * @param {NormalRange} [velocity=1] The velocity the note should be triggered at.\n\t\t * @returns {Tone.Instrument} this\n\t\t * @example\n\t\t * //trigger \"C4\" for the duration of an 8th note\n\t\t * synth.triggerAttackRelease(\"C4\", \"8n\");\n\t\t */\n\t Tone.Instrument.prototype.triggerAttackRelease = function (note, duration, time, velocity) {\n\t time = this.toSeconds(time);\n\t duration = this.toSeconds(duration);\n\t this.triggerAttack(note, time, velocity);\n\t this.triggerRelease(time + duration);\n\t return this;\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.Instrument.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._volume.dispose();\n\t this._volume = null;\n\t this._writable(['volume']);\n\t this.volume = null;\n\t this.unsync();\n\t this._scheduledEvents = null;\n\t return this;\n\t };\n\t return Tone.Instrument;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class This is an abstract base class for other monophonic instruments to \n\t\t * extend. IMPORTANT: It does not make any sound on its own and\n\t\t * shouldn't be directly instantiated.\n\t\t *\n\t\t * @constructor\n\t\t * @abstract\n\t\t * @extends {Tone.Instrument}\n\t\t */\n\t Tone.Monophonic = function (options) {\n\t //get the defaults\n\t options = Tone.defaultArg(options, Tone.Monophonic.defaults);\n\t Tone.Instrument.call(this, options);\n\t /**\n\t\t\t * The glide time between notes. \n\t\t\t * @type {Time}\n\t\t\t */\n\t this.portamento = options.portamento;\n\t };\n\t Tone.extend(Tone.Monophonic, Tone.Instrument);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Monophonic.defaults = { 'portamento': 0 };\n\t /**\n\t\t * Trigger the attack of the note optionally with a given velocity. \n\t\t * \n\t\t * \n\t\t * @param {Frequency} note The note to trigger.\n\t\t * @param {Time} [time=now] When the note should start.\n\t\t * @param {number} [velocity=1] velocity The velocity scaler \n\t\t * determines how \"loud\" the note \n\t\t * will be triggered.\n\t\t * @returns {Tone.Monophonic} this\n\t\t * @example\n\t\t * synth.triggerAttack(\"C4\");\n\t\t * @example\n\t\t * //trigger the note a half second from now at half velocity\n\t\t * synth.triggerAttack(\"C4\", \"+0.5\", 0.5);\n\t\t */\n\t Tone.Monophonic.prototype.triggerAttack = function (note, time, velocity) {\n\t time = this.toSeconds(time);\n\t this._triggerEnvelopeAttack(time, velocity);\n\t this.setNote(note, time);\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the release portion of the envelope\n\t\t * @param {Time} [time=now] If no time is given, the release happens immediatly\n\t\t * @returns {Tone.Monophonic} this\n\t\t * @example\n\t\t * synth.triggerRelease();\n\t\t */\n\t Tone.Monophonic.prototype.triggerRelease = function (time) {\n\t time = this.toSeconds(time);\n\t this._triggerEnvelopeRelease(time);\n\t return this;\n\t };\n\t /**\n\t\t * override this method with the actual method\n\t\t * @abstract\n\t\t * @private\n\t\t */\n\t Tone.Monophonic.prototype._triggerEnvelopeAttack = function () {\n\t };\n\t /**\n\t\t * override this method with the actual method\n\t\t * @abstract\n\t\t * @private\n\t\t */\n\t Tone.Monophonic.prototype._triggerEnvelopeRelease = function () {\n\t };\n\t /**\n\t\t * Get the level of the output at the given time. Measures\n\t\t * the envelope(s) value at the time. \n\t\t * @param {Time} time The time to query the envelope value\n\t\t * @return {NormalRange} The output level between 0-1\n\t\t */\n\t Tone.Monophonic.prototype.getLevelAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t return this.envelope.getValueAtTime(time);\n\t };\n\t /**\n\t\t * Set the note at the given time. If no time is given, the note\n\t\t * will set immediately. \n\t\t * @param {Frequency} note The note to change to.\n\t\t * @param {Time} [time=now] The time when the note should be set. \n\t\t * @returns {Tone.Monophonic} this\n\t\t * @example\n\t\t * //change to F#6 in one quarter note from now.\n\t\t * synth.setNote(\"F#6\", \"+4n\");\n\t\t * @example\n\t\t * //change to Bb4 right now\n\t\t * synth.setNote(\"Bb4\");\n\t\t */\n\t Tone.Monophonic.prototype.setNote = function (note, time) {\n\t time = this.toSeconds(time);\n\t if (this.portamento > 0 && this.getLevelAtTime(time) > 0.05) {\n\t var portTime = this.toSeconds(this.portamento);\n\t this.frequency.exponentialRampTo(note, portTime, time);\n\t } else {\n\t this.frequency.setValueAtTime(note, time);\n\t }\n\t return this;\n\t };\n\t return Tone.Monophonic;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Synth is composed simply of a Tone.OmniOscillator\n\t\t * routed through a Tone.AmplitudeEnvelope.\n\t\t * <img src=\"https://docs.google.com/drawings/d/1-1_0YW2Z1J2EPI36P8fNCMcZG7N1w1GZluPs4og4evo/pub?w=1163&h=231\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Monophonic}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var synth = new Tone.Synth().toMaster();\n\t\t * synth.triggerAttackRelease(\"C4\", \"8n\");\n\t\t */\n\t Tone.Synth = function (options) {\n\t //get the defaults\n\t options = Tone.defaultArg(options, Tone.Synth.defaults);\n\t Tone.Monophonic.call(this, options);\n\t /**\n\t\t\t * The oscillator.\n\t\t\t * @type {Tone.OmniOscillator}\n\t\t\t */\n\t this.oscillator = new Tone.OmniOscillator(options.oscillator);\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this.oscillator.frequency;\n\t /**\n\t\t\t * The detune control.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = this.oscillator.detune;\n\t /**\n\t\t\t * The amplitude envelope.\n\t\t\t * @type {Tone.AmplitudeEnvelope}\n\t\t\t */\n\t this.envelope = new Tone.AmplitudeEnvelope(options.envelope);\n\t //connect the oscillators to the output\n\t this.oscillator.chain(this.envelope, this.output);\n\t this._readOnly([\n\t 'oscillator',\n\t 'frequency',\n\t 'detune',\n\t 'envelope'\n\t ]);\n\t };\n\t Tone.extend(Tone.Synth, Tone.Monophonic);\n\t /**\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Synth.defaults = {\n\t 'oscillator': { 'type': 'triangle' },\n\t 'envelope': {\n\t 'attack': 0.005,\n\t 'decay': 0.1,\n\t 'sustain': 0.3,\n\t 'release': 1\n\t }\n\t };\n\t /**\n\t\t * start the attack portion of the envelope\n\t\t * @param {Time} [time=now] the time the attack should start\n\t\t * @param {number} [velocity=1] the velocity of the note (0-1)\n\t\t * @returns {Tone.Synth} this\n\t\t * @private\n\t\t */\n\t Tone.Synth.prototype._triggerEnvelopeAttack = function (time, velocity) {\n\t //the envelopes\n\t this.envelope.triggerAttack(time, velocity);\n\t this.oscillator.start(time);\n\t //if there is no release portion, stop the oscillator\n\t if (this.envelope.sustain === 0) {\n\t this.oscillator.stop(time + this.envelope.attack + this.envelope.decay);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * start the release portion of the envelope\n\t\t * @param {Time} [time=now] the time the release should start\n\t\t * @returns {Tone.Synth} this\n\t\t * @private\n\t\t */\n\t Tone.Synth.prototype._triggerEnvelopeRelease = function (time) {\n\t time = this.toSeconds(time);\n\t this.envelope.triggerRelease(time);\n\t this.oscillator.stop(time + this.envelope.release);\n\t return this;\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Synth} this\n\t\t */\n\t Tone.Synth.prototype.dispose = function () {\n\t Tone.Monophonic.prototype.dispose.call(this);\n\t this._writable([\n\t 'oscillator',\n\t 'frequency',\n\t 'detune',\n\t 'envelope'\n\t ]);\n\t this.oscillator.dispose();\n\t this.oscillator = null;\n\t this.envelope.dispose();\n\t this.envelope = null;\n\t this.frequency = null;\n\t this.detune = null;\n\t return this;\n\t };\n\t return Tone.Synth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class AMSynth uses the output of one Tone.Synth to modulate the\n\t\t * amplitude of another Tone.Synth. The harmonicity (the ratio between\n\t\t * the two signals) affects the timbre of the output signal greatly.\n\t\t * Read more about Amplitude Modulation Synthesis on\n\t\t * [SoundOnSound](https://web.archive.org/web/20160404103653/http://www.soundonsound.com:80/sos/mar00/articles/synthsecrets.htm).\n\t\t * <img src=\"https://docs.google.com/drawings/d/1TQu8Ed4iFr1YTLKpB3U1_hur-UwBrh5gdBXc8BxfGKw/pub?w=1009&h=457\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Monophonic}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var synth = new Tone.AMSynth().toMaster();\n\t\t * synth.triggerAttackRelease(\"C4\", \"4n\");\n\t\t */\n\t Tone.AMSynth = function (options) {\n\t options = Tone.defaultArg(options, Tone.AMSynth.defaults);\n\t Tone.Monophonic.call(this, options);\n\t /**\n\t\t\t * The carrier voice.\n\t\t\t * @type {Tone.Synth}\n\t\t\t * @private\n\t\t\t */\n\t this._carrier = new Tone.Synth();\n\t this._carrier.volume.value = -10;\n\t /**\n\t\t\t * The carrier's oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t */\n\t this.oscillator = this._carrier.oscillator;\n\t /**\n\t\t\t * The carrier's envelope\n\t\t\t * @type {Tone.AmplitudeEnvelope}\n\t\t\t */\n\t this.envelope = this._carrier.envelope.set(options.envelope);\n\t /**\n\t\t\t * The modulator voice.\n\t\t\t * @type {Tone.Synth}\n\t\t\t * @private\n\t\t\t */\n\t this._modulator = new Tone.Synth();\n\t this._modulator.volume.value = -10;\n\t /**\n\t\t\t * The modulator's oscillator which is applied\n\t\t\t * to the amplitude of the oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t */\n\t this.modulation = this._modulator.oscillator.set(options.modulation);\n\t /**\n\t\t\t * The modulator's envelope\n\t\t\t * @type {Tone.AmplitudeEnvelope}\n\t\t\t */\n\t this.modulationEnvelope = this._modulator.envelope.set(options.modulationEnvelope);\n\t /**\n\t\t\t * The frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(440, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune in cents\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(options.detune, Tone.Type.Cents);\n\t /**\n\t\t\t * Harmonicity is the ratio between the two voices. A harmonicity of\n\t\t\t * 1 is no change. Harmonicity = 2 means a change of an octave.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * //pitch voice1 an octave below voice0\n\t\t\t * synth.harmonicity.value = 0.5;\n\t\t\t */\n\t this.harmonicity = new Tone.Multiply(options.harmonicity);\n\t this.harmonicity.units = Tone.Type.Positive;\n\t /**\n\t\t\t * convert the -1,1 output to 0,1\n\t\t\t * @type {Tone.AudioToGain}\n\t\t\t * @private\n\t\t\t */\n\t this._modulationScale = new Tone.AudioToGain();\n\t /**\n\t\t\t * the node where the modulation happens\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._modulationNode = new Tone.Gain();\n\t //control the two voices frequency\n\t this.frequency.connect(this._carrier.frequency);\n\t this.frequency.chain(this.harmonicity, this._modulator.frequency);\n\t this.detune.fan(this._carrier.detune, this._modulator.detune);\n\t this._modulator.chain(this._modulationScale, this._modulationNode.gain);\n\t this._carrier.chain(this._modulationNode, this.output);\n\t this._readOnly([\n\t 'frequency',\n\t 'harmonicity',\n\t 'oscillator',\n\t 'envelope',\n\t 'modulation',\n\t 'modulationEnvelope',\n\t 'detune'\n\t ]);\n\t };\n\t Tone.extend(Tone.AMSynth, Tone.Monophonic);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.AMSynth.defaults = {\n\t 'harmonicity': 3,\n\t 'detune': 0,\n\t 'oscillator': { 'type': 'sine' },\n\t 'envelope': {\n\t 'attack': 0.01,\n\t 'decay': 0.01,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t },\n\t 'modulation': { 'type': 'square' },\n\t 'modulationEnvelope': {\n\t 'attack': 0.5,\n\t 'decay': 0,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t }\n\t };\n\t /**\n\t\t * trigger the attack portion of the note\n\t\t *\n\t\t * @param {Time} [time=now] the time the note will occur\n\t\t * @param {NormalRange} [velocity=1] the velocity of the note\n\t\t * @private\n\t\t * @returns {Tone.AMSynth} this\n\t\t */\n\t Tone.AMSynth.prototype._triggerEnvelopeAttack = function (time, velocity) {\n\t //the port glide\n\t time = this.toSeconds(time);\n\t //the envelopes\n\t this._carrier._triggerEnvelopeAttack(time, velocity);\n\t this._modulator._triggerEnvelopeAttack(time);\n\t return this;\n\t };\n\t /**\n\t\t * trigger the release portion of the note\n\t\t *\n\t\t * @param {Time} [time=now] the time the note will release\n\t\t * @private\n\t\t * @returns {Tone.AMSynth} this\n\t\t */\n\t Tone.AMSynth.prototype._triggerEnvelopeRelease = function (time) {\n\t this._carrier._triggerEnvelopeRelease(time);\n\t this._modulator._triggerEnvelopeRelease(time);\n\t return this;\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.AMSynth} this\n\t\t */\n\t Tone.AMSynth.prototype.dispose = function () {\n\t Tone.Monophonic.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'harmonicity',\n\t 'oscillator',\n\t 'envelope',\n\t 'modulation',\n\t 'modulationEnvelope',\n\t 'detune'\n\t ]);\n\t this._carrier.dispose();\n\t this._carrier = null;\n\t this._modulator.dispose();\n\t this._modulator = null;\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this.detune.dispose();\n\t this.detune = null;\n\t this.harmonicity.dispose();\n\t this.harmonicity = null;\n\t this._modulationScale.dispose();\n\t this._modulationScale = null;\n\t this._modulationNode.dispose();\n\t this._modulationNode = null;\n\t this.oscillator = null;\n\t this.envelope = null;\n\t this.modulationEnvelope = null;\n\t this.modulation = null;\n\t return this;\n\t };\n\t return Tone.AMSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.MonoSynth is composed of one oscillator, one filter, and two envelopes.\n\t\t * The amplitude of the Tone.Oscillator and the cutoff frequency of the\n\t\t * Tone.Filter are controlled by Tone.Envelopes.\n\t\t * <img src=\"https://docs.google.com/drawings/d/1gaY1DF9_Hzkodqf8JI1Cg2VZfwSElpFQfI94IQwad38/pub?w=924&h=240\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Monophonic}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var synth = new Tone.MonoSynth({\n\t\t * \t\"oscillator\" : {\n\t\t * \t\t\"type\" : \"square\"\n\t\t * },\n\t\t * \"envelope\" : {\n\t\t * \t\"attack\" : 0.1\n\t\t * }\n\t\t * }).toMaster();\n\t\t * synth.triggerAttackRelease(\"C4\", \"8n\");\n\t\t */\n\t Tone.MonoSynth = function (options) {\n\t //get the defaults\n\t options = Tone.defaultArg(options, Tone.MonoSynth.defaults);\n\t Tone.Monophonic.call(this, options);\n\t /**\n\t\t\t * The oscillator.\n\t\t\t * @type {Tone.OmniOscillator}\n\t\t\t */\n\t this.oscillator = new Tone.OmniOscillator(options.oscillator);\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this.oscillator.frequency;\n\t /**\n\t\t\t * The detune control.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = this.oscillator.detune;\n\t /**\n\t\t\t * The filter.\n\t\t\t * @type {Tone.Filter}\n\t\t\t */\n\t this.filter = new Tone.Filter(options.filter);\n\t /**\n\t\t\t * The filter envelope.\n\t\t\t * @type {Tone.FrequencyEnvelope}\n\t\t\t */\n\t this.filterEnvelope = new Tone.FrequencyEnvelope(options.filterEnvelope);\n\t /**\n\t\t\t * The amplitude envelope.\n\t\t\t * @type {Tone.AmplitudeEnvelope}\n\t\t\t */\n\t this.envelope = new Tone.AmplitudeEnvelope(options.envelope);\n\t //connect the oscillators to the output\n\t this.oscillator.chain(this.filter, this.envelope, this.output);\n\t //connect the filter envelope\n\t this.filterEnvelope.connect(this.filter.frequency);\n\t this._readOnly([\n\t 'oscillator',\n\t 'frequency',\n\t 'detune',\n\t 'filter',\n\t 'filterEnvelope',\n\t 'envelope'\n\t ]);\n\t };\n\t Tone.extend(Tone.MonoSynth, Tone.Monophonic);\n\t /**\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.MonoSynth.defaults = {\n\t 'frequency': 'C4',\n\t 'detune': 0,\n\t 'oscillator': { 'type': 'square' },\n\t 'filter': {\n\t 'Q': 6,\n\t 'type': 'lowpass',\n\t 'rolloff': -24\n\t },\n\t 'envelope': {\n\t 'attack': 0.005,\n\t 'decay': 0.1,\n\t 'sustain': 0.9,\n\t 'release': 1\n\t },\n\t 'filterEnvelope': {\n\t 'attack': 0.06,\n\t 'decay': 0.2,\n\t 'sustain': 0.5,\n\t 'release': 2,\n\t 'baseFrequency': 200,\n\t 'octaves': 7,\n\t 'exponent': 2\n\t }\n\t };\n\t /**\n\t\t * start the attack portion of the envelope\n\t\t * @param {Time} [time=now] the time the attack should start\n\t\t * @param {NormalRange} [velocity=1] the velocity of the note (0-1)\n\t\t * @returns {Tone.MonoSynth} this\n\t\t * @private\n\t\t */\n\t Tone.MonoSynth.prototype._triggerEnvelopeAttack = function (time, velocity) {\n\t time = this.toSeconds(time);\n\t //the envelopes\n\t this.envelope.triggerAttack(time, velocity);\n\t this.filterEnvelope.triggerAttack(time);\n\t this.oscillator.start(time);\n\t if (this.envelope.sustain === 0) {\n\t this.oscillator.stop(time + this.envelope.attack + this.envelope.decay);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * start the release portion of the envelope\n\t\t * @param {Time} [time=now] the time the release should start\n\t\t * @returns {Tone.MonoSynth} this\n\t\t * @private\n\t\t */\n\t Tone.MonoSynth.prototype._triggerEnvelopeRelease = function (time) {\n\t this.envelope.triggerRelease(time);\n\t this.filterEnvelope.triggerRelease(time);\n\t this.oscillator.stop(time + this.envelope.release);\n\t return this;\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.MonoSynth} this\n\t\t */\n\t Tone.MonoSynth.prototype.dispose = function () {\n\t Tone.Monophonic.prototype.dispose.call(this);\n\t this._writable([\n\t 'oscillator',\n\t 'frequency',\n\t 'detune',\n\t 'filter',\n\t 'filterEnvelope',\n\t 'envelope'\n\t ]);\n\t this.oscillator.dispose();\n\t this.oscillator = null;\n\t this.envelope.dispose();\n\t this.envelope = null;\n\t this.filterEnvelope.dispose();\n\t this.filterEnvelope = null;\n\t this.filter.dispose();\n\t this.filter = null;\n\t this.frequency = null;\n\t this.detune = null;\n\t return this;\n\t };\n\t return Tone.MonoSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.DuoSynth is a monophonic synth composed of two\n\t\t * MonoSynths run in parallel with control over the\n\t\t * frequency ratio between the two voices and vibrato effect.\n\t\t * <img src=\"https://docs.google.com/drawings/d/1bL4GXvfRMMlqS7XyBm9CjL9KJPSUKbcdBNpqOlkFLxk/pub?w=1012&h=448\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Monophonic}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var duoSynth = new Tone.DuoSynth().toMaster();\n\t\t * duoSynth.triggerAttackRelease(\"C4\", \"2n\");\n\t\t */\n\t Tone.DuoSynth = function (options) {\n\t options = Tone.defaultArg(options, Tone.DuoSynth.defaults);\n\t Tone.Monophonic.call(this, options);\n\t /**\n\t\t\t * the first voice\n\t\t\t * @type {Tone.MonoSynth}\n\t\t\t */\n\t this.voice0 = new Tone.MonoSynth(options.voice0);\n\t this.voice0.volume.value = -10;\n\t /**\n\t\t\t * the second voice\n\t\t\t * @type {Tone.MonoSynth}\n\t\t\t */\n\t this.voice1 = new Tone.MonoSynth(options.voice1);\n\t this.voice1.volume.value = -10;\n\t /**\n\t\t\t * The vibrato LFO.\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._vibrato = new Tone.LFO(options.vibratoRate, -50, 50);\n\t this._vibrato.start();\n\t /**\n\t\t\t * the vibrato frequency\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.vibratoRate = this._vibrato.frequency;\n\t /**\n\t\t\t * the vibrato gain\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._vibratoGain = new Tone.Gain(options.vibratoAmount, Tone.Type.Positive);\n\t /**\n\t\t\t * The amount of vibrato\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this.vibratoAmount = this._vibratoGain.gain;\n\t /**\n\t\t\t * the frequency control\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(440, Tone.Type.Frequency);\n\t /**\n\t\t\t * Harmonicity is the ratio between the two voices. A harmonicity of\n\t\t\t * 1 is no change. Harmonicity = 2 means a change of an octave.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * //pitch voice1 an octave below voice0\n\t\t\t * duoSynth.harmonicity.value = 0.5;\n\t\t\t */\n\t this.harmonicity = new Tone.Multiply(options.harmonicity);\n\t this.harmonicity.units = Tone.Type.Positive;\n\t //control the two voices frequency\n\t this.frequency.connect(this.voice0.frequency);\n\t this.frequency.chain(this.harmonicity, this.voice1.frequency);\n\t this._vibrato.connect(this._vibratoGain);\n\t this._vibratoGain.fan(this.voice0.detune, this.voice1.detune);\n\t this.voice0.connect(this.output);\n\t this.voice1.connect(this.output);\n\t this._readOnly([\n\t 'voice0',\n\t 'voice1',\n\t 'frequency',\n\t 'vibratoAmount',\n\t 'vibratoRate'\n\t ]);\n\t };\n\t Tone.extend(Tone.DuoSynth, Tone.Monophonic);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.DuoSynth.defaults = {\n\t 'vibratoAmount': 0.5,\n\t 'vibratoRate': 5,\n\t 'harmonicity': 1.5,\n\t 'voice0': {\n\t 'volume': -10,\n\t 'portamento': 0,\n\t 'oscillator': { 'type': 'sine' },\n\t 'filterEnvelope': {\n\t 'attack': 0.01,\n\t 'decay': 0,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t },\n\t 'envelope': {\n\t 'attack': 0.01,\n\t 'decay': 0,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t }\n\t },\n\t 'voice1': {\n\t 'volume': -10,\n\t 'portamento': 0,\n\t 'oscillator': { 'type': 'sine' },\n\t 'filterEnvelope': {\n\t 'attack': 0.01,\n\t 'decay': 0,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t },\n\t 'envelope': {\n\t 'attack': 0.01,\n\t 'decay': 0,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t }\n\t }\n\t };\n\t /**\n\t\t * start the attack portion of the envelopes\n\t\t *\n\t\t * @param {Time} [time=now] the time the attack should start\n\t\t * @param {NormalRange} [velocity=1] the velocity of the note (0-1)\n\t\t * @returns {Tone.DuoSynth} this\n\t\t * @private\n\t\t */\n\t Tone.DuoSynth.prototype._triggerEnvelopeAttack = function (time, velocity) {\n\t time = this.toSeconds(time);\n\t this.voice0._triggerEnvelopeAttack(time, velocity);\n\t this.voice1._triggerEnvelopeAttack(time, velocity);\n\t return this;\n\t };\n\t /**\n\t\t * start the release portion of the envelopes\n\t\t *\n\t\t * @param {Time} [time=now] the time the release should start\n\t\t * @returns {Tone.DuoSynth} this\n\t\t * @private\n\t\t */\n\t Tone.DuoSynth.prototype._triggerEnvelopeRelease = function (time) {\n\t this.voice0._triggerEnvelopeRelease(time);\n\t this.voice1._triggerEnvelopeRelease(time);\n\t return this;\n\t };\n\t /**\n\t\t * Get the level of the output at the given time. Measures\n\t\t * the envelope(s) value at the time. \n\t\t * @param {Time} time The time to query the envelope value\n\t\t * @return {NormalRange} The output level between 0-1\n\t\t */\n\t Tone.DuoSynth.prototype.getLevelAtTime = function (time) {\n\t return (this.voice0.getLevelAtTime(time) + this.voice1.getLevelAtTime(time)) / 2;\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.DuoSynth} this\n\t\t */\n\t Tone.DuoSynth.prototype.dispose = function () {\n\t Tone.Monophonic.prototype.dispose.call(this);\n\t this._writable([\n\t 'voice0',\n\t 'voice1',\n\t 'frequency',\n\t 'vibratoAmount',\n\t 'vibratoRate'\n\t ]);\n\t this.voice0.dispose();\n\t this.voice0 = null;\n\t this.voice1.dispose();\n\t this.voice1 = null;\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this._vibratoGain.dispose();\n\t this._vibratoGain = null;\n\t this._vibrato = null;\n\t this.harmonicity.dispose();\n\t this.harmonicity = null;\n\t this.vibratoAmount.dispose();\n\t this.vibratoAmount = null;\n\t this.vibratoRate = null;\n\t return this;\n\t };\n\t return Tone.DuoSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class FMSynth is composed of two Tone.Synths where one Tone.Synth modulates\n\t\t * the frequency of a second Tone.Synth. A lot of spectral content\n\t\t * can be explored using the modulationIndex parameter. Read more about\n\t\t * frequency modulation synthesis on Sound On Sound: [Part 1](https://web.archive.org/web/20160403123704/http://www.soundonsound.com/sos/apr00/articles/synthsecrets.htm), [Part 2](https://web.archive.org/web/20160403115835/http://www.soundonsound.com/sos/may00/articles/synth.htm).\n\t\t * <img src=\"https://docs.google.com/drawings/d/1h0PUDZXPgi4Ikx6bVT6oncrYPLluFKy7lj53puxj-DM/pub?w=902&h=462\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Monophonic}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var fmSynth = new Tone.FMSynth().toMaster();\n\t\t * fmSynth.triggerAttackRelease(\"C5\", \"4n\");\n\t\t */\n\t Tone.FMSynth = function (options) {\n\t options = Tone.defaultArg(options, Tone.FMSynth.defaults);\n\t Tone.Monophonic.call(this, options);\n\t /**\n\t\t\t * The carrier voice.\n\t\t\t * @type {Tone.Synth}\n\t\t\t * @private\n\t\t\t */\n\t this._carrier = new Tone.Synth(options.carrier);\n\t this._carrier.volume.value = -10;\n\t /**\n\t\t\t * The carrier's oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t */\n\t this.oscillator = this._carrier.oscillator;\n\t /**\n\t\t\t * The carrier's envelope\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t */\n\t this.envelope = this._carrier.envelope.set(options.envelope);\n\t /**\n\t\t\t * The modulator voice.\n\t\t\t * @type {Tone.Synth}\n\t\t\t * @private\n\t\t\t */\n\t this._modulator = new Tone.Synth(options.modulator);\n\t this._modulator.volume.value = -10;\n\t /**\n\t\t\t * The modulator's oscillator which is applied\n\t\t\t * to the amplitude of the oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t */\n\t this.modulation = this._modulator.oscillator.set(options.modulation);\n\t /**\n\t\t\t * The modulator's envelope\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t */\n\t this.modulationEnvelope = this._modulator.envelope.set(options.modulationEnvelope);\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(440, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune in cents\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(options.detune, Tone.Type.Cents);\n\t /**\n\t\t\t * Harmonicity is the ratio between the two voices. A harmonicity of\n\t\t\t * 1 is no change. Harmonicity = 2 means a change of an octave.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * //pitch voice1 an octave below voice0\n\t\t\t * synth.harmonicity.value = 0.5;\n\t\t\t */\n\t this.harmonicity = new Tone.Multiply(options.harmonicity);\n\t this.harmonicity.units = Tone.Type.Positive;\n\t /**\n\t\t\t * The modulation index which essentially the depth or amount of the modulation. It is the\n\t\t\t * ratio of the frequency of the modulating signal (mf) to the amplitude of the\n\t\t\t * modulating signal (ma) -- as in ma/mf.\n\t\t\t *\t@type {Positive}\n\t\t\t *\t@signal\n\t\t\t */\n\t this.modulationIndex = new Tone.Multiply(options.modulationIndex);\n\t this.modulationIndex.units = Tone.Type.Positive;\n\t /**\n\t\t\t * the node where the modulation happens\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this._modulationNode = new Tone.Gain(0);\n\t //control the two voices frequency\n\t this.frequency.connect(this._carrier.frequency);\n\t this.frequency.chain(this.harmonicity, this._modulator.frequency);\n\t this.frequency.chain(this.modulationIndex, this._modulationNode);\n\t this.detune.fan(this._carrier.detune, this._modulator.detune);\n\t this._modulator.connect(this._modulationNode.gain);\n\t this._modulationNode.connect(this._carrier.frequency);\n\t this._carrier.connect(this.output);\n\t this._readOnly([\n\t 'frequency',\n\t 'harmonicity',\n\t 'modulationIndex',\n\t 'oscillator',\n\t 'envelope',\n\t 'modulation',\n\t 'modulationEnvelope',\n\t 'detune'\n\t ]);\n\t };\n\t Tone.extend(Tone.FMSynth, Tone.Monophonic);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.FMSynth.defaults = {\n\t 'harmonicity': 3,\n\t 'modulationIndex': 10,\n\t 'detune': 0,\n\t 'oscillator': { 'type': 'sine' },\n\t 'envelope': {\n\t 'attack': 0.01,\n\t 'decay': 0.01,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t },\n\t 'modulation': { 'type': 'square' },\n\t 'modulationEnvelope': {\n\t 'attack': 0.5,\n\t 'decay': 0,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t }\n\t };\n\t /**\n\t\t * \ttrigger the attack portion of the note\n\t\t *\n\t\t * @param {Time} [time=now] the time the note will occur\n\t\t * @param {number} [velocity=1] the velocity of the note\n\t\t * @returns {Tone.FMSynth} this\n\t\t * @private\n\t\t */\n\t Tone.FMSynth.prototype._triggerEnvelopeAttack = function (time, velocity) {\n\t time = this.toSeconds(time);\n\t //the envelopes\n\t this._carrier._triggerEnvelopeAttack(time, velocity);\n\t this._modulator._triggerEnvelopeAttack(time);\n\t return this;\n\t };\n\t /**\n\t\t * trigger the release portion of the note\n\t\t *\n\t\t * @param {Time} [time=now] the time the note will release\n\t\t * @returns {Tone.FMSynth} this\n\t\t * @private\n\t\t */\n\t Tone.FMSynth.prototype._triggerEnvelopeRelease = function (time) {\n\t time = this.toSeconds(time);\n\t this._carrier._triggerEnvelopeRelease(time);\n\t this._modulator._triggerEnvelopeRelease(time);\n\t return this;\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.FMSynth} this\n\t\t */\n\t Tone.FMSynth.prototype.dispose = function () {\n\t Tone.Monophonic.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'harmonicity',\n\t 'modulationIndex',\n\t 'oscillator',\n\t 'envelope',\n\t 'modulation',\n\t 'modulationEnvelope',\n\t 'detune'\n\t ]);\n\t this._carrier.dispose();\n\t this._carrier = null;\n\t this._modulator.dispose();\n\t this._modulator = null;\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this.detune.dispose();\n\t this.detune = null;\n\t this.modulationIndex.dispose();\n\t this.modulationIndex = null;\n\t this.harmonicity.dispose();\n\t this.harmonicity = null;\n\t this._modulationNode.dispose();\n\t this._modulationNode = null;\n\t this.oscillator = null;\n\t this.envelope = null;\n\t this.modulationEnvelope = null;\n\t this.modulation = null;\n\t return this;\n\t };\n\t return Tone.FMSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.MembraneSynth makes kick and tom sounds using a single oscillator\n\t\t * with an amplitude envelope and frequency ramp. A Tone.OmniOscillator\n\t\t * is routed through a Tone.AmplitudeEnvelope to the output. The drum\n\t\t * quality of the sound comes from the frequency envelope applied\n\t\t * during Tone.MembraneSynth.triggerAttack(note). The frequency envelope\n\t\t * starts at <code>note * .octaves</code> and ramps to <code>note</code>\n\t\t * over the duration of <code>.pitchDecay</code>.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Instrument}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var synth = new Tone.MembraneSynth().toMaster();\n\t\t * synth.triggerAttackRelease(\"C2\", \"8n\");\n\t\t */\n\t Tone.MembraneSynth = function (options) {\n\t options = Tone.defaultArg(options, Tone.MembraneSynth.defaults);\n\t Tone.Instrument.call(this, options);\n\t /**\n\t\t\t * The oscillator.\n\t\t\t * @type {Tone.OmniOscillator}\n\t\t\t */\n\t this.oscillator = new Tone.OmniOscillator(options.oscillator);\n\t /**\n\t\t\t * The amplitude envelope.\n\t\t\t * @type {Tone.AmplitudeEnvelope}\n\t\t\t */\n\t this.envelope = new Tone.AmplitudeEnvelope(options.envelope);\n\t /**\n\t\t\t * The number of octaves the pitch envelope ramps.\n\t\t\t * @type {Positive}\n\t\t\t */\n\t this.octaves = options.octaves;\n\t /**\n\t\t\t * The amount of time the frequency envelope takes.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.pitchDecay = options.pitchDecay;\n\t this.oscillator.chain(this.envelope, this.output);\n\t this._readOnly([\n\t 'oscillator',\n\t 'envelope'\n\t ]);\n\t };\n\t Tone.extend(Tone.MembraneSynth, Tone.Instrument);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.MembraneSynth.defaults = {\n\t 'pitchDecay': 0.05,\n\t 'octaves': 10,\n\t 'oscillator': { 'type': 'sine' },\n\t 'envelope': {\n\t 'attack': 0.001,\n\t 'decay': 0.4,\n\t 'sustain': 0.01,\n\t 'release': 1.4,\n\t 'attackCurve': 'exponential'\n\t }\n\t };\n\t /**\n\t\t * Trigger the note at the given time with the given velocity.\n\t\t *\n\t\t * @param {Frequency} note the note\n\t\t * @param {Time} [time=now] the time, if not given is now\n\t\t * @param {number} [velocity=1] velocity defaults to 1\n\t\t * @returns {Tone.MembraneSynth} this\n\t\t * @example\n\t\t * kick.triggerAttack(60);\n\t\t */\n\t Tone.MembraneSynth.prototype.triggerAttack = function (note, time, velocity) {\n\t time = this.toSeconds(time);\n\t note = this.toFrequency(note);\n\t var maxNote = note * this.octaves;\n\t this.oscillator.frequency.setValueAtTime(maxNote, time);\n\t this.oscillator.frequency.exponentialRampToValueAtTime(note, time + this.toSeconds(this.pitchDecay));\n\t this.envelope.triggerAttack(time, velocity);\n\t this.oscillator.start(time);\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the release portion of the note.\n\t\t *\n\t\t * @param {Time} [time=now] the time the note will release\n\t\t * @returns {Tone.MembraneSynth} this\n\t\t */\n\t Tone.MembraneSynth.prototype.triggerRelease = function (time) {\n\t time = this.toSeconds(time);\n\t this.envelope.triggerRelease(time);\n\t this.oscillator.stop(time + this.envelope.release);\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.MembraneSynth} this\n\t\t */\n\t Tone.MembraneSynth.prototype.dispose = function () {\n\t Tone.Instrument.prototype.dispose.call(this);\n\t this._writable([\n\t 'oscillator',\n\t 'envelope'\n\t ]);\n\t this.oscillator.dispose();\n\t this.oscillator = null;\n\t this.envelope.dispose();\n\t this.envelope = null;\n\t return this;\n\t };\n\t return Tone.MembraneSynth;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * Inharmonic ratio of frequencies based on the Roland TR-808\n\t\t * Taken from https://ccrma.stanford.edu/papers/tr-808-cymbal-physically-informed-circuit-bendable-digital-model\n\t\t * @private\n\t\t * @static\n\t\t * @type {Array}\n\t\t */\n\t var inharmRatios = [\n\t 1,\n\t 1.483,\n\t 1.932,\n\t 2.546,\n\t 2.63,\n\t 3.897\n\t ];\n\t /**\n\t\t * @class A highly inharmonic and spectrally complex source with a highpass filter\n\t\t * and amplitude envelope which is good for making metalophone sounds. Based\n\t\t * on CymbalSynth by [@polyrhythmatic](https://github.com/polyrhythmatic).\n\t\t * Inspiration from [Sound on Sound](https://web.archive.org/web/20160610143924/https://www.soundonsound.com/sos/jul02/articles/synthsecrets0702.asp).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Instrument}\n\t\t * @param {Object} [options] The options availble for the synth\n\t\t * see defaults below\n\t\t */\n\t Tone.MetalSynth = function (options) {\n\t options = Tone.defaultArg(options, Tone.MetalSynth.defaults);\n\t Tone.Instrument.call(this, options);\n\t /**\n\t\t\t * The frequency of the cymbal\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The array of FMOscillators\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._oscillators = [];\n\t /**\n\t\t\t * The frequency multipliers\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._freqMultipliers = [];\n\t /**\n\t\t\t * The amplitude for the body\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._amplitue = new Tone.Gain(0).connect(this.output);\n\t /**\n\t\t\t * highpass the output\n\t\t\t * @type {Tone.Filter}\n\t\t\t * @private\n\t\t\t */\n\t this._highpass = new Tone.Filter({\n\t 'type': 'highpass',\n\t 'Q': -3.0102999566398125\n\t }).connect(this._amplitue);\n\t /**\n\t\t\t * The number of octaves the highpass\n\t\t\t * filter frequency ramps\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._octaves = options.octaves;\n\t /**\n\t\t\t * Scale the body envelope\n\t\t\t * for the bandpass\n\t\t\t * @type {Tone.Scale}\n\t\t\t * @private\n\t\t\t */\n\t this._filterFreqScaler = new Tone.Scale(options.resonance, 7000);\n\t /**\n\t\t\t * The envelope which is connected both to the\n\t\t\t * amplitude and highpass filter's cutoff frequency\n\t\t\t * @type {Tone.Envelope}\n\t\t\t */\n\t this.envelope = new Tone.Envelope({\n\t 'attack': options.envelope.attack,\n\t 'attackCurve': 'linear',\n\t 'decay': options.envelope.decay,\n\t 'sustain': 0,\n\t 'release': options.envelope.release\n\t }).chain(this._filterFreqScaler, this._highpass.frequency);\n\t this.envelope.connect(this._amplitue.gain);\n\t for (var i = 0; i < inharmRatios.length; i++) {\n\t var osc = new Tone.FMOscillator({\n\t 'type': 'square',\n\t 'modulationType': 'square',\n\t 'harmonicity': options.harmonicity,\n\t 'modulationIndex': options.modulationIndex\n\t });\n\t osc.connect(this._highpass);\n\t this._oscillators[i] = osc;\n\t var mult = new Tone.Multiply(inharmRatios[i]);\n\t this._freqMultipliers[i] = mult;\n\t this.frequency.chain(mult, osc.frequency);\n\t }\n\t //set the octaves\n\t this.octaves = options.octaves;\n\t };\n\t Tone.extend(Tone.MetalSynth, Tone.Instrument);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.MetalSynth.defaults = {\n\t 'frequency': 200,\n\t 'envelope': {\n\t 'attack': 0.001,\n\t 'decay': 1.4,\n\t 'release': 0.2\n\t },\n\t 'harmonicity': 5.1,\n\t 'modulationIndex': 32,\n\t 'resonance': 4000,\n\t 'octaves': 1.5\n\t };\n\t /**\n\t\t * Trigger the attack.\n\t\t * @param {Time} time When the attack should be triggered.\n\t\t * @param {NormalRange} [velocity=1] The velocity that the envelope should be triggered at.\n\t\t * @return {Tone.MetalSynth} this\n\t\t */\n\t Tone.MetalSynth.prototype.triggerAttack = function (time, vel) {\n\t time = this.toSeconds(time);\n\t vel = Tone.defaultArg(vel, 1);\n\t this.envelope.triggerAttack(time, vel);\n\t this._oscillators.forEach(function (osc) {\n\t osc.start(time);\n\t });\n\t //if the sustain is 0, stop the oscillator as well\n\t if (this.envelope.sustain === 0) {\n\t this._oscillators.forEach(function (osc) {\n\t osc.stop(time + this.envelope.attack + this.envelope.decay);\n\t }.bind(this));\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the release of the envelope.\n\t\t * @param {Time} time When the release should be triggered.\n\t\t * @return {Tone.MetalSynth} this\n\t\t */\n\t Tone.MetalSynth.prototype.triggerRelease = function (time) {\n\t time = this.toSeconds(time);\n\t this.envelope.triggerRelease(time);\n\t this._oscillators.forEach(function (osc) {\n\t osc.stop(time + this.envelope.release);\n\t }.bind(this));\n\t return this;\n\t };\n\t /**\n\t\t * Sync the instrument to the Transport. All subsequent calls of\n\t\t * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease)\n\t\t * will be scheduled along the transport.\n\t\t * @example\n\t\t * synth.sync()\n\t\t * //schedule 3 notes when the transport first starts\n\t\t * synth.triggerAttackRelease('8n', 0)\n\t\t * synth.triggerAttackRelease('8n', '8n')\n\t\t * synth.triggerAttackRelease('8n', '4n')\n\t\t * //start the transport to hear the notes\n\t\t * Transport.start()\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.MetalSynth.prototype.sync = function () {\n\t this._syncMethod('triggerAttack', 0);\n\t this._syncMethod('triggerRelease', 0);\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the attack and release of the envelope after the given\n\t\t * duration.\n\t\t * @param {Time} duration The duration before triggering the release\n\t\t * @param {Time} time When the attack should be triggered.\n\t\t * @param {NormalRange} [velocity=1] The velocity that the envelope should be triggered at.\n\t\t * @return {Tone.MetalSynth} this\n\t\t */\n\t Tone.MetalSynth.prototype.triggerAttackRelease = function (duration, time, velocity) {\n\t time = this.toSeconds(time);\n\t duration = this.toSeconds(duration);\n\t this.triggerAttack(time, velocity);\n\t this.triggerRelease(time + duration);\n\t return this;\n\t };\n\t /**\n\t\t * The modulationIndex of the oscillators which make up the source.\n\t\t * see Tone.FMOscillator.modulationIndex\n\t\t * @memberOf Tone.MetalSynth#\n\t\t * @type {Positive}\n\t\t * @name modulationIndex\n\t\t */\n\t Object.defineProperty(Tone.MetalSynth.prototype, 'modulationIndex', {\n\t get: function () {\n\t return this._oscillators[0].modulationIndex.value;\n\t },\n\t set: function (val) {\n\t for (var i = 0; i < this._oscillators.length; i++) {\n\t this._oscillators[i].modulationIndex.value = val;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The harmonicity of the oscillators which make up the source.\n\t\t * see Tone.FMOscillator.harmonicity\n\t\t * @memberOf Tone.MetalSynth#\n\t\t * @type {Positive}\n\t\t * @name harmonicity\n\t\t */\n\t Object.defineProperty(Tone.MetalSynth.prototype, 'harmonicity', {\n\t get: function () {\n\t return this._oscillators[0].harmonicity.value;\n\t },\n\t set: function (val) {\n\t for (var i = 0; i < this._oscillators.length; i++) {\n\t this._oscillators[i].harmonicity.value = val;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The frequency of the highpass filter attached to the envelope\n\t\t * @memberOf Tone.MetalSynth#\n\t\t * @type {Frequency}\n\t\t * @name resonance\n\t\t */\n\t Object.defineProperty(Tone.MetalSynth.prototype, 'resonance', {\n\t get: function () {\n\t return this._filterFreqScaler.min;\n\t },\n\t set: function (val) {\n\t this._filterFreqScaler.min = val;\n\t this.octaves = this._octaves;\n\t }\n\t });\n\t /**\n\t\t * The number of octaves above the \"resonance\" frequency\n\t\t * that the filter ramps during the attack/decay envelope\n\t\t * @memberOf Tone.MetalSynth#\n\t\t * @type {Number}\n\t\t * @name octaves\n\t\t */\n\t Object.defineProperty(Tone.MetalSynth.prototype, 'octaves', {\n\t get: function () {\n\t return this._octaves;\n\t },\n\t set: function (octs) {\n\t this._octaves = octs;\n\t this._filterFreqScaler.max = this._filterFreqScaler.min * Math.pow(2, octs);\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @returns {Tone.MetalSynth} this\n\t\t */\n\t Tone.MetalSynth.prototype.dispose = function () {\n\t Tone.Instrument.prototype.dispose.call(this);\n\t for (var i = 0; i < this._oscillators.length; i++) {\n\t this._oscillators[i].dispose();\n\t this._freqMultipliers[i].dispose();\n\t }\n\t this._oscillators = null;\n\t this._freqMultipliers = null;\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this._filterFreqScaler.dispose();\n\t this._filterFreqScaler = null;\n\t this._amplitue.dispose();\n\t this._amplitue = null;\n\t this.envelope.dispose();\n\t this.envelope = null;\n\t this._highpass.dispose();\n\t this._highpass = null;\n\t };\n\t return Tone.MetalSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.NoiseSynth is composed of a noise generator (Tone.Noise), one filter (Tone.Filter),\n\t\t * and two envelopes (Tone.Envelop). One envelope controls the amplitude\n\t\t * of the noise and the other is controls the cutoff frequency of the filter.\n\t\t * <img src=\"https://docs.google.com/drawings/d/1rqzuX9rBlhT50MRvD2TKml9bnZhcZmzXF1rf_o7vdnE/pub?w=918&h=242\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Instrument}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var noiseSynth = new Tone.NoiseSynth().toMaster();\n\t\t * noiseSynth.triggerAttackRelease(\"8n\");\n\t\t */\n\t Tone.NoiseSynth = function (options) {\n\t //get the defaults\n\t options = Tone.defaultArg(options, Tone.NoiseSynth.defaults);\n\t Tone.Instrument.call(this, options);\n\t /**\n\t\t\t * The noise source.\n\t\t\t * @type {Tone.Noise}\n\t\t\t * @example\n\t\t\t * noiseSynth.set(\"noise.type\", \"brown\");\n\t\t\t */\n\t this.noise = new Tone.Noise();\n\t /**\n\t\t\t * The amplitude envelope.\n\t\t\t * @type {Tone.AmplitudeEnvelope}\n\t\t\t */\n\t this.envelope = new Tone.AmplitudeEnvelope(options.envelope);\n\t //connect the noise to the output\n\t this.noise.chain(this.envelope, this.output);\n\t this._readOnly([\n\t 'noise',\n\t 'envelope'\n\t ]);\n\t };\n\t Tone.extend(Tone.NoiseSynth, Tone.Instrument);\n\t /**\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.NoiseSynth.defaults = {\n\t 'noise': { 'type': 'white' },\n\t 'envelope': {\n\t 'attack': 0.005,\n\t 'decay': 0.1,\n\t 'sustain': 0\n\t }\n\t };\n\t /**\n\t\t * Start the attack portion of the envelopes. Unlike other\n\t\t * instruments, Tone.NoiseSynth doesn't have a note.\n\t\t * @param {Time} [time=now] the time the attack should start\n\t\t * @param {number} [velocity=1] the velocity of the note (0-1)\n\t\t * @returns {Tone.NoiseSynth} this\n\t\t * @example\n\t\t * noiseSynth.triggerAttack();\n\t\t */\n\t Tone.NoiseSynth.prototype.triggerAttack = function (time, velocity) {\n\t //the envelopes\n\t this.envelope.triggerAttack(time, velocity);\n\t //start the noise\n\t this.noise.start(time);\n\t if (this.envelope.sustain === 0) {\n\t this.noise.stop(time = this.envelope.attack + this.envelope.decay);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Start the release portion of the envelopes.\n\t\t * @param {Time} [time=now] the time the release should start\n\t\t * @returns {Tone.NoiseSynth} this\n\t\t */\n\t Tone.NoiseSynth.prototype.triggerRelease = function (time) {\n\t this.envelope.triggerRelease(time);\n\t this.noise.stop(time + this.envelope.release);\n\t return this;\n\t };\n\t /**\n\t\t * Sync the instrument to the Transport. All subsequent calls of\n\t\t * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease)\n\t\t * will be scheduled along the transport.\n\t\t * @example\n\t\t * synth.sync()\n\t\t * //schedule 3 notes when the transport first starts\n\t\t * synth.triggerAttackRelease('8n', 0)\n\t\t * synth.triggerAttackRelease('8n', '8n')\n\t\t * synth.triggerAttackRelease('8n', '4n')\n\t\t * //start the transport to hear the notes\n\t\t * Transport.start()\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.NoiseSynth.prototype.sync = function () {\n\t this._syncMethod('triggerAttack', 0);\n\t this._syncMethod('triggerRelease', 0);\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the attack and then the release.\n\t\t * @param {Time} duration the duration of the note\n\t\t * @param {Time} [time=now] the time of the attack\n\t\t * @param {number} [velocity=1] the velocity\n\t\t * @returns {Tone.NoiseSynth} this\n\t\t */\n\t Tone.NoiseSynth.prototype.triggerAttackRelease = function (duration, time, velocity) {\n\t time = this.toSeconds(time);\n\t duration = this.toSeconds(duration);\n\t this.triggerAttack(time, velocity);\n\t this.triggerRelease(time + duration);\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.NoiseSynth} this\n\t\t */\n\t Tone.NoiseSynth.prototype.dispose = function () {\n\t Tone.Instrument.prototype.dispose.call(this);\n\t this._writable([\n\t 'noise',\n\t 'envelope'\n\t ]);\n\t this.noise.dispose();\n\t this.noise = null;\n\t this.envelope.dispose();\n\t this.envelope = null;\n\t return this;\n\t };\n\t return Tone.NoiseSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Karplus-String string synthesis. Often out of tune.\n\t\t * Will change when the AudioWorkerNode is available across\n\t\t * browsers.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Instrument}\n\t\t * @param {Object} [options] see the defaults\n\t\t * @example\n\t\t * var plucky = new Tone.PluckSynth().toMaster();\n\t\t * plucky.triggerAttack(\"C4\");\n\t\t */\n\t Tone.PluckSynth = function (options) {\n\t options = Tone.defaultArg(options, Tone.PluckSynth.defaults);\n\t Tone.Instrument.call(this, options);\n\t /**\n\t\t\t * @type {Tone.Noise}\n\t\t\t * @private\n\t\t\t */\n\t this._noise = new Tone.Noise('pink');\n\t /**\n\t\t\t * The amount of noise at the attack.\n\t\t\t * Nominal range of [0.1, 20]\n\t\t\t * @type {number}\n\t\t\t */\n\t this.attackNoise = options.attackNoise;\n\t /**\n\t\t\t * the LFCF\n\t\t\t * @type {Tone.LowpassCombFilter}\n\t\t\t * @private\n\t\t\t */\n\t this._lfcf = new Tone.LowpassCombFilter({\n\t 'resonance': options.resonance,\n\t 'dampening': options.dampening\n\t });\n\t /**\n\t\t\t * The resonance control.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.resonance = this._lfcf.resonance;\n\t /**\n\t\t\t * The dampening control. i.e. the lowpass filter frequency of the comb filter\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.dampening = this._lfcf.dampening;\n\t //connections\n\t this._noise.connect(this._lfcf);\n\t this._lfcf.connect(this.output);\n\t this._readOnly([\n\t 'resonance',\n\t 'dampening'\n\t ]);\n\t };\n\t Tone.extend(Tone.PluckSynth, Tone.Instrument);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.PluckSynth.defaults = {\n\t 'attackNoise': 1,\n\t 'dampening': 4000,\n\t 'resonance': 0.7\n\t };\n\t /**\n\t\t * Trigger the note.\n\t\t * @param {Frequency} note The note to trigger.\n\t\t * @param {Time} [time=now] When the note should be triggered.\n\t\t * @returns {Tone.PluckSynth} this\n\t\t */\n\t Tone.PluckSynth.prototype.triggerAttack = function (note, time) {\n\t note = this.toFrequency(note);\n\t time = this.toSeconds(time);\n\t var delayAmount = 1 / note;\n\t this._lfcf.delayTime.setValueAtTime(delayAmount, time);\n\t this._noise.start(time);\n\t this._noise.stop(time + delayAmount * this.attackNoise);\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.PluckSynth} this\n\t\t */\n\t Tone.PluckSynth.prototype.dispose = function () {\n\t Tone.Instrument.prototype.dispose.call(this);\n\t this._noise.dispose();\n\t this._lfcf.dispose();\n\t this._noise = null;\n\t this._lfcf = null;\n\t this._writable([\n\t 'resonance',\n\t 'dampening'\n\t ]);\n\t this.dampening = null;\n\t this.resonance = null;\n\t return this;\n\t };\n\t return Tone.PluckSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.PolySynth handles voice creation and allocation for any\n\t\t * instruments passed in as the second paramter. PolySynth is\n\t\t * not a synthesizer by itself, it merely manages voices of\n\t\t * one of the other types of synths, allowing any of the\n\t\t * monophonic synthesizers to be polyphonic.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Instrument}\n\t\t * @param {number|Object} [polyphony=4] The number of voices to create\n\t\t * @param {function} [voice=Tone.Synth] The constructor of the voices\n\t\t * uses Tone.Synth by default.\n\t\t * @example\n\t\t * //a polysynth composed of 6 Voices of Synth\n\t\t * var synth = new Tone.PolySynth(6, Tone.Synth).toMaster();\n\t\t * //set the attributes using the set interface\n\t\t * synth.set(\"detune\", -1200);\n\t\t * //play a chord\n\t\t * synth.triggerAttackRelease([\"C4\", \"E4\", \"A4\"], \"4n\");\n\t\t */\n\t Tone.PolySynth = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'polyphony',\n\t 'voice'\n\t ], Tone.PolySynth);\n\t Tone.Instrument.call(this, options);\n\t options = Tone.defaultArg(options, Tone.Instrument.defaults);\n\t //max polyphony\n\t options.polyphony = Math.min(Tone.PolySynth.MAX_POLYPHONY, options.polyphony);\n\t /**\n\t\t\t * the array of voices\n\t\t\t * @type {Array}\n\t\t\t */\n\t this.voices = new Array(options.polyphony);\n\t /**\n\t\t\t * The queue of voices with data about last trigger\n\t\t\t * and the triggered note\n\t\t\t * @private\n\t\t\t * @type {Array}\n\t\t\t */\n\t this._triggers = new Array(options.polyphony);\n\t /**\n\t\t\t * The detune in cents\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(options.detune, Tone.Type.Cents);\n\t this._readOnly('detune');\n\t //create the voices\n\t for (var i = 0; i < options.polyphony; i++) {\n\t var v = new options.voice(arguments[2], arguments[3]);\n\t if (!(v instanceof Tone.Monophonic)) {\n\t throw new Error('Synth constructor must be instance of Tone.Monophonic');\n\t }\n\t this.voices[i] = v;\n\t v.connect(this.output);\n\t if (v.hasOwnProperty('detune')) {\n\t this.detune.connect(v.detune);\n\t }\n\t this._triggers[i] = {\n\t release: -1,\n\t note: null,\n\t voice: v\n\t };\n\t }\n\t };\n\t Tone.extend(Tone.PolySynth, Tone.Instrument);\n\t /**\n\t\t * the defaults\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.PolySynth.defaults = {\n\t 'polyphony': 4,\n\t 'volume': 0,\n\t 'detune': 0,\n\t 'voice': Tone.Synth\n\t };\n\t /**\n\t\t * Trigger the attack portion of the note\n\t\t * @param {Frequency|Array} notes The notes to play. Accepts a single\n\t\t * Frequency or an array of frequencies.\n\t\t * @param {Time} [time=now] The start time of the note.\n\t\t * @param {number} [velocity=1] The velocity of the note.\n\t\t * @returns {Tone.PolySynth} this\n\t\t * @example\n\t\t * //trigger a chord immediately with a velocity of 0.2\n\t\t * poly.triggerAttack([\"Ab3\", \"C4\", \"F5\"], undefined, 0.2);\n\t\t */\n\t Tone.PolySynth.prototype.triggerAttack = function (notes, time, velocity) {\n\t if (!Array.isArray(notes)) {\n\t notes = [notes];\n\t }\n\t time = this.toSeconds(time);\n\t for (var i = 0; i < notes.length; i++) {\n\t var val = notes[i];\n\t //trigger the oldest voice\n\t var oldest = this._triggers[0];\n\t for (var j = 1; j < this._triggers.length; j++) {\n\t if (this._triggers[j].release < oldest.release) {\n\t oldest = this._triggers[j];\n\t }\n\t }\n\t oldest.release = Infinity;\n\t oldest.note = JSON.stringify(val);\n\t oldest.voice.triggerAttack(val, time, velocity);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the attack and release after the specified duration\n\t\t *\n\t\t * @param {Frequency|Array} notes The notes to play. Accepts a single\n\t\t * Frequency or an array of frequencies.\n\t\t * @param {Time} duration the duration of the note\n\t\t * @param {Time} [time=now] if no time is given, defaults to now\n\t\t * @param {number} [velocity=1] the velocity of the attack (0-1)\n\t\t * @returns {Tone.PolySynth} this\n\t\t * @example\n\t\t * //trigger a chord for a duration of a half note\n\t\t * poly.triggerAttackRelease([\"Eb3\", \"G4\", \"C5\"], \"2n\");\n\t\t * @example\n\t\t * //can pass in an array of durations as well\n\t\t * poly.triggerAttackRelease([\"Eb3\", \"G4\", \"C5\"], [\"2n\", \"4n\", \"4n\"]);\n\t\t */\n\t Tone.PolySynth.prototype.triggerAttackRelease = function (notes, duration, time, velocity) {\n\t time = this.toSeconds(time);\n\t this.triggerAttack(notes, time, velocity);\n\t if (Tone.isArray(duration) && Tone.isArray(notes)) {\n\t for (var i = 0; i < notes.length; i++) {\n\t var d = duration[Math.min(i, duration.length - 1)];\n\t this.triggerRelease(notes[i], time + this.toSeconds(d));\n\t }\n\t } else {\n\t this.triggerRelease(notes, time + this.toSeconds(duration));\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the release of the note. Unlike monophonic instruments,\n\t\t * a note (or array of notes) needs to be passed in as the first argument.\n\t\t * @param {Frequency|Array} notes The notes to play. Accepts a single\n\t\t * Frequency or an array of frequencies.\n\t\t * @param {Time} [time=now] When the release will be triggered.\n\t\t * @returns {Tone.PolySynth} this\n\t\t * @example\n\t\t * poly.triggerRelease([\"Ab3\", \"C4\", \"F5\"], \"+2n\");\n\t\t */\n\t Tone.PolySynth.prototype.triggerRelease = function (notes, time) {\n\t if (!Array.isArray(notes)) {\n\t notes = [notes];\n\t }\n\t time = this.toSeconds(time);\n\t for (var i = 0; i < notes.length; i++) {\n\t //get the voice\n\t var stringified = JSON.stringify(notes[i]);\n\t for (var v = 0; v < this._triggers.length; v++) {\n\t var desc = this._triggers[v];\n\t if (desc.note === stringified && desc.release > time) {\n\t desc.voice.triggerRelease(time);\n\t desc.release = time;\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Sync the instrument to the Transport. All subsequent calls of\n\t\t * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease)\n\t\t * will be scheduled along the transport.\n\t\t * @example\n\t\t * synth.sync()\n\t\t * //schedule 3 notes when the transport first starts\n\t\t * synth.triggerAttackRelease('8n', 0)\n\t\t * synth.triggerAttackRelease('8n', '8n')\n\t\t * synth.triggerAttackRelease('8n', '4n')\n\t\t * //start the transport to hear the notes\n\t\t * Transport.start()\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.PolySynth.prototype.sync = function () {\n\t this._syncMethod('triggerAttack', 1);\n\t this._syncMethod('triggerRelease', 1);\n\t return this;\n\t };\n\t /**\n\t\t * Set a member/attribute of the voices.\n\t\t * @param {Object|string} params\n\t\t * @param {number=} value\n\t\t * @param {Time=} rampTime\n\t\t * @returns {Tone.PolySynth} this\n\t\t * @example\n\t\t * poly.set({\n\t\t * \t\"filter\" : {\n\t\t * \t\t\"type\" : \"highpass\"\n\t\t * \t},\n\t\t * \t\"envelope\" : {\n\t\t * \t\t\"attack\" : 0.25\n\t\t * \t}\n\t\t * });\n\t\t */\n\t Tone.PolySynth.prototype.set = function (params, value, rampTime) {\n\t for (var i = 0; i < this.voices.length; i++) {\n\t this.voices[i].set(params, value, rampTime);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Get the synth's attributes. Given no arguments get\n\t\t * will return all available object properties and their corresponding\n\t\t * values. Pass in a single attribute to retrieve or an array\n\t\t * of attributes. The attribute strings can also include a \".\"\n\t\t * to access deeper properties.\n\t\t * @param {Array=} params the parameters to get, otherwise will return\n\t\t * \t\t\t\t\t all available.\n\t\t */\n\t Tone.PolySynth.prototype.get = function (params) {\n\t return this.voices[0].get(params);\n\t };\n\t /**\n\t\t * Trigger the release portion of all the currently active voices.\n\t\t * @param {Time} [time=now] When the notes should be released.\n\t\t * @return {Tone.PolySynth} this\n\t\t */\n\t Tone.PolySynth.prototype.releaseAll = function (time) {\n\t time = this.toSeconds(time);\n\t for (var i = 0; i < this._triggers.length; i++) {\n\t var desc = this._triggers[i];\n\t if (desc.release > time) {\n\t desc.release = time;\n\t desc.voice.triggerRelease(time);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.PolySynth} this\n\t\t */\n\t Tone.PolySynth.prototype.dispose = function () {\n\t Tone.Instrument.prototype.dispose.call(this);\n\t for (var i = 0; i < this.voices.length; i++) {\n\t this.voices[i].dispose();\n\t this.voices[i] = null;\n\t }\n\t this._writable('detune');\n\t this.detune.dispose();\n\t this.detune = null;\n\t this.voices = null;\n\t this._triggers = null;\n\t return this;\n\t };\n\t /**\n\t\t * The maximum number of notes that can be allocated\n\t\t * to a polysynth.\n\t\t * @type {Number}\n\t\t * @static\n\t\t */\n\t Tone.PolySynth.MAX_POLYPHONY = 20;\n\t return Tone.PolySynth;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Automatically interpolates between a set of pitched samples. Pass in an object which maps the note's pitch or midi value to the url, then you can trigger the attack and release of that note like other instruments. By automatically repitching the samples, it is possible to play pitches which were not explicitly included which can save loading time.\n\t\t * For sample or buffer playback where repitching is not necessary, use [Tone.Player](https://tonejs.github.io/docs/Player).\n\t\t * @param {Object} samples An object of samples mapping either Midi\n\t\t * Note Numbers or Scientific Pitch Notation\n\t\t * to the url of that sample.\n\t\t * @param {Function=} onload The callback to invoke when all of the samples are loaded.\n\t\t * @param {String=} baseUrl The root URL of all of the samples, which is prepended to all the URLs.\n\t\t * @example\n\t\t * var sampler = new Tone.Sampler({\n\t\t * \t\"C3\" : \"path/to/C3.mp3\",\n\t\t * \t\"D#3\" : \"path/to/Dsharp3.mp3\",\n\t\t * \t\"F#3\" : \"path/to/Fsharp3.mp3\",\n\t\t * \t\"A3\" : \"path/to/A3.mp3\",\n\t\t * }, function(){\n\t\t * \t//sampler will repitch the closest sample\n\t\t * \tsampler.triggerAttack(\"D3\")\n\t\t * })\n\t\t * @extends {Tone.Instrument}\n\t\t */\n\t Tone.Sampler = function (urls) {\n\t // shift arguments over one. Those are the remainder of the options\n\t var args = Array.prototype.slice.call(arguments);\n\t args.shift();\n\t var options = Tone.defaults(args, [\n\t 'onload',\n\t 'baseUrl'\n\t ], Tone.Sampler);\n\t Tone.Instrument.call(this, options);\n\t var urlMap = {};\n\t for (var note in urls) {\n\t if (Tone.isNote(note)) {\n\t //convert the note name to MIDI\n\t var mid = Tone.Frequency(note).toMidi();\n\t urlMap[mid] = urls[note];\n\t } else if (!isNaN(parseFloat(note))) {\n\t //otherwise if it's numbers assume it's midi\n\t urlMap[note] = urls[note];\n\t } else {\n\t throw new Error('Tone.Sampler: url keys must be the note\\'s pitch');\n\t }\n\t }\n\t /**\n\t\t\t * The stored and loaded buffers\n\t\t\t * @type {Tone.Buffers}\n\t\t\t * @private\n\t\t\t */\n\t this._buffers = new Tone.Buffers(urlMap, options.onload, options.baseUrl);\n\t /**\n\t\t\t * The object of all currently playing BufferSources\n\t\t\t * @type {Object}\n\t\t\t * @private\n\t\t\t */\n\t this._activeSources = {};\n\t /**\n\t\t\t * The envelope applied to the beginning of the sample.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.attack = options.attack;\n\t /**\n\t\t\t * The envelope applied to the end of the envelope.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.release = options.release;\n\t };\n\t Tone.extend(Tone.Sampler, Tone.Instrument);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Sampler.defaults = {\n\t attack: 0,\n\t release: 0.1,\n\t onload: Tone.noOp,\n\t baseUrl: ''\n\t };\n\t /**\n\t\t * Returns the difference in steps between the given midi note at the closets sample.\n\t\t * @param {Midi} midi\n\t\t * @return {Interval}\n\t\t * @private\n\t\t */\n\t Tone.Sampler.prototype._findClosest = function (midi) {\n\t //searches within 8 octaves of the given midi note\n\t var MAX_INTERVAL = 96;\n\t var interval = 0;\n\t while (interval < MAX_INTERVAL) {\n\t // check above and below\n\t if (this._buffers.has(midi + interval)) {\n\t return -interval;\n\t } else if (this._buffers.has(midi - interval)) {\n\t return interval;\n\t }\n\t interval++;\n\t }\n\t return null;\n\t };\n\t /**\n\t\t * @param {Frequency} note The note to play\n\t\t * @param {Time=} time When to play the note\n\t\t * @param {NormalRange=} velocity The velocity to play the sample back.\n\t\t * @return {Tone.Sampler} this\n\t\t */\n\t Tone.Sampler.prototype.triggerAttack = function (note, time, velocity) {\n\t var midi = Tone.Frequency(note).toMidi();\n\t // find the closest note pitch\n\t var difference = this._findClosest(midi);\n\t if (difference !== null) {\n\t var closestNote = midi - difference;\n\t var buffer = this._buffers.get(closestNote);\n\t // play that note\n\t var source = new Tone.BufferSource({\n\t 'buffer': buffer,\n\t 'playbackRate': Tone.intervalToFrequencyRatio(difference),\n\t 'fadeIn': this.attack,\n\t 'fadeOut': this.release,\n\t 'curve': 'exponential'\n\t }).connect(this.output);\n\t source.start(time, 0, buffer.duration, velocity);\n\t // add it to the active sources\n\t if (!Tone.isArray(this._activeSources[midi])) {\n\t this._activeSources[midi] = [];\n\t }\n\t this._activeSources[midi].push({\n\t note: midi,\n\t source: source\n\t });\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * @param {Frequency} note The note to release.\n\t\t * @param {Time=} time \tWhen to release the note.\n\t\t * @return {Tone.Sampler}\tthis\n\t\t */\n\t Tone.Sampler.prototype.triggerRelease = function (note, time) {\n\t var midi = Tone.Frequency(note).toMidi();\n\t // find the note\n\t if (this._activeSources[midi] && this._activeSources[midi].length) {\n\t var source = this._activeSources[midi].shift().source;\n\t time = this.toSeconds(time);\n\t source.stop(time + this.release, this.release);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Release all currently active notes.\n\t\t * @param {Time=} time \tWhen to release the notes.\n\t\t * @return {Tone.Sampler}\tthis\n\t\t */\n\t Tone.Sampler.prototype.releaseAll = function (time) {\n\t time = this.toSeconds(time);\n\t for (var note in this._activeSources) {\n\t var sources = this._activeSources[note];\n\t while (sources.length) {\n\t var source = sources.shift().source;\n\t source.stop(time + this.release, this.release);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Sync the instrument to the Transport. All subsequent calls of\n\t\t * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease)\n\t\t * will be scheduled along the transport.\n\t\t * @example\n\t\t * synth.sync()\n\t\t * //schedule 3 notes when the transport first starts\n\t\t * synth.triggerAttackRelease('8n', 0)\n\t\t * synth.triggerAttackRelease('8n', '8n')\n\t\t * synth.triggerAttackRelease('8n', '4n')\n\t\t * //start the transport to hear the notes\n\t\t * Transport.start()\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.Sampler.prototype.sync = function () {\n\t this._syncMethod('triggerAttack', 1);\n\t this._syncMethod('triggerRelease', 1);\n\t return this;\n\t };\n\t /**\n\t\t * Invoke the attack phase, then after the duration, invoke the release.\n\t\t * @param {Frequency} note The note to play\n\t\t * @param {Time} duration The time the note should be held\n\t\t * @param {Time=} time When to start the attack\n\t\t * @param {NormalRange} [velocity=1] The velocity of the attack\n\t\t * @return {Tone.Sampler} this\n\t\t */\n\t Tone.Sampler.prototype.triggerAttackRelease = function (note, duration, time, velocity) {\n\t time = this.toSeconds(time);\n\t duration = this.toSeconds(duration);\n\t this.triggerAttack(note, time, velocity);\n\t this.triggerRelease(note, time + duration);\n\t return this;\n\t };\n\t /**\n\t\t * Add a note to the sampler.\n\t\t * @param {Note|Midi} note The buffer's pitch.\n\t\t * @param {String|Tone.Buffer|Audiobuffer} url Either the url of the bufer,\n\t\t * or a buffer which will be added\n\t\t * with the given name.\n\t\t * @param {Function=} callback The callback to invoke\n\t\t * when the url is loaded.\n\t\t */\n\t Tone.Sampler.prototype.add = function (note, url, callback) {\n\t if (Tone.isNote(note)) {\n\t //convert the note name to MIDI\n\t var mid = Tone.Frequency(note).toMidi();\n\t this._buffers.add(mid, url, callback);\n\t } else if (!isNaN(parseFloat(note))) {\n\t //otherwise if it's numbers assume it's midi\n\t this._buffers.add(note, url, callback);\n\t } else {\n\t throw new Error('Tone.Sampler: note must be the note\\'s pitch. Instead got ' + note);\n\t }\n\t };\n\t /**\n\t\t * If the buffers are loaded or not\n\t\t * @memberOf Tone.Sampler#\n\t\t * @type {Boolean}\n\t\t * @name loaded\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Sampler.prototype, 'loaded', {\n\t get: function () {\n\t return this._buffers.loaded;\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Sampler} this\n\t\t */\n\t Tone.Sampler.prototype.dispose = function () {\n\t Tone.Instrument.prototype.dispose.call(this);\n\t this._buffers.dispose();\n\t this._buffers = null;\n\t for (var midi in this._activeSources) {\n\t this._activeSources[midi].forEach(function (event) {\n\t event.source.dispose();\n\t });\n\t }\n\t this._activeSources = null;\n\t return this;\n\t };\n\t return Tone.Sampler;\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported) {\n\t if (!OscillatorNode.prototype.setPeriodicWave) {\n\t OscillatorNode.prototype.setPeriodicWave = OscillatorNode.prototype.setWaveTable;\n\t }\n\t if (!AudioContext.prototype.createPeriodicWave) {\n\t AudioContext.prototype.createPeriodicWave = AudioContext.prototype.createWaveTable;\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Maps a NormalRange [0, 1] to an AudioRange [-1, 1]. \n\t\t * See also Tone.AudioToGain. \n\t\t *\n\t\t * @extends {Tone.SignalBase}\n\t\t * @constructor\n\t\t * @example\n\t\t * var g2a = new Tone.GainToAudio();\n\t\t */\n\t Tone.GainToAudio = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * @type {WaveShaperNode}\n\t\t\t * @private\n\t\t\t */\n\t this._norm = this.input = this.output = new Tone.WaveShaper(function (x) {\n\t return Math.abs(x) * 2 - 1;\n\t });\n\t };\n\t Tone.extend(Tone.GainToAudio, Tone.SignalBase);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.GainToAudio} this\n\t\t */\n\t Tone.GainToAudio.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._norm.dispose();\n\t this._norm = null;\n\t return this;\n\t };\n\t return Tone.GainToAudio;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Normalize takes an input min and max and maps it linearly to NormalRange [0,1]\n\t\t *\n\t\t * @extends {Tone.SignalBase}\n\t\t * @constructor\n\t\t * @param {number} inputMin the min input value\n\t\t * @param {number} inputMax the max input value\n\t\t * @example\n\t\t * var norm = new Tone.Normalize(2, 4);\n\t\t * var sig = new Tone.Signal(3).connect(norm);\n\t\t * //output of norm is 0.5. \n\t\t */\n\t Tone.Normalize = function (inputMin, inputMax) {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * the min input value\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._inputMin = Tone.defaultArg(inputMin, 0);\n\t /**\n\t\t\t * the max input value\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._inputMax = Tone.defaultArg(inputMax, 1);\n\t /**\n\t\t\t * subtract the min from the input\n\t\t\t * @type {Tone.Add}\n\t\t\t * @private\n\t\t\t */\n\t this._sub = this.input = new Tone.Add(0);\n\t /**\n\t\t\t * divide by the difference between the input and output\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._div = this.output = new Tone.Multiply(1);\n\t this._sub.connect(this._div);\n\t this._setRange();\n\t };\n\t Tone.extend(Tone.Normalize, Tone.SignalBase);\n\t /**\n\t\t * The minimum value the input signal will reach.\n\t\t * @memberOf Tone.Normalize#\n\t\t * @type {number}\n\t\t * @name min\n\t\t */\n\t Object.defineProperty(Tone.Normalize.prototype, 'min', {\n\t get: function () {\n\t return this._inputMin;\n\t },\n\t set: function (min) {\n\t this._inputMin = min;\n\t this._setRange();\n\t }\n\t });\n\t /**\n\t\t * The maximum value the input signal will reach.\n\t\t * @memberOf Tone.Normalize#\n\t\t * @type {number}\n\t\t * @name max\n\t\t */\n\t Object.defineProperty(Tone.Normalize.prototype, 'max', {\n\t get: function () {\n\t return this._inputMax;\n\t },\n\t set: function (max) {\n\t this._inputMax = max;\n\t this._setRange();\n\t }\n\t });\n\t /**\n\t\t * set the values\n\t\t * @private\n\t\t */\n\t Tone.Normalize.prototype._setRange = function () {\n\t this._sub.value = -this._inputMin;\n\t this._div.value = 1 / (this._inputMax - this._inputMin);\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Normalize} this\n\t\t */\n\t Tone.Normalize.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._sub.dispose();\n\t this._sub = null;\n\t this._div.dispose();\n\t this._div = null;\n\t return this;\n\t };\n\t return Tone.Normalize;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.TransportTimelineSignal extends Tone.Signal, but adds the ability to synchronize the signal to the signal to the Tone.Transport\n\t\t * @extends {Tone.Signal}\n\t\t */\n\t Tone.TransportTimelineSignal = function () {\n\t Tone.Signal.apply(this, arguments);\n\t /**\n\t\t\t * The real signal output\n\t\t\t * @type {Tone.Signal}\n\t\t\t * @private\n\t\t\t */\n\t this.output = this._outputSig = new Tone.Signal(this._initialValue);\n\t /**\n\t\t\t * Keep track of the last value. (small optimization)\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._lastVal = this.value;\n\t /**\n\t\t\t * The event id of the tick update loop\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._synced = Tone.Transport.scheduleRepeat(this._onTick.bind(this), '1i');\n\t /**\n\t\t\t * A bound version of the anchor value methods\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._bindAnchorValue = this._anchorValue.bind(this);\n\t Tone.Transport.on('start stop pause', this._bindAnchorValue);\n\t this._events.memory = Infinity;\n\t };\n\t Tone.extend(Tone.TransportTimelineSignal, Tone.Signal);\n\t /**\n\t\t * Callback which is invoked every tick.\n\t\t * @private\n\t\t * @param {Number} time\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype._onTick = function (time) {\n\t var val = this.getValueAtTime(Tone.Transport.seconds);\n\t if (this._lastVal !== val) {\n\t this._lastVal = val;\n\t //approximate ramp curves with linear ramps\n\t this._outputSig.linearRampToValueAtTime(val, time);\n\t }\n\t };\n\t /**\n\t\t * Anchor the value at the start and stop of the Transport\n\t\t * @param {Number} time The time of the event\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t * @private\n\t\t */\n\t Tone.TransportTimelineSignal.prototype._anchorValue = function (time) {\n\t var val = this.getValueAtTime(Tone.Transport.seconds);\n\t this._lastVal = val;\n\t this._outputSig.cancelScheduledValues(time);\n\t this._outputSig.setValueAtTime(val, time);\n\t return this;\n\t };\n\t /**\n\t\t * Get the scheduled value at the given time. This will\n\t\t * return the unconverted (raw) value.\n\t\t * @param {TransportTime} time The time in seconds.\n\t\t * @return {Number} The scheduled value at the given time.\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.getValueAtTime = function (time) {\n\t time = Tone.TransportTime(time);\n\t return Tone.Signal.prototype.getValueAtTime.call(this, time);\n\t };\n\t /**\n\t\t * Set the output of the signal at the given time\n\t\t * @param {Number} value The value to change to at the given time\n\t\t * @param {TransportTime} time The time to change the signal\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.setValueAtTime = function (value, time) {\n\t time = Tone.TransportTime(time);\n\t Tone.Signal.prototype.setValueAtTime.call(this, value, time);\n\t return this;\n\t };\n\t /**\n\t\t * Linear ramp to the given value from the previous scheduled point to the given value\n\t\t * @param {Number} value The value to change to at the given time\n\t\t * @param {TransportTime} time The time to change the signal\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.linearRampToValueAtTime = function (value, time) {\n\t time = Tone.TransportTime(time);\n\t Tone.Signal.prototype.linearRampToValueAtTime.call(this, value, time);\n\t return this;\n\t };\n\t /**\n\t\t * Exponential ramp to the given value from the previous scheduled point to the given value\n\t\t * @param {Number} value The value to change to at the given time\n\t\t * @param {TransportTime} time The time to change the signal\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.exponentialRampToValueAtTime = function (value, time) {\n\t time = Tone.TransportTime(time);\n\t Tone.Signal.prototype.exponentialRampToValueAtTime.call(this, value, time);\n\t return this;\n\t };\n\t /**\n\t\t * Start exponentially approaching the target value at the given time with\n\t\t * a rate having the given time constant.\n\t\t * @param {number} value\n\t\t * @param {TransportTime} startTime\n\t\t * @param {number} timeConstant\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t startTime = Tone.TransportTime(startTime);\n\t Tone.Signal.prototype.setTargetAtTime.call(this, value, startTime, timeConstant);\n\t return this;\n\t };\n\t /**\n\t\t * Cancels all scheduled parameter changes with times greater than or\n\t\t * equal to startTime.\n\t\t * @param {TransportTime} startTime\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.cancelScheduledValues = function (startTime) {\n\t startTime = Tone.TransportTime(startTime);\n\t Tone.Signal.prototype.cancelScheduledValues.call(this, startTime);\n\t return this;\n\t };\n\t /**\n\t\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t\t * @param {Float32Array} values\n\t\t * @param {Time} startTime\n\t\t * @param {Time} duration\n\t\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t\t * @returns {Tone.Signal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t startTime = Tone.TransportTime(startTime);\n\t duration = Tone.TransportTime(duration);\n\t Tone.Signal.prototype.setValueCurveAtTime.call(this, values, startTime, duration, scaling);\n\t return this;\n\t };\n\t /**\n\t\t * This is similar to [cancelScheduledValues](#cancelScheduledValues) except\n\t\t * it holds the automated value at time until the next automated event.\n\t\t * @param {Time} time\n\t\t * @returns {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.cancelAndHoldAtTime = function (time) {\n\t return Tone.Signal.prototype.cancelAndHoldAtTime.call(this, Tone.TransportTime(time));\n\t };\n\t /**\n\t\t * Dispose and disconnect\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.dispose = function () {\n\t Tone.Transport.clear(this._synced);\n\t Tone.Transport.off('start stop pause', this._syncedCallback);\n\t this._events.cancel(0);\n\t Tone.Signal.prototype.dispose.call(this);\n\t this._outputSig.dispose();\n\t this._outputSig = null;\n\t };\n\t return Tone.TransportTimelineSignal;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.GrainPlayer implements [granular synthesis](https://en.wikipedia.org/wiki/Granular_synthesis).\n\t\t * Granular Synthesis enables you to adjust pitch and playback rate independently. The grainSize is the\n\t\t * amount of time each small chunk of audio is played for and the overlap is the\n\t\t * amount of crossfading transition time between successive grains.\n\t\t * @extends {Tone.Source}\n\t\t * @param {String|Tone.Buffer} url\tThe url to load, or the Tone.Buffer to play.\n\t\t * @param {Function=} callback The callback to invoke after the url is loaded.\n\t\t */\n\t Tone.GrainPlayer = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'url',\n\t 'onload'\n\t ], Tone.GrainPlayer);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * The audio buffer belonging to the player.\n\t\t\t * @type {Tone.Buffer}\n\t\t\t */\n\t this.buffer = new Tone.Buffer(options.url, options.onload);\n\t /**\n\t\t\t * Create a repeating tick to schedule\n\t\t\t * the grains.\n\t\t\t * @type {Tone.Clock}\n\t\t\t * @private\n\t\t\t */\n\t this._clock = new Tone.Clock(this._tick.bind(this), options.grainSize);\n\t /**\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._loopStart = 0;\n\t /**\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._loopEnd = 0;\n\t /**\n\t\t\t * All of the currently playing BufferSources\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._activeSources = [];\n\t /**\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._playbackRate = options.playbackRate;\n\t /**\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._grainSize = options.grainSize;\n\t /**\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._overlap = options.overlap;\n\t /**\n\t\t\t * Adjust the pitch independently of the playbackRate.\n\t\t\t * @type {Cents}\n\t\t\t */\n\t this.detune = options.detune;\n\t //setup\n\t this.overlap = options.overlap;\n\t this.loop = options.loop;\n\t this.playbackRate = options.playbackRate;\n\t this.grainSize = options.grainSize;\n\t this.loopStart = options.loopStart;\n\t this.loopEnd = options.loopEnd;\n\t this.reverse = options.reverse;\n\t this._clock.on('stop', this._onstop.bind(this));\n\t };\n\t Tone.extend(Tone.GrainPlayer, Tone.Source);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.GrainPlayer.defaults = {\n\t 'onload': Tone.noOp,\n\t 'overlap': 0.1,\n\t 'grainSize': 0.2,\n\t 'playbackRate': 1,\n\t 'detune': 0,\n\t 'loop': false,\n\t 'loopStart': 0,\n\t 'loopEnd': 0,\n\t 'reverse': false\n\t };\n\t /**\n\t\t * Play the buffer at the given startTime. Optionally add an offset\n\t\t * and/or duration which will play the buffer from a position\n\t\t * within the buffer for the given duration.\n\t\t *\n\t\t * @param {Time} [startTime=now] When the player should start.\n\t\t * @param {Time} [offset=0] The offset from the beginning of the sample\n\t\t * to start at.\n\t\t * @param {Time=} duration How long the sample should play. If no duration\n\t\t * is given, it will default to the full length\n\t\t * of the sample (minus any offset)\n\t\t * @returns {Tone.GrainPlayer} this\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @method start\n\t\t * @name start\n\t\t */\n\t /**\n\t\t * Internal start method\n\t\t * @param {Time} time\n\t\t * @param {Time} offset\n\t\t * @private\n\t\t */\n\t Tone.GrainPlayer.prototype._start = function (time, offset, duration) {\n\t offset = Tone.defaultArg(offset, 0);\n\t offset = this.toSeconds(offset);\n\t time = this.toSeconds(time);\n\t this._offset = offset;\n\t this._clock.start(time);\n\t if (duration) {\n\t this.stop(time + this.toSeconds(duration));\n\t }\n\t };\n\t /**\n\t\t * Internal start method\n\t\t * @param {Time} time\n\t\t * @private\n\t\t */\n\t Tone.GrainPlayer.prototype._stop = function (time) {\n\t this._clock.stop(time);\n\t };\n\t /**\n\t\t * Invoked when the clock is stopped\n\t\t * @param {Number} time\n\t\t * @private\n\t\t */\n\t Tone.GrainPlayer.prototype._onstop = function (time) {\n\t //stop the players\n\t this._activeSources.forEach(function (source) {\n\t source.stop(time, 0);\n\t });\n\t };\n\t /**\n\t\t * Invoked on each clock tick. scheduled a new\n\t\t * grain at this time.\n\t\t * @param {Time} time\n\t\t * @private\n\t\t */\n\t Tone.GrainPlayer.prototype._tick = function (time) {\n\t var fadeIn = this._offset < this._overlap ? 0 : this._overlap;\n\t var source = new Tone.BufferSource({\n\t 'buffer': this.buffer,\n\t 'fadeIn': fadeIn,\n\t 'fadeOut': this._overlap,\n\t 'loop': this.loop,\n\t 'loopStart': this._loopStart,\n\t 'loopEnd': this._loopEnd,\n\t 'playbackRate': Tone.intervalToFrequencyRatio(this.detune / 100)\n\t }).connect(this.output);\n\t source.start(time, this._offset);\n\t this._offset += this.grainSize;\n\t source.stop(time + this.grainSize);\n\t //add it to the active sources\n\t this._activeSources.push(source);\n\t //remove it when it's done\n\t source.onended = function () {\n\t var index = this._activeSources.indexOf(source);\n\t if (index !== -1) {\n\t this._activeSources.splice(index, 1);\n\t }\n\t }.bind(this);\n\t };\n\t /**\n\t\t * Jump to a specific time and play it.\n\t\t * @param {Time} offset The offset to jump to.\n\t\t * @param {Time=} time When to make the jump.\n\t\t * @return {Tone.GrainPlayer} this\n\t\t */\n\t Tone.GrainPlayer.prototype.seek = function (offset, time) {\n\t this._offset = this.toSeconds(offset);\n\t this._tick(this.toSeconds(time));\n\t return this;\n\t };\n\t /**\n\t\t * The playback rate of the sample\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @type {Positive}\n\t\t * @name playbackRate\n\t\t */\n\t Object.defineProperty(Tone.GrainPlayer.prototype, 'playbackRate', {\n\t get: function () {\n\t return this._playbackRate;\n\t },\n\t set: function (rate) {\n\t this._playbackRate = rate;\n\t this.grainSize = this._grainSize;\n\t }\n\t });\n\t /**\n\t\t * The loop start time.\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @type {Time}\n\t\t * @name loopStart\n\t\t */\n\t Object.defineProperty(Tone.GrainPlayer.prototype, 'loopStart', {\n\t get: function () {\n\t return this._loopStart;\n\t },\n\t set: function (time) {\n\t this._loopStart = this.toSeconds(time);\n\t }\n\t });\n\t /**\n\t\t * The loop end time.\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @type {Time}\n\t\t * @name loopEnd\n\t\t */\n\t Object.defineProperty(Tone.GrainPlayer.prototype, 'loopEnd', {\n\t get: function () {\n\t return this._loopEnd;\n\t },\n\t set: function (time) {\n\t this._loopEnd = this.toSeconds(time);\n\t }\n\t });\n\t /**\n\t\t * The direction the buffer should play in\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @type {boolean}\n\t\t * @name reverse\n\t\t */\n\t Object.defineProperty(Tone.GrainPlayer.prototype, 'reverse', {\n\t get: function () {\n\t return this.buffer.reverse;\n\t },\n\t set: function (rev) {\n\t this.buffer.reverse = rev;\n\t }\n\t });\n\t /**\n\t\t * The size of each chunk of audio that the\n\t\t * buffer is chopped into and played back at.\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @type {Time}\n\t\t * @name grainSize\n\t\t */\n\t Object.defineProperty(Tone.GrainPlayer.prototype, 'grainSize', {\n\t get: function () {\n\t return this._grainSize;\n\t },\n\t set: function (size) {\n\t this._grainSize = this.toSeconds(size);\n\t this._clock.frequency.value = this._playbackRate / this._grainSize;\n\t }\n\t });\n\t /**\n\t\t * This is the duration of the cross-fade between\n\t\t * sucessive grains.\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @type {Time}\n\t\t * @name overlap\n\t\t */\n\t Object.defineProperty(Tone.GrainPlayer.prototype, 'overlap', {\n\t get: function () {\n\t return this._overlap;\n\t },\n\t set: function (time) {\n\t this._overlap = this.toSeconds(time);\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.GrainPlayer} this\n\t\t */\n\t Tone.GrainPlayer.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this.buffer.dispose();\n\t this.buffer = null;\n\t this._clock.dispose();\n\t this._clock = null;\n\t this._activeSources.forEach(function (source) {\n\t source.dispose();\n\t });\n\t this._activeSources = null;\n\t return this;\n\t };\n\t return Tone.GrainPlayer;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Player is an audio file player with start, loop, and stop functions.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Source}\n\t\t * @param {string|AudioBuffer} url Either the AudioBuffer or the url from\n\t\t * which to load the AudioBuffer\n\t\t * @param {Function=} onload The function to invoke when the buffer is loaded.\n\t\t * Recommended to use Tone.Buffer.on('load') instead.\n\t\t * @example\n\t\t * var player = new Tone.Player(\"./path/to/sample.mp3\").toMaster();\n\t\t * //play as soon as the buffer is loaded\n\t\t * player.autostart = true;\n\t\t */\n\t Tone.Player = function (url) {\n\t var options;\n\t if (url instanceof Tone.Buffer && url.loaded) {\n\t url = url.get();\n\t options = Tone.Player.defaults;\n\t } else {\n\t options = Tone.defaults(arguments, [\n\t 'url',\n\t 'onload'\n\t ], Tone.Player);\n\t }\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * If the file should play as soon\n\t\t\t * as the buffer is loaded.\n\t\t\t * @type {Boolean}\n\t\t\t * @example\n\t\t\t * //will play as soon as it's loaded\n\t\t\t * var player = new Tone.Player({\n\t\t\t * \t\"url\" : \"./path/to/sample.mp3\",\n\t\t\t * \t\"autostart\" : true,\n\t\t\t * }).toMaster();\n\t\t\t */\n\t this.autostart = options.autostart;\n\t /**\n\t\t\t * the buffer\n\t\t\t * @private\n\t\t\t * @type {Tone.Buffer}\n\t\t\t */\n\t this._buffer = new Tone.Buffer({\n\t 'url': options.url,\n\t 'onload': this._onload.bind(this, options.onload),\n\t 'reverse': options.reverse\n\t });\n\t if (url instanceof AudioBuffer) {\n\t this._buffer.set(url);\n\t }\n\t /**\n\t\t\t * if the buffer should loop once it's over\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t this._loop = options.loop;\n\t /**\n\t\t\t * if 'loop' is true, the loop will start at this position\n\t\t\t * @type {Time}\n\t\t\t * @private\n\t\t\t */\n\t this._loopStart = options.loopStart;\n\t /**\n\t\t\t * if 'loop' is true, the loop will end at this position\n\t\t\t * @type {Time}\n\t\t\t * @private\n\t\t\t */\n\t this._loopEnd = options.loopEnd;\n\t /**\n\t\t\t * the playback rate\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._playbackRate = options.playbackRate;\n\t /**\n\t\t\t * All of the active buffer source nodes\n\t\t\t * @type {Array<Tone.BufferSource>}\n\t\t\t * @private\n\t\t\t */\n\t this._activeSources = [];\n\t /**\n\t\t\t * The elapsed time counter.\n\t\t\t * @type {Tone.TickSource}\n\t\t\t * @private\n\t\t\t */\n\t this._elapsedTime = new Tone.TickSource(options.playbackRate);\n\t /**\n\t\t\t * The fadeIn time of the amplitude envelope.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.fadeIn = options.fadeIn;\n\t /**\n\t\t\t * The fadeOut time of the amplitude envelope.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.fadeOut = options.fadeOut;\n\t };\n\t Tone.extend(Tone.Player, Tone.Source);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Player.defaults = {\n\t 'onload': Tone.noOp,\n\t 'playbackRate': 1,\n\t 'loop': false,\n\t 'autostart': false,\n\t 'loopStart': 0,\n\t 'loopEnd': 0,\n\t 'retrigger': false,\n\t 'reverse': false,\n\t 'fadeIn': 0,\n\t 'fadeOut': 0\n\t };\n\t /**\n\t\t * Load the audio file as an audio buffer.\n\t\t * Decodes the audio asynchronously and invokes\n\t\t * the callback once the audio buffer loads.\n\t\t * Note: this does not need to be called if a url\n\t\t * was passed in to the constructor. Only use this\n\t\t * if you want to manually load a new url.\n\t\t * @param {string} url The url of the buffer to load.\n\t\t * Filetype support depends on the\n\t\t * browser.\n\t\t * @param {Function=} callback The function to invoke once\n\t\t * the sample is loaded.\n\t\t * @returns {Promise}\n\t\t */\n\t Tone.Player.prototype.load = function (url, callback) {\n\t return this._buffer.load(url, this._onload.bind(this, callback));\n\t };\n\t /**\n\t\t * Internal callback when the buffer is loaded.\n\t\t * @private\n\t\t */\n\t Tone.Player.prototype._onload = function (callback) {\n\t callback = Tone.defaultArg(callback, Tone.noOp);\n\t callback(this);\n\t if (this.autostart) {\n\t this.start();\n\t }\n\t };\n\t /**\n\t\t * Internal callback when the buffer is done playing.\n\t\t * @private\n\t\t */\n\t Tone.Player.prototype._onSourceEnd = function (source) {\n\t var index = this._activeSources.indexOf(source);\n\t this._activeSources.splice(index, 1);\n\t };\n\t /**\n\t\t * Play the buffer at the given startTime. Optionally add an offset\n\t\t * and/or duration which will play the buffer from a position\n\t\t * within the buffer for the given duration.\n\t\t *\n\t\t * @param {Time} [startTime=now] When the player should start.\n\t\t * @param {Time} [offset=0] The offset from the beginning of the sample\n\t\t * to start at.\n\t\t * @param {Time=} duration How long the sample should play. If no duration\n\t\t * is given, it will default to the full length\n\t\t * of the sample (minus any offset)\n\t\t * @returns {Tone.Player} this\n\t\t * @memberOf Tone.Player#\n\t\t * @method start\n\t\t * @name start\n\t\t */\n\t /**\n\t\t * Internal start method\n\t\t * @private\n\t\t */\n\t Tone.Player.prototype._start = function (startTime, offset, duration) {\n\t //if it's a loop the default offset is the loopstart point\n\t if (this._loop) {\n\t offset = Tone.defaultArg(offset, this._loopStart);\n\t } else {\n\t //otherwise the default offset is 0\n\t offset = Tone.defaultArg(offset, 0);\n\t }\n\t //compute the values in seconds\n\t offset = this.toSeconds(offset);\n\t var computedDuration = Tone.defaultArg(duration, Math.max(this._buffer.duration - offset, 0));\n\t computedDuration = this.toSeconds(computedDuration);\n\t startTime = this.toSeconds(startTime);\n\t //start the elapsed time counter\n\t this._elapsedTime.start(startTime, offset);\n\t //make the source\n\t var source = new Tone.BufferSource({\n\t 'buffer': this._buffer,\n\t 'loop': this._loop,\n\t 'loopStart': this._loopStart,\n\t 'loopEnd': this._loopEnd,\n\t 'onended': this._onSourceEnd.bind(this),\n\t 'playbackRate': this._playbackRate,\n\t 'fadeIn': this.fadeIn,\n\t 'fadeOut': this.fadeOut\n\t }).connect(this.output);\n\t //set the looping properties\n\t if (!this._loop && !this._synced) {\n\t //if it's not looping, set the state change at the end of the sample\n\t this._state.setStateAtTime(Tone.State.Stopped, startTime + computedDuration / this._playbackRate);\n\t }\n\t //add it to the array of active sources\n\t this._activeSources.push(source);\n\t //start it\n\t if (this._loop && Tone.isUndef(duration)) {\n\t source.start(startTime, offset);\n\t } else {\n\t source.start(startTime, offset, computedDuration);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Stop playback.\n\t\t * @private\n\t\t * @param {Time} [time=now]\n\t\t * @returns {Tone.Player} this\n\t\t */\n\t Tone.Player.prototype._stop = function (time) {\n\t time = this.toSeconds(time);\n\t this._elapsedTime.stop(time);\n\t this._activeSources.forEach(function (source) {\n\t source.stop(time);\n\t });\n\t return this;\n\t };\n\t /**\n\t\t * Stop and then restart the player from the beginning (or offset)\n\t\t * @param {Time} [startTime=now] When the player should start.\n\t\t * @param {Time} [offset=0] The offset from the beginning of the sample\n\t\t * to start at.\n\t\t * @param {Time=} duration How long the sample should play. If no duration\n\t\t * is given, it will default to the full length\n\t\t * of the sample (minus any offset)\n\t\t * @returns {Tone.Player} this\n\t\t */\n\t Tone.Player.prototype.restart = function (time, offset, duration) {\n\t this._stop(time);\n\t this._start(time, offset, duration);\n\t return this;\n\t };\n\t /**\n\t\t * Seek to a specific time in the player's buffer. If the\n\t\t * source is no longer playing at that time, it will stop.\n\t\t * If you seek to a time that\n\t\t * @param {Time} offset The time to seek to.\n\t\t * @param {Time=} time The time for the seek event to occur.\n\t\t * @return {Tone.Player} this\n\t\t * @example\n\t\t * source.start(0.2);\n\t\t * source.stop(0.4);\n\t\t */\n\t Tone.Player.prototype.seek = function (offset, time) {\n\t time = this.toSeconds(time);\n\t if (this._state.getValueAtTime(time) === Tone.State.Started) {\n\t offset = this.toSeconds(offset);\n\t // if it's currently playing, stop it\n\t this._stop(time);\n\t //restart it at the given time\n\t this._start(time, offset);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Set the loop start and end. Will only loop if loop is\n\t\t * set to true.\n\t\t * @param {Time} loopStart The loop end time\n\t\t * @param {Time} loopEnd The loop end time\n\t\t * @returns {Tone.Player} this\n\t\t * @example\n\t\t * //loop 0.1 seconds of the file.\n\t\t * player.setLoopPoints(0.2, 0.3);\n\t\t * player.loop = true;\n\t\t */\n\t Tone.Player.prototype.setLoopPoints = function (loopStart, loopEnd) {\n\t this.loopStart = loopStart;\n\t this.loopEnd = loopEnd;\n\t return this;\n\t };\n\t /**\n\t\t * If loop is true, the loop will start at this position.\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Time}\n\t\t * @name loopStart\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'loopStart', {\n\t get: function () {\n\t return this._loopStart;\n\t },\n\t set: function (loopStart) {\n\t this._loopStart = loopStart;\n\t //get the current source\n\t this._activeSources.forEach(function (source) {\n\t source.loopStart = loopStart;\n\t });\n\t }\n\t });\n\t /**\n\t\t * If loop is true, the loop will end at this position.\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Time}\n\t\t * @name loopEnd\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'loopEnd', {\n\t get: function () {\n\t return this._loopEnd;\n\t },\n\t set: function (loopEnd) {\n\t this._loopEnd = loopEnd;\n\t //get the current source\n\t this._activeSources.forEach(function (source) {\n\t source.loopEnd = loopEnd;\n\t });\n\t }\n\t });\n\t /**\n\t\t * The audio buffer belonging to the player.\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Tone.Buffer}\n\t\t * @name buffer\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'buffer', {\n\t get: function () {\n\t return this._buffer;\n\t },\n\t set: function (buffer) {\n\t this._buffer.set(buffer);\n\t }\n\t });\n\t /**\n\t\t * If the buffer should loop once it's over.\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Boolean}\n\t\t * @name loop\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'loop', {\n\t get: function () {\n\t return this._loop;\n\t },\n\t set: function (loop) {\n\t //if no change, do nothing\n\t if (this._loop === loop) {\n\t return;\n\t }\n\t this._loop = loop;\n\t var now = this.now();\n\t if (!loop) {\n\t //stop the playback on the next cycle\n\t this._stopAtNextIteration(now);\n\t } else {\n\t //remove the next stopEvent\n\t var stopEvent = this._state.getNextState(Tone.State.Stopped, now);\n\t if (stopEvent) {\n\t this._activeSources.forEach(function (source) {\n\t source.loop = loop;\n\t });\n\t this._state.cancel(stopEvent.time);\n\t this._elapsedTime.cancel(stopEvent.time);\n\t }\n\t }\n\t }\n\t });\n\t /**\n\t\t * Schedules a stop event at the next full iteration. Used\n\t\t * for scheduling stop when the loop state or playbackRate changes\n\t\t * @param {Number} now The current time\n\t\t * @private\n\t\t */\n\t Tone.Player.prototype._stopAtNextIteration = function (now) {\n\t if (this._state.getValueAtTime(now) === Tone.State.Started) {\n\t var nextStop = this._state.getNextState(Tone.State.Stopped, now);\n\t var position = this._elapsedTime.getTicksAtTime(now);\n\t var iterations = Math.max(Math.ceil(position / this.buffer.duration), 1);\n\t var stopTime = this._elapsedTime.getTimeOfTick(iterations * this.buffer.duration, nextStop ? nextStop.time - this.sampleTime : Infinity);\n\t this.stop(stopTime);\n\t }\n\t };\n\t /**\n\t\t * The playback speed. 1 is normal speed. This is not a signal because\n\t\t * Safari and iOS currently don't support playbackRate as a signal.\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Number}\n\t\t * @name playbackRate\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'playbackRate', {\n\t get: function () {\n\t return this._playbackRate;\n\t },\n\t set: function (rate) {\n\t this._playbackRate = rate;\n\t var now = this.now();\n\t this._elapsedTime.frequency.setValueAtTime(rate, now);\n\t //if it's not looping\n\t if (!this._loop) {\n\t this._stopAtNextIteration(now);\n\t }\n\t //set all the sources\n\t this._activeSources.forEach(function (source) {\n\t source.playbackRate.setValueAtTime(rate, now);\n\t });\n\t }\n\t });\n\t /**\n\t\t * The current playback position of the buffer. \n\t\t * @memberOf Tone.Player#\n\t\t * @type {Number}\n\t\t * @name position\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'position', {\n\t get: function () {\n\t var now = this.now();\n\t if (this._state.getValueAtTime(now) === Tone.State.Started && this.loaded) {\n\t var duration = this.buffer.duration;\n\t var position = this._elapsedTime.getTicksAtTime(now);\n\t return position % duration;\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The direction the buffer should play in\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Boolean}\n\t\t * @name reverse\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'reverse', {\n\t get: function () {\n\t return this._buffer.reverse;\n\t },\n\t set: function (rev) {\n\t this._buffer.reverse = rev;\n\t }\n\t });\n\t /**\n\t\t * If all the buffer is loaded\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Boolean}\n\t\t * @name loaded\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'loaded', {\n\t get: function () {\n\t return this._buffer.loaded;\n\t }\n\t });\n\t /**\n\t\t * Dispose and disconnect.\n\t\t * @return {Tone.Player} this\n\t\t */\n\t Tone.Player.prototype.dispose = function () {\n\t //disconnect all of the players\n\t this._activeSources.forEach(function (source) {\n\t source.dispose();\n\t });\n\t this._activeSources = null;\n\t Tone.Source.prototype.dispose.call(this);\n\t this._buffer.dispose();\n\t this._buffer = null;\n\t this._elapsedTime.dispose();\n\t this._elapsedTime = null;\n\t return this;\n\t };\n\t return Tone.Player;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Players combines multiple [Tone.Player](Player) objects.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Object} urls An object mapping a name to a url.\n\t\t * @param {function=} onload The function to invoke when all buffers are loaded.\n\t\t */\n\t Tone.Players = function (urls) {\n\t var args = Array.prototype.slice.call(arguments);\n\t args.shift();\n\t var options = Tone.defaults(args, ['onload'], Tone.Players);\n\t Tone.call(this);\n\t /**\n\t\t\t * The output volume node\n\t\t\t * @type {Tone.Volume}\n\t\t\t * @private\n\t\t\t */\n\t this._volume = this.output = new Tone.Volume(options.volume);\n\t /**\n\t\t\t * The volume of the output in decibels.\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * source.volume.value = -6;\n\t\t\t */\n\t this.volume = this._volume.volume;\n\t this._readOnly('volume');\n\t //make the output explicitly stereo\n\t this._volume.output.output.channelCount = 2;\n\t this._volume.output.output.channelCountMode = 'explicit';\n\t //mute initially\n\t this.mute = options.mute;\n\t /**\n\t\t\t * The container of all of the players\n\t\t\t * @type {Object}\n\t\t\t * @private\n\t\t\t */\n\t this._players = {};\n\t /**\n\t\t\t * The loading count\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._loadingCount = 0;\n\t /**\n\t\t\t * private holder of the fadeIn time\n\t\t\t * @type {Time}\n\t\t\t * @private\n\t\t\t */\n\t this._fadeIn = options.fadeIn;\n\t /**\n\t\t\t * private holder of the fadeOut time\n\t\t\t * @type {Time}\n\t\t\t * @private\n\t\t\t */\n\t this._fadeOut = options.fadeOut;\n\t //add all of the players\n\t for (var name in urls) {\n\t this._loadingCount++;\n\t this.add(name, urls[name], this._bufferLoaded.bind(this, options.onload));\n\t }\n\t };\n\t Tone.extend(Tone.Players, Tone.AudioNode);\n\t /**\n\t\t * The default values\n\t\t * @type {Object}\n\t\t */\n\t Tone.Players.defaults = {\n\t 'volume': 0,\n\t 'mute': false,\n\t 'onload': Tone.noOp,\n\t 'fadeIn': 0,\n\t 'fadeOut': 0\n\t };\n\t /**\n\t\t * A buffer was loaded. decrement the counter.\n\t\t * @param {Function} callback\n\t\t * @private\n\t\t */\n\t Tone.Players.prototype._bufferLoaded = function (callback) {\n\t this._loadingCount--;\n\t if (this._loadingCount === 0 && callback) {\n\t callback(this);\n\t }\n\t };\n\t /**\n\t\t * Mute the output.\n\t\t * @memberOf Tone.Source#\n\t\t * @type {boolean}\n\t\t * @name mute\n\t\t * @example\n\t\t * //mute the output\n\t\t * source.mute = true;\n\t\t */\n\t Object.defineProperty(Tone.Players.prototype, 'mute', {\n\t get: function () {\n\t return this._volume.mute;\n\t },\n\t set: function (mute) {\n\t this._volume.mute = mute;\n\t }\n\t });\n\t /**\n\t\t * The fadeIn time of the amplitude envelope.\n\t\t * @memberOf Tone.Source#\n\t\t * @type {Time}\n\t\t * @name fadeIn\n\t\t */\n\t Object.defineProperty(Tone.Players.prototype, 'fadeIn', {\n\t get: function () {\n\t return this._fadeIn;\n\t },\n\t set: function (fadeIn) {\n\t this._fadeIn = fadeIn;\n\t this._forEach(function (player) {\n\t player.fadeIn = fadeIn;\n\t });\n\t }\n\t });\n\t /**\n\t\t * The fadeOut time of the amplitude envelope.\n\t\t * @memberOf Tone.Source#\n\t\t * @type {Time}\n\t\t * @name fadeOut\n\t\t */\n\t Object.defineProperty(Tone.Players.prototype, 'fadeOut', {\n\t get: function () {\n\t return this._fadeOut;\n\t },\n\t set: function (fadeOut) {\n\t this._fadeOut = fadeOut;\n\t this._forEach(function (player) {\n\t player.fadeOut = fadeOut;\n\t });\n\t }\n\t });\n\t /**\n\t\t * The state of the players object. Returns \"started\" if any of the players are playing.\n\t\t * @memberOf Tone.Players#\n\t\t * @type {String}\n\t\t * @name state\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Players.prototype, 'state', {\n\t get: function () {\n\t var playing = false;\n\t this._forEach(function (player) {\n\t playing = playing || player.state === Tone.State.Started;\n\t });\n\t return playing ? Tone.State.Started : Tone.State.Stopped;\n\t }\n\t });\n\t /**\n\t\t * True if the buffers object has a buffer by that name.\n\t\t * @param {String|Number} name The key or index of the\n\t\t * buffer.\n\t\t * @return {Boolean}\n\t\t */\n\t Tone.Players.prototype.has = function (name) {\n\t return this._players.hasOwnProperty(name);\n\t };\n\t /**\n\t\t * Get a player by name.\n\t\t * @param {String} name The players name as defined in\n\t\t * the constructor object or `add` method.\n\t\t * @return {Tone.Player}\n\t\t */\n\t Tone.Players.prototype.get = function (name) {\n\t if (this.has(name)) {\n\t return this._players[name];\n\t } else {\n\t throw new Error('Tone.Players: no player named ' + name);\n\t }\n\t };\n\t /**\n\t\t * Iterate over all of the players\n\t\t * @param {Function} callback\n\t\t * @return {Tone.Players} this\n\t\t * @private\n\t\t */\n\t Tone.Players.prototype._forEach = function (callback) {\n\t for (var playerName in this._players) {\n\t callback(this._players[playerName], playerName);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * If all the buffers are loaded or not\n\t\t * @memberOf Tone.Players#\n\t\t * @type {Boolean}\n\t\t * @name loaded\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Players.prototype, 'loaded', {\n\t get: function () {\n\t var isLoaded = true;\n\t this._forEach(function (player) {\n\t isLoaded = isLoaded && player.loaded;\n\t });\n\t return isLoaded;\n\t }\n\t });\n\t /**\n\t\t * Add a player by name and url to the Players\n\t\t * @param {String} name A unique name to give the player\n\t\t * @param {String|Tone.Buffer|Audiobuffer} url Either the url of the bufer,\n\t\t * or a buffer which will be added\n\t\t * with the given name.\n\t\t * @param {Function=} callback The callback to invoke\n\t\t * when the url is loaded.\n\t\t */\n\t Tone.Players.prototype.add = function (name, url, callback) {\n\t this._players[name] = new Tone.Player(url, callback).connect(this.output);\n\t this._players[name].fadeIn = this._fadeIn;\n\t this._players[name].fadeOut = this._fadeOut;\n\t return this;\n\t };\n\t /**\n\t\t * Stop all of the players at the given time\n\t\t * @param {Time} time The time to stop all of the players.\n\t\t * @return {Tone.Players} this\n\t\t */\n\t Tone.Players.prototype.stopAll = function (time) {\n\t this._forEach(function (player) {\n\t player.stop(time);\n\t });\n\t };\n\t /**\n\t\t * Dispose and disconnect.\n\t\t * @return {Tone.Players} this\n\t\t */\n\t Tone.Players.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._volume.dispose();\n\t this._volume = null;\n\t this._writable('volume');\n\t this.volume = null;\n\t this.output = null;\n\t this._forEach(function (player) {\n\t player.dispose();\n\t });\n\t this._players = null;\n\t return this;\n\t };\n\t return Tone.Players;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.UserMedia uses MediaDevices.getUserMedia to open up\n\t\t * and external microphone or audio input. Check\n\t\t * [MediaDevices API Support](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)\n\t\t * to see which browsers are supported. Access to an external input\n\t\t * is limited to secure (HTTPS) connections.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Decibels=} volume The level of the input\n\t\t * @example\n\t\t * //list the inputs and open the third one\n\t\t * var motu = new Tone.UserMedia();\n\t\t *\n\t\t * //opening the input asks the user to activate their mic\n\t\t * motu.open().then(function(){\n\t\t * \t//promise resolves when input is available\n\t\t * });\n\t\t */\n\t Tone.UserMedia = function () {\n\t var options = Tone.defaults(arguments, ['volume'], Tone.UserMedia);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The MediaStreamNode\n\t\t\t * @type {MediaStreamAudioSourceNode}\n\t\t\t * @private\n\t\t\t */\n\t this._mediaStream = null;\n\t /**\n\t\t\t * The media stream created by getUserMedia.\n\t\t\t * @type {LocalMediaStream}\n\t\t\t * @private\n\t\t\t */\n\t this._stream = null;\n\t /**\n\t\t\t * The open device\n\t\t\t * @type {MediaDeviceInfo}\n\t\t\t * @private\n\t\t\t */\n\t this._device = null;\n\t /**\n\t\t\t * The output volume node\n\t\t\t * @type {Tone.Volume}\n\t\t\t * @private\n\t\t\t */\n\t this._volume = this.output = new Tone.Volume(options.volume);\n\t /**\n\t\t\t * The volume of the output in decibels.\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * input.volume.value = -6;\n\t\t\t */\n\t this.volume = this._volume.volume;\n\t this._readOnly('volume');\n\t this.mute = options.mute;\n\t };\n\t Tone.extend(Tone.UserMedia, Tone.AudioNode);\n\t /**\n\t\t * the default parameters\n\t\t * @type {Object}\n\t\t */\n\t Tone.UserMedia.defaults = {\n\t 'volume': 0,\n\t 'mute': false\n\t };\n\t /**\n\t\t * Open the media stream. If a string is passed in, it is assumed\n\t\t * to be the label or id of the stream, if a number is passed in,\n\t\t * it is the input number of the stream.\n\t\t * @param {String|Number} [labelOrId=\"default\"] The label or id of the audio input media device.\n\t\t * With no argument, the default stream is opened.\n\t\t * @return {Promise} The promise is resolved when the stream is open.\n\t\t */\n\t Tone.UserMedia.prototype.open = function (labelOrId) {\n\t return Tone.UserMedia.enumerateDevices().then(function (devices) {\n\t var device;\n\t if (Tone.isNumber(labelOrId)) {\n\t device = devices[labelOrId];\n\t } else {\n\t device = devices.find(function (device) {\n\t return device.label === labelOrId || device.deviceId === labelOrId;\n\t });\n\t //didn't find a matching device\n\t if (!device && devices.length > 0) {\n\t device = devices[0];\n\t } else if (!device && Tone.isDefined(labelOrId)) {\n\t throw new Error('Tone.UserMedia: no matching device: ' + labelOrId);\n\t }\n\t }\n\t this._device = device;\n\t //do getUserMedia\n\t var constraints = {\n\t audio: {\n\t 'echoCancellation': false,\n\t 'sampleRate': this.context.sampleRate\n\t }\n\t };\n\t if (device) {\n\t constraints.audio.deviceId = device.deviceId;\n\t }\n\t return navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {\n\t //start a new source only if the previous one is closed\n\t if (!this._stream) {\n\t this._stream = stream;\n\t //Wrap a MediaStreamSourceNode around the live input stream.\n\t this._mediaStream = this.context.createMediaStreamSource(stream);\n\t //Connect the MediaStreamSourceNode to a gate gain node\n\t this._mediaStream.connect(this.output);\n\t }\n\t return this;\n\t }.bind(this));\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Close the media stream\n\t\t * @return {Tone.UserMedia} this\n\t\t */\n\t Tone.UserMedia.prototype.close = function () {\n\t if (this._stream) {\n\t this._stream.getAudioTracks().forEach(function (track) {\n\t track.stop();\n\t });\n\t this._stream = null;\n\t //remove the old media stream\n\t this._mediaStream.disconnect();\n\t this._mediaStream = null;\n\t }\n\t this._device = null;\n\t return this;\n\t };\n\t /**\n\t\t * Returns a promise which resolves with the list of audio input devices available.\n\t\t * @return {Promise} The promise that is resolved with the devices\n\t\t * @static\n\t\t * @example\n\t\t * Tone.UserMedia.enumerateDevices().then(function(devices){\n\t\t * \tconsole.log(devices)\n\t\t * })\n\t\t */\n\t Tone.UserMedia.enumerateDevices = function () {\n\t return navigator.mediaDevices.enumerateDevices().then(function (devices) {\n\t return devices.filter(function (device) {\n\t return device.kind === 'audioinput';\n\t });\n\t });\n\t };\n\t /**\n\t\t * Returns the playback state of the source, \"started\" when the microphone is open\n\t\t * and \"stopped\" when the mic is closed.\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.UserMedia#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.UserMedia.prototype, 'state', {\n\t get: function () {\n\t return this._stream && this._stream.active ? Tone.State.Started : Tone.State.Stopped;\n\t }\n\t });\n\t /**\n\t\t * \tReturns an identifier for the represented device that is\n\t\t * \tpersisted across sessions. It is un-guessable by other applications and\n\t\t * \tunique to the origin of the calling application. It is reset when the\n\t\t * \tuser clears cookies (for Private Browsing, a different identifier is\n\t\t * \tused that is not persisted across sessions). Returns undefined when the\n\t\t * \tdevice is not open.\n\t\t * @type {String}\n\t\t * @readOnly\n\t\t * @memberOf Tone.UserMedia#\n\t\t * @name deviceId\n\t\t */\n\t Object.defineProperty(Tone.UserMedia.prototype, 'deviceId', {\n\t get: function () {\n\t if (this._device) {\n\t return this._device.deviceId;\n\t }\n\t }\n\t });\n\t /**\n\t\t * \tReturns a group identifier. Two devices have the\n\t\t * \tsame group identifier if they belong to the same physical device.\n\t\t * \tReturns undefined when the device is not open.\n\t\t * @type {String}\n\t\t * @readOnly\n\t\t * @memberOf Tone.UserMedia#\n\t\t * @name groupId\n\t\t */\n\t Object.defineProperty(Tone.UserMedia.prototype, 'groupId', {\n\t get: function () {\n\t if (this._device) {\n\t return this._device.groupId;\n\t }\n\t }\n\t });\n\t /**\n\t\t * \tReturns a label describing this device (for example \"Built-in Microphone\").\n\t\t * \tReturns undefined when the device is not open or label is not available\n\t\t * \tbecause of permissions.\n\t\t * @type {String}\n\t\t * @readOnly\n\t\t * @memberOf Tone.UserMedia#\n\t\t * @name groupId\n\t\t */\n\t Object.defineProperty(Tone.UserMedia.prototype, 'label', {\n\t get: function () {\n\t if (this._device) {\n\t return this._device.label;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Mute the output.\n\t\t * @memberOf Tone.UserMedia#\n\t\t * @type {boolean}\n\t\t * @name mute\n\t\t * @example\n\t\t * //mute the output\n\t\t * userMedia.mute = true;\n\t\t */\n\t Object.defineProperty(Tone.UserMedia.prototype, 'mute', {\n\t get: function () {\n\t return this._volume.mute;\n\t },\n\t set: function (mute) {\n\t this._volume.mute = mute;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.UserMedia} this\n\t\t */\n\t Tone.UserMedia.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.close();\n\t this._writable('volume');\n\t this._volume.dispose();\n\t this._volume = null;\n\t this.volume = null;\n\t return this;\n\t };\n\t /**\n\t\t * If getUserMedia is supported by the browser.\n\t\t * @type {Boolean}\n\t\t * @memberOf Tone.UserMedia#\n\t\t * @name supported\n\t\t * @static\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.UserMedia, 'supported', {\n\t get: function () {\n\t return Tone.isDefined(navigator.mediaDevices) && Tone.isFunction(navigator.mediaDevices.getUserMedia);\n\t }\n\t });\n\t return Tone.UserMedia;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Midi is a primitive type for encoding Time values.\n\t\t * Tone.Midi can be constructed with or without the `new` keyword. Tone.Midi can be passed\n\t\t * into the parameter of any method which takes time as an argument.\n\t\t * @constructor\n\t\t * @extends {Tone.Frequency}\n\t\t * @param {String|Number} val The time value.\n\t\t * @param {String=} units The units of the value.\n\t\t * @example\n\t\t * var t = Tone.Midi(\"4n\");//a quarter note\n\t\t */\n\t Tone.Midi = function (val, units) {\n\t if (this instanceof Tone.Midi) {\n\t Tone.Frequency.call(this, val, units);\n\t } else {\n\t return new Tone.Midi(val, units);\n\t }\n\t };\n\t Tone.extend(Tone.Midi, Tone.Frequency);\n\t /**\n\t\t * The default units if none are given.\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t Tone.Midi.prototype._defaultUnits = 'midi';\n\t /**\n\t\t * Returns the value of a frequency in the current units\n\t\t * @param {Frequency} freq\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Midi.prototype._frequencyToUnits = function (freq) {\n\t return Tone.Frequency.ftom(Tone.Frequency.prototype._frequencyToUnits.call(this, freq));\n\t };\n\t /**\n\t\t * Returns the value of a tick in the current time units\n\t\t * @param {Ticks} ticks\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Midi.prototype._ticksToUnits = function (ticks) {\n\t return Tone.Frequency.ftom(Tone.Frequency.prototype._ticksToUnits.call(this, ticks));\n\t };\n\t /**\n\t\t * Return the value of the beats in the current units\n\t\t * @param {Number} beats\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Midi.prototype._beatsToUnits = function (beats) {\n\t return Tone.Frequency.ftom(Tone.Frequency.prototype._beatsToUnits.call(this, beats));\n\t };\n\t /**\n\t\t * Returns the value of a second in the current units\n\t\t * @param {Seconds} seconds\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Midi.prototype._secondsToUnits = function (seconds) {\n\t return Tone.Frequency.ftom(Tone.Frequency.prototype._secondsToUnits.call(this, seconds));\n\t };\n\t /**\n\t\t * Return the value of the frequency as a MIDI note\n\t\t * @return {MIDI}\n\t\t * @example\n\t\t * Tone.Midi(60).toMidi(); //60\n\t\t */\n\t Tone.Midi.prototype.toMidi = function () {\n\t return this.valueOf();\n\t };\n\t /**\n\t\t * Return the value of the frequency as a MIDI note\n\t\t * @return {MIDI}\n\t\t * @example\n\t\t * Tone.Midi(60).toMidi(); //60\n\t\t */\n\t Tone.Midi.prototype.toFrequency = function () {\n\t return Tone.Frequency.mtof(this.toMidi());\n\t };\n\t /**\n\t\t * Transposes the frequency by the given number of semitones.\n\t\t * @param {Interval} interval\n\t\t * @return {Tone.Frequency} A new transposed frequency\n\t\t * @example\n\t\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t\t */\n\t Tone.Midi.prototype.transpose = function (interval) {\n\t return new this.constructor(this.toMidi() + interval);\n\t };\n\t return Tone.Midi;\n\t});\n\t\n\treturn Tone;\n}));\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/tone/build/Tone.js\n// module id = 21\n// module chunks = 0","// optional / simple context binding\nvar aFunction = require('./_a-function');\nmodule.exports = function(fn, that, length){\n aFunction(fn);\n if(that === undefined)return fn;\n switch(length){\n case 1: return function(a){\n return fn.call(that, a);\n };\n case 2: return function(a, b){\n return fn.call(that, a, b);\n };\n case 3: return function(a, b, c){\n return fn.call(that, a, b, c);\n };\n }\n return function(/* ...args */){\n return fn.apply(that, arguments);\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_ctx.js\n// module id = 22\n// module chunks = 0","module.exports = true;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_library.js\n// module id = 23\n// module chunks = 0","exports.f = {}.propertyIsEnumerable;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-pie.js\n// module id = 24\n// module chunks = 0","module.exports = function(bitmap, value){\n return {\n enumerable : !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable : !(bitmap & 4),\n value : value\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_property-desc.js\n// module id = 25\n// module chunks = 0","var def = require('./_object-dp').f\n , has = require('./_has')\n , TAG = require('./_wks')('toStringTag');\n\nmodule.exports = function(it, tag, stat){\n if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag});\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_set-to-string-tag.js\n// module id = 26\n// module chunks = 0","var id = 0\n , px = Math.random();\nmodule.exports = function(key){\n return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_uid.js\n// module id = 27\n// module chunks = 0","'use strict';\nvar $at = require('./_string-at')(true);\n\n// 21.1.3.27 String.prototype[@@iterator]()\nrequire('./_iter-define')(String, 'String', function(iterated){\n this._t = String(iterated); // target\n this._i = 0; // next index\n// 21.1.5.2.1 %StringIteratorPrototype%.next()\n}, function(){\n var O = this._t\n , index = this._i\n , point;\n if(index >= O.length)return {value: undefined, done: true};\n point = $at(O, index);\n this._i += point.length;\n return {value: point, done: false};\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/es6.string.iterator.js\n// module id = 28\n// module chunks = 0","require('./es6.array.iterator');\nvar global = require('./_global')\n , hide = require('./_hide')\n , Iterators = require('./_iterators')\n , TO_STRING_TAG = require('./_wks')('toStringTag');\n\nfor(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){\n var NAME = collections[i]\n , Collection = global[NAME]\n , proto = Collection && Collection.prototype;\n if(proto && !proto[TO_STRING_TAG])hide(proto, TO_STRING_TAG, NAME);\n Iterators[NAME] = Iterators.Array;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/web.dom.iterable.js\n// module id = 29\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.browser = exports.isDesktop = exports.isMobile = exports.isAndroid = exports.isIpad = exports.isIphone = undefined;\n\nvar _log = require('babel-runtime/core-js/math/log2');\n\nvar _log2 = _interopRequireDefault(_log);\n\nvar _assign = require('babel-runtime/core-js/object/assign');\n\nvar _assign2 = _interopRequireDefault(_assign);\n\nexports.choice = choice;\nexports.mod = mod;\nexports.norm = norm;\nexports.requestAudioContext = requestAudioContext;\nexports.dataURItoBlob = dataURItoBlob;\nexports.ftom = ftom;\nexports.mtof = mtof;\nexports.tap = tap;\nexports.get_diff_bounds = get_diff_bounds;\nexports.get_bounds = get_bounds;\nexports.transpose = transpose;\n\nvar _tone = require('tone');\n\nvar _tone2 = _interopRequireDefault(_tone);\n\nvar _startAudioContext = require('./startAudioContext');\n\nvar _startAudioContext2 = _interopRequireDefault(_startAudioContext);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar isIphone = exports.isIphone = navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i);\nvar isIpad = exports.isIpad = navigator.userAgent.match(/iPad/i);\nvar isAndroid = exports.isAndroid = navigator.userAgent.match(/Android/i);\nvar isMobile = exports.isMobile = isIphone || isIpad || isAndroid;\nvar isDesktop = exports.isDesktop = !isMobile;\n\ndocument.body.classList.add(isMobile ? 'mobile' : 'desktop');\n\nvar browser = exports.browser = { isIphone: isIphone, isIpad: isIpad, isMobile: isMobile, isDesktop: isDesktop };\n\nfunction choice(a) {\n return a[Math.floor(Math.random() * a.length)];\n}\nfunction mod(n, m) {\n return n - m * Math.floor(n / m);\n}\nfunction norm(n, min, max) {\n return (n - min) / (max - min);\n}\n\nfunction requestAudioContext(fn) {\n if (isMobile) {\n var container = document.createElement('div');\n var button = document.createElement('div');\n button.innerHTML = 'Tap to start - please unmute your phone';\n (0, _assign2.default)(container.style, {\n position: 'absolute',\n width: '100%',\n height: '100%',\n zIndex: '10000',\n top: '0px',\n left: '0px',\n backgroundColor: 'rgba(0, 0, 0, 0.8)'\n });\n (0, _assign2.default)(button.style, {\n position: 'absolute',\n left: '50%',\n top: '50%',\n padding: '20px',\n backgroundColor: '#7F33ED',\n color: 'white',\n fontFamily: 'monospace',\n borderRadius: '3px',\n transform: 'translate3D(-50%,-50%,0)',\n textAlign: 'center',\n lineHeight: '1.5'\n });\n container.appendChild(button);\n document.body.appendChild(container);\n _startAudioContext2.default.setContext(_tone2.default.context);\n _startAudioContext2.default.on(button);\n _startAudioContext2.default.onStarted(function (_) {\n container.remove();\n fn();\n });\n } else {\n fn();\n }\n}\n\nfunction dataURItoBlob(dataURI) {\n // convert base64 to raw binary data held in a string\n // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this\n var byteString = atob(dataURI.split(',')[1]);\n\n // separate out the mime component\n var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];\n\n // write the bytes of the string to an ArrayBuffer\n var ab = new ArrayBuffer(byteString.length);\n\n // create a view into the buffer\n var ia = new Uint8Array(ab);\n\n // set the bytes of the buffer to the correct values\n for (var i = 0; i < byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n\n // write the ArrayBuffer to a blob, and you're done\n var blob = new Blob([ab], { type: mimeString });\n return blob;\n}\nfunction ftom(f) {\n // return (Math.log(f) - Math.log(261.626)) / Math.log(2) + 4.0\n return 69 + 12 * (0, _log2.default)(f / 440);\n}\nfunction mtof(m) {\n return 440 * Math.pow(2, (m - 69) / 12);\n}\nfunction tap(fn) {\n return function (e) {\n if (browser.isMobile) fn();else if (e.press) fn();\n };\n}\n\n/* get minimum and maximum variance from row-to-row */\n\nfunction get_diff_bounds(rows) {\n var diffs = rows.map(function (row) {\n var row_min = Math.min.apply(Math, row);\n var row_max = Math.max.apply(Math, row);\n return row_max - row_min;\n });\n var min = Math.min.apply(Math, diffs);\n var max = Math.max.apply(Math, diffs);\n return { min: min, max: max };\n}\n\n/* get minimum and maximum values from a dataset */\n\nfunction get_bounds(dataset) {\n var rows = dataset.lines;\n // rows.forEach(row => row.shift())\n rows = rows.map(function (a) {\n return a.map(function (n) {\n return parseFloat(n);\n });\n });\n var max = rows.reduce(function (a, b) {\n return b.reduce(function (z, bb) {\n return Math.max(z, bb);\n }, a);\n }, -Infinity);\n var min = rows.reduce(function (a, b) {\n return b.reduce(function (z, bb) {\n return Math.min(z, bb);\n }, a);\n }, Infinity);\n return { rows: rows, max: max, min: min };\n}\n\n/* transpose a 2D array */\n\nfunction transpose(a) {\n var i_len = a[0].length;\n var j_len = a.length;\n var T = new Array(i_len);\n for (var i = 0; i < i_len; i++) {\n T[i] = new Array(j_len);\n for (var j = 0; j < j_len; j++) {\n T[i][j] = a[j][i];\n }\n }\n return T;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/util.js\n// module id = 30\n// module chunks = 0","'use strict';\n\nvar buffer = require('buffer');\nvar Buffer = buffer.Buffer;\nvar SlowBuffer = buffer.SlowBuffer;\nvar MAX_LEN = buffer.kMaxLength || 2147483647;\nexports.alloc = function alloc(size, fill, encoding) {\n if (typeof Buffer.alloc === 'function') {\n return Buffer.alloc(size, fill, encoding);\n }\n if (typeof encoding === 'number') {\n throw new TypeError('encoding must not be number');\n }\n if (typeof size !== 'number') {\n throw new TypeError('size must be a number');\n }\n if (size > MAX_LEN) {\n throw new RangeError('size is too large');\n }\n var enc = encoding;\n var _fill = fill;\n if (_fill === undefined) {\n enc = undefined;\n _fill = 0;\n }\n var buf = new Buffer(size);\n if (typeof _fill === 'string') {\n var fillBuf = new Buffer(_fill, enc);\n var flen = fillBuf.length;\n var i = -1;\n while (++i < size) {\n buf[i] = fillBuf[i % flen];\n }\n } else {\n buf.fill(_fill);\n }\n return buf;\n}\nexports.allocUnsafe = function allocUnsafe(size) {\n if (typeof Buffer.allocUnsafe === 'function') {\n return Buffer.allocUnsafe(size);\n }\n if (typeof size !== 'number') {\n throw new TypeError('size must be a number');\n }\n if (size > MAX_LEN) {\n throw new RangeError('size is too large');\n }\n return new Buffer(size);\n}\nexports.from = function from(value, encodingOrOffset, length) {\n if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) {\n return Buffer.from(value, encodingOrOffset, length);\n }\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number');\n }\n if (typeof value === 'string') {\n return new Buffer(value, encodingOrOffset);\n }\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n var offset = encodingOrOffset;\n if (arguments.length === 1) {\n return new Buffer(value);\n }\n if (typeof offset === 'undefined') {\n offset = 0;\n }\n var len = length;\n if (typeof len === 'undefined') {\n len = value.byteLength - offset;\n }\n if (offset >= value.byteLength) {\n throw new RangeError('\\'offset\\' is out of bounds');\n }\n if (len > value.byteLength - offset) {\n throw new RangeError('\\'length\\' is out of bounds');\n }\n return new Buffer(value.slice(offset, offset + len));\n }\n if (Buffer.isBuffer(value)) {\n var out = new Buffer(value.length);\n value.copy(out, 0, 0, value.length);\n return out;\n }\n if (value) {\n if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) {\n return new Buffer(value);\n }\n if (value.type === 'Buffer' && Array.isArray(value.data)) {\n return new Buffer(value.data);\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.');\n}\nexports.allocUnsafeSlow = function allocUnsafeSlow(size) {\n if (typeof Buffer.allocUnsafeSlow === 'function') {\n return Buffer.allocUnsafeSlow(size);\n }\n if (typeof size !== 'number') {\n throw new TypeError('size must be a number');\n }\n if (size >= MAX_LEN) {\n throw new RangeError('size is too large');\n }\n return new SlowBuffer(size);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/buffer-shims/index.js\n// module id = 31\n// module chunks = 0","module.exports = function(it){\n if(typeof it != 'function')throw TypeError(it + ' is not a function!');\n return it;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_a-function.js\n// module id = 32\n// module chunks = 0","// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = require('./_cof')\n , TAG = require('./_wks')('toStringTag')\n // ES3 wrong here\n , ARG = cof(function(){ return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function(it, key){\n try {\n return it[key];\n } catch(e){ /* empty */ }\n};\n\nmodule.exports = function(it){\n var O, T, B;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T\n // builtinTag case\n : ARG ? cof(O)\n // ES3 arguments fallback\n : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_classof.js\n// module id = 33\n// module chunks = 0","// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function(it){\n if(it == undefined)throw TypeError(\"Can't call method on \" + it);\n return it;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_defined.js\n// module id = 34\n// module chunks = 0","var isObject = require('./_is-object')\n , document = require('./_global').document\n // in old IE typeof document.createElement is 'object'\n , is = isObject(document) && isObject(document.createElement);\nmodule.exports = function(it){\n return is ? document.createElement(it) : {};\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_dom-create.js\n// module id = 35\n// module chunks = 0","// IE 8- don't enum bug keys\nmodule.exports = (\n 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\n).split(',');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_enum-bug-keys.js\n// module id = 36\n// module chunks = 0","exports.f = Object.getOwnPropertySymbols;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-gops.js\n// module id = 37\n// module chunks = 0","var shared = require('./_shared')('keys')\n , uid = require('./_uid');\nmodule.exports = function(key){\n return shared[key] || (shared[key] = uid(key));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_shared-key.js\n// module id = 38\n// module chunks = 0","var global = require('./_global')\n , SHARED = '__core-js_shared__'\n , store = global[SHARED] || (global[SHARED] = {});\nmodule.exports = function(key){\n return store[key] || (store[key] = {});\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_shared.js\n// module id = 39\n// module chunks = 0","// 7.1.4 ToInteger\nvar ceil = Math.ceil\n , floor = Math.floor;\nmodule.exports = function(it){\n return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_to-integer.js\n// module id = 40\n// module chunks = 0","// 7.1.13 ToObject(argument)\nvar defined = require('./_defined');\nmodule.exports = function(it){\n return Object(defined(it));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_to-object.js\n// module id = 41\n// module chunks = 0","// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = require('./_is-object');\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function(it, S){\n if(!isObject(it))return it;\n var fn, val;\n if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;\n if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;\n if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;\n throw TypeError(\"Can't convert object to primitive value\");\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_to-primitive.js\n// module id = 42\n// module chunks = 0","var global = require('./_global')\n , core = require('./_core')\n , LIBRARY = require('./_library')\n , wksExt = require('./_wks-ext')\n , defineProperty = require('./_object-dp').f;\nmodule.exports = function(name){\n var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {});\n if(name.charAt(0) != '_' && !(name in $Symbol))defineProperty($Symbol, name, {value: wksExt.f(name)});\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_wks-define.js\n// module id = 43\n// module chunks = 0","exports.f = require('./_wks');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_wks-ext.js\n// module id = 44\n// module chunks = 0","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n args = Array.prototype.slice.call(arguments, 1);\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n args = Array.prototype.slice.call(arguments, 1);\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/events/events.js\n// module id = 45\n// module chunks = 0","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar Buffer = require('buffer').Buffer;\n\nvar isBufferEncoding = Buffer.isEncoding\n || function(encoding) {\n switch (encoding && encoding.toLowerCase()) {\n case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;\n default: return false;\n }\n }\n\n\nfunction assertEncoding(encoding) {\n if (encoding && !isBufferEncoding(encoding)) {\n throw new Error('Unknown encoding: ' + encoding);\n }\n}\n\n// StringDecoder provides an interface for efficiently splitting a series of\n// buffers into a series of JS strings without breaking apart multi-byte\n// characters. CESU-8 is handled as part of the UTF-8 encoding.\n//\n// @TODO Handling all encodings inside a single object makes it very difficult\n// to reason about this code, so it should be split up in the future.\n// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code\n// points as used by CESU-8.\nvar StringDecoder = exports.StringDecoder = function(encoding) {\n this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');\n assertEncoding(encoding);\n switch (this.encoding) {\n case 'utf8':\n // CESU-8 represents each of Surrogate Pair by 3-bytes\n this.surrogateSize = 3;\n break;\n case 'ucs2':\n case 'utf16le':\n // UTF-16 represents each of Surrogate Pair by 2-bytes\n this.surrogateSize = 2;\n this.detectIncompleteChar = utf16DetectIncompleteChar;\n break;\n case 'base64':\n // Base-64 stores 3 bytes in 4 chars, and pads the remainder.\n this.surrogateSize = 3;\n this.detectIncompleteChar = base64DetectIncompleteChar;\n break;\n default:\n this.write = passThroughWrite;\n return;\n }\n\n // Enough space to store all bytes of a single character. UTF-8 needs 4\n // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).\n this.charBuffer = new Buffer(6);\n // Number of bytes received for the current incomplete multi-byte character.\n this.charReceived = 0;\n // Number of bytes expected for the current incomplete multi-byte character.\n this.charLength = 0;\n};\n\n\n// write decodes the given buffer and returns it as JS string that is\n// guaranteed to not contain any partial multi-byte characters. Any partial\n// character found at the end of the buffer is buffered up, and will be\n// returned when calling write again with the remaining bytes.\n//\n// Note: Converting a Buffer containing an orphan surrogate to a String\n// currently works, but converting a String to a Buffer (via `new Buffer`, or\n// Buffer#write) will replace incomplete surrogates with the unicode\n// replacement character. See https://codereview.chromium.org/121173009/ .\nStringDecoder.prototype.write = function(buffer) {\n var charStr = '';\n // if our last write ended with an incomplete multibyte character\n while (this.charLength) {\n // determine how many remaining bytes this buffer has to offer for this char\n var available = (buffer.length >= this.charLength - this.charReceived) ?\n this.charLength - this.charReceived :\n buffer.length;\n\n // add the new bytes to the char buffer\n buffer.copy(this.charBuffer, this.charReceived, 0, available);\n this.charReceived += available;\n\n if (this.charReceived < this.charLength) {\n // still not enough chars in this buffer? wait for more ...\n return '';\n }\n\n // remove bytes belonging to the current character from the buffer\n buffer = buffer.slice(available, buffer.length);\n\n // get the character that was split\n charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);\n\n // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n var charCode = charStr.charCodeAt(charStr.length - 1);\n if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n this.charLength += this.surrogateSize;\n charStr = '';\n continue;\n }\n this.charReceived = this.charLength = 0;\n\n // if there are no more bytes in this buffer, just emit our char\n if (buffer.length === 0) {\n return charStr;\n }\n break;\n }\n\n // determine and set charLength / charReceived\n this.detectIncompleteChar(buffer);\n\n var end = buffer.length;\n if (this.charLength) {\n // buffer the incomplete character bytes we got\n buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);\n end -= this.charReceived;\n }\n\n charStr += buffer.toString(this.encoding, 0, end);\n\n var end = charStr.length - 1;\n var charCode = charStr.charCodeAt(end);\n // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n var size = this.surrogateSize;\n this.charLength += size;\n this.charReceived += size;\n this.charBuffer.copy(this.charBuffer, size, 0, size);\n buffer.copy(this.charBuffer, 0, 0, size);\n return charStr.substring(0, end);\n }\n\n // or just emit the charStr\n return charStr;\n};\n\n// detectIncompleteChar determines if there is an incomplete UTF-8 character at\n// the end of the given buffer. If so, it sets this.charLength to the byte\n// length that character, and sets this.charReceived to the number of bytes\n// that are available for this character.\nStringDecoder.prototype.detectIncompleteChar = function(buffer) {\n // determine how many bytes we have to check at the end of this buffer\n var i = (buffer.length >= 3) ? 3 : buffer.length;\n\n // Figure out if one of the last i bytes of our buffer announces an\n // incomplete char.\n for (; i > 0; i--) {\n var c = buffer[buffer.length - i];\n\n // See http://en.wikipedia.org/wiki/UTF-8#Description\n\n // 110XXXXX\n if (i == 1 && c >> 5 == 0x06) {\n this.charLength = 2;\n break;\n }\n\n // 1110XXXX\n if (i <= 2 && c >> 4 == 0x0E) {\n this.charLength = 3;\n break;\n }\n\n // 11110XXX\n if (i <= 3 && c >> 3 == 0x1E) {\n this.charLength = 4;\n break;\n }\n }\n this.charReceived = i;\n};\n\nStringDecoder.prototype.end = function(buffer) {\n var res = '';\n if (buffer && buffer.length)\n res = this.write(buffer);\n\n if (this.charReceived) {\n var cr = this.charReceived;\n var buf = this.charBuffer;\n var enc = this.encoding;\n res += buf.slice(0, cr).toString(enc);\n }\n\n return res;\n};\n\nfunction passThroughWrite(buffer) {\n return buffer.toString(this.encoding);\n}\n\nfunction utf16DetectIncompleteChar(buffer) {\n this.charReceived = buffer.length % 2;\n this.charLength = this.charReceived ? 2 : 0;\n}\n\nfunction base64DetectIncompleteChar(buffer) {\n this.charReceived = buffer.length % 3;\n this.charLength = this.charReceived ? 3 : 0;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/node-libs-browser/~/string_decoder/index.js\n// module id = 46\n// module chunks = 0","'use strict';\n\nif (!process.version ||\n process.version.indexOf('v0.') === 0 ||\n process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {\n module.exports = nextTick;\n} else {\n module.exports = process.nextTick;\n}\n\nfunction nextTick(fn, arg1, arg2, arg3) {\n if (typeof fn !== 'function') {\n throw new TypeError('\"callback\" argument must be a function');\n }\n var len = arguments.length;\n var args, i;\n switch (len) {\n case 0:\n case 1:\n return process.nextTick(fn);\n case 2:\n return process.nextTick(function afterTickOne() {\n fn.call(null, arg1);\n });\n case 3:\n return process.nextTick(function afterTickTwo() {\n fn.call(null, arg1, arg2);\n });\n case 4:\n return process.nextTick(function afterTickThree() {\n fn.call(null, arg1, arg2, arg3);\n });\n default:\n args = new Array(len - 1);\n i = 0;\n while (i < args.length) {\n args[i++] = arguments[i];\n }\n return process.nextTick(function afterTick() {\n fn.apply(null, args);\n });\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/process-nextick-args/index.js\n// module id = 47\n// module chunks = 0","// A bit simpler than readable streams.\n// Implement an async ._write(chunk, encoding, cb), and it'll handle all\n// the drain event emission and buffering.\n\n'use strict';\n\nmodule.exports = Writable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;\n/*</replacement>*/\n\n/*<replacement>*/\nvar Duplex;\n/*</replacement>*/\n\nWritable.WritableState = WritableState;\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar internalUtil = {\n deprecate: require('util-deprecate')\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream = require('./internal/streams/stream');\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nutil.inherits(Writable, Stream);\n\nfunction nop() {}\n\nfunction WriteReq(chunk, encoding, cb) {\n this.chunk = chunk;\n this.encoding = encoding;\n this.callback = cb;\n this.next = null;\n}\n\nfunction WritableState(options, stream) {\n Duplex = Duplex || require('./_stream_duplex');\n\n options = options || {};\n\n // object stream flag to indicate whether or not this stream\n // contains buffers or objects.\n this.objectMode = !!options.objectMode;\n\n if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;\n\n // the point at which write() starts returning false\n // Note: 0 is a valid value, means that we always return false if\n // the entire buffer is not flushed immediately on write()\n var hwm = options.highWaterMark;\n var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n // cast to ints.\n this.highWaterMark = ~~this.highWaterMark;\n\n // drain event flag.\n this.needDrain = false;\n // at the start of calling end()\n this.ending = false;\n // when end() has been called, and returned\n this.ended = false;\n // when 'finish' is emitted\n this.finished = false;\n\n // should we decode strings into buffers before passing to _write?\n // this is here so that some node-core streams can optimize string\n // handling at a lower level.\n var noDecode = options.decodeStrings === false;\n this.decodeStrings = !noDecode;\n\n // Crypto is kind of old and crusty. Historically, its default string\n // encoding is 'binary' so we have to make this configurable.\n // Everything else in the universe uses 'utf8', though.\n this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n // not an actual buffer we keep track of, but a measurement\n // of how much we're waiting to get pushed to some underlying\n // socket or file.\n this.length = 0;\n\n // a flag to see when we're in the middle of a write.\n this.writing = false;\n\n // when true all writes will be buffered until .uncork() call\n this.corked = 0;\n\n // a flag to be able to tell if the onwrite cb is called immediately,\n // or on a later tick. We set this to true at first, because any\n // actions that shouldn't happen until \"later\" should generally also\n // not happen before the first write call.\n this.sync = true;\n\n // a flag to know if we're processing previously buffered items, which\n // may call the _write() callback in the same tick, so that we don't\n // end up in an overlapped onwrite situation.\n this.bufferProcessing = false;\n\n // the callback that's passed to _write(chunk,cb)\n this.onwrite = function (er) {\n onwrite(stream, er);\n };\n\n // the callback that the user supplies to write(chunk,encoding,cb)\n this.writecb = null;\n\n // the amount that is being written when _write is called.\n this.writelen = 0;\n\n this.bufferedRequest = null;\n this.lastBufferedRequest = null;\n\n // number of pending user-supplied write callbacks\n // this must be 0 before 'finish' can be emitted\n this.pendingcb = 0;\n\n // emit prefinish if the only thing we're waiting for is _write cbs\n // This is relevant for synchronous Transform streams\n this.prefinished = false;\n\n // True if the error was already emitted and should not be thrown again\n this.errorEmitted = false;\n\n // count buffered requests\n this.bufferedRequestCount = 0;\n\n // allocate the first CorkedRequest, there is always\n // one allocated and free to use, and we maintain at most two\n this.corkedRequestsFree = new CorkedRequest(this);\n}\n\nWritableState.prototype.getBuffer = function getBuffer() {\n var current = this.bufferedRequest;\n var out = [];\n while (current) {\n out.push(current);\n current = current.next;\n }\n return out;\n};\n\n(function () {\n try {\n Object.defineProperty(WritableState.prototype, 'buffer', {\n get: internalUtil.deprecate(function () {\n return this.getBuffer();\n }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')\n });\n } catch (_) {}\n})();\n\n// Test _writableState for inheritance to account for Duplex streams,\n// whose prototype chain only points to Readable.\nvar realHasInstance;\nif (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {\n realHasInstance = Function.prototype[Symbol.hasInstance];\n Object.defineProperty(Writable, Symbol.hasInstance, {\n value: function (object) {\n if (realHasInstance.call(this, object)) return true;\n\n return object && object._writableState instanceof WritableState;\n }\n });\n} else {\n realHasInstance = function (object) {\n return object instanceof this;\n };\n}\n\nfunction Writable(options) {\n Duplex = Duplex || require('./_stream_duplex');\n\n // Writable ctor is applied to Duplexes, too.\n // `realHasInstance` is necessary because using plain `instanceof`\n // would return false, as no `_writableState` property is attached.\n\n // Trying to use the custom `instanceof` for Writable here will also break the\n // Node.js LazyTransform implementation, which has a non-trivial getter for\n // `_writableState` that would lead to infinite recursion.\n if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) {\n return new Writable(options);\n }\n\n this._writableState = new WritableState(options, this);\n\n // legacy.\n this.writable = true;\n\n if (options) {\n if (typeof options.write === 'function') this._write = options.write;\n\n if (typeof options.writev === 'function') this._writev = options.writev;\n }\n\n Stream.call(this);\n}\n\n// Otherwise people can pipe Writable streams, which is just wrong.\nWritable.prototype.pipe = function () {\n this.emit('error', new Error('Cannot pipe, not readable'));\n};\n\nfunction writeAfterEnd(stream, cb) {\n var er = new Error('write after end');\n // TODO: defer error events consistently everywhere, not just the cb\n stream.emit('error', er);\n processNextTick(cb, er);\n}\n\n// Checks that a user-supplied chunk is valid, especially for the particular\n// mode the stream is in. Currently this means that `null` is never accepted\n// and undefined/non-string values are only allowed in object mode.\nfunction validChunk(stream, state, chunk, cb) {\n var valid = true;\n var er = false;\n\n if (chunk === null) {\n er = new TypeError('May not write null values to stream');\n } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {\n er = new TypeError('Invalid non-string/buffer chunk');\n }\n if (er) {\n stream.emit('error', er);\n processNextTick(cb, er);\n valid = false;\n }\n return valid;\n}\n\nWritable.prototype.write = function (chunk, encoding, cb) {\n var state = this._writableState;\n var ret = false;\n var isBuf = Buffer.isBuffer(chunk);\n\n if (typeof encoding === 'function') {\n cb = encoding;\n encoding = null;\n }\n\n if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;\n\n if (typeof cb !== 'function') cb = nop;\n\n if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {\n state.pendingcb++;\n ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);\n }\n\n return ret;\n};\n\nWritable.prototype.cork = function () {\n var state = this._writableState;\n\n state.corked++;\n};\n\nWritable.prototype.uncork = function () {\n var state = this._writableState;\n\n if (state.corked) {\n state.corked--;\n\n if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);\n }\n};\n\nWritable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {\n // node::ParseEncoding() requires lower case.\n if (typeof encoding === 'string') encoding = encoding.toLowerCase();\n if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);\n this._writableState.defaultEncoding = encoding;\n return this;\n};\n\nfunction decodeChunk(state, chunk, encoding) {\n if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {\n chunk = bufferShim.from(chunk, encoding);\n }\n return chunk;\n}\n\n// if we're already writing something, then just put this\n// in the queue, and wait our turn. Otherwise, call _write\n// If we return false, then we need a drain event, so set that flag.\nfunction writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {\n if (!isBuf) {\n chunk = decodeChunk(state, chunk, encoding);\n if (Buffer.isBuffer(chunk)) encoding = 'buffer';\n }\n var len = state.objectMode ? 1 : chunk.length;\n\n state.length += len;\n\n var ret = state.length < state.highWaterMark;\n // we must ensure that previous needDrain will not be reset to false.\n if (!ret) state.needDrain = true;\n\n if (state.writing || state.corked) {\n var last = state.lastBufferedRequest;\n state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);\n if (last) {\n last.next = state.lastBufferedRequest;\n } else {\n state.bufferedRequest = state.lastBufferedRequest;\n }\n state.bufferedRequestCount += 1;\n } else {\n doWrite(stream, state, false, len, chunk, encoding, cb);\n }\n\n return ret;\n}\n\nfunction doWrite(stream, state, writev, len, chunk, encoding, cb) {\n state.writelen = len;\n state.writecb = cb;\n state.writing = true;\n state.sync = true;\n if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);\n state.sync = false;\n}\n\nfunction onwriteError(stream, state, sync, er, cb) {\n --state.pendingcb;\n if (sync) processNextTick(cb, er);else cb(er);\n\n stream._writableState.errorEmitted = true;\n stream.emit('error', er);\n}\n\nfunction onwriteStateUpdate(state) {\n state.writing = false;\n state.writecb = null;\n state.length -= state.writelen;\n state.writelen = 0;\n}\n\nfunction onwrite(stream, er) {\n var state = stream._writableState;\n var sync = state.sync;\n var cb = state.writecb;\n\n onwriteStateUpdate(state);\n\n if (er) onwriteError(stream, state, sync, er, cb);else {\n // Check if we're actually ready to finish, but don't emit yet\n var finished = needFinish(state);\n\n if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {\n clearBuffer(stream, state);\n }\n\n if (sync) {\n /*<replacement>*/\n asyncWrite(afterWrite, stream, state, finished, cb);\n /*</replacement>*/\n } else {\n afterWrite(stream, state, finished, cb);\n }\n }\n}\n\nfunction afterWrite(stream, state, finished, cb) {\n if (!finished) onwriteDrain(stream, state);\n state.pendingcb--;\n cb();\n finishMaybe(stream, state);\n}\n\n// Must force callback to be called on nextTick, so that we don't\n// emit 'drain' before the write() consumer gets the 'false' return\n// value, and has a chance to attach a 'drain' listener.\nfunction onwriteDrain(stream, state) {\n if (state.length === 0 && state.needDrain) {\n state.needDrain = false;\n stream.emit('drain');\n }\n}\n\n// if there's something in the buffer waiting, then process it\nfunction clearBuffer(stream, state) {\n state.bufferProcessing = true;\n var entry = state.bufferedRequest;\n\n if (stream._writev && entry && entry.next) {\n // Fast case, write everything using _writev()\n var l = state.bufferedRequestCount;\n var buffer = new Array(l);\n var holder = state.corkedRequestsFree;\n holder.entry = entry;\n\n var count = 0;\n while (entry) {\n buffer[count] = entry;\n entry = entry.next;\n count += 1;\n }\n\n doWrite(stream, state, true, state.length, buffer, '', holder.finish);\n\n // doWrite is almost always async, defer these to save a bit of time\n // as the hot path ends with doWrite\n state.pendingcb++;\n state.lastBufferedRequest = null;\n if (holder.next) {\n state.corkedRequestsFree = holder.next;\n holder.next = null;\n } else {\n state.corkedRequestsFree = new CorkedRequest(state);\n }\n } else {\n // Slow case, write chunks one-by-one\n while (entry) {\n var chunk = entry.chunk;\n var encoding = entry.encoding;\n var cb = entry.callback;\n var len = state.objectMode ? 1 : chunk.length;\n\n doWrite(stream, state, false, len, chunk, encoding, cb);\n entry = entry.next;\n // if we didn't call the onwrite immediately, then\n // it means that we need to wait until it does.\n // also, that means that the chunk and cb are currently\n // being processed, so move the buffer counter past them.\n if (state.writing) {\n break;\n }\n }\n\n if (entry === null) state.lastBufferedRequest = null;\n }\n\n state.bufferedRequestCount = 0;\n state.bufferedRequest = entry;\n state.bufferProcessing = false;\n}\n\nWritable.prototype._write = function (chunk, encoding, cb) {\n cb(new Error('_write() is not implemented'));\n};\n\nWritable.prototype._writev = null;\n\nWritable.prototype.end = function (chunk, encoding, cb) {\n var state = this._writableState;\n\n if (typeof chunk === 'function') {\n cb = chunk;\n chunk = null;\n encoding = null;\n } else if (typeof encoding === 'function') {\n cb = encoding;\n encoding = null;\n }\n\n if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);\n\n // .end() fully uncorks\n if (state.corked) {\n state.corked = 1;\n this.uncork();\n }\n\n // ignore unnecessary end() calls.\n if (!state.ending && !state.finished) endWritable(this, state, cb);\n};\n\nfunction needFinish(state) {\n return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;\n}\n\nfunction prefinish(stream, state) {\n if (!state.prefinished) {\n state.prefinished = true;\n stream.emit('prefinish');\n }\n}\n\nfunction finishMaybe(stream, state) {\n var need = needFinish(state);\n if (need) {\n if (state.pendingcb === 0) {\n prefinish(stream, state);\n state.finished = true;\n stream.emit('finish');\n } else {\n prefinish(stream, state);\n }\n }\n return need;\n}\n\nfunction endWritable(stream, state, cb) {\n state.ending = true;\n finishMaybe(stream, state);\n if (cb) {\n if (state.finished) processNextTick(cb);else stream.once('finish', cb);\n }\n state.ended = true;\n stream.writable = false;\n}\n\n// It seems a linked list but it is not\n// there will be only 2 of these for each stream\nfunction CorkedRequest(state) {\n var _this = this;\n\n this.next = null;\n this.entry = null;\n this.finish = function (err) {\n var entry = _this.entry;\n _this.entry = null;\n while (entry) {\n var cb = entry.callback;\n state.pendingcb--;\n cb(err);\n entry = entry.next;\n }\n if (state.corkedRequestsFree) {\n state.corkedRequestsFree.next = _this;\n } else {\n state.corkedRequestsFree = _this;\n }\n };\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/readable-stream/lib/_stream_writable.js\n// module id = 48\n// module chunks = 0","exports = module.exports = require('./lib/_stream_readable.js');\nexports.Stream = exports;\nexports.Readable = exports;\nexports.Writable = require('./lib/_stream_writable.js');\nexports.Duplex = require('./lib/_stream_duplex.js');\nexports.Transform = require('./lib/_stream_transform.js');\nexports.PassThrough = require('./lib/_stream_passthrough.js');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/readable-stream/readable-browser.js\n// module id = 49\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _intonation = require('./intonation');\n\nvar _intonation2 = _interopRequireDefault(_intonation);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar meantone = '! meanquar.scl\\n!\\n1/4-comma meantone scale. Pietro Aaron\\'s temperament (1523)\\n 12\\n!\\n 76.04900\\n 193.15686\\n 310.26471\\n 5/4\\n 503.42157\\n 579.47057\\n 696.57843\\n 25/16\\n 889.73529\\n 1006.84314\\n 1082.89214\\n 2/1\\n';\n\nvar shares = '! shares.scl\\n!\\nA scale based on shares of wealth\\n!\\n1.\\n5.\\n15.\\n32.\\n52.\\n78.\\n116.\\n182.\\n521.\\n1000.\\n';\n\nvar shares_sum = '! shares_sum.scl\\n!\\nA scale based on summing shares of wealth\\n!\\n1\\n6.0\\n21.0\\n53.0\\n105.0\\n183.0\\n299.0\\n481.0\\n1002.0\\n2/1\\n';\n\nvar mavila = '! mavila12.scl\\n!\\nA 12-note mavila scale (for warping meantone-based music), 5-limit TOP\\n 12\\n!\\n-30.99719\\n 163.50770\\n 358.01258\\n 327.01540\\n 521.52028\\n 490.52310\\n 685.02798\\n 654.03080\\n 848.53568\\n 1043.04057\\n 1012.04338\\n 1206.54826\\n';\n\nvar carlos_alpha = '! carlos_alpha.scl\\n!\\nWendy Carlos\\' Alpha scale with perfect fifth divided in nine\\n 18\\n!\\n 78.00000\\n 156.00000\\n 234.00000\\n 312.00000\\n 390.00000\\n 468.00000\\n 546.00000\\n 624.00000\\n 702.00000\\n 780.00000\\n 858.00000\\n 936.00000\\n 1014.00000\\n 1092.00000\\n 1170.00000\\n 1248.00000\\n 1326.00000\\n 1404.00000\\n';\n\nvar lamonte = '! young-lm_piano.scl\\n!\\nLaMonte Young\\'s Well-Tempered Piano\\n12\\n!\\n567/512\\n9/8\\n147/128\\n21/16\\n1323/1024\\n189/128\\n3/2\\n49/32\\n7/4\\n441/256\\n63/32\\n2/1\\n';\n\nvar colundi = '! colundi.scl\\n!\\nColundi scale\\n10\\n!\\n9/8\\n171/140\\n137/112\\n43/35\\n3/2\\n421/280\\n213/140\\n263/150\\n66/35\\n2/1\\n';\n\nvar liu_major = '! liu_major.scl\\n!\\nLinus Liu\\'s Major Scale, see his 1978 book, \"Intonation Theory\" \\n 7\\n!\\n 10/9\\n 100/81\\n 4/3\\n 3/2\\n 5/3\\n 50/27\\n 2/1\\n';\nvar liu_pentatonic = '! liu_pent.scl\\n!\\nLinus Liu\\'s \"pentatonic scale\" \\n 7\\n!\\n 9/8\\n 81/64\\n 27/20\\n 3/2\\n 27/16\\n 243/128\\n 81/40\\n';\n\nvar liu_minor = '! LIU_MINor.scl\\n!\\nLinus Liu\\'s Harmonic Minor \\n 7\\n!\\n 10/9\\n 6/5\\n 4/3\\n 40/27\\n 8/5\\n 50/27\\n 2/1\\n';\n\nvar liu_melodic_minor = '! liu_mel.scl\\n!\\nLinus Liu\\'s Melodic Minor, use 5 and 7 descending and 6 and 8 ascending \\n 9\\n!\\n 10/9\\n 6/5\\n 4/3\\n 3/2\\n 81/50\\n 5/3\\n 9/5\\n 50/27\\n 2/1\\n';\n\nvar scales = [{\n intervals: '1/1 9/8 5/4 4/3 3/2 5/3 15/8 2/1',\n name: \"harmonic scale\"\n}, {\n root: 450,\n intervals: '1/1 9/8 5/4 4/3 3/2 5/3 15/8 2/1',\n name: \"harmonic scale @ 450\"\n}, {\n tet: 5\n}, {\n tet: 12\n}, {\n tet: 17\n}, {\n intervals: '1/1 81/80 33/32 21/20 16/15 12/11 11/10 10/9 9/8 8/7 7/6 32/27 6/5 11/9 5/4 14/11 9/7 21/16 4/3 27/20 11/8 7/5 10/7 16/11 40/27 3/2 32/21 14/9 11/7 8/5 18/11 5/3 27/16 12/7 7/4 16/9 9/5 20/11 11/6 15/8 40/21 64/33 160/81 2/1',\n name: \"harry partch scale\"\n}, {\n scl: lamonte\n}, {\n scl: meantone\n}, {\n scl: mavila\n}, {\n scl: carlos_alpha\n}, {\n scl: colundi\n}, {\n scl: shares\n}, {\n scl: shares_sum\n}, {\n scl: liu_major\n}, {\n scl: liu_minor\n}, {\n scl: liu_melodic_minor\n}, {\n scl: liu_pentatonic\n}].map(function (opt) {\n return new _intonation2.default(opt);\n});\n\nvar scale = scales[0];\nvar handleChange = function handleChange() {};\n\nfunction build() {\n scales.forEach(function (scale, i) {\n scale.heading = document.createElement('div');\n scale.heading.innerHTML = scale.name;\n scale.heading.classList.add('heading');\n scale.heading.addEventListener('click', function () {\n pick(i);\n });\n scale_list.appendChild(scale.heading);\n });\n pick(0);\n}\nfunction build_options(el) {\n scales.forEach(function (scale, i) {\n var option = document.createElement('option');\n option.innerHTML = scale.name;\n option.value = i;\n el.appendChild(option);\n });\n el.addEventListener('input', function (e) {\n pick(e.target.value);\n });\n pick(0);\n}\n\nfunction pick(i) {\n if (scale) {\n scale.heading && scale.heading.classList.remove('selected');\n }\n scale = scales[i];\n scale.heading && scale.heading.classList.add('selected');\n handleChange(scale);\n}\n\nfunction current() {\n return scale;\n}\n\nfunction onChange(fn) {\n handleChange = fn;\n}\n\nfunction names() {\n return scales.map(function (scale) {\n return scale.name;\n });\n}\n\nexports.default = { scales: scales, current: current, build: build, build_options: build_options, pick: pick, names: names, onChange: onChange };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/scales.js\n// module id = 50\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.nx = undefined;\n\nvar _keys = require('babel-runtime/core-js/object/keys');\n\nvar _keys2 = _interopRequireDefault(_keys);\n\nexports.update_value_on_change = update_value_on_change;\nexports.update_radio_value_on_change = update_radio_value_on_change;\nexports.build_options = build_options;\n\nvar _nexusui = require('nexusui');\n\nvar _nexusui2 = _interopRequireDefault(_nexusui);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar nx = exports.nx = window.nx = {};\n\n/* ui - update an int/float value */\n\nfunction update_value_on_change(el, id, is_int, fn) {\n var label = document.querySelector(id + ' + .val');\n var update = function update(v) {\n label.innerHTML = is_int ? parseInt(v) : v.toFixed(2);\n fn && fn(v);\n };\n el.on('change', update);\n update(el.value);\n el.update = update;\n}\n\n/* ui - update a radio button */\n\nfunction update_radio_value_on_change(el, id, values, fn) {\n var old_v = el.active;\n var label = document.querySelector(id + ' + .val');\n var update = function update(v) {\n if (v === -1) {\n v = el.active = old_v;\n } else {\n old_v = v;\n }\n label.innerHTML = values[v][1];\n fn && fn(v);\n };\n el.on('change', update);\n update(el.active);\n el.update = update;\n}\n\n/* ui - bind/build a select dropdown */\n\nfunction build_options(el, lists, fn) {\n (0, _keys2.default)(lists).forEach(function (key) {\n var list = lists[key];\n var option = document.createElement('option');\n option.innerHTML = list.name;\n option.value = key;\n el.appendChild(option);\n });\n el.addEventListener('input', function (e) {\n fn(e.target.value);\n });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/ui.js\n// module id = 51\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/object/assign\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/babel-runtime/core-js/object/assign.js\n// module id = 52\n// module chunks = 0","module.exports = require('./_global').document && document.documentElement;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_html.js\n// module id = 53\n// module chunks = 0","module.exports = !require('./_descriptors') && !require('./_fails')(function(){\n return Object.defineProperty(require('./_dom-create')('div'), 'a', {get: function(){ return 7; }}).a != 7;\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_ie8-dom-define.js\n// module id = 54\n// module chunks = 0","// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = require('./_cof');\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){\n return cof(it) == 'String' ? it.split('') : Object(it);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_iobject.js\n// module id = 55\n// module chunks = 0","'use strict';\nvar LIBRARY = require('./_library')\n , $export = require('./_export')\n , redefine = require('./_redefine')\n , hide = require('./_hide')\n , has = require('./_has')\n , Iterators = require('./_iterators')\n , $iterCreate = require('./_iter-create')\n , setToStringTag = require('./_set-to-string-tag')\n , getPrototypeOf = require('./_object-gpo')\n , ITERATOR = require('./_wks')('iterator')\n , BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`\n , FF_ITERATOR = '@@iterator'\n , KEYS = 'keys'\n , VALUES = 'values';\n\nvar returnThis = function(){ return this; };\n\nmodule.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){\n $iterCreate(Constructor, NAME, next);\n var getMethod = function(kind){\n if(!BUGGY && kind in proto)return proto[kind];\n switch(kind){\n case KEYS: return function keys(){ return new Constructor(this, kind); };\n case VALUES: return function values(){ return new Constructor(this, kind); };\n } return function entries(){ return new Constructor(this, kind); };\n };\n var TAG = NAME + ' Iterator'\n , DEF_VALUES = DEFAULT == VALUES\n , VALUES_BUG = false\n , proto = Base.prototype\n , $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]\n , $default = $native || getMethod(DEFAULT)\n , $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined\n , $anyNative = NAME == 'Array' ? proto.entries || $native : $native\n , methods, key, IteratorPrototype;\n // Fix native\n if($anyNative){\n IteratorPrototype = getPrototypeOf($anyNative.call(new Base));\n if(IteratorPrototype !== Object.prototype){\n // Set @@toStringTag to native iterators\n setToStringTag(IteratorPrototype, TAG, true);\n // fix for some old engines\n if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis);\n }\n }\n // fix Array#{values, @@iterator}.name in V8 / FF\n if(DEF_VALUES && $native && $native.name !== VALUES){\n VALUES_BUG = true;\n $default = function values(){ return $native.call(this); };\n }\n // Define iterator\n if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){\n hide(proto, ITERATOR, $default);\n }\n // Plug for library\n Iterators[NAME] = $default;\n Iterators[TAG] = returnThis;\n if(DEFAULT){\n methods = {\n values: DEF_VALUES ? $default : getMethod(VALUES),\n keys: IS_SET ? $default : getMethod(KEYS),\n entries: $entries\n };\n if(FORCED)for(key in methods){\n if(!(key in proto))redefine(proto, key, methods[key]);\n } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);\n }\n return methods;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_iter-define.js\n// module id = 56\n// module chunks = 0","// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = require('./_an-object')\n , dPs = require('./_object-dps')\n , enumBugKeys = require('./_enum-bug-keys')\n , IE_PROTO = require('./_shared-key')('IE_PROTO')\n , Empty = function(){ /* empty */ }\n , PROTOTYPE = 'prototype';\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function(){\n // Thrash, waste and sodomy: IE GC bug\n var iframe = require('./_dom-create')('iframe')\n , i = enumBugKeys.length\n , lt = '<'\n , gt = '>'\n , iframeDocument;\n iframe.style.display = 'none';\n require('./_html').appendChild(iframe);\n iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n // createDict = iframe.contentWindow.Object;\n // html.removeChild(iframe);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n iframeDocument.close();\n createDict = iframeDocument.F;\n while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]];\n return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties){\n var result;\n if(O !== null){\n Empty[PROTOTYPE] = anObject(O);\n result = new Empty;\n Empty[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = createDict();\n return Properties === undefined ? result : dPs(result, Properties);\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-create.js\n// module id = 57\n// module chunks = 0","// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)\nvar $keys = require('./_object-keys-internal')\n , hiddenKeys = require('./_enum-bug-keys').concat('length', 'prototype');\n\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O){\n return $keys(O, hiddenKeys);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-gopn.js\n// module id = 58\n// module chunks = 0","var has = require('./_has')\n , toIObject = require('./_to-iobject')\n , arrayIndexOf = require('./_array-includes')(false)\n , IE_PROTO = require('./_shared-key')('IE_PROTO');\n\nmodule.exports = function(object, names){\n var O = toIObject(object)\n , i = 0\n , result = []\n , key;\n for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key);\n // Don't enum bug & hidden keys\n while(names.length > i)if(has(O, key = names[i++])){\n ~arrayIndexOf(result, key) || result.push(key);\n }\n return result;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-keys-internal.js\n// module id = 59\n// module chunks = 0","module.exports = require('./_hide');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_redefine.js\n// module id = 60\n// module chunks = 0","var ctx = require('./_ctx')\n , invoke = require('./_invoke')\n , html = require('./_html')\n , cel = require('./_dom-create')\n , global = require('./_global')\n , process = global.process\n , setTask = global.setImmediate\n , clearTask = global.clearImmediate\n , MessageChannel = global.MessageChannel\n , counter = 0\n , queue = {}\n , ONREADYSTATECHANGE = 'onreadystatechange'\n , defer, channel, port;\nvar run = function(){\n var id = +this;\n if(queue.hasOwnProperty(id)){\n var fn = queue[id];\n delete queue[id];\n fn();\n }\n};\nvar listener = function(event){\n run.call(event.data);\n};\n// Node.js 0.9+ & IE10+ has setImmediate, otherwise:\nif(!setTask || !clearTask){\n setTask = function setImmediate(fn){\n var args = [], i = 1;\n while(arguments.length > i)args.push(arguments[i++]);\n queue[++counter] = function(){\n invoke(typeof fn == 'function' ? fn : Function(fn), args);\n };\n defer(counter);\n return counter;\n };\n clearTask = function clearImmediate(id){\n delete queue[id];\n };\n // Node.js 0.8-\n if(require('./_cof')(process) == 'process'){\n defer = function(id){\n process.nextTick(ctx(run, id, 1));\n };\n // Browsers with MessageChannel, includes WebWorkers\n } else if(MessageChannel){\n channel = new MessageChannel;\n port = channel.port2;\n channel.port1.onmessage = listener;\n defer = ctx(port.postMessage, port, 1);\n // Browsers with postMessage, skip WebWorkers\n // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'\n } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){\n defer = function(id){\n global.postMessage(id + '', '*');\n };\n global.addEventListener('message', listener, false);\n // IE8-\n } else if(ONREADYSTATECHANGE in cel('script')){\n defer = function(id){\n html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){\n html.removeChild(this);\n run.call(id);\n };\n };\n // Rest old browsers\n } else {\n defer = function(id){\n setTimeout(ctx(run, id, 1), 0);\n };\n }\n}\nmodule.exports = {\n set: setTask,\n clear: clearTask\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_task.js\n// module id = 61\n// module chunks = 0","// 7.1.15 ToLength\nvar toInteger = require('./_to-integer')\n , min = Math.min;\nmodule.exports = function(it){\n return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_to-length.js\n// module id = 62\n// module chunks = 0","var classof = require('./_classof')\n , ITERATOR = require('./_wks')('iterator')\n , Iterators = require('./_iterators');\nmodule.exports = require('./_core').getIteratorMethod = function(it){\n if(it != undefined)return it[ITERATOR]\n || it['@@iterator']\n || Iterators[classof(it)];\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/core.get-iterator-method.js\n// module id = 63\n// module chunks = 0","var toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/isarray/index.js\n// module id = 65\n// module chunks = 0","'use strict';\n\nmodule.exports = Readable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar isArray = require('isarray');\n/*</replacement>*/\n\n/*<replacement>*/\nvar Duplex;\n/*</replacement>*/\n\nReadable.ReadableState = ReadableState;\n\n/*<replacement>*/\nvar EE = require('events').EventEmitter;\n\nvar EElistenerCount = function (emitter, type) {\n return emitter.listeners(type).length;\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream = require('./internal/streams/stream');\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar debugUtil = require('util');\nvar debug = void 0;\nif (debugUtil && debugUtil.debuglog) {\n debug = debugUtil.debuglog('stream');\n} else {\n debug = function () {};\n}\n/*</replacement>*/\n\nvar BufferList = require('./internal/streams/BufferList');\nvar StringDecoder;\n\nutil.inherits(Readable, Stream);\n\nvar kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];\n\nfunction prependListener(emitter, event, fn) {\n // Sadly this is not cacheable as some libraries bundle their own\n // event emitter implementation with them.\n if (typeof emitter.prependListener === 'function') {\n return emitter.prependListener(event, fn);\n } else {\n // This is a hack to make sure that our error handler is attached before any\n // userland ones. NEVER DO THIS. This is here only because this code needs\n // to continue to work with older versions of Node.js that do not include\n // the prependListener() method. The goal is to eventually remove this hack.\n if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];\n }\n}\n\nfunction ReadableState(options, stream) {\n Duplex = Duplex || require('./_stream_duplex');\n\n options = options || {};\n\n // object stream flag. Used to make read(n) ignore n and to\n // make all the buffer merging and length checks go away\n this.objectMode = !!options.objectMode;\n\n if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;\n\n // the point at which it stops calling _read() to fill the buffer\n // Note: 0 is a valid value, means \"don't call _read preemptively ever\"\n var hwm = options.highWaterMark;\n var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n // cast to ints.\n this.highWaterMark = ~~this.highWaterMark;\n\n // A linked list is used to store data chunks instead of an array because the\n // linked list can remove elements from the beginning faster than\n // array.shift()\n this.buffer = new BufferList();\n this.length = 0;\n this.pipes = null;\n this.pipesCount = 0;\n this.flowing = null;\n this.ended = false;\n this.endEmitted = false;\n this.reading = false;\n\n // a flag to be able to tell if the onwrite cb is called immediately,\n // or on a later tick. We set this to true at first, because any\n // actions that shouldn't happen until \"later\" should generally also\n // not happen before the first write call.\n this.sync = true;\n\n // whenever we return null, then we set a flag to say\n // that we're awaiting a 'readable' event emission.\n this.needReadable = false;\n this.emittedReadable = false;\n this.readableListening = false;\n this.resumeScheduled = false;\n\n // Crypto is kind of old and crusty. Historically, its default string\n // encoding is 'binary' so we have to make this configurable.\n // Everything else in the universe uses 'utf8', though.\n this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n // when piping, we only care about 'readable' events that happen\n // after read()ing all the bytes and not getting any pushback.\n this.ranOut = false;\n\n // the number of writers that are awaiting a drain event in .pipe()s\n this.awaitDrain = 0;\n\n // if true, a maybeReadMore has been scheduled\n this.readingMore = false;\n\n this.decoder = null;\n this.encoding = null;\n if (options.encoding) {\n if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n this.decoder = new StringDecoder(options.encoding);\n this.encoding = options.encoding;\n }\n}\n\nfunction Readable(options) {\n Duplex = Duplex || require('./_stream_duplex');\n\n if (!(this instanceof Readable)) return new Readable(options);\n\n this._readableState = new ReadableState(options, this);\n\n // legacy\n this.readable = true;\n\n if (options && typeof options.read === 'function') this._read = options.read;\n\n Stream.call(this);\n}\n\n// Manually shove something into the read() buffer.\n// This returns true if the highWaterMark has not been hit yet,\n// similar to how Writable.write() returns true if you should\n// write() some more.\nReadable.prototype.push = function (chunk, encoding) {\n var state = this._readableState;\n\n if (!state.objectMode && typeof chunk === 'string') {\n encoding = encoding || state.defaultEncoding;\n if (encoding !== state.encoding) {\n chunk = bufferShim.from(chunk, encoding);\n encoding = '';\n }\n }\n\n return readableAddChunk(this, state, chunk, encoding, false);\n};\n\n// Unshift should *always* be something directly out of read()\nReadable.prototype.unshift = function (chunk) {\n var state = this._readableState;\n return readableAddChunk(this, state, chunk, '', true);\n};\n\nReadable.prototype.isPaused = function () {\n return this._readableState.flowing === false;\n};\n\nfunction readableAddChunk(stream, state, chunk, encoding, addToFront) {\n var er = chunkInvalid(state, chunk);\n if (er) {\n stream.emit('error', er);\n } else if (chunk === null) {\n state.reading = false;\n onEofChunk(stream, state);\n } else if (state.objectMode || chunk && chunk.length > 0) {\n if (state.ended && !addToFront) {\n var e = new Error('stream.push() after EOF');\n stream.emit('error', e);\n } else if (state.endEmitted && addToFront) {\n var _e = new Error('stream.unshift() after end event');\n stream.emit('error', _e);\n } else {\n var skipAdd;\n if (state.decoder && !addToFront && !encoding) {\n chunk = state.decoder.write(chunk);\n skipAdd = !state.objectMode && chunk.length === 0;\n }\n\n if (!addToFront) state.reading = false;\n\n // Don't add to the buffer if we've decoded to an empty string chunk and\n // we're not in object mode\n if (!skipAdd) {\n // if we want the data now, just emit it.\n if (state.flowing && state.length === 0 && !state.sync) {\n stream.emit('data', chunk);\n stream.read(0);\n } else {\n // update the buffer info.\n state.length += state.objectMode ? 1 : chunk.length;\n if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);\n\n if (state.needReadable) emitReadable(stream);\n }\n }\n\n maybeReadMore(stream, state);\n }\n } else if (!addToFront) {\n state.reading = false;\n }\n\n return needMoreData(state);\n}\n\n// if it's past the high water mark, we can push in some more.\n// Also, if we have no data yet, we can stand some\n// more bytes. This is to work around cases where hwm=0,\n// such as the repl. Also, if the push() triggered a\n// readable event, and the user called read(largeNumber) such that\n// needReadable was set, then we ought to push more, so that another\n// 'readable' event will be triggered.\nfunction needMoreData(state) {\n return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);\n}\n\n// backwards compatibility.\nReadable.prototype.setEncoding = function (enc) {\n if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n this._readableState.decoder = new StringDecoder(enc);\n this._readableState.encoding = enc;\n return this;\n};\n\n// Don't raise the hwm > 8MB\nvar MAX_HWM = 0x800000;\nfunction computeNewHighWaterMark(n) {\n if (n >= MAX_HWM) {\n n = MAX_HWM;\n } else {\n // Get the next highest power of 2 to prevent increasing hwm excessively in\n // tiny amounts\n n--;\n n |= n >>> 1;\n n |= n >>> 2;\n n |= n >>> 4;\n n |= n >>> 8;\n n |= n >>> 16;\n n++;\n }\n return n;\n}\n\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction howMuchToRead(n, state) {\n if (n <= 0 || state.length === 0 && state.ended) return 0;\n if (state.objectMode) return 1;\n if (n !== n) {\n // Only flow one buffer at a time\n if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;\n }\n // If we're asking for more than the current hwm, then raise the hwm.\n if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);\n if (n <= state.length) return n;\n // Don't have enough\n if (!state.ended) {\n state.needReadable = true;\n return 0;\n }\n return state.length;\n}\n\n// you can override either this method, or the async _read(n) below.\nReadable.prototype.read = function (n) {\n debug('read', n);\n n = parseInt(n, 10);\n var state = this._readableState;\n var nOrig = n;\n\n if (n !== 0) state.emittedReadable = false;\n\n // if we're doing read(0) to trigger a readable event, but we\n // already have a bunch of data in the buffer, then just trigger\n // the 'readable' event and move on.\n if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {\n debug('read: emitReadable', state.length, state.ended);\n if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);\n return null;\n }\n\n n = howMuchToRead(n, state);\n\n // if we've ended, and we're now clear, then finish it up.\n if (n === 0 && state.ended) {\n if (state.length === 0) endReadable(this);\n return null;\n }\n\n // All the actual chunk generation logic needs to be\n // *below* the call to _read. The reason is that in certain\n // synthetic stream cases, such as passthrough streams, _read\n // may be a completely synchronous operation which may change\n // the state of the read buffer, providing enough data when\n // before there was *not* enough.\n //\n // So, the steps are:\n // 1. Figure out what the state of things will be after we do\n // a read from the buffer.\n //\n // 2. If that resulting state will trigger a _read, then call _read.\n // Note that this may be asynchronous, or synchronous. Yes, it is\n // deeply ugly to write APIs this way, but that still doesn't mean\n // that the Readable class should behave improperly, as streams are\n // designed to be sync/async agnostic.\n // Take note if the _read call is sync or async (ie, if the read call\n // has returned yet), so that we know whether or not it's safe to emit\n // 'readable' etc.\n //\n // 3. Actually pull the requested chunks out of the buffer and return.\n\n // if we need a readable event, then we need to do some reading.\n var doRead = state.needReadable;\n debug('need readable', doRead);\n\n // if we currently have less than the highWaterMark, then also read some\n if (state.length === 0 || state.length - n < state.highWaterMark) {\n doRead = true;\n debug('length less than watermark', doRead);\n }\n\n // however, if we've ended, then there's no point, and if we're already\n // reading, then it's unnecessary.\n if (state.ended || state.reading) {\n doRead = false;\n debug('reading or ended', doRead);\n } else if (doRead) {\n debug('do read');\n state.reading = true;\n state.sync = true;\n // if the length is currently zero, then we *need* a readable event.\n if (state.length === 0) state.needReadable = true;\n // call internal read method\n this._read(state.highWaterMark);\n state.sync = false;\n // If _read pushed data synchronously, then `reading` will be false,\n // and we need to re-evaluate how much data we can return to the user.\n if (!state.reading) n = howMuchToRead(nOrig, state);\n }\n\n var ret;\n if (n > 0) ret = fromList(n, state);else ret = null;\n\n if (ret === null) {\n state.needReadable = true;\n n = 0;\n } else {\n state.length -= n;\n }\n\n if (state.length === 0) {\n // If we have nothing in the buffer, then we want to know\n // as soon as we *do* get something into the buffer.\n if (!state.ended) state.needReadable = true;\n\n // If we tried to read() past the EOF, then emit end on the next tick.\n if (nOrig !== n && state.ended) endReadable(this);\n }\n\n if (ret !== null) this.emit('data', ret);\n\n return ret;\n};\n\nfunction chunkInvalid(state, chunk) {\n var er = null;\n if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {\n er = new TypeError('Invalid non-string/buffer chunk');\n }\n return er;\n}\n\nfunction onEofChunk(stream, state) {\n if (state.ended) return;\n if (state.decoder) {\n var chunk = state.decoder.end();\n if (chunk && chunk.length) {\n state.buffer.push(chunk);\n state.length += state.objectMode ? 1 : chunk.length;\n }\n }\n state.ended = true;\n\n // emit 'readable' now to make sure it gets picked up.\n emitReadable(stream);\n}\n\n// Don't emit readable right away in sync mode, because this can trigger\n// another read() call => stack overflow. This way, it might trigger\n// a nextTick recursion warning, but that's not so bad.\nfunction emitReadable(stream) {\n var state = stream._readableState;\n state.needReadable = false;\n if (!state.emittedReadable) {\n debug('emitReadable', state.flowing);\n state.emittedReadable = true;\n if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);\n }\n}\n\nfunction emitReadable_(stream) {\n debug('emit readable');\n stream.emit('readable');\n flow(stream);\n}\n\n// at this point, the user has presumably seen the 'readable' event,\n// and called read() to consume some data. that may have triggered\n// in turn another _read(n) call, in which case reading = true if\n// it's in progress.\n// However, if we're not ended, or reading, and the length < hwm,\n// then go ahead and try to read some more preemptively.\nfunction maybeReadMore(stream, state) {\n if (!state.readingMore) {\n state.readingMore = true;\n processNextTick(maybeReadMore_, stream, state);\n }\n}\n\nfunction maybeReadMore_(stream, state) {\n var len = state.length;\n while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {\n debug('maybeReadMore read 0');\n stream.read(0);\n if (len === state.length)\n // didn't get any data, stop spinning.\n break;else len = state.length;\n }\n state.readingMore = false;\n}\n\n// abstract method. to be overridden in specific implementation classes.\n// call cb(er, data) where data is <= n in length.\n// for virtual (non-string, non-buffer) streams, \"length\" is somewhat\n// arbitrary, and perhaps not very meaningful.\nReadable.prototype._read = function (n) {\n this.emit('error', new Error('_read() is not implemented'));\n};\n\nReadable.prototype.pipe = function (dest, pipeOpts) {\n var src = this;\n var state = this._readableState;\n\n switch (state.pipesCount) {\n case 0:\n state.pipes = dest;\n break;\n case 1:\n state.pipes = [state.pipes, dest];\n break;\n default:\n state.pipes.push(dest);\n break;\n }\n state.pipesCount += 1;\n debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);\n\n var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;\n\n var endFn = doEnd ? onend : cleanup;\n if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);\n\n dest.on('unpipe', onunpipe);\n function onunpipe(readable) {\n debug('onunpipe');\n if (readable === src) {\n cleanup();\n }\n }\n\n function onend() {\n debug('onend');\n dest.end();\n }\n\n // when the dest drains, it reduces the awaitDrain counter\n // on the source. This would be more elegant with a .once()\n // handler in flow(), but adding and removing repeatedly is\n // too slow.\n var ondrain = pipeOnDrain(src);\n dest.on('drain', ondrain);\n\n var cleanedUp = false;\n function cleanup() {\n debug('cleanup');\n // cleanup event handlers once the pipe is broken\n dest.removeListener('close', onclose);\n dest.removeListener('finish', onfinish);\n dest.removeListener('drain', ondrain);\n dest.removeListener('error', onerror);\n dest.removeListener('unpipe', onunpipe);\n src.removeListener('end', onend);\n src.removeListener('end', cleanup);\n src.removeListener('data', ondata);\n\n cleanedUp = true;\n\n // if the reader is waiting for a drain event from this\n // specific writer, then it would cause it to never start\n // flowing again.\n // So, if this is awaiting a drain, then we just call it now.\n // If we don't know, then assume that we are waiting for one.\n if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();\n }\n\n // If the user pushes more data while we're writing to dest then we'll end up\n // in ondata again. However, we only want to increase awaitDrain once because\n // dest will only emit one 'drain' event for the multiple writes.\n // => Introduce a guard on increasing awaitDrain.\n var increasedAwaitDrain = false;\n src.on('data', ondata);\n function ondata(chunk) {\n debug('ondata');\n increasedAwaitDrain = false;\n var ret = dest.write(chunk);\n if (false === ret && !increasedAwaitDrain) {\n // If the user unpiped during `dest.write()`, it is possible\n // to get stuck in a permanently paused state if that write\n // also returned false.\n // => Check whether `dest` is still a piping destination.\n if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {\n debug('false write response, pause', src._readableState.awaitDrain);\n src._readableState.awaitDrain++;\n increasedAwaitDrain = true;\n }\n src.pause();\n }\n }\n\n // if the dest has an error, then stop piping into it.\n // however, don't suppress the throwing behavior for this.\n function onerror(er) {\n debug('onerror', er);\n unpipe();\n dest.removeListener('error', onerror);\n if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);\n }\n\n // Make sure our error handler is attached before userland ones.\n prependListener(dest, 'error', onerror);\n\n // Both close and finish should trigger unpipe, but only once.\n function onclose() {\n dest.removeListener('finish', onfinish);\n unpipe();\n }\n dest.once('close', onclose);\n function onfinish() {\n debug('onfinish');\n dest.removeListener('close', onclose);\n unpipe();\n }\n dest.once('finish', onfinish);\n\n function unpipe() {\n debug('unpipe');\n src.unpipe(dest);\n }\n\n // tell the dest that it's being piped to\n dest.emit('pipe', src);\n\n // start the flow if it hasn't been started already.\n if (!state.flowing) {\n debug('pipe resume');\n src.resume();\n }\n\n return dest;\n};\n\nfunction pipeOnDrain(src) {\n return function () {\n var state = src._readableState;\n debug('pipeOnDrain', state.awaitDrain);\n if (state.awaitDrain) state.awaitDrain--;\n if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {\n state.flowing = true;\n flow(src);\n }\n };\n}\n\nReadable.prototype.unpipe = function (dest) {\n var state = this._readableState;\n\n // if we're not piping anywhere, then do nothing.\n if (state.pipesCount === 0) return this;\n\n // just one destination. most common case.\n if (state.pipesCount === 1) {\n // passed in one, but it's not the right one.\n if (dest && dest !== state.pipes) return this;\n\n if (!dest) dest = state.pipes;\n\n // got a match.\n state.pipes = null;\n state.pipesCount = 0;\n state.flowing = false;\n if (dest) dest.emit('unpipe', this);\n return this;\n }\n\n // slow case. multiple pipe destinations.\n\n if (!dest) {\n // remove all.\n var dests = state.pipes;\n var len = state.pipesCount;\n state.pipes = null;\n state.pipesCount = 0;\n state.flowing = false;\n\n for (var i = 0; i < len; i++) {\n dests[i].emit('unpipe', this);\n }return this;\n }\n\n // try to find the right one.\n var index = indexOf(state.pipes, dest);\n if (index === -1) return this;\n\n state.pipes.splice(index, 1);\n state.pipesCount -= 1;\n if (state.pipesCount === 1) state.pipes = state.pipes[0];\n\n dest.emit('unpipe', this);\n\n return this;\n};\n\n// set up data events if they are asked for\n// Ensure readable listeners eventually get something\nReadable.prototype.on = function (ev, fn) {\n var res = Stream.prototype.on.call(this, ev, fn);\n\n if (ev === 'data') {\n // Start flowing on next tick if stream isn't explicitly paused\n if (this._readableState.flowing !== false) this.resume();\n } else if (ev === 'readable') {\n var state = this._readableState;\n if (!state.endEmitted && !state.readableListening) {\n state.readableListening = state.needReadable = true;\n state.emittedReadable = false;\n if (!state.reading) {\n processNextTick(nReadingNextTick, this);\n } else if (state.length) {\n emitReadable(this, state);\n }\n }\n }\n\n return res;\n};\nReadable.prototype.addListener = Readable.prototype.on;\n\nfunction nReadingNextTick(self) {\n debug('readable nexttick read 0');\n self.read(0);\n}\n\n// pause() and resume() are remnants of the legacy readable stream API\n// If the user uses them, then switch into old mode.\nReadable.prototype.resume = function () {\n var state = this._readableState;\n if (!state.flowing) {\n debug('resume');\n state.flowing = true;\n resume(this, state);\n }\n return this;\n};\n\nfunction resume(stream, state) {\n if (!state.resumeScheduled) {\n state.resumeScheduled = true;\n processNextTick(resume_, stream, state);\n }\n}\n\nfunction resume_(stream, state) {\n if (!state.reading) {\n debug('resume read 0');\n stream.read(0);\n }\n\n state.resumeScheduled = false;\n state.awaitDrain = 0;\n stream.emit('resume');\n flow(stream);\n if (state.flowing && !state.reading) stream.read(0);\n}\n\nReadable.prototype.pause = function () {\n debug('call pause flowing=%j', this._readableState.flowing);\n if (false !== this._readableState.flowing) {\n debug('pause');\n this._readableState.flowing = false;\n this.emit('pause');\n }\n return this;\n};\n\nfunction flow(stream) {\n var state = stream._readableState;\n debug('flow', state.flowing);\n while (state.flowing && stream.read() !== null) {}\n}\n\n// wrap an old-style stream as the async data source.\n// This is *not* part of the readable stream interface.\n// It is an ugly unfortunate mess of history.\nReadable.prototype.wrap = function (stream) {\n var state = this._readableState;\n var paused = false;\n\n var self = this;\n stream.on('end', function () {\n debug('wrapped end');\n if (state.decoder && !state.ended) {\n var chunk = state.decoder.end();\n if (chunk && chunk.length) self.push(chunk);\n }\n\n self.push(null);\n });\n\n stream.on('data', function (chunk) {\n debug('wrapped data');\n if (state.decoder) chunk = state.decoder.write(chunk);\n\n // don't skip over falsy values in objectMode\n if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;\n\n var ret = self.push(chunk);\n if (!ret) {\n paused = true;\n stream.pause();\n }\n });\n\n // proxy all the other methods.\n // important when wrapping filters and duplexes.\n for (var i in stream) {\n if (this[i] === undefined && typeof stream[i] === 'function') {\n this[i] = function (method) {\n return function () {\n return stream[method].apply(stream, arguments);\n };\n }(i);\n }\n }\n\n // proxy certain important events.\n for (var n = 0; n < kProxyEvents.length; n++) {\n stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n]));\n }\n\n // when we try to consume some more bytes, simply unpause the\n // underlying stream.\n self._read = function (n) {\n debug('wrapped _read', n);\n if (paused) {\n paused = false;\n stream.resume();\n }\n };\n\n return self;\n};\n\n// exposed for testing purposes only.\nReadable._fromList = fromList;\n\n// Pluck off n bytes from an array of buffers.\n// Length is the combined lengths of all the buffers in the list.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromList(n, state) {\n // nothing buffered\n if (state.length === 0) return null;\n\n var ret;\n if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {\n // read it all, truncate the list\n if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);\n state.buffer.clear();\n } else {\n // read part of list\n ret = fromListPartial(n, state.buffer, state.decoder);\n }\n\n return ret;\n}\n\n// Extracts only enough buffered data to satisfy the amount requested.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromListPartial(n, list, hasStrings) {\n var ret;\n if (n < list.head.data.length) {\n // slice is the same for buffers and strings\n ret = list.head.data.slice(0, n);\n list.head.data = list.head.data.slice(n);\n } else if (n === list.head.data.length) {\n // first chunk is a perfect match\n ret = list.shift();\n } else {\n // result spans more than one buffer\n ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);\n }\n return ret;\n}\n\n// Copies a specified amount of characters from the list of buffered data\n// chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBufferString(n, list) {\n var p = list.head;\n var c = 1;\n var ret = p.data;\n n -= ret.length;\n while (p = p.next) {\n var str = p.data;\n var nb = n > str.length ? str.length : n;\n if (nb === str.length) ret += str;else ret += str.slice(0, n);\n n -= nb;\n if (n === 0) {\n if (nb === str.length) {\n ++c;\n if (p.next) list.head = p.next;else list.head = list.tail = null;\n } else {\n list.head = p;\n p.data = str.slice(nb);\n }\n break;\n }\n ++c;\n }\n list.length -= c;\n return ret;\n}\n\n// Copies a specified amount of bytes from the list of buffered data chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBuffer(n, list) {\n var ret = bufferShim.allocUnsafe(n);\n var p = list.head;\n var c = 1;\n p.data.copy(ret);\n n -= p.data.length;\n while (p = p.next) {\n var buf = p.data;\n var nb = n > buf.length ? buf.length : n;\n buf.copy(ret, ret.length - n, 0, nb);\n n -= nb;\n if (n === 0) {\n if (nb === buf.length) {\n ++c;\n if (p.next) list.head = p.next;else list.head = list.tail = null;\n } else {\n list.head = p;\n p.data = buf.slice(nb);\n }\n break;\n }\n ++c;\n }\n list.length -= c;\n return ret;\n}\n\nfunction endReadable(stream) {\n var state = stream._readableState;\n\n // If we get here before consuming all the bytes, then that is a\n // bug in node. Should never happen.\n if (state.length > 0) throw new Error('\"endReadable()\" called on non-empty stream');\n\n if (!state.endEmitted) {\n state.ended = true;\n processNextTick(endReadableNT, state, stream);\n }\n}\n\nfunction endReadableNT(state, stream) {\n // Check that we didn't get one last unshift.\n if (!state.endEmitted && state.length === 0) {\n state.endEmitted = true;\n stream.readable = false;\n stream.emit('end');\n }\n}\n\nfunction forEach(xs, f) {\n for (var i = 0, l = xs.length; i < l; i++) {\n f(xs[i], i);\n }\n}\n\nfunction indexOf(xs, x) {\n for (var i = 0, l = xs.length; i < l; i++) {\n if (xs[i] === x) return i;\n }\n return -1;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/readable-stream/lib/_stream_readable.js\n// module id = 66\n// module chunks = 0","// a transform stream is a readable/writable stream where you do\n// something with the data. Sometimes it's called a \"filter\",\n// but that's not a great name for it, since that implies a thing where\n// some bits pass through, and others are simply ignored. (That would\n// be a valid example of a transform, of course.)\n//\n// While the output is causally related to the input, it's not a\n// necessarily symmetric or synchronous transformation. For example,\n// a zlib stream might take multiple plain-text writes(), and then\n// emit a single compressed chunk some time in the future.\n//\n// Here's how this works:\n//\n// The Transform stream has all the aspects of the readable and writable\n// stream classes. When you write(chunk), that calls _write(chunk,cb)\n// internally, and returns false if there's a lot of pending writes\n// buffered up. When you call read(), that calls _read(n) until\n// there's enough pending readable data buffered up.\n//\n// In a transform stream, the written data is placed in a buffer. When\n// _read(n) is called, it transforms the queued up data, calling the\n// buffered _write cb's as it consumes chunks. If consuming a single\n// written chunk would result in multiple output chunks, then the first\n// outputted bit calls the readcb, and subsequent chunks just go into\n// the read buffer, and will cause it to emit 'readable' if necessary.\n//\n// This way, back-pressure is actually determined by the reading side,\n// since _read has to be called to start processing a new chunk. However,\n// a pathological inflate type of transform can cause excessive buffering\n// here. For example, imagine a stream where every byte of input is\n// interpreted as an integer from 0-255, and then results in that many\n// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in\n// 1kb of data being output. In this case, you could write a very small\n// amount of input, and end up with a very large amount of output. In\n// such a pathological inflating mechanism, there'd be no way to tell\n// the system to stop doing the transform. A single 4MB write could\n// cause the system to run out of memory.\n//\n// However, even in such a pathological case, only a single written chunk\n// would be consumed, and then the rest would wait (un-transformed) until\n// the results of the previous transformed chunk were consumed.\n\n'use strict';\n\nmodule.exports = Transform;\n\nvar Duplex = require('./_stream_duplex');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(Transform, Duplex);\n\nfunction TransformState(stream) {\n this.afterTransform = function (er, data) {\n return afterTransform(stream, er, data);\n };\n\n this.needTransform = false;\n this.transforming = false;\n this.writecb = null;\n this.writechunk = null;\n this.writeencoding = null;\n}\n\nfunction afterTransform(stream, er, data) {\n var ts = stream._transformState;\n ts.transforming = false;\n\n var cb = ts.writecb;\n\n if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));\n\n ts.writechunk = null;\n ts.writecb = null;\n\n if (data !== null && data !== undefined) stream.push(data);\n\n cb(er);\n\n var rs = stream._readableState;\n rs.reading = false;\n if (rs.needReadable || rs.length < rs.highWaterMark) {\n stream._read(rs.highWaterMark);\n }\n}\n\nfunction Transform(options) {\n if (!(this instanceof Transform)) return new Transform(options);\n\n Duplex.call(this, options);\n\n this._transformState = new TransformState(this);\n\n var stream = this;\n\n // start out asking for a readable event once data is transformed.\n this._readableState.needReadable = true;\n\n // we have implemented the _read method, and done the other things\n // that Readable wants before the first _read call, so unset the\n // sync guard flag.\n this._readableState.sync = false;\n\n if (options) {\n if (typeof options.transform === 'function') this._transform = options.transform;\n\n if (typeof options.flush === 'function') this._flush = options.flush;\n }\n\n // When the writable side finishes, then flush out anything remaining.\n this.once('prefinish', function () {\n if (typeof this._flush === 'function') this._flush(function (er, data) {\n done(stream, er, data);\n });else done(stream);\n });\n}\n\nTransform.prototype.push = function (chunk, encoding) {\n this._transformState.needTransform = false;\n return Duplex.prototype.push.call(this, chunk, encoding);\n};\n\n// This is the part where you do stuff!\n// override this function in implementation classes.\n// 'chunk' is an input chunk.\n//\n// Call `push(newChunk)` to pass along transformed output\n// to the readable side. You may call 'push' zero or more times.\n//\n// Call `cb(err)` when you are done with this chunk. If you pass\n// an error, then that'll put the hurt on the whole operation. If you\n// never call cb(), then you'll never get another chunk.\nTransform.prototype._transform = function (chunk, encoding, cb) {\n throw new Error('_transform() is not implemented');\n};\n\nTransform.prototype._write = function (chunk, encoding, cb) {\n var ts = this._transformState;\n ts.writecb = cb;\n ts.writechunk = chunk;\n ts.writeencoding = encoding;\n if (!ts.transforming) {\n var rs = this._readableState;\n if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);\n }\n};\n\n// Doesn't matter what the args are here.\n// _transform does all the work.\n// That we got here means that the readable side wants more data.\nTransform.prototype._read = function (n) {\n var ts = this._transformState;\n\n if (ts.writechunk !== null && ts.writecb && !ts.transforming) {\n ts.transforming = true;\n this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);\n } else {\n // mark that we need a transform, so that any data that comes in\n // will get processed, now that we've asked for it.\n ts.needTransform = true;\n }\n};\n\nfunction done(stream, er, data) {\n if (er) return stream.emit('error', er);\n\n if (data !== null && data !== undefined) stream.push(data);\n\n // if there's nothing in the write buffer, then that means\n // that nothing more will ever be provided\n var ws = stream._writableState;\n var ts = stream._transformState;\n\n if (ws.length) throw new Error('Calling transform done when ws.length != 0');\n\n if (ts.transforming) throw new Error('Calling transform done when still transforming');\n\n return stream.push(null);\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/readable-stream/lib/_stream_transform.js\n// module id = 67\n// module chunks = 0","module.exports = require('events').EventEmitter;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/readable-stream/lib/internal/streams/stream-browser.js\n// module id = 68\n// module chunks = 0","var apply = Function.prototype.apply;\n\n// DOM APIs, for completeness\n\nexports.setTimeout = function() {\n return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);\n};\nexports.setInterval = function() {\n return new Timeout(apply.call(setInterval, window, arguments), clearInterval);\n};\nexports.clearTimeout =\nexports.clearInterval = function(timeout) {\n if (timeout) {\n timeout.close();\n }\n};\n\nfunction Timeout(id, clearFn) {\n this._id = id;\n this._clearFn = clearFn;\n}\nTimeout.prototype.unref = Timeout.prototype.ref = function() {};\nTimeout.prototype.close = function() {\n this._clearFn.call(window, this._id);\n};\n\n// Does not start the time, just sets up the members needed.\nexports.enroll = function(item, msecs) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = msecs;\n};\n\nexports.unenroll = function(item) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = -1;\n};\n\nexports._unrefActive = exports.active = function(item) {\n clearTimeout(item._idleTimeoutId);\n\n var msecs = item._idleTimeout;\n if (msecs >= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// setimmediate attaches itself to the global object\nrequire(\"setimmediate\");\nexports.setImmediate = setImmediate;\nexports.clearImmediate = clearImmediate;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/timers-browserify/main.js\n// module id = 69\n// module chunks = 0","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.load = undefined;\n\nvar _promise = require(\"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar files = [\n// \"gun_violence\",\n\"mass_shootings_lite\", \"gun_violence_by_month\"];\nvar parse = require('csv-parse');\n\nvar dataPromises = files.map(function (name) {\n return fetch('./data/' + name + '.csv').then(function (rows) {\n return rows.text();\n }).then(function (text) {\n return new _promise2.default(function (resolve, reject) {\n parse(text, {}, function (_, lines) {\n return resolve(lines);\n });\n });\n }).then(function (lines) {\n // console.log(name, lines)\n var h = lines.shift();\n return {\n name: name,\n h: h,\n lines: lines.filter(function (s) {\n return !!s;\n })\n };\n });\n});\nvar allPromises = _promise2.default.all(dataPromises).then(function (data) {\n return data.reduce(function (a, b) {\n // console.log(b)\n a[b.name] = b;\n return a;\n }, {});\n});\nvar load = function load() {\n return allPromises;\n};\n\nexports.load = load;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/data.js\n// module id = 70\n// module chunks = 0","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar keys = {};\nvar key_numbers = {};\nvar letters = \"zxcvbnmasdfghjklqwertyuiop\";\nvar numbers = \"1234567890\";\n\nvar callback = function callback() {};\n\nletters.toUpperCase().split(\"\").map(function (k, i) {\n keys[k.charCodeAt(0)] = i;\n});\n\nnumbers.split(\"\").map(function (k, i) {\n keys[k.charCodeAt(0)] = i + letters.length;\n key_numbers[k.charCodeAt(0)] = true;\n});\n\nwindow.addEventListener(\"keydown\", keydown, true);\nfunction keydown(e) {\n if (e.altKey || e.ctrlKey || e.metaKey) {\n e.stopPropagation();\n return;\n }\n if (document.activeElement instanceof HTMLInputElement && e.keyCode in key_numbers) {\n e.stopPropagation();\n return;\n }\n if (!(e.keyCode in keys)) return;\n var index = keys[e.keyCode];\n if (e.shiftKey) index += letters.length;\n index -= 7;\n callback(index);\n}\n\nfunction listen(fn) {\n callback = fn;\n}\n\nexports.default = { listen: listen };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/keys.js\n// module id = 71\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.note_values = exports.MidiWriter = undefined;\n\nvar _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');\n\nvar _slicedToArray3 = _interopRequireDefault(_slicedToArray2);\n\nexports.midi_init = midi_init;\nexports.play_note = play_note;\nexports.play_midi_note = play_midi_note;\nexports.play_sequence = play_sequence;\nexports.play_interval_sequence = play_interval_sequence;\nexports.export_pattern_as_midi = export_pattern_as_midi;\n\nvar _tone = require('tone');\n\nvar _tone2 = _interopRequireDefault(_tone);\n\nvar _webmidi = require('webmidi');\n\nvar _webmidi2 = _interopRequireDefault(_webmidi);\n\nvar _scales = require('./scales');\n\nvar _scales2 = _interopRequireDefault(_scales);\n\nvar _util = require('./util');\n\nvar _kalimba = require('./kalimba');\n\nvar _kalimba2 = _interopRequireDefault(_kalimba);\n\nvar _FileSaver = require('file-saver/FileSaver');\n\nvar _ui = require('./ui');\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar midiDevice = void 0;\nvar sendPitchBend = false;\n\nvar MidiWriter = exports.MidiWriter = require('midi-writer-js');\n\nvar note_values = exports.note_values = [[8, '8 measures', 8 * 512], [4, '4 measures', 4 * 512], [2, '2 measures', 2 * 512], [1, 'whole note', 512], [1 / 2, 'half note', 256], [1 / 3, 'third note', [170, 170, 171]], [1 / 4, 'quarter note', 128], [1 / 5, 'fifth note', [51, 51, 51, 51, 52]], [1 / 6, 'sixth note', [85, 85, 86, 85, 85, 86]], [1 / 8, 'eighth note', 64], [1 / 10, 'tenth note', [25, 26, 26, 25, 26, 25, 26, 26, 25, 26]], [1 / 12, 'twelfth note', [21, 21, 22, 21, 21, 22, 21, 21, 22, 21, 21, 22]], [1 / 16, 'sixteenth note', 32], [1 / 32, 'thirtysecond note', 16]];\n\nfunction midi_init() {\n _webmidi2.default.enable(midi_ready);\n function midi_ready(err) {\n if (err) {\n console.error('webmidi failed to initialize');\n return;\n }\n if (!_webmidi2.default.outputs.length) {\n console.error('no MIDI output found');\n return;\n }\n console.log(_webmidi2.default.inputs);\n console.log(_webmidi2.default.outputs);\n if (_webmidi2.default.outputs.length > 1) {\n var filtered = _webmidi2.default.outputs.filter(function (output) {\n return output.name.match(/prodipe/i);\n });\n if (filtered.length) {\n // midiDevice = filtered[0]\n }\n }\n // midiDevice = midiDevice || WebMidi.outputs[0]\n // console.log(midiDevice.name)\n }\n}\n\n/* play a single note */\n\nfunction play_note(index, duration) {\n var channel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : \"all\";\n var exporting = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n var rest = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;\n var defer = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;\n\n // console.log(index)\n var scale = _scales2.default.current();\n var freq = scale.index(index + Math.round(_ui.nx.offset.value), _ui.nx.octave.value);\n var midi_note = (0, _util.ftom)(freq);\n var cents = midi_note % 1;\n if (cents > 0.5) {\n midi_note += 1;\n cents -= 1;\n }\n cents *= 2;\n midi_note = Math.floor(midi_note);\n if ((midiDevice || exporting) && midi_note > 127) return 0;\n var note = _tone2.default.Frequency(Math.floor(midi_note), \"midi\").toNote();\n var defer_time = 30000 / _tone2.default.Transport.bpm.value * defer / 128;\n console.log(defer, defer_time);\n if (exporting || midiDevice) {\n duration = duration || 60000 / _tone2.default.Transport.bpm.value;\n if (!exporting) {\n if (defer) {\n setTimeout(function () {\n play_midi_note(note, cents, channel, duration);\n }, defer);\n } else {\n play_midi_note(note, cents, channel, duration);\n }\n }\n } else if (defer) {\n setTimeout(function () {\n _kalimba2.default.play(freq);\n }, defer_time);\n } else {\n _kalimba2.default.play(freq);\n }\n return note;\n}\n\nfunction play_midi_note(note, cents, channel, duration) {\n midiDevice.playNote(note, channel, { duration: duration });\n if (sendPitchBend) {\n midiDevice.sendPitchBend(cents, channel);\n }\n}\n\n/* play the next note in sequence */\n\nfunction play_sequence(i, bounds, diff, note_time) {\n var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : \"all\";\n var exporting = arguments[5];\n var rows = bounds.rows,\n min = bounds.min,\n max = bounds.max;\n\n var count = rows.length * rows[0].length;\n if (i >= count) i = 0;\n var y = Math.floor(i / rows[0].length);\n var x = i % rows[0].length;\n // if (!x) console.log(y)\n var n = rows[y][x];\n i += 1;\n if (i >= count) i = 0;\n var midi_note = play_note((0, _util.norm)(n, min, max) * _ui.nx.multiply.value, note_time, channel, exporting);\n return [i, [midi_note]];\n}\n\n/* play the next row as an interval */\n\nfunction play_interval_sequence(i, bounds, diff, note_time) {\n var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : \"all\";\n var exporting = arguments[5];\n var rows = bounds.rows,\n min = bounds.min,\n max = bounds.max;\n\n var count = rows.length;\n if (i >= count) i = 0;\n var y = i % count;\n var row = rows[y];\n if (!row) {\n i = 0;return;\n }\n var row_min = Math.min.apply(Math, row);\n // const row_max = Math.max.apply(Math, row)\n var row_f0 = (0, _util.norm)(row_min, min, max);\n var row_root = row_f0 * _ui.nx.multiply.value;\n var notes = row.map(function (n) {\n var note = row_root + (0, _util.norm)(n - row_min, diff.min, diff.max) * _ui.nx.interval.value;\n play_note(note, note_time, channel, exporting);\n });\n i += 1;\n return [i, notes];\n}\n\n/* generate a 1-track midi file by calling the play function repeatedly */\n\nfunction export_pattern_as_midi(datasetName, bounds, diff, tempo, timingIndex, play_fn) {\n // const behavior = document.querySelector('#behavior').value\n var rows = bounds.rows;\n // let count = behavior === 'sequence' ? rows[0].length * rows.length : rows.length\n\n var count = rows[0].length;\n var notes = void 0,\n timings = void 0,\n wait = void 0;\n var note_time = void 0;\n // let timing = note_values[timingIndex][2]\n var midi_track = new MidiWriter.Track();\n midi_track.setTempo(tempo);\n for (var i = 0, len = count; i < len; i++) {\n // if (timing.length) {\n // note_time = timing[i % timing.length]\n // } else {\n // note_time = timing\n // }\n // midi_track.addEvent(new MidiWriter.NoteEvent({ pitch: notes, duration: 't' + note_time }))\n var _play_fn = play_fn(i, bounds, note_time, \"all\", true);\n\n var _play_fn2 = (0, _slicedToArray3.default)(_play_fn, 4);\n\n i = _play_fn2[0];\n notes = _play_fn2[1];\n timings = _play_fn2[2];\n wait = _play_fn2[3];\n console.log(i, notes, timings);\n for (var j = 0; j < notes.length; j++) {\n midi_track.addEvent(new MidiWriter.NoteEvent({ pitch: notes[j], duration: 't' + timings[j], wait: wait }));\n }\n }\n var writer = new MidiWriter.Writer([midi_track]);\n var blob = (0, _util.dataURItoBlob)(writer.dataUri());\n (0, _FileSaver.saveAs)(blob, 'Recording - ' + datasetName + '.mid');\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/midi.js\n// module id = 72\n// module chunks = 0","\"use strict\";\n\nexports.__esModule = true;\n\nvar _isIterable2 = require(\"../core-js/is-iterable\");\n\nvar _isIterable3 = _interopRequireDefault(_isIterable2);\n\nvar _getIterator2 = require(\"../core-js/get-iterator\");\n\nvar _getIterator3 = _interopRequireDefault(_getIterator2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nexports.default = function () {\n function sliceIterator(arr, i) {\n var _arr = [];\n var _n = true;\n var _d = false;\n var _e = undefined;\n\n try {\n for (var _i = (0, _getIterator3.default)(arr), _s; !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"]) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n }\n\n return function (arr, i) {\n if (Array.isArray(arr)) {\n return arr;\n } else if ((0, _isIterable3.default)(Object(arr))) {\n return sliceIterator(arr, i);\n } else {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance\");\n }\n };\n}();\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/babel-runtime/helpers/slicedToArray.js\n// module id = 73\n// module chunks = 0","/* FileSaver.js\n * A saveAs() FileSaver implementation.\n * 1.3.2\n * 2016-06-16 18:25:19\n *\n * By Eli Grey, http://eligrey.com\n * License: MIT\n * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md\n */\n\n/*global self */\n/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */\n\n/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */\n\nvar saveAs = saveAs || (function(view) {\n\t\"use strict\";\n\t// IE <10 is explicitly unsupported\n\tif (typeof view === \"undefined\" || typeof navigator !== \"undefined\" && /MSIE [1-9]\\./.test(navigator.userAgent)) {\n\t\treturn;\n\t}\n\tvar\n\t\t doc = view.document\n\t\t // only get URL when necessary in case Blob.js hasn't overridden it yet\n\t\t, get_URL = function() {\n\t\t\treturn view.URL || view.webkitURL || view;\n\t\t}\n\t\t, save_link = doc.createElementNS(\"http://www.w3.org/1999/xhtml\", \"a\")\n\t\t, can_use_save_link = \"download\" in save_link\n\t\t, click = function(node) {\n\t\t\tvar event = new MouseEvent(\"click\");\n\t\t\tnode.dispatchEvent(event);\n\t\t}\n\t\t, is_safari = /constructor/i.test(view.HTMLElement) || view.safari\n\t\t, is_chrome_ios =/CriOS\\/[\\d]+/.test(navigator.userAgent)\n\t\t, throw_outside = function(ex) {\n\t\t\t(view.setImmediate || view.setTimeout)(function() {\n\t\t\t\tthrow ex;\n\t\t\t}, 0);\n\t\t}\n\t\t, force_saveable_type = \"application/octet-stream\"\n\t\t// the Blob API is fundamentally broken as there is no \"downloadfinished\" event to subscribe to\n\t\t, arbitrary_revoke_timeout = 1000 * 40 // in ms\n\t\t, revoke = function(file) {\n\t\t\tvar revoker = function() {\n\t\t\t\tif (typeof file === \"string\") { // file is an object URL\n\t\t\t\t\tget_URL().revokeObjectURL(file);\n\t\t\t\t} else { // file is a File\n\t\t\t\t\tfile.remove();\n\t\t\t\t}\n\t\t\t};\n\t\t\tsetTimeout(revoker, arbitrary_revoke_timeout);\n\t\t}\n\t\t, dispatch = function(filesaver, event_types, event) {\n\t\t\tevent_types = [].concat(event_types);\n\t\t\tvar i = event_types.length;\n\t\t\twhile (i--) {\n\t\t\t\tvar listener = filesaver[\"on\" + event_types[i]];\n\t\t\t\tif (typeof listener === \"function\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlistener.call(filesaver, event || filesaver);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\tthrow_outside(ex);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t, auto_bom = function(blob) {\n\t\t\t// prepend BOM for UTF-8 XML and text/* types (including HTML)\n\t\t\t// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF\n\t\t\tif (/^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(blob.type)) {\n\t\t\t\treturn new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});\n\t\t\t}\n\t\t\treturn blob;\n\t\t}\n\t\t, FileSaver = function(blob, name, no_auto_bom) {\n\t\t\tif (!no_auto_bom) {\n\t\t\t\tblob = auto_bom(blob);\n\t\t\t}\n\t\t\t// First try a.download, then web filesystem, then object URLs\n\t\t\tvar\n\t\t\t\t filesaver = this\n\t\t\t\t, type = blob.type\n\t\t\t\t, force = type === force_saveable_type\n\t\t\t\t, object_url\n\t\t\t\t, dispatch_all = function() {\n\t\t\t\t\tdispatch(filesaver, \"writestart progress write writeend\".split(\" \"));\n\t\t\t\t}\n\t\t\t\t// on any filesys errors revert to saving with object URLs\n\t\t\t\t, fs_error = function() {\n\t\t\t\t\tif ((is_chrome_ios || (force && is_safari)) && view.FileReader) {\n\t\t\t\t\t\t// Safari doesn't allow downloading of blob urls\n\t\t\t\t\t\tvar reader = new FileReader();\n\t\t\t\t\t\treader.onloadend = function() {\n\t\t\t\t\t\t\tvar url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');\n\t\t\t\t\t\t\tvar popup = view.open(url, '_blank');\n\t\t\t\t\t\t\tif(!popup) view.location.href = url;\n\t\t\t\t\t\t\turl=undefined; // release reference before dispatching\n\t\t\t\t\t\t\tfilesaver.readyState = filesaver.DONE;\n\t\t\t\t\t\t\tdispatch_all();\n\t\t\t\t\t\t};\n\t\t\t\t\t\treader.readAsDataURL(blob);\n\t\t\t\t\t\tfilesaver.readyState = filesaver.INIT;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// don't create more object URLs than needed\n\t\t\t\t\tif (!object_url) {\n\t\t\t\t\t\tobject_url = get_URL().createObjectURL(blob);\n\t\t\t\t\t}\n\t\t\t\t\tif (force) {\n\t\t\t\t\t\tview.location.href = object_url;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar opened = view.open(object_url, \"_blank\");\n\t\t\t\t\t\tif (!opened) {\n\t\t\t\t\t\t\t// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html\n\t\t\t\t\t\t\tview.location.href = object_url;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfilesaver.readyState = filesaver.DONE;\n\t\t\t\t\tdispatch_all();\n\t\t\t\t\trevoke(object_url);\n\t\t\t\t}\n\t\t\t;\n\t\t\tfilesaver.readyState = filesaver.INIT;\n\n\t\t\tif (can_use_save_link) {\n\t\t\t\tobject_url = get_URL().createObjectURL(blob);\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\tsave_link.href = object_url;\n\t\t\t\t\tsave_link.download = name;\n\t\t\t\t\tclick(save_link);\n\t\t\t\t\tdispatch_all();\n\t\t\t\t\trevoke(object_url);\n\t\t\t\t\tfilesaver.readyState = filesaver.DONE;\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfs_error();\n\t\t}\n\t\t, FS_proto = FileSaver.prototype\n\t\t, saveAs = function(blob, name, no_auto_bom) {\n\t\t\treturn new FileSaver(blob, name || blob.name || \"download\", no_auto_bom);\n\t\t}\n\t;\n\t// IE 10+ (native saveAs)\n\tif (typeof navigator !== \"undefined\" && navigator.msSaveOrOpenBlob) {\n\t\treturn function(blob, name, no_auto_bom) {\n\t\t\tname = name || blob.name || \"download\";\n\n\t\t\tif (!no_auto_bom) {\n\t\t\t\tblob = auto_bom(blob);\n\t\t\t}\n\t\t\treturn navigator.msSaveOrOpenBlob(blob, name);\n\t\t};\n\t}\n\n\tFS_proto.abort = function(){};\n\tFS_proto.readyState = FS_proto.INIT = 0;\n\tFS_proto.WRITING = 1;\n\tFS_proto.DONE = 2;\n\n\tFS_proto.error =\n\tFS_proto.onwritestart =\n\tFS_proto.onprogress =\n\tFS_proto.onwrite =\n\tFS_proto.onabort =\n\tFS_proto.onerror =\n\tFS_proto.onwriteend =\n\t\tnull;\n\n\treturn saveAs;\n}(\n\t typeof self !== \"undefined\" && self\n\t|| typeof window !== \"undefined\" && window\n\t|| this.content\n));\n// `self` is undefined in Firefox for Android content script context\n// while `this` is nsIContentFrameMessageManager\n// with an attribute `content` that corresponds to the window\n\nif (typeof module !== \"undefined\" && module.exports) {\n module.exports.saveAs = saveAs;\n} else if ((typeof define !== \"undefined\" && define !== null) && (define.amd !== null)) {\n define(\"FileSaver.js\", function() {\n return saveAs;\n });\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/file-saver/FileSaver.js\n// module id = 74\n// module chunks = 0","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Nexus\"] = factory();\n\telse\n\t\troot[\"Nexus\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar NexusUI = _interopRequire(__webpack_require__(1));\n\t\n\tmodule.exports = NexusUI;\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\texports.colors = colors;\n\texports.context = context;\n\texports.clock = clock;\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\"use strict\";\n\t\n\tvar Interfaces = _interopRequire(__webpack_require__(2));\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar Rack = _interopRequire(__webpack_require__(38));\n\t\n\tvar Tune = _interopRequire(__webpack_require__(40));\n\t\n\tvar Transform = _interopRequireWildcard(__webpack_require__(39));\n\t\n\tvar Counter = __webpack_require__(28);\n\tvar Radio = __webpack_require__(41);\n\tvar Drunk = __webpack_require__(27);\n\tvar Sequence = __webpack_require__(26);\n\tvar Matrix = __webpack_require__(25);\n\t\n\tvar WAAClock = _interopRequire(__webpack_require__(42));\n\t\n\tvar Interval = _interopRequire(__webpack_require__(45));\n\t\n\t/**\n\tNexusUI => created as Nexus\n\t*/\n\t\n\tvar NexusUI = (function () {\n\t function NexusUI(context) {\n\t _classCallCheck(this, NexusUI);\n\t\n\t for (var key in Interfaces) {\n\t this[key] = Interfaces[key];\n\t }\n\t\n\t for (var key in math) {\n\t this[key] = math[key];\n\t }\n\t\n\t var Core = {\n\t Rack: Rack\n\t };\n\t\n\t var Models = {\n\t Counter: Counter,\n\t Radio: Radio,\n\t Drunk: Drunk,\n\t Sequence: Sequence,\n\t Matrix: Matrix\n\t };\n\t\n\t for (var key in Models) {\n\t this[key] = Models[key];\n\t }\n\t\n\t for (var key in Core) {\n\t this[key] = Core[key];\n\t }\n\t\n\t var DefaultContext = window.AudioContext || window.webkitAudioContext;\n\t this._context = context || new DefaultContext();\n\t\n\t this.tune = new Tune();\n\t this.note = this.tune.note.bind(this.tune);\n\t\n\t this.clock = new WAAClock(this._context);\n\t this.clock.start();\n\t this.Interval = Interval;\n\t\n\t this.colors = {\n\t accent: \"#2bb\",\n\t fill: \"#eee\",\n\t light: \"#fff\",\n\t dark: \"#333\",\n\t mediumLight: \"#ccc\",\n\t mediumDark: \"#666\"\n\t };\n\t\n\t this.transform = Transform;\n\t this.add = Transform.add;\n\t\n\t this.Add = {};\n\t for (var key in Interfaces) {\n\t this.Add[key] = Transform.add.bind(this, key);\n\t }\n\t\n\t /* create default component size */\n\t /* jshint ignore:start */\n\t var existingStylesheets = document.getElementsByTagName(\"style\");\n\t var defaultSizeDeclaration = \"[nexus-ui]{height:5000px;width:5000px}\";\n\t var defaultStyleNode = document.createElement(\"style\");\n\t defaultStyleNode.type = \"text/css\";\n\t defaultStyleNode.innerHTML = defaultSizeDeclaration;\n\t if (existingStylesheets.length > 0) {\n\t var parent = existingStylesheets[0].parentNode;\n\t parent.insertBefore(defaultStyleNode, existingStylesheets[0]);\n\t } else {\n\t document.write(\"<style>\" + defaultSizeDeclaration + \"</style>\");\n\t }\n\t /* jshint ignore:end */\n\t }\n\t\n\t _createClass(NexusUI, {\n\t context: {\n\t get: function () {\n\t return this._context;\n\t },\n\t set: function (ctx) {\n\t this.clock.stop();\n\t this._context = ctx;\n\t this.clock = new WAAClock(this.context);\n\t this.clock.start();\n\t }\n\t }\n\t });\n\t\n\t return NexusUI;\n\t})();\n\t\n\tvar Nexus = new NexusUI();\n\t\n\tfunction colors() {\n\t return Nexus.colors;\n\t}\n\t\n\tfunction context() {\n\t return Nexus.context;\n\t}\n\t\n\tfunction clock() {\n\t return Nexus.clock;\n\t}\n\t\n\texports[\"default\"] = Nexus;\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tmodule.exports = {\n\t Position: __webpack_require__(3),\n\t Slider: __webpack_require__(14),\n\t Toggle: __webpack_require__(15),\n\t /* Range: require('./rangeslider'),\n\t Waveform: require('./waveform'), */\n\t Button: __webpack_require__(16),\n\t TextButton: __webpack_require__(18),\n\t RadioButton: __webpack_require__(19),\n\t Number: __webpack_require__(20),\n\t Select: __webpack_require__(21),\n\t Dial: __webpack_require__(22),\n\t Piano: __webpack_require__(23),\n\t Sequencer: __webpack_require__(24),\n\t Pan2D: __webpack_require__(29),\n\t Tilt: __webpack_require__(30),\n\t Multislider: __webpack_require__(31),\n\t Pan: __webpack_require__(33),\n\t Envelope: __webpack_require__(34),\n\t Spectrogram: __webpack_require__(35),\n\t Meter: __webpack_require__(36),\n\t Oscilloscope: __webpack_require__(37)\n\t};\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\t\n\tvar Interaction = _interopRequireWildcard(__webpack_require__(12));\n\t\n\t/**\n\t* Position\n\t*\n\t* @description Two-dimensional touch slider.\n\t*\n\t* @demo <span nexus-ui=\"position\"></span>\n\t*\n\t* @example\n\t* var position = new Nexus.Position('#target')\n\t*\n\t* @example\n\t* var position = new Nexus.Position('#target',{\n\t* 'size': [200,200],\n\t* 'mode': 'absolute', // \"absolute\" or \"relative\"\n\t* 'x': 0.5, // initial x value\n\t* 'minX': 0,\n\t* 'maxX': 1,\n\t* 'stepX': 0,\n\t* 'y': 0.5, // initial y value\n\t* 'minY': 0,\n\t* 'maxY': 1,\n\t* 'stepY': 0\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data is an object with x and y properties containing the x and y values of the interface.\n\t*\n\t* @outputexample\n\t* position.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Position = (function (_Interface) {\n\t function Position() {\n\t _classCallCheck(this, Position);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [200, 200],\n\t mode: \"absolute\",\n\t minX: 0,\n\t maxX: 1,\n\t stepX: 0,\n\t x: 0.5,\n\t minY: 0,\n\t maxY: 1,\n\t stepY: 0,\n\t y: 0.5\n\t };\n\t\n\t _get(Object.getPrototypeOf(Position.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._x = new Step(this.settings.minX, this.settings.maxX, this.settings.stepX, this.settings.x);\n\t this._y = new Step(this.settings.minY, this.settings.maxY, this.settings.stepY, this.settings.y);\n\t\n\t this.position = {\n\t x: new Interaction.Handle(this.settings.mode, \"horizontal\", [0, this.width], [this.height, 0]),\n\t y: new Interaction.Handle(this.settings.mode, \"vertical\", [0, this.width], [this.height, 0])\n\t };\n\t this.position.x.value = this._x.normalized;\n\t this.position.y.value = this._y.normalized;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(Position, _Interface);\n\t\n\t _createClass(Position, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.knob = svg.create(\"circle\");\n\t this.element.appendChild(this.knob);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t this.position.x.resize([0, this.width], [this.height, 0]);\n\t this.position.y.resize([0, this.width], [this.height, 0]);\n\t\n\t this._minDimension = Math.min(this.width, this.height);\n\t\n\t this.knobRadius = {\n\t off: ~ ~(this._minDimension / 100) * 5 + 5 };\n\t this.knobRadius.on = this.knobRadius.off * 2;\n\t\n\t this.knob.setAttribute(\"cx\", this.width / 2);\n\t this.knob.setAttribute(\"cy\", this.height / 2);\n\t this.knob.setAttribute(\"r\", this.knobRadius.off);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.knob.setAttribute(\"fill\", this.colors.accent);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (this.clicked) {\n\t // this.knobRadius = 30;\n\t this.knob.setAttribute(\"r\", this.knobRadius.on);\n\t } else {\n\t // this.knobRadius = 15;\n\t this.knob.setAttribute(\"r\", this.knobRadius.off);\n\t }\n\t\n\t this.knobCoordinates = {\n\t x: this._x.normalized * this.width,\n\t y: this.height - this._y.normalized * this.height\n\t };\n\t\n\t this.knob.setAttribute(\"cx\", this.knobCoordinates.x);\n\t this.knob.setAttribute(\"cy\", this.knobCoordinates.y);\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.position.x.anchor = this.mouse;\n\t this.position.y.anchor = this.mouse;\n\t this.move();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.clicked) {\n\t this.position.x.update(this.mouse);\n\t this.position.y.update(this.mouse);\n\t this._x.updateNormal(this.position.x.value);\n\t this._y.updateNormal(this.position.y.value);\n\t this.emit(\"change\", {\n\t x: this._x.value,\n\t y: this._y.value\n\t });\n\t this.render();\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t this.render();\n\t }\n\t },\n\t x: {\n\t\n\t /**\n\t * The interface's x value. When set, it will automatically adjust to fit min/max/step settings of the interface.\n\t * @type {object}\n\t * @example position.x = 0.5;\n\t */\n\t\n\t get: function () {\n\t return this._x.value;\n\t },\n\t set: function (value) {\n\t this._x.update(value);\n\t this.emit(\"change\", {\n\t x: this._x.value,\n\t y: this._y.value\n\t });\n\t this.render();\n\t }\n\t },\n\t y: {\n\t\n\t /**\n\t * The interface's y values. When set, it will automatically adjust to fit min/max/step settings of the interface.\n\t * @type {object}\n\t * @example position.x = 0.5;\n\t */\n\t\n\t get: function () {\n\t return this._y.value;\n\t },\n\t set: function (value) {\n\t this._y.update(value);\n\t this.emit(\"change\", {\n\t x: this._x.value,\n\t y: this._y.value\n\t });\n\t this.render();\n\t }\n\t },\n\t normalized: {\n\t get: function () {\n\t return {\n\t x: this._x.normalized,\n\t y: this._y.normalized\n\t };\n\t }\n\t },\n\t minX: {\n\t\n\t /**\n\t * The lower limit of value on the x axis\n\t * @type {object}\n\t */\n\t\n\t get: function () {\n\t return this._x.min;\n\t },\n\t set: function (v) {\n\t this._x.min = v;\n\t this.render();\n\t }\n\t },\n\t minY: {\n\t\n\t /**\n\t * The lower limit of value on the y axis\n\t * @type {object}\n\t */\n\t\n\t get: function () {\n\t return this._y.min;\n\t },\n\t set: function (v) {\n\t this._y.min = v;\n\t this.render();\n\t }\n\t },\n\t maxX: {\n\t\n\t /**\n\t * The upper limit of value on the x axis\n\t * @type {object}\n\t */\n\t\n\t get: function () {\n\t return this._x.max;\n\t },\n\t set: function (v) {\n\t this._x.max = v;\n\t this.render();\n\t }\n\t },\n\t maxY: {\n\t\n\t /**\n\t * The upper limit of value on the y axis\n\t * @type {object}\n\t */\n\t\n\t get: function () {\n\t return this._y.max;\n\t },\n\t set: function (v) {\n\t this._y.max = v;\n\t this.render();\n\t }\n\t },\n\t stepX: {\n\t\n\t /**\n\t * The incremental step of values on the x axis\n\t * @type {object}\n\t */\n\t\n\t get: function () {\n\t return this._x.step;\n\t },\n\t set: function (v) {\n\t this._x.step = v;\n\t this.render();\n\t }\n\t },\n\t stepY: {\n\t\n\t /**\n\t * The incremental step of values on the y axis\n\t * @type {object}\n\t */\n\t\n\t get: function () {\n\t return this._y.step;\n\t },\n\t set: function (v) {\n\t this._y.step = v;\n\t this.render();\n\t }\n\t },\n\t mode: {\n\t\n\t /**\n\t Absolute mode (position's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: \"absolute\".\n\t @type {string}\n\t @example position.mode = \"relative\";\n\t */\n\t\n\t get: function () {\n\t return this.position.x.mode;\n\t },\n\t set: function (v) {\n\t this.position.x.mode = v;\n\t this.position.y.mode = v;\n\t }\n\t }\n\t });\n\t\n\t return Position;\n\t})(Interface);\n\t\n\tmodule.exports = Position;\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar math = __webpack_require__(5);\n\t\n\tmodule.exports = {\n\t\n\t create: function (type) {\n\t return document.createElementNS(\"http://www.w3.org/2000/svg\", type);\n\t },\n\t\n\t arc: function (x, y, radius, startAngle, endAngle) {\n\t\n\t var start = math.toCartesian(radius, endAngle);\n\t var end = math.toCartesian(radius, startAngle);\n\t\n\t var largeArcFlag = endAngle - startAngle <= 180 ? \"0\" : \"1\";\n\t\n\t var d = [\"M\", start.x + x, start.y + y, \"A\", radius, radius, 0, largeArcFlag, 0, end.x + x, end.y + y].join(\" \");\n\t\n\t return d;\n\t },\n\t\n\t radialGradient: function (defs, numberOfStops) {\n\t\n\t var id = \"gradient\" + math.ri(100000000000);\n\t var stops = [];\n\t\n\t var gradient = document.createElementNS(\"http://www.w3.org/2000/svg\", \"radialGradient\");\n\t gradient.setAttribute(\"id\", id);\n\t gradient.setAttribute(\"cx\", \"50%\");\n\t gradient.setAttribute(\"cy\", \"50%\");\n\t gradient.setAttribute(\"r\", \"50%\");\n\t\n\t defs.appendChild(gradient);\n\t\n\t for (var i = 0; i < numberOfStops; i++) {\n\t var _stop = document.createElementNS(\"http://www.w3.org/2000/svg\", \"stop\");\n\t _stop.setAttribute(\"id\", \"stop\" + i);\n\t //stop.setAttribute('offset', '70%');\n\t //stop.setAttribute('stop-color', 'White');\n\t gradient.appendChild(_stop);\n\t stops.push(_stop);\n\t }\n\t\n\t return {\n\t id: id,\n\t stops: stops,\n\t element: gradient\n\t };\n\t }\n\t\n\t};\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\t/**\n\t * Limit a number to within a minimum and maximum\n\t * @param {number} value Input value\n\t * @param {number} min Lower limit\n\t * @param {number} max Upper limit\n\t * @return {number} The input value constrained within the lower and upper limits\n\t * @example\n\t * Nexus.clip(11,0,10) // returns 10\n\t * Nexus.clip(-1,0,10) // returns 0\n\t * Nexus.clip(5,0,10) // returns 5\n\t */\n\t\n\texports.clip = function (value, min, max) {\n\t return Math.min(Math.max(value, min), max);\n\t};\n\t\n\texports.normalize = function (value, min, max) {\n\t return (value - min) / (max - min);\n\t};\n\t\n\t/**\n\t * Scale a value from one range to another range.\n\t * @param {number} inNum Input value\n\t * @param {number} inMin Input range minimum\n\t * @param {number} inMax Input range maximum\n\t * @param {number} outMin Output range minimum\n\t * @param {number} outMax Output range maximum\n\t * @return {number} The input value scaled to its new range\n\t * @example\n\t * Nexus.scale(0.5,0,1,0,10) // returns 5\n\t * Nexus.scale(0.9,0,1,1,0) // returns 0.1\n\t */\n\texports.scale = function (inNum, inMin, inMax, outMin, outMax) {\n\t if (inMin === inMax) {\n\t return outMin;\n\t }\n\t return (inNum - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;\n\t};\n\t\n\texports.toPolar = function (x, y) {\n\t var r = Math.sqrt(x * x + y * y);\n\t\n\t var theta = Math.atan2(y, x);\n\t if (theta < 0) {\n\t theta = theta + 2 * Math.PI;\n\t }\n\t return { radius: r, angle: theta };\n\t};\n\t\n\texports.toCartesian = function (radius, angle) {\n\t var cos = Math.cos(angle);\n\t var sin = Math.sin(angle);\n\t return { x: radius * cos, y: radius * sin * -1 };\n\t};\n\t/*\n\texports.polarToCartesian(centerX, centerY, radius, angleInDegrees) {\n\t var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;\n\t\n\t return {\n\t x: centerX + (radius * Math.cos(angleInRadians)),\n\t y: centerY + (radius * Math.sin(angleInRadians))\n\t };\n\t} */\n\t\n\texports.prune = function (data, scale) {\n\t return parseFloat(data.toFixed(scale));\n\t};\n\t\n\texports.invert = function (inNum) {\n\t return exports.scale(inNum, 1, 0, 0, 1);\n\t};\n\t\n\t/**\n\t * Convert a MIDi note number to a frequency value in equal temperament.\n\t * @param {number} midi MIDI note value\n\t * @return {number} Frequence value\n\t * @example\n\t * Nexus.mtof(60) // returns the frequency number of Middle C\n\t */\n\texports.mtof = function (midi) {\n\t return Math.pow(2, (midi - 69) / 12) * 440;\n\t};\n\t\n\t/**\n\t * Interpolate between two numbers\n\t * @param {number} loc Interpolation index (0-1)\n\t * @param {number} min Lower value\n\t * @param {number} max Upper value\n\t * @return {number} Interpolated value\n\t * @example\n\t * Nexus.interp(0.5,2,4) // returns 3\n\t * Nexus.interp(0.1,0,10) // returns 1\n\t */\n\texports.interp = function (loc, min, max) {\n\t return loc * (max - min) + min;\n\t};\n\t\n\t/**\n\t * Return a random choice from a list of arguments\n\t * @return {various} One random argument\n\t * @example\n\t * Nexus.pick(1,2,3,4) // returns 1, 2, 3, or 4\n\t * Nexus.pick(function1,function2) // returns either function1 or function2\n\t */\n\texports.pick = function () {\n\t return arguments[~ ~(Math.random() * arguments.length)];\n\t};\n\t\n\t/**\n\t * Returns an octave multiplier for frequency values\n\t * @param {number} num Relative octave number (e.g. -1 for one octave down, 1 for one octave up)\n\t * @return {number} Octave multiplier\n\t * @example\n\t * Nexus.octave(-1) // returns 0.5\n\t * Nexus.octave(0) // returns 1\n\t * Nexus.octave(1) // returns 2\n\t * Nexus.octave(2) // returns 4\n\t */\n\texports.octave = function (num) {\n\t return Math.pow(2, num);\n\t};\n\t\n\t/**\n\t * Random integer generator. If no second argument is given, will return random integer from 0 to bound1.\n\t * @param {number} bound1 Minimum random value\n\t * @param {number} bound2 Maximum random value\n\t * @return {number} Random integer between lower and upper boundary\n\t * @example\n\t * Nexus.ri(10) // returns random int from 0 to 10\n\t * Nexus.ri(20,2000) // returns random int from 20 to 2000\n\t */\n\texports.ri = function (bound1, bound2) {\n\t if (!bound2) {\n\t bound2 = bound1;\n\t bound1 = 0;\n\t }\n\t var low = Math.min(bound1, bound2);\n\t var high = Math.max(bound1, bound2);\n\t return Math.floor(Math.random() * (high - low) + low);\n\t};\n\t\n\t/**\n\t * Random float number generator. If no second argument is given, will return random float from 0 to bound1.\n\t * @param {number} bound1 Minimum random value\n\t * @param {number} bound2 Maximum random value\n\t * @return {number} Random float between lower and upper boundary\n\t * @example\n\t * Nexus.rf(1) // returns random float from 0 to 1\n\t * Nexus.rf(1,2) // returns random float from 1 to 2\n\t */\n\texports.rf = function (bound1, bound2) {\n\t if (!bound2) {\n\t bound2 = bound1;\n\t bound1 = 0;\n\t }\n\t var low = Math.min(bound1, bound2);\n\t var high = Math.max(bound1, bound2);\n\t return Math.random() * (high - low) + low;\n\t};\n\t\n\texports.cycle = function (input, min, max) {\n\t input++;\n\t if (input >= max) {\n\t input = min;\n\t }\n\t return input;\n\t};\n\t\n\t/**\n\t * Average an array of numbers\n\t * @param {Array} data Array of numbers to average\n\t * @return {number} Average of the input data\n\t * @example\n\t * Nexus.average([0,2,4,6,8,10]) // returns 5\n\t */\n\texports.average = function (data) {\n\t var total = 0;\n\t for (var i = 0; i < data.length; i++) {\n\t total += data[i];\n\t }\n\t return total / data.length;\n\t};\n\t\n\t/**\n\t * Get the distance from one (x,y) point to another (x,y) point\n\t * @param {number} x1 x of first point\n\t * @param {number} y1 y of first point\n\t * @param {number} x2 x of second point\n\t * @param {number} y2 y of second poiny\n\t * @return {number} Distance\n\t * @example\n\t * Nexus.distance(0,0,3,4) // returns 5\n\t */\n\texports.distance = function (x1, y1, x2, y2) {\n\t var a = x1 - x2;\n\t var b = y1 - y2;\n\t return Math.sqrt(a * a + b * b);\n\t};\n\t\n\texports.gainToDB = function (gain) {\n\t return 20 * Math.log10(gain);\n\t};\n\t\n\t/**\n\t * Flip a coin, returning either 0 or 1 according to a probability\n\t * @param {number} [odds=0.5] Likelihood of returning 1\n\t * @return {number} 1 or 0\n\t * @example\n\t * Nexus.coin(0.1) // returns 1 (10% of the time) or 0 (90% of the time)\n\t */\n\texports.coin = function () {\n\t var odds = arguments[0] === undefined ? 0.5 : arguments[0];\n\t\n\t if (exports.rf(0, 1) < odds) {\n\t return 1;\n\t } else {\n\t return 0;\n\t }\n\t};\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar dom = __webpack_require__(7);\n\tvar util = __webpack_require__(8);\n\tvar touch = __webpack_require__(9);\n\tvar EventEmitter = __webpack_require__(10);\n\t\n\tvar colors = __webpack_require__(1).colors;\n\t\n\t/**\n\tInterface\n\t*/\n\t\n\tvar Interface = (function (_EventEmitter) {\n\t function Interface(args, options, defaults) {\n\t _classCallCheck(this, Interface);\n\t\n\t _get(Object.getPrototypeOf(Interface.prototype), \"constructor\", this).call(this);\n\t this.type = this.constructor.name;\n\t this.settings = this.parseSettings(args, options, defaults);\n\t this.mouse = {};\n\t this.wait = false;\n\t this.colors = {};\n\t var defaultColors = colors(); // jshint ignore:line\n\t this.colors.accent = defaultColors.accent;\n\t this.colors.fill = defaultColors.fill;\n\t this.colors.light = defaultColors.light;\n\t this.colors.dark = defaultColors.dark;\n\t this.colors.mediumLight = defaultColors.mediumLight;\n\t this.colors.mediumDark = defaultColors.mediumDark;\n\t }\n\t\n\t _inherits(Interface, _EventEmitter);\n\t\n\t _createClass(Interface, {\n\t parseSettings: {\n\t value: function parseSettings(args, options, defaults) {\n\t\n\t options.unshift(\"target\");\n\t defaults.defaultSize = defaults.size.splice(0, 2);\n\t defaults.size = false;\n\t\n\t var settings = {\n\t target: document.body,\n\t colors: {}, // should inherit from a colors module,\n\t snapWithParent: true,\n\t event: function event() {},\n\t component: false\n\t };\n\t\n\t for (var key in defaults) {\n\t settings[key] = defaults[key];\n\t }\n\t\n\t for (var i = 0; i < args.length; i++) {\n\t // grabs the next argument\n\t var setting = args[i];\n\t // if it's an object, it must be the settings object\n\t if (util.isObject(setting)) {\n\t for (var key in setting) {\n\t settings[key] = setting[key];\n\t }\n\t // if it's a function, it must be the event setting\n\t } else if (typeof setting === \"function\") {\n\t settings.event = setting;\n\t // otherwise, consider it one of the widget's custom options\n\t } else if (options.length >= 1) {\n\t // grab the first option -- i.e. 'target'\n\t var key = options.splice(0, 1)[0];\n\t settings[key] = setting;\n\t }\n\t }\n\t\n\t /* handle common settings */\n\t\n\t // target\n\t this.parent = dom.parseElement(settings.target);\n\t\n\t // nexus-ui attribute\n\t if (this.parent && this.parent instanceof HTMLElement && !settings.component) {\n\t if (!this.parent.hasAttribute(\"nexus-ui\")) {\n\t this.parent.setAttribute(\"nexus-ui\", \"\");\n\t }\n\t }\n\t\n\t // size\n\t\n\t if (settings.size && Array.isArray(settings.size) && settings.snapWithParent) {\n\t this.width = settings.size[0];\n\t this.height = settings.size[1];\n\t this.parent.style.width = this.width + \"px\";\n\t this.parent.style.height = this.height + \"px\";\n\t } else if (settings.snapWithParent && !settings.component) {\n\t\n\t this.width = parseFloat(window.getComputedStyle(this.parent, null).getPropertyValue(\"width\").replace(\"px\", \"\"));\n\t this.height = parseFloat(window.getComputedStyle(this.parent, null).getPropertyValue(\"height\").replace(\"px\", \"\"));\n\t\n\t if (this.width == 5000) {\n\t this.width = settings.defaultSize[0];\n\t this.parent.style.width = this.parent.width = this.width + \"px\";\n\t }\n\t if (this.height == 5000) {\n\t this.height = settings.defaultSize[1];\n\t this.parent.style.height = this.parent.height = this.height + \"px\";\n\t }\n\t } else {\n\t settings.size = settings.defaultSize;\n\t this.width = settings.size[0];\n\t this.height = settings.size[1];\n\t }\n\t\n\t // event\n\t if (settings.event) {\n\t this.event = this.on(\"change\", settings.event);\n\t } else {\n\t this.event = false;\n\t }\n\t\n\t return settings;\n\t }\n\t },\n\t init: {\n\t value: function init() {\n\t this.buildFrame();\n\t this.buildInterface();\n\t this.sizeInterface();\n\t this.attachListeners();\n\t this.colorInterface();\n\t this.finalTouches();\n\t }\n\t },\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = svg.create(\"svg\");\n\t this.element.setAttribute(\"width\", this.width);\n\t this.element.setAttribute(\"height\", this.height);\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {}\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {}\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {}\n\t },\n\t attachListeners: {\n\t value: function attachListeners() {\n\t var _this = this;\n\t\n\t this.interactionTarget = this.interactionTarget || this.element;\n\t\n\t // Setup interaction\n\t if (touch.exists) {\n\t this.interactionTarget.addEventListener(\"touchstart\", function (evt) {\n\t return _this.preTouch(evt);\n\t });\n\t this.interactionTarget.addEventListener(\"touchmove\", function (evt) {\n\t return _this.preTouchMove(evt);\n\t });\n\t this.interactionTarget.addEventListener(\"touchend\", function (evt) {\n\t return _this.preTouchRelease(evt);\n\t });\n\t }\n\t this.boundPreMove = function (evt) {\n\t return _this.preMove(evt);\n\t };\n\t this.boundPreRelease = function (evt) {\n\t return _this.preRelease(evt);\n\t };\n\t this.interactionTarget.addEventListener(\"mousedown\", function (evt) {\n\t return _this.preClick(evt);\n\t });\n\t }\n\t },\n\t finalTouches: {\n\t value: function finalTouches() {\n\t this.element.style.cursor = \"pointer\";\n\t }\n\t },\n\t preClick: {\n\t value: function preClick(e) {\n\t // 10000 getComputedStyle calls takes 100 ms.\n\t // .:. one takes about .01ms\n\t if (this.element instanceof HTMLElement) {\n\t this.width = window.getComputedStyle(this.element, null).getPropertyValue(\"width\").replace(\"px\", \"\");\n\t }\n\t // 10000 getComputedStyle calls takes 40 ms.\n\t // .:. one takes about .004ms\n\t this.offset = dom.findPosition(this.element);\n\t this.mouse = dom.locateMouse(e, this.offset);\n\t this.clicked = true;\n\t this.click();\n\t this.moveEvent = document.addEventListener(\"mousemove\", this.boundPreMove);\n\t this.releaseEvent = document.addEventListener(\"mouseup\", this.boundPreRelease);\n\t this.emit(\"click\");\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t },\n\t preMove: {\n\t value: function preMove(e) {\n\t var _this = this;\n\t\n\t if (!this.wait) {\n\t this.mouse = dom.locateMouse(e, this.offset);\n\t this.move();\n\t this.wait = true;\n\t setTimeout(function () {\n\t _this.wait = false;\n\t }, 25);\n\t }\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t },\n\t preRelease: {\n\t value: function preRelease(e) {\n\t this.mouse = dom.locateMouse(e, this.offset);\n\t this.clicked = false;\n\t this.release();\n\t this.emit(\"release\");\n\t document.removeEventListener(\"mousemove\", this.boundPreMove);\n\t document.removeEventListener(\"mouseup\", this.boundPreRelease);\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t },\n\t click: {\n\t value: function click() {}\n\t },\n\t move: {\n\t value: function move() {}\n\t },\n\t release: {\n\t value: function release() {}\n\t },\n\t preTouch: {\n\t\n\t /* touch */\n\t\n\t value: function preTouch(e) {\n\t if (this.element instanceof HTMLElement) {\n\t this.width = window.getComputedStyle(this.element, null).getPropertyValue(\"width\").replace(\"px\", \"\");\n\t }\n\t this.offset = dom.findPosition(this.element);\n\t this.mouse = dom.locateTouch(e, this.offset);\n\t this.clicked = true;\n\t this.touch(e);\n\t this.emit(\"click\");\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t },\n\t preTouchMove: {\n\t value: function preTouchMove(e) {\n\t if (this.clicked) {\n\t this.mouse = dom.locateTouch(e, this.offset);\n\t this.touchMove();\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t }\n\t },\n\t preTouchRelease: {\n\t value: function preTouchRelease(e) {\n\t this.mouse = dom.locateTouch(e, this.offset);\n\t this.clicked = false;\n\t this.touchRelease();\n\t this.emit(\"release\");\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t },\n\t touch: {\n\t value: function touch() {\n\t this.click();\n\t }\n\t },\n\t touchMove: {\n\t value: function touchMove() {\n\t this.move();\n\t }\n\t },\n\t touchRelease: {\n\t value: function touchRelease() {\n\t this.release();\n\t }\n\t },\n\t resize: {\n\t\n\t /**\n\t * Resize the interface\n\t * @param width {number} New width in pixels\n\t * @param height {number} New height in pixels\n\t *\n\t * @example\n\t * button.resize(100,100);\n\t */\n\t\n\t value: function resize(width, height) {\n\t this.width = width;\n\t this.height = height;\n\t this.parent.style.width = this.width + \"px\";\n\t this.parent.style.height = this.height + \"px\";\n\t this.element.setAttribute(\"width\", this.width);\n\t this.element.setAttribute(\"height\", this.height);\n\t this.sizeInterface();\n\t }\n\t },\n\t empty: {\n\t value: function empty() {\n\t while (this.element.lastChild) {\n\t this.element.removeChild(this.element.lastChild);\n\t }\n\t }\n\t },\n\t destroy: {\n\t\n\t /**\n\t * Remove the interface from the page and cancel its event listener(s).\n\t *\n\t * @example\n\t * button.destroy();\n\t */\n\t\n\t value: function destroy() {\n\t this.empty();\n\t this.parent.removeChild(this.element);\n\t this.removeAllListeners();\n\t if (this.instrument) {\n\t delete this.instrument[this.id];\n\t }\n\t this.customDestroy();\n\t }\n\t },\n\t customDestroy: {\n\t value: function customDestroy() {}\n\t },\n\t colorize: {\n\t value: function colorize(type, color) {\n\t this.colors[type] = color;\n\t this.colorInterface();\n\t }\n\t }\n\t });\n\t\n\t return Interface;\n\t})(EventEmitter);\n\t\n\tmodule.exports = Interface;\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\texports.findPosition = function (el) {\n\t var viewportOffset = el.getBoundingClientRect();\n\t var top = viewportOffset.top + window.scrollY;\n\t var left = viewportOffset.left + window.scrollX;\n\t return { top: top, left: left };\n\t};\n\t\n\texports.parseElement = function (parent) {\n\t if (typeof parent === \"string\") {\n\t parent = document.getElementById(parent.replace(\"#\", \"\"));\n\t }\n\t\n\t if (parent instanceof HTMLElement || parent instanceof SVGElement) {\n\t return parent;\n\t } else {\n\t return \"No valid parent argument\";\n\t }\n\t};\n\t\n\texports.locateMouse = function (e, offset) {\n\t return {\n\t x: e.pageX - offset.left,\n\t y: e.pageY - offset.top\n\t };\n\t};\n\t\n\texports.locateTouch = function (e, offset) {\n\t return {\n\t x: e.targetTouches.length ? e.targetTouches[0].pageX - offset.left : false,\n\t y: e.targetTouches.length ? e.targetTouches[0].pageY - offset.top : false\n\t };\n\t};\n\t\n\texports.SmartCanvas = function (parent) {\n\t var _this = this;\n\t\n\t this.element = document.createElement(\"canvas\");\n\t this.context = this.element.getContext(\"2d\");\n\t parent.appendChild(this.element);\n\t\n\t this.resize = function (w, h) {\n\t _this.element.width = w * 2;\n\t _this.element.height = h * 2;\n\t _this.element.style.width = w + \"px\";\n\t _this.element.style.height = h + \"px\";\n\t };\n\t};\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\texports.isObject = function (obj) {\n\t if (typeof obj === \"object\" && !Array.isArray(obj) && obj !== null && obj instanceof SVGElement === false && obj instanceof HTMLElement === false) {\n\t return true;\n\t } else {\n\t return false;\n\t }\n\t};\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\texports.exists = \"ontouchstart\" in document.documentElement;\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports) {\n\n\t// Copyright Joyent, Inc. and other Node contributors.\n\t//\n\t// Permission is hereby granted, free of charge, to any person obtaining a\n\t// copy of this software and associated documentation files (the\n\t// \"Software\"), to deal in the Software without restriction, including\n\t// without limitation the rights to use, copy, modify, merge, publish,\n\t// distribute, sublicense, and/or sell copies of the Software, and to permit\n\t// persons to whom the Software is furnished to do so, subject to the\n\t// following conditions:\n\t//\n\t// The above copyright notice and this permission notice shall be included\n\t// in all copies or substantial portions of the Software.\n\t//\n\t// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n\t// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n\t// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n\t// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n\t// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n\t// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n\t// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\t\n\tfunction EventEmitter() {\n\t this._events = this._events || {};\n\t this._maxListeners = this._maxListeners || undefined;\n\t}\n\tmodule.exports = EventEmitter;\n\t\n\t// Backwards-compat with node 0.10.x\n\tEventEmitter.EventEmitter = EventEmitter;\n\t\n\tEventEmitter.prototype._events = undefined;\n\tEventEmitter.prototype._maxListeners = undefined;\n\t\n\t// By default EventEmitters will print a warning if more than 10 listeners are\n\t// added to it. This is a useful default which helps finding memory leaks.\n\tEventEmitter.defaultMaxListeners = 10;\n\t\n\t// Obviously not all Emitters should be limited to 10. This function allows\n\t// that to be increased. Set to zero for unlimited.\n\tEventEmitter.prototype.setMaxListeners = function(n) {\n\t if (!isNumber(n) || n < 0 || isNaN(n))\n\t throw TypeError('n must be a positive number');\n\t this._maxListeners = n;\n\t return this;\n\t};\n\t\n\tEventEmitter.prototype.emit = function(type) {\n\t var er, handler, len, args, i, listeners;\n\t\n\t if (!this._events)\n\t this._events = {};\n\t\n\t // If there is no 'error' event listener then throw.\n\t if (type === 'error') {\n\t if (!this._events.error ||\n\t (isObject(this._events.error) && !this._events.error.length)) {\n\t er = arguments[1];\n\t if (er instanceof Error) {\n\t throw er; // Unhandled 'error' event\n\t } else {\n\t // At least give some kind of context to the user\n\t var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n\t err.context = er;\n\t throw err;\n\t }\n\t }\n\t }\n\t\n\t handler = this._events[type];\n\t\n\t if (isUndefined(handler))\n\t return false;\n\t\n\t if (isFunction(handler)) {\n\t switch (arguments.length) {\n\t // fast cases\n\t case 1:\n\t handler.call(this);\n\t break;\n\t case 2:\n\t handler.call(this, arguments[1]);\n\t break;\n\t case 3:\n\t handler.call(this, arguments[1], arguments[2]);\n\t break;\n\t // slower\n\t default:\n\t args = Array.prototype.slice.call(arguments, 1);\n\t handler.apply(this, args);\n\t }\n\t } else if (isObject(handler)) {\n\t args = Array.prototype.slice.call(arguments, 1);\n\t listeners = handler.slice();\n\t len = listeners.length;\n\t for (i = 0; i < len; i++)\n\t listeners[i].apply(this, args);\n\t }\n\t\n\t return true;\n\t};\n\t\n\tEventEmitter.prototype.addListener = function(type, listener) {\n\t var m;\n\t\n\t if (!isFunction(listener))\n\t throw TypeError('listener must be a function');\n\t\n\t if (!this._events)\n\t this._events = {};\n\t\n\t // To avoid recursion in the case that type === \"newListener\"! Before\n\t // adding it to the listeners, first emit \"newListener\".\n\t if (this._events.newListener)\n\t this.emit('newListener', type,\n\t isFunction(listener.listener) ?\n\t listener.listener : listener);\n\t\n\t if (!this._events[type])\n\t // Optimize the case of one listener. Don't need the extra array object.\n\t this._events[type] = listener;\n\t else if (isObject(this._events[type]))\n\t // If we've already got an array, just append.\n\t this._events[type].push(listener);\n\t else\n\t // Adding the second element, need to change to array.\n\t this._events[type] = [this._events[type], listener];\n\t\n\t // Check for listener leak\n\t if (isObject(this._events[type]) && !this._events[type].warned) {\n\t if (!isUndefined(this._maxListeners)) {\n\t m = this._maxListeners;\n\t } else {\n\t m = EventEmitter.defaultMaxListeners;\n\t }\n\t\n\t if (m && m > 0 && this._events[type].length > m) {\n\t this._events[type].warned = true;\n\t console.error('(node) warning: possible EventEmitter memory ' +\n\t 'leak detected. %d listeners added. ' +\n\t 'Use emitter.setMaxListeners() to increase limit.',\n\t this._events[type].length);\n\t if (typeof console.trace === 'function') {\n\t // not supported in IE 10\n\t console.trace();\n\t }\n\t }\n\t }\n\t\n\t return this;\n\t};\n\t\n\tEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\t\n\tEventEmitter.prototype.once = function(type, listener) {\n\t if (!isFunction(listener))\n\t throw TypeError('listener must be a function');\n\t\n\t var fired = false;\n\t\n\t function g() {\n\t this.removeListener(type, g);\n\t\n\t if (!fired) {\n\t fired = true;\n\t listener.apply(this, arguments);\n\t }\n\t }\n\t\n\t g.listener = listener;\n\t this.on(type, g);\n\t\n\t return this;\n\t};\n\t\n\t// emits a 'removeListener' event iff the listener was removed\n\tEventEmitter.prototype.removeListener = function(type, listener) {\n\t var list, position, length, i;\n\t\n\t if (!isFunction(listener))\n\t throw TypeError('listener must be a function');\n\t\n\t if (!this._events || !this._events[type])\n\t return this;\n\t\n\t list = this._events[type];\n\t length = list.length;\n\t position = -1;\n\t\n\t if (list === listener ||\n\t (isFunction(list.listener) && list.listener === listener)) {\n\t delete this._events[type];\n\t if (this._events.removeListener)\n\t this.emit('removeListener', type, listener);\n\t\n\t } else if (isObject(list)) {\n\t for (i = length; i-- > 0;) {\n\t if (list[i] === listener ||\n\t (list[i].listener && list[i].listener === listener)) {\n\t position = i;\n\t break;\n\t }\n\t }\n\t\n\t if (position < 0)\n\t return this;\n\t\n\t if (list.length === 1) {\n\t list.length = 0;\n\t delete this._events[type];\n\t } else {\n\t list.splice(position, 1);\n\t }\n\t\n\t if (this._events.removeListener)\n\t this.emit('removeListener', type, listener);\n\t }\n\t\n\t return this;\n\t};\n\t\n\tEventEmitter.prototype.removeAllListeners = function(type) {\n\t var key, listeners;\n\t\n\t if (!this._events)\n\t return this;\n\t\n\t // not listening for removeListener, no need to emit\n\t if (!this._events.removeListener) {\n\t if (arguments.length === 0)\n\t this._events = {};\n\t else if (this._events[type])\n\t delete this._events[type];\n\t return this;\n\t }\n\t\n\t // emit removeListener for all listeners on all events\n\t if (arguments.length === 0) {\n\t for (key in this._events) {\n\t if (key === 'removeListener') continue;\n\t this.removeAllListeners(key);\n\t }\n\t this.removeAllListeners('removeListener');\n\t this._events = {};\n\t return this;\n\t }\n\t\n\t listeners = this._events[type];\n\t\n\t if (isFunction(listeners)) {\n\t this.removeListener(type, listeners);\n\t } else if (listeners) {\n\t // LIFO order\n\t while (listeners.length)\n\t this.removeListener(type, listeners[listeners.length - 1]);\n\t }\n\t delete this._events[type];\n\t\n\t return this;\n\t};\n\t\n\tEventEmitter.prototype.listeners = function(type) {\n\t var ret;\n\t if (!this._events || !this._events[type])\n\t ret = [];\n\t else if (isFunction(this._events[type]))\n\t ret = [this._events[type]];\n\t else\n\t ret = this._events[type].slice();\n\t return ret;\n\t};\n\t\n\tEventEmitter.prototype.listenerCount = function(type) {\n\t if (this._events) {\n\t var evlistener = this._events[type];\n\t\n\t if (isFunction(evlistener))\n\t return 1;\n\t else if (evlistener)\n\t return evlistener.length;\n\t }\n\t return 0;\n\t};\n\t\n\tEventEmitter.listenerCount = function(emitter, type) {\n\t return emitter.listenerCount(type);\n\t};\n\t\n\tfunction isFunction(arg) {\n\t return typeof arg === 'function';\n\t}\n\t\n\tfunction isNumber(arg) {\n\t return typeof arg === 'number';\n\t}\n\t\n\tfunction isObject(arg) {\n\t return typeof arg === 'object' && arg !== null;\n\t}\n\t\n\tfunction isUndefined(arg) {\n\t return arg === void 0;\n\t}\n\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = __webpack_require__(5);\n\t\n\t/**\n\t Creates a steppable value with minimum, maximum, and step size. This is used in many interfaces to constrict their values to certain ranges.\n\t @param {number} [min=0] minimum\n\t @param {number} [max=1] maximum\n\t @param {number} [step=0]\n\t @param {number} [value=0] initial value\n\t @returns {Object} Step\n\t*/\n\t\n\tvar Step = (function () {\n\t function Step() {\n\t var min = arguments[0] === undefined ? 0 : arguments[0];\n\t var max = arguments[1] === undefined ? 1 : arguments[1];\n\t var step = arguments[2] === undefined ? 0 : arguments[2];\n\t var value = arguments[3] === undefined ? 0 : arguments[3];\n\t\n\t _classCallCheck(this, Step);\n\t\n\t //Object.assign(this,{min,max,step});\n\t //Cannot use Object.assign because not supported in Safari.\n\t //I would expect for Babel to take care of this but it is not.\n\t this.min = min;\n\t this.max = max;\n\t this.step = step;\n\t this.value = value;\n\t this.changed = false;\n\t this.oldValue = false;\n\t this.update(this.value);\n\t }\n\t\n\t _createClass(Step, {\n\t update: {\n\t\n\t /**\n\t Update with a new value. The value will be auto-adjusted to fit the min/max/step.\n\t @param {number} value\n\t */\n\t\n\t value: function update(value) {\n\t if (this.step) {\n\t // this.value = math.clip(Math.round(value / (this.step)) * this.step, this.min,this.max);\n\t this.value = math.clip(Math.round((value - this.min) / this.step) * this.step + this.min, this.min, this.max);\n\t } else {\n\t this.value = math.clip(value, this.min, this.max);\n\t }\n\t if (this.oldValue !== this.value) {\n\t this.oldValue = this.value;\n\t this.changed = true;\n\t } else {\n\t this.changed = false;\n\t }\n\t return this.value;\n\t }\n\t },\n\t updateNormal: {\n\t\n\t /**\n\t Update with a normalized value 0-1.\n\t @param {number} value\n\t */\n\t\n\t value: function updateNormal(value) {\n\t this.value = math.scale(value, 0, 1, this.min, this.max);\n\t return this.update(this.value);\n\t }\n\t },\n\t normalized: {\n\t\n\t /**\n\t Get a normalized version of this.value . Not settable.\n\t */\n\t\n\t get: function () {\n\t return math.normalize(this.value, this.min, this.max);\n\t }\n\t }\n\t });\n\t\n\t return Step;\n\t})();\n\t\n\tmodule.exports = Step;\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\"use strict\";\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar ToggleModel = _interopRequire(__webpack_require__(13));\n\t\n\t/*\n\thow to use :\n\t\n\tdial.interaction = new Handle('radial','relative',this.width,this.height);\n\t// dial.interaction.mode = 'relative'\n\t// dial.interaction.direction = 'radial'\n\t\n\ton click:\n\tdial.interaction.anchor = this.mouse;\n\t\n\ton move:\n\tdial.interaction.update(this.mouse);\n\t\n\tconsole.log( dial.interaction.value ); should be a normalized value.\n\t\n\t*/\n\t\n\t/*\n\t absolute/relative are property: mode\n\t radial/vertical/horizontal/2d are property: direction\n\t\n\t plan :\n\t\n\t if relative --\n\t NO on click, get value offset between current value and click value.\n\t NO on move, use click value - offset\n\t INSTEAD\n\t use delta -- bc vertical motion on dial is impossible otherwise\n\t also allow to set sensitivity\n\t\n\t*/\n\t\n\tvar Handle = exports.Handle = (function () {\n\t function Handle() {\n\t var mode = arguments[0] === undefined ? \"absolute\" : arguments[0];\n\t var direction = arguments[1] === undefined ? \"vertical\" : arguments[1];\n\t var xbound = arguments[2] === undefined ? [0, 100] : arguments[2];\n\t var ybound = arguments[3] === undefined ? [0, 100] : arguments[3];\n\t\n\t _classCallCheck(this, Handle);\n\t\n\t this.mode = mode;\n\t this.direction = direction;\n\t this.previous = 0;\n\t this.value = 0;\n\t this.sensitivity = 1;\n\t this.resize(xbound, ybound);\n\t }\n\t\n\t _createClass(Handle, {\n\t resize: {\n\t value: function resize(xbound, ybound) {\n\t this.boundary = {\n\t min: {\n\t x: xbound[0],\n\t y: ybound[0]\n\t },\n\t max: {\n\t x: xbound[1],\n\t y: ybound[1]\n\t },\n\t center: {\n\t x: (xbound[1] - xbound[0]) / 2 + xbound[0],\n\t y: (ybound[1] - ybound[0]) / 2 + ybound[0]\n\t }\n\t };\n\t }\n\t },\n\t anchor: {\n\t set: function (mouse) {\n\t this._anchor = this.convertPositionToValue(mouse);\n\t },\n\t get: function () {\n\t return this._anchor;\n\t }\n\t },\n\t update: {\n\t value: function update(mouse) {\n\t if (this.mode === \"relative\") {\n\t var increment = this.convertPositionToValue(mouse) - this.anchor;\n\t if (Math.abs(increment) > 0.5) {\n\t increment = 0;\n\t }\n\t this.anchor = mouse;\n\t this.value = this.value + increment * this.sensitivity;\n\t } else {\n\t this.value = this.convertPositionToValue(mouse);\n\t }\n\t this.value = math.clip(this.value, 0, 1);\n\t }\n\t },\n\t convertPositionToValue: {\n\t value: function convertPositionToValue(current) {\n\t switch (this.direction) {\n\t case \"radial\":\n\t var position = math.toPolar(current.x - this.boundary.center.x, current.y - this.boundary.center.y);\n\t position = position.angle / (Math.PI * 2);\n\t position = (position - 0.25 + 1) % 1;\n\t return position;\n\t case \"vertical\":\n\t return math.scale(current.y, this.boundary.min.y, this.boundary.max.y, 0, 1);\n\t case \"horizontal\":\n\t return math.scale(current.x, this.boundary.min.x, this.boundary.max.x, 0, 1);\n\t }\n\t }\n\t }\n\t });\n\t\n\t return Handle;\n\t})();\n\t\n\tvar Button = exports.Button = (function () {\n\t function Button() {\n\t var mode = arguments[0] === undefined ? \"button\" : arguments[0];\n\t\n\t _classCallCheck(this, Button);\n\t\n\t this.mode = mode;\n\t this.state = new ToggleModel();\n\t this.paintbrush = false;\n\t }\n\t\n\t _createClass(Button, {\n\t click: {\n\t value: function click() {\n\t switch (this.mode) {\n\t case \"impulse\":\n\t this.state.on();\n\t if (this.timeout) {\n\t clearTimeout(this.timeout);\n\t }\n\t this.timeout = setTimeout(this.state.off.bind(this), 30);\n\t this.emit(\"change\", this.state);\n\t break;\n\t case \"button\":\n\t this.turnOn();\n\t this.emit(\"change\", this.state);\n\t break;\n\t case \"aftertouch\":\n\t this.position = {\n\t x: math.clip(this.mouse.x / this.width, 0, 1),\n\t y: math.clip(1 - this.mouse.y / this.height, 0, 1)\n\t };\n\t this.turnOn();\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t break;\n\t case \"toggle\":\n\t this.flip();\n\t this.emit(\"change\", this.state);\n\t break;\n\t }\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.mode === \"aftertouch\") {\n\t this.position = {\n\t x: math.clip(this.mouse.x / this.width, 0, 1),\n\t y: math.clip(1 - this.mouse.y / this.height, 0, 1)\n\t };\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t this.render();\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t switch (this.mode) {\n\t case \"button\":\n\t this.turnOff();\n\t this.emit(\"change\", this.state);\n\t break;\n\t case \"aftertouch\":\n\t this.turnOff();\n\t this.position = {\n\t x: this.mouse.x / this.width,\n\t y: 1 - this.mouse.y / this.height\n\t };\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t break;\n\t }\n\t }\n\t }\n\t });\n\t\n\t return Button;\n\t})();\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar Toggle = (function () {\n\t function Toggle(state) {\n\t _classCallCheck(this, Toggle);\n\t\n\t this.state = state || false;\n\t }\n\t\n\t _createClass(Toggle, {\n\t flip: {\n\t value: function flip(state) {\n\t if (state || state === false) {\n\t this.state = state;\n\t } else {\n\t this.state = !this.state;\n\t }\n\t }\n\t },\n\t on: {\n\t value: function on() {\n\t this.state = true;\n\t }\n\t },\n\t off: {\n\t value: function off() {\n\t this.state = false;\n\t }\n\t }\n\t });\n\t\n\t return Toggle;\n\t})();\n\t\n\tmodule.exports = Toggle;\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\t\n\tvar Interaction = _interopRequireWildcard(__webpack_require__(12));\n\t\n\t/**\n\t* Slider\n\t*\n\t* @description Horizontal or vertical slider with settable interaction modes.\n\t*\n\t* @demo <span nexus-ui=\"slider\" step=0.2></span>\n\t*\n\t* @example\n\t* var slider = new Nexus.Slider('#target')\n\t*\n\t* @example\n\t* var slider = new Nexus.Slider('#target',{\n\t* 'size': [120,20],\n\t* 'mode': 'relative', // 'relative' or 'absolute'\n\t* 'min': 0,\n\t* 'max': 1,\n\t* 'step': 0,\n\t* 'value': 0\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires when the interface's value changes. <br>\n\t* Event data: <i>number</i> The number value of the interface.\n\t*\n\t* @outputexample\n\t* slider.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Slider = (function (_Interface) {\n\t function Slider() {\n\t _classCallCheck(this, Slider);\n\t\n\t var options = [\"min\", \"max\", \"value\"];\n\t\n\t var defaults = {\n\t size: [120, 20],\n\t mode: \"relative\", // 'relative' or 'absolute'\n\t min: 0,\n\t max: 1,\n\t step: 0,\n\t value: 0\n\t };\n\t\n\t _get(Object.getPrototypeOf(Slider.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.orientation = \"vertical\"; // This will change automatically to 'horizontal'if the interface is wider than it is tall.\n\t\n\t this._value = new Step(this.settings.min, this.settings.max, this.settings.step, this.settings.value);\n\t\n\t this.position = new Interaction.Handle(this.settings.mode, this.orientation, [0, this.width], [this.height, 0]);\n\t this.position.value = this._value.normalized;\n\t\n\t this.init();\n\t\n\t this.position.direction = this.orientation;\n\t\n\t this.emit(\"change\", this.value);\n\t }\n\t\n\t _inherits(Slider, _Interface);\n\t\n\t _createClass(Slider, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.bar = svg.create(\"rect\");\n\t this.fillbar = svg.create(\"rect\");\n\t this.knob = svg.create(\"circle\");\n\t\n\t this.element.appendChild(this.bar);\n\t this.element.appendChild(this.fillbar);\n\t this.element.appendChild(this.knob);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t if (this.width < this.height) {\n\t this.orientation = \"vertical\";\n\t } else {\n\t this.orientation = \"horizontal\";\n\t }\n\t\n\t if (this.position) {\n\t this.position.resize([0, this.width], [this.height, 0]);\n\t }\n\t\n\t var x = undefined,\n\t y = undefined,\n\t w = undefined,\n\t h = undefined,\n\t barOffset = undefined,\n\t cornerRadius = undefined;\n\t this.knobData = {\n\t level: 0,\n\t r: 0\n\t };\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.thickness = this.width / 2;\n\t x = this.width / 2;\n\t y = 0;\n\t w = this.thickness;\n\t h = this.height;\n\t this.knobData.r = this.thickness * 0.8;\n\t this.knobData.level = h - this.knobData.r - this.normalized * (h - this.knobData.r * 2);\n\t barOffset = \"translate(\" + this.thickness * -1 / 2 + \",0)\";\n\t cornerRadius = w / 2;\n\t } else {\n\t this.thickness = this.height / 2;\n\t x = 0;\n\t y = this.height / 2;\n\t w = this.width;\n\t h = this.thickness;\n\t this.knobData.r = this.thickness * 0.8;\n\t this.knobData.level = this.normalized * (w - this.knobData.r * 2) + this.knobData.r;\n\t barOffset = \"translate(0,\" + this.thickness * -1 / 2 + \")\";\n\t cornerRadius = h / 2;\n\t }\n\t\n\t this.bar.setAttribute(\"x\", x);\n\t this.bar.setAttribute(\"y\", y);\n\t this.bar.setAttribute(\"transform\", barOffset);\n\t this.bar.setAttribute(\"rx\", cornerRadius); // corner radius\n\t this.bar.setAttribute(\"ry\", cornerRadius);\n\t this.bar.setAttribute(\"width\", w);\n\t this.bar.setAttribute(\"height\", h);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.fillbar.setAttribute(\"x\", x);\n\t this.fillbar.setAttribute(\"y\", this.knobData.level);\n\t this.fillbar.setAttribute(\"width\", w);\n\t this.fillbar.setAttribute(\"height\", h - this.knobData.level);\n\t } else {\n\t this.fillbar.setAttribute(\"x\", 0);\n\t this.fillbar.setAttribute(\"y\", y);\n\t this.fillbar.setAttribute(\"width\", this.knobData.level);\n\t this.fillbar.setAttribute(\"height\", h);\n\t }\n\t this.fillbar.setAttribute(\"transform\", barOffset);\n\t this.fillbar.setAttribute(\"rx\", cornerRadius);\n\t this.fillbar.setAttribute(\"ry\", cornerRadius);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.knob.setAttribute(\"cx\", x);\n\t this.knob.setAttribute(\"cy\", this.knobData.level);\n\t } else {\n\t this.knob.setAttribute(\"cx\", this.knobData.level);\n\t this.knob.setAttribute(\"cy\", y);\n\t }\n\t this.knob.setAttribute(\"r\", this.knobData.r);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.bar.setAttribute(\"fill\", this.colors.fill);\n\t this.fillbar.setAttribute(\"fill\", this.colors.accent);\n\t this.knob.setAttribute(\"fill\", this.colors.accent);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.clicked) {\n\t this.knobData.r = this.thickness * 0.75;\n\t }\n\t this.knob.setAttribute(\"r\", this.knobData.r);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.knobData.level = this.knobData.r + this._value.normalized * (this.height - this.knobData.r * 2);\n\t this.knob.setAttribute(\"cy\", this.height - this.knobData.level);\n\t this.fillbar.setAttribute(\"y\", this.height - this.knobData.level);\n\t this.fillbar.setAttribute(\"height\", this.knobData.level);\n\t } else {\n\t this.knobData.level = this._value.normalized * (this.width - this.knobData.r * 2) + this.knobData.r;\n\t this.knob.setAttribute(\"cx\", this.knobData.level);\n\t this.fillbar.setAttribute(\"x\", 0);\n\t this.fillbar.setAttribute(\"width\", this.knobData.level);\n\t }\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.knobData.r = this.thickness * 0.9;\n\t this.position.anchor = this.mouse;\n\t this.move();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.clicked) {\n\t this.position.update(this.mouse);\n\t this._value.updateNormal(this.position.value);\n\t this.emit(\"change\", this._value.value);\n\t this.render();\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t this.render();\n\t }\n\t },\n\t normalized: {\n\t get: function () {\n\t return this._value.normalized;\n\t }\n\t },\n\t value: {\n\t\n\t /**\n\t The slider's current value. If set manually, will update the interface and trigger the output event.\n\t @type {number}\n\t @example slider.value = 10;\n\t */\n\t\n\t get: function () {\n\t return this._value.value;\n\t },\n\t set: function (v) {\n\t this._value.update(v);\n\t this.position.value = this._value.normalized;\n\t this.emit(\"change\", this._value.value);\n\t this.render();\n\t }\n\t },\n\t min: {\n\t\n\t /**\n\t Lower limit of the sliders's output range\n\t @type {number}\n\t @example slider.min = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.min;\n\t },\n\t set: function (v) {\n\t this._value.min = v;\n\t }\n\t },\n\t max: {\n\t\n\t /**\n\t Upper limit of the slider's output range\n\t @type {number}\n\t @example slider.max = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.max;\n\t },\n\t set: function (v) {\n\t this._value.max = v;\n\t }\n\t },\n\t step: {\n\t\n\t /**\n\t The increment that the slider's value changes by.\n\t @type {number}\n\t @example slider.step = 5;\n\t */\n\t\n\t get: function () {\n\t return this._value.step;\n\t },\n\t set: function (v) {\n\t this._value.step = v;\n\t }\n\t },\n\t mode: {\n\t\n\t /**\n\t Absolute mode (slider's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: \"relative\".\n\t @type {string}\n\t @example slider.mode = \"relative\";\n\t */\n\t\n\t get: function () {\n\t return this.position.mode;\n\t },\n\t set: function (v) {\n\t this.position.mode = v;\n\t }\n\t }\n\t });\n\t\n\t return Slider;\n\t})(Interface);\n\t\n\tmodule.exports = Slider;\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar ToggleModel = __webpack_require__(13);\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\t* Toggle\n\t*\n\t* @description Binary switch\n\t*\n\t* @demo <span nexus-ui=\"toggle\"></span>\n\t*\n\t* @example\n\t* var toggle = new Nexus.Toggle('#target')\n\t*\n\t* @example\n\t* var toggle = new Nexus.Toggle('#target',{\n\t* 'size': [40,20],\n\t* 'state': false\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* Parameter: The boolean state of the interface.\n\t*\n\t* @outputexample\n\t* toggle.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Toggle = (function (_Interface) {\n\t function Toggle() {\n\t _classCallCheck(this, Toggle);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [40, 20],\n\t target: false,\n\t state: false\n\t };\n\t\n\t _get(Object.getPrototypeOf(Toggle.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._state = new ToggleModel(this.settings.state);\n\t\n\t this.init();\n\t }\n\t\n\t _inherits(Toggle, _Interface);\n\t\n\t _createClass(Toggle, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.bar = svg.create(\"rect\");\n\t this.knob = svg.create(\"circle\");\n\t this.element.appendChild(this.bar);\n\t this.element.appendChild(this.knob);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t if (this.height < this.width / 2) {\n\t this.knobSize = this.height / 2;\n\t } else {\n\t this.knobSize = this.width / 4;\n\t }\n\t\n\t this.bar.setAttribute(\"x\", this.width / 2 - this.knobSize * 1.5);\n\t this.bar.setAttribute(\"y\", this.height / 2 - this.knobSize / 2);\n\t this.bar.setAttribute(\"rx\", this.knobSize / 2);\n\t this.bar.setAttribute(\"ry\", this.knobSize / 2);\n\t this.bar.setAttribute(\"width\", this.knobSize * 3);\n\t this.bar.setAttribute(\"height\", this.knobSize);\n\t\n\t this.knob.setAttribute(\"cx\", this.width / 2 - this.knobSize);\n\t this.knob.setAttribute(\"cy\", this.height / 2);\n\t this.knob.setAttribute(\"r\", this.knobSize);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.knob.setAttribute(\"fill\", this.colors.accent);\n\t this.render();\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.state) {\n\t this.knob.setAttribute(\"cx\", this.width / 2 - this.knobSize);\n\t this.bar.setAttribute(\"fill\", this.colors.fill);\n\t } else {\n\t this.knob.setAttribute(\"cx\", this.width / 2 + this.knobSize);\n\t this.bar.setAttribute(\"fill\", this.colors.accent);\n\t }\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.flip();\n\t this.render();\n\t this.emit(\"change\", this.state);\n\t }\n\t },\n\t state: {\n\t\n\t /**\n\t Whether the toggle is currently on or off. Setting this property will update the toggle interface and trigger the output event.\n\t @type {boolean}\n\t @example toggle.state = false;\n\t */\n\t\n\t get: function () {\n\t return this._state.state;\n\t },\n\t set: function (value) {\n\t this._state.flip(value);\n\t this.emit(\"change\", this.state);\n\t this.render();\n\t }\n\t },\n\t flip: {\n\t\n\t /**\n\t * Switch the toggle state to its opposite state\n\t * @example\n\t * toggle.flip();\n\t */\n\t\n\t value: function flip() {\n\t this._state.flip();\n\t this.render();\n\t }\n\t }\n\t });\n\t\n\t return Toggle;\n\t})(Interface);\n\t\n\tmodule.exports = Toggle;\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar ButtonTemplate = __webpack_require__(17);\n\t\n\t/**\n\t* Button\n\t*\n\t* @description Circular button with optional aftertouch.\n\t*\n\t* @demo <span nexus-ui=\"button\"></span>\n\t*\n\t* @example\n\t* var button = new Nexus.Button('#target')\n\t*\n\t* @example\n\t* var button = new Nexus.Button('#target',{\n\t* 'size': [80,80],\n\t* 'mode': 'aftertouch',\n\t* 'state': false\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* In <b>button mode</b>, <b>toggle mode</b>, and <b>impulse mode</b>, the output data is a boolean describing the state of the button.<br>\n\t* In <b>aftertouch mode</b>, the output data is an object containing x (0-1) and y (0-1) positions of aftertouch.\n\t*\n\t* @outputexample\n\t* button.on('change',function(v) {\n\t* // v is the value of the button\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\tvar Button = (function (_ButtonTemplate) {\n\t function Button() {\n\t _classCallCheck(this, Button);\n\t\n\t var options = [\"mode\"];\n\t\n\t var defaults = {\n\t size: [80, 80],\n\t mode: \"aftertouch\", // button, aftertouch, impulse, toggle\n\t state: false\n\t };\n\t\n\t _get(Object.getPrototypeOf(Button.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t /**\n\t * Interaction mode: supports \"button\", \"aftertouch\", \"impulse\", or \"toggle\"\n\t * @type {string}\n\t * @example button.mode = 'toggle';\n\t */\n\t this.mode = this.settings.mode;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(Button, _ButtonTemplate);\n\t\n\t _createClass(Button, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t this.pad = svg.create(\"circle\");\n\t this.element.appendChild(this.pad);\n\t\n\t this.interactionTarget = this.pad;\n\t\n\t // only used if in 'aftertouch' mode\n\t this.defs = svg.create(\"defs\");\n\t this.element.appendChild(this.defs);\n\t\n\t this.gradient = svg.radialGradient(this.defs, 2);\n\t\n\t this.gradient.stops[0].setAttribute(\"offset\", \"30%\");\n\t\n\t this.gradient.stops[1].setAttribute(\"offset\", \"100%\");\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t this.pad.setAttribute(\"cx\", this.width / 2);\n\t this.pad.setAttribute(\"cy\", this.height / 2);\n\t this.pad.setAttribute(\"r\", Math.min(this.width, this.height) / 2 - this.width / 40);\n\t this.pad.setAttribute(\"stroke-width\", this.width / 20);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t\n\t this.gradient.stops[0].setAttribute(\"stop-color\", this.colors.accent);\n\t this.gradient.stops[1].setAttribute(\"stop-color\", this.colors.fill);\n\t this.render();\n\t }\n\t },\n\t render: {\n\t\n\t /*\n\t * Update the visual interface using its current state\n\t *\n\t * @example\n\t * button.render();\n\t */\n\t\n\t value: function render() {\n\t if (!this.state) {\n\t this.pad.setAttribute(\"fill\", this.colors.fill);\n\t this.pad.setAttribute(\"stroke\", this.colors.mediumLight);\n\t } else {\n\t if (this.mode === \"aftertouch\") {\n\t this.pad.setAttribute(\"stroke\", \"url(#\" + this.gradient.id + \")\");\n\t this.gradient.element.setAttribute(\"cx\", this.position.x * 100 + \"%\");\n\t this.gradient.element.setAttribute(\"cy\", (1 - this.position.y) * 100 + \"%\");\n\t } else {\n\t this.pad.setAttribute(\"stroke\", this.colors.accent);\n\t }\n\t this.pad.setAttribute(\"fill\", this.colors.accent);\n\t }\n\t }\n\t }\n\t });\n\t\n\t return Button;\n\t})(ButtonTemplate);\n\t\n\tmodule.exports = Button;\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar math = __webpack_require__(5);\n\tvar ToggleModel = __webpack_require__(13);\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\tButton Template\n\t*/\n\t\n\tvar ButtonTemplate = (function (_Interface) {\n\t function ButtonTemplate(args, options, defaults) {\n\t _classCallCheck(this, ButtonTemplate);\n\t\n\t _get(Object.getPrototypeOf(ButtonTemplate.prototype), \"constructor\", this).call(this, args, options, defaults);\n\t\n\t this.mode = this.settings.mode || \"button\";\n\t\n\t this.position = {\n\t x: 0,\n\t y: 0\n\t };\n\t\n\t this._state = new ToggleModel(this.settings.state);\n\t }\n\t\n\t _inherits(ButtonTemplate, _Interface);\n\t\n\t _createClass(ButtonTemplate, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t this.pad = svg.create(\"circle\");\n\t this.pad.setAttribute(\"fill\", \"#d18\");\n\t this.pad.setAttribute(\"stroke\", \"#d18\");\n\t this.pad.setAttribute(\"stroke-width\", 4);\n\t\n\t this.element.appendChild(this.pad);\n\t\n\t this.interactionTarget = this.pad;\n\t\n\t this.sizeInterface();\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t this.pad.setAttribute(\"cx\", this.width / 2);\n\t this.pad.setAttribute(\"cy\", this.height / 2);\n\t this.pad.setAttribute(\"r\", Math.min(this.width, this.height) / 2 - 2);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.state) {\n\t this.pad.setAttribute(\"fill\", this.colors.fill);\n\t this.pad.setAttribute(\"stroke\", this.colors.mediumLight);\n\t } else {\n\t this.pad.setAttribute(\"fill\", this.colors.accent);\n\t this.pad.setAttribute(\"stroke\", this.colors.accent);\n\t }\n\t }\n\t },\n\t down: {\n\t value: function down(paintbrush) {\n\t switch (this.mode) {\n\t case \"impulse\":\n\t this.turnOn();\n\t if (this.timeout) {\n\t clearTimeout(this.timeout);\n\t }\n\t this.timeout = setTimeout(this.turnOff.bind(this), 30);\n\t // this.emit('change',this.state);\n\t break;\n\t case \"button\":\n\t this.turnOn();\n\t // this.emit('change',this.state);\n\t break;\n\t case \"aftertouch\":\n\t this.position = {\n\t x: math.clip(this.mouse.x / this.width, 0, 1),\n\t y: math.clip(1 - this.mouse.y / this.height, 0, 1)\n\t };\n\t this.turnOn();\n\t // this.emit('change',{\n\t // state: this.state,\n\t // x: this.position.x,\n\t // y: this.position.y,\n\t // });\n\t break;\n\t case \"toggle\":\n\t this.flip(paintbrush);\n\t // this.emit('change',this.state);\n\t break;\n\t }\n\t }\n\t },\n\t bend: {\n\t value: function bend(mouse) {\n\t if (this.mode === \"aftertouch\") {\n\t this.mouse = mouse || this.mouse;\n\t this.position = {\n\t x: math.clip(this.mouse.x / this.width, 0, 1),\n\t y: math.clip(1 - this.mouse.y / this.height, 0, 1)\n\t };\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t this.render();\n\t }\n\t }\n\t },\n\t up: {\n\t value: function up() {\n\t switch (this.mode) {\n\t case \"button\":\n\t this.turnOff();\n\t // this.emit('change',this.state);\n\t break;\n\t case \"aftertouch\":\n\t this.turnOff();\n\t this.position = {\n\t x: math.clip(this.mouse.x / this.width, 0, 1),\n\t y: math.clip(1 - this.mouse.y / this.height, 0, 1)\n\t };\n\t // this.emit('change',{\n\t // state: this.state,\n\t // x: this.position.x,\n\t // y: this.position.y,\n\t // });\n\t break;\n\t }\n\t }\n\t },\n\t click: {\n\t\n\t /* overwritable interaction handlers */\n\t\n\t value: function click() {\n\t this.down();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t this.bend();\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t this.up();\n\t }\n\t },\n\t state: {\n\t\n\t /**\n\t Whether the button is on (pressed) or off (not pressed)\n\t @type {boolean}\n\t @example button.state = true;\n\t */\n\t\n\t get: function () {\n\t return this._state.state;\n\t },\n\t set: function (value) {\n\t this._state.flip(value);\n\t if (this.mode === \"aftertouch\") {\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t } else {\n\t this.emit(\"change\", this.state);\n\t }\n\t this.render();\n\t }\n\t },\n\t flip: {\n\t\n\t /**\n\t Change the button to its alternate state (off=>on, on=>off), or flip it to a specified state.\n\t @param value {boolean} (Optional) State to flip to.\n\t @example button.flip();\n\t */\n\t\n\t value: function flip(value) {\n\t this._state.flip(value);\n\t if (this.mode === \"aftertouch\") {\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t } else {\n\t this.emit(\"change\", this.state);\n\t }\n\t this.render();\n\t }\n\t },\n\t turnOn: {\n\t\n\t /**\n\t Turn the button's state to true.\n\t @example button.turnOn();\n\t */\n\t\n\t value: function turnOn(emitting) {\n\t this._state.on();\n\t if (emitting !== false) {\n\t if (this.mode === \"aftertouch\") {\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t } else {\n\t this.emit(\"change\", this.state);\n\t }\n\t }\n\t this.render();\n\t }\n\t },\n\t turnOff: {\n\t\n\t /**\n\t Turn the button's state to false.\n\t @example button.turnOff();\n\t */\n\t\n\t value: function turnOff(emitting) {\n\t this._state.off();\n\t if (emitting !== false) {\n\t if (this.mode === \"aftertouch\") {\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t } else {\n\t this.emit(\"change\", this.state);\n\t }\n\t }\n\t this.render();\n\t }\n\t }\n\t });\n\t\n\t return ButtonTemplate;\n\t})(Interface);\n\t\n\tmodule.exports = ButtonTemplate;\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar ButtonTemplate = __webpack_require__(17);\n\t\n\t/**\n\t* TextButton\n\t*\n\t* @description Text button\n\t*\n\t* @demo <span nexus-ui=\"textButton\"></span>\n\t*\n\t* @example\n\t* var textbutton = new Nexus.TextButton('#target')\n\t*\n\t* @example\n\t* var textbutton = new Nexus.TextButton('#target',{\n\t* 'size': [150,50],\n\t* 'state': false,\n\t* 'text': 'Play',\n\t* 'alternateText': 'Stop'\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data is a <i>string</i> of the text on the button at the moment it was clicked.\n\t*\n\t* @outputexample\n\t* textbutton.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\tvar TextButton = (function (_ButtonTemplate) {\n\t function TextButton() {\n\t _classCallCheck(this, TextButton);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [150, 50],\n\t state: false,\n\t text: \"Play\"\n\t };\n\t\n\t _get(Object.getPrototypeOf(TextButton.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._text = this.settings.text;\n\t\n\t if (this.settings.alternate) {\n\t //TODO: Remove this conditional in a breaking-changes release\n\t this.settings.alternateText = this.settings.alternate;\n\t console.warn(\"'alternate' initiator is deprecated. Use 'alternateText' instead.\");\n\t }\n\t this._alternateText = this.settings.alternateText;\n\t this.mode = this.settings.alternateText ? \"toggle\" : \"button\";\n\t this.init();\n\t this.render();\n\t\n\t this.state = this.settings.state;\n\t }\n\t\n\t _inherits(TextButton, _ButtonTemplate);\n\t\n\t _createClass(TextButton, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t\n\t this.element = document.createElement(\"div\");\n\t this.parent.appendChild(this.element);\n\t\n\t this.textElement = document.createElement(\"div\");\n\t this.textElement.innerHTML = this._text;\n\t this.element.appendChild(this.textElement);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {}\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.element.style.color = this.colors.dark;\n\t this.render();\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t var textsize = this.height / 3;\n\t var textsize2 = this.width / (this._text.length + 2);\n\t textsize = Math.min(textsize, textsize2);\n\t if (this.alternateText) {\n\t var textsize3 = this.width / (this.alternateText.length + 2);\n\t textsize = Math.min(textsize, textsize3);\n\t }\n\t var styles = \"width: \" + this.width + \"px;\";\n\t styles += \"height: \" + this.height + \"px;\";\n\t styles += \"padding: \" + (this.height - textsize) / 2 + \"px 0px;\";\n\t styles += \"box-sizing: border-box;\";\n\t styles += \"text-align: center;\";\n\t styles += \"font-family: inherit;\";\n\t styles += \"font-weight: 700;\";\n\t styles += \"opacity: 1;\";\n\t styles += \"font-size:\" + textsize + \"px;\";\n\t this.textElement.style.cssText = styles;\n\t this.render();\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.state) {\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.textElement.style.color = this.colors.dark;\n\t this.textElement.innerHTML = this._text;\n\t } else {\n\t this.element.style.backgroundColor = this.colors.accent;\n\t this.textElement.style.color = this.colors.fill;\n\t if (this.alternateText) {\n\t this.textElement.innerHTML = this._alternateText;\n\t } else {\n\t this.textElement.innerHTML = this._text;\n\t }\n\t }\n\t }\n\t },\n\t alternateText: {\n\t\n\t /**\n\t The text to display when the button is in its \"on\" state. If set, this puts the button in \"toggle\" mode.\n\t @type {String}\n\t */\n\t\n\t get: function () {\n\t return this._alternateText;\n\t },\n\t set: function (text) {\n\t if (text) {\n\t this.mode = \"toggle\";\n\t } else {\n\t this.mode = \"button\";\n\t }\n\t this._alternateText = text;\n\t this.render();\n\t }\n\t },\n\t text: {\n\t\n\t /**\n\t The text to display. (If .alternateText exists, then this .text will only be displayed when the button is in its \"off\" state.)\n\t @type {String}\n\t */\n\t\n\t get: function () {\n\t return this._text;\n\t },\n\t set: function (text) {\n\t this._text = text;\n\t this.sizeInterface();\n\t this.render();\n\t }\n\t }\n\t });\n\t\n\t return TextButton;\n\t})(ButtonTemplate);\n\t\n\tmodule.exports = TextButton;\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\t//let svg = require('../util/svg');\n\tvar Interface = __webpack_require__(6);\n\tvar Button = __webpack_require__(16);\n\t\n\t/**\n\t* RadioButton\n\t*\n\t* @description An array of buttons. By default, selecting one button will deselect all other buttons, but this can be customized using the API below.\n\t*\n\t* @demo <div nexus-ui=\"RadioButton\"></div>\n\t*\n\t* @example\n\t* var radiobutton = new Nexus.RadioButton('#target')\n\t*\n\t* @example\n\t* var radiobutton = new Nexus.RadioButton('#target',{\n\t* 'size': [120,25],\n\t* 'numberOfButtons': 4,\n\t* 'active': -1\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data an <i>integer</i>, the index of the button that is currently on. If no button is selected, the value will be -1.\n\t*\n\t* @outputexample\n\t* radiobutton.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\tvar RadioButton = (function (_Interface) {\n\t function RadioButton() {\n\t _classCallCheck(this, RadioButton);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [120, 25],\n\t numberOfButtons: 4,\n\t active: -1\n\t };\n\t\n\t _get(Object.getPrototypeOf(RadioButton.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.buttons = [];\n\t this._numberOfButtons = this.settings.numberOfButtons;\n\t this.active = this.settings.active;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(RadioButton, _Interface);\n\t\n\t _createClass(RadioButton, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = document.createElement(\"div\");\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t for (var i = 0; i < this._numberOfButtons; i++) {\n\t var container = document.createElement(\"span\");\n\t\n\t var button = new Button(container, {\n\t mode: \"toggle\",\n\t component: true }, this.update.bind(this, i));\n\t\n\t this.buttons.push(button);\n\t this.element.appendChild(container);\n\t }\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t var buttonWidth = this.width / this._numberOfButtons;\n\t var buttonHeight = this.height;\n\t\n\t for (var i = 0; i < this._numberOfButtons; i++) {\n\t this.buttons[i].resize(buttonWidth, buttonHeight);\n\t }\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t for (var i = 0; i < this._numberOfButtons; i++) {\n\t this.buttons[i].colors = this.colors;\n\t this.buttons[i].render();\n\t }\n\t }\n\t },\n\t update: {\n\t value: function update(index) {\n\t if (this.buttons[index].state) {\n\t this.select(index);\n\t } else {\n\t this.deselect();\n\t }\n\t // this.render();\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t for (var i = 0; i < this.buttons.length; i++) {\n\t if (i === this.active) {\n\t this.buttons[i].turnOn(false);\n\t } else {\n\t this.buttons[i].turnOff(false);\n\t }\n\t }\n\t }\n\t },\n\t select: {\n\t\n\t /**\n\t Select one button and deselect all other buttons.\n\t @param index {number} The index of the button to select\n\t */\n\t\n\t value: function select(index) {\n\t if (index >= 0 && index < this.buttons.length) {\n\t this.active = index;\n\t this.emit(\"change\", this.active);\n\t this.render();\n\t }\n\t }\n\t },\n\t deselect: {\n\t\n\t /**\n\t Deselect all buttons.\n\t */\n\t\n\t value: function deselect() {\n\t this.active = -1;\n\t this.emit(\"change\", this.active);\n\t this.render();\n\t }\n\t },\n\t numberOfButtons: {\n\t get: function () {\n\t return this._numberOfButtons;\n\t },\n\t\n\t /**\n\t * Update how many buttons are in the interface\n\t * @param {number} buttons How many buttons are in the interface\n\t */\n\t set: function (buttons) {\n\t this._numberOfButtons = buttons;\n\t for (var i = 0; i < this.buttons.length; i++) {\n\t this.buttons[i].destroy();\n\t }\n\t this.buttons = [];\n\t // for (let i=0;i<this.buttons.length;i++) {\n\t // this.buttons[i].destroy();\n\t // }\n\t this.empty();\n\t this.buildInterface();\n\t }\n\t }\n\t });\n\t\n\t return RadioButton;\n\t})(Interface);\n\t\n\tmodule.exports = RadioButton;\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\tvar math = __webpack_require__(5);\n\t\n\t/**\n\t* Number\n\t*\n\t* @description Number interface which is controllable by dragging or typing.\n\t*\n\t* @demo <span nexus-ui=\"number\"></span>\n\t*\n\t* @example\n\t* var number = new Nexus.Number('#target')\n\t*\n\t* @example\n\t* var number = new Nexus.Number('#target',{\n\t* 'size': [60,30],\n\t* 'value': 0,\n\t* 'min': 0,\n\t* 'max': 20000,\n\t* 'step': 1\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data is the number value of the interface.\n\t*\n\t* @outputexample\n\t* number.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Number = (function (_Interface) {\n\t function Number() {\n\t _classCallCheck(this, Number);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [60, 30],\n\t value: 0,\n\t min: 0,\n\t max: 20000,\n\t step: 1\n\t };\n\t\n\t _get(Object.getPrototypeOf(Number.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._value = new Step(this.settings.min, this.settings.max, this.settings.step, this.settings.value);\n\t\n\t /*\n\t Default: 2. How many decimal places to clip the number's visual rendering to. This does not affect number's actual value output -- for that, set the step property to .01, .1, or 1.\n\t @type {number}\n\t @example number.decimalPlaces = 2;\n\t */\n\t this.decimalPlaces = 2;\n\t this.actual = 0;\n\t\n\t this.max = this._value.max;\n\t\n\t this.min = this._value.min;\n\t\n\t this.step = this._value.step;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(Number, _Interface);\n\t\n\t _createClass(Number, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = document.createElement(\"input\");\n\t this.element.type = \"text\";\n\t\n\t this.element.addEventListener(\"blur\", (function () {\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.element.style.color = this.colors.dark;\n\t if (this.element.value !== this.value) {\n\t this.value = parseFloat(this.element.value);\n\t this.render();\n\t }\n\t }).bind(this));\n\t\n\t this.element.addEventListener(\"keydown\", (function (e) {\n\t if (e.which < 48 || e.which > 57) {\n\t if (e.which !== 189 && e.which !== 190 && e.which !== 8) {\n\t e.preventDefault();\n\t }\n\t }\n\t if (e.which === 13) {\n\t this.element.blur();\n\t this.value = this.element.value;\n\t this.emit(\"change\", this.value);\n\t this.render();\n\t }\n\t }).bind(this));\n\t\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t this._minDimension = Math.min(this.width, this.height);\n\t\n\t var styles = \"width: \" + this.width + \"px;\";\n\t styles += \"height: \" + this.height + \"px;\";\n\t styles += \"background-color: #e7e7e7;\";\n\t styles += \"color: #333;\";\n\t styles += \"font-family: arial;\";\n\t styles += \"font-weight: 500;\";\n\t styles += \"font-size:\" + this._minDimension / 2 + \"px;\";\n\t // styles += 'highlight: #d18;';\n\t styles += \"border: none;\";\n\t styles += \"outline: none;\";\n\t styles += \"padding: \" + this._minDimension / 4 + \"px \" + this._minDimension / 4 + \"px;\";\n\t styles += \"box-sizing: border-box;\";\n\t styles += \"userSelect: text;\";\n\t styles += \"mozUserSelect: text;\";\n\t styles += \"webkitUserSelect: text;\";\n\t this.element.style.cssText += styles;\n\t\n\t // to add eventually\n\t // var css = '#'+this.elementID+'::selection{ background-color: transparent }';\n\t\n\t this.element.value = this.value;\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.element.style.color = this.colors.dark;\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t\n\t this.element.value = math.prune(this.value, this.decimalPlaces);\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.hasMoved = false;\n\t this.element.readOnly = true;\n\t this.actual = this.value;\n\t this.initial = { y: this.mouse.y };\n\t this.changeFactor = math.invert(this.mouse.x / this.width);\n\t console.log(this.changeFactor);\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t this.hasMoved = true;\n\t if (this.clicked) {\n\t\n\t var newvalue = this.actual - (this.mouse.y - this.initial.y) * (math.clip(this.max - this.min, 0, 1000) / 200) * Math.pow(this.changeFactor, 2);\n\t this.value = newvalue;\n\t\n\t this.render();\n\t if (this._value.changed) {\n\t this.emit(\"change\", this.value);\n\t }\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t if (!this.hasMoved) {\n\t this.element.readOnly = false;\n\t this.element.focus();\n\t this.element.setSelectionRange(0, this.element.value.length);\n\t this.element.style.backgroundColor = this.colors.accent;\n\t this.element.style.color = this.colors.light;\n\t } else {\n\t document.body.focus();\n\t }\n\t }\n\t },\n\t link: {\n\t\n\t /**\n\t Connect this number interface to a dial or slider\n\t @param {Interface} element Element to connect to.\n\t @example number.link(slider)\n\t */\n\t\n\t value: function link(destination) {\n\t var _this = this;\n\t\n\t this.min = destination.min;\n\t this.max = destination.max;\n\t this.step = destination.step;\n\t destination.on(\"change\", function (v) {\n\t _this.passiveUpdate(v);\n\t });\n\t this.on(\"change\", function (v) {\n\t destination.value = v;\n\t });\n\t this.value = destination.value;\n\t /* return {\n\t listener1: listener1,\n\t listener2: listener2,\n\t destroy: () => {\n\t listener1.remove() (or similar)\n\t listener2.remove() (or similar)\n\t }\n\t } */\n\t }\n\t },\n\t passiveUpdate: {\n\t value: function passiveUpdate(v) {\n\t this._value.update(v);\n\t this.render();\n\t }\n\t },\n\t value: {\n\t\n\t /**\n\t The interface's current value. If set manually, will update the interface and trigger the output event.\n\t @type {number}\n\t @example number.value = 10;\n\t */\n\t\n\t get: function () {\n\t return this._value.value;\n\t },\n\t set: function (v) {\n\t this._value.update(v);\n\t this.emit(\"change\", this.value);\n\t this.render();\n\t }\n\t },\n\t min: {\n\t\n\t /**\n\t Lower limit of the number's output range\n\t @type {number}\n\t @example number.min = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.min;\n\t },\n\t set: function (v) {\n\t this._value.min = v;\n\t }\n\t },\n\t max: {\n\t\n\t /**\n\t Upper limit of the number's output range\n\t @type {number}\n\t @example number.max = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.max;\n\t },\n\t set: function (v) {\n\t this._value.max = v;\n\t }\n\t },\n\t step: {\n\t\n\t /**\n\t The increment that the number's value changes by.\n\t @type {number}\n\t @example number.step = 5;\n\t */\n\t\n\t get: function () {\n\t return this._value.step;\n\t },\n\t set: function (v) {\n\t this._value.step = v;\n\t }\n\t }\n\t });\n\t\n\t return Number;\n\t})(Interface);\n\t\n\tmodule.exports = Number;\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\t* Select\n\t*\n\t* @description Dropdown menu\n\t*\n\t* @demo <span nexus-ui=\"select\"></span>\n\t*\n\t* @example\n\t* var select = new Nexus.Select('#target')\n\t*\n\t* @example\n\t* var select = new Nexus.Select('#target',{\n\t* 'size': [100,30],\n\t* 'options': ['default','options']\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data is an object containing the text value of the selected option, as well as the numeric index of the selection.\n\t*\n\t* @outputexample\n\t* select.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Select = (function (_Interface) {\n\t function Select() {\n\t _classCallCheck(this, Select);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [100, 30],\n\t options: [\"default\", \"options\"]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Select.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._selectedIndex = -1;\n\t this._value = false;\n\t\n\t this._options = this.settings.options;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(Select, _Interface);\n\t\n\t _createClass(Select, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = document.createElement(\"select\");\n\t this.element.style.fontSize = this.height / 2 + \"px\";\n\t this.element.style.outline = \"none\";\n\t this.element.style.highlight = \"none\";\n\t this.element.style.width = this.width + \"px\";\n\t this.element.style.height = this.height + \"px\";\n\t\n\t this.boundRender = this.render.bind(this);\n\t\n\t this.element.addEventListener(\"change\", this.boundRender);\n\t\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t attachListeners: {\n\t value: function attachListeners() {}\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.defineOptions();\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.element.style.color = this.colors.dark;\n\t this.element.style.border = \"solid 0px \" + this.colors.mediumLight;\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t\n\t this._value = this.element.options[this.element.selectedIndex].text;\n\t this._selectedIndex = this.element.selectedIndex;\n\t this.emit(\"change\", {\n\t value: this._value,\n\t index: this._selectedIndex\n\t });\n\t }\n\t },\n\t click: {\n\t value: function click() {}\n\t },\n\t move: {\n\t value: function move() {}\n\t },\n\t release: {\n\t value: function release() {}\n\t },\n\t defineOptions: {\n\t\n\t /**\n\t * Update the list of options. This removes all existing options and creates a new list of options.\n\t * @param {array} options New array of options\n\t */\n\t\n\t value: function defineOptions(options) {\n\t\n\t /* function removeOptions(selectbox)\n\t {\n\t var i;\n\t for(i = selectbox.options.length - 1 ; i >= 0 ; i--)\n\t {\n\t selectbox.remove(i);\n\t }\n\t }\n\t //using the function:\n\t removeOptions(document.getElementById(\"mySelectObject\")); */\n\t\n\t if (options) {\n\t this._options = options;\n\t }\n\t\n\t for (var i = this.element.options.length - 1; i >= 0; i--) {\n\t this.element.remove(i);\n\t }\n\t\n\t for (var i = 0; i < this._options.length; i++) {\n\t this.element.options.add(new Option(this._options[i], i));\n\t }\n\t }\n\t },\n\t value: {\n\t\n\t /**\n\t The text of the option that is currently selected. If set, will update the interface and trigger the output event.\n\t @type {String}\n\t @example select.value = \"sawtooth\";\n\t */\n\t\n\t get: function () {\n\t return this._value;\n\t },\n\t set: function (v) {\n\t this._value = v;\n\t for (var i = 0; i < this.element.options.length; i++) {\n\t if (v === this.element.options[i].text) {\n\t this.selectedIndex = i;\n\t break;\n\t }\n\t }\n\t }\n\t },\n\t selectedIndex: {\n\t\n\t /**\n\t The numeric index of the option that is currently selected. If set, will update the interface and trigger the output event.\n\t @type {number}\n\t @example select.selectedIndex = 2;\n\t */\n\t\n\t get: function () {\n\t return this._selectedIndex;\n\t },\n\t set: function (v) {\n\t this._selectedIndex = v;\n\t this.element.selectedIndex = v;\n\t this.render();\n\t }\n\t },\n\t customDestroy: {\n\t value: function customDestroy() {\n\t this.element.removeEventListener(\"change\", this.boundRender);\n\t }\n\t }\n\t });\n\t\n\t return Select;\n\t})(Interface);\n\t\n\tmodule.exports = Select;\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar math = __webpack_require__(5);\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\t\n\tvar Interaction = _interopRequireWildcard(__webpack_require__(12));\n\t\n\t/**\n\t* Dial\n\t*\n\t*\n\t* @description Dial with radial or linear interaction.\n\t*\n\t* @demo <span nexus-ui=\"dial\"></span>\n\t*\n\t* @example\n\t* var dial = new Nexus.Dial('#target')\n\t*\n\t* @example\n\t* var dial = new Nexus.Dial('#target',{\n\t* 'size': [75,75],\n\t* 'interaction': 'radial', // \"radial\", \"vertical\", or \"horizontal\"\n\t* 'mode': 'relative', // \"absolute\" or \"relative\"\n\t* 'min': 0,\n\t* 'max': 1,\n\t* 'step': 0,\n\t* 'value': 0\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data is the number value of the interface.\n\t*\n\t* @outputexample\n\t* dial.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t* @tutorial\n\t* Dial\n\t* ygGMxq\n\t*\n\t*/\n\t\n\tvar Dial = (function (_Interface) {\n\t function Dial() {\n\t _classCallCheck(this, Dial);\n\t\n\t var options = [\"min\", \"max\", \"value\"];\n\t\n\t var defaults = {\n\t size: [75, 75],\n\t interaction: \"radial\", // radial, vertical, horizontal\n\t mode: \"relative\", // absolute, relative\n\t min: 0,\n\t max: 1,\n\t step: 0,\n\t value: 0\n\t };\n\t\n\t _get(Object.getPrototypeOf(Dial.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.interaction = this.settings.interaction;\n\t\n\t this._value = new Step(this.settings.min, this.settings.max, this.settings.step, this.settings.value);\n\t\n\t this.position = new Interaction.Handle(this.settings.mode, this.interaction, [0, this.width], [this.height, 0]);\n\t\n\t this.init();\n\t\n\t this.value = this._value.value;\n\t\n\t this.position.value = this._value.normalized;\n\t\n\t this.previousAngle = false;\n\t\n\t this.emit(\"change\", this.value);\n\t }\n\t\n\t _inherits(Dial, _Interface);\n\t\n\t _createClass(Dial, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.background = svg.create(\"circle\");\n\t this.screw = svg.create(\"circle\");\n\t this.handle = svg.create(\"path\");\n\t this.handle2 = svg.create(\"path\");\n\t this.handleFill = svg.create(\"path\");\n\t this.handle2Fill = svg.create(\"path\");\n\t this.handleLine = svg.create(\"path\");\n\t\n\t this.element.appendChild(this.background);\n\t this.element.appendChild(this.handle);\n\t this.element.appendChild(this.handle2);\n\t this.element.appendChild(this.handleFill);\n\t this.element.appendChild(this.handle2Fill);\n\t this.element.appendChild(this.handleLine);\n\t this.element.appendChild(this.screw);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t this.position.resize([0, this.width], [this.height, 0]);\n\t\n\t var center = {\n\t x: this.width / 2,\n\t y: this.height / 2\n\t };\n\t\n\t var diameter = Math.min(this.width, this.height);\n\t\n\t this.background.setAttribute(\"cx\", center.x);\n\t this.background.setAttribute(\"cy\", center.y);\n\t this.background.setAttribute(\"r\", diameter / 2 - diameter / 40);\n\t\n\t this.screw.setAttribute(\"cx\", center.x);\n\t this.screw.setAttribute(\"cy\", center.y);\n\t this.screw.setAttribute(\"r\", diameter / 12);\n\t\n\t var value = this.value;\n\t\n\t var handlePoints = {\n\t start: Math.PI * 1.5,\n\t end: math.clip(math.scale(value, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5)\n\t };\n\t var handle2Points = {\n\t start: Math.PI * 2.5,\n\t end: math.clip(math.scale(value, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5)\n\t };\n\t\n\t var handlePath = svg.arc(center.x, center.y, diameter / 2 - diameter / 40, handlePoints.start, handlePoints.end);\n\t var handle2Path = svg.arc(center.x, center.y, diameter / 2 - diameter / 40, handle2Points.start, handle2Points.end);\n\t\n\t this.handle.setAttribute(\"d\", handlePath);\n\t this.handle.setAttribute(\"stroke-width\", diameter / 20);\n\t this.handle.setAttribute(\"fill\", \"none\");\n\t\n\t this.handle2.setAttribute(\"d\", handle2Path);\n\t this.handle2.setAttribute(\"stroke-width\", diameter / 20);\n\t this.handle2.setAttribute(\"fill\", \"none\");\n\t\n\t handlePath += \" L \" + center.x + \" \" + center.y;\n\t\n\t this.handleFill.setAttribute(\"d\", handlePath);\n\t this.handleFill.setAttribute(\"fill-opacity\", \"0.3\");\n\t\n\t handle2Path += \" L \" + center.x + \" \" + center.y;\n\t\n\t this.handle2Fill.setAttribute(\"d\", handle2Path);\n\t this.handle2Fill.setAttribute(\"fill-opacity\", \"0.3\");\n\t\n\t var arcEndingA = undefined;\n\t if (value < 0.5) {\n\t arcEndingA = handlePoints.end;\n\t } else {\n\t arcEndingA = handle2Points.end;\n\t }\n\t\n\t var arcEndingX = center.x + Math.cos(arcEndingA) * (diameter / 2);\n\t var arcEndingY = center.y + Math.sin(arcEndingA) * (diameter / 2) * -1;\n\t\n\t this.handleLine.setAttribute(\"d\", \"M \" + center.x + \" \" + center.y + \" L \" + arcEndingX + \" \" + arcEndingY);\n\t this.handleLine.setAttribute(\"stroke-width\", diameter / 20);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.background.setAttribute(\"fill\", this.colors.fill);\n\t this.screw.setAttribute(\"fill\", this.colors.accent);\n\t this.handle.setAttribute(\"stroke\", this.colors.accent);\n\t this.handle2.setAttribute(\"stroke\", this.colors.accent);\n\t this.handleFill.setAttribute(\"fill\", this.colors.accent);\n\t this.handle2Fill.setAttribute(\"fill\", this.colors.accent);\n\t this.handleLine.setAttribute(\"stroke\", this.colors.accent);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t var value = this._value.normalized;\n\t\n\t var center = {\n\t x: this.width / 2,\n\t y: this.height / 2\n\t };\n\t\n\t var diameter = Math.min(this.width, this.height);\n\t\n\t var handlePoints = {\n\t start: Math.PI * 1.5,\n\t end: math.clip(math.scale(value, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5)\n\t };\n\t var handle2Points = {\n\t start: Math.PI * 2.5,\n\t end: math.clip(math.scale(value, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5)\n\t };\n\t\n\t var handlePath = svg.arc(center.x, center.y, diameter / 2 - diameter / 40, handlePoints.start, handlePoints.end);\n\t var handle2Path = svg.arc(center.x, center.y, diameter / 2 - diameter / 40, handle2Points.start, handle2Points.end);\n\t\n\t this.handle.setAttribute(\"d\", handlePath);\n\t this.handle2.setAttribute(\"d\", handle2Path);\n\t\n\t handlePath += \" L \" + center.x + \" \" + center.y;\n\t\n\t this.handleFill.setAttribute(\"d\", handlePath);\n\t\n\t handle2Path += \" L \" + center.x + \" \" + center.y;\n\t\n\t this.handle2Fill.setAttribute(\"d\", handle2Path);\n\t\n\t var arcEndingA = undefined;\n\t if (value <= 0.5) {\n\t arcEndingA = handlePoints.end;\n\t } else {\n\t arcEndingA = handle2Points.end;\n\t }\n\t\n\t var arcEndingX = center.x + Math.cos(arcEndingA) * (diameter / 2);\n\t var arcEndingY = center.y + Math.sin(arcEndingA) * (diameter / 2) * -1;\n\t\n\t this.handleLine.setAttribute(\"d\", \"M \" + center.x + \" \" + center.y + \" L \" + arcEndingX + \" \" + arcEndingY);\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t if (this.mode === \"relative\") {\n\t this.previousAngle = false;\n\t }\n\t this.position.anchor = this.mouse;\n\t this.position.value = this._value.normalized;\n\t this.move();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.clicked) {\n\t\n\t this.position.update(this.mouse);\n\t\n\t var angle = this.position.value * Math.PI * 2;\n\t\n\t if (angle < 0) {\n\t angle += Math.PI * 2;\n\t }\n\t\n\t if (this.mode === \"relative\") {\n\t if (this.previousAngle !== false && Math.abs(this.previousAngle - angle) > 2) {\n\t if (this.previousAngle > 3) {\n\t angle = Math.PI * 2;\n\t } else {\n\t angle = 0;\n\t }\n\t }\n\t } /* else {\n\t if (this.previousAngle !== false && Math.abs(this.previousAngle - angle) > 2) {\n\t if (this.previousAngle > 3) {\n\t angle = Math.PI*2;\n\t } else {\n\t angle = 0;\n\t }\n\t }\n\t } */\n\t this.previousAngle = angle;\n\t\n\t var realValue = angle / (Math.PI * 2);\n\t\n\t this.value = this._value.updateNormal(realValue);\n\t\n\t if (this.mode === \"relative\") {\n\t this.position.value = realValue;\n\t }\n\t\n\t this.emit(\"change\", this._value.value);\n\t\n\t this.render();\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {}\n\t },\n\t value: {\n\t\n\t /*\n\t Dial's value. When set, it will automatically be adjust to fit min/max/step settings of the interface.\n\t @type {number}\n\t @example dial.value = 10;\n\t get value() {\n\t return this._value.value;\n\t }\n\t set value(value) {\n\t this._value.update(value);\n\t this.emit('change',this.value);\n\t this.render();\n\t }\n\t */\n\t\n\t /**\n\t Dial's value. When set, it will automatically be adjust to fit min/max/step settings of the interface.\n\t @type {number}\n\t @example dial.value = 10;\n\t */\n\t\n\t get: function () {\n\t return this._value.value;\n\t },\n\t set: function (v) {\n\t this._value.update(v);\n\t this.position.value = this._value.normalized;\n\t this.emit(\"change\", this._value.value);\n\t this.render();\n\t }\n\t },\n\t min: {\n\t\n\t /**\n\t Lower limit of the dial's output range\n\t @type {number}\n\t @example dial.min = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.min;\n\t },\n\t set: function (v) {\n\t this._value.min = v;\n\t }\n\t },\n\t max: {\n\t\n\t /**\n\t Upper limit of the dial's output range\n\t @type {number}\n\t @example dial.max = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.max;\n\t },\n\t set: function (v) {\n\t this._value.max = v;\n\t }\n\t },\n\t step: {\n\t\n\t /**\n\t The increment that the dial's value changes by.\n\t @type {number}\n\t @example dial.step = 5;\n\t */\n\t\n\t get: function () {\n\t return this._value.step;\n\t },\n\t set: function (v) {\n\t this._value.step = v;\n\t }\n\t },\n\t mode: {\n\t\n\t /**\n\t Absolute mode (dial's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: \"relative\".\n\t @type {string}\n\t @example dial.mode = \"relative\";\n\t */\n\t\n\t get: function () {\n\t return this.position.mode;\n\t },\n\t set: function (v) {\n\t this.position.mode = v;\n\t }\n\t },\n\t normalized: {\n\t\n\t /**\n\t Normalized value of the dial.\n\t @type {number}\n\t @example dial.normalized = 0.5;\n\t */\n\t\n\t get: function () {\n\t return this._value.normalized;\n\t },\n\t set: function (v) {\n\t this._value.updateNormal(v);\n\t this.emit(\"change\", this.value);\n\t }\n\t }\n\t });\n\t\n\t return Dial;\n\t})(Interface);\n\t\n\tmodule.exports = Dial;\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar Interface = __webpack_require__(6);\n\tvar ButtonTemplate = __webpack_require__(17);\n\tvar touch = __webpack_require__(9);\n\t\n\tvar PianoKey = (function (_ButtonTemplate) {\n\t function PianoKey() {\n\t _classCallCheck(this, PianoKey);\n\t\n\t var options = [\"value\", \"note\", \"color\"];\n\t\n\t var defaults = {\n\t size: [80, 80],\n\t target: false,\n\t mode: \"button\",\n\t value: 0\n\t };\n\t\n\t _get(Object.getPrototypeOf(PianoKey.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.note = this.settings.note;\n\t this.color = this.settings.color;\n\t\n\t this.colors = {\n\t w: \"#fff\",\n\t b: \"#666\" };\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(PianoKey, _ButtonTemplate);\n\t\n\t _createClass(PianoKey, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = svg.create(\"svg\");\n\t this.element.setAttribute(\"width\", this.width);\n\t this.element.setAttribute(\"height\", this.height);\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t var _this = this;\n\t\n\t this.pad = svg.create(\"rect\");\n\t\n\t this.element.appendChild(this.pad);\n\t\n\t this.interactionTarget = this.pad;\n\t\n\t /* events */\n\t\n\t if (!touch.exists) {\n\t\n\t this.click = function () {\n\t // console.log('click');\n\t _this.piano.interacting = true;\n\t _this.piano.paintbrush = !_this.state;\n\t _this.down(_this.piano.paintbrush);\n\t };\n\t\n\t this.pad.addEventListener(\"mouseover\", function () {\n\t if (_this.piano.interacting) {\n\t // console.log('mouseover');\n\t _this.down(_this.piano.paintbrush);\n\t }\n\t });\n\t\n\t this.move = function () {\n\t if (_this.piano.interacting) {\n\t // console.log('move');\n\t _this.bend();\n\t }\n\t };\n\t\n\t this.release = function () {\n\t _this.piano.interacting = false;\n\t // console.log('release');\n\t // this.up();\n\t };\n\t this.pad.addEventListener(\"mouseup\", function () {\n\t if (_this.piano.interacting) {\n\t // console.log('mouseup');\n\t _this.up();\n\t }\n\t });\n\t this.pad.addEventListener(\"mouseout\", function () {\n\t if (_this.piano.interacting) {\n\t // console.log('mouseout');\n\t _this.up();\n\t }\n\t });\n\t }\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t //let radius = Math.min(this.width,this.height) / 5;\n\t var radius = 0;\n\t\n\t this.pad.setAttribute(\"x\", 0.5);\n\t this.pad.setAttribute(\"y\", 0.5);\n\t if (this.width > 2) {\n\t this.pad.setAttribute(\"width\", this.width - 1);\n\t } else {\n\t this.pad.setAttribute(\"width\", this.width);\n\t }\n\t if (this.height > 2) {\n\t this.pad.setAttribute(\"height\", this.height);\n\t } else {\n\t this.pad.setAttribute(\"height\", this.height);\n\t }\n\t this.pad.setAttribute(\"rx\", radius);\n\t this.pad.setAttribute(\"ry\", radius);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.state) {\n\t this.pad.setAttribute(\"fill\", this.colors[this.color]);\n\t } else {\n\t this.pad.setAttribute(\"fill\", this.colors.accent);\n\t }\n\t }\n\t }\n\t });\n\t\n\t return PianoKey;\n\t})(ButtonTemplate);\n\t\n\t/**\n\t* Piano\n\t*\n\t* @description Piano keyboard interface\n\t*\n\t* @demo <div nexus-ui=\"piano\"></div>\n\t*\n\t* @example\n\t* var piano = new Nexus.Piano('#target')\n\t*\n\t* @example\n\t* var piano = new Nexus.Piano('#target',{\n\t* 'size': [500,125],\n\t* 'mode': 'button', // 'button', 'toggle', or 'impulse'\n\t* 'lowNote': 24,\n\t* 'highNote': 60\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time a new key is pressed or released <br>\n\t* The event data is an object containing <i>note</i> and <i>state</i> properties.\n\t*\n\t* @outputexample\n\t* piano.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\tvar Piano = (function (_Interface) {\n\t function Piano() {\n\t _classCallCheck(this, Piano);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [500, 125],\n\t lowNote: 24,\n\t highNote: 60,\n\t mode: \"button\"\n\t };\n\t\n\t _get(Object.getPrototypeOf(Piano.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.keyPattern = [\"w\", \"b\", \"w\", \"b\", \"w\", \"w\", \"b\", \"w\", \"b\", \"w\", \"b\", \"w\"];\n\t\n\t this.paintbrush = false;\n\t\n\t this.mode = this.settings.mode;\n\t\n\t this.range = {\n\t low: this.settings.lowNote,\n\t high: this.settings.highNote\n\t };\n\t\n\t this.range.size = this.range.high - this.range.low;\n\t\n\t this.keys = [];\n\t\n\t this.toggleTo = false;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(Piano, _Interface);\n\t\n\t _createClass(Piano, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = document.createElement(\"div\");\n\t this.element.style.position = \"relative\";\n\t this.element.style.borderRadius = \"0px\";\n\t this.element.style.display = \"block\";\n\t this.element.style.width = \"100%\";\n\t this.element.style.height = \"100%\";\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.keys = [];\n\t\n\t for (var i = 0; i < this.range.high - this.range.low; i++) {\n\t\n\t var container = document.createElement(\"span\");\n\t var scaleIndex = (i + this.range.low) % this.keyPattern.length;\n\t\n\t var key = new PianoKey(container, {\n\t component: true,\n\t note: i + this.range.low,\n\t color: this.keyPattern[scaleIndex],\n\t mode: this.mode\n\t }, this.keyChange.bind(this, i + this.range.low));\n\t\n\t key.piano = this;\n\t\n\t if (touch.exists) {\n\t key.pad.index = i;\n\t key.preClick = key.preMove = key.preRelease = function () {};\n\t key.click = key.move = key.release = function () {};\n\t key.preTouch = key.preTouchMove = key.preTouchRelease = function () {};\n\t key.touch = key.touchMove = key.touchRelease = function () {};\n\t }\n\t\n\t this.keys.push(key);\n\t this.element.appendChild(container);\n\t }\n\t if (touch.exists) {\n\t this.addTouchListeners();\n\t }\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t var keyX = 0;\n\t\n\t var keyPositions = [];\n\t\n\t for (var i = 0; i < this.range.high - this.range.low; i++) {\n\t\n\t keyPositions.push(keyX);\n\t\n\t var scaleIndex = (i + this.range.low) % this.keyPattern.length;\n\t var nextScaleIndex = (i + 1 + this.range.low) % this.keyPattern.length;\n\t if (i + 1 + this.range.low >= this.range.high) {\n\t keyX += 1;\n\t } else if (this.keyPattern[scaleIndex] === \"w\" && this.keyPattern[nextScaleIndex] === \"w\") {\n\t keyX += 1;\n\t } else {\n\t keyX += 0.5;\n\t }\n\t }\n\t var keysWide = keyX;\n\t\n\t // let padding = this.width / 120;\n\t var padding = 1;\n\t var buttonWidth = (this.width - padding * 2) / keysWide;\n\t var buttonHeight = (this.height - padding * 2) / 2;\n\t\n\t for (var i = 0; i < this.keys.length; i++) {\n\t\n\t var container = this.keys[i].parent;\n\t container.style.position = \"absolute\";\n\t container.style.left = keyPositions[i] * buttonWidth + padding + \"px\";\n\t if (this.keys[i].color === \"w\") {\n\t container.style.top = padding + \"px\";\n\t this.keys[i].resize(buttonWidth, buttonHeight * 2);\n\t } else {\n\t container.style.zIndex = 1;\n\t container.style.top = padding + \"px\";\n\t this.keys[i].resize(buttonWidth, buttonHeight * 1.1);\n\t }\n\t }\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t\n\t // Piano keys don't actually have a stroke border\n\t // They have space between them, which shows the Piano bg color\n\t this.element.style.backgroundColor = this.colors.mediumLight;\n\t\n\t for (var i = 0; i < this.keys.length; i++) {\n\t this.keys[i].colors = {\n\t w: this.colors.light,\n\t b: this.colors.dark,\n\t accent: this.colors.accent,\n\t border: this.colors.mediumLight\n\t };\n\t this.keys[i].colorInterface();\n\t this.keys[i].render();\n\t }\n\t }\n\t },\n\t keyChange: {\n\t value: function keyChange(note, on) {\n\t // emit data for any key turning on/off\n\t // \"note\" is the note value\n\t // \"on\" is a boolean whether it is on or off\n\t // in aftertouch mode, \"on: is an object with state/x/y properties\n\t var data = {\n\t note: note\n\t };\n\t if (typeof on === \"object\") {\n\t data.state = on.state;\n\t // data.x = on.x\n\t // data.y = on.y\n\t } else {\n\t data.state = on;\n\t }\n\t this.emit(\"change\", data);\n\t }\n\t },\n\t render: {\n\t\n\t /* drag(note,on) {\n\t this.emit('change',{\n\t note: note,\n\t state: on\n\t });\n\t } */\n\t\n\t value: function render() {}\n\t },\n\t addTouchListeners: {\n\t value: function addTouchListeners() {\n\t var _this = this;\n\t\n\t this.preClick = this.preMove = this.preRelease = function () {};\n\t this.click = this.move = this.release = function () {};\n\t this.preTouch = this.preTouchMove = this.preTouchRelease = function () {};\n\t this.touch = this.touchMove = this.touchRelease = function () {};\n\t\n\t this.currentElement = false;\n\t\n\t this.element.addEventListener(\"touchstart\", function (e) {\n\t console.log(\"touchstart\");\n\t var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);\n\t var key = _this.keys[element.index];\n\t _this.paintbrush = !key.state;\n\t key.down(_this.paintbrush);\n\t _this.currentElement = element.index;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t\n\t this.element.addEventListener(\"touchmove\", function (e) {\n\t var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);\n\t var key = _this.keys[element.index];\n\t if (element.index !== _this.currentElement) {\n\t if (_this.currentElement) {\n\t var pastKey = _this.keys[_this.currentElement];\n\t pastKey.up();\n\t }\n\t key.down(_this.paintbrush);\n\t } else {\n\t key.bend();\n\t }\n\t _this.currentElement = element.index;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t\n\t this.element.addEventListener(\"touchend\", function (e) {\n\t // no touches to calculate because none remaining\n\t var key = _this.keys[_this.currentElement];\n\t key.up();\n\t _this.interacting = false;\n\t _this.currentElement = false;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t }\n\t },\n\t setRange: {\n\t\n\t /**\n\t Define the pitch range (lowest and highest note) of the piano keyboard.\n\t @param low {number} MIDI note value of the lowest note on the keyboard\n\t @param high {number} MIDI note value of the highest note on the keyboard\n\t */\n\t\n\t value: function setRange(low, high) {\n\t this.range.low = low;\n\t this.range.high = high;\n\t this.empty();\n\t this.buildInterface();\n\t }\n\t },\n\t toggleKey: {\n\t\n\t /**\n\t Turn a key on or off using its MIDI note value;\n\t @param note {number} MIDI note value of the key to change\n\t @param on {boolean} Whether the note should turn on or off\n\t */\n\t\n\t value: function toggleKey(note, on) {\n\t this.keys[note - this.range.low].flip(on);\n\t }\n\t },\n\t toggleIndex: {\n\t\n\t /**\n\t Turn a key on or off using its key index on the piano interface.\n\t @param index {number} Index of the key to change\n\t @param on {boolean} Whether the note should turn on or off\n\t */\n\t\n\t value: function toggleIndex(index, on) {\n\t this.keys[index].flip(on);\n\t }\n\t }\n\t });\n\t\n\t return Piano;\n\t})(Interface);\n\t\n\tmodule.exports = Piano;\n\t\n\t// loop through and render the keys?\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar dom = __webpack_require__(7);\n\tvar Interface = __webpack_require__(6);\n\tvar ButtonTemplate = __webpack_require__(17);\n\tvar MatrixModel = __webpack_require__(25);\n\tvar CounterModel = __webpack_require__(28);\n\tvar touch = __webpack_require__(9);\n\t\n\tvar MatrixCell = (function (_ButtonTemplate) {\n\t function MatrixCell() {\n\t _classCallCheck(this, MatrixCell);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [80, 80],\n\t target: false,\n\t mode: \"toggle\",\n\t value: 0\n\t };\n\t\n\t _get(Object.getPrototypeOf(MatrixCell.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.index = this.settings.index;\n\t this.row = this.settings.row;\n\t this.column = this.settings.column;\n\t\n\t this.matrix = this.settings.matrix;\n\t\n\t this.interacting = false;\n\t this.paintbrush = false;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(MatrixCell, _ButtonTemplate);\n\t\n\t _createClass(MatrixCell, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = svg.create(\"svg\");\n\t this.element.setAttribute(\"width\", this.width);\n\t this.element.setAttribute(\"height\", this.height);\n\t this.element.style.top = \"0px\";\n\t this.element.style.left = \"0px\";\n\t this.element.style.position = \"absolute\";\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t var _this = this;\n\t\n\t this.pad = svg.create(\"rect\");\n\t this.element.appendChild(this.pad);\n\t\n\t this.interactionTarget = this.pad;\n\t\n\t /* events */\n\t\n\t if (!touch.exists) {\n\t\n\t this.click = function () {\n\t _this.matrix.interacting = true;\n\t _this.matrix.paintbrush = !_this.state;\n\t _this.down(_this.matrix.paintbrush);\n\t };\n\t this.pad.addEventListener(\"mouseover\", function () {\n\t if (_this.matrix.interacting) {\n\t _this.down(_this.matrix.paintbrush);\n\t }\n\t });\n\t\n\t this.move = function () {};\n\t this.pad.addEventListener(\"mousemove\", function (e) {\n\t if (_this.matrix.interacting) {\n\t if (!_this.offset) {\n\t _this.offset = dom.findPosition(_this.element);\n\t }\n\t _this.mouse = dom.locateMouse(e, _this.offset);\n\t _this.bend();\n\t }\n\t });\n\t\n\t this.release = function () {\n\t _this.matrix.interacting = false;\n\t };\n\t this.pad.addEventListener(\"mouseup\", function () {\n\t if (_this.matrix.interacting) {\n\t _this.up();\n\t }\n\t });\n\t this.pad.addEventListener(\"mouseout\", function () {\n\t if (_this.matrix.interacting) {\n\t _this.up();\n\t }\n\t });\n\t }\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t this.pad.setAttribute(\"x\", 1);\n\t this.pad.setAttribute(\"y\", 1);\n\t if (this.width > 2) {\n\t this.pad.setAttribute(\"width\", this.width - 2);\n\t } else {\n\t this.pad.setAttribute(\"width\", this.width);\n\t }\n\t if (this.height > 2) {\n\t this.pad.setAttribute(\"height\", this.height - 2);\n\t } else {\n\t this.pad.setAttribute(\"height\", this.height);\n\t }\n\t //this.pad.setAttribute('height', this.height - 2);\n\t this.pad.setAttribute(\"fill\", this.matrix.colors.fill);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.state) {\n\t this.pad.setAttribute(\"fill\", this.matrix.colors.fill);\n\t } else {\n\t this.pad.setAttribute(\"fill\", this.matrix.colors.accent);\n\t }\n\t }\n\t }\n\t });\n\t\n\t return MatrixCell;\n\t})(ButtonTemplate);\n\t\n\t/**\n\t* Sequencer\n\t*\n\t* @description Grid of buttons with built-in step sequencer.\n\t*\n\t* @demo <div nexus-ui=\"sequencer\" style=\"width:400px;height:200px;\"></div>\n\t*\n\t* @example\n\t* var sequencer = new Nexus.Sequencer('#target')\n\t*\n\t* @example\n\t* var sequencer = new Nexus.Sequencer('#target',{\n\t* 'size': [400,200],\n\t* 'mode': 'toggle',\n\t* 'rows': 5,\n\t* 'columns': 10\n\t*})\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's matrix changes. <br>\n\t* The event data is an object containing <i>row</i> (number), <i>column</i> (number), and <i>state</i> (boolean) properties.\n\t*\n\t* @outputexample\n\t* sequencer.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t* @output\n\t* step\n\t* Fires any time the sequencer steps to the next column, in sequece mode. <br>\n\t* The event data is an <i>array</i> containing all values in the column, <i>bottom row first</i>.\n\t*\n\t* @outputexample\n\t* sequencer.on('step',function(v) {\n\t* console.log(v);\n\t* })\n\t*/\n\t\n\tvar Sequencer = (function (_Interface) {\n\t function Sequencer() {\n\t _classCallCheck(this, Sequencer);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [400, 200],\n\t mode: \"toggle\",\n\t rows: 5,\n\t columns: 10\n\t };\n\t\n\t _get(Object.getPrototypeOf(Sequencer.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.active = -1;\n\t\n\t /**\n\t * Button interaction mode: see Button\n\t * @type {string}\n\t * @example button.mode = 'toggle';\n\t */\n\t this.mode = this.settings.mode;\n\t\n\t /**\n\t * The interval object which controls timing and sequence scheduling.\n\t * @type {interval}\n\t */\n\t this.interval = new Nexus.Interval(200, function () {}, false); // jshint ignore:line\n\t\n\t /**\n\t * A Matrix model containing methods for manipulating the sequencer's array of values. To learn how to manipulate the matrix, read about the matrix model.\n\t * @type {matrix}\n\t */\n\t this.matrix = new MatrixModel(this.settings.rows, this.settings.columns);\n\t this.matrix.ui = this;\n\t\n\t /**\n\t * A Counter model which the sequencer steps through. For example, you could use this model to step through the sequencer in reverse, randomly, or in a drunk walk.\n\t * @type {counter}\n\t */\n\t this.stepper = new CounterModel(0, this.columns);\n\t\n\t this.init();\n\t }\n\t\n\t _inherits(Sequencer, _Interface);\n\t\n\t _createClass(Sequencer, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = document.createElement(\"div\");\n\t this.element.style.position = \"relative\";\n\t this.element.style.display = \"block\";\n\t this.element.style.width = \"100%\";\n\t this.element.style.height = \"100%\";\n\t this.parent.appendChild(this.element);\n\t if (touch.exists) {\n\t this.addTouchListeners();\n\t }\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.cells = [];\n\t for (var i = 0; i < this.matrix.length; i++) {\n\t\n\t var _location = this.matrix.locate(i);\n\t // returns {row,col}\n\t\n\t var container = document.createElement(\"span\");\n\t container.style.position = \"absolute\";\n\t\n\t var cell = new MatrixCell(container, {\n\t component: true,\n\t index: i,\n\t row: _location.row,\n\t column: _location.column,\n\t mode: this.mode,\n\t matrix: this\n\t }, this.keyChange.bind(this, i));\n\t\n\t // cell.matrix = this;\n\t if (touch.exists) {\n\t cell.pad.index = i;\n\t cell.preClick = cell.preMove = cell.preRelease = function () {};\n\t cell.click = cell.move = cell.release = function () {};\n\t cell.preTouch = cell.preTouchMove = cell.preTouchRelease = function () {};\n\t cell.touch = cell.touchMove = cell.touchRelease = function () {};\n\t }\n\t\n\t this.cells.push(cell);\n\t this.element.appendChild(container);\n\t }\n\t this.sizeInterface();\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t var cellWidth = this.width / this.columns;\n\t var cellHeight = this.height / this.rows;\n\t\n\t for (var i = 0; i < this.cells.length; i++) {\n\t var container = this.cells[i].parent;\n\t container.style.left = this.cells[i].column * cellWidth + \"px\";\n\t container.style.top = this.cells[i].row * cellHeight + \"px\";\n\t this.cells[i].resize(cellWidth, cellHeight);\n\t }\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t for (var i = 0; i < this.cells.length; i++) {\n\t this.cells[i].render();\n\t }\n\t }\n\t },\n\t update: {\n\t value: function update() {\n\t var _this = this;\n\t\n\t // console.log(\"updating...\")\n\t //on = on || false;\n\t this.matrix.iterate(function (r, c, i) {\n\t // console.log(this.matrix.pattern[r][c], this.cells[i].state);\n\t if (_this.matrix.pattern[r][c] !== _this.cells[i].state) {\n\t if (_this.matrix.pattern[r][c] > 0) {\n\t _this.cells[i].turnOn();\n\t } else {\n\t _this.cells[i].turnOff();\n\t }\n\t }\n\t });\n\t }\n\t },\n\t keyChange: {\n\t\n\t // update => cell.turnOn => cell.emit => keyChange (seq.emit) => matrix.set.cell => update\n\t //\n\t // interaction => keyChange => matrix.set.cell => update => cell.turnOn\n\t // => emit\n\t //\n\t // set.cell => update => needs to emit.\n\t\n\t value: function keyChange(note, on) {\n\t // emit data for any key turning on/off\n\t // i is the note index\n\t // v is whether it is on or off\n\t var cell = this.matrix.locate(note);\n\t // this.matrix.set.cell(cell.column,cell.row,on);\n\t this.matrix.pattern[cell.row][cell.column] = on;\n\t var data = {\n\t row: cell.row,\n\t column: cell.column,\n\t state: on\n\t };\n\t this.emit(\"change\", data);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t var _this = this;\n\t\n\t if (this.stepper.value >= 0) {\n\t this.matrix.iterate(function (r, c, i) {\n\t if (c === _this.stepper.value) {\n\t _this.cells[i].pad.setAttribute(\"stroke\", _this.colors.mediumLight);\n\t _this.cells[i].pad.setAttribute(\"stroke-width\", \"1\");\n\t _this.cells[i].pad.setAttribute(\"stroke-opacity\", \"1\");\n\t } else {\n\t _this.cells[i].pad.setAttribute(\"stroke\", \"none\");\n\t }\n\t });\n\t }\n\t }\n\t },\n\t start: {\n\t\n\t /**\n\t * Start sequencing\n\t * @param {number} ms Beat tempo in milliseconds\n\t */\n\t\n\t value: function start(ms) {\n\t this.interval.event = this.next.bind(this);\n\t if (ms) {\n\t this.interval.ms(ms);\n\t }\n\t this.interval.start();\n\t }\n\t },\n\t stop: {\n\t\n\t /**\n\t Stop sequencing\n\t */\n\t\n\t value: function stop() {\n\t this.interval.stop();\n\t }\n\t },\n\t next: {\n\t\n\t /**\n\t Manually jump to the next column and trigger the 'change' event. The \"next\" column is determined by your mode of sequencing.\n\t */\n\t\n\t value: function next() {\n\t this.stepper.next();\n\t this.emit(\"step\", this.matrix.column(this.stepper.value).reverse());\n\t this.render();\n\t }\n\t },\n\t addTouchListeners: {\n\t value: function addTouchListeners() {\n\t var _this = this;\n\t\n\t this.preClick = this.preMove = this.preRelease = function () {};\n\t this.click = this.move = this.release = function () {};\n\t this.preTouch = this.preTouchMove = this.preTouchRelease = function () {};\n\t this.touch = this.touchMove = this.touchRelease = function () {};\n\t\n\t this.currentElement = false;\n\t\n\t this.element.addEventListener(\"touchstart\", function (e) {\n\t var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);\n\t var cell = _this.cells[element.index];\n\t _this.paintbrush = !cell.state;\n\t cell.down(_this.paintbrush);\n\t _this.currentElement = element.index;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t\n\t this.element.addEventListener(\"touchmove\", function (e) {\n\t var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);\n\t var cell = _this.cells[element.index];\n\t if (element.index !== _this.currentElement) {\n\t if (_this.currentElement >= 0) {\n\t var pastCell = _this.cells[_this.currentElement];\n\t pastCell.up();\n\t }\n\t cell.down(_this.paintbrush);\n\t } else {\n\t cell.bend();\n\t }\n\t _this.currentElement = element.index;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t\n\t this.element.addEventListener(\"touchend\", function (e) {\n\t // no touches to calculate because none remaining\n\t var cell = _this.cells[_this.currentElement];\n\t cell.up();\n\t _this.interacting = false;\n\t _this.currentElement = false;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t }\n\t },\n\t rows: {\n\t\n\t /**\n\t Number of rows in the sequencer\n\t @type {number}\n\t */\n\t\n\t get: function () {\n\t return this.matrix.rows;\n\t },\n\t set: function (v) {\n\t this.matrix.rows = v;\n\t this.empty();\n\t this.buildInterface();\n\t this.update();\n\t }\n\t },\n\t columns: {\n\t\n\t /**\n\t Number of columns in the sequencer\n\t @type {number}\n\t */\n\t\n\t get: function () {\n\t return this.matrix.columns;\n\t },\n\t set: function (v) {\n\t this.matrix.columns = v;\n\t this.stepper.max = v;\n\t this.empty();\n\t this.buildInterface();\n\t this.update();\n\t }\n\t }\n\t });\n\t\n\t return Sequencer;\n\t})(Interface);\n\t\n\tmodule.exports = Sequencer;\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar Sequence = _interopRequire(__webpack_require__(26));\n\t\n\t// For the tutorial, looking at\n\t\n\t//Pattern section:\n\t// .create(), .rows, .columns,\n\t// .pattern, .length, .formatAsText(), .log(),\n\t// .locate(i), .indexOf(c,r)\n\t// row(), column() (returns contents of row or colum)\n\t\n\t//Control section:\n\t// toggle x3\n\t// set x4\n\t// rotate x3\n\t// populate x3\n\t// erase x3\n\t\n\t// should some version of this have a float value for each cell?\n\t// could be like a mirror .pattern that has values. by default, everything is 1, but could be set...\n\t// not a good way to do that on interface, but as a model it would be nice...\n\t// for .formatAsText(), could multiply by 100 and floor, so each cell is an int from 0 to 9\n\t\n\tvar Matrix = (function () {\n\t function Matrix(rows, columns) {\n\t var _this = this;\n\t\n\t _classCallCheck(this, Matrix);\n\t\n\t // should also have ability to create using an existing matrix (2d array)\n\t this.pattern = [];\n\t this.create(rows, columns);\n\t\n\t this.toggle = {\n\t cell: function (column, row) {\n\t _this.pattern[row][column] = !_this.pattern[row][column]; // math.invert(this.pattern[row][column]);\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t return _this.pattern[row][column];\n\t },\n\t all: function () {\n\t _this.iterate(function (r, c) {\n\t _this.toggle.cell(c, r);\n\t });\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t row: function (row) {\n\t for (var i = 0; i < _this.columns; i++) {\n\t _this.toggle.cell(i, row);\n\t }\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t column: function (column) {\n\t for (var i = 0; i < _this.rows; i++) {\n\t _this.toggle.cell(column, i);\n\t }\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t }\n\t };\n\t\n\t this.set = {\n\t cell: function (column, row, value) {\n\t _this.pattern[row][column] = value;\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t all: function (values) {\n\t // set the whole matrix using a 2d array as input\n\t // this should also resize the array?\n\t _this.pattern = values;\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t row: function (row, values) {\n\t // set a row using an array as input\n\t _this.pattern[row] = values;\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t column: function (column, values) {\n\t // set a column using an array as input\n\t _this.pattern.forEach(function (row, i) {\n\t _this.pattern[i][column] = values[i];\n\t });\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t }\n\t };\n\t\n\t this.rotate = {\n\t //should eventually do (amountX, amountY) here\n\t // could just use a loop and this.rotate.row(i,amountX);\n\t all: function (amount) {\n\t if (!amount && amount !== 0) {\n\t amount = 1;\n\t }\n\t amount %= _this.pattern[0].length;\n\t if (amount < 0) {\n\t amount = _this.pattern[0].length + amount;\n\t }\n\t for (var i = 0; i < _this.rows; i++) {\n\t var cut = _this.pattern[i].splice(_this.pattern[i].length - amount, amount);\n\t _this.pattern[i] = cut.concat(_this.pattern[i]);\n\t }\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t row: function (row, amount) {\n\t if (!amount && amount !== 0) {\n\t amount = 1;\n\t }\n\t amount %= _this.pattern[0].length;\n\t if (amount < 0) {\n\t amount = _this.pattern[0].length + amount;\n\t }\n\t var cut = _this.pattern[row].splice(_this.pattern[row].length - amount, amount);\n\t _this.pattern[row] = cut.concat(_this.pattern[row]);\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t column: function (column, amount) {\n\t if (!amount && amount !== 0) {\n\t amount = 1;\n\t }\n\t amount %= _this.pattern.length;\n\t if (amount < 0) {\n\t amount = _this.pattern.length + amount;\n\t }\n\t var proxy = [];\n\t _this.pattern.forEach(function (row) {\n\t proxy.push(row[column]);\n\t });\n\t var cut = proxy.splice(proxy.length - amount, amount);\n\t proxy = cut.concat(proxy);\n\t _this.pattern.forEach(function (row, i) {\n\t row[column] = proxy[i];\n\t });\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t }\n\t };\n\t\n\t // the idea behind populate is to be able to set a whole row or column to 0 or 1\n\t // IF the value is a float, such as 0.7, then it would become a probability\n\t // so populate(0.7) would give each cell a 70% chance of being 1\n\t this.populate = {\n\t all: function (odds) {\n\t var oddsSequence = new Sequence(odds);\n\t _this.iterate(function (r, c) {\n\t _this.pattern[r][c] = math.coin(oddsSequence.next());\n\t });\n\t // This could be used so that each row has same odds pattern, even if row length is not divisibly by sequence length.\n\t //,() => {\n\t // odds.pos = -1;\n\t // }\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t row: function () {\n\t var row = arguments[0] === undefined ? 0 : arguments[0];\n\t var odds = arguments[1] === undefined ? 1 : arguments[1];\n\t\n\t var oddsSequence = new Sequence(odds);\n\t _this.pattern[row].forEach(function (cell, i) {\n\t _this.pattern[row][i] = math.coin(oddsSequence.next());\n\t });\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t column: function () {\n\t var column = arguments[0] === undefined ? 0 : arguments[0];\n\t var odds = arguments[1] === undefined ? 1 : arguments[1];\n\t\n\t var oddsSequence = new Sequence(odds);\n\t _this.pattern.forEach(function (row, i) {\n\t _this.pattern[i][column] = math.coin(oddsSequence.next());\n\t });\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t }\n\t };\n\t\n\t // essentiall populate(0) so i'm not sure if this is necessary but is nice\n\t this.erase = {\n\t all: function () {\n\t _this.set.all(0);\n\t },\n\t row: function (row) {\n\t _this.set.row(row, 0);\n\t },\n\t column: function (column) {\n\t _this.set.column(column, 0);\n\t }\n\t };\n\t\n\t // end constructor\n\t }\n\t\n\t _createClass(Matrix, {\n\t create: {\n\t value: function create(rows, columns) {\n\t var _this = this;\n\t\n\t this.pattern = [];\n\t for (var row = 0; row < rows; row++) {\n\t var arr = new Array(columns);\n\t this.pattern.push(arr);\n\t }\n\t this.iterate(function (r, c) {\n\t _this.pattern[r][c] = false;\n\t });\n\t }\n\t },\n\t iterate: {\n\t value: function iterate(f, f2) {\n\t var i = 0;\n\t for (var row = 0; row < this.rows; row++) {\n\t if (f2) {\n\t f2(row);\n\t }\n\t for (var column = 0; column < this.columns; column++) {\n\t f(row, column, i);\n\t i++;\n\t }\n\t }\n\t }\n\t },\n\t formatAsText: {\n\t value: function formatAsText() {\n\t var _this = this;\n\t\n\t var patternString = \"\";\n\t this.iterate(function (r, c) {\n\t patternString += (_this.pattern[r][c] ? 1 : 0) + \" \";\n\t }, function () {\n\t patternString += \"\\n\";\n\t });\n\t return patternString;\n\t }\n\t },\n\t log: {\n\t value: function log() {\n\t console.log(this.formatAsText());\n\t }\n\t },\n\t update: {\n\t value: function update(pattern) {\n\t this.pattern = pattern || this.pattern;\n\t }\n\t },\n\t length: {\n\t get: function () {\n\t return this.rows * this.columns;\n\t }\n\t },\n\t locate: {\n\t value: function locate(index) {\n\t // returns row and column of cell by index\n\t return {\n\t row: ~ ~(index / this.columns),\n\t column: index % this.columns\n\t };\n\t }\n\t },\n\t indexOf: {\n\t value: function indexOf(row, column) {\n\t return column + row * this.columns;\n\t // returns index of cell by row and column\n\t }\n\t },\n\t row: {\n\t value: (function (_row) {\n\t var _rowWrapper = function row(_x) {\n\t return _row.apply(this, arguments);\n\t };\n\t\n\t _rowWrapper.toString = function () {\n\t return _row.toString();\n\t };\n\t\n\t return _rowWrapper;\n\t })(function (row) {\n\t var data = [];\n\t for (var i = 0; i < this.columns; i++) {\n\t data.push(this.pattern[row] ? 1 : 0);\n\t }\n\t return data;\n\t })\n\t },\n\t column: {\n\t value: (function (_column) {\n\t var _columnWrapper = function column(_x2) {\n\t return _column.apply(this, arguments);\n\t };\n\t\n\t _columnWrapper.toString = function () {\n\t return _column.toString();\n\t };\n\t\n\t return _columnWrapper;\n\t })(function (column) {\n\t var data = [];\n\t for (var i = 0; i < this.rows; i++) {\n\t data.push(this.pattern[i][column] ? 1 : 0);\n\t }\n\t return data;\n\t })\n\t },\n\t rows: {\n\t get: function () {\n\t return this.pattern.length;\n\t },\n\t set: function (v) {\n\t var _this = this;\n\t\n\t var previous = this.pattern.slice(0);\n\t this.create(v, this.columns);\n\t this.iterate(function (r, c) {\n\t if (previous[r] && previous[r][c]) {\n\t _this.pattern[r][c] = previous[r][c];\n\t }\n\t });\n\t }\n\t },\n\t columns: {\n\t get: function () {\n\t return this.pattern[0].length;\n\t },\n\t set: function (v) {\n\t var _this = this;\n\t\n\t var previous = this.pattern.slice(0);\n\t this.create(this.rows, v);\n\t this.iterate(function (r, c) {\n\t if (previous[r] && previous[r][c]) {\n\t _this.pattern[r][c] = previous[r][c];\n\t }\n\t });\n\t }\n\t }\n\t });\n\t\n\t return Matrix;\n\t})();\n\t\n\tmodule.exports = Matrix;\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar Drunk = _interopRequire(__webpack_require__(27));\n\t\n\tvar Sequence = (function () {\n\t function Sequence() {\n\t var sequence = arguments[0] === undefined ? [0, 10, 20, 30] : arguments[0];\n\t var mode = arguments[1] === undefined ? \"up\" : arguments[1];\n\t var position = arguments[2] === undefined ? false : arguments[2];\n\t\n\t _classCallCheck(this, Sequence);\n\t\n\t this.values = sequence;\n\t if (!Array.isArray(this.values)) {\n\t this.values = [this.values];\n\t }\n\t this._mode = mode;\n\t this.position = position;\n\t\n\t this.drunkWalk = new Drunk(0, this.values.length - 1);\n\t\n\t this.startValues = {\n\t up: 0,\n\t down: this.values.length - 1,\n\t drunk: ~ ~(this.values.length / 2),\n\t random: math.ri(this.values.length)\n\t };\n\t\n\t if (this.position !== false) {\n\t this.next = this[this._mode];\n\t } else {\n\t this.next = this.first;\n\t }\n\t }\n\t\n\t _createClass(Sequence, {\n\t mode: {\n\t get: function () {\n\t return this._mode;\n\t },\n\t set: function (mode) {\n\t if (!(mode === \"up\" || mode === \"down\" || mode === \"random\" || mode === \"drunk\")) {\n\t console.error(\"The only modes currently allowed are: up, down, random, drunk\");\n\t return;\n\t }\n\t this._mode = mode;\n\t if (this.position) {\n\t this.next = this[this._mode];\n\t }\n\t }\n\t },\n\t value: {\n\t get: function () {\n\t return this.values[this.position];\n\t },\n\t set: function (v) {\n\t this.position = this.values.indexOf(v);\n\t }\n\t },\n\t first: {\n\t value: function first() {\n\t if (this.position !== false) {\n\t this.next = this[this._mode];\n\t return this.next();\n\t }\n\t this.position = this.startValues[this._mode];\n\t this.next = this[this._mode];\n\t return this.value;\n\t }\n\t },\n\t up: {\n\t value: function up() {\n\t this.position++;\n\t this.position %= this.values.length;\n\t return this.value;\n\t }\n\t },\n\t down: {\n\t value: function down() {\n\t this.position--;\n\t if (this.position < 0) {\n\t this.position = (this.position + this.values.length) % this.values.length;\n\t }\n\t return this.value;\n\t }\n\t },\n\t random: {\n\t value: function random() {\n\t this.position = math.ri(0, this.values.length);\n\t return this.value;\n\t }\n\t },\n\t drunk: {\n\t value: function drunk() {\n\t this.drunkWalk.max = this.values.length;\n\t this.drunkWalk.value = this.position;\n\t this.position = this.drunkWalk.next();\n\t return this.value;\n\t }\n\t\n\t /* future methods\r\n\t .group(start,stop) -- outputs a group of n items from the list, with wrapping\r\n\t .loop(start,stop) -- confines sequencing to a subset of the values\r\n\t (could even have a distinction between .originalValues and the array of values being used)\r\n\t */\n\t\n\t }\n\t });\n\t\n\t return Sequence;\n\t})();\n\t\n\tmodule.exports = Sequence;\n\n/***/ }),\n/* 27 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar Drunk = (function () {\n\t function Drunk() {\n\t var min = arguments[0] === undefined ? 0 : arguments[0];\n\t var max = arguments[1] === undefined ? 9 : arguments[1];\n\t var value = arguments[2] === undefined ? 0 : arguments[2];\n\t var increment = arguments[3] === undefined ? 1 : arguments[3];\n\t var loop = arguments[4] === undefined ? false : arguments[4];\n\t\n\t _classCallCheck(this, Drunk);\n\t\n\t this.min = min;\n\t this.max = max;\n\t this.value = value;\n\t this.increment = increment;\n\t this.loop = loop;\n\t }\n\t\n\t _createClass(Drunk, {\n\t next: {\n\t value: function next() {\n\t this.value += math.pick(-1 * this.increment, this.increment);\n\t if (this.value > this.max) {\n\t if (this.loop) {\n\t this.value = this.min;\n\t } else {\n\t this.value = this.max - this.increment;\n\t }\n\t }\n\t\n\t if (this.value < this.min) {\n\t if (this.loop) {\n\t this.value = this.max;\n\t } else {\n\t this.value = this.min + this.increment;\n\t }\n\t }\n\t return this.value;\n\t }\n\t }\n\t });\n\t\n\t return Drunk;\n\t})();\n\t\n\tmodule.exports = Drunk;\n\n/***/ }),\n/* 28 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar Drunk = _interopRequire(__webpack_require__(27));\n\t\n\tvar Counter = (function () {\n\t function Counter() {\n\t var min = arguments[0] === undefined ? 0 : arguments[0];\n\t var max = arguments[1] === undefined ? 10 : arguments[1];\n\t var mode = arguments[2] === undefined ? \"up\" : arguments[2];\n\t var value = arguments[3] === undefined ? false : arguments[3];\n\t\n\t _classCallCheck(this, Counter);\n\t\n\t this.min = min;\n\t this.max = max;\n\t this.value = value;\n\t this.mode = mode;\n\t this.drunkWalk = new Drunk(this.min, this.max);\n\t if (this.value !== false) {\n\t this.next = this[this._mode];\n\t } else {\n\t this.next = this.first;\n\t }\n\t }\n\t\n\t _createClass(Counter, {\n\t mode: {\n\t set: function (mode) {\n\t if (!(mode === \"up\" || mode === \"down\" || mode === \"random\" || mode === \"drunk\")) {\n\t console.error(\"The only modes currently allowed are: up, down, random, drunk\");\n\t return;\n\t }\n\t this._mode = mode;\n\t if (this.value) {\n\t this.next = this[this._mode];\n\t }\n\t },\n\t get: function () {\n\t return this._mode;\n\t }\n\t },\n\t first: {\n\t value: function first() {\n\t if (this.value !== false) {\n\t this.next = this[this._mode];\n\t return this.next();\n\t }\n\t this.startValues = {\n\t up: this.min,\n\t down: this.max,\n\t drunk: ~ ~math.average(this.min, this.max),\n\t random: math.ri(this.min, this.max)\n\t };\n\t this.value = this.startValues[this._mode];\n\t this.next = this[this._mode];\n\t return this.value;\n\t }\n\t },\n\t up: {\n\t value: function up() {\n\t this.value++;\n\t if (this.value >= this.max) {\n\t this.value = this.min;\n\t }\n\t return this.value;\n\t }\n\t },\n\t down: {\n\t value: function down() {\n\t this.value--;\n\t if (this.value < this.min) {\n\t this.value = this.max;\n\t }\n\t return this.value;\n\t }\n\t },\n\t random: {\n\t value: function random() {\n\t this.value = math.ri(this.min, this.max);\n\t return this.value;\n\t }\n\t },\n\t drunk: {\n\t value: function drunk() {\n\t this.drunkWalk.min = this.min;\n\t this.drunkWalk.max = this.max;\n\t this.drunkWalk.value = this.value;\n\t this.value = this.drunkWalk.next();\n\t return this.value;\n\t }\n\t }\n\t });\n\t\n\t return Counter;\n\t})();\n\t\n\tmodule.exports = Counter;\n\n/***/ }),\n/* 29 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar math = __webpack_require__(5);\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\t\n\tvar Interaction = _interopRequireWildcard(__webpack_require__(12));\n\t\n\t/**\n\t* Pan2D\n\t*\n\t* @description Interface for moving a sound around an array of speakers. Speaker locations can be customized. The interface calculates the closeness of the sound source to each speaker and returns that distance as a numeric value.\n\t*\n\t* @demo <span nexus-ui=\"pan2D\"></span>\n\t*\n\t* @example\n\t* var pan2d = new Nexus.Pan2d('#target')\n\t*\n\t* @example\n\t* var pan2d = new Nexus.Pan2D('#target',{\n\t* 'size': [200,200],\n\t* 'range': 0.5, // detection radius of each speaker\n\t* 'mode': 'absolute', // 'absolute' or 'relative' sound movement\n\t* 'speakers': [ // the speaker [x,y] positions\n\t* [0.5,0.2],\n\t* [0.75,0.25],\n\t* [0.8,0.5],\n\t* [0.75,0.75],\n\t* [0.5,0.8],\n\t* [0.25,0.75]\n\t* [0.2,0.5],\n\t* [0.25,0.25]\n\t* ]\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the \"source\" node's position changes. <br>\n\t* The event data is an array of the amplitudes (0-1), representing the level of each speaker (as calculated by its distance to the audio source).\n\t*\n\t* @outputexample\n\t* pan2d.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\tvar Pan2D = (function (_Interface) {\n\t function Pan2D() {\n\t _classCallCheck(this, Pan2D);\n\t\n\t var options = [\"range\"];\n\t\n\t var defaults = {\n\t size: [200, 200],\n\t range: 0.5,\n\t mode: \"absolute\",\n\t speakers: [[0.5, 0.2], [0.75, 0.25], [0.8, 0.5], [0.75, 0.75], [0.5, 0.8], [0.25, 0.75], [0.2, 0.5], [0.25, 0.25]]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Pan2D.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.value = {\n\t x: new Step(0, 1, 0, 0.5),\n\t y: new Step(0, 1, 0, 0.5)\n\t };\n\t\n\t /**\n\t Absolute or relative mouse interaction. In \"absolute\" mode, the source node will jump to your mouse position on mouse click. In \"relative\" mode, it does not.\n\t */\n\t this.mode = this.settings.mode;\n\t\n\t this.position = {\n\t x: new Interaction.Handle(this.mode, \"horizontal\", [0, this.width], [this.height, 0]),\n\t y: new Interaction.Handle(this.mode, \"vertical\", [0, this.width], [this.height, 0])\n\t };\n\t this.position.x.value = this.value.x.normalized;\n\t this.position.y.value = this.value.y.normalized;\n\t\n\t /**\n\t An array of speaker locations. Update this with .moveSpeaker() or .moveAllSpeakers()\n\t */\n\t this.speakers = this.settings.speakers;\n\t\n\t /**\n\t Rewrite: The maximum distance from a speaker that the source node can be for it to be heard from that speaker. A low range (0.1) will result in speakers only playing when the sound is very close it. Default is 0.5 (half of the interface).\n\t */\n\t this.range = this.settings.range;\n\t\n\t /**\n\t The current levels for each speaker. This is calculated when a source node or speaker node is moved through interaction or programatically.\n\t */\n\t this.levels = [];\n\t\n\t this.init();\n\t\n\t this.calculateLevels();\n\t this.render();\n\t }\n\t\n\t _inherits(Pan2D, _Interface);\n\t\n\t _createClass(Pan2D, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.knob = svg.create(\"circle\");\n\t\n\t this.element.appendChild(this.knob);\n\t\n\t // add speakers\n\t this.speakerElements = [];\n\t\n\t for (var i = 0; i < this.speakers.length; i++) {\n\t var speakerElement = svg.create(\"circle\");\n\t\n\t this.element.appendChild(speakerElement);\n\t\n\t this.speakerElements.push(speakerElement);\n\t }\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t this._minDimension = Math.min(this.width, this.height);\n\t\n\t this.knobRadius = {\n\t off: ~ ~(this._minDimension / 100) * 3 + 5 };\n\t this.knobRadius.on = this.knobRadius.off * 2;\n\t\n\t this.knob.setAttribute(\"cx\", this.width / 2);\n\t this.knob.setAttribute(\"cy\", this.height / 2);\n\t this.knob.setAttribute(\"r\", this.knobRadius.off);\n\t\n\t for (var i = 0; i < this.speakers.length; i++) {\n\t var speakerElement = this.speakerElements[i];\n\t var speaker = this.speakers[i];\n\t speakerElement.setAttribute(\"cx\", speaker[0] * this.width);\n\t speakerElement.setAttribute(\"cy\", speaker[1] * this.height);\n\t speakerElement.setAttribute(\"r\", this._minDimension / 20 + 5);\n\t speakerElement.setAttribute(\"fill-opacity\", \"0\");\n\t }\n\t\n\t this.position.x.resize([0, this.width], [this.height, 0]);\n\t this.position.y.resize([0, this.width], [this.height, 0]);\n\t\n\t // next, need to\n\t // resize positions\n\t // calculate speaker distances\n\t this.calculateLevels();\n\t this.render();\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.knob.setAttribute(\"fill\", this.colors.mediumLight);\n\t\n\t for (var i = 0; i < this.speakers.length; i++) {\n\t var speakerElement = this.speakerElements[i];\n\t speakerElement.setAttribute(\"fill\", this.colors.accent);\n\t speakerElement.setAttribute(\"stroke\", this.colors.accent);\n\t }\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t this.knobCoordinates = {\n\t x: this.value.x.normalized * this.width,\n\t y: this.height - this.value.y.normalized * this.height\n\t };\n\t\n\t this.knob.setAttribute(\"cx\", this.knobCoordinates.x);\n\t this.knob.setAttribute(\"cy\", this.knobCoordinates.y);\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.position.x.anchor = this.mouse;\n\t this.position.y.anchor = this.mouse;\n\t this.move();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.clicked) {\n\t this.position.x.update(this.mouse);\n\t this.position.y.update(this.mouse);\n\t // position.x and position.y are normalized\n\t // so are the levels\n\t // likely don't need this.value at all -- only used for drawing\n\t // not going to be a 'step' or 'min' and 'max' in this one.\n\t this.calculateLevels();\n\t this.emit(\"change\", this.levels);\n\t this.render();\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t this.render();\n\t }\n\t },\n\t normalized: {\n\t get: function () {\n\t return {\n\t x: this.value.x.normalized,\n\t y: this.value.y.normalized\n\t };\n\t }\n\t },\n\t calculateLevels: {\n\t value: function calculateLevels() {\n\t var _this = this;\n\t\n\t this.value.x.updateNormal(this.position.x.value);\n\t this.value.y.updateNormal(this.position.y.value);\n\t this.levels = [];\n\t this.speakers.forEach(function (s, i) {\n\t var distance = math.distance(s[0] * _this.width, s[1] * _this.height, _this.position.x.value * _this.width, (1 - _this.position.y.value) * _this.height);\n\t var level = math.clip(1 - distance / (_this.range * _this.width), 0, 1);\n\t _this.levels.push(level);\n\t _this.speakerElements[i].setAttribute(\"fill-opacity\", level);\n\t });\n\t }\n\t },\n\t moveSource: {\n\t\n\t /**\n\t Move the audio source node and trigger the output event.\n\t @param x {number} New x location, normalized 0-1\n\t @param y {number} New y location, normalized 0-1\n\t */\n\t\n\t value: function moveSource(x, y) {\n\t var location = {\n\t x: x * this.width,\n\t y: y * this.height\n\t };\n\t this.position.x.update(location);\n\t this.position.y.update(location);\n\t this.calculateLevels();\n\t this.emit(\"change\", this.levels);\n\t this.render();\n\t }\n\t },\n\t moveSpeaker: {\n\t\n\t /**\n\t Move a speaker node and trigger the output event.\n\t @param index {number} Index of the speaker to move\n\t @param x {number} New x location, normalized 0-1\n\t @param y {number} New y location, normalized 0-1\n\t */\n\t\n\t value: function moveSpeaker(index, x, y) {\n\t\n\t this.speakers[index] = [x, y];\n\t this.speakerElements[index].setAttribute(\"cx\", x * this.width);\n\t this.speakerElements[index].setAttribute(\"cy\", y * this.height);\n\t this.calculateLevels();\n\t this.emit(\"change\", this.levels);\n\t this.render();\n\t }\n\t\n\t /**\n\t Set all speaker locations\n\t @param locations {Array} Array of speaker locations. Each item in the array should be an array of normalized x and y coordinates.\n\t setSpeakers(locations) {\n\t }\n\t */\n\t\n\t }\n\t });\n\t\n\t return Pan2D;\n\t})(Interface);\n\t\n\tmodule.exports = Pan2D;\n\n/***/ }),\n/* 30 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = __webpack_require__(5);\n\tvar svg = __webpack_require__(4);\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\t* Tilt\n\t*\n\t* @description Device tilt sensor with 2 or 3 axes (depending on your device and browser).\n\t*\n\t* @demo <span nexus-ui='tilt'></span>\n\t*\n\t* @example\n\t* var tilt = new Nexus.Tilt('#target')\n\t*\n\t* @output\n\t* change\n\t* Fires at a regular interval, as long as this interface is active (see the interface's <i>.active</i> property)<br>\n\t* The event data is an <i>object</i> containing x (number) and y (number) properties which represent the current tilt state of the device.\n\t*\n\t* @outputexample\n\t* tilt.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Tilt = (function (_Interface) {\n\t function Tilt() {\n\t _classCallCheck(this, Tilt);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [80, 80]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Tilt.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._active = true;\n\t\n\t this.init();\n\t\n\t // add event listener for device orientation\n\t\n\t this.boundUpdate = this.update.bind(this);\n\t //\tthis.boundMozTilt = this.mozTilt.bind(this)\n\t\n\t if (window.DeviceOrientationEvent) {\n\t this.orientationListener = window.addEventListener(\"deviceorientation\", this.boundUpdate, false);\n\t } else {\n\t this._active = false;\n\t this.colorInterface();\n\t }\n\t\n\t /*else if (window.OrientationEvent) {\n\t //\t \twindow.addEventListener('MozOrientation', this.boundMozTilt, false);\n\t } else {\n\t console.log('Not supported on your device or browser.');\n\t } */\n\t }\n\t\n\t _inherits(Tilt, _Interface);\n\t\n\t _createClass(Tilt, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.title = svg.create(\"text\");\n\t this.circleX = svg.create(\"circle\");\n\t this.circleY = svg.create(\"circle\");\n\t this.circleZ = svg.create(\"circle\");\n\t\n\t this.barX = svg.create(\"path\");\n\t this.barY = svg.create(\"path\");\n\t this.barZ = svg.create(\"path\");\n\t\n\t this.barX2 = svg.create(\"path\");\n\t this.barY2 = svg.create(\"path\");\n\t this.barZ2 = svg.create(\"path\");\n\t\n\t this.barX.setAttribute(\"opacity\", \"0.8\");\n\t this.barY.setAttribute(\"opacity\", \"0.8\");\n\t this.barZ.setAttribute(\"opacity\", \"0.8\");\n\t this.barX2.setAttribute(\"opacity\", \"0.8\");\n\t this.barY2.setAttribute(\"opacity\", \"0.8\");\n\t this.barZ2.setAttribute(\"opacity\", \"0.8\");\n\t\n\t this.circleX.setAttribute(\"cx\", this.width * 3 / 12);\n\t this.circleX.setAttribute(\"cy\", this.height * 3 / 4);\n\t this.circleX.setAttribute(\"r\", this.height / 10);\n\t this.circleX.setAttribute(\"opacity\", \"0.4\");\n\t\n\t this.circleY.setAttribute(\"cx\", this.width * 6 / 12);\n\t this.circleY.setAttribute(\"cy\", this.height * 3 / 4);\n\t this.circleY.setAttribute(\"r\", this.height / 10);\n\t this.circleY.setAttribute(\"opacity\", \"0.4\");\n\t\n\t this.circleZ.setAttribute(\"cx\", this.width * 9 / 12);\n\t this.circleZ.setAttribute(\"cy\", this.height * 3 / 4);\n\t this.circleZ.setAttribute(\"r\", this.height / 10);\n\t this.circleZ.setAttribute(\"opacity\", \"0.4\");\n\t\n\t this.barX.setAttribute(\"stroke-width\", Math.round(this.height / 30));\n\t this.barY.setAttribute(\"stroke-width\", Math.round(this.height / 30));\n\t this.barZ.setAttribute(\"stroke-width\", Math.round(this.height / 30));\n\t\n\t this.barX.setAttribute(\"fill\", \"none\");\n\t this.barY.setAttribute(\"fill\", \"none\");\n\t this.barZ.setAttribute(\"fill\", \"none\");\n\t\n\t this.barX2.setAttribute(\"stroke-width\", Math.round(this.height / 30));\n\t this.barY2.setAttribute(\"stroke-width\", Math.round(this.height / 30));\n\t this.barZ2.setAttribute(\"stroke-width\", Math.round(this.height / 30));\n\t\n\t this.barX2.setAttribute(\"fill\", \"none\");\n\t this.barY2.setAttribute(\"fill\", \"none\");\n\t this.barZ2.setAttribute(\"fill\", \"none\");\n\t\n\t this.title.setAttribute(\"x\", this.width / 2);\n\t this.title.setAttribute(\"y\", this.height / 3 + 7);\n\t this.title.setAttribute(\"font-size\", \"15px\");\n\t this.title.setAttribute(\"font-weight\", \"bold\");\n\t this.title.setAttribute(\"letter-spacing\", \"2px\");\n\t this.title.setAttribute(\"opacity\", \"0.7\");\n\t this.title.setAttribute(\"text-anchor\", \"middle\");\n\t this.title.textContent = \"TILT\";\n\t\n\t this.element.appendChild(this.circleX);\n\t this.element.appendChild(this.circleY);\n\t this.element.appendChild(this.circleZ);\n\t\n\t this.element.appendChild(this.barX);\n\t this.element.appendChild(this.barY);\n\t this.element.appendChild(this.barZ);\n\t\n\t this.element.appendChild(this.barX2);\n\t this.element.appendChild(this.barY2);\n\t this.element.appendChild(this.barZ2);\n\t\n\t this.element.appendChild(this.title);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t\n\t if (this._active) {\n\t this.element.style.backgroundColor = this.colors.accent;\n\t this.circleX.setAttribute(\"fill\", this.colors.light);\n\t this.circleY.setAttribute(\"fill\", this.colors.light);\n\t this.circleZ.setAttribute(\"fill\", this.colors.light);\n\t this.circleX.setAttribute(\"stroke\", this.colors.light);\n\t this.circleY.setAttribute(\"stroke\", this.colors.light);\n\t this.circleZ.setAttribute(\"stroke\", this.colors.light);\n\t this.barX.setAttribute(\"stroke\", this.colors.light);\n\t this.barY.setAttribute(\"stroke\", this.colors.light);\n\t this.barZ.setAttribute(\"stroke\", this.colors.light);\n\t this.barX2.setAttribute(\"stroke\", this.colors.light);\n\t this.barY2.setAttribute(\"stroke\", this.colors.light);\n\t this.barZ2.setAttribute(\"stroke\", this.colors.light);\n\t this.title.setAttribute(\"fill\", this.colors.light);\n\t } else {\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.circleX.setAttribute(\"fill\", this.colors.mediumLight);\n\t this.circleY.setAttribute(\"fill\", this.colors.mediumLight);\n\t this.circleZ.setAttribute(\"fill\", this.colors.mediumLight);\n\t this.circleX.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.circleY.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.circleZ.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.barX.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.barY.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.barZ.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.barX2.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.barY2.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.barZ2.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.title.setAttribute(\"fill\", this.colors.mediumLight);\n\t }\n\t }\n\t },\n\t update: {\n\t value: function update(v) {\n\t if (this._active) {\n\t\n\t var y = v.beta;\n\t var x = v.gamma;\n\t var z = v.alpha;\n\t\n\t // take the original -90 to 90 scale and normalize it 0-1\n\t x = math.scale(x, -90, 90, 0, 1);\n\t y = math.scale(y, -90, 90, 0, 1);\n\t z = math.scale(z, 0, 360, 0, 1);\n\t\n\t var handlePoints = {\n\t start: Math.PI * 1.5,\n\t end: math.clip(math.scale(x, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5)\n\t };\n\t var handle2Points = {\n\t start: Math.PI * 2.5,\n\t end: math.clip(math.scale(x, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5)\n\t };\n\t\n\t var handlePath = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value, handlePoints.start, handlePoints.end);\n\t var handle2Path = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value, handle2Points.start, handle2Points.end);\n\t\n\t this.barX.setAttribute(\"d\", handlePath);\n\t this.barX2.setAttribute(\"d\", handle2Path);\n\t\n\t handlePoints = {\n\t start: Math.PI * 1.5,\n\t end: math.clip(math.scale(y, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5)\n\t };\n\t handle2Points = {\n\t start: Math.PI * 2.5,\n\t end: math.clip(math.scale(y, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5)\n\t };\n\t\n\t handlePath = svg.arc(this.circleY.cx.baseVal.value, this.circleY.cy.baseVal.value, this.circleY.r.baseVal.value, handlePoints.start, handlePoints.end);\n\t handle2Path = svg.arc(this.circleY.cx.baseVal.value, this.circleY.cy.baseVal.value, this.circleY.r.baseVal.value, handle2Points.start, handle2Points.end);\n\t\n\t this.barY.setAttribute(\"d\", handlePath);\n\t this.barY2.setAttribute(\"d\", handle2Path);\n\t\n\t handlePoints = {\n\t start: Math.PI * 1.5,\n\t end: math.clip(math.scale(z, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5)\n\t };\n\t handle2Points = {\n\t start: Math.PI * 2.5,\n\t end: math.clip(math.scale(z, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5)\n\t };\n\t\n\t handlePath = svg.arc(this.circleZ.cx.baseVal.value, this.circleZ.cy.baseVal.value, this.circleZ.r.baseVal.value, handlePoints.start, handlePoints.end);\n\t handle2Path = svg.arc(this.circleZ.cx.baseVal.value, this.circleZ.cy.baseVal.value, this.circleZ.r.baseVal.value, handle2Points.start, handle2Points.end);\n\t\n\t this.barZ.setAttribute(\"d\", handlePath);\n\t this.barZ2.setAttribute(\"d\", handle2Path);\n\t\n\t /*\n\t let pointsX = {\n\t start: 0,\n\t end: math.scale( x, 0, 1, 0, Math.PI*2 )\n\t };\n\t // console.log(this.circleX.cx.baseVal.value);\n\t let pathX = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value*2, pointsX.start, pointsX.end);\n\t this.barX.setAttribute('d',pathX); */\n\t\n\t //this.textH.textContent = math.prune(x,2);\n\t //this.textV.textContent = math.prune(y,2);\n\t //\n\t // this.circleX.setAttribute('opacity',x);\n\t // this.circleY.setAttribute('opacity',y);\n\t // this.circleZ.setAttribute('opacity',z);\n\t\n\t this.emit(\"change\", {\n\t x: x,\n\t y: y,\n\t z: z\n\t });\n\t }\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t if (window.DeviceOrientationEvent) {\n\t this.active = !this.active;\n\t }\n\t }\n\t },\n\t active: {\n\t\n\t /**\n\t Whether the interface is on (emitting values) or off (paused & not emitting values). Setting this property will update it.\n\t @type {boolean}\n\t */\n\t\n\t get: function () {\n\t return this._active;\n\t },\n\t set: function (on) {\n\t this._active = on;\n\t this.colorInterface();\n\t }\n\t },\n\t customDestroy: {\n\t value: function customDestroy() {\n\t window.removeEventListener(\"deviceorientation\", this.boundUpdate, false);\n\t }\n\t }\n\t });\n\t\n\t return Tilt;\n\t})(Interface);\n\t\n\tmodule.exports = Tilt;\n\n/***/ }),\n/* 31 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar dom = __webpack_require__(7);\n\tvar math = __webpack_require__(5);\n\tvar Interface = __webpack_require__(6);\n\tvar SliderTemplate = __webpack_require__(32);\n\tvar touch = __webpack_require__(9);\n\t\n\tvar SingleSlider = (function (_SliderTemplate) {\n\t function SingleSlider() {\n\t var _this = this;\n\t\n\t _classCallCheck(this, SingleSlider);\n\t\n\t var options = [\"scale\", \"value\"];\n\t\n\t var defaults = {\n\t size: [120, 20],\n\t orientation: \"vertical\",\n\t mode: \"absolute\",\n\t scale: [0, 1],\n\t step: 0,\n\t value: 0,\n\t hasKnob: true\n\t };\n\t\n\t _get(Object.getPrototypeOf(SingleSlider.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t /* events */\n\t\n\t if (!touch.exists) {\n\t\n\t this.click = function () {\n\t _this.multislider.interacting = true;\n\t _this.multislider.interpolation = {\n\t index: _this.index,\n\t value: _this.value\n\t };\n\t _this.down();\n\t _this.multislider.values[_this.index] = _this.value;\n\t };\n\t this.element.addEventListener(\"mouseover\", function (e) {\n\t if (_this.multislider.interacting) {\n\t if (!_this.offset) {\n\t _this.offset = dom.findPosition(_this.element);\n\t }\n\t _this.mouse = dom.locateMouse(e, _this.offset);\n\t _this.down();\n\t _this.multislider.values[_this.index] = _this.value;\n\t if (_this.multislider.interpolation) {\n\t var distance = Math.abs(_this.multislider.interpolation.index - _this.index);\n\t if (distance > 1) {\n\t var low = Math.min(_this.multislider.interpolation.index, _this.index);\n\t var high = Math.max(_this.multislider.interpolation.index, _this.index);\n\t var lowValue = _this.multislider.sliders[low].value;\n\t var highValue = _this.multislider.sliders[high].value;\n\t for (var i = low; i < high; i++) {\n\t _this.multislider.sliders[i].value = math.interp((i - low) / distance, lowValue, highValue);\n\t var smoothedValue = _this.multislider.sliders[i].value;\n\t _this.multislider.values[i] = smoothedValue;\n\t _this.multislider.update(i, smoothedValue);\n\t }\n\t }\n\t }\n\t\n\t _this.multislider.interpolation = {\n\t index: _this.index,\n\t value: _this.value\n\t };\n\t }\n\t });\n\t\n\t this.move = function () {};\n\t this.element.addEventListener(\"mousemove\", function (e) {\n\t if (_this.multislider.interacting) {\n\t if (!_this.offset) {\n\t _this.offset = dom.findPosition(_this.element);\n\t }\n\t _this.mouse = dom.locateMouse(e, _this.offset);\n\t _this.slide();\n\t _this.multislider.values[_this.index] = _this.value;\n\t }\n\t });\n\t\n\t this.release = function () {\n\t _this.multislider.interacting = false;\n\t _this.multislider.interpolation = false;\n\t };\n\t this.element.addEventListener(\"mouseup\", function () {\n\t if (_this.multislider.interacting) {\n\t _this.up();\n\t _this.multislider.interpolation = false;\n\t _this.multislider.values[_this.index] = _this.value;\n\t }\n\t });\n\t this.element.addEventListener(\"mouseout\", function () {\n\t if (_this.multislider.interacting) {\n\t _this.up();\n\t _this.multislider.values[_this.index] = _this.value;\n\t }\n\t });\n\t }\n\t\n\t this.customStyle();\n\t }\n\t\n\t _inherits(SingleSlider, _SliderTemplate);\n\t\n\t _createClass(SingleSlider, {\n\t customStyle: {\n\t value: function customStyle() {\n\t\n\t /* style changes */\n\t\n\t this.bar.setAttribute(\"x\", 0);\n\t this.bar.setAttribute(\"transform\", \"translate(0,0)\");\n\t this.bar.setAttribute(\"rx\", 0); // corner radius\n\t this.bar.setAttribute(\"ry\", 0);\n\t this.bar.setAttribute(\"width\", this.width);\n\t this.bar.setAttribute(\"height\", this.height);\n\t\n\t this.fillbar.setAttribute(\"x\", 0);\n\t this.fillbar.setAttribute(\"transform\", \"translate(0,0)\");\n\t this.fillbar.setAttribute(\"rx\", 0); // corner radius\n\t this.fillbar.setAttribute(\"ry\", 0);\n\t this.fillbar.setAttribute(\"width\", this.width);\n\t this.fillbar.setAttribute(\"height\", this.height);\n\t }\n\t }\n\t });\n\t\n\t return SingleSlider;\n\t})(SliderTemplate);\n\t\n\t/**\n\t* Multislider\n\t*\n\t* @description Multislider\n\t*\n\t* @demo <span nexus-ui=\"multislider\"></span>\n\t*\n\t* @example\n\t* var multislider = new Nexus.Multislider('#target')\n\t*\n\t* @example\n\t* var multislider = new Nexus.Multislider('#target',{\n\t* 'size': [200,100],\n\t* 'numberOfSliders': 5,\n\t* 'min': 0,\n\t* 'max': 1,\n\t* 'step': 0,\n\t* 'values': [0.7,0.7,0.7,0.7,0.7]\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data an object containing <i>index</i> and <i>value</i> properties\n\t*\n\t* @outputexample\n\t* multislider.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\t/*\n\tProperties\n\t.values\n\t\n\t*/\n\t\n\tvar Multislider = (function (_Interface) {\n\t function Multislider() {\n\t _classCallCheck(this, Multislider);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [200, 100],\n\t numberOfSliders: 5,\n\t min: 0,\n\t max: 1,\n\t step: 0,\n\t values: [0.7, 0.7, 0.7, 0.7, 0.7]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Multislider.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._numberOfSliders = this.settings.numberOfSliders;\n\t this.values = this.settings.values;\n\t\n\t this.sliders = [];\n\t\n\t this.interacting = false;\n\t\n\t this.init();\n\t }\n\t\n\t _inherits(Multislider, _Interface);\n\t\n\t _createClass(Multislider, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = document.createElement(\"div\");\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t var min = this.settings.min;\n\t var max = this.settings.max;\n\t var step = this.settings.step;\n\t\n\t if (this.sliders.length) {\n\t min = this.sliders[0].min;\n\t max = this.sliders[0].max;\n\t step = this.sliders[0].step;\n\t }\n\t\n\t this.sliders = [];\n\t\n\t for (var i = 0; i < this._numberOfSliders; i++) {\n\t var container = document.createElement(\"span\");\n\t\n\t var slider = new SingleSlider(container, {\n\t scale: [min, max],\n\t step: step,\n\t mode: \"absolute\",\n\t orientation: \"vertical\",\n\t value: this.values[i],\n\t hasKnob: false,\n\t component: true }, this.update.bind(this, i));\n\t slider.multislider = this;\n\t\n\t slider.index = i;\n\t if (touch.exists) {\n\t slider.bar.index = i;\n\t slider.fillbar.index = i;\n\t slider.preClick = slider.preMove = slider.preRelease = function () {};\n\t slider.click = slider.move = slider.release = function () {};\n\t slider.preTouch = slider.preTouchMove = slider.preTouchRelease = function () {};\n\t slider.touch = slider.touchMove = slider.touchRelease = function () {};\n\t }\n\t\n\t this.sliders.push(slider);\n\t this.element.appendChild(container);\n\t }\n\t if (touch.exists) {\n\t this.addTouchListeners();\n\t }\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t for (var i = 0; i < this.sliders.length; i++) {\n\t this.sliders[i].colors = this.colors;\n\t this.sliders[i].colorInterface();\n\t }\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t var sliderWidth = this.width / this.sliders.length;\n\t var sliderHeight = this.height;\n\t\n\t for (var i = 0; i < this.sliders.length; i++) {\n\t this.sliders[i].resize(sliderWidth, sliderHeight);\n\t this.sliders[i].customStyle();\n\t }\n\t }\n\t },\n\t update: {\n\t value: function update(index, value) {\n\t this.emit(\"change\", {\n\t index: index,\n\t value: value\n\t });\n\t }\n\t },\n\t addTouchListeners: {\n\t value: function addTouchListeners() {\n\t var _this = this;\n\t\n\t this.preClick = this.preMove = this.preRelease = function () {};\n\t this.click = this.move = this.release = function () {};\n\t this.preTouch = this.preTouchMove = this.preTouchRelease = function () {};\n\t this.touch = this.touchMove = this.touchRelease = function () {};\n\t\n\t this.currentElement = false;\n\t\n\t this.element.addEventListener(\"touchstart\", function (e) {\n\t var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);\n\t var slider = _this.sliders[element.index];\n\t if (!slider.offset) {\n\t slider.offset = dom.findPosition(slider.element);\n\t }\n\t slider.mouse = dom.locateMouse(e, slider.offset);\n\t slider.down();\n\t _this.currentElement = element.index;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t\n\t this.element.addEventListener(\"touchmove\", function (e) {\n\t var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);\n\t var slider = _this.sliders[element.index];\n\t if (!slider.offset) {\n\t slider.offset = dom.findPosition(slider.element);\n\t }\n\t slider.mouse = dom.locateMouse(e, slider.offset);\n\t if (element.index !== _this.currentElement) {\n\t if (_this.currentElement >= 0) {\n\t var pastslider = _this.sliders[_this.currentElement];\n\t pastslider.up();\n\t }\n\t slider.down();\n\t } else {\n\t slider.slide();\n\t }\n\t _this.currentElement = element.index;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t\n\t this.element.addEventListener(\"touchend\", function (e) {\n\t // no touches to calculate because none remaining\n\t var slider = _this.sliders[_this.currentElement];\n\t slider.up();\n\t _this.interacting = false;\n\t _this.currentElement = false;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t }\n\t },\n\t numberOfSliders: {\n\t\n\t /**\n\t Get or set the number of sliders\n\t @type {Number}\n\t */\n\t\n\t get: function () {\n\t return this.sliders.length;\n\t },\n\t set: function (v) {\n\t if (v === this.sliders.length) {\n\t return;\n\t }\n\t this.sliders.forEach(function (slider) {\n\t slider.destroy();\n\t });\n\t this.empty();\n\t this._numberOfSliders = v;\n\t this.buildInterface();\n\t }\n\t },\n\t min: {\n\t\n\t /**\n\t Lower limit of the multislider's output range\n\t @type {number}\n\t @example multislider.min = 1000;\n\t */\n\t\n\t get: function () {\n\t return this.sliders[0].min;\n\t },\n\t set: function (v) {\n\t this.sliders.forEach(function (slider) {\n\t slider.min = v;\n\t });\n\t }\n\t },\n\t max: {\n\t\n\t /**\n\t Upper limit of the multislider's output range\n\t @type {number}\n\t @example multislider.max = 1000;\n\t */\n\t\n\t get: function () {\n\t return this.sliders[0].max;\n\t },\n\t set: function (v) {\n\t this.sliders.forEach(function (slider) {\n\t slider.max = v;\n\t });\n\t }\n\t },\n\t step: {\n\t\n\t /**\n\t The increment that the multislider's value changes by.\n\t @type {number}\n\t @example multislider.step = 5;\n\t */\n\t\n\t get: function () {\n\t return this.sliders[0].step;\n\t },\n\t set: function (v) {\n\t this.sliders.forEach(function (slider) {\n\t slider.step = v;\n\t });\n\t }\n\t },\n\t setSlider: {\n\t\n\t /**\n\t Set the value of an individual slider\n\t @param index {number} Slider index\n\t @param value {number} New slider value\n\t @example\n\t // Set the first slider to value 0.5\n\t multislider.setSlider(0,0.5)\n\t */\n\t\n\t value: function setSlider(index, value) {\n\t this.sliders[index].value = value;\n\t this.emit(\"change\", {\n\t index: index,\n\t value: value\n\t });\n\t }\n\t },\n\t setAllSliders: {\n\t\n\t /**\n\t Set the value of all sliders at once. If the size of the input array does not match the current number of sliders, the value array will repeat until all sliders have been set. I.e. an input array of length 1 will set all sliders to that value.\n\t @param values {Array} All slider values\n\t @example\n\t multislider.setAllSliders([0.2,0.3,0.4,0.5,0.6])\n\t */\n\t\n\t value: function setAllSliders(values) {\n\t var _this = this;\n\t\n\t this.values = values;\n\t this.sliders.forEach(function (slider, i) {\n\t slider.value = values[i % values.length];\n\t _this.emit(\"change\", {\n\t index: i,\n\t value: slider.value\n\t });\n\t });\n\t }\n\t }\n\t });\n\t\n\t return Multislider;\n\t})(Interface);\n\t\n\tmodule.exports = Multislider;\n\n/***/ }),\n/* 32 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\t\n\tvar Interaction = _interopRequireWildcard(__webpack_require__(12));\n\t\n\tvar SliderTemplate = (function (_Interface) {\n\t function SliderTemplate(args, options, defaults) {\n\t _classCallCheck(this, SliderTemplate);\n\t\n\t _get(Object.getPrototypeOf(SliderTemplate.prototype), \"constructor\", this).call(this, args, options, defaults);\n\t\n\t this.orientation = this.settings.orientation;\n\t\n\t // this.mode = this.settings.mode;\n\t\n\t this.hasKnob = this.settings.hasKnob;\n\t\n\t // this.step should eventually be get/set\n\t // updating it will update the _value step model\n\t // this.step = this.settings.step; // float\n\t\n\t this._value = new Step(this.settings.scale[0], this.settings.scale[1], this.settings.step, this.settings.value);\n\t\n\t this.init();\n\t\n\t this.position = new Interaction.Handle(this.settings.mode, this.orientation, [0, this.width], [this.height, 0]);\n\t this.position.value = this._value.normalized;\n\t\n\t this.value = this._value.value;\n\t\n\t this.emit(\"change\", this.value);\n\t }\n\t\n\t _inherits(SliderTemplate, _Interface);\n\t\n\t _createClass(SliderTemplate, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.bar = svg.create(\"rect\");\n\t this.fillbar = svg.create(\"rect\");\n\t this.knob = svg.create(\"circle\");\n\t\n\t this.element.appendChild(this.bar);\n\t this.element.appendChild(this.fillbar);\n\t this.element.appendChild(this.knob);\n\t\n\t this.sizeInterface();\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t if (!this.settings.orientation) {\n\t if (this.width < this.height) {\n\t this.orientation = \"vertical\";\n\t } else {\n\t this.orientation = \"horizontal\";\n\t }\n\t }\n\t\n\t var x = undefined,\n\t y = undefined,\n\t w = undefined,\n\t h = undefined,\n\t barOffset = undefined,\n\t cornerRadius = undefined;\n\t this.knobData = {\n\t level: 0,\n\t r: 0\n\t };\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.thickness = this.width / 2;\n\t x = this.width / 2;\n\t y = 0;\n\t w = this.thickness;\n\t h = this.height;\n\t this.knobData.r = this.thickness * 0.8;\n\t this.knobData.level = h - this.normalized * h;\n\t barOffset = \"translate(\" + this.thickness * -1 / 2 + \",0)\";\n\t cornerRadius = w / 2;\n\t } else {\n\t this.thickness = this.height / 2;\n\t x = 0;\n\t y = this.height / 2;\n\t w = this.width;\n\t h = this.thickness;\n\t this.knobData.r = this.thickness * 0.8;\n\t this.knobData.level = this.normalized * w;\n\t barOffset = \"translate(0,\" + this.thickness * -1 / 2 + \")\";\n\t cornerRadius = h / 2;\n\t }\n\t\n\t this.bar.setAttribute(\"x\", x);\n\t this.bar.setAttribute(\"y\", y);\n\t this.bar.setAttribute(\"transform\", barOffset);\n\t this.bar.setAttribute(\"rx\", cornerRadius); // corner radius\n\t this.bar.setAttribute(\"ry\", cornerRadius);\n\t this.bar.setAttribute(\"width\", w);\n\t this.bar.setAttribute(\"height\", h);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.fillbar.setAttribute(\"x\", x);\n\t this.fillbar.setAttribute(\"y\", this.knobData.level);\n\t this.fillbar.setAttribute(\"width\", w);\n\t this.fillbar.setAttribute(\"height\", h - this.knobData.level);\n\t } else {\n\t this.fillbar.setAttribute(\"x\", 0);\n\t this.fillbar.setAttribute(\"y\", y);\n\t this.fillbar.setAttribute(\"width\", this.knobData.level);\n\t this.fillbar.setAttribute(\"height\", h);\n\t }\n\t this.fillbar.setAttribute(\"transform\", barOffset);\n\t this.fillbar.setAttribute(\"rx\", cornerRadius);\n\t this.fillbar.setAttribute(\"ry\", cornerRadius);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.knob.setAttribute(\"cx\", x);\n\t this.knob.setAttribute(\"cy\", this.knobData.level);\n\t } else {\n\t this.knob.setAttribute(\"cx\", this.knobData.level);\n\t this.knob.setAttribute(\"cy\", y);\n\t }\n\t this.knob.setAttribute(\"r\", this.knobData.r);\n\t\n\t if (this.position) {\n\t this.position.resize([0, this.width], [this.height, 0]);\n\t }\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t\n\t this.bar.setAttribute(\"fill\", this.colors.fill);\n\t this.fillbar.setAttribute(\"fill\", this.colors.accent);\n\t this.knob.setAttribute(\"fill\", this.colors.accent);\n\t if (!this.hasKnob) {\n\t this.knob.setAttribute(\"fill\", \"none\");\n\t }\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.clicked) {\n\t this.knobData.r = this.thickness * 0.75;\n\t }\n\t this.knob.setAttribute(\"r\", this.knobData.r);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.knobData.level = this._value.normalized * this.height;\n\t this.knob.setAttribute(\"cy\", this.height - this.knobData.level);\n\t this.fillbar.setAttribute(\"y\", this.height - this.knobData.level);\n\t this.fillbar.setAttribute(\"height\", this.knobData.level);\n\t } else {\n\t this.knobData.level = this._value.normalized * this.width;\n\t this.knob.setAttribute(\"cx\", this.knobData.level);\n\t this.fillbar.setAttribute(\"x\", 0);\n\t this.fillbar.setAttribute(\"width\", this.knobData.level);\n\t }\n\t }\n\t },\n\t down: {\n\t value: function down() {\n\t this.clicked = true;\n\t this.knobData.r = this.thickness * 0.9;\n\t this.position.anchor = this.mouse;\n\t this.slide();\n\t }\n\t },\n\t slide: {\n\t value: function slide() {\n\t if (this.clicked) {\n\t this.position.update(this.mouse);\n\t this.value = this._value.updateNormal(this.position.value);\n\t this.emit(\"change\", this.value);\n\t }\n\t }\n\t },\n\t up: {\n\t value: function up() {\n\t this.clicked = false;\n\t this.render();\n\t }\n\t },\n\t normalized: {\n\t get: function () {\n\t return this._value.normalized;\n\t }\n\t },\n\t value: {\n\t\n\t /**\n\t The slider's current value. If set manually, will update the interface and trigger the output event.\n\t @type {number}\n\t @example slider.value = 10;\n\t */\n\t\n\t get: function () {\n\t return this._value.value;\n\t },\n\t set: function (v) {\n\t this._value.update(v);\n\t this.position.value = this._value.normalized;\n\t this.render();\n\t }\n\t },\n\t min: {\n\t\n\t /**\n\t Lower limit of the sliders's output range\n\t @type {number}\n\t @example slider.min = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.min;\n\t },\n\t set: function (v) {\n\t this._value.min = v;\n\t }\n\t },\n\t max: {\n\t\n\t /**\n\t Upper limit of the slider's output range\n\t @type {number}\n\t @example slider.max = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.max;\n\t },\n\t set: function (v) {\n\t this._value.max = v;\n\t }\n\t },\n\t step: {\n\t\n\t /**\n\t The increment that the slider's value changes by.\n\t @type {number}\n\t @example slider.step = 5;\n\t */\n\t\n\t get: function () {\n\t return this._value.step;\n\t },\n\t set: function (v) {\n\t this._value.step = v;\n\t }\n\t },\n\t mode: {\n\t\n\t /**\n\t Absolute mode (slider's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: \"relative\".\n\t @type {string}\n\t @example slider.mode = \"relative\";\n\t */\n\t\n\t get: function () {\n\t return this.position.mode;\n\t },\n\t set: function (v) {\n\t this.position.mode = v;\n\t }\n\t }\n\t });\n\t\n\t return SliderTemplate;\n\t})(Interface);\n\t\n\tmodule.exports = SliderTemplate;\n\n/***/ }),\n/* 33 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar math = __webpack_require__(5);\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\t\n\tvar Interaction = _interopRequireWildcard(__webpack_require__(12));\n\t\n\t/**\n\t* Pan\n\t*\n\t* @description Stereo crossfader.\n\t*\n\t* @demo <span nexus-ui=\"pan\"></span>\n\t*\n\t* @example\n\t* var pan = new Nexus.Pan('#target')\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data is an object containing the interface's <i>value</i> (-1 to 1), as well as <i>L</i> and <i>R</i> amplitude values (0-1) for left and right speakers, calculated by a square-root crossfade algorithm.\n\t*\n\t* @outputexample\n\t* pan.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Pan = (function (_Interface) {\n\t function Pan() {\n\t _classCallCheck(this, Pan);\n\t\n\t var options = [\"scale\", \"value\"];\n\t\n\t var defaults = {\n\t size: [120, 20],\n\t orientation: \"horizontal\",\n\t mode: \"relative\",\n\t scale: [-1, 1],\n\t step: 0,\n\t value: 0,\n\t hasKnob: true\n\t };\n\t\n\t _get(Object.getPrototypeOf(Pan.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.orientation = this.settings.orientation;\n\t\n\t this.mode = this.settings.mode;\n\t\n\t this.hasKnob = this.settings.hasKnob;\n\t\n\t // this.step should eventually be get/set\n\t // updating it will update the _value step model\n\t this.step = this.settings.step; // float\n\t\n\t this._value = new Step(this.settings.scale[0], this.settings.scale[1], this.settings.step, this.settings.value);\n\t\n\t this.init();\n\t\n\t this.position = new Interaction.Handle(this.mode, this.orientation, [0, this.width], [this.height, 0]);\n\t this.position.value = this._value.normalized;\n\t\n\t this.value = this._value.value;\n\t\n\t this.emit(\"change\", this.value);\n\t }\n\t\n\t _inherits(Pan, _Interface);\n\t\n\t _createClass(Pan, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.bar = svg.create(\"rect\");\n\t this.knob = svg.create(\"circle\");\n\t\n\t this.element.appendChild(this.bar);\n\t this.element.appendChild(this.knob);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t if (this.position) {\n\t this.position.resize([0, this.width], [this.height, 0]);\n\t }\n\t\n\t if (this.width < this.height) {\n\t this.orientation = \"vertical\";\n\t } else {\n\t this.orientation = \"horizontal\";\n\t }\n\t\n\t var x = undefined,\n\t y = undefined,\n\t w = undefined,\n\t h = undefined,\n\t barOffset = undefined,\n\t cornerRadius = undefined;\n\t this.knobData = {\n\t level: 0,\n\t r: 0\n\t };\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.thickness = this.width / 2;\n\t x = this.width / 2;\n\t y = 0;\n\t w = this.thickness;\n\t h = this.height;\n\t this.knobData.r = this.thickness * 0.8;\n\t this.knobData.level = h - this.knobData.r - this.normalized * (h - this.knobData.r * 2);\n\t barOffset = \"translate(\" + this.thickness * -1 / 2 + \",0)\";\n\t cornerRadius = w / 2;\n\t } else {\n\t this.thickness = this.height / 2;\n\t x = 0;\n\t y = this.height / 2;\n\t w = this.width;\n\t h = this.thickness;\n\t this.knobData.r = this.thickness * 0.8;\n\t this.knobData.level = this.normalized * (w - this.knobData.r * 2) + this.knobData.r;\n\t barOffset = \"translate(0,\" + this.thickness * -1 / 2 + \")\";\n\t cornerRadius = h / 2;\n\t }\n\t\n\t this.bar.setAttribute(\"x\", x);\n\t this.bar.setAttribute(\"y\", y);\n\t this.bar.setAttribute(\"transform\", barOffset);\n\t this.bar.setAttribute(\"rx\", cornerRadius); // corner radius\n\t this.bar.setAttribute(\"ry\", cornerRadius);\n\t this.bar.setAttribute(\"width\", w);\n\t this.bar.setAttribute(\"height\", h);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.knob.setAttribute(\"cx\", x);\n\t this.knob.setAttribute(\"cy\", this.knobData.level);\n\t } else {\n\t this.knob.setAttribute(\"cx\", this.knobData.level);\n\t this.knob.setAttribute(\"cy\", y);\n\t }\n\t this.knob.setAttribute(\"r\", this.knobData.r);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t\n\t this.bar.setAttribute(\"fill\", this.colors.fill);\n\t this.knob.setAttribute(\"fill\", this.colors.accent);\n\t\n\t if (!this.hasKnob) {\n\t this.knob.setAttribute(\"fill\", \"transparent\");\n\t }\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.clicked) {\n\t this.knobData.r = this.thickness * 0.75;\n\t }\n\t this.knob.setAttribute(\"r\", this.knobData.r);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.knobData.level = this.knobData.r + this._value.normalized * (this.height - this.knobData.r * 2);\n\t this.knob.setAttribute(\"cy\", this.height - this.knobData.level);\n\t } else {\n\t this.knobData.level = this._value.normalized * (this.width - this.knobData.r * 2) + this.knobData.r;\n\t this.knob.setAttribute(\"cx\", this.knobData.level);\n\t }\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.knobData.r = this.thickness * 0.9;\n\t this.position.anchor = this.mouse;\n\t this.move();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.clicked) {\n\t this.position.update(this.mouse);\n\t\n\t this.value = this._value.updateNormal(this.position.value);\n\t\n\t this.emit(\"change\", {\n\t value: this.value,\n\t L: Math.pow(math.scale(this.value, -1, 1, 1, 0), 2),\n\t R: Math.pow(math.scale(this.value, -1, 1, 0, 1), 2)\n\t });\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t this.render();\n\t }\n\t },\n\t value: {\n\t\n\t /**\n\t The position of crossfader, from -1 (left) to 1 (right). Setting this value updates the interface and triggers the output event.\n\t @type {number}\n\t */\n\t\n\t get: function () {\n\t return this._value.value;\n\t },\n\t set: function (value) {\n\t this._value.update(value);\n\t this.position.value = this._value.normalized;\n\t this.emit(\"change\", {\n\t value: this.value,\n\t L: Math.pow(math.scale(this.value, -1, 1, 1, 0), 2),\n\t R: Math.pow(math.scale(this.value, -1, 1, 0, 1), 2)\n\t });\n\t this.render();\n\t }\n\t },\n\t normalized: {\n\t get: function () {\n\t return this._value.normalized;\n\t }\n\t }\n\t });\n\t\n\t return Pan;\n\t})(Interface);\n\t\n\tmodule.exports = Pan;\n\n/***/ }),\n/* 34 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = __webpack_require__(5);\n\tvar svg = __webpack_require__(4);\n\tvar Interface = __webpack_require__(6);\n\t\n\tvar Point = function Point(point, envelope) {\n\t\n\t this.x = point.x;\n\t this.y = point.y;\n\t this.envelope = envelope;\n\t\n\t this.element = svg.create(\"circle\");\n\t this.element.setAttribute(\"fill\", this.envelope.colors.accent);\n\t\n\t this.envelope.element.appendChild(this.element);\n\t\n\t this.resize = function () {\n\t var r = ~ ~(Math.min(this.envelope.width, this.envelope.height) / 50) + 2;\n\t this.element.setAttribute(\"r\", r);\n\t };\n\t\n\t this.move = function (x, y) {\n\t\n\t this.x = x || x === 0 ? x : this.x;\n\t this.y = y || y === 0 ? y : this.y;\n\t\n\t if (this.envelope.nodes.indexOf(this) >= 0) {\n\t\n\t var prevIndex = this.envelope.nodes.indexOf(this) - 1;\n\t var nextIndex = this.envelope.nodes.indexOf(this) + 1;\n\t\n\t var prevNode = this.envelope.nodes[prevIndex];\n\t var nextNode = this.envelope.nodes[nextIndex];\n\t\n\t var lowX = prevIndex >= 0 ? prevNode.x : 0;\n\t var highX = nextIndex < this.envelope.nodes.length ? nextNode.x : 1;\n\t\n\t if (this.x < lowX) {\n\t this.x = lowX;\n\t }\n\t if (this.x > highX) {\n\t this.x = highX;\n\t }\n\t }\n\t\n\t this.location = this.getCoordinates();\n\t this.element.setAttribute(\"cx\", this.location.x);\n\t this.element.setAttribute(\"cy\", this.location.y);\n\t };\n\t\n\t this.getCoordinates = function () {\n\t return {\n\t x: this.x * this.envelope.width,\n\t y: (1 - this.y) * this.envelope.height\n\t };\n\t };\n\t\n\t this.move(this.x, this.y, true);\n\t this.resize();\n\t\n\t this.destroy = function () {\n\t this.envelope.element.removeChild(this.element);\n\t this.envelope.nodes.splice(this.envelope.nodes.indexOf(this), 1);\n\t };\n\t};\n\t\n\t/**\n\t* Envelope\n\t*\n\t* @description Interactive linear ramp visualization.\n\t*\n\t* @demo <span nexus-ui=\"envelope\"></span>\n\t*\n\t* @example\n\t* var envelope = new Nexus.Envelope('#target')\n\t*\n\t* @example\n\t* var envelope = new Nexus.Envelope('#target',{\n\t* 'size': [300,150],\n\t* 'points': [\n\t* {\n\t* x: 0.1,\n\t* y: 0.4\n\t* },\n\t* {\n\t* x: 0.35,\n\t* y: 0.6\n\t* },\n\t* {\n\t* x: 0.65,\n\t* y: 0.2\n\t* },\n\t* {\n\t* x: 0.9,\n\t* y: 0.4\n\t* },\n\t* ]\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time a node is moved. <br>\n\t* The event data is an array of point locations. Each item in the array is an object containing <i>x</i> and <i>y</i> properties describing the location of a point on the envelope.\n\t*\n\t* @outputexample\n\t* envelope.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\tvar Envelope = (function (_Interface) {\n\t function Envelope() {\n\t _classCallCheck(this, Envelope);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [300, 150],\n\t points: [{\n\t x: 0.1,\n\t y: 0.4\n\t }, {\n\t x: 0.35,\n\t y: 0.6\n\t }, {\n\t x: 0.65,\n\t y: 0.2\n\t }, {\n\t x: 0.9,\n\t y: 0.4\n\t }]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Envelope.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.points = this.settings.points;\n\t\n\t this.nodes = [];\n\t\n\t this.selected = false;\n\t\n\t this.init();\n\t }\n\t\n\t _inherits(Envelope, _Interface);\n\t\n\t _createClass(Envelope, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t var _this = this;\n\t\n\t this.points.forEach(function (point) {\n\t var node = new Point(point, _this);\n\t _this.nodes.push(node);\n\t });\n\t\n\t this.sortPoints();\n\t\n\t this.line = svg.create(\"polyline\");\n\t this.line.setAttribute(\"stroke-width\", 2);\n\t this.line.setAttribute(\"fill\", \"none\");\n\t\n\t this.element.appendChild(this.line);\n\t\n\t this.fill = svg.create(\"polyline\");\n\t this.fill.setAttribute(\"fill-opacity\", \"0.2\");\n\t\n\t this.element.appendChild(this.fill);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t for (var i = 0; i < this.nodes.length; i++) {\n\t this.nodes[i].resize();\n\t this.nodes[i].move();\n\t }\n\t\n\t this.render();\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t var _this = this;\n\t\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.line.setAttribute(\"stroke\", this.colors.accent);\n\t this.fill.setAttribute(\"fill\", this.colors.accent);\n\t this.nodes.forEach(function (node) {\n\t node.element.setAttribute(\"fill\", _this.colors.accent);\n\t });\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t // this.nodes[this.selected].move( this.points )\n\t this.calculatePath();\n\t }\n\t },\n\t calculatePoints: {\n\t value: function calculatePoints() {\n\t var _this = this;\n\t\n\t this.points = [];\n\t this.nodes.forEach(function (node) {\n\t _this.points.push({ x: node.x, y: node.y });\n\t });\n\t }\n\t },\n\t calculatePath: {\n\t value: function calculatePath() {\n\t\n\t //stroke data\n\t var data = \"0 \" + this.nodes[0].location.y + \", \";\n\t\n\t // data should be re-ordered based on x location.\n\t // whatever function adds a node should add it at the right index\n\t\n\t this.nodes.forEach(function (node) {\n\t // let location = node.getCoordinates();\n\t data += node.location.x + \" \" + node.location.y + \", \";\n\t });\n\t\n\t // data += point.x*this.width+' '+ point.y*this.height+', ';\n\t data += this.width + \" \" + this.nodes[this.nodes.length - 1].location.y;\n\t\n\t this.line.setAttribute(\"points\", data);\n\t\n\t // fill data\n\t // add bottom corners\n\t\n\t data += \", \" + this.width + \" \" + this.height + \", \";\n\t data += \"0 \" + this.height;\n\t\n\t this.fill.setAttribute(\"points\", data);\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t // find nearest node and set this.selected (index)\n\t this.hasMoved = false;\n\t this.selected = this.findNearestNode();\n\t\n\t this.nodes[this.selected].move(this.mouse.x / this.width, 1 - this.mouse.y / this.height);\n\t this.scaleNode(this.selected);\n\t\n\t // must do this b/c new node may have been created\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.clicked) {\n\t this.mouse.x = math.clip(this.mouse.x, 0, this.width);\n\t this.hasMoved = true;\n\t\n\t this.nodes[this.selected].move(this.mouse.x / this.width, 1 - this.mouse.y / this.height);\n\t this.scaleNode(this.selected);\n\t\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t\n\t if (!this.hasMoved) {\n\t this.nodes[this.selected].destroy();\n\t }\n\t\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t\n\t // reset this.selected\n\t this.selected = null;\n\t }\n\t },\n\t findNearestNode: {\n\t value: function findNearestNode() {\n\t var nearestIndex = null;\n\t // set this unreasonably high so that every distance will be lower than it.\n\t var nearestDist = 10000;\n\t var before = false;\n\t var x = this.mouse.x / this.width;\n\t var y = 1 - this.mouse.y / this.height;\n\t var nodes = this.nodes;\n\t for (var i = 0; i < nodes.length; i++) {\n\t\n\t // calculate the distance from mouse to this node using pythagorean theorem\n\t var distance = Math.sqrt(Math.pow(nodes[i].x - x, 2) + Math.pow(nodes[i].y - y, 2));\n\t\n\t // if this distance is less than the previous shortest distance, use this index\n\t if (distance < nearestDist) {\n\t nearestDist = distance;\n\t nearestIndex = i;\n\t before = x > nodes[i].x;\n\t }\n\t }\n\t\n\t // if not very close to any node, create a node\n\t if (nearestDist > 0.07) {\n\t\n\t nearestIndex = this.getIndexFromX(this.mouse.x / this.width);\n\t\n\t this.nodes.splice(nearestIndex, 0, new Point({\n\t x: this.mouse.x / this.width,\n\t y: 1 - this.mouse.y / this.height\n\t }, this));\n\t this.hasMoved = true;\n\t }\n\t\n\t return nearestIndex;\n\t }\n\t },\n\t getIndexFromX: {\n\t value: function getIndexFromX(x) {\n\t var _this = this;\n\t\n\t var index = 0;\n\t this.nodes.forEach(function (node, i) {\n\t if (_this.nodes[i].x <= x) {\n\t index = i + 1;\n\t }\n\t });\n\t return index;\n\t }\n\t },\n\t scaleNode: {\n\t value: function scaleNode(i) {\n\t\n\t var clippedX = math.clip(this.nodes[i].x, 0, 1);\n\t var clippedY = math.clip(this.nodes[i].y, 0, 1);\n\t\n\t this.nodes[i].move(clippedX, clippedY);\n\t }\n\t },\n\t sortPoints: {\n\t\n\t /**\n\t Sort the this.points array from left-most point to right-most point. You should not regularly need to use this, however it may be useful if the points get unordered.\n\t */\n\t\n\t value: function sortPoints() {\n\t this.nodes.sort(function (a, b) {\n\t return a.x > b.x;\n\t });\n\t }\n\t },\n\t addPoint: {\n\t\n\t /**\n\t Add a breakpoint on the envelope.\n\t @param x {number} x location of the point, normalized (0-1)\n\t @param y {number} y location of the point, normalized (0-1)\n\t */\n\t\n\t value: function addPoint(x, y) {\n\t var index = this.nodes.length;\n\t\n\t this.sortPoints();\n\t\n\t for (var i = 0; i < this.nodes.length; i++) {\n\t if (x < this.nodes[i].x) {\n\t index = i;\n\t break;\n\t }\n\t }\n\t\n\t this.nodes.splice(index, 0, new Point({\n\t x: x,\n\t y: y\n\t }, this));\n\t\n\t this.scaleNode(index);\n\t\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t\n\t this.render();\n\t }\n\t },\n\t scan: {\n\t\n\t /**\n\t Find the level at a certain x location on the envelope.\n\t @param x {number} The x location to find the level of, normalized 0-1\n\t */\n\t\n\t value: function scan(x) {\n\t // find surrounding points\n\t var nextIndex = this.getIndexFromX(x);\n\t var priorIndex = nextIndex - 1;\n\t if (priorIndex < 0) {\n\t priorIndex = 0;\n\t }\n\t if (nextIndex >= this.nodes.length) {\n\t nextIndex = this.nodes.length - 1;\n\t }\n\t var priorPoint = this.nodes[priorIndex];\n\t var nextPoint = this.nodes[nextIndex];\n\t var loc = math.scale(x, priorPoint.x, nextPoint.x, 0, 1);\n\t var value = math.interp(loc, priorPoint.y, nextPoint.y);\n\t this.emit(\"scan\", value);\n\t return value;\n\t }\n\t },\n\t movePoint: {\n\t\n\t /**\n\t Move a breakpoint on the envelope.\n\t @param index {number} The index of the breakpoint to move\n\t @param x {number} New x location, normalized 0-1\n\t @param y {number} New y location, normalized 0-1\n\t */\n\t\n\t value: function movePoint(index, x, y) {\n\t this.nodes[index].move(x, y);\n\t this.scaleNode(index);\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t }\n\t },\n\t adjustPoint: {\n\t\n\t /**\n\t Move a breakpoint on the envelope by a certain amount.\n\t @param index {number} The index of the breakpoint to move\n\t @param xOffset {number} X displacement, normalized 0-1\n\t @param yOffset {number} Y displacement, normalized 0-1\n\t */\n\t\n\t value: function adjustPoint(index, xOffset, yOffset) {\n\t this.nodes[index].move(this.nodes[index].x + xOffset, this.nodes[index].y + yOffset);\n\t this.scaleNode(index);\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t }\n\t },\n\t destroyPoint: {\n\t\n\t /**\n\t Remove a breakpoint from the envelope.\n\t @param index {number} Index of the breakpoint to remove\n\t */\n\t\n\t value: function destroyPoint(index) {\n\t this.nodes[index].destroy();\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t }\n\t },\n\t setPoints: {\n\t\n\t /**\n\t Remove all existing breakpoints and add an entirely new set of breakpoints.\n\t @param allPoints {array} An array of objects with x/y properties (normalized 0-1). Each object in the array specifices the x/y location of a new breakpoint to be added.\n\t */\n\t\n\t value: function setPoints(allPoints) {\n\t var _this = this;\n\t\n\t while (this.nodes.length) {\n\t this.nodes[0].destroy();\n\t }\n\t allPoints.forEach(function (point) {\n\t _this.addPoint(point.x, point.y);\n\t });\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t }\n\t }\n\t });\n\t\n\t return Envelope;\n\t})(Interface);\n\t\n\tmodule.exports = Envelope;\n\n/***/ }),\n/* 35 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar dom = __webpack_require__(7);\n\t//let math = require('../util/math');\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\t* Spectrogram\n\t*\n\t* @description Audio spectrum visualization\n\t*\n\t* @demo <span nexus-ui=\"spectrogram\"></span>\n\t*\n\t* @example\n\t* var spectrogram = new Nexus.Spectrogram('#target')\n\t*\n\t* @example\n\t* var spectrogram = new Nexus.Spectrogram('#target',{\n\t* 'size': [300,150]\n\t* })\n\t*\n\t* @output\n\t* \n\t* No events\n\t*\n\t*/\n\t\n\tvar context = __webpack_require__(1).context;\n\t\n\tvar Spectrogram = (function (_Interface) {\n\t function Spectrogram() {\n\t _classCallCheck(this, Spectrogram);\n\t\n\t var options = [\"scale\", \"value\"];\n\t\n\t var defaults = {\n\t size: [300, 150]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Spectrogram.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.context = context(); // jshint ignore:line\n\t\n\t this.analyser = this.context.createAnalyser();\n\t this.analyser.fftSize = 2048;\n\t this.bufferLength = this.analyser.frequencyBinCount;\n\t this.dataArray = new Uint8Array(this.bufferLength);\n\t\n\t this.active = true;\n\t\n\t this.source = false;\n\t\n\t this.init();\n\t }\n\t\n\t _inherits(Spectrogram, _Interface);\n\t\n\t _createClass(Spectrogram, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.canvas = new dom.SmartCanvas(this.parent);\n\t this.element = this.canvas.element;\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t this.canvas.resize(this.width, this.height);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.canvas.element.style.backgroundColor = this.colors.fill;\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t\n\t if (this.active) {\n\t requestAnimationFrame(this.render.bind(this));\n\t }\n\t\n\t this.analyser.getByteFrequencyData(this.dataArray);\n\t\n\t this.canvas.context.fillStyle = this.colors.fill;\n\t this.canvas.context.fillRect(0, 0, this.canvas.element.width, this.canvas.element.height);\n\t\n\t if (this.source && this.dataArray) {\n\t\n\t //console.log(this.dataArray);\n\t\n\t var barWidth = this.canvas.element.width / this.bufferLength;\n\t var barHeight = undefined;\n\t var x = 0;\n\t\n\t var definition = this.canvas.element.width / 50;\n\t\n\t for (var i = 0; i < this.bufferLength; i = i + definition) {\n\t barHeight = Math.max.apply(null, this.dataArray.subarray(i, i + definition));\n\t barHeight /= 255;\n\t barHeight *= this.canvas.element.height;\n\t\n\t this.canvas.context.fillStyle = this.colors.accent;\n\t this.canvas.context.fillRect(x, this.canvas.element.height - barHeight, barWidth * definition, barHeight);\n\t\n\t x += barWidth * definition;\n\t }\n\t }\n\t }\n\t },\n\t connect: {\n\t\n\t /**\n\t Equivalent to \"patching in\" an audio node to visualize. NOTE: You cannot connect audio nodes across two different audio contexts. NexusUI runs its audio analysis on its own audio context, Nexus.context. If the audio node you are visualizing is created on a different audio context, you will need to tell NexusUI to use that context instead: i.e. Nexus.context = YourAudioContextName. For example, in ToneJS projects, the line would be: Nexus.context = Tone.context . We recommend that you write that line of code only once at the beginning of your project.\n\t @param node {AudioNode} The audio node to visualize\n\t @example Nexus.context = Tone.context // or another audio context you have created\n\t spectrogram.connect( Tone.Master );\n\t */\n\t\n\t value: function connect(node) {\n\t if (this.source) {\n\t this.disconnect();\n\t }\n\t this.source = node;\n\t this.source.connect(this.analyser);\n\t this.render();\n\t }\n\t },\n\t disconnect: {\n\t\n\t /**\n\t Stop visualizing the source node and disconnect it.\n\t */\n\t\n\t value: function disconnect() {\n\t this.source.disconnect(this.analyser);\n\t this.source = null;\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.active = !this.active;\n\t this.render();\n\t }\n\t },\n\t customDestroy: {\n\t value: function customDestroy() {\n\t this.active = false;\n\t }\n\t }\n\t });\n\t\n\t return Spectrogram;\n\t})(Interface);\n\t\n\tmodule.exports = Spectrogram;\n\n/***/ }),\n/* 36 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar dom = __webpack_require__(7);\n\tvar math = __webpack_require__(5);\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\t* Meter\n\t*\n\t* @description Stereo decibel meter\n\t*\n\t* @demo <span nexus-ui=\"meter\"></span>\n\t*\n\t* @example\n\t* var meter = new Nexus.Meter('#target')\n\t*\n\t* @example\n\t* var meter = new Nexus.Meter('#target',{\n\t* size: [75,75]\n\t* })\n\t*\n\t* @output\n\t* \n\t* No events\n\t*\n\t*/\n\t\n\tvar context = __webpack_require__(1).context;\n\t\n\tvar Meter = (function (_Interface) {\n\t function Meter() {\n\t _classCallCheck(this, Meter);\n\t\n\t var options = [\"scale\", \"value\"];\n\t\n\t var defaults = {\n\t size: [30, 100]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Meter.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.context = context(); // jshint ignore:line\n\t\n\t this.channels = 2;\n\t\n\t this.splitter = this.context.createChannelSplitter(this.channels);\n\t\n\t this.analysers = [];\n\t\n\t for (var i = 0; i < this.channels; i++) {\n\t var analyser = this.context.createAnalyser();\n\t this.splitter.connect(analyser, i);\n\t analyser.fftSize = 1024;\n\t analyser.smoothingTimeConstant = 1;\n\t this.analysers.push(analyser);\n\t }\n\t this.bufferLength = this.analysers[0].frequencyBinCount;\n\t this.dataArray = new Float32Array(this.bufferLength);\n\t\n\t /*\n\t // add linear gradient\n\t var grd = canvasCtx.createLinearGradient(0, 0, 0, canvas.height);\n\t // light blue\n\t grd.addColorStop(0, '#000');\n\t grd.addColorStop(0.2, '#bbb');\n\t grd.addColorStop(0.4, '#d18');\n\t // dark blue\n\t grd.addColorStop(1, '#d18');\n\t canvasCtx.fillStyle = grd; */\n\t\n\t this.active = true;\n\t\n\t this.db = -Infinity;\n\t\n\t this.init();\n\t\n\t this.meterWidth = this.canvas.element.width / this.channels;\n\t\n\t this.render();\n\t }\n\t\n\t _inherits(Meter, _Interface);\n\t\n\t _createClass(Meter, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.canvas = new dom.SmartCanvas(this.parent);\n\t this.element = this.canvas.element;\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t this.canvas.resize(this.width, this.height);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.canvas.element.style.backgroundColor = this.colors.fill;\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t\n\t if (this.active) {\n\t requestAnimationFrame(this.render.bind(this));\n\t }\n\t\n\t this.canvas.context.fillStyle = this.colors.fill;\n\t this.canvas.context.fillRect(0, 0, this.canvas.element.width, this.canvas.element.height);\n\t\n\t for (var i = 0; i < this.analysers.length; i++) {\n\t\n\t if (this.source) {\n\t\n\t this.analysers[i].getFloatTimeDomainData(this.dataArray);\n\t\n\t var rms = 0;\n\t\n\t for (var _i = 0; _i < this.dataArray.length; _i++) {\n\t rms += this.dataArray[_i] * this.dataArray[_i];\n\t }\n\t\n\t rms = Math.sqrt(rms / this.dataArray.length);\n\t\n\t this.db = 20 * Math.log10(rms);\n\t } else if (this.db > -200 && this.db !== -Infinity) {\n\t this.db -= 1;\n\t } else {\n\t this.db = -Infinity;\n\t }\n\t\n\t //console.log(db)\n\t\n\t if (this.db > -70) {\n\t\n\t var linear = math.normalize(this.db, -70, 5);\n\t var exp = linear * linear;\n\t var y = math.scale(exp, 0, 1, this.element.height, 0);\n\t\n\t this.canvas.context.fillStyle = this.colors.accent;\n\t this.canvas.context.fillRect(this.meterWidth * i, y, this.meterWidth, this.canvas.element.height - y);\n\t\n\t //console.log(\"rendering...\")\n\t }\n\t }\n\t }\n\t },\n\t connect: {\n\t\n\t /**\n\t Equivalent to \"patching in\" an audio node to visualize. NOTE: You cannot connect audio nodes across two different audio contexts. NexusUI runs its audio analysis on its own audio context, Nexus.context. If the audio node you are visualizing is created on a different audio context, you will need to tell NexusUI to use that context instead: i.e. Nexus.context = YourAudioContextName. For example, in ToneJS projects, the line would be: Nexus.context = Tone.context . We recommend that you write that line of code only once at the beginning of your project.\n\t @param node {AudioNode} The audio node to visualize\n\t @param channels {number} (optional) The number of channels in the source node to watch. If not specified, the interface will look for a .channelCount property on the input node. If it does not exist, the interface will default to 1 channel.\n\t @example Nexus.context = Tone.context // or another audio context you have created\n\t meter.connect( Tone.Master, 2 );\n\t */\n\t\n\t value: function connect(node, channels) {\n\t if (this.source) {\n\t this.disconnect();\n\t }\n\t //this.dummy.disconnect(this.splitter);\n\t\n\t if (channels) {\n\t this.channels = channels;\n\t } else if (node.channelCount) {\n\t this.channels = node.channelCount;\n\t } else {\n\t this.channels = 2;\n\t }\n\t this.meterWidth = this.canvas.element.width / this.channels;\n\t\n\t this.source = node;\n\t this.source.connect(this.splitter);\n\t\n\t // this.render();\n\t }\n\t },\n\t disconnect: {\n\t\n\t /**\n\t Stop visualizing the source node and disconnect it.\n\t */\n\t\n\t value: function disconnect() {\n\t\n\t this.source.disconnect(this.splitter);\n\t this.source = false;\n\t // this.dummy.connect(this.splitter);\n\t this.meterWidth = this.canvas.element.width / this.channels;\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.active = !this.active;\n\t this.render();\n\t }\n\t },\n\t customDestroy: {\n\t value: function customDestroy() {\n\t this.active = false;\n\t }\n\t }\n\t });\n\t\n\t return Meter;\n\t})(Interface);\n\t\n\tmodule.exports = Meter;\n\n/***/ }),\n/* 37 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar dom = __webpack_require__(7);\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\t* Oscilloscope\n\t*\n\t* @description Visualizes a waveform's stream of values.\n\t*\n\t* @demo <span nexus-ui=\"oscilloscope\"></span>\n\t*\n\t* @example\n\t* var oscilloscope = new Nexus.Oscilloscope('#target')\n\t*\n\t* @example\n\t* var oscilloscope = new Nexus.Oscilloscope('#target',{\n\t* 'size': [300,150]\n\t* })\n\t*\n\t* @output\n\t* \n\t* No events\n\t*\n\t*/\n\t\n\tvar context = __webpack_require__(1).context;\n\t\n\tvar Oscilloscope = (function (_Interface) {\n\t function Oscilloscope() {\n\t _classCallCheck(this, Oscilloscope);\n\t\n\t var options = [\"scale\", \"value\"];\n\t\n\t var defaults = {\n\t size: [300, 150]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Oscilloscope.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.context = context(); // jshint ignore:line\n\t\n\t this.analyser = this.context.createAnalyser();\n\t this.analyser.fftSize = 2048;\n\t this.bufferLength = this.analyser.frequencyBinCount;\n\t this.dataArray = new Uint8Array(this.bufferLength);\n\t this.analyser.getByteTimeDomainData(this.dataArray);\n\t\n\t this.active = true;\n\t\n\t this.source = false;\n\t\n\t this.init();\n\t\n\t this.render();\n\t }\n\t\n\t _inherits(Oscilloscope, _Interface);\n\t\n\t _createClass(Oscilloscope, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.canvas = new dom.SmartCanvas(this.parent);\n\t this.element = this.canvas.element;\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t this.canvas.resize(this.width, this.height);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.canvas.element.style.backgroundColor = this.colors.fill;\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t\n\t if (this.active) {\n\t requestAnimationFrame(this.render.bind(this));\n\t }\n\t\n\t this.analyser.getByteTimeDomainData(this.dataArray);\n\t\n\t this.canvas.context.fillStyle = this.colors.fill;\n\t this.canvas.context.fillRect(0, 0, this.canvas.element.width, this.canvas.element.height);\n\t\n\t this.canvas.context.lineWidth = ~ ~(this.height / 100 + 2);\n\t this.canvas.context.strokeStyle = this.colors.accent;\n\t\n\t this.canvas.context.beginPath();\n\t\n\t if (this.source) {\n\t\n\t var sliceWidth = this.canvas.element.width * 1 / this.bufferLength;\n\t var x = 0;\n\t\n\t for (var i = 0; i < this.bufferLength; i++) {\n\t\n\t var v = this.dataArray[i] / 128;\n\t var y = v * this.canvas.element.height / 2;\n\t\n\t if (i === 0) {\n\t this.canvas.context.moveTo(x, y);\n\t } else {\n\t this.canvas.context.lineTo(x, y);\n\t }\n\t\n\t x += sliceWidth;\n\t }\n\t } else {\n\t this.canvas.context.moveTo(0, this.canvas.element.height / 2);\n\t this.canvas.context.lineTo(this.canvas.element.width, this.canvas.element.height / 2);\n\t }\n\t\n\t this.canvas.context.stroke();\n\t }\n\t },\n\t connect: {\n\t\n\t /**\n\t Equivalent to \"patching in\" an audio node to visualize. NOTE: You cannot connect audio nodes across two different audio contexts. NexusUI runs its audio analysis on its own audio context, Nexus.context. If the audio node you are visualizing is created on a different audio context, you will need to tell NexusUI to use that context instead: i.e. Nexus.context = YourAudioContextName. For example, in ToneJS projects, the line would be: Nexus.context = Tone.context . We recommend that you write that line of code only once at the beginning of your project.\n\t @param node {AudioNode} The audio node to visualize\n\t @example Nexus.context = Tone.context // or another audio context you have created\n\t oscilloscope.connect( Tone.Master );\n\t */\n\t\n\t value: function connect(node) {\n\t\n\t if (this.source) {\n\t this.disconnect();\n\t }\n\t\n\t this.source = node;\n\t this.source.connect(this.analyser);\n\t\n\t this.render();\n\t }\n\t },\n\t disconnect: {\n\t\n\t /**\n\t Stop visualizing the source node and disconnect it.\n\t */\n\t\n\t value: function disconnect() {\n\t if (this.source) {\n\t this.source.disconnect(this.analyser);\n\t this.source = null;\n\t }\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.active = !this.active;\n\t this.render();\n\t }\n\t },\n\t customDestroy: {\n\t value: function customDestroy() {\n\t this.active = false;\n\t }\n\t }\n\t });\n\t\n\t return Oscilloscope;\n\t})(Interface);\n\t\n\tmodule.exports = Oscilloscope;\n\n/***/ }),\n/* 38 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\t/*\n\tMain concept:\n\tsynth = new Nexus.Rack('elementID');\n\t\n\tTransform all elements inside the div\n\tsynth.elementID will hold the first slider interface\n\t\n\t2) In future, potentially writing a rack that is re-usable?\n\tCould also take JSON\n\t\n\tnew Nexus.Rack('#target',{\n\t pre: () => {\n\t create some divs here, or some audio code\n\t },\n\t interface: {\n\t slider1: Nexus.add.slider({\n\t top:10,\n\t left:10,\n\t width:50,\n\t height:100,\n\t min: 0,\n\t max: 100,\n\t step: 1\n\t }),\n\t wave1: Nexus.add.waveform({\n\t file: './path/to/file.mp3',\n\t width:500,\n\t height:100,\n\t mode: 'range'\n\t })\n\t },\n\t init: () => {\n\t // some audio init code goes here...\n\t }\n\t});\n\t\n\t*/\n\t\n\tvar transform = _interopRequireWildcard(__webpack_require__(39));\n\t\n\tvar dom = _interopRequire(__webpack_require__(7));\n\t\n\tvar colors = __webpack_require__(1).colors;\n\t\n\tvar Rack = (function () {\n\t function Rack(target, settings) {\n\t _classCallCheck(this, Rack);\n\t\n\t this.meta = {};\n\t this.meta.target = target;\n\t this.meta.parent = dom.parseElement(target); // should be a generic function for parsing a 'target' argument that checks for string/DOM/jQUERY\n\t this.meta.colors = {};\n\t\n\t if (settings) {\n\t this.meta.attribute = settings.attribute || \"nexus-ui\";\n\t this.meta.title = settings.name || false;\n\t this.meta.open = settings.open || false;\n\t } else {\n\t this.meta.attribute = \"nexus-ui\";\n\t this.meta.title = false;\n\t this.meta.open = false;\n\t }\n\t\n\t var defaultColors = colors(); // jshint ignore:line\n\t this.meta.colors.accent = defaultColors.accent;\n\t this.meta.colors.fill = defaultColors.fill;\n\t this.meta.colors.light = defaultColors.light;\n\t this.meta.colors.dark = defaultColors.dark;\n\t this.meta.colors.mediumLight = defaultColors.mediumLight;\n\t this.meta.colors.mediumDark = defaultColors.mediumDark;\n\t this.buildInterface();\n\t this.colorInterface();\n\t }\n\t\n\t _createClass(Rack, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t var _this = this;\n\t\n\t this.meta.parent.style.boxSizing = \"border-box\";\n\t this.meta.parent.style.userSelect = \"none\";\n\t this.meta.parent.style.mozUserSelect = \"none\";\n\t this.meta.parent.style.webkitUserSelect = \"none\";\n\t\n\t this.meta.contents = document.createElement(\"div\");\n\t\n\t while (this.meta.parent.childNodes.length > 0) {\n\t this.meta.contents.appendChild(this.meta.parent.childNodes[0]);\n\t }\n\t\n\t this.meta.contents.style.padding = \"0px\";\n\t this.meta.contents.style.boxSizing = \"border-box\";\n\t\n\t if (this.meta.title) {\n\t this.meta.titleBar = document.createElement(\"div\");\n\t this.meta.titleBar.innerHTML = this.meta.title;\n\t this.meta.titleBar.style.fontFamily = \"arial\";\n\t this.meta.titleBar.style.position = \"relative\";\n\t this.meta.titleBar.style.color = \"#888\";\n\t this.meta.titleBar.style.padding = \"7px\";\n\t this.meta.titleBar.style.fontSize = \"12px\";\n\t\n\t this.meta.button = document.createElement(\"div\");\n\t this.meta.button.style.position = \"absolute\";\n\t this.meta.button.style.top = \"5px\";\n\t this.meta.button.style.right = \"5px\";\n\t this.meta.button.innerHTML = \"-\";\n\t this.meta.button.style.padding = \"0px 5px 2px\";\n\t this.meta.button.style.lineHeight = \"12px\";\n\t this.meta.button.style.fontSize = \"15px\";\n\t\n\t this.meta.button.style.cursor = \"pointer\";\n\t\n\t this.meta.button.addEventListener(\"mouseover\", function () {\n\t _this.meta.button.style.backgroundColor = _this.meta.colors.mediumDark;\n\t });\n\t this.meta.button.addEventListener(\"mouseleave\", function () {\n\t _this.meta.button.style.backgroundColor = _this.meta.colors.mediumLight;\n\t });\n\t this.meta.button.addEventListener(\"click\", function () {\n\t if (_this.meta.open) {\n\t _this.hide();\n\t } else {\n\t _this.show();\n\t }\n\t });\n\t\n\t this.meta.titleBar.appendChild(this.meta.button);\n\t\n\t this.meta.parent.appendChild(this.meta.titleBar);\n\t }\n\t this.meta.parent.appendChild(this.meta.contents);\n\t\n\t // var width = this.meta.parent.style.width = getComputedStyle(this.meta.parent).getPropertyValue('width');\n\t // this.meta.parent.style.width = width;\n\t\n\t var ui = transform.section(this.meta.target, this.meta.attribute);\n\t for (var key in ui) {\n\t this[key] = ui[key];\n\t }\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t if (this.meta.title) {\n\t this.meta.button.style.backgroundColor = this.meta.colors.mediumLight;\n\t this.meta.button.style.border = \"solid 0px \" + this.meta.colors.fill;\n\t this.meta.parent.style.border = \"solid 1px \" + this.meta.colors.mediumLight;\n\t this.meta.parent.style.backgroundColor = this.meta.colors.light;\n\t this.meta.titleBar.style.backgroundColor = this.meta.colors.fill;\n\t }\n\t }\n\t },\n\t show: {\n\t value: function show() {\n\t this.meta.contents.style.display = \"block\";\n\t this.meta.open = true;\n\t }\n\t },\n\t hide: {\n\t value: function hide() {\n\t this.meta.contents.style.display = \"none\";\n\t this.meta.open = false;\n\t }\n\t },\n\t colorize: {\n\t value: function colorize(type, color) {\n\t for (var key in this) {\n\t if (this[key].colorize) {\n\t this[key].colorize(type, color);\n\t }\n\t }\n\t this.meta.colors[type] = color;\n\t this.colorInterface();\n\t }\n\t },\n\t empty: {\n\t value: function empty() {\n\t for (var key in this) {\n\t if (this[key].destroy) {\n\t this[key].destroy();\n\t }\n\t }\n\t }\n\t }\n\t });\n\t\n\t return Rack;\n\t})();\n\t\n\tmodule.exports = Rack;\n\n/***/ }),\n/* 39 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\"use strict\";\n\t\n\tvar dom = _interopRequire(__webpack_require__(7));\n\t\n\tvar Interfaces = _interopRequire(__webpack_require__(2));\n\t\n\tvar createInterfaceID = function (widget, interfaceIDs) {\n\t var type = widget.type;\n\t if (interfaceIDs[type]) {\n\t interfaceIDs[type]++;\n\t } else {\n\t interfaceIDs[type] = 1;\n\t }\n\t return type + interfaceIDs[type];\n\t};\n\t\n\tvar element = function (element, type, options) {\n\t options = options || {};\n\t for (var i = 0; i < element.attributes.length; i++) {\n\t var att = element.attributes[i];\n\t // try {\n\t // options[att.nodeName] = eval(att.nodeValue);\n\t // } catch(e) {\n\t options[att.nodeName] = att.nodeValue;\n\t // }\n\t }\n\t type = type[0].toUpperCase() + type.slice(1);\n\t var widget = new Interfaces[type](element, options);\n\t widget.id = element.id;\n\t return widget;\n\t};\n\t\n\tvar section = function (parent, keyword) {\n\t\n\t keyword = keyword || \"nexus-ui\";\n\t\n\t var interfaceIDs = {};\n\t\n\t var container = dom.parseElement(parent);\n\t\n\t var ui = {};\n\t\n\t var htmlElements = container.getElementsByTagName(\"*\");\n\t var elements = [];\n\t for (var i = 0; i < htmlElements.length; i++) {\n\t elements.push(htmlElements[i]);\n\t }\n\t for (var i = 0; i < elements.length; i++) {\n\t var type = elements[i].getAttribute(keyword);\n\t if (type) {\n\t var formattedType = false;\n\t for (var key in Interfaces) {\n\t if (type.toLowerCase() === key.toLowerCase()) {\n\t formattedType = key;\n\t }\n\t }\n\t console.log(formattedType);\n\t var widget = element(elements[i], formattedType);\n\t if (widget.id) {\n\t ui[widget.id] = widget;\n\t } else {\n\t var id = createInterfaceID(widget, interfaceIDs);\n\t ui[id] = widget;\n\t }\n\t }\n\t }\n\t\n\t return ui;\n\t};\n\t\n\tvar add = function (type, parent, options) {\n\t var target = document.createElement(\"div\");\n\t options = options || {};\n\t if (parent) {\n\t parent = dom.parseElement(parent);\n\t } else {\n\t parent = document.body;\n\t }\n\t parent.appendChild(target);\n\t options.target = target;\n\t if (options.size) {\n\t target.style.width = options.size[0] + \"px\";\n\t target.style.height = options.size[1] + \"px\";\n\t }\n\t return element(target, type, options);\n\t};\n\t\n\texports.element = element;\n\texports.section = section;\n\texports.add = add;\n\n/***/ }),\n/* 40 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar Tune = (function () {\n\t function Tune() {\n\t _classCallCheck(this, Tune);\n\t\n\t // the scale as ratios\n\t this.scale = [];\n\t\n\t // i/o modes\n\t this.mode = {\n\t output: \"frequency\",\n\t input: \"step\"\n\t };\n\t\n\t // ET major\n\t this.etmajor = [261.62558, 293.664764, 329.627563, 349.228241, 391.995422, 440, 493.883301, 523.25116];\n\t\n\t // Root frequency.\n\t this.root = math.mtof(60); // * Math.pow(2,(60-69)/12);\n\t\n\t // default is a major scale\n\t this.createScale(0, 2, 4, 5, 7, 9, 11);\n\t }\n\t\n\t _createClass(Tune, {\n\t note: {\n\t\n\t /* Return data in the mode you are in (freq, ratio, or midi) */\n\t\n\t value: function note(input, octave) {\n\t\n\t var newvalue = undefined;\n\t\n\t if (this.mode.output === \"frequency\") {\n\t newvalue = this.frequency(input, octave);\n\t } else if (this.mode.output === \"ratio\") {\n\t newvalue = this.ratio(input, octave);\n\t } else if (this.mode.output === \"MIDI\") {\n\t newvalue = this.MIDI(input, octave);\n\t } else {\n\t newvalue = this.frequency(input, octave);\n\t }\n\t\n\t return newvalue;\n\t }\n\t },\n\t frequency: {\n\t\n\t /* Return freq data */\n\t\n\t value: function frequency(stepIn, octaveIn) {\n\t\n\t if (this.mode.input === \"midi\" || this.mode.input === \"MIDI\") {\n\t this.stepIn += 60;\n\t }\n\t\n\t // what octave is our input\n\t var octave = Math.floor(stepIn / this.scale.length);\n\t\n\t if (octaveIn) {\n\t octave += octaveIn;\n\t }\n\t\n\t // which scale degree (0 - scale length) is our input\n\t var scaleDegree = stepIn % this.scale.length;\n\t\n\t while (scaleDegree < 0) {\n\t scaleDegree += this.scale.length;\n\t }\n\t\n\t var ratio = this.scale[scaleDegree];\n\t\n\t var freq = this.root * ratio;\n\t\n\t freq = freq * Math.pow(2, octave);\n\t\n\t // truncate irrational numbers\n\t freq = Math.floor(freq * 100000000000) / 100000000000;\n\t\n\t return freq;\n\t }\n\t },\n\t ratio: {\n\t\n\t /* Force return ratio data */\n\t\n\t value: function ratio(stepIn, octaveIn) {\n\t\n\t if (this.mode.input === \"midi\" || this.mode.input === \"MIDI\") {\n\t this.stepIn += 60;\n\t }\n\t\n\t // what octave is our input\n\t var octave = Math.floor(stepIn / this.scale.length);\n\t\n\t if (octaveIn) {\n\t octave += octaveIn;\n\t }\n\t\n\t // which scale degree (0 - scale length) is our input\n\t var scaleDegree = stepIn % this.scale.length;\n\t\n\t // what ratio is our input to our key\n\t var ratio = Math.pow(2, octave) * this.scale[scaleDegree];\n\t\n\t ratio = Math.floor(ratio * 100000000000) / 100000000000;\n\t\n\t return ratio;\n\t }\n\t },\n\t MIDI: {\n\t\n\t /* Force return adjusted MIDI data */\n\t\n\t value: function MIDI(stepIn, octaveIn) {\n\t\n\t var newvalue = this.frequency(stepIn, octaveIn);\n\t\n\t var n = 69 + 12 * Math.log(newvalue / 440) / Math.log(2);\n\t\n\t n = Math.floor(n * 1000000000) / 1000000000;\n\t\n\t return n;\n\t }\n\t },\n\t createScale: {\n\t value: function createScale() {\n\t var newScale = [];\n\t for (var i = 0; i < arguments.length; i++) {\n\t newScale.push(math.mtof(60 + arguments[i]));\n\t }\n\t this.loadScaleFromFrequencies(newScale);\n\t }\n\t },\n\t createJIScale: {\n\t value: function createJIScale() {\n\t this.scale = [];\n\t for (var i = 0; i < arguments.length; i++) {\n\t this.scale.push(arguments[i]);\n\t }\n\t }\n\t },\n\t loadScaleFromFrequencies: {\n\t value: function loadScaleFromFrequencies(freqs) {\n\t this.scale = [];\n\t for (var i = 0; i < freqs.length - 1; i++) {\n\t this.scale.push(freqs[i] / freqs[0]);\n\t }\n\t }\n\t },\n\t loadScale: {\n\t\n\t /* Load a new scale */\n\t\n\t value: function loadScale(name) {\n\t\n\t /* load the scale */\n\t var freqs = this.scales[name].frequencies;\n\t this.loadScaleFromFrequencies(freqs);\n\t }\n\t },\n\t search: {\n\t\n\t /* Search the names of tunings\n\t \t Returns an array of names of tunings */\n\t\n\t value: function search(letters) {\n\t var possible = [];\n\t for (var key in this.scales) {\n\t if (key.toLowerCase().indexOf(letters.toLowerCase()) !== -1) {\n\t possible.push(key);\n\t }\n\t }\n\t return possible;\n\t }\n\t },\n\t chord: {\n\t\n\t /* Return a collection of notes as an array */\n\t\n\t value: function chord(midis) {\n\t var output = [];\n\t for (var i = 0; i < midis.length; i++) {\n\t output.push(this.note(midis[i]));\n\t }\n\t return output;\n\t }\n\t }\n\t });\n\t\n\t return Tune;\n\t})();\n\t\n\tmodule.exports = Tune;\n\n/***/ }),\n/* 41 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\t//Disable jshint warning concerning trailing regular params\n\t/*jshint -W138 */\n\t\n\tvar Radio = (function () {\n\t //if non-existent buttons are switched, they are ignored\n\t\n\t function Radio() {\n\t for (var _len = arguments.length, onVals = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n\t onVals[_key - 1] = arguments[_key];\n\t }\n\t\n\t var length = arguments[0] === undefined ? 3 : arguments[0];\n\t\n\t _classCallCheck(this, Radio);\n\t\n\t //each optional 'onVals' argument switches on that value in the Radio if it exists\n\t //In the example below, a 3-button radio is created, index 0 is switched on, index 1 is switched on then then attempted again producing an warning, and the final argument produces a warning because the index value does not exist.\n\t //Example:\n\t //` radio = new Radio(3, 0, 1, 1, 3);\n\t //… [1,1,0]\n\t\n\t if (length < 0) {\n\t length = 1;\n\t }\n\t\n\t this.length = length;\n\t this.onVals = onVals;\n\t this.array = new Array(length).fill(0);\n\t\n\t if (onVals.length > 0) {\n\t this.on.apply(this, onVals);\n\t }\n\t }\n\t\n\t _createClass(Radio, {\n\t select: {\n\t value: function select(value) {\n\t this.array.fill(0);\n\t this.array[value] = 1;\n\t return this.array;\n\t }\n\t },\n\t flip: {\n\t value: function flip() {\n\t for (var _len = arguments.length, values = Array(_len), _key = 0; _key < _len; _key++) {\n\t values[_key] = arguments[_key];\n\t }\n\t\n\t //flips the specified values. if no value is specified, flips all buttons\n\t var a = this.array;\n\t if (values.length > 0) {\n\t values.forEach(function (v) {\n\t if (v > a.length - 1) {\n\t console.warn(\"Warning: AnonRadio[\" + v + \"] does not exist\");\n\t } else {\n\t a[v] = a[v] ? 0 : 1;\n\t }\n\t });\n\t } else {\n\t a.forEach(function (v, i, arr) {\n\t arr[i] = v ? 0 : 1;\n\t });\n\t }\n\t return a;\n\t }\n\t },\n\t on: {\n\t value: function on() {\n\t for (var _len = arguments.length, values = Array(_len), _key = 0; _key < _len; _key++) {\n\t values[_key] = arguments[_key];\n\t }\n\t\n\t //switch on the specified values. if no value specified, flips on all buttons\n\t var a = this.array;\n\t if (values.length > 0) {\n\t values.forEach(function (v) {\n\t if (v > a.length - 1) {\n\t console.warn(\"Warning: AnonRadio[\" + v + \"] exceeds size of object\");\n\t } else {\n\t if (a[v] === 1) {\n\t console.warn(\"Warning: AnonRadio[\" + v + \"] was already on.\");\n\t }\n\t a[v] = 1;\n\t }\n\t });\n\t } else {\n\t a.fill(1);\n\t }\n\t return a;\n\t }\n\t },\n\t off: {\n\t value: function off() {\n\t for (var _len = arguments.length, values = Array(_len), _key = 0; _key < _len; _key++) {\n\t values[_key] = arguments[_key];\n\t }\n\t\n\t //switch off the specified values. if no value specified, flips off all buttons\n\t var a = this.array;\n\t if (values.length > 0) {\n\t values.forEach(function (v) {\n\t a[v] = 0;\n\t });\n\t } else {\n\t a.fill(0);\n\t }\n\t return a;\n\t }\n\t }\n\t });\n\t\n\t return Radio;\n\t})();\n\t\n\tmodule.exports = Radio;\n\n/***/ }),\n/* 42 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar WAAClock = __webpack_require__(43)\n\t\n\tmodule.exports = WAAClock\n\tif (typeof window !== 'undefined') window.WAAClock = WAAClock\n\n\n/***/ }),\n/* 43 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(process) {var isBrowser = (typeof window !== 'undefined')\n\t\n\tvar CLOCK_DEFAULTS = {\n\t toleranceLate: 0.10,\n\t toleranceEarly: 0.001\n\t}\n\t\n\t// ==================== Event ==================== //\n\tvar Event = function(clock, deadline, func) {\n\t this.clock = clock\n\t this.func = func\n\t this._cleared = false // Flag used to clear an event inside callback\n\t\n\t this.toleranceLate = clock.toleranceLate\n\t this.toleranceEarly = clock.toleranceEarly\n\t this._latestTime = null\n\t this._earliestTime = null\n\t this.deadline = null\n\t this.repeatTime = null\n\t\n\t this.schedule(deadline)\n\t}\n\t\n\t// Unschedules the event\n\tEvent.prototype.clear = function() {\n\t this.clock._removeEvent(this)\n\t this._cleared = true\n\t return this\n\t}\n\t\n\t// Sets the event to repeat every `time` seconds.\n\tEvent.prototype.repeat = function(time) {\n\t if (time === 0)\n\t throw new Error('delay cannot be 0')\n\t this.repeatTime = time\n\t if (!this.clock._hasEvent(this))\n\t this.schedule(this.deadline + this.repeatTime)\n\t return this\n\t}\n\t\n\t// Sets the time tolerance of the event.\n\t// The event will be executed in the interval `[deadline - early, deadline + late]`\n\t// If the clock fails to execute the event in time, the event will be dropped.\n\tEvent.prototype.tolerance = function(values) {\n\t if (typeof values.late === 'number')\n\t this.toleranceLate = values.late\n\t if (typeof values.early === 'number')\n\t this.toleranceEarly = values.early\n\t this._refreshEarlyLateDates()\n\t if (this.clock._hasEvent(this)) {\n\t this.clock._removeEvent(this)\n\t this.clock._insertEvent(this)\n\t }\n\t return this\n\t}\n\t\n\t// Returns true if the event is repeated, false otherwise\n\tEvent.prototype.isRepeated = function() { return this.repeatTime !== null }\n\t\n\t// Schedules the event to be ran before `deadline`.\n\t// If the time is within the event tolerance, we handle the event immediately.\n\t// If the event was already scheduled at a different time, it is rescheduled.\n\tEvent.prototype.schedule = function(deadline) {\n\t this._cleared = false\n\t this.deadline = deadline\n\t this._refreshEarlyLateDates()\n\t\n\t if (this.clock.context.currentTime >= this._earliestTime) {\n\t this._execute()\n\t \n\t } else if (this.clock._hasEvent(this)) {\n\t this.clock._removeEvent(this)\n\t this.clock._insertEvent(this)\n\t \n\t } else this.clock._insertEvent(this)\n\t}\n\t\n\tEvent.prototype.timeStretch = function(tRef, ratio) {\n\t if (this.isRepeated())\n\t this.repeatTime = this.repeatTime * ratio\n\t\n\t var deadline = tRef + ratio * (this.deadline - tRef)\n\t // If the deadline is too close or past, and the event has a repeat,\n\t // we calculate the next repeat possible in the stretched space.\n\t if (this.isRepeated()) {\n\t while (this.clock.context.currentTime >= deadline - this.toleranceEarly)\n\t deadline += this.repeatTime\n\t }\n\t this.schedule(deadline)\n\t}\n\t\n\t// Executes the event\n\tEvent.prototype._execute = function() {\n\t if (this.clock._started === false) return\n\t this.clock._removeEvent(this)\n\t\n\t if (this.clock.context.currentTime < this._latestTime)\n\t this.func(this)\n\t else {\n\t if (this.onexpired) this.onexpired(this)\n\t console.warn('event expired')\n\t }\n\t // In the case `schedule` is called inside `func`, we need to avoid\n\t // overrwriting with yet another `schedule`.\n\t if (!this.clock._hasEvent(this) && this.isRepeated() && !this._cleared)\n\t this.schedule(this.deadline + this.repeatTime) \n\t}\n\t\n\t// Updates cached times\n\tEvent.prototype._refreshEarlyLateDates = function() {\n\t this._latestTime = this.deadline + this.toleranceLate\n\t this._earliestTime = this.deadline - this.toleranceEarly\n\t}\n\t\n\t// ==================== WAAClock ==================== //\n\tvar WAAClock = module.exports = function(context, opts) {\n\t var self = this\n\t opts = opts || {}\n\t this.tickMethod = opts.tickMethod || 'ScriptProcessorNode'\n\t this.toleranceEarly = opts.toleranceEarly || CLOCK_DEFAULTS.toleranceEarly\n\t this.toleranceLate = opts.toleranceLate || CLOCK_DEFAULTS.toleranceLate\n\t this.context = context\n\t this._events = []\n\t this._started = false\n\t}\n\t\n\t// ---------- Public API ---------- //\n\t// Schedules `func` to run after `delay` seconds.\n\tWAAClock.prototype.setTimeout = function(func, delay) {\n\t return this._createEvent(func, this._absTime(delay))\n\t}\n\t\n\t// Schedules `func` to run before `deadline`.\n\tWAAClock.prototype.callbackAtTime = function(func, deadline) {\n\t return this._createEvent(func, deadline)\n\t}\n\t\n\t// Stretches `deadline` and `repeat` of all scheduled `events` by `ratio`, keeping\n\t// their relative distance to `tRef`. In fact this is equivalent to changing the tempo.\n\tWAAClock.prototype.timeStretch = function(tRef, events, ratio) {\n\t events.forEach(function(event) { event.timeStretch(tRef, ratio) })\n\t return events\n\t}\n\t\n\t// Removes all scheduled events and starts the clock \n\tWAAClock.prototype.start = function() {\n\t if (this._started === false) {\n\t var self = this\n\t this._started = true\n\t this._events = []\n\t\n\t if (this.tickMethod === 'ScriptProcessorNode') {\n\t var bufferSize = 256\n\t // We have to keep a reference to the node to avoid garbage collection\n\t this._clockNode = this.context.createScriptProcessor(bufferSize, 1, 1)\n\t this._clockNode.connect(this.context.destination)\n\t this._clockNode.onaudioprocess = function () {\n\t process.nextTick(function() { self._tick() })\n\t }\n\t } else if (this.tickMethod === 'manual') null // _tick is called manually\n\t\n\t else throw new Error('invalid tickMethod ' + this.tickMethod)\n\t }\n\t}\n\t\n\t// Stops the clock\n\tWAAClock.prototype.stop = function() {\n\t if (this._started === true) {\n\t this._started = false\n\t this._clockNode.disconnect()\n\t } \n\t}\n\t\n\t// ---------- Private ---------- //\n\t\n\t// This function is ran periodically, and at each tick it executes\n\t// events for which `currentTime` is included in their tolerance interval.\n\tWAAClock.prototype._tick = function() {\n\t var event = this._events.shift()\n\t\n\t while(event && event._earliestTime <= this.context.currentTime) {\n\t event._execute()\n\t event = this._events.shift()\n\t }\n\t\n\t // Put back the last event\n\t if(event) this._events.unshift(event)\n\t}\n\t\n\t// Creates an event and insert it to the list\n\tWAAClock.prototype._createEvent = function(func, deadline) {\n\t return new Event(this, deadline, func)\n\t}\n\t\n\t// Inserts an event to the list\n\tWAAClock.prototype._insertEvent = function(event) {\n\t this._events.splice(this._indexByTime(event._earliestTime), 0, event)\n\t}\n\t\n\t// Removes an event from the list\n\tWAAClock.prototype._removeEvent = function(event) {\n\t var ind = this._events.indexOf(event)\n\t if (ind !== -1) this._events.splice(ind, 1)\n\t}\n\t\n\t// Returns true if `event` is in queue, false otherwise\n\tWAAClock.prototype._hasEvent = function(event) {\n\t return this._events.indexOf(event) !== -1\n\t}\n\t\n\t// Returns the index of the first event whose deadline is >= to `deadline`\n\tWAAClock.prototype._indexByTime = function(deadline) {\n\t // performs a binary search\n\t var low = 0\n\t , high = this._events.length\n\t , mid\n\t while (low < high) {\n\t mid = Math.floor((low + high) / 2)\n\t if (this._events[mid]._earliestTime < deadline)\n\t low = mid + 1\n\t else high = mid\n\t }\n\t return low\n\t}\n\t\n\t// Converts from relative time to absolute time\n\tWAAClock.prototype._absTime = function(relTime) {\n\t return relTime + this.context.currentTime\n\t}\n\t\n\t// Converts from absolute time to relative time \n\tWAAClock.prototype._relTime = function(absTime) {\n\t return absTime - this.context.currentTime\n\t}\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(44)))\n\n/***/ }),\n/* 44 */\n/***/ (function(module, exports) {\n\n\t// shim for using process in browser\n\tvar process = module.exports = {};\n\t\n\t// cached from whatever global is present so that test runners that stub it\n\t// don't break things. But we need to wrap it in a try catch in case it is\n\t// wrapped in strict mode code which doesn't define any globals. It's inside a\n\t// function because try/catches deoptimize in certain engines.\n\t\n\tvar cachedSetTimeout;\n\tvar cachedClearTimeout;\n\t\n\tfunction defaultSetTimout() {\n\t throw new Error('setTimeout has not been defined');\n\t}\n\tfunction defaultClearTimeout () {\n\t throw new Error('clearTimeout has not been defined');\n\t}\n\t(function () {\n\t try {\n\t if (typeof setTimeout === 'function') {\n\t cachedSetTimeout = setTimeout;\n\t } else {\n\t cachedSetTimeout = defaultSetTimout;\n\t }\n\t } catch (e) {\n\t cachedSetTimeout = defaultSetTimout;\n\t }\n\t try {\n\t if (typeof clearTimeout === 'function') {\n\t cachedClearTimeout = clearTimeout;\n\t } else {\n\t cachedClearTimeout = defaultClearTimeout;\n\t }\n\t } catch (e) {\n\t cachedClearTimeout = defaultClearTimeout;\n\t }\n\t} ())\n\tfunction runTimeout(fun) {\n\t if (cachedSetTimeout === setTimeout) {\n\t //normal enviroments in sane situations\n\t return setTimeout(fun, 0);\n\t }\n\t // if setTimeout wasn't available but was latter defined\n\t if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n\t cachedSetTimeout = setTimeout;\n\t return setTimeout(fun, 0);\n\t }\n\t try {\n\t // when when somebody has screwed with setTimeout but no I.E. maddness\n\t return cachedSetTimeout(fun, 0);\n\t } catch(e){\n\t try {\n\t // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n\t return cachedSetTimeout.call(null, fun, 0);\n\t } catch(e){\n\t // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n\t return cachedSetTimeout.call(this, fun, 0);\n\t }\n\t }\n\t\n\t\n\t}\n\tfunction runClearTimeout(marker) {\n\t if (cachedClearTimeout === clearTimeout) {\n\t //normal enviroments in sane situations\n\t return clearTimeout(marker);\n\t }\n\t // if clearTimeout wasn't available but was latter defined\n\t if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n\t cachedClearTimeout = clearTimeout;\n\t return clearTimeout(marker);\n\t }\n\t try {\n\t // when when somebody has screwed with setTimeout but no I.E. maddness\n\t return cachedClearTimeout(marker);\n\t } catch (e){\n\t try {\n\t // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n\t return cachedClearTimeout.call(null, marker);\n\t } catch (e){\n\t // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n\t // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n\t return cachedClearTimeout.call(this, marker);\n\t }\n\t }\n\t\n\t\n\t\n\t}\n\tvar queue = [];\n\tvar draining = false;\n\tvar currentQueue;\n\tvar queueIndex = -1;\n\t\n\tfunction cleanUpNextTick() {\n\t if (!draining || !currentQueue) {\n\t return;\n\t }\n\t draining = false;\n\t if (currentQueue.length) {\n\t queue = currentQueue.concat(queue);\n\t } else {\n\t queueIndex = -1;\n\t }\n\t if (queue.length) {\n\t drainQueue();\n\t }\n\t}\n\t\n\tfunction drainQueue() {\n\t if (draining) {\n\t return;\n\t }\n\t var timeout = runTimeout(cleanUpNextTick);\n\t draining = true;\n\t\n\t var len = queue.length;\n\t while(len) {\n\t currentQueue = queue;\n\t queue = [];\n\t while (++queueIndex < len) {\n\t if (currentQueue) {\n\t currentQueue[queueIndex].run();\n\t }\n\t }\n\t queueIndex = -1;\n\t len = queue.length;\n\t }\n\t currentQueue = null;\n\t draining = false;\n\t runClearTimeout(timeout);\n\t}\n\t\n\tprocess.nextTick = function (fun) {\n\t var args = new Array(arguments.length - 1);\n\t if (arguments.length > 1) {\n\t for (var i = 1; i < arguments.length; i++) {\n\t args[i - 1] = arguments[i];\n\t }\n\t }\n\t queue.push(new Item(fun, args));\n\t if (queue.length === 1 && !draining) {\n\t runTimeout(drainQueue);\n\t }\n\t};\n\t\n\t// v8 likes predictible objects\n\tfunction Item(fun, array) {\n\t this.fun = fun;\n\t this.array = array;\n\t}\n\tItem.prototype.run = function () {\n\t this.fun.apply(null, this.array);\n\t};\n\tprocess.title = 'browser';\n\tprocess.browser = true;\n\tprocess.env = {};\n\tprocess.argv = [];\n\tprocess.version = ''; // empty string to avoid regexp issues\n\tprocess.versions = {};\n\t\n\tfunction noop() {}\n\t\n\tprocess.on = noop;\n\tprocess.addListener = noop;\n\tprocess.once = noop;\n\tprocess.off = noop;\n\tprocess.removeListener = noop;\n\tprocess.removeAllListeners = noop;\n\tprocess.emit = noop;\n\tprocess.prependListener = noop;\n\tprocess.prependOnceListener = noop;\n\t\n\tprocess.listeners = function (name) { return [] }\n\t\n\tprocess.binding = function (name) {\n\t throw new Error('process.binding is not supported');\n\t};\n\t\n\tprocess.cwd = function () { return '/' };\n\tprocess.chdir = function (dir) {\n\t throw new Error('process.chdir is not supported');\n\t};\n\tprocess.umask = function() { return 0; };\n\n\n/***/ }),\n/* 45 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar clock = __webpack_require__(1).clock;\n\t\n\tvar Interval = (function () {\n\t function Interval(rate, func, on) {\n\t _classCallCheck(this, Interval);\n\t\n\t this.rate = rate;\n\t this.on = on;\n\t this.clock = clock(); // jshint ignore:line\n\t\n\t this.pattern = [1];\n\t this.index = 0;\n\t\n\t this.event = func ? func : function () {};\n\t\n\t if (this.on) {\n\t this.start();\n\t }\n\t }\n\t\n\t _createClass(Interval, {\n\t _event: {\n\t value: function _event(e) {\n\t // if (this.pattern[this.index%this.pattern.length]) {\n\t this.event(e);\n\t // }\n\t this.index++;\n\t }\n\t },\n\t stop: {\n\t value: function stop() {\n\t this.on = false;\n\t this.interval.clear();\n\t }\n\t },\n\t start: {\n\t value: function start() {\n\t this.on = true;\n\t this.interval = this.clock.callbackAtTime(this._event.bind(this), this.clock.context.currentTime).repeat(this.rate / 1000).tolerance({ early: 0.1, late: 1 });\n\t }\n\t },\n\t ms: {\n\t value: function ms(newrate) {\n\t if (this.on) {\n\t var ratio = newrate / this.rate;\n\t this.rate = newrate;\n\t this.clock.timeStretch(this.clock.context.currentTime, [this.interval], ratio);\n\t } else {\n\t this.rate = newrate;\n\t }\n\t }\n\t }\n\t });\n\t\n\t return Interval;\n\t})();\n\t\n\tmodule.exports = Interval;\n\n/***/ })\n/******/ ])\n});\n;\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovLy93ZWJwYWNrL2Jvb3RzdHJhcCBiMjY5YWNlZjhjYWRhNzA4NDUwMiIsIndlYnBhY2s6Ly8vLi9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvbWFpbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9wb3NpdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC9zdmcuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwvbWF0aC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvY29yZS9pbnRlcmZhY2UuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwvZG9tLmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsL3V0aWwuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwvdG91Y2guanMiLCJ3ZWJwYWNrOi8vLy4vfi9ldmVudHMvZXZlbnRzLmpzIiwid2VicGFjazovLy8uL2xpYi9tb2RlbHMvc3RlcC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC9pbnRlcmFjdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvbW9kZWxzL3RvZ2dsZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zbGlkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2ludGVyZmFjZXMvdG9nZ2xlLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL2J1dHRvbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvY29tcG9uZW50cy9idXR0b250ZW1wbGF0ZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy90ZXh0YnV0dG9uLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL3JhZGlvYnV0dG9uLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL251bWJlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zZWxlY3QuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2ludGVyZmFjZXMvZGlhbC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9waWFuby5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zZXF1ZW5jZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21vZGVscy9tYXRyaXguanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21vZGVscy9zZXF1ZW5jZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvbW9kZWxzL2RydW5rLmpzIiwid2VicGFjazovLy8uL2xpYi9tb2RlbHMvY291bnRlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9wYW4yZC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy90aWx0LmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL211bHRpc2xpZGVyLmpzIiwid2VicGFjazovLy8uL2xpYi9jb21wb25lbnRzL3NsaWRlcnRlbXBsYXRlLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL3Bhbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9lbnZlbG9wZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zcGVjdHJvZ3JhbS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9tZXRlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9vc2NpbGxvc2NvcGUuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2NvcmUvcmFjay5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC90cmFuc2Zvcm0uanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3R1bmluZy90dW5pbmcuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21vZGVscy9yYWRpby5qcyIsIndlYnBhY2s6Ly8vLi9+L3dhYWNsb2NrL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vd2FhY2xvY2svbGliL1dBQUNsb2NrLmpzIiwid2VicGFjazovLy8uL34vcHJvY2Vzcy9icm93c2VyLmpzIiwid2VicGFjazovLy8uL2xpYi90aW1lL2ludGVydmFsLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRCxPO0FDVkE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQWU7QUFDZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7OztBQ3RDQSxhQUFZLENBQUM7Ozs7S0FFTixPQUFPLHVDQUFNLENBQVk7O2tCQUVqQixPQUFPLEM7Ozs7Ozs7Ozs7Ozs7Ozs7U0NtSE4sTUFBTSxHQUFOLE1BQU07U0FHTixPQUFPLEdBQVAsT0FBTztTQUdQLEtBQUssR0FBTCxLQUFLOzs7O0FBN0hyQixhQUFZLENBQUM7O0tBRU4sVUFBVSx1Q0FBTSxDQUFlOztLQUMvQixJQUFJLHVDQUFNLENBQWE7O0tBQ3ZCLElBQUksdUNBQU0sRUFBYTs7S0FDdkIsSUFBSSx1Q0FBTSxFQUFpQjs7S0FDdEIsU0FBUywrQ0FBTSxFQUFrQjs7QUFFN0MsS0FBSSxPQUFPLEdBQUcsbUJBQU8sQ0FBQyxFQUFrQixDQUFDLENBQUM7QUFDMUMsS0FBSSxLQUFLLEdBQUcsbUJBQU8sQ0FBQyxFQUFnQixDQUFDLENBQUM7QUFDdEMsS0FBSSxLQUFLLEdBQUcsbUJBQU8sQ0FBQyxFQUFnQixDQUFDLENBQUM7QUFDdEMsS0FBSSxRQUFRLEdBQUcsbUJBQU8sQ0FBQyxFQUFtQixDQUFDLENBQUM7QUFDNUMsS0FBSSxNQUFNLEdBQUcsbUJBQU8sQ0FBQyxFQUFpQixDQUFDLENBQUM7O0tBRWpDLFFBQVEsdUNBQU0sRUFBVTs7S0FDeEIsUUFBUSx1Q0FBTSxFQUFpQjs7Ozs7O0tBT2hDLE9BQU87QUFFRSxZQUZULE9BQU8s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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxnQkFBZSxTQUFTO0FBQ3hCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxJQUFHO0FBQ0gscUJBQW9CLFNBQVM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7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QUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNsRSxhQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7O0FBRWxFLGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN2QyxhQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDdkMsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDOztBQUV2QyxhQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDbkUsYUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ25FLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzs7QUFFbkUsYUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3hDLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN4QyxhQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7O0FBR3hDLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxJQUFJLENB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Q0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ25ELGVBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ25ELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1VBQ25ELE1BQU07QUFDTCxlQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDdEQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDNUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDNUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDNUQsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekQsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekQsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7VUFDekQ7UUFFRjs7QUFFRCxXQUFNO2NBQUEsZ0JBQUMsQ0FBQyxFQUFFO0FBQ1IsYUFBSSxJQUFJLENBQUMsT0FBTyxFQUFDOztBQUVmLGVBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDZixlQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ2hCLGVBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUM7OztBQUdoQixZQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFFLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixZQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFFLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixZQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLEdBQUcsRUFBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRzVCLGVBQUksWUFBWSxHQUFHO0FBQ2pCLGtCQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHO0FBQ2xCLGdCQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQyxDQUFDLEVBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxDQUFDLEVBQUcsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLENBQUU7WUFDekYsQ0FBQztBQUNGLGVBQUksYUFBYSxHQUFHO0FBQ2xCLGtCQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHO0FBQ2xCLGdCQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQyxHQUFHLEVBQUMsQ0FBQyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxDQUFDLEVBQUcsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLENBQUU7WUFDekYsQ0FBQzs7QUFFRixlQUFJLFVBQVUsR0FBRyxHQUFHLENBQUMsR0FB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QUFJLENBQUMsSUFBSSxDQUFDLEtBQUcsQ0FBQyxHQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDOztBQUVuQyxTQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBRSxDQUFDLEVBQUU7O0FBRXhDLFdBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBQyxDQUFDLENBQUM7QUFDcEQsV0FBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFDLENBQUMsQ0FBQzs7QUFFcEQsV0FBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDOUMsV0FBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7O0FBRTlDLFdBQUksSUFBSSxHQUFHLFNBQVMsSUFBSSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0MsV0FBSSxLQUFLLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7QUFFcEUsV0FBSSxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRTtBQUFFLGFBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQUU7QUFDckMsV0FBSSxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssRUFBRTtBQUFFLGFBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQUU7TUFFeEM7O0FBRUQsU0FBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDdEMsU0FBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFR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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQ0FBeUM7O0FBRXpDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsSUFBRztBQUNIO0FBQ0E7O0FBRUEsSUFBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBa0MsaUNBQWlDO0FBQ25FO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFxQyxlQUFlO0FBQ3BEO0FBQ0EsTUFBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEk7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7Ozs7QUN6T0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQSxFQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdCQUF1QixzQkFBc0I7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBcUI7QUFDckI7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNDQUFxQzs7QUFFckM7QUFDQTtBQUNBOztBQUVBLDRCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQSw2QkFBNEIsVUFBVTs7Ozs7OztBQ3ZMdEMsYUFBWSxDQUFDOzs7Ozs7S0FFSixLQUFLLHVCQUFRLENBQVMsRUFBdEIsS0FBSzs7S0FFTyxRQUFRO0FBRWhCLFlBRlEsUUFBUSxDQUVmLElBQUksRUFBQyxJQUFJLEVBQUMsRUFBRSxFQUFFOzJCQUZQLFFBQVE7O0FBSXpCLFNBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ2pCLFNBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2IsU0FBSSxDQUFDLEtBQUssR0FBRyxLQUFLLEVBQUUsQ0FBQzs7QUFFckIsU0FBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25CLFNBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDOztBQUVmLFNBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxZQUFXLEVBQUcsQ0FBQzs7QUFFMUMsU0FBSSxJQUFJLENBQUMsRUFBRSxFQUFFO0FBQ1gsV0FBSSxDQUFDLEtBQUssRUFBRSxDQUFDO01BQ2Q7SUFFRjs7Z0JBakJrQixRQUFRO0FBbUIzQixXQUFNO2NBQUEsZ0JBQUMsQ0FBQyxFQUFFOztBQUVOLGFBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRWhCLGFBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNkOztBQUVELFNBQUk7Y0FBQSxnQkFBRztBQUNMLGFBQUksQ0FBQyxFQUFFLEdBQUcsS0FBSyxDQUFDO0FBQ2hCLGFBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkI7O0FBRUQsVUFBSztjQUFBLGlCQUFHO0FBQ04sYUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDZixhQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7UUFDMUo7O0FBRUQsT0FBRTtjQUFBLFlBQUMsT0FBTyxFQUFFO0FBQ1YsYUFBSSxJQUFJLENBQUMsRUFBRSxFQUFFO0FBQ1gsZUFBSSxLQUFLLEdBQUcsT0FBTyxHQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDOUIsZUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7QUFDcEIsZUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1VBQ2hGLE1BQU07QUFDTCxlQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQztVQUNyQjtRQUNGOzs7O1VBNUNrQixRQUFROzs7a0JBQVIsUUFBUSxDIiwiZmlsZSI6Ii4vZGlzdC9OZXh1c1VJLmpzIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wiTmV4dXNcIl0gPSBmYWN0b3J5KCk7XG5cdGVsc2Vcblx0XHRyb290W1wiTmV4dXNcIl0gPSBmYWN0b3J5KCk7XG59KSh0aGlzLCBmdW5jdGlvbigpIHtcbnJldHVybiBcblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pXG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG5cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGV4cG9ydHM6IHt9LFxuIFx0XHRcdGlkOiBtb2R1bGVJZCxcbiBcdFx0XHRsb2FkZWQ6IGZhbHNlXG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oMCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay9ib290c3RyYXAgYjI2OWFjZWY4Y2FkYTcwODQ1MDIiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBOZXh1c1VJIGZyb20gJy4vbGliL21haW4nO1xuXG5leHBvcnQgZGVmYXVsdCBOZXh1c1VJO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vaW5kZXguanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBJbnRlcmZhY2VzIGZyb20gJy4vaW50ZXJmYWNlcy8nO1xuaW1wb3J0IG1hdGggZnJvbSAnLi91dGlsL21hdGgnO1xuaW1wb3J0IFJhY2sgZnJvbSAnLi9jb3JlL3JhY2snO1xuaW1wb3J0IFR1bmUgZnJvbSAnLi90dW5pbmcvdHVuaW5nJztcbmltcG9ydCAqIGFzIFRyYW5zZm9ybSBmcm9tICcuL3V0aWwvdHJhbnNmb3JtJztcblxubGV0IENvdW50ZXIgPSByZXF1aXJlKCcuL21vZGVscy9jb3VudGVyJyk7XG5sZXQgUmFkaW8gPSByZXF1aXJlKCcuL21vZGVscy9yYWRpbycpO1xubGV0IERydW5rID0gcmVxdWlyZSgnLi9tb2RlbHMvZHJ1bmsnKTtcbmxldCBTZXF1ZW5jZSA9IHJlcXVpcmUoJy4vbW9kZWxzL3NlcXVlbmNlJyk7XG5sZXQgTWF0cml4ID0gcmVxdWlyZSgnLi9tb2RlbHMvbWF0cml4Jyk7XG5cbmltcG9ydCBXQUFDbG9jayBmcm9tICd3YWFjbG9jayc7XG5pbXBvcnQgSW50ZXJ2YWwgZnJvbSAnLi90aW1lL2ludGVydmFsJztcblxuXG4vKipcbk5leHVzVUkgPT4gY3JlYXRlZCBhcyBOZXh1c1xuKi9cblxuY2xhc3MgTmV4dXNVSSB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0KSB7XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIEludGVyZmFjZXMpIHtcbiAgICAgICAgICAgIHRoaXNba2V5XSA9IEludGVyZmFjZXNba2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGtleSBpbiBtYXRoKSB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSBtYXRoW2tleV07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgQ29yZSA9IHtcbiAgICAgICAgICAnUmFjayc6IFJhY2tcbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgTW9kZWxzID0ge1xuICAgICAgICAgICdDb3VudGVyJzogQ291bnRlcixcbiAgICAgICAgICAnUmFkaW8nOiBSYWRpbyxcbiAgICAgICAgICAnRHJ1bmsnOiBEcnVuayxcbiAgICAgICAgICAnU2VxdWVuY2UnOiBTZXF1ZW5jZSxcbiAgICAgICAgICAnTWF0cml4JzogTWF0cml4XG4gICAgICAgIH07XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIE1vZGVscykge1xuICAgICAgICAgIHRoaXNba2V5XSA9IE1vZGVsc1trZXldO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIENvcmUpIHtcbiAgICAgICAgICB0aGlzW2tleV0gPSBDb3JlW2tleV07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgRGVmYXVsdENvbnRleHQgPSB3aW5kb3cuQXVkaW9Db250ZXh0IHx8IHdpbmRvdy53ZWJraXRBdWRpb0NvbnRleHQ7XG4gICAgICAgIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0IHx8IG5ldyBEZWZhdWx0Q29udGV4dCgpO1xuXG4gICAgICAgIHRoaXMudHVuZSA9IG5ldyBUdW5lKCk7XG4gICAgICAgIHRoaXMubm90ZSA9IHRoaXMudHVuZS5ub3RlLmJpbmQodGhpcy50dW5lKTtcblxuICAgICAgICB0aGlzLmNsb2NrID0gbmV3IFdBQUNsb2NrKHRoaXMuX2NvbnRleHQpO1xuICAgICAgICB0aGlzLmNsb2NrLnN0YXJ0KCk7XG4gICAgICAgIHRoaXMuSW50ZXJ2YWwgPSBJbnRlcnZhbDtcblxuICAgICAgICB0aGlzLmNvbG9ycyA9IHtcbiAgICAgICAgICBhY2NlbnQ6ICcjMmJiJyxcbiAgICAgICAgICBmaWxsOiAnI2VlZScsXG4gICAgICAgICAgbGlnaHQ6ICcjZmZmJyxcbiAgICAgICAgICBkYXJrOiAnIzMzMycsXG4gICAgICAgICAgbWVkaXVtTGlnaHQ6ICcjY2NjJyxcbiAgICAgICAgICBtZWRpdW1EYXJrOiAnIzY2NidcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnRyYW5zZm9ybSA9IFRyYW5zZm9ybTtcbiAgICAgICAgdGhpcy5hZGQgPSBUcmFuc2Zvcm0uYWRkO1xuXG5cbiAgICAgICAgdGhpcy5BZGQgPSB7fTtcbiAgICAgICAgZm9yIChsZXQga2V5IGluIEludGVyZmFjZXMpIHtcbiAgICAgICAgICB0aGlzLkFkZFtrZXldID0gVHJhbnNmb3JtLmFkZC5iaW5kKHRoaXMsa2V5KTtcbiAgICAgICAgfVxuXG5cblxuXG4gICAgICAgIC8qIGNyZWF0ZSBkZWZhdWx0IGNvbXBvbmVudCBzaXplICovXG4gICAgICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICAgICAgdmFyIGV4aXN0aW5nU3R5bGVzaGVldHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcInN0eWxlXCIpO1xuICAgICAgICB2YXIgZGVmYXVsdFNpemVEZWNsYXJhdGlvbiA9ICdbbmV4dXMtdWlde2hlaWdodDo1MDAwcHg7d2lkdGg6NTAwMHB4fSc7XG4gICAgICAgIHZhciBkZWZhdWx0U3R5bGVOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICAgICAgZGVmYXVsdFN0eWxlTm9kZS50eXBlID0gJ3RleHQvY3NzJztcbiAgICAgICAgZGVmYXVsdFN0eWxlTm9kZS5pbm5lckhUTUwgPSBkZWZhdWx0U2l6ZURlY2xhcmF0aW9uO1xuICAgICAgICBpZiAoZXhpc3RpbmdTdHlsZXNoZWV0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdmFyIHBhcmVudCA9IGV4aXN0aW5nU3R5bGVzaGVldHNbMF0ucGFyZW50Tm9kZVxuICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoIGRlZmF1bHRTdHlsZU5vZGUsIGV4aXN0aW5nU3R5bGVzaGVldHNbMF0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoJzxzdHlsZT4nK2RlZmF1bHRTaXplRGVjbGFyYXRpb24rJzxcXC9zdHlsZT4nKTtcbiAgICAgICAgfVxuICAgICAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG4gICAgfVxuXG4gICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY29udGV4dDtcbiAgICB9XG5cbiAgICBzZXQgY29udGV4dChjdHgpIHtcbiAgICAgIHRoaXMuY2xvY2suc3RvcCgpO1xuICAgICAgdGhpcy5fY29udGV4dCA9IGN0eDtcbiAgICAgIHRoaXMuY2xvY2sgPSBuZXcgV0FBQ2xvY2sodGhpcy5jb250ZXh0KTtcbiAgICAgIHRoaXMuY2xvY2suc3RhcnQoKTtcbiAgICB9XG5cblxuXG59XG5cbmxldCBOZXh1cyA9IG5ldyBOZXh1c1VJKCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBjb2xvcnMoKSB7XG4gICAgcmV0dXJuIE5leHVzLmNvbG9ycztcbn1cbmV4cG9ydCBmdW5jdGlvbiBjb250ZXh0KCkge1xuICAgIHJldHVybiBOZXh1cy5jb250ZXh0O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNsb2NrKCkge1xuICAgIHJldHVybiBOZXh1cy5jbG9jaztcbn1cblxuZXhwb3J0IGRlZmF1bHQgTmV4dXM7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbWFpbi5qcyIsImV4cG9ydCBkZWZhdWx0IHtcbiAgUG9zaXRpb246IHJlcXVpcmUoJy4vcG9zaXRpb24nKSxcbiAgU2xpZGVyOiByZXF1aXJlKCcuL3NsaWRlcicpLFxuICBUb2dnbGU6IHJlcXVpcmUoJy4vdG9nZ2xlJyksXG4vKiAgUmFuZ2U6IHJlcXVpcmUoJy4vcmFuZ2VzbGlkZXInKSxcbiAgV2F2ZWZvcm06IHJlcXVpcmUoJy4vd2F2ZWZvcm0nKSwgKi9cbiAgQnV0dG9uOiByZXF1aXJlKCcuL2J1dHRvbicpLFxuICBUZXh0QnV0dG9uOiByZXF1aXJlKCcuL3RleHRidXR0b24nKSxcbiAgUmFkaW9CdXR0b246IHJlcXVpcmUoJy4vcmFkaW9idXR0b24nKSxcbiAgTnVtYmVyOiByZXF1aXJlKCcuL251bWJlcicpLFxuICBTZWxlY3Q6IHJlcXVpcmUoJy4vc2VsZWN0JyksXG4gIERpYWw6IHJlcXVpcmUoJy4vZGlhbCcpLFxuICBQaWFubzogcmVxdWlyZSgnLi9waWFubycpLFxuICBTZXF1ZW5jZXI6IHJlcXVpcmUoJy4vc2VxdWVuY2VyJyksXG4gIFBhbjJEOiByZXF1aXJlKCcuL3BhbjJkJyksXG4gIFRpbHQ6IHJlcXVpcmUoJy4vdGlsdCcpLFxuICBNdWx0aXNsaWRlcjogcmVxdWlyZSgnLi9tdWx0aXNsaWRlcicpLFxuICBQYW46IHJlcXVpcmUoJy4vcGFuJyksXG4gIEVudmVsb3BlOiByZXF1aXJlKCcuL2VudmVsb3BlJyksXG4gIFNwZWN0cm9ncmFtOiByZXF1aXJlKCcuL3NwZWN0cm9ncmFtJyksXG4gIE1ldGVyOiByZXF1aXJlKCcuL21ldGVyJyksXG4gIE9zY2lsbG9zY29wZTogcmVxdWlyZSgnLi9vc2NpbGxvc2NvcGUnKVxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL2luZGV4LmpzIiwiXG4ndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgU3RlcCA9IHJlcXVpcmUoJy4uL21vZGVscy9zdGVwJyk7XG5pbXBvcnQgKiBhcyBJbnRlcmFjdGlvbiBmcm9tICcuLi91dGlsL2ludGVyYWN0aW9uJztcblxuLyoqXG4qIFBvc2l0aW9uXG4qXG4qIEBkZXNjcmlwdGlvbiBUd28tZGltZW5zaW9uYWwgdG91Y2ggc2xpZGVyLlxuKlxuKiBAZGVtbyA8c3BhbiBuZXh1cy11aT1cInBvc2l0aW9uXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcG9zaXRpb24gPSBuZXcgTmV4dXMuUG9zaXRpb24oJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcG9zaXRpb24gPSBuZXcgTmV4dXMuUG9zaXRpb24oJyN0YXJnZXQnLHtcbiogICAnc2l6ZSc6IFsyMDAsMjAwXSxcbiogICAnbW9kZSc6ICdhYnNvbHV0ZScsICAvLyBcImFic29sdXRlXCIgb3IgXCJyZWxhdGl2ZVwiXG4qICAgJ3gnOiAwLjUsICAvLyBpbml0aWFsIHggdmFsdWVcbiogICAnbWluWCc6IDAsXG4qICAgJ21heFgnOiAxLFxuKiAgICdzdGVwWCc6IDAsXG4qICAgJ3knOiAwLjUsICAvLyBpbml0aWFsIHkgdmFsdWVcbiogICAnbWluWSc6IDAsXG4qICAgJ21heFknOiAxLFxuKiAgICdzdGVwWSc6IDBcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgaXMgYW4gb2JqZWN0IHdpdGggeCBhbmQgeSBwcm9wZXJ0aWVzIGNvbnRhaW5pbmcgdGhlIHggYW5kIHkgdmFsdWVzIG9mIHRoZSBpbnRlcmZhY2UuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIHBvc2l0aW9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBvc2l0aW9uIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMjAwLDIwMF0sXG4gICAgICAnbW9kZSc6ICdhYnNvbHV0ZScsXG4gICAgICAnbWluWCc6IDAsXG4gICAgICAnbWF4WCc6IDEsXG4gICAgICAnc3RlcFgnOiAwLFxuICAgICAgJ3gnOiAwLjUsXG4gICAgICAnbWluWSc6IDAsXG4gICAgICAnbWF4WSc6IDEsXG4gICAgICAnc3RlcFknOiAwLFxuICAgICAgJ3knOiAwLjVcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG5cbiAgICB0aGlzLl94ID0gbmV3IFN0ZXAoIHRoaXMuc2V0dGluZ3MubWluWCwgdGhpcy5zZXR0aW5ncy5tYXhYLCB0aGlzLnNldHRpbmdzLnN0ZXBYLCB0aGlzLnNldHRpbmdzLnggKTtcbiAgICB0aGlzLl95ID0gbmV3IFN0ZXAoIHRoaXMuc2V0dGluZ3MubWluWSwgdGhpcy5zZXR0aW5ncy5tYXhZLCB0aGlzLnNldHRpbmdzLnN0ZXBZLCB0aGlzLnNldHRpbmdzLnkgKTtcblxuICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICB4OiBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMuc2V0dGluZ3MubW9kZSwnaG9yaXpvbnRhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKSxcbiAgICAgIHk6IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLCd2ZXJ0aWNhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKVxuICAgIH07XG4gICAgdGhpcy5wb3NpdGlvbi54LnZhbHVlID0gdGhpcy5feC5ub3JtYWxpemVkO1xuICAgIHRoaXMucG9zaXRpb24ueS52YWx1ZSA9IHRoaXMuX3kubm9ybWFsaXplZDtcblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG4gICAgXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgICB0aGlzLnBvc2l0aW9uLngucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG4gICAgICB0aGlzLnBvc2l0aW9uLnkucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG5cbiAgICAgIHRoaXMuX21pbkRpbWVuc2lvbiA9IE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpO1xuXG4gICAgICB0aGlzLmtub2JSYWRpdXMgPSB7XG4gICAgICAgIG9mZjogfn4odGhpcy5fbWluRGltZW5zaW9uLzEwMCkgKiA1ICsgNSxcbiAgICAgIH07XG4gICAgICB0aGlzLmtub2JSYWRpdXMub24gPSB0aGlzLmtub2JSYWRpdXMub2ZmICogMjtcblxuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMud2lkdGgvMik7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQvMik7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JSYWRpdXMub2ZmKTtcbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAodGhpcy5jbGlja2VkKSB7XG4gICAgLy8gIHRoaXMua25vYlJhZGl1cyA9IDMwO1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgncicsdGhpcy5rbm9iUmFkaXVzLm9uKTtcbiAgICB9IGVsc2Uge1xuICAgIC8vICB0aGlzLmtub2JSYWRpdXMgPSAxNTtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYlJhZGl1cy5vZmYpO1xuICAgIH1cblxuICAgIHRoaXMua25vYkNvb3JkaW5hdGVzID0ge1xuICAgICAgeDogdGhpcy5feC5ub3JtYWxpemVkICogdGhpcy53aWR0aCxcbiAgICAgIHk6IHRoaXMuaGVpZ2h0IC0gdGhpcy5feS5ub3JtYWxpemVkICogdGhpcy5oZWlnaHRcbiAgICB9O1xuXG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkNvb3JkaW5hdGVzLngpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmtub2JDb29yZGluYXRlcy55KTtcbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgdGhpcy5wb3NpdGlvbi54LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5wb3NpdGlvbi55LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMucG9zaXRpb24ueC51cGRhdGUodGhpcy5tb3VzZSk7XG4gICAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKHRoaXMubW91c2UpO1xuICAgICAgdGhpcy5feC51cGRhdGVOb3JtYWwoIHRoaXMucG9zaXRpb24ueC52YWx1ZSApO1xuICAgICAgdGhpcy5feS51cGRhdGVOb3JtYWwoIHRoaXMucG9zaXRpb24ueS52YWx1ZSApO1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgeDogdGhpcy5feC52YWx1ZSxcbiAgICAgICAgeTogdGhpcy5feS52YWx1ZVxuICAgICAgfSk7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFRoZSBpbnRlcmZhY2UncyB4IHZhbHVlLiBXaGVuIHNldCwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IGFkanVzdCB0byBmaXQgbWluL21heC9zdGVwIHNldHRpbmdzIG9mIHRoZSBpbnRlcmZhY2UuXG4gICogQHR5cGUge29iamVjdH1cbiAgKiBAZXhhbXBsZSBwb3NpdGlvbi54ID0gMC41O1xuICAqL1xuXG4gIGdldCB4KCkge1xuICAgIHJldHVybiB0aGlzLl94LnZhbHVlO1xuICB9XG5cbiAgc2V0IHgodmFsdWUpIHtcbiAgICB0aGlzLl94LnVwZGF0ZSh2YWx1ZSk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgIHg6IHRoaXMuX3gudmFsdWUsXG4gICAgICB5OiB0aGlzLl95LnZhbHVlXG4gICAgfSk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFRoZSBpbnRlcmZhY2UncyB5IHZhbHVlcy4gV2hlbiBzZXQsIGl0IHdpbGwgYXV0b21hdGljYWxseSBhZGp1c3QgdG8gZml0IG1pbi9tYXgvc3RlcCBzZXR0aW5ncyBvZiB0aGUgaW50ZXJmYWNlLlxuICAqIEB0eXBlIHtvYmplY3R9XG4gICogQGV4YW1wbGUgcG9zaXRpb24ueCA9IDAuNTtcbiAgKi9cblxuICBnZXQgeSgpIHtcbiAgICByZXR1cm4gdGhpcy5feS52YWx1ZTtcbiAgfVxuXG4gIHNldCB5KHZhbHVlKSB7XG4gICAgdGhpcy5feS51cGRhdGUodmFsdWUpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICB4OiB0aGlzLl94LnZhbHVlLFxuICAgICAgeTogdGhpcy5feS52YWx1ZVxuICAgIH0pO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuXG5cbiAgZ2V0IG5vcm1hbGl6ZWQoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHRoaXMuX3gubm9ybWFsaXplZCxcbiAgICAgIHk6IHRoaXMuX3kubm9ybWFsaXplZFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgKiBUaGUgbG93ZXIgbGltaXQgb2YgdmFsdWUgb24gdGhlIHggYXhpc1xuICAqIEB0eXBlIHtvYmplY3R9XG4gICovXG4gIGdldCBtaW5YKCkge1xuICAgIHJldHVybiB0aGlzLl94Lm1pbjtcbiAgfVxuXG4gIHNldCBtaW5YKHYpIHtcbiAgICB0aGlzLl94Lm1pbiA9IHY7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFRoZSBsb3dlciBsaW1pdCBvZiB2YWx1ZSBvbiB0aGUgeSBheGlzXG4gICogQHR5cGUge29iamVjdH1cbiAgKi9cbiAgZ2V0IG1pblkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3kubWluO1xuICB9XG5cbiAgc2V0IG1pblkodikge1xuICAgIHRoaXMuX3kubWluID0gdjtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgKiBUaGUgdXBwZXIgbGltaXQgb2YgdmFsdWUgb24gdGhlIHggYXhpc1xuICAqIEB0eXBlIHtvYmplY3R9XG4gICovXG4gIGdldCBtYXhYKCkge1xuICAgIHJldHVybiB0aGlzLl94Lm1heDtcbiAgfVxuXG4gIHNldCBtYXhYKHYpIHtcbiAgICB0aGlzLl94Lm1heCA9IHY7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gICogVGhlIHVwcGVyIGxpbWl0IG9mIHZhbHVlIG9uIHRoZSB5IGF4aXNcbiAgKiBAdHlwZSB7b2JqZWN0fVxuICAqL1xuICBnZXQgbWF4WSgpIHtcbiAgICByZXR1cm4gdGhpcy5feS5tYXg7XG4gIH1cblxuICBzZXQgbWF4WSh2KSB7XG4gICAgdGhpcy5feS5tYXggPSB2O1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuXG4gIC8qKlxuICAqIFRoZSBpbmNyZW1lbnRhbCBzdGVwIG9mIHZhbHVlcyBvbiB0aGUgeCBheGlzXG4gICogQHR5cGUge29iamVjdH1cbiAgKi9cbiAgZ2V0IHN0ZXBYKCkge1xuICAgIHJldHVybiB0aGlzLl94LnN0ZXA7XG4gIH1cblxuICBzZXQgc3RlcFgodikge1xuICAgIHRoaXMuX3guc3RlcCA9IHY7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gICogVGhlIGluY3JlbWVudGFsIHN0ZXAgb2YgdmFsdWVzIG9uIHRoZSB5IGF4aXNcbiAgKiBAdHlwZSB7b2JqZWN0fVxuICAqL1xuICBnZXQgc3RlcFkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3kuc3RlcDtcbiAgfVxuXG4gIHNldCBzdGVwWSh2KSB7XG4gICAgdGhpcy5feS5zdGVwID0gdjtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgQWJzb2x1dGUgbW9kZSAocG9zaXRpb24ncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJhYnNvbHV0ZVwiLlxuICBAdHlwZSB7c3RyaW5nfVxuICBAZXhhbXBsZSBwb3NpdGlvbi5tb2RlID0gXCJyZWxhdGl2ZVwiO1xuICAqL1xuICBnZXQgbW9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi54Lm1vZGU7XG4gIH1cbiAgc2V0IG1vZGUodikge1xuICAgIHRoaXMucG9zaXRpb24ueC5tb2RlID0gdjtcbiAgICB0aGlzLnBvc2l0aW9uLnkubW9kZSA9IHY7XG4gIH1cblxuXG5cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvcG9zaXRpb24uanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5cbmV4cG9ydCBkZWZhdWx0IHtcblxuICBjcmVhdGU6ICh0eXBlKSA9PiB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCB0eXBlKTtcbiAgfSxcblxuICBhcmM6ICh4LCB5LCByYWRpdXMsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlKSA9PiB7XG5cbiAgICB2YXIgc3RhcnQgPSBtYXRoLnRvQ2FydGVzaWFuKHJhZGl1cywgZW5kQW5nbGUpO1xuICAgIHZhciBlbmQgPSBtYXRoLnRvQ2FydGVzaWFuKHJhZGl1cywgc3RhcnRBbmdsZSk7XG5cbiAgICB2YXIgbGFyZ2VBcmNGbGFnID0gZW5kQW5nbGUgLSBzdGFydEFuZ2xlIDw9IDE4MCA/ICcwJyA6ICcxJztcblxuICAgIHZhciBkID0gW1xuICAgICAgICAnTScsIHN0YXJ0LngreCwgc3RhcnQueSt5LFxuICAgICAgICAnQScsIHJhZGl1cywgcmFkaXVzLCAwLCBsYXJnZUFyY0ZsYWcsIDAsIGVuZC54K3gsIGVuZC55K3lcbiAgICBdLmpvaW4oJyAnKTtcblxuICAgIHJldHVybiBkO1xuICB9LFxuXG4gIHJhZGlhbEdyYWRpZW50OiAoZGVmcyxudW1iZXJPZlN0b3BzKSA9PiB7XG5cbiAgICBsZXQgaWQgPSAnZ3JhZGllbnQnICsgbWF0aC5yaSgxMDAwMDAwMDAwMDApO1xuICAgIGxldCBzdG9wcyA9IFtdO1xuXG4gICAgbGV0IGdyYWRpZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsICdyYWRpYWxHcmFkaWVudCcpO1xuICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZSgnaWQnLCBpZCk7XG4gICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlKCdjeCcsICc1MCUnKTtcbiAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGUoJ2N5JywgJzUwJScpO1xuICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZSgncicsICc1MCUnKTtcblxuICAgIGRlZnMuYXBwZW5kQ2hpbGQoZ3JhZGllbnQpO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8bnVtYmVyT2ZTdG9wcztpKyspIHtcbiAgICAgIGxldCBzdG9wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsICdzdG9wJyk7XG4gICAgICBzdG9wLnNldEF0dHJpYnV0ZSgnaWQnLCAnc3RvcCcraSk7XG4gICAgICAvL3N0b3Auc2V0QXR0cmlidXRlKCdvZmZzZXQnLCAnNzAlJyk7XG4gICAgICAvL3N0b3Auc2V0QXR0cmlidXRlKCdzdG9wLWNvbG9yJywgJ1doaXRlJyk7XG4gICAgICBncmFkaWVudC5hcHBlbmRDaGlsZChzdG9wKTtcbiAgICAgIHN0b3BzLnB1c2goc3RvcCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBpZCxcbiAgICAgIHN0b3BzOiBzdG9wcyxcbiAgICAgIGVsZW1lbnQ6IGdyYWRpZW50XG4gICAgfTtcblxuICB9XG5cbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvdXRpbC9zdmcuanMiLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogTGltaXQgYSBudW1iZXIgdG8gd2l0aGluIGEgbWluaW11bSBhbmQgbWF4aW11bVxuICogQHBhcmFtICB7bnVtYmVyfSB2YWx1ZSBJbnB1dCB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBtaW4gICBMb3dlciBsaW1pdFxuICogQHBhcmFtICB7bnVtYmVyfSBtYXggICBVcHBlciBsaW1pdFxuICogQHJldHVybiB7bnVtYmVyfSAgICAgICBUaGUgaW5wdXQgdmFsdWUgY29uc3RyYWluZWQgd2l0aGluIHRoZSBsb3dlciBhbmQgdXBwZXIgbGltaXRzXG4gKiBAZXhhbXBsZVxuICogTmV4dXMuY2xpcCgxMSwwLDEwKSAgIC8vIHJldHVybnMgMTBcbiAqIE5leHVzLmNsaXAoLTEsMCwxMCkgICAvLyByZXR1cm5zIDBcbiAqIE5leHVzLmNsaXAoNSwwLDEwKSAgICAvLyByZXR1cm5zIDVcbiAqL1xuXG5leHBvcnRzLmNsaXAgPSAodmFsdWUsbWluLG1heCkgPT4ge1xuICByZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgodmFsdWUsbWluKSxtYXgpO1xufTtcblxuZXhwb3J0cy5ub3JtYWxpemUgPSAodmFsdWUsbWluLG1heCkgPT4ge1xuICByZXR1cm4gKCAodmFsdWUtbWluKSAvIChtYXgtbWluKSApO1xufTtcblxuLyoqXG4gKiBTY2FsZSBhIHZhbHVlIGZyb20gb25lIHJhbmdlIHRvIGFub3RoZXIgcmFuZ2UuXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGluTnVtICBJbnB1dCB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBpbk1pbiAgSW5wdXQgcmFuZ2UgbWluaW11bVxuICogQHBhcmFtICB7bnVtYmVyfSBpbk1heCAgSW5wdXQgcmFuZ2UgbWF4aW11bVxuICogQHBhcmFtICB7bnVtYmVyfSBvdXRNaW4gT3V0cHV0IHJhbmdlIG1pbmltdW1cbiAqIEBwYXJhbSAge251bWJlcn0gb3V0TWF4IE91dHB1dCByYW5nZSBtYXhpbXVtXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgICBUaGUgaW5wdXQgdmFsdWUgc2NhbGVkIHRvIGl0cyBuZXcgcmFuZ2VcbiAqIEBleGFtcGxlXG4gKiBOZXh1cy5zY2FsZSgwLjUsMCwxLDAsMTApICAgLy8gcmV0dXJucyA1XG4gKiBOZXh1cy5zY2FsZSgwLjksMCwxLDEsMCkgICAgLy8gcmV0dXJucyAwLjFcbiAqL1xuZXhwb3J0cy5zY2FsZSA9IChpbk51bSwgaW5NaW4sIGluTWF4LCBvdXRNaW4sIG91dE1heCkgPT4ge1xuICBpZiAoaW5NaW4gPT09IGluTWF4KSB7XG4gICAgcmV0dXJuIG91dE1pbjtcbiAgfVxuICByZXR1cm4gKCgoaW5OdW0gLSBpbk1pbikgKiAob3V0TWF4IC0gb3V0TWluKSkgLyAoaW5NYXggLSBpbk1pbikpICsgb3V0TWluO1xufTtcblxuZXhwb3J0cy50b1BvbGFyID0gKHgseSkgPT4ge1xuICB2YXIgciA9IE1hdGguc3FydCh4KnggKyB5KnkpO1xuXG4gIHZhciB0aGV0YSA9IE1hdGguYXRhbjIoeSx4KTtcbiAgaWYgKHRoZXRhIDwgMCkge1xuICAgIHRoZXRhID0gdGhldGEgKyAoMiAqIE1hdGguUEkpO1xuICB9XG4gIHJldHVybiB7cmFkaXVzOiByLCBhbmdsZTogdGhldGF9O1xufTtcblxuZXhwb3J0cy50b0NhcnRlc2lhbiA9IGZ1bmN0aW9uKHJhZGl1cywgYW5nbGUpe1xuICB2YXIgY29zID0gTWF0aC5jb3MoYW5nbGUpO1xuICB2YXIgc2luID0gTWF0aC5zaW4oYW5nbGUpO1xuICByZXR1cm4ge3g6IHJhZGl1cypjb3MsIHk6IHJhZGl1cypzaW4qLTF9O1xufTtcbi8qXG5leHBvcnRzLnBvbGFyVG9DYXJ0ZXNpYW4oY2VudGVyWCwgY2VudGVyWSwgcmFkaXVzLCBhbmdsZUluRGVncmVlcykge1xuICB2YXIgYW5nbGVJblJhZGlhbnMgPSAoYW5nbGVJbkRlZ3JlZXMtOTApICogTWF0aC5QSSAvIDE4MC4wO1xuXG4gIHJldHVybiB7XG4gICAgeDogY2VudGVyWCArIChyYWRpdXMgKiBNYXRoLmNvcyhhbmdsZUluUmFkaWFucykpLFxuICAgIHk6IGNlbnRlclkgKyAocmFkaXVzICogTWF0aC5zaW4oYW5nbGVJblJhZGlhbnMpKVxuICB9O1xufSAgKi9cblxuXG5cbmV4cG9ydHMucHJ1bmUgPSBmdW5jdGlvbihkYXRhLCBzY2FsZSkge1xuICByZXR1cm4gcGFyc2VGbG9hdChkYXRhLnRvRml4ZWQoc2NhbGUpKTtcbn07XG5cbmV4cG9ydHMuaW52ZXJ0ID0gZnVuY3Rpb24gKGluTnVtKSB7XG4gIHJldHVybiBleHBvcnRzLnNjYWxlKGluTnVtLCAxLCAwLCAwLCAxKTtcbn07XG5cbi8qKlxuICogQ29udmVydCBhIE1JRGkgbm90ZSBudW1iZXIgdG8gYSBmcmVxdWVuY3kgdmFsdWUgaW4gZXF1YWwgdGVtcGVyYW1lbnQuXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG1pZGkgTUlESSBub3RlIHZhbHVlXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgRnJlcXVlbmNlIHZhbHVlXG4gKiBAZXhhbXBsZVxuICogTmV4dXMubXRvZig2MCkgIC8vIHJldHVybnMgdGhlIGZyZXF1ZW5jeSBudW1iZXIgb2YgTWlkZGxlIENcbiAqL1xuZXhwb3J0cy5tdG9mID0gZnVuY3Rpb24obWlkaSkge1xuICByZXR1cm4gTWF0aC5wb3coMiwgKChtaWRpLTY5KS8xMikpICogNDQwO1xufTtcblxuLyoqXG4gKiBJbnRlcnBvbGF0ZSBiZXR3ZWVuIHR3byBudW1iZXJzXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGxvYyBJbnRlcnBvbGF0aW9uIGluZGV4ICgwLTEpXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG1pbiBMb3dlciB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBtYXggVXBwZXIgdmFsdWVcbiAqIEByZXR1cm4ge251bWJlcn0gICAgIEludGVycG9sYXRlZCB2YWx1ZVxuICogQGV4YW1wbGVcbiAqIE5leHVzLmludGVycCgwLjUsMiw0KSAgIC8vIHJldHVybnMgM1xuICogTmV4dXMuaW50ZXJwKDAuMSwwLDEwKSAgICAgLy8gcmV0dXJucyAxXG4gKi9cbmV4cG9ydHMuaW50ZXJwID0gZnVuY3Rpb24obG9jLG1pbixtYXgpIHtcbiAgcmV0dXJuIGxvYyAqIChtYXggLSBtaW4pICsgbWluO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYSByYW5kb20gY2hvaWNlIGZyb20gYSBsaXN0IG9mIGFyZ3VtZW50c1xuICogQHJldHVybiB7dmFyaW91c30gT25lIHJhbmRvbSBhcmd1bWVudFxuICogQGV4YW1wbGVcbiAqIE5leHVzLnBpY2soMSwyLDMsNCkgICAvLyByZXR1cm5zIDEsIDIsIDMsIG9yIDRcbiAqIE5leHVzLnBpY2soZnVuY3Rpb24xLGZ1bmN0aW9uMikgICAvLyByZXR1cm5zIGVpdGhlciBmdW5jdGlvbjEgb3IgZnVuY3Rpb24yXG4gKi9cbmV4cG9ydHMucGljayA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gYXJndW1lbnRzW35+KE1hdGgucmFuZG9tKCkqYXJndW1lbnRzLmxlbmd0aCldO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGFuIG9jdGF2ZSBtdWx0aXBsaWVyIGZvciBmcmVxdWVuY3kgdmFsdWVzXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG51bSBSZWxhdGl2ZSBvY3RhdmUgbnVtYmVyIChlLmcuIC0xIGZvciBvbmUgb2N0YXZlIGRvd24sIDEgZm9yIG9uZSBvY3RhdmUgdXApXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICBPY3RhdmUgbXVsdGlwbGllclxuICogQGV4YW1wbGVcbiAqIE5leHVzLm9jdGF2ZSgtMSkgIC8vIHJldHVybnMgMC41XG4gKiBOZXh1cy5vY3RhdmUoMCkgICAvLyByZXR1cm5zIDFcbiAqIE5leHVzLm9jdGF2ZSgxKSAgIC8vIHJldHVybnMgMlxuICogTmV4dXMub2N0YXZlKDIpICAgLy8gcmV0dXJucyA0XG4gKi9cbmV4cG9ydHMub2N0YXZlID0gZnVuY3Rpb24obnVtKSB7XG4gIHJldHVybiBNYXRoLnBvdygyLG51bSk7XG59O1xuXG4vKipcbiAqIFJhbmRvbSBpbnRlZ2VyIGdlbmVyYXRvci4gSWYgbm8gc2Vjb25kIGFyZ3VtZW50IGlzIGdpdmVuLCB3aWxsIHJldHVybiByYW5kb20gaW50ZWdlciBmcm9tIDAgdG8gYm91bmQxLlxuICogQHBhcmFtICB7bnVtYmVyfSBib3VuZDEgTWluaW11bSByYW5kb20gdmFsdWVcbiAqIEBwYXJhbSAge251bWJlcn0gYm91bmQyIE1heGltdW0gcmFuZG9tIHZhbHVlXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgICBSYW5kb20gaW50ZWdlciBiZXR3ZWVuIGxvd2VyIGFuZCB1cHBlciBib3VuZGFyeVxuICogQGV4YW1wbGVcbiAqIE5leHVzLnJpKDEwKSAgICAvLyByZXR1cm5zIHJhbmRvbSBpbnQgZnJvbSAwIHRvIDEwXG4gKiBOZXh1cy5yaSgyMCwyMDAwKSAvLyByZXR1cm5zIHJhbmRvbSBpbnQgZnJvbSAyMCB0byAyMDAwXG4gKi9cbmV4cG9ydHMucmkgPSBmdW5jdGlvbihib3VuZDEsYm91bmQyKSB7XG4gIGlmICghYm91bmQyKSB7XG4gICAgYm91bmQyID0gYm91bmQxO1xuICAgIGJvdW5kMSA9IDA7XG4gIH1cbiAgdmFyIGxvdyA9IE1hdGgubWluKGJvdW5kMSxib3VuZDIpO1xuICB2YXIgaGlnaCA9IE1hdGgubWF4KGJvdW5kMSxib3VuZDIpO1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpKihoaWdoLWxvdykrbG93KTtcbn07XG5cbi8qKlxuICogUmFuZG9tIGZsb2F0IG51bWJlciBnZW5lcmF0b3IuIElmIG5vIHNlY29uZCBhcmd1bWVudCBpcyBnaXZlbiwgd2lsbCByZXR1cm4gcmFuZG9tIGZsb2F0IGZyb20gMCB0byBib3VuZDEuXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGJvdW5kMSBNaW5pbXVtIHJhbmRvbSB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBib3VuZDIgTWF4aW11bSByYW5kb20gdmFsdWVcbiAqIEByZXR1cm4ge251bWJlcn0gICAgICAgIFJhbmRvbSBmbG9hdCBiZXR3ZWVuIGxvd2VyIGFuZCB1cHBlciBib3VuZGFyeVxuICogQGV4YW1wbGVcbiAqIE5leHVzLnJmKDEpICAgIC8vIHJldHVybnMgcmFuZG9tIGZsb2F0IGZyb20gMCB0byAxXG4gKiBOZXh1cy5yZigxLDIpIC8vIHJldHVybnMgcmFuZG9tIGZsb2F0IGZyb20gMSB0byAyXG4gKi9cbmV4cG9ydHMucmYgPSBmdW5jdGlvbihib3VuZDEsYm91bmQyKSB7XG4gIGlmICghYm91bmQyKSB7XG4gICAgYm91bmQyID0gYm91bmQxO1xuICAgIGJvdW5kMSA9IDA7XG4gIH1cbiAgdmFyIGxvdyA9IE1hdGgubWluKGJvdW5kMSxib3VuZDIpO1xuICB2YXIgaGlnaCA9IE1hdGgubWF4KGJvdW5kMSxib3VuZDIpO1xuICByZXR1cm4gTWF0aC5yYW5kb20oKSooaGlnaC1sb3cpK2xvdztcbn07XG5cblxuZXhwb3J0cy5jeWNsZSA9IGZ1bmN0aW9uKGlucHV0LG1pbixtYXgpIHtcbiAgaW5wdXQrKztcbiAgaWYgKGlucHV0ID49IG1heCkge1xuICAgIGlucHV0ID0gbWluO1xuICB9XG4gIHJldHVybiBpbnB1dDtcbn07XG5cbi8qKlxuICogQXZlcmFnZSBhbiBhcnJheSBvZiBudW1iZXJzXG4gKiBAcGFyYW0gIHtBcnJheX0gZGF0YSBBcnJheSBvZiBudW1iZXJzIHRvIGF2ZXJhZ2VcbiAqIEByZXR1cm4ge251bWJlcn0gICAgICBBdmVyYWdlIG9mIHRoZSBpbnB1dCBkYXRhXG4gKiBAZXhhbXBsZVxuICogTmV4dXMuYXZlcmFnZShbMCwyLDQsNiw4LDEwXSkgICAvLyByZXR1cm5zIDVcbiAqL1xuZXhwb3J0cy5hdmVyYWdlID0gZnVuY3Rpb24oZGF0YSkge1xuICBsZXQgdG90YWwgPSAwO1xuICBmb3IgKHZhciBpPTA7aTxkYXRhLmxlbmd0aDtpKyspIHtcbiAgICB0b3RhbCArPSBkYXRhW2ldO1xuICB9XG4gIHJldHVybiB0b3RhbCAvIGRhdGEubGVuZ3RoO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGRpc3RhbmNlIGZyb20gb25lICh4LHkpIHBvaW50IHRvIGFub3RoZXIgKHgseSkgcG9pbnRcbiAqIEBwYXJhbSAge251bWJlcn0geDEgeCBvZiBmaXJzdCBwb2ludFxuICogQHBhcmFtICB7bnVtYmVyfSB5MSB5IG9mIGZpcnN0IHBvaW50XG4gKiBAcGFyYW0gIHtudW1iZXJ9IHgyIHggb2Ygc2Vjb25kIHBvaW50XG4gKiBAcGFyYW0gIHtudW1iZXJ9IHkyIHkgb2Ygc2Vjb25kIHBvaW55XG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgIERpc3RhbmNlXG4gKiBAZXhhbXBsZVxuICogTmV4dXMuZGlzdGFuY2UoMCwwLDMsNCkgICAvLyByZXR1cm5zIDVcbiAqL1xuZXhwb3J0cy5kaXN0YW5jZSA9IGZ1bmN0aW9uKHgxLHkxLHgyLHkyKSB7XG4gIGxldCBhID0geDEgLSB4MjtcbiAgbGV0IGIgPSB5MSAtIHkyO1xuICByZXR1cm4gTWF0aC5zcXJ0KCBhKmEgKyBiKmIgKTtcbn07XG5cbmV4cG9ydHMuZ2FpblRvREIgPSBmdW5jdGlvbihnYWluKSB7XG4gIHJldHVybiAyMCAqIE1hdGgubG9nMTAoZ2Fpbik7XG59O1xuXG4vKipcbiAqIEZsaXAgYSBjb2luLCByZXR1cm5pbmcgZWl0aGVyIDAgb3IgMSBhY2NvcmRpbmcgdG8gYSBwcm9iYWJpbGl0eVxuICogQHBhcmFtICB7bnVtYmVyfSBbb2Rkcz0wLjVdIExpa2VsaWhvb2Qgb2YgcmV0dXJuaW5nIDFcbiAqIEByZXR1cm4ge251bWJlcn0gICAgICAgICAgICAxIG9yIDBcbiAqIEBleGFtcGxlXG4gKiBOZXh1cy5jb2luKDAuMSkgICAvLyByZXR1cm5zIDEgKDEwJSBvZiB0aGUgdGltZSkgb3IgMCAoOTAlIG9mIHRoZSB0aW1lKVxuICovXG5leHBvcnRzLmNvaW4gPSBmdW5jdGlvbihvZGRzPTAuNSkge1xuICBpZiAoZXhwb3J0cy5yZigwLDEpIDwgb2Rkcykge1xuICAgIHJldHVybiAxO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAwO1xuICB9XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3V0aWwvbWF0aC5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgZG9tID0gcmVxdWlyZSgnLi4vdXRpbC9kb20nKTtcbmxldCB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbC91dGlsJyk7XG5sZXQgdG91Y2ggPSByZXF1aXJlKCcuLi91dGlsL3RvdWNoJyk7XG5jb25zdCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKTtcblxuaW1wb3J0IHsgY29sb3JzIH0gZnJvbSAnLi4vbWFpbic7XG5cbi8qKlxuSW50ZXJmYWNlXG4qL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSW50ZXJmYWNlIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcblxuICBjb25zdHJ1Y3RvcihhcmdzLG9wdGlvbnMsZGVmYXVsdHMpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMudHlwZSA9IHRoaXMuY29uc3RydWN0b3IubmFtZTtcbiAgICB0aGlzLnNldHRpbmdzID0gdGhpcy5wYXJzZVNldHRpbmdzKGFyZ3Msb3B0aW9ucyxkZWZhdWx0cyk7XG4gICAgdGhpcy5tb3VzZSA9IHt9O1xuICAgIHRoaXMud2FpdCA9IGZhbHNlO1xuICAgIHRoaXMuY29sb3JzID0ge307XG4gICAgbGV0IGRlZmF1bHRDb2xvcnMgPSBjb2xvcnMoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gICAgdGhpcy5jb2xvcnMuYWNjZW50ID0gZGVmYXVsdENvbG9ycy5hY2NlbnQ7XG4gICAgdGhpcy5jb2xvcnMuZmlsbCA9IGRlZmF1bHRDb2xvcnMuZmlsbDtcbiAgICB0aGlzLmNvbG9ycy5saWdodCA9IGRlZmF1bHRDb2xvcnMubGlnaHQ7XG4gICAgdGhpcy5jb2xvcnMuZGFyayA9IGRlZmF1bHRDb2xvcnMuZGFyaztcbiAgICB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCA9IGRlZmF1bHRDb2xvcnMubWVkaXVtTGlnaHQ7XG4gICAgdGhpcy5jb2xvcnMubWVkaXVtRGFyayA9IGRlZmF1bHRDb2xvcnMubWVkaXVtRGFyaztcbiAgfVxuXG4gIHBhcnNlU2V0dGluZ3MoYXJncyxvcHRpb25zLGRlZmF1bHRzKSB7XG5cbiAgICBvcHRpb25zLnVuc2hpZnQoJ3RhcmdldCcpO1xuICAgIGRlZmF1bHRzLmRlZmF1bHRTaXplID0gZGVmYXVsdHMuc2l6ZS5zcGxpY2UoMCwyKTtcbiAgICBkZWZhdWx0cy5zaXplID0gZmFsc2U7XG5cbiAgICBsZXQgc2V0dGluZ3MgPSB7XG4gICAgICAndGFyZ2V0JzogZG9jdW1lbnQuYm9keSxcbiAgICAgICdjb2xvcnMnOiB7fSwgLy8gc2hvdWxkIGluaGVyaXQgZnJvbSBhIGNvbG9ycyBtb2R1bGUsXG4gICAgICAnc25hcFdpdGhQYXJlbnQnOiB0cnVlLFxuICAgICAgJ2V2ZW50JzogZnVuY3Rpb24oKSB7fSxcbiAgICAgICdjb21wb25lbnQnOiBmYWxzZVxuICAgIH07XG5cbiAgICBmb3IgKGxldCBrZXkgaW4gZGVmYXVsdHMpIHtcbiAgICAgIHNldHRpbmdzW2tleV0gPSBkZWZhdWx0c1trZXldO1xuICAgIH1cblxuICAgIGZvciAobGV0IGk9MDsgaTxhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBncmFicyB0aGUgbmV4dCBhcmd1bWVudFxuICAgICAgbGV0IHNldHRpbmcgPSBhcmdzW2ldO1xuICAgICAgLy8gaWYgaXQncyBhbiBvYmplY3QsIGl0IG11c3QgYmUgdGhlIHNldHRpbmdzIG9iamVjdFxuICAgICAgaWYgKCB1dGlsLmlzT2JqZWN0KHNldHRpbmcpICkge1xuICAgICAgICBmb3IgKCBsZXQga2V5IGluIHNldHRpbmcgKSB7XG4gICAgICAgICAgc2V0dGluZ3Nba2V5XSA9IHNldHRpbmdba2V5XTtcbiAgICAgICAgfVxuICAgICAgLy8gaWYgaXQncyBhIGZ1bmN0aW9uLCBpdCBtdXN0IGJlIHRoZSBldmVudCBzZXR0aW5nXG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXR0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHNldHRpbmdzLmV2ZW50ID0gc2V0dGluZztcbiAgICAgIC8vIG90aGVyd2lzZSwgY29uc2lkZXIgaXQgb25lIG9mIHRoZSB3aWRnZXQncyBjdXN0b20gb3B0aW9uc1xuICAgICAgfSBlbHNlIGlmIChvcHRpb25zLmxlbmd0aD49MSkge1xuICAgICAgICAvLyBncmFiIHRoZSBmaXJzdCBvcHRpb24gLS0gaS5lLiAndGFyZ2V0J1xuICAgICAgICBsZXQga2V5ID0gb3B0aW9ucy5zcGxpY2UoMCwxKVswXTtcbiAgICAgICAgc2V0dGluZ3Nba2V5XSA9IHNldHRpbmc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyogIGhhbmRsZSBjb21tb24gc2V0dGluZ3MgICovXG5cbiAgICAvLyB0YXJnZXRcbiAgICB0aGlzLnBhcmVudCA9IGRvbS5wYXJzZUVsZW1lbnQoc2V0dGluZ3MudGFyZ2V0KTtcblxuICAgIC8vIG5leHVzLXVpIGF0dHJpYnV0ZVxuICAgIGlmICh0aGlzLnBhcmVudCAmJiB0aGlzLnBhcmVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmICFzZXR0aW5ncy5jb21wb25lbnQpIHtcbiAgICAgIGlmICghdGhpcy5wYXJlbnQuaGFzQXR0cmlidXRlKCduZXh1cy11aScpKSB7XG4gICAgICAgIHRoaXMucGFyZW50LnNldEF0dHJpYnV0ZSgnbmV4dXMtdWknLCcnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzaXplXG5cbiAgICBpZiAoc2V0dGluZ3Muc2l6ZSAmJiBBcnJheS5pc0FycmF5KHNldHRpbmdzLnNpemUpICYmIHNldHRpbmdzLnNuYXBXaXRoUGFyZW50KSB7XG4gICAgICB0aGlzLndpZHRoID0gc2V0dGluZ3Muc2l6ZVswXTtcbiAgICAgIHRoaXMuaGVpZ2h0ID0gc2V0dGluZ3Muc2l6ZVsxXTtcbiAgICAgIHRoaXMucGFyZW50LnN0eWxlLndpZHRoID0gdGhpcy53aWR0aCArICdweCc7XG4gICAgICB0aGlzLnBhcmVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmhlaWdodCArICdweCc7XG4gICAgfSBlbHNlIGlmIChzZXR0aW5ncy5zbmFwV2l0aFBhcmVudCAmJiAhc2V0dGluZ3MuY29tcG9uZW50KSB7XG5cbiAgICAgIHRoaXMud2lkdGggPSBwYXJzZUZsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMucGFyZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCd3aWR0aCcpLnJlcGxhY2UoJ3B4JywnJykpO1xuICAgICAgdGhpcy5oZWlnaHQgPSBwYXJzZUZsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMucGFyZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCdoZWlnaHQnKS5yZXBsYWNlKCdweCcsJycpKTtcblxuICAgICAgaWYgKHRoaXMud2lkdGg9PTUwMDApIHtcbiAgICAgICAgdGhpcy53aWR0aCA9IHNldHRpbmdzLmRlZmF1bHRTaXplWzBdO1xuICAgICAgICB0aGlzLnBhcmVudC5zdHlsZS53aWR0aCA9IHRoaXMucGFyZW50LndpZHRoID0gdGhpcy53aWR0aCArICdweCc7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5oZWlnaHQ9PTUwMDApIHtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBzZXR0aW5ncy5kZWZhdWx0U2l6ZVsxXTtcbiAgICAgICAgdGhpcy5wYXJlbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5wYXJlbnQuaGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyAncHgnO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIHNldHRpbmdzLnNpemUgPSBzZXR0aW5ncy5kZWZhdWx0U2l6ZTtcbiAgICAgIHRoaXMud2lkdGggPSBzZXR0aW5ncy5zaXplWzBdO1xuICAgICAgdGhpcy5oZWlnaHQgPSBzZXR0aW5ncy5zaXplWzFdO1xuICAgIH1cblxuICAgIC8vIGV2ZW50XG4gICAgaWYgKHNldHRpbmdzLmV2ZW50KSB7XG4gICAgICB0aGlzLmV2ZW50ID0gdGhpcy5vbignY2hhbmdlJywgc2V0dGluZ3MuZXZlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmV2ZW50ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNldHRpbmdzO1xuXG4gIH1cblxuICBpbml0KCkge1xuICAgIHRoaXMuYnVpbGRGcmFtZSgpO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgICB0aGlzLnNpemVJbnRlcmZhY2UoKTtcbiAgICB0aGlzLmF0dGFjaExpc3RlbmVycygpO1xuICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcbiAgICB0aGlzLmZpbmFsVG91Y2hlcygpO1xuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge31cbiAgc2l6ZUludGVyZmFjZSgpIHt9XG4gIGNvbG9ySW50ZXJmYWNlKCkge31cblxuICBhdHRhY2hMaXN0ZW5lcnMoKSB7XG5cbiAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0ID0gdGhpcy5pbnRlcmFjdGlvblRhcmdldCB8fCB0aGlzLmVsZW1lbnQ7XG5cbiAgICAvLyBTZXR1cCBpbnRlcmFjdGlvblxuICAgIGlmICh0b3VjaC5leGlzdHMpIHtcbiAgICAgIHRoaXMuaW50ZXJhY3Rpb25UYXJnZXQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGV2dCA9PiB0aGlzLnByZVRvdWNoKGV2dCkpO1xuICAgICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCBldnQgPT4gdGhpcy5wcmVUb3VjaE1vdmUoZXZ0KSk7XG4gICAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgZXZ0ID0+IHRoaXMucHJlVG91Y2hSZWxlYXNlKGV2dCkpO1xuICAgIH1cbiAgICB0aGlzLmJvdW5kUHJlTW92ZSA9IGV2dCA9PiB0aGlzLnByZU1vdmUoZXZ0KTtcbiAgICB0aGlzLmJvdW5kUHJlUmVsZWFzZSA9IGV2dCA9PiB0aGlzLnByZVJlbGVhc2UoZXZ0KTtcbiAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGV2dCA9PiB0aGlzLnByZUNsaWNrKGV2dCkpO1xuICB9XG5cbiAgZmluYWxUb3VjaGVzKCkge1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5jdXJzb3IgPSAncG9pbnRlcic7XG4gIH1cblxuICBwcmVDbGljayhlKSB7XG4gICAgLy8gMTAwMDAgZ2V0Q29tcHV0ZWRTdHlsZSBjYWxscyB0YWtlcyAxMDAgbXMuXG4gICAgLy8gLjouIG9uZSB0YWtlcyBhYm91dCAuMDFtc1xuICAgIGlmICh0aGlzLmVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgdGhpcy53aWR0aCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuZWxlbWVudCwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZSgnd2lkdGgnKS5yZXBsYWNlKCdweCcsJycpO1xuICAgIH1cbiAgICAvLyAxMDAwMCBnZXRDb21wdXRlZFN0eWxlIGNhbGxzIHRha2VzIDQwIG1zLlxuICAgIC8vIC46LiBvbmUgdGFrZXMgYWJvdXQgLjAwNG1zXG4gICAgdGhpcy5vZmZzZXQgPSBkb20uZmluZFBvc2l0aW9uKHRoaXMuZWxlbWVudCk7XG4gICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVNb3VzZShlLHRoaXMub2Zmc2V0KTtcbiAgICB0aGlzLmNsaWNrZWQgPSB0cnVlO1xuICAgIHRoaXMuY2xpY2soKTtcbiAgICB0aGlzLm1vdmVFdmVudCA9IGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuYm91bmRQcmVNb3ZlKTtcbiAgICB0aGlzLnJlbGVhc2VFdmVudCA9IGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLmJvdW5kUHJlUmVsZWFzZSk7XG4gICAgdGhpcy5lbWl0KCdjbGljaycpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgcHJlTW92ZShlKSB7XG4gICAgaWYgKCF0aGlzLndhaXQpIHtcbiAgICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSx0aGlzLm9mZnNldCk7XG4gICAgICB0aGlzLm1vdmUoKTtcbiAgICAgIHRoaXMud2FpdCA9IHRydWU7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHsgdGhpcy53YWl0ID0gZmFsc2U7IH0sMjUpO1xuICAgIH1cbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHByZVJlbGVhc2UoZSkge1xuICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSx0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG4gICAgdGhpcy5yZWxlYXNlKCk7XG4gICAgdGhpcy5lbWl0KCdyZWxlYXNlJyk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJyx0aGlzLmJvdW5kUHJlTW92ZSk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsdGhpcy5ib3VuZFByZVJlbGVhc2UpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgY2xpY2soKSB7XG5cbiAgfVxuXG4gIG1vdmUoKSB7XG5cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG5cbiAgfVxuXG5cbiAgLyogdG91Y2ggKi9cblxuICBwcmVUb3VjaChlKSB7XG4gICAgaWYgKHRoaXMuZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICB0aGlzLndpZHRoID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbGVtZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCd3aWR0aCcpLnJlcGxhY2UoJ3B4JywnJyk7XG4gICAgfVxuICAgIHRoaXMub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbih0aGlzLmVsZW1lbnQpO1xuICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlVG91Y2goZSx0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5jbGlja2VkID0gdHJ1ZTtcbiAgICB0aGlzLnRvdWNoKGUpO1xuICAgIHRoaXMuZW1pdCgnY2xpY2snKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHByZVRvdWNoTW92ZShlKSB7XG4gICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVUb3VjaChlLHRoaXMub2Zmc2V0KTtcbiAgICAgIHRoaXMudG91Y2hNb3ZlKCk7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIHByZVRvdWNoUmVsZWFzZShlKSB7XG4gICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVUb3VjaChlLCB0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG4gICAgdGhpcy50b3VjaFJlbGVhc2UoKTtcbiAgICB0aGlzLmVtaXQoJ3JlbGVhc2UnKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHRvdWNoKCkge1xuICAgIHRoaXMuY2xpY2soKTtcbiAgfVxuXG4gIHRvdWNoTW92ZSgpIHtcbiAgICB0aGlzLm1vdmUoKTtcbiAgfVxuXG4gIHRvdWNoUmVsZWFzZSgpIHtcbiAgICB0aGlzLnJlbGVhc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFJlc2l6ZSB0aGUgaW50ZXJmYWNlXG4gICogQHBhcmFtIHdpZHRoIHtudW1iZXJ9IE5ldyB3aWR0aCBpbiBwaXhlbHNcbiAgKiBAcGFyYW0gaGVpZ2h0IHtudW1iZXJ9IE5ldyBoZWlnaHQgaW4gcGl4ZWxzXG4gICpcbiAgKiBAZXhhbXBsZVxuICAqIGJ1dHRvbi5yZXNpemUoMTAwLDEwMCk7XG4gICovXG4gIHJlc2l6ZSh3aWR0aCxoZWlnaHQpIHtcbiAgICB0aGlzLndpZHRoID0gd2lkdGg7XG4gICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgdGhpcy5wYXJlbnQuc3R5bGUud2lkdGggPSB0aGlzLndpZHRoKydweCc7XG4gICAgdGhpcy5wYXJlbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5oZWlnaHQrJ3B4JztcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG4gIH1cblxuICBlbXB0eSgpIHtcbiAgICB3aGlsZSAodGhpcy5lbGVtZW50Lmxhc3RDaGlsZCkge1xuICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudC5sYXN0Q2hpbGQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAqIFJlbW92ZSB0aGUgaW50ZXJmYWNlIGZyb20gdGhlIHBhZ2UgYW5kIGNhbmNlbCBpdHMgZXZlbnQgbGlzdGVuZXIocykuXG4gICpcbiAgKiBAZXhhbXBsZVxuICAqIGJ1dHRvbi5kZXN0cm95KCk7XG4gICovXG4gIGRlc3Ryb3koKSB7XG4gICAgdGhpcy5lbXB0eSgpO1xuICAgIHRoaXMucGFyZW50LnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudCk7XG4gICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICBpZiAodGhpcy5pbnN0cnVtZW50KSB7XG4gICAgICBkZWxldGUgdGhpcy5pbnN0cnVtZW50W3RoaXMuaWRdO1xuICAgIH1cbiAgICB0aGlzLmN1c3RvbURlc3Ryb3koKTtcbiAgfVxuXG4gIGN1c3RvbURlc3Ryb3koKSB7XG5cbiAgfVxuXG4gIGNvbG9yaXplKHR5cGUsY29sb3IpIHtcbiAgICB0aGlzLmNvbG9yc1t0eXBlXSA9IGNvbG9yO1xuICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvY29yZS9pbnRlcmZhY2UuanMiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuZmluZFBvc2l0aW9uID0gKGVsKSA9PiB7XG4gIGxldCB2aWV3cG9ydE9mZnNldCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBsZXQgdG9wID0gdmlld3BvcnRPZmZzZXQudG9wICsgd2luZG93LnNjcm9sbFk7XG4gIGxldCBsZWZ0ID0gdmlld3BvcnRPZmZzZXQubGVmdCArIHdpbmRvdy5zY3JvbGxYO1xuICByZXR1cm4ge3RvcCxsZWZ0fTtcbn07XG5cbmV4cG9ydHMucGFyc2VFbGVtZW50ID0gKHBhcmVudCkgPT4ge1xuICBpZiAodHlwZW9mIHBhcmVudCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChwYXJlbnQucmVwbGFjZSgnIycsJycpKTtcbiAgfVxuXG4gIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCB8fCBwYXJlbnQgaW5zdGFuY2VvZiBTVkdFbGVtZW50KXtcbiAgICByZXR1cm4gcGFyZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAnTm8gdmFsaWQgcGFyZW50IGFyZ3VtZW50JztcbiAgfVxufTtcblxuZXhwb3J0cy5sb2NhdGVNb3VzZSA9IChlLG9mZnNldCkgPT4ge1xuICByZXR1cm4ge1xuICAgIHg6IGUucGFnZVggLSBvZmZzZXQubGVmdCxcbiAgICB5OiBlLnBhZ2VZIC0gb2Zmc2V0LnRvcFxuICB9O1xufTtcblxuZXhwb3J0cy5sb2NhdGVUb3VjaCA9IChlLG9mZnNldCkgPT4ge1xuICByZXR1cm4ge1xuICAgIHg6IGUudGFyZ2V0VG91Y2hlcy5sZW5ndGggPyBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVggLSBvZmZzZXQubGVmdCA6IGZhbHNlLFxuICAgIHk6IGUudGFyZ2V0VG91Y2hlcy5sZW5ndGggPyBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVkgLSBvZmZzZXQudG9wIDogZmFsc2VcbiAgfTtcbn07XG5cbmV4cG9ydHMuU21hcnRDYW52YXMgPSBmdW5jdGlvbihwYXJlbnQpIHtcblxuICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgdGhpcy5jb250ZXh0ID0gdGhpcy5lbGVtZW50LmdldENvbnRleHQoJzJkJyk7XG4gIHBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXG4gIHRoaXMucmVzaXplID0gKHcsaCkgPT4ge1xuICAgIHRoaXMuZWxlbWVudC53aWR0aCA9IHcqMjtcbiAgICB0aGlzLmVsZW1lbnQuaGVpZ2h0ID0gaCoyO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9IHcrJ3B4JztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gaCsncHgnO1xuICB9O1xuXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3V0aWwvZG9tLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLmlzT2JqZWN0ID0gKG9iaikgPT4ge1xuICBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkob2JqKSAmJiBvYmogIT09IG51bGwgJiYgb2JqIGluc3RhbmNlb2YgU1ZHRWxlbWVudCA9PT0gZmFsc2UgJiYgb2JqIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgPT09IGZhbHNlICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi91dGlsL3V0aWwuanMiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuZXhpc3RzID0gKCdvbnRvdWNoc3RhcnQnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvdXRpbC90b3VjaC5qcyIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gIHRoaXMuX2V2ZW50cyA9IHRoaXMuX2V2ZW50cyB8fCB7fTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxuRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24obikge1xuICBpZiAoIWlzTnVtYmVyKG4pIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IFR5cGVFcnJvcignbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcbiAgICBpZiAoIXRoaXMuX2V2ZW50cy5lcnJvciB8fFxuICAgICAgICAoaXNPYmplY3QodGhpcy5fZXZlbnRzLmVycm9yKSAmJiAhdGhpcy5fZXZlbnRzLmVycm9yLmxlbmd0aCkpIHtcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuY2F1Z2h0LCB1bnNwZWNpZmllZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNVbmRlZmluZWQoaGFuZGxlcikpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgICBjYXNlIDE6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICBoYW5kbGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc09iamVjdChoYW5kbGVyKSkge1xuICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBtO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gIGlmICh0aGlzLl9ldmVudHMubmV3TGlzdGVuZXIpXG4gICAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG4gICAgICAgICAgICAgIGlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpID9cbiAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gIGVsc2UgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcbiAgZWxzZVxuICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFt0aGlzLl9ldmVudHNbdHlwZV0sIGxpc3RlbmVyXTtcblxuICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSAmJiAhdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCkge1xuICAgIGlmICghaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSkge1xuICAgICAgbSA9IHRoaXMuX21heExpc3RlbmVycztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGlmIChtICYmIG0gPiAwICYmIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGggPiBtKSB7XG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJyhub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5ICcgK1xuICAgICAgICAgICAgICAgICAgICAnbGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ1VzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO1xuICAgICAgaWYgKHR5cGVvZiBjb25zb2xlLnRyYWNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgaW4gSUUgMTBcbiAgICAgICAgY29uc29sZS50cmFjZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICB2YXIgZmlyZWQgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBnKCkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgZyk7XG5cbiAgICBpZiAoIWZpcmVkKSB7XG4gICAgICBmaXJlZCA9IHRydWU7XG4gICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfVxuXG4gIGcubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgdGhpcy5vbih0eXBlLCBnKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZmYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGxpc3QsIHBvc2l0aW9uLCBsZW5ndGgsIGk7XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgbGlzdCA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgbGVuZ3RoID0gbGlzdC5sZW5ndGg7XG4gIHBvc2l0aW9uID0gLTE7XG5cbiAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8XG4gICAgICAoaXNGdW5jdGlvbihsaXN0Lmxpc3RlbmVyKSAmJiBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuXG4gIH0gZWxzZSBpZiAoaXNPYmplY3QobGlzdCkpIHtcbiAgICBmb3IgKGkgPSBsZW5ndGg7IGktLSA+IDA7KSB7XG4gICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHxcbiAgICAgICAgICAobGlzdFtpXS5saXN0ZW5lciAmJiBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpc3Quc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBrZXksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gIGlmICghdGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChrZXkgaW4gdGhpcy5fZXZlbnRzKSB7XG4gICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGxpc3RlbmVycykpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gIH0gZWxzZSBpZiAobGlzdGVuZXJzKSB7XG4gICAgLy8gTElGTyBvcmRlclxuICAgIHdoaWxlIChsaXN0ZW5lcnMubGVuZ3RoKVxuICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbbGlzdGVuZXJzLmxlbmd0aCAtIDFdKTtcbiAgfVxuICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gW107XG4gIGVsc2UgaWYgKGlzRnVuY3Rpb24odGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICByZXQgPSBbdGhpcy5fZXZlbnRzW3R5cGVdXTtcbiAgZWxzZVxuICAgIHJldCA9IHRoaXMuX2V2ZW50c1t0eXBlXS5zbGljZSgpO1xuICByZXR1cm4gcmV0O1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24odHlwZSkge1xuICBpZiAodGhpcy5fZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgICBpZiAoaXNGdW5jdGlvbihldmxpc3RlbmVyKSlcbiAgICAgIHJldHVybiAxO1xuICAgIGVsc2UgaWYgKGV2bGlzdGVuZXIpXG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gIH1cbiAgcmV0dXJuIDA7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJDb3VudCh0eXBlKTtcbn07XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9ldmVudHMvZXZlbnRzLmpzXG4vLyBtb2R1bGUgaWQgPSAxMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG5cbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5cbi8qKlxuICBDcmVhdGVzIGEgc3RlcHBhYmxlIHZhbHVlIHdpdGggbWluaW11bSwgbWF4aW11bSwgYW5kIHN0ZXAgc2l6ZS4gVGhpcyBpcyB1c2VkIGluIG1hbnkgaW50ZXJmYWNlcyB0byBjb25zdHJpY3QgdGhlaXIgdmFsdWVzIHRvIGNlcnRhaW4gcmFuZ2VzLlxuICBAcGFyYW0ge251bWJlcn0gW21pbj0wXSBtaW5pbXVtXG4gIEBwYXJhbSB7bnVtYmVyfSBbbWF4PTFdIG1heGltdW1cbiAgQHBhcmFtIHtudW1iZXJ9IFtzdGVwPTBdXG4gIEBwYXJhbSB7bnVtYmVyfSBbdmFsdWU9MF0gaW5pdGlhbCB2YWx1ZVxuICBAcmV0dXJucyB7T2JqZWN0fSBTdGVwXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdGVwIHtcblxuICBjb25zdHJ1Y3RvcihtaW4gPSAwLG1heCA9IDEsc3RlcCA9IDAsdmFsdWUgPSAwKSB7XG4gICAgLy9PYmplY3QuYXNzaWduKHRoaXMse21pbixtYXgsc3RlcH0pO1xuICAgIC8vQ2Fubm90IHVzZSBPYmplY3QuYXNzaWduIGJlY2F1c2Ugbm90IHN1cHBvcnRlZCBpbiBTYWZhcmkuXG4gICAgLy9JIHdvdWxkIGV4cGVjdCBmb3IgQmFiZWwgdG8gdGFrZSBjYXJlIG9mIHRoaXMgYnV0IGl0IGlzIG5vdC5cbiAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICB0aGlzLm1heCA9IG1heDtcbiAgICB0aGlzLnN0ZXAgPSBzdGVwO1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmNoYW5nZWQgPSBmYWxzZTtcbiAgICB0aGlzLm9sZFZhbHVlID0gZmFsc2U7XG4gICAgdGhpcy51cGRhdGUodGhpcy52YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICBVcGRhdGUgd2l0aCBhIG5ldyB2YWx1ZS4gVGhlIHZhbHVlIHdpbGwgYmUgYXV0by1hZGp1c3RlZCB0byBmaXQgdGhlIG1pbi9tYXgvc3RlcC5cbiAgICBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAgKi9cblxuICB1cGRhdGUodmFsdWUpIHtcbiAgICBpZiAodGhpcy5zdGVwKSB7XG4gICAgICAvLyB0aGlzLnZhbHVlID0gbWF0aC5jbGlwKE1hdGgucm91bmQodmFsdWUgLyAodGhpcy5zdGVwKSkgKiB0aGlzLnN0ZXAsIHRoaXMubWluLHRoaXMubWF4KTtcbiAgICAgIHRoaXMudmFsdWUgPSBtYXRoLmNsaXAoTWF0aC5yb3VuZCgodmFsdWUtdGhpcy5taW4pIC8gKHRoaXMuc3RlcCkpICogdGhpcy5zdGVwICsgdGhpcy5taW4sIHRoaXMubWluLHRoaXMubWF4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52YWx1ZSA9IG1hdGguY2xpcCh2YWx1ZSx0aGlzLm1pbix0aGlzLm1heCk7XG4gICAgfVxuICAgIGlmICh0aGlzLm9sZFZhbHVlICE9PSB0aGlzLnZhbHVlKSB7XG4gICAgICB0aGlzLm9sZFZhbHVlID0gdGhpcy52YWx1ZTtcbiAgICAgIHRoaXMuY2hhbmdlZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hhbmdlZCA9IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgIFVwZGF0ZSB3aXRoIGEgbm9ybWFsaXplZCB2YWx1ZSAwLTEuXG4gICAgQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gICovXG4gIHVwZGF0ZU5vcm1hbCh2YWx1ZSkge1xuICAgIHRoaXMudmFsdWUgPSBtYXRoLnNjYWxlKHZhbHVlLDAsMSx0aGlzLm1pbix0aGlzLm1heCk7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlKHRoaXMudmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAgR2V0IGEgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIHRoaXMudmFsdWUgLiBOb3Qgc2V0dGFibGUuXG4gICovXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiBtYXRoLm5vcm1hbGl6ZSh0aGlzLnZhbHVlLHRoaXMubWluLHRoaXMubWF4KTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbW9kZWxzL3N0ZXAuanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5pbXBvcnQgVG9nZ2xlTW9kZWwgZnJvbSAnLi4vbW9kZWxzL3RvZ2dsZSc7XG5cblxuLypcbmhvdyB0byB1c2UgOlxuXG5kaWFsLmludGVyYWN0aW9uID0gbmV3IEhhbmRsZSgncmFkaWFsJywncmVsYXRpdmUnLHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpO1xuLy8gZGlhbC5pbnRlcmFjdGlvbi5tb2RlID0gJ3JlbGF0aXZlJ1xuLy8gZGlhbC5pbnRlcmFjdGlvbi5kaXJlY3Rpb24gPSAncmFkaWFsJ1xuXG5vbiBjbGljazpcbmRpYWwuaW50ZXJhY3Rpb24uYW5jaG9yID0gdGhpcy5tb3VzZTtcblxub24gbW92ZTpcbmRpYWwuaW50ZXJhY3Rpb24udXBkYXRlKHRoaXMubW91c2UpO1xuXG5jb25zb2xlLmxvZyggZGlhbC5pbnRlcmFjdGlvbi52YWx1ZSApOyBzaG91bGQgYmUgYSBub3JtYWxpemVkIHZhbHVlLlxuXG4qL1xuXG4vKlxuICBhYnNvbHV0ZS9yZWxhdGl2ZSBhcmUgcHJvcGVydHk6IG1vZGVcbiAgcmFkaWFsL3ZlcnRpY2FsL2hvcml6b250YWwvMmQgYXJlIHByb3BlcnR5OiBkaXJlY3Rpb25cblxuICBwbGFuIDpcblxuICBpZiByZWxhdGl2ZSAtLVxuICBOTyBvbiBjbGljaywgZ2V0IHZhbHVlIG9mZnNldCBiZXR3ZWVuIGN1cnJlbnQgdmFsdWUgYW5kIGNsaWNrIHZhbHVlLlxuICBOTyBvbiBtb3ZlLCB1c2UgY2xpY2sgdmFsdWUgLSBvZmZzZXRcbiAgSU5TVEVBRFxuICB1c2UgZGVsdGEgLS0gYmMgdmVydGljYWwgbW90aW9uIG9uIGRpYWwgaXMgaW1wb3NzaWJsZSBvdGhlcndpc2VcbiAgYWxzbyBhbGxvdyB0byBzZXQgc2Vuc2l0aXZpdHlcblxuKi9cblxuZXhwb3J0IGNsYXNzIEhhbmRsZSB7XG5cbiAgY29uc3RydWN0b3IobW9kZT0nYWJzb2x1dGUnLGRpcmVjdGlvbj0ndmVydGljYWwnLHhib3VuZD1bMCwxMDBdLHlib3VuZD1bMCwxMDBdKSB7XG4gICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICB0aGlzLmRpcmVjdGlvbiA9IGRpcmVjdGlvbjtcbiAgICB0aGlzLnByZXZpb3VzID0gMDtcbiAgICB0aGlzLnZhbHVlID0gMDtcbiAgICB0aGlzLnNlbnNpdGl2aXR5ID0gMTtcbiAgICB0aGlzLnJlc2l6ZSh4Ym91bmQseWJvdW5kKTtcbiAgfVxuXG4gIHJlc2l6ZSh4Ym91bmQseWJvdW5kKSB7XG4gICAgdGhpcy5ib3VuZGFyeSA9IHtcbiAgICAgIG1pbjoge1xuICAgICAgICB4OiB4Ym91bmRbMF0sXG4gICAgICAgIHk6IHlib3VuZFswXVxuICAgICAgfSxcbiAgICAgIG1heDoge1xuICAgICAgICB4OiB4Ym91bmRbMV0sXG4gICAgICAgIHk6IHlib3VuZFsxXVxuICAgICAgfSxcbiAgICAgIGNlbnRlcjoge1xuICAgICAgICB4OiAoeGJvdW5kWzFdIC0geGJvdW5kWzBdKS8yICsgeGJvdW5kWzBdLFxuICAgICAgICB5OiAoeWJvdW5kWzFdIC0geWJvdW5kWzBdKS8yICsgeWJvdW5kWzBdXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHNldCBhbmNob3IobW91c2UpIHtcbiAgICB0aGlzLl9hbmNob3IgPSB0aGlzLmNvbnZlcnRQb3NpdGlvblRvVmFsdWUobW91c2UpO1xuICB9XG5cbiAgZ2V0IGFuY2hvcigpIHtcbiAgICByZXR1cm4gdGhpcy5fYW5jaG9yO1xuICB9XG5cblxuICB1cGRhdGUobW91c2UpIHtcbiAgICBpZiAodGhpcy5tb2RlPT09J3JlbGF0aXZlJykge1xuICAgICAgbGV0IGluY3JlbWVudCA9IHRoaXMuY29udmVydFBvc2l0aW9uVG9WYWx1ZShtb3VzZSkgLSB0aGlzLmFuY2hvcjtcbiAgICAgIGlmIChNYXRoLmFicyhpbmNyZW1lbnQpID4gMC41KSB7IGluY3JlbWVudCA9IDA7IH1cbiAgICAgIHRoaXMuYW5jaG9yID0gbW91c2U7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy52YWx1ZSArIGluY3JlbWVudCAqIHRoaXMuc2Vuc2l0aXZpdHk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLmNvbnZlcnRQb3NpdGlvblRvVmFsdWUobW91c2UpO1xuICAgIH1cbiAgICB0aGlzLnZhbHVlID0gbWF0aC5jbGlwKHRoaXMudmFsdWUsMCwxKTtcbiAgfVxuXG4gIGNvbnZlcnRQb3NpdGlvblRvVmFsdWUoY3VycmVudCkge1xuICAgIHN3aXRjaCh0aGlzLmRpcmVjdGlvbikge1xuICAgICAgY2FzZSAncmFkaWFsJzpcbiAgICAgICAgbGV0IHBvc2l0aW9uID0gbWF0aC50b1BvbGFyKGN1cnJlbnQueCAtIHRoaXMuYm91bmRhcnkuY2VudGVyLngsIGN1cnJlbnQueSAtIHRoaXMuYm91bmRhcnkuY2VudGVyLnkpO1xuICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uLmFuZ2xlIC8gKE1hdGguUEkqMik7XG4gICAgICAgIHBvc2l0aW9uID0gKChwb3NpdGlvbiAtIDAuMjUpICsgMSkgJSAxO1xuICAgICAgICByZXR1cm4gcG9zaXRpb247XG4gICAgICBjYXNlICd2ZXJ0aWNhbCc6XG4gICAgICAgIHJldHVybiBtYXRoLnNjYWxlKGN1cnJlbnQueSx0aGlzLmJvdW5kYXJ5Lm1pbi55LHRoaXMuYm91bmRhcnkubWF4LnksMCwxKTtcbiAgICAgIGNhc2UgJ2hvcml6b250YWwnOlxuICAgICAgICByZXR1cm4gbWF0aC5zY2FsZShjdXJyZW50LngsdGhpcy5ib3VuZGFyeS5taW4ueCx0aGlzLmJvdW5kYXJ5Lm1heC54LDAsMSk7XG4gICAgfVxuICB9XG5cbn1cblxuXG5leHBvcnQgY2xhc3MgQnV0dG9uIHtcblxuICBjb25zdHJ1Y3Rvcihtb2RlPSdidXR0b24nKSB7XG4gICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICB0aGlzLnN0YXRlID0gbmV3IFRvZ2dsZU1vZGVsKCk7XG4gICAgdGhpcy5wYWludGJydXNoID0gZmFsc2U7XG4gIH1cblxuICBjbGljaygpIHtcbiAgICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuICAgICAgY2FzZSAnaW1wdWxzZSc6XG4gICAgICAgIHRoaXMuc3RhdGUub24oKTtcbiAgICAgICAgaWYgKHRoaXMudGltZW91dCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudGltZW91dCA9IHNldFRpbWVvdXQodGhpcy5zdGF0ZS5vZmYuYmluZCh0aGlzKSwzMCk7XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdidXR0b24nOlxuICAgICAgICB0aGlzLnR1cm5PbigpO1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgICB5OiBtYXRoLmNsaXAoMSAtIHRoaXMubW91c2UueSAvIHRoaXMuaGVpZ2h0LDAsMSlcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy50dXJuT24oKTtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG4gICAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd0b2dnbGUnOlxuICAgICAgICB0aGlzLmZsaXAoKTtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgfVxuXG4gIG1vdmUoKSB7XG4gICAgaWYgKHRoaXMubW9kZT09PSdhZnRlcnRvdWNoJykge1xuICAgICAgdGhpcy5wb3NpdGlvbiA9IHtcbiAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICB9O1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgc3dpdGNoICh0aGlzLm1vZGUpIHtcbiAgICAgIGNhc2UgJ2J1dHRvbic6XG4gICAgICAgIHRoaXMudHVybk9mZigpO1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMudHVybk9mZigpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uID0ge1xuICAgICAgICAgIHg6IHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsXG4gICAgICAgICAgeTogMSAtIHRoaXMubW91c2UueSAvIHRoaXMuaGVpZ2h0XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgICAgICAgIHk6IHRoaXMucG9zaXRpb24ueSxcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3V0aWwvaW50ZXJhY3Rpb24uanMiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRvZ2dsZSB7XG5cbiAgY29uc3RydWN0b3Ioc3RhdGUpIHtcbiAgICB0aGlzLnN0YXRlID0gc3RhdGUgfHwgZmFsc2U7XG4gIH1cblxuICBmbGlwKHN0YXRlKSB7XG4gICAgaWYgKHN0YXRlIHx8IHN0YXRlID09PSBmYWxzZSkge1xuICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0YXRlID0gIXRoaXMuc3RhdGU7XG4gICAgfVxuICB9XG5cbiAgb24oKSB7XG4gICAgdGhpcy5zdGF0ZSA9IHRydWU7XG4gIH1cblxuICBvZmYoKSB7XG4gICAgdGhpcy5zdGF0ZSA9IGZhbHNlO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9tb2RlbHMvdG9nZ2xlLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbi8qKlxuKiBTbGlkZXJcbipcbiogQGRlc2NyaXB0aW9uIEhvcml6b250YWwgb3IgdmVydGljYWwgc2xpZGVyIHdpdGggc2V0dGFibGUgaW50ZXJhY3Rpb24gbW9kZXMuXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwic2xpZGVyXCIgc3RlcD0wLjI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc2xpZGVyID0gbmV3IE5leHVzLlNsaWRlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBzbGlkZXIgPSBuZXcgTmV4dXMuU2xpZGVyKCcjdGFyZ2V0Jyx7XG4qICAgICAnc2l6ZSc6IFsxMjAsMjBdLFxuKiAgICAgJ21vZGUnOiAncmVsYXRpdmUnLCAgLy8gJ3JlbGF0aXZlJyBvciAnYWJzb2x1dGUnXG4qICAgICAnbWluJzogMCxcbiogICAgICdtYXgnOiAxLFxuKiAgICAgJ3N0ZXAnOiAwLFxuKiAgICAgJ3ZhbHVlJzogMFxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyB3aGVuIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIEV2ZW50IGRhdGE6IDxpPm51bWJlcjwvaT4gVGhlIG51bWJlciB2YWx1ZSBvZiB0aGUgaW50ZXJmYWNlLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiBzbGlkZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2xpZGVyIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWydtaW4nLCdtYXgnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMTIwLDIwXSxcbiAgICAgICdtb2RlJzogJ3JlbGF0aXZlJywgIC8vICdyZWxhdGl2ZScgb3IgJ2Fic29sdXRlJ1xuICAgICAgJ21pbic6IDAsXG4gICAgICAnbWF4JzogMSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDBcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5vcmllbnRhdGlvbiA9ICd2ZXJ0aWNhbCc7IC8vIFRoaXMgd2lsbCBjaGFuZ2UgYXV0b21hdGljYWxseSB0byAnaG9yaXpvbnRhbCdpZiB0aGUgaW50ZXJmYWNlIGlzIHdpZGVyIHRoYW4gaXQgaXMgdGFsbC5cblxuICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5taW4sIHRoaXMuc2V0dGluZ3MubWF4LCB0aGlzLnNldHRpbmdzLnN0ZXAsIHRoaXMuc2V0dGluZ3MudmFsdWUpO1xuXG4gICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLHRoaXMub3JpZW50YXRpb24sWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbi5kaXJlY3Rpb24gPSB0aGlzLm9yaWVudGF0aW9uO1xuXG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuXG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyID0gc3ZnLmNyZWF0ZSgncmVjdCcpO1xuICAgIHRoaXMuZmlsbGJhciA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmtub2IgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuZmlsbGJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBpZiAodGhpcy53aWR0aCA8IHRoaXMuaGVpZ2h0KSB7XG4gICAgICB0aGlzLm9yaWVudGF0aW9uID0gJ3ZlcnRpY2FsJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcmllbnRhdGlvbiA9ICdob3Jpem9udGFsJztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wb3NpdGlvbikge1xuICAgICAgdGhpcy5wb3NpdGlvbi5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB9XG5cbiAgICBsZXQgeCwgeSwgdywgaCwgYmFyT2Zmc2V0LCBjb3JuZXJSYWRpdXM7XG4gICAgdGhpcy5rbm9iRGF0YSA9IHtcbiAgICAgIGxldmVsOiAwLFxuICAgICAgcjogMFxuICAgIH07XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy50aGlja25lc3MgPSB0aGlzLndpZHRoIC8gMjtcbiAgICBcdHggPSB0aGlzLndpZHRoLzI7XG4gICAgXHR5ID0gMDtcbiAgICBcdHcgPSB0aGlzLnRoaWNrbmVzcztcbiAgICBcdGggPSB0aGlzLmhlaWdodDtcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IGgtdGhpcy5rbm9iRGF0YS5yLXRoaXMubm9ybWFsaXplZCooaC10aGlzLmtub2JEYXRhLnIqMik7XG4gICAgICBiYXJPZmZzZXQgPSAndHJhbnNsYXRlKCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycsMCknO1xuICAgICAgY29ybmVyUmFkaXVzID0gdy8yO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMuaGVpZ2h0IC8gMjtcbiAgICBcdHggPSAwO1xuICAgIFx0eSA9IHRoaXMuaGVpZ2h0LzI7XG4gICAgXHR3ID0gdGhpcy53aWR0aDtcbiAgICBcdGggPSB0aGlzLnRoaWNrbmVzcztcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IHRoaXMubm9ybWFsaXplZCoody10aGlzLmtub2JEYXRhLnIqMikrdGhpcy5rbm9iRGF0YS5yO1xuICAgICAgYmFyT2Zmc2V0ID0gJ3RyYW5zbGF0ZSgwLCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycpJztcbiAgICAgIGNvcm5lclJhZGl1cyA9IGgvMjtcbiAgICB9XG5cbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3gnLHgpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneScseSk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGJhck9mZnNldCk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsY29ybmVyUmFkaXVzKTsgLy8gY29ybmVyIHJhZGl1c1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgncnknLGNvcm5lclJhZGl1cyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3gnLHgpO1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneScsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdyk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgtdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3gnLDApO1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneScseSk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgpO1xuICAgIH1cbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGJhck9mZnNldCk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgncngnLGNvcm5lclJhZGl1cyk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgncnknLGNvcm5lclJhZGl1cyk7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHgpO1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScseSk7XG4gICAgfVxuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYkRhdGEucik7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICB9XG5cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKCF0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzKjAuNzU7XG4gICAgfVxuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYkRhdGEucik7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICBcdCAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLmtub2JEYXRhLnIrdGhpcy5fdmFsdWUubm9ybWFsaXplZCoodGhpcy5oZWlnaHQtdGhpcy5rbm9iRGF0YS5yKjIpO1xuICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmhlaWdodCAtIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3knLHRoaXMuaGVpZ2h0IC0gdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICBcdCAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkKih0aGlzLndpZHRoLXRoaXMua25vYkRhdGEucioyKSt0aGlzLmtub2JEYXRhLnI7XG4gICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3gnLDApO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9XG4gIH1cblxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzKjAuOTtcbiAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMucG9zaXRpb24udXBkYXRlKHRoaXMubW91c2UpO1xuICAgICAgdGhpcy5fdmFsdWUudXBkYXRlTm9ybWFsKCB0aGlzLnBvc2l0aW9uLnZhbHVlICk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5fdmFsdWUudmFsdWUpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuICB9XG5cbiAgLyoqXG4gIFRoZSBzbGlkZXIncyBjdXJyZW50IHZhbHVlLiBJZiBzZXQgbWFudWFsbHksIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgc2xpZGVyLnZhbHVlID0gMTA7XG4gICovXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHYpIHtcbiAgICB0aGlzLl92YWx1ZS51cGRhdGUodik7XG4gICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuX3ZhbHVlLnZhbHVlKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIExvd2VyIGxpbWl0IG9mIHRoZSBzbGlkZXJzJ3Mgb3V0cHV0IHJhbmdlXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNsaWRlci5taW4gPSAxMDAwO1xuICAqL1xuICBnZXQgbWluKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5taW47XG4gIH1cbiAgc2V0IG1pbih2KSB7XG4gICAgdGhpcy5fdmFsdWUubWluID0gdjtcbiAgfVxuXG4gIC8qKlxuICBVcHBlciBsaW1pdCBvZiB0aGUgc2xpZGVyJ3Mgb3V0cHV0IHJhbmdlXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNsaWRlci5tYXggPSAxMDAwO1xuICAqL1xuICBnZXQgbWF4KCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5tYXg7XG4gIH1cbiAgc2V0IG1heCh2KSB7XG4gICAgdGhpcy5fdmFsdWUubWF4ID0gdjtcbiAgfVxuXG4gIC8qKlxuICBUaGUgaW5jcmVtZW50IHRoYXQgdGhlIHNsaWRlcidzIHZhbHVlIGNoYW5nZXMgYnkuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNsaWRlci5zdGVwID0gNTtcbiAgKi9cbiAgZ2V0IHN0ZXAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnN0ZXA7XG4gIH1cbiAgc2V0IHN0ZXAodikge1xuICAgIHRoaXMuX3ZhbHVlLnN0ZXAgPSB2O1xuICB9XG5cbiAgLyoqXG4gIEFic29sdXRlIG1vZGUgKHNsaWRlcidzIHZhbHVlIGp1bXBzIHRvIG1vdXNlIGNsaWNrIHBvc2l0aW9uKSBvciByZWxhdGl2ZSBtb2RlIChtb3VzZSBkcmFnIGNoYW5nZXMgdmFsdWUgcmVsYXRpdmUgdG8gaXRzIGN1cnJlbnQgcG9zaXRpb24pLiBEZWZhdWx0OiBcInJlbGF0aXZlXCIuXG4gIEB0eXBlIHtzdHJpbmd9XG4gIEBleGFtcGxlIHNsaWRlci5tb2RlID0gXCJyZWxhdGl2ZVwiO1xuICAqL1xuICBnZXQgbW9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi5tb2RlO1xuICB9XG4gIHNldCBtb2RlKHYpIHtcbiAgICB0aGlzLnBvc2l0aW9uLm1vZGUgPSB2O1xuICB9XG5cblxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9zbGlkZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IFRvZ2dsZU1vZGVsID0gcmVxdWlyZSgnLi4vbW9kZWxzL3RvZ2dsZScpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5cbi8qKlxuKiBUb2dnbGVcbipcbiogQGRlc2NyaXB0aW9uIEJpbmFyeSBzd2l0Y2hcbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJ0b2dnbGVcIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciB0b2dnbGUgPSBuZXcgTmV4dXMuVG9nZ2xlKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHRvZ2dsZSA9IG5ldyBOZXh1cy5Ub2dnbGUoJyN0YXJnZXQnLHtcbiogICAgICdzaXplJzogWzQwLDIwXSxcbiogICAgICdzdGF0ZSc6IGZhbHNlXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIFBhcmFtZXRlcjogVGhlIGJvb2xlYW4gc3RhdGUgb2YgdGhlIGludGVyZmFjZS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogdG9nZ2xlLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbipcbiovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUb2dnbGUgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3ZhbHVlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFs0MCwyMF0sXG4gICAgICAndGFyZ2V0JzogZmFsc2UsXG4gICAgICAnc3RhdGUnOiBmYWxzZVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLl9zdGF0ZSA9IG5ldyBUb2dnbGVNb2RlbCh0aGlzLnNldHRpbmdzLnN0YXRlKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyID0gc3ZnLmNyZWF0ZSgncmVjdCcpO1xuICAgIHRoaXMua25vYiA9IHN2Zy5jcmVhdGUoJ2NpcmNsZScpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBpZiAodGhpcy5oZWlnaHQgPCB0aGlzLndpZHRoLzIpIHtcbiAgICAgIHRoaXMua25vYlNpemUgPSB0aGlzLmhlaWdodC8yO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmtub2JTaXplID0gdGhpcy53aWR0aC80O1xuICAgIH1cblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneCcsdGhpcy53aWR0aC8yIC0gdGhpcy5rbm9iU2l6ZSoxLjUpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneScsdGhpcy5oZWlnaHQvMiAtIHRoaXMua25vYlNpemUvMik7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsdGhpcy5rbm9iU2l6ZS8yKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3J5Jyx0aGlzLmtub2JTaXplLzIpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnd2lkdGgnLHRoaXMua25vYlNpemUqMyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLHRoaXMua25vYlNpemUpO1xuXG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMud2lkdGgvMiAtIHRoaXMua25vYlNpemUpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmhlaWdodC8yKTtcbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JTaXplKTtcblxuICB9XG5cbiAgY29sb3JJbnRlcmZhY2UoKSB7XG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIgLSB0aGlzLmtub2JTaXplKTtcbiAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeCcsdGhpcy53aWR0aC8yICsgdGhpcy5rbm9iU2l6ZSk7XG4gICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIH1cbiAgfVxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMuZmxpcCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICB9XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIHRvZ2dsZSBpcyBjdXJyZW50bHkgb24gb3Igb2ZmLiBTZXR0aW5nIHRoaXMgcHJvcGVydHkgd2lsbCB1cGRhdGUgdGhlIHRvZ2dsZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge2Jvb2xlYW59XG4gIEBleGFtcGxlIHRvZ2dsZS5zdGF0ZSA9IGZhbHNlO1xuICAqL1xuICBnZXQgc3RhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlLnN0YXRlO1xuICB9XG4gIHNldCBzdGF0ZSh2YWx1ZSkge1xuICAgIHRoaXMuX3N0YXRlLmZsaXAodmFsdWUpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgKiBTd2l0Y2ggdGhlIHRvZ2dsZSBzdGF0ZSB0byBpdHMgb3Bwb3NpdGUgc3RhdGVcbiAgKiBAZXhhbXBsZVxuICAqIHRvZ2dsZS5mbGlwKCk7XG4gICovXG4gIGZsaXAoKSB7XG4gICAgdGhpcy5fc3RhdGUuZmxpcCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvdG9nZ2xlLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBCdXR0b25UZW1wbGF0ZSA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvYnV0dG9udGVtcGxhdGUnKTtcblxuLyoqXG4qIEJ1dHRvblxuKlxuKiBAZGVzY3JpcHRpb24gQ2lyY3VsYXIgYnV0dG9uIHdpdGggb3B0aW9uYWwgYWZ0ZXJ0b3VjaC5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJidXR0b25cIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBidXR0b24gPSBuZXcgTmV4dXMuQnV0dG9uKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIGJ1dHRvbiA9IG5ldyBOZXh1cy5CdXR0b24oJyN0YXJnZXQnLHtcbiogICAnc2l6ZSc6IFs4MCw4MF0sXG4qICAgJ21vZGUnOiAnYWZ0ZXJ0b3VjaCcsXG4qICAgJ3N0YXRlJzogZmFsc2VcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogSW4gPGI+YnV0dG9uIG1vZGU8L2I+LCA8Yj50b2dnbGUgbW9kZTwvYj4sIGFuZCA8Yj5pbXB1bHNlIG1vZGU8L2I+LCB0aGUgb3V0cHV0IGRhdGEgaXMgYSBib29sZWFuIGRlc2NyaWJpbmcgdGhlIHN0YXRlIG9mIHRoZSBidXR0b24uPGJyPlxuKiBJbiA8Yj5hZnRlcnRvdWNoIG1vZGU8L2I+LCB0aGUgb3V0cHV0IGRhdGEgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgeCAoMC0xKSBhbmQgeSAoMC0xKSBwb3NpdGlvbnMgb2YgYWZ0ZXJ0b3VjaC5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogYnV0dG9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICAvLyB2IGlzIHRoZSB2YWx1ZSBvZiB0aGUgYnV0dG9uXG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCdXR0b24gZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnbW9kZSddO1xuXG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFs4MCw4MF0sXG4gICAgICAnbW9kZSc6ICdhZnRlcnRvdWNoJywgLy8gYnV0dG9uLCBhZnRlcnRvdWNoLCBpbXB1bHNlLCB0b2dnbGVcbiAgICAgICdzdGF0ZSc6IGZhbHNlXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuXG4gICAgLyoqXG4gICAgKiBJbnRlcmFjdGlvbiBtb2RlOiBzdXBwb3J0cyBcImJ1dHRvblwiLCBcImFmdGVydG91Y2hcIiwgXCJpbXB1bHNlXCIsIG9yIFwidG9nZ2xlXCJcbiAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgKiBAZXhhbXBsZSBidXR0b24ubW9kZSA9ICd0b2dnbGUnO1xuICAgICovXG4gICAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG4gICAgdGhpcy5wYWQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wYWQpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXG4gICAgLy8gb25seSB1c2VkIGlmIGluICdhZnRlcnRvdWNoJyBtb2RlXG4gICAgdGhpcy5kZWZzID0gc3ZnLmNyZWF0ZSgnZGVmcycpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmRlZnMpO1xuXG4gICAgdGhpcy5ncmFkaWVudCA9IHN2Zy5yYWRpYWxHcmFkaWVudCh0aGlzLmRlZnMsMik7XG5cbiAgICB0aGlzLmdyYWRpZW50LnN0b3BzWzBdLnNldEF0dHJpYnV0ZSgnb2Zmc2V0JywgJzMwJScpO1xuXG4gICAgdGhpcy5ncmFkaWVudC5zdG9wc1sxXS5zZXRBdHRyaWJ1dGUoJ29mZnNldCcsICcxMDAlJyk7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMuaGVpZ2h0LzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgncicsIE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpIC8gMiAtIHRoaXMud2lkdGgvNDApO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJywgdGhpcy53aWR0aC8yMCk7XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuZ3JhZGllbnQuc3RvcHNbMF0uc2V0QXR0cmlidXRlKCdzdG9wLWNvbG9yJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB0aGlzLmdyYWRpZW50LnN0b3BzWzFdLnNldEF0dHJpYnV0ZSgnc3RvcC1jb2xvcicsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKlxuICAqIFVwZGF0ZSB0aGUgdmlzdWFsIGludGVyZmFjZSB1c2luZyBpdHMgY3VycmVudCBzdGF0ZVxuICAqXG4gICogQGV4YW1wbGVcbiAgKiBidXR0b24ucmVuZGVyKCk7XG4gICovXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2UnLCB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLm1vZGU9PT0nYWZ0ZXJ0b3VjaCcpIHtcbiAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2UnLCAndXJsKCMnK3RoaXMuZ3JhZGllbnQuaWQrJyknKTtcbiAgICAgICAgdGhpcy5ncmFkaWVudC5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3gnLCAodGhpcy5wb3NpdGlvbi54KjEwMCkrJyUnKTtcbiAgICAgICAgdGhpcy5ncmFkaWVudC5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3knLCAoKDEtdGhpcy5wb3NpdGlvbi55KSoxMDApKyclJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgICB9XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIH1cbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9idXR0b24uanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IG1hdGggPSByZXF1aXJlKCcuLi91dGlsL21hdGgnKTtcbmxldCBUb2dnbGVNb2RlbCA9IHJlcXVpcmUoJy4uL21vZGVscy90b2dnbGUnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xuXG4vKipcbkJ1dHRvbiBUZW1wbGF0ZVxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnV0dG9uVGVtcGxhdGUgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKGFyZ3Msb3B0aW9ucyxkZWZhdWx0cykge1xuXG4gICAgc3VwZXIoYXJncyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZSB8fCAnYnV0dG9uJztcblxuICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICB4OiAwLFxuICAgICAgeTogMFxuICAgIH07XG5cbiAgICB0aGlzLl9zdGF0ZSA9IG5ldyBUb2dnbGVNb2RlbCh0aGlzLnNldHRpbmdzLnN0YXRlKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG4gICAgdGhpcy5wYWQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAnI2QxOCcpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgJyNkMTgnKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsIDQpO1xuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMucGFkKTtcblxuICAgIHRoaXMuaW50ZXJhY3Rpb25UYXJnZXQgPSB0aGlzLnBhZDtcblxuICAgIHRoaXMuc2l6ZUludGVyZmFjZSgpO1xuICB9XG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMuaGVpZ2h0LzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgncicsIE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpIC8gMiAtIDIpO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5zdGF0ZSkge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuZmlsbCk7XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB9XG4gIH1cblxuICBkb3duKHBhaW50YnJ1c2gpIHtcbiAgICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuICAgICAgY2FzZSAnaW1wdWxzZSc6XG4gICAgICAgIHRoaXMudHVybk9uKCk7XG4gICAgICAgIGlmICh0aGlzLnRpbWVvdXQpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRpbWVvdXQgPSBzZXRUaW1lb3V0KHRoaXMudHVybk9mZi5iaW5kKHRoaXMpLDMwKTtcbiAgICAvLyAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYnV0dG9uJzpcbiAgICAgICAgdGhpcy50dXJuT24oKTtcbiAgICAvLyAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgICB5OiBtYXRoLmNsaXAoMS10aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMudHVybk9uKCk7XG4gICAgLy8gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAvLyAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgIC8vICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgIC8vICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgIC8vICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3RvZ2dsZSc6XG4gICAgICAgIHRoaXMuZmxpcChwYWludGJydXNoKTtcbiAgICAvLyAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICB9XG5cbiAgYmVuZChtb3VzZSkge1xuICAgIGlmICh0aGlzLm1vZGU9PT0nYWZ0ZXJ0b3VjaCcpIHtcbiAgICAgIHRoaXMubW91c2UgPSBtb3VzZSB8fCB0aGlzLm1vdXNlO1xuICAgICAgdGhpcy5wb3NpdGlvbiA9IHtcbiAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICB9O1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIHVwKCkge1xuICAgIHN3aXRjaCAodGhpcy5tb2RlKSB7XG4gICAgICBjYXNlICdidXR0b24nOlxuICAgICAgICB0aGlzLnR1cm5PZmYoKTtcbiAgICAgIC8vICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMudHVybk9mZigpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uID0ge1xuICAgICAgICAgIHg6IG1hdGguY2xpcCh0aGlzLm1vdXNlLnggLyB0aGlzLndpZHRoLDAsMSksXG4gICAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICAgIH07XG4gICAgICAvLyAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgIC8vICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgLy8gICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgICAgLy8gICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgLy8gIH0pO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvKiBvdmVyd3JpdGFibGUgaW50ZXJhY3Rpb24gaGFuZGxlcnMgKi9cblxuICBjbGljaygpIHtcbiAgICB0aGlzLmRvd24oKTtcbiAgfVxuICBtb3ZlKCkge1xuICAgIHRoaXMuYmVuZCgpO1xuICB9XG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy51cCgpO1xuICB9XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIGJ1dHRvbiBpcyBvbiAocHJlc3NlZCkgb3Igb2ZmIChub3QgcHJlc3NlZClcbiAgQHR5cGUge2Jvb2xlYW59XG4gIEBleGFtcGxlIGJ1dHRvbi5zdGF0ZSA9IHRydWU7XG4gICovXG4gIGdldCBzdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGUuc3RhdGU7XG4gIH1cbiAgc2V0IHN0YXRlKHZhbHVlKSB7XG4gICAgdGhpcy5fc3RhdGUuZmxpcCh2YWx1ZSk7XG4gICAgaWYgKHRoaXMubW9kZT09PSdhZnRlcnRvdWNoJykge1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICB9XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBDaGFuZ2UgdGhlIGJ1dHRvbiB0byBpdHMgYWx0ZXJuYXRlIHN0YXRlIChvZmY9Pm9uLCBvbj0+b2ZmKSwgb3IgZmxpcCBpdCB0byBhIHNwZWNpZmllZCBzdGF0ZS5cbiAgQHBhcmFtIHZhbHVlIHtib29sZWFufSAoT3B0aW9uYWwpIFN0YXRlIHRvIGZsaXAgdG8uXG4gIEBleGFtcGxlIGJ1dHRvbi5mbGlwKCk7XG4gICovXG4gIGZsaXAodmFsdWUpIHtcbiAgICB0aGlzLl9zdGF0ZS5mbGlwKHZhbHVlKTtcbiAgICBpZiAodGhpcy5tb2RlPT09J2FmdGVydG91Y2gnKSB7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgICAgICB5OiB0aGlzLnBvc2l0aW9uLnksXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICAgIH1cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIFR1cm4gdGhlIGJ1dHRvbidzIHN0YXRlIHRvIHRydWUuXG4gIEBleGFtcGxlIGJ1dHRvbi50dXJuT24oKTtcbiAgKi9cbiAgdHVybk9uKGVtaXR0aW5nKSB7XG4gICAgdGhpcy5fc3RhdGUub24oKTtcbiAgICBpZiAoZW1pdHRpbmchPT1mYWxzZSkge1xuICAgICAgaWYgKHRoaXMubW9kZT09PSdhZnRlcnRvdWNoJykge1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgICB5OiB0aGlzLnBvc2l0aW9uLnksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIFR1cm4gdGhlIGJ1dHRvbidzIHN0YXRlIHRvIGZhbHNlLlxuICBAZXhhbXBsZSBidXR0b24udHVybk9mZigpO1xuICAqL1xuICB0dXJuT2ZmKGVtaXR0aW5nKSB7XG4gICAgdGhpcy5fc3RhdGUub2ZmKCk7XG4gICAgaWYgKGVtaXR0aW5nIT09ZmFsc2UpIHtcbiAgICAgIGlmICh0aGlzLm1vZGU9PT0nYWZ0ZXJ0b3VjaCcpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG4gICAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvY29tcG9uZW50cy9idXR0b250ZW1wbGF0ZS5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IEJ1dHRvblRlbXBsYXRlID0gcmVxdWlyZSgnLi4vY29tcG9uZW50cy9idXR0b250ZW1wbGF0ZScpO1xuXG4vKipcbiogVGV4dEJ1dHRvblxuKlxuKiBAZGVzY3JpcHRpb24gVGV4dCBidXR0b25cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJ0ZXh0QnV0dG9uXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgdGV4dGJ1dHRvbiA9IG5ldyBOZXh1cy5UZXh0QnV0dG9uKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHRleHRidXR0b24gPSBuZXcgTmV4dXMuVGV4dEJ1dHRvbignI3RhcmdldCcse1xuKiAgICAgJ3NpemUnOiBbMTUwLDUwXSxcbiogICAgICdzdGF0ZSc6IGZhbHNlLFxuKiAgICAgJ3RleHQnOiAnUGxheScsXG4qICAgICAnYWx0ZXJuYXRlVGV4dCc6ICdTdG9wJ1xuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhIDxpPnN0cmluZzwvaT4gb2YgdGhlIHRleHQgb24gdGhlIGJ1dHRvbiBhdCB0aGUgbW9tZW50IGl0IHdhcyBjbGlja2VkLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiB0ZXh0YnV0dG9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRleHRCdXR0b24gZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzE1MCw1MF0sXG4gICAgICAnc3RhdGUnOiBmYWxzZSxcbiAgICAgICd0ZXh0JzogJ1BsYXknXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuX3RleHQgPSB0aGlzLnNldHRpbmdzLnRleHQ7XG5cbiAgICBpZih0aGlzLnNldHRpbmdzLmFsdGVybmF0ZSl7IC8vVE9ETzogUmVtb3ZlIHRoaXMgY29uZGl0aW9uYWwgaW4gYSBicmVha2luZy1jaGFuZ2VzIHJlbGVhc2VcbiAgICAgIHRoaXMuc2V0dGluZ3MuYWx0ZXJuYXRlVGV4dCA9IHRoaXMuc2V0dGluZ3MuYWx0ZXJuYXRlO1xuICAgICAgY29uc29sZS53YXJuKFwiJ2FsdGVybmF0ZScgaW5pdGlhdG9yIGlzIGRlcHJlY2F0ZWQuIFVzZSAnYWx0ZXJuYXRlVGV4dCcgaW5zdGVhZC5cIik7XG4gICAgfVxuICAgIHRoaXMuX2FsdGVybmF0ZVRleHQgPSB0aGlzLnNldHRpbmdzLmFsdGVybmF0ZVRleHQ7XG4gICAgdGhpcy5tb2RlID0gKHRoaXMuc2V0dGluZ3MuYWx0ZXJuYXRlVGV4dCkgPyAndG9nZ2xlJyA6ICdidXR0b24nO1xuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICB0aGlzLnN0YXRlID0gdGhpcy5zZXR0aW5ncy5zdGF0ZTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcblxuICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG5cbiAgICB0aGlzLnRleHRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl90ZXh0O1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnRleHRFbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY29sb3IgPSB0aGlzLmNvbG9ycy5kYXJrO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuICAgICAgbGV0IHRleHRzaXplID0gdGhpcy5oZWlnaHQvMztcbiAgICAgIGxldCB0ZXh0c2l6ZTIgPSAodGhpcy53aWR0aCAvICh0aGlzLl90ZXh0Lmxlbmd0aCArIDIpICk7XG4gICAgICB0ZXh0c2l6ZSA9IE1hdGgubWluKHRleHRzaXplLHRleHRzaXplMik7XG4gICAgICBpZiAodGhpcy5hbHRlcm5hdGVUZXh0KSB7XG4gICAgICAgIGxldCB0ZXh0c2l6ZTMgPSAodGhpcy53aWR0aCAvICh0aGlzLmFsdGVybmF0ZVRleHQubGVuZ3RoICsgMikgKTtcbiAgICAgICAgdGV4dHNpemUgPSBNYXRoLm1pbih0ZXh0c2l6ZSx0ZXh0c2l6ZTMpO1xuICAgICAgfVxuICAgICAgbGV0IHN0eWxlcyA9ICd3aWR0aDogJyArIHRoaXMud2lkdGggKyAncHg7JztcbiAgICAgIHN0eWxlcyArPSAnaGVpZ2h0OiAnICsgdGhpcy5oZWlnaHQgKyAncHg7JztcbiAgICAgIHN0eWxlcyArPSAncGFkZGluZzogJysodGhpcy5oZWlnaHQtdGV4dHNpemUpLzIrJ3B4IDBweDsnO1xuICAgICAgc3R5bGVzICs9ICdib3gtc2l6aW5nOiBib3JkZXItYm94Oyc7XG4gICAgICBzdHlsZXMgKz0gJ3RleHQtYWxpZ246IGNlbnRlcjsnO1xuICAgICAgc3R5bGVzICs9ICdmb250LWZhbWlseTogaW5oZXJpdDsnO1xuICAgICAgc3R5bGVzICs9ICdmb250LXdlaWdodDogNzAwOyc7XG4gICAgICBzdHlsZXMgKz0gJ29wYWNpdHk6IDE7JztcbiAgICAgIHN0eWxlcyArPSAnZm9udC1zaXplOicgKyB0ZXh0c2l6ZSArICdweDsnO1xuICAgICAgdGhpcy50ZXh0RWxlbWVudC5zdHlsZS5jc3NUZXh0ID0gc3R5bGVzO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5maWxsO1xuICAgICAgdGhpcy50ZXh0RWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG4gICAgICB0aGlzLnRleHRFbGVtZW50LmlubmVySFRNTCA9IHRoaXMuX3RleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG4gICAgICB0aGlzLnRleHRFbGVtZW50LnN0eWxlLmNvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICAgIGlmICh0aGlzLmFsdGVybmF0ZVRleHQpIHtcbiAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl9hbHRlcm5hdGVUZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl90ZXh0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICBUaGUgdGV4dCB0byBkaXNwbGF5IHdoZW4gdGhlIGJ1dHRvbiBpcyBpbiBpdHMgXCJvblwiIHN0YXRlLiBJZiBzZXQsIHRoaXMgcHV0cyB0aGUgYnV0dG9uIGluIFwidG9nZ2xlXCIgbW9kZS5cbiAgQHR5cGUge1N0cmluZ31cbiAgKi9cbiAgZ2V0IGFsdGVybmF0ZVRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsdGVybmF0ZVRleHQ7XG4gIH1cblxuICBzZXQgYWx0ZXJuYXRlVGV4dCh0ZXh0KSB7XG4gICAgaWYgKHRleHQpIHtcbiAgICAgIHRoaXMubW9kZSA9ICd0b2dnbGUnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1vZGUgPSAnYnV0dG9uJztcbiAgICB9XG4gICAgdGhpcy5fYWx0ZXJuYXRlVGV4dCA9IHRleHQ7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIFRoZSB0ZXh0IHRvIGRpc3BsYXkuIChJZiAuYWx0ZXJuYXRlVGV4dCBleGlzdHMsIHRoZW4gdGhpcyAudGV4dCB3aWxsIG9ubHkgYmUgZGlzcGxheWVkIHdoZW4gdGhlIGJ1dHRvbiBpcyBpbiBpdHMgXCJvZmZcIiBzdGF0ZS4pXG4gIEB0eXBlIHtTdHJpbmd9XG4gICovXG4gIGdldCB0ZXh0KCkge1xuICAgIHJldHVybiB0aGlzLl90ZXh0O1xuICB9XG5cbiAgc2V0IHRleHQodGV4dCkge1xuICAgIHRoaXMuX3RleHQgPSB0ZXh0O1xuICAgIHRoaXMuc2l6ZUludGVyZmFjZSgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy90ZXh0YnV0dG9uLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG4vL2xldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgQnV0dG9uID0gcmVxdWlyZSgnLi4vaW50ZXJmYWNlcy9idXR0b24nKTtcblxuLyoqXG4qIFJhZGlvQnV0dG9uXG4qXG4qIEBkZXNjcmlwdGlvbiBBbiBhcnJheSBvZiBidXR0b25zLiBCeSBkZWZhdWx0LCBzZWxlY3Rpbmcgb25lIGJ1dHRvbiB3aWxsIGRlc2VsZWN0IGFsbCBvdGhlciBidXR0b25zLCBidXQgdGhpcyBjYW4gYmUgY3VzdG9taXplZCB1c2luZyB0aGUgQVBJIGJlbG93LlxuKlxuKiBAZGVtbyA8ZGl2IG5leHVzLXVpPVwiUmFkaW9CdXR0b25cIj48L2Rpdj5cbipcbiogQGV4YW1wbGVcbiogdmFyIHJhZGlvYnV0dG9uID0gbmV3IE5leHVzLlJhZGlvQnV0dG9uKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHJhZGlvYnV0dG9uID0gbmV3IE5leHVzLlJhZGlvQnV0dG9uKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMTIwLDI1XSxcbiogICAnbnVtYmVyT2ZCdXR0b25zJzogNCxcbiogICAnYWN0aXZlJzogLTFcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgYW4gPGk+aW50ZWdlcjwvaT4sIHRoZSBpbmRleCBvZiB0aGUgYnV0dG9uIHRoYXQgaXMgY3VycmVudGx5IG9uLiBJZiBubyBidXR0b24gaXMgc2VsZWN0ZWQsIHRoZSB2YWx1ZSB3aWxsIGJlIC0xLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiByYWRpb2J1dHRvbi5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSYWRpb0J1dHRvbiBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzEyMCwyNV0sXG4gICAgICAnbnVtYmVyT2ZCdXR0b25zJzogNCxcbiAgICAgICdhY3RpdmUnOiAtMVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLmJ1dHRvbnMgPSBbXTtcbiAgICB0aGlzLl9udW1iZXJPZkJ1dHRvbnMgPSB0aGlzLnNldHRpbmdzLm51bWJlck9mQnV0dG9ucztcbiAgICB0aGlzLmFjdGl2ZSA9IHRoaXMuc2V0dGluZ3MuYWN0aXZlO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLl9udW1iZXJPZkJ1dHRvbnM7aSsrKSB7XG4gICAgICBsZXQgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuXG4gICAgICBsZXQgYnV0dG9uID0gbmV3IEJ1dHRvbihjb250YWluZXIsIHtcbiAgICAgICAgICBtb2RlOiAndG9nZ2xlJyxcbiAgICAgICAgICBjb21wb25lbnQ6IHRydWUsXG4gICAgICAgIH0sIHRoaXMudXBkYXRlLmJpbmQodGhpcyxpKSk7XG5cbiAgICAgIHRoaXMuYnV0dG9ucy5wdXNoKGJ1dHRvbik7XG4gICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgICB9XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBsZXQgYnV0dG9uV2lkdGggPSB0aGlzLndpZHRoIC8gdGhpcy5fbnVtYmVyT2ZCdXR0b25zO1xuICAgIGxldCBidXR0b25IZWlnaHQgPSB0aGlzLmhlaWdodDtcblxuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuX251bWJlck9mQnV0dG9ucztpKyspIHtcbiAgICAgIHRoaXMuYnV0dG9uc1tpXS5yZXNpemUoYnV0dG9uV2lkdGgsYnV0dG9uSGVpZ2h0KTtcbiAgICB9XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuX251bWJlck9mQnV0dG9ucztpKyspIHtcbiAgICAgIHRoaXMuYnV0dG9uc1tpXS5jb2xvcnMgPSB0aGlzLmNvbG9ycztcbiAgICAgIHRoaXMuYnV0dG9uc1tpXS5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGUoaW5kZXgpIHtcbiAgICBpZiAodGhpcy5idXR0b25zW2luZGV4XS5zdGF0ZSkge1xuICAgICAgdGhpcy5zZWxlY3QoaW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlc2VsZWN0KCk7XG4gICAgfVxuICAvLyAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLmJ1dHRvbnMubGVuZ3RoO2krKykge1xuICAgICAgaWYgKGk9PT10aGlzLmFjdGl2ZSkge1xuICAgICAgICB0aGlzLmJ1dHRvbnNbaV0udHVybk9uKGZhbHNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYnV0dG9uc1tpXS50dXJuT2ZmKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgU2VsZWN0IG9uZSBidXR0b24gYW5kIGRlc2VsZWN0IGFsbCBvdGhlciBidXR0b25zLlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBidXR0b24gdG8gc2VsZWN0XG4gICovXG4gIHNlbGVjdChpbmRleCkge1xuICAgIGlmIChpbmRleD49MCAmJiBpbmRleCA8IHRoaXMuYnV0dG9ucy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuYWN0aXZlID0gaW5kZXg7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5hY3RpdmUpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgRGVzZWxlY3QgYWxsIGJ1dHRvbnMuXG4gICovXG4gIGRlc2VsZWN0KCkge1xuICAgIHRoaXMuYWN0aXZlID0gLTE7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuYWN0aXZlKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgZ2V0IG51bWJlck9mQnV0dG9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5fbnVtYmVyT2ZCdXR0b25zO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBob3cgbWFueSBidXR0b25zIGFyZSBpbiB0aGUgaW50ZXJmYWNlXG4gICAqIEBwYXJhbSAge251bWJlcn0gYnV0dG9ucyBIb3cgbWFueSBidXR0b25zIGFyZSBpbiB0aGUgaW50ZXJmYWNlXG4gICAqL1xuICBzZXQgbnVtYmVyT2ZCdXR0b25zKGJ1dHRvbnMpIHtcbiAgICB0aGlzLl9udW1iZXJPZkJ1dHRvbnMgPSBidXR0b25zO1xuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuYnV0dG9ucy5sZW5ndGg7aSsrKSB7XG4gICAgICB0aGlzLmJ1dHRvbnNbaV0uZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLmJ1dHRvbnMgPSBbXTtcbiAgLy8gIGZvciAobGV0IGk9MDtpPHRoaXMuYnV0dG9ucy5sZW5ndGg7aSsrKSB7XG4gIC8vICAgIHRoaXMuYnV0dG9uc1tpXS5kZXN0cm95KCk7XG4gIC8vICB9XG4gICAgdGhpcy5lbXB0eSgpO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9yYWRpb2J1dHRvbi5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgU3RlcCA9IHJlcXVpcmUoJy4uL21vZGVscy9zdGVwJyk7XG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xuXG4vKipcbiogTnVtYmVyXG4qXG4qIEBkZXNjcmlwdGlvbiBOdW1iZXIgaW50ZXJmYWNlIHdoaWNoIGlzIGNvbnRyb2xsYWJsZSBieSBkcmFnZ2luZyBvciB0eXBpbmcuXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwibnVtYmVyXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgbnVtYmVyID0gbmV3IE5leHVzLk51bWJlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBudW1iZXIgPSBuZXcgTmV4dXMuTnVtYmVyKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbNjAsMzBdLFxuKiAgICd2YWx1ZSc6IDAsXG4qICAgJ21pbic6IDAsXG4qICAgJ21heCc6IDIwMDAwLFxuKiAgICdzdGVwJzogMVxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyB0aGUgbnVtYmVyIHZhbHVlIG9mIHRoZSBpbnRlcmZhY2UuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIG51bWJlci5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qXG4qL1xuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE51bWJlciBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzYwLDMwXSxcbiAgICAgICd2YWx1ZSc6IDAsXG4gICAgICAnbWluJzogMCxcbiAgICAgICdtYXgnOiAyMDAwMCxcbiAgICAgICdzdGVwJzogMVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLl92YWx1ZSA9IG5ldyBTdGVwKHRoaXMuc2V0dGluZ3MubWluLHRoaXMuc2V0dGluZ3MubWF4LHRoaXMuc2V0dGluZ3Muc3RlcCx0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIC8qXG4gICAgRGVmYXVsdDogMi4gSG93IG1hbnkgZGVjaW1hbCBwbGFjZXMgdG8gY2xpcCB0aGUgbnVtYmVyJ3MgdmlzdWFsIHJlbmRlcmluZyB0by4gVGhpcyBkb2VzIG5vdCBhZmZlY3QgbnVtYmVyJ3MgYWN0dWFsIHZhbHVlIG91dHB1dCAtLSBmb3IgdGhhdCwgc2V0IHRoZSBzdGVwIHByb3BlcnR5IHRvIC4wMSwgLjEsIG9yIDEuXG4gICAgQHR5cGUge251bWJlcn1cbiAgICBAZXhhbXBsZSBudW1iZXIuZGVjaW1hbFBsYWNlcyA9IDI7XG4gICAgKi9cbiAgICB0aGlzLmRlY2ltYWxQbGFjZXMgPSAyO1xuICAgIHRoaXMuYWN0dWFsID0gMDtcblxuICAgIHRoaXMubWF4ID0gdGhpcy5fdmFsdWUubWF4O1xuXG4gICAgdGhpcy5taW4gPSB0aGlzLl92YWx1ZS5taW47XG5cbiAgICB0aGlzLnN0ZXAgPSB0aGlzLl92YWx1ZS5zdGVwO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgIHRoaXMuZWxlbWVudC50eXBlID0gJ3RleHQnO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCBmdW5jdGlvbiAoKSB7XG4gIFx0ICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgXHQgIHRoaXMuZWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG4gIFx0ICBpZiAodGhpcy5lbGVtZW50LnZhbHVlICE9PSB0aGlzLnZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBwYXJzZUZsb2F0KHRoaXMuZWxlbWVudC52YWx1ZSk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gIFx0ICB9XG4gIFx0fS5iaW5kKHRoaXMpKTtcblxuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBmdW5jdGlvbiAoZSkge1xuICBcdCAgaWYgKGUud2hpY2ggPCA0OCB8fCBlLndoaWNoID4gNTcpIHtcbiAgXHQgIFx0aWYgKGUud2hpY2ggIT09IDE4OSAmJiBlLndoaWNoICE9PSAxOTAgJiYgZS53aGljaCAhPT0gOCkge1xuICBcdCAgXHRcdGUucHJldmVudERlZmF1bHQoKTtcbiAgXHQgIFx0fVxuICBcdCAgfVxuICBcdCAgaWYgKGUud2hpY2g9PT0xMykge1xuICBcdCAgXHR0aGlzLmVsZW1lbnQuYmx1cigpO1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5lbGVtZW50LnZhbHVlO1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gIFx0ICB9XG4gIFx0fS5iaW5kKHRoaXMpKTtcblxuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLl9taW5EaW1lbnNpb24gPSBNYXRoLm1pbih0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcblxuICAgIGxldCBzdHlsZXMgPSAnd2lkdGg6ICcgKyB0aGlzLndpZHRoICsgJ3B4Oyc7XG4gICAgc3R5bGVzICs9ICdoZWlnaHQ6ICcgKyB0aGlzLmhlaWdodCArICdweDsnO1xuICAgIHN0eWxlcyArPSAnYmFja2dyb3VuZC1jb2xvcjogI2U3ZTdlNzsnO1xuICAgIHN0eWxlcyArPSAnY29sb3I6ICMzMzM7JztcbiAgICBzdHlsZXMgKz0gJ2ZvbnQtZmFtaWx5OiBhcmlhbDsnO1xuICAgIHN0eWxlcyArPSAnZm9udC13ZWlnaHQ6IDUwMDsnO1xuICAgIHN0eWxlcyArPSAnZm9udC1zaXplOicgKyB0aGlzLl9taW5EaW1lbnNpb24vMiArICdweDsnO1xuICAvLyAgc3R5bGVzICs9ICdoaWdobGlnaHQ6ICNkMTg7JztcbiAgICBzdHlsZXMgKz0gJ2JvcmRlcjogbm9uZTsnO1xuICAgIHN0eWxlcyArPSAnb3V0bGluZTogbm9uZTsnO1xuICAgIHN0eWxlcyArPSAncGFkZGluZzogJyt0aGlzLl9taW5EaW1lbnNpb24vNCsncHggJyt0aGlzLl9taW5EaW1lbnNpb24vNCsncHg7JztcbiAgICBzdHlsZXMgKz0gJ2JveC1zaXppbmc6IGJvcmRlci1ib3g7JztcbiAgICBzdHlsZXMgKz0gJ3VzZXJTZWxlY3Q6IHRleHQ7JztcbiAgICBzdHlsZXMgKz0gJ21velVzZXJTZWxlY3Q6IHRleHQ7JztcbiAgICBzdHlsZXMgKz0gJ3dlYmtpdFVzZXJTZWxlY3Q6IHRleHQ7JztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY3NzVGV4dCArPSBzdHlsZXM7XG5cbiAgICAvLyB0byBhZGQgZXZlbnR1YWxseVxuICAgIC8vIHZhciBjc3MgPSAnIycrdGhpcy5lbGVtZW50SUQrJzo6c2VsZWN0aW9ueyBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudCB9JztcblxuICAgIHRoaXMuZWxlbWVudC52YWx1ZSA9IHRoaXMudmFsdWU7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY29sb3IgPSB0aGlzLmNvbG9ycy5kYXJrO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuXG4gICAgdGhpcy5lbGVtZW50LnZhbHVlID0gbWF0aC5wcnVuZSh0aGlzLnZhbHVlLHRoaXMuZGVjaW1hbFBsYWNlcyk7XG5cbiAgfVxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMuaGFzTW92ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmVsZW1lbnQucmVhZE9ubHkgPSB0cnVlO1xuXHQgIHRoaXMuYWN0dWFsID0gdGhpcy52YWx1ZTtcbiAgICB0aGlzLmluaXRpYWwgPSB7IHk6IHRoaXMubW91c2UueSB9O1xuICAgIHRoaXMuY2hhbmdlRmFjdG9yID0gbWF0aC5pbnZlcnQoIHRoaXMubW91c2UueCAvIHRoaXMud2lkdGggKTtcbiAgICBjb25zb2xlLmxvZyh0aGlzLmNoYW5nZUZhY3Rvcik7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIHRoaXMuaGFzTW92ZWQgPSB0cnVlO1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcblxuICAgICAgbGV0IG5ld3ZhbHVlID0gdGhpcy5hY3R1YWwgLSAodGhpcy5tb3VzZS55IC0gdGhpcy5pbml0aWFsLnkpICogKCBtYXRoLmNsaXAoIHRoaXMubWF4LXRoaXMubWluLCAwLCAxMDAwICkgLyAyMDAgKSAqIE1hdGgucG93KHRoaXMuY2hhbmdlRmFjdG9yLDIpO1xuICAgICAgdGhpcy52YWx1ZSA9IG5ld3ZhbHVlO1xuXG4gIFx0XHR0aGlzLnJlbmRlcigpO1xuICAgICAgaWYgKHRoaXMuX3ZhbHVlLmNoYW5nZWQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuICAgICAgfVxuXG4gIFx0fVxuICB9XG5cbiAgcmVsZWFzZSgpIHtcbiAgICBpZiAoIXRoaXMuaGFzTW92ZWQpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5yZWFkT25seSA9IGZhbHNlO1xuICBcdFx0dGhpcy5lbGVtZW50LmZvY3VzKCk7XG4gIFx0XHR0aGlzLmVsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UoMCwgdGhpcy5lbGVtZW50LnZhbHVlLmxlbmd0aCk7XG4gIFx0XHR0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuICBcdFx0dGhpcy5lbGVtZW50LnN0eWxlLmNvbG9yID0gdGhpcy5jb2xvcnMubGlnaHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRvY3VtZW50LmJvZHkuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgQ29ubmVjdCB0aGlzIG51bWJlciBpbnRlcmZhY2UgdG8gYSBkaWFsIG9yIHNsaWRlclxuICBAcGFyYW0ge0ludGVyZmFjZX0gZWxlbWVudCBFbGVtZW50IHRvIGNvbm5lY3QgdG8uXG4gIEBleGFtcGxlIG51bWJlci5saW5rKHNsaWRlcilcbiAgKi9cbiAgbGluayhkZXN0aW5hdGlvbikge1xuICAgIHRoaXMubWluID0gZGVzdGluYXRpb24ubWluO1xuICAgIHRoaXMubWF4ID0gZGVzdGluYXRpb24ubWF4O1xuICAgIHRoaXMuc3RlcCA9IGRlc3RpbmF0aW9uLnN0ZXA7XG4gICAgZGVzdGluYXRpb24ub24oJ2NoYW5nZScsKHYpID0+IHtcbiAgICAgIHRoaXMucGFzc2l2ZVVwZGF0ZSh2KTtcbiAgICB9KTtcbiAgICB0aGlzLm9uKCdjaGFuZ2UnLCh2KSA9PiB7XG4gICAgICBkZXN0aW5hdGlvbi52YWx1ZSA9IHY7XG4gICAgfSk7XG4gICAgdGhpcy52YWx1ZSA9IGRlc3RpbmF0aW9uLnZhbHVlO1xuICAvKiAgcmV0dXJuIHtcbiAgICAgIGxpc3RlbmVyMTogbGlzdGVuZXIxLFxuICAgICAgbGlzdGVuZXIyOiBsaXN0ZW5lcjIsXG4gICAgICBkZXN0cm95OiAoKSA9PiB7XG4gICAgICAgIGxpc3RlbmVyMS5yZW1vdmUoKSAob3Igc2ltaWxhcilcbiAgICAgICAgbGlzdGVuZXIyLnJlbW92ZSgpIChvciBzaW1pbGFyKVxuICAgICAgfVxuICAgIH0gKi9cbiAgfVxuXG4gIHBhc3NpdmVVcGRhdGUodikge1xuICAgIHRoaXMuX3ZhbHVlLnVwZGF0ZSh2KTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIFRoZSBpbnRlcmZhY2UncyBjdXJyZW50IHZhbHVlLiBJZiBzZXQgbWFudWFsbHksIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgbnVtYmVyLnZhbHVlID0gMTA7XG4gICovXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHYpIHtcbiAgICB0aGlzLl92YWx1ZS51cGRhdGUodik7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKipcbiAgTG93ZXIgbGltaXQgb2YgdGhlIG51bWJlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBudW1iZXIubWluID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1pbigpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWluO1xuICB9XG4gIHNldCBtaW4odikge1xuICAgIHRoaXMuX3ZhbHVlLm1pbiA9IHY7XG4gIH1cblxuICAvKipcbiAgVXBwZXIgbGltaXQgb2YgdGhlIG51bWJlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBudW1iZXIubWF4ID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWF4O1xuICB9XG4gIHNldCBtYXgodikge1xuICAgIHRoaXMuX3ZhbHVlLm1heCA9IHY7XG4gIH1cblxuICAvKipcbiAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBudW1iZXIncyB2YWx1ZSBjaGFuZ2VzIGJ5LlxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBudW1iZXIuc3RlcCA9IDU7XG4gICovXG4gIGdldCBzdGVwKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5zdGVwO1xuICB9XG4gIHNldCBzdGVwKHYpIHtcbiAgICB0aGlzLl92YWx1ZS5zdGVwID0gdjtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9udW1iZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xuXG4vKipcbiogU2VsZWN0XG4qXG4qIEBkZXNjcmlwdGlvbiBEcm9wZG93biBtZW51XG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwic2VsZWN0XCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc2VsZWN0ID0gbmV3IE5leHVzLlNlbGVjdCgnI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBzZWxlY3QgPSBuZXcgTmV4dXMuU2VsZWN0KCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMTAwLDMwXSxcbiogICAnb3B0aW9ucyc6IFsnZGVmYXVsdCcsJ29wdGlvbnMnXVxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgdGV4dCB2YWx1ZSBvZiB0aGUgc2VsZWN0ZWQgb3B0aW9uLCBhcyB3ZWxsIGFzIHRoZSBudW1lcmljIGluZGV4IG9mIHRoZSBzZWxlY3Rpb24uXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIHNlbGVjdC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qXG4qL1xuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNlbGVjdCBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICAnc2l6ZSc6IFsxMDAsMzBdLFxuICAgICAgICdvcHRpb25zJzogWydkZWZhdWx0Jywnb3B0aW9ucyddXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSAtMTtcbiAgICB0aGlzLl92YWx1ZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5fb3B0aW9ucyA9IHRoaXMuc2V0dGluZ3Mub3B0aW9ucztcblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2VsZWN0Jyk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmZvbnRTaXplID0gdGhpcy5oZWlnaHQvMisncHgnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5vdXRsaW5lID0gJ25vbmUnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5oaWdobGlnaHQgPSAnbm9uZSc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLndpZHRoID0gdGhpcy53aWR0aCsncHgnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmhlaWdodCsncHgnO1xuXG4gICAgdGhpcy5ib3VuZFJlbmRlciA9IHRoaXMucmVuZGVyLmJpbmQodGhpcyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5ib3VuZFJlbmRlcik7XG5cbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXG4gIH1cblxuICBhdHRhY2hMaXN0ZW5lcnMoKSB7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5kZWZpbmVPcHRpb25zKCk7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5maWxsO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmJvcmRlciA9ICdzb2xpZCAwcHggJyt0aGlzLmNvbG9ycy5tZWRpdW1MaWdodDtcbiAgfVxuXG4gIHJlbmRlcigpIHtcblxuICAgIHRoaXMuX3ZhbHVlID0gdGhpcy5lbGVtZW50Lm9wdGlvbnNbdGhpcy5lbGVtZW50LnNlbGVjdGVkSW5kZXhdLnRleHQ7XG4gICAgdGhpcy5fc2VsZWN0ZWRJbmRleCA9IHRoaXMuZWxlbWVudC5zZWxlY3RlZEluZGV4O1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICB2YWx1ZTogdGhpcy5fdmFsdWUsXG4gICAgICBpbmRleDogdGhpcy5fc2VsZWN0ZWRJbmRleFxuICAgIH0pO1xuXG4gIH1cblxuICBjbGljaygpIHtcblxuICB9XG5cbiAgbW92ZSgpIHtcblxuICB9XG5cbiAgcmVsZWFzZSgpIHtcblxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgbGlzdCBvZiBvcHRpb25zLiBUaGlzIHJlbW92ZXMgYWxsIGV4aXN0aW5nIG9wdGlvbnMgYW5kIGNyZWF0ZXMgYSBuZXcgbGlzdCBvZiBvcHRpb25zLlxuICAgKiBAcGFyYW0gIHthcnJheX0gb3B0aW9ucyBOZXcgYXJyYXkgb2Ygb3B0aW9uc1xuICAgKi9cblxuICBkZWZpbmVPcHRpb25zKG9wdGlvbnMpIHtcblxuICAvKiAgZnVuY3Rpb24gcmVtb3ZlT3B0aW9ucyhzZWxlY3Rib3gpXG4gICAge1xuICAgICAgICB2YXIgaTtcbiAgICAgICAgZm9yKGkgPSBzZWxlY3Rib3gub3B0aW9ucy5sZW5ndGggLSAxIDsgaSA+PSAwIDsgaS0tKVxuICAgICAgICB7XG4gICAgICAgICAgICBzZWxlY3Rib3gucmVtb3ZlKGkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vdXNpbmcgdGhlIGZ1bmN0aW9uOlxuICAgIHJlbW92ZU9wdGlvbnMoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJteVNlbGVjdE9iamVjdFwiKSk7ICovXG5cblxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcbiAgICB9XG5cbiAgICBmb3IobGV0IGk9dGhpcy5lbGVtZW50Lm9wdGlvbnMubGVuZ3RoLTE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB0aGlzLmVsZW1lbnQucmVtb3ZlKGkpO1xuICAgIH1cblxuICAgIGZvcihsZXQgaT0wO2k8dGhpcy5fb3B0aW9ucy5sZW5ndGg7aSsrKSB7XG4gICAgICB0aGlzLmVsZW1lbnQub3B0aW9ucy5hZGQobmV3IE9wdGlvbih0aGlzLl9vcHRpb25zW2ldLCBpKSk7XG4gICAgfVxuXG4gIH1cblxuXG4gIC8qKlxuICBUaGUgdGV4dCBvZiB0aGUgb3B0aW9uIHRoYXQgaXMgY3VycmVudGx5IHNlbGVjdGVkLiBJZiBzZXQsIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge1N0cmluZ31cbiAgQGV4YW1wbGUgc2VsZWN0LnZhbHVlID0gXCJzYXd0b290aFwiO1xuICAqL1xuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICB9XG4gIHNldCB2YWx1ZSh2KSB7XG4gICAgdGhpcy5fdmFsdWUgPSB2O1xuICAgIGZvcihsZXQgaT0wO2k8dGhpcy5lbGVtZW50Lm9wdGlvbnMubGVuZ3RoO2krKykge1xuICAgICAgaWYgKHYgPT09IHRoaXMuZWxlbWVudC5vcHRpb25zW2ldLnRleHQpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgVGhlIG51bWVyaWMgaW5kZXggb2YgdGhlIG9wdGlvbiB0aGF0IGlzIGN1cnJlbnRseSBzZWxlY3RlZC4gSWYgc2V0LCB3aWxsIHVwZGF0ZSB0aGUgaW50ZXJmYWNlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNlbGVjdC5zZWxlY3RlZEluZGV4ID0gMjtcbiAgKi9cbiAgZ2V0IHNlbGVjdGVkSW5kZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkSW5kZXg7XG4gIH1cbiAgc2V0IHNlbGVjdGVkSW5kZXgodikge1xuICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSB2O1xuICAgIHRoaXMuZWxlbWVudC5zZWxlY3RlZEluZGV4ID0gdjtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5ib3VuZFJlbmRlcik7XG4gIH1cblxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9zZWxlY3QuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IG1hdGggPSByZXF1aXJlKCcuLi91dGlsL21hdGgnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbi8qKlxuKiBEaWFsXG4qXG4qXG4qIEBkZXNjcmlwdGlvbiBEaWFsIHdpdGggcmFkaWFsIG9yIGxpbmVhciBpbnRlcmFjdGlvbi5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJkaWFsXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgZGlhbCA9IG5ldyBOZXh1cy5EaWFsKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIGRpYWwgPSBuZXcgTmV4dXMuRGlhbCgnI3RhcmdldCcse1xuKiAgICdzaXplJzogWzc1LDc1XSxcbiogICAnaW50ZXJhY3Rpb24nOiAncmFkaWFsJywgLy8gXCJyYWRpYWxcIiwgXCJ2ZXJ0aWNhbFwiLCBvciBcImhvcml6b250YWxcIlxuKiAgICdtb2RlJzogJ3JlbGF0aXZlJywgLy8gXCJhYnNvbHV0ZVwiIG9yIFwicmVsYXRpdmVcIlxuKiAgICdtaW4nOiAwLFxuKiAgICdtYXgnOiAxLFxuKiAgICdzdGVwJzogMCxcbiogICAndmFsdWUnOiAwXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIFRoZSBldmVudCBkYXRhIGlzIHRoZSBudW1iZXIgdmFsdWUgb2YgdGhlIGludGVyZmFjZS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogZGlhbC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qIEB0dXRvcmlhbFxuKiBEaWFsXG4qIHlnR014cVxuKlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGlhbCBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnbWluJywnbWF4JywndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzc1LDc1XSxcbiAgICAgICdpbnRlcmFjdGlvbic6ICdyYWRpYWwnLCAvLyByYWRpYWwsIHZlcnRpY2FsLCBob3Jpem9udGFsXG4gICAgICAnbW9kZSc6ICdyZWxhdGl2ZScsIC8vIGFic29sdXRlLCByZWxhdGl2ZVxuICAgICAgJ21pbic6IDAsXG4gICAgICAnbWF4JzogMSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDBcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvbiA9IHRoaXMuc2V0dGluZ3MuaW50ZXJhY3Rpb247XG5cbiAgICB0aGlzLl92YWx1ZSA9IG5ldyBTdGVwKHRoaXMuc2V0dGluZ3MubWluLCB0aGlzLnNldHRpbmdzLm1heCwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIHRoaXMucG9zaXRpb24gPSBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMuc2V0dGluZ3MubW9kZSx0aGlzLmludGVyYWN0aW9uLFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG5cbiAgICB0aGlzLmluaXQoKTtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblxuICAgIHRoaXMucG9zaXRpb24udmFsdWUgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXG4gICAgdGhpcy5wcmV2aW91c0FuZ2xlID0gZmFsc2U7XG5cbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5iYWNrZ3JvdW5kID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG4gICAgdGhpcy5zY3JldyA9IHN2Zy5jcmVhdGUoJ2NpcmNsZScpO1xuICAgIHRoaXMuaGFuZGxlID0gc3ZnLmNyZWF0ZSgncGF0aCcpO1xuICAgIHRoaXMuaGFuZGxlMiA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmhhbmRsZUZpbGwgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG4gICAgdGhpcy5oYW5kbGUyRmlsbCA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmhhbmRsZUxpbmUgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYWNrZ3JvdW5kKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5oYW5kbGUpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZTIpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZUZpbGwpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZTJGaWxsKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5oYW5kbGVMaW5lKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5zY3Jldyk7XG5cbiAgfVxuXG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcblxuICAgIHRoaXMucG9zaXRpb24ucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG5cbiAgICBsZXQgY2VudGVyID0ge1xuICAgICAgeDogdGhpcy53aWR0aC8yLFxuICAgICAgeTogdGhpcy5oZWlnaHQvMlxuICAgIH07XG5cbiAgICBsZXQgZGlhbWV0ZXIgPSBNYXRoLm1pbih0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcblxuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ2N4JywgY2VudGVyLngpO1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ2N5JywgY2VudGVyLnkpO1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ3InLCBkaWFtZXRlci8yLWRpYW1ldGVyLzQwKTtcblxuICAgIHRoaXMuc2NyZXcuc2V0QXR0cmlidXRlKCdjeCcsIGNlbnRlci54KTtcbiAgICB0aGlzLnNjcmV3LnNldEF0dHJpYnV0ZSgnY3knLCBjZW50ZXIueSk7XG4gICAgdGhpcy5zY3Jldy5zZXRBdHRyaWJ1dGUoJ3InLCBkaWFtZXRlci8xMik7XG5cbiAgICBsZXQgdmFsdWUgPSB0aGlzLnZhbHVlO1xuXG4gICAgbGV0IGhhbmRsZVBvaW50cyA9IHtcbiAgICAgIHN0YXJ0OiBNYXRoLlBJKjEuNSxcbiAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHZhbHVlLDAsMC41LE1hdGguUEkqMS41LE1hdGguUEkqMC41KSAsIE1hdGguUEkqMC41LCBNYXRoLlBJKjEuNSApXG4gICAgfTtcbiAgICBsZXQgaGFuZGxlMlBvaW50cyA9IHtcbiAgICAgIHN0YXJ0OiBNYXRoLlBJKjIuNSxcbiAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHZhbHVlLDAuNSwxLE1hdGguUEkqMi41LE1hdGguUEkqMS41KSAsIE1hdGguUEkqMS41LCBNYXRoLlBJKjIuNSApXG4gICAgfTtcblxuICAgIGxldCBoYW5kbGVQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZVBvaW50cy5zdGFydCwgaGFuZGxlUG9pbnRzLmVuZCk7XG4gICAgbGV0IGhhbmRsZTJQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgIHRoaXMuaGFuZGxlLnNldEF0dHJpYnV0ZSgnZCcsaGFuZGxlUGF0aCk7XG4gICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBkaWFtZXRlci8yMCk7XG4gICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcblxuICAgIHRoaXMuaGFuZGxlMi5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZTJQYXRoKTtcbiAgICB0aGlzLmhhbmRsZTIuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBkaWFtZXRlci8yMCk7XG4gICAgdGhpcy5oYW5kbGUyLnNldEF0dHJpYnV0ZSgnZmlsbCcsICdub25lJyk7XG5cbiAgICBoYW5kbGVQYXRoICs9ICcgTCAnK2NlbnRlci54KycgJytjZW50ZXIueTtcblxuICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZVBhdGgpO1xuICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwtb3BhY2l0eScsICcwLjMnKTtcblxuICAgIGhhbmRsZTJQYXRoICs9ICcgTCAnK2NlbnRlci54KycgJytjZW50ZXIueTtcblxuICAgIHRoaXMuaGFuZGxlMkZpbGwuc2V0QXR0cmlidXRlKCdkJyxoYW5kbGUyUGF0aCk7XG4gICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwtb3BhY2l0eScsICcwLjMnKTtcblxuICAgIGxldCBhcmNFbmRpbmdBO1xuICAgIGlmICh2YWx1ZSA8IDAuNSkge1xuICAgICAgYXJjRW5kaW5nQSA9IGhhbmRsZVBvaW50cy5lbmQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFyY0VuZGluZ0EgPSBoYW5kbGUyUG9pbnRzLmVuZDtcbiAgICB9XG5cbiAgICBsZXQgYXJjRW5kaW5nWCA9IGNlbnRlci54ICsgTWF0aC5jb3MoYXJjRW5kaW5nQSkgKiAoZGlhbWV0ZXIvMik7XG4gICAgbGV0IGFyY0VuZGluZ1kgPSBjZW50ZXIueSArIE1hdGguc2luKGFyY0VuZGluZ0EpICogKGRpYW1ldGVyLzIpICogLTE7XG5cbiAgICB0aGlzLmhhbmRsZUxpbmUuc2V0QXR0cmlidXRlKCdkJywnTSAnK2NlbnRlci54KycgJytjZW50ZXIueSsnIEwgJythcmNFbmRpbmdYKycgJythcmNFbmRpbmdZKTtcbiAgICB0aGlzLmhhbmRsZUxpbmUuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBkaWFtZXRlci8yMCk7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5maWxsKTtcbiAgICB0aGlzLnNjcmV3LnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKCdzdHJva2UnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMuaGFuZGxlMi5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5oYW5kbGVGaWxsLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMuaGFuZGxlTGluZS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXG4gICAgbGV0IGNlbnRlciA9IHtcbiAgICAgIHg6IHRoaXMud2lkdGgvMixcbiAgICAgIHk6IHRoaXMuaGVpZ2h0LzJcbiAgICB9O1xuXG4gICAgbGV0IGRpYW1ldGVyID0gTWF0aC5taW4odGhpcy53aWR0aCx0aGlzLmhlaWdodCk7XG5cbiAgICBsZXQgaGFuZGxlUG9pbnRzID0ge1xuICAgICAgc3RhcnQ6IE1hdGguUEkqMS41LFxuICAgICAgZW5kOiBtYXRoLmNsaXAoIG1hdGguc2NhbGUodmFsdWUsMCwwLjUsTWF0aC5QSSoxLjUsTWF0aC5QSSowLjUpICwgTWF0aC5QSSowLjUsIE1hdGguUEkqMS41IClcbiAgICB9O1xuICAgIGxldCBoYW5kbGUyUG9pbnRzID0ge1xuICAgICAgc3RhcnQ6IE1hdGguUEkgKjIuNSxcbiAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHZhbHVlLDAuNSwxLE1hdGguUEkqMi41LE1hdGguUEkqMS41KSAsIE1hdGguUEkqMS41LCBNYXRoLlBJKjIuNSApXG4gICAgfTtcblxuICAgIGxldCBoYW5kbGVQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZVBvaW50cy5zdGFydCwgaGFuZGxlUG9pbnRzLmVuZCk7XG4gICAgbGV0IGhhbmRsZTJQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgIHRoaXMuaGFuZGxlLnNldEF0dHJpYnV0ZSgnZCcsaGFuZGxlUGF0aCk7XG4gICAgdGhpcy5oYW5kbGUyLnNldEF0dHJpYnV0ZSgnZCcsaGFuZGxlMlBhdGgpO1xuXG5cbiAgICBoYW5kbGVQYXRoICs9ICcgTCAnK2NlbnRlci54KycgJytjZW50ZXIueTtcblxuICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZVBhdGgpO1xuXG4gICAgaGFuZGxlMlBhdGggKz0gJyBMICcrY2VudGVyLngrJyAnK2NlbnRlci55O1xuXG4gICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZTJQYXRoKTtcblxuICAgIGxldCBhcmNFbmRpbmdBO1xuICAgIGlmICh2YWx1ZSA8PSAwLjUpIHtcbiAgICAgIGFyY0VuZGluZ0EgPSBoYW5kbGVQb2ludHMuZW5kO1xuICAgIH0gZWxzZSB7XG4gICAgICBhcmNFbmRpbmdBID0gaGFuZGxlMlBvaW50cy5lbmQ7XG4gICAgfVxuXG4gICAgbGV0IGFyY0VuZGluZ1ggPSBjZW50ZXIueCArIE1hdGguY29zKGFyY0VuZGluZ0EpICogKGRpYW1ldGVyLzIpO1xuICAgIGxldCBhcmNFbmRpbmdZID0gY2VudGVyLnkgKyBNYXRoLnNpbihhcmNFbmRpbmdBKSAqIChkaWFtZXRlci8yKSAqIC0xO1xuXG4gICAgdGhpcy5oYW5kbGVMaW5lLnNldEF0dHJpYnV0ZSgnZCcsJ00gJytjZW50ZXIueCsnICcrY2VudGVyLnkrJyBMICcrYXJjRW5kaW5nWCsnICcrYXJjRW5kaW5nWSk7XG5cbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgaWYgKHRoaXMubW9kZT09PSdyZWxhdGl2ZScpIHtcbiAgICAgIHRoaXMucHJldmlvdXNBbmdsZSA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5tb3ZlKCk7XG4gICB9XG5cbiAgbW92ZSgpIHtcbiAgICBpZiAodGhpcy5jbGlja2VkKSB7XG5cbiAgICAgIHRoaXMucG9zaXRpb24udXBkYXRlKHRoaXMubW91c2UpO1xuXG4gICAgICBsZXQgYW5nbGUgPSB0aGlzLnBvc2l0aW9uLnZhbHVlKk1hdGguUEkqMjtcblxuICAgICAgaWYgKGFuZ2xlIDwgMCApIHsgYW5nbGUgKz0gKE1hdGguUEkqMik7IH1cblxuICAgICAgaWYgKHRoaXMubW9kZSA9PT0gJ3JlbGF0aXZlJykge1xuICAgICAgICBpZiAodGhpcy5wcmV2aW91c0FuZ2xlICE9PSBmYWxzZSAmJiBNYXRoLmFicyh0aGlzLnByZXZpb3VzQW5nbGUgLSBhbmdsZSkgPiAyKSB7XG4gICAgICAgICAgaWYgKHRoaXMucHJldmlvdXNBbmdsZSA+IDMpIHtcbiAgICAgICAgICAgIGFuZ2xlID0gTWF0aC5QSSoyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbmdsZSA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IC8qIGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5wcmV2aW91c0FuZ2xlICE9PSBmYWxzZSAmJiBNYXRoLmFicyh0aGlzLnByZXZpb3VzQW5nbGUgLSBhbmdsZSkgPiAyKSB7XG4gICAgICAgICAgaWYgKHRoaXMucHJldmlvdXNBbmdsZSA+IDMpIHtcbiAgICAgICAgICAgIGFuZ2xlID0gTWF0aC5QSSoyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbmdsZSA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9ICovXG4gICAgICB0aGlzLnByZXZpb3VzQW5nbGUgPSBhbmdsZTtcblxuICAgICAgbGV0IHJlYWxWYWx1ZSA9IGFuZ2xlIC8gKE1hdGguUEkqMik7XG5cbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS51cGRhdGVOb3JtYWwoIHJlYWxWYWx1ZSApO1xuXG4gICAgICBpZiAodGhpcy5tb2RlID09PSAncmVsYXRpdmUnKSB7XG4gICAgICAgIHRoaXMucG9zaXRpb24udmFsdWUgPSByZWFsVmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLl92YWx1ZS52YWx1ZSk7XG5cbiAgICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICB9XG4gIH1cblxuICByZWxlYXNlKCkge1xuICB9XG5cbiAgLypcbiAgRGlhbCdzIHZhbHVlLiBXaGVuIHNldCwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGFkanVzdCB0byBmaXQgbWluL21heC9zdGVwIHNldHRpbmdzIG9mIHRoZSBpbnRlcmZhY2UuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIGRpYWwudmFsdWUgPSAxMDtcblxuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuICB9XG5cbiAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgdGhpcy5fdmFsdWUudXBkYXRlKHZhbHVlKTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuKi9cblxuICAgIC8qKlxuICAgIERpYWwncyB2YWx1ZS4gV2hlbiBzZXQsIGl0IHdpbGwgYXV0b21hdGljYWxseSBiZSBhZGp1c3QgdG8gZml0IG1pbi9tYXgvc3RlcCBzZXR0aW5ncyBvZiB0aGUgaW50ZXJmYWNlLlxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC52YWx1ZSA9IDEwO1xuICAgICovXG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuICAgIH1cbiAgICBzZXQgdmFsdWUodikge1xuICAgICAgdGhpcy5fdmFsdWUudXBkYXRlKHYpO1xuICAgICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5fdmFsdWUudmFsdWUpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICBMb3dlciBsaW1pdCBvZiB0aGUgZGlhbCdzIG91dHB1dCByYW5nZVxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC5taW4gPSAxMDAwO1xuICAgICovXG4gICAgZ2V0IG1pbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5taW47XG4gICAgfVxuICAgIHNldCBtaW4odikge1xuICAgICAgdGhpcy5fdmFsdWUubWluID0gdjtcbiAgICB9XG5cbiAgICAvKipcbiAgICBVcHBlciBsaW1pdCBvZiB0aGUgZGlhbCdzIG91dHB1dCByYW5nZVxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC5tYXggPSAxMDAwO1xuICAgICovXG4gICAgZ2V0IG1heCgpIHtcbiAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5tYXg7XG4gICAgfVxuICAgIHNldCBtYXgodikge1xuICAgICAgdGhpcy5fdmFsdWUubWF4ID0gdjtcbiAgICB9XG5cbiAgICAvKipcbiAgICBUaGUgaW5jcmVtZW50IHRoYXQgdGhlIGRpYWwncyB2YWx1ZSBjaGFuZ2VzIGJ5LlxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC5zdGVwID0gNTtcbiAgICAqL1xuICAgIGdldCBzdGVwKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnN0ZXA7XG4gICAgfVxuICAgIHNldCBzdGVwKHYpIHtcbiAgICAgIHRoaXMuX3ZhbHVlLnN0ZXAgPSB2O1xuICAgIH1cblxuICAgIC8qKlxuICAgIEFic29sdXRlIG1vZGUgKGRpYWwncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJyZWxhdGl2ZVwiLlxuICAgIEB0eXBlIHtzdHJpbmd9XG4gICAgQGV4YW1wbGUgZGlhbC5tb2RlID0gXCJyZWxhdGl2ZVwiO1xuICAgICovXG4gICAgZ2V0IG1vZGUoKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi5tb2RlO1xuICAgIH1cbiAgICBzZXQgbW9kZSh2KSB7XG4gICAgICB0aGlzLnBvc2l0aW9uLm1vZGUgPSB2O1xuICAgIH1cblxuXG4gIC8qKlxuICBOb3JtYWxpemVkIHZhbHVlIG9mIHRoZSBkaWFsLlxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBkaWFsLm5vcm1hbGl6ZWQgPSAwLjU7XG4gICovXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuICB9XG5cbiAgc2V0IG5vcm1hbGl6ZWQodikge1xuICAgIHRoaXMuX3ZhbHVlLnVwZGF0ZU5vcm1hbCh2KTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvZGlhbC5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcbmxldCBCdXR0b25UZW1wbGF0ZSA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvYnV0dG9udGVtcGxhdGUnKTtcbmxldCB0b3VjaCA9IHJlcXVpcmUoJy4uL3V0aWwvdG91Y2gnKTtcblxuY2xhc3MgUGlhbm9LZXkgZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnLCdub3RlJywnY29sb3InXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzgwLDgwXSxcbiAgICAgICd0YXJnZXQnOiBmYWxzZSxcbiAgICAgICdtb2RlJzogJ2J1dHRvbicsXG4gICAgICAndmFsdWUnOiAwXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMubm90ZSA9IHRoaXMuc2V0dGluZ3Mubm90ZTtcbiAgICB0aGlzLmNvbG9yID0gdGhpcy5zZXR0aW5ncy5jb2xvcjtcblxuICAgIHRoaXMuY29sb3JzID0ge1xuICAgICAgJ3cnOiAnI2ZmZicsXG4gICAgICAnYic6ICcjNjY2JyxcbiAgICB9O1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5wYWQgPSBzdmcuY3JlYXRlKCdyZWN0Jyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wYWQpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXG4gICAgLyogZXZlbnRzICovXG5cbiAgICBpZiAoIXRvdWNoLmV4aXN0cykge1xuXG4gICAgICB0aGlzLmNsaWNrID0gKCkgPT4ge1xuICAgICAgLy8gIGNvbnNvbGUubG9nKCdjbGljaycpO1xuICAgICAgICB0aGlzLnBpYW5vLmludGVyYWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5waWFuby5wYWludGJydXNoID0gIXRoaXMuc3RhdGU7XG4gICAgICAgIHRoaXMuZG93bih0aGlzLnBpYW5vLnBhaW50YnJ1c2gpO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5waWFuby5pbnRlcmFjdGluZykge1xuICAgICAgLy8gICAgY29uc29sZS5sb2coJ21vdXNlb3ZlcicpO1xuICAgICAgICAgIHRoaXMuZG93bih0aGlzLnBpYW5vLnBhaW50YnJ1c2gpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuXG4gICAgICB0aGlzLm1vdmUgPSAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnBpYW5vLmludGVyYWN0aW5nKSB7XG4gICAgICAgIC8vICBjb25zb2xlLmxvZygnbW92ZScpO1xuICAgICAgICAgIHRoaXMuYmVuZCgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG5cbiAgICAgIHRoaXMucmVsZWFzZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5waWFuby5pbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgICAgLy8gIGNvbnNvbGUubG9nKCdyZWxlYXNlJyk7XG4gICAgICAvLyAgdGhpcy51cCgpO1xuICAgICAgfTtcbiAgICAgIHRoaXMucGFkLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnBpYW5vLmludGVyYWN0aW5nKSB7XG4gICAgICAgIC8vICBjb25zb2xlLmxvZygnbW91c2V1cCcpO1xuICAgICAgICAgIHRoaXMudXAoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLnBhZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMucGlhbm8uaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgLy8gIGNvbnNvbGUubG9nKCdtb3VzZW91dCcpO1xuICAgICAgICAgIHRoaXMudXAoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICB9XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICAgICAgLy9sZXQgcmFkaXVzID0gTWF0aC5taW4odGhpcy53aWR0aCx0aGlzLmhlaWdodCkgLyA1O1xuICAgICAgICBsZXQgcmFkaXVzID0gMDtcblxuICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3gnLDAuNSk7XG4gICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgneScsMC41KTtcbiAgICAgICAgaWYgKHRoaXMud2lkdGggPiAyKSB7XG4gICAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMud2lkdGggLSAxKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgdGhpcy53aWR0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaGVpZ2h0ID4gMikge1xuICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgncngnLCByYWRpdXMpO1xuICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3J5JywgcmFkaXVzKTtcblxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5zdGF0ZSkge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnNbdGhpcy5jb2xvcl0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIH1cbiAgfVxuXG59XG5cbi8qKlxuKiBQaWFub1xuKlxuKiBAZGVzY3JpcHRpb24gUGlhbm8ga2V5Ym9hcmQgaW50ZXJmYWNlXG4qXG4qIEBkZW1vIDxkaXYgbmV4dXMtdWk9XCJwaWFub1wiPjwvZGl2PlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcGlhbm8gPSBuZXcgTmV4dXMuUGlhbm8oJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcGlhbm8gPSBuZXcgTmV4dXMuUGlhbm8oJyN0YXJnZXQnLHtcbiogICAgICdzaXplJzogWzUwMCwxMjVdLFxuKiAgICAgJ21vZGUnOiAnYnV0dG9uJywgIC8vICdidXR0b24nLCAndG9nZ2xlJywgb3IgJ2ltcHVsc2UnXG4qICAgICAnbG93Tm90ZSc6IDI0LFxuKiAgICAgJ2hpZ2hOb3RlJzogNjBcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgYSBuZXcga2V5IGlzIHByZXNzZWQgb3IgcmVsZWFzZWQgPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyA8aT5ub3RlPC9pPiBhbmQgPGk+c3RhdGU8L2k+IHByb3BlcnRpZXMuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIHBpYW5vLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBpYW5vIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbNTAwLDEyNV0sXG4gICAgICAnbG93Tm90ZSc6IDI0LFxuICAgICAgJ2hpZ2hOb3RlJzogNjAsXG4gICAgICAnbW9kZSc6ICdidXR0b24nXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMua2V5UGF0dGVybiA9IFsndycsJ2InLCd3JywnYicsJ3cnLCd3JywnYicsJ3cnLCdiJywndycsJ2InLCd3J107XG5cbiAgICB0aGlzLnBhaW50YnJ1c2ggPSBmYWxzZTtcblxuICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZTtcblxuICAgIHRoaXMucmFuZ2UgPSB7XG4gICAgICBsb3c6IHRoaXMuc2V0dGluZ3MubG93Tm90ZSxcbiAgICAgIGhpZ2g6IHRoaXMuc2V0dGluZ3MuaGlnaE5vdGVcbiAgICB9O1xuXG4gICAgdGhpcy5yYW5nZS5zaXplID0gdGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7XG5cbiAgICB0aGlzLmtleXMgPSBbXTtcblxuICAgIHRoaXMudG9nZ2xlVG8gPSBmYWxzZTtcblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYm9yZGVyUmFkaXVzID0gJzBweCc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcblxuICAgIHRoaXMua2V5cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7aSsrKSB7XG5cbiAgICAgIGxldCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICBsZXQgc2NhbGVJbmRleCA9IChpK3RoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG5cbiAgICAgIGxldCBrZXkgPSBuZXcgUGlhbm9LZXkoY29udGFpbmVyLCB7XG4gICAgICAgICAgY29tcG9uZW50OiB0cnVlLFxuICAgICAgICAgIG5vdGU6IGkrdGhpcy5yYW5nZS5sb3csXG4gICAgICAgICAgY29sb3I6IHRoaXMua2V5UGF0dGVybltzY2FsZUluZGV4XSxcbiAgICAgICAgICBtb2RlOiB0aGlzLm1vZGVcbiAgICAgICAgfSwgdGhpcy5rZXlDaGFuZ2UuYmluZCh0aGlzLGkrdGhpcy5yYW5nZS5sb3cpKTtcblxuICAgICAga2V5LnBpYW5vID0gdGhpcztcblxuICAgICAgaWYgKHRvdWNoLmV4aXN0cykge1xuICAgICAgICBrZXkucGFkLmluZGV4ID0gaTtcbiAgICAgICAga2V5LnByZUNsaWNrID0ga2V5LnByZU1vdmUgPSBrZXkucHJlUmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgICBrZXkuY2xpY2sgPSBrZXkubW92ZSA9IGtleS5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgICAgIGtleS5wcmVUb3VjaCA9IGtleS5wcmVUb3VjaE1vdmUgPSBrZXkucHJlVG91Y2hSZWxlYXNlID0gKCkgPT4ge307XG4gICAgICAgIGtleS50b3VjaCA9IGtleS50b3VjaE1vdmUgPSBrZXkudG91Y2hSZWxlYXNlID0gKCkgPT4ge307XG4gICAgICB9XG5cbiAgICAgIHRoaXMua2V5cy5wdXNoKGtleSk7XG4gICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblxuICAgIH1cbiAgICBpZiAodG91Y2guZXhpc3RzKSB7XG4gICAgICB0aGlzLmFkZFRvdWNoTGlzdGVuZXJzKCk7XG4gICAgfVxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgbGV0IGtleVggPSAwO1xuXG4gICAgbGV0IGtleVBvc2l0aW9ucyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7aSsrKSB7XG5cbiAgICAgIGtleVBvc2l0aW9ucy5wdXNoKGtleVgpO1xuXG4gICAgICBsZXQgc2NhbGVJbmRleCA9IChpK3RoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG4gICAgICBsZXQgbmV4dFNjYWxlSW5kZXggPSAoaSsxK3RoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG4gICAgICBpZiAoaSsxK3RoaXMucmFuZ2UubG93ID49IHRoaXMucmFuZ2UuaGlnaCkge1xuICAgICAgICBrZXlYICs9IDE7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMua2V5UGF0dGVybltzY2FsZUluZGV4XSA9PT0gJ3cnICYmIHRoaXMua2V5UGF0dGVybltuZXh0U2NhbGVJbmRleF0gPT09ICd3Jykge1xuICAgICAgICBrZXlYICs9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBrZXlYICs9IDAuNTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IGtleXNXaWRlID0ga2V5WDtcblxuXG4gIC8vICBsZXQgcGFkZGluZyA9IHRoaXMud2lkdGggLyAxMjA7XG4gICAgbGV0IHBhZGRpbmcgPSAxO1xuICAgIGxldCBidXR0b25XaWR0aCA9ICh0aGlzLndpZHRoLXBhZGRpbmcqMikgLyBrZXlzV2lkZTtcbiAgICBsZXQgYnV0dG9uSGVpZ2h0ID0gKHRoaXMuaGVpZ2h0LXBhZGRpbmcqMikgLyAyO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5rZXlzLmxlbmd0aDtpKyspIHtcblxuICAgICAgbGV0IGNvbnRhaW5lciA9IHRoaXMua2V5c1tpXS5wYXJlbnQ7XG4gICAgICBjb250YWluZXIuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgY29udGFpbmVyLnN0eWxlLmxlZnQgPSAoa2V5UG9zaXRpb25zW2ldKmJ1dHRvbldpZHRoK3BhZGRpbmcpICsgJ3B4JztcbiAgICAgIGlmICh0aGlzLmtleXNbaV0uY29sb3IgPT09ICd3Jykge1xuICAgICAgICBjb250YWluZXIuc3R5bGUudG9wID0gKHBhZGRpbmcpICsgJ3B4JztcbiAgICAgICAgdGhpcy5rZXlzW2ldLnJlc2l6ZShidXR0b25XaWR0aCwgYnV0dG9uSGVpZ2h0KjIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGFpbmVyLnN0eWxlLnpJbmRleCA9IDE7XG4gICAgICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSBwYWRkaW5nKydweCc7XG4gICAgICAgIHRoaXMua2V5c1tpXS5yZXNpemUoYnV0dG9uV2lkdGgsIGJ1dHRvbkhlaWdodCoxLjEpO1xuICAgICAgfVxuXG4gICAgfVxuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIC8vIFBpYW5vIGtleXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSBhIHN0cm9rZSBib3JkZXJcbiAgICAvLyBUaGV5IGhhdmUgc3BhY2UgYmV0d2VlbiB0aGVtLCB3aGljaCBzaG93cyB0aGUgUGlhbm8gYmcgY29sb3JcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQ7XG5cbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLmtleXMubGVuZ3RoO2krKykge1xuICAgICAgdGhpcy5rZXlzW2ldLmNvbG9ycyA9IHtcbiAgICAgICAgJ3cnOiB0aGlzLmNvbG9ycy5saWdodCxcbiAgICAgICAgJ2InOiB0aGlzLmNvbG9ycy5kYXJrLFxuICAgICAgICAnYWNjZW50JzogdGhpcy5jb2xvcnMuYWNjZW50LFxuICAgICAgICAnYm9yZGVyJzogdGhpcy5jb2xvcnMubWVkaXVtTGlnaHRcbiAgICAgIH07XG4gICAgICB0aGlzLmtleXNbaV0uY29sb3JJbnRlcmZhY2UoKTtcbiAgICAgIHRoaXMua2V5c1tpXS5yZW5kZXIoKTtcbiAgICB9XG5cblxuICB9XG5cbiAga2V5Q2hhbmdlKG5vdGUsb24pIHtcbiAgICAvLyBlbWl0IGRhdGEgZm9yIGFueSBrZXkgdHVybmluZyBvbi9vZmZcbiAgICAvLyBcIm5vdGVcIiBpcyB0aGUgbm90ZSB2YWx1ZVxuICAgIC8vIFwib25cIiBpcyBhIGJvb2xlYW4gd2hldGhlciBpdCBpcyBvbiBvciBvZmZcbiAgICAvLyBpbiBhZnRlcnRvdWNoIG1vZGUsIFwib246IGlzIGFuIG9iamVjdCB3aXRoIHN0YXRlL3gveSBwcm9wZXJ0aWVzXG4gICAgdmFyIGRhdGEgPSB7XG4gICAgICBub3RlOiBub3RlXG4gICAgfTtcbiAgICBpZiAodHlwZW9mIG9uID09PSAnb2JqZWN0Jykge1xuICAgICAgZGF0YS5zdGF0ZSA9IG9uLnN0YXRlO1xuICAgIC8vICBkYXRhLnggPSBvbi54XG4gICAgLy8gIGRhdGEueSA9IG9uLnlcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YS5zdGF0ZSA9IG9uO1xuICAgIH1cbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsZGF0YSk7XG4gIH1cblxuICAvKiBkcmFnKG5vdGUsb24pIHtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgbm90ZTogbm90ZSxcbiAgICAgIHN0YXRlOiBvblxuICAgIH0pO1xuICB9ICovXG5cbiAgcmVuZGVyKCkge1xuICAgIC8vIGxvb3AgdGhyb3VnaCBhbmQgcmVuZGVyIHRoZSBrZXlzP1xuICB9XG5cblxuICBhZGRUb3VjaExpc3RlbmVycygpIHtcblxuICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuXG4gICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGZhbHNlO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoZSkgPT4ge1xuICAgICAgY29uc29sZS5sb2coJ3RvdWNoc3RhcnQnKTtcbiAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCxlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG4gICAgICBsZXQga2V5ID0gdGhpcy5rZXlzW2VsZW1lbnQuaW5kZXhdO1xuICAgICAgdGhpcy5wYWludGJydXNoID0gIWtleS5zdGF0ZTtcbiAgICAgIGtleS5kb3duKHRoaXMucGFpbnRicnVzaCk7XG4gICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZWxlbWVudC5pbmRleDtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgKGUpID0+IHtcbiAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCxlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG4gICAgICBsZXQga2V5ID0gdGhpcy5rZXlzW2VsZW1lbnQuaW5kZXhdO1xuICAgICAgaWYgKGVsZW1lbnQuaW5kZXghPT10aGlzLmN1cnJlbnRFbGVtZW50KSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgbGV0IHBhc3RLZXkgPSB0aGlzLmtleXNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICAgICAgcGFzdEtleS51cCgpO1xuICAgICAgICB9XG4gICAgICAgIGtleS5kb3duKHRoaXMucGFpbnRicnVzaCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBrZXkuYmVuZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGVsZW1lbnQuaW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgKGUpID0+IHtcbiAgICAgIC8vIG5vIHRvdWNoZXMgdG8gY2FsY3VsYXRlIGJlY2F1c2Ugbm9uZSByZW1haW5pbmdcbiAgICAgIGxldCBrZXkgPSB0aGlzLmtleXNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICBrZXkudXAoKTtcbiAgICAgIHRoaXMuaW50ZXJhY3RpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBmYWxzZTtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIC8qKlxuICBEZWZpbmUgdGhlIHBpdGNoIHJhbmdlIChsb3dlc3QgYW5kIGhpZ2hlc3Qgbm90ZSkgb2YgdGhlIHBpYW5vIGtleWJvYXJkLlxuICBAcGFyYW0gbG93IHtudW1iZXJ9IE1JREkgbm90ZSB2YWx1ZSBvZiB0aGUgbG93ZXN0IG5vdGUgb24gdGhlIGtleWJvYXJkXG4gIEBwYXJhbSBoaWdoIHtudW1iZXJ9IE1JREkgbm90ZSB2YWx1ZSBvZiB0aGUgaGlnaGVzdCBub3RlIG9uIHRoZSBrZXlib2FyZFxuICAqL1xuICBzZXRSYW5nZShsb3csaGlnaCkge1xuICAgIHRoaXMucmFuZ2UubG93ID0gbG93O1xuICAgIHRoaXMucmFuZ2UuaGlnaCA9IGhpZ2g7XG4gICAgdGhpcy5lbXB0eSgpO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgfVxuXG4gIC8qKlxuICBUdXJuIGEga2V5IG9uIG9yIG9mZiB1c2luZyBpdHMgTUlESSBub3RlIHZhbHVlO1xuICBAcGFyYW0gbm90ZSB7bnVtYmVyfSBNSURJIG5vdGUgdmFsdWUgb2YgdGhlIGtleSB0byBjaGFuZ2VcbiAgQHBhcmFtIG9uIHtib29sZWFufSBXaGV0aGVyIHRoZSBub3RlIHNob3VsZCB0dXJuIG9uIG9yIG9mZlxuICAqL1xuICB0b2dnbGVLZXkobm90ZSwgb24pIHtcbiAgICB0aGlzLmtleXNbbm90ZS10aGlzLnJhbmdlLmxvd10uZmxpcChvbik7XG4gIH1cblxuICAvKipcbiAgVHVybiBhIGtleSBvbiBvciBvZmYgdXNpbmcgaXRzIGtleSBpbmRleCBvbiB0aGUgcGlhbm8gaW50ZXJmYWNlLlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gSW5kZXggb2YgdGhlIGtleSB0byBjaGFuZ2VcbiAgQHBhcmFtIG9uIHtib29sZWFufSBXaGV0aGVyIHRoZSBub3RlIHNob3VsZCB0dXJuIG9uIG9yIG9mZlxuICAqL1xuICB0b2dnbGVJbmRleChpbmRleCwgb24pIHtcbiAgICB0aGlzLmtleXNbaW5kZXhdLmZsaXAob24pO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL3BpYW5vLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBkb20gPSByZXF1aXJlKCcuLi91dGlsL2RvbScpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgQnV0dG9uVGVtcGxhdGUgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL2J1dHRvbnRlbXBsYXRlJyk7XG5sZXQgTWF0cml4TW9kZWwgPSByZXF1aXJlKCcuLi9tb2RlbHMvbWF0cml4Jyk7XG5sZXQgQ291bnRlck1vZGVsID0gcmVxdWlyZSgnLi4vbW9kZWxzL2NvdW50ZXInKTtcbmxldCB0b3VjaCA9IHJlcXVpcmUoJy4uL3V0aWwvdG91Y2gnKTtcblxuXG5cbmNsYXNzIE1hdHJpeENlbGwgZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnLF07XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFs4MCw4MF0sXG4gICAgICAndGFyZ2V0JzogZmFsc2UsXG4gICAgICAnbW9kZSc6ICd0b2dnbGUnLFxuICAgICAgJ3ZhbHVlJzogMFxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLmluZGV4ID0gdGhpcy5zZXR0aW5ncy5pbmRleDtcbiAgICB0aGlzLnJvdyA9IHRoaXMuc2V0dGluZ3Mucm93O1xuICAgIHRoaXMuY29sdW1uID0gdGhpcy5zZXR0aW5ncy5jb2x1bW47XG5cbiAgICB0aGlzLm1hdHJpeCA9IHRoaXMuc2V0dGluZ3MubWF0cml4O1xuXG4gICAgdGhpcy5pbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgIHRoaXMucGFpbnRicnVzaCA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnRvcCA9ICcwcHgnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5sZWZ0ID0gJzBweCc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLnBhZCA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wYWQpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXG4gICAgLyogZXZlbnRzICovXG5cbiAgICBpZiAoIXRvdWNoLmV4aXN0cykge1xuXG4gICAgICB0aGlzLmNsaWNrID0gKCkgPT4ge1xuICAgICAgICB0aGlzLm1hdHJpeC5pbnRlcmFjdGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMubWF0cml4LnBhaW50YnJ1c2ggPSAhdGhpcy5zdGF0ZTtcbiAgICAgICAgdGhpcy5kb3duKHRoaXMubWF0cml4LnBhaW50YnJ1c2gpO1xuICAgICAgfTtcbiAgICAgIHRoaXMucGFkLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3ZlcicsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubWF0cml4LmludGVyYWN0aW5nKSB7XG4gICAgICAgICAgdGhpcy5kb3duKHRoaXMubWF0cml4LnBhaW50YnJ1c2gpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuXG4gICAgICB0aGlzLm1vdmUgPSAoKSA9PiB7XG4gICAgICB9O1xuICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGUpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubWF0cml4LmludGVyYWN0aW5nKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLm9mZnNldCkge1xuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBkb20uZmluZFBvc2l0aW9uKHRoaXMuZWxlbWVudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSx0aGlzLm9mZnNldCk7XG4gICAgICAgICAgdGhpcy5iZW5kKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG5cbiAgICAgIHRoaXMucmVsZWFzZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5tYXRyaXguaW50ZXJhY3RpbmcgPSBmYWxzZTtcbiAgICAgIH07XG4gICAgICB0aGlzLnBhZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tYXRyaXguaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdXQnLCAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLm1hdHJpeC5pbnRlcmFjdGluZykge1xuICAgICAgICAgIHRoaXMudXAoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd4JywxKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3knLDEpO1xuICAgIGlmICh0aGlzLndpZHRoID4gMikge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMud2lkdGggLSAyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMud2lkdGgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5oZWlnaHQgPiAyKSB7XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIHRoaXMuaGVpZ2h0IC0gMik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQpO1xuICAgIH1cbiAgICAvL3RoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQgLSAyKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLm1hdHJpeC5jb2xvcnMuZmlsbCk7XG5cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMubWF0cml4LmNvbG9ycy5maWxsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5tYXRyaXguY29sb3JzLmFjY2VudCk7XG4gICAgfVxuICB9XG5cbn1cblxuLyoqXG4qIFNlcXVlbmNlclxuKlxuKiBAZGVzY3JpcHRpb24gR3JpZCBvZiBidXR0b25zIHdpdGggYnVpbHQtaW4gc3RlcCBzZXF1ZW5jZXIuXG4qXG4qIEBkZW1vIDxkaXYgbmV4dXMtdWk9XCJzZXF1ZW5jZXJcIiBzdHlsZT1cIndpZHRoOjQwMHB4O2hlaWdodDoyMDBweDtcIj48L2Rpdj5cbipcbiogQGV4YW1wbGVcbiogdmFyIHNlcXVlbmNlciA9IG5ldyBOZXh1cy5TZXF1ZW5jZXIoJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc2VxdWVuY2VyID0gbmV3IE5leHVzLlNlcXVlbmNlcignI3RhcmdldCcse1xuKiAgJ3NpemUnOiBbNDAwLDIwMF0sXG4qICAnbW9kZSc6ICd0b2dnbGUnLFxuKiAgJ3Jvd3MnOiA1LFxuKiAgJ2NvbHVtbnMnOiAxMFxuKn0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyBtYXRyaXggY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyA8aT5yb3c8L2k+IChudW1iZXIpLCA8aT5jb2x1bW48L2k+IChudW1iZXIpLCBhbmQgPGk+c3RhdGU8L2k+IChib29sZWFuKSBwcm9wZXJ0aWVzLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiBzZXF1ZW5jZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIHN0ZXBcbiogRmlyZXMgYW55IHRpbWUgdGhlIHNlcXVlbmNlciBzdGVwcyB0byB0aGUgbmV4dCBjb2x1bW4sIGluIHNlcXVlY2UgbW9kZS4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiA8aT5hcnJheTwvaT4gY29udGFpbmluZyBhbGwgdmFsdWVzIGluIHRoZSBjb2x1bW4sIDxpPmJvdHRvbSByb3cgZmlyc3Q8L2k+LlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiBzZXF1ZW5jZXIub24oJ3N0ZXAnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNlcXVlbmNlciBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzQwMCwyMDBdLFxuICAgICAgJ21vZGUnOiAndG9nZ2xlJyxcbiAgICAgICdyb3dzJzogNSxcbiAgICAgICdjb2x1bW5zJzogMTBcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5hY3RpdmUgPSAtMTtcblxuICAgIC8qKlxuICAgICogQnV0dG9uIGludGVyYWN0aW9uIG1vZGU6IHNlZSBCdXR0b25cbiAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgKiBAZXhhbXBsZSBidXR0b24ubW9kZSA9ICd0b2dnbGUnO1xuICAgICovXG4gICAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXG4gICAgLyoqXG4gICAgKiBUaGUgaW50ZXJ2YWwgb2JqZWN0IHdoaWNoIGNvbnRyb2xzIHRpbWluZyBhbmQgc2VxdWVuY2Ugc2NoZWR1bGluZy5cbiAgICAqIEB0eXBlIHtpbnRlcnZhbH1cbiAgICAqL1xuICAgIHRoaXMuaW50ZXJ2YWwgPSBuZXcgTmV4dXMuSW50ZXJ2YWwoMjAwLGZ1bmN0aW9uKCkge30sZmFsc2UpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuICAgIC8qKlxuICAgICogQSBNYXRyaXggbW9kZWwgY29udGFpbmluZyBtZXRob2RzIGZvciBtYW5pcHVsYXRpbmcgdGhlIHNlcXVlbmNlcidzIGFycmF5IG9mIHZhbHVlcy4gVG8gbGVhcm4gaG93IHRvIG1hbmlwdWxhdGUgdGhlIG1hdHJpeCwgcmVhZCBhYm91dCB0aGUgbWF0cml4IG1vZGVsLlxuICAgICogQHR5cGUge21hdHJpeH1cbiAgICAqL1xuICAgIHRoaXMubWF0cml4ID0gbmV3IE1hdHJpeE1vZGVsKHRoaXMuc2V0dGluZ3Mucm93cyx0aGlzLnNldHRpbmdzLmNvbHVtbnMpO1xuICAgIHRoaXMubWF0cml4LnVpID0gdGhpcztcblxuICAgIC8qKlxuICAgICogQSBDb3VudGVyIG1vZGVsIHdoaWNoIHRoZSBzZXF1ZW5jZXIgc3RlcHMgdGhyb3VnaC4gRm9yIGV4YW1wbGUsIHlvdSBjb3VsZCB1c2UgdGhpcyBtb2RlbCB0byBzdGVwIHRocm91Z2ggdGhlIHNlcXVlbmNlciBpbiByZXZlcnNlLCByYW5kb21seSwgb3IgaW4gYSBkcnVuayB3YWxrLlxuICAgICogQHR5cGUge2NvdW50ZXJ9XG4gICAgKi9cbiAgICB0aGlzLnN0ZXBwZXIgPSBuZXcgQ291bnRlck1vZGVsKDAsdGhpcy5jb2x1bW5zKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gIH1cblxuICBidWlsZEZyYW1lKCkge1xuICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG4gICAgaWYgKHRvdWNoLmV4aXN0cykge1xuICAgICAgdGhpcy5hZGRUb3VjaExpc3RlbmVycygpO1xuICAgIH1cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5jZWxscyA9IFtdO1xuICAgIGZvciAobGV0IGk9MDtpPHRoaXMubWF0cml4Lmxlbmd0aDtpKyspIHtcblxuICAgICAgbGV0IGxvY2F0aW9uID0gdGhpcy5tYXRyaXgubG9jYXRlKGkpO1xuICAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJucyB7cm93LGNvbH1cblxuICAgICAgbGV0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgIGNvbnRhaW5lci5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG5cblxuICAgICAgbGV0IGNlbGwgPSBuZXcgTWF0cml4Q2VsbChjb250YWluZXIsIHtcbiAgICAgICAgICBjb21wb25lbnQ6IHRydWUsXG4gICAgICAgICAgaW5kZXg6IGksXG4gICAgICAgICAgcm93OiBsb2NhdGlvbi5yb3csXG4gICAgICAgICAgY29sdW1uOiBsb2NhdGlvbi5jb2x1bW4sXG4gICAgICAgICAgbW9kZTogdGhpcy5tb2RlLFxuICAgICAgICAgIG1hdHJpeDogdGhpc1xuICAgICAgICB9LCB0aGlzLmtleUNoYW5nZS5iaW5kKHRoaXMsaSkpO1xuXG4gICAgLy8gIGNlbGwubWF0cml4ID0gdGhpcztcbiAgICAgIGlmICh0b3VjaC5leGlzdHMpIHtcbiAgICAgICAgY2VsbC5wYWQuaW5kZXggPSBpO1xuICAgICAgICBjZWxsLnByZUNsaWNrID0gY2VsbC5wcmVNb3ZlID0gY2VsbC5wcmVSZWxlYXNlID0gKCkgPT4ge307XG4gICAgICAgIGNlbGwuY2xpY2sgPSBjZWxsLm1vdmUgPSBjZWxsLnJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgICAgY2VsbC5wcmVUb3VjaCA9IGNlbGwucHJlVG91Y2hNb3ZlID0gY2VsbC5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgICAgY2VsbC50b3VjaCA9IGNlbGwudG91Y2hNb3ZlID0gY2VsbC50b3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5jZWxscy5wdXNoKGNlbGwpO1xuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cbiAgICB9XG4gICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgbGV0IGNlbGxXaWR0aCA9IHRoaXMud2lkdGggLyB0aGlzLmNvbHVtbnM7XG4gICAgbGV0IGNlbGxIZWlnaHQgPSB0aGlzLmhlaWdodCAvIHRoaXMucm93cztcblxuICAgIGZvciAobGV0IGk9MDsgaTx0aGlzLmNlbGxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgY29udGFpbmVyID0gdGhpcy5jZWxsc1tpXS5wYXJlbnQ7XG4gICAgICBjb250YWluZXIuc3R5bGUubGVmdCA9IHRoaXMuY2VsbHNbaV0uY29sdW1uICogY2VsbFdpZHRoICsgJ3B4JztcbiAgICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSB0aGlzLmNlbGxzW2ldLnJvdyAqIGNlbGxIZWlnaHQgKyAncHgnO1xuICAgICAgdGhpcy5jZWxsc1tpXS5yZXNpemUoY2VsbFdpZHRoLGNlbGxIZWlnaHQpO1xuICAgIH1cblxuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICBmb3IgKHZhciBpPTA7IGk8dGhpcy5jZWxscy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5jZWxsc1tpXS5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGUoKSB7XG4gIC8vICBjb25zb2xlLmxvZyhcInVwZGF0aW5nLi4uXCIpXG4gICAgLy9vbiA9IG9uIHx8IGZhbHNlO1xuICAgIHRoaXMubWF0cml4Lml0ZXJhdGUoKHIsYyxpKSA9PiB7XG4gICAgICAvLyAgY29uc29sZS5sb2codGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSwgdGhpcy5jZWxsc1tpXS5zdGF0ZSk7XG4gICAgICBpZiAodGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSAhPT0gdGhpcy5jZWxsc1tpXS5zdGF0ZSkge1xuICAgICAgICBpZiAodGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSA+IDApIHtcbiAgICAgICAgICB0aGlzLmNlbGxzW2ldLnR1cm5PbigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuY2VsbHNbaV0udHVybk9mZigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuLy8gdXBkYXRlID0+IGNlbGwudHVybk9uID0+IGNlbGwuZW1pdCA9PiBrZXlDaGFuZ2UgKHNlcS5lbWl0KSA9PiBtYXRyaXguc2V0LmNlbGwgPT4gdXBkYXRlXG4vL1xuLy8gaW50ZXJhY3Rpb24gPT4ga2V5Q2hhbmdlID0+IG1hdHJpeC5zZXQuY2VsbCA9PiB1cGRhdGUgPT4gY2VsbC50dXJuT25cbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gZW1pdFxuLy9cbi8vIHNldC5jZWxsID0+IHVwZGF0ZSA9PiBuZWVkcyB0byBlbWl0LlxuXG4gIGtleUNoYW5nZShub3RlLG9uKSB7XG4gICAgLy8gZW1pdCBkYXRhIGZvciBhbnkga2V5IHR1cm5pbmcgb24vb2ZmXG4gICAgLy8gaSBpcyB0aGUgbm90ZSBpbmRleFxuICAgIC8vIHYgaXMgd2hldGhlciBpdCBpcyBvbiBvciBvZmZcbiAgICBsZXQgY2VsbCA9IHRoaXMubWF0cml4LmxvY2F0ZShub3RlKTtcbiAgLy8gIHRoaXMubWF0cml4LnNldC5jZWxsKGNlbGwuY29sdW1uLGNlbGwucm93LG9uKTtcbiAgICB0aGlzLm1hdHJpeC5wYXR0ZXJuW2NlbGwucm93XVtjZWxsLmNvbHVtbl0gPSBvbjtcbiAgICB2YXIgZGF0YSA9IHtcbiAgICAgIHJvdzogY2VsbC5yb3csXG4gICAgICBjb2x1bW46IGNlbGwuY29sdW1uLFxuICAgICAgc3RhdGU6IG9uXG4gICAgfTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsZGF0YSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKHRoaXMuc3RlcHBlci52YWx1ZSA+PSAwKSB7XG4gICAgICB0aGlzLm1hdHJpeC5pdGVyYXRlKChyLGMsaSkgPT4ge1xuICAgICAgICBpZiAoYz09PXRoaXMuc3RlcHBlci52YWx1ZSkge1xuICAgICAgICAgIHRoaXMuY2VsbHNbaV0ucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgICAgICAgdGhpcy5jZWxsc1tpXS5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCcxJyk7XG4gICAgICAgICAgdGhpcy5jZWxsc1tpXS5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2Utb3BhY2l0eScsJzEnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNlbGxzW2ldLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsJ25vbmUnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHNlcXVlbmNpbmdcbiAgICogQHBhcmFtICB7bnVtYmVyfSBtcyBCZWF0IHRlbXBvIGluIG1pbGxpc2Vjb25kc1xuICAgKi9cbiAgc3RhcnQobXMpIHtcbiAgICB0aGlzLmludGVydmFsLmV2ZW50ID0gdGhpcy5uZXh0LmJpbmQodGhpcyk7XG4gICAgaWYgKG1zKSB7XG4gICAgICB0aGlzLmludGVydmFsLm1zKG1zKTtcbiAgICB9XG4gICAgdGhpcy5pbnRlcnZhbC5zdGFydCgpO1xuICB9XG5cbiAgLyoqXG4gIFN0b3Agc2VxdWVuY2luZ1xuICAqL1xuICBzdG9wKCkge1xuICAgIHRoaXMuaW50ZXJ2YWwuc3RvcCgpO1xuICB9XG5cbiAgLyoqXG4gIE1hbnVhbGx5IGp1bXAgdG8gdGhlIG5leHQgY29sdW1uIGFuZCB0cmlnZ2VyIHRoZSAnY2hhbmdlJyBldmVudC4gVGhlIFwibmV4dFwiIGNvbHVtbiBpcyBkZXRlcm1pbmVkIGJ5IHlvdXIgbW9kZSBvZiBzZXF1ZW5jaW5nLlxuICAqL1xuICBuZXh0KCkge1xuICAgIHRoaXMuc3RlcHBlci5uZXh0KCk7XG4gICAgdGhpcy5lbWl0KCdzdGVwJyx0aGlzLm1hdHJpeC5jb2x1bW4odGhpcy5zdGVwcGVyLnZhbHVlKS5yZXZlcnNlKCkpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBhZGRUb3VjaExpc3RlbmVycygpIHtcblxuICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuXG4gICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGZhbHNlO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoZSkgPT4ge1xuICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRYLGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRZKTtcbiAgICAgIGxldCBjZWxsID0gdGhpcy5jZWxsc1tlbGVtZW50LmluZGV4XTtcbiAgICAgIHRoaXMucGFpbnRicnVzaCA9ICFjZWxsLnN0YXRlO1xuICAgICAgY2VsbC5kb3duKHRoaXMucGFpbnRicnVzaCk7XG4gICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZWxlbWVudC5pbmRleDtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgKGUpID0+IHtcbiAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCxlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG4gICAgICBsZXQgY2VsbCA9IHRoaXMuY2VsbHNbZWxlbWVudC5pbmRleF07XG4gICAgICBpZiAoZWxlbWVudC5pbmRleCE9PXRoaXMuY3VycmVudEVsZW1lbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEVsZW1lbnQgPj0gMCkge1xuICAgICAgICAgIGxldCBwYXN0Q2VsbCA9IHRoaXMuY2VsbHNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICAgICAgcGFzdENlbGwudXAoKTtcbiAgICAgICAgfVxuICAgICAgICBjZWxsLmRvd24odGhpcy5wYWludGJydXNoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNlbGwuYmVuZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGVsZW1lbnQuaW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgKGUpID0+IHtcbiAgICAgIC8vIG5vIHRvdWNoZXMgdG8gY2FsY3VsYXRlIGJlY2F1c2Ugbm9uZSByZW1haW5pbmdcbiAgICAgIGxldCBjZWxsID0gdGhpcy5jZWxsc1t0aGlzLmN1cnJlbnRFbGVtZW50XTtcbiAgICAgIGNlbGwudXAoKTtcbiAgICAgIHRoaXMuaW50ZXJhY3RpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBmYWxzZTtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIC8qKlxuICBOdW1iZXIgb2Ygcm93cyBpbiB0aGUgc2VxdWVuY2VyXG4gIEB0eXBlIHtudW1iZXJ9XG4gICovXG4gIGdldCByb3dzKCkge1xuICAgIHJldHVybiB0aGlzLm1hdHJpeC5yb3dzO1xuICB9XG5cbiAgc2V0IHJvd3Modikge1xuICAgIHRoaXMubWF0cml4LnJvd3MgPSB2O1xuICAgIHRoaXMuZW1wdHkoKTtcbiAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICBOdW1iZXIgb2YgY29sdW1ucyBpbiB0aGUgc2VxdWVuY2VyXG4gIEB0eXBlIHtudW1iZXJ9XG4gICovXG4gIGdldCBjb2x1bW5zKCkge1xuICAgIHJldHVybiB0aGlzLm1hdHJpeC5jb2x1bW5zO1xuICB9XG5cbiAgc2V0IGNvbHVtbnModikge1xuICAgIHRoaXMubWF0cml4LmNvbHVtbnMgPSB2O1xuICAgIHRoaXMuc3RlcHBlci5tYXggPSB2O1xuICAgIHRoaXMuZW1wdHkoKTtcbiAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9zZXF1ZW5jZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5pbXBvcnQgU2VxdWVuY2UgZnJvbSAnLi4vbW9kZWxzL3NlcXVlbmNlJztcblxuLy8gRm9yIHRoZSB0dXRvcmlhbCwgbG9va2luZyBhdFxuXG4vL1BhdHRlcm4gc2VjdGlvbjpcbi8vIC5jcmVhdGUoKSwgLnJvd3MsIC5jb2x1bW5zLFxuLy8gLnBhdHRlcm4sIC5sZW5ndGgsIC5mb3JtYXRBc1RleHQoKSwgLmxvZygpLFxuLy8gLmxvY2F0ZShpKSwgLmluZGV4T2YoYyxyKVxuLy8gcm93KCksIGNvbHVtbigpIChyZXR1cm5zIGNvbnRlbnRzIG9mIHJvdyBvciBjb2x1bSlcblxuLy9Db250cm9sIHNlY3Rpb246XG4vLyB0b2dnbGUgeDNcbi8vIHNldCB4NFxuLy8gcm90YXRlIHgzXG4vLyBwb3B1bGF0ZSB4M1xuLy8gZXJhc2UgeDNcblxuXG4vLyBzaG91bGQgc29tZSB2ZXJzaW9uIG9mIHRoaXMgaGF2ZSBhIGZsb2F0IHZhbHVlIGZvciBlYWNoIGNlbGw/XG4vLyBjb3VsZCBiZSBsaWtlIGEgbWlycm9yIC5wYXR0ZXJuIHRoYXQgaGFzIHZhbHVlcy4gYnkgZGVmYXVsdCwgZXZlcnl0aGluZyBpcyAxLCBidXQgY291bGQgYmUgc2V0Li4uXG4vLyBub3QgYSBnb29kIHdheSB0byBkbyB0aGF0IG9uIGludGVyZmFjZSwgYnV0IGFzIGEgbW9kZWwgaXQgd291bGQgYmUgbmljZS4uLlxuLy8gZm9yIC5mb3JtYXRBc1RleHQoKSwgY291bGQgbXVsdGlwbHkgYnkgMTAwIGFuZCBmbG9vciwgc28gZWFjaCBjZWxsIGlzIGFuIGludCBmcm9tIDAgdG8gOVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNYXRyaXgge1xuXG4gIGNvbnN0cnVjdG9yKHJvd3MsY29sdW1ucykge1xuICAgIC8vIHNob3VsZCBhbHNvIGhhdmUgYWJpbGl0eSB0byBjcmVhdGUgdXNpbmcgYW4gZXhpc3RpbmcgbWF0cml4ICgyZCBhcnJheSlcbiAgICB0aGlzLnBhdHRlcm4gPSBbXTtcbiAgICB0aGlzLmNyZWF0ZShyb3dzLGNvbHVtbnMpO1xuXG4gICAgdGhpcy50b2dnbGUgPSB7XG4gICAgICBjZWxsOiAoY29sdW1uLCByb3cpID0+IHtcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3Jvd11bY29sdW1uXSA9ICF0aGlzLnBhdHRlcm5bcm93XVtjb2x1bW5dOyAvLyBtYXRoLmludmVydCh0aGlzLnBhdHRlcm5bcm93XVtjb2x1bW5dKTtcbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgICByZXR1cm4gdGhpcy5wYXR0ZXJuW3Jvd11bY29sdW1uXTtcbiAgICAgIH0sXG4gICAgICBhbGw6ICgpID0+IHtcbiAgICAgICAgdGhpcy5pdGVyYXRlKChyLGMpID0+IHsgdGhpcy50b2dnbGUuY2VsbChjLHIpOyB9KTtcbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgfSxcbiAgICAgIHJvdzogKHJvdykgPT4ge1xuICAgICAgICBmb3IgKGxldCBpPTA7IGk8dGhpcy5jb2x1bW5zOyBpKyspIHtcbiAgICAgICAgICB0aGlzLnRvZ2dsZS5jZWxsKGkscm93KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9LFxuICAgICAgY29sdW1uOiAoY29sdW1uKSA9PiB7XG4gICAgICAgIGZvciAobGV0IGk9MDsgaTx0aGlzLnJvd3M7IGkrKykge1xuICAgICAgICAgIHRoaXMudG9nZ2xlLmNlbGwoY29sdW1uLGkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5zZXQgPSB7XG4gICAgICBjZWxsOiAoY29sdW1uLCByb3csIHZhbHVlKSA9PiB7XG4gICAgICAgIHRoaXMucGF0dGVybltyb3ddW2NvbHVtbl0gPSB2YWx1ZTtcbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgfSxcbiAgICAgIGFsbDogKHZhbHVlcykgPT4ge1xuICAgICAgICAvLyBzZXQgdGhlIHdob2xlIG1hdHJpeCB1c2luZyBhIDJkIGFycmF5IGFzIGlucHV0XG4gICAgICAgIC8vIHRoaXMgc2hvdWxkIGFsc28gcmVzaXplIHRoZSBhcnJheT9cbiAgICAgICAgdGhpcy5wYXR0ZXJuID0gdmFsdWVzO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9LFxuICAgICAgcm93OiAocm93LHZhbHVlcykgPT4ge1xuICAgICAgICAvLyBzZXQgYSByb3cgdXNpbmcgYW4gYXJyYXkgYXMgaW5wdXRcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3Jvd10gPSB2YWx1ZXM7XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH0sXG4gICAgICBjb2x1bW46IChjb2x1bW4sdmFsdWVzKSA9PiB7XG4gICAgICAgIC8vIHNldCBhIGNvbHVtbiB1c2luZyBhbiBhcnJheSBhcyBpbnB1dFxuICAgICAgICB0aGlzLnBhdHRlcm4uZm9yRWFjaCgocm93LGkpID0+IHtcbiAgICAgICAgICB0aGlzLnBhdHRlcm5baV1bY29sdW1uXSA9IHZhbHVlc1tpXTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5yb3RhdGUgPSB7XG4gICAgICAvL3Nob3VsZCBldmVudHVhbGx5IGRvIChhbW91bnRYLCBhbW91bnRZKSBoZXJlXG4gICAgICAvLyBjb3VsZCBqdXN0IHVzZSBhIGxvb3AgYW5kIHRoaXMucm90YXRlLnJvdyhpLGFtb3VudFgpO1xuICAgICAgYWxsOiAoYW1vdW50KSA9PiB7XG4gICAgICAgIGlmICghYW1vdW50ICYmIGFtb3VudCE9PTApIHtcbiAgICAgICAgICBhbW91bnQgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGFtb3VudCAlPSB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuICAgICAgICBpZiAoYW1vdW50IDwgMCkge1xuICAgICAgICAgIGFtb3VudCA9IHRoaXMucGF0dGVyblswXS5sZW5ndGggKyBhbW91bnQ7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaT0wOyBpPHRoaXMucm93czsgaSsrKSB7XG4gICAgICAgICAgbGV0IGN1dCA9IHRoaXMucGF0dGVybltpXS5zcGxpY2UoIHRoaXMucGF0dGVybltpXS5sZW5ndGggLSBhbW91bnQsIGFtb3VudCApO1xuICAgICAgICAgIHRoaXMucGF0dGVybltpXSA9IGN1dC5jb25jYXQoIHRoaXMucGF0dGVybltpXSApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH0sXG4gICAgICByb3c6IChyb3csYW1vdW50KSA9PiB7XG4gICAgICAgIGlmICghYW1vdW50ICYmIGFtb3VudCE9PTApIHtcbiAgICAgICAgICBhbW91bnQgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGFtb3VudCAlPSB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuICAgICAgICBpZiAoYW1vdW50IDwgMCkge1xuICAgICAgICAgIGFtb3VudCA9IHRoaXMucGF0dGVyblswXS5sZW5ndGggKyBhbW91bnQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGN1dCA9IHRoaXMucGF0dGVybltyb3ddLnNwbGljZSggdGhpcy5wYXR0ZXJuW3Jvd10ubGVuZ3RoIC0gYW1vdW50LCBhbW91bnQgKTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3Jvd10gPSBjdXQuY29uY2F0KCB0aGlzLnBhdHRlcm5bcm93XSApO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9LFxuICAgICAgY29sdW1uOiAoY29sdW1uLCBhbW91bnQpID0+IHtcbiAgICAgICAgaWYgKCFhbW91bnQgJiYgYW1vdW50IT09MCkge1xuICAgICAgICAgIGFtb3VudCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgYW1vdW50ICU9IHRoaXMucGF0dGVybi5sZW5ndGg7XG4gICAgICAgIGlmIChhbW91bnQgPCAwKSB7XG4gICAgICAgICAgYW1vdW50ID0gdGhpcy5wYXR0ZXJuLmxlbmd0aCArIGFtb3VudDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcHJveHkgPSBbXTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuLmZvckVhY2goKHJvdykgPT4ge1xuICAgICAgICAgIHByb3h5LnB1c2goIHJvd1tjb2x1bW5dICk7XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgY3V0ID0gcHJveHkuc3BsaWNlKCBwcm94eS5sZW5ndGggLSBhbW91bnQsIGFtb3VudCApO1xuICAgICAgICBwcm94eSA9IGN1dC5jb25jYXQoIHByb3h5ICk7XG4gICAgICAgIHRoaXMucGF0dGVybi5mb3JFYWNoKChyb3csaSkgPT4ge1xuICAgICAgICAgIHJvd1tjb2x1bW5dID0gcHJveHlbaV07XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIHRoZSBpZGVhIGJlaGluZCBwb3B1bGF0ZSBpcyB0byBiZSBhYmxlIHRvIHNldCBhIHdob2xlIHJvdyBvciBjb2x1bW4gdG8gMCBvciAxXG4gICAgLy8gSUYgdGhlIHZhbHVlIGlzIGEgZmxvYXQsIHN1Y2ggYXMgMC43LCB0aGVuIGl0IHdvdWxkIGJlY29tZSBhIHByb2JhYmlsaXR5XG4gICAgLy8gc28gcG9wdWxhdGUoMC43KSB3b3VsZCBnaXZlIGVhY2ggY2VsbCBhIDcwJSBjaGFuY2Ugb2YgYmVpbmcgMVxuICAgIHRoaXMucG9wdWxhdGUgPSB7XG4gICAgICBhbGw6IChvZGRzKSA9PiB7XG4gICAgICAgIGxldCBvZGRzU2VxdWVuY2UgPSBuZXcgU2VxdWVuY2Uob2Rkcyk7XG4gICAgICAgIHRoaXMuaXRlcmF0ZSgocixjKSA9PiB7XG4gICAgICAgICAgdGhpcy5wYXR0ZXJuW3JdW2NdID0gbWF0aC5jb2luKG9kZHNTZXF1ZW5jZS5uZXh0KCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gVGhpcyBjb3VsZCBiZSB1c2VkIHNvIHRoYXQgZWFjaCByb3cgaGFzIHNhbWUgb2RkcyBwYXR0ZXJuLCBldmVuIGlmIHJvdyBsZW5ndGggaXMgbm90IGRpdmlzaWJseSBieSBzZXF1ZW5jZSBsZW5ndGguXG4gICAgICAgIC8vLCgpID0+IHtcbiAgICAgICAgLy8gIG9kZHMucG9zID0gLTE7XG4gICAgICAgIC8vIH1cbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgfSxcbiAgICAgIHJvdzogKHJvdz0wLG9kZHM9MSkgPT4ge1xuICAgICAgICBsZXQgb2Rkc1NlcXVlbmNlID0gbmV3IFNlcXVlbmNlKG9kZHMpO1xuICAgICAgICB0aGlzLnBhdHRlcm5bcm93XS5mb3JFYWNoKChjZWxsLGkpID0+IHtcbiAgICAgICAgICB0aGlzLnBhdHRlcm5bcm93XVtpXSA9IG1hdGguY29pbihvZGRzU2VxdWVuY2UubmV4dCgpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH0sXG4gICAgICBjb2x1bW46IChjb2x1bW49MCxvZGRzPTEpID0+IHtcbiAgICAgICAgbGV0IG9kZHNTZXF1ZW5jZSA9IG5ldyBTZXF1ZW5jZShvZGRzKTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuLmZvckVhY2goKHJvdyxpKSA9PiB7XG4gICAgICAgICAgdGhpcy5wYXR0ZXJuW2ldW2NvbHVtbl0gPSBtYXRoLmNvaW4ob2Rkc1NlcXVlbmNlLm5leHQoKSk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIGVzc2VudGlhbGwgcG9wdWxhdGUoMCkgc28gaSdtIG5vdCBzdXJlIGlmIHRoaXMgaXMgbmVjZXNzYXJ5IGJ1dCBpcyBuaWNlXG4gICAgdGhpcy5lcmFzZSA9IHtcbiAgICAgIGFsbDogKCkgPT4ge1xuICAgICAgICB0aGlzLnNldC5hbGwoMCk7XG4gICAgICB9LFxuICAgICAgcm93OiAocm93KSA9PiB7XG4gICAgICAgIHRoaXMuc2V0LnJvdyhyb3csMCk7XG4gICAgICB9LFxuICAgICAgY29sdW1uOiAoY29sdW1uKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0LmNvbHVtbihjb2x1bW4sMCk7XG4gICAgICB9XG4gICAgfTtcblxuICAvLyBlbmQgY29uc3RydWN0b3JcbiAgfVxuXG5cbiAgY3JlYXRlKHJvd3MsY29sdW1ucykge1xuICAgIHRoaXMucGF0dGVybiA9IFtdO1xuICAgIGZvciAoIGxldCByb3c9MDsgcm93IDwgcm93czsgcm93KysgKSB7XG4gICAgICBsZXQgYXJyID0gbmV3IEFycmF5KGNvbHVtbnMpO1xuICAgICAgdGhpcy5wYXR0ZXJuLnB1c2goYXJyKTtcbiAgICB9XG4gICAgdGhpcy5pdGVyYXRlKChyLGMpID0+IHsgdGhpcy5wYXR0ZXJuW3JdW2NdID0gZmFsc2U7IH0pO1xuICB9XG5cbiAgaXRlcmF0ZShmLCBmMikge1xuICAgIGxldCBpID0gMDtcbiAgICBmb3IgKCBsZXQgcm93PTA7IHJvdyA8IHRoaXMucm93czsgcm93KysgKSB7XG4gICAgICBpZiAoZjIpIHsgZjIocm93KTsgfVxuICAgICAgZm9yICggbGV0IGNvbHVtbj0wOyBjb2x1bW4gPCB0aGlzLmNvbHVtbnM7IGNvbHVtbisrICkge1xuICAgICAgICBmKHJvdyxjb2x1bW4saSk7XG4gICAgICAgIGkrKztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3JtYXRBc1RleHQoKSB7XG4gICAgbGV0IHBhdHRlcm5TdHJpbmcgPSAnJztcbiAgICB0aGlzLml0ZXJhdGUoXG4gICAgICAocixjKSA9PiB7IHBhdHRlcm5TdHJpbmcgKz0gKHRoaXMucGF0dGVybltyXVtjXSA/IDEgOiAwKSArICcgJzsgfSxcbiAgICAgICgpID0+IHsgcGF0dGVyblN0cmluZyArPSAnXFxuJzsgfVxuICAgICk7XG4gICAgcmV0dXJuIHBhdHRlcm5TdHJpbmc7XG4gIH1cblxuICBsb2coKSB7XG4gICAgY29uc29sZS5sb2codGhpcy5mb3JtYXRBc1RleHQoKSk7XG4gIH1cblxuICB1cGRhdGUocGF0dGVybikge1xuICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm4gfHwgdGhpcy5wYXR0ZXJuO1xuICB9XG5cbiAgZ2V0IGxlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5yb3dzKnRoaXMuY29sdW1ucztcbiAgfVxuXG4gIGxvY2F0ZShpbmRleCkge1xuICAgIC8vIHJldHVybnMgcm93IGFuZCBjb2x1bW4gb2YgY2VsbCBieSBpbmRleFxuICAgIHJldHVybiB7XG4gICAgICByb3c6IH5+KCBpbmRleCAvIHRoaXMuY29sdW1ucyApLFxuICAgICAgY29sdW1uOiBpbmRleCAlIHRoaXMuY29sdW1uc1xuICAgIH07XG4gIH1cblxuICBpbmRleE9mKHJvdyxjb2x1bW4pIHtcbiAgICByZXR1cm4gY29sdW1uICsgcm93ICogdGhpcy5jb2x1bW5zO1xuICAgIC8vIHJldHVybnMgaW5kZXggb2YgY2VsbCBieSByb3cgYW5kIGNvbHVtblxuICB9XG5cbiAgcm93KHJvdykge1xuICAgIGxldCBkYXRhID0gW107XG4gICAgZm9yIChsZXQgaT0wOyBpPHRoaXMuY29sdW1uczsgaSsrKSB7XG4gICAgICBkYXRhLnB1c2godGhpcy5wYXR0ZXJuW3Jvd10gPyAxIDogMCk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgY29sdW1uKGNvbHVtbikge1xuICAgIGxldCBkYXRhID0gW107XG4gICAgZm9yIChsZXQgaT0wOyBpPHRoaXMucm93czsgaSsrKSB7XG4gICAgICBkYXRhLnB1c2godGhpcy5wYXR0ZXJuW2ldW2NvbHVtbl0gPyAxIDogMCk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgZ2V0IHJvd3MoKSB7XG4gICAgcmV0dXJuIHRoaXMucGF0dGVybi5sZW5ndGg7XG4gIH1cbiAgc2V0IHJvd3Modikge1xuICAgIGxldCBwcmV2aW91cyA9IHRoaXMucGF0dGVybi5zbGljZSgwKTtcbiAgICB0aGlzLmNyZWF0ZSh2LHRoaXMuY29sdW1ucyk7XG4gICAgdGhpcy5pdGVyYXRlKChyLGMpID0+IHtcbiAgICAgIGlmIChwcmV2aW91c1tyXSAmJiBwcmV2aW91c1tyXVtjXSkge1xuICAgICAgICB0aGlzLnBhdHRlcm5bcl1bY10gPSBwcmV2aW91c1tyXVtjXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGdldCBjb2x1bW5zKCkge1xuICAgIHJldHVybiB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuICB9XG4gIHNldCBjb2x1bW5zKHYpIHtcbiAgICBsZXQgcHJldmlvdXMgPSB0aGlzLnBhdHRlcm4uc2xpY2UoMCk7XG4gICAgdGhpcy5jcmVhdGUodGhpcy5yb3dzLHYpO1xuICAgIHRoaXMuaXRlcmF0ZSgocixjKSA9PiB7XG4gICAgICBpZiAocHJldmlvdXNbcl0gJiYgcHJldmlvdXNbcl1bY10pIHtcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3JdW2NdID0gcHJldmlvdXNbcl1bY107XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL21vZGVscy9tYXRyaXguanMiLCIndXNlIHN0cmljdCc7XHJcblxyXG5pbXBvcnQgbWF0aCBmcm9tICcuLi91dGlsL21hdGgnO1xyXG5pbXBvcnQgRHJ1bmsgZnJvbSAnLi9kcnVuayc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTZXF1ZW5jZSB7XHJcblxyXG4gICAgY29uc3RydWN0b3Ioc2VxdWVuY2UgPSBbMCwxMCwyMCwzMF0sIG1vZGU9J3VwJywgcG9zaXRpb249ZmFsc2UpIHtcclxuICAgICAgICB0aGlzLnZhbHVlcyA9IHNlcXVlbmNlO1xyXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLnZhbHVlcykpIHtcclxuICAgICAgICAgIHRoaXMudmFsdWVzID0gW3RoaXMudmFsdWVzXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fbW9kZSA9IG1vZGU7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xyXG5cclxuICAgICAgICB0aGlzLmRydW5rV2FsayA9IG5ldyBEcnVuaygwLCB0aGlzLnZhbHVlcy5sZW5ndGggLSAxKTtcclxuXHJcbiAgICAgICAgdGhpcy5zdGFydFZhbHVlcyA9IHtcclxuICAgICAgICAgICd1cCc6IDAsXHJcbiAgICAgICAgICAnZG93bic6IHRoaXMudmFsdWVzLmxlbmd0aCAtIDEsXHJcbiAgICAgICAgICAnZHJ1bmsnOiB+fih0aGlzLnZhbHVlcy5sZW5ndGgvMiksXHJcbiAgICAgICAgICAncmFuZG9tJzogbWF0aC5yaSh0aGlzLnZhbHVlcy5sZW5ndGgpXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMucG9zaXRpb24hPT1mYWxzZSkge1xyXG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpcy5maXJzdDtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgIH1cclxuXHJcbiAgICBnZXQgbW9kZSgpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX21vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IG1vZGUobW9kZSkge1xyXG4gICAgICAgIGlmICghKG1vZGUgPT09ICd1cCcgfHwgbW9kZSA9PT0gJ2Rvd24nIHx8IG1vZGUgPT09ICdyYW5kb20nIHx8IG1vZGUgPT09ICdkcnVuaycpKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBvbmx5IG1vZGVzIGN1cnJlbnRseSBhbGxvd2VkIGFyZTogdXAsIGRvd24sIHJhbmRvbSwgZHJ1bmsnKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9tb2RlID0gbW9kZTtcclxuICAgICAgICBpZiAodGhpcy5wb3NpdGlvbikge1xyXG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHZhbHVlKCkge1xyXG4gICAgICByZXR1cm4gdGhpcy52YWx1ZXNbdGhpcy5wb3NpdGlvbl07XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IHZhbHVlKHYpIHtcclxuICAgICAgdGhpcy5wb3NpdGlvbiA9IHRoaXMudmFsdWVzLmluZGV4T2Yodik7XHJcbiAgICB9XHJcblxyXG4gICAgZmlyc3QoKSB7XHJcbiAgICAgIGlmICh0aGlzLnBvc2l0aW9uIT09ZmFsc2UpIHtcclxuICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xyXG4gICAgICAgIHJldHVybiB0aGlzLm5leHQoKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLnBvc2l0aW9uID0gdGhpcy5zdGFydFZhbHVlc1t0aGlzLl9tb2RlXTtcclxuICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcclxuICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgdXAoKSB7XHJcbiAgICAgIHRoaXMucG9zaXRpb24rKztcclxuICAgICAgdGhpcy5wb3NpdGlvbiAlPSB0aGlzLnZhbHVlcy5sZW5ndGg7XHJcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGRvd24oKSB7XHJcbiAgICAgIHRoaXMucG9zaXRpb24tLTtcclxuICAgICAgaWYgKHRoaXMucG9zaXRpb24gPCAwKSB7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbiA9ICh0aGlzLnBvc2l0aW9uICsgdGhpcy52YWx1ZXMubGVuZ3RoKSAlIHRoaXMudmFsdWVzLmxlbmd0aDtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdGhpcy52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICByYW5kb20oKSB7XHJcbiAgICAgIHRoaXMucG9zaXRpb24gPSBtYXRoLnJpKDAsIHRoaXMudmFsdWVzLmxlbmd0aCk7XHJcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGRydW5rKCkge1xyXG4gICAgICB0aGlzLmRydW5rV2Fsay5tYXggPSB0aGlzLnZhbHVlcy5sZW5ndGg7XHJcbiAgICAgIHRoaXMuZHJ1bmtXYWxrLnZhbHVlID0gdGhpcy5wb3NpdGlvbjtcclxuICAgICAgdGhpcy5wb3NpdGlvbiA9IHRoaXMuZHJ1bmtXYWxrLm5leHQoKTtcclxuICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyogZnV0dXJlIG1ldGhvZHNcclxuICAgIC5ncm91cChzdGFydCxzdG9wKSAtLSBvdXRwdXRzIGEgZ3JvdXAgb2YgbiBpdGVtcyBmcm9tIHRoZSBsaXN0LCB3aXRoIHdyYXBwaW5nXHJcbiAgICAubG9vcChzdGFydCxzdG9wKSAtLSBjb25maW5lcyBzZXF1ZW5jaW5nIHRvIGEgc3Vic2V0IG9mIHRoZSB2YWx1ZXNcclxuICAgICAgICAoY291bGQgZXZlbiBoYXZlIGEgZGlzdGluY3Rpb24gYmV0d2VlbiAub3JpZ2luYWxWYWx1ZXMgYW5kIHRoZSBhcnJheSBvZiB2YWx1ZXMgYmVpbmcgdXNlZClcclxuICAgICovXHJcbn1cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL21vZGVscy9zZXF1ZW5jZS5qcyIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IG1hdGggZnJvbSAnLi4vdXRpbC9tYXRoJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRHJ1bmsge1xuXG4gICAgY29uc3RydWN0b3IobWluPTAsIG1heD05LCB2YWx1ZT0wLCBpbmNyZW1lbnQ9MSwgbG9vcD1mYWxzZSkge1xuICAgICAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5pbmNyZW1lbnQgPSBpbmNyZW1lbnQ7XG4gICAgICAgIHRoaXMubG9vcCA9IGxvb3A7XG4gICAgfVxuXG4gICAgbmV4dCgpIHtcbiAgICAgICAgdGhpcy52YWx1ZSArPSBtYXRoLnBpY2soLTEgKiB0aGlzLmluY3JlbWVudCwgdGhpcy5pbmNyZW1lbnQpO1xuICAgICAgICBpZiAodGhpcy52YWx1ZSA+IHRoaXMubWF4KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5sb29wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5tYXggLSB0aGlzLmluY3JlbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnZhbHVlIDwgdGhpcy5taW4pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5tYXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLm1pbiArIHRoaXMuaW5jcmVtZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9tb2RlbHMvZHJ1bmsuanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5pbXBvcnQgRHJ1bmsgZnJvbSAnLi9kcnVuayc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENvdW50ZXIge1xuXG4gICAgY29uc3RydWN0b3IobWluPTAsIG1heD0xMCwgbW9kZT0ndXAnLCB2YWx1ZT1mYWxzZSkge1xuICAgICAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICAgICAgdGhpcy5kcnVua1dhbGsgPSBuZXcgRHJ1bmsodGhpcy5taW4sIHRoaXMubWF4KTtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUhPT1mYWxzZSkge1xuICAgICAgICAgIHRoaXMubmV4dCA9IHRoaXNbdGhpcy5fbW9kZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpcy5maXJzdDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldCBtb2RlKG1vZGUpIHtcbiAgICAgICAgaWYgKCEobW9kZSA9PT0gJ3VwJyB8fCBtb2RlID09PSAnZG93bicgfHwgbW9kZSA9PT0gJ3JhbmRvbScgfHwgbW9kZSA9PT0gJ2RydW5rJykpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBvbmx5IG1vZGVzIGN1cnJlbnRseSBhbGxvd2VkIGFyZTogdXAsIGRvd24sIHJhbmRvbSwgZHJ1bmsnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9tb2RlID0gbW9kZTtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUpIHtcbiAgICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IG1vZGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb2RlO1xuICAgIH1cblxuICAgIGZpcnN0KCkge1xuICAgICAgaWYgKHRoaXMudmFsdWUhPT1mYWxzZSkge1xuICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xuICAgICAgICByZXR1cm4gdGhpcy5uZXh0KCk7XG4gICAgICB9XG4gICAgICB0aGlzLnN0YXJ0VmFsdWVzID0ge1xuICAgICAgICAndXAnOiB0aGlzLm1pbixcbiAgICAgICAgJ2Rvd24nOiB0aGlzLm1heCxcbiAgICAgICAgJ2RydW5rJzogfn5tYXRoLmF2ZXJhZ2UodGhpcy5taW4sdGhpcy5tYXgpLFxuICAgICAgICAncmFuZG9tJzogbWF0aC5yaSh0aGlzLm1pbix0aGlzLm1heClcbiAgICAgIH07XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5zdGFydFZhbHVlc1t0aGlzLl9tb2RlXTtcbiAgICAgIHRoaXMubmV4dCA9IHRoaXNbdGhpcy5fbW9kZV07XG4gICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG5cbiAgICB1cCgpIHtcbiAgICAgICAgdGhpcy52YWx1ZSsrO1xuICAgICAgICBpZiAodGhpcy52YWx1ZSA+PSB0aGlzLm1heCkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIGRvd24oKSB7XG4gICAgICAgIHRoaXMudmFsdWUtLTtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUgPCB0aGlzLm1pbikge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWF4O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIHJhbmRvbSgpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IG1hdGgucmkodGhpcy5taW4sIHRoaXMubWF4KTtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgZHJ1bmsoKSB7XG4gICAgICAgIHRoaXMuZHJ1bmtXYWxrLm1pbiA9IHRoaXMubWluO1xuICAgICAgICB0aGlzLmRydW5rV2Fsay5tYXggPSB0aGlzLm1heDtcbiAgICAgICAgdGhpcy5kcnVua1dhbGsudmFsdWUgPSB0aGlzLnZhbHVlO1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5kcnVua1dhbGsubmV4dCgpO1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbW9kZWxzL2NvdW50ZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IG1hdGggPSByZXF1aXJlKCcuLi91dGlsL21hdGgnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbi8qKlxuKiBQYW4yRFxuKlxuKiBAZGVzY3JpcHRpb24gSW50ZXJmYWNlIGZvciBtb3ZpbmcgYSBzb3VuZCBhcm91bmQgYW4gYXJyYXkgb2Ygc3BlYWtlcnMuIFNwZWFrZXIgbG9jYXRpb25zIGNhbiBiZSBjdXN0b21pemVkLiBUaGUgaW50ZXJmYWNlIGNhbGN1bGF0ZXMgdGhlIGNsb3NlbmVzcyBvZiB0aGUgc291bmQgc291cmNlIHRvIGVhY2ggc3BlYWtlciBhbmQgcmV0dXJucyB0aGF0IGRpc3RhbmNlIGFzIGEgbnVtZXJpYyB2YWx1ZS5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJwYW4yRFwiPjwvc3Bhbj5cbipcbiogQGV4YW1wbGVcbiogdmFyIHBhbjJkID0gbmV3IE5leHVzLlBhbjJkKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHBhbjJkID0gbmV3IE5leHVzLlBhbjJEKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMjAwLDIwMF0sXG4qICAgJ3JhbmdlJzogMC41LCAgLy8gZGV0ZWN0aW9uIHJhZGl1cyBvZiBlYWNoIHNwZWFrZXJcbiogICAnbW9kZSc6ICdhYnNvbHV0ZScsICAgLy8gJ2Fic29sdXRlJyBvciAncmVsYXRpdmUnIHNvdW5kIG1vdmVtZW50XG4qICAgJ3NwZWFrZXJzJzogWyAgLy8gdGhlIHNwZWFrZXIgW3gseV0gcG9zaXRpb25zXG4qICAgICAgIFswLjUsMC4yXSxcbiogICAgICAgWzAuNzUsMC4yNV0sXG4qICAgICAgIFswLjgsMC41XSxcbiogICAgICAgWzAuNzUsMC43NV0sXG4qICAgICAgIFswLjUsMC44XSxcbiogICAgICAgWzAuMjUsMC43NV1cbiogICAgICAgWzAuMiwwLjVdLFxuKiAgICAgICBbMC4yNSwwLjI1XVxuKiAgIF1cbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIFwic291cmNlXCIgbm9kZSdzIHBvc2l0aW9uIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgaXMgYW4gYXJyYXkgb2YgdGhlIGFtcGxpdHVkZXMgKDAtMSksIHJlcHJlc2VudGluZyB0aGUgbGV2ZWwgb2YgZWFjaCBzcGVha2VyIChhcyBjYWxjdWxhdGVkIGJ5IGl0cyBkaXN0YW5jZSB0byB0aGUgYXVkaW8gc291cmNlKS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogcGFuMmQub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUGFuMkQgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3JhbmdlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFsyMDAsMjAwXSxcbiAgICAgICdyYW5nZSc6IDAuNSxcbiAgICAgICdtb2RlJzogJ2Fic29sdXRlJyxcbiAgICAgICdzcGVha2Vycyc6IFtcbiAgICAgICAgWzAuNSwwLjJdLFxuICAgICAgICBbMC43NSwwLjI1XSxcbiAgICAgICAgWzAuOCwwLjVdLFxuICAgICAgICBbMC43NSwwLjc1XSxcbiAgICAgICAgWzAuNSwwLjhdLFxuICAgICAgICBbMC4yNSwwLjc1XSxcbiAgICAgICAgWzAuMiwwLjVdLFxuICAgICAgICBbMC4yNSwwLjI1XVxuICAgICAgXVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLnZhbHVlID0ge1xuICAgICAgeDogbmV3IFN0ZXAoMCwxLDAsMC41KSxcbiAgICAgIHk6IG5ldyBTdGVwKDAsMSwwLDAuNSlcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgQWJzb2x1dGUgb3IgcmVsYXRpdmUgbW91c2UgaW50ZXJhY3Rpb24uIEluIFwiYWJzb2x1dGVcIiBtb2RlLCB0aGUgc291cmNlIG5vZGUgd2lsbCBqdW1wIHRvIHlvdXIgbW91c2UgcG9zaXRpb24gb24gbW91c2UgY2xpY2suIEluIFwicmVsYXRpdmVcIiBtb2RlLCBpdCBkb2VzIG5vdC5cbiAgICAqL1xuICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZTtcblxuICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICB4OiBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMubW9kZSwnaG9yaXpvbnRhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKSxcbiAgICAgIHk6IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5tb2RlLCd2ZXJ0aWNhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKVxuICAgIH07XG4gICAgdGhpcy5wb3NpdGlvbi54LnZhbHVlID0gdGhpcy52YWx1ZS54Lm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5wb3NpdGlvbi55LnZhbHVlID0gdGhpcy52YWx1ZS55Lm5vcm1hbGl6ZWQ7XG5cbiAgICAvKipcbiAgICBBbiBhcnJheSBvZiBzcGVha2VyIGxvY2F0aW9ucy4gVXBkYXRlIHRoaXMgd2l0aCAubW92ZVNwZWFrZXIoKSBvciAubW92ZUFsbFNwZWFrZXJzKClcbiAgICAqL1xuICAgIHRoaXMuc3BlYWtlcnMgPSB0aGlzLnNldHRpbmdzLnNwZWFrZXJzO1xuXG4gICAgLyoqXG4gICAgUmV3cml0ZTogVGhlIG1heGltdW0gZGlzdGFuY2UgZnJvbSBhIHNwZWFrZXIgdGhhdCB0aGUgc291cmNlIG5vZGUgY2FuIGJlIGZvciBpdCB0byBiZSBoZWFyZCBmcm9tIHRoYXQgc3BlYWtlci4gQSBsb3cgcmFuZ2UgKDAuMSkgd2lsbCByZXN1bHQgaW4gc3BlYWtlcnMgb25seSBwbGF5aW5nIHdoZW4gdGhlIHNvdW5kIGlzIHZlcnkgY2xvc2UgaXQuIERlZmF1bHQgaXMgMC41IChoYWxmIG9mIHRoZSBpbnRlcmZhY2UpLlxuICAgICovXG4gICAgdGhpcy5yYW5nZSA9IHRoaXMuc2V0dGluZ3MucmFuZ2U7XG5cbiAgICAvKipcbiAgICBUaGUgY3VycmVudCBsZXZlbHMgZm9yIGVhY2ggc3BlYWtlci4gVGhpcyBpcyBjYWxjdWxhdGVkIHdoZW4gYSBzb3VyY2Ugbm9kZSBvciBzcGVha2VyIG5vZGUgaXMgbW92ZWQgdGhyb3VnaCBpbnRlcmFjdGlvbiBvciBwcm9ncmFtYXRpY2FsbHkuXG4gICAgKi9cbiAgICB0aGlzLmxldmVscyA9IFtdO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgICB0aGlzLmNhbGN1bGF0ZUxldmVscygpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG5cblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmtub2IpO1xuXG5cbiAgICAvLyBhZGQgc3BlYWtlcnNcbiAgICB0aGlzLnNwZWFrZXJFbGVtZW50cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5zcGVha2Vycy5sZW5ndGg7aSsrKSB7XG4gICAgICBsZXQgc3BlYWtlckVsZW1lbnQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHNwZWFrZXJFbGVtZW50KTtcblxuICAgICAgdGhpcy5zcGVha2VyRWxlbWVudHMucHVzaChzcGVha2VyRWxlbWVudCk7XG4gICAgfVxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgICAgIHRoaXMuX21pbkRpbWVuc2lvbiA9IE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpO1xuXG4gICAgICAgIHRoaXMua25vYlJhZGl1cyA9IHtcbiAgICAgICAgICBvZmY6IH5+KHRoaXMuX21pbkRpbWVuc2lvbi8xMDApICogMyArIDUsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMua25vYlJhZGl1cy5vbiA9IHRoaXMua25vYlJhZGl1cy5vZmYgKiAyO1xuXG4gICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIpO1xuICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQvMik7XG4gICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYlJhZGl1cy5vZmYpO1xuXG4gICAgICAgIGZvciAobGV0IGk9MDtpPHRoaXMuc3BlYWtlcnMubGVuZ3RoO2krKykge1xuICAgICAgICAgIGxldCBzcGVha2VyRWxlbWVudCA9IHRoaXMuc3BlYWtlckVsZW1lbnRzW2ldO1xuICAgICAgICAgIGxldCBzcGVha2VyID0gdGhpcy5zcGVha2Vyc1tpXTtcbiAgICAgICAgICBzcGVha2VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2N4JyxzcGVha2VyWzBdKnRoaXMud2lkdGgpO1xuICAgICAgICAgIHNwZWFrZXJFbGVtZW50LnNldEF0dHJpYnV0ZSgnY3knLHNwZWFrZXJbMV0qdGhpcy5oZWlnaHQpO1xuICAgICAgICAgIHNwZWFrZXJFbGVtZW50LnNldEF0dHJpYnV0ZSgncicsdGhpcy5fbWluRGltZW5zaW9uLzIwICsgNSk7XG4gICAgICAgICAgc3BlYWtlckVsZW1lbnQuc2V0QXR0cmlidXRlKCdmaWxsLW9wYWNpdHknLCAnMCcpO1xuICAgICAgICB9XG5cbiAgICAgIHRoaXMucG9zaXRpb24ueC5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICAgIHRoaXMucG9zaXRpb24ueS5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcblxuICAgICAgICAvLyBuZXh0LCBuZWVkIHRvXG4gICAgICAgIC8vIHJlc2l6ZSBwb3NpdGlvbnNcbiAgICAgICAgLy8gY2FsY3VsYXRlIHNwZWFrZXIgZGlzdGFuY2VzXG4gICAgICB0aGlzLmNhbGN1bGF0ZUxldmVscygpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgY29sb3JJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5zcGVha2Vycy5sZW5ndGg7aSsrKSB7XG4gICAgICBsZXQgc3BlYWtlckVsZW1lbnQgPSB0aGlzLnNwZWFrZXJFbGVtZW50c1tpXTtcbiAgICAgIHNwZWFrZXJFbGVtZW50LnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgICBzcGVha2VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgfVxuXG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgdGhpcy5rbm9iQ29vcmRpbmF0ZXMgPSB7XG4gICAgICB4OiB0aGlzLnZhbHVlLngubm9ybWFsaXplZCAqIHRoaXMud2lkdGgsXG4gICAgICB5OiB0aGlzLmhlaWdodCAtIHRoaXMudmFsdWUueS5ub3JtYWxpemVkICogdGhpcy5oZWlnaHRcbiAgICB9O1xuXG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkNvb3JkaW5hdGVzLngpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmtub2JDb29yZGluYXRlcy55KTtcbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgdGhpcy5wb3NpdGlvbi54LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5wb3NpdGlvbi55LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMucG9zaXRpb24ueC51cGRhdGUodGhpcy5tb3VzZSk7XG4gICAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKHRoaXMubW91c2UpO1xuICAgICAgLy8gcG9zaXRpb24ueCBhbmQgcG9zaXRpb24ueSBhcmUgbm9ybWFsaXplZFxuICAgICAgLy8gc28gYXJlIHRoZSBsZXZlbHNcbiAgICAgIC8vIGxpa2VseSBkb24ndCBuZWVkIHRoaXMudmFsdWUgYXQgYWxsIC0tIG9ubHkgdXNlZCBmb3IgZHJhd2luZ1xuICAgICAgLy8gbm90IGdvaW5nIHRvIGJlIGEgJ3N0ZXAnIG9yICdtaW4nIGFuZCAnbWF4JyBpbiB0aGlzIG9uZS5cbiAgICAgIHRoaXMuY2FsY3VsYXRlTGV2ZWxzKCk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5sZXZlbHMpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICByZWxlYXNlKCkge1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBnZXQgbm9ybWFsaXplZCgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogdGhpcy52YWx1ZS54Lm5vcm1hbGl6ZWQsXG4gICAgICB5OiB0aGlzLnZhbHVlLnkubm9ybWFsaXplZFxuICAgIH07XG4gIH1cblxuICBjYWxjdWxhdGVMZXZlbHMoKSB7XG4gICAgdGhpcy52YWx1ZS54LnVwZGF0ZU5vcm1hbCggdGhpcy5wb3NpdGlvbi54LnZhbHVlICk7XG4gICAgdGhpcy52YWx1ZS55LnVwZGF0ZU5vcm1hbCggdGhpcy5wb3NpdGlvbi55LnZhbHVlICk7XG4gICAgdGhpcy5sZXZlbHMgPSBbXTtcbiAgICB0aGlzLnNwZWFrZXJzLmZvckVhY2goKHMsaSkgPT4ge1xuICAgICAgbGV0IGRpc3RhbmNlID0gbWF0aC5kaXN0YW5jZShzWzBdKnRoaXMud2lkdGgsc1sxXSp0aGlzLmhlaWdodCx0aGlzLnBvc2l0aW9uLngudmFsdWUqdGhpcy53aWR0aCwoMS10aGlzLnBvc2l0aW9uLnkudmFsdWUpKnRoaXMuaGVpZ2h0KTtcbiAgICAgIGxldCBsZXZlbCA9IG1hdGguY2xpcCgxLWRpc3RhbmNlLyh0aGlzLnJhbmdlKnRoaXMud2lkdGgpLDAsMSk7XG4gICAgICB0aGlzLmxldmVscy5wdXNoKGxldmVsKTtcbiAgICAgIHRoaXMuc3BlYWtlckVsZW1lbnRzW2ldLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywgbGV2ZWwpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gIE1vdmUgdGhlIGF1ZGlvIHNvdXJjZSBub2RlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG4gIEBwYXJhbSB4IHtudW1iZXJ9IE5ldyB4IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuICBAcGFyYW0geSB7bnVtYmVyfSBOZXcgeSBsb2NhdGlvbiwgbm9ybWFsaXplZCAwLTFcbiAgKi9cbiAgbW92ZVNvdXJjZSh4LHkpIHtcbiAgICBsZXQgbG9jYXRpb24gPSB7XG4gICAgICB4OiB4KnRoaXMud2lkdGgsXG4gICAgICB5OiB5KnRoaXMuaGVpZ2h0XG4gICAgfTtcbiAgICB0aGlzLnBvc2l0aW9uLngudXBkYXRlKGxvY2F0aW9uKTtcbiAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKGxvY2F0aW9uKTtcbiAgICB0aGlzLmNhbGN1bGF0ZUxldmVscygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLmxldmVscyk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBNb3ZlIGEgc3BlYWtlciBub2RlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG4gIEBwYXJhbSBpbmRleCB7bnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlYWtlciB0byBtb3ZlXG4gIEBwYXJhbSB4IHtudW1iZXJ9IE5ldyB4IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuICBAcGFyYW0geSB7bnVtYmVyfSBOZXcgeSBsb2NhdGlvbiwgbm9ybWFsaXplZCAwLTFcbiAgKi9cbiAgbW92ZVNwZWFrZXIoaW5kZXgseCx5KSB7XG5cbiAgICB0aGlzLnNwZWFrZXJzW2luZGV4XSA9IFt4LHldO1xuICAgIHRoaXMuc3BlYWtlckVsZW1lbnRzW2luZGV4XS5zZXRBdHRyaWJ1dGUoJ2N4JywgeCp0aGlzLndpZHRoKTtcbiAgICB0aGlzLnNwZWFrZXJFbGVtZW50c1tpbmRleF0uc2V0QXR0cmlidXRlKCdjeScsIHkqdGhpcy5oZWlnaHQpO1xuICAgIHRoaXMuY2FsY3VsYXRlTGV2ZWxzKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMubGV2ZWxzKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuXG4gIH1cblxuICAvKipcbiAgU2V0IGFsbCBzcGVha2VyIGxvY2F0aW9uc1xuICBAcGFyYW0gbG9jYXRpb25zIHtBcnJheX0gQXJyYXkgb2Ygc3BlYWtlciBsb2NhdGlvbnMuIEVhY2ggaXRlbSBpbiB0aGUgYXJyYXkgc2hvdWxkIGJlIGFuIGFycmF5IG9mIG5vcm1hbGl6ZWQgeCBhbmQgeSBjb29yZGluYXRlcy5cblxuICBzZXRTcGVha2Vycyhsb2NhdGlvbnMpIHtcblxuICB9XG4gICovXG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL3BhbjJkLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcblxuLyoqXG4qIFRpbHRcbipcbiogQGRlc2NyaXB0aW9uIERldmljZSB0aWx0IHNlbnNvciB3aXRoIDIgb3IgMyBheGVzIChkZXBlbmRpbmcgb24geW91ciBkZXZpY2UgYW5kIGJyb3dzZXIpLlxuKlxuKiBAZGVtbyA8c3BhbiBuZXh1cy11aT0ndGlsdCc+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgdGlsdCA9IG5ldyBOZXh1cy5UaWx0KCcjdGFyZ2V0JylcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYXQgYSByZWd1bGFyIGludGVydmFsLCBhcyBsb25nIGFzIHRoaXMgaW50ZXJmYWNlIGlzIGFjdGl2ZSAoc2VlIHRoZSBpbnRlcmZhY2UncyA8aT4uYWN0aXZlPC9pPiBwcm9wZXJ0eSk8YnI+XG4qIFRoZSBldmVudCBkYXRhIGlzIGFuIDxpPm9iamVjdDwvaT4gY29udGFpbmluZyB4IChudW1iZXIpIGFuZCB5IChudW1iZXIpIHByb3BlcnRpZXMgd2hpY2ggcmVwcmVzZW50IHRoZSBjdXJyZW50IHRpbHQgc3RhdGUgb2YgdGhlIGRldmljZS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogdGlsdC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUaWx0IGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbODAsODBdXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuX2FjdGl2ZSA9IHRydWU7XG5cbiAgICB0aGlzLmluaXQoKTtcblxuICAgIC8vIGFkZCBldmVudCBsaXN0ZW5lciBmb3IgZGV2aWNlIG9yaWVudGF0aW9uXG5cbiAgXHR0aGlzLmJvdW5kVXBkYXRlID0gdGhpcy51cGRhdGUuYmluZCh0aGlzKTtcbiAgLy9cdHRoaXMuYm91bmRNb3pUaWx0ID0gdGhpcy5tb3pUaWx0LmJpbmQodGhpcylcblxuICBcdGlmICh3aW5kb3cuRGV2aWNlT3JpZW50YXRpb25FdmVudCkge1xuICBcdFx0dGhpcy5vcmllbnRhdGlvbkxpc3RlbmVyID0gd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2RldmljZW9yaWVudGF0aW9uJywgdGhpcy5ib3VuZFVwZGF0ZSwgZmFsc2UpO1xuICBcdH0gZWxzZSB7XG4gICAgICB0aGlzLl9hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcbiAgICB9XG5cblxuXG4gICAgICAvKmVsc2UgaWYgKHdpbmRvdy5PcmllbnRhdGlvbkV2ZW50KSB7XG4gIC8vXHQgIFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ01vek9yaWVudGF0aW9uJywgdGhpcy5ib3VuZE1velRpbHQsIGZhbHNlKTtcbiAgXHR9IGVsc2Uge1xuICBcdCAgXHRjb25zb2xlLmxvZygnTm90IHN1cHBvcnRlZCBvbiB5b3VyIGRldmljZSBvciBicm93c2VyLicpO1xuICBcdH0gKi9cblxuXG4gIH1cblxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy50aXRsZSA9IHN2Zy5jcmVhdGUoJ3RleHQnKTtcbiAgICB0aGlzLmNpcmNsZVggPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLmNpcmNsZVkgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLmNpcmNsZVogPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgIHRoaXMuYmFyWCA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmJhclkgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG4gICAgdGhpcy5iYXJaID0gc3ZnLmNyZWF0ZSgncGF0aCcpO1xuXG4gICAgdGhpcy5iYXJYMiA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmJhclkyID0gc3ZnLmNyZWF0ZSgncGF0aCcpO1xuICAgIHRoaXMuYmFyWjIgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG5cbiAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC44Jyk7XG4gICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScsJzAuOCcpO1xuICAgIHRoaXMuYmFyWi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLCcwLjgnKTtcbiAgICB0aGlzLmJhclgyLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScsJzAuOCcpO1xuICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC44Jyk7XG4gICAgdGhpcy5iYXJaMi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLCcwLjgnKTtcblxuICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoKjMvMTIpO1xuICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmhlaWdodCozLzQpO1xuICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMuaGVpZ2h0LzEwKTtcbiAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC40Jyk7XG5cbiAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdjeCcsdGhpcy53aWR0aCo2LzEyKTtcbiAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQqMy80KTtcbiAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmhlaWdodC8xMCk7XG4gICAgdGhpcy5jaXJjbGVZLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScsJzAuNCcpO1xuXG4gICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMud2lkdGgqOS8xMik7XG4gICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMuaGVpZ2h0KjMvNCk7XG4gICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgncicsdGhpcy5oZWlnaHQvMTApO1xuICAgIHRoaXMuY2lyY2xlWi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLCcwLjQnKTtcblxuXG4gICAgdGhpcy5iYXJYLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG4gICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG4gICAgdGhpcy5iYXJaLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG5cbiAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICB0aGlzLmJhclkuc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcblxuICAgIHRoaXMuYmFyWDIuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLE1hdGgucm91bmQodGhpcy5oZWlnaHQvMzApKTtcbiAgICB0aGlzLmJhclkyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG4gICAgdGhpcy5iYXJaMi5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsTWF0aC5yb3VuZCh0aGlzLmhlaWdodC8zMCkpO1xuXG4gICAgdGhpcy5iYXJYMi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAnbm9uZScpO1xuICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZSgnZmlsbCcsICdub25lJyk7XG5cblxuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCd4Jyx0aGlzLndpZHRoLzIpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCd5Jyx0aGlzLmhlaWdodC8zKzcpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdmb250LXNpemUnLCcxNXB4Jyk7XG4gICAgdGhpcy50aXRsZS5zZXRBdHRyaWJ1dGUoJ2ZvbnQtd2VpZ2h0JywnYm9sZCcpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdsZXR0ZXItc3BhY2luZycsJzJweCcpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC43Jyk7XG4gICAgdGhpcy50aXRsZS5zZXRBdHRyaWJ1dGUoJ3RleHQtYW5jaG9yJywnbWlkZGxlJyk7XG4gICAgdGhpcy50aXRsZS50ZXh0Q29udGVudCA9ICdUSUxUJztcblxuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2lyY2xlWCk7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2lyY2xlWSk7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2lyY2xlWik7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJYKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJZKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJaKTtcblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhclgyKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJZMik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuYmFyWjIpO1xuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudGl0bGUpO1xuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIGlmICh0aGlzLl9hY3RpdmUpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG4gICAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLmxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubGlnaHQpO1xuICAgICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLmxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubGlnaHQpO1xuICAgICAgdGhpcy5iYXJaLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhclgyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhclkyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLnRpdGxlLnNldEF0dHJpYnV0ZSgnZmlsbCcsdGhpcy5jb2xvcnMubGlnaHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuICAgICAgdGhpcy5jaXJjbGVZLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuICAgICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWDIuc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWjIuc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgfVxuXG4gIH1cblxuICB1cGRhdGUodikge1xuICAgIGlmICh0aGlzLl9hY3RpdmUpe1xuXG4gICAgICBsZXQgeSA9IHYuYmV0YTtcbiAgICAgIGxldCB4ID0gdi5nYW1tYTtcbiAgICAgIGxldCB6ID0gdi5hbHBoYTtcblxuICAgICAgLy8gdGFrZSB0aGUgb3JpZ2luYWwgLTkwIHRvIDkwIHNjYWxlIGFuZCBub3JtYWxpemUgaXQgMC0xXG4gICAgICB4ID0gbWF0aC5zY2FsZSh4LC05MCw5MCwwLDEpO1xuICAgICAgeSA9IG1hdGguc2NhbGUoeSwtOTAsOTAsMCwxKTtcbiAgICAgIHogPSBtYXRoLnNjYWxlKHosMCwzNjAsMCwxKTtcblxuXG4gICAgICBsZXQgaGFuZGxlUG9pbnRzID0ge1xuICAgICAgICBzdGFydDogTWF0aC5QSSoxLjUsXG4gICAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHgsMCwwLjUsTWF0aC5QSSoxLjUsTWF0aC5QSSowLjUpICwgTWF0aC5QSSowLjUsIE1hdGguUEkqMS41IClcbiAgICAgIH07XG4gICAgICBsZXQgaGFuZGxlMlBvaW50cyA9IHtcbiAgICAgICAgc3RhcnQ6IE1hdGguUEkqMi41LFxuICAgICAgICBlbmQ6IG1hdGguY2xpcCggbWF0aC5zY2FsZSh4LDAuNSwxLE1hdGguUEkqMi41LE1hdGguUEkqMS41KSAsIE1hdGguUEkqMS41LCBNYXRoLlBJKjIuNSApXG4gICAgICB9O1xuXG4gICAgICBsZXQgaGFuZGxlUGF0aCA9IHN2Zy5hcmModGhpcy5jaXJjbGVYLmN4LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWC5jeS5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVguci5iYXNlVmFsLnZhbHVlLCBoYW5kbGVQb2ludHMuc3RhcnQsIGhhbmRsZVBvaW50cy5lbmQpO1xuICAgICAgbGV0IGhhbmRsZTJQYXRoID0gc3ZnLmFyYyh0aGlzLmNpcmNsZVguY3guYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVYLmN5LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWC5yLmJhc2VWYWwudmFsdWUsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgICAgdGhpcy5iYXJYLnNldEF0dHJpYnV0ZSgnZCcsIGhhbmRsZVBhdGgpO1xuICAgICAgdGhpcy5iYXJYMi5zZXRBdHRyaWJ1dGUoJ2QnLCBoYW5kbGUyUGF0aCk7XG5cblxuXG5cblxuICAgICAgaGFuZGxlUG9pbnRzID0ge1xuICAgICAgICBzdGFydDogTWF0aC5QSSoxLjUsXG4gICAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHksMCwwLjUsTWF0aC5QSSoxLjUsTWF0aC5QSSowLjUpICwgTWF0aC5QSSowLjUsIE1hdGguUEkqMS41IClcbiAgICAgIH07XG4gICAgICBoYW5kbGUyUG9pbnRzID0ge1xuICAgICAgICBzdGFydDogTWF0aC5QSSoyLjUsXG4gICAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHksMC41LDEsTWF0aC5QSSoyLjUsTWF0aC5QSSoxLjUpICwgTWF0aC5QSSoxLjUsIE1hdGguUEkqMi41IClcbiAgICAgIH07XG5cbiAgICAgIGhhbmRsZVBhdGggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWS5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVkuY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVZLnIuYmFzZVZhbC52YWx1ZSwgaGFuZGxlUG9pbnRzLnN0YXJ0LCBoYW5kbGVQb2ludHMuZW5kKTtcbiAgICAgIGhhbmRsZTJQYXRoID0gc3ZnLmFyYyh0aGlzLmNpcmNsZVkuY3guYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVZLmN5LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWS5yLmJhc2VWYWwudmFsdWUsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnZCcsIGhhbmRsZVBhdGgpO1xuICAgICAgdGhpcy5iYXJZMi5zZXRBdHRyaWJ1dGUoJ2QnLCBoYW5kbGUyUGF0aCk7XG5cblxuXG5cblxuXG4gICAgICBoYW5kbGVQb2ludHMgPSB7XG4gICAgICAgIHN0YXJ0OiBNYXRoLlBJKjEuNSxcbiAgICAgICAgZW5kOiBtYXRoLmNsaXAoIG1hdGguc2NhbGUoeiwwLDAuNSxNYXRoLlBJKjEuNSxNYXRoLlBJKjAuNSkgLCBNYXRoLlBJKjAuNSwgTWF0aC5QSSoxLjUgKVxuICAgICAgfTtcbiAgICAgIGhhbmRsZTJQb2ludHMgPSB7XG4gICAgICAgIHN0YXJ0OiBNYXRoLlBJKjIuNSxcbiAgICAgICAgZW5kOiBtYXRoLmNsaXAoIG1hdGguc2NhbGUoeiwwLjUsMSxNYXRoLlBJKjIuNSxNYXRoLlBJKjEuNSkgLCBNYXRoLlBJKjEuNSwgTWF0aC5QSSoyLjUgKVxuICAgICAgfTtcblxuICAgICAgaGFuZGxlUGF0aCA9IHN2Zy5hcmModGhpcy5jaXJjbGVaLmN4LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWi5jeS5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVouci5iYXNlVmFsLnZhbHVlLCBoYW5kbGVQb2ludHMuc3RhcnQsIGhhbmRsZVBvaW50cy5lbmQpO1xuICAgICAgaGFuZGxlMlBhdGggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWi5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVouY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVaLnIuYmFzZVZhbC52YWx1ZSwgaGFuZGxlMlBvaW50cy5zdGFydCwgaGFuZGxlMlBvaW50cy5lbmQpO1xuXG4gICAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKCdkJywgaGFuZGxlUGF0aCk7XG4gICAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZSgnZCcsIGhhbmRsZTJQYXRoKTtcblxuXG4gICAgICAvKlxuXG4gICAgICBsZXQgcG9pbnRzWCA9IHtcbiAgICAgICAgc3RhcnQ6IDAsXG4gICAgICAgIGVuZDogbWF0aC5zY2FsZSggeCwgMCwgMSwgMCwgTWF0aC5QSSoyIClcbiAgICAgIH07XG5cbiAgICAvLyAgY29uc29sZS5sb2codGhpcy5jaXJjbGVYLmN4LmJhc2VWYWwudmFsdWUpO1xuXG4gICAgICBsZXQgcGF0aFggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWC5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVguY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVYLnIuYmFzZVZhbC52YWx1ZSoyLCBwb2ludHNYLnN0YXJ0LCBwb2ludHNYLmVuZCk7XG5cbiAgICAgIHRoaXMuYmFyWC5zZXRBdHRyaWJ1dGUoJ2QnLHBhdGhYKTsgKi9cblxuICAgICAgLy90aGlzLnRleHRILnRleHRDb250ZW50ID0gbWF0aC5wcnVuZSh4LDIpO1xuICAgICAgLy90aGlzLnRleHRWLnRleHRDb250ZW50ID0gbWF0aC5wcnVuZSh5LDIpO1xuICAgICAgLy9cbiAgICAvLyAgdGhpcy5jaXJjbGVYLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScseCk7XG4gICAgLy8gIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLHkpO1xuICAgIC8vICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKCdvcGFjaXR5Jyx6KTtcblxuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLCB7XG4gICAgICAgIHg6IHgsXG4gICAgICAgIHk6IHksXG4gICAgICAgIHo6IHpcbiAgICAgIH0pO1xuXG4gICAgfVxuXG4gIH1cblxuICBjbGljaygpIHtcbiAgICBpZiAod2luZG93LkRldmljZU9yaWVudGF0aW9uRXZlbnQpIHtcbiAgICAgIHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICBXaGV0aGVyIHRoZSBpbnRlcmZhY2UgaXMgb24gKGVtaXR0aW5nIHZhbHVlcykgb3Igb2ZmIChwYXVzZWQgJiBub3QgZW1pdHRpbmcgdmFsdWVzKS4gU2V0dGluZyB0aGlzIHByb3BlcnR5IHdpbGwgdXBkYXRlIGl0LlxuICBAdHlwZSB7Ym9vbGVhbn1cbiAgKi9cblxuICBnZXQgYWN0aXZlKCkge1xuICAgIHJldHVybiB0aGlzLl9hY3RpdmU7XG4gIH1cblxuICBzZXQgYWN0aXZlKG9uKSB7XG4gICAgdGhpcy5fYWN0aXZlID0gb247XG4gICAgdGhpcy5jb2xvckludGVyZmFjZSgpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGV2aWNlb3JpZW50YXRpb24nLCB0aGlzLmJvdW5kVXBkYXRlLCBmYWxzZSk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvdGlsdC5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IGRvbSA9IHJlcXVpcmUoJy4uL3V0aWwvZG9tJyk7XG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgU2xpZGVyVGVtcGxhdGUgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL3NsaWRlcnRlbXBsYXRlJyk7XG5sZXQgdG91Y2ggPSByZXF1aXJlKCcuLi91dGlsL3RvdWNoJyk7XG5cblxuXG5jbGFzcyBTaW5nbGVTbGlkZXIgZXh0ZW5kcyBTbGlkZXJUZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnc2NhbGUnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMTIwLDIwXSxcbiAgICAgICdvcmllbnRhdGlvbic6ICd2ZXJ0aWNhbCcsXG4gICAgICAnbW9kZSc6ICdhYnNvbHV0ZScsXG4gICAgICAnc2NhbGUnOiBbMCwxXSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDAsXG4gICAgICAnaGFzS25vYic6IHRydWVcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG5cbiAgICAvKiBldmVudHMgKi9cblxuICAgIGlmICghdG91Y2guZXhpc3RzKSB7XG5cbiAgICAgIHRoaXMuY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgIHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24gPSB7XG4gICAgICAgICAgaW5kZXg6IHRoaXMuaW5kZXgsXG4gICAgICAgICAgdmFsdWU6IHRoaXMudmFsdWVcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5kb3duKCk7XG4gICAgICAgIHRoaXMubXVsdGlzbGlkZXIudmFsdWVzW3RoaXMuaW5kZXhdID0gdGhpcy52YWx1ZTtcbiAgICAgIH07XG4gICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgKGUpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICBpZiAoIXRoaXMub2Zmc2V0KSB7XG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IGRvbS5maW5kUG9zaXRpb24odGhpcy5lbGVtZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVNb3VzZShlLHRoaXMub2Zmc2V0KTtcbiAgICAgICAgICB0aGlzLmRvd24oKTtcbiAgICAgICAgICB0aGlzLm11bHRpc2xpZGVyLnZhbHVlc1t0aGlzLmluZGV4XSA9IHRoaXMudmFsdWU7XG4gICAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJwb2xhdGlvbikge1xuICAgICAgICAgICAgbGV0IGRpc3RhbmNlID0gTWF0aC5hYnModGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uLmluZGV4LXRoaXMuaW5kZXgpO1xuICAgICAgICAgICAgaWYgKCBkaXN0YW5jZSA+IDEgKSB7XG4gICAgICAgICAgICAgIGxldCBsb3cgPSBNYXRoLm1pbih0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24uaW5kZXgsdGhpcy5pbmRleCk7XG4gICAgICAgICAgICAgIGxldCBoaWdoID0gTWF0aC5tYXgodGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uLmluZGV4LHRoaXMuaW5kZXgpO1xuICAgICAgICAgICAgICBsZXQgbG93VmFsdWUgPSB0aGlzLm11bHRpc2xpZGVyLnNsaWRlcnNbbG93XS52YWx1ZTtcbiAgICAgICAgICAgICAgbGV0IGhpZ2hWYWx1ZSA9IHRoaXMubXVsdGlzbGlkZXIuc2xpZGVyc1toaWdoXS52YWx1ZTtcbiAgICAgICAgICAgICAgZm9yIChsZXQgaT1sb3c7aTxoaWdoO2krKykge1xuICAgICAgICAgICAgICAgIHRoaXMubXVsdGlzbGlkZXIuc2xpZGVyc1tpXS52YWx1ZSA9IG1hdGguaW50ZXJwKCAoaS1sb3cpL2Rpc3RhbmNlLCBsb3dWYWx1ZSwgaGlnaFZhbHVlICk7XG4gICAgICAgICAgICAgICAgbGV0IHNtb290aGVkVmFsdWUgPSB0aGlzLm11bHRpc2xpZGVyLnNsaWRlcnNbaV0udmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbaV0gPSBzbW9vdGhlZFZhbHVlO1xuICAgICAgICAgICAgICAgIHRoaXMubXVsdGlzbGlkZXIudXBkYXRlKGksc21vb3RoZWRWYWx1ZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24gPSB7XG4gICAgICAgICAgICBpbmRleDogdGhpcy5pbmRleCxcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cblxuICAgICAgdGhpcy5tb3ZlID0gKCkgPT4ge1xuICAgICAgfTtcbiAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCAoZSkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tdWx0aXNsaWRlci5pbnRlcmFjdGluZykge1xuICAgICAgICAgIGlmICghdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbih0aGlzLmVsZW1lbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLm1vdXNlID0gZG9tLmxvY2F0ZU1vdXNlKGUsdGhpcy5vZmZzZXQpO1xuICAgICAgICAgIHRoaXMuc2xpZGUoKTtcbiAgICAgICAgICB0aGlzLm11bHRpc2xpZGVyLnZhbHVlc1t0aGlzLmluZGV4XSA9IHRoaXMudmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG5cbiAgICAgIHRoaXMucmVsZWFzZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5tdWx0aXNsaWRlci5pbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24gPSBmYWxzZTtcbiAgICAgIH07XG4gICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbdGhpcy5pbmRleF0gPSB0aGlzLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbdGhpcy5pbmRleF0gPSB0aGlzLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIH1cblxuICAgIHRoaXMuY3VzdG9tU3R5bGUoKTtcbiAgfVxuXG4gIGN1c3RvbVN0eWxlKCkge1xuXG4gICAgLyogc3R5bGUgY2hhbmdlcyAqL1xuXG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd4JywwKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsJ3RyYW5zbGF0ZSgwLDApJyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsMCk7IC8vIGNvcm5lciByYWRpdXNcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3J5JywwKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx0aGlzLndpZHRoKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsdGhpcy5oZWlnaHQpO1xuXG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneCcsMCk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywndHJhbnNsYXRlKDAsMCknKTtcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeCcsMCk7IC8vIGNvcm5lciByYWRpdXNcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeScsMCk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgnd2lkdGgnLHRoaXMud2lkdGgpO1xuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsdGhpcy5oZWlnaHQpO1xuXG4gIH1cblxufVxuXG4vKipcbiogTXVsdGlzbGlkZXJcbipcbiogQGRlc2NyaXB0aW9uIE11bHRpc2xpZGVyXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwibXVsdGlzbGlkZXJcIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBtdWx0aXNsaWRlciA9IG5ldyBOZXh1cy5NdWx0aXNsaWRlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBtdWx0aXNsaWRlciA9IG5ldyBOZXh1cy5NdWx0aXNsaWRlcignI3RhcmdldCcse1xuKiAgJ3NpemUnOiBbMjAwLDEwMF0sXG4qICAnbnVtYmVyT2ZTbGlkZXJzJzogNSxcbiogICdtaW4nOiAwLFxuKiAgJ21heCc6IDEsXG4qICAnc3RlcCc6IDAsXG4qICAndmFsdWVzJzogWzAuNywwLjcsMC43LDAuNywwLjddXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIFRoZSBldmVudCBkYXRhIGFuIG9iamVjdCBjb250YWluaW5nIDxpPmluZGV4PC9pPiBhbmQgPGk+dmFsdWU8L2k+IHByb3BlcnRpZXNcbipcbiogQG91dHB1dGV4YW1wbGVcbiogbXVsdGlzbGlkZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKi9cblxuLypcblByb3BlcnRpZXNcbi52YWx1ZXNcblxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTXVsdGlzbGlkZXIgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3ZhbHVlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFsyMDAsMTAwXSxcbiAgICAgICdudW1iZXJPZlNsaWRlcnMnOiA1LFxuICAgICAgJ21pbic6IDAsXG4gICAgICAnbWF4JzogMSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZXMnOiBbMC43LDAuNywwLjcsMC43LDAuN11cbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5fbnVtYmVyT2ZTbGlkZXJzID0gdGhpcy5zZXR0aW5ncy5udW1iZXJPZlNsaWRlcnM7XG4gICAgdGhpcy52YWx1ZXMgPSB0aGlzLnNldHRpbmdzLnZhbHVlcztcblxuICAgIHRoaXMuc2xpZGVycyA9IFtdO1xuXG4gICAgdGhpcy5pbnRlcmFjdGluZyA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgbGV0IG1pbiA9IHRoaXMuc2V0dGluZ3MubWluO1xuICAgIGxldCBtYXggPSB0aGlzLnNldHRpbmdzLm1heDtcbiAgICBsZXQgc3RlcCA9IHRoaXMuc2V0dGluZ3Muc3RlcDtcblxuICAgIGlmICh0aGlzLnNsaWRlcnMubGVuZ3RoKSB7XG4gICAgICBtaW4gPSB0aGlzLnNsaWRlcnNbMF0ubWluO1xuICAgICAgbWF4ID0gdGhpcy5zbGlkZXJzWzBdLm1heDtcbiAgICAgIHN0ZXAgPSB0aGlzLnNsaWRlcnNbMF0uc3RlcDtcbiAgICB9XG5cbiAgICB0aGlzLnNsaWRlcnMgPSBbXTtcblxuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuX251bWJlck9mU2xpZGVycztpKyspIHtcbiAgICAgIGxldCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG5cbiAgICAgIGxldCBzbGlkZXIgPSBuZXcgU2luZ2xlU2xpZGVyKGNvbnRhaW5lciwge1xuICAgICAgICAgIHNjYWxlOiBbbWluLG1heF0sXG4gICAgICAgICAgc3RlcDogc3RlcCxcbiAgICAgICAgICBtb2RlOiAnYWJzb2x1dGUnLFxuICAgICAgICAgIG9yaWVudGF0aW9uOiAndmVydGljYWwnLFxuICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlc1tpXSxcbiAgICAgICAgICBoYXNLbm9iOiBmYWxzZSxcbiAgICAgICAgICBjb21wb25lbnQ6IHRydWUsXG4gICAgICAgIH0sdGhpcy51cGRhdGUuYmluZCh0aGlzLGkpKTtcbiAgICAgIHNsaWRlci5tdWx0aXNsaWRlciA9IHRoaXM7XG5cbiAgICAgIHNsaWRlci5pbmRleCA9IGk7XG4gICAgICBpZiAodG91Y2guZXhpc3RzKSB7XG4gICAgICAgIHNsaWRlci5iYXIuaW5kZXggPSBpO1xuICAgICAgICBzbGlkZXIuZmlsbGJhci5pbmRleCA9IGk7XG4gICAgICAgIHNsaWRlci5wcmVDbGljayA9IHNsaWRlci5wcmVNb3ZlID0gc2xpZGVyLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgICAgc2xpZGVyLmNsaWNrID0gc2xpZGVyLm1vdmUgPSBzbGlkZXIucmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgICBzbGlkZXIucHJlVG91Y2ggPSBzbGlkZXIucHJlVG91Y2hNb3ZlID0gc2xpZGVyLnByZVRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgICBzbGlkZXIudG91Y2ggPSBzbGlkZXIudG91Y2hNb3ZlID0gc2xpZGVyLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNsaWRlcnMucHVzaChzbGlkZXIpO1xuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cbiAgICB9XG4gICAgaWYgKHRvdWNoLmV4aXN0cykge1xuICAgICAgdGhpcy5hZGRUb3VjaExpc3RlbmVycygpO1xuICAgIH1cblxuICB9XG5cbiAgY29sb3JJbnRlcmZhY2UoKSB7XG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5zbGlkZXJzLmxlbmd0aDtpKyspIHtcbiAgICAgIHRoaXMuc2xpZGVyc1tpXS5jb2xvcnMgPSB0aGlzLmNvbG9ycztcbiAgICAgIHRoaXMuc2xpZGVyc1tpXS5jb2xvckludGVyZmFjZSgpO1xuICAgIH1cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBsZXQgc2xpZGVyV2lkdGggPSB0aGlzLndpZHRoIC8gdGhpcy5zbGlkZXJzLmxlbmd0aDtcbiAgICBsZXQgc2xpZGVySGVpZ2h0ID0gdGhpcy5oZWlnaHQ7XG5cbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLnNsaWRlcnMubGVuZ3RoO2krKykge1xuICAgICAgdGhpcy5zbGlkZXJzW2ldLnJlc2l6ZShzbGlkZXJXaWR0aCxzbGlkZXJIZWlnaHQpO1xuICAgICAgdGhpcy5zbGlkZXJzW2ldLmN1c3RvbVN0eWxlKCk7XG4gICAgfVxuXG5cbiAgfVxuXG4gIHVwZGF0ZShpbmRleCx2YWx1ZSkge1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICAnaW5kZXgnOiBpbmRleCxcbiAgICAgICd2YWx1ZSc6IHZhbHVlXG4gICAgfSk7XG4gIH1cblxuICBhZGRUb3VjaExpc3RlbmVycygpIHtcblxuICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuXG4gICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGZhbHNlO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoZSkgPT4ge1xuICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRYLGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRZKTtcbiAgICAgIGxldCBzbGlkZXIgPSB0aGlzLnNsaWRlcnNbZWxlbWVudC5pbmRleF07XG4gICAgICBpZiAoIXNsaWRlci5vZmZzZXQpIHtcbiAgICAgICAgc2xpZGVyLm9mZnNldCA9IGRvbS5maW5kUG9zaXRpb24oc2xpZGVyLmVsZW1lbnQpO1xuICAgICAgfVxuICAgICAgc2xpZGVyLm1vdXNlID0gZG9tLmxvY2F0ZU1vdXNlKGUsc2xpZGVyLm9mZnNldCk7XG4gICAgICBzbGlkZXIuZG93bigpO1xuICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGVsZW1lbnQuaW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIChlKSA9PiB7XG4gICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFgsZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFkpO1xuICAgICAgbGV0IHNsaWRlciA9IHRoaXMuc2xpZGVyc1tlbGVtZW50LmluZGV4XTtcbiAgICAgIGlmICghc2xpZGVyLm9mZnNldCkge1xuICAgICAgICBzbGlkZXIub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbihzbGlkZXIuZWxlbWVudCk7XG4gICAgICB9XG4gICAgICBzbGlkZXIubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSxzbGlkZXIub2Zmc2V0KTtcbiAgICAgIGlmIChlbGVtZW50LmluZGV4IT09dGhpcy5jdXJyZW50RWxlbWVudCkge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50RWxlbWVudCA+PSAwKSB7XG4gICAgICAgICAgbGV0IHBhc3RzbGlkZXIgPSB0aGlzLnNsaWRlcnNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICAgICAgcGFzdHNsaWRlci51cCgpO1xuICAgICAgICB9XG4gICAgICAgIHNsaWRlci5kb3duKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzbGlkZXIuc2xpZGUoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBlbGVtZW50LmluZGV4O1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9KTtcblxuICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIChlKSA9PiB7XG4gICAgICAvLyBubyB0b3VjaGVzIHRvIGNhbGN1bGF0ZSBiZWNhdXNlIG5vbmUgcmVtYWluaW5nXG4gICAgICBsZXQgc2xpZGVyID0gdGhpcy5zbGlkZXJzW3RoaXMuY3VycmVudEVsZW1lbnRdO1xuICAgICAgc2xpZGVyLnVwKCk7XG4gICAgICB0aGlzLmludGVyYWN0aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZmFsc2U7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gIH1cblxuICAvKipcbiAgR2V0IG9yIHNldCB0aGUgbnVtYmVyIG9mIHNsaWRlcnNcbiAgQHR5cGUge051bWJlcn1cbiAgKi9cbiAgZ2V0IG51bWJlck9mU2xpZGVycygpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXJzLmxlbmd0aDtcbiAgfVxuXG4gIHNldCBudW1iZXJPZlNsaWRlcnModikge1xuICAgIGlmICh2PT09dGhpcy5zbGlkZXJzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNsaWRlcnMuZm9yRWFjaCgoc2xpZGVyKT0+e1xuICAgICAgc2xpZGVyLmRlc3Ryb3koKTtcbiAgICB9KTtcbiAgICB0aGlzLmVtcHR5KCk7XG4gICAgdGhpcy5fbnVtYmVyT2ZTbGlkZXJzID0gdjtcbiAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG4gIH1cblxuXG5cbiAgLyoqXG4gIExvd2VyIGxpbWl0IG9mIHRoZSBtdWx0aXNsaWRlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBtdWx0aXNsaWRlci5taW4gPSAxMDAwO1xuICAqL1xuICBnZXQgbWluKCkge1xuICAgIHJldHVybiB0aGlzLnNsaWRlcnNbMF0ubWluO1xuICB9XG4gIHNldCBtaW4odikge1xuICAgIHRoaXMuc2xpZGVycy5mb3JFYWNoKChzbGlkZXIpPT57XG4gICAgICBzbGlkZXIubWluID0gdjtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICBVcHBlciBsaW1pdCBvZiB0aGUgbXVsdGlzbGlkZXIncyBvdXRwdXQgcmFuZ2VcbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgbXVsdGlzbGlkZXIubWF4ID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXJzWzBdLm1heDtcbiAgfVxuICBzZXQgbWF4KHYpIHtcbiAgICB0aGlzLnNsaWRlcnMuZm9yRWFjaCgoc2xpZGVyKT0+e1xuICAgICAgc2xpZGVyLm1heCA9IHY7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBtdWx0aXNsaWRlcidzIHZhbHVlIGNoYW5nZXMgYnkuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIG11bHRpc2xpZGVyLnN0ZXAgPSA1O1xuICAqL1xuICBnZXQgc3RlcCgpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXJzWzBdLnN0ZXA7XG4gIH1cbiAgc2V0IHN0ZXAodikge1xuICAgIHRoaXMuc2xpZGVycy5mb3JFYWNoKChzbGlkZXIpPT57XG4gICAgICBzbGlkZXIuc3RlcCA9IHY7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgU2V0IHRoZSB2YWx1ZSBvZiBhbiBpbmRpdmlkdWFsIHNsaWRlclxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gU2xpZGVyIGluZGV4XG4gIEBwYXJhbSB2YWx1ZSB7bnVtYmVyfSBOZXcgc2xpZGVyIHZhbHVlXG4gIEBleGFtcGxlXG4gIC8vIFNldCB0aGUgZmlyc3Qgc2xpZGVyIHRvIHZhbHVlIDAuNVxuICBtdWx0aXNsaWRlci5zZXRTbGlkZXIoMCwwLjUpXG4gICovXG4gIHNldFNsaWRlcihpbmRleCx2YWx1ZSkge1xuICAgIHRoaXMuc2xpZGVyc1tpbmRleF0udmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgJ2luZGV4JzogaW5kZXgsXG4gICAgICAndmFsdWUnOiB2YWx1ZVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gIFNldCB0aGUgdmFsdWUgb2YgYWxsIHNsaWRlcnMgYXQgb25jZS4gSWYgdGhlIHNpemUgb2YgdGhlIGlucHV0IGFycmF5IGRvZXMgbm90IG1hdGNoIHRoZSBjdXJyZW50IG51bWJlciBvZiBzbGlkZXJzLCB0aGUgdmFsdWUgYXJyYXkgd2lsbCByZXBlYXQgdW50aWwgYWxsIHNsaWRlcnMgaGF2ZSBiZWVuIHNldC4gSS5lLiBhbiBpbnB1dCBhcnJheSBvZiBsZW5ndGggMSB3aWxsIHNldCBhbGwgc2xpZGVycyB0byB0aGF0IHZhbHVlLlxuICBAcGFyYW0gdmFsdWVzIHtBcnJheX0gQWxsIHNsaWRlciB2YWx1ZXNcbiAgQGV4YW1wbGVcbiAgbXVsdGlzbGlkZXIuc2V0QWxsU2xpZGVycyhbMC4yLDAuMywwLjQsMC41LDAuNl0pXG4gICovXG4gIHNldEFsbFNsaWRlcnModmFsdWVzKSB7XG4gICAgdGhpcy52YWx1ZXMgPSB2YWx1ZXM7XG4gICAgdGhpcy5zbGlkZXJzLmZvckVhY2goKHNsaWRlcixpKT0+e1xuICAgICAgc2xpZGVyLnZhbHVlID0gdmFsdWVzW2kldmFsdWVzLmxlbmd0aF07XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgICAnaW5kZXgnOiBpLFxuICAgICAgICAndmFsdWUnOiBzbGlkZXIudmFsdWVcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL211bHRpc2xpZGVyLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNsaWRlclRlbXBsYXRlIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcihhcmdzLG9wdGlvbnMsZGVmYXVsdHMpIHtcblxuICAgIHN1cGVyKGFyZ3Msb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLm9yaWVudGF0aW9uID0gdGhpcy5zZXR0aW5ncy5vcmllbnRhdGlvbjtcblxuICAvLyAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXG4gICAgdGhpcy5oYXNLbm9iID0gdGhpcy5zZXR0aW5ncy5oYXNLbm9iO1xuXG4gICAgLy8gdGhpcy5zdGVwIHNob3VsZCBldmVudHVhbGx5IGJlIGdldC9zZXRcbiAgICAvLyB1cGRhdGluZyBpdCB3aWxsIHVwZGF0ZSB0aGUgX3ZhbHVlIHN0ZXAgbW9kZWxcbiAgLy8gIHRoaXMuc3RlcCA9IHRoaXMuc2V0dGluZ3Muc3RlcDsgLy8gZmxvYXRcblxuICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5zY2FsZVswXSwgdGhpcy5zZXR0aW5ncy5zY2FsZVsxXSwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLHRoaXMub3JpZW50YXRpb24sWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblxuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnZhbHVlKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLmJhciA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmZpbGxiYXIgPSBzdmcuY3JlYXRlKCdyZWN0Jyk7XG4gICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXIpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmZpbGxiYXIpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmtub2IpO1xuXG4gICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG5cblxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG5cbiAgICBpZiAoIXRoaXMuc2V0dGluZ3Mub3JpZW50YXRpb24pIHtcbiAgICAgIGlmICh0aGlzLndpZHRoIDwgdGhpcy5oZWlnaHQpIHtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvbiA9ICd2ZXJ0aWNhbCc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uID0gJ2hvcml6b250YWwnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCB4LCB5LCB3LCBoLCBiYXJPZmZzZXQsIGNvcm5lclJhZGl1cztcbiAgICB0aGlzLmtub2JEYXRhID0ge1xuICAgICAgbGV2ZWw6IDAsXG4gICAgICByOiAwXG4gICAgfTtcblxuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAndmVydGljYWwnKSB7XG4gICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMud2lkdGggLyAyO1xuICAgIFx0eCA9IHRoaXMud2lkdGgvMjtcbiAgICBcdHkgPSAwO1xuICAgIFx0dyA9IHRoaXMudGhpY2tuZXNzO1xuICAgIFx0aCA9IHRoaXMuaGVpZ2h0O1xuICAgICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MgKiAwLjg7XG4gICAgXHR0aGlzLmtub2JEYXRhLmxldmVsID0gaC10aGlzLm5vcm1hbGl6ZWQqaDtcbiAgICAgIGJhck9mZnNldCA9ICd0cmFuc2xhdGUoJyt0aGlzLnRoaWNrbmVzcyooLTEpLzIrJywwKSc7XG4gICAgICBjb3JuZXJSYWRpdXMgPSB3LzI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGhpY2tuZXNzID0gdGhpcy5oZWlnaHQgLyAyO1xuICAgIFx0eCA9IDA7XG4gICAgXHR5ID0gdGhpcy5oZWlnaHQvMjtcbiAgICBcdHcgPSB0aGlzLndpZHRoO1xuICAgIFx0aCA9IHRoaXMudGhpY2tuZXNzO1xuICAgICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MgKiAwLjg7XG4gICAgXHR0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5ub3JtYWxpemVkKnc7XG4gICAgICBiYXJPZmZzZXQgPSAndHJhbnNsYXRlKDAsJyt0aGlzLnRoaWNrbmVzcyooLTEpLzIrJyknO1xuICAgICAgY29ybmVyUmFkaXVzID0gaC8yO1xuICAgIH1cblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneCcseCk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd5Jyx5KTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsYmFyT2Zmc2V0KTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3J4Jyxjb3JuZXJSYWRpdXMpOyAvLyBjb3JuZXIgcmFkaXVzXG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeScsY29ybmVyUmFkaXVzKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx3KTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsaCk7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneCcseCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd5Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx3KTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsaC10aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneCcsMCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd5Jyx5KTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsaCk7XG4gICAgfVxuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsYmFyT2Zmc2V0KTtcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeCcsY29ybmVyUmFkaXVzKTtcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeScsY29ybmVyUmFkaXVzKTtcblxuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAndmVydGljYWwnKSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeCcseCk7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx5KTtcbiAgICB9XG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgncicsdGhpcy5rbm9iRGF0YS5yKTtcblxuXG4gICAgaWYgKHRoaXMucG9zaXRpb24pIHtcbiAgICAgIHRoaXMucG9zaXRpb24ucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG4gICAgfVxuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIGlmICghdGhpcy5oYXNLbm9iKSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdmaWxsJywnbm9uZScpO1xuICAgIH1cblxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5jbGlja2VkKSB7XG4gICAgICB0aGlzLmtub2JEYXRhLnIgPSB0aGlzLnRoaWNrbmVzcyowLjc1O1xuICAgIH1cbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JEYXRhLnIpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZCp0aGlzLmhlaWdodDtcbiAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQgLSB0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd5Jyx0aGlzLmhlaWdodCAtIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZCp0aGlzLndpZHRoO1xuICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd4JywwKTtcbiAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfVxuICB9XG5cbiAgZG93bigpIHtcbiAgICB0aGlzLmNsaWNrZWQgPSB0cnVlO1xuICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzKjAuOTtcbiAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5zbGlkZSgpO1xuICB9XG5cbiAgc2xpZGUoKSB7XG4gICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5wb3NpdGlvbi51cGRhdGUodGhpcy5tb3VzZSk7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5fdmFsdWUudXBkYXRlTm9ybWFsKCB0aGlzLnBvc2l0aW9uLnZhbHVlICk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdXAoKSB7XG4gICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuICB9XG5cbiAgLyoqXG4gIFRoZSBzbGlkZXIncyBjdXJyZW50IHZhbHVlLiBJZiBzZXQgbWFudWFsbHksIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgc2xpZGVyLnZhbHVlID0gMTA7XG4gICovXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHYpIHtcbiAgICB0aGlzLl92YWx1ZS51cGRhdGUodik7XG4gICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBMb3dlciBsaW1pdCBvZiB0aGUgc2xpZGVycydzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBzbGlkZXIubWluID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1pbigpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWluO1xuICB9XG4gIHNldCBtaW4odikge1xuICAgIHRoaXMuX3ZhbHVlLm1pbiA9IHY7XG4gIH1cblxuICAvKipcbiAgVXBwZXIgbGltaXQgb2YgdGhlIHNsaWRlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBzbGlkZXIubWF4ID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWF4O1xuICB9XG4gIHNldCBtYXgodikge1xuICAgIHRoaXMuX3ZhbHVlLm1heCA9IHY7XG4gIH1cblxuICAvKipcbiAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBzbGlkZXIncyB2YWx1ZSBjaGFuZ2VzIGJ5LlxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBzbGlkZXIuc3RlcCA9IDU7XG4gICovXG4gIGdldCBzdGVwKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5zdGVwO1xuICB9XG4gIHNldCBzdGVwKHYpIHtcbiAgICB0aGlzLl92YWx1ZS5zdGVwID0gdjtcbiAgfVxuXG4gIC8qKlxuICBBYnNvbHV0ZSBtb2RlIChzbGlkZXIncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJyZWxhdGl2ZVwiLlxuICBAdHlwZSB7c3RyaW5nfVxuICBAZXhhbXBsZSBzbGlkZXIubW9kZSA9IFwicmVsYXRpdmVcIjtcbiAgKi9cbiAgZ2V0IG1vZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb24ubW9kZTtcbiAgfVxuICBzZXQgbW9kZSh2KSB7XG4gICAgdGhpcy5wb3NpdGlvbi5tb2RlID0gdjtcbiAgfVxuXG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9jb21wb25lbnRzL3NsaWRlcnRlbXBsYXRlLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcbmxldCBTdGVwID0gcmVxdWlyZSgnLi4vbW9kZWxzL3N0ZXAnKTtcbmltcG9ydCAqIGFzIEludGVyYWN0aW9uIGZyb20gJy4uL3V0aWwvaW50ZXJhY3Rpb24nO1xuXG4vKipcbiogUGFuXG4qXG4qIEBkZXNjcmlwdGlvbiBTdGVyZW8gY3Jvc3NmYWRlci5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJwYW5cIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBwYW4gPSBuZXcgTmV4dXMuUGFuKCcjdGFyZ2V0JylcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGludGVyZmFjZSdzIDxpPnZhbHVlPC9pPiAoLTEgdG8gMSksIGFzIHdlbGwgYXMgPGk+TDwvaT4gYW5kIDxpPlI8L2k+IGFtcGxpdHVkZSB2YWx1ZXMgKDAtMSkgZm9yIGxlZnQgYW5kIHJpZ2h0IHNwZWFrZXJzLCBjYWxjdWxhdGVkIGJ5IGEgc3F1YXJlLXJvb3QgY3Jvc3NmYWRlIGFsZ29yaXRobS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogcGFuLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhbiBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnc2NhbGUnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMTIwLDIwXSxcbiAgICAgICdvcmllbnRhdGlvbic6ICdob3Jpem9udGFsJyxcbiAgICAgICdtb2RlJzogJ3JlbGF0aXZlJyxcbiAgICAgICdzY2FsZSc6IFstMSwxXSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDAsXG4gICAgICAnaGFzS25vYic6IHRydWVcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5vcmllbnRhdGlvbiA9IHRoaXMuc2V0dGluZ3Mub3JpZW50YXRpb247XG5cbiAgICB0aGlzLm1vZGUgPSB0aGlzLnNldHRpbmdzLm1vZGU7XG5cbiAgICB0aGlzLmhhc0tub2IgPSB0aGlzLnNldHRpbmdzLmhhc0tub2I7XG5cbiAgICAvLyB0aGlzLnN0ZXAgc2hvdWxkIGV2ZW50dWFsbHkgYmUgZ2V0L3NldFxuICAgIC8vIHVwZGF0aW5nIGl0IHdpbGwgdXBkYXRlIHRoZSBfdmFsdWUgc3RlcCBtb2RlbFxuICAgIHRoaXMuc3RlcCA9IHRoaXMuc2V0dGluZ3Muc3RlcDsgLy8gZmxvYXRcblxuICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5zY2FsZVswXSwgdGhpcy5zZXR0aW5ncy5zY2FsZVsxXSwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5tb2RlLHRoaXMub3JpZW50YXRpb24sWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblxuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnZhbHVlKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLmJhciA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmtub2IgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBpZiAodGhpcy5wb3NpdGlvbikge1xuICAgICAgdGhpcy5wb3NpdGlvbi5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy53aWR0aCA8IHRoaXMuaGVpZ2h0KSB7XG4gICAgICB0aGlzLm9yaWVudGF0aW9uID0gJ3ZlcnRpY2FsJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcmllbnRhdGlvbiA9ICdob3Jpem9udGFsJztcbiAgICB9XG5cbiAgICBsZXQgeCwgeSwgdywgaCwgYmFyT2Zmc2V0LCBjb3JuZXJSYWRpdXM7XG4gICAgdGhpcy5rbm9iRGF0YSA9IHtcbiAgICAgIGxldmVsOiAwLFxuICAgICAgcjogMFxuICAgIH07XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy50aGlja25lc3MgPSB0aGlzLndpZHRoIC8gMjtcbiAgICBcdHggPSB0aGlzLndpZHRoLzI7XG4gICAgXHR5ID0gMDtcbiAgICBcdHcgPSB0aGlzLnRoaWNrbmVzcztcbiAgICBcdGggPSB0aGlzLmhlaWdodDtcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IGgtdGhpcy5rbm9iRGF0YS5yLXRoaXMubm9ybWFsaXplZCooaC10aGlzLmtub2JEYXRhLnIqMik7XG4gICAgICBiYXJPZmZzZXQgPSAndHJhbnNsYXRlKCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycsMCknO1xuICAgICAgY29ybmVyUmFkaXVzID0gdy8yO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMuaGVpZ2h0IC8gMjtcbiAgICBcdHggPSAwO1xuICAgIFx0eSA9IHRoaXMuaGVpZ2h0LzI7XG4gICAgXHR3ID0gdGhpcy53aWR0aDtcbiAgICBcdGggPSB0aGlzLnRoaWNrbmVzcztcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IHRoaXMubm9ybWFsaXplZCoody10aGlzLmtub2JEYXRhLnIqMikrdGhpcy5rbm9iRGF0YS5yO1xuICAgICAgYmFyT2Zmc2V0ID0gJ3RyYW5zbGF0ZSgwLCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycpJztcbiAgICAgIGNvcm5lclJhZGl1cyA9IGgvMjtcbiAgICB9XG5cbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3gnLHgpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneScseSk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGJhck9mZnNldCk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsY29ybmVyUmFkaXVzKTsgLy8gY29ybmVyIHJhZGl1c1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgncnknLGNvcm5lclJhZGl1cyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx4KTtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3knLHkpO1xuICAgIH1cbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JEYXRhLnIpO1xuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuXG4gICAgaWYgKCF0aGlzLmhhc0tub2IpIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCd0cmFuc3BhcmVudCcpO1xuICAgIH1cblxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5jbGlja2VkKSB7XG4gICAgICB0aGlzLmtub2JEYXRhLnIgPSB0aGlzLnRoaWNrbmVzcyowLjc1O1xuICAgIH1cbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JEYXRhLnIpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgXHQgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5rbm9iRGF0YS5yK3RoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQqKHRoaXMuaGVpZ2h0LXRoaXMua25vYkRhdGEucioyKTtcbiAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQgLSB0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICBcdCAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkKih0aGlzLndpZHRoLXRoaXMua25vYkRhdGEucioyKSt0aGlzLmtub2JEYXRhLnI7XG4gICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgIH1cbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MqMC45O1xuICAgIHRoaXMucG9zaXRpb24uYW5jaG9yID0gdGhpcy5tb3VzZTtcbiAgICB0aGlzLm1vdmUoKTtcbiAgfVxuXG4gIG1vdmUoKSB7XG4gICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5wb3NpdGlvbi51cGRhdGUodGhpcy5tb3VzZSk7XG5cbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS51cGRhdGVOb3JtYWwoIHRoaXMucG9zaXRpb24udmFsdWUgKTtcblxuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXG4gICAgICAgIEw6IE1hdGgucG93KCBtYXRoLnNjYWxlKHRoaXMudmFsdWUsLTEsMSwxLDApLCAyKSxcbiAgICAgICAgUjogTWF0aC5wb3coIG1hdGguc2NhbGUodGhpcy52YWx1ZSwtMSwxLDAsMSksIDIpXG4gICAgICB9KTtcblxuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBUaGUgcG9zaXRpb24gb2YgY3Jvc3NmYWRlciwgZnJvbSAtMSAobGVmdCkgdG8gMSAocmlnaHQpLiBTZXR0aW5nIHRoaXMgdmFsdWUgdXBkYXRlcyB0aGUgaW50ZXJmYWNlIGFuZCB0cmlnZ2VycyB0aGUgb3V0cHV0IGV2ZW50LlxuICBAdHlwZSB7bnVtYmVyfVxuICAqL1xuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuICB9XG5cbiAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgdGhpcy5fdmFsdWUudXBkYXRlKHZhbHVlKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXG4gICAgICBMOiBNYXRoLnBvdyggbWF0aC5zY2FsZSh0aGlzLnZhbHVlLC0xLDEsMSwwKSwgMiksXG4gICAgICBSOiBNYXRoLnBvdyggbWF0aC5zY2FsZSh0aGlzLnZhbHVlLC0xLDEsMCwxKSwgMilcbiAgICB9KTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgZ2V0IG5vcm1hbGl6ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvcGFuLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcblxuXG5sZXQgUG9pbnQgPSBmdW5jdGlvbihwb2ludCxlbnZlbG9wZSkge1xuXG4gIHRoaXMueCA9IHBvaW50Lng7XG4gIHRoaXMueSA9IHBvaW50Lnk7XG4gIHRoaXMuZW52ZWxvcGUgPSBlbnZlbG9wZTtcblxuICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnZmlsbCcsdGhpcy5lbnZlbG9wZS5jb2xvcnMuYWNjZW50KTtcblxuICB0aGlzLmVudmVsb3BlLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcblxuICB0aGlzLnJlc2l6ZSA9IGZ1bmN0aW9uKCkge1xuICAgIGxldCByID0gfn4oTWF0aC5taW4odGhpcy5lbnZlbG9wZS53aWR0aCx0aGlzLmVudmVsb3BlLmhlaWdodCkvNTApKzI7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgncicscik7XG4gIH07XG5cbiAgdGhpcy5tb3ZlID0gZnVuY3Rpb24oeCx5KSB7XG5cbiAgICB0aGlzLnggPSAoeCB8fCB4PT09MCkgPyB4IDogdGhpcy54O1xuICAgIHRoaXMueSA9ICh5IHx8IHk9PT0wKSA/IHkgOiB0aGlzLnk7XG5cbiAgICBpZiAodGhpcy5lbnZlbG9wZS5ub2Rlcy5pbmRleE9mKHRoaXMpPj0wKSB7XG5cbiAgICAgIGxldCBwcmV2SW5kZXggPSB0aGlzLmVudmVsb3BlLm5vZGVzLmluZGV4T2YodGhpcyktMTtcbiAgICAgIGxldCBuZXh0SW5kZXggPSB0aGlzLmVudmVsb3BlLm5vZGVzLmluZGV4T2YodGhpcykrMTtcblxuICAgICAgbGV0IHByZXZOb2RlID0gdGhpcy5lbnZlbG9wZS5ub2Rlc1twcmV2SW5kZXhdO1xuICAgICAgbGV0IG5leHROb2RlID0gdGhpcy5lbnZlbG9wZS5ub2Rlc1tuZXh0SW5kZXhdO1xuXG4gICAgICBsZXQgbG93WCA9IHByZXZJbmRleCA+PSAwID8gcHJldk5vZGUueCA6IDA7XG4gICAgICBsZXQgaGlnaFggPSBuZXh0SW5kZXggPCB0aGlzLmVudmVsb3BlLm5vZGVzLmxlbmd0aCA/IG5leHROb2RlLnggOiAxO1xuXG4gICAgICBpZiAodGhpcy54IDwgbG93WCkgeyB0aGlzLnggPSBsb3dYOyB9XG4gICAgICBpZiAodGhpcy54ID4gaGlnaFgpIHsgdGhpcy54ID0gaGlnaFg7IH1cblxuICAgIH1cblxuICAgIHRoaXMubG9jYXRpb24gPSB0aGlzLmdldENvb3JkaW5hdGVzKCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3gnLCB0aGlzLmxvY2F0aW9uLngpO1xuICAgIHRoaXMuZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2N5JywgdGhpcy5sb2NhdGlvbi55KTtcbiAgfTtcblxuICB0aGlzLmdldENvb3JkaW5hdGVzID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHRoaXMueCAqIHRoaXMuZW52ZWxvcGUud2lkdGgsXG4gICAgICB5OiAoMS10aGlzLnkpICogdGhpcy5lbnZlbG9wZS5oZWlnaHRcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMubW92ZSh0aGlzLngsdGhpcy55LHRydWUpO1xuICB0aGlzLnJlc2l6ZSgpO1xuXG4gIHRoaXMuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuZW52ZWxvcGUuZWxlbWVudC5yZW1vdmVDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICAgIHRoaXMuZW52ZWxvcGUubm9kZXMuc3BsaWNlKHRoaXMuZW52ZWxvcGUubm9kZXMuaW5kZXhPZih0aGlzKSwxKTtcbiAgfTtcblxuXG59O1xuXG5cbi8qKlxuKiBFbnZlbG9wZVxuKlxuKiBAZGVzY3JpcHRpb24gSW50ZXJhY3RpdmUgbGluZWFyIHJhbXAgdmlzdWFsaXphdGlvbi5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJlbnZlbG9wZVwiPjwvc3Bhbj5cbipcbiogQGV4YW1wbGVcbiogdmFyIGVudmVsb3BlID0gbmV3IE5leHVzLkVudmVsb3BlKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIGVudmVsb3BlID0gbmV3IE5leHVzLkVudmVsb3BlKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMzAwLDE1MF0sXG4qICAgJ3BvaW50cyc6IFtcbiogICAgIHtcbiogICAgICAgeDogMC4xLFxuKiAgICAgICB5OiAwLjRcbiogICAgIH0sXG4qICAgICB7XG4qICAgICAgIHg6IDAuMzUsXG4qICAgICAgIHk6IDAuNlxuKiAgICAgfSxcbiogICAgIHtcbiogICAgICAgeDogMC42NSxcbiogICAgICAgeTogMC4yXG4qICAgICB9LFxuKiAgICAge1xuKiAgICAgICB4OiAwLjksXG4qICAgICAgIHk6IDAuNFxuKiAgICAgfSxcbiogICBdXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIGEgbm9kZSBpcyBtb3ZlZC4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBhcnJheSBvZiBwb2ludCBsb2NhdGlvbnMuIEVhY2ggaXRlbSBpbiB0aGUgYXJyYXkgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgPGk+eDwvaT4gYW5kIDxpPnk8L2k+IHByb3BlcnRpZXMgZGVzY3JpYmluZyB0aGUgbG9jYXRpb24gb2YgYSBwb2ludCBvbiB0aGUgZW52ZWxvcGUuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIGVudmVsb3BlLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEVudmVsb3BlIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMzAwLDE1MF0sXG4gICAgICAncG9pbnRzJzogW1xuICBcdFx0XHR7XG4gIFx0XHRcdFx0eDogMC4xLFxuICBcdFx0XHRcdHk6IDAuNFxuICBcdFx0XHR9LFxuICBcdFx0XHR7XG4gIFx0XHRcdFx0eDogMC4zNSxcbiAgXHRcdFx0XHR5OiAwLjZcbiAgXHRcdFx0fSxcbiAgXHRcdFx0e1xuICBcdFx0XHRcdHg6IDAuNjUsXG4gIFx0XHRcdFx0eTogMC4yXG4gIFx0XHRcdH0sXG4gIFx0XHRcdHtcbiAgXHRcdFx0XHR4OiAwLjksXG4gIFx0XHRcdFx0eTogMC40XG4gIFx0XHRcdH1cbiAgXHRcdF1cbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5wb2ludHMgPSB0aGlzLnNldHRpbmdzLnBvaW50cztcblxuICAgIHRoaXMubm9kZXMgPSBbXTtcblxuICAgIHRoaXMuc2VsZWN0ZWQgPSBmYWxzZTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG5cbiAgICB0aGlzLnBvaW50cy5mb3JFYWNoKChwb2ludCkgPT4ge1xuICAgICAgbGV0IG5vZGUgPSBuZXcgUG9pbnQocG9pbnQsdGhpcyk7XG4gICAgICB0aGlzLm5vZGVzLnB1c2gobm9kZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNvcnRQb2ludHMoKTtcblxuICAgIHRoaXMubGluZSA9IHN2Zy5jcmVhdGUoJ3BvbHlsaW5lJyk7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJywgMik7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZSgnZmlsbCcsICdub25lJyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5saW5lKTtcblxuICAgIHRoaXMuZmlsbCA9IHN2Zy5jcmVhdGUoJ3BvbHlsaW5lJyk7XG4gICAgdGhpcy5maWxsLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywgJzAuMicpO1xuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuZmlsbCk7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBmb3IgKGxldCBpPTA7IGk8dGhpcy5ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5ub2Rlc1tpXS5yZXNpemUoKTtcbiAgICAgIHRoaXMubm9kZXNbaV0ubW92ZSgpO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB0aGlzLmZpbGwuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB0aGlzLm5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgIG5vZGUuZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgLy8gIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0ubW92ZSggdGhpcy5wb2ludHMgKVxuICAgIHRoaXMuY2FsY3VsYXRlUGF0aCgpO1xuICB9XG5cbiAgY2FsY3VsYXRlUG9pbnRzKCkge1xuICAgIHRoaXMucG9pbnRzID0gW107XG4gICAgdGhpcy5ub2Rlcy5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgICB0aGlzLnBvaW50cy5wdXNoKHsgeDogbm9kZS54LCB5OiBub2RlLnkgfSk7XG4gICAgfSk7XG4gIH1cblxuICBjYWxjdWxhdGVQYXRoKCkge1xuXG4gICAgLy9zdHJva2UgZGF0YVxuICAgIGxldCBkYXRhID0gJzAgJysgdGhpcy5ub2Rlc1swXS5sb2NhdGlvbi55KycsICc7XG5cbiAgICAvLyBkYXRhIHNob3VsZCBiZSByZS1vcmRlcmVkIGJhc2VkIG9uIHggbG9jYXRpb24uXG4gICAgLy8gd2hhdGV2ZXIgZnVuY3Rpb24gYWRkcyBhIG5vZGUgc2hvdWxkIGFkZCBpdCBhdCB0aGUgcmlnaHQgaW5kZXhcblxuICAgIHRoaXMubm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgIC8vICBsZXQgbG9jYXRpb24gPSBub2RlLmdldENvb3JkaW5hdGVzKCk7XG4gICAgICBkYXRhICs9IG5vZGUubG9jYXRpb24ueCArICcgJyArIG5vZGUubG9jYXRpb24ueSArICcsICc7XG4gICAgfSk7XG5cblxuICAvLyAgZGF0YSArPSBwb2ludC54KnRoaXMud2lkdGgrJyAnKyBwb2ludC55KnRoaXMuaGVpZ2h0KycsICc7XG4gICAgZGF0YSArPSB0aGlzLndpZHRoICsgJyAnKyB0aGlzLm5vZGVzW3RoaXMubm9kZXMubGVuZ3RoLTFdLmxvY2F0aW9uLnk7XG5cbiAgICB0aGlzLmxpbmUuc2V0QXR0cmlidXRlKCdwb2ludHMnLCBkYXRhKTtcblxuICAgIC8vIGZpbGwgZGF0YVxuICAgIC8vIGFkZCBib3R0b20gY29ybmVyc1xuXG4gICAgZGF0YSArPSAnLCAnK3RoaXMud2lkdGggKycgJyt0aGlzLmhlaWdodCsnLCAnO1xuICAgIGRhdGEgKz0gJzAgJyt0aGlzLmhlaWdodDtcblxuICAgIHRoaXMuZmlsbC5zZXRBdHRyaWJ1dGUoJ3BvaW50cycsIGRhdGEpO1xuXG4gIH1cblxuXG5cbiAgY2xpY2soKSB7XG4gIFx0Ly8gZmluZCBuZWFyZXN0IG5vZGUgYW5kIHNldCB0aGlzLnNlbGVjdGVkIChpbmRleClcbiAgICB0aGlzLmhhc01vdmVkID0gZmFsc2U7XG4gIFx0dGhpcy5zZWxlY3RlZCA9IHRoaXMuZmluZE5lYXJlc3ROb2RlKCk7XG5cbiAgICB0aGlzLm5vZGVzW3RoaXMuc2VsZWN0ZWRdLm1vdmUodGhpcy5tb3VzZS54L3RoaXMud2lkdGgsMS10aGlzLm1vdXNlLnkvdGhpcy5oZWlnaHQpO1xuICAgIHRoaXMuc2NhbGVOb2RlKHRoaXMuc2VsZWN0ZWQpO1xuXG4gICAgLy8gbXVzdCBkbyB0aGlzIGIvYyBuZXcgbm9kZSBtYXkgaGF2ZSBiZWVuIGNyZWF0ZWRcbiAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gIFx0dGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIG1vdmUoKSB7XG4gIFx0aWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5tb3VzZS54ID0gbWF0aC5jbGlwKHRoaXMubW91c2UueCwwLHRoaXMud2lkdGgpO1xuICAgICAgdGhpcy5oYXNNb3ZlZCA9IHRydWU7XG5cbiAgICAgIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0ubW92ZSh0aGlzLm1vdXNlLngvdGhpcy53aWR0aCwxLXRoaXMubW91c2UueS90aGlzLmhlaWdodCk7XG4gICAgXHR0aGlzLnNjYWxlTm9kZSh0aGlzLnNlbGVjdGVkKTtcblxuICAgICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcbiAgXHRcdHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gIFx0XHR0aGlzLnJlbmRlcigpO1xuICBcdH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG5cbiAgXHRpZiAoIXRoaXMuaGFzTW92ZWQpIHtcbiAgICAgIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0uZGVzdHJveSgpO1xuICBcdH1cblxuICAgIHRoaXMuY2FsY3VsYXRlUG9pbnRzKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMucG9pbnRzKTtcbiAgXHR0aGlzLnJlbmRlcigpO1xuXG4gIFx0Ly8gcmVzZXQgdGhpcy5zZWxlY3RlZFxuICBcdHRoaXMuc2VsZWN0ZWQgPSBudWxsO1xuICB9XG5cblxuICBmaW5kTmVhcmVzdE5vZGUoKSB7XG4gIFx0dmFyIG5lYXJlc3RJbmRleCA9IG51bGw7XG4gICAgLy8gc2V0IHRoaXMgdW5yZWFzb25hYmx5IGhpZ2ggc28gdGhhdCBldmVyeSBkaXN0YW5jZSB3aWxsIGJlIGxvd2VyIHRoYW4gaXQuXG4gIFx0dmFyIG5lYXJlc3REaXN0ID0gMTAwMDA7XG4gIFx0dmFyIGJlZm9yZSA9IGZhbHNlO1xuICAgIGxldCB4ID0gdGhpcy5tb3VzZS54L3RoaXMud2lkdGg7XG4gICAgbGV0IHkgPSAxLXRoaXMubW91c2UueS90aGlzLmhlaWdodDtcbiAgICBsZXQgbm9kZXMgPSB0aGlzLm5vZGVzO1xuICBcdGZvciAobGV0IGkgPSAwOyBpPG5vZGVzLmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgZGlzdGFuY2UgZnJvbSBtb3VzZSB0byB0aGlzIG5vZGUgdXNpbmcgcHl0aGFnb3JlYW4gdGhlb3JlbVxuICBcdFx0dmFyIGRpc3RhbmNlID0gTWF0aC5zcXJ0KCAgTWF0aC5wb3coIChub2Rlc1tpXS54IC0geCksIDIpICsgTWF0aC5wb3coKG5vZGVzW2ldLnkgLSB5KSwgMikgKTtcblxuICAgICAgLy8gaWYgdGhpcyBkaXN0YW5jZSBpcyBsZXNzIHRoYW4gdGhlIHByZXZpb3VzIHNob3J0ZXN0IGRpc3RhbmNlLCB1c2UgdGhpcyBpbmRleFxuICBcdFx0aWYgKGRpc3RhbmNlIDwgbmVhcmVzdERpc3QpIHtcbiAgXHRcdFx0bmVhcmVzdERpc3QgPSBkaXN0YW5jZTtcbiAgXHRcdFx0bmVhcmVzdEluZGV4ID0gaTtcbiAgXHRcdFx0YmVmb3JlID0geCA+IG5vZGVzW2ldLng7XG4gIFx0XHR9XG5cbiAgXHR9XG5cbiAgICAvLyBpZiBub3QgdmVyeSBjbG9zZSB0byBhbnkgbm9kZSwgY3JlYXRlIGEgbm9kZVxuICBcdGlmIChuZWFyZXN0RGlzdD4wLjA3KSB7XG5cbiAgICAgIG5lYXJlc3RJbmRleCA9IHRoaXMuZ2V0SW5kZXhGcm9tWCh0aGlzLm1vdXNlLngvdGhpcy53aWR0aCk7XG5cbiAgXHRcdHRoaXMubm9kZXMuc3BsaWNlKG5lYXJlc3RJbmRleCwwLCBuZXcgUG9pbnQoe1xuICBcdFx0XHR4OiB0aGlzLm1vdXNlLngvdGhpcy53aWR0aCxcbiAgXHRcdFx0eTogMS10aGlzLm1vdXNlLnkvdGhpcy5oZWlnaHRcbiAgXHRcdH0sIHRoaXMpKTtcbiAgICAgIHRoaXMuaGFzTW92ZWQgPSB0cnVlO1xuXG4gIFx0fVxuXG4gIFx0cmV0dXJuIG5lYXJlc3RJbmRleDtcbiAgfVxuXG4gIGdldEluZGV4RnJvbVgoeCkge1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgdGhpcy5ub2Rlcy5mb3JFYWNoKChub2RlLGkpID0+IHtcbiAgICAgIGlmICh0aGlzLm5vZGVzW2ldLnggPD0geCkge1xuICAgICAgICBpbmRleCA9IGkrMTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBzY2FsZU5vZGUoaSkge1xuXG4gIFx0bGV0IGNsaXBwZWRYID0gbWF0aC5jbGlwKHRoaXMubm9kZXNbaV0ueCwgMCwgMSk7XG4gIFx0bGV0IGNsaXBwZWRZID0gbWF0aC5jbGlwKHRoaXMubm9kZXNbaV0ueSwgMCwgMSk7XG5cbiAgICB0aGlzLm5vZGVzW2ldLm1vdmUoIGNsaXBwZWRYLCBjbGlwcGVkWSApO1xuXG4gIH1cblxuICAvKipcbiAgU29ydCB0aGUgdGhpcy5wb2ludHMgYXJyYXkgZnJvbSBsZWZ0LW1vc3QgcG9pbnQgdG8gcmlnaHQtbW9zdCBwb2ludC4gWW91IHNob3VsZCBub3QgcmVndWxhcmx5IG5lZWQgdG8gdXNlIHRoaXMsIGhvd2V2ZXIgaXQgbWF5IGJlIHVzZWZ1bCBpZiB0aGUgcG9pbnRzIGdldCB1bm9yZGVyZWQuXG4gICovXG4gIHNvcnRQb2ludHMoKSB7XG4gICAgdGhpcy5ub2Rlcy5zb3J0KGZ1bmN0aW9uKGEsIGIpe1xuICAgICAgcmV0dXJuIGEueCA+IGIueDtcbiAgICB9KTtcbiAgfVxuXG5cbiAgLyoqXG4gIEFkZCBhIGJyZWFrcG9pbnQgb24gdGhlIGVudmVsb3BlLlxuICBAcGFyYW0geCB7bnVtYmVyfSB4IGxvY2F0aW9uIG9mIHRoZSBwb2ludCwgbm9ybWFsaXplZCAoMC0xKVxuICBAcGFyYW0geSB7bnVtYmVyfSB5IGxvY2F0aW9uIG9mIHRoZSBwb2ludCwgbm9ybWFsaXplZCAoMC0xKVxuICAqL1xuICBhZGRQb2ludCh4LHkpIHtcbiAgICBsZXQgaW5kZXggPSB0aGlzLm5vZGVzLmxlbmd0aDtcblxuICAgIHRoaXMuc29ydFBvaW50cygpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGk8dGhpcy5ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHggPCB0aGlzLm5vZGVzW2ldLngpIHtcbiAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgXHR9XG5cbiAgICB0aGlzLm5vZGVzLnNwbGljZShpbmRleCwgMCwgbmV3IFBvaW50KHtcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5XG4gICAgfSwgdGhpcykpO1xuXG4gICAgdGhpcy5zY2FsZU5vZGUoaW5kZXgpO1xuXG4gICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5wb2ludHMpO1xuXG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIEZpbmQgdGhlIGxldmVsIGF0IGEgY2VydGFpbiB4IGxvY2F0aW9uIG9uIHRoZSBlbnZlbG9wZS5cbiAgQHBhcmFtIHgge251bWJlcn0gVGhlIHggbG9jYXRpb24gdG8gZmluZCB0aGUgbGV2ZWwgb2YsIG5vcm1hbGl6ZWQgMC0xXG4gICovXG4gIHNjYW4oeCkge1xuICAgIC8vIGZpbmQgc3Vycm91bmRpbmcgcG9pbnRzXG4gICAgbGV0IG5leHRJbmRleCA9IHRoaXMuZ2V0SW5kZXhGcm9tWCh4KTtcbiAgICBsZXQgcHJpb3JJbmRleCA9IG5leHRJbmRleC0xO1xuICAgIGlmIChwcmlvckluZGV4IDwgMCkge1xuICAgICAgcHJpb3JJbmRleCA9IDA7XG4gICAgfVxuICAgIGlmIChuZXh0SW5kZXggPj0gdGhpcy5ub2Rlcy5sZW5ndGgpIHtcbiAgICAgIG5leHRJbmRleCA9IHRoaXMubm9kZXMubGVuZ3RoLTE7XG4gICAgfVxuICAgIGxldCBwcmlvclBvaW50ID0gdGhpcy5ub2Rlc1twcmlvckluZGV4XTtcbiAgICBsZXQgbmV4dFBvaW50ID0gdGhpcy5ub2Rlc1tuZXh0SW5kZXhdO1xuICAgIGxldCBsb2MgPSBtYXRoLnNjYWxlKHgscHJpb3JQb2ludC54LCBuZXh0UG9pbnQueCwgMCwgMSk7XG4gICAgbGV0IHZhbHVlID0gbWF0aC5pbnRlcnAobG9jLHByaW9yUG9pbnQueSxuZXh0UG9pbnQueSk7XG4gICAgdGhpcy5lbWl0KCdzY2FuJyx2YWx1ZSk7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cblxuICAvKipcbiAgTW92ZSBhIGJyZWFrcG9pbnQgb24gdGhlIGVudmVsb3BlLlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBicmVha3BvaW50IHRvIG1vdmVcbiAgQHBhcmFtIHgge251bWJlcn0gTmV3IHggbG9jYXRpb24sIG5vcm1hbGl6ZWQgMC0xXG4gIEBwYXJhbSB5IHtudW1iZXJ9IE5ldyB5IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuICAqL1xuICBtb3ZlUG9pbnQoaW5kZXgseCx5KSB7XG4gICAgdGhpcy5ub2Rlc1tpbmRleF0ubW92ZSh4LHkpO1xuICAgIHRoaXMuc2NhbGVOb2RlKGluZGV4KTtcbiAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIE1vdmUgYSBicmVha3BvaW50IG9uIHRoZSBlbnZlbG9wZSBieSBhIGNlcnRhaW4gYW1vdW50LlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBicmVha3BvaW50IHRvIG1vdmVcbiAgQHBhcmFtIHhPZmZzZXQge251bWJlcn0gWCBkaXNwbGFjZW1lbnQsIG5vcm1hbGl6ZWQgMC0xXG4gIEBwYXJhbSB5T2Zmc2V0IHtudW1iZXJ9IFkgZGlzcGxhY2VtZW50LCBub3JtYWxpemVkIDAtMVxuICAqL1xuICBhZGp1c3RQb2ludChpbmRleCx4T2Zmc2V0LHlPZmZzZXQpIHtcbiAgICB0aGlzLm5vZGVzW2luZGV4XS5tb3ZlKHRoaXMubm9kZXNbaW5kZXhdLngreE9mZnNldCx0aGlzLm5vZGVzW2luZGV4XS55K3lPZmZzZXQpO1xuICAgIHRoaXMuc2NhbGVOb2RlKGluZGV4KTtcbiAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIFJlbW92ZSBhIGJyZWFrcG9pbnQgZnJvbSB0aGUgZW52ZWxvcGUuXG4gIEBwYXJhbSBpbmRleCB7bnVtYmVyfSBJbmRleCBvZiB0aGUgYnJlYWtwb2ludCB0byByZW1vdmVcbiAgKi9cbiAgZGVzdHJveVBvaW50KGluZGV4KSB7XG4gICAgdGhpcy5ub2Rlc1tpbmRleF0uZGVzdHJveSgpO1xuICAgIHRoaXMuY2FsY3VsYXRlUG9pbnRzKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMucG9pbnRzKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgUmVtb3ZlIGFsbCBleGlzdGluZyBicmVha3BvaW50cyBhbmQgYWRkIGFuIGVudGlyZWx5IG5ldyBzZXQgb2YgYnJlYWtwb2ludHMuXG4gIEBwYXJhbSBhbGxQb2ludHMge2FycmF5fSBBbiBhcnJheSBvZiBvYmplY3RzIHdpdGggeC95IHByb3BlcnRpZXMgKG5vcm1hbGl6ZWQgMC0xKS4gRWFjaCBvYmplY3QgaW4gdGhlIGFycmF5IHNwZWNpZmljZXMgdGhlIHgveSBsb2NhdGlvbiBvZiBhIG5ldyBicmVha3BvaW50IHRvIGJlIGFkZGVkLlxuICAqL1xuICBzZXRQb2ludHMoYWxsUG9pbnRzKSB7XG4gICAgd2hpbGUgKHRoaXMubm9kZXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLm5vZGVzWzBdLmRlc3Ryb3koKTtcbiAgICB9XG4gICAgYWxsUG9pbnRzLmZvckVhY2goKHBvaW50KSA9PiB7XG4gICAgICB0aGlzLmFkZFBvaW50KHBvaW50LngscG9pbnQueSk7XG4gICAgfSk7XG4gICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5wb2ludHMpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvZW52ZWxvcGUuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBkb20gPSByZXF1aXJlKCcuLi91dGlsL2RvbScpO1xuLy9sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5cbi8qKlxuKiBTcGVjdHJvZ3JhbVxuKlxuKiBAZGVzY3JpcHRpb24gQXVkaW8gc3BlY3RydW0gdmlzdWFsaXphdGlvblxuKlxuKiBAZGVtbyA8c3BhbiBuZXh1cy11aT1cInNwZWN0cm9ncmFtXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc3BlY3Ryb2dyYW0gPSBuZXcgTmV4dXMuU3BlY3Ryb2dyYW0oJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc3BlY3Ryb2dyYW0gPSBuZXcgTmV4dXMuU3BlY3Ryb2dyYW0oJyN0YXJnZXQnLHtcbiogICAnc2l6ZSc6IFszMDAsMTUwXVxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qICZuYnNwO1xuKiBObyBldmVudHNcbipcbiovXG5cbmltcG9ydCB7IGNvbnRleHQgfSBmcm9tICcuLi9tYWluJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3BlY3Ryb2dyYW0gZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3NjYWxlJywndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzMwMCwxNTBdXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgICB0aGlzLmFuYWx5c2VyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gICAgdGhpcy5hbmFseXNlci5mZnRTaXplID0gMjA0ODtcbiAgICB0aGlzLmJ1ZmZlckxlbmd0aCA9IHRoaXMuYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQ7XG4gICAgdGhpcy5kYXRhQXJyYXkgPSBuZXcgVWludDhBcnJheSh0aGlzLmJ1ZmZlckxlbmd0aCk7XG5cbiAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG5cbiAgICB0aGlzLnNvdXJjZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5jYW52YXMgPSBuZXcgZG9tLlNtYXJ0Q2FudmFzKHRoaXMucGFyZW50KTtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNhbnZhcy5lbGVtZW50O1xuICB9XG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5yZXNpemUodGhpcy53aWR0aCx0aGlzLmhlaWdodCk7XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gIH1cblxuICByZW5kZXIoKSB7XG5cbiAgICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlci5iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICB0aGlzLmFuYWx5c2VyLmdldEJ5dGVGcmVxdWVuY3lEYXRhKHRoaXMuZGF0YUFycmF5KTtcblxuICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KDAsIDAsIHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgsIHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0KTtcblxuICAgIGlmICh0aGlzLnNvdXJjZSAmJiB0aGlzLmRhdGFBcnJheSkge1xuXG4gICAgICAvL2NvbnNvbGUubG9nKHRoaXMuZGF0YUFycmF5KTtcblxuICAgICAgbGV0IGJhcldpZHRoID0gKHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGggLyB0aGlzLmJ1ZmZlckxlbmd0aCk7XG4gICAgICBsZXQgYmFySGVpZ2h0O1xuICAgICAgbGV0IHggPSAwO1xuXG4gICAgICBsZXQgZGVmaW5pdGlvbiA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgvNTA7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5idWZmZXJMZW5ndGg7IGkgPSBpK2RlZmluaXRpb24pIHtcbiAgICAgICAgYmFySGVpZ2h0ID0gTWF0aC5tYXguYXBwbHkobnVsbCwgdGhpcy5kYXRhQXJyYXkuc3ViYXJyYXkoaSxpK2RlZmluaXRpb24pKTtcbiAgICAgICAgYmFySGVpZ2h0IC89IDI1NTtcbiAgICAgICAgYmFySGVpZ2h0ICo9IHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0O1xuXG4gICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KHgsdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQtYmFySGVpZ2h0LGJhcldpZHRoKmRlZmluaXRpb24sYmFySGVpZ2h0KTtcblxuICAgICAgICB4ICs9IChiYXJXaWR0aCpkZWZpbml0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgRXF1aXZhbGVudCB0byBcInBhdGNoaW5nIGluXCIgYW4gYXVkaW8gbm9kZSB0byB2aXN1YWxpemUuIE5PVEU6IFlvdSBjYW5ub3QgY29ubmVjdCBhdWRpbyBub2RlcyBhY3Jvc3MgdHdvIGRpZmZlcmVudCBhdWRpbyBjb250ZXh0cy4gTmV4dXNVSSBydW5zIGl0cyBhdWRpbyBhbmFseXNpcyBvbiBpdHMgb3duIGF1ZGlvIGNvbnRleHQsIE5leHVzLmNvbnRleHQuIElmIHRoZSBhdWRpbyBub2RlIHlvdSBhcmUgdmlzdWFsaXppbmcgaXMgY3JlYXRlZCBvbiBhIGRpZmZlcmVudCBhdWRpbyBjb250ZXh0LCB5b3Ugd2lsbCBuZWVkIHRvIHRlbGwgTmV4dXNVSSB0byB1c2UgdGhhdCBjb250ZXh0IGluc3RlYWQ6IGkuZS4gTmV4dXMuY29udGV4dCA9IFlvdXJBdWRpb0NvbnRleHROYW1lLiBGb3IgZXhhbXBsZSwgaW4gVG9uZUpTIHByb2plY3RzLCB0aGUgbGluZSB3b3VsZCBiZTogTmV4dXMuY29udGV4dCA9IFRvbmUuY29udGV4dCAuIFdlIHJlY29tbWVuZCB0aGF0IHlvdSB3cml0ZSB0aGF0IGxpbmUgb2YgY29kZSBvbmx5IG9uY2UgYXQgdGhlIGJlZ2lubmluZyBvZiB5b3VyIHByb2plY3QuXG4gIEBwYXJhbSBub2RlIHtBdWRpb05vZGV9IFRoZSBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZVxuICBAZXhhbXBsZSBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC8vIG9yIGFub3RoZXIgYXVkaW8gY29udGV4dCB5b3UgaGF2ZSBjcmVhdGVkXG4gIHNwZWN0cm9ncmFtLmNvbm5lY3QoIFRvbmUuTWFzdGVyICk7XG4gICovXG4gIGNvbm5lY3Qobm9kZSkge1xuICAgIGlmICh0aGlzLnNvdXJjZSkge1xuICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgfVxuICAgIHRoaXMuc291cmNlID0gbm9kZTtcbiAgICB0aGlzLnNvdXJjZS5jb25uZWN0KHRoaXMuYW5hbHlzZXIpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKipcbiAgU3RvcCB2aXN1YWxpemluZyB0aGUgc291cmNlIG5vZGUgYW5kIGRpc2Nvbm5lY3QgaXQuXG4gICovXG4gIGRpc2Nvbm5lY3QoKSB7XG4gICAgdGhpcy5zb3VyY2UuZGlzY29ubmVjdCh0aGlzLmFuYWx5c2VyKTtcbiAgICB0aGlzLnNvdXJjZSA9IG51bGw7XG4gIH1cblxuICBjbGljaygpIHtcbiAgICB0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL3NwZWN0cm9ncmFtLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgZG9tID0gcmVxdWlyZSgnLi4vdXRpbC9kb20nKTtcbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcblxuXG4vKipcbiogTWV0ZXJcbipcbiogQGRlc2NyaXB0aW9uIFN0ZXJlbyBkZWNpYmVsIG1ldGVyXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwibWV0ZXJcIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBtZXRlciA9IG5ldyBOZXh1cy5NZXRlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBtZXRlciA9IG5ldyBOZXh1cy5NZXRlcignI3RhcmdldCcse1xuKiAgIHNpemU6IFs3NSw3NV1cbiogfSlcbipcbiogQG91dHB1dFxuKiAmbmJzcDtcbiogTm8gZXZlbnRzXG4qXG4qL1xuXG5pbXBvcnQgeyBjb250ZXh0IH0gZnJvbSAnLi4vbWFpbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1ldGVyIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWydzY2FsZScsJ3ZhbHVlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFszMCwxMDBdXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgICB0aGlzLmNoYW5uZWxzID0gMjtcblxuICAgIHRoaXMuc3BsaXR0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKCB0aGlzLmNoYW5uZWxzICk7XG5cbiAgICB0aGlzLmFuYWx5c2VycyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wOyBpPHRoaXMuY2hhbm5lbHM7IGkrKykge1xuICAgICAgbGV0IGFuYWx5c2VyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gICAgICB0aGlzLnNwbGl0dGVyLmNvbm5lY3QoYW5hbHlzZXIsaSk7XG4gICAgICBhbmFseXNlci5mZnRTaXplID0gMTAyNDtcbiAgICAgIGFuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IDE7XG4gICAgICB0aGlzLmFuYWx5c2Vycy5wdXNoKCBhbmFseXNlciApO1xuICAgIH1cbiAgICB0aGlzLmJ1ZmZlckxlbmd0aCA9IHRoaXMuYW5hbHlzZXJzWzBdLmZyZXF1ZW5jeUJpbkNvdW50O1xuICAgIHRoaXMuZGF0YUFycmF5ID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJ1ZmZlckxlbmd0aCk7XG5cbi8qXG4gICAgLy8gYWRkIGxpbmVhciBncmFkaWVudFxuICAgIHZhciBncmQgPSBjYW52YXNDdHguY3JlYXRlTGluZWFyR3JhZGllbnQoMCwgMCwgMCwgY2FudmFzLmhlaWdodCk7XG4gICAgLy8gbGlnaHQgYmx1ZVxuICAgIGdyZC5hZGRDb2xvclN0b3AoMCwgJyMwMDAnKTtcbiAgICBncmQuYWRkQ29sb3JTdG9wKDAuMiwgJyNiYmInKTtcbiAgICBncmQuYWRkQ29sb3JTdG9wKDAuNCwgJyNkMTgnKTtcbiAgICAvLyBkYXJrIGJsdWVcbiAgICBncmQuYWRkQ29sb3JTdG9wKDEsICcjZDE4Jyk7XG4gICAgY2FudmFzQ3R4LmZpbGxTdHlsZSA9IGdyZDsgKi9cblxuICAgIHRoaXMuYWN0aXZlID0gdHJ1ZTtcblxuICAgIHRoaXMuZGIgPSAtSW5maW5pdHk7XG5cbiAgICB0aGlzLmluaXQoKTtcblxuICAgIHRoaXMubWV0ZXJXaWR0aCA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgvdGhpcy5jaGFubmVscztcblxuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5jYW52YXMgPSBuZXcgZG9tLlNtYXJ0Q2FudmFzKHRoaXMucGFyZW50KTtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNhbnZhcy5lbGVtZW50O1xuICB9XG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5yZXNpemUodGhpcy53aWR0aCx0aGlzLmhlaWdodCk7XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gIH1cblxuICByZW5kZXIoKSB7XG5cbiAgICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlci5iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxTdHlsZSA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgdGhpcy5jYW52YXMuY29udGV4dC5maWxsUmVjdCgwLCAwLCB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoICwgdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQpO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5hbmFseXNlcnMubGVuZ3RoO2krKykge1xuXG4gICAgICBpZiAodGhpcy5zb3VyY2UpIHtcblxuICAgICAgICB0aGlzLmFuYWx5c2Vyc1tpXS5nZXRGbG9hdFRpbWVEb21haW5EYXRhKHRoaXMuZGF0YUFycmF5KTtcblxuICAgICAgICBsZXQgcm1zID0gMDtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZGF0YUFycmF5Lmxlbmd0aDsgaSsrKXtcbiAgICAgICAgICAgICBybXMgKz0gKHRoaXMuZGF0YUFycmF5W2ldICogdGhpcy5kYXRhQXJyYXlbaV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcm1zID0gTWF0aC5zcXJ0KHJtcyAvIHRoaXMuZGF0YUFycmF5Lmxlbmd0aCk7XG5cbiAgICAgICAgdGhpcy5kYiA9IDIwICogTWF0aC5sb2cxMChybXMpO1xuXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuZGIgPiAtMjAwICYmIHRoaXMuZGIgIT09IC1JbmZpbml0eSkge1xuICAgICAgICB0aGlzLmRiIC09IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRiID0gLUluZmluaXR5O1xuICAgICAgfVxuXG5cbiAgICAgIC8vY29uc29sZS5sb2coZGIpXG5cbiAgICAgIGlmICh0aGlzLmRiID4gLTcwKSB7XG5cbiAgICAgICAgbGV0IGxpbmVhciA9IG1hdGgubm9ybWFsaXplKHRoaXMuZGIsLTcwLDUpO1xuICAgICAgICBsZXQgZXhwID0gbGluZWFyICogbGluZWFyO1xuICAgICAgICBsZXQgeSA9IG1hdGguc2NhbGUoZXhwLDAsMSx0aGlzLmVsZW1lbnQuaGVpZ2h0LDApO1xuXG4gICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KHRoaXMubWV0ZXJXaWR0aCppLHksdGhpcy5tZXRlcldpZHRoLHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0IC0geSk7XG5cbiAgICAgICAgLy9jb25zb2xlLmxvZyhcInJlbmRlcmluZy4uLlwiKVxuXG4gICAgICB9XG5cbiAgICB9XG5cbiAgfVxuXG4gIC8qKlxuICBFcXVpdmFsZW50IHRvIFwicGF0Y2hpbmcgaW5cIiBhbiBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZS4gTk9URTogWW91IGNhbm5vdCBjb25uZWN0IGF1ZGlvIG5vZGVzIGFjcm9zcyB0d28gZGlmZmVyZW50IGF1ZGlvIGNvbnRleHRzLiBOZXh1c1VJIHJ1bnMgaXRzIGF1ZGlvIGFuYWx5c2lzIG9uIGl0cyBvd24gYXVkaW8gY29udGV4dCwgTmV4dXMuY29udGV4dC4gSWYgdGhlIGF1ZGlvIG5vZGUgeW91IGFyZSB2aXN1YWxpemluZyBpcyBjcmVhdGVkIG9uIGEgZGlmZmVyZW50IGF1ZGlvIGNvbnRleHQsIHlvdSB3aWxsIG5lZWQgdG8gdGVsbCBOZXh1c1VJIHRvIHVzZSB0aGF0IGNvbnRleHQgaW5zdGVhZDogaS5lLiBOZXh1cy5jb250ZXh0ID0gWW91ckF1ZGlvQ29udGV4dE5hbWUuIEZvciBleGFtcGxlLCBpbiBUb25lSlMgcHJvamVjdHMsIHRoZSBsaW5lIHdvdWxkIGJlOiBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC4gV2UgcmVjb21tZW5kIHRoYXQgeW91IHdyaXRlIHRoYXQgbGluZSBvZiBjb2RlIG9ubHkgb25jZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgcHJvamVjdC5cbiAgQHBhcmFtIG5vZGUge0F1ZGlvTm9kZX0gVGhlIGF1ZGlvIG5vZGUgdG8gdmlzdWFsaXplXG4gIEBwYXJhbSBjaGFubmVscyB7bnVtYmVyfSAob3B0aW9uYWwpIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIHNvdXJjZSBub2RlIHRvIHdhdGNoLiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgaW50ZXJmYWNlIHdpbGwgbG9vayBmb3IgYSAuY2hhbm5lbENvdW50IHByb3BlcnR5IG9uIHRoZSBpbnB1dCBub2RlLiBJZiBpdCBkb2VzIG5vdCBleGlzdCwgdGhlIGludGVyZmFjZSB3aWxsIGRlZmF1bHQgdG8gMSBjaGFubmVsLlxuICBAZXhhbXBsZSBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC8vIG9yIGFub3RoZXIgYXVkaW8gY29udGV4dCB5b3UgaGF2ZSBjcmVhdGVkXG4gIG1ldGVyLmNvbm5lY3QoIFRvbmUuTWFzdGVyLCAyICk7XG4gICovXG5cbiAgY29ubmVjdChub2RlLGNoYW5uZWxzKSB7XG4gICAgaWYgKHRoaXMuc291cmNlKSB7XG4gICAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG4gICAgLy90aGlzLmR1bW15LmRpc2Nvbm5lY3QodGhpcy5zcGxpdHRlcik7XG5cbiAgICBpZiAoY2hhbm5lbHMpIHtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVscztcbiAgICB9IGVsc2UgaWYgKG5vZGUuY2hhbm5lbENvdW50KSB7XG4gICAgICB0aGlzLmNoYW5uZWxzID0gbm9kZS5jaGFubmVsQ291bnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSAyO1xuICAgIH1cbiAgICB0aGlzLm1ldGVyV2lkdGggPSB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoL3RoaXMuY2hhbm5lbHM7XG5cbiAgICB0aGlzLnNvdXJjZSA9IG5vZGU7XG4gICAgdGhpcy5zb3VyY2UuY29ubmVjdCh0aGlzLnNwbGl0dGVyKTtcblxuICAvLyAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBTdG9wIHZpc3VhbGl6aW5nIHRoZSBzb3VyY2Ugbm9kZSBhbmQgZGlzY29ubmVjdCBpdC5cbiAgKi9cbiAgZGlzY29ubmVjdCgpIHtcblxuICAgIHRoaXMuc291cmNlLmRpc2Nvbm5lY3QodGhpcy5zcGxpdHRlcik7XG4gICAgdGhpcy5zb3VyY2UgPSBmYWxzZTtcbiAgLy8gIHRoaXMuZHVtbXkuY29ubmVjdCh0aGlzLnNwbGl0dGVyKTtcbiAgICB0aGlzLm1ldGVyV2lkdGggPSB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoL3RoaXMuY2hhbm5lbHM7XG5cbiAgfVxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBjdXN0b21EZXN0cm95KCkge1xuICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvbWV0ZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBkb20gPSByZXF1aXJlKCcuLi91dGlsL2RvbScpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5cbi8qKlxuKiBPc2NpbGxvc2NvcGVcbipcbiogQGRlc2NyaXB0aW9uIFZpc3VhbGl6ZXMgYSB3YXZlZm9ybSdzIHN0cmVhbSBvZiB2YWx1ZXMuXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwib3NjaWxsb3Njb3BlXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgb3NjaWxsb3Njb3BlID0gbmV3IE5leHVzLk9zY2lsbG9zY29wZSgnI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBvc2NpbGxvc2NvcGUgPSBuZXcgTmV4dXMuT3NjaWxsb3Njb3BlKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMzAwLDE1MF1cbiogfSlcbipcbiogQG91dHB1dFxuKiAmbmJzcDtcbiogTm8gZXZlbnRzXG4qXG4qL1xuXG5pbXBvcnQgeyBjb250ZXh0IH0gZnJvbSAnLi4vbWFpbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE9zY2lsbG9zY29wZSBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnc2NhbGUnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMzAwLDE1MF1cbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dCgpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuICAgIHRoaXMuYW5hbHlzZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgICB0aGlzLmFuYWx5c2VyLmZmdFNpemUgPSAyMDQ4O1xuICAgIHRoaXMuYnVmZmVyTGVuZ3RoID0gdGhpcy5hbmFseXNlci5mcmVxdWVuY3lCaW5Db3VudDtcbiAgICB0aGlzLmRhdGFBcnJheSA9IG5ldyBVaW50OEFycmF5KHRoaXMuYnVmZmVyTGVuZ3RoKTtcbiAgICB0aGlzLmFuYWx5c2VyLmdldEJ5dGVUaW1lRG9tYWluRGF0YSh0aGlzLmRhdGFBcnJheSk7XG5cbiAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG5cbiAgICB0aGlzLnNvdXJjZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmNhbnZhcyA9IG5ldyBkb20uU21hcnRDYW52YXModGhpcy5wYXJlbnQpO1xuICAgIHRoaXMuZWxlbWVudCA9IHRoaXMuY2FudmFzLmVsZW1lbnQ7XG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuICAgIHRoaXMuY2FudmFzLnJlc2l6ZSh0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuY2FudmFzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgfVxuXG4gIHJlbmRlcigpIHtcblxuICAgIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMucmVuZGVyLmJpbmQodGhpcykpO1xuICAgIH1cblxuICAgIHRoaXMuYW5hbHlzZXIuZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKHRoaXMuZGF0YUFycmF5KTtcblxuICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KDAsIDAsIHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgsIHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0KTtcblxuICAgIHRoaXMuY2FudmFzLmNvbnRleHQubGluZVdpZHRoID0gfn4odGhpcy5oZWlnaHQgLyAxMDAgKyAyKTtcbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LnN0cm9rZVN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuXG4gICAgdGhpcy5jYW52YXMuY29udGV4dC5iZWdpblBhdGgoKTtcblxuICAgIGlmICh0aGlzLnNvdXJjZSkge1xuXG4gICAgICB2YXIgc2xpY2VXaWR0aCA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGggKiAxLjAgLyB0aGlzLmJ1ZmZlckxlbmd0aDtcbiAgICAgIHZhciB4ID0gMDtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJ1ZmZlckxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgdmFyIHYgPSB0aGlzLmRhdGFBcnJheVtpXSAvIDEyOC4wO1xuICAgICAgICB2YXIgeSA9IHYgKiB0aGlzLmNhbnZhcy5lbGVtZW50LmhlaWdodCAvIDI7XG5cbiAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0Lm1vdmVUbyh4LCB5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmxpbmVUbyh4LCB5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHggKz0gc2xpY2VXaWR0aDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0Lm1vdmVUbygwLCB0aGlzLmNhbnZhcy5lbGVtZW50LmhlaWdodC8yKTtcbiAgICAgICAgdGhpcy5jYW52YXMuY29udGV4dC5saW5lVG8odGhpcy5jYW52YXMuZWxlbWVudC53aWR0aCwgdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQvMik7XG4gICAgfVxuXG4gICAgdGhpcy5jYW52YXMuY29udGV4dC5zdHJva2UoKTtcbiAgfVxuXG4gIC8qKlxuICBFcXVpdmFsZW50IHRvIFwicGF0Y2hpbmcgaW5cIiBhbiBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZS4gTk9URTogWW91IGNhbm5vdCBjb25uZWN0IGF1ZGlvIG5vZGVzIGFjcm9zcyB0d28gZGlmZmVyZW50IGF1ZGlvIGNvbnRleHRzLiBOZXh1c1VJIHJ1bnMgaXRzIGF1ZGlvIGFuYWx5c2lzIG9uIGl0cyBvd24gYXVkaW8gY29udGV4dCwgTmV4dXMuY29udGV4dC4gSWYgdGhlIGF1ZGlvIG5vZGUgeW91IGFyZSB2aXN1YWxpemluZyBpcyBjcmVhdGVkIG9uIGEgZGlmZmVyZW50IGF1ZGlvIGNvbnRleHQsIHlvdSB3aWxsIG5lZWQgdG8gdGVsbCBOZXh1c1VJIHRvIHVzZSB0aGF0IGNvbnRleHQgaW5zdGVhZDogaS5lLiBOZXh1cy5jb250ZXh0ID0gWW91ckF1ZGlvQ29udGV4dE5hbWUuIEZvciBleGFtcGxlLCBpbiBUb25lSlMgcHJvamVjdHMsIHRoZSBsaW5lIHdvdWxkIGJlOiBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC4gV2UgcmVjb21tZW5kIHRoYXQgeW91IHdyaXRlIHRoYXQgbGluZSBvZiBjb2RlIG9ubHkgb25jZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgcHJvamVjdC5cbiAgQHBhcmFtIG5vZGUge0F1ZGlvTm9kZX0gVGhlIGF1ZGlvIG5vZGUgdG8gdmlzdWFsaXplXG4gIEBleGFtcGxlIE5leHVzLmNvbnRleHQgPSBUb25lLmNvbnRleHQgLy8gb3IgYW5vdGhlciBhdWRpbyBjb250ZXh0IHlvdSBoYXZlIGNyZWF0ZWRcbiAgb3NjaWxsb3Njb3BlLmNvbm5lY3QoIFRvbmUuTWFzdGVyICk7XG4gICovXG5cbiAgY29ubmVjdChub2RlKSB7XG5cbiAgICBpZiAodGhpcy5zb3VyY2UpIHtcbiAgICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIH1cblxuICAgIHRoaXMuc291cmNlID0gbm9kZTtcbiAgICB0aGlzLnNvdXJjZS5jb25uZWN0KHRoaXMuYW5hbHlzZXIpO1xuXG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBTdG9wIHZpc3VhbGl6aW5nIHRoZSBzb3VyY2Ugbm9kZSBhbmQgZGlzY29ubmVjdCBpdC5cbiAgKi9cbiAgZGlzY29ubmVjdCgpIHtcbiAgICBpZiAodGhpcy5zb3VyY2UpIHtcbiAgICAgIHRoaXMuc291cmNlLmRpc2Nvbm5lY3QodGhpcy5hbmFseXNlcik7XG4gICAgICB0aGlzLnNvdXJjZSA9IG51bGw7XG4gICAgfVxuXG4gIH1cblxuICBjbGljaygpIHtcbiAgICB0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL29zY2lsbG9zY29wZS5qcyIsIi8qXG5NYWluIGNvbmNlcHQ6XG5zeW50aCA9IG5ldyBOZXh1cy5SYWNrKCdlbGVtZW50SUQnKTtcblxuVHJhbnNmb3JtIGFsbCBlbGVtZW50cyBpbnNpZGUgdGhlIGRpdlxuc3ludGguZWxlbWVudElEIHdpbGwgaG9sZCB0aGUgZmlyc3Qgc2xpZGVyIGludGVyZmFjZVxuXG4yKSBJbiBmdXR1cmUsIHBvdGVudGlhbGx5IHdyaXRpbmcgYSByYWNrIHRoYXQgaXMgcmUtdXNhYmxlP1xuQ291bGQgYWxzbyB0YWtlIEpTT05cblxubmV3IE5leHVzLlJhY2soJyN0YXJnZXQnLHtcbiAgcHJlOiAoKSA9PiB7XG4gICAgY3JlYXRlIHNvbWUgZGl2cyBoZXJlLCBvciBzb21lIGF1ZGlvIGNvZGVcbiAgfSxcbiAgaW50ZXJmYWNlOiB7XG4gICAgc2xpZGVyMTogTmV4dXMuYWRkLnNsaWRlcih7XG4gICAgICB0b3A6MTAsXG4gICAgICBsZWZ0OjEwLFxuICAgICAgd2lkdGg6NTAsXG4gICAgICBoZWlnaHQ6MTAwLFxuICAgICAgbWluOiAwLFxuICAgICAgbWF4OiAxMDAsXG4gICAgICBzdGVwOiAxXG4gICAgfSksXG4gICAgd2F2ZTE6IE5leHVzLmFkZC53YXZlZm9ybSh7XG4gICAgICBmaWxlOiAnLi9wYXRoL3RvL2ZpbGUubXAzJyxcbiAgICAgIHdpZHRoOjUwMCxcbiAgICAgIGhlaWdodDoxMDAsXG4gICAgICBtb2RlOiAncmFuZ2UnXG4gICAgfSlcbiAgfSxcbiAgaW5pdDogKCkgPT4ge1xuICAgIC8vIHNvbWUgYXVkaW8gaW5pdCBjb2RlIGdvZXMgaGVyZS4uLlxuICB9XG59KTtcblxuKi9cblxuaW1wb3J0ICogYXMgdHJhbnNmb3JtIGZyb20gJy4uL3V0aWwvdHJhbnNmb3JtJztcbmltcG9ydCBkb20gZnJvbSAnLi4vdXRpbC9kb20nO1xuXG5pbXBvcnQgeyBjb2xvcnMgfSBmcm9tICcuLi9tYWluJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmFjayB7XG5cbiAgY29uc3RydWN0b3IodGFyZ2V0LCBzZXR0aW5ncykge1xuXG4gICAgdGhpcy5tZXRhID0ge307XG4gICAgdGhpcy5tZXRhLnRhcmdldCA9IHRhcmdldDtcbiAgICB0aGlzLm1ldGEucGFyZW50ID0gZG9tLnBhcnNlRWxlbWVudCh0YXJnZXQpOyAvLyBzaG91bGQgYmUgYSBnZW5lcmljIGZ1bmN0aW9uIGZvciBwYXJzaW5nIGEgJ3RhcmdldCcgYXJndW1lbnQgdGhhdCBjaGVja3MgZm9yIHN0cmluZy9ET00valFVRVJZXG4gICAgdGhpcy5tZXRhLmNvbG9ycyA9IHt9O1xuXG4gICAgaWYgKHNldHRpbmdzKSB7XG4gICAgICB0aGlzLm1ldGEuYXR0cmlidXRlID0gc2V0dGluZ3MuYXR0cmlidXRlIHx8ICduZXh1cy11aSc7XG4gICAgICB0aGlzLm1ldGEudGl0bGUgPSBzZXR0aW5ncy5uYW1lIHx8IGZhbHNlO1xuICAgICAgdGhpcy5tZXRhLm9wZW4gPSBzZXR0aW5ncy5vcGVuIHx8IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1ldGEuYXR0cmlidXRlID0gJ25leHVzLXVpJztcbiAgICAgIHRoaXMubWV0YS50aXRsZSA9IGZhbHNlO1xuICAgICAgdGhpcy5tZXRhLm9wZW4gPSBmYWxzZTtcbiAgICB9XG5cbiAgICBsZXQgZGVmYXVsdENvbG9ycyA9IGNvbG9ycygpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgICB0aGlzLm1ldGEuY29sb3JzLmFjY2VudCA9IGRlZmF1bHRDb2xvcnMuYWNjZW50O1xuICAgIHRoaXMubWV0YS5jb2xvcnMuZmlsbCA9IGRlZmF1bHRDb2xvcnMuZmlsbDtcbiAgICB0aGlzLm1ldGEuY29sb3JzLmxpZ2h0ID0gZGVmYXVsdENvbG9ycy5saWdodDtcbiAgICB0aGlzLm1ldGEuY29sb3JzLmRhcmsgPSBkZWZhdWx0Q29sb3JzLmRhcms7XG4gICAgdGhpcy5tZXRhLmNvbG9ycy5tZWRpdW1MaWdodCA9IGRlZmF1bHRDb2xvcnMubWVkaXVtTGlnaHQ7XG4gICAgdGhpcy5tZXRhLmNvbG9ycy5tZWRpdW1EYXJrID0gZGVmYXVsdENvbG9ycy5tZWRpdW1EYXJrO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgICB0aGlzLmNvbG9ySW50ZXJmYWNlKCk7XG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcbiAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLmJveFNpemluZyA9ICdib3JkZXItYm94JztcbiAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLnVzZXJTZWxlY3QgPSAnbm9uZSc7XG4gICAgdGhpcy5tZXRhLnBhcmVudC5zdHlsZS5tb3pVc2VyU2VsZWN0ID0gJ25vbmUnO1xuICAgIHRoaXMubWV0YS5wYXJlbnQuc3R5bGUud2Via2l0VXNlclNlbGVjdCA9ICdub25lJztcblxuICAgIHRoaXMubWV0YS5jb250ZW50cyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG4gICAgd2hpbGUgKHRoaXMubWV0YS5wYXJlbnQuY2hpbGROb2Rlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMubWV0YS5jb250ZW50cy5hcHBlbmRDaGlsZCh0aGlzLm1ldGEucGFyZW50LmNoaWxkTm9kZXNbMF0pO1xuICAgIH1cblxuICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5wYWRkaW5nID0gJzBweCc7XG4gICAgdGhpcy5tZXRhLmNvbnRlbnRzLnN0eWxlLmJveFNpemluZyA9ICdib3JkZXItYm94JztcblxuICAgIGlmICh0aGlzLm1ldGEudGl0bGUpIHtcbiAgICAgIHRoaXMubWV0YS50aXRsZUJhciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLmlubmVySFRNTCA9IHRoaXMubWV0YS50aXRsZTtcbiAgICAgIHRoaXMubWV0YS50aXRsZUJhci5zdHlsZS5mb250RmFtaWx5ID0gJ2FyaWFsJztcbiAgICAgIHRoaXMubWV0YS50aXRsZUJhci5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgICB0aGlzLm1ldGEudGl0bGVCYXIuc3R5bGUuY29sb3IgPSAnIzg4OCc7XG4gICAgICB0aGlzLm1ldGEudGl0bGVCYXIuc3R5bGUucGFkZGluZyA9ICc3cHgnO1xuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLnN0eWxlLmZvbnRTaXplID0gJzEycHgnO1xuXG4gICAgICB0aGlzLm1ldGEuYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUudG9wID0gJzVweCcgO1xuICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5yaWdodCA9ICc1cHgnIDtcbiAgICAgIHRoaXMubWV0YS5idXR0b24uaW5uZXJIVE1MID0gJy0nO1xuICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5wYWRkaW5nID0gJzBweCA1cHggMnB4JztcbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUubGluZUhlaWdodCA9ICcxMnB4JztcbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUuZm9udFNpemUgPSAnMTVweCc7XG5cbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInO1xuXG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3ZlcicsICgpID0+IHtcbiAgICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLm1lZGl1bURhcms7XG4gICAgICB9KTtcbiAgICAgIHRoaXMubWV0YS5idXR0b24uYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLm1lZGl1bUxpZ2h0O1xuICAgICAgfSk7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tZXRhLm9wZW4pIHtcbiAgICAgICAgICB0aGlzLmhpZGUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNob3coKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cblxuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLmFwcGVuZENoaWxkKHRoaXMubWV0YS5idXR0b24pO1xuXG4gICAgICB0aGlzLm1ldGEucGFyZW50LmFwcGVuZENoaWxkKHRoaXMubWV0YS50aXRsZUJhcik7XG4gICAgfVxuICAgIHRoaXMubWV0YS5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5tZXRhLmNvbnRlbnRzKTtcblxuICAvLyAgdmFyIHdpZHRoID0gdGhpcy5tZXRhLnBhcmVudC5zdHlsZS53aWR0aCA9IGdldENvbXB1dGVkU3R5bGUodGhpcy5tZXRhLnBhcmVudCkuZ2V0UHJvcGVydHlWYWx1ZSgnd2lkdGgnKTtcbi8vICAgIHRoaXMubWV0YS5wYXJlbnQuc3R5bGUud2lkdGggPSB3aWR0aDtcblxuICAgIGxldCB1aSA9IHRyYW5zZm9ybS5zZWN0aW9uKHRoaXMubWV0YS50YXJnZXQsIHRoaXMubWV0YS5hdHRyaWJ1dGUpO1xuICAgIGZvciAodmFyIGtleSBpbiB1aSkge1xuICAgICAgdGhpc1trZXldID0gdWlba2V5XTtcbiAgICB9XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICBpZiAodGhpcy5tZXRhLnRpdGxlKSB7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMubWV0YS5jb2xvcnMubWVkaXVtTGlnaHQ7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLmJvcmRlciA9ICdzb2xpZCAwcHggJyt0aGlzLm1ldGEuY29sb3JzLmZpbGw7XG4gICAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLmJvcmRlciA9ICdzb2xpZCAxcHggJyt0aGlzLm1ldGEuY29sb3JzLm1lZGl1bUxpZ2h0O1xuICAgICAgdGhpcy5tZXRhLnBhcmVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLmxpZ2h0O1xuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMubWV0YS5jb2xvcnMuZmlsbDtcbiAgICB9XG4gIH1cblxuICBzaG93KCkge1xuICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICB0aGlzLm1ldGEub3BlbiA9IHRydWU7XG4gIH1cblxuICBoaWRlKCkge1xuICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHRoaXMubWV0YS5vcGVuID0gZmFsc2U7XG4gIH1cblxuICBjb2xvcml6ZSh0eXBlLGNvbG9yKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMpIHtcbiAgICAgIGlmICh0aGlzW2tleV0uY29sb3JpemUpIHtcbiAgICAgICAgdGhpc1trZXldLmNvbG9yaXplKHR5cGUsY29sb3IpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLm1ldGEuY29sb3JzW3R5cGVdID0gY29sb3I7XG4gICAgdGhpcy5jb2xvckludGVyZmFjZSgpO1xuICB9XG5cbiAgZW1wdHkoKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMpIHtcbiAgICAgIGlmICh0aGlzW2tleV0uZGVzdHJveSkge1xuICAgICAgICB0aGlzW2tleV0uZGVzdHJveSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvY29yZS9yYWNrLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgZG9tIGZyb20gJy4uL3V0aWwvZG9tJztcbmltcG9ydCBJbnRlcmZhY2VzIGZyb20gJy4uL2ludGVyZmFjZXMvJztcblxubGV0IGNyZWF0ZUludGVyZmFjZUlEID0gKHdpZGdldCxpbnRlcmZhY2VJRHMpID0+IHtcbiAgbGV0IHR5cGUgPSB3aWRnZXQudHlwZTtcbiAgaWYgKGludGVyZmFjZUlEc1t0eXBlXSkge1xuICAgIGludGVyZmFjZUlEc1t0eXBlXSsrO1xuICB9IGVsc2Uge1xuICAgIGludGVyZmFjZUlEc1t0eXBlXSA9IDE7XG4gIH1cbiAgcmV0dXJuICggdHlwZSArIGludGVyZmFjZUlEc1t0eXBlXSApO1xufTtcblxubGV0IGVsZW1lbnQgPSAoZWxlbWVudCx0eXBlLG9wdGlvbnMpID0+IHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudC5hdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKXtcbiAgICBsZXQgYXR0ID0gZWxlbWVudC5hdHRyaWJ1dGVzW2ldO1xuICAvLyAgdHJ5IHtcbiAgLy8gICAgb3B0aW9uc1thdHQubm9kZU5hbWVdID0gZXZhbChhdHQubm9kZVZhbHVlKTtcbiAgLy8gIH0gY2F0Y2goZSkge1xuICAgICAgb3B0aW9uc1thdHQubm9kZU5hbWVdID0gYXR0Lm5vZGVWYWx1ZTtcbiAgLy8gIH1cbiAgfVxuICB0eXBlID0gdHlwZVswXS50b1VwcGVyQ2FzZSgpICsgdHlwZS5zbGljZSgxKTtcbiAgbGV0IHdpZGdldCA9IG5ldyBJbnRlcmZhY2VzW3R5cGVdKGVsZW1lbnQsb3B0aW9ucyk7XG4gIHdpZGdldC5pZCA9IGVsZW1lbnQuaWQ7XG4gIHJldHVybiB3aWRnZXQ7XG59O1xuXG5cbmxldCBzZWN0aW9uID0gKHBhcmVudCxrZXl3b3JkKSA9PiB7XG5cbiAga2V5d29yZCA9IGtleXdvcmQgfHwgJ25leHVzLXVpJztcblxuICBsZXQgaW50ZXJmYWNlSURzID0ge307XG5cbiAgbGV0IGNvbnRhaW5lciA9IGRvbS5wYXJzZUVsZW1lbnQocGFyZW50KTtcblxuICBsZXQgdWkgPSB7fTtcblxuICBsZXQgaHRtbEVsZW1lbnRzID0gY29udGFpbmVyLmdldEVsZW1lbnRzQnlUYWdOYW1lKCcqJyk7XG4gIGxldCBlbGVtZW50cyA9IFtdO1xuICBmb3IgKGxldCBpPTA7IGk8aHRtbEVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgZWxlbWVudHMucHVzaChodG1sRWxlbWVudHNbaV0pO1xuICB9XG4gIGZvciAobGV0IGk9MDtpPGVsZW1lbnRzLmxlbmd0aDtpKyspIHtcbiAgICBsZXQgdHlwZSA9IGVsZW1lbnRzW2ldLmdldEF0dHJpYnV0ZShrZXl3b3JkKTtcbiAgICBpZiAodHlwZSkge1xuICAgICAgbGV0IGZvcm1hdHRlZFR5cGUgPSBmYWxzZTtcbiAgICAgIGZvciAobGV0IGtleSBpbiBJbnRlcmZhY2VzKSB7XG4gICAgICAgIGlmICh0eXBlLnRvTG93ZXJDYXNlKCk9PT1rZXkudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgIGZvcm1hdHRlZFR5cGUgPSBrZXk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnNvbGUubG9nKGZvcm1hdHRlZFR5cGUpO1xuICAgICAgbGV0IHdpZGdldCA9IGVsZW1lbnQoZWxlbWVudHNbaV0sZm9ybWF0dGVkVHlwZSk7XG4gICAgICBpZiAod2lkZ2V0LmlkKSB7XG4gICAgICAgIHVpW3dpZGdldC5pZF0gPSB3aWRnZXQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgaWQgPSBjcmVhdGVJbnRlcmZhY2VJRCh3aWRnZXQsaW50ZXJmYWNlSURzKTtcbiAgICAgICAgdWlbaWRdID0gd2lkZ2V0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1aTtcblxufTtcblxubGV0IGFkZCA9ICh0eXBlLHBhcmVudCxvcHRpb25zKSA9PiB7XG4gIGxldCB0YXJnZXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGlmIChwYXJlbnQpIHtcbiAgICBwYXJlbnQgPSBkb20ucGFyc2VFbGVtZW50KHBhcmVudCk7XG4gIH0gZWxzZSB7XG4gICAgcGFyZW50ID0gZG9jdW1lbnQuYm9keTtcbiAgfVxuICBwYXJlbnQuYXBwZW5kQ2hpbGQodGFyZ2V0KTtcbiAgb3B0aW9ucy50YXJnZXQgPSB0YXJnZXQ7XG4gIGlmIChvcHRpb25zLnNpemUpIHtcbiAgICB0YXJnZXQuc3R5bGUud2lkdGggPSBvcHRpb25zLnNpemVbMF0gKyAncHgnO1xuICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSBvcHRpb25zLnNpemVbMV0gKyAncHgnO1xuICB9XG4gIHJldHVybiBlbGVtZW50KHRhcmdldCx0eXBlLG9wdGlvbnMpO1xufTtcblxuZXhwb3J0IHsgZWxlbWVudCB9O1xuZXhwb3J0IHsgc2VjdGlvbiB9O1xuZXhwb3J0IHsgYWRkIH07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvdXRpbC90cmFuc2Zvcm0uanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFR1bmUge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gIFx0Ly8gdGhlIHNjYWxlIGFzIHJhdGlvc1xuICBcdHRoaXMuc2NhbGUgPSBbXTtcblxuICBcdC8vIGkvbyBtb2Rlc1xuICBcdHRoaXMubW9kZSA9IHtcbiAgXHRcdG91dHB1dDogJ2ZyZXF1ZW5jeScsXG4gIFx0XHRpbnB1dDogJ3N0ZXAnXG4gIFx0fTtcblxuICBcdC8vIEVUIG1ham9yXG4gIFx0dGhpcy5ldG1ham9yID0gWyAyNjEuNjI1NTgsXG4gIFx0XHQyOTMuNjY0NzY0LFxuICBcdFx0MzI5LjYyNzU2MyxcbiAgXHRcdDM0OS4yMjgyNDEsXG4gIFx0XHQzOTEuOTk1NDIyLFxuICBcdFx0NDQwLFxuICBcdFx0NDkzLjg4MzMwMSxcbiAgXHRcdDUyMy4yNTExNlxuICBcdF07XG5cbiAgXHQvLyBSb290IGZyZXF1ZW5jeS5cbiAgXHR0aGlzLnJvb3QgPSBtYXRoLm10b2YoNjApOyAgICAgLy8gKiBNYXRoLnBvdygyLCg2MC02OSkvMTIpO1xuXG4gICAgLy8gZGVmYXVsdCBpcyBhIG1ham9yIHNjYWxlXG4gICAgdGhpcy5jcmVhdGVTY2FsZSgwLDIsNCw1LDcsOSwxMSk7XG5cbiAgfVxuXG4gIC8qIFJldHVybiBkYXRhIGluIHRoZSBtb2RlIHlvdSBhcmUgaW4gKGZyZXEsIHJhdGlvLCBvciBtaWRpKSAqL1xuICBub3RlKGlucHV0LG9jdGF2ZSkge1xuXG4gIFx0bGV0IG5ld3ZhbHVlO1xuXG4gIFx0aWYgKHRoaXMubW9kZS5vdXRwdXQgPT09ICdmcmVxdWVuY3knKSB7XG4gIFx0XHRuZXd2YWx1ZSA9IHRoaXMuZnJlcXVlbmN5KGlucHV0LG9jdGF2ZSk7XG4gIFx0fSBlbHNlIGlmICh0aGlzLm1vZGUub3V0cHV0ID09PSAncmF0aW8nKSB7XG4gIFx0XHRuZXd2YWx1ZSA9IHRoaXMucmF0aW8oaW5wdXQsb2N0YXZlKTtcbiAgXHR9IGVsc2UgaWYgKHRoaXMubW9kZS5vdXRwdXQgPT09ICdNSURJJykge1xuICBcdFx0bmV3dmFsdWUgPSB0aGlzLk1JREkoaW5wdXQsb2N0YXZlKTtcbiAgXHR9IGVsc2Uge1xuICBcdFx0bmV3dmFsdWUgPSB0aGlzLmZyZXF1ZW5jeShpbnB1dCxvY3RhdmUpO1xuICBcdH1cblxuICBcdHJldHVybiBuZXd2YWx1ZTtcblxuICB9XG5cblxuICAvKiBSZXR1cm4gZnJlcSBkYXRhICovXG4gIGZyZXF1ZW5jeShzdGVwSW4sIG9jdGF2ZUluKSB7XG5cbiAgXHRpZiAodGhpcy5tb2RlLmlucHV0ID09PSAnbWlkaScgfHwgdGhpcy5tb2RlLmlucHV0ID09PSAnTUlESScgKSB7XG4gIFx0XHR0aGlzLnN0ZXBJbiArPSA2MDtcbiAgXHR9XG5cbiAgXHQvLyB3aGF0IG9jdGF2ZSBpcyBvdXIgaW5wdXRcbiAgXHRsZXQgb2N0YXZlID0gTWF0aC5mbG9vcihzdGVwSW4vdGhpcy5zY2FsZS5sZW5ndGgpO1xuXG4gIFx0aWYgKG9jdGF2ZUluKSB7XG4gIFx0XHRvY3RhdmUgKz0gb2N0YXZlSW47XG4gIFx0fVxuXG4gIFx0Ly8gd2hpY2ggc2NhbGUgZGVncmVlICgwIC0gc2NhbGUgbGVuZ3RoKSBpcyBvdXIgaW5wdXRcbiAgXHRsZXQgc2NhbGVEZWdyZWUgPSBzdGVwSW4gJSB0aGlzLnNjYWxlLmxlbmd0aDtcblxuICBcdHdoaWxlIChzY2FsZURlZ3JlZSA8IDApIHtcbiAgXHRcdHNjYWxlRGVncmVlICs9IHRoaXMuc2NhbGUubGVuZ3RoO1xuICBcdH1cblxuICAgIGxldCByYXRpbyA9IHRoaXMuc2NhbGVbc2NhbGVEZWdyZWVdO1xuXG4gIFx0bGV0IGZyZXEgPSB0aGlzLnJvb3QgKiByYXRpbztcblxuICBcdGZyZXEgPSBmcmVxKihNYXRoLnBvdygyLG9jdGF2ZSkpO1xuXG4gIFx0Ly8gdHJ1bmNhdGUgaXJyYXRpb25hbCBudW1iZXJzXG4gIFx0ZnJlcSA9IE1hdGguZmxvb3IoZnJlcSoxMDAwMDAwMDAwMDApLzEwMDAwMDAwMDAwMDtcblxuICBcdHJldHVybiBmcmVxO1xuXG4gIH1cblxuICAvKiBGb3JjZSByZXR1cm4gcmF0aW8gZGF0YSAqL1xuXG4gIHJhdGlvKHN0ZXBJbiwgb2N0YXZlSW4pIHtcblxuICBcdGlmICh0aGlzLm1vZGUuaW5wdXQgPT09ICdtaWRpJyB8fCB0aGlzLm1vZGUuaW5wdXQgPT09ICdNSURJJyApIHtcbiAgXHRcdHRoaXMuc3RlcEluICs9IDYwO1xuICBcdH1cblxuICBcdC8vIHdoYXQgb2N0YXZlIGlzIG91ciBpbnB1dFxuICBcdGxldCBvY3RhdmUgPSBNYXRoLmZsb29yKHN0ZXBJbi90aGlzLnNjYWxlLmxlbmd0aCk7XG5cbiAgXHRpZiAob2N0YXZlSW4pIHtcbiAgXHRcdG9jdGF2ZSArPSBvY3RhdmVJbjtcbiAgXHR9XG5cbiAgXHQvLyB3aGljaCBzY2FsZSBkZWdyZWUgKDAgLSBzY2FsZSBsZW5ndGgpIGlzIG91ciBpbnB1dFxuICBcdGxldCBzY2FsZURlZ3JlZSA9IHN0ZXBJbiAlIHRoaXMuc2NhbGUubGVuZ3RoO1xuXG4gIFx0Ly8gd2hhdCByYXRpbyBpcyBvdXIgaW5wdXQgdG8gb3VyIGtleVxuICBcdGxldCByYXRpbyA9IE1hdGgucG93KDIsb2N0YXZlKSp0aGlzLnNjYWxlW3NjYWxlRGVncmVlXTtcblxuICBcdHJhdGlvID0gTWF0aC5mbG9vcihyYXRpbyoxMDAwMDAwMDAwMDApLzEwMDAwMDAwMDAwMDtcblxuICBcdHJldHVybiByYXRpbztcblxuICB9XG5cbiAgLyogRm9yY2UgcmV0dXJuIGFkanVzdGVkIE1JREkgZGF0YSAqL1xuXG4gIE1JREkoc3RlcEluLG9jdGF2ZUluKSB7XG5cbiAgXHRsZXQgbmV3dmFsdWUgPSB0aGlzLmZyZXF1ZW5jeShzdGVwSW4sb2N0YXZlSW4pO1xuXG4gIFx0bGV0IG4gPSA2OSArIDEyKk1hdGgubG9nKG5ld3ZhbHVlLzQ0MCkvTWF0aC5sb2coMik7XG5cbiAgXHRuID0gTWF0aC5mbG9vcihuKjEwMDAwMDAwMDApLzEwMDAwMDAwMDA7XG5cbiAgXHRyZXR1cm4gbjtcblxuICB9XG5cbiAgY3JlYXRlU2NhbGUoKSB7XG4gICAgbGV0IG5ld1NjYWxlID0gW107XG4gICAgZm9yIChsZXQgaT0wO2k8YXJndW1lbnRzLmxlbmd0aDtpKyspIHtcbiAgICAgIG5ld1NjYWxlLnB1c2goIG1hdGgubXRvZiggNjAgKyBhcmd1bWVudHNbaV0gKSApO1xuICAgIH1cbiAgICB0aGlzLmxvYWRTY2FsZUZyb21GcmVxdWVuY2llcyhuZXdTY2FsZSk7XG4gIH1cblxuICBjcmVhdGVKSVNjYWxlKCkge1xuICAgIHRoaXMuc2NhbGUgPSBbXTtcbiAgICBmb3IgKGxldCBpPTA7aTxhcmd1bWVudHMubGVuZ3RoO2krKykge1xuICAgICAgdGhpcy5zY2FsZS5wdXNoKGFyZ3VtZW50c1tpXSk7XG4gICAgfVxuICB9XG5cbiAgbG9hZFNjYWxlRnJvbUZyZXF1ZW5jaWVzKGZyZXFzKSB7XG4gICAgdGhpcy5zY2FsZSA9IFtdO1xuICAgIGZvciAobGV0IGk9MDtpPGZyZXFzLmxlbmd0aC0xO2krKykge1xuICAgICAgdGhpcy5zY2FsZS5wdXNoKGZyZXFzW2ldL2ZyZXFzWzBdKTtcbiAgICB9XG4gIH1cblxuICAvKiBMb2FkIGEgbmV3IHNjYWxlICovXG5cbiAgbG9hZFNjYWxlKG5hbWUpe1xuXG4gIFx0LyogbG9hZCB0aGUgc2NhbGUgKi9cbiAgXHRsZXQgZnJlcXMgPSB0aGlzLnNjYWxlc1tuYW1lXS5mcmVxdWVuY2llcztcbiAgICB0aGlzLmxvYWRTY2FsZUZyb21GcmVxdWVuY2llcyhmcmVxcyk7XG5cbiAgfVxuXG4gIC8qIFNlYXJjaCB0aGUgbmFtZXMgb2YgdHVuaW5nc1xuICBcdCBSZXR1cm5zIGFuIGFycmF5IG9mIG5hbWVzIG9mIHR1bmluZ3MgKi9cblxuICBzZWFyY2gobGV0dGVycykge1xuICBcdGxldCBwb3NzaWJsZSA9IFtdO1xuICBcdGZvciAobGV0IGtleSBpbiB0aGlzLnNjYWxlcykge1xuICBcdFx0aWYgKGtleS50b0xvd2VyQ2FzZSgpLmluZGV4T2YobGV0dGVycy50b0xvd2VyQ2FzZSgpKSAhPT0gLTEpIHtcbiAgXHRcdFx0cG9zc2libGUucHVzaChrZXkpO1xuICBcdFx0fVxuICBcdH1cbiAgXHRyZXR1cm4gcG9zc2libGU7XG4gIH1cblxuICAvKiBSZXR1cm4gYSBjb2xsZWN0aW9uIG9mIG5vdGVzIGFzIGFuIGFycmF5ICovXG5cbiAgY2hvcmQobWlkaXMpIHtcbiAgXHRsZXQgb3V0cHV0ID0gW107XG4gIFx0Zm9yIChsZXQgaT0wO2k8bWlkaXMubGVuZ3RoO2krKykge1xuICBcdFx0b3V0cHV0LnB1c2godGhpcy5ub3RlKG1pZGlzW2ldKSk7XG4gIFx0fVxuICBcdHJldHVybiBvdXRwdXQ7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3R1bmluZy90dW5pbmcuanMiLCIndXNlIHN0cmljdCc7XG5cbi8vRGlzYWJsZSBqc2hpbnQgd2FybmluZyBjb25jZXJuaW5nIHRyYWlsaW5nIHJlZ3VsYXIgcGFyYW1zXG4vKmpzaGludCAtVzEzOCAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSYWRpbyB7XG4gICAgLy9pZiBub24tZXhpc3RlbnQgYnV0dG9ucyBhcmUgc3dpdGNoZWQsIHRoZXkgYXJlIGlnbm9yZWRcblxuICAgIGNvbnN0cnVjdG9yKGxlbmd0aCA9IDMsIC4uLm9uVmFscykge1xuICAgICAgICAvL2VhY2ggb3B0aW9uYWwgJ29uVmFscycgYXJndW1lbnQgc3dpdGNoZXMgb24gdGhhdCB2YWx1ZSBpbiB0aGUgUmFkaW8gaWYgaXQgZXhpc3RzXG4gICAgICAgIC8vSW4gdGhlIGV4YW1wbGUgYmVsb3csIGEgMy1idXR0b24gcmFkaW8gaXMgY3JlYXRlZCwgaW5kZXggMCBpcyBzd2l0Y2hlZCBvbiwgaW5kZXggMSBpcyBzd2l0Y2hlZCBvbiB0aGVuIHRoZW4gYXR0ZW1wdGVkIGFnYWluIHByb2R1Y2luZyBhbiB3YXJuaW5nLCBhbmQgdGhlIGZpbmFsIGFyZ3VtZW50IHByb2R1Y2VzIGEgd2FybmluZyBiZWNhdXNlIHRoZSBpbmRleCB2YWx1ZSBkb2VzIG5vdCBleGlzdC5cbiAgICAgICAgLy9FeGFtcGxlOlxuICAgICAgICAvL2AgIHJhZGlvID0gbmV3IFJhZGlvKDMsIDAsIDEsIDEsIDMpO1xuICAgICAgICAvL+KApiAgWzEsMSwwXVxuXG4gICAgICAgIGlmIChsZW5ndGggPCAwKSB7IGxlbmd0aCA9IDE7IH1cblxuICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcbiAgICAgICAgdGhpcy5vblZhbHMgPSBvblZhbHM7XG4gICAgICAgIHRoaXMuYXJyYXkgPSBuZXcgQXJyYXkobGVuZ3RoKS5maWxsKDApO1xuXG4gICAgICAgIGlmIChvblZhbHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5vbiguLi5vblZhbHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2VsZWN0KHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYXJyYXkuZmlsbCgwKTtcbiAgICAgICAgdGhpcy5hcnJheVt2YWx1ZV0gPSAxO1xuICAgICAgICByZXR1cm4gdGhpcy5hcnJheTtcbiAgICB9XG5cbiAgICBmbGlwKC4uLnZhbHVlcykge1xuICAgICAgICAvL2ZsaXBzIHRoZSBzcGVjaWZpZWQgdmFsdWVzLiBpZiBubyB2YWx1ZSBpcyBzcGVjaWZpZWQsIGZsaXBzIGFsbCBidXR0b25zXG4gICAgICAgIGxldCBhID0gdGhpcy5hcnJheTtcbiAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB2YWx1ZXMuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgICAgICAgICAgaWYgKHYgPiBhLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdXYXJuaW5nOiBBbm9uUmFkaW9bJyArIHYgKyAnXSBkb2VzIG5vdCBleGlzdCcpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFbdl0gPSAoYVt2XSA/IDAgOiAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGEuZm9yRWFjaChmdW5jdGlvbih2LCBpLCBhcnIpIHtcbiAgICAgICAgICAgICAgICBhcnJbaV0gPSAodiA/IDAgOiAxKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhO1xuICAgIH1cblxuICAgIG9uKC4uLnZhbHVlcykge1xuICAgICAgICAvL3N3aXRjaCBvbiB0aGUgc3BlY2lmaWVkIHZhbHVlcy4gaWYgbm8gdmFsdWUgc3BlY2lmaWVkLCBmbGlwcyBvbiBhbGwgYnV0dG9uc1xuICAgICAgICBsZXQgYSA9IHRoaXMuYXJyYXk7XG4gICAgICAgIGlmICh2YWx1ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdmFsdWVzLmZvckVhY2goZnVuY3Rpb24odikge1xuICAgICAgICAgICAgICAgIGlmICh2ID4gYS5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignV2FybmluZzogQW5vblJhZGlvWycgKyB2ICsgJ10gZXhjZWVkcyBzaXplIG9mIG9iamVjdCcpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhW3ZdID09PSAxKSB7IGNvbnNvbGUud2FybignV2FybmluZzogQW5vblJhZGlvWycgKyB2ICsgJ10gd2FzIGFscmVhZHkgb24uJyk7IH1cbiAgICAgICAgICAgICAgICAgICAgYVt2XSA9IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhLmZpbGwoMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgb2ZmKC4uLnZhbHVlcykge1xuICAgICAgICAvL3N3aXRjaCBvZmYgdGhlIHNwZWNpZmllZCB2YWx1ZXMuIGlmIG5vIHZhbHVlIHNwZWNpZmllZCwgZmxpcHMgb2ZmIGFsbCBidXR0b25zXG4gICAgICAgIGxldCBhID0gdGhpcy5hcnJheTtcbiAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB2YWx1ZXMuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgICAgICAgICAgYVt2XSA9IDA7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGEuZmlsbCgwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYTtcbiAgICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbW9kZWxzL3JhZGlvLmpzIiwidmFyIFdBQUNsb2NrID0gcmVxdWlyZSgnLi9saWIvV0FBQ2xvY2snKVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdBQUNsb2NrXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHdpbmRvdy5XQUFDbG9jayA9IFdBQUNsb2NrXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vd2FhY2xvY2svaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDQyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBpc0Jyb3dzZXIgPSAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpXG5cbnZhciBDTE9DS19ERUZBVUxUUyA9IHtcbiAgdG9sZXJhbmNlTGF0ZTogMC4xMCxcbiAgdG9sZXJhbmNlRWFybHk6IDAuMDAxXG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09IEV2ZW50ID09PT09PT09PT09PT09PT09PT09IC8vXG52YXIgRXZlbnQgPSBmdW5jdGlvbihjbG9jaywgZGVhZGxpbmUsIGZ1bmMpIHtcbiAgdGhpcy5jbG9jayA9IGNsb2NrXG4gIHRoaXMuZnVuYyA9IGZ1bmNcbiAgdGhpcy5fY2xlYXJlZCA9IGZhbHNlIC8vIEZsYWcgdXNlZCB0byBjbGVhciBhbiBldmVudCBpbnNpZGUgY2FsbGJhY2tcblxuICB0aGlzLnRvbGVyYW5jZUxhdGUgPSBjbG9jay50b2xlcmFuY2VMYXRlXG4gIHRoaXMudG9sZXJhbmNlRWFybHkgPSBjbG9jay50b2xlcmFuY2VFYXJseVxuICB0aGlzLl9sYXRlc3RUaW1lID0gbnVsbFxuICB0aGlzLl9lYXJsaWVzdFRpbWUgPSBudWxsXG4gIHRoaXMuZGVhZGxpbmUgPSBudWxsXG4gIHRoaXMucmVwZWF0VGltZSA9IG51bGxcblxuICB0aGlzLnNjaGVkdWxlKGRlYWRsaW5lKVxufVxuXG4vLyBVbnNjaGVkdWxlcyB0aGUgZXZlbnRcbkV2ZW50LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuICB0aGlzLl9jbGVhcmVkID0gdHJ1ZVxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBTZXRzIHRoZSBldmVudCB0byByZXBlYXQgZXZlcnkgYHRpbWVgIHNlY29uZHMuXG5FdmVudC5wcm90b3R5cGUucmVwZWF0ID0gZnVuY3Rpb24odGltZSkge1xuICBpZiAodGltZSA9PT0gMClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlbGF5IGNhbm5vdCBiZSAwJylcbiAgdGhpcy5yZXBlYXRUaW1lID0gdGltZVxuICBpZiAoIXRoaXMuY2xvY2suX2hhc0V2ZW50KHRoaXMpKVxuICAgIHRoaXMuc2NoZWR1bGUodGhpcy5kZWFkbGluZSArIHRoaXMucmVwZWF0VGltZSlcbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gU2V0cyB0aGUgdGltZSB0b2xlcmFuY2Ugb2YgdGhlIGV2ZW50LlxuLy8gVGhlIGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQgaW4gdGhlIGludGVydmFsIGBbZGVhZGxpbmUgLSBlYXJseSwgZGVhZGxpbmUgKyBsYXRlXWBcbi8vIElmIHRoZSBjbG9jayBmYWlscyB0byBleGVjdXRlIHRoZSBldmVudCBpbiB0aW1lLCB0aGUgZXZlbnQgd2lsbCBiZSBkcm9wcGVkLlxuRXZlbnQucHJvdG90eXBlLnRvbGVyYW5jZSA9IGZ1bmN0aW9uKHZhbHVlcykge1xuICBpZiAodHlwZW9mIHZhbHVlcy5sYXRlID09PSAnbnVtYmVyJylcbiAgICB0aGlzLnRvbGVyYW5jZUxhdGUgPSB2YWx1ZXMubGF0ZVxuICBpZiAodHlwZW9mIHZhbHVlcy5lYXJseSA9PT0gJ251bWJlcicpXG4gICAgdGhpcy50b2xlcmFuY2VFYXJseSA9IHZhbHVlcy5lYXJseVxuICB0aGlzLl9yZWZyZXNoRWFybHlMYXRlRGF0ZXMoKVxuICBpZiAodGhpcy5jbG9jay5faGFzRXZlbnQodGhpcykpIHtcbiAgICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuICAgIHRoaXMuY2xvY2suX2luc2VydEV2ZW50KHRoaXMpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBldmVudCBpcyByZXBlYXRlZCwgZmFsc2Ugb3RoZXJ3aXNlXG5FdmVudC5wcm90b3R5cGUuaXNSZXBlYXRlZCA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5yZXBlYXRUaW1lICE9PSBudWxsIH1cblxuLy8gU2NoZWR1bGVzIHRoZSBldmVudCB0byBiZSByYW4gYmVmb3JlIGBkZWFkbGluZWAuXG4vLyBJZiB0aGUgdGltZSBpcyB3aXRoaW4gdGhlIGV2ZW50IHRvbGVyYW5jZSwgd2UgaGFuZGxlIHRoZSBldmVudCBpbW1lZGlhdGVseS5cbi8vIElmIHRoZSBldmVudCB3YXMgYWxyZWFkeSBzY2hlZHVsZWQgYXQgYSBkaWZmZXJlbnQgdGltZSwgaXQgaXMgcmVzY2hlZHVsZWQuXG5FdmVudC5wcm90b3R5cGUuc2NoZWR1bGUgPSBmdW5jdGlvbihkZWFkbGluZSkge1xuICB0aGlzLl9jbGVhcmVkID0gZmFsc2VcbiAgdGhpcy5kZWFkbGluZSA9IGRlYWRsaW5lXG4gIHRoaXMuX3JlZnJlc2hFYXJseUxhdGVEYXRlcygpXG5cbiAgaWYgKHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSA+PSB0aGlzLl9lYXJsaWVzdFRpbWUpIHtcbiAgICB0aGlzLl9leGVjdXRlKClcbiAgXG4gIH0gZWxzZSBpZiAodGhpcy5jbG9jay5faGFzRXZlbnQodGhpcykpIHtcbiAgICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuICAgIHRoaXMuY2xvY2suX2luc2VydEV2ZW50KHRoaXMpXG4gIFxuICB9IGVsc2UgdGhpcy5jbG9jay5faW5zZXJ0RXZlbnQodGhpcylcbn1cblxuRXZlbnQucHJvdG90eXBlLnRpbWVTdHJldGNoID0gZnVuY3Rpb24odFJlZiwgcmF0aW8pIHtcbiAgaWYgKHRoaXMuaXNSZXBlYXRlZCgpKVxuICAgIHRoaXMucmVwZWF0VGltZSA9IHRoaXMucmVwZWF0VGltZSAqIHJhdGlvXG5cbiAgdmFyIGRlYWRsaW5lID0gdFJlZiArIHJhdGlvICogKHRoaXMuZGVhZGxpbmUgLSB0UmVmKVxuICAvLyBJZiB0aGUgZGVhZGxpbmUgaXMgdG9vIGNsb3NlIG9yIHBhc3QsIGFuZCB0aGUgZXZlbnQgaGFzIGEgcmVwZWF0LFxuICAvLyB3ZSBjYWxjdWxhdGUgdGhlIG5leHQgcmVwZWF0IHBvc3NpYmxlIGluIHRoZSBzdHJldGNoZWQgc3BhY2UuXG4gIGlmICh0aGlzLmlzUmVwZWF0ZWQoKSkge1xuICAgIHdoaWxlICh0aGlzLmNsb2NrLmNvbnRleHQuY3VycmVudFRpbWUgPj0gZGVhZGxpbmUgLSB0aGlzLnRvbGVyYW5jZUVhcmx5KVxuICAgICAgZGVhZGxpbmUgKz0gdGhpcy5yZXBlYXRUaW1lXG4gIH1cbiAgdGhpcy5zY2hlZHVsZShkZWFkbGluZSlcbn1cblxuLy8gRXhlY3V0ZXMgdGhlIGV2ZW50XG5FdmVudC5wcm90b3R5cGUuX2V4ZWN1dGUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuY2xvY2suX3N0YXJ0ZWQgPT09IGZhbHNlKSByZXR1cm5cbiAgdGhpcy5jbG9jay5fcmVtb3ZlRXZlbnQodGhpcylcblxuICBpZiAodGhpcy5jbG9jay5jb250ZXh0LmN1cnJlbnRUaW1lIDwgdGhpcy5fbGF0ZXN0VGltZSlcbiAgICB0aGlzLmZ1bmModGhpcylcbiAgZWxzZSB7XG4gICAgaWYgKHRoaXMub25leHBpcmVkKSB0aGlzLm9uZXhwaXJlZCh0aGlzKVxuICAgIGNvbnNvbGUud2FybignZXZlbnQgZXhwaXJlZCcpXG4gIH1cbiAgLy8gSW4gdGhlIGNhc2UgYHNjaGVkdWxlYCBpcyBjYWxsZWQgaW5zaWRlIGBmdW5jYCwgd2UgbmVlZCB0byBhdm9pZFxuICAvLyBvdmVycndyaXRpbmcgd2l0aCB5ZXQgYW5vdGhlciBgc2NoZWR1bGVgLlxuICBpZiAoIXRoaXMuY2xvY2suX2hhc0V2ZW50KHRoaXMpICYmIHRoaXMuaXNSZXBlYXRlZCgpICYmICF0aGlzLl9jbGVhcmVkKVxuICAgIHRoaXMuc2NoZWR1bGUodGhpcy5kZWFkbGluZSArIHRoaXMucmVwZWF0VGltZSkgXG59XG5cbi8vIFVwZGF0ZXMgY2FjaGVkIHRpbWVzXG5FdmVudC5wcm90b3R5cGUuX3JlZnJlc2hFYXJseUxhdGVEYXRlcyA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9sYXRlc3RUaW1lID0gdGhpcy5kZWFkbGluZSArIHRoaXMudG9sZXJhbmNlTGF0ZVxuICB0aGlzLl9lYXJsaWVzdFRpbWUgPSB0aGlzLmRlYWRsaW5lIC0gdGhpcy50b2xlcmFuY2VFYXJseVxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PSBXQUFDbG9jayA9PT09PT09PT09PT09PT09PT09PSAvL1xudmFyIFdBQUNsb2NrID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihjb250ZXh0LCBvcHRzKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBvcHRzID0gb3B0cyB8fCB7fVxuICB0aGlzLnRpY2tNZXRob2QgPSBvcHRzLnRpY2tNZXRob2QgfHwgJ1NjcmlwdFByb2Nlc3Nvck5vZGUnXG4gIHRoaXMudG9sZXJhbmNlRWFybHkgPSBvcHRzLnRvbGVyYW5jZUVhcmx5IHx8IENMT0NLX0RFRkFVTFRTLnRvbGVyYW5jZUVhcmx5XG4gIHRoaXMudG9sZXJhbmNlTGF0ZSA9IG9wdHMudG9sZXJhbmNlTGF0ZSB8fCBDTE9DS19ERUZBVUxUUy50b2xlcmFuY2VMYXRlXG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHRcbiAgdGhpcy5fZXZlbnRzID0gW11cbiAgdGhpcy5fc3RhcnRlZCA9IGZhbHNlXG59XG5cbi8vIC0tLS0tLS0tLS0gUHVibGljIEFQSSAtLS0tLS0tLS0tIC8vXG4vLyBTY2hlZHVsZXMgYGZ1bmNgIHRvIHJ1biBhZnRlciBgZGVsYXlgIHNlY29uZHMuXG5XQUFDbG9jay5wcm90b3R5cGUuc2V0VGltZW91dCA9IGZ1bmN0aW9uKGZ1bmMsIGRlbGF5KSB7XG4gIHJldHVybiB0aGlzLl9jcmVhdGVFdmVudChmdW5jLCB0aGlzLl9hYnNUaW1lKGRlbGF5KSlcbn1cblxuLy8gU2NoZWR1bGVzIGBmdW5jYCB0byBydW4gYmVmb3JlIGBkZWFkbGluZWAuXG5XQUFDbG9jay5wcm90b3R5cGUuY2FsbGJhY2tBdFRpbWUgPSBmdW5jdGlvbihmdW5jLCBkZWFkbGluZSkge1xuICByZXR1cm4gdGhpcy5fY3JlYXRlRXZlbnQoZnVuYywgZGVhZGxpbmUpXG59XG5cbi8vIFN0cmV0Y2hlcyBgZGVhZGxpbmVgIGFuZCBgcmVwZWF0YCBvZiBhbGwgc2NoZWR1bGVkIGBldmVudHNgIGJ5IGByYXRpb2AsIGtlZXBpbmdcbi8vIHRoZWlyIHJlbGF0aXZlIGRpc3RhbmNlIHRvIGB0UmVmYC4gSW4gZmFjdCB0aGlzIGlzIGVxdWl2YWxlbnQgdG8gY2hhbmdpbmcgdGhlIHRlbXBvLlxuV0FBQ2xvY2sucHJvdG90eXBlLnRpbWVTdHJldGNoID0gZnVuY3Rpb24odFJlZiwgZXZlbnRzLCByYXRpbykge1xuICBldmVudHMuZm9yRWFjaChmdW5jdGlvbihldmVudCkgeyBldmVudC50aW1lU3RyZXRjaCh0UmVmLCByYXRpbykgfSlcbiAgcmV0dXJuIGV2ZW50c1xufVxuXG4vLyBSZW1vdmVzIGFsbCBzY2hlZHVsZWQgZXZlbnRzIGFuZCBzdGFydHMgdGhlIGNsb2NrIFxuV0FBQ2xvY2sucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLl9zdGFydGVkID09PSBmYWxzZSkge1xuICAgIHZhciBzZWxmID0gdGhpc1xuICAgIHRoaXMuX3N0YXJ0ZWQgPSB0cnVlXG4gICAgdGhpcy5fZXZlbnRzID0gW11cblxuICAgIGlmICh0aGlzLnRpY2tNZXRob2QgPT09ICdTY3JpcHRQcm9jZXNzb3JOb2RlJykge1xuICAgICAgdmFyIGJ1ZmZlclNpemUgPSAyNTZcbiAgICAgIC8vIFdlIGhhdmUgdG8ga2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgbm9kZSB0byBhdm9pZCBnYXJiYWdlIGNvbGxlY3Rpb25cbiAgICAgIHRoaXMuX2Nsb2NrTm9kZSA9IHRoaXMuY29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IoYnVmZmVyU2l6ZSwgMSwgMSlcbiAgICAgIHRoaXMuX2Nsb2NrTm9kZS5jb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbilcbiAgICAgIHRoaXMuX2Nsb2NrTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbigpIHsgc2VsZi5fdGljaygpIH0pXG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0aGlzLnRpY2tNZXRob2QgPT09ICdtYW51YWwnKSBudWxsIC8vIF90aWNrIGlzIGNhbGxlZCBtYW51YWxseVxuXG4gICAgZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgdGlja01ldGhvZCAnICsgdGhpcy50aWNrTWV0aG9kKVxuICB9XG59XG5cbi8vIFN0b3BzIHRoZSBjbG9ja1xuV0FBQ2xvY2sucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuX3N0YXJ0ZWQgPT09IHRydWUpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2VcbiAgICB0aGlzLl9jbG9ja05vZGUuZGlzY29ubmVjdCgpXG4gIH0gIFxufVxuXG4vLyAtLS0tLS0tLS0tIFByaXZhdGUgLS0tLS0tLS0tLSAvL1xuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIHJhbiBwZXJpb2RpY2FsbHksIGFuZCBhdCBlYWNoIHRpY2sgaXQgZXhlY3V0ZXNcbi8vIGV2ZW50cyBmb3Igd2hpY2ggYGN1cnJlbnRUaW1lYCBpcyBpbmNsdWRlZCBpbiB0aGVpciB0b2xlcmFuY2UgaW50ZXJ2YWwuXG5XQUFDbG9jay5wcm90b3R5cGUuX3RpY2sgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGV2ZW50ID0gdGhpcy5fZXZlbnRzLnNoaWZ0KClcblxuICB3aGlsZShldmVudCAmJiBldmVudC5fZWFybGllc3RUaW1lIDw9IHRoaXMuY29udGV4dC5jdXJyZW50VGltZSkge1xuICAgIGV2ZW50Ll9leGVjdXRlKClcbiAgICBldmVudCA9IHRoaXMuX2V2ZW50cy5zaGlmdCgpXG4gIH1cblxuICAvLyBQdXQgYmFjayB0aGUgbGFzdCBldmVudFxuICBpZihldmVudCkgdGhpcy5fZXZlbnRzLnVuc2hpZnQoZXZlbnQpXG59XG5cbi8vIENyZWF0ZXMgYW4gZXZlbnQgYW5kIGluc2VydCBpdCB0byB0aGUgbGlzdFxuV0FBQ2xvY2sucHJvdG90eXBlLl9jcmVhdGVFdmVudCA9IGZ1bmN0aW9uKGZ1bmMsIGRlYWRsaW5lKSB7XG4gIHJldHVybiBuZXcgRXZlbnQodGhpcywgZGVhZGxpbmUsIGZ1bmMpXG59XG5cbi8vIEluc2VydHMgYW4gZXZlbnQgdG8gdGhlIGxpc3RcbldBQUNsb2NrLnByb3RvdHlwZS5faW5zZXJ0RXZlbnQgPSBmdW5jdGlvbihldmVudCkge1xuICB0aGlzLl9ldmVudHMuc3BsaWNlKHRoaXMuX2luZGV4QnlUaW1lKGV2ZW50Ll9lYXJsaWVzdFRpbWUpLCAwLCBldmVudClcbn1cblxuLy8gUmVtb3ZlcyBhbiBldmVudCBmcm9tIHRoZSBsaXN0XG5XQUFDbG9jay5wcm90b3R5cGUuX3JlbW92ZUV2ZW50ID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgdmFyIGluZCA9IHRoaXMuX2V2ZW50cy5pbmRleE9mKGV2ZW50KVxuICBpZiAoaW5kICE9PSAtMSkgdGhpcy5fZXZlbnRzLnNwbGljZShpbmQsIDEpXG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiBgZXZlbnRgIGlzIGluIHF1ZXVlLCBmYWxzZSBvdGhlcndpc2VcbldBQUNsb2NrLnByb3RvdHlwZS5faGFzRXZlbnQgPSBmdW5jdGlvbihldmVudCkge1xuIHJldHVybiB0aGlzLl9ldmVudHMuaW5kZXhPZihldmVudCkgIT09IC0xXG59XG5cbi8vIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBldmVudCB3aG9zZSBkZWFkbGluZSBpcyA+PSB0byBgZGVhZGxpbmVgXG5XQUFDbG9jay5wcm90b3R5cGUuX2luZGV4QnlUaW1lID0gZnVuY3Rpb24oZGVhZGxpbmUpIHtcbiAgLy8gcGVyZm9ybXMgYSBiaW5hcnkgc2VhcmNoXG4gIHZhciBsb3cgPSAwXG4gICAgLCBoaWdoID0gdGhpcy5fZXZlbnRzLmxlbmd0aFxuICAgICwgbWlkXG4gIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgbWlkID0gTWF0aC5mbG9vcigobG93ICsgaGlnaCkgLyAyKVxuICAgIGlmICh0aGlzLl9ldmVudHNbbWlkXS5fZWFybGllc3RUaW1lIDwgZGVhZGxpbmUpXG4gICAgICBsb3cgPSBtaWQgKyAxXG4gICAgZWxzZSBoaWdoID0gbWlkXG4gIH1cbiAgcmV0dXJuIGxvd1xufVxuXG4vLyBDb252ZXJ0cyBmcm9tIHJlbGF0aXZlIHRpbWUgdG8gYWJzb2x1dGUgdGltZVxuV0FBQ2xvY2sucHJvdG90eXBlLl9hYnNUaW1lID0gZnVuY3Rpb24ocmVsVGltZSkge1xuICByZXR1cm4gcmVsVGltZSArIHRoaXMuY29udGV4dC5jdXJyZW50VGltZVxufVxuXG4vLyBDb252ZXJ0cyBmcm9tIGFic29sdXRlIHRpbWUgdG8gcmVsYXRpdmUgdGltZSBcbldBQUNsb2NrLnByb3RvdHlwZS5fcmVsVGltZSA9IGZ1bmN0aW9uKGFic1RpbWUpIHtcbiAgcmV0dXJuIGFic1RpbWUgLSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWVcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vd2FhY2xvY2svbGliL1dBQUNsb2NrLmpzXG4vLyBtb2R1bGUgaWQgPSA0M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRPbmNlTGlzdGVuZXIgPSBub29wO1xuXG5wcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Byb2Nlc3MvYnJvd3Nlci5qc1xuLy8gbW9kdWxlIGlkID0gNDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBjbG9jayB9IGZyb20gJy4uL21haW4nO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJbnRlcnZhbCB7XG5cbiAgY29uc3RydWN0b3IocmF0ZSxmdW5jLG9uKSB7XG5cbiAgICB0aGlzLnJhdGUgPSByYXRlO1xuICAgIHRoaXMub24gPSBvbjtcbiAgICB0aGlzLmNsb2NrID0gY2xvY2soKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgICB0aGlzLnBhdHRlcm4gPSBbMV07XG4gICAgdGhpcy5pbmRleCA9IDA7XG5cbiAgICB0aGlzLmV2ZW50ID0gZnVuYyA/IGZ1bmMgOiBmdW5jdGlvbigpIHsgfTtcblxuICAgIGlmICh0aGlzLm9uKSB7XG4gICAgICB0aGlzLnN0YXJ0KCk7XG4gICAgfVxuXG4gIH1cblxuICBfZXZlbnQoZSkge1xuICAvLyAgaWYgKHRoaXMucGF0dGVyblt0aGlzLmluZGV4JXRoaXMucGF0dGVybi5sZW5ndGhdKSB7XG4gICAgICB0aGlzLmV2ZW50KGUpO1xuICAvLyAgfVxuICAgIHRoaXMuaW5kZXgrKztcbiAgfVxuXG4gIHN0b3AoKSB7XG4gICAgdGhpcy5vbiA9IGZhbHNlO1xuICAgIHRoaXMuaW50ZXJ2YWwuY2xlYXIoKTtcbiAgfVxuXG4gIHN0YXJ0KCkge1xuICAgIHRoaXMub24gPSB0cnVlO1xuICAgIHRoaXMuaW50ZXJ2YWwgPSB0aGlzLmNsb2NrLmNhbGxiYWNrQXRUaW1lKHRoaXMuX2V2ZW50LmJpbmQodGhpcyksIHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSkucmVwZWF0KHRoaXMucmF0ZS8xMDAwKS50b2xlcmFuY2Uoe2Vhcmx5OiAwLjEsIGxhdGU6MX0pO1xuICB9XG5cbiAgbXMobmV3cmF0ZSkge1xuICAgIGlmICh0aGlzLm9uKSB7XG4gICAgICB2YXIgcmF0aW8gPSBuZXdyYXRlL3RoaXMucmF0ZTtcbiAgICAgIHRoaXMucmF0ZSA9IG5ld3JhdGU7XG4gICAgICB0aGlzLmNsb2NrLnRpbWVTdHJldGNoKHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSwgW3RoaXMuaW50ZXJ2YWxdLCByYXRpbyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmF0ZSA9IG5ld3JhdGU7XG4gICAgfVxuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi90aW1lL2ludGVydmFsLmpzIl0sInNvdXJjZVJvb3QiOiIifQ==\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/nexusui/dist/NexusUI.js\n// module id = 75\n// module chunks = 0","'use strict';\n\nvar _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');\n\nvar _slicedToArray3 = _interopRequireDefault(_slicedToArray2);\n\nvar _toArray2 = require('babel-runtime/helpers/toArray');\n\nvar _toArray3 = _interopRequireDefault(_toArray2);\n\nvar _tone = require('tone');\n\nvar _tone2 = _interopRequireDefault(_tone);\n\nvar _nexusui = require('nexusui');\n\nvar _nexusui2 = _interopRequireDefault(_nexusui);\n\nvar _keys = require('./lib/keys');\n\nvar _keys2 = _interopRequireDefault(_keys);\n\nvar _scales = require('./lib/scales');\n\nvar _scales2 = _interopRequireDefault(_scales);\n\nvar _kalimba = require('./lib/kalimba');\n\nvar _kalimba2 = _interopRequireDefault(_kalimba);\n\nvar _midi = require('./lib/midi');\n\nvar _util = require('./lib/util');\n\nvar _ui = require('./lib/ui');\n\nvar _data = require('./data');\n\nvar data = _interopRequireWildcard(_data);\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar DEFAULT_BPM = 60;\n\nvar recorder = null;\nvar recording = false;\n\n(0, _midi.midi_init)();\n\n/* initialization */\n\nvar mass_fields = [\"date\", \"timestamp\", \"fatalities\", \"injured\", \"total_victims\", \"age\", \"case\", \"weapon_type\", \"weapon_details\"].reduce(function (a, b, i) {\n a[b] = i;\n return a;\n}, {});\n\nvar i = 0,\n mass_i = 0,\n datasets = {},\n dataset = {},\n bounds = {},\n diff = [];\nvar play_fn = _midi.play_sequence;\ndata.load().then(function (lists) {\n console.log(lists);\n (0, _util.transpose)(lists.gun_violence_by_month.lines).forEach(function (row, i) {\n var name = lists.gun_violence_by_month.h[i];\n if (name === 'Date') return;\n console.log(name, row);\n datasets[name] = {\n name: name,\n h: [name],\n lines: [row.map(function (n) {\n return parseInt(n);\n })],\n play_fn: _midi.play_sequence\n };\n });\n datasets[\"Mass Shootings\"] = lists.mass_shootings_lite;\n datasets[\"Mass Shootings\"].name = \"Mass Shootings\";\n datasets[\"Mass Shootings\"].play_fn = play_mass_shootings;\n var lines = datasets[\"Mass Shootings\"].lines.reverse();\n\n var _lines$0$mass_fields$ = lines[0][mass_fields.date].split('/'),\n _lines$0$mass_fields$2 = (0, _toArray3.default)(_lines$0$mass_fields$),\n min_y = _lines$0$mass_fields$2[0],\n rest = _lines$0$mass_fields$2.slice(1);\n\n datasets[\"Mass Shootings\"].dates = lines.map(function (row) {\n var _row$mass_fields$date = row[mass_fields.date].split('/'),\n _row$mass_fields$date2 = (0, _slicedToArray3.default)(_row$mass_fields$date, 3),\n y = _row$mass_fields$date2[0],\n m = _row$mass_fields$date2[1],\n d = _row$mass_fields$date2[2];\n\n return (parseInt(y) - parseInt(min_y)) * 12 + parseInt(m);\n });\n datasets[\"Mass Shootings\"].data = lines;\n datasets[\"Mass Shootings\"].lines = [lines.map(function (row) {\n return row[mass_fields.total_victims];\n })];\n (0, _util.requestAudioContext)(ready);\n});\n\n/* play function for mass shooting data w/ custom timing */\n\nvar mass_rest = 0;\n\n// export const note_values = [\n// [8, '8 measures', 8 * 512],\n// [4, '4 measures', 4 * 512],\n// [2, '2 measures', 2 * 512],\n// [1, 'whole note', 512],\n// [1/2, 'half note', 256],\n// [1/3, 'third note', [170, 170, 171]],\n// [1/4, 'quarter note', 128],\n// [1/5, 'fifth note', [51,51,51,51,52]],\n// [1/6, 'sixth note', [85, 85, 86, 85, 85, 86]],\n// [1/8, 'eighth note', 64],\n// [1/10, 'tenth note', [25,26,26,25,26,25,26,26,25,26]],\n// [1/12, 'twelfth note', [21,21,22, 21,21,22, 21,21,22, 21,21,22]],\n// [1/16, 'sixteenth note', 32],\n// [1/32, 'thirtysecond note', 16],\n// ]\n\nfunction play_mass_shootings(i, bounds, diff, note_time) {\n var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : \"all\";\n var exporting = arguments[5];\n var rows = bounds.rows,\n min = bounds.min,\n max = bounds.max;\n\n var y = 0;\n var x = i % rows[0].length;\n var n = rows[y][x];\n var total = dataset.dates.length;\n var notes = [],\n midi_notes = [],\n cases = [],\n timings = void 0;\n console.log(i, mass_i, dataset.dates[mass_i]);\n while (i >= dataset.dates[mass_i] && mass_i < total) {\n notes.push(dataset.lines[0][mass_i]);\n cases.push(dataset.data[mass_i][mass_fields.date] + ' ' + dataset.data[mass_i][mass_fields.case] + \", \" + dataset.data[mass_i][mass_fields.fatalities] + ' dead, ' + dataset.data[mass_i][mass_fields.injured] + ' injured');\n console.log('push case', dataset.data[mass_i][mass_fields.date] + ' ' + dataset.data[mass_i][mass_fields.case]);\n mass_i += 1;\n }\n switch (notes.length) {\n default:\n case 0:\n mass_rest += 1;\n break;\n case 1:\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 128, channel, exporting, mass_rest, 0));\n timings = [128];\n break;\n case 2:\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 64, channel, exporting, mass_rest, 0));\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[1], min, max) * _ui.nx.multiply.value, 64, channel, exporting, 0, 64));\n timings = [64, 64];\n break;\n case 3:\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 43, channel, exporting, mass_rest));\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[1], min, max) * _ui.nx.multiply.value, 43, channel, exporting, 0, 43));\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[2], min, max) * _ui.nx.multiply.value, 42, channel, exporting, 0, 85));\n timings = [43, 43, 42];\n break;\n case 4:\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 32, channel, exporting, mass_rest));\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[1], min, max) * _ui.nx.multiply.value, 32, channel, exporting, 0, 32));\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[2], min, max) * _ui.nx.multiply.value, 32, channel, exporting, 0, 64));\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[3], min, max) * _ui.nx.multiply.value, 32, channel, exporting, 0, 96));\n timings = [32, 32, 32, 32];\n break;\n }\n if (cases.length) {\n document.querySelector('#cases').innerHTML = cases.join('<br>');\n }\n if (total <= mass_i) {\n mass_rest = 0;\n mass_i = 0;\n i = 0;\n } else {\n i += 1;\n }\n _kalimba2.default.play(220, -12);\n if (notes.length) {\n mass_rest = 0;\n return [i, midi_notes, timings, mass_rest];\n }\n mass_rest += 128;\n return [i, [], [], 0];\n}\n\n/* play next note according to sonification */\n\nfunction play_next() {\n var note_time = 120000 / _tone2.default.Transport.bpm.value * _midi.note_values[_ui.nx.timing.active][0];\n setTimeout(play_next, note_time);\n\n var _play_fn = play_fn(i, bounds, diff, note_time),\n _play_fn2 = (0, _slicedToArray3.default)(_play_fn, 3),\n new_i = _play_fn2[0],\n notes = _play_fn2[1],\n timings = _play_fn2[2];\n\n i = new_i;\n if (recording) {\n var timing = _midi.note_values[_ui.nx.timing.active][2];\n if (timing.length) timing = timing[i % timing.length];\n recorder.addEvent(new _midi.MidiWriter.NoteEvent({ pitch: notes, duration: 't' + timing }));\n }\n}\n\n/* bind selects */\n\nfunction pick_dataset(key) {\n console.log('pick dataset:', key, datasets[key]);\n i = 0;\n mass_i = 0;\n mass_rest = 0;\n dataset = datasets[key];\n bounds = (0, _util.get_bounds)(dataset);\n diff = (0, _util.get_diff_bounds)(bounds.rows);\n play_fn = dataset.play_fn;\n}\n\n/* build and bind the UI */\n\nfunction ready() {\n _scales2.default.build_options(document.querySelector('#scale'));\n (0, _ui.build_options)(document.querySelector('#dataset'), datasets, pick_dataset);\n\n var dial_size = [50, 50];\n\n _tone2.default.Transport.bpm.value = DEFAULT_BPM;\n _ui.nx.tempo = new _nexusui2.default.Dial('#tempo', {\n size: dial_size,\n min: 10,\n max: 300,\n step: 1,\n value: DEFAULT_BPM\n });\n (0, _ui.update_value_on_change)(_ui.nx.tempo, '#tempo', true, function (v) {\n return _tone2.default.Transport.bpm.value = v;\n });\n\n _ui.nx.timing = new _nexusui2.default.RadioButton('#timing', {\n size: [400, 25],\n numberOfButtons: _midi.note_values.length,\n active: 6\n });\n (0, _ui.update_radio_value_on_change)(_ui.nx.timing, '#timing', _midi.note_values);\n\n _ui.nx.duration = new _nexusui2.default.Dial('#duration', {\n size: dial_size,\n min: 0,\n max: 2,\n step: 0.01,\n value: 0.8\n });\n (0, _ui.update_value_on_change)(_ui.nx.duration, '#duration', false);\n\n _ui.nx.offset = new _nexusui2.default.Dial('#offset', {\n size: dial_size,\n min: -24,\n max: 24,\n step: 1,\n value: -5\n });\n (0, _ui.update_value_on_change)(_ui.nx.offset, '#offset', true);\n\n _ui.nx.octave = new _nexusui2.default.Dial('#octave', {\n size: dial_size,\n min: -4,\n max: 4,\n step: 1,\n value: 0\n });\n (0, _ui.update_value_on_change)(_ui.nx.octave, '#octave', true);\n\n _ui.nx.multiply = new _nexusui2.default.Dial('#multiply', {\n size: dial_size,\n min: -64,\n max: 64,\n step: 1,\n value: 17\n });\n (0, _ui.update_value_on_change)(_ui.nx.multiply, '#multiply', true);\n\n _ui.nx.interval = new _nexusui2.default.Dial('#interval', {\n size: dial_size,\n min: -64,\n max: 64,\n step: 1,\n value: 10\n });\n (0, _ui.update_value_on_change)(_ui.nx.interval, '#interval', true);\n\n var export_midi_button = document.querySelector('#export_midi');\n export_midi_button.addEventListener('click', function () {\n (0, _midi.export_pattern_as_midi)(dataset.name, bounds, diff, _ui.nx.tempo.value, _ui.nx.timing.active, play_fn);\n });\n\n var record_midi_button = document.querySelector('#record_midi');\n record_midi_button.addEventListener('click', function () {\n if (recording) {\n record_midi_button.innerHTML = 'Record MIDI';\n document.body.classList.remove('recording');\n recording = false;\n var writer = new _midi.MidiWriter.Writer([recorder]);\n var blob = (0, _util.dataURItoBlob)(writer.dataUri());\n saveAs(blob, 'Recording - ' + dataset.name + '.mid');\n } else {\n record_midi_button.innerHTML = 'Save Recording';\n document.body.classList.add('recording');\n recording = true;\n recorder = new _midi.MidiWriter.Track();\n recorder.setTempo(_ui.nx.tempo.value);\n }\n });\n\n document.querySelector('.loading').classList.remove('loading');\n\n document.querySelector('#dataset').value = 'Mass Shootings';\n pick_dataset('Mass Shootings');\n\n document.querySelector('#scale').value = '14';\n _scales2.default.pick(14);\n\n play_next();\n}\n\n/* keys */\n\n_keys2.default.listen(function (index) {\n _ui.nx.offset.value = index;\n _ui.nx.offset.update(index);\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/index.js\n// module id = 76\n// module chunks = 0","\"use strict\";\n\nvar _assign = require(\"babel-runtime/core-js/object/assign\");\n\nvar _assign2 = _interopRequireDefault(_assign);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nmodule.exports = function () {\n var Intonation = function Intonation(opt) {\n opt = this.opt = (0, _assign2.default)({\n name: \"\",\n root: 440,\n octave: 0,\n interval: 2,\n tet: 0,\n intervals: null\n }, opt || {});\n this.generate();\n };\n Intonation.prototype.generate = function (opt) {\n opt = (0, _assign2.default)(this.opt, opt || {});\n if (opt.scl) {\n this.generate_scl();\n } else if (opt.tet) {\n this.generate_tet();\n } else if (opt.intervals) {\n this.generate_intervals();\n }\n };\n Intonation.prototype.generate_intervals = function () {\n var root = this.opt.root;\n var interval_list = this.opt.intervals;\n if (typeof interval_list == \"string\") {\n interval_list = interval_list.split(\" \");\n }\n this.name = this.opt.name || \"interval list\";\n this.intervals = interval_list;\n this.interval = this.opt.interval = parseInterval.call(this, interval_list.pop());\n this.scale = interval_list.map(parseIntervalString.bind(this)).filter(function (v) {\n return !!v;\n });\n };\n Intonation.prototype.generate_tet = function () {\n var scale = this.scale = [];\n var root = this.opt.root;\n var tet = this.opt.tet;\n var interval = this.interval = this.opt.interval;\n var ratio = Math.pow(interval, 1 / tet);\n var n = root;\n scale.push(n);\n for (var i = 0; i < tet - 1; i++) {\n n *= ratio;\n scale.push(n);\n }\n this.name = this.opt.name || tet + \"-tone equal temperament\";\n this.intervals = null;\n };\n Intonation.prototype.generate_scl = function () {\n var root = this.opt.root;\n var scl = this.parse_scl(this.opt.scl);\n this.intervals = scl.notes;\n this.interval = scl.notes.pop();\n this.name = this.opt.name || scl.description;\n this.scale = scl.notes.map(function (v) {\n return v * root;\n });\n };\n Intonation.prototype.parse_scl = function (s) {\n var scl = {};\n scl.comments = [];\n scl.notes = [];\n s.trim().split(\"\\n\").forEach(function (line) {\n // Lines beginning with an exclamation mark are regarded as comments\n // and are to be ignored.\n if (line.indexOf(\"!\") !== -1) {\n scl.comments.push(line);\n }\n // The first (non comment) line contains a short description of the scale.\n // If there is no description, there should be an empty line. (nb: which is falsey)\n else if (!('description' in scl)) {\n scl.description = line;\n }\n // The second line contains the number of notes.\n // The first note of 1/1 or 0.0 cents is implicit and not in the files.\n else if (!scl.notes.length) {\n scl.notes.push(1);\n } else {\n // If the value contains a period, it is a cents value, otherwise a ratio.\n var note = line.replace(/^[^-\\.0-9]+/, \"\").replace(/[^-\\/\\.0-9]+$/, \"\");\n if (note.indexOf(\".\") !== -1) {\n note = Math.pow(2, parseFloat(note) / 1200);\n } else {\n note = parseInterval(note);\n }\n if (note) {\n scl.notes.push(note);\n }\n }\n });\n return scl;\n };\n Intonation.prototype.index = function (i, octave) {\n octave = octave || this.opt.octave;\n var f = this.scale[mod(i, this.scale.length) | 0];\n var pow = Math.floor(norm(i, 0, this.scale.length)) + octave;\n f *= Math.pow(this.interval, pow);\n return f;\n };\n Intonation.prototype.range = function (min, max) {\n var a = [];\n for (var i = min; i < max; i++) {\n a.push(this.index(i));\n }\n return a;\n };\n Intonation.prototype.set_root = function (f) {\n this.opt.root = f;\n this.generate();\n };\n Intonation.prototype.quantize_frequency = function (f) {\n if (f == 0) return 0;\n var scale_f = f;\n var pow = 0;\n var interval = this.interval;\n var scale = this.scale;\n while (scale_f < root) {\n scale_f *= interval;\n pow -= 1;\n }\n while (scale_f > root * interval) {\n scale_f /= interval;\n pow += 1;\n }\n for (var i = 0; i < scale.length; i++) {\n if (scale_f > scale[i]) continue;\n scale_f = scale[i];\n break;\n }\n scale_f *= Math.pow(2, pow);\n return scale_f;\n };\n Intonation.prototype.quantize_index = function (i) {\n return mod(index - 1, this.scale.length) | 0;\n };\n var parseInterval = Intonation.prototype.parse_interval = function (s) {\n if (typeof s == \"number\") return s;\n if (!s.indexOf(\"/\") == -1) return parseInt(s);\n var pp = s.split(\"/\");\n var num = parseInt(pp[0]);\n var den = parseInt(pp[1]);\n if (isNaN(num)) return 1;\n if (isNaN(den) || den == 0) return num;\n if (num == den) return 1;\n return num / den;\n };\n var parseIntervalString = Intonation.prototype.parse_interval_string = function (s) {\n if (s.indexOf(\"/\") !== -1) return parseInterval(s) * this.opt.root; // intervals\n if (s.indexOf(\"f\") !== -1) return parseFloat(s); // pure frequencies\n return parseFloat(s);\n };\n function norm(n, a, b) {\n return (n - a) / (b - a);\n }\n function mod(n, m) {\n return n - m * Math.floor(n / m);\n }\n\n return Intonation;\n}();\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/intonation.js\n// module id = 77\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _tone = require('tone');\n\nvar _tone2 = _interopRequireDefault(_tone);\n\nvar _util = require('./util');\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar player_count = 2;\nvar sample_index = 0;\n\nvar compressor = new _tone2.default.Compressor(-30, 3).toMaster();\n\nvar samples = [{ root: 226, fn: 'samples/380737__cabled-mess__sansula-01-a-raw.mp3' }, { root: 267, fn: 'samples/380736__cabled-mess__sansula-02-c-raw.mp3' }, { root: 340, fn: 'samples/380735__cabled-mess__sansula-03-e-raw.mp3' }, { root: 452, fn: 'samples/380733__cabled-mess__sansula-06-a-02-raw.mp3' }];\n\nsamples.forEach(function (sample) {\n sample.players = [];\n sample.index = -1;\n for (var i = 0; i < player_count; i++) {\n var fn = sample.fn;\n if (window.location.href.match(/asdf.us/)) {\n fn = '//asdf.us/kalimba/' + fn;\n }\n var player = new _tone2.default.Player({\n url: fn,\n retrigger: true,\n playbackRate: 1\n });\n player.connect(compressor);\n sample.players.push(player);\n }\n});\n\nfunction play(freq) {\n var volume = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.0;\n\n var best = { sample: samples[sample_index] };\n sample_index = (sample_index + 1) % samples.length;\n best.sample.index = (best.sample.index + 1) % player_count;\n\n var player = best.sample.players[best.sample.index];\n player.playbackRate = freq / best.sample.root;\n // console.log(player)\n player.volume.value = volume;\n setTimeout(function () {\n player.start();\n }, 0);\n}\n\nexports.default = { play: play };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/kalimba.js\n// module id = 78\n// module chunks = 0","\"use strict\";\n\nvar _typeof2 = require(\"babel-runtime/helpers/typeof\");\n\nvar _typeof3 = _interopRequireDefault(_typeof2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * StartAudioContext.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2016 Yotam Mann\n */\n(function (root, factory) {\n if (typeof define === \"function\" && define.amd) {\n define([], factory);\n } else if ((typeof module === \"undefined\" ? \"undefined\" : (0, _typeof3.default)(module)) === 'object' && module.exports) {\n module.exports = factory();\n } else {\n root.StartAudioContext = factory();\n }\n})(undefined, function () {\n\n /**\n * The StartAudioContext object\n */\n var StartAudioContext = {\n /**\n * The audio context passed in by the user\n * @type {AudioContext}\n */\n context: null,\n /**\n * The TapListeners bound to the elements\n * @type {Array}\n * @private\n */\n _tapListeners: [],\n /**\n * Callbacks to invoke when the audio context is started\n * @type {Array}\n * @private\n */\n _onStarted: []\n };\n\n /**\n * Set the context\n * @param {AudioContext} ctx\n * @returns {StartAudioContext}\n */\n StartAudioContext.setContext = function (ctx) {\n StartAudioContext.context = ctx;\n return StartAudioContext;\n };\n\n /**\n * Add a tap listener to the audio context\n * @param {Array|Element|String|jQuery} element\n * @returns {StartAudioContext}\n */\n StartAudioContext.on = function (element) {\n if (Array.isArray(element) || NodeList && element instanceof NodeList) {\n for (var i = 0; i < element.length; i++) {\n StartAudioContext.on(element[i]);\n }\n } else if (typeof element === \"string\") {\n StartAudioContext.on(document.querySelectorAll(element));\n } else if (element.jquery && typeof element.toArray === \"function\") {\n StartAudioContext.on(element.toArray());\n } else if (Element && element instanceof Element) {\n //if it's an element, create a TapListener\n var tap = new TapListener(element, onTap);\n StartAudioContext._tapListeners.push(tap);\n }\n return StartAudioContext;\n };\n\n /**\n * Bind a callback to when the audio context is started. \n * @param {Function} cb\n * @return {StartAudioContext}\n */\n StartAudioContext.onStarted = function (cb) {\n //if it's already started, invoke the callback\n if (StartAudioContext.isStarted()) {\n cb();\n } else {\n StartAudioContext._onStarted.push(cb);\n }\n return StartAudioContext;\n };\n\n /**\n * returns true if the context is started\n * @return {Boolean}\n */\n StartAudioContext.isStarted = function () {\n return StartAudioContext.context !== null && StartAudioContext.context.state === \"running\";\n };\n\n /**\n * @class Listens for non-dragging tap ends on the given element\n * @param {Element} element\n * @internal\n */\n var TapListener = function TapListener(element) {\n\n this._dragged = false;\n\n this._element = element;\n\n this._bindedMove = this._moved.bind(this);\n this._bindedEnd = this._ended.bind(this);\n\n element.addEventListener(\"touchmove\", this._bindedMove);\n element.addEventListener(\"touchend\", this._bindedEnd);\n element.addEventListener(\"mouseup\", this._bindedEnd);\n };\n\n /**\n * drag move event\n */\n TapListener.prototype._moved = function (e) {\n this._dragged = true;\n };\n\n /**\n * tap ended listener\n */\n TapListener.prototype._ended = function (e) {\n if (!this._dragged) {\n onTap();\n }\n this._dragged = false;\n };\n\n /**\n * remove all the bound events\n */\n TapListener.prototype.dispose = function () {\n this._element.removeEventListener(\"touchmove\", this._bindedMove);\n this._element.removeEventListener(\"touchend\", this._bindedEnd);\n this._element.removeEventListener(\"mouseup\", this._bindedEnd);\n this._bindedMove = null;\n this._bindedEnd = null;\n this._element = null;\n };\n\n /**\n * Invoked the first time of the elements is tapped.\n * Creates a silent oscillator when a non-dragging touchend \n * event has been triggered.\n */\n function onTap() {\n //start the audio context with a silent oscillator\n if (StartAudioContext.context && !StartAudioContext.isStarted()) {\n var osc = StartAudioContext.context.createOscillator();\n var silent = StartAudioContext.context.createGain();\n silent.gain.value = 0;\n osc.connect(silent);\n silent.connect(StartAudioContext.context.destination);\n var now = StartAudioContext.context.currentTime;\n osc.start(now);\n osc.stop(now + 0.5);\n }\n\n //dispose all the tap listeners\n if (StartAudioContext._tapListeners) {\n for (var i = 0; i < StartAudioContext._tapListeners.length; i++) {\n StartAudioContext._tapListeners[i].dispose();\n }\n StartAudioContext._tapListeners = null;\n }\n //the onstarted callbacks\n if (StartAudioContext._onStarted) {\n for (var j = 0; j < StartAudioContext._onStarted.length; j++) {\n StartAudioContext._onStarted[j]();\n }\n StartAudioContext._onStarted = null;\n }\n }\n\n return StartAudioContext;\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/startAudioContext.js\n// module id = 79\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/get-iterator\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/babel-runtime/core-js/get-iterator.js\n// module id = 80\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/is-iterable\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/babel-runtime/core-js/is-iterable.js\n// module id = 81\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/math/log2\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/babel-runtime/core-js/math/log2.js\n// module id = 82\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/object/keys\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/babel-runtime/core-js/object/keys.js\n// module id = 83\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/promise\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/babel-runtime/core-js/promise.js\n// module id = 84\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/symbol\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/babel-runtime/core-js/symbol.js\n// module id = 85\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/symbol/iterator\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/babel-runtime/core-js/symbol/iterator.js\n// module id = 86\n// module chunks = 0","\"use strict\";\n\nexports.__esModule = true;\n\nvar _iterator = require(\"../core-js/symbol/iterator\");\n\nvar _iterator2 = _interopRequireDefault(_iterator);\n\nvar _symbol = require(\"../core-js/symbol\");\n\nvar _symbol2 = _interopRequireDefault(_symbol);\n\nvar _typeof = typeof _symbol2.default === \"function\" && typeof _iterator2.default === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof _symbol2.default === \"function\" && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? \"symbol\" : typeof obj; };\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nexports.default = typeof _symbol2.default === \"function\" && _typeof(_iterator2.default) === \"symbol\" ? function (obj) {\n return typeof obj === \"undefined\" ? \"undefined\" : _typeof(obj);\n} : function (obj) {\n return obj && typeof _symbol2.default === \"function\" && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? \"symbol\" : typeof obj === \"undefined\" ? \"undefined\" : _typeof(obj);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/babel-runtime/helpers/typeof.js\n// module id = 87\n// module chunks = 0","'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction placeHoldersCount (b64) {\n var len = b64.length\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // the number of equal signs (place holders)\n // if there are two placeholders, than the two characters before it\n // represent one byte\n // if there is only one, then the three characters before it represent 2 bytes\n // this is just a cheap hack to not do indexOf twice\n return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0\n}\n\nfunction byteLength (b64) {\n // base64 is 4/3 + up to two characters of the original data\n return b64.length * 3 / 4 - placeHoldersCount(b64)\n}\n\nfunction toByteArray (b64) {\n var i, j, l, tmp, placeHolders, arr\n var len = b64.length\n placeHolders = placeHoldersCount(b64)\n\n arr = new Arr(len * 3 / 4 - placeHolders)\n\n // if there are placeholders, only get up to the last complete 4 chars\n l = placeHolders > 0 ? len - 4 : len\n\n var L = 0\n\n for (i = 0, j = 0; i < l; i += 4, j += 3) {\n tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]\n arr[L++] = (tmp >> 16) & 0xFF\n arr[L++] = (tmp >> 8) & 0xFF\n arr[L++] = tmp & 0xFF\n }\n\n if (placeHolders === 2) {\n tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[L++] = tmp & 0xFF\n } else if (placeHolders === 1) {\n tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[L++] = (tmp >> 8) & 0xFF\n arr[L++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var output = ''\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n output += lookup[tmp >> 2]\n output += lookup[(tmp << 4) & 0x3F]\n output += '=='\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + (uint8[len - 1])\n output += lookup[tmp >> 10]\n output += lookup[(tmp >> 4) & 0x3F]\n output += lookup[(tmp << 2) & 0x3F]\n output += '='\n }\n\n parts.push(output)\n\n return parts.join('')\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/base64-js/index.js\n// module id = 88\n// module chunks = 0","require('../modules/web.dom.iterable');\nrequire('../modules/es6.string.iterator');\nmodule.exports = require('../modules/core.get-iterator');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/fn/get-iterator.js\n// module id = 89\n// module chunks = 0","require('../modules/web.dom.iterable');\nrequire('../modules/es6.string.iterator');\nmodule.exports = require('../modules/core.is-iterable');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/fn/is-iterable.js\n// module id = 90\n// module chunks = 0","require('../../modules/es6.math.log2');\nmodule.exports = require('../../modules/_core').Math.log2;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/fn/math/log2.js\n// module id = 91\n// module chunks = 0","require('../../modules/es6.object.assign');\nmodule.exports = require('../../modules/_core').Object.assign;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/fn/object/assign.js\n// module id = 92\n// module chunks = 0","require('../../modules/es6.object.keys');\nmodule.exports = require('../../modules/_core').Object.keys;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/fn/object/keys.js\n// module id = 93\n// module chunks = 0","require('../modules/es6.object.to-string');\nrequire('../modules/es6.string.iterator');\nrequire('../modules/web.dom.iterable');\nrequire('../modules/es6.promise');\nmodule.exports = require('../modules/_core').Promise;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/fn/promise.js\n// module id = 94\n// module chunks = 0","require('../../modules/es6.symbol');\nrequire('../../modules/es6.object.to-string');\nrequire('../../modules/es7.symbol.async-iterator');\nrequire('../../modules/es7.symbol.observable');\nmodule.exports = require('../../modules/_core').Symbol;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/fn/symbol/index.js\n// module id = 95\n// module chunks = 0","require('../../modules/es6.string.iterator');\nrequire('../../modules/web.dom.iterable');\nmodule.exports = require('../../modules/_wks-ext').f('iterator');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/fn/symbol/iterator.js\n// module id = 96\n// module chunks = 0","module.exports = function(){ /* empty */ };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_add-to-unscopables.js\n// module id = 97\n// module chunks = 0","module.exports = function(it, Constructor, name, forbiddenField){\n if(!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)){\n throw TypeError(name + ': incorrect invocation!');\n } return it;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_an-instance.js\n// module id = 98\n// module chunks = 0","// false -> Array#indexOf\n// true -> Array#includes\nvar toIObject = require('./_to-iobject')\n , toLength = require('./_to-length')\n , toIndex = require('./_to-index');\nmodule.exports = function(IS_INCLUDES){\n return function($this, el, fromIndex){\n var O = toIObject($this)\n , length = toLength(O.length)\n , index = toIndex(fromIndex, length)\n , value;\n // Array#includes uses SameValueZero equality algorithm\n if(IS_INCLUDES && el != el)while(length > index){\n value = O[index++];\n if(value != value)return true;\n // Array#toIndex ignores holes, Array#includes - not\n } else for(;length > index; index++)if(IS_INCLUDES || index in O){\n if(O[index] === el)return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_array-includes.js\n// module id = 99\n// module chunks = 0","// all enumerable object keys, includes symbols\nvar getKeys = require('./_object-keys')\n , gOPS = require('./_object-gops')\n , pIE = require('./_object-pie');\nmodule.exports = function(it){\n var result = getKeys(it)\n , getSymbols = gOPS.f;\n if(getSymbols){\n var symbols = getSymbols(it)\n , isEnum = pIE.f\n , i = 0\n , key;\n while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))result.push(key);\n } return result;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_enum-keys.js\n// module id = 100\n// module chunks = 0","var ctx = require('./_ctx')\n , call = require('./_iter-call')\n , isArrayIter = require('./_is-array-iter')\n , anObject = require('./_an-object')\n , toLength = require('./_to-length')\n , getIterFn = require('./core.get-iterator-method')\n , BREAK = {}\n , RETURN = {};\nvar exports = module.exports = function(iterable, entries, fn, that, ITERATOR){\n var iterFn = ITERATOR ? function(){ return iterable; } : getIterFn(iterable)\n , f = ctx(fn, that, entries ? 2 : 1)\n , index = 0\n , length, step, iterator, result;\n if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!');\n // fast case for arrays with default iterator\n if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){\n result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);\n if(result === BREAK || result === RETURN)return result;\n } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){\n result = call(iterator, f, step.value, entries);\n if(result === BREAK || result === RETURN)return result;\n }\n};\nexports.BREAK = BREAK;\nexports.RETURN = RETURN;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_for-of.js\n// module id = 101\n// module chunks = 0","// fast apply, http://jsperf.lnkit.com/fast-apply/5\nmodule.exports = function(fn, args, that){\n var un = that === undefined;\n switch(args.length){\n case 0: return un ? fn()\n : fn.call(that);\n case 1: return un ? fn(args[0])\n : fn.call(that, args[0]);\n case 2: return un ? fn(args[0], args[1])\n : fn.call(that, args[0], args[1]);\n case 3: return un ? fn(args[0], args[1], args[2])\n : fn.call(that, args[0], args[1], args[2]);\n case 4: return un ? fn(args[0], args[1], args[2], args[3])\n : fn.call(that, args[0], args[1], args[2], args[3]);\n } return fn.apply(that, args);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_invoke.js\n// module id = 102\n// module chunks = 0","// check on default Array iterator\nvar Iterators = require('./_iterators')\n , ITERATOR = require('./_wks')('iterator')\n , ArrayProto = Array.prototype;\n\nmodule.exports = function(it){\n return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_is-array-iter.js\n// module id = 103\n// module chunks = 0","// 7.2.2 IsArray(argument)\nvar cof = require('./_cof');\nmodule.exports = Array.isArray || function isArray(arg){\n return cof(arg) == 'Array';\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_is-array.js\n// module id = 104\n// module chunks = 0","// call something on iterator step with safe closing on error\nvar anObject = require('./_an-object');\nmodule.exports = function(iterator, fn, value, entries){\n try {\n return entries ? fn(anObject(value)[0], value[1]) : fn(value);\n // 7.4.6 IteratorClose(iterator, completion)\n } catch(e){\n var ret = iterator['return'];\n if(ret !== undefined)anObject(ret.call(iterator));\n throw e;\n }\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_iter-call.js\n// module id = 105\n// module chunks = 0","'use strict';\nvar create = require('./_object-create')\n , descriptor = require('./_property-desc')\n , setToStringTag = require('./_set-to-string-tag')\n , IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\nrequire('./_hide')(IteratorPrototype, require('./_wks')('iterator'), function(){ return this; });\n\nmodule.exports = function(Constructor, NAME, next){\n Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)});\n setToStringTag(Constructor, NAME + ' Iterator');\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_iter-create.js\n// module id = 106\n// module chunks = 0","var ITERATOR = require('./_wks')('iterator')\n , SAFE_CLOSING = false;\n\ntry {\n var riter = [7][ITERATOR]();\n riter['return'] = function(){ SAFE_CLOSING = true; };\n Array.from(riter, function(){ throw 2; });\n} catch(e){ /* empty */ }\n\nmodule.exports = function(exec, skipClosing){\n if(!skipClosing && !SAFE_CLOSING)return false;\n var safe = false;\n try {\n var arr = [7]\n , iter = arr[ITERATOR]();\n iter.next = function(){ return {done: safe = true}; };\n arr[ITERATOR] = function(){ return iter; };\n exec(arr);\n } catch(e){ /* empty */ }\n return safe;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_iter-detect.js\n// module id = 107\n// module chunks = 0","module.exports = function(done, value){\n return {value: value, done: !!done};\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_iter-step.js\n// module id = 108\n// module chunks = 0","var getKeys = require('./_object-keys')\n , toIObject = require('./_to-iobject');\nmodule.exports = function(object, el){\n var O = toIObject(object)\n , keys = getKeys(O)\n , length = keys.length\n , index = 0\n , key;\n while(length > index)if(O[key = keys[index++]] === el)return key;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_keyof.js\n// module id = 109\n// module chunks = 0","var META = require('./_uid')('meta')\n , isObject = require('./_is-object')\n , has = require('./_has')\n , setDesc = require('./_object-dp').f\n , id = 0;\nvar isExtensible = Object.isExtensible || function(){\n return true;\n};\nvar FREEZE = !require('./_fails')(function(){\n return isExtensible(Object.preventExtensions({}));\n});\nvar setMeta = function(it){\n setDesc(it, META, {value: {\n i: 'O' + ++id, // object ID\n w: {} // weak collections IDs\n }});\n};\nvar fastKey = function(it, create){\n // return primitive with prefix\n if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;\n if(!has(it, META)){\n // can't set metadata to uncaught frozen object\n if(!isExtensible(it))return 'F';\n // not necessary to add metadata\n if(!create)return 'E';\n // add missing metadata\n setMeta(it);\n // return object ID\n } return it[META].i;\n};\nvar getWeak = function(it, create){\n if(!has(it, META)){\n // can't set metadata to uncaught frozen object\n if(!isExtensible(it))return true;\n // not necessary to add metadata\n if(!create)return false;\n // add missing metadata\n setMeta(it);\n // return hash weak collections IDs\n } return it[META].w;\n};\n// add metadata on freeze-family methods calling\nvar onFreeze = function(it){\n if(FREEZE && meta.NEED && isExtensible(it) && !has(it, META))setMeta(it);\n return it;\n};\nvar meta = module.exports = {\n KEY: META,\n NEED: false,\n fastKey: fastKey,\n getWeak: getWeak,\n onFreeze: onFreeze\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_meta.js\n// module id = 110\n// module chunks = 0","var global = require('./_global')\n , macrotask = require('./_task').set\n , Observer = global.MutationObserver || global.WebKitMutationObserver\n , process = global.process\n , Promise = global.Promise\n , isNode = require('./_cof')(process) == 'process';\n\nmodule.exports = function(){\n var head, last, notify;\n\n var flush = function(){\n var parent, fn;\n if(isNode && (parent = process.domain))parent.exit();\n while(head){\n fn = head.fn;\n head = head.next;\n try {\n fn();\n } catch(e){\n if(head)notify();\n else last = undefined;\n throw e;\n }\n } last = undefined;\n if(parent)parent.enter();\n };\n\n // Node.js\n if(isNode){\n notify = function(){\n process.nextTick(flush);\n };\n // browsers with MutationObserver\n } else if(Observer){\n var toggle = true\n , node = document.createTextNode('');\n new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new\n notify = function(){\n node.data = toggle = !toggle;\n };\n // environments with maybe non-completely correct, but existent Promise\n } else if(Promise && Promise.resolve){\n var promise = Promise.resolve();\n notify = function(){\n promise.then(flush);\n };\n // for other environments - macrotask based on:\n // - setImmediate\n // - MessageChannel\n // - window.postMessag\n // - onreadystatechange\n // - setTimeout\n } else {\n notify = function(){\n // strange IE + webpack dev server bug - use .call(global)\n macrotask.call(global, flush);\n };\n }\n\n return function(fn){\n var task = {fn: fn, next: undefined};\n if(last)last.next = task;\n if(!head){\n head = task;\n notify();\n } last = task;\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_microtask.js\n// module id = 111\n// module chunks = 0","'use strict';\n// 19.1.2.1 Object.assign(target, source, ...)\nvar getKeys = require('./_object-keys')\n , gOPS = require('./_object-gops')\n , pIE = require('./_object-pie')\n , toObject = require('./_to-object')\n , IObject = require('./_iobject')\n , $assign = Object.assign;\n\n// should work with symbols and should have deterministic property order (V8 bug)\nmodule.exports = !$assign || require('./_fails')(function(){\n var A = {}\n , B = {}\n , S = Symbol()\n , K = 'abcdefghijklmnopqrst';\n A[S] = 7;\n K.split('').forEach(function(k){ B[k] = k; });\n return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;\n}) ? function assign(target, source){ // eslint-disable-line no-unused-vars\n var T = toObject(target)\n , aLen = arguments.length\n , index = 1\n , getSymbols = gOPS.f\n , isEnum = pIE.f;\n while(aLen > index){\n var S = IObject(arguments[index++])\n , keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S)\n , length = keys.length\n , j = 0\n , key;\n while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key];\n } return T;\n} : $assign;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-assign.js\n// module id = 112\n// module chunks = 0","var dP = require('./_object-dp')\n , anObject = require('./_an-object')\n , getKeys = require('./_object-keys');\n\nmodule.exports = require('./_descriptors') ? Object.defineProperties : function defineProperties(O, Properties){\n anObject(O);\n var keys = getKeys(Properties)\n , length = keys.length\n , i = 0\n , P;\n while(length > i)dP.f(O, P = keys[i++], Properties[P]);\n return O;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-dps.js\n// module id = 113\n// module chunks = 0","var pIE = require('./_object-pie')\n , createDesc = require('./_property-desc')\n , toIObject = require('./_to-iobject')\n , toPrimitive = require('./_to-primitive')\n , has = require('./_has')\n , IE8_DOM_DEFINE = require('./_ie8-dom-define')\n , gOPD = Object.getOwnPropertyDescriptor;\n\nexports.f = require('./_descriptors') ? gOPD : function getOwnPropertyDescriptor(O, P){\n O = toIObject(O);\n P = toPrimitive(P, true);\n if(IE8_DOM_DEFINE)try {\n return gOPD(O, P);\n } catch(e){ /* empty */ }\n if(has(O, P))return createDesc(!pIE.f.call(O, P), O[P]);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-gopd.js\n// module id = 114\n// module chunks = 0","// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window\nvar toIObject = require('./_to-iobject')\n , gOPN = require('./_object-gopn').f\n , toString = {}.toString;\n\nvar windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames\n ? Object.getOwnPropertyNames(window) : [];\n\nvar getWindowNames = function(it){\n try {\n return gOPN(it);\n } catch(e){\n return windowNames.slice();\n }\n};\n\nmodule.exports.f = function getOwnPropertyNames(it){\n return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it));\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-gopn-ext.js\n// module id = 115\n// module chunks = 0","// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\nvar has = require('./_has')\n , toObject = require('./_to-object')\n , IE_PROTO = require('./_shared-key')('IE_PROTO')\n , ObjectProto = Object.prototype;\n\nmodule.exports = Object.getPrototypeOf || function(O){\n O = toObject(O);\n if(has(O, IE_PROTO))return O[IE_PROTO];\n if(typeof O.constructor == 'function' && O instanceof O.constructor){\n return O.constructor.prototype;\n } return O instanceof Object ? ObjectProto : null;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-gpo.js\n// module id = 116\n// module chunks = 0","// most Object methods by ES6 should accept primitives\nvar $export = require('./_export')\n , core = require('./_core')\n , fails = require('./_fails');\nmodule.exports = function(KEY, exec){\n var fn = (core.Object || {})[KEY] || Object[KEY]\n , exp = {};\n exp[KEY] = exec(fn);\n $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_object-sap.js\n// module id = 117\n// module chunks = 0","var hide = require('./_hide');\nmodule.exports = function(target, src, safe){\n for(var key in src){\n if(safe && target[key])target[key] = src[key];\n else hide(target, key, src[key]);\n } return target;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_redefine-all.js\n// module id = 118\n// module chunks = 0","'use strict';\nvar global = require('./_global')\n , core = require('./_core')\n , dP = require('./_object-dp')\n , DESCRIPTORS = require('./_descriptors')\n , SPECIES = require('./_wks')('species');\n\nmodule.exports = function(KEY){\n var C = typeof core[KEY] == 'function' ? core[KEY] : global[KEY];\n if(DESCRIPTORS && C && !C[SPECIES])dP.f(C, SPECIES, {\n configurable: true,\n get: function(){ return this; }\n });\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_set-species.js\n// module id = 119\n// module chunks = 0","// 7.3.20 SpeciesConstructor(O, defaultConstructor)\nvar anObject = require('./_an-object')\n , aFunction = require('./_a-function')\n , SPECIES = require('./_wks')('species');\nmodule.exports = function(O, D){\n var C = anObject(O).constructor, S;\n return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_species-constructor.js\n// module id = 120\n// module chunks = 0","var toInteger = require('./_to-integer')\n , defined = require('./_defined');\n// true -> String#at\n// false -> String#codePointAt\nmodule.exports = function(TO_STRING){\n return function(that, pos){\n var s = String(defined(that))\n , i = toInteger(pos)\n , l = s.length\n , a, b;\n if(i < 0 || i >= l)return TO_STRING ? '' : undefined;\n a = s.charCodeAt(i);\n return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n ? TO_STRING ? s.charAt(i) : a\n : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_string-at.js\n// module id = 121\n// module chunks = 0","var toInteger = require('./_to-integer')\n , max = Math.max\n , min = Math.min;\nmodule.exports = function(index, length){\n index = toInteger(index);\n return index < 0 ? max(index + length, 0) : min(index, length);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_to-index.js\n// module id = 122\n// module chunks = 0","var anObject = require('./_an-object')\n , get = require('./core.get-iterator-method');\nmodule.exports = require('./_core').getIterator = function(it){\n var iterFn = get(it);\n if(typeof iterFn != 'function')throw TypeError(it + ' is not iterable!');\n return anObject(iterFn.call(it));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/core.get-iterator.js\n// module id = 123\n// module chunks = 0","var classof = require('./_classof')\n , ITERATOR = require('./_wks')('iterator')\n , Iterators = require('./_iterators');\nmodule.exports = require('./_core').isIterable = function(it){\n var O = Object(it);\n return O[ITERATOR] !== undefined\n || '@@iterator' in O\n || Iterators.hasOwnProperty(classof(O));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/core.is-iterable.js\n// module id = 124\n// module chunks = 0","'use strict';\nvar addToUnscopables = require('./_add-to-unscopables')\n , step = require('./_iter-step')\n , Iterators = require('./_iterators')\n , toIObject = require('./_to-iobject');\n\n// 22.1.3.4 Array.prototype.entries()\n// 22.1.3.13 Array.prototype.keys()\n// 22.1.3.29 Array.prototype.values()\n// 22.1.3.30 Array.prototype[@@iterator]()\nmodule.exports = require('./_iter-define')(Array, 'Array', function(iterated, kind){\n this._t = toIObject(iterated); // target\n this._i = 0; // next index\n this._k = kind; // kind\n// 22.1.5.2.1 %ArrayIteratorPrototype%.next()\n}, function(){\n var O = this._t\n , kind = this._k\n , index = this._i++;\n if(!O || index >= O.length){\n this._t = undefined;\n return step(1);\n }\n if(kind == 'keys' )return step(0, index);\n if(kind == 'values')return step(0, O[index]);\n return step(0, [index, O[index]]);\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)\nIterators.Arguments = Iterators.Array;\n\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/es6.array.iterator.js\n// module id = 125\n// module chunks = 0","// 20.2.2.22 Math.log2(x)\nvar $export = require('./_export');\n\n$export($export.S, 'Math', {\n log2: function log2(x){\n return Math.log(x) / Math.LN2;\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/es6.math.log2.js\n// module id = 126\n// module chunks = 0","// 19.1.3.1 Object.assign(target, source)\nvar $export = require('./_export');\n\n$export($export.S + $export.F, 'Object', {assign: require('./_object-assign')});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/es6.object.assign.js\n// module id = 127\n// module chunks = 0","// 19.1.2.14 Object.keys(O)\nvar toObject = require('./_to-object')\n , $keys = require('./_object-keys');\n\nrequire('./_object-sap')('keys', function(){\n return function keys(it){\n return $keys(toObject(it));\n };\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/es6.object.keys.js\n// module id = 128\n// module chunks = 0","'use strict';\nvar LIBRARY = require('./_library')\n , global = require('./_global')\n , ctx = require('./_ctx')\n , classof = require('./_classof')\n , $export = require('./_export')\n , isObject = require('./_is-object')\n , aFunction = require('./_a-function')\n , anInstance = require('./_an-instance')\n , forOf = require('./_for-of')\n , speciesConstructor = require('./_species-constructor')\n , task = require('./_task').set\n , microtask = require('./_microtask')()\n , PROMISE = 'Promise'\n , TypeError = global.TypeError\n , process = global.process\n , $Promise = global[PROMISE]\n , process = global.process\n , isNode = classof(process) == 'process'\n , empty = function(){ /* empty */ }\n , Internal, GenericPromiseCapability, Wrapper;\n\nvar USE_NATIVE = !!function(){\n try {\n // correct subclassing with @@species support\n var promise = $Promise.resolve(1)\n , FakePromise = (promise.constructor = {})[require('./_wks')('species')] = function(exec){ exec(empty, empty); };\n // unhandled rejections tracking support, NodeJS Promise without it fails @@species test\n return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise;\n } catch(e){ /* empty */ }\n}();\n\n// helpers\nvar sameConstructor = function(a, b){\n // with library wrapper special case\n return a === b || a === $Promise && b === Wrapper;\n};\nvar isThenable = function(it){\n var then;\n return isObject(it) && typeof (then = it.then) == 'function' ? then : false;\n};\nvar newPromiseCapability = function(C){\n return sameConstructor($Promise, C)\n ? new PromiseCapability(C)\n : new GenericPromiseCapability(C);\n};\nvar PromiseCapability = GenericPromiseCapability = function(C){\n var resolve, reject;\n this.promise = new C(function($$resolve, $$reject){\n if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor');\n resolve = $$resolve;\n reject = $$reject;\n });\n this.resolve = aFunction(resolve);\n this.reject = aFunction(reject);\n};\nvar perform = function(exec){\n try {\n exec();\n } catch(e){\n return {error: e};\n }\n};\nvar notify = function(promise, isReject){\n if(promise._n)return;\n promise._n = true;\n var chain = promise._c;\n microtask(function(){\n var value = promise._v\n , ok = promise._s == 1\n , i = 0;\n var run = function(reaction){\n var handler = ok ? reaction.ok : reaction.fail\n , resolve = reaction.resolve\n , reject = reaction.reject\n , domain = reaction.domain\n , result, then;\n try {\n if(handler){\n if(!ok){\n if(promise._h == 2)onHandleUnhandled(promise);\n promise._h = 1;\n }\n if(handler === true)result = value;\n else {\n if(domain)domain.enter();\n result = handler(value);\n if(domain)domain.exit();\n }\n if(result === reaction.promise){\n reject(TypeError('Promise-chain cycle'));\n } else if(then = isThenable(result)){\n then.call(result, resolve, reject);\n } else resolve(result);\n } else reject(value);\n } catch(e){\n reject(e);\n }\n };\n while(chain.length > i)run(chain[i++]); // variable length - can't use forEach\n promise._c = [];\n promise._n = false;\n if(isReject && !promise._h)onUnhandled(promise);\n });\n};\nvar onUnhandled = function(promise){\n task.call(global, function(){\n var value = promise._v\n , abrupt, handler, console;\n if(isUnhandled(promise)){\n abrupt = perform(function(){\n if(isNode){\n process.emit('unhandledRejection', value, promise);\n } else if(handler = global.onunhandledrejection){\n handler({promise: promise, reason: value});\n } else if((console = global.console) && console.error){\n console.error('Unhandled promise rejection', value);\n }\n });\n // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should\n promise._h = isNode || isUnhandled(promise) ? 2 : 1;\n } promise._a = undefined;\n if(abrupt)throw abrupt.error;\n });\n};\nvar isUnhandled = function(promise){\n if(promise._h == 1)return false;\n var chain = promise._a || promise._c\n , i = 0\n , reaction;\n while(chain.length > i){\n reaction = chain[i++];\n if(reaction.fail || !isUnhandled(reaction.promise))return false;\n } return true;\n};\nvar onHandleUnhandled = function(promise){\n task.call(global, function(){\n var handler;\n if(isNode){\n process.emit('rejectionHandled', promise);\n } else if(handler = global.onrejectionhandled){\n handler({promise: promise, reason: promise._v});\n }\n });\n};\nvar $reject = function(value){\n var promise = this;\n if(promise._d)return;\n promise._d = true;\n promise = promise._w || promise; // unwrap\n promise._v = value;\n promise._s = 2;\n if(!promise._a)promise._a = promise._c.slice();\n notify(promise, true);\n};\nvar $resolve = function(value){\n var promise = this\n , then;\n if(promise._d)return;\n promise._d = true;\n promise = promise._w || promise; // unwrap\n try {\n if(promise === value)throw TypeError(\"Promise can't be resolved itself\");\n if(then = isThenable(value)){\n microtask(function(){\n var wrapper = {_w: promise, _d: false}; // wrap\n try {\n then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));\n } catch(e){\n $reject.call(wrapper, e);\n }\n });\n } else {\n promise._v = value;\n promise._s = 1;\n notify(promise, false);\n }\n } catch(e){\n $reject.call({_w: promise, _d: false}, e); // wrap\n }\n};\n\n// constructor polyfill\nif(!USE_NATIVE){\n // 25.4.3.1 Promise(executor)\n $Promise = function Promise(executor){\n anInstance(this, $Promise, PROMISE, '_h');\n aFunction(executor);\n Internal.call(this);\n try {\n executor(ctx($resolve, this, 1), ctx($reject, this, 1));\n } catch(err){\n $reject.call(this, err);\n }\n };\n Internal = function Promise(executor){\n this._c = []; // <- awaiting reactions\n this._a = undefined; // <- checked in isUnhandled reactions\n this._s = 0; // <- state\n this._d = false; // <- done\n this._v = undefined; // <- value\n this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled\n this._n = false; // <- notify\n };\n Internal.prototype = require('./_redefine-all')($Promise.prototype, {\n // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)\n then: function then(onFulfilled, onRejected){\n var reaction = newPromiseCapability(speciesConstructor(this, $Promise));\n reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;\n reaction.fail = typeof onRejected == 'function' && onRejected;\n reaction.domain = isNode ? process.domain : undefined;\n this._c.push(reaction);\n if(this._a)this._a.push(reaction);\n if(this._s)notify(this, false);\n return reaction.promise;\n },\n // 25.4.5.1 Promise.prototype.catch(onRejected)\n 'catch': function(onRejected){\n return this.then(undefined, onRejected);\n }\n });\n PromiseCapability = function(){\n var promise = new Internal;\n this.promise = promise;\n this.resolve = ctx($resolve, promise, 1);\n this.reject = ctx($reject, promise, 1);\n };\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: $Promise});\nrequire('./_set-to-string-tag')($Promise, PROMISE);\nrequire('./_set-species')(PROMISE);\nWrapper = require('./_core')[PROMISE];\n\n// statics\n$export($export.S + $export.F * !USE_NATIVE, PROMISE, {\n // 25.4.4.5 Promise.reject(r)\n reject: function reject(r){\n var capability = newPromiseCapability(this)\n , $$reject = capability.reject;\n $$reject(r);\n return capability.promise;\n }\n});\n$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {\n // 25.4.4.6 Promise.resolve(x)\n resolve: function resolve(x){\n // instanceof instead of internal slot check because we should fix it without replacement native Promise core\n if(x instanceof $Promise && sameConstructor(x.constructor, this))return x;\n var capability = newPromiseCapability(this)\n , $$resolve = capability.resolve;\n $$resolve(x);\n return capability.promise;\n }\n});\n$export($export.S + $export.F * !(USE_NATIVE && require('./_iter-detect')(function(iter){\n $Promise.all(iter)['catch'](empty);\n})), PROMISE, {\n // 25.4.4.1 Promise.all(iterable)\n all: function all(iterable){\n var C = this\n , capability = newPromiseCapability(C)\n , resolve = capability.resolve\n , reject = capability.reject;\n var abrupt = perform(function(){\n var values = []\n , index = 0\n , remaining = 1;\n forOf(iterable, false, function(promise){\n var $index = index++\n , alreadyCalled = false;\n values.push(undefined);\n remaining++;\n C.resolve(promise).then(function(value){\n if(alreadyCalled)return;\n alreadyCalled = true;\n values[$index] = value;\n --remaining || resolve(values);\n }, reject);\n });\n --remaining || resolve(values);\n });\n if(abrupt)reject(abrupt.error);\n return capability.promise;\n },\n // 25.4.4.4 Promise.race(iterable)\n race: function race(iterable){\n var C = this\n , capability = newPromiseCapability(C)\n , reject = capability.reject;\n var abrupt = perform(function(){\n forOf(iterable, false, function(promise){\n C.resolve(promise).then(capability.resolve, reject);\n });\n });\n if(abrupt)reject(abrupt.error);\n return capability.promise;\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/es6.promise.js\n// module id = 129\n// module chunks = 0","'use strict';\n// ECMAScript 6 symbols shim\nvar global = require('./_global')\n , has = require('./_has')\n , DESCRIPTORS = require('./_descriptors')\n , $export = require('./_export')\n , redefine = require('./_redefine')\n , META = require('./_meta').KEY\n , $fails = require('./_fails')\n , shared = require('./_shared')\n , setToStringTag = require('./_set-to-string-tag')\n , uid = require('./_uid')\n , wks = require('./_wks')\n , wksExt = require('./_wks-ext')\n , wksDefine = require('./_wks-define')\n , keyOf = require('./_keyof')\n , enumKeys = require('./_enum-keys')\n , isArray = require('./_is-array')\n , anObject = require('./_an-object')\n , toIObject = require('./_to-iobject')\n , toPrimitive = require('./_to-primitive')\n , createDesc = require('./_property-desc')\n , _create = require('./_object-create')\n , gOPNExt = require('./_object-gopn-ext')\n , $GOPD = require('./_object-gopd')\n , $DP = require('./_object-dp')\n , $keys = require('./_object-keys')\n , gOPD = $GOPD.f\n , dP = $DP.f\n , gOPN = gOPNExt.f\n , $Symbol = global.Symbol\n , $JSON = global.JSON\n , _stringify = $JSON && $JSON.stringify\n , PROTOTYPE = 'prototype'\n , HIDDEN = wks('_hidden')\n , TO_PRIMITIVE = wks('toPrimitive')\n , isEnum = {}.propertyIsEnumerable\n , SymbolRegistry = shared('symbol-registry')\n , AllSymbols = shared('symbols')\n , OPSymbols = shared('op-symbols')\n , ObjectProto = Object[PROTOTYPE]\n , USE_NATIVE = typeof $Symbol == 'function'\n , QObject = global.QObject;\n// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173\nvar setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;\n\n// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687\nvar setSymbolDesc = DESCRIPTORS && $fails(function(){\n return _create(dP({}, 'a', {\n get: function(){ return dP(this, 'a', {value: 7}).a; }\n })).a != 7;\n}) ? function(it, key, D){\n var protoDesc = gOPD(ObjectProto, key);\n if(protoDesc)delete ObjectProto[key];\n dP(it, key, D);\n if(protoDesc && it !== ObjectProto)dP(ObjectProto, key, protoDesc);\n} : dP;\n\nvar wrap = function(tag){\n var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]);\n sym._k = tag;\n return sym;\n};\n\nvar isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function(it){\n return typeof it == 'symbol';\n} : function(it){\n return it instanceof $Symbol;\n};\n\nvar $defineProperty = function defineProperty(it, key, D){\n if(it === ObjectProto)$defineProperty(OPSymbols, key, D);\n anObject(it);\n key = toPrimitive(key, true);\n anObject(D);\n if(has(AllSymbols, key)){\n if(!D.enumerable){\n if(!has(it, HIDDEN))dP(it, HIDDEN, createDesc(1, {}));\n it[HIDDEN][key] = true;\n } else {\n if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false;\n D = _create(D, {enumerable: createDesc(0, false)});\n } return setSymbolDesc(it, key, D);\n } return dP(it, key, D);\n};\nvar $defineProperties = function defineProperties(it, P){\n anObject(it);\n var keys = enumKeys(P = toIObject(P))\n , i = 0\n , l = keys.length\n , key;\n while(l > i)$defineProperty(it, key = keys[i++], P[key]);\n return it;\n};\nvar $create = function create(it, P){\n return P === undefined ? _create(it) : $defineProperties(_create(it), P);\n};\nvar $propertyIsEnumerable = function propertyIsEnumerable(key){\n var E = isEnum.call(this, key = toPrimitive(key, true));\n if(this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return false;\n return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true;\n};\nvar $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){\n it = toIObject(it);\n key = toPrimitive(key, true);\n if(it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return;\n var D = gOPD(it, key);\n if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true;\n return D;\n};\nvar $getOwnPropertyNames = function getOwnPropertyNames(it){\n var names = gOPN(toIObject(it))\n , result = []\n , i = 0\n , key;\n while(names.length > i){\n if(!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META)result.push(key);\n } return result;\n};\nvar $getOwnPropertySymbols = function getOwnPropertySymbols(it){\n var IS_OP = it === ObjectProto\n , names = gOPN(IS_OP ? OPSymbols : toIObject(it))\n , result = []\n , i = 0\n , key;\n while(names.length > i){\n if(has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true))result.push(AllSymbols[key]);\n } return result;\n};\n\n// 19.4.1.1 Symbol([description])\nif(!USE_NATIVE){\n $Symbol = function Symbol(){\n if(this instanceof $Symbol)throw TypeError('Symbol is not a constructor!');\n var tag = uid(arguments.length > 0 ? arguments[0] : undefined);\n var $set = function(value){\n if(this === ObjectProto)$set.call(OPSymbols, value);\n if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false;\n setSymbolDesc(this, tag, createDesc(1, value));\n };\n if(DESCRIPTORS && setter)setSymbolDesc(ObjectProto, tag, {configurable: true, set: $set});\n return wrap(tag);\n };\n redefine($Symbol[PROTOTYPE], 'toString', function toString(){\n return this._k;\n });\n\n $GOPD.f = $getOwnPropertyDescriptor;\n $DP.f = $defineProperty;\n require('./_object-gopn').f = gOPNExt.f = $getOwnPropertyNames;\n require('./_object-pie').f = $propertyIsEnumerable;\n require('./_object-gops').f = $getOwnPropertySymbols;\n\n if(DESCRIPTORS && !require('./_library')){\n redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);\n }\n\n wksExt.f = function(name){\n return wrap(wks(name));\n }\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, {Symbol: $Symbol});\n\nfor(var symbols = (\n // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14\n 'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'\n).split(','), i = 0; symbols.length > i; )wks(symbols[i++]);\n\nfor(var symbols = $keys(wks.store), i = 0; symbols.length > i; )wksDefine(symbols[i++]);\n\n$export($export.S + $export.F * !USE_NATIVE, 'Symbol', {\n // 19.4.2.1 Symbol.for(key)\n 'for': function(key){\n return has(SymbolRegistry, key += '')\n ? SymbolRegistry[key]\n : SymbolRegistry[key] = $Symbol(key);\n },\n // 19.4.2.5 Symbol.keyFor(sym)\n keyFor: function keyFor(key){\n if(isSymbol(key))return keyOf(SymbolRegistry, key);\n throw TypeError(key + ' is not a symbol!');\n },\n useSetter: function(){ setter = true; },\n useSimple: function(){ setter = false; }\n});\n\n$export($export.S + $export.F * !USE_NATIVE, 'Object', {\n // 19.1.2.2 Object.create(O [, Properties])\n create: $create,\n // 19.1.2.4 Object.defineProperty(O, P, Attributes)\n defineProperty: $defineProperty,\n // 19.1.2.3 Object.defineProperties(O, Properties)\n defineProperties: $defineProperties,\n // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)\n getOwnPropertyDescriptor: $getOwnPropertyDescriptor,\n // 19.1.2.7 Object.getOwnPropertyNames(O)\n getOwnPropertyNames: $getOwnPropertyNames,\n // 19.1.2.8 Object.getOwnPropertySymbols(O)\n getOwnPropertySymbols: $getOwnPropertySymbols\n});\n\n// 24.3.2 JSON.stringify(value [, replacer [, space]])\n$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function(){\n var S = $Symbol();\n // MS Edge converts symbol values to JSON as {}\n // WebKit converts symbol values to JSON as null\n // V8 throws on boxed symbols\n return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}';\n})), 'JSON', {\n stringify: function stringify(it){\n if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined\n var args = [it]\n , i = 1\n , replacer, $replacer;\n while(arguments.length > i)args.push(arguments[i++]);\n replacer = args[1];\n if(typeof replacer == 'function')$replacer = replacer;\n if($replacer || !isArray(replacer))replacer = function(key, value){\n if($replacer)value = $replacer.call(this, key, value);\n if(!isSymbol(value))return value;\n };\n args[1] = replacer;\n return _stringify.apply($JSON, args);\n }\n});\n\n// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)\n$Symbol[PROTOTYPE][TO_PRIMITIVE] || require('./_hide')($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);\n// 19.4.3.5 Symbol.prototype[@@toStringTag]\nsetToStringTag($Symbol, 'Symbol');\n// 20.2.1.9 Math[@@toStringTag]\nsetToStringTag(Math, 'Math', true);\n// 24.3.3 JSON[@@toStringTag]\nsetToStringTag(global.JSON, 'JSON', true);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/es6.symbol.js\n// module id = 130\n// module chunks = 0","require('./_wks-define')('asyncIterator');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/es7.symbol.async-iterator.js\n// module id = 131\n// module chunks = 0","require('./_wks-define')('observable');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/es7.symbol.observable.js\n// module id = 132\n// module chunks = 0","// Generated by CoffeeScript 2.3.1\n// # CSV Parser\n\n// This module provides a CSV parser tested and used against large datasets. Over\n// the year, it has been enhance and is now full of useful options.\n\n// Please look at the [README], the [project website][site] the [samples] and the\n// [tests] for additional information.\nvar Parser, StringDecoder, isObjLiteral, stream, util;\n\nstream = require('stream');\n\nutil = require('util');\n\nStringDecoder = require('string_decoder').StringDecoder;\n\n// ## Usage\n\n// Callback approach, for ease of use: \n\n// `parse(data, [options], callback)` \n\n// [Node.js Stream API][stream], for maximum of power: \n\n// `parse([options], [callback])` \nmodule.exports = function() {\n var callback, called, chunks, data, err, options, parser;\n if (arguments.length === 3) {\n data = arguments[0];\n options = arguments[1];\n callback = arguments[2];\n if (typeof callback !== 'function') {\n throw Error(`Invalid callback argument: ${JSON.stringify(callback)}`);\n }\n if (!(typeof data === 'string' || Buffer.isBuffer(arguments[0]))) {\n return callback(Error(`Invalid data argument: ${JSON.stringify(data)}`));\n }\n } else if (arguments.length === 2) {\n // 1st arg is data:string or options:object\n if (typeof arguments[0] === 'string' || Buffer.isBuffer(arguments[0])) {\n data = arguments[0];\n } else if (isObjLiteral(arguments[0])) {\n options = arguments[0];\n } else {\n err = `Invalid first argument: ${JSON.stringify(arguments[0])}`;\n }\n // 2nd arg is options:object or callback:function\n if (typeof arguments[1] === 'function') {\n callback = arguments[1];\n } else if (isObjLiteral(arguments[1])) {\n if (options) {\n err = 'Invalid arguments: got options twice as first and second arguments';\n } else {\n options = arguments[1];\n }\n } else {\n err = `Invalid first argument: ${JSON.stringify(arguments[1])}`;\n }\n if (err) {\n if (!callback) {\n throw Error(err);\n } else {\n return callback(Error(err));\n }\n }\n } else if (arguments.length === 1) {\n if (typeof arguments[0] === 'function') {\n callback = arguments[0];\n } else {\n options = arguments[0];\n }\n }\n if (options == null) {\n options = {};\n }\n parser = new Parser(options);\n if (data != null) {\n process.nextTick(function() {\n parser.write(data);\n return parser.end();\n });\n }\n if (callback) {\n called = false;\n chunks = options.objname ? {} : [];\n parser.on('readable', function() {\n var chunk, results;\n results = [];\n while (chunk = parser.read()) {\n if (options.objname) {\n results.push(chunks[chunk[0]] = chunk[1]);\n } else {\n results.push(chunks.push(chunk));\n }\n }\n return results;\n });\n parser.on('error', function(err) {\n called = true;\n return callback(err);\n });\n parser.on('end', function() {\n if (!called) {\n return callback(null, chunks);\n }\n });\n }\n return parser;\n};\n\n// ## `Parser([options])`\n\n// Options are documented [here](http://csv.adaltas.com/parse/).\nParser = function(options = {}) {\n var base, base1, base10, base11, base12, base13, base14, base15, base16, base17, base2, base3, base4, base5, base6, base7, base8, base9, k, v;\n // @options = options\n this.options = {};\n for (k in options) {\n v = options[k];\n this.options[k] = v;\n }\n this.options.objectMode = true;\n stream.Transform.call(this, this.options);\n if ((base = this.options).rowDelimiter == null) {\n base.rowDelimiter = null;\n }\n if (typeof this.options.rowDelimiter === 'string') {\n this.options.rowDelimiter = [this.options.rowDelimiter];\n }\n if ((base1 = this.options).delimiter == null) {\n base1.delimiter = ',';\n }\n if (this.options.quote !== void 0 && !this.options.quote) {\n this.options.quote = '';\n }\n if ((base2 = this.options).quote == null) {\n base2.quote = '\"';\n }\n if ((base3 = this.options).escape == null) {\n base3.escape = '\"';\n }\n if ((base4 = this.options).columns == null) {\n base4.columns = null;\n }\n if ((base5 = this.options).comment == null) {\n base5.comment = '';\n }\n if ((base6 = this.options).objname == null) {\n base6.objname = false;\n }\n if ((base7 = this.options).trim == null) {\n base7.trim = false;\n }\n if ((base8 = this.options).ltrim == null) {\n base8.ltrim = false;\n }\n if ((base9 = this.options).rtrim == null) {\n base9.rtrim = false;\n }\n if (this.options.auto_parse != null) {\n this.options.cast = this.options.auto_parse;\n }\n if ((base10 = this.options).cast == null) {\n base10.cast = false;\n }\n if (this.options.auto_parse_date != null) {\n this.options.cast_date = this.options.auto_parse_date;\n }\n if ((base11 = this.options).cast_date == null) {\n base11.cast_date = false;\n }\n if (this.options.cast_date === true) {\n this.options.cast_date = function(value) {\n var m;\n m = Date.parse(value);\n if (!isNaN(m)) {\n value = new Date(m);\n }\n return value;\n };\n }\n if ((base12 = this.options).relax == null) {\n base12.relax = false;\n }\n if ((base13 = this.options).relax_column_count == null) {\n base13.relax_column_count = false;\n }\n if ((base14 = this.options).skip_empty_lines == null) {\n base14.skip_empty_lines = false;\n }\n if ((base15 = this.options).max_limit_on_data_read == null) {\n base15.max_limit_on_data_read = 128000;\n }\n if ((base16 = this.options).skip_lines_with_empty_values == null) {\n base16.skip_lines_with_empty_values = false;\n }\n if ((base17 = this.options).skip_lines_with_error == null) {\n base17.skip_lines_with_error = false;\n }\n // Counters\n // lines = count + skipped_line_count + empty_line_count\n this.lines = 0; // Number of lines encountered in the source dataset\n this.count = 0; // Number of records being processed\n this.skipped_line_count = 0; // Number of records skipped due to errors\n this.empty_line_count = 0; // Number of empty lines\n // Constants\n this.is_int = /^(\\-|\\+)?([1-9]+[0-9]*)$/;\n // @is_float = /^(\\-|\\+)?([0-9]+(\\.[0-9]+)([eE][0-9]+)?|Infinity)$/\n // @is_float = /^(\\-|\\+)?((([0-9])|([1-9]+[0-9]*))(\\.[0-9]+)([eE][0-9]+)?|Infinity)$/\n this.is_float = function(value) {\n return (value - parseFloat(value) + 1) >= 0; // Borrowed from jquery\n };\n // Internal state\n this._ = {\n decoder: new StringDecoder(),\n quoting: false,\n commenting: false,\n field: null,\n nextChar: null,\n closingQuote: 0,\n line: [],\n chunks: [],\n rawBuf: '',\n buf: '',\n rowDelimiterLength: this.options.rowDelimiter ? Math.max(...this.options.rowDelimiter.map(function(v) {\n return v.length;\n })) : void 0,\n lineHasError: false,\n isEnded: false\n };\n return this;\n};\n\n// ## Internal API\n\n// The Parser implement a [`stream.Transform` class][transform].\n\n// ### Events\n\n// The library extends Node [EventEmitter][event] class and emit all\n// the events of the Writable and Readable [Stream API][stream]. \nutil.inherits(Parser, stream.Transform);\n\n// For extra flexibility, you can get access to the original Parser\n// class: `require('csv-parse').Parser`.\nmodule.exports.Parser = Parser;\n\n// ### `_transform(chunk, encoding, callback)`\n\n// * `chunk` Buffer | String \n// The chunk to be transformed. Will always be a buffer unless the decodeStrings option was set to false.\n// * `encoding` String \n// If the chunk is a string, then this is the encoding type. (Ignore if decodeStrings chunk is a buffer.)\n// * `callback` Function \n// Call this function (optionally with an error argument) when you are done processing the supplied chunk.\n\n// Implementation of the [`stream.Transform` API][transform]\nParser.prototype._transform = function(chunk, encoding, callback) {\n return setImmediate(() => {\n var err;\n if (chunk instanceof Buffer) {\n chunk = this._.decoder.write(chunk);\n }\n err = this.__write(chunk, false);\n if (err) {\n return this.emit('error', err);\n }\n return callback();\n });\n};\n\nParser.prototype._flush = function(callback) {\n return callback(this.__flush());\n};\n\nParser.prototype.__flush = function() {\n var err;\n err = this.__write(this._.decoder.end(), true);\n if (err) {\n return err;\n }\n if (this._.quoting) {\n err = this.error(`Quoted field not terminated at line ${this.lines + 1}`);\n return err;\n }\n if (this._.line.length > 0) {\n return this.__push(this._.line);\n }\n};\n\nParser.prototype.__push = function(line) {\n var call_column_udf, columns, err, field, i, j, len, lineAsColumns, record;\n if (this._.isEnded) {\n return;\n }\n if (this.options.skip_lines_with_empty_values && line.join('').trim() === '') {\n return;\n }\n record = null;\n if (this.options.columns === true) {\n this.options.columns = line;\n return;\n } else if (typeof this.options.columns === 'function') {\n call_column_udf = function(fn, line) {\n var columns, err;\n try {\n columns = fn.call(null, line);\n return [null, columns];\n } catch (error) {\n err = error;\n return [err];\n }\n };\n [err, columns] = call_column_udf(this.options.columns, line);\n if (err) {\n return err;\n }\n this.options.columns = columns;\n return;\n }\n if (!this._.line_length && line.length > 0) {\n this._.line_length = this.options.columns ? this.options.columns.length : line.length;\n }\n // Dont check column count on empty lines\n if (line.length === 1 && line[0] === '') {\n this.empty_line_count++;\n } else if (line.length !== this._.line_length) {\n // Dont check column count with relax_column_count\n if (this.options.relax_column_count) {\n this.count++;\n this.skipped_line_count++;\n } else if (this.options.columns != null) {\n // Suggest: Inconsistent header and column numbers: header is 1 and number of columns is 1 on line 1\n err = this.error(`Number of columns on line ${this.lines} does not match header`);\n return err;\n } else {\n err = this.error(`Number of columns is inconsistent on line ${this.lines}`);\n return err;\n }\n } else {\n this.count++;\n }\n if (this.options.columns != null) {\n lineAsColumns = {};\n for (i = j = 0, len = line.length; j < len; i = ++j) {\n field = line[i];\n if (this.options.columns[i] === false) {\n continue;\n }\n lineAsColumns[this.options.columns[i]] = field;\n }\n if (this.options.objname) {\n record = [lineAsColumns[this.options.objname], lineAsColumns];\n } else {\n record = lineAsColumns;\n }\n } else {\n record = line;\n }\n if (this.count < this.options.from) {\n return;\n }\n if (this.options.raw) {\n this.push({\n raw: this._.rawBuf,\n row: record\n });\n this._.rawBuf = '';\n } else {\n this.push(record);\n }\n if (this.listenerCount('record')) {\n this.emit('record', record);\n }\n // When to is reached set ignore any future calls\n if (this.count >= this.options.to) {\n this._.isEnded = true;\n return this.push(null);\n }\n return null;\n};\n\nParser.prototype.__write = function(chars, end) {\n var areNextCharsDelimiter, areNextCharsRowDelimiters, cast, char, err, escapeIsQuote, i, isDelimiter, isEscape, isNextCharAComment, isNextCharTrimable, isQuote, isRowDelimiter, isRowDelimiterLength, is_float, is_int, l, ltrim, nextCharPos, ref, ref1, ref2, ref3, ref4, ref5, ref6, remainingBuffer, rowDelimiter, rtrim, wasCommenting;\n is_int = (value) => {\n if (typeof this.is_int === 'function') {\n return this.is_int(value);\n } else {\n return this.is_int.test(value);\n }\n };\n is_float = (value) => {\n if (typeof this.is_float === 'function') {\n return this.is_float(value);\n } else {\n return this.is_float.test(value);\n }\n };\n cast = (value, context = {}) => {\n if (!this.options.cast) {\n return value;\n }\n if (context.quoting == null) {\n context.quoting = !!this._.closingQuote;\n }\n if (context.lines == null) {\n context.lines = this.lines;\n }\n if (context.count == null) {\n context.count = this.count;\n }\n if (context.index == null) {\n context.index = this._.line.length;\n }\n // context.header ?= if @options.column and @lines is 1 and @count is 0 then true else false\n if (context.header == null) {\n context.header = this.options.columns === true;\n }\n if (context.column == null) {\n context.column = Array.isArray(this.options.columns) ? this.options.columns[context.index] : context.index;\n }\n if (typeof this.options.cast === 'function') {\n return this.options.cast(value, context);\n }\n if (is_int(value)) {\n value = parseInt(value);\n } else if (is_float(value)) {\n value = parseFloat(value);\n } else if (this.options.cast_date) {\n value = this.options.cast_date(value, context);\n }\n return value;\n };\n ltrim = this.options.trim || this.options.ltrim;\n rtrim = this.options.trim || this.options.rtrim;\n chars = this._.buf + chars;\n l = chars.length;\n i = 0;\n if (this.lines === 0 && 0xFEFF === chars.charCodeAt(0)) {\n // Strip BOM header\n i++;\n }\n while (i < l) {\n // Ensure we get enough space to look ahead\n if (!end) {\n remainingBuffer = chars.substr(i, l - i);\n // (i+1000 >= l) or\n // Skip if the remaining buffer can be comment\n // Skip if the remaining buffer can be row delimiter\n if ((!this.options.rowDelimiter && i + 3 > l) || (!this._.commenting && l - i < this.options.comment.length && this.options.comment.substr(0, l - i) === remainingBuffer) || (this.options.rowDelimiter && l - i < this._.rowDelimiterLength && this.options.rowDelimiter.some(function(rd) {\n return rd.substr(0, l - i) === remainingBuffer;\n // Skip if the remaining buffer can be row delimiter following the closing quote\n })) || (this.options.rowDelimiter && this._.quoting && l - i < (this.options.quote.length + this._.rowDelimiterLength) && this.options.rowDelimiter.some((rd) => {\n return (this.options.quote + rd).substr(0, l - i) === remainingBuffer;\n // Skip if the remaining buffer can be delimiter\n // Skip if the remaining buffer can be escape sequence\n })) || (l - i <= this.options.delimiter.length && this.options.delimiter.substr(0, l - i) === remainingBuffer) || (l - i <= this.options.escape.length && this.options.escape.substr(0, l - i) === remainingBuffer)) {\n break;\n }\n }\n char = this._.nextChar ? this._.nextChar : chars.charAt(i);\n this._.nextChar = l > i + 1 ? chars.charAt(i + 1) : null;\n if (this.options.raw) {\n this._.rawBuf += char;\n }\n // Auto discovery of rowDelimiter, unix, mac and windows supported\n if (this.options.rowDelimiter == null) {\n nextCharPos = i;\n rowDelimiter = null;\n // First empty line\n if (!this._.quoting && (char === '\\n' || char === '\\r')) {\n rowDelimiter = char;\n nextCharPos += 1;\n } else if (this._.quoting && char === this.options.quote && ((ref = this._.nextChar) === '\\n' || ref === '\\r')) {\n rowDelimiter = this._.nextChar;\n nextCharPos += 2;\n }\n if (rowDelimiter) {\n if (rowDelimiter === '\\r' && chars.charAt(nextCharPos) === '\\n') {\n rowDelimiter += '\\n';\n }\n this.options.rowDelimiter = [rowDelimiter];\n this._.rowDelimiterLength = rowDelimiter.length;\n }\n }\n // Parse that damn char\n // Note, shouldn't we have sth like chars.substr(i, @options.escape.length)\n if (!this._.commenting && char === this.options.escape) {\n // Make sure the escape is really here for escaping:\n // If escape is same as quote, and escape is first char of a field \n // and it's not quoted, then it is a quote\n // Next char should be an escape or a quote\n escapeIsQuote = this.options.escape === this.options.quote;\n isEscape = this._.nextChar === this.options.escape;\n isQuote = this._.nextChar === this.options.quote;\n if (!(escapeIsQuote && !this._.field && !this._.quoting) && (isEscape || isQuote)) {\n i++;\n char = this._.nextChar;\n this._.nextChar = chars.charAt(i + 1);\n if (this._.field == null) {\n this._.field = '';\n }\n this._.field += char;\n // Since we're skipping the next one, better add it now if in raw mode.\n if (this.options.raw) {\n this._.rawBuf += char;\n }\n i++;\n continue;\n }\n }\n // Char match quote\n if (!this._.commenting && char === this.options.quote) {\n if (this._.acceptOnlyEmptyChars && (char !== ' ' && char !== '\\t')) {\n return this.error('Only trimable characters are accepted after quotes');\n }\n if (this._.quoting) {\n // Make sure a closing quote is followed by a delimiter\n // If we have a next character and \n // it isnt a rowDelimiter and \n // it isnt an column delimiter and\n // it isnt the begining of a comment\n // Otherwise, if this is not \"relax\" mode, throw an error\n isNextCharTrimable = rtrim && ((ref1 = this._.nextChar) === ' ' || ref1 === '\\t');\n areNextCharsRowDelimiters = this.options.rowDelimiter && this.options.rowDelimiter.some(function(rd) {\n return chars.substr(i + 1, rd.length) === rd;\n });\n areNextCharsDelimiter = chars.substr(i + 1, this.options.delimiter.length) === this.options.delimiter;\n isNextCharAComment = this._.nextChar === this.options.comment;\n if ((this._.nextChar != null) && !isNextCharTrimable && !areNextCharsRowDelimiters && !areNextCharsDelimiter && !isNextCharAComment) {\n if (this.options.relax) {\n this._.quoting = false;\n if (this._.field) {\n this._.field = `${this.options.quote}${this._.field}`;\n }\n } else {\n if (err = this.error(`Invalid closing quote at line ${this.lines + 1}; found ${JSON.stringify(this._.nextChar)} instead of delimiter ${JSON.stringify(this.options.delimiter)}`)) {\n return err;\n }\n }\n } else if ((this._.nextChar != null) && isNextCharTrimable) {\n i++;\n this._.quoting = false;\n this._.closingQuote = this.options.quote.length;\n this._.acceptOnlyEmptyChars = true;\n continue;\n } else {\n i++;\n this._.quoting = false;\n this._.closingQuote = this.options.quote.length;\n if (end && i === l) {\n this._.line.push(cast(this._.field || ''));\n this._.field = null;\n }\n continue;\n }\n } else if (!this._.field) {\n this._.quoting = true;\n i++;\n continue;\n } else if ((this._.field != null) && !this.options.relax) {\n if (err = this.error(`Invalid opening quote at line ${this.lines + 1}`)) {\n return err;\n }\n }\n }\n // Otherwise, treat quote as a regular character\n isRowDelimiter = this.options.rowDelimiter && this.options.rowDelimiter.some(function(rd) {\n return chars.substr(i, rd.length) === rd;\n });\n if (isRowDelimiter || (end && i === l - 1)) {\n this.lines++;\n }\n // Set the commenting flag\n wasCommenting = false;\n if (!this._.commenting && !this._.quoting && this.options.comment && chars.substr(i, this.options.comment.length) === this.options.comment) {\n this._.commenting = true;\n } else if (this._.commenting && isRowDelimiter) {\n wasCommenting = true;\n this._.commenting = false;\n }\n isDelimiter = chars.substr(i, this.options.delimiter.length) === this.options.delimiter;\n if (this._.acceptOnlyEmptyChars) {\n if (isDelimiter || isRowDelimiter) {\n this._.acceptOnlyEmptyChars = false;\n } else {\n if (char === ' ' || char === '\\t') {\n i++;\n continue;\n } else {\n return this.error('Only trimable characters are accepted after quotes');\n }\n }\n }\n if (!this._.commenting && !this._.quoting && (isDelimiter || isRowDelimiter)) {\n if (isRowDelimiter) {\n isRowDelimiterLength = this.options.rowDelimiter.filter(function(rd) {\n return chars.substr(i, rd.length) === rd;\n })[0].length;\n }\n // Empty lines\n if (isRowDelimiter && this._.line.length === 0 && (this._.field == null)) {\n if (wasCommenting || this.options.skip_empty_lines) {\n i += isRowDelimiterLength;\n this._.nextChar = chars.charAt(i);\n continue;\n }\n }\n if (rtrim) {\n if (!this._.closingQuote) {\n this._.field = (ref2 = this._.field) != null ? ref2.trimRight() : void 0;\n }\n }\n this._.line.push(cast(this._.field || ''));\n this._.closingQuote = 0;\n this._.field = null;\n if (isDelimiter) { // End of field\n i += this.options.delimiter.length;\n this._.nextChar = chars.charAt(i);\n if (end && !this._.nextChar) {\n isRowDelimiter = true;\n this._.line.push('');\n }\n }\n if (isRowDelimiter) { // End of record\n if (!this._.lineHasError) {\n err = this.__push(this._.line);\n if (err) {\n return err;\n }\n }\n if (this._.lineHasError) {\n this._.lineHasError = false;\n }\n // Some cleanup for the next record\n this._.line = [];\n i += isRowDelimiterLength;\n this._.nextChar = chars.charAt(i);\n continue;\n }\n } else if (!this._.commenting && !this._.quoting && (char === ' ' || char === '\\t')) {\n if (this._.field == null) {\n // Left trim unless we are quoting or field already filled\n this._.field = '';\n }\n if (!(ltrim && !this._.field)) {\n this._.field += char;\n }\n i++;\n } else if (!this._.commenting) {\n if (this._.field == null) {\n this._.field = '';\n }\n this._.field += char;\n i++;\n } else {\n i++;\n }\n if (!this._.commenting && ((ref3 = this._.field) != null ? ref3.length : void 0) > this.options.max_limit_on_data_read) {\n return Error(`Field exceeds max_limit_on_data_read setting (${this.options.max_limit_on_data_read}) ${JSON.stringify(this.options.delimiter)}`);\n }\n if (!this._.commenting && ((ref4 = this._.line) != null ? ref4.length : void 0) > this.options.max_limit_on_data_read) {\n return Error(`Row delimiter not found in the file ${JSON.stringify(this.options.rowDelimiter)}`);\n }\n }\n // Flush remaining fields and lines\n if (end) {\n if (l === 0) {\n this.lines++;\n }\n if (this._.field != null) {\n if (rtrim) {\n if (!this._.closingQuote) {\n this._.field = (ref5 = this._.field) != null ? ref5.trimRight() : void 0;\n }\n }\n this._.line.push(cast(this._.field || ''));\n this._.field = null;\n }\n if (((ref6 = this._.field) != null ? ref6.length : void 0) > this.options.max_limit_on_data_read) {\n return Error(`Delimiter not found in the file ${JSON.stringify(this.options.delimiter)}`);\n }\n if (this._.line.length > this.options.max_limit_on_data_read) {\n return Error(`Row delimiter not found in the file ${JSON.stringify(this.options.rowDelimiter)}`);\n }\n }\n // Store un-parsed chars for next call\n this._.buf = chars.substr(i);\n return null;\n};\n\nParser.prototype.error = function(msg) {\n var err;\n err = Error(msg);\n if (!this.options.skip_lines_with_error) {\n return err;\n } else {\n if (!this._.lineHasError) {\n this._.lineHasError = true;\n this.emit('skip', err);\n }\n }\n return null;\n};\n\n// ## Utils\nisObjLiteral = function(_obj) {\n var _test;\n _test = _obj;\n if (typeof _obj !== 'object' || _obj === null || Array.isArray(_obj)) {\n return false;\n } else {\n return (function() {\n while (!false) {\n if (Object.getPrototypeOf(_test = Object.getPrototypeOf(_test)) === null) {\n break;\n }\n }\n return Object.getPrototypeOf(_obj === _test);\n })();\n }\n};\n\n// [readme]: https://github.com/wdavidw/node-csv-parse\n// [site]: http://csv.adaltas.com/parse/\n// [samples]: https://github.com/wdavidw/node-csv-parse/tree/master/samples\n// [tests]: https://github.com/wdavidw/node-csv-parse/tree/master/test\n// [stream]: (http://nodejs.org/api/stream.html\n// [transform]: (http://nodejs.org/api/stream.html#stream_class_stream_transform_1)\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/csv-parse/lib/index.js\n// module id = 133\n// module chunks = 0","exports.read = function (buffer, offset, isLE, mLen, nBytes) {\n var e, m\n var eLen = nBytes * 8 - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var nBits = -7\n var i = isLE ? (nBytes - 1) : 0\n var d = isLE ? -1 : 1\n var s = buffer[offset + i]\n\n i += d\n\n e = s & ((1 << (-nBits)) - 1)\n s >>= (-nBits)\n nBits += eLen\n for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & ((1 << (-nBits)) - 1)\n e >>= (-nBits)\n nBits += mLen\n for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity)\n } else {\n m = m + Math.pow(2, mLen)\n e = e - eBias\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c\n var eLen = nBytes * 8 - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n var i = isLE ? 0 : (nBytes - 1)\n var d = isLE ? 1 : -1\n var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n value = Math.abs(value)\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0\n e = eMax\n } else {\n e = Math.floor(Math.log(value) / Math.LN2)\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--\n c *= 2\n }\n if (e + eBias >= 1) {\n value += rt / c\n } else {\n value += rt * Math.pow(2, 1 - eBias)\n }\n if (value * c >= 2) {\n e++\n c /= 2\n }\n\n if (e + eBias >= eMax) {\n m = 0\n e = eMax\n } else if (e + eBias >= 1) {\n m = (value * c - 1) * Math.pow(2, mLen)\n e = e + eBias\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n e = 0\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = (e << mLen) | m\n eLen += mLen\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/ieee754/index.js\n// module id = 134\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\nexports.Writer = exports.VexFlow = exports.Utils = exports.Track = exports.ProgramChangeEvent = exports.NoteOnEvent = exports.NoteOffEvent = exports.NoteEvent = exports.MetaEvent = exports.ControllerChangeEvent = exports.Constants = exports.Chunk = undefined;\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _tonalMidi = require('tonal-midi');\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Object representation of the chunk section of a MIDI file.\n * @param {object} fields - {type: number, data: array, size: array}\n * @return {Chunk}\n */\nvar Chunk = function Chunk(fields) {\n\t_classCallCheck(this, Chunk);\n\n\tthis.type = fields.type;\n\tthis.data = fields.data;\n\tthis.size = [0, 0, 0, fields.data.length];\n};\n\nexports.Chunk = Chunk;\n/**\n * MIDI file format constants, including note -> MIDI number translation.\n * @return {Constants}\n */\n\nvar Constants = {\n\tVERSION: '1.5.2',\n\tHEADER_CHUNK_TYPE: [0x4d, 0x54, 0x68, 0x64], // Mthd\n\tHEADER_CHUNK_LENGTH: [0x00, 0x00, 0x00, 0x06], // Header size for SMF\n\tHEADER_CHUNK_FORMAT0: [0x00, 0x00], // Midi Type 0 id\n\tHEADER_CHUNK_FORMAT1: [0x00, 0x01], // Midi Type 1 id\n\tHEADER_CHUNK_DIVISION: [0x00, 0x80], // Defaults to 128 ticks per beat\n\tTRACK_CHUNK_TYPE: [0x4d, 0x54, 0x72, 0x6b], // MTrk,\n\tMETA_EVENT_ID: 0xFF,\n\tMETA_TEXT_ID: 0x01,\n\tMETA_COPYRIGHT_ID: 0x02,\n\tMETA_TRACK_NAME_ID: 0x03,\n\tMETA_INSTRUMENT_NAME_ID: 0x04,\n\tMETA_LYRIC_ID: 0x05,\n\tMETA_MARKER_ID: 0x06,\n\tMETA_CUE_POINT: 0x07,\n\tMETA_TEMPO_ID: 0x51,\n\tMETA_SMTPE_OFFSET: 0x54,\n\tMETA_TIME_SIGNATURE_ID: 0x58,\n\tMETA_KEY_SIGNATURE_ID: 0x59,\n\tMETA_END_OF_TRACK_ID: [0x2F, 0x00],\n\tCONTROLLER_CHANGE_STATUS: 0xB0, // includes channel number (0)\n\tPROGRAM_CHANGE_STATUS: 0xC0 // includes channel number (0)\n};\n\nexports.Constants = Constants;\n/**\n * Holds all data for a \"controller change\" MIDI event\n * @param {object} fields {controllerNumber: integer, controllerValue: integer}\n * @return {ControllerChangeEvent}\n */\n\nvar ControllerChangeEvent = function ControllerChangeEvent(fields) {\n\t_classCallCheck(this, ControllerChangeEvent);\n\n\tthis.type = 'controller';\n\t// delta time defaults to 0.\n\tthis.data = Utils.numberToVariableLength(0x00).concat(Constants.CONTROLLER_CHANGE_STATUS, fields.controllerNumber, fields.controllerValue);\n};\n\nexports.ControllerChangeEvent = ControllerChangeEvent;\n/**\n * Object representation of a meta event.\n * @param {object} fields - type, data\n * @return {MetaEvent}\n */\n\nvar MetaEvent = function MetaEvent(fields) {\n\t_classCallCheck(this, MetaEvent);\n\n\tthis.type = 'meta';\n\tthis.data = Utils.numberToVariableLength(0x00); // Start with zero time delta\n\tthis.data = this.data.concat(Constants.META_EVENT_ID, fields.data);\n};\n\nexports.MetaEvent = MetaEvent;\n/**\n * Wrapper for noteOnEvent/noteOffEvent objects that builds both events.\n * @param {object} fields - {pitch: '[C4]', duration: '4', wait: '4', velocity: 1-100}\n * @return {NoteEvent}\n */\n\nvar NoteEvent = function () {\n\tfunction NoteEvent(fields) {\n\t\t_classCallCheck(this, NoteEvent);\n\n\t\tthis.type = 'note';\n\t\tthis.pitch = Utils.toArray(fields.pitch);\n\t\tthis.wait = fields.wait || 0;\n\t\tthis.duration = fields.duration;\n\t\tthis.sequential = fields.sequential || false;\n\t\tthis.velocity = fields.velocity || 50;\n\t\tthis.channel = fields.channel || 1;\n\t\tthis.repeat = fields.repeat || 1;\n\t\tthis.velocity = this.convertVelocity(this.velocity);\n\t\tthis.grace = fields.grace;\n\t\tthis.buildData();\n\t}\n\n\t/**\n * Builds int array for this event.\n * @return {NoteEvent}\n */\n\n\n\t_createClass(NoteEvent, [{\n\t\tkey: 'buildData',\n\t\tvalue: function buildData() {\n\t\t\tthis.data = [];\n\n\t\t\tvar tickDuration = this.getTickDuration(this.duration, 'note');\n\t\t\tvar restDuration = this.getTickDuration(this.wait, 'rest');\n\n\t\t\t// Apply grace note(s) and subtract ticks (currently 1 tick per grace note) from tickDuration so net value is the same\n\t\t\tif (this.grace) {\n\t\t\t\tvar graceDuration = 1;\n\t\t\t\tthis.grace = Utils.toArray(this.grace);\n\t\t\t\tthis.grace.forEach(function (pitch) {\n\t\t\t\t\tvar noteEvent = new NoteEvent({ pitch: this.grace, duration: 'T' + graceDuration });\n\t\t\t\t\tthis.data = this.data.concat(noteEvent.data);\n\n\t\t\t\t\ttickDuration -= graceDuration;\n\t\t\t\t}, this);\n\t\t\t}\n\n\t\t\t// fields.pitch could be an array of pitches.\n\t\t\t// If so create note events for each and apply the same duration.\n\t\t\tvar noteOn, noteOff;\n\t\t\tif (Array.isArray(this.pitch)) {\n\t\t\t\t// By default this is a chord if it's an array of notes that requires one NoteOnEvent.\n\t\t\t\t// If this.sequential === true then it's a sequential string of notes that requires separate NoteOnEvents.\n\t\t\t\tif (!this.sequential) {\n\t\t\t\t\t// Handle repeat\n\t\t\t\t\tfor (var j = 0; j < this.repeat; j++) {\n\t\t\t\t\t\t// Note on\n\t\t\t\t\t\tthis.pitch.forEach(function (p, i) {\n\t\t\t\t\t\t\tif (i == 0) {\n\t\t\t\t\t\t\t\tnoteOn = new NoteOnEvent({ data: Utils.numberToVariableLength(restDuration).concat(this.getNoteOnStatus(), Utils.getPitch(p), this.velocity) });\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Running status (can ommit the note on status)\n\t\t\t\t\t\t\t\tnoteOn = new NoteOnEvent({ data: [0, Utils.getPitch(p), this.velocity] });\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.data = this.data.concat(noteOn.data);\n\t\t\t\t\t\t}, this);\n\n\t\t\t\t\t\t// Note off\n\t\t\t\t\t\tthis.pitch.forEach(function (p, i) {\n\t\t\t\t\t\t\tif (i == 0) {\n\t\t\t\t\t\t\t\tnoteOff = new NoteOffEvent({ data: Utils.numberToVariableLength(tickDuration).concat(this.getNoteOffStatus(), Utils.getPitch(p), this.velocity) });\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Running status (can ommit the note off status)\n\t\t\t\t\t\t\t\tnoteOff = new NoteOffEvent({ data: [0, Utils.getPitch(p), this.velocity] });\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.data = this.data.concat(noteOff.data);\n\t\t\t\t\t\t}, this);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Handle repeat\n\t\t\t\t\tfor (var j = 0; j < this.repeat; j++) {\n\t\t\t\t\t\tthis.pitch.forEach(function (p, i) {\n\t\t\t\t\t\t\t// restDuration only applies to first note\n\t\t\t\t\t\t\tif (i > 0) {\n\t\t\t\t\t\t\t\trestDuration = 0;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// If duration is 8th triplets we need to make sure that the total ticks == quarter note.\n\t\t\t\t\t\t\t// So, the last one will need to be the remainder\n\t\t\t\t\t\t\tif (this.duration === '8t' && i == this.pitch.length - 1) {\n\t\t\t\t\t\t\t\tvar quarterTicks = Utils.numberFromBytes(Constants.HEADER_CHUNK_DIVISION);\n\t\t\t\t\t\t\t\ttickDuration = quarterTicks - tickDuration * 2;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tnoteOn = new NoteOnEvent({ data: Utils.numberToVariableLength(restDuration).concat([this.getNoteOnStatus(), Utils.getPitch(p), this.velocity]) });\n\t\t\t\t\t\t\tnoteOff = new NoteOffEvent({ data: Utils.numberToVariableLength(tickDuration).concat([this.getNoteOffStatus(), Utils.getPitch(p), this.velocity]) });\n\n\t\t\t\t\t\t\tthis.data = this.data.concat(noteOn.data, noteOff.data);\n\t\t\t\t\t\t}, this);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t}\n\n\t\t\tthrow 'pitch must be an array.';\n\t\t}\n\t}, {\n\t\tkey: 'convertVelocity',\n\n\n\t\t/**\n * Converts velocity to value 0-127\n * @param {number} velocity - Velocity value 1-100\n * @return {number}\n */\n\t\tvalue: function convertVelocity(velocity) {\n\t\t\t// Max passed value limited to 100\n\t\t\tvelocity = velocity > 100 ? 100 : velocity;\n\t\t\treturn Math.round(velocity / 100 * 127);\n\t\t}\n\t}, {\n\t\tkey: 'getTickDuration',\n\n\n\t\t/**\n * Gets the total number of ticks based on passed duration.\n * Note: type=='note' defaults to quarter note, type==='rest' defaults to 0\n * @param {(string|array)} duration\n * @param {string} type ['note', 'rest']\n * @return {number}\n */\n\t\tvalue: function getTickDuration(duration, type) {\n\t\t\tif (Array.isArray(duration)) {\n\t\t\t\t// Recursively execute this method for each item in the array and return the sum of tick durations.\n\t\t\t\treturn duration.map(function (value) {\n\t\t\t\t\treturn this.getTickDuration(value, type);\n\t\t\t\t}, this).reduce(function (a, b) {\n\t\t\t\t\treturn a + b;\n\t\t\t\t}, 0);\n\t\t\t}\n\n\t\t\tduration = duration.toString();\n\n\t\t\tif (duration.toLowerCase().charAt(0) === 't') {\n\t\t\t\t// If duration starts with 't' then the number that follows is an explicit tick count\n\t\t\t\treturn parseInt(duration.substring(1));\n\t\t\t}\n\n\t\t\t// Need to apply duration here. Quarter note == Constants.HEADER_CHUNK_DIVISION\n\t\t\t// Rounding only applies to triplets, which the remainder is handled below\n\t\t\tvar quarterTicks = Utils.numberFromBytes(Constants.HEADER_CHUNK_DIVISION);\n\t\t\treturn Math.round(quarterTicks * this.getDurationMultiplier(duration, type));\n\t\t}\n\n\t\t/**\n * Gets what to multiple ticks/quarter note by to get the specified duration.\n * Note: type=='note' defaults to quarter note, type==='rest' defaults to 0\n * @param {string} duration\n * @param {string} type ['note','rest']\n * @return {number}\n */\n\n\t}, {\n\t\tkey: 'getDurationMultiplier',\n\t\tvalue: function getDurationMultiplier(duration, type) {\n\t\t\t// Need to apply duration here. Quarter note == Constants.HEADER_CHUNK_DIVISION\n\t\t\tswitch (duration) {\n\t\t\t\tcase '0':\n\t\t\t\t\treturn 0;\n\t\t\t\tcase '1':\n\t\t\t\t\treturn 4;\n\t\t\t\tcase '2':\n\t\t\t\t\treturn 2;\n\t\t\t\tcase 'd2':\n\t\t\t\t\treturn 3;\n\t\t\t\tcase '4':\n\t\t\t\t\treturn 1;\n\t\t\t\tcase '4t':\n\t\t\t\t\treturn 0.666;\n\t\t\t\tcase 'd4':\n\t\t\t\t\treturn 1.5;\n\t\t\t\tcase '8':\n\t\t\t\t\treturn 0.5;\n\t\t\t\tcase '8t':\n\t\t\t\t\t// For 8th triplets, let's divide a quarter by 3, round to the nearest int, and substract the remainder to the last one.\n\t\t\t\t\treturn 0.33;\n\t\t\t\tcase 'd8':\n\t\t\t\t\treturn 0.75;\n\t\t\t\tcase '16':\n\t\t\t\t\treturn 0.25;\n\t\t\t\tcase '16t':\n\t\t\t\t\treturn 0.166;\n\t\t\t\tcase '32':\n\t\t\t\t\treturn 0.125;\n\t\t\t\tcase '64':\n\t\t\t\t\treturn 0.0625;\n\t\t\t\tdefault:\n\t\t\t\t// Notes default to a quarter, rests default to 0\n\t\t\t\t//return type === 'note' ? 1 : 0;\n\t\t\t}\n\n\t\t\tthrow duration + ' is not a valid duration.';\n\t\t}\n\t}, {\n\t\tkey: 'getNoteOnStatus',\n\n\n\t\t/**\n * Gets the note on status code based on the selected channel. 0x9{0-F}\n * Note on at channel 0 is 0x90 (144)\n * 0 = Ch 1\n * @return {number}\n */\n\t\tvalue: function getNoteOnStatus() {\n\t\t\treturn 144 + this.channel - 1;\n\t\t}\n\n\t\t/**\n * Gets the note off status code based on the selected channel. 0x8{0-F}\n * Note off at channel 0 is 0x80 (128)\n * 0 = Ch 1\n * @return {number}\n */\n\n\t}, {\n\t\tkey: 'getNoteOffStatus',\n\t\tvalue: function getNoteOffStatus() {\n\t\t\treturn 128 + this.channel - 1;\n\t\t}\n\t}]);\n\n\treturn NoteEvent;\n}();\n\nexports.NoteEvent = NoteEvent;\n/**\n * Holds all data for a \"note off\" MIDI event\n * @param {object} fields {data: []}\n * @return {NoteOffEvent}\n */\n\nvar NoteOffEvent = function NoteOffEvent(fields) {\n\t_classCallCheck(this, NoteOffEvent);\n\n\tthis.data = fields.data;\n};\n\nexports.NoteOffEvent = NoteOffEvent;\n/**\n * Holds all data for a \"note on\" MIDI event\n * @param {object} fields {data: []}\n * @return {NoteOnEvent}\n */\n\nvar NoteOnEvent = function NoteOnEvent(fields) {\n\t_classCallCheck(this, NoteOnEvent);\n\n\tthis.data = fields.data;\n};\n\nexports.NoteOnEvent = NoteOnEvent;\n/**\n * Holds all data for a \"program change\" MIDI event\n * @param {object} fields {instrument: integer}\n * @return {ProgramChangeEvent}\n */\n\nvar ProgramChangeEvent = function ProgramChangeEvent(fields) {\n\t_classCallCheck(this, ProgramChangeEvent);\n\n\tthis.type = 'program';\n\t// delta time defaults to 0.\n\tthis.data = Utils.numberToVariableLength(0x00).concat(Constants.PROGRAM_CHANGE_STATUS, fields.instrument);\n};\n\nexports.ProgramChangeEvent = ProgramChangeEvent;\n/**\n * Holds all data for a track.\n * @param {object} fields {type: number, data: array, size: array, events: array}\n * @return {Track}\n */\n\nvar Track = function () {\n\tfunction Track() {\n\t\t_classCallCheck(this, Track);\n\n\t\tthis.type = Constants.TRACK_CHUNK_TYPE;\n\t\tthis.data = [];\n\t\tthis.size = [];\n\t\tthis.events = [];\n\t}\n\n\t/**\n * Adds any event type to the track.\n * @param {(NoteEvent|MetaEvent|ProgramChangeEvent)} event - Event object.\n * @param {function} mapFunction - Callback which can be used to apply specific properties to all events. \n * @return {Track}\n */\n\n\n\t_createClass(Track, [{\n\t\tkey: 'addEvent',\n\t\tvalue: function addEvent(event, mapFunction) {\n\t\t\tif (Array.isArray(event)) {\n\t\t\t\tevent.forEach(function (e, i) {\n\t\t\t\t\t// Handle map function if provided\n\t\t\t\t\tif (typeof mapFunction === 'function' && e.type === 'note') {\n\t\t\t\t\t\tvar properties = mapFunction(i, e);\n\n\t\t\t\t\t\tif ((typeof properties === 'undefined' ? 'undefined' : _typeof(properties)) === 'object') {\n\t\t\t\t\t\t\tfor (var j in properties) {\n\t\t\t\t\t\t\t\tswitch (j) {\n\t\t\t\t\t\t\t\t\tcase 'duration':\n\t\t\t\t\t\t\t\t\t\te.duration = properties[j];\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'sequential':\n\t\t\t\t\t\t\t\t\t\te.sequential = properties[j];\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'velocity':\n\t\t\t\t\t\t\t\t\t\te.velocity = e.convertVelocity(properties[j]);\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Gotta build that data\n\t\t\t\t\t\t\te.buildData();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.data = this.data.concat(e.data);\n\t\t\t\t\tthis.size = Utils.numberToBytes(this.data.length, 4); // 4 bytes long\n\t\t\t\t\tthis.events.push(e);\n\t\t\t\t}, this);\n\t\t\t} else {\n\t\t\t\tthis.data = this.data.concat(event.data);\n\t\t\t\tthis.size = Utils.numberToBytes(this.data.length, 4); // 4 bytes long\n\t\t\t\tthis.events.push(event);\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\t/**\n * Sets tempo of the MIDI file.\n * @param {number} bpm - Tempo in beats per minute.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'setTempo',\n\t\tvalue: function setTempo(bpm) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_TEMPO_ID] });\n\t\t\tevent.data.push(0x03); // Size\n\t\t\tvar tempo = Math.round(60000000 / bpm);\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(tempo, 3)); // Tempo, 3 bytes\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Sets time signature.\n * @param {number} numerator - Top number of the time signature.\n * @param {number} denominator - Bottom number of the time signature.\n * @param {number} midiclockspertick - Defaults to 24.\n * @param {number} notespermidiclock - Defaults to 8.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'setTimeSignature',\n\t\tvalue: function setTimeSignature(numerator, denominator, midiclockspertick, notespermidiclock) {\n\t\t\tmidiclockspertick = midiclockspertick || 24;\n\t\t\tnotespermidiclock = notespermidiclock || 8;\n\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_TIME_SIGNATURE_ID] });\n\t\t\tevent.data.push(0x04); // Size\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(numerator, 1)); // Numerator, 1 bytes\n\n\t\t\tvar _denominator = Math.log2(denominator); // Denominator is expressed as pow of 2\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(_denominator, 1)); // Denominator, 1 bytes\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(midiclockspertick, 1)); // MIDI Clocks per tick, 1 bytes\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(notespermidiclock, 1)); // Number of 1/32 notes per MIDI clocks, 1 bytes\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Sets key signature.\n * @param {*} sf - \n * @param {*} mi -\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'setKeySignature',\n\t\tvalue: function setKeySignature(sf, mi) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_KEY_SIGNATURE_ID] });\n\t\t\tevent.data.push(0x02); // Size\n\n\t\t\tvar mode = mi || 0;\n\t\t\tsf = sf || 0;\n\n\t\t\t//\tFunction called with string notation\n\t\t\tif (typeof mi === 'undefined') {\n\t\t\t\tvar fifths = [['Cb', 'Gb', 'Db', 'Ab', 'Eb', 'Bb', 'F', 'C', 'G', 'D', 'A', 'E', 'B', 'F#', 'C#'], ['ab', 'eb', 'bb', 'f', 'c', 'g', 'd', 'a', 'e', 'b', 'f#', 'c#', 'g#', 'd#', 'a#']];\n\t\t\t\tvar _sflen = sf.length;\n\t\t\t\tvar note = sf || 'C';\n\n\t\t\t\tif (sf[0] === sf[0].toLowerCase()) mode = 1;\n\n\t\t\t\tif (_sflen > 1) {\n\t\t\t\t\tswitch (sf.charAt(_sflen - 1)) {\n\t\t\t\t\t\tcase 'm':\n\t\t\t\t\t\t\tmode = 1;\n\t\t\t\t\t\t\tnote = sf.charAt(0).toLowerCase();\n\t\t\t\t\t\t\tnote = note.concat(sf.substring(1, _sflen - 1));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '-':\n\t\t\t\t\t\t\tmode = 1;\n\t\t\t\t\t\t\tnote = sf.charAt(0).toLowerCase();\n\t\t\t\t\t\t\tnote = note.concat(sf.substring(1, _sflen - 1));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'M':\n\t\t\t\t\t\t\tmode = 0;\n\t\t\t\t\t\t\tnote = sf.charAt(0).toUpperCase();\n\t\t\t\t\t\t\tnote = note.concat(sf.substring(1, _sflen - 1));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '+':\n\t\t\t\t\t\t\tmode = 0;\n\t\t\t\t\t\t\tnote = sf.charAt(0).toUpperCase();\n\t\t\t\t\t\t\tnote = note.concat(sf.substring(1, _sflen - 1));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar fifthindex = fifths[mode].indexOf(note);\n\t\t\t\tsf = fifthindex === -1 ? 0 : fifthindex - 7;\n\t\t\t}\n\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(sf, 1)); // Number of sharp or flats ( < 0 flat; > 0 sharp)\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(mode, 1)); // Mode: 0 major, 1 minor\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Adds text to MIDI file.\n * @param {string} text - Text to add.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addText',\n\t\tvalue: function addText(text) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_TEXT_ID] });\n\t\t\tvar stringBytes = Utils.stringToBytes(text);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Text\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Adds copyright to MIDI file.\n * @param {string} text - Text of copyright line.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addCopyright',\n\t\tvalue: function addCopyright(text) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_COPYRIGHT_ID] });\n\t\t\tvar stringBytes = Utils.stringToBytes(text);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Text\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Adds Sequence/Track Name.\n * @param {string} text - Text of track name.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addTrackName',\n\t\tvalue: function addTrackName(text) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_TRACK_NAME_ID] });\n\t\t\tvar stringBytes = Utils.stringToBytes(text);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Text\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Sets instrument name of track.\n * @param {string} text - Name of instrument.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addInstrumentName',\n\t\tvalue: function addInstrumentName(text) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_INSTRUMENT_NAME_ID] });\n\t\t\tvar stringBytes = Utils.stringToBytes(text);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Text\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Adds marker to MIDI file.\n * @param {string} text - Marker text.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addMarker',\n\t\tvalue: function addMarker(text) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_MARKER_ID] });\n\t\t\tvar stringBytes = Utils.stringToBytes(text);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Text\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Adds cue point to MIDI file.\n * @param {string} text - Text of cue point.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addCuePoint',\n\t\tvalue: function addCuePoint(text) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_CUE_POINT] });\n\t\t\tvar stringBytes = Utils.stringToBytes(text);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Text\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Adds lyric to MIDI file.\n * @param {string} lyric - Lyric text to add.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addLyric',\n\t\tvalue: function addLyric(lyric) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_LYRIC_ID] });\n\t\t\tvar stringBytes = Utils.stringToBytes(lyric);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Lyric\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Channel mode messages\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'polyModeOn',\n\t\tvalue: function polyModeOn() {\n\t\t\tvar event = new NoteOnEvent({ data: [0x00, 0xB0, 0x7E, 0x00] });\n\t\t\treturn this.addEvent(event);\n\t\t}\n\t}]);\n\n\treturn Track;\n}();\n\nexports.Track = Track;\n\n/**\n * Static utility functions used throughout the library.\n */\nvar Utils = function () {\n\tfunction Utils() {\n\t\t_classCallCheck(this, Utils);\n\t}\n\n\t_createClass(Utils, null, [{\n\t\tkey: 'version',\n\n\n\t\t/**\n * Gets MidiWriterJS version number.\n * @return {string}\n */\n\t\tvalue: function version() {\n\t\t\treturn Constants.VERSION;\n\t\t}\n\n\t\t/**\n * Convert a string to an array of bytes\n * @param {string} string\n * @return {array}\n */\n\n\t}, {\n\t\tkey: 'stringToBytes',\n\t\tvalue: function stringToBytes(string) {\n\t\t\treturn string.split('').map(function (char) {\n\t\t\t\treturn char.charCodeAt();\n\t\t\t});\n\t\t}\n\n\t\t/**\n * Checks if argument is a valid number.\n * @param {*} n - Value to check\n * @return {boolean}\n */\n\n\t}, {\n\t\tkey: 'isNumeric',\n\t\tvalue: function isNumeric(n) {\n\t\t\treturn !isNaN(parseFloat(n)) && isFinite(n);\n\t\t}\n\n\t\t/**\n * Returns the correct MIDI number for the specified pitch.\n * Uses Tonal Midi - https://github.com/danigb/tonal/tree/master/packages/midi\n * @param {(string|number)} pitch - 'C#4' or midi note code\n * @return {number}\n */\n\n\t}, {\n\t\tkey: 'getPitch',\n\t\tvalue: function getPitch(pitch) {\n\t\t\treturn (0, _tonalMidi.toMidi)(pitch);\n\t\t}\n\n\t\t/**\n * Translates number of ticks to MIDI timestamp format, returning an array of\n * hex strings with the time values. Midi has a very particular time to express time,\n * take a good look at the spec before ever touching this function.\n * Thanks to https://github.com/sergi/jsmidi\n *\n * @param {number} ticks - Number of ticks to be translated\n * @return {array} - Bytes that form the MIDI time value\n */\n\n\t}, {\n\t\tkey: 'numberToVariableLength',\n\t\tvalue: function numberToVariableLength(ticks) {\n\t\t\tvar buffer = ticks & 0x7F;\n\n\t\t\twhile (ticks = ticks >> 7) {\n\t\t\t\tbuffer <<= 8;\n\t\t\t\tbuffer |= ticks & 0x7F | 0x80;\n\t\t\t}\n\n\t\t\tvar bList = [];\n\t\t\twhile (true) {\n\t\t\t\tbList.push(buffer & 0xff);\n\n\t\t\t\tif (buffer & 0x80) buffer >>= 8;else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn bList;\n\t\t}\n\n\t\t/**\n * Counts number of bytes in string\n * @param {string} s\n * @return {array}\n */\n\n\t}, {\n\t\tkey: 'stringByteCount',\n\t\tvalue: function stringByteCount(s) {\n\t\t\treturn encodeURI(s).split(/%..|./).length - 1;\n\t\t}\n\n\t\t/**\n * Get an int from an array of bytes.\n * @param {array} bytes\n * @return {number}\n */\n\n\t}, {\n\t\tkey: 'numberFromBytes',\n\t\tvalue: function numberFromBytes(bytes) {\n\t\t\tvar hex = '';\n\t\t\tvar stringResult;\n\n\t\t\tbytes.forEach(function (byte) {\n\t\t\t\tstringResult = byte.toString(16);\n\n\t\t\t\t// ensure string is 2 chars\n\t\t\t\tif (stringResult.length == 1) stringResult = \"0\" + stringResult;\n\n\t\t\t\thex += stringResult;\n\t\t\t});\n\n\t\t\treturn parseInt(hex, 16);\n\t\t}\n\n\t\t/**\n * Takes a number and splits it up into an array of bytes. Can be padded by passing a number to bytesNeeded\n * @param {number} number\n * @param {number} bytesNeeded\n * @return {array} - Array of bytes\n */\n\n\t}, {\n\t\tkey: 'numberToBytes',\n\t\tvalue: function numberToBytes(number, bytesNeeded) {\n\t\t\tbytesNeeded = bytesNeeded || 1;\n\n\t\t\tvar hexString = number.toString(16);\n\n\t\t\tif (hexString.length & 1) {\n\t\t\t\t// Make sure hex string is even number of chars\n\t\t\t\thexString = '0' + hexString;\n\t\t\t}\n\n\t\t\t// Split hex string into an array of two char elements\n\t\t\tvar hexArray = hexString.match(/.{2}/g);\n\n\t\t\t// Now parse them out as integers\n\t\t\thexArray = hexArray.map(function (item) {\n\t\t\t\treturn parseInt(item, 16);\n\t\t\t});\n\n\t\t\t// Prepend empty bytes if we don't have enough\n\t\t\tif (hexArray.length < bytesNeeded) {\n\t\t\t\twhile (bytesNeeded - hexArray.length > 0) {\n\t\t\t\t\thexArray.unshift(0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn hexArray;\n\t\t}\n\n\t\t/**\t\n * Converts value to array if needed.\n * @param {string} value\n * @return {array}\n */\n\n\t}, {\n\t\tkey: 'toArray',\n\t\tvalue: function toArray(value) {\n\t\t\tif (Array.isArray(value)) return value;\n\t\t\treturn [value];\n\t\t}\n\t}]);\n\n\treturn Utils;\n}();\n\nexports.Utils = Utils;\n\nvar VexFlow = function () {\n\tfunction VexFlow() {\n\t\t_classCallCheck(this, VexFlow);\n\t}\n\t// code...\n\n\n\t/**\n * Support for converting VexFlow voice into MidiWriterJS track\n * @return MidiWritier.Track object\n */\n\n\n\t_createClass(VexFlow, [{\n\t\tkey: 'trackFromVoice',\n\t\tvalue: function trackFromVoice(voice) {\n\t\t\tvar track = new Track();\n\t\t\tvar wait;\n\t\t\tvar pitches = [];\n\n\t\t\tvoice.tickables.forEach(function (tickable) {\n\t\t\t\tpitches = [];\n\n\t\t\t\tif (tickable.noteType === 'n') {\n\t\t\t\t\ttickable.keys.forEach(function (key) {\n\t\t\t\t\t\t// build array of pitches\n\t\t\t\t\t\tpitches.push(this.convertPitch(key));\n\t\t\t\t\t});\n\t\t\t\t} else if (tickable.noteType === 'r') {\n\t\t\t\t\t// move on to the next tickable and use this rest as a `wait` property for the next event\n\t\t\t\t\twait = this.convertDuration(tickable);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\ttrack.addEvent(new NoteEvent({ pitch: pitches, duration: this.convertDuration(tickable), wait: wait }));\n\n\t\t\t\t// reset wait\n\t\t\t\twait = 0;\n\t\t\t});\n\n\t\t\treturn track;\n\t\t}\n\n\t\t/**\n * Converts VexFlow pitch syntax to MidiWriterJS syntax\n * @param pitch string\n */\n\n\t}, {\n\t\tkey: 'convertPitch',\n\t\tvalue: function convertPitch(pitch) {\n\t\t\treturn pitch.replace('/', '');\n\t\t}\n\n\t\t/**\n * Converts VexFlow duration syntax to MidiWriterJS syntax\n * @param note struct from VexFlow\n */\n\n\t}, {\n\t\tkey: 'convertDuration',\n\t\tvalue: function convertDuration(note) {\n\t\t\tswitch (note.duration) {\n\t\t\t\tcase 'w':\n\t\t\t\t\treturn '1';\n\t\t\t\tcase 'h':\n\t\t\t\t\treturn note.isDotted() ? 'd2' : '2';\n\t\t\t\tcase 'q':\n\t\t\t\t\treturn note.isDotted() ? 'd4' : '4';\n\t\t\t\tcase '8':\n\t\t\t\t\treturn note.isDotted() ? 'd8' : '8';\n\t\t\t}\n\n\t\t\treturn note.duration;\n\t\t}\n\t}]);\n\n\treturn VexFlow;\n}();\n\nexports.VexFlow = VexFlow;\n/**\n * Object that puts together tracks and provides methods for file output.\n * @param {array} tracks - An array of {Track} objects.\n * @return {Writer}\n */\n\nvar Writer = function () {\n\tfunction Writer(tracks) {\n\t\t_classCallCheck(this, Writer);\n\n\t\tthis.data = [];\n\n\t\tvar trackType = tracks.length > 1 ? Constants.HEADER_CHUNK_FORMAT1 : Constants.HEADER_CHUNK_FORMAT0;\n\t\tvar numberOfTracks = Utils.numberToBytes(tracks.length, 2); // two bytes long\n\n\t\t// Header chunk\n\t\tthis.data.push(new Chunk({\n\t\t\ttype: Constants.HEADER_CHUNK_TYPE,\n\t\t\tdata: trackType.concat(numberOfTracks, Constants.HEADER_CHUNK_DIVISION) }));\n\n\t\t// Track chunks\n\t\ttracks.forEach(function (track, i) {\n\t\t\ttrack.addEvent(new MetaEvent({ data: Constants.META_END_OF_TRACK_ID }));\n\t\t\tthis.data.push(track);\n\t\t}, this);\n\t}\n\n\t/**\n * Builds the file into a Uint8Array\n * @return {Uint8Array}\n */\n\n\n\t_createClass(Writer, [{\n\t\tkey: 'buildFile',\n\t\tvalue: function buildFile() {\n\t\t\tvar build = [];\n\n\t\t\t// Data consists of chunks which consists of data\n\t\t\tthis.data.forEach(function (d) {\n\t\t\t\treturn build = build.concat(d.type, d.size, d.data);\n\t\t\t});\n\n\t\t\treturn new Uint8Array(build);\n\t\t}\n\n\t\t/**\n * Convert file buffer to a base64 string. Different methods depending on if browser or node.\n * @return {string}\n */\n\n\t}, {\n\t\tkey: 'base64',\n\t\tvalue: function base64() {\n\t\t\tif (typeof btoa === 'function') return btoa(String.fromCharCode.apply(null, this.buildFile()));\n\t\t\treturn new Buffer(this.buildFile()).toString('base64');\n\t\t}\n\n\t\t/**\n * Get the data URI.\n * @return {string}\n */\n\n\t}, {\n\t\tkey: 'dataUri',\n\t\tvalue: function dataUri() {\n\t\t\treturn 'data:audio/midi;base64,' + this.base64();\n\t\t}\n\n\t\t/**\n * Output to stdout\n * @return {string}\n */\n\n\t}, {\n\t\tkey: 'stdout',\n\t\tvalue: function stdout() {\n\t\t\treturn process.stdout.write(new Buffer(this.buildFile()));\n\t\t}\n\n\t\t/**\n * Save to MIDI file\n * @param {string} filename\n */\n\n\t}, {\n\t\tkey: 'saveMIDI',\n\t\tvalue: function saveMIDI(filename) {\n\t\t\tvar buffer = new Buffer(this.buildFile());\n\t\t\tfs.writeFile(filename + '.mid', buffer, function (err) {\n\t\t\t\tif (err) return console.log(err);\n\t\t\t});\n\t\t}\n\t}]);\n\n\treturn Writer;\n}();\n\nexports.Writer = Writer;\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbIkNodW5rIiwiZmllbGRzIiwidHlwZSIsImRhdGEiLCJzaXplIiwibGVuZ3RoIiwiQ29uc3RhbnRzIiwiVkVSU0lPTiIsIkhFQURFUl9DSFVOS19UWVBFIiwiSEVBREVSX0NIVU5LX0xFTkdUSCIsIkhFQURFUl9DSFVOS19GT1JNQVQwIiwiSEVBREVSX0NIVU5LX0ZPUk1BVDEiLCJIRUFERVJfQ0hVTktfRElWSVNJT04iLCJUUkFDS19DSFVOS19UWVBFIiwiTUVUQV9FVkVOVF9JRCIsIk1FVEFfVEVYVF9JRCIsIk1FVEFfQ09QWVJJR0hUX0lEIiwiTUVUQV9UUkFDS19OQU1FX0lEIiwiTUVUQV9JTlNUUlVNRU5UX05BTUVfSUQiLCJNRVRBX0xZUklDX0lEIiwiTUVUQV9NQVJLRVJfSUQiLCJNRVRBX0NVRV9QT0lOVCIsIk1FVEFfVEVNUE9fSUQiLCJNRVRBX1NNVFBFX09GRlNFVCIsIk1FVEFfVElNRV9TSUdOQVRVUkVfSUQiLCJNRVRBX0tFWV9TSUdOQVRVUkVfSUQiLCJNRVRBX0VORF9PRl9UUkFDS19JRCIsIkNPTlRST0xMRVJfQ0hBTkdFX1NUQVRVUyIsIlBST0dSQU1fQ0hBTkdFX1NUQVRVUyIsIkNvbnRyb2xsZXJDaGFuZ2VFdmVudCIsIlV0aWxzIiwibnVtYmVyVG9WYXJpYWJsZUxlbmd0aCIsImNvbmNhdCIsImNvbnRyb2xsZXJOdW1iZXIiLCJjb250cm9sbGVyVmFsdWUiLCJNZXRhRXZlbnQiLCJOb3RlRXZlbnQiLCJwaXRjaCIsInRvQXJyYXkiLCJ3YWl0IiwiZHVyYXRpb24iLCJzZXF1ZW50aWFsIiwidmVsb2NpdHkiLCJjaGFubmVsIiwicmVwZWF0IiwiY29udmVydFZlbG9jaXR5IiwiZ3JhY2UiLCJidWlsZERhdGEiLCJ0aWNrRHVyYXRpb24iLCJnZXRUaWNrRHVyYXRpb24iLCJyZXN0RHVyYXRpb24iLCJncmFjZUR1cmF0aW9uIiwiZm9yRWFjaCIsIm5vdGVFdmVudCIsIm5vdGVPbiIsIm5vdGVPZmYiLCJBcnJheSIsImlzQXJyYXkiLCJqIiwicCIsImkiLCJOb3RlT25FdmVudCIsImdldE5vdGVPblN0YXR1cyIsImdldFBpdGNoIiwiTm90ZU9mZkV2ZW50IiwiZ2V0Tm90ZU9mZlN0YXR1cyIsInF1YXJ0ZXJUaWNrcyIsIm51bWJlckZyb21CeXRlcyIsIk1hdGgiLCJyb3VuZCIsIm1hcCIsInZhbHVlIiwicmVkdWNlIiwiYSIsImIiLCJ0b1N0cmluZyIsInRvTG93ZXJDYXNlIiwiY2hhckF0IiwicGFyc2VJbnQiLCJzdWJzdHJpbmciLCJnZXREdXJhdGlvbk11bHRpcGxpZXIiLCJQcm9ncmFtQ2hhbmdlRXZlbnQiLCJpbnN0cnVtZW50IiwiVHJhY2siLCJldmVudHMiLCJldmVudCIsIm1hcEZ1bmN0aW9uIiwiZSIsInByb3BlcnRpZXMiLCJudW1iZXJUb0J5dGVzIiwicHVzaCIsImJwbSIsInRlbXBvIiwiYWRkRXZlbnQiLCJudW1lcmF0b3IiLCJkZW5vbWluYXRvciIsIm1pZGljbG9ja3NwZXJ0aWNrIiwibm90ZXNwZXJtaWRpY2xvY2siLCJfZGVub21pbmF0b3IiLCJsb2cyIiwic2YiLCJtaSIsIm1vZGUiLCJmaWZ0aHMiLCJfc2ZsZW4iLCJub3RlIiwidG9VcHBlckNhc2UiLCJmaWZ0aGluZGV4IiwiaW5kZXhPZiIsInRleHQiLCJzdHJpbmdCeXRlcyIsInN0cmluZ1RvQnl0ZXMiLCJseXJpYyIsInN0cmluZyIsInNwbGl0IiwiY2hhciIsImNoYXJDb2RlQXQiLCJuIiwiaXNOYU4iLCJwYXJzZUZsb2F0IiwiaXNGaW5pdGUiLCJ0aWNrcyIsImJ1ZmZlciIsImJMaXN0IiwicyIsImVuY29kZVVSSSIsImJ5dGVzIiwiaGV4Iiwic3RyaW5nUmVzdWx0IiwiYnl0ZSIsIm51bWJlciIsImJ5dGVzTmVlZGVkIiwiaGV4U3RyaW5nIiwiaGV4QXJyYXkiLCJtYXRjaCIsIml0ZW0iLCJ1bnNoaWZ0IiwiVmV4RmxvdyIsInZvaWNlIiwidHJhY2siLCJwaXRjaGVzIiwidGlja2FibGVzIiwidGlja2FibGUiLCJub3RlVHlwZSIsImtleXMiLCJrZXkiLCJjb252ZXJ0UGl0Y2giLCJjb252ZXJ0RHVyYXRpb24iLCJyZXBsYWNlIiwiaXNEb3R0ZWQiLCJXcml0ZXIiLCJ0cmFja3MiLCJ0cmFja1R5cGUiLCJudW1iZXJPZlRyYWNrcyIsImJ1aWxkIiwiZCIsIlVpbnQ4QXJyYXkiLCJidG9hIiwiU3RyaW5nIiwiZnJvbUNoYXJDb2RlIiwiYXBwbHkiLCJidWlsZEZpbGUiLCJCdWZmZXIiLCJiYXNlNjQiLCJwcm9jZXNzIiwic3Rkb3V0Iiwid3JpdGUiLCJmaWxlbmFtZSIsImZzIiwid3JpdGVGaWxlIiwiZXJyIiwiY29uc29sZSIsImxvZyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFza0JBOzs7O0FBdGtCQTs7Ozs7SUFLTUEsSyxHQUNMLGVBQVlDLE1BQVosRUFBb0I7QUFBQTs7QUFDbkIsTUFBS0MsSUFBTCxHQUFZRCxPQUFPQyxJQUFuQjtBQUNBLE1BQUtDLElBQUwsR0FBWUYsT0FBT0UsSUFBbkI7QUFDQSxNQUFLQyxJQUFMLEdBQVksQ0FBQyxDQUFELEVBQUksQ0FBSixFQUFPLENBQVAsRUFBVUgsT0FBT0UsSUFBUCxDQUFZRSxNQUF0QixDQUFaO0FBQ0EsQzs7UUFHTUwsSyxHQUFBQSxLO0FBQ1I7Ozs7O0FBS0EsSUFBSU0sWUFBWTtBQUNmQyxVQUFjLE9BREM7QUFFZkMsb0JBQXVCLENBQUMsSUFBRCxFQUFPLElBQVAsRUFBYSxJQUFiLEVBQW1CLElBQW5CLENBRlIsRUFFa0M7QUFDakRDLHNCQUF3QixDQUFDLElBQUQsRUFBTyxJQUFQLEVBQWEsSUFBYixFQUFtQixJQUFuQixDQUhULEVBR21DO0FBQ2xEQyx1QkFBMEIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQUpYLEVBSXlCO0FBQ3hDQyx1QkFBMEIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQUxYLEVBS3lCO0FBQ3hDQyx3QkFBMEIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQU5YLEVBTXlCO0FBQ3hDQyxtQkFBb0IsQ0FBQyxJQUFELEVBQU8sSUFBUCxFQUFh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QUFLQyxPQUFPQyxZQUFQLENBQW9CQyxLQUFwQixDQUEwQixJQUExQixFQUFnQyxLQUFLQyxTQUFMLEVBQWhDLENBQUwsQ0FBUDtBQUNoQyxVQUFPLElBQUlDLE1BQUosQ0FBVyxLQUFLRCxTQUFMLEVBQVgsRUFBNkJ0RixRQUE3QixDQUFzQyxRQUF0QyxDQUFQO0FBQ0E7O0FBRUU7Ozs7Ozs7NEJBSVU7QUFDVCxVQUFPLDRCQUE0QixLQUFLd0YsTUFBTCxFQUFuQztBQUNBOztBQUVKOzs7Ozs7OzJCQUlZO0FBQ1IsVUFBT0MsUUFBUUMsTUFBUixDQUFlQyxLQUFmLENBQXFCLElBQUlKLE1BQUosQ0FBVyxLQUFLRCxTQUFMLEVBQVgsQ0FBckIsQ0FBUDtBQUNBOztBQUVKOzs7Ozs7OzJCQUlTTSxRLEVBQVU7QUFDbEIsT0FBSTdDLFNBQVMsSUFBSXdDLE1BQUosQ0FBVyxLQUFLRCxTQUFMLEVBQVgsQ0FBYjtBQUNBTyxNQUFHQyxTQUFILENBQWFGLFdBQVcsTUFBeEIsRUFBZ0M3QyxNQUFoQyxFQUF3QyxVQUFVZ0QsR0FBVixFQUFlO0FBQ3RELFFBQUdBLEdBQUgsRUFBUSxPQUFPQyxRQUFRQyxHQUFSLENBQVlGLEdBQVosQ0FBUDtBQUNSLElBRkQ7QUFHQTs7Ozs7O1FBR01wQixNLEdBQUFBLE0iLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE9iamVjdCByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2h1bmsgc2VjdGlvbiBvZiBhIE1JREkgZmlsZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMgLSB7dHlwZTogbnVtYmVyLCBkYXRhOiBhcnJheSwgc2l6ZTogYXJyYXl9XG4gKiBAcmV0dXJuIHtDaHVua31cbiAqL1xuY2xhc3MgQ2h1bmsge1xuXHRjb25zdHJ1Y3RvcihmaWVsZHMpIHtcblx0XHR0aGlzLnR5cGUgPSBmaWVsZHMudHlwZTtcblx0XHR0aGlzLmRhdGEgPSBmaWVsZHMuZGF0YTtcblx0XHR0aGlzLnNpemUgPSBbMCwgMCwgMCwgZmllbGRzLmRhdGEubGVuZ3RoXTtcblx0fVxufVxuXG5leHBvcnQge0NodW5rfTtcbi8qKlxuICogTUlESSBmaWxlIGZvcm1hdCBjb25zdGFudHMsIGluY2x1ZGluZyBub3RlIC0+IE1JREkgbnVtYmVyIHRyYW5zbGF0aW9uLlxuICogQHJldHVybiB7Q29uc3RhbnRzfVxuICovXG5cbnZhciBDb25zdGFudHMgPSB7XG5cdFZFUlNJT05cdFx0XHRcdFx0OiAnMS41LjInLFxuXHRIRUFERVJfQ0hVTktfVFlQRSAgXHRcdDogWzB4NGQsIDB4NTQsIDB4NjgsIDB4NjRdLCAvLyBNdGhkXG5cdEhFQURFUl9DSFVOS19MRU5HVEggIFx0OiBbMHgwMCwgMHgwMCwgMHgwMCwgMHgwNl0sIC8vIEhlYWRlciBzaXplIGZvciBTTUZcblx0SEVBREVSX0NIVU5LX0ZPUk1BVDAgICAgOiBbMHgwMCwgMHgwMF0sIC8vIE1pZGkgVHlwZSAwIGlkXG5cdEhFQURFUl9DSFVOS19GT1JNQVQxICAgIDogWzB4MDAsIDB4MDFdLCAvLyBNaWRpIFR5cGUgMSBpZFxuXHRIRUFERVJfQ0hVTktfRElWSVNJT04gICA6IFsweDAwLCAweDgwXSwgLy8gRGVmYXVsdHMgdG8gMTI4IHRpY2tzIHBlciBiZWF0XG5cdFRSQUNLX0NIVU5LX1RZUEVcdFx0OiBbMHg0ZCwgMHg1NCwgMHg3MiwgMHg2Yl0sIC8vIE1UcmssXG5cdE1FVEFfRVZFTlRfSURcdFx0XHQ6IDB4RkYsXG5cdE1FVEFfVEVYVF9JRFx0XHRcdDogMHgwMSxcblx0TUVUQV9DT1BZUklHSFRfSURcdFx0OiAweDAyLFxuXHRNRVRBX1RSQUNLX05BTUVfSURcdFx0OiAweDAzLFxuXHRNRVRBX0lOU1RSVU1FTlRfTkFNRV9JRCA6IDB4MDQsXG5cdE1FVEFfTFlSSUNfSURcdFx0XHQ6IDB4MDUsXG5cdE1FVEFfTUFSS0VSX0lEXHRcdFx0OiAweDA2LFxuXHRNRVRBX0NVRV9QT0lOVFx0XHRcdDogMHgwNyxcblx0TUVUQV9URU1QT19JRFx0XHRcdDogMHg1MSxcblx0TUVUQV9TTVRQRV9PRkZTRVRcdFx0OiAweDU0LFxuXHRNRVRBX1RJTUVfU0lHTkFUVVJFX0lEXHQ6IDB4NTgsXG5cdE1FVEFfS0VZX1NJR05BVFVSRV9JRFx0OiAweDU5LFxuXHRNRVRBX0VORF9PRl9UUkFDS19JRFx0OiBbMHgyRiwgMHgwMF0sXG5cdENPTlRST0xMRVJfQ0hBTkdFX1NUQVRVUzogMHhCMCwgLy8gaW5jbHVkZXMgY2hhbm5lbCBudW1iZXIgKDApXG5cdFBST0dSQU1fQ0hBTkdFX1NUQVRVU1x0OiAweEMwLCAvLyBpbmNsdWRlcyBjaGFubmVsIG51bWJlciAoMClcbn07XG5cbmV4cG9ydCB7Q29uc3RhbnRzfTtcbi8qKlxuICogSG9sZHMgYWxsIGRhdGEgZm9yIGEgXCJjb250cm9sbGVyIGNoYW5nZVwiIE1JREkgZXZlbnRcbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMge2NvbnRyb2xsZXJOdW1iZXI6IGludGVnZXIsIGNvbnRyb2xsZXJWYWx1ZTogaW50ZWdlcn1cbiAqIEByZXR1cm4ge0NvbnRyb2xsZXJDaGFuZ2VFdmVudH1cbiAqL1xuY2xhc3MgQ29udHJvbGxlckNoYW5nZUV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy50eXBlID0gJ2NvbnRyb2xsZXInO1xuXHRcdC8vIGRlbHRhIHRpbWUgZGVmYXVsdHMgdG8gMC5cblx0XHR0aGlzLmRhdGEgPSBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKDB4MDApLmNvbmNhdChDb25zdGFudHMuQ09OVFJPTExFUl9DSEFOR0VfU1RBVFVTLCBmaWVsZHMuY29udHJvbGxlck51bWJlciwgZmllbGRzLmNvbnRyb2xsZXJWYWx1ZSk7XG5cdH1cbn1cblxuZXhwb3J0IHtDb250cm9sbGVyQ2hhbmdlRXZlbnR9O1xuLyoqXG4gKiBPYmplY3QgcmVwcmVzZW50YXRpb24gb2YgYSBtZXRhIGV2ZW50LlxuICogQHBhcmFtIHtvYmplY3R9IGZpZWxkcyAtIHR5cGUsIGRhdGFcbiAqIEByZXR1cm4ge01ldGFFdmVudH1cbiAqL1xuY2xhc3MgTWV0YUV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy50eXBlID0gJ21ldGEnO1xuXHRcdHRoaXMuZGF0YSA9IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoMHgwMCk7Ly8gU3RhcnQgd2l0aCB6ZXJvIHRpbWUgZGVsdGFcblx0XHR0aGlzLmRhdGEgPSB0aGlzLmRhdGEuY29uY2F0KENvbnN0YW50cy5NRVRBX0VWRU5UX0lELCBmaWVsZHMuZGF0YSk7XG5cdH1cbn1cblxuZXhwb3J0IHtNZXRhRXZlbnR9O1xuLyoqXG4gKiBXcmFwcGVyIGZvciBub3RlT25FdmVudC9ub3RlT2ZmRXZlbnQgb2JqZWN0cyB0aGF0IGJ1aWxkcyBib3RoIGV2ZW50cy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMgLSB7cGl0Y2g6ICdbQzRdJywgZHVyYXRpb246ICc0Jywgd2FpdDogJzQnLCB2ZWxvY2l0eTogMS0xMDB9XG4gKiBAcmV0dXJuIHtOb3RlRXZlbnR9XG4gKi9cbmNsYXNzIE5vdGVFdmVudCB7XG5cdGNvbnN0cnVjdG9yKGZpZWxkcykge1xuXHRcdHRoaXMudHlwZSBcdFx0PSAnbm90ZSc7XG5cdFx0dGhpcy5waXRjaCBcdFx0PSBVdGlscy50b0FycmF5KGZpZWxkcy5waXRjaCk7XG5cdFx0dGhpcy53YWl0IFx0XHQ9IGZpZWxkcy53YWl0IHx8IDA7XG5cdFx0dGhpcy5kdXJhdGlvbiBcdD0gZmllbGRzLmR1cmF0aW9uO1xuXHRcdHRoaXMuc2VxdWVudGlhbCA9IGZpZWxkcy5zZXF1ZW50aWFsIHx8IGZhbHNlO1xuXHRcdHRoaXMudmVsb2NpdHkgXHQ9IGZpZWxkcy52ZWxvY2l0eSB8fCA1MDtcblx0XHR0aGlzLmNoYW5uZWwgXHQ9IGZpZWxkcy5jaGFubmVsIHx8IDE7XG5cdFx0dGhpcy5yZXBlYXQgXHQ9IGZpZWxkcy5yZXBlYXQgfHwgMTtcblx0XHR0aGlzLnZlbG9jaXR5IFx0PSB0aGlzLmNvbnZlcnRWZWxvY2l0eSh0aGlzLnZlbG9jaXR5KTtcblx0XHR0aGlzLmdyYWNlXHRcdD0gZmllbGRzLmdyYWNlO1xuXHRcdHRoaXMuYnVpbGREYXRhKCk7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIGludCBhcnJheSBmb3IgdGhpcyBldmVudC5cblx0ICogQHJldHVybiB7Tm90ZUV2ZW50fVxuXHQgKi9cblx0YnVpbGREYXRhKCkge1xuXHRcdHRoaXMuZGF0YSA9IFtdO1xuXG5cdFx0dmFyIHRpY2tEdXJhdGlvbiA9IHRoaXMuZ2V0VGlja0R1cmF0aW9uKHRoaXMuZHVyYXRpb24sICdub3RlJyk7XG5cdFx0dmFyIHJlc3REdXJhdGlvbiA9IHRoaXMuZ2V0VGlja0R1cmF0aW9uKHRoaXMud2FpdCwgJ3Jlc3QnKTtcblxuXHRcdC8vIEFwcGx5IGdyYWNlIG5vdGUocykgYW5kIHN1YnRyYWN0IHRpY2tzIChjdXJyZW50bHkgMSB0aWNrIHBlciBncmFjZSBub3RlKSBmcm9tIHRpY2tEdXJhdGlvbiBzbyBuZXQgdmFsdWUgaXMgdGhlIHNhbWVcblx0XHRpZiAodGhpcy5ncmFjZSkge1xuXHRcdFx0bGV0IGdyYWNlRHVyYXRpb24gPSAxO1xuXHRcdFx0dGhpcy5ncmFjZSA9IFV0aWxzLnRvQXJyYXkodGhpcy5ncmFjZSk7XG5cdFx0XHR0aGlzLmdyYWNlLmZvckVhY2goZnVuY3Rpb24ocGl0Y2gpIHtcblx0XHRcdFx0bGV0IG5vdGVFdmVudCA9IG5ldyBOb3RlRXZlbnQoe3BpdGNoOnRoaXMuZ3JhY2UsIGR1cmF0aW9uOidUJyArIGdyYWNlRHVyYXRpb259KTtcblx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChub3RlRXZlbnQuZGF0YSlcblxuXHRcdFx0XHR0aWNrRHVyYXRpb24gLT0gZ3JhY2VEdXJhdGlvbjtcblx0XHRcdH0sIHRoaXMpO1xuXHRcdH1cblxuXHRcdC8vIGZpZWxkcy5waXRjaCBjb3VsZCBiZSBhbiBhcnJheSBvZiBwaXRjaGVzLlxuXHRcdC8vIElmIHNvIGNyZWF0ZSBub3RlIGV2ZW50cyBmb3IgZWFjaCBhbmQgYXBwbHkgdGhlIHNhbWUgZHVyYXRpb24uXG5cdFx0dmFyIG5vdGVPbiwgbm90ZU9mZjtcblx0XHRpZiAoQXJyYXkuaXNBcnJheSh0aGlzLnBpdGNoKSkge1xuXHRcdFx0Ly8gQnkgZGVmYXVsdCB0aGlzIGlzIGEgY2hvcmQgaWYgaXQncyBhbiBhcnJheSBvZiBub3RlcyB0aGF0IHJlcXVpcmVzIG9uZSBOb3RlT25FdmVudC5cblx0XHRcdC8vIElmIHRoaXMuc2VxdWVudGlhbCA9PT0gdHJ1ZSB0aGVuIGl0J3MgYSBzZXF1ZW50aWFsIHN0cmluZyBvZiBub3RlcyB0aGF0IHJlcXVpcmVzIHNlcGFyYXRlIE5vdGVPbkV2ZW50cy5cblx0XHRcdGlmICggISB0aGlzLnNlcXVlbnRpYWwpIHtcblx0XHRcdFx0Ly8gSGFuZGxlIHJlcGVhdFxuXHRcdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMucmVwZWF0OyBqKyspIHtcblx0XHRcdFx0XHQvLyBOb3RlIG9uXG5cdFx0XHRcdFx0dGhpcy5waXRjaC5mb3JFYWNoKGZ1bmN0aW9uKHAsIGkpIHtcblx0XHRcdFx0XHRcdGlmIChpID09IDApIHtcblx0XHRcdFx0XHRcdFx0bm90ZU9uID0gbmV3IE5vdGVPbkV2ZW50KHtkYXRhOiBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKHJlc3REdXJhdGlvbikuY29uY2F0KHRoaXMuZ2V0Tm90ZU9uU3RhdHVzKCksIFV0aWxzLmdldFBpdGNoKHApLCB0aGlzLnZlbG9jaXR5KX0pO1xuXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHQvLyBSdW5uaW5nIHN0YXR1cyAoY2FuIG9tbWl0IHRoZSBub3RlIG9uIHN0YXR1cylcblx0XHRcdFx0XHRcdFx0bm90ZU9uID0gbmV3IE5vdGVPbkV2ZW50KHtkYXRhOiBbMCwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHldfSk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQobm90ZU9uLmRhdGEpO1xuXHRcdFx0XHRcdH0sIHRoaXMpO1xuXG5cdFx0XHRcdFx0Ly8gTm90ZSBvZmZcblx0XHRcdFx0XHR0aGlzLnBpdGNoLmZvckVhY2goZnVuY3Rpb24ocCwgaSkge1xuXHRcdFx0XHRcdFx0aWYgKGkgPT0gMCkge1xuXHRcdFx0XHRcdFx0XHRub3RlT2ZmID0gbmV3IE5vdGVPZmZFdmVudCh7ZGF0YTogVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aCh0aWNrRHVyYXRpb24pLmNvbmNhdCh0aGlzLmdldE5vdGVPZmZTdGF0dXMoKSwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHkpfSk7XG5cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdC8vIFJ1bm5pbmcgc3RhdHVzIChjYW4gb21taXQgdGhlIG5vdGUgb2ZmIHN0YXR1cylcblx0XHRcdFx0XHRcdFx0bm90ZU9mZiA9IG5ldyBOb3RlT2ZmRXZlbnQoe2RhdGE6IFswLCBVdGlscy5nZXRQaXRjaChwKSwgdGhpcy52ZWxvY2l0eV19KTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChub3RlT2ZmLmRhdGEpO1xuXHRcdFx0XHRcdH0sIHRoaXMpO1xuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIEhhbmRsZSByZXBlYXRcblx0XHRcdFx0Zm9yICh2YXIgaiA9IDA7IGogPCB0aGlzLnJlcGVhdDsgaisrKSB7XG5cdFx0XHRcdFx0dGhpcy5waXRjaC5mb3JFYWNoKGZ1bmN0aW9uKHAsIGkpIHtcblx0XHRcdFx0XHRcdC8vIHJlc3REdXJhdGlvbiBvbmx5IGFwcGxpZXMgdG8gZmlyc3Qgbm90ZVxuXHRcdFx0XHRcdFx0aWYgKGkgPiAwKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3REdXJhdGlvbiA9IDA7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIElmIGR1cmF0aW9uIGlzIDh0aCB0cmlwbGV0cyB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSB0b3RhbCB0aWNrcyA9PSBxdWFydGVyIG5vdGUuXG5cdFx0XHRcdFx0XHQvLyBTbywgdGhlIGxhc3Qgb25lIHdpbGwgbmVlZCB0byBiZSB0aGUgcmVtYWluZGVyXG5cdFx0XHRcdFx0XHRpZiAodGhpcy5kdXJhdGlvbiA9PT0gJzh0JyAmJiBpID09IHRoaXMucGl0Y2gubGVuZ3RoIC0gMSkge1xuXHRcdFx0XHRcdFx0XHRsZXQgcXVhcnRlclRpY2tzID0gVXRpbHMubnVtYmVyRnJvbUJ5dGVzKENvbnN0YW50cy5IRUFERVJfQ0hVTktfRElWSVNJT04pO1xuXHRcdFx0XHRcdFx0XHR0aWNrRHVyYXRpb24gPSBxdWFydGVyVGlja3MgLSAodGlja0R1cmF0aW9uICogMik7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdG5vdGVPbiA9IG5ldyBOb3RlT25FdmVudCh7ZGF0YTogVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChyZXN0RHVyYXRpb24pLmNvbmNhdChbdGhpcy5nZXROb3RlT25TdGF0dXMoKSwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHldKX0pO1xuXHRcdFx0XHRcdFx0bm90ZU9mZiA9IG5ldyBOb3RlT2ZmRXZlbnQoe2RhdGE6IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgodGlja0R1cmF0aW9uKS5jb25jYXQoW3RoaXMuZ2V0Tm90ZU9mZlN0YXR1cygpLCBVdGlscy5nZXRQaXRjaChwKSwgdGhpcy52ZWxvY2l0eV0pfSk7XG5cblx0XHRcdFx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQobm90ZU9uLmRhdGEsIG5vdGVPZmYuZGF0YSk7XG5cdFx0XHRcdFx0fSwgdGhpcyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0dGhyb3cgJ3BpdGNoIG11c3QgYmUgYW4gYXJyYXkuJztcblx0fTtcblxuXHQvKipcblx0ICogQ29udmVydHMgdmVsb2NpdHkgdG8gdmFsdWUgMC0xMjdcblx0ICogQHBhcmFtIHtudW1iZXJ9IHZlbG9jaXR5IC0gVmVsb2NpdHkgdmFsdWUgMS0xMDBcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cblx0Y29udmVydFZlbG9jaXR5KHZlbG9jaXR5KSB7XG5cdFx0Ly8gTWF4IHBhc3NlZCB2YWx1ZSBsaW1pdGVkIHRvIDEwMFxuXHRcdHZlbG9jaXR5ID0gdmVsb2NpdHkgPiAxMDAgPyAxMDAgOiB2ZWxvY2l0eTtcblx0XHRyZXR1cm4gTWF0aC5yb3VuZCh2ZWxvY2l0eSAvIDEwMCAqIDEyNyk7XG5cdH07XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHRvdGFsIG51bWJlciBvZiB0aWNrcyBiYXNlZCBvbiBwYXNzZWQgZHVyYXRpb24uXG5cdCAqIE5vdGU6IHR5cGU9PSdub3RlJyBkZWZhdWx0cyB0byBxdWFydGVyIG5vdGUsIHR5cGU9PT0ncmVzdCcgZGVmYXVsdHMgdG8gMFxuXHQgKiBAcGFyYW0geyhzdHJpbmd8YXJyYXkpfSBkdXJhdGlvblxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBbJ25vdGUnLCAncmVzdCddXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdGdldFRpY2tEdXJhdGlvbihkdXJhdGlvbiwgdHlwZSkge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KGR1cmF0aW9uKSkge1xuXHRcdFx0Ly8gUmVjdXJzaXZlbHkgZXhlY3V0ZSB0aGlzIG1ldGhvZCBmb3IgZWFjaCBpdGVtIGluIHRoZSBhcnJheSBhbmQgcmV0dXJuIHRoZSBzdW0gb2YgdGljayBkdXJhdGlvbnMuXG5cdFx0XHRyZXR1cm4gZHVyYXRpb24ubWFwKGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLmdldFRpY2tEdXJhdGlvbih2YWx1ZSwgdHlwZSk7XG5cdFx0XHR9LCB0aGlzKS5yZWR1Y2UoZnVuY3Rpb24oYSwgYikge1xuXHRcdFx0XHRyZXR1cm4gYSArIGI7XG5cdFx0XHR9LCAwKTtcblx0XHR9XG5cblx0XHRkdXJhdGlvbiA9IGR1cmF0aW9uLnRvU3RyaW5nKCk7XG5cblx0XHRpZiAoZHVyYXRpb24udG9Mb3dlckNhc2UoKS5jaGFyQXQoMCkgPT09ICd0Jykge1xuXHRcdFx0Ly8gSWYgZHVyYXRpb24gc3RhcnRzIHdpdGggJ3QnIHRoZW4gdGhlIG51bWJlciB0aGF0IGZvbGxvd3MgaXMgYW4gZXhwbGljaXQgdGljayBjb3VudFxuXHRcdFx0cmV0dXJuIHBhcnNlSW50KGR1cmF0aW9uLnN1YnN0cmluZygxKSk7XG5cdFx0fVxuXG5cdFx0Ly8gTmVlZCB0byBhcHBseSBkdXJhdGlvbiBoZXJlLiAgUXVhcnRlciBub3RlID09IENvbnN0YW50cy5IRUFERVJfQ0hVTktfRElWSVNJT05cblx0XHQvLyBSb3VuZGluZyBvbmx5IGFwcGxpZXMgdG8gdHJpcGxldHMsIHdoaWNoIHRoZSByZW1haW5kZXIgaXMgaGFuZGxlZCBiZWxvd1xuXHRcdHZhciBxdWFydGVyVGlja3MgPSBVdGlscy5udW1iZXJGcm9tQnl0ZXMoQ29uc3RhbnRzLkhFQURFUl9DSFVOS19ESVZJU0lPTik7XG5cdFx0cmV0dXJuIE1hdGgucm91bmQocXVhcnRlclRpY2tzICogdGhpcy5nZXREdXJhdGlvbk11bHRpcGxpZXIoZHVyYXRpb24sIHR5cGUpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHdoYXQgdG8gbXVsdGlwbGUgdGlja3MvcXVhcnRlciBub3RlIGJ5IHRvIGdldCB0aGUgc3BlY2lmaWVkIGR1cmF0aW9uLlxuXHQgKiBOb3RlOiB0eXBlPT0nbm90ZScgZGVmYXVsdHMgdG8gcXVhcnRlciBub3RlLCB0eXBlPT09J3Jlc3QnIGRlZmF1bHRzIHRvIDBcblx0ICogQHBhcmFtIHtzdHJpbmd9IGR1cmF0aW9uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFsnbm90ZScsJ3Jlc3QnXVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXREdXJhdGlvbk11bHRpcGxpZXIoZHVyYXRpb24sIHR5cGUpIHtcblx0XHQvLyBOZWVkIHRvIGFwcGx5IGR1cmF0aW9uIGhlcmUuICBRdWFydGVyIG5vdGUgPT0gQ29uc3RhbnRzLkhFQURFUl9DSFVOS19ESVZJU0lPTlxuXHRcdHN3aXRjaCAoZHVyYXRpb24pIHtcblx0XHRcdGNhc2UgJzAnOlxuXHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdGNhc2UgJzEnOlxuXHRcdFx0XHRyZXR1cm4gNDtcblx0XHRcdGNhc2UgJzInOlxuXHRcdFx0XHRyZXR1cm4gMjtcblx0XHRcdGNhc2UgJ2QyJzpcblx0XHRcdFx0cmV0dXJuIDM7XG5cdFx0XHRjYXNlICc0Jzpcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHRjYXNlICc0dCc6XG5cdFx0XHRcdHJldHVybiAwLjY2Njtcblx0XHRcdGNhc2UgJ2Q0Jzpcblx0XHRcdFx0cmV0dXJuIDEuNTtcblx0XHRcdGNhc2UgJzgnOlxuXHRcdFx0XHRyZXR1cm4gMC41O1xuXHRcdFx0Y2FzZSAnOHQnOlxuXHRcdFx0XHQvLyBGb3IgOHRoIHRyaXBsZXRzLCBsZXQncyBkaXZpZGUgYSBxdWFydGVyIGJ5IDMsIHJvdW5kIHRvIHRoZSBuZWFyZXN0IGludCwgYW5kIHN1YnN0cmFjdCB0aGUgcmVtYWluZGVyIHRvIHRoZSBsYXN0IG9uZS5cblx0XHRcdFx0cmV0dXJuIDAuMzM7XG5cdFx0XHRjYXNlICdkOCc6XG5cdFx0XHRcdHJldHVybiAwLjc1O1xuXHRcdFx0Y2FzZSAnMTYnOlxuXHRcdFx0XHRyZXR1cm4gMC4yNTtcblx0XHRcdGNhc2UgJzE2dCc6XG5cdFx0XHRcdHJldHVybiAwLjE2Njtcblx0XHRcdGNhc2UgJzMyJzpcblx0XHRcdFx0cmV0dXJuIDAuMTI1O1xuXHRcdFx0Y2FzZSAnNjQnOlxuXHRcdFx0XHRyZXR1cm4gMC4wNjI1O1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0Ly8gTm90ZXMgZGVmYXVsdCB0byBhIHF1YXJ0ZXIsIHJlc3RzIGRlZmF1bHQgdG8gMFxuXHRcdFx0XHQvL3JldHVybiB0eXBlID09PSAnbm90ZScgPyAxIDogMDtcblx0XHR9XG5cblx0XHR0aHJvdyBkdXJhdGlvbiArICcgaXMgbm90IGEgdmFsaWQgZHVyYXRpb24uJztcblx0fTtcblxuXHQvKipcblx0ICogR2V0cyB0aGUgbm90ZSBvbiBzdGF0dXMgY29kZSBiYXNlZCBvbiB0aGUgc2VsZWN0ZWQgY2hhbm5lbC4gMHg5ezAtRn1cblx0ICogTm90ZSBvbiBhdCBjaGFubmVsIDAgaXMgMHg5MCAoMTQ0KVxuXHQgKiAwID0gQ2ggMVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXROb3RlT25TdGF0dXMoKSB7cmV0dXJuIDE0NCArIHRoaXMuY2hhbm5lbCAtIDF9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIG5vdGUgb2ZmIHN0YXR1cyBjb2RlIGJhc2VkIG9uIHRoZSBzZWxlY3RlZCBjaGFubmVsLiAweDh7MC1GfVxuXHQgKiBOb3RlIG9mZiBhdCBjaGFubmVsIDAgaXMgMHg4MCAoMTI4KVxuXHQgKiAwID0gQ2ggMVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXROb3RlT2ZmU3RhdHVzKCkge3JldHVybiAxMjggKyB0aGlzLmNoYW5uZWwgLSAxfVxufVxuXG5leHBvcnQge05vdGVFdmVudH07XG4vKipcbiAqIEhvbGRzIGFsbCBkYXRhIGZvciBhIFwibm90ZSBvZmZcIiBNSURJIGV2ZW50XG4gKiBAcGFyYW0ge29iamVjdH0gZmllbGRzIHtkYXRhOiBbXX1cbiAqIEByZXR1cm4ge05vdGVPZmZFdmVudH1cbiAqL1xuY2xhc3MgTm90ZU9mZkV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy5kYXRhID0gZmllbGRzLmRhdGE7XG5cdH1cbn1cblxuZXhwb3J0IHtOb3RlT2ZmRXZlbnR9O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSBcIm5vdGUgb25cIiBNSURJIGV2ZW50XG4gKiBAcGFyYW0ge29iamVjdH0gZmllbGRzIHtkYXRhOiBbXX1cbiAqIEByZXR1cm4ge05vdGVPbkV2ZW50fVxuICovXG5jbGFzcyBOb3RlT25FdmVudCB7XG5cdGNvbnN0cnVjdG9yKGZpZWxkcykge1xuXHRcdHRoaXMuZGF0YSA9IGZpZWxkcy5kYXRhO1xuXHR9XG59XG5cbmV4cG9ydCB7Tm90ZU9uRXZlbnR9O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSBcInByb2dyYW0gY2hhbmdlXCIgTUlESSBldmVudFxuICogQHBhcmFtIHtvYmplY3R9IGZpZWxkcyB7aW5zdHJ1bWVudDogaW50ZWdlcn1cbiAqIEByZXR1cm4ge1Byb2dyYW1DaGFuZ2VFdmVudH1cbiAqL1xuY2xhc3MgUHJvZ3JhbUNoYW5nZUV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy50eXBlID0gJ3Byb2dyYW0nO1xuXHRcdC8vIGRlbHRhIHRpbWUgZGVmYXVsdHMgdG8gMC5cblx0XHR0aGlzLmRhdGEgPSBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKDB4MDApLmNvbmNhdChDb25zdGFudHMuUFJPR1JBTV9DSEFOR0VfU1RBVFVTLCBmaWVsZHMuaW5zdHJ1bWVudCk7XG5cdH1cbn1cblxuZXhwb3J0IHtQcm9ncmFtQ2hhbmdlRXZlbnR9O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSB0cmFjay5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMge3R5cGU6IG51bWJlciwgZGF0YTogYXJyYXksIHNpemU6IGFycmF5LCBldmVudHM6IGFycmF5fVxuICogQHJldHVybiB7VHJhY2t9XG4gKi9cbmNsYXNzIFRyYWNrIHtcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0dGhpcy50eXBlID0gQ29uc3RhbnRzLlRSQUNLX0NIVU5LX1RZUEU7XG5cdFx0dGhpcy5kYXRhID0gW107XG5cdFx0dGhpcy5zaXplID0gW107XG5cdFx0dGhpcy5ldmVudHMgPSBbXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGFueSBldmVudCB0eXBlIHRvIHRoZSB0cmFjay5cblx0ICogQHBhcmFtIHsoTm90ZUV2ZW50fE1ldGFFdmVudHxQcm9ncmFtQ2hhbmdlRXZlbnQpfSBldmVudCAtIEV2ZW50IG9iamVjdC5cblx0ICogQHBhcmFtIHtmdW5jdGlvbn0gbWFwRnVuY3Rpb24gLSBDYWxsYmFjayB3aGljaCBjYW4gYmUgdXNlZCB0byBhcHBseSBzcGVjaWZpYyBwcm9wZXJ0aWVzIHRvIGFsbCBldmVudHMuIFxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZEV2ZW50KGV2ZW50LCBtYXBGdW5jdGlvbikge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KGV2ZW50KSkge1xuXHRcdFx0ZXZlbnQuZm9yRWFjaChmdW5jdGlvbihlLCBpKSB7XG5cdFx0XHRcdC8vIEhhbmRsZSBtYXAgZnVuY3Rpb24gaWYgcHJvdmlkZWRcblx0XHRcdFx0aWYgKHR5cGVvZiBtYXBGdW5jdGlvbiA9PT0gJ2Z1bmN0aW9uJyAmJiBlLnR5cGUgPT09ICdub3RlJykge1xuXHRcdFx0XHRcdHZhciBwcm9wZXJ0aWVzID0gbWFwRnVuY3Rpb24oaSwgZSk7XG5cblx0XHRcdFx0XHRpZiAodHlwZW9mIHByb3BlcnRpZXMgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdFx0XHRmb3IgKHZhciBqIGluIHByb3BlcnRpZXMpIHtcblx0XHRcdFx0XHRcdFx0c3dpdGNoKGopIHtcblx0XHRcdFx0XHRcdFx0XHRjYXNlICdkdXJhdGlvbic6XG5cdFx0XHRcdFx0XHRcdFx0XHRlLmR1cmF0aW9uID0gcHJvcGVydGllc1tqXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdGNhc2UgJ3NlcXVlbnRpYWwnOlxuXHRcdFx0XHRcdFx0XHRcdFx0ZS5zZXF1ZW50aWFsID0gcHJvcGVydGllc1tqXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdGNhc2UgJ3ZlbG9jaXR5Jzpcblx0XHRcdFx0XHRcdFx0XHRcdGUudmVsb2NpdHkgPSBlLmNvbnZlcnRWZWxvY2l0eShwcm9wZXJ0aWVzW2pdKTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XHRcdFxuXG5cdFx0XHRcdFx0XHQvLyBHb3R0YSBidWlsZCB0aGF0IGRhdGFcblx0XHRcdFx0XHRcdGUuYnVpbGREYXRhKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChlLmRhdGEpO1xuXHRcdFx0XHR0aGlzLnNpemUgPSBVdGlscy5udW1iZXJUb0J5dGVzKHRoaXMuZGF0YS5sZW5ndGgsIDQpOyAvLyA0IGJ5dGVzIGxvbmdcblx0XHRcdFx0dGhpcy5ldmVudHMucHVzaChlKTtcblx0XHRcdH0sIHRoaXMpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQoZXZlbnQuZGF0YSk7XG5cdFx0XHR0aGlzLnNpemUgPSBVdGlscy5udW1iZXJUb0J5dGVzKHRoaXMuZGF0YS5sZW5ndGgsIDQpOyAvLyA0IGJ5dGVzIGxvbmdcblx0XHRcdHRoaXMuZXZlbnRzLnB1c2goZXZlbnQpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGVtcG8gb2YgdGhlIE1JREkgZmlsZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGJwbSAtIFRlbXBvIGluIGJlYXRzIHBlciBtaW51dGUuXG5cdCAqIEByZXR1cm4ge1RyYWNrfVxuXHQgKi9cblx0c2V0VGVtcG8oYnBtKSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX1RFTVBPX0lEXX0pO1xuXHRcdGV2ZW50LmRhdGEucHVzaCgweDAzKTsgLy8gU2l6ZVxuXHRcdHZhciB0ZW1wbyA9IE1hdGgucm91bmQoNjAwMDAwMDAgLyBicG0pO1xuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKHRlbXBvLCAzKSk7IC8vIFRlbXBvLCAzIGJ5dGVzXG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGltZSBzaWduYXR1cmUuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBudW1lcmF0b3IgLSBUb3AgbnVtYmVyIG9mIHRoZSB0aW1lIHNpZ25hdHVyZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGRlbm9taW5hdG9yIC0gQm90dG9tIG51bWJlciBvZiB0aGUgdGltZSBzaWduYXR1cmUuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBtaWRpY2xvY2tzcGVydGljayAtIERlZmF1bHRzIHRvIDI0LlxuXHQgKiBAcGFyYW0ge251bWJlcn0gbm90ZXNwZXJtaWRpY2xvY2sgLSBEZWZhdWx0cyB0byA4LlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdHNldFRpbWVTaWduYXR1cmUobnVtZXJhdG9yLCBkZW5vbWluYXRvciwgbWlkaWNsb2Nrc3BlcnRpY2ssIG5vdGVzcGVybWlkaWNsb2NrKSB7XG5cdFx0bWlkaWNsb2Nrc3BlcnRpY2sgPSBtaWRpY2xvY2tzcGVydGljayB8fCAyNDtcblx0XHRub3Rlc3Blcm1pZGljbG9jayA9IG5vdGVzcGVybWlkaWNsb2NrIHx8IDg7XG5cdFx0XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX1RJTUVfU0lHTkFUVVJFX0lEXX0pO1xuXHRcdGV2ZW50LmRhdGEucHVzaCgweDA0KTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG51bWVyYXRvciwgMSkpOyAvLyBOdW1lcmF0b3IsIDEgYnl0ZXNcblx0XHRcblx0XHR2YXIgX2Rlbm9taW5hdG9yID0gTWF0aC5sb2cyKGRlbm9taW5hdG9yKTtcdC8vIERlbm9taW5hdG9yIGlzIGV4cHJlc3NlZCBhcyBwb3cgb2YgMlxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKF9kZW5vbWluYXRvciwgMSkpOyAvLyBEZW5vbWluYXRvciwgMSBieXRlc1xuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG1pZGljbG9ja3NwZXJ0aWNrLCAxKSk7IC8vIE1JREkgQ2xvY2tzIHBlciB0aWNrLCAxIGJ5dGVzXG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvQnl0ZXMobm90ZXNwZXJtaWRpY2xvY2ssIDEpKTsgLy8gTnVtYmVyIG9mIDEvMzIgbm90ZXMgcGVyIE1JREkgY2xvY2tzLCAxIGJ5dGVzXG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMga2V5IHNpZ25hdHVyZS5cblx0ICogQHBhcmFtIHsqfSBzZiAtIFxuXHQgKiBAcGFyYW0geyp9IG1pIC1cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRzZXRLZXlTaWduYXR1cmUoc2YsIG1pKSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX0tFWV9TSUdOQVRVUkVfSURdfSk7XG5cdFx0ZXZlbnQuZGF0YS5wdXNoKDB4MDIpOyAvLyBTaXplXG5cblx0XHR2YXIgbW9kZSA9IG1pIHx8IDA7XG5cdFx0c2YgPSBzZiB8fCAwO1xuXG5cdFx0Ly9cdEZ1bmN0aW9uIGNhbGxlZCB3aXRoIHN0cmluZyBub3RhdGlvblxuXHRcdGlmICh0eXBlb2YgbWkgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHR2YXIgZmlmdGhzID0gW1xuXHRcdFx0XHRbJ0NiJywgJ0diJywgJ0RiJywgJ0FiJywgJ0ViJywgJ0JiJywgJ0YnLCAnQycsICdHJywgJ0QnLCAnQScsICdFJywgJ0InLCAnRiMnLCAnQyMnXSxcblx0XHRcdFx0WydhYicsICdlYicsICdiYicsICdmJywgJ2MnLCAnZycsICdkJywgJ2EnLCAnZScsICdiJywgJ2YjJywgJ2MjJywgJ2cjJywgJ2QjJywgJ2EjJ11cblx0XHRcdF07XG5cdFx0XHR2YXIgX3NmbGVuID0gc2YubGVuZ3RoO1xuXHRcdFx0dmFyIG5vdGUgPSBzZiB8fCAnQyc7XG5cblx0XHRcdGlmIChzZlswXSA9PT0gc2ZbMF0udG9Mb3dlckNhc2UoKSkgbW9kZSA9IDFcblxuXHRcdFx0aWYgKF9zZmxlbiA+IDEpIHtcblx0XHRcdFx0c3dpdGNoIChzZi5jaGFyQXQoX3NmbGVuIC0gMSkpIHtcblx0XHRcdFx0XHRjYXNlICdtJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAxO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICctJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAxO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdNJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAwO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICcrJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAwO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgZmlmdGhpbmRleCA9IGZpZnRoc1ttb2RlXS5pbmRleE9mKG5vdGUpO1xuXHRcdFx0c2YgPSBmaWZ0aGluZGV4ID09PSAtMSA/IDAgOiBmaWZ0aGluZGV4IC0gNztcblx0XHR9XG5cblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9CeXRlcyhzZiwgMSkpOyAvLyBOdW1iZXIgb2Ygc2hhcnAgb3IgZmxhdHMgKCA8IDAgZmxhdDsgPiAwIHNoYXJwKVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG1vZGUsIDEpKTsgLy8gTW9kZTogMCBtYWpvciwgMSBtaW5vclxuXHRcdHJldHVybiB0aGlzLmFkZEV2ZW50KGV2ZW50KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIHRleHQgdG8gTUlESSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRleHQgdG8gYWRkLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZFRleHQodGV4dCkge1xuXHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoe2RhdGE6IFtDb25zdGFudHMuTUVUQV9URVhUX0lEXX0pO1xuXHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgY29weXJpZ2h0IHRvIE1JREkgZmlsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUZXh0IG9mIGNvcHlyaWdodCBsaW5lLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZENvcHlyaWdodCh0ZXh0KSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX0NPUFlSSUdIVF9JRF19KTtcblx0XHR2YXIgc3RyaW5nQnl0ZXMgPSBVdGlscy5zdHJpbmdUb0J5dGVzKHRleHQpO1xuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKHN0cmluZ0J5dGVzLmxlbmd0aCkpOyAvLyBTaXplXG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KHN0cmluZ0J5dGVzKTsgLy8gVGV4dFxuXHRcdHJldHVybiB0aGlzLmFkZEV2ZW50KGV2ZW50KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIFNlcXVlbmNlL1RyYWNrIE5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGV4dCBvZiB0cmFjayBuYW1lLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZFRyYWNrTmFtZSh0ZXh0KSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX1RSQUNLX05BTUVfSURdfSk7XG5cdFx0dmFyIHN0cmluZ0J5dGVzID0gVXRpbHMuc3RyaW5nVG9CeXRlcyh0ZXh0KTtcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIFRleHRcblx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBpbnN0cnVtZW50IG5hbWUgb2YgdHJhY2suXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gTmFtZSBvZiBpbnN0cnVtZW50LlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZEluc3RydW1lbnROYW1lKHRleHQpIHtcblx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHtkYXRhOiBbQ29uc3RhbnRzLk1FVEFfSU5TVFJVTUVOVF9OQU1FX0lEXX0pO1xuXHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgbWFya2VyIHRvIE1JREkgZmlsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBNYXJrZXIgdGV4dC5cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRhZGRNYXJrZXIodGV4dCkge1xuXHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoe2RhdGE6IFtDb25zdGFudHMuTUVUQV9NQVJLRVJfSURdfSk7XG5cdFx0dmFyIHN0cmluZ0J5dGVzID0gVXRpbHMuc3RyaW5nVG9CeXRlcyh0ZXh0KTtcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIFRleHRcblx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBjdWUgcG9pbnQgdG8gTUlESSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRleHQgb2YgY3VlIHBvaW50LlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZEN1ZVBvaW50KHRleHQpIHtcblx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHtkYXRhOiBbQ29uc3RhbnRzLk1FVEFfQ1VFX1BPSU5UXX0pO1xuXHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgbHlyaWMgdG8gTUlESSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbHlyaWMgLSBMeXJpYyB0ZXh0IHRvIGFkZC5cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRhZGRMeXJpYyhseXJpYykge1xuXHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoe2RhdGE6IFtDb25zdGFudHMuTUVUQV9MWVJJQ19JRF19KTtcblx0XHR2YXIgc3RyaW5nQnl0ZXMgPSBVdGlscy5zdHJpbmdUb0J5dGVzKGx5cmljKTtcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIEx5cmljXG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoYW5uZWwgbW9kZSBtZXNzYWdlc1xuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdHBvbHlNb2RlT24oKSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE5vdGVPbkV2ZW50KHtkYXRhOiBbMHgwMCwgMHhCMCwgMHg3RSwgMHgwMF19KTtcblx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdH1cblxufVxuXG5leHBvcnQge1RyYWNrfTtcbmltcG9ydCB7dG9NaWRpfSBmcm9tICd0b25hbC1taWRpJztcblxuLyoqXG4gKiBTdGF0aWMgdXRpbGl0eSBmdW5jdGlvbnMgdXNlZCB0aHJvdWdob3V0IHRoZSBsaWJyYXJ5LlxuICovXG5jbGFzcyBVdGlscyB7XG5cblx0LyoqXG5cdCAqIEdldHMgTWlkaVdyaXRlckpTIHZlcnNpb24gbnVtYmVyLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRzdGF0aWMgdmVyc2lvbigpIHtcblx0XHRyZXR1cm4gQ29uc3RhbnRzLlZFUlNJT047XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydCBhIHN0cmluZyB0byBhbiBhcnJheSBvZiBieXRlc1xuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG5cdCAqIEByZXR1cm4ge2FycmF5fVxuXHQgKi9cblx0c3RhdGljIHN0cmluZ1RvQnl0ZXMoc3RyaW5nKSB7XG5cdFx0cmV0dXJuIHN0cmluZy5zcGxpdCgnJykubWFwKGNoYXIgPT4gY2hhci5jaGFyQ29kZUF0KCkpXG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIGFyZ3VtZW50IGlzIGEgdmFsaWQgbnVtYmVyLlxuXHQgKiBAcGFyYW0geyp9IG4gLSBWYWx1ZSB0byBjaGVja1xuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0c3RhdGljIGlzTnVtZXJpYyhuKSB7XG5cdFx0cmV0dXJuICFpc05hTihwYXJzZUZsb2F0KG4pKSAmJiBpc0Zpbml0ZShuKVxuXHR9XG5cblx0LyoqXG4gICAgICogUmV0dXJucyB0aGUgY29ycmVjdCBNSURJIG51bWJlciBmb3IgdGhlIHNwZWNpZmllZCBwaXRjaC5cbiAgICAgKiBVc2VzIFRvbmFsIE1pZGkgLSBodHRwczovL2dpdGh1Yi5jb20vZGFuaWdiL3RvbmFsL3RyZWUvbWFzdGVyL3BhY2thZ2VzL21pZGlcbiAgICAgKiBAcGFyYW0geyhzdHJpbmd8bnVtYmVyKX0gcGl0Y2ggLSAnQyM0JyBvciBtaWRpIG5vdGUgY29kZVxuICAgICAqIEByZXR1cm4ge251bWJlcn1cbiAgICAgKi9cbiAgICAgc3RhdGljIGdldFBpdGNoKHBpdGNoKSB7XG4gICAgIFx0cmV0dXJuIHRvTWlkaShwaXRjaCk7XG4gICAgIH1cblxuXHQvKipcblx0ICogVHJhbnNsYXRlcyBudW1iZXIgb2YgdGlja3MgdG8gTUlESSB0aW1lc3RhbXAgZm9ybWF0LCByZXR1cm5pbmcgYW4gYXJyYXkgb2Zcblx0ICogaGV4IHN0cmluZ3Mgd2l0aCB0aGUgdGltZSB2YWx1ZXMuIE1pZGkgaGFzIGEgdmVyeSBwYXJ0aWN1bGFyIHRpbWUgdG8gZXhwcmVzcyB0aW1lLFxuXHQgKiB0YWtlIGEgZ29vZCBsb29rIGF0IHRoZSBzcGVjIGJlZm9yZSBldmVyIHRvdWNoaW5nIHRoaXMgZnVuY3Rpb24uXG5cdCAqIFRoYW5rcyB0byBodHRwczovL2dpdGh1Yi5jb20vc2VyZ2kvanNtaWRpXG5cdCAqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB0aWNrcyAtIE51bWJlciBvZiB0aWNrcyB0byBiZSB0cmFuc2xhdGVkXG5cdCAqIEByZXR1cm4ge2FycmF5fSAtIEJ5dGVzIHRoYXQgZm9ybSB0aGUgTUlESSB0aW1lIHZhbHVlXG5cdCAqL1xuXHRzdGF0aWMgbnVtYmVyVG9WYXJpYWJsZUxlbmd0aCh0aWNrcykge1xuXHQgICAgdmFyIGJ1ZmZlciA9IHRpY2tzICYgMHg3RjtcblxuXHQgICAgd2hpbGUgKHRpY2tzID0gdGlja3MgPj4gNykge1xuXHQgICAgICAgIGJ1ZmZlciA8PD0gODtcblx0ICAgICAgICBidWZmZXIgfD0gKCh0aWNrcyAmIDB4N0YpIHwgMHg4MCk7XG5cdCAgICB9XG5cblx0ICAgIHZhciBiTGlzdCA9IFtdO1xuXHQgICAgd2hpbGUgKHRydWUpIHtcblx0ICAgICAgICBiTGlzdC5wdXNoKGJ1ZmZlciAmIDB4ZmYpO1xuXG5cdCAgICAgICAgaWYgKGJ1ZmZlciAmIDB4ODApIGJ1ZmZlciA+Pj0gOFxuXHQgICAgICAgIGVsc2UgeyBicmVhazsgfVxuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gYkxpc3Q7XG5cdH1cblxuXHQvKipcblx0ICogQ291bnRzIG51bWJlciBvZiBieXRlcyBpbiBzdHJpbmdcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNcblx0ICogQHJldHVybiB7YXJyYXl9XG5cdCAqL1xuXHRzdGF0aWMgc3RyaW5nQnl0ZUNvdW50KHMpIHtcblx0XHRyZXR1cm4gZW5jb2RlVVJJKHMpLnNwbGl0KC8lLi58Li8pLmxlbmd0aCAtIDFcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgYW4gaW50IGZyb20gYW4gYXJyYXkgb2YgYnl0ZXMuXG5cdCAqIEBwYXJhbSB7YXJyYXl9IGJ5dGVzXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdHN0YXRpYyBudW1iZXJGcm9tQnl0ZXMoYnl0ZXMpIHtcblx0XHR2YXIgaGV4ID0gJyc7XG5cdFx0dmFyIHN0cmluZ1Jlc3VsdDtcblxuXHRcdGJ5dGVzLmZvckVhY2goZnVuY3Rpb24oYnl0ZSkge1xuXHRcdFx0c3RyaW5nUmVzdWx0ID0gYnl0ZS50b1N0cmluZygxNik7XG5cblx0XHRcdC8vIGVuc3VyZSBzdHJpbmcgaXMgMiBjaGFyc1xuXHRcdFx0aWYgKHN0cmluZ1Jlc3VsdC5sZW5ndGggPT0gMSkgc3RyaW5nUmVzdWx0ID0gXCIwXCIgKyBzdHJpbmdSZXN1bHRcblxuXHRcdFx0aGV4ICs9IHN0cmluZ1Jlc3VsdDtcblx0XHR9KTtcblxuXHRcdHJldHVybiBwYXJzZUludChoZXgsIDE2KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUYWtlcyBhIG51bWJlciBhbmQgc3BsaXRzIGl0IHVwIGludG8gYW4gYXJyYXkgb2YgYnl0ZXMuICBDYW4gYmUgcGFkZGVkIGJ5IHBhc3NpbmcgYSBudW1iZXIgdG8gYnl0ZXNOZWVkZWRcblx0ICogQHBhcmFtIHtudW1iZXJ9IG51bWJlclxuXHQgKiBAcGFyYW0ge251bWJlcn0gYnl0ZXNOZWVkZWRcblx0ICogQHJldHVybiB7YXJyYXl9IC0gQXJyYXkgb2YgYnl0ZXNcblx0ICovXG5cdHN0YXRpYyBudW1iZXJUb0J5dGVzKG51bWJlciwgYnl0ZXNOZWVkZWQpIHtcblx0XHRieXRlc05lZWRlZCA9IGJ5dGVzTmVlZGVkIHx8IDE7XG5cblx0XHR2YXIgaGV4U3RyaW5nID0gbnVtYmVyLnRvU3RyaW5nKDE2KTtcblxuXHRcdGlmIChoZXhTdHJpbmcubGVuZ3RoICYgMSkgeyAvLyBNYWtlIHN1cmUgaGV4IHN0cmluZyBpcyBldmVuIG51bWJlciBvZiBjaGFyc1xuXHRcdFx0aGV4U3RyaW5nID0gJzAnICsgaGV4U3RyaW5nO1xuXHRcdH1cblxuXHRcdC8vIFNwbGl0IGhleCBzdHJpbmcgaW50byBhbiBhcnJheSBvZiB0d28gY2hhciBlbGVtZW50c1xuXHRcdHZhciBoZXhBcnJheSA9IGhleFN0cmluZy5tYXRjaCgvLnsyfS9nKTtcblxuXHRcdC8vIE5vdyBwYXJzZSB0aGVtIG91dCBhcyBpbnRlZ2Vyc1xuXHRcdGhleEFycmF5ID0gaGV4QXJyYXkubWFwKGl0ZW0gPT4gcGFyc2VJbnQoaXRlbSwgMTYpKVxuXG5cdFx0Ly8gUHJlcGVuZCBlbXB0eSBieXRlcyBpZiB3ZSBkb24ndCBoYXZlIGVub3VnaFxuXHRcdGlmIChoZXhBcnJheS5sZW5ndGggPCBieXRlc05lZWRlZCkge1xuXHRcdFx0d2hpbGUgKGJ5dGVzTmVlZGVkIC0gaGV4QXJyYXkubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRoZXhBcnJheS51bnNoaWZ0KDApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBoZXhBcnJheTtcblx0fVxuXG5cdC8qKlx0XG5cdCAqIENvbnZlcnRzIHZhbHVlIHRvIGFycmF5IGlmIG5lZWRlZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG5cdCAqIEByZXR1cm4ge2FycmF5fVxuXHQgKi9cblx0c3RhdGljIHRvQXJyYXkodmFsdWUpIHtcblx0XHRpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB2YWx1ZTtcblx0XHRyZXR1cm4gW3ZhbHVlXTtcblx0fVxufVxuXG5leHBvcnQge1V0aWxzfTtcbmNsYXNzIFZleEZsb3cge1xuXHRcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0Ly8gY29kZS4uLlxuXHR9XG5cblx0LyoqXG5cdCAqIFN1cHBvcnQgZm9yIGNvbnZlcnRpbmcgVmV4RmxvdyB2b2ljZSBpbnRvIE1pZGlXcml0ZXJKUyB0cmFja1xuXHQgKiBAcmV0dXJuIE1pZGlXcml0aWVyLlRyYWNrIG9iamVjdFxuXHQgKi9cblx0dHJhY2tGcm9tVm9pY2Uodm9pY2UpIHtcblx0XHR2YXIgdHJhY2sgPSBuZXcgVHJhY2soKTtcblx0XHR2YXIgd2FpdDtcblx0XHR2YXIgcGl0Y2hlcyA9IFtdO1xuXG5cdFx0dm9pY2UudGlja2FibGVzLmZvckVhY2goZnVuY3Rpb24odGlja2FibGUpIHtcblx0XHRcdHBpdGNoZXMgPSBbXTtcblxuXHRcdFx0aWYgKHRpY2thYmxlLm5vdGVUeXBlID09PSAnbicpIHtcblx0XHRcdFx0dGlja2FibGUua2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuXHRcdFx0XHRcdC8vIGJ1aWxkIGFycmF5IG9mIHBpdGNoZXNcblx0XHRcdFx0XHRwaXRjaGVzLnB1c2godGhpcy5jb252ZXJ0UGl0Y2goa2V5KSk7XG5cdFx0XHRcdH0pO1xuXG5cdFx0XHR9IGVsc2UgaWYgKHRpY2thYmxlLm5vdGVUeXBlID09PSAncicpIHtcblx0XHRcdFx0Ly8gbW92ZSBvbiB0byB0aGUgbmV4dCB0aWNrYWJsZSBhbmQgdXNlIHRoaXMgcmVzdCBhcyBhIGB3YWl0YCBwcm9wZXJ0eSBmb3IgdGhlIG5leHQgZXZlbnRcblx0XHRcdFx0d2FpdCA9IHRoaXMuY29udmVydER1cmF0aW9uKHRpY2thYmxlKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR0cmFjay5hZGRFdmVudChuZXcgTm90ZUV2ZW50KHtwaXRjaDogcGl0Y2hlcywgZHVyYXRpb246IHRoaXMuY29udmVydER1cmF0aW9uKHRpY2thYmxlKSwgd2FpdDogd2FpdH0pKTtcblx0XHRcdFxuXHRcdFx0Ly8gcmVzZXQgd2FpdFxuXHRcdFx0d2FpdCA9IDA7XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gdHJhY2s7XG5cdH1cblxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBWZXhGbG93IHBpdGNoIHN5bnRheCB0byBNaWRpV3JpdGVySlMgc3ludGF4XG5cdCAqIEBwYXJhbSBwaXRjaCBzdHJpbmdcblx0ICovXG5cdGNvbnZlcnRQaXRjaChwaXRjaCkge1xuXHRcdHJldHVybiBwaXRjaC5yZXBsYWNlKCcvJywgJycpO1xuXHR9IFxuXG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIFZleEZsb3cgZHVyYXRpb24gc3ludGF4IHRvIE1pZGlXcml0ZXJKUyBzeW50YXhcblx0ICogQHBhcmFtIG5vdGUgc3RydWN0IGZyb20gVmV4Rmxvd1xuXHQgKi9cblx0Y29udmVydER1cmF0aW9uKG5vdGUpIHtcblx0XHRzd2l0Y2ggKG5vdGUuZHVyYXRpb24pIHtcblx0XHRcdGNhc2UgJ3cnOlxuXHRcdFx0XHRyZXR1cm4gJzEnO1xuXHRcdFx0Y2FzZSAnaCc6XG5cdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDInIDogJzInO1xuXHRcdFx0Y2FzZSAncSc6XG5cdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDQnIDogJzQnO1xuXHRcdFx0Y2FzZSAnOCc6XG5cdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDgnIDogJzgnO1xuXHRcdH1cblxuXHRcdHJldHVybiBub3RlLmR1cmF0aW9uO1xuXHR9O1xufVxuXG5leHBvcnQge1ZleEZsb3d9O1xuLyoqXG4gKiBPYmplY3QgdGhhdCBwdXRzIHRvZ2V0aGVyIHRyYWNrcyBhbmQgcHJvdmlkZXMgbWV0aG9kcyBmb3IgZmlsZSBvdXRwdXQuXG4gKiBAcGFyYW0ge2FycmF5fSB0cmFja3MgLSBBbiBhcnJheSBvZiB7VHJhY2t9IG9iamVjdHMuXG4gKiBAcmV0dXJuIHtXcml0ZXJ9XG4gKi9cbmNsYXNzIFdyaXRlciB7XG5cdGNvbnN0cnVjdG9yKHRyYWNrcykge1xuXHRcdHRoaXMuZGF0YSA9IFtdO1xuXG5cdFx0dmFyIHRyYWNrVHlwZSA9IHRyYWNrcy5sZW5ndGggPiAxID8gQ29uc3RhbnRzLkhFQURFUl9DSFVOS19GT1JNQVQxIDogQ29uc3RhbnRzLkhFQURFUl9DSFVOS19GT1JNQVQwO1xuXHRcdHZhciBudW1iZXJPZlRyYWNrcyA9IFV0aWxzLm51bWJlclRvQnl0ZXModHJhY2tzLmxlbmd0aCwgMik7IC8vIHR3byBieXRlcyBsb25nXG5cblx0XHQvLyBIZWFkZXIgY2h1bmtcblx0XHR0aGlzLmRhdGEucHVzaChuZXcgQ2h1bmsoe1xuXHRcdFx0XHRcdFx0XHRcdHR5cGU6IENvbnN0YW50cy5IRUFERVJfQ0hVTktfVFlQRSxcblx0XHRcdFx0XHRcdFx0XHRkYXRhOiB0cmFja1R5cGUuY29uY2F0KG51bWJlck9mVHJhY2tzLCBDb25zdGFudHMuSEVBREVSX0NIVU5LX0RJVklTSU9OKX0pKTtcblxuXHRcdC8vIFRyYWNrIGNodW5rc1xuXHRcdHRyYWNrcy5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrLCBpKSB7XG5cdFx0XHR0cmFjay5hZGRFdmVudChuZXcgTWV0YUV2ZW50KHtkYXRhOiBDb25zdGFudHMuTUVUQV9FTkRfT0ZfVFJBQ0tfSUR9KSk7XG5cdFx0XHR0aGlzLmRhdGEucHVzaCh0cmFjayk7XG5cdFx0fSwgdGhpcyk7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIHRoZSBmaWxlIGludG8gYSBVaW50OEFycmF5XG5cdCAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9XG5cdCAqL1xuXHRidWlsZEZpbGUoKSB7XG5cdFx0dmFyIGJ1aWxkID0gW107XG5cblx0XHQvLyBEYXRhIGNvbnNpc3RzIG9mIGNodW5rcyB3aGljaCBjb25zaXN0cyBvZiBkYXRhXG5cdFx0dGhpcy5kYXRhLmZvckVhY2goKGQpID0+IGJ1aWxkID0gYnVpbGQuY29uY2F0KGQudHlwZSwgZC5zaXplLCBkLmRhdGEpKTtcblxuXHRcdHJldHVybiBuZXcgVWludDhBcnJheShidWlsZCk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydCBmaWxlIGJ1ZmZlciB0byBhIGJhc2U2NCBzdHJpbmcuICBEaWZmZXJlbnQgbWV0aG9kcyBkZXBlbmRpbmcgb24gaWYgYnJvd3NlciBvciBub2RlLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRiYXNlNjQoKSB7XG5cdFx0aWYgKHR5cGVvZiBidG9hID09PSAnZnVuY3Rpb24nKSByZXR1cm4gYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIHRoaXMuYnVpbGRGaWxlKCkpKTtcblx0XHRyZXR1cm4gbmV3IEJ1ZmZlcih0aGlzLmJ1aWxkRmlsZSgpKS50b1N0cmluZygnYmFzZTY0Jyk7XG5cdH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZGF0YSBVUkkuXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqL1xuICAgIGRhdGFVcmkoKSB7XG4gICAgXHRyZXR1cm4gJ2RhdGE6YXVkaW8vbWlkaTtiYXNlNjQsJyArIHRoaXMuYmFzZTY0KCk7XG4gICAgfVxuXG5cdC8qKlxuXHQgKiBPdXRwdXQgdG8gc3Rkb3V0XG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG4gICAgc3Rkb3V0KCkge1xuICAgIFx0cmV0dXJuIHByb2Nlc3Muc3Rkb3V0LndyaXRlKG5ldyBCdWZmZXIodGhpcy5idWlsZEZpbGUoKSkpO1xuICAgIH1cblxuXHQvKipcblx0ICogU2F2ZSB0byBNSURJIGZpbGVcblx0ICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lXG5cdCAqL1xuXHRzYXZlTUlESShmaWxlbmFtZSkge1xuXHRcdHZhciBidWZmZXIgPSBuZXcgQnVmZmVyKHRoaXMuYnVpbGRGaWxlKCkpO1xuXHRcdGZzLndyaXRlRmlsZShmaWxlbmFtZSArICcubWlkJywgYnVmZmVyLCBmdW5jdGlvbiAoZXJyKSB7XG5cdFx0XHRpZihlcnIpIHJldHVybiBjb25zb2xlLmxvZyhlcnIpO1xuXHRcdH0pO1xuXHR9XG59XG5cbmV4cG9ydCB7V3JpdGVyfTtcbiJdfQ==\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/midi-writer-js/build/index.js\n// module id = 135\n// module chunks = 0","'use strict'\n\n// util\nfunction fillStr (s, num) { return Array(num + 1).join(s) }\nfunction isNum (x) { return typeof x === 'number' }\nfunction isStr (x) { return typeof x === 'string' }\nfunction isDef (x) { return typeof x !== 'undefined' }\nfunction midiToFreq (midi, tuning) {\n return Math.pow(2, (midi - 69) / 12) * (tuning || 440)\n}\n\nvar REGEX = /^([a-gA-G])(#{1,}|b{1,}|x{1,}|)(-?\\d*)\\s*(.*)\\s*$/\n/**\n * A regex for matching note strings in scientific notation.\n *\n * @name regex\n * @function\n * @return {RegExp} the regexp used to parse the note name\n *\n * The note string should have the form `letter[accidentals][octave][element]`\n * where:\n *\n * - letter: (Required) is a letter from A to G either upper or lower case\n * - accidentals: (Optional) can be one or more `b` (flats), `#` (sharps) or `x` (double sharps).\n * They can NOT be mixed.\n * - octave: (Optional) a positive or negative integer\n * - element: (Optional) additionally anything after the duration is considered to\n * be the element name (for example: 'C2 dorian')\n *\n * The executed regex contains (by array index):\n *\n * - 0: the complete string\n * - 1: the note letter\n * - 2: the optional accidentals\n * - 3: the optional octave\n * - 4: the rest of the string (trimmed)\n *\n * @example\n * var parser = require('note-parser')\n * parser.regex.exec('c#4')\n * // => ['c#4', 'c', '#', '4', '']\n * parser.regex.exec('c#4 major')\n * // => ['c#4major', 'c', '#', '4', 'major']\n * parser.regex().exec('CMaj7')\n * // => ['CMaj7', 'C', '', '', 'Maj7']\n */\nexport function regex () { return REGEX }\n\nvar SEMITONES = [0, 2, 4, 5, 7, 9, 11]\n/**\n * Parse a note name in scientific notation an return it's components,\n * and some numeric properties including midi number and frequency.\n *\n * @name parse\n * @function\n * @param {String} note - the note string to be parsed\n * @param {Boolean} isTonic - true the strings it's supposed to contain a note number\n * and some category (for example an scale: 'C# major'). It's false by default,\n * but when true, en extra tonicOf property is returned with the category ('major')\n * @param {Float} tunning - The frequency of A4 note to calculate frequencies.\n * By default it 440.\n * @return {Object} the parsed note name or null if not a valid note\n *\n * The parsed note name object will ALWAYS contains:\n * - letter: the uppercase letter of the note\n * - acc: the accidentals of the note (only sharps or flats)\n * - pc: the pitch class (letter + acc)\n * - step: s a numeric representation of the letter. It's an integer from 0 to 6\n * where 0 = C, 1 = D ... 6 = B\n * - alt: a numeric representation of the accidentals. 0 means no alteration,\n * positive numbers are for sharps and negative for flats\n * - chroma: a numeric representation of the pitch class. It's like midi for\n * pitch classes. 0 = C, 1 = C#, 2 = D ... 11 = B. Can be used to find enharmonics\n * since, for example, chroma of 'Cb' and 'B' are both 11\n *\n * If the note has octave, the parser object will contain:\n * - oct: the octave number (as integer)\n * - midi: the midi number\n * - freq: the frequency (using tuning parameter as base)\n *\n * If the parameter `isTonic` is set to true, the parsed object will contain:\n * - tonicOf: the rest of the string that follows note name (left and right trimmed)\n *\n * @example\n * var parse = require('note-parser').parse\n * parse('Cb4')\n * // => { letter: 'C', acc: 'b', pc: 'Cb', step: 0, alt: -1, chroma: -1,\n * oct: 4, midi: 59, freq: 246.94165062806206 }\n * // if no octave, no midi, no freq\n * parse('fx')\n * // => { letter: 'F', acc: '##', pc: 'F##', step: 3, alt: 2, chroma: 7 })\n */\nexport function parse (str, isTonic, tuning) {\n if (typeof str !== 'string') return null\n var m = REGEX.exec(str)\n if (!m || (!isTonic && m[4])) return null\n\n var p = { letter: m[1].toUpperCase(), acc: m[2].replace(/x/g, '##') }\n p.pc = p.letter + p.acc\n p.step = (p.letter.charCodeAt(0) + 3) % 7\n p.alt = p.acc[0] === 'b' ? -p.acc.length : p.acc.length\n var pos = SEMITONES[p.step] + p.alt\n p.chroma = pos < 0 ? 12 + pos : pos % 12\n if (m[3]) { // has octave\n p.oct = +m[3]\n p.midi = pos + 12 * (p.oct + 1)\n p.freq = midiToFreq(p.midi, tuning)\n }\n if (isTonic) p.tonicOf = m[4]\n return p\n}\n\nvar LETTERS = 'CDEFGAB'\nfunction accStr (n) { return !isNum(n) ? '' : n < 0 ? fillStr('b', -n) : fillStr('#', n) }\nfunction octStr (n) { return !isNum(n) ? '' : '' + n }\n\n/**\n * Create a string from a parsed object or `step, alteration, octave` parameters\n * @param {Object} obj - the parsed data object\n * @return {String} a note string or null if not valid parameters\n * @since 1.2\n * @example\n * parser.build(parser.parse('cb2')) // => 'Cb2'\n *\n * @example\n * // it accepts (step, alteration, octave) parameters:\n * parser.build(3) // => 'F'\n * parser.build(3, -1) // => 'Fb'\n * parser.build(3, -1, 4) // => 'Fb4'\n */\nexport function build (s, a, o) {\n if (s === null || typeof s === 'undefined') return null\n if (s.step) return build(s.step, s.alt, s.oct)\n if (s < 0 || s > 6) return null\n return LETTERS.charAt(s) + accStr(a) + octStr(o)\n}\n\n/**\n * Get midi of a note\n *\n * @name midi\n * @function\n * @param {String|Integer} note - the note name or midi number\n * @return {Integer} the midi number of the note or null if not a valid note\n * or the note does NOT contains octave\n * @example\n * var parser = require('note-parser')\n * parser.midi('A4') // => 69\n * parser.midi('A') // => null\n * @example\n * // midi numbers are bypassed (even as strings)\n * parser.midi(60) // => 60\n * parser.midi('60') // => 60\n */\nexport function midi (note) {\n if ((isNum(note) || isStr(note)) && note >= 0 && note < 128) return +note\n var p = parse(note)\n return p && isDef(p.midi) ? p.midi : null\n}\n\n/**\n * Get freq of a note in hertzs (in a well tempered 440Hz A4)\n *\n * @name freq\n * @function\n * @param {String} note - the note name or note midi number\n * @param {String} tuning - (Optional) the A4 frequency (440 by default)\n * @return {Float} the freq of the number if hertzs or null if not valid note\n * @example\n * var parser = require('note-parser')\n * parser.freq('A4') // => 440\n * parser.freq('A') // => null\n * @example\n * // can change tuning (440 by default)\n * parser.freq('A4', 444) // => 444\n * parser.freq('A3', 444) // => 222\n * @example\n * // it accepts midi numbers (as numbers and as strings)\n * parser.freq(69) // => 440\n * parser.freq('69', 442) // => 442\n */\nexport function freq (note, tuning) {\n var m = midi(note)\n return m === null ? null : midiToFreq(m, tuning)\n}\n\nexport function letter (src) { return (parse(src) || {}).letter }\nexport function acc (src) { return (parse(src) || {}).acc }\nexport function pc (src) { return (parse(src) || {}).pc }\nexport function step (src) { return (parse(src) || {}).step }\nexport function alt (src) { return (parse(src) || {}).alt }\nexport function chroma (src) { return (parse(src) || {}).chroma }\nexport function oct (src) { return (parse(src) || {}).oct }\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/note-parser/index.js\n// module id = 136\n// module chunks = 0","module.exports = require('./lib/_stream_duplex.js');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/readable-stream/duplex-browser.js\n// module id = 137\n// module chunks = 0","// a passthrough stream.\n// basically just the most minimal sort of Transform stream.\n// Every written chunk gets output as-is.\n\n'use strict';\n\nmodule.exports = PassThrough;\n\nvar Transform = require('./_stream_transform');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(PassThrough, Transform);\n\nfunction PassThrough(options) {\n if (!(this instanceof PassThrough)) return new PassThrough(options);\n\n Transform.call(this, options);\n}\n\nPassThrough.prototype._transform = function (chunk, encoding, cb) {\n cb(null, chunk);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/readable-stream/lib/_stream_passthrough.js\n// module id = 138\n// module chunks = 0","'use strict';\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nmodule.exports = BufferList;\n\nfunction BufferList() {\n this.head = null;\n this.tail = null;\n this.length = 0;\n}\n\nBufferList.prototype.push = function (v) {\n var entry = { data: v, next: null };\n if (this.length > 0) this.tail.next = entry;else this.head = entry;\n this.tail = entry;\n ++this.length;\n};\n\nBufferList.prototype.unshift = function (v) {\n var entry = { data: v, next: this.head };\n if (this.length === 0) this.tail = entry;\n this.head = entry;\n ++this.length;\n};\n\nBufferList.prototype.shift = function () {\n if (this.length === 0) return;\n var ret = this.head.data;\n if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;\n --this.length;\n return ret;\n};\n\nBufferList.prototype.clear = function () {\n this.head = this.tail = null;\n this.length = 0;\n};\n\nBufferList.prototype.join = function (s) {\n if (this.length === 0) return '';\n var p = this.head;\n var ret = '' + p.data;\n while (p = p.next) {\n ret += s + p.data;\n }return ret;\n};\n\nBufferList.prototype.concat = function (n) {\n if (this.length === 0) return bufferShim.alloc(0);\n if (this.length === 1) return this.head.data;\n var ret = bufferShim.allocUnsafe(n >>> 0);\n var p = this.head;\n var i = 0;\n while (p) {\n p.data.copy(ret, i);\n i += p.data.length;\n p = p.next;\n }\n return ret;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/readable-stream/lib/internal/streams/BufferList.js\n// module id = 139\n// module chunks = 0","module.exports = require('./readable').PassThrough\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/readable-stream/passthrough.js\n// module id = 140\n// module chunks = 0","module.exports = require('./readable').Transform\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/readable-stream/transform.js\n// module id = 141\n// module chunks = 0","module.exports = require('./lib/_stream_writable.js');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/readable-stream/writable-browser.js\n// module id = 142\n// module chunks = 0","(function (global, undefined) {\n \"use strict\";\n\n if (global.setImmediate) {\n return;\n }\n\n var nextHandle = 1; // Spec says greater than zero\n var tasksByHandle = {};\n var currentlyRunningATask = false;\n var doc = global.document;\n var registerImmediate;\n\n function setImmediate(callback) {\n // Callback can either be a function or a string\n if (typeof callback !== \"function\") {\n callback = new Function(\"\" + callback);\n }\n // Copy function arguments\n var args = new Array(arguments.length - 1);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i + 1];\n }\n // Store and register the task\n var task = { callback: callback, args: args };\n tasksByHandle[nextHandle] = task;\n registerImmediate(nextHandle);\n return nextHandle++;\n }\n\n function clearImmediate(handle) {\n delete tasksByHandle[handle];\n }\n\n function run(task) {\n var callback = task.callback;\n var args = task.args;\n switch (args.length) {\n case 0:\n callback();\n break;\n case 1:\n callback(args[0]);\n break;\n case 2:\n callback(args[0], args[1]);\n break;\n case 3:\n callback(args[0], args[1], args[2]);\n break;\n default:\n callback.apply(undefined, args);\n break;\n }\n }\n\n function runIfPresent(handle) {\n // From the spec: \"Wait until any invocations of this algorithm started before this one have completed.\"\n // So if we're currently running a task, we'll need to delay this invocation.\n if (currentlyRunningATask) {\n // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a\n // \"too much recursion\" error.\n setTimeout(runIfPresent, 0, handle);\n } else {\n var task = tasksByHandle[handle];\n if (task) {\n currentlyRunningATask = true;\n try {\n run(task);\n } finally {\n clearImmediate(handle);\n currentlyRunningATask = false;\n }\n }\n }\n }\n\n function installNextTickImplementation() {\n registerImmediate = function(handle) {\n process.nextTick(function () { runIfPresent(handle); });\n };\n }\n\n function canUsePostMessage() {\n // The test against `importScripts` prevents this implementation from being installed inside a web worker,\n // where `global.postMessage` means something completely different and can't be used for this purpose.\n if (global.postMessage && !global.importScripts) {\n var postMessageIsAsynchronous = true;\n var oldOnMessage = global.onmessage;\n global.onmessage = function() {\n postMessageIsAsynchronous = false;\n };\n global.postMessage(\"\", \"*\");\n global.onmessage = oldOnMessage;\n return postMessageIsAsynchronous;\n }\n }\n\n function installPostMessageImplementation() {\n // Installs an event handler on `global` for the `message` event: see\n // * https://developer.mozilla.org/en/DOM/window.postMessage\n // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages\n\n var messagePrefix = \"setImmediate$\" + Math.random() + \"$\";\n var onGlobalMessage = function(event) {\n if (event.source === global &&\n typeof event.data === \"string\" &&\n event.data.indexOf(messagePrefix) === 0) {\n runIfPresent(+event.data.slice(messagePrefix.length));\n }\n };\n\n if (global.addEventListener) {\n global.addEventListener(\"message\", onGlobalMessage, false);\n } else {\n global.attachEvent(\"onmessage\", onGlobalMessage);\n }\n\n registerImmediate = function(handle) {\n global.postMessage(messagePrefix + handle, \"*\");\n };\n }\n\n function installMessageChannelImplementation() {\n var channel = new MessageChannel();\n channel.port1.onmessage = function(event) {\n var handle = event.data;\n runIfPresent(handle);\n };\n\n registerImmediate = function(handle) {\n channel.port2.postMessage(handle);\n };\n }\n\n function installReadyStateChangeImplementation() {\n var html = doc.documentElement;\n registerImmediate = function(handle) {\n // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var script = doc.createElement(\"script\");\n script.onreadystatechange = function () {\n runIfPresent(handle);\n script.onreadystatechange = null;\n html.removeChild(script);\n script = null;\n };\n html.appendChild(script);\n };\n }\n\n function installSetTimeoutImplementation() {\n registerImmediate = function(handle) {\n setTimeout(runIfPresent, 0, handle);\n };\n }\n\n // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.\n var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);\n attachTo = attachTo && attachTo.setTimeout ? attachTo : global;\n\n // Don't get fooled by e.g. browserify environments.\n if ({}.toString.call(global.process) === \"[object process]\") {\n // For Node.js before 0.9\n installNextTickImplementation();\n\n } else if (canUsePostMessage()) {\n // For non-IE10 modern browsers\n installPostMessageImplementation();\n\n } else if (global.MessageChannel) {\n // For web workers, where supported\n installMessageChannelImplementation();\n\n } else if (doc && \"onreadystatechange\" in doc.createElement(\"script\")) {\n // For IE 6–8\n installReadyStateChangeImplementation();\n\n } else {\n // For older browsers\n installSetTimeoutImplementation();\n }\n\n attachTo.setImmediate = setImmediate;\n attachTo.clearImmediate = clearImmediate;\n}(typeof self === \"undefined\" ? typeof global === \"undefined\" ? this : global : self));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/setimmediate/setImmediate.js\n// module id = 143\n// module chunks = 0","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Stream;\n\nvar EE = require('events').EventEmitter;\nvar inherits = require('inherits');\n\ninherits(Stream, EE);\nStream.Readable = require('readable-stream/readable.js');\nStream.Writable = require('readable-stream/writable.js');\nStream.Duplex = require('readable-stream/duplex.js');\nStream.Transform = require('readable-stream/transform.js');\nStream.PassThrough = require('readable-stream/passthrough.js');\n\n// Backwards-compat with node 0.4.x\nStream.Stream = Stream;\n\n\n\n// old-style streams. Note that the pipe method (the only relevant\n// part of this class) is overridden in the Readable class.\n\nfunction Stream() {\n EE.call(this);\n}\n\nStream.prototype.pipe = function(dest, options) {\n var source = this;\n\n function ondata(chunk) {\n if (dest.writable) {\n if (false === dest.write(chunk) && source.pause) {\n source.pause();\n }\n }\n }\n\n source.on('data', ondata);\n\n function ondrain() {\n if (source.readable && source.resume) {\n source.resume();\n }\n }\n\n dest.on('drain', ondrain);\n\n // If the 'end' option is not supplied, dest.end() will be called when\n // source gets the 'end' or 'close' events. Only dest.end() once.\n if (!dest._isStdio && (!options || options.end !== false)) {\n source.on('end', onend);\n source.on('close', onclose);\n }\n\n var didOnEnd = false;\n function onend() {\n if (didOnEnd) return;\n didOnEnd = true;\n\n dest.end();\n }\n\n\n function onclose() {\n if (didOnEnd) return;\n didOnEnd = true;\n\n if (typeof dest.destroy === 'function') dest.destroy();\n }\n\n // don't leave dangling pipes when there are errors.\n function onerror(er) {\n cleanup();\n if (EE.listenerCount(this, 'error') === 0) {\n throw er; // Unhandled stream error in pipe.\n }\n }\n\n source.on('error', onerror);\n dest.on('error', onerror);\n\n // remove all the event listeners that were added.\n function cleanup() {\n source.removeListener('data', ondata);\n dest.removeListener('drain', ondrain);\n\n source.removeListener('end', onend);\n source.removeListener('close', onclose);\n\n source.removeListener('error', onerror);\n dest.removeListener('error', onerror);\n\n source.removeListener('end', cleanup);\n source.removeListener('close', cleanup);\n\n dest.removeListener('close', cleanup);\n }\n\n source.on('end', cleanup);\n source.on('close', cleanup);\n\n dest.on('close', cleanup);\n\n dest.emit('pipe', source);\n\n // Allow for unix-like usage: A.pipe(B).pipe(C)\n return dest;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/stream-browserify/index.js\n// module id = 144\n// module chunks = 0","/**\n * A midi note number is a number representation of a note pitch. It can be\n * integers so it's equal tempered tuned, or float to indicate it's not\n * tuned into equal temepered scale.\n *\n * This module contains functions to convert to and from midi notes.\n *\n * @example\n * var midi = require('tonal-midi')\n * midi.toMidi('A4') // => 69\n * midi.note(69) // => 'A4'\n * midi.note(61) // => 'Db4'\n * midi.note(61, true) // => 'C#4'\n *\n * @module midi\n */\n\nimport { midi } from 'note-parser'\n\n/**\n * Convert the given note to a midi note number. If you pass a midi number it\n * will returned as is.\n *\n * @param {Array|String|Number} note - the note to get the midi number from\n * @return {Integer} the midi number or null if not valid pitch\n * @example\n * midi.toMidi('C4') // => 60\n * midi.toMidi(60) // => 60\n * midi.toMidi('60') // => 60\n */\nexport function toMidi (val) {\n if (Array.isArray(val) && val.length === 2) return val[0] * 7 + val[1] * 12 + 12\n return midi(val)\n}\n\nvar FLATS = 'C Db D Eb E F Gb G Ab A Bb B'.split(' ')\nvar SHARPS = 'C C# D D# E F F# G G# A A# B'.split(' ')\n\n/**\n * Given a midi number, returns a note name. The altered notes will have\n * flats unless explicitly set with the optional `useSharps` parameter.\n *\n * @function\n * @param {Integer} midi - the midi note number\n * @param {Boolean} useSharps - (Optional) set to true to use sharps instead of flats\n * @return {String} the note name\n * @example\n * var midi = require('tonal-midi')\n * midi.note(61) // => 'Db4'\n * midi.note(61, true) // => 'C#4'\n * // it rounds to nearest note\n * midi.note(61.7) // => 'D4'\n */\nexport function note (num, sharps) {\n if (num === true || num === false) return function (m) { return note(m, num) }\n num = Math.round(num)\n var pcs = sharps === true ? SHARPS : FLATS\n var pc = pcs[num % 12]\n var o = Math.floor(num / 12) - 1\n return pc + o\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/tonal-midi/index.js\n// module id = 145\n// module chunks = 0","\n/**\n * Module exports.\n */\n\nmodule.exports = deprecate;\n\n/**\n * Mark that a method should not be used.\n * Returns a modified function which warns once by default.\n *\n * If `localStorage.noDeprecation = true` is set, then it is a no-op.\n *\n * If `localStorage.throwDeprecation = true` is set, then deprecated functions\n * will throw an Error when invoked.\n *\n * If `localStorage.traceDeprecation = true` is set, then deprecated functions\n * will invoke `console.trace()` instead of `console.error()`.\n *\n * @param {Function} fn - the function to deprecate\n * @param {String} msg - the string to print to the console when `fn` is invoked\n * @returns {Function} a new \"deprecated\" version of `fn`\n * @api public\n */\n\nfunction deprecate (fn, msg) {\n if (config('noDeprecation')) {\n return fn;\n }\n\n var warned = false;\n function deprecated() {\n if (!warned) {\n if (config('throwDeprecation')) {\n throw new Error(msg);\n } else if (config('traceDeprecation')) {\n console.trace(msg);\n } else {\n console.warn(msg);\n }\n warned = true;\n }\n return fn.apply(this, arguments);\n }\n\n return deprecated;\n}\n\n/**\n * Checks `localStorage` for boolean values for the given `name`.\n *\n * @param {String} name\n * @returns {Boolean}\n * @api private\n */\n\nfunction config (name) {\n // accessing global.localStorage can trigger a DOMException in sandboxed iframes\n try {\n if (!global.localStorage) return false;\n } catch (_) {\n return false;\n }\n var val = global.localStorage[name];\n if (null == val) return false;\n return String(val).toLowerCase() === 'true';\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/util-deprecate/browser.js\n// module id = 146\n// module chunks = 0","if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/util/~/inherits/inherits_browser.js\n// module id = 147\n// module chunks = 0","module.exports = function isBuffer(arg) {\n return arg && typeof arg === 'object'\n && typeof arg.copy === 'function'\n && typeof arg.fill === 'function'\n && typeof arg.readUInt8 === 'function';\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/util/support/isBufferBrowser.js\n// module id = 148\n// module chunks = 0","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n if (!isString(f)) {\n var objects = [];\n for (var i = 0; i < arguments.length; i++) {\n objects.push(inspect(arguments[i]));\n }\n return objects.join(' ');\n }\n\n var i = 1;\n var args = arguments;\n var len = args.length;\n var str = String(f).replace(formatRegExp, function(x) {\n if (x === '%%') return '%';\n if (i >= len) return x;\n switch (x) {\n case '%s': return String(args[i++]);\n case '%d': return Number(args[i++]);\n case '%j':\n try {\n return JSON.stringify(args[i++]);\n } catch (_) {\n return '[Circular]';\n }\n default:\n return x;\n }\n });\n for (var x = args[i]; i < len; x = args[++i]) {\n if (isNull(x) || !isObject(x)) {\n str += ' ' + x;\n } else {\n str += ' ' + inspect(x);\n }\n }\n return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n // Allow for deprecating things in the process of starting up.\n if (isUndefined(global.process)) {\n return function() {\n return exports.deprecate(fn, msg).apply(this, arguments);\n };\n }\n\n if (process.noDeprecation === true) {\n return fn;\n }\n\n var warned = false;\n function deprecated() {\n if (!warned) {\n if (process.throwDeprecation) {\n throw new Error(msg);\n } else if (process.traceDeprecation) {\n console.trace(msg);\n } else {\n console.error(msg);\n }\n warned = true;\n }\n return fn.apply(this, arguments);\n }\n\n return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n if (isUndefined(debugEnviron))\n debugEnviron = process.env.NODE_DEBUG || '';\n set = set.toUpperCase();\n if (!debugs[set]) {\n if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n var pid = process.pid;\n debugs[set] = function() {\n var msg = exports.format.apply(exports, arguments);\n console.error('%s %d: %s', set, pid, msg);\n };\n } else {\n debugs[set] = function() {};\n }\n }\n return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n // default options\n var ctx = {\n seen: [],\n stylize: stylizeNoColor\n };\n // legacy...\n if (arguments.length >= 3) ctx.depth = arguments[2];\n if (arguments.length >= 4) ctx.colors = arguments[3];\n if (isBoolean(opts)) {\n // legacy...\n ctx.showHidden = opts;\n } else if (opts) {\n // got an \"options\" object\n exports._extend(ctx, opts);\n }\n // set default options\n if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n if (isUndefined(ctx.depth)) ctx.depth = 2;\n if (isUndefined(ctx.colors)) ctx.colors = false;\n if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n if (ctx.colors) ctx.stylize = stylizeWithColor;\n return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n 'bold' : [1, 22],\n 'italic' : [3, 23],\n 'underline' : [4, 24],\n 'inverse' : [7, 27],\n 'white' : [37, 39],\n 'grey' : [90, 39],\n 'black' : [30, 39],\n 'blue' : [34, 39],\n 'cyan' : [36, 39],\n 'green' : [32, 39],\n 'magenta' : [35, 39],\n 'red' : [31, 39],\n 'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n 'special': 'cyan',\n 'number': 'yellow',\n 'boolean': 'yellow',\n 'undefined': 'grey',\n 'null': 'bold',\n 'string': 'green',\n 'date': 'magenta',\n // \"name\": intentionally not styling\n 'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n var style = inspect.styles[styleType];\n\n if (style) {\n return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n '\\u001b[' + inspect.colors[style][1] + 'm';\n } else {\n return str;\n }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n return str;\n}\n\n\nfunction arrayToHash(array) {\n var hash = {};\n\n array.forEach(function(val, idx) {\n hash[val] = true;\n });\n\n return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (ctx.customInspect &&\n value &&\n isFunction(value.inspect) &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes, ctx);\n if (!isString(ret)) {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // Look up the keys of the object.\n var keys = Object.keys(value);\n var visibleKeys = arrayToHash(keys);\n\n if (ctx.showHidden) {\n keys = Object.getOwnPropertyNames(value);\n }\n\n // IE doesn't make error fields non-enumerable\n // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n if (isError(value)\n && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n return formatError(value);\n }\n\n // Some type of object without properties can be shortcutted.\n if (keys.length === 0) {\n if (isFunction(value)) {\n var name = value.name ? ': ' + value.name : '';\n return ctx.stylize('[Function' + name + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (isFunction(value)) {\n var n = value.name ? ': ' + value.name : '';\n base = ' [Function' + n + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n base = ' ' + formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n if (isUndefined(value))\n return ctx.stylize('undefined', 'undefined');\n if (isString(value)) {\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n }\n if (isNumber(value))\n return ctx.stylize('' + value, 'number');\n if (isBoolean(value))\n return ctx.stylize('' + value, 'boolean');\n // For some reason typeof null is \"object\", so special case here.\n if (isNull(value))\n return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (hasOwnProperty(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str, desc;\n desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n if (desc.get) {\n if (desc.set) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (desc.set) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n if (!hasOwnProperty(visibleKeys, key)) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(desc.value) < 0) {\n if (isNull(recurseTimes)) {\n str = formatValue(ctx, desc.value, null);\n } else {\n str = formatValue(ctx, desc.value, recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (isUndefined(name)) {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n return isObject(e) &&\n (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n return arg === null ||\n typeof arg === 'boolean' ||\n typeof arg === 'number' ||\n typeof arg === 'string' ||\n typeof arg === 'symbol' || // ES6 symbol\n typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n 'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n var d = new Date();\n var time = [pad(d.getHours()),\n pad(d.getMinutes()),\n pad(d.getSeconds())].join(':');\n return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n * prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n // Don't do anything if add isn't an object\n if (!add || !isObject(add)) return origin;\n\n var keys = Object.keys(add);\n var i = keys.length;\n while (i--) {\n origin[keys[i]] = add[keys[i]];\n }\n return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/util/util.js\n// module id = 149\n// module chunks = 0","/*\n\nWebMidi v2.2.0\n\nWebMidi.js helps you tame the Web MIDI API. Send and receive MIDI messages with ease. Control instruments with user-friendly functions (playNote, sendPitchBend, etc.). React to MIDI input with simple event listeners (noteon, pitchbend, controlchange, etc.).\nhttps://github.com/djipco/webmidi\n\n\nThe MIT License (MIT)\n\nCopyright (c) 2015-2018, Jean-Philippe Côté\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and\nassociated documentation files (the \"Software\"), to deal in the Software without restriction,\nincluding without limitation the rights to use, copy, modify, merge, publish, distribute,\nsublicense, and/or sell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial\nportions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\nNOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES\nOR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n*/\n\n!function(scope){\"use strict\";function WebMidi(){if(WebMidi.prototype._singleton)throw new Error(\"WebMidi is a singleton, it cannot be instantiated directly.\");WebMidi.prototype._singleton=this,this._inputs=[],this._outputs=[],this._userHandlers={},this._stateChangeQueue=[],this._processingStateChange=!1,this._midiInterfaceEvents=[\"connected\",\"disconnected\"],this._notes=[\"C\",\"C#\",\"D\",\"D#\",\"E\",\"F\",\"F#\",\"G\",\"G#\",\"A\",\"A#\",\"B\"],this._semitones={C:0,D:2,E:4,F:5,G:7,A:9,B:11},Object.defineProperties(this,{MIDI_SYSTEM_MESSAGES:{value:{sysex:240,timecode:241,songposition:242,songselect:243,tuningrequest:246,sysexend:247,clock:248,start:250,\"continue\":251,stop:252,activesensing:254,reset:255,midimessage:0,unknownsystemmessage:-1},writable:!1,enumerable:!0,configurable:!1},MIDI_CHANNEL_MESSAGES:{value:{noteoff:8,noteon:9,keyaftertouch:10,controlchange:11,channelmode:11,programchange:12,channelaftertouch:13,pitchbend:14},writable:!1,enumerable:!0,configurable:!1},MIDI_REGISTERED_PARAMETER:{value:{pitchbendrange:[0,0],channelfinetuning:[0,1],channelcoarsetuning:[0,2],tuningprogram:[0,3],tuningbank:[0,4],modulationrange:[0,5],azimuthangle:[61,0],elevationangle:[61,1],gain:[61,2],distanceratio:[61,3],maximumdistance:[61,4],maximumdistancegain:[61,5],referencedistanceratio:[61,6],panspreadangle:[61,7],rollangle:[61,8]},writable:!1,enumerable:!0,configurable:!1},MIDI_CONTROL_CHANGE_MESSAGES:{value:{bankselectcoarse:0,modulationwheelcoarse:1,breathcontrollercoarse:2,footcontrollercoarse:4,portamentotimecoarse:5,dataentrycoarse:6,volumecoarse:7,balancecoarse:8,pancoarse:10,expressioncoarse:11,effectcontrol1coarse:12,effectcontrol2coarse:13,generalpurposeslider1:16,generalpurposeslider2:17,generalpurposeslider3:18,generalpurposeslider4:19,bankselectfine:32,modulationwheelfine:33,breathcontrollerfine:34,footcontrollerfine:36,portamentotimefine:37,dataentryfine:38,volumefine:39,balancefine:40,panfine:42,expressionfine:43,effectcontrol1fine:44,effectcontrol2fine:45,holdpedal:64,portamento:65,sustenutopedal:66,softpedal:67,legatopedal:68,hold2pedal:69,soundvariation:70,resonance:71,soundreleasetime:72,soundattacktime:73,brightness:74,soundcontrol6:75,soundcontrol7:76,soundcontrol8:77,soundcontrol9:78,soundcontrol10:79,generalpurposebutton1:80,generalpurposebutton2:81,generalpurposebutton3:82,generalpurposebutton4:83,reverblevel:91,tremololevel:92,choruslevel:93,celestelevel:94,phaserlevel:95,databuttonincrement:96,databuttondecrement:97,nonregisteredparametercoarse:98,nonregisteredparameterfine:99,registeredparametercoarse:100,registeredparameterfine:101},writable:!1,enumerable:!0,configurable:!1},MIDI_CHANNEL_MODE_MESSAGES:{value:{allsoundoff:120,resetallcontrollers:121,localcontrol:122,allnotesoff:123,omnimodeoff:124,omnimodeon:125,monomodeon:126,polymodeon:127},writable:!1,enumerable:!0,configurable:!1},octaveOffset:{value:0,writable:!0,enumerable:!0,configurable:!1}}),Object.defineProperties(this,{supported:{enumerable:!0,get:function(){return\"requestMIDIAccess\"in navigator}},enabled:{enumerable:!0,get:function(){return void 0!==this[\"interface\"]}.bind(this)},inputs:{enumerable:!0,get:function(){return this._inputs}.bind(this)},outputs:{enumerable:!0,get:function(){return this._outputs}.bind(this)},sysexEnabled:{enumerable:!0,get:function(){return!(!this[\"interface\"]||!this[\"interface\"].sysexEnabled)}.bind(this)},time:{enumerable:!0,get:function(){return performance.now()}}})}function Input(midiInput){var that=this;this._userHandlers={channel:{},system:{}},this._midiInput=midiInput,Object.defineProperties(this,{connection:{enumerable:!0,get:function(){return that._midiInput.connection}},id:{enumerable:!0,get:function(){return that._midiInput.id}},manufacturer:{enumerable:!0,get:function(){return that._midiInput.manufacturer}},name:{enumerable:!0,get:function(){return that._midiInput.name}},state:{enumerable:!0,get:function(){return that._midiInput.state}},type:{enumerable:!0,get:function(){return that._midiInput.type}}}),this._initializeUserHandlers(),this._midiInput.onmidimessage=this._onMidiMessage.bind(this)}function Output(midiOutput){var that=this;this._midiOutput=midiOutput,Object.defineProperties(this,{connection:{enumerable:!0,get:function(){return that._midiOutput.connection}},id:{enumerable:!0,get:function(){return that._midiOutput.id}},manufacturer:{enumerable:!0,get:function(){return that._midiOutput.manufacturer}},name:{enumerable:!0,get:function(){return that._midiOutput.name}},state:{enumerable:!0,get:function(){return that._midiOutput.state}},type:{enumerable:!0,get:function(){return that._midiOutput.type}}})}var wm=new WebMidi;WebMidi.prototype.enable=function(callback,sysex){return this.enabled?void 0:this.supported?void navigator.requestMIDIAccess({sysex:sysex}).then(function(midiAccess){function onPortsOpen(){clearTimeout(promiseTimeout),this._updateInputsAndOutputs(),this[\"interface\"].onstatechange=this._onInterfaceStateChange.bind(this),\"function\"==typeof callback&&callback.call(this),events.forEach(function(event){this._onInterfaceStateChange(event)}.bind(this))}var promiseTimeout,events=[],promises=[];this[\"interface\"]=midiAccess,this._resetInterfaceUserHandlers(),this[\"interface\"].onstatechange=function(e){events.push(e)};for(var inputs=midiAccess.inputs.values(),input=inputs.next();input&&!input.done;input=inputs.next())promises.push(input.value.open());for(var outputs=midiAccess.outputs.values(),output=outputs.next();output&&!output.done;output=outputs.next())promises.push(output.value.open());promiseTimeout=setTimeout(onPortsOpen.bind(this),200),Promise&&Promise.all(promises)[\"catch\"](function(err){}).then(onPortsOpen.bind(this))}.bind(this),function(err){\"function\"==typeof callback&&callback.call(this,err)}.bind(this)):void(\"function\"==typeof callback&&callback(new Error(\"The Web MIDI API is not supported by your browser.\")))},WebMidi.prototype.disable=function(){if(!this.supported)throw new Error(\"The Web MIDI API is not supported by your browser.\");this[\"interface\"]&&(this[\"interface\"].onstatechange=void 0),this[\"interface\"]=void 0,this._inputs=[],this._outputs=[],this._resetInterfaceUserHandlers()},WebMidi.prototype.addListener=function(type,listener){if(!this.enabled)throw new Error(\"WebMidi must be enabled before adding event listeners.\");if(\"function\"!=typeof listener)throw new TypeError(\"The 'listener' parameter must be a function.\");if(!(this._midiInterfaceEvents.indexOf(type)>=0))throw new TypeError(\"The specified event type is not supported.\");return this._userHandlers[type].push(listener),this},WebMidi.prototype.hasListener=function(type,listener){if(!this.enabled)throw new Error(\"WebMidi must be enabled before checking event listeners.\");if(\"function\"!=typeof listener)throw new TypeError(\"The 'listener' parameter must be a function.\");if(!(this._midiInterfaceEvents.indexOf(type)>=0))throw new TypeError(\"The specified event type is not supported.\");for(var o=0;o<this._userHandlers[type].length;o++)if(this._userHandlers[type][o]===listener)return!0;return!1},WebMidi.prototype.removeListener=function(type,listener){if(!this.enabled)throw new Error(\"WebMidi must be enabled before removing event listeners.\");if(void 0!==listener&&\"function\"!=typeof listener)throw new TypeError(\"The 'listener' parameter must be a function.\");if(this._midiInterfaceEvents.indexOf(type)>=0)if(listener)for(var o=0;o<this._userHandlers[type].length;o++)this._userHandlers[type][o]===listener&&this._userHandlers[type].splice(o,1);else this._userHandlers[type]=[];else{if(void 0!==type)throw new TypeError(\"The specified event type is not supported.\");this._resetInterfaceUserHandlers()}return this},WebMidi.prototype.toMIDIChannels=function(channel){var channels;return channels=\"all\"===channel||void 0===channel?[\"all\"]:Array.isArray(channel)?channel:[channel],channels.indexOf(\"all\")>-1&&(channels=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]),channels.map(function(ch){return parseInt(ch)}).filter(function(ch){return ch>=1&&16>=ch})},WebMidi.prototype.getInputById=function(id){if(!this.enabled)throw new Error(\"WebMidi is not enabled.\");for(var i=0;i<this.inputs.length;i++)if(this.inputs[i].id===id)return this.inputs[i];return!1},WebMidi.prototype.getOutputById=function(id){if(!this.enabled)throw new Error(\"WebMidi is not enabled.\");for(var i=0;i<this.outputs.length;i++)if(this.outputs[i].id===id)return this.outputs[i];return!1},WebMidi.prototype.getInputByName=function(name){if(!this.enabled)throw new Error(\"WebMidi is not enabled.\");for(var i=0;i<this.inputs.length;i++)if(~this.inputs[i].name.indexOf(name))return this.inputs[i];return!1},WebMidi.prototype.getOctave=function(number){return null!=number&&number>=0&&127>=number?Math.floor(Math.floor(number)/12-1)+Math.floor(wm.octaveOffset):void 0},WebMidi.prototype.getOutputByName=function(name){if(!this.enabled)throw new Error(\"WebMidi is not enabled.\");for(var i=0;i<this.outputs.length;i++)if(~this.outputs[i].name.indexOf(name))return this.outputs[i];return!1},WebMidi.prototype.guessNoteNumber=function(input){var output=!1;if(input&&input.toFixed&&input>=0&&127>=input?output=Math.round(input):parseInt(input)>=0&&parseInt(input)<=127?output=parseInt(input):(\"string\"==typeof input||input instanceof String)&&(output=this.noteNameToNumber(input)),output===!1)throw new Error(\"Invalid input value (\"+input+\").\");return output},WebMidi.prototype.noteNameToNumber=function(name){\"string\"!=typeof name&&(name=\"\");var matches=name.match(/([CDEFGAB])(#{0,2}|b{0,2})(-?\\d+)/i);if(!matches)throw new RangeError(\"Invalid note name.\");var semitones=wm._semitones[matches[1].toUpperCase()],octave=parseInt(matches[3]),result=12*(octave+1-Math.floor(wm.octaveOffset))+semitones;if(matches[2].toLowerCase().indexOf(\"b\")>-1?result-=matches[2].length:matches[2].toLowerCase().indexOf(\"#\")>-1&&(result+=matches[2].length),0>result||result>127)throw new RangeError(\"Invalid note name or note outside valid range.\");return result},WebMidi.prototype._updateInputsAndOutputs=function(){this._updateInputs(),this._updateOutputs()},WebMidi.prototype._updateInputs=function(){for(var i=0;i<this._inputs.length;i++){for(var remove=!0,updated=this[\"interface\"].inputs.values(),input=updated.next();input&&!input.done;input=updated.next())if(this._inputs[i]._midiInput===input.value){remove=!1;break}remove&&this._inputs.splice(i,1)}this[\"interface\"]&&this[\"interface\"].inputs.forEach(function(nInput){for(var add=!0,j=0;j<this._inputs.length;j++)this._inputs[j]._midiInput===nInput&&(add=!1);add&&this._inputs.push(new Input(nInput))}.bind(this))},WebMidi.prototype._updateOutputs=function(){for(var i=0;i<this._outputs.length;i++){for(var remove=!0,updated=this[\"interface\"].outputs.values(),output=updated.next();output&&!output.done;output=updated.next())if(this._outputs[i]._midiOutput===output.value){remove=!1;break}remove&&this._outputs.splice(i,1)}this[\"interface\"]&&this[\"interface\"].outputs.forEach(function(nOutput){for(var add=!0,j=0;j<this._outputs.length;j++)this._outputs[j]._midiOutput===nOutput&&(add=!1);add&&this._outputs.push(new Output(nOutput))}.bind(this))},WebMidi.prototype._onInterfaceStateChange=function(e){this._updateInputsAndOutputs();var event={timestamp:e.timeStamp,type:e.port.state};this[\"interface\"]&&\"connected\"===e.port.state?\"output\"===e.port.type?event.port=this.getOutputById(e.port.id):\"input\"===e.port.type&&(event.port=this.getInputById(e.port.id)):event.port={connection:\"closed\",id:e.port.id,manufacturer:e.port.manufacturer,name:e.port.name,state:e.port.state,type:e.port.type},this._userHandlers[e.port.state].forEach(function(handler){handler(event)})},WebMidi.prototype._resetInterfaceUserHandlers=function(){for(var i=0;i<this._midiInterfaceEvents.length;i++)this._userHandlers[this._midiInterfaceEvents[i]]=[]},Input.prototype.addListener=function(type,channel,listener){var that=this;if(void 0===channel&&(channel=\"all\"),Array.isArray(channel)||(channel=[channel]),channel.forEach(function(item){if(\"all\"!==item&&!(item>=1&&16>=item))throw new RangeError(\"The 'channel' parameter is invalid.\")}),\"function\"!=typeof listener)throw new TypeError(\"The 'listener' parameter must be a function.\");if(void 0!==wm.MIDI_SYSTEM_MESSAGES[type])this._userHandlers.system[type]||(this._userHandlers.system[type]=[]),this._userHandlers.system[type].push(listener);else{if(void 0===wm.MIDI_CHANNEL_MESSAGES[type])throw new TypeError(\"The specified event type is not supported.\");if(channel.indexOf(\"all\")>-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}this._userHandlers.channel[type]||(this._userHandlers.channel[type]=[]),channel.forEach(function(ch){that._userHandlers.channel[type][ch]||(that._userHandlers.channel[type][ch]=[]),that._userHandlers.channel[type][ch].push(listener)})}return this},Input.prototype.on=Input.prototype.addListener,Input.prototype.hasListener=function(type,channel,listener){var that=this;if(\"function\"!=typeof listener)throw new TypeError(\"The 'listener' parameter must be a function.\");if(void 0===channel&&(channel=\"all\"),channel.constructor!==Array&&(channel=[channel]),void 0!==wm.MIDI_SYSTEM_MESSAGES[type]){for(var o=0;o<this._userHandlers.system[type].length;o++)if(this._userHandlers.system[type][o]===listener)return!0}else if(void 0!==wm.MIDI_CHANNEL_MESSAGES[type]){if(channel.indexOf(\"all\")>-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}return this._userHandlers.channel[type]?channel.every(function(chNum){var listeners=that._userHandlers.channel[type][chNum];return listeners&&listeners.indexOf(listener)>-1}):!1}return!1},Input.prototype.removeListener=function(type,channel,listener){var that=this;if(void 0!==listener&&\"function\"!=typeof listener)throw new TypeError(\"The 'listener' parameter must be a function.\");if(void 0===channel&&(channel=\"all\"),channel.constructor!==Array&&(channel=[channel]),void 0!==wm.MIDI_SYSTEM_MESSAGES[type])if(void 0===listener)this._userHandlers.system[type]=[];else for(var o=0;o<this._userHandlers.system[type].length;o++)this._userHandlers.system[type][o]===listener&&this._userHandlers.system[type].splice(o,1);else if(void 0!==wm.MIDI_CHANNEL_MESSAGES[type]){if(channel.indexOf(\"all\")>-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}if(!this._userHandlers.channel[type])return this;channel.forEach(function(chNum){var listeners=that._userHandlers.channel[type][chNum];if(listeners)if(void 0===listener)that._userHandlers.channel[type][chNum]=[];else for(var l=0;l<listeners.length;l++)listeners[l]===listener&&listeners.splice(l,1)})}else{if(void 0!==type)throw new TypeError(\"The specified event type is not supported.\");this._initializeUserHandlers()}return this},Input.prototype._initializeUserHandlers=function(){for(var prop1 in wm.MIDI_CHANNEL_MESSAGES)wm.MIDI_CHANNEL_MESSAGES.hasOwnProperty(prop1)&&(this._userHandlers.channel[prop1]={});for(var prop2 in wm.MIDI_SYSTEM_MESSAGES)wm.MIDI_SYSTEM_MESSAGES.hasOwnProperty(prop2)&&(this._userHandlers.system[prop2]=[])},Input.prototype._onMidiMessage=function(e){if(this._userHandlers.system.midimessage.length>0){var event={target:this,data:e.data,timestamp:e.timeStamp,type:\"midimessage\"};this._userHandlers.system.midimessage.forEach(function(callback){callback(event)})}e.data[0]<240?this._parseChannelEvent(e):e.data[0]<=255&&this._parseSystemEvent(e)},Input.prototype._parseChannelEvent=function(e){var data1,data2,command=e.data[0]>>4,channel=(15&e.data[0])+1;e.data.length>1&&(data1=e.data[1],data2=e.data.length>2?e.data[2]:void 0);var event={target:this,data:e.data,timestamp:e.timeStamp,channel:channel};command===wm.MIDI_CHANNEL_MESSAGES.noteoff||command===wm.MIDI_CHANNEL_MESSAGES.noteon&&0===data2?(event.type=\"noteoff\",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.velocity=data2/127,event.rawVelocity=data2):command===wm.MIDI_CHANNEL_MESSAGES.noteon?(event.type=\"noteon\",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.velocity=data2/127,event.rawVelocity=data2):command===wm.MIDI_CHANNEL_MESSAGES.keyaftertouch?(event.type=\"keyaftertouch\",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.value=data2/127):command===wm.MIDI_CHANNEL_MESSAGES.controlchange&&data1>=0&&119>=data1?(event.type=\"controlchange\",event.controller={number:data1,name:this.getCcNameByNumber(data1)},event.value=data2):command===wm.MIDI_CHANNEL_MESSAGES.channelmode&&data1>=120&&127>=data1?(event.type=\"channelmode\",event.controller={number:data1,name:this.getChannelModeByNumber(data1)},event.value=data2):command===wm.MIDI_CHANNEL_MESSAGES.programchange?(event.type=\"programchange\",event.value=data1):command===wm.MIDI_CHANNEL_MESSAGES.channelaftertouch?(event.type=\"channelaftertouch\",event.value=data1/127):command===wm.MIDI_CHANNEL_MESSAGES.pitchbend?(event.type=\"pitchbend\",event.value=((data2<<7)+data1-8192)/8192):event.type=\"unknownchannelmessage\",this._userHandlers.channel[event.type]&&this._userHandlers.channel[event.type][channel]&&this._userHandlers.channel[event.type][channel].forEach(function(callback){callback(event)})},Input.prototype.getCcNameByNumber=function(number){if(number=Math.floor(number),!(number>=0&&119>=number))throw new RangeError(\"The control change number must be between 0 and 119.\");for(var cc in wm.MIDI_CONTROL_CHANGE_MESSAGES)if(wm.MIDI_CONTROL_CHANGE_MESSAGES.hasOwnProperty(cc)&&number===wm.MIDI_CONTROL_CHANGE_MESSAGES[cc])return cc;return void 0},Input.prototype.getChannelModeByNumber=function(number){if(number=Math.floor(number),!(number>=120&&status<=127))throw new RangeError(\"The control change number must be between 120 and 127.\");for(var cm in wm.MIDI_CHANNEL_MODE_MESSAGES)if(wm.MIDI_CHANNEL_MODE_MESSAGES.hasOwnProperty(cm)&&number===wm.MIDI_CHANNEL_MODE_MESSAGES[cm])return cm},Input.prototype._parseSystemEvent=function(e){var command=e.data[0],event={target:this,data:e.data,timestamp:e.timeStamp};command===wm.MIDI_SYSTEM_MESSAGES.sysex?event.type=\"sysex\":command===wm.MIDI_SYSTEM_MESSAGES.timecode?event.type=\"timecode\":command===wm.MIDI_SYSTEM_MESSAGES.songposition?event.type=\"songposition\":command===wm.MIDI_SYSTEM_MESSAGES.songselect?(event.type=\"songselect\",event.song=e.data[1]):command===wm.MIDI_SYSTEM_MESSAGES.tuningrequest?event.type=\"tuningrequest\":command===wm.MIDI_SYSTEM_MESSAGES.clock?event.type=\"clock\":command===wm.MIDI_SYSTEM_MESSAGES.start?event.type=\"start\":command===wm.MIDI_SYSTEM_MESSAGES[\"continue\"]?event.type=\"continue\":command===wm.MIDI_SYSTEM_MESSAGES.stop?event.type=\"stop\":command===wm.MIDI_SYSTEM_MESSAGES.activesensing?event.type=\"activesensing\":command===wm.MIDI_SYSTEM_MESSAGES.reset?event.type=\"reset\":event.type=\"unknownsystemmessage\",this._userHandlers.system[event.type]&&this._userHandlers.system[event.type].forEach(function(callback){callback(event)})},Output.prototype.send=function(status,data,timestamp){if(!(status>=128&&255>=status))throw new RangeError(\"The status byte must be an integer between 128 (0x80) and 255 (0xFF).\");void 0===data&&(data=[]),Array.isArray(data)||(data=[data]);var message=[];return data.forEach(function(item,index){var parsed=Math.floor(item);if(!(parsed>=0&&255>=parsed))throw new RangeError(\"Data bytes must be integers between 0 (0x00) and 255 (0xFF).\");message.push(parsed)}),this._midiOutput.send([status].concat(message),parseFloat(timestamp)||0),this},Output.prototype.sendSysex=function(manufacturer,data,options){if(!wm.sysexEnabled)throw new Error(\"Sysex message support must first be activated.\");return options=options||{},manufacturer=[].concat(manufacturer),data.forEach(function(item){if(0>item||item>127)throw new RangeError(\"The data bytes of a sysex message must be integers between 0 (0x00) and 127 (0x7F).\")}),data=manufacturer.concat(data,wm.MIDI_SYSTEM_MESSAGES.sysexend),this.send(wm.MIDI_SYSTEM_MESSAGES.sysex,data,this._parseTimeParameter(options.time)),this},Output.prototype.sendTimecodeQuarterFrame=function(value,options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.timecode,value,this._parseTimeParameter(options.time)),this},Output.prototype.sendSongPosition=function(value,options){value=Math.floor(value)||0,options=options||{};var msb=value>>7&127,lsb=127&value;return this.send(wm.MIDI_SYSTEM_MESSAGES.songposition,[msb,lsb],this._parseTimeParameter(options.time)),this},Output.prototype.sendSongSelect=function(value,options){if(value=Math.floor(value),options=options||{},!(value>=0&&127>=value))throw new RangeError(\"The song number must be between 0 and 127.\");return this.send(wm.MIDI_SYSTEM_MESSAGES.songselect,[value],this._parseTimeParameter(options.time)),this},Output.prototype.sendTuningRequest=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.tuningrequest,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendClock=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.clock,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendStart=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.start,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendContinue=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES[\"continue\"],void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendStop=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.stop,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendActiveSensing=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.activesensing,[],this._parseTimeParameter(options.time)),this},Output.prototype.sendReset=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.reset,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.stopNote=function(note,channel,options){if(\"all\"===note)return this.sendChannelMode(\"allnotesoff\",0,channel,options);var nVelocity=64;return options=options||{},options.rawVelocity?!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=127&&(nVelocity=options.velocity):!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=1&&(nVelocity=127*options.velocity),this._convertNoteToArray(note).forEach(function(item){wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteoff<<4)+(ch-1),[item,Math.round(nVelocity)],this._parseTimeParameter(options.time))}.bind(this))}.bind(this)),this},Output.prototype.playNote=function(note,channel,options){var nVelocity=64;if(options=options||{},options.rawVelocity?!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=127&&(nVelocity=options.velocity):!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=1&&(nVelocity=127*options.velocity),options.time=this._parseTimeParameter(options.time),this._convertNoteToArray(note).forEach(function(item){wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteon<<4)+(ch-1),[item,Math.round(nVelocity)],options.time)}.bind(this))}.bind(this)),!isNaN(options.duration)){options.duration<=0&&(options.duration=0);var nRelease=64;options.rawVelocity?!isNaN(options.release)&&options.release>=0&&options.release<=127&&(nRelease=options.release):!isNaN(options.release)&&options.release>=0&&options.release<=1&&(nRelease=127*options.release),this._convertNoteToArray(note).forEach(function(item){wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteoff<<4)+(ch-1),[item,Math.round(nRelease)],(options.time||wm.time)+options.duration)}.bind(this))}.bind(this))}return this},Output.prototype.sendKeyAftertouch=function(note,channel,pressure,options){var that=this;if(options=options||{},1>channel||channel>16)throw new RangeError(\"The channel must be between 1 and 16.\");(isNaN(pressure)||0>pressure||pressure>1)&&(pressure=.5);var nPressure=Math.round(127*pressure);return this._convertNoteToArray(note).forEach(function(item){wm.toMIDIChannels(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.keyaftertouch<<4)+(ch-1),[item,nPressure],that._parseTimeParameter(options.time))})}),this},Output.prototype.sendControlChange=function(controller,value,channel,options){if(options=options||{},\"string\"==typeof controller){if(controller=wm.MIDI_CONTROL_CHANGE_MESSAGES[controller],!controller)throw new TypeError(\"Invalid controller name.\")}else if(controller=Math.floor(controller),!(controller>=0&&119>=controller))throw new RangeError(\"Controller numbers must be between 0 and 119.\");if(value=Math.floor(value)||0,!(value>=0&&127>=value))throw new RangeError(\"Controller value must be between 0 and 127.\");return wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.controlchange<<4)+(ch-1),[controller,value],this._parseTimeParameter(options.time))}.bind(this)),this},Output.prototype._selectRegisteredParameter=function(parameter,channel,time){var that=this;if(parameter[0]=Math.floor(parameter[0]),!(parameter[0]>=0&¶meter[0]<=127))throw new RangeError(\"The control65 value must be between 0 and 127\");if(parameter[1]=Math.floor(parameter[1]),!(parameter[1]>=0&¶meter[1]<=127))throw new RangeError(\"The control64 value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(101,parameter[0],channel,{time:time}),that.sendControlChange(100,parameter[1],channel,{time:time})}),this},Output.prototype._selectNonRegisteredParameter=function(parameter,channel,time){var that=this;if(parameter[0]=Math.floor(parameter[0]),!(parameter[0]>=0&¶meter[0]<=127))throw new RangeError(\"The control63 value must be between 0 and 127\");if(parameter[1]=Math.floor(parameter[1]),!(parameter[1]>=0&¶meter[1]<=127))throw new RangeError(\"The control62 value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(99,parameter[0],channel,{time:time}),that.sendControlChange(98,parameter[1],channel,{time:time})}),this},Output.prototype._setCurrentRegisteredParameter=function(data,channel,time){var that=this;if(data=[].concat(data),data[0]=Math.floor(data[0]),!(data[0]>=0&&data[0]<=127))throw new RangeError(\"The msb value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(6,data[0],channel,{time:time})}),data[1]=Math.floor(data[1]),data[1]>=0&&data[1]<=127&&wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(38,data[1],channel,{time:time})}),this},Output.prototype._deselectRegisteredParameter=function(channel,time){var that=this;return wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(101,127,channel,{time:time}),that.sendControlChange(100,127,channel,{time:time})}),this},Output.prototype.setRegisteredParameter=function(parameter,data,channel,options){var that=this;if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new Error(\"The specified parameter is not available.\");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return wm.toMIDIChannels(channel).forEach(function(ch){that._selectRegisteredParameter(parameter,channel,options.time),that._setCurrentRegisteredParameter(data,channel,options.time),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.setNonRegisteredParameter=function(parameter,data,channel,options){var that=this;if(options=options||{},!(parameter[0]>=0&¶meter[0]<=127&¶meter[1]>=0&¶meter[1]<=127))throw new Error(\"Position 0 and 1 of the 2-position parameter array must both be between 0 and 127.\");return data=[].concat(data),wm.toMIDIChannels(channel).forEach(function(ch){that._selectNonRegisteredParameter(parameter,channel,options.time),that._setCurrentRegisteredParameter(data,channel,options.time),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.incrementRegisteredParameter=function(parameter,channel,options){var that=this;if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new Error(\"The specified parameter is not available.\");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return wm.toMIDIChannels(channel).forEach(function(ch){that._selectRegisteredParameter(parameter,channel,options.time),that.sendControlChange(96,0,channel,{time:options.time}),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.decrementRegisteredParameter=function(parameter,channel,options){if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new TypeError(\"The specified parameter is not available.\");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return wm.toMIDIChannels(channel).forEach(function(ch){this._selectRegisteredParameter(parameter,channel,options.time),this.sendControlChange(97,0,channel,{time:options.time}),this._deselectRegisteredParameter(channel,options.time)}.bind(this)),this},Output.prototype.setPitchBendRange=function(semitones,cents,channel,options){var that=this;if(options=options||{},semitones=Math.floor(semitones)||0,!(semitones>=0&&127>=semitones))throw new RangeError(\"The semitones value must be between 0 and 127\");if(cents=Math.floor(cents)||0,!(cents>=0&&127>=cents))throw new RangeError(\"The cents value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter(\"pitchbendrange\",[semitones,cents],channel,{time:options.time})}),this},Output.prototype.setModulationRange=function(semitones,cents,channel,options){var that=this;if(options=options||{},semitones=Math.floor(semitones)||0,!(semitones>=0&&127>=semitones))throw new RangeError(\"The semitones value must be between 0 and 127\");if(cents=Math.floor(cents)||0,!(cents>=0&&127>=cents))throw new RangeError(\"The cents value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter(\"modulationrange\",[semitones,cents],channel,{time:options.time})}),this},Output.prototype.setMasterTuning=function(value,channel,options){var that=this;if(options=options||{},value=parseFloat(value)||0,-65>=value||value>=64)throw new RangeError(\"The value must be a decimal number larger than -65 and smaller than 64.\");var coarse=Math.floor(value)+64,fine=value-Math.floor(value);fine=Math.round((fine+1)/2*16383);var msb=fine>>7&127,lsb=127&fine;return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter(\"channelcoarsetuning\",coarse,channel,{time:options.time}),that.setRegisteredParameter(\"channelfinetuning\",[msb,lsb],channel,{time:options.time})}),this},Output.prototype.setTuningProgram=function(value,channel,options){var that=this;if(options=options||{},value=Math.floor(value),!(value>=0&&127>=value))throw new RangeError(\"The program value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter(\"tuningprogram\",value,channel,{time:options.time})}),this},Output.prototype.setTuningBank=function(value,channel,options){var that=this;if(options=options||{},value=Math.floor(value)||0,!(value>=0&&127>=value))throw new RangeError(\"The bank value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter(\"tuningbank\",value,channel,{time:options.time})}),this},Output.prototype.sendChannelMode=function(command,value,channel,options){if(options=options||{},\"string\"==typeof command){if(command=wm.MIDI_CHANNEL_MODE_MESSAGES[command],!command)throw new TypeError(\"Invalid channel mode message name.\")}else if(command=Math.floor(command),!(command>=120&&127>=command))throw new RangeError(\"Channel mode numerical identifiers must be between 120 and 127.\");if(value=Math.floor(value)||0,0>value||value>127)throw new RangeError(\"Value must be an integer between 0 and 127.\");return wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.channelmode<<4)+(ch-1),[command,value],this._parseTimeParameter(options.time))}.bind(this)),this},Output.prototype.sendProgramChange=function(program,channel,options){\nvar that=this;if(options=options||{},program=Math.floor(program),isNaN(program)||0>program||program>127)throw new RangeError(\"Program numbers must be between 0 and 127.\");return wm.toMIDIChannels(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.programchange<<4)+(ch-1),[program],that._parseTimeParameter(options.time))}),this},Output.prototype.sendChannelAftertouch=function(pressure,channel,options){var that=this;options=options||{},pressure=parseFloat(pressure),(isNaN(pressure)||0>pressure||pressure>1)&&(pressure=.5);var nPressure=Math.round(127*pressure);return wm.toMIDIChannels(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.channelaftertouch<<4)+(ch-1),[nPressure],that._parseTimeParameter(options.time))}),this},Output.prototype.sendPitchBend=function(bend,channel,options){var that=this;if(options=options||{},isNaN(bend)||-1>bend||bend>1)throw new RangeError(\"Pitch bend value must be between -1 and 1.\");var nLevel=Math.round((bend+1)/2*16383),msb=nLevel>>7&127,lsb=127&nLevel;return wm.toMIDIChannels(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.pitchbend<<4)+(ch-1),[lsb,msb],that._parseTimeParameter(options.time))}),this},Output.prototype._parseTimeParameter=function(time){var parsed,value;return\"string\"==typeof time&&\"+\"===time.substring(0,1)?(parsed=parseFloat(time),parsed&&parsed>0&&(value=wm.time+parsed)):(parsed=parseFloat(time),parsed>wm.time&&(value=parsed)),value},Output.prototype._convertNoteToArray=function(note){var notes=[];return Array.isArray(note)||(note=[note]),note.forEach(function(item){notes.push(wm.guessNoteNumber(item))}),notes},\"function\"==typeof define&&\"object\"==typeof define.amd?define([],function(){return wm}):\"undefined\"!=typeof module&&module.exports?module.exports=wm:scope.WebMidi||(scope.WebMidi=wm)}(this);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/webmidi/webmidi.min.js\n// module id = 150\n// module chunks = 0","module.exports = function() {\r\n\tthrow new Error(\"define cannot be used indirect\");\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/webpack/buildin/amd-define.js\n// module id = 151\n// module chunks = 0","/* globals __webpack_amd_options__ */\r\nmodule.exports = __webpack_amd_options__;\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/webpack/buildin/amd-options.js\n// module id = 152\n// module chunks = 0","\"use strict\";\n\nexports.__esModule = true;\n\nvar _from = require(\"../core-js/array/from\");\n\nvar _from2 = _interopRequireDefault(_from);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nexports.default = function (arr) {\n return Array.isArray(arr) ? arr : (0, _from2.default)(arr);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/babel-runtime/helpers/toArray.js\n// module id = 154\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/array/from\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/babel-runtime/core-js/array/from.js\n// module id = 155\n// module chunks = 0","require('../../modules/es6.string.iterator');\nrequire('../../modules/es6.array.from');\nmodule.exports = require('../../modules/_core').Array.from;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/fn/array/from.js\n// module id = 156\n// module chunks = 0","'use strict';\nvar $defineProperty = require('./_object-dp')\n , createDesc = require('./_property-desc');\n\nmodule.exports = function(object, index, value){\n if(index in object)$defineProperty.f(object, index, createDesc(0, value));\n else object[index] = value;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/_create-property.js\n// module id = 157\n// module chunks = 0","'use strict';\nvar ctx = require('./_ctx')\n , $export = require('./_export')\n , toObject = require('./_to-object')\n , call = require('./_iter-call')\n , isArrayIter = require('./_is-array-iter')\n , toLength = require('./_to-length')\n , createProperty = require('./_create-property')\n , getIterFn = require('./core.get-iterator-method');\n\n$export($export.S + $export.F * !require('./_iter-detect')(function(iter){ Array.from(iter); }), 'Array', {\n // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)\n from: function from(arrayLike/*, mapfn = undefined, thisArg = undefined*/){\n var O = toObject(arrayLike)\n , C = typeof this == 'function' ? this : Array\n , aLen = arguments.length\n , mapfn = aLen > 1 ? arguments[1] : undefined\n , mapping = mapfn !== undefined\n , index = 0\n , iterFn = getIterFn(O)\n , length, result, step, iterator;\n if(mapping)mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);\n // if object isn't iterable or it's array with default iterator - use simple case\n if(iterFn != undefined && !(C == Array && isArrayIter(iterFn))){\n for(iterator = iterFn.call(O), result = new C; !(step = iterator.next()).done; index++){\n createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value);\n }\n } else {\n length = toLength(O.length);\n for(result = new C(length); length > index; index++){\n createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);\n }\n }\n result.length = index;\n return result;\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../inequality/~/core-js/library/modules/es6.array.from.js\n// module id = 158\n// module chunks = 0"],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;A;;;;AChEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACVA;AACA;;;;;;ACDA;AACA;AACA;AACA;;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AC5vDA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;;;;;;ACHA;AACA;AACA;AACA;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACnLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC1EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACtBA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;;;;;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC7zvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACnBA;;;;;;ACAA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;AACA;AACA;AACA;AACA;;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACtLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AC3GA;AACA;AACA;AACA;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACtBA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;AACA;AACA;AACA;;;;;;ACHA;;;;;;ACAA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;;;;;;ACLA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACRA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC7SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AC5NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC/hBA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC9HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACpEA;;;;;;ACAA;;;;;;ACAA;AACA;AACA;;;;;;ACFA;AACA;AACA;AACA;AACA;;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AChBA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC1EA;AACA;AACA;AACA;AACA;AACA;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;;;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACt6BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACrLA;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACrNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;;;;;;;AC3LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACh5SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACpVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACzKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACzLA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACjHA;AACA;AACA;;;;;;ACFA;AACA;AACA;;;;;;ACFA;AACA;;;;;;ACDA;AACA;;;;;;ACDA;AACA;;;;;;ACDA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;;;;;;ACFA;;;;;;ACAA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACPA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACpBA;AACA;AACA;;;;;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACnEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACPA;AACA;AACA;AACA;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC1SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC1OA;;;;;;ACAA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACxtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACnFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;ACtgCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AChMA;;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC/DA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACzLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AC9HA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACzkBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC/BA;AACA;AACA;;;;;;;ACFA;AACA;;;;;;;;;;;;;;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACZA;;;;;;ACAA;AACA;AACA;;;;;;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;A","sourceRoot":""}
\ No newline at end of file +{"version":3,"file":"./bundle.js","sources":["webpack:///webpack/bootstrap a43288a3f23ecd0a891e","webpack:///./~/core-js/library/modules/_core.js","webpack:///./~/core-js/library/modules/_wks.js","webpack:///./~/core-js/library/modules/_global.js","webpack:///./~/buffer/index.js","webpack:///./~/core-js/library/modules/_an-object.js","webpack:///./~/core-js/library/modules/_object-dp.js","webpack:///./~/core-js/library/modules/_descriptors.js","webpack:///./~/core-js/library/modules/_export.js","webpack:///./~/core-js/library/modules/_has.js","webpack:///./~/core-js/library/modules/_hide.js","webpack:///./~/core-js/library/modules/_to-iobject.js","webpack:///./~/process/browser.js","webpack:///./~/readable-stream/lib/_stream_duplex.js","webpack:///./~/core-js/library/modules/_fails.js","webpack:///./~/core-js/library/modules/_iterators.js","webpack:///./~/core-js/library/modules/_object-keys.js","webpack:///./~/inherits/inherits_browser.js","webpack:///./~/core-js/library/modules/_cof.js","webpack:///./~/core-js/library/modules/_ctx.js","webpack:///./~/core-js/library/modules/_is-object.js","webpack:///./~/core-js/library/modules/_property-desc.js","webpack:///./~/core-js/library/modules/es6.string.iterator.js","webpack:///./~/core-util-is/lib/util.js","webpack:///(webpack)/buildin/global.js","webpack:///./~/tone/build/Tone.js","webpack:///./~/core-js/library/modules/_library.js","webpack:///./~/core-js/library/modules/_object-pie.js","webpack:///./~/core-js/library/modules/_set-to-string-tag.js","webpack:///./~/core-js/library/modules/_to-object.js","webpack:///./~/core-js/library/modules/_uid.js","webpack:///./~/core-js/library/modules/web.dom.iterable.js","webpack:///./client/lib/util.js","webpack:///./~/buffer-shims/index.js","webpack:///./~/core-js/library/modules/_a-function.js","webpack:///./~/core-js/library/modules/_classof.js","webpack:///./~/core-js/library/modules/_defined.js","webpack:///./~/core-js/library/modules/_dom-create.js","webpack:///./~/core-js/library/modules/_enum-bug-keys.js","webpack:///./~/core-js/library/modules/_object-gops.js","webpack:///./~/core-js/library/modules/_shared-key.js","webpack:///./~/core-js/library/modules/_shared.js","webpack:///./~/core-js/library/modules/_to-integer.js","webpack:///./~/core-js/library/modules/_to-length.js","webpack:///./~/core-js/library/modules/_to-primitive.js","webpack:///./~/core-js/library/modules/_wks-define.js","webpack:///./~/core-js/library/modules/_wks-ext.js","webpack:///./~/core-js/library/modules/core.get-iterator-method.js","webpack:///./~/events/events.js","webpack:///./~/node-libs-browser/~/string_decoder/index.js","webpack:///./~/process-nextick-args/index.js","webpack:///./~/readable-stream/lib/_stream_writable.js","webpack:///./~/readable-stream/readable-browser.js","webpack:///./client/lib/kalimba.js","webpack:///./client/lib/scales.js","webpack:///./client/lib/ui.js","webpack:///./~/babel-runtime/helpers/slicedToArray.js","webpack:///./~/nexusui/dist/NexusUI.js","webpack:///./~/babel-runtime/core-js/object/assign.js","webpack:///./~/core-js/library/modules/_html.js","webpack:///./~/core-js/library/modules/_ie8-dom-define.js","webpack:///./~/core-js/library/modules/_iobject.js","webpack:///./~/core-js/library/modules/_is-array-iter.js","webpack:///./~/core-js/library/modules/_iter-call.js","webpack:///./~/core-js/library/modules/_iter-define.js","webpack:///./~/core-js/library/modules/_iter-detect.js","webpack:///./~/core-js/library/modules/_object-create.js","webpack:///./~/core-js/library/modules/_object-gopn.js","webpack:///./~/core-js/library/modules/_object-keys-internal.js","webpack:///./~/core-js/library/modules/_redefine.js","webpack:///./~/core-js/library/modules/_task.js","webpack:///./~/isarray/index.js","webpack:///./~/readable-stream/lib/_stream_readable.js","webpack:///./~/readable-stream/lib/_stream_transform.js","webpack:///./~/readable-stream/lib/internal/streams/stream-browser.js","webpack:///./~/timers-browserify/main.js","webpack:///./client/data.js","webpack:///./client/lib/keys.js","webpack:///./client/lib/midi.js","webpack:///./~/babel-runtime/helpers/toArray.js","webpack:///./client/index.js","webpack:///./client/lib/intonation.js","webpack:///./client/lib/startAudioContext.js","webpack:///./~/babel-runtime/core-js/array/from.js","webpack:///./~/babel-runtime/core-js/get-iterator.js","webpack:///./~/babel-runtime/core-js/is-iterable.js","webpack:///./~/babel-runtime/core-js/math/log2.js","webpack:///./~/babel-runtime/core-js/object/keys.js","webpack:///./~/babel-runtime/core-js/promise.js","webpack:///./~/babel-runtime/core-js/symbol.js","webpack:///./~/babel-runtime/core-js/symbol/iterator.js","webpack:///./~/babel-runtime/helpers/typeof.js","webpack:///./~/base64-js/index.js","webpack:///./~/core-js/library/fn/array/from.js","webpack:///./~/core-js/library/fn/get-iterator.js","webpack:///./~/core-js/library/fn/is-iterable.js","webpack:///./~/core-js/library/fn/math/log2.js","webpack:///./~/core-js/library/fn/object/assign.js","webpack:///./~/core-js/library/fn/object/keys.js","webpack:///./~/core-js/library/fn/promise.js","webpack:///./~/core-js/library/fn/symbol/index.js","webpack:///./~/core-js/library/fn/symbol/iterator.js","webpack:///./~/core-js/library/modules/_add-to-unscopables.js","webpack:///./~/core-js/library/modules/_an-instance.js","webpack:///./~/core-js/library/modules/_array-includes.js","webpack:///./~/core-js/library/modules/_create-property.js","webpack:///./~/core-js/library/modules/_enum-keys.js","webpack:///./~/core-js/library/modules/_for-of.js","webpack:///./~/core-js/library/modules/_invoke.js","webpack:///./~/core-js/library/modules/_is-array.js","webpack:///./~/core-js/library/modules/_iter-create.js","webpack:///./~/core-js/library/modules/_iter-step.js","webpack:///./~/core-js/library/modules/_keyof.js","webpack:///./~/core-js/library/modules/_meta.js","webpack:///./~/core-js/library/modules/_microtask.js","webpack:///./~/core-js/library/modules/_object-assign.js","webpack:///./~/core-js/library/modules/_object-dps.js","webpack:///./~/core-js/library/modules/_object-gopd.js","webpack:///./~/core-js/library/modules/_object-gopn-ext.js","webpack:///./~/core-js/library/modules/_object-gpo.js","webpack:///./~/core-js/library/modules/_object-sap.js","webpack:///./~/core-js/library/modules/_redefine-all.js","webpack:///./~/core-js/library/modules/_set-species.js","webpack:///./~/core-js/library/modules/_species-constructor.js","webpack:///./~/core-js/library/modules/_string-at.js","webpack:///./~/core-js/library/modules/_to-index.js","webpack:///./~/core-js/library/modules/core.get-iterator.js","webpack:///./~/core-js/library/modules/core.is-iterable.js","webpack:///./~/core-js/library/modules/es6.array.from.js","webpack:///./~/core-js/library/modules/es6.array.iterator.js","webpack:///./~/core-js/library/modules/es6.math.log2.js","webpack:///./~/core-js/library/modules/es6.object.assign.js","webpack:///./~/core-js/library/modules/es6.object.keys.js","webpack:///./~/core-js/library/modules/es6.promise.js","webpack:///./~/core-js/library/modules/es6.symbol.js","webpack:///./~/core-js/library/modules/es7.symbol.async-iterator.js","webpack:///./~/core-js/library/modules/es7.symbol.observable.js","webpack:///./~/csv-parse/lib/index.js","webpack:///./~/file-saver/FileSaver.js","webpack:///./~/ieee754/index.js","webpack:///./~/midi-writer-js/build/index.js","webpack:///./~/note-parser/index.js","webpack:///./~/readable-stream/duplex-browser.js","webpack:///./~/readable-stream/lib/_stream_passthrough.js","webpack:///./~/readable-stream/lib/internal/streams/BufferList.js","webpack:///./~/readable-stream/passthrough.js","webpack:///./~/readable-stream/transform.js","webpack:///./~/readable-stream/writable-browser.js","webpack:///./~/setimmediate/setImmediate.js","webpack:///./~/stream-browserify/index.js","webpack:///./~/tonal-midi/index.js","webpack:///./~/util-deprecate/browser.js","webpack:///./~/util/~/inherits/inherits_browser.js","webpack:///./~/util/support/isBufferBrowser.js","webpack:///./~/util/util.js","webpack:///./~/webmidi/webmidi.min.js","webpack:///(webpack)/buildin/amd-define.js","webpack:///(webpack)/buildin/amd-options.js","webpack:///util (ignored)"],"sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 80);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap a43288a3f23ecd0a891e","var core = module.exports = {version: '2.4.0'};\nif(typeof __e == 'number')__e = core; // eslint-disable-line no-undef\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_core.js\n// module id = 0\n// module chunks = 0","var store = require('./_shared')('wks')\n , uid = require('./_uid')\n , Symbol = require('./_global').Symbol\n , USE_SYMBOL = typeof Symbol == 'function';\n\nvar $exports = module.exports = function(name){\n return store[name] || (store[name] =\n USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n\n$exports.store = store;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_wks.js\n// module id = 1\n// module chunks = 0","// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();\nif(typeof __g == 'number')__g = global; // eslint-disable-line no-undef\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_global.js\n// module id = 2\n// module chunks = 0","/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n * incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n ? global.TYPED_ARRAY_SUPPORT\n : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n try {\n var arr = new Uint8Array(1)\n arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n return arr.foo() === 42 && // typed array instances can be augmented\n typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n } catch (e) {\n return false\n }\n}\n\nfunction kMaxLength () {\n return Buffer.TYPED_ARRAY_SUPPORT\n ? 0x7fffffff\n : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n if (kMaxLength() < length) {\n throw new RangeError('Invalid typed array length')\n }\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = new Uint8Array(length)\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n if (that === null) {\n that = new Buffer(length)\n }\n that.length = length\n }\n\n return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n return new Buffer(arg, encodingOrOffset, length)\n }\n\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new Error(\n 'If encoding is specified then the first argument must be a string'\n )\n }\n return allocUnsafe(this, arg)\n }\n return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n arr.__proto__ = Buffer.prototype\n return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number')\n }\n\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return fromArrayBuffer(that, value, encodingOrOffset, length)\n }\n\n if (typeof value === 'string') {\n return fromString(that, value, encodingOrOffset)\n }\n\n return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n Buffer.prototype.__proto__ = Uint8Array.prototype\n Buffer.__proto__ = Uint8Array\n if (typeof Symbol !== 'undefined' && Symbol.species &&\n Buffer[Symbol.species] === Buffer) {\n // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n Object.defineProperty(Buffer, Symbol.species, {\n value: null,\n configurable: true\n })\n }\n}\n\nfunction assertSize (size) {\n if (typeof size !== 'number') {\n throw new TypeError('\"size\" argument must be a number')\n } else if (size < 0) {\n throw new RangeError('\"size\" argument must not be negative')\n }\n}\n\nfunction alloc (that, size, fill, encoding) {\n assertSize(size)\n if (size <= 0) {\n return createBuffer(that, size)\n }\n if (fill !== undefined) {\n // Only pay attention to encoding if it's a string. This\n // prevents accidentally sending in a number that would\n // be interpretted as a start offset.\n return typeof encoding === 'string'\n ? createBuffer(that, size).fill(fill, encoding)\n : createBuffer(that, size).fill(fill)\n }\n return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n assertSize(size)\n that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) {\n for (var i = 0; i < size; ++i) {\n that[i] = 0\n }\n }\n return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n if (typeof encoding !== 'string' || encoding === '') {\n encoding = 'utf8'\n }\n\n if (!Buffer.isEncoding(encoding)) {\n throw new TypeError('\"encoding\" must be a valid string encoding')\n }\n\n var length = byteLength(string, encoding) | 0\n that = createBuffer(that, length)\n\n var actual = that.write(string, encoding)\n\n if (actual !== length) {\n // Writing a hex string, for example, that contains invalid characters will\n // cause everything after the first invalid character to be ignored. (e.g.\n // 'abxxcd' will be treated as 'ab')\n that = that.slice(0, actual)\n }\n\n return that\n}\n\nfunction fromArrayLike (that, array) {\n var length = array.length < 0 ? 0 : checked(array.length) | 0\n that = createBuffer(that, length)\n for (var i = 0; i < length; i += 1) {\n that[i] = array[i] & 255\n }\n return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n if (byteOffset < 0 || array.byteLength < byteOffset) {\n throw new RangeError('\\'offset\\' is out of bounds')\n }\n\n if (array.byteLength < byteOffset + (length || 0)) {\n throw new RangeError('\\'length\\' is out of bounds')\n }\n\n if (byteOffset === undefined && length === undefined) {\n array = new Uint8Array(array)\n } else if (length === undefined) {\n array = new Uint8Array(array, byteOffset)\n } else {\n array = new Uint8Array(array, byteOffset, length)\n }\n\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = array\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n that = fromArrayLike(that, array)\n }\n return that\n}\n\nfunction fromObject (that, obj) {\n if (Buffer.isBuffer(obj)) {\n var len = checked(obj.length) | 0\n that = createBuffer(that, len)\n\n if (that.length === 0) {\n return that\n }\n\n obj.copy(that, 0, 0, len)\n return that\n }\n\n if (obj) {\n if ((typeof ArrayBuffer !== 'undefined' &&\n obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n if (typeof obj.length !== 'number' || isnan(obj.length)) {\n return createBuffer(that, 0)\n }\n return fromArrayLike(that, obj)\n }\n\n if (obj.type === 'Buffer' && isArray(obj.data)) {\n return fromArrayLike(that, obj.data)\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n // Note: cannot use `length < kMaxLength()` here because that fails when\n // length is NaN (which is otherwise coerced to zero.)\n if (length >= kMaxLength()) {\n throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n 'size: 0x' + kMaxLength().toString(16) + ' bytes')\n }\n return length | 0\n}\n\nfunction SlowBuffer (length) {\n if (+length != length) { // eslint-disable-line eqeqeq\n length = 0\n }\n return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n throw new TypeError('Arguments must be Buffers')\n }\n\n if (a === b) return 0\n\n var x = a.length\n var y = b.length\n\n for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n if (a[i] !== b[i]) {\n x = a[i]\n y = b[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'latin1':\n case 'binary':\n case 'base64':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.concat = function concat (list, length) {\n if (!isArray(list)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n\n if (list.length === 0) {\n return Buffer.alloc(0)\n }\n\n var i\n if (length === undefined) {\n length = 0\n for (i = 0; i < list.length; ++i) {\n length += list[i].length\n }\n }\n\n var buffer = Buffer.allocUnsafe(length)\n var pos = 0\n for (i = 0; i < list.length; ++i) {\n var buf = list[i]\n if (!Buffer.isBuffer(buf)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n buf.copy(buffer, pos)\n pos += buf.length\n }\n return buffer\n}\n\nfunction byteLength (string, encoding) {\n if (Buffer.isBuffer(string)) {\n return string.length\n }\n if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n return string.byteLength\n }\n if (typeof string !== 'string') {\n string = '' + string\n }\n\n var len = string.length\n if (len === 0) return 0\n\n // Use a for loop to avoid recursion\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return len\n case 'utf8':\n case 'utf-8':\n case undefined:\n return utf8ToBytes(string).length\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return len * 2\n case 'hex':\n return len >>> 1\n case 'base64':\n return base64ToBytes(string).length\n default:\n if (loweredCase) return utf8ToBytes(string).length // assume utf8\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n var loweredCase = false\n\n // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n // property of a typed array.\n\n // This behaves neither like String nor Uint8Array in that we set start/end\n // to their upper/lower bounds if the value passed is out of range.\n // undefined is handled specially as per ECMA-262 6th Edition,\n // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n if (start === undefined || start < 0) {\n start = 0\n }\n // Return early if start > this.length. Done here to prevent potential uint32\n // coercion fail below.\n if (start > this.length) {\n return ''\n }\n\n if (end === undefined || end > this.length) {\n end = this.length\n }\n\n if (end <= 0) {\n return ''\n }\n\n // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n end >>>= 0\n start >>>= 0\n\n if (end <= start) {\n return ''\n }\n\n if (!encoding) encoding = 'utf8'\n\n while (true) {\n switch (encoding) {\n case 'hex':\n return hexSlice(this, start, end)\n\n case 'utf8':\n case 'utf-8':\n return utf8Slice(this, start, end)\n\n case 'ascii':\n return asciiSlice(this, start, end)\n\n case 'latin1':\n case 'binary':\n return latin1Slice(this, start, end)\n\n case 'base64':\n return base64Slice(this, start, end)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return utf16leSlice(this, start, end)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = (encoding + '').toLowerCase()\n loweredCase = true\n }\n }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n var i = b[n]\n b[n] = b[m]\n b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n var len = this.length\n if (len % 2 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 16-bits')\n }\n for (var i = 0; i < len; i += 2) {\n swap(this, i, i + 1)\n }\n return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n var len = this.length\n if (len % 4 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 32-bits')\n }\n for (var i = 0; i < len; i += 4) {\n swap(this, i, i + 3)\n swap(this, i + 1, i + 2)\n }\n return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n var len = this.length\n if (len % 8 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 64-bits')\n }\n for (var i = 0; i < len; i += 8) {\n swap(this, i, i + 7)\n swap(this, i + 1, i + 6)\n swap(this, i + 2, i + 5)\n swap(this, i + 3, i + 4)\n }\n return this\n}\n\nBuffer.prototype.toString = function toString () {\n var length = this.length | 0\n if (length === 0) return ''\n if (arguments.length === 0) return utf8Slice(this, 0, length)\n return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n if (this === b) return true\n return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n var str = ''\n var max = exports.INSPECT_MAX_BYTES\n if (this.length > 0) {\n str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n if (this.length > max) str += ' ... '\n }\n return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n if (!Buffer.isBuffer(target)) {\n throw new TypeError('Argument must be a Buffer')\n }\n\n if (start === undefined) {\n start = 0\n }\n if (end === undefined) {\n end = target ? target.length : 0\n }\n if (thisStart === undefined) {\n thisStart = 0\n }\n if (thisEnd === undefined) {\n thisEnd = this.length\n }\n\n if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n throw new RangeError('out of range index')\n }\n\n if (thisStart >= thisEnd && start >= end) {\n return 0\n }\n if (thisStart >= thisEnd) {\n return -1\n }\n if (start >= end) {\n return 1\n }\n\n start >>>= 0\n end >>>= 0\n thisStart >>>= 0\n thisEnd >>>= 0\n\n if (this === target) return 0\n\n var x = thisEnd - thisStart\n var y = end - start\n var len = Math.min(x, y)\n\n var thisCopy = this.slice(thisStart, thisEnd)\n var targetCopy = target.slice(start, end)\n\n for (var i = 0; i < len; ++i) {\n if (thisCopy[i] !== targetCopy[i]) {\n x = thisCopy[i]\n y = targetCopy[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n // Empty buffer means no match\n if (buffer.length === 0) return -1\n\n // Normalize byteOffset\n if (typeof byteOffset === 'string') {\n encoding = byteOffset\n byteOffset = 0\n } else if (byteOffset > 0x7fffffff) {\n byteOffset = 0x7fffffff\n } else if (byteOffset < -0x80000000) {\n byteOffset = -0x80000000\n }\n byteOffset = +byteOffset // Coerce to Number.\n if (isNaN(byteOffset)) {\n // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n byteOffset = dir ? 0 : (buffer.length - 1)\n }\n\n // Normalize byteOffset: negative offsets start from the end of the buffer\n if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n if (byteOffset >= buffer.length) {\n if (dir) return -1\n else byteOffset = buffer.length - 1\n } else if (byteOffset < 0) {\n if (dir) byteOffset = 0\n else return -1\n }\n\n // Normalize val\n if (typeof val === 'string') {\n val = Buffer.from(val, encoding)\n }\n\n // Finally, search either indexOf (if dir is true) or lastIndexOf\n if (Buffer.isBuffer(val)) {\n // Special case: looking for empty string/buffer always fails\n if (val.length === 0) {\n return -1\n }\n return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n } else if (typeof val === 'number') {\n val = val & 0xFF // Search for a byte value [0-255]\n if (Buffer.TYPED_ARRAY_SUPPORT &&\n typeof Uint8Array.prototype.indexOf === 'function') {\n if (dir) {\n return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n } else {\n return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n }\n }\n return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n }\n\n throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n var indexSize = 1\n var arrLength = arr.length\n var valLength = val.length\n\n if (encoding !== undefined) {\n encoding = String(encoding).toLowerCase()\n if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n encoding === 'utf16le' || encoding === 'utf-16le') {\n if (arr.length < 2 || val.length < 2) {\n return -1\n }\n indexSize = 2\n arrLength /= 2\n valLength /= 2\n byteOffset /= 2\n }\n }\n\n function read (buf, i) {\n if (indexSize === 1) {\n return buf[i]\n } else {\n return buf.readUInt16BE(i * indexSize)\n }\n }\n\n var i\n if (dir) {\n var foundIndex = -1\n for (i = byteOffset; i < arrLength; i++) {\n if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n if (foundIndex === -1) foundIndex = i\n if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n } else {\n if (foundIndex !== -1) i -= i - foundIndex\n foundIndex = -1\n }\n }\n } else {\n if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n for (i = byteOffset; i >= 0; i--) {\n var found = true\n for (var j = 0; j < valLength; j++) {\n if (read(arr, i + j) !== read(val, j)) {\n found = false\n break\n }\n }\n if (found) return i\n }\n }\n\n return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n // must be an even number of digits\n var strLen = string.length\n if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; ++i) {\n var parsed = parseInt(string.substr(i * 2, 2), 16)\n if (isNaN(parsed)) return i\n buf[offset + i] = parsed\n }\n return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n // Buffer#write(string)\n if (offset === undefined) {\n encoding = 'utf8'\n length = this.length\n offset = 0\n // Buffer#write(string, encoding)\n } else if (length === undefined && typeof offset === 'string') {\n encoding = offset\n length = this.length\n offset = 0\n // Buffer#write(string, offset[, length][, encoding])\n } else if (isFinite(offset)) {\n offset = offset | 0\n if (isFinite(length)) {\n length = length | 0\n if (encoding === undefined) encoding = 'utf8'\n } else {\n encoding = length\n length = undefined\n }\n // legacy write(string, encoding, offset, length) - remove in v0.13\n } else {\n throw new Error(\n 'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n )\n }\n\n var remaining = this.length - offset\n if (length === undefined || length > remaining) length = remaining\n\n if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n throw new RangeError('Attempt to write outside buffer bounds')\n }\n\n if (!encoding) encoding = 'utf8'\n\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'hex':\n return hexWrite(this, string, offset, length)\n\n case 'utf8':\n case 'utf-8':\n return utf8Write(this, string, offset, length)\n\n case 'ascii':\n return asciiWrite(this, string, offset, length)\n\n case 'latin1':\n case 'binary':\n return latin1Write(this, string, offset, length)\n\n case 'base64':\n // Warning: maxLength not taken into account in base64Write\n return base64Write(this, string, offset, length)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return ucs2Write(this, string, offset, length)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\nfunction base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction utf8Slice (buf, start, end) {\n end = Math.min(buf.length, end)\n var res = []\n\n var i = start\n while (i < end) {\n var firstByte = buf[i]\n var codePoint = null\n var bytesPerSequence = (firstByte > 0xEF) ? 4\n : (firstByte > 0xDF) ? 3\n : (firstByte > 0xBF) ? 2\n : 1\n\n if (i + bytesPerSequence <= end) {\n var secondByte, thirdByte, fourthByte, tempCodePoint\n\n switch (bytesPerSequence) {\n case 1:\n if (firstByte < 0x80) {\n codePoint = firstByte\n }\n break\n case 2:\n secondByte = buf[i + 1]\n if ((secondByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n if (tempCodePoint > 0x7F) {\n codePoint = tempCodePoint\n }\n }\n break\n case 3:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n codePoint = tempCodePoint\n }\n }\n break\n case 4:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n fourthByte = buf[i + 3]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n codePoint = tempCodePoint\n }\n }\n }\n }\n\n if (codePoint === null) {\n // we did not generate a valid codePoint so insert a\n // replacement char (U+FFFD) and advance only 1 byte\n codePoint = 0xFFFD\n bytesPerSequence = 1\n } else if (codePoint > 0xFFFF) {\n // encode to utf16 (surrogate pair dance)\n codePoint -= 0x10000\n res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n codePoint = 0xDC00 | codePoint & 0x3FF\n }\n\n res.push(codePoint)\n i += bytesPerSequence\n }\n\n return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n var len = codePoints.length\n if (len <= MAX_ARGUMENTS_LENGTH) {\n return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n }\n\n // Decode in chunks to avoid \"call stack size exceeded\".\n var res = ''\n var i = 0\n while (i < len) {\n res += String.fromCharCode.apply(\n String,\n codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n )\n }\n return res\n}\n\nfunction asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i] & 0x7F)\n }\n return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i])\n }\n return ret\n}\n\nfunction hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; ++i) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n }\n return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n var len = this.length\n start = ~~start\n end = end === undefined ? len : ~~end\n\n if (start < 0) {\n start += len\n if (start < 0) start = 0\n } else if (start > len) {\n start = len\n }\n\n if (end < 0) {\n end += len\n if (end < 0) end = 0\n } else if (end > len) {\n end = len\n }\n\n if (end < start) end = start\n\n var newBuf\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n newBuf = this.subarray(start, end)\n newBuf.__proto__ = Buffer.prototype\n } else {\n var sliceLen = end - start\n newBuf = new Buffer(sliceLen, undefined)\n for (var i = 0; i < sliceLen; ++i) {\n newBuf[i] = this[i + start]\n }\n }\n\n return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n checkOffset(offset, byteLength, this.length)\n }\n\n var val = this[offset + --byteLength]\n var mul = 1\n while (byteLength > 0 && (mul *= 0x100)) {\n val += this[offset + --byteLength] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return ((this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16)) +\n (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] * 0x1000000) +\n ((this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var i = byteLength\n var mul = 1\n var val = this[offset + --i]\n while (i > 0 && (mul *= 0x100)) {\n val += this[offset + --i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n if (!(this[offset] & 0x80)) return (this[offset])\n return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset] | (this[offset + 1] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset + 1] | (this[offset] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16) |\n (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] << 24) |\n (this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var mul = 1\n var i = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var i = byteLength - 1\n var mul = 1\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n (littleEndian ? i : 1 - i) * 8\n }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffffffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset + 3] = (value >>> 24)\n this[offset + 2] = (value >>> 16)\n this[offset + 1] = (value >>> 8)\n this[offset] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = 0\n var mul = 1\n var sub = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = byteLength - 1\n var mul = 1\n var sub = 0\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n if (value < 0) value = 0xff + value + 1\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n this[offset + 2] = (value >>> 16)\n this[offset + 3] = (value >>> 24)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (value < 0) value = 0xffffffff + value + 1\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (targetStart >= target.length) targetStart = target.length\n if (!targetStart) targetStart = 0\n if (end > 0 && end < start) end = start\n\n // Copy 0 bytes; we're done\n if (end === start) return 0\n if (target.length === 0 || this.length === 0) return 0\n\n // Fatal error conditions\n if (targetStart < 0) {\n throw new RangeError('targetStart out of bounds')\n }\n if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length) end = this.length\n if (target.length - targetStart < end - start) {\n end = target.length - targetStart + start\n }\n\n var len = end - start\n var i\n\n if (this === target && start < targetStart && targetStart < end) {\n // descending copy from end\n for (i = len - 1; i >= 0; --i) {\n target[i + targetStart] = this[i + start]\n }\n } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n // ascending copy from start\n for (i = 0; i < len; ++i) {\n target[i + targetStart] = this[i + start]\n }\n } else {\n Uint8Array.prototype.set.call(\n target,\n this.subarray(start, start + len),\n targetStart\n )\n }\n\n return len\n}\n\n// Usage:\n// buffer.fill(number[, offset[, end]])\n// buffer.fill(buffer[, offset[, end]])\n// buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n // Handle string cases:\n if (typeof val === 'string') {\n if (typeof start === 'string') {\n encoding = start\n start = 0\n end = this.length\n } else if (typeof end === 'string') {\n encoding = end\n end = this.length\n }\n if (val.length === 1) {\n var code = val.charCodeAt(0)\n if (code < 256) {\n val = code\n }\n }\n if (encoding !== undefined && typeof encoding !== 'string') {\n throw new TypeError('encoding must be a string')\n }\n if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n throw new TypeError('Unknown encoding: ' + encoding)\n }\n } else if (typeof val === 'number') {\n val = val & 255\n }\n\n // Invalid ranges are not set to a default, so can range check early.\n if (start < 0 || this.length < start || this.length < end) {\n throw new RangeError('Out of range index')\n }\n\n if (end <= start) {\n return this\n }\n\n start = start >>> 0\n end = end === undefined ? this.length : end >>> 0\n\n if (!val) val = 0\n\n var i\n if (typeof val === 'number') {\n for (i = start; i < end; ++i) {\n this[i] = val\n }\n } else {\n var bytes = Buffer.isBuffer(val)\n ? val\n : utf8ToBytes(new Buffer(val, encoding).toString())\n var len = bytes.length\n for (i = 0; i < end - start; ++i) {\n this[i + start] = bytes[i % len]\n }\n }\n\n return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n // Node converts strings with length < 2 to ''\n if (str.length < 2) return ''\n // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n while (str.length % 4 !== 0) {\n str = str + '='\n }\n return str\n}\n\nfunction stringtrim (str) {\n if (str.trim) return str.trim()\n return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n units = units || Infinity\n var codePoint\n var length = string.length\n var leadSurrogate = null\n var bytes = []\n\n for (var i = 0; i < length; ++i) {\n codePoint = string.charCodeAt(i)\n\n // is surrogate component\n if (codePoint > 0xD7FF && codePoint < 0xE000) {\n // last char was a lead\n if (!leadSurrogate) {\n // no lead yet\n if (codePoint > 0xDBFF) {\n // unexpected trail\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n } else if (i + 1 === length) {\n // unpaired lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n }\n\n // valid lead\n leadSurrogate = codePoint\n\n continue\n }\n\n // 2 leads in a row\n if (codePoint < 0xDC00) {\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n leadSurrogate = codePoint\n continue\n }\n\n // valid surrogate pair\n codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n } else if (leadSurrogate) {\n // valid bmp char, but last char was a lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n }\n\n leadSurrogate = null\n\n // encode utf8\n if (codePoint < 0x80) {\n if ((units -= 1) < 0) break\n bytes.push(codePoint)\n } else if (codePoint < 0x800) {\n if ((units -= 2) < 0) break\n bytes.push(\n codePoint >> 0x6 | 0xC0,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x10000) {\n if ((units -= 3) < 0) break\n bytes.push(\n codePoint >> 0xC | 0xE0,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x110000) {\n if ((units -= 4) < 0) break\n bytes.push(\n codePoint >> 0x12 | 0xF0,\n codePoint >> 0xC & 0x3F | 0x80,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else {\n throw new Error('Invalid code point')\n }\n }\n\n return bytes\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n if ((units -= 2) < 0) break\n\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n for (var i = 0; i < length; ++i) {\n if ((i + offset >= dst.length) || (i >= src.length)) break\n dst[i + offset] = src[i]\n }\n return i\n}\n\nfunction isnan (val) {\n return val !== val // eslint-disable-line no-self-compare\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/buffer/index.js\n// module id = 3\n// module chunks = 0","var isObject = require('./_is-object');\nmodule.exports = function(it){\n if(!isObject(it))throw TypeError(it + ' is not an object!');\n return it;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_an-object.js\n// module id = 4\n// module chunks = 0","var anObject = require('./_an-object')\n , IE8_DOM_DEFINE = require('./_ie8-dom-define')\n , toPrimitive = require('./_to-primitive')\n , dP = Object.defineProperty;\n\nexports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes){\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if(IE8_DOM_DEFINE)try {\n return dP(O, P, Attributes);\n } catch(e){ /* empty */ }\n if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');\n if('value' in Attributes)O[P] = Attributes.value;\n return O;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-dp.js\n// module id = 5\n// module chunks = 0","// Thank's IE8 for his funny defineProperty\nmodule.exports = !require('./_fails')(function(){\n return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_descriptors.js\n// module id = 6\n// module chunks = 0","var global = require('./_global')\n , core = require('./_core')\n , ctx = require('./_ctx')\n , hide = require('./_hide')\n , PROTOTYPE = 'prototype';\n\nvar $export = function(type, name, source){\n var IS_FORCED = type & $export.F\n , IS_GLOBAL = type & $export.G\n , IS_STATIC = type & $export.S\n , IS_PROTO = type & $export.P\n , IS_BIND = type & $export.B\n , IS_WRAP = type & $export.W\n , exports = IS_GLOBAL ? core : core[name] || (core[name] = {})\n , expProto = exports[PROTOTYPE]\n , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]\n , key, own, out;\n if(IS_GLOBAL)source = name;\n for(key in source){\n // contains in native\n own = !IS_FORCED && target && target[key] !== undefined;\n if(own && key in exports)continue;\n // export native or passed\n out = own ? target[key] : source[key];\n // prevent global pollution for namespaces\n exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]\n // bind timers to global for call from export context\n : IS_BIND && own ? ctx(out, global)\n // wrap global constructors for prevent change them in library\n : IS_WRAP && target[key] == out ? (function(C){\n var F = function(a, b, c){\n if(this instanceof C){\n switch(arguments.length){\n case 0: return new C;\n case 1: return new C(a);\n case 2: return new C(a, b);\n } return new C(a, b, c);\n } return C.apply(this, arguments);\n };\n F[PROTOTYPE] = C[PROTOTYPE];\n return F;\n // make static versions for prototype methods\n })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%\n if(IS_PROTO){\n (exports.virtual || (exports.virtual = {}))[key] = out;\n // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%\n if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out);\n }\n }\n};\n// type bitmap\n$export.F = 1; // forced\n$export.G = 2; // global\n$export.S = 4; // static\n$export.P = 8; // proto\n$export.B = 16; // bind\n$export.W = 32; // wrap\n$export.U = 64; // safe\n$export.R = 128; // real proto method for `library` \nmodule.exports = $export;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_export.js\n// module id = 7\n// module chunks = 0","var hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function(it, key){\n return hasOwnProperty.call(it, key);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_has.js\n// module id = 8\n// module chunks = 0","var dP = require('./_object-dp')\n , createDesc = require('./_property-desc');\nmodule.exports = require('./_descriptors') ? function(object, key, value){\n return dP.f(object, key, createDesc(1, value));\n} : function(object, key, value){\n object[key] = value;\n return object;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_hide.js\n// module id = 9\n// module chunks = 0","// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = require('./_iobject')\n , defined = require('./_defined');\nmodule.exports = function(it){\n return IObject(defined(it));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_to-iobject.js\n// module id = 10\n// module chunks = 0","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/process/browser.js\n// module id = 11\n// module chunks = 0","// a duplex stream is just a stream that is both readable and writable.\n// Since JS doesn't have multiple prototypal inheritance, this class\n// prototypally inherits from Readable, and then parasitically from\n// Writable.\n\n'use strict';\n\n/*<replacement>*/\n\nvar objectKeys = Object.keys || function (obj) {\n var keys = [];\n for (var key in obj) {\n keys.push(key);\n }return keys;\n};\n/*</replacement>*/\n\nmodule.exports = Duplex;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Readable = require('./_stream_readable');\nvar Writable = require('./_stream_writable');\n\nutil.inherits(Duplex, Readable);\n\nvar keys = objectKeys(Writable.prototype);\nfor (var v = 0; v < keys.length; v++) {\n var method = keys[v];\n if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];\n}\n\nfunction Duplex(options) {\n if (!(this instanceof Duplex)) return new Duplex(options);\n\n Readable.call(this, options);\n Writable.call(this, options);\n\n if (options && options.readable === false) this.readable = false;\n\n if (options && options.writable === false) this.writable = false;\n\n this.allowHalfOpen = true;\n if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;\n\n this.once('end', onend);\n}\n\n// the no-half-open enforcer\nfunction onend() {\n // if we allow half-open state, or if the writable side ended,\n // then we're ok.\n if (this.allowHalfOpen || this._writableState.ended) return;\n\n // no more data can be written.\n // But allow more writes to happen in this tick.\n processNextTick(onEndNT, this);\n}\n\nfunction onEndNT(self) {\n self.end();\n}\n\nfunction forEach(xs, f) {\n for (var i = 0, l = xs.length; i < l; i++) {\n f(xs[i], i);\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/readable-stream/lib/_stream_duplex.js\n// module id = 12\n// module chunks = 0","module.exports = function(exec){\n try {\n return !!exec();\n } catch(e){\n return true;\n }\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_fails.js\n// module id = 13\n// module chunks = 0","module.exports = {};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_iterators.js\n// module id = 14\n// module chunks = 0","// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = require('./_object-keys-internal')\n , enumBugKeys = require('./_enum-bug-keys');\n\nmodule.exports = Object.keys || function keys(O){\n return $keys(O, enumBugKeys);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-keys.js\n// module id = 15\n// module chunks = 0","if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/inherits/inherits_browser.js\n// module id = 16\n// module chunks = 0","var toString = {}.toString;\n\nmodule.exports = function(it){\n return toString.call(it).slice(8, -1);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_cof.js\n// module id = 17\n// module chunks = 0","// optional / simple context binding\nvar aFunction = require('./_a-function');\nmodule.exports = function(fn, that, length){\n aFunction(fn);\n if(that === undefined)return fn;\n switch(length){\n case 1: return function(a){\n return fn.call(that, a);\n };\n case 2: return function(a, b){\n return fn.call(that, a, b);\n };\n case 3: return function(a, b, c){\n return fn.call(that, a, b, c);\n };\n }\n return function(/* ...args */){\n return fn.apply(that, arguments);\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_ctx.js\n// module id = 18\n// module chunks = 0","module.exports = function(it){\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_is-object.js\n// module id = 19\n// module chunks = 0","module.exports = function(bitmap, value){\n return {\n enumerable : !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable : !(bitmap & 4),\n value : value\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_property-desc.js\n// module id = 20\n// module chunks = 0","'use strict';\nvar $at = require('./_string-at')(true);\n\n// 21.1.3.27 String.prototype[@@iterator]()\nrequire('./_iter-define')(String, 'String', function(iterated){\n this._t = String(iterated); // target\n this._i = 0; // next index\n// 21.1.5.2.1 %StringIteratorPrototype%.next()\n}, function(){\n var O = this._t\n , index = this._i\n , point;\n if(index >= O.length)return {value: undefined, done: true};\n point = $at(O, index);\n this._i += point.length;\n return {value: point, done: false};\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/es6.string.iterator.js\n// module id = 21\n// module chunks = 0","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\n\nfunction isArray(arg) {\n if (Array.isArray) {\n return Array.isArray(arg);\n }\n return objectToString(arg) === '[object Array]';\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n return objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n return objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n return (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n return arg === null ||\n typeof arg === 'boolean' ||\n typeof arg === 'number' ||\n typeof arg === 'string' ||\n typeof arg === 'symbol' || // ES6 symbol\n typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = Buffer.isBuffer;\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-util-is/lib/util.js\n// module id = 22\n// module chunks = 0","var g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/global.js\n// module id = 23\n// module chunks = 0","(function(root, factory){\n\n\t//UMD\n\tif ( typeof define === \"function\" && define.amd ) {\n\t\tdefine(function() {\n\t\t\treturn factory();\n\t\t});\n\t} else if (typeof module === \"object\") {\n\t\tmodule.exports = factory();\n \t} else {\n\t\troot.Tone = factory();\n\t}\n\n}(this, function(){\n\n\t\"use strict\";\n\t\n\tvar Tone;\n\t//constructs the main Tone object\n\tfunction Main(func){\n\t\tTone = func();\n\t}\n\t//invokes each of the modules with the main Tone object as the argument\n\tfunction Module(func){\n\t\tfunc(Tone);\n\t}\t/**\n\t * Tone.js\n\t * @author Yotam Mann\n\t * @license http://opensource.org/licenses/MIT MIT License\n\t * @copyright 2014-2018 Yotam Mann\n\t */\n\tMain(function () {\n\t \n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tTONE\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * @class Tone is the base class of all other classes.\n\t\t * @constructor\n\t\t */\n\t var Tone = function () {\n\t if (!(this instanceof Tone)) {\n\t throw new Error('constructor needs to be called with the \\'new\\' keyword');\n\t }\n\t };\n\t /**\n\t\t * @memberOf Tone#\n\t\t * @returns {String} returns the name of the class as a string\n\t\t */\n\t Tone.prototype.toString = function () {\n\t for (var className in Tone) {\n\t var isLetter = className[0].match(/^[A-Z]$/);\n\t var sameConstructor = Tone[className] === this.constructor;\n\t if (Tone.isFunction(Tone[className]) && isLetter && sameConstructor) {\n\t return className;\n\t }\n\t }\n\t return 'Tone';\n\t };\n\t /**\n\t\t * @memberOf Tone#\n\t\t * disconnect and dispose\n\t\t * @returns {Tone} this\n\t\t */\n\t Tone.prototype.dispose = function () {\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tGET/SET\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Set the parameters at once. Either pass in an\n\t\t * object mapping parameters to values, or to set a\n\t\t * single parameter, by passing in a string and value.\n\t\t * The last argument is an optional ramp time which\n\t\t * will ramp any signal values to their destination value\n\t\t * over the duration of the rampTime.\n\t\t * @param {Object|String} params\n\t\t * @param {Number=} value\n\t\t * @param {Time=} rampTime\n\t\t * @returns {Tone} this\n\t\t * @memberOf Tone#\n\t\t * @example\n\t\t * //set values using an object\n\t\t * filter.set({\n\t\t * \t\"frequency\" : 300,\n\t\t * \t\"type\" : highpass\n\t\t * });\n\t\t * @example\n\t\t * filter.set(\"type\", \"highpass\");\n\t\t * @example\n\t\t * //ramp to the value 220 over 3 seconds.\n\t\t * oscillator.set({\n\t\t * \t\"frequency\" : 220\n\t\t * }, 3);\n\t\t */\n\t Tone.prototype.set = function (params, value, rampTime) {\n\t if (Tone.isObject(params)) {\n\t rampTime = value;\n\t } else if (Tone.isString(params)) {\n\t var tmpObj = {};\n\t tmpObj[params] = value;\n\t params = tmpObj;\n\t }\n\t paramLoop:\n\t for (var attr in params) {\n\t value = params[attr];\n\t var parent = this;\n\t if (attr.indexOf('.') !== -1) {\n\t var attrSplit = attr.split('.');\n\t for (var i = 0; i < attrSplit.length - 1; i++) {\n\t parent = parent[attrSplit[i]];\n\t if (parent instanceof Tone) {\n\t attrSplit.splice(0, i + 1);\n\t var innerParam = attrSplit.join('.');\n\t parent.set(innerParam, value);\n\t continue paramLoop;\n\t }\n\t }\n\t attr = attrSplit[attrSplit.length - 1];\n\t }\n\t var param = parent[attr];\n\t if (Tone.isUndef(param)) {\n\t continue;\n\t }\n\t if (Tone.Signal && param instanceof Tone.Signal || Tone.Param && param instanceof Tone.Param) {\n\t if (param.value !== value) {\n\t if (Tone.isUndef(rampTime)) {\n\t param.value = value;\n\t } else {\n\t param.rampTo(value, rampTime);\n\t }\n\t }\n\t } else if (param instanceof AudioParam) {\n\t if (param.value !== value) {\n\t param.value = value;\n\t }\n\t } else if (Tone.TimeBase && param instanceof Tone.TimeBase) {\n\t parent[attr] = value;\n\t } else if (param instanceof Tone) {\n\t param.set(value);\n\t } else if (param !== value) {\n\t parent[attr] = value;\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Get the object's attributes. Given no arguments get\n\t\t * will return all available object properties and their corresponding\n\t\t * values. Pass in a single attribute to retrieve or an array\n\t\t * of attributes. The attribute strings can also include a \".\"\n\t\t * to access deeper properties.\n\t\t * @memberOf Tone#\n\t\t * @example\n\t\t * osc.get();\n\t\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t\t * @example\n\t\t * osc.get(\"type\");\n\t\t * //returns { \"type\" : \"sine\"}\n\t\t * @example\n\t\t * //use dot notation to access deep properties\n\t\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return\n\t\t * \t\t\t\t\t all available.\n\t\t * @returns {Object}\n\t\t */\n\t Tone.prototype.get = function (params) {\n\t if (Tone.isUndef(params)) {\n\t params = this._collectDefaults(this.constructor);\n\t } else if (Tone.isString(params)) {\n\t params = [params];\n\t }\n\t var ret = {};\n\t for (var i = 0; i < params.length; i++) {\n\t var attr = params[i];\n\t var parent = this;\n\t var subRet = ret;\n\t if (attr.indexOf('.') !== -1) {\n\t var attrSplit = attr.split('.');\n\t for (var j = 0; j < attrSplit.length - 1; j++) {\n\t var subAttr = attrSplit[j];\n\t subRet[subAttr] = subRet[subAttr] || {};\n\t subRet = subRet[subAttr];\n\t parent = parent[subAttr];\n\t }\n\t attr = attrSplit[attrSplit.length - 1];\n\t }\n\t var param = parent[attr];\n\t if (Tone.isObject(params[attr])) {\n\t subRet[attr] = param.get();\n\t } else if (Tone.Signal && param instanceof Tone.Signal) {\n\t subRet[attr] = param.value;\n\t } else if (Tone.Param && param instanceof Tone.Param) {\n\t subRet[attr] = param.value;\n\t } else if (param instanceof AudioParam) {\n\t subRet[attr] = param.value;\n\t } else if (param instanceof Tone) {\n\t subRet[attr] = param.get();\n\t } else if (!Tone.isFunction(param) && Tone.isDefined(param)) {\n\t subRet[attr] = param;\n\t }\n\t }\n\t return ret;\n\t };\n\t /**\n\t\t * collect all of the default attributes in one\n\t\t * @private\n\t\t * @param {Function} constr the constructor to find the defaults from\n\t\t * @return {Array} all of the attributes which belong to the class\n\t\t */\n\t Tone.prototype._collectDefaults = function (constr) {\n\t var ret = [];\n\t if (Tone.isDefined(constr.defaults)) {\n\t ret = Object.keys(constr.defaults);\n\t }\n\t if (Tone.isDefined(constr._super)) {\n\t var superDefs = this._collectDefaults(constr._super);\n\t //filter out repeats\n\t for (var i = 0; i < superDefs.length; i++) {\n\t if (ret.indexOf(superDefs[i]) === -1) {\n\t ret.push(superDefs[i]);\n\t }\n\t }\n\t }\n\t return ret;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tDEFAULTS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * @memberOf Tone\n\t\t * @param {Array} values The arguments array\n\t\t * @param {Array} keys The names of the arguments\n\t\t * @param {Function|Object} constr The class constructor\n\t\t * @return {Object} An object composed of the defaults between the class' defaults\n\t\t * and the passed in arguments.\n\t\t */\n\t Tone.defaults = function (values, keys, constr) {\n\t var options = {};\n\t if (values.length === 1 && Tone.isObject(values[0])) {\n\t options = values[0];\n\t } else {\n\t for (var i = 0; i < keys.length; i++) {\n\t options[keys[i]] = values[i];\n\t }\n\t }\n\t if (Tone.isDefined(constr.defaults)) {\n\t return Tone.defaultArg(options, constr.defaults);\n\t } else if (Tone.isObject(constr)) {\n\t return Tone.defaultArg(options, constr);\n\t } else {\n\t return options;\n\t }\n\t };\n\t /**\n\t\t * If the `given` parameter is undefined, use the `fallback`.\n\t\t * If both `given` and `fallback` are object literals, it will\n\t\t * return a deep copy which includes all of the parameters from both\n\t\t * objects. If a parameter is undefined in given, it will return\n\t\t * the fallback property.\n\t\t * <br><br>\n\t\t * WARNING: if object is self referential, it will go into an an\n\t\t * infinite recursive loop.\n\t\t * @memberOf Tone\n\t\t * @param {*} given\n\t\t * @param {*} fallback\n\t\t * @return {*}\n\t\t */\n\t Tone.defaultArg = function (given, fallback) {\n\t if (Tone.isObject(given) && Tone.isObject(fallback)) {\n\t var ret = {};\n\t //make a deep copy of the given object\n\t for (var givenProp in given) {\n\t ret[givenProp] = Tone.defaultArg(fallback[givenProp], given[givenProp]);\n\t }\n\t for (var fallbackProp in fallback) {\n\t ret[fallbackProp] = Tone.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t }\n\t return ret;\n\t } else {\n\t return Tone.isUndef(given) ? fallback : given;\n\t }\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tCONNECTIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * connect together all of the arguments in series\n\t\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t\t * @returns {Tone}\n\t\t * @memberOf Tone\n\t\t * @static\n\t\t */\n\t Tone.connectSeries = function () {\n\t var currentUnit = arguments[0];\n\t for (var i = 1; i < arguments.length; i++) {\n\t var toUnit = arguments[i];\n\t currentUnit.connect(toUnit);\n\t currentUnit = toUnit;\n\t }\n\t return Tone;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t // TYPE CHECKING\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Test if the arg is undefined\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is undefined\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isUndef = function (val) {\n\t return typeof val === 'undefined';\n\t };\n\t /**\n\t\t * Test if the arg is not undefined\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is undefined\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isDefined = function (val) {\n\t return !Tone.isUndef(val);\n\t };\n\t /**\n\t\t * Test if the arg is a function\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is a function\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isFunction = function (val) {\n\t return typeof val === 'function';\n\t };\n\t /**\n\t\t * Test if the argument is a number.\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is a number\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isNumber = function (arg) {\n\t return typeof arg === 'number';\n\t };\n\t /**\n\t\t * Test if the given argument is an object literal (i.e. `{}`);\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is an object literal.\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isObject = function (arg) {\n\t return Object.prototype.toString.call(arg) === '[object Object]' && arg.constructor === Object;\n\t };\n\t /**\n\t\t * Test if the argument is a boolean.\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is a boolean\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isBoolean = function (arg) {\n\t return typeof arg === 'boolean';\n\t };\n\t /**\n\t\t * Test if the argument is an Array\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is an array\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isArray = function (arg) {\n\t return Array.isArray(arg);\n\t };\n\t /**\n\t\t * Test if the argument is a string.\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is a string\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isString = function (arg) {\n\t return typeof arg === 'string';\n\t };\n\t /**\n\t\t * Test if the argument is in the form of a note in scientific pitch notation.\n\t\t * e.g. \"C4\"\n\t\t * @param {*} arg the argument to test\n\t\t * @returns {Boolean} true if the arg is a string\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.isNote = function (arg) {\n\t return Tone.isString(arg) && /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i.test(arg);\n\t };\n\t /**\n\t\t * An empty function.\n\t\t * @static\n\t\t */\n\t Tone.noOp = function () {\n\t };\n\t /**\n\t\t * Make the property not writable. Internal use only.\n\t\t * @private\n\t\t * @param {String} property the property to make not writable\n\t\t */\n\t Tone.prototype._readOnly = function (property) {\n\t if (Array.isArray(property)) {\n\t for (var i = 0; i < property.length; i++) {\n\t this._readOnly(property[i]);\n\t }\n\t } else {\n\t Object.defineProperty(this, property, {\n\t writable: false,\n\t enumerable: true\n\t });\n\t }\n\t };\n\t /**\n\t\t * Make an attribute writeable. Interal use only.\n\t\t * @private\n\t\t * @param {String} property the property to make writable\n\t\t */\n\t Tone.prototype._writable = function (property) {\n\t if (Array.isArray(property)) {\n\t for (var i = 0; i < property.length; i++) {\n\t this._writable(property[i]);\n\t }\n\t } else {\n\t Object.defineProperty(this, property, { writable: true });\n\t }\n\t };\n\t /**\n\t\t * Possible play states.\n\t\t * @enum {String}\n\t\t */\n\t Tone.State = {\n\t Started: 'started',\n\t Stopped: 'stopped',\n\t Paused: 'paused'\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t // CONVERSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Equal power gain scale. Good for cross-fading.\n\t\t * @param {NormalRange} percent (0-1)\n\t\t * @return {Number} output gain (0-1)\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.equalPowerScale = function (percent) {\n\t var piFactor = 0.5 * Math.PI;\n\t return Math.sin(percent * piFactor);\n\t };\n\t /**\n\t\t * Convert decibels into gain.\n\t\t * @param {Decibels} db\n\t\t * @return {Number}\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.dbToGain = function (db) {\n\t return Math.pow(10, db / 20);\n\t };\n\t /**\n\t\t * Convert gain to decibels.\n\t\t * @param {Number} gain (0-1)\n\t\t * @return {Decibels}\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.gainToDb = function (gain) {\n\t return 20 * (Math.log(gain) / Math.LN10);\n\t };\n\t /**\n\t\t * Convert an interval (in semitones) to a frequency ratio.\n\t\t * @param {Interval} interval the number of semitones above the base note\n\t\t * @return {Number} the frequency ratio\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t * @example\n\t\t * tone.intervalToFrequencyRatio(0); // 1\n\t\t * tone.intervalToFrequencyRatio(12); // 2\n\t\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t\t */\n\t Tone.intervalToFrequencyRatio = function (interval) {\n\t return Math.pow(2, interval / 12);\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tTIMING\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Return the current time of the AudioContext clock.\n\t\t * @return {Number} the currentTime from the AudioContext\n\t\t * @memberOf Tone#\n\t\t */\n\t Tone.prototype.now = function () {\n\t return Tone.context.now();\n\t };\n\t /**\n\t\t * Return the current time of the AudioContext clock.\n\t\t * @return {Number} the currentTime from the AudioContext\n\t\t * @static\n\t\t * @memberOf Tone\n\t\t */\n\t Tone.now = function () {\n\t return Tone.context.now();\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tINHERITANCE\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * have a child inherit all of Tone's (or a parent's) prototype\n\t\t * to inherit the parent's properties, make sure to call\n\t\t * Parent.call(this) in the child's constructor\n\t\t *\n\t\t * based on closure library's inherit function\n\t\t *\n\t\t * @memberOf Tone\n\t\t * @static\n\t\t * @param {Function} \tchild\n\t\t * @param {Function=} parent (optional) parent to inherit from\n\t\t * if no parent is supplied, the child\n\t\t * will inherit from Tone\n\t\t */\n\t Tone.extend = function (child, parent) {\n\t if (Tone.isUndef(parent)) {\n\t parent = Tone;\n\t }\n\t function TempConstructor() {\n\t }\n\t TempConstructor.prototype = parent.prototype;\n\t child.prototype = new TempConstructor();\n\t /** @override */\n\t child.prototype.constructor = child;\n\t child._super = parent;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tCONTEXT\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Private reference to the global AudioContext\n\t\t * @type {AudioContext}\n\t\t * @private\n\t\t */\n\t var audioContext = null;\n\t /**\n\t\t * A static pointer to the audio context accessible as Tone.context.\n\t\t * @type {Tone.Context}\n\t\t * @name context\n\t\t * @memberOf Tone\n\t\t */\n\t Object.defineProperty(Tone, 'context', {\n\t get: function () {\n\t return audioContext;\n\t },\n\t set: function (context) {\n\t if (Tone.Context && context instanceof Tone.Context) {\n\t audioContext = context;\n\t } else {\n\t audioContext = new Tone.Context(context);\n\t }\n\t //initialize the new audio context\n\t Tone.Context.emit('init', audioContext);\n\t }\n\t });\n\t /**\n\t\t * The AudioContext\n\t\t * @type {Tone.Context}\n\t\t * @name context\n\t\t * @memberOf Tone#\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.prototype, 'context', {\n\t get: function () {\n\t return Tone.context;\n\t }\n\t });\n\t /**\n\t\t * Tone automatically creates a context on init, but if you are working\n\t\t * with other libraries which also create an AudioContext, it can be\n\t\t * useful to set your own. If you are going to set your own context,\n\t\t * be sure to do it at the start of your code, before creating any objects.\n\t\t * @static\n\t\t * @param {AudioContext} ctx The new audio context to set\n\t\t */\n\t Tone.setContext = function (ctx) {\n\t Tone.context = ctx;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tATTRIBUTES\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * The number of seconds of 1 processing block (128 samples)\n\t\t * @type {Number}\n\t\t * @name blockTime\n\t\t * @memberOf Tone\n\t\t * @static\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.prototype, 'blockTime', {\n\t get: function () {\n\t return 128 / this.context.sampleRate;\n\t }\n\t });\n\t /**\n\t\t * The duration in seconds of one sample.\n\t\t * @type {Number}\n\t\t * @name sampleTime\n\t\t * @memberOf Tone\n\t\t * @static\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.prototype, 'sampleTime', {\n\t get: function () {\n\t return 1 / this.context.sampleRate;\n\t }\n\t });\n\t /**\n\t\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser.\n\t\t * @type {Boolean}\n\t\t * @name supported\n\t\t * @memberOf Tone\n\t\t * @readOnly\n\t\t * @static\n\t\t */\n\t Object.defineProperty(Tone, 'supported', {\n\t get: function () {\n\t var hasAudioContext = window.hasOwnProperty('AudioContext') || window.hasOwnProperty('webkitAudioContext');\n\t var hasPromises = window.hasOwnProperty('Promise');\n\t var hasWorkers = window.hasOwnProperty('Worker');\n\t return hasAudioContext && hasPromises && hasWorkers;\n\t }\n\t });\n\t /**\n\t\t * Boolean value if the audio context has been initialized.\n\t\t * @type {Boolean}\n\t\t * @memberOf Tone\n\t\t * @static\n\t\t * @name initialized\n\t\t */\n\t Object.defineProperty(Tone, 'initialized', {\n\t get: function () {\n\t return audioContext !== null;\n\t }\n\t });\n\t /**\n\t\t * Get the context when it becomes available\n\t\t * @param {Function} resolve Callback when the context is initialized\n\t\t * @return {Tone}\n\t\t */\n\t Tone.getContext = function (resolve) {\n\t if (Tone.initialized) {\n\t resolve(Tone.context);\n\t } else {\n\t var resCallback = function () {\n\t resolve(Tone.context);\n\t Tone.Context.off('init', resCallback);\n\t };\n\t Tone.Context.on('init', resCallback);\n\t }\n\t return Tone;\n\t };\n\t /**\n\t\t * The version number\n\t\t * @type {String}\n\t\t * @static\n\t\t */\n\t Tone.version = 'r12';\n\t return Tone;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Emitter gives classes which extend it\n\t\t * the ability to listen for and emit events.\n\t\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t\t * MIT (c) 2011 Jerome Etienne.\n\t\t *\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.Emitter = function () {\n\t Tone.call(this);\n\t /**\n\t\t\t * Contains all of the events.\n\t\t\t * @private\n\t\t\t * @type {Object}\n\t\t\t */\n\t this._events = {};\n\t };\n\t Tone.extend(Tone.Emitter);\n\t /**\n\t\t * Bind a callback to a specific event.\n\t\t * @param {String} event The name of the event to listen for.\n\t\t * @param {Function} callback The callback to invoke when the\n\t\t * event is emitted\n\t\t * @return {Tone.Emitter} this\n\t\t */\n\t Tone.Emitter.prototype.on = function (event, callback) {\n\t //split the event\n\t var events = event.split(/\\W+/);\n\t for (var i = 0; i < events.length; i++) {\n\t var eventName = events[i];\n\t if (!this._events.hasOwnProperty(eventName)) {\n\t this._events[eventName] = [];\n\t }\n\t this._events[eventName].push(callback);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Bind a callback which is only invoked once\n\t\t * @param {String} event The name of the event to listen for.\n\t\t * @param {Function} callback The callback to invoke when the\n\t\t * event is emitted\n\t\t * @return {Tone.Emitter} this\n\t\t */\n\t Tone.Emitter.prototype.once = function (event, callback) {\n\t var boundCallback = function () {\n\t //invoke the callback\n\t callback.apply(this, arguments);\n\t this.off(event, boundCallback);\n\t }.bind(this);\n\t this.on(event, boundCallback);\n\t return this;\n\t };\n\t /**\n\t\t * Remove the event listener.\n\t\t * @param {String} event The event to stop listening to.\n\t\t * @param {Function=} callback The callback which was bound to\n\t\t * the event with Tone.Emitter.on.\n\t\t * If no callback is given, all callbacks\n\t\t * events are removed.\n\t\t * @return {Tone.Emitter} this\n\t\t */\n\t Tone.Emitter.prototype.off = function (event, callback) {\n\t var events = event.split(/\\W+/);\n\t for (var ev = 0; ev < events.length; ev++) {\n\t event = events[ev];\n\t if (this._events.hasOwnProperty(event)) {\n\t if (Tone.isUndef(callback)) {\n\t this._events[event] = [];\n\t } else {\n\t var eventList = this._events[event];\n\t for (var i = 0; i < eventList.length; i++) {\n\t if (eventList[i] === callback) {\n\t eventList.splice(i, 1);\n\t }\n\t }\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Invoke all of the callbacks bound to the event\n\t\t * with any arguments passed in.\n\t\t * @param {String} event The name of the event.\n\t\t * @param {*} args... The arguments to pass to the functions listening.\n\t\t * @return {Tone.Emitter} this\n\t\t */\n\t Tone.Emitter.prototype.emit = function (event) {\n\t if (this._events) {\n\t var args = Array.apply(null, arguments).slice(1);\n\t if (this._events.hasOwnProperty(event)) {\n\t var eventList = this._events[event].slice(0);\n\t for (var i = 0, len = eventList.length; i < len; i++) {\n\t eventList[i].apply(this, args);\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Add Emitter functions (on/off/emit) to the object\n\t\t * @param {Object|Function} object The object or class to extend.\n\t\t * @returns {Tone.Emitter}\n\t\t */\n\t Tone.Emitter.mixin = function (object) {\n\t var functions = [\n\t 'on',\n\t 'once',\n\t 'off',\n\t 'emit'\n\t ];\n\t object._events = {};\n\t for (var i = 0; i < functions.length; i++) {\n\t var func = functions[i];\n\t var emitterFunc = Tone.Emitter.prototype[func];\n\t object[func] = emitterFunc;\n\t }\n\t return Tone.Emitter;\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Emitter} this\n\t\t */\n\t Tone.Emitter.prototype.dispose = function () {\n\t Tone.prototype.dispose.call(this);\n\t this._events = null;\n\t return this;\n\t };\n\t return Tone.Emitter;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A Timeline class for scheduling and maintaining state\n\t\t * along a timeline. All events must have a \"time\" property.\n\t\t * Internally, events are stored in time order for fast\n\t\t * retrieval.\n\t\t * @extends {Tone}\n\t\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t\t */\n\t Tone.Timeline = function () {\n\t var options = Tone.defaults(arguments, ['memory'], Tone.Timeline);\n\t Tone.call(this);\n\t /**\n\t\t\t * The array of scheduled timeline events\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._timeline = [];\n\t /**\n\t\t\t * The memory of the timeline, i.e.\n\t\t\t * how many events in the past it will retain\n\t\t\t * @type {Positive}\n\t\t\t */\n\t this.memory = options.memory;\n\t };\n\t Tone.extend(Tone.Timeline);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t * @const\n\t\t */\n\t Tone.Timeline.defaults = { 'memory': Infinity };\n\t /**\n\t\t * The number of items in the timeline.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Timeline#\n\t\t * @name length\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Timeline.prototype, 'length', {\n\t get: function () {\n\t return this._timeline.length;\n\t }\n\t });\n\t /**\n\t\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t\t * @param {Object} event The event object to insert into the\n\t\t * timeline.\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.add = function (event) {\n\t //the event needs to have a time attribute\n\t if (Tone.isUndef(event.time)) {\n\t throw new Error('Tone.Timeline: events must have a time attribute');\n\t }\n\t event.time = event.time.valueOf();\n\t var index = this._search(event.time);\n\t this._timeline.splice(index + 1, 0, event);\n\t //if the length is more than the memory, remove the previous ones\n\t if (this.length > this.memory) {\n\t var diff = this.length - this.memory;\n\t this._timeline.splice(0, diff);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Remove an event from the timeline.\n\t\t * @param {Object} event The event object to remove from the list.\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.remove = function (event) {\n\t var index = this._timeline.indexOf(event);\n\t if (index !== -1) {\n\t this._timeline.splice(index, 1);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Get the nearest event whose time is less than or equal to the given time.\n\t\t * @param {Number} time The time to query.\n\t\t * @param {String} comparator Which value in the object to compare\n\t\t * @returns {Object} The event object set after that time.\n\t\t */\n\t Tone.Timeline.prototype.get = function (time, comparator) {\n\t comparator = Tone.defaultArg(comparator, 'time');\n\t var index = this._search(time, comparator);\n\t if (index !== -1) {\n\t return this._timeline[index];\n\t } else {\n\t return null;\n\t }\n\t };\n\t /**\n\t\t * Return the first event in the timeline without removing it\n\t\t * @returns {Object} The first event object\n\t\t */\n\t Tone.Timeline.prototype.peek = function () {\n\t return this._timeline[0];\n\t };\n\t /**\n\t\t * Return the first event in the timeline and remove it\n\t\t * @returns {Object} The first event object\n\t\t */\n\t Tone.Timeline.prototype.shift = function () {\n\t return this._timeline.shift();\n\t };\n\t /**\n\t\t * Get the event which is scheduled after the given time.\n\t\t * @param {Number} time The time to query.\n\t\t * @param {String} comparator Which value in the object to compare\n\t\t * @returns {Object} The event object after the given time\n\t\t */\n\t Tone.Timeline.prototype.getAfter = function (time, comparator) {\n\t comparator = Tone.defaultArg(comparator, 'time');\n\t var index = this._search(time, comparator);\n\t if (index + 1 < this._timeline.length) {\n\t return this._timeline[index + 1];\n\t } else {\n\t return null;\n\t }\n\t };\n\t /**\n\t\t * Get the event before the event at the given time.\n\t\t * @param {Number} time The time to query.\n\t\t * @param {String} comparator Which value in the object to compare\n\t\t * @returns {Object} The event object before the given time\n\t\t */\n\t Tone.Timeline.prototype.getBefore = function (time, comparator) {\n\t comparator = Tone.defaultArg(comparator, 'time');\n\t var len = this._timeline.length;\n\t //if it's after the last item, return the last item\n\t if (len > 0 && this._timeline[len - 1][comparator] < time) {\n\t return this._timeline[len - 1];\n\t }\n\t var index = this._search(time, comparator);\n\t if (index - 1 >= 0) {\n\t return this._timeline[index - 1];\n\t } else {\n\t return null;\n\t }\n\t };\n\t /**\n\t\t * Cancel events after the given time\n\t\t * @param {Number} time The time to query.\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.cancel = function (after) {\n\t if (this._timeline.length > 1) {\n\t var index = this._search(after);\n\t if (index >= 0) {\n\t if (this._timeline[index].time === after) {\n\t //get the first item with that time\n\t for (var i = index; i >= 0; i--) {\n\t if (this._timeline[i].time === after) {\n\t index = i;\n\t } else {\n\t break;\n\t }\n\t }\n\t this._timeline = this._timeline.slice(0, index);\n\t } else {\n\t this._timeline = this._timeline.slice(0, index + 1);\n\t }\n\t } else {\n\t this._timeline = [];\n\t }\n\t } else if (this._timeline.length === 1) {\n\t //the first item's time\n\t if (this._timeline[0].time >= after) {\n\t this._timeline = [];\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Cancel events before or equal to the given time.\n\t\t * @param {Number} time The time to cancel before.\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.cancelBefore = function (time) {\n\t var index = this._search(time);\n\t if (index >= 0) {\n\t this._timeline = this._timeline.slice(index + 1);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Returns the previous event if there is one. null otherwise\n\t\t * @param {Object} event The event to find the previous one of\n\t\t * @return {Object} The event right before the given event\n\t\t */\n\t Tone.Timeline.prototype.previousEvent = function (event) {\n\t var index = this._timeline.indexOf(event);\n\t if (index > 0) {\n\t return this._timeline[index - 1];\n\t } else {\n\t return null;\n\t }\n\t };\n\t /**\n\t\t * Does a binary search on the timeline array and returns the\n\t\t * nearest event index whose time is after or equal to the given time.\n\t\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t\t * If the time is after the end, the index of the last item is returned.\n\t\t * @param {Number} time\n\t\t * @param {String} comparator Which value in the object to compare\n\t\t * @return {Number} the index in the timeline array\n\t\t * @private\n\t\t */\n\t Tone.Timeline.prototype._search = function (time, comparator) {\n\t if (this._timeline.length === 0) {\n\t return -1;\n\t }\n\t comparator = Tone.defaultArg(comparator, 'time');\n\t var beginning = 0;\n\t var len = this._timeline.length;\n\t var end = len;\n\t if (len > 0 && this._timeline[len - 1][comparator] <= time) {\n\t return len - 1;\n\t }\n\t while (beginning < end) {\n\t // calculate the midpoint for roughly equal partition\n\t var midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t var event = this._timeline[midPoint];\n\t var nextEvent = this._timeline[midPoint + 1];\n\t if (event[comparator] === time) {\n\t //choose the last one that has the same time\n\t for (var i = midPoint; i < this._timeline.length; i++) {\n\t var testEvent = this._timeline[i];\n\t if (testEvent[comparator] === time) {\n\t midPoint = i;\n\t }\n\t }\n\t return midPoint;\n\t } else if (event[comparator] < time && nextEvent[comparator] > time) {\n\t return midPoint;\n\t } else if (event[comparator] > time) {\n\t //search lower\n\t end = midPoint;\n\t } else {\n\t //search upper\n\t beginning = midPoint + 1;\n\t }\n\t }\n\t return -1;\n\t };\n\t /**\n\t\t * Internal iterator. Applies extra safety checks for\n\t\t * removing items from the array.\n\t\t * @param {Function} callback\n\t\t * @param {Number=} lowerBound\n\t\t * @param {Number=} upperBound\n\t\t * @private\n\t\t */\n\t Tone.Timeline.prototype._iterate = function (callback, lowerBound, upperBound) {\n\t lowerBound = Tone.defaultArg(lowerBound, 0);\n\t upperBound = Tone.defaultArg(upperBound, this._timeline.length - 1);\n\t this._timeline.slice(lowerBound, upperBound + 1).forEach(function (event) {\n\t callback.call(this, event);\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Iterate over everything in the array\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.forEach = function (callback) {\n\t this._iterate(callback);\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array at or before the given time.\n\t\t * @param {Number} time The time to check if items are before\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.forEachBefore = function (time, callback) {\n\t //iterate over the items in reverse so that removing an item doesn't break things\n\t var upperBound = this._search(time);\n\t if (upperBound !== -1) {\n\t this._iterate(callback, 0, upperBound);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array after the given time.\n\t\t * @param {Number} time The time to check if items are before\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.forEachAfter = function (time, callback) {\n\t //iterate over the items in reverse so that removing an item doesn't break things\n\t var lowerBound = this._search(time);\n\t this._iterate(callback, lowerBound + 1);\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array between the startTime and endTime. \n\t\t * The timerange is inclusive of the startTime, but exclusive of the endTime. \n\t\t * range = [startTime, endTime). \n\t\t * @param {Number} startTime The time to check if items are before\n\t\t * @param {Number} endTime The end of the test interval. \n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.forEachBetween = function (startTime, endTime, callback) {\n\t var lowerBound = this._search(startTime);\n\t var upperBound = this._search(endTime);\n\t if (lowerBound !== -1 && upperBound !== -1) {\n\t if (this._timeline[lowerBound].time !== startTime) {\n\t lowerBound += 1;\n\t }\n\t //exclusive of the end time\n\t if (this._timeline[upperBound].time === endTime) {\n\t upperBound -= 1;\n\t }\n\t this._iterate(callback, lowerBound, upperBound);\n\t } else if (lowerBound === -1) {\n\t this._iterate(callback, 0, upperBound);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array at or after the given time. Similar to\n\t\t * forEachAfter, but includes the item(s) at the given time.\n\t\t * @param {Number} time The time to check if items are before\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.forEachFrom = function (time, callback) {\n\t //iterate over the items in reverse so that removing an item doesn't break things\n\t var lowerBound = this._search(time);\n\t //work backwards until the event time is less than time\n\t while (lowerBound >= 0 && this._timeline[lowerBound].time >= time) {\n\t lowerBound--;\n\t }\n\t this._iterate(callback, lowerBound + 1);\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array at the given time\n\t\t * @param {Number} time The time to check if items are before\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.forEachAtTime = function (time, callback) {\n\t //iterate over the items in reverse so that removing an item doesn't break things\n\t var upperBound = this._search(time);\n\t if (upperBound !== -1) {\n\t this._iterate(function (event) {\n\t if (event.time === time) {\n\t callback.call(this, event);\n\t }\n\t }, 0, upperBound);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Timeline} this\n\t\t */\n\t Tone.Timeline.prototype.dispose = function () {\n\t Tone.prototype.dispose.call(this);\n\t this._timeline = null;\n\t return this;\n\t };\n\t return Tone.Timeline;\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported) {\n\t if (!window.hasOwnProperty('OfflineAudioContext') && window.hasOwnProperty('webkitOfflineAudioContext')) {\n\t window.OfflineAudioContext = window.webkitOfflineAudioContext;\n\t }\n\t //returns promise?\n\t var context = new OfflineAudioContext(1, 1, 44100);\n\t var ret = context.startRendering();\n\t if (!(ret instanceof Promise)) {\n\t OfflineAudioContext.prototype._native_startRendering = OfflineAudioContext.prototype.startRendering;\n\t OfflineAudioContext.prototype.startRendering = function () {\n\t return new Promise(function (done) {\n\t this.oncomplete = function (e) {\n\t done(e.renderedBuffer);\n\t };\n\t this._native_startRendering();\n\t }.bind(this));\n\t };\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported) {\n\t if (!window.hasOwnProperty('AudioContext') && window.hasOwnProperty('webkitAudioContext')) {\n\t window.AudioContext = window.webkitAudioContext;\n\t }\n\t //not functionally equivalent, but only an API placeholder\n\t if (!AudioContext.prototype.close) {\n\t AudioContext.prototype.close = function () {\n\t if (Tone.isFunction(this.suspend)) {\n\t this.suspend();\n\t }\n\t return Promise.resolve();\n\t };\n\t }\n\t //not functionally equivalent\n\t if (!AudioContext.prototype.resume) {\n\t AudioContext.prototype.resume = function () {\n\t return Promise.resolve();\n\t };\n\t }\n\t //createGain\n\t if (!AudioContext.prototype.createGain && AudioContext.prototype.createGainNode) {\n\t AudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t }\n\t //createDelay\n\t if (!AudioContext.prototype.createDelay && AudioContext.prototype.createDelayNode) {\n\t AudioContext.prototype.createDelay = AudioContext.prototype.createDelayNode;\n\t }\n\t //test decodeAudioData returns a promise\n\t // https://github.com/mohayonao/web-audio-api-shim/blob/master/src/AudioContext.js\n\t // MIT License (c) 2015 @mohayonao\n\t var decodeAudioDataPromise = false;\n\t var offlineContext = new OfflineAudioContext(1, 1, 44100);\n\t var audioData = new Uint32Array([\n\t 1179011410,\n\t 48,\n\t 1163280727,\n\t 544501094,\n\t 16,\n\t 131073,\n\t 44100,\n\t 176400,\n\t 1048580,\n\t 1635017060,\n\t 8,\n\t 0,\n\t 0,\n\t 0,\n\t 0\n\t ]).buffer;\n\t try {\n\t var ret = offlineContext.decodeAudioData(audioData);\n\t if (ret instanceof Promise) {\n\t decodeAudioDataPromise = true;\n\t }\n\t } catch (e) {\n\t decodeAudioDataPromise = false;\n\t }\n\t if (!decodeAudioDataPromise) {\n\t AudioContext.prototype._native_decodeAudioData = AudioContext.prototype.decodeAudioData;\n\t AudioContext.prototype.decodeAudioData = function (audioData) {\n\t return new Promise(function (success, error) {\n\t this._native_decodeAudioData(audioData, success, error);\n\t }.bind(this));\n\t };\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Wrapper around the native AudioContext.\n\t\t * @extends {Tone.Emitter}\n\t\t * @param {AudioContext=} context optionally pass in a context\n\t\t */\n\t Tone.Context = function () {\n\t Tone.Emitter.call(this);\n\t var options = Tone.defaults(arguments, ['context'], Tone.Context);\n\t if (!options.context) {\n\t options.context = new window.AudioContext();\n\t if (!options.context) {\n\t throw new Error('could not create AudioContext. Possibly too many AudioContexts running already.');\n\t }\n\t }\n\t this._context = options.context;\n\t // extend all of the methods\n\t for (var prop in this._context) {\n\t this._defineProperty(this._context, prop);\n\t }\n\t /**\n\t\t\t * The default latency hint\n\t\t\t * @type {String}\n\t\t\t * @private\n\t\t\t */\n\t this._latencyHint = options.latencyHint;\n\t /**\n\t\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t\t * @type {Object}\n\t\t\t * @private\n\t\t\t */\n\t this._constants = {};\n\t ///////////////////////////////////////////////////////////////////////\n\t // WORKER\n\t ///////////////////////////////////////////////////////////////////////\n\t /**\n\t\t\t * The amount of time events are scheduled\n\t\t\t * into the future\n\t\t\t * @type {Number}\n\t\t\t */\n\t this.lookAhead = options.lookAhead;\n\t /**\n\t\t\t * A reference to the actual computed update interval\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._computedUpdateInterval = 0;\n\t /**\n\t\t\t * A reliable callback method\n\t\t\t * @private\n\t\t\t * @type {Ticker}\n\t\t\t */\n\t this._ticker = new Ticker(this.emit.bind(this, 'tick'), options.clockSource, options.updateInterval);\n\t ///////////////////////////////////////////////////////////////////////\n\t // TIMEOUTS\n\t ///////////////////////////////////////////////////////////////////////\n\t /**\n\t\t\t * All of the setTimeout events.\n\t\t\t * @type {Tone.Timeline}\n\t\t\t * @private\n\t\t\t */\n\t this._timeouts = new Tone.Timeline();\n\t /**\n\t\t\t * The timeout id counter\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._timeoutIds = 0;\n\t this.on('tick', this._timeoutLoop.bind(this));\n\t };\n\t Tone.extend(Tone.Context, Tone.Emitter);\n\t Tone.Emitter.mixin(Tone.Context);\n\t /**\n\t\t * defaults\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Context.defaults = {\n\t 'clockSource': 'worker',\n\t 'latencyHint': 'interactive',\n\t 'lookAhead': 0.1,\n\t 'updateInterval': 0.03\n\t };\n\t /**\n\t\t * Define a property on this Tone.Context.\n\t\t * This is used to extend the native AudioContext\n\t\t * @param {AudioContext} context\n\t\t * @param {String} prop\n\t\t * @private\n\t\t */\n\t Tone.Context.prototype._defineProperty = function (context, prop) {\n\t if (Tone.isUndef(this[prop])) {\n\t Object.defineProperty(this, prop, {\n\t get: function () {\n\t if (typeof context[prop] === 'function') {\n\t return context[prop].bind(context);\n\t } else {\n\t return context[prop];\n\t }\n\t },\n\t set: function (val) {\n\t context[prop] = val;\n\t }\n\t });\n\t }\n\t };\n\t /**\n\t\t * The current audio context time\n\t\t * @return {Number}\n\t\t */\n\t Tone.Context.prototype.now = function () {\n\t return this._context.currentTime + this.lookAhead;\n\t };\n\t /**\n\t\t * Promise which is invoked when the context is running.\n\t\t * Tries to resume the context if it's not started.\n\t\t * @return {Promise}\n\t\t */\n\t Tone.Context.prototype.ready = function () {\n\t return new Promise(function (done) {\n\t if (this._context.state === 'running') {\n\t done();\n\t } else {\n\t this._context.resume().then(function () {\n\t done();\n\t });\n\t }\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Promise which is invoked when the context is running.\n\t\t * Tries to resume the context if it's not started.\n\t\t * @return {Promise}\n\t\t */\n\t Tone.Context.prototype.close = function () {\n\t return this._context.close().then(function () {\n\t Tone.Context.emit('close', this);\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Generate a looped buffer at some constant value.\n\t\t * @param {Number} val\n\t\t * @return {BufferSourceNode}\n\t\t */\n\t Tone.Context.prototype.getConstant = function (val) {\n\t if (this._constants[val]) {\n\t return this._constants[val];\n\t } else {\n\t var buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t var arr = buffer.getChannelData(0);\n\t for (var i = 0; i < arr.length; i++) {\n\t arr[i] = val;\n\t }\n\t var constant = this._context.createBufferSource();\n\t constant.channelCount = 1;\n\t constant.channelCountMode = 'explicit';\n\t constant.buffer = buffer;\n\t constant.loop = true;\n\t constant.start(0);\n\t this._constants[val] = constant;\n\t return constant;\n\t }\n\t };\n\t /**\n\t\t * The private loop which keeps track of the context scheduled timeouts\n\t\t * Is invoked from the clock source\n\t\t * @private\n\t\t */\n\t Tone.Context.prototype._timeoutLoop = function () {\n\t var now = this.now();\n\t while (this._timeouts && this._timeouts.length && this._timeouts.peek().time <= now) {\n\t this._timeouts.shift().callback();\n\t }\n\t };\n\t /**\n\t\t * A setTimeout which is gaurenteed by the clock source.\n\t\t * Also runs in the offline context.\n\t\t * @param {Function} fn The callback to invoke\n\t\t * @param {Seconds} timeout The timeout in seconds\n\t\t * @returns {Number} ID to use when invoking Tone.Context.clearTimeout\n\t\t */\n\t Tone.Context.prototype.setTimeout = function (fn, timeout) {\n\t this._timeoutIds++;\n\t var now = this.now();\n\t this._timeouts.add({\n\t callback: fn,\n\t time: now + timeout,\n\t id: this._timeoutIds\n\t });\n\t return this._timeoutIds;\n\t };\n\t /**\n\t\t * Clears a previously scheduled timeout with Tone.context.setTimeout\n\t\t * @param {Number} id The ID returned from setTimeout\n\t\t * @return {Tone.Context} this\n\t\t */\n\t Tone.Context.prototype.clearTimeout = function (id) {\n\t this._timeouts.forEach(function (event) {\n\t if (event.id === id) {\n\t this.remove(event);\n\t }\n\t });\n\t return this;\n\t };\n\t /**\n\t\t * How often the Web Worker callback is invoked.\n\t\t * This number corresponds to how responsive the scheduling\n\t\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t\t * total latency between scheduling an event and hearing it.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Context#\n\t\t * @name updateInterval\n\t\t */\n\t Object.defineProperty(Tone.Context.prototype, 'updateInterval', {\n\t get: function () {\n\t return this._ticker.updateInterval;\n\t },\n\t set: function (interval) {\n\t this._ticker.updateInterval = interval;\n\t }\n\t });\n\t /**\n\t\t * What the source of the clock is, either \"worker\" (Web Worker [default]),\n\t\t * \"timeout\" (setTimeout), or \"offline\" (none).\n\t\t * @type {String}\n\t\t * @memberOf Tone.Context#\n\t\t * @name clockSource\n\t\t */\n\t Object.defineProperty(Tone.Context.prototype, 'clockSource', {\n\t get: function () {\n\t return this._ticker.type;\n\t },\n\t set: function (type) {\n\t this._ticker.type = type;\n\t }\n\t });\n\t /**\n\t\t * The type of playback, which affects tradeoffs between audio\n\t\t * output latency and responsiveness.\n\t\t *\n\t\t * In addition to setting the value in seconds, the latencyHint also\n\t\t * accepts the strings \"interactive\" (prioritizes low latency),\n\t\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often).\n\t\t * @type {String|Seconds}\n\t\t * @memberOf Tone.Context#\n\t\t * @name latencyHint\n\t\t * @example\n\t\t * //set the lookAhead to 0.3 seconds\n\t\t * Tone.context.latencyHint = 0.3;\n\t\t */\n\t Object.defineProperty(Tone.Context.prototype, 'latencyHint', {\n\t get: function () {\n\t return this._latencyHint;\n\t },\n\t set: function (hint) {\n\t var lookAhead = hint;\n\t this._latencyHint = hint;\n\t if (Tone.isString(hint)) {\n\t switch (hint) {\n\t case 'interactive':\n\t lookAhead = 0.1;\n\t this._context.latencyHint = hint;\n\t break;\n\t case 'playback':\n\t lookAhead = 0.8;\n\t this._context.latencyHint = hint;\n\t break;\n\t case 'balanced':\n\t lookAhead = 0.25;\n\t this._context.latencyHint = hint;\n\t break;\n\t case 'fastest':\n\t this._context.latencyHint = 'interactive';\n\t lookAhead = 0.01;\n\t break;\n\t }\n\t }\n\t this.lookAhead = lookAhead;\n\t this.updateInterval = lookAhead / 3;\n\t }\n\t });\n\t /**\n\t\t * Unlike other dispose methods, this returns a Promise\n\t\t * which executes when the context is closed and disposed\n\t\t * @returns {Promise} this\n\t\t */\n\t Tone.Context.prototype.dispose = function () {\n\t return this.close().then(function () {\n\t Tone.Emitter.prototype.dispose.call(this);\n\t this._ticker.dispose();\n\t this._ticker = null;\n\t this._timeouts.dispose();\n\t this._timeouts = null;\n\t for (var con in this._constants) {\n\t this._constants[con].disconnect();\n\t }\n\t this._constants = null;\n\t }.bind(this));\n\t };\n\t /**\n\t\t * @class A class which provides a reliable callback using either\n\t\t * a Web Worker, or if that isn't supported, falls back to setTimeout.\n\t\t * @private\n\t\t */\n\t var Ticker = function (callback, type, updateInterval) {\n\t /**\n\t\t\t * Either \"worker\" or \"timeout\"\n\t\t\t * @type {String}\n\t\t\t * @private\n\t\t\t */\n\t this._type = type;\n\t /**\n\t\t\t * The update interval of the worker\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._updateInterval = updateInterval;\n\t /**\n\t\t\t * The callback to invoke at regular intervals\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._callback = Tone.defaultArg(callback, Tone.noOp);\n\t //create the clock source for the first time\n\t this._createClock();\n\t };\n\t /**\n\t\t * The possible ticker types\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t Ticker.Type = {\n\t Worker: 'worker',\n\t Timeout: 'timeout',\n\t Offline: 'offline'\n\t };\n\t /**\n\t\t * Generate a web worker\n\t\t * @return {WebWorker}\n\t\t * @private\n\t\t */\n\t Ticker.prototype._createWorker = function () {\n\t //URL Shim\n\t window.URL = window.URL || window.webkitURL;\n\t var blob = new Blob([//the initial timeout time\n\t 'var timeoutTime = ' + (this._updateInterval * 1000).toFixed(1) + ';' + //onmessage callback\n\t 'self.onmessage = function(msg){' + '\\ttimeoutTime = parseInt(msg.data);' + '};' + //the tick function which posts a message\n\t //and schedules a new tick\n\t 'function tick(){' + '\\tsetTimeout(tick, timeoutTime);' + '\\tself.postMessage(\\'tick\\');' + '}' + //call tick initially\n\t 'tick();']);\n\t var blobUrl = URL.createObjectURL(blob);\n\t var worker = new Worker(blobUrl);\n\t worker.onmessage = this._callback.bind(this);\n\t this._worker = worker;\n\t };\n\t /**\n\t\t * Create a timeout loop\n\t\t * @private\n\t\t */\n\t Ticker.prototype._createTimeout = function () {\n\t this._timeout = setTimeout(function () {\n\t this._createTimeout();\n\t this._callback();\n\t }.bind(this), this._updateInterval * 1000);\n\t };\n\t /**\n\t\t * Create the clock source.\n\t\t * @private\n\t\t */\n\t Ticker.prototype._createClock = function () {\n\t if (this._type === Ticker.Type.Worker) {\n\t try {\n\t this._createWorker();\n\t } catch (e) {\n\t // workers not supported, fallback to timeout\n\t this._type = Ticker.Type.Timeout;\n\t this._createClock();\n\t }\n\t } else if (this._type === Ticker.Type.Timeout) {\n\t this._createTimeout();\n\t }\n\t };\n\t /**\n\t\t * @memberOf Ticker#\n\t\t * @type {Number}\n\t\t * @name updateInterval\n\t\t * @private\n\t\t */\n\t Object.defineProperty(Ticker.prototype, 'updateInterval', {\n\t get: function () {\n\t return this._updateInterval;\n\t },\n\t set: function (interval) {\n\t this._updateInterval = Math.max(interval, 128 / 44100);\n\t if (this._type === Ticker.Type.Worker) {\n\t this._worker.postMessage(Math.max(interval * 1000, 1));\n\t }\n\t }\n\t });\n\t /**\n\t\t * The type of the ticker, either a worker or a timeout\n\t\t * @memberOf Ticker#\n\t\t * @type {Number}\n\t\t * @name type\n\t\t * @private\n\t\t */\n\t Object.defineProperty(Ticker.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t this._disposeClock();\n\t this._type = type;\n\t this._createClock();\n\t }\n\t });\n\t /**\n\t\t * Clean up the current clock source\n\t\t * @private\n\t\t */\n\t Ticker.prototype._disposeClock = function () {\n\t if (this._timeout) {\n\t clearTimeout(this._timeout);\n\t this._timeout = null;\n\t }\n\t if (this._worker) {\n\t this._worker.terminate();\n\t this._worker.onmessage = null;\n\t this._worker = null;\n\t }\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @private\n\t\t */\n\t Ticker.prototype.dispose = function () {\n\t this._disposeClock();\n\t this._callback = null;\n\t };\n\t /**\n\t\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t\t * some older implementations.\n\t\t * @private\n\t\t */\n\t Tone.getContext(function () {\n\t var nativeConnect = AudioNode.prototype.connect;\n\t var nativeDisconnect = AudioNode.prototype.disconnect;\n\t //replace the old connect method\n\t function toneConnect(B, outNum, inNum) {\n\t if (B.input) {\n\t inNum = Tone.defaultArg(inNum, 0);\n\t if (Tone.isArray(B.input)) {\n\t return this.connect(B.input[inNum]);\n\t } else {\n\t return this.connect(B.input, outNum, inNum);\n\t }\n\t } else {\n\t try {\n\t if (B instanceof AudioNode) {\n\t nativeConnect.call(this, B, outNum, inNum);\n\t return B;\n\t } else {\n\t nativeConnect.call(this, B, outNum);\n\t return B;\n\t }\n\t } catch (e) {\n\t throw new Error('error connecting to node: ' + B + '\\n' + e);\n\t }\n\t }\n\t }\n\t //replace the old disconnect method\n\t function toneDisconnect(B, outNum, inNum) {\n\t if (B && B.input && Tone.isArray(B.input)) {\n\t inNum = Tone.defaultArg(inNum, 0);\n\t this.disconnect(B.input[inNum], outNum, 0);\n\t } else if (B && B.input) {\n\t this.disconnect(B.input, outNum, inNum);\n\t } else {\n\t try {\n\t nativeDisconnect.apply(this, arguments);\n\t } catch (e) {\n\t throw new Error('error disconnecting node: ' + B + '\\n' + e);\n\t }\n\t }\n\t }\n\t if (AudioNode.prototype.connect !== toneConnect) {\n\t AudioNode.prototype.connect = toneConnect;\n\t AudioNode.prototype.disconnect = toneDisconnect;\n\t }\n\t });\n\t // set the audio context initially, and if one is not already created\n\t if (Tone.supported && !Tone.initialized) {\n\t Tone.context = new Tone.Context();\n\t // log on first initialization\n\t // allow optional silencing of this log\n\t if (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t // eslint-disable-next-line no-console\n\t console.log('%c * Tone.js ' + Tone.version + ' * ', 'background: #000; color: #fff');\n\t }\n\t } else if (!Tone.supported) {\n\t // eslint-disable-next-line no-console\n\t console.warn('This browser does not support Tone.js');\n\t }\n\t return Tone.Context;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.AudioNode is the base class for classes which process audio.\n\t\t * AudioNodes have inputs and outputs.\n\t\t * @param\t{AudioContext=} context\tThe audio context to use with the class\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.AudioNode = function () {\n\t Tone.call(this);\n\t //use the default context if one is not passed in\n\t var options = Tone.defaults(arguments, ['context'], { 'context': Tone.context });\n\t /**\n\t\t\t * The AudioContext of this instance\n\t\t\t * @private\n\t\t\t * @type {AudioContext}\n\t\t\t */\n\t this._context = options.context;\n\t };\n\t Tone.extend(Tone.AudioNode);\n\t /**\n\t\t * Get the audio context belonging to this instance.\n\t\t * @type {Tone.Context}\n\t\t * @memberOf Tone.AudioNode#\n\t\t * @name context\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.AudioNode.prototype, 'context', {\n\t get: function () {\n\t return this._context;\n\t }\n\t });\n\t /**\n\t\t * Create input and outputs for this object.\n\t\t * @param {Number} [input=0] The number of inputs\n\t\t * @param {Number} [outputs=0] The number of outputs\n\t\t * @return {Tone.AudioNode} this\n\t\t * @private\n\t\t */\n\t Tone.AudioNode.prototype.createInsOuts = function (inputs, outputs) {\n\t if (inputs === 1) {\n\t this.input = this.context.createGain();\n\t } else if (inputs > 1) {\n\t this.input = new Array(inputs);\n\t }\n\t if (outputs === 1) {\n\t this.output = this.context.createGain();\n\t } else if (outputs > 1) {\n\t this.output = new Array(outputs);\n\t }\n\t };\n\t /**\n\t\t * channelCount is the number of channels used when up-mixing and down-mixing\n\t\t * connections to any inputs to the node. The default value is 2 except for\n\t\t * specific nodes where its value is specially determined.\n\t\t *\n\t\t * @memberof Tone.AudioNode#\n\t\t * @type {Number}\n\t\t * @name channelCount\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.AudioNode.prototype, 'channelCount', {\n\t get: function () {\n\t return this.output.channelCount;\n\t },\n\t set: function (c) {\n\t return this.output.channelCount = c;\n\t }\n\t });\n\t /**\n\t\t * channelCountMode determines how channels will be counted when up-mixing and\n\t\t * down-mixing connections to any inputs to the node.\n\t\t * The default value is \"max\". This attribute has no effect for nodes with no inputs.\n\t\t * @memberof Tone.AudioNode#\n\t\t * @type {String}\n\t\t * @name channelCountMode\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.AudioNode.prototype, 'channelCountMode', {\n\t get: function () {\n\t return this.output.channelCountMode;\n\t },\n\t set: function (m) {\n\t return this.output.channelCountMode = m;\n\t }\n\t });\n\t /**\n\t\t * channelInterpretation determines how individual channels will be treated\n\t\t * when up-mixing and down-mixing connections to any inputs to the node.\n\t\t * The default value is \"speakers\".\n\t\t * @memberof Tone.AudioNode#\n\t\t * @type {String}\n\t\t * @name channelInterpretation\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.AudioNode.prototype, 'channelInterpretation', {\n\t get: function () {\n\t return this.output.channelInterpretation;\n\t },\n\t set: function (i) {\n\t return this.output.channelInterpretation = i;\n\t }\n\t });\n\t /**\n\t\t * The number of inputs feeding into the AudioNode.\n\t\t * For source nodes, this will be 0.\n\t\t * @type {Number}\n\t\t * @name numberOfInputs\n\t\t * @memberof Tone.AudioNode#\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.AudioNode.prototype, 'numberOfInputs', {\n\t get: function () {\n\t if (this.input) {\n\t if (Tone.isArray(this.input)) {\n\t return this.input.length;\n\t } else {\n\t return 1;\n\t }\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The number of outputs coming out of the AudioNode.\n\t\t * @type {Number}\n\t\t * @name numberOfOutputs\n\t\t * @memberof Tone.AudioNode#\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.AudioNode.prototype, 'numberOfOutputs', {\n\t get: function () {\n\t if (this.output) {\n\t if (Tone.isArray(this.output)) {\n\t return this.output.length;\n\t } else {\n\t return 1;\n\t }\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Called when an audio param connects to this node\n\t\t * @private\n\t\t */\n\t Tone.AudioNode.prototype._onConnect = function () {\n\t };\n\t /**\n\t\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t\t * @param {Tone | AudioParam | AudioNode} unit\n\t\t * @param {number} [outputNum=0] optionally which output to connect from\n\t\t * @param {number} [inputNum=0] optionally which input to connect to\n\t\t * @returns {Tone.AudioNode} this\n\t\t */\n\t Tone.AudioNode.prototype.connect = function (unit, outputNum, inputNum) {\n\t if (unit._onConnect) {\n\t unit._onConnect(this);\n\t }\n\t if (Tone.isArray(this.output)) {\n\t outputNum = Tone.defaultArg(outputNum, 0);\n\t this.output[outputNum].connect(unit, 0, inputNum);\n\t } else {\n\t this.output.connect(unit, outputNum, inputNum);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * disconnect the output\n\t\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t\t * if the output is an array, or the\n\t\t * node to disconnect from.\n\t\t * @returns {Tone.AudioNode} this\n\t\t */\n\t Tone.AudioNode.prototype.disconnect = function (destination, outputNum, inputNum) {\n\t if (Tone.isArray(this.output)) {\n\t if (Tone.isNumber(destination)) {\n\t this.output[destination].disconnect();\n\t } else {\n\t outputNum = Tone.defaultArg(outputNum, 0);\n\t this.output[outputNum].disconnect(destination, 0, inputNum);\n\t }\n\t } else {\n\t this.output.disconnect.apply(this.output, arguments);\n\t }\n\t };\n\t /**\n\t\t * Connect the output of this node to the rest of the nodes in series.\n\t\t * @example\n\t\t * //connect a node to an effect, panVol and then to the master output\n\t\t * node.chain(effect, panVol, Tone.Master);\n\t\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t\t * @returns {Tone.AudioNode} this\n\t\t * @private\n\t\t */\n\t Tone.AudioNode.prototype.chain = function () {\n\t var currentUnit = this;\n\t for (var i = 0; i < arguments.length; i++) {\n\t var toUnit = arguments[i];\n\t currentUnit.connect(toUnit);\n\t currentUnit = toUnit;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * connect the output of this node to the rest of the nodes in parallel.\n\t\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t\t * @returns {Tone.AudioNode} this\n\t\t * @private\n\t\t */\n\t Tone.AudioNode.prototype.fan = function () {\n\t for (var i = 0; i < arguments.length; i++) {\n\t this.connect(arguments[i]);\n\t }\n\t return this;\n\t };\n\t if (window.AudioNode) {\n\t //give native nodes chain and fan methods\n\t AudioNode.prototype.chain = Tone.AudioNode.prototype.chain;\n\t AudioNode.prototype.fan = Tone.AudioNode.prototype.fan;\n\t }\n\t /**\n\t\t * Dispose and disconnect\n\t\t * @return {Tone.AudioNode} this\n\t\t */\n\t Tone.AudioNode.prototype.dispose = function () {\n\t if (Tone.isDefined(this.input)) {\n\t if (this.input instanceof AudioNode) {\n\t this.input.disconnect();\n\t }\n\t this.input = null;\n\t }\n\t if (Tone.isDefined(this.output)) {\n\t if (this.output instanceof AudioNode) {\n\t this.output.disconnect();\n\t }\n\t this.output = null;\n\t }\n\t this._context = null;\n\t return this;\n\t };\n\t return Tone.AudioNode;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Base class for all Signals. Used Internally.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.SignalBase = function () {\n\t Tone.AudioNode.call(this);\n\t };\n\t Tone.extend(Tone.SignalBase, Tone.AudioNode);\n\t /**\n\t\t * When signals connect to other signals or AudioParams,\n\t\t * they take over the output value of that signal or AudioParam.\n\t\t * For all other nodes, the behavior is the same as a default <code>connect</code>.\n\t\t *\n\t\t * @override\n\t\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node\n\t\t * @param {number} [outputNumber=0] The output number to connect from.\n\t\t * @param {number} [inputNumber=0] The input number to connect to.\n\t\t * @returns {Tone.SignalBase} this\n\t\t */\n\t Tone.SignalBase.prototype.connect = function (node, outputNumber, inputNumber) {\n\t //zero it out so that the signal can have full control\n\t if (Tone.Signal && Tone.Signal === node.constructor || Tone.Param && Tone.Param === node.constructor) {\n\t //cancel changes\n\t node._param.cancelScheduledValues(0);\n\t //reset the value\n\t node._param.value = 0;\n\t //mark the value as overridden\n\t node.overridden = true;\n\t } else if (node instanceof AudioParam) {\n\t node.cancelScheduledValues(0);\n\t node.value = 0;\n\t }\n\t Tone.AudioNode.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t return this;\n\t };\n\t return Tone.SignalBase;\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported) {\n\t //fixes safari only bug which is still present in 11\n\t var ua = navigator.userAgent.toLowerCase();\n\t var isSafari = ua.includes('safari') && !ua.includes('chrome');\n\t if (isSafari) {\n\t var WaveShaperNode = function (context) {\n\t this._internalNode = this.input = this.output = context._native_createWaveShaper();\n\t this._curve = null;\n\t for (var prop in this._internalNode) {\n\t this._defineProperty(this._internalNode, prop);\n\t }\n\t };\n\t Object.defineProperty(WaveShaperNode.prototype, 'curve', {\n\t get: function () {\n\t return this._curve;\n\t },\n\t set: function (curve) {\n\t this._curve = curve;\n\t var array = new Float32Array(curve.length + 1);\n\t array.set(curve, 1);\n\t array[0] = curve[0];\n\t this._internalNode.curve = array;\n\t }\n\t });\n\t WaveShaperNode.prototype._defineProperty = function (context, prop) {\n\t if (Tone.isUndef(this[prop])) {\n\t Object.defineProperty(this, prop, {\n\t get: function () {\n\t if (typeof context[prop] === 'function') {\n\t return context[prop].bind(context);\n\t } else {\n\t return context[prop];\n\t }\n\t },\n\t set: function (val) {\n\t context[prop] = val;\n\t }\n\t });\n\t }\n\t };\n\t AudioContext.prototype._native_createWaveShaper = AudioContext.prototype.createWaveShaper;\n\t AudioContext.prototype.createWaveShaper = function () {\n\t return new WaveShaperNode(this);\n\t };\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Wraps the native Web Audio API\n\t\t * [WaveShaperNode](http://webaudio.github.io/web-audio-api/#the-waveshapernode-interface).\n\t\t *\n\t\t * @extends {Tone.SignalBase}\n\t\t * @constructor\n\t\t * @param {function|Array|Number} mapping The function used to define the values.\n\t\t * The mapping function should take two arguments:\n\t\t * the first is the value at the current position\n\t\t * and the second is the array position.\n\t\t * If the argument is an array, that array will be\n\t\t * set as the wave shaping function. The input\n\t\t * signal is an AudioRange [-1, 1] value and the output\n\t\t * signal can take on any numerical values.\n\t\t *\n\t\t * @param {Number} [bufferLen=1024] The length of the WaveShaperNode buffer.\n\t\t * @example\n\t\t * var timesTwo = new Tone.WaveShaper(function(val){\n\t\t * \treturn val * 2;\n\t\t * }, 2048);\n\t\t * @example\n\t\t * //a waveshaper can also be constructed with an array of values\n\t\t * var invert = new Tone.WaveShaper([1, -1]);\n\t\t */\n\t Tone.WaveShaper = function (mapping, bufferLen) {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * the waveshaper\n\t\t\t * @type {WaveShaperNode}\n\t\t\t * @private\n\t\t\t */\n\t this._shaper = this.input = this.output = this.context.createWaveShaper();\n\t /**\n\t\t\t * the waveshapers curve\n\t\t\t * @type {Float32Array}\n\t\t\t * @private\n\t\t\t */\n\t this._curve = null;\n\t if (Array.isArray(mapping)) {\n\t this.curve = mapping;\n\t } else if (isFinite(mapping) || Tone.isUndef(mapping)) {\n\t this._curve = new Float32Array(Tone.defaultArg(mapping, 1024));\n\t } else if (Tone.isFunction(mapping)) {\n\t this._curve = new Float32Array(Tone.defaultArg(bufferLen, 1024));\n\t this.setMap(mapping);\n\t }\n\t };\n\t Tone.extend(Tone.WaveShaper, Tone.SignalBase);\n\t /**\n\t\t * Uses a mapping function to set the value of the curve.\n\t\t * @param {function} mapping The function used to define the values.\n\t\t * The mapping function take two arguments:\n\t\t * the first is the value at the current position\n\t\t * which goes from -1 to 1 over the number of elements\n\t\t * in the curve array. The second argument is the array position.\n\t\t * @returns {Tone.WaveShaper} this\n\t\t * @example\n\t\t * //map the input signal from [-1, 1] to [0, 10]\n\t\t * shaper.setMap(function(val, index){\n\t\t * \treturn (val + 1) * 5;\n\t\t * })\n\t\t */\n\t Tone.WaveShaper.prototype.setMap = function (mapping) {\n\t var array = new Array(this._curve.length);\n\t for (var i = 0, len = this._curve.length; i < len; i++) {\n\t var normalized = i / (len - 1) * 2 - 1;\n\t array[i] = mapping(normalized, i);\n\t }\n\t this.curve = array;\n\t return this;\n\t };\n\t /**\n\t\t * The array to set as the waveshaper curve. For linear curves\n\t\t * array length does not make much difference, but for complex curves\n\t\t * longer arrays will provide smoother interpolation.\n\t\t * @memberOf Tone.WaveShaper#\n\t\t * @type {Array}\n\t\t * @name curve\n\t\t */\n\t Object.defineProperty(Tone.WaveShaper.prototype, 'curve', {\n\t get: function () {\n\t return this._shaper.curve;\n\t },\n\t set: function (mapping) {\n\t this._curve = new Float32Array(mapping);\n\t this._shaper.curve = this._curve;\n\t }\n\t });\n\t /**\n\t\t * Specifies what type of oversampling (if any) should be used when\n\t\t * applying the shaping curve. Can either be \"none\", \"2x\" or \"4x\".\n\t\t * @memberOf Tone.WaveShaper#\n\t\t * @type {string}\n\t\t * @name oversample\n\t\t */\n\t Object.defineProperty(Tone.WaveShaper.prototype, 'oversample', {\n\t get: function () {\n\t return this._shaper.oversample;\n\t },\n\t set: function (oversampling) {\n\t if ([\n\t 'none',\n\t '2x',\n\t '4x'\n\t ].includes(oversampling)) {\n\t this._shaper.oversample = oversampling;\n\t } else {\n\t throw new RangeError('Tone.WaveShaper: oversampling must be either \\'none\\', \\'2x\\', or \\'4x\\'');\n\t }\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.WaveShaper} this\n\t\t */\n\t Tone.WaveShaper.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._shaper.disconnect();\n\t this._shaper = null;\n\t this._curve = null;\n\t return this;\n\t };\n\t return Tone.WaveShaper;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.TimeBase is a flexible encoding of time\n\t\t * which can be evaluated to and from a string.\n\t\t * @extends {Tone}\n\t\t * @param {Time} val The time value as a number or string\n\t\t * @param {String=} units Unit values\n\t\t * @example\n\t\t * Tone.TimeBase(4, \"n\")\n\t\t * Tone.TimeBase(2, \"t\")\n\t\t * Tone.TimeBase(\"2t\")\n\t\t * Tone.TimeBase(\"2t\") + Tone.TimeBase(\"4n\");\n\t\t */\n\t Tone.TimeBase = function (val, units) {\n\t //allows it to be constructed with or without 'new'\n\t if (this instanceof Tone.TimeBase) {\n\t /**\n\t\t\t\t * The value\n\t\t\t\t * @type {Number|String|Tone.TimeBase}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._val = val;\n\t /**\n\t\t\t\t * The units\n\t\t\t\t * @type {String?}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._units = units;\n\t //test if the value is a string representation of a number\n\t if (Tone.isUndef(this._units) && Tone.isString(this._val) && // eslint-disable-next-line eqeqeq\n\t parseFloat(this._val) == this._val && this._val.charAt(0) !== '+') {\n\t this._val = parseFloat(this._val);\n\t this._units = this._defaultUnits;\n\t } else if (val && val.constructor === this.constructor) {\n\t //if they're the same type, just copy values over\n\t this._val = val._val;\n\t this._units = val._units;\n\t } else if (val instanceof Tone.TimeBase) {\n\t switch (this._defaultUnits) {\n\t case 's':\n\t this._val = val.toSeconds();\n\t break;\n\t case 'i':\n\t this._val = val.toTicks();\n\t break;\n\t case 'hz':\n\t this._val = val.toFrequency();\n\t break;\n\t case 'midi':\n\t this._val = val.toMidi();\n\t break;\n\t default:\n\t throw new Error('Unrecognized default units ' + this._defaultUnits);\n\t }\n\t }\n\t } else {\n\t return new Tone.TimeBase(val, units);\n\t }\n\t };\n\t Tone.extend(Tone.TimeBase);\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tABSTRACT SYNTAX TREE PARSER\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * All the primary expressions.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t Tone.TimeBase.prototype._expressions = {\n\t 'n': {\n\t regexp: /^(\\d+)n(\\.?)$/i,\n\t method: function (value, dot) {\n\t value = parseInt(value);\n\t var scalar = dot === '.' ? 1.5 : 1;\n\t if (value === 1) {\n\t return this._beatsToUnits(this._getTimeSignature()) * scalar;\n\t } else {\n\t return this._beatsToUnits(4 / value) * scalar;\n\t }\n\t }\n\t },\n\t 't': {\n\t regexp: /^(\\d+)t$/i,\n\t method: function (value) {\n\t value = parseInt(value);\n\t return this._beatsToUnits(8 / (parseInt(value) * 3));\n\t }\n\t },\n\t 'm': {\n\t regexp: /^(\\d+)m$/i,\n\t method: function (value) {\n\t return this._beatsToUnits(parseInt(value) * this._getTimeSignature());\n\t }\n\t },\n\t 'i': {\n\t regexp: /^(\\d+)i$/i,\n\t method: function (value) {\n\t return this._ticksToUnits(parseInt(value));\n\t }\n\t },\n\t 'hz': {\n\t regexp: /^(\\d+(?:\\.\\d+)?)hz$/i,\n\t method: function (value) {\n\t return this._frequencyToUnits(parseFloat(value));\n\t }\n\t },\n\t 'tr': {\n\t regexp: /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?$/,\n\t method: function (m, q, s) {\n\t var total = 0;\n\t if (m && m !== '0') {\n\t total += this._beatsToUnits(this._getTimeSignature() * parseFloat(m));\n\t }\n\t if (q && q !== '0') {\n\t total += this._beatsToUnits(parseFloat(q));\n\t }\n\t if (s && s !== '0') {\n\t total += this._beatsToUnits(parseFloat(s) / 4);\n\t }\n\t return total;\n\t }\n\t },\n\t 's': {\n\t regexp: /^(\\d+(?:\\.\\d+)?)s$/,\n\t method: function (value) {\n\t return this._secondsToUnits(parseFloat(value));\n\t }\n\t },\n\t 'samples': {\n\t regexp: /^(\\d+)samples$/,\n\t method: function (value) {\n\t return parseInt(value) / this.context.sampleRate;\n\t }\n\t },\n\t 'default': {\n\t regexp: /^(\\d+(?:\\.\\d+)?)$/,\n\t method: function (value) {\n\t return this._expressions[this._defaultUnits].method.call(this, value);\n\t }\n\t }\n\t };\n\t /**\n\t\t * The default units if none are given.\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._defaultUnits = 's';\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tTRANSPORT FALLBACKS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Return the bpm, or 120 if Transport is not available\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._getBpm = function () {\n\t if (Tone.Transport) {\n\t return Tone.Transport.bpm.value;\n\t } else {\n\t return 120;\n\t }\n\t };\n\t /**\n\t\t * Return the timeSignature or 4 if Transport is not available\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._getTimeSignature = function () {\n\t if (Tone.Transport) {\n\t return Tone.Transport.timeSignature;\n\t } else {\n\t return 4;\n\t }\n\t };\n\t /**\n\t\t * Return the PPQ or 192 if Transport is not available\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._getPPQ = function () {\n\t if (Tone.Transport) {\n\t return Tone.Transport.PPQ;\n\t } else {\n\t return 192;\n\t }\n\t };\n\t /**\n\t\t * Return the current time in whichever context is relevant\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._now = function () {\n\t return this.now();\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tUNIT CONVERSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Returns the value of a frequency in the current units\n\t\t * @param {Frequency} freq\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._frequencyToUnits = function (freq) {\n\t return 1 / freq;\n\t };\n\t /**\n\t\t * Return the value of the beats in the current units\n\t\t * @param {Number} beats\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._beatsToUnits = function (beats) {\n\t return 60 / this._getBpm() * beats;\n\t };\n\t /**\n\t\t * Returns the value of a second in the current units\n\t\t * @param {Seconds} seconds\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._secondsToUnits = function (seconds) {\n\t return seconds;\n\t };\n\t /**\n\t\t * Returns the value of a tick in the current time units\n\t\t * @param {Ticks} ticks\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._ticksToUnits = function (ticks) {\n\t return ticks * (this._beatsToUnits(1) / this._getPPQ());\n\t };\n\t /**\n\t\t * With no arguments, return 'now'\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.TimeBase.prototype._noArg = function () {\n\t return this._now();\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tEXPRESSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Evaluate the time value. Returns the time\n\t\t * in seconds.\n\t\t * @return {Seconds}\n\t\t */\n\t Tone.TimeBase.prototype.valueOf = function () {\n\t if (Tone.isUndef(this._val)) {\n\t return this._noArg();\n\t } else if (Tone.isString(this._val) && Tone.isUndef(this._units)) {\n\t for (var units in this._expressions) {\n\t if (this._expressions[units].regexp.test(this._val.trim())) {\n\t this._units = units;\n\t break;\n\t }\n\t }\n\t }\n\t if (Tone.isDefined(this._units)) {\n\t var expr = this._expressions[this._units];\n\t var matching = this._val.toString().trim().match(expr.regexp);\n\t if (matching) {\n\t return expr.method.apply(this, matching.slice(1));\n\t } else {\n\t return expr.method.call(this, parseFloat(this._val));\n\t }\n\t } else {\n\t return this._val;\n\t }\n\t };\n\t /**\n\t\t * Return the value in seconds\n\t\t * @return {Seconds}\n\t\t */\n\t Tone.TimeBase.prototype.toSeconds = function () {\n\t return this.valueOf();\n\t };\n\t /**\n\t\t * Return the value in hertz\n\t\t * @return {Frequency}\n\t\t */\n\t Tone.TimeBase.prototype.toFrequency = function () {\n\t return 1 / this.toSeconds();\n\t };\n\t /**\n\t\t * Return the time in samples\n\t\t * @return {Samples}\n\t\t */\n\t Tone.TimeBase.prototype.toSamples = function () {\n\t return this.toSeconds() * this.context.sampleRate;\n\t };\n\t /**\n\t\t * Return the time in milliseconds.\n\t\t * @return {Milliseconds}\n\t\t */\n\t Tone.TimeBase.prototype.toMilliseconds = function () {\n\t return this.toSeconds() * 1000;\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.TimeBase} this\n\t\t */\n\t Tone.TimeBase.prototype.dispose = function () {\n\t this._val = null;\n\t this._units = null;\n\t };\n\t return Tone.TimeBase;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Frequency is a primitive type for encoding Frequency values.\n\t\t * Eventually all time values are evaluated to hertz\n\t\t * using the `eval` method.\n\t\t * @constructor\n\t\t * @extends {Tone.TimeBase}\n\t\t * @param {String|Number} val The time value.\n\t\t * @param {String=} units The units of the value.\n\t\t * @example\n\t\t * Tone.Frequency(\"C3\") // 261\n\t\t * Tone.Frequency(38, \"midi\") //\n\t\t * Tone.Frequency(\"C3\").transpose(4);\n\t\t */\n\t Tone.Frequency = function (val, units) {\n\t if (this instanceof Tone.Frequency) {\n\t Tone.TimeBase.call(this, val, units);\n\t } else {\n\t return new Tone.Frequency(val, units);\n\t }\n\t };\n\t Tone.extend(Tone.Frequency, Tone.TimeBase);\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tAUGMENT BASE EXPRESSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t Tone.Frequency.prototype._expressions = Object.assign({}, Tone.TimeBase.prototype._expressions, {\n\t 'midi': {\n\t regexp: /^(\\d+(?:\\.\\d+)?midi)/,\n\t method: function (value) {\n\t if (this._defaultUnits === 'midi') {\n\t return value;\n\t } else {\n\t return Tone.Frequency.mtof(value);\n\t }\n\t }\n\t },\n\t 'note': {\n\t regexp: /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t method: function (pitch, octave) {\n\t var index = noteToScaleIndex[pitch.toLowerCase()];\n\t var noteNumber = index + (parseInt(octave) + 1) * 12;\n\t if (this._defaultUnits === 'midi') {\n\t return noteNumber;\n\t } else {\n\t return Tone.Frequency.mtof(noteNumber);\n\t }\n\t }\n\t },\n\t 'tr': {\n\t regexp: /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t method: function (m, q, s) {\n\t var total = 1;\n\t if (m && m !== '0') {\n\t total *= this._beatsToUnits(this._getTimeSignature() * parseFloat(m));\n\t }\n\t if (q && q !== '0') {\n\t total *= this._beatsToUnits(parseFloat(q));\n\t }\n\t if (s && s !== '0') {\n\t total *= this._beatsToUnits(parseFloat(s) / 4);\n\t }\n\t return total;\n\t }\n\t }\n\t });\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tEXPRESSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Transposes the frequency by the given number of semitones.\n\t\t * @param {Interval} interval\n\t\t * @return {Tone.Frequency} A new transposed frequency\n\t\t * @example\n\t\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t\t */\n\t Tone.Frequency.prototype.transpose = function (interval) {\n\t return new this.constructor(this.valueOf() * Tone.intervalToFrequencyRatio(interval));\n\t };\n\t /**\n\t\t * Takes an array of semitone intervals and returns\n\t\t * an array of frequencies transposed by those intervals.\n\t\t * @param {Array} intervals\n\t\t * @return {Array<Tone.Frequency>} Returns an array of Frequencies\n\t\t * @example\n\t\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t\t */\n\t Tone.Frequency.prototype.harmonize = function (intervals) {\n\t return intervals.map(function (interval) {\n\t return this.transpose(interval);\n\t }.bind(this));\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tUNIT CONVERSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Return the value of the frequency as a MIDI note\n\t\t * @return {MIDI}\n\t\t * @example\n\t\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t\t */\n\t Tone.Frequency.prototype.toMidi = function () {\n\t return Tone.Frequency.ftom(this.valueOf());\n\t };\n\t /**\n\t\t * Return the value of the frequency in Scientific Pitch Notation\n\t\t * @return {Note}\n\t\t * @example\n\t\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t\t */\n\t Tone.Frequency.prototype.toNote = function () {\n\t var freq = this.toFrequency();\n\t var log = Math.log2(freq / Tone.Frequency.A4);\n\t var noteNumber = Math.round(12 * log) + 57;\n\t var octave = Math.floor(noteNumber / 12);\n\t if (octave < 0) {\n\t noteNumber += -12 * octave;\n\t }\n\t var noteName = scaleIndexToNote[noteNumber % 12];\n\t return noteName + octave.toString();\n\t };\n\t /**\n\t\t * Return the duration of one cycle in seconds.\n\t\t * @return {Seconds}\n\t\t */\n\t Tone.Frequency.prototype.toSeconds = function () {\n\t return 1 / Tone.TimeBase.prototype.toSeconds.call(this);\n\t };\n\t /**\n\t\t * Return the value in Hertz\n\t\t * @return {Frequency}\n\t\t */\n\t Tone.Frequency.prototype.toFrequency = function () {\n\t return Tone.TimeBase.prototype.toFrequency.call(this);\n\t };\n\t /**\n\t\t * Return the duration of one cycle in ticks\n\t\t * @return {Ticks}\n\t\t */\n\t Tone.Frequency.prototype.toTicks = function () {\n\t var quarterTime = this._beatsToUnits(1);\n\t var quarters = this.valueOf() / quarterTime;\n\t return Math.floor(quarters * Tone.Transport.PPQ);\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tUNIT CONVERSIONS HELPERS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * With no arguments, return 0\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Frequency.prototype._noArg = function () {\n\t return 0;\n\t };\n\t /**\n\t\t * Returns the value of a frequency in the current units\n\t\t * @param {Frequency} freq\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Frequency.prototype._frequencyToUnits = function (freq) {\n\t return freq;\n\t };\n\t /**\n\t\t * Returns the value of a tick in the current time units\n\t\t * @param {Ticks} ticks\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Frequency.prototype._ticksToUnits = function (ticks) {\n\t return 1 / (ticks * 60 / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t };\n\t /**\n\t\t * Return the value of the beats in the current units\n\t\t * @param {Number} beats\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Frequency.prototype._beatsToUnits = function (beats) {\n\t return 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t };\n\t /**\n\t\t * Returns the value of a second in the current units\n\t\t * @param {Seconds} seconds\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Frequency.prototype._secondsToUnits = function (seconds) {\n\t return 1 / seconds;\n\t };\n\t /**\n\t\t * The default units if none are given.\n\t\t * @private\n\t\t */\n\t Tone.Frequency.prototype._defaultUnits = 'hz';\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tFREQUENCY CONVERSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Note to scale index\n\t\t * @type {Object}\n\t\t */\n\t var noteToScaleIndex = {\n\t 'cbb': -2,\n\t 'cb': -1,\n\t 'c': 0,\n\t 'c#': 1,\n\t 'cx': 2,\n\t 'dbb': 0,\n\t 'db': 1,\n\t 'd': 2,\n\t 'd#': 3,\n\t 'dx': 4,\n\t 'ebb': 2,\n\t 'eb': 3,\n\t 'e': 4,\n\t 'e#': 5,\n\t 'ex': 6,\n\t 'fbb': 3,\n\t 'fb': 4,\n\t 'f': 5,\n\t 'f#': 6,\n\t 'fx': 7,\n\t 'gbb': 5,\n\t 'gb': 6,\n\t 'g': 7,\n\t 'g#': 8,\n\t 'gx': 9,\n\t 'abb': 7,\n\t 'ab': 8,\n\t 'a': 9,\n\t 'a#': 10,\n\t 'ax': 11,\n\t 'bbb': 9,\n\t 'bb': 10,\n\t 'b': 11,\n\t 'b#': 12,\n\t 'bx': 13\n\t };\n\t /**\n\t\t * scale index to note (sharps)\n\t\t * @type {Array}\n\t\t */\n\t var scaleIndexToNote = [\n\t 'C',\n\t 'C#',\n\t 'D',\n\t 'D#',\n\t 'E',\n\t 'F',\n\t 'F#',\n\t 'G',\n\t 'G#',\n\t 'A',\n\t 'A#',\n\t 'B'\n\t ];\n\t /**\n\t\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t\t * A4's values in Hertz.\n\t\t * @type {Frequency}\n\t\t * @static\n\t\t */\n\t Tone.Frequency.A4 = 440;\n\t /**\n\t\t * Convert a MIDI note to frequency value.\n\t\t * @param {MIDI} midi The midi number to convert.\n\t\t * @return {Frequency} the corresponding frequency value\n\t\t * @static\n\t\t * @example\n\t\t * Tone.Frequency.mtof(69); // returns 440\n\t\t */\n\t Tone.Frequency.mtof = function (midi) {\n\t return Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t };\n\t /**\n\t\t * Convert a frequency value to a MIDI note.\n\t\t * @param {Frequency} frequency The value to frequency value to convert.\n\t\t * @returns {MIDI}\n\t\t * @static\n\t\t * @example\n\t\t * Tone.Frequency.ftom(440); // returns 69\n\t\t */\n\t Tone.Frequency.ftom = function (frequency) {\n\t return 69 + Math.round(12 * Math.log2(frequency / Tone.Frequency.A4));\n\t };\n\t return Tone.Frequency;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Time is a primitive type for encoding Time values.\n\t\t * Tone.Time can be constructed with or without the `new` keyword. Tone.Time can be passed\n\t\t * into the parameter of any method which takes time as an argument.\n\t\t * @constructor\n\t\t * @extends {Tone.TimeBase}\n\t\t * @param {String|Number} val The time value.\n\t\t * @param {String=} units The units of the value.\n\t\t * @example\n\t\t * var t = Tone.Time(\"4n\");//a quarter note\n\t\t */\n\t Tone.Time = function (val, units) {\n\t if (this instanceof Tone.Time) {\n\t Tone.TimeBase.call(this, val, units);\n\t } else {\n\t return new Tone.Time(val, units);\n\t }\n\t };\n\t Tone.extend(Tone.Time, Tone.TimeBase);\n\t /**\n\t\t * Extend the base expressions\n\t\t */\n\t Tone.Time.prototype._expressions = Object.assign({}, Tone.TimeBase.prototype._expressions, {\n\t 'quantize': {\n\t regexp: /^@(.+)/,\n\t method: function (capture) {\n\t if (Tone.Transport) {\n\t var quantTo = new this.constructor(capture);\n\t return Tone.Transport.nextSubdivision(quantTo);\n\t } else {\n\t return 0;\n\t }\n\t }\n\t },\n\t 'now': {\n\t regexp: /^\\+(.+)/,\n\t method: function (capture) {\n\t return this._now() + new this.constructor(capture);\n\t }\n\t }\n\t });\n\t /**\n\t\t * Quantize the time by the given subdivision. Optionally add a\n\t\t * percentage which will move the time value towards the ideal\n\t\t * quantized value by that percentage.\n\t\t * @param {Number|Time} val The subdivision to quantize to\n\t\t * @param {NormalRange} [percent=1] Move the time value\n\t\t * towards the quantized value by\n\t\t * a percentage.\n\t\t * @return {Number} this\n\t\t * @example\n\t\t * Tone.Time(21).quantize(2) //returns 22\n\t\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t\t */\n\t Tone.Time.prototype.quantize = function (subdiv, percent) {\n\t percent = Tone.defaultArg(percent, 1);\n\t var subdivision = new this.constructor(subdiv);\n\t var value = this.valueOf();\n\t var multiple = Math.round(value / subdivision);\n\t var ideal = multiple * subdivision;\n\t var diff = ideal - value;\n\t return value + diff * percent;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t // CONVERSIONS\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Convert a Time to Notation. The notation values are will be the\n\t\t * closest representation between 1m to 128th note.\n\t\t * @return {Notation}\n\t\t * @example\n\t\t * //if the Transport is at 120bpm:\n\t\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t\t */\n\t Tone.Time.prototype.toNotation = function () {\n\t var time = this.toSeconds();\n\t var testNotations = ['1m'];\n\t for (var power = 1; power < 8; power++) {\n\t var subdiv = Math.pow(2, power);\n\t testNotations.push(subdiv + 'n.');\n\t testNotations.push(subdiv + 'n');\n\t testNotations.push(subdiv + 't');\n\t }\n\t testNotations.push('0');\n\t //find the closets notation representation\n\t var closest = testNotations[0];\n\t var closestSeconds = Tone.Time(testNotations[0]).toSeconds();\n\t testNotations.forEach(function (notation) {\n\t var notationSeconds = Tone.Time(notation).toSeconds();\n\t if (Math.abs(notationSeconds - time) < Math.abs(closestSeconds - time)) {\n\t closest = notation;\n\t closestSeconds = notationSeconds;\n\t }\n\t });\n\t return closest;\n\t };\n\t /**\n\t\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t\t * @return {BarsBeatsSixteenths}\n\t\t */\n\t Tone.Time.prototype.toBarsBeatsSixteenths = function () {\n\t var quarterTime = this._beatsToUnits(1);\n\t var quarters = this.valueOf() / quarterTime;\n\t var measures = Math.floor(quarters / this._getTimeSignature());\n\t var sixteenths = quarters % 1 * 4;\n\t quarters = Math.floor(quarters) % this._getTimeSignature();\n\t sixteenths = sixteenths.toString();\n\t if (sixteenths.length > 3) {\n\t // the additional parseFloat removes insignificant trailing zeroes\n\t sixteenths = parseFloat(parseFloat(sixteenths).toFixed(3));\n\t }\n\t var progress = [\n\t measures,\n\t quarters,\n\t sixteenths\n\t ];\n\t return progress.join(':');\n\t };\n\t /**\n\t\t * Return the time in ticks.\n\t\t * @return {Ticks}\n\t\t */\n\t Tone.Time.prototype.toTicks = function () {\n\t var quarterTime = this._beatsToUnits(1);\n\t var quarters = this.valueOf() / quarterTime;\n\t return Math.round(quarters * this._getPPQ());\n\t };\n\t /**\n\t\t * Return the time in seconds.\n\t\t * @return {Seconds}\n\t\t */\n\t Tone.Time.prototype.toSeconds = function () {\n\t return this.valueOf();\n\t };\n\t /**\n\t\t * Return the value as a midi note.\n\t\t * @return {Midi}\n\t\t */\n\t Tone.Time.prototype.toMidi = function () {\n\t return Tone.Frequency.ftom(this.toFrequency());\n\t };\n\t return Tone.Time;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.TransportTime is a the time along the Transport's\n\t\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t\t * against the AudioContext's clock, it is evaluated against\n\t\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t\t * @constructor\n\t\t * @param {Time} val The time value as a number or string\n\t\t * @param {String=} units Unit values\n\t\t * @extends {Tone.Time}\n\t\t */\n\t Tone.TransportTime = function (val, units) {\n\t if (this instanceof Tone.TransportTime) {\n\t Tone.Time.call(this, val, units);\n\t } else {\n\t return new Tone.TransportTime(val, units);\n\t }\n\t };\n\t Tone.extend(Tone.TransportTime, Tone.Time);\n\t /**\n\t\t * Return the current time in whichever context is relevant\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.TransportTime.prototype._now = function () {\n\t return Tone.Transport.seconds;\n\t };\n\t return Tone.TransportTime;\n\t});\n\tModule(function (Tone) {\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tTYPES\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Units which a value can take on.\n\t\t * @enum {String}\n\t\t */\n\t Tone.Type = {\n\t /**\n\t\t\t * Default units\n\t\t\t * @typedef {Default}\n\t\t\t */\n\t Default: 'number',\n\t /**\n\t\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t\t *\n\t\t\t * * Numbers, which will be taken literally as the time (in seconds).\n\t\t\t * * Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.\n\t\t\t * * TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times\n\t\t\t * in the form BARS:QUARTERS:SIXTEENTHS.\n\t\t\t * * Frequency, (\"8hz\") is converted to the length of the cycle in seconds.\n\t\t\t * * Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as\n\t\t\t * \"the current time plus whatever expression follows\".\n\t\t\t * * Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined\n\t\t\t * into a mathematical expression which will be evaluated to compute the desired time.\n\t\t\t * * No Argument, for methods which accept time, no argument will be interpreted as\n\t\t\t * \"now\" (i.e. the currentTime).\n\t\t\t *\n\t\t\t * @typedef {Time}\n\t\t\t */\n\t Time: 'time',\n\t /**\n\t\t\t * Frequency can be described similar to time, except ultimately the\n\t\t\t * values are converted to frequency instead of seconds. A number\n\t\t\t * is taken literally as the value in hertz. Additionally any of the\n\t\t\t * Time encodings can be used. Note names in the form\n\t\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t\t * frequency value.\n\t\t\t * @typedef {Frequency}\n\t\t\t */\n\t Frequency: 'frequency',\n\t /**\n\t\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable.\n\t\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t\t * @typedef {TransportTime}\n\t\t\t */\n\t TransportTime: 'transportTime',\n\t /**\n\t\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t\t * the smallest unit of time that the Transport supports.\n\t\t\t * @typedef {Ticks}\n\t\t\t */\n\t Ticks: 'ticks',\n\t /**\n\t\t\t * Normal values are within the range [0, 1].\n\t\t\t * @typedef {NormalRange}\n\t\t\t */\n\t NormalRange: 'normalRange',\n\t /**\n\t\t\t * AudioRange values are between [-1, 1].\n\t\t\t * @typedef {AudioRange}\n\t\t\t */\n\t AudioRange: 'audioRange',\n\t /**\n\t\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t\t * because of the logarithmic way that we perceive loudness. 0 decibels\n\t\t\t * means no change in volume. -10db is approximately half as loud and 10db\n\t\t\t * is twice is loud.\n\t\t\t * @typedef {Decibels}\n\t\t\t */\n\t Decibels: 'db',\n\t /**\n\t\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t\t * @typedef {Interval}\n\t\t\t */\n\t Interval: 'interval',\n\t /**\n\t\t\t * Beats per minute.\n\t\t\t * @typedef {BPM}\n\t\t\t */\n\t BPM: 'bpm',\n\t /**\n\t\t\t * The value must be greater than or equal to 0.\n\t\t\t * @typedef {Positive}\n\t\t\t */\n\t Positive: 'positive',\n\t /**\n\t\t\t * Gain is the ratio between input and output of a signal.\n\t\t\t * A gain of 0 is the same as silencing the signal. A gain of\n\t\t\t * 1, causes no change to the incoming signal.\n\t\t\t * @typedef {Gain}\n\t\t\t */\n\t Gain: 'gain',\n\t /**\n\t\t\t * A cent is a hundredth of a semitone.\n\t\t\t * @typedef {Cents}\n\t\t\t */\n\t Cents: 'cents',\n\t /**\n\t\t\t * Angle between 0 and 360.\n\t\t\t * @typedef {Degrees}\n\t\t\t */\n\t Degrees: 'degrees',\n\t /**\n\t\t\t * A number representing a midi note.\n\t\t\t * @typedef {MIDI}\n\t\t\t */\n\t MIDI: 'midi',\n\t /**\n\t\t\t * A colon-separated representation of time in the form of\n\t\t\t * Bars:Beats:Sixteenths.\n\t\t\t * @typedef {BarsBeatsSixteenths}\n\t\t\t */\n\t BarsBeatsSixteenths: 'barsBeatsSixteenths',\n\t /**\n\t\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t\t * Audio is typically sampled 44100 times per second.\n\t\t\t * @typedef {Samples}\n\t\t\t */\n\t Samples: 'samples',\n\t /**\n\t\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t\t * @typedef {Hertz}\n\t\t\t */\n\t Hertz: 'hertz',\n\t /**\n\t\t\t * A frequency represented by a letter name,\n\t\t\t * accidental and octave. This system is known as\n\t\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t\t * @typedef {Note}\n\t\t\t */\n\t Note: 'note',\n\t /**\n\t\t\t * One millisecond is a thousandth of a second.\n\t\t\t * @typedef {Milliseconds}\n\t\t\t */\n\t Milliseconds: 'milliseconds',\n\t /**\n\t\t\t * Seconds are the time unit of the AudioContext. In the end,\n\t\t\t * all values need to be evaluated to seconds.\n\t\t\t * @typedef {Seconds}\n\t\t\t */\n\t Seconds: 'seconds',\n\t /**\n\t\t\t * A string representing a duration relative to a measure.\n\t\t\t * * \"4n\" = quarter note\n\t\t\t * * \"2m\" = two measures\n\t\t\t * * \"8t\" = eighth-note triplet\n\t\t\t * @typedef {Notation}\n\t\t\t */\n\t Notation: 'notation'\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t // AUGMENT TONE's PROTOTYPE\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Convert Time into seconds.\n\t\t *\n\t\t * Unlike the method which it overrides, this takes into account\n\t\t * transporttime and musical notation.\n\t\t *\n\t\t * Time : 1.40\n\t\t * Notation: 4n or 1m or 2t\n\t\t * Now Relative: +3n\n\t\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t\t *\n\t\t * @param {Time} time\n\t\t * @return {Seconds}\n\t\t */\n\t Tone.prototype.toSeconds = function (time) {\n\t if (Tone.isNumber(time)) {\n\t return time;\n\t } else if (Tone.isUndef(time)) {\n\t return this.now();\n\t } else if (Tone.isString(time)) {\n\t return new Tone.Time(time).toSeconds();\n\t } else if (time instanceof Tone.TimeBase) {\n\t return time.toSeconds();\n\t }\n\t };\n\t /**\n\t\t * Convert a frequency representation into a number.\n\t\t * @param {Frequency} freq\n\t\t * @return {Hertz} the frequency in hertz\n\t\t */\n\t Tone.prototype.toFrequency = function (freq) {\n\t if (Tone.isNumber(freq)) {\n\t return freq;\n\t } else if (Tone.isString(freq) || Tone.isUndef(freq)) {\n\t return new Tone.Frequency(freq).valueOf();\n\t } else if (freq instanceof Tone.TimeBase) {\n\t return freq.toFrequency();\n\t }\n\t };\n\t /**\n\t\t * Convert a time representation into ticks.\n\t\t * @param {Time} time\n\t\t * @return {Ticks} the time in ticks\n\t\t */\n\t Tone.prototype.toTicks = function (time) {\n\t if (Tone.isNumber(time) || Tone.isString(time)) {\n\t return new Tone.TransportTime(time).toTicks();\n\t } else if (Tone.isUndef(time)) {\n\t return Tone.Transport.ticks;\n\t } else if (time instanceof Tone.TimeBase) {\n\t return time.toTicks();\n\t }\n\t };\n\t return Tone;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t\t * additional unit conversion functionality. It also\n\t\t * serves as a base-class for classes which have a single,\n\t\t * automatable parameter.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {AudioParam} param The parameter to wrap.\n\t\t * @param {Tone.Type} units The units of the audio param.\n\t\t * @param {Boolean} convert If the param should be converted.\n\t\t */\n\t Tone.Param = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'param',\n\t 'units',\n\t 'convert'\n\t ], Tone.Param);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The native parameter to control\n\t\t\t * @type {AudioParam}\n\t\t\t * @private\n\t\t\t */\n\t this._param = this.input = options.param;\n\t /**\n\t\t\t * The units of the parameter\n\t\t\t * @type {Tone.Type}\n\t\t\t */\n\t this.units = options.units;\n\t /**\n\t\t\t * If the value should be converted or not\n\t\t\t * @type {Boolean}\n\t\t\t */\n\t this.convert = options.convert;\n\t /**\n\t\t\t * True if the signal value is being overridden by\n\t\t\t * a connected signal.\n\t\t\t * @readOnly\n\t\t\t * @type {boolean}\n\t\t\t * @private\n\t\t\t */\n\t this.overridden = false;\n\t /**\n\t\t\t * The timeline which tracks all of the automations.\n\t\t\t * @type {Tone.Timeline}\n\t\t\t * @private\n\t\t\t */\n\t this._events = new Tone.Timeline(1000);\n\t if (Tone.isDefined(options.value) && this._param) {\n\t this.value = options.value;\n\t }\n\t };\n\t Tone.extend(Tone.Param, Tone.AudioNode);\n\t /**\n\t\t * Defaults\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Param.defaults = {\n\t 'units': Tone.Type.Default,\n\t 'convert': true,\n\t 'param': undefined\n\t };\n\t /**\n\t\t * The current value of the parameter.\n\t\t * @memberOf Tone.Param#\n\t\t * @type {Number}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.Param.prototype, 'value', {\n\t get: function () {\n\t var now = this.now();\n\t return this._toUnits(this.getValueAtTime(now));\n\t },\n\t set: function (value) {\n\t this._initialValue = this._fromUnits(value);\n\t this.cancelScheduledValues(this.context.currentTime);\n\t this.setValueAtTime(value, this.context.currentTime);\n\t }\n\t });\n\t /**\n\t\t * The minimum output value of the parameter\n\t\t * @memberOf Tone.Param#\n\t\t * @type {Number}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.Param.prototype, 'minValue', {\n\t get: function () {\n\t if (this.units === Tone.Type.Time || this.units === Tone.Type.Frequency || this.units === Tone.Type.NormalRange || this.units === Tone.Type.Positive || this.units === Tone.Type.BPM) {\n\t return 0;\n\t } else if (this.units === Tone.Type.AudioRange) {\n\t return -1;\n\t } else if (this.units === Tone.Type.Decibels) {\n\t return -Infinity;\n\t } else {\n\t return this._param.minValue;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The maximum output value of the parameter\n\t\t * @memberOf Tone.Param#\n\t\t * @type {Number}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.Param.prototype, 'maxValue', {\n\t get: function () {\n\t if (this.units === Tone.Type.NormalRange || this.units === Tone.Type.AudioRange) {\n\t return 1;\n\t } else {\n\t return this._param.maxValue;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Convert the given value from the type specified by Tone.Param.units\n\t\t * into the destination value (such as Gain or Frequency).\n\t\t * @private\n\t\t * @param {*} val the value to convert\n\t\t * @return {number} the number which the value should be set to\n\t\t */\n\t Tone.Param.prototype._fromUnits = function (val) {\n\t if ((this.convert || Tone.isUndef(this.convert)) && !this.overridden) {\n\t switch (this.units) {\n\t case Tone.Type.Time:\n\t return this.toSeconds(val);\n\t case Tone.Type.Frequency:\n\t return this.toFrequency(val);\n\t case Tone.Type.Decibels:\n\t return Tone.dbToGain(val);\n\t case Tone.Type.NormalRange:\n\t return Math.min(Math.max(val, 0), 1);\n\t case Tone.Type.AudioRange:\n\t return Math.min(Math.max(val, -1), 1);\n\t case Tone.Type.Positive:\n\t return Math.max(val, 0);\n\t default:\n\t return val;\n\t }\n\t } else {\n\t return val;\n\t }\n\t };\n\t /**\n\t\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t\t * @private\n\t\t * @param {number} val the value to convert\n\t\t * @return {number}\n\t\t */\n\t Tone.Param.prototype._toUnits = function (val) {\n\t if (this.convert || Tone.isUndef(this.convert)) {\n\t switch (this.units) {\n\t case Tone.Type.Decibels:\n\t return Tone.gainToDb(val);\n\t default:\n\t return val;\n\t }\n\t } else {\n\t return val;\n\t }\n\t };\n\t /**\n\t\t * the minimum output value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.Param.prototype._minOutput = 0.00001;\n\t /**\n\t\t * The event types\n\t\t * @enum {String}\n\t\t * @private\n\t\t */\n\t Tone.Param.AutomationType = {\n\t Linear: 'linearRampToValueAtTime',\n\t Exponential: 'exponentialRampToValueAtTime',\n\t Target: 'setTargetAtTime',\n\t SetValue: 'setValueAtTime'\n\t };\n\t /**\n\t\t * Schedules a parameter value change at the given time.\n\t\t * @param {*}\tvalue The value to set the signal.\n\t\t * @param {Time} time The time when the change should occur.\n\t\t * @returns {Tone.Param} this\n\t\t * @example\n\t\t * //set the frequency to \"G4\" in exactly 1 second from now.\n\t\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t\t */\n\t Tone.Param.prototype.setValueAtTime = function (value, time) {\n\t time = this.toSeconds(time);\n\t value = this._fromUnits(value);\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.SetValue,\n\t 'value': value,\n\t 'time': time\n\t });\n\t this._param.setValueAtTime(value, time);\n\t return this;\n\t };\n\t /**\n\t\t * Get the signals value at the given time. Subsequent scheduling\n\t\t * may invalidate the returned value.\n\t\t * @param {Time} time When to get the value\n\t\t * @returns {Number} The value at the given time\n\t\t */\n\t Tone.Param.prototype.getValueAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t var after = this._events.getAfter(time);\n\t var before = this._events.get(time);\n\t var initialValue = Tone.defaultArg(this._initialValue, this._param.defaultValue);\n\t var value = initialValue;\n\t //if it was set by\n\t if (before === null) {\n\t value = initialValue;\n\t } else if (before.type === Tone.Param.AutomationType.Target) {\n\t var previous = this._events.getBefore(before.time);\n\t var previousVal;\n\t if (previous === null) {\n\t previousVal = initialValue;\n\t } else {\n\t previousVal = previous.value;\n\t }\n\t value = this._exponentialApproach(before.time, previousVal, before.value, before.constant, time);\n\t } else if (after === null) {\n\t value = before.value;\n\t } else if (after.type === Tone.Param.AutomationType.Linear) {\n\t value = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t } else if (after.type === Tone.Param.AutomationType.Exponential) {\n\t value = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t } else {\n\t value = before.value;\n\t }\n\t return value;\n\t };\n\t /**\n\t\t * Creates a schedule point with the current value at the current time.\n\t\t * This is useful for creating an automation anchor point in order to\n\t\t * schedule changes from the current value.\n\t\t *\n\t\t * @param {number=} now (Optionally) pass the now value in.\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.setRampPoint = function (time) {\n\t time = this.toSeconds(time);\n\t var currentVal = this.getValueAtTime(time);\n\t this.cancelAndHoldAtTime(time);\n\t if (currentVal === 0) {\n\t currentVal = this._minOutput;\n\t }\n\t this.setValueAtTime(this._toUnits(currentVal), time);\n\t return this;\n\t };\n\t /**\n\t\t * Schedules a linear continuous change in parameter value from the\n\t\t * previous scheduled parameter value to the given value.\n\t\t *\n\t\t * @param {number} value\n\t\t * @param {Time} endTime\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t value = this._fromUnits(value);\n\t endTime = this.toSeconds(endTime);\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.Linear,\n\t 'value': value,\n\t 'time': endTime\n\t });\n\t this._param.linearRampToValueAtTime(value, endTime);\n\t return this;\n\t };\n\t /**\n\t\t * Schedules an exponential continuous change in parameter value from\n\t\t * the previous scheduled parameter value to the given value.\n\t\t *\n\t\t * @param {number} value\n\t\t * @param {Time} endTime\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t value = this._fromUnits(value);\n\t value = Math.max(this._minOutput, value);\n\t endTime = this.toSeconds(endTime);\n\t //store the event\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.Exponential,\n\t 'time': endTime,\n\t 'value': value\n\t });\n\t this._param.exponentialRampToValueAtTime(value, endTime);\n\t return this;\n\t };\n\t /**\n\t\t * Schedules an exponential continuous change in parameter value from\n\t\t * the current time and current value to the given value over the\n\t\t * duration of the rampTime.\n\t\t *\n\t\t * @param {number} value The value to ramp to.\n\t\t * @param {Time} rampTime the time that it takes the\n\t\t * value to ramp from it's current value\n\t\t * @param {Time}\t[startTime=now] \tWhen the ramp should start.\n\t\t * @returns {Tone.Param} this\n\t\t * @example\n\t\t * //exponentially ramp to the value 2 over 4 seconds.\n\t\t * signal.exponentialRampTo(2, 4);\n\t\t */\n\t Tone.Param.prototype.exponentialRampTo = function (value, rampTime, startTime) {\n\t startTime = this.toSeconds(startTime);\n\t this.setRampPoint(startTime);\n\t this.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t return this;\n\t };\n\t /**\n\t\t * Schedules an linear continuous change in parameter value from\n\t\t * the current time and current value to the given value over the\n\t\t * duration of the rampTime.\n\t\t *\n\t\t * @param {number} value The value to ramp to.\n\t\t * @param {Time} rampTime the time that it takes the\n\t\t * value to ramp from it's current value\n\t\t * @param {Time}\t[startTime=now] \tWhen the ramp should start.\n\t\t * @returns {Tone.Param} this\n\t\t * @example\n\t\t * //linearly ramp to the value 4 over 3 seconds.\n\t\t * signal.linearRampTo(4, 3);\n\t\t */\n\t Tone.Param.prototype.linearRampTo = function (value, rampTime, startTime) {\n\t startTime = this.toSeconds(startTime);\n\t this.setRampPoint(startTime);\n\t this.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t return this;\n\t };\n\t /**\n\t\t * Start exponentially approaching the target value at the given time. Since it\n\t\t * is an exponential approach it will continue approaching after the ramp duration. The\n\t\t * rampTime is the time that it takes to reach over 99% of the way towards the value.\n\t\t * @param {number} value The value to ramp to.\n\t\t * @param {Time} rampTime the time that it takes the\n\t\t * value to ramp from it's current value\n\t\t * @param {Time}\t[startTime=now] \tWhen the ramp should start.\n\t\t * @returns {Tone.Param} this\n\t\t * @example\n\t\t * //exponentially ramp to the value 2 over 4 seconds.\n\t\t * signal.exponentialRampTo(2, 4);\n\t\t */\n\t Tone.Param.prototype.targetRampTo = function (value, rampTime, startTime) {\n\t startTime = this.toSeconds(startTime);\n\t this.setRampPoint(startTime);\n\t this.exponentialApproachValueAtTime(value, startTime, rampTime);\n\t return this;\n\t };\n\t /**\n\t\t * Start exponentially approaching the target value at the given time. Since it\n\t\t * is an exponential approach it will continue approaching after the ramp duration. The\n\t\t * rampTime is the time that it takes to reach over 99% of the way towards the value. This methods\n\t\t * is similar to setTargetAtTime except the third argument is a time instead of a 'timeConstant'\n\t\t * @param {number} value The value to ramp to.\n\t\t * @param {Time}\ttime \tWhen the ramp should start.\n\t\t * @param {Time} rampTime the time that it takes the\n\t\t * value to ramp from it's current value\n\t\t * @returns {Tone.Param} this\n\t\t * @example\n\t\t * //exponentially ramp to the value 2 over 4 seconds.\n\t\t * signal.exponentialRampTo(2, 4);\n\t\t */\n\t Tone.Param.prototype.exponentialApproachValueAtTime = function (value, time, rampTime) {\n\t var timeConstant = Math.log(this.toSeconds(rampTime) + 1) / Math.log(200);\n\t time = this.toSeconds(time);\n\t return this.setTargetAtTime(value, time, timeConstant);\n\t };\n\t /**\n\t\t * Start exponentially approaching the target value at the given time with\n\t\t * a rate having the given time constant.\n\t\t * @param {number} value\n\t\t * @param {Time} startTime\n\t\t * @param {number} timeConstant\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t value = this._fromUnits(value);\n\t // The value will never be able to approach without timeConstant > 0.\n\t if (timeConstant <= 0) {\n\t throw new Error('timeConstant must be greater than 0');\n\t }\n\t startTime = this.toSeconds(startTime);\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.Target,\n\t 'value': value,\n\t 'time': startTime,\n\t 'constant': timeConstant\n\t });\n\t this._param.setTargetAtTime(value, startTime, timeConstant);\n\t return this;\n\t };\n\t /**\n\t\t * Sets an array of arbitrary parameter values starting at the given time\n\t\t * for the given duration.\n\t\t *\n\t\t * @param {Array} values\n\t\t * @param {Time} startTime\n\t\t * @param {Time} duration\n\t\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t scaling = Tone.defaultArg(scaling, 1);\n\t duration = this.toSeconds(duration);\n\t startTime = this.toSeconds(startTime);\n\t this.setValueAtTime(values[0] * scaling, startTime);\n\t var segTime = duration / (values.length - 1);\n\t for (var i = 1; i < values.length; i++) {\n\t this.linearRampToValueAtTime(values[i] * scaling, startTime + i * segTime);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Cancels all scheduled parameter changes with times greater than or\n\t\t * equal to startTime.\n\t\t *\n\t\t * @param {Time} time\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.cancelScheduledValues = function (time) {\n\t time = this.toSeconds(time);\n\t this._events.cancel(time);\n\t this._param.cancelScheduledValues(time);\n\t return this;\n\t };\n\t /**\n\t\t * This is similar to [cancelScheduledValues](#cancelScheduledValues) except\n\t\t * it holds the automated value at time until the next automated event.\n\t\t * @param {Time} time\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.cancelAndHoldAtTime = function (time) {\n\t var valueAtTime = this.getValueAtTime(time);\n\t //if there is an event at the given time\n\t //and that even is not a \"set\"\n\t var before = this._events.get(time);\n\t var after = this._events.getAfter(time);\n\t if (before && before.time === time) {\n\t //remove everything after\n\t if (after) {\n\t this._events.cancel(after.time);\n\t } else {\n\t this._events.cancel(time + 0.000001);\n\t }\n\t } else if (after) {\n\t //cancel the next event(s)\n\t this._events.cancel(after.time);\n\t if (!this._param.cancelAndHoldAtTime) {\n\t this._param.cancelScheduledValues(time);\n\t }\n\t if (after.type === Tone.Param.AutomationType.Linear) {\n\t if (!this._param.cancelAndHoldAtTime) {\n\t this.linearRampToValueAtTime(valueAtTime, time);\n\t } else {\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.Linear,\n\t 'value': valueAtTime,\n\t 'time': time\n\t });\n\t }\n\t } else if (after.type === Tone.Param.AutomationType.Exponential) {\n\t if (!this._param.cancelAndHoldAtTime) {\n\t this.exponentialRampToValueAtTime(valueAtTime, time);\n\t } else {\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.Exponential,\n\t 'value': valueAtTime,\n\t 'time': time\n\t });\n\t }\n\t }\n\t }\n\t //set the value at the given time\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.SetValue,\n\t 'value': valueAtTime,\n\t 'time': time\n\t });\n\t if (this._param.cancelAndHoldAtTime) {\n\t this._param.cancelAndHoldAtTime(time);\n\t } else {\n\t this._param.setValueAtTime(valueAtTime, time);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Ramps to the given value over the duration of the rampTime.\n\t\t * Automatically selects the best ramp type (exponential or linear)\n\t\t * depending on the `units` of the signal\n\t\t *\n\t\t * @param {number} value\n\t\t * @param {Time} rampTime \tThe time that it takes the\n\t\t * value to ramp from it's current value\n\t\t * @param {Time}\t[startTime=now] \tWhen the ramp should start.\n\t\t * @returns {Tone.Param} this\n\t\t * @example\n\t\t * //ramp to the value either linearly or exponentially\n\t\t * //depending on the \"units\" value of the signal\n\t\t * signal.rampTo(0, 10);\n\t\t * @example\n\t\t * //schedule it to ramp starting at a specific time\n\t\t * signal.rampTo(0, 10, 5)\n\t\t */\n\t Tone.Param.prototype.rampTo = function (value, rampTime, startTime) {\n\t rampTime = Tone.defaultArg(rampTime, 0.1);\n\t if (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels) {\n\t this.exponentialRampTo(value, rampTime, startTime);\n\t } else {\n\t this.linearRampTo(value, rampTime, startTime);\n\t }\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tAUTOMATION CURVE CALCULATIONS\n\t //\tMIT License, copyright (c) 2014 Jordan Santell\n\t ///////////////////////////////////////////////////////////////////////////\n\t // Calculates the the value along the curve produced by setTargetAtTime\n\t Tone.Param.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t };\n\t // Calculates the the value along the curve produced by linearRampToValueAtTime\n\t Tone.Param.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t };\n\t // Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t Tone.Param.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.Param.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._param = null;\n\t this._events = null;\n\t return this;\n\t };\n\t return Tone.Param;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Wrapper around the OfflineAudioContext\n\t\t * @extends {Tone.Context}\n\t\t * @param {Number} channels The number of channels to render\n\t\t * @param {Number} duration The duration to render in samples\n\t\t * @param {Number} sampleRate the sample rate to render at\n\t\t */\n\t Tone.OfflineContext = function (channels, duration, sampleRate) {\n\t /**\n\t\t\t * The offline context\n\t\t\t * @private\n\t\t\t * @type {OfflineAudioContext}\n\t\t\t */\n\t var offlineContext = new OfflineAudioContext(channels, duration * sampleRate, sampleRate);\n\t //wrap the methods/members\n\t Tone.Context.call(this, {\n\t 'context': offlineContext,\n\t 'clockSource': 'offline',\n\t 'lookAhead': 0,\n\t 'updateInterval': 128 / sampleRate\n\t });\n\t /**\n\t\t\t * A private reference to the duration\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._duration = duration;\n\t /**\n\t\t\t * An artificial clock source\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._currentTime = 0;\n\t };\n\t Tone.extend(Tone.OfflineContext, Tone.Context);\n\t /**\n\t\t * Override the now method to point to the internal clock time\n\t\t * @return {Number}\n\t\t */\n\t Tone.OfflineContext.prototype.now = function () {\n\t return this._currentTime;\n\t };\n\t /**\n\t\t * Render the output of the OfflineContext\n\t\t * @return {Promise}\n\t\t */\n\t Tone.OfflineContext.prototype.render = function () {\n\t while (this._duration - this._currentTime >= 0) {\n\t //invoke all the callbacks on that time\n\t this.emit('tick');\n\t //increment the clock\n\t this._currentTime += this.blockTime;\n\t }\n\t return this._context.startRendering();\n\t };\n\t /**\n\t\t * Close the context\n\t\t * @return {Promise}\n\t\t */\n\t Tone.OfflineContext.prototype.close = function () {\n\t this._context = null;\n\t return Promise.resolve();\n\t };\n\t return Tone.OfflineContext;\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported) {\n\t var ua = navigator.userAgent.toLowerCase();\n\t var isMobileSafari = ua.includes('safari') && !ua.includes('chrome') && ua.includes('mobile');\n\t if (isMobileSafari) {\n\t //mobile safari has a bizarre bug with the offline context\n\t //when a BufferSourceNode is started, it starts the offline context\n\t //\n\t //deferring all BufferSource starts till the last possible moment\n\t //reduces the likelihood of this happening\n\t Tone.OfflineContext.prototype.createBufferSource = function () {\n\t var bufferSource = this._context.createBufferSource();\n\t var _native_start = bufferSource.start;\n\t bufferSource.start = function (time) {\n\t this.setTimeout(function () {\n\t _native_start.call(bufferSource, time);\n\t }.bind(this), 0);\n\t }.bind(this);\n\t return bufferSource;\n\t };\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t\t * The GainNode is a basic building block of the Web Audio\n\t\t * API and is useful for routing audio and adjusting gains.\n\t\t * @extends {Tone}\n\t\t * @param {Number=} gain The initial gain of the GainNode\n\t\t * @param {Tone.Type=} units The units of the gain parameter.\n\t\t */\n\t Tone.Gain = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'gain',\n\t 'units'\n\t ], Tone.Gain);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The GainNode\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.input = this.output = this._gainNode = this.context.createGain();\n\t /**\n\t\t\t * The gain parameter of the gain node.\n\t\t\t * @type {Gain}\n\t\t\t * @signal\n\t\t\t */\n\t this.gain = new Tone.Param({\n\t 'param': this._gainNode.gain,\n\t 'units': options.units,\n\t 'value': options.gain,\n\t 'convert': options.convert\n\t });\n\t this._readOnly('gain');\n\t };\n\t Tone.extend(Tone.Gain, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Gain.defaults = {\n\t 'gain': 1,\n\t 'convert': true\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Gain} this\n\t\t */\n\t Tone.Gain.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._gainNode.disconnect();\n\t this._gainNode = null;\n\t this._writable('gain');\n\t this.gain.dispose();\n\t this.gain = null;\n\t };\n\t return Tone.Gain;\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported && !AudioContext.prototype.createConstantSource) {\n\t var ConstantSourceNode = function (context) {\n\t this.context = context;\n\t var buffer = context.createBuffer(1, 128, context.sampleRate);\n\t var arr = buffer.getChannelData(0);\n\t for (var i = 0; i < arr.length; i++) {\n\t arr[i] = 1;\n\t }\n\t this._bufferSource = context.createBufferSource();\n\t this._bufferSource.channelCount = 1;\n\t this._bufferSource.channelCountMode = 'explicit';\n\t this._bufferSource.buffer = buffer;\n\t this._bufferSource.loop = true;\n\t var gainNode = this._output = context.createGain();\n\t this.offset = gainNode.gain;\n\t this._bufferSource.connect(gainNode);\n\t };\n\t ConstantSourceNode.prototype.start = function (time) {\n\t this._bufferSource.start(time);\n\t return this;\n\t };\n\t ConstantSourceNode.prototype.stop = function (time) {\n\t this._bufferSource.stop(time);\n\t return this;\n\t };\n\t ConstantSourceNode.prototype.connect = function () {\n\t this._output.connect.apply(this._output, arguments);\n\t return this;\n\t };\n\t ConstantSourceNode.prototype.disconnect = function () {\n\t this._output.disconnect.apply(this._output, arguments);\n\t return this;\n\t };\n\t AudioContext.prototype.createConstantSource = function () {\n\t return new ConstantSourceNode(this);\n\t };\n\t Tone.Context.prototype.createConstantSource = function () {\n\t return new ConstantSourceNode(this);\n\t };\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t\t * has all of the methods available to native Web Audio\n\t\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t\t * as well as additional conveniences. Read more about working with signals\n\t\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Param}\n\t\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t\t * is passed in, that parameter will be wrapped\n\t\t * and controlled by the Signal.\n\t\t * @param {string} [units=Number] unit The units the signal is in.\n\t\t * @example\n\t\t * var signal = new Tone.Signal(10);\n\t\t */\n\t Tone.Signal = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'value',\n\t 'units'\n\t ], Tone.Signal);\n\t Tone.Param.call(this, options);\n\t /**\n\t\t\t* When a signal is connected to another signal or audio param,\n\t\t\t* this signal becomes a proxy for it\n\t\t\t* @type {Array}\n\t\t\t* @private\n\t\t\t*/\n\t this._proxies = [];\n\t /**\n\t\t\t* Indicates if the constant source was started or not\n\t\t\t* @private\n\t\t\t* @type {Boolean}\n\t\t\t*/\n\t this._sourceStarted = false;\n\t /**\n\t\t\t * The constant source node which generates the signal\n\t\t\t * @type {ConstantSourceNode}\n\t\t\t * @private\n\t\t\t */\n\t this._constantSource = this.context.createConstantSource();\n\t this._param = this._constantSource.offset;\n\t this.value = options.value;\n\t /**\n\t\t\t * The node where the constant signal value is scaled.\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.output = this._constantSource;\n\t /**\n\t\t\t * The node where the value is set.\n\t\t\t * @type {Tone.Param}\n\t\t\t * @private\n\t\t\t */\n\t this.input = this._param = this.output.offset;\n\t };\n\t Tone.extend(Tone.Signal, Tone.Param);\n\t /**\n\t\t * The default values\n\t\t * @type {Object}\n\t\t * @static\n\t\t * @const\n\t\t */\n\t Tone.Signal.defaults = {\n\t 'value': 0,\n\t 'units': Tone.Type.Default,\n\t 'convert': true\n\t };\n\t /**\n\t\t * When signals connect to other signals or AudioParams,\n\t\t * they take over the output value of that signal or AudioParam.\n\t\t * For all other nodes, the behavior is the same as a default <code>connect</code>.\n\t\t *\n\t\t * @override\n\t\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node\n\t\t * @param {number} [outputNumber=0] The output number to connect from.\n\t\t * @param {number} [inputNumber=0] The input number to connect to.\n\t\t * @returns {Tone.Signal} this\n\t\t * @method\n\t\t */\n\t Tone.Signal.prototype.connect = function (node) {\n\t //this is an optimization where this node will forward automations\n\t //to connected nodes without any signal if possible.\n\t if (this._isParam(node) && !this._sourceStarted) {\n\t this._proxies.push(node);\n\t node.overridden = true;\n\t this._applyAutomations(node);\n\t } else {\n\t Tone.SignalBase.prototype.connect.apply(this, arguments);\n\t if (!this._sourceStarted) {\n\t this._sourceStarted = true;\n\t this._constantSource.start(0);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Takes a node as an argument and returns if it is a Param or AudioParam\n\t\t * @param {*} node The node to test\n\t\t * @return {Boolean}\n\t\t * @private\n\t\t */\n\t Tone.Signal.prototype._isParam = function (node) {\n\t return Tone.Param && Tone.Param === node.constructor || node instanceof AudioParam;\n\t };\n\t /**\n\t\t * Discard the optimization and connect all of the proxies\n\t\t * @private\n\t\t */\n\t Tone.Signal.prototype._connectProxies = function () {\n\t if (!this._sourceStarted) {\n\t this._sourceStarted = true;\n\t this._constantSource.start(0);\n\t }\n\t this._proxies.forEach(function (proxy) {\n\t Tone.SignalBase.prototype.connect.call(this, proxy);\n\t if (proxy._proxies) {\n\t proxy._connectProxies();\n\t }\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Invoked when a node is connected to this\n\t\t * @param {AudioNode} from\n\t\t * @private\n\t\t */\n\t Tone.Signal.prototype._onConnect = function (from) {\n\t if (!this._isParam(from)) {\n\t //connect all the proxies\n\t this._connectProxies();\n\t }\n\t };\n\t /**\n\t\t * Apply all the current automations to the given parameter\n\t\t * @param {AudioParam} param\n\t\t * @private\n\t\t */\n\t Tone.Signal.prototype._applyAutomations = function (param) {\n\t var now = this.context.currentTime;\n\t param.cancelScheduledValues(now);\n\t var currentVal = this.getValueAtTime(now);\n\t param.setValueAtTime(currentVal, now);\n\t this._events.forEachFrom(now, function (event) {\n\t param[event.type](event.value, event.time, event.constant);\n\t });\n\t };\n\t /**\n\t\t * Disconnect from the given node or all nodes if no param is given.\n\t\t * @param {AudioNode|AudioParam} node\n\t\t * @return {Tone.Signal} this\n\t\t */\n\t Tone.Signal.prototype.disconnect = function (node) {\n\t if (this._proxies.includes(node)) {\n\t var index = this._proxies.indexOf(node);\n\t this._proxies.splice(index, 1);\n\t } else if (!node) {\n\t //no argument, disconnect everything\n\t this._proxies = [];\n\t }\n\t return Tone.SignalBase.prototype.disconnect.apply(this, arguments);\n\t };\n\t /**\n\t\t * Return the current signal value at the given time.\n\t\t * @param {Time} time When to get the signal value\n\t\t * @return {Number}\n\t\t */\n\t Tone.Signal.prototype.getValueAtTime = function (time) {\n\t if (this._param.getValueAtTime) {\n\t return this._param.getValueAtTime(time);\n\t } else {\n\t return Tone.Param.prototype.getValueAtTime.call(this, time);\n\t }\n\t };\n\t //wrap all of the automation methods\n\t [\n\t 'setValueAtTime',\n\t 'linearRampToValueAtTime',\n\t 'exponentialRampToValueAtTime',\n\t 'setTargetAtTime'\n\t ].forEach(function (method) {\n\t var previousMethod = Tone.Signal.prototype[method];\n\t Tone.Signal.prototype[method] = function () {\n\t var args = arguments;\n\t previousMethod.apply(this, arguments);\n\t args[0] = this._fromUnits(args[0]);\n\t args[1] = this.toSeconds(args[1]);\n\t //apply it to the proxies\n\t this._proxies.forEach(function (signal) {\n\t signal[method].apply(signal, args);\n\t });\n\t };\n\t });\n\t [\n\t 'cancelScheduledValues',\n\t 'cancelAndHoldAtTime'\n\t ].forEach(function (method) {\n\t var previousMethod = Tone.Signal.prototype[method];\n\t Tone.Signal.prototype[method] = function () {\n\t var args = arguments;\n\t previousMethod.apply(this, arguments);\n\t args[0] = this.toSeconds(args[0]);\n\t //apply it to the proxies\n\t this._proxies.forEach(function (signal) {\n\t signal[method].apply(signal, args);\n\t });\n\t };\n\t });\n\t /**\n\t\t * dispose and disconnect\n\t\t * @returns {Tone.Signal} this\n\t\t */\n\t Tone.Signal.prototype.dispose = function () {\n\t Tone.Param.prototype.dispose.call(this);\n\t this._constantSource.disconnect();\n\t this._constantSource = null;\n\t this._proxies = null;\n\t return this;\n\t };\n\t return Tone.Signal;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t\t * must be AudioRange.\n\t\t *\n\t\t * @extends {Tone.SignalBase}\n\t\t * @constructor\n\t\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t\t * @example\n\t\t * var pow = new Tone.Pow(2);\n\t\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t\t * //output of pow is 0.25. \n\t\t */\n\t Tone.Pow = function (exp) {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * the exponent\n\t\t\t * @private\n\t\t\t * @type {number}\n\t\t\t */\n\t this._exp = Tone.defaultArg(exp, 1);\n\t /**\n\t\t\t * @type {WaveShaperNode}\n\t\t\t * @private\n\t\t\t */\n\t this._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t };\n\t Tone.extend(Tone.Pow, Tone.SignalBase);\n\t /**\n\t\t * The value of the exponent.\n\t\t * @memberOf Tone.Pow#\n\t\t * @type {number}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.Pow.prototype, 'value', {\n\t get: function () {\n\t return this._exp;\n\t },\n\t set: function (exp) {\n\t this._exp = exp;\n\t this._expScaler.setMap(this._expFunc(this._exp));\n\t }\n\t });\n\t /**\n\t\t * the function which maps the waveshaper\n\t\t * @param {number} exp\n\t\t * @return {function}\n\t\t * @private\n\t\t */\n\t Tone.Pow.prototype._expFunc = function (exp) {\n\t return function (val) {\n\t return Math.pow(Math.abs(val), exp);\n\t };\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Pow} this\n\t\t */\n\t Tone.Pow.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._expScaler.dispose();\n\t this._expScaler = null;\n\t return this;\n\t };\n\t return Tone.Pow;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Envelope is an [ADSR](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope)\n\t\t * envelope generator. Tone.Envelope outputs a signal which\n\t\t * can be connected to an AudioParam or Tone.Signal.\n\t\t * <img src=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Time} [attack] The amount of time it takes for the envelope to go from\n\t\t * 0 to it's maximum value.\n\t\t * @param {Time} [decay]\tThe period of time after the attack that it takes for the envelope\n\t\t * \tto fall to the sustain value.\n\t\t * @param {NormalRange} [sustain]\tThe percent of the maximum value that the envelope rests at until\n\t\t * \tthe release is triggered.\n\t\t * @param {Time} [release]\tThe amount of time after the release is triggered it takes to reach 0.\n\t\t * @example\n\t\t * //an amplitude envelope\n\t\t * var gainNode = Tone.context.createGain();\n\t\t * var env = new Tone.Envelope({\n\t\t * \t\"attack\" : 0.1,\n\t\t * \t\"decay\" : 0.2,\n\t\t * \t\"sustain\" : 1,\n\t\t * \t\"release\" : 0.8,\n\t\t * });\n\t\t * env.connect(gainNode.gain);\n\t\t */\n\t Tone.Envelope = function () {\n\t //get all of the defaults\n\t var options = Tone.defaults(arguments, [\n\t 'attack',\n\t 'decay',\n\t 'sustain',\n\t 'release'\n\t ], Tone.Envelope);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * When triggerAttack is called, the attack time is the amount of\n\t\t\t * time it takes for the envelope to reach it's maximum value.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.attack = options.attack;\n\t /**\n\t\t\t * After the attack portion of the envelope, the value will fall\n\t\t\t * over the duration of the decay time to it's sustain value.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.decay = options.decay;\n\t /**\n\t\t\t * \tThe sustain value is the value\n\t\t\t * \twhich the envelope rests at after triggerAttack is\n\t\t\t * \tcalled, but before triggerRelease is invoked.\n\t\t\t * @type {NormalRange}\n\t\t\t */\n\t this.sustain = options.sustain;\n\t /**\n\t\t\t * After triggerRelease is called, the envelope's\n\t\t\t * value will fall to it's miminum value over the\n\t\t\t * duration of the release time.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.release = options.release;\n\t /**\n\t\t\t * the next time the envelope is at standby\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._attackCurve = 'linear';\n\t /**\n\t\t\t * the next time the envelope is at standby\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._releaseCurve = 'exponential';\n\t /**\n\t\t\t * the signal\n\t\t\t * @type {Tone.Signal}\n\t\t\t * @private\n\t\t\t */\n\t this._sig = this.output = new Tone.Signal(0);\n\t //set the attackCurve initially\n\t this.attackCurve = options.attackCurve;\n\t this.releaseCurve = options.releaseCurve;\n\t };\n\t Tone.extend(Tone.Envelope, Tone.AudioNode);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t * @const\n\t\t */\n\t Tone.Envelope.defaults = {\n\t 'attack': 0.01,\n\t 'decay': 0.1,\n\t 'sustain': 0.5,\n\t 'release': 1,\n\t 'attackCurve': 'linear',\n\t 'releaseCurve': 'exponential'\n\t };\n\t /**\n\t\t * Read the current value of the envelope. Useful for\n\t\t * syncronizing visual output to the envelope.\n\t\t * @memberOf Tone.Envelope#\n\t\t * @type {Number}\n\t\t * @name value\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Envelope.prototype, 'value', {\n\t get: function () {\n\t return this.getValueAtTime(this.now());\n\t }\n\t });\n\t /**\n\t\t * The shape of the attack.\n\t\t * Can be any of these strings:\n\t\t * <ul>\n\t\t * <li>linear</li>\n\t\t * <li>exponential</li>\n\t\t * <li>sine</li>\n\t\t * <li>cosine</li>\n\t\t * <li>bounce</li>\n\t\t * <li>ripple</li>\n\t\t * <li>step</li>\n\t\t * </ul>\n\t\t * Can also be an array which describes the curve. Values\n\t\t * in the array are evenly subdivided and linearly\n\t\t * interpolated over the duration of the attack.\n\t\t * @memberOf Tone.Envelope#\n\t\t * @type {String|Array}\n\t\t * @name attackCurve\n\t\t * @example\n\t\t * env.attackCurve = \"linear\";\n\t\t * @example\n\t\t * //can also be an array\n\t\t * env.attackCurve = [0, 0.2, 0.3, 0.4, 1]\n\t\t */\n\t Object.defineProperty(Tone.Envelope.prototype, 'attackCurve', {\n\t get: function () {\n\t if (Tone.isString(this._attackCurve)) {\n\t return this._attackCurve;\n\t } else if (Tone.isArray(this._attackCurve)) {\n\t //look up the name in the curves array\n\t for (var type in Tone.Envelope.Type) {\n\t if (Tone.Envelope.Type[type].In === this._attackCurve) {\n\t return type;\n\t }\n\t }\n\t //otherwise just return the array\n\t return this._attackCurve;\n\t }\n\t },\n\t set: function (curve) {\n\t //check if it's a valid type\n\t if (Tone.Envelope.Type.hasOwnProperty(curve)) {\n\t var curveDef = Tone.Envelope.Type[curve];\n\t if (Tone.isObject(curveDef)) {\n\t this._attackCurve = curveDef.In;\n\t } else {\n\t this._attackCurve = curveDef;\n\t }\n\t } else if (Tone.isArray(curve)) {\n\t this._attackCurve = curve;\n\t } else {\n\t throw new Error('Tone.Envelope: invalid curve: ' + curve);\n\t }\n\t }\n\t });\n\t /**\n\t\t * The shape of the release. See the attack curve types.\n\t\t * @memberOf Tone.Envelope#\n\t\t * @type {String|Array}\n\t\t * @name releaseCurve\n\t\t * @example\n\t\t * env.releaseCurve = \"linear\";\n\t\t */\n\t Object.defineProperty(Tone.Envelope.prototype, 'releaseCurve', {\n\t get: function () {\n\t if (Tone.isString(this._releaseCurve)) {\n\t return this._releaseCurve;\n\t } else if (Tone.isArray(this._releaseCurve)) {\n\t //look up the name in the curves array\n\t for (var type in Tone.Envelope.Type) {\n\t if (Tone.Envelope.Type[type].Out === this._releaseCurve) {\n\t return type;\n\t }\n\t }\n\t //otherwise just return the array\n\t return this._releaseCurve;\n\t }\n\t },\n\t set: function (curve) {\n\t //check if it's a valid type\n\t if (Tone.Envelope.Type.hasOwnProperty(curve)) {\n\t var curveDef = Tone.Envelope.Type[curve];\n\t if (Tone.isObject(curveDef)) {\n\t this._releaseCurve = curveDef.Out;\n\t } else {\n\t this._releaseCurve = curveDef;\n\t }\n\t } else if (Tone.isArray(curve)) {\n\t this._releaseCurve = curve;\n\t } else {\n\t throw new Error('Tone.Envelope: invalid curve: ' + curve);\n\t }\n\t }\n\t });\n\t /**\n\t\t * Trigger the attack/decay portion of the ADSR envelope.\n\t\t * @param {Time} [time=now] When the attack should start.\n\t\t * @param {NormalRange} [velocity=1] The velocity of the envelope scales the vales.\n\t\t * number between 0-1\n\t\t * @returns {Tone.Envelope} this\n\t\t * @example\n\t\t * //trigger the attack 0.5 seconds from now with a velocity of 0.2\n\t\t * env.triggerAttack(\"+0.5\", 0.2);\n\t\t */\n\t Tone.Envelope.prototype.triggerAttack = function (time, velocity) {\n\t time = this.toSeconds(time);\n\t var originalAttack = this.toSeconds(this.attack);\n\t var attack = originalAttack;\n\t var decay = this.toSeconds(this.decay);\n\t velocity = Tone.defaultArg(velocity, 1);\n\t //check if it's not a complete attack\n\t var currentValue = this.getValueAtTime(time);\n\t if (currentValue > 0) {\n\t //subtract the current value from the attack time\n\t var attackRate = 1 / attack;\n\t var remainingDistance = 1 - currentValue;\n\t //the attack is now the remaining time\n\t attack = remainingDistance / attackRate;\n\t }\n\t //attack\n\t if (this._attackCurve === 'linear') {\n\t this._sig.linearRampTo(velocity, attack, time);\n\t } else if (this._attackCurve === 'exponential') {\n\t this._sig.targetRampTo(velocity, attack, time);\n\t } else if (attack > 0) {\n\t this._sig.cancelAndHoldAtTime(time);\n\t var curve = this._attackCurve;\n\t //take only a portion of the curve\n\t if (attack < originalAttack) {\n\t var percentComplete = 1 - attack / originalAttack;\n\t var sliceIndex = Math.floor(percentComplete * this._attackCurve.length);\n\t curve = this._attackCurve.slice(sliceIndex);\n\t //the first index is the current value\n\t curve[0] = currentValue;\n\t }\n\t this._sig.setValueCurveAtTime(curve, time, attack, velocity);\n\t }\n\t //decay\n\t if (decay) {\n\t this._sig.targetRampTo(velocity * this.sustain, decay, attack + time);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Triggers the release of the envelope.\n\t\t * @param {Time} [time=now] When the release portion of the envelope should start.\n\t\t * @returns {Tone.Envelope} this\n\t\t * @example\n\t\t * //trigger release immediately\n\t\t * env.triggerRelease();\n\t\t */\n\t Tone.Envelope.prototype.triggerRelease = function (time) {\n\t time = this.toSeconds(time);\n\t var currentValue = this.getValueAtTime(time);\n\t if (currentValue > 0) {\n\t var release = this.toSeconds(this.release);\n\t if (this._releaseCurve === 'linear') {\n\t this._sig.linearRampTo(0, release, time);\n\t } else if (this._releaseCurve === 'exponential') {\n\t this._sig.targetRampTo(0, release, time);\n\t } else {\n\t var curve = this._releaseCurve;\n\t if (Tone.isArray(curve)) {\n\t this._sig.cancelAndHoldAtTime(time);\n\t this._sig.setValueCurveAtTime(curve, time, release, currentValue);\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Get the scheduled value at the given time. This will\n\t\t * return the unconverted (raw) value.\n\t\t * @param {Number} time The time in seconds.\n\t\t * @return {Number} The scheduled value at the given time.\n\t\t */\n\t Tone.Envelope.prototype.getValueAtTime = function (time) {\n\t return this._sig.getValueAtTime(time);\n\t };\n\t /**\n\t\t * triggerAttackRelease is shorthand for triggerAttack, then waiting\n\t\t * some duration, then triggerRelease.\n\t\t * @param {Time} duration The duration of the sustain.\n\t\t * @param {Time} [time=now] When the attack should be triggered.\n\t\t * @param {number} [velocity=1] The velocity of the envelope.\n\t\t * @returns {Tone.Envelope} this\n\t\t * @example\n\t\t * //trigger the attack and then the release after 0.6 seconds.\n\t\t * env.triggerAttackRelease(0.6);\n\t\t */\n\t Tone.Envelope.prototype.triggerAttackRelease = function (duration, time, velocity) {\n\t time = this.toSeconds(time);\n\t this.triggerAttack(time, velocity);\n\t this.triggerRelease(time + this.toSeconds(duration));\n\t return this;\n\t };\n\t /**\n\t\t * Cancels all scheduled envelope changes after the given time.\n\t\t * @param {Time} after\n\t\t * @returns {Tone.Envelope} this\n\t\t */\n\t Tone.Envelope.prototype.cancel = function (after) {\n\t this._sig.cancelScheduledValues(after);\n\t return this;\n\t };\n\t /**\n\t\t * Borrows the connect method from Tone.Signal.\n\t\t * @function\n\t\t * @private\n\t\t */\n\t Tone.Envelope.prototype.connect = Tone.SignalBase.prototype.connect;\n\t /**\n\t \t * Generate some complex envelope curves.\n\t \t */\n\t (function _createCurves() {\n\t var curveLen = 128;\n\t var i, k;\n\t //cosine curve\n\t var cosineCurve = [];\n\t for (i = 0; i < curveLen; i++) {\n\t cosineCurve[i] = Math.sin(i / (curveLen - 1) * (Math.PI / 2));\n\t }\n\t //ripple curve\n\t var rippleCurve = [];\n\t var rippleCurveFreq = 6.4;\n\t for (i = 0; i < curveLen - 1; i++) {\n\t k = i / (curveLen - 1);\n\t var sineWave = Math.sin(k * (Math.PI * 2) * rippleCurveFreq - Math.PI / 2) + 1;\n\t rippleCurve[i] = sineWave / 10 + k * 0.83;\n\t }\n\t rippleCurve[curveLen - 1] = 1;\n\t //stairs curve\n\t var stairsCurve = [];\n\t var steps = 5;\n\t for (i = 0; i < curveLen; i++) {\n\t stairsCurve[i] = Math.ceil(i / (curveLen - 1) * steps) / steps;\n\t }\n\t //in-out easing curve\n\t var sineCurve = [];\n\t for (i = 0; i < curveLen; i++) {\n\t k = i / (curveLen - 1);\n\t sineCurve[i] = 0.5 * (1 - Math.cos(Math.PI * k));\n\t }\n\t //a bounce curve\n\t var bounceCurve = [];\n\t for (i = 0; i < curveLen; i++) {\n\t k = i / (curveLen - 1);\n\t var freq = Math.pow(k, 3) * 4 + 0.2;\n\t var val = Math.cos(freq * Math.PI * 2 * k);\n\t bounceCurve[i] = Math.abs(val * (1 - k));\n\t }\n\t /**\n\t\t\t * Invert a value curve to make it work for the release\n\t\t\t * @private\n\t\t\t */\n\t function invertCurve(curve) {\n\t var out = new Array(curve.length);\n\t for (var j = 0; j < curve.length; j++) {\n\t out[j] = 1 - curve[j];\n\t }\n\t return out;\n\t }\n\t /**\n\t\t\t * reverse the curve\n\t\t\t * @private\n\t\t\t */\n\t function reverseCurve(curve) {\n\t return curve.slice(0).reverse();\n\t }\n\t /**\n\t\t\t * attack and release curve arrays\n\t\t\t * @type {Object}\n\t\t\t * @private\n\t\t\t */\n\t Tone.Envelope.Type = {\n\t 'linear': 'linear',\n\t 'exponential': 'exponential',\n\t 'bounce': {\n\t In: invertCurve(bounceCurve),\n\t Out: bounceCurve\n\t },\n\t 'cosine': {\n\t In: cosineCurve,\n\t Out: reverseCurve(cosineCurve)\n\t },\n\t 'step': {\n\t In: stairsCurve,\n\t Out: invertCurve(stairsCurve)\n\t },\n\t 'ripple': {\n\t In: rippleCurve,\n\t Out: invertCurve(rippleCurve)\n\t },\n\t 'sine': {\n\t In: sineCurve,\n\t Out: invertCurve(sineCurve)\n\t }\n\t };\n\t }());\n\t /**\n\t\t * Disconnect and dispose.\n\t\t * @returns {Tone.Envelope} this\n\t\t */\n\t Tone.Envelope.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._sig.dispose();\n\t this._sig = null;\n\t this._attackCurve = null;\n\t this._releaseCurve = null;\n\t return this;\n\t };\n\t return Tone.Envelope;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.AmplitudeEnvelope is a Tone.Envelope connected to a gain node.\n\t\t * Unlike Tone.Envelope, which outputs the envelope's value, Tone.AmplitudeEnvelope accepts\n\t\t * an audio signal as the input and will apply the envelope to the amplitude\n\t\t * of the signal. Read more about ADSR Envelopes on [Wikipedia](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Envelope}\n\t\t * @param {Time|Object} [attack] The amount of time it takes for the envelope to go from\n\t\t * 0 to it's maximum value.\n\t\t * @param {Time} [decay]\tThe period of time after the attack that it takes for the envelope\n\t\t * \tto fall to the sustain value.\n\t\t * @param {NormalRange} [sustain]\tThe percent of the maximum value that the envelope rests at until\n\t\t * \tthe release is triggered.\n\t\t * @param {Time} [release]\tThe amount of time after the release is triggered it takes to reach 0.\n\t\t * @example\n\t\t * var ampEnv = new Tone.AmplitudeEnvelope({\n\t\t * \t\"attack\": 0.1,\n\t\t * \t\"decay\": 0.2,\n\t\t * \t\"sustain\": 1.0,\n\t\t * \t\"release\": 0.8\n\t\t * }).toMaster();\n\t\t * //create an oscillator and connect it\n\t\t * var osc = new Tone.Oscillator().connect(ampEnv).start();\n\t\t * //trigger the envelopes attack and release \"8t\" apart\n\t\t * ampEnv.triggerAttackRelease(\"8t\");\n\t\t */\n\t Tone.AmplitudeEnvelope = function () {\n\t Tone.Envelope.apply(this, arguments);\n\t /**\n\t\t\t * the input node\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.input = this.output = new Tone.Gain();\n\t this._sig.connect(this.output.gain);\n\t };\n\t Tone.extend(Tone.AmplitudeEnvelope, Tone.Envelope);\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.AmplitudeEnvelope} this\n\t\t */\n\t Tone.AmplitudeEnvelope.prototype.dispose = function () {\n\t Tone.Envelope.prototype.dispose.call(this);\n\t return this;\n\t };\n\t return Tone.AmplitudeEnvelope;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * AnalyserNode.getFloatTimeDomainData polyfill\n\t\t * @private\n\t\t */\n\t if (Tone.supported) {\n\t if (!AnalyserNode.prototype.getFloatTimeDomainData) {\n\t //referenced https://github.com/mohayonao/get-float-time-domain-data\n\t AnalyserNode.prototype.getFloatTimeDomainData = function (array) {\n\t var uint8 = new Uint8Array(array.length);\n\t this.getByteTimeDomainData(uint8);\n\t for (var i = 0; i < uint8.length; i++) {\n\t array[i] = (uint8[i] - 128) / 128;\n\t }\n\t };\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Wrapper around the native Web Audio's\n\t\t * [AnalyserNode](http://webaudio.github.io/web-audio-api/#idl-def-AnalyserNode).\n\t\t * Extracts FFT or Waveform data from the incoming signal.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {String=} type The return type of the analysis, either \"fft\", or \"waveform\".\n\t\t * @param {Number=} size The size of the FFT. Value must be a power of\n\t\t * two in the range 32 to 32768.\n\t\t */\n\t Tone.Analyser = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'type',\n\t 'size'\n\t ], Tone.Analyser);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The analyser node.\n\t\t\t * @private\n\t\t\t * @type {AnalyserNode}\n\t\t\t */\n\t this._analyser = this.input = this.output = this.context.createAnalyser();\n\t /**\n\t\t\t * The analysis type\n\t\t\t * @type {String}\n\t\t\t * @private\n\t\t\t */\n\t this._type = options.type;\n\t /**\n\t\t\t * The buffer that the FFT data is written to\n\t\t\t * @type {TypedArray}\n\t\t\t * @private\n\t\t\t */\n\t this._buffer = null;\n\t //set the values initially\n\t this.size = options.size;\n\t this.type = options.type;\n\t };\n\t Tone.extend(Tone.Analyser, Tone.AudioNode);\n\t /**\n\t\t * The default values.\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Analyser.defaults = {\n\t 'size': 1024,\n\t 'type': 'fft',\n\t 'smoothing': 0.8\n\t };\n\t /**\n\t\t * Possible return types of analyser.getValue()\n\t\t * @enum {String}\n\t\t */\n\t Tone.Analyser.Type = {\n\t Waveform: 'waveform',\n\t FFT: 'fft'\n\t };\n\t /**\n\t\t * Run the analysis given the current settings and return the\n\t\t * result as a TypedArray.\n\t\t * @returns {TypedArray}\n\t\t */\n\t Tone.Analyser.prototype.getValue = function () {\n\t if (this._type === Tone.Analyser.Type.FFT) {\n\t this._analyser.getFloatFrequencyData(this._buffer);\n\t } else if (this._type === Tone.Analyser.Type.Waveform) {\n\t this._analyser.getFloatTimeDomainData(this._buffer);\n\t }\n\t return this._buffer;\n\t };\n\t /**\n\t\t * The size of analysis. This must be a power of two in the range 32 to 32768.\n\t\t * @memberOf Tone.Analyser#\n\t\t * @type {Number}\n\t\t * @name size\n\t\t */\n\t Object.defineProperty(Tone.Analyser.prototype, 'size', {\n\t get: function () {\n\t return this._analyser.frequencyBinCount;\n\t },\n\t set: function (size) {\n\t this._analyser.fftSize = size * 2;\n\t this._buffer = new Float32Array(size);\n\t }\n\t });\n\t /**\n\t\t * The analysis function returned by analyser.getValue(), either \"fft\" or \"waveform\".\n\t\t * @memberOf Tone.Analyser#\n\t\t * @type {String}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.Analyser.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t if (type !== Tone.Analyser.Type.Waveform && type !== Tone.Analyser.Type.FFT) {\n\t throw new TypeError('Tone.Analyser: invalid type: ' + type);\n\t }\n\t this._type = type;\n\t }\n\t });\n\t /**\n\t\t * 0 represents no time averaging with the last analysis frame.\n\t\t * @memberOf Tone.Analyser#\n\t\t * @type {NormalRange}\n\t\t * @name smoothing\n\t\t */\n\t Object.defineProperty(Tone.Analyser.prototype, 'smoothing', {\n\t get: function () {\n\t return this._analyser.smoothingTimeConstant;\n\t },\n\t set: function (val) {\n\t this._analyser.smoothingTimeConstant = val;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Analyser} this\n\t\t */\n\t Tone.Analyser.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._analyser.disconnect();\n\t this._analyser = null;\n\t this._buffer = null;\n\t };\n\t return Tone.Analyser;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Compressor is a thin wrapper around the Web Audio\n\t\t * [DynamicsCompressorNode](http://webaudio.github.io/web-audio-api/#the-dynamicscompressornode-interface).\n\t\t * Compression reduces the volume of loud sounds or amplifies quiet sounds\n\t\t * by narrowing or \"compressing\" an audio signal's dynamic range.\n\t\t * Read more on [Wikipedia](https://en.wikipedia.org/wiki/Dynamic_range_compression).\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {Decibels|Object} [threshold] The value above which the compression starts to be applied.\n\t\t * @param {Positive} [ratio] The gain reduction ratio.\n\t\t * @example\n\t\t * var comp = new Tone.Compressor(-30, 3);\n\t\t */\n\t Tone.Compressor = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'threshold',\n\t 'ratio'\n\t ], Tone.Compressor);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * the compressor node\n\t\t\t * @type {DynamicsCompressorNode}\n\t\t\t * @private\n\t\t\t */\n\t this._compressor = this.input = this.output = this.context.createDynamicsCompressor();\n\t /**\n\t\t\t * the threshold vaue\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.threshold = new Tone.Param({\n\t 'param': this._compressor.threshold,\n\t 'units': Tone.Type.Decibels,\n\t 'convert': false\n\t });\n\t /**\n\t\t\t * The attack parameter\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.attack = new Tone.Param(this._compressor.attack, Tone.Type.Time);\n\t /**\n\t\t\t * The release parameter\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.release = new Tone.Param(this._compressor.release, Tone.Type.Time);\n\t /**\n\t\t\t * The knee parameter\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.knee = new Tone.Param({\n\t 'param': this._compressor.knee,\n\t 'units': Tone.Type.Decibels,\n\t 'convert': false\n\t });\n\t /**\n\t\t\t * The ratio value\n\t\t\t * @type {Number}\n\t\t\t * @signal\n\t\t\t */\n\t this.ratio = new Tone.Param({\n\t 'param': this._compressor.ratio,\n\t 'convert': false\n\t });\n\t //set the defaults\n\t this._readOnly([\n\t 'knee',\n\t 'release',\n\t 'attack',\n\t 'ratio',\n\t 'threshold'\n\t ]);\n\t this.set(options);\n\t };\n\t Tone.extend(Tone.Compressor, Tone.AudioNode);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Compressor.defaults = {\n\t 'ratio': 12,\n\t 'threshold': -24,\n\t 'release': 0.25,\n\t 'attack': 0.003,\n\t 'knee': 30\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Compressor} this\n\t\t */\n\t Tone.Compressor.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'knee',\n\t 'release',\n\t 'attack',\n\t 'ratio',\n\t 'threshold'\n\t ]);\n\t this._compressor.disconnect();\n\t this._compressor = null;\n\t this.attack.dispose();\n\t this.attack = null;\n\t this.release.dispose();\n\t this.release = null;\n\t this.threshold.dispose();\n\t this.threshold = null;\n\t this.ratio.dispose();\n\t this.ratio = null;\n\t this.knee.dispose();\n\t this.knee = null;\n\t return this;\n\t };\n\t return Tone.Compressor;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Add a signal and a number or two signals. When no value is\n\t\t * passed into the constructor, Tone.Add will sum <code>input[0]</code>\n\t\t * and <code>input[1]</code>. If a value is passed into the constructor, \n\t\t * the it will be added to the input.\n\t\t * \n\t\t * @constructor\n\t\t * @extends {Tone.Signal}\n\t\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t\t * and second inputs. \n\t\t * @example\n\t\t * var signal = new Tone.Signal(2);\n\t\t * var add = new Tone.Add(2);\n\t\t * signal.connect(add);\n\t\t * //the output of add equals 4\n\t\t * @example\n\t\t * //if constructed with no arguments\n\t\t * //it will add the first and second inputs\n\t\t * var add = new Tone.Add();\n\t\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t\t * //the output of add equals 7. \n\t\t */\n\t Tone.Add = function (value) {\n\t Tone.Signal.call(this);\n\t this.createInsOuts(2, 0);\n\t /**\n\t\t\t * the summing node\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\t /**\n\t\t\t * @private\n\t\t\t * @type {Tone.Signal}\n\t\t\t */\n\t this._param = this.input[1] = new Tone.Signal(value);\n\t this._param.connect(this._sum);\n\t };\n\t Tone.extend(Tone.Add, Tone.Signal);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Add} this\n\t\t */\n\t Tone.Add.prototype.dispose = function () {\n\t Tone.Signal.prototype.dispose.call(this);\n\t this._sum.dispose();\n\t this._sum = null;\n\t return this;\n\t };\n\t return Tone.Add;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Multiply two incoming signals. Or, if a number is given in the constructor,\n\t\t * multiplies the incoming signal by that value.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Signal}\n\t\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t\t * it will return the product of the first and second inputs\n\t\t * @example\n\t\t * var mult = new Tone.Multiply();\n\t\t * var sigA = new Tone.Signal(3);\n\t\t * var sigB = new Tone.Signal(4);\n\t\t * sigA.connect(mult, 0, 0);\n\t\t * sigB.connect(mult, 0, 1);\n\t\t * //output of mult is 12.\n\t\t * @example\n\t\t * var mult = new Tone.Multiply(10);\n\t\t * var sig = new Tone.Signal(2).connect(mult);\n\t\t * //the output of mult is 20.\n\t\t */\n\t Tone.Multiply = function (value) {\n\t Tone.Signal.call(this);\n\t this.createInsOuts(2, 0);\n\t /**\n\t\t\t * the input node is the same as the output node\n\t\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t\t *\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this._mult = this.input[0] = this.output = new Tone.Gain();\n\t /**\n\t\t\t * the scaling parameter\n\t\t\t * @type {AudioParam}\n\t\t\t * @private\n\t\t\t */\n\t this._param = this.input[1] = this.output.gain;\n\t this.value = Tone.defaultArg(value, 0);\n\t };\n\t Tone.extend(Tone.Multiply, Tone.Signal);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Multiply} this\n\t\t */\n\t Tone.Multiply.prototype.dispose = function () {\n\t Tone.Signal.prototype.dispose.call(this);\n\t this._mult.dispose();\n\t this._mult = null;\n\t this._param = null;\n\t return this;\n\t };\n\t return Tone.Multiply;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.SignalBase}\n\t\t * @example\n\t\t * var neg = new Tone.Negate();\n\t\t * var sig = new Tone.Signal(-2).connect(neg);\n\t\t * //output of neg is positive 2. \n\t\t */\n\t Tone.Negate = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * negation is done by multiplying by -1\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t };\n\t Tone.extend(Tone.Negate, Tone.SignalBase);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Negate} this\n\t\t */\n\t Tone.Negate.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._multiply.dispose();\n\t this._multiply = null;\n\t return this;\n\t };\n\t return Tone.Negate;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Subtract the signal connected to <code>input[1]</code> from the signal connected \n\t\t * to <code>input[0]</code>. If an argument is provided in the constructor, the \n\t\t * signals <code>.value</code> will be subtracted from the incoming signal.\n\t\t *\n\t\t * @extends {Tone.Signal}\n\t\t * @constructor\n\t\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t\t * is omitted, it will subtract the second signal from the first.\n\t\t * @example\n\t\t * var sub = new Tone.Subtract(1);\n\t\t * var sig = new Tone.Signal(4).connect(sub);\n\t\t * //the output of sub is 3. \n\t\t * @example\n\t\t * var sub = new Tone.Subtract();\n\t\t * var sigA = new Tone.Signal(10);\n\t\t * var sigB = new Tone.Signal(2.5);\n\t\t * sigA.connect(sub, 0, 0);\n\t\t * sigB.connect(sub, 0, 1);\n\t\t * //output of sub is 7.5\n\t\t */\n\t Tone.Subtract = function (value) {\n\t Tone.Signal.call(this);\n\t this.createInsOuts(2, 0);\n\t /**\n\t\t\t * the summing node\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this._sum = this.input[0] = this.output = new Tone.Gain();\n\t /**\n\t\t\t * negate the input of the second input before connecting it\n\t\t\t * to the summing node.\n\t\t\t * @type {Tone.Negate}\n\t\t\t * @private\n\t\t\t */\n\t this._neg = new Tone.Negate();\n\t /**\n\t\t\t * the node where the value is set\n\t\t\t * @private\n\t\t\t * @type {Tone.Signal}\n\t\t\t */\n\t this._param = this.input[1] = new Tone.Signal(value);\n\t this._param.chain(this._neg, this._sum);\n\t };\n\t Tone.extend(Tone.Subtract, Tone.Signal);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.SignalBase} this\n\t\t */\n\t Tone.Subtract.prototype.dispose = function () {\n\t Tone.Signal.prototype.dispose.call(this);\n\t this._neg.dispose();\n\t this._neg = null;\n\t this._sum.disconnect();\n\t this._sum = null;\n\t return this;\n\t };\n\t return Tone.Subtract;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t\t *\n\t\t * @extends {Tone.SignalBase}\n\t\t * @constructor\n\t\t * @example\n\t\t * var eqPowGain = new Tone.EqualPowerGain();\n\t\t */\n\t Tone.EqualPowerGain = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * @type {Tone.WaveShaper}\n\t\t\t * @private\n\t\t\t */\n\t this._eqPower = this.input = this.output = new Tone.WaveShaper(function (val) {\n\t if (Math.abs(val) < 0.001) {\n\t //should output 0 when input is 0\n\t return 0;\n\t } else {\n\t return Tone.equalPowerScale(val);\n\t }\n\t }.bind(this), 4096);\n\t };\n\t Tone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.EqualPowerGain} this\n\t\t */\n\t Tone.EqualPowerGain.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._eqPower.dispose();\n\t this._eqPower = null;\n\t return this;\n\t };\n\t return Tone.EqualPowerGain;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Crossfade provides equal power fading between two inputs.\n\t\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {NormalRange} [initialFade=0.5]\n\t\t * @example\n\t\t * var crossFade = new Tone.CrossFade(0.5);\n\t\t * //connect effect A to crossfade from\n\t\t * //effect output 0 to crossfade input 0\n\t\t * effectA.connect(crossFade, 0, 0);\n\t\t * //connect effect B to crossfade from\n\t\t * //effect output 0 to crossfade input 1\n\t\t * effectB.connect(crossFade, 0, 1);\n\t\t * crossFade.fade.value = 0;\n\t\t * // ^ only effectA is output\n\t\t * crossFade.fade.value = 1;\n\t\t * // ^ only effectB is output\n\t\t * crossFade.fade.value = 0.5;\n\t\t * // ^ the two signals are mixed equally.\n\t\t */\n\t Tone.CrossFade = function (initialFade) {\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(2, 1);\n\t /**\n\t\t\t * Alias for <code>input[0]</code>.\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.a = this.input[0] = new Tone.Gain();\n\t /**\n\t\t\t * Alias for <code>input[1]</code>.\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.b = this.input[1] = new Tone.Gain();\n\t /**\n\t\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t\t * \twill output 100% <code>input[0]</code> and\n\t\t\t * \ta value of 1 will output 100% <code>input[1]</code>.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.fade = new Tone.Signal(Tone.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\t /**\n\t\t\t * equal power gain cross fade\n\t\t\t * @private\n\t\t\t * @type {Tone.EqualPowerGain}\n\t\t\t */\n\t this._equalPowerA = new Tone.EqualPowerGain();\n\t /**\n\t\t\t * equal power gain cross fade\n\t\t\t * @private\n\t\t\t * @type {Tone.EqualPowerGain}\n\t\t\t */\n\t this._equalPowerB = new Tone.EqualPowerGain();\n\t /**\n\t\t\t * invert the incoming signal\n\t\t\t * @private\n\t\t\t * @type {Tone}\n\t\t\t */\n\t this._one = this.context.getConstant(1);\n\t /**\n\t\t\t * invert the incoming signal\n\t\t\t * @private\n\t\t\t * @type {Tone.Subtract}\n\t\t\t */\n\t this._invert = new Tone.Subtract();\n\t //connections\n\t this.a.connect(this.output);\n\t this.b.connect(this.output);\n\t this.fade.chain(this._equalPowerB, this.b.gain);\n\t this._one.connect(this._invert, 0, 0);\n\t this.fade.connect(this._invert, 0, 1);\n\t this._invert.chain(this._equalPowerA, this.a.gain);\n\t this._readOnly('fade');\n\t };\n\t Tone.extend(Tone.CrossFade, Tone.AudioNode);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.CrossFade} this\n\t\t */\n\t Tone.CrossFade.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable('fade');\n\t this._equalPowerA.dispose();\n\t this._equalPowerA = null;\n\t this._equalPowerB.dispose();\n\t this._equalPowerB = null;\n\t this.fade.dispose();\n\t this.fade = null;\n\t this._invert.dispose();\n\t this._invert = null;\n\t this._one = null;\n\t this.a.dispose();\n\t this.a = null;\n\t this.b.dispose();\n\t this.b = null;\n\t return this;\n\t };\n\t return Tone.CrossFade;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Filter is a filter which allows for all of the same native methods\n\t\t * as the [BiquadFilterNode](http://webaudio.github.io/web-audio-api/#the-biquadfilternode-interface).\n\t\t * Tone.Filter has the added ability to set the filter rolloff at -12\n\t\t * (default), -24 and -48.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Frequency|Object} [frequency] The cutoff frequency of the filter.\n\t\t * @param {string=} type The type of filter.\n\t\t * @param {number=} rolloff The drop in decibels per octave after the cutoff frequency.\n\t\t * 3 choices: -12, -24, and -48\n\t\t * @example\n\t\t * var filter = new Tone.Filter(200, \"highpass\");\n\t\t */\n\t Tone.Filter = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type',\n\t 'rolloff'\n\t ], Tone.Filter);\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(1, 1);\n\t /**\n\t\t\t * the filter(s)\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._filters = [];\n\t /**\n\t\t\t * The cutoff frequency of the filter.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune parameter\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(0, Tone.Type.Cents);\n\t /**\n\t\t\t * The gain of the filter, only used in certain filter types\n\t\t\t * @type {Number}\n\t\t\t * @signal\n\t\t\t */\n\t this.gain = new Tone.Signal({\n\t 'value': options.gain,\n\t 'convert': false\n\t });\n\t /**\n\t\t\t * The Q or Quality of the filter\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this.Q = new Tone.Signal(options.Q);\n\t /**\n\t\t\t * the type of the filter\n\t\t\t * @type {string}\n\t\t\t * @private\n\t\t\t */\n\t this._type = options.type;\n\t /**\n\t\t\t * the rolloff value of the filter\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._rolloff = options.rolloff;\n\t //set the rolloff;\n\t this.rolloff = options.rolloff;\n\t this._readOnly([\n\t 'detune',\n\t 'frequency',\n\t 'gain',\n\t 'Q'\n\t ]);\n\t };\n\t Tone.extend(Tone.Filter, Tone.AudioNode);\n\t /**\n\t\t * the default parameters\n\t\t *\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Filter.defaults = {\n\t 'type': 'lowpass',\n\t 'frequency': 350,\n\t 'rolloff': -12,\n\t 'Q': 1,\n\t 'gain': 0\n\t };\n\t /**\n\t\t * The type of the filter. Types: \"lowpass\", \"highpass\",\n\t\t * \"bandpass\", \"lowshelf\", \"highshelf\", \"notch\", \"allpass\", or \"peaking\".\n\t\t * @memberOf Tone.Filter#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.Filter.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t var types = [\n\t 'lowpass',\n\t 'highpass',\n\t 'bandpass',\n\t 'lowshelf',\n\t 'highshelf',\n\t 'notch',\n\t 'allpass',\n\t 'peaking'\n\t ];\n\t if (types.indexOf(type) === -1) {\n\t throw new TypeError('Tone.Filter: invalid type ' + type);\n\t }\n\t this._type = type;\n\t for (var i = 0; i < this._filters.length; i++) {\n\t this._filters[i].type = type;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The rolloff of the filter which is the drop in db\n\t\t * per octave. Implemented internally by cascading filters.\n\t\t * Only accepts the values -12, -24, -48 and -96.\n\t\t * @memberOf Tone.Filter#\n\t\t * @type {number}\n\t\t * @name rolloff\n\t\t */\n\t Object.defineProperty(Tone.Filter.prototype, 'rolloff', {\n\t get: function () {\n\t return this._rolloff;\n\t },\n\t set: function (rolloff) {\n\t rolloff = parseInt(rolloff, 10);\n\t var possibilities = [\n\t -12,\n\t -24,\n\t -48,\n\t -96\n\t ];\n\t var cascadingCount = possibilities.indexOf(rolloff);\n\t //check the rolloff is valid\n\t if (cascadingCount === -1) {\n\t throw new RangeError('Tone.Filter: rolloff can only be -12, -24, -48 or -96');\n\t }\n\t cascadingCount += 1;\n\t this._rolloff = rolloff;\n\t //first disconnect the filters and throw them away\n\t this.input.disconnect();\n\t for (var i = 0; i < this._filters.length; i++) {\n\t this._filters[i].disconnect();\n\t this._filters[i] = null;\n\t }\n\t this._filters = new Array(cascadingCount);\n\t for (var count = 0; count < cascadingCount; count++) {\n\t var filter = this.context.createBiquadFilter();\n\t filter.type = this._type;\n\t this.frequency.connect(filter.frequency);\n\t this.detune.connect(filter.detune);\n\t this.Q.connect(filter.Q);\n\t this.gain.connect(filter.gain);\n\t this._filters[count] = filter;\n\t }\n\t //connect them up\n\t var connectionChain = [this.input].concat(this._filters).concat([this.output]);\n\t Tone.connectSeries.apply(Tone, connectionChain);\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Filter} this\n\t\t */\n\t Tone.Filter.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t for (var i = 0; i < this._filters.length; i++) {\n\t this._filters[i].disconnect();\n\t this._filters[i] = null;\n\t }\n\t this._filters = null;\n\t this._writable([\n\t 'detune',\n\t 'frequency',\n\t 'gain',\n\t 'Q'\n\t ]);\n\t this.frequency.dispose();\n\t this.Q.dispose();\n\t this.frequency = null;\n\t this.Q = null;\n\t this.detune.dispose();\n\t this.detune = null;\n\t this.gain.dispose();\n\t this.gain = null;\n\t return this;\n\t };\n\t return Tone.Filter;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Split the incoming signal into three bands (low, mid, high)\n\t\t * with two crossover frequency controls.\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {Frequency|Object} [lowFrequency] the low/mid crossover frequency\n\t\t * @param {Frequency} [highFrequency] the mid/high crossover frequency\n\t\t */\n\t Tone.MultibandSplit = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'lowFrequency',\n\t 'highFrequency'\n\t ], Tone.MultibandSplit);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * the input\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this.input = new Tone.Gain();\n\t /**\n\t\t\t * the outputs\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this.output = new Array(3);\n\t /**\n\t\t\t * The low band. Alias for <code>output[0]</code>\n\t\t\t * @type {Tone.Filter}\n\t\t\t */\n\t this.low = this.output[0] = new Tone.Filter(0, 'lowpass');\n\t /**\n\t\t\t * the lower filter of the mid band\n\t\t\t * @type {Tone.Filter}\n\t\t\t * @private\n\t\t\t */\n\t this._lowMidFilter = new Tone.Filter(0, 'highpass');\n\t /**\n\t\t\t * The mid band output. Alias for <code>output[1]</code>\n\t\t\t * @type {Tone.Filter}\n\t\t\t */\n\t this.mid = this.output[1] = new Tone.Filter(0, 'lowpass');\n\t /**\n\t\t\t * The high band output. Alias for <code>output[2]</code>\n\t\t\t * @type {Tone.Filter}\n\t\t\t */\n\t this.high = this.output[2] = new Tone.Filter(0, 'highpass');\n\t /**\n\t\t\t * The low/mid crossover frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.lowFrequency = new Tone.Signal(options.lowFrequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The mid/high crossover frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.highFrequency = new Tone.Signal(options.highFrequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The quality of all the filters\n\t\t\t * @type {Number}\n\t\t\t * @signal\n\t\t\t */\n\t this.Q = new Tone.Signal(options.Q);\n\t this.input.fan(this.low, this.high);\n\t this.input.chain(this._lowMidFilter, this.mid);\n\t //the frequency control signal\n\t this.lowFrequency.connect(this.low.frequency);\n\t this.lowFrequency.connect(this._lowMidFilter.frequency);\n\t this.highFrequency.connect(this.mid.frequency);\n\t this.highFrequency.connect(this.high.frequency);\n\t //the Q value\n\t this.Q.connect(this.low.Q);\n\t this.Q.connect(this._lowMidFilter.Q);\n\t this.Q.connect(this.mid.Q);\n\t this.Q.connect(this.high.Q);\n\t this._readOnly([\n\t 'high',\n\t 'mid',\n\t 'low',\n\t 'highFrequency',\n\t 'lowFrequency'\n\t ]);\n\t };\n\t Tone.extend(Tone.MultibandSplit, Tone.AudioNode);\n\t /**\n\t\t * @private\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.MultibandSplit.defaults = {\n\t 'lowFrequency': 400,\n\t 'highFrequency': 2500,\n\t 'Q': 1\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.MultibandSplit} this\n\t\t */\n\t Tone.MultibandSplit.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'high',\n\t 'mid',\n\t 'low',\n\t 'highFrequency',\n\t 'lowFrequency'\n\t ]);\n\t this.low.dispose();\n\t this.low = null;\n\t this._lowMidFilter.dispose();\n\t this._lowMidFilter = null;\n\t this.mid.dispose();\n\t this.mid = null;\n\t this.high.dispose();\n\t this.high = null;\n\t this.lowFrequency.dispose();\n\t this.lowFrequency = null;\n\t this.highFrequency.dispose();\n\t this.highFrequency = null;\n\t this.Q.dispose();\n\t this.Q = null;\n\t return this;\n\t };\n\t return Tone.MultibandSplit;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.EQ3 is a three band EQ with control over low, mid, and high gain as\n\t\t * well as the low and high crossover frequencies.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t *\n\t\t * @param {Decibels|Object} [lowLevel] The gain applied to the lows.\n\t\t * @param {Decibels} [midLevel] The gain applied to the mid.\n\t\t * @param {Decibels} [highLevel] The gain applied to the high.\n\t\t * @example\n\t\t * var eq = new Tone.EQ3(-10, 3, -20);\n\t\t */\n\t Tone.EQ3 = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'low',\n\t 'mid',\n\t 'high'\n\t ], Tone.EQ3);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * the output node\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.output = new Tone.Gain();\n\t /**\n\t\t\t * the multiband split\n\t\t\t * @type {Tone.MultibandSplit}\n\t\t\t * @private\n\t\t\t */\n\t this._multibandSplit = this.input = new Tone.MultibandSplit({\n\t 'lowFrequency': options.lowFrequency,\n\t 'highFrequency': options.highFrequency\n\t });\n\t /**\n\t\t\t * The gain for the lower signals\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._lowGain = new Tone.Gain(options.low, Tone.Type.Decibels);\n\t /**\n\t\t\t * The gain for the mid signals\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._midGain = new Tone.Gain(options.mid, Tone.Type.Decibels);\n\t /**\n\t\t\t * The gain in decibels of the high part\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._highGain = new Tone.Gain(options.high, Tone.Type.Decibels);\n\t /**\n\t\t\t * The gain in decibels of the low part\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.low = this._lowGain.gain;\n\t /**\n\t\t\t * The gain in decibels of the mid part\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.mid = this._midGain.gain;\n\t /**\n\t\t\t * The gain in decibels of the high part\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.high = this._highGain.gain;\n\t /**\n\t\t\t * The Q value for all of the filters.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this.Q = this._multibandSplit.Q;\n\t /**\n\t\t\t * The low/mid crossover frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.lowFrequency = this._multibandSplit.lowFrequency;\n\t /**\n\t\t\t * The mid/high crossover frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.highFrequency = this._multibandSplit.highFrequency;\n\t //the frequency bands\n\t this._multibandSplit.low.chain(this._lowGain, this.output);\n\t this._multibandSplit.mid.chain(this._midGain, this.output);\n\t this._multibandSplit.high.chain(this._highGain, this.output);\n\t this._readOnly([\n\t 'low',\n\t 'mid',\n\t 'high',\n\t 'lowFrequency',\n\t 'highFrequency'\n\t ]);\n\t };\n\t Tone.extend(Tone.EQ3, Tone.AudioNode);\n\t /**\n\t\t * the default values\n\t\t */\n\t Tone.EQ3.defaults = {\n\t 'low': 0,\n\t 'mid': 0,\n\t 'high': 0,\n\t 'lowFrequency': 400,\n\t 'highFrequency': 2500\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.EQ3} this\n\t\t */\n\t Tone.EQ3.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'low',\n\t 'mid',\n\t 'high',\n\t 'lowFrequency',\n\t 'highFrequency'\n\t ]);\n\t this._multibandSplit.dispose();\n\t this._multibandSplit = null;\n\t this.lowFrequency = null;\n\t this.highFrequency = null;\n\t this._lowGain.dispose();\n\t this._lowGain = null;\n\t this._midGain.dispose();\n\t this._midGain = null;\n\t this._highGain.dispose();\n\t this._highGain = null;\n\t this.low = null;\n\t this.mid = null;\n\t this.high = null;\n\t this.Q = null;\n\t return this;\n\t };\n\t return Tone.EQ3;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Performs a linear scaling on an input signal.\n\t\t * Scales a NormalRange input to between\n\t\t * outputMin and outputMax.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.SignalBase}\n\t\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t\t * @example\n\t\t * var scale = new Tone.Scale(50, 100);\n\t\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t\t * //the output of scale equals 75\n\t\t */\n\t Tone.Scale = function (outputMin, outputMax) {\n\t Tone.SignalBase.call(this);\n\t /** \n\t\t\t * @private\n\t\t\t * @type {number}\n\t\t\t */\n\t this._outputMin = Tone.defaultArg(outputMin, 0);\n\t /** \n\t\t\t * @private\n\t\t\t * @type {number}\n\t\t\t */\n\t this._outputMax = Tone.defaultArg(outputMax, 1);\n\t /** \n\t\t\t * @private\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._scale = this.input = new Tone.Multiply(1);\n\t /** \n\t\t\t * @private\n\t\t\t * @type {Tone.Add}\n\t\t\t * @private\n\t\t\t */\n\t this._add = this.output = new Tone.Add(0);\n\t this._scale.connect(this._add);\n\t this._setRange();\n\t };\n\t Tone.extend(Tone.Scale, Tone.SignalBase);\n\t /**\n\t\t * The minimum output value. This number is output when \n\t\t * the value input value is 0. \n\t\t * @memberOf Tone.Scale#\n\t\t * @type {number}\n\t\t * @name min\n\t\t */\n\t Object.defineProperty(Tone.Scale.prototype, 'min', {\n\t get: function () {\n\t return this._outputMin;\n\t },\n\t set: function (min) {\n\t this._outputMin = min;\n\t this._setRange();\n\t }\n\t });\n\t /**\n\t\t * The maximum output value. This number is output when \n\t\t * the value input value is 1. \n\t\t * @memberOf Tone.Scale#\n\t\t * @type {number}\n\t\t * @name max\n\t\t */\n\t Object.defineProperty(Tone.Scale.prototype, 'max', {\n\t get: function () {\n\t return this._outputMax;\n\t },\n\t set: function (max) {\n\t this._outputMax = max;\n\t this._setRange();\n\t }\n\t });\n\t /**\n\t\t * set the values\n\t\t * @private\n\t\t */\n\t Tone.Scale.prototype._setRange = function () {\n\t this._add.value = this._outputMin;\n\t this._scale.value = this._outputMax - this._outputMin;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Scale} this\n\t\t */\n\t Tone.Scale.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._add.dispose();\n\t this._add = null;\n\t this._scale.dispose();\n\t this._scale = null;\n\t return this;\n\t };\n\t return Tone.Scale;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Performs an exponential scaling on an input signal.\n\t\t * Scales a NormalRange value [0,1] exponentially\n\t\t * to the output range of outputMin to outputMax.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.SignalBase}\n\t\t * @param {number} [outputMin=0] The output value when the input is 0.\n\t\t * @param {number} [outputMax=1]\tThe output value when the input is 1.\n\t\t * @param {number} [exponent=2] The exponent which scales the incoming signal.\n\t\t * @example\n\t\t * var scaleExp = new Tone.ScaleExp(0, 100, 2);\n\t\t * var signal = new Tone.Signal(0.5).connect(scaleExp);\n\t\t */\n\t Tone.ScaleExp = function (outputMin, outputMax, exponent) {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * scale the input to the output range\n\t\t\t * @type {Tone.Scale}\n\t\t\t * @private\n\t\t\t */\n\t this._scale = this.output = new Tone.Scale(outputMin, outputMax);\n\t /**\n\t\t\t * @private\n\t\t\t * @type {Tone.Pow}\n\t\t\t * @private\n\t\t\t */\n\t this._exp = this.input = new Tone.Pow(Tone.defaultArg(exponent, 2));\n\t this._exp.connect(this._scale);\n\t };\n\t Tone.extend(Tone.ScaleExp, Tone.SignalBase);\n\t /**\n\t\t * Instead of interpolating linearly between the <code>min</code> and\n\t\t * <code>max</code> values, setting the exponent will interpolate between\n\t\t * the two values with an exponential curve.\n\t\t * @memberOf Tone.ScaleExp#\n\t\t * @type {number}\n\t\t * @name exponent\n\t\t */\n\t Object.defineProperty(Tone.ScaleExp.prototype, 'exponent', {\n\t get: function () {\n\t return this._exp.value;\n\t },\n\t set: function (exp) {\n\t this._exp.value = exp;\n\t }\n\t });\n\t /**\n\t\t * The minimum output value. This number is output when\n\t\t * the value input value is 0.\n\t\t * @memberOf Tone.ScaleExp#\n\t\t * @type {number}\n\t\t * @name min\n\t\t */\n\t Object.defineProperty(Tone.ScaleExp.prototype, 'min', {\n\t get: function () {\n\t return this._scale.min;\n\t },\n\t set: function (min) {\n\t this._scale.min = min;\n\t }\n\t });\n\t /**\n\t\t * The maximum output value. This number is output when\n\t\t * the value input value is 1.\n\t\t * @memberOf Tone.ScaleExp#\n\t\t * @type {number}\n\t\t * @name max\n\t\t */\n\t Object.defineProperty(Tone.ScaleExp.prototype, 'max', {\n\t get: function () {\n\t return this._scale.max;\n\t },\n\t set: function (max) {\n\t this._scale.max = max;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.ScaleExp} this\n\t\t */\n\t Tone.ScaleExp.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._scale.dispose();\n\t this._scale = null;\n\t this._exp.dispose();\n\t this._exp = null;\n\t return this;\n\t };\n\t return Tone.ScaleExp;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Wrapper around Web Audio's native [DelayNode](http://webaudio.github.io/web-audio-api/#the-delaynode-interface).\n\t\t * @extends {Tone}\n\t\t * @param {Time=} delayTime The delay applied to the incoming signal.\n\t\t * @param {Time=} maxDelay The maximum delay time.\n\t\t */\n\t Tone.Delay = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'delayTime',\n\t 'maxDelay'\n\t ], Tone.Delay);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The maximum delay time initialized with the node\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._maxDelay = Math.max(this.toSeconds(options.maxDelay), this.toSeconds(options.delayTime));\n\t /**\n\t\t\t * The native delay node\n\t\t\t * @type {DelayNode}\n\t\t\t * @private\n\t\t\t */\n\t this._delayNode = this.input = this.output = this.context.createDelay(this._maxDelay);\n\t /**\n\t\t\t * The amount of time the incoming signal is\n\t\t\t * delayed.\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.delayTime = new Tone.Param({\n\t 'param': this._delayNode.delayTime,\n\t 'units': Tone.Type.Time,\n\t 'value': options.delayTime\n\t });\n\t this._readOnly('delayTime');\n\t };\n\t Tone.extend(Tone.Delay, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Delay.defaults = {\n\t 'maxDelay': 1,\n\t 'delayTime': 0\n\t };\n\t /**\n\t\t * The maximum delay time. This cannot be changed. The value is passed into the constructor.\n\t\t * @memberof Tone.Delay#\n\t\t * @type {Time}\n\t\t * @name maxDelay\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Delay.prototype, 'maxDelay', {\n\t get: function () {\n\t return this._maxDelay;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Delay} this\n\t\t */\n\t Tone.Delay.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._delayNode.disconnect();\n\t this._delayNode = null;\n\t this._writable('delayTime');\n\t this.delayTime = null;\n\t return this;\n\t };\n\t return Tone.Delay;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Comb filters are basic building blocks for physical modeling. Read more\n\t\t * about comb filters on [CCRMA's website](https://ccrma.stanford.edu/~jos/pasp/Feedback_Comb_Filters.html).\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {Time|Object} [delayTime] The delay time of the filter.\n\t\t * @param {NormalRange=} resonance The amount of feedback the filter has.\n\t\t */\n\t Tone.FeedbackCombFilter = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'delayTime',\n\t 'resonance'\n\t ], Tone.FeedbackCombFilter);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * the delay node\n\t\t\t * @type {DelayNode}\n\t\t\t * @private\n\t\t\t */\n\t this._delay = this.input = this.output = new Tone.Delay(options.delayTime);\n\t /**\n\t\t\t * The amount of delay of the comb filter.\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.delayTime = this._delay.delayTime;\n\t /**\n\t\t\t * the feedback node\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this._feedback = new Tone.Gain(options.resonance, Tone.Type.NormalRange);\n\t /**\n\t\t\t * The amount of feedback of the delayed signal.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.resonance = this._feedback.gain;\n\t this._delay.chain(this._feedback, this._delay);\n\t this._readOnly([\n\t 'resonance',\n\t 'delayTime'\n\t ]);\n\t };\n\t Tone.extend(Tone.FeedbackCombFilter, Tone.AudioNode);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.FeedbackCombFilter.defaults = {\n\t 'delayTime': 0.1,\n\t 'resonance': 0.5\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.FeedbackCombFilter} this\n\t\t */\n\t Tone.FeedbackCombFilter.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'resonance',\n\t 'delayTime'\n\t ]);\n\t this._delay.dispose();\n\t this._delay = null;\n\t this.delayTime = null;\n\t this._feedback.dispose();\n\t this._feedback = null;\n\t this.resonance = null;\n\t return this;\n\t };\n\t return Tone.FeedbackCombFilter;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Get the current waveform data of the connected audio source.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Number=} size The size of the FFT. Value must be a power of\n\t\t * two in the range 32 to 32768.\n\t\t */\n\t Tone.FFT = function () {\n\t var options = Tone.defaults(arguments, ['size'], Tone.FFT);\n\t options.type = Tone.Analyser.Type.FFT;\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The analyser node.\n\t\t\t * @private\n\t\t\t * @type {Tone.Analyser}\n\t\t\t */\n\t this._analyser = this.input = this.output = new Tone.Analyser(options);\n\t };\n\t Tone.extend(Tone.FFT, Tone.AudioNode);\n\t /**\n\t\t * The default values.\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.FFT.defaults = { 'size': 1024 };\n\t /**\n\t\t * Gets the waveform of the audio source. Returns the waveform data\n\t\t * of length [size](#size) as a Float32Array with values between -1 and 1.\n\t\t * @returns {TypedArray}\n\t\t */\n\t Tone.FFT.prototype.getValue = function () {\n\t return this._analyser.getValue();\n\t };\n\t /**\n\t\t * The size of analysis. This must be a power of two in the range 32 to 32768.\n\t\t * @memberOf Tone.FFT#\n\t\t * @type {Number}\n\t\t * @name size\n\t\t */\n\t Object.defineProperty(Tone.FFT.prototype, 'size', {\n\t get: function () {\n\t return this._analyser.size;\n\t },\n\t set: function (size) {\n\t this._analyser.size = size;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.FFT} this\n\t\t */\n\t Tone.FFT.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._analyser.dispose();\n\t this._analyser = null;\n\t };\n\t return Tone.FFT;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Return the absolute value of an incoming signal.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.SignalBase}\n\t\t * @example\n\t\t * var signal = new Tone.Signal(-1);\n\t\t * var abs = new Tone.Abs();\n\t\t * signal.connect(abs);\n\t\t * //the output of abs is 1.\n\t\t */\n\t Tone.Abs = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * @type {Tone.LessThan}\n\t\t\t * @private\n\t\t\t */\n\t this._abs = this.input = this.output = new Tone.WaveShaper(function (val) {\n\t if (Math.abs(val) < 0.001) {\n\t return 0;\n\t } else {\n\t return Math.abs(val);\n\t }\n\t }, 1024);\n\t };\n\t Tone.extend(Tone.Abs, Tone.SignalBase);\n\t /**\n\t\t * dispose method\n\t\t * @returns {Tone.Abs} this\n\t\t */\n\t Tone.Abs.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._abs.dispose();\n\t this._abs = null;\n\t return this;\n\t };\n\t return Tone.Abs;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Follower is a crude envelope follower which will follow\n\t\t * the amplitude of an incoming signal.\n\t\t * Take care with small (< 0.02) attack or decay values\n\t\t * as follower has some ripple which is exaggerated\n\t\t * at these values. Read more about envelope followers (also known\n\t\t * as envelope detectors) on [Wikipedia](https://en.wikipedia.org/wiki/Envelope_detector).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Time|Object} [attack] The rate at which the follower rises.\n\t\t * @param {Time=} release The rate at which the folower falls.\n\t\t * @example\n\t\t * var follower = new Tone.Follower(0.2, 0.4);\n\t\t */\n\t Tone.Follower = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'attack',\n\t 'release'\n\t ], Tone.Follower);\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(1, 1);\n\t /**\n\t\t\t * @type {Tone.Abs}\n\t\t\t * @private\n\t\t\t */\n\t this._abs = new Tone.Abs();\n\t /**\n\t\t\t * the lowpass filter which smooths the input\n\t\t\t * @type {BiquadFilterNode}\n\t\t\t * @private\n\t\t\t */\n\t this._filter = this.context.createBiquadFilter();\n\t this._filter.type = 'lowpass';\n\t this._filter.frequency.value = 0;\n\t this._filter.Q.value = -100;\n\t /**\n\t\t\t * @type {WaveShaperNode}\n\t\t\t * @private\n\t\t\t */\n\t this._frequencyValues = new Tone.WaveShaper();\n\t /**\n\t\t\t * @type {Tone.Subtract}\n\t\t\t * @private\n\t\t\t */\n\t this._sub = new Tone.Subtract();\n\t /**\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._delay = new Tone.Delay(this.blockTime);\n\t /**\n\t\t\t * this keeps it far from 0, even for very small differences\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._mult = new Tone.Multiply(10000);\n\t /**\n\t\t\t * @private\n\t\t\t * @type {number}\n\t\t\t */\n\t this._attack = options.attack;\n\t /**\n\t\t\t * @private\n\t\t\t * @type {number}\n\t\t\t */\n\t this._release = options.release;\n\t //the smoothed signal to get the values\n\t this.input.chain(this._abs, this._filter, this.output);\n\t //the difference path\n\t this._abs.connect(this._sub, 0, 1);\n\t this._filter.chain(this._delay, this._sub);\n\t //threshold the difference and use the thresh to set the frequency\n\t this._sub.chain(this._mult, this._frequencyValues, this._filter.frequency);\n\t //set the attack and release values in the table\n\t this._setAttackRelease(this._attack, this._release);\n\t };\n\t Tone.extend(Tone.Follower, Tone.AudioNode);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Follower.defaults = {\n\t 'attack': 0.05,\n\t 'release': 0.5\n\t };\n\t /**\n\t\t * sets the attack and release times in the wave shaper\n\t\t * @param {Time} attack\n\t\t * @param {Time} release\n\t\t * @private\n\t\t */\n\t Tone.Follower.prototype._setAttackRelease = function (attack, release) {\n\t var minTime = this.blockTime;\n\t attack = Tone.Time(attack).toFrequency();\n\t release = Tone.Time(release).toFrequency();\n\t attack = Math.max(attack, minTime);\n\t release = Math.max(release, minTime);\n\t this._frequencyValues.setMap(function (val) {\n\t if (val <= 0) {\n\t return attack;\n\t } else {\n\t return release;\n\t }\n\t });\n\t };\n\t /**\n\t\t * The attack time.\n\t\t * @memberOf Tone.Follower#\n\t\t * @type {Time}\n\t\t * @name attack\n\t\t */\n\t Object.defineProperty(Tone.Follower.prototype, 'attack', {\n\t get: function () {\n\t return this._attack;\n\t },\n\t set: function (attack) {\n\t this._attack = attack;\n\t this._setAttackRelease(this._attack, this._release);\n\t }\n\t });\n\t /**\n\t\t * The release time.\n\t\t * @memberOf Tone.Follower#\n\t\t * @type {Time}\n\t\t * @name release\n\t\t */\n\t Object.defineProperty(Tone.Follower.prototype, 'release', {\n\t get: function () {\n\t return this._release;\n\t },\n\t set: function (release) {\n\t this._release = release;\n\t this._setAttackRelease(this._attack, this._release);\n\t }\n\t });\n\t /**\n\t\t * Borrows the connect method from Signal so that the output can be used\n\t\t * as a Tone.Signal control signal.\n\t\t * @function\n\t\t */\n\t Tone.Follower.prototype.connect = Tone.SignalBase.prototype.connect;\n\t /**\n\t\t * dispose\n\t\t * @returns {Tone.Follower} this\n\t\t */\n\t Tone.Follower.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._filter.disconnect();\n\t this._filter = null;\n\t this._frequencyValues.disconnect();\n\t this._frequencyValues = null;\n\t this._delay.dispose();\n\t this._delay = null;\n\t this._sub.disconnect();\n\t this._sub = null;\n\t this._abs.dispose();\n\t this._abs = null;\n\t this._mult.dispose();\n\t this._mult = null;\n\t this._curve = null;\n\t return this;\n\t };\n\t return Tone.Follower;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.ScaledEnvelop is an envelope which can be scaled\n\t\t * to any range. It's useful for applying an envelope\n\t\t * to a frequency or any other non-NormalRange signal\n\t\t * parameter.\n\t\t *\n\t\t * @extends {Tone.Envelope}\n\t\t * @constructor\n\t\t * @param {Time|Object} [attack]\tthe attack time in seconds\n\t\t * @param {Time} [decay]\tthe decay time in seconds\n\t\t * @param {number} [sustain] \ta percentage (0-1) of the full amplitude\n\t\t * @param {Time} [release]\tthe release time in seconds\n\t\t * @example\n\t\t * var scaledEnv = new Tone.ScaledEnvelope({\n\t\t * \t\"attack\" : 0.2,\n\t\t * \t\"min\" : 200,\n\t\t * \t\"max\" : 2000\n\t\t * });\n\t\t * scaledEnv.connect(oscillator.frequency);\n\t\t */\n\t Tone.ScaledEnvelope = function () {\n\t //get all of the defaults\n\t var options = Tone.defaults(arguments, [\n\t 'attack',\n\t 'decay',\n\t 'sustain',\n\t 'release'\n\t ], Tone.Envelope);\n\t Tone.Envelope.call(this, options);\n\t options = Tone.defaultArg(options, Tone.ScaledEnvelope.defaults);\n\t /**\n\t\t\t * scale the incoming signal by an exponent\n\t\t\t * @type {Tone.Pow}\n\t\t\t * @private\n\t\t\t */\n\t this._exp = this.output = new Tone.Pow(options.exponent);\n\t /**\n\t\t\t * scale the signal to the desired range\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._scale = this.output = new Tone.Scale(options.min, options.max);\n\t this._sig.chain(this._exp, this._scale);\n\t };\n\t Tone.extend(Tone.ScaledEnvelope, Tone.Envelope);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t */\n\t Tone.ScaledEnvelope.defaults = {\n\t 'min': 0,\n\t 'max': 1,\n\t 'exponent': 1\n\t };\n\t /**\n\t\t * The envelope's min output value. This is the value which it\n\t\t * starts at.\n\t\t * @memberOf Tone.ScaledEnvelope#\n\t\t * @type {number}\n\t\t * @name min\n\t\t */\n\t Object.defineProperty(Tone.ScaledEnvelope.prototype, 'min', {\n\t get: function () {\n\t return this._scale.min;\n\t },\n\t set: function (min) {\n\t this._scale.min = min;\n\t }\n\t });\n\t /**\n\t\t * The envelope's max output value. In other words, the value\n\t\t * at the peak of the attack portion of the envelope.\n\t\t * @memberOf Tone.ScaledEnvelope#\n\t\t * @type {number}\n\t\t * @name max\n\t\t */\n\t Object.defineProperty(Tone.ScaledEnvelope.prototype, 'max', {\n\t get: function () {\n\t return this._scale.max;\n\t },\n\t set: function (max) {\n\t this._scale.max = max;\n\t }\n\t });\n\t /**\n\t\t * The envelope's exponent value.\n\t\t * @memberOf Tone.ScaledEnvelope#\n\t\t * @type {number}\n\t\t * @name exponent\n\t\t */\n\t Object.defineProperty(Tone.ScaledEnvelope.prototype, 'exponent', {\n\t get: function () {\n\t return this._exp.value;\n\t },\n\t set: function (exp) {\n\t this._exp.value = exp;\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.ScaledEnvelope} this\n\t\t */\n\t Tone.ScaledEnvelope.prototype.dispose = function () {\n\t Tone.Envelope.prototype.dispose.call(this);\n\t this._scale.dispose();\n\t this._scale = null;\n\t this._exp.dispose();\n\t this._exp = null;\n\t return this;\n\t };\n\t return Tone.ScaledEnvelope;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.FrequencyEnvelope is a Tone.ScaledEnvelope, but instead of `min` and `max`\n\t\t * it's got a `baseFrequency` and `octaves` parameter.\n\t\t *\n\t\t * @extends {Tone.Envelope}\n\t\t * @constructor\n\t\t * @param {Time|Object} [attack]\tthe attack time in seconds\n\t\t * @param {Time} [decay]\tthe decay time in seconds\n\t\t * @param {number} [sustain] \ta percentage (0-1) of the full amplitude\n\t\t * @param {Time} [release]\tthe release time in seconds\n\t\t * @example\n\t\t * var freqEnv = new Tone.FrequencyEnvelope({\n\t\t * \t\"attack\" : 0.2,\n\t\t * \t\"baseFrequency\" : \"C2\",\n\t\t * \t\"octaves\" : 4\n\t\t * });\n\t\t * freqEnv.connect(oscillator.frequency);\n\t\t */\n\t Tone.FrequencyEnvelope = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'attack',\n\t 'decay',\n\t 'sustain',\n\t 'release'\n\t ], Tone.Envelope);\n\t Tone.ScaledEnvelope.call(this, options);\n\t //merge it with the frequency envelope defaults\n\t options = Tone.defaultArg(options, Tone.FrequencyEnvelope.defaults);\n\t /**\n\t\t\t * Stores the octave value\n\t\t\t * @type {Positive}\n\t\t\t * @private\n\t\t\t */\n\t this._octaves = options.octaves;\n\t //setup\n\t this.baseFrequency = options.baseFrequency;\n\t this.octaves = options.octaves;\n\t };\n\t Tone.extend(Tone.FrequencyEnvelope, Tone.Envelope);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t */\n\t Tone.FrequencyEnvelope.defaults = {\n\t 'baseFrequency': 200,\n\t 'octaves': 4,\n\t 'exponent': 2\n\t };\n\t /**\n\t\t * The envelope's mininum output value. This is the value which it\n\t\t * starts at.\n\t\t * @memberOf Tone.FrequencyEnvelope#\n\t\t * @type {Frequency}\n\t\t * @name baseFrequency\n\t\t */\n\t Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'baseFrequency', {\n\t get: function () {\n\t return this._scale.min;\n\t },\n\t set: function (min) {\n\t this._scale.min = this.toFrequency(min);\n\t //also update the octaves\n\t this.octaves = this._octaves;\n\t }\n\t });\n\t /**\n\t\t * The number of octaves above the baseFrequency that the\n\t\t * envelope will scale to.\n\t\t * @memberOf Tone.FrequencyEnvelope#\n\t\t * @type {Positive}\n\t\t * @name octaves\n\t\t */\n\t Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'octaves', {\n\t get: function () {\n\t return this._octaves;\n\t },\n\t set: function (octaves) {\n\t this._octaves = octaves;\n\t this._scale.max = this.baseFrequency * Math.pow(2, octaves);\n\t }\n\t });\n\t /**\n\t\t * The envelope's exponent value.\n\t\t * @memberOf Tone.FrequencyEnvelope#\n\t\t * @type {number}\n\t\t * @name exponent\n\t\t */\n\t Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'exponent', {\n\t get: function () {\n\t return this._exp.value;\n\t },\n\t set: function (exp) {\n\t this._exp.value = exp;\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.FrequencyEnvelope} this\n\t\t */\n\t Tone.FrequencyEnvelope.prototype.dispose = function () {\n\t Tone.ScaledEnvelope.prototype.dispose.call(this);\n\t return this;\n\t };\n\t return Tone.FrequencyEnvelope;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.SignalBase}\n\t\t * @example\n\t\t * var gt0 = new Tone.GreaterThanZero();\n\t\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t\t * //the output of gt0 is 1.\n\t\t * sig.value = 0;\n\t\t * //the output of gt0 is 0.\n\t\t */\n\t Tone.GreaterThanZero = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * @type {Tone.WaveShaper}\n\t\t\t * @private\n\t\t\t */\n\t this._thresh = this.output = new Tone.WaveShaper(function (val) {\n\t if (val <= 0) {\n\t return 0;\n\t } else {\n\t return 1;\n\t }\n\t }, 127);\n\t /**\n\t\t\t * scale the first thresholded signal by a large value.\n\t\t\t * this will help with values which are very close to 0\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._scale = this.input = new Tone.Multiply(10000);\n\t //connections\n\t this._scale.connect(this._thresh);\n\t };\n\t Tone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\t /**\n\t\t * dispose method\n\t\t * @returns {Tone.GreaterThanZero} this\n\t\t */\n\t Tone.GreaterThanZero.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._scale.dispose();\n\t this._scale = null;\n\t this._thresh.dispose();\n\t this._thresh = null;\n\t return this;\n\t };\n\t return Tone.GreaterThanZero;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t\t * can compare two signals or a signal and a number.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Signal}\n\t\t * @param {number} [value=0] the value to compare to the incoming signal\n\t\t * @example\n\t\t * var gt = new Tone.GreaterThan(2);\n\t\t * var sig = new Tone.Signal(4).connect(gt);\n\t\t * //output of gt is equal 1.\n\t\t */\n\t Tone.GreaterThan = function (value) {\n\t Tone.Signal.call(this);\n\t this.createInsOuts(2, 0);\n\t /**\n\t\t\t * subtract the amount from the incoming signal\n\t\t\t * @type {Tone.Subtract}\n\t\t\t * @private\n\t\t\t */\n\t this._param = this.input[0] = new Tone.Subtract(value);\n\t this.input[1] = this._param.input[1];\n\t /**\n\t\t\t * compare that amount to zero\n\t\t\t * @type {Tone.GreaterThanZero}\n\t\t\t * @private\n\t\t\t */\n\t this._gtz = this.output = new Tone.GreaterThanZero();\n\t //connect\n\t this._param.connect(this._gtz);\n\t };\n\t Tone.extend(Tone.GreaterThan, Tone.Signal);\n\t /**\n\t\t * dispose method\n\t\t * @returns {Tone.GreaterThan} this\n\t\t */\n\t Tone.GreaterThan.prototype.dispose = function () {\n\t Tone.Signal.prototype.dispose.call(this);\n\t this._gtz.dispose();\n\t this._gtz = null;\n\t return this;\n\t };\n\t return Tone.GreaterThan;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Gate only passes a signal through when the incoming\n\t\t * signal exceeds a specified threshold. To do this, Gate uses\n\t\t * a Tone.Follower to follow the amplitude of the incoming signal.\n\t\t * A common implementation of this class is a [Noise Gate](https://en.wikipedia.org/wiki/Noise_gate).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Decibels|Object} [threshold] The threshold above which the gate will open.\n\t\t * @param {Time=} attack The follower's attack time\n\t\t * @param {Time=} release The follower's release time\n\t\t * @example\n\t\t * var gate = new Tone.Gate(-30, 0.2, 0.3).toMaster();\n\t\t * var mic = new Tone.UserMedia().connect(gate);\n\t\t * //the gate will only pass through the incoming\n\t\t * //signal when it's louder than -30db\n\t\t */\n\t Tone.Gate = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'threshold',\n\t 'attack',\n\t 'release'\n\t ], Tone.Gate);\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(1, 1);\n\t /**\n\t\t\t * @type {Tone.Follower}\n\t\t\t * @private\n\t\t\t */\n\t this._follower = new Tone.Follower(options.attack, options.release);\n\t /**\n\t\t\t * @type {Tone.GreaterThan}\n\t\t\t * @private\n\t\t\t */\n\t this._gt = new Tone.GreaterThan(Tone.dbToGain(options.threshold));\n\t //the connections\n\t this.input.connect(this.output);\n\t //the control signal\n\t this.input.chain(this._gt, this._follower, this.output.gain);\n\t };\n\t Tone.extend(Tone.Gate, Tone.AudioNode);\n\t /**\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Gate.defaults = {\n\t 'attack': 0.1,\n\t 'release': 0.1,\n\t 'threshold': -40\n\t };\n\t /**\n\t\t * The threshold of the gate in decibels\n\t\t * @memberOf Tone.Gate#\n\t\t * @type {Decibels}\n\t\t * @name threshold\n\t\t */\n\t Object.defineProperty(Tone.Gate.prototype, 'threshold', {\n\t get: function () {\n\t return Tone.gainToDb(this._gt.value);\n\t },\n\t set: function (thresh) {\n\t this._gt.value = Tone.dbToGain(thresh);\n\t }\n\t });\n\t /**\n\t\t * The attack speed of the gate\n\t\t * @memberOf Tone.Gate#\n\t\t * @type {Time}\n\t\t * @name attack\n\t\t */\n\t Object.defineProperty(Tone.Gate.prototype, 'attack', {\n\t get: function () {\n\t return this._follower.attack;\n\t },\n\t set: function (attackTime) {\n\t this._follower.attack = attackTime;\n\t }\n\t });\n\t /**\n\t\t * The release speed of the gate\n\t\t * @memberOf Tone.Gate#\n\t\t * @type {Time}\n\t\t * @name release\n\t\t */\n\t Object.defineProperty(Tone.Gate.prototype, 'release', {\n\t get: function () {\n\t return this._follower.release;\n\t },\n\t set: function (releaseTime) {\n\t this._follower.release = releaseTime;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Gate} this\n\t\t */\n\t Tone.Gate.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._follower.dispose();\n\t this._gt.dispose();\n\t this._follower = null;\n\t this._gt = null;\n\t return this;\n\t };\n\t return Tone.Gate;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.TickSignal extends Tone.Signal, but adds the capability\n\t\t * to calculate the number of elapsed ticks. exponential and target curves\n\t\t * are approximated with multiple linear ramps.\n\t\t *\n\t\t * Thank you Bruno Dias, H. Sofia Pinto, and David M. Matos, for your [WAC paper](https://smartech.gatech.edu/bitstream/handle/1853/54588/WAC2016-49.pdf)\n\t\t * describing integrating timing functions for tempo calculations.\n\t\t *\n\t\t * @param {Number} value The initial value of the signal\n\t\t * @extends {Tone.Signal}\n\t\t */\n\t Tone.TickSignal = function (value) {\n\t value = Tone.defaultArg(value, 1);\n\t Tone.Signal.call(this, {\n\t 'units': Tone.Type.Ticks,\n\t 'value': value\n\t });\n\t //extend the memory\n\t this._events.memory = Infinity;\n\t //clear the clock from the beginning\n\t this.cancelScheduledValues(0);\n\t //set an initial event\n\t this._events.add({\n\t 'type': Tone.Param.AutomationType.SetValue,\n\t 'time': 0,\n\t 'value': value\n\t });\n\t };\n\t Tone.extend(Tone.TickSignal, Tone.Signal);\n\t /**\n\t\t * Wraps Tone.Signal methods so that they also\n\t\t * record the ticks.\n\t\t * @param {Function} method\n\t\t * @return {Function}\n\t\t * @private\n\t\t */\n\t function _wrapScheduleMethods(method) {\n\t return function (value, time) {\n\t time = this.toSeconds(time);\n\t method.apply(this, arguments);\n\t var event = this._events.get(time);\n\t var previousEvent = this._events.previousEvent(event);\n\t var ticksUntilTime = this._getTicksUntilEvent(previousEvent, time);\n\t event.ticks = Math.max(ticksUntilTime, 0);\n\t return this;\n\t };\n\t }\n\t Tone.TickSignal.prototype.setValueAtTime = _wrapScheduleMethods(Tone.Signal.prototype.setValueAtTime);\n\t Tone.TickSignal.prototype.linearRampToValueAtTime = _wrapScheduleMethods(Tone.Signal.prototype.linearRampToValueAtTime);\n\t /**\n\t\t * Start exponentially approaching the target value at the given time with\n\t\t * a rate having the given time constant.\n\t\t * @param {number} value\n\t\t * @param {Time} startTime\n\t\t * @param {number} timeConstant\n\t\t * @returns {Tone.TickSignal} this\n\t\t */\n\t Tone.TickSignal.prototype.setTargetAtTime = function (value, time, constant) {\n\t //aproximate it with multiple linear ramps\n\t time = this.toSeconds(time);\n\t this.setRampPoint(time);\n\t value = this._fromUnits(value);\n\t //start from previously scheduled value\n\t var prevEvent = this._events.get(time);\n\t var segments = Math.round(Math.max(1 / constant, 1));\n\t for (var i = 0; i <= segments; i++) {\n\t var segTime = constant * i + time;\n\t var rampVal = this._exponentialApproach(prevEvent.time, prevEvent.value, value, constant, segTime);\n\t this.linearRampToValueAtTime(this._toUnits(rampVal), segTime);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Schedules an exponential continuous change in parameter value from\n\t\t * the previous scheduled parameter value to the given value.\n\t\t * @param {number} value\n\t\t * @param {Time} endTime\n\t\t * @returns {Tone.TickSignal} this\n\t\t */\n\t Tone.TickSignal.prototype.exponentialRampToValueAtTime = function (value, time) {\n\t //aproximate it with multiple linear ramps\n\t time = this.toSeconds(time);\n\t value = this._fromUnits(value);\n\t //start from previously scheduled value\n\t var prevEvent = this._events.get(time);\n\t if (prevEvent === null) {\n\t prevEvent = {\n\t 'value': this._initialValue,\n\t 'time': 0\n\t };\n\t }\n\t //approx 10 segments per second\n\t var segments = Math.round(Math.max((time - prevEvent.time) * 10, 1));\n\t var segmentDur = (time - prevEvent.time) / segments;\n\t for (var i = 0; i <= segments; i++) {\n\t var segTime = segmentDur * i + prevEvent.time;\n\t var rampVal = this._exponentialInterpolate(prevEvent.time, prevEvent.value, time, value, segTime);\n\t this.linearRampToValueAtTime(this._toUnits(rampVal), segTime);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Returns the tick value at the time. Takes into account\n\t\t * any automation curves scheduled on the signal.\n\t\t * @private\n\t\t * @param {Time} time The time to get the tick count at\n\t\t * @return {Ticks} The number of ticks which have elapsed at the time\n\t\t * given any automations.\n\t\t */\n\t Tone.TickSignal.prototype._getTicksUntilEvent = function (event, time) {\n\t if (event === null) {\n\t event = {\n\t 'ticks': 0,\n\t 'time': 0\n\t };\n\t } else if (Tone.isUndef(event.ticks)) {\n\t var previousEvent = this._events.previousEvent(event);\n\t event.ticks = this._getTicksUntilEvent(previousEvent, event.time);\n\t }\n\t var val0 = this.getValueAtTime(event.time);\n\t var val1 = this.getValueAtTime(time);\n\t //if it's right on the line, take the previous value\n\t if (this._events.get(time).time === time && this._events.get(time).type === Tone.Param.AutomationType.SetValue) {\n\t val1 = this.getValueAtTime(time - this.sampleTime);\n\t }\n\t return 0.5 * (time - event.time) * (val0 + val1) + event.ticks;\n\t };\n\t /**\n\t\t * Returns the tick value at the time. Takes into account\n\t\t * any automation curves scheduled on the signal.\n\t\t * @param {Time} time The time to get the tick count at\n\t\t * @return {Ticks} The number of ticks which have elapsed at the time\n\t\t * given any automations.\n\t\t */\n\t Tone.TickSignal.prototype.getTicksAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t var event = this._events.get(time);\n\t return Math.max(this._getTicksUntilEvent(event, time), 0);\n\t };\n\t /**\n\t\t * Return the elapsed time of the number of ticks from the given time\n\t\t * @param {Ticks} ticks The number of ticks to calculate\n\t\t * @param {Time} time The time to get the next tick from\n\t\t * @return {Seconds} The duration of the number of ticks from the given time in seconds\n\t\t */\n\t Tone.TickSignal.prototype.getDurationOfTicks = function (ticks, time) {\n\t time = this.toSeconds(time);\n\t var currentTick = this.getTicksAtTime(time);\n\t return this.getTimeOfTick(currentTick + ticks) - time;\n\t };\n\t /**\n\t\t * Given a tick, returns the time that tick occurs at.\n\t\t * @param {Ticks} tick\n\t\t * @return {Time} The time that the tick occurs.\n\t\t */\n\t Tone.TickSignal.prototype.getTimeOfTick = function (tick) {\n\t var before = this._events.get(tick, 'ticks');\n\t var after = this._events.getAfter(tick, 'ticks');\n\t if (before && before.ticks === tick) {\n\t return before.time;\n\t } else if (before && after && after.type === Tone.Param.AutomationType.Linear && before.value !== after.value) {\n\t var val0 = this.getValueAtTime(before.time);\n\t var val1 = this.getValueAtTime(after.time);\n\t var delta = (val1 - val0) / (after.time - before.time);\n\t var k = Math.sqrt(Math.pow(val0, 2) - 2 * delta * (before.ticks - tick));\n\t var sol1 = (-val0 + k) / delta;\n\t var sol2 = (-val0 - k) / delta;\n\t return (sol1 > 0 ? sol1 : sol2) + before.time;\n\t } else if (before) {\n\t if (before.value === 0) {\n\t return Infinity;\n\t } else {\n\t return before.time + (tick - before.ticks) / before.value;\n\t }\n\t } else {\n\t return tick / this._initialValue;\n\t }\n\t };\n\t /**\n\t\t * Convert some number of ticks their the duration in seconds accounting\n\t\t * for any automation curves starting at the given time.\n\t\t * @param {Ticks} ticks The number of ticks to convert to seconds.\n\t\t * @param {Time} [when=now] When along the automation timeline to convert the ticks.\n\t\t * @return {Tone.Time} The duration in seconds of the ticks.\n\t\t */\n\t Tone.TickSignal.prototype.ticksToTime = function (ticks, when) {\n\t when = this.toSeconds(when);\n\t return new Tone.Time(this.getDurationOfTicks(ticks, when));\n\t };\n\t /**\n\t\t * The inverse of [ticksToTime](#tickstotime). Convert a duration in\n\t\t * seconds to the corresponding number of ticks accounting for any\n\t\t * automation curves starting at the given time.\n\t\t * @param {Time} duration The time interval to convert to ticks.\n\t\t * @param {Time} [when=now] When along the automation timeline to convert the ticks.\n\t\t * @return {Tone.Ticks} The duration in ticks.\n\t\t */\n\t Tone.TickSignal.prototype.timeToTicks = function (duration, when) {\n\t when = this.toSeconds(when);\n\t duration = this.toSeconds(duration);\n\t var startTicks = this.getTicksAtTime(when);\n\t var endTicks = this.getTicksAtTime(when + duration);\n\t return new Tone.Ticks(endTicks - startTicks);\n\t };\n\t return Tone.TickSignal;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A Timeline State. Provides the methods: <code>setStateAtTime(\"state\", time)</code>\n\t\t * and <code>getValueAtTime(time)</code>.\n\t\t *\n\t\t * @extends {Tone.Timeline}\n\t\t * @param {String} initial The initial state of the TimelineState. \n\t\t * Defaults to <code>undefined</code>\n\t\t */\n\t Tone.TimelineState = function (initial) {\n\t Tone.Timeline.call(this);\n\t /**\n\t\t\t * The initial state\n\t\t\t * @private\n\t\t\t * @type {String}\n\t\t\t */\n\t this._initial = initial;\n\t };\n\t Tone.extend(Tone.TimelineState, Tone.Timeline);\n\t /**\n\t\t * Returns the scheduled state scheduled before or at\n\t\t * the given time.\n\t\t * @param {Number} time The time to query.\n\t\t * @return {String} The name of the state input in setStateAtTime.\n\t\t */\n\t Tone.TimelineState.prototype.getValueAtTime = function (time) {\n\t var event = this.get(time);\n\t if (event !== null) {\n\t return event.state;\n\t } else {\n\t return this._initial;\n\t }\n\t };\n\t /**\n\t\t * Add a state to the timeline.\n\t\t * @param {String} state The name of the state to set.\n\t\t * @param {Number} time The time to query.\n\t\t * @returns {Tone.TimelineState} this\n\t\t */\n\t Tone.TimelineState.prototype.setStateAtTime = function (state, time) {\n\t //all state changes need to be >= the previous state time\n\t //TODO throw error if time < the previous event time\n\t this.add({\n\t 'state': state,\n\t 'time': time\n\t });\n\t return this;\n\t };\n\t /**\n\t\t * Return the event before the time with the given state\n\t\t * @param {Tone.State} state The state to look for\n\t\t * @param {Time} time When to check before\t\t\t\n\t\t * @return {Object} The event with the given state before the time\n\t\t */\n\t Tone.TimelineState.prototype.getLastState = function (state, time) {\n\t time = this.toSeconds(time);\n\t var index = this._search(time);\n\t for (var i = index; i >= 0; i--) {\n\t var event = this._timeline[i];\n\t if (event.state === state) {\n\t return event;\n\t }\n\t }\n\t };\n\t /**\n\t\t * Return the event after the time with the given state\n\t\t * @param {Tone.State} state The state to look for\n\t\t * @param {Time} time When to check from\n\t\t * @return {Object} The event with the given state after the time\n\t\t */\n\t Tone.TimelineState.prototype.getNextState = function (state, time) {\n\t time = this.toSeconds(time);\n\t var index = this._search(time);\n\t if (index !== -1) {\n\t for (var i = index; i < this._timeline.length; i++) {\n\t var event = this._timeline[i];\n\t if (event.state === state) {\n\t return event;\n\t }\n\t }\n\t }\n\t };\n\t return Tone.TimelineState;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Uses [Tone.TickSignal](TickSignal) to track elapsed ticks with\n\t\t * \t\tcomplex automation curves.\n\t\t *\n\t\t * \t@constructor\n\t * @param {Frequency} frequency The initial frequency that the signal ticks at\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.TickSource = function () {\n\t var options = Tone.defaults(arguments, ['frequency'], Tone.TickSource);\n\t /**\n\t\t\t * The frequency the callback function should be invoked.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.TickSignal(options.frequency, Tone.Type.Frequency);\n\t this._readOnly('frequency');\n\t /**\n\t\t\t * The state timeline\n\t\t\t * @type {Tone.TimelineState}\n\t\t\t * @private\n\t\t\t */\n\t this._state = new Tone.TimelineState(Tone.State.Stopped);\n\t this._state.setStateAtTime(Tone.State.Stopped, 0);\n\t /**\n\t\t\t * The offset values of the ticks\n\t\t\t * @type {Tone.Timeline}\n\t\t\t * @private\n\t\t\t */\n\t this._tickOffset = new Tone.Timeline();\n\t //add the first event\n\t this.setTicksAtTime(0, 0);\n\t };\n\t Tone.extend(Tone.TickSource);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.TickSource.defaults = { 'frequency': 1 };\n\t /**\n\t\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.TickSource#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.TickSource.prototype, 'state', {\n\t get: function () {\n\t return this._state.getValueAtTime(this.now());\n\t }\n\t });\n\t /**\n\t\t * Start the clock at the given time. Optionally pass in an offset\n\t\t * of where to start the tick counter from.\n\t\t * @param {Time=} time The time the clock should start\n\t\t * @param {Ticks=0} offset The number of ticks to start the source at\n\t\t * @return {Tone.TickSource} this\n\t\t */\n\t Tone.TickSource.prototype.start = function (time, offset) {\n\t time = this.toSeconds(time);\n\t if (this._state.getValueAtTime(time) !== Tone.State.Started) {\n\t this._state.setStateAtTime(Tone.State.Started, time);\n\t if (Tone.isDefined(offset)) {\n\t this.setTicksAtTime(offset, time);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t\t * @param {Time} [time=now] The time when the clock should stop.\n\t\t * @returns {Tone.TickSource} this\n\t\t * @example\n\t\t * clock.stop();\n\t\t */\n\t Tone.TickSource.prototype.stop = function (time) {\n\t time = this.toSeconds(time);\n\t //cancel the previous stop\n\t if (this._state.getValueAtTime(time) === Tone.State.Stopped) {\n\t var event = this._state.get(time);\n\t if (event.time > 0) {\n\t this._tickOffset.cancel(event.time);\n\t this._state.cancel(event.time);\n\t }\n\t }\n\t this._state.cancel(time);\n\t this._state.setStateAtTime(Tone.State.Stopped, time);\n\t this.setTicksAtTime(0, time);\n\t return this;\n\t };\n\t /**\n\t\t * Pause the clock. Pausing does not reset the tick counter.\n\t\t * @param {Time} [time=now] The time when the clock should stop.\n\t\t * @returns {Tone.TickSource} this\n\t\t */\n\t Tone.TickSource.prototype.pause = function (time) {\n\t time = this.toSeconds(time);\n\t if (this._state.getValueAtTime(time) === Tone.State.Started) {\n\t this._state.setStateAtTime(Tone.State.Paused, time);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Cancel start/stop/pause and setTickAtTime events scheduled after the given time.\n\t\t * @param {Time} [time=now] When to clear the events after\n\t\t * @returns {Tone.TickSource} this\n\t\t */\n\t Tone.TickSource.prototype.cancel = function (time) {\n\t time = this.toSeconds(time);\n\t this._state.cancel(time);\n\t this._tickOffset.cancel(time);\n\t return this;\n\t };\n\t /**\n\t\t * Get the elapsed ticks at the given time\n\t\t * @param {Time} time When to get the tick value\n\t\t * @return {Ticks} The number of ticks\n\t\t */\n\t Tone.TickSource.prototype.getTicksAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t var stopEvent = this._state.getLastState(Tone.State.Stopped, time);\n\t //this event allows forEachBetween to iterate until the current time\n\t var tmpEvent = {\n\t state: Tone.State.Paused,\n\t time: time\n\t };\n\t this._state.add(tmpEvent);\n\t //keep track of the previous offset event\n\t var lastState = stopEvent;\n\t var elapsedTicks = 0;\n\t //iterate through all the events since the last stop\n\t this._state.forEachBetween(stopEvent.time, time + this.sampleTime, function (e) {\n\t var periodStartTime = lastState.time;\n\t //if there is an offset event in this period use that\n\t var offsetEvent = this._tickOffset.get(e.time);\n\t if (offsetEvent.time >= lastState.time) {\n\t elapsedTicks = offsetEvent.ticks;\n\t periodStartTime = offsetEvent.time;\n\t }\n\t if (lastState.state === Tone.State.Started && e.state !== Tone.State.Started) {\n\t elapsedTicks += this.frequency.getTicksAtTime(e.time) - this.frequency.getTicksAtTime(periodStartTime);\n\t }\n\t lastState = e;\n\t }.bind(this));\n\t //remove the temporary event\n\t this._state.remove(tmpEvent);\n\t //return the ticks\n\t return elapsedTicks;\n\t };\n\t /**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. Returns -1 when stopped.\n\t\t * @memberOf Tone.TickSource#\n\t\t * @name ticks\n\t\t * @type {Ticks}\n\t\t */\n\t Object.defineProperty(Tone.TickSource.prototype, 'ticks', {\n\t get: function () {\n\t return this.getTicksAtTime(this.now());\n\t },\n\t set: function (t) {\n\t this.setTicksAtTime(t, this.now());\n\t }\n\t });\n\t /**\n\t\t * The time since ticks=0 that the TickSource has been running. Accounts\n\t\t * for tempo curves\n\t\t * @memberOf Tone.TickSource#\n\t\t * @name seconds\n\t\t * @type {Seconds}\n\t\t */\n\t Object.defineProperty(Tone.TickSource.prototype, 'seconds', {\n\t get: function () {\n\t return this.getSecondsAtTime(this.now());\n\t },\n\t set: function (s) {\n\t var now = this.now();\n\t var ticks = this.frequency.timeToTicks(s, now);\n\t this.setTicksAtTime(ticks, now);\n\t }\n\t });\n\t /**\n\t\t * Return the elapsed seconds at the given time.\n\t\t * @param {Time} time When to get the elapsed seconds\n\t\t * @return {Seconds} The number of elapsed seconds\n\t\t */\n\t Tone.TickSource.prototype.getSecondsAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t var stopEvent = this._state.getLastState(Tone.State.Stopped, time);\n\t //this event allows forEachBetween to iterate until the current time\n\t var tmpEvent = {\n\t state: Tone.State.Paused,\n\t time: time\n\t };\n\t this._state.add(tmpEvent);\n\t //keep track of the previous offset event\n\t var lastState = stopEvent;\n\t var elapsedSeconds = 0;\n\t //iterate through all the events since the last stop\n\t this._state.forEachBetween(stopEvent.time, time + this.sampleTime, function (e) {\n\t var periodStartTime = lastState.time;\n\t //if there is an offset event in this period use that\n\t var offsetEvent = this._tickOffset.get(e.time);\n\t if (offsetEvent.time >= lastState.time) {\n\t elapsedSeconds = offsetEvent.seconds;\n\t periodStartTime = offsetEvent.time;\n\t }\n\t if (lastState.state === Tone.State.Started && e.state !== Tone.State.Started) {\n\t elapsedSeconds += e.time - periodStartTime;\n\t }\n\t lastState = e;\n\t }.bind(this));\n\t //remove the temporary event\n\t this._state.remove(tmpEvent);\n\t //return the ticks\n\t return elapsedSeconds;\n\t };\n\t /**\n\t\t * Set the clock's ticks at the given time.\n\t\t * @param {Ticks} ticks The tick value to set\n\t\t * @param {Time} time When to set the tick value\n\t\t * @return {Tone.TickSource} this\n\t\t */\n\t Tone.TickSource.prototype.setTicksAtTime = function (ticks, time) {\n\t time = this.toSeconds(time);\n\t this._tickOffset.cancel(time);\n\t this._tickOffset.add({\n\t 'time': time,\n\t 'ticks': ticks,\n\t 'seconds': this.frequency.getDurationOfTicks(ticks, time)\n\t });\n\t return this;\n\t };\n\t /**\n\t\t * Returns the scheduled state at the given time.\n\t\t * @param {Time} time The time to query.\n\t\t * @return {String} The name of the state input in setStateAtTime.\n\t\t * @example\n\t\t * source.start(\"+0.1\");\n\t\t * source.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t\t */\n\t Tone.TickSource.prototype.getStateAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t return this._state.getValueAtTime(time);\n\t };\n\t /**\n\t\t * Get the time of the given tick. The second argument\n\t\t * is when to test before. Since ticks can be set (with setTicksAtTime)\n\t\t * there may be multiple times for a given tick value. \n\t\t * @param {Ticks} ticks The tick number.\n\t\t * @param {Time=} before When to measure the tick value from. \n\t\t * @return {Time} The time of the tick\n\t\t */\n\t Tone.TickSource.prototype.getTimeOfTick = function (tick, before) {\n\t before = Tone.defaultArg(before, this.now());\n\t var offset = this._tickOffset.get(before);\n\t var event = this._state.get(before);\n\t var startTime = Math.max(offset.time, event.time);\n\t var absoluteTicks = this.frequency.getTicksAtTime(startTime) + tick - offset.ticks;\n\t return this.frequency.getTimeOfTick(absoluteTicks);\n\t };\n\t /**\n\t\t * Invoke the callback event at all scheduled ticks between the \n\t\t * start time and the end time\n\t\t * @param {Time} startTime The beginning of the search range\n\t\t * @param {Time} endTime The end of the search range\n\t\t * @param {Function<Time,Ticks>} callback The callback to invoke with each tick\n\t\t * @return {Tone.TickSource} this\n\t\t */\n\t Tone.TickSource.prototype.forEachTickBetween = function (startTime, endTime, callback) {\n\t //only iterate through the sections where it is \"started\"\n\t var lastStateEvent = this._state.get(startTime);\n\t this._state.forEachBetween(startTime, endTime, function (event) {\n\t if (lastStateEvent.state === Tone.State.Started && event.state !== Tone.State.Started) {\n\t this.forEachTickBetween(Math.max(lastStateEvent.time, startTime), event.time - this.sampleTime, callback);\n\t }\n\t lastStateEvent = event;\n\t }.bind(this));\n\t startTime = Math.max(lastStateEvent.time, startTime);\n\t if (lastStateEvent.state === Tone.State.Started && this._state) {\n\t //figure out the difference between the frequency ticks and the \n\t var startTicks = this.frequency.getTicksAtTime(startTime);\n\t var ticksAtStart = this.frequency.getTicksAtTime(lastStateEvent.time);\n\t var diff = startTicks - ticksAtStart;\n\t var offset = diff % 1;\n\t if (offset !== 0) {\n\t offset = 1 - offset;\n\t }\n\t var nextTickTime = this.frequency.getTimeOfTick(startTicks + offset);\n\t var error = null;\n\t while (nextTickTime < endTime && this._state) {\n\t try {\n\t callback(nextTickTime, Math.round(this.getTicksAtTime(nextTickTime)));\n\t } catch (e) {\n\t error = e;\n\t break;\n\t }\n\t if (this._state) {\n\t nextTickTime += this.frequency.getDurationOfTicks(1, nextTickTime);\n\t }\n\t }\n\t }\n\t if (error) {\n\t throw error;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @returns {Tone.TickSource} this\n\t\t */\n\t Tone.TickSource.prototype.dispose = function () {\n\t Tone.Param.prototype.dispose.call(this);\n\t this._state.dispose();\n\t this._state = null;\n\t this._tickOffset.dispose();\n\t this._tickOffset = null;\n\t this._writable('frequency');\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t return this;\n\t };\n\t return Tone.TickSource;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A sample accurate clock which provides a callback at the given rate.\n\t\t * While the callback is not sample-accurate (it is still susceptible to\n\t\t * loose JS timing), the time passed in as the argument to the callback\n\t\t * is precise. For most applications, it is better to use Tone.Transport\n\t\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t\t *\n\t\t * \t@constructor\n\t\t * @extends {Tone.Emitter}\n\t\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t\t * \t@param {Frequency} frequency The rate of the callback\n\t\t * \t@example\n\t\t * //the callback will be invoked approximately once a second\n\t\t * //and will print the time exactly once a second apart.\n\t\t * var clock = new Tone.Clock(function(time){\n\t\t * \tconsole.log(time);\n\t\t * }, 1);\n\t\t */\n\t Tone.Clock = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'callback',\n\t 'frequency'\n\t ], Tone.Clock);\n\t Tone.Emitter.call(this);\n\t /**\n\t\t\t * The callback function to invoke at the scheduled tick.\n\t\t\t * @type {Function}\n\t\t\t */\n\t this.callback = options.callback;\n\t /**\n\t\t\t * The next time the callback is scheduled.\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._nextTick = 0;\n\t /**\n\t\t\t * The tick counter\n\t\t\t * @type {Tone.TickSource}\n\t\t\t * @private\n\t\t\t */\n\t this._tickSource = new Tone.TickSource(options.frequency);\n\t /**\n\t\t\t * The last time the loop callback was invoked\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._lastUpdate = 0;\n\t /**\n\t\t\t * The rate the callback function should be invoked.\n\t\t\t * @type {BPM}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._tickSource.frequency;\n\t this._readOnly('frequency');\n\t /**\n\t\t\t * The state timeline\n\t\t\t * @type {Tone.TimelineState}\n\t\t\t * @private\n\t\t\t */\n\t this._state = new Tone.TimelineState(Tone.State.Stopped);\n\t //add an initial state\n\t this._state.setStateAtTime(Tone.State.Stopped, 0);\n\t /**\n\t\t\t * The loop function bound to its context.\n\t\t\t * This is necessary to remove the event in the end.\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._boundLoop = this._loop.bind(this);\n\t //bind a callback to the worker thread\n\t this.context.on('tick', this._boundLoop);\n\t };\n\t Tone.extend(Tone.Clock, Tone.Emitter);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Clock.defaults = {\n\t 'callback': Tone.noOp,\n\t 'frequency': 1\n\t };\n\t /**\n\t\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.Clock#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.Clock.prototype, 'state', {\n\t get: function () {\n\t return this._state.getValueAtTime(this.now());\n\t }\n\t });\n\t /**\n\t\t * Start the clock at the given time. Optionally pass in an offset\n\t\t * of where to start the tick counter from.\n\t\t * @param {Time=} time The time the clock should start\n\t\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t\t * @return {Tone.Clock} this\n\t\t */\n\t Tone.Clock.prototype.start = function (time, offset) {\n\t time = this.toSeconds(time);\n\t if (this._state.getValueAtTime(time) !== Tone.State.Started) {\n\t this._state.setStateAtTime(Tone.State.Started, time);\n\t this._tickSource.start(time, offset);\n\t if (time < this._lastUpdate) {\n\t this.emit('start', time, offset);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t\t * @param {Time} [time=now] The time when the clock should stop.\n\t\t * @returns {Tone.Clock} this\n\t\t * @example\n\t\t * clock.stop();\n\t\t */\n\t Tone.Clock.prototype.stop = function (time) {\n\t time = this.toSeconds(time);\n\t this._state.cancel(time);\n\t this._state.setStateAtTime(Tone.State.Stopped, time);\n\t this._tickSource.stop(time);\n\t if (time < this._lastUpdate) {\n\t this.emit('stop', time);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Pause the clock. Pausing does not reset the tick counter.\n\t\t * @param {Time} [time=now] The time when the clock should stop.\n\t\t * @returns {Tone.Clock} this\n\t\t */\n\t Tone.Clock.prototype.pause = function (time) {\n\t time = this.toSeconds(time);\n\t if (this._state.getValueAtTime(time) === Tone.State.Started) {\n\t this._state.setStateAtTime(Tone.State.Paused, time);\n\t this._tickSource.pause(time);\n\t if (time < this._lastUpdate) {\n\t this.emit('pause', time);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked.\n\t\t * @type {Ticks}\n\t\t */\n\t Object.defineProperty(Tone.Clock.prototype, 'ticks', {\n\t get: function () {\n\t return Math.ceil(this.getTicksAtTime(this.now()));\n\t },\n\t set: function (t) {\n\t this._tickSource.ticks = t;\n\t }\n\t });\n\t /**\n\t\t * The time since ticks=0 that the Clock has been running. Accounts\n\t\t * for tempo curves\n\t\t * @type {Seconds}\n\t\t */\n\t Object.defineProperty(Tone.Clock.prototype, 'seconds', {\n\t get: function () {\n\t return this._tickSource.seconds;\n\t },\n\t set: function (s) {\n\t this._tickSource.seconds = s;\n\t }\n\t });\n\t /**\n\t\t * Return the elapsed seconds at the given time.\n\t\t * @param {Time} time When to get the elapsed seconds\n\t\t * @return {Seconds} The number of elapsed seconds\n\t\t */\n\t Tone.Clock.prototype.getSecondsAtTime = function (time) {\n\t return this._tickSource.getSecondsAtTime(time);\n\t };\n\t /**\n\t\t * Set the clock's ticks at the given time.\n\t\t * @param {Ticks} ticks The tick value to set\n\t\t * @param {Time} time When to set the tick value\n\t\t * @return {Tone.Clock} this\n\t\t */\n\t Tone.Clock.prototype.setTicksAtTime = function (ticks, time) {\n\t this._tickSource.setTicksAtTime(ticks, time);\n\t return this;\n\t };\n\t /**\n\t\t * Get the clock's ticks at the given time.\n\t\t * @param {Time} time When to get the tick value\n\t\t * @return {Ticks} The tick value at the given time.\n\t\t */\n\t Tone.Clock.prototype.getTicksAtTime = function (time) {\n\t return this._tickSource.getTicksAtTime(time);\n\t };\n\t /**\n\t\t * Get the time of the next tick\n\t\t * @param {Ticks} ticks The tick number.\n\t\t * @param {Time} before \n\t\t * @return {Tone.Clock} this\n\t\t */\n\t Tone.Clock.prototype.nextTickTime = function (offset, when) {\n\t when = this.toSeconds(when);\n\t var currentTick = this.getTicksAtTime(when);\n\t return this._tickSource.getTimeOfTick(currentTick + offset, when);\n\t };\n\t /**\n\t\t * The scheduling loop.\n\t\t * @private\n\t\t */\n\t Tone.Clock.prototype._loop = function () {\n\t var startTime = this._lastUpdate;\n\t var endTime = this.now();\n\t this._lastUpdate = endTime;\n\t if (startTime !== endTime) {\n\t //the state change events\n\t this._state.forEachBetween(startTime, endTime, function (e) {\n\t switch (e.state) {\n\t case Tone.State.Started:\n\t var offset = this._tickSource.getTicksAtTime(e.time);\n\t this.emit('start', e.time, offset);\n\t break;\n\t case Tone.State.Stopped:\n\t if (e.time !== 0) {\n\t this.emit('stop', e.time);\n\t }\n\t break;\n\t case Tone.State.Paused:\n\t this.emit('pause', e.time);\n\t break;\n\t }\n\t }.bind(this));\n\t //the tick callbacks\n\t this._tickSource.forEachTickBetween(startTime, endTime, function (time, ticks) {\n\t this.callback(time, ticks);\n\t }.bind(this));\n\t }\n\t };\n\t /**\n\t\t * Returns the scheduled state at the given time.\n\t\t * @param {Time} time The time to query.\n\t\t * @return {String} The name of the state input in setStateAtTime.\n\t\t * @example\n\t\t * clock.start(\"+0.1\");\n\t\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t\t */\n\t Tone.Clock.prototype.getStateAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t return this._state.getValueAtTime(time);\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @returns {Tone.Clock} this\n\t\t */\n\t Tone.Clock.prototype.dispose = function () {\n\t Tone.Emitter.prototype.dispose.call(this);\n\t this.context.off('tick', this._boundLoop);\n\t this._writable('frequency');\n\t this._tickSource.dispose();\n\t this._tickSource = null;\n\t this.frequency = null;\n\t this._boundLoop = null;\n\t this._nextTick = Infinity;\n\t this.callback = null;\n\t this._state.dispose();\n\t this._state = null;\n\t };\n\t return Tone.Clock;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Similar to Tone.Timeline, but all events represent\n\t\t * intervals with both \"time\" and \"duration\" times. The\n\t\t * events are placed in a tree structure optimized\n\t\t * for querying an intersection point with the timeline\n\t\t * events. Internally uses an [Interval Tree](https://en.wikipedia.org/wiki/Interval_tree)\n\t\t * to represent the data.\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.IntervalTimeline = function () {\n\t Tone.call(this);\n\t /**\n\t\t\t * The root node of the inteval tree\n\t\t\t * @type {IntervalNode}\n\t\t\t * @private\n\t\t\t */\n\t this._root = null;\n\t /**\n\t\t\t * Keep track of the length of the timeline.\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._length = 0;\n\t };\n\t Tone.extend(Tone.IntervalTimeline);\n\t /**\n\t\t * The event to add to the timeline. All events must\n\t\t * have a time and duration value\n\t\t * @param {Object} event The event to add to the timeline\n\t\t * @return {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.add = function (event) {\n\t if (Tone.isUndef(event.time) || Tone.isUndef(event.duration)) {\n\t throw new Error('Tone.IntervalTimeline: events must have time and duration parameters');\n\t }\n\t event.time = event.time.valueOf();\n\t var node = new IntervalNode(event.time, event.time + event.duration, event);\n\t if (this._root === null) {\n\t this._root = node;\n\t } else {\n\t this._root.insert(node);\n\t }\n\t this._length++;\n\t // Restructure tree to be balanced\n\t while (node !== null) {\n\t node.updateHeight();\n\t node.updateMax();\n\t this._rebalance(node);\n\t node = node.parent;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Remove an event from the timeline.\n\t\t * @param {Object} event The event to remove from the timeline\n\t\t * @return {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.remove = function (event) {\n\t if (this._root !== null) {\n\t var results = [];\n\t this._root.search(event.time, results);\n\t for (var i = 0; i < results.length; i++) {\n\t var node = results[i];\n\t if (node.event === event) {\n\t this._removeNode(node);\n\t this._length--;\n\t break;\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * The number of items in the timeline.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.IntervalTimeline#\n\t\t * @name length\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.IntervalTimeline.prototype, 'length', {\n\t get: function () {\n\t return this._length;\n\t }\n\t });\n\t /**\n\t\t * Remove events whose time time is after the given time\n\t\t * @param {Number} time The time to query.\n\t\t * @returns {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.cancel = function (after) {\n\t this.forEachFrom(after, function (event) {\n\t this.remove(event);\n\t }.bind(this));\n\t return this;\n\t };\n\t /**\n\t\t * Set the root node as the given node\n\t\t * @param {IntervalNode} node\n\t\t * @private\n\t\t */\n\t Tone.IntervalTimeline.prototype._setRoot = function (node) {\n\t this._root = node;\n\t if (this._root !== null) {\n\t this._root.parent = null;\n\t }\n\t };\n\t /**\n\t\t * Replace the references to the node in the node's parent\n\t\t * with the replacement node.\n\t\t * @param {IntervalNode} node\n\t\t * @param {IntervalNode} replacement\n\t\t * @private\n\t\t */\n\t Tone.IntervalTimeline.prototype._replaceNodeInParent = function (node, replacement) {\n\t if (node.parent !== null) {\n\t if (node.isLeftChild()) {\n\t node.parent.left = replacement;\n\t } else {\n\t node.parent.right = replacement;\n\t }\n\t this._rebalance(node.parent);\n\t } else {\n\t this._setRoot(replacement);\n\t }\n\t };\n\t /**\n\t\t * Remove the node from the tree and replace it with\n\t\t * a successor which follows the schema.\n\t\t * @param {IntervalNode} node\n\t\t * @private\n\t\t */\n\t Tone.IntervalTimeline.prototype._removeNode = function (node) {\n\t if (node.left === null && node.right === null) {\n\t this._replaceNodeInParent(node, null);\n\t } else if (node.right === null) {\n\t this._replaceNodeInParent(node, node.left);\n\t } else if (node.left === null) {\n\t this._replaceNodeInParent(node, node.right);\n\t } else {\n\t var balance = node.getBalance();\n\t var replacement, temp;\n\t if (balance > 0) {\n\t if (node.left.right === null) {\n\t replacement = node.left;\n\t replacement.right = node.right;\n\t temp = replacement;\n\t } else {\n\t replacement = node.left.right;\n\t while (replacement.right !== null) {\n\t replacement = replacement.right;\n\t }\n\t replacement.parent.right = replacement.left;\n\t temp = replacement.parent;\n\t replacement.left = node.left;\n\t replacement.right = node.right;\n\t }\n\t } else if (node.right.left === null) {\n\t replacement = node.right;\n\t replacement.left = node.left;\n\t temp = replacement;\n\t } else {\n\t replacement = node.right.left;\n\t while (replacement.left !== null) {\n\t replacement = replacement.left;\n\t }\n\t replacement.parent = replacement.parent;\n\t replacement.parent.left = replacement.right;\n\t temp = replacement.parent;\n\t replacement.left = node.left;\n\t replacement.right = node.right;\n\t }\n\t if (node.parent !== null) {\n\t if (node.isLeftChild()) {\n\t node.parent.left = replacement;\n\t } else {\n\t node.parent.right = replacement;\n\t }\n\t } else {\n\t this._setRoot(replacement);\n\t }\n\t // this._replaceNodeInParent(node, replacement);\n\t this._rebalance(temp);\n\t }\n\t node.dispose();\n\t };\n\t /**\n\t\t * Rotate the tree to the left\n\t\t * @param {IntervalNode} node\n\t\t * @private\n\t\t */\n\t Tone.IntervalTimeline.prototype._rotateLeft = function (node) {\n\t var parent = node.parent;\n\t var isLeftChild = node.isLeftChild();\n\t // Make node.right the new root of this sub tree (instead of node)\n\t var pivotNode = node.right;\n\t node.right = pivotNode.left;\n\t pivotNode.left = node;\n\t if (parent !== null) {\n\t if (isLeftChild) {\n\t parent.left = pivotNode;\n\t } else {\n\t parent.right = pivotNode;\n\t }\n\t } else {\n\t this._setRoot(pivotNode);\n\t }\n\t };\n\t /**\n\t\t * Rotate the tree to the right\n\t\t * @param {IntervalNode} node\n\t\t * @private\n\t\t */\n\t Tone.IntervalTimeline.prototype._rotateRight = function (node) {\n\t var parent = node.parent;\n\t var isLeftChild = node.isLeftChild();\n\t // Make node.left the new root of this sub tree (instead of node)\n\t var pivotNode = node.left;\n\t node.left = pivotNode.right;\n\t pivotNode.right = node;\n\t if (parent !== null) {\n\t if (isLeftChild) {\n\t parent.left = pivotNode;\n\t } else {\n\t parent.right = pivotNode;\n\t }\n\t } else {\n\t this._setRoot(pivotNode);\n\t }\n\t };\n\t /**\n\t\t * Balance the BST\n\t\t * @param {IntervalNode} node\n\t\t * @private\n\t\t */\n\t Tone.IntervalTimeline.prototype._rebalance = function (node) {\n\t var balance = node.getBalance();\n\t if (balance > 1) {\n\t if (node.left.getBalance() < 0) {\n\t this._rotateLeft(node.left);\n\t } else {\n\t this._rotateRight(node);\n\t }\n\t } else if (balance < -1) {\n\t if (node.right.getBalance() > 0) {\n\t this._rotateRight(node.right);\n\t } else {\n\t this._rotateLeft(node);\n\t }\n\t }\n\t };\n\t /**\n\t\t * Get an event whose time and duration span the give time. Will\n\t\t * return the match whose \"time\" value is closest to the given time.\n\t\t * @param {Object} event The event to add to the timeline\n\t\t * @return {Object} The event which spans the desired time\n\t\t */\n\t Tone.IntervalTimeline.prototype.get = function (time) {\n\t if (this._root !== null) {\n\t var results = [];\n\t this._root.search(time, results);\n\t if (results.length > 0) {\n\t var max = results[0];\n\t for (var i = 1; i < results.length; i++) {\n\t if (results[i].low > max.low) {\n\t max = results[i];\n\t }\n\t }\n\t return max.event;\n\t }\n\t }\n\t return null;\n\t };\n\t /**\n\t\t * Iterate over everything in the timeline.\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.forEach = function (callback) {\n\t if (this._root !== null) {\n\t var allNodes = [];\n\t this._root.traverse(function (node) {\n\t allNodes.push(node);\n\t });\n\t for (var i = 0; i < allNodes.length; i++) {\n\t var ev = allNodes[i].event;\n\t if (ev) {\n\t callback(ev);\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array in which the given time\n\t\t * overlaps with the time and duration time of the event.\n\t\t * @param {Number} time The time to check if items are overlapping\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.forEachAtTime = function (time, callback) {\n\t if (this._root !== null) {\n\t var results = [];\n\t this._root.search(time, results);\n\t for (var i = results.length - 1; i >= 0; i--) {\n\t var ev = results[i].event;\n\t if (ev) {\n\t callback(ev);\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over everything in the array in which the time is greater\n\t\t * than or equal to the given time.\n\t\t * @param {Number} time The time to check if items are before\n\t\t * @param {Function} callback The callback to invoke with every item\n\t\t * @returns {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.forEachFrom = function (time, callback) {\n\t if (this._root !== null) {\n\t var results = [];\n\t this._root.searchAfter(time, results);\n\t for (var i = results.length - 1; i >= 0; i--) {\n\t var ev = results[i].event;\n\t callback(ev);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.IntervalTimeline} this\n\t\t */\n\t Tone.IntervalTimeline.prototype.dispose = function () {\n\t var allNodes = [];\n\t if (this._root !== null) {\n\t this._root.traverse(function (node) {\n\t allNodes.push(node);\n\t });\n\t }\n\t for (var i = 0; i < allNodes.length; i++) {\n\t allNodes[i].dispose();\n\t }\n\t allNodes = null;\n\t this._root = null;\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tINTERVAL NODE HELPER\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Represents a node in the binary search tree, with the addition\n\t\t * of a \"high\" value which keeps track of the highest value of\n\t\t * its children.\n\t\t * References:\n\t\t * https://brooknovak.wordpress.com/2013/12/07/augmented-interval-tree-in-c/\n\t\t * http://www.mif.vu.lt/~valdas/ALGORITMAI/LITERATURA/Cormen/Cormen.pdf\n\t\t * @param {Number} low\n\t\t * @param {Number} high\n\t\t * @private\n\t\t */\n\t var IntervalNode = function (low, high, event) {\n\t //the event container\n\t this.event = event;\n\t //the low value\n\t this.low = low;\n\t //the high value\n\t this.high = high;\n\t //the high value for this and all child nodes\n\t this.max = this.high;\n\t //the nodes to the left\n\t this._left = null;\n\t //the nodes to the right\n\t this._right = null;\n\t //the parent node\n\t this.parent = null;\n\t //the number of child nodes\n\t this.height = 0;\n\t };\n\t /**\n\t\t * Insert a node into the correct spot in the tree\n\t\t * @param {IntervalNode} node\n\t\t */\n\t IntervalNode.prototype.insert = function (node) {\n\t if (node.low <= this.low) {\n\t if (this.left === null) {\n\t this.left = node;\n\t } else {\n\t this.left.insert(node);\n\t }\n\t } else if (this.right === null) {\n\t this.right = node;\n\t } else {\n\t this.right.insert(node);\n\t }\n\t };\n\t /**\n\t\t * Search the tree for nodes which overlap\n\t\t * with the given point\n\t\t * @param {Number} point The point to query\n\t\t * @param {Array} results The array to put the results\n\t\t */\n\t IntervalNode.prototype.search = function (point, results) {\n\t // If p is to the right of the rightmost point of any interval\n\t // in this node and all children, there won't be any matches.\n\t if (point > this.max) {\n\t return;\n\t }\n\t // Search left children\n\t if (this.left !== null) {\n\t this.left.search(point, results);\n\t }\n\t // Check this node\n\t if (this.low <= point && this.high > point) {\n\t results.push(this);\n\t }\n\t // If p is to the left of the time of this interval,\n\t // then it can't be in any child to the right.\n\t if (this.low > point) {\n\t return;\n\t }\n\t // Search right children\n\t if (this.right !== null) {\n\t this.right.search(point, results);\n\t }\n\t };\n\t /**\n\t\t * Search the tree for nodes which are less\n\t\t * than the given point\n\t\t * @param {Number} point The point to query\n\t\t * @param {Array} results The array to put the results\n\t\t */\n\t IntervalNode.prototype.searchAfter = function (point, results) {\n\t // Check this node\n\t if (this.low >= point) {\n\t results.push(this);\n\t if (this.left !== null) {\n\t this.left.searchAfter(point, results);\n\t }\n\t }\n\t // search the right side\n\t if (this.right !== null) {\n\t this.right.searchAfter(point, results);\n\t }\n\t };\n\t /**\n\t\t * Invoke the callback on this element and both it's branches\n\t\t * @param {Function} callback\n\t\t */\n\t IntervalNode.prototype.traverse = function (callback) {\n\t callback(this);\n\t if (this.left !== null) {\n\t this.left.traverse(callback);\n\t }\n\t if (this.right !== null) {\n\t this.right.traverse(callback);\n\t }\n\t };\n\t /**\n\t\t * Update the height of the node\n\t\t */\n\t IntervalNode.prototype.updateHeight = function () {\n\t if (this.left !== null && this.right !== null) {\n\t this.height = Math.max(this.left.height, this.right.height) + 1;\n\t } else if (this.right !== null) {\n\t this.height = this.right.height + 1;\n\t } else if (this.left !== null) {\n\t this.height = this.left.height + 1;\n\t } else {\n\t this.height = 0;\n\t }\n\t };\n\t /**\n\t\t * Update the height of the node\n\t\t */\n\t IntervalNode.prototype.updateMax = function () {\n\t this.max = this.high;\n\t if (this.left !== null) {\n\t this.max = Math.max(this.max, this.left.max);\n\t }\n\t if (this.right !== null) {\n\t this.max = Math.max(this.max, this.right.max);\n\t }\n\t };\n\t /**\n\t\t * The balance is how the leafs are distributed on the node\n\t\t * @return {Number} Negative numbers are balanced to the right\n\t\t */\n\t IntervalNode.prototype.getBalance = function () {\n\t var balance = 0;\n\t if (this.left !== null && this.right !== null) {\n\t balance = this.left.height - this.right.height;\n\t } else if (this.left !== null) {\n\t balance = this.left.height + 1;\n\t } else if (this.right !== null) {\n\t balance = -(this.right.height + 1);\n\t }\n\t return balance;\n\t };\n\t /**\n\t\t * @returns {Boolean} true if this node is the left child\n\t\t * of its parent\n\t\t */\n\t IntervalNode.prototype.isLeftChild = function () {\n\t return this.parent !== null && this.parent.left === this;\n\t };\n\t /**\n\t\t * get/set the left node\n\t\t * @type {IntervalNode}\n\t\t */\n\t Object.defineProperty(IntervalNode.prototype, 'left', {\n\t get: function () {\n\t return this._left;\n\t },\n\t set: function (node) {\n\t this._left = node;\n\t if (node !== null) {\n\t node.parent = this;\n\t }\n\t this.updateHeight();\n\t this.updateMax();\n\t }\n\t });\n\t /**\n\t\t * get/set the right node\n\t\t * @type {IntervalNode}\n\t\t */\n\t Object.defineProperty(IntervalNode.prototype, 'right', {\n\t get: function () {\n\t return this._right;\n\t },\n\t set: function (node) {\n\t this._right = node;\n\t if (node !== null) {\n\t node.parent = this;\n\t }\n\t this.updateHeight();\n\t this.updateMax();\n\t }\n\t });\n\t /**\n\t\t * null out references.\n\t\t */\n\t IntervalNode.prototype.dispose = function () {\n\t this.parent = null;\n\t this._left = null;\n\t this._right = null;\n\t this.event = null;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tEND INTERVAL NODE HELPER\n\t ///////////////////////////////////////////////////////////////////////////\n\t return Tone.IntervalTimeline;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Ticks is a primitive type for encoding Time values.\n\t\t * Tone.Ticks can be constructed with or without the `new` keyword. Tone.Ticks can be passed\n\t\t * into the parameter of any method which takes time as an argument.\n\t\t * @constructor\n\t\t * @extends {Tone.TransportTime}\n\t\t * @param {String|Number} val The time value.\n\t\t * @param {String=} units The units of the value.\n\t\t * @example\n\t\t * var t = Tone.Ticks(\"4n\");//a quarter note\n\t\t */\n\t Tone.Ticks = function (val, units) {\n\t if (this instanceof Tone.Ticks) {\n\t Tone.TransportTime.call(this, val, units);\n\t } else {\n\t return new Tone.Ticks(val, units);\n\t }\n\t };\n\t Tone.extend(Tone.Ticks, Tone.TransportTime);\n\t /**\n\t\t * The default units if none are given.\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t Tone.Ticks.prototype._defaultUnits = 'i';\n\t /**\n\t\t * Get the current time in the given units\n\t\t * @return {Ticks}\n\t\t * @private\n\t\t */\n\t Tone.Ticks.prototype._now = function () {\n\t return Tone.Transport.ticks;\n\t };\n\t /**\n\t\t * Return the value of the beats in the current units\n\t\t * @param {Number} beats\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Ticks.prototype._beatsToUnits = function (beats) {\n\t return this._getPPQ() * beats;\n\t };\n\t /**\n\t\t * Returns the value of a second in the current units\n\t\t * @param {Seconds} seconds\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Ticks.prototype._secondsToUnits = function (seconds) {\n\t return seconds / (60 / this._getBpm()) * this._getPPQ();\n\t };\n\t /**\n\t\t * Returns the value of a tick in the current time units\n\t\t * @param {Ticks} ticks\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Ticks.prototype._ticksToUnits = function (ticks) {\n\t return ticks;\n\t };\n\t /**\n\t\t * Return the time in ticks\n\t\t * @return {Ticks}\n\t\t */\n\t Tone.Ticks.prototype.toTicks = function () {\n\t return this.valueOf();\n\t };\n\t /**\n\t\t * Return the time in ticks\n\t\t * @return {Ticks}\n\t\t */\n\t Tone.Ticks.prototype.toSeconds = function () {\n\t return this.valueOf() / this._getPPQ() * (60 / this._getBpm());\n\t };\n\t return Tone.Ticks;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.TransportEvent is an internal class used by (Tone.Transport)[Transport]\n\t\t * to schedule events. Do no invoke this class directly, it is\n\t\t * handled from within Tone.Transport.\n\t\t * @extends {Tone}\n\t\t * @param {Object} options\n\t\t */\n\t Tone.TransportEvent = function (Transport, options) {\n\t options = Tone.defaultArg(options, Tone.TransportEvent.defaults);\n\t Tone.call(this);\n\t /**\n\t\t\t * Reference to the Transport that created it\n\t\t\t * @type {Tone.Transport}\n\t\t\t */\n\t this.Transport = Transport;\n\t /**\n\t\t\t * The unique id of the event\n\t\t\t * @type {Number}\n\t\t\t */\n\t this.id = Tone.TransportEvent._eventId++;\n\t /**\n\t\t\t * The time the event starts\n\t\t\t * @type {Ticks}\n\t\t\t */\n\t this.time = Tone.Ticks(options.time);\n\t /**\n\t\t\t * The callback to invoke\n\t\t\t * @type {Function}\n\t\t\t */\n\t this.callback = options.callback;\n\t /**\n\t\t\t * If the event should be removed after being created.\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t this._once = options.once;\n\t };\n\t Tone.extend(Tone.TransportEvent);\n\t /**\n\t\t * The defaults\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.TransportEvent.defaults = {\n\t 'once': false,\n\t 'callback': Tone.noOp\n\t };\n\t /**\n\t\t * Current ID counter\n\t\t * @private\n\t\t * @static\n\t\t * @type {Number}\n\t\t */\n\t Tone.TransportEvent._eventId = 0;\n\t /**\n\t\t * Invoke the event callback.\n\t\t * @param {Time} time The AudioContext time in seconds of the event\n\t\t */\n\t Tone.TransportEvent.prototype.invoke = function (time) {\n\t if (this.callback) {\n\t this.callback(time);\n\t if (this._once && this.Transport) {\n\t this.Transport.clear(this.id);\n\t }\n\t }\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.TransportEvent} this\n\t\t */\n\t Tone.TransportEvent.prototype.dispose = function () {\n\t Tone.prototype.dispose.call(this);\n\t this.Transport = null;\n\t this.callback = null;\n\t this.time = null;\n\t return this;\n\t };\n\t return Tone.TransportEvent;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.TransportRepeatEvent is an internal class used by Tone.Transport\n\t\t * to schedule repeat events. This class should not be instantiated directly.\n\t\t * @extends {Tone.TransportEvent}\n\t\t * @param {Object} options\n\t\t */\n\t Tone.TransportRepeatEvent = function (Transport, options) {\n\t Tone.TransportEvent.call(this, Transport, options);\n\t options = Tone.defaultArg(options, Tone.TransportRepeatEvent.defaults);\n\t /**\n\t\t\t * When the event should stop repeating\n\t\t\t * @type {Ticks}\n\t\t\t * @private\n\t\t\t */\n\t this.duration = Tone.Ticks(options.duration);\n\t /**\n\t\t\t * The interval of the repeated event\n\t\t\t * @type {Ticks}\n\t\t\t * @private\n\t\t\t */\n\t this._interval = Tone.Ticks(options.interval);\n\t /**\n\t\t\t * The ID of the current timeline event\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._currentId = -1;\n\t /**\n\t\t\t * The ID of the next timeline event\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._nextId = -1;\n\t /**\n\t\t\t * The time of the next event\n\t\t\t * @type {Ticks}\n\t\t\t * @private\n\t\t\t */\n\t this._nextTick = this.time;\n\t /**\n\t\t\t * a reference to the bound start method\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._boundRestart = this._restart.bind(this);\n\t this.Transport.on('start loopStart', this._boundRestart);\n\t this._restart();\n\t };\n\t Tone.extend(Tone.TransportRepeatEvent, Tone.TransportEvent);\n\t /**\n\t\t * The defaults\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.TransportRepeatEvent.defaults = {\n\t 'duration': Infinity,\n\t 'interval': 1\n\t };\n\t /**\n\t\t * Invoke the callback. Returns the tick time which\n\t\t * the next event should be scheduled at.\n\t\t * @param {Number} time The AudioContext time in seconds of the event\n\t\t */\n\t Tone.TransportRepeatEvent.prototype.invoke = function (time) {\n\t //create more events if necessary\n\t this._createEvents(time);\n\t //call the super class\n\t Tone.TransportEvent.prototype.invoke.call(this, time);\n\t };\n\t /**\n\t\t * Push more events onto the timeline to keep up with the position of the timeline\n\t\t * @private\n\t\t */\n\t Tone.TransportRepeatEvent.prototype._createEvents = function (time) {\n\t // schedule the next event\n\t var ticks = this.Transport.getTicksAtTime(time);\n\t if (ticks >= this.time && ticks >= this._nextTick && this._nextTick + this._interval < this.time + this.duration) {\n\t this._nextTick += this._interval;\n\t this._currentId = this._nextId;\n\t this._nextId = this.Transport.scheduleOnce(this.invoke.bind(this), Tone.Ticks(this._nextTick));\n\t }\n\t };\n\t /**\n\t\t * Push more events onto the timeline to keep up with the position of the timeline\n\t\t * @private\n\t\t */\n\t Tone.TransportRepeatEvent.prototype._restart = function (time) {\n\t this.Transport.clear(this._currentId);\n\t this.Transport.clear(this._nextId);\n\t this._nextTick = this.time;\n\t var ticks = this.Transport.getTicksAtTime(time);\n\t if (ticks > this.time) {\n\t this._nextTick = this.time + Math.ceil((ticks - this.time) / this._interval) * this._interval;\n\t }\n\t this._currentId = this.Transport.scheduleOnce(this.invoke.bind(this), Tone.Ticks(this._nextTick));\n\t this._nextTick += this._interval;\n\t this._nextId = this.Transport.scheduleOnce(this.invoke.bind(this), Tone.Ticks(this._nextTick));\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.TransportRepeatEvent} this\n\t\t */\n\t Tone.TransportRepeatEvent.prototype.dispose = function () {\n\t this.Transport.clear(this._currentId);\n\t this.Transport.clear(this._nextId);\n\t this.Transport.off('start loopStart', this._boundRestart);\n\t this._boundCreateEvents = null;\n\t Tone.TransportEvent.prototype.dispose.call(this);\n\t this.duration = null;\n\t this._interval = null;\n\t return this;\n\t };\n\t return Tone.TransportRepeatEvent;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Transport for timing musical events.\n\t\t * Supports tempo curves and time changes. Unlike browser-based timing (setInterval, requestAnimationFrame)\n\t\t * Tone.Transport timing events pass in the exact time of the scheduled event\n\t\t * in the argument of the callback function. Pass that time value to the object\n\t\t * you're scheduling. <br><br>\n\t\t * A single transport is created for you when the library is initialized.\n\t\t * <br><br>\n\t\t * The transport emits the events: \"start\", \"stop\", \"pause\", and \"loop\" which are\n\t\t * called with the time of that event as the argument.\n\t\t *\n\t\t * @extends {Tone.Emitter}\n\t\t * @singleton\n\t\t * @example\n\t\t * //repeated event every 8th note\n\t\t * Tone.Transport.scheduleRepeat(function(time){\n\t\t * \t//do something with the time\n\t\t * }, \"8n\");\n\t\t * @example\n\t\t * //schedule an event on the 16th measure\n\t\t * Tone.Transport.schedule(function(time){\n\t\t * \t//do something with the time\n\t\t * }, \"16:0:0\");\n\t\t */\n\t Tone.Transport = function () {\n\t Tone.Emitter.call(this);\n\t Tone.getContext(function () {\n\t ///////////////////////////////////////////////////////////////////////\n\t //\tLOOPING\n\t //////////////////////////////////////////////////////////////////////\n\t /**\n\t\t\t\t * \tIf the transport loops or not.\n\t\t\t\t * @type {boolean}\n\t\t\t\t */\n\t this.loop = false;\n\t /**\n\t\t\t\t * \tThe loop start position in ticks\n\t\t\t\t * @type {Ticks}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._loopStart = 0;\n\t /**\n\t\t\t\t * \tThe loop end position in ticks\n\t\t\t\t * @type {Ticks}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._loopEnd = 0;\n\t ///////////////////////////////////////////////////////////////////////\n\t //\tCLOCK/TEMPO\n\t //////////////////////////////////////////////////////////////////////\n\t /**\n\t\t\t\t * Pulses per quarter is the number of ticks per quarter note.\n\t\t\t\t * @private\n\t\t\t\t * @type {Number}\n\t\t\t\t */\n\t this._ppq = TransportConstructor.defaults.PPQ;\n\t /**\n\t\t\t\t * watches the main oscillator for timing ticks\n\t\t\t\t * initially starts at 120bpm\n\t\t\t\t * @private\n\t\t\t\t * @type {Tone.Clock}\n\t\t\t\t */\n\t this._clock = new Tone.Clock({\n\t 'callback': this._processTick.bind(this),\n\t 'frequency': 0\n\t });\n\t this._bindClockEvents();\n\t /**\n\t\t\t\t * The Beats Per Minute of the Transport.\n\t\t\t\t * @type {BPM}\n\t\t\t\t * @signal\n\t\t\t\t * @example\n\t\t\t\t * Tone.Transport.bpm.value = 80;\n\t\t\t\t * //ramp the bpm to 120 over 10 seconds\n\t\t\t\t * Tone.Transport.bpm.rampTo(120, 10);\n\t\t\t\t */\n\t this.bpm = this._clock.frequency;\n\t this.bpm._toUnits = this._toUnits.bind(this);\n\t this.bpm._fromUnits = this._fromUnits.bind(this);\n\t this.bpm.units = Tone.Type.BPM;\n\t this.bpm.value = TransportConstructor.defaults.bpm;\n\t this._readOnly('bpm');\n\t /**\n\t\t\t\t * The time signature, or more accurately the numerator\n\t\t\t\t * of the time signature over a denominator of 4.\n\t\t\t\t * @type {Number}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._timeSignature = TransportConstructor.defaults.timeSignature;\n\t ///////////////////////////////////////////////////////////////////////\n\t //\tTIMELINE EVENTS\n\t //////////////////////////////////////////////////////////////////////\n\t /**\n\t\t\t\t * All the events in an object to keep track by ID\n\t\t\t\t * @type {Object}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._scheduledEvents = {};\n\t /**\n\t\t\t\t * \tThe scheduled events.\n\t\t\t\t * @type {Tone.Timeline}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._timeline = new Tone.Timeline();\n\t /**\n\t\t\t\t * Repeated events\n\t\t\t\t * @type {Array}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._repeatedEvents = new Tone.IntervalTimeline();\n\t /**\n\t\t\t\t * All of the synced Signals\n\t\t\t\t * @private\n\t\t\t\t * @type {Array}\n\t\t\t\t */\n\t this._syncedSignals = [];\n\t ///////////////////////////////////////////////////////////////////////\n\t //\tSWING\n\t //////////////////////////////////////////////////////////////////////\n\t /**\n\t\t\t\t * The subdivision of the swing\n\t\t\t\t * @type {Ticks}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._swingTicks = TransportConstructor.defaults.PPQ / 2;\n\t //8n\n\t /**\n\t\t\t\t * The swing amount\n\t\t\t\t * @type {NormalRange}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._swingAmount = 0;\n\t }.bind(this));\n\t };\n\t Tone.extend(Tone.Transport, Tone.Emitter);\n\t /**\n\t\t * the defaults\n\t\t * @type {Object}\n\t\t * @const\n\t\t * @static\n\t\t */\n\t Tone.Transport.defaults = {\n\t 'bpm': 120,\n\t 'swing': 0,\n\t 'swingSubdivision': '8n',\n\t 'timeSignature': 4,\n\t 'loopStart': 0,\n\t 'loopEnd': '4m',\n\t 'PPQ': 192\n\t };\n\t ///////////////////////////////////////////////////////////////////////////////\n\t //\tTICKS\n\t ///////////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * called on every tick\n\t\t * @param {number} tickTime clock relative tick time\n\t\t * @private\n\t\t */\n\t Tone.Transport.prototype._processTick = function (tickTime, ticks) {\n\t //handle swing\n\t if (this._swingAmount > 0 && ticks % this._ppq !== 0 && //not on a downbeat\n\t ticks % (this._swingTicks * 2) !== 0) {\n\t //add some swing\n\t var progress = ticks % (this._swingTicks * 2) / (this._swingTicks * 2);\n\t var amount = Math.sin(progress * Math.PI) * this._swingAmount;\n\t tickTime += Tone.Ticks(this._swingTicks * 2 / 3).toSeconds() * amount;\n\t }\n\t //do the loop test\n\t if (this.loop) {\n\t if (ticks >= this._loopEnd) {\n\t this.emit('loopEnd', tickTime);\n\t this._clock.setTicksAtTime(this._loopStart, tickTime);\n\t ticks = this._loopStart;\n\t this.emit('loopStart', tickTime, this._clock.getSecondsAtTime(tickTime));\n\t this.emit('loop', tickTime);\n\t }\n\t }\n\t //invoke the timeline events scheduled on this tick\n\t this._timeline.forEachAtTime(ticks, function (event) {\n\t event.invoke(tickTime);\n\t });\n\t };\n\t ///////////////////////////////////////////////////////////////////////////////\n\t //\tSCHEDULABLE EVENTS\n\t ///////////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Schedule an event along the timeline.\n\t\t * @param {Function} callback The callback to be invoked at the time.\n\t\t * @param {TransportTime} time The time to invoke the callback at.\n\t\t * @return {Number} The id of the event which can be used for canceling the event.\n\t\t * @example\n\t\t * //trigger the callback when the Transport reaches the desired time\n\t\t * Tone.Transport.schedule(function(time){\n\t\t * \tenvelope.triggerAttack(time);\n\t\t * }, \"128i\");\n\t\t */\n\t Tone.Transport.prototype.schedule = function (callback, time) {\n\t var event = new Tone.TransportEvent(this, {\n\t 'time': Tone.TransportTime(time),\n\t 'callback': callback\n\t });\n\t return this._addEvent(event, this._timeline);\n\t };\n\t /**\n\t\t * Schedule a repeated event along the timeline. The event will fire\n\t\t * at the `interval` starting at the `startTime` and for the specified\n\t\t * `duration`.\n\t\t * @param {Function} callback The callback to invoke.\n\t\t * @param {Time} interval The duration between successive\n\t\t * callbacks. Must be a positive number.\n\t\t * @param {TransportTime=} startTime When along the timeline the events should\n\t\t * start being invoked.\n\t\t * @param {Time} [duration=Infinity] How long the event should repeat.\n\t\t * @return {Number} The ID of the scheduled event. Use this to cancel\n\t\t * the event.\n\t\t * @example\n\t\t * //a callback invoked every eighth note after the first measure\n\t\t * Tone.Transport.scheduleRepeat(callback, \"8n\", \"1m\");\n\t\t */\n\t Tone.Transport.prototype.scheduleRepeat = function (callback, interval, startTime, duration) {\n\t var event = new Tone.TransportRepeatEvent(this, {\n\t 'callback': callback,\n\t 'interval': Tone.Time(interval),\n\t 'time': Tone.TransportTime(startTime),\n\t 'duration': Tone.Time(Tone.defaultArg(duration, Infinity))\n\t });\n\t //kick it off if the Transport is started\n\t return this._addEvent(event, this._repeatedEvents);\n\t };\n\t /**\n\t\t * Schedule an event that will be removed after it is invoked.\n\t\t * Note that if the given time is less than the current transport time,\n\t\t * the event will be invoked immediately.\n\t\t * @param {Function} callback The callback to invoke once.\n\t\t * @param {TransportTime} time The time the callback should be invoked.\n\t\t * @returns {Number} The ID of the scheduled event.\n\t\t */\n\t Tone.Transport.prototype.scheduleOnce = function (callback, time) {\n\t var event = new Tone.TransportEvent(this, {\n\t 'time': Tone.TransportTime(time),\n\t 'callback': callback,\n\t 'once': true\n\t });\n\t return this._addEvent(event, this._timeline);\n\t };\n\t /**\n\t\t * Clear the passed in event id from the timeline\n\t\t * @param {Number} eventId The id of the event.\n\t\t * @returns {Tone.Transport} this\n\t\t */\n\t Tone.Transport.prototype.clear = function (eventId) {\n\t if (this._scheduledEvents.hasOwnProperty(eventId)) {\n\t var item = this._scheduledEvents[eventId.toString()];\n\t item.timeline.remove(item.event);\n\t item.event.dispose();\n\t delete this._scheduledEvents[eventId.toString()];\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Add an event to the correct timeline. Keep track of the\n\t\t * timeline it was added to.\n\t\t * @param {Tone.TransportEvent}\tevent\n\t\t * @param {Tone.Timeline} timeline\n\t\t * @returns {Number} the event id which was just added\n\t\t * @private\n\t\t */\n\t Tone.Transport.prototype._addEvent = function (event, timeline) {\n\t this._scheduledEvents[event.id.toString()] = {\n\t 'event': event,\n\t 'timeline': timeline\n\t };\n\t timeline.add(event);\n\t return event.id;\n\t };\n\t /**\n\t\t * Remove scheduled events from the timeline after\n\t\t * the given time. Repeated events will be removed\n\t\t * if their startTime is after the given time\n\t\t * @param {TransportTime} [after=0] Clear all events after\n\t\t * this time.\n\t\t * @returns {Tone.Transport} this\n\t\t */\n\t Tone.Transport.prototype.cancel = function (after) {\n\t after = Tone.defaultArg(after, 0);\n\t after = this.toTicks(after);\n\t this._timeline.forEachFrom(after, function (event) {\n\t this.clear(event.id);\n\t }.bind(this));\n\t this._repeatedEvents.forEachFrom(after, function (event) {\n\t this.clear(event.id);\n\t }.bind(this));\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////////\n\t //\tSTART/STOP/PAUSE\n\t ///////////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Bind start/stop/pause events from the clock and emit them.\n\t\t * @private\n\t\t */\n\t Tone.Transport.prototype._bindClockEvents = function () {\n\t this._clock.on('start', function (time, offset) {\n\t offset = Tone.Ticks(offset).toSeconds();\n\t this.emit('start', time, offset);\n\t }.bind(this));\n\t this._clock.on('stop', function (time) {\n\t this.emit('stop', time);\n\t }.bind(this));\n\t this._clock.on('pause', function (time) {\n\t this.emit('pause', time);\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Returns the playback state of the source, either \"started\", \"stopped\", or \"paused\"\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.Transport#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'state', {\n\t get: function () {\n\t return this._clock.getStateAtTime(this.now());\n\t }\n\t });\n\t /**\n\t\t * Start the transport and all sources synced to the transport.\n\t\t * @param {Time} [time=now] The time when the transport should start.\n\t\t * @param {TransportTime=} offset The timeline offset to start the transport.\n\t\t * @returns {Tone.Transport} this\n\t\t * @example\n\t\t * //start the transport in one second starting at beginning of the 5th measure.\n\t\t * Tone.Transport.start(\"+1\", \"4:0:0\");\n\t\t */\n\t Tone.Transport.prototype.start = function (time, offset) {\n\t //start the clock\n\t if (Tone.isDefined(offset)) {\n\t offset = this.toTicks(offset);\n\t }\n\t this._clock.start(time, offset);\n\t return this;\n\t };\n\t /**\n\t\t * Stop the transport and all sources synced to the transport.\n\t\t * @param {Time} [time=now] The time when the transport should stop.\n\t\t * @returns {Tone.Transport} this\n\t\t * @example\n\t\t * Tone.Transport.stop();\n\t\t */\n\t Tone.Transport.prototype.stop = function (time) {\n\t this._clock.stop(time);\n\t return this;\n\t };\n\t /**\n\t\t * Pause the transport and all sources synced to the transport.\n\t\t * @param {Time} [time=now]\n\t\t * @returns {Tone.Transport} this\n\t\t */\n\t Tone.Transport.prototype.pause = function (time) {\n\t this._clock.pause(time);\n\t return this;\n\t };\n\t /**\n\t\t * Toggle the current state of the transport. If it is\n\t\t * started, it will stop it, otherwise it will start the Transport.\n\t\t * @param {Time=} time The time of the event\n\t\t * @return {Tone.Transport} this\n\t\t */\n\t Tone.Transport.prototype.toggle = function (time) {\n\t time = this.toSeconds(time);\n\t if (this._clock.getStateAtTime(time) !== Tone.State.Started) {\n\t this.start(time);\n\t } else {\n\t this.stop(time);\n\t }\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////////\n\t //\tSETTERS/GETTERS\n\t ///////////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * The time signature as just the numerator over 4.\n\t\t * For example 4/4 would be just 4 and 6/8 would be 3.\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Number|Array}\n\t\t * @name timeSignature\n\t\t * @example\n\t\t * //common time\n\t\t * Tone.Transport.timeSignature = 4;\n\t\t * // 7/8\n\t\t * Tone.Transport.timeSignature = [7, 8];\n\t\t * //this will be reduced to a single number\n\t\t * Tone.Transport.timeSignature; //returns 3.5\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'timeSignature', {\n\t get: function () {\n\t return this._timeSignature;\n\t },\n\t set: function (timeSig) {\n\t if (Tone.isArray(timeSig)) {\n\t timeSig = timeSig[0] / timeSig[1] * 4;\n\t }\n\t this._timeSignature = timeSig;\n\t }\n\t });\n\t /**\n\t\t * When the Tone.Transport.loop = true, this is the starting position of the loop.\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Time}\n\t\t * @name loopStart\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'loopStart', {\n\t get: function () {\n\t return Tone.Ticks(this._loopStart).toSeconds();\n\t },\n\t set: function (startPosition) {\n\t this._loopStart = this.toTicks(startPosition);\n\t }\n\t });\n\t /**\n\t\t * When the Tone.Transport.loop = true, this is the ending position of the loop.\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Time}\n\t\t * @name loopEnd\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'loopEnd', {\n\t get: function () {\n\t return Tone.Ticks(this._loopEnd).toSeconds();\n\t },\n\t set: function (endPosition) {\n\t this._loopEnd = this.toTicks(endPosition);\n\t }\n\t });\n\t /**\n\t\t * Set the loop start and stop at the same time.\n\t\t * @param {TransportTime} startPosition\n\t\t * @param {TransportTime} endPosition\n\t\t * @returns {Tone.Transport} this\n\t\t * @example\n\t\t * //loop over the first measure\n\t\t * Tone.Transport.setLoopPoints(0, \"1m\");\n\t\t * Tone.Transport.loop = true;\n\t\t */\n\t Tone.Transport.prototype.setLoopPoints = function (startPosition, endPosition) {\n\t this.loopStart = startPosition;\n\t this.loopEnd = endPosition;\n\t return this;\n\t };\n\t /**\n\t\t * The swing value. Between 0-1 where 1 equal to\n\t\t * the note + half the subdivision.\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {NormalRange}\n\t\t * @name swing\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'swing', {\n\t get: function () {\n\t return this._swingAmount;\n\t },\n\t set: function (amount) {\n\t //scale the values to a normal range\n\t this._swingAmount = amount;\n\t }\n\t });\n\t /**\n\t\t * Set the subdivision which the swing will be applied to.\n\t\t * The default value is an 8th note. Value must be less\n\t\t * than a quarter note.\n\t\t *\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Time}\n\t\t * @name swingSubdivision\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'swingSubdivision', {\n\t get: function () {\n\t return Tone.Ticks(this._swingTicks).toNotation();\n\t },\n\t set: function (subdivision) {\n\t this._swingTicks = this.toTicks(subdivision);\n\t }\n\t });\n\t /**\n\t\t * The Transport's position in Bars:Beats:Sixteenths.\n\t\t * Setting the value will jump to that position right away.\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {BarsBeatsSixteenths}\n\t\t * @name position\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'position', {\n\t get: function () {\n\t var now = this.now();\n\t var ticks = this._clock.getTicksAtTime(now);\n\t return Tone.Ticks(ticks).toBarsBeatsSixteenths();\n\t },\n\t set: function (progress) {\n\t var ticks = this.toTicks(progress);\n\t this.ticks = ticks;\n\t }\n\t });\n\t /**\n\t\t * The Transport's position in seconds\n\t\t * Setting the value will jump to that position right away.\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Seconds}\n\t\t * @name seconds\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'seconds', {\n\t get: function () {\n\t return this._clock.seconds;\n\t },\n\t set: function (s) {\n\t var now = this.now();\n\t var ticks = this.bpm.timeToTicks(s, now);\n\t this.ticks = ticks;\n\t }\n\t });\n\t /**\n\t\t * The Transport's loop position as a normalized value. Always\n\t\t * returns 0 if the transport if loop is not true.\n\t\t * @memberOf Tone.Transport#\n\t\t * @name progress\n\t\t * @type {NormalRange}\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'progress', {\n\t get: function () {\n\t if (this.loop) {\n\t var now = this.now();\n\t var ticks = this._clock.getTicksAtTime(now);\n\t return (ticks - this._loopStart) / (this._loopEnd - this._loopStart);\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The transports current tick position.\n\t\t *\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Ticks}\n\t\t * @name ticks\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'ticks', {\n\t get: function () {\n\t return this._clock.ticks;\n\t },\n\t set: function (t) {\n\t if (this._clock.ticks !== t) {\n\t var now = this.now();\n\t //stop everything synced to the transport\n\t if (this.state === Tone.State.Started) {\n\t this.emit('stop', now);\n\t this._clock.setTicksAtTime(t, now);\n\t //restart it with the new time\n\t this.emit('start', now, this.seconds);\n\t } else {\n\t this._clock.setTicksAtTime(t, now);\n\t }\n\t }\n\t }\n\t });\n\t /**\n\t\t * Get the clock's ticks at the given time.\n\t\t * @param {Time} time When to get the tick value\n\t\t * @return {Ticks} The tick value at the given time.\n\t\t */\n\t Tone.Transport.prototype.getTicksAtTime = function (time) {\n\t return Math.round(this._clock.getTicksAtTime(time));\n\t };\n\t /**\n\t\t * Return the elapsed seconds at the given time.\n\t\t * @param {Time} time When to get the elapsed seconds\n\t\t * @return {Seconds} The number of elapsed seconds\n\t\t */\n\t Tone.Transport.prototype.getSecondsAtTime = function (time) {\n\t return this._clock.getSecondsAtTime(time);\n\t };\n\t /**\n\t\t * Pulses Per Quarter note. This is the smallest resolution\n\t\t * the Transport timing supports. This should be set once\n\t\t * on initialization and not set again. Changing this value\n\t\t * after other objects have been created can cause problems.\n\t\t *\n\t\t * @memberOf Tone.Transport#\n\t\t * @type {Number}\n\t\t * @name PPQ\n\t\t */\n\t Object.defineProperty(Tone.Transport.prototype, 'PPQ', {\n\t get: function () {\n\t return this._ppq;\n\t },\n\t set: function (ppq) {\n\t var bpm = this.bpm.value;\n\t this._ppq = ppq;\n\t this.bpm.value = bpm;\n\t }\n\t });\n\t /**\n\t\t * Convert from BPM to frequency (factoring in PPQ)\n\t\t * @param {BPM} bpm The BPM value to convert to frequency\n\t\t * @return {Frequency} The BPM as a frequency with PPQ factored in.\n\t\t * @private\n\t\t */\n\t Tone.Transport.prototype._fromUnits = function (bpm) {\n\t return 1 / (60 / bpm / this.PPQ);\n\t };\n\t /**\n\t\t * Convert from frequency (with PPQ) into BPM\n\t\t * @param {Frequency} freq The clocks frequency to convert to BPM\n\t\t * @return {BPM} The frequency value as BPM.\n\t\t * @private\n\t\t */\n\t Tone.Transport.prototype._toUnits = function (freq) {\n\t return freq / this.PPQ * 60;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////////\n\t //\tSYNCING\n\t ///////////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Returns the time aligned to the next subdivision\n\t\t * of the Transport. If the Transport is not started,\n\t\t * it will return 0.\n\t\t * Note: this will not work precisely during tempo ramps.\n\t\t * @param {Time} subdivision The subdivision to quantize to\n\t\t * @return {Number} The context time of the next subdivision.\n\t\t * @example\n\t\t * Tone.Transport.start(); //the transport must be started\n\t\t * Tone.Transport.nextSubdivision(\"4n\");\n\t\t */\n\t Tone.Transport.prototype.nextSubdivision = function (subdivision) {\n\t subdivision = this.toTicks(subdivision);\n\t if (this.state !== Tone.State.Started) {\n\t //if the transport's not started, return 0\n\t return 0;\n\t } else {\n\t var now = this.now();\n\t //the remainder of the current ticks and the subdivision\n\t var transportPos = this.getTicksAtTime(now);\n\t var remainingTicks = subdivision - transportPos % subdivision;\n\t return this._clock.nextTickTime(remainingTicks, now);\n\t }\n\t };\n\t /**\n\t\t * Attaches the signal to the tempo control signal so that\n\t\t * any changes in the tempo will change the signal in the same\n\t\t * ratio.\n\t\t *\n\t\t * @param {Tone.Signal} signal\n\t\t * @param {number=} ratio Optionally pass in the ratio between\n\t\t * the two signals. Otherwise it will be computed\n\t\t * based on their current values.\n\t\t * @returns {Tone.Transport} this\n\t\t */\n\t Tone.Transport.prototype.syncSignal = function (signal, ratio) {\n\t if (!ratio) {\n\t //get the sync ratio\n\t var now = this.now();\n\t if (signal.getValueAtTime(now) !== 0) {\n\t ratio = signal.getValueAtTime(now) / this.bpm.getValueAtTime(now);\n\t } else {\n\t ratio = 0;\n\t }\n\t }\n\t var ratioSignal = new Tone.Gain(ratio);\n\t this.bpm.chain(ratioSignal, signal._param);\n\t this._syncedSignals.push({\n\t 'ratio': ratioSignal,\n\t 'signal': signal,\n\t 'initial': signal.value\n\t });\n\t signal.value = 0;\n\t return this;\n\t };\n\t /**\n\t\t * Unsyncs a previously synced signal from the transport's control.\n\t\t * See Tone.Transport.syncSignal.\n\t\t * @param {Tone.Signal} signal\n\t\t * @returns {Tone.Transport} this\n\t\t */\n\t Tone.Transport.prototype.unsyncSignal = function (signal) {\n\t for (var i = this._syncedSignals.length - 1; i >= 0; i--) {\n\t var syncedSignal = this._syncedSignals[i];\n\t if (syncedSignal.signal === signal) {\n\t syncedSignal.ratio.dispose();\n\t syncedSignal.signal.value = syncedSignal.initial;\n\t this._syncedSignals.splice(i, 1);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Transport} this\n\t\t * @private\n\t\t */\n\t Tone.Transport.prototype.dispose = function () {\n\t Tone.Emitter.prototype.dispose.call(this);\n\t this._clock.dispose();\n\t this._clock = null;\n\t this._writable('bpm');\n\t this.bpm = null;\n\t this._timeline.dispose();\n\t this._timeline = null;\n\t this._repeatedEvents.dispose();\n\t this._repeatedEvents = null;\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////////\n\t //\tINITIALIZATION\n\t ///////////////////////////////////////////////////////////////////////////////\n\t var TransportConstructor = Tone.Transport;\n\t Tone.Transport = new TransportConstructor();\n\t Tone.Context.on('init', function (context) {\n\t if (context.Transport instanceof TransportConstructor) {\n\t Tone.Transport = context.Transport;\n\t } else {\n\t Tone.Transport = new TransportConstructor();\n\t }\n\t //store the Transport on the context so it can be retrieved later\n\t context.Transport = Tone.Transport;\n\t });\n\t Tone.Context.on('close', function (context) {\n\t if (context.Transport instanceof TransportConstructor) {\n\t context.Transport.dispose();\n\t }\n\t });\n\t return Tone.Transport;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Volume is a simple volume node, useful for creating a volume fader.\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {Decibels} [volume=0] the initial volume\n\t\t * @example\n\t\t * var vol = new Tone.Volume(-12);\n\t\t * instrument.chain(vol, Tone.Master);\n\t\t */\n\t Tone.Volume = function () {\n\t var options = Tone.defaults(arguments, ['volume'], Tone.Volume);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * the output node\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.output = this.input = new Tone.Gain(options.volume, Tone.Type.Decibels);\n\t /**\n\t\t\t * The unmuted volume\n\t\t\t * @type {Decibels}\n\t\t\t * @private\n\t\t\t */\n\t this._unmutedVolume = options.volume;\n\t /**\n\t\t\t * The volume control in decibels.\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.volume = this.output.gain;\n\t this._readOnly('volume');\n\t //set the mute initially\n\t this.mute = options.mute;\n\t };\n\t Tone.extend(Tone.Volume, Tone.AudioNode);\n\t /**\n\t\t * Defaults\n\t\t * @type {Object}\n\t\t * @const\n\t\t * @static\n\t\t */\n\t Tone.Volume.defaults = {\n\t 'volume': 0,\n\t 'mute': false\n\t };\n\t /**\n\t\t * Mute the output.\n\t\t * @memberOf Tone.Volume#\n\t\t * @type {boolean}\n\t\t * @name mute\n\t\t * @example\n\t\t * //mute the output\n\t\t * volume.mute = true;\n\t\t */\n\t Object.defineProperty(Tone.Volume.prototype, 'mute', {\n\t get: function () {\n\t return this.volume.value === -Infinity;\n\t },\n\t set: function (mute) {\n\t if (!this.mute && mute) {\n\t this._unmutedVolume = this.volume.value;\n\t //maybe it should ramp here?\n\t this.volume.value = -Infinity;\n\t } else if (this.mute && !mute) {\n\t this.volume.value = this._unmutedVolume;\n\t }\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Volume} this\n\t\t */\n\t Tone.Volume.prototype.dispose = function () {\n\t this.input.dispose();\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable('volume');\n\t this.volume.dispose();\n\t this.volume = null;\n\t return this;\n\t };\n\t return Tone.Volume;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A single master output which is connected to the\n\t\t * AudioDestinationNode (aka your speakers).\n\t\t * It provides useful conveniences such as the ability\n\t\t * to set the volume and mute the entire application.\n\t\t * It also gives you the ability to apply master effects to your application.\n\t\t * <br><br>\n\t\t * Like Tone.Transport, A single Tone.Master is created\n\t\t * on initialization and you do not need to explicitly construct one.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone}\n\t\t * @singleton\n\t\t * @example\n\t\t * //the audio will go from the oscillator to the speakers\n\t\t * oscillator.connect(Tone.Master);\n\t\t * //a convenience for connecting to the master output is also provided:\n\t\t * oscillator.toMaster();\n\t\t * //the above two examples are equivalent.\n\t\t */\n\t Tone.Master = function () {\n\t Tone.AudioNode.call(this);\n\t Tone.getContext(function () {\n\t this.createInsOuts(1, 0);\n\t /**\n\t\t\t\t * The private volume node\n\t\t\t\t * @type {Tone.Volume}\n\t\t\t\t * @private\n\t\t\t\t */\n\t this._volume = this.output = new Tone.Volume();\n\t /**\n\t\t\t\t * The volume of the master output.\n\t\t\t\t * @type {Decibels}\n\t\t\t\t * @signal\n\t\t\t\t */\n\t this.volume = this._volume.volume;\n\t this._readOnly('volume');\n\t //connections\n\t this.input.chain(this.output, this.context.destination);\n\t }.bind(this));\n\t };\n\t Tone.extend(Tone.Master, Tone.AudioNode);\n\t /**\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Master.defaults = {\n\t 'volume': 0,\n\t 'mute': false\n\t };\n\t /**\n\t\t * Mute the output.\n\t\t * @memberOf Tone.Master#\n\t\t * @type {boolean}\n\t\t * @name mute\n\t\t * @example\n\t\t * //mute the output\n\t\t * Tone.Master.mute = true;\n\t\t */\n\t Object.defineProperty(Tone.Master.prototype, 'mute', {\n\t get: function () {\n\t return this._volume.mute;\n\t },\n\t set: function (mute) {\n\t this._volume.mute = mute;\n\t }\n\t });\n\t /**\n\t\t * Add a master effects chain. NOTE: this will disconnect any nodes which were previously\n\t\t * chained in the master effects chain.\n\t\t * @param {AudioNode|Tone} args... All arguments will be connected in a row\n\t\t * and the Master will be routed through it.\n\t\t * @return {Tone.Master} this\n\t\t * @example\n\t\t * //some overall compression to keep the levels in check\n\t\t * var masterCompressor = new Tone.Compressor({\n\t\t * \t\"threshold\" : -6,\n\t\t * \t\"ratio\" : 3,\n\t\t * \t\"attack\" : 0.5,\n\t\t * \t\"release\" : 0.1\n\t\t * });\n\t\t * //give a little boost to the lows\n\t\t * var lowBump = new Tone.Filter(200, \"lowshelf\");\n\t\t * //route everything through the filter\n\t\t * //and compressor before going to the speakers\n\t\t * Tone.Master.chain(lowBump, masterCompressor);\n\t\t */\n\t Tone.Master.prototype.chain = function () {\n\t this.input.disconnect();\n\t this.input.chain.apply(this.input, arguments);\n\t arguments[arguments.length - 1].connect(this.output);\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Master} this\n\t\t */\n\t Tone.Master.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable('volume');\n\t this._volume.dispose();\n\t this._volume = null;\n\t this.volume = null;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t //\tAUGMENT TONE's PROTOTYPE\n\t ///////////////////////////////////////////////////////////////////////////\n\t /**\n\t\t * Connect 'this' to the master output. Shorthand for this.connect(Tone.Master)\n\t\t * @returns {Tone.AudioNode} this\n\t\t * @example\n\t\t * //connect an oscillator to the master output\n\t\t * var osc = new Tone.Oscillator().toMaster();\n\t\t */\n\t Tone.AudioNode.prototype.toMaster = function () {\n\t this.connect(Tone.Master);\n\t return this;\n\t };\n\t if (window.AudioNode) {\n\t // Also augment AudioNode's prototype to include toMaster as a convenience\n\t AudioNode.prototype.toMaster = function () {\n\t this.connect(Tone.Master);\n\t return this;\n\t };\n\t }\n\t /**\n\t\t * initialize the module and listen for new audio contexts\n\t\t */\n\t var MasterConstructor = Tone.Master;\n\t Tone.Master = new MasterConstructor();\n\t Tone.Context.on('init', function (context) {\n\t // if it already exists, just restore it\n\t if (context.Master instanceof MasterConstructor) {\n\t Tone.Master = context.Master;\n\t } else {\n\t Tone.Master = new MasterConstructor();\n\t }\n\t context.Master = Tone.Master;\n\t });\n\t Tone.Context.on('close', function (context) {\n\t if (context.Master instanceof MasterConstructor) {\n\t context.Master.dispose();\n\t }\n\t });\n\t return Tone.Master;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Base class for sources. Sources have start/stop methods\n\t\t * and the ability to be synced to the\n\t\t * start/stop of Tone.Transport.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @example\n\t\t * //Multiple state change events can be chained together,\n\t\t * //but must be set in the correct order and with ascending times\n\t\t *\n\t\t * // OK\n\t\t * state.start().stop(\"+0.2\");\n\t\t * // AND\n\t\t * state.start().stop(\"+0.2\").start(\"+0.4\").stop(\"+0.7\")\n\t\t *\n\t\t * // BAD\n\t\t * state.stop(\"+0.2\").start();\n\t\t * // OR\n\t\t * state.start(\"+0.3\").stop(\"+0.2\");\n\t\t *\n\t\t */\n\t Tone.Source = function (options) {\n\t options = Tone.defaultArg(options, Tone.Source.defaults);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The output volume node\n\t\t\t * @type {Tone.Volume}\n\t\t\t * @private\n\t\t\t */\n\t this._volume = this.output = new Tone.Volume(options.volume);\n\t /**\n\t\t\t * The volume of the output in decibels.\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * source.volume.value = -6;\n\t\t\t */\n\t this.volume = this._volume.volume;\n\t this._readOnly('volume');\n\t /**\n\t\t\t * \tKeep track of the scheduled state.\n\t\t\t * @type {Tone.TimelineState}\n\t\t\t * @private\n\t\t\t */\n\t this._state = new Tone.TimelineState(Tone.State.Stopped);\n\t this._state.memory = 100;\n\t /**\n\t\t\t * The synced `start` callback function from the transport\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._synced = false;\n\t /**\n\t\t\t * Keep track of all of the scheduled event ids\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._scheduled = [];\n\t //make the output explicitly stereo\n\t this._volume.output.output.channelCount = 2;\n\t this._volume.output.output.channelCountMode = 'explicit';\n\t //mute initially\n\t this.mute = options.mute;\n\t };\n\t Tone.extend(Tone.Source, Tone.AudioNode);\n\t /**\n\t\t * The default parameters\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Source.defaults = {\n\t 'volume': 0,\n\t 'mute': false\n\t };\n\t /**\n\t\t * Returns the playback state of the source, either \"started\" or \"stopped\".\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.Source#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.Source.prototype, 'state', {\n\t get: function () {\n\t if (this._synced) {\n\t if (Tone.Transport.state === Tone.State.Started) {\n\t return this._state.getValueAtTime(Tone.Transport.seconds);\n\t } else {\n\t return Tone.State.Stopped;\n\t }\n\t } else {\n\t return this._state.getValueAtTime(this.now());\n\t }\n\t }\n\t });\n\t /**\n\t\t * Mute the output.\n\t\t * @memberOf Tone.Source#\n\t\t * @type {boolean}\n\t\t * @name mute\n\t\t * @example\n\t\t * //mute the output\n\t\t * source.mute = true;\n\t\t */\n\t Object.defineProperty(Tone.Source.prototype, 'mute', {\n\t get: function () {\n\t return this._volume.mute;\n\t },\n\t set: function (mute) {\n\t this._volume.mute = mute;\n\t }\n\t });\n\t //overwrite these functions\n\t Tone.Source.prototype._start = Tone.noOp;\n\t Tone.Source.prototype.restart = Tone.noOp;\n\t Tone.Source.prototype._stop = Tone.noOp;\n\t /**\n\t\t * Start the source at the specified time. If no time is given,\n\t\t * start the source now.\n\t\t * @param {Time} [time=now] When the source should be started.\n\t\t * @returns {Tone.Source} this\n\t\t * @example\n\t\t * source.start(\"+0.5\"); //starts the source 0.5 seconds from now\n\t\t */\n\t Tone.Source.prototype.start = function (time, offset, duration) {\n\t if (Tone.isUndef(time) && this._synced) {\n\t time = Tone.Transport.seconds;\n\t } else {\n\t time = this.toSeconds(time);\n\t }\n\t //if it's started, stop it and restart it\n\t if (this._state.getValueAtTime(time) === Tone.State.Started) {\n\t this._state.cancel(time);\n\t this._state.setStateAtTime(Tone.State.Started, time);\n\t this.restart(time, offset, duration);\n\t } else {\n\t this._state.setStateAtTime(Tone.State.Started, time);\n\t if (this._synced) {\n\t // add the offset time to the event\n\t var event = this._state.get(time);\n\t event.offset = Tone.defaultArg(offset, 0);\n\t event.duration = duration;\n\t var sched = Tone.Transport.schedule(function (t) {\n\t this._start(t, offset, duration);\n\t }.bind(this), time);\n\t this._scheduled.push(sched);\n\t //if it's already started\n\t if (Tone.Transport.state === Tone.State.Started) {\n\t this._syncedStart(this.now(), Tone.Transport.seconds);\n\t }\n\t } else {\n\t this._start.apply(this, arguments);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Stop the source at the specified time. If no time is given,\n\t\t * stop the source now.\n\t\t * @param {Time} [time=now] When the source should be stopped.\n\t\t * @returns {Tone.Source} this\n\t\t * @example\n\t\t * source.stop(); // stops the source immediately\n\t\t */\n\t Tone.Source.prototype.stop = function (time) {\n\t if (Tone.isUndef(time) && this._synced) {\n\t time = Tone.Transport.seconds;\n\t } else {\n\t time = this.toSeconds(time);\n\t }\n\t if (!this._synced) {\n\t this._stop.apply(this, arguments);\n\t } else {\n\t var sched = Tone.Transport.schedule(this._stop.bind(this), time);\n\t this._scheduled.push(sched);\n\t }\n\t this._state.cancel(time);\n\t this._state.setStateAtTime(Tone.State.Stopped, time);\n\t return this;\n\t };\n\t /**\n\t\t * Sync the source to the Transport so that all subsequent\n\t\t * calls to `start` and `stop` are synced to the TransportTime\n\t\t * instead of the AudioContext time.\n\t\t *\n\t\t * @returns {Tone.Source} this\n\t\t * @example\n\t\t * //sync the source so that it plays between 0 and 0.3 on the Transport's timeline\n\t\t * source.sync().start(0).stop(0.3);\n\t\t * //start the transport.\n\t\t * Tone.Transport.start();\n\t\t *\n\t\t * @example\n\t\t * //start the transport with an offset and the sync'ed sources\n\t\t * //will start in the correct position\n\t\t * source.sync().start(0.1);\n\t\t * //the source will be invoked with an offset of 0.4\n\t\t * Tone.Transport.start(\"+0.5\", 0.5);\n\t\t */\n\t Tone.Source.prototype.sync = function () {\n\t this._synced = true;\n\t this._syncedStart = function (time, offset) {\n\t if (offset > 0) {\n\t // get the playback state at that time\n\t var stateEvent = this._state.get(offset);\n\t // listen for start events which may occur in the middle of the sync'ed time\n\t if (stateEvent && stateEvent.state === Tone.State.Started && stateEvent.time !== offset) {\n\t // get the offset\n\t var startOffset = offset - this.toSeconds(stateEvent.time);\n\t var duration;\n\t if (stateEvent.duration) {\n\t duration = this.toSeconds(stateEvent.duration) - startOffset;\n\t }\n\t this._start(time, this.toSeconds(stateEvent.offset) + startOffset, duration);\n\t }\n\t }\n\t }.bind(this);\n\t this._syncedStop = function (time) {\n\t var seconds = Tone.Transport.getSecondsAtTime(Math.max(time - this.sampleTime, 0));\n\t if (this._state.getValueAtTime(seconds) === Tone.State.Started) {\n\t this._stop(time);\n\t }\n\t }.bind(this);\n\t Tone.Transport.on('start loopStart', this._syncedStart);\n\t Tone.Transport.on('stop pause loopEnd', this._syncedStop);\n\t return this;\n\t };\n\t /**\n\t\t * Unsync the source to the Transport. See Tone.Source.sync\n\t\t * @returns {Tone.Source} this\n\t\t */\n\t Tone.Source.prototype.unsync = function () {\n\t if (this._synced) {\n\t Tone.Transport.off('stop pause loopEnd', this._syncedStop);\n\t Tone.Transport.off('start loopStart', this._syncedStart);\n\t }\n\t this._synced = false;\n\t // clear all of the scheduled ids\n\t for (var i = 0; i < this._scheduled.length; i++) {\n\t var id = this._scheduled[i];\n\t Tone.Transport.clear(id);\n\t }\n\t this._scheduled = [];\n\t this._state.cancel(0);\n\t return this;\n\t };\n\t /**\n\t\t *\tClean up.\n\t\t * @return {Tone.Source} this\n\t\t */\n\t Tone.Source.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.unsync();\n\t this._scheduled = null;\n\t this._writable('volume');\n\t this._volume.dispose();\n\t this._volume = null;\n\t this.volume = null;\n\t this._state.dispose();\n\t this._state = null;\n\t };\n\t return Tone.Source;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * AudioBuffer.copyTo/FromChannel polyfill\n\t\t * @private\n\t\t */\n\t if (Tone.supported) {\n\t if (!AudioBuffer.prototype.copyToChannel) {\n\t AudioBuffer.prototype.copyToChannel = function (src, chanNum, start) {\n\t var channel = this.getChannelData(chanNum);\n\t start = start || 0;\n\t for (var i = 0; i < channel.length; i++) {\n\t channel[i + start] = src[i];\n\t }\n\t };\n\t AudioBuffer.prototype.copyFromChannel = function (dest, chanNum, start) {\n\t var channel = this.getChannelData(chanNum);\n\t start = start || 0;\n\t for (var i = 0; i < dest.length; i++) {\n\t dest[i] = channel[i + start];\n\t }\n\t };\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Buffer loading and storage. Tone.Buffer is used internally by all\n\t\t * classes that make requests for audio files such as Tone.Player,\n\t\t * Tone.Sampler and Tone.Convolver.\n\t\t *\n\t\t * Aside from load callbacks from individual buffers, Tone.Buffer\n\t\t * \t\tprovides events which keep track of the loading progress\n\t\t * \t\tof _all_ of the buffers. These are Tone.Buffer.on(\"load\" / \"progress\" / \"error\")\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone}\n\t\t * @param {AudioBuffer|String} url The url to load, or the audio buffer to set.\n\t\t * @param {Function=} onload A callback which is invoked after the buffer is loaded.\n\t\t * It's recommended to use `Tone.Buffer.on('load', callback)` instead\n\t\t * since it will give you a callback when _all_ buffers are loaded.\n\t\t * @param {Function=} onerror The callback to invoke if there is an error\n\t\t * @example\n\t\t * var buffer = new Tone.Buffer(\"path/to/sound.mp3\", function(){\n\t\t * \t//the buffer is now available.\n\t\t * \tvar buff = buffer.get();\n\t\t * });\n\t\t * @example\n\t\t * //can load provide fallback extension types if the first type is not supported.\n\t\t * var buffer = new Tone.Buffer(\"path/to/sound.[mp3|ogg|wav]\");\n\t\t */\n\t Tone.Buffer = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'url',\n\t 'onload',\n\t 'onerror'\n\t ], Tone.Buffer);\n\t Tone.call(this);\n\t /**\n\t\t\t * stores the loaded AudioBuffer\n\t\t\t * @type {AudioBuffer}\n\t\t\t * @private\n\t\t\t */\n\t this._buffer = null;\n\t /**\n\t\t\t * indicates if the buffer should be reversed or not\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t this._reversed = options.reverse;\n\t /**\n\t\t\t * The XHR\n\t\t\t * @type {XMLHttpRequest}\n\t\t\t * @private\n\t\t\t */\n\t this._xhr = null;\n\t /**\n\t\t\t * Private callback when the buffer is loaded.\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._onload = Tone.noOp;\n\t if (options.url instanceof AudioBuffer || options.url instanceof Tone.Buffer) {\n\t this.set(options.url);\n\t // invoke the onload callback\n\t if (options.onload) {\n\t if (this.loaded) {\n\t options.onload(this);\n\t } else {\n\t this._onload = options.onload;\n\t }\n\t }\n\t } else if (Tone.isString(options.url)) {\n\t this.load(options.url).then(options.onload).catch(options.onerror);\n\t }\n\t };\n\t Tone.extend(Tone.Buffer);\n\t /**\n\t\t * the default parameters\n\t\t * @type {Object}\n\t\t */\n\t Tone.Buffer.defaults = {\n\t 'url': undefined,\n\t 'reverse': false,\n\t 'onload': Tone.noOp,\n\t 'onerror': Tone.noOp\n\t };\n\t /**\n\t\t * Pass in an AudioBuffer or Tone.Buffer to set the value\n\t\t * of this buffer.\n\t\t * @param {AudioBuffer|Tone.Buffer} buffer the buffer\n\t\t * @returns {Tone.Buffer} this\n\t\t */\n\t Tone.Buffer.prototype.set = function (buffer) {\n\t if (buffer instanceof Tone.Buffer) {\n\t if (buffer.loaded) {\n\t this._buffer = buffer.get();\n\t } else {\n\t buffer._onload = function () {\n\t this.set(buffer);\n\t this._onload(this);\n\t }.bind(this);\n\t }\n\t } else {\n\t this._buffer = buffer;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * @return {AudioBuffer} The audio buffer stored in the object.\n\t\t */\n\t Tone.Buffer.prototype.get = function () {\n\t return this._buffer;\n\t };\n\t /**\n\t\t * Makes an xhr reqest for the selected url then decodes\n\t\t * the file as an audio buffer. Invokes\n\t\t * the callback once the audio buffer loads.\n\t\t * @param {String} url The url of the buffer to load.\n\t\t * filetype support depends on the\n\t\t * browser.\n\t\t * @returns {Promise} returns a Promise which resolves with the Tone.Buffer\n\t\t */\n\t Tone.Buffer.prototype.load = function (url, onload, onerror) {\n\t var promise = new Promise(function (load, error) {\n\t this._xhr = Tone.Buffer.load(url, //success\n\t function (buff) {\n\t this._xhr = null;\n\t this.set(buff);\n\t load(this);\n\t this._onload(this);\n\t if (onload) {\n\t onload(this);\n\t }\n\t }.bind(this), //error\n\t function (err) {\n\t this._xhr = null;\n\t error(err);\n\t if (onerror) {\n\t onerror(err);\n\t }\n\t }.bind(this));\n\t }.bind(this));\n\t return promise;\n\t };\n\t /**\n\t\t * dispose and disconnect\n\t\t * @returns {Tone.Buffer} this\n\t\t */\n\t Tone.Buffer.prototype.dispose = function () {\n\t Tone.prototype.dispose.call(this);\n\t this._buffer = null;\n\t if (this._xhr) {\n\t Tone.Buffer._removeFromDownloadQueue(this._xhr);\n\t this._xhr.abort();\n\t this._xhr = null;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * If the buffer is loaded or not\n\t\t * @memberOf Tone.Buffer#\n\t\t * @type {Boolean}\n\t\t * @name loaded\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Buffer.prototype, 'loaded', {\n\t get: function () {\n\t return this.length > 0;\n\t }\n\t });\n\t /**\n\t\t * The duration of the buffer.\n\t\t * @memberOf Tone.Buffer#\n\t\t * @type {Number}\n\t\t * @name duration\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Buffer.prototype, 'duration', {\n\t get: function () {\n\t if (this._buffer) {\n\t return this._buffer.duration;\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The length of the buffer in samples\n\t\t * @memberOf Tone.Buffer#\n\t\t * @type {Number}\n\t\t * @name length\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Buffer.prototype, 'length', {\n\t get: function () {\n\t if (this._buffer) {\n\t return this._buffer.length;\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The number of discrete audio channels. Returns 0 if no buffer\n\t\t * is loaded.\n\t\t * @memberOf Tone.Buffer#\n\t\t * @type {Number}\n\t\t * @name numberOfChannels\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Buffer.prototype, 'numberOfChannels', {\n\t get: function () {\n\t if (this._buffer) {\n\t return this._buffer.numberOfChannels;\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Set the audio buffer from the array. To create a multichannel AudioBuffer,\n\t\t * pass in a multidimensional array.\n\t\t * @param {Float32Array} array The array to fill the audio buffer\n\t\t * @return {Tone.Buffer} this\n\t\t */\n\t Tone.Buffer.prototype.fromArray = function (array) {\n\t var isMultidimensional = array[0].length > 0;\n\t var channels = isMultidimensional ? array.length : 1;\n\t var len = isMultidimensional ? array[0].length : array.length;\n\t var buffer = this.context.createBuffer(channels, len, this.context.sampleRate);\n\t if (!isMultidimensional && channels === 1) {\n\t array = [array];\n\t }\n\t for (var c = 0; c < channels; c++) {\n\t buffer.copyToChannel(array[c], c);\n\t }\n\t this._buffer = buffer;\n\t return this;\n\t };\n\t /**\n\t\t * \tSums muliple channels into 1 channel\n\t\t * @param {Number=} channel Optionally only copy a single channel from the array.\n\t\t * @return {Array}\n\t\t */\n\t Tone.Buffer.prototype.toMono = function (chanNum) {\n\t if (Tone.isNumber(chanNum)) {\n\t this.fromArray(this.toArray(chanNum));\n\t } else {\n\t var outputArray = new Float32Array(this.length);\n\t var numChannels = this.numberOfChannels;\n\t for (var channel = 0; channel < numChannels; channel++) {\n\t var channelArray = this.toArray(channel);\n\t for (var i = 0; i < channelArray.length; i++) {\n\t outputArray[i] += channelArray[i];\n\t }\n\t }\n\t //divide by the number of channels\n\t outputArray = outputArray.map(function (sample) {\n\t return sample / numChannels;\n\t });\n\t this.fromArray(outputArray);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * \tGet the buffer as an array. Single channel buffers will return a 1-dimensional\n\t\t * \tFloat32Array, and multichannel buffers will return multidimensional arrays.\n\t\t * @param {Number=} channel Optionally only copy a single channel from the array.\n\t\t * @return {Array}\n\t\t */\n\t Tone.Buffer.prototype.toArray = function (channel) {\n\t if (Tone.isNumber(channel)) {\n\t return this.getChannelData(channel);\n\t } else if (this.numberOfChannels === 1) {\n\t return this.toArray(0);\n\t } else {\n\t var ret = [];\n\t for (var c = 0; c < this.numberOfChannels; c++) {\n\t ret[c] = this.getChannelData(c);\n\t }\n\t return ret;\n\t }\n\t };\n\t /**\n\t\t * Returns the Float32Array representing the PCM audio data for the specific channel.\n\t\t * @param {Number} channel The channel number to return\n\t\t * @return {Float32Array} The audio as a TypedArray\n\t\t */\n\t Tone.Buffer.prototype.getChannelData = function (channel) {\n\t return this._buffer.getChannelData(channel);\n\t };\n\t /**\n\t\t * Cut a subsection of the array and return a buffer of the\n\t\t * subsection. Does not modify the original buffer\n\t\t * @param {Time} start The time to start the slice\n\t\t * @param {Time=} end The end time to slice. If none is given\n\t\t * will default to the end of the buffer\n\t\t * @return {Tone.Buffer} this\n\t\t */\n\t Tone.Buffer.prototype.slice = function (start, end) {\n\t end = Tone.defaultArg(end, this.duration);\n\t var startSamples = Math.floor(this.context.sampleRate * this.toSeconds(start));\n\t var endSamples = Math.floor(this.context.sampleRate * this.toSeconds(end));\n\t var replacement = [];\n\t for (var i = 0; i < this.numberOfChannels; i++) {\n\t replacement[i] = this.toArray(i).slice(startSamples, endSamples);\n\t }\n\t var retBuffer = new Tone.Buffer().fromArray(replacement);\n\t return retBuffer;\n\t };\n\t /**\n\t\t * Reverse the buffer.\n\t\t * @private\n\t\t * @return {Tone.Buffer} this\n\t\t */\n\t Tone.Buffer.prototype._reverse = function () {\n\t if (this.loaded) {\n\t for (var i = 0; i < this.numberOfChannels; i++) {\n\t Array.prototype.reverse.call(this.getChannelData(i));\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Reverse the buffer.\n\t\t * @memberOf Tone.Buffer#\n\t\t * @type {Boolean}\n\t\t * @name reverse\n\t\t */\n\t Object.defineProperty(Tone.Buffer.prototype, 'reverse', {\n\t get: function () {\n\t return this._reversed;\n\t },\n\t set: function (rev) {\n\t if (this._reversed !== rev) {\n\t this._reversed = rev;\n\t this._reverse();\n\t }\n\t }\n\t });\n\t ///////////////////////////////////////////////////////////////////////////\n\t // STATIC METHODS\n\t ///////////////////////////////////////////////////////////////////////////\n\t //statically inherits Emitter methods\n\t Tone.Emitter.mixin(Tone.Buffer);\n\t /**\n\t\t * the static queue for all of the xhr requests\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t Tone.Buffer._downloadQueue = [];\n\t /**\n\t\t * A path which is prefixed before every url.\n\t\t * @type {String}\n\t\t * @static\n\t\t */\n\t Tone.Buffer.baseUrl = '';\n\t /**\n\t\t * Create a Tone.Buffer from the array. To create a multichannel AudioBuffer,\n\t\t * pass in a multidimensional array.\n\t\t * @param {Float32Array} array The array to fill the audio buffer\n\t\t * @return {Tone.Buffer} A Tone.Buffer created from the array\n\t\t */\n\t Tone.Buffer.fromArray = function (array) {\n\t return new Tone.Buffer().fromArray(array);\n\t };\n\t /**\n\t\t * Creates a Tone.Buffer from a URL, returns a promise\n\t\t * which resolves to a Tone.Buffer\n\t\t * @param {String} url The url to load.\n\t\t * @return {Promise<Tone.Buffer>} A promise which resolves to a Tone.Buffer\n\t\t */\n\t Tone.Buffer.fromUrl = function (url) {\n\t var buffer = new Tone.Buffer();\n\t return buffer.load(url).then(function () {\n\t return buffer;\n\t });\n\t };\n\t /**\n\t\t * Remove an xhr request from the download queue\n\t\t * @private\n\t\t */\n\t Tone.Buffer._removeFromDownloadQueue = function (request) {\n\t var index = Tone.Buffer._downloadQueue.indexOf(request);\n\t if (index !== -1) {\n\t Tone.Buffer._downloadQueue.splice(index, 1);\n\t }\n\t };\n\t /**\n\t\t * Loads a url using XMLHttpRequest.\n\t\t * @param {String} url\n\t\t * @param {Function} onload\n\t\t * @param {Function} onerror\n\t\t * @param {Function} onprogress\n\t\t * @return {XMLHttpRequest}\n\t\t */\n\t Tone.Buffer.load = function (url, onload, onerror) {\n\t //default\n\t onload = Tone.defaultArg(onload, Tone.noOp);\n\t // test if the url contains multiple extensions\n\t var matches = url.match(/\\[(.+\\|?)+\\]$/);\n\t if (matches) {\n\t var extensions = matches[1].split('|');\n\t var extension = extensions[0];\n\t for (var i = 0; i < extensions.length; i++) {\n\t if (Tone.Buffer.supportsType(extensions[i])) {\n\t extension = extensions[i];\n\t break;\n\t }\n\t }\n\t url = url.replace(matches[0], extension);\n\t }\n\t function onError(e) {\n\t Tone.Buffer._removeFromDownloadQueue(request);\n\t Tone.Buffer.emit('error', e);\n\t if (onerror) {\n\t onerror(e);\n\t } else {\n\t throw e;\n\t }\n\t }\n\t function onProgress() {\n\t //calculate the progress\n\t var totalProgress = 0;\n\t for (var i = 0; i < Tone.Buffer._downloadQueue.length; i++) {\n\t totalProgress += Tone.Buffer._downloadQueue[i].progress;\n\t }\n\t Tone.Buffer.emit('progress', totalProgress / Tone.Buffer._downloadQueue.length);\n\t }\n\t var request = new XMLHttpRequest();\n\t request.open('GET', Tone.Buffer.baseUrl + url, true);\n\t request.responseType = 'arraybuffer';\n\t //start out as 0\n\t request.progress = 0;\n\t Tone.Buffer._downloadQueue.push(request);\n\t request.addEventListener('load', function () {\n\t if (request.status === 200) {\n\t Tone.context.decodeAudioData(request.response).then(function (buff) {\n\t request.progress = 1;\n\t onProgress();\n\t onload(buff);\n\t Tone.Buffer._removeFromDownloadQueue(request);\n\t if (Tone.Buffer._downloadQueue.length === 0) {\n\t //emit the event at the end\n\t Tone.Buffer.emit('load');\n\t }\n\t }).catch(function () {\n\t Tone.Buffer._removeFromDownloadQueue(request);\n\t onError('Tone.Buffer: could not decode audio data: ' + url);\n\t });\n\t } else {\n\t onError('Tone.Buffer: could not locate file: ' + url);\n\t }\n\t });\n\t request.addEventListener('error', onError);\n\t request.addEventListener('progress', function (event) {\n\t if (event.lengthComputable) {\n\t //only go to 95%, the last 5% is when the audio is decoded\n\t request.progress = event.loaded / event.total * 0.95;\n\t onProgress();\n\t }\n\t });\n\t request.send();\n\t return request;\n\t };\n\t /**\n\t\t * Stop all of the downloads in progress\n\t\t * @return {Tone.Buffer}\n\t\t * @static\n\t\t */\n\t Tone.Buffer.cancelDownloads = function () {\n\t Tone.Buffer._downloadQueue.slice().forEach(function (request) {\n\t Tone.Buffer._removeFromDownloadQueue(request);\n\t request.abort();\n\t });\n\t return Tone.Buffer;\n\t };\n\t /**\n\t\t * Checks a url's extension to see if the current browser can play that file type.\n\t\t * @param {String} url The url/extension to test\n\t\t * @return {Boolean} If the file extension can be played\n\t\t * @static\n\t\t * @example\n\t\t * Tone.Buffer.supportsType(\"wav\"); //returns true\n\t\t * Tone.Buffer.supportsType(\"path/to/file.wav\"); //returns true\n\t\t */\n\t Tone.Buffer.supportsType = function (url) {\n\t var extension = url.split('.');\n\t extension = extension[extension.length - 1];\n\t var response = document.createElement('audio').canPlayType('audio/' + extension);\n\t return response !== '';\n\t };\n\t /**\n\t\t * Returns a Promise which resolves when all of the buffers have loaded\n\t\t * @return {Promise}\n\t\t */\n\t Tone.loaded = function () {\n\t var onload, onerror;\n\t function removeEvents() {\n\t //remove the events when it's resolved\n\t Tone.Buffer.off('load', onload);\n\t Tone.Buffer.off('error', onerror);\n\t }\n\t return new Promise(function (success, fail) {\n\t onload = function () {\n\t success();\n\t };\n\t onerror = function () {\n\t fail();\n\t };\n\t //add the event listeners\n\t Tone.Buffer.on('load', onload);\n\t Tone.Buffer.on('error', onerror);\n\t }).then(removeEvents).catch(function (e) {\n\t removeEvents();\n\t throw new Error(e);\n\t });\n\t };\n\t return Tone.Buffer;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Wrapper around the native fire-and-forget OscillatorNode. Adds the\n\t\t * ability to reschedule the stop method.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {AudioBuffer|Tone.Buffer} buffer The buffer to play\n\t\t * @param {Function} onload The callback to invoke when the\n\t\t * buffer is done playing.\n\t\t */\n\t Tone.OscillatorNode = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type'\n\t ], Tone.OscillatorNode);\n\t Tone.AudioNode.call(this, options);\n\t /**\n\t\t\t * The callback to invoke after the\n\t\t\t * buffer source is done playing.\n\t\t\t * @type {Function}\n\t\t\t */\n\t this.onended = options.onended;\n\t /**\n\t\t\t * The oscillator start time\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._startTime = -1;\n\t /**\n\t\t\t * The oscillator stop time\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._stopTime = -1;\n\t /**\n\t\t\t * The gain node which envelopes the OscillatorNode\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._gainNode = this.output = new Tone.Gain();\n\t this._gainNode.gain.setValueAtTime(0, this.context.currentTime);\n\t /**\n\t\t\t * The oscillator\n\t\t\t * @type {OscillatorNode}\n\t\t\t * @private\n\t\t\t */\n\t this._oscillator = this.context.createOscillator();\n\t this._oscillator.connect(this._gainNode);\n\t this.type = options.type;\n\t /**\n\t\t\t * The frequency of the oscillator\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Param(this._oscillator.frequency, Tone.Type.Frequency);\n\t this.frequency.value = options.frequency;\n\t /**\n\t\t\t * The detune of the oscillator\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Param(this._oscillator.detune, Tone.Type.Cents);\n\t this.detune.value = options.detune;\n\t /**\n\t\t\t * The value that the buffer ramps to\n\t\t\t * @type {Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._gain = 1;\n\t };\n\t Tone.extend(Tone.OscillatorNode, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.OscillatorNode.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'type': 'sine',\n\t 'onended': Tone.noOp\n\t };\n\t /**\n\t\t * Returns the playback state of the oscillator, either \"started\" or \"stopped\".\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.OscillatorNode#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.OscillatorNode.prototype, 'state', {\n\t get: function () {\n\t return this.getStateAtTime(this.now());\n\t }\n\t });\n\t /**\n\t\t * Get the playback state at the given time\n\t\t * @param {Time} time The time to test the state at\n\t\t * @return {Tone.State} The playback state. \n\t\t */\n\t Tone.OscillatorNode.prototype.getStateAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t if (this._startTime !== -1 && time >= this._startTime && (this._stopTime === -1 || time <= this._stopTime)) {\n\t return Tone.State.Started;\n\t } else {\n\t return Tone.State.Stopped;\n\t }\n\t };\n\t /**\n\t * Start the oscillator node at the given time\n\t * @param {Time=} time When to start the oscillator\n\t * @return {OscillatorNode} this\n\t */\n\t Tone.OscillatorNode.prototype.start = function (time) {\n\t if (this._startTime === -1) {\n\t this._startTime = this.toSeconds(time);\n\t this._oscillator.start(this._startTime);\n\t var now = this.context.currentTime;\n\t this._gainNode.gain.cancelScheduledValues(now);\n\t this._gainNode.gain.setValueAtTime(0, now);\n\t this._gainNode.gain.setValueAtTime(1, this._startTime);\n\t } else {\n\t throw new Error('cannot call OscillatorNode.start more than once');\n\t }\n\t return this;\n\t };\n\t /**\n\t * Sets an arbitrary custom periodic waveform given a PeriodicWave.\n\t * @param {PeriodicWave} periodicWave PeriodicWave should be created with context.createPeriodicWave\n\t * @return {OscillatorNode} this\n\t */\n\t Tone.OscillatorNode.prototype.setPeriodicWave = function (periodicWave) {\n\t this._oscillator.setPeriodicWave(periodicWave);\n\t return this;\n\t };\n\t /**\n\t * Stop the oscillator node at the given time\n\t * @param {Time=} time When to stop the oscillator\n\t * @return {OscillatorNode} this\n\t */\n\t Tone.OscillatorNode.prototype.stop = function (time) {\n\t //cancel the previous stop\n\t this.cancelStop();\n\t //reschedule it\n\t this._stopTime = this.toSeconds(time);\n\t this._gainNode.gain.setValueAtTime(0, this._stopTime);\n\t this.context.clearTimeout(this._timeout);\n\t this._timeout = this.context.setTimeout(function () {\n\t this._oscillator.stop(this.now());\n\t this.onended();\n\t }.bind(this), this._stopTime - this.now());\n\t return this;\n\t };\n\t /**\n\t\t * Cancel a scheduled stop event\n\t\t * @return {Tone.OscillatorNode} this\n\t\t */\n\t Tone.OscillatorNode.prototype.cancelStop = function () {\n\t if (this._startTime !== -1) {\n\t //cancel the stop envelope\n\t this._gainNode.gain.cancelScheduledValues(this._startTime + this.sampleTime);\n\t this._gainNode.gain.setValueAtTime(1, Math.max(this.now(), this._startTime));\n\t this.context.clearTimeout(this._timeout);\n\t this._stopTime = -1;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * The oscillator type. Either 'sine', 'sawtooth', 'square', or 'triangle'\n\t\t * @memberOf Tone.OscillatorNode#\n\t\t * @type {Time}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.OscillatorNode.prototype, 'type', {\n\t get: function () {\n\t return this._oscillator.type;\n\t },\n\t set: function (type) {\n\t this._oscillator.type = type;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.OscillatorNode} this\n\t\t */\n\t Tone.OscillatorNode.prototype.dispose = function () {\n\t this.context.clearTimeout(this._timeout);\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.onended = null;\n\t this._oscillator.disconnect();\n\t this._oscillator = null;\n\t this._gainNode.dispose();\n\t this._gainNode = null;\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this.detune.dispose();\n\t this.detune = null;\n\t return this;\n\t };\n\t return Tone.OscillatorNode;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Oscillator supports a number of features including\n\t\t * phase rotation, multiple oscillator types (see Tone.Oscillator.type),\n\t\t * and Transport syncing (see Tone.Oscillator.syncFrequency).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Source}\n\t\t * @param {Frequency} [frequency] Starting frequency\n\t\t * @param {string} [type] The oscillator type. Read more about type below.\n\t\t * @example\n\t\t * //make and start a 440hz sine tone\n\t\t * var osc = new Tone.Oscillator(440, \"sine\").toMaster().start();\n\t\t */\n\t Tone.Oscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type'\n\t ], Tone.Oscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * the main oscillator\n\t\t\t * @type {OscillatorNode}\n\t\t\t * @private\n\t\t\t */\n\t this._oscillator = null;\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune control signal.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(options.detune, Tone.Type.Cents);\n\t /**\n\t\t\t * the periodic wave\n\t\t\t * @type {PeriodicWave}\n\t\t\t * @private\n\t\t\t */\n\t this._wave = null;\n\t /**\n\t\t\t * The partials of the oscillator\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._partials = Tone.defaultArg(options.partials, [1]);\n\t /**\n\t\t\t * the phase of the oscillator\n\t\t\t * between 0 - 360\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._phase = options.phase;\n\t /**\n\t\t\t * the type of the oscillator\n\t\t\t * @type {string}\n\t\t\t * @private\n\t\t\t */\n\t this._type = null;\n\t //setup\n\t this.type = options.type;\n\t this.phase = this._phase;\n\t this._readOnly([\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t };\n\t Tone.extend(Tone.Oscillator, Tone.Source);\n\t /**\n\t\t * the default parameters\n\t\t * @type {Object}\n\t\t */\n\t Tone.Oscillator.defaults = {\n\t 'type': 'sine',\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'phase': 0,\n\t 'partials': []\n\t };\n\t /**\n\t\t * The Oscillator types\n\t\t * @enum {String}\n\t\t */\n\t Tone.Oscillator.Type = {\n\t Sine: 'sine',\n\t Triangle: 'triangle',\n\t Sawtooth: 'sawtooth',\n\t Square: 'square',\n\t Custom: 'custom'\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now]\n\t\t * @private\n\t\t */\n\t Tone.Oscillator.prototype._start = function (time) {\n\t //new oscillator with previous values\n\t this._oscillator = new Tone.OscillatorNode();\n\t if (this._wave) {\n\t this._oscillator.setPeriodicWave(this._wave);\n\t } else {\n\t this._oscillator.type = this._type;\n\t }\n\t //connect the control signal to the oscillator frequency & detune\n\t this._oscillator.connect(this.output);\n\t this.frequency.connect(this._oscillator.frequency);\n\t this.detune.connect(this._oscillator.detune);\n\t //start the oscillator\n\t time = this.toSeconds(time);\n\t this._oscillator.start(time);\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @private\n\t\t * @param {Time} [time=now] (optional) timing parameter\n\t\t * @returns {Tone.Oscillator} this\n\t\t */\n\t Tone.Oscillator.prototype._stop = function (time) {\n\t if (this._oscillator) {\n\t time = this.toSeconds(time);\n\t this._oscillator.stop(time);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Restart the oscillator. Does not stop the oscillator, but instead\n\t\t * just cancels any scheduled 'stop' from being invoked.\n\t\t * @param {Time=} time\n\t\t * @return {Tone.Oscillator} this\n\t\t */\n\t Tone.Oscillator.prototype.restart = function (time) {\n\t this._oscillator.cancelStop();\n\t this._state.cancel(this.toSeconds(time));\n\t return this;\n\t };\n\t /**\n\t\t * Sync the signal to the Transport's bpm. Any changes to the transports bpm,\n\t\t * will also affect the oscillators frequency.\n\t\t * @returns {Tone.Oscillator} this\n\t\t * @example\n\t\t * Tone.Transport.bpm.value = 120;\n\t\t * osc.frequency.value = 440;\n\t\t * //the ration between the bpm and the frequency will be maintained\n\t\t * osc.syncFrequency();\n\t\t * Tone.Transport.bpm.value = 240;\n\t\t * // the frequency of the oscillator is doubled to 880\n\t\t */\n\t Tone.Oscillator.prototype.syncFrequency = function () {\n\t Tone.Transport.syncSignal(this.frequency);\n\t return this;\n\t };\n\t /**\n\t\t * Unsync the oscillator's frequency from the Transport.\n\t\t * See Tone.Oscillator.syncFrequency\n\t\t * @returns {Tone.Oscillator} this\n\t\t */\n\t Tone.Oscillator.prototype.unsyncFrequency = function () {\n\t Tone.Transport.unsyncSignal(this.frequency);\n\t return this;\n\t };\n\t /**\n\t\t * The type of the oscillator: either sine, square, triangle, or sawtooth. Also capable of\n\t\t * setting the first x number of partials of the oscillator. For example: \"sine4\" would\n\t\t * set be the first 4 partials of the sine wave and \"triangle8\" would set the first\n\t\t * 8 partials of the triangle wave.\n\t\t * <br><br>\n\t\t * Uses PeriodicWave internally even for native types so that it can set the phase.\n\t\t * PeriodicWave equations are from the\n\t\t * [Webkit Web Audio implementation](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/modules/webaudio/PeriodicWave.cpp&sq=package:chromium).\n\t\t *\n\t\t * @memberOf Tone.Oscillator#\n\t\t * @type {string}\n\t\t * @name type\n\t\t * @example\n\t\t * //set it to a square wave\n\t\t * osc.type = \"square\";\n\t\t * @example\n\t\t * //set the first 6 partials of a sawtooth wave\n\t\t * osc.type = \"sawtooth6\";\n\t\t */\n\t Object.defineProperty(Tone.Oscillator.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t var isBasicType = [\n\t Tone.Oscillator.Type.Sine,\n\t Tone.Oscillator.Type.Square,\n\t Tone.Oscillator.Type.Triangle,\n\t Tone.Oscillator.Type.Sawtooth\n\t ].includes(type);\n\t if (this._phase === 0 && isBasicType) {\n\t this._wave = null;\n\t //just go with the basic approach\n\t if (this._oscillator !== null) {\n\t this._oscillator.type === type;\n\t }\n\t } else {\n\t var coefs = this._getRealImaginary(type, this._phase);\n\t var periodicWave = this.context.createPeriodicWave(coefs[0], coefs[1]);\n\t this._wave = periodicWave;\n\t if (this._oscillator !== null) {\n\t this._oscillator.setPeriodicWave(this._wave);\n\t }\n\t }\n\t this._type = type;\n\t }\n\t });\n\t /**\n\t\t * Returns the real and imaginary components based\n\t\t * on the oscillator type.\n\t\t * @returns {Array} [real, imaginary]\n\t\t * @private\n\t\t */\n\t Tone.Oscillator.prototype._getRealImaginary = function (type, phase) {\n\t var fftSize = 4096;\n\t var periodicWaveSize = fftSize / 2;\n\t var real = new Float32Array(periodicWaveSize);\n\t var imag = new Float32Array(periodicWaveSize);\n\t var partialCount = 1;\n\t if (type === Tone.Oscillator.Type.Custom) {\n\t partialCount = this._partials.length + 1;\n\t periodicWaveSize = partialCount;\n\t } else {\n\t var partial = /^(sine|triangle|square|sawtooth)(\\d+)$/.exec(type);\n\t if (partial) {\n\t partialCount = parseInt(partial[2]) + 1;\n\t type = partial[1];\n\t partialCount = Math.max(partialCount, 2);\n\t periodicWaveSize = partialCount;\n\t }\n\t }\n\t for (var n = 1; n < periodicWaveSize; ++n) {\n\t var piFactor = 2 / (n * Math.PI);\n\t var b;\n\t switch (type) {\n\t case Tone.Oscillator.Type.Sine:\n\t b = n <= partialCount ? 1 : 0;\n\t break;\n\t case Tone.Oscillator.Type.Square:\n\t b = n & 1 ? 2 * piFactor : 0;\n\t break;\n\t case Tone.Oscillator.Type.Sawtooth:\n\t b = piFactor * (n & 1 ? 1 : -1);\n\t break;\n\t case Tone.Oscillator.Type.Triangle:\n\t if (n & 1) {\n\t b = 2 * (piFactor * piFactor) * (n - 1 >> 1 & 1 ? -1 : 1);\n\t } else {\n\t b = 0;\n\t }\n\t break;\n\t case Tone.Oscillator.Type.Custom:\n\t b = this._partials[n - 1];\n\t break;\n\t default:\n\t throw new TypeError('Tone.Oscillator: invalid type: ' + type);\n\t }\n\t if (b !== 0) {\n\t real[n] = -b * Math.sin(phase * n);\n\t imag[n] = b * Math.cos(phase * n);\n\t } else {\n\t real[n] = 0;\n\t imag[n] = 0;\n\t }\n\t }\n\t return [\n\t real,\n\t imag\n\t ];\n\t };\n\t /**\n\t\t * Compute the inverse FFT for a given phase.\n\t\t * @param {Float32Array} real\n\t\t * @param {Float32Array} imag\n\t\t * @param {NormalRange} phase\n\t\t * @return {AudioRange}\n\t\t * @private\n\t\t */\n\t Tone.Oscillator.prototype._inverseFFT = function (real, imag, phase) {\n\t var sum = 0;\n\t var len = real.length;\n\t for (var i = 0; i < len; i++) {\n\t sum += real[i] * Math.cos(i * phase) + imag[i] * Math.sin(i * phase);\n\t }\n\t return sum;\n\t };\n\t /**\n\t\t * Returns the initial value of the oscillator.\n\t\t * @return {AudioRange}\n\t\t * @private\n\t\t */\n\t Tone.Oscillator.prototype._getInitialValue = function () {\n\t var coefs = this._getRealImaginary(this._type, 0);\n\t var real = coefs[0];\n\t var imag = coefs[1];\n\t var maxValue = 0;\n\t var twoPi = Math.PI * 2;\n\t //check for peaks in 8 places\n\t for (var i = 0; i < 8; i++) {\n\t maxValue = Math.max(this._inverseFFT(real, imag, i / 8 * twoPi), maxValue);\n\t }\n\t return -this._inverseFFT(real, imag, this._phase) / maxValue;\n\t };\n\t /**\n\t\t * The partials of the waveform. A partial represents\n\t\t * the amplitude at a harmonic. The first harmonic is the\n\t\t * fundamental frequency, the second is the octave and so on\n\t\t * following the harmonic series.\n\t\t * Setting this value will automatically set the type to \"custom\".\n\t\t * The value is an empty array when the type is not \"custom\".\n\t\t * @memberOf Tone.Oscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @example\n\t\t * osc.partials = [1, 0.2, 0.01];\n\t\t */\n\t Object.defineProperty(Tone.Oscillator.prototype, 'partials', {\n\t get: function () {\n\t if (this._type !== Tone.Oscillator.Type.Custom) {\n\t return [];\n\t } else {\n\t return this._partials;\n\t }\n\t },\n\t set: function (partials) {\n\t this._partials = partials;\n\t this.type = Tone.Oscillator.Type.Custom;\n\t }\n\t });\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.Oscillator#\n\t\t * @type {Degrees}\n\t\t * @name phase\n\t\t * @example\n\t\t * osc.phase = 180; //flips the phase of the oscillator\n\t\t */\n\t Object.defineProperty(Tone.Oscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._phase * (180 / Math.PI);\n\t },\n\t set: function (phase) {\n\t this._phase = phase * Math.PI / 180;\n\t //reset the type\n\t this.type = this._type;\n\t }\n\t });\n\t /**\n\t\t * Dispose and disconnect.\n\t\t * @return {Tone.Oscillator} this\n\t\t */\n\t Tone.Oscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t if (this._oscillator !== null) {\n\t this._oscillator.dispose();\n\t this._oscillator = null;\n\t }\n\t this._wave = null;\n\t this._writable([\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this.detune.dispose();\n\t this.detune = null;\n\t this._partials = null;\n\t return this;\n\t };\n\t return Tone.Oscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t\t * See Tone.GainToAudio.\n\t\t *\n\t\t * @extends {Tone.SignalBase}\n\t\t * @constructor\n\t\t * @example\n\t\t * var a2g = new Tone.AudioToGain();\n\t\t */\n\t Tone.AudioToGain = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * @type {WaveShaperNode}\n\t\t\t * @private\n\t\t\t */\n\t this._norm = this.input = this.output = new Tone.WaveShaper(function (x) {\n\t return (x + 1) / 2;\n\t });\n\t };\n\t Tone.extend(Tone.AudioToGain, Tone.SignalBase);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.AudioToGain} this\n\t\t */\n\t Tone.AudioToGain.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._norm.dispose();\n\t this._norm = null;\n\t return this;\n\t };\n\t return Tone.AudioToGain;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Zero outputs 0's at audio-rate. The reason this has to be\n\t\t * it's own class is that many browsers optimize out Tone.Signal\n\t\t * with a value of 0 and will not process nodes further down the graph.\n\t\t * @extends {Tone.SignalBase}\n\t\t */\n\t Tone.Zero = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * The gain node\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._gain = this.input = this.output = new Tone.Gain();\n\t this.context.getConstant(0).connect(this._gain);\n\t };\n\t Tone.extend(Tone.Zero, Tone.SignalBase);\n\t /**\n\t\t * clean up\n\t\t * @return {Tone.Zero} this\n\t\t */\n\t Tone.Zero.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._gain.dispose();\n\t this._gain = null;\n\t return this;\n\t };\n\t return Tone.Zero;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class LFO stands for low frequency oscillator. Tone.LFO produces an output signal\n\t\t * which can be attached to an AudioParam or Tone.Signal\n\t\t * in order to modulate that parameter with an oscillator. The LFO can\n\t\t * also be synced to the transport to start/stop and change when the tempo changes.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Frequency|Object} [frequency] The frequency of the oscillation. Typically, LFOs will be\n\t\t * in the frequency range of 0.1 to 10 hertz.\n\t\t * @param {number=} min The minimum output value of the LFO.\n\t\t * @param {number=} max The maximum value of the LFO.\n\t\t * @example\n\t\t * var lfo = new Tone.LFO(\"4n\", 400, 4000);\n\t\t * lfo.connect(filter.frequency);\n\t\t */\n\t Tone.LFO = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'min',\n\t 'max'\n\t ], Tone.LFO);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The oscillator.\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._oscillator = new Tone.Oscillator({\n\t 'frequency': options.frequency,\n\t 'type': options.type\n\t });\n\t /**\n\t\t\t * the lfo's frequency\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._oscillator.frequency;\n\t /**\n\t\t\t * The amplitude of the LFO, which controls the output range between\n\t\t\t * the min and max output. For example if the min is -10 and the max\n\t\t\t * is 10, setting the amplitude to 0.5 would make the LFO modulate\n\t\t\t * between -5 and 5.\n\t\t\t * @type {Number}\n\t\t\t * @signal\n\t\t\t */\n\t this.amplitude = this._oscillator.volume;\n\t this.amplitude.units = Tone.Type.NormalRange;\n\t this.amplitude.value = options.amplitude;\n\t /**\n\t\t\t * The signal which is output when the LFO is stopped\n\t\t\t * @type {Tone.Signal}\n\t\t\t * @private\n\t\t\t */\n\t this._stoppedSignal = new Tone.Signal(0, Tone.Type.AudioRange);\n\t /**\n\t\t\t * Just outputs zeros.\n\t\t\t * @type {Tone.Zero}\n\t\t\t * @private\n\t\t\t */\n\t this._zeros = new Tone.Zero();\n\t /**\n\t\t\t * The value that the LFO outputs when it's stopped\n\t\t\t * @type {AudioRange}\n\t\t\t * @private\n\t\t\t */\n\t this._stoppedValue = 0;\n\t /**\n\t\t\t * @type {Tone.AudioToGain}\n\t\t\t * @private\n\t\t\t */\n\t this._a2g = new Tone.AudioToGain();\n\t /**\n\t\t\t * @type {Tone.Scale}\n\t\t\t * @private\n\t\t\t */\n\t this._scaler = this.output = new Tone.Scale(options.min, options.max);\n\t /**\n\t\t\t * the units of the LFO (used for converting)\n\t\t\t * @type {Tone.Type}\n\t\t\t * @private\n\t\t\t */\n\t this._units = Tone.Type.Default;\n\t this.units = options.units;\n\t //connect it up\n\t this._oscillator.chain(this._a2g, this._scaler);\n\t this._zeros.connect(this._a2g);\n\t this._stoppedSignal.connect(this._a2g);\n\t this._readOnly([\n\t 'amplitude',\n\t 'frequency'\n\t ]);\n\t this.phase = options.phase;\n\t };\n\t Tone.extend(Tone.LFO, Tone.AudioNode);\n\t /**\n\t\t * the default parameters\n\t\t *\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.LFO.defaults = {\n\t 'type': 'sine',\n\t 'min': 0,\n\t 'max': 1,\n\t 'phase': 0,\n\t 'frequency': '4n',\n\t 'amplitude': 1,\n\t 'units': Tone.Type.Default\n\t };\n\t /**\n\t\t * Start the LFO.\n\t\t * @param {Time} [time=now] the time the LFO will start\n\t\t * @returns {Tone.LFO} this\n\t\t */\n\t Tone.LFO.prototype.start = function (time) {\n\t time = this.toSeconds(time);\n\t this._stoppedSignal.setValueAtTime(0, time);\n\t this._oscillator.start(time);\n\t return this;\n\t };\n\t /**\n\t\t * Stop the LFO.\n\t\t * @param {Time} [time=now] the time the LFO will stop\n\t\t * @returns {Tone.LFO} this\n\t\t */\n\t Tone.LFO.prototype.stop = function (time) {\n\t time = this.toSeconds(time);\n\t this._stoppedSignal.setValueAtTime(this._stoppedValue, time);\n\t this._oscillator.stop(time);\n\t return this;\n\t };\n\t /**\n\t\t * Sync the start/stop/pause to the transport\n\t\t * and the frequency to the bpm of the transport\n\t\t * @returns {Tone.LFO} this\n\t\t * @example\n\t\t * lfo.frequency.value = \"8n\";\n\t\t * lfo.sync().start(0)\n\t\t * //the rate of the LFO will always be an eighth note,\n\t\t * //even as the tempo changes\n\t\t */\n\t Tone.LFO.prototype.sync = function () {\n\t this._oscillator.sync();\n\t this._oscillator.syncFrequency();\n\t return this;\n\t };\n\t /**\n\t\t * unsync the LFO from transport control\n\t\t * @returns {Tone.LFO} this\n\t\t */\n\t Tone.LFO.prototype.unsync = function () {\n\t this._oscillator.unsync();\n\t this._oscillator.unsyncFrequency();\n\t return this;\n\t };\n\t /**\n\t\t * The miniumum output of the LFO.\n\t\t * @memberOf Tone.LFO#\n\t\t * @type {number}\n\t\t * @name min\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'min', {\n\t get: function () {\n\t return this._toUnits(this._scaler.min);\n\t },\n\t set: function (min) {\n\t min = this._fromUnits(min);\n\t this._scaler.min = min;\n\t }\n\t });\n\t /**\n\t\t * The maximum output of the LFO.\n\t\t * @memberOf Tone.LFO#\n\t\t * @type {number}\n\t\t * @name max\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'max', {\n\t get: function () {\n\t return this._toUnits(this._scaler.max);\n\t },\n\t set: function (max) {\n\t max = this._fromUnits(max);\n\t this._scaler.max = max;\n\t }\n\t });\n\t /**\n\t\t * The type of the oscillator: sine, square, sawtooth, triangle.\n\t\t * @memberOf Tone.LFO#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'type', {\n\t get: function () {\n\t return this._oscillator.type;\n\t },\n\t set: function (type) {\n\t this._oscillator.type = type;\n\t this._stoppedValue = this._oscillator._getInitialValue();\n\t this._stoppedSignal.value = this._stoppedValue;\n\t }\n\t });\n\t /**\n\t\t * The phase of the LFO.\n\t\t * @memberOf Tone.LFO#\n\t\t * @type {number}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'phase', {\n\t get: function () {\n\t return this._oscillator.phase;\n\t },\n\t set: function (phase) {\n\t this._oscillator.phase = phase;\n\t this._stoppedValue = this._oscillator._getInitialValue();\n\t this._stoppedSignal.value = this._stoppedValue;\n\t }\n\t });\n\t /**\n\t\t * The output units of the LFO.\n\t\t * @memberOf Tone.LFO#\n\t\t * @type {Tone.Type}\n\t\t * @name units\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'units', {\n\t get: function () {\n\t return this._units;\n\t },\n\t set: function (val) {\n\t var currentMin = this.min;\n\t var currentMax = this.max;\n\t //convert the min and the max\n\t this._units = val;\n\t this.min = currentMin;\n\t this.max = currentMax;\n\t }\n\t });\n\t /**\n\t\t * Mute the output.\n\t\t * @memberOf Tone.LFO#\n\t\t * @type {Boolean}\n\t\t * @name mute\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'mute', {\n\t get: function () {\n\t return this._oscillator.mute;\n\t },\n\t set: function (mute) {\n\t this._oscillator.mute = mute;\n\t }\n\t });\n\t /**\n\t\t * Returns the playback state of the source, either \"started\" or \"stopped\".\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.LFO#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.LFO.prototype, 'state', {\n\t get: function () {\n\t return this._oscillator.state;\n\t }\n\t });\n\t /**\n\t\t * Connect the output of the LFO to an AudioParam, AudioNode, or Tone Node.\n\t\t * Tone.LFO will automatically convert to the destination units of the\n\t\t * will get the units from the connected node.\n\t\t * @param {Tone | AudioParam | AudioNode} node\n\t\t * @param {number} [outputNum=0] optionally which output to connect from\n\t\t * @param {number} [inputNum=0] optionally which input to connect to\n\t\t * @returns {Tone.LFO} this\n\t\t * @private\n\t\t */\n\t Tone.LFO.prototype.connect = function (node) {\n\t if (node.constructor === Tone.Signal || node.constructor === Tone.Param) {\n\t this.convert = node.convert;\n\t this.units = node.units;\n\t }\n\t Tone.SignalBase.prototype.connect.apply(this, arguments);\n\t return this;\n\t };\n\t /**\n\t\t * private method borrowed from Param converts\n\t\t * units from their destination value\n\t\t * @function\n\t\t * @private\n\t\t */\n\t Tone.LFO.prototype._fromUnits = Tone.Param.prototype._fromUnits;\n\t /**\n\t\t * private method borrowed from Param converts\n\t\t * units to their destination value\n\t\t * @function\n\t\t * @private\n\t\t */\n\t Tone.LFO.prototype._toUnits = Tone.Param.prototype._toUnits;\n\t /**\n\t\t * disconnect and dispose\n\t\t * @returns {Tone.LFO} this\n\t\t */\n\t Tone.LFO.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'amplitude',\n\t 'frequency'\n\t ]);\n\t this._oscillator.dispose();\n\t this._oscillator = null;\n\t this._stoppedSignal.dispose();\n\t this._stoppedSignal = null;\n\t this._zeros.dispose();\n\t this._zeros = null;\n\t this._scaler.dispose();\n\t this._scaler = null;\n\t this._a2g.dispose();\n\t this._a2g = null;\n\t this.frequency = null;\n\t this.amplitude = null;\n\t return this;\n\t };\n\t return Tone.LFO;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Limiter will limit the loudness of an incoming signal.\n\t\t * It is composed of a Tone.Compressor with a fast attack\n\t\t * and release. Limiters are commonly used to safeguard against\n\t\t * signal clipping. Unlike a compressor, limiters do not provide\n\t\t * smooth gain reduction and almost completely prevent\n\t\t * additional gain above the threshold.\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {number} threshold The theshold above which the limiting is applied.\n\t\t * @example\n\t\t * var limiter = new Tone.Limiter(-6);\n\t\t */\n\t Tone.Limiter = function () {\n\t var options = Tone.defaults(arguments, ['threshold'], Tone.Limiter);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * the compressor\n\t\t\t * @private\n\t\t\t * @type {Tone.Compressor}\n\t\t\t */\n\t this._compressor = this.input = this.output = new Tone.Compressor({\n\t 'attack': 0.001,\n\t 'decay': 0.001,\n\t 'threshold': options.threshold\n\t });\n\t /**\n\t\t\t * The threshold of of the limiter\n\t\t\t * @type {Decibel}\n\t\t\t * @signal\n\t\t\t */\n\t this.threshold = this._compressor.threshold;\n\t this._readOnly('threshold');\n\t };\n\t Tone.extend(Tone.Limiter, Tone.AudioNode);\n\t /**\n\t\t * The default value\n\t\t * @type {Object}\n\t\t * @const\n\t\t * @static\n\t\t */\n\t Tone.Limiter.defaults = { 'threshold': -12 };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Limiter} this\n\t\t */\n\t Tone.Limiter.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._compressor.dispose();\n\t this._compressor = null;\n\t this._writable('threshold');\n\t this.threshold = null;\n\t return this;\n\t };\n\t return Tone.Limiter;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Lowpass is a lowpass feedback comb filter. It is similar to\n\t\t * Tone.FeedbackCombFilter, but includes a lowpass filter.\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {Time|Object} [delayTime] The delay time of the comb filter\n\t\t * @param {NormalRange=} resonance The resonance (feedback) of the comb filter\n\t\t * @param {Frequency=} dampening The cutoff of the lowpass filter dampens the\n\t\t * signal as it is fedback.\n\t\t */\n\t Tone.LowpassCombFilter = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'delayTime',\n\t 'resonance',\n\t 'dampening'\n\t ], Tone.LowpassCombFilter);\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(1, 1);\n\t /**\n\t\t\t * the delay node\n\t\t\t * @type {DelayNode}\n\t\t\t * @private\n\t\t\t */\n\t this._delay = this.input = new Tone.Delay(options.delayTime);\n\t /**\n\t\t\t * The delayTime of the comb filter.\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.delayTime = this._delay.delayTime;\n\t /**\n\t\t\t * the lowpass filter\n\t\t\t * @type {BiquadFilterNode}\n\t\t\t * @private\n\t\t\t */\n\t this._lowpass = this.output = this.context.createBiquadFilter();\n\t this._lowpass.Q.value = -3.0102999566398125;\n\t this._lowpass.type = 'lowpass';\n\t /**\n\t\t\t * The dampening control of the feedback\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.dampening = new Tone.Param({\n\t 'param': this._lowpass.frequency,\n\t 'units': Tone.Type.Frequency,\n\t 'value': options.dampening\n\t });\n\t /**\n\t\t\t * the feedback gain\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._feedback = new Tone.Gain(options.resonance, Tone.Type.NormalRange);\n\t /**\n\t\t\t * The amount of feedback of the delayed signal.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.resonance = this._feedback.gain;\n\t //connections\n\t this._delay.chain(this._lowpass, this._feedback, this._delay);\n\t this._readOnly([\n\t 'dampening',\n\t 'resonance',\n\t 'delayTime'\n\t ]);\n\t };\n\t Tone.extend(Tone.LowpassCombFilter, Tone.AudioNode);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.LowpassCombFilter.defaults = {\n\t 'delayTime': 0.1,\n\t 'resonance': 0.5,\n\t 'dampening': 3000\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.LowpassCombFilter} this\n\t\t */\n\t Tone.LowpassCombFilter.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'dampening',\n\t 'resonance',\n\t 'delayTime'\n\t ]);\n\t this.dampening.dispose();\n\t this.dampening = null;\n\t this.resonance.dispose();\n\t this.resonance = null;\n\t this._delay.dispose();\n\t this._delay = null;\n\t this.delayTime = null;\n\t this._lowpass.disconnect();\n\t this._lowpass = null;\n\t this._feedback.disconnect();\n\t this._feedback = null;\n\t return this;\n\t };\n\t return Tone.LowpassCombFilter;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Merge brings two signals into the left and right\n\t\t * channels of a single stereo channel.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @example\n\t\t * var merge = new Tone.Merge().toMaster();\n\t\t * //routing a sine tone in the left channel\n\t\t * //and noise in the right channel\n\t\t * var osc = new Tone.Oscillator().connect(merge.left);\n\t\t * var noise = new Tone.Noise().connect(merge.right);\n\t\t * //starting our oscillators\n\t\t * noise.start();\n\t\t * osc.start();\n\t\t */\n\t Tone.Merge = function () {\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(2, 0);\n\t /**\n\t\t\t * The left input channel.\n\t\t\t * Alias for <code>input[0]</code>\n\t\t\t * @type {GainNode}\n\t\t\t */\n\t this.left = this.input[0] = new Tone.Gain();\n\t /**\n\t\t\t * The right input channel.\n\t\t\t * Alias for <code>input[1]</code>.\n\t\t\t * @type {GainNode}\n\t\t\t */\n\t this.right = this.input[1] = new Tone.Gain();\n\t /**\n\t\t\t * the merger node for the two channels\n\t\t\t * @type {ChannelMergerNode}\n\t\t\t * @private\n\t\t\t */\n\t this._merger = this.output = this.context.createChannelMerger(2);\n\t //connections\n\t this.left.connect(this._merger, 0, 0);\n\t this.right.connect(this._merger, 0, 1);\n\t this.left.channelCount = 1;\n\t this.right.channelCount = 1;\n\t this.left.channelCountMode = 'explicit';\n\t this.right.channelCountMode = 'explicit';\n\t };\n\t Tone.extend(Tone.Merge, Tone.AudioNode);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Merge} this\n\t\t */\n\t Tone.Merge.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.left.dispose();\n\t this.left = null;\n\t this.right.dispose();\n\t this.right = null;\n\t this._merger.disconnect();\n\t this._merger = null;\n\t return this;\n\t };\n\t return Tone.Merge;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Meter gets the [RMS](https://en.wikipedia.org/wiki/Root_mean_square)\n\t\t * of an input signal with some averaging applied. It can also get the raw\n\t\t * value of the input signal.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Number} smoothing The amount of smoothing applied between frames.\n\t\t * @example\n\t\t * var meter = new Tone.Meter();\n\t\t * var mic = new Tone.UserMedia().open();\n\t\t * //connect mic to the meter\n\t\t * mic.connect(meter);\n\t\t * //the current level of the mic input in decibels\n\t\t * var level = meter.getValue();\n\t\t */\n\t Tone.Meter = function () {\n\t var options = Tone.defaults(arguments, ['smoothing'], Tone.Meter);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The analyser node which computes the levels.\n\t\t\t * @private\n\t\t\t * @type {Tone.Analyser}\n\t\t\t */\n\t this.input = this.output = this._analyser = new Tone.Analyser('waveform', 1024);\n\t /**\n\t\t\t * The amount of carryover between the current and last frame.\n\t\t\t * Only applied meter for \"level\" type.\n\t\t\t * @type {Number}\n\t\t\t */\n\t this.smoothing = options.smoothing;\n\t };\n\t Tone.extend(Tone.Meter, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @type {Object}\n\t\t * @static\n\t\t * @const\n\t\t */\n\t Tone.Meter.defaults = { 'smoothing': 0.8 };\n\t /**\n\t\t * Get the current decibel value of the incoming signal\n\t\t * @returns {Decibels}\n\t\t */\n\t Tone.Meter.prototype.getLevel = function () {\n\t this._analyser.type = 'fft';\n\t var values = this._analyser.getValue();\n\t var offset = 28;\n\t // normalizes most signal levels\n\t // TODO: compute loudness from FFT\n\t return Math.max.apply(this, values) + offset;\n\t };\n\t /**\n\t\t * Get the signal value of the incoming signal\n\t\t * @returns {Number}\n\t\t */\n\t Tone.Meter.prototype.getValue = function () {\n\t this._analyser.type = 'waveform';\n\t var value = this._analyser.getValue();\n\t return value[0];\n\t };\n\t /**\n\t\t * A value from 0 -> 1 where 0 represents no time averaging with the last analysis frame.\n\t\t * @memberOf Tone.Meter#\n\t\t * @type {Number}\n\t\t * @name smoothing\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Meter.prototype, 'smoothing', {\n\t get: function () {\n\t return this._analyser.smoothing;\n\t },\n\t set: function (val) {\n\t this._analyser.smoothing = val;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Meter} this\n\t\t */\n\t Tone.Meter.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._analyser.dispose();\n\t this._analyser = null;\n\t return this;\n\t };\n\t return Tone.Meter;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t *\t@class Tone.Split splits an incoming signal into left and right channels.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @example\n\t\t * var split = new Tone.Split();\n\t\t * stereoSignal.connect(split);\n\t\t */\n\t Tone.Split = function () {\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(0, 2);\n\t /**\n\t\t\t * @type {ChannelSplitterNode}\n\t\t\t * @private\n\t\t\t */\n\t this._splitter = this.input = this.context.createChannelSplitter(2);\n\t this._splitter.channelCount = 2;\n\t this._splitter.channelCountMode = 'explicit';\n\t /**\n\t\t\t * Left channel output.\n\t\t\t * Alias for <code>output[0]</code>\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.left = this.output[0] = new Tone.Gain();\n\t /**\n\t\t\t * Right channel output.\n\t\t\t * Alias for <code>output[1]</code>\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.right = this.output[1] = new Tone.Gain();\n\t //connections\n\t this._splitter.connect(this.left, 0, 0);\n\t this._splitter.connect(this.right, 1, 0);\n\t };\n\t Tone.extend(Tone.Split, Tone.AudioNode);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Split} this\n\t\t */\n\t Tone.Split.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._splitter.disconnect();\n\t this.left.dispose();\n\t this.left = null;\n\t this.right.dispose();\n\t this.right = null;\n\t this._splitter = null;\n\t return this;\n\t };\n\t return Tone.Split;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Mid/Side processing separates the the 'mid' signal\n\t\t * (which comes out of both the left and the right channel)\n\t\t * and the 'side' (which only comes out of the the side channels). <br><br>\n\t\t * <code>\n\t\t * Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right<br>\n\t\t * Side = (Left-Right)/sqrt(2); // obtain side-signal from left and righ<br>\n\t\t * </code>\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t */\n\t Tone.MidSideSplit = function () {\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(0, 2);\n\t /**\n\t\t\t * split the incoming signal into left and right channels\n\t\t\t * @type {Tone.Split}\n\t\t\t * @private\n\t\t\t */\n\t this._split = this.input = new Tone.Split();\n\t /**\n\t\t\t * The mid send. Connect to mid processing. Alias for\n\t\t\t * <code>output[0]</code>\n\t\t\t * @type {Tone.Add}\n\t\t\t */\n\t this._midAdd = new Tone.Add();\n\t /**\n\t\t\t * Multiply the _midAdd by sqrt(1/2)\n\t\t\t * @type {Tone.Multiply}\n\t\t\t */\n\t this.mid = this.output[0] = new Tone.Multiply(Math.SQRT1_2);\n\t /**\n\t\t\t * The side output. Connect to side processing. Also Output 1\n\t\t\t * @type {Tone.Subtract}\n\t\t\t */\n\t this._sideSubtract = new Tone.Subtract();\n\t /**\n\t\t\t * Multiply the _midAdd by sqrt(1/2)\n\t\t\t * @type {Tone.Multiply}\n\t\t\t */\n\t this.side = this.output[1] = new Tone.Multiply(Math.SQRT1_2);\n\t this._split.connect(this._midAdd, 0, 0);\n\t this._split.connect(this._midAdd, 1, 1);\n\t this._split.connect(this._sideSubtract, 0, 0);\n\t this._split.connect(this._sideSubtract, 1, 1);\n\t this._midAdd.connect(this.mid);\n\t this._sideSubtract.connect(this.side);\n\t };\n\t Tone.extend(Tone.MidSideSplit, Tone.AudioNode);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.MidSideSplit} this\n\t\t */\n\t Tone.MidSideSplit.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.mid.dispose();\n\t this.mid = null;\n\t this.side.dispose();\n\t this.side = null;\n\t this._midAdd.dispose();\n\t this._midAdd = null;\n\t this._sideSubtract.dispose();\n\t this._sideSubtract = null;\n\t this._split.dispose();\n\t this._split = null;\n\t return this;\n\t };\n\t return Tone.MidSideSplit;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Mid/Side processing separates the the 'mid' signal\n\t\t * (which comes out of both the left and the right channel)\n\t\t * and the 'side' (which only comes out of the the side channels).\n\t\t * MidSideMerge merges the mid and side signal after they've been seperated\n\t\t * by Tone.MidSideSplit.<br><br>\n\t\t * <code>\n\t\t * Left = (Mid+Side)/sqrt(2); // obtain left signal from mid and side<br>\n\t\t * Right = (Mid-Side)/sqrt(2); // obtain right signal from mid and side<br>\n\t\t * </code>\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t */\n\t Tone.MidSideMerge = function () {\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(2, 0);\n\t /**\n\t\t\t * The mid signal input. Alias for\n\t\t\t * <code>input[0]</code>\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.mid = this.input[0] = new Tone.Gain();\n\t /**\n\t\t\t * recombine the mid/side into Left\n\t\t\t * @type {Tone.Add}\n\t\t\t * @private\n\t\t\t */\n\t this._left = new Tone.Add();\n\t /**\n\t\t\t * Multiply the left by sqrt(1/2)\n\t\t\t * @type {Tone.Multiply}\n\t\t\t */\n\t this._timesTwoLeft = new Tone.Multiply(Math.SQRT1_2);\n\t /**\n\t\t\t * The side signal input. Alias for\n\t\t\t * <code>input[1]</code>\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.side = this.input[1] = new Tone.Gain();\n\t /**\n\t\t\t * recombine the mid/side into Right\n\t\t\t * @type {Tone.Subtract}\n\t\t\t * @private\n\t\t\t */\n\t this._right = new Tone.Subtract();\n\t /**\n\t\t\t * Multiply the right by sqrt(1/2)\n\t\t\t * @type {Tone.Multiply}\n\t\t\t */\n\t this._timesTwoRight = new Tone.Multiply(Math.SQRT1_2);\n\t /**\n\t\t\t * Merge the left/right signal back into a stereo signal.\n\t\t\t * @type {Tone.Merge}\n\t\t\t * @private\n\t\t\t */\n\t this._merge = this.output = new Tone.Merge();\n\t this.mid.connect(this._left, 0, 0);\n\t this.side.connect(this._left, 0, 1);\n\t this.mid.connect(this._right, 0, 0);\n\t this.side.connect(this._right, 0, 1);\n\t this._left.connect(this._timesTwoLeft);\n\t this._right.connect(this._timesTwoRight);\n\t this._timesTwoLeft.connect(this._merge, 0, 0);\n\t this._timesTwoRight.connect(this._merge, 0, 1);\n\t };\n\t Tone.extend(Tone.MidSideMerge, Tone.AudioNode);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.MidSideMerge} this\n\t\t */\n\t Tone.MidSideMerge.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.mid.dispose();\n\t this.mid = null;\n\t this.side.dispose();\n\t this.side = null;\n\t this._left.dispose();\n\t this._left = null;\n\t this._timesTwoLeft.dispose();\n\t this._timesTwoLeft = null;\n\t this._right.dispose();\n\t this._right = null;\n\t this._timesTwoRight.dispose();\n\t this._timesTwoRight = null;\n\t this._merge.dispose();\n\t this._merge = null;\n\t return this;\n\t };\n\t return Tone.MidSideMerge;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.MidSideCompressor applies two different compressors to the mid\n\t\t * and side signal components. See Tone.MidSideSplit.\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Object} options The options that are passed to the mid and side\n\t\t * compressors.\n\t\t * @constructor\n\t\t */\n\t Tone.MidSideCompressor = function (options) {\n\t Tone.AudioNode.call(this);\n\t options = Tone.defaultArg(options, Tone.MidSideCompressor.defaults);\n\t /**\n\t\t\t * the mid/side split\n\t\t\t * @type {Tone.MidSideSplit}\n\t\t\t * @private\n\t\t\t */\n\t this._midSideSplit = this.input = new Tone.MidSideSplit();\n\t /**\n\t\t\t * the mid/side recombination\n\t\t\t * @type {Tone.MidSideMerge}\n\t\t\t * @private\n\t\t\t */\n\t this._midSideMerge = this.output = new Tone.MidSideMerge();\n\t /**\n\t\t\t * The compressor applied to the mid signal\n\t\t\t * @type {Tone.Compressor}\n\t\t\t */\n\t this.mid = new Tone.Compressor(options.mid);\n\t /**\n\t\t\t * The compressor applied to the side signal\n\t\t\t * @type {Tone.Compressor}\n\t\t\t */\n\t this.side = new Tone.Compressor(options.side);\n\t this._midSideSplit.mid.chain(this.mid, this._midSideMerge.mid);\n\t this._midSideSplit.side.chain(this.side, this._midSideMerge.side);\n\t this._readOnly([\n\t 'mid',\n\t 'side'\n\t ]);\n\t };\n\t Tone.extend(Tone.MidSideCompressor, Tone.AudioNode);\n\t /**\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.MidSideCompressor.defaults = {\n\t 'mid': {\n\t 'ratio': 3,\n\t 'threshold': -24,\n\t 'release': 0.03,\n\t 'attack': 0.02,\n\t 'knee': 16\n\t },\n\t 'side': {\n\t 'ratio': 6,\n\t 'threshold': -30,\n\t 'release': 0.25,\n\t 'attack': 0.03,\n\t 'knee': 10\n\t }\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.MidSideCompressor} this\n\t\t */\n\t Tone.MidSideCompressor.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'mid',\n\t 'side'\n\t ]);\n\t this.mid.dispose();\n\t this.mid = null;\n\t this.side.dispose();\n\t this.side = null;\n\t this._midSideSplit.dispose();\n\t this._midSideSplit = null;\n\t this._midSideMerge.dispose();\n\t this._midSideMerge = null;\n\t return this;\n\t };\n\t return Tone.MidSideCompressor;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Mono coerces the incoming mono or stereo signal into a mono signal\n\t\t * where both left and right channels have the same value. This can be useful\n\t\t * for [stereo imaging](https://en.wikipedia.org/wiki/Stereo_imaging).\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t */\n\t Tone.Mono = function () {\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(1, 0);\n\t /**\n\t\t\t * merge the signal\n\t\t\t * @type {Tone.Merge}\n\t\t\t * @private\n\t\t\t */\n\t this._merge = this.output = new Tone.Merge();\n\t this.input.connect(this._merge, 0, 0);\n\t this.input.connect(this._merge, 0, 1);\n\t };\n\t Tone.extend(Tone.Mono, Tone.AudioNode);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Mono} this\n\t\t */\n\t Tone.Mono.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._merge.dispose();\n\t this._merge = null;\n\t return this;\n\t };\n\t return Tone.Mono;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A compressor with seperate controls over low/mid/high dynamics\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {Object} options The low/mid/high compressor settings.\n\t\t * @example\n\t\t * var multiband = new Tone.MultibandCompressor({\n\t\t * \t\"lowFrequency\" : 200,\n\t\t * \t\"highFrequency\" : 1300\n\t\t * \t\"low\" : {\n\t\t * \t\t\"threshold\" : -12\n\t\t * \t}\n\t\t * })\n\t\t */\n\t Tone.MultibandCompressor = function (options) {\n\t Tone.AudioNode.call(this);\n\t options = Tone.defaultArg(arguments, Tone.MultibandCompressor.defaults);\n\t /**\n\t\t\t * split the incoming signal into high/mid/low\n\t\t\t * @type {Tone.MultibandSplit}\n\t\t\t * @private\n\t\t\t */\n\t this._splitter = this.input = new Tone.MultibandSplit({\n\t 'lowFrequency': options.lowFrequency,\n\t 'highFrequency': options.highFrequency\n\t });\n\t /**\n\t\t\t * low/mid crossover frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.lowFrequency = this._splitter.lowFrequency;\n\t /**\n\t\t\t * mid/high crossover frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.highFrequency = this._splitter.highFrequency;\n\t /**\n\t\t\t * the output\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this.output = new Tone.Gain();\n\t /**\n\t\t\t * The compressor applied to the low frequencies.\n\t\t\t * @type {Tone.Compressor}\n\t\t\t */\n\t this.low = new Tone.Compressor(options.low);\n\t /**\n\t\t\t * The compressor applied to the mid frequencies.\n\t\t\t * @type {Tone.Compressor}\n\t\t\t */\n\t this.mid = new Tone.Compressor(options.mid);\n\t /**\n\t\t\t * The compressor applied to the high frequencies.\n\t\t\t * @type {Tone.Compressor}\n\t\t\t */\n\t this.high = new Tone.Compressor(options.high);\n\t //connect the compressor\n\t this._splitter.low.chain(this.low, this.output);\n\t this._splitter.mid.chain(this.mid, this.output);\n\t this._splitter.high.chain(this.high, this.output);\n\t this._readOnly([\n\t 'high',\n\t 'mid',\n\t 'low',\n\t 'highFrequency',\n\t 'lowFrequency'\n\t ]);\n\t };\n\t Tone.extend(Tone.MultibandCompressor, Tone.AudioNode);\n\t /**\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.MultibandCompressor.defaults = {\n\t 'low': Tone.Compressor.defaults,\n\t 'mid': Tone.Compressor.defaults,\n\t 'high': Tone.Compressor.defaults,\n\t 'lowFrequency': 250,\n\t 'highFrequency': 2000\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.MultibandCompressor} this\n\t\t */\n\t Tone.MultibandCompressor.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._splitter.dispose();\n\t this._writable([\n\t 'high',\n\t 'mid',\n\t 'low',\n\t 'highFrequency',\n\t 'lowFrequency'\n\t ]);\n\t this.low.dispose();\n\t this.mid.dispose();\n\t this.high.dispose();\n\t this._splitter = null;\n\t this.low = null;\n\t this.mid = null;\n\t this.high = null;\n\t this.lowFrequency = null;\n\t this.highFrequency = null;\n\t return this;\n\t };\n\t return Tone.MultibandCompressor;\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported && !window.StereoPannerNode) {\n\t /**\n\t\t\t * @class Shimmed StereoPannerNode\n\t\t\t * @param {AudioContext} context\n\t\t\t * @private\n\t\t\t */\n\t var StereoPannerNode = function (context) {\n\t /**\n\t\t\t\t * The audio context\n\t\t\t\t * @type {AudioContext}\n\t\t\t\t */\n\t this.context = context;\n\t /**\n\t\t\t\t * The left/right panning. [-1, 1]\n\t\t\t\t * @type {AudioRange}\n\t\t\t\t * @signal\n\t\t\t\t */\n\t this.pan = new Tone.Signal(0, Tone.Type.AudioRange);\n\t /**\n\t\t\t\t * Equal power scaling of the right gain\n\t\t\t\t * @type {Tone.WaveShaper}\n\t\t\t\t */\n\t var rightWaveShaper = new Tone.WaveShaper(function (val) {\n\t return Tone.equalPowerScale((val + 1) / 2);\n\t }, 4096);\n\t /**\n\t\t\t\t * Equal power scaling of the left gain\n\t\t\t\t * @type {Tone.WaveShaper}\n\t\t\t\t * @private\n\t\t\t\t */\n\t var leftWaveShaper = new Tone.WaveShaper(function (val) {\n\t return Tone.equalPowerScale(1 - (val + 1) / 2);\n\t }, 4096);\n\t /**\n\t\t\t\t * The left gain value\n\t\t\t\t * @type {Tone.Gain}\n\t\t\t\t * @private\n\t\t\t\t */\n\t var leftGain = new Tone.Gain();\n\t /**\n\t\t\t\t * The right gain value\n\t\t\t\t * @type {Tone.Gain}\n\t\t\t\t * @private\n\t\t\t\t */\n\t var rightGain = new Tone.Gain();\n\t /**\n\t\t\t\t * Split the incoming signal\n\t\t\t\t * @type {Tone.Split}\n\t\t\t\t * @private\n\t\t\t\t */\n\t var split = this.input = new Tone.Split();\n\t /**\n\t\t\t\t * Keeps the waveshapers from optimizing 0s\n\t\t\t\t * @type {Tone.Zero}\n\t\t\t\t * @private\n\t\t\t\t */\n\t var zero = new Tone.Zero();\n\t zero.fan(rightWaveShaper, leftWaveShaper);\n\t /**\n\t\t\t\t * Merge the outgoing signal\n\t\t\t\t * @type {Tone.Merge}\n\t\t\t\t * @private\n\t\t\t\t */\n\t var merge = this.output = new Tone.Merge();\n\t //connections\n\t split.left.chain(leftGain, merge.left);\n\t split.right.chain(rightGain, merge.right);\n\t this.pan.chain(leftWaveShaper, leftGain.gain);\n\t this.pan.chain(rightWaveShaper, rightGain.gain);\n\t };\n\t StereoPannerNode.prototype.disconnect = function () {\n\t this.output.disconnect.apply(this.output, arguments);\n\t };\n\t StereoPannerNode.prototype.connect = function () {\n\t this.output.connect.apply(this.output, arguments);\n\t };\n\t //add it to the AudioContext\n\t AudioContext.prototype.createStereoPanner = function () {\n\t return new StereoPannerNode(this);\n\t };\n\t Tone.Context.prototype.createStereoPanner = function () {\n\t return new StereoPannerNode(this);\n\t };\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Panner is an equal power Left/Right Panner and does not\n\t\t * support 3D. Panner uses the StereoPannerNode when available.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {NormalRange} [initialPan=0] The initail panner value (center).\n\t\t * @example\n\t\t * //pan the input signal hard right.\n\t\t * var panner = new Tone.Panner(1);\n\t\t */\n\t Tone.Panner = function (initialPan) {\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t* the panner node\n\t\t\t* @type {StereoPannerNode}\n\t\t\t* @private\n\t\t\t*/\n\t this._panner = this.input = this.output = this.context.createStereoPanner();\n\t /**\n\t\t\t* The pan control. -1 = hard left, 1 = hard right.\n\t\t\t* @type {AudioRange}\n\t\t\t* @signal\n\t\t\t*/\n\t this.pan = this._panner.pan;\n\t //initial value\n\t this.pan.value = Tone.defaultArg(initialPan, 0);\n\t this._readOnly('pan');\n\t };\n\t Tone.extend(Tone.Panner, Tone.AudioNode);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Panner} this\n\t\t */\n\t Tone.Panner.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable('pan');\n\t this._panner.disconnect();\n\t this._panner = null;\n\t this.pan = null;\n\t return this;\n\t };\n\t return Tone.Panner;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A spatialized panner node which supports equalpower or HRTF panning.\n\t\t * Tries to normalize the API across various browsers. See Tone.Listener\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Number} positionX The initial x position.\n\t\t * @param {Number} positionY The initial y position.\n\t\t * @param {Number} positionZ The initial z position.\n\t\t */\n\t Tone.Panner3D = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'positionX',\n\t 'positionY',\n\t 'positionZ'\n\t ], Tone.Panner3D);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The panner node\n\t\t\t * @type {PannerNode}\n\t\t\t * @private\n\t\t\t */\n\t this._panner = this.input = this.output = this.context.createPanner();\n\t //set some values\n\t this._panner.panningModel = options.panningModel;\n\t this._panner.maxDistance = options.maxDistance;\n\t this._panner.distanceModel = options.distanceModel;\n\t this._panner.coneOuterGain = options.coneOuterGain;\n\t this._panner.coneOuterAngle = options.coneOuterAngle;\n\t this._panner.coneInnerAngle = options.coneInnerAngle;\n\t this._panner.refDistance = options.refDistance;\n\t this._panner.rolloffFactor = options.rolloffFactor;\n\t /**\n\t\t\t * Holds the current orientation\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._orientation = [\n\t options.orientationX,\n\t options.orientationY,\n\t options.orientationZ\n\t ];\n\t /**\n\t\t\t * Holds the current position\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._position = [\n\t options.positionX,\n\t options.positionY,\n\t options.positionZ\n\t ];\n\t // set the default position/orientation\n\t this.orientationX = options.orientationX;\n\t this.orientationY = options.orientationY;\n\t this.orientationZ = options.orientationZ;\n\t this.positionX = options.positionX;\n\t this.positionY = options.positionY;\n\t this.positionZ = options.positionZ;\n\t };\n\t Tone.extend(Tone.Panner3D, Tone.AudioNode);\n\t /**\n\t\t * Defaults according to the specification\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Panner3D.defaults = {\n\t 'positionX': 0,\n\t 'positionY': 0,\n\t 'positionZ': 0,\n\t 'orientationX': 0,\n\t 'orientationY': 0,\n\t 'orientationZ': 0,\n\t 'panningModel': 'equalpower',\n\t 'maxDistance': 10000,\n\t 'distanceModel': 'inverse',\n\t 'coneOuterGain': 0,\n\t 'coneOuterAngle': 360,\n\t 'coneInnerAngle': 360,\n\t 'refDistance': 1,\n\t 'rolloffFactor': 1\n\t };\n\t /**\n\t\t * The ramp time which is applied to the setTargetAtTime\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.Panner3D.prototype._rampTimeConstant = 0.01;\n\t /**\n\t\t * Sets the position of the source in 3d space.\n\t\t * @param {Number} x\n\t\t * @param {Number} y\n\t\t * @param {Number} z\n\t\t * @return {Tone.Panner3D} this\n\t\t */\n\t Tone.Panner3D.prototype.setPosition = function (x, y, z) {\n\t if (this._panner.positionX) {\n\t var now = this.now();\n\t this._panner.positionX.setTargetAtTime(x, now, this._rampTimeConstant);\n\t this._panner.positionY.setTargetAtTime(y, now, this._rampTimeConstant);\n\t this._panner.positionZ.setTargetAtTime(z, now, this._rampTimeConstant);\n\t } else {\n\t this._panner.setPosition(x, y, z);\n\t }\n\t this._position = Array.prototype.slice.call(arguments);\n\t return this;\n\t };\n\t /**\n\t\t * Sets the orientation of the source in 3d space.\n\t\t * @param {Number} x\n\t\t * @param {Number} y\n\t\t * @param {Number} z\n\t\t * @return {Tone.Panner3D} this\n\t\t */\n\t Tone.Panner3D.prototype.setOrientation = function (x, y, z) {\n\t if (this._panner.orientationX) {\n\t var now = this.now();\n\t this._panner.orientationX.setTargetAtTime(x, now, this._rampTimeConstant);\n\t this._panner.orientationY.setTargetAtTime(y, now, this._rampTimeConstant);\n\t this._panner.orientationZ.setTargetAtTime(z, now, this._rampTimeConstant);\n\t } else {\n\t this._panner.setOrientation(x, y, z);\n\t }\n\t this._orientation = Array.prototype.slice.call(arguments);\n\t return this;\n\t };\n\t /**\n\t\t * The x position of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name positionX\n\t\t */\n\t Object.defineProperty(Tone.Panner3D.prototype, 'positionX', {\n\t set: function (pos) {\n\t this._position[0] = pos;\n\t this.setPosition.apply(this, this._position);\n\t },\n\t get: function () {\n\t return this._position[0];\n\t }\n\t });\n\t /**\n\t\t * The y position of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name positionY\n\t\t */\n\t Object.defineProperty(Tone.Panner3D.prototype, 'positionY', {\n\t set: function (pos) {\n\t this._position[1] = pos;\n\t this.setPosition.apply(this, this._position);\n\t },\n\t get: function () {\n\t return this._position[1];\n\t }\n\t });\n\t /**\n\t\t * The z position of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name positionZ\n\t\t */\n\t Object.defineProperty(Tone.Panner3D.prototype, 'positionZ', {\n\t set: function (pos) {\n\t this._position[2] = pos;\n\t this.setPosition.apply(this, this._position);\n\t },\n\t get: function () {\n\t return this._position[2];\n\t }\n\t });\n\t /**\n\t\t * The x orientation of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name orientationX\n\t\t */\n\t Object.defineProperty(Tone.Panner3D.prototype, 'orientationX', {\n\t set: function (pos) {\n\t this._orientation[0] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[0];\n\t }\n\t });\n\t /**\n\t\t * The y orientation of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name orientationY\n\t\t */\n\t Object.defineProperty(Tone.Panner3D.prototype, 'orientationY', {\n\t set: function (pos) {\n\t this._orientation[1] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[1];\n\t }\n\t });\n\t /**\n\t\t * The z orientation of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name orientationZ\n\t\t */\n\t Object.defineProperty(Tone.Panner3D.prototype, 'orientationZ', {\n\t set: function (pos) {\n\t this._orientation[2] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[2];\n\t }\n\t });\n\t /**\n\t\t * Proxy a property on the panner to an exposed public propery\n\t\t * @param {String} prop\n\t\t * @private\n\t\t */\n\t Tone.Panner3D._aliasProperty = function (prop) {\n\t Object.defineProperty(Tone.Panner3D.prototype, prop, {\n\t set: function (val) {\n\t this._panner[prop] = val;\n\t },\n\t get: function () {\n\t return this._panner[prop];\n\t }\n\t });\n\t };\n\t /**\n\t\t * The panning model. Either \"equalpower\" or \"HRTF\".\n\t\t * @type {String}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name panningModel\n\t\t */\n\t Tone.Panner3D._aliasProperty('panningModel');\n\t /**\n\t\t * A reference distance for reducing volume as source move further from the listener\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name refDistance\n\t\t */\n\t Tone.Panner3D._aliasProperty('refDistance');\n\t /**\n\t\t * Describes how quickly the volume is reduced as source moves away from listener.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name rolloffFactor\n\t\t */\n\t Tone.Panner3D._aliasProperty('rolloffFactor');\n\t /**\n\t\t * The distance model used by, \"linear\", \"inverse\", or \"exponential\".\n\t\t * @type {String}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name distanceModel\n\t\t */\n\t Tone.Panner3D._aliasProperty('distanceModel');\n\t /**\n\t\t * The angle, in degrees, inside of which there will be no volume reduction\n\t\t * @type {Degrees}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name coneInnerAngle\n\t\t */\n\t Tone.Panner3D._aliasProperty('coneInnerAngle');\n\t /**\n\t\t * The angle, in degrees, outside of which the volume will be reduced\n\t\t * to a constant value of coneOuterGain\n\t\t * @type {Degrees}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name coneOuterAngle\n\t\t */\n\t Tone.Panner3D._aliasProperty('coneOuterAngle');\n\t /**\n\t\t * The gain outside of the coneOuterAngle\n\t\t * @type {Gain}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name coneOuterGain\n\t\t */\n\t Tone.Panner3D._aliasProperty('coneOuterGain');\n\t /**\n\t\t * The maximum distance between source and listener,\n\t\t * after which the volume will not be reduced any further.\n\t\t * @type {Positive}\n\t\t * @memberOf Tone.Panner3D#\n\t\t * @name maxDistance\n\t\t */\n\t Tone.Panner3D._aliasProperty('maxDistance');\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Panner3D} this\n\t\t */\n\t Tone.Panner3D.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._panner.disconnect();\n\t this._panner = null;\n\t this._orientation = null;\n\t this._position = null;\n\t return this;\n\t };\n\t return Tone.Panner3D;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.PanVol is a Tone.Panner and Tone.Volume in one.\n\t\t *\n\t\t * @extends {Tone.AudioNode}\n\t\t * @constructor\n\t\t * @param {AudioRange} pan the initial pan\n\t\t * @param {number} volume The output volume.\n\t\t * @example\n\t\t * //pan the incoming signal left and drop the volume\n\t\t * var panVol = new Tone.PanVol(-0.25, -12);\n\t\t */\n\t Tone.PanVol = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'pan',\n\t 'volume'\n\t ], Tone.PanVol);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The panning node\n\t\t\t * @type {Tone.Panner}\n\t\t\t * @private\n\t\t\t */\n\t this._panner = this.input = new Tone.Panner(options.pan);\n\t /**\n\t\t\t * The L/R panning control.\n\t\t\t * @type {AudioRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.pan = this._panner.pan;\n\t /**\n\t\t\t * The volume node\n\t\t\t * @type {Tone.Volume}\n\t\t\t * @private\n\t\t\t */\n\t this._volume = this.output = new Tone.Volume(options.volume);\n\t /**\n\t\t\t * The volume control in decibels.\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t */\n\t this.volume = this._volume.volume;\n\t //connections\n\t this._panner.connect(this._volume);\n\t this.mute = options.mute;\n\t this._readOnly([\n\t 'pan',\n\t 'volume'\n\t ]);\n\t };\n\t Tone.extend(Tone.PanVol, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @type {Object}\n\t\t * @const\n\t\t * @static\n\t\t */\n\t Tone.PanVol.defaults = {\n\t 'pan': 0,\n\t 'volume': 0,\n\t 'mute': false\n\t };\n\t /**\n\t\t * Mute/unmute the volume\n\t\t * @memberOf Tone.PanVol#\n\t\t * @name mute\n\t\t * @type {Boolean}\n\t\t */\n\t Object.defineProperty(Tone.PanVol.prototype, 'mute', {\n\t get: function () {\n\t return this._volume.mute;\n\t },\n\t set: function (mute) {\n\t this._volume.mute = mute;\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.PanVol} this\n\t\t */\n\t Tone.PanVol.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._writable([\n\t 'pan',\n\t 'volume'\n\t ]);\n\t this._panner.dispose();\n\t this._panner = null;\n\t this.pan = null;\n\t this._volume.dispose();\n\t this._volume = null;\n\t this.volume = null;\n\t return this;\n\t };\n\t return Tone.PanVol;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Solo lets you isolate a specific audio stream. When\n\t\t * an instance is set to `solo=true`, it will mute all other instances.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @example\n\t\t * var soloA = new Tone.Solo()\n\t\t * var soloB = new Tone.Solo()\n\t\t * soloA.solo = true\n\t\t * //no audio will pass through soloB\n\t\t */\n\t Tone.Solo = function () {\n\t var options = Tone.defaults(arguments, ['solo'], Tone.Solo);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The input and output node\n\t\t\t * @type {Tone.Gain}\n\t\t\t */\n\t this.input = this.output = new Tone.Gain();\n\t /**\n\t\t\t * A bound _soloed method\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._soloBind = this._soloed.bind(this);\n\t //listen for solo events class-wide.\n\t this.context.on('solo', this._soloBind);\n\t //set initially\n\t this.solo = options.solo;\n\t };\n\t Tone.extend(Tone.Solo, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @type {Object}\n\t\t * @static\n\t\t */\n\t Tone.Solo.defaults = { solo: false };\n\t /**\n\t\t * Isolates this instance and mutes all other instances of Tone.Solo.\n\t\t * Only one instance can be soloed at a time. A soloed\n\t\t * instance will report `solo=false` when another instance is soloed.\n\t\t * @memberOf Tone.Solo#\n\t\t * @type {Boolean}\n\t\t * @name solo\n\t\t */\n\t Object.defineProperty(Tone.Solo.prototype, 'solo', {\n\t get: function () {\n\t return this._isSoloed();\n\t },\n\t set: function (solo) {\n\t if (solo) {\n\t this._addSolo();\n\t } else {\n\t this._removeSolo();\n\t }\n\t this.context.emit('solo', this);\n\t }\n\t });\n\t /**\n\t\t * If the current instance is muted, i.e. another instance is soloed\n\t\t * @memberOf Tone.Solo#\n\t\t * @type {Boolean}\n\t\t * @name muted\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Solo.prototype, 'muted', {\n\t get: function () {\n\t return this.input.gain.value === 0;\n\t }\n\t });\n\t /**\n\t\t * Add this to the soloed array\n\t\t * @private\n\t\t */\n\t Tone.Solo.prototype._addSolo = function () {\n\t if (!Tone.isArray(this.context._currentSolo)) {\n\t this.context._currentSolo = [];\n\t }\n\t if (!this._isSoloed()) {\n\t this.context._currentSolo.push(this);\n\t }\n\t };\n\t /**\n\t\t * Remove this from the soloed array\n\t\t * @private\n\t\t */\n\t Tone.Solo.prototype._removeSolo = function () {\n\t if (this._isSoloed()) {\n\t var index = this.context._currentSolo.indexOf(this);\n\t this.context._currentSolo.splice(index, 1);\n\t }\n\t };\n\t /**\n\t\t * @return {Boolean} Is this on the soloed array\n\t\t * @private\n\t\t */\n\t Tone.Solo.prototype._isSoloed = function () {\n\t if (Tone.isArray(this.context._currentSolo)) {\n\t return this.context._currentSolo.length !== 0 && this.context._currentSolo.indexOf(this) !== -1;\n\t } else {\n\t return false;\n\t }\n\t };\n\t /**\n\t\t * @return {Boolean} Returns true if no one is soloed\n\t\t * @private\n\t\t */\n\t Tone.Solo.prototype._noSolos = function () {\n\t return !Tone.isArray(this.context._currentSolo) || this.context._currentSolo.length === 0;\n\t };\n\t /**\n\t\t * Solo the current instance and unsolo all other instances.\n\t\t * @param {Tone.Solo} instance The instance which is being soloed/unsoloed.\n\t\t * @private\n\t\t */\n\t Tone.Solo.prototype._soloed = function () {\n\t if (this._isSoloed()) {\n\t this.input.gain.value = 1;\n\t } else if (this._noSolos()) {\n\t //no one is soloed\n\t this.input.gain.value = 1;\n\t } else {\n\t this.input.gain.value = 0;\n\t }\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Solo} this\n\t\t */\n\t Tone.Solo.prototype.dispose = function () {\n\t this.context.off('solo', this._soloBind);\n\t this._removeSolo();\n\t this._soloBind = null;\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t return this;\n\t };\n\t return Tone.Solo;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Get the current waveform data of the connected audio source.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Number=} size The size of the FFT. Value must be a power of\n\t\t * two in the range 32 to 32768.\n\t\t */\n\t Tone.Waveform = function () {\n\t var options = Tone.defaults(arguments, ['size'], Tone.Waveform);\n\t options.type = Tone.Analyser.Type.Waveform;\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The analyser node.\n\t\t\t * @private\n\t\t\t * @type {Tone.Analyser}\n\t\t\t */\n\t this._analyser = this.input = this.output = new Tone.Analyser(options);\n\t };\n\t Tone.extend(Tone.Waveform, Tone.AudioNode);\n\t /**\n\t\t * The default values.\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Waveform.defaults = { 'size': 1024 };\n\t /**\n\t\t * Gets the waveform of the audio source. Returns the waveform data\n\t\t * of length [size](#size) as a Float32Array with values between -1 and 1.\n\t\t * @returns {TypedArray}\n\t\t */\n\t Tone.Waveform.prototype.getValue = function () {\n\t return this._analyser.getValue();\n\t };\n\t /**\n\t\t * The size of analysis. This must be a power of two in the range 32 to 32768.\n\t\t * @memberOf Tone.Waveform#\n\t\t * @type {Number}\n\t\t * @name size\n\t\t */\n\t Object.defineProperty(Tone.Waveform.prototype, 'size', {\n\t get: function () {\n\t return this._analyser.size;\n\t },\n\t set: function (size) {\n\t this._analyser.size = size;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Waveform} this\n\t\t */\n\t Tone.Waveform.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._analyser.dispose();\n\t this._analyser = null;\n\t };\n\t return Tone.Waveform;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.CtrlInterpolate will interpolate between given values based\n\t\t * on the \"index\" property. Passing in an array or object literal\n\t\t * will interpolate each of the parameters. Note (i.e. \"C3\")\n\t\t * and Time (i.e. \"4n + 2\") can be interpolated. All other values are\n\t\t * assumed to be numbers. \n\t\t * @example\n\t\t * var interp = new Tone.CtrlInterpolate([0, 2, 9, 4]);\n\t\t * interp.index = 0.75;\n\t\t * interp.value; //returns 1.5\n\t\t *\n\t\t * @example\n\t\t * var interp = new Tone.CtrlInterpolate([\n\t\t * \t[2, 4, 5],\n\t\t * \t[9, 3, 2],\n\t\t * ]);\n\t\t * @param {Array} values The array of values to interpolate over\n\t\t * @param {Positive} index The initial interpolation index.\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.CtrlInterpolate = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'values',\n\t 'index'\n\t ], Tone.CtrlInterpolate);\n\t Tone.call(this);\n\t /**\n\t\t\t * The values to interpolate between\n\t\t\t * @type {Array}\n\t\t\t */\n\t this.values = options.values;\n\t /**\n\t\t\t * The interpolated index between values. For example: a value of 1.5\n\t\t\t * would interpolate equally between the value at index 1\n\t\t\t * and the value at index 2. \n\t\t\t * @example\n\t\t\t * interp.index = 0; \n\t\t\t * interp.value; //returns the value at 0\n\t\t\t * interp.index = 0.5;\n\t\t\t * interp.value; //returns the value between indices 0 and 1. \n\t\t\t * @type {Positive}\n\t\t\t */\n\t this.index = options.index;\n\t };\n\t Tone.extend(Tone.CtrlInterpolate);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.CtrlInterpolate.defaults = {\n\t 'index': 0,\n\t 'values': []\n\t };\n\t /**\n\t\t * The current interpolated value based on the index\n\t\t * @readOnly\n\t\t * @memberOf Tone.CtrlInterpolate#\n\t\t * @type {*}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.CtrlInterpolate.prototype, 'value', {\n\t get: function () {\n\t var index = this.index;\n\t index = Math.min(index, this.values.length - 1);\n\t var lowerPosition = Math.floor(index);\n\t var lower = this.values[lowerPosition];\n\t var upper = this.values[Math.ceil(index)];\n\t return this._interpolate(index - lowerPosition, lower, upper);\n\t }\n\t });\n\t /**\n\t\t * Internal interpolation routine\n\t\t * @param {NormalRange} index The index between the lower and upper\n\t\t * @param {*} lower \n\t\t * @param {*} upper \n\t\t * @return {*} The interpolated value\n\t\t * @private\n\t\t */\n\t Tone.CtrlInterpolate.prototype._interpolate = function (index, lower, upper) {\n\t if (Tone.isArray(lower)) {\n\t var retArray = [];\n\t for (var i = 0; i < lower.length; i++) {\n\t retArray[i] = this._interpolate(index, lower[i], upper[i]);\n\t }\n\t return retArray;\n\t } else if (Tone.isObject(lower)) {\n\t var retObj = {};\n\t for (var attr in lower) {\n\t retObj[attr] = this._interpolate(index, lower[attr], upper[attr]);\n\t }\n\t return retObj;\n\t } else {\n\t lower = this._toNumber(lower);\n\t upper = this._toNumber(upper);\n\t return (1 - index) * lower + index * upper;\n\t }\n\t };\n\t /**\n\t\t * Convert from the given type into a number\n\t\t * @param {Number|String} value\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.CtrlInterpolate.prototype._toNumber = function (val) {\n\t if (Tone.isNumber(val)) {\n\t return val;\n\t } else {\n\t //otherwise assume that it's Time...\n\t return this.toSeconds(val);\n\t }\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.CtrlInterpolate} this\n\t\t */\n\t Tone.CtrlInterpolate.prototype.dispose = function () {\n\t this.values = null;\n\t };\n\t return Tone.CtrlInterpolate;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.CtrlMarkov represents a Markov Chain where each call\n\t\t * to Tone.CtrlMarkov.next will move to the next state. If the next\n\t\t * state choice is an array, the next state is chosen randomly with\n\t\t * even probability for all of the choices. For a weighted probability\n\t\t * of the next choices, pass in an object with \"state\" and \"probability\" attributes. \n\t\t * The probabilities will be normalized and then chosen. If no next options\n\t\t * are given for the current state, the state will stay there. \n\t\t * @extends {Tone}\n\t\t * @example\n\t\t * var chain = new Tone.CtrlMarkov({\n\t\t * \t\"beginning\" : [\"end\", \"middle\"],\n\t\t * \t\"middle\" : \"end\"\n\t\t * });\n\t\t * chain.value = \"beginning\";\n\t\t * chain.next(); //returns \"end\" or \"middle\" with 50% probability\n\t\t *\n\t\t * @example\n\t\t * var chain = new Tone.CtrlMarkov({\n\t\t * \t\"beginning\" : [{\"value\" : \"end\", \"probability\" : 0.8}, \n\t\t * \t\t\t\t\t{\"value\" : \"middle\", \"probability\" : 0.2}],\n\t\t * \t\"middle\" : \"end\"\n\t\t * });\n\t\t * chain.value = \"beginning\";\n\t\t * chain.next(); //returns \"end\" with 80% probability or \"middle\" with 20%.\n\t\t * @param {Object} values An object with the state names as the keys\n\t\t * and the next state(s) as the values. \n\t\t */\n\t Tone.CtrlMarkov = function (values, initial) {\n\t Tone.call(this);\n\t /**\n\t\t\t * The Markov values with states as the keys\n\t\t\t * and next state(s) as the values. \n\t\t\t * @type {Object}\n\t\t\t */\n\t this.values = Tone.defaultArg(values, {});\n\t /**\n\t\t\t * The current state of the Markov values. The next\n\t\t\t * state will be evaluated and returned when Tone.CtrlMarkov.next\n\t\t\t * is invoked.\n\t\t\t * @type {String}\n\t\t\t */\n\t this.value = Tone.defaultArg(initial, Object.keys(this.values)[0]);\n\t };\n\t Tone.extend(Tone.CtrlMarkov);\n\t /**\n\t\t * Returns the next state of the Markov values. \n\t\t * @return {String}\n\t\t */\n\t Tone.CtrlMarkov.prototype.next = function () {\n\t if (this.values.hasOwnProperty(this.value)) {\n\t var next = this.values[this.value];\n\t if (Tone.isArray(next)) {\n\t var distribution = this._getProbDistribution(next);\n\t var rand = Math.random();\n\t var total = 0;\n\t for (var i = 0; i < distribution.length; i++) {\n\t var dist = distribution[i];\n\t if (rand > total && rand < total + dist) {\n\t var chosen = next[i];\n\t if (Tone.isObject(chosen)) {\n\t this.value = chosen.value;\n\t } else {\n\t this.value = chosen;\n\t }\n\t }\n\t total += dist;\n\t }\n\t } else {\n\t this.value = next;\n\t }\n\t }\n\t return this.value;\n\t };\n\t /**\n\t\t * Choose randomly from an array weighted options in the form \n\t\t * {\"state\" : string, \"probability\" : number} or an array of values\n\t\t * @param {Array} options \n\t\t * @return {Array} The randomly selected choice\n\t\t * @private\n\t\t */\n\t Tone.CtrlMarkov.prototype._getProbDistribution = function (options) {\n\t var distribution = [];\n\t var total = 0;\n\t var needsNormalizing = false;\n\t for (var i = 0; i < options.length; i++) {\n\t var option = options[i];\n\t if (Tone.isObject(option)) {\n\t needsNormalizing = true;\n\t distribution[i] = option.probability;\n\t } else {\n\t distribution[i] = 1 / options.length;\n\t }\n\t total += distribution[i];\n\t }\n\t if (needsNormalizing) {\n\t //normalize the values\n\t for (var j = 0; j < distribution.length; j++) {\n\t distribution[j] = distribution[j] / total;\n\t }\n\t }\n\t return distribution;\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.CtrlMarkov} this\n\t\t */\n\t Tone.CtrlMarkov.prototype.dispose = function () {\n\t this.values = null;\n\t };\n\t return Tone.CtrlMarkov;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Generate patterns from an array of values.\n\t\t * Has a number of arpeggiation and randomized\n\t\t * selection patterns. \n\t\t * <ul>\n\t\t * \t <li>\"up\" - cycles upward</li>\n\t\t * \t\t\t<li>\"down\" - cycles downward</li>\n\t\t * \t\t\t<li>\"upDown\" - up then and down</li>\n\t\t * \t\t\t<li>\"downUp\" - cycles down then and up</li>\n\t\t * \t\t\t<li>\"alternateUp\" - jump up two and down one</li>\n\t\t * \t\t\t<li>\"alternateDown\" - jump down two and up one</li>\n\t\t * \t\t\t<li>\"random\" - randomly select an index</li>\n\t\t * \t\t\t<li>\"randomWalk\" - randomly moves one index away from the current position</li>\n\t\t * \t\t\t<li>\"randomOnce\" - randomly select an index without repeating until all values have been chosen.</li>\n\t\t * \t\t</ul>\n\t\t * @param {Array} values An array of options to choose from.\n\t\t * @param {Tone.CtrlPattern.Type=} type The name of the pattern.\n\t\t * @extends {Tone}\n\t\t */\n\t Tone.CtrlPattern = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'values',\n\t 'type'\n\t ], Tone.CtrlPattern);\n\t Tone.call(this);\n\t /**\n\t\t\t * The array of values to arpeggiate over\n\t\t\t * @type {Array}\n\t\t\t */\n\t this.values = options.values;\n\t /**\n\t\t\t * The current position in the values array\n\t\t\t * @type {Number}\n\t\t\t */\n\t this.index = 0;\n\t /**\n\t\t\t * The type placeholder\n\t\t\t * @type {Tone.CtrlPattern.Type}\n\t\t\t * @private\n\t\t\t */\n\t this._type = null;\n\t /**\n\t\t\t * Shuffled values for the RandomOnce type\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._shuffled = null;\n\t /**\n\t\t\t * The direction of the movement\n\t\t\t * @type {String}\n\t\t\t * @private\n\t\t\t */\n\t this._direction = null;\n\t this.type = options.type;\n\t };\n\t Tone.extend(Tone.CtrlPattern);\n\t /**\n\t\t * The Control Patterns\n\t\t * @type {Object}\n\t\t * @static\n\t\t */\n\t Tone.CtrlPattern.Type = {\n\t Up: 'up',\n\t Down: 'down',\n\t UpDown: 'upDown',\n\t DownUp: 'downUp',\n\t AlternateUp: 'alternateUp',\n\t AlternateDown: 'alternateDown',\n\t Random: 'random',\n\t RandomWalk: 'randomWalk',\n\t RandomOnce: 'randomOnce'\n\t };\n\t /**\n\t\t * The default values. \n\t\t * @type {Object}\n\t\t */\n\t Tone.CtrlPattern.defaults = {\n\t 'type': Tone.CtrlPattern.Type.Up,\n\t 'values': []\n\t };\n\t /**\n\t\t * The value at the current index of the pattern.\n\t\t * @readOnly\n\t\t * @memberOf Tone.CtrlPattern#\n\t\t * @type {*}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.CtrlPattern.prototype, 'value', {\n\t get: function () {\n\t //some safeguards\n\t if (this.values.length === 0) {\n\t return;\n\t } else if (this.values.length === 1) {\n\t return this.values[0];\n\t }\n\t this.index = Math.min(this.index, this.values.length - 1);\n\t var val = this.values[this.index];\n\t if (this.type === Tone.CtrlPattern.Type.RandomOnce) {\n\t if (this.values.length !== this._shuffled.length) {\n\t this._shuffleValues();\n\t }\n\t val = this.values[this._shuffled[this.index]];\n\t }\n\t return val;\n\t }\n\t });\n\t /**\n\t\t * The pattern used to select the next\n\t\t * item from the values array\n\t\t * @memberOf Tone.CtrlPattern#\n\t\t * @type {Tone.CtrlPattern.Type}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.CtrlPattern.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t this._type = type;\n\t this._shuffled = null;\n\t //the first index\n\t if (this._type === Tone.CtrlPattern.Type.Up || this._type === Tone.CtrlPattern.Type.UpDown || this._type === Tone.CtrlPattern.Type.RandomOnce || this._type === Tone.CtrlPattern.Type.AlternateUp) {\n\t this.index = 0;\n\t } else if (this._type === Tone.CtrlPattern.Type.Down || this._type === Tone.CtrlPattern.Type.DownUp || this._type === Tone.CtrlPattern.Type.AlternateDown) {\n\t this.index = this.values.length - 1;\n\t }\n\t //the direction\n\t if (this._type === Tone.CtrlPattern.Type.UpDown || this._type === Tone.CtrlPattern.Type.AlternateUp) {\n\t this._direction = Tone.CtrlPattern.Type.Up;\n\t } else if (this._type === Tone.CtrlPattern.Type.DownUp || this._type === Tone.CtrlPattern.Type.AlternateDown) {\n\t this._direction = Tone.CtrlPattern.Type.Down;\n\t }\n\t //randoms\n\t if (this._type === Tone.CtrlPattern.Type.RandomOnce) {\n\t this._shuffleValues();\n\t } else if (this._type === Tone.CtrlPattern.Random) {\n\t this.index = Math.floor(Math.random() * this.values.length);\n\t }\n\t }\n\t });\n\t /**\n\t\t * Return the next value given the current position\n\t\t * and pattern.\n\t\t * @return {*} The next value\n\t\t */\n\t Tone.CtrlPattern.prototype.next = function () {\n\t var type = this.type;\n\t //choose the next index\n\t if (type === Tone.CtrlPattern.Type.Up) {\n\t this.index++;\n\t if (this.index >= this.values.length) {\n\t this.index = 0;\n\t }\n\t } else if (type === Tone.CtrlPattern.Type.Down) {\n\t this.index--;\n\t if (this.index < 0) {\n\t this.index = this.values.length - 1;\n\t }\n\t } else if (type === Tone.CtrlPattern.Type.UpDown || type === Tone.CtrlPattern.Type.DownUp) {\n\t if (this._direction === Tone.CtrlPattern.Type.Up) {\n\t this.index++;\n\t } else {\n\t this.index--;\n\t }\n\t if (this.index < 0) {\n\t this.index = 1;\n\t this._direction = Tone.CtrlPattern.Type.Up;\n\t } else if (this.index >= this.values.length) {\n\t this.index = this.values.length - 2;\n\t this._direction = Tone.CtrlPattern.Type.Down;\n\t }\n\t } else if (type === Tone.CtrlPattern.Type.Random) {\n\t this.index = Math.floor(Math.random() * this.values.length);\n\t } else if (type === Tone.CtrlPattern.Type.RandomWalk) {\n\t if (Math.random() < 0.5) {\n\t this.index--;\n\t this.index = Math.max(this.index, 0);\n\t } else {\n\t this.index++;\n\t this.index = Math.min(this.index, this.values.length - 1);\n\t }\n\t } else if (type === Tone.CtrlPattern.Type.RandomOnce) {\n\t this.index++;\n\t if (this.index >= this.values.length) {\n\t this.index = 0;\n\t //reshuffle the values for next time\n\t this._shuffleValues();\n\t }\n\t } else if (type === Tone.CtrlPattern.Type.AlternateUp) {\n\t if (this._direction === Tone.CtrlPattern.Type.Up) {\n\t this.index += 2;\n\t this._direction = Tone.CtrlPattern.Type.Down;\n\t } else {\n\t this.index -= 1;\n\t this._direction = Tone.CtrlPattern.Type.Up;\n\t }\n\t if (this.index >= this.values.length) {\n\t this.index = 0;\n\t this._direction = Tone.CtrlPattern.Type.Up;\n\t }\n\t } else if (type === Tone.CtrlPattern.Type.AlternateDown) {\n\t if (this._direction === Tone.CtrlPattern.Type.Up) {\n\t this.index += 1;\n\t this._direction = Tone.CtrlPattern.Type.Down;\n\t } else {\n\t this.index -= 2;\n\t this._direction = Tone.CtrlPattern.Type.Up;\n\t }\n\t if (this.index < 0) {\n\t this.index = this.values.length - 1;\n\t this._direction = Tone.CtrlPattern.Type.Down;\n\t }\n\t }\n\t return this.value;\n\t };\n\t /**\n\t\t * Shuffles the values and places the results into the _shuffled\n\t\t * @private\n\t\t */\n\t Tone.CtrlPattern.prototype._shuffleValues = function () {\n\t var copy = [];\n\t this._shuffled = [];\n\t for (var i = 0; i < this.values.length; i++) {\n\t copy[i] = i;\n\t }\n\t while (copy.length > 0) {\n\t var randVal = copy.splice(Math.floor(copy.length * Math.random()), 1);\n\t this._shuffled.push(randVal[0]);\n\t }\n\t };\n\t /**\n\t\t * Clean up\n\t\t * @returns {Tone.CtrlPattern} this\n\t\t */\n\t Tone.CtrlPattern.prototype.dispose = function () {\n\t this._shuffled = null;\n\t this.values = null;\n\t };\n\t return Tone.CtrlPattern;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Choose a random value.\n\t\t * @extends {Tone}\n\t\t * @example\n\t\t * var randomWalk = new Tone.CtrlRandom({\n\t\t * \t\"min\" : 0,\n\t\t * \t\"max\" : 10,\n\t\t * \t\"integer\" : true\n\t\t * });\n\t\t * randomWalk.eval();\n\t\t *\n\t\t * @param {Number|Time=} min The minimum return value.\n\t\t * @param {Number|Time=} max The maximum return value.\n\t\t */\n\t Tone.CtrlRandom = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'min',\n\t 'max'\n\t ], Tone.CtrlRandom);\n\t Tone.call(this);\n\t /**\n\t\t\t * The minimum return value\n\t\t\t * @type {Number|Time}\n\t\t\t */\n\t this.min = options.min;\n\t /**\n\t\t\t * The maximum return value\n\t\t\t * @type {Number|Time}\n\t\t\t */\n\t this.max = options.max;\n\t /**\n\t\t\t * If the return value should be an integer\n\t\t\t * @type {Boolean}\n\t\t\t */\n\t this.integer = options.integer;\n\t };\n\t Tone.extend(Tone.CtrlRandom);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.CtrlRandom.defaults = {\n\t 'min': 0,\n\t 'max': 1,\n\t 'integer': false\n\t };\n\t /**\n\t\t * Return a random value between min and max. \n\t\t * @readOnly\n\t\t * @memberOf Tone.CtrlRandom#\n\t\t * @type {*}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.CtrlRandom.prototype, 'value', {\n\t get: function () {\n\t var min = this.toSeconds(this.min);\n\t var max = this.toSeconds(this.max);\n\t var rand = Math.random();\n\t var val = rand * min + (1 - rand) * max;\n\t if (this.integer) {\n\t val = Math.floor(val);\n\t }\n\t return val;\n\t }\n\t });\n\t return Tone.CtrlRandom;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class A data structure for holding multiple buffers.\n\t\t * \n\t\t * @param {Object|Array} urls An object literal or array\n\t\t * of urls to load.\n\t\t * @param {Function=} callback The callback to invoke when\n\t\t * the buffers are loaded. \n\t\t * @extends {Tone}\n\t\t * @example\n\t\t * //load a whole bank of piano samples\n\t\t * var pianoSamples = new Tone.Buffers({\n\t\t * \t\"C4\" : \"path/to/C4.mp3\"\n\t\t * \t\"C#4\" : \"path/to/C#4.mp3\"\n\t\t * \t\"D4\" : \"path/to/D4.mp3\"\n\t\t * \t\"D#4\" : \"path/to/D#4.mp3\"\n\t\t * \t...\n\t\t * }, function(){\n\t\t * \t//play one of the samples when they all load\n\t\t * \tplayer.buffer = pianoSamples.get(\"C4\");\n\t\t * \tplayer.start();\n\t\t * });\n\t\t * \t@example\n\t\t * //To pass in additional parameters in the second parameter\n\t\t * var buffers = new Tone.Buffers(urls, {\n\t\t * \t\"onload\" : callback,\n\t\t * \t\"baseUrl\" : \"../path/to/audio/\"\n\t\t * })\n\t\t */\n\t Tone.Buffers = function (urls) {\n\t //remove the urls from the options\n\t var args = Array.prototype.slice.call(arguments);\n\t args.shift();\n\t var options = Tone.defaults(args, [\n\t 'onload',\n\t 'baseUrl'\n\t ], Tone.Buffers);\n\t Tone.call(this);\n\t /**\n\t\t\t * All of the buffers\n\t\t\t * @type {Object}\n\t\t\t * @private\n\t\t\t */\n\t this._buffers = {};\n\t /**\n\t\t\t * A path which is prefixed before every url.\n\t\t\t * @type {String}\n\t\t\t */\n\t this.baseUrl = options.baseUrl;\n\t this._loadingCount = 0;\n\t //add each one\n\t for (var key in urls) {\n\t this._loadingCount++;\n\t this.add(key, urls[key], this._bufferLoaded.bind(this, options.onload));\n\t }\n\t };\n\t Tone.extend(Tone.Buffers);\n\t /**\n\t\t * Defaults\n\t\t * @type {Object}\n\t\t */\n\t Tone.Buffers.defaults = {\n\t 'onload': Tone.noOp,\n\t 'baseUrl': ''\n\t };\n\t /**\n\t\t * True if the buffers object has a buffer by that name.\n\t\t * @param {String|Number} name The key or index of the \n\t\t * buffer.\n\t\t * @return {Boolean}\n\t\t */\n\t Tone.Buffers.prototype.has = function (name) {\n\t return this._buffers.hasOwnProperty(name);\n\t };\n\t /**\n\t\t * Get a buffer by name. If an array was loaded, \n\t\t * then use the array index.\n\t\t * @param {String|Number} name The key or index of the \n\t\t * buffer.\n\t\t * @return {Tone.Buffer}\n\t\t */\n\t Tone.Buffers.prototype.get = function (name) {\n\t if (this.has(name)) {\n\t return this._buffers[name];\n\t } else {\n\t throw new Error('Tone.Buffers: no buffer named ' + name);\n\t }\n\t };\n\t /**\n\t\t * A buffer was loaded. decrement the counter.\n\t\t * @param {Function} callback \n\t\t * @private\n\t\t */\n\t Tone.Buffers.prototype._bufferLoaded = function (callback) {\n\t this._loadingCount--;\n\t if (this._loadingCount === 0 && callback) {\n\t callback(this);\n\t }\n\t };\n\t /**\n\t\t * If the buffers are loaded or not\n\t\t * @memberOf Tone.Buffers#\n\t\t * @type {Boolean}\n\t\t * @name loaded\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Buffers.prototype, 'loaded', {\n\t get: function () {\n\t var isLoaded = true;\n\t for (var buffName in this._buffers) {\n\t var buff = this.get(buffName);\n\t isLoaded = isLoaded && buff.loaded;\n\t }\n\t return isLoaded;\n\t }\n\t });\n\t /**\n\t\t * Add a buffer by name and url to the Buffers\n\t\t * @param {String} name A unique name to give\n\t\t * the buffer\n\t\t * @param {String|Tone.Buffer|Audiobuffer} url Either the url of the bufer, \n\t\t * or a buffer which will be added\n\t\t * with the given name.\n\t\t * @param {Function=} callback The callback to invoke \n\t\t * when the url is loaded.\n\t\t */\n\t Tone.Buffers.prototype.add = function (name, url, callback) {\n\t callback = Tone.defaultArg(callback, Tone.noOp);\n\t if (url instanceof Tone.Buffer) {\n\t this._buffers[name] = url;\n\t callback(this);\n\t } else if (url instanceof AudioBuffer) {\n\t this._buffers[name] = new Tone.Buffer(url);\n\t callback(this);\n\t } else if (Tone.isString(url)) {\n\t this._buffers[name] = new Tone.Buffer(this.baseUrl + url, callback);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Buffers} this\n\t\t */\n\t Tone.Buffers.prototype.dispose = function () {\n\t Tone.prototype.dispose.call(this);\n\t for (var name in this._buffers) {\n\t this._buffers[name].dispose();\n\t }\n\t this._buffers = null;\n\t return this;\n\t };\n\t return Tone.Buffers;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * buses are another way of routing audio\n\t\t *\n\t\t * augments Tone.prototype to include send and recieve\n\t\t */\n\t /**\n\t\t * All of the routes\n\t\t *\n\t\t * @type {Object}\n\t\t * @static\n\t\t * @private\n\t\t */\n\t var Buses = {};\n\t /**\n\t\t * Send this signal to the channel name.\n\t\t * @param {String} channelName A named channel to send the signal to.\n\t\t * @param {Decibels} amount The amount of the source to send to the bus.\n\t\t * @return {GainNode} The gain node which connects this node to the desired channel.\n\t\t * Can be used to adjust the levels of the send.\n\t\t * @example\n\t\t * source.send(\"reverb\", -12);\n\t\t */\n\t Tone.prototype.send = function (channelName, amount) {\n\t if (!Buses.hasOwnProperty(channelName)) {\n\t Buses[channelName] = this.context.createGain();\n\t }\n\t amount = Tone.defaultArg(amount, 0);\n\t var sendKnob = new Tone.Gain(amount, Tone.Type.Decibels);\n\t this.connect(sendKnob);\n\t sendKnob.connect(Buses[channelName]);\n\t return sendKnob;\n\t };\n\t /**\n\t\t * Recieve the input from the desired channelName to the input\n\t\t *\n\t\t * @param {String} channelName A named channel to send the signal to.\n\t\t * @param {Number=} channelNumber The channel to connect to\n\t\t * @returns {Tone} this\n\t\t * @example\n\t\t * reverbEffect.receive(\"reverb\");\n\t\t */\n\t Tone.prototype.receive = function (channelName, inputNum) {\n\t if (!Buses.hasOwnProperty(channelName)) {\n\t Buses[channelName] = this.context.createGain();\n\t }\n\t Buses[channelName].connect(this, 0, inputNum);\n\t return this;\n\t };\n\t //remove all the send/receives when a new audio context is passed in\n\t Tone.Context.on('init', function (context) {\n\t if (context.Buses) {\n\t Buses = context.Buses;\n\t } else {\n\t Buses = {};\n\t context.Buses = Buses;\n\t }\n\t });\n\t return Tone;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Draw is useful for synchronizing visuals and audio events.\n\t\t * Callbacks from Tone.Transport or any of the Tone.Event classes\n\t\t * always happen _before_ the scheduled time and are not synchronized\n\t\t * to the animation frame so they are not good for triggering tightly\n\t\t * synchronized visuals and sound. Tone.Draw makes it easy to schedule\n\t\t * callbacks using the AudioContext time and uses requestAnimationFrame.\n\t\t * \n\t\t * @singleton\n\t\t * @extends {Tone}\n\t\t * @example\n\t\t * Tone.Transport.schedule(function(time){\n\t\t * \t//use the time argument to schedule a callback with Tone.Draw\n\t\t * \tTone.Draw.schedule(function(){\n\t\t * \t\t//do drawing or DOM manipulation here\n\t\t * \t}, time)\n\t\t * }, \"+0.5\")\n\t\t */\n\t Tone.Draw = function () {\n\t Tone.call(this);\n\t /**\n\t\t\t * All of the events.\n\t\t\t * @type {Tone.Timeline}\n\t\t\t * @private\n\t\t\t */\n\t this._events = new Tone.Timeline();\n\t /**\n\t\t\t * The duration after which events are not invoked.\n\t\t\t * @type {Number}\n\t\t\t * @default 0.25\n\t\t\t */\n\t this.expiration = 0.25;\n\t /**\n\t\t\t * The amount of time before the scheduled time \n\t\t\t * that the callback can be invoked. Default is\n\t\t\t * half the time of an animation frame (0.008 seconds).\n\t\t\t * @type {Number}\n\t\t\t * @default 0.008\n\t\t\t */\n\t this.anticipation = 0.008;\n\t /**\n\t\t\t * The draw loop\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._boundDrawLoop = this._drawLoop.bind(this);\n\t };\n\t Tone.extend(Tone.Draw);\n\t /**\n\t\t * Schedule a function at the given time to be invoked\n\t\t * on the nearest animation frame.\n\t\t * @param {Function} callback Callback is invoked at the given time.\n\t\t * @param {Time} time The time relative to the AudioContext time\n\t\t * to invoke the callback.\n\t\t * @return {Tone.Draw} this\n\t\t */\n\t Tone.Draw.prototype.schedule = function (callback, time) {\n\t this._events.add({\n\t callback: callback,\n\t time: this.toSeconds(time)\n\t });\n\t //start the draw loop on the first event\n\t if (this._events.length === 1) {\n\t requestAnimationFrame(this._boundDrawLoop);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Cancel events scheduled after the given time\n\t\t * @param {Time=} after Time after which scheduled events will \n\t\t * be removed from the scheduling timeline.\n\t\t * @return {Tone.Draw} this\n\t\t */\n\t Tone.Draw.prototype.cancel = function (after) {\n\t this._events.cancel(this.toSeconds(after));\n\t return this;\n\t };\n\t /**\n\t\t * The draw loop\n\t\t * @private\n\t\t */\n\t Tone.Draw.prototype._drawLoop = function () {\n\t var now = Tone.now();\n\t while (this._events.length && this._events.peek().time - this.anticipation <= now) {\n\t var event = this._events.shift();\n\t if (now - event.time <= this.expiration) {\n\t event.callback();\n\t }\n\t }\n\t if (this._events.length > 0) {\n\t requestAnimationFrame(this._boundDrawLoop);\n\t }\n\t };\n\t //make a singleton\n\t Tone.Draw = new Tone.Draw();\n\t return Tone.Draw;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Both Tone.Panner3D and Tone.Listener have a position in 3D space\n\t\t * using a right-handed cartesian coordinate system.\n\t\t * The units used in the coordinate system are not defined;\n\t\t * these coordinates are independent/invariant of any particular\n\t\t * units such as meters or feet. Tone.Panner3D objects have an forward\n\t\t * vector representing the direction the sound is projecting. Additionally,\n\t\t * they have a sound cone representing how directional the sound is.\n\t\t * For example, the sound could be omnidirectional, in which case it would\n\t\t * be heard anywhere regardless of its forward, or it can be more directional\n\t\t * and heard only if it is facing the listener. Tone.Listener objects\n\t\t * (representing a person's ears) have an forward and up vector\n\t\t * representing in which direction the person is facing. Because both the\n\t\t * source stream and the listener can be moving, they both have a velocity\n\t\t * vector representing both the speed and direction of movement. Taken together,\n\t\t * these two velocities can be used to generate a doppler shift effect which changes the pitch.\n\t\t * <br><br>\n\t\t * Note: the position of the Listener will have no effect on nodes not connected to a Tone.Panner3D\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone}\n\t\t * @singleton\n\t\t */\n\t Tone.Listener = function () {\n\t Tone.call(this);\n\t /**\n\t\t\t * Holds the current forward orientation\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._orientation = [\n\t 0,\n\t 0,\n\t 0,\n\t 0,\n\t 0,\n\t 0\n\t ];\n\t /**\n\t\t\t * Holds the current position\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._position = [\n\t 0,\n\t 0,\n\t 0\n\t ];\n\t Tone.getContext(function () {\n\t // set the default position/forward\n\t this.set(ListenerConstructor.defaults);\n\t }.bind(this));\n\t };\n\t Tone.extend(Tone.Listener);\n\t /**\n\t\t * Defaults according to the specification\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Listener.defaults = {\n\t 'positionX': 0,\n\t 'positionY': 0,\n\t 'positionZ': 0,\n\t 'forwardX': 0,\n\t 'forwardY': 0,\n\t 'forwardZ': 1,\n\t 'upX': 0,\n\t 'upY': 1,\n\t 'upZ': 0\n\t };\n\t /**\n\t\t * The ramp time which is applied to the setTargetAtTime\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t Tone.Listener.prototype._rampTimeConstant = 0.01;\n\t /**\n\t\t * Sets the position of the listener in 3d space.\n\t\t * @param {Number} x\n\t\t * @param {Number} y\n\t\t * @param {Number} z\n\t\t * @return {Tone.Listener} this\n\t\t */\n\t Tone.Listener.prototype.setPosition = function (x, y, z) {\n\t if (this.context.listener.positionX) {\n\t var now = this.now();\n\t this.context.listener.positionX.setTargetAtTime(x, now, this._rampTimeConstant);\n\t this.context.listener.positionY.setTargetAtTime(y, now, this._rampTimeConstant);\n\t this.context.listener.positionZ.setTargetAtTime(z, now, this._rampTimeConstant);\n\t } else {\n\t this.context.listener.setPosition(x, y, z);\n\t }\n\t this._position = Array.prototype.slice.call(arguments);\n\t return this;\n\t };\n\t /**\n\t\t * Sets the orientation of the listener using two vectors, the forward\n\t\t * vector (which direction the listener is facing) and the up vector\n\t\t * (which the up direction of the listener). An up vector\n\t\t * of 0, 0, 1 is equivalent to the listener standing up in the Z direction.\n\t\t * @param {Number} x\n\t\t * @param {Number} y\n\t\t * @param {Number} z\n\t\t * @param {Number} upX\n\t\t * @param {Number} upY\n\t\t * @param {Number} upZ\n\t\t * @return {Tone.Listener} this\n\t\t */\n\t Tone.Listener.prototype.setOrientation = function (x, y, z, upX, upY, upZ) {\n\t if (this.context.listener.forwardX) {\n\t var now = this.now();\n\t this.context.listener.forwardX.setTargetAtTime(x, now, this._rampTimeConstant);\n\t this.context.listener.forwardY.setTargetAtTime(y, now, this._rampTimeConstant);\n\t this.context.listener.forwardZ.setTargetAtTime(z, now, this._rampTimeConstant);\n\t this.context.listener.upX.setTargetAtTime(upX, now, this._rampTimeConstant);\n\t this.context.listener.upY.setTargetAtTime(upY, now, this._rampTimeConstant);\n\t this.context.listener.upZ.setTargetAtTime(upZ, now, this._rampTimeConstant);\n\t } else {\n\t this.context.listener.setOrientation(x, y, z, upX, upY, upZ);\n\t }\n\t this._orientation = Array.prototype.slice.call(arguments);\n\t return this;\n\t };\n\t /**\n\t\t * The x position of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name positionX\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'positionX', {\n\t set: function (pos) {\n\t this._position[0] = pos;\n\t this.setPosition.apply(this, this._position);\n\t },\n\t get: function () {\n\t return this._position[0];\n\t }\n\t });\n\t /**\n\t\t * The y position of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name positionY\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'positionY', {\n\t set: function (pos) {\n\t this._position[1] = pos;\n\t this.setPosition.apply(this, this._position);\n\t },\n\t get: function () {\n\t return this._position[1];\n\t }\n\t });\n\t /**\n\t\t * The z position of the panner object.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name positionZ\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'positionZ', {\n\t set: function (pos) {\n\t this._position[2] = pos;\n\t this.setPosition.apply(this, this._position);\n\t },\n\t get: function () {\n\t return this._position[2];\n\t }\n\t });\n\t /**\n\t\t * The x coordinate of the listeners front direction. i.e.\n\t\t * which way they are facing.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name forwardX\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'forwardX', {\n\t set: function (pos) {\n\t this._orientation[0] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[0];\n\t }\n\t });\n\t /**\n\t\t * The y coordinate of the listeners front direction. i.e.\n\t\t * which way they are facing.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name forwardY\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'forwardY', {\n\t set: function (pos) {\n\t this._orientation[1] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[1];\n\t }\n\t });\n\t /**\n\t\t * The z coordinate of the listeners front direction. i.e.\n\t\t * which way they are facing.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name forwardZ\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'forwardZ', {\n\t set: function (pos) {\n\t this._orientation[2] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[2];\n\t }\n\t });\n\t /**\n\t\t * The x coordinate of the listener's up direction. i.e.\n\t\t * the direction the listener is standing in.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name upX\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'upX', {\n\t set: function (pos) {\n\t this._orientation[3] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[3];\n\t }\n\t });\n\t /**\n\t\t * The y coordinate of the listener's up direction. i.e.\n\t\t * the direction the listener is standing in.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name upY\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'upY', {\n\t set: function (pos) {\n\t this._orientation[4] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[4];\n\t }\n\t });\n\t /**\n\t\t * The z coordinate of the listener's up direction. i.e.\n\t\t * the direction the listener is standing in.\n\t\t * @type {Number}\n\t\t * @memberOf Tone.Listener#\n\t\t * @name upZ\n\t\t */\n\t Object.defineProperty(Tone.Listener.prototype, 'upZ', {\n\t set: function (pos) {\n\t this._orientation[5] = pos;\n\t this.setOrientation.apply(this, this._orientation);\n\t },\n\t get: function () {\n\t return this._orientation[5];\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Listener} this\n\t\t */\n\t Tone.Listener.prototype.dispose = function () {\n\t this._orientation = null;\n\t this._position = null;\n\t return this;\n\t };\n\t //SINGLETON SETUP\n\t var ListenerConstructor = Tone.Listener;\n\t Tone.Listener = new ListenerConstructor();\n\t Tone.Context.on('init', function (context) {\n\t if (context.Listener instanceof ListenerConstructor) {\n\t //a single listener object\n\t Tone.Listener = context.Listener;\n\t } else {\n\t //make new Listener insides\n\t Tone.Listener = new ListenerConstructor();\n\t }\n\t context.Listener = Tone.Listener;\n\t });\n\t //END SINGLETON SETUP\n\t return Tone.Listener;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * Because of a bug in iOS causing the currentTime to increment\n\t\t * before the rendering is started, sometimes it takes multiple\n\t\t * attempts to render the audio correctly.\n\t\t * @private\n\t\t */\n\t function attemptRender(callback, duration, sampleRate, tries) {\n\t tries = Tone.defaultArg(tries, 0);\n\t var context = new Tone.OfflineContext(2, duration, sampleRate);\n\t Tone.context = context;\n\t //invoke the callback/scheduling\n\t var response = callback(Tone.Transport);\n\t if (context.currentTime > 0 && tries < 1000) {\n\t return attemptRender(callback, duration, sampleRate, ++tries);\n\t } else {\n\t return {\n\t 'response': response,\n\t 'context': context\n\t };\n\t }\n\t }\n\t /**\n\t\t * Generate a buffer by rendering all of the Tone.js code within the callback using the OfflineAudioContext.\n\t\t * The OfflineAudioContext is capable of rendering much faster than real time in many cases.\n\t\t * The callback function also passes in an offline instance of Tone.Transport which can be used\n\t\t * to schedule events along the Transport. **NOTE** OfflineAudioContext has the same restrictions\n\t\t * as the AudioContext in that on certain platforms (like iOS) it must be invoked by an explicit\n\t\t * user action like a click or tap. \n\t\t * @param {Function} callback All Tone.js nodes which are created and scheduled within this callback are recorded into the output Buffer.\n\t\t * @param {Time} duration the amount of time to record for.\n\t\t * @return {Promise} The promise which is invoked with the Tone.Buffer of the recorded output.\n\t\t * @example\n\t\t * //render 2 seconds of the oscillator\n\t\t * Tone.Offline(function(){\n\t\t * \t//only nodes created in this callback will be recorded\n\t\t * \tvar oscillator = new Tone.Oscillator().toMaster().start(0)\n\t\t * \t//schedule their events\n\t\t * }, 2).then(function(buffer){\n\t\t * \t//do something with the output buffer\n\t\t * })\n\t\t * @example\n\t\t * //can also schedule events along the Transport\n\t\t * //using the passed in Offline Transport\n\t\t * Tone.Offline(function(Transport){\n\t\t * \tvar osc = new Tone.Oscillator().toMaster()\n\t\t * \tTransport.schedule(function(time){\n\t\t * \t\tosc.start(time).stop(time + 0.1)\n\t\t * \t}, 1)\n\t\t * \tTransport.start(0.2)\n\t\t * }, 4).then(function(buffer){\n\t\t * \t//do something with the output buffer\n\t\t * })\n\t\t */\n\t Tone.Offline = function (callback, duration) {\n\t //set the OfflineAudioContext\n\t var sampleRate = Tone.context.sampleRate;\n\t var originalContext = Tone.context;\n\t var renderRet = attemptRender(callback, duration, sampleRate);\n\t var response = renderRet.response;\n\t var context = renderRet.context;\n\t var ret;\n\t if (response instanceof Promise) {\n\t //wait for the promise to resolve\n\t ret = response.then(function () {\n\t //then render the audio\n\t return context.render();\n\t });\n\t } else {\n\t //process the audio\n\t ret = context.render();\n\t }\n\t //return the original AudioContext\n\t Tone.context = originalContext;\n\t //return the audio\n\t return ret.then(function (buffer) {\n\t //wrap it in a Tone.Buffer\n\t return new Tone.Buffer(buffer);\n\t });\n\t };\n\t return Tone.Offline;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * \t@class Tone.Effect is the base class for effects. Connect the effect between\n\t\t * \t the effectSend and effectReturn GainNodes, then control the amount of\n\t\t * \t effect which goes to the output using the wet control.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {NormalRange|Object} [wet] The starting wet value.\n\t\t */\n\t Tone.Effect = function () {\n\t var options = Tone.defaults(arguments, ['wet'], Tone.Effect);\n\t Tone.AudioNode.call(this);\n\t this.createInsOuts(1, 1);\n\t /**\n\t\t\t * the drywet knob to control the amount of effect\n\t\t\t * @type {Tone.CrossFade}\n\t\t\t * @private\n\t\t\t */\n\t this._dryWet = new Tone.CrossFade(options.wet);\n\t /**\n\t\t\t * The wet control is how much of the effected\n\t\t\t * will pass through to the output. 1 = 100% effected\n\t\t\t * signal, 0 = 100% dry signal.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.wet = this._dryWet.fade;\n\t /**\n\t\t\t * connect the effectSend to the input of hte effect\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this.effectSend = new Tone.Gain();\n\t /**\n\t\t\t * connect the output of the effect to the effectReturn\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this.effectReturn = new Tone.Gain();\n\t //connections\n\t this.input.connect(this._dryWet.a);\n\t this.input.connect(this.effectSend);\n\t this.effectReturn.connect(this._dryWet.b);\n\t this._dryWet.connect(this.output);\n\t this._readOnly(['wet']);\n\t };\n\t Tone.extend(Tone.Effect, Tone.AudioNode);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Effect.defaults = { 'wet': 1 };\n\t /**\n\t\t * chains the effect in between the effectSend and effectReturn\n\t\t * @param {Tone} effect\n\t\t * @private\n\t\t * @returns {Tone.Effect} this\n\t\t */\n\t Tone.Effect.prototype.connectEffect = function (effect) {\n\t this.effectSend.chain(effect, this.effectReturn);\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Effect} this\n\t\t */\n\t Tone.Effect.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._dryWet.dispose();\n\t this._dryWet = null;\n\t this.effectSend.dispose();\n\t this.effectSend = null;\n\t this.effectReturn.dispose();\n\t this.effectReturn = null;\n\t this._writable(['wet']);\n\t this.wet = null;\n\t return this;\n\t };\n\t return Tone.Effect;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.AutoFilter is a Tone.Filter with a Tone.LFO connected to the filter cutoff frequency.\n\t\t * Setting the LFO rate and depth allows for control over the filter modulation rate \n\t\t * and depth.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Effect}\n\t\t * @param {Time|Object} [frequency] The rate of the LFO.\n\t\t * @param {Frequency=} baseFrequency The lower value of the LFOs oscillation\n\t \t * @param {Frequency=} octaves The number of octaves above the baseFrequency\n\t\t * @example\n\t\t * //create an autofilter and start it's LFO\n\t\t * var autoFilter = new Tone.AutoFilter(\"4n\").toMaster().start();\n\t\t * //route an oscillator through the filter and start it\n\t\t * var oscillator = new Tone.Oscillator().connect(autoFilter).start();\n\t\t */\n\t Tone.AutoFilter = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'baseFrequency',\n\t 'octaves'\n\t ], Tone.AutoFilter);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * the lfo which drives the filter cutoff\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfo = new Tone.LFO({\n\t 'frequency': options.frequency,\n\t 'amplitude': options.depth\n\t });\n\t /**\n\t\t\t * The range of the filter modulating between the min and max frequency. \n\t\t\t * 0 = no modulation. 1 = full modulation.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.depth = this._lfo.amplitude;\n\t /**\n\t\t\t * How fast the filter modulates between min and max. \n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._lfo.frequency;\n\t /**\n\t\t\t * The filter node\n\t\t\t * @type {Tone.Filter}\n\t\t\t */\n\t this.filter = new Tone.Filter(options.filter);\n\t /**\n\t\t\t * The octaves placeholder\n\t\t\t * @type {Positive}\n\t\t\t * @private\n\t\t\t */\n\t this._octaves = 0;\n\t //connections\n\t this.connectEffect(this.filter);\n\t this._lfo.connect(this.filter.frequency);\n\t this.type = options.type;\n\t this._readOnly([\n\t 'frequency',\n\t 'depth'\n\t ]);\n\t this.octaves = options.octaves;\n\t this.baseFrequency = options.baseFrequency;\n\t };\n\t //extend Effect\n\t Tone.extend(Tone.AutoFilter, Tone.Effect);\n\t /**\n\t\t * defaults\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.AutoFilter.defaults = {\n\t 'frequency': 1,\n\t 'type': 'sine',\n\t 'depth': 1,\n\t 'baseFrequency': 200,\n\t 'octaves': 2.6,\n\t 'filter': {\n\t 'type': 'lowpass',\n\t 'rolloff': -12,\n\t 'Q': 1\n\t }\n\t };\n\t /**\n\t\t * Start the effect.\n\t\t * @param {Time} [time=now] When the LFO will start. \n\t\t * @returns {Tone.AutoFilter} this\n\t\t */\n\t Tone.AutoFilter.prototype.start = function (time) {\n\t this._lfo.start(time);\n\t return this;\n\t };\n\t /**\n\t\t * Stop the effect.\n\t\t * @param {Time} [time=now] When the LFO will stop. \n\t\t * @returns {Tone.AutoFilter} this\n\t\t */\n\t Tone.AutoFilter.prototype.stop = function (time) {\n\t this._lfo.stop(time);\n\t return this;\n\t };\n\t /**\n\t\t * Sync the filter to the transport.\n\t\t * @param {Time} [delay=0] Delay time before starting the effect after the\n\t\t * Transport has started. \n\t\t * @returns {Tone.AutoFilter} this\n\t\t */\n\t Tone.AutoFilter.prototype.sync = function (delay) {\n\t this._lfo.sync(delay);\n\t return this;\n\t };\n\t /**\n\t\t * Unsync the filter from the transport.\n\t\t * @returns {Tone.AutoFilter} this\n\t\t */\n\t Tone.AutoFilter.prototype.unsync = function () {\n\t this._lfo.unsync();\n\t return this;\n\t };\n\t /**\n\t\t * Type of oscillator attached to the AutoFilter. \n\t\t * Possible values: \"sine\", \"square\", \"triangle\", \"sawtooth\".\n\t\t * @memberOf Tone.AutoFilter#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.AutoFilter.prototype, 'type', {\n\t get: function () {\n\t return this._lfo.type;\n\t },\n\t set: function (type) {\n\t this._lfo.type = type;\n\t }\n\t });\n\t /**\n\t\t * The minimum value of the filter's cutoff frequency.\n\t\t * @memberOf Tone.AutoFilter#\n\t\t * @type {Frequency}\n\t\t * @name min\n\t\t */\n\t Object.defineProperty(Tone.AutoFilter.prototype, 'baseFrequency', {\n\t get: function () {\n\t return this._lfo.min;\n\t },\n\t set: function (freq) {\n\t this._lfo.min = this.toFrequency(freq);\n\t //and set the max\n\t this.octaves = this._octaves;\n\t }\n\t });\n\t /**\n\t\t * The maximum value of the filter's cutoff frequency. \n\t\t * @memberOf Tone.AutoFilter#\n\t\t * @type {Positive}\n\t\t * @name octaves\n\t\t */\n\t Object.defineProperty(Tone.AutoFilter.prototype, 'octaves', {\n\t get: function () {\n\t return this._octaves;\n\t },\n\t set: function (oct) {\n\t this._octaves = oct;\n\t this._lfo.max = this.baseFrequency * Math.pow(2, oct);\n\t }\n\t });\n\t /**\n\t\t * Clean up. \n\t\t * @returns {Tone.AutoFilter} this\n\t\t */\n\t Tone.AutoFilter.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._lfo.dispose();\n\t this._lfo = null;\n\t this.filter.dispose();\n\t this.filter = null;\n\t this._writable([\n\t 'frequency',\n\t 'depth'\n\t ]);\n\t this.frequency = null;\n\t this.depth = null;\n\t return this;\n\t };\n\t return Tone.AutoFilter;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.AutoPanner is a Tone.Panner with an LFO connected to the pan amount. \n\t\t * More on using autopanners [here](https://www.ableton.com/en/blog/autopan-chopper-effect-and-more-liveschool/).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Effect}\n\t\t * @param {Frequency|Object} [frequency] Rate of left-right oscillation. \n\t\t * @example\n\t\t * //create an autopanner and start it's LFO\n\t\t * var autoPanner = new Tone.AutoPanner(\"4n\").toMaster().start();\n\t\t * //route an oscillator through the panner and start it\n\t\t * var oscillator = new Tone.Oscillator().connect(autoPanner).start();\n\t\t */\n\t Tone.AutoPanner = function () {\n\t var options = Tone.defaults(arguments, ['frequency'], Tone.AutoPanner);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * the lfo which drives the panning\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfo = new Tone.LFO({\n\t 'frequency': options.frequency,\n\t 'amplitude': options.depth,\n\t 'min': -1,\n\t 'max': 1\n\t });\n\t /**\n\t\t\t * The amount of panning between left and right. \n\t\t\t * 0 = always center. 1 = full range between left and right. \n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.depth = this._lfo.amplitude;\n\t /**\n\t\t\t * the panner node which does the panning\n\t\t\t * @type {Tone.Panner}\n\t\t\t * @private\n\t\t\t */\n\t this._panner = new Tone.Panner();\n\t /**\n\t\t\t * How fast the panner modulates between left and right. \n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._lfo.frequency;\n\t //connections\n\t this.connectEffect(this._panner);\n\t this._lfo.connect(this._panner.pan);\n\t this.type = options.type;\n\t this._readOnly([\n\t 'depth',\n\t 'frequency'\n\t ]);\n\t };\n\t //extend Effect\n\t Tone.extend(Tone.AutoPanner, Tone.Effect);\n\t /**\n\t\t * defaults\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.AutoPanner.defaults = {\n\t 'frequency': 1,\n\t 'type': 'sine',\n\t 'depth': 1\n\t };\n\t /**\n\t\t * Start the effect.\n\t\t * @param {Time} [time=now] When the LFO will start. \n\t\t * @returns {Tone.AutoPanner} this\n\t\t */\n\t Tone.AutoPanner.prototype.start = function (time) {\n\t this._lfo.start(time);\n\t return this;\n\t };\n\t /**\n\t\t * Stop the effect.\n\t\t * @param {Time} [time=now] When the LFO will stop. \n\t\t * @returns {Tone.AutoPanner} this\n\t\t */\n\t Tone.AutoPanner.prototype.stop = function (time) {\n\t this._lfo.stop(time);\n\t return this;\n\t };\n\t /**\n\t\t * Sync the panner to the transport.\n\t\t * @param {Time} [delay=0] Delay time before starting the effect after the\n\t\t * Transport has started. \n\t\t * @returns {Tone.AutoPanner} this\n\t\t */\n\t Tone.AutoPanner.prototype.sync = function (delay) {\n\t this._lfo.sync(delay);\n\t return this;\n\t };\n\t /**\n\t\t * Unsync the panner from the transport\n\t\t * @returns {Tone.AutoPanner} this\n\t\t */\n\t Tone.AutoPanner.prototype.unsync = function () {\n\t this._lfo.unsync();\n\t return this;\n\t };\n\t /**\n\t\t * Type of oscillator attached to the AutoFilter. \n\t\t * Possible values: \"sine\", \"square\", \"triangle\", \"sawtooth\".\n\t\t * @memberOf Tone.AutoFilter#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.AutoPanner.prototype, 'type', {\n\t get: function () {\n\t return this._lfo.type;\n\t },\n\t set: function (type) {\n\t this._lfo.type = type;\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.AutoPanner} this\n\t\t */\n\t Tone.AutoPanner.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._lfo.dispose();\n\t this._lfo = null;\n\t this._panner.dispose();\n\t this._panner = null;\n\t this._writable([\n\t 'depth',\n\t 'frequency'\n\t ]);\n\t this.frequency = null;\n\t this.depth = null;\n\t return this;\n\t };\n\t return Tone.AutoPanner;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.AutoWah connects a Tone.Follower to a bandpass filter (Tone.Filter).\n\t\t * The frequency of the filter is adjusted proportionally to the\n\t\t * incoming signal's amplitude. Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Effect}\n\t\t * @param {Frequency|Object} [baseFrequency] The frequency the filter is set\n\t\t * to at the low point of the wah\n\t\t * @param {Positive} [octaves] The number of octaves above the baseFrequency\n\t\t * the filter will sweep to when fully open\n\t\t * @param {Decibels} [sensitivity] The decibel threshold sensitivity for\n\t\t * the incoming signal. Normal range of -40 to 0.\n\t\t * @example\n\t\t * var autoWah = new Tone.AutoWah(50, 6, -30).toMaster();\n\t\t * //initialize the synth and connect to autowah\n\t\t * var synth = new Synth.connect(autoWah);\n\t\t * //Q value influences the effect of the wah - default is 2\n\t\t * autoWah.Q.value = 6;\n\t\t * //more audible on higher notes\n\t\t * synth.triggerAttackRelease(\"C4\", \"8n\")\n\t\t */\n\t Tone.AutoWah = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'baseFrequency',\n\t 'octaves',\n\t 'sensitivity'\n\t ], Tone.AutoWah);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * The envelope follower. Set the attack/release\n\t\t\t * timing to adjust how the envelope is followed.\n\t\t\t * @type {Tone.Follower}\n\t\t\t * @private\n\t\t\t */\n\t this.follower = new Tone.Follower(options.follower);\n\t /**\n\t\t\t * scales the follower value to the frequency domain\n\t\t\t * @type {Tone}\n\t\t\t * @private\n\t\t\t */\n\t this._sweepRange = new Tone.ScaleExp(0, 1, 0.5);\n\t /**\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._baseFrequency = options.baseFrequency;\n\t /**\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._octaves = options.octaves;\n\t /**\n\t\t\t * the input gain to adjust the sensitivity\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._inputBoost = new Tone.Gain();\n\t /**\n\t\t\t * @type {BiquadFilterNode}\n\t\t\t * @private\n\t\t\t */\n\t this._bandpass = new Tone.Filter({\n\t 'rolloff': -48,\n\t 'frequency': 0,\n\t 'Q': options.Q\n\t });\n\t /**\n\t\t\t * @type {Tone.Filter}\n\t\t\t * @private\n\t\t\t */\n\t this._peaking = new Tone.Filter(0, 'peaking');\n\t this._peaking.gain.value = options.gain;\n\t /**\n\t\t\t * The gain of the filter.\n\t\t\t * @type {Number}\n\t\t\t * @signal\n\t\t\t */\n\t this.gain = this._peaking.gain;\n\t /**\n\t\t\t * The quality of the filter.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this.Q = this._bandpass.Q;\n\t //the control signal path\n\t this.effectSend.chain(this._inputBoost, this.follower, this._sweepRange);\n\t this._sweepRange.connect(this._bandpass.frequency);\n\t this._sweepRange.connect(this._peaking.frequency);\n\t //the filtered path\n\t this.effectSend.chain(this._bandpass, this._peaking, this.effectReturn);\n\t //set the initial value\n\t this._setSweepRange();\n\t this.sensitivity = options.sensitivity;\n\t this._readOnly([\n\t 'gain',\n\t 'Q'\n\t ]);\n\t };\n\t Tone.extend(Tone.AutoWah, Tone.Effect);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.AutoWah.defaults = {\n\t 'baseFrequency': 100,\n\t 'octaves': 6,\n\t 'sensitivity': 0,\n\t 'Q': 2,\n\t 'gain': 2,\n\t 'follower': {\n\t 'attack': 0.3,\n\t 'release': 0.5\n\t }\n\t };\n\t /**\n\t\t * The number of octaves that the filter will sweep above the\n\t\t * baseFrequency.\n\t\t * @memberOf Tone.AutoWah#\n\t\t * @type {Number}\n\t\t * @name octaves\n\t\t */\n\t Object.defineProperty(Tone.AutoWah.prototype, 'octaves', {\n\t get: function () {\n\t return this._octaves;\n\t },\n\t set: function (octaves) {\n\t this._octaves = octaves;\n\t this._setSweepRange();\n\t }\n\t });\n\t /**\n\t\t * The base frequency from which the sweep will start from.\n\t\t * @memberOf Tone.AutoWah#\n\t\t * @type {Frequency}\n\t\t * @name baseFrequency\n\t\t */\n\t Object.defineProperty(Tone.AutoWah.prototype, 'baseFrequency', {\n\t get: function () {\n\t return this._baseFrequency;\n\t },\n\t set: function (baseFreq) {\n\t this._baseFrequency = baseFreq;\n\t this._setSweepRange();\n\t }\n\t });\n\t /**\n\t\t * The sensitivity to control how responsive to the input signal the filter is.\n\t\t * @memberOf Tone.AutoWah#\n\t\t * @type {Decibels}\n\t\t * @name sensitivity\n\t\t */\n\t Object.defineProperty(Tone.AutoWah.prototype, 'sensitivity', {\n\t get: function () {\n\t return Tone.gainToDb(1 / this._inputBoost.gain.value);\n\t },\n\t set: function (sensitivy) {\n\t this._inputBoost.gain.value = 1 / Tone.dbToGain(sensitivy);\n\t }\n\t });\n\t /**\n\t\t * sets the sweep range of the scaler\n\t\t * @private\n\t\t */\n\t Tone.AutoWah.prototype._setSweepRange = function () {\n\t this._sweepRange.min = this._baseFrequency;\n\t this._sweepRange.max = Math.min(this._baseFrequency * Math.pow(2, this._octaves), this.context.sampleRate / 2);\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.AutoWah} this\n\t\t */\n\t Tone.AutoWah.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this.follower.dispose();\n\t this.follower = null;\n\t this._sweepRange.dispose();\n\t this._sweepRange = null;\n\t this._bandpass.dispose();\n\t this._bandpass = null;\n\t this._peaking.dispose();\n\t this._peaking = null;\n\t this._inputBoost.dispose();\n\t this._inputBoost = null;\n\t this._writable([\n\t 'gain',\n\t 'Q'\n\t ]);\n\t this.gain = null;\n\t this.Q = null;\n\t return this;\n\t };\n\t return Tone.AutoWah;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t\t * values in the NormalRange.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.SignalBase}\n\t\t * @param {NormalRange} modulus The modulus to apply.\n\t\t * @example\n\t\t * var mod = new Tone.Modulo(0.2)\n\t\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t\t * //mod outputs 0.1\n\t\t */\n\t Tone.Modulo = function (modulus) {\n\t Tone.SignalBase.call(this);\n\t this.createInsOuts(1, 0);\n\t /**\n\t\t\t * A waveshaper gets the integer multiple of\n\t\t\t * the input signal and the modulus.\n\t\t\t * @private\n\t\t\t * @type {Tone.WaveShaper}\n\t\t\t */\n\t this._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\t /**\n\t\t\t * the integer multiple is multiplied by the modulus\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._multiply = new Tone.Multiply();\n\t /**\n\t\t\t * and subtracted from the input signal\n\t\t\t * @type {Tone.Subtract}\n\t\t\t * @private\n\t\t\t */\n\t this._subtract = this.output = new Tone.Subtract();\n\t /**\n\t\t\t * the modulus signal\n\t\t\t * @type {Tone.Signal}\n\t\t\t * @private\n\t\t\t */\n\t this._modSignal = new Tone.Signal(modulus);\n\t //connections\n\t this.input.fan(this._shaper, this._subtract);\n\t this._modSignal.connect(this._multiply, 0, 0);\n\t this._shaper.connect(this._multiply, 0, 1);\n\t this._multiply.connect(this._subtract, 0, 1);\n\t this._setWaveShaper(modulus);\n\t };\n\t Tone.extend(Tone.Modulo, Tone.SignalBase);\n\t /**\n\t\t * @param {number} mod the modulus to apply\n\t\t * @private\n\t\t */\n\t Tone.Modulo.prototype._setWaveShaper = function (mod) {\n\t this._shaper.setMap(function (val) {\n\t var multiple = Math.floor((val + 0.0001) / mod);\n\t return multiple;\n\t });\n\t };\n\t /**\n\t\t * The modulus value.\n\t\t * @memberOf Tone.Modulo#\n\t\t * @type {NormalRange}\n\t\t * @name value\n\t\t */\n\t Object.defineProperty(Tone.Modulo.prototype, 'value', {\n\t get: function () {\n\t return this._modSignal.value;\n\t },\n\t set: function (mod) {\n\t this._modSignal.value = mod;\n\t this._setWaveShaper(mod);\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Modulo} this\n\t\t */\n\t Tone.Modulo.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._shaper.dispose();\n\t this._shaper = null;\n\t this._multiply.dispose();\n\t this._multiply = null;\n\t this._subtract.dispose();\n\t this._subtract = null;\n\t this._modSignal.dispose();\n\t this._modSignal = null;\n\t return this;\n\t };\n\t return Tone.Modulo;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Bitcrusher downsamples the incoming signal to a different bitdepth.\n\t\t * Lowering the bitdepth of the signal creates distortion. Read more about Bitcrushing\n\t\t * on [Wikipedia](https://en.wikipedia.org/wiki/Bitcrusher).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Effect}\n\t\t * @param {Number} bits The number of bits to downsample the signal. Nominal range\n\t\t * of 1 to 8.\n\t\t * @example\n\t\t * //initialize crusher and route a synth through it\n\t\t * var crusher = new Tone.BitCrusher(4).toMaster();\n\t\t * var synth = new Tone.MonoSynth().connect(crusher);\n\t\t */\n\t Tone.BitCrusher = function () {\n\t var options = Tone.defaults(arguments, ['bits'], Tone.BitCrusher);\n\t Tone.Effect.call(this, options);\n\t var invStepSize = 1 / Math.pow(2, options.bits - 1);\n\t /**\n\t\t\t * Subtract the input signal and the modulus of the input signal\n\t\t\t * @type {Tone.Subtract}\n\t\t\t * @private\n\t\t\t */\n\t this._subtract = new Tone.Subtract();\n\t /**\n\t\t\t * The mod function\n\t\t\t * @type {Tone.Modulo}\n\t\t\t * @private\n\t\t\t */\n\t this._modulo = new Tone.Modulo(invStepSize);\n\t /**\n\t\t\t * keeps track of the bits\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._bits = options.bits;\n\t //connect it up\n\t this.effectSend.fan(this._subtract, this._modulo);\n\t this._modulo.connect(this._subtract, 0, 1);\n\t this._subtract.connect(this.effectReturn);\n\t };\n\t Tone.extend(Tone.BitCrusher, Tone.Effect);\n\t /**\n\t\t * the default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.BitCrusher.defaults = { 'bits': 4 };\n\t /**\n\t\t * The bit depth of the effect. Nominal range of 1-8.\n\t\t * @memberOf Tone.BitCrusher#\n\t\t * @type {number}\n\t\t * @name bits\n\t\t */\n\t Object.defineProperty(Tone.BitCrusher.prototype, 'bits', {\n\t get: function () {\n\t return this._bits;\n\t },\n\t set: function (bits) {\n\t this._bits = bits;\n\t var invStepSize = 1 / Math.pow(2, bits - 1);\n\t this._modulo.value = invStepSize;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.BitCrusher} this\n\t\t */\n\t Tone.BitCrusher.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._subtract.dispose();\n\t this._subtract = null;\n\t this._modulo.dispose();\n\t this._modulo = null;\n\t return this;\n\t };\n\t return Tone.BitCrusher;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.ChebyShev is a Chebyshev waveshaper, an effect which is good \n\t\t * for making different types of distortion sounds.\n\t\t * Note that odd orders sound very different from even ones, \n\t\t * and order = 1 is no change. \n\t\t * Read more at [music.columbia.edu](http://music.columbia.edu/cmc/musicandcomputers/chapter4/04_06.php).\n\t\t *\n\t\t * @extends {Tone.Effect}\n\t\t * @constructor\n\t\t * @param {Positive|Object} [order] The order of the chebyshev polynomial. Normal range between 1-100. \n\t\t * @example\n\t\t * //create a new cheby\n\t\t * var cheby = new Tone.Chebyshev(50);\n\t\t * //create a monosynth connected to our cheby\n\t\t * synth = new Tone.MonoSynth().connect(cheby);\n\t\t */\n\t Tone.Chebyshev = function () {\n\t var options = Tone.defaults(arguments, ['order'], Tone.Chebyshev);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * @type {WaveShaperNode}\n\t\t\t * @private\n\t\t\t */\n\t this._shaper = new Tone.WaveShaper(4096);\n\t /**\n\t\t\t * holds onto the order of the filter\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._order = options.order;\n\t this.connectEffect(this._shaper);\n\t this.order = options.order;\n\t this.oversample = options.oversample;\n\t };\n\t Tone.extend(Tone.Chebyshev, Tone.Effect);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Chebyshev.defaults = {\n\t 'order': 1,\n\t 'oversample': 'none'\n\t };\n\t /**\n\t\t * get the coefficient for that degree\n\t\t * @param {number} x the x value\n\t\t * @param {number} degree \n\t\t * @param {Object} memo memoize the computed value. \n\t\t * this speeds up computation greatly. \n\t\t * @return {number} the coefficient \n\t\t * @private\n\t\t */\n\t Tone.Chebyshev.prototype._getCoefficient = function (x, degree, memo) {\n\t if (memo.hasOwnProperty(degree)) {\n\t return memo[degree];\n\t } else if (degree === 0) {\n\t memo[degree] = 0;\n\t } else if (degree === 1) {\n\t memo[degree] = x;\n\t } else {\n\t memo[degree] = 2 * x * this._getCoefficient(x, degree - 1, memo) - this._getCoefficient(x, degree - 2, memo);\n\t }\n\t return memo[degree];\n\t };\n\t /**\n\t\t * The order of the Chebyshev polynomial which creates\n\t\t * the equation which is applied to the incoming \n\t\t * signal through a Tone.WaveShaper. The equations\n\t\t * are in the form:<br>\n\t\t * order 2: 2x^2 + 1<br>\n\t\t * order 3: 4x^3 + 3x <br>\n\t\t * @memberOf Tone.Chebyshev#\n\t\t * @type {Positive}\n\t\t * @name order\n\t\t */\n\t Object.defineProperty(Tone.Chebyshev.prototype, 'order', {\n\t get: function () {\n\t return this._order;\n\t },\n\t set: function (order) {\n\t this._order = order;\n\t var curve = new Array(4096);\n\t var len = curve.length;\n\t for (var i = 0; i < len; ++i) {\n\t var x = i * 2 / len - 1;\n\t if (x === 0) {\n\t //should output 0 when input is 0\n\t curve[i] = 0;\n\t } else {\n\t curve[i] = this._getCoefficient(x, order, {});\n\t }\n\t }\n\t this._shaper.curve = curve;\n\t }\n\t });\n\t /**\n\t\t * The oversampling of the effect. Can either be \"none\", \"2x\" or \"4x\".\n\t\t * @memberOf Tone.Chebyshev#\n\t\t * @type {string}\n\t\t * @name oversample\n\t\t */\n\t Object.defineProperty(Tone.Chebyshev.prototype, 'oversample', {\n\t get: function () {\n\t return this._shaper.oversample;\n\t },\n\t set: function (oversampling) {\n\t this._shaper.oversample = oversampling;\n\t }\n\t });\n\t /**\n\t\t * Clean up. \n\t\t * @returns {Tone.Chebyshev} this\n\t\t */\n\t Tone.Chebyshev.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._shaper.dispose();\n\t this._shaper = null;\n\t return this;\n\t };\n\t return Tone.Chebyshev;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Base class for Stereo effects. Provides effectSendL/R and effectReturnL/R.\n\t\t *\n\t\t *\t@constructor\n\t\t *\t@extends {Tone.Effect}\n\t\t */\n\t Tone.StereoEffect = function () {\n\t //get the defaults\n\t Tone.AudioNode.call(this);\n\t var options = Tone.defaults(arguments, ['wet'], Tone.Effect);\n\t this.createInsOuts(1, 1);\n\t /**\n\t\t\t * the drywet knob to control the amount of effect\n\t\t\t * @type {Tone.CrossFade}\n\t\t\t * @private\n\t\t\t */\n\t this._dryWet = new Tone.CrossFade(options.wet);\n\t /**\n\t\t\t * The wet control, i.e. how much of the effected\n\t\t\t * will pass through to the output.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.wet = this._dryWet.fade;\n\t /**\n\t\t\t * then split it\n\t\t\t * @type {Tone.Split}\n\t\t\t * @private\n\t\t\t */\n\t this._split = new Tone.Split();\n\t /**\n\t\t\t * the effects send LEFT\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.effectSendL = this._split.left;\n\t /**\n\t\t\t * the effects send RIGHT\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.effectSendR = this._split.right;\n\t /**\n\t\t\t * the stereo effect merger\n\t\t\t * @type {Tone.Merge}\n\t\t\t * @private\n\t\t\t */\n\t this._merge = new Tone.Merge();\n\t /**\n\t\t\t * the effect return LEFT\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.effectReturnL = this._merge.left;\n\t /**\n\t\t\t * the effect return RIGHT\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.effectReturnR = this._merge.right;\n\t //connections\n\t this.input.connect(this._split);\n\t //dry wet connections\n\t this.input.connect(this._dryWet, 0, 0);\n\t this._merge.connect(this._dryWet, 0, 1);\n\t this._dryWet.connect(this.output);\n\t this._readOnly(['wet']);\n\t };\n\t Tone.extend(Tone.StereoEffect, Tone.Effect);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.StereoEffect} this\n\t\t */\n\t Tone.StereoEffect.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._dryWet.dispose();\n\t this._dryWet = null;\n\t this._split.dispose();\n\t this._split = null;\n\t this._merge.dispose();\n\t this._merge = null;\n\t this.effectSendL = null;\n\t this.effectSendR = null;\n\t this.effectReturnL = null;\n\t this.effectReturnR = null;\n\t this._writable(['wet']);\n\t this.wet = null;\n\t return this;\n\t };\n\t return Tone.StereoEffect;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Chorus is a stereo chorus effect composed of\n\t\t * a left and right delay with a Tone.LFO applied to the delayTime of each channel.\n\t\t * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna/blob/master/tuna.js).\n\t\t * Read more on the chorus effect on [SoundOnSound](http://www.soundonsound.com/sos/jun04/articles/synthsecrets.htm).\n\t\t *\n\t\t *\t@constructor\n\t\t *\t@extends {Tone.StereoEffect}\n\t\t *\t@param {Frequency|Object} [frequency] The frequency of the LFO.\n\t\t *\t@param {Milliseconds} [delayTime] The delay of the chorus effect in ms.\n\t\t *\t@param {NormalRange} [depth] The depth of the chorus.\n\t\t *\t@example\n\t\t * var chorus = new Tone.Chorus(4, 2.5, 0.5);\n\t\t * var synth = new Tone.PolySynth(4, Tone.MonoSynth).connect(chorus);\n\t\t * synth.triggerAttackRelease([\"C3\",\"E3\",\"G3\"], \"8n\");\n\t\t */\n\t Tone.Chorus = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'delayTime',\n\t 'depth'\n\t ], Tone.Chorus);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * the depth of the chorus\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._depth = options.depth;\n\t /**\n\t\t\t * the delayTime\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._delayTime = options.delayTime / 1000;\n\t /**\n\t\t\t * the lfo which controls the delayTime\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoL = new Tone.LFO({\n\t 'frequency': options.frequency,\n\t 'min': 0,\n\t 'max': 1\n\t });\n\t /**\n\t\t\t * another LFO for the right side with a 180 degree phase diff\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoR = new Tone.LFO({\n\t 'frequency': options.frequency,\n\t 'min': 0,\n\t 'max': 1,\n\t 'phase': 180\n\t });\n\t /**\n\t\t\t * delay for left\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._delayNodeL = new Tone.Delay();\n\t /**\n\t\t\t * delay for right\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._delayNodeR = new Tone.Delay();\n\t /**\n\t\t\t * The frequency of the LFO which modulates the delayTime.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._lfoL.frequency;\n\t //connections\n\t this.effectSendL.chain(this._delayNodeL, this.effectReturnL);\n\t this.effectSendR.chain(this._delayNodeR, this.effectReturnR);\n\t //and pass through to make the detune apparent\n\t this.effectSendL.connect(this.effectReturnL);\n\t this.effectSendR.connect(this.effectReturnR);\n\t //lfo setup\n\t this._lfoL.connect(this._delayNodeL.delayTime);\n\t this._lfoR.connect(this._delayNodeR.delayTime);\n\t //start the lfo\n\t this._lfoL.start();\n\t this._lfoR.start();\n\t //have one LFO frequency control the other\n\t this._lfoL.frequency.connect(this._lfoR.frequency);\n\t //set the initial values\n\t this.depth = this._depth;\n\t this.frequency.value = options.frequency;\n\t this.type = options.type;\n\t this._readOnly(['frequency']);\n\t this.spread = options.spread;\n\t };\n\t Tone.extend(Tone.Chorus, Tone.StereoEffect);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Chorus.defaults = {\n\t 'frequency': 1.5,\n\t 'delayTime': 3.5,\n\t 'depth': 0.7,\n\t 'type': 'sine',\n\t 'spread': 180\n\t };\n\t /**\n\t\t * The depth of the effect. A depth of 1 makes the delayTime\n\t\t * modulate between 0 and 2*delayTime (centered around the delayTime).\n\t\t * @memberOf Tone.Chorus#\n\t\t * @type {NormalRange}\n\t\t * @name depth\n\t\t */\n\t Object.defineProperty(Tone.Chorus.prototype, 'depth', {\n\t get: function () {\n\t return this._depth;\n\t },\n\t set: function (depth) {\n\t this._depth = depth;\n\t var deviation = this._delayTime * depth;\n\t this._lfoL.min = Math.max(this._delayTime - deviation, 0);\n\t this._lfoL.max = this._delayTime + deviation;\n\t this._lfoR.min = Math.max(this._delayTime - deviation, 0);\n\t this._lfoR.max = this._delayTime + deviation;\n\t }\n\t });\n\t /**\n\t\t * The delayTime in milliseconds of the chorus. A larger delayTime\n\t\t * will give a more pronounced effect. Nominal range a delayTime\n\t\t * is between 2 and 20ms.\n\t\t * @memberOf Tone.Chorus#\n\t\t * @type {Milliseconds}\n\t\t * @name delayTime\n\t\t */\n\t Object.defineProperty(Tone.Chorus.prototype, 'delayTime', {\n\t get: function () {\n\t return this._delayTime * 1000;\n\t },\n\t set: function (delayTime) {\n\t this._delayTime = delayTime / 1000;\n\t this.depth = this._depth;\n\t }\n\t });\n\t /**\n\t\t * The oscillator type of the LFO.\n\t\t * @memberOf Tone.Chorus#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.Chorus.prototype, 'type', {\n\t get: function () {\n\t return this._lfoL.type;\n\t },\n\t set: function (type) {\n\t this._lfoL.type = type;\n\t this._lfoR.type = type;\n\t }\n\t });\n\t /**\n\t\t * Amount of stereo spread. When set to 0, both LFO's will be panned centrally.\n\t\t * When set to 180, LFO's will be panned hard left and right respectively.\n\t\t * @memberOf Tone.Chorus#\n\t\t * @type {Degrees}\n\t\t * @name spread\n\t\t */\n\t Object.defineProperty(Tone.Chorus.prototype, 'spread', {\n\t get: function () {\n\t return this._lfoR.phase - this._lfoL.phase;\n\t },\n\t set: function (spread) {\n\t this._lfoL.phase = 90 - spread / 2;\n\t this._lfoR.phase = spread / 2 + 90;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Chorus} this\n\t\t */\n\t Tone.Chorus.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t this._lfoL.dispose();\n\t this._lfoL = null;\n\t this._lfoR.dispose();\n\t this._lfoR = null;\n\t this._delayNodeL.dispose();\n\t this._delayNodeL = null;\n\t this._delayNodeR.dispose();\n\t this._delayNodeR = null;\n\t this._writable('frequency');\n\t this.frequency = null;\n\t return this;\n\t };\n\t return Tone.Chorus;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Convolver is a wrapper around the Native Web Audio\n\t\t * [ConvolverNode](http://webaudio.github.io/web-audio-api/#the-convolvernode-interface).\n\t\t * Convolution is useful for reverb and filter emulation. Read more about convolution reverb on\n\t\t * [Wikipedia](https://en.wikipedia.org/wiki/Convolution_reverb).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Effect}\n\t\t * @param {string|Tone.Buffer|Object} [url] The URL of the impulse response or the Tone.Buffer\n\t\t * contianing the impulse response.\n\t\t * @param {Function=} onload The callback to invoke when the url is loaded.\n\t\t * @example\n\t\t * //initializing the convolver with an impulse response\n\t\t * var convolver = new Tone.Convolver(\"./path/to/ir.wav\").toMaster();\n\t\t */\n\t Tone.Convolver = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'url',\n\t 'onload'\n\t ], Tone.Convolver);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * convolver node\n\t\t\t * @type {ConvolverNode}\n\t\t\t * @private\n\t\t\t */\n\t this._convolver = this.context.createConvolver();\n\t /**\n\t\t\t * the convolution buffer\n\t\t\t * @type {Tone.Buffer}\n\t\t\t * @private\n\t\t\t */\n\t this._buffer = new Tone.Buffer(options.url, function (buffer) {\n\t this._convolver.buffer = buffer.get();\n\t options.onload();\n\t }.bind(this));\n\t this.connectEffect(this._convolver);\n\t };\n\t Tone.extend(Tone.Convolver, Tone.Effect);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Convolver.defaults = { 'onload': Tone.noOp };\n\t /**\n\t\t * The convolver's buffer\n\t\t * @memberOf Tone.Convolver#\n\t\t * @type {AudioBuffer}\n\t\t * @name buffer\n\t\t */\n\t Object.defineProperty(Tone.Convolver.prototype, 'buffer', {\n\t get: function () {\n\t return this._buffer.get();\n\t },\n\t set: function (buffer) {\n\t this._buffer.set(buffer);\n\t this._convolver.buffer = this._buffer.get();\n\t }\n\t });\n\t /**\n\t\t * Load an impulse response url as an audio buffer.\n\t\t * Decodes the audio asynchronously and invokes\n\t\t * the callback once the audio buffer loads.\n\t\t * @param {string} url The url of the buffer to load.\n\t\t * filetype support depends on the\n\t\t * browser.\n\t\t * @param {function=} callback\n\t\t * @returns {Promise}\n\t\t */\n\t Tone.Convolver.prototype.load = function (url, callback) {\n\t return this._buffer.load(url, function (buff) {\n\t this.buffer = buff;\n\t if (callback) {\n\t callback();\n\t }\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Convolver} this\n\t\t */\n\t Tone.Convolver.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._convolver.disconnect();\n\t this._convolver = null;\n\t this._buffer.dispose();\n\t this._buffer = null;\n\t return this;\n\t };\n\t return Tone.Convolver;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Distortion is a simple distortion effect using Tone.WaveShaper.\n\t\t * Algorithm from [a stackoverflow answer](http://stackoverflow.com/a/22313408).\n\t\t *\n\t\t * @extends {Tone.Effect}\n\t\t * @constructor\n\t\t * @param {Number|Object} [distortion] The amount of distortion (nominal range of 0-1)\n\t\t * @example\n\t\t * var dist = new Tone.Distortion(0.8).toMaster();\n\t\t * var fm = new Tone.SimpleFM().connect(dist);\n\t\t * //this sounds good on bass notes\n\t\t * fm.triggerAttackRelease(\"A1\", \"8n\");\n\t\t */\n\t Tone.Distortion = function () {\n\t var options = Tone.defaults(arguments, ['distortion'], Tone.Distortion);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * @type {Tone.WaveShaper}\n\t\t\t * @private\n\t\t\t */\n\t this._shaper = new Tone.WaveShaper(4096);\n\t /**\n\t\t\t * holds the distortion amount\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._distortion = options.distortion;\n\t this.connectEffect(this._shaper);\n\t this.distortion = options.distortion;\n\t this.oversample = options.oversample;\n\t };\n\t Tone.extend(Tone.Distortion, Tone.Effect);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Distortion.defaults = {\n\t 'distortion': 0.4,\n\t 'oversample': 'none'\n\t };\n\t /**\n\t\t * The amount of distortion.\n\t\t * @memberOf Tone.Distortion#\n\t\t * @type {NormalRange}\n\t\t * @name distortion\n\t\t */\n\t Object.defineProperty(Tone.Distortion.prototype, 'distortion', {\n\t get: function () {\n\t return this._distortion;\n\t },\n\t set: function (amount) {\n\t this._distortion = amount;\n\t var k = amount * 100;\n\t var deg = Math.PI / 180;\n\t this._shaper.setMap(function (x) {\n\t if (Math.abs(x) < 0.001) {\n\t //should output 0 when input is 0\n\t return 0;\n\t } else {\n\t return (3 + k) * x * 20 * deg / (Math.PI + k * Math.abs(x));\n\t }\n\t });\n\t }\n\t });\n\t /**\n\t\t * The oversampling of the effect. Can either be \"none\", \"2x\" or \"4x\".\n\t\t * @memberOf Tone.Distortion#\n\t\t * @type {string}\n\t\t * @name oversample\n\t\t */\n\t Object.defineProperty(Tone.Distortion.prototype, 'oversample', {\n\t get: function () {\n\t return this._shaper.oversample;\n\t },\n\t set: function (oversampling) {\n\t this._shaper.oversample = oversampling;\n\t }\n\t });\n\t /**\n\t\t * Clean up. \n\t\t * @returns {Tone.Distortion} this\n\t\t */\n\t Tone.Distortion.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._shaper.dispose();\n\t this._shaper = null;\n\t return this;\n\t };\n\t return Tone.Distortion;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * \t@class Tone.FeedbackEffect provides a loop between an \n\t\t * \t audio source and its own output. This is a base-class\n\t\t * \t for feedback effects. \n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Effect}\n\t\t * @param {NormalRange|Object} [feedback] The initial feedback value.\n\t\t */\n\t Tone.FeedbackEffect = function () {\n\t var options = Tone.defaults(arguments, ['feedback'], Tone.FeedbackEffect);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * the gain which controls the feedback\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackGain = new Tone.Gain(options.feedback, Tone.Type.NormalRange);\n\t /**\n\t\t\t * The amount of signal which is fed back into the effect input. \n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.feedback = this._feedbackGain.gain;\n\t //the feedback loop\n\t this.effectReturn.chain(this._feedbackGain, this.effectSend);\n\t this._readOnly(['feedback']);\n\t };\n\t Tone.extend(Tone.FeedbackEffect, Tone.Effect);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.FeedbackEffect.defaults = { 'feedback': 0.125 };\n\t /**\n\t\t * Clean up. \n\t\t * @returns {Tone.FeedbackEffect} this\n\t\t */\n\t Tone.FeedbackEffect.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._writable(['feedback']);\n\t this._feedbackGain.dispose();\n\t this._feedbackGain = null;\n\t this.feedback = null;\n\t return this;\n\t };\n\t return Tone.FeedbackEffect;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.FeedbackDelay is a DelayNode in which part of output\n\t\t * signal is fed back into the delay.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.FeedbackEffect}\n\t\t * @param {Time|Object} [delayTime] The delay applied to the incoming signal.\n\t\t * @param {NormalRange=} feedback The amount of the effected signal which\n\t\t * is fed back through the delay.\n\t\t * @example\n\t\t * var feedbackDelay = new Tone.FeedbackDelay(\"8n\", 0.5).toMaster();\n\t\t * var tom = new Tone.DrumSynth({\n\t\t * \t\"octaves\" : 4,\n\t\t * \t\"pitchDecay\" : 0.1\n\t\t * }).connect(feedbackDelay);\n\t\t * tom.triggerAttackRelease(\"A2\",\"32n\");\n\t\t */\n\t Tone.FeedbackDelay = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'delayTime',\n\t 'feedback'\n\t ], Tone.FeedbackDelay);\n\t Tone.FeedbackEffect.call(this, options);\n\t /**\n\t\t\t * the delay node\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._delayNode = new Tone.Delay(options.delayTime, options.maxDelay);\n\t /**\n\t\t\t * The delayTime of the DelayNode.\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.delayTime = this._delayNode.delayTime;\n\t // connect it up\n\t this.connectEffect(this._delayNode);\n\t this._readOnly(['delayTime']);\n\t };\n\t Tone.extend(Tone.FeedbackDelay, Tone.FeedbackEffect);\n\t /**\n\t\t * The default values.\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.FeedbackDelay.defaults = {\n\t 'delayTime': 0.25,\n\t 'maxDelay': 1\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.FeedbackDelay} this\n\t\t */\n\t Tone.FeedbackDelay.prototype.dispose = function () {\n\t Tone.FeedbackEffect.prototype.dispose.call(this);\n\t this._delayNode.dispose();\n\t this._delayNode = null;\n\t this._writable(['delayTime']);\n\t this.delayTime = null;\n\t return this;\n\t };\n\t return Tone.FeedbackDelay;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * an array of comb filter delay values from Freeverb implementation\n\t\t * @static\n\t\t * @private\n\t\t * @type {Array}\n\t\t */\n\t var combFilterTunings = [\n\t 1557 / 44100,\n\t 1617 / 44100,\n\t 1491 / 44100,\n\t 1422 / 44100,\n\t 1277 / 44100,\n\t 1356 / 44100,\n\t 1188 / 44100,\n\t 1116 / 44100\n\t ];\n\t /**\n\t\t * an array of allpass filter frequency values from Freeverb implementation\n\t\t * @private\n\t\t * @static\n\t\t * @type {Array}\n\t\t */\n\t var allpassFilterFrequencies = [\n\t 225,\n\t 556,\n\t 441,\n\t 341\n\t ];\n\t /**\n\t\t * @class Tone.Freeverb is a reverb based on [Freeverb](https://ccrma.stanford.edu/~jos/pasp/Freeverb.html).\n\t\t * Read more on reverb on [Sound On Sound](https://web.archive.org/web/20160404083902/http://www.soundonsound.com:80/sos/feb01/articles/synthsecrets.asp).\n\t\t *\n\t\t * @extends {Tone.Effect}\n\t\t * @constructor\n\t\t * @param {NormalRange|Object} [roomSize] Correlated to the decay time.\n\t\t * @param {Frequency} [dampening] The cutoff frequency of a lowpass filter as part\n\t\t * of the reverb.\n\t\t * @example\n\t\t * var freeverb = new Tone.Freeverb().toMaster();\n\t\t * freeverb.dampening.value = 1000;\n\t\t * //routing synth through the reverb\n\t\t * var synth = new Tone.AMSynth().connect(freeverb);\n\t\t */\n\t Tone.Freeverb = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'roomSize',\n\t 'dampening'\n\t ], Tone.Freeverb);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * The roomSize value between. A larger roomSize\n\t\t\t * will result in a longer decay.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.roomSize = new Tone.Signal(options.roomSize, Tone.Type.NormalRange);\n\t /**\n\t\t\t * The amount of dampening of the reverberant signal.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.dampening = new Tone.Signal(options.dampening, Tone.Type.Frequency);\n\t /**\n\t\t\t * the comb filters\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._combFilters = [];\n\t /**\n\t\t\t * the allpass filters on the left\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._allpassFiltersL = [];\n\t /**\n\t\t\t * the allpass filters on the right\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._allpassFiltersR = [];\n\t //make the allpass filters on the right\n\t for (var l = 0; l < allpassFilterFrequencies.length; l++) {\n\t var allpassL = this.context.createBiquadFilter();\n\t allpassL.type = 'allpass';\n\t allpassL.frequency.value = allpassFilterFrequencies[l];\n\t this._allpassFiltersL.push(allpassL);\n\t }\n\t //make the allpass filters on the left\n\t for (var r = 0; r < allpassFilterFrequencies.length; r++) {\n\t var allpassR = this.context.createBiquadFilter();\n\t allpassR.type = 'allpass';\n\t allpassR.frequency.value = allpassFilterFrequencies[r];\n\t this._allpassFiltersR.push(allpassR);\n\t }\n\t //make the comb filters\n\t for (var c = 0; c < combFilterTunings.length; c++) {\n\t var lfpf = new Tone.LowpassCombFilter(combFilterTunings[c]);\n\t if (c < combFilterTunings.length / 2) {\n\t this.effectSendL.chain(lfpf, this._allpassFiltersL[0]);\n\t } else {\n\t this.effectSendR.chain(lfpf, this._allpassFiltersR[0]);\n\t }\n\t this.roomSize.connect(lfpf.resonance);\n\t this.dampening.connect(lfpf.dampening);\n\t this._combFilters.push(lfpf);\n\t }\n\t //chain the allpass filters togetehr\n\t Tone.connectSeries.apply(Tone, this._allpassFiltersL);\n\t Tone.connectSeries.apply(Tone, this._allpassFiltersR);\n\t this._allpassFiltersL[this._allpassFiltersL.length - 1].connect(this.effectReturnL);\n\t this._allpassFiltersR[this._allpassFiltersR.length - 1].connect(this.effectReturnR);\n\t this._readOnly([\n\t 'roomSize',\n\t 'dampening'\n\t ]);\n\t };\n\t Tone.extend(Tone.Freeverb, Tone.StereoEffect);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Freeverb.defaults = {\n\t 'roomSize': 0.7,\n\t 'dampening': 3000\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Freeverb} this\n\t\t */\n\t Tone.Freeverb.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t for (var al = 0; al < this._allpassFiltersL.length; al++) {\n\t this._allpassFiltersL[al].disconnect();\n\t this._allpassFiltersL[al] = null;\n\t }\n\t this._allpassFiltersL = null;\n\t for (var ar = 0; ar < this._allpassFiltersR.length; ar++) {\n\t this._allpassFiltersR[ar].disconnect();\n\t this._allpassFiltersR[ar] = null;\n\t }\n\t this._allpassFiltersR = null;\n\t for (var cf = 0; cf < this._combFilters.length; cf++) {\n\t this._combFilters[cf].dispose();\n\t this._combFilters[cf] = null;\n\t }\n\t this._combFilters = null;\n\t this._writable([\n\t 'roomSize',\n\t 'dampening'\n\t ]);\n\t this.roomSize.dispose();\n\t this.roomSize = null;\n\t this.dampening.dispose();\n\t this.dampening = null;\n\t return this;\n\t };\n\t return Tone.Freeverb;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * an array of the comb filter delay time values\n\t\t * @private\n\t\t * @static\n\t\t * @type {Array}\n\t\t */\n\t var combFilterDelayTimes = [\n\t 1687 / 25000,\n\t 1601 / 25000,\n\t 2053 / 25000,\n\t 2251 / 25000\n\t ];\n\t /**\n\t\t * the resonances of each of the comb filters\n\t\t * @private\n\t\t * @static\n\t\t * @type {Array}\n\t\t */\n\t var combFilterResonances = [\n\t 0.773,\n\t 0.802,\n\t 0.753,\n\t 0.733\n\t ];\n\t /**\n\t\t * the allpass filter frequencies\n\t\t * @private\n\t\t * @static\n\t\t * @type {Array}\n\t\t */\n\t var allpassFilterFreqs = [\n\t 347,\n\t 113,\n\t 37\n\t ];\n\t /**\n\t\t * @class Tone.JCReverb is a simple [Schroeder Reverberator](https://ccrma.stanford.edu/~jos/pasp/Schroeder_Reverberators.html)\n\t\t * tuned by John Chowning in 1970.\n\t\t * It is made up of three allpass filters and four Tone.FeedbackCombFilter.\n\t\t *\n\t\t *\n\t\t * @extends {Tone.Effect}\n\t\t * @constructor\n\t\t * @param {NormalRange|Object} [roomSize] Coorelates to the decay time.\n\t\t * @example\n\t\t * var reverb = new Tone.JCReverb(0.4).connect(Tone.Master);\n\t\t * var delay = new Tone.FeedbackDelay(0.5);\n\t\t * //connecting the synth to reverb through delay\n\t\t * var synth = new Tone.DuoSynth().chain(delay, reverb);\n\t\t * synth.triggerAttackRelease(\"A4\",\"8n\");\n\t\t */\n\t Tone.JCReverb = function () {\n\t var options = Tone.defaults(arguments, ['roomSize'], Tone.JCReverb);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * room size control values between [0,1]\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.roomSize = new Tone.Signal(options.roomSize, Tone.Type.NormalRange);\n\t /**\n\t\t\t * scale the room size\n\t\t\t * @type {Tone.Scale}\n\t\t\t * @private\n\t\t\t */\n\t this._scaleRoomSize = new Tone.Scale(-0.733, 0.197);\n\t /**\n\t\t\t * a series of allpass filters\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._allpassFilters = [];\n\t /**\n\t\t\t * parallel feedback comb filters\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackCombFilters = [];\n\t //make the allpass filters\n\t for (var af = 0; af < allpassFilterFreqs.length; af++) {\n\t var allpass = this.context.createBiquadFilter();\n\t allpass.type = 'allpass';\n\t allpass.frequency.value = allpassFilterFreqs[af];\n\t this._allpassFilters.push(allpass);\n\t }\n\t //and the comb filters\n\t for (var cf = 0; cf < combFilterDelayTimes.length; cf++) {\n\t var fbcf = new Tone.FeedbackCombFilter(combFilterDelayTimes[cf], 0.1);\n\t this._scaleRoomSize.connect(fbcf.resonance);\n\t fbcf.resonance.value = combFilterResonances[cf];\n\t this._allpassFilters[this._allpassFilters.length - 1].connect(fbcf);\n\t if (cf < combFilterDelayTimes.length / 2) {\n\t fbcf.connect(this.effectReturnL);\n\t } else {\n\t fbcf.connect(this.effectReturnR);\n\t }\n\t this._feedbackCombFilters.push(fbcf);\n\t }\n\t //chain the allpass filters together\n\t this.roomSize.connect(this._scaleRoomSize);\n\t Tone.connectSeries.apply(Tone, this._allpassFilters);\n\t this.effectSendL.connect(this._allpassFilters[0]);\n\t this.effectSendR.connect(this._allpassFilters[0]);\n\t this._readOnly(['roomSize']);\n\t };\n\t Tone.extend(Tone.JCReverb, Tone.StereoEffect);\n\t /**\n\t\t * the default values\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.JCReverb.defaults = { 'roomSize': 0.5 };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.JCReverb} this\n\t\t */\n\t Tone.JCReverb.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t for (var apf = 0; apf < this._allpassFilters.length; apf++) {\n\t this._allpassFilters[apf].disconnect();\n\t this._allpassFilters[apf] = null;\n\t }\n\t this._allpassFilters = null;\n\t for (var fbcf = 0; fbcf < this._feedbackCombFilters.length; fbcf++) {\n\t this._feedbackCombFilters[fbcf].dispose();\n\t this._feedbackCombFilters[fbcf] = null;\n\t }\n\t this._feedbackCombFilters = null;\n\t this._writable(['roomSize']);\n\t this.roomSize.dispose();\n\t this.roomSize = null;\n\t this._scaleRoomSize.dispose();\n\t this._scaleRoomSize = null;\n\t return this;\n\t };\n\t return Tone.JCReverb;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Mid/Side processing separates the the 'mid' signal\n\t\t * (which comes out of both the left and the right channel)\n\t\t * and the 'side' (which only comes out of the the side channels)\n\t\t * and effects them separately before being recombined.\n\t\t * Applies a Mid/Side seperation and recombination.\n\t\t * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587).\n\t\t * <br><br>\n\t\t * This is a base-class for Mid/Side Effects.\n\t\t *\n\t\t * @extends {Tone.Effect}\n\t\t * @constructor\n\t\t */\n\t Tone.MidSideEffect = function () {\n\t Tone.Effect.apply(this, arguments);\n\t /**\n\t\t\t * The mid/side split\n\t\t\t * @type {Tone.MidSideSplit}\n\t\t\t * @private\n\t\t\t */\n\t this._midSideSplit = new Tone.MidSideSplit();\n\t /**\n\t\t\t * The mid/side merge\n\t\t\t * @type {Tone.MidSideMerge}\n\t\t\t * @private\n\t\t\t */\n\t this._midSideMerge = new Tone.MidSideMerge();\n\t /**\n\t\t\t * The mid send. Connect to mid processing\n\t\t\t * @type {Tone}\n\t\t\t * @private\n\t\t\t */\n\t this.midSend = this._midSideSplit.mid;\n\t /**\n\t\t\t * The side send. Connect to side processing\n\t\t\t * @type {Tone}\n\t\t\t * @private\n\t\t\t */\n\t this.sideSend = this._midSideSplit.side;\n\t /**\n\t\t\t * The mid return connection\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.midReturn = this._midSideMerge.mid;\n\t /**\n\t\t\t * The side return connection\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this.sideReturn = this._midSideMerge.side;\n\t //the connections\n\t this.effectSend.connect(this._midSideSplit);\n\t this._midSideMerge.connect(this.effectReturn);\n\t };\n\t Tone.extend(Tone.MidSideEffect, Tone.Effect);\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.MidSideEffect} this\n\t\t */\n\t Tone.MidSideEffect.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._midSideSplit.dispose();\n\t this._midSideSplit = null;\n\t this._midSideMerge.dispose();\n\t this._midSideMerge = null;\n\t this.midSend = null;\n\t this.sideSend = null;\n\t this.midReturn = null;\n\t this.sideReturn = null;\n\t return this;\n\t };\n\t return Tone.MidSideEffect;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Phaser is a phaser effect. Phasers work by changing the phase\n\t\t * of different frequency components of an incoming signal. Read more on\n\t\t * [Wikipedia](https://en.wikipedia.org/wiki/Phaser_(effect)).\n\t\t * Inspiration for this phaser comes from [Tuna.js](https://github.com/Dinahmoe/tuna/).\n\t\t *\n\t\t *\t@extends {Tone.StereoEffect}\n\t\t *\t@constructor\n\t\t *\t@param {Frequency|Object} [frequency] The speed of the phasing.\n\t\t *\t@param {number} [octaves] The octaves of the effect.\n\t\t *\t@param {Frequency} [baseFrequency] The base frequency of the filters.\n\t\t *\t@example\n\t\t * var phaser = new Tone.Phaser({\n\t\t * \t\"frequency\" : 15,\n\t\t * \t\"octaves\" : 5,\n\t\t * \t\"baseFrequency\" : 1000\n\t\t * }).toMaster();\n\t\t * var synth = new Tone.FMSynth().connect(phaser);\n\t\t * synth.triggerAttackRelease(\"E3\", \"2n\");\n\t\t */\n\t Tone.Phaser = function () {\n\t //set the defaults\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'octaves',\n\t 'baseFrequency'\n\t ], Tone.Phaser);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * the lfo which controls the frequency on the left side\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoL = new Tone.LFO(options.frequency, 0, 1);\n\t /**\n\t\t\t * the lfo which controls the frequency on the right side\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoR = new Tone.LFO(options.frequency, 0, 1);\n\t this._lfoR.phase = 180;\n\t /**\n\t\t\t * the base modulation frequency\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._baseFrequency = options.baseFrequency;\n\t /**\n\t\t\t * the octaves of the phasing\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._octaves = options.octaves;\n\t /**\n\t\t\t * The quality factor of the filters\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this.Q = new Tone.Signal(options.Q, Tone.Type.Positive);\n\t /**\n\t\t\t * the array of filters for the left side\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._filtersL = this._makeFilters(options.stages, this._lfoL, this.Q);\n\t /**\n\t\t\t * the array of filters for the left side\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._filtersR = this._makeFilters(options.stages, this._lfoR, this.Q);\n\t /**\n\t\t\t * the frequency of the effect\n\t\t\t * @type {Tone.Signal}\n\t\t\t */\n\t this.frequency = this._lfoL.frequency;\n\t this.frequency.value = options.frequency;\n\t //connect them up\n\t this.effectSendL.connect(this._filtersL[0]);\n\t this.effectSendR.connect(this._filtersR[0]);\n\t this._filtersL[options.stages - 1].connect(this.effectReturnL);\n\t this._filtersR[options.stages - 1].connect(this.effectReturnR);\n\t //control the frequency with one LFO\n\t this._lfoL.frequency.connect(this._lfoR.frequency);\n\t //set the options\n\t this.baseFrequency = options.baseFrequency;\n\t this.octaves = options.octaves;\n\t //start the lfo\n\t this._lfoL.start();\n\t this._lfoR.start();\n\t this._readOnly([\n\t 'frequency',\n\t 'Q'\n\t ]);\n\t };\n\t Tone.extend(Tone.Phaser, Tone.StereoEffect);\n\t /**\n\t\t * defaults\n\t\t * @static\n\t\t * @type {object}\n\t\t */\n\t Tone.Phaser.defaults = {\n\t 'frequency': 0.5,\n\t 'octaves': 3,\n\t 'stages': 10,\n\t 'Q': 10,\n\t 'baseFrequency': 350\n\t };\n\t /**\n\t\t * @param {number} stages\n\t\t * @returns {Array} the number of filters all connected together\n\t\t * @private\n\t\t */\n\t Tone.Phaser.prototype._makeFilters = function (stages, connectToFreq, Q) {\n\t var filters = new Array(stages);\n\t //make all the filters\n\t for (var i = 0; i < stages; i++) {\n\t var filter = this.context.createBiquadFilter();\n\t filter.type = 'allpass';\n\t Q.connect(filter.Q);\n\t connectToFreq.connect(filter.frequency);\n\t filters[i] = filter;\n\t }\n\t Tone.connectSeries.apply(Tone, filters);\n\t return filters;\n\t };\n\t /**\n\t\t * The number of octaves the phase goes above\n\t\t * the baseFrequency\n\t\t * @memberOf Tone.Phaser#\n\t\t * @type {Positive}\n\t\t * @name octaves\n\t\t */\n\t Object.defineProperty(Tone.Phaser.prototype, 'octaves', {\n\t get: function () {\n\t return this._octaves;\n\t },\n\t set: function (octaves) {\n\t this._octaves = octaves;\n\t var max = this._baseFrequency * Math.pow(2, octaves);\n\t this._lfoL.max = max;\n\t this._lfoR.max = max;\n\t }\n\t });\n\t /**\n\t\t * The the base frequency of the filters.\n\t\t * @memberOf Tone.Phaser#\n\t\t * @type {number}\n\t\t * @name baseFrequency\n\t\t */\n\t Object.defineProperty(Tone.Phaser.prototype, 'baseFrequency', {\n\t get: function () {\n\t return this._baseFrequency;\n\t },\n\t set: function (freq) {\n\t this._baseFrequency = freq;\n\t this._lfoL.min = freq;\n\t this._lfoR.min = freq;\n\t this.octaves = this._octaves;\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Phaser} this\n\t\t */\n\t Tone.Phaser.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'Q'\n\t ]);\n\t this.Q.dispose();\n\t this.Q = null;\n\t this._lfoL.dispose();\n\t this._lfoL = null;\n\t this._lfoR.dispose();\n\t this._lfoR = null;\n\t for (var i = 0; i < this._filtersL.length; i++) {\n\t this._filtersL[i].disconnect();\n\t this._filtersL[i] = null;\n\t }\n\t this._filtersL = null;\n\t for (var j = 0; j < this._filtersR.length; j++) {\n\t this._filtersR[j].disconnect();\n\t this._filtersR[j] = null;\n\t }\n\t this._filtersR = null;\n\t this.frequency = null;\n\t return this;\n\t };\n\t return Tone.Phaser;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Just like a stereo feedback effect, but the feedback is routed from left to right\n\t\t * and right to left instead of on the same channel.\n\t\t *\n\t\t *\t@constructor\n\t\t *\t@extends {Tone.StereoEffect}\n\t\t */\n\t Tone.StereoXFeedbackEffect = function () {\n\t var options = Tone.defaults(arguments, ['feedback'], Tone.FeedbackEffect);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * The amount of feedback from the output\n\t\t\t * back into the input of the effect (routed\n\t\t\t * across left and right channels).\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.feedback = new Tone.Signal(options.feedback, Tone.Type.NormalRange);\n\t /**\n\t\t\t * the left side feeback\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackLR = new Tone.Gain();\n\t /**\n\t\t\t * the right side feeback\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackRL = new Tone.Gain();\n\t //connect it up\n\t this.effectReturnL.chain(this._feedbackLR, this.effectSendR);\n\t this.effectReturnR.chain(this._feedbackRL, this.effectSendL);\n\t this.feedback.fan(this._feedbackLR.gain, this._feedbackRL.gain);\n\t this._readOnly(['feedback']);\n\t };\n\t Tone.extend(Tone.StereoXFeedbackEffect, Tone.StereoEffect);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.StereoXFeedbackEffect} this\n\t\t */\n\t Tone.StereoXFeedbackEffect.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t this._writable(['feedback']);\n\t this.feedback.dispose();\n\t this.feedback = null;\n\t this._feedbackLR.dispose();\n\t this._feedbackLR = null;\n\t this._feedbackRL.dispose();\n\t this._feedbackRL = null;\n\t return this;\n\t };\n\t return Tone.StereoXFeedbackEffect;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.PingPongDelay is a feedback delay effect where the echo is heard\n\t\t * first in one channel and next in the opposite channel. In a stereo\n\t\t * system these are the right and left channels.\n\t\t * PingPongDelay in more simplified terms is two Tone.FeedbackDelays\n\t\t * with independent delay values. Each delay is routed to one channel\n\t\t * (left or right), and the channel triggered second will always\n\t\t * trigger at the same interval after the first.\n\t\t *\n\t\t * \t@constructor\n\t\t * \t@extends {Tone.StereoXFeedbackEffect}\n\t\t * @param {Time|Object} [delayTime] The delayTime between consecutive echos.\n\t\t * @param {NormalRange=} feedback The amount of the effected signal which\n\t\t * is fed back through the delay.\n\t\t * @example\n\t\t * var pingPong = new Tone.PingPongDelay(\"4n\", 0.2).toMaster();\n\t\t * var drum = new Tone.DrumSynth().connect(pingPong);\n\t\t * drum.triggerAttackRelease(\"C4\", \"32n\");\n\t\t */\n\t Tone.PingPongDelay = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'delayTime',\n\t 'feedback'\n\t ], Tone.PingPongDelay);\n\t Tone.StereoXFeedbackEffect.call(this, options);\n\t /**\n\t\t\t * the delay node on the left side\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._leftDelay = new Tone.Delay(0, options.maxDelayTime);\n\t /**\n\t\t\t * the delay node on the right side\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._rightDelay = new Tone.Delay(0, options.maxDelayTime);\n\t /**\n\t\t\t * the predelay on the right side\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._rightPreDelay = new Tone.Delay(0, options.maxDelayTime);\n\t /**\n\t\t\t * the delay time signal\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.delayTime = new Tone.Signal(options.delayTime, Tone.Type.Time);\n\t //connect it up\n\t this.effectSendL.chain(this._leftDelay, this.effectReturnL);\n\t this.effectSendR.chain(this._rightPreDelay, this._rightDelay, this.effectReturnR);\n\t this.delayTime.fan(this._leftDelay.delayTime, this._rightDelay.delayTime, this._rightPreDelay.delayTime);\n\t //rearranged the feedback to be after the rightPreDelay\n\t this._feedbackLR.disconnect();\n\t this._feedbackLR.connect(this._rightDelay);\n\t this._readOnly(['delayTime']);\n\t };\n\t Tone.extend(Tone.PingPongDelay, Tone.StereoXFeedbackEffect);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.PingPongDelay.defaults = {\n\t 'delayTime': 0.25,\n\t 'maxDelayTime': 1\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.PingPongDelay} this\n\t\t */\n\t Tone.PingPongDelay.prototype.dispose = function () {\n\t Tone.StereoXFeedbackEffect.prototype.dispose.call(this);\n\t this._leftDelay.dispose();\n\t this._leftDelay = null;\n\t this._rightDelay.dispose();\n\t this._rightDelay = null;\n\t this._rightPreDelay.dispose();\n\t this._rightPreDelay = null;\n\t this._writable(['delayTime']);\n\t this.delayTime.dispose();\n\t this.delayTime = null;\n\t return this;\n\t };\n\t return Tone.PingPongDelay;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.PitchShift does near-realtime pitch shifting to the incoming signal.\n\t\t * The effect is achieved by speeding up or slowing down the delayTime\n\t\t * of a DelayNode using a sawtooth wave.\n\t\t * Algorithm found in [this pdf](http://dsp-book.narod.ru/soundproc.pdf).\n\t\t * Additional reference by [Miller Pucket](http://msp.ucsd.edu/techniques/v0.11/book-html/node115.html).\n\t\t *\n\t\t * @extends {Tone.FeedbackEffect}\n\t\t * @param {Interval=} pitch The interval to transpose the incoming signal by.\n\t\t */\n\t Tone.PitchShift = function () {\n\t var options = Tone.defaults(arguments, ['pitch'], Tone.PitchShift);\n\t Tone.FeedbackEffect.call(this, options);\n\t /**\n\t\t\t * The pitch signal\n\t\t\t * @type {Tone.Signal}\n\t\t\t * @private\n\t\t\t */\n\t this._frequency = new Tone.Signal(0);\n\t /**\n\t\t\t * Uses two DelayNodes to cover up the jump in\n\t\t\t * the sawtooth wave.\n\t\t\t * @type {DelayNode}\n\t\t\t * @private\n\t\t\t */\n\t this._delayA = new Tone.Delay(0, 1);\n\t /**\n\t\t\t * The first LFO.\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoA = new Tone.LFO({\n\t 'min': 0,\n\t 'max': 0.1,\n\t 'type': 'sawtooth'\n\t }).connect(this._delayA.delayTime);\n\t /**\n\t\t\t * The second DelayNode\n\t\t\t * @type {DelayNode}\n\t\t\t * @private\n\t\t\t */\n\t this._delayB = new Tone.Delay(0, 1);\n\t /**\n\t\t\t * The first LFO.\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoB = new Tone.LFO({\n\t 'min': 0,\n\t 'max': 0.1,\n\t 'type': 'sawtooth',\n\t 'phase': 180\n\t }).connect(this._delayB.delayTime);\n\t /**\n\t\t\t * Crossfade quickly between the two delay lines\n\t\t\t * to cover up the jump in the sawtooth wave\n\t\t\t * @type {Tone.CrossFade}\n\t\t\t * @private\n\t\t\t */\n\t this._crossFade = new Tone.CrossFade();\n\t /**\n\t\t\t * LFO which alternates between the two\n\t\t\t * delay lines to cover up the disparity in the\n\t\t\t * sawtooth wave.\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._crossFadeLFO = new Tone.LFO({\n\t 'min': 0,\n\t 'max': 1,\n\t 'type': 'triangle',\n\t 'phase': 90\n\t }).connect(this._crossFade.fade);\n\t /**\n\t\t\t * The delay node\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackDelay = new Tone.Delay(options.delayTime);\n\t /**\n\t\t\t * The amount of delay on the input signal\n\t\t\t * @type {Time}\n\t\t\t * @signal\n\t\t\t */\n\t this.delayTime = this._feedbackDelay.delayTime;\n\t this._readOnly('delayTime');\n\t /**\n\t\t\t * Hold the current pitch\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._pitch = options.pitch;\n\t /**\n\t\t\t * Hold the current windowSize\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._windowSize = options.windowSize;\n\t //connect the two delay lines up\n\t this._delayA.connect(this._crossFade.a);\n\t this._delayB.connect(this._crossFade.b);\n\t //connect the frequency\n\t this._frequency.fan(this._lfoA.frequency, this._lfoB.frequency, this._crossFadeLFO.frequency);\n\t //route the input\n\t this.effectSend.fan(this._delayA, this._delayB);\n\t this._crossFade.chain(this._feedbackDelay, this.effectReturn);\n\t //start the LFOs at the same time\n\t var now = this.now();\n\t this._lfoA.start(now);\n\t this._lfoB.start(now);\n\t this._crossFadeLFO.start(now);\n\t //set the initial value\n\t this.windowSize = this._windowSize;\n\t };\n\t Tone.extend(Tone.PitchShift, Tone.FeedbackEffect);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.PitchShift.defaults = {\n\t 'pitch': 0,\n\t 'windowSize': 0.1,\n\t 'delayTime': 0,\n\t 'feedback': 0\n\t };\n\t /**\n\t\t * Repitch the incoming signal by some interval (measured\n\t\t * in semi-tones).\n\t\t * @memberOf Tone.PitchShift#\n\t\t * @type {Interval}\n\t\t * @name pitch\n\t\t * @example\n\t\t * pitchShift.pitch = -12; //down one octave\n\t\t * pitchShift.pitch = 7; //up a fifth\n\t\t */\n\t Object.defineProperty(Tone.PitchShift.prototype, 'pitch', {\n\t get: function () {\n\t return this._pitch;\n\t },\n\t set: function (interval) {\n\t this._pitch = interval;\n\t var factor = 0;\n\t if (interval < 0) {\n\t this._lfoA.min = 0;\n\t this._lfoA.max = this._windowSize;\n\t this._lfoB.min = 0;\n\t this._lfoB.max = this._windowSize;\n\t factor = Tone.intervalToFrequencyRatio(interval - 1) + 1;\n\t } else {\n\t this._lfoA.min = this._windowSize;\n\t this._lfoA.max = 0;\n\t this._lfoB.min = this._windowSize;\n\t this._lfoB.max = 0;\n\t factor = Tone.intervalToFrequencyRatio(interval) - 1;\n\t }\n\t this._frequency.value = factor * (1.2 / this._windowSize);\n\t }\n\t });\n\t /**\n\t\t * The window size corresponds roughly to the sample length in a looping sampler.\n\t\t * Smaller values are desirable for a less noticeable delay time of the pitch shifted\n\t\t * signal, but larger values will result in smoother pitch shifting for larger intervals.\n\t\t * A nominal range of 0.03 to 0.1 is recommended.\n\t\t * @memberOf Tone.PitchShift#\n\t\t * @type {Time}\n\t\t * @name windowSize\n\t\t * @example\n\t\t * pitchShift.windowSize = 0.1;\n\t\t */\n\t Object.defineProperty(Tone.PitchShift.prototype, 'windowSize', {\n\t get: function () {\n\t return this._windowSize;\n\t },\n\t set: function (size) {\n\t this._windowSize = this.toSeconds(size);\n\t this.pitch = this._pitch;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.PitchShift} this\n\t\t */\n\t Tone.PitchShift.prototype.dispose = function () {\n\t Tone.FeedbackEffect.prototype.dispose.call(this);\n\t this._frequency.dispose();\n\t this._frequency = null;\n\t this._delayA.disconnect();\n\t this._delayA = null;\n\t this._delayB.disconnect();\n\t this._delayB = null;\n\t this._lfoA.dispose();\n\t this._lfoA = null;\n\t this._lfoB.dispose();\n\t this._lfoB = null;\n\t this._crossFade.dispose();\n\t this._crossFade = null;\n\t this._crossFadeLFO.dispose();\n\t this._crossFadeLFO = null;\n\t this._writable('delayTime');\n\t this._feedbackDelay.dispose();\n\t this._feedbackDelay = null;\n\t this.delayTime = null;\n\t return this;\n\t };\n\t return Tone.PitchShift;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Wrapper around the native BufferSourceNode.\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {AudioBuffer|Tone.Buffer} buffer The buffer to play\n\t\t * @param {Function} onload The callback to invoke when the\n\t\t * buffer is done playing.\n\t\t */\n\t Tone.BufferSource = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'buffer',\n\t 'onload'\n\t ], Tone.BufferSource);\n\t Tone.AudioNode.call(this, options);\n\t /**\n\t\t\t * The callback to invoke after the\n\t\t\t * buffer source is done playing.\n\t\t\t * @type {Function}\n\t\t\t */\n\t this.onended = options.onended;\n\t /**\n\t\t\t * The time that the buffer was started.\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._startTime = -1;\n\t /**\n\t\t\t * An additional flag if the actual BufferSourceNode\n\t\t\t * has been started. b/c stopping an unstarted buffer\n\t\t\t * will throw it into an invalid state\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t this._sourceStarted = false;\n\t /**\n\t\t\t * Flag if the source has already been stopped\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t this._sourceStopped = false;\n\t /**\n\t\t\t * The time that the buffer is scheduled to stop.\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._stopTime = -1;\n\t /**\n\t\t\t * The gain node which envelopes the BufferSource\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._gainNode = this.output = new Tone.Gain();\n\t /**\n\t\t\t * The buffer source\n\t\t\t * @type {AudioBufferSourceNode}\n\t\t\t * @private\n\t\t\t */\n\t this._source = this.context.createBufferSource();\n\t this._source.connect(this._gainNode);\n\t this._source.onended = this._onended.bind(this);\n\t /**\n\t\t\t * The private buffer instance\n\t\t\t * @type {Tone.Buffer}\n\t\t\t * @private\n\t\t\t */\n\t this._buffer = new Tone.Buffer(options.buffer, options.onload);\n\t /**\n\t\t\t * The playbackRate of the buffer\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this.playbackRate = new Tone.Param(this._source.playbackRate, Tone.Type.Positive);\n\t /**\n\t\t\t * The fadeIn time of the amplitude envelope.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.fadeIn = options.fadeIn;\n\t /**\n\t\t\t * The fadeOut time of the amplitude envelope.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.fadeOut = options.fadeOut;\n\t /**\n\t\t\t * The curve applied to the fades, either \"linear\" or \"exponential\"\n\t\t\t * @type {String}\n\t\t\t */\n\t this.curve = options.curve;\n\t /**\n\t\t\t * The value that the buffer ramps to\n\t\t\t * @type {Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._gain = 1;\n\t /**\n\t\t\t * The onended timeout\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._onendedTimeout = -1;\n\t //set some values initially\n\t this.loop = options.loop;\n\t this.loopStart = options.loopStart;\n\t this.loopEnd = options.loopEnd;\n\t this.playbackRate.value = options.playbackRate;\n\t };\n\t Tone.extend(Tone.BufferSource, Tone.AudioNode);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.BufferSource.defaults = {\n\t 'onended': Tone.noOp,\n\t 'onload': Tone.noOp,\n\t 'loop': false,\n\t 'loopStart': 0,\n\t 'loopEnd': 0,\n\t 'fadeIn': 0,\n\t 'fadeOut': 0,\n\t 'curve': 'linear',\n\t 'playbackRate': 1\n\t };\n\t /**\n\t\t * Returns the playback state of the source, either \"started\" or \"stopped\".\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.BufferSource#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.BufferSource.prototype, 'state', {\n\t get: function () {\n\t return this.getStateAtTime(this.now());\n\t }\n\t });\n\t /**\n\t\t * Get the playback state at the given time\n\t\t * @param {Time} time The time to test the state at\n\t\t * @return {Tone.State} The playback state. \n\t\t */\n\t Tone.BufferSource.prototype.getStateAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t if (this._startTime !== -1 && time >= this._startTime && !this._sourceStopped) {\n\t return Tone.State.Started;\n\t } else {\n\t return Tone.State.Stopped;\n\t }\n\t };\n\t /**\n\t\t * Start the buffer\n\t\t * @param {Time} [startTime=now] When the player should start.\n\t\t * @param {Time} [offset=0] The offset from the beginning of the sample\n\t\t * to start at.\n\t\t * @param {Time=} duration How long the sample should play. If no duration\n\t\t * is given, it will default to the full length\n\t\t * of the sample (minus any offset)\n\t\t * @param {Gain} [gain=1] The gain to play the buffer back at.\n\t\t * @param {Time=} fadeInTime The optional fadeIn ramp time.\n\t\t * @return {Tone.BufferSource} this\n\t\t */\n\t Tone.BufferSource.prototype.start = function (time, offset, duration, gain, fadeInTime) {\n\t if (this._startTime !== -1) {\n\t throw new Error('Tone.BufferSource can only be started once.');\n\t }\n\t if (!this.buffer.loaded) {\n\t throw new Error('Tone.BufferSource: buffer is either not set or not loaded.');\n\t }\n\t time = this.toSeconds(time);\n\t //if it's a loop the default offset is the loopstart point\n\t if (this.loop) {\n\t offset = Tone.defaultArg(offset, this.loopStart);\n\t } else {\n\t //otherwise the default offset is 0\n\t offset = Tone.defaultArg(offset, 0);\n\t }\n\t offset = this.toSeconds(offset);\n\t gain = Tone.defaultArg(gain, 1);\n\t this._gain = gain;\n\t fadeInTime = this.toSeconds(Tone.defaultArg(fadeInTime, this.fadeIn));\n\t this.fadeIn = fadeInTime;\n\t if (fadeInTime > 0) {\n\t this._gainNode.gain.setValueAtTime(0, time);\n\t if (this.curve === 'linear') {\n\t this._gainNode.gain.linearRampToValueAtTime(this._gain, time + fadeInTime);\n\t } else {\n\t this._gainNode.gain.exponentialApproachValueAtTime(this._gain, time, fadeInTime);\n\t }\n\t } else {\n\t this._gainNode.gain.setValueAtTime(gain, time);\n\t }\n\t this._startTime = time;\n\t var computedDur = this.toSeconds(Tone.defaultArg(duration, this.buffer.duration - offset % this.buffer.duration));\n\t computedDur = Math.max(computedDur, 0);\n\t if (Tone.isDefined(duration)) {\n\t //clip the duration when not looping\n\t if (!this.loop) {\n\t computedDur = Math.min(computedDur, this.buffer.duration - offset % this.buffer.duration);\n\t }\n\t this.stop(time + computedDur, this.fadeOut);\n\t }\n\t //start the buffer source\n\t if (this.loop) {\n\t //modify the offset if it's greater than the loop time\n\t var loopEnd = this.loopEnd || this.buffer.duration;\n\t var loopStart = this.loopStart;\n\t var loopDuration = loopEnd - loopStart;\n\t //move the offset back\n\t if (offset >= loopEnd) {\n\t offset = (offset - loopStart) % loopDuration + loopStart;\n\t }\n\t }\n\t this._source.buffer = this.buffer.get();\n\t this._source.loopEnd = this.loopEnd || this.buffer.duration;\n\t if (offset < this.buffer.duration) {\n\t this._sourceStarted = true;\n\t this._source.start(time, offset);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Stop the buffer. Optionally add a ramp time to fade the\n\t\t * buffer out.\n\t\t * @param {Time=} time The time the buffer should stop.\n\t\t * @param {Time=} fadeOutTime How long the gain should fade out for\n\t\t * @return {Tone.BufferSource} this\n\t\t */\n\t Tone.BufferSource.prototype.stop = function (time, fadeOutTime) {\n\t if (!this.buffer.loaded) {\n\t throw new Error('Tone.BufferSource: buffer is either not set or not loaded.');\n\t }\n\t if (this._sourceStopped) {\n\t return;\n\t }\n\t time = this.toSeconds(time);\n\t //if the event has already been scheduled, clear it\n\t if (this._stopTime !== -1) {\n\t this.cancelStop();\n\t }\n\t //stop if it's schedule before the start time\n\t if (time <= this._startTime) {\n\t this._gainNode.gain.cancelScheduledValues(time);\n\t this._gainNode.gain.value = 0;\n\t return this;\n\t }\n\t time = Math.max(this._startTime + this.fadeIn + this.sampleTime, time);\n\t //cancel the previous curve\n\t this._gainNode.gain.cancelScheduledValues(time);\n\t this._stopTime = time;\n\t //the fadeOut time\n\t fadeOutTime = this.toSeconds(Tone.defaultArg(fadeOutTime, this.fadeOut));\n\t var heldDuration = time - this._startTime - this.fadeIn - this.sampleTime;\n\t if (!this.loop) {\n\t //make sure the fade does not go beyond the length of the buffer\n\t heldDuration = Math.min(heldDuration, this.buffer.duration);\n\t }\n\t fadeOutTime = Math.min(heldDuration, fadeOutTime);\n\t var startFade = time - fadeOutTime;\n\t if (fadeOutTime > this.sampleTime) {\n\t this._gainNode.gain.setValueAtTime(this._gain, startFade);\n\t if (this.curve === 'linear') {\n\t this._gainNode.gain.linearRampToValueAtTime(0, time);\n\t } else {\n\t this._gainNode.gain.exponentialApproachValueAtTime(0, startFade, fadeOutTime);\n\t }\n\t } else {\n\t this._gainNode.gain.setValueAtTime(0, time);\n\t }\n\t Tone.context.clearTimeout(this._onendedTimeout);\n\t this._onendedTimeout = Tone.context.setTimeout(this._onended.bind(this), this._stopTime - this.now());\n\t return this;\n\t };\n\t /**\n\t\t * Cancel a scheduled stop event\n\t\t * @return {Tone.BufferSource} this\n\t\t */\n\t Tone.BufferSource.prototype.cancelStop = function () {\n\t if (this._startTime !== -1 && !this._sourceStopped) {\n\t //cancel the stop envelope\n\t var fadeInTime = this.toSeconds(this.fadeIn);\n\t this._gainNode.gain.cancelScheduledValues(this._startTime + fadeInTime + this.sampleTime);\n\t this._gainNode.gain.setValueAtTime(1, Math.max(this.now(), this._startTime + fadeInTime + this.sampleTime));\n\t this.context.clearTimeout(this._onendedTimeout);\n\t this._stopTime = -1;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Internal callback when the buffer is ended.\n\t\t * Invokes `onended` and disposes the node.\n\t\t * @private\n\t\t */\n\t Tone.BufferSource.prototype._onended = function () {\n\t if (!this._sourceStopped) {\n\t this._sourceStopped = true;\n\t //allow additional time for the exponential curve to fully decay\n\t var additionalTail = this.curve === 'exponential' ? this.fadeOut * 2 : 0;\n\t if (this._sourceStarted && this._stopTime !== -1) {\n\t this._source.stop(this._stopTime + additionalTail);\n\t }\n\t this.onended(this);\n\t }\n\t };\n\t /**\n\t\t * If loop is true, the loop will start at this position.\n\t\t * @memberOf Tone.BufferSource#\n\t\t * @type {Time}\n\t\t * @name loopStart\n\t\t */\n\t Object.defineProperty(Tone.BufferSource.prototype, 'loopStart', {\n\t get: function () {\n\t return this._source.loopStart;\n\t },\n\t set: function (loopStart) {\n\t this._source.loopStart = this.toSeconds(loopStart);\n\t }\n\t });\n\t /**\n\t\t * If loop is true, the loop will end at this position.\n\t\t * @memberOf Tone.BufferSource#\n\t\t * @type {Time}\n\t\t * @name loopEnd\n\t\t */\n\t Object.defineProperty(Tone.BufferSource.prototype, 'loopEnd', {\n\t get: function () {\n\t return this._source.loopEnd;\n\t },\n\t set: function (loopEnd) {\n\t this._source.loopEnd = this.toSeconds(loopEnd);\n\t }\n\t });\n\t /**\n\t\t * The audio buffer belonging to the player.\n\t\t * @memberOf Tone.BufferSource#\n\t\t * @type {Tone.Buffer}\n\t\t * @name buffer\n\t\t */\n\t Object.defineProperty(Tone.BufferSource.prototype, 'buffer', {\n\t get: function () {\n\t return this._buffer;\n\t },\n\t set: function (buffer) {\n\t this._buffer.set(buffer);\n\t }\n\t });\n\t /**\n\t\t * If the buffer should loop once it's over.\n\t\t * @memberOf Tone.BufferSource#\n\t\t * @type {Boolean}\n\t\t * @name loop\n\t\t */\n\t Object.defineProperty(Tone.BufferSource.prototype, 'loop', {\n\t get: function () {\n\t return this._source.loop;\n\t },\n\t set: function (loop) {\n\t this._source.loop = loop;\n\t this.cancelStop();\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.BufferSource} this\n\t\t */\n\t Tone.BufferSource.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.onended = null;\n\t this._source.onended = null;\n\t this._source.disconnect();\n\t this._source = null;\n\t this._gainNode.dispose();\n\t this._gainNode = null;\n\t this._buffer.dispose();\n\t this._buffer = null;\n\t this._startTime = -1;\n\t this.playbackRate = null;\n\t Tone.context.clearTimeout(this._onendedTimeout);\n\t return this;\n\t };\n\t return Tone.BufferSource;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Noise is a noise generator. It uses looped noise buffers to save on performance.\n\t\t * Tone.Noise supports the noise types: \"pink\", \"white\", and \"brown\". Read more about\n\t\t * colors of noise on [Wikipedia](https://en.wikipedia.org/wiki/Colors_of_noise).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Source}\n\t\t * @param {string} type the noise type (white|pink|brown)\n\t\t * @example\n\t\t * //initialize the noise and start\n\t\t * var noise = new Tone.Noise(\"pink\").start();\n\t\t *\n\t\t * //make an autofilter to shape the noise\n\t\t * var autoFilter = new Tone.AutoFilter({\n\t\t * \t\"frequency\" : \"8m\",\n\t\t * \t\"min\" : 800,\n\t\t * \t\"max\" : 15000\n\t\t * }).connect(Tone.Master);\n\t\t *\n\t\t * //connect the noise\n\t\t * noise.connect(autoFilter);\n\t\t * //start the autofilter LFO\n\t\t * autoFilter.start()\n\t\t */\n\t Tone.Noise = function () {\n\t var options = Tone.defaults(arguments, ['type'], Tone.Noise);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * @private\n\t\t\t * @type {AudioBufferSourceNode}\n\t\t\t */\n\t this._source = null;\n\t /**\n\t\t\t * the buffer\n\t\t\t * @private\n\t\t\t * @type {AudioBuffer}\n\t\t\t */\n\t this._type = options.type;\n\t /**\n\t\t\t * The playback rate of the noise. Affects\n\t\t\t * the \"frequency\" of the noise.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this._playbackRate = options.playbackRate;\n\t };\n\t Tone.extend(Tone.Noise, Tone.Source);\n\t /**\n\t\t * the default parameters\n\t\t *\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Noise.defaults = {\n\t 'type': 'white',\n\t 'playbackRate': 1\n\t };\n\t /**\n\t\t * The type of the noise. Can be \"white\", \"brown\", or \"pink\".\n\t\t * @memberOf Tone.Noise#\n\t\t * @type {string}\n\t\t * @name type\n\t\t * @example\n\t\t * noise.type = \"white\";\n\t\t */\n\t Object.defineProperty(Tone.Noise.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t if (this._type !== type) {\n\t if (type in _noiseBuffers) {\n\t this._type = type;\n\t //if it's playing, stop and restart it\n\t if (this.state === Tone.State.Started) {\n\t var now = this.now();\n\t this._stop(now);\n\t this._start(now);\n\t }\n\t } else {\n\t throw new TypeError('Tone.Noise: invalid type: ' + type);\n\t }\n\t }\n\t }\n\t });\n\t /**\n\t\t * The playback rate of the noise. Affects\n\t\t * the \"frequency\" of the noise.\n\t\t * @type {Positive}\n\t\t * @signal\n\t\t */\n\t Object.defineProperty(Tone.Noise.prototype, 'playbackRate', {\n\t get: function () {\n\t return this._playbackRate;\n\t },\n\t set: function (rate) {\n\t this._playbackRate = rate;\n\t if (this._source) {\n\t this._source.playbackRate.value = rate;\n\t }\n\t }\n\t });\n\t /**\n\t\t * internal start method\n\t\t *\n\t\t * @param {Time} time\n\t\t * @private\n\t\t */\n\t Tone.Noise.prototype._start = function (time) {\n\t var buffer = _noiseBuffers[this._type];\n\t this._source = new Tone.BufferSource(buffer).connect(this.output);\n\t this._source.loop = true;\n\t this._source.playbackRate.value = this._playbackRate;\n\t this._source.start(this.toSeconds(time), Math.random() * (buffer.duration - 0.001));\n\t };\n\t /**\n\t\t * internal stop method\n\t\t *\n\t\t * @param {Time} time\n\t\t * @private\n\t\t */\n\t Tone.Noise.prototype._stop = function (time) {\n\t if (this._source) {\n\t this._source.stop(this.toSeconds(time));\n\t this._source = null;\n\t }\n\t };\n\t /**\n\t\t * Restarts the noise.\n\t\t * @param {[type]} time [description]\n\t\t * @return {[type]} [description]\n\t\t */\n\t Tone.Noise.prototype.restart = function (time) {\n\t //TODO could be optimized by cancelling the buffer source 'stop'\n\t //stop and restart\n\t this._stop(time);\n\t this._start(time);\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Noise} this\n\t\t */\n\t Tone.Noise.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t if (this._source !== null) {\n\t this._source.disconnect();\n\t this._source = null;\n\t }\n\t this._buffer = null;\n\t return this;\n\t };\n\t ///////////////////////////////////////////////////////////////////////////\n\t // THE BUFFERS\n\t ///////////////////////////////////////////////////////////////////////////\n\t //Noise buffer stats\n\t var bufferLength = 44100 * 5;\n\t var channels = 2;\n\t /**\n\t\t *\tThe noise arrays. Generated on initialization.\n\t\t * borrowed heavily from https://github.com/zacharydenton/noise.js\n\t\t * (c) 2013 Zach Denton (MIT)\n\t\t * @static\n\t\t * @private\n\t\t * @type {Array}\n\t\t */\n\t var _noiseArrays = {\n\t 'pink': function () {\n\t var buffer = [];\n\t for (var channelNum = 0; channelNum < channels; channelNum++) {\n\t var channel = new Float32Array(bufferLength);\n\t buffer[channelNum] = channel;\n\t var b0, b1, b2, b3, b4, b5, b6;\n\t b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0;\n\t for (var i = 0; i < bufferLength; i++) {\n\t var white = Math.random() * 2 - 1;\n\t b0 = 0.99886 * b0 + white * 0.0555179;\n\t b1 = 0.99332 * b1 + white * 0.0750759;\n\t b2 = 0.969 * b2 + white * 0.153852;\n\t b3 = 0.8665 * b3 + white * 0.3104856;\n\t b4 = 0.55 * b4 + white * 0.5329522;\n\t b5 = -0.7616 * b5 - white * 0.016898;\n\t channel[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;\n\t channel[i] *= 0.11;\n\t // (roughly) compensate for gain\n\t b6 = white * 0.115926;\n\t }\n\t }\n\t return buffer;\n\t }(),\n\t 'brown': function () {\n\t var buffer = [];\n\t for (var channelNum = 0; channelNum < channels; channelNum++) {\n\t var channel = new Float32Array(bufferLength);\n\t buffer[channelNum] = channel;\n\t var lastOut = 0;\n\t for (var i = 0; i < bufferLength; i++) {\n\t var white = Math.random() * 2 - 1;\n\t channel[i] = (lastOut + 0.02 * white) / 1.02;\n\t lastOut = channel[i];\n\t channel[i] *= 3.5; // (roughly) compensate for gain\n\t }\n\t }\n\t return buffer;\n\t }(),\n\t 'white': function () {\n\t var buffer = [];\n\t for (var channelNum = 0; channelNum < channels; channelNum++) {\n\t var channel = new Float32Array(bufferLength);\n\t buffer[channelNum] = channel;\n\t for (var i = 0; i < bufferLength; i++) {\n\t channel[i] = Math.random() * 2 - 1;\n\t }\n\t }\n\t return buffer;\n\t }()\n\t };\n\t /**\n\t\t *\tstatic noise buffers\n\t\t * @static\n\t\t * @private\n\t\t * @type {Tone.Buffer}\n\t\t */\n\t var _noiseBuffers = {};\n\t //create the Tone.Buffers\n\t function createBuffers() {\n\t for (var type in _noiseArrays) {\n\t _noiseBuffers[type] = new Tone.Buffer().fromArray(_noiseArrays[type]);\n\t }\n\t }\n\t //create the noise buffers\n\t Tone.getContext(createBuffers);\n\t Tone.Context.on('init', createBuffers);\n\t return Tone.Noise;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Simple convolution created with decaying noise.\n\t\t * \t\tGenerates an Impulse Response Buffer\n\t\t * \t\t\twith Tone.Offline then feeds the IR into ConvolverNode.\n\t\t * \t\t\tNote: the Reverb will not make any sound until [generate](#generate)\n\t\t * \t\t\thas been invoked and resolved.\n\t\t *\n\t\t * \t\t\tInspiration from [ReverbGen](https://github.com/adelespinasse/reverbGen).\n\t\t * \t\t\tCopyright (c) 2014 Alan deLespinasse Apache 2.0 License.\n\t\t *\n\t\t * @extends {Tone.Convolver}\n\t\t * @param {Time=} decay The amount of time it will reverberate for.\n\t\t */\n\t Tone.Reverb = function () {\n\t var options = Tone.defaults(arguments, ['decay'], Tone.Reverb);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * Convolver node\n\t\t\t * @type {ConvolverNode}\n\t\t\t * @private\n\t\t\t */\n\t this._convolver = this.context.createConvolver();\n\t /**\n\t\t\t * The duration of the reverb\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.decay = options.decay;\n\t /**\n\t\t\t * The amount of time before the reverb is fully\n\t\t\t * ramped in.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.preDelay = options.preDelay;\n\t this.connectEffect(this._convolver);\n\t };\n\t Tone.extend(Tone.Reverb, Tone.Effect);\n\t /**\n\t\t * The defaults\n\t\t * @type {Object}\n\t\t * @static\n\t\t */\n\t Tone.Reverb.defaults = {\n\t 'decay': 1.5,\n\t 'preDelay': 0.01\n\t };\n\t /**\n\t\t * Generate the Impulse Response. Returns a promise while the IR is being\n\t\t * generated.\n\t\t * @return {Promise<Tone.Reverb>} Promise which returns this object.\n\t\t */\n\t Tone.Reverb.prototype.generate = function () {\n\t return Tone.Offline(function () {\n\t //create a noise burst which decays over the duration\n\t var noiseL = new Tone.Noise();\n\t var noiseR = new Tone.Noise();\n\t var merge = new Tone.Merge();\n\t noiseL.connect(merge.left);\n\t noiseR.connect(merge.right);\n\t var gainNode = new Tone.Gain().toMaster();\n\t merge.connect(gainNode);\n\t noiseL.start(0);\n\t noiseR.start(0);\n\t //short fade in\n\t gainNode.gain.setValueAtTime(0, 0);\n\t gainNode.gain.linearRampToValueAtTime(1, this.preDelay);\n\t //decay\n\t gainNode.gain.exponentialApproachValueAtTime(0, this.preDelay, this.decay - this.preDelay);\n\t }.bind(this), this.decay).then(function (buffer) {\n\t this._convolver.buffer = buffer.get();\n\t return this;\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Reverb} this\n\t\t */\n\t Tone.Reverb.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._convolver.disconnect();\n\t this._convolver = null;\n\t return this;\n\t };\n\t return Tone.Reverb;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Base class for stereo feedback effects where the effectReturn\n\t\t * is fed back into the same channel.\n\t\t *\n\t\t *\t@constructor\n\t\t *\t@extends {Tone.StereoEffect}\n\t\t */\n\t Tone.StereoFeedbackEffect = function () {\n\t var options = Tone.defaults(arguments, ['feedback'], Tone.FeedbackEffect);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * controls the amount of feedback\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.feedback = new Tone.Signal(options.feedback, Tone.Type.NormalRange);\n\t /**\n\t\t\t * the left side feeback\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackL = new Tone.Gain();\n\t /**\n\t\t\t * the right side feeback\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._feedbackR = new Tone.Gain();\n\t //connect it up\n\t this.effectReturnL.chain(this._feedbackL, this.effectSendL);\n\t this.effectReturnR.chain(this._feedbackR, this.effectSendR);\n\t this.feedback.fan(this._feedbackL.gain, this._feedbackR.gain);\n\t this._readOnly(['feedback']);\n\t };\n\t Tone.extend(Tone.StereoFeedbackEffect, Tone.StereoEffect);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.StereoFeedbackEffect} this\n\t\t */\n\t Tone.StereoFeedbackEffect.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t this._writable(['feedback']);\n\t this.feedback.dispose();\n\t this.feedback = null;\n\t this._feedbackL.dispose();\n\t this._feedbackL = null;\n\t this._feedbackR.dispose();\n\t this._feedbackR = null;\n\t return this;\n\t };\n\t return Tone.StereoFeedbackEffect;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Applies a width factor to the mid/side seperation.\n\t\t * 0 is all mid and 1 is all side.\n\t\t * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587).\n\t\t * <br><br>\n\t\t * <code>\n\t\t * Mid *= 2*(1-width)<br>\n\t\t * Side *= 2*width\n\t\t * </code>\n\t\t *\n\t\t * @extends {Tone.MidSideEffect}\n\t\t * @constructor\n\t\t * @param {NormalRange|Object} [width] The stereo width. A width of 0 is mono and 1 is stereo. 0.5 is no change.\n\t\t */\n\t Tone.StereoWidener = function () {\n\t var options = Tone.defaults(arguments, ['width'], Tone.StereoWidener);\n\t Tone.MidSideEffect.call(this, options);\n\t /**\n\t\t\t * The width control. 0 = 100% mid. 1 = 100% side. 0.5 = no change.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.width = new Tone.Signal(options.width, Tone.Type.NormalRange);\n\t this._readOnly(['width']);\n\t /**\n\t\t\t * Two times the (1-width) for the mid channel\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._twoTimesWidthMid = new Tone.Multiply(2);\n\t /**\n\t\t\t * Two times the width for the side channel\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._twoTimesWidthSide = new Tone.Multiply(2);\n\t /**\n\t\t\t * Mid multiplier\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._midMult = new Tone.Multiply();\n\t this._twoTimesWidthMid.connect(this._midMult, 0, 1);\n\t this.midSend.chain(this._midMult, this.midReturn);\n\t /**\n\t\t\t * 1 - width\n\t\t\t * @type {Tone}\n\t\t\t */\n\t this._oneMinusWidth = new Tone.Subtract();\n\t this._oneMinusWidth.connect(this._twoTimesWidthMid);\n\t this.context.getConstant(1).connect(this._oneMinusWidth, 0, 0);\n\t this.width.connect(this._oneMinusWidth, 0, 1);\n\t /**\n\t\t\t * Side multiplier\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._sideMult = new Tone.Multiply();\n\t this.width.connect(this._twoTimesWidthSide);\n\t this._twoTimesWidthSide.connect(this._sideMult, 0, 1);\n\t this.sideSend.chain(this._sideMult, this.sideReturn);\n\t };\n\t Tone.extend(Tone.StereoWidener, Tone.MidSideEffect);\n\t /**\n\t\t * the default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.StereoWidener.defaults = { 'width': 0.5 };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.StereoWidener} this\n\t\t */\n\t Tone.StereoWidener.prototype.dispose = function () {\n\t Tone.MidSideEffect.prototype.dispose.call(this);\n\t this._writable(['width']);\n\t this.width.dispose();\n\t this.width = null;\n\t this._midMult.dispose();\n\t this._midMult = null;\n\t this._sideMult.dispose();\n\t this._sideMult = null;\n\t this._twoTimesWidthMid.dispose();\n\t this._twoTimesWidthMid = null;\n\t this._twoTimesWidthSide.dispose();\n\t this._twoTimesWidthSide = null;\n\t this._oneMinusWidth.dispose();\n\t this._oneMinusWidth = null;\n\t return this;\n\t };\n\t return Tone.StereoWidener;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Tremolo modulates the amplitude of an incoming signal using a Tone.LFO.\n\t\t * The type, frequency, and depth of the LFO is controllable.\n\t\t *\n\t\t * @extends {Tone.StereoEffect}\n\t\t * @constructor\n\t\t * @param {Frequency} [frequency] The rate of the effect.\n\t\t * @param {NormalRange} [depth] The depth of the effect.\n\t\t * @example\n\t\t * //create a tremolo and start it's LFO\n\t\t * var tremolo = new Tone.Tremolo(9, 0.75).toMaster().start();\n\t\t * //route an oscillator through the tremolo and start it\n\t\t * var oscillator = new Tone.Oscillator().connect(tremolo).start();\n\t\t */\n\t Tone.Tremolo = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'depth'\n\t ], Tone.Tremolo);\n\t Tone.StereoEffect.call(this, options);\n\t /**\n\t\t\t * The tremelo LFO in the left channel\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoL = new Tone.LFO({\n\t 'phase': options.spread,\n\t 'min': 1,\n\t 'max': 0\n\t });\n\t /**\n\t\t\t * The tremelo LFO in the left channel\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfoR = new Tone.LFO({\n\t 'phase': options.spread,\n\t 'min': 1,\n\t 'max': 0\n\t });\n\t /**\n\t\t\t * Where the gain is multiplied\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._amplitudeL = new Tone.Gain();\n\t /**\n\t\t\t * Where the gain is multiplied\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._amplitudeR = new Tone.Gain();\n\t /**\n\t\t\t * The frequency of the tremolo.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The depth of the effect. A depth of 0, has no effect\n\t\t\t * on the amplitude, and a depth of 1 makes the amplitude\n\t\t\t * modulate fully between 0 and 1.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.depth = new Tone.Signal(options.depth, Tone.Type.NormalRange);\n\t this._readOnly([\n\t 'frequency',\n\t 'depth'\n\t ]);\n\t this.effectSendL.chain(this._amplitudeL, this.effectReturnL);\n\t this.effectSendR.chain(this._amplitudeR, this.effectReturnR);\n\t this._lfoL.connect(this._amplitudeL.gain);\n\t this._lfoR.connect(this._amplitudeR.gain);\n\t this.frequency.fan(this._lfoL.frequency, this._lfoR.frequency);\n\t this.depth.fan(this._lfoR.amplitude, this._lfoL.amplitude);\n\t this.type = options.type;\n\t this.spread = options.spread;\n\t };\n\t Tone.extend(Tone.Tremolo, Tone.StereoEffect);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Tremolo.defaults = {\n\t 'frequency': 10,\n\t 'type': 'sine',\n\t 'depth': 0.5,\n\t 'spread': 180\n\t };\n\t /**\n\t\t * Start the tremolo.\n\t\t * @param {Time} [time=now] When the tremolo begins.\n\t\t * @returns {Tone.Tremolo} this\n\t\t */\n\t Tone.Tremolo.prototype.start = function (time) {\n\t this._lfoL.start(time);\n\t this._lfoR.start(time);\n\t return this;\n\t };\n\t /**\n\t\t * Stop the tremolo.\n\t\t * @param {Time} [time=now] When the tremolo stops.\n\t\t * @returns {Tone.Tremolo} this\n\t\t */\n\t Tone.Tremolo.prototype.stop = function (time) {\n\t this._lfoL.stop(time);\n\t this._lfoR.stop(time);\n\t return this;\n\t };\n\t /**\n\t\t * Sync the effect to the transport.\n\t\t * @param {Time} [delay=0] Delay time before starting the effect after the\n\t\t * Transport has started.\n\t\t * @returns {Tone.AutoFilter} this\n\t\t */\n\t Tone.Tremolo.prototype.sync = function (delay) {\n\t this._lfoL.sync(delay);\n\t this._lfoR.sync(delay);\n\t Tone.Transport.syncSignal(this.frequency);\n\t return this;\n\t };\n\t /**\n\t\t * Unsync the filter from the transport\n\t\t * @returns {Tone.Tremolo} this\n\t\t */\n\t Tone.Tremolo.prototype.unsync = function () {\n\t this._lfoL.unsync();\n\t this._lfoR.unsync();\n\t Tone.Transport.unsyncSignal(this.frequency);\n\t return this;\n\t };\n\t /**\n\t\t * The Tremolo's oscillator type.\n\t\t * @memberOf Tone.Tremolo#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.Tremolo.prototype, 'type', {\n\t get: function () {\n\t return this._lfoL.type;\n\t },\n\t set: function (type) {\n\t this._lfoL.type = type;\n\t this._lfoR.type = type;\n\t }\n\t });\n\t /**\n\t\t * Amount of stereo spread. When set to 0, both LFO's will be panned centrally.\n\t\t * When set to 180, LFO's will be panned hard left and right respectively.\n\t\t * @memberOf Tone.Tremolo#\n\t\t * @type {Degrees}\n\t\t * @name spread\n\t\t */\n\t Object.defineProperty(Tone.Tremolo.prototype, 'spread', {\n\t get: function () {\n\t return this._lfoR.phase - this._lfoL.phase; //180\n\t },\n\t set: function (spread) {\n\t this._lfoL.phase = 90 - spread / 2;\n\t this._lfoR.phase = spread / 2 + 90;\n\t }\n\t });\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Tremolo} this\n\t\t */\n\t Tone.Tremolo.prototype.dispose = function () {\n\t Tone.StereoEffect.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'depth'\n\t ]);\n\t this._lfoL.dispose();\n\t this._lfoL = null;\n\t this._lfoR.dispose();\n\t this._lfoR = null;\n\t this._amplitudeL.dispose();\n\t this._amplitudeL = null;\n\t this._amplitudeR.dispose();\n\t this._amplitudeR = null;\n\t this.frequency = null;\n\t this.depth = null;\n\t return this;\n\t };\n\t return Tone.Tremolo;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A Vibrato effect composed of a Tone.Delay and a Tone.LFO. The LFO\n\t\t * modulates the delayTime of the delay, causing the pitch to rise\n\t\t * and fall. \n\t\t * @extends {Tone.Effect}\n\t\t * @param {Frequency} frequency The frequency of the vibrato.\n\t\t * @param {NormalRange} depth The amount the pitch is modulated.\n\t\t */\n\t Tone.Vibrato = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'depth'\n\t ], Tone.Vibrato);\n\t Tone.Effect.call(this, options);\n\t /**\n\t\t\t * The delay node used for the vibrato effect\n\t\t\t * @type {Tone.Delay}\n\t\t\t * @private\n\t\t\t */\n\t this._delayNode = new Tone.Delay(0, options.maxDelay);\n\t /**\n\t\t\t * The LFO used to control the vibrato\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._lfo = new Tone.LFO({\n\t 'type': options.type,\n\t 'min': 0,\n\t 'max': options.maxDelay,\n\t 'frequency': options.frequency,\n\t 'phase': -90 //offse the phase so the resting position is in the center\n\t }).start().connect(this._delayNode.delayTime);\n\t /**\n\t\t\t * The frequency of the vibrato\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._lfo.frequency;\n\t /**\n\t\t\t * The depth of the vibrato. \n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.depth = this._lfo.amplitude;\n\t this.depth.value = options.depth;\n\t this._readOnly([\n\t 'frequency',\n\t 'depth'\n\t ]);\n\t this.effectSend.chain(this._delayNode, this.effectReturn);\n\t };\n\t Tone.extend(Tone.Vibrato, Tone.Effect);\n\t /**\n\t\t * The defaults\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Vibrato.defaults = {\n\t 'maxDelay': 0.005,\n\t 'frequency': 5,\n\t 'depth': 0.1,\n\t 'type': 'sine'\n\t };\n\t /**\n\t\t * Type of oscillator attached to the Vibrato.\n\t\t * @memberOf Tone.Vibrato#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.Vibrato.prototype, 'type', {\n\t get: function () {\n\t return this._lfo.type;\n\t },\n\t set: function (type) {\n\t this._lfo.type = type;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.Vibrato} this\n\t\t */\n\t Tone.Vibrato.prototype.dispose = function () {\n\t Tone.Effect.prototype.dispose.call(this);\n\t this._delayNode.dispose();\n\t this._delayNode = null;\n\t this._lfo.dispose();\n\t this._lfo = null;\n\t this._writable([\n\t 'frequency',\n\t 'depth'\n\t ]);\n\t this.frequency = null;\n\t this.depth = null;\n\t };\n\t return Tone.Vibrato;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Event abstracts away Tone.Transport.schedule and provides a schedulable\n\t\t * callback for a single or repeatable events along the timeline.\n\t\t *\n\t\t * @extends {Tone}\n\t\t * @param {function} callback The callback to invoke at the time.\n\t\t * @param {*} value The value or values which should be passed to\n\t\t * the callback function on invocation.\n\t\t * @example\n\t\t * var chord = new Tone.Event(function(time, chord){\n\t\t * \t//the chord as well as the exact time of the event\n\t\t * \t//are passed in as arguments to the callback function\n\t\t * }, [\"D4\", \"E4\", \"F4\"]);\n\t\t * //start the chord at the beginning of the transport timeline\n\t\t * chord.start();\n\t\t * //loop it every measure for 8 measures\n\t\t * chord.loop = 8;\n\t\t * chord.loopEnd = \"1m\";\n\t\t */\n\t Tone.Event = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'callback',\n\t 'value'\n\t ], Tone.Event);\n\t Tone.call(this);\n\t /**\n\t\t\t * Loop value\n\t\t\t * @type {Boolean|Positive}\n\t\t\t * @private\n\t\t\t */\n\t this._loop = options.loop;\n\t /**\n\t\t\t * The callback to invoke.\n\t\t\t * @type {Function}\n\t\t\t */\n\t this.callback = options.callback;\n\t /**\n\t\t\t * The value which is passed to the\n\t\t\t * callback function.\n\t\t\t * @type {*}\n\t\t\t * @private\n\t\t\t */\n\t this.value = options.value;\n\t /**\n\t\t\t * When the note is scheduled to start.\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._loopStart = this.toTicks(options.loopStart);\n\t /**\n\t\t\t * When the note is scheduled to start.\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._loopEnd = this.toTicks(options.loopEnd);\n\t /**\n\t\t\t * Tracks the scheduled events\n\t\t\t * @type {Tone.TimelineState}\n\t\t\t * @private\n\t\t\t */\n\t this._state = new Tone.TimelineState(Tone.State.Stopped);\n\t /**\n\t\t\t * The playback speed of the note. A speed of 1\n\t\t\t * is no change.\n\t\t\t * @private\n\t\t\t * @type {Positive}\n\t\t\t */\n\t this._playbackRate = 1;\n\t /**\n\t\t\t * A delay time from when the event is scheduled to start\n\t\t\t * @type {Ticks}\n\t\t\t * @private\n\t\t\t */\n\t this._startOffset = 0;\n\t /**\n\t\t\t * private holder of probability value\n\t\t\t * @type {NormalRange}\n\t\t\t * @private\n\t\t\t */\n\t this._probability = options.probability;\n\t /**\n\t\t\t * the amount of variation from the\n\t\t\t * given time.\n\t\t\t * @type {Boolean|Time}\n\t\t\t * @private\n\t\t\t */\n\t this._humanize = options.humanize;\n\t /**\n\t\t\t * If mute is true, the callback won't be\n\t\t\t * invoked.\n\t\t\t * @type {Boolean}\n\t\t\t */\n\t this.mute = options.mute;\n\t //set the initial values\n\t this.playbackRate = options.playbackRate;\n\t };\n\t Tone.extend(Tone.Event);\n\t /**\n\t\t * The default values\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Event.defaults = {\n\t 'callback': Tone.noOp,\n\t 'loop': false,\n\t 'loopEnd': '1m',\n\t 'loopStart': 0,\n\t 'playbackRate': 1,\n\t 'value': null,\n\t 'probability': 1,\n\t 'mute': false,\n\t 'humanize': false\n\t };\n\t /**\n\t\t * Reschedule all of the events along the timeline\n\t\t * with the updated values.\n\t\t * @param {Time} after Only reschedules events after the given time.\n\t\t * @return {Tone.Event} this\n\t\t * @private\n\t\t */\n\t Tone.Event.prototype._rescheduleEvents = function (after) {\n\t //if no argument is given, schedules all of the events\n\t after = Tone.defaultArg(after, -1);\n\t this._state.forEachFrom(after, function (event) {\n\t var duration;\n\t if (event.state === Tone.State.Started) {\n\t if (Tone.isDefined(event.id)) {\n\t Tone.Transport.clear(event.id);\n\t }\n\t var startTick = event.time + Math.round(this.startOffset / this._playbackRate);\n\t if (this._loop) {\n\t duration = Infinity;\n\t if (Tone.isNumber(this._loop)) {\n\t duration = this._loop * this._getLoopDuration();\n\t }\n\t var nextEvent = this._state.getAfter(startTick);\n\t if (nextEvent !== null) {\n\t duration = Math.min(duration, nextEvent.time - startTick);\n\t }\n\t if (duration !== Infinity) {\n\t //schedule a stop since it's finite duration\n\t this._state.setStateAtTime(Tone.State.Stopped, startTick + duration + 1);\n\t duration = Tone.Ticks(duration);\n\t }\n\t var interval = Tone.Ticks(this._getLoopDuration());\n\t event.id = Tone.Transport.scheduleRepeat(this._tick.bind(this), interval, Tone.Ticks(startTick), duration);\n\t } else {\n\t event.id = Tone.Transport.schedule(this._tick.bind(this), Tone.Ticks(startTick));\n\t }\n\t }\n\t }.bind(this));\n\t return this;\n\t };\n\t /**\n\t\t * Returns the playback state of the note, either \"started\" or \"stopped\".\n\t\t * @type {String}\n\t\t * @readOnly\n\t\t * @memberOf Tone.Event#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'state', {\n\t get: function () {\n\t return this._state.getValueAtTime(Tone.Transport.ticks);\n\t }\n\t });\n\t /**\n\t\t * The start from the scheduled start time\n\t\t * @type {Ticks}\n\t\t * @memberOf Tone.Event#\n\t\t * @name startOffset\n\t\t * @private\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'startOffset', {\n\t get: function () {\n\t return this._startOffset;\n\t },\n\t set: function (offset) {\n\t this._startOffset = offset;\n\t }\n\t });\n\t /**\n\t\t * The probability of the notes being triggered.\n\t\t * @memberOf Tone.Event#\n\t\t * @type {NormalRange}\n\t\t * @name probability\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'probability', {\n\t get: function () {\n\t return this._probability;\n\t },\n\t set: function (prob) {\n\t this._probability = prob;\n\t }\n\t });\n\t /**\n\t\t * If set to true, will apply small random variation\n\t\t * to the callback time. If the value is given as a time, it will randomize\n\t\t * by that amount.\n\t\t * @example\n\t\t * event.humanize = true;\n\t\t * @type {Boolean|Time}\n\t\t * @name humanize\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'humanize', {\n\t get: function () {\n\t return this._humanize;\n\t },\n\t set: function (variation) {\n\t this._humanize = variation;\n\t }\n\t });\n\t /**\n\t\t * Start the note at the given time.\n\t\t * @param {TimelinePosition} time When the note should start.\n\t\t * @return {Tone.Event} this\n\t\t */\n\t Tone.Event.prototype.start = function (time) {\n\t time = this.toTicks(time);\n\t if (this._state.getValueAtTime(time) === Tone.State.Stopped) {\n\t this._state.add({\n\t 'state': Tone.State.Started,\n\t 'time': time,\n\t 'id': undefined\n\t });\n\t this._rescheduleEvents(time);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Stop the Event at the given time.\n\t\t * @param {TimelinePosition} time When the note should stop.\n\t\t * @return {Tone.Event} this\n\t\t */\n\t Tone.Event.prototype.stop = function (time) {\n\t this.cancel(time);\n\t time = this.toTicks(time);\n\t if (this._state.getValueAtTime(time) === Tone.State.Started) {\n\t this._state.setStateAtTime(Tone.State.Stopped, time);\n\t var previousEvent = this._state.getBefore(time);\n\t var reschedulTime = time;\n\t if (previousEvent !== null) {\n\t reschedulTime = previousEvent.time;\n\t }\n\t this._rescheduleEvents(reschedulTime);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Cancel all scheduled events greater than or equal to the given time\n\t\t * @param {TimelinePosition} [time=0] The time after which events will be cancel.\n\t\t * @return {Tone.Event} this\n\t\t */\n\t Tone.Event.prototype.cancel = function (time) {\n\t time = Tone.defaultArg(time, -Infinity);\n\t time = this.toTicks(time);\n\t this._state.forEachFrom(time, function (event) {\n\t Tone.Transport.clear(event.id);\n\t });\n\t this._state.cancel(time);\n\t return this;\n\t };\n\t /**\n\t\t * The callback function invoker. Also\n\t\t * checks if the Event is done playing\n\t\t * @param {Number} time The time of the event in seconds\n\t\t * @private\n\t\t */\n\t Tone.Event.prototype._tick = function (time) {\n\t var ticks = Tone.Transport.getTicksAtTime(time);\n\t if (!this.mute && this._state.getValueAtTime(ticks) === Tone.State.Started) {\n\t if (this.probability < 1 && Math.random() > this.probability) {\n\t return;\n\t }\n\t if (this.humanize) {\n\t var variation = 0.02;\n\t if (!Tone.isBoolean(this.humanize)) {\n\t variation = this.toSeconds(this.humanize);\n\t }\n\t time += (Math.random() * 2 - 1) * variation;\n\t }\n\t this.callback(time, this.value);\n\t }\n\t };\n\t /**\n\t\t * Get the duration of the loop.\n\t\t * @return {Ticks}\n\t\t * @private\n\t\t */\n\t Tone.Event.prototype._getLoopDuration = function () {\n\t return Math.round((this._loopEnd - this._loopStart) / this._playbackRate);\n\t };\n\t /**\n\t\t * If the note should loop or not\n\t\t * between Tone.Event.loopStart and\n\t\t * Tone.Event.loopEnd. An integer\n\t\t * value corresponds to the number of\n\t\t * loops the Event does after it starts.\n\t\t * @memberOf Tone.Event#\n\t\t * @type {Boolean|Positive}\n\t\t * @name loop\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'loop', {\n\t get: function () {\n\t return this._loop;\n\t },\n\t set: function (loop) {\n\t this._loop = loop;\n\t this._rescheduleEvents();\n\t }\n\t });\n\t /**\n\t\t * \tThe playback rate of the note. Defaults to 1.\n\t\t * @memberOf Tone.Event#\n\t\t * @type {Positive}\n\t\t * @name playbackRate\n\t\t * @example\n\t\t * note.loop = true;\n\t\t * //repeat the note twice as fast\n\t\t * note.playbackRate = 2;\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'playbackRate', {\n\t get: function () {\n\t return this._playbackRate;\n\t },\n\t set: function (rate) {\n\t this._playbackRate = rate;\n\t this._rescheduleEvents();\n\t }\n\t });\n\t /**\n\t\t * The loopEnd point is the time the event will loop\n\t\t * if Tone.Event.loop is true.\n\t\t * @memberOf Tone.Event#\n\t\t * @type {Time}\n\t\t * @name loopEnd\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'loopEnd', {\n\t get: function () {\n\t return Tone.Ticks(this._loopEnd).toSeconds();\n\t },\n\t set: function (loopEnd) {\n\t this._loopEnd = this.toTicks(loopEnd);\n\t if (this._loop) {\n\t this._rescheduleEvents();\n\t }\n\t }\n\t });\n\t /**\n\t\t * The time when the loop should start.\n\t\t * @memberOf Tone.Event#\n\t\t * @type {Time}\n\t\t * @name loopStart\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'loopStart', {\n\t get: function () {\n\t return Tone.Ticks(this._loopStart).toSeconds();\n\t },\n\t set: function (loopStart) {\n\t this._loopStart = this.toTicks(loopStart);\n\t if (this._loop) {\n\t this._rescheduleEvents();\n\t }\n\t }\n\t });\n\t /**\n\t\t * The current progress of the loop interval.\n\t\t * Returns 0 if the event is not started yet or\n\t\t * it is not set to loop.\n\t\t * @memberOf Tone.Event#\n\t\t * @type {NormalRange}\n\t\t * @name progress\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Event.prototype, 'progress', {\n\t get: function () {\n\t if (this._loop) {\n\t var ticks = Tone.Transport.ticks;\n\t var lastEvent = this._state.get(ticks);\n\t if (lastEvent !== null && lastEvent.state === Tone.State.Started) {\n\t var loopDuration = this._getLoopDuration();\n\t var progress = (ticks - lastEvent.time) % loopDuration;\n\t return progress / loopDuration;\n\t } else {\n\t return 0;\n\t }\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Event} this\n\t\t */\n\t Tone.Event.prototype.dispose = function () {\n\t this.cancel();\n\t this._state.dispose();\n\t this._state = null;\n\t this.callback = null;\n\t this.value = null;\n\t };\n\t return Tone.Event;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Loop creates a looped callback at the \n\t\t * specified interval. The callback can be \n\t\t * started, stopped and scheduled along\n\t\t * the Transport's timeline. \n\t\t * @example\n\t\t * var loop = new Tone.Loop(function(time){\n\t\t * \t//triggered every eighth note. \n\t\t * \tconsole.log(time);\n\t\t * }, \"8n\").start(0);\n\t\t * Tone.Transport.start();\n\t\t * @extends {Tone}\n\t\t * @param {Function} callback The callback to invoke with the event.\n\t\t * @param {Time} interval The time between successive callback calls. \n\t\t */\n\t Tone.Loop = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'callback',\n\t 'interval'\n\t ], Tone.Loop);\n\t Tone.call(this);\n\t /**\n\t\t\t * The event which produces the callbacks\n\t\t\t */\n\t this._event = new Tone.Event({\n\t 'callback': this._tick.bind(this),\n\t 'loop': true,\n\t 'loopEnd': options.interval,\n\t 'playbackRate': options.playbackRate,\n\t 'probability': options.probability\n\t });\n\t /**\n\t\t\t * The callback to invoke with the next event in the pattern\n\t\t\t * @type {Function}\n\t\t\t */\n\t this.callback = options.callback;\n\t //set the iterations\n\t this.iterations = options.iterations;\n\t };\n\t Tone.extend(Tone.Loop);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Loop.defaults = {\n\t 'interval': '4n',\n\t 'callback': Tone.noOp,\n\t 'playbackRate': 1,\n\t 'iterations': Infinity,\n\t 'probability': true,\n\t 'mute': false\n\t };\n\t /**\n\t\t * Start the loop at the specified time along the Transport's\n\t\t * timeline.\n\t\t * @param {TimelinePosition=} time When to start the Loop.\n\t\t * @return {Tone.Loop} this\n\t\t */\n\t Tone.Loop.prototype.start = function (time) {\n\t this._event.start(time);\n\t return this;\n\t };\n\t /**\n\t\t * Stop the loop at the given time.\n\t\t * @param {TimelinePosition=} time When to stop the Arpeggio\n\t\t * @return {Tone.Loop} this\n\t\t */\n\t Tone.Loop.prototype.stop = function (time) {\n\t this._event.stop(time);\n\t return this;\n\t };\n\t /**\n\t\t * Cancel all scheduled events greater than or equal to the given time\n\t\t * @param {TimelinePosition} [time=0] The time after which events will be cancel.\n\t\t * @return {Tone.Loop} this\n\t\t */\n\t Tone.Loop.prototype.cancel = function (time) {\n\t this._event.cancel(time);\n\t return this;\n\t };\n\t /**\n\t\t * Internal function called when the notes should be called\n\t\t * @param {Number} time The time the event occurs\n\t\t * @private\n\t\t */\n\t Tone.Loop.prototype._tick = function (time) {\n\t this.callback(time);\n\t };\n\t /**\n\t\t * The state of the Loop, either started or stopped.\n\t\t * @memberOf Tone.Loop#\n\t\t * @type {String}\n\t\t * @name state\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'state', {\n\t get: function () {\n\t return this._event.state;\n\t }\n\t });\n\t /**\n\t\t * The progress of the loop as a value between 0-1. 0, when\n\t\t * the loop is stopped or done iterating. \n\t\t * @memberOf Tone.Loop#\n\t\t * @type {NormalRange}\n\t\t * @name progress\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'progress', {\n\t get: function () {\n\t return this._event.progress;\n\t }\n\t });\n\t /**\n\t\t * The time between successive callbacks. \n\t\t * @example\n\t\t * loop.interval = \"8n\"; //loop every 8n\n\t\t * @memberOf Tone.Loop#\n\t\t * @type {Time}\n\t\t * @name interval\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'interval', {\n\t get: function () {\n\t return this._event.loopEnd;\n\t },\n\t set: function (interval) {\n\t this._event.loopEnd = interval;\n\t }\n\t });\n\t /**\n\t\t * The playback rate of the loop. The normal playback rate is 1 (no change). \n\t\t * A `playbackRate` of 2 would be twice as fast. \n\t\t * @memberOf Tone.Loop#\n\t\t * @type {Time}\n\t\t * @name playbackRate\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'playbackRate', {\n\t get: function () {\n\t return this._event.playbackRate;\n\t },\n\t set: function (rate) {\n\t this._event.playbackRate = rate;\n\t }\n\t });\n\t /**\n\t\t * Random variation +/-0.01s to the scheduled time. \n\t\t * Or give it a time value which it will randomize by.\n\t\t * @type {Boolean|Time}\n\t\t * @memberOf Tone.Loop#\n\t\t * @name humanize\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'humanize', {\n\t get: function () {\n\t return this._event.humanize;\n\t },\n\t set: function (variation) {\n\t this._event.humanize = variation;\n\t }\n\t });\n\t /**\n\t\t * The probably of the callback being invoked.\n\t\t * @memberOf Tone.Loop#\n\t\t * @type {NormalRange}\n\t\t * @name probability\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'probability', {\n\t get: function () {\n\t return this._event.probability;\n\t },\n\t set: function (prob) {\n\t this._event.probability = prob;\n\t }\n\t });\n\t /**\n\t\t * Muting the Loop means that no callbacks are invoked.\n\t\t * @memberOf Tone.Loop#\n\t\t * @type {Boolean}\n\t\t * @name mute\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'mute', {\n\t get: function () {\n\t return this._event.mute;\n\t },\n\t set: function (mute) {\n\t this._event.mute = mute;\n\t }\n\t });\n\t /**\n\t\t * The number of iterations of the loop. The default\n\t\t * value is Infinity (loop forever).\n\t\t * @memberOf Tone.Loop#\n\t\t * @type {Positive}\n\t\t * @name iterations\n\t\t */\n\t Object.defineProperty(Tone.Loop.prototype, 'iterations', {\n\t get: function () {\n\t if (this._event.loop === true) {\n\t return Infinity;\n\t } else {\n\t return this._event.loop;\n\t }\n\t },\n\t set: function (iters) {\n\t if (iters === Infinity) {\n\t this._event.loop = true;\n\t } else {\n\t this._event.loop = iters;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Loop} this\n\t\t */\n\t Tone.Loop.prototype.dispose = function () {\n\t this._event.dispose();\n\t this._event = null;\n\t this.callback = null;\n\t };\n\t return Tone.Loop;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Part is a collection Tone.Events which can be\n\t\t * started/stopped and looped as a single unit.\n\t\t *\n\t\t * @extends {Tone.Event}\n\t\t * @param {Function} callback The callback to invoke on each event\n\t\t * @param {Array} events the array of events\n\t\t * @example\n\t\t * var part = new Tone.Part(function(time, note){\n\t\t * \t//the notes given as the second element in the array\n\t\t * \t//will be passed in as the second argument\n\t\t * \tsynth.triggerAttackRelease(note, \"8n\", time);\n\t\t * }, [[0, \"C2\"], [\"0:2\", \"C3\"], [\"0:3:2\", \"G2\"]]);\n\t\t * @example\n\t\t * //use an array of objects as long as the object has a \"time\" attribute\n\t\t * var part = new Tone.Part(function(time, value){\n\t\t * \t//the value is an object which contains both the note and the velocity\n\t\t * \tsynth.triggerAttackRelease(value.note, \"8n\", time, value.velocity);\n\t\t * }, [{\"time\" : 0, \"note\" : \"C3\", \"velocity\": 0.9},\n\t\t * \t {\"time\" : \"0:2\", \"note\" : \"C4\", \"velocity\": 0.5}\n\t\t * ]).start(0);\n\t\t */\n\t Tone.Part = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'callback',\n\t 'events'\n\t ], Tone.Part);\n\t Tone.Event.call(this, options);\n\t /**\n\t\t\t * An array of Objects.\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._events = [];\n\t //add the events\n\t for (var i = 0; i < options.events.length; i++) {\n\t if (Array.isArray(options.events[i])) {\n\t this.add(options.events[i][0], options.events[i][1]);\n\t } else {\n\t this.add(options.events[i]);\n\t }\n\t }\n\t };\n\t Tone.extend(Tone.Part, Tone.Event);\n\t /**\n\t\t * The default values\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.Part.defaults = {\n\t 'callback': Tone.noOp,\n\t 'loop': false,\n\t 'loopEnd': '1m',\n\t 'loopStart': 0,\n\t 'playbackRate': 1,\n\t 'probability': 1,\n\t 'humanize': false,\n\t 'mute': false,\n\t 'events': []\n\t };\n\t /**\n\t\t * Start the part at the given time.\n\t\t * @param {TransportTime} time When to start the part.\n\t\t * @param {Time=} offset The offset from the start of the part\n\t\t * to begin playing at.\n\t\t * @return {Tone.Part} this\n\t\t */\n\t Tone.Part.prototype.start = function (time, offset) {\n\t var ticks = this.toTicks(time);\n\t if (this._state.getValueAtTime(ticks) !== Tone.State.Started) {\n\t if (this._loop) {\n\t offset = Tone.defaultArg(offset, this._loopStart);\n\t } else {\n\t offset = Tone.defaultArg(offset, 0);\n\t }\n\t offset = this.toTicks(offset);\n\t this._state.add({\n\t 'state': Tone.State.Started,\n\t 'time': ticks,\n\t 'offset': offset\n\t });\n\t this._forEach(function (event) {\n\t this._startNote(event, ticks, offset);\n\t });\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Start the event in the given event at the correct time given\n\t\t * the ticks and offset and looping.\n\t\t * @param {Tone.Event} event\n\t\t * @param {Ticks} ticks\n\t\t * @param {Ticks} offset\n\t\t * @private\n\t\t */\n\t Tone.Part.prototype._startNote = function (event, ticks, offset) {\n\t ticks -= offset;\n\t if (this._loop) {\n\t if (event.startOffset >= this._loopStart && event.startOffset < this._loopEnd) {\n\t if (event.startOffset < offset) {\n\t //start it on the next loop\n\t ticks += this._getLoopDuration();\n\t }\n\t event.start(Tone.Ticks(ticks));\n\t } else if (event.startOffset < this._loopStart && event.startOffset >= offset) {\n\t event.loop = false;\n\t event.start(Tone.Ticks(ticks));\n\t }\n\t } else if (event.startOffset >= offset) {\n\t event.start(Tone.Ticks(ticks));\n\t }\n\t };\n\t /**\n\t\t * The start from the scheduled start time\n\t\t * @type {Ticks}\n\t\t * @memberOf Tone.Part#\n\t\t * @name startOffset\n\t\t * @private\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'startOffset', {\n\t get: function () {\n\t return this._startOffset;\n\t },\n\t set: function (offset) {\n\t this._startOffset = offset;\n\t this._forEach(function (event) {\n\t event.startOffset += this._startOffset;\n\t });\n\t }\n\t });\n\t /**\n\t\t * Stop the part at the given time.\n\t\t * @param {TimelinePosition} time When to stop the part.\n\t\t * @return {Tone.Part} this\n\t\t */\n\t Tone.Part.prototype.stop = function (time) {\n\t var ticks = this.toTicks(time);\n\t this._state.cancel(ticks);\n\t this._state.setStateAtTime(Tone.State.Stopped, ticks);\n\t this._forEach(function (event) {\n\t event.stop(time);\n\t });\n\t return this;\n\t };\n\t /**\n\t\t * Get/Set an Event's value at the given time.\n\t\t * If a value is passed in and no event exists at\n\t\t * the given time, one will be created with that value.\n\t\t * If two events are at the same time, the first one will\n\t\t * be returned.\n\t\t * @example\n\t\t * part.at(\"1m\"); //returns the part at the first measure\n\t\t *\n\t\t * part.at(\"2m\", \"C2\"); //set the value at \"2m\" to C2.\n\t\t * //if an event didn't exist at that time, it will be created.\n\t\t * @param {TransportTime} time The time of the event to get or set.\n\t\t * @param {*=} value If a value is passed in, the value of the\n\t\t * event at the given time will be set to it.\n\t\t * @return {Tone.Event} the event at the time\n\t\t */\n\t Tone.Part.prototype.at = function (time, value) {\n\t time = Tone.TransportTime(time);\n\t var tickTime = Tone.Ticks(1).toSeconds();\n\t for (var i = 0; i < this._events.length; i++) {\n\t var event = this._events[i];\n\t if (Math.abs(time.toTicks() - event.startOffset) < tickTime) {\n\t if (Tone.isDefined(value)) {\n\t event.value = value;\n\t }\n\t return event;\n\t }\n\t }\n\t //if there was no event at that time, create one\n\t if (Tone.isDefined(value)) {\n\t this.add(time, value);\n\t //return the new event\n\t return this._events[this._events.length - 1];\n\t } else {\n\t return null;\n\t }\n\t };\n\t /**\n\t\t * Add a an event to the part.\n\t\t * @param {Time} time The time the note should start.\n\t\t * If an object is passed in, it should\n\t\t * have a 'time' attribute and the rest\n\t\t * of the object will be used as the 'value'.\n\t\t * @param {Tone.Event|*} value\n\t\t * @returns {Tone.Part} this\n\t\t * @example\n\t\t * part.add(\"1m\", \"C#+11\");\n\t\t */\n\t Tone.Part.prototype.add = function (time, value) {\n\t //extract the parameters\n\t if (time.hasOwnProperty('time')) {\n\t value = time;\n\t time = value.time;\n\t }\n\t time = this.toTicks(time);\n\t var event;\n\t if (value instanceof Tone.Event) {\n\t event = value;\n\t event.callback = this._tick.bind(this);\n\t } else {\n\t event = new Tone.Event({\n\t 'callback': this._tick.bind(this),\n\t 'value': value\n\t });\n\t }\n\t //the start offset\n\t event.startOffset = time;\n\t //initialize the values\n\t event.set({\n\t 'loopEnd': this.loopEnd,\n\t 'loopStart': this.loopStart,\n\t 'loop': this.loop,\n\t 'humanize': this.humanize,\n\t 'playbackRate': this.playbackRate,\n\t 'probability': this.probability\n\t });\n\t this._events.push(event);\n\t //start the note if it should be played right now\n\t this._restartEvent(event);\n\t return this;\n\t };\n\t /**\n\t\t * Restart the given event\n\t\t * @param {Tone.Event} event\n\t\t * @private\n\t\t */\n\t Tone.Part.prototype._restartEvent = function (event) {\n\t this._state.forEach(function (stateEvent) {\n\t if (stateEvent.state === Tone.State.Started) {\n\t this._startNote(event, stateEvent.time, stateEvent.offset);\n\t } else {\n\t //stop the note\n\t event.stop(Tone.Ticks(stateEvent.time));\n\t }\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Remove an event from the part. Will recursively iterate\n\t\t * into nested parts to find the event.\n\t\t * @param {Time} time The time of the event\n\t\t * @param {*} value Optionally select only a specific event value\n\t\t * @return {Tone.Part} this\n\t\t */\n\t Tone.Part.prototype.remove = function (time, value) {\n\t //extract the parameters\n\t if (time.hasOwnProperty('time')) {\n\t value = time;\n\t time = value.time;\n\t }\n\t time = this.toTicks(time);\n\t for (var i = this._events.length - 1; i >= 0; i--) {\n\t var event = this._events[i];\n\t if (event instanceof Tone.Part) {\n\t event.remove(time, value);\n\t } else if (event.startOffset === time) {\n\t if (Tone.isUndef(value) || Tone.isDefined(value) && event.value === value) {\n\t this._events.splice(i, 1);\n\t event.dispose();\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Remove all of the notes from the group.\n\t\t * @return {Tone.Part} this\n\t\t */\n\t Tone.Part.prototype.removeAll = function () {\n\t this._forEach(function (event) {\n\t event.dispose();\n\t });\n\t this._events = [];\n\t return this;\n\t };\n\t /**\n\t\t * Cancel scheduled state change events: i.e. \"start\" and \"stop\".\n\t\t * @param {TimelinePosition} after The time after which to cancel the scheduled events.\n\t\t * @return {Tone.Part} this\n\t\t */\n\t Tone.Part.prototype.cancel = function (after) {\n\t this._forEach(function (event) {\n\t event.cancel(after);\n\t });\n\t this._state.cancel(this.toTicks(after));\n\t return this;\n\t };\n\t /**\n\t\t * Iterate over all of the events\n\t\t * @param {Function} callback\n\t\t * @param {Object} ctx The context\n\t\t * @private\n\t\t */\n\t Tone.Part.prototype._forEach = function (callback, ctx) {\n\t if (this._events) {\n\t ctx = Tone.defaultArg(ctx, this);\n\t for (var i = this._events.length - 1; i >= 0; i--) {\n\t var e = this._events[i];\n\t if (e instanceof Tone.Part) {\n\t e._forEach(callback, ctx);\n\t } else {\n\t callback.call(ctx, e);\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Set the attribute of all of the events\n\t\t * @param {String} attr the attribute to set\n\t\t * @param {*} value The value to set it to\n\t\t * @private\n\t\t */\n\t Tone.Part.prototype._setAll = function (attr, value) {\n\t this._forEach(function (event) {\n\t event[attr] = value;\n\t });\n\t };\n\t /**\n\t\t * Internal tick method\n\t\t * @param {Number} time The time of the event in seconds\n\t\t * @private\n\t\t */\n\t Tone.Part.prototype._tick = function (time, value) {\n\t if (!this.mute) {\n\t this.callback(time, value);\n\t }\n\t };\n\t /**\n\t\t * Determine if the event should be currently looping\n\t\t * given the loop boundries of this Part.\n\t\t * @param {Tone.Event} event The event to test\n\t\t * @private\n\t\t */\n\t Tone.Part.prototype._testLoopBoundries = function (event) {\n\t if (event.startOffset < this._loopStart || event.startOffset >= this._loopEnd) {\n\t event.cancel(0);\n\t } else if (event.state === Tone.State.Stopped) {\n\t //reschedule it if it's stopped\n\t this._restartEvent(event);\n\t }\n\t };\n\t /**\n\t\t * The probability of the notes being triggered.\n\t\t * @memberOf Tone.Part#\n\t\t * @type {NormalRange}\n\t\t * @name probability\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'probability', {\n\t get: function () {\n\t return this._probability;\n\t },\n\t set: function (prob) {\n\t this._probability = prob;\n\t this._setAll('probability', prob);\n\t }\n\t });\n\t /**\n\t\t * If set to true, will apply small random variation\n\t\t * to the callback time. If the value is given as a time, it will randomize\n\t\t * by that amount.\n\t\t * @example\n\t\t * event.humanize = true;\n\t\t * @type {Boolean|Time}\n\t\t * @name humanize\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'humanize', {\n\t get: function () {\n\t return this._humanize;\n\t },\n\t set: function (variation) {\n\t this._humanize = variation;\n\t this._setAll('humanize', variation);\n\t }\n\t });\n\t /**\n\t\t * If the part should loop or not\n\t\t * between Tone.Part.loopStart and\n\t\t * Tone.Part.loopEnd. An integer\n\t\t * value corresponds to the number of\n\t\t * loops the Part does after it starts.\n\t\t * @memberOf Tone.Part#\n\t\t * @type {Boolean|Positive}\n\t\t * @name loop\n\t\t * @example\n\t\t * //loop the part 8 times\n\t\t * part.loop = 8;\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'loop', {\n\t get: function () {\n\t return this._loop;\n\t },\n\t set: function (loop) {\n\t this._loop = loop;\n\t this._forEach(function (event) {\n\t event._loopStart = this._loopStart;\n\t event._loopEnd = this._loopEnd;\n\t event.loop = loop;\n\t this._testLoopBoundries(event);\n\t });\n\t }\n\t });\n\t /**\n\t\t * The loopEnd point determines when it will\n\t\t * loop if Tone.Part.loop is true.\n\t\t * @memberOf Tone.Part#\n\t\t * @type {Time}\n\t\t * @name loopEnd\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'loopEnd', {\n\t get: function () {\n\t return Tone.Ticks(this._loopEnd).toSeconds();\n\t },\n\t set: function (loopEnd) {\n\t this._loopEnd = this.toTicks(loopEnd);\n\t if (this._loop) {\n\t this._forEach(function (event) {\n\t event.loopEnd = loopEnd;\n\t this._testLoopBoundries(event);\n\t });\n\t }\n\t }\n\t });\n\t /**\n\t\t * The loopStart point determines when it will\n\t\t * loop if Tone.Part.loop is true.\n\t\t * @memberOf Tone.Part#\n\t\t * @type {Time}\n\t\t * @name loopStart\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'loopStart', {\n\t get: function () {\n\t return Tone.Ticks(this._loopStart).toSeconds();\n\t },\n\t set: function (loopStart) {\n\t this._loopStart = this.toTicks(loopStart);\n\t if (this._loop) {\n\t this._forEach(function (event) {\n\t event.loopStart = this.loopStart;\n\t this._testLoopBoundries(event);\n\t });\n\t }\n\t }\n\t });\n\t /**\n\t\t * \tThe playback rate of the part\n\t\t * @memberOf Tone.Part#\n\t\t * @type {Positive}\n\t\t * @name playbackRate\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'playbackRate', {\n\t get: function () {\n\t return this._playbackRate;\n\t },\n\t set: function (rate) {\n\t this._playbackRate = rate;\n\t this._setAll('playbackRate', rate);\n\t }\n\t });\n\t /**\n\t\t * \tThe number of scheduled notes in the part.\n\t\t * @memberOf Tone.Part#\n\t\t * @type {Positive}\n\t\t * @name length\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Part.prototype, 'length', {\n\t get: function () {\n\t return this._events.length;\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Part} this\n\t\t */\n\t Tone.Part.prototype.dispose = function () {\n\t this.removeAll();\n\t this._state.dispose();\n\t this._state = null;\n\t this.callback = null;\n\t this._events = null;\n\t return this;\n\t };\n\t return Tone.Part;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Pattern arpeggiates between the given notes\n\t\t * in a number of patterns. See Tone.CtrlPattern for\n\t\t * a full list of patterns.\n\t\t * @example\n\t\t * var pattern = new Tone.Pattern(function(time, note){\n\t\t * //the order of the notes passed in depends on the pattern\n\t\t * }, [\"C2\", \"D4\", \"E5\", \"A6\"], \"upDown\");\n\t\t * @extends {Tone.Loop}\n\t\t * @param {Function} callback The callback to invoke with the\n\t\t * event.\n\t\t * @param {Array} values The values to arpeggiate over.\n\t\t */\n\t Tone.Pattern = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'callback',\n\t 'values',\n\t 'pattern'\n\t ], Tone.Pattern);\n\t Tone.Loop.call(this, options);\n\t /**\n\t\t\t * The pattern manager\n\t\t\t * @type {Tone.CtrlPattern}\n\t\t\t * @private\n\t\t\t */\n\t this._pattern = new Tone.CtrlPattern({\n\t 'values': options.values,\n\t 'type': options.pattern,\n\t 'index': options.index\n\t });\n\t };\n\t Tone.extend(Tone.Pattern, Tone.Loop);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Pattern.defaults = {\n\t 'pattern': Tone.CtrlPattern.Type.Up,\n\t 'callback': Tone.noOp,\n\t 'values': []\n\t };\n\t /**\n\t\t * Internal function called when the notes should be called\n\t\t * @param {Number} time The time the event occurs\n\t\t * @private\n\t\t */\n\t Tone.Pattern.prototype._tick = function (time) {\n\t this.callback(time, this._pattern.value);\n\t this._pattern.next();\n\t };\n\t /**\n\t\t * The current index in the values array.\n\t\t * @memberOf Tone.Pattern#\n\t\t * @type {Positive}\n\t\t * @name index\n\t\t */\n\t Object.defineProperty(Tone.Pattern.prototype, 'index', {\n\t get: function () {\n\t return this._pattern.index;\n\t },\n\t set: function (i) {\n\t this._pattern.index = i;\n\t }\n\t });\n\t /**\n\t\t * The array of events.\n\t\t * @memberOf Tone.Pattern#\n\t\t * @type {Array}\n\t\t * @name values\n\t\t */\n\t Object.defineProperty(Tone.Pattern.prototype, 'values', {\n\t get: function () {\n\t return this._pattern.values;\n\t },\n\t set: function (vals) {\n\t this._pattern.values = vals;\n\t }\n\t });\n\t /**\n\t\t * The current value of the pattern.\n\t\t * @memberOf Tone.Pattern#\n\t\t * @type {*}\n\t\t * @name value\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Pattern.prototype, 'value', {\n\t get: function () {\n\t return this._pattern.value;\n\t }\n\t });\n\t /**\n\t\t * The pattern type. See Tone.CtrlPattern for the full list of patterns.\n\t\t * @memberOf Tone.Pattern#\n\t\t * @type {String}\n\t\t * @name pattern\n\t\t */\n\t Object.defineProperty(Tone.Pattern.prototype, 'pattern', {\n\t get: function () {\n\t return this._pattern.type;\n\t },\n\t set: function (pattern) {\n\t this._pattern.type = pattern;\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Pattern} this\n\t\t */\n\t Tone.Pattern.prototype.dispose = function () {\n\t Tone.Loop.prototype.dispose.call(this);\n\t this._pattern.dispose();\n\t this._pattern = null;\n\t };\n\t return Tone.Pattern;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class A sequence is an alternate notation of a part. Instead\n\t\t * of passing in an array of [time, event] pairs, pass\n\t\t * in an array of events which will be spaced at the\n\t\t * given subdivision. Sub-arrays will subdivide that beat\n\t\t * by the number of items are in the array.\n\t\t * Sequence notation inspiration from [Tidal](http://yaxu.org/tidal/)\n\t\t * @param {Function} callback The callback to invoke with every note\n\t\t * @param {Array} events The sequence\n\t\t * @param {Time} subdivision The subdivision between which events are placed.\n\t\t * @extends {Tone.Part}\n\t\t * @example\n\t\t * var seq = new Tone.Sequence(function(time, note){\n\t\t * \tconsole.log(note);\n\t\t * //straight quater notes\n\t\t * }, [\"C4\", \"E4\", \"G4\", \"A4\"], \"4n\");\n\t\t * @example\n\t\t * var seq = new Tone.Sequence(function(time, note){\n\t\t * \tconsole.log(note);\n\t\t * //subdivisions are given as subarrays\n\t\t * }, [\"C4\", [\"E4\", \"D4\", \"E4\"], \"G4\", [\"A4\", \"G4\"]]);\n\t\t */\n\t Tone.Sequence = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'callback',\n\t 'events',\n\t 'subdivision'\n\t ], Tone.Sequence);\n\t //remove the events\n\t var events = options.events;\n\t delete options.events;\n\t Tone.Part.call(this, options);\n\t /**\n\t\t\t * The subdivison of each note\n\t\t\t * @type {Ticks}\n\t\t\t * @private\n\t\t\t */\n\t this._subdivision = this.toTicks(options.subdivision);\n\t //if no time was passed in, the loop end is the end of the cycle\n\t if (Tone.isUndef(options.loopEnd) && Tone.isDefined(events)) {\n\t this._loopEnd = events.length * this._subdivision;\n\t }\n\t //defaults to looping\n\t this._loop = true;\n\t //add all of the events\n\t if (Tone.isDefined(events)) {\n\t for (var i = 0; i < events.length; i++) {\n\t this.add(i, events[i]);\n\t }\n\t }\n\t };\n\t Tone.extend(Tone.Sequence, Tone.Part);\n\t /**\n\t\t * The default values.\n\t\t * @type {Object}\n\t\t */\n\t Tone.Sequence.defaults = { 'subdivision': '4n' };\n\t /**\n\t\t * The subdivision of the sequence. This can only be\n\t\t * set in the constructor. The subdivision is the\n\t\t * interval between successive steps.\n\t\t * @type {Time}\n\t\t * @memberOf Tone.Sequence#\n\t\t * @name subdivision\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Sequence.prototype, 'subdivision', {\n\t get: function () {\n\t return Tone.Ticks(this._subdivision).toSeconds();\n\t }\n\t });\n\t /**\n\t\t * Get/Set an index of the sequence. If the index contains a subarray,\n\t\t * a Tone.Sequence representing that sub-array will be returned.\n\t\t * @example\n\t\t * var sequence = new Tone.Sequence(playNote, [\"E4\", \"C4\", \"F#4\", [\"A4\", \"Bb3\"]])\n\t\t * sequence.at(0)// => returns \"E4\"\n\t\t * //set a value\n\t\t * sequence.at(0, \"G3\");\n\t\t * //get a nested sequence\n\t\t * sequence.at(3).at(1)// => returns \"Bb3\"\n\t\t * @param {Positive} index The index to get or set\n\t\t * @param {*} value Optionally pass in the value to set at the given index.\n\t\t */\n\t Tone.Sequence.prototype.at = function (index, value) {\n\t //if the value is an array,\n\t if (Tone.isArray(value)) {\n\t //remove the current event at that index\n\t this.remove(index);\n\t }\n\t //call the parent's method\n\t return Tone.Part.prototype.at.call(this, this._indexTime(index), value);\n\t };\n\t /**\n\t\t * Add an event at an index, if there's already something\n\t\t * at that index, overwrite it. If `value` is an array,\n\t\t * it will be parsed as a subsequence.\n\t\t * @param {Number} index The index to add the event to\n\t\t * @param {*} value The value to add at that index\n\t\t * @returns {Tone.Sequence} this\n\t\t */\n\t Tone.Sequence.prototype.add = function (index, value) {\n\t if (value === null) {\n\t return this;\n\t }\n\t if (Tone.isArray(value)) {\n\t //make a subsequence and add that to the sequence\n\t var subSubdivision = Math.round(this._subdivision / value.length);\n\t value = new Tone.Sequence(this._tick.bind(this), value, Tone.Ticks(subSubdivision));\n\t }\n\t Tone.Part.prototype.add.call(this, this._indexTime(index), value);\n\t return this;\n\t };\n\t /**\n\t\t * Remove a value from the sequence by index\n\t\t * @param {Number} index The index of the event to remove\n\t\t * @returns {Tone.Sequence} this\n\t\t */\n\t Tone.Sequence.prototype.remove = function (index, value) {\n\t Tone.Part.prototype.remove.call(this, this._indexTime(index), value);\n\t return this;\n\t };\n\t /**\n\t\t * Get the time of the index given the Sequence's subdivision\n\t\t * @param {Number} index\n\t\t * @return {Time} The time of that index\n\t\t * @private\n\t\t */\n\t Tone.Sequence.prototype._indexTime = function (index) {\n\t if (index instanceof Tone.TransportTime) {\n\t return index;\n\t } else {\n\t return Tone.Ticks(index * this._subdivision + this.startOffset).toSeconds();\n\t }\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.Sequence} this\n\t\t */\n\t Tone.Sequence.prototype.dispose = function () {\n\t Tone.Part.prototype.dispose.call(this);\n\t return this;\n\t };\n\t return Tone.Sequence;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.PulseOscillator is a pulse oscillator with control over pulse width,\n\t\t * also known as the duty cycle. At 50% duty cycle (width = 0.5) the wave is\n\t\t * a square and only odd-numbered harmonics are present. At all other widths\n\t\t * even-numbered harmonics are present. Read more\n\t\t * [here](https://wigglewave.wordpress.com/2014/08/16/pulse-waveforms-and-harmonics/).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Source}\n\t\t * @param {Frequency} [frequency] The frequency of the oscillator\n\t\t * @param {NormalRange} [width] The width of the pulse\n\t\t * @example\n\t\t * var pulse = new Tone.PulseOscillator(\"E5\", 0.4).toMaster().start();\n\t\t */\n\t Tone.PulseOscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'width'\n\t ], Tone.Oscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * The width of the pulse.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.width = new Tone.Signal(options.width, Tone.Type.NormalRange);\n\t /**\n\t\t\t * gate the width amount\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._widthGate = new Tone.Gain();\n\t /**\n\t\t\t * the sawtooth oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._sawtooth = new Tone.Oscillator({\n\t frequency: options.frequency,\n\t detune: options.detune,\n\t type: 'sawtooth',\n\t phase: options.phase\n\t });\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._sawtooth.frequency;\n\t /**\n\t\t\t * The detune in cents.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = this._sawtooth.detune;\n\t /**\n\t\t\t * Threshold the signal to turn it into a square\n\t\t\t * @type {Tone.WaveShaper}\n\t\t\t * @private\n\t\t\t */\n\t this._thresh = new Tone.WaveShaper(function (val) {\n\t if (val < 0) {\n\t return -1;\n\t } else {\n\t return 1;\n\t }\n\t });\n\t //connections\n\t this._sawtooth.chain(this._thresh, this.output);\n\t this.width.chain(this._widthGate, this._thresh);\n\t this._readOnly([\n\t 'width',\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t };\n\t Tone.extend(Tone.PulseOscillator, Tone.Source);\n\t /**\n\t\t * The default parameters.\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.PulseOscillator.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'phase': 0,\n\t 'width': 0.2\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} time\n\t\t * @private\n\t\t */\n\t Tone.PulseOscillator.prototype._start = function (time) {\n\t time = this.toSeconds(time);\n\t this._sawtooth.start(time);\n\t this._widthGate.gain.setValueAtTime(1, time);\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @param {Time} time\n\t\t * @private\n\t\t */\n\t Tone.PulseOscillator.prototype._stop = function (time) {\n\t time = this.toSeconds(time);\n\t this._sawtooth.stop(time);\n\t //the width is still connected to the output.\n\t //that needs to be stopped also\n\t this._widthGate.gain.setValueAtTime(0, time);\n\t };\n\t /**\n\t\t * restart the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.PulseOscillator.prototype.restart = function (time) {\n\t this._sawtooth.restart(time);\n\t };\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.PulseOscillator#\n\t\t * @type {Degrees}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.PulseOscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._sawtooth.phase;\n\t },\n\t set: function (phase) {\n\t this._sawtooth.phase = phase;\n\t }\n\t });\n\t /**\n\t\t * The type of the oscillator. Always returns \"pulse\".\n\t\t * @readOnly\n\t\t * @memberOf Tone.PulseOscillator#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.PulseOscillator.prototype, 'type', {\n\t get: function () {\n\t return 'pulse';\n\t }\n\t });\n\t /**\n\t\t * The partials of the waveform. Cannot set partials for this waveform type\n\t\t * @memberOf Tone.PulseOscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @private\n\t\t */\n\t Object.defineProperty(Tone.PulseOscillator.prototype, 'partials', {\n\t get: function () {\n\t return [];\n\t }\n\t });\n\t /**\n\t\t * Clean up method.\n\t\t * @return {Tone.PulseOscillator} this\n\t\t */\n\t Tone.PulseOscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this._sawtooth.dispose();\n\t this._sawtooth = null;\n\t this._writable([\n\t 'width',\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t this.width.dispose();\n\t this.width = null;\n\t this._widthGate.dispose();\n\t this._widthGate = null;\n\t this._thresh.dispose();\n\t this._thresh = null;\n\t this.frequency = null;\n\t this.detune = null;\n\t return this;\n\t };\n\t return Tone.PulseOscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.PWMOscillator modulates the width of a Tone.PulseOscillator\n\t\t * at the modulationFrequency. This has the effect of continuously\n\t\t * changing the timbre of the oscillator by altering the harmonics\n\t\t * generated.\n\t\t *\n\t\t * @extends {Tone.Source}\n\t\t * @constructor\n\t\t * @param {Frequency} frequency The starting frequency of the oscillator.\n\t\t * @param {Frequency} modulationFrequency The modulation frequency of the width of the pulse.\n\t\t * @example\n\t\t * var pwm = new Tone.PWMOscillator(\"Ab3\", 0.3).toMaster().start();\n\t\t */\n\t Tone.PWMOscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'modulationFrequency'\n\t ], Tone.PWMOscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * the pulse oscillator\n\t\t\t * @type {Tone.PulseOscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._pulse = new Tone.PulseOscillator(options.modulationFrequency);\n\t //change the pulse oscillator type\n\t this._pulse._sawtooth.type = 'sine';\n\t /**\n\t\t\t * the modulator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._modulator = new Tone.Oscillator({\n\t 'frequency': options.frequency,\n\t 'detune': options.detune,\n\t 'phase': options.phase\n\t });\n\t /**\n\t\t\t * Scale the oscillator so it doesn't go silent\n\t\t\t * at the extreme values.\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._scale = new Tone.Multiply(2);\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._modulator.frequency;\n\t /**\n\t\t\t * The detune of the oscillator.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = this._modulator.detune;\n\t /**\n\t\t\t * The modulation rate of the oscillator.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.modulationFrequency = this._pulse.frequency;\n\t //connections\n\t this._modulator.chain(this._scale, this._pulse.width);\n\t this._pulse.connect(this.output);\n\t this._readOnly([\n\t 'modulationFrequency',\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t };\n\t Tone.extend(Tone.PWMOscillator, Tone.Source);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.PWMOscillator.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'phase': 0,\n\t 'modulationFrequency': 0.4\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now]\n\t\t * @private\n\t\t */\n\t Tone.PWMOscillator.prototype._start = function (time) {\n\t time = this.toSeconds(time);\n\t this._modulator.start(time);\n\t this._pulse.start(time);\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.PWMOscillator.prototype._stop = function (time) {\n\t time = this.toSeconds(time);\n\t this._modulator.stop(time);\n\t this._pulse.stop(time);\n\t };\n\t /**\n\t\t * restart the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.PWMOscillator.prototype.restart = function (time) {\n\t this._modulator.restart(time);\n\t this._pulse.restart(time);\n\t };\n\t /**\n\t\t * The type of the oscillator. Always returns \"pwm\".\n\t\t * @readOnly\n\t\t * @memberOf Tone.PWMOscillator#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.PWMOscillator.prototype, 'type', {\n\t get: function () {\n\t return 'pwm';\n\t }\n\t });\n\t /**\n\t\t * The partials of the waveform. Cannot set partials for this waveform type\n\t\t * @memberOf Tone.PWMOscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @private\n\t\t */\n\t Object.defineProperty(Tone.PWMOscillator.prototype, 'partials', {\n\t get: function () {\n\t return [];\n\t }\n\t });\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.PWMOscillator#\n\t\t * @type {number}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.PWMOscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._modulator.phase;\n\t },\n\t set: function (phase) {\n\t this._modulator.phase = phase;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.PWMOscillator} this\n\t\t */\n\t Tone.PWMOscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this._pulse.dispose();\n\t this._pulse = null;\n\t this._scale.dispose();\n\t this._scale = null;\n\t this._modulator.dispose();\n\t this._modulator = null;\n\t this._writable([\n\t 'modulationFrequency',\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t this.frequency = null;\n\t this.detune = null;\n\t this.modulationFrequency = null;\n\t return this;\n\t };\n\t return Tone.PWMOscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.FMOscillator\n\t\t *\n\t\t * @extends {Tone.Source}\n\t\t * @constructor\n\t\t * @param {Frequency} frequency The starting frequency of the oscillator.\n\t\t * @param {String} type The type of the carrier oscillator.\n\t\t * @param {String} modulationType The type of the modulator oscillator.\n\t\t * @example\n\t\t * //a sine oscillator frequency-modulated by a square wave\n\t\t * var fmOsc = new Tone.FMOscillator(\"Ab3\", \"sine\", \"square\").toMaster().start();\n\t\t */\n\t Tone.FMOscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type',\n\t 'modulationType'\n\t ], Tone.FMOscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * The carrier oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._carrier = new Tone.Oscillator(options.frequency, options.type);\n\t /**\n\t\t\t * The oscillator's frequency\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune control signal.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = this._carrier.detune;\n\t this.detune.value = options.detune;\n\t /**\n\t\t\t * The modulation index which is in essence the depth or amount of the modulation. In other terms it is the\n\t\t\t * ratio of the frequency of the modulating signal (mf) to the amplitude of the\n\t\t\t * modulating signal (ma) -- as in ma/mf.\n\t\t\t *\t@type {Positive}\n\t\t\t *\t@signal\n\t\t\t */\n\t this.modulationIndex = new Tone.Multiply(options.modulationIndex);\n\t this.modulationIndex.units = Tone.Type.Positive;\n\t /**\n\t\t\t * The modulating oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._modulator = new Tone.Oscillator(options.frequency, options.modulationType);\n\t /**\n\t\t\t * Harmonicity is the frequency ratio between the carrier and the modulator oscillators.\n\t\t\t * A harmonicity of 1 gives both oscillators the same frequency.\n\t\t\t * Harmonicity = 2 means a change of an octave.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * //pitch the modulator an octave below carrier\n\t\t\t * synth.harmonicity.value = 0.5;\n\t\t\t */\n\t this.harmonicity = new Tone.Multiply(options.harmonicity);\n\t this.harmonicity.units = Tone.Type.Positive;\n\t /**\n\t\t\t * the node where the modulation happens\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._modulationNode = new Tone.Gain(0);\n\t //connections\n\t this.frequency.connect(this._carrier.frequency);\n\t this.frequency.chain(this.harmonicity, this._modulator.frequency);\n\t this.frequency.chain(this.modulationIndex, this._modulationNode);\n\t this._modulator.connect(this._modulationNode.gain);\n\t this._modulationNode.connect(this._carrier.frequency);\n\t this._carrier.connect(this.output);\n\t this.detune.connect(this._modulator.detune);\n\t this.phase = options.phase;\n\t this._readOnly([\n\t 'modulationIndex',\n\t 'frequency',\n\t 'detune',\n\t 'harmonicity'\n\t ]);\n\t };\n\t Tone.extend(Tone.FMOscillator, Tone.Source);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.FMOscillator.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'phase': 0,\n\t 'modulationIndex': 2,\n\t 'modulationType': 'square',\n\t 'harmonicity': 1\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now]\n\t\t * @private\n\t\t */\n\t Tone.FMOscillator.prototype._start = function (time) {\n\t this._modulator.start(time);\n\t this._carrier.start(time);\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.FMOscillator.prototype._stop = function (time) {\n\t this._modulator.stop(time);\n\t this._carrier.stop(time);\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.FMOscillator.prototype.restart = function (time) {\n\t this._modulator.restart(time);\n\t this._carrier.restart(time);\n\t };\n\t /**\n\t\t * The type of the carrier oscillator\n\t\t * @memberOf Tone.FMOscillator#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.FMOscillator.prototype, 'type', {\n\t get: function () {\n\t return this._carrier.type;\n\t },\n\t set: function (type) {\n\t this._carrier.type = type;\n\t }\n\t });\n\t /**\n\t\t * The type of the modulator oscillator\n\t\t * @memberOf Tone.FMOscillator#\n\t\t * @type {String}\n\t\t * @name modulationType\n\t\t */\n\t Object.defineProperty(Tone.FMOscillator.prototype, 'modulationType', {\n\t get: function () {\n\t return this._modulator.type;\n\t },\n\t set: function (type) {\n\t this._modulator.type = type;\n\t }\n\t });\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.FMOscillator#\n\t\t * @type {number}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.FMOscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._carrier.phase;\n\t },\n\t set: function (phase) {\n\t this._carrier.phase = phase;\n\t this._modulator.phase = phase;\n\t }\n\t });\n\t /**\n\t\t * The partials of the carrier waveform. A partial represents\n\t\t * the amplitude at a harmonic. The first harmonic is the\n\t\t * fundamental frequency, the second is the octave and so on\n\t\t * following the harmonic series.\n\t\t * Setting this value will automatically set the type to \"custom\".\n\t\t * The value is an empty array when the type is not \"custom\".\n\t\t * @memberOf Tone.FMOscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @example\n\t\t * osc.partials = [1, 0.2, 0.01];\n\t\t */\n\t Object.defineProperty(Tone.FMOscillator.prototype, 'partials', {\n\t get: function () {\n\t return this._carrier.partials;\n\t },\n\t set: function (partials) {\n\t this._carrier.partials = partials;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.FMOscillator} this\n\t\t */\n\t Tone.FMOscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this._writable([\n\t 'modulationIndex',\n\t 'frequency',\n\t 'detune',\n\t 'harmonicity'\n\t ]);\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this.detune = null;\n\t this.harmonicity.dispose();\n\t this.harmonicity = null;\n\t this._carrier.dispose();\n\t this._carrier = null;\n\t this._modulator.dispose();\n\t this._modulator = null;\n\t this._modulationNode.dispose();\n\t this._modulationNode = null;\n\t this.modulationIndex.dispose();\n\t this.modulationIndex = null;\n\t return this;\n\t };\n\t return Tone.FMOscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.AMOscillator\n\t\t *\n\t\t * @extends {Tone.Oscillator}\n\t\t * @constructor\n\t\t * @param {Frequency} frequency The starting frequency of the oscillator.\n\t\t * @param {String} type The type of the carrier oscillator.\n\t\t * @param {String} modulationType The type of the modulator oscillator.\n\t\t * @example\n\t\t * //a sine oscillator frequency-modulated by a square wave\n\t\t * var fmOsc = new Tone.AMOscillator(\"Ab3\", \"sine\", \"square\").toMaster().start();\n\t\t */\n\t Tone.AMOscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type',\n\t 'modulationType'\n\t ], Tone.AMOscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * The carrier oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._carrier = new Tone.Oscillator(options.frequency, options.type);\n\t /**\n\t\t\t * The oscillator's frequency\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this._carrier.frequency;\n\t /**\n\t\t\t * The detune control signal.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = this._carrier.detune;\n\t this.detune.value = options.detune;\n\t /**\n\t\t\t * The modulating oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._modulator = new Tone.Oscillator(options.frequency, options.modulationType);\n\t /**\n\t\t\t * convert the -1,1 output to 0,1\n\t\t\t * @type {Tone.AudioToGain}\n\t\t\t * @private\n\t\t\t */\n\t this._modulationScale = new Tone.AudioToGain();\n\t /**\n\t\t\t * Harmonicity is the frequency ratio between the carrier and the modulator oscillators.\n\t\t\t * A harmonicity of 1 gives both oscillators the same frequency.\n\t\t\t * Harmonicity = 2 means a change of an octave.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * //pitch the modulator an octave below carrier\n\t\t\t * synth.harmonicity.value = 0.5;\n\t\t\t */\n\t this.harmonicity = new Tone.Multiply(options.harmonicity);\n\t this.harmonicity.units = Tone.Type.Positive;\n\t /**\n\t\t\t * the node where the modulation happens\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._modulationNode = new Tone.Gain(0);\n\t //connections\n\t this.frequency.chain(this.harmonicity, this._modulator.frequency);\n\t this.detune.connect(this._modulator.detune);\n\t this._modulator.chain(this._modulationScale, this._modulationNode.gain);\n\t this._carrier.chain(this._modulationNode, this.output);\n\t this.phase = options.phase;\n\t this._readOnly([\n\t 'frequency',\n\t 'detune',\n\t 'harmonicity'\n\t ]);\n\t };\n\t Tone.extend(Tone.AMOscillator, Tone.Oscillator);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.AMOscillator.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'phase': 0,\n\t 'modulationType': 'square',\n\t 'harmonicity': 1\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now]\n\t\t * @private\n\t\t */\n\t Tone.AMOscillator.prototype._start = function (time) {\n\t this._modulator.start(time);\n\t this._carrier.start(time);\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.AMOscillator.prototype._stop = function (time) {\n\t this._modulator.stop(time);\n\t this._carrier.stop(time);\n\t };\n\t /**\n\t\t * restart the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.AMOscillator.prototype.restart = function (time) {\n\t this._modulator.restart(time);\n\t this._carrier.restart(time);\n\t };\n\t /**\n\t\t * The type of the carrier oscillator\n\t\t * @memberOf Tone.AMOscillator#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.AMOscillator.prototype, 'type', {\n\t get: function () {\n\t return this._carrier.type;\n\t },\n\t set: function (type) {\n\t this._carrier.type = type;\n\t }\n\t });\n\t /**\n\t\t * The type of the modulator oscillator\n\t\t * @memberOf Tone.AMOscillator#\n\t\t * @type {string}\n\t\t * @name modulationType\n\t\t */\n\t Object.defineProperty(Tone.AMOscillator.prototype, 'modulationType', {\n\t get: function () {\n\t return this._modulator.type;\n\t },\n\t set: function (type) {\n\t this._modulator.type = type;\n\t }\n\t });\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.AMOscillator#\n\t\t * @type {number}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.AMOscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._carrier.phase;\n\t },\n\t set: function (phase) {\n\t this._carrier.phase = phase;\n\t this._modulator.phase = phase;\n\t }\n\t });\n\t /**\n\t\t * The partials of the carrier waveform. A partial represents\n\t\t * the amplitude at a harmonic. The first harmonic is the\n\t\t * fundamental frequency, the second is the octave and so on\n\t\t * following the harmonic series.\n\t\t * Setting this value will automatically set the type to \"custom\".\n\t\t * The value is an empty array when the type is not \"custom\".\n\t\t * @memberOf Tone.AMOscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @example\n\t\t * osc.partials = [1, 0.2, 0.01];\n\t\t */\n\t Object.defineProperty(Tone.AMOscillator.prototype, 'partials', {\n\t get: function () {\n\t return this._carrier.partials;\n\t },\n\t set: function (partials) {\n\t this._carrier.partials = partials;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.AMOscillator} this\n\t\t */\n\t Tone.AMOscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'detune',\n\t 'harmonicity'\n\t ]);\n\t this.frequency = null;\n\t this.detune = null;\n\t this.harmonicity.dispose();\n\t this.harmonicity = null;\n\t this._carrier.dispose();\n\t this._carrier = null;\n\t this._modulator.dispose();\n\t this._modulator = null;\n\t this._modulationNode.dispose();\n\t this._modulationNode = null;\n\t this._modulationScale.dispose();\n\t this._modulationScale = null;\n\t return this;\n\t };\n\t return Tone.AMOscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.FatOscillator\n\t\t *\n\t\t * @extends {Tone.Source}\n\t\t * @constructor\n\t\t * @param {Frequency} frequency The starting frequency of the oscillator.\n\t\t * @param {String} type The type of the carrier oscillator.\n\t\t * @param {String} modulationType The type of the modulator oscillator.\n\t\t * @example\n\t\t * //a sine oscillator frequency-modulated by a square wave\n\t\t * var fmOsc = new Tone.FatOscillator(\"Ab3\", \"sine\", \"square\").toMaster().start();\n\t\t */\n\t Tone.FatOscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type',\n\t 'spread'\n\t ], Tone.FatOscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * The oscillator's frequency\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune control signal.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(options.detune, Tone.Type.Cents);\n\t /**\n\t\t\t * The array of oscillators\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._oscillators = [];\n\t /**\n\t\t\t * The total spread of the oscillators\n\t\t\t * @type {Cents}\n\t\t\t * @private\n\t\t\t */\n\t this._spread = options.spread;\n\t /**\n\t\t\t * The type of the oscillator\n\t\t\t * @type {String}\n\t\t\t * @private\n\t\t\t */\n\t this._type = options.type;\n\t /**\n\t\t\t * The phase of the oscillators\n\t\t\t * @type {Degrees}\n\t\t\t * @private\n\t\t\t */\n\t this._phase = options.phase;\n\t /**\n\t\t\t * The partials array\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._partials = Tone.defaultArg(options.partials, []);\n\t //set the count initially\n\t this.count = options.count;\n\t this._readOnly([\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t };\n\t Tone.extend(Tone.FatOscillator, Tone.Source);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.FatOscillator.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'phase': 0,\n\t 'spread': 20,\n\t 'count': 3,\n\t 'type': 'sawtooth'\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now]\n\t\t * @private\n\t\t */\n\t Tone.FatOscillator.prototype._start = function (time) {\n\t time = this.toSeconds(time);\n\t this._forEach(function (osc) {\n\t osc.start(time);\n\t });\n\t };\n\t /**\n\t\t * stop the oscillator\n\t\t * @param {Time} [time=now]\n\t\t * @private\n\t\t */\n\t Tone.FatOscillator.prototype._stop = function (time) {\n\t time = this.toSeconds(time);\n\t this._forEach(function (osc) {\n\t osc.stop(time);\n\t });\n\t };\n\t /**\n\t\t * restart the oscillator\n\t\t * @param {Time} time (optional) timing parameter\n\t\t * @private\n\t\t */\n\t Tone.FatOscillator.prototype.restart = function (time) {\n\t time = this.toSeconds(time);\n\t this._forEach(function (osc) {\n\t osc.restart(time);\n\t });\n\t };\n\t /**\n\t\t * Iterate over all of the oscillators\n\t\t * @param {Function} iterator The iterator function\n\t\t * @private\n\t\t */\n\t Tone.FatOscillator.prototype._forEach = function (iterator) {\n\t for (var i = 0; i < this._oscillators.length; i++) {\n\t iterator.call(this, this._oscillators[i], i);\n\t }\n\t };\n\t /**\n\t\t * The type of the carrier oscillator\n\t\t * @memberOf Tone.FatOscillator#\n\t\t * @type {string}\n\t\t * @name type\n\t\t */\n\t Object.defineProperty(Tone.FatOscillator.prototype, 'type', {\n\t get: function () {\n\t return this._type;\n\t },\n\t set: function (type) {\n\t this._type = type;\n\t this._forEach(function (osc) {\n\t osc.type = type;\n\t });\n\t }\n\t });\n\t /**\n\t\t * The detune spread between the oscillators. If \"count\" is\n\t\t * set to 3 oscillators and the \"spread\" is set to 40,\n\t\t * the three oscillators would be detuned like this: [-20, 0, 20]\n\t\t * for a total detune spread of 40 cents.\n\t\t * @memberOf Tone.FatOscillator#\n\t\t * @type {Cents}\n\t\t * @name spread\n\t\t */\n\t Object.defineProperty(Tone.FatOscillator.prototype, 'spread', {\n\t get: function () {\n\t return this._spread;\n\t },\n\t set: function (spread) {\n\t this._spread = spread;\n\t if (this._oscillators.length > 1) {\n\t var start = -spread / 2;\n\t var step = spread / (this._oscillators.length - 1);\n\t this._forEach(function (osc, i) {\n\t osc.detune.value = start + step * i;\n\t });\n\t }\n\t }\n\t });\n\t /**\n\t\t * The number of detuned oscillators\n\t\t * @memberOf Tone.FatOscillator#\n\t\t * @type {Number}\n\t\t * @name count\n\t\t */\n\t Object.defineProperty(Tone.FatOscillator.prototype, 'count', {\n\t get: function () {\n\t return this._oscillators.length;\n\t },\n\t set: function (count) {\n\t count = Math.max(count, 1);\n\t if (this._oscillators.length !== count) {\n\t // var partials = this.partials;\n\t // var type = this.type;\n\t //dispose the previous oscillators\n\t this._forEach(function (osc) {\n\t osc.dispose();\n\t });\n\t this._oscillators = [];\n\t for (var i = 0; i < count; i++) {\n\t var osc = new Tone.Oscillator();\n\t if (this.type === Tone.Oscillator.Type.Custom) {\n\t osc.partials = this._partials;\n\t } else {\n\t osc.type = this._type;\n\t }\n\t osc.phase = this._phase;\n\t osc.volume.value = -6 - count * 1.1;\n\t this.frequency.connect(osc.frequency);\n\t this.detune.connect(osc.detune);\n\t osc.connect(this.output);\n\t this._oscillators[i] = osc;\n\t }\n\t //set the spread\n\t this.spread = this._spread;\n\t if (this.state === Tone.State.Started) {\n\t this._forEach(function (osc) {\n\t osc.start();\n\t });\n\t }\n\t }\n\t }\n\t });\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.FatOscillator#\n\t\t * @type {Number}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.FatOscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._phase;\n\t },\n\t set: function (phase) {\n\t this._phase = phase;\n\t this._forEach(function (osc) {\n\t osc.phase = phase;\n\t });\n\t }\n\t });\n\t /**\n\t\t * The partials of the carrier waveform. A partial represents\n\t\t * the amplitude at a harmonic. The first harmonic is the\n\t\t * fundamental frequency, the second is the octave and so on\n\t\t * following the harmonic series.\n\t\t * Setting this value will automatically set the type to \"custom\".\n\t\t * The value is an empty array when the type is not \"custom\".\n\t\t * @memberOf Tone.FatOscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @example\n\t\t * osc.partials = [1, 0.2, 0.01];\n\t\t */\n\t Object.defineProperty(Tone.FatOscillator.prototype, 'partials', {\n\t get: function () {\n\t return this._partials;\n\t },\n\t set: function (partials) {\n\t this._partials = partials;\n\t this._type = Tone.Oscillator.Type.Custom;\n\t this._forEach(function (osc) {\n\t osc.partials = partials;\n\t });\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.FatOscillator} this\n\t\t */\n\t Tone.FatOscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this.detune.dispose();\n\t this.detune = null;\n\t this._forEach(function (osc) {\n\t osc.dispose();\n\t });\n\t this._oscillators = null;\n\t this._partials = null;\n\t return this;\n\t };\n\t return Tone.FatOscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.OmniOscillator aggregates Tone.Oscillator, Tone.PulseOscillator,\n\t\t * Tone.PWMOscillator, Tone.FMOscillator, Tone.AMOscillator, and Tone.FatOscillator\n\t\t * into one class. The oscillator class can be changed by setting the `type`.\n\t\t * `omniOsc.type = \"pwm\"` will set it to the Tone.PWMOscillator. Prefixing\n\t\t * any of the basic types (\"sine\", \"square4\", etc.) with \"fm\", \"am\", or \"fat\"\n\t\t * will use the FMOscillator, AMOscillator or FatOscillator respectively.\n\t\t * For example: `omniOsc.type = \"fatsawtooth\"` will create set the oscillator\n\t\t * to a FatOscillator of type \"sawtooth\".\n\t\t *\n\t\t * @extends {Tone.Source}\n\t\t * @constructor\n\t\t * @param {Frequency} frequency The initial frequency of the oscillator.\n\t\t * @param {String} type The type of the oscillator.\n\t\t * @example\n\t\t * var omniOsc = new Tone.OmniOscillator(\"C#4\", \"pwm\");\n\t\t */\n\t Tone.OmniOscillator = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'frequency',\n\t 'type'\n\t ], Tone.OmniOscillator);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune control\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(options.detune, Tone.Type.Cents);\n\t /**\n\t\t\t * the type of the oscillator source\n\t\t\t * @type {String}\n\t\t\t * @private\n\t\t\t */\n\t this._sourceType = undefined;\n\t /**\n\t\t\t * the oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t * @private\n\t\t\t */\n\t this._oscillator = null;\n\t //set the oscillator\n\t this.type = options.type;\n\t this._readOnly([\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t //set the options\n\t this.set(options);\n\t };\n\t Tone.extend(Tone.OmniOscillator, Tone.Source);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @type {Object}\n\t\t * @const\n\t\t */\n\t Tone.OmniOscillator.defaults = {\n\t 'frequency': 440,\n\t 'detune': 0,\n\t 'type': 'sine',\n\t 'phase': 0\n\t };\n\t /**\n\t\t * @enum {String}\n\t\t * @private\n\t\t */\n\t var OmniOscType = {\n\t Pulse: 'PulseOscillator',\n\t PWM: 'PWMOscillator',\n\t Osc: 'Oscillator',\n\t FM: 'FMOscillator',\n\t AM: 'AMOscillator',\n\t Fat: 'FatOscillator'\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now] the time to start the oscillator\n\t\t * @private\n\t\t */\n\t Tone.OmniOscillator.prototype._start = function (time) {\n\t this._oscillator.start(time);\n\t };\n\t /**\n\t\t * start the oscillator\n\t\t * @param {Time} [time=now] the time to start the oscillator\n\t\t * @private\n\t\t */\n\t Tone.OmniOscillator.prototype._stop = function (time) {\n\t this._oscillator.stop(time);\n\t };\n\t Tone.OmniOscillator.prototype.restart = function (time) {\n\t this._oscillator.restart(time);\n\t };\n\t /**\n\t\t * The type of the oscillator. Can be any of the basic types: sine, square, triangle, sawtooth. Or\n\t\t * prefix the basic types with \"fm\", \"am\", or \"fat\" to use the FMOscillator, AMOscillator or FatOscillator\n\t\t * types. The oscillator could also be set to \"pwm\" or \"pulse\". All of the parameters of the\n\t\t * oscillator's class are accessible when the oscillator is set to that type, but throws an error\n\t\t * when it's not.\n\t\t *\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {String}\n\t\t * @name type\n\t\t * @example\n\t\t * omniOsc.type = \"pwm\";\n\t\t * //modulationFrequency is parameter which is available\n\t\t * //only when the type is \"pwm\".\n\t\t * omniOsc.modulationFrequency.value = 0.5;\n\t\t * @example\n\t\t * //an square wave frequency modulated by a sawtooth\n\t\t * omniOsc.type = \"fmsquare\";\n\t\t * omniOsc.modulationType = \"sawtooth\";\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'type', {\n\t get: function () {\n\t var prefix = '';\n\t if (this._sourceType === OmniOscType.FM) {\n\t prefix = 'fm';\n\t } else if (this._sourceType === OmniOscType.AM) {\n\t prefix = 'am';\n\t } else if (this._sourceType === OmniOscType.Fat) {\n\t prefix = 'fat';\n\t }\n\t return prefix + this._oscillator.type;\n\t },\n\t set: function (type) {\n\t if (type.substr(0, 2) === 'fm') {\n\t this._createNewOscillator(OmniOscType.FM);\n\t this._oscillator.type = type.substr(2);\n\t } else if (type.substr(0, 2) === 'am') {\n\t this._createNewOscillator(OmniOscType.AM);\n\t this._oscillator.type = type.substr(2);\n\t } else if (type.substr(0, 3) === 'fat') {\n\t this._createNewOscillator(OmniOscType.Fat);\n\t this._oscillator.type = type.substr(3);\n\t } else if (type === 'pwm') {\n\t this._createNewOscillator(OmniOscType.PWM);\n\t } else if (type === 'pulse') {\n\t this._createNewOscillator(OmniOscType.Pulse);\n\t } else {\n\t this._createNewOscillator(OmniOscType.Osc);\n\t this._oscillator.type = type;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The partials of the waveform. A partial represents\n\t\t * the amplitude at a harmonic. The first harmonic is the\n\t\t * fundamental frequency, the second is the octave and so on\n\t\t * following the harmonic series.\n\t\t * Setting this value will automatically set the type to \"custom\".\n\t\t * The value is an empty array when the type is not \"custom\".\n\t\t * This is not available on \"pwm\" and \"pulse\" oscillator types.\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {Array}\n\t\t * @name partials\n\t\t * @example\n\t\t * osc.partials = [1, 0.2, 0.01];\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'partials', {\n\t get: function () {\n\t return this._oscillator.partials;\n\t },\n\t set: function (partials) {\n\t this._oscillator.partials = partials;\n\t }\n\t });\n\t /**\n\t\t * Set a member/attribute of the oscillator.\n\t\t * @param {Object|String} params\n\t\t * @param {number=} value\n\t\t * @param {Time=} rampTime\n\t\t * @returns {Tone.OmniOscillator} this\n\t\t */\n\t Tone.OmniOscillator.prototype.set = function (params, value) {\n\t //make sure the type is set first\n\t if (params === 'type') {\n\t this.type = value;\n\t } else if (Tone.isObject(params) && params.hasOwnProperty('type')) {\n\t this.type = params.type;\n\t }\n\t //then set the rest\n\t Tone.prototype.set.apply(this, arguments);\n\t return this;\n\t };\n\t /**\n\t\t * connect the oscillator to the frequency and detune signals\n\t\t * @private\n\t\t */\n\t Tone.OmniOscillator.prototype._createNewOscillator = function (oscType) {\n\t if (oscType !== this._sourceType) {\n\t this._sourceType = oscType;\n\t var OscillatorConstructor = Tone[oscType];\n\t //short delay to avoid clicks on the change\n\t var now = this.now();\n\t if (this._oscillator !== null) {\n\t var oldOsc = this._oscillator;\n\t oldOsc.stop(now);\n\t //dispose the old one\n\t this.context.setTimeout(function () {\n\t oldOsc.dispose();\n\t oldOsc = null;\n\t }, this.blockTime);\n\t }\n\t this._oscillator = new OscillatorConstructor();\n\t this.frequency.connect(this._oscillator.frequency);\n\t this.detune.connect(this._oscillator.detune);\n\t this._oscillator.connect(this.output);\n\t if (this.state === Tone.State.Started) {\n\t this._oscillator.start(now);\n\t }\n\t }\n\t };\n\t /**\n\t\t * The phase of the oscillator in degrees.\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {Degrees}\n\t\t * @name phase\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'phase', {\n\t get: function () {\n\t return this._oscillator.phase;\n\t },\n\t set: function (phase) {\n\t this._oscillator.phase = phase;\n\t }\n\t });\n\t /**\n\t\t * The width of the oscillator (only if the oscillator is set to \"pulse\")\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t * @name width\n\t\t * @example\n\t\t * var omniOsc = new Tone.OmniOscillator(440, \"pulse\");\n\t\t * //can access the width attribute only if type === \"pulse\"\n\t\t * omniOsc.width.value = 0.2;\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'width', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.Pulse) {\n\t return this._oscillator.width;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The number of detuned oscillators\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {Number}\n\t\t * @name count\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'count', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.Fat) {\n\t return this._oscillator.count;\n\t }\n\t },\n\t set: function (count) {\n\t if (this._sourceType === OmniOscType.Fat) {\n\t this._oscillator.count = count;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The detune spread between the oscillators. If \"count\" is\n\t\t * set to 3 oscillators and the \"spread\" is set to 40,\n\t\t * the three oscillators would be detuned like this: [-20, 0, 20]\n\t\t * for a total detune spread of 40 cents. See Tone.FatOscillator\n\t\t * for more info.\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {Cents}\n\t\t * @name spread\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'spread', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.Fat) {\n\t return this._oscillator.spread;\n\t }\n\t },\n\t set: function (spread) {\n\t if (this._sourceType === OmniOscType.Fat) {\n\t this._oscillator.spread = spread;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The type of the modulator oscillator. Only if the oscillator\n\t\t * is set to \"am\" or \"fm\" types. see. Tone.AMOscillator or Tone.FMOscillator\n\t\t * for more info.\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {String}\n\t\t * @name modulationType\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationType', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) {\n\t return this._oscillator.modulationType;\n\t }\n\t },\n\t set: function (mType) {\n\t if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) {\n\t this._oscillator.modulationType = mType;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The modulation index which is in essence the depth or amount of the modulation. In other terms it is the\n\t\t * ratio of the frequency of the modulating signal (mf) to the amplitude of the\n\t\t * modulating signal (ma) -- as in ma/mf.\n\t\t * See Tone.FMOscillator for more info.\n\t\t * @type {Positive}\n\t\t * @signal\n\t\t * @name modulationIndex\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationIndex', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.FM) {\n\t return this._oscillator.modulationIndex;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Harmonicity is the frequency ratio between the carrier and the modulator oscillators.\n\t\t * A harmonicity of 1 gives both oscillators the same frequency.\n\t\t * Harmonicity = 2 means a change of an octave. See Tone.AMOscillator or Tone.FMOscillator\n\t\t * for more info.\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @signal\n\t\t * @type {Positive}\n\t\t * @name harmonicity\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'harmonicity', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) {\n\t return this._oscillator.harmonicity;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The modulationFrequency Signal of the oscillator\n\t\t * (only if the oscillator type is set to pwm). See\n\t\t * Tone.PWMOscillator for more info.\n\t\t * @memberOf Tone.OmniOscillator#\n\t\t * @type {Frequency}\n\t\t * @signal\n\t\t * @name modulationFrequency\n\t\t * @example\n\t\t * var omniOsc = new Tone.OmniOscillator(440, \"pwm\");\n\t\t * //can access the modulationFrequency attribute only if type === \"pwm\"\n\t\t * omniOsc.modulationFrequency.value = 0.2;\n\t\t */\n\t Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationFrequency', {\n\t get: function () {\n\t if (this._sourceType === OmniOscType.PWM) {\n\t return this._oscillator.modulationFrequency;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.OmniOscillator} this\n\t\t */\n\t Tone.OmniOscillator.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'detune'\n\t ]);\n\t this.detune.dispose();\n\t this.detune = null;\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this._oscillator.dispose();\n\t this._oscillator = null;\n\t this._sourceType = null;\n\t return this;\n\t };\n\t return Tone.OmniOscillator;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Base-class for all instruments\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t */\n\t Tone.Instrument = function (options) {\n\t //get the defaults\n\t options = Tone.defaultArg(options, Tone.Instrument.defaults);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The output and volume triming node\n\t\t\t * @type {Tone.Volume}\n\t\t\t * @private\n\t\t\t */\n\t this._volume = this.output = new Tone.Volume(options.volume);\n\t /**\n\t\t\t * The volume of the output in decibels.\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * source.volume.value = -6;\n\t\t\t */\n\t this.volume = this._volume.volume;\n\t this._readOnly('volume');\n\t /**\n\t\t\t * Keep track of all events scheduled to the transport\n\t\t\t * when the instrument is 'synced'\n\t\t\t * @type {Array<Number>}\n\t\t\t * @private\n\t\t\t */\n\t this._scheduledEvents = [];\n\t };\n\t Tone.extend(Tone.Instrument, Tone.AudioNode);\n\t /**\n\t\t * the default attributes\n\t\t * @type {object}\n\t\t */\n\t Tone.Instrument.defaults = {\n\t /** the volume of the output in decibels */\n\t 'volume': 0\n\t };\n\t /**\n\t\t * @abstract\n\t\t * @param {string|number} note the note to trigger\n\t\t * @param {Time} [time=now] the time to trigger the ntoe\n\t\t * @param {number} [velocity=1] the velocity to trigger the note\n\t\t */\n\t Tone.Instrument.prototype.triggerAttack = Tone.noOp;\n\t /**\n\t\t * @abstract\n\t\t * @param {Time} [time=now] when to trigger the release\n\t\t */\n\t Tone.Instrument.prototype.triggerRelease = Tone.noOp;\n\t /**\n\t\t * Sync the instrument to the Transport. All subsequent calls of\n\t\t * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease)\n\t\t * will be scheduled along the transport.\n\t\t * @example\n\t\t * instrument.sync()\n\t\t * //schedule 3 notes when the transport first starts\n\t\t * instrument.triggerAttackRelease('C4', '8n', 0)\n\t\t * instrument.triggerAttackRelease('E4', '8n', '8n')\n\t\t * instrument.triggerAttackRelease('G4', '8n', '4n')\n\t\t * //start the transport to hear the notes\n\t\t * Transport.start()\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.Instrument.prototype.sync = function () {\n\t this._syncMethod('triggerAttack', 1);\n\t this._syncMethod('triggerRelease', 0);\n\t return this;\n\t };\n\t /**\n\t\t * Wrap the given method so that it can be synchronized\n\t\t * @param {String} method Which method to wrap and sync\n\t\t * @param {Number} timePosition What position the time argument appears in\n\t\t * @private\n\t\t */\n\t Tone.Instrument.prototype._syncMethod = function (method, timePosition) {\n\t var originalMethod = this['_original_' + method] = this[method];\n\t this[method] = function () {\n\t var args = Array.prototype.slice.call(arguments);\n\t var time = args[timePosition];\n\t var id = Tone.Transport.schedule(function (t) {\n\t args[timePosition] = t;\n\t originalMethod.apply(this, args);\n\t }.bind(this), time);\n\t this._scheduledEvents.push(id);\n\t }.bind(this);\n\t };\n\t /**\n\t\t * Unsync the instrument from the Transport\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.Instrument.prototype.unsync = function () {\n\t this._scheduledEvents.forEach(function (id) {\n\t Tone.Transport.clear(id);\n\t });\n\t this._scheduledEvents = [];\n\t if (this._original_triggerAttack) {\n\t this.triggerAttack = this._original_triggerAttack;\n\t this.triggerRelease = this._original_triggerRelease;\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the attack and then the release after the duration.\n\t\t * @param {Frequency} note The note to trigger.\n\t\t * @param {Time} duration How long the note should be held for before\n\t\t * triggering the release. This value must be greater than 0.\n\t\t * @param {Time} [time=now] When the note should be triggered.\n\t\t * @param {NormalRange} [velocity=1] The velocity the note should be triggered at.\n\t\t * @returns {Tone.Instrument} this\n\t\t * @example\n\t\t * //trigger \"C4\" for the duration of an 8th note\n\t\t * synth.triggerAttackRelease(\"C4\", \"8n\");\n\t\t */\n\t Tone.Instrument.prototype.triggerAttackRelease = function (note, duration, time, velocity) {\n\t time = this.toSeconds(time);\n\t duration = this.toSeconds(duration);\n\t this.triggerAttack(note, time, velocity);\n\t this.triggerRelease(time + duration);\n\t return this;\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.Instrument.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._volume.dispose();\n\t this._volume = null;\n\t this._writable(['volume']);\n\t this.volume = null;\n\t this.unsync();\n\t this._scheduledEvents = null;\n\t return this;\n\t };\n\t return Tone.Instrument;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class This is an abstract base class for other monophonic instruments to \n\t\t * extend. IMPORTANT: It does not make any sound on its own and\n\t\t * shouldn't be directly instantiated.\n\t\t *\n\t\t * @constructor\n\t\t * @abstract\n\t\t * @extends {Tone.Instrument}\n\t\t */\n\t Tone.Monophonic = function (options) {\n\t //get the defaults\n\t options = Tone.defaultArg(options, Tone.Monophonic.defaults);\n\t Tone.Instrument.call(this, options);\n\t /**\n\t\t\t * The glide time between notes. \n\t\t\t * @type {Time}\n\t\t\t */\n\t this.portamento = options.portamento;\n\t };\n\t Tone.extend(Tone.Monophonic, Tone.Instrument);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Monophonic.defaults = { 'portamento': 0 };\n\t /**\n\t\t * Trigger the attack of the note optionally with a given velocity. \n\t\t * \n\t\t * \n\t\t * @param {Frequency} note The note to trigger.\n\t\t * @param {Time} [time=now] When the note should start.\n\t\t * @param {number} [velocity=1] velocity The velocity scaler \n\t\t * determines how \"loud\" the note \n\t\t * will be triggered.\n\t\t * @returns {Tone.Monophonic} this\n\t\t * @example\n\t\t * synth.triggerAttack(\"C4\");\n\t\t * @example\n\t\t * //trigger the note a half second from now at half velocity\n\t\t * synth.triggerAttack(\"C4\", \"+0.5\", 0.5);\n\t\t */\n\t Tone.Monophonic.prototype.triggerAttack = function (note, time, velocity) {\n\t time = this.toSeconds(time);\n\t this._triggerEnvelopeAttack(time, velocity);\n\t this.setNote(note, time);\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the release portion of the envelope\n\t\t * @param {Time} [time=now] If no time is given, the release happens immediatly\n\t\t * @returns {Tone.Monophonic} this\n\t\t * @example\n\t\t * synth.triggerRelease();\n\t\t */\n\t Tone.Monophonic.prototype.triggerRelease = function (time) {\n\t time = this.toSeconds(time);\n\t this._triggerEnvelopeRelease(time);\n\t return this;\n\t };\n\t /**\n\t\t * override this method with the actual method\n\t\t * @abstract\n\t\t * @private\n\t\t */\n\t Tone.Monophonic.prototype._triggerEnvelopeAttack = function () {\n\t };\n\t /**\n\t\t * override this method with the actual method\n\t\t * @abstract\n\t\t * @private\n\t\t */\n\t Tone.Monophonic.prototype._triggerEnvelopeRelease = function () {\n\t };\n\t /**\n\t\t * Get the level of the output at the given time. Measures\n\t\t * the envelope(s) value at the time. \n\t\t * @param {Time} time The time to query the envelope value\n\t\t * @return {NormalRange} The output level between 0-1\n\t\t */\n\t Tone.Monophonic.prototype.getLevelAtTime = function (time) {\n\t time = this.toSeconds(time);\n\t return this.envelope.getValueAtTime(time);\n\t };\n\t /**\n\t\t * Set the note at the given time. If no time is given, the note\n\t\t * will set immediately. \n\t\t * @param {Frequency} note The note to change to.\n\t\t * @param {Time} [time=now] The time when the note should be set. \n\t\t * @returns {Tone.Monophonic} this\n\t\t * @example\n\t\t * //change to F#6 in one quarter note from now.\n\t\t * synth.setNote(\"F#6\", \"+4n\");\n\t\t * @example\n\t\t * //change to Bb4 right now\n\t\t * synth.setNote(\"Bb4\");\n\t\t */\n\t Tone.Monophonic.prototype.setNote = function (note, time) {\n\t time = this.toSeconds(time);\n\t if (this.portamento > 0 && this.getLevelAtTime(time) > 0.05) {\n\t var portTime = this.toSeconds(this.portamento);\n\t this.frequency.exponentialRampTo(note, portTime, time);\n\t } else {\n\t this.frequency.setValueAtTime(note, time);\n\t }\n\t return this;\n\t };\n\t return Tone.Monophonic;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Synth is composed simply of a Tone.OmniOscillator\n\t\t * routed through a Tone.AmplitudeEnvelope.\n\t\t * <img src=\"https://docs.google.com/drawings/d/1-1_0YW2Z1J2EPI36P8fNCMcZG7N1w1GZluPs4og4evo/pub?w=1163&h=231\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Monophonic}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var synth = new Tone.Synth().toMaster();\n\t\t * synth.triggerAttackRelease(\"C4\", \"8n\");\n\t\t */\n\t Tone.Synth = function (options) {\n\t //get the defaults\n\t options = Tone.defaultArg(options, Tone.Synth.defaults);\n\t Tone.Monophonic.call(this, options);\n\t /**\n\t\t\t * The oscillator.\n\t\t\t * @type {Tone.OmniOscillator}\n\t\t\t */\n\t this.oscillator = new Tone.OmniOscillator(options.oscillator);\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this.oscillator.frequency;\n\t /**\n\t\t\t * The detune control.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = this.oscillator.detune;\n\t /**\n\t\t\t * The amplitude envelope.\n\t\t\t * @type {Tone.AmplitudeEnvelope}\n\t\t\t */\n\t this.envelope = new Tone.AmplitudeEnvelope(options.envelope);\n\t //connect the oscillators to the output\n\t this.oscillator.chain(this.envelope, this.output);\n\t this._readOnly([\n\t 'oscillator',\n\t 'frequency',\n\t 'detune',\n\t 'envelope'\n\t ]);\n\t };\n\t Tone.extend(Tone.Synth, Tone.Monophonic);\n\t /**\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.Synth.defaults = {\n\t 'oscillator': { 'type': 'triangle' },\n\t 'envelope': {\n\t 'attack': 0.005,\n\t 'decay': 0.1,\n\t 'sustain': 0.3,\n\t 'release': 1\n\t }\n\t };\n\t /**\n\t\t * start the attack portion of the envelope\n\t\t * @param {Time} [time=now] the time the attack should start\n\t\t * @param {number} [velocity=1] the velocity of the note (0-1)\n\t\t * @returns {Tone.Synth} this\n\t\t * @private\n\t\t */\n\t Tone.Synth.prototype._triggerEnvelopeAttack = function (time, velocity) {\n\t //the envelopes\n\t this.envelope.triggerAttack(time, velocity);\n\t this.oscillator.start(time);\n\t //if there is no release portion, stop the oscillator\n\t if (this.envelope.sustain === 0) {\n\t this.oscillator.stop(time + this.envelope.attack + this.envelope.decay);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * start the release portion of the envelope\n\t\t * @param {Time} [time=now] the time the release should start\n\t\t * @returns {Tone.Synth} this\n\t\t * @private\n\t\t */\n\t Tone.Synth.prototype._triggerEnvelopeRelease = function (time) {\n\t time = this.toSeconds(time);\n\t this.envelope.triggerRelease(time);\n\t this.oscillator.stop(time + this.envelope.release);\n\t return this;\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Synth} this\n\t\t */\n\t Tone.Synth.prototype.dispose = function () {\n\t Tone.Monophonic.prototype.dispose.call(this);\n\t this._writable([\n\t 'oscillator',\n\t 'frequency',\n\t 'detune',\n\t 'envelope'\n\t ]);\n\t this.oscillator.dispose();\n\t this.oscillator = null;\n\t this.envelope.dispose();\n\t this.envelope = null;\n\t this.frequency = null;\n\t this.detune = null;\n\t return this;\n\t };\n\t return Tone.Synth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class AMSynth uses the output of one Tone.Synth to modulate the\n\t\t * amplitude of another Tone.Synth. The harmonicity (the ratio between\n\t\t * the two signals) affects the timbre of the output signal greatly.\n\t\t * Read more about Amplitude Modulation Synthesis on\n\t\t * [SoundOnSound](https://web.archive.org/web/20160404103653/http://www.soundonsound.com:80/sos/mar00/articles/synthsecrets.htm).\n\t\t * <img src=\"https://docs.google.com/drawings/d/1TQu8Ed4iFr1YTLKpB3U1_hur-UwBrh5gdBXc8BxfGKw/pub?w=1009&h=457\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Monophonic}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var synth = new Tone.AMSynth().toMaster();\n\t\t * synth.triggerAttackRelease(\"C4\", \"4n\");\n\t\t */\n\t Tone.AMSynth = function (options) {\n\t options = Tone.defaultArg(options, Tone.AMSynth.defaults);\n\t Tone.Monophonic.call(this, options);\n\t /**\n\t\t\t * The carrier voice.\n\t\t\t * @type {Tone.Synth}\n\t\t\t * @private\n\t\t\t */\n\t this._carrier = new Tone.Synth();\n\t this._carrier.volume.value = -10;\n\t /**\n\t\t\t * The carrier's oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t */\n\t this.oscillator = this._carrier.oscillator;\n\t /**\n\t\t\t * The carrier's envelope\n\t\t\t * @type {Tone.AmplitudeEnvelope}\n\t\t\t */\n\t this.envelope = this._carrier.envelope.set(options.envelope);\n\t /**\n\t\t\t * The modulator voice.\n\t\t\t * @type {Tone.Synth}\n\t\t\t * @private\n\t\t\t */\n\t this._modulator = new Tone.Synth();\n\t this._modulator.volume.value = -10;\n\t /**\n\t\t\t * The modulator's oscillator which is applied\n\t\t\t * to the amplitude of the oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t */\n\t this.modulation = this._modulator.oscillator.set(options.modulation);\n\t /**\n\t\t\t * The modulator's envelope\n\t\t\t * @type {Tone.AmplitudeEnvelope}\n\t\t\t */\n\t this.modulationEnvelope = this._modulator.envelope.set(options.modulationEnvelope);\n\t /**\n\t\t\t * The frequency.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(440, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune in cents\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(options.detune, Tone.Type.Cents);\n\t /**\n\t\t\t * Harmonicity is the ratio between the two voices. A harmonicity of\n\t\t\t * 1 is no change. Harmonicity = 2 means a change of an octave.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * //pitch voice1 an octave below voice0\n\t\t\t * synth.harmonicity.value = 0.5;\n\t\t\t */\n\t this.harmonicity = new Tone.Multiply(options.harmonicity);\n\t this.harmonicity.units = Tone.Type.Positive;\n\t /**\n\t\t\t * convert the -1,1 output to 0,1\n\t\t\t * @type {Tone.AudioToGain}\n\t\t\t * @private\n\t\t\t */\n\t this._modulationScale = new Tone.AudioToGain();\n\t /**\n\t\t\t * the node where the modulation happens\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._modulationNode = new Tone.Gain();\n\t //control the two voices frequency\n\t this.frequency.connect(this._carrier.frequency);\n\t this.frequency.chain(this.harmonicity, this._modulator.frequency);\n\t this.detune.fan(this._carrier.detune, this._modulator.detune);\n\t this._modulator.chain(this._modulationScale, this._modulationNode.gain);\n\t this._carrier.chain(this._modulationNode, this.output);\n\t this._readOnly([\n\t 'frequency',\n\t 'harmonicity',\n\t 'oscillator',\n\t 'envelope',\n\t 'modulation',\n\t 'modulationEnvelope',\n\t 'detune'\n\t ]);\n\t };\n\t Tone.extend(Tone.AMSynth, Tone.Monophonic);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.AMSynth.defaults = {\n\t 'harmonicity': 3,\n\t 'detune': 0,\n\t 'oscillator': { 'type': 'sine' },\n\t 'envelope': {\n\t 'attack': 0.01,\n\t 'decay': 0.01,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t },\n\t 'modulation': { 'type': 'square' },\n\t 'modulationEnvelope': {\n\t 'attack': 0.5,\n\t 'decay': 0,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t }\n\t };\n\t /**\n\t\t * trigger the attack portion of the note\n\t\t *\n\t\t * @param {Time} [time=now] the time the note will occur\n\t\t * @param {NormalRange} [velocity=1] the velocity of the note\n\t\t * @private\n\t\t * @returns {Tone.AMSynth} this\n\t\t */\n\t Tone.AMSynth.prototype._triggerEnvelopeAttack = function (time, velocity) {\n\t //the port glide\n\t time = this.toSeconds(time);\n\t //the envelopes\n\t this._carrier._triggerEnvelopeAttack(time, velocity);\n\t this._modulator._triggerEnvelopeAttack(time);\n\t return this;\n\t };\n\t /**\n\t\t * trigger the release portion of the note\n\t\t *\n\t\t * @param {Time} [time=now] the time the note will release\n\t\t * @private\n\t\t * @returns {Tone.AMSynth} this\n\t\t */\n\t Tone.AMSynth.prototype._triggerEnvelopeRelease = function (time) {\n\t this._carrier._triggerEnvelopeRelease(time);\n\t this._modulator._triggerEnvelopeRelease(time);\n\t return this;\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.AMSynth} this\n\t\t */\n\t Tone.AMSynth.prototype.dispose = function () {\n\t Tone.Monophonic.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'harmonicity',\n\t 'oscillator',\n\t 'envelope',\n\t 'modulation',\n\t 'modulationEnvelope',\n\t 'detune'\n\t ]);\n\t this._carrier.dispose();\n\t this._carrier = null;\n\t this._modulator.dispose();\n\t this._modulator = null;\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this.detune.dispose();\n\t this.detune = null;\n\t this.harmonicity.dispose();\n\t this.harmonicity = null;\n\t this._modulationScale.dispose();\n\t this._modulationScale = null;\n\t this._modulationNode.dispose();\n\t this._modulationNode = null;\n\t this.oscillator = null;\n\t this.envelope = null;\n\t this.modulationEnvelope = null;\n\t this.modulation = null;\n\t return this;\n\t };\n\t return Tone.AMSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.MonoSynth is composed of one oscillator, one filter, and two envelopes.\n\t\t * The amplitude of the Tone.Oscillator and the cutoff frequency of the\n\t\t * Tone.Filter are controlled by Tone.Envelopes.\n\t\t * <img src=\"https://docs.google.com/drawings/d/1gaY1DF9_Hzkodqf8JI1Cg2VZfwSElpFQfI94IQwad38/pub?w=924&h=240\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Monophonic}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var synth = new Tone.MonoSynth({\n\t\t * \t\"oscillator\" : {\n\t\t * \t\t\"type\" : \"square\"\n\t\t * },\n\t\t * \"envelope\" : {\n\t\t * \t\"attack\" : 0.1\n\t\t * }\n\t\t * }).toMaster();\n\t\t * synth.triggerAttackRelease(\"C4\", \"8n\");\n\t\t */\n\t Tone.MonoSynth = function (options) {\n\t //get the defaults\n\t options = Tone.defaultArg(options, Tone.MonoSynth.defaults);\n\t Tone.Monophonic.call(this, options);\n\t /**\n\t\t\t * The oscillator.\n\t\t\t * @type {Tone.OmniOscillator}\n\t\t\t */\n\t this.oscillator = new Tone.OmniOscillator(options.oscillator);\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = this.oscillator.frequency;\n\t /**\n\t\t\t * The detune control.\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = this.oscillator.detune;\n\t /**\n\t\t\t * The filter.\n\t\t\t * @type {Tone.Filter}\n\t\t\t */\n\t this.filter = new Tone.Filter(options.filter);\n\t /**\n\t\t\t * The filter envelope.\n\t\t\t * @type {Tone.FrequencyEnvelope}\n\t\t\t */\n\t this.filterEnvelope = new Tone.FrequencyEnvelope(options.filterEnvelope);\n\t /**\n\t\t\t * The amplitude envelope.\n\t\t\t * @type {Tone.AmplitudeEnvelope}\n\t\t\t */\n\t this.envelope = new Tone.AmplitudeEnvelope(options.envelope);\n\t //connect the oscillators to the output\n\t this.oscillator.chain(this.filter, this.envelope, this.output);\n\t //connect the filter envelope\n\t this.filterEnvelope.connect(this.filter.frequency);\n\t this._readOnly([\n\t 'oscillator',\n\t 'frequency',\n\t 'detune',\n\t 'filter',\n\t 'filterEnvelope',\n\t 'envelope'\n\t ]);\n\t };\n\t Tone.extend(Tone.MonoSynth, Tone.Monophonic);\n\t /**\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.MonoSynth.defaults = {\n\t 'frequency': 'C4',\n\t 'detune': 0,\n\t 'oscillator': { 'type': 'square' },\n\t 'filter': {\n\t 'Q': 6,\n\t 'type': 'lowpass',\n\t 'rolloff': -24\n\t },\n\t 'envelope': {\n\t 'attack': 0.005,\n\t 'decay': 0.1,\n\t 'sustain': 0.9,\n\t 'release': 1\n\t },\n\t 'filterEnvelope': {\n\t 'attack': 0.06,\n\t 'decay': 0.2,\n\t 'sustain': 0.5,\n\t 'release': 2,\n\t 'baseFrequency': 200,\n\t 'octaves': 7,\n\t 'exponent': 2\n\t }\n\t };\n\t /**\n\t\t * start the attack portion of the envelope\n\t\t * @param {Time} [time=now] the time the attack should start\n\t\t * @param {NormalRange} [velocity=1] the velocity of the note (0-1)\n\t\t * @returns {Tone.MonoSynth} this\n\t\t * @private\n\t\t */\n\t Tone.MonoSynth.prototype._triggerEnvelopeAttack = function (time, velocity) {\n\t time = this.toSeconds(time);\n\t //the envelopes\n\t this.envelope.triggerAttack(time, velocity);\n\t this.filterEnvelope.triggerAttack(time);\n\t this.oscillator.start(time);\n\t if (this.envelope.sustain === 0) {\n\t this.oscillator.stop(time + this.envelope.attack + this.envelope.decay);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * start the release portion of the envelope\n\t\t * @param {Time} [time=now] the time the release should start\n\t\t * @returns {Tone.MonoSynth} this\n\t\t * @private\n\t\t */\n\t Tone.MonoSynth.prototype._triggerEnvelopeRelease = function (time) {\n\t this.envelope.triggerRelease(time);\n\t this.filterEnvelope.triggerRelease(time);\n\t this.oscillator.stop(time + this.envelope.release);\n\t return this;\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.MonoSynth} this\n\t\t */\n\t Tone.MonoSynth.prototype.dispose = function () {\n\t Tone.Monophonic.prototype.dispose.call(this);\n\t this._writable([\n\t 'oscillator',\n\t 'frequency',\n\t 'detune',\n\t 'filter',\n\t 'filterEnvelope',\n\t 'envelope'\n\t ]);\n\t this.oscillator.dispose();\n\t this.oscillator = null;\n\t this.envelope.dispose();\n\t this.envelope = null;\n\t this.filterEnvelope.dispose();\n\t this.filterEnvelope = null;\n\t this.filter.dispose();\n\t this.filter = null;\n\t this.frequency = null;\n\t this.detune = null;\n\t return this;\n\t };\n\t return Tone.MonoSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.DuoSynth is a monophonic synth composed of two\n\t\t * MonoSynths run in parallel with control over the\n\t\t * frequency ratio between the two voices and vibrato effect.\n\t\t * <img src=\"https://docs.google.com/drawings/d/1bL4GXvfRMMlqS7XyBm9CjL9KJPSUKbcdBNpqOlkFLxk/pub?w=1012&h=448\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Monophonic}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var duoSynth = new Tone.DuoSynth().toMaster();\n\t\t * duoSynth.triggerAttackRelease(\"C4\", \"2n\");\n\t\t */\n\t Tone.DuoSynth = function (options) {\n\t options = Tone.defaultArg(options, Tone.DuoSynth.defaults);\n\t Tone.Monophonic.call(this, options);\n\t /**\n\t\t\t * the first voice\n\t\t\t * @type {Tone.MonoSynth}\n\t\t\t */\n\t this.voice0 = new Tone.MonoSynth(options.voice0);\n\t this.voice0.volume.value = -10;\n\t /**\n\t\t\t * the second voice\n\t\t\t * @type {Tone.MonoSynth}\n\t\t\t */\n\t this.voice1 = new Tone.MonoSynth(options.voice1);\n\t this.voice1.volume.value = -10;\n\t /**\n\t\t\t * The vibrato LFO.\n\t\t\t * @type {Tone.LFO}\n\t\t\t * @private\n\t\t\t */\n\t this._vibrato = new Tone.LFO(options.vibratoRate, -50, 50);\n\t this._vibrato.start();\n\t /**\n\t\t\t * the vibrato frequency\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.vibratoRate = this._vibrato.frequency;\n\t /**\n\t\t\t * the vibrato gain\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._vibratoGain = new Tone.Gain(options.vibratoAmount, Tone.Type.Positive);\n\t /**\n\t\t\t * The amount of vibrato\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t */\n\t this.vibratoAmount = this._vibratoGain.gain;\n\t /**\n\t\t\t * the frequency control\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(440, Tone.Type.Frequency);\n\t /**\n\t\t\t * Harmonicity is the ratio between the two voices. A harmonicity of\n\t\t\t * 1 is no change. Harmonicity = 2 means a change of an octave.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * //pitch voice1 an octave below voice0\n\t\t\t * duoSynth.harmonicity.value = 0.5;\n\t\t\t */\n\t this.harmonicity = new Tone.Multiply(options.harmonicity);\n\t this.harmonicity.units = Tone.Type.Positive;\n\t //control the two voices frequency\n\t this.frequency.connect(this.voice0.frequency);\n\t this.frequency.chain(this.harmonicity, this.voice1.frequency);\n\t this._vibrato.connect(this._vibratoGain);\n\t this._vibratoGain.fan(this.voice0.detune, this.voice1.detune);\n\t this.voice0.connect(this.output);\n\t this.voice1.connect(this.output);\n\t this._readOnly([\n\t 'voice0',\n\t 'voice1',\n\t 'frequency',\n\t 'vibratoAmount',\n\t 'vibratoRate'\n\t ]);\n\t };\n\t Tone.extend(Tone.DuoSynth, Tone.Monophonic);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.DuoSynth.defaults = {\n\t 'vibratoAmount': 0.5,\n\t 'vibratoRate': 5,\n\t 'harmonicity': 1.5,\n\t 'voice0': {\n\t 'volume': -10,\n\t 'portamento': 0,\n\t 'oscillator': { 'type': 'sine' },\n\t 'filterEnvelope': {\n\t 'attack': 0.01,\n\t 'decay': 0,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t },\n\t 'envelope': {\n\t 'attack': 0.01,\n\t 'decay': 0,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t }\n\t },\n\t 'voice1': {\n\t 'volume': -10,\n\t 'portamento': 0,\n\t 'oscillator': { 'type': 'sine' },\n\t 'filterEnvelope': {\n\t 'attack': 0.01,\n\t 'decay': 0,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t },\n\t 'envelope': {\n\t 'attack': 0.01,\n\t 'decay': 0,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t }\n\t }\n\t };\n\t /**\n\t\t * start the attack portion of the envelopes\n\t\t *\n\t\t * @param {Time} [time=now] the time the attack should start\n\t\t * @param {NormalRange} [velocity=1] the velocity of the note (0-1)\n\t\t * @returns {Tone.DuoSynth} this\n\t\t * @private\n\t\t */\n\t Tone.DuoSynth.prototype._triggerEnvelopeAttack = function (time, velocity) {\n\t time = this.toSeconds(time);\n\t this.voice0._triggerEnvelopeAttack(time, velocity);\n\t this.voice1._triggerEnvelopeAttack(time, velocity);\n\t return this;\n\t };\n\t /**\n\t\t * start the release portion of the envelopes\n\t\t *\n\t\t * @param {Time} [time=now] the time the release should start\n\t\t * @returns {Tone.DuoSynth} this\n\t\t * @private\n\t\t */\n\t Tone.DuoSynth.prototype._triggerEnvelopeRelease = function (time) {\n\t this.voice0._triggerEnvelopeRelease(time);\n\t this.voice1._triggerEnvelopeRelease(time);\n\t return this;\n\t };\n\t /**\n\t\t * Get the level of the output at the given time. Measures\n\t\t * the envelope(s) value at the time. \n\t\t * @param {Time} time The time to query the envelope value\n\t\t * @return {NormalRange} The output level between 0-1\n\t\t */\n\t Tone.DuoSynth.prototype.getLevelAtTime = function (time) {\n\t return (this.voice0.getLevelAtTime(time) + this.voice1.getLevelAtTime(time)) / 2;\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.DuoSynth} this\n\t\t */\n\t Tone.DuoSynth.prototype.dispose = function () {\n\t Tone.Monophonic.prototype.dispose.call(this);\n\t this._writable([\n\t 'voice0',\n\t 'voice1',\n\t 'frequency',\n\t 'vibratoAmount',\n\t 'vibratoRate'\n\t ]);\n\t this.voice0.dispose();\n\t this.voice0 = null;\n\t this.voice1.dispose();\n\t this.voice1 = null;\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this._vibratoGain.dispose();\n\t this._vibratoGain = null;\n\t this._vibrato = null;\n\t this.harmonicity.dispose();\n\t this.harmonicity = null;\n\t this.vibratoAmount.dispose();\n\t this.vibratoAmount = null;\n\t this.vibratoRate = null;\n\t return this;\n\t };\n\t return Tone.DuoSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class FMSynth is composed of two Tone.Synths where one Tone.Synth modulates\n\t\t * the frequency of a second Tone.Synth. A lot of spectral content\n\t\t * can be explored using the modulationIndex parameter. Read more about\n\t\t * frequency modulation synthesis on Sound On Sound: [Part 1](https://web.archive.org/web/20160403123704/http://www.soundonsound.com/sos/apr00/articles/synthsecrets.htm), [Part 2](https://web.archive.org/web/20160403115835/http://www.soundonsound.com/sos/may00/articles/synth.htm).\n\t\t * <img src=\"https://docs.google.com/drawings/d/1h0PUDZXPgi4Ikx6bVT6oncrYPLluFKy7lj53puxj-DM/pub?w=902&h=462\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Monophonic}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var fmSynth = new Tone.FMSynth().toMaster();\n\t\t * fmSynth.triggerAttackRelease(\"C5\", \"4n\");\n\t\t */\n\t Tone.FMSynth = function (options) {\n\t options = Tone.defaultArg(options, Tone.FMSynth.defaults);\n\t Tone.Monophonic.call(this, options);\n\t /**\n\t\t\t * The carrier voice.\n\t\t\t * @type {Tone.Synth}\n\t\t\t * @private\n\t\t\t */\n\t this._carrier = new Tone.Synth(options.carrier);\n\t this._carrier.volume.value = -10;\n\t /**\n\t\t\t * The carrier's oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t */\n\t this.oscillator = this._carrier.oscillator;\n\t /**\n\t\t\t * The carrier's envelope\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t */\n\t this.envelope = this._carrier.envelope.set(options.envelope);\n\t /**\n\t\t\t * The modulator voice.\n\t\t\t * @type {Tone.Synth}\n\t\t\t * @private\n\t\t\t */\n\t this._modulator = new Tone.Synth(options.modulator);\n\t this._modulator.volume.value = -10;\n\t /**\n\t\t\t * The modulator's oscillator which is applied\n\t\t\t * to the amplitude of the oscillator\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t */\n\t this.modulation = this._modulator.oscillator.set(options.modulation);\n\t /**\n\t\t\t * The modulator's envelope\n\t\t\t * @type {Tone.Oscillator}\n\t\t\t */\n\t this.modulationEnvelope = this._modulator.envelope.set(options.modulationEnvelope);\n\t /**\n\t\t\t * The frequency control.\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(440, Tone.Type.Frequency);\n\t /**\n\t\t\t * The detune in cents\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(options.detune, Tone.Type.Cents);\n\t /**\n\t\t\t * Harmonicity is the ratio between the two voices. A harmonicity of\n\t\t\t * 1 is no change. Harmonicity = 2 means a change of an octave.\n\t\t\t * @type {Positive}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * //pitch voice1 an octave below voice0\n\t\t\t * synth.harmonicity.value = 0.5;\n\t\t\t */\n\t this.harmonicity = new Tone.Multiply(options.harmonicity);\n\t this.harmonicity.units = Tone.Type.Positive;\n\t /**\n\t\t\t * The modulation index which essentially the depth or amount of the modulation. It is the\n\t\t\t * ratio of the frequency of the modulating signal (mf) to the amplitude of the\n\t\t\t * modulating signal (ma) -- as in ma/mf.\n\t\t\t *\t@type {Positive}\n\t\t\t *\t@signal\n\t\t\t */\n\t this.modulationIndex = new Tone.Multiply(options.modulationIndex);\n\t this.modulationIndex.units = Tone.Type.Positive;\n\t /**\n\t\t\t * the node where the modulation happens\n\t\t\t * @type {GainNode}\n\t\t\t * @private\n\t\t\t */\n\t this._modulationNode = new Tone.Gain(0);\n\t //control the two voices frequency\n\t this.frequency.connect(this._carrier.frequency);\n\t this.frequency.chain(this.harmonicity, this._modulator.frequency);\n\t this.frequency.chain(this.modulationIndex, this._modulationNode);\n\t this.detune.fan(this._carrier.detune, this._modulator.detune);\n\t this._modulator.connect(this._modulationNode.gain);\n\t this._modulationNode.connect(this._carrier.frequency);\n\t this._carrier.connect(this.output);\n\t this._readOnly([\n\t 'frequency',\n\t 'harmonicity',\n\t 'modulationIndex',\n\t 'oscillator',\n\t 'envelope',\n\t 'modulation',\n\t 'modulationEnvelope',\n\t 'detune'\n\t ]);\n\t };\n\t Tone.extend(Tone.FMSynth, Tone.Monophonic);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.FMSynth.defaults = {\n\t 'harmonicity': 3,\n\t 'modulationIndex': 10,\n\t 'detune': 0,\n\t 'oscillator': { 'type': 'sine' },\n\t 'envelope': {\n\t 'attack': 0.01,\n\t 'decay': 0.01,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t },\n\t 'modulation': { 'type': 'square' },\n\t 'modulationEnvelope': {\n\t 'attack': 0.5,\n\t 'decay': 0,\n\t 'sustain': 1,\n\t 'release': 0.5\n\t }\n\t };\n\t /**\n\t\t * \ttrigger the attack portion of the note\n\t\t *\n\t\t * @param {Time} [time=now] the time the note will occur\n\t\t * @param {number} [velocity=1] the velocity of the note\n\t\t * @returns {Tone.FMSynth} this\n\t\t * @private\n\t\t */\n\t Tone.FMSynth.prototype._triggerEnvelopeAttack = function (time, velocity) {\n\t time = this.toSeconds(time);\n\t //the envelopes\n\t this._carrier._triggerEnvelopeAttack(time, velocity);\n\t this._modulator._triggerEnvelopeAttack(time);\n\t return this;\n\t };\n\t /**\n\t\t * trigger the release portion of the note\n\t\t *\n\t\t * @param {Time} [time=now] the time the note will release\n\t\t * @returns {Tone.FMSynth} this\n\t\t * @private\n\t\t */\n\t Tone.FMSynth.prototype._triggerEnvelopeRelease = function (time) {\n\t time = this.toSeconds(time);\n\t this._carrier._triggerEnvelopeRelease(time);\n\t this._modulator._triggerEnvelopeRelease(time);\n\t return this;\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.FMSynth} this\n\t\t */\n\t Tone.FMSynth.prototype.dispose = function () {\n\t Tone.Monophonic.prototype.dispose.call(this);\n\t this._writable([\n\t 'frequency',\n\t 'harmonicity',\n\t 'modulationIndex',\n\t 'oscillator',\n\t 'envelope',\n\t 'modulation',\n\t 'modulationEnvelope',\n\t 'detune'\n\t ]);\n\t this._carrier.dispose();\n\t this._carrier = null;\n\t this._modulator.dispose();\n\t this._modulator = null;\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this.detune.dispose();\n\t this.detune = null;\n\t this.modulationIndex.dispose();\n\t this.modulationIndex = null;\n\t this.harmonicity.dispose();\n\t this.harmonicity = null;\n\t this._modulationNode.dispose();\n\t this._modulationNode = null;\n\t this.oscillator = null;\n\t this.envelope = null;\n\t this.modulationEnvelope = null;\n\t this.modulation = null;\n\t return this;\n\t };\n\t return Tone.FMSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.MembraneSynth makes kick and tom sounds using a single oscillator\n\t\t * with an amplitude envelope and frequency ramp. A Tone.OmniOscillator\n\t\t * is routed through a Tone.AmplitudeEnvelope to the output. The drum\n\t\t * quality of the sound comes from the frequency envelope applied\n\t\t * during Tone.MembraneSynth.triggerAttack(note). The frequency envelope\n\t\t * starts at <code>note * .octaves</code> and ramps to <code>note</code>\n\t\t * over the duration of <code>.pitchDecay</code>.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Instrument}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var synth = new Tone.MembraneSynth().toMaster();\n\t\t * synth.triggerAttackRelease(\"C2\", \"8n\");\n\t\t */\n\t Tone.MembraneSynth = function (options) {\n\t options = Tone.defaultArg(options, Tone.MembraneSynth.defaults);\n\t Tone.Instrument.call(this, options);\n\t /**\n\t\t\t * The oscillator.\n\t\t\t * @type {Tone.OmniOscillator}\n\t\t\t */\n\t this.oscillator = new Tone.OmniOscillator(options.oscillator);\n\t /**\n\t\t\t * The amplitude envelope.\n\t\t\t * @type {Tone.AmplitudeEnvelope}\n\t\t\t */\n\t this.envelope = new Tone.AmplitudeEnvelope(options.envelope);\n\t /**\n\t\t\t * The number of octaves the pitch envelope ramps.\n\t\t\t * @type {Positive}\n\t\t\t */\n\t this.octaves = options.octaves;\n\t /**\n\t\t\t * The amount of time the frequency envelope takes.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.pitchDecay = options.pitchDecay;\n\t this.oscillator.chain(this.envelope, this.output);\n\t this._readOnly([\n\t 'oscillator',\n\t 'envelope'\n\t ]);\n\t };\n\t Tone.extend(Tone.MembraneSynth, Tone.Instrument);\n\t /**\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.MembraneSynth.defaults = {\n\t 'pitchDecay': 0.05,\n\t 'octaves': 10,\n\t 'oscillator': { 'type': 'sine' },\n\t 'envelope': {\n\t 'attack': 0.001,\n\t 'decay': 0.4,\n\t 'sustain': 0.01,\n\t 'release': 1.4,\n\t 'attackCurve': 'exponential'\n\t }\n\t };\n\t /**\n\t\t * Trigger the note at the given time with the given velocity.\n\t\t *\n\t\t * @param {Frequency} note the note\n\t\t * @param {Time} [time=now] the time, if not given is now\n\t\t * @param {number} [velocity=1] velocity defaults to 1\n\t\t * @returns {Tone.MembraneSynth} this\n\t\t * @example\n\t\t * kick.triggerAttack(60);\n\t\t */\n\t Tone.MembraneSynth.prototype.triggerAttack = function (note, time, velocity) {\n\t time = this.toSeconds(time);\n\t note = this.toFrequency(note);\n\t var maxNote = note * this.octaves;\n\t this.oscillator.frequency.setValueAtTime(maxNote, time);\n\t this.oscillator.frequency.exponentialRampToValueAtTime(note, time + this.toSeconds(this.pitchDecay));\n\t this.envelope.triggerAttack(time, velocity);\n\t this.oscillator.start(time);\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the release portion of the note.\n\t\t *\n\t\t * @param {Time} [time=now] the time the note will release\n\t\t * @returns {Tone.MembraneSynth} this\n\t\t */\n\t Tone.MembraneSynth.prototype.triggerRelease = function (time) {\n\t time = this.toSeconds(time);\n\t this.envelope.triggerRelease(time);\n\t this.oscillator.stop(time + this.envelope.release);\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.MembraneSynth} this\n\t\t */\n\t Tone.MembraneSynth.prototype.dispose = function () {\n\t Tone.Instrument.prototype.dispose.call(this);\n\t this._writable([\n\t 'oscillator',\n\t 'envelope'\n\t ]);\n\t this.oscillator.dispose();\n\t this.oscillator = null;\n\t this.envelope.dispose();\n\t this.envelope = null;\n\t return this;\n\t };\n\t return Tone.MembraneSynth;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * Inharmonic ratio of frequencies based on the Roland TR-808\n\t\t * Taken from https://ccrma.stanford.edu/papers/tr-808-cymbal-physically-informed-circuit-bendable-digital-model\n\t\t * @private\n\t\t * @static\n\t\t * @type {Array}\n\t\t */\n\t var inharmRatios = [\n\t 1,\n\t 1.483,\n\t 1.932,\n\t 2.546,\n\t 2.63,\n\t 3.897\n\t ];\n\t /**\n\t\t * @class A highly inharmonic and spectrally complex source with a highpass filter\n\t\t * and amplitude envelope which is good for making metalophone sounds. Based\n\t\t * on CymbalSynth by [@polyrhythmatic](https://github.com/polyrhythmatic).\n\t\t * Inspiration from [Sound on Sound](https://web.archive.org/web/20160610143924/https://www.soundonsound.com/sos/jul02/articles/synthsecrets0702.asp).\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Instrument}\n\t\t * @param {Object} [options] The options availble for the synth\n\t\t * see defaults below\n\t\t */\n\t Tone.MetalSynth = function (options) {\n\t options = Tone.defaultArg(options, Tone.MetalSynth.defaults);\n\t Tone.Instrument.call(this, options);\n\t /**\n\t\t\t * The frequency of the cymbal\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency);\n\t /**\n\t\t\t * The array of FMOscillators\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._oscillators = [];\n\t /**\n\t\t\t * The frequency multipliers\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._freqMultipliers = [];\n\t /**\n\t\t\t * The amplitude for the body\n\t\t\t * @type {Tone.Gain}\n\t\t\t * @private\n\t\t\t */\n\t this._amplitue = new Tone.Gain(0).connect(this.output);\n\t /**\n\t\t\t * highpass the output\n\t\t\t * @type {Tone.Filter}\n\t\t\t * @private\n\t\t\t */\n\t this._highpass = new Tone.Filter({\n\t 'type': 'highpass',\n\t 'Q': -3.0102999566398125\n\t }).connect(this._amplitue);\n\t /**\n\t\t\t * The number of octaves the highpass\n\t\t\t * filter frequency ramps\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._octaves = options.octaves;\n\t /**\n\t\t\t * Scale the body envelope\n\t\t\t * for the bandpass\n\t\t\t * @type {Tone.Scale}\n\t\t\t * @private\n\t\t\t */\n\t this._filterFreqScaler = new Tone.Scale(options.resonance, 7000);\n\t /**\n\t\t\t * The envelope which is connected both to the\n\t\t\t * amplitude and highpass filter's cutoff frequency\n\t\t\t * @type {Tone.Envelope}\n\t\t\t */\n\t this.envelope = new Tone.Envelope({\n\t 'attack': options.envelope.attack,\n\t 'attackCurve': 'linear',\n\t 'decay': options.envelope.decay,\n\t 'sustain': 0,\n\t 'release': options.envelope.release\n\t }).chain(this._filterFreqScaler, this._highpass.frequency);\n\t this.envelope.connect(this._amplitue.gain);\n\t for (var i = 0; i < inharmRatios.length; i++) {\n\t var osc = new Tone.FMOscillator({\n\t 'type': 'square',\n\t 'modulationType': 'square',\n\t 'harmonicity': options.harmonicity,\n\t 'modulationIndex': options.modulationIndex\n\t });\n\t osc.connect(this._highpass);\n\t this._oscillators[i] = osc;\n\t var mult = new Tone.Multiply(inharmRatios[i]);\n\t this._freqMultipliers[i] = mult;\n\t this.frequency.chain(mult, osc.frequency);\n\t }\n\t //set the octaves\n\t this.octaves = options.octaves;\n\t };\n\t Tone.extend(Tone.MetalSynth, Tone.Instrument);\n\t /**\n\t\t * default values\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.MetalSynth.defaults = {\n\t 'frequency': 200,\n\t 'envelope': {\n\t 'attack': 0.001,\n\t 'decay': 1.4,\n\t 'release': 0.2\n\t },\n\t 'harmonicity': 5.1,\n\t 'modulationIndex': 32,\n\t 'resonance': 4000,\n\t 'octaves': 1.5\n\t };\n\t /**\n\t\t * Trigger the attack.\n\t\t * @param {Time} time When the attack should be triggered.\n\t\t * @param {NormalRange} [velocity=1] The velocity that the envelope should be triggered at.\n\t\t * @return {Tone.MetalSynth} this\n\t\t */\n\t Tone.MetalSynth.prototype.triggerAttack = function (time, vel) {\n\t time = this.toSeconds(time);\n\t vel = Tone.defaultArg(vel, 1);\n\t this.envelope.triggerAttack(time, vel);\n\t this._oscillators.forEach(function (osc) {\n\t osc.start(time);\n\t });\n\t //if the sustain is 0, stop the oscillator as well\n\t if (this.envelope.sustain === 0) {\n\t this._oscillators.forEach(function (osc) {\n\t osc.stop(time + this.envelope.attack + this.envelope.decay);\n\t }.bind(this));\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the release of the envelope.\n\t\t * @param {Time} time When the release should be triggered.\n\t\t * @return {Tone.MetalSynth} this\n\t\t */\n\t Tone.MetalSynth.prototype.triggerRelease = function (time) {\n\t time = this.toSeconds(time);\n\t this.envelope.triggerRelease(time);\n\t this._oscillators.forEach(function (osc) {\n\t osc.stop(time + this.envelope.release);\n\t }.bind(this));\n\t return this;\n\t };\n\t /**\n\t\t * Sync the instrument to the Transport. All subsequent calls of\n\t\t * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease)\n\t\t * will be scheduled along the transport.\n\t\t * @example\n\t\t * synth.sync()\n\t\t * //schedule 3 notes when the transport first starts\n\t\t * synth.triggerAttackRelease('8n', 0)\n\t\t * synth.triggerAttackRelease('8n', '8n')\n\t\t * synth.triggerAttackRelease('8n', '4n')\n\t\t * //start the transport to hear the notes\n\t\t * Transport.start()\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.MetalSynth.prototype.sync = function () {\n\t this._syncMethod('triggerAttack', 0);\n\t this._syncMethod('triggerRelease', 0);\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the attack and release of the envelope after the given\n\t\t * duration.\n\t\t * @param {Time} duration The duration before triggering the release\n\t\t * @param {Time} time When the attack should be triggered.\n\t\t * @param {NormalRange} [velocity=1] The velocity that the envelope should be triggered at.\n\t\t * @return {Tone.MetalSynth} this\n\t\t */\n\t Tone.MetalSynth.prototype.triggerAttackRelease = function (duration, time, velocity) {\n\t time = this.toSeconds(time);\n\t duration = this.toSeconds(duration);\n\t this.triggerAttack(time, velocity);\n\t this.triggerRelease(time + duration);\n\t return this;\n\t };\n\t /**\n\t\t * The modulationIndex of the oscillators which make up the source.\n\t\t * see Tone.FMOscillator.modulationIndex\n\t\t * @memberOf Tone.MetalSynth#\n\t\t * @type {Positive}\n\t\t * @name modulationIndex\n\t\t */\n\t Object.defineProperty(Tone.MetalSynth.prototype, 'modulationIndex', {\n\t get: function () {\n\t return this._oscillators[0].modulationIndex.value;\n\t },\n\t set: function (val) {\n\t for (var i = 0; i < this._oscillators.length; i++) {\n\t this._oscillators[i].modulationIndex.value = val;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The harmonicity of the oscillators which make up the source.\n\t\t * see Tone.FMOscillator.harmonicity\n\t\t * @memberOf Tone.MetalSynth#\n\t\t * @type {Positive}\n\t\t * @name harmonicity\n\t\t */\n\t Object.defineProperty(Tone.MetalSynth.prototype, 'harmonicity', {\n\t get: function () {\n\t return this._oscillators[0].harmonicity.value;\n\t },\n\t set: function (val) {\n\t for (var i = 0; i < this._oscillators.length; i++) {\n\t this._oscillators[i].harmonicity.value = val;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The frequency of the highpass filter attached to the envelope\n\t\t * @memberOf Tone.MetalSynth#\n\t\t * @type {Frequency}\n\t\t * @name resonance\n\t\t */\n\t Object.defineProperty(Tone.MetalSynth.prototype, 'resonance', {\n\t get: function () {\n\t return this._filterFreqScaler.min;\n\t },\n\t set: function (val) {\n\t this._filterFreqScaler.min = val;\n\t this.octaves = this._octaves;\n\t }\n\t });\n\t /**\n\t\t * The number of octaves above the \"resonance\" frequency\n\t\t * that the filter ramps during the attack/decay envelope\n\t\t * @memberOf Tone.MetalSynth#\n\t\t * @type {Number}\n\t\t * @name octaves\n\t\t */\n\t Object.defineProperty(Tone.MetalSynth.prototype, 'octaves', {\n\t get: function () {\n\t return this._octaves;\n\t },\n\t set: function (octs) {\n\t this._octaves = octs;\n\t this._filterFreqScaler.max = this._filterFreqScaler.min * Math.pow(2, octs);\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @returns {Tone.MetalSynth} this\n\t\t */\n\t Tone.MetalSynth.prototype.dispose = function () {\n\t Tone.Instrument.prototype.dispose.call(this);\n\t for (var i = 0; i < this._oscillators.length; i++) {\n\t this._oscillators[i].dispose();\n\t this._freqMultipliers[i].dispose();\n\t }\n\t this._oscillators = null;\n\t this._freqMultipliers = null;\n\t this.frequency.dispose();\n\t this.frequency = null;\n\t this._filterFreqScaler.dispose();\n\t this._filterFreqScaler = null;\n\t this._amplitue.dispose();\n\t this._amplitue = null;\n\t this.envelope.dispose();\n\t this.envelope = null;\n\t this._highpass.dispose();\n\t this._highpass = null;\n\t };\n\t return Tone.MetalSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.NoiseSynth is composed of a noise generator (Tone.Noise), one filter (Tone.Filter),\n\t\t * and two envelopes (Tone.Envelop). One envelope controls the amplitude\n\t\t * of the noise and the other is controls the cutoff frequency of the filter.\n\t\t * <img src=\"https://docs.google.com/drawings/d/1rqzuX9rBlhT50MRvD2TKml9bnZhcZmzXF1rf_o7vdnE/pub?w=918&h=242\">\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Instrument}\n\t\t * @param {Object} [options] the options available for the synth\n\t\t * see defaults below\n\t\t * @example\n\t\t * var noiseSynth = new Tone.NoiseSynth().toMaster();\n\t\t * noiseSynth.triggerAttackRelease(\"8n\");\n\t\t */\n\t Tone.NoiseSynth = function (options) {\n\t //get the defaults\n\t options = Tone.defaultArg(options, Tone.NoiseSynth.defaults);\n\t Tone.Instrument.call(this, options);\n\t /**\n\t\t\t * The noise source.\n\t\t\t * @type {Tone.Noise}\n\t\t\t * @example\n\t\t\t * noiseSynth.set(\"noise.type\", \"brown\");\n\t\t\t */\n\t this.noise = new Tone.Noise();\n\t /**\n\t\t\t * The amplitude envelope.\n\t\t\t * @type {Tone.AmplitudeEnvelope}\n\t\t\t */\n\t this.envelope = new Tone.AmplitudeEnvelope(options.envelope);\n\t //connect the noise to the output\n\t this.noise.chain(this.envelope, this.output);\n\t this._readOnly([\n\t 'noise',\n\t 'envelope'\n\t ]);\n\t };\n\t Tone.extend(Tone.NoiseSynth, Tone.Instrument);\n\t /**\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.NoiseSynth.defaults = {\n\t 'noise': { 'type': 'white' },\n\t 'envelope': {\n\t 'attack': 0.005,\n\t 'decay': 0.1,\n\t 'sustain': 0\n\t }\n\t };\n\t /**\n\t\t * Start the attack portion of the envelopes. Unlike other\n\t\t * instruments, Tone.NoiseSynth doesn't have a note.\n\t\t * @param {Time} [time=now] the time the attack should start\n\t\t * @param {number} [velocity=1] the velocity of the note (0-1)\n\t\t * @returns {Tone.NoiseSynth} this\n\t\t * @example\n\t\t * noiseSynth.triggerAttack();\n\t\t */\n\t Tone.NoiseSynth.prototype.triggerAttack = function (time, velocity) {\n\t //the envelopes\n\t this.envelope.triggerAttack(time, velocity);\n\t //start the noise\n\t this.noise.start(time);\n\t if (this.envelope.sustain === 0) {\n\t this.noise.stop(time = this.envelope.attack + this.envelope.decay);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Start the release portion of the envelopes.\n\t\t * @param {Time} [time=now] the time the release should start\n\t\t * @returns {Tone.NoiseSynth} this\n\t\t */\n\t Tone.NoiseSynth.prototype.triggerRelease = function (time) {\n\t this.envelope.triggerRelease(time);\n\t this.noise.stop(time + this.envelope.release);\n\t return this;\n\t };\n\t /**\n\t\t * Sync the instrument to the Transport. All subsequent calls of\n\t\t * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease)\n\t\t * will be scheduled along the transport.\n\t\t * @example\n\t\t * synth.sync()\n\t\t * //schedule 3 notes when the transport first starts\n\t\t * synth.triggerAttackRelease('8n', 0)\n\t\t * synth.triggerAttackRelease('8n', '8n')\n\t\t * synth.triggerAttackRelease('8n', '4n')\n\t\t * //start the transport to hear the notes\n\t\t * Transport.start()\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.NoiseSynth.prototype.sync = function () {\n\t this._syncMethod('triggerAttack', 0);\n\t this._syncMethod('triggerRelease', 0);\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the attack and then the release.\n\t\t * @param {Time} duration the duration of the note\n\t\t * @param {Time} [time=now] the time of the attack\n\t\t * @param {number} [velocity=1] the velocity\n\t\t * @returns {Tone.NoiseSynth} this\n\t\t */\n\t Tone.NoiseSynth.prototype.triggerAttackRelease = function (duration, time, velocity) {\n\t time = this.toSeconds(time);\n\t duration = this.toSeconds(duration);\n\t this.triggerAttack(time, velocity);\n\t this.triggerRelease(time + duration);\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.NoiseSynth} this\n\t\t */\n\t Tone.NoiseSynth.prototype.dispose = function () {\n\t Tone.Instrument.prototype.dispose.call(this);\n\t this._writable([\n\t 'noise',\n\t 'envelope'\n\t ]);\n\t this.noise.dispose();\n\t this.noise = null;\n\t this.envelope.dispose();\n\t this.envelope = null;\n\t return this;\n\t };\n\t return Tone.NoiseSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Karplus-String string synthesis. Often out of tune.\n\t\t * Will change when the AudioWorkerNode is available across\n\t\t * browsers.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Instrument}\n\t\t * @param {Object} [options] see the defaults\n\t\t * @example\n\t\t * var plucky = new Tone.PluckSynth().toMaster();\n\t\t * plucky.triggerAttack(\"C4\");\n\t\t */\n\t Tone.PluckSynth = function (options) {\n\t options = Tone.defaultArg(options, Tone.PluckSynth.defaults);\n\t Tone.Instrument.call(this, options);\n\t /**\n\t\t\t * @type {Tone.Noise}\n\t\t\t * @private\n\t\t\t */\n\t this._noise = new Tone.Noise('pink');\n\t /**\n\t\t\t * The amount of noise at the attack.\n\t\t\t * Nominal range of [0.1, 20]\n\t\t\t * @type {number}\n\t\t\t */\n\t this.attackNoise = options.attackNoise;\n\t /**\n\t\t\t * the LFCF\n\t\t\t * @type {Tone.LowpassCombFilter}\n\t\t\t * @private\n\t\t\t */\n\t this._lfcf = new Tone.LowpassCombFilter({\n\t 'resonance': options.resonance,\n\t 'dampening': options.dampening\n\t });\n\t /**\n\t\t\t * The resonance control.\n\t\t\t * @type {NormalRange}\n\t\t\t * @signal\n\t\t\t */\n\t this.resonance = this._lfcf.resonance;\n\t /**\n\t\t\t * The dampening control. i.e. the lowpass filter frequency of the comb filter\n\t\t\t * @type {Frequency}\n\t\t\t * @signal\n\t\t\t */\n\t this.dampening = this._lfcf.dampening;\n\t //connections\n\t this._noise.connect(this._lfcf);\n\t this._lfcf.connect(this.output);\n\t this._readOnly([\n\t 'resonance',\n\t 'dampening'\n\t ]);\n\t };\n\t Tone.extend(Tone.PluckSynth, Tone.Instrument);\n\t /**\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.PluckSynth.defaults = {\n\t 'attackNoise': 1,\n\t 'dampening': 4000,\n\t 'resonance': 0.7\n\t };\n\t /**\n\t\t * Trigger the note.\n\t\t * @param {Frequency} note The note to trigger.\n\t\t * @param {Time} [time=now] When the note should be triggered.\n\t\t * @returns {Tone.PluckSynth} this\n\t\t */\n\t Tone.PluckSynth.prototype.triggerAttack = function (note, time) {\n\t note = this.toFrequency(note);\n\t time = this.toSeconds(time);\n\t var delayAmount = 1 / note;\n\t this._lfcf.delayTime.setValueAtTime(delayAmount, time);\n\t this._noise.start(time);\n\t this._noise.stop(time + delayAmount * this.attackNoise);\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.PluckSynth} this\n\t\t */\n\t Tone.PluckSynth.prototype.dispose = function () {\n\t Tone.Instrument.prototype.dispose.call(this);\n\t this._noise.dispose();\n\t this._lfcf.dispose();\n\t this._noise = null;\n\t this._lfcf = null;\n\t this._writable([\n\t 'resonance',\n\t 'dampening'\n\t ]);\n\t this.dampening = null;\n\t this.resonance = null;\n\t return this;\n\t };\n\t return Tone.PluckSynth;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.PolySynth handles voice creation and allocation for any\n\t\t * instruments passed in as the second paramter. PolySynth is\n\t\t * not a synthesizer by itself, it merely manages voices of\n\t\t * one of the other types of synths, allowing any of the\n\t\t * monophonic synthesizers to be polyphonic.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Instrument}\n\t\t * @param {number|Object} [polyphony=4] The number of voices to create\n\t\t * @param {function} [voice=Tone.Synth] The constructor of the voices\n\t\t * uses Tone.Synth by default.\n\t\t * @example\n\t\t * //a polysynth composed of 6 Voices of Synth\n\t\t * var synth = new Tone.PolySynth(6, Tone.Synth).toMaster();\n\t\t * //set the attributes using the set interface\n\t\t * synth.set(\"detune\", -1200);\n\t\t * //play a chord\n\t\t * synth.triggerAttackRelease([\"C4\", \"E4\", \"A4\"], \"4n\");\n\t\t */\n\t Tone.PolySynth = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'polyphony',\n\t 'voice'\n\t ], Tone.PolySynth);\n\t Tone.Instrument.call(this, options);\n\t options = Tone.defaultArg(options, Tone.Instrument.defaults);\n\t //max polyphony\n\t options.polyphony = Math.min(Tone.PolySynth.MAX_POLYPHONY, options.polyphony);\n\t /**\n\t\t\t * the array of voices\n\t\t\t * @type {Array}\n\t\t\t */\n\t this.voices = new Array(options.polyphony);\n\t /**\n\t\t\t * The queue of voices with data about last trigger\n\t\t\t * and the triggered note\n\t\t\t * @private\n\t\t\t * @type {Array}\n\t\t\t */\n\t this._triggers = new Array(options.polyphony);\n\t /**\n\t\t\t * The detune in cents\n\t\t\t * @type {Cents}\n\t\t\t * @signal\n\t\t\t */\n\t this.detune = new Tone.Signal(options.detune, Tone.Type.Cents);\n\t this._readOnly('detune');\n\t //create the voices\n\t for (var i = 0; i < options.polyphony; i++) {\n\t var v = new options.voice(arguments[2], arguments[3]);\n\t if (!(v instanceof Tone.Monophonic)) {\n\t throw new Error('Synth constructor must be instance of Tone.Monophonic');\n\t }\n\t this.voices[i] = v;\n\t v.connect(this.output);\n\t if (v.hasOwnProperty('detune')) {\n\t this.detune.connect(v.detune);\n\t }\n\t this._triggers[i] = {\n\t release: -1,\n\t note: null,\n\t voice: v\n\t };\n\t }\n\t };\n\t Tone.extend(Tone.PolySynth, Tone.Instrument);\n\t /**\n\t\t * the defaults\n\t\t * @const\n\t\t * @static\n\t\t * @type {Object}\n\t\t */\n\t Tone.PolySynth.defaults = {\n\t 'polyphony': 4,\n\t 'volume': 0,\n\t 'detune': 0,\n\t 'voice': Tone.Synth\n\t };\n\t /**\n\t\t * Trigger the attack portion of the note\n\t\t * @param {Frequency|Array} notes The notes to play. Accepts a single\n\t\t * Frequency or an array of frequencies.\n\t\t * @param {Time} [time=now] The start time of the note.\n\t\t * @param {number} [velocity=1] The velocity of the note.\n\t\t * @returns {Tone.PolySynth} this\n\t\t * @example\n\t\t * //trigger a chord immediately with a velocity of 0.2\n\t\t * poly.triggerAttack([\"Ab3\", \"C4\", \"F5\"], undefined, 0.2);\n\t\t */\n\t Tone.PolySynth.prototype.triggerAttack = function (notes, time, velocity) {\n\t if (!Array.isArray(notes)) {\n\t notes = [notes];\n\t }\n\t time = this.toSeconds(time);\n\t for (var i = 0; i < notes.length; i++) {\n\t var val = notes[i];\n\t //trigger the oldest voice\n\t var oldest = this._triggers[0];\n\t for (var j = 1; j < this._triggers.length; j++) {\n\t if (this._triggers[j].release < oldest.release) {\n\t oldest = this._triggers[j];\n\t }\n\t }\n\t oldest.release = Infinity;\n\t oldest.note = JSON.stringify(val);\n\t oldest.voice.triggerAttack(val, time, velocity);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the attack and release after the specified duration\n\t\t *\n\t\t * @param {Frequency|Array} notes The notes to play. Accepts a single\n\t\t * Frequency or an array of frequencies.\n\t\t * @param {Time} duration the duration of the note\n\t\t * @param {Time} [time=now] if no time is given, defaults to now\n\t\t * @param {number} [velocity=1] the velocity of the attack (0-1)\n\t\t * @returns {Tone.PolySynth} this\n\t\t * @example\n\t\t * //trigger a chord for a duration of a half note\n\t\t * poly.triggerAttackRelease([\"Eb3\", \"G4\", \"C5\"], \"2n\");\n\t\t * @example\n\t\t * //can pass in an array of durations as well\n\t\t * poly.triggerAttackRelease([\"Eb3\", \"G4\", \"C5\"], [\"2n\", \"4n\", \"4n\"]);\n\t\t */\n\t Tone.PolySynth.prototype.triggerAttackRelease = function (notes, duration, time, velocity) {\n\t time = this.toSeconds(time);\n\t this.triggerAttack(notes, time, velocity);\n\t if (Tone.isArray(duration) && Tone.isArray(notes)) {\n\t for (var i = 0; i < notes.length; i++) {\n\t var d = duration[Math.min(i, duration.length - 1)];\n\t this.triggerRelease(notes[i], time + this.toSeconds(d));\n\t }\n\t } else {\n\t this.triggerRelease(notes, time + this.toSeconds(duration));\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Trigger the release of the note. Unlike monophonic instruments,\n\t\t * a note (or array of notes) needs to be passed in as the first argument.\n\t\t * @param {Frequency|Array} notes The notes to play. Accepts a single\n\t\t * Frequency or an array of frequencies.\n\t\t * @param {Time} [time=now] When the release will be triggered.\n\t\t * @returns {Tone.PolySynth} this\n\t\t * @example\n\t\t * poly.triggerRelease([\"Ab3\", \"C4\", \"F5\"], \"+2n\");\n\t\t */\n\t Tone.PolySynth.prototype.triggerRelease = function (notes, time) {\n\t if (!Array.isArray(notes)) {\n\t notes = [notes];\n\t }\n\t time = this.toSeconds(time);\n\t for (var i = 0; i < notes.length; i++) {\n\t //get the voice\n\t var stringified = JSON.stringify(notes[i]);\n\t for (var v = 0; v < this._triggers.length; v++) {\n\t var desc = this._triggers[v];\n\t if (desc.note === stringified && desc.release > time) {\n\t desc.voice.triggerRelease(time);\n\t desc.release = time;\n\t }\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Sync the instrument to the Transport. All subsequent calls of\n\t\t * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease)\n\t\t * will be scheduled along the transport.\n\t\t * @example\n\t\t * synth.sync()\n\t\t * //schedule 3 notes when the transport first starts\n\t\t * synth.triggerAttackRelease('8n', 0)\n\t\t * synth.triggerAttackRelease('8n', '8n')\n\t\t * synth.triggerAttackRelease('8n', '4n')\n\t\t * //start the transport to hear the notes\n\t\t * Transport.start()\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.PolySynth.prototype.sync = function () {\n\t this._syncMethod('triggerAttack', 1);\n\t this._syncMethod('triggerRelease', 1);\n\t return this;\n\t };\n\t /**\n\t\t * Set a member/attribute of the voices.\n\t\t * @param {Object|string} params\n\t\t * @param {number=} value\n\t\t * @param {Time=} rampTime\n\t\t * @returns {Tone.PolySynth} this\n\t\t * @example\n\t\t * poly.set({\n\t\t * \t\"filter\" : {\n\t\t * \t\t\"type\" : \"highpass\"\n\t\t * \t},\n\t\t * \t\"envelope\" : {\n\t\t * \t\t\"attack\" : 0.25\n\t\t * \t}\n\t\t * });\n\t\t */\n\t Tone.PolySynth.prototype.set = function (params, value, rampTime) {\n\t for (var i = 0; i < this.voices.length; i++) {\n\t this.voices[i].set(params, value, rampTime);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Get the synth's attributes. Given no arguments get\n\t\t * will return all available object properties and their corresponding\n\t\t * values. Pass in a single attribute to retrieve or an array\n\t\t * of attributes. The attribute strings can also include a \".\"\n\t\t * to access deeper properties.\n\t\t * @param {Array=} params the parameters to get, otherwise will return\n\t\t * \t\t\t\t\t all available.\n\t\t */\n\t Tone.PolySynth.prototype.get = function (params) {\n\t return this.voices[0].get(params);\n\t };\n\t /**\n\t\t * Trigger the release portion of all the currently active voices.\n\t\t * @param {Time} [time=now] When the notes should be released.\n\t\t * @return {Tone.PolySynth} this\n\t\t */\n\t Tone.PolySynth.prototype.releaseAll = function (time) {\n\t time = this.toSeconds(time);\n\t for (var i = 0; i < this._triggers.length; i++) {\n\t var desc = this._triggers[i];\n\t if (desc.release > time) {\n\t desc.release = time;\n\t desc.voice.triggerRelease(time);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Clean up.\n\t\t * @returns {Tone.PolySynth} this\n\t\t */\n\t Tone.PolySynth.prototype.dispose = function () {\n\t Tone.Instrument.prototype.dispose.call(this);\n\t for (var i = 0; i < this.voices.length; i++) {\n\t this.voices[i].dispose();\n\t this.voices[i] = null;\n\t }\n\t this._writable('detune');\n\t this.detune.dispose();\n\t this.detune = null;\n\t this.voices = null;\n\t this._triggers = null;\n\t return this;\n\t };\n\t /**\n\t\t * The maximum number of notes that can be allocated\n\t\t * to a polysynth.\n\t\t * @type {Number}\n\t\t * @static\n\t\t */\n\t Tone.PolySynth.MAX_POLYPHONY = 20;\n\t return Tone.PolySynth;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Automatically interpolates between a set of pitched samples. Pass in an object which maps the note's pitch or midi value to the url, then you can trigger the attack and release of that note like other instruments. By automatically repitching the samples, it is possible to play pitches which were not explicitly included which can save loading time.\n\t\t * For sample or buffer playback where repitching is not necessary, use [Tone.Player](https://tonejs.github.io/docs/Player).\n\t\t * @param {Object} samples An object of samples mapping either Midi\n\t\t * Note Numbers or Scientific Pitch Notation\n\t\t * to the url of that sample.\n\t\t * @param {Function=} onload The callback to invoke when all of the samples are loaded.\n\t\t * @param {String=} baseUrl The root URL of all of the samples, which is prepended to all the URLs.\n\t\t * @example\n\t\t * var sampler = new Tone.Sampler({\n\t\t * \t\"C3\" : \"path/to/C3.mp3\",\n\t\t * \t\"D#3\" : \"path/to/Dsharp3.mp3\",\n\t\t * \t\"F#3\" : \"path/to/Fsharp3.mp3\",\n\t\t * \t\"A3\" : \"path/to/A3.mp3\",\n\t\t * }, function(){\n\t\t * \t//sampler will repitch the closest sample\n\t\t * \tsampler.triggerAttack(\"D3\")\n\t\t * })\n\t\t * @extends {Tone.Instrument}\n\t\t */\n\t Tone.Sampler = function (urls) {\n\t // shift arguments over one. Those are the remainder of the options\n\t var args = Array.prototype.slice.call(arguments);\n\t args.shift();\n\t var options = Tone.defaults(args, [\n\t 'onload',\n\t 'baseUrl'\n\t ], Tone.Sampler);\n\t Tone.Instrument.call(this, options);\n\t var urlMap = {};\n\t for (var note in urls) {\n\t if (Tone.isNote(note)) {\n\t //convert the note name to MIDI\n\t var mid = Tone.Frequency(note).toMidi();\n\t urlMap[mid] = urls[note];\n\t } else if (!isNaN(parseFloat(note))) {\n\t //otherwise if it's numbers assume it's midi\n\t urlMap[note] = urls[note];\n\t } else {\n\t throw new Error('Tone.Sampler: url keys must be the note\\'s pitch');\n\t }\n\t }\n\t /**\n\t\t\t * The stored and loaded buffers\n\t\t\t * @type {Tone.Buffers}\n\t\t\t * @private\n\t\t\t */\n\t this._buffers = new Tone.Buffers(urlMap, options.onload, options.baseUrl);\n\t /**\n\t\t\t * The object of all currently playing BufferSources\n\t\t\t * @type {Object}\n\t\t\t * @private\n\t\t\t */\n\t this._activeSources = {};\n\t /**\n\t\t\t * The envelope applied to the beginning of the sample.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.attack = options.attack;\n\t /**\n\t\t\t * The envelope applied to the end of the envelope.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.release = options.release;\n\t };\n\t Tone.extend(Tone.Sampler, Tone.Instrument);\n\t /**\n\t\t * The defaults\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Sampler.defaults = {\n\t attack: 0,\n\t release: 0.1,\n\t onload: Tone.noOp,\n\t baseUrl: ''\n\t };\n\t /**\n\t\t * Returns the difference in steps between the given midi note at the closets sample.\n\t\t * @param {Midi} midi\n\t\t * @return {Interval}\n\t\t * @private\n\t\t */\n\t Tone.Sampler.prototype._findClosest = function (midi) {\n\t //searches within 8 octaves of the given midi note\n\t var MAX_INTERVAL = 96;\n\t var interval = 0;\n\t while (interval < MAX_INTERVAL) {\n\t // check above and below\n\t if (this._buffers.has(midi + interval)) {\n\t return -interval;\n\t } else if (this._buffers.has(midi - interval)) {\n\t return interval;\n\t }\n\t interval++;\n\t }\n\t return null;\n\t };\n\t /**\n\t\t * @param {Frequency} note The note to play\n\t\t * @param {Time=} time When to play the note\n\t\t * @param {NormalRange=} velocity The velocity to play the sample back.\n\t\t * @return {Tone.Sampler} this\n\t\t */\n\t Tone.Sampler.prototype.triggerAttack = function (note, time, velocity) {\n\t var midi = Tone.Frequency(note).toMidi();\n\t // find the closest note pitch\n\t var difference = this._findClosest(midi);\n\t if (difference !== null) {\n\t var closestNote = midi - difference;\n\t var buffer = this._buffers.get(closestNote);\n\t // play that note\n\t var source = new Tone.BufferSource({\n\t 'buffer': buffer,\n\t 'playbackRate': Tone.intervalToFrequencyRatio(difference),\n\t 'fadeIn': this.attack,\n\t 'fadeOut': this.release,\n\t 'curve': 'exponential'\n\t }).connect(this.output);\n\t source.start(time, 0, buffer.duration, velocity);\n\t // add it to the active sources\n\t if (!Tone.isArray(this._activeSources[midi])) {\n\t this._activeSources[midi] = [];\n\t }\n\t this._activeSources[midi].push({\n\t note: midi,\n\t source: source\n\t });\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * @param {Frequency} note The note to release.\n\t\t * @param {Time=} time \tWhen to release the note.\n\t\t * @return {Tone.Sampler}\tthis\n\t\t */\n\t Tone.Sampler.prototype.triggerRelease = function (note, time) {\n\t var midi = Tone.Frequency(note).toMidi();\n\t // find the note\n\t if (this._activeSources[midi] && this._activeSources[midi].length) {\n\t var source = this._activeSources[midi].shift().source;\n\t time = this.toSeconds(time);\n\t source.stop(time + this.release, this.release);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Release all currently active notes.\n\t\t * @param {Time=} time \tWhen to release the notes.\n\t\t * @return {Tone.Sampler}\tthis\n\t\t */\n\t Tone.Sampler.prototype.releaseAll = function (time) {\n\t time = this.toSeconds(time);\n\t for (var note in this._activeSources) {\n\t var sources = this._activeSources[note];\n\t while (sources.length) {\n\t var source = sources.shift().source;\n\t source.stop(time + this.release, this.release);\n\t }\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Sync the instrument to the Transport. All subsequent calls of\n\t\t * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease)\n\t\t * will be scheduled along the transport.\n\t\t * @example\n\t\t * synth.sync()\n\t\t * //schedule 3 notes when the transport first starts\n\t\t * synth.triggerAttackRelease('8n', 0)\n\t\t * synth.triggerAttackRelease('8n', '8n')\n\t\t * synth.triggerAttackRelease('8n', '4n')\n\t\t * //start the transport to hear the notes\n\t\t * Transport.start()\n\t\t * @returns {Tone.Instrument} this\n\t\t */\n\t Tone.Sampler.prototype.sync = function () {\n\t this._syncMethod('triggerAttack', 1);\n\t this._syncMethod('triggerRelease', 1);\n\t return this;\n\t };\n\t /**\n\t\t * Invoke the attack phase, then after the duration, invoke the release.\n\t\t * @param {Frequency} note The note to play\n\t\t * @param {Time} duration The time the note should be held\n\t\t * @param {Time=} time When to start the attack\n\t\t * @param {NormalRange} [velocity=1] The velocity of the attack\n\t\t * @return {Tone.Sampler} this\n\t\t */\n\t Tone.Sampler.prototype.triggerAttackRelease = function (note, duration, time, velocity) {\n\t time = this.toSeconds(time);\n\t duration = this.toSeconds(duration);\n\t this.triggerAttack(note, time, velocity);\n\t this.triggerRelease(note, time + duration);\n\t return this;\n\t };\n\t /**\n\t\t * Add a note to the sampler.\n\t\t * @param {Note|Midi} note The buffer's pitch.\n\t\t * @param {String|Tone.Buffer|Audiobuffer} url Either the url of the bufer,\n\t\t * or a buffer which will be added\n\t\t * with the given name.\n\t\t * @param {Function=} callback The callback to invoke\n\t\t * when the url is loaded.\n\t\t */\n\t Tone.Sampler.prototype.add = function (note, url, callback) {\n\t if (Tone.isNote(note)) {\n\t //convert the note name to MIDI\n\t var mid = Tone.Frequency(note).toMidi();\n\t this._buffers.add(mid, url, callback);\n\t } else if (!isNaN(parseFloat(note))) {\n\t //otherwise if it's numbers assume it's midi\n\t this._buffers.add(note, url, callback);\n\t } else {\n\t throw new Error('Tone.Sampler: note must be the note\\'s pitch. Instead got ' + note);\n\t }\n\t };\n\t /**\n\t\t * If the buffers are loaded or not\n\t\t * @memberOf Tone.Sampler#\n\t\t * @type {Boolean}\n\t\t * @name loaded\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Sampler.prototype, 'loaded', {\n\t get: function () {\n\t return this._buffers.loaded;\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.Sampler} this\n\t\t */\n\t Tone.Sampler.prototype.dispose = function () {\n\t Tone.Instrument.prototype.dispose.call(this);\n\t this._buffers.dispose();\n\t this._buffers = null;\n\t for (var midi in this._activeSources) {\n\t this._activeSources[midi].forEach(function (event) {\n\t event.source.dispose();\n\t });\n\t }\n\t this._activeSources = null;\n\t return this;\n\t };\n\t return Tone.Sampler;\n\t});\n\tModule(function (Tone) {\n\t if (Tone.supported) {\n\t if (!OscillatorNode.prototype.setPeriodicWave) {\n\t OscillatorNode.prototype.setPeriodicWave = OscillatorNode.prototype.setWaveTable;\n\t }\n\t if (!AudioContext.prototype.createPeriodicWave) {\n\t AudioContext.prototype.createPeriodicWave = AudioContext.prototype.createWaveTable;\n\t }\n\t }\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Maps a NormalRange [0, 1] to an AudioRange [-1, 1]. \n\t\t * See also Tone.AudioToGain. \n\t\t *\n\t\t * @extends {Tone.SignalBase}\n\t\t * @constructor\n\t\t * @example\n\t\t * var g2a = new Tone.GainToAudio();\n\t\t */\n\t Tone.GainToAudio = function () {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * @type {WaveShaperNode}\n\t\t\t * @private\n\t\t\t */\n\t this._norm = this.input = this.output = new Tone.WaveShaper(function (x) {\n\t return Math.abs(x) * 2 - 1;\n\t });\n\t };\n\t Tone.extend(Tone.GainToAudio, Tone.SignalBase);\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.GainToAudio} this\n\t\t */\n\t Tone.GainToAudio.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._norm.dispose();\n\t this._norm = null;\n\t return this;\n\t };\n\t return Tone.GainToAudio;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Normalize takes an input min and max and maps it linearly to NormalRange [0,1]\n\t\t *\n\t\t * @extends {Tone.SignalBase}\n\t\t * @constructor\n\t\t * @param {number} inputMin the min input value\n\t\t * @param {number} inputMax the max input value\n\t\t * @example\n\t\t * var norm = new Tone.Normalize(2, 4);\n\t\t * var sig = new Tone.Signal(3).connect(norm);\n\t\t * //output of norm is 0.5. \n\t\t */\n\t Tone.Normalize = function (inputMin, inputMax) {\n\t Tone.SignalBase.call(this);\n\t /**\n\t\t\t * the min input value\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._inputMin = Tone.defaultArg(inputMin, 0);\n\t /**\n\t\t\t * the max input value\n\t\t\t * @type {number}\n\t\t\t * @private\n\t\t\t */\n\t this._inputMax = Tone.defaultArg(inputMax, 1);\n\t /**\n\t\t\t * subtract the min from the input\n\t\t\t * @type {Tone.Add}\n\t\t\t * @private\n\t\t\t */\n\t this._sub = this.input = new Tone.Add(0);\n\t /**\n\t\t\t * divide by the difference between the input and output\n\t\t\t * @type {Tone.Multiply}\n\t\t\t * @private\n\t\t\t */\n\t this._div = this.output = new Tone.Multiply(1);\n\t this._sub.connect(this._div);\n\t this._setRange();\n\t };\n\t Tone.extend(Tone.Normalize, Tone.SignalBase);\n\t /**\n\t\t * The minimum value the input signal will reach.\n\t\t * @memberOf Tone.Normalize#\n\t\t * @type {number}\n\t\t * @name min\n\t\t */\n\t Object.defineProperty(Tone.Normalize.prototype, 'min', {\n\t get: function () {\n\t return this._inputMin;\n\t },\n\t set: function (min) {\n\t this._inputMin = min;\n\t this._setRange();\n\t }\n\t });\n\t /**\n\t\t * The maximum value the input signal will reach.\n\t\t * @memberOf Tone.Normalize#\n\t\t * @type {number}\n\t\t * @name max\n\t\t */\n\t Object.defineProperty(Tone.Normalize.prototype, 'max', {\n\t get: function () {\n\t return this._inputMax;\n\t },\n\t set: function (max) {\n\t this._inputMax = max;\n\t this._setRange();\n\t }\n\t });\n\t /**\n\t\t * set the values\n\t\t * @private\n\t\t */\n\t Tone.Normalize.prototype._setRange = function () {\n\t this._sub.value = -this._inputMin;\n\t this._div.value = 1 / (this._inputMax - this._inputMin);\n\t };\n\t /**\n\t\t * clean up\n\t\t * @returns {Tone.Normalize} this\n\t\t */\n\t Tone.Normalize.prototype.dispose = function () {\n\t Tone.SignalBase.prototype.dispose.call(this);\n\t this._sub.dispose();\n\t this._sub = null;\n\t this._div.dispose();\n\t this._div = null;\n\t return this;\n\t };\n\t return Tone.Normalize;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.TransportTimelineSignal extends Tone.Signal, but adds the ability to synchronize the signal to the signal to the Tone.Transport\n\t\t * @extends {Tone.Signal}\n\t\t */\n\t Tone.TransportTimelineSignal = function () {\n\t Tone.Signal.apply(this, arguments);\n\t /**\n\t\t\t * The real signal output\n\t\t\t * @type {Tone.Signal}\n\t\t\t * @private\n\t\t\t */\n\t this.output = this._outputSig = new Tone.Signal(this._initialValue);\n\t /**\n\t\t\t * Keep track of the last value. (small optimization)\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._lastVal = this.value;\n\t /**\n\t\t\t * The event id of the tick update loop\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._synced = Tone.Transport.scheduleRepeat(this._onTick.bind(this), '1i');\n\t /**\n\t\t\t * A bound version of the anchor value methods\n\t\t\t * @type {Function}\n\t\t\t * @private\n\t\t\t */\n\t this._bindAnchorValue = this._anchorValue.bind(this);\n\t Tone.Transport.on('start stop pause', this._bindAnchorValue);\n\t this._events.memory = Infinity;\n\t };\n\t Tone.extend(Tone.TransportTimelineSignal, Tone.Signal);\n\t /**\n\t\t * Callback which is invoked every tick.\n\t\t * @private\n\t\t * @param {Number} time\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype._onTick = function (time) {\n\t var val = this.getValueAtTime(Tone.Transport.seconds);\n\t if (this._lastVal !== val) {\n\t this._lastVal = val;\n\t //approximate ramp curves with linear ramps\n\t this._outputSig.linearRampToValueAtTime(val, time);\n\t }\n\t };\n\t /**\n\t\t * Anchor the value at the start and stop of the Transport\n\t\t * @param {Number} time The time of the event\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t * @private\n\t\t */\n\t Tone.TransportTimelineSignal.prototype._anchorValue = function (time) {\n\t var val = this.getValueAtTime(Tone.Transport.seconds);\n\t this._lastVal = val;\n\t this._outputSig.cancelScheduledValues(time);\n\t this._outputSig.setValueAtTime(val, time);\n\t return this;\n\t };\n\t /**\n\t\t * Get the scheduled value at the given time. This will\n\t\t * return the unconverted (raw) value.\n\t\t * @param {TransportTime} time The time in seconds.\n\t\t * @return {Number} The scheduled value at the given time.\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.getValueAtTime = function (time) {\n\t time = Tone.TransportTime(time);\n\t return Tone.Signal.prototype.getValueAtTime.call(this, time);\n\t };\n\t /**\n\t\t * Set the output of the signal at the given time\n\t\t * @param {Number} value The value to change to at the given time\n\t\t * @param {TransportTime} time The time to change the signal\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.setValueAtTime = function (value, time) {\n\t time = Tone.TransportTime(time);\n\t Tone.Signal.prototype.setValueAtTime.call(this, value, time);\n\t return this;\n\t };\n\t /**\n\t\t * Linear ramp to the given value from the previous scheduled point to the given value\n\t\t * @param {Number} value The value to change to at the given time\n\t\t * @param {TransportTime} time The time to change the signal\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.linearRampToValueAtTime = function (value, time) {\n\t time = Tone.TransportTime(time);\n\t Tone.Signal.prototype.linearRampToValueAtTime.call(this, value, time);\n\t return this;\n\t };\n\t /**\n\t\t * Exponential ramp to the given value from the previous scheduled point to the given value\n\t\t * @param {Number} value The value to change to at the given time\n\t\t * @param {TransportTime} time The time to change the signal\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.exponentialRampToValueAtTime = function (value, time) {\n\t time = Tone.TransportTime(time);\n\t Tone.Signal.prototype.exponentialRampToValueAtTime.call(this, value, time);\n\t return this;\n\t };\n\t /**\n\t\t * Start exponentially approaching the target value at the given time with\n\t\t * a rate having the given time constant.\n\t\t * @param {number} value\n\t\t * @param {TransportTime} startTime\n\t\t * @param {number} timeConstant\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t startTime = Tone.TransportTime(startTime);\n\t Tone.Signal.prototype.setTargetAtTime.call(this, value, startTime, timeConstant);\n\t return this;\n\t };\n\t /**\n\t\t * Cancels all scheduled parameter changes with times greater than or\n\t\t * equal to startTime.\n\t\t * @param {TransportTime} startTime\n\t\t * @returns {Tone.Param} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.cancelScheduledValues = function (startTime) {\n\t startTime = Tone.TransportTime(startTime);\n\t Tone.Signal.prototype.cancelScheduledValues.call(this, startTime);\n\t return this;\n\t };\n\t /**\n\t\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t\t * @param {Float32Array} values\n\t\t * @param {Time} startTime\n\t\t * @param {Time} duration\n\t\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t\t * @returns {Tone.Signal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t startTime = Tone.TransportTime(startTime);\n\t duration = Tone.TransportTime(duration);\n\t Tone.Signal.prototype.setValueCurveAtTime.call(this, values, startTime, duration, scaling);\n\t return this;\n\t };\n\t /**\n\t\t * This is similar to [cancelScheduledValues](#cancelScheduledValues) except\n\t\t * it holds the automated value at time until the next automated event.\n\t\t * @param {Time} time\n\t\t * @returns {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.cancelAndHoldAtTime = function (time) {\n\t return Tone.Signal.prototype.cancelAndHoldAtTime.call(this, Tone.TransportTime(time));\n\t };\n\t /**\n\t\t * Dispose and disconnect\n\t\t * @return {Tone.TransportTimelineSignal} this\n\t\t */\n\t Tone.TransportTimelineSignal.prototype.dispose = function () {\n\t Tone.Transport.clear(this._synced);\n\t Tone.Transport.off('start stop pause', this._syncedCallback);\n\t this._events.cancel(0);\n\t Tone.Signal.prototype.dispose.call(this);\n\t this._outputSig.dispose();\n\t this._outputSig = null;\n\t };\n\t return Tone.TransportTimelineSignal;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.GrainPlayer implements [granular synthesis](https://en.wikipedia.org/wiki/Granular_synthesis).\n\t\t * Granular Synthesis enables you to adjust pitch and playback rate independently. The grainSize is the\n\t\t * amount of time each small chunk of audio is played for and the overlap is the\n\t\t * amount of crossfading transition time between successive grains.\n\t\t * @extends {Tone.Source}\n\t\t * @param {String|Tone.Buffer} url\tThe url to load, or the Tone.Buffer to play.\n\t\t * @param {Function=} callback The callback to invoke after the url is loaded.\n\t\t */\n\t Tone.GrainPlayer = function () {\n\t var options = Tone.defaults(arguments, [\n\t 'url',\n\t 'onload'\n\t ], Tone.GrainPlayer);\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * The audio buffer belonging to the player.\n\t\t\t * @type {Tone.Buffer}\n\t\t\t */\n\t this.buffer = new Tone.Buffer(options.url, options.onload);\n\t /**\n\t\t\t * Create a repeating tick to schedule\n\t\t\t * the grains.\n\t\t\t * @type {Tone.Clock}\n\t\t\t * @private\n\t\t\t */\n\t this._clock = new Tone.Clock(this._tick.bind(this), options.grainSize);\n\t /**\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._loopStart = 0;\n\t /**\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._loopEnd = 0;\n\t /**\n\t\t\t * All of the currently playing BufferSources\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t this._activeSources = [];\n\t /**\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._playbackRate = options.playbackRate;\n\t /**\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._grainSize = options.grainSize;\n\t /**\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._overlap = options.overlap;\n\t /**\n\t\t\t * Adjust the pitch independently of the playbackRate.\n\t\t\t * @type {Cents}\n\t\t\t */\n\t this.detune = options.detune;\n\t //setup\n\t this.overlap = options.overlap;\n\t this.loop = options.loop;\n\t this.playbackRate = options.playbackRate;\n\t this.grainSize = options.grainSize;\n\t this.loopStart = options.loopStart;\n\t this.loopEnd = options.loopEnd;\n\t this.reverse = options.reverse;\n\t this._clock.on('stop', this._onstop.bind(this));\n\t };\n\t Tone.extend(Tone.GrainPlayer, Tone.Source);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.GrainPlayer.defaults = {\n\t 'onload': Tone.noOp,\n\t 'overlap': 0.1,\n\t 'grainSize': 0.2,\n\t 'playbackRate': 1,\n\t 'detune': 0,\n\t 'loop': false,\n\t 'loopStart': 0,\n\t 'loopEnd': 0,\n\t 'reverse': false\n\t };\n\t /**\n\t\t * Play the buffer at the given startTime. Optionally add an offset\n\t\t * and/or duration which will play the buffer from a position\n\t\t * within the buffer for the given duration.\n\t\t *\n\t\t * @param {Time} [startTime=now] When the player should start.\n\t\t * @param {Time} [offset=0] The offset from the beginning of the sample\n\t\t * to start at.\n\t\t * @param {Time=} duration How long the sample should play. If no duration\n\t\t * is given, it will default to the full length\n\t\t * of the sample (minus any offset)\n\t\t * @returns {Tone.GrainPlayer} this\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @method start\n\t\t * @name start\n\t\t */\n\t /**\n\t\t * Internal start method\n\t\t * @param {Time} time\n\t\t * @param {Time} offset\n\t\t * @private\n\t\t */\n\t Tone.GrainPlayer.prototype._start = function (time, offset, duration) {\n\t offset = Tone.defaultArg(offset, 0);\n\t offset = this.toSeconds(offset);\n\t time = this.toSeconds(time);\n\t this._offset = offset;\n\t this._clock.start(time);\n\t if (duration) {\n\t this.stop(time + this.toSeconds(duration));\n\t }\n\t };\n\t /**\n\t\t * Internal start method\n\t\t * @param {Time} time\n\t\t * @private\n\t\t */\n\t Tone.GrainPlayer.prototype._stop = function (time) {\n\t this._clock.stop(time);\n\t };\n\t /**\n\t\t * Invoked when the clock is stopped\n\t\t * @param {Number} time\n\t\t * @private\n\t\t */\n\t Tone.GrainPlayer.prototype._onstop = function (time) {\n\t //stop the players\n\t this._activeSources.forEach(function (source) {\n\t source.stop(time, 0);\n\t });\n\t };\n\t /**\n\t\t * Invoked on each clock tick. scheduled a new\n\t\t * grain at this time.\n\t\t * @param {Time} time\n\t\t * @private\n\t\t */\n\t Tone.GrainPlayer.prototype._tick = function (time) {\n\t var fadeIn = this._offset < this._overlap ? 0 : this._overlap;\n\t var source = new Tone.BufferSource({\n\t 'buffer': this.buffer,\n\t 'fadeIn': fadeIn,\n\t 'fadeOut': this._overlap,\n\t 'loop': this.loop,\n\t 'loopStart': this._loopStart,\n\t 'loopEnd': this._loopEnd,\n\t 'playbackRate': Tone.intervalToFrequencyRatio(this.detune / 100)\n\t }).connect(this.output);\n\t source.start(time, this._offset);\n\t this._offset += this.grainSize;\n\t source.stop(time + this.grainSize);\n\t //add it to the active sources\n\t this._activeSources.push(source);\n\t //remove it when it's done\n\t source.onended = function () {\n\t var index = this._activeSources.indexOf(source);\n\t if (index !== -1) {\n\t this._activeSources.splice(index, 1);\n\t }\n\t }.bind(this);\n\t };\n\t /**\n\t\t * Jump to a specific time and play it.\n\t\t * @param {Time} offset The offset to jump to.\n\t\t * @param {Time=} time When to make the jump.\n\t\t * @return {Tone.GrainPlayer} this\n\t\t */\n\t Tone.GrainPlayer.prototype.seek = function (offset, time) {\n\t this._offset = this.toSeconds(offset);\n\t this._tick(this.toSeconds(time));\n\t return this;\n\t };\n\t /**\n\t\t * The playback rate of the sample\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @type {Positive}\n\t\t * @name playbackRate\n\t\t */\n\t Object.defineProperty(Tone.GrainPlayer.prototype, 'playbackRate', {\n\t get: function () {\n\t return this._playbackRate;\n\t },\n\t set: function (rate) {\n\t this._playbackRate = rate;\n\t this.grainSize = this._grainSize;\n\t }\n\t });\n\t /**\n\t\t * The loop start time.\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @type {Time}\n\t\t * @name loopStart\n\t\t */\n\t Object.defineProperty(Tone.GrainPlayer.prototype, 'loopStart', {\n\t get: function () {\n\t return this._loopStart;\n\t },\n\t set: function (time) {\n\t this._loopStart = this.toSeconds(time);\n\t }\n\t });\n\t /**\n\t\t * The loop end time.\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @type {Time}\n\t\t * @name loopEnd\n\t\t */\n\t Object.defineProperty(Tone.GrainPlayer.prototype, 'loopEnd', {\n\t get: function () {\n\t return this._loopEnd;\n\t },\n\t set: function (time) {\n\t this._loopEnd = this.toSeconds(time);\n\t }\n\t });\n\t /**\n\t\t * The direction the buffer should play in\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @type {boolean}\n\t\t * @name reverse\n\t\t */\n\t Object.defineProperty(Tone.GrainPlayer.prototype, 'reverse', {\n\t get: function () {\n\t return this.buffer.reverse;\n\t },\n\t set: function (rev) {\n\t this.buffer.reverse = rev;\n\t }\n\t });\n\t /**\n\t\t * The size of each chunk of audio that the\n\t\t * buffer is chopped into and played back at.\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @type {Time}\n\t\t * @name grainSize\n\t\t */\n\t Object.defineProperty(Tone.GrainPlayer.prototype, 'grainSize', {\n\t get: function () {\n\t return this._grainSize;\n\t },\n\t set: function (size) {\n\t this._grainSize = this.toSeconds(size);\n\t this._clock.frequency.value = this._playbackRate / this._grainSize;\n\t }\n\t });\n\t /**\n\t\t * This is the duration of the cross-fade between\n\t\t * sucessive grains.\n\t\t * @memberOf Tone.GrainPlayer#\n\t\t * @type {Time}\n\t\t * @name overlap\n\t\t */\n\t Object.defineProperty(Tone.GrainPlayer.prototype, 'overlap', {\n\t get: function () {\n\t return this._overlap;\n\t },\n\t set: function (time) {\n\t this._overlap = this.toSeconds(time);\n\t }\n\t });\n\t /**\n\t\t * Clean up\n\t\t * @return {Tone.GrainPlayer} this\n\t\t */\n\t Tone.GrainPlayer.prototype.dispose = function () {\n\t Tone.Source.prototype.dispose.call(this);\n\t this.buffer.dispose();\n\t this.buffer = null;\n\t this._clock.dispose();\n\t this._clock = null;\n\t this._activeSources.forEach(function (source) {\n\t source.dispose();\n\t });\n\t this._activeSources = null;\n\t return this;\n\t };\n\t return Tone.GrainPlayer;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Player is an audio file player with start, loop, and stop functions.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.Source}\n\t\t * @param {string|AudioBuffer} url Either the AudioBuffer or the url from\n\t\t * which to load the AudioBuffer\n\t\t * @param {Function=} onload The function to invoke when the buffer is loaded.\n\t\t * Recommended to use Tone.Buffer.on('load') instead.\n\t\t * @example\n\t\t * var player = new Tone.Player(\"./path/to/sample.mp3\").toMaster();\n\t\t * //play as soon as the buffer is loaded\n\t\t * player.autostart = true;\n\t\t */\n\t Tone.Player = function (url) {\n\t var options;\n\t if (url instanceof Tone.Buffer && url.loaded) {\n\t url = url.get();\n\t options = Tone.Player.defaults;\n\t } else {\n\t options = Tone.defaults(arguments, [\n\t 'url',\n\t 'onload'\n\t ], Tone.Player);\n\t }\n\t Tone.Source.call(this, options);\n\t /**\n\t\t\t * If the file should play as soon\n\t\t\t * as the buffer is loaded.\n\t\t\t * @type {Boolean}\n\t\t\t * @example\n\t\t\t * //will play as soon as it's loaded\n\t\t\t * var player = new Tone.Player({\n\t\t\t * \t\"url\" : \"./path/to/sample.mp3\",\n\t\t\t * \t\"autostart\" : true,\n\t\t\t * }).toMaster();\n\t\t\t */\n\t this.autostart = options.autostart;\n\t /**\n\t\t\t * the buffer\n\t\t\t * @private\n\t\t\t * @type {Tone.Buffer}\n\t\t\t */\n\t this._buffer = new Tone.Buffer({\n\t 'url': options.url,\n\t 'onload': this._onload.bind(this, options.onload),\n\t 'reverse': options.reverse\n\t });\n\t if (url instanceof AudioBuffer) {\n\t this._buffer.set(url);\n\t }\n\t /**\n\t\t\t * if the buffer should loop once it's over\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t this._loop = options.loop;\n\t /**\n\t\t\t * if 'loop' is true, the loop will start at this position\n\t\t\t * @type {Time}\n\t\t\t * @private\n\t\t\t */\n\t this._loopStart = options.loopStart;\n\t /**\n\t\t\t * if 'loop' is true, the loop will end at this position\n\t\t\t * @type {Time}\n\t\t\t * @private\n\t\t\t */\n\t this._loopEnd = options.loopEnd;\n\t /**\n\t\t\t * the playback rate\n\t\t\t * @private\n\t\t\t * @type {Number}\n\t\t\t */\n\t this._playbackRate = options.playbackRate;\n\t /**\n\t\t\t * All of the active buffer source nodes\n\t\t\t * @type {Array<Tone.BufferSource>}\n\t\t\t * @private\n\t\t\t */\n\t this._activeSources = [];\n\t /**\n\t\t\t * The elapsed time counter.\n\t\t\t * @type {Tone.TickSource}\n\t\t\t * @private\n\t\t\t */\n\t this._elapsedTime = new Tone.TickSource(options.playbackRate);\n\t /**\n\t\t\t * The fadeIn time of the amplitude envelope.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.fadeIn = options.fadeIn;\n\t /**\n\t\t\t * The fadeOut time of the amplitude envelope.\n\t\t\t * @type {Time}\n\t\t\t */\n\t this.fadeOut = options.fadeOut;\n\t };\n\t Tone.extend(Tone.Player, Tone.Source);\n\t /**\n\t\t * the default parameters\n\t\t * @static\n\t\t * @const\n\t\t * @type {Object}\n\t\t */\n\t Tone.Player.defaults = {\n\t 'onload': Tone.noOp,\n\t 'playbackRate': 1,\n\t 'loop': false,\n\t 'autostart': false,\n\t 'loopStart': 0,\n\t 'loopEnd': 0,\n\t 'retrigger': false,\n\t 'reverse': false,\n\t 'fadeIn': 0,\n\t 'fadeOut': 0\n\t };\n\t /**\n\t\t * Load the audio file as an audio buffer.\n\t\t * Decodes the audio asynchronously and invokes\n\t\t * the callback once the audio buffer loads.\n\t\t * Note: this does not need to be called if a url\n\t\t * was passed in to the constructor. Only use this\n\t\t * if you want to manually load a new url.\n\t\t * @param {string} url The url of the buffer to load.\n\t\t * Filetype support depends on the\n\t\t * browser.\n\t\t * @param {Function=} callback The function to invoke once\n\t\t * the sample is loaded.\n\t\t * @returns {Promise}\n\t\t */\n\t Tone.Player.prototype.load = function (url, callback) {\n\t return this._buffer.load(url, this._onload.bind(this, callback));\n\t };\n\t /**\n\t\t * Internal callback when the buffer is loaded.\n\t\t * @private\n\t\t */\n\t Tone.Player.prototype._onload = function (callback) {\n\t callback = Tone.defaultArg(callback, Tone.noOp);\n\t callback(this);\n\t if (this.autostart) {\n\t this.start();\n\t }\n\t };\n\t /**\n\t\t * Internal callback when the buffer is done playing.\n\t\t * @private\n\t\t */\n\t Tone.Player.prototype._onSourceEnd = function (source) {\n\t var index = this._activeSources.indexOf(source);\n\t this._activeSources.splice(index, 1);\n\t };\n\t /**\n\t\t * Play the buffer at the given startTime. Optionally add an offset\n\t\t * and/or duration which will play the buffer from a position\n\t\t * within the buffer for the given duration.\n\t\t *\n\t\t * @param {Time} [startTime=now] When the player should start.\n\t\t * @param {Time} [offset=0] The offset from the beginning of the sample\n\t\t * to start at.\n\t\t * @param {Time=} duration How long the sample should play. If no duration\n\t\t * is given, it will default to the full length\n\t\t * of the sample (minus any offset)\n\t\t * @returns {Tone.Player} this\n\t\t * @memberOf Tone.Player#\n\t\t * @method start\n\t\t * @name start\n\t\t */\n\t /**\n\t\t * Internal start method\n\t\t * @private\n\t\t */\n\t Tone.Player.prototype._start = function (startTime, offset, duration) {\n\t //if it's a loop the default offset is the loopstart point\n\t if (this._loop) {\n\t offset = Tone.defaultArg(offset, this._loopStart);\n\t } else {\n\t //otherwise the default offset is 0\n\t offset = Tone.defaultArg(offset, 0);\n\t }\n\t //compute the values in seconds\n\t offset = this.toSeconds(offset);\n\t var computedDuration = Tone.defaultArg(duration, Math.max(this._buffer.duration - offset, 0));\n\t computedDuration = this.toSeconds(computedDuration);\n\t startTime = this.toSeconds(startTime);\n\t //start the elapsed time counter\n\t this._elapsedTime.start(startTime, offset);\n\t //make the source\n\t var source = new Tone.BufferSource({\n\t 'buffer': this._buffer,\n\t 'loop': this._loop,\n\t 'loopStart': this._loopStart,\n\t 'loopEnd': this._loopEnd,\n\t 'onended': this._onSourceEnd.bind(this),\n\t 'playbackRate': this._playbackRate,\n\t 'fadeIn': this.fadeIn,\n\t 'fadeOut': this.fadeOut\n\t }).connect(this.output);\n\t //set the looping properties\n\t if (!this._loop && !this._synced) {\n\t //if it's not looping, set the state change at the end of the sample\n\t this._state.setStateAtTime(Tone.State.Stopped, startTime + computedDuration / this._playbackRate);\n\t }\n\t //add it to the array of active sources\n\t this._activeSources.push(source);\n\t //start it\n\t if (this._loop && Tone.isUndef(duration)) {\n\t source.start(startTime, offset);\n\t } else {\n\t source.start(startTime, offset, computedDuration);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Stop playback.\n\t\t * @private\n\t\t * @param {Time} [time=now]\n\t\t * @returns {Tone.Player} this\n\t\t */\n\t Tone.Player.prototype._stop = function (time) {\n\t time = this.toSeconds(time);\n\t this._elapsedTime.stop(time);\n\t this._activeSources.forEach(function (source) {\n\t source.stop(time);\n\t });\n\t return this;\n\t };\n\t /**\n\t\t * Stop and then restart the player from the beginning (or offset)\n\t\t * @param {Time} [startTime=now] When the player should start.\n\t\t * @param {Time} [offset=0] The offset from the beginning of the sample\n\t\t * to start at.\n\t\t * @param {Time=} duration How long the sample should play. If no duration\n\t\t * is given, it will default to the full length\n\t\t * of the sample (minus any offset)\n\t\t * @returns {Tone.Player} this\n\t\t */\n\t Tone.Player.prototype.restart = function (time, offset, duration) {\n\t this._stop(time);\n\t this._start(time, offset, duration);\n\t return this;\n\t };\n\t /**\n\t\t * Seek to a specific time in the player's buffer. If the\n\t\t * source is no longer playing at that time, it will stop.\n\t\t * If you seek to a time that\n\t\t * @param {Time} offset The time to seek to.\n\t\t * @param {Time=} time The time for the seek event to occur.\n\t\t * @return {Tone.Player} this\n\t\t * @example\n\t\t * source.start(0.2);\n\t\t * source.stop(0.4);\n\t\t */\n\t Tone.Player.prototype.seek = function (offset, time) {\n\t time = this.toSeconds(time);\n\t if (this._state.getValueAtTime(time) === Tone.State.Started) {\n\t offset = this.toSeconds(offset);\n\t // if it's currently playing, stop it\n\t this._stop(time);\n\t //restart it at the given time\n\t this._start(time, offset);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * Set the loop start and end. Will only loop if loop is\n\t\t * set to true.\n\t\t * @param {Time} loopStart The loop end time\n\t\t * @param {Time} loopEnd The loop end time\n\t\t * @returns {Tone.Player} this\n\t\t * @example\n\t\t * //loop 0.1 seconds of the file.\n\t\t * player.setLoopPoints(0.2, 0.3);\n\t\t * player.loop = true;\n\t\t */\n\t Tone.Player.prototype.setLoopPoints = function (loopStart, loopEnd) {\n\t this.loopStart = loopStart;\n\t this.loopEnd = loopEnd;\n\t return this;\n\t };\n\t /**\n\t\t * If loop is true, the loop will start at this position.\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Time}\n\t\t * @name loopStart\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'loopStart', {\n\t get: function () {\n\t return this._loopStart;\n\t },\n\t set: function (loopStart) {\n\t this._loopStart = loopStart;\n\t //get the current source\n\t this._activeSources.forEach(function (source) {\n\t source.loopStart = loopStart;\n\t });\n\t }\n\t });\n\t /**\n\t\t * If loop is true, the loop will end at this position.\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Time}\n\t\t * @name loopEnd\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'loopEnd', {\n\t get: function () {\n\t return this._loopEnd;\n\t },\n\t set: function (loopEnd) {\n\t this._loopEnd = loopEnd;\n\t //get the current source\n\t this._activeSources.forEach(function (source) {\n\t source.loopEnd = loopEnd;\n\t });\n\t }\n\t });\n\t /**\n\t\t * The audio buffer belonging to the player.\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Tone.Buffer}\n\t\t * @name buffer\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'buffer', {\n\t get: function () {\n\t return this._buffer;\n\t },\n\t set: function (buffer) {\n\t this._buffer.set(buffer);\n\t }\n\t });\n\t /**\n\t\t * If the buffer should loop once it's over.\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Boolean}\n\t\t * @name loop\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'loop', {\n\t get: function () {\n\t return this._loop;\n\t },\n\t set: function (loop) {\n\t //if no change, do nothing\n\t if (this._loop === loop) {\n\t return;\n\t }\n\t this._loop = loop;\n\t var now = this.now();\n\t if (!loop) {\n\t //stop the playback on the next cycle\n\t this._stopAtNextIteration(now);\n\t } else {\n\t //remove the next stopEvent\n\t var stopEvent = this._state.getNextState(Tone.State.Stopped, now);\n\t if (stopEvent) {\n\t this._activeSources.forEach(function (source) {\n\t source.loop = loop;\n\t });\n\t this._state.cancel(stopEvent.time);\n\t this._elapsedTime.cancel(stopEvent.time);\n\t }\n\t }\n\t }\n\t });\n\t /**\n\t\t * Schedules a stop event at the next full iteration. Used\n\t\t * for scheduling stop when the loop state or playbackRate changes\n\t\t * @param {Number} now The current time\n\t\t * @private\n\t\t */\n\t Tone.Player.prototype._stopAtNextIteration = function (now) {\n\t if (this._state.getValueAtTime(now) === Tone.State.Started) {\n\t var nextStop = this._state.getNextState(Tone.State.Stopped, now);\n\t var position = this._elapsedTime.getTicksAtTime(now);\n\t var iterations = Math.max(Math.ceil(position / this.buffer.duration), 1);\n\t var stopTime = this._elapsedTime.getTimeOfTick(iterations * this.buffer.duration, nextStop ? nextStop.time - this.sampleTime : Infinity);\n\t this.stop(stopTime);\n\t }\n\t };\n\t /**\n\t\t * The playback speed. 1 is normal speed. This is not a signal because\n\t\t * Safari and iOS currently don't support playbackRate as a signal.\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Number}\n\t\t * @name playbackRate\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'playbackRate', {\n\t get: function () {\n\t return this._playbackRate;\n\t },\n\t set: function (rate) {\n\t this._playbackRate = rate;\n\t var now = this.now();\n\t this._elapsedTime.frequency.setValueAtTime(rate, now);\n\t //if it's not looping\n\t if (!this._loop) {\n\t this._stopAtNextIteration(now);\n\t }\n\t //set all the sources\n\t this._activeSources.forEach(function (source) {\n\t source.playbackRate.setValueAtTime(rate, now);\n\t });\n\t }\n\t });\n\t /**\n\t\t * The current playback position of the buffer. \n\t\t * @memberOf Tone.Player#\n\t\t * @type {Number}\n\t\t * @name position\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'position', {\n\t get: function () {\n\t var now = this.now();\n\t if (this._state.getValueAtTime(now) === Tone.State.Started && this.loaded) {\n\t var duration = this.buffer.duration;\n\t var position = this._elapsedTime.getTicksAtTime(now);\n\t return position % duration;\n\t } else {\n\t return 0;\n\t }\n\t }\n\t });\n\t /**\n\t\t * The direction the buffer should play in\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Boolean}\n\t\t * @name reverse\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'reverse', {\n\t get: function () {\n\t return this._buffer.reverse;\n\t },\n\t set: function (rev) {\n\t this._buffer.reverse = rev;\n\t }\n\t });\n\t /**\n\t\t * If all the buffer is loaded\n\t\t * @memberOf Tone.Player#\n\t\t * @type {Boolean}\n\t\t * @name loaded\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Player.prototype, 'loaded', {\n\t get: function () {\n\t return this._buffer.loaded;\n\t }\n\t });\n\t /**\n\t\t * Dispose and disconnect.\n\t\t * @return {Tone.Player} this\n\t\t */\n\t Tone.Player.prototype.dispose = function () {\n\t //disconnect all of the players\n\t this._activeSources.forEach(function (source) {\n\t source.dispose();\n\t });\n\t this._activeSources = null;\n\t Tone.Source.prototype.dispose.call(this);\n\t this._buffer.dispose();\n\t this._buffer = null;\n\t this._elapsedTime.dispose();\n\t this._elapsedTime = null;\n\t return this;\n\t };\n\t return Tone.Player;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.Players combines multiple [Tone.Player](Player) objects.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Object} urls An object mapping a name to a url.\n\t\t * @param {function=} onload The function to invoke when all buffers are loaded.\n\t\t */\n\t Tone.Players = function (urls) {\n\t var args = Array.prototype.slice.call(arguments);\n\t args.shift();\n\t var options = Tone.defaults(args, ['onload'], Tone.Players);\n\t Tone.call(this);\n\t /**\n\t\t\t * The output volume node\n\t\t\t * @type {Tone.Volume}\n\t\t\t * @private\n\t\t\t */\n\t this._volume = this.output = new Tone.Volume(options.volume);\n\t /**\n\t\t\t * The volume of the output in decibels.\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * source.volume.value = -6;\n\t\t\t */\n\t this.volume = this._volume.volume;\n\t this._readOnly('volume');\n\t //make the output explicitly stereo\n\t this._volume.output.output.channelCount = 2;\n\t this._volume.output.output.channelCountMode = 'explicit';\n\t //mute initially\n\t this.mute = options.mute;\n\t /**\n\t\t\t * The container of all of the players\n\t\t\t * @type {Object}\n\t\t\t * @private\n\t\t\t */\n\t this._players = {};\n\t /**\n\t\t\t * The loading count\n\t\t\t * @type {Number}\n\t\t\t * @private\n\t\t\t */\n\t this._loadingCount = 0;\n\t /**\n\t\t\t * private holder of the fadeIn time\n\t\t\t * @type {Time}\n\t\t\t * @private\n\t\t\t */\n\t this._fadeIn = options.fadeIn;\n\t /**\n\t\t\t * private holder of the fadeOut time\n\t\t\t * @type {Time}\n\t\t\t * @private\n\t\t\t */\n\t this._fadeOut = options.fadeOut;\n\t //add all of the players\n\t for (var name in urls) {\n\t this._loadingCount++;\n\t this.add(name, urls[name], this._bufferLoaded.bind(this, options.onload));\n\t }\n\t };\n\t Tone.extend(Tone.Players, Tone.AudioNode);\n\t /**\n\t\t * The default values\n\t\t * @type {Object}\n\t\t */\n\t Tone.Players.defaults = {\n\t 'volume': 0,\n\t 'mute': false,\n\t 'onload': Tone.noOp,\n\t 'fadeIn': 0,\n\t 'fadeOut': 0\n\t };\n\t /**\n\t\t * A buffer was loaded. decrement the counter.\n\t\t * @param {Function} callback\n\t\t * @private\n\t\t */\n\t Tone.Players.prototype._bufferLoaded = function (callback) {\n\t this._loadingCount--;\n\t if (this._loadingCount === 0 && callback) {\n\t callback(this);\n\t }\n\t };\n\t /**\n\t\t * Mute the output.\n\t\t * @memberOf Tone.Source#\n\t\t * @type {boolean}\n\t\t * @name mute\n\t\t * @example\n\t\t * //mute the output\n\t\t * source.mute = true;\n\t\t */\n\t Object.defineProperty(Tone.Players.prototype, 'mute', {\n\t get: function () {\n\t return this._volume.mute;\n\t },\n\t set: function (mute) {\n\t this._volume.mute = mute;\n\t }\n\t });\n\t /**\n\t\t * The fadeIn time of the amplitude envelope.\n\t\t * @memberOf Tone.Source#\n\t\t * @type {Time}\n\t\t * @name fadeIn\n\t\t */\n\t Object.defineProperty(Tone.Players.prototype, 'fadeIn', {\n\t get: function () {\n\t return this._fadeIn;\n\t },\n\t set: function (fadeIn) {\n\t this._fadeIn = fadeIn;\n\t this._forEach(function (player) {\n\t player.fadeIn = fadeIn;\n\t });\n\t }\n\t });\n\t /**\n\t\t * The fadeOut time of the amplitude envelope.\n\t\t * @memberOf Tone.Source#\n\t\t * @type {Time}\n\t\t * @name fadeOut\n\t\t */\n\t Object.defineProperty(Tone.Players.prototype, 'fadeOut', {\n\t get: function () {\n\t return this._fadeOut;\n\t },\n\t set: function (fadeOut) {\n\t this._fadeOut = fadeOut;\n\t this._forEach(function (player) {\n\t player.fadeOut = fadeOut;\n\t });\n\t }\n\t });\n\t /**\n\t\t * The state of the players object. Returns \"started\" if any of the players are playing.\n\t\t * @memberOf Tone.Players#\n\t\t * @type {String}\n\t\t * @name state\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Players.prototype, 'state', {\n\t get: function () {\n\t var playing = false;\n\t this._forEach(function (player) {\n\t playing = playing || player.state === Tone.State.Started;\n\t });\n\t return playing ? Tone.State.Started : Tone.State.Stopped;\n\t }\n\t });\n\t /**\n\t\t * True if the buffers object has a buffer by that name.\n\t\t * @param {String|Number} name The key or index of the\n\t\t * buffer.\n\t\t * @return {Boolean}\n\t\t */\n\t Tone.Players.prototype.has = function (name) {\n\t return this._players.hasOwnProperty(name);\n\t };\n\t /**\n\t\t * Get a player by name.\n\t\t * @param {String} name The players name as defined in\n\t\t * the constructor object or `add` method.\n\t\t * @return {Tone.Player}\n\t\t */\n\t Tone.Players.prototype.get = function (name) {\n\t if (this.has(name)) {\n\t return this._players[name];\n\t } else {\n\t throw new Error('Tone.Players: no player named ' + name);\n\t }\n\t };\n\t /**\n\t\t * Iterate over all of the players\n\t\t * @param {Function} callback\n\t\t * @return {Tone.Players} this\n\t\t * @private\n\t\t */\n\t Tone.Players.prototype._forEach = function (callback) {\n\t for (var playerName in this._players) {\n\t callback(this._players[playerName], playerName);\n\t }\n\t return this;\n\t };\n\t /**\n\t\t * If all the buffers are loaded or not\n\t\t * @memberOf Tone.Players#\n\t\t * @type {Boolean}\n\t\t * @name loaded\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.Players.prototype, 'loaded', {\n\t get: function () {\n\t var isLoaded = true;\n\t this._forEach(function (player) {\n\t isLoaded = isLoaded && player.loaded;\n\t });\n\t return isLoaded;\n\t }\n\t });\n\t /**\n\t\t * Add a player by name and url to the Players\n\t\t * @param {String} name A unique name to give the player\n\t\t * @param {String|Tone.Buffer|Audiobuffer} url Either the url of the bufer,\n\t\t * or a buffer which will be added\n\t\t * with the given name.\n\t\t * @param {Function=} callback The callback to invoke\n\t\t * when the url is loaded.\n\t\t */\n\t Tone.Players.prototype.add = function (name, url, callback) {\n\t this._players[name] = new Tone.Player(url, callback).connect(this.output);\n\t this._players[name].fadeIn = this._fadeIn;\n\t this._players[name].fadeOut = this._fadeOut;\n\t return this;\n\t };\n\t /**\n\t\t * Stop all of the players at the given time\n\t\t * @param {Time} time The time to stop all of the players.\n\t\t * @return {Tone.Players} this\n\t\t */\n\t Tone.Players.prototype.stopAll = function (time) {\n\t this._forEach(function (player) {\n\t player.stop(time);\n\t });\n\t };\n\t /**\n\t\t * Dispose and disconnect.\n\t\t * @return {Tone.Players} this\n\t\t */\n\t Tone.Players.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this._volume.dispose();\n\t this._volume = null;\n\t this._writable('volume');\n\t this.volume = null;\n\t this.output = null;\n\t this._forEach(function (player) {\n\t player.dispose();\n\t });\n\t this._players = null;\n\t return this;\n\t };\n\t return Tone.Players;\n\t});\n\tModule(function (Tone) {\n\t \n\t /**\n\t\t * @class Tone.UserMedia uses MediaDevices.getUserMedia to open up\n\t\t * and external microphone or audio input. Check\n\t\t * [MediaDevices API Support](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)\n\t\t * to see which browsers are supported. Access to an external input\n\t\t * is limited to secure (HTTPS) connections.\n\t\t *\n\t\t * @constructor\n\t\t * @extends {Tone.AudioNode}\n\t\t * @param {Decibels=} volume The level of the input\n\t\t * @example\n\t\t * //list the inputs and open the third one\n\t\t * var motu = new Tone.UserMedia();\n\t\t *\n\t\t * //opening the input asks the user to activate their mic\n\t\t * motu.open().then(function(){\n\t\t * \t//promise resolves when input is available\n\t\t * });\n\t\t */\n\t Tone.UserMedia = function () {\n\t var options = Tone.defaults(arguments, ['volume'], Tone.UserMedia);\n\t Tone.AudioNode.call(this);\n\t /**\n\t\t\t * The MediaStreamNode\n\t\t\t * @type {MediaStreamAudioSourceNode}\n\t\t\t * @private\n\t\t\t */\n\t this._mediaStream = null;\n\t /**\n\t\t\t * The media stream created by getUserMedia.\n\t\t\t * @type {LocalMediaStream}\n\t\t\t * @private\n\t\t\t */\n\t this._stream = null;\n\t /**\n\t\t\t * The open device\n\t\t\t * @type {MediaDeviceInfo}\n\t\t\t * @private\n\t\t\t */\n\t this._device = null;\n\t /**\n\t\t\t * The output volume node\n\t\t\t * @type {Tone.Volume}\n\t\t\t * @private\n\t\t\t */\n\t this._volume = this.output = new Tone.Volume(options.volume);\n\t /**\n\t\t\t * The volume of the output in decibels.\n\t\t\t * @type {Decibels}\n\t\t\t * @signal\n\t\t\t * @example\n\t\t\t * input.volume.value = -6;\n\t\t\t */\n\t this.volume = this._volume.volume;\n\t this._readOnly('volume');\n\t this.mute = options.mute;\n\t };\n\t Tone.extend(Tone.UserMedia, Tone.AudioNode);\n\t /**\n\t\t * the default parameters\n\t\t * @type {Object}\n\t\t */\n\t Tone.UserMedia.defaults = {\n\t 'volume': 0,\n\t 'mute': false\n\t };\n\t /**\n\t\t * Open the media stream. If a string is passed in, it is assumed\n\t\t * to be the label or id of the stream, if a number is passed in,\n\t\t * it is the input number of the stream.\n\t\t * @param {String|Number} [labelOrId=\"default\"] The label or id of the audio input media device.\n\t\t * With no argument, the default stream is opened.\n\t\t * @return {Promise} The promise is resolved when the stream is open.\n\t\t */\n\t Tone.UserMedia.prototype.open = function (labelOrId) {\n\t return Tone.UserMedia.enumerateDevices().then(function (devices) {\n\t var device;\n\t if (Tone.isNumber(labelOrId)) {\n\t device = devices[labelOrId];\n\t } else {\n\t device = devices.find(function (device) {\n\t return device.label === labelOrId || device.deviceId === labelOrId;\n\t });\n\t //didn't find a matching device\n\t if (!device && devices.length > 0) {\n\t device = devices[0];\n\t } else if (!device && Tone.isDefined(labelOrId)) {\n\t throw new Error('Tone.UserMedia: no matching device: ' + labelOrId);\n\t }\n\t }\n\t this._device = device;\n\t //do getUserMedia\n\t var constraints = {\n\t audio: {\n\t 'echoCancellation': false,\n\t 'sampleRate': this.context.sampleRate\n\t }\n\t };\n\t if (device) {\n\t constraints.audio.deviceId = device.deviceId;\n\t }\n\t return navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {\n\t //start a new source only if the previous one is closed\n\t if (!this._stream) {\n\t this._stream = stream;\n\t //Wrap a MediaStreamSourceNode around the live input stream.\n\t this._mediaStream = this.context.createMediaStreamSource(stream);\n\t //Connect the MediaStreamSourceNode to a gate gain node\n\t this._mediaStream.connect(this.output);\n\t }\n\t return this;\n\t }.bind(this));\n\t }.bind(this));\n\t };\n\t /**\n\t\t * Close the media stream\n\t\t * @return {Tone.UserMedia} this\n\t\t */\n\t Tone.UserMedia.prototype.close = function () {\n\t if (this._stream) {\n\t this._stream.getAudioTracks().forEach(function (track) {\n\t track.stop();\n\t });\n\t this._stream = null;\n\t //remove the old media stream\n\t this._mediaStream.disconnect();\n\t this._mediaStream = null;\n\t }\n\t this._device = null;\n\t return this;\n\t };\n\t /**\n\t\t * Returns a promise which resolves with the list of audio input devices available.\n\t\t * @return {Promise} The promise that is resolved with the devices\n\t\t * @static\n\t\t * @example\n\t\t * Tone.UserMedia.enumerateDevices().then(function(devices){\n\t\t * \tconsole.log(devices)\n\t\t * })\n\t\t */\n\t Tone.UserMedia.enumerateDevices = function () {\n\t return navigator.mediaDevices.enumerateDevices().then(function (devices) {\n\t return devices.filter(function (device) {\n\t return device.kind === 'audioinput';\n\t });\n\t });\n\t };\n\t /**\n\t\t * Returns the playback state of the source, \"started\" when the microphone is open\n\t\t * and \"stopped\" when the mic is closed.\n\t\t * @type {Tone.State}\n\t\t * @readOnly\n\t\t * @memberOf Tone.UserMedia#\n\t\t * @name state\n\t\t */\n\t Object.defineProperty(Tone.UserMedia.prototype, 'state', {\n\t get: function () {\n\t return this._stream && this._stream.active ? Tone.State.Started : Tone.State.Stopped;\n\t }\n\t });\n\t /**\n\t\t * \tReturns an identifier for the represented device that is\n\t\t * \tpersisted across sessions. It is un-guessable by other applications and\n\t\t * \tunique to the origin of the calling application. It is reset when the\n\t\t * \tuser clears cookies (for Private Browsing, a different identifier is\n\t\t * \tused that is not persisted across sessions). Returns undefined when the\n\t\t * \tdevice is not open.\n\t\t * @type {String}\n\t\t * @readOnly\n\t\t * @memberOf Tone.UserMedia#\n\t\t * @name deviceId\n\t\t */\n\t Object.defineProperty(Tone.UserMedia.prototype, 'deviceId', {\n\t get: function () {\n\t if (this._device) {\n\t return this._device.deviceId;\n\t }\n\t }\n\t });\n\t /**\n\t\t * \tReturns a group identifier. Two devices have the\n\t\t * \tsame group identifier if they belong to the same physical device.\n\t\t * \tReturns undefined when the device is not open.\n\t\t * @type {String}\n\t\t * @readOnly\n\t\t * @memberOf Tone.UserMedia#\n\t\t * @name groupId\n\t\t */\n\t Object.defineProperty(Tone.UserMedia.prototype, 'groupId', {\n\t get: function () {\n\t if (this._device) {\n\t return this._device.groupId;\n\t }\n\t }\n\t });\n\t /**\n\t\t * \tReturns a label describing this device (for example \"Built-in Microphone\").\n\t\t * \tReturns undefined when the device is not open or label is not available\n\t\t * \tbecause of permissions.\n\t\t * @type {String}\n\t\t * @readOnly\n\t\t * @memberOf Tone.UserMedia#\n\t\t * @name groupId\n\t\t */\n\t Object.defineProperty(Tone.UserMedia.prototype, 'label', {\n\t get: function () {\n\t if (this._device) {\n\t return this._device.label;\n\t }\n\t }\n\t });\n\t /**\n\t\t * Mute the output.\n\t\t * @memberOf Tone.UserMedia#\n\t\t * @type {boolean}\n\t\t * @name mute\n\t\t * @example\n\t\t * //mute the output\n\t\t * userMedia.mute = true;\n\t\t */\n\t Object.defineProperty(Tone.UserMedia.prototype, 'mute', {\n\t get: function () {\n\t return this._volume.mute;\n\t },\n\t set: function (mute) {\n\t this._volume.mute = mute;\n\t }\n\t });\n\t /**\n\t\t * Clean up.\n\t\t * @return {Tone.UserMedia} this\n\t\t */\n\t Tone.UserMedia.prototype.dispose = function () {\n\t Tone.AudioNode.prototype.dispose.call(this);\n\t this.close();\n\t this._writable('volume');\n\t this._volume.dispose();\n\t this._volume = null;\n\t this.volume = null;\n\t return this;\n\t };\n\t /**\n\t\t * If getUserMedia is supported by the browser.\n\t\t * @type {Boolean}\n\t\t * @memberOf Tone.UserMedia#\n\t\t * @name supported\n\t\t * @static\n\t\t * @readOnly\n\t\t */\n\t Object.defineProperty(Tone.UserMedia, 'supported', {\n\t get: function () {\n\t return Tone.isDefined(navigator.mediaDevices) && Tone.isFunction(navigator.mediaDevices.getUserMedia);\n\t }\n\t });\n\t return Tone.UserMedia;\n\t});\n\tModule(function (Tone) {\n\t /**\n\t\t * @class Tone.Midi is a primitive type for encoding Time values.\n\t\t * Tone.Midi can be constructed with or without the `new` keyword. Tone.Midi can be passed\n\t\t * into the parameter of any method which takes time as an argument.\n\t\t * @constructor\n\t\t * @extends {Tone.Frequency}\n\t\t * @param {String|Number} val The time value.\n\t\t * @param {String=} units The units of the value.\n\t\t * @example\n\t\t * var t = Tone.Midi(\"4n\");//a quarter note\n\t\t */\n\t Tone.Midi = function (val, units) {\n\t if (this instanceof Tone.Midi) {\n\t Tone.Frequency.call(this, val, units);\n\t } else {\n\t return new Tone.Midi(val, units);\n\t }\n\t };\n\t Tone.extend(Tone.Midi, Tone.Frequency);\n\t /**\n\t\t * The default units if none are given.\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t Tone.Midi.prototype._defaultUnits = 'midi';\n\t /**\n\t\t * Returns the value of a frequency in the current units\n\t\t * @param {Frequency} freq\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Midi.prototype._frequencyToUnits = function (freq) {\n\t return Tone.Frequency.ftom(Tone.Frequency.prototype._frequencyToUnits.call(this, freq));\n\t };\n\t /**\n\t\t * Returns the value of a tick in the current time units\n\t\t * @param {Ticks} ticks\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Midi.prototype._ticksToUnits = function (ticks) {\n\t return Tone.Frequency.ftom(Tone.Frequency.prototype._ticksToUnits.call(this, ticks));\n\t };\n\t /**\n\t\t * Return the value of the beats in the current units\n\t\t * @param {Number} beats\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Midi.prototype._beatsToUnits = function (beats) {\n\t return Tone.Frequency.ftom(Tone.Frequency.prototype._beatsToUnits.call(this, beats));\n\t };\n\t /**\n\t\t * Returns the value of a second in the current units\n\t\t * @param {Seconds} seconds\n\t\t * @return {Number}\n\t\t * @private\n\t\t */\n\t Tone.Midi.prototype._secondsToUnits = function (seconds) {\n\t return Tone.Frequency.ftom(Tone.Frequency.prototype._secondsToUnits.call(this, seconds));\n\t };\n\t /**\n\t\t * Return the value of the frequency as a MIDI note\n\t\t * @return {MIDI}\n\t\t * @example\n\t\t * Tone.Midi(60).toMidi(); //60\n\t\t */\n\t Tone.Midi.prototype.toMidi = function () {\n\t return this.valueOf();\n\t };\n\t /**\n\t\t * Return the value of the frequency as a MIDI note\n\t\t * @return {MIDI}\n\t\t * @example\n\t\t * Tone.Midi(60).toMidi(); //60\n\t\t */\n\t Tone.Midi.prototype.toFrequency = function () {\n\t return Tone.Frequency.mtof(this.toMidi());\n\t };\n\t /**\n\t\t * Transposes the frequency by the given number of semitones.\n\t\t * @param {Interval} interval\n\t\t * @return {Tone.Frequency} A new transposed frequency\n\t\t * @example\n\t\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t\t */\n\t Tone.Midi.prototype.transpose = function (interval) {\n\t return new this.constructor(this.toMidi() + interval);\n\t };\n\t return Tone.Midi;\n\t});\n\t\n\treturn Tone;\n}));\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/tone/build/Tone.js\n// module id = 24\n// module chunks = 0","module.exports = true;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_library.js\n// module id = 25\n// module chunks = 0","exports.f = {}.propertyIsEnumerable;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-pie.js\n// module id = 26\n// module chunks = 0","var def = require('./_object-dp').f\n , has = require('./_has')\n , TAG = require('./_wks')('toStringTag');\n\nmodule.exports = function(it, tag, stat){\n if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag});\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_set-to-string-tag.js\n// module id = 27\n// module chunks = 0","// 7.1.13 ToObject(argument)\nvar defined = require('./_defined');\nmodule.exports = function(it){\n return Object(defined(it));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_to-object.js\n// module id = 28\n// module chunks = 0","var id = 0\n , px = Math.random();\nmodule.exports = function(key){\n return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_uid.js\n// module id = 29\n// module chunks = 0","require('./es6.array.iterator');\nvar global = require('./_global')\n , hide = require('./_hide')\n , Iterators = require('./_iterators')\n , TO_STRING_TAG = require('./_wks')('toStringTag');\n\nfor(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){\n var NAME = collections[i]\n , Collection = global[NAME]\n , proto = Collection && Collection.prototype;\n if(proto && !proto[TO_STRING_TAG])hide(proto, TO_STRING_TAG, NAME);\n Iterators[NAME] = Iterators.Array;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/web.dom.iterable.js\n// module id = 30\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.browser = exports.isDesktop = exports.isMobile = exports.isAndroid = exports.isIpad = exports.isIphone = undefined;\n\nvar _log = require('babel-runtime/core-js/math/log2');\n\nvar _log2 = _interopRequireDefault(_log);\n\nvar _assign = require('babel-runtime/core-js/object/assign');\n\nvar _assign2 = _interopRequireDefault(_assign);\n\nexports.choice = choice;\nexports.mod = mod;\nexports.norm = norm;\nexports.requestAudioContext = requestAudioContext;\nexports.dataURItoBlob = dataURItoBlob;\nexports.ftom = ftom;\nexports.mtof = mtof;\nexports.tap = tap;\nexports.get_diff_bounds = get_diff_bounds;\nexports.get_bounds = get_bounds;\nexports.transpose = transpose;\n\nvar _tone = require('tone');\n\nvar _tone2 = _interopRequireDefault(_tone);\n\nvar _startAudioContext = require('./startAudioContext');\n\nvar _startAudioContext2 = _interopRequireDefault(_startAudioContext);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar isIphone = exports.isIphone = navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i);\nvar isIpad = exports.isIpad = navigator.userAgent.match(/iPad/i);\nvar isAndroid = exports.isAndroid = navigator.userAgent.match(/Android/i);\nvar isMobile = exports.isMobile = isIphone || isIpad || isAndroid;\nvar isDesktop = exports.isDesktop = !isMobile;\n\ndocument.body.classList.add(isMobile ? 'mobile' : 'desktop');\n\nvar browser = exports.browser = { isIphone: isIphone, isIpad: isIpad, isMobile: isMobile, isDesktop: isDesktop };\n\nfunction choice(a) {\n return a[Math.floor(Math.random() * a.length)];\n}\nfunction mod(n, m) {\n return n - m * Math.floor(n / m);\n}\nfunction norm(n, min, max) {\n return (n - min) / (max - min);\n}\n\nfunction requestAudioContext(fn) {\n if (isMobile) {\n var container = document.createElement('div');\n var button = document.createElement('div');\n button.innerHTML = 'Tap to start - please unmute your phone';\n (0, _assign2.default)(container.style, {\n position: 'absolute',\n width: '100%',\n height: '100%',\n zIndex: '10000',\n top: '0px',\n left: '0px',\n backgroundColor: 'rgba(0, 0, 0, 0.8)'\n });\n (0, _assign2.default)(button.style, {\n position: 'absolute',\n left: '50%',\n top: '50%',\n padding: '20px',\n backgroundColor: '#7F33ED',\n color: 'white',\n fontFamily: 'monospace',\n borderRadius: '3px',\n transform: 'translate3D(-50%,-50%,0)',\n textAlign: 'center',\n lineHeight: '1.5'\n });\n container.appendChild(button);\n document.body.appendChild(container);\n _startAudioContext2.default.setContext(_tone2.default.context);\n _startAudioContext2.default.on(button);\n _startAudioContext2.default.onStarted(function (_) {\n container.remove();\n fn();\n });\n } else {\n fn();\n }\n}\n\nfunction dataURItoBlob(dataURI) {\n // convert base64 to raw binary data held in a string\n // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this\n var byteString = atob(dataURI.split(',')[1]);\n\n // separate out the mime component\n var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];\n\n // write the bytes of the string to an ArrayBuffer\n var ab = new ArrayBuffer(byteString.length);\n\n // create a view into the buffer\n var ia = new Uint8Array(ab);\n\n // set the bytes of the buffer to the correct values\n for (var i = 0; i < byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n\n // write the ArrayBuffer to a blob, and you're done\n var blob = new Blob([ab], { type: mimeString });\n return blob;\n}\nfunction ftom(f) {\n // return (Math.log(f) - Math.log(261.626)) / Math.log(2) + 4.0\n return 69 + 12 * (0, _log2.default)(f / 440);\n}\nfunction mtof(m) {\n return 440 * Math.pow(2, (m - 69) / 12);\n}\nfunction tap(fn) {\n return function (e) {\n if (browser.isMobile) fn();else if (e.press) fn();\n };\n}\n\n/* get minimum and maximum variance from row-to-row */\n\nfunction get_diff_bounds(rows) {\n var diffs = rows.map(function (row) {\n var row_min = Math.min.apply(Math, row);\n var row_max = Math.max.apply(Math, row);\n return row_max - row_min;\n });\n var min = Math.min.apply(Math, diffs);\n var max = Math.max.apply(Math, diffs);\n return { min: min, max: max };\n}\n\n/* get minimum and maximum values from a dataset */\n\nfunction get_bounds(dataset) {\n var rows = dataset.lines;\n // rows.forEach(row => row.shift())\n rows = rows.map(function (a) {\n return a.map(function (n) {\n return parseFloat(n);\n });\n });\n var max = rows.reduce(function (a, b) {\n return b.reduce(function (z, bb) {\n return Math.max(z, bb);\n }, a);\n }, -Infinity);\n var min = rows.reduce(function (a, b) {\n return b.reduce(function (z, bb) {\n return Math.min(z, bb);\n }, a);\n }, Infinity);\n return { rows: rows, max: max, min: min };\n}\n\n/* transpose a 2D array */\n\nfunction transpose(a) {\n var i_len = a[0].length;\n var j_len = a.length;\n var T = new Array(i_len);\n for (var i = 0; i < i_len; i++) {\n T[i] = new Array(j_len);\n for (var j = 0; j < j_len; j++) {\n T[i][j] = a[j][i];\n }\n }\n return T;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/util.js\n// module id = 31\n// module chunks = 0","'use strict';\n\nvar buffer = require('buffer');\nvar Buffer = buffer.Buffer;\nvar SlowBuffer = buffer.SlowBuffer;\nvar MAX_LEN = buffer.kMaxLength || 2147483647;\nexports.alloc = function alloc(size, fill, encoding) {\n if (typeof Buffer.alloc === 'function') {\n return Buffer.alloc(size, fill, encoding);\n }\n if (typeof encoding === 'number') {\n throw new TypeError('encoding must not be number');\n }\n if (typeof size !== 'number') {\n throw new TypeError('size must be a number');\n }\n if (size > MAX_LEN) {\n throw new RangeError('size is too large');\n }\n var enc = encoding;\n var _fill = fill;\n if (_fill === undefined) {\n enc = undefined;\n _fill = 0;\n }\n var buf = new Buffer(size);\n if (typeof _fill === 'string') {\n var fillBuf = new Buffer(_fill, enc);\n var flen = fillBuf.length;\n var i = -1;\n while (++i < size) {\n buf[i] = fillBuf[i % flen];\n }\n } else {\n buf.fill(_fill);\n }\n return buf;\n}\nexports.allocUnsafe = function allocUnsafe(size) {\n if (typeof Buffer.allocUnsafe === 'function') {\n return Buffer.allocUnsafe(size);\n }\n if (typeof size !== 'number') {\n throw new TypeError('size must be a number');\n }\n if (size > MAX_LEN) {\n throw new RangeError('size is too large');\n }\n return new Buffer(size);\n}\nexports.from = function from(value, encodingOrOffset, length) {\n if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) {\n return Buffer.from(value, encodingOrOffset, length);\n }\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number');\n }\n if (typeof value === 'string') {\n return new Buffer(value, encodingOrOffset);\n }\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n var offset = encodingOrOffset;\n if (arguments.length === 1) {\n return new Buffer(value);\n }\n if (typeof offset === 'undefined') {\n offset = 0;\n }\n var len = length;\n if (typeof len === 'undefined') {\n len = value.byteLength - offset;\n }\n if (offset >= value.byteLength) {\n throw new RangeError('\\'offset\\' is out of bounds');\n }\n if (len > value.byteLength - offset) {\n throw new RangeError('\\'length\\' is out of bounds');\n }\n return new Buffer(value.slice(offset, offset + len));\n }\n if (Buffer.isBuffer(value)) {\n var out = new Buffer(value.length);\n value.copy(out, 0, 0, value.length);\n return out;\n }\n if (value) {\n if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) {\n return new Buffer(value);\n }\n if (value.type === 'Buffer' && Array.isArray(value.data)) {\n return new Buffer(value.data);\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.');\n}\nexports.allocUnsafeSlow = function allocUnsafeSlow(size) {\n if (typeof Buffer.allocUnsafeSlow === 'function') {\n return Buffer.allocUnsafeSlow(size);\n }\n if (typeof size !== 'number') {\n throw new TypeError('size must be a number');\n }\n if (size >= MAX_LEN) {\n throw new RangeError('size is too large');\n }\n return new SlowBuffer(size);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/buffer-shims/index.js\n// module id = 32\n// module chunks = 0","module.exports = function(it){\n if(typeof it != 'function')throw TypeError(it + ' is not a function!');\n return it;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_a-function.js\n// module id = 33\n// module chunks = 0","// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = require('./_cof')\n , TAG = require('./_wks')('toStringTag')\n // ES3 wrong here\n , ARG = cof(function(){ return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function(it, key){\n try {\n return it[key];\n } catch(e){ /* empty */ }\n};\n\nmodule.exports = function(it){\n var O, T, B;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T\n // builtinTag case\n : ARG ? cof(O)\n // ES3 arguments fallback\n : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_classof.js\n// module id = 34\n// module chunks = 0","// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function(it){\n if(it == undefined)throw TypeError(\"Can't call method on \" + it);\n return it;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_defined.js\n// module id = 35\n// module chunks = 0","var isObject = require('./_is-object')\n , document = require('./_global').document\n // in old IE typeof document.createElement is 'object'\n , is = isObject(document) && isObject(document.createElement);\nmodule.exports = function(it){\n return is ? document.createElement(it) : {};\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_dom-create.js\n// module id = 36\n// module chunks = 0","// IE 8- don't enum bug keys\nmodule.exports = (\n 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\n).split(',');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_enum-bug-keys.js\n// module id = 37\n// module chunks = 0","exports.f = Object.getOwnPropertySymbols;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-gops.js\n// module id = 38\n// module chunks = 0","var shared = require('./_shared')('keys')\n , uid = require('./_uid');\nmodule.exports = function(key){\n return shared[key] || (shared[key] = uid(key));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_shared-key.js\n// module id = 39\n// module chunks = 0","var global = require('./_global')\n , SHARED = '__core-js_shared__'\n , store = global[SHARED] || (global[SHARED] = {});\nmodule.exports = function(key){\n return store[key] || (store[key] = {});\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_shared.js\n// module id = 40\n// module chunks = 0","// 7.1.4 ToInteger\nvar ceil = Math.ceil\n , floor = Math.floor;\nmodule.exports = function(it){\n return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_to-integer.js\n// module id = 41\n// module chunks = 0","// 7.1.15 ToLength\nvar toInteger = require('./_to-integer')\n , min = Math.min;\nmodule.exports = function(it){\n return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_to-length.js\n// module id = 42\n// module chunks = 0","// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = require('./_is-object');\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function(it, S){\n if(!isObject(it))return it;\n var fn, val;\n if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;\n if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;\n if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;\n throw TypeError(\"Can't convert object to primitive value\");\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_to-primitive.js\n// module id = 43\n// module chunks = 0","var global = require('./_global')\n , core = require('./_core')\n , LIBRARY = require('./_library')\n , wksExt = require('./_wks-ext')\n , defineProperty = require('./_object-dp').f;\nmodule.exports = function(name){\n var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {});\n if(name.charAt(0) != '_' && !(name in $Symbol))defineProperty($Symbol, name, {value: wksExt.f(name)});\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_wks-define.js\n// module id = 44\n// module chunks = 0","exports.f = require('./_wks');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_wks-ext.js\n// module id = 45\n// module chunks = 0","var classof = require('./_classof')\n , ITERATOR = require('./_wks')('iterator')\n , Iterators = require('./_iterators');\nmodule.exports = require('./_core').getIteratorMethod = function(it){\n if(it != undefined)return it[ITERATOR]\n || it['@@iterator']\n || Iterators[classof(it)];\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/core.get-iterator-method.js\n// module id = 46\n// module chunks = 0","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n args = Array.prototype.slice.call(arguments, 1);\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n args = Array.prototype.slice.call(arguments, 1);\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/events/events.js\n// module id = 47\n// module chunks = 0","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar Buffer = require('buffer').Buffer;\n\nvar isBufferEncoding = Buffer.isEncoding\n || function(encoding) {\n switch (encoding && encoding.toLowerCase()) {\n case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;\n default: return false;\n }\n }\n\n\nfunction assertEncoding(encoding) {\n if (encoding && !isBufferEncoding(encoding)) {\n throw new Error('Unknown encoding: ' + encoding);\n }\n}\n\n// StringDecoder provides an interface for efficiently splitting a series of\n// buffers into a series of JS strings without breaking apart multi-byte\n// characters. CESU-8 is handled as part of the UTF-8 encoding.\n//\n// @TODO Handling all encodings inside a single object makes it very difficult\n// to reason about this code, so it should be split up in the future.\n// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code\n// points as used by CESU-8.\nvar StringDecoder = exports.StringDecoder = function(encoding) {\n this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');\n assertEncoding(encoding);\n switch (this.encoding) {\n case 'utf8':\n // CESU-8 represents each of Surrogate Pair by 3-bytes\n this.surrogateSize = 3;\n break;\n case 'ucs2':\n case 'utf16le':\n // UTF-16 represents each of Surrogate Pair by 2-bytes\n this.surrogateSize = 2;\n this.detectIncompleteChar = utf16DetectIncompleteChar;\n break;\n case 'base64':\n // Base-64 stores 3 bytes in 4 chars, and pads the remainder.\n this.surrogateSize = 3;\n this.detectIncompleteChar = base64DetectIncompleteChar;\n break;\n default:\n this.write = passThroughWrite;\n return;\n }\n\n // Enough space to store all bytes of a single character. UTF-8 needs 4\n // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).\n this.charBuffer = new Buffer(6);\n // Number of bytes received for the current incomplete multi-byte character.\n this.charReceived = 0;\n // Number of bytes expected for the current incomplete multi-byte character.\n this.charLength = 0;\n};\n\n\n// write decodes the given buffer and returns it as JS string that is\n// guaranteed to not contain any partial multi-byte characters. Any partial\n// character found at the end of the buffer is buffered up, and will be\n// returned when calling write again with the remaining bytes.\n//\n// Note: Converting a Buffer containing an orphan surrogate to a String\n// currently works, but converting a String to a Buffer (via `new Buffer`, or\n// Buffer#write) will replace incomplete surrogates with the unicode\n// replacement character. See https://codereview.chromium.org/121173009/ .\nStringDecoder.prototype.write = function(buffer) {\n var charStr = '';\n // if our last write ended with an incomplete multibyte character\n while (this.charLength) {\n // determine how many remaining bytes this buffer has to offer for this char\n var available = (buffer.length >= this.charLength - this.charReceived) ?\n this.charLength - this.charReceived :\n buffer.length;\n\n // add the new bytes to the char buffer\n buffer.copy(this.charBuffer, this.charReceived, 0, available);\n this.charReceived += available;\n\n if (this.charReceived < this.charLength) {\n // still not enough chars in this buffer? wait for more ...\n return '';\n }\n\n // remove bytes belonging to the current character from the buffer\n buffer = buffer.slice(available, buffer.length);\n\n // get the character that was split\n charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);\n\n // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n var charCode = charStr.charCodeAt(charStr.length - 1);\n if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n this.charLength += this.surrogateSize;\n charStr = '';\n continue;\n }\n this.charReceived = this.charLength = 0;\n\n // if there are no more bytes in this buffer, just emit our char\n if (buffer.length === 0) {\n return charStr;\n }\n break;\n }\n\n // determine and set charLength / charReceived\n this.detectIncompleteChar(buffer);\n\n var end = buffer.length;\n if (this.charLength) {\n // buffer the incomplete character bytes we got\n buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);\n end -= this.charReceived;\n }\n\n charStr += buffer.toString(this.encoding, 0, end);\n\n var end = charStr.length - 1;\n var charCode = charStr.charCodeAt(end);\n // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n var size = this.surrogateSize;\n this.charLength += size;\n this.charReceived += size;\n this.charBuffer.copy(this.charBuffer, size, 0, size);\n buffer.copy(this.charBuffer, 0, 0, size);\n return charStr.substring(0, end);\n }\n\n // or just emit the charStr\n return charStr;\n};\n\n// detectIncompleteChar determines if there is an incomplete UTF-8 character at\n// the end of the given buffer. If so, it sets this.charLength to the byte\n// length that character, and sets this.charReceived to the number of bytes\n// that are available for this character.\nStringDecoder.prototype.detectIncompleteChar = function(buffer) {\n // determine how many bytes we have to check at the end of this buffer\n var i = (buffer.length >= 3) ? 3 : buffer.length;\n\n // Figure out if one of the last i bytes of our buffer announces an\n // incomplete char.\n for (; i > 0; i--) {\n var c = buffer[buffer.length - i];\n\n // See http://en.wikipedia.org/wiki/UTF-8#Description\n\n // 110XXXXX\n if (i == 1 && c >> 5 == 0x06) {\n this.charLength = 2;\n break;\n }\n\n // 1110XXXX\n if (i <= 2 && c >> 4 == 0x0E) {\n this.charLength = 3;\n break;\n }\n\n // 11110XXX\n if (i <= 3 && c >> 3 == 0x1E) {\n this.charLength = 4;\n break;\n }\n }\n this.charReceived = i;\n};\n\nStringDecoder.prototype.end = function(buffer) {\n var res = '';\n if (buffer && buffer.length)\n res = this.write(buffer);\n\n if (this.charReceived) {\n var cr = this.charReceived;\n var buf = this.charBuffer;\n var enc = this.encoding;\n res += buf.slice(0, cr).toString(enc);\n }\n\n return res;\n};\n\nfunction passThroughWrite(buffer) {\n return buffer.toString(this.encoding);\n}\n\nfunction utf16DetectIncompleteChar(buffer) {\n this.charReceived = buffer.length % 2;\n this.charLength = this.charReceived ? 2 : 0;\n}\n\nfunction base64DetectIncompleteChar(buffer) {\n this.charReceived = buffer.length % 3;\n this.charLength = this.charReceived ? 3 : 0;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/node-libs-browser/~/string_decoder/index.js\n// module id = 48\n// module chunks = 0","'use strict';\n\nif (!process.version ||\n process.version.indexOf('v0.') === 0 ||\n process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {\n module.exports = nextTick;\n} else {\n module.exports = process.nextTick;\n}\n\nfunction nextTick(fn, arg1, arg2, arg3) {\n if (typeof fn !== 'function') {\n throw new TypeError('\"callback\" argument must be a function');\n }\n var len = arguments.length;\n var args, i;\n switch (len) {\n case 0:\n case 1:\n return process.nextTick(fn);\n case 2:\n return process.nextTick(function afterTickOne() {\n fn.call(null, arg1);\n });\n case 3:\n return process.nextTick(function afterTickTwo() {\n fn.call(null, arg1, arg2);\n });\n case 4:\n return process.nextTick(function afterTickThree() {\n fn.call(null, arg1, arg2, arg3);\n });\n default:\n args = new Array(len - 1);\n i = 0;\n while (i < args.length) {\n args[i++] = arguments[i];\n }\n return process.nextTick(function afterTick() {\n fn.apply(null, args);\n });\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/process-nextick-args/index.js\n// module id = 49\n// module chunks = 0","// A bit simpler than readable streams.\n// Implement an async ._write(chunk, encoding, cb), and it'll handle all\n// the drain event emission and buffering.\n\n'use strict';\n\nmodule.exports = Writable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;\n/*</replacement>*/\n\n/*<replacement>*/\nvar Duplex;\n/*</replacement>*/\n\nWritable.WritableState = WritableState;\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar internalUtil = {\n deprecate: require('util-deprecate')\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream = require('./internal/streams/stream');\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nutil.inherits(Writable, Stream);\n\nfunction nop() {}\n\nfunction WriteReq(chunk, encoding, cb) {\n this.chunk = chunk;\n this.encoding = encoding;\n this.callback = cb;\n this.next = null;\n}\n\nfunction WritableState(options, stream) {\n Duplex = Duplex || require('./_stream_duplex');\n\n options = options || {};\n\n // object stream flag to indicate whether or not this stream\n // contains buffers or objects.\n this.objectMode = !!options.objectMode;\n\n if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;\n\n // the point at which write() starts returning false\n // Note: 0 is a valid value, means that we always return false if\n // the entire buffer is not flushed immediately on write()\n var hwm = options.highWaterMark;\n var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n // cast to ints.\n this.highWaterMark = ~~this.highWaterMark;\n\n // drain event flag.\n this.needDrain = false;\n // at the start of calling end()\n this.ending = false;\n // when end() has been called, and returned\n this.ended = false;\n // when 'finish' is emitted\n this.finished = false;\n\n // should we decode strings into buffers before passing to _write?\n // this is here so that some node-core streams can optimize string\n // handling at a lower level.\n var noDecode = options.decodeStrings === false;\n this.decodeStrings = !noDecode;\n\n // Crypto is kind of old and crusty. Historically, its default string\n // encoding is 'binary' so we have to make this configurable.\n // Everything else in the universe uses 'utf8', though.\n this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n // not an actual buffer we keep track of, but a measurement\n // of how much we're waiting to get pushed to some underlying\n // socket or file.\n this.length = 0;\n\n // a flag to see when we're in the middle of a write.\n this.writing = false;\n\n // when true all writes will be buffered until .uncork() call\n this.corked = 0;\n\n // a flag to be able to tell if the onwrite cb is called immediately,\n // or on a later tick. We set this to true at first, because any\n // actions that shouldn't happen until \"later\" should generally also\n // not happen before the first write call.\n this.sync = true;\n\n // a flag to know if we're processing previously buffered items, which\n // may call the _write() callback in the same tick, so that we don't\n // end up in an overlapped onwrite situation.\n this.bufferProcessing = false;\n\n // the callback that's passed to _write(chunk,cb)\n this.onwrite = function (er) {\n onwrite(stream, er);\n };\n\n // the callback that the user supplies to write(chunk,encoding,cb)\n this.writecb = null;\n\n // the amount that is being written when _write is called.\n this.writelen = 0;\n\n this.bufferedRequest = null;\n this.lastBufferedRequest = null;\n\n // number of pending user-supplied write callbacks\n // this must be 0 before 'finish' can be emitted\n this.pendingcb = 0;\n\n // emit prefinish if the only thing we're waiting for is _write cbs\n // This is relevant for synchronous Transform streams\n this.prefinished = false;\n\n // True if the error was already emitted and should not be thrown again\n this.errorEmitted = false;\n\n // count buffered requests\n this.bufferedRequestCount = 0;\n\n // allocate the first CorkedRequest, there is always\n // one allocated and free to use, and we maintain at most two\n this.corkedRequestsFree = new CorkedRequest(this);\n}\n\nWritableState.prototype.getBuffer = function getBuffer() {\n var current = this.bufferedRequest;\n var out = [];\n while (current) {\n out.push(current);\n current = current.next;\n }\n return out;\n};\n\n(function () {\n try {\n Object.defineProperty(WritableState.prototype, 'buffer', {\n get: internalUtil.deprecate(function () {\n return this.getBuffer();\n }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')\n });\n } catch (_) {}\n})();\n\n// Test _writableState for inheritance to account for Duplex streams,\n// whose prototype chain only points to Readable.\nvar realHasInstance;\nif (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {\n realHasInstance = Function.prototype[Symbol.hasInstance];\n Object.defineProperty(Writable, Symbol.hasInstance, {\n value: function (object) {\n if (realHasInstance.call(this, object)) return true;\n\n return object && object._writableState instanceof WritableState;\n }\n });\n} else {\n realHasInstance = function (object) {\n return object instanceof this;\n };\n}\n\nfunction Writable(options) {\n Duplex = Duplex || require('./_stream_duplex');\n\n // Writable ctor is applied to Duplexes, too.\n // `realHasInstance` is necessary because using plain `instanceof`\n // would return false, as no `_writableState` property is attached.\n\n // Trying to use the custom `instanceof` for Writable here will also break the\n // Node.js LazyTransform implementation, which has a non-trivial getter for\n // `_writableState` that would lead to infinite recursion.\n if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) {\n return new Writable(options);\n }\n\n this._writableState = new WritableState(options, this);\n\n // legacy.\n this.writable = true;\n\n if (options) {\n if (typeof options.write === 'function') this._write = options.write;\n\n if (typeof options.writev === 'function') this._writev = options.writev;\n }\n\n Stream.call(this);\n}\n\n// Otherwise people can pipe Writable streams, which is just wrong.\nWritable.prototype.pipe = function () {\n this.emit('error', new Error('Cannot pipe, not readable'));\n};\n\nfunction writeAfterEnd(stream, cb) {\n var er = new Error('write after end');\n // TODO: defer error events consistently everywhere, not just the cb\n stream.emit('error', er);\n processNextTick(cb, er);\n}\n\n// Checks that a user-supplied chunk is valid, especially for the particular\n// mode the stream is in. Currently this means that `null` is never accepted\n// and undefined/non-string values are only allowed in object mode.\nfunction validChunk(stream, state, chunk, cb) {\n var valid = true;\n var er = false;\n\n if (chunk === null) {\n er = new TypeError('May not write null values to stream');\n } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {\n er = new TypeError('Invalid non-string/buffer chunk');\n }\n if (er) {\n stream.emit('error', er);\n processNextTick(cb, er);\n valid = false;\n }\n return valid;\n}\n\nWritable.prototype.write = function (chunk, encoding, cb) {\n var state = this._writableState;\n var ret = false;\n var isBuf = Buffer.isBuffer(chunk);\n\n if (typeof encoding === 'function') {\n cb = encoding;\n encoding = null;\n }\n\n if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;\n\n if (typeof cb !== 'function') cb = nop;\n\n if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {\n state.pendingcb++;\n ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);\n }\n\n return ret;\n};\n\nWritable.prototype.cork = function () {\n var state = this._writableState;\n\n state.corked++;\n};\n\nWritable.prototype.uncork = function () {\n var state = this._writableState;\n\n if (state.corked) {\n state.corked--;\n\n if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);\n }\n};\n\nWritable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {\n // node::ParseEncoding() requires lower case.\n if (typeof encoding === 'string') encoding = encoding.toLowerCase();\n if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);\n this._writableState.defaultEncoding = encoding;\n return this;\n};\n\nfunction decodeChunk(state, chunk, encoding) {\n if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {\n chunk = bufferShim.from(chunk, encoding);\n }\n return chunk;\n}\n\n// if we're already writing something, then just put this\n// in the queue, and wait our turn. Otherwise, call _write\n// If we return false, then we need a drain event, so set that flag.\nfunction writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {\n if (!isBuf) {\n chunk = decodeChunk(state, chunk, encoding);\n if (Buffer.isBuffer(chunk)) encoding = 'buffer';\n }\n var len = state.objectMode ? 1 : chunk.length;\n\n state.length += len;\n\n var ret = state.length < state.highWaterMark;\n // we must ensure that previous needDrain will not be reset to false.\n if (!ret) state.needDrain = true;\n\n if (state.writing || state.corked) {\n var last = state.lastBufferedRequest;\n state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);\n if (last) {\n last.next = state.lastBufferedRequest;\n } else {\n state.bufferedRequest = state.lastBufferedRequest;\n }\n state.bufferedRequestCount += 1;\n } else {\n doWrite(stream, state, false, len, chunk, encoding, cb);\n }\n\n return ret;\n}\n\nfunction doWrite(stream, state, writev, len, chunk, encoding, cb) {\n state.writelen = len;\n state.writecb = cb;\n state.writing = true;\n state.sync = true;\n if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);\n state.sync = false;\n}\n\nfunction onwriteError(stream, state, sync, er, cb) {\n --state.pendingcb;\n if (sync) processNextTick(cb, er);else cb(er);\n\n stream._writableState.errorEmitted = true;\n stream.emit('error', er);\n}\n\nfunction onwriteStateUpdate(state) {\n state.writing = false;\n state.writecb = null;\n state.length -= state.writelen;\n state.writelen = 0;\n}\n\nfunction onwrite(stream, er) {\n var state = stream._writableState;\n var sync = state.sync;\n var cb = state.writecb;\n\n onwriteStateUpdate(state);\n\n if (er) onwriteError(stream, state, sync, er, cb);else {\n // Check if we're actually ready to finish, but don't emit yet\n var finished = needFinish(state);\n\n if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {\n clearBuffer(stream, state);\n }\n\n if (sync) {\n /*<replacement>*/\n asyncWrite(afterWrite, stream, state, finished, cb);\n /*</replacement>*/\n } else {\n afterWrite(stream, state, finished, cb);\n }\n }\n}\n\nfunction afterWrite(stream, state, finished, cb) {\n if (!finished) onwriteDrain(stream, state);\n state.pendingcb--;\n cb();\n finishMaybe(stream, state);\n}\n\n// Must force callback to be called on nextTick, so that we don't\n// emit 'drain' before the write() consumer gets the 'false' return\n// value, and has a chance to attach a 'drain' listener.\nfunction onwriteDrain(stream, state) {\n if (state.length === 0 && state.needDrain) {\n state.needDrain = false;\n stream.emit('drain');\n }\n}\n\n// if there's something in the buffer waiting, then process it\nfunction clearBuffer(stream, state) {\n state.bufferProcessing = true;\n var entry = state.bufferedRequest;\n\n if (stream._writev && entry && entry.next) {\n // Fast case, write everything using _writev()\n var l = state.bufferedRequestCount;\n var buffer = new Array(l);\n var holder = state.corkedRequestsFree;\n holder.entry = entry;\n\n var count = 0;\n while (entry) {\n buffer[count] = entry;\n entry = entry.next;\n count += 1;\n }\n\n doWrite(stream, state, true, state.length, buffer, '', holder.finish);\n\n // doWrite is almost always async, defer these to save a bit of time\n // as the hot path ends with doWrite\n state.pendingcb++;\n state.lastBufferedRequest = null;\n if (holder.next) {\n state.corkedRequestsFree = holder.next;\n holder.next = null;\n } else {\n state.corkedRequestsFree = new CorkedRequest(state);\n }\n } else {\n // Slow case, write chunks one-by-one\n while (entry) {\n var chunk = entry.chunk;\n var encoding = entry.encoding;\n var cb = entry.callback;\n var len = state.objectMode ? 1 : chunk.length;\n\n doWrite(stream, state, false, len, chunk, encoding, cb);\n entry = entry.next;\n // if we didn't call the onwrite immediately, then\n // it means that we need to wait until it does.\n // also, that means that the chunk and cb are currently\n // being processed, so move the buffer counter past them.\n if (state.writing) {\n break;\n }\n }\n\n if (entry === null) state.lastBufferedRequest = null;\n }\n\n state.bufferedRequestCount = 0;\n state.bufferedRequest = entry;\n state.bufferProcessing = false;\n}\n\nWritable.prototype._write = function (chunk, encoding, cb) {\n cb(new Error('_write() is not implemented'));\n};\n\nWritable.prototype._writev = null;\n\nWritable.prototype.end = function (chunk, encoding, cb) {\n var state = this._writableState;\n\n if (typeof chunk === 'function') {\n cb = chunk;\n chunk = null;\n encoding = null;\n } else if (typeof encoding === 'function') {\n cb = encoding;\n encoding = null;\n }\n\n if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);\n\n // .end() fully uncorks\n if (state.corked) {\n state.corked = 1;\n this.uncork();\n }\n\n // ignore unnecessary end() calls.\n if (!state.ending && !state.finished) endWritable(this, state, cb);\n};\n\nfunction needFinish(state) {\n return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;\n}\n\nfunction prefinish(stream, state) {\n if (!state.prefinished) {\n state.prefinished = true;\n stream.emit('prefinish');\n }\n}\n\nfunction finishMaybe(stream, state) {\n var need = needFinish(state);\n if (need) {\n if (state.pendingcb === 0) {\n prefinish(stream, state);\n state.finished = true;\n stream.emit('finish');\n } else {\n prefinish(stream, state);\n }\n }\n return need;\n}\n\nfunction endWritable(stream, state, cb) {\n state.ending = true;\n finishMaybe(stream, state);\n if (cb) {\n if (state.finished) processNextTick(cb);else stream.once('finish', cb);\n }\n state.ended = true;\n stream.writable = false;\n}\n\n// It seems a linked list but it is not\n// there will be only 2 of these for each stream\nfunction CorkedRequest(state) {\n var _this = this;\n\n this.next = null;\n this.entry = null;\n this.finish = function (err) {\n var entry = _this.entry;\n _this.entry = null;\n while (entry) {\n var cb = entry.callback;\n state.pendingcb--;\n cb(err);\n entry = entry.next;\n }\n if (state.corkedRequestsFree) {\n state.corkedRequestsFree.next = _this;\n } else {\n state.corkedRequestsFree = _this;\n }\n };\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/readable-stream/lib/_stream_writable.js\n// module id = 50\n// module chunks = 0","exports = module.exports = require('./lib/_stream_readable.js');\nexports.Stream = exports;\nexports.Readable = exports;\nexports.Writable = require('./lib/_stream_writable.js');\nexports.Duplex = require('./lib/_stream_duplex.js');\nexports.Transform = require('./lib/_stream_transform.js');\nexports.PassThrough = require('./lib/_stream_passthrough.js');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/readable-stream/readable-browser.js\n// module id = 51\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _tone = require('tone');\n\nvar _tone2 = _interopRequireDefault(_tone);\n\nvar _util = require('./util');\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar player_count = 2;\nvar sample_index = 0;\n\nvar compressor = new _tone2.default.Compressor(-30, 3).toMaster();\n\nvar samples = [{ root: 226, fn: 'samples/380737__cabled-mess__sansula-01-a-raw.mp3' }, { root: 267, fn: 'samples/380736__cabled-mess__sansula-02-c-raw.mp3' }, { root: 340, fn: 'samples/380735__cabled-mess__sansula-03-e-raw.mp3' }, { root: 452, fn: 'samples/380733__cabled-mess__sansula-06-a-02-raw.mp3' }];\n\nsamples.forEach(function (sample) {\n sample.players = [];\n sample.index = -1;\n for (var i = 0; i < player_count; i++) {\n var fn = sample.fn;\n if (window.location.href.match(/asdf.us/)) {\n fn = '//asdf.us/kalimba/' + fn;\n }\n var player = new _tone2.default.Player({\n url: fn,\n retrigger: true,\n playbackRate: 1\n });\n player.connect(compressor);\n sample.players.push(player);\n }\n});\n\nfunction play(freq) {\n var volume = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.0;\n\n var best = { sample: samples[sample_index] };\n sample_index = (sample_index + 1) % samples.length;\n best.sample.index = (best.sample.index + 1) % player_count;\n\n var player = best.sample.players[best.sample.index];\n player.playbackRate = freq / best.sample.root;\n // console.log(player)\n player.volume.value = volume;\n setTimeout(function () {\n player.start();\n }, 0);\n}\n\nexports.default = { play: play };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/kalimba.js\n// module id = 52\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _intonation = require('./intonation');\n\nvar _intonation2 = _interopRequireDefault(_intonation);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar meantone = '! meanquar.scl\\n!\\n1/4-comma meantone scale. Pietro Aaron\\'s temperament (1523)\\n 12\\n!\\n 76.04900\\n 193.15686\\n 310.26471\\n 5/4\\n 503.42157\\n 579.47057\\n 696.57843\\n 25/16\\n 889.73529\\n 1006.84314\\n 1082.89214\\n 2/1\\n';\n\nvar shares = '! shares.scl\\n!\\nA scale based on shares of wealth\\n!\\n1.\\n5.\\n15.\\n32.\\n52.\\n78.\\n116.\\n182.\\n521.\\n1000.\\n';\n\nvar shares_sum = '! shares_sum.scl\\n!\\nA scale based on summing shares of wealth\\n!\\n1\\n6.0\\n21.0\\n53.0\\n105.0\\n183.0\\n299.0\\n481.0\\n1002.0\\n2/1\\n';\n\nvar mavila = '! mavila12.scl\\n!\\nA 12-note mavila scale (for warping meantone-based music), 5-limit TOP\\n 12\\n!\\n-30.99719\\n 163.50770\\n 358.01258\\n 327.01540\\n 521.52028\\n 490.52310\\n 685.02798\\n 654.03080\\n 848.53568\\n 1043.04057\\n 1012.04338\\n 1206.54826\\n';\n\nvar carlos_alpha = '! carlos_alpha.scl\\n!\\nWendy Carlos\\' Alpha scale with perfect fifth divided in nine\\n 18\\n!\\n 78.00000\\n 156.00000\\n 234.00000\\n 312.00000\\n 390.00000\\n 468.00000\\n 546.00000\\n 624.00000\\n 702.00000\\n 780.00000\\n 858.00000\\n 936.00000\\n 1014.00000\\n 1092.00000\\n 1170.00000\\n 1248.00000\\n 1326.00000\\n 1404.00000\\n';\n\nvar lamonte = '! young-lm_piano.scl\\n!\\nLaMonte Young\\'s Well-Tempered Piano\\n12\\n!\\n567/512\\n9/8\\n147/128\\n21/16\\n1323/1024\\n189/128\\n3/2\\n49/32\\n7/4\\n441/256\\n63/32\\n2/1\\n';\n\nvar colundi = '! colundi.scl\\n!\\nColundi scale\\n10\\n!\\n9/8\\n171/140\\n137/112\\n43/35\\n3/2\\n421/280\\n213/140\\n263/150\\n66/35\\n2/1\\n';\n\nvar liu_major = '! liu_major.scl\\n!\\nLinus Liu\\'s Major Scale, see his 1978 book, \"Intonation Theory\" \\n 7\\n!\\n 10/9\\n 100/81\\n 4/3\\n 3/2\\n 5/3\\n 50/27\\n 2/1\\n';\nvar liu_pentatonic = '! liu_pent.scl\\n!\\nLinus Liu\\'s \"pentatonic scale\" \\n 7\\n!\\n 9/8\\n 81/64\\n 27/20\\n 3/2\\n 27/16\\n 243/128\\n 81/40\\n';\n\nvar liu_minor = '! LIU_MINor.scl\\n!\\nLinus Liu\\'s Harmonic Minor \\n 7\\n!\\n 10/9\\n 6/5\\n 4/3\\n 40/27\\n 8/5\\n 50/27\\n 2/1\\n';\n\nvar liu_melodic_minor = '! liu_mel.scl\\n!\\nLinus Liu\\'s Melodic Minor, use 5 and 7 descending and 6 and 8 ascending \\n 9\\n!\\n 10/9\\n 6/5\\n 4/3\\n 3/2\\n 81/50\\n 5/3\\n 9/5\\n 50/27\\n 2/1\\n';\n\nvar scales = [{\n intervals: '1/1 9/8 5/4 4/3 3/2 5/3 15/8 2/1',\n name: \"harmonic scale\"\n}, {\n root: 450,\n intervals: '1/1 9/8 5/4 4/3 3/2 5/3 15/8 2/1',\n name: \"harmonic scale @ 450\"\n}, {\n tet: 5\n}, {\n tet: 12\n}, {\n tet: 17\n}, {\n intervals: '1/1 81/80 33/32 21/20 16/15 12/11 11/10 10/9 9/8 8/7 7/6 32/27 6/5 11/9 5/4 14/11 9/7 21/16 4/3 27/20 11/8 7/5 10/7 16/11 40/27 3/2 32/21 14/9 11/7 8/5 18/11 5/3 27/16 12/7 7/4 16/9 9/5 20/11 11/6 15/8 40/21 64/33 160/81 2/1',\n name: \"harry partch scale\"\n}, {\n scl: lamonte\n}, {\n scl: meantone\n}, {\n scl: mavila\n}, {\n scl: carlos_alpha\n}, {\n scl: colundi\n}, {\n scl: shares\n}, {\n scl: shares_sum\n}, {\n scl: liu_major\n}, {\n scl: liu_minor\n}, {\n scl: liu_melodic_minor\n}, {\n scl: liu_pentatonic\n}].map(function (opt) {\n return new _intonation2.default(opt);\n});\n\nvar scale = scales[0];\nvar handleChange = function handleChange() {};\n\nfunction build() {\n scales.forEach(function (scale, i) {\n scale.heading = document.createElement('div');\n scale.heading.innerHTML = scale.name;\n scale.heading.classList.add('heading');\n scale.heading.addEventListener('click', function () {\n pick(i);\n });\n scale_list.appendChild(scale.heading);\n });\n pick(0);\n}\nfunction build_options(el) {\n scales.forEach(function (scale, i) {\n var option = document.createElement('option');\n option.innerHTML = scale.name;\n option.value = i;\n el.appendChild(option);\n });\n el.addEventListener('input', function (e) {\n pick(e.target.value);\n });\n pick(0);\n}\n\nfunction pick(i) {\n if (scale) {\n scale.heading && scale.heading.classList.remove('selected');\n }\n scale = scales[i];\n scale.heading && scale.heading.classList.add('selected');\n handleChange(scale);\n}\n\nfunction current() {\n return scale;\n}\n\nfunction onChange(fn) {\n handleChange = fn;\n}\n\nfunction names() {\n return scales.map(function (scale) {\n return scale.name;\n });\n}\n\nexports.default = { scales: scales, current: current, build: build, build_options: build_options, pick: pick, names: names, onChange: onChange };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/scales.js\n// module id = 53\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.nx = undefined;\n\nvar _keys = require('babel-runtime/core-js/object/keys');\n\nvar _keys2 = _interopRequireDefault(_keys);\n\nexports.update_value_on_change = update_value_on_change;\nexports.update_radio_value_on_change = update_radio_value_on_change;\nexports.build_options = build_options;\n\nvar _nexusui = require('nexusui');\n\nvar _nexusui2 = _interopRequireDefault(_nexusui);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar nx = exports.nx = window.nx = {};\n\n/* ui - update an int/float value */\n\nfunction update_value_on_change(el, id, is_int, fn) {\n var label = document.querySelector(id + ' + .val');\n var update = function update(v) {\n label.innerHTML = is_int ? parseInt(v) : v.toFixed(2);\n fn && fn(v);\n };\n el.on('change', update);\n update(el.value);\n el.update = update;\n}\n\n/* ui - update a radio button */\n\nfunction update_radio_value_on_change(el, id, values, fn) {\n var old_v = el.active;\n var label = document.querySelector(id + ' + .val');\n var update = function update(v) {\n if (v === -1) {\n v = el.active = old_v;\n } else {\n old_v = v;\n }\n label.innerHTML = values[v][1];\n fn && fn(v);\n };\n el.on('change', update);\n update(el.active);\n el.update = update;\n}\n\n/* ui - bind/build a select dropdown */\n\nfunction build_options(el, lists, fn) {\n (0, _keys2.default)(lists).forEach(function (key) {\n var list = lists[key];\n var option = document.createElement('option');\n option.innerHTML = list.name;\n option.value = key;\n el.appendChild(option);\n });\n el.addEventListener('input', function (e) {\n fn(e.target.value);\n });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/ui.js\n// module id = 54\n// module chunks = 0","\"use strict\";\n\nexports.__esModule = true;\n\nvar _isIterable2 = require(\"../core-js/is-iterable\");\n\nvar _isIterable3 = _interopRequireDefault(_isIterable2);\n\nvar _getIterator2 = require(\"../core-js/get-iterator\");\n\nvar _getIterator3 = _interopRequireDefault(_getIterator2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nexports.default = function () {\n function sliceIterator(arr, i) {\n var _arr = [];\n var _n = true;\n var _d = false;\n var _e = undefined;\n\n try {\n for (var _i = (0, _getIterator3.default)(arr), _s; !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"]) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n }\n\n return function (arr, i) {\n if (Array.isArray(arr)) {\n return arr;\n } else if ((0, _isIterable3.default)(Object(arr))) {\n return sliceIterator(arr, i);\n } else {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance\");\n }\n };\n}();\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/babel-runtime/helpers/slicedToArray.js\n// module id = 55\n// module chunks = 0","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Nexus\"] = factory();\n\telse\n\t\troot[\"Nexus\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar NexusUI = _interopRequire(__webpack_require__(1));\n\t\n\tmodule.exports = NexusUI;\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\texports.colors = colors;\n\texports.context = context;\n\texports.clock = clock;\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\"use strict\";\n\t\n\tvar Interfaces = _interopRequire(__webpack_require__(2));\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar Rack = _interopRequire(__webpack_require__(38));\n\t\n\tvar Tune = _interopRequire(__webpack_require__(40));\n\t\n\tvar Transform = _interopRequireWildcard(__webpack_require__(39));\n\t\n\tvar Counter = __webpack_require__(28);\n\tvar Radio = __webpack_require__(41);\n\tvar Drunk = __webpack_require__(27);\n\tvar Sequence = __webpack_require__(26);\n\tvar Matrix = __webpack_require__(25);\n\t\n\tvar WAAClock = _interopRequire(__webpack_require__(42));\n\t\n\tvar Interval = _interopRequire(__webpack_require__(45));\n\t\n\t/**\n\tNexusUI => created as Nexus\n\t*/\n\t\n\tvar NexusUI = (function () {\n\t function NexusUI(context) {\n\t _classCallCheck(this, NexusUI);\n\t\n\t for (var key in Interfaces) {\n\t this[key] = Interfaces[key];\n\t }\n\t\n\t for (var key in math) {\n\t this[key] = math[key];\n\t }\n\t\n\t var Core = {\n\t Rack: Rack\n\t };\n\t\n\t var Models = {\n\t Counter: Counter,\n\t Radio: Radio,\n\t Drunk: Drunk,\n\t Sequence: Sequence,\n\t Matrix: Matrix\n\t };\n\t\n\t for (var key in Models) {\n\t this[key] = Models[key];\n\t }\n\t\n\t for (var key in Core) {\n\t this[key] = Core[key];\n\t }\n\t\n\t var DefaultContext = window.AudioContext || window.webkitAudioContext;\n\t this._context = context || new DefaultContext();\n\t\n\t this.tune = new Tune();\n\t this.note = this.tune.note.bind(this.tune);\n\t\n\t this.clock = new WAAClock(this._context);\n\t this.clock.start();\n\t this.Interval = Interval;\n\t\n\t this.colors = {\n\t accent: \"#2bb\",\n\t fill: \"#eee\",\n\t light: \"#fff\",\n\t dark: \"#333\",\n\t mediumLight: \"#ccc\",\n\t mediumDark: \"#666\"\n\t };\n\t\n\t this.transform = Transform;\n\t this.add = Transform.add;\n\t\n\t this.Add = {};\n\t for (var key in Interfaces) {\n\t this.Add[key] = Transform.add.bind(this, key);\n\t }\n\t\n\t /* create default component size */\n\t /* jshint ignore:start */\n\t var existingStylesheets = document.getElementsByTagName(\"style\");\n\t var defaultSizeDeclaration = \"[nexus-ui]{height:5000px;width:5000px}\";\n\t var defaultStyleNode = document.createElement(\"style\");\n\t defaultStyleNode.type = \"text/css\";\n\t defaultStyleNode.innerHTML = defaultSizeDeclaration;\n\t if (existingStylesheets.length > 0) {\n\t var parent = existingStylesheets[0].parentNode;\n\t parent.insertBefore(defaultStyleNode, existingStylesheets[0]);\n\t } else {\n\t document.write(\"<style>\" + defaultSizeDeclaration + \"</style>\");\n\t }\n\t /* jshint ignore:end */\n\t }\n\t\n\t _createClass(NexusUI, {\n\t context: {\n\t get: function () {\n\t return this._context;\n\t },\n\t set: function (ctx) {\n\t this.clock.stop();\n\t this._context = ctx;\n\t this.clock = new WAAClock(this.context);\n\t this.clock.start();\n\t }\n\t }\n\t });\n\t\n\t return NexusUI;\n\t})();\n\t\n\tvar Nexus = new NexusUI();\n\t\n\tfunction colors() {\n\t return Nexus.colors;\n\t}\n\t\n\tfunction context() {\n\t return Nexus.context;\n\t}\n\t\n\tfunction clock() {\n\t return Nexus.clock;\n\t}\n\t\n\texports[\"default\"] = Nexus;\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tmodule.exports = {\n\t Position: __webpack_require__(3),\n\t Slider: __webpack_require__(14),\n\t Toggle: __webpack_require__(15),\n\t /* Range: require('./rangeslider'),\n\t Waveform: require('./waveform'), */\n\t Button: __webpack_require__(16),\n\t TextButton: __webpack_require__(18),\n\t RadioButton: __webpack_require__(19),\n\t Number: __webpack_require__(20),\n\t Select: __webpack_require__(21),\n\t Dial: __webpack_require__(22),\n\t Piano: __webpack_require__(23),\n\t Sequencer: __webpack_require__(24),\n\t Pan2D: __webpack_require__(29),\n\t Tilt: __webpack_require__(30),\n\t Multislider: __webpack_require__(31),\n\t Pan: __webpack_require__(33),\n\t Envelope: __webpack_require__(34),\n\t Spectrogram: __webpack_require__(35),\n\t Meter: __webpack_require__(36),\n\t Oscilloscope: __webpack_require__(37)\n\t};\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\t\n\tvar Interaction = _interopRequireWildcard(__webpack_require__(12));\n\t\n\t/**\n\t* Position\n\t*\n\t* @description Two-dimensional touch slider.\n\t*\n\t* @demo <span nexus-ui=\"position\"></span>\n\t*\n\t* @example\n\t* var position = new Nexus.Position('#target')\n\t*\n\t* @example\n\t* var position = new Nexus.Position('#target',{\n\t* 'size': [200,200],\n\t* 'mode': 'absolute', // \"absolute\" or \"relative\"\n\t* 'x': 0.5, // initial x value\n\t* 'minX': 0,\n\t* 'maxX': 1,\n\t* 'stepX': 0,\n\t* 'y': 0.5, // initial y value\n\t* 'minY': 0,\n\t* 'maxY': 1,\n\t* 'stepY': 0\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data is an object with x and y properties containing the x and y values of the interface.\n\t*\n\t* @outputexample\n\t* position.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Position = (function (_Interface) {\n\t function Position() {\n\t _classCallCheck(this, Position);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [200, 200],\n\t mode: \"absolute\",\n\t minX: 0,\n\t maxX: 1,\n\t stepX: 0,\n\t x: 0.5,\n\t minY: 0,\n\t maxY: 1,\n\t stepY: 0,\n\t y: 0.5\n\t };\n\t\n\t _get(Object.getPrototypeOf(Position.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._x = new Step(this.settings.minX, this.settings.maxX, this.settings.stepX, this.settings.x);\n\t this._y = new Step(this.settings.minY, this.settings.maxY, this.settings.stepY, this.settings.y);\n\t\n\t this.position = {\n\t x: new Interaction.Handle(this.settings.mode, \"horizontal\", [0, this.width], [this.height, 0]),\n\t y: new Interaction.Handle(this.settings.mode, \"vertical\", [0, this.width], [this.height, 0])\n\t };\n\t this.position.x.value = this._x.normalized;\n\t this.position.y.value = this._y.normalized;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(Position, _Interface);\n\t\n\t _createClass(Position, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.knob = svg.create(\"circle\");\n\t this.element.appendChild(this.knob);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t this.position.x.resize([0, this.width], [this.height, 0]);\n\t this.position.y.resize([0, this.width], [this.height, 0]);\n\t\n\t this._minDimension = Math.min(this.width, this.height);\n\t\n\t this.knobRadius = {\n\t off: ~ ~(this._minDimension / 100) * 5 + 5 };\n\t this.knobRadius.on = this.knobRadius.off * 2;\n\t\n\t this.knob.setAttribute(\"cx\", this.width / 2);\n\t this.knob.setAttribute(\"cy\", this.height / 2);\n\t this.knob.setAttribute(\"r\", this.knobRadius.off);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.knob.setAttribute(\"fill\", this.colors.accent);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (this.clicked) {\n\t // this.knobRadius = 30;\n\t this.knob.setAttribute(\"r\", this.knobRadius.on);\n\t } else {\n\t // this.knobRadius = 15;\n\t this.knob.setAttribute(\"r\", this.knobRadius.off);\n\t }\n\t\n\t this.knobCoordinates = {\n\t x: this._x.normalized * this.width,\n\t y: this.height - this._y.normalized * this.height\n\t };\n\t\n\t this.knob.setAttribute(\"cx\", this.knobCoordinates.x);\n\t this.knob.setAttribute(\"cy\", this.knobCoordinates.y);\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.position.x.anchor = this.mouse;\n\t this.position.y.anchor = this.mouse;\n\t this.move();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.clicked) {\n\t this.position.x.update(this.mouse);\n\t this.position.y.update(this.mouse);\n\t this._x.updateNormal(this.position.x.value);\n\t this._y.updateNormal(this.position.y.value);\n\t this.emit(\"change\", {\n\t x: this._x.value,\n\t y: this._y.value\n\t });\n\t this.render();\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t this.render();\n\t }\n\t },\n\t x: {\n\t\n\t /**\n\t * The interface's x value. When set, it will automatically adjust to fit min/max/step settings of the interface.\n\t * @type {object}\n\t * @example position.x = 0.5;\n\t */\n\t\n\t get: function () {\n\t return this._x.value;\n\t },\n\t set: function (value) {\n\t this._x.update(value);\n\t this.emit(\"change\", {\n\t x: this._x.value,\n\t y: this._y.value\n\t });\n\t this.render();\n\t }\n\t },\n\t y: {\n\t\n\t /**\n\t * The interface's y values. When set, it will automatically adjust to fit min/max/step settings of the interface.\n\t * @type {object}\n\t * @example position.x = 0.5;\n\t */\n\t\n\t get: function () {\n\t return this._y.value;\n\t },\n\t set: function (value) {\n\t this._y.update(value);\n\t this.emit(\"change\", {\n\t x: this._x.value,\n\t y: this._y.value\n\t });\n\t this.render();\n\t }\n\t },\n\t normalized: {\n\t get: function () {\n\t return {\n\t x: this._x.normalized,\n\t y: this._y.normalized\n\t };\n\t }\n\t },\n\t minX: {\n\t\n\t /**\n\t * The lower limit of value on the x axis\n\t * @type {object}\n\t */\n\t\n\t get: function () {\n\t return this._x.min;\n\t },\n\t set: function (v) {\n\t this._x.min = v;\n\t this.render();\n\t }\n\t },\n\t minY: {\n\t\n\t /**\n\t * The lower limit of value on the y axis\n\t * @type {object}\n\t */\n\t\n\t get: function () {\n\t return this._y.min;\n\t },\n\t set: function (v) {\n\t this._y.min = v;\n\t this.render();\n\t }\n\t },\n\t maxX: {\n\t\n\t /**\n\t * The upper limit of value on the x axis\n\t * @type {object}\n\t */\n\t\n\t get: function () {\n\t return this._x.max;\n\t },\n\t set: function (v) {\n\t this._x.max = v;\n\t this.render();\n\t }\n\t },\n\t maxY: {\n\t\n\t /**\n\t * The upper limit of value on the y axis\n\t * @type {object}\n\t */\n\t\n\t get: function () {\n\t return this._y.max;\n\t },\n\t set: function (v) {\n\t this._y.max = v;\n\t this.render();\n\t }\n\t },\n\t stepX: {\n\t\n\t /**\n\t * The incremental step of values on the x axis\n\t * @type {object}\n\t */\n\t\n\t get: function () {\n\t return this._x.step;\n\t },\n\t set: function (v) {\n\t this._x.step = v;\n\t this.render();\n\t }\n\t },\n\t stepY: {\n\t\n\t /**\n\t * The incremental step of values on the y axis\n\t * @type {object}\n\t */\n\t\n\t get: function () {\n\t return this._y.step;\n\t },\n\t set: function (v) {\n\t this._y.step = v;\n\t this.render();\n\t }\n\t },\n\t mode: {\n\t\n\t /**\n\t Absolute mode (position's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: \"absolute\".\n\t @type {string}\n\t @example position.mode = \"relative\";\n\t */\n\t\n\t get: function () {\n\t return this.position.x.mode;\n\t },\n\t set: function (v) {\n\t this.position.x.mode = v;\n\t this.position.y.mode = v;\n\t }\n\t }\n\t });\n\t\n\t return Position;\n\t})(Interface);\n\t\n\tmodule.exports = Position;\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar math = __webpack_require__(5);\n\t\n\tmodule.exports = {\n\t\n\t create: function (type) {\n\t return document.createElementNS(\"http://www.w3.org/2000/svg\", type);\n\t },\n\t\n\t arc: function (x, y, radius, startAngle, endAngle) {\n\t\n\t var start = math.toCartesian(radius, endAngle);\n\t var end = math.toCartesian(radius, startAngle);\n\t\n\t var largeArcFlag = endAngle - startAngle <= 180 ? \"0\" : \"1\";\n\t\n\t var d = [\"M\", start.x + x, start.y + y, \"A\", radius, radius, 0, largeArcFlag, 0, end.x + x, end.y + y].join(\" \");\n\t\n\t return d;\n\t },\n\t\n\t radialGradient: function (defs, numberOfStops) {\n\t\n\t var id = \"gradient\" + math.ri(100000000000);\n\t var stops = [];\n\t\n\t var gradient = document.createElementNS(\"http://www.w3.org/2000/svg\", \"radialGradient\");\n\t gradient.setAttribute(\"id\", id);\n\t gradient.setAttribute(\"cx\", \"50%\");\n\t gradient.setAttribute(\"cy\", \"50%\");\n\t gradient.setAttribute(\"r\", \"50%\");\n\t\n\t defs.appendChild(gradient);\n\t\n\t for (var i = 0; i < numberOfStops; i++) {\n\t var _stop = document.createElementNS(\"http://www.w3.org/2000/svg\", \"stop\");\n\t _stop.setAttribute(\"id\", \"stop\" + i);\n\t //stop.setAttribute('offset', '70%');\n\t //stop.setAttribute('stop-color', 'White');\n\t gradient.appendChild(_stop);\n\t stops.push(_stop);\n\t }\n\t\n\t return {\n\t id: id,\n\t stops: stops,\n\t element: gradient\n\t };\n\t }\n\t\n\t};\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\t/**\n\t * Limit a number to within a minimum and maximum\n\t * @param {number} value Input value\n\t * @param {number} min Lower limit\n\t * @param {number} max Upper limit\n\t * @return {number} The input value constrained within the lower and upper limits\n\t * @example\n\t * Nexus.clip(11,0,10) // returns 10\n\t * Nexus.clip(-1,0,10) // returns 0\n\t * Nexus.clip(5,0,10) // returns 5\n\t */\n\t\n\texports.clip = function (value, min, max) {\n\t return Math.min(Math.max(value, min), max);\n\t};\n\t\n\texports.normalize = function (value, min, max) {\n\t return (value - min) / (max - min);\n\t};\n\t\n\t/**\n\t * Scale a value from one range to another range.\n\t * @param {number} inNum Input value\n\t * @param {number} inMin Input range minimum\n\t * @param {number} inMax Input range maximum\n\t * @param {number} outMin Output range minimum\n\t * @param {number} outMax Output range maximum\n\t * @return {number} The input value scaled to its new range\n\t * @example\n\t * Nexus.scale(0.5,0,1,0,10) // returns 5\n\t * Nexus.scale(0.9,0,1,1,0) // returns 0.1\n\t */\n\texports.scale = function (inNum, inMin, inMax, outMin, outMax) {\n\t if (inMin === inMax) {\n\t return outMin;\n\t }\n\t return (inNum - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;\n\t};\n\t\n\texports.toPolar = function (x, y) {\n\t var r = Math.sqrt(x * x + y * y);\n\t\n\t var theta = Math.atan2(y, x);\n\t if (theta < 0) {\n\t theta = theta + 2 * Math.PI;\n\t }\n\t return { radius: r, angle: theta };\n\t};\n\t\n\texports.toCartesian = function (radius, angle) {\n\t var cos = Math.cos(angle);\n\t var sin = Math.sin(angle);\n\t return { x: radius * cos, y: radius * sin * -1 };\n\t};\n\t/*\n\texports.polarToCartesian(centerX, centerY, radius, angleInDegrees) {\n\t var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;\n\t\n\t return {\n\t x: centerX + (radius * Math.cos(angleInRadians)),\n\t y: centerY + (radius * Math.sin(angleInRadians))\n\t };\n\t} */\n\t\n\texports.prune = function (data, scale) {\n\t return parseFloat(data.toFixed(scale));\n\t};\n\t\n\texports.invert = function (inNum) {\n\t return exports.scale(inNum, 1, 0, 0, 1);\n\t};\n\t\n\t/**\n\t * Convert a MIDi note number to a frequency value in equal temperament.\n\t * @param {number} midi MIDI note value\n\t * @return {number} Frequence value\n\t * @example\n\t * Nexus.mtof(60) // returns the frequency number of Middle C\n\t */\n\texports.mtof = function (midi) {\n\t return Math.pow(2, (midi - 69) / 12) * 440;\n\t};\n\t\n\t/**\n\t * Interpolate between two numbers\n\t * @param {number} loc Interpolation index (0-1)\n\t * @param {number} min Lower value\n\t * @param {number} max Upper value\n\t * @return {number} Interpolated value\n\t * @example\n\t * Nexus.interp(0.5,2,4) // returns 3\n\t * Nexus.interp(0.1,0,10) // returns 1\n\t */\n\texports.interp = function (loc, min, max) {\n\t return loc * (max - min) + min;\n\t};\n\t\n\t/**\n\t * Return a random choice from a list of arguments\n\t * @return {various} One random argument\n\t * @example\n\t * Nexus.pick(1,2,3,4) // returns 1, 2, 3, or 4\n\t * Nexus.pick(function1,function2) // returns either function1 or function2\n\t */\n\texports.pick = function () {\n\t return arguments[~ ~(Math.random() * arguments.length)];\n\t};\n\t\n\t/**\n\t * Returns an octave multiplier for frequency values\n\t * @param {number} num Relative octave number (e.g. -1 for one octave down, 1 for one octave up)\n\t * @return {number} Octave multiplier\n\t * @example\n\t * Nexus.octave(-1) // returns 0.5\n\t * Nexus.octave(0) // returns 1\n\t * Nexus.octave(1) // returns 2\n\t * Nexus.octave(2) // returns 4\n\t */\n\texports.octave = function (num) {\n\t return Math.pow(2, num);\n\t};\n\t\n\t/**\n\t * Random integer generator. If no second argument is given, will return random integer from 0 to bound1.\n\t * @param {number} bound1 Minimum random value\n\t * @param {number} bound2 Maximum random value\n\t * @return {number} Random integer between lower and upper boundary\n\t * @example\n\t * Nexus.ri(10) // returns random int from 0 to 10\n\t * Nexus.ri(20,2000) // returns random int from 20 to 2000\n\t */\n\texports.ri = function (bound1, bound2) {\n\t if (!bound2) {\n\t bound2 = bound1;\n\t bound1 = 0;\n\t }\n\t var low = Math.min(bound1, bound2);\n\t var high = Math.max(bound1, bound2);\n\t return Math.floor(Math.random() * (high - low) + low);\n\t};\n\t\n\t/**\n\t * Random float number generator. If no second argument is given, will return random float from 0 to bound1.\n\t * @param {number} bound1 Minimum random value\n\t * @param {number} bound2 Maximum random value\n\t * @return {number} Random float between lower and upper boundary\n\t * @example\n\t * Nexus.rf(1) // returns random float from 0 to 1\n\t * Nexus.rf(1,2) // returns random float from 1 to 2\n\t */\n\texports.rf = function (bound1, bound2) {\n\t if (!bound2) {\n\t bound2 = bound1;\n\t bound1 = 0;\n\t }\n\t var low = Math.min(bound1, bound2);\n\t var high = Math.max(bound1, bound2);\n\t return Math.random() * (high - low) + low;\n\t};\n\t\n\texports.cycle = function (input, min, max) {\n\t input++;\n\t if (input >= max) {\n\t input = min;\n\t }\n\t return input;\n\t};\n\t\n\t/**\n\t * Average an array of numbers\n\t * @param {Array} data Array of numbers to average\n\t * @return {number} Average of the input data\n\t * @example\n\t * Nexus.average([0,2,4,6,8,10]) // returns 5\n\t */\n\texports.average = function (data) {\n\t var total = 0;\n\t for (var i = 0; i < data.length; i++) {\n\t total += data[i];\n\t }\n\t return total / data.length;\n\t};\n\t\n\t/**\n\t * Get the distance from one (x,y) point to another (x,y) point\n\t * @param {number} x1 x of first point\n\t * @param {number} y1 y of first point\n\t * @param {number} x2 x of second point\n\t * @param {number} y2 y of second poiny\n\t * @return {number} Distance\n\t * @example\n\t * Nexus.distance(0,0,3,4) // returns 5\n\t */\n\texports.distance = function (x1, y1, x2, y2) {\n\t var a = x1 - x2;\n\t var b = y1 - y2;\n\t return Math.sqrt(a * a + b * b);\n\t};\n\t\n\texports.gainToDB = function (gain) {\n\t return 20 * Math.log10(gain);\n\t};\n\t\n\t/**\n\t * Flip a coin, returning either 0 or 1 according to a probability\n\t * @param {number} [odds=0.5] Likelihood of returning 1\n\t * @return {number} 1 or 0\n\t * @example\n\t * Nexus.coin(0.1) // returns 1 (10% of the time) or 0 (90% of the time)\n\t */\n\texports.coin = function () {\n\t var odds = arguments[0] === undefined ? 0.5 : arguments[0];\n\t\n\t if (exports.rf(0, 1) < odds) {\n\t return 1;\n\t } else {\n\t return 0;\n\t }\n\t};\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar dom = __webpack_require__(7);\n\tvar util = __webpack_require__(8);\n\tvar touch = __webpack_require__(9);\n\tvar EventEmitter = __webpack_require__(10);\n\t\n\tvar colors = __webpack_require__(1).colors;\n\t\n\t/**\n\tInterface\n\t*/\n\t\n\tvar Interface = (function (_EventEmitter) {\n\t function Interface(args, options, defaults) {\n\t _classCallCheck(this, Interface);\n\t\n\t _get(Object.getPrototypeOf(Interface.prototype), \"constructor\", this).call(this);\n\t this.type = this.constructor.name;\n\t this.settings = this.parseSettings(args, options, defaults);\n\t this.mouse = {};\n\t this.wait = false;\n\t this.colors = {};\n\t var defaultColors = colors(); // jshint ignore:line\n\t this.colors.accent = defaultColors.accent;\n\t this.colors.fill = defaultColors.fill;\n\t this.colors.light = defaultColors.light;\n\t this.colors.dark = defaultColors.dark;\n\t this.colors.mediumLight = defaultColors.mediumLight;\n\t this.colors.mediumDark = defaultColors.mediumDark;\n\t }\n\t\n\t _inherits(Interface, _EventEmitter);\n\t\n\t _createClass(Interface, {\n\t parseSettings: {\n\t value: function parseSettings(args, options, defaults) {\n\t\n\t options.unshift(\"target\");\n\t defaults.defaultSize = defaults.size.splice(0, 2);\n\t defaults.size = false;\n\t\n\t var settings = {\n\t target: document.body,\n\t colors: {}, // should inherit from a colors module,\n\t snapWithParent: true,\n\t event: function event() {},\n\t component: false\n\t };\n\t\n\t for (var key in defaults) {\n\t settings[key] = defaults[key];\n\t }\n\t\n\t for (var i = 0; i < args.length; i++) {\n\t // grabs the next argument\n\t var setting = args[i];\n\t // if it's an object, it must be the settings object\n\t if (util.isObject(setting)) {\n\t for (var key in setting) {\n\t settings[key] = setting[key];\n\t }\n\t // if it's a function, it must be the event setting\n\t } else if (typeof setting === \"function\") {\n\t settings.event = setting;\n\t // otherwise, consider it one of the widget's custom options\n\t } else if (options.length >= 1) {\n\t // grab the first option -- i.e. 'target'\n\t var key = options.splice(0, 1)[0];\n\t settings[key] = setting;\n\t }\n\t }\n\t\n\t /* handle common settings */\n\t\n\t // target\n\t this.parent = dom.parseElement(settings.target);\n\t\n\t // nexus-ui attribute\n\t if (this.parent && this.parent instanceof HTMLElement && !settings.component) {\n\t if (!this.parent.hasAttribute(\"nexus-ui\")) {\n\t this.parent.setAttribute(\"nexus-ui\", \"\");\n\t }\n\t }\n\t\n\t // size\n\t\n\t if (settings.size && Array.isArray(settings.size) && settings.snapWithParent) {\n\t this.width = settings.size[0];\n\t this.height = settings.size[1];\n\t this.parent.style.width = this.width + \"px\";\n\t this.parent.style.height = this.height + \"px\";\n\t } else if (settings.snapWithParent && !settings.component) {\n\t\n\t this.width = parseFloat(window.getComputedStyle(this.parent, null).getPropertyValue(\"width\").replace(\"px\", \"\"));\n\t this.height = parseFloat(window.getComputedStyle(this.parent, null).getPropertyValue(\"height\").replace(\"px\", \"\"));\n\t\n\t if (this.width == 5000) {\n\t this.width = settings.defaultSize[0];\n\t this.parent.style.width = this.parent.width = this.width + \"px\";\n\t }\n\t if (this.height == 5000) {\n\t this.height = settings.defaultSize[1];\n\t this.parent.style.height = this.parent.height = this.height + \"px\";\n\t }\n\t } else {\n\t settings.size = settings.defaultSize;\n\t this.width = settings.size[0];\n\t this.height = settings.size[1];\n\t }\n\t\n\t // event\n\t if (settings.event) {\n\t this.event = this.on(\"change\", settings.event);\n\t } else {\n\t this.event = false;\n\t }\n\t\n\t return settings;\n\t }\n\t },\n\t init: {\n\t value: function init() {\n\t this.buildFrame();\n\t this.buildInterface();\n\t this.sizeInterface();\n\t this.attachListeners();\n\t this.colorInterface();\n\t this.finalTouches();\n\t }\n\t },\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = svg.create(\"svg\");\n\t this.element.setAttribute(\"width\", this.width);\n\t this.element.setAttribute(\"height\", this.height);\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {}\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {}\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {}\n\t },\n\t attachListeners: {\n\t value: function attachListeners() {\n\t var _this = this;\n\t\n\t this.interactionTarget = this.interactionTarget || this.element;\n\t\n\t // Setup interaction\n\t if (touch.exists) {\n\t this.interactionTarget.addEventListener(\"touchstart\", function (evt) {\n\t return _this.preTouch(evt);\n\t });\n\t this.interactionTarget.addEventListener(\"touchmove\", function (evt) {\n\t return _this.preTouchMove(evt);\n\t });\n\t this.interactionTarget.addEventListener(\"touchend\", function (evt) {\n\t return _this.preTouchRelease(evt);\n\t });\n\t }\n\t this.boundPreMove = function (evt) {\n\t return _this.preMove(evt);\n\t };\n\t this.boundPreRelease = function (evt) {\n\t return _this.preRelease(evt);\n\t };\n\t this.interactionTarget.addEventListener(\"mousedown\", function (evt) {\n\t return _this.preClick(evt);\n\t });\n\t }\n\t },\n\t finalTouches: {\n\t value: function finalTouches() {\n\t this.element.style.cursor = \"pointer\";\n\t }\n\t },\n\t preClick: {\n\t value: function preClick(e) {\n\t // 10000 getComputedStyle calls takes 100 ms.\n\t // .:. one takes about .01ms\n\t if (this.element instanceof HTMLElement) {\n\t this.width = window.getComputedStyle(this.element, null).getPropertyValue(\"width\").replace(\"px\", \"\");\n\t }\n\t // 10000 getComputedStyle calls takes 40 ms.\n\t // .:. one takes about .004ms\n\t this.offset = dom.findPosition(this.element);\n\t this.mouse = dom.locateMouse(e, this.offset);\n\t this.clicked = true;\n\t this.click();\n\t this.moveEvent = document.addEventListener(\"mousemove\", this.boundPreMove);\n\t this.releaseEvent = document.addEventListener(\"mouseup\", this.boundPreRelease);\n\t this.emit(\"click\");\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t },\n\t preMove: {\n\t value: function preMove(e) {\n\t var _this = this;\n\t\n\t if (!this.wait) {\n\t this.mouse = dom.locateMouse(e, this.offset);\n\t this.move();\n\t this.wait = true;\n\t setTimeout(function () {\n\t _this.wait = false;\n\t }, 25);\n\t }\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t },\n\t preRelease: {\n\t value: function preRelease(e) {\n\t this.mouse = dom.locateMouse(e, this.offset);\n\t this.clicked = false;\n\t this.release();\n\t this.emit(\"release\");\n\t document.removeEventListener(\"mousemove\", this.boundPreMove);\n\t document.removeEventListener(\"mouseup\", this.boundPreRelease);\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t },\n\t click: {\n\t value: function click() {}\n\t },\n\t move: {\n\t value: function move() {}\n\t },\n\t release: {\n\t value: function release() {}\n\t },\n\t preTouch: {\n\t\n\t /* touch */\n\t\n\t value: function preTouch(e) {\n\t if (this.element instanceof HTMLElement) {\n\t this.width = window.getComputedStyle(this.element, null).getPropertyValue(\"width\").replace(\"px\", \"\");\n\t }\n\t this.offset = dom.findPosition(this.element);\n\t this.mouse = dom.locateTouch(e, this.offset);\n\t this.clicked = true;\n\t this.touch(e);\n\t this.emit(\"click\");\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t },\n\t preTouchMove: {\n\t value: function preTouchMove(e) {\n\t if (this.clicked) {\n\t this.mouse = dom.locateTouch(e, this.offset);\n\t this.touchMove();\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t }\n\t },\n\t preTouchRelease: {\n\t value: function preTouchRelease(e) {\n\t this.mouse = dom.locateTouch(e, this.offset);\n\t this.clicked = false;\n\t this.touchRelease();\n\t this.emit(\"release\");\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t },\n\t touch: {\n\t value: function touch() {\n\t this.click();\n\t }\n\t },\n\t touchMove: {\n\t value: function touchMove() {\n\t this.move();\n\t }\n\t },\n\t touchRelease: {\n\t value: function touchRelease() {\n\t this.release();\n\t }\n\t },\n\t resize: {\n\t\n\t /**\n\t * Resize the interface\n\t * @param width {number} New width in pixels\n\t * @param height {number} New height in pixels\n\t *\n\t * @example\n\t * button.resize(100,100);\n\t */\n\t\n\t value: function resize(width, height) {\n\t this.width = width;\n\t this.height = height;\n\t this.parent.style.width = this.width + \"px\";\n\t this.parent.style.height = this.height + \"px\";\n\t this.element.setAttribute(\"width\", this.width);\n\t this.element.setAttribute(\"height\", this.height);\n\t this.sizeInterface();\n\t }\n\t },\n\t empty: {\n\t value: function empty() {\n\t while (this.element.lastChild) {\n\t this.element.removeChild(this.element.lastChild);\n\t }\n\t }\n\t },\n\t destroy: {\n\t\n\t /**\n\t * Remove the interface from the page and cancel its event listener(s).\n\t *\n\t * @example\n\t * button.destroy();\n\t */\n\t\n\t value: function destroy() {\n\t this.empty();\n\t this.parent.removeChild(this.element);\n\t this.removeAllListeners();\n\t if (this.instrument) {\n\t delete this.instrument[this.id];\n\t }\n\t this.customDestroy();\n\t }\n\t },\n\t customDestroy: {\n\t value: function customDestroy() {}\n\t },\n\t colorize: {\n\t value: function colorize(type, color) {\n\t this.colors[type] = color;\n\t this.colorInterface();\n\t }\n\t }\n\t });\n\t\n\t return Interface;\n\t})(EventEmitter);\n\t\n\tmodule.exports = Interface;\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\texports.findPosition = function (el) {\n\t var viewportOffset = el.getBoundingClientRect();\n\t var top = viewportOffset.top + window.scrollY;\n\t var left = viewportOffset.left + window.scrollX;\n\t return { top: top, left: left };\n\t};\n\t\n\texports.parseElement = function (parent) {\n\t if (typeof parent === \"string\") {\n\t parent = document.getElementById(parent.replace(\"#\", \"\"));\n\t }\n\t\n\t if (parent instanceof HTMLElement || parent instanceof SVGElement) {\n\t return parent;\n\t } else {\n\t return \"No valid parent argument\";\n\t }\n\t};\n\t\n\texports.locateMouse = function (e, offset) {\n\t return {\n\t x: e.pageX - offset.left,\n\t y: e.pageY - offset.top\n\t };\n\t};\n\t\n\texports.locateTouch = function (e, offset) {\n\t return {\n\t x: e.targetTouches.length ? e.targetTouches[0].pageX - offset.left : false,\n\t y: e.targetTouches.length ? e.targetTouches[0].pageY - offset.top : false\n\t };\n\t};\n\t\n\texports.SmartCanvas = function (parent) {\n\t var _this = this;\n\t\n\t this.element = document.createElement(\"canvas\");\n\t this.context = this.element.getContext(\"2d\");\n\t parent.appendChild(this.element);\n\t\n\t this.resize = function (w, h) {\n\t _this.element.width = w * 2;\n\t _this.element.height = h * 2;\n\t _this.element.style.width = w + \"px\";\n\t _this.element.style.height = h + \"px\";\n\t };\n\t};\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\texports.isObject = function (obj) {\n\t if (typeof obj === \"object\" && !Array.isArray(obj) && obj !== null && obj instanceof SVGElement === false && obj instanceof HTMLElement === false) {\n\t return true;\n\t } else {\n\t return false;\n\t }\n\t};\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\texports.exists = \"ontouchstart\" in document.documentElement;\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports) {\n\n\t// Copyright Joyent, Inc. and other Node contributors.\n\t//\n\t// Permission is hereby granted, free of charge, to any person obtaining a\n\t// copy of this software and associated documentation files (the\n\t// \"Software\"), to deal in the Software without restriction, including\n\t// without limitation the rights to use, copy, modify, merge, publish,\n\t// distribute, sublicense, and/or sell copies of the Software, and to permit\n\t// persons to whom the Software is furnished to do so, subject to the\n\t// following conditions:\n\t//\n\t// The above copyright notice and this permission notice shall be included\n\t// in all copies or substantial portions of the Software.\n\t//\n\t// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n\t// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n\t// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n\t// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n\t// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n\t// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n\t// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\t\n\tfunction EventEmitter() {\n\t this._events = this._events || {};\n\t this._maxListeners = this._maxListeners || undefined;\n\t}\n\tmodule.exports = EventEmitter;\n\t\n\t// Backwards-compat with node 0.10.x\n\tEventEmitter.EventEmitter = EventEmitter;\n\t\n\tEventEmitter.prototype._events = undefined;\n\tEventEmitter.prototype._maxListeners = undefined;\n\t\n\t// By default EventEmitters will print a warning if more than 10 listeners are\n\t// added to it. This is a useful default which helps finding memory leaks.\n\tEventEmitter.defaultMaxListeners = 10;\n\t\n\t// Obviously not all Emitters should be limited to 10. This function allows\n\t// that to be increased. Set to zero for unlimited.\n\tEventEmitter.prototype.setMaxListeners = function(n) {\n\t if (!isNumber(n) || n < 0 || isNaN(n))\n\t throw TypeError('n must be a positive number');\n\t this._maxListeners = n;\n\t return this;\n\t};\n\t\n\tEventEmitter.prototype.emit = function(type) {\n\t var er, handler, len, args, i, listeners;\n\t\n\t if (!this._events)\n\t this._events = {};\n\t\n\t // If there is no 'error' event listener then throw.\n\t if (type === 'error') {\n\t if (!this._events.error ||\n\t (isObject(this._events.error) && !this._events.error.length)) {\n\t er = arguments[1];\n\t if (er instanceof Error) {\n\t throw er; // Unhandled 'error' event\n\t } else {\n\t // At least give some kind of context to the user\n\t var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n\t err.context = er;\n\t throw err;\n\t }\n\t }\n\t }\n\t\n\t handler = this._events[type];\n\t\n\t if (isUndefined(handler))\n\t return false;\n\t\n\t if (isFunction(handler)) {\n\t switch (arguments.length) {\n\t // fast cases\n\t case 1:\n\t handler.call(this);\n\t break;\n\t case 2:\n\t handler.call(this, arguments[1]);\n\t break;\n\t case 3:\n\t handler.call(this, arguments[1], arguments[2]);\n\t break;\n\t // slower\n\t default:\n\t args = Array.prototype.slice.call(arguments, 1);\n\t handler.apply(this, args);\n\t }\n\t } else if (isObject(handler)) {\n\t args = Array.prototype.slice.call(arguments, 1);\n\t listeners = handler.slice();\n\t len = listeners.length;\n\t for (i = 0; i < len; i++)\n\t listeners[i].apply(this, args);\n\t }\n\t\n\t return true;\n\t};\n\t\n\tEventEmitter.prototype.addListener = function(type, listener) {\n\t var m;\n\t\n\t if (!isFunction(listener))\n\t throw TypeError('listener must be a function');\n\t\n\t if (!this._events)\n\t this._events = {};\n\t\n\t // To avoid recursion in the case that type === \"newListener\"! Before\n\t // adding it to the listeners, first emit \"newListener\".\n\t if (this._events.newListener)\n\t this.emit('newListener', type,\n\t isFunction(listener.listener) ?\n\t listener.listener : listener);\n\t\n\t if (!this._events[type])\n\t // Optimize the case of one listener. Don't need the extra array object.\n\t this._events[type] = listener;\n\t else if (isObject(this._events[type]))\n\t // If we've already got an array, just append.\n\t this._events[type].push(listener);\n\t else\n\t // Adding the second element, need to change to array.\n\t this._events[type] = [this._events[type], listener];\n\t\n\t // Check for listener leak\n\t if (isObject(this._events[type]) && !this._events[type].warned) {\n\t if (!isUndefined(this._maxListeners)) {\n\t m = this._maxListeners;\n\t } else {\n\t m = EventEmitter.defaultMaxListeners;\n\t }\n\t\n\t if (m && m > 0 && this._events[type].length > m) {\n\t this._events[type].warned = true;\n\t console.error('(node) warning: possible EventEmitter memory ' +\n\t 'leak detected. %d listeners added. ' +\n\t 'Use emitter.setMaxListeners() to increase limit.',\n\t this._events[type].length);\n\t if (typeof console.trace === 'function') {\n\t // not supported in IE 10\n\t console.trace();\n\t }\n\t }\n\t }\n\t\n\t return this;\n\t};\n\t\n\tEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\t\n\tEventEmitter.prototype.once = function(type, listener) {\n\t if (!isFunction(listener))\n\t throw TypeError('listener must be a function');\n\t\n\t var fired = false;\n\t\n\t function g() {\n\t this.removeListener(type, g);\n\t\n\t if (!fired) {\n\t fired = true;\n\t listener.apply(this, arguments);\n\t }\n\t }\n\t\n\t g.listener = listener;\n\t this.on(type, g);\n\t\n\t return this;\n\t};\n\t\n\t// emits a 'removeListener' event iff the listener was removed\n\tEventEmitter.prototype.removeListener = function(type, listener) {\n\t var list, position, length, i;\n\t\n\t if (!isFunction(listener))\n\t throw TypeError('listener must be a function');\n\t\n\t if (!this._events || !this._events[type])\n\t return this;\n\t\n\t list = this._events[type];\n\t length = list.length;\n\t position = -1;\n\t\n\t if (list === listener ||\n\t (isFunction(list.listener) && list.listener === listener)) {\n\t delete this._events[type];\n\t if (this._events.removeListener)\n\t this.emit('removeListener', type, listener);\n\t\n\t } else if (isObject(list)) {\n\t for (i = length; i-- > 0;) {\n\t if (list[i] === listener ||\n\t (list[i].listener && list[i].listener === listener)) {\n\t position = i;\n\t break;\n\t }\n\t }\n\t\n\t if (position < 0)\n\t return this;\n\t\n\t if (list.length === 1) {\n\t list.length = 0;\n\t delete this._events[type];\n\t } else {\n\t list.splice(position, 1);\n\t }\n\t\n\t if (this._events.removeListener)\n\t this.emit('removeListener', type, listener);\n\t }\n\t\n\t return this;\n\t};\n\t\n\tEventEmitter.prototype.removeAllListeners = function(type) {\n\t var key, listeners;\n\t\n\t if (!this._events)\n\t return this;\n\t\n\t // not listening for removeListener, no need to emit\n\t if (!this._events.removeListener) {\n\t if (arguments.length === 0)\n\t this._events = {};\n\t else if (this._events[type])\n\t delete this._events[type];\n\t return this;\n\t }\n\t\n\t // emit removeListener for all listeners on all events\n\t if (arguments.length === 0) {\n\t for (key in this._events) {\n\t if (key === 'removeListener') continue;\n\t this.removeAllListeners(key);\n\t }\n\t this.removeAllListeners('removeListener');\n\t this._events = {};\n\t return this;\n\t }\n\t\n\t listeners = this._events[type];\n\t\n\t if (isFunction(listeners)) {\n\t this.removeListener(type, listeners);\n\t } else if (listeners) {\n\t // LIFO order\n\t while (listeners.length)\n\t this.removeListener(type, listeners[listeners.length - 1]);\n\t }\n\t delete this._events[type];\n\t\n\t return this;\n\t};\n\t\n\tEventEmitter.prototype.listeners = function(type) {\n\t var ret;\n\t if (!this._events || !this._events[type])\n\t ret = [];\n\t else if (isFunction(this._events[type]))\n\t ret = [this._events[type]];\n\t else\n\t ret = this._events[type].slice();\n\t return ret;\n\t};\n\t\n\tEventEmitter.prototype.listenerCount = function(type) {\n\t if (this._events) {\n\t var evlistener = this._events[type];\n\t\n\t if (isFunction(evlistener))\n\t return 1;\n\t else if (evlistener)\n\t return evlistener.length;\n\t }\n\t return 0;\n\t};\n\t\n\tEventEmitter.listenerCount = function(emitter, type) {\n\t return emitter.listenerCount(type);\n\t};\n\t\n\tfunction isFunction(arg) {\n\t return typeof arg === 'function';\n\t}\n\t\n\tfunction isNumber(arg) {\n\t return typeof arg === 'number';\n\t}\n\t\n\tfunction isObject(arg) {\n\t return typeof arg === 'object' && arg !== null;\n\t}\n\t\n\tfunction isUndefined(arg) {\n\t return arg === void 0;\n\t}\n\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = __webpack_require__(5);\n\t\n\t/**\n\t Creates a steppable value with minimum, maximum, and step size. This is used in many interfaces to constrict their values to certain ranges.\n\t @param {number} [min=0] minimum\n\t @param {number} [max=1] maximum\n\t @param {number} [step=0]\n\t @param {number} [value=0] initial value\n\t @returns {Object} Step\n\t*/\n\t\n\tvar Step = (function () {\n\t function Step() {\n\t var min = arguments[0] === undefined ? 0 : arguments[0];\n\t var max = arguments[1] === undefined ? 1 : arguments[1];\n\t var step = arguments[2] === undefined ? 0 : arguments[2];\n\t var value = arguments[3] === undefined ? 0 : arguments[3];\n\t\n\t _classCallCheck(this, Step);\n\t\n\t //Object.assign(this,{min,max,step});\n\t //Cannot use Object.assign because not supported in Safari.\n\t //I would expect for Babel to take care of this but it is not.\n\t this.min = min;\n\t this.max = max;\n\t this.step = step;\n\t this.value = value;\n\t this.changed = false;\n\t this.oldValue = false;\n\t this.update(this.value);\n\t }\n\t\n\t _createClass(Step, {\n\t update: {\n\t\n\t /**\n\t Update with a new value. The value will be auto-adjusted to fit the min/max/step.\n\t @param {number} value\n\t */\n\t\n\t value: function update(value) {\n\t if (this.step) {\n\t // this.value = math.clip(Math.round(value / (this.step)) * this.step, this.min,this.max);\n\t this.value = math.clip(Math.round((value - this.min) / this.step) * this.step + this.min, this.min, this.max);\n\t } else {\n\t this.value = math.clip(value, this.min, this.max);\n\t }\n\t if (this.oldValue !== this.value) {\n\t this.oldValue = this.value;\n\t this.changed = true;\n\t } else {\n\t this.changed = false;\n\t }\n\t return this.value;\n\t }\n\t },\n\t updateNormal: {\n\t\n\t /**\n\t Update with a normalized value 0-1.\n\t @param {number} value\n\t */\n\t\n\t value: function updateNormal(value) {\n\t this.value = math.scale(value, 0, 1, this.min, this.max);\n\t return this.update(this.value);\n\t }\n\t },\n\t normalized: {\n\t\n\t /**\n\t Get a normalized version of this.value . Not settable.\n\t */\n\t\n\t get: function () {\n\t return math.normalize(this.value, this.min, this.max);\n\t }\n\t }\n\t });\n\t\n\t return Step;\n\t})();\n\t\n\tmodule.exports = Step;\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\"use strict\";\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar ToggleModel = _interopRequire(__webpack_require__(13));\n\t\n\t/*\n\thow to use :\n\t\n\tdial.interaction = new Handle('radial','relative',this.width,this.height);\n\t// dial.interaction.mode = 'relative'\n\t// dial.interaction.direction = 'radial'\n\t\n\ton click:\n\tdial.interaction.anchor = this.mouse;\n\t\n\ton move:\n\tdial.interaction.update(this.mouse);\n\t\n\tconsole.log( dial.interaction.value ); should be a normalized value.\n\t\n\t*/\n\t\n\t/*\n\t absolute/relative are property: mode\n\t radial/vertical/horizontal/2d are property: direction\n\t\n\t plan :\n\t\n\t if relative --\n\t NO on click, get value offset between current value and click value.\n\t NO on move, use click value - offset\n\t INSTEAD\n\t use delta -- bc vertical motion on dial is impossible otherwise\n\t also allow to set sensitivity\n\t\n\t*/\n\t\n\tvar Handle = exports.Handle = (function () {\n\t function Handle() {\n\t var mode = arguments[0] === undefined ? \"absolute\" : arguments[0];\n\t var direction = arguments[1] === undefined ? \"vertical\" : arguments[1];\n\t var xbound = arguments[2] === undefined ? [0, 100] : arguments[2];\n\t var ybound = arguments[3] === undefined ? [0, 100] : arguments[3];\n\t\n\t _classCallCheck(this, Handle);\n\t\n\t this.mode = mode;\n\t this.direction = direction;\n\t this.previous = 0;\n\t this.value = 0;\n\t this.sensitivity = 1;\n\t this.resize(xbound, ybound);\n\t }\n\t\n\t _createClass(Handle, {\n\t resize: {\n\t value: function resize(xbound, ybound) {\n\t this.boundary = {\n\t min: {\n\t x: xbound[0],\n\t y: ybound[0]\n\t },\n\t max: {\n\t x: xbound[1],\n\t y: ybound[1]\n\t },\n\t center: {\n\t x: (xbound[1] - xbound[0]) / 2 + xbound[0],\n\t y: (ybound[1] - ybound[0]) / 2 + ybound[0]\n\t }\n\t };\n\t }\n\t },\n\t anchor: {\n\t set: function (mouse) {\n\t this._anchor = this.convertPositionToValue(mouse);\n\t },\n\t get: function () {\n\t return this._anchor;\n\t }\n\t },\n\t update: {\n\t value: function update(mouse) {\n\t if (this.mode === \"relative\") {\n\t var increment = this.convertPositionToValue(mouse) - this.anchor;\n\t if (Math.abs(increment) > 0.5) {\n\t increment = 0;\n\t }\n\t this.anchor = mouse;\n\t this.value = this.value + increment * this.sensitivity;\n\t } else {\n\t this.value = this.convertPositionToValue(mouse);\n\t }\n\t this.value = math.clip(this.value, 0, 1);\n\t }\n\t },\n\t convertPositionToValue: {\n\t value: function convertPositionToValue(current) {\n\t switch (this.direction) {\n\t case \"radial\":\n\t var position = math.toPolar(current.x - this.boundary.center.x, current.y - this.boundary.center.y);\n\t position = position.angle / (Math.PI * 2);\n\t position = (position - 0.25 + 1) % 1;\n\t return position;\n\t case \"vertical\":\n\t return math.scale(current.y, this.boundary.min.y, this.boundary.max.y, 0, 1);\n\t case \"horizontal\":\n\t return math.scale(current.x, this.boundary.min.x, this.boundary.max.x, 0, 1);\n\t }\n\t }\n\t }\n\t });\n\t\n\t return Handle;\n\t})();\n\t\n\tvar Button = exports.Button = (function () {\n\t function Button() {\n\t var mode = arguments[0] === undefined ? \"button\" : arguments[0];\n\t\n\t _classCallCheck(this, Button);\n\t\n\t this.mode = mode;\n\t this.state = new ToggleModel();\n\t this.paintbrush = false;\n\t }\n\t\n\t _createClass(Button, {\n\t click: {\n\t value: function click() {\n\t switch (this.mode) {\n\t case \"impulse\":\n\t this.state.on();\n\t if (this.timeout) {\n\t clearTimeout(this.timeout);\n\t }\n\t this.timeout = setTimeout(this.state.off.bind(this), 30);\n\t this.emit(\"change\", this.state);\n\t break;\n\t case \"button\":\n\t this.turnOn();\n\t this.emit(\"change\", this.state);\n\t break;\n\t case \"aftertouch\":\n\t this.position = {\n\t x: math.clip(this.mouse.x / this.width, 0, 1),\n\t y: math.clip(1 - this.mouse.y / this.height, 0, 1)\n\t };\n\t this.turnOn();\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t break;\n\t case \"toggle\":\n\t this.flip();\n\t this.emit(\"change\", this.state);\n\t break;\n\t }\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.mode === \"aftertouch\") {\n\t this.position = {\n\t x: math.clip(this.mouse.x / this.width, 0, 1),\n\t y: math.clip(1 - this.mouse.y / this.height, 0, 1)\n\t };\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t this.render();\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t switch (this.mode) {\n\t case \"button\":\n\t this.turnOff();\n\t this.emit(\"change\", this.state);\n\t break;\n\t case \"aftertouch\":\n\t this.turnOff();\n\t this.position = {\n\t x: this.mouse.x / this.width,\n\t y: 1 - this.mouse.y / this.height\n\t };\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t break;\n\t }\n\t }\n\t }\n\t });\n\t\n\t return Button;\n\t})();\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar Toggle = (function () {\n\t function Toggle(state) {\n\t _classCallCheck(this, Toggle);\n\t\n\t this.state = state || false;\n\t }\n\t\n\t _createClass(Toggle, {\n\t flip: {\n\t value: function flip(state) {\n\t if (state || state === false) {\n\t this.state = state;\n\t } else {\n\t this.state = !this.state;\n\t }\n\t }\n\t },\n\t on: {\n\t value: function on() {\n\t this.state = true;\n\t }\n\t },\n\t off: {\n\t value: function off() {\n\t this.state = false;\n\t }\n\t }\n\t });\n\t\n\t return Toggle;\n\t})();\n\t\n\tmodule.exports = Toggle;\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\t\n\tvar Interaction = _interopRequireWildcard(__webpack_require__(12));\n\t\n\t/**\n\t* Slider\n\t*\n\t* @description Horizontal or vertical slider with settable interaction modes.\n\t*\n\t* @demo <span nexus-ui=\"slider\" step=0.2></span>\n\t*\n\t* @example\n\t* var slider = new Nexus.Slider('#target')\n\t*\n\t* @example\n\t* var slider = new Nexus.Slider('#target',{\n\t* 'size': [120,20],\n\t* 'mode': 'relative', // 'relative' or 'absolute'\n\t* 'min': 0,\n\t* 'max': 1,\n\t* 'step': 0,\n\t* 'value': 0\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires when the interface's value changes. <br>\n\t* Event data: <i>number</i> The number value of the interface.\n\t*\n\t* @outputexample\n\t* slider.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Slider = (function (_Interface) {\n\t function Slider() {\n\t _classCallCheck(this, Slider);\n\t\n\t var options = [\"min\", \"max\", \"value\"];\n\t\n\t var defaults = {\n\t size: [120, 20],\n\t mode: \"relative\", // 'relative' or 'absolute'\n\t min: 0,\n\t max: 1,\n\t step: 0,\n\t value: 0\n\t };\n\t\n\t _get(Object.getPrototypeOf(Slider.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.orientation = \"vertical\"; // This will change automatically to 'horizontal'if the interface is wider than it is tall.\n\t\n\t this._value = new Step(this.settings.min, this.settings.max, this.settings.step, this.settings.value);\n\t\n\t this.position = new Interaction.Handle(this.settings.mode, this.orientation, [0, this.width], [this.height, 0]);\n\t this.position.value = this._value.normalized;\n\t\n\t this.init();\n\t\n\t this.position.direction = this.orientation;\n\t\n\t this.emit(\"change\", this.value);\n\t }\n\t\n\t _inherits(Slider, _Interface);\n\t\n\t _createClass(Slider, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.bar = svg.create(\"rect\");\n\t this.fillbar = svg.create(\"rect\");\n\t this.knob = svg.create(\"circle\");\n\t\n\t this.element.appendChild(this.bar);\n\t this.element.appendChild(this.fillbar);\n\t this.element.appendChild(this.knob);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t if (this.width < this.height) {\n\t this.orientation = \"vertical\";\n\t } else {\n\t this.orientation = \"horizontal\";\n\t }\n\t\n\t if (this.position) {\n\t this.position.resize([0, this.width], [this.height, 0]);\n\t }\n\t\n\t var x = undefined,\n\t y = undefined,\n\t w = undefined,\n\t h = undefined,\n\t barOffset = undefined,\n\t cornerRadius = undefined;\n\t this.knobData = {\n\t level: 0,\n\t r: 0\n\t };\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.thickness = this.width / 2;\n\t x = this.width / 2;\n\t y = 0;\n\t w = this.thickness;\n\t h = this.height;\n\t this.knobData.r = this.thickness * 0.8;\n\t this.knobData.level = h - this.knobData.r - this.normalized * (h - this.knobData.r * 2);\n\t barOffset = \"translate(\" + this.thickness * -1 / 2 + \",0)\";\n\t cornerRadius = w / 2;\n\t } else {\n\t this.thickness = this.height / 2;\n\t x = 0;\n\t y = this.height / 2;\n\t w = this.width;\n\t h = this.thickness;\n\t this.knobData.r = this.thickness * 0.8;\n\t this.knobData.level = this.normalized * (w - this.knobData.r * 2) + this.knobData.r;\n\t barOffset = \"translate(0,\" + this.thickness * -1 / 2 + \")\";\n\t cornerRadius = h / 2;\n\t }\n\t\n\t this.bar.setAttribute(\"x\", x);\n\t this.bar.setAttribute(\"y\", y);\n\t this.bar.setAttribute(\"transform\", barOffset);\n\t this.bar.setAttribute(\"rx\", cornerRadius); // corner radius\n\t this.bar.setAttribute(\"ry\", cornerRadius);\n\t this.bar.setAttribute(\"width\", w);\n\t this.bar.setAttribute(\"height\", h);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.fillbar.setAttribute(\"x\", x);\n\t this.fillbar.setAttribute(\"y\", this.knobData.level);\n\t this.fillbar.setAttribute(\"width\", w);\n\t this.fillbar.setAttribute(\"height\", h - this.knobData.level);\n\t } else {\n\t this.fillbar.setAttribute(\"x\", 0);\n\t this.fillbar.setAttribute(\"y\", y);\n\t this.fillbar.setAttribute(\"width\", this.knobData.level);\n\t this.fillbar.setAttribute(\"height\", h);\n\t }\n\t this.fillbar.setAttribute(\"transform\", barOffset);\n\t this.fillbar.setAttribute(\"rx\", cornerRadius);\n\t this.fillbar.setAttribute(\"ry\", cornerRadius);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.knob.setAttribute(\"cx\", x);\n\t this.knob.setAttribute(\"cy\", this.knobData.level);\n\t } else {\n\t this.knob.setAttribute(\"cx\", this.knobData.level);\n\t this.knob.setAttribute(\"cy\", y);\n\t }\n\t this.knob.setAttribute(\"r\", this.knobData.r);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.bar.setAttribute(\"fill\", this.colors.fill);\n\t this.fillbar.setAttribute(\"fill\", this.colors.accent);\n\t this.knob.setAttribute(\"fill\", this.colors.accent);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.clicked) {\n\t this.knobData.r = this.thickness * 0.75;\n\t }\n\t this.knob.setAttribute(\"r\", this.knobData.r);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.knobData.level = this.knobData.r + this._value.normalized * (this.height - this.knobData.r * 2);\n\t this.knob.setAttribute(\"cy\", this.height - this.knobData.level);\n\t this.fillbar.setAttribute(\"y\", this.height - this.knobData.level);\n\t this.fillbar.setAttribute(\"height\", this.knobData.level);\n\t } else {\n\t this.knobData.level = this._value.normalized * (this.width - this.knobData.r * 2) + this.knobData.r;\n\t this.knob.setAttribute(\"cx\", this.knobData.level);\n\t this.fillbar.setAttribute(\"x\", 0);\n\t this.fillbar.setAttribute(\"width\", this.knobData.level);\n\t }\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.knobData.r = this.thickness * 0.9;\n\t this.position.anchor = this.mouse;\n\t this.move();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.clicked) {\n\t this.position.update(this.mouse);\n\t this._value.updateNormal(this.position.value);\n\t this.emit(\"change\", this._value.value);\n\t this.render();\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t this.render();\n\t }\n\t },\n\t normalized: {\n\t get: function () {\n\t return this._value.normalized;\n\t }\n\t },\n\t value: {\n\t\n\t /**\n\t The slider's current value. If set manually, will update the interface and trigger the output event.\n\t @type {number}\n\t @example slider.value = 10;\n\t */\n\t\n\t get: function () {\n\t return this._value.value;\n\t },\n\t set: function (v) {\n\t this._value.update(v);\n\t this.position.value = this._value.normalized;\n\t this.emit(\"change\", this._value.value);\n\t this.render();\n\t }\n\t },\n\t min: {\n\t\n\t /**\n\t Lower limit of the sliders's output range\n\t @type {number}\n\t @example slider.min = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.min;\n\t },\n\t set: function (v) {\n\t this._value.min = v;\n\t }\n\t },\n\t max: {\n\t\n\t /**\n\t Upper limit of the slider's output range\n\t @type {number}\n\t @example slider.max = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.max;\n\t },\n\t set: function (v) {\n\t this._value.max = v;\n\t }\n\t },\n\t step: {\n\t\n\t /**\n\t The increment that the slider's value changes by.\n\t @type {number}\n\t @example slider.step = 5;\n\t */\n\t\n\t get: function () {\n\t return this._value.step;\n\t },\n\t set: function (v) {\n\t this._value.step = v;\n\t }\n\t },\n\t mode: {\n\t\n\t /**\n\t Absolute mode (slider's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: \"relative\".\n\t @type {string}\n\t @example slider.mode = \"relative\";\n\t */\n\t\n\t get: function () {\n\t return this.position.mode;\n\t },\n\t set: function (v) {\n\t this.position.mode = v;\n\t }\n\t }\n\t });\n\t\n\t return Slider;\n\t})(Interface);\n\t\n\tmodule.exports = Slider;\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar ToggleModel = __webpack_require__(13);\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\t* Toggle\n\t*\n\t* @description Binary switch\n\t*\n\t* @demo <span nexus-ui=\"toggle\"></span>\n\t*\n\t* @example\n\t* var toggle = new Nexus.Toggle('#target')\n\t*\n\t* @example\n\t* var toggle = new Nexus.Toggle('#target',{\n\t* 'size': [40,20],\n\t* 'state': false\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* Parameter: The boolean state of the interface.\n\t*\n\t* @outputexample\n\t* toggle.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Toggle = (function (_Interface) {\n\t function Toggle() {\n\t _classCallCheck(this, Toggle);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [40, 20],\n\t target: false,\n\t state: false\n\t };\n\t\n\t _get(Object.getPrototypeOf(Toggle.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._state = new ToggleModel(this.settings.state);\n\t\n\t this.init();\n\t }\n\t\n\t _inherits(Toggle, _Interface);\n\t\n\t _createClass(Toggle, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.bar = svg.create(\"rect\");\n\t this.knob = svg.create(\"circle\");\n\t this.element.appendChild(this.bar);\n\t this.element.appendChild(this.knob);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t if (this.height < this.width / 2) {\n\t this.knobSize = this.height / 2;\n\t } else {\n\t this.knobSize = this.width / 4;\n\t }\n\t\n\t this.bar.setAttribute(\"x\", this.width / 2 - this.knobSize * 1.5);\n\t this.bar.setAttribute(\"y\", this.height / 2 - this.knobSize / 2);\n\t this.bar.setAttribute(\"rx\", this.knobSize / 2);\n\t this.bar.setAttribute(\"ry\", this.knobSize / 2);\n\t this.bar.setAttribute(\"width\", this.knobSize * 3);\n\t this.bar.setAttribute(\"height\", this.knobSize);\n\t\n\t this.knob.setAttribute(\"cx\", this.width / 2 - this.knobSize);\n\t this.knob.setAttribute(\"cy\", this.height / 2);\n\t this.knob.setAttribute(\"r\", this.knobSize);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.knob.setAttribute(\"fill\", this.colors.accent);\n\t this.render();\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.state) {\n\t this.knob.setAttribute(\"cx\", this.width / 2 - this.knobSize);\n\t this.bar.setAttribute(\"fill\", this.colors.fill);\n\t } else {\n\t this.knob.setAttribute(\"cx\", this.width / 2 + this.knobSize);\n\t this.bar.setAttribute(\"fill\", this.colors.accent);\n\t }\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.flip();\n\t this.render();\n\t this.emit(\"change\", this.state);\n\t }\n\t },\n\t state: {\n\t\n\t /**\n\t Whether the toggle is currently on or off. Setting this property will update the toggle interface and trigger the output event.\n\t @type {boolean}\n\t @example toggle.state = false;\n\t */\n\t\n\t get: function () {\n\t return this._state.state;\n\t },\n\t set: function (value) {\n\t this._state.flip(value);\n\t this.emit(\"change\", this.state);\n\t this.render();\n\t }\n\t },\n\t flip: {\n\t\n\t /**\n\t * Switch the toggle state to its opposite state\n\t * @example\n\t * toggle.flip();\n\t */\n\t\n\t value: function flip() {\n\t this._state.flip();\n\t this.render();\n\t }\n\t }\n\t });\n\t\n\t return Toggle;\n\t})(Interface);\n\t\n\tmodule.exports = Toggle;\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar ButtonTemplate = __webpack_require__(17);\n\t\n\t/**\n\t* Button\n\t*\n\t* @description Circular button with optional aftertouch.\n\t*\n\t* @demo <span nexus-ui=\"button\"></span>\n\t*\n\t* @example\n\t* var button = new Nexus.Button('#target')\n\t*\n\t* @example\n\t* var button = new Nexus.Button('#target',{\n\t* 'size': [80,80],\n\t* 'mode': 'aftertouch',\n\t* 'state': false\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* In <b>button mode</b>, <b>toggle mode</b>, and <b>impulse mode</b>, the output data is a boolean describing the state of the button.<br>\n\t* In <b>aftertouch mode</b>, the output data is an object containing x (0-1) and y (0-1) positions of aftertouch.\n\t*\n\t* @outputexample\n\t* button.on('change',function(v) {\n\t* // v is the value of the button\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\tvar Button = (function (_ButtonTemplate) {\n\t function Button() {\n\t _classCallCheck(this, Button);\n\t\n\t var options = [\"mode\"];\n\t\n\t var defaults = {\n\t size: [80, 80],\n\t mode: \"aftertouch\", // button, aftertouch, impulse, toggle\n\t state: false\n\t };\n\t\n\t _get(Object.getPrototypeOf(Button.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t /**\n\t * Interaction mode: supports \"button\", \"aftertouch\", \"impulse\", or \"toggle\"\n\t * @type {string}\n\t * @example button.mode = 'toggle';\n\t */\n\t this.mode = this.settings.mode;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(Button, _ButtonTemplate);\n\t\n\t _createClass(Button, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t this.pad = svg.create(\"circle\");\n\t this.element.appendChild(this.pad);\n\t\n\t this.interactionTarget = this.pad;\n\t\n\t // only used if in 'aftertouch' mode\n\t this.defs = svg.create(\"defs\");\n\t this.element.appendChild(this.defs);\n\t\n\t this.gradient = svg.radialGradient(this.defs, 2);\n\t\n\t this.gradient.stops[0].setAttribute(\"offset\", \"30%\");\n\t\n\t this.gradient.stops[1].setAttribute(\"offset\", \"100%\");\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t this.pad.setAttribute(\"cx\", this.width / 2);\n\t this.pad.setAttribute(\"cy\", this.height / 2);\n\t this.pad.setAttribute(\"r\", Math.min(this.width, this.height) / 2 - this.width / 40);\n\t this.pad.setAttribute(\"stroke-width\", this.width / 20);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t\n\t this.gradient.stops[0].setAttribute(\"stop-color\", this.colors.accent);\n\t this.gradient.stops[1].setAttribute(\"stop-color\", this.colors.fill);\n\t this.render();\n\t }\n\t },\n\t render: {\n\t\n\t /*\n\t * Update the visual interface using its current state\n\t *\n\t * @example\n\t * button.render();\n\t */\n\t\n\t value: function render() {\n\t if (!this.state) {\n\t this.pad.setAttribute(\"fill\", this.colors.fill);\n\t this.pad.setAttribute(\"stroke\", this.colors.mediumLight);\n\t } else {\n\t if (this.mode === \"aftertouch\") {\n\t this.pad.setAttribute(\"stroke\", \"url(#\" + this.gradient.id + \")\");\n\t this.gradient.element.setAttribute(\"cx\", this.position.x * 100 + \"%\");\n\t this.gradient.element.setAttribute(\"cy\", (1 - this.position.y) * 100 + \"%\");\n\t } else {\n\t this.pad.setAttribute(\"stroke\", this.colors.accent);\n\t }\n\t this.pad.setAttribute(\"fill\", this.colors.accent);\n\t }\n\t }\n\t }\n\t });\n\t\n\t return Button;\n\t})(ButtonTemplate);\n\t\n\tmodule.exports = Button;\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar math = __webpack_require__(5);\n\tvar ToggleModel = __webpack_require__(13);\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\tButton Template\n\t*/\n\t\n\tvar ButtonTemplate = (function (_Interface) {\n\t function ButtonTemplate(args, options, defaults) {\n\t _classCallCheck(this, ButtonTemplate);\n\t\n\t _get(Object.getPrototypeOf(ButtonTemplate.prototype), \"constructor\", this).call(this, args, options, defaults);\n\t\n\t this.mode = this.settings.mode || \"button\";\n\t\n\t this.position = {\n\t x: 0,\n\t y: 0\n\t };\n\t\n\t this._state = new ToggleModel(this.settings.state);\n\t }\n\t\n\t _inherits(ButtonTemplate, _Interface);\n\t\n\t _createClass(ButtonTemplate, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t this.pad = svg.create(\"circle\");\n\t this.pad.setAttribute(\"fill\", \"#d18\");\n\t this.pad.setAttribute(\"stroke\", \"#d18\");\n\t this.pad.setAttribute(\"stroke-width\", 4);\n\t\n\t this.element.appendChild(this.pad);\n\t\n\t this.interactionTarget = this.pad;\n\t\n\t this.sizeInterface();\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t this.pad.setAttribute(\"cx\", this.width / 2);\n\t this.pad.setAttribute(\"cy\", this.height / 2);\n\t this.pad.setAttribute(\"r\", Math.min(this.width, this.height) / 2 - 2);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.state) {\n\t this.pad.setAttribute(\"fill\", this.colors.fill);\n\t this.pad.setAttribute(\"stroke\", this.colors.mediumLight);\n\t } else {\n\t this.pad.setAttribute(\"fill\", this.colors.accent);\n\t this.pad.setAttribute(\"stroke\", this.colors.accent);\n\t }\n\t }\n\t },\n\t down: {\n\t value: function down(paintbrush) {\n\t switch (this.mode) {\n\t case \"impulse\":\n\t this.turnOn();\n\t if (this.timeout) {\n\t clearTimeout(this.timeout);\n\t }\n\t this.timeout = setTimeout(this.turnOff.bind(this), 30);\n\t // this.emit('change',this.state);\n\t break;\n\t case \"button\":\n\t this.turnOn();\n\t // this.emit('change',this.state);\n\t break;\n\t case \"aftertouch\":\n\t this.position = {\n\t x: math.clip(this.mouse.x / this.width, 0, 1),\n\t y: math.clip(1 - this.mouse.y / this.height, 0, 1)\n\t };\n\t this.turnOn();\n\t // this.emit('change',{\n\t // state: this.state,\n\t // x: this.position.x,\n\t // y: this.position.y,\n\t // });\n\t break;\n\t case \"toggle\":\n\t this.flip(paintbrush);\n\t // this.emit('change',this.state);\n\t break;\n\t }\n\t }\n\t },\n\t bend: {\n\t value: function bend(mouse) {\n\t if (this.mode === \"aftertouch\") {\n\t this.mouse = mouse || this.mouse;\n\t this.position = {\n\t x: math.clip(this.mouse.x / this.width, 0, 1),\n\t y: math.clip(1 - this.mouse.y / this.height, 0, 1)\n\t };\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t this.render();\n\t }\n\t }\n\t },\n\t up: {\n\t value: function up() {\n\t switch (this.mode) {\n\t case \"button\":\n\t this.turnOff();\n\t // this.emit('change',this.state);\n\t break;\n\t case \"aftertouch\":\n\t this.turnOff();\n\t this.position = {\n\t x: math.clip(this.mouse.x / this.width, 0, 1),\n\t y: math.clip(1 - this.mouse.y / this.height, 0, 1)\n\t };\n\t // this.emit('change',{\n\t // state: this.state,\n\t // x: this.position.x,\n\t // y: this.position.y,\n\t // });\n\t break;\n\t }\n\t }\n\t },\n\t click: {\n\t\n\t /* overwritable interaction handlers */\n\t\n\t value: function click() {\n\t this.down();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t this.bend();\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t this.up();\n\t }\n\t },\n\t state: {\n\t\n\t /**\n\t Whether the button is on (pressed) or off (not pressed)\n\t @type {boolean}\n\t @example button.state = true;\n\t */\n\t\n\t get: function () {\n\t return this._state.state;\n\t },\n\t set: function (value) {\n\t this._state.flip(value);\n\t if (this.mode === \"aftertouch\") {\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t } else {\n\t this.emit(\"change\", this.state);\n\t }\n\t this.render();\n\t }\n\t },\n\t flip: {\n\t\n\t /**\n\t Change the button to its alternate state (off=>on, on=>off), or flip it to a specified state.\n\t @param value {boolean} (Optional) State to flip to.\n\t @example button.flip();\n\t */\n\t\n\t value: function flip(value) {\n\t this._state.flip(value);\n\t if (this.mode === \"aftertouch\") {\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t } else {\n\t this.emit(\"change\", this.state);\n\t }\n\t this.render();\n\t }\n\t },\n\t turnOn: {\n\t\n\t /**\n\t Turn the button's state to true.\n\t @example button.turnOn();\n\t */\n\t\n\t value: function turnOn(emitting) {\n\t this._state.on();\n\t if (emitting !== false) {\n\t if (this.mode === \"aftertouch\") {\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t } else {\n\t this.emit(\"change\", this.state);\n\t }\n\t }\n\t this.render();\n\t }\n\t },\n\t turnOff: {\n\t\n\t /**\n\t Turn the button's state to false.\n\t @example button.turnOff();\n\t */\n\t\n\t value: function turnOff(emitting) {\n\t this._state.off();\n\t if (emitting !== false) {\n\t if (this.mode === \"aftertouch\") {\n\t this.emit(\"change\", {\n\t state: this.state,\n\t x: this.position.x,\n\t y: this.position.y });\n\t } else {\n\t this.emit(\"change\", this.state);\n\t }\n\t }\n\t this.render();\n\t }\n\t }\n\t });\n\t\n\t return ButtonTemplate;\n\t})(Interface);\n\t\n\tmodule.exports = ButtonTemplate;\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar ButtonTemplate = __webpack_require__(17);\n\t\n\t/**\n\t* TextButton\n\t*\n\t* @description Text button\n\t*\n\t* @demo <span nexus-ui=\"textButton\"></span>\n\t*\n\t* @example\n\t* var textbutton = new Nexus.TextButton('#target')\n\t*\n\t* @example\n\t* var textbutton = new Nexus.TextButton('#target',{\n\t* 'size': [150,50],\n\t* 'state': false,\n\t* 'text': 'Play',\n\t* 'alternateText': 'Stop'\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data is a <i>string</i> of the text on the button at the moment it was clicked.\n\t*\n\t* @outputexample\n\t* textbutton.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\tvar TextButton = (function (_ButtonTemplate) {\n\t function TextButton() {\n\t _classCallCheck(this, TextButton);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [150, 50],\n\t state: false,\n\t text: \"Play\"\n\t };\n\t\n\t _get(Object.getPrototypeOf(TextButton.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._text = this.settings.text;\n\t\n\t if (this.settings.alternate) {\n\t //TODO: Remove this conditional in a breaking-changes release\n\t this.settings.alternateText = this.settings.alternate;\n\t console.warn(\"'alternate' initiator is deprecated. Use 'alternateText' instead.\");\n\t }\n\t this._alternateText = this.settings.alternateText;\n\t this.mode = this.settings.alternateText ? \"toggle\" : \"button\";\n\t this.init();\n\t this.render();\n\t\n\t this.state = this.settings.state;\n\t }\n\t\n\t _inherits(TextButton, _ButtonTemplate);\n\t\n\t _createClass(TextButton, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t\n\t this.element = document.createElement(\"div\");\n\t this.parent.appendChild(this.element);\n\t\n\t this.textElement = document.createElement(\"div\");\n\t this.textElement.innerHTML = this._text;\n\t this.element.appendChild(this.textElement);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {}\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.element.style.color = this.colors.dark;\n\t this.render();\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t var textsize = this.height / 3;\n\t var textsize2 = this.width / (this._text.length + 2);\n\t textsize = Math.min(textsize, textsize2);\n\t if (this.alternateText) {\n\t var textsize3 = this.width / (this.alternateText.length + 2);\n\t textsize = Math.min(textsize, textsize3);\n\t }\n\t var styles = \"width: \" + this.width + \"px;\";\n\t styles += \"height: \" + this.height + \"px;\";\n\t styles += \"padding: \" + (this.height - textsize) / 2 + \"px 0px;\";\n\t styles += \"box-sizing: border-box;\";\n\t styles += \"text-align: center;\";\n\t styles += \"font-family: inherit;\";\n\t styles += \"font-weight: 700;\";\n\t styles += \"opacity: 1;\";\n\t styles += \"font-size:\" + textsize + \"px;\";\n\t this.textElement.style.cssText = styles;\n\t this.render();\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.state) {\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.textElement.style.color = this.colors.dark;\n\t this.textElement.innerHTML = this._text;\n\t } else {\n\t this.element.style.backgroundColor = this.colors.accent;\n\t this.textElement.style.color = this.colors.fill;\n\t if (this.alternateText) {\n\t this.textElement.innerHTML = this._alternateText;\n\t } else {\n\t this.textElement.innerHTML = this._text;\n\t }\n\t }\n\t }\n\t },\n\t alternateText: {\n\t\n\t /**\n\t The text to display when the button is in its \"on\" state. If set, this puts the button in \"toggle\" mode.\n\t @type {String}\n\t */\n\t\n\t get: function () {\n\t return this._alternateText;\n\t },\n\t set: function (text) {\n\t if (text) {\n\t this.mode = \"toggle\";\n\t } else {\n\t this.mode = \"button\";\n\t }\n\t this._alternateText = text;\n\t this.render();\n\t }\n\t },\n\t text: {\n\t\n\t /**\n\t The text to display. (If .alternateText exists, then this .text will only be displayed when the button is in its \"off\" state.)\n\t @type {String}\n\t */\n\t\n\t get: function () {\n\t return this._text;\n\t },\n\t set: function (text) {\n\t this._text = text;\n\t this.sizeInterface();\n\t this.render();\n\t }\n\t }\n\t });\n\t\n\t return TextButton;\n\t})(ButtonTemplate);\n\t\n\tmodule.exports = TextButton;\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\t//let svg = require('../util/svg');\n\tvar Interface = __webpack_require__(6);\n\tvar Button = __webpack_require__(16);\n\t\n\t/**\n\t* RadioButton\n\t*\n\t* @description An array of buttons. By default, selecting one button will deselect all other buttons, but this can be customized using the API below.\n\t*\n\t* @demo <div nexus-ui=\"RadioButton\"></div>\n\t*\n\t* @example\n\t* var radiobutton = new Nexus.RadioButton('#target')\n\t*\n\t* @example\n\t* var radiobutton = new Nexus.RadioButton('#target',{\n\t* 'size': [120,25],\n\t* 'numberOfButtons': 4,\n\t* 'active': -1\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data an <i>integer</i>, the index of the button that is currently on. If no button is selected, the value will be -1.\n\t*\n\t* @outputexample\n\t* radiobutton.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\tvar RadioButton = (function (_Interface) {\n\t function RadioButton() {\n\t _classCallCheck(this, RadioButton);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [120, 25],\n\t numberOfButtons: 4,\n\t active: -1\n\t };\n\t\n\t _get(Object.getPrototypeOf(RadioButton.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.buttons = [];\n\t this._numberOfButtons = this.settings.numberOfButtons;\n\t this.active = this.settings.active;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(RadioButton, _Interface);\n\t\n\t _createClass(RadioButton, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = document.createElement(\"div\");\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t for (var i = 0; i < this._numberOfButtons; i++) {\n\t var container = document.createElement(\"span\");\n\t\n\t var button = new Button(container, {\n\t mode: \"toggle\",\n\t component: true }, this.update.bind(this, i));\n\t\n\t this.buttons.push(button);\n\t this.element.appendChild(container);\n\t }\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t var buttonWidth = this.width / this._numberOfButtons;\n\t var buttonHeight = this.height;\n\t\n\t for (var i = 0; i < this._numberOfButtons; i++) {\n\t this.buttons[i].resize(buttonWidth, buttonHeight);\n\t }\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t for (var i = 0; i < this._numberOfButtons; i++) {\n\t this.buttons[i].colors = this.colors;\n\t this.buttons[i].render();\n\t }\n\t }\n\t },\n\t update: {\n\t value: function update(index) {\n\t if (this.buttons[index].state) {\n\t this.select(index);\n\t } else {\n\t this.deselect();\n\t }\n\t // this.render();\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t for (var i = 0; i < this.buttons.length; i++) {\n\t if (i === this.active) {\n\t this.buttons[i].turnOn(false);\n\t } else {\n\t this.buttons[i].turnOff(false);\n\t }\n\t }\n\t }\n\t },\n\t select: {\n\t\n\t /**\n\t Select one button and deselect all other buttons.\n\t @param index {number} The index of the button to select\n\t */\n\t\n\t value: function select(index) {\n\t if (index >= 0 && index < this.buttons.length) {\n\t this.active = index;\n\t this.emit(\"change\", this.active);\n\t this.render();\n\t }\n\t }\n\t },\n\t deselect: {\n\t\n\t /**\n\t Deselect all buttons.\n\t */\n\t\n\t value: function deselect() {\n\t this.active = -1;\n\t this.emit(\"change\", this.active);\n\t this.render();\n\t }\n\t },\n\t numberOfButtons: {\n\t get: function () {\n\t return this._numberOfButtons;\n\t },\n\t\n\t /**\n\t * Update how many buttons are in the interface\n\t * @param {number} buttons How many buttons are in the interface\n\t */\n\t set: function (buttons) {\n\t this._numberOfButtons = buttons;\n\t for (var i = 0; i < this.buttons.length; i++) {\n\t this.buttons[i].destroy();\n\t }\n\t this.buttons = [];\n\t // for (let i=0;i<this.buttons.length;i++) {\n\t // this.buttons[i].destroy();\n\t // }\n\t this.empty();\n\t this.buildInterface();\n\t }\n\t }\n\t });\n\t\n\t return RadioButton;\n\t})(Interface);\n\t\n\tmodule.exports = RadioButton;\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\tvar math = __webpack_require__(5);\n\t\n\t/**\n\t* Number\n\t*\n\t* @description Number interface which is controllable by dragging or typing.\n\t*\n\t* @demo <span nexus-ui=\"number\"></span>\n\t*\n\t* @example\n\t* var number = new Nexus.Number('#target')\n\t*\n\t* @example\n\t* var number = new Nexus.Number('#target',{\n\t* 'size': [60,30],\n\t* 'value': 0,\n\t* 'min': 0,\n\t* 'max': 20000,\n\t* 'step': 1\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data is the number value of the interface.\n\t*\n\t* @outputexample\n\t* number.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Number = (function (_Interface) {\n\t function Number() {\n\t _classCallCheck(this, Number);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [60, 30],\n\t value: 0,\n\t min: 0,\n\t max: 20000,\n\t step: 1\n\t };\n\t\n\t _get(Object.getPrototypeOf(Number.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._value = new Step(this.settings.min, this.settings.max, this.settings.step, this.settings.value);\n\t\n\t /*\n\t Default: 2. How many decimal places to clip the number's visual rendering to. This does not affect number's actual value output -- for that, set the step property to .01, .1, or 1.\n\t @type {number}\n\t @example number.decimalPlaces = 2;\n\t */\n\t this.decimalPlaces = 2;\n\t this.actual = 0;\n\t\n\t this.max = this._value.max;\n\t\n\t this.min = this._value.min;\n\t\n\t this.step = this._value.step;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(Number, _Interface);\n\t\n\t _createClass(Number, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = document.createElement(\"input\");\n\t this.element.type = \"text\";\n\t\n\t this.element.addEventListener(\"blur\", (function () {\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.element.style.color = this.colors.dark;\n\t if (this.element.value !== this.value) {\n\t this.value = parseFloat(this.element.value);\n\t this.render();\n\t }\n\t }).bind(this));\n\t\n\t this.element.addEventListener(\"keydown\", (function (e) {\n\t if (e.which < 48 || e.which > 57) {\n\t if (e.which !== 189 && e.which !== 190 && e.which !== 8) {\n\t e.preventDefault();\n\t }\n\t }\n\t if (e.which === 13) {\n\t this.element.blur();\n\t this.value = this.element.value;\n\t this.emit(\"change\", this.value);\n\t this.render();\n\t }\n\t }).bind(this));\n\t\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t this._minDimension = Math.min(this.width, this.height);\n\t\n\t var styles = \"width: \" + this.width + \"px;\";\n\t styles += \"height: \" + this.height + \"px;\";\n\t styles += \"background-color: #e7e7e7;\";\n\t styles += \"color: #333;\";\n\t styles += \"font-family: arial;\";\n\t styles += \"font-weight: 500;\";\n\t styles += \"font-size:\" + this._minDimension / 2 + \"px;\";\n\t // styles += 'highlight: #d18;';\n\t styles += \"border: none;\";\n\t styles += \"outline: none;\";\n\t styles += \"padding: \" + this._minDimension / 4 + \"px \" + this._minDimension / 4 + \"px;\";\n\t styles += \"box-sizing: border-box;\";\n\t styles += \"userSelect: text;\";\n\t styles += \"mozUserSelect: text;\";\n\t styles += \"webkitUserSelect: text;\";\n\t this.element.style.cssText += styles;\n\t\n\t // to add eventually\n\t // var css = '#'+this.elementID+'::selection{ background-color: transparent }';\n\t\n\t this.element.value = this.value;\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.element.style.color = this.colors.dark;\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t\n\t this.element.value = math.prune(this.value, this.decimalPlaces);\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.hasMoved = false;\n\t this.element.readOnly = true;\n\t this.actual = this.value;\n\t this.initial = { y: this.mouse.y };\n\t this.changeFactor = math.invert(this.mouse.x / this.width);\n\t console.log(this.changeFactor);\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t this.hasMoved = true;\n\t if (this.clicked) {\n\t\n\t var newvalue = this.actual - (this.mouse.y - this.initial.y) * (math.clip(this.max - this.min, 0, 1000) / 200) * Math.pow(this.changeFactor, 2);\n\t this.value = newvalue;\n\t\n\t this.render();\n\t if (this._value.changed) {\n\t this.emit(\"change\", this.value);\n\t }\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t if (!this.hasMoved) {\n\t this.element.readOnly = false;\n\t this.element.focus();\n\t this.element.setSelectionRange(0, this.element.value.length);\n\t this.element.style.backgroundColor = this.colors.accent;\n\t this.element.style.color = this.colors.light;\n\t } else {\n\t document.body.focus();\n\t }\n\t }\n\t },\n\t link: {\n\t\n\t /**\n\t Connect this number interface to a dial or slider\n\t @param {Interface} element Element to connect to.\n\t @example number.link(slider)\n\t */\n\t\n\t value: function link(destination) {\n\t var _this = this;\n\t\n\t this.min = destination.min;\n\t this.max = destination.max;\n\t this.step = destination.step;\n\t destination.on(\"change\", function (v) {\n\t _this.passiveUpdate(v);\n\t });\n\t this.on(\"change\", function (v) {\n\t destination.value = v;\n\t });\n\t this.value = destination.value;\n\t /* return {\n\t listener1: listener1,\n\t listener2: listener2,\n\t destroy: () => {\n\t listener1.remove() (or similar)\n\t listener2.remove() (or similar)\n\t }\n\t } */\n\t }\n\t },\n\t passiveUpdate: {\n\t value: function passiveUpdate(v) {\n\t this._value.update(v);\n\t this.render();\n\t }\n\t },\n\t value: {\n\t\n\t /**\n\t The interface's current value. If set manually, will update the interface and trigger the output event.\n\t @type {number}\n\t @example number.value = 10;\n\t */\n\t\n\t get: function () {\n\t return this._value.value;\n\t },\n\t set: function (v) {\n\t this._value.update(v);\n\t this.emit(\"change\", this.value);\n\t this.render();\n\t }\n\t },\n\t min: {\n\t\n\t /**\n\t Lower limit of the number's output range\n\t @type {number}\n\t @example number.min = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.min;\n\t },\n\t set: function (v) {\n\t this._value.min = v;\n\t }\n\t },\n\t max: {\n\t\n\t /**\n\t Upper limit of the number's output range\n\t @type {number}\n\t @example number.max = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.max;\n\t },\n\t set: function (v) {\n\t this._value.max = v;\n\t }\n\t },\n\t step: {\n\t\n\t /**\n\t The increment that the number's value changes by.\n\t @type {number}\n\t @example number.step = 5;\n\t */\n\t\n\t get: function () {\n\t return this._value.step;\n\t },\n\t set: function (v) {\n\t this._value.step = v;\n\t }\n\t }\n\t });\n\t\n\t return Number;\n\t})(Interface);\n\t\n\tmodule.exports = Number;\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\t* Select\n\t*\n\t* @description Dropdown menu\n\t*\n\t* @demo <span nexus-ui=\"select\"></span>\n\t*\n\t* @example\n\t* var select = new Nexus.Select('#target')\n\t*\n\t* @example\n\t* var select = new Nexus.Select('#target',{\n\t* 'size': [100,30],\n\t* 'options': ['default','options']\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data is an object containing the text value of the selected option, as well as the numeric index of the selection.\n\t*\n\t* @outputexample\n\t* select.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Select = (function (_Interface) {\n\t function Select() {\n\t _classCallCheck(this, Select);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [100, 30],\n\t options: [\"default\", \"options\"]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Select.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._selectedIndex = -1;\n\t this._value = false;\n\t\n\t this._options = this.settings.options;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(Select, _Interface);\n\t\n\t _createClass(Select, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = document.createElement(\"select\");\n\t this.element.style.fontSize = this.height / 2 + \"px\";\n\t this.element.style.outline = \"none\";\n\t this.element.style.highlight = \"none\";\n\t this.element.style.width = this.width + \"px\";\n\t this.element.style.height = this.height + \"px\";\n\t\n\t this.boundRender = this.render.bind(this);\n\t\n\t this.element.addEventListener(\"change\", this.boundRender);\n\t\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t attachListeners: {\n\t value: function attachListeners() {}\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.defineOptions();\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.element.style.color = this.colors.dark;\n\t this.element.style.border = \"solid 0px \" + this.colors.mediumLight;\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t\n\t this._value = this.element.options[this.element.selectedIndex].text;\n\t this._selectedIndex = this.element.selectedIndex;\n\t this.emit(\"change\", {\n\t value: this._value,\n\t index: this._selectedIndex\n\t });\n\t }\n\t },\n\t click: {\n\t value: function click() {}\n\t },\n\t move: {\n\t value: function move() {}\n\t },\n\t release: {\n\t value: function release() {}\n\t },\n\t defineOptions: {\n\t\n\t /**\n\t * Update the list of options. This removes all existing options and creates a new list of options.\n\t * @param {array} options New array of options\n\t */\n\t\n\t value: function defineOptions(options) {\n\t\n\t /* function removeOptions(selectbox)\n\t {\n\t var i;\n\t for(i = selectbox.options.length - 1 ; i >= 0 ; i--)\n\t {\n\t selectbox.remove(i);\n\t }\n\t }\n\t //using the function:\n\t removeOptions(document.getElementById(\"mySelectObject\")); */\n\t\n\t if (options) {\n\t this._options = options;\n\t }\n\t\n\t for (var i = this.element.options.length - 1; i >= 0; i--) {\n\t this.element.remove(i);\n\t }\n\t\n\t for (var i = 0; i < this._options.length; i++) {\n\t this.element.options.add(new Option(this._options[i], i));\n\t }\n\t }\n\t },\n\t value: {\n\t\n\t /**\n\t The text of the option that is currently selected. If set, will update the interface and trigger the output event.\n\t @type {String}\n\t @example select.value = \"sawtooth\";\n\t */\n\t\n\t get: function () {\n\t return this._value;\n\t },\n\t set: function (v) {\n\t this._value = v;\n\t for (var i = 0; i < this.element.options.length; i++) {\n\t if (v === this.element.options[i].text) {\n\t this.selectedIndex = i;\n\t break;\n\t }\n\t }\n\t }\n\t },\n\t selectedIndex: {\n\t\n\t /**\n\t The numeric index of the option that is currently selected. If set, will update the interface and trigger the output event.\n\t @type {number}\n\t @example select.selectedIndex = 2;\n\t */\n\t\n\t get: function () {\n\t return this._selectedIndex;\n\t },\n\t set: function (v) {\n\t this._selectedIndex = v;\n\t this.element.selectedIndex = v;\n\t this.render();\n\t }\n\t },\n\t customDestroy: {\n\t value: function customDestroy() {\n\t this.element.removeEventListener(\"change\", this.boundRender);\n\t }\n\t }\n\t });\n\t\n\t return Select;\n\t})(Interface);\n\t\n\tmodule.exports = Select;\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar math = __webpack_require__(5);\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\t\n\tvar Interaction = _interopRequireWildcard(__webpack_require__(12));\n\t\n\t/**\n\t* Dial\n\t*\n\t*\n\t* @description Dial with radial or linear interaction.\n\t*\n\t* @demo <span nexus-ui=\"dial\"></span>\n\t*\n\t* @example\n\t* var dial = new Nexus.Dial('#target')\n\t*\n\t* @example\n\t* var dial = new Nexus.Dial('#target',{\n\t* 'size': [75,75],\n\t* 'interaction': 'radial', // \"radial\", \"vertical\", or \"horizontal\"\n\t* 'mode': 'relative', // \"absolute\" or \"relative\"\n\t* 'min': 0,\n\t* 'max': 1,\n\t* 'step': 0,\n\t* 'value': 0\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data is the number value of the interface.\n\t*\n\t* @outputexample\n\t* dial.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t* @tutorial\n\t* Dial\n\t* ygGMxq\n\t*\n\t*/\n\t\n\tvar Dial = (function (_Interface) {\n\t function Dial() {\n\t _classCallCheck(this, Dial);\n\t\n\t var options = [\"min\", \"max\", \"value\"];\n\t\n\t var defaults = {\n\t size: [75, 75],\n\t interaction: \"radial\", // radial, vertical, horizontal\n\t mode: \"relative\", // absolute, relative\n\t min: 0,\n\t max: 1,\n\t step: 0,\n\t value: 0\n\t };\n\t\n\t _get(Object.getPrototypeOf(Dial.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.interaction = this.settings.interaction;\n\t\n\t this._value = new Step(this.settings.min, this.settings.max, this.settings.step, this.settings.value);\n\t\n\t this.position = new Interaction.Handle(this.settings.mode, this.interaction, [0, this.width], [this.height, 0]);\n\t\n\t this.init();\n\t\n\t this.value = this._value.value;\n\t\n\t this.position.value = this._value.normalized;\n\t\n\t this.previousAngle = false;\n\t\n\t this.emit(\"change\", this.value);\n\t }\n\t\n\t _inherits(Dial, _Interface);\n\t\n\t _createClass(Dial, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.background = svg.create(\"circle\");\n\t this.screw = svg.create(\"circle\");\n\t this.handle = svg.create(\"path\");\n\t this.handle2 = svg.create(\"path\");\n\t this.handleFill = svg.create(\"path\");\n\t this.handle2Fill = svg.create(\"path\");\n\t this.handleLine = svg.create(\"path\");\n\t\n\t this.element.appendChild(this.background);\n\t this.element.appendChild(this.handle);\n\t this.element.appendChild(this.handle2);\n\t this.element.appendChild(this.handleFill);\n\t this.element.appendChild(this.handle2Fill);\n\t this.element.appendChild(this.handleLine);\n\t this.element.appendChild(this.screw);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t this.position.resize([0, this.width], [this.height, 0]);\n\t\n\t var center = {\n\t x: this.width / 2,\n\t y: this.height / 2\n\t };\n\t\n\t var diameter = Math.min(this.width, this.height);\n\t\n\t this.background.setAttribute(\"cx\", center.x);\n\t this.background.setAttribute(\"cy\", center.y);\n\t this.background.setAttribute(\"r\", diameter / 2 - diameter / 40);\n\t\n\t this.screw.setAttribute(\"cx\", center.x);\n\t this.screw.setAttribute(\"cy\", center.y);\n\t this.screw.setAttribute(\"r\", diameter / 12);\n\t\n\t var value = this.value;\n\t\n\t var handlePoints = {\n\t start: Math.PI * 1.5,\n\t end: math.clip(math.scale(value, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5)\n\t };\n\t var handle2Points = {\n\t start: Math.PI * 2.5,\n\t end: math.clip(math.scale(value, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5)\n\t };\n\t\n\t var handlePath = svg.arc(center.x, center.y, diameter / 2 - diameter / 40, handlePoints.start, handlePoints.end);\n\t var handle2Path = svg.arc(center.x, center.y, diameter / 2 - diameter / 40, handle2Points.start, handle2Points.end);\n\t\n\t this.handle.setAttribute(\"d\", handlePath);\n\t this.handle.setAttribute(\"stroke-width\", diameter / 20);\n\t this.handle.setAttribute(\"fill\", \"none\");\n\t\n\t this.handle2.setAttribute(\"d\", handle2Path);\n\t this.handle2.setAttribute(\"stroke-width\", diameter / 20);\n\t this.handle2.setAttribute(\"fill\", \"none\");\n\t\n\t handlePath += \" L \" + center.x + \" \" + center.y;\n\t\n\t this.handleFill.setAttribute(\"d\", handlePath);\n\t this.handleFill.setAttribute(\"fill-opacity\", \"0.3\");\n\t\n\t handle2Path += \" L \" + center.x + \" \" + center.y;\n\t\n\t this.handle2Fill.setAttribute(\"d\", handle2Path);\n\t this.handle2Fill.setAttribute(\"fill-opacity\", \"0.3\");\n\t\n\t var arcEndingA = undefined;\n\t if (value < 0.5) {\n\t arcEndingA = handlePoints.end;\n\t } else {\n\t arcEndingA = handle2Points.end;\n\t }\n\t\n\t var arcEndingX = center.x + Math.cos(arcEndingA) * (diameter / 2);\n\t var arcEndingY = center.y + Math.sin(arcEndingA) * (diameter / 2) * -1;\n\t\n\t this.handleLine.setAttribute(\"d\", \"M \" + center.x + \" \" + center.y + \" L \" + arcEndingX + \" \" + arcEndingY);\n\t this.handleLine.setAttribute(\"stroke-width\", diameter / 20);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.background.setAttribute(\"fill\", this.colors.fill);\n\t this.screw.setAttribute(\"fill\", this.colors.accent);\n\t this.handle.setAttribute(\"stroke\", this.colors.accent);\n\t this.handle2.setAttribute(\"stroke\", this.colors.accent);\n\t this.handleFill.setAttribute(\"fill\", this.colors.accent);\n\t this.handle2Fill.setAttribute(\"fill\", this.colors.accent);\n\t this.handleLine.setAttribute(\"stroke\", this.colors.accent);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t var value = this._value.normalized;\n\t\n\t var center = {\n\t x: this.width / 2,\n\t y: this.height / 2\n\t };\n\t\n\t var diameter = Math.min(this.width, this.height);\n\t\n\t var handlePoints = {\n\t start: Math.PI * 1.5,\n\t end: math.clip(math.scale(value, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5)\n\t };\n\t var handle2Points = {\n\t start: Math.PI * 2.5,\n\t end: math.clip(math.scale(value, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5)\n\t };\n\t\n\t var handlePath = svg.arc(center.x, center.y, diameter / 2 - diameter / 40, handlePoints.start, handlePoints.end);\n\t var handle2Path = svg.arc(center.x, center.y, diameter / 2 - diameter / 40, handle2Points.start, handle2Points.end);\n\t\n\t this.handle.setAttribute(\"d\", handlePath);\n\t this.handle2.setAttribute(\"d\", handle2Path);\n\t\n\t handlePath += \" L \" + center.x + \" \" + center.y;\n\t\n\t this.handleFill.setAttribute(\"d\", handlePath);\n\t\n\t handle2Path += \" L \" + center.x + \" \" + center.y;\n\t\n\t this.handle2Fill.setAttribute(\"d\", handle2Path);\n\t\n\t var arcEndingA = undefined;\n\t if (value <= 0.5) {\n\t arcEndingA = handlePoints.end;\n\t } else {\n\t arcEndingA = handle2Points.end;\n\t }\n\t\n\t var arcEndingX = center.x + Math.cos(arcEndingA) * (diameter / 2);\n\t var arcEndingY = center.y + Math.sin(arcEndingA) * (diameter / 2) * -1;\n\t\n\t this.handleLine.setAttribute(\"d\", \"M \" + center.x + \" \" + center.y + \" L \" + arcEndingX + \" \" + arcEndingY);\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t if (this.mode === \"relative\") {\n\t this.previousAngle = false;\n\t }\n\t this.position.anchor = this.mouse;\n\t this.position.value = this._value.normalized;\n\t this.move();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.clicked) {\n\t\n\t this.position.update(this.mouse);\n\t\n\t var angle = this.position.value * Math.PI * 2;\n\t\n\t if (angle < 0) {\n\t angle += Math.PI * 2;\n\t }\n\t\n\t if (this.mode === \"relative\") {\n\t if (this.previousAngle !== false && Math.abs(this.previousAngle - angle) > 2) {\n\t if (this.previousAngle > 3) {\n\t angle = Math.PI * 2;\n\t } else {\n\t angle = 0;\n\t }\n\t }\n\t } /* else {\n\t if (this.previousAngle !== false && Math.abs(this.previousAngle - angle) > 2) {\n\t if (this.previousAngle > 3) {\n\t angle = Math.PI*2;\n\t } else {\n\t angle = 0;\n\t }\n\t }\n\t } */\n\t this.previousAngle = angle;\n\t\n\t var realValue = angle / (Math.PI * 2);\n\t\n\t this.value = this._value.updateNormal(realValue);\n\t\n\t if (this.mode === \"relative\") {\n\t this.position.value = realValue;\n\t }\n\t\n\t this.emit(\"change\", this._value.value);\n\t\n\t this.render();\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {}\n\t },\n\t value: {\n\t\n\t /*\n\t Dial's value. When set, it will automatically be adjust to fit min/max/step settings of the interface.\n\t @type {number}\n\t @example dial.value = 10;\n\t get value() {\n\t return this._value.value;\n\t }\n\t set value(value) {\n\t this._value.update(value);\n\t this.emit('change',this.value);\n\t this.render();\n\t }\n\t */\n\t\n\t /**\n\t Dial's value. When set, it will automatically be adjust to fit min/max/step settings of the interface.\n\t @type {number}\n\t @example dial.value = 10;\n\t */\n\t\n\t get: function () {\n\t return this._value.value;\n\t },\n\t set: function (v) {\n\t this._value.update(v);\n\t this.position.value = this._value.normalized;\n\t this.emit(\"change\", this._value.value);\n\t this.render();\n\t }\n\t },\n\t min: {\n\t\n\t /**\n\t Lower limit of the dial's output range\n\t @type {number}\n\t @example dial.min = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.min;\n\t },\n\t set: function (v) {\n\t this._value.min = v;\n\t }\n\t },\n\t max: {\n\t\n\t /**\n\t Upper limit of the dial's output range\n\t @type {number}\n\t @example dial.max = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.max;\n\t },\n\t set: function (v) {\n\t this._value.max = v;\n\t }\n\t },\n\t step: {\n\t\n\t /**\n\t The increment that the dial's value changes by.\n\t @type {number}\n\t @example dial.step = 5;\n\t */\n\t\n\t get: function () {\n\t return this._value.step;\n\t },\n\t set: function (v) {\n\t this._value.step = v;\n\t }\n\t },\n\t mode: {\n\t\n\t /**\n\t Absolute mode (dial's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: \"relative\".\n\t @type {string}\n\t @example dial.mode = \"relative\";\n\t */\n\t\n\t get: function () {\n\t return this.position.mode;\n\t },\n\t set: function (v) {\n\t this.position.mode = v;\n\t }\n\t },\n\t normalized: {\n\t\n\t /**\n\t Normalized value of the dial.\n\t @type {number}\n\t @example dial.normalized = 0.5;\n\t */\n\t\n\t get: function () {\n\t return this._value.normalized;\n\t },\n\t set: function (v) {\n\t this._value.updateNormal(v);\n\t this.emit(\"change\", this.value);\n\t }\n\t }\n\t });\n\t\n\t return Dial;\n\t})(Interface);\n\t\n\tmodule.exports = Dial;\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar Interface = __webpack_require__(6);\n\tvar ButtonTemplate = __webpack_require__(17);\n\tvar touch = __webpack_require__(9);\n\t\n\tvar PianoKey = (function (_ButtonTemplate) {\n\t function PianoKey() {\n\t _classCallCheck(this, PianoKey);\n\t\n\t var options = [\"value\", \"note\", \"color\"];\n\t\n\t var defaults = {\n\t size: [80, 80],\n\t target: false,\n\t mode: \"button\",\n\t value: 0\n\t };\n\t\n\t _get(Object.getPrototypeOf(PianoKey.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.note = this.settings.note;\n\t this.color = this.settings.color;\n\t\n\t this.colors = {\n\t w: \"#fff\",\n\t b: \"#666\" };\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(PianoKey, _ButtonTemplate);\n\t\n\t _createClass(PianoKey, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = svg.create(\"svg\");\n\t this.element.setAttribute(\"width\", this.width);\n\t this.element.setAttribute(\"height\", this.height);\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t var _this = this;\n\t\n\t this.pad = svg.create(\"rect\");\n\t\n\t this.element.appendChild(this.pad);\n\t\n\t this.interactionTarget = this.pad;\n\t\n\t /* events */\n\t\n\t if (!touch.exists) {\n\t\n\t this.click = function () {\n\t // console.log('click');\n\t _this.piano.interacting = true;\n\t _this.piano.paintbrush = !_this.state;\n\t _this.down(_this.piano.paintbrush);\n\t };\n\t\n\t this.pad.addEventListener(\"mouseover\", function () {\n\t if (_this.piano.interacting) {\n\t // console.log('mouseover');\n\t _this.down(_this.piano.paintbrush);\n\t }\n\t });\n\t\n\t this.move = function () {\n\t if (_this.piano.interacting) {\n\t // console.log('move');\n\t _this.bend();\n\t }\n\t };\n\t\n\t this.release = function () {\n\t _this.piano.interacting = false;\n\t // console.log('release');\n\t // this.up();\n\t };\n\t this.pad.addEventListener(\"mouseup\", function () {\n\t if (_this.piano.interacting) {\n\t // console.log('mouseup');\n\t _this.up();\n\t }\n\t });\n\t this.pad.addEventListener(\"mouseout\", function () {\n\t if (_this.piano.interacting) {\n\t // console.log('mouseout');\n\t _this.up();\n\t }\n\t });\n\t }\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t //let radius = Math.min(this.width,this.height) / 5;\n\t var radius = 0;\n\t\n\t this.pad.setAttribute(\"x\", 0.5);\n\t this.pad.setAttribute(\"y\", 0.5);\n\t if (this.width > 2) {\n\t this.pad.setAttribute(\"width\", this.width - 1);\n\t } else {\n\t this.pad.setAttribute(\"width\", this.width);\n\t }\n\t if (this.height > 2) {\n\t this.pad.setAttribute(\"height\", this.height);\n\t } else {\n\t this.pad.setAttribute(\"height\", this.height);\n\t }\n\t this.pad.setAttribute(\"rx\", radius);\n\t this.pad.setAttribute(\"ry\", radius);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.state) {\n\t this.pad.setAttribute(\"fill\", this.colors[this.color]);\n\t } else {\n\t this.pad.setAttribute(\"fill\", this.colors.accent);\n\t }\n\t }\n\t }\n\t });\n\t\n\t return PianoKey;\n\t})(ButtonTemplate);\n\t\n\t/**\n\t* Piano\n\t*\n\t* @description Piano keyboard interface\n\t*\n\t* @demo <div nexus-ui=\"piano\"></div>\n\t*\n\t* @example\n\t* var piano = new Nexus.Piano('#target')\n\t*\n\t* @example\n\t* var piano = new Nexus.Piano('#target',{\n\t* 'size': [500,125],\n\t* 'mode': 'button', // 'button', 'toggle', or 'impulse'\n\t* 'lowNote': 24,\n\t* 'highNote': 60\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time a new key is pressed or released <br>\n\t* The event data is an object containing <i>note</i> and <i>state</i> properties.\n\t*\n\t* @outputexample\n\t* piano.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\tvar Piano = (function (_Interface) {\n\t function Piano() {\n\t _classCallCheck(this, Piano);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [500, 125],\n\t lowNote: 24,\n\t highNote: 60,\n\t mode: \"button\"\n\t };\n\t\n\t _get(Object.getPrototypeOf(Piano.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.keyPattern = [\"w\", \"b\", \"w\", \"b\", \"w\", \"w\", \"b\", \"w\", \"b\", \"w\", \"b\", \"w\"];\n\t\n\t this.paintbrush = false;\n\t\n\t this.mode = this.settings.mode;\n\t\n\t this.range = {\n\t low: this.settings.lowNote,\n\t high: this.settings.highNote\n\t };\n\t\n\t this.range.size = this.range.high - this.range.low;\n\t\n\t this.keys = [];\n\t\n\t this.toggleTo = false;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(Piano, _Interface);\n\t\n\t _createClass(Piano, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = document.createElement(\"div\");\n\t this.element.style.position = \"relative\";\n\t this.element.style.borderRadius = \"0px\";\n\t this.element.style.display = \"block\";\n\t this.element.style.width = \"100%\";\n\t this.element.style.height = \"100%\";\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.keys = [];\n\t\n\t for (var i = 0; i < this.range.high - this.range.low; i++) {\n\t\n\t var container = document.createElement(\"span\");\n\t var scaleIndex = (i + this.range.low) % this.keyPattern.length;\n\t\n\t var key = new PianoKey(container, {\n\t component: true,\n\t note: i + this.range.low,\n\t color: this.keyPattern[scaleIndex],\n\t mode: this.mode\n\t }, this.keyChange.bind(this, i + this.range.low));\n\t\n\t key.piano = this;\n\t\n\t if (touch.exists) {\n\t key.pad.index = i;\n\t key.preClick = key.preMove = key.preRelease = function () {};\n\t key.click = key.move = key.release = function () {};\n\t key.preTouch = key.preTouchMove = key.preTouchRelease = function () {};\n\t key.touch = key.touchMove = key.touchRelease = function () {};\n\t }\n\t\n\t this.keys.push(key);\n\t this.element.appendChild(container);\n\t }\n\t if (touch.exists) {\n\t this.addTouchListeners();\n\t }\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t var keyX = 0;\n\t\n\t var keyPositions = [];\n\t\n\t for (var i = 0; i < this.range.high - this.range.low; i++) {\n\t\n\t keyPositions.push(keyX);\n\t\n\t var scaleIndex = (i + this.range.low) % this.keyPattern.length;\n\t var nextScaleIndex = (i + 1 + this.range.low) % this.keyPattern.length;\n\t if (i + 1 + this.range.low >= this.range.high) {\n\t keyX += 1;\n\t } else if (this.keyPattern[scaleIndex] === \"w\" && this.keyPattern[nextScaleIndex] === \"w\") {\n\t keyX += 1;\n\t } else {\n\t keyX += 0.5;\n\t }\n\t }\n\t var keysWide = keyX;\n\t\n\t // let padding = this.width / 120;\n\t var padding = 1;\n\t var buttonWidth = (this.width - padding * 2) / keysWide;\n\t var buttonHeight = (this.height - padding * 2) / 2;\n\t\n\t for (var i = 0; i < this.keys.length; i++) {\n\t\n\t var container = this.keys[i].parent;\n\t container.style.position = \"absolute\";\n\t container.style.left = keyPositions[i] * buttonWidth + padding + \"px\";\n\t if (this.keys[i].color === \"w\") {\n\t container.style.top = padding + \"px\";\n\t this.keys[i].resize(buttonWidth, buttonHeight * 2);\n\t } else {\n\t container.style.zIndex = 1;\n\t container.style.top = padding + \"px\";\n\t this.keys[i].resize(buttonWidth, buttonHeight * 1.1);\n\t }\n\t }\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t\n\t // Piano keys don't actually have a stroke border\n\t // They have space between them, which shows the Piano bg color\n\t this.element.style.backgroundColor = this.colors.mediumLight;\n\t\n\t for (var i = 0; i < this.keys.length; i++) {\n\t this.keys[i].colors = {\n\t w: this.colors.light,\n\t b: this.colors.dark,\n\t accent: this.colors.accent,\n\t border: this.colors.mediumLight\n\t };\n\t this.keys[i].colorInterface();\n\t this.keys[i].render();\n\t }\n\t }\n\t },\n\t keyChange: {\n\t value: function keyChange(note, on) {\n\t // emit data for any key turning on/off\n\t // \"note\" is the note value\n\t // \"on\" is a boolean whether it is on or off\n\t // in aftertouch mode, \"on: is an object with state/x/y properties\n\t var data = {\n\t note: note\n\t };\n\t if (typeof on === \"object\") {\n\t data.state = on.state;\n\t // data.x = on.x\n\t // data.y = on.y\n\t } else {\n\t data.state = on;\n\t }\n\t this.emit(\"change\", data);\n\t }\n\t },\n\t render: {\n\t\n\t /* drag(note,on) {\n\t this.emit('change',{\n\t note: note,\n\t state: on\n\t });\n\t } */\n\t\n\t value: function render() {}\n\t },\n\t addTouchListeners: {\n\t value: function addTouchListeners() {\n\t var _this = this;\n\t\n\t this.preClick = this.preMove = this.preRelease = function () {};\n\t this.click = this.move = this.release = function () {};\n\t this.preTouch = this.preTouchMove = this.preTouchRelease = function () {};\n\t this.touch = this.touchMove = this.touchRelease = function () {};\n\t\n\t this.currentElement = false;\n\t\n\t this.element.addEventListener(\"touchstart\", function (e) {\n\t console.log(\"touchstart\");\n\t var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);\n\t var key = _this.keys[element.index];\n\t _this.paintbrush = !key.state;\n\t key.down(_this.paintbrush);\n\t _this.currentElement = element.index;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t\n\t this.element.addEventListener(\"touchmove\", function (e) {\n\t var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);\n\t var key = _this.keys[element.index];\n\t if (element.index !== _this.currentElement) {\n\t if (_this.currentElement) {\n\t var pastKey = _this.keys[_this.currentElement];\n\t pastKey.up();\n\t }\n\t key.down(_this.paintbrush);\n\t } else {\n\t key.bend();\n\t }\n\t _this.currentElement = element.index;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t\n\t this.element.addEventListener(\"touchend\", function (e) {\n\t // no touches to calculate because none remaining\n\t var key = _this.keys[_this.currentElement];\n\t key.up();\n\t _this.interacting = false;\n\t _this.currentElement = false;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t }\n\t },\n\t setRange: {\n\t\n\t /**\n\t Define the pitch range (lowest and highest note) of the piano keyboard.\n\t @param low {number} MIDI note value of the lowest note on the keyboard\n\t @param high {number} MIDI note value of the highest note on the keyboard\n\t */\n\t\n\t value: function setRange(low, high) {\n\t this.range.low = low;\n\t this.range.high = high;\n\t this.empty();\n\t this.buildInterface();\n\t }\n\t },\n\t toggleKey: {\n\t\n\t /**\n\t Turn a key on or off using its MIDI note value;\n\t @param note {number} MIDI note value of the key to change\n\t @param on {boolean} Whether the note should turn on or off\n\t */\n\t\n\t value: function toggleKey(note, on) {\n\t this.keys[note - this.range.low].flip(on);\n\t }\n\t },\n\t toggleIndex: {\n\t\n\t /**\n\t Turn a key on or off using its key index on the piano interface.\n\t @param index {number} Index of the key to change\n\t @param on {boolean} Whether the note should turn on or off\n\t */\n\t\n\t value: function toggleIndex(index, on) {\n\t this.keys[index].flip(on);\n\t }\n\t }\n\t });\n\t\n\t return Piano;\n\t})(Interface);\n\t\n\tmodule.exports = Piano;\n\t\n\t// loop through and render the keys?\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar dom = __webpack_require__(7);\n\tvar Interface = __webpack_require__(6);\n\tvar ButtonTemplate = __webpack_require__(17);\n\tvar MatrixModel = __webpack_require__(25);\n\tvar CounterModel = __webpack_require__(28);\n\tvar touch = __webpack_require__(9);\n\t\n\tvar MatrixCell = (function (_ButtonTemplate) {\n\t function MatrixCell() {\n\t _classCallCheck(this, MatrixCell);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [80, 80],\n\t target: false,\n\t mode: \"toggle\",\n\t value: 0\n\t };\n\t\n\t _get(Object.getPrototypeOf(MatrixCell.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.index = this.settings.index;\n\t this.row = this.settings.row;\n\t this.column = this.settings.column;\n\t\n\t this.matrix = this.settings.matrix;\n\t\n\t this.interacting = false;\n\t this.paintbrush = false;\n\t\n\t this.init();\n\t this.render();\n\t }\n\t\n\t _inherits(MatrixCell, _ButtonTemplate);\n\t\n\t _createClass(MatrixCell, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = svg.create(\"svg\");\n\t this.element.setAttribute(\"width\", this.width);\n\t this.element.setAttribute(\"height\", this.height);\n\t this.element.style.top = \"0px\";\n\t this.element.style.left = \"0px\";\n\t this.element.style.position = \"absolute\";\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t var _this = this;\n\t\n\t this.pad = svg.create(\"rect\");\n\t this.element.appendChild(this.pad);\n\t\n\t this.interactionTarget = this.pad;\n\t\n\t /* events */\n\t\n\t if (!touch.exists) {\n\t\n\t this.click = function () {\n\t _this.matrix.interacting = true;\n\t _this.matrix.paintbrush = !_this.state;\n\t _this.down(_this.matrix.paintbrush);\n\t };\n\t this.pad.addEventListener(\"mouseover\", function () {\n\t if (_this.matrix.interacting) {\n\t _this.down(_this.matrix.paintbrush);\n\t }\n\t });\n\t\n\t this.move = function () {};\n\t this.pad.addEventListener(\"mousemove\", function (e) {\n\t if (_this.matrix.interacting) {\n\t if (!_this.offset) {\n\t _this.offset = dom.findPosition(_this.element);\n\t }\n\t _this.mouse = dom.locateMouse(e, _this.offset);\n\t _this.bend();\n\t }\n\t });\n\t\n\t this.release = function () {\n\t _this.matrix.interacting = false;\n\t };\n\t this.pad.addEventListener(\"mouseup\", function () {\n\t if (_this.matrix.interacting) {\n\t _this.up();\n\t }\n\t });\n\t this.pad.addEventListener(\"mouseout\", function () {\n\t if (_this.matrix.interacting) {\n\t _this.up();\n\t }\n\t });\n\t }\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t this.pad.setAttribute(\"x\", 1);\n\t this.pad.setAttribute(\"y\", 1);\n\t if (this.width > 2) {\n\t this.pad.setAttribute(\"width\", this.width - 2);\n\t } else {\n\t this.pad.setAttribute(\"width\", this.width);\n\t }\n\t if (this.height > 2) {\n\t this.pad.setAttribute(\"height\", this.height - 2);\n\t } else {\n\t this.pad.setAttribute(\"height\", this.height);\n\t }\n\t //this.pad.setAttribute('height', this.height - 2);\n\t this.pad.setAttribute(\"fill\", this.matrix.colors.fill);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.state) {\n\t this.pad.setAttribute(\"fill\", this.matrix.colors.fill);\n\t } else {\n\t this.pad.setAttribute(\"fill\", this.matrix.colors.accent);\n\t }\n\t }\n\t }\n\t });\n\t\n\t return MatrixCell;\n\t})(ButtonTemplate);\n\t\n\t/**\n\t* Sequencer\n\t*\n\t* @description Grid of buttons with built-in step sequencer.\n\t*\n\t* @demo <div nexus-ui=\"sequencer\" style=\"width:400px;height:200px;\"></div>\n\t*\n\t* @example\n\t* var sequencer = new Nexus.Sequencer('#target')\n\t*\n\t* @example\n\t* var sequencer = new Nexus.Sequencer('#target',{\n\t* 'size': [400,200],\n\t* 'mode': 'toggle',\n\t* 'rows': 5,\n\t* 'columns': 10\n\t*})\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's matrix changes. <br>\n\t* The event data is an object containing <i>row</i> (number), <i>column</i> (number), and <i>state</i> (boolean) properties.\n\t*\n\t* @outputexample\n\t* sequencer.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t* @output\n\t* step\n\t* Fires any time the sequencer steps to the next column, in sequece mode. <br>\n\t* The event data is an <i>array</i> containing all values in the column, <i>bottom row first</i>.\n\t*\n\t* @outputexample\n\t* sequencer.on('step',function(v) {\n\t* console.log(v);\n\t* })\n\t*/\n\t\n\tvar Sequencer = (function (_Interface) {\n\t function Sequencer() {\n\t _classCallCheck(this, Sequencer);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [400, 200],\n\t mode: \"toggle\",\n\t rows: 5,\n\t columns: 10\n\t };\n\t\n\t _get(Object.getPrototypeOf(Sequencer.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.active = -1;\n\t\n\t /**\n\t * Button interaction mode: see Button\n\t * @type {string}\n\t * @example button.mode = 'toggle';\n\t */\n\t this.mode = this.settings.mode;\n\t\n\t /**\n\t * The interval object which controls timing and sequence scheduling.\n\t * @type {interval}\n\t */\n\t this.interval = new Nexus.Interval(200, function () {}, false); // jshint ignore:line\n\t\n\t /**\n\t * A Matrix model containing methods for manipulating the sequencer's array of values. To learn how to manipulate the matrix, read about the matrix model.\n\t * @type {matrix}\n\t */\n\t this.matrix = new MatrixModel(this.settings.rows, this.settings.columns);\n\t this.matrix.ui = this;\n\t\n\t /**\n\t * A Counter model which the sequencer steps through. For example, you could use this model to step through the sequencer in reverse, randomly, or in a drunk walk.\n\t * @type {counter}\n\t */\n\t this.stepper = new CounterModel(0, this.columns);\n\t\n\t this.init();\n\t }\n\t\n\t _inherits(Sequencer, _Interface);\n\t\n\t _createClass(Sequencer, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = document.createElement(\"div\");\n\t this.element.style.position = \"relative\";\n\t this.element.style.display = \"block\";\n\t this.element.style.width = \"100%\";\n\t this.element.style.height = \"100%\";\n\t this.parent.appendChild(this.element);\n\t if (touch.exists) {\n\t this.addTouchListeners();\n\t }\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.cells = [];\n\t for (var i = 0; i < this.matrix.length; i++) {\n\t\n\t var _location = this.matrix.locate(i);\n\t // returns {row,col}\n\t\n\t var container = document.createElement(\"span\");\n\t container.style.position = \"absolute\";\n\t\n\t var cell = new MatrixCell(container, {\n\t component: true,\n\t index: i,\n\t row: _location.row,\n\t column: _location.column,\n\t mode: this.mode,\n\t matrix: this\n\t }, this.keyChange.bind(this, i));\n\t\n\t // cell.matrix = this;\n\t if (touch.exists) {\n\t cell.pad.index = i;\n\t cell.preClick = cell.preMove = cell.preRelease = function () {};\n\t cell.click = cell.move = cell.release = function () {};\n\t cell.preTouch = cell.preTouchMove = cell.preTouchRelease = function () {};\n\t cell.touch = cell.touchMove = cell.touchRelease = function () {};\n\t }\n\t\n\t this.cells.push(cell);\n\t this.element.appendChild(container);\n\t }\n\t this.sizeInterface();\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t var cellWidth = this.width / this.columns;\n\t var cellHeight = this.height / this.rows;\n\t\n\t for (var i = 0; i < this.cells.length; i++) {\n\t var container = this.cells[i].parent;\n\t container.style.left = this.cells[i].column * cellWidth + \"px\";\n\t container.style.top = this.cells[i].row * cellHeight + \"px\";\n\t this.cells[i].resize(cellWidth, cellHeight);\n\t }\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t for (var i = 0; i < this.cells.length; i++) {\n\t this.cells[i].render();\n\t }\n\t }\n\t },\n\t update: {\n\t value: function update() {\n\t var _this = this;\n\t\n\t // console.log(\"updating...\")\n\t //on = on || false;\n\t this.matrix.iterate(function (r, c, i) {\n\t // console.log(this.matrix.pattern[r][c], this.cells[i].state);\n\t if (_this.matrix.pattern[r][c] !== _this.cells[i].state) {\n\t if (_this.matrix.pattern[r][c] > 0) {\n\t _this.cells[i].turnOn();\n\t } else {\n\t _this.cells[i].turnOff();\n\t }\n\t }\n\t });\n\t }\n\t },\n\t keyChange: {\n\t\n\t // update => cell.turnOn => cell.emit => keyChange (seq.emit) => matrix.set.cell => update\n\t //\n\t // interaction => keyChange => matrix.set.cell => update => cell.turnOn\n\t // => emit\n\t //\n\t // set.cell => update => needs to emit.\n\t\n\t value: function keyChange(note, on) {\n\t // emit data for any key turning on/off\n\t // i is the note index\n\t // v is whether it is on or off\n\t var cell = this.matrix.locate(note);\n\t // this.matrix.set.cell(cell.column,cell.row,on);\n\t this.matrix.pattern[cell.row][cell.column] = on;\n\t var data = {\n\t row: cell.row,\n\t column: cell.column,\n\t state: on\n\t };\n\t this.emit(\"change\", data);\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t var _this = this;\n\t\n\t if (this.stepper.value >= 0) {\n\t this.matrix.iterate(function (r, c, i) {\n\t if (c === _this.stepper.value) {\n\t _this.cells[i].pad.setAttribute(\"stroke\", _this.colors.mediumLight);\n\t _this.cells[i].pad.setAttribute(\"stroke-width\", \"1\");\n\t _this.cells[i].pad.setAttribute(\"stroke-opacity\", \"1\");\n\t } else {\n\t _this.cells[i].pad.setAttribute(\"stroke\", \"none\");\n\t }\n\t });\n\t }\n\t }\n\t },\n\t start: {\n\t\n\t /**\n\t * Start sequencing\n\t * @param {number} ms Beat tempo in milliseconds\n\t */\n\t\n\t value: function start(ms) {\n\t this.interval.event = this.next.bind(this);\n\t if (ms) {\n\t this.interval.ms(ms);\n\t }\n\t this.interval.start();\n\t }\n\t },\n\t stop: {\n\t\n\t /**\n\t Stop sequencing\n\t */\n\t\n\t value: function stop() {\n\t this.interval.stop();\n\t }\n\t },\n\t next: {\n\t\n\t /**\n\t Manually jump to the next column and trigger the 'change' event. The \"next\" column is determined by your mode of sequencing.\n\t */\n\t\n\t value: function next() {\n\t this.stepper.next();\n\t this.emit(\"step\", this.matrix.column(this.stepper.value).reverse());\n\t this.render();\n\t }\n\t },\n\t addTouchListeners: {\n\t value: function addTouchListeners() {\n\t var _this = this;\n\t\n\t this.preClick = this.preMove = this.preRelease = function () {};\n\t this.click = this.move = this.release = function () {};\n\t this.preTouch = this.preTouchMove = this.preTouchRelease = function () {};\n\t this.touch = this.touchMove = this.touchRelease = function () {};\n\t\n\t this.currentElement = false;\n\t\n\t this.element.addEventListener(\"touchstart\", function (e) {\n\t var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);\n\t var cell = _this.cells[element.index];\n\t _this.paintbrush = !cell.state;\n\t cell.down(_this.paintbrush);\n\t _this.currentElement = element.index;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t\n\t this.element.addEventListener(\"touchmove\", function (e) {\n\t var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);\n\t var cell = _this.cells[element.index];\n\t if (element.index !== _this.currentElement) {\n\t if (_this.currentElement >= 0) {\n\t var pastCell = _this.cells[_this.currentElement];\n\t pastCell.up();\n\t }\n\t cell.down(_this.paintbrush);\n\t } else {\n\t cell.bend();\n\t }\n\t _this.currentElement = element.index;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t\n\t this.element.addEventListener(\"touchend\", function (e) {\n\t // no touches to calculate because none remaining\n\t var cell = _this.cells[_this.currentElement];\n\t cell.up();\n\t _this.interacting = false;\n\t _this.currentElement = false;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t }\n\t },\n\t rows: {\n\t\n\t /**\n\t Number of rows in the sequencer\n\t @type {number}\n\t */\n\t\n\t get: function () {\n\t return this.matrix.rows;\n\t },\n\t set: function (v) {\n\t this.matrix.rows = v;\n\t this.empty();\n\t this.buildInterface();\n\t this.update();\n\t }\n\t },\n\t columns: {\n\t\n\t /**\n\t Number of columns in the sequencer\n\t @type {number}\n\t */\n\t\n\t get: function () {\n\t return this.matrix.columns;\n\t },\n\t set: function (v) {\n\t this.matrix.columns = v;\n\t this.stepper.max = v;\n\t this.empty();\n\t this.buildInterface();\n\t this.update();\n\t }\n\t }\n\t });\n\t\n\t return Sequencer;\n\t})(Interface);\n\t\n\tmodule.exports = Sequencer;\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar Sequence = _interopRequire(__webpack_require__(26));\n\t\n\t// For the tutorial, looking at\n\t\n\t//Pattern section:\n\t// .create(), .rows, .columns,\n\t// .pattern, .length, .formatAsText(), .log(),\n\t// .locate(i), .indexOf(c,r)\n\t// row(), column() (returns contents of row or colum)\n\t\n\t//Control section:\n\t// toggle x3\n\t// set x4\n\t// rotate x3\n\t// populate x3\n\t// erase x3\n\t\n\t// should some version of this have a float value for each cell?\n\t// could be like a mirror .pattern that has values. by default, everything is 1, but could be set...\n\t// not a good way to do that on interface, but as a model it would be nice...\n\t// for .formatAsText(), could multiply by 100 and floor, so each cell is an int from 0 to 9\n\t\n\tvar Matrix = (function () {\n\t function Matrix(rows, columns) {\n\t var _this = this;\n\t\n\t _classCallCheck(this, Matrix);\n\t\n\t // should also have ability to create using an existing matrix (2d array)\n\t this.pattern = [];\n\t this.create(rows, columns);\n\t\n\t this.toggle = {\n\t cell: function (column, row) {\n\t _this.pattern[row][column] = !_this.pattern[row][column]; // math.invert(this.pattern[row][column]);\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t return _this.pattern[row][column];\n\t },\n\t all: function () {\n\t _this.iterate(function (r, c) {\n\t _this.toggle.cell(c, r);\n\t });\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t row: function (row) {\n\t for (var i = 0; i < _this.columns; i++) {\n\t _this.toggle.cell(i, row);\n\t }\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t column: function (column) {\n\t for (var i = 0; i < _this.rows; i++) {\n\t _this.toggle.cell(column, i);\n\t }\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t }\n\t };\n\t\n\t this.set = {\n\t cell: function (column, row, value) {\n\t _this.pattern[row][column] = value;\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t all: function (values) {\n\t // set the whole matrix using a 2d array as input\n\t // this should also resize the array?\n\t _this.pattern = values;\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t row: function (row, values) {\n\t // set a row using an array as input\n\t _this.pattern[row] = values;\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t column: function (column, values) {\n\t // set a column using an array as input\n\t _this.pattern.forEach(function (row, i) {\n\t _this.pattern[i][column] = values[i];\n\t });\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t }\n\t };\n\t\n\t this.rotate = {\n\t //should eventually do (amountX, amountY) here\n\t // could just use a loop and this.rotate.row(i,amountX);\n\t all: function (amount) {\n\t if (!amount && amount !== 0) {\n\t amount = 1;\n\t }\n\t amount %= _this.pattern[0].length;\n\t if (amount < 0) {\n\t amount = _this.pattern[0].length + amount;\n\t }\n\t for (var i = 0; i < _this.rows; i++) {\n\t var cut = _this.pattern[i].splice(_this.pattern[i].length - amount, amount);\n\t _this.pattern[i] = cut.concat(_this.pattern[i]);\n\t }\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t row: function (row, amount) {\n\t if (!amount && amount !== 0) {\n\t amount = 1;\n\t }\n\t amount %= _this.pattern[0].length;\n\t if (amount < 0) {\n\t amount = _this.pattern[0].length + amount;\n\t }\n\t var cut = _this.pattern[row].splice(_this.pattern[row].length - amount, amount);\n\t _this.pattern[row] = cut.concat(_this.pattern[row]);\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t column: function (column, amount) {\n\t if (!amount && amount !== 0) {\n\t amount = 1;\n\t }\n\t amount %= _this.pattern.length;\n\t if (amount < 0) {\n\t amount = _this.pattern.length + amount;\n\t }\n\t var proxy = [];\n\t _this.pattern.forEach(function (row) {\n\t proxy.push(row[column]);\n\t });\n\t var cut = proxy.splice(proxy.length - amount, amount);\n\t proxy = cut.concat(proxy);\n\t _this.pattern.forEach(function (row, i) {\n\t row[column] = proxy[i];\n\t });\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t }\n\t };\n\t\n\t // the idea behind populate is to be able to set a whole row or column to 0 or 1\n\t // IF the value is a float, such as 0.7, then it would become a probability\n\t // so populate(0.7) would give each cell a 70% chance of being 1\n\t this.populate = {\n\t all: function (odds) {\n\t var oddsSequence = new Sequence(odds);\n\t _this.iterate(function (r, c) {\n\t _this.pattern[r][c] = math.coin(oddsSequence.next());\n\t });\n\t // This could be used so that each row has same odds pattern, even if row length is not divisibly by sequence length.\n\t //,() => {\n\t // odds.pos = -1;\n\t // }\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t row: function () {\n\t var row = arguments[0] === undefined ? 0 : arguments[0];\n\t var odds = arguments[1] === undefined ? 1 : arguments[1];\n\t\n\t var oddsSequence = new Sequence(odds);\n\t _this.pattern[row].forEach(function (cell, i) {\n\t _this.pattern[row][i] = math.coin(oddsSequence.next());\n\t });\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t },\n\t column: function () {\n\t var column = arguments[0] === undefined ? 0 : arguments[0];\n\t var odds = arguments[1] === undefined ? 1 : arguments[1];\n\t\n\t var oddsSequence = new Sequence(odds);\n\t _this.pattern.forEach(function (row, i) {\n\t _this.pattern[i][column] = math.coin(oddsSequence.next());\n\t });\n\t if (_this.ui) {\n\t _this.ui.update();\n\t }\n\t }\n\t };\n\t\n\t // essentiall populate(0) so i'm not sure if this is necessary but is nice\n\t this.erase = {\n\t all: function () {\n\t _this.set.all(0);\n\t },\n\t row: function (row) {\n\t _this.set.row(row, 0);\n\t },\n\t column: function (column) {\n\t _this.set.column(column, 0);\n\t }\n\t };\n\t\n\t // end constructor\n\t }\n\t\n\t _createClass(Matrix, {\n\t create: {\n\t value: function create(rows, columns) {\n\t var _this = this;\n\t\n\t this.pattern = [];\n\t for (var row = 0; row < rows; row++) {\n\t var arr = new Array(columns);\n\t this.pattern.push(arr);\n\t }\n\t this.iterate(function (r, c) {\n\t _this.pattern[r][c] = false;\n\t });\n\t }\n\t },\n\t iterate: {\n\t value: function iterate(f, f2) {\n\t var i = 0;\n\t for (var row = 0; row < this.rows; row++) {\n\t if (f2) {\n\t f2(row);\n\t }\n\t for (var column = 0; column < this.columns; column++) {\n\t f(row, column, i);\n\t i++;\n\t }\n\t }\n\t }\n\t },\n\t formatAsText: {\n\t value: function formatAsText() {\n\t var _this = this;\n\t\n\t var patternString = \"\";\n\t this.iterate(function (r, c) {\n\t patternString += (_this.pattern[r][c] ? 1 : 0) + \" \";\n\t }, function () {\n\t patternString += \"\\n\";\n\t });\n\t return patternString;\n\t }\n\t },\n\t log: {\n\t value: function log() {\n\t console.log(this.formatAsText());\n\t }\n\t },\n\t update: {\n\t value: function update(pattern) {\n\t this.pattern = pattern || this.pattern;\n\t }\n\t },\n\t length: {\n\t get: function () {\n\t return this.rows * this.columns;\n\t }\n\t },\n\t locate: {\n\t value: function locate(index) {\n\t // returns row and column of cell by index\n\t return {\n\t row: ~ ~(index / this.columns),\n\t column: index % this.columns\n\t };\n\t }\n\t },\n\t indexOf: {\n\t value: function indexOf(row, column) {\n\t return column + row * this.columns;\n\t // returns index of cell by row and column\n\t }\n\t },\n\t row: {\n\t value: (function (_row) {\n\t var _rowWrapper = function row(_x) {\n\t return _row.apply(this, arguments);\n\t };\n\t\n\t _rowWrapper.toString = function () {\n\t return _row.toString();\n\t };\n\t\n\t return _rowWrapper;\n\t })(function (row) {\n\t var data = [];\n\t for (var i = 0; i < this.columns; i++) {\n\t data.push(this.pattern[row] ? 1 : 0);\n\t }\n\t return data;\n\t })\n\t },\n\t column: {\n\t value: (function (_column) {\n\t var _columnWrapper = function column(_x2) {\n\t return _column.apply(this, arguments);\n\t };\n\t\n\t _columnWrapper.toString = function () {\n\t return _column.toString();\n\t };\n\t\n\t return _columnWrapper;\n\t })(function (column) {\n\t var data = [];\n\t for (var i = 0; i < this.rows; i++) {\n\t data.push(this.pattern[i][column] ? 1 : 0);\n\t }\n\t return data;\n\t })\n\t },\n\t rows: {\n\t get: function () {\n\t return this.pattern.length;\n\t },\n\t set: function (v) {\n\t var _this = this;\n\t\n\t var previous = this.pattern.slice(0);\n\t this.create(v, this.columns);\n\t this.iterate(function (r, c) {\n\t if (previous[r] && previous[r][c]) {\n\t _this.pattern[r][c] = previous[r][c];\n\t }\n\t });\n\t }\n\t },\n\t columns: {\n\t get: function () {\n\t return this.pattern[0].length;\n\t },\n\t set: function (v) {\n\t var _this = this;\n\t\n\t var previous = this.pattern.slice(0);\n\t this.create(this.rows, v);\n\t this.iterate(function (r, c) {\n\t if (previous[r] && previous[r][c]) {\n\t _this.pattern[r][c] = previous[r][c];\n\t }\n\t });\n\t }\n\t }\n\t });\n\t\n\t return Matrix;\n\t})();\n\t\n\tmodule.exports = Matrix;\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar Drunk = _interopRequire(__webpack_require__(27));\n\t\n\tvar Sequence = (function () {\n\t function Sequence() {\n\t var sequence = arguments[0] === undefined ? [0, 10, 20, 30] : arguments[0];\n\t var mode = arguments[1] === undefined ? \"up\" : arguments[1];\n\t var position = arguments[2] === undefined ? false : arguments[2];\n\t\n\t _classCallCheck(this, Sequence);\n\t\n\t this.values = sequence;\n\t if (!Array.isArray(this.values)) {\n\t this.values = [this.values];\n\t }\n\t this._mode = mode;\n\t this.position = position;\n\t\n\t this.drunkWalk = new Drunk(0, this.values.length - 1);\n\t\n\t this.startValues = {\n\t up: 0,\n\t down: this.values.length - 1,\n\t drunk: ~ ~(this.values.length / 2),\n\t random: math.ri(this.values.length)\n\t };\n\t\n\t if (this.position !== false) {\n\t this.next = this[this._mode];\n\t } else {\n\t this.next = this.first;\n\t }\n\t }\n\t\n\t _createClass(Sequence, {\n\t mode: {\n\t get: function () {\n\t return this._mode;\n\t },\n\t set: function (mode) {\n\t if (!(mode === \"up\" || mode === \"down\" || mode === \"random\" || mode === \"drunk\")) {\n\t console.error(\"The only modes currently allowed are: up, down, random, drunk\");\n\t return;\n\t }\n\t this._mode = mode;\n\t if (this.position) {\n\t this.next = this[this._mode];\n\t }\n\t }\n\t },\n\t value: {\n\t get: function () {\n\t return this.values[this.position];\n\t },\n\t set: function (v) {\n\t this.position = this.values.indexOf(v);\n\t }\n\t },\n\t first: {\n\t value: function first() {\n\t if (this.position !== false) {\n\t this.next = this[this._mode];\n\t return this.next();\n\t }\n\t this.position = this.startValues[this._mode];\n\t this.next = this[this._mode];\n\t return this.value;\n\t }\n\t },\n\t up: {\n\t value: function up() {\n\t this.position++;\n\t this.position %= this.values.length;\n\t return this.value;\n\t }\n\t },\n\t down: {\n\t value: function down() {\n\t this.position--;\n\t if (this.position < 0) {\n\t this.position = (this.position + this.values.length) % this.values.length;\n\t }\n\t return this.value;\n\t }\n\t },\n\t random: {\n\t value: function random() {\n\t this.position = math.ri(0, this.values.length);\n\t return this.value;\n\t }\n\t },\n\t drunk: {\n\t value: function drunk() {\n\t this.drunkWalk.max = this.values.length;\n\t this.drunkWalk.value = this.position;\n\t this.position = this.drunkWalk.next();\n\t return this.value;\n\t }\n\t\n\t /* future methods\r\n\t .group(start,stop) -- outputs a group of n items from the list, with wrapping\r\n\t .loop(start,stop) -- confines sequencing to a subset of the values\r\n\t (could even have a distinction between .originalValues and the array of values being used)\r\n\t */\n\t\n\t }\n\t });\n\t\n\t return Sequence;\n\t})();\n\t\n\tmodule.exports = Sequence;\n\n/***/ }),\n/* 27 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar Drunk = (function () {\n\t function Drunk() {\n\t var min = arguments[0] === undefined ? 0 : arguments[0];\n\t var max = arguments[1] === undefined ? 9 : arguments[1];\n\t var value = arguments[2] === undefined ? 0 : arguments[2];\n\t var increment = arguments[3] === undefined ? 1 : arguments[3];\n\t var loop = arguments[4] === undefined ? false : arguments[4];\n\t\n\t _classCallCheck(this, Drunk);\n\t\n\t this.min = min;\n\t this.max = max;\n\t this.value = value;\n\t this.increment = increment;\n\t this.loop = loop;\n\t }\n\t\n\t _createClass(Drunk, {\n\t next: {\n\t value: function next() {\n\t this.value += math.pick(-1 * this.increment, this.increment);\n\t if (this.value > this.max) {\n\t if (this.loop) {\n\t this.value = this.min;\n\t } else {\n\t this.value = this.max - this.increment;\n\t }\n\t }\n\t\n\t if (this.value < this.min) {\n\t if (this.loop) {\n\t this.value = this.max;\n\t } else {\n\t this.value = this.min + this.increment;\n\t }\n\t }\n\t return this.value;\n\t }\n\t }\n\t });\n\t\n\t return Drunk;\n\t})();\n\t\n\tmodule.exports = Drunk;\n\n/***/ }),\n/* 28 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar Drunk = _interopRequire(__webpack_require__(27));\n\t\n\tvar Counter = (function () {\n\t function Counter() {\n\t var min = arguments[0] === undefined ? 0 : arguments[0];\n\t var max = arguments[1] === undefined ? 10 : arguments[1];\n\t var mode = arguments[2] === undefined ? \"up\" : arguments[2];\n\t var value = arguments[3] === undefined ? false : arguments[3];\n\t\n\t _classCallCheck(this, Counter);\n\t\n\t this.min = min;\n\t this.max = max;\n\t this.value = value;\n\t this.mode = mode;\n\t this.drunkWalk = new Drunk(this.min, this.max);\n\t if (this.value !== false) {\n\t this.next = this[this._mode];\n\t } else {\n\t this.next = this.first;\n\t }\n\t }\n\t\n\t _createClass(Counter, {\n\t mode: {\n\t set: function (mode) {\n\t if (!(mode === \"up\" || mode === \"down\" || mode === \"random\" || mode === \"drunk\")) {\n\t console.error(\"The only modes currently allowed are: up, down, random, drunk\");\n\t return;\n\t }\n\t this._mode = mode;\n\t if (this.value) {\n\t this.next = this[this._mode];\n\t }\n\t },\n\t get: function () {\n\t return this._mode;\n\t }\n\t },\n\t first: {\n\t value: function first() {\n\t if (this.value !== false) {\n\t this.next = this[this._mode];\n\t return this.next();\n\t }\n\t this.startValues = {\n\t up: this.min,\n\t down: this.max,\n\t drunk: ~ ~math.average(this.min, this.max),\n\t random: math.ri(this.min, this.max)\n\t };\n\t this.value = this.startValues[this._mode];\n\t this.next = this[this._mode];\n\t return this.value;\n\t }\n\t },\n\t up: {\n\t value: function up() {\n\t this.value++;\n\t if (this.value >= this.max) {\n\t this.value = this.min;\n\t }\n\t return this.value;\n\t }\n\t },\n\t down: {\n\t value: function down() {\n\t this.value--;\n\t if (this.value < this.min) {\n\t this.value = this.max;\n\t }\n\t return this.value;\n\t }\n\t },\n\t random: {\n\t value: function random() {\n\t this.value = math.ri(this.min, this.max);\n\t return this.value;\n\t }\n\t },\n\t drunk: {\n\t value: function drunk() {\n\t this.drunkWalk.min = this.min;\n\t this.drunkWalk.max = this.max;\n\t this.drunkWalk.value = this.value;\n\t this.value = this.drunkWalk.next();\n\t return this.value;\n\t }\n\t }\n\t });\n\t\n\t return Counter;\n\t})();\n\t\n\tmodule.exports = Counter;\n\n/***/ }),\n/* 29 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar math = __webpack_require__(5);\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\t\n\tvar Interaction = _interopRequireWildcard(__webpack_require__(12));\n\t\n\t/**\n\t* Pan2D\n\t*\n\t* @description Interface for moving a sound around an array of speakers. Speaker locations can be customized. The interface calculates the closeness of the sound source to each speaker and returns that distance as a numeric value.\n\t*\n\t* @demo <span nexus-ui=\"pan2D\"></span>\n\t*\n\t* @example\n\t* var pan2d = new Nexus.Pan2d('#target')\n\t*\n\t* @example\n\t* var pan2d = new Nexus.Pan2D('#target',{\n\t* 'size': [200,200],\n\t* 'range': 0.5, // detection radius of each speaker\n\t* 'mode': 'absolute', // 'absolute' or 'relative' sound movement\n\t* 'speakers': [ // the speaker [x,y] positions\n\t* [0.5,0.2],\n\t* [0.75,0.25],\n\t* [0.8,0.5],\n\t* [0.75,0.75],\n\t* [0.5,0.8],\n\t* [0.25,0.75]\n\t* [0.2,0.5],\n\t* [0.25,0.25]\n\t* ]\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the \"source\" node's position changes. <br>\n\t* The event data is an array of the amplitudes (0-1), representing the level of each speaker (as calculated by its distance to the audio source).\n\t*\n\t* @outputexample\n\t* pan2d.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\tvar Pan2D = (function (_Interface) {\n\t function Pan2D() {\n\t _classCallCheck(this, Pan2D);\n\t\n\t var options = [\"range\"];\n\t\n\t var defaults = {\n\t size: [200, 200],\n\t range: 0.5,\n\t mode: \"absolute\",\n\t speakers: [[0.5, 0.2], [0.75, 0.25], [0.8, 0.5], [0.75, 0.75], [0.5, 0.8], [0.25, 0.75], [0.2, 0.5], [0.25, 0.25]]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Pan2D.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.value = {\n\t x: new Step(0, 1, 0, 0.5),\n\t y: new Step(0, 1, 0, 0.5)\n\t };\n\t\n\t /**\n\t Absolute or relative mouse interaction. In \"absolute\" mode, the source node will jump to your mouse position on mouse click. In \"relative\" mode, it does not.\n\t */\n\t this.mode = this.settings.mode;\n\t\n\t this.position = {\n\t x: new Interaction.Handle(this.mode, \"horizontal\", [0, this.width], [this.height, 0]),\n\t y: new Interaction.Handle(this.mode, \"vertical\", [0, this.width], [this.height, 0])\n\t };\n\t this.position.x.value = this.value.x.normalized;\n\t this.position.y.value = this.value.y.normalized;\n\t\n\t /**\n\t An array of speaker locations. Update this with .moveSpeaker() or .moveAllSpeakers()\n\t */\n\t this.speakers = this.settings.speakers;\n\t\n\t /**\n\t Rewrite: The maximum distance from a speaker that the source node can be for it to be heard from that speaker. A low range (0.1) will result in speakers only playing when the sound is very close it. Default is 0.5 (half of the interface).\n\t */\n\t this.range = this.settings.range;\n\t\n\t /**\n\t The current levels for each speaker. This is calculated when a source node or speaker node is moved through interaction or programatically.\n\t */\n\t this.levels = [];\n\t\n\t this.init();\n\t\n\t this.calculateLevels();\n\t this.render();\n\t }\n\t\n\t _inherits(Pan2D, _Interface);\n\t\n\t _createClass(Pan2D, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.knob = svg.create(\"circle\");\n\t\n\t this.element.appendChild(this.knob);\n\t\n\t // add speakers\n\t this.speakerElements = [];\n\t\n\t for (var i = 0; i < this.speakers.length; i++) {\n\t var speakerElement = svg.create(\"circle\");\n\t\n\t this.element.appendChild(speakerElement);\n\t\n\t this.speakerElements.push(speakerElement);\n\t }\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t this._minDimension = Math.min(this.width, this.height);\n\t\n\t this.knobRadius = {\n\t off: ~ ~(this._minDimension / 100) * 3 + 5 };\n\t this.knobRadius.on = this.knobRadius.off * 2;\n\t\n\t this.knob.setAttribute(\"cx\", this.width / 2);\n\t this.knob.setAttribute(\"cy\", this.height / 2);\n\t this.knob.setAttribute(\"r\", this.knobRadius.off);\n\t\n\t for (var i = 0; i < this.speakers.length; i++) {\n\t var speakerElement = this.speakerElements[i];\n\t var speaker = this.speakers[i];\n\t speakerElement.setAttribute(\"cx\", speaker[0] * this.width);\n\t speakerElement.setAttribute(\"cy\", speaker[1] * this.height);\n\t speakerElement.setAttribute(\"r\", this._minDimension / 20 + 5);\n\t speakerElement.setAttribute(\"fill-opacity\", \"0\");\n\t }\n\t\n\t this.position.x.resize([0, this.width], [this.height, 0]);\n\t this.position.y.resize([0, this.width], [this.height, 0]);\n\t\n\t // next, need to\n\t // resize positions\n\t // calculate speaker distances\n\t this.calculateLevels();\n\t this.render();\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.knob.setAttribute(\"fill\", this.colors.mediumLight);\n\t\n\t for (var i = 0; i < this.speakers.length; i++) {\n\t var speakerElement = this.speakerElements[i];\n\t speakerElement.setAttribute(\"fill\", this.colors.accent);\n\t speakerElement.setAttribute(\"stroke\", this.colors.accent);\n\t }\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t this.knobCoordinates = {\n\t x: this.value.x.normalized * this.width,\n\t y: this.height - this.value.y.normalized * this.height\n\t };\n\t\n\t this.knob.setAttribute(\"cx\", this.knobCoordinates.x);\n\t this.knob.setAttribute(\"cy\", this.knobCoordinates.y);\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.position.x.anchor = this.mouse;\n\t this.position.y.anchor = this.mouse;\n\t this.move();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.clicked) {\n\t this.position.x.update(this.mouse);\n\t this.position.y.update(this.mouse);\n\t // position.x and position.y are normalized\n\t // so are the levels\n\t // likely don't need this.value at all -- only used for drawing\n\t // not going to be a 'step' or 'min' and 'max' in this one.\n\t this.calculateLevels();\n\t this.emit(\"change\", this.levels);\n\t this.render();\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t this.render();\n\t }\n\t },\n\t normalized: {\n\t get: function () {\n\t return {\n\t x: this.value.x.normalized,\n\t y: this.value.y.normalized\n\t };\n\t }\n\t },\n\t calculateLevels: {\n\t value: function calculateLevels() {\n\t var _this = this;\n\t\n\t this.value.x.updateNormal(this.position.x.value);\n\t this.value.y.updateNormal(this.position.y.value);\n\t this.levels = [];\n\t this.speakers.forEach(function (s, i) {\n\t var distance = math.distance(s[0] * _this.width, s[1] * _this.height, _this.position.x.value * _this.width, (1 - _this.position.y.value) * _this.height);\n\t var level = math.clip(1 - distance / (_this.range * _this.width), 0, 1);\n\t _this.levels.push(level);\n\t _this.speakerElements[i].setAttribute(\"fill-opacity\", level);\n\t });\n\t }\n\t },\n\t moveSource: {\n\t\n\t /**\n\t Move the audio source node and trigger the output event.\n\t @param x {number} New x location, normalized 0-1\n\t @param y {number} New y location, normalized 0-1\n\t */\n\t\n\t value: function moveSource(x, y) {\n\t var location = {\n\t x: x * this.width,\n\t y: y * this.height\n\t };\n\t this.position.x.update(location);\n\t this.position.y.update(location);\n\t this.calculateLevels();\n\t this.emit(\"change\", this.levels);\n\t this.render();\n\t }\n\t },\n\t moveSpeaker: {\n\t\n\t /**\n\t Move a speaker node and trigger the output event.\n\t @param index {number} Index of the speaker to move\n\t @param x {number} New x location, normalized 0-1\n\t @param y {number} New y location, normalized 0-1\n\t */\n\t\n\t value: function moveSpeaker(index, x, y) {\n\t\n\t this.speakers[index] = [x, y];\n\t this.speakerElements[index].setAttribute(\"cx\", x * this.width);\n\t this.speakerElements[index].setAttribute(\"cy\", y * this.height);\n\t this.calculateLevels();\n\t this.emit(\"change\", this.levels);\n\t this.render();\n\t }\n\t\n\t /**\n\t Set all speaker locations\n\t @param locations {Array} Array of speaker locations. Each item in the array should be an array of normalized x and y coordinates.\n\t setSpeakers(locations) {\n\t }\n\t */\n\t\n\t }\n\t });\n\t\n\t return Pan2D;\n\t})(Interface);\n\t\n\tmodule.exports = Pan2D;\n\n/***/ }),\n/* 30 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = __webpack_require__(5);\n\tvar svg = __webpack_require__(4);\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\t* Tilt\n\t*\n\t* @description Device tilt sensor with 2 or 3 axes (depending on your device and browser).\n\t*\n\t* @demo <span nexus-ui='tilt'></span>\n\t*\n\t* @example\n\t* var tilt = new Nexus.Tilt('#target')\n\t*\n\t* @output\n\t* change\n\t* Fires at a regular interval, as long as this interface is active (see the interface's <i>.active</i> property)<br>\n\t* The event data is an <i>object</i> containing x (number) and y (number) properties which represent the current tilt state of the device.\n\t*\n\t* @outputexample\n\t* tilt.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Tilt = (function (_Interface) {\n\t function Tilt() {\n\t _classCallCheck(this, Tilt);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [80, 80]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Tilt.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._active = true;\n\t\n\t this.init();\n\t\n\t // add event listener for device orientation\n\t\n\t this.boundUpdate = this.update.bind(this);\n\t //\tthis.boundMozTilt = this.mozTilt.bind(this)\n\t\n\t if (window.DeviceOrientationEvent) {\n\t this.orientationListener = window.addEventListener(\"deviceorientation\", this.boundUpdate, false);\n\t } else {\n\t this._active = false;\n\t this.colorInterface();\n\t }\n\t\n\t /*else if (window.OrientationEvent) {\n\t //\t \twindow.addEventListener('MozOrientation', this.boundMozTilt, false);\n\t } else {\n\t console.log('Not supported on your device or browser.');\n\t } */\n\t }\n\t\n\t _inherits(Tilt, _Interface);\n\t\n\t _createClass(Tilt, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.title = svg.create(\"text\");\n\t this.circleX = svg.create(\"circle\");\n\t this.circleY = svg.create(\"circle\");\n\t this.circleZ = svg.create(\"circle\");\n\t\n\t this.barX = svg.create(\"path\");\n\t this.barY = svg.create(\"path\");\n\t this.barZ = svg.create(\"path\");\n\t\n\t this.barX2 = svg.create(\"path\");\n\t this.barY2 = svg.create(\"path\");\n\t this.barZ2 = svg.create(\"path\");\n\t\n\t this.barX.setAttribute(\"opacity\", \"0.8\");\n\t this.barY.setAttribute(\"opacity\", \"0.8\");\n\t this.barZ.setAttribute(\"opacity\", \"0.8\");\n\t this.barX2.setAttribute(\"opacity\", \"0.8\");\n\t this.barY2.setAttribute(\"opacity\", \"0.8\");\n\t this.barZ2.setAttribute(\"opacity\", \"0.8\");\n\t\n\t this.circleX.setAttribute(\"cx\", this.width * 3 / 12);\n\t this.circleX.setAttribute(\"cy\", this.height * 3 / 4);\n\t this.circleX.setAttribute(\"r\", this.height / 10);\n\t this.circleX.setAttribute(\"opacity\", \"0.4\");\n\t\n\t this.circleY.setAttribute(\"cx\", this.width * 6 / 12);\n\t this.circleY.setAttribute(\"cy\", this.height * 3 / 4);\n\t this.circleY.setAttribute(\"r\", this.height / 10);\n\t this.circleY.setAttribute(\"opacity\", \"0.4\");\n\t\n\t this.circleZ.setAttribute(\"cx\", this.width * 9 / 12);\n\t this.circleZ.setAttribute(\"cy\", this.height * 3 / 4);\n\t this.circleZ.setAttribute(\"r\", this.height / 10);\n\t this.circleZ.setAttribute(\"opacity\", \"0.4\");\n\t\n\t this.barX.setAttribute(\"stroke-width\", Math.round(this.height / 30));\n\t this.barY.setAttribute(\"stroke-width\", Math.round(this.height / 30));\n\t this.barZ.setAttribute(\"stroke-width\", Math.round(this.height / 30));\n\t\n\t this.barX.setAttribute(\"fill\", \"none\");\n\t this.barY.setAttribute(\"fill\", \"none\");\n\t this.barZ.setAttribute(\"fill\", \"none\");\n\t\n\t this.barX2.setAttribute(\"stroke-width\", Math.round(this.height / 30));\n\t this.barY2.setAttribute(\"stroke-width\", Math.round(this.height / 30));\n\t this.barZ2.setAttribute(\"stroke-width\", Math.round(this.height / 30));\n\t\n\t this.barX2.setAttribute(\"fill\", \"none\");\n\t this.barY2.setAttribute(\"fill\", \"none\");\n\t this.barZ2.setAttribute(\"fill\", \"none\");\n\t\n\t this.title.setAttribute(\"x\", this.width / 2);\n\t this.title.setAttribute(\"y\", this.height / 3 + 7);\n\t this.title.setAttribute(\"font-size\", \"15px\");\n\t this.title.setAttribute(\"font-weight\", \"bold\");\n\t this.title.setAttribute(\"letter-spacing\", \"2px\");\n\t this.title.setAttribute(\"opacity\", \"0.7\");\n\t this.title.setAttribute(\"text-anchor\", \"middle\");\n\t this.title.textContent = \"TILT\";\n\t\n\t this.element.appendChild(this.circleX);\n\t this.element.appendChild(this.circleY);\n\t this.element.appendChild(this.circleZ);\n\t\n\t this.element.appendChild(this.barX);\n\t this.element.appendChild(this.barY);\n\t this.element.appendChild(this.barZ);\n\t\n\t this.element.appendChild(this.barX2);\n\t this.element.appendChild(this.barY2);\n\t this.element.appendChild(this.barZ2);\n\t\n\t this.element.appendChild(this.title);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t\n\t if (this._active) {\n\t this.element.style.backgroundColor = this.colors.accent;\n\t this.circleX.setAttribute(\"fill\", this.colors.light);\n\t this.circleY.setAttribute(\"fill\", this.colors.light);\n\t this.circleZ.setAttribute(\"fill\", this.colors.light);\n\t this.circleX.setAttribute(\"stroke\", this.colors.light);\n\t this.circleY.setAttribute(\"stroke\", this.colors.light);\n\t this.circleZ.setAttribute(\"stroke\", this.colors.light);\n\t this.barX.setAttribute(\"stroke\", this.colors.light);\n\t this.barY.setAttribute(\"stroke\", this.colors.light);\n\t this.barZ.setAttribute(\"stroke\", this.colors.light);\n\t this.barX2.setAttribute(\"stroke\", this.colors.light);\n\t this.barY2.setAttribute(\"stroke\", this.colors.light);\n\t this.barZ2.setAttribute(\"stroke\", this.colors.light);\n\t this.title.setAttribute(\"fill\", this.colors.light);\n\t } else {\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.circleX.setAttribute(\"fill\", this.colors.mediumLight);\n\t this.circleY.setAttribute(\"fill\", this.colors.mediumLight);\n\t this.circleZ.setAttribute(\"fill\", this.colors.mediumLight);\n\t this.circleX.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.circleY.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.circleZ.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.barX.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.barY.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.barZ.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.barX2.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.barY2.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.barZ2.setAttribute(\"stroke\", this.colors.mediumLight);\n\t this.title.setAttribute(\"fill\", this.colors.mediumLight);\n\t }\n\t }\n\t },\n\t update: {\n\t value: function update(v) {\n\t if (this._active) {\n\t\n\t var y = v.beta;\n\t var x = v.gamma;\n\t var z = v.alpha;\n\t\n\t // take the original -90 to 90 scale and normalize it 0-1\n\t x = math.scale(x, -90, 90, 0, 1);\n\t y = math.scale(y, -90, 90, 0, 1);\n\t z = math.scale(z, 0, 360, 0, 1);\n\t\n\t var handlePoints = {\n\t start: Math.PI * 1.5,\n\t end: math.clip(math.scale(x, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5)\n\t };\n\t var handle2Points = {\n\t start: Math.PI * 2.5,\n\t end: math.clip(math.scale(x, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5)\n\t };\n\t\n\t var handlePath = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value, handlePoints.start, handlePoints.end);\n\t var handle2Path = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value, handle2Points.start, handle2Points.end);\n\t\n\t this.barX.setAttribute(\"d\", handlePath);\n\t this.barX2.setAttribute(\"d\", handle2Path);\n\t\n\t handlePoints = {\n\t start: Math.PI * 1.5,\n\t end: math.clip(math.scale(y, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5)\n\t };\n\t handle2Points = {\n\t start: Math.PI * 2.5,\n\t end: math.clip(math.scale(y, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5)\n\t };\n\t\n\t handlePath = svg.arc(this.circleY.cx.baseVal.value, this.circleY.cy.baseVal.value, this.circleY.r.baseVal.value, handlePoints.start, handlePoints.end);\n\t handle2Path = svg.arc(this.circleY.cx.baseVal.value, this.circleY.cy.baseVal.value, this.circleY.r.baseVal.value, handle2Points.start, handle2Points.end);\n\t\n\t this.barY.setAttribute(\"d\", handlePath);\n\t this.barY2.setAttribute(\"d\", handle2Path);\n\t\n\t handlePoints = {\n\t start: Math.PI * 1.5,\n\t end: math.clip(math.scale(z, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5)\n\t };\n\t handle2Points = {\n\t start: Math.PI * 2.5,\n\t end: math.clip(math.scale(z, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5)\n\t };\n\t\n\t handlePath = svg.arc(this.circleZ.cx.baseVal.value, this.circleZ.cy.baseVal.value, this.circleZ.r.baseVal.value, handlePoints.start, handlePoints.end);\n\t handle2Path = svg.arc(this.circleZ.cx.baseVal.value, this.circleZ.cy.baseVal.value, this.circleZ.r.baseVal.value, handle2Points.start, handle2Points.end);\n\t\n\t this.barZ.setAttribute(\"d\", handlePath);\n\t this.barZ2.setAttribute(\"d\", handle2Path);\n\t\n\t /*\n\t let pointsX = {\n\t start: 0,\n\t end: math.scale( x, 0, 1, 0, Math.PI*2 )\n\t };\n\t // console.log(this.circleX.cx.baseVal.value);\n\t let pathX = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value*2, pointsX.start, pointsX.end);\n\t this.barX.setAttribute('d',pathX); */\n\t\n\t //this.textH.textContent = math.prune(x,2);\n\t //this.textV.textContent = math.prune(y,2);\n\t //\n\t // this.circleX.setAttribute('opacity',x);\n\t // this.circleY.setAttribute('opacity',y);\n\t // this.circleZ.setAttribute('opacity',z);\n\t\n\t this.emit(\"change\", {\n\t x: x,\n\t y: y,\n\t z: z\n\t });\n\t }\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t if (window.DeviceOrientationEvent) {\n\t this.active = !this.active;\n\t }\n\t }\n\t },\n\t active: {\n\t\n\t /**\n\t Whether the interface is on (emitting values) or off (paused & not emitting values). Setting this property will update it.\n\t @type {boolean}\n\t */\n\t\n\t get: function () {\n\t return this._active;\n\t },\n\t set: function (on) {\n\t this._active = on;\n\t this.colorInterface();\n\t }\n\t },\n\t customDestroy: {\n\t value: function customDestroy() {\n\t window.removeEventListener(\"deviceorientation\", this.boundUpdate, false);\n\t }\n\t }\n\t });\n\t\n\t return Tilt;\n\t})(Interface);\n\t\n\tmodule.exports = Tilt;\n\n/***/ }),\n/* 31 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar dom = __webpack_require__(7);\n\tvar math = __webpack_require__(5);\n\tvar Interface = __webpack_require__(6);\n\tvar SliderTemplate = __webpack_require__(32);\n\tvar touch = __webpack_require__(9);\n\t\n\tvar SingleSlider = (function (_SliderTemplate) {\n\t function SingleSlider() {\n\t var _this = this;\n\t\n\t _classCallCheck(this, SingleSlider);\n\t\n\t var options = [\"scale\", \"value\"];\n\t\n\t var defaults = {\n\t size: [120, 20],\n\t orientation: \"vertical\",\n\t mode: \"absolute\",\n\t scale: [0, 1],\n\t step: 0,\n\t value: 0,\n\t hasKnob: true\n\t };\n\t\n\t _get(Object.getPrototypeOf(SingleSlider.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t /* events */\n\t\n\t if (!touch.exists) {\n\t\n\t this.click = function () {\n\t _this.multislider.interacting = true;\n\t _this.multislider.interpolation = {\n\t index: _this.index,\n\t value: _this.value\n\t };\n\t _this.down();\n\t _this.multislider.values[_this.index] = _this.value;\n\t };\n\t this.element.addEventListener(\"mouseover\", function (e) {\n\t if (_this.multislider.interacting) {\n\t if (!_this.offset) {\n\t _this.offset = dom.findPosition(_this.element);\n\t }\n\t _this.mouse = dom.locateMouse(e, _this.offset);\n\t _this.down();\n\t _this.multislider.values[_this.index] = _this.value;\n\t if (_this.multislider.interpolation) {\n\t var distance = Math.abs(_this.multislider.interpolation.index - _this.index);\n\t if (distance > 1) {\n\t var low = Math.min(_this.multislider.interpolation.index, _this.index);\n\t var high = Math.max(_this.multislider.interpolation.index, _this.index);\n\t var lowValue = _this.multislider.sliders[low].value;\n\t var highValue = _this.multislider.sliders[high].value;\n\t for (var i = low; i < high; i++) {\n\t _this.multislider.sliders[i].value = math.interp((i - low) / distance, lowValue, highValue);\n\t var smoothedValue = _this.multislider.sliders[i].value;\n\t _this.multislider.values[i] = smoothedValue;\n\t _this.multislider.update(i, smoothedValue);\n\t }\n\t }\n\t }\n\t\n\t _this.multislider.interpolation = {\n\t index: _this.index,\n\t value: _this.value\n\t };\n\t }\n\t });\n\t\n\t this.move = function () {};\n\t this.element.addEventListener(\"mousemove\", function (e) {\n\t if (_this.multislider.interacting) {\n\t if (!_this.offset) {\n\t _this.offset = dom.findPosition(_this.element);\n\t }\n\t _this.mouse = dom.locateMouse(e, _this.offset);\n\t _this.slide();\n\t _this.multislider.values[_this.index] = _this.value;\n\t }\n\t });\n\t\n\t this.release = function () {\n\t _this.multislider.interacting = false;\n\t _this.multislider.interpolation = false;\n\t };\n\t this.element.addEventListener(\"mouseup\", function () {\n\t if (_this.multislider.interacting) {\n\t _this.up();\n\t _this.multislider.interpolation = false;\n\t _this.multislider.values[_this.index] = _this.value;\n\t }\n\t });\n\t this.element.addEventListener(\"mouseout\", function () {\n\t if (_this.multislider.interacting) {\n\t _this.up();\n\t _this.multislider.values[_this.index] = _this.value;\n\t }\n\t });\n\t }\n\t\n\t this.customStyle();\n\t }\n\t\n\t _inherits(SingleSlider, _SliderTemplate);\n\t\n\t _createClass(SingleSlider, {\n\t customStyle: {\n\t value: function customStyle() {\n\t\n\t /* style changes */\n\t\n\t this.bar.setAttribute(\"x\", 0);\n\t this.bar.setAttribute(\"transform\", \"translate(0,0)\");\n\t this.bar.setAttribute(\"rx\", 0); // corner radius\n\t this.bar.setAttribute(\"ry\", 0);\n\t this.bar.setAttribute(\"width\", this.width);\n\t this.bar.setAttribute(\"height\", this.height);\n\t\n\t this.fillbar.setAttribute(\"x\", 0);\n\t this.fillbar.setAttribute(\"transform\", \"translate(0,0)\");\n\t this.fillbar.setAttribute(\"rx\", 0); // corner radius\n\t this.fillbar.setAttribute(\"ry\", 0);\n\t this.fillbar.setAttribute(\"width\", this.width);\n\t this.fillbar.setAttribute(\"height\", this.height);\n\t }\n\t }\n\t });\n\t\n\t return SingleSlider;\n\t})(SliderTemplate);\n\t\n\t/**\n\t* Multislider\n\t*\n\t* @description Multislider\n\t*\n\t* @demo <span nexus-ui=\"multislider\"></span>\n\t*\n\t* @example\n\t* var multislider = new Nexus.Multislider('#target')\n\t*\n\t* @example\n\t* var multislider = new Nexus.Multislider('#target',{\n\t* 'size': [200,100],\n\t* 'numberOfSliders': 5,\n\t* 'min': 0,\n\t* 'max': 1,\n\t* 'step': 0,\n\t* 'values': [0.7,0.7,0.7,0.7,0.7]\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data an object containing <i>index</i> and <i>value</i> properties\n\t*\n\t* @outputexample\n\t* multislider.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\t/*\n\tProperties\n\t.values\n\t\n\t*/\n\t\n\tvar Multislider = (function (_Interface) {\n\t function Multislider() {\n\t _classCallCheck(this, Multislider);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [200, 100],\n\t numberOfSliders: 5,\n\t min: 0,\n\t max: 1,\n\t step: 0,\n\t values: [0.7, 0.7, 0.7, 0.7, 0.7]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Multislider.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this._numberOfSliders = this.settings.numberOfSliders;\n\t this.values = this.settings.values;\n\t\n\t this.sliders = [];\n\t\n\t this.interacting = false;\n\t\n\t this.init();\n\t }\n\t\n\t _inherits(Multislider, _Interface);\n\t\n\t _createClass(Multislider, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.element = document.createElement(\"div\");\n\t this.parent.appendChild(this.element);\n\t }\n\t },\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t var min = this.settings.min;\n\t var max = this.settings.max;\n\t var step = this.settings.step;\n\t\n\t if (this.sliders.length) {\n\t min = this.sliders[0].min;\n\t max = this.sliders[0].max;\n\t step = this.sliders[0].step;\n\t }\n\t\n\t this.sliders = [];\n\t\n\t for (var i = 0; i < this._numberOfSliders; i++) {\n\t var container = document.createElement(\"span\");\n\t\n\t var slider = new SingleSlider(container, {\n\t scale: [min, max],\n\t step: step,\n\t mode: \"absolute\",\n\t orientation: \"vertical\",\n\t value: this.values[i],\n\t hasKnob: false,\n\t component: true }, this.update.bind(this, i));\n\t slider.multislider = this;\n\t\n\t slider.index = i;\n\t if (touch.exists) {\n\t slider.bar.index = i;\n\t slider.fillbar.index = i;\n\t slider.preClick = slider.preMove = slider.preRelease = function () {};\n\t slider.click = slider.move = slider.release = function () {};\n\t slider.preTouch = slider.preTouchMove = slider.preTouchRelease = function () {};\n\t slider.touch = slider.touchMove = slider.touchRelease = function () {};\n\t }\n\t\n\t this.sliders.push(slider);\n\t this.element.appendChild(container);\n\t }\n\t if (touch.exists) {\n\t this.addTouchListeners();\n\t }\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t for (var i = 0; i < this.sliders.length; i++) {\n\t this.sliders[i].colors = this.colors;\n\t this.sliders[i].colorInterface();\n\t }\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t var sliderWidth = this.width / this.sliders.length;\n\t var sliderHeight = this.height;\n\t\n\t for (var i = 0; i < this.sliders.length; i++) {\n\t this.sliders[i].resize(sliderWidth, sliderHeight);\n\t this.sliders[i].customStyle();\n\t }\n\t }\n\t },\n\t update: {\n\t value: function update(index, value) {\n\t this.emit(\"change\", {\n\t index: index,\n\t value: value\n\t });\n\t }\n\t },\n\t addTouchListeners: {\n\t value: function addTouchListeners() {\n\t var _this = this;\n\t\n\t this.preClick = this.preMove = this.preRelease = function () {};\n\t this.click = this.move = this.release = function () {};\n\t this.preTouch = this.preTouchMove = this.preTouchRelease = function () {};\n\t this.touch = this.touchMove = this.touchRelease = function () {};\n\t\n\t this.currentElement = false;\n\t\n\t this.element.addEventListener(\"touchstart\", function (e) {\n\t var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);\n\t var slider = _this.sliders[element.index];\n\t if (!slider.offset) {\n\t slider.offset = dom.findPosition(slider.element);\n\t }\n\t slider.mouse = dom.locateMouse(e, slider.offset);\n\t slider.down();\n\t _this.currentElement = element.index;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t\n\t this.element.addEventListener(\"touchmove\", function (e) {\n\t var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);\n\t var slider = _this.sliders[element.index];\n\t if (!slider.offset) {\n\t slider.offset = dom.findPosition(slider.element);\n\t }\n\t slider.mouse = dom.locateMouse(e, slider.offset);\n\t if (element.index !== _this.currentElement) {\n\t if (_this.currentElement >= 0) {\n\t var pastslider = _this.sliders[_this.currentElement];\n\t pastslider.up();\n\t }\n\t slider.down();\n\t } else {\n\t slider.slide();\n\t }\n\t _this.currentElement = element.index;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t\n\t this.element.addEventListener(\"touchend\", function (e) {\n\t // no touches to calculate because none remaining\n\t var slider = _this.sliders[_this.currentElement];\n\t slider.up();\n\t _this.interacting = false;\n\t _this.currentElement = false;\n\t e.preventDefault();\n\t e.stopPropagation();\n\t });\n\t }\n\t },\n\t numberOfSliders: {\n\t\n\t /**\n\t Get or set the number of sliders\n\t @type {Number}\n\t */\n\t\n\t get: function () {\n\t return this.sliders.length;\n\t },\n\t set: function (v) {\n\t if (v === this.sliders.length) {\n\t return;\n\t }\n\t this.sliders.forEach(function (slider) {\n\t slider.destroy();\n\t });\n\t this.empty();\n\t this._numberOfSliders = v;\n\t this.buildInterface();\n\t }\n\t },\n\t min: {\n\t\n\t /**\n\t Lower limit of the multislider's output range\n\t @type {number}\n\t @example multislider.min = 1000;\n\t */\n\t\n\t get: function () {\n\t return this.sliders[0].min;\n\t },\n\t set: function (v) {\n\t this.sliders.forEach(function (slider) {\n\t slider.min = v;\n\t });\n\t }\n\t },\n\t max: {\n\t\n\t /**\n\t Upper limit of the multislider's output range\n\t @type {number}\n\t @example multislider.max = 1000;\n\t */\n\t\n\t get: function () {\n\t return this.sliders[0].max;\n\t },\n\t set: function (v) {\n\t this.sliders.forEach(function (slider) {\n\t slider.max = v;\n\t });\n\t }\n\t },\n\t step: {\n\t\n\t /**\n\t The increment that the multislider's value changes by.\n\t @type {number}\n\t @example multislider.step = 5;\n\t */\n\t\n\t get: function () {\n\t return this.sliders[0].step;\n\t },\n\t set: function (v) {\n\t this.sliders.forEach(function (slider) {\n\t slider.step = v;\n\t });\n\t }\n\t },\n\t setSlider: {\n\t\n\t /**\n\t Set the value of an individual slider\n\t @param index {number} Slider index\n\t @param value {number} New slider value\n\t @example\n\t // Set the first slider to value 0.5\n\t multislider.setSlider(0,0.5)\n\t */\n\t\n\t value: function setSlider(index, value) {\n\t this.sliders[index].value = value;\n\t this.emit(\"change\", {\n\t index: index,\n\t value: value\n\t });\n\t }\n\t },\n\t setAllSliders: {\n\t\n\t /**\n\t Set the value of all sliders at once. If the size of the input array does not match the current number of sliders, the value array will repeat until all sliders have been set. I.e. an input array of length 1 will set all sliders to that value.\n\t @param values {Array} All slider values\n\t @example\n\t multislider.setAllSliders([0.2,0.3,0.4,0.5,0.6])\n\t */\n\t\n\t value: function setAllSliders(values) {\n\t var _this = this;\n\t\n\t this.values = values;\n\t this.sliders.forEach(function (slider, i) {\n\t slider.value = values[i % values.length];\n\t _this.emit(\"change\", {\n\t index: i,\n\t value: slider.value\n\t });\n\t });\n\t }\n\t }\n\t });\n\t\n\t return Multislider;\n\t})(Interface);\n\t\n\tmodule.exports = Multislider;\n\n/***/ }),\n/* 32 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\t\n\tvar Interaction = _interopRequireWildcard(__webpack_require__(12));\n\t\n\tvar SliderTemplate = (function (_Interface) {\n\t function SliderTemplate(args, options, defaults) {\n\t _classCallCheck(this, SliderTemplate);\n\t\n\t _get(Object.getPrototypeOf(SliderTemplate.prototype), \"constructor\", this).call(this, args, options, defaults);\n\t\n\t this.orientation = this.settings.orientation;\n\t\n\t // this.mode = this.settings.mode;\n\t\n\t this.hasKnob = this.settings.hasKnob;\n\t\n\t // this.step should eventually be get/set\n\t // updating it will update the _value step model\n\t // this.step = this.settings.step; // float\n\t\n\t this._value = new Step(this.settings.scale[0], this.settings.scale[1], this.settings.step, this.settings.value);\n\t\n\t this.init();\n\t\n\t this.position = new Interaction.Handle(this.settings.mode, this.orientation, [0, this.width], [this.height, 0]);\n\t this.position.value = this._value.normalized;\n\t\n\t this.value = this._value.value;\n\t\n\t this.emit(\"change\", this.value);\n\t }\n\t\n\t _inherits(SliderTemplate, _Interface);\n\t\n\t _createClass(SliderTemplate, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.bar = svg.create(\"rect\");\n\t this.fillbar = svg.create(\"rect\");\n\t this.knob = svg.create(\"circle\");\n\t\n\t this.element.appendChild(this.bar);\n\t this.element.appendChild(this.fillbar);\n\t this.element.appendChild(this.knob);\n\t\n\t this.sizeInterface();\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t if (!this.settings.orientation) {\n\t if (this.width < this.height) {\n\t this.orientation = \"vertical\";\n\t } else {\n\t this.orientation = \"horizontal\";\n\t }\n\t }\n\t\n\t var x = undefined,\n\t y = undefined,\n\t w = undefined,\n\t h = undefined,\n\t barOffset = undefined,\n\t cornerRadius = undefined;\n\t this.knobData = {\n\t level: 0,\n\t r: 0\n\t };\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.thickness = this.width / 2;\n\t x = this.width / 2;\n\t y = 0;\n\t w = this.thickness;\n\t h = this.height;\n\t this.knobData.r = this.thickness * 0.8;\n\t this.knobData.level = h - this.normalized * h;\n\t barOffset = \"translate(\" + this.thickness * -1 / 2 + \",0)\";\n\t cornerRadius = w / 2;\n\t } else {\n\t this.thickness = this.height / 2;\n\t x = 0;\n\t y = this.height / 2;\n\t w = this.width;\n\t h = this.thickness;\n\t this.knobData.r = this.thickness * 0.8;\n\t this.knobData.level = this.normalized * w;\n\t barOffset = \"translate(0,\" + this.thickness * -1 / 2 + \")\";\n\t cornerRadius = h / 2;\n\t }\n\t\n\t this.bar.setAttribute(\"x\", x);\n\t this.bar.setAttribute(\"y\", y);\n\t this.bar.setAttribute(\"transform\", barOffset);\n\t this.bar.setAttribute(\"rx\", cornerRadius); // corner radius\n\t this.bar.setAttribute(\"ry\", cornerRadius);\n\t this.bar.setAttribute(\"width\", w);\n\t this.bar.setAttribute(\"height\", h);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.fillbar.setAttribute(\"x\", x);\n\t this.fillbar.setAttribute(\"y\", this.knobData.level);\n\t this.fillbar.setAttribute(\"width\", w);\n\t this.fillbar.setAttribute(\"height\", h - this.knobData.level);\n\t } else {\n\t this.fillbar.setAttribute(\"x\", 0);\n\t this.fillbar.setAttribute(\"y\", y);\n\t this.fillbar.setAttribute(\"width\", this.knobData.level);\n\t this.fillbar.setAttribute(\"height\", h);\n\t }\n\t this.fillbar.setAttribute(\"transform\", barOffset);\n\t this.fillbar.setAttribute(\"rx\", cornerRadius);\n\t this.fillbar.setAttribute(\"ry\", cornerRadius);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.knob.setAttribute(\"cx\", x);\n\t this.knob.setAttribute(\"cy\", this.knobData.level);\n\t } else {\n\t this.knob.setAttribute(\"cx\", this.knobData.level);\n\t this.knob.setAttribute(\"cy\", y);\n\t }\n\t this.knob.setAttribute(\"r\", this.knobData.r);\n\t\n\t if (this.position) {\n\t this.position.resize([0, this.width], [this.height, 0]);\n\t }\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t\n\t this.bar.setAttribute(\"fill\", this.colors.fill);\n\t this.fillbar.setAttribute(\"fill\", this.colors.accent);\n\t this.knob.setAttribute(\"fill\", this.colors.accent);\n\t if (!this.hasKnob) {\n\t this.knob.setAttribute(\"fill\", \"none\");\n\t }\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.clicked) {\n\t this.knobData.r = this.thickness * 0.75;\n\t }\n\t this.knob.setAttribute(\"r\", this.knobData.r);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.knobData.level = this._value.normalized * this.height;\n\t this.knob.setAttribute(\"cy\", this.height - this.knobData.level);\n\t this.fillbar.setAttribute(\"y\", this.height - this.knobData.level);\n\t this.fillbar.setAttribute(\"height\", this.knobData.level);\n\t } else {\n\t this.knobData.level = this._value.normalized * this.width;\n\t this.knob.setAttribute(\"cx\", this.knobData.level);\n\t this.fillbar.setAttribute(\"x\", 0);\n\t this.fillbar.setAttribute(\"width\", this.knobData.level);\n\t }\n\t }\n\t },\n\t down: {\n\t value: function down() {\n\t this.clicked = true;\n\t this.knobData.r = this.thickness * 0.9;\n\t this.position.anchor = this.mouse;\n\t this.slide();\n\t }\n\t },\n\t slide: {\n\t value: function slide() {\n\t if (this.clicked) {\n\t this.position.update(this.mouse);\n\t this.value = this._value.updateNormal(this.position.value);\n\t this.emit(\"change\", this.value);\n\t }\n\t }\n\t },\n\t up: {\n\t value: function up() {\n\t this.clicked = false;\n\t this.render();\n\t }\n\t },\n\t normalized: {\n\t get: function () {\n\t return this._value.normalized;\n\t }\n\t },\n\t value: {\n\t\n\t /**\n\t The slider's current value. If set manually, will update the interface and trigger the output event.\n\t @type {number}\n\t @example slider.value = 10;\n\t */\n\t\n\t get: function () {\n\t return this._value.value;\n\t },\n\t set: function (v) {\n\t this._value.update(v);\n\t this.position.value = this._value.normalized;\n\t this.render();\n\t }\n\t },\n\t min: {\n\t\n\t /**\n\t Lower limit of the sliders's output range\n\t @type {number}\n\t @example slider.min = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.min;\n\t },\n\t set: function (v) {\n\t this._value.min = v;\n\t }\n\t },\n\t max: {\n\t\n\t /**\n\t Upper limit of the slider's output range\n\t @type {number}\n\t @example slider.max = 1000;\n\t */\n\t\n\t get: function () {\n\t return this._value.max;\n\t },\n\t set: function (v) {\n\t this._value.max = v;\n\t }\n\t },\n\t step: {\n\t\n\t /**\n\t The increment that the slider's value changes by.\n\t @type {number}\n\t @example slider.step = 5;\n\t */\n\t\n\t get: function () {\n\t return this._value.step;\n\t },\n\t set: function (v) {\n\t this._value.step = v;\n\t }\n\t },\n\t mode: {\n\t\n\t /**\n\t Absolute mode (slider's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: \"relative\".\n\t @type {string}\n\t @example slider.mode = \"relative\";\n\t */\n\t\n\t get: function () {\n\t return this.position.mode;\n\t },\n\t set: function (v) {\n\t this.position.mode = v;\n\t }\n\t }\n\t });\n\t\n\t return SliderTemplate;\n\t})(Interface);\n\t\n\tmodule.exports = SliderTemplate;\n\n/***/ }),\n/* 33 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar svg = __webpack_require__(4);\n\tvar math = __webpack_require__(5);\n\tvar Interface = __webpack_require__(6);\n\tvar Step = __webpack_require__(11);\n\t\n\tvar Interaction = _interopRequireWildcard(__webpack_require__(12));\n\t\n\t/**\n\t* Pan\n\t*\n\t* @description Stereo crossfader.\n\t*\n\t* @demo <span nexus-ui=\"pan\"></span>\n\t*\n\t* @example\n\t* var pan = new Nexus.Pan('#target')\n\t*\n\t* @output\n\t* change\n\t* Fires any time the interface's value changes. <br>\n\t* The event data is an object containing the interface's <i>value</i> (-1 to 1), as well as <i>L</i> and <i>R</i> amplitude values (0-1) for left and right speakers, calculated by a square-root crossfade algorithm.\n\t*\n\t* @outputexample\n\t* pan.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*\n\t*/\n\t\n\tvar Pan = (function (_Interface) {\n\t function Pan() {\n\t _classCallCheck(this, Pan);\n\t\n\t var options = [\"scale\", \"value\"];\n\t\n\t var defaults = {\n\t size: [120, 20],\n\t orientation: \"horizontal\",\n\t mode: \"relative\",\n\t scale: [-1, 1],\n\t step: 0,\n\t value: 0,\n\t hasKnob: true\n\t };\n\t\n\t _get(Object.getPrototypeOf(Pan.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.orientation = this.settings.orientation;\n\t\n\t this.mode = this.settings.mode;\n\t\n\t this.hasKnob = this.settings.hasKnob;\n\t\n\t // this.step should eventually be get/set\n\t // updating it will update the _value step model\n\t this.step = this.settings.step; // float\n\t\n\t this._value = new Step(this.settings.scale[0], this.settings.scale[1], this.settings.step, this.settings.value);\n\t\n\t this.init();\n\t\n\t this.position = new Interaction.Handle(this.mode, this.orientation, [0, this.width], [this.height, 0]);\n\t this.position.value = this._value.normalized;\n\t\n\t this.value = this._value.value;\n\t\n\t this.emit(\"change\", this.value);\n\t }\n\t\n\t _inherits(Pan, _Interface);\n\t\n\t _createClass(Pan, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t\n\t this.bar = svg.create(\"rect\");\n\t this.knob = svg.create(\"circle\");\n\t\n\t this.element.appendChild(this.bar);\n\t this.element.appendChild(this.knob);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t if (this.position) {\n\t this.position.resize([0, this.width], [this.height, 0]);\n\t }\n\t\n\t if (this.width < this.height) {\n\t this.orientation = \"vertical\";\n\t } else {\n\t this.orientation = \"horizontal\";\n\t }\n\t\n\t var x = undefined,\n\t y = undefined,\n\t w = undefined,\n\t h = undefined,\n\t barOffset = undefined,\n\t cornerRadius = undefined;\n\t this.knobData = {\n\t level: 0,\n\t r: 0\n\t };\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.thickness = this.width / 2;\n\t x = this.width / 2;\n\t y = 0;\n\t w = this.thickness;\n\t h = this.height;\n\t this.knobData.r = this.thickness * 0.8;\n\t this.knobData.level = h - this.knobData.r - this.normalized * (h - this.knobData.r * 2);\n\t barOffset = \"translate(\" + this.thickness * -1 / 2 + \",0)\";\n\t cornerRadius = w / 2;\n\t } else {\n\t this.thickness = this.height / 2;\n\t x = 0;\n\t y = this.height / 2;\n\t w = this.width;\n\t h = this.thickness;\n\t this.knobData.r = this.thickness * 0.8;\n\t this.knobData.level = this.normalized * (w - this.knobData.r * 2) + this.knobData.r;\n\t barOffset = \"translate(0,\" + this.thickness * -1 / 2 + \")\";\n\t cornerRadius = h / 2;\n\t }\n\t\n\t this.bar.setAttribute(\"x\", x);\n\t this.bar.setAttribute(\"y\", y);\n\t this.bar.setAttribute(\"transform\", barOffset);\n\t this.bar.setAttribute(\"rx\", cornerRadius); // corner radius\n\t this.bar.setAttribute(\"ry\", cornerRadius);\n\t this.bar.setAttribute(\"width\", w);\n\t this.bar.setAttribute(\"height\", h);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.knob.setAttribute(\"cx\", x);\n\t this.knob.setAttribute(\"cy\", this.knobData.level);\n\t } else {\n\t this.knob.setAttribute(\"cx\", this.knobData.level);\n\t this.knob.setAttribute(\"cy\", y);\n\t }\n\t this.knob.setAttribute(\"r\", this.knobData.r);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t\n\t this.bar.setAttribute(\"fill\", this.colors.fill);\n\t this.knob.setAttribute(\"fill\", this.colors.accent);\n\t\n\t if (!this.hasKnob) {\n\t this.knob.setAttribute(\"fill\", \"transparent\");\n\t }\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t if (!this.clicked) {\n\t this.knobData.r = this.thickness * 0.75;\n\t }\n\t this.knob.setAttribute(\"r\", this.knobData.r);\n\t\n\t if (this.orientation === \"vertical\") {\n\t this.knobData.level = this.knobData.r + this._value.normalized * (this.height - this.knobData.r * 2);\n\t this.knob.setAttribute(\"cy\", this.height - this.knobData.level);\n\t } else {\n\t this.knobData.level = this._value.normalized * (this.width - this.knobData.r * 2) + this.knobData.r;\n\t this.knob.setAttribute(\"cx\", this.knobData.level);\n\t }\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.knobData.r = this.thickness * 0.9;\n\t this.position.anchor = this.mouse;\n\t this.move();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.clicked) {\n\t this.position.update(this.mouse);\n\t\n\t this.value = this._value.updateNormal(this.position.value);\n\t\n\t this.emit(\"change\", {\n\t value: this.value,\n\t L: Math.pow(math.scale(this.value, -1, 1, 1, 0), 2),\n\t R: Math.pow(math.scale(this.value, -1, 1, 0, 1), 2)\n\t });\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t this.render();\n\t }\n\t },\n\t value: {\n\t\n\t /**\n\t The position of crossfader, from -1 (left) to 1 (right). Setting this value updates the interface and triggers the output event.\n\t @type {number}\n\t */\n\t\n\t get: function () {\n\t return this._value.value;\n\t },\n\t set: function (value) {\n\t this._value.update(value);\n\t this.position.value = this._value.normalized;\n\t this.emit(\"change\", {\n\t value: this.value,\n\t L: Math.pow(math.scale(this.value, -1, 1, 1, 0), 2),\n\t R: Math.pow(math.scale(this.value, -1, 1, 0, 1), 2)\n\t });\n\t this.render();\n\t }\n\t },\n\t normalized: {\n\t get: function () {\n\t return this._value.normalized;\n\t }\n\t }\n\t });\n\t\n\t return Pan;\n\t})(Interface);\n\t\n\tmodule.exports = Pan;\n\n/***/ }),\n/* 34 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = __webpack_require__(5);\n\tvar svg = __webpack_require__(4);\n\tvar Interface = __webpack_require__(6);\n\t\n\tvar Point = function Point(point, envelope) {\n\t\n\t this.x = point.x;\n\t this.y = point.y;\n\t this.envelope = envelope;\n\t\n\t this.element = svg.create(\"circle\");\n\t this.element.setAttribute(\"fill\", this.envelope.colors.accent);\n\t\n\t this.envelope.element.appendChild(this.element);\n\t\n\t this.resize = function () {\n\t var r = ~ ~(Math.min(this.envelope.width, this.envelope.height) / 50) + 2;\n\t this.element.setAttribute(\"r\", r);\n\t };\n\t\n\t this.move = function (x, y) {\n\t\n\t this.x = x || x === 0 ? x : this.x;\n\t this.y = y || y === 0 ? y : this.y;\n\t\n\t if (this.envelope.nodes.indexOf(this) >= 0) {\n\t\n\t var prevIndex = this.envelope.nodes.indexOf(this) - 1;\n\t var nextIndex = this.envelope.nodes.indexOf(this) + 1;\n\t\n\t var prevNode = this.envelope.nodes[prevIndex];\n\t var nextNode = this.envelope.nodes[nextIndex];\n\t\n\t var lowX = prevIndex >= 0 ? prevNode.x : 0;\n\t var highX = nextIndex < this.envelope.nodes.length ? nextNode.x : 1;\n\t\n\t if (this.x < lowX) {\n\t this.x = lowX;\n\t }\n\t if (this.x > highX) {\n\t this.x = highX;\n\t }\n\t }\n\t\n\t this.location = this.getCoordinates();\n\t this.element.setAttribute(\"cx\", this.location.x);\n\t this.element.setAttribute(\"cy\", this.location.y);\n\t };\n\t\n\t this.getCoordinates = function () {\n\t return {\n\t x: this.x * this.envelope.width,\n\t y: (1 - this.y) * this.envelope.height\n\t };\n\t };\n\t\n\t this.move(this.x, this.y, true);\n\t this.resize();\n\t\n\t this.destroy = function () {\n\t this.envelope.element.removeChild(this.element);\n\t this.envelope.nodes.splice(this.envelope.nodes.indexOf(this), 1);\n\t };\n\t};\n\t\n\t/**\n\t* Envelope\n\t*\n\t* @description Interactive linear ramp visualization.\n\t*\n\t* @demo <span nexus-ui=\"envelope\"></span>\n\t*\n\t* @example\n\t* var envelope = new Nexus.Envelope('#target')\n\t*\n\t* @example\n\t* var envelope = new Nexus.Envelope('#target',{\n\t* 'size': [300,150],\n\t* 'points': [\n\t* {\n\t* x: 0.1,\n\t* y: 0.4\n\t* },\n\t* {\n\t* x: 0.35,\n\t* y: 0.6\n\t* },\n\t* {\n\t* x: 0.65,\n\t* y: 0.2\n\t* },\n\t* {\n\t* x: 0.9,\n\t* y: 0.4\n\t* },\n\t* ]\n\t* })\n\t*\n\t* @output\n\t* change\n\t* Fires any time a node is moved. <br>\n\t* The event data is an array of point locations. Each item in the array is an object containing <i>x</i> and <i>y</i> properties describing the location of a point on the envelope.\n\t*\n\t* @outputexample\n\t* envelope.on('change',function(v) {\n\t* console.log(v);\n\t* })\n\t*\n\t*/\n\t\n\tvar Envelope = (function (_Interface) {\n\t function Envelope() {\n\t _classCallCheck(this, Envelope);\n\t\n\t var options = [\"value\"];\n\t\n\t var defaults = {\n\t size: [300, 150],\n\t points: [{\n\t x: 0.1,\n\t y: 0.4\n\t }, {\n\t x: 0.35,\n\t y: 0.6\n\t }, {\n\t x: 0.65,\n\t y: 0.2\n\t }, {\n\t x: 0.9,\n\t y: 0.4\n\t }]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Envelope.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.points = this.settings.points;\n\t\n\t this.nodes = [];\n\t\n\t this.selected = false;\n\t\n\t this.init();\n\t }\n\t\n\t _inherits(Envelope, _Interface);\n\t\n\t _createClass(Envelope, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t var _this = this;\n\t\n\t this.points.forEach(function (point) {\n\t var node = new Point(point, _this);\n\t _this.nodes.push(node);\n\t });\n\t\n\t this.sortPoints();\n\t\n\t this.line = svg.create(\"polyline\");\n\t this.line.setAttribute(\"stroke-width\", 2);\n\t this.line.setAttribute(\"fill\", \"none\");\n\t\n\t this.element.appendChild(this.line);\n\t\n\t this.fill = svg.create(\"polyline\");\n\t this.fill.setAttribute(\"fill-opacity\", \"0.2\");\n\t\n\t this.element.appendChild(this.fill);\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t\n\t for (var i = 0; i < this.nodes.length; i++) {\n\t this.nodes[i].resize();\n\t this.nodes[i].move();\n\t }\n\t\n\t this.render();\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t var _this = this;\n\t\n\t this.element.style.backgroundColor = this.colors.fill;\n\t this.line.setAttribute(\"stroke\", this.colors.accent);\n\t this.fill.setAttribute(\"fill\", this.colors.accent);\n\t this.nodes.forEach(function (node) {\n\t node.element.setAttribute(\"fill\", _this.colors.accent);\n\t });\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t // this.nodes[this.selected].move( this.points )\n\t this.calculatePath();\n\t }\n\t },\n\t calculatePoints: {\n\t value: function calculatePoints() {\n\t var _this = this;\n\t\n\t this.points = [];\n\t this.nodes.forEach(function (node) {\n\t _this.points.push({ x: node.x, y: node.y });\n\t });\n\t }\n\t },\n\t calculatePath: {\n\t value: function calculatePath() {\n\t\n\t //stroke data\n\t var data = \"0 \" + this.nodes[0].location.y + \", \";\n\t\n\t // data should be re-ordered based on x location.\n\t // whatever function adds a node should add it at the right index\n\t\n\t this.nodes.forEach(function (node) {\n\t // let location = node.getCoordinates();\n\t data += node.location.x + \" \" + node.location.y + \", \";\n\t });\n\t\n\t // data += point.x*this.width+' '+ point.y*this.height+', ';\n\t data += this.width + \" \" + this.nodes[this.nodes.length - 1].location.y;\n\t\n\t this.line.setAttribute(\"points\", data);\n\t\n\t // fill data\n\t // add bottom corners\n\t\n\t data += \", \" + this.width + \" \" + this.height + \", \";\n\t data += \"0 \" + this.height;\n\t\n\t this.fill.setAttribute(\"points\", data);\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t // find nearest node and set this.selected (index)\n\t this.hasMoved = false;\n\t this.selected = this.findNearestNode();\n\t\n\t this.nodes[this.selected].move(this.mouse.x / this.width, 1 - this.mouse.y / this.height);\n\t this.scaleNode(this.selected);\n\t\n\t // must do this b/c new node may have been created\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t }\n\t },\n\t move: {\n\t value: function move() {\n\t if (this.clicked) {\n\t this.mouse.x = math.clip(this.mouse.x, 0, this.width);\n\t this.hasMoved = true;\n\t\n\t this.nodes[this.selected].move(this.mouse.x / this.width, 1 - this.mouse.y / this.height);\n\t this.scaleNode(this.selected);\n\t\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t }\n\t }\n\t },\n\t release: {\n\t value: function release() {\n\t\n\t if (!this.hasMoved) {\n\t this.nodes[this.selected].destroy();\n\t }\n\t\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t\n\t // reset this.selected\n\t this.selected = null;\n\t }\n\t },\n\t findNearestNode: {\n\t value: function findNearestNode() {\n\t var nearestIndex = null;\n\t // set this unreasonably high so that every distance will be lower than it.\n\t var nearestDist = 10000;\n\t var before = false;\n\t var x = this.mouse.x / this.width;\n\t var y = 1 - this.mouse.y / this.height;\n\t var nodes = this.nodes;\n\t for (var i = 0; i < nodes.length; i++) {\n\t\n\t // calculate the distance from mouse to this node using pythagorean theorem\n\t var distance = Math.sqrt(Math.pow(nodes[i].x - x, 2) + Math.pow(nodes[i].y - y, 2));\n\t\n\t // if this distance is less than the previous shortest distance, use this index\n\t if (distance < nearestDist) {\n\t nearestDist = distance;\n\t nearestIndex = i;\n\t before = x > nodes[i].x;\n\t }\n\t }\n\t\n\t // if not very close to any node, create a node\n\t if (nearestDist > 0.07) {\n\t\n\t nearestIndex = this.getIndexFromX(this.mouse.x / this.width);\n\t\n\t this.nodes.splice(nearestIndex, 0, new Point({\n\t x: this.mouse.x / this.width,\n\t y: 1 - this.mouse.y / this.height\n\t }, this));\n\t this.hasMoved = true;\n\t }\n\t\n\t return nearestIndex;\n\t }\n\t },\n\t getIndexFromX: {\n\t value: function getIndexFromX(x) {\n\t var _this = this;\n\t\n\t var index = 0;\n\t this.nodes.forEach(function (node, i) {\n\t if (_this.nodes[i].x <= x) {\n\t index = i + 1;\n\t }\n\t });\n\t return index;\n\t }\n\t },\n\t scaleNode: {\n\t value: function scaleNode(i) {\n\t\n\t var clippedX = math.clip(this.nodes[i].x, 0, 1);\n\t var clippedY = math.clip(this.nodes[i].y, 0, 1);\n\t\n\t this.nodes[i].move(clippedX, clippedY);\n\t }\n\t },\n\t sortPoints: {\n\t\n\t /**\n\t Sort the this.points array from left-most point to right-most point. You should not regularly need to use this, however it may be useful if the points get unordered.\n\t */\n\t\n\t value: function sortPoints() {\n\t this.nodes.sort(function (a, b) {\n\t return a.x > b.x;\n\t });\n\t }\n\t },\n\t addPoint: {\n\t\n\t /**\n\t Add a breakpoint on the envelope.\n\t @param x {number} x location of the point, normalized (0-1)\n\t @param y {number} y location of the point, normalized (0-1)\n\t */\n\t\n\t value: function addPoint(x, y) {\n\t var index = this.nodes.length;\n\t\n\t this.sortPoints();\n\t\n\t for (var i = 0; i < this.nodes.length; i++) {\n\t if (x < this.nodes[i].x) {\n\t index = i;\n\t break;\n\t }\n\t }\n\t\n\t this.nodes.splice(index, 0, new Point({\n\t x: x,\n\t y: y\n\t }, this));\n\t\n\t this.scaleNode(index);\n\t\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t\n\t this.render();\n\t }\n\t },\n\t scan: {\n\t\n\t /**\n\t Find the level at a certain x location on the envelope.\n\t @param x {number} The x location to find the level of, normalized 0-1\n\t */\n\t\n\t value: function scan(x) {\n\t // find surrounding points\n\t var nextIndex = this.getIndexFromX(x);\n\t var priorIndex = nextIndex - 1;\n\t if (priorIndex < 0) {\n\t priorIndex = 0;\n\t }\n\t if (nextIndex >= this.nodes.length) {\n\t nextIndex = this.nodes.length - 1;\n\t }\n\t var priorPoint = this.nodes[priorIndex];\n\t var nextPoint = this.nodes[nextIndex];\n\t var loc = math.scale(x, priorPoint.x, nextPoint.x, 0, 1);\n\t var value = math.interp(loc, priorPoint.y, nextPoint.y);\n\t this.emit(\"scan\", value);\n\t return value;\n\t }\n\t },\n\t movePoint: {\n\t\n\t /**\n\t Move a breakpoint on the envelope.\n\t @param index {number} The index of the breakpoint to move\n\t @param x {number} New x location, normalized 0-1\n\t @param y {number} New y location, normalized 0-1\n\t */\n\t\n\t value: function movePoint(index, x, y) {\n\t this.nodes[index].move(x, y);\n\t this.scaleNode(index);\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t }\n\t },\n\t adjustPoint: {\n\t\n\t /**\n\t Move a breakpoint on the envelope by a certain amount.\n\t @param index {number} The index of the breakpoint to move\n\t @param xOffset {number} X displacement, normalized 0-1\n\t @param yOffset {number} Y displacement, normalized 0-1\n\t */\n\t\n\t value: function adjustPoint(index, xOffset, yOffset) {\n\t this.nodes[index].move(this.nodes[index].x + xOffset, this.nodes[index].y + yOffset);\n\t this.scaleNode(index);\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t }\n\t },\n\t destroyPoint: {\n\t\n\t /**\n\t Remove a breakpoint from the envelope.\n\t @param index {number} Index of the breakpoint to remove\n\t */\n\t\n\t value: function destroyPoint(index) {\n\t this.nodes[index].destroy();\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t }\n\t },\n\t setPoints: {\n\t\n\t /**\n\t Remove all existing breakpoints and add an entirely new set of breakpoints.\n\t @param allPoints {array} An array of objects with x/y properties (normalized 0-1). Each object in the array specifices the x/y location of a new breakpoint to be added.\n\t */\n\t\n\t value: function setPoints(allPoints) {\n\t var _this = this;\n\t\n\t while (this.nodes.length) {\n\t this.nodes[0].destroy();\n\t }\n\t allPoints.forEach(function (point) {\n\t _this.addPoint(point.x, point.y);\n\t });\n\t this.calculatePoints();\n\t this.emit(\"change\", this.points);\n\t this.render();\n\t }\n\t }\n\t });\n\t\n\t return Envelope;\n\t})(Interface);\n\t\n\tmodule.exports = Envelope;\n\n/***/ }),\n/* 35 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar dom = __webpack_require__(7);\n\t//let math = require('../util/math');\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\t* Spectrogram\n\t*\n\t* @description Audio spectrum visualization\n\t*\n\t* @demo <span nexus-ui=\"spectrogram\"></span>\n\t*\n\t* @example\n\t* var spectrogram = new Nexus.Spectrogram('#target')\n\t*\n\t* @example\n\t* var spectrogram = new Nexus.Spectrogram('#target',{\n\t* 'size': [300,150]\n\t* })\n\t*\n\t* @output\n\t* \n\t* No events\n\t*\n\t*/\n\t\n\tvar context = __webpack_require__(1).context;\n\t\n\tvar Spectrogram = (function (_Interface) {\n\t function Spectrogram() {\n\t _classCallCheck(this, Spectrogram);\n\t\n\t var options = [\"scale\", \"value\"];\n\t\n\t var defaults = {\n\t size: [300, 150]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Spectrogram.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.context = context(); // jshint ignore:line\n\t\n\t this.analyser = this.context.createAnalyser();\n\t this.analyser.fftSize = 2048;\n\t this.bufferLength = this.analyser.frequencyBinCount;\n\t this.dataArray = new Uint8Array(this.bufferLength);\n\t\n\t this.active = true;\n\t\n\t this.source = false;\n\t\n\t this.init();\n\t }\n\t\n\t _inherits(Spectrogram, _Interface);\n\t\n\t _createClass(Spectrogram, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.canvas = new dom.SmartCanvas(this.parent);\n\t this.element = this.canvas.element;\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t this.canvas.resize(this.width, this.height);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.canvas.element.style.backgroundColor = this.colors.fill;\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t\n\t if (this.active) {\n\t requestAnimationFrame(this.render.bind(this));\n\t }\n\t\n\t this.analyser.getByteFrequencyData(this.dataArray);\n\t\n\t this.canvas.context.fillStyle = this.colors.fill;\n\t this.canvas.context.fillRect(0, 0, this.canvas.element.width, this.canvas.element.height);\n\t\n\t if (this.source && this.dataArray) {\n\t\n\t //console.log(this.dataArray);\n\t\n\t var barWidth = this.canvas.element.width / this.bufferLength;\n\t var barHeight = undefined;\n\t var x = 0;\n\t\n\t var definition = this.canvas.element.width / 50;\n\t\n\t for (var i = 0; i < this.bufferLength; i = i + definition) {\n\t barHeight = Math.max.apply(null, this.dataArray.subarray(i, i + definition));\n\t barHeight /= 255;\n\t barHeight *= this.canvas.element.height;\n\t\n\t this.canvas.context.fillStyle = this.colors.accent;\n\t this.canvas.context.fillRect(x, this.canvas.element.height - barHeight, barWidth * definition, barHeight);\n\t\n\t x += barWidth * definition;\n\t }\n\t }\n\t }\n\t },\n\t connect: {\n\t\n\t /**\n\t Equivalent to \"patching in\" an audio node to visualize. NOTE: You cannot connect audio nodes across two different audio contexts. NexusUI runs its audio analysis on its own audio context, Nexus.context. If the audio node you are visualizing is created on a different audio context, you will need to tell NexusUI to use that context instead: i.e. Nexus.context = YourAudioContextName. For example, in ToneJS projects, the line would be: Nexus.context = Tone.context . We recommend that you write that line of code only once at the beginning of your project.\n\t @param node {AudioNode} The audio node to visualize\n\t @example Nexus.context = Tone.context // or another audio context you have created\n\t spectrogram.connect( Tone.Master );\n\t */\n\t\n\t value: function connect(node) {\n\t if (this.source) {\n\t this.disconnect();\n\t }\n\t this.source = node;\n\t this.source.connect(this.analyser);\n\t this.render();\n\t }\n\t },\n\t disconnect: {\n\t\n\t /**\n\t Stop visualizing the source node and disconnect it.\n\t */\n\t\n\t value: function disconnect() {\n\t this.source.disconnect(this.analyser);\n\t this.source = null;\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.active = !this.active;\n\t this.render();\n\t }\n\t },\n\t customDestroy: {\n\t value: function customDestroy() {\n\t this.active = false;\n\t }\n\t }\n\t });\n\t\n\t return Spectrogram;\n\t})(Interface);\n\t\n\tmodule.exports = Spectrogram;\n\n/***/ }),\n/* 36 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar dom = __webpack_require__(7);\n\tvar math = __webpack_require__(5);\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\t* Meter\n\t*\n\t* @description Stereo decibel meter\n\t*\n\t* @demo <span nexus-ui=\"meter\"></span>\n\t*\n\t* @example\n\t* var meter = new Nexus.Meter('#target')\n\t*\n\t* @example\n\t* var meter = new Nexus.Meter('#target',{\n\t* size: [75,75]\n\t* })\n\t*\n\t* @output\n\t* \n\t* No events\n\t*\n\t*/\n\t\n\tvar context = __webpack_require__(1).context;\n\t\n\tvar Meter = (function (_Interface) {\n\t function Meter() {\n\t _classCallCheck(this, Meter);\n\t\n\t var options = [\"scale\", \"value\"];\n\t\n\t var defaults = {\n\t size: [30, 100]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Meter.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.context = context(); // jshint ignore:line\n\t\n\t this.channels = 2;\n\t\n\t this.splitter = this.context.createChannelSplitter(this.channels);\n\t\n\t this.analysers = [];\n\t\n\t for (var i = 0; i < this.channels; i++) {\n\t var analyser = this.context.createAnalyser();\n\t this.splitter.connect(analyser, i);\n\t analyser.fftSize = 1024;\n\t analyser.smoothingTimeConstant = 1;\n\t this.analysers.push(analyser);\n\t }\n\t this.bufferLength = this.analysers[0].frequencyBinCount;\n\t this.dataArray = new Float32Array(this.bufferLength);\n\t\n\t /*\n\t // add linear gradient\n\t var grd = canvasCtx.createLinearGradient(0, 0, 0, canvas.height);\n\t // light blue\n\t grd.addColorStop(0, '#000');\n\t grd.addColorStop(0.2, '#bbb');\n\t grd.addColorStop(0.4, '#d18');\n\t // dark blue\n\t grd.addColorStop(1, '#d18');\n\t canvasCtx.fillStyle = grd; */\n\t\n\t this.active = true;\n\t\n\t this.db = -Infinity;\n\t\n\t this.init();\n\t\n\t this.meterWidth = this.canvas.element.width / this.channels;\n\t\n\t this.render();\n\t }\n\t\n\t _inherits(Meter, _Interface);\n\t\n\t _createClass(Meter, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.canvas = new dom.SmartCanvas(this.parent);\n\t this.element = this.canvas.element;\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t this.canvas.resize(this.width, this.height);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.canvas.element.style.backgroundColor = this.colors.fill;\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t\n\t if (this.active) {\n\t requestAnimationFrame(this.render.bind(this));\n\t }\n\t\n\t this.canvas.context.fillStyle = this.colors.fill;\n\t this.canvas.context.fillRect(0, 0, this.canvas.element.width, this.canvas.element.height);\n\t\n\t for (var i = 0; i < this.analysers.length; i++) {\n\t\n\t if (this.source) {\n\t\n\t this.analysers[i].getFloatTimeDomainData(this.dataArray);\n\t\n\t var rms = 0;\n\t\n\t for (var _i = 0; _i < this.dataArray.length; _i++) {\n\t rms += this.dataArray[_i] * this.dataArray[_i];\n\t }\n\t\n\t rms = Math.sqrt(rms / this.dataArray.length);\n\t\n\t this.db = 20 * Math.log10(rms);\n\t } else if (this.db > -200 && this.db !== -Infinity) {\n\t this.db -= 1;\n\t } else {\n\t this.db = -Infinity;\n\t }\n\t\n\t //console.log(db)\n\t\n\t if (this.db > -70) {\n\t\n\t var linear = math.normalize(this.db, -70, 5);\n\t var exp = linear * linear;\n\t var y = math.scale(exp, 0, 1, this.element.height, 0);\n\t\n\t this.canvas.context.fillStyle = this.colors.accent;\n\t this.canvas.context.fillRect(this.meterWidth * i, y, this.meterWidth, this.canvas.element.height - y);\n\t\n\t //console.log(\"rendering...\")\n\t }\n\t }\n\t }\n\t },\n\t connect: {\n\t\n\t /**\n\t Equivalent to \"patching in\" an audio node to visualize. NOTE: You cannot connect audio nodes across two different audio contexts. NexusUI runs its audio analysis on its own audio context, Nexus.context. If the audio node you are visualizing is created on a different audio context, you will need to tell NexusUI to use that context instead: i.e. Nexus.context = YourAudioContextName. For example, in ToneJS projects, the line would be: Nexus.context = Tone.context . We recommend that you write that line of code only once at the beginning of your project.\n\t @param node {AudioNode} The audio node to visualize\n\t @param channels {number} (optional) The number of channels in the source node to watch. If not specified, the interface will look for a .channelCount property on the input node. If it does not exist, the interface will default to 1 channel.\n\t @example Nexus.context = Tone.context // or another audio context you have created\n\t meter.connect( Tone.Master, 2 );\n\t */\n\t\n\t value: function connect(node, channels) {\n\t if (this.source) {\n\t this.disconnect();\n\t }\n\t //this.dummy.disconnect(this.splitter);\n\t\n\t if (channels) {\n\t this.channels = channels;\n\t } else if (node.channelCount) {\n\t this.channels = node.channelCount;\n\t } else {\n\t this.channels = 2;\n\t }\n\t this.meterWidth = this.canvas.element.width / this.channels;\n\t\n\t this.source = node;\n\t this.source.connect(this.splitter);\n\t\n\t // this.render();\n\t }\n\t },\n\t disconnect: {\n\t\n\t /**\n\t Stop visualizing the source node and disconnect it.\n\t */\n\t\n\t value: function disconnect() {\n\t\n\t this.source.disconnect(this.splitter);\n\t this.source = false;\n\t // this.dummy.connect(this.splitter);\n\t this.meterWidth = this.canvas.element.width / this.channels;\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.active = !this.active;\n\t this.render();\n\t }\n\t },\n\t customDestroy: {\n\t value: function customDestroy() {\n\t this.active = false;\n\t }\n\t }\n\t });\n\t\n\t return Meter;\n\t})(Interface);\n\t\n\tmodule.exports = Meter;\n\n/***/ }),\n/* 37 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\t\n\tvar _inherits = function (subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar dom = __webpack_require__(7);\n\tvar Interface = __webpack_require__(6);\n\t\n\t/**\n\t* Oscilloscope\n\t*\n\t* @description Visualizes a waveform's stream of values.\n\t*\n\t* @demo <span nexus-ui=\"oscilloscope\"></span>\n\t*\n\t* @example\n\t* var oscilloscope = new Nexus.Oscilloscope('#target')\n\t*\n\t* @example\n\t* var oscilloscope = new Nexus.Oscilloscope('#target',{\n\t* 'size': [300,150]\n\t* })\n\t*\n\t* @output\n\t* \n\t* No events\n\t*\n\t*/\n\t\n\tvar context = __webpack_require__(1).context;\n\t\n\tvar Oscilloscope = (function (_Interface) {\n\t function Oscilloscope() {\n\t _classCallCheck(this, Oscilloscope);\n\t\n\t var options = [\"scale\", \"value\"];\n\t\n\t var defaults = {\n\t size: [300, 150]\n\t };\n\t\n\t _get(Object.getPrototypeOf(Oscilloscope.prototype), \"constructor\", this).call(this, arguments, options, defaults);\n\t\n\t this.context = context(); // jshint ignore:line\n\t\n\t this.analyser = this.context.createAnalyser();\n\t this.analyser.fftSize = 2048;\n\t this.bufferLength = this.analyser.frequencyBinCount;\n\t this.dataArray = new Uint8Array(this.bufferLength);\n\t this.analyser.getByteTimeDomainData(this.dataArray);\n\t\n\t this.active = true;\n\t\n\t this.source = false;\n\t\n\t this.init();\n\t\n\t this.render();\n\t }\n\t\n\t _inherits(Oscilloscope, _Interface);\n\t\n\t _createClass(Oscilloscope, {\n\t buildFrame: {\n\t value: function buildFrame() {\n\t this.canvas = new dom.SmartCanvas(this.parent);\n\t this.element = this.canvas.element;\n\t }\n\t },\n\t sizeInterface: {\n\t value: function sizeInterface() {\n\t this.canvas.resize(this.width, this.height);\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t this.canvas.element.style.backgroundColor = this.colors.fill;\n\t }\n\t },\n\t render: {\n\t value: function render() {\n\t\n\t if (this.active) {\n\t requestAnimationFrame(this.render.bind(this));\n\t }\n\t\n\t this.analyser.getByteTimeDomainData(this.dataArray);\n\t\n\t this.canvas.context.fillStyle = this.colors.fill;\n\t this.canvas.context.fillRect(0, 0, this.canvas.element.width, this.canvas.element.height);\n\t\n\t this.canvas.context.lineWidth = ~ ~(this.height / 100 + 2);\n\t this.canvas.context.strokeStyle = this.colors.accent;\n\t\n\t this.canvas.context.beginPath();\n\t\n\t if (this.source) {\n\t\n\t var sliceWidth = this.canvas.element.width * 1 / this.bufferLength;\n\t var x = 0;\n\t\n\t for (var i = 0; i < this.bufferLength; i++) {\n\t\n\t var v = this.dataArray[i] / 128;\n\t var y = v * this.canvas.element.height / 2;\n\t\n\t if (i === 0) {\n\t this.canvas.context.moveTo(x, y);\n\t } else {\n\t this.canvas.context.lineTo(x, y);\n\t }\n\t\n\t x += sliceWidth;\n\t }\n\t } else {\n\t this.canvas.context.moveTo(0, this.canvas.element.height / 2);\n\t this.canvas.context.lineTo(this.canvas.element.width, this.canvas.element.height / 2);\n\t }\n\t\n\t this.canvas.context.stroke();\n\t }\n\t },\n\t connect: {\n\t\n\t /**\n\t Equivalent to \"patching in\" an audio node to visualize. NOTE: You cannot connect audio nodes across two different audio contexts. NexusUI runs its audio analysis on its own audio context, Nexus.context. If the audio node you are visualizing is created on a different audio context, you will need to tell NexusUI to use that context instead: i.e. Nexus.context = YourAudioContextName. For example, in ToneJS projects, the line would be: Nexus.context = Tone.context . We recommend that you write that line of code only once at the beginning of your project.\n\t @param node {AudioNode} The audio node to visualize\n\t @example Nexus.context = Tone.context // or another audio context you have created\n\t oscilloscope.connect( Tone.Master );\n\t */\n\t\n\t value: function connect(node) {\n\t\n\t if (this.source) {\n\t this.disconnect();\n\t }\n\t\n\t this.source = node;\n\t this.source.connect(this.analyser);\n\t\n\t this.render();\n\t }\n\t },\n\t disconnect: {\n\t\n\t /**\n\t Stop visualizing the source node and disconnect it.\n\t */\n\t\n\t value: function disconnect() {\n\t if (this.source) {\n\t this.source.disconnect(this.analyser);\n\t this.source = null;\n\t }\n\t }\n\t },\n\t click: {\n\t value: function click() {\n\t this.active = !this.active;\n\t this.render();\n\t }\n\t },\n\t customDestroy: {\n\t value: function customDestroy() {\n\t this.active = false;\n\t }\n\t }\n\t });\n\t\n\t return Oscilloscope;\n\t})(Interface);\n\t\n\tmodule.exports = Oscilloscope;\n\n/***/ }),\n/* 38 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\t/*\n\tMain concept:\n\tsynth = new Nexus.Rack('elementID');\n\t\n\tTransform all elements inside the div\n\tsynth.elementID will hold the first slider interface\n\t\n\t2) In future, potentially writing a rack that is re-usable?\n\tCould also take JSON\n\t\n\tnew Nexus.Rack('#target',{\n\t pre: () => {\n\t create some divs here, or some audio code\n\t },\n\t interface: {\n\t slider1: Nexus.add.slider({\n\t top:10,\n\t left:10,\n\t width:50,\n\t height:100,\n\t min: 0,\n\t max: 100,\n\t step: 1\n\t }),\n\t wave1: Nexus.add.waveform({\n\t file: './path/to/file.mp3',\n\t width:500,\n\t height:100,\n\t mode: 'range'\n\t })\n\t },\n\t init: () => {\n\t // some audio init code goes here...\n\t }\n\t});\n\t\n\t*/\n\t\n\tvar transform = _interopRequireWildcard(__webpack_require__(39));\n\t\n\tvar dom = _interopRequire(__webpack_require__(7));\n\t\n\tvar colors = __webpack_require__(1).colors;\n\t\n\tvar Rack = (function () {\n\t function Rack(target, settings) {\n\t _classCallCheck(this, Rack);\n\t\n\t this.meta = {};\n\t this.meta.target = target;\n\t this.meta.parent = dom.parseElement(target); // should be a generic function for parsing a 'target' argument that checks for string/DOM/jQUERY\n\t this.meta.colors = {};\n\t\n\t if (settings) {\n\t this.meta.attribute = settings.attribute || \"nexus-ui\";\n\t this.meta.title = settings.name || false;\n\t this.meta.open = settings.open || false;\n\t } else {\n\t this.meta.attribute = \"nexus-ui\";\n\t this.meta.title = false;\n\t this.meta.open = false;\n\t }\n\t\n\t var defaultColors = colors(); // jshint ignore:line\n\t this.meta.colors.accent = defaultColors.accent;\n\t this.meta.colors.fill = defaultColors.fill;\n\t this.meta.colors.light = defaultColors.light;\n\t this.meta.colors.dark = defaultColors.dark;\n\t this.meta.colors.mediumLight = defaultColors.mediumLight;\n\t this.meta.colors.mediumDark = defaultColors.mediumDark;\n\t this.buildInterface();\n\t this.colorInterface();\n\t }\n\t\n\t _createClass(Rack, {\n\t buildInterface: {\n\t value: function buildInterface() {\n\t var _this = this;\n\t\n\t this.meta.parent.style.boxSizing = \"border-box\";\n\t this.meta.parent.style.userSelect = \"none\";\n\t this.meta.parent.style.mozUserSelect = \"none\";\n\t this.meta.parent.style.webkitUserSelect = \"none\";\n\t\n\t this.meta.contents = document.createElement(\"div\");\n\t\n\t while (this.meta.parent.childNodes.length > 0) {\n\t this.meta.contents.appendChild(this.meta.parent.childNodes[0]);\n\t }\n\t\n\t this.meta.contents.style.padding = \"0px\";\n\t this.meta.contents.style.boxSizing = \"border-box\";\n\t\n\t if (this.meta.title) {\n\t this.meta.titleBar = document.createElement(\"div\");\n\t this.meta.titleBar.innerHTML = this.meta.title;\n\t this.meta.titleBar.style.fontFamily = \"arial\";\n\t this.meta.titleBar.style.position = \"relative\";\n\t this.meta.titleBar.style.color = \"#888\";\n\t this.meta.titleBar.style.padding = \"7px\";\n\t this.meta.titleBar.style.fontSize = \"12px\";\n\t\n\t this.meta.button = document.createElement(\"div\");\n\t this.meta.button.style.position = \"absolute\";\n\t this.meta.button.style.top = \"5px\";\n\t this.meta.button.style.right = \"5px\";\n\t this.meta.button.innerHTML = \"-\";\n\t this.meta.button.style.padding = \"0px 5px 2px\";\n\t this.meta.button.style.lineHeight = \"12px\";\n\t this.meta.button.style.fontSize = \"15px\";\n\t\n\t this.meta.button.style.cursor = \"pointer\";\n\t\n\t this.meta.button.addEventListener(\"mouseover\", function () {\n\t _this.meta.button.style.backgroundColor = _this.meta.colors.mediumDark;\n\t });\n\t this.meta.button.addEventListener(\"mouseleave\", function () {\n\t _this.meta.button.style.backgroundColor = _this.meta.colors.mediumLight;\n\t });\n\t this.meta.button.addEventListener(\"click\", function () {\n\t if (_this.meta.open) {\n\t _this.hide();\n\t } else {\n\t _this.show();\n\t }\n\t });\n\t\n\t this.meta.titleBar.appendChild(this.meta.button);\n\t\n\t this.meta.parent.appendChild(this.meta.titleBar);\n\t }\n\t this.meta.parent.appendChild(this.meta.contents);\n\t\n\t // var width = this.meta.parent.style.width = getComputedStyle(this.meta.parent).getPropertyValue('width');\n\t // this.meta.parent.style.width = width;\n\t\n\t var ui = transform.section(this.meta.target, this.meta.attribute);\n\t for (var key in ui) {\n\t this[key] = ui[key];\n\t }\n\t }\n\t },\n\t colorInterface: {\n\t value: function colorInterface() {\n\t if (this.meta.title) {\n\t this.meta.button.style.backgroundColor = this.meta.colors.mediumLight;\n\t this.meta.button.style.border = \"solid 0px \" + this.meta.colors.fill;\n\t this.meta.parent.style.border = \"solid 1px \" + this.meta.colors.mediumLight;\n\t this.meta.parent.style.backgroundColor = this.meta.colors.light;\n\t this.meta.titleBar.style.backgroundColor = this.meta.colors.fill;\n\t }\n\t }\n\t },\n\t show: {\n\t value: function show() {\n\t this.meta.contents.style.display = \"block\";\n\t this.meta.open = true;\n\t }\n\t },\n\t hide: {\n\t value: function hide() {\n\t this.meta.contents.style.display = \"none\";\n\t this.meta.open = false;\n\t }\n\t },\n\t colorize: {\n\t value: function colorize(type, color) {\n\t for (var key in this) {\n\t if (this[key].colorize) {\n\t this[key].colorize(type, color);\n\t }\n\t }\n\t this.meta.colors[type] = color;\n\t this.colorInterface();\n\t }\n\t },\n\t empty: {\n\t value: function empty() {\n\t for (var key in this) {\n\t if (this[key].destroy) {\n\t this[key].destroy();\n\t }\n\t }\n\t }\n\t }\n\t });\n\t\n\t return Rack;\n\t})();\n\t\n\tmodule.exports = Rack;\n\n/***/ }),\n/* 39 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\"use strict\";\n\t\n\tvar dom = _interopRequire(__webpack_require__(7));\n\t\n\tvar Interfaces = _interopRequire(__webpack_require__(2));\n\t\n\tvar createInterfaceID = function (widget, interfaceIDs) {\n\t var type = widget.type;\n\t if (interfaceIDs[type]) {\n\t interfaceIDs[type]++;\n\t } else {\n\t interfaceIDs[type] = 1;\n\t }\n\t return type + interfaceIDs[type];\n\t};\n\t\n\tvar element = function (element, type, options) {\n\t options = options || {};\n\t for (var i = 0; i < element.attributes.length; i++) {\n\t var att = element.attributes[i];\n\t // try {\n\t // options[att.nodeName] = eval(att.nodeValue);\n\t // } catch(e) {\n\t options[att.nodeName] = att.nodeValue;\n\t // }\n\t }\n\t type = type[0].toUpperCase() + type.slice(1);\n\t var widget = new Interfaces[type](element, options);\n\t widget.id = element.id;\n\t return widget;\n\t};\n\t\n\tvar section = function (parent, keyword) {\n\t\n\t keyword = keyword || \"nexus-ui\";\n\t\n\t var interfaceIDs = {};\n\t\n\t var container = dom.parseElement(parent);\n\t\n\t var ui = {};\n\t\n\t var htmlElements = container.getElementsByTagName(\"*\");\n\t var elements = [];\n\t for (var i = 0; i < htmlElements.length; i++) {\n\t elements.push(htmlElements[i]);\n\t }\n\t for (var i = 0; i < elements.length; i++) {\n\t var type = elements[i].getAttribute(keyword);\n\t if (type) {\n\t var formattedType = false;\n\t for (var key in Interfaces) {\n\t if (type.toLowerCase() === key.toLowerCase()) {\n\t formattedType = key;\n\t }\n\t }\n\t console.log(formattedType);\n\t var widget = element(elements[i], formattedType);\n\t if (widget.id) {\n\t ui[widget.id] = widget;\n\t } else {\n\t var id = createInterfaceID(widget, interfaceIDs);\n\t ui[id] = widget;\n\t }\n\t }\n\t }\n\t\n\t return ui;\n\t};\n\t\n\tvar add = function (type, parent, options) {\n\t var target = document.createElement(\"div\");\n\t options = options || {};\n\t if (parent) {\n\t parent = dom.parseElement(parent);\n\t } else {\n\t parent = document.body;\n\t }\n\t parent.appendChild(target);\n\t options.target = target;\n\t if (options.size) {\n\t target.style.width = options.size[0] + \"px\";\n\t target.style.height = options.size[1] + \"px\";\n\t }\n\t return element(target, type, options);\n\t};\n\t\n\texports.element = element;\n\texports.section = section;\n\texports.add = add;\n\n/***/ }),\n/* 40 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _interopRequire = function (obj) { return obj && obj.__esModule ? obj[\"default\"] : obj; };\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar math = _interopRequire(__webpack_require__(5));\n\t\n\tvar Tune = (function () {\n\t function Tune() {\n\t _classCallCheck(this, Tune);\n\t\n\t // the scale as ratios\n\t this.scale = [];\n\t\n\t // i/o modes\n\t this.mode = {\n\t output: \"frequency\",\n\t input: \"step\"\n\t };\n\t\n\t // ET major\n\t this.etmajor = [261.62558, 293.664764, 329.627563, 349.228241, 391.995422, 440, 493.883301, 523.25116];\n\t\n\t // Root frequency.\n\t this.root = math.mtof(60); // * Math.pow(2,(60-69)/12);\n\t\n\t // default is a major scale\n\t this.createScale(0, 2, 4, 5, 7, 9, 11);\n\t }\n\t\n\t _createClass(Tune, {\n\t note: {\n\t\n\t /* Return data in the mode you are in (freq, ratio, or midi) */\n\t\n\t value: function note(input, octave) {\n\t\n\t var newvalue = undefined;\n\t\n\t if (this.mode.output === \"frequency\") {\n\t newvalue = this.frequency(input, octave);\n\t } else if (this.mode.output === \"ratio\") {\n\t newvalue = this.ratio(input, octave);\n\t } else if (this.mode.output === \"MIDI\") {\n\t newvalue = this.MIDI(input, octave);\n\t } else {\n\t newvalue = this.frequency(input, octave);\n\t }\n\t\n\t return newvalue;\n\t }\n\t },\n\t frequency: {\n\t\n\t /* Return freq data */\n\t\n\t value: function frequency(stepIn, octaveIn) {\n\t\n\t if (this.mode.input === \"midi\" || this.mode.input === \"MIDI\") {\n\t this.stepIn += 60;\n\t }\n\t\n\t // what octave is our input\n\t var octave = Math.floor(stepIn / this.scale.length);\n\t\n\t if (octaveIn) {\n\t octave += octaveIn;\n\t }\n\t\n\t // which scale degree (0 - scale length) is our input\n\t var scaleDegree = stepIn % this.scale.length;\n\t\n\t while (scaleDegree < 0) {\n\t scaleDegree += this.scale.length;\n\t }\n\t\n\t var ratio = this.scale[scaleDegree];\n\t\n\t var freq = this.root * ratio;\n\t\n\t freq = freq * Math.pow(2, octave);\n\t\n\t // truncate irrational numbers\n\t freq = Math.floor(freq * 100000000000) / 100000000000;\n\t\n\t return freq;\n\t }\n\t },\n\t ratio: {\n\t\n\t /* Force return ratio data */\n\t\n\t value: function ratio(stepIn, octaveIn) {\n\t\n\t if (this.mode.input === \"midi\" || this.mode.input === \"MIDI\") {\n\t this.stepIn += 60;\n\t }\n\t\n\t // what octave is our input\n\t var octave = Math.floor(stepIn / this.scale.length);\n\t\n\t if (octaveIn) {\n\t octave += octaveIn;\n\t }\n\t\n\t // which scale degree (0 - scale length) is our input\n\t var scaleDegree = stepIn % this.scale.length;\n\t\n\t // what ratio is our input to our key\n\t var ratio = Math.pow(2, octave) * this.scale[scaleDegree];\n\t\n\t ratio = Math.floor(ratio * 100000000000) / 100000000000;\n\t\n\t return ratio;\n\t }\n\t },\n\t MIDI: {\n\t\n\t /* Force return adjusted MIDI data */\n\t\n\t value: function MIDI(stepIn, octaveIn) {\n\t\n\t var newvalue = this.frequency(stepIn, octaveIn);\n\t\n\t var n = 69 + 12 * Math.log(newvalue / 440) / Math.log(2);\n\t\n\t n = Math.floor(n * 1000000000) / 1000000000;\n\t\n\t return n;\n\t }\n\t },\n\t createScale: {\n\t value: function createScale() {\n\t var newScale = [];\n\t for (var i = 0; i < arguments.length; i++) {\n\t newScale.push(math.mtof(60 + arguments[i]));\n\t }\n\t this.loadScaleFromFrequencies(newScale);\n\t }\n\t },\n\t createJIScale: {\n\t value: function createJIScale() {\n\t this.scale = [];\n\t for (var i = 0; i < arguments.length; i++) {\n\t this.scale.push(arguments[i]);\n\t }\n\t }\n\t },\n\t loadScaleFromFrequencies: {\n\t value: function loadScaleFromFrequencies(freqs) {\n\t this.scale = [];\n\t for (var i = 0; i < freqs.length - 1; i++) {\n\t this.scale.push(freqs[i] / freqs[0]);\n\t }\n\t }\n\t },\n\t loadScale: {\n\t\n\t /* Load a new scale */\n\t\n\t value: function loadScale(name) {\n\t\n\t /* load the scale */\n\t var freqs = this.scales[name].frequencies;\n\t this.loadScaleFromFrequencies(freqs);\n\t }\n\t },\n\t search: {\n\t\n\t /* Search the names of tunings\n\t \t Returns an array of names of tunings */\n\t\n\t value: function search(letters) {\n\t var possible = [];\n\t for (var key in this.scales) {\n\t if (key.toLowerCase().indexOf(letters.toLowerCase()) !== -1) {\n\t possible.push(key);\n\t }\n\t }\n\t return possible;\n\t }\n\t },\n\t chord: {\n\t\n\t /* Return a collection of notes as an array */\n\t\n\t value: function chord(midis) {\n\t var output = [];\n\t for (var i = 0; i < midis.length; i++) {\n\t output.push(this.note(midis[i]));\n\t }\n\t return output;\n\t }\n\t }\n\t });\n\t\n\t return Tune;\n\t})();\n\t\n\tmodule.exports = Tune;\n\n/***/ }),\n/* 41 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\t//Disable jshint warning concerning trailing regular params\n\t/*jshint -W138 */\n\t\n\tvar Radio = (function () {\n\t //if non-existent buttons are switched, they are ignored\n\t\n\t function Radio() {\n\t for (var _len = arguments.length, onVals = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n\t onVals[_key - 1] = arguments[_key];\n\t }\n\t\n\t var length = arguments[0] === undefined ? 3 : arguments[0];\n\t\n\t _classCallCheck(this, Radio);\n\t\n\t //each optional 'onVals' argument switches on that value in the Radio if it exists\n\t //In the example below, a 3-button radio is created, index 0 is switched on, index 1 is switched on then then attempted again producing an warning, and the final argument produces a warning because the index value does not exist.\n\t //Example:\n\t //` radio = new Radio(3, 0, 1, 1, 3);\n\t //… [1,1,0]\n\t\n\t if (length < 0) {\n\t length = 1;\n\t }\n\t\n\t this.length = length;\n\t this.onVals = onVals;\n\t this.array = new Array(length).fill(0);\n\t\n\t if (onVals.length > 0) {\n\t this.on.apply(this, onVals);\n\t }\n\t }\n\t\n\t _createClass(Radio, {\n\t select: {\n\t value: function select(value) {\n\t this.array.fill(0);\n\t this.array[value] = 1;\n\t return this.array;\n\t }\n\t },\n\t flip: {\n\t value: function flip() {\n\t for (var _len = arguments.length, values = Array(_len), _key = 0; _key < _len; _key++) {\n\t values[_key] = arguments[_key];\n\t }\n\t\n\t //flips the specified values. if no value is specified, flips all buttons\n\t var a = this.array;\n\t if (values.length > 0) {\n\t values.forEach(function (v) {\n\t if (v > a.length - 1) {\n\t console.warn(\"Warning: AnonRadio[\" + v + \"] does not exist\");\n\t } else {\n\t a[v] = a[v] ? 0 : 1;\n\t }\n\t });\n\t } else {\n\t a.forEach(function (v, i, arr) {\n\t arr[i] = v ? 0 : 1;\n\t });\n\t }\n\t return a;\n\t }\n\t },\n\t on: {\n\t value: function on() {\n\t for (var _len = arguments.length, values = Array(_len), _key = 0; _key < _len; _key++) {\n\t values[_key] = arguments[_key];\n\t }\n\t\n\t //switch on the specified values. if no value specified, flips on all buttons\n\t var a = this.array;\n\t if (values.length > 0) {\n\t values.forEach(function (v) {\n\t if (v > a.length - 1) {\n\t console.warn(\"Warning: AnonRadio[\" + v + \"] exceeds size of object\");\n\t } else {\n\t if (a[v] === 1) {\n\t console.warn(\"Warning: AnonRadio[\" + v + \"] was already on.\");\n\t }\n\t a[v] = 1;\n\t }\n\t });\n\t } else {\n\t a.fill(1);\n\t }\n\t return a;\n\t }\n\t },\n\t off: {\n\t value: function off() {\n\t for (var _len = arguments.length, values = Array(_len), _key = 0; _key < _len; _key++) {\n\t values[_key] = arguments[_key];\n\t }\n\t\n\t //switch off the specified values. if no value specified, flips off all buttons\n\t var a = this.array;\n\t if (values.length > 0) {\n\t values.forEach(function (v) {\n\t a[v] = 0;\n\t });\n\t } else {\n\t a.fill(0);\n\t }\n\t return a;\n\t }\n\t }\n\t });\n\t\n\t return Radio;\n\t})();\n\t\n\tmodule.exports = Radio;\n\n/***/ }),\n/* 42 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar WAAClock = __webpack_require__(43)\n\t\n\tmodule.exports = WAAClock\n\tif (typeof window !== 'undefined') window.WAAClock = WAAClock\n\n\n/***/ }),\n/* 43 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(process) {var isBrowser = (typeof window !== 'undefined')\n\t\n\tvar CLOCK_DEFAULTS = {\n\t toleranceLate: 0.10,\n\t toleranceEarly: 0.001\n\t}\n\t\n\t// ==================== Event ==================== //\n\tvar Event = function(clock, deadline, func) {\n\t this.clock = clock\n\t this.func = func\n\t this._cleared = false // Flag used to clear an event inside callback\n\t\n\t this.toleranceLate = clock.toleranceLate\n\t this.toleranceEarly = clock.toleranceEarly\n\t this._latestTime = null\n\t this._earliestTime = null\n\t this.deadline = null\n\t this.repeatTime = null\n\t\n\t this.schedule(deadline)\n\t}\n\t\n\t// Unschedules the event\n\tEvent.prototype.clear = function() {\n\t this.clock._removeEvent(this)\n\t this._cleared = true\n\t return this\n\t}\n\t\n\t// Sets the event to repeat every `time` seconds.\n\tEvent.prototype.repeat = function(time) {\n\t if (time === 0)\n\t throw new Error('delay cannot be 0')\n\t this.repeatTime = time\n\t if (!this.clock._hasEvent(this))\n\t this.schedule(this.deadline + this.repeatTime)\n\t return this\n\t}\n\t\n\t// Sets the time tolerance of the event.\n\t// The event will be executed in the interval `[deadline - early, deadline + late]`\n\t// If the clock fails to execute the event in time, the event will be dropped.\n\tEvent.prototype.tolerance = function(values) {\n\t if (typeof values.late === 'number')\n\t this.toleranceLate = values.late\n\t if (typeof values.early === 'number')\n\t this.toleranceEarly = values.early\n\t this._refreshEarlyLateDates()\n\t if (this.clock._hasEvent(this)) {\n\t this.clock._removeEvent(this)\n\t this.clock._insertEvent(this)\n\t }\n\t return this\n\t}\n\t\n\t// Returns true if the event is repeated, false otherwise\n\tEvent.prototype.isRepeated = function() { return this.repeatTime !== null }\n\t\n\t// Schedules the event to be ran before `deadline`.\n\t// If the time is within the event tolerance, we handle the event immediately.\n\t// If the event was already scheduled at a different time, it is rescheduled.\n\tEvent.prototype.schedule = function(deadline) {\n\t this._cleared = false\n\t this.deadline = deadline\n\t this._refreshEarlyLateDates()\n\t\n\t if (this.clock.context.currentTime >= this._earliestTime) {\n\t this._execute()\n\t \n\t } else if (this.clock._hasEvent(this)) {\n\t this.clock._removeEvent(this)\n\t this.clock._insertEvent(this)\n\t \n\t } else this.clock._insertEvent(this)\n\t}\n\t\n\tEvent.prototype.timeStretch = function(tRef, ratio) {\n\t if (this.isRepeated())\n\t this.repeatTime = this.repeatTime * ratio\n\t\n\t var deadline = tRef + ratio * (this.deadline - tRef)\n\t // If the deadline is too close or past, and the event has a repeat,\n\t // we calculate the next repeat possible in the stretched space.\n\t if (this.isRepeated()) {\n\t while (this.clock.context.currentTime >= deadline - this.toleranceEarly)\n\t deadline += this.repeatTime\n\t }\n\t this.schedule(deadline)\n\t}\n\t\n\t// Executes the event\n\tEvent.prototype._execute = function() {\n\t if (this.clock._started === false) return\n\t this.clock._removeEvent(this)\n\t\n\t if (this.clock.context.currentTime < this._latestTime)\n\t this.func(this)\n\t else {\n\t if (this.onexpired) this.onexpired(this)\n\t console.warn('event expired')\n\t }\n\t // In the case `schedule` is called inside `func`, we need to avoid\n\t // overrwriting with yet another `schedule`.\n\t if (!this.clock._hasEvent(this) && this.isRepeated() && !this._cleared)\n\t this.schedule(this.deadline + this.repeatTime) \n\t}\n\t\n\t// Updates cached times\n\tEvent.prototype._refreshEarlyLateDates = function() {\n\t this._latestTime = this.deadline + this.toleranceLate\n\t this._earliestTime = this.deadline - this.toleranceEarly\n\t}\n\t\n\t// ==================== WAAClock ==================== //\n\tvar WAAClock = module.exports = function(context, opts) {\n\t var self = this\n\t opts = opts || {}\n\t this.tickMethod = opts.tickMethod || 'ScriptProcessorNode'\n\t this.toleranceEarly = opts.toleranceEarly || CLOCK_DEFAULTS.toleranceEarly\n\t this.toleranceLate = opts.toleranceLate || CLOCK_DEFAULTS.toleranceLate\n\t this.context = context\n\t this._events = []\n\t this._started = false\n\t}\n\t\n\t// ---------- Public API ---------- //\n\t// Schedules `func` to run after `delay` seconds.\n\tWAAClock.prototype.setTimeout = function(func, delay) {\n\t return this._createEvent(func, this._absTime(delay))\n\t}\n\t\n\t// Schedules `func` to run before `deadline`.\n\tWAAClock.prototype.callbackAtTime = function(func, deadline) {\n\t return this._createEvent(func, deadline)\n\t}\n\t\n\t// Stretches `deadline` and `repeat` of all scheduled `events` by `ratio`, keeping\n\t// their relative distance to `tRef`. In fact this is equivalent to changing the tempo.\n\tWAAClock.prototype.timeStretch = function(tRef, events, ratio) {\n\t events.forEach(function(event) { event.timeStretch(tRef, ratio) })\n\t return events\n\t}\n\t\n\t// Removes all scheduled events and starts the clock \n\tWAAClock.prototype.start = function() {\n\t if (this._started === false) {\n\t var self = this\n\t this._started = true\n\t this._events = []\n\t\n\t if (this.tickMethod === 'ScriptProcessorNode') {\n\t var bufferSize = 256\n\t // We have to keep a reference to the node to avoid garbage collection\n\t this._clockNode = this.context.createScriptProcessor(bufferSize, 1, 1)\n\t this._clockNode.connect(this.context.destination)\n\t this._clockNode.onaudioprocess = function () {\n\t process.nextTick(function() { self._tick() })\n\t }\n\t } else if (this.tickMethod === 'manual') null // _tick is called manually\n\t\n\t else throw new Error('invalid tickMethod ' + this.tickMethod)\n\t }\n\t}\n\t\n\t// Stops the clock\n\tWAAClock.prototype.stop = function() {\n\t if (this._started === true) {\n\t this._started = false\n\t this._clockNode.disconnect()\n\t } \n\t}\n\t\n\t// ---------- Private ---------- //\n\t\n\t// This function is ran periodically, and at each tick it executes\n\t// events for which `currentTime` is included in their tolerance interval.\n\tWAAClock.prototype._tick = function() {\n\t var event = this._events.shift()\n\t\n\t while(event && event._earliestTime <= this.context.currentTime) {\n\t event._execute()\n\t event = this._events.shift()\n\t }\n\t\n\t // Put back the last event\n\t if(event) this._events.unshift(event)\n\t}\n\t\n\t// Creates an event and insert it to the list\n\tWAAClock.prototype._createEvent = function(func, deadline) {\n\t return new Event(this, deadline, func)\n\t}\n\t\n\t// Inserts an event to the list\n\tWAAClock.prototype._insertEvent = function(event) {\n\t this._events.splice(this._indexByTime(event._earliestTime), 0, event)\n\t}\n\t\n\t// Removes an event from the list\n\tWAAClock.prototype._removeEvent = function(event) {\n\t var ind = this._events.indexOf(event)\n\t if (ind !== -1) this._events.splice(ind, 1)\n\t}\n\t\n\t// Returns true if `event` is in queue, false otherwise\n\tWAAClock.prototype._hasEvent = function(event) {\n\t return this._events.indexOf(event) !== -1\n\t}\n\t\n\t// Returns the index of the first event whose deadline is >= to `deadline`\n\tWAAClock.prototype._indexByTime = function(deadline) {\n\t // performs a binary search\n\t var low = 0\n\t , high = this._events.length\n\t , mid\n\t while (low < high) {\n\t mid = Math.floor((low + high) / 2)\n\t if (this._events[mid]._earliestTime < deadline)\n\t low = mid + 1\n\t else high = mid\n\t }\n\t return low\n\t}\n\t\n\t// Converts from relative time to absolute time\n\tWAAClock.prototype._absTime = function(relTime) {\n\t return relTime + this.context.currentTime\n\t}\n\t\n\t// Converts from absolute time to relative time \n\tWAAClock.prototype._relTime = function(absTime) {\n\t return absTime - this.context.currentTime\n\t}\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(44)))\n\n/***/ }),\n/* 44 */\n/***/ (function(module, exports) {\n\n\t// shim for using process in browser\n\tvar process = module.exports = {};\n\t\n\t// cached from whatever global is present so that test runners that stub it\n\t// don't break things. But we need to wrap it in a try catch in case it is\n\t// wrapped in strict mode code which doesn't define any globals. It's inside a\n\t// function because try/catches deoptimize in certain engines.\n\t\n\tvar cachedSetTimeout;\n\tvar cachedClearTimeout;\n\t\n\tfunction defaultSetTimout() {\n\t throw new Error('setTimeout has not been defined');\n\t}\n\tfunction defaultClearTimeout () {\n\t throw new Error('clearTimeout has not been defined');\n\t}\n\t(function () {\n\t try {\n\t if (typeof setTimeout === 'function') {\n\t cachedSetTimeout = setTimeout;\n\t } else {\n\t cachedSetTimeout = defaultSetTimout;\n\t }\n\t } catch (e) {\n\t cachedSetTimeout = defaultSetTimout;\n\t }\n\t try {\n\t if (typeof clearTimeout === 'function') {\n\t cachedClearTimeout = clearTimeout;\n\t } else {\n\t cachedClearTimeout = defaultClearTimeout;\n\t }\n\t } catch (e) {\n\t cachedClearTimeout = defaultClearTimeout;\n\t }\n\t} ())\n\tfunction runTimeout(fun) {\n\t if (cachedSetTimeout === setTimeout) {\n\t //normal enviroments in sane situations\n\t return setTimeout(fun, 0);\n\t }\n\t // if setTimeout wasn't available but was latter defined\n\t if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n\t cachedSetTimeout = setTimeout;\n\t return setTimeout(fun, 0);\n\t }\n\t try {\n\t // when when somebody has screwed with setTimeout but no I.E. maddness\n\t return cachedSetTimeout(fun, 0);\n\t } catch(e){\n\t try {\n\t // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n\t return cachedSetTimeout.call(null, fun, 0);\n\t } catch(e){\n\t // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n\t return cachedSetTimeout.call(this, fun, 0);\n\t }\n\t }\n\t\n\t\n\t}\n\tfunction runClearTimeout(marker) {\n\t if (cachedClearTimeout === clearTimeout) {\n\t //normal enviroments in sane situations\n\t return clearTimeout(marker);\n\t }\n\t // if clearTimeout wasn't available but was latter defined\n\t if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n\t cachedClearTimeout = clearTimeout;\n\t return clearTimeout(marker);\n\t }\n\t try {\n\t // when when somebody has screwed with setTimeout but no I.E. maddness\n\t return cachedClearTimeout(marker);\n\t } catch (e){\n\t try {\n\t // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n\t return cachedClearTimeout.call(null, marker);\n\t } catch (e){\n\t // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n\t // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n\t return cachedClearTimeout.call(this, marker);\n\t }\n\t }\n\t\n\t\n\t\n\t}\n\tvar queue = [];\n\tvar draining = false;\n\tvar currentQueue;\n\tvar queueIndex = -1;\n\t\n\tfunction cleanUpNextTick() {\n\t if (!draining || !currentQueue) {\n\t return;\n\t }\n\t draining = false;\n\t if (currentQueue.length) {\n\t queue = currentQueue.concat(queue);\n\t } else {\n\t queueIndex = -1;\n\t }\n\t if (queue.length) {\n\t drainQueue();\n\t }\n\t}\n\t\n\tfunction drainQueue() {\n\t if (draining) {\n\t return;\n\t }\n\t var timeout = runTimeout(cleanUpNextTick);\n\t draining = true;\n\t\n\t var len = queue.length;\n\t while(len) {\n\t currentQueue = queue;\n\t queue = [];\n\t while (++queueIndex < len) {\n\t if (currentQueue) {\n\t currentQueue[queueIndex].run();\n\t }\n\t }\n\t queueIndex = -1;\n\t len = queue.length;\n\t }\n\t currentQueue = null;\n\t draining = false;\n\t runClearTimeout(timeout);\n\t}\n\t\n\tprocess.nextTick = function (fun) {\n\t var args = new Array(arguments.length - 1);\n\t if (arguments.length > 1) {\n\t for (var i = 1; i < arguments.length; i++) {\n\t args[i - 1] = arguments[i];\n\t }\n\t }\n\t queue.push(new Item(fun, args));\n\t if (queue.length === 1 && !draining) {\n\t runTimeout(drainQueue);\n\t }\n\t};\n\t\n\t// v8 likes predictible objects\n\tfunction Item(fun, array) {\n\t this.fun = fun;\n\t this.array = array;\n\t}\n\tItem.prototype.run = function () {\n\t this.fun.apply(null, this.array);\n\t};\n\tprocess.title = 'browser';\n\tprocess.browser = true;\n\tprocess.env = {};\n\tprocess.argv = [];\n\tprocess.version = ''; // empty string to avoid regexp issues\n\tprocess.versions = {};\n\t\n\tfunction noop() {}\n\t\n\tprocess.on = noop;\n\tprocess.addListener = noop;\n\tprocess.once = noop;\n\tprocess.off = noop;\n\tprocess.removeListener = noop;\n\tprocess.removeAllListeners = noop;\n\tprocess.emit = noop;\n\tprocess.prependListener = noop;\n\tprocess.prependOnceListener = noop;\n\t\n\tprocess.listeners = function (name) { return [] }\n\t\n\tprocess.binding = function (name) {\n\t throw new Error('process.binding is not supported');\n\t};\n\t\n\tprocess.cwd = function () { return '/' };\n\tprocess.chdir = function (dir) {\n\t throw new Error('process.chdir is not supported');\n\t};\n\tprocess.umask = function() { return 0; };\n\n\n/***/ }),\n/* 45 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tvar _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\t\n\tvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\t\n\tvar clock = __webpack_require__(1).clock;\n\t\n\tvar Interval = (function () {\n\t function Interval(rate, func, on) {\n\t _classCallCheck(this, Interval);\n\t\n\t this.rate = rate;\n\t this.on = on;\n\t this.clock = clock(); // jshint ignore:line\n\t\n\t this.pattern = [1];\n\t this.index = 0;\n\t\n\t this.event = func ? func : function () {};\n\t\n\t if (this.on) {\n\t this.start();\n\t }\n\t }\n\t\n\t _createClass(Interval, {\n\t _event: {\n\t value: function _event(e) {\n\t // if (this.pattern[this.index%this.pattern.length]) {\n\t this.event(e);\n\t // }\n\t this.index++;\n\t }\n\t },\n\t stop: {\n\t value: function stop() {\n\t this.on = false;\n\t this.interval.clear();\n\t }\n\t },\n\t start: {\n\t value: function start() {\n\t this.on = true;\n\t this.interval = this.clock.callbackAtTime(this._event.bind(this), this.clock.context.currentTime).repeat(this.rate / 1000).tolerance({ early: 0.1, late: 1 });\n\t }\n\t },\n\t ms: {\n\t value: function ms(newrate) {\n\t if (this.on) {\n\t var ratio = newrate / this.rate;\n\t this.rate = newrate;\n\t this.clock.timeStretch(this.clock.context.currentTime, [this.interval], ratio);\n\t } else {\n\t this.rate = newrate;\n\t }\n\t }\n\t }\n\t });\n\t\n\t return Interval;\n\t})();\n\t\n\tmodule.exports = Interval;\n\n/***/ })\n/******/ ])\n});\n;\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovLy93ZWJwYWNrL2Jvb3RzdHJhcCBiMjY5YWNlZjhjYWRhNzA4NDUwMiIsIndlYnBhY2s6Ly8vLi9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvbWFpbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9wb3NpdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC9zdmcuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwvbWF0aC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvY29yZS9pbnRlcmZhY2UuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwvZG9tLmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsL3V0aWwuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwvdG91Y2guanMiLCJ3ZWJwYWNrOi8vLy4vfi9ldmVudHMvZXZlbnRzLmpzIiwid2VicGFjazovLy8uL2xpYi9tb2RlbHMvc3RlcC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC9pbnRlcmFjdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvbW9kZWxzL3RvZ2dsZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zbGlkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2ludGVyZmFjZXMvdG9nZ2xlLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL2J1dHRvbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvY29tcG9uZW50cy9idXR0b250ZW1wbGF0ZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy90ZXh0YnV0dG9uLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL3JhZGlvYnV0dG9uLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL251bWJlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zZWxlY3QuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2ludGVyZmFjZXMvZGlhbC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9waWFuby5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zZXF1ZW5jZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21vZGVscy9tYXRyaXguanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21vZGVscy9zZXF1ZW5jZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvbW9kZWxzL2RydW5rLmpzIiwid2VicGFjazovLy8uL2xpYi9tb2RlbHMvY291bnRlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9wYW4yZC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy90aWx0LmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL211bHRpc2xpZGVyLmpzIiwid2VicGFjazovLy8uL2xpYi9jb21wb25lbnRzL3NsaWRlcnRlbXBsYXRlLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL3Bhbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9lbnZlbG9wZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zcGVjdHJvZ3JhbS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9tZXRlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9vc2NpbGxvc2NvcGUuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2NvcmUvcmFjay5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC90cmFuc2Zvcm0uanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3R1bmluZy90dW5pbmcuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21vZGVscy9yYWRpby5qcyIsIndlYnBhY2s6Ly8vLi9+L3dhYWNsb2NrL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vd2FhY2xvY2svbGliL1dBQUNsb2NrLmpzIiwid2VicGFjazovLy8uL34vcHJvY2Vzcy9icm93c2VyLmpzIiwid2VicGFjazovLy8uL2xpYi90aW1lL2ludGVydmFsLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRCxPO0FDVkE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQWU7QUFDZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7OztBQ3RDQSxhQUFZLENBQUM7Ozs7S0FFTixPQUFPLHVDQUFNLENBQVk7O2tCQUVqQixPQUFPLEM7Ozs7Ozs7Ozs7Ozs7Ozs7U0NtSE4sTUFBTSxHQUFOLE1BQU07U0FHTixPQUFPLEdBQVAsT0FBTztTQUdQLEtBQUssR0FBTCxLQUFLOzs7O0FBN0hyQixhQUFZLENBQUM7O0tBRU4sVUFBVSx1Q0FBTSxDQUFlOztLQUMvQixJQUFJLHVDQUFNLENBQWE7O0tBQ3ZCLElBQUksdUNBQU0sRUFBYTs7S0FDdkIsSUFBSSx1Q0FBTSxFQUFpQjs7S0FDdEIsU0FBUywrQ0FBTSxFQUFrQjs7QUFFN0MsS0FBSSxPQUFPLEdBQUcsbUJBQU8sQ0FBQyxFQUFrQixDQUFDLENBQUM7QUFDMUMsS0FBSSxLQUFLLEdBQUcsbUJBQU8sQ0FBQyxFQUFnQixDQUFDLENBQUM7QUFDdEMsS0FBSSxLQUFLLEdBQUcsbUJBQU8sQ0FBQyxFQUFnQixDQUFDLENBQUM7QUFDdEMsS0FBSSxRQUFRLEdBQUcsbUJBQU8sQ0FBQyxFQUFtQixDQUFDLENBQUM7QUFDNUMsS0FBSSxNQUFNLEdBQUcsbUJBQU8sQ0FBQyxFQUFpQixDQUFDLENBQUM7O0tBRWpDLFFBQVEsdUNBQU0sRUFBVTs7S0FDeEIsUUFBUSx1Q0FBTSxFQUFpQjs7Ozs7O0tBT2hDLE9BQU87QUFFRSxZQUZULE9BQU8s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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxnQkFBZSxTQUFTO0FBQ3hCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxJQUFHO0FBQ0gscUJBQW9CLFNBQVM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7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QUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNsRSxhQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7O0FBRWxFLGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN2QyxhQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDdkMsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDOztBQUV2QyxhQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDbkUsYUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ25FLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzs7QUFFbkUsYUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3hDLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN4QyxhQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7O0FBR3hDLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxJQUFJLENB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Q0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ25ELGVBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ25ELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1VBQ25ELE1BQU07QUFDTCxlQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDdEQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDNUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDNUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDNUQsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekQsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekQsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7VUFDekQ7UUFFRjs7QUFFRCxXQUFNO2NBQUEsZ0JBQUMsQ0FBQyxFQUFFO0FBQ1IsYUFBSSxJQUFJLENBQUMsT0FBTyxFQUFDOztBQUVmLGVBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDZixlQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ2hCLGVBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUM7OztBQUdoQixZQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFFLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixZQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFFLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixZQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLEdBQUcsRUFBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRzVCLGVBQUksWUFBWSxHQUFHO0FBQ2pCLGtCQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHO0FBQ2xCLGdCQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQyxDQUFDLEVBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxDQUFDLEVBQUcsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLENBQUU7WUFDekYsQ0FBQztBQUNGLGVBQUksYUFBYSxHQUFHO0FBQ2xCLGtCQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHO0FBQ2xCLGdCQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQyxHQUFHLEVBQUMsQ0FBQyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxDQUFDLEVBQUcsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLENBQUU7WUFDekYsQ0FBQzs7QUFFRixlQUFJLFVBQVUsR0FBRyxHQUFHLENBQUMsR0FB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QUFJLENBQUMsSUFBSSxDQUFDLEtBQUcsQ0FBQyxHQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDOztBQUVuQyxTQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBRSxDQUFDLEVBQUU7O0FBRXhDLFdBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBQyxDQUFDLENBQUM7QUFDcEQsV0FBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFDLENBQUMsQ0FBQzs7QUFFcEQsV0FBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDOUMsV0FBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7O0FBRTlDLFdBQUksSUFBSSxHQUFHLFNBQVMsSUFBSSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0MsV0FBSSxLQUFLLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7QUFFcEUsV0FBSSxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRTtBQUFFLGFBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQUU7QUFDckMsV0FBSSxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssRUFBRTtBQUFFLGFBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQUU7TUFFeEM7O0FBRUQsU0FBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDdEMsU0FBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFR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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQ0FBeUM7O0FBRXpDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsSUFBRztBQUNIO0FBQ0E7O0FBRUEsSUFBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBa0MsaUNBQWlDO0FBQ25FO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFxQyxlQUFlO0FBQ3BEO0FBQ0EsTUFBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEk7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7Ozs7QUN6T0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQSxFQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdCQUF1QixzQkFBc0I7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBcUI7QUFDckI7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNDQUFxQzs7QUFFckM7QUFDQTtBQUNBOztBQUVBLDRCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQSw2QkFBNEIsVUFBVTs7Ozs7OztBQ3ZMdEMsYUFBWSxDQUFDOzs7Ozs7S0FFSixLQUFLLHVCQUFRLENBQVMsRUFBdEIsS0FBSzs7S0FFTyxRQUFRO0FBRWhCLFlBRlEsUUFBUSxDQUVmLElBQUksRUFBQyxJQUFJLEVBQUMsRUFBRSxFQUFFOzJCQUZQLFFBQVE7O0FBSXpCLFNBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ2pCLFNBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2IsU0FBSSxDQUFDLEtBQUssR0FBRyxLQUFLLEVBQUUsQ0FBQzs7QUFFckIsU0FBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25CLFNBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDOztBQUVmLFNBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxZQUFXLEVBQUcsQ0FBQzs7QUFFMUMsU0FBSSxJQUFJLENBQUMsRUFBRSxFQUFFO0FBQ1gsV0FBSSxDQUFDLEtBQUssRUFBRSxDQUFDO01BQ2Q7SUFFRjs7Z0JBakJrQixRQUFRO0FBbUIzQixXQUFNO2NBQUEsZ0JBQUMsQ0FBQyxFQUFFOztBQUVOLGFBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRWhCLGFBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNkOztBQUVELFNBQUk7Y0FBQSxnQkFBRztBQUNMLGFBQUksQ0FBQyxFQUFFLEdBQUcsS0FBSyxDQUFDO0FBQ2hCLGFBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkI7O0FBRUQsVUFBSztjQUFBLGlCQUFHO0FBQ04sYUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDZixhQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7UUFDMUo7O0FBRUQsT0FBRTtjQUFBLFlBQUMsT0FBTyxFQUFFO0FBQ1YsYUFBSSxJQUFJLENBQUMsRUFBRSxFQUFFO0FBQ1gsZUFBSSxLQUFLLEdBQUcsT0FBTyxHQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDOUIsZUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7QUFDcEIsZUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1VBQ2hGLE1BQU07QUFDTCxlQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQztVQUNyQjtRQUNGOzs7O1VBNUNrQixRQUFROzs7a0JBQVIsUUFBUSxDIiwiZmlsZSI6Ii4vZGlzdC9OZXh1c1VJLmpzIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wiTmV4dXNcIl0gPSBmYWN0b3J5KCk7XG5cdGVsc2Vcblx0XHRyb290W1wiTmV4dXNcIl0gPSBmYWN0b3J5KCk7XG59KSh0aGlzLCBmdW5jdGlvbigpIHtcbnJldHVybiBcblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pXG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG5cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGV4cG9ydHM6IHt9LFxuIFx0XHRcdGlkOiBtb2R1bGVJZCxcbiBcdFx0XHRsb2FkZWQ6IGZhbHNlXG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oMCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay9ib290c3RyYXAgYjI2OWFjZWY4Y2FkYTcwODQ1MDIiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBOZXh1c1VJIGZyb20gJy4vbGliL21haW4nO1xuXG5leHBvcnQgZGVmYXVsdCBOZXh1c1VJO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vaW5kZXguanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBJbnRlcmZhY2VzIGZyb20gJy4vaW50ZXJmYWNlcy8nO1xuaW1wb3J0IG1hdGggZnJvbSAnLi91dGlsL21hdGgnO1xuaW1wb3J0IFJhY2sgZnJvbSAnLi9jb3JlL3JhY2snO1xuaW1wb3J0IFR1bmUgZnJvbSAnLi90dW5pbmcvdHVuaW5nJztcbmltcG9ydCAqIGFzIFRyYW5zZm9ybSBmcm9tICcuL3V0aWwvdHJhbnNmb3JtJztcblxubGV0IENvdW50ZXIgPSByZXF1aXJlKCcuL21vZGVscy9jb3VudGVyJyk7XG5sZXQgUmFkaW8gPSByZXF1aXJlKCcuL21vZGVscy9yYWRpbycpO1xubGV0IERydW5rID0gcmVxdWlyZSgnLi9tb2RlbHMvZHJ1bmsnKTtcbmxldCBTZXF1ZW5jZSA9IHJlcXVpcmUoJy4vbW9kZWxzL3NlcXVlbmNlJyk7XG5sZXQgTWF0cml4ID0gcmVxdWlyZSgnLi9tb2RlbHMvbWF0cml4Jyk7XG5cbmltcG9ydCBXQUFDbG9jayBmcm9tICd3YWFjbG9jayc7XG5pbXBvcnQgSW50ZXJ2YWwgZnJvbSAnLi90aW1lL2ludGVydmFsJztcblxuXG4vKipcbk5leHVzVUkgPT4gY3JlYXRlZCBhcyBOZXh1c1xuKi9cblxuY2xhc3MgTmV4dXNVSSB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0KSB7XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIEludGVyZmFjZXMpIHtcbiAgICAgICAgICAgIHRoaXNba2V5XSA9IEludGVyZmFjZXNba2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGtleSBpbiBtYXRoKSB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSBtYXRoW2tleV07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgQ29yZSA9IHtcbiAgICAgICAgICAnUmFjayc6IFJhY2tcbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgTW9kZWxzID0ge1xuICAgICAgICAgICdDb3VudGVyJzogQ291bnRlcixcbiAgICAgICAgICAnUmFkaW8nOiBSYWRpbyxcbiAgICAgICAgICAnRHJ1bmsnOiBEcnVuayxcbiAgICAgICAgICAnU2VxdWVuY2UnOiBTZXF1ZW5jZSxcbiAgICAgICAgICAnTWF0cml4JzogTWF0cml4XG4gICAgICAgIH07XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIE1vZGVscykge1xuICAgICAgICAgIHRoaXNba2V5XSA9IE1vZGVsc1trZXldO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIENvcmUpIHtcbiAgICAgICAgICB0aGlzW2tleV0gPSBDb3JlW2tleV07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgRGVmYXVsdENvbnRleHQgPSB3aW5kb3cuQXVkaW9Db250ZXh0IHx8IHdpbmRvdy53ZWJraXRBdWRpb0NvbnRleHQ7XG4gICAgICAgIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0IHx8IG5ldyBEZWZhdWx0Q29udGV4dCgpO1xuXG4gICAgICAgIHRoaXMudHVuZSA9IG5ldyBUdW5lKCk7XG4gICAgICAgIHRoaXMubm90ZSA9IHRoaXMudHVuZS5ub3RlLmJpbmQodGhpcy50dW5lKTtcblxuICAgICAgICB0aGlzLmNsb2NrID0gbmV3IFdBQUNsb2NrKHRoaXMuX2NvbnRleHQpO1xuICAgICAgICB0aGlzLmNsb2NrLnN0YXJ0KCk7XG4gICAgICAgIHRoaXMuSW50ZXJ2YWwgPSBJbnRlcnZhbDtcblxuICAgICAgICB0aGlzLmNvbG9ycyA9IHtcbiAgICAgICAgICBhY2NlbnQ6ICcjMmJiJyxcbiAgICAgICAgICBmaWxsOiAnI2VlZScsXG4gICAgICAgICAgbGlnaHQ6ICcjZmZmJyxcbiAgICAgICAgICBkYXJrOiAnIzMzMycsXG4gICAgICAgICAgbWVkaXVtTGlnaHQ6ICcjY2NjJyxcbiAgICAgICAgICBtZWRpdW1EYXJrOiAnIzY2NidcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnRyYW5zZm9ybSA9IFRyYW5zZm9ybTtcbiAgICAgICAgdGhpcy5hZGQgPSBUcmFuc2Zvcm0uYWRkO1xuXG5cbiAgICAgICAgdGhpcy5BZGQgPSB7fTtcbiAgICAgICAgZm9yIChsZXQga2V5IGluIEludGVyZmFjZXMpIHtcbiAgICAgICAgICB0aGlzLkFkZFtrZXldID0gVHJhbnNmb3JtLmFkZC5iaW5kKHRoaXMsa2V5KTtcbiAgICAgICAgfVxuXG5cblxuXG4gICAgICAgIC8qIGNyZWF0ZSBkZWZhdWx0IGNvbXBvbmVudCBzaXplICovXG4gICAgICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICAgICAgdmFyIGV4aXN0aW5nU3R5bGVzaGVldHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcInN0eWxlXCIpO1xuICAgICAgICB2YXIgZGVmYXVsdFNpemVEZWNsYXJhdGlvbiA9ICdbbmV4dXMtdWlde2hlaWdodDo1MDAwcHg7d2lkdGg6NTAwMHB4fSc7XG4gICAgICAgIHZhciBkZWZhdWx0U3R5bGVOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICAgICAgZGVmYXVsdFN0eWxlTm9kZS50eXBlID0gJ3RleHQvY3NzJztcbiAgICAgICAgZGVmYXVsdFN0eWxlTm9kZS5pbm5lckhUTUwgPSBkZWZhdWx0U2l6ZURlY2xhcmF0aW9uO1xuICAgICAgICBpZiAoZXhpc3RpbmdTdHlsZXNoZWV0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdmFyIHBhcmVudCA9IGV4aXN0aW5nU3R5bGVzaGVldHNbMF0ucGFyZW50Tm9kZVxuICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoIGRlZmF1bHRTdHlsZU5vZGUsIGV4aXN0aW5nU3R5bGVzaGVldHNbMF0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoJzxzdHlsZT4nK2RlZmF1bHRTaXplRGVjbGFyYXRpb24rJzxcXC9zdHlsZT4nKTtcbiAgICAgICAgfVxuICAgICAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG4gICAgfVxuXG4gICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY29udGV4dDtcbiAgICB9XG5cbiAgICBzZXQgY29udGV4dChjdHgpIHtcbiAgICAgIHRoaXMuY2xvY2suc3RvcCgpO1xuICAgICAgdGhpcy5fY29udGV4dCA9IGN0eDtcbiAgICAgIHRoaXMuY2xvY2sgPSBuZXcgV0FBQ2xvY2sodGhpcy5jb250ZXh0KTtcbiAgICAgIHRoaXMuY2xvY2suc3RhcnQoKTtcbiAgICB9XG5cblxuXG59XG5cbmxldCBOZXh1cyA9IG5ldyBOZXh1c1VJKCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBjb2xvcnMoKSB7XG4gICAgcmV0dXJuIE5leHVzLmNvbG9ycztcbn1cbmV4cG9ydCBmdW5jdGlvbiBjb250ZXh0KCkge1xuICAgIHJldHVybiBOZXh1cy5jb250ZXh0O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNsb2NrKCkge1xuICAgIHJldHVybiBOZXh1cy5jbG9jaztcbn1cblxuZXhwb3J0IGRlZmF1bHQgTmV4dXM7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbWFpbi5qcyIsImV4cG9ydCBkZWZhdWx0IHtcbiAgUG9zaXRpb246IHJlcXVpcmUoJy4vcG9zaXRpb24nKSxcbiAgU2xpZGVyOiByZXF1aXJlKCcuL3NsaWRlcicpLFxuICBUb2dnbGU6IHJlcXVpcmUoJy4vdG9nZ2xlJyksXG4vKiAgUmFuZ2U6IHJlcXVpcmUoJy4vcmFuZ2VzbGlkZXInKSxcbiAgV2F2ZWZvcm06IHJlcXVpcmUoJy4vd2F2ZWZvcm0nKSwgKi9cbiAgQnV0dG9uOiByZXF1aXJlKCcuL2J1dHRvbicpLFxuICBUZXh0QnV0dG9uOiByZXF1aXJlKCcuL3RleHRidXR0b24nKSxcbiAgUmFkaW9CdXR0b246IHJlcXVpcmUoJy4vcmFkaW9idXR0b24nKSxcbiAgTnVtYmVyOiByZXF1aXJlKCcuL251bWJlcicpLFxuICBTZWxlY3Q6IHJlcXVpcmUoJy4vc2VsZWN0JyksXG4gIERpYWw6IHJlcXVpcmUoJy4vZGlhbCcpLFxuICBQaWFubzogcmVxdWlyZSgnLi9waWFubycpLFxuICBTZXF1ZW5jZXI6IHJlcXVpcmUoJy4vc2VxdWVuY2VyJyksXG4gIFBhbjJEOiByZXF1aXJlKCcuL3BhbjJkJyksXG4gIFRpbHQ6IHJlcXVpcmUoJy4vdGlsdCcpLFxuICBNdWx0aXNsaWRlcjogcmVxdWlyZSgnLi9tdWx0aXNsaWRlcicpLFxuICBQYW46IHJlcXVpcmUoJy4vcGFuJyksXG4gIEVudmVsb3BlOiByZXF1aXJlKCcuL2VudmVsb3BlJyksXG4gIFNwZWN0cm9ncmFtOiByZXF1aXJlKCcuL3NwZWN0cm9ncmFtJyksXG4gIE1ldGVyOiByZXF1aXJlKCcuL21ldGVyJyksXG4gIE9zY2lsbG9zY29wZTogcmVxdWlyZSgnLi9vc2NpbGxvc2NvcGUnKVxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL2luZGV4LmpzIiwiXG4ndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgU3RlcCA9IHJlcXVpcmUoJy4uL21vZGVscy9zdGVwJyk7XG5pbXBvcnQgKiBhcyBJbnRlcmFjdGlvbiBmcm9tICcuLi91dGlsL2ludGVyYWN0aW9uJztcblxuLyoqXG4qIFBvc2l0aW9uXG4qXG4qIEBkZXNjcmlwdGlvbiBUd28tZGltZW5zaW9uYWwgdG91Y2ggc2xpZGVyLlxuKlxuKiBAZGVtbyA8c3BhbiBuZXh1cy11aT1cInBvc2l0aW9uXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcG9zaXRpb24gPSBuZXcgTmV4dXMuUG9zaXRpb24oJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcG9zaXRpb24gPSBuZXcgTmV4dXMuUG9zaXRpb24oJyN0YXJnZXQnLHtcbiogICAnc2l6ZSc6IFsyMDAsMjAwXSxcbiogICAnbW9kZSc6ICdhYnNvbHV0ZScsICAvLyBcImFic29sdXRlXCIgb3IgXCJyZWxhdGl2ZVwiXG4qICAgJ3gnOiAwLjUsICAvLyBpbml0aWFsIHggdmFsdWVcbiogICAnbWluWCc6IDAsXG4qICAgJ21heFgnOiAxLFxuKiAgICdzdGVwWCc6IDAsXG4qICAgJ3knOiAwLjUsICAvLyBpbml0aWFsIHkgdmFsdWVcbiogICAnbWluWSc6IDAsXG4qICAgJ21heFknOiAxLFxuKiAgICdzdGVwWSc6IDBcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgaXMgYW4gb2JqZWN0IHdpdGggeCBhbmQgeSBwcm9wZXJ0aWVzIGNvbnRhaW5pbmcgdGhlIHggYW5kIHkgdmFsdWVzIG9mIHRoZSBpbnRlcmZhY2UuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIHBvc2l0aW9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBvc2l0aW9uIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMjAwLDIwMF0sXG4gICAgICAnbW9kZSc6ICdhYnNvbHV0ZScsXG4gICAgICAnbWluWCc6IDAsXG4gICAgICAnbWF4WCc6IDEsXG4gICAgICAnc3RlcFgnOiAwLFxuICAgICAgJ3gnOiAwLjUsXG4gICAgICAnbWluWSc6IDAsXG4gICAgICAnbWF4WSc6IDEsXG4gICAgICAnc3RlcFknOiAwLFxuICAgICAgJ3knOiAwLjVcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG5cbiAgICB0aGlzLl94ID0gbmV3IFN0ZXAoIHRoaXMuc2V0dGluZ3MubWluWCwgdGhpcy5zZXR0aW5ncy5tYXhYLCB0aGlzLnNldHRpbmdzLnN0ZXBYLCB0aGlzLnNldHRpbmdzLnggKTtcbiAgICB0aGlzLl95ID0gbmV3IFN0ZXAoIHRoaXMuc2V0dGluZ3MubWluWSwgdGhpcy5zZXR0aW5ncy5tYXhZLCB0aGlzLnNldHRpbmdzLnN0ZXBZLCB0aGlzLnNldHRpbmdzLnkgKTtcblxuICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICB4OiBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMuc2V0dGluZ3MubW9kZSwnaG9yaXpvbnRhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKSxcbiAgICAgIHk6IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLCd2ZXJ0aWNhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKVxuICAgIH07XG4gICAgdGhpcy5wb3NpdGlvbi54LnZhbHVlID0gdGhpcy5feC5ub3JtYWxpemVkO1xuICAgIHRoaXMucG9zaXRpb24ueS52YWx1ZSA9IHRoaXMuX3kubm9ybWFsaXplZDtcblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG4gICAgXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgICB0aGlzLnBvc2l0aW9uLngucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG4gICAgICB0aGlzLnBvc2l0aW9uLnkucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG5cbiAgICAgIHRoaXMuX21pbkRpbWVuc2lvbiA9IE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpO1xuXG4gICAgICB0aGlzLmtub2JSYWRpdXMgPSB7XG4gICAgICAgIG9mZjogfn4odGhpcy5fbWluRGltZW5zaW9uLzEwMCkgKiA1ICsgNSxcbiAgICAgIH07XG4gICAgICB0aGlzLmtub2JSYWRpdXMub24gPSB0aGlzLmtub2JSYWRpdXMub2ZmICogMjtcblxuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMud2lkdGgvMik7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQvMik7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JSYWRpdXMub2ZmKTtcbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAodGhpcy5jbGlja2VkKSB7XG4gICAgLy8gIHRoaXMua25vYlJhZGl1cyA9IDMwO1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgncicsdGhpcy5rbm9iUmFkaXVzLm9uKTtcbiAgICB9IGVsc2Uge1xuICAgIC8vICB0aGlzLmtub2JSYWRpdXMgPSAxNTtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYlJhZGl1cy5vZmYpO1xuICAgIH1cblxuICAgIHRoaXMua25vYkNvb3JkaW5hdGVzID0ge1xuICAgICAgeDogdGhpcy5feC5ub3JtYWxpemVkICogdGhpcy53aWR0aCxcbiAgICAgIHk6IHRoaXMuaGVpZ2h0IC0gdGhpcy5feS5ub3JtYWxpemVkICogdGhpcy5oZWlnaHRcbiAgICB9O1xuXG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkNvb3JkaW5hdGVzLngpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmtub2JDb29yZGluYXRlcy55KTtcbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgdGhpcy5wb3NpdGlvbi54LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5wb3NpdGlvbi55LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMucG9zaXRpb24ueC51cGRhdGUodGhpcy5tb3VzZSk7XG4gICAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKHRoaXMubW91c2UpO1xuICAgICAgdGhpcy5feC51cGRhdGVOb3JtYWwoIHRoaXMucG9zaXRpb24ueC52YWx1ZSApO1xuICAgICAgdGhpcy5feS51cGRhdGVOb3JtYWwoIHRoaXMucG9zaXRpb24ueS52YWx1ZSApO1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgeDogdGhpcy5feC52YWx1ZSxcbiAgICAgICAgeTogdGhpcy5feS52YWx1ZVxuICAgICAgfSk7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFRoZSBpbnRlcmZhY2UncyB4IHZhbHVlLiBXaGVuIHNldCwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IGFkanVzdCB0byBmaXQgbWluL21heC9zdGVwIHNldHRpbmdzIG9mIHRoZSBpbnRlcmZhY2UuXG4gICogQHR5cGUge29iamVjdH1cbiAgKiBAZXhhbXBsZSBwb3NpdGlvbi54ID0gMC41O1xuICAqL1xuXG4gIGdldCB4KCkge1xuICAgIHJldHVybiB0aGlzLl94LnZhbHVlO1xuICB9XG5cbiAgc2V0IHgodmFsdWUpIHtcbiAgICB0aGlzLl94LnVwZGF0ZSh2YWx1ZSk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgIHg6IHRoaXMuX3gudmFsdWUsXG4gICAgICB5OiB0aGlzLl95LnZhbHVlXG4gICAgfSk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFRoZSBpbnRlcmZhY2UncyB5IHZhbHVlcy4gV2hlbiBzZXQsIGl0IHdpbGwgYXV0b21hdGljYWxseSBhZGp1c3QgdG8gZml0IG1pbi9tYXgvc3RlcCBzZXR0aW5ncyBvZiB0aGUgaW50ZXJmYWNlLlxuICAqIEB0eXBlIHtvYmplY3R9XG4gICogQGV4YW1wbGUgcG9zaXRpb24ueCA9IDAuNTtcbiAgKi9cblxuICBnZXQgeSgpIHtcbiAgICByZXR1cm4gdGhpcy5feS52YWx1ZTtcbiAgfVxuXG4gIHNldCB5KHZhbHVlKSB7XG4gICAgdGhpcy5feS51cGRhdGUodmFsdWUpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICB4OiB0aGlzLl94LnZhbHVlLFxuICAgICAgeTogdGhpcy5feS52YWx1ZVxuICAgIH0pO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuXG5cbiAgZ2V0IG5vcm1hbGl6ZWQoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHRoaXMuX3gubm9ybWFsaXplZCxcbiAgICAgIHk6IHRoaXMuX3kubm9ybWFsaXplZFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgKiBUaGUgbG93ZXIgbGltaXQgb2YgdmFsdWUgb24gdGhlIHggYXhpc1xuICAqIEB0eXBlIHtvYmplY3R9XG4gICovXG4gIGdldCBtaW5YKCkge1xuICAgIHJldHVybiB0aGlzLl94Lm1pbjtcbiAgfVxuXG4gIHNldCBtaW5YKHYpIHtcbiAgICB0aGlzLl94Lm1pbiA9IHY7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFRoZSBsb3dlciBsaW1pdCBvZiB2YWx1ZSBvbiB0aGUgeSBheGlzXG4gICogQHR5cGUge29iamVjdH1cbiAgKi9cbiAgZ2V0IG1pblkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3kubWluO1xuICB9XG5cbiAgc2V0IG1pblkodikge1xuICAgIHRoaXMuX3kubWluID0gdjtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgKiBUaGUgdXBwZXIgbGltaXQgb2YgdmFsdWUgb24gdGhlIHggYXhpc1xuICAqIEB0eXBlIHtvYmplY3R9XG4gICovXG4gIGdldCBtYXhYKCkge1xuICAgIHJldHVybiB0aGlzLl94Lm1heDtcbiAgfVxuXG4gIHNldCBtYXhYKHYpIHtcbiAgICB0aGlzLl94Lm1heCA9IHY7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gICogVGhlIHVwcGVyIGxpbWl0IG9mIHZhbHVlIG9uIHRoZSB5IGF4aXNcbiAgKiBAdHlwZSB7b2JqZWN0fVxuICAqL1xuICBnZXQgbWF4WSgpIHtcbiAgICByZXR1cm4gdGhpcy5feS5tYXg7XG4gIH1cblxuICBzZXQgbWF4WSh2KSB7XG4gICAgdGhpcy5feS5tYXggPSB2O1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuXG4gIC8qKlxuICAqIFRoZSBpbmNyZW1lbnRhbCBzdGVwIG9mIHZhbHVlcyBvbiB0aGUgeCBheGlzXG4gICogQHR5cGUge29iamVjdH1cbiAgKi9cbiAgZ2V0IHN0ZXBYKCkge1xuICAgIHJldHVybiB0aGlzLl94LnN0ZXA7XG4gIH1cblxuICBzZXQgc3RlcFgodikge1xuICAgIHRoaXMuX3guc3RlcCA9IHY7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gICogVGhlIGluY3JlbWVudGFsIHN0ZXAgb2YgdmFsdWVzIG9uIHRoZSB5IGF4aXNcbiAgKiBAdHlwZSB7b2JqZWN0fVxuICAqL1xuICBnZXQgc3RlcFkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3kuc3RlcDtcbiAgfVxuXG4gIHNldCBzdGVwWSh2KSB7XG4gICAgdGhpcy5feS5zdGVwID0gdjtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgQWJzb2x1dGUgbW9kZSAocG9zaXRpb24ncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJhYnNvbHV0ZVwiLlxuICBAdHlwZSB7c3RyaW5nfVxuICBAZXhhbXBsZSBwb3NpdGlvbi5tb2RlID0gXCJyZWxhdGl2ZVwiO1xuICAqL1xuICBnZXQgbW9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi54Lm1vZGU7XG4gIH1cbiAgc2V0IG1vZGUodikge1xuICAgIHRoaXMucG9zaXRpb24ueC5tb2RlID0gdjtcbiAgICB0aGlzLnBvc2l0aW9uLnkubW9kZSA9IHY7XG4gIH1cblxuXG5cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvcG9zaXRpb24uanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5cbmV4cG9ydCBkZWZhdWx0IHtcblxuICBjcmVhdGU6ICh0eXBlKSA9PiB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCB0eXBlKTtcbiAgfSxcblxuICBhcmM6ICh4LCB5LCByYWRpdXMsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlKSA9PiB7XG5cbiAgICB2YXIgc3RhcnQgPSBtYXRoLnRvQ2FydGVzaWFuKHJhZGl1cywgZW5kQW5nbGUpO1xuICAgIHZhciBlbmQgPSBtYXRoLnRvQ2FydGVzaWFuKHJhZGl1cywgc3RhcnRBbmdsZSk7XG5cbiAgICB2YXIgbGFyZ2VBcmNGbGFnID0gZW5kQW5nbGUgLSBzdGFydEFuZ2xlIDw9IDE4MCA/ICcwJyA6ICcxJztcblxuICAgIHZhciBkID0gW1xuICAgICAgICAnTScsIHN0YXJ0LngreCwgc3RhcnQueSt5LFxuICAgICAgICAnQScsIHJhZGl1cywgcmFkaXVzLCAwLCBsYXJnZUFyY0ZsYWcsIDAsIGVuZC54K3gsIGVuZC55K3lcbiAgICBdLmpvaW4oJyAnKTtcblxuICAgIHJldHVybiBkO1xuICB9LFxuXG4gIHJhZGlhbEdyYWRpZW50OiAoZGVmcyxudW1iZXJPZlN0b3BzKSA9PiB7XG5cbiAgICBsZXQgaWQgPSAnZ3JhZGllbnQnICsgbWF0aC5yaSgxMDAwMDAwMDAwMDApO1xuICAgIGxldCBzdG9wcyA9IFtdO1xuXG4gICAgbGV0IGdyYWRpZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsICdyYWRpYWxHcmFkaWVudCcpO1xuICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZSgnaWQnLCBpZCk7XG4gICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlKCdjeCcsICc1MCUnKTtcbiAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGUoJ2N5JywgJzUwJScpO1xuICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZSgncicsICc1MCUnKTtcblxuICAgIGRlZnMuYXBwZW5kQ2hpbGQoZ3JhZGllbnQpO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8bnVtYmVyT2ZTdG9wcztpKyspIHtcbiAgICAgIGxldCBzdG9wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsICdzdG9wJyk7XG4gICAgICBzdG9wLnNldEF0dHJpYnV0ZSgnaWQnLCAnc3RvcCcraSk7XG4gICAgICAvL3N0b3Auc2V0QXR0cmlidXRlKCdvZmZzZXQnLCAnNzAlJyk7XG4gICAgICAvL3N0b3Auc2V0QXR0cmlidXRlKCdzdG9wLWNvbG9yJywgJ1doaXRlJyk7XG4gICAgICBncmFkaWVudC5hcHBlbmRDaGlsZChzdG9wKTtcbiAgICAgIHN0b3BzLnB1c2goc3RvcCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBpZCxcbiAgICAgIHN0b3BzOiBzdG9wcyxcbiAgICAgIGVsZW1lbnQ6IGdyYWRpZW50XG4gICAgfTtcblxuICB9XG5cbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvdXRpbC9zdmcuanMiLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogTGltaXQgYSBudW1iZXIgdG8gd2l0aGluIGEgbWluaW11bSBhbmQgbWF4aW11bVxuICogQHBhcmFtICB7bnVtYmVyfSB2YWx1ZSBJbnB1dCB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBtaW4gICBMb3dlciBsaW1pdFxuICogQHBhcmFtICB7bnVtYmVyfSBtYXggICBVcHBlciBsaW1pdFxuICogQHJldHVybiB7bnVtYmVyfSAgICAgICBUaGUgaW5wdXQgdmFsdWUgY29uc3RyYWluZWQgd2l0aGluIHRoZSBsb3dlciBhbmQgdXBwZXIgbGltaXRzXG4gKiBAZXhhbXBsZVxuICogTmV4dXMuY2xpcCgxMSwwLDEwKSAgIC8vIHJldHVybnMgMTBcbiAqIE5leHVzLmNsaXAoLTEsMCwxMCkgICAvLyByZXR1cm5zIDBcbiAqIE5leHVzLmNsaXAoNSwwLDEwKSAgICAvLyByZXR1cm5zIDVcbiAqL1xuXG5leHBvcnRzLmNsaXAgPSAodmFsdWUsbWluLG1heCkgPT4ge1xuICByZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgodmFsdWUsbWluKSxtYXgpO1xufTtcblxuZXhwb3J0cy5ub3JtYWxpemUgPSAodmFsdWUsbWluLG1heCkgPT4ge1xuICByZXR1cm4gKCAodmFsdWUtbWluKSAvIChtYXgtbWluKSApO1xufTtcblxuLyoqXG4gKiBTY2FsZSBhIHZhbHVlIGZyb20gb25lIHJhbmdlIHRvIGFub3RoZXIgcmFuZ2UuXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGluTnVtICBJbnB1dCB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBpbk1pbiAgSW5wdXQgcmFuZ2UgbWluaW11bVxuICogQHBhcmFtICB7bnVtYmVyfSBpbk1heCAgSW5wdXQgcmFuZ2UgbWF4aW11bVxuICogQHBhcmFtICB7bnVtYmVyfSBvdXRNaW4gT3V0cHV0IHJhbmdlIG1pbmltdW1cbiAqIEBwYXJhbSAge251bWJlcn0gb3V0TWF4IE91dHB1dCByYW5nZSBtYXhpbXVtXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgICBUaGUgaW5wdXQgdmFsdWUgc2NhbGVkIHRvIGl0cyBuZXcgcmFuZ2VcbiAqIEBleGFtcGxlXG4gKiBOZXh1cy5zY2FsZSgwLjUsMCwxLDAsMTApICAgLy8gcmV0dXJucyA1XG4gKiBOZXh1cy5zY2FsZSgwLjksMCwxLDEsMCkgICAgLy8gcmV0dXJucyAwLjFcbiAqL1xuZXhwb3J0cy5zY2FsZSA9IChpbk51bSwgaW5NaW4sIGluTWF4LCBvdXRNaW4sIG91dE1heCkgPT4ge1xuICBpZiAoaW5NaW4gPT09IGluTWF4KSB7XG4gICAgcmV0dXJuIG91dE1pbjtcbiAgfVxuICByZXR1cm4gKCgoaW5OdW0gLSBpbk1pbikgKiAob3V0TWF4IC0gb3V0TWluKSkgLyAoaW5NYXggLSBpbk1pbikpICsgb3V0TWluO1xufTtcblxuZXhwb3J0cy50b1BvbGFyID0gKHgseSkgPT4ge1xuICB2YXIgciA9IE1hdGguc3FydCh4KnggKyB5KnkpO1xuXG4gIHZhciB0aGV0YSA9IE1hdGguYXRhbjIoeSx4KTtcbiAgaWYgKHRoZXRhIDwgMCkge1xuICAgIHRoZXRhID0gdGhldGEgKyAoMiAqIE1hdGguUEkpO1xuICB9XG4gIHJldHVybiB7cmFkaXVzOiByLCBhbmdsZTogdGhldGF9O1xufTtcblxuZXhwb3J0cy50b0NhcnRlc2lhbiA9IGZ1bmN0aW9uKHJhZGl1cywgYW5nbGUpe1xuICB2YXIgY29zID0gTWF0aC5jb3MoYW5nbGUpO1xuICB2YXIgc2luID0gTWF0aC5zaW4oYW5nbGUpO1xuICByZXR1cm4ge3g6IHJhZGl1cypjb3MsIHk6IHJhZGl1cypzaW4qLTF9O1xufTtcbi8qXG5leHBvcnRzLnBvbGFyVG9DYXJ0ZXNpYW4oY2VudGVyWCwgY2VudGVyWSwgcmFkaXVzLCBhbmdsZUluRGVncmVlcykge1xuICB2YXIgYW5nbGVJblJhZGlhbnMgPSAoYW5nbGVJbkRlZ3JlZXMtOTApICogTWF0aC5QSSAvIDE4MC4wO1xuXG4gIHJldHVybiB7XG4gICAgeDogY2VudGVyWCArIChyYWRpdXMgKiBNYXRoLmNvcyhhbmdsZUluUmFkaWFucykpLFxuICAgIHk6IGNlbnRlclkgKyAocmFkaXVzICogTWF0aC5zaW4oYW5nbGVJblJhZGlhbnMpKVxuICB9O1xufSAgKi9cblxuXG5cbmV4cG9ydHMucHJ1bmUgPSBmdW5jdGlvbihkYXRhLCBzY2FsZSkge1xuICByZXR1cm4gcGFyc2VGbG9hdChkYXRhLnRvRml4ZWQoc2NhbGUpKTtcbn07XG5cbmV4cG9ydHMuaW52ZXJ0ID0gZnVuY3Rpb24gKGluTnVtKSB7XG4gIHJldHVybiBleHBvcnRzLnNjYWxlKGluTnVtLCAxLCAwLCAwLCAxKTtcbn07XG5cbi8qKlxuICogQ29udmVydCBhIE1JRGkgbm90ZSBudW1iZXIgdG8gYSBmcmVxdWVuY3kgdmFsdWUgaW4gZXF1YWwgdGVtcGVyYW1lbnQuXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG1pZGkgTUlESSBub3RlIHZhbHVlXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgRnJlcXVlbmNlIHZhbHVlXG4gKiBAZXhhbXBsZVxuICogTmV4dXMubXRvZig2MCkgIC8vIHJldHVybnMgdGhlIGZyZXF1ZW5jeSBudW1iZXIgb2YgTWlkZGxlIENcbiAqL1xuZXhwb3J0cy5tdG9mID0gZnVuY3Rpb24obWlkaSkge1xuICByZXR1cm4gTWF0aC5wb3coMiwgKChtaWRpLTY5KS8xMikpICogNDQwO1xufTtcblxuLyoqXG4gKiBJbnRlcnBvbGF0ZSBiZXR3ZWVuIHR3byBudW1iZXJzXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGxvYyBJbnRlcnBvbGF0aW9uIGluZGV4ICgwLTEpXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG1pbiBMb3dlciB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBtYXggVXBwZXIgdmFsdWVcbiAqIEByZXR1cm4ge251bWJlcn0gICAgIEludGVycG9sYXRlZCB2YWx1ZVxuICogQGV4YW1wbGVcbiAqIE5leHVzLmludGVycCgwLjUsMiw0KSAgIC8vIHJldHVybnMgM1xuICogTmV4dXMuaW50ZXJwKDAuMSwwLDEwKSAgICAgLy8gcmV0dXJucyAxXG4gKi9cbmV4cG9ydHMuaW50ZXJwID0gZnVuY3Rpb24obG9jLG1pbixtYXgpIHtcbiAgcmV0dXJuIGxvYyAqIChtYXggLSBtaW4pICsgbWluO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYSByYW5kb20gY2hvaWNlIGZyb20gYSBsaXN0IG9mIGFyZ3VtZW50c1xuICogQHJldHVybiB7dmFyaW91c30gT25lIHJhbmRvbSBhcmd1bWVudFxuICogQGV4YW1wbGVcbiAqIE5leHVzLnBpY2soMSwyLDMsNCkgICAvLyByZXR1cm5zIDEsIDIsIDMsIG9yIDRcbiAqIE5leHVzLnBpY2soZnVuY3Rpb24xLGZ1bmN0aW9uMikgICAvLyByZXR1cm5zIGVpdGhlciBmdW5jdGlvbjEgb3IgZnVuY3Rpb24yXG4gKi9cbmV4cG9ydHMucGljayA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gYXJndW1lbnRzW35+KE1hdGgucmFuZG9tKCkqYXJndW1lbnRzLmxlbmd0aCldO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGFuIG9jdGF2ZSBtdWx0aXBsaWVyIGZvciBmcmVxdWVuY3kgdmFsdWVzXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG51bSBSZWxhdGl2ZSBvY3RhdmUgbnVtYmVyIChlLmcuIC0xIGZvciBvbmUgb2N0YXZlIGRvd24sIDEgZm9yIG9uZSBvY3RhdmUgdXApXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICBPY3RhdmUgbXVsdGlwbGllclxuICogQGV4YW1wbGVcbiAqIE5leHVzLm9jdGF2ZSgtMSkgIC8vIHJldHVybnMgMC41XG4gKiBOZXh1cy5vY3RhdmUoMCkgICAvLyByZXR1cm5zIDFcbiAqIE5leHVzLm9jdGF2ZSgxKSAgIC8vIHJldHVybnMgMlxuICogTmV4dXMub2N0YXZlKDIpICAgLy8gcmV0dXJucyA0XG4gKi9cbmV4cG9ydHMub2N0YXZlID0gZnVuY3Rpb24obnVtKSB7XG4gIHJldHVybiBNYXRoLnBvdygyLG51bSk7XG59O1xuXG4vKipcbiAqIFJhbmRvbSBpbnRlZ2VyIGdlbmVyYXRvci4gSWYgbm8gc2Vjb25kIGFyZ3VtZW50IGlzIGdpdmVuLCB3aWxsIHJldHVybiByYW5kb20gaW50ZWdlciBmcm9tIDAgdG8gYm91bmQxLlxuICogQHBhcmFtICB7bnVtYmVyfSBib3VuZDEgTWluaW11bSByYW5kb20gdmFsdWVcbiAqIEBwYXJhbSAge251bWJlcn0gYm91bmQyIE1heGltdW0gcmFuZG9tIHZhbHVlXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgICBSYW5kb20gaW50ZWdlciBiZXR3ZWVuIGxvd2VyIGFuZCB1cHBlciBib3VuZGFyeVxuICogQGV4YW1wbGVcbiAqIE5leHVzLnJpKDEwKSAgICAvLyByZXR1cm5zIHJhbmRvbSBpbnQgZnJvbSAwIHRvIDEwXG4gKiBOZXh1cy5yaSgyMCwyMDAwKSAvLyByZXR1cm5zIHJhbmRvbSBpbnQgZnJvbSAyMCB0byAyMDAwXG4gKi9cbmV4cG9ydHMucmkgPSBmdW5jdGlvbihib3VuZDEsYm91bmQyKSB7XG4gIGlmICghYm91bmQyKSB7XG4gICAgYm91bmQyID0gYm91bmQxO1xuICAgIGJvdW5kMSA9IDA7XG4gIH1cbiAgdmFyIGxvdyA9IE1hdGgubWluKGJvdW5kMSxib3VuZDIpO1xuICB2YXIgaGlnaCA9IE1hdGgubWF4KGJvdW5kMSxib3VuZDIpO1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpKihoaWdoLWxvdykrbG93KTtcbn07XG5cbi8qKlxuICogUmFuZG9tIGZsb2F0IG51bWJlciBnZW5lcmF0b3IuIElmIG5vIHNlY29uZCBhcmd1bWVudCBpcyBnaXZlbiwgd2lsbCByZXR1cm4gcmFuZG9tIGZsb2F0IGZyb20gMCB0byBib3VuZDEuXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGJvdW5kMSBNaW5pbXVtIHJhbmRvbSB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBib3VuZDIgTWF4aW11bSByYW5kb20gdmFsdWVcbiAqIEByZXR1cm4ge251bWJlcn0gICAgICAgIFJhbmRvbSBmbG9hdCBiZXR3ZWVuIGxvd2VyIGFuZCB1cHBlciBib3VuZGFyeVxuICogQGV4YW1wbGVcbiAqIE5leHVzLnJmKDEpICAgIC8vIHJldHVybnMgcmFuZG9tIGZsb2F0IGZyb20gMCB0byAxXG4gKiBOZXh1cy5yZigxLDIpIC8vIHJldHVybnMgcmFuZG9tIGZsb2F0IGZyb20gMSB0byAyXG4gKi9cbmV4cG9ydHMucmYgPSBmdW5jdGlvbihib3VuZDEsYm91bmQyKSB7XG4gIGlmICghYm91bmQyKSB7XG4gICAgYm91bmQyID0gYm91bmQxO1xuICAgIGJvdW5kMSA9IDA7XG4gIH1cbiAgdmFyIGxvdyA9IE1hdGgubWluKGJvdW5kMSxib3VuZDIpO1xuICB2YXIgaGlnaCA9IE1hdGgubWF4KGJvdW5kMSxib3VuZDIpO1xuICByZXR1cm4gTWF0aC5yYW5kb20oKSooaGlnaC1sb3cpK2xvdztcbn07XG5cblxuZXhwb3J0cy5jeWNsZSA9IGZ1bmN0aW9uKGlucHV0LG1pbixtYXgpIHtcbiAgaW5wdXQrKztcbiAgaWYgKGlucHV0ID49IG1heCkge1xuICAgIGlucHV0ID0gbWluO1xuICB9XG4gIHJldHVybiBpbnB1dDtcbn07XG5cbi8qKlxuICogQXZlcmFnZSBhbiBhcnJheSBvZiBudW1iZXJzXG4gKiBAcGFyYW0gIHtBcnJheX0gZGF0YSBBcnJheSBvZiBudW1iZXJzIHRvIGF2ZXJhZ2VcbiAqIEByZXR1cm4ge251bWJlcn0gICAgICBBdmVyYWdlIG9mIHRoZSBpbnB1dCBkYXRhXG4gKiBAZXhhbXBsZVxuICogTmV4dXMuYXZlcmFnZShbMCwyLDQsNiw4LDEwXSkgICAvLyByZXR1cm5zIDVcbiAqL1xuZXhwb3J0cy5hdmVyYWdlID0gZnVuY3Rpb24oZGF0YSkge1xuICBsZXQgdG90YWwgPSAwO1xuICBmb3IgKHZhciBpPTA7aTxkYXRhLmxlbmd0aDtpKyspIHtcbiAgICB0b3RhbCArPSBkYXRhW2ldO1xuICB9XG4gIHJldHVybiB0b3RhbCAvIGRhdGEubGVuZ3RoO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGRpc3RhbmNlIGZyb20gb25lICh4LHkpIHBvaW50IHRvIGFub3RoZXIgKHgseSkgcG9pbnRcbiAqIEBwYXJhbSAge251bWJlcn0geDEgeCBvZiBmaXJzdCBwb2ludFxuICogQHBhcmFtICB7bnVtYmVyfSB5MSB5IG9mIGZpcnN0IHBvaW50XG4gKiBAcGFyYW0gIHtudW1iZXJ9IHgyIHggb2Ygc2Vjb25kIHBvaW50XG4gKiBAcGFyYW0gIHtudW1iZXJ9IHkyIHkgb2Ygc2Vjb25kIHBvaW55XG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgIERpc3RhbmNlXG4gKiBAZXhhbXBsZVxuICogTmV4dXMuZGlzdGFuY2UoMCwwLDMsNCkgICAvLyByZXR1cm5zIDVcbiAqL1xuZXhwb3J0cy5kaXN0YW5jZSA9IGZ1bmN0aW9uKHgxLHkxLHgyLHkyKSB7XG4gIGxldCBhID0geDEgLSB4MjtcbiAgbGV0IGIgPSB5MSAtIHkyO1xuICByZXR1cm4gTWF0aC5zcXJ0KCBhKmEgKyBiKmIgKTtcbn07XG5cbmV4cG9ydHMuZ2FpblRvREIgPSBmdW5jdGlvbihnYWluKSB7XG4gIHJldHVybiAyMCAqIE1hdGgubG9nMTAoZ2Fpbik7XG59O1xuXG4vKipcbiAqIEZsaXAgYSBjb2luLCByZXR1cm5pbmcgZWl0aGVyIDAgb3IgMSBhY2NvcmRpbmcgdG8gYSBwcm9iYWJpbGl0eVxuICogQHBhcmFtICB7bnVtYmVyfSBbb2Rkcz0wLjVdIExpa2VsaWhvb2Qgb2YgcmV0dXJuaW5nIDFcbiAqIEByZXR1cm4ge251bWJlcn0gICAgICAgICAgICAxIG9yIDBcbiAqIEBleGFtcGxlXG4gKiBOZXh1cy5jb2luKDAuMSkgICAvLyByZXR1cm5zIDEgKDEwJSBvZiB0aGUgdGltZSkgb3IgMCAoOTAlIG9mIHRoZSB0aW1lKVxuICovXG5leHBvcnRzLmNvaW4gPSBmdW5jdGlvbihvZGRzPTAuNSkge1xuICBpZiAoZXhwb3J0cy5yZigwLDEpIDwgb2Rkcykge1xuICAgIHJldHVybiAxO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAwO1xuICB9XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3V0aWwvbWF0aC5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgZG9tID0gcmVxdWlyZSgnLi4vdXRpbC9kb20nKTtcbmxldCB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbC91dGlsJyk7XG5sZXQgdG91Y2ggPSByZXF1aXJlKCcuLi91dGlsL3RvdWNoJyk7XG5jb25zdCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKTtcblxuaW1wb3J0IHsgY29sb3JzIH0gZnJvbSAnLi4vbWFpbic7XG5cbi8qKlxuSW50ZXJmYWNlXG4qL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSW50ZXJmYWNlIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcblxuICBjb25zdHJ1Y3RvcihhcmdzLG9wdGlvbnMsZGVmYXVsdHMpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMudHlwZSA9IHRoaXMuY29uc3RydWN0b3IubmFtZTtcbiAgICB0aGlzLnNldHRpbmdzID0gdGhpcy5wYXJzZVNldHRpbmdzKGFyZ3Msb3B0aW9ucyxkZWZhdWx0cyk7XG4gICAgdGhpcy5tb3VzZSA9IHt9O1xuICAgIHRoaXMud2FpdCA9IGZhbHNlO1xuICAgIHRoaXMuY29sb3JzID0ge307XG4gICAgbGV0IGRlZmF1bHRDb2xvcnMgPSBjb2xvcnMoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gICAgdGhpcy5jb2xvcnMuYWNjZW50ID0gZGVmYXVsdENvbG9ycy5hY2NlbnQ7XG4gICAgdGhpcy5jb2xvcnMuZmlsbCA9IGRlZmF1bHRDb2xvcnMuZmlsbDtcbiAgICB0aGlzLmNvbG9ycy5saWdodCA9IGRlZmF1bHRDb2xvcnMubGlnaHQ7XG4gICAgdGhpcy5jb2xvcnMuZGFyayA9IGRlZmF1bHRDb2xvcnMuZGFyaztcbiAgICB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCA9IGRlZmF1bHRDb2xvcnMubWVkaXVtTGlnaHQ7XG4gICAgdGhpcy5jb2xvcnMubWVkaXVtRGFyayA9IGRlZmF1bHRDb2xvcnMubWVkaXVtRGFyaztcbiAgfVxuXG4gIHBhcnNlU2V0dGluZ3MoYXJncyxvcHRpb25zLGRlZmF1bHRzKSB7XG5cbiAgICBvcHRpb25zLnVuc2hpZnQoJ3RhcmdldCcpO1xuICAgIGRlZmF1bHRzLmRlZmF1bHRTaXplID0gZGVmYXVsdHMuc2l6ZS5zcGxpY2UoMCwyKTtcbiAgICBkZWZhdWx0cy5zaXplID0gZmFsc2U7XG5cbiAgICBsZXQgc2V0dGluZ3MgPSB7XG4gICAgICAndGFyZ2V0JzogZG9jdW1lbnQuYm9keSxcbiAgICAgICdjb2xvcnMnOiB7fSwgLy8gc2hvdWxkIGluaGVyaXQgZnJvbSBhIGNvbG9ycyBtb2R1bGUsXG4gICAgICAnc25hcFdpdGhQYXJlbnQnOiB0cnVlLFxuICAgICAgJ2V2ZW50JzogZnVuY3Rpb24oKSB7fSxcbiAgICAgICdjb21wb25lbnQnOiBmYWxzZVxuICAgIH07XG5cbiAgICBmb3IgKGxldCBrZXkgaW4gZGVmYXVsdHMpIHtcbiAgICAgIHNldHRpbmdzW2tleV0gPSBkZWZhdWx0c1trZXldO1xuICAgIH1cblxuICAgIGZvciAobGV0IGk9MDsgaTxhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBncmFicyB0aGUgbmV4dCBhcmd1bWVudFxuICAgICAgbGV0IHNldHRpbmcgPSBhcmdzW2ldO1xuICAgICAgLy8gaWYgaXQncyBhbiBvYmplY3QsIGl0IG11c3QgYmUgdGhlIHNldHRpbmdzIG9iamVjdFxuICAgICAgaWYgKCB1dGlsLmlzT2JqZWN0KHNldHRpbmcpICkge1xuICAgICAgICBmb3IgKCBsZXQga2V5IGluIHNldHRpbmcgKSB7XG4gICAgICAgICAgc2V0dGluZ3Nba2V5XSA9IHNldHRpbmdba2V5XTtcbiAgICAgICAgfVxuICAgICAgLy8gaWYgaXQncyBhIGZ1bmN0aW9uLCBpdCBtdXN0IGJlIHRoZSBldmVudCBzZXR0aW5nXG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXR0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHNldHRpbmdzLmV2ZW50ID0gc2V0dGluZztcbiAgICAgIC8vIG90aGVyd2lzZSwgY29uc2lkZXIgaXQgb25lIG9mIHRoZSB3aWRnZXQncyBjdXN0b20gb3B0aW9uc1xuICAgICAgfSBlbHNlIGlmIChvcHRpb25zLmxlbmd0aD49MSkge1xuICAgICAgICAvLyBncmFiIHRoZSBmaXJzdCBvcHRpb24gLS0gaS5lLiAndGFyZ2V0J1xuICAgICAgICBsZXQga2V5ID0gb3B0aW9ucy5zcGxpY2UoMCwxKVswXTtcbiAgICAgICAgc2V0dGluZ3Nba2V5XSA9IHNldHRpbmc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyogIGhhbmRsZSBjb21tb24gc2V0dGluZ3MgICovXG5cbiAgICAvLyB0YXJnZXRcbiAgICB0aGlzLnBhcmVudCA9IGRvbS5wYXJzZUVsZW1lbnQoc2V0dGluZ3MudGFyZ2V0KTtcblxuICAgIC8vIG5leHVzLXVpIGF0dHJpYnV0ZVxuICAgIGlmICh0aGlzLnBhcmVudCAmJiB0aGlzLnBhcmVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmICFzZXR0aW5ncy5jb21wb25lbnQpIHtcbiAgICAgIGlmICghdGhpcy5wYXJlbnQuaGFzQXR0cmlidXRlKCduZXh1cy11aScpKSB7XG4gICAgICAgIHRoaXMucGFyZW50LnNldEF0dHJpYnV0ZSgnbmV4dXMtdWknLCcnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzaXplXG5cbiAgICBpZiAoc2V0dGluZ3Muc2l6ZSAmJiBBcnJheS5pc0FycmF5KHNldHRpbmdzLnNpemUpICYmIHNldHRpbmdzLnNuYXBXaXRoUGFyZW50KSB7XG4gICAgICB0aGlzLndpZHRoID0gc2V0dGluZ3Muc2l6ZVswXTtcbiAgICAgIHRoaXMuaGVpZ2h0ID0gc2V0dGluZ3Muc2l6ZVsxXTtcbiAgICAgIHRoaXMucGFyZW50LnN0eWxlLndpZHRoID0gdGhpcy53aWR0aCArICdweCc7XG4gICAgICB0aGlzLnBhcmVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmhlaWdodCArICdweCc7XG4gICAgfSBlbHNlIGlmIChzZXR0aW5ncy5zbmFwV2l0aFBhcmVudCAmJiAhc2V0dGluZ3MuY29tcG9uZW50KSB7XG5cbiAgICAgIHRoaXMud2lkdGggPSBwYXJzZUZsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMucGFyZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCd3aWR0aCcpLnJlcGxhY2UoJ3B4JywnJykpO1xuICAgICAgdGhpcy5oZWlnaHQgPSBwYXJzZUZsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMucGFyZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCdoZWlnaHQnKS5yZXBsYWNlKCdweCcsJycpKTtcblxuICAgICAgaWYgKHRoaXMud2lkdGg9PTUwMDApIHtcbiAgICAgICAgdGhpcy53aWR0aCA9IHNldHRpbmdzLmRlZmF1bHRTaXplWzBdO1xuICAgICAgICB0aGlzLnBhcmVudC5zdHlsZS53aWR0aCA9IHRoaXMucGFyZW50LndpZHRoID0gdGhpcy53aWR0aCArICdweCc7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5oZWlnaHQ9PTUwMDApIHtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBzZXR0aW5ncy5kZWZhdWx0U2l6ZVsxXTtcbiAgICAgICAgdGhpcy5wYXJlbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5wYXJlbnQuaGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyAncHgnO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIHNldHRpbmdzLnNpemUgPSBzZXR0aW5ncy5kZWZhdWx0U2l6ZTtcbiAgICAgIHRoaXMud2lkdGggPSBzZXR0aW5ncy5zaXplWzBdO1xuICAgICAgdGhpcy5oZWlnaHQgPSBzZXR0aW5ncy5zaXplWzFdO1xuICAgIH1cblxuICAgIC8vIGV2ZW50XG4gICAgaWYgKHNldHRpbmdzLmV2ZW50KSB7XG4gICAgICB0aGlzLmV2ZW50ID0gdGhpcy5vbignY2hhbmdlJywgc2V0dGluZ3MuZXZlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmV2ZW50ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNldHRpbmdzO1xuXG4gIH1cblxuICBpbml0KCkge1xuICAgIHRoaXMuYnVpbGRGcmFtZSgpO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgICB0aGlzLnNpemVJbnRlcmZhY2UoKTtcbiAgICB0aGlzLmF0dGFjaExpc3RlbmVycygpO1xuICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcbiAgICB0aGlzLmZpbmFsVG91Y2hlcygpO1xuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge31cbiAgc2l6ZUludGVyZmFjZSgpIHt9XG4gIGNvbG9ySW50ZXJmYWNlKCkge31cblxuICBhdHRhY2hMaXN0ZW5lcnMoKSB7XG5cbiAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0ID0gdGhpcy5pbnRlcmFjdGlvblRhcmdldCB8fCB0aGlzLmVsZW1lbnQ7XG5cbiAgICAvLyBTZXR1cCBpbnRlcmFjdGlvblxuICAgIGlmICh0b3VjaC5leGlzdHMpIHtcbiAgICAgIHRoaXMuaW50ZXJhY3Rpb25UYXJnZXQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGV2dCA9PiB0aGlzLnByZVRvdWNoKGV2dCkpO1xuICAgICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCBldnQgPT4gdGhpcy5wcmVUb3VjaE1vdmUoZXZ0KSk7XG4gICAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgZXZ0ID0+IHRoaXMucHJlVG91Y2hSZWxlYXNlKGV2dCkpO1xuICAgIH1cbiAgICB0aGlzLmJvdW5kUHJlTW92ZSA9IGV2dCA9PiB0aGlzLnByZU1vdmUoZXZ0KTtcbiAgICB0aGlzLmJvdW5kUHJlUmVsZWFzZSA9IGV2dCA9PiB0aGlzLnByZVJlbGVhc2UoZXZ0KTtcbiAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGV2dCA9PiB0aGlzLnByZUNsaWNrKGV2dCkpO1xuICB9XG5cbiAgZmluYWxUb3VjaGVzKCkge1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5jdXJzb3IgPSAncG9pbnRlcic7XG4gIH1cblxuICBwcmVDbGljayhlKSB7XG4gICAgLy8gMTAwMDAgZ2V0Q29tcHV0ZWRTdHlsZSBjYWxscyB0YWtlcyAxMDAgbXMuXG4gICAgLy8gLjouIG9uZSB0YWtlcyBhYm91dCAuMDFtc1xuICAgIGlmICh0aGlzLmVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgdGhpcy53aWR0aCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuZWxlbWVudCwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZSgnd2lkdGgnKS5yZXBsYWNlKCdweCcsJycpO1xuICAgIH1cbiAgICAvLyAxMDAwMCBnZXRDb21wdXRlZFN0eWxlIGNhbGxzIHRha2VzIDQwIG1zLlxuICAgIC8vIC46LiBvbmUgdGFrZXMgYWJvdXQgLjAwNG1zXG4gICAgdGhpcy5vZmZzZXQgPSBkb20uZmluZFBvc2l0aW9uKHRoaXMuZWxlbWVudCk7XG4gICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVNb3VzZShlLHRoaXMub2Zmc2V0KTtcbiAgICB0aGlzLmNsaWNrZWQgPSB0cnVlO1xuICAgIHRoaXMuY2xpY2soKTtcbiAgICB0aGlzLm1vdmVFdmVudCA9IGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuYm91bmRQcmVNb3ZlKTtcbiAgICB0aGlzLnJlbGVhc2VFdmVudCA9IGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLmJvdW5kUHJlUmVsZWFzZSk7XG4gICAgdGhpcy5lbWl0KCdjbGljaycpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgcHJlTW92ZShlKSB7XG4gICAgaWYgKCF0aGlzLndhaXQpIHtcbiAgICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSx0aGlzLm9mZnNldCk7XG4gICAgICB0aGlzLm1vdmUoKTtcbiAgICAgIHRoaXMud2FpdCA9IHRydWU7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHsgdGhpcy53YWl0ID0gZmFsc2U7IH0sMjUpO1xuICAgIH1cbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHByZVJlbGVhc2UoZSkge1xuICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSx0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG4gICAgdGhpcy5yZWxlYXNlKCk7XG4gICAgdGhpcy5lbWl0KCdyZWxlYXNlJyk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJyx0aGlzLmJvdW5kUHJlTW92ZSk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsdGhpcy5ib3VuZFByZVJlbGVhc2UpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgY2xpY2soKSB7XG5cbiAgfVxuXG4gIG1vdmUoKSB7XG5cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG5cbiAgfVxuXG5cbiAgLyogdG91Y2ggKi9cblxuICBwcmVUb3VjaChlKSB7XG4gICAgaWYgKHRoaXMuZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICB0aGlzLndpZHRoID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbGVtZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCd3aWR0aCcpLnJlcGxhY2UoJ3B4JywnJyk7XG4gICAgfVxuICAgIHRoaXMub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbih0aGlzLmVsZW1lbnQpO1xuICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlVG91Y2goZSx0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5jbGlja2VkID0gdHJ1ZTtcbiAgICB0aGlzLnRvdWNoKGUpO1xuICAgIHRoaXMuZW1pdCgnY2xpY2snKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHByZVRvdWNoTW92ZShlKSB7XG4gICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVUb3VjaChlLHRoaXMub2Zmc2V0KTtcbiAgICAgIHRoaXMudG91Y2hNb3ZlKCk7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIHByZVRvdWNoUmVsZWFzZShlKSB7XG4gICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVUb3VjaChlLCB0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG4gICAgdGhpcy50b3VjaFJlbGVhc2UoKTtcbiAgICB0aGlzLmVtaXQoJ3JlbGVhc2UnKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHRvdWNoKCkge1xuICAgIHRoaXMuY2xpY2soKTtcbiAgfVxuXG4gIHRvdWNoTW92ZSgpIHtcbiAgICB0aGlzLm1vdmUoKTtcbiAgfVxuXG4gIHRvdWNoUmVsZWFzZSgpIHtcbiAgICB0aGlzLnJlbGVhc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFJlc2l6ZSB0aGUgaW50ZXJmYWNlXG4gICogQHBhcmFtIHdpZHRoIHtudW1iZXJ9IE5ldyB3aWR0aCBpbiBwaXhlbHNcbiAgKiBAcGFyYW0gaGVpZ2h0IHtudW1iZXJ9IE5ldyBoZWlnaHQgaW4gcGl4ZWxzXG4gICpcbiAgKiBAZXhhbXBsZVxuICAqIGJ1dHRvbi5yZXNpemUoMTAwLDEwMCk7XG4gICovXG4gIHJlc2l6ZSh3aWR0aCxoZWlnaHQpIHtcbiAgICB0aGlzLndpZHRoID0gd2lkdGg7XG4gICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgdGhpcy5wYXJlbnQuc3R5bGUud2lkdGggPSB0aGlzLndpZHRoKydweCc7XG4gICAgdGhpcy5wYXJlbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5oZWlnaHQrJ3B4JztcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG4gIH1cblxuICBlbXB0eSgpIHtcbiAgICB3aGlsZSAodGhpcy5lbGVtZW50Lmxhc3RDaGlsZCkge1xuICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudC5sYXN0Q2hpbGQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAqIFJlbW92ZSB0aGUgaW50ZXJmYWNlIGZyb20gdGhlIHBhZ2UgYW5kIGNhbmNlbCBpdHMgZXZlbnQgbGlzdGVuZXIocykuXG4gICpcbiAgKiBAZXhhbXBsZVxuICAqIGJ1dHRvbi5kZXN0cm95KCk7XG4gICovXG4gIGRlc3Ryb3koKSB7XG4gICAgdGhpcy5lbXB0eSgpO1xuICAgIHRoaXMucGFyZW50LnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudCk7XG4gICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICBpZiAodGhpcy5pbnN0cnVtZW50KSB7XG4gICAgICBkZWxldGUgdGhpcy5pbnN0cnVtZW50W3RoaXMuaWRdO1xuICAgIH1cbiAgICB0aGlzLmN1c3RvbURlc3Ryb3koKTtcbiAgfVxuXG4gIGN1c3RvbURlc3Ryb3koKSB7XG5cbiAgfVxuXG4gIGNvbG9yaXplKHR5cGUsY29sb3IpIHtcbiAgICB0aGlzLmNvbG9yc1t0eXBlXSA9IGNvbG9yO1xuICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvY29yZS9pbnRlcmZhY2UuanMiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuZmluZFBvc2l0aW9uID0gKGVsKSA9PiB7XG4gIGxldCB2aWV3cG9ydE9mZnNldCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBsZXQgdG9wID0gdmlld3BvcnRPZmZzZXQudG9wICsgd2luZG93LnNjcm9sbFk7XG4gIGxldCBsZWZ0ID0gdmlld3BvcnRPZmZzZXQubGVmdCArIHdpbmRvdy5zY3JvbGxYO1xuICByZXR1cm4ge3RvcCxsZWZ0fTtcbn07XG5cbmV4cG9ydHMucGFyc2VFbGVtZW50ID0gKHBhcmVudCkgPT4ge1xuICBpZiAodHlwZW9mIHBhcmVudCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChwYXJlbnQucmVwbGFjZSgnIycsJycpKTtcbiAgfVxuXG4gIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCB8fCBwYXJlbnQgaW5zdGFuY2VvZiBTVkdFbGVtZW50KXtcbiAgICByZXR1cm4gcGFyZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAnTm8gdmFsaWQgcGFyZW50IGFyZ3VtZW50JztcbiAgfVxufTtcblxuZXhwb3J0cy5sb2NhdGVNb3VzZSA9IChlLG9mZnNldCkgPT4ge1xuICByZXR1cm4ge1xuICAgIHg6IGUucGFnZVggLSBvZmZzZXQubGVmdCxcbiAgICB5OiBlLnBhZ2VZIC0gb2Zmc2V0LnRvcFxuICB9O1xufTtcblxuZXhwb3J0cy5sb2NhdGVUb3VjaCA9IChlLG9mZnNldCkgPT4ge1xuICByZXR1cm4ge1xuICAgIHg6IGUudGFyZ2V0VG91Y2hlcy5sZW5ndGggPyBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVggLSBvZmZzZXQubGVmdCA6IGZhbHNlLFxuICAgIHk6IGUudGFyZ2V0VG91Y2hlcy5sZW5ndGggPyBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVkgLSBvZmZzZXQudG9wIDogZmFsc2VcbiAgfTtcbn07XG5cbmV4cG9ydHMuU21hcnRDYW52YXMgPSBmdW5jdGlvbihwYXJlbnQpIHtcblxuICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgdGhpcy5jb250ZXh0ID0gdGhpcy5lbGVtZW50LmdldENvbnRleHQoJzJkJyk7XG4gIHBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXG4gIHRoaXMucmVzaXplID0gKHcsaCkgPT4ge1xuICAgIHRoaXMuZWxlbWVudC53aWR0aCA9IHcqMjtcbiAgICB0aGlzLmVsZW1lbnQuaGVpZ2h0ID0gaCoyO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9IHcrJ3B4JztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gaCsncHgnO1xuICB9O1xuXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3V0aWwvZG9tLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLmlzT2JqZWN0ID0gKG9iaikgPT4ge1xuICBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkob2JqKSAmJiBvYmogIT09IG51bGwgJiYgb2JqIGluc3RhbmNlb2YgU1ZHRWxlbWVudCA9PT0gZmFsc2UgJiYgb2JqIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgPT09IGZhbHNlICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi91dGlsL3V0aWwuanMiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuZXhpc3RzID0gKCdvbnRvdWNoc3RhcnQnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvdXRpbC90b3VjaC5qcyIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gIHRoaXMuX2V2ZW50cyA9IHRoaXMuX2V2ZW50cyB8fCB7fTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxuRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24obikge1xuICBpZiAoIWlzTnVtYmVyKG4pIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IFR5cGVFcnJvcignbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcbiAgICBpZiAoIXRoaXMuX2V2ZW50cy5lcnJvciB8fFxuICAgICAgICAoaXNPYmplY3QodGhpcy5fZXZlbnRzLmVycm9yKSAmJiAhdGhpcy5fZXZlbnRzLmVycm9yLmxlbmd0aCkpIHtcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuY2F1Z2h0LCB1bnNwZWNpZmllZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNVbmRlZmluZWQoaGFuZGxlcikpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgICBjYXNlIDE6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICBoYW5kbGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc09iamVjdChoYW5kbGVyKSkge1xuICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBtO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gIGlmICh0aGlzLl9ldmVudHMubmV3TGlzdGVuZXIpXG4gICAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG4gICAgICAgICAgICAgIGlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpID9cbiAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gIGVsc2UgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcbiAgZWxzZVxuICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFt0aGlzLl9ldmVudHNbdHlwZV0sIGxpc3RlbmVyXTtcblxuICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSAmJiAhdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCkge1xuICAgIGlmICghaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSkge1xuICAgICAgbSA9IHRoaXMuX21heExpc3RlbmVycztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGlmIChtICYmIG0gPiAwICYmIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGggPiBtKSB7XG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJyhub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5ICcgK1xuICAgICAgICAgICAgICAgICAgICAnbGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ1VzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO1xuICAgICAgaWYgKHR5cGVvZiBjb25zb2xlLnRyYWNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgaW4gSUUgMTBcbiAgICAgICAgY29uc29sZS50cmFjZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICB2YXIgZmlyZWQgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBnKCkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgZyk7XG5cbiAgICBpZiAoIWZpcmVkKSB7XG4gICAgICBmaXJlZCA9IHRydWU7XG4gICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfVxuXG4gIGcubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgdGhpcy5vbih0eXBlLCBnKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZmYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGxpc3QsIHBvc2l0aW9uLCBsZW5ndGgsIGk7XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgbGlzdCA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgbGVuZ3RoID0gbGlzdC5sZW5ndGg7XG4gIHBvc2l0aW9uID0gLTE7XG5cbiAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8XG4gICAgICAoaXNGdW5jdGlvbihsaXN0Lmxpc3RlbmVyKSAmJiBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuXG4gIH0gZWxzZSBpZiAoaXNPYmplY3QobGlzdCkpIHtcbiAgICBmb3IgKGkgPSBsZW5ndGg7IGktLSA+IDA7KSB7XG4gICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHxcbiAgICAgICAgICAobGlzdFtpXS5saXN0ZW5lciAmJiBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpc3Quc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBrZXksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gIGlmICghdGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChrZXkgaW4gdGhpcy5fZXZlbnRzKSB7XG4gICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGxpc3RlbmVycykpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gIH0gZWxzZSBpZiAobGlzdGVuZXJzKSB7XG4gICAgLy8gTElGTyBvcmRlclxuICAgIHdoaWxlIChsaXN0ZW5lcnMubGVuZ3RoKVxuICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbbGlzdGVuZXJzLmxlbmd0aCAtIDFdKTtcbiAgfVxuICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gW107XG4gIGVsc2UgaWYgKGlzRnVuY3Rpb24odGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICByZXQgPSBbdGhpcy5fZXZlbnRzW3R5cGVdXTtcbiAgZWxzZVxuICAgIHJldCA9IHRoaXMuX2V2ZW50c1t0eXBlXS5zbGljZSgpO1xuICByZXR1cm4gcmV0O1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24odHlwZSkge1xuICBpZiAodGhpcy5fZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgICBpZiAoaXNGdW5jdGlvbihldmxpc3RlbmVyKSlcbiAgICAgIHJldHVybiAxO1xuICAgIGVsc2UgaWYgKGV2bGlzdGVuZXIpXG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gIH1cbiAgcmV0dXJuIDA7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJDb3VudCh0eXBlKTtcbn07XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9ldmVudHMvZXZlbnRzLmpzXG4vLyBtb2R1bGUgaWQgPSAxMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG5cbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5cbi8qKlxuICBDcmVhdGVzIGEgc3RlcHBhYmxlIHZhbHVlIHdpdGggbWluaW11bSwgbWF4aW11bSwgYW5kIHN0ZXAgc2l6ZS4gVGhpcyBpcyB1c2VkIGluIG1hbnkgaW50ZXJmYWNlcyB0byBjb25zdHJpY3QgdGhlaXIgdmFsdWVzIHRvIGNlcnRhaW4gcmFuZ2VzLlxuICBAcGFyYW0ge251bWJlcn0gW21pbj0wXSBtaW5pbXVtXG4gIEBwYXJhbSB7bnVtYmVyfSBbbWF4PTFdIG1heGltdW1cbiAgQHBhcmFtIHtudW1iZXJ9IFtzdGVwPTBdXG4gIEBwYXJhbSB7bnVtYmVyfSBbdmFsdWU9MF0gaW5pdGlhbCB2YWx1ZVxuICBAcmV0dXJucyB7T2JqZWN0fSBTdGVwXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdGVwIHtcblxuICBjb25zdHJ1Y3RvcihtaW4gPSAwLG1heCA9IDEsc3RlcCA9IDAsdmFsdWUgPSAwKSB7XG4gICAgLy9PYmplY3QuYXNzaWduKHRoaXMse21pbixtYXgsc3RlcH0pO1xuICAgIC8vQ2Fubm90IHVzZSBPYmplY3QuYXNzaWduIGJlY2F1c2Ugbm90IHN1cHBvcnRlZCBpbiBTYWZhcmkuXG4gICAgLy9JIHdvdWxkIGV4cGVjdCBmb3IgQmFiZWwgdG8gdGFrZSBjYXJlIG9mIHRoaXMgYnV0IGl0IGlzIG5vdC5cbiAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICB0aGlzLm1heCA9IG1heDtcbiAgICB0aGlzLnN0ZXAgPSBzdGVwO1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmNoYW5nZWQgPSBmYWxzZTtcbiAgICB0aGlzLm9sZFZhbHVlID0gZmFsc2U7XG4gICAgdGhpcy51cGRhdGUodGhpcy52YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICBVcGRhdGUgd2l0aCBhIG5ldyB2YWx1ZS4gVGhlIHZhbHVlIHdpbGwgYmUgYXV0by1hZGp1c3RlZCB0byBmaXQgdGhlIG1pbi9tYXgvc3RlcC5cbiAgICBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAgKi9cblxuICB1cGRhdGUodmFsdWUpIHtcbiAgICBpZiAodGhpcy5zdGVwKSB7XG4gICAgICAvLyB0aGlzLnZhbHVlID0gbWF0aC5jbGlwKE1hdGgucm91bmQodmFsdWUgLyAodGhpcy5zdGVwKSkgKiB0aGlzLnN0ZXAsIHRoaXMubWluLHRoaXMubWF4KTtcbiAgICAgIHRoaXMudmFsdWUgPSBtYXRoLmNsaXAoTWF0aC5yb3VuZCgodmFsdWUtdGhpcy5taW4pIC8gKHRoaXMuc3RlcCkpICogdGhpcy5zdGVwICsgdGhpcy5taW4sIHRoaXMubWluLHRoaXMubWF4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52YWx1ZSA9IG1hdGguY2xpcCh2YWx1ZSx0aGlzLm1pbix0aGlzLm1heCk7XG4gICAgfVxuICAgIGlmICh0aGlzLm9sZFZhbHVlICE9PSB0aGlzLnZhbHVlKSB7XG4gICAgICB0aGlzLm9sZFZhbHVlID0gdGhpcy52YWx1ZTtcbiAgICAgIHRoaXMuY2hhbmdlZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hhbmdlZCA9IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgIFVwZGF0ZSB3aXRoIGEgbm9ybWFsaXplZCB2YWx1ZSAwLTEuXG4gICAgQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gICovXG4gIHVwZGF0ZU5vcm1hbCh2YWx1ZSkge1xuICAgIHRoaXMudmFsdWUgPSBtYXRoLnNjYWxlKHZhbHVlLDAsMSx0aGlzLm1pbix0aGlzLm1heCk7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlKHRoaXMudmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAgR2V0IGEgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIHRoaXMudmFsdWUgLiBOb3Qgc2V0dGFibGUuXG4gICovXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiBtYXRoLm5vcm1hbGl6ZSh0aGlzLnZhbHVlLHRoaXMubWluLHRoaXMubWF4KTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbW9kZWxzL3N0ZXAuanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5pbXBvcnQgVG9nZ2xlTW9kZWwgZnJvbSAnLi4vbW9kZWxzL3RvZ2dsZSc7XG5cblxuLypcbmhvdyB0byB1c2UgOlxuXG5kaWFsLmludGVyYWN0aW9uID0gbmV3IEhhbmRsZSgncmFkaWFsJywncmVsYXRpdmUnLHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpO1xuLy8gZGlhbC5pbnRlcmFjdGlvbi5tb2RlID0gJ3JlbGF0aXZlJ1xuLy8gZGlhbC5pbnRlcmFjdGlvbi5kaXJlY3Rpb24gPSAncmFkaWFsJ1xuXG5vbiBjbGljazpcbmRpYWwuaW50ZXJhY3Rpb24uYW5jaG9yID0gdGhpcy5tb3VzZTtcblxub24gbW92ZTpcbmRpYWwuaW50ZXJhY3Rpb24udXBkYXRlKHRoaXMubW91c2UpO1xuXG5jb25zb2xlLmxvZyggZGlhbC5pbnRlcmFjdGlvbi52YWx1ZSApOyBzaG91bGQgYmUgYSBub3JtYWxpemVkIHZhbHVlLlxuXG4qL1xuXG4vKlxuICBhYnNvbHV0ZS9yZWxhdGl2ZSBhcmUgcHJvcGVydHk6IG1vZGVcbiAgcmFkaWFsL3ZlcnRpY2FsL2hvcml6b250YWwvMmQgYXJlIHByb3BlcnR5OiBkaXJlY3Rpb25cblxuICBwbGFuIDpcblxuICBpZiByZWxhdGl2ZSAtLVxuICBOTyBvbiBjbGljaywgZ2V0IHZhbHVlIG9mZnNldCBiZXR3ZWVuIGN1cnJlbnQgdmFsdWUgYW5kIGNsaWNrIHZhbHVlLlxuICBOTyBvbiBtb3ZlLCB1c2UgY2xpY2sgdmFsdWUgLSBvZmZzZXRcbiAgSU5TVEVBRFxuICB1c2UgZGVsdGEgLS0gYmMgdmVydGljYWwgbW90aW9uIG9uIGRpYWwgaXMgaW1wb3NzaWJsZSBvdGhlcndpc2VcbiAgYWxzbyBhbGxvdyB0byBzZXQgc2Vuc2l0aXZpdHlcblxuKi9cblxuZXhwb3J0IGNsYXNzIEhhbmRsZSB7XG5cbiAgY29uc3RydWN0b3IobW9kZT0nYWJzb2x1dGUnLGRpcmVjdGlvbj0ndmVydGljYWwnLHhib3VuZD1bMCwxMDBdLHlib3VuZD1bMCwxMDBdKSB7XG4gICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICB0aGlzLmRpcmVjdGlvbiA9IGRpcmVjdGlvbjtcbiAgICB0aGlzLnByZXZpb3VzID0gMDtcbiAgICB0aGlzLnZhbHVlID0gMDtcbiAgICB0aGlzLnNlbnNpdGl2aXR5ID0gMTtcbiAgICB0aGlzLnJlc2l6ZSh4Ym91bmQseWJvdW5kKTtcbiAgfVxuXG4gIHJlc2l6ZSh4Ym91bmQseWJvdW5kKSB7XG4gICAgdGhpcy5ib3VuZGFyeSA9IHtcbiAgICAgIG1pbjoge1xuICAgICAgICB4OiB4Ym91bmRbMF0sXG4gICAgICAgIHk6IHlib3VuZFswXVxuICAgICAgfSxcbiAgICAgIG1heDoge1xuICAgICAgICB4OiB4Ym91bmRbMV0sXG4gICAgICAgIHk6IHlib3VuZFsxXVxuICAgICAgfSxcbiAgICAgIGNlbnRlcjoge1xuICAgICAgICB4OiAoeGJvdW5kWzFdIC0geGJvdW5kWzBdKS8yICsgeGJvdW5kWzBdLFxuICAgICAgICB5OiAoeWJvdW5kWzFdIC0geWJvdW5kWzBdKS8yICsgeWJvdW5kWzBdXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHNldCBhbmNob3IobW91c2UpIHtcbiAgICB0aGlzLl9hbmNob3IgPSB0aGlzLmNvbnZlcnRQb3NpdGlvblRvVmFsdWUobW91c2UpO1xuICB9XG5cbiAgZ2V0IGFuY2hvcigpIHtcbiAgICByZXR1cm4gdGhpcy5fYW5jaG9yO1xuICB9XG5cblxuICB1cGRhdGUobW91c2UpIHtcbiAgICBpZiAodGhpcy5tb2RlPT09J3JlbGF0aXZlJykge1xuICAgICAgbGV0IGluY3JlbWVudCA9IHRoaXMuY29udmVydFBvc2l0aW9uVG9WYWx1ZShtb3VzZSkgLSB0aGlzLmFuY2hvcjtcbiAgICAgIGlmIChNYXRoLmFicyhpbmNyZW1lbnQpID4gMC41KSB7IGluY3JlbWVudCA9IDA7IH1cbiAgICAgIHRoaXMuYW5jaG9yID0gbW91c2U7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy52YWx1ZSArIGluY3JlbWVudCAqIHRoaXMuc2Vuc2l0aXZpdHk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLmNvbnZlcnRQb3NpdGlvblRvVmFsdWUobW91c2UpO1xuICAgIH1cbiAgICB0aGlzLnZhbHVlID0gbWF0aC5jbGlwKHRoaXMudmFsdWUsMCwxKTtcbiAgfVxuXG4gIGNvbnZlcnRQb3NpdGlvblRvVmFsdWUoY3VycmVudCkge1xuICAgIHN3aXRjaCh0aGlzLmRpcmVjdGlvbikge1xuICAgICAgY2FzZSAncmFkaWFsJzpcbiAgICAgICAgbGV0IHBvc2l0aW9uID0gbWF0aC50b1BvbGFyKGN1cnJlbnQueCAtIHRoaXMuYm91bmRhcnkuY2VudGVyLngsIGN1cnJlbnQueSAtIHRoaXMuYm91bmRhcnkuY2VudGVyLnkpO1xuICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uLmFuZ2xlIC8gKE1hdGguUEkqMik7XG4gICAgICAgIHBvc2l0aW9uID0gKChwb3NpdGlvbiAtIDAuMjUpICsgMSkgJSAxO1xuICAgICAgICByZXR1cm4gcG9zaXRpb247XG4gICAgICBjYXNlICd2ZXJ0aWNhbCc6XG4gICAgICAgIHJldHVybiBtYXRoLnNjYWxlKGN1cnJlbnQueSx0aGlzLmJvdW5kYXJ5Lm1pbi55LHRoaXMuYm91bmRhcnkubWF4LnksMCwxKTtcbiAgICAgIGNhc2UgJ2hvcml6b250YWwnOlxuICAgICAgICByZXR1cm4gbWF0aC5zY2FsZShjdXJyZW50LngsdGhpcy5ib3VuZGFyeS5taW4ueCx0aGlzLmJvdW5kYXJ5Lm1heC54LDAsMSk7XG4gICAgfVxuICB9XG5cbn1cblxuXG5leHBvcnQgY2xhc3MgQnV0dG9uIHtcblxuICBjb25zdHJ1Y3Rvcihtb2RlPSdidXR0b24nKSB7XG4gICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICB0aGlzLnN0YXRlID0gbmV3IFRvZ2dsZU1vZGVsKCk7XG4gICAgdGhpcy5wYWludGJydXNoID0gZmFsc2U7XG4gIH1cblxuICBjbGljaygpIHtcbiAgICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuICAgICAgY2FzZSAnaW1wdWxzZSc6XG4gICAgICAgIHRoaXMuc3RhdGUub24oKTtcbiAgICAgICAgaWYgKHRoaXMudGltZW91dCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudGltZW91dCA9IHNldFRpbWVvdXQodGhpcy5zdGF0ZS5vZmYuYmluZCh0aGlzKSwzMCk7XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdidXR0b24nOlxuICAgICAgICB0aGlzLnR1cm5PbigpO1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgICB5OiBtYXRoLmNsaXAoMSAtIHRoaXMubW91c2UueSAvIHRoaXMuaGVpZ2h0LDAsMSlcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy50dXJuT24oKTtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG4gICAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd0b2dnbGUnOlxuICAgICAgICB0aGlzLmZsaXAoKTtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgfVxuXG4gIG1vdmUoKSB7XG4gICAgaWYgKHRoaXMubW9kZT09PSdhZnRlcnRvdWNoJykge1xuICAgICAgdGhpcy5wb3NpdGlvbiA9IHtcbiAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICB9O1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgc3dpdGNoICh0aGlzLm1vZGUpIHtcbiAgICAgIGNhc2UgJ2J1dHRvbic6XG4gICAgICAgIHRoaXMudHVybk9mZigpO1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMudHVybk9mZigpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uID0ge1xuICAgICAgICAgIHg6IHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsXG4gICAgICAgICAgeTogMSAtIHRoaXMubW91c2UueSAvIHRoaXMuaGVpZ2h0XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgICAgICAgIHk6IHRoaXMucG9zaXRpb24ueSxcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3V0aWwvaW50ZXJhY3Rpb24uanMiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRvZ2dsZSB7XG5cbiAgY29uc3RydWN0b3Ioc3RhdGUpIHtcbiAgICB0aGlzLnN0YXRlID0gc3RhdGUgfHwgZmFsc2U7XG4gIH1cblxuICBmbGlwKHN0YXRlKSB7XG4gICAgaWYgKHN0YXRlIHx8IHN0YXRlID09PSBmYWxzZSkge1xuICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0YXRlID0gIXRoaXMuc3RhdGU7XG4gICAgfVxuICB9XG5cbiAgb24oKSB7XG4gICAgdGhpcy5zdGF0ZSA9IHRydWU7XG4gIH1cblxuICBvZmYoKSB7XG4gICAgdGhpcy5zdGF0ZSA9IGZhbHNlO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9tb2RlbHMvdG9nZ2xlLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbi8qKlxuKiBTbGlkZXJcbipcbiogQGRlc2NyaXB0aW9uIEhvcml6b250YWwgb3IgdmVydGljYWwgc2xpZGVyIHdpdGggc2V0dGFibGUgaW50ZXJhY3Rpb24gbW9kZXMuXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwic2xpZGVyXCIgc3RlcD0wLjI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc2xpZGVyID0gbmV3IE5leHVzLlNsaWRlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBzbGlkZXIgPSBuZXcgTmV4dXMuU2xpZGVyKCcjdGFyZ2V0Jyx7XG4qICAgICAnc2l6ZSc6IFsxMjAsMjBdLFxuKiAgICAgJ21vZGUnOiAncmVsYXRpdmUnLCAgLy8gJ3JlbGF0aXZlJyBvciAnYWJzb2x1dGUnXG4qICAgICAnbWluJzogMCxcbiogICAgICdtYXgnOiAxLFxuKiAgICAgJ3N0ZXAnOiAwLFxuKiAgICAgJ3ZhbHVlJzogMFxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyB3aGVuIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIEV2ZW50IGRhdGE6IDxpPm51bWJlcjwvaT4gVGhlIG51bWJlciB2YWx1ZSBvZiB0aGUgaW50ZXJmYWNlLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiBzbGlkZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2xpZGVyIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWydtaW4nLCdtYXgnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMTIwLDIwXSxcbiAgICAgICdtb2RlJzogJ3JlbGF0aXZlJywgIC8vICdyZWxhdGl2ZScgb3IgJ2Fic29sdXRlJ1xuICAgICAgJ21pbic6IDAsXG4gICAgICAnbWF4JzogMSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDBcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5vcmllbnRhdGlvbiA9ICd2ZXJ0aWNhbCc7IC8vIFRoaXMgd2lsbCBjaGFuZ2UgYXV0b21hdGljYWxseSB0byAnaG9yaXpvbnRhbCdpZiB0aGUgaW50ZXJmYWNlIGlzIHdpZGVyIHRoYW4gaXQgaXMgdGFsbC5cblxuICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5taW4sIHRoaXMuc2V0dGluZ3MubWF4LCB0aGlzLnNldHRpbmdzLnN0ZXAsIHRoaXMuc2V0dGluZ3MudmFsdWUpO1xuXG4gICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLHRoaXMub3JpZW50YXRpb24sWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbi5kaXJlY3Rpb24gPSB0aGlzLm9yaWVudGF0aW9uO1xuXG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuXG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyID0gc3ZnLmNyZWF0ZSgncmVjdCcpO1xuICAgIHRoaXMuZmlsbGJhciA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmtub2IgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuZmlsbGJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBpZiAodGhpcy53aWR0aCA8IHRoaXMuaGVpZ2h0KSB7XG4gICAgICB0aGlzLm9yaWVudGF0aW9uID0gJ3ZlcnRpY2FsJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcmllbnRhdGlvbiA9ICdob3Jpem9udGFsJztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wb3NpdGlvbikge1xuICAgICAgdGhpcy5wb3NpdGlvbi5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB9XG5cbiAgICBsZXQgeCwgeSwgdywgaCwgYmFyT2Zmc2V0LCBjb3JuZXJSYWRpdXM7XG4gICAgdGhpcy5rbm9iRGF0YSA9IHtcbiAgICAgIGxldmVsOiAwLFxuICAgICAgcjogMFxuICAgIH07XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy50aGlja25lc3MgPSB0aGlzLndpZHRoIC8gMjtcbiAgICBcdHggPSB0aGlzLndpZHRoLzI7XG4gICAgXHR5ID0gMDtcbiAgICBcdHcgPSB0aGlzLnRoaWNrbmVzcztcbiAgICBcdGggPSB0aGlzLmhlaWdodDtcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IGgtdGhpcy5rbm9iRGF0YS5yLXRoaXMubm9ybWFsaXplZCooaC10aGlzLmtub2JEYXRhLnIqMik7XG4gICAgICBiYXJPZmZzZXQgPSAndHJhbnNsYXRlKCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycsMCknO1xuICAgICAgY29ybmVyUmFkaXVzID0gdy8yO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMuaGVpZ2h0IC8gMjtcbiAgICBcdHggPSAwO1xuICAgIFx0eSA9IHRoaXMuaGVpZ2h0LzI7XG4gICAgXHR3ID0gdGhpcy53aWR0aDtcbiAgICBcdGggPSB0aGlzLnRoaWNrbmVzcztcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IHRoaXMubm9ybWFsaXplZCoody10aGlzLmtub2JEYXRhLnIqMikrdGhpcy5rbm9iRGF0YS5yO1xuICAgICAgYmFyT2Zmc2V0ID0gJ3RyYW5zbGF0ZSgwLCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycpJztcbiAgICAgIGNvcm5lclJhZGl1cyA9IGgvMjtcbiAgICB9XG5cbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3gnLHgpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneScseSk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGJhck9mZnNldCk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsY29ybmVyUmFkaXVzKTsgLy8gY29ybmVyIHJhZGl1c1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgncnknLGNvcm5lclJhZGl1cyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3gnLHgpO1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneScsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdyk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgtdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3gnLDApO1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneScseSk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgpO1xuICAgIH1cbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGJhck9mZnNldCk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgncngnLGNvcm5lclJhZGl1cyk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgncnknLGNvcm5lclJhZGl1cyk7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHgpO1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScseSk7XG4gICAgfVxuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYkRhdGEucik7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICB9XG5cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKCF0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzKjAuNzU7XG4gICAgfVxuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYkRhdGEucik7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICBcdCAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLmtub2JEYXRhLnIrdGhpcy5fdmFsdWUubm9ybWFsaXplZCoodGhpcy5oZWlnaHQtdGhpcy5rbm9iRGF0YS5yKjIpO1xuICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmhlaWdodCAtIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3knLHRoaXMuaGVpZ2h0IC0gdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICBcdCAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkKih0aGlzLndpZHRoLXRoaXMua25vYkRhdGEucioyKSt0aGlzLmtub2JEYXRhLnI7XG4gICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3gnLDApO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9XG4gIH1cblxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzKjAuOTtcbiAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMucG9zaXRpb24udXBkYXRlKHRoaXMubW91c2UpO1xuICAgICAgdGhpcy5fdmFsdWUudXBkYXRlTm9ybWFsKCB0aGlzLnBvc2l0aW9uLnZhbHVlICk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5fdmFsdWUudmFsdWUpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuICB9XG5cbiAgLyoqXG4gIFRoZSBzbGlkZXIncyBjdXJyZW50IHZhbHVlLiBJZiBzZXQgbWFudWFsbHksIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgc2xpZGVyLnZhbHVlID0gMTA7XG4gICovXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHYpIHtcbiAgICB0aGlzLl92YWx1ZS51cGRhdGUodik7XG4gICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuX3ZhbHVlLnZhbHVlKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIExvd2VyIGxpbWl0IG9mIHRoZSBzbGlkZXJzJ3Mgb3V0cHV0IHJhbmdlXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNsaWRlci5taW4gPSAxMDAwO1xuICAqL1xuICBnZXQgbWluKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5taW47XG4gIH1cbiAgc2V0IG1pbih2KSB7XG4gICAgdGhpcy5fdmFsdWUubWluID0gdjtcbiAgfVxuXG4gIC8qKlxuICBVcHBlciBsaW1pdCBvZiB0aGUgc2xpZGVyJ3Mgb3V0cHV0IHJhbmdlXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNsaWRlci5tYXggPSAxMDAwO1xuICAqL1xuICBnZXQgbWF4KCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5tYXg7XG4gIH1cbiAgc2V0IG1heCh2KSB7XG4gICAgdGhpcy5fdmFsdWUubWF4ID0gdjtcbiAgfVxuXG4gIC8qKlxuICBUaGUgaW5jcmVtZW50IHRoYXQgdGhlIHNsaWRlcidzIHZhbHVlIGNoYW5nZXMgYnkuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNsaWRlci5zdGVwID0gNTtcbiAgKi9cbiAgZ2V0IHN0ZXAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnN0ZXA7XG4gIH1cbiAgc2V0IHN0ZXAodikge1xuICAgIHRoaXMuX3ZhbHVlLnN0ZXAgPSB2O1xuICB9XG5cbiAgLyoqXG4gIEFic29sdXRlIG1vZGUgKHNsaWRlcidzIHZhbHVlIGp1bXBzIHRvIG1vdXNlIGNsaWNrIHBvc2l0aW9uKSBvciByZWxhdGl2ZSBtb2RlIChtb3VzZSBkcmFnIGNoYW5nZXMgdmFsdWUgcmVsYXRpdmUgdG8gaXRzIGN1cnJlbnQgcG9zaXRpb24pLiBEZWZhdWx0OiBcInJlbGF0aXZlXCIuXG4gIEB0eXBlIHtzdHJpbmd9XG4gIEBleGFtcGxlIHNsaWRlci5tb2RlID0gXCJyZWxhdGl2ZVwiO1xuICAqL1xuICBnZXQgbW9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi5tb2RlO1xuICB9XG4gIHNldCBtb2RlKHYpIHtcbiAgICB0aGlzLnBvc2l0aW9uLm1vZGUgPSB2O1xuICB9XG5cblxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9zbGlkZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IFRvZ2dsZU1vZGVsID0gcmVxdWlyZSgnLi4vbW9kZWxzL3RvZ2dsZScpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5cbi8qKlxuKiBUb2dnbGVcbipcbiogQGRlc2NyaXB0aW9uIEJpbmFyeSBzd2l0Y2hcbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJ0b2dnbGVcIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciB0b2dnbGUgPSBuZXcgTmV4dXMuVG9nZ2xlKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHRvZ2dsZSA9IG5ldyBOZXh1cy5Ub2dnbGUoJyN0YXJnZXQnLHtcbiogICAgICdzaXplJzogWzQwLDIwXSxcbiogICAgICdzdGF0ZSc6IGZhbHNlXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIFBhcmFtZXRlcjogVGhlIGJvb2xlYW4gc3RhdGUgb2YgdGhlIGludGVyZmFjZS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogdG9nZ2xlLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbipcbiovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUb2dnbGUgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3ZhbHVlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFs0MCwyMF0sXG4gICAgICAndGFyZ2V0JzogZmFsc2UsXG4gICAgICAnc3RhdGUnOiBmYWxzZVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLl9zdGF0ZSA9IG5ldyBUb2dnbGVNb2RlbCh0aGlzLnNldHRpbmdzLnN0YXRlKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyID0gc3ZnLmNyZWF0ZSgncmVjdCcpO1xuICAgIHRoaXMua25vYiA9IHN2Zy5jcmVhdGUoJ2NpcmNsZScpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBpZiAodGhpcy5oZWlnaHQgPCB0aGlzLndpZHRoLzIpIHtcbiAgICAgIHRoaXMua25vYlNpemUgPSB0aGlzLmhlaWdodC8yO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmtub2JTaXplID0gdGhpcy53aWR0aC80O1xuICAgIH1cblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneCcsdGhpcy53aWR0aC8yIC0gdGhpcy5rbm9iU2l6ZSoxLjUpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneScsdGhpcy5oZWlnaHQvMiAtIHRoaXMua25vYlNpemUvMik7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsdGhpcy5rbm9iU2l6ZS8yKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3J5Jyx0aGlzLmtub2JTaXplLzIpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnd2lkdGgnLHRoaXMua25vYlNpemUqMyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLHRoaXMua25vYlNpemUpO1xuXG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMud2lkdGgvMiAtIHRoaXMua25vYlNpemUpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmhlaWdodC8yKTtcbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JTaXplKTtcblxuICB9XG5cbiAgY29sb3JJbnRlcmZhY2UoKSB7XG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIgLSB0aGlzLmtub2JTaXplKTtcbiAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeCcsdGhpcy53aWR0aC8yICsgdGhpcy5rbm9iU2l6ZSk7XG4gICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIH1cbiAgfVxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMuZmxpcCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICB9XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIHRvZ2dsZSBpcyBjdXJyZW50bHkgb24gb3Igb2ZmLiBTZXR0aW5nIHRoaXMgcHJvcGVydHkgd2lsbCB1cGRhdGUgdGhlIHRvZ2dsZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge2Jvb2xlYW59XG4gIEBleGFtcGxlIHRvZ2dsZS5zdGF0ZSA9IGZhbHNlO1xuICAqL1xuICBnZXQgc3RhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlLnN0YXRlO1xuICB9XG4gIHNldCBzdGF0ZSh2YWx1ZSkge1xuICAgIHRoaXMuX3N0YXRlLmZsaXAodmFsdWUpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgKiBTd2l0Y2ggdGhlIHRvZ2dsZSBzdGF0ZSB0byBpdHMgb3Bwb3NpdGUgc3RhdGVcbiAgKiBAZXhhbXBsZVxuICAqIHRvZ2dsZS5mbGlwKCk7XG4gICovXG4gIGZsaXAoKSB7XG4gICAgdGhpcy5fc3RhdGUuZmxpcCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvdG9nZ2xlLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBCdXR0b25UZW1wbGF0ZSA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvYnV0dG9udGVtcGxhdGUnKTtcblxuLyoqXG4qIEJ1dHRvblxuKlxuKiBAZGVzY3JpcHRpb24gQ2lyY3VsYXIgYnV0dG9uIHdpdGggb3B0aW9uYWwgYWZ0ZXJ0b3VjaC5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJidXR0b25cIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBidXR0b24gPSBuZXcgTmV4dXMuQnV0dG9uKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIGJ1dHRvbiA9IG5ldyBOZXh1cy5CdXR0b24oJyN0YXJnZXQnLHtcbiogICAnc2l6ZSc6IFs4MCw4MF0sXG4qICAgJ21vZGUnOiAnYWZ0ZXJ0b3VjaCcsXG4qICAgJ3N0YXRlJzogZmFsc2VcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogSW4gPGI+YnV0dG9uIG1vZGU8L2I+LCA8Yj50b2dnbGUgbW9kZTwvYj4sIGFuZCA8Yj5pbXB1bHNlIG1vZGU8L2I+LCB0aGUgb3V0cHV0IGRhdGEgaXMgYSBib29sZWFuIGRlc2NyaWJpbmcgdGhlIHN0YXRlIG9mIHRoZSBidXR0b24uPGJyPlxuKiBJbiA8Yj5hZnRlcnRvdWNoIG1vZGU8L2I+LCB0aGUgb3V0cHV0IGRhdGEgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgeCAoMC0xKSBhbmQgeSAoMC0xKSBwb3NpdGlvbnMgb2YgYWZ0ZXJ0b3VjaC5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogYnV0dG9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICAvLyB2IGlzIHRoZSB2YWx1ZSBvZiB0aGUgYnV0dG9uXG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCdXR0b24gZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnbW9kZSddO1xuXG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFs4MCw4MF0sXG4gICAgICAnbW9kZSc6ICdhZnRlcnRvdWNoJywgLy8gYnV0dG9uLCBhZnRlcnRvdWNoLCBpbXB1bHNlLCB0b2dnbGVcbiAgICAgICdzdGF0ZSc6IGZhbHNlXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuXG4gICAgLyoqXG4gICAgKiBJbnRlcmFjdGlvbiBtb2RlOiBzdXBwb3J0cyBcImJ1dHRvblwiLCBcImFmdGVydG91Y2hcIiwgXCJpbXB1bHNlXCIsIG9yIFwidG9nZ2xlXCJcbiAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgKiBAZXhhbXBsZSBidXR0b24ubW9kZSA9ICd0b2dnbGUnO1xuICAgICovXG4gICAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG4gICAgdGhpcy5wYWQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wYWQpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXG4gICAgLy8gb25seSB1c2VkIGlmIGluICdhZnRlcnRvdWNoJyBtb2RlXG4gICAgdGhpcy5kZWZzID0gc3ZnLmNyZWF0ZSgnZGVmcycpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmRlZnMpO1xuXG4gICAgdGhpcy5ncmFkaWVudCA9IHN2Zy5yYWRpYWxHcmFkaWVudCh0aGlzLmRlZnMsMik7XG5cbiAgICB0aGlzLmdyYWRpZW50LnN0b3BzWzBdLnNldEF0dHJpYnV0ZSgnb2Zmc2V0JywgJzMwJScpO1xuXG4gICAgdGhpcy5ncmFkaWVudC5zdG9wc1sxXS5zZXRBdHRyaWJ1dGUoJ29mZnNldCcsICcxMDAlJyk7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMuaGVpZ2h0LzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgncicsIE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpIC8gMiAtIHRoaXMud2lkdGgvNDApO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJywgdGhpcy53aWR0aC8yMCk7XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuZ3JhZGllbnQuc3RvcHNbMF0uc2V0QXR0cmlidXRlKCdzdG9wLWNvbG9yJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB0aGlzLmdyYWRpZW50LnN0b3BzWzFdLnNldEF0dHJpYnV0ZSgnc3RvcC1jb2xvcicsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKlxuICAqIFVwZGF0ZSB0aGUgdmlzdWFsIGludGVyZmFjZSB1c2luZyBpdHMgY3VycmVudCBzdGF0ZVxuICAqXG4gICogQGV4YW1wbGVcbiAgKiBidXR0b24ucmVuZGVyKCk7XG4gICovXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2UnLCB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLm1vZGU9PT0nYWZ0ZXJ0b3VjaCcpIHtcbiAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2UnLCAndXJsKCMnK3RoaXMuZ3JhZGllbnQuaWQrJyknKTtcbiAgICAgICAgdGhpcy5ncmFkaWVudC5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3gnLCAodGhpcy5wb3NpdGlvbi54KjEwMCkrJyUnKTtcbiAgICAgICAgdGhpcy5ncmFkaWVudC5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3knLCAoKDEtdGhpcy5wb3NpdGlvbi55KSoxMDApKyclJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgICB9XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIH1cbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9idXR0b24uanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IG1hdGggPSByZXF1aXJlKCcuLi91dGlsL21hdGgnKTtcbmxldCBUb2dnbGVNb2RlbCA9IHJlcXVpcmUoJy4uL21vZGVscy90b2dnbGUnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xuXG4vKipcbkJ1dHRvbiBUZW1wbGF0ZVxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnV0dG9uVGVtcGxhdGUgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKGFyZ3Msb3B0aW9ucyxkZWZhdWx0cykge1xuXG4gICAgc3VwZXIoYXJncyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZSB8fCAnYnV0dG9uJztcblxuICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICB4OiAwLFxuICAgICAgeTogMFxuICAgIH07XG5cbiAgICB0aGlzLl9zdGF0ZSA9IG5ldyBUb2dnbGVNb2RlbCh0aGlzLnNldHRpbmdzLnN0YXRlKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG4gICAgdGhpcy5wYWQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAnI2QxOCcpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgJyNkMTgnKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsIDQpO1xuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMucGFkKTtcblxuICAgIHRoaXMuaW50ZXJhY3Rpb25UYXJnZXQgPSB0aGlzLnBhZDtcblxuICAgIHRoaXMuc2l6ZUludGVyZmFjZSgpO1xuICB9XG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMuaGVpZ2h0LzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgncicsIE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpIC8gMiAtIDIpO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5zdGF0ZSkge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuZmlsbCk7XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB9XG4gIH1cblxuICBkb3duKHBhaW50YnJ1c2gpIHtcbiAgICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuICAgICAgY2FzZSAnaW1wdWxzZSc6XG4gICAgICAgIHRoaXMudHVybk9uKCk7XG4gICAgICAgIGlmICh0aGlzLnRpbWVvdXQpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRpbWVvdXQgPSBzZXRUaW1lb3V0KHRoaXMudHVybk9mZi5iaW5kKHRoaXMpLDMwKTtcbiAgICAvLyAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYnV0dG9uJzpcbiAgICAgICAgdGhpcy50dXJuT24oKTtcbiAgICAvLyAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgICB5OiBtYXRoLmNsaXAoMS10aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMudHVybk9uKCk7XG4gICAgLy8gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAvLyAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgIC8vICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgIC8vICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgIC8vICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3RvZ2dsZSc6XG4gICAgICAgIHRoaXMuZmxpcChwYWludGJydXNoKTtcbiAgICAvLyAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICB9XG5cbiAgYmVuZChtb3VzZSkge1xuICAgIGlmICh0aGlzLm1vZGU9PT0nYWZ0ZXJ0b3VjaCcpIHtcbiAgICAgIHRoaXMubW91c2UgPSBtb3VzZSB8fCB0aGlzLm1vdXNlO1xuICAgICAgdGhpcy5wb3NpdGlvbiA9IHtcbiAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICB9O1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIHVwKCkge1xuICAgIHN3aXRjaCAodGhpcy5tb2RlKSB7XG4gICAgICBjYXNlICdidXR0b24nOlxuICAgICAgICB0aGlzLnR1cm5PZmYoKTtcbiAgICAgIC8vICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMudHVybk9mZigpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uID0ge1xuICAgICAgICAgIHg6IG1hdGguY2xpcCh0aGlzLm1vdXNlLnggLyB0aGlzLndpZHRoLDAsMSksXG4gICAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICAgIH07XG4gICAgICAvLyAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgIC8vICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgLy8gICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgICAgLy8gICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgLy8gIH0pO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvKiBvdmVyd3JpdGFibGUgaW50ZXJhY3Rpb24gaGFuZGxlcnMgKi9cblxuICBjbGljaygpIHtcbiAgICB0aGlzLmRvd24oKTtcbiAgfVxuICBtb3ZlKCkge1xuICAgIHRoaXMuYmVuZCgpO1xuICB9XG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy51cCgpO1xuICB9XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIGJ1dHRvbiBpcyBvbiAocHJlc3NlZCkgb3Igb2ZmIChub3QgcHJlc3NlZClcbiAgQHR5cGUge2Jvb2xlYW59XG4gIEBleGFtcGxlIGJ1dHRvbi5zdGF0ZSA9IHRydWU7XG4gICovXG4gIGdldCBzdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGUuc3RhdGU7XG4gIH1cbiAgc2V0IHN0YXRlKHZhbHVlKSB7XG4gICAgdGhpcy5fc3RhdGUuZmxpcCh2YWx1ZSk7XG4gICAgaWYgKHRoaXMubW9kZT09PSdhZnRlcnRvdWNoJykge1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICB9XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBDaGFuZ2UgdGhlIGJ1dHRvbiB0byBpdHMgYWx0ZXJuYXRlIHN0YXRlIChvZmY9Pm9uLCBvbj0+b2ZmKSwgb3IgZmxpcCBpdCB0byBhIHNwZWNpZmllZCBzdGF0ZS5cbiAgQHBhcmFtIHZhbHVlIHtib29sZWFufSAoT3B0aW9uYWwpIFN0YXRlIHRvIGZsaXAgdG8uXG4gIEBleGFtcGxlIGJ1dHRvbi5mbGlwKCk7XG4gICovXG4gIGZsaXAodmFsdWUpIHtcbiAgICB0aGlzLl9zdGF0ZS5mbGlwKHZhbHVlKTtcbiAgICBpZiAodGhpcy5tb2RlPT09J2FmdGVydG91Y2gnKSB7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgICAgICB5OiB0aGlzLnBvc2l0aW9uLnksXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICAgIH1cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIFR1cm4gdGhlIGJ1dHRvbidzIHN0YXRlIHRvIHRydWUuXG4gIEBleGFtcGxlIGJ1dHRvbi50dXJuT24oKTtcbiAgKi9cbiAgdHVybk9uKGVtaXR0aW5nKSB7XG4gICAgdGhpcy5fc3RhdGUub24oKTtcbiAgICBpZiAoZW1pdHRpbmchPT1mYWxzZSkge1xuICAgICAgaWYgKHRoaXMubW9kZT09PSdhZnRlcnRvdWNoJykge1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgICB5OiB0aGlzLnBvc2l0aW9uLnksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIFR1cm4gdGhlIGJ1dHRvbidzIHN0YXRlIHRvIGZhbHNlLlxuICBAZXhhbXBsZSBidXR0b24udHVybk9mZigpO1xuICAqL1xuICB0dXJuT2ZmKGVtaXR0aW5nKSB7XG4gICAgdGhpcy5fc3RhdGUub2ZmKCk7XG4gICAgaWYgKGVtaXR0aW5nIT09ZmFsc2UpIHtcbiAgICAgIGlmICh0aGlzLm1vZGU9PT0nYWZ0ZXJ0b3VjaCcpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG4gICAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvY29tcG9uZW50cy9idXR0b250ZW1wbGF0ZS5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IEJ1dHRvblRlbXBsYXRlID0gcmVxdWlyZSgnLi4vY29tcG9uZW50cy9idXR0b250ZW1wbGF0ZScpO1xuXG4vKipcbiogVGV4dEJ1dHRvblxuKlxuKiBAZGVzY3JpcHRpb24gVGV4dCBidXR0b25cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJ0ZXh0QnV0dG9uXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgdGV4dGJ1dHRvbiA9IG5ldyBOZXh1cy5UZXh0QnV0dG9uKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHRleHRidXR0b24gPSBuZXcgTmV4dXMuVGV4dEJ1dHRvbignI3RhcmdldCcse1xuKiAgICAgJ3NpemUnOiBbMTUwLDUwXSxcbiogICAgICdzdGF0ZSc6IGZhbHNlLFxuKiAgICAgJ3RleHQnOiAnUGxheScsXG4qICAgICAnYWx0ZXJuYXRlVGV4dCc6ICdTdG9wJ1xuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhIDxpPnN0cmluZzwvaT4gb2YgdGhlIHRleHQgb24gdGhlIGJ1dHRvbiBhdCB0aGUgbW9tZW50IGl0IHdhcyBjbGlja2VkLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiB0ZXh0YnV0dG9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRleHRCdXR0b24gZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzE1MCw1MF0sXG4gICAgICAnc3RhdGUnOiBmYWxzZSxcbiAgICAgICd0ZXh0JzogJ1BsYXknXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuX3RleHQgPSB0aGlzLnNldHRpbmdzLnRleHQ7XG5cbiAgICBpZih0aGlzLnNldHRpbmdzLmFsdGVybmF0ZSl7IC8vVE9ETzogUmVtb3ZlIHRoaXMgY29uZGl0aW9uYWwgaW4gYSBicmVha2luZy1jaGFuZ2VzIHJlbGVhc2VcbiAgICAgIHRoaXMuc2V0dGluZ3MuYWx0ZXJuYXRlVGV4dCA9IHRoaXMuc2V0dGluZ3MuYWx0ZXJuYXRlO1xuICAgICAgY29uc29sZS53YXJuKFwiJ2FsdGVybmF0ZScgaW5pdGlhdG9yIGlzIGRlcHJlY2F0ZWQuIFVzZSAnYWx0ZXJuYXRlVGV4dCcgaW5zdGVhZC5cIik7XG4gICAgfVxuICAgIHRoaXMuX2FsdGVybmF0ZVRleHQgPSB0aGlzLnNldHRpbmdzLmFsdGVybmF0ZVRleHQ7XG4gICAgdGhpcy5tb2RlID0gKHRoaXMuc2V0dGluZ3MuYWx0ZXJuYXRlVGV4dCkgPyAndG9nZ2xlJyA6ICdidXR0b24nO1xuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICB0aGlzLnN0YXRlID0gdGhpcy5zZXR0aW5ncy5zdGF0ZTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcblxuICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG5cbiAgICB0aGlzLnRleHRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl90ZXh0O1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnRleHRFbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY29sb3IgPSB0aGlzLmNvbG9ycy5kYXJrO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuICAgICAgbGV0IHRleHRzaXplID0gdGhpcy5oZWlnaHQvMztcbiAgICAgIGxldCB0ZXh0c2l6ZTIgPSAodGhpcy53aWR0aCAvICh0aGlzLl90ZXh0Lmxlbmd0aCArIDIpICk7XG4gICAgICB0ZXh0c2l6ZSA9IE1hdGgubWluKHRleHRzaXplLHRleHRzaXplMik7XG4gICAgICBpZiAodGhpcy5hbHRlcm5hdGVUZXh0KSB7XG4gICAgICAgIGxldCB0ZXh0c2l6ZTMgPSAodGhpcy53aWR0aCAvICh0aGlzLmFsdGVybmF0ZVRleHQubGVuZ3RoICsgMikgKTtcbiAgICAgICAgdGV4dHNpemUgPSBNYXRoLm1pbih0ZXh0c2l6ZSx0ZXh0c2l6ZTMpO1xuICAgICAgfVxuICAgICAgbGV0IHN0eWxlcyA9ICd3aWR0aDogJyArIHRoaXMud2lkdGggKyAncHg7JztcbiAgICAgIHN0eWxlcyArPSAnaGVpZ2h0OiAnICsgdGhpcy5oZWlnaHQgKyAncHg7JztcbiAgICAgIHN0eWxlcyArPSAncGFkZGluZzogJysodGhpcy5oZWlnaHQtdGV4dHNpemUpLzIrJ3B4IDBweDsnO1xuICAgICAgc3R5bGVzICs9ICdib3gtc2l6aW5nOiBib3JkZXItYm94Oyc7XG4gICAgICBzdHlsZXMgKz0gJ3RleHQtYWxpZ246IGNlbnRlcjsnO1xuICAgICAgc3R5bGVzICs9ICdmb250LWZhbWlseTogaW5oZXJpdDsnO1xuICAgICAgc3R5bGVzICs9ICdmb250LXdlaWdodDogNzAwOyc7XG4gICAgICBzdHlsZXMgKz0gJ29wYWNpdHk6IDE7JztcbiAgICAgIHN0eWxlcyArPSAnZm9udC1zaXplOicgKyB0ZXh0c2l6ZSArICdweDsnO1xuICAgICAgdGhpcy50ZXh0RWxlbWVudC5zdHlsZS5jc3NUZXh0ID0gc3R5bGVzO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5maWxsO1xuICAgICAgdGhpcy50ZXh0RWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG4gICAgICB0aGlzLnRleHRFbGVtZW50LmlubmVySFRNTCA9IHRoaXMuX3RleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG4gICAgICB0aGlzLnRleHRFbGVtZW50LnN0eWxlLmNvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICAgIGlmICh0aGlzLmFsdGVybmF0ZVRleHQpIHtcbiAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl9hbHRlcm5hdGVUZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl90ZXh0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICBUaGUgdGV4dCB0byBkaXNwbGF5IHdoZW4gdGhlIGJ1dHRvbiBpcyBpbiBpdHMgXCJvblwiIHN0YXRlLiBJZiBzZXQsIHRoaXMgcHV0cyB0aGUgYnV0dG9uIGluIFwidG9nZ2xlXCIgbW9kZS5cbiAgQHR5cGUge1N0cmluZ31cbiAgKi9cbiAgZ2V0IGFsdGVybmF0ZVRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsdGVybmF0ZVRleHQ7XG4gIH1cblxuICBzZXQgYWx0ZXJuYXRlVGV4dCh0ZXh0KSB7XG4gICAgaWYgKHRleHQpIHtcbiAgICAgIHRoaXMubW9kZSA9ICd0b2dnbGUnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1vZGUgPSAnYnV0dG9uJztcbiAgICB9XG4gICAgdGhpcy5fYWx0ZXJuYXRlVGV4dCA9IHRleHQ7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIFRoZSB0ZXh0IHRvIGRpc3BsYXkuIChJZiAuYWx0ZXJuYXRlVGV4dCBleGlzdHMsIHRoZW4gdGhpcyAudGV4dCB3aWxsIG9ubHkgYmUgZGlzcGxheWVkIHdoZW4gdGhlIGJ1dHRvbiBpcyBpbiBpdHMgXCJvZmZcIiBzdGF0ZS4pXG4gIEB0eXBlIHtTdHJpbmd9XG4gICovXG4gIGdldCB0ZXh0KCkge1xuICAgIHJldHVybiB0aGlzLl90ZXh0O1xuICB9XG5cbiAgc2V0IHRleHQodGV4dCkge1xuICAgIHRoaXMuX3RleHQgPSB0ZXh0O1xuICAgIHRoaXMuc2l6ZUludGVyZmFjZSgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy90ZXh0YnV0dG9uLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG4vL2xldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgQnV0dG9uID0gcmVxdWlyZSgnLi4vaW50ZXJmYWNlcy9idXR0b24nKTtcblxuLyoqXG4qIFJhZGlvQnV0dG9uXG4qXG4qIEBkZXNjcmlwdGlvbiBBbiBhcnJheSBvZiBidXR0b25zLiBCeSBkZWZhdWx0LCBzZWxlY3Rpbmcgb25lIGJ1dHRvbiB3aWxsIGRlc2VsZWN0IGFsbCBvdGhlciBidXR0b25zLCBidXQgdGhpcyBjYW4gYmUgY3VzdG9taXplZCB1c2luZyB0aGUgQVBJIGJlbG93LlxuKlxuKiBAZGVtbyA8ZGl2IG5leHVzLXVpPVwiUmFkaW9CdXR0b25cIj48L2Rpdj5cbipcbiogQGV4YW1wbGVcbiogdmFyIHJhZGlvYnV0dG9uID0gbmV3IE5leHVzLlJhZGlvQnV0dG9uKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHJhZGlvYnV0dG9uID0gbmV3IE5leHVzLlJhZGlvQnV0dG9uKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMTIwLDI1XSxcbiogICAnbnVtYmVyT2ZCdXR0b25zJzogNCxcbiogICAnYWN0aXZlJzogLTFcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgYW4gPGk+aW50ZWdlcjwvaT4sIHRoZSBpbmRleCBvZiB0aGUgYnV0dG9uIHRoYXQgaXMgY3VycmVudGx5IG9uLiBJZiBubyBidXR0b24gaXMgc2VsZWN0ZWQsIHRoZSB2YWx1ZSB3aWxsIGJlIC0xLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiByYWRpb2J1dHRvbi5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSYWRpb0J1dHRvbiBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzEyMCwyNV0sXG4gICAgICAnbnVtYmVyT2ZCdXR0b25zJzogNCxcbiAgICAgICdhY3RpdmUnOiAtMVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLmJ1dHRvbnMgPSBbXTtcbiAgICB0aGlzLl9udW1iZXJPZkJ1dHRvbnMgPSB0aGlzLnNldHRpbmdzLm51bWJlck9mQnV0dG9ucztcbiAgICB0aGlzLmFjdGl2ZSA9IHRoaXMuc2V0dGluZ3MuYWN0aXZlO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLl9udW1iZXJPZkJ1dHRvbnM7aSsrKSB7XG4gICAgICBsZXQgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuXG4gICAgICBsZXQgYnV0dG9uID0gbmV3IEJ1dHRvbihjb250YWluZXIsIHtcbiAgICAgICAgICBtb2RlOiAndG9nZ2xlJyxcbiAgICAgICAgICBjb21wb25lbnQ6IHRydWUsXG4gICAgICAgIH0sIHRoaXMudXBkYXRlLmJpbmQodGhpcyxpKSk7XG5cbiAgICAgIHRoaXMuYnV0dG9ucy5wdXNoKGJ1dHRvbik7XG4gICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgICB9XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBsZXQgYnV0dG9uV2lkdGggPSB0aGlzLndpZHRoIC8gdGhpcy5fbnVtYmVyT2ZCdXR0b25zO1xuICAgIGxldCBidXR0b25IZWlnaHQgPSB0aGlzLmhlaWdodDtcblxuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuX251bWJlck9mQnV0dG9ucztpKyspIHtcbiAgICAgIHRoaXMuYnV0dG9uc1tpXS5yZXNpemUoYnV0dG9uV2lkdGgsYnV0dG9uSGVpZ2h0KTtcbiAgICB9XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuX251bWJlck9mQnV0dG9ucztpKyspIHtcbiAgICAgIHRoaXMuYnV0dG9uc1tpXS5jb2xvcnMgPSB0aGlzLmNvbG9ycztcbiAgICAgIHRoaXMuYnV0dG9uc1tpXS5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGUoaW5kZXgpIHtcbiAgICBpZiAodGhpcy5idXR0b25zW2luZGV4XS5zdGF0ZSkge1xuICAgICAgdGhpcy5zZWxlY3QoaW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlc2VsZWN0KCk7XG4gICAgfVxuICAvLyAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLmJ1dHRvbnMubGVuZ3RoO2krKykge1xuICAgICAgaWYgKGk9PT10aGlzLmFjdGl2ZSkge1xuICAgICAgICB0aGlzLmJ1dHRvbnNbaV0udHVybk9uKGZhbHNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYnV0dG9uc1tpXS50dXJuT2ZmKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgU2VsZWN0IG9uZSBidXR0b24gYW5kIGRlc2VsZWN0IGFsbCBvdGhlciBidXR0b25zLlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBidXR0b24gdG8gc2VsZWN0XG4gICovXG4gIHNlbGVjdChpbmRleCkge1xuICAgIGlmIChpbmRleD49MCAmJiBpbmRleCA8IHRoaXMuYnV0dG9ucy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuYWN0aXZlID0gaW5kZXg7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5hY3RpdmUpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgRGVzZWxlY3QgYWxsIGJ1dHRvbnMuXG4gICovXG4gIGRlc2VsZWN0KCkge1xuICAgIHRoaXMuYWN0aXZlID0gLTE7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuYWN0aXZlKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgZ2V0IG51bWJlck9mQnV0dG9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5fbnVtYmVyT2ZCdXR0b25zO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBob3cgbWFueSBidXR0b25zIGFyZSBpbiB0aGUgaW50ZXJmYWNlXG4gICAqIEBwYXJhbSAge251bWJlcn0gYnV0dG9ucyBIb3cgbWFueSBidXR0b25zIGFyZSBpbiB0aGUgaW50ZXJmYWNlXG4gICAqL1xuICBzZXQgbnVtYmVyT2ZCdXR0b25zKGJ1dHRvbnMpIHtcbiAgICB0aGlzLl9udW1iZXJPZkJ1dHRvbnMgPSBidXR0b25zO1xuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuYnV0dG9ucy5sZW5ndGg7aSsrKSB7XG4gICAgICB0aGlzLmJ1dHRvbnNbaV0uZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLmJ1dHRvbnMgPSBbXTtcbiAgLy8gIGZvciAobGV0IGk9MDtpPHRoaXMuYnV0dG9ucy5sZW5ndGg7aSsrKSB7XG4gIC8vICAgIHRoaXMuYnV0dG9uc1tpXS5kZXN0cm95KCk7XG4gIC8vICB9XG4gICAgdGhpcy5lbXB0eSgpO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9yYWRpb2J1dHRvbi5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgU3RlcCA9IHJlcXVpcmUoJy4uL21vZGVscy9zdGVwJyk7XG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xuXG4vKipcbiogTnVtYmVyXG4qXG4qIEBkZXNjcmlwdGlvbiBOdW1iZXIgaW50ZXJmYWNlIHdoaWNoIGlzIGNvbnRyb2xsYWJsZSBieSBkcmFnZ2luZyBvciB0eXBpbmcuXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwibnVtYmVyXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgbnVtYmVyID0gbmV3IE5leHVzLk51bWJlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBudW1iZXIgPSBuZXcgTmV4dXMuTnVtYmVyKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbNjAsMzBdLFxuKiAgICd2YWx1ZSc6IDAsXG4qICAgJ21pbic6IDAsXG4qICAgJ21heCc6IDIwMDAwLFxuKiAgICdzdGVwJzogMVxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyB0aGUgbnVtYmVyIHZhbHVlIG9mIHRoZSBpbnRlcmZhY2UuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIG51bWJlci5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qXG4qL1xuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE51bWJlciBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzYwLDMwXSxcbiAgICAgICd2YWx1ZSc6IDAsXG4gICAgICAnbWluJzogMCxcbiAgICAgICdtYXgnOiAyMDAwMCxcbiAgICAgICdzdGVwJzogMVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLl92YWx1ZSA9IG5ldyBTdGVwKHRoaXMuc2V0dGluZ3MubWluLHRoaXMuc2V0dGluZ3MubWF4LHRoaXMuc2V0dGluZ3Muc3RlcCx0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIC8qXG4gICAgRGVmYXVsdDogMi4gSG93IG1hbnkgZGVjaW1hbCBwbGFjZXMgdG8gY2xpcCB0aGUgbnVtYmVyJ3MgdmlzdWFsIHJlbmRlcmluZyB0by4gVGhpcyBkb2VzIG5vdCBhZmZlY3QgbnVtYmVyJ3MgYWN0dWFsIHZhbHVlIG91dHB1dCAtLSBmb3IgdGhhdCwgc2V0IHRoZSBzdGVwIHByb3BlcnR5IHRvIC4wMSwgLjEsIG9yIDEuXG4gICAgQHR5cGUge251bWJlcn1cbiAgICBAZXhhbXBsZSBudW1iZXIuZGVjaW1hbFBsYWNlcyA9IDI7XG4gICAgKi9cbiAgICB0aGlzLmRlY2ltYWxQbGFjZXMgPSAyO1xuICAgIHRoaXMuYWN0dWFsID0gMDtcblxuICAgIHRoaXMubWF4ID0gdGhpcy5fdmFsdWUubWF4O1xuXG4gICAgdGhpcy5taW4gPSB0aGlzLl92YWx1ZS5taW47XG5cbiAgICB0aGlzLnN0ZXAgPSB0aGlzLl92YWx1ZS5zdGVwO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgIHRoaXMuZWxlbWVudC50eXBlID0gJ3RleHQnO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCBmdW5jdGlvbiAoKSB7XG4gIFx0ICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgXHQgIHRoaXMuZWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG4gIFx0ICBpZiAodGhpcy5lbGVtZW50LnZhbHVlICE9PSB0aGlzLnZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBwYXJzZUZsb2F0KHRoaXMuZWxlbWVudC52YWx1ZSk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gIFx0ICB9XG4gIFx0fS5iaW5kKHRoaXMpKTtcblxuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBmdW5jdGlvbiAoZSkge1xuICBcdCAgaWYgKGUud2hpY2ggPCA0OCB8fCBlLndoaWNoID4gNTcpIHtcbiAgXHQgIFx0aWYgKGUud2hpY2ggIT09IDE4OSAmJiBlLndoaWNoICE9PSAxOTAgJiYgZS53aGljaCAhPT0gOCkge1xuICBcdCAgXHRcdGUucHJldmVudERlZmF1bHQoKTtcbiAgXHQgIFx0fVxuICBcdCAgfVxuICBcdCAgaWYgKGUud2hpY2g9PT0xMykge1xuICBcdCAgXHR0aGlzLmVsZW1lbnQuYmx1cigpO1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5lbGVtZW50LnZhbHVlO1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gIFx0ICB9XG4gIFx0fS5iaW5kKHRoaXMpKTtcblxuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLl9taW5EaW1lbnNpb24gPSBNYXRoLm1pbih0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcblxuICAgIGxldCBzdHlsZXMgPSAnd2lkdGg6ICcgKyB0aGlzLndpZHRoICsgJ3B4Oyc7XG4gICAgc3R5bGVzICs9ICdoZWlnaHQ6ICcgKyB0aGlzLmhlaWdodCArICdweDsnO1xuICAgIHN0eWxlcyArPSAnYmFja2dyb3VuZC1jb2xvcjogI2U3ZTdlNzsnO1xuICAgIHN0eWxlcyArPSAnY29sb3I6ICMzMzM7JztcbiAgICBzdHlsZXMgKz0gJ2ZvbnQtZmFtaWx5OiBhcmlhbDsnO1xuICAgIHN0eWxlcyArPSAnZm9udC13ZWlnaHQ6IDUwMDsnO1xuICAgIHN0eWxlcyArPSAnZm9udC1zaXplOicgKyB0aGlzLl9taW5EaW1lbnNpb24vMiArICdweDsnO1xuICAvLyAgc3R5bGVzICs9ICdoaWdobGlnaHQ6ICNkMTg7JztcbiAgICBzdHlsZXMgKz0gJ2JvcmRlcjogbm9uZTsnO1xuICAgIHN0eWxlcyArPSAnb3V0bGluZTogbm9uZTsnO1xuICAgIHN0eWxlcyArPSAncGFkZGluZzogJyt0aGlzLl9taW5EaW1lbnNpb24vNCsncHggJyt0aGlzLl9taW5EaW1lbnNpb24vNCsncHg7JztcbiAgICBzdHlsZXMgKz0gJ2JveC1zaXppbmc6IGJvcmRlci1ib3g7JztcbiAgICBzdHlsZXMgKz0gJ3VzZXJTZWxlY3Q6IHRleHQ7JztcbiAgICBzdHlsZXMgKz0gJ21velVzZXJTZWxlY3Q6IHRleHQ7JztcbiAgICBzdHlsZXMgKz0gJ3dlYmtpdFVzZXJTZWxlY3Q6IHRleHQ7JztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY3NzVGV4dCArPSBzdHlsZXM7XG5cbiAgICAvLyB0byBhZGQgZXZlbnR1YWxseVxuICAgIC8vIHZhciBjc3MgPSAnIycrdGhpcy5lbGVtZW50SUQrJzo6c2VsZWN0aW9ueyBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudCB9JztcblxuICAgIHRoaXMuZWxlbWVudC52YWx1ZSA9IHRoaXMudmFsdWU7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY29sb3IgPSB0aGlzLmNvbG9ycy5kYXJrO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuXG4gICAgdGhpcy5lbGVtZW50LnZhbHVlID0gbWF0aC5wcnVuZSh0aGlzLnZhbHVlLHRoaXMuZGVjaW1hbFBsYWNlcyk7XG5cbiAgfVxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMuaGFzTW92ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmVsZW1lbnQucmVhZE9ubHkgPSB0cnVlO1xuXHQgIHRoaXMuYWN0dWFsID0gdGhpcy52YWx1ZTtcbiAgICB0aGlzLmluaXRpYWwgPSB7IHk6IHRoaXMubW91c2UueSB9O1xuICAgIHRoaXMuY2hhbmdlRmFjdG9yID0gbWF0aC5pbnZlcnQoIHRoaXMubW91c2UueCAvIHRoaXMud2lkdGggKTtcbiAgICBjb25zb2xlLmxvZyh0aGlzLmNoYW5nZUZhY3Rvcik7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIHRoaXMuaGFzTW92ZWQgPSB0cnVlO1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcblxuICAgICAgbGV0IG5ld3ZhbHVlID0gdGhpcy5hY3R1YWwgLSAodGhpcy5tb3VzZS55IC0gdGhpcy5pbml0aWFsLnkpICogKCBtYXRoLmNsaXAoIHRoaXMubWF4LXRoaXMubWluLCAwLCAxMDAwICkgLyAyMDAgKSAqIE1hdGgucG93KHRoaXMuY2hhbmdlRmFjdG9yLDIpO1xuICAgICAgdGhpcy52YWx1ZSA9IG5ld3ZhbHVlO1xuXG4gIFx0XHR0aGlzLnJlbmRlcigpO1xuICAgICAgaWYgKHRoaXMuX3ZhbHVlLmNoYW5nZWQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuICAgICAgfVxuXG4gIFx0fVxuICB9XG5cbiAgcmVsZWFzZSgpIHtcbiAgICBpZiAoIXRoaXMuaGFzTW92ZWQpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5yZWFkT25seSA9IGZhbHNlO1xuICBcdFx0dGhpcy5lbGVtZW50LmZvY3VzKCk7XG4gIFx0XHR0aGlzLmVsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UoMCwgdGhpcy5lbGVtZW50LnZhbHVlLmxlbmd0aCk7XG4gIFx0XHR0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuICBcdFx0dGhpcy5lbGVtZW50LnN0eWxlLmNvbG9yID0gdGhpcy5jb2xvcnMubGlnaHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRvY3VtZW50LmJvZHkuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgQ29ubmVjdCB0aGlzIG51bWJlciBpbnRlcmZhY2UgdG8gYSBkaWFsIG9yIHNsaWRlclxuICBAcGFyYW0ge0ludGVyZmFjZX0gZWxlbWVudCBFbGVtZW50IHRvIGNvbm5lY3QgdG8uXG4gIEBleGFtcGxlIG51bWJlci5saW5rKHNsaWRlcilcbiAgKi9cbiAgbGluayhkZXN0aW5hdGlvbikge1xuICAgIHRoaXMubWluID0gZGVzdGluYXRpb24ubWluO1xuICAgIHRoaXMubWF4ID0gZGVzdGluYXRpb24ubWF4O1xuICAgIHRoaXMuc3RlcCA9IGRlc3RpbmF0aW9uLnN0ZXA7XG4gICAgZGVzdGluYXRpb24ub24oJ2NoYW5nZScsKHYpID0+IHtcbiAgICAgIHRoaXMucGFzc2l2ZVVwZGF0ZSh2KTtcbiAgICB9KTtcbiAgICB0aGlzLm9uKCdjaGFuZ2UnLCh2KSA9PiB7XG4gICAgICBkZXN0aW5hdGlvbi52YWx1ZSA9IHY7XG4gICAgfSk7XG4gICAgdGhpcy52YWx1ZSA9IGRlc3RpbmF0aW9uLnZhbHVlO1xuICAvKiAgcmV0dXJuIHtcbiAgICAgIGxpc3RlbmVyMTogbGlzdGVuZXIxLFxuICAgICAgbGlzdGVuZXIyOiBsaXN0ZW5lcjIsXG4gICAgICBkZXN0cm95OiAoKSA9PiB7XG4gICAgICAgIGxpc3RlbmVyMS5yZW1vdmUoKSAob3Igc2ltaWxhcilcbiAgICAgICAgbGlzdGVuZXIyLnJlbW92ZSgpIChvciBzaW1pbGFyKVxuICAgICAgfVxuICAgIH0gKi9cbiAgfVxuXG4gIHBhc3NpdmVVcGRhdGUodikge1xuICAgIHRoaXMuX3ZhbHVlLnVwZGF0ZSh2KTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIFRoZSBpbnRlcmZhY2UncyBjdXJyZW50IHZhbHVlLiBJZiBzZXQgbWFudWFsbHksIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgbnVtYmVyLnZhbHVlID0gMTA7XG4gICovXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHYpIHtcbiAgICB0aGlzLl92YWx1ZS51cGRhdGUodik7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKipcbiAgTG93ZXIgbGltaXQgb2YgdGhlIG51bWJlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBudW1iZXIubWluID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1pbigpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWluO1xuICB9XG4gIHNldCBtaW4odikge1xuICAgIHRoaXMuX3ZhbHVlLm1pbiA9IHY7XG4gIH1cblxuICAvKipcbiAgVXBwZXIgbGltaXQgb2YgdGhlIG51bWJlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBudW1iZXIubWF4ID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWF4O1xuICB9XG4gIHNldCBtYXgodikge1xuICAgIHRoaXMuX3ZhbHVlLm1heCA9IHY7XG4gIH1cblxuICAvKipcbiAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBudW1iZXIncyB2YWx1ZSBjaGFuZ2VzIGJ5LlxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBudW1iZXIuc3RlcCA9IDU7XG4gICovXG4gIGdldCBzdGVwKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5zdGVwO1xuICB9XG4gIHNldCBzdGVwKHYpIHtcbiAgICB0aGlzLl92YWx1ZS5zdGVwID0gdjtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9udW1iZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xuXG4vKipcbiogU2VsZWN0XG4qXG4qIEBkZXNjcmlwdGlvbiBEcm9wZG93biBtZW51XG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwic2VsZWN0XCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc2VsZWN0ID0gbmV3IE5leHVzLlNlbGVjdCgnI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBzZWxlY3QgPSBuZXcgTmV4dXMuU2VsZWN0KCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMTAwLDMwXSxcbiogICAnb3B0aW9ucyc6IFsnZGVmYXVsdCcsJ29wdGlvbnMnXVxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgdGV4dCB2YWx1ZSBvZiB0aGUgc2VsZWN0ZWQgb3B0aW9uLCBhcyB3ZWxsIGFzIHRoZSBudW1lcmljIGluZGV4IG9mIHRoZSBzZWxlY3Rpb24uXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIHNlbGVjdC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qXG4qL1xuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNlbGVjdCBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICAnc2l6ZSc6IFsxMDAsMzBdLFxuICAgICAgICdvcHRpb25zJzogWydkZWZhdWx0Jywnb3B0aW9ucyddXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSAtMTtcbiAgICB0aGlzLl92YWx1ZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5fb3B0aW9ucyA9IHRoaXMuc2V0dGluZ3Mub3B0aW9ucztcblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2VsZWN0Jyk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmZvbnRTaXplID0gdGhpcy5oZWlnaHQvMisncHgnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5vdXRsaW5lID0gJ25vbmUnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5oaWdobGlnaHQgPSAnbm9uZSc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLndpZHRoID0gdGhpcy53aWR0aCsncHgnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmhlaWdodCsncHgnO1xuXG4gICAgdGhpcy5ib3VuZFJlbmRlciA9IHRoaXMucmVuZGVyLmJpbmQodGhpcyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5ib3VuZFJlbmRlcik7XG5cbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXG4gIH1cblxuICBhdHRhY2hMaXN0ZW5lcnMoKSB7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5kZWZpbmVPcHRpb25zKCk7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5maWxsO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmJvcmRlciA9ICdzb2xpZCAwcHggJyt0aGlzLmNvbG9ycy5tZWRpdW1MaWdodDtcbiAgfVxuXG4gIHJlbmRlcigpIHtcblxuICAgIHRoaXMuX3ZhbHVlID0gdGhpcy5lbGVtZW50Lm9wdGlvbnNbdGhpcy5lbGVtZW50LnNlbGVjdGVkSW5kZXhdLnRleHQ7XG4gICAgdGhpcy5fc2VsZWN0ZWRJbmRleCA9IHRoaXMuZWxlbWVudC5zZWxlY3RlZEluZGV4O1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICB2YWx1ZTogdGhpcy5fdmFsdWUsXG4gICAgICBpbmRleDogdGhpcy5fc2VsZWN0ZWRJbmRleFxuICAgIH0pO1xuXG4gIH1cblxuICBjbGljaygpIHtcblxuICB9XG5cbiAgbW92ZSgpIHtcblxuICB9XG5cbiAgcmVsZWFzZSgpIHtcblxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgbGlzdCBvZiBvcHRpb25zLiBUaGlzIHJlbW92ZXMgYWxsIGV4aXN0aW5nIG9wdGlvbnMgYW5kIGNyZWF0ZXMgYSBuZXcgbGlzdCBvZiBvcHRpb25zLlxuICAgKiBAcGFyYW0gIHthcnJheX0gb3B0aW9ucyBOZXcgYXJyYXkgb2Ygb3B0aW9uc1xuICAgKi9cblxuICBkZWZpbmVPcHRpb25zKG9wdGlvbnMpIHtcblxuICAvKiAgZnVuY3Rpb24gcmVtb3ZlT3B0aW9ucyhzZWxlY3Rib3gpXG4gICAge1xuICAgICAgICB2YXIgaTtcbiAgICAgICAgZm9yKGkgPSBzZWxlY3Rib3gub3B0aW9ucy5sZW5ndGggLSAxIDsgaSA+PSAwIDsgaS0tKVxuICAgICAgICB7XG4gICAgICAgICAgICBzZWxlY3Rib3gucmVtb3ZlKGkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vdXNpbmcgdGhlIGZ1bmN0aW9uOlxuICAgIHJlbW92ZU9wdGlvbnMoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJteVNlbGVjdE9iamVjdFwiKSk7ICovXG5cblxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcbiAgICB9XG5cbiAgICBmb3IobGV0IGk9dGhpcy5lbGVtZW50Lm9wdGlvbnMubGVuZ3RoLTE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB0aGlzLmVsZW1lbnQucmVtb3ZlKGkpO1xuICAgIH1cblxuICAgIGZvcihsZXQgaT0wO2k8dGhpcy5fb3B0aW9ucy5sZW5ndGg7aSsrKSB7XG4gICAgICB0aGlzLmVsZW1lbnQub3B0aW9ucy5hZGQobmV3IE9wdGlvbih0aGlzLl9vcHRpb25zW2ldLCBpKSk7XG4gICAgfVxuXG4gIH1cblxuXG4gIC8qKlxuICBUaGUgdGV4dCBvZiB0aGUgb3B0aW9uIHRoYXQgaXMgY3VycmVudGx5IHNlbGVjdGVkLiBJZiBzZXQsIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge1N0cmluZ31cbiAgQGV4YW1wbGUgc2VsZWN0LnZhbHVlID0gXCJzYXd0b290aFwiO1xuICAqL1xuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICB9XG4gIHNldCB2YWx1ZSh2KSB7XG4gICAgdGhpcy5fdmFsdWUgPSB2O1xuICAgIGZvcihsZXQgaT0wO2k8dGhpcy5lbGVtZW50Lm9wdGlvbnMubGVuZ3RoO2krKykge1xuICAgICAgaWYgKHYgPT09IHRoaXMuZWxlbWVudC5vcHRpb25zW2ldLnRleHQpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgVGhlIG51bWVyaWMgaW5kZXggb2YgdGhlIG9wdGlvbiB0aGF0IGlzIGN1cnJlbnRseSBzZWxlY3RlZC4gSWYgc2V0LCB3aWxsIHVwZGF0ZSB0aGUgaW50ZXJmYWNlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNlbGVjdC5zZWxlY3RlZEluZGV4ID0gMjtcbiAgKi9cbiAgZ2V0IHNlbGVjdGVkSW5kZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkSW5kZXg7XG4gIH1cbiAgc2V0IHNlbGVjdGVkSW5kZXgodikge1xuICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSB2O1xuICAgIHRoaXMuZWxlbWVudC5zZWxlY3RlZEluZGV4ID0gdjtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5ib3VuZFJlbmRlcik7XG4gIH1cblxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9zZWxlY3QuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IG1hdGggPSByZXF1aXJlKCcuLi91dGlsL21hdGgnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbi8qKlxuKiBEaWFsXG4qXG4qXG4qIEBkZXNjcmlwdGlvbiBEaWFsIHdpdGggcmFkaWFsIG9yIGxpbmVhciBpbnRlcmFjdGlvbi5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJkaWFsXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgZGlhbCA9IG5ldyBOZXh1cy5EaWFsKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIGRpYWwgPSBuZXcgTmV4dXMuRGlhbCgnI3RhcmdldCcse1xuKiAgICdzaXplJzogWzc1LDc1XSxcbiogICAnaW50ZXJhY3Rpb24nOiAncmFkaWFsJywgLy8gXCJyYWRpYWxcIiwgXCJ2ZXJ0aWNhbFwiLCBvciBcImhvcml6b250YWxcIlxuKiAgICdtb2RlJzogJ3JlbGF0aXZlJywgLy8gXCJhYnNvbHV0ZVwiIG9yIFwicmVsYXRpdmVcIlxuKiAgICdtaW4nOiAwLFxuKiAgICdtYXgnOiAxLFxuKiAgICdzdGVwJzogMCxcbiogICAndmFsdWUnOiAwXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIFRoZSBldmVudCBkYXRhIGlzIHRoZSBudW1iZXIgdmFsdWUgb2YgdGhlIGludGVyZmFjZS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogZGlhbC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qIEB0dXRvcmlhbFxuKiBEaWFsXG4qIHlnR014cVxuKlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGlhbCBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnbWluJywnbWF4JywndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzc1LDc1XSxcbiAgICAgICdpbnRlcmFjdGlvbic6ICdyYWRpYWwnLCAvLyByYWRpYWwsIHZlcnRpY2FsLCBob3Jpem9udGFsXG4gICAgICAnbW9kZSc6ICdyZWxhdGl2ZScsIC8vIGFic29sdXRlLCByZWxhdGl2ZVxuICAgICAgJ21pbic6IDAsXG4gICAgICAnbWF4JzogMSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDBcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvbiA9IHRoaXMuc2V0dGluZ3MuaW50ZXJhY3Rpb247XG5cbiAgICB0aGlzLl92YWx1ZSA9IG5ldyBTdGVwKHRoaXMuc2V0dGluZ3MubWluLCB0aGlzLnNldHRpbmdzLm1heCwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIHRoaXMucG9zaXRpb24gPSBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMuc2V0dGluZ3MubW9kZSx0aGlzLmludGVyYWN0aW9uLFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG5cbiAgICB0aGlzLmluaXQoKTtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblxuICAgIHRoaXMucG9zaXRpb24udmFsdWUgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXG4gICAgdGhpcy5wcmV2aW91c0FuZ2xlID0gZmFsc2U7XG5cbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5iYWNrZ3JvdW5kID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG4gICAgdGhpcy5zY3JldyA9IHN2Zy5jcmVhdGUoJ2NpcmNsZScpO1xuICAgIHRoaXMuaGFuZGxlID0gc3ZnLmNyZWF0ZSgncGF0aCcpO1xuICAgIHRoaXMuaGFuZGxlMiA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmhhbmRsZUZpbGwgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG4gICAgdGhpcy5oYW5kbGUyRmlsbCA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmhhbmRsZUxpbmUgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYWNrZ3JvdW5kKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5oYW5kbGUpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZTIpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZUZpbGwpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZTJGaWxsKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5oYW5kbGVMaW5lKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5zY3Jldyk7XG5cbiAgfVxuXG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcblxuICAgIHRoaXMucG9zaXRpb24ucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG5cbiAgICBsZXQgY2VudGVyID0ge1xuICAgICAgeDogdGhpcy53aWR0aC8yLFxuICAgICAgeTogdGhpcy5oZWlnaHQvMlxuICAgIH07XG5cbiAgICBsZXQgZGlhbWV0ZXIgPSBNYXRoLm1pbih0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcblxuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ2N4JywgY2VudGVyLngpO1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ2N5JywgY2VudGVyLnkpO1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ3InLCBkaWFtZXRlci8yLWRpYW1ldGVyLzQwKTtcblxuICAgIHRoaXMuc2NyZXcuc2V0QXR0cmlidXRlKCdjeCcsIGNlbnRlci54KTtcbiAgICB0aGlzLnNjcmV3LnNldEF0dHJpYnV0ZSgnY3knLCBjZW50ZXIueSk7XG4gICAgdGhpcy5zY3Jldy5zZXRBdHRyaWJ1dGUoJ3InLCBkaWFtZXRlci8xMik7XG5cbiAgICBsZXQgdmFsdWUgPSB0aGlzLnZhbHVlO1xuXG4gICAgbGV0IGhhbmRsZVBvaW50cyA9IHtcbiAgICAgIHN0YXJ0OiBNYXRoLlBJKjEuNSxcbiAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHZhbHVlLDAsMC41LE1hdGguUEkqMS41LE1hdGguUEkqMC41KSAsIE1hdGguUEkqMC41LCBNYXRoLlBJKjEuNSApXG4gICAgfTtcbiAgICBsZXQgaGFuZGxlMlBvaW50cyA9IHtcbiAgICAgIHN0YXJ0OiBNYXRoLlBJKjIuNSxcbiAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHZhbHVlLDAuNSwxLE1hdGguUEkqMi41LE1hdGguUEkqMS41KSAsIE1hdGguUEkqMS41LCBNYXRoLlBJKjIuNSApXG4gICAgfTtcblxuICAgIGxldCBoYW5kbGVQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZVBvaW50cy5zdGFydCwgaGFuZGxlUG9pbnRzLmVuZCk7XG4gICAgbGV0IGhhbmRsZTJQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgIHRoaXMuaGFuZGxlLnNldEF0dHJpYnV0ZSgnZCcsaGFuZGxlUGF0aCk7XG4gICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBkaWFtZXRlci8yMCk7XG4gICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcblxuICAgIHRoaXMuaGFuZGxlMi5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZTJQYXRoKTtcbiAgICB0aGlzLmhhbmRsZTIuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBkaWFtZXRlci8yMCk7XG4gICAgdGhpcy5oYW5kbGUyLnNldEF0dHJpYnV0ZSgnZmlsbCcsICdub25lJyk7XG5cbiAgICBoYW5kbGVQYXRoICs9ICcgTCAnK2NlbnRlci54KycgJytjZW50ZXIueTtcblxuICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZVBhdGgpO1xuICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwtb3BhY2l0eScsICcwLjMnKTtcblxuICAgIGhhbmRsZTJQYXRoICs9ICcgTCAnK2NlbnRlci54KycgJytjZW50ZXIueTtcblxuICAgIHRoaXMuaGFuZGxlMkZpbGwuc2V0QXR0cmlidXRlKCdkJyxoYW5kbGUyUGF0aCk7XG4gICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwtb3BhY2l0eScsICcwLjMnKTtcblxuICAgIGxldCBhcmNFbmRpbmdBO1xuICAgIGlmICh2YWx1ZSA8IDAuNSkge1xuICAgICAgYXJjRW5kaW5nQSA9IGhhbmRsZVBvaW50cy5lbmQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFyY0VuZGluZ0EgPSBoYW5kbGUyUG9pbnRzLmVuZDtcbiAgICB9XG5cbiAgICBsZXQgYXJjRW5kaW5nWCA9IGNlbnRlci54ICsgTWF0aC5jb3MoYXJjRW5kaW5nQSkgKiAoZGlhbWV0ZXIvMik7XG4gICAgbGV0IGFyY0VuZGluZ1kgPSBjZW50ZXIueSArIE1hdGguc2luKGFyY0VuZGluZ0EpICogKGRpYW1ldGVyLzIpICogLTE7XG5cbiAgICB0aGlzLmhhbmRsZUxpbmUuc2V0QXR0cmlidXRlKCdkJywnTSAnK2NlbnRlci54KycgJytjZW50ZXIueSsnIEwgJythcmNFbmRpbmdYKycgJythcmNFbmRpbmdZKTtcbiAgICB0aGlzLmhhbmRsZUxpbmUuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBkaWFtZXRlci8yMCk7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5maWxsKTtcbiAgICB0aGlzLnNjcmV3LnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKCdzdHJva2UnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMuaGFuZGxlMi5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5oYW5kbGVGaWxsLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMuaGFuZGxlTGluZS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXG4gICAgbGV0IGNlbnRlciA9IHtcbiAgICAgIHg6IHRoaXMud2lkdGgvMixcbiAgICAgIHk6IHRoaXMuaGVpZ2h0LzJcbiAgICB9O1xuXG4gICAgbGV0IGRpYW1ldGVyID0gTWF0aC5taW4odGhpcy53aWR0aCx0aGlzLmhlaWdodCk7XG5cbiAgICBsZXQgaGFuZGxlUG9pbnRzID0ge1xuICAgICAgc3RhcnQ6IE1hdGguUEkqMS41LFxuICAgICAgZW5kOiBtYXRoLmNsaXAoIG1hdGguc2NhbGUodmFsdWUsMCwwLjUsTWF0aC5QSSoxLjUsTWF0aC5QSSowLjUpICwgTWF0aC5QSSowLjUsIE1hdGguUEkqMS41IClcbiAgICB9O1xuICAgIGxldCBoYW5kbGUyUG9pbnRzID0ge1xuICAgICAgc3RhcnQ6IE1hdGguUEkgKjIuNSxcbiAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHZhbHVlLDAuNSwxLE1hdGguUEkqMi41LE1hdGguUEkqMS41KSAsIE1hdGguUEkqMS41LCBNYXRoLlBJKjIuNSApXG4gICAgfTtcblxuICAgIGxldCBoYW5kbGVQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZVBvaW50cy5zdGFydCwgaGFuZGxlUG9pbnRzLmVuZCk7XG4gICAgbGV0IGhhbmRsZTJQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgIHRoaXMuaGFuZGxlLnNldEF0dHJpYnV0ZSgnZCcsaGFuZGxlUGF0aCk7XG4gICAgdGhpcy5oYW5kbGUyLnNldEF0dHJpYnV0ZSgnZCcsaGFuZGxlMlBhdGgpO1xuXG5cbiAgICBoYW5kbGVQYXRoICs9ICcgTCAnK2NlbnRlci54KycgJytjZW50ZXIueTtcblxuICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZVBhdGgpO1xuXG4gICAgaGFuZGxlMlBhdGggKz0gJyBMICcrY2VudGVyLngrJyAnK2NlbnRlci55O1xuXG4gICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZTJQYXRoKTtcblxuICAgIGxldCBhcmNFbmRpbmdBO1xuICAgIGlmICh2YWx1ZSA8PSAwLjUpIHtcbiAgICAgIGFyY0VuZGluZ0EgPSBoYW5kbGVQb2ludHMuZW5kO1xuICAgIH0gZWxzZSB7XG4gICAgICBhcmNFbmRpbmdBID0gaGFuZGxlMlBvaW50cy5lbmQ7XG4gICAgfVxuXG4gICAgbGV0IGFyY0VuZGluZ1ggPSBjZW50ZXIueCArIE1hdGguY29zKGFyY0VuZGluZ0EpICogKGRpYW1ldGVyLzIpO1xuICAgIGxldCBhcmNFbmRpbmdZID0gY2VudGVyLnkgKyBNYXRoLnNpbihhcmNFbmRpbmdBKSAqIChkaWFtZXRlci8yKSAqIC0xO1xuXG4gICAgdGhpcy5oYW5kbGVMaW5lLnNldEF0dHJpYnV0ZSgnZCcsJ00gJytjZW50ZXIueCsnICcrY2VudGVyLnkrJyBMICcrYXJjRW5kaW5nWCsnICcrYXJjRW5kaW5nWSk7XG5cbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgaWYgKHRoaXMubW9kZT09PSdyZWxhdGl2ZScpIHtcbiAgICAgIHRoaXMucHJldmlvdXNBbmdsZSA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5tb3ZlKCk7XG4gICB9XG5cbiAgbW92ZSgpIHtcbiAgICBpZiAodGhpcy5jbGlja2VkKSB7XG5cbiAgICAgIHRoaXMucG9zaXRpb24udXBkYXRlKHRoaXMubW91c2UpO1xuXG4gICAgICBsZXQgYW5nbGUgPSB0aGlzLnBvc2l0aW9uLnZhbHVlKk1hdGguUEkqMjtcblxuICAgICAgaWYgKGFuZ2xlIDwgMCApIHsgYW5nbGUgKz0gKE1hdGguUEkqMik7IH1cblxuICAgICAgaWYgKHRoaXMubW9kZSA9PT0gJ3JlbGF0aXZlJykge1xuICAgICAgICBpZiAodGhpcy5wcmV2aW91c0FuZ2xlICE9PSBmYWxzZSAmJiBNYXRoLmFicyh0aGlzLnByZXZpb3VzQW5nbGUgLSBhbmdsZSkgPiAyKSB7XG4gICAgICAgICAgaWYgKHRoaXMucHJldmlvdXNBbmdsZSA+IDMpIHtcbiAgICAgICAgICAgIGFuZ2xlID0gTWF0aC5QSSoyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbmdsZSA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IC8qIGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5wcmV2aW91c0FuZ2xlICE9PSBmYWxzZSAmJiBNYXRoLmFicyh0aGlzLnByZXZpb3VzQW5nbGUgLSBhbmdsZSkgPiAyKSB7XG4gICAgICAgICAgaWYgKHRoaXMucHJldmlvdXNBbmdsZSA+IDMpIHtcbiAgICAgICAgICAgIGFuZ2xlID0gTWF0aC5QSSoyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbmdsZSA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9ICovXG4gICAgICB0aGlzLnByZXZpb3VzQW5nbGUgPSBhbmdsZTtcblxuICAgICAgbGV0IHJlYWxWYWx1ZSA9IGFuZ2xlIC8gKE1hdGguUEkqMik7XG5cbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS51cGRhdGVOb3JtYWwoIHJlYWxWYWx1ZSApO1xuXG4gICAgICBpZiAodGhpcy5tb2RlID09PSAncmVsYXRpdmUnKSB7XG4gICAgICAgIHRoaXMucG9zaXRpb24udmFsdWUgPSByZWFsVmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLl92YWx1ZS52YWx1ZSk7XG5cbiAgICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICB9XG4gIH1cblxuICByZWxlYXNlKCkge1xuICB9XG5cbiAgLypcbiAgRGlhbCdzIHZhbHVlLiBXaGVuIHNldCwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGFkanVzdCB0byBmaXQgbWluL21heC9zdGVwIHNldHRpbmdzIG9mIHRoZSBpbnRlcmZhY2UuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIGRpYWwudmFsdWUgPSAxMDtcblxuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuICB9XG5cbiAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgdGhpcy5fdmFsdWUudXBkYXRlKHZhbHVlKTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuKi9cblxuICAgIC8qKlxuICAgIERpYWwncyB2YWx1ZS4gV2hlbiBzZXQsIGl0IHdpbGwgYXV0b21hdGljYWxseSBiZSBhZGp1c3QgdG8gZml0IG1pbi9tYXgvc3RlcCBzZXR0aW5ncyBvZiB0aGUgaW50ZXJmYWNlLlxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC52YWx1ZSA9IDEwO1xuICAgICovXG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuICAgIH1cbiAgICBzZXQgdmFsdWUodikge1xuICAgICAgdGhpcy5fdmFsdWUudXBkYXRlKHYpO1xuICAgICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5fdmFsdWUudmFsdWUpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICBMb3dlciBsaW1pdCBvZiB0aGUgZGlhbCdzIG91dHB1dCByYW5nZVxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC5taW4gPSAxMDAwO1xuICAgICovXG4gICAgZ2V0IG1pbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5taW47XG4gICAgfVxuICAgIHNldCBtaW4odikge1xuICAgICAgdGhpcy5fdmFsdWUubWluID0gdjtcbiAgICB9XG5cbiAgICAvKipcbiAgICBVcHBlciBsaW1pdCBvZiB0aGUgZGlhbCdzIG91dHB1dCByYW5nZVxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC5tYXggPSAxMDAwO1xuICAgICovXG4gICAgZ2V0IG1heCgpIHtcbiAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5tYXg7XG4gICAgfVxuICAgIHNldCBtYXgodikge1xuICAgICAgdGhpcy5fdmFsdWUubWF4ID0gdjtcbiAgICB9XG5cbiAgICAvKipcbiAgICBUaGUgaW5jcmVtZW50IHRoYXQgdGhlIGRpYWwncyB2YWx1ZSBjaGFuZ2VzIGJ5LlxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC5zdGVwID0gNTtcbiAgICAqL1xuICAgIGdldCBzdGVwKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnN0ZXA7XG4gICAgfVxuICAgIHNldCBzdGVwKHYpIHtcbiAgICAgIHRoaXMuX3ZhbHVlLnN0ZXAgPSB2O1xuICAgIH1cblxuICAgIC8qKlxuICAgIEFic29sdXRlIG1vZGUgKGRpYWwncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJyZWxhdGl2ZVwiLlxuICAgIEB0eXBlIHtzdHJpbmd9XG4gICAgQGV4YW1wbGUgZGlhbC5tb2RlID0gXCJyZWxhdGl2ZVwiO1xuICAgICovXG4gICAgZ2V0IG1vZGUoKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi5tb2RlO1xuICAgIH1cbiAgICBzZXQgbW9kZSh2KSB7XG4gICAgICB0aGlzLnBvc2l0aW9uLm1vZGUgPSB2O1xuICAgIH1cblxuXG4gIC8qKlxuICBOb3JtYWxpemVkIHZhbHVlIG9mIHRoZSBkaWFsLlxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBkaWFsLm5vcm1hbGl6ZWQgPSAwLjU7XG4gICovXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuICB9XG5cbiAgc2V0IG5vcm1hbGl6ZWQodikge1xuICAgIHRoaXMuX3ZhbHVlLnVwZGF0ZU5vcm1hbCh2KTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvZGlhbC5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcbmxldCBCdXR0b25UZW1wbGF0ZSA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvYnV0dG9udGVtcGxhdGUnKTtcbmxldCB0b3VjaCA9IHJlcXVpcmUoJy4uL3V0aWwvdG91Y2gnKTtcblxuY2xhc3MgUGlhbm9LZXkgZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnLCdub3RlJywnY29sb3InXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzgwLDgwXSxcbiAgICAgICd0YXJnZXQnOiBmYWxzZSxcbiAgICAgICdtb2RlJzogJ2J1dHRvbicsXG4gICAgICAndmFsdWUnOiAwXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMubm90ZSA9IHRoaXMuc2V0dGluZ3Mubm90ZTtcbiAgICB0aGlzLmNvbG9yID0gdGhpcy5zZXR0aW5ncy5jb2xvcjtcblxuICAgIHRoaXMuY29sb3JzID0ge1xuICAgICAgJ3cnOiAnI2ZmZicsXG4gICAgICAnYic6ICcjNjY2JyxcbiAgICB9O1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5wYWQgPSBzdmcuY3JlYXRlKCdyZWN0Jyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wYWQpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXG4gICAgLyogZXZlbnRzICovXG5cbiAgICBpZiAoIXRvdWNoLmV4aXN0cykge1xuXG4gICAgICB0aGlzLmNsaWNrID0gKCkgPT4ge1xuICAgICAgLy8gIGNvbnNvbGUubG9nKCdjbGljaycpO1xuICAgICAgICB0aGlzLnBpYW5vLmludGVyYWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5waWFuby5wYWludGJydXNoID0gIXRoaXMuc3RhdGU7XG4gICAgICAgIHRoaXMuZG93bih0aGlzLnBpYW5vLnBhaW50YnJ1c2gpO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5waWFuby5pbnRlcmFjdGluZykge1xuICAgICAgLy8gICAgY29uc29sZS5sb2coJ21vdXNlb3ZlcicpO1xuICAgICAgICAgIHRoaXMuZG93bih0aGlzLnBpYW5vLnBhaW50YnJ1c2gpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuXG4gICAgICB0aGlzLm1vdmUgPSAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnBpYW5vLmludGVyYWN0aW5nKSB7XG4gICAgICAgIC8vICBjb25zb2xlLmxvZygnbW92ZScpO1xuICAgICAgICAgIHRoaXMuYmVuZCgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG5cbiAgICAgIHRoaXMucmVsZWFzZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5waWFuby5pbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgICAgLy8gIGNvbnNvbGUubG9nKCdyZWxlYXNlJyk7XG4gICAgICAvLyAgdGhpcy51cCgpO1xuICAgICAgfTtcbiAgICAgIHRoaXMucGFkLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnBpYW5vLmludGVyYWN0aW5nKSB7XG4gICAgICAgIC8vICBjb25zb2xlLmxvZygnbW91c2V1cCcpO1xuICAgICAgICAgIHRoaXMudXAoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLnBhZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMucGlhbm8uaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgLy8gIGNvbnNvbGUubG9nKCdtb3VzZW91dCcpO1xuICAgICAgICAgIHRoaXMudXAoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICB9XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICAgICAgLy9sZXQgcmFkaXVzID0gTWF0aC5taW4odGhpcy53aWR0aCx0aGlzLmhlaWdodCkgLyA1O1xuICAgICAgICBsZXQgcmFkaXVzID0gMDtcblxuICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3gnLDAuNSk7XG4gICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgneScsMC41KTtcbiAgICAgICAgaWYgKHRoaXMud2lkdGggPiAyKSB7XG4gICAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMud2lkdGggLSAxKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgdGhpcy53aWR0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaGVpZ2h0ID4gMikge1xuICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgncngnLCByYWRpdXMpO1xuICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3J5JywgcmFkaXVzKTtcblxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5zdGF0ZSkge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnNbdGhpcy5jb2xvcl0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIH1cbiAgfVxuXG59XG5cbi8qKlxuKiBQaWFub1xuKlxuKiBAZGVzY3JpcHRpb24gUGlhbm8ga2V5Ym9hcmQgaW50ZXJmYWNlXG4qXG4qIEBkZW1vIDxkaXYgbmV4dXMtdWk9XCJwaWFub1wiPjwvZGl2PlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcGlhbm8gPSBuZXcgTmV4dXMuUGlhbm8oJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcGlhbm8gPSBuZXcgTmV4dXMuUGlhbm8oJyN0YXJnZXQnLHtcbiogICAgICdzaXplJzogWzUwMCwxMjVdLFxuKiAgICAgJ21vZGUnOiAnYnV0dG9uJywgIC8vICdidXR0b24nLCAndG9nZ2xlJywgb3IgJ2ltcHVsc2UnXG4qICAgICAnbG93Tm90ZSc6IDI0LFxuKiAgICAgJ2hpZ2hOb3RlJzogNjBcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgYSBuZXcga2V5IGlzIHByZXNzZWQgb3IgcmVsZWFzZWQgPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyA8aT5ub3RlPC9pPiBhbmQgPGk+c3RhdGU8L2k+IHByb3BlcnRpZXMuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIHBpYW5vLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBpYW5vIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbNTAwLDEyNV0sXG4gICAgICAnbG93Tm90ZSc6IDI0LFxuICAgICAgJ2hpZ2hOb3RlJzogNjAsXG4gICAgICAnbW9kZSc6ICdidXR0b24nXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMua2V5UGF0dGVybiA9IFsndycsJ2InLCd3JywnYicsJ3cnLCd3JywnYicsJ3cnLCdiJywndycsJ2InLCd3J107XG5cbiAgICB0aGlzLnBhaW50YnJ1c2ggPSBmYWxzZTtcblxuICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZTtcblxuICAgIHRoaXMucmFuZ2UgPSB7XG4gICAgICBsb3c6IHRoaXMuc2V0dGluZ3MubG93Tm90ZSxcbiAgICAgIGhpZ2g6IHRoaXMuc2V0dGluZ3MuaGlnaE5vdGVcbiAgICB9O1xuXG4gICAgdGhpcy5yYW5nZS5zaXplID0gdGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7XG5cbiAgICB0aGlzLmtleXMgPSBbXTtcblxuICAgIHRoaXMudG9nZ2xlVG8gPSBmYWxzZTtcblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYm9yZGVyUmFkaXVzID0gJzBweCc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcblxuICAgIHRoaXMua2V5cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7aSsrKSB7XG5cbiAgICAgIGxldCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICBsZXQgc2NhbGVJbmRleCA9IChpK3RoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG5cbiAgICAgIGxldCBrZXkgPSBuZXcgUGlhbm9LZXkoY29udGFpbmVyLCB7XG4gICAgICAgICAgY29tcG9uZW50OiB0cnVlLFxuICAgICAgICAgIG5vdGU6IGkrdGhpcy5yYW5nZS5sb3csXG4gICAgICAgICAgY29sb3I6IHRoaXMua2V5UGF0dGVybltzY2FsZUluZGV4XSxcbiAgICAgICAgICBtb2RlOiB0aGlzLm1vZGVcbiAgICAgICAgfSwgdGhpcy5rZXlDaGFuZ2UuYmluZCh0aGlzLGkrdGhpcy5yYW5nZS5sb3cpKTtcblxuICAgICAga2V5LnBpYW5vID0gdGhpcztcblxuICAgICAgaWYgKHRvdWNoLmV4aXN0cykge1xuICAgICAgICBrZXkucGFkLmluZGV4ID0gaTtcbiAgICAgICAga2V5LnByZUNsaWNrID0ga2V5LnByZU1vdmUgPSBrZXkucHJlUmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgICBrZXkuY2xpY2sgPSBrZXkubW92ZSA9IGtleS5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgICAgIGtleS5wcmVUb3VjaCA9IGtleS5wcmVUb3VjaE1vdmUgPSBrZXkucHJlVG91Y2hSZWxlYXNlID0gKCkgPT4ge307XG4gICAgICAgIGtleS50b3VjaCA9IGtleS50b3VjaE1vdmUgPSBrZXkudG91Y2hSZWxlYXNlID0gKCkgPT4ge307XG4gICAgICB9XG5cbiAgICAgIHRoaXMua2V5cy5wdXNoKGtleSk7XG4gICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblxuICAgIH1cbiAgICBpZiAodG91Y2guZXhpc3RzKSB7XG4gICAgICB0aGlzLmFkZFRvdWNoTGlzdGVuZXJzKCk7XG4gICAgfVxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgbGV0IGtleVggPSAwO1xuXG4gICAgbGV0IGtleVBvc2l0aW9ucyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7aSsrKSB7XG5cbiAgICAgIGtleVBvc2l0aW9ucy5wdXNoKGtleVgpO1xuXG4gICAgICBsZXQgc2NhbGVJbmRleCA9IChpK3RoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG4gICAgICBsZXQgbmV4dFNjYWxlSW5kZXggPSAoaSsxK3RoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG4gICAgICBpZiAoaSsxK3RoaXMucmFuZ2UubG93ID49IHRoaXMucmFuZ2UuaGlnaCkge1xuICAgICAgICBrZXlYICs9IDE7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMua2V5UGF0dGVybltzY2FsZUluZGV4XSA9PT0gJ3cnICYmIHRoaXMua2V5UGF0dGVybltuZXh0U2NhbGVJbmRleF0gPT09ICd3Jykge1xuICAgICAgICBrZXlYICs9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBrZXlYICs9IDAuNTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IGtleXNXaWRlID0ga2V5WDtcblxuXG4gIC8vICBsZXQgcGFkZGluZyA9IHRoaXMud2lkdGggLyAxMjA7XG4gICAgbGV0IHBhZGRpbmcgPSAxO1xuICAgIGxldCBidXR0b25XaWR0aCA9ICh0aGlzLndpZHRoLXBhZGRpbmcqMikgLyBrZXlzV2lkZTtcbiAgICBsZXQgYnV0dG9uSGVpZ2h0ID0gKHRoaXMuaGVpZ2h0LXBhZGRpbmcqMikgLyAyO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5rZXlzLmxlbmd0aDtpKyspIHtcblxuICAgICAgbGV0IGNvbnRhaW5lciA9IHRoaXMua2V5c1tpXS5wYXJlbnQ7XG4gICAgICBjb250YWluZXIuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgY29udGFpbmVyLnN0eWxlLmxlZnQgPSAoa2V5UG9zaXRpb25zW2ldKmJ1dHRvbldpZHRoK3BhZGRpbmcpICsgJ3B4JztcbiAgICAgIGlmICh0aGlzLmtleXNbaV0uY29sb3IgPT09ICd3Jykge1xuICAgICAgICBjb250YWluZXIuc3R5bGUudG9wID0gKHBhZGRpbmcpICsgJ3B4JztcbiAgICAgICAgdGhpcy5rZXlzW2ldLnJlc2l6ZShidXR0b25XaWR0aCwgYnV0dG9uSGVpZ2h0KjIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGFpbmVyLnN0eWxlLnpJbmRleCA9IDE7XG4gICAgICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSBwYWRkaW5nKydweCc7XG4gICAgICAgIHRoaXMua2V5c1tpXS5yZXNpemUoYnV0dG9uV2lkdGgsIGJ1dHRvbkhlaWdodCoxLjEpO1xuICAgICAgfVxuXG4gICAgfVxuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIC8vIFBpYW5vIGtleXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSBhIHN0cm9rZSBib3JkZXJcbiAgICAvLyBUaGV5IGhhdmUgc3BhY2UgYmV0d2VlbiB0aGVtLCB3aGljaCBzaG93cyB0aGUgUGlhbm8gYmcgY29sb3JcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQ7XG5cbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLmtleXMubGVuZ3RoO2krKykge1xuICAgICAgdGhpcy5rZXlzW2ldLmNvbG9ycyA9IHtcbiAgICAgICAgJ3cnOiB0aGlzLmNvbG9ycy5saWdodCxcbiAgICAgICAgJ2InOiB0aGlzLmNvbG9ycy5kYXJrLFxuICAgICAgICAnYWNjZW50JzogdGhpcy5jb2xvcnMuYWNjZW50LFxuICAgICAgICAnYm9yZGVyJzogdGhpcy5jb2xvcnMubWVkaXVtTGlnaHRcbiAgICAgIH07XG4gICAgICB0aGlzLmtleXNbaV0uY29sb3JJbnRlcmZhY2UoKTtcbiAgICAgIHRoaXMua2V5c1tpXS5yZW5kZXIoKTtcbiAgICB9XG5cblxuICB9XG5cbiAga2V5Q2hhbmdlKG5vdGUsb24pIHtcbiAgICAvLyBlbWl0IGRhdGEgZm9yIGFueSBrZXkgdHVybmluZyBvbi9vZmZcbiAgICAvLyBcIm5vdGVcIiBpcyB0aGUgbm90ZSB2YWx1ZVxuICAgIC8vIFwib25cIiBpcyBhIGJvb2xlYW4gd2hldGhlciBpdCBpcyBvbiBvciBvZmZcbiAgICAvLyBpbiBhZnRlcnRvdWNoIG1vZGUsIFwib246IGlzIGFuIG9iamVjdCB3aXRoIHN0YXRlL3gveSBwcm9wZXJ0aWVzXG4gICAgdmFyIGRhdGEgPSB7XG4gICAgICBub3RlOiBub3RlXG4gICAgfTtcbiAgICBpZiAodHlwZW9mIG9uID09PSAnb2JqZWN0Jykge1xuICAgICAgZGF0YS5zdGF0ZSA9IG9uLnN0YXRlO1xuICAgIC8vICBkYXRhLnggPSBvbi54XG4gICAgLy8gIGRhdGEueSA9IG9uLnlcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YS5zdGF0ZSA9IG9uO1xuICAgIH1cbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsZGF0YSk7XG4gIH1cblxuICAvKiBkcmFnKG5vdGUsb24pIHtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgbm90ZTogbm90ZSxcbiAgICAgIHN0YXRlOiBvblxuICAgIH0pO1xuICB9ICovXG5cbiAgcmVuZGVyKCkge1xuICAgIC8vIGxvb3AgdGhyb3VnaCBhbmQgcmVuZGVyIHRoZSBrZXlzP1xuICB9XG5cblxuICBhZGRUb3VjaExpc3RlbmVycygpIHtcblxuICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuXG4gICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGZhbHNlO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoZSkgPT4ge1xuICAgICAgY29uc29sZS5sb2coJ3RvdWNoc3RhcnQnKTtcbiAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCxlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG4gICAgICBsZXQga2V5ID0gdGhpcy5rZXlzW2VsZW1lbnQuaW5kZXhdO1xuICAgICAgdGhpcy5wYWludGJydXNoID0gIWtleS5zdGF0ZTtcbiAgICAgIGtleS5kb3duKHRoaXMucGFpbnRicnVzaCk7XG4gICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZWxlbWVudC5pbmRleDtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgKGUpID0+IHtcbiAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCxlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG4gICAgICBsZXQga2V5ID0gdGhpcy5rZXlzW2VsZW1lbnQuaW5kZXhdO1xuICAgICAgaWYgKGVsZW1lbnQuaW5kZXghPT10aGlzLmN1cnJlbnRFbGVtZW50KSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgbGV0IHBhc3RLZXkgPSB0aGlzLmtleXNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICAgICAgcGFzdEtleS51cCgpO1xuICAgICAgICB9XG4gICAgICAgIGtleS5kb3duKHRoaXMucGFpbnRicnVzaCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBrZXkuYmVuZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGVsZW1lbnQuaW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgKGUpID0+IHtcbiAgICAgIC8vIG5vIHRvdWNoZXMgdG8gY2FsY3VsYXRlIGJlY2F1c2Ugbm9uZSByZW1haW5pbmdcbiAgICAgIGxldCBrZXkgPSB0aGlzLmtleXNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICBrZXkudXAoKTtcbiAgICAgIHRoaXMuaW50ZXJhY3RpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBmYWxzZTtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIC8qKlxuICBEZWZpbmUgdGhlIHBpdGNoIHJhbmdlIChsb3dlc3QgYW5kIGhpZ2hlc3Qgbm90ZSkgb2YgdGhlIHBpYW5vIGtleWJvYXJkLlxuICBAcGFyYW0gbG93IHtudW1iZXJ9IE1JREkgbm90ZSB2YWx1ZSBvZiB0aGUgbG93ZXN0IG5vdGUgb24gdGhlIGtleWJvYXJkXG4gIEBwYXJhbSBoaWdoIHtudW1iZXJ9IE1JREkgbm90ZSB2YWx1ZSBvZiB0aGUgaGlnaGVzdCBub3RlIG9uIHRoZSBrZXlib2FyZFxuICAqL1xuICBzZXRSYW5nZShsb3csaGlnaCkge1xuICAgIHRoaXMucmFuZ2UubG93ID0gbG93O1xuICAgIHRoaXMucmFuZ2UuaGlnaCA9IGhpZ2g7XG4gICAgdGhpcy5lbXB0eSgpO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgfVxuXG4gIC8qKlxuICBUdXJuIGEga2V5IG9uIG9yIG9mZiB1c2luZyBpdHMgTUlESSBub3RlIHZhbHVlO1xuICBAcGFyYW0gbm90ZSB7bnVtYmVyfSBNSURJIG5vdGUgdmFsdWUgb2YgdGhlIGtleSB0byBjaGFuZ2VcbiAgQHBhcmFtIG9uIHtib29sZWFufSBXaGV0aGVyIHRoZSBub3RlIHNob3VsZCB0dXJuIG9uIG9yIG9mZlxuICAqL1xuICB0b2dnbGVLZXkobm90ZSwgb24pIHtcbiAgICB0aGlzLmtleXNbbm90ZS10aGlzLnJhbmdlLmxvd10uZmxpcChvbik7XG4gIH1cblxuICAvKipcbiAgVHVybiBhIGtleSBvbiBvciBvZmYgdXNpbmcgaXRzIGtleSBpbmRleCBvbiB0aGUgcGlhbm8gaW50ZXJmYWNlLlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gSW5kZXggb2YgdGhlIGtleSB0byBjaGFuZ2VcbiAgQHBhcmFtIG9uIHtib29sZWFufSBXaGV0aGVyIHRoZSBub3RlIHNob3VsZCB0dXJuIG9uIG9yIG9mZlxuICAqL1xuICB0b2dnbGVJbmRleChpbmRleCwgb24pIHtcbiAgICB0aGlzLmtleXNbaW5kZXhdLmZsaXAob24pO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL3BpYW5vLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBkb20gPSByZXF1aXJlKCcuLi91dGlsL2RvbScpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgQnV0dG9uVGVtcGxhdGUgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL2J1dHRvbnRlbXBsYXRlJyk7XG5sZXQgTWF0cml4TW9kZWwgPSByZXF1aXJlKCcuLi9tb2RlbHMvbWF0cml4Jyk7XG5sZXQgQ291bnRlck1vZGVsID0gcmVxdWlyZSgnLi4vbW9kZWxzL2NvdW50ZXInKTtcbmxldCB0b3VjaCA9IHJlcXVpcmUoJy4uL3V0aWwvdG91Y2gnKTtcblxuXG5cbmNsYXNzIE1hdHJpeENlbGwgZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnLF07XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFs4MCw4MF0sXG4gICAgICAndGFyZ2V0JzogZmFsc2UsXG4gICAgICAnbW9kZSc6ICd0b2dnbGUnLFxuICAgICAgJ3ZhbHVlJzogMFxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLmluZGV4ID0gdGhpcy5zZXR0aW5ncy5pbmRleDtcbiAgICB0aGlzLnJvdyA9IHRoaXMuc2V0dGluZ3Mucm93O1xuICAgIHRoaXMuY29sdW1uID0gdGhpcy5zZXR0aW5ncy5jb2x1bW47XG5cbiAgICB0aGlzLm1hdHJpeCA9IHRoaXMuc2V0dGluZ3MubWF0cml4O1xuXG4gICAgdGhpcy5pbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgIHRoaXMucGFpbnRicnVzaCA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnRvcCA9ICcwcHgnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5sZWZ0ID0gJzBweCc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLnBhZCA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wYWQpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXG4gICAgLyogZXZlbnRzICovXG5cbiAgICBpZiAoIXRvdWNoLmV4aXN0cykge1xuXG4gICAgICB0aGlzLmNsaWNrID0gKCkgPT4ge1xuICAgICAgICB0aGlzLm1hdHJpeC5pbnRlcmFjdGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMubWF0cml4LnBhaW50YnJ1c2ggPSAhdGhpcy5zdGF0ZTtcbiAgICAgICAgdGhpcy5kb3duKHRoaXMubWF0cml4LnBhaW50YnJ1c2gpO1xuICAgICAgfTtcbiAgICAgIHRoaXMucGFkLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3ZlcicsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubWF0cml4LmludGVyYWN0aW5nKSB7XG4gICAgICAgICAgdGhpcy5kb3duKHRoaXMubWF0cml4LnBhaW50YnJ1c2gpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuXG4gICAgICB0aGlzLm1vdmUgPSAoKSA9PiB7XG4gICAgICB9O1xuICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGUpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubWF0cml4LmludGVyYWN0aW5nKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLm9mZnNldCkge1xuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBkb20uZmluZFBvc2l0aW9uKHRoaXMuZWxlbWVudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSx0aGlzLm9mZnNldCk7XG4gICAgICAgICAgdGhpcy5iZW5kKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG5cbiAgICAgIHRoaXMucmVsZWFzZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5tYXRyaXguaW50ZXJhY3RpbmcgPSBmYWxzZTtcbiAgICAgIH07XG4gICAgICB0aGlzLnBhZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tYXRyaXguaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdXQnLCAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLm1hdHJpeC5pbnRlcmFjdGluZykge1xuICAgICAgICAgIHRoaXMudXAoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd4JywxKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3knLDEpO1xuICAgIGlmICh0aGlzLndpZHRoID4gMikge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMud2lkdGggLSAyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMud2lkdGgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5oZWlnaHQgPiAyKSB7XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIHRoaXMuaGVpZ2h0IC0gMik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQpO1xuICAgIH1cbiAgICAvL3RoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQgLSAyKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLm1hdHJpeC5jb2xvcnMuZmlsbCk7XG5cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMubWF0cml4LmNvbG9ycy5maWxsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5tYXRyaXguY29sb3JzLmFjY2VudCk7XG4gICAgfVxuICB9XG5cbn1cblxuLyoqXG4qIFNlcXVlbmNlclxuKlxuKiBAZGVzY3JpcHRpb24gR3JpZCBvZiBidXR0b25zIHdpdGggYnVpbHQtaW4gc3RlcCBzZXF1ZW5jZXIuXG4qXG4qIEBkZW1vIDxkaXYgbmV4dXMtdWk9XCJzZXF1ZW5jZXJcIiBzdHlsZT1cIndpZHRoOjQwMHB4O2hlaWdodDoyMDBweDtcIj48L2Rpdj5cbipcbiogQGV4YW1wbGVcbiogdmFyIHNlcXVlbmNlciA9IG5ldyBOZXh1cy5TZXF1ZW5jZXIoJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc2VxdWVuY2VyID0gbmV3IE5leHVzLlNlcXVlbmNlcignI3RhcmdldCcse1xuKiAgJ3NpemUnOiBbNDAwLDIwMF0sXG4qICAnbW9kZSc6ICd0b2dnbGUnLFxuKiAgJ3Jvd3MnOiA1LFxuKiAgJ2NvbHVtbnMnOiAxMFxuKn0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyBtYXRyaXggY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyA8aT5yb3c8L2k+IChudW1iZXIpLCA8aT5jb2x1bW48L2k+IChudW1iZXIpLCBhbmQgPGk+c3RhdGU8L2k+IChib29sZWFuKSBwcm9wZXJ0aWVzLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiBzZXF1ZW5jZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIHN0ZXBcbiogRmlyZXMgYW55IHRpbWUgdGhlIHNlcXVlbmNlciBzdGVwcyB0byB0aGUgbmV4dCBjb2x1bW4sIGluIHNlcXVlY2UgbW9kZS4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiA8aT5hcnJheTwvaT4gY29udGFpbmluZyBhbGwgdmFsdWVzIGluIHRoZSBjb2x1bW4sIDxpPmJvdHRvbSByb3cgZmlyc3Q8L2k+LlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiBzZXF1ZW5jZXIub24oJ3N0ZXAnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNlcXVlbmNlciBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzQwMCwyMDBdLFxuICAgICAgJ21vZGUnOiAndG9nZ2xlJyxcbiAgICAgICdyb3dzJzogNSxcbiAgICAgICdjb2x1bW5zJzogMTBcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5hY3RpdmUgPSAtMTtcblxuICAgIC8qKlxuICAgICogQnV0dG9uIGludGVyYWN0aW9uIG1vZGU6IHNlZSBCdXR0b25cbiAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgKiBAZXhhbXBsZSBidXR0b24ubW9kZSA9ICd0b2dnbGUnO1xuICAgICovXG4gICAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXG4gICAgLyoqXG4gICAgKiBUaGUgaW50ZXJ2YWwgb2JqZWN0IHdoaWNoIGNvbnRyb2xzIHRpbWluZyBhbmQgc2VxdWVuY2Ugc2NoZWR1bGluZy5cbiAgICAqIEB0eXBlIHtpbnRlcnZhbH1cbiAgICAqL1xuICAgIHRoaXMuaW50ZXJ2YWwgPSBuZXcgTmV4dXMuSW50ZXJ2YWwoMjAwLGZ1bmN0aW9uKCkge30sZmFsc2UpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuICAgIC8qKlxuICAgICogQSBNYXRyaXggbW9kZWwgY29udGFpbmluZyBtZXRob2RzIGZvciBtYW5pcHVsYXRpbmcgdGhlIHNlcXVlbmNlcidzIGFycmF5IG9mIHZhbHVlcy4gVG8gbGVhcm4gaG93IHRvIG1hbmlwdWxhdGUgdGhlIG1hdHJpeCwgcmVhZCBhYm91dCB0aGUgbWF0cml4IG1vZGVsLlxuICAgICogQHR5cGUge21hdHJpeH1cbiAgICAqL1xuICAgIHRoaXMubWF0cml4ID0gbmV3IE1hdHJpeE1vZGVsKHRoaXMuc2V0dGluZ3Mucm93cyx0aGlzLnNldHRpbmdzLmNvbHVtbnMpO1xuICAgIHRoaXMubWF0cml4LnVpID0gdGhpcztcblxuICAgIC8qKlxuICAgICogQSBDb3VudGVyIG1vZGVsIHdoaWNoIHRoZSBzZXF1ZW5jZXIgc3RlcHMgdGhyb3VnaC4gRm9yIGV4YW1wbGUsIHlvdSBjb3VsZCB1c2UgdGhpcyBtb2RlbCB0byBzdGVwIHRocm91Z2ggdGhlIHNlcXVlbmNlciBpbiByZXZlcnNlLCByYW5kb21seSwgb3IgaW4gYSBkcnVuayB3YWxrLlxuICAgICogQHR5cGUge2NvdW50ZXJ9XG4gICAgKi9cbiAgICB0aGlzLnN0ZXBwZXIgPSBuZXcgQ291bnRlck1vZGVsKDAsdGhpcy5jb2x1bW5zKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gIH1cblxuICBidWlsZEZyYW1lKCkge1xuICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG4gICAgaWYgKHRvdWNoLmV4aXN0cykge1xuICAgICAgdGhpcy5hZGRUb3VjaExpc3RlbmVycygpO1xuICAgIH1cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5jZWxscyA9IFtdO1xuICAgIGZvciAobGV0IGk9MDtpPHRoaXMubWF0cml4Lmxlbmd0aDtpKyspIHtcblxuICAgICAgbGV0IGxvY2F0aW9uID0gdGhpcy5tYXRyaXgubG9jYXRlKGkpO1xuICAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJucyB7cm93LGNvbH1cblxuICAgICAgbGV0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgIGNvbnRhaW5lci5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG5cblxuICAgICAgbGV0IGNlbGwgPSBuZXcgTWF0cml4Q2VsbChjb250YWluZXIsIHtcbiAgICAgICAgICBjb21wb25lbnQ6IHRydWUsXG4gICAgICAgICAgaW5kZXg6IGksXG4gICAgICAgICAgcm93OiBsb2NhdGlvbi5yb3csXG4gICAgICAgICAgY29sdW1uOiBsb2NhdGlvbi5jb2x1bW4sXG4gICAgICAgICAgbW9kZTogdGhpcy5tb2RlLFxuICAgICAgICAgIG1hdHJpeDogdGhpc1xuICAgICAgICB9LCB0aGlzLmtleUNoYW5nZS5iaW5kKHRoaXMsaSkpO1xuXG4gICAgLy8gIGNlbGwubWF0cml4ID0gdGhpcztcbiAgICAgIGlmICh0b3VjaC5leGlzdHMpIHtcbiAgICAgICAgY2VsbC5wYWQuaW5kZXggPSBpO1xuICAgICAgICBjZWxsLnByZUNsaWNrID0gY2VsbC5wcmVNb3ZlID0gY2VsbC5wcmVSZWxlYXNlID0gKCkgPT4ge307XG4gICAgICAgIGNlbGwuY2xpY2sgPSBjZWxsLm1vdmUgPSBjZWxsLnJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgICAgY2VsbC5wcmVUb3VjaCA9IGNlbGwucHJlVG91Y2hNb3ZlID0gY2VsbC5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgICAgY2VsbC50b3VjaCA9IGNlbGwudG91Y2hNb3ZlID0gY2VsbC50b3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5jZWxscy5wdXNoKGNlbGwpO1xuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cbiAgICB9XG4gICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgbGV0IGNlbGxXaWR0aCA9IHRoaXMud2lkdGggLyB0aGlzLmNvbHVtbnM7XG4gICAgbGV0IGNlbGxIZWlnaHQgPSB0aGlzLmhlaWdodCAvIHRoaXMucm93cztcblxuICAgIGZvciAobGV0IGk9MDsgaTx0aGlzLmNlbGxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgY29udGFpbmVyID0gdGhpcy5jZWxsc1tpXS5wYXJlbnQ7XG4gICAgICBjb250YWluZXIuc3R5bGUubGVmdCA9IHRoaXMuY2VsbHNbaV0uY29sdW1uICogY2VsbFdpZHRoICsgJ3B4JztcbiAgICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSB0aGlzLmNlbGxzW2ldLnJvdyAqIGNlbGxIZWlnaHQgKyAncHgnO1xuICAgICAgdGhpcy5jZWxsc1tpXS5yZXNpemUoY2VsbFdpZHRoLGNlbGxIZWlnaHQpO1xuICAgIH1cblxuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICBmb3IgKHZhciBpPTA7IGk8dGhpcy5jZWxscy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5jZWxsc1tpXS5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGUoKSB7XG4gIC8vICBjb25zb2xlLmxvZyhcInVwZGF0aW5nLi4uXCIpXG4gICAgLy9vbiA9IG9uIHx8IGZhbHNlO1xuICAgIHRoaXMubWF0cml4Lml0ZXJhdGUoKHIsYyxpKSA9PiB7XG4gICAgICAvLyAgY29uc29sZS5sb2codGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSwgdGhpcy5jZWxsc1tpXS5zdGF0ZSk7XG4gICAgICBpZiAodGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSAhPT0gdGhpcy5jZWxsc1tpXS5zdGF0ZSkge1xuICAgICAgICBpZiAodGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSA+IDApIHtcbiAgICAgICAgICB0aGlzLmNlbGxzW2ldLnR1cm5PbigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuY2VsbHNbaV0udHVybk9mZigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuLy8gdXBkYXRlID0+IGNlbGwudHVybk9uID0+IGNlbGwuZW1pdCA9PiBrZXlDaGFuZ2UgKHNlcS5lbWl0KSA9PiBtYXRyaXguc2V0LmNlbGwgPT4gdXBkYXRlXG4vL1xuLy8gaW50ZXJhY3Rpb24gPT4ga2V5Q2hhbmdlID0+IG1hdHJpeC5zZXQuY2VsbCA9PiB1cGRhdGUgPT4gY2VsbC50dXJuT25cbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gZW1pdFxuLy9cbi8vIHNldC5jZWxsID0+IHVwZGF0ZSA9PiBuZWVkcyB0byBlbWl0LlxuXG4gIGtleUNoYW5nZShub3RlLG9uKSB7XG4gICAgLy8gZW1pdCBkYXRhIGZvciBhbnkga2V5IHR1cm5pbmcgb24vb2ZmXG4gICAgLy8gaSBpcyB0aGUgbm90ZSBpbmRleFxuICAgIC8vIHYgaXMgd2hldGhlciBpdCBpcyBvbiBvciBvZmZcbiAgICBsZXQgY2VsbCA9IHRoaXMubWF0cml4LmxvY2F0ZShub3RlKTtcbiAgLy8gIHRoaXMubWF0cml4LnNldC5jZWxsKGNlbGwuY29sdW1uLGNlbGwucm93LG9uKTtcbiAgICB0aGlzLm1hdHJpeC5wYXR0ZXJuW2NlbGwucm93XVtjZWxsLmNvbHVtbl0gPSBvbjtcbiAgICB2YXIgZGF0YSA9IHtcbiAgICAgIHJvdzogY2VsbC5yb3csXG4gICAgICBjb2x1bW46IGNlbGwuY29sdW1uLFxuICAgICAgc3RhdGU6IG9uXG4gICAgfTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsZGF0YSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKHRoaXMuc3RlcHBlci52YWx1ZSA+PSAwKSB7XG4gICAgICB0aGlzLm1hdHJpeC5pdGVyYXRlKChyLGMsaSkgPT4ge1xuICAgICAgICBpZiAoYz09PXRoaXMuc3RlcHBlci52YWx1ZSkge1xuICAgICAgICAgIHRoaXMuY2VsbHNbaV0ucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgICAgICAgdGhpcy5jZWxsc1tpXS5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCcxJyk7XG4gICAgICAgICAgdGhpcy5jZWxsc1tpXS5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2Utb3BhY2l0eScsJzEnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNlbGxzW2ldLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsJ25vbmUnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHNlcXVlbmNpbmdcbiAgICogQHBhcmFtICB7bnVtYmVyfSBtcyBCZWF0IHRlbXBvIGluIG1pbGxpc2Vjb25kc1xuICAgKi9cbiAgc3RhcnQobXMpIHtcbiAgICB0aGlzLmludGVydmFsLmV2ZW50ID0gdGhpcy5uZXh0LmJpbmQodGhpcyk7XG4gICAgaWYgKG1zKSB7XG4gICAgICB0aGlzLmludGVydmFsLm1zKG1zKTtcbiAgICB9XG4gICAgdGhpcy5pbnRlcnZhbC5zdGFydCgpO1xuICB9XG5cbiAgLyoqXG4gIFN0b3Agc2VxdWVuY2luZ1xuICAqL1xuICBzdG9wKCkge1xuICAgIHRoaXMuaW50ZXJ2YWwuc3RvcCgpO1xuICB9XG5cbiAgLyoqXG4gIE1hbnVhbGx5IGp1bXAgdG8gdGhlIG5leHQgY29sdW1uIGFuZCB0cmlnZ2VyIHRoZSAnY2hhbmdlJyBldmVudC4gVGhlIFwibmV4dFwiIGNvbHVtbiBpcyBkZXRlcm1pbmVkIGJ5IHlvdXIgbW9kZSBvZiBzZXF1ZW5jaW5nLlxuICAqL1xuICBuZXh0KCkge1xuICAgIHRoaXMuc3RlcHBlci5uZXh0KCk7XG4gICAgdGhpcy5lbWl0KCdzdGVwJyx0aGlzLm1hdHJpeC5jb2x1bW4odGhpcy5zdGVwcGVyLnZhbHVlKS5yZXZlcnNlKCkpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBhZGRUb3VjaExpc3RlbmVycygpIHtcblxuICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuXG4gICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGZhbHNlO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoZSkgPT4ge1xuICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRYLGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRZKTtcbiAgICAgIGxldCBjZWxsID0gdGhpcy5jZWxsc1tlbGVtZW50LmluZGV4XTtcbiAgICAgIHRoaXMucGFpbnRicnVzaCA9ICFjZWxsLnN0YXRlO1xuICAgICAgY2VsbC5kb3duKHRoaXMucGFpbnRicnVzaCk7XG4gICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZWxlbWVudC5pbmRleDtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgKGUpID0+IHtcbiAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCxlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG4gICAgICBsZXQgY2VsbCA9IHRoaXMuY2VsbHNbZWxlbWVudC5pbmRleF07XG4gICAgICBpZiAoZWxlbWVudC5pbmRleCE9PXRoaXMuY3VycmVudEVsZW1lbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEVsZW1lbnQgPj0gMCkge1xuICAgICAgICAgIGxldCBwYXN0Q2VsbCA9IHRoaXMuY2VsbHNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICAgICAgcGFzdENlbGwudXAoKTtcbiAgICAgICAgfVxuICAgICAgICBjZWxsLmRvd24odGhpcy5wYWludGJydXNoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNlbGwuYmVuZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGVsZW1lbnQuaW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgKGUpID0+IHtcbiAgICAgIC8vIG5vIHRvdWNoZXMgdG8gY2FsY3VsYXRlIGJlY2F1c2Ugbm9uZSByZW1haW5pbmdcbiAgICAgIGxldCBjZWxsID0gdGhpcy5jZWxsc1t0aGlzLmN1cnJlbnRFbGVtZW50XTtcbiAgICAgIGNlbGwudXAoKTtcbiAgICAgIHRoaXMuaW50ZXJhY3RpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBmYWxzZTtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIC8qKlxuICBOdW1iZXIgb2Ygcm93cyBpbiB0aGUgc2VxdWVuY2VyXG4gIEB0eXBlIHtudW1iZXJ9XG4gICovXG4gIGdldCByb3dzKCkge1xuICAgIHJldHVybiB0aGlzLm1hdHJpeC5yb3dzO1xuICB9XG5cbiAgc2V0IHJvd3Modikge1xuICAgIHRoaXMubWF0cml4LnJvd3MgPSB2O1xuICAgIHRoaXMuZW1wdHkoKTtcbiAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICBOdW1iZXIgb2YgY29sdW1ucyBpbiB0aGUgc2VxdWVuY2VyXG4gIEB0eXBlIHtudW1iZXJ9XG4gICovXG4gIGdldCBjb2x1bW5zKCkge1xuICAgIHJldHVybiB0aGlzLm1hdHJpeC5jb2x1bW5zO1xuICB9XG5cbiAgc2V0IGNvbHVtbnModikge1xuICAgIHRoaXMubWF0cml4LmNvbHVtbnMgPSB2O1xuICAgIHRoaXMuc3RlcHBlci5tYXggPSB2O1xuICAgIHRoaXMuZW1wdHkoKTtcbiAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9zZXF1ZW5jZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5pbXBvcnQgU2VxdWVuY2UgZnJvbSAnLi4vbW9kZWxzL3NlcXVlbmNlJztcblxuLy8gRm9yIHRoZSB0dXRvcmlhbCwgbG9va2luZyBhdFxuXG4vL1BhdHRlcm4gc2VjdGlvbjpcbi8vIC5jcmVhdGUoKSwgLnJvd3MsIC5jb2x1bW5zLFxuLy8gLnBhdHRlcm4sIC5sZW5ndGgsIC5mb3JtYXRBc1RleHQoKSwgLmxvZygpLFxuLy8gLmxvY2F0ZShpKSwgLmluZGV4T2YoYyxyKVxuLy8gcm93KCksIGNvbHVtbigpIChyZXR1cm5zIGNvbnRlbnRzIG9mIHJvdyBvciBjb2x1bSlcblxuLy9Db250cm9sIHNlY3Rpb246XG4vLyB0b2dnbGUgeDNcbi8vIHNldCB4NFxuLy8gcm90YXRlIHgzXG4vLyBwb3B1bGF0ZSB4M1xuLy8gZXJhc2UgeDNcblxuXG4vLyBzaG91bGQgc29tZSB2ZXJzaW9uIG9mIHRoaXMgaGF2ZSBhIGZsb2F0IHZhbHVlIGZvciBlYWNoIGNlbGw/XG4vLyBjb3VsZCBiZSBsaWtlIGEgbWlycm9yIC5wYXR0ZXJuIHRoYXQgaGFzIHZhbHVlcy4gYnkgZGVmYXVsdCwgZXZlcnl0aGluZyBpcyAxLCBidXQgY291bGQgYmUgc2V0Li4uXG4vLyBub3QgYSBnb29kIHdheSB0byBkbyB0aGF0IG9uIGludGVyZmFjZSwgYnV0IGFzIGEgbW9kZWwgaXQgd291bGQgYmUgbmljZS4uLlxuLy8gZm9yIC5mb3JtYXRBc1RleHQoKSwgY291bGQgbXVsdGlwbHkgYnkgMTAwIGFuZCBmbG9vciwgc28gZWFjaCBjZWxsIGlzIGFuIGludCBmcm9tIDAgdG8gOVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNYXRyaXgge1xuXG4gIGNvbnN0cnVjdG9yKHJvd3MsY29sdW1ucykge1xuICAgIC8vIHNob3VsZCBhbHNvIGhhdmUgYWJpbGl0eSB0byBjcmVhdGUgdXNpbmcgYW4gZXhpc3RpbmcgbWF0cml4ICgyZCBhcnJheSlcbiAgICB0aGlzLnBhdHRlcm4gPSBbXTtcbiAgICB0aGlzLmNyZWF0ZShyb3dzLGNvbHVtbnMpO1xuXG4gICAgdGhpcy50b2dnbGUgPSB7XG4gICAgICBjZWxsOiAoY29sdW1uLCByb3cpID0+IHtcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3Jvd11bY29sdW1uXSA9ICF0aGlzLnBhdHRlcm5bcm93XVtjb2x1bW5dOyAvLyBtYXRoLmludmVydCh0aGlzLnBhdHRlcm5bcm93XVtjb2x1bW5dKTtcbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgICByZXR1cm4gdGhpcy5wYXR0ZXJuW3Jvd11bY29sdW1uXTtcbiAgICAgIH0sXG4gICAgICBhbGw6ICgpID0+IHtcbiAgICAgICAgdGhpcy5pdGVyYXRlKChyLGMpID0+IHsgdGhpcy50b2dnbGUuY2VsbChjLHIpOyB9KTtcbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgfSxcbiAgICAgIHJvdzogKHJvdykgPT4ge1xuICAgICAgICBmb3IgKGxldCBpPTA7IGk8dGhpcy5jb2x1bW5zOyBpKyspIHtcbiAgICAgICAgICB0aGlzLnRvZ2dsZS5jZWxsKGkscm93KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9LFxuICAgICAgY29sdW1uOiAoY29sdW1uKSA9PiB7XG4gICAgICAgIGZvciAobGV0IGk9MDsgaTx0aGlzLnJvd3M7IGkrKykge1xuICAgICAgICAgIHRoaXMudG9nZ2xlLmNlbGwoY29sdW1uLGkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5zZXQgPSB7XG4gICAgICBjZWxsOiAoY29sdW1uLCByb3csIHZhbHVlKSA9PiB7XG4gICAgICAgIHRoaXMucGF0dGVybltyb3ddW2NvbHVtbl0gPSB2YWx1ZTtcbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgfSxcbiAgICAgIGFsbDogKHZhbHVlcykgPT4ge1xuICAgICAgICAvLyBzZXQgdGhlIHdob2xlIG1hdHJpeCB1c2luZyBhIDJkIGFycmF5IGFzIGlucHV0XG4gICAgICAgIC8vIHRoaXMgc2hvdWxkIGFsc28gcmVzaXplIHRoZSBhcnJheT9cbiAgICAgICAgdGhpcy5wYXR0ZXJuID0gdmFsdWVzO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9LFxuICAgICAgcm93OiAocm93LHZhbHVlcykgPT4ge1xuICAgICAgICAvLyBzZXQgYSByb3cgdXNpbmcgYW4gYXJyYXkgYXMgaW5wdXRcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3Jvd10gPSB2YWx1ZXM7XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH0sXG4gICAgICBjb2x1bW46IChjb2x1bW4sdmFsdWVzKSA9PiB7XG4gICAgICAgIC8vIHNldCBhIGNvbHVtbiB1c2luZyBhbiBhcnJheSBhcyBpbnB1dFxuICAgICAgICB0aGlzLnBhdHRlcm4uZm9yRWFjaCgocm93LGkpID0+IHtcbiAgICAgICAgICB0aGlzLnBhdHRlcm5baV1bY29sdW1uXSA9IHZhbHVlc1tpXTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5yb3RhdGUgPSB7XG4gICAgICAvL3Nob3VsZCBldmVudHVhbGx5IGRvIChhbW91bnRYLCBhbW91bnRZKSBoZXJlXG4gICAgICAvLyBjb3VsZCBqdXN0IHVzZSBhIGxvb3AgYW5kIHRoaXMucm90YXRlLnJvdyhpLGFtb3VudFgpO1xuICAgICAgYWxsOiAoYW1vdW50KSA9PiB7XG4gICAgICAgIGlmICghYW1vdW50ICYmIGFtb3VudCE9PTApIHtcbiAgICAgICAgICBhbW91bnQgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGFtb3VudCAlPSB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuICAgICAgICBpZiAoYW1vdW50IDwgMCkge1xuICAgICAgICAgIGFtb3VudCA9IHRoaXMucGF0dGVyblswXS5sZW5ndGggKyBhbW91bnQ7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaT0wOyBpPHRoaXMucm93czsgaSsrKSB7XG4gICAgICAgICAgbGV0IGN1dCA9IHRoaXMucGF0dGVybltpXS5zcGxpY2UoIHRoaXMucGF0dGVybltpXS5sZW5ndGggLSBhbW91bnQsIGFtb3VudCApO1xuICAgICAgICAgIHRoaXMucGF0dGVybltpXSA9IGN1dC5jb25jYXQoIHRoaXMucGF0dGVybltpXSApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH0sXG4gICAgICByb3c6IChyb3csYW1vdW50KSA9PiB7XG4gICAgICAgIGlmICghYW1vdW50ICYmIGFtb3VudCE9PTApIHtcbiAgICAgICAgICBhbW91bnQgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGFtb3VudCAlPSB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuICAgICAgICBpZiAoYW1vdW50IDwgMCkge1xuICAgICAgICAgIGFtb3VudCA9IHRoaXMucGF0dGVyblswXS5sZW5ndGggKyBhbW91bnQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGN1dCA9IHRoaXMucGF0dGVybltyb3ddLnNwbGljZSggdGhpcy5wYXR0ZXJuW3Jvd10ubGVuZ3RoIC0gYW1vdW50LCBhbW91bnQgKTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3Jvd10gPSBjdXQuY29uY2F0KCB0aGlzLnBhdHRlcm5bcm93XSApO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9LFxuICAgICAgY29sdW1uOiAoY29sdW1uLCBhbW91bnQpID0+IHtcbiAgICAgICAgaWYgKCFhbW91bnQgJiYgYW1vdW50IT09MCkge1xuICAgICAgICAgIGFtb3VudCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgYW1vdW50ICU9IHRoaXMucGF0dGVybi5sZW5ndGg7XG4gICAgICAgIGlmIChhbW91bnQgPCAwKSB7XG4gICAgICAgICAgYW1vdW50ID0gdGhpcy5wYXR0ZXJuLmxlbmd0aCArIGFtb3VudDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcHJveHkgPSBbXTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuLmZvckVhY2goKHJvdykgPT4ge1xuICAgICAgICAgIHByb3h5LnB1c2goIHJvd1tjb2x1bW5dICk7XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgY3V0ID0gcHJveHkuc3BsaWNlKCBwcm94eS5sZW5ndGggLSBhbW91bnQsIGFtb3VudCApO1xuICAgICAgICBwcm94eSA9IGN1dC5jb25jYXQoIHByb3h5ICk7XG4gICAgICAgIHRoaXMucGF0dGVybi5mb3JFYWNoKChyb3csaSkgPT4ge1xuICAgICAgICAgIHJvd1tjb2x1bW5dID0gcHJveHlbaV07XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIHRoZSBpZGVhIGJlaGluZCBwb3B1bGF0ZSBpcyB0byBiZSBhYmxlIHRvIHNldCBhIHdob2xlIHJvdyBvciBjb2x1bW4gdG8gMCBvciAxXG4gICAgLy8gSUYgdGhlIHZhbHVlIGlzIGEgZmxvYXQsIHN1Y2ggYXMgMC43LCB0aGVuIGl0IHdvdWxkIGJlY29tZSBhIHByb2JhYmlsaXR5XG4gICAgLy8gc28gcG9wdWxhdGUoMC43KSB3b3VsZCBnaXZlIGVhY2ggY2VsbCBhIDcwJSBjaGFuY2Ugb2YgYmVpbmcgMVxuICAgIHRoaXMucG9wdWxhdGUgPSB7XG4gICAgICBhbGw6IChvZGRzKSA9PiB7XG4gICAgICAgIGxldCBvZGRzU2VxdWVuY2UgPSBuZXcgU2VxdWVuY2Uob2Rkcyk7XG4gICAgICAgIHRoaXMuaXRlcmF0ZSgocixjKSA9PiB7XG4gICAgICAgICAgdGhpcy5wYXR0ZXJuW3JdW2NdID0gbWF0aC5jb2luKG9kZHNTZXF1ZW5jZS5uZXh0KCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gVGhpcyBjb3VsZCBiZSB1c2VkIHNvIHRoYXQgZWFjaCByb3cgaGFzIHNhbWUgb2RkcyBwYXR0ZXJuLCBldmVuIGlmIHJvdyBsZW5ndGggaXMgbm90IGRpdmlzaWJseSBieSBzZXF1ZW5jZSBsZW5ndGguXG4gICAgICAgIC8vLCgpID0+IHtcbiAgICAgICAgLy8gIG9kZHMucG9zID0gLTE7XG4gICAgICAgIC8vIH1cbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgfSxcbiAgICAgIHJvdzogKHJvdz0wLG9kZHM9MSkgPT4ge1xuICAgICAgICBsZXQgb2Rkc1NlcXVlbmNlID0gbmV3IFNlcXVlbmNlKG9kZHMpO1xuICAgICAgICB0aGlzLnBhdHRlcm5bcm93XS5mb3JFYWNoKChjZWxsLGkpID0+IHtcbiAgICAgICAgICB0aGlzLnBhdHRlcm5bcm93XVtpXSA9IG1hdGguY29pbihvZGRzU2VxdWVuY2UubmV4dCgpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH0sXG4gICAgICBjb2x1bW46IChjb2x1bW49MCxvZGRzPTEpID0+IHtcbiAgICAgICAgbGV0IG9kZHNTZXF1ZW5jZSA9IG5ldyBTZXF1ZW5jZShvZGRzKTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuLmZvckVhY2goKHJvdyxpKSA9PiB7XG4gICAgICAgICAgdGhpcy5wYXR0ZXJuW2ldW2NvbHVtbl0gPSBtYXRoLmNvaW4ob2Rkc1NlcXVlbmNlLm5leHQoKSk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIGVzc2VudGlhbGwgcG9wdWxhdGUoMCkgc28gaSdtIG5vdCBzdXJlIGlmIHRoaXMgaXMgbmVjZXNzYXJ5IGJ1dCBpcyBuaWNlXG4gICAgdGhpcy5lcmFzZSA9IHtcbiAgICAgIGFsbDogKCkgPT4ge1xuICAgICAgICB0aGlzLnNldC5hbGwoMCk7XG4gICAgICB9LFxuICAgICAgcm93OiAocm93KSA9PiB7XG4gICAgICAgIHRoaXMuc2V0LnJvdyhyb3csMCk7XG4gICAgICB9LFxuICAgICAgY29sdW1uOiAoY29sdW1uKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0LmNvbHVtbihjb2x1bW4sMCk7XG4gICAgICB9XG4gICAgfTtcblxuICAvLyBlbmQgY29uc3RydWN0b3JcbiAgfVxuXG5cbiAgY3JlYXRlKHJvd3MsY29sdW1ucykge1xuICAgIHRoaXMucGF0dGVybiA9IFtdO1xuICAgIGZvciAoIGxldCByb3c9MDsgcm93IDwgcm93czsgcm93KysgKSB7XG4gICAgICBsZXQgYXJyID0gbmV3IEFycmF5KGNvbHVtbnMpO1xuICAgICAgdGhpcy5wYXR0ZXJuLnB1c2goYXJyKTtcbiAgICB9XG4gICAgdGhpcy5pdGVyYXRlKChyLGMpID0+IHsgdGhpcy5wYXR0ZXJuW3JdW2NdID0gZmFsc2U7IH0pO1xuICB9XG5cbiAgaXRlcmF0ZShmLCBmMikge1xuICAgIGxldCBpID0gMDtcbiAgICBmb3IgKCBsZXQgcm93PTA7IHJvdyA8IHRoaXMucm93czsgcm93KysgKSB7XG4gICAgICBpZiAoZjIpIHsgZjIocm93KTsgfVxuICAgICAgZm9yICggbGV0IGNvbHVtbj0wOyBjb2x1bW4gPCB0aGlzLmNvbHVtbnM7IGNvbHVtbisrICkge1xuICAgICAgICBmKHJvdyxjb2x1bW4saSk7XG4gICAgICAgIGkrKztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3JtYXRBc1RleHQoKSB7XG4gICAgbGV0IHBhdHRlcm5TdHJpbmcgPSAnJztcbiAgICB0aGlzLml0ZXJhdGUoXG4gICAgICAocixjKSA9PiB7IHBhdHRlcm5TdHJpbmcgKz0gKHRoaXMucGF0dGVybltyXVtjXSA/IDEgOiAwKSArICcgJzsgfSxcbiAgICAgICgpID0+IHsgcGF0dGVyblN0cmluZyArPSAnXFxuJzsgfVxuICAgICk7XG4gICAgcmV0dXJuIHBhdHRlcm5TdHJpbmc7XG4gIH1cblxuICBsb2coKSB7XG4gICAgY29uc29sZS5sb2codGhpcy5mb3JtYXRBc1RleHQoKSk7XG4gIH1cblxuICB1cGRhdGUocGF0dGVybikge1xuICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm4gfHwgdGhpcy5wYXR0ZXJuO1xuICB9XG5cbiAgZ2V0IGxlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5yb3dzKnRoaXMuY29sdW1ucztcbiAgfVxuXG4gIGxvY2F0ZShpbmRleCkge1xuICAgIC8vIHJldHVybnMgcm93IGFuZCBjb2x1bW4gb2YgY2VsbCBieSBpbmRleFxuICAgIHJldHVybiB7XG4gICAgICByb3c6IH5+KCBpbmRleCAvIHRoaXMuY29sdW1ucyApLFxuICAgICAgY29sdW1uOiBpbmRleCAlIHRoaXMuY29sdW1uc1xuICAgIH07XG4gIH1cblxuICBpbmRleE9mKHJvdyxjb2x1bW4pIHtcbiAgICByZXR1cm4gY29sdW1uICsgcm93ICogdGhpcy5jb2x1bW5zO1xuICAgIC8vIHJldHVybnMgaW5kZXggb2YgY2VsbCBieSByb3cgYW5kIGNvbHVtblxuICB9XG5cbiAgcm93KHJvdykge1xuICAgIGxldCBkYXRhID0gW107XG4gICAgZm9yIChsZXQgaT0wOyBpPHRoaXMuY29sdW1uczsgaSsrKSB7XG4gICAgICBkYXRhLnB1c2godGhpcy5wYXR0ZXJuW3Jvd10gPyAxIDogMCk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgY29sdW1uKGNvbHVtbikge1xuICAgIGxldCBkYXRhID0gW107XG4gICAgZm9yIChsZXQgaT0wOyBpPHRoaXMucm93czsgaSsrKSB7XG4gICAgICBkYXRhLnB1c2godGhpcy5wYXR0ZXJuW2ldW2NvbHVtbl0gPyAxIDogMCk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgZ2V0IHJvd3MoKSB7XG4gICAgcmV0dXJuIHRoaXMucGF0dGVybi5sZW5ndGg7XG4gIH1cbiAgc2V0IHJvd3Modikge1xuICAgIGxldCBwcmV2aW91cyA9IHRoaXMucGF0dGVybi5zbGljZSgwKTtcbiAgICB0aGlzLmNyZWF0ZSh2LHRoaXMuY29sdW1ucyk7XG4gICAgdGhpcy5pdGVyYXRlKChyLGMpID0+IHtcbiAgICAgIGlmIChwcmV2aW91c1tyXSAmJiBwcmV2aW91c1tyXVtjXSkge1xuICAgICAgICB0aGlzLnBhdHRlcm5bcl1bY10gPSBwcmV2aW91c1tyXVtjXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGdldCBjb2x1bW5zKCkge1xuICAgIHJldHVybiB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuICB9XG4gIHNldCBjb2x1bW5zKHYpIHtcbiAgICBsZXQgcHJldmlvdXMgPSB0aGlzLnBhdHRlcm4uc2xpY2UoMCk7XG4gICAgdGhpcy5jcmVhdGUodGhpcy5yb3dzLHYpO1xuICAgIHRoaXMuaXRlcmF0ZSgocixjKSA9PiB7XG4gICAgICBpZiAocHJldmlvdXNbcl0gJiYgcHJldmlvdXNbcl1bY10pIHtcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3JdW2NdID0gcHJldmlvdXNbcl1bY107XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL21vZGVscy9tYXRyaXguanMiLCIndXNlIHN0cmljdCc7XHJcblxyXG5pbXBvcnQgbWF0aCBmcm9tICcuLi91dGlsL21hdGgnO1xyXG5pbXBvcnQgRHJ1bmsgZnJvbSAnLi9kcnVuayc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTZXF1ZW5jZSB7XHJcblxyXG4gICAgY29uc3RydWN0b3Ioc2VxdWVuY2UgPSBbMCwxMCwyMCwzMF0sIG1vZGU9J3VwJywgcG9zaXRpb249ZmFsc2UpIHtcclxuICAgICAgICB0aGlzLnZhbHVlcyA9IHNlcXVlbmNlO1xyXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLnZhbHVlcykpIHtcclxuICAgICAgICAgIHRoaXMudmFsdWVzID0gW3RoaXMudmFsdWVzXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fbW9kZSA9IG1vZGU7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xyXG5cclxuICAgICAgICB0aGlzLmRydW5rV2FsayA9IG5ldyBEcnVuaygwLCB0aGlzLnZhbHVlcy5sZW5ndGggLSAxKTtcclxuXHJcbiAgICAgICAgdGhpcy5zdGFydFZhbHVlcyA9IHtcclxuICAgICAgICAgICd1cCc6IDAsXHJcbiAgICAgICAgICAnZG93bic6IHRoaXMudmFsdWVzLmxlbmd0aCAtIDEsXHJcbiAgICAgICAgICAnZHJ1bmsnOiB+fih0aGlzLnZhbHVlcy5sZW5ndGgvMiksXHJcbiAgICAgICAgICAncmFuZG9tJzogbWF0aC5yaSh0aGlzLnZhbHVlcy5sZW5ndGgpXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMucG9zaXRpb24hPT1mYWxzZSkge1xyXG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpcy5maXJzdDtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgIH1cclxuXHJcbiAgICBnZXQgbW9kZSgpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX21vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IG1vZGUobW9kZSkge1xyXG4gICAgICAgIGlmICghKG1vZGUgPT09ICd1cCcgfHwgbW9kZSA9PT0gJ2Rvd24nIHx8IG1vZGUgPT09ICdyYW5kb20nIHx8IG1vZGUgPT09ICdkcnVuaycpKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBvbmx5IG1vZGVzIGN1cnJlbnRseSBhbGxvd2VkIGFyZTogdXAsIGRvd24sIHJhbmRvbSwgZHJ1bmsnKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9tb2RlID0gbW9kZTtcclxuICAgICAgICBpZiAodGhpcy5wb3NpdGlvbikge1xyXG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHZhbHVlKCkge1xyXG4gICAgICByZXR1cm4gdGhpcy52YWx1ZXNbdGhpcy5wb3NpdGlvbl07XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IHZhbHVlKHYpIHtcclxuICAgICAgdGhpcy5wb3NpdGlvbiA9IHRoaXMudmFsdWVzLmluZGV4T2Yodik7XHJcbiAgICB9XHJcblxyXG4gICAgZmlyc3QoKSB7XHJcbiAgICAgIGlmICh0aGlzLnBvc2l0aW9uIT09ZmFsc2UpIHtcclxuICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xyXG4gICAgICAgIHJldHVybiB0aGlzLm5leHQoKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLnBvc2l0aW9uID0gdGhpcy5zdGFydFZhbHVlc1t0aGlzLl9tb2RlXTtcclxuICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcclxuICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgdXAoKSB7XHJcbiAgICAgIHRoaXMucG9zaXRpb24rKztcclxuICAgICAgdGhpcy5wb3NpdGlvbiAlPSB0aGlzLnZhbHVlcy5sZW5ndGg7XHJcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGRvd24oKSB7XHJcbiAgICAgIHRoaXMucG9zaXRpb24tLTtcclxuICAgICAgaWYgKHRoaXMucG9zaXRpb24gPCAwKSB7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbiA9ICh0aGlzLnBvc2l0aW9uICsgdGhpcy52YWx1ZXMubGVuZ3RoKSAlIHRoaXMudmFsdWVzLmxlbmd0aDtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdGhpcy52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICByYW5kb20oKSB7XHJcbiAgICAgIHRoaXMucG9zaXRpb24gPSBtYXRoLnJpKDAsIHRoaXMudmFsdWVzLmxlbmd0aCk7XHJcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGRydW5rKCkge1xyXG4gICAgICB0aGlzLmRydW5rV2Fsay5tYXggPSB0aGlzLnZhbHVlcy5sZW5ndGg7XHJcbiAgICAgIHRoaXMuZHJ1bmtXYWxrLnZhbHVlID0gdGhpcy5wb3NpdGlvbjtcclxuICAgICAgdGhpcy5wb3NpdGlvbiA9IHRoaXMuZHJ1bmtXYWxrLm5leHQoKTtcclxuICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyogZnV0dXJlIG1ldGhvZHNcclxuICAgIC5ncm91cChzdGFydCxzdG9wKSAtLSBvdXRwdXRzIGEgZ3JvdXAgb2YgbiBpdGVtcyBmcm9tIHRoZSBsaXN0LCB3aXRoIHdyYXBwaW5nXHJcbiAgICAubG9vcChzdGFydCxzdG9wKSAtLSBjb25maW5lcyBzZXF1ZW5jaW5nIHRvIGEgc3Vic2V0IG9mIHRoZSB2YWx1ZXNcclxuICAgICAgICAoY291bGQgZXZlbiBoYXZlIGEgZGlzdGluY3Rpb24gYmV0d2VlbiAub3JpZ2luYWxWYWx1ZXMgYW5kIHRoZSBhcnJheSBvZiB2YWx1ZXMgYmVpbmcgdXNlZClcclxuICAgICovXHJcbn1cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL21vZGVscy9zZXF1ZW5jZS5qcyIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IG1hdGggZnJvbSAnLi4vdXRpbC9tYXRoJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRHJ1bmsge1xuXG4gICAgY29uc3RydWN0b3IobWluPTAsIG1heD05LCB2YWx1ZT0wLCBpbmNyZW1lbnQ9MSwgbG9vcD1mYWxzZSkge1xuICAgICAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5pbmNyZW1lbnQgPSBpbmNyZW1lbnQ7XG4gICAgICAgIHRoaXMubG9vcCA9IGxvb3A7XG4gICAgfVxuXG4gICAgbmV4dCgpIHtcbiAgICAgICAgdGhpcy52YWx1ZSArPSBtYXRoLnBpY2soLTEgKiB0aGlzLmluY3JlbWVudCwgdGhpcy5pbmNyZW1lbnQpO1xuICAgICAgICBpZiAodGhpcy52YWx1ZSA+IHRoaXMubWF4KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5sb29wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5tYXggLSB0aGlzLmluY3JlbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnZhbHVlIDwgdGhpcy5taW4pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5tYXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLm1pbiArIHRoaXMuaW5jcmVtZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9tb2RlbHMvZHJ1bmsuanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5pbXBvcnQgRHJ1bmsgZnJvbSAnLi9kcnVuayc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENvdW50ZXIge1xuXG4gICAgY29uc3RydWN0b3IobWluPTAsIG1heD0xMCwgbW9kZT0ndXAnLCB2YWx1ZT1mYWxzZSkge1xuICAgICAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICAgICAgdGhpcy5kcnVua1dhbGsgPSBuZXcgRHJ1bmsodGhpcy5taW4sIHRoaXMubWF4KTtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUhPT1mYWxzZSkge1xuICAgICAgICAgIHRoaXMubmV4dCA9IHRoaXNbdGhpcy5fbW9kZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpcy5maXJzdDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldCBtb2RlKG1vZGUpIHtcbiAgICAgICAgaWYgKCEobW9kZSA9PT0gJ3VwJyB8fCBtb2RlID09PSAnZG93bicgfHwgbW9kZSA9PT0gJ3JhbmRvbScgfHwgbW9kZSA9PT0gJ2RydW5rJykpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBvbmx5IG1vZGVzIGN1cnJlbnRseSBhbGxvd2VkIGFyZTogdXAsIGRvd24sIHJhbmRvbSwgZHJ1bmsnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9tb2RlID0gbW9kZTtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUpIHtcbiAgICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IG1vZGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb2RlO1xuICAgIH1cblxuICAgIGZpcnN0KCkge1xuICAgICAgaWYgKHRoaXMudmFsdWUhPT1mYWxzZSkge1xuICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xuICAgICAgICByZXR1cm4gdGhpcy5uZXh0KCk7XG4gICAgICB9XG4gICAgICB0aGlzLnN0YXJ0VmFsdWVzID0ge1xuICAgICAgICAndXAnOiB0aGlzLm1pbixcbiAgICAgICAgJ2Rvd24nOiB0aGlzLm1heCxcbiAgICAgICAgJ2RydW5rJzogfn5tYXRoLmF2ZXJhZ2UodGhpcy5taW4sdGhpcy5tYXgpLFxuICAgICAgICAncmFuZG9tJzogbWF0aC5yaSh0aGlzLm1pbix0aGlzLm1heClcbiAgICAgIH07XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5zdGFydFZhbHVlc1t0aGlzLl9tb2RlXTtcbiAgICAgIHRoaXMubmV4dCA9IHRoaXNbdGhpcy5fbW9kZV07XG4gICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG5cbiAgICB1cCgpIHtcbiAgICAgICAgdGhpcy52YWx1ZSsrO1xuICAgICAgICBpZiAodGhpcy52YWx1ZSA+PSB0aGlzLm1heCkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIGRvd24oKSB7XG4gICAgICAgIHRoaXMudmFsdWUtLTtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUgPCB0aGlzLm1pbikge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWF4O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIHJhbmRvbSgpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IG1hdGgucmkodGhpcy5taW4sIHRoaXMubWF4KTtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgZHJ1bmsoKSB7XG4gICAgICAgIHRoaXMuZHJ1bmtXYWxrLm1pbiA9IHRoaXMubWluO1xuICAgICAgICB0aGlzLmRydW5rV2Fsay5tYXggPSB0aGlzLm1heDtcbiAgICAgICAgdGhpcy5kcnVua1dhbGsudmFsdWUgPSB0aGlzLnZhbHVlO1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5kcnVua1dhbGsubmV4dCgpO1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbW9kZWxzL2NvdW50ZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IG1hdGggPSByZXF1aXJlKCcuLi91dGlsL21hdGgnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbi8qKlxuKiBQYW4yRFxuKlxuKiBAZGVzY3JpcHRpb24gSW50ZXJmYWNlIGZvciBtb3ZpbmcgYSBzb3VuZCBhcm91bmQgYW4gYXJyYXkgb2Ygc3BlYWtlcnMuIFNwZWFrZXIgbG9jYXRpb25zIGNhbiBiZSBjdXN0b21pemVkLiBUaGUgaW50ZXJmYWNlIGNhbGN1bGF0ZXMgdGhlIGNsb3NlbmVzcyBvZiB0aGUgc291bmQgc291cmNlIHRvIGVhY2ggc3BlYWtlciBhbmQgcmV0dXJucyB0aGF0IGRpc3RhbmNlIGFzIGEgbnVtZXJpYyB2YWx1ZS5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJwYW4yRFwiPjwvc3Bhbj5cbipcbiogQGV4YW1wbGVcbiogdmFyIHBhbjJkID0gbmV3IE5leHVzLlBhbjJkKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHBhbjJkID0gbmV3IE5leHVzLlBhbjJEKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMjAwLDIwMF0sXG4qICAgJ3JhbmdlJzogMC41LCAgLy8gZGV0ZWN0aW9uIHJhZGl1cyBvZiBlYWNoIHNwZWFrZXJcbiogICAnbW9kZSc6ICdhYnNvbHV0ZScsICAgLy8gJ2Fic29sdXRlJyBvciAncmVsYXRpdmUnIHNvdW5kIG1vdmVtZW50XG4qICAgJ3NwZWFrZXJzJzogWyAgLy8gdGhlIHNwZWFrZXIgW3gseV0gcG9zaXRpb25zXG4qICAgICAgIFswLjUsMC4yXSxcbiogICAgICAgWzAuNzUsMC4yNV0sXG4qICAgICAgIFswLjgsMC41XSxcbiogICAgICAgWzAuNzUsMC43NV0sXG4qICAgICAgIFswLjUsMC44XSxcbiogICAgICAgWzAuMjUsMC43NV1cbiogICAgICAgWzAuMiwwLjVdLFxuKiAgICAgICBbMC4yNSwwLjI1XVxuKiAgIF1cbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIFwic291cmNlXCIgbm9kZSdzIHBvc2l0aW9uIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgaXMgYW4gYXJyYXkgb2YgdGhlIGFtcGxpdHVkZXMgKDAtMSksIHJlcHJlc2VudGluZyB0aGUgbGV2ZWwgb2YgZWFjaCBzcGVha2VyIChhcyBjYWxjdWxhdGVkIGJ5IGl0cyBkaXN0YW5jZSB0byB0aGUgYXVkaW8gc291cmNlKS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogcGFuMmQub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUGFuMkQgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3JhbmdlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFsyMDAsMjAwXSxcbiAgICAgICdyYW5nZSc6IDAuNSxcbiAgICAgICdtb2RlJzogJ2Fic29sdXRlJyxcbiAgICAgICdzcGVha2Vycyc6IFtcbiAgICAgICAgWzAuNSwwLjJdLFxuICAgICAgICBbMC43NSwwLjI1XSxcbiAgICAgICAgWzAuOCwwLjVdLFxuICAgICAgICBbMC43NSwwLjc1XSxcbiAgICAgICAgWzAuNSwwLjhdLFxuICAgICAgICBbMC4yNSwwLjc1XSxcbiAgICAgICAgWzAuMiwwLjVdLFxuICAgICAgICBbMC4yNSwwLjI1XVxuICAgICAgXVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLnZhbHVlID0ge1xuICAgICAgeDogbmV3IFN0ZXAoMCwxLDAsMC41KSxcbiAgICAgIHk6IG5ldyBTdGVwKDAsMSwwLDAuNSlcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgQWJzb2x1dGUgb3IgcmVsYXRpdmUgbW91c2UgaW50ZXJhY3Rpb24uIEluIFwiYWJzb2x1dGVcIiBtb2RlLCB0aGUgc291cmNlIG5vZGUgd2lsbCBqdW1wIHRvIHlvdXIgbW91c2UgcG9zaXRpb24gb24gbW91c2UgY2xpY2suIEluIFwicmVsYXRpdmVcIiBtb2RlLCBpdCBkb2VzIG5vdC5cbiAgICAqL1xuICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZTtcblxuICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICB4OiBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMubW9kZSwnaG9yaXpvbnRhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKSxcbiAgICAgIHk6IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5tb2RlLCd2ZXJ0aWNhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKVxuICAgIH07XG4gICAgdGhpcy5wb3NpdGlvbi54LnZhbHVlID0gdGhpcy52YWx1ZS54Lm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5wb3NpdGlvbi55LnZhbHVlID0gdGhpcy52YWx1ZS55Lm5vcm1hbGl6ZWQ7XG5cbiAgICAvKipcbiAgICBBbiBhcnJheSBvZiBzcGVha2VyIGxvY2F0aW9ucy4gVXBkYXRlIHRoaXMgd2l0aCAubW92ZVNwZWFrZXIoKSBvciAubW92ZUFsbFNwZWFrZXJzKClcbiAgICAqL1xuICAgIHRoaXMuc3BlYWtlcnMgPSB0aGlzLnNldHRpbmdzLnNwZWFrZXJzO1xuXG4gICAgLyoqXG4gICAgUmV3cml0ZTogVGhlIG1heGltdW0gZGlzdGFuY2UgZnJvbSBhIHNwZWFrZXIgdGhhdCB0aGUgc291cmNlIG5vZGUgY2FuIGJlIGZvciBpdCB0byBiZSBoZWFyZCBmcm9tIHRoYXQgc3BlYWtlci4gQSBsb3cgcmFuZ2UgKDAuMSkgd2lsbCByZXN1bHQgaW4gc3BlYWtlcnMgb25seSBwbGF5aW5nIHdoZW4gdGhlIHNvdW5kIGlzIHZlcnkgY2xvc2UgaXQuIERlZmF1bHQgaXMgMC41IChoYWxmIG9mIHRoZSBpbnRlcmZhY2UpLlxuICAgICovXG4gICAgdGhpcy5yYW5nZSA9IHRoaXMuc2V0dGluZ3MucmFuZ2U7XG5cbiAgICAvKipcbiAgICBUaGUgY3VycmVudCBsZXZlbHMgZm9yIGVhY2ggc3BlYWtlci4gVGhpcyBpcyBjYWxjdWxhdGVkIHdoZW4gYSBzb3VyY2Ugbm9kZSBvciBzcGVha2VyIG5vZGUgaXMgbW92ZWQgdGhyb3VnaCBpbnRlcmFjdGlvbiBvciBwcm9ncmFtYXRpY2FsbHkuXG4gICAgKi9cbiAgICB0aGlzLmxldmVscyA9IFtdO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgICB0aGlzLmNhbGN1bGF0ZUxldmVscygpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG5cblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmtub2IpO1xuXG5cbiAgICAvLyBhZGQgc3BlYWtlcnNcbiAgICB0aGlzLnNwZWFrZXJFbGVtZW50cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5zcGVha2Vycy5sZW5ndGg7aSsrKSB7XG4gICAgICBsZXQgc3BlYWtlckVsZW1lbnQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHNwZWFrZXJFbGVtZW50KTtcblxuICAgICAgdGhpcy5zcGVha2VyRWxlbWVudHMucHVzaChzcGVha2VyRWxlbWVudCk7XG4gICAgfVxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgICAgIHRoaXMuX21pbkRpbWVuc2lvbiA9IE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpO1xuXG4gICAgICAgIHRoaXMua25vYlJhZGl1cyA9IHtcbiAgICAgICAgICBvZmY6IH5+KHRoaXMuX21pbkRpbWVuc2lvbi8xMDApICogMyArIDUsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMua25vYlJhZGl1cy5vbiA9IHRoaXMua25vYlJhZGl1cy5vZmYgKiAyO1xuXG4gICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIpO1xuICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQvMik7XG4gICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYlJhZGl1cy5vZmYpO1xuXG4gICAgICAgIGZvciAobGV0IGk9MDtpPHRoaXMuc3BlYWtlcnMubGVuZ3RoO2krKykge1xuICAgICAgICAgIGxldCBzcGVha2VyRWxlbWVudCA9IHRoaXMuc3BlYWtlckVsZW1lbnRzW2ldO1xuICAgICAgICAgIGxldCBzcGVha2VyID0gdGhpcy5zcGVha2Vyc1tpXTtcbiAgICAgICAgICBzcGVha2VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2N4JyxzcGVha2VyWzBdKnRoaXMud2lkdGgpO1xuICAgICAgICAgIHNwZWFrZXJFbGVtZW50LnNldEF0dHJpYnV0ZSgnY3knLHNwZWFrZXJbMV0qdGhpcy5oZWlnaHQpO1xuICAgICAgICAgIHNwZWFrZXJFbGVtZW50LnNldEF0dHJpYnV0ZSgncicsdGhpcy5fbWluRGltZW5zaW9uLzIwICsgNSk7XG4gICAgICAgICAgc3BlYWtlckVsZW1lbnQuc2V0QXR0cmlidXRlKCdmaWxsLW9wYWNpdHknLCAnMCcpO1xuICAgICAgICB9XG5cbiAgICAgIHRoaXMucG9zaXRpb24ueC5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICAgIHRoaXMucG9zaXRpb24ueS5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcblxuICAgICAgICAvLyBuZXh0LCBuZWVkIHRvXG4gICAgICAgIC8vIHJlc2l6ZSBwb3NpdGlvbnNcbiAgICAgICAgLy8gY2FsY3VsYXRlIHNwZWFrZXIgZGlzdGFuY2VzXG4gICAgICB0aGlzLmNhbGN1bGF0ZUxldmVscygpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgY29sb3JJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5zcGVha2Vycy5sZW5ndGg7aSsrKSB7XG4gICAgICBsZXQgc3BlYWtlckVsZW1lbnQgPSB0aGlzLnNwZWFrZXJFbGVtZW50c1tpXTtcbiAgICAgIHNwZWFrZXJFbGVtZW50LnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgICBzcGVha2VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgfVxuXG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgdGhpcy5rbm9iQ29vcmRpbmF0ZXMgPSB7XG4gICAgICB4OiB0aGlzLnZhbHVlLngubm9ybWFsaXplZCAqIHRoaXMud2lkdGgsXG4gICAgICB5OiB0aGlzLmhlaWdodCAtIHRoaXMudmFsdWUueS5ub3JtYWxpemVkICogdGhpcy5oZWlnaHRcbiAgICB9O1xuXG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkNvb3JkaW5hdGVzLngpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmtub2JDb29yZGluYXRlcy55KTtcbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgdGhpcy5wb3NpdGlvbi54LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5wb3NpdGlvbi55LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMucG9zaXRpb24ueC51cGRhdGUodGhpcy5tb3VzZSk7XG4gICAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKHRoaXMubW91c2UpO1xuICAgICAgLy8gcG9zaXRpb24ueCBhbmQgcG9zaXRpb24ueSBhcmUgbm9ybWFsaXplZFxuICAgICAgLy8gc28gYXJlIHRoZSBsZXZlbHNcbiAgICAgIC8vIGxpa2VseSBkb24ndCBuZWVkIHRoaXMudmFsdWUgYXQgYWxsIC0tIG9ubHkgdXNlZCBmb3IgZHJhd2luZ1xuICAgICAgLy8gbm90IGdvaW5nIHRvIGJlIGEgJ3N0ZXAnIG9yICdtaW4nIGFuZCAnbWF4JyBpbiB0aGlzIG9uZS5cbiAgICAgIHRoaXMuY2FsY3VsYXRlTGV2ZWxzKCk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5sZXZlbHMpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICByZWxlYXNlKCkge1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBnZXQgbm9ybWFsaXplZCgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogdGhpcy52YWx1ZS54Lm5vcm1hbGl6ZWQsXG4gICAgICB5OiB0aGlzLnZhbHVlLnkubm9ybWFsaXplZFxuICAgIH07XG4gIH1cblxuICBjYWxjdWxhdGVMZXZlbHMoKSB7XG4gICAgdGhpcy52YWx1ZS54LnVwZGF0ZU5vcm1hbCggdGhpcy5wb3NpdGlvbi54LnZhbHVlICk7XG4gICAgdGhpcy52YWx1ZS55LnVwZGF0ZU5vcm1hbCggdGhpcy5wb3NpdGlvbi55LnZhbHVlICk7XG4gICAgdGhpcy5sZXZlbHMgPSBbXTtcbiAgICB0aGlzLnNwZWFrZXJzLmZvckVhY2goKHMsaSkgPT4ge1xuICAgICAgbGV0IGRpc3RhbmNlID0gbWF0aC5kaXN0YW5jZShzWzBdKnRoaXMud2lkdGgsc1sxXSp0aGlzLmhlaWdodCx0aGlzLnBvc2l0aW9uLngudmFsdWUqdGhpcy53aWR0aCwoMS10aGlzLnBvc2l0aW9uLnkudmFsdWUpKnRoaXMuaGVpZ2h0KTtcbiAgICAgIGxldCBsZXZlbCA9IG1hdGguY2xpcCgxLWRpc3RhbmNlLyh0aGlzLnJhbmdlKnRoaXMud2lkdGgpLDAsMSk7XG4gICAgICB0aGlzLmxldmVscy5wdXNoKGxldmVsKTtcbiAgICAgIHRoaXMuc3BlYWtlckVsZW1lbnRzW2ldLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywgbGV2ZWwpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gIE1vdmUgdGhlIGF1ZGlvIHNvdXJjZSBub2RlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG4gIEBwYXJhbSB4IHtudW1iZXJ9IE5ldyB4IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuICBAcGFyYW0geSB7bnVtYmVyfSBOZXcgeSBsb2NhdGlvbiwgbm9ybWFsaXplZCAwLTFcbiAgKi9cbiAgbW92ZVNvdXJjZSh4LHkpIHtcbiAgICBsZXQgbG9jYXRpb24gPSB7XG4gICAgICB4OiB4KnRoaXMud2lkdGgsXG4gICAgICB5OiB5KnRoaXMuaGVpZ2h0XG4gICAgfTtcbiAgICB0aGlzLnBvc2l0aW9uLngudXBkYXRlKGxvY2F0aW9uKTtcbiAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKGxvY2F0aW9uKTtcbiAgICB0aGlzLmNhbGN1bGF0ZUxldmVscygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLmxldmVscyk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBNb3ZlIGEgc3BlYWtlciBub2RlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG4gIEBwYXJhbSBpbmRleCB7bnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlYWtlciB0byBtb3ZlXG4gIEBwYXJhbSB4IHtudW1iZXJ9IE5ldyB4IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuICBAcGFyYW0geSB7bnVtYmVyfSBOZXcgeSBsb2NhdGlvbiwgbm9ybWFsaXplZCAwLTFcbiAgKi9cbiAgbW92ZVNwZWFrZXIoaW5kZXgseCx5KSB7XG5cbiAgICB0aGlzLnNwZWFrZXJzW2luZGV4XSA9IFt4LHldO1xuICAgIHRoaXMuc3BlYWtlckVsZW1lbnRzW2luZGV4XS5zZXRBdHRyaWJ1dGUoJ2N4JywgeCp0aGlzLndpZHRoKTtcbiAgICB0aGlzLnNwZWFrZXJFbGVtZW50c1tpbmRleF0uc2V0QXR0cmlidXRlKCdjeScsIHkqdGhpcy5oZWlnaHQpO1xuICAgIHRoaXMuY2FsY3VsYXRlTGV2ZWxzKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMubGV2ZWxzKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuXG4gIH1cblxuICAvKipcbiAgU2V0IGFsbCBzcGVha2VyIGxvY2F0aW9uc1xuICBAcGFyYW0gbG9jYXRpb25zIHtBcnJheX0gQXJyYXkgb2Ygc3BlYWtlciBsb2NhdGlvbnMuIEVhY2ggaXRlbSBpbiB0aGUgYXJyYXkgc2hvdWxkIGJlIGFuIGFycmF5IG9mIG5vcm1hbGl6ZWQgeCBhbmQgeSBjb29yZGluYXRlcy5cblxuICBzZXRTcGVha2Vycyhsb2NhdGlvbnMpIHtcblxuICB9XG4gICovXG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL3BhbjJkLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcblxuLyoqXG4qIFRpbHRcbipcbiogQGRlc2NyaXB0aW9uIERldmljZSB0aWx0IHNlbnNvciB3aXRoIDIgb3IgMyBheGVzIChkZXBlbmRpbmcgb24geW91ciBkZXZpY2UgYW5kIGJyb3dzZXIpLlxuKlxuKiBAZGVtbyA8c3BhbiBuZXh1cy11aT0ndGlsdCc+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgdGlsdCA9IG5ldyBOZXh1cy5UaWx0KCcjdGFyZ2V0JylcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYXQgYSByZWd1bGFyIGludGVydmFsLCBhcyBsb25nIGFzIHRoaXMgaW50ZXJmYWNlIGlzIGFjdGl2ZSAoc2VlIHRoZSBpbnRlcmZhY2UncyA8aT4uYWN0aXZlPC9pPiBwcm9wZXJ0eSk8YnI+XG4qIFRoZSBldmVudCBkYXRhIGlzIGFuIDxpPm9iamVjdDwvaT4gY29udGFpbmluZyB4IChudW1iZXIpIGFuZCB5IChudW1iZXIpIHByb3BlcnRpZXMgd2hpY2ggcmVwcmVzZW50IHRoZSBjdXJyZW50IHRpbHQgc3RhdGUgb2YgdGhlIGRldmljZS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogdGlsdC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUaWx0IGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbODAsODBdXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuX2FjdGl2ZSA9IHRydWU7XG5cbiAgICB0aGlzLmluaXQoKTtcblxuICAgIC8vIGFkZCBldmVudCBsaXN0ZW5lciBmb3IgZGV2aWNlIG9yaWVudGF0aW9uXG5cbiAgXHR0aGlzLmJvdW5kVXBkYXRlID0gdGhpcy51cGRhdGUuYmluZCh0aGlzKTtcbiAgLy9cdHRoaXMuYm91bmRNb3pUaWx0ID0gdGhpcy5tb3pUaWx0LmJpbmQodGhpcylcblxuICBcdGlmICh3aW5kb3cuRGV2aWNlT3JpZW50YXRpb25FdmVudCkge1xuICBcdFx0dGhpcy5vcmllbnRhdGlvbkxpc3RlbmVyID0gd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2RldmljZW9yaWVudGF0aW9uJywgdGhpcy5ib3VuZFVwZGF0ZSwgZmFsc2UpO1xuICBcdH0gZWxzZSB7XG4gICAgICB0aGlzLl9hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcbiAgICB9XG5cblxuXG4gICAgICAvKmVsc2UgaWYgKHdpbmRvdy5PcmllbnRhdGlvbkV2ZW50KSB7XG4gIC8vXHQgIFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ01vek9yaWVudGF0aW9uJywgdGhpcy5ib3VuZE1velRpbHQsIGZhbHNlKTtcbiAgXHR9IGVsc2Uge1xuICBcdCAgXHRjb25zb2xlLmxvZygnTm90IHN1cHBvcnRlZCBvbiB5b3VyIGRldmljZSBvciBicm93c2VyLicpO1xuICBcdH0gKi9cblxuXG4gIH1cblxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy50aXRsZSA9IHN2Zy5jcmVhdGUoJ3RleHQnKTtcbiAgICB0aGlzLmNpcmNsZVggPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLmNpcmNsZVkgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLmNpcmNsZVogPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgIHRoaXMuYmFyWCA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmJhclkgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG4gICAgdGhpcy5iYXJaID0gc3ZnLmNyZWF0ZSgncGF0aCcpO1xuXG4gICAgdGhpcy5iYXJYMiA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmJhclkyID0gc3ZnLmNyZWF0ZSgncGF0aCcpO1xuICAgIHRoaXMuYmFyWjIgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG5cbiAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC44Jyk7XG4gICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScsJzAuOCcpO1xuICAgIHRoaXMuYmFyWi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLCcwLjgnKTtcbiAgICB0aGlzLmJhclgyLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScsJzAuOCcpO1xuICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC44Jyk7XG4gICAgdGhpcy5iYXJaMi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLCcwLjgnKTtcblxuICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoKjMvMTIpO1xuICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmhlaWdodCozLzQpO1xuICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMuaGVpZ2h0LzEwKTtcbiAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC40Jyk7XG5cbiAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdjeCcsdGhpcy53aWR0aCo2LzEyKTtcbiAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQqMy80KTtcbiAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmhlaWdodC8xMCk7XG4gICAgdGhpcy5jaXJjbGVZLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScsJzAuNCcpO1xuXG4gICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMud2lkdGgqOS8xMik7XG4gICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMuaGVpZ2h0KjMvNCk7XG4gICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgncicsdGhpcy5oZWlnaHQvMTApO1xuICAgIHRoaXMuY2lyY2xlWi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLCcwLjQnKTtcblxuXG4gICAgdGhpcy5iYXJYLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG4gICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG4gICAgdGhpcy5iYXJaLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG5cbiAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICB0aGlzLmJhclkuc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcblxuICAgIHRoaXMuYmFyWDIuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLE1hdGgucm91bmQodGhpcy5oZWlnaHQvMzApKTtcbiAgICB0aGlzLmJhclkyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG4gICAgdGhpcy5iYXJaMi5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsTWF0aC5yb3VuZCh0aGlzLmhlaWdodC8zMCkpO1xuXG4gICAgdGhpcy5iYXJYMi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAnbm9uZScpO1xuICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZSgnZmlsbCcsICdub25lJyk7XG5cblxuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCd4Jyx0aGlzLndpZHRoLzIpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCd5Jyx0aGlzLmhlaWdodC8zKzcpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdmb250LXNpemUnLCcxNXB4Jyk7XG4gICAgdGhpcy50aXRsZS5zZXRBdHRyaWJ1dGUoJ2ZvbnQtd2VpZ2h0JywnYm9sZCcpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdsZXR0ZXItc3BhY2luZycsJzJweCcpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC43Jyk7XG4gICAgdGhpcy50aXRsZS5zZXRBdHRyaWJ1dGUoJ3RleHQtYW5jaG9yJywnbWlkZGxlJyk7XG4gICAgdGhpcy50aXRsZS50ZXh0Q29udGVudCA9ICdUSUxUJztcblxuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2lyY2xlWCk7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2lyY2xlWSk7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2lyY2xlWik7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJYKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJZKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJaKTtcblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhclgyKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJZMik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuYmFyWjIpO1xuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudGl0bGUpO1xuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIGlmICh0aGlzLl9hY3RpdmUpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG4gICAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLmxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubGlnaHQpO1xuICAgICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLmxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubGlnaHQpO1xuICAgICAgdGhpcy5iYXJaLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhclgyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhclkyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLnRpdGxlLnNldEF0dHJpYnV0ZSgnZmlsbCcsdGhpcy5jb2xvcnMubGlnaHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuICAgICAgdGhpcy5jaXJjbGVZLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuICAgICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWDIuc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWjIuc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgfVxuXG4gIH1cblxuICB1cGRhdGUodikge1xuICAgIGlmICh0aGlzLl9hY3RpdmUpe1xuXG4gICAgICBsZXQgeSA9IHYuYmV0YTtcbiAgICAgIGxldCB4ID0gdi5nYW1tYTtcbiAgICAgIGxldCB6ID0gdi5hbHBoYTtcblxuICAgICAgLy8gdGFrZSB0aGUgb3JpZ2luYWwgLTkwIHRvIDkwIHNjYWxlIGFuZCBub3JtYWxpemUgaXQgMC0xXG4gICAgICB4ID0gbWF0aC5zY2FsZSh4LC05MCw5MCwwLDEpO1xuICAgICAgeSA9IG1hdGguc2NhbGUoeSwtOTAsOTAsMCwxKTtcbiAgICAgIHogPSBtYXRoLnNjYWxlKHosMCwzNjAsMCwxKTtcblxuXG4gICAgICBsZXQgaGFuZGxlUG9pbnRzID0ge1xuICAgICAgICBzdGFydDogTWF0aC5QSSoxLjUsXG4gICAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHgsMCwwLjUsTWF0aC5QSSoxLjUsTWF0aC5QSSowLjUpICwgTWF0aC5QSSowLjUsIE1hdGguUEkqMS41IClcbiAgICAgIH07XG4gICAgICBsZXQgaGFuZGxlMlBvaW50cyA9IHtcbiAgICAgICAgc3RhcnQ6IE1hdGguUEkqMi41LFxuICAgICAgICBlbmQ6IG1hdGguY2xpcCggbWF0aC5zY2FsZSh4LDAuNSwxLE1hdGguUEkqMi41LE1hdGguUEkqMS41KSAsIE1hdGguUEkqMS41LCBNYXRoLlBJKjIuNSApXG4gICAgICB9O1xuXG4gICAgICBsZXQgaGFuZGxlUGF0aCA9IHN2Zy5hcmModGhpcy5jaXJjbGVYLmN4LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWC5jeS5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVguci5iYXNlVmFsLnZhbHVlLCBoYW5kbGVQb2ludHMuc3RhcnQsIGhhbmRsZVBvaW50cy5lbmQpO1xuICAgICAgbGV0IGhhbmRsZTJQYXRoID0gc3ZnLmFyYyh0aGlzLmNpcmNsZVguY3guYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVYLmN5LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWC5yLmJhc2VWYWwudmFsdWUsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgICAgdGhpcy5iYXJYLnNldEF0dHJpYnV0ZSgnZCcsIGhhbmRsZVBhdGgpO1xuICAgICAgdGhpcy5iYXJYMi5zZXRBdHRyaWJ1dGUoJ2QnLCBoYW5kbGUyUGF0aCk7XG5cblxuXG5cblxuICAgICAgaGFuZGxlUG9pbnRzID0ge1xuICAgICAgICBzdGFydDogTWF0aC5QSSoxLjUsXG4gICAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHksMCwwLjUsTWF0aC5QSSoxLjUsTWF0aC5QSSowLjUpICwgTWF0aC5QSSowLjUsIE1hdGguUEkqMS41IClcbiAgICAgIH07XG4gICAgICBoYW5kbGUyUG9pbnRzID0ge1xuICAgICAgICBzdGFydDogTWF0aC5QSSoyLjUsXG4gICAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHksMC41LDEsTWF0aC5QSSoyLjUsTWF0aC5QSSoxLjUpICwgTWF0aC5QSSoxLjUsIE1hdGguUEkqMi41IClcbiAgICAgIH07XG5cbiAgICAgIGhhbmRsZVBhdGggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWS5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVkuY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVZLnIuYmFzZVZhbC52YWx1ZSwgaGFuZGxlUG9pbnRzLnN0YXJ0LCBoYW5kbGVQb2ludHMuZW5kKTtcbiAgICAgIGhhbmRsZTJQYXRoID0gc3ZnLmFyYyh0aGlzLmNpcmNsZVkuY3guYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVZLmN5LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWS5yLmJhc2VWYWwudmFsdWUsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnZCcsIGhhbmRsZVBhdGgpO1xuICAgICAgdGhpcy5iYXJZMi5zZXRBdHRyaWJ1dGUoJ2QnLCBoYW5kbGUyUGF0aCk7XG5cblxuXG5cblxuXG4gICAgICBoYW5kbGVQb2ludHMgPSB7XG4gICAgICAgIHN0YXJ0OiBNYXRoLlBJKjEuNSxcbiAgICAgICAgZW5kOiBtYXRoLmNsaXAoIG1hdGguc2NhbGUoeiwwLDAuNSxNYXRoLlBJKjEuNSxNYXRoLlBJKjAuNSkgLCBNYXRoLlBJKjAuNSwgTWF0aC5QSSoxLjUgKVxuICAgICAgfTtcbiAgICAgIGhhbmRsZTJQb2ludHMgPSB7XG4gICAgICAgIHN0YXJ0OiBNYXRoLlBJKjIuNSxcbiAgICAgICAgZW5kOiBtYXRoLmNsaXAoIG1hdGguc2NhbGUoeiwwLjUsMSxNYXRoLlBJKjIuNSxNYXRoLlBJKjEuNSkgLCBNYXRoLlBJKjEuNSwgTWF0aC5QSSoyLjUgKVxuICAgICAgfTtcblxuICAgICAgaGFuZGxlUGF0aCA9IHN2Zy5hcmModGhpcy5jaXJjbGVaLmN4LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWi5jeS5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVouci5iYXNlVmFsLnZhbHVlLCBoYW5kbGVQb2ludHMuc3RhcnQsIGhhbmRsZVBvaW50cy5lbmQpO1xuICAgICAgaGFuZGxlMlBhdGggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWi5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVouY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVaLnIuYmFzZVZhbC52YWx1ZSwgaGFuZGxlMlBvaW50cy5zdGFydCwgaGFuZGxlMlBvaW50cy5lbmQpO1xuXG4gICAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKCdkJywgaGFuZGxlUGF0aCk7XG4gICAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZSgnZCcsIGhhbmRsZTJQYXRoKTtcblxuXG4gICAgICAvKlxuXG4gICAgICBsZXQgcG9pbnRzWCA9IHtcbiAgICAgICAgc3RhcnQ6IDAsXG4gICAgICAgIGVuZDogbWF0aC5zY2FsZSggeCwgMCwgMSwgMCwgTWF0aC5QSSoyIClcbiAgICAgIH07XG5cbiAgICAvLyAgY29uc29sZS5sb2codGhpcy5jaXJjbGVYLmN4LmJhc2VWYWwudmFsdWUpO1xuXG4gICAgICBsZXQgcGF0aFggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWC5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVguY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVYLnIuYmFzZVZhbC52YWx1ZSoyLCBwb2ludHNYLnN0YXJ0LCBwb2ludHNYLmVuZCk7XG5cbiAgICAgIHRoaXMuYmFyWC5zZXRBdHRyaWJ1dGUoJ2QnLHBhdGhYKTsgKi9cblxuICAgICAgLy90aGlzLnRleHRILnRleHRDb250ZW50ID0gbWF0aC5wcnVuZSh4LDIpO1xuICAgICAgLy90aGlzLnRleHRWLnRleHRDb250ZW50ID0gbWF0aC5wcnVuZSh5LDIpO1xuICAgICAgLy9cbiAgICAvLyAgdGhpcy5jaXJjbGVYLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScseCk7XG4gICAgLy8gIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLHkpO1xuICAgIC8vICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKCdvcGFjaXR5Jyx6KTtcblxuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLCB7XG4gICAgICAgIHg6IHgsXG4gICAgICAgIHk6IHksXG4gICAgICAgIHo6IHpcbiAgICAgIH0pO1xuXG4gICAgfVxuXG4gIH1cblxuICBjbGljaygpIHtcbiAgICBpZiAod2luZG93LkRldmljZU9yaWVudGF0aW9uRXZlbnQpIHtcbiAgICAgIHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICBXaGV0aGVyIHRoZSBpbnRlcmZhY2UgaXMgb24gKGVtaXR0aW5nIHZhbHVlcykgb3Igb2ZmIChwYXVzZWQgJiBub3QgZW1pdHRpbmcgdmFsdWVzKS4gU2V0dGluZyB0aGlzIHByb3BlcnR5IHdpbGwgdXBkYXRlIGl0LlxuICBAdHlwZSB7Ym9vbGVhbn1cbiAgKi9cblxuICBnZXQgYWN0aXZlKCkge1xuICAgIHJldHVybiB0aGlzLl9hY3RpdmU7XG4gIH1cblxuICBzZXQgYWN0aXZlKG9uKSB7XG4gICAgdGhpcy5fYWN0aXZlID0gb247XG4gICAgdGhpcy5jb2xvckludGVyZmFjZSgpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGV2aWNlb3JpZW50YXRpb24nLCB0aGlzLmJvdW5kVXBkYXRlLCBmYWxzZSk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvdGlsdC5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IGRvbSA9IHJlcXVpcmUoJy4uL3V0aWwvZG9tJyk7XG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgU2xpZGVyVGVtcGxhdGUgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL3NsaWRlcnRlbXBsYXRlJyk7XG5sZXQgdG91Y2ggPSByZXF1aXJlKCcuLi91dGlsL3RvdWNoJyk7XG5cblxuXG5jbGFzcyBTaW5nbGVTbGlkZXIgZXh0ZW5kcyBTbGlkZXJUZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnc2NhbGUnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMTIwLDIwXSxcbiAgICAgICdvcmllbnRhdGlvbic6ICd2ZXJ0aWNhbCcsXG4gICAgICAnbW9kZSc6ICdhYnNvbHV0ZScsXG4gICAgICAnc2NhbGUnOiBbMCwxXSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDAsXG4gICAgICAnaGFzS25vYic6IHRydWVcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG5cbiAgICAvKiBldmVudHMgKi9cblxuICAgIGlmICghdG91Y2guZXhpc3RzKSB7XG5cbiAgICAgIHRoaXMuY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgIHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24gPSB7XG4gICAgICAgICAgaW5kZXg6IHRoaXMuaW5kZXgsXG4gICAgICAgICAgdmFsdWU6IHRoaXMudmFsdWVcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5kb3duKCk7XG4gICAgICAgIHRoaXMubXVsdGlzbGlkZXIudmFsdWVzW3RoaXMuaW5kZXhdID0gdGhpcy52YWx1ZTtcbiAgICAgIH07XG4gICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgKGUpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICBpZiAoIXRoaXMub2Zmc2V0KSB7XG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IGRvbS5maW5kUG9zaXRpb24odGhpcy5lbGVtZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVNb3VzZShlLHRoaXMub2Zmc2V0KTtcbiAgICAgICAgICB0aGlzLmRvd24oKTtcbiAgICAgICAgICB0aGlzLm11bHRpc2xpZGVyLnZhbHVlc1t0aGlzLmluZGV4XSA9IHRoaXMudmFsdWU7XG4gICAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJwb2xhdGlvbikge1xuICAgICAgICAgICAgbGV0IGRpc3RhbmNlID0gTWF0aC5hYnModGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uLmluZGV4LXRoaXMuaW5kZXgpO1xuICAgICAgICAgICAgaWYgKCBkaXN0YW5jZSA+IDEgKSB7XG4gICAgICAgICAgICAgIGxldCBsb3cgPSBNYXRoLm1pbih0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24uaW5kZXgsdGhpcy5pbmRleCk7XG4gICAgICAgICAgICAgIGxldCBoaWdoID0gTWF0aC5tYXgodGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uLmluZGV4LHRoaXMuaW5kZXgpO1xuICAgICAgICAgICAgICBsZXQgbG93VmFsdWUgPSB0aGlzLm11bHRpc2xpZGVyLnNsaWRlcnNbbG93XS52YWx1ZTtcbiAgICAgICAgICAgICAgbGV0IGhpZ2hWYWx1ZSA9IHRoaXMubXVsdGlzbGlkZXIuc2xpZGVyc1toaWdoXS52YWx1ZTtcbiAgICAgICAgICAgICAgZm9yIChsZXQgaT1sb3c7aTxoaWdoO2krKykge1xuICAgICAgICAgICAgICAgIHRoaXMubXVsdGlzbGlkZXIuc2xpZGVyc1tpXS52YWx1ZSA9IG1hdGguaW50ZXJwKCAoaS1sb3cpL2Rpc3RhbmNlLCBsb3dWYWx1ZSwgaGlnaFZhbHVlICk7XG4gICAgICAgICAgICAgICAgbGV0IHNtb290aGVkVmFsdWUgPSB0aGlzLm11bHRpc2xpZGVyLnNsaWRlcnNbaV0udmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbaV0gPSBzbW9vdGhlZFZhbHVlO1xuICAgICAgICAgICAgICAgIHRoaXMubXVsdGlzbGlkZXIudXBkYXRlKGksc21vb3RoZWRWYWx1ZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24gPSB7XG4gICAgICAgICAgICBpbmRleDogdGhpcy5pbmRleCxcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cblxuICAgICAgdGhpcy5tb3ZlID0gKCkgPT4ge1xuICAgICAgfTtcbiAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCAoZSkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tdWx0aXNsaWRlci5pbnRlcmFjdGluZykge1xuICAgICAgICAgIGlmICghdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbih0aGlzLmVsZW1lbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLm1vdXNlID0gZG9tLmxvY2F0ZU1vdXNlKGUsdGhpcy5vZmZzZXQpO1xuICAgICAgICAgIHRoaXMuc2xpZGUoKTtcbiAgICAgICAgICB0aGlzLm11bHRpc2xpZGVyLnZhbHVlc1t0aGlzLmluZGV4XSA9IHRoaXMudmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG5cbiAgICAgIHRoaXMucmVsZWFzZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5tdWx0aXNsaWRlci5pbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24gPSBmYWxzZTtcbiAgICAgIH07XG4gICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbdGhpcy5pbmRleF0gPSB0aGlzLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbdGhpcy5pbmRleF0gPSB0aGlzLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIH1cblxuICAgIHRoaXMuY3VzdG9tU3R5bGUoKTtcbiAgfVxuXG4gIGN1c3RvbVN0eWxlKCkge1xuXG4gICAgLyogc3R5bGUgY2hhbmdlcyAqL1xuXG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd4JywwKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsJ3RyYW5zbGF0ZSgwLDApJyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsMCk7IC8vIGNvcm5lciByYWRpdXNcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3J5JywwKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx0aGlzLndpZHRoKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsdGhpcy5oZWlnaHQpO1xuXG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneCcsMCk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywndHJhbnNsYXRlKDAsMCknKTtcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeCcsMCk7IC8vIGNvcm5lciByYWRpdXNcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeScsMCk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgnd2lkdGgnLHRoaXMud2lkdGgpO1xuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsdGhpcy5oZWlnaHQpO1xuXG4gIH1cblxufVxuXG4vKipcbiogTXVsdGlzbGlkZXJcbipcbiogQGRlc2NyaXB0aW9uIE11bHRpc2xpZGVyXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwibXVsdGlzbGlkZXJcIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBtdWx0aXNsaWRlciA9IG5ldyBOZXh1cy5NdWx0aXNsaWRlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBtdWx0aXNsaWRlciA9IG5ldyBOZXh1cy5NdWx0aXNsaWRlcignI3RhcmdldCcse1xuKiAgJ3NpemUnOiBbMjAwLDEwMF0sXG4qICAnbnVtYmVyT2ZTbGlkZXJzJzogNSxcbiogICdtaW4nOiAwLFxuKiAgJ21heCc6IDEsXG4qICAnc3RlcCc6IDAsXG4qICAndmFsdWVzJzogWzAuNywwLjcsMC43LDAuNywwLjddXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIFRoZSBldmVudCBkYXRhIGFuIG9iamVjdCBjb250YWluaW5nIDxpPmluZGV4PC9pPiBhbmQgPGk+dmFsdWU8L2k+IHByb3BlcnRpZXNcbipcbiogQG91dHB1dGV4YW1wbGVcbiogbXVsdGlzbGlkZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKi9cblxuLypcblByb3BlcnRpZXNcbi52YWx1ZXNcblxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTXVsdGlzbGlkZXIgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3ZhbHVlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFsyMDAsMTAwXSxcbiAgICAgICdudW1iZXJPZlNsaWRlcnMnOiA1LFxuICAgICAgJ21pbic6IDAsXG4gICAgICAnbWF4JzogMSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZXMnOiBbMC43LDAuNywwLjcsMC43LDAuN11cbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5fbnVtYmVyT2ZTbGlkZXJzID0gdGhpcy5zZXR0aW5ncy5udW1iZXJPZlNsaWRlcnM7XG4gICAgdGhpcy52YWx1ZXMgPSB0aGlzLnNldHRpbmdzLnZhbHVlcztcblxuICAgIHRoaXMuc2xpZGVycyA9IFtdO1xuXG4gICAgdGhpcy5pbnRlcmFjdGluZyA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgbGV0IG1pbiA9IHRoaXMuc2V0dGluZ3MubWluO1xuICAgIGxldCBtYXggPSB0aGlzLnNldHRpbmdzLm1heDtcbiAgICBsZXQgc3RlcCA9IHRoaXMuc2V0dGluZ3Muc3RlcDtcblxuICAgIGlmICh0aGlzLnNsaWRlcnMubGVuZ3RoKSB7XG4gICAgICBtaW4gPSB0aGlzLnNsaWRlcnNbMF0ubWluO1xuICAgICAgbWF4ID0gdGhpcy5zbGlkZXJzWzBdLm1heDtcbiAgICAgIHN0ZXAgPSB0aGlzLnNsaWRlcnNbMF0uc3RlcDtcbiAgICB9XG5cbiAgICB0aGlzLnNsaWRlcnMgPSBbXTtcblxuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuX251bWJlck9mU2xpZGVycztpKyspIHtcbiAgICAgIGxldCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG5cbiAgICAgIGxldCBzbGlkZXIgPSBuZXcgU2luZ2xlU2xpZGVyKGNvbnRhaW5lciwge1xuICAgICAgICAgIHNjYWxlOiBbbWluLG1heF0sXG4gICAgICAgICAgc3RlcDogc3RlcCxcbiAgICAgICAgICBtb2RlOiAnYWJzb2x1dGUnLFxuICAgICAgICAgIG9yaWVudGF0aW9uOiAndmVydGljYWwnLFxuICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlc1tpXSxcbiAgICAgICAgICBoYXNLbm9iOiBmYWxzZSxcbiAgICAgICAgICBjb21wb25lbnQ6IHRydWUsXG4gICAgICAgIH0sdGhpcy51cGRhdGUuYmluZCh0aGlzLGkpKTtcbiAgICAgIHNsaWRlci5tdWx0aXNsaWRlciA9IHRoaXM7XG5cbiAgICAgIHNsaWRlci5pbmRleCA9IGk7XG4gICAgICBpZiAodG91Y2guZXhpc3RzKSB7XG4gICAgICAgIHNsaWRlci5iYXIuaW5kZXggPSBpO1xuICAgICAgICBzbGlkZXIuZmlsbGJhci5pbmRleCA9IGk7XG4gICAgICAgIHNsaWRlci5wcmVDbGljayA9IHNsaWRlci5wcmVNb3ZlID0gc2xpZGVyLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgICAgc2xpZGVyLmNsaWNrID0gc2xpZGVyLm1vdmUgPSBzbGlkZXIucmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgICBzbGlkZXIucHJlVG91Y2ggPSBzbGlkZXIucHJlVG91Y2hNb3ZlID0gc2xpZGVyLnByZVRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgICBzbGlkZXIudG91Y2ggPSBzbGlkZXIudG91Y2hNb3ZlID0gc2xpZGVyLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNsaWRlcnMucHVzaChzbGlkZXIpO1xuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cbiAgICB9XG4gICAgaWYgKHRvdWNoLmV4aXN0cykge1xuICAgICAgdGhpcy5hZGRUb3VjaExpc3RlbmVycygpO1xuICAgIH1cblxuICB9XG5cbiAgY29sb3JJbnRlcmZhY2UoKSB7XG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5zbGlkZXJzLmxlbmd0aDtpKyspIHtcbiAgICAgIHRoaXMuc2xpZGVyc1tpXS5jb2xvcnMgPSB0aGlzLmNvbG9ycztcbiAgICAgIHRoaXMuc2xpZGVyc1tpXS5jb2xvckludGVyZmFjZSgpO1xuICAgIH1cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBsZXQgc2xpZGVyV2lkdGggPSB0aGlzLndpZHRoIC8gdGhpcy5zbGlkZXJzLmxlbmd0aDtcbiAgICBsZXQgc2xpZGVySGVpZ2h0ID0gdGhpcy5oZWlnaHQ7XG5cbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLnNsaWRlcnMubGVuZ3RoO2krKykge1xuICAgICAgdGhpcy5zbGlkZXJzW2ldLnJlc2l6ZShzbGlkZXJXaWR0aCxzbGlkZXJIZWlnaHQpO1xuICAgICAgdGhpcy5zbGlkZXJzW2ldLmN1c3RvbVN0eWxlKCk7XG4gICAgfVxuXG5cbiAgfVxuXG4gIHVwZGF0ZShpbmRleCx2YWx1ZSkge1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICAnaW5kZXgnOiBpbmRleCxcbiAgICAgICd2YWx1ZSc6IHZhbHVlXG4gICAgfSk7XG4gIH1cblxuICBhZGRUb3VjaExpc3RlbmVycygpIHtcblxuICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuXG4gICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGZhbHNlO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoZSkgPT4ge1xuICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRYLGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRZKTtcbiAgICAgIGxldCBzbGlkZXIgPSB0aGlzLnNsaWRlcnNbZWxlbWVudC5pbmRleF07XG4gICAgICBpZiAoIXNsaWRlci5vZmZzZXQpIHtcbiAgICAgICAgc2xpZGVyLm9mZnNldCA9IGRvbS5maW5kUG9zaXRpb24oc2xpZGVyLmVsZW1lbnQpO1xuICAgICAgfVxuICAgICAgc2xpZGVyLm1vdXNlID0gZG9tLmxvY2F0ZU1vdXNlKGUsc2xpZGVyLm9mZnNldCk7XG4gICAgICBzbGlkZXIuZG93bigpO1xuICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGVsZW1lbnQuaW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIChlKSA9PiB7XG4gICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFgsZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFkpO1xuICAgICAgbGV0IHNsaWRlciA9IHRoaXMuc2xpZGVyc1tlbGVtZW50LmluZGV4XTtcbiAgICAgIGlmICghc2xpZGVyLm9mZnNldCkge1xuICAgICAgICBzbGlkZXIub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbihzbGlkZXIuZWxlbWVudCk7XG4gICAgICB9XG4gICAgICBzbGlkZXIubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSxzbGlkZXIub2Zmc2V0KTtcbiAgICAgIGlmIChlbGVtZW50LmluZGV4IT09dGhpcy5jdXJyZW50RWxlbWVudCkge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50RWxlbWVudCA+PSAwKSB7XG4gICAgICAgICAgbGV0IHBhc3RzbGlkZXIgPSB0aGlzLnNsaWRlcnNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICAgICAgcGFzdHNsaWRlci51cCgpO1xuICAgICAgICB9XG4gICAgICAgIHNsaWRlci5kb3duKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzbGlkZXIuc2xpZGUoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBlbGVtZW50LmluZGV4O1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9KTtcblxuICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIChlKSA9PiB7XG4gICAgICAvLyBubyB0b3VjaGVzIHRvIGNhbGN1bGF0ZSBiZWNhdXNlIG5vbmUgcmVtYWluaW5nXG4gICAgICBsZXQgc2xpZGVyID0gdGhpcy5zbGlkZXJzW3RoaXMuY3VycmVudEVsZW1lbnRdO1xuICAgICAgc2xpZGVyLnVwKCk7XG4gICAgICB0aGlzLmludGVyYWN0aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZmFsc2U7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gIH1cblxuICAvKipcbiAgR2V0IG9yIHNldCB0aGUgbnVtYmVyIG9mIHNsaWRlcnNcbiAgQHR5cGUge051bWJlcn1cbiAgKi9cbiAgZ2V0IG51bWJlck9mU2xpZGVycygpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXJzLmxlbmd0aDtcbiAgfVxuXG4gIHNldCBudW1iZXJPZlNsaWRlcnModikge1xuICAgIGlmICh2PT09dGhpcy5zbGlkZXJzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNsaWRlcnMuZm9yRWFjaCgoc2xpZGVyKT0+e1xuICAgICAgc2xpZGVyLmRlc3Ryb3koKTtcbiAgICB9KTtcbiAgICB0aGlzLmVtcHR5KCk7XG4gICAgdGhpcy5fbnVtYmVyT2ZTbGlkZXJzID0gdjtcbiAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG4gIH1cblxuXG5cbiAgLyoqXG4gIExvd2VyIGxpbWl0IG9mIHRoZSBtdWx0aXNsaWRlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBtdWx0aXNsaWRlci5taW4gPSAxMDAwO1xuICAqL1xuICBnZXQgbWluKCkge1xuICAgIHJldHVybiB0aGlzLnNsaWRlcnNbMF0ubWluO1xuICB9XG4gIHNldCBtaW4odikge1xuICAgIHRoaXMuc2xpZGVycy5mb3JFYWNoKChzbGlkZXIpPT57XG4gICAgICBzbGlkZXIubWluID0gdjtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICBVcHBlciBsaW1pdCBvZiB0aGUgbXVsdGlzbGlkZXIncyBvdXRwdXQgcmFuZ2VcbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgbXVsdGlzbGlkZXIubWF4ID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXJzWzBdLm1heDtcbiAgfVxuICBzZXQgbWF4KHYpIHtcbiAgICB0aGlzLnNsaWRlcnMuZm9yRWFjaCgoc2xpZGVyKT0+e1xuICAgICAgc2xpZGVyLm1heCA9IHY7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBtdWx0aXNsaWRlcidzIHZhbHVlIGNoYW5nZXMgYnkuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIG11bHRpc2xpZGVyLnN0ZXAgPSA1O1xuICAqL1xuICBnZXQgc3RlcCgpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXJzWzBdLnN0ZXA7XG4gIH1cbiAgc2V0IHN0ZXAodikge1xuICAgIHRoaXMuc2xpZGVycy5mb3JFYWNoKChzbGlkZXIpPT57XG4gICAgICBzbGlkZXIuc3RlcCA9IHY7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgU2V0IHRoZSB2YWx1ZSBvZiBhbiBpbmRpdmlkdWFsIHNsaWRlclxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gU2xpZGVyIGluZGV4XG4gIEBwYXJhbSB2YWx1ZSB7bnVtYmVyfSBOZXcgc2xpZGVyIHZhbHVlXG4gIEBleGFtcGxlXG4gIC8vIFNldCB0aGUgZmlyc3Qgc2xpZGVyIHRvIHZhbHVlIDAuNVxuICBtdWx0aXNsaWRlci5zZXRTbGlkZXIoMCwwLjUpXG4gICovXG4gIHNldFNsaWRlcihpbmRleCx2YWx1ZSkge1xuICAgIHRoaXMuc2xpZGVyc1tpbmRleF0udmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgJ2luZGV4JzogaW5kZXgsXG4gICAgICAndmFsdWUnOiB2YWx1ZVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gIFNldCB0aGUgdmFsdWUgb2YgYWxsIHNsaWRlcnMgYXQgb25jZS4gSWYgdGhlIHNpemUgb2YgdGhlIGlucHV0IGFycmF5IGRvZXMgbm90IG1hdGNoIHRoZSBjdXJyZW50IG51bWJlciBvZiBzbGlkZXJzLCB0aGUgdmFsdWUgYXJyYXkgd2lsbCByZXBlYXQgdW50aWwgYWxsIHNsaWRlcnMgaGF2ZSBiZWVuIHNldC4gSS5lLiBhbiBpbnB1dCBhcnJheSBvZiBsZW5ndGggMSB3aWxsIHNldCBhbGwgc2xpZGVycyB0byB0aGF0IHZhbHVlLlxuICBAcGFyYW0gdmFsdWVzIHtBcnJheX0gQWxsIHNsaWRlciB2YWx1ZXNcbiAgQGV4YW1wbGVcbiAgbXVsdGlzbGlkZXIuc2V0QWxsU2xpZGVycyhbMC4yLDAuMywwLjQsMC41LDAuNl0pXG4gICovXG4gIHNldEFsbFNsaWRlcnModmFsdWVzKSB7XG4gICAgdGhpcy52YWx1ZXMgPSB2YWx1ZXM7XG4gICAgdGhpcy5zbGlkZXJzLmZvckVhY2goKHNsaWRlcixpKT0+e1xuICAgICAgc2xpZGVyLnZhbHVlID0gdmFsdWVzW2kldmFsdWVzLmxlbmd0aF07XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgICAnaW5kZXgnOiBpLFxuICAgICAgICAndmFsdWUnOiBzbGlkZXIudmFsdWVcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL211bHRpc2xpZGVyLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNsaWRlclRlbXBsYXRlIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcihhcmdzLG9wdGlvbnMsZGVmYXVsdHMpIHtcblxuICAgIHN1cGVyKGFyZ3Msb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLm9yaWVudGF0aW9uID0gdGhpcy5zZXR0aW5ncy5vcmllbnRhdGlvbjtcblxuICAvLyAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXG4gICAgdGhpcy5oYXNLbm9iID0gdGhpcy5zZXR0aW5ncy5oYXNLbm9iO1xuXG4gICAgLy8gdGhpcy5zdGVwIHNob3VsZCBldmVudHVhbGx5IGJlIGdldC9zZXRcbiAgICAvLyB1cGRhdGluZyBpdCB3aWxsIHVwZGF0ZSB0aGUgX3ZhbHVlIHN0ZXAgbW9kZWxcbiAgLy8gIHRoaXMuc3RlcCA9IHRoaXMuc2V0dGluZ3Muc3RlcDsgLy8gZmxvYXRcblxuICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5zY2FsZVswXSwgdGhpcy5zZXR0aW5ncy5zY2FsZVsxXSwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLHRoaXMub3JpZW50YXRpb24sWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblxuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnZhbHVlKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLmJhciA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmZpbGxiYXIgPSBzdmcuY3JlYXRlKCdyZWN0Jyk7XG4gICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXIpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmZpbGxiYXIpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmtub2IpO1xuXG4gICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG5cblxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG5cbiAgICBpZiAoIXRoaXMuc2V0dGluZ3Mub3JpZW50YXRpb24pIHtcbiAgICAgIGlmICh0aGlzLndpZHRoIDwgdGhpcy5oZWlnaHQpIHtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvbiA9ICd2ZXJ0aWNhbCc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uID0gJ2hvcml6b250YWwnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCB4LCB5LCB3LCBoLCBiYXJPZmZzZXQsIGNvcm5lclJhZGl1cztcbiAgICB0aGlzLmtub2JEYXRhID0ge1xuICAgICAgbGV2ZWw6IDAsXG4gICAgICByOiAwXG4gICAgfTtcblxuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAndmVydGljYWwnKSB7XG4gICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMud2lkdGggLyAyO1xuICAgIFx0eCA9IHRoaXMud2lkdGgvMjtcbiAgICBcdHkgPSAwO1xuICAgIFx0dyA9IHRoaXMudGhpY2tuZXNzO1xuICAgIFx0aCA9IHRoaXMuaGVpZ2h0O1xuICAgICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MgKiAwLjg7XG4gICAgXHR0aGlzLmtub2JEYXRhLmxldmVsID0gaC10aGlzLm5vcm1hbGl6ZWQqaDtcbiAgICAgIGJhck9mZnNldCA9ICd0cmFuc2xhdGUoJyt0aGlzLnRoaWNrbmVzcyooLTEpLzIrJywwKSc7XG4gICAgICBjb3JuZXJSYWRpdXMgPSB3LzI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGhpY2tuZXNzID0gdGhpcy5oZWlnaHQgLyAyO1xuICAgIFx0eCA9IDA7XG4gICAgXHR5ID0gdGhpcy5oZWlnaHQvMjtcbiAgICBcdHcgPSB0aGlzLndpZHRoO1xuICAgIFx0aCA9IHRoaXMudGhpY2tuZXNzO1xuICAgICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MgKiAwLjg7XG4gICAgXHR0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5ub3JtYWxpemVkKnc7XG4gICAgICBiYXJPZmZzZXQgPSAndHJhbnNsYXRlKDAsJyt0aGlzLnRoaWNrbmVzcyooLTEpLzIrJyknO1xuICAgICAgY29ybmVyUmFkaXVzID0gaC8yO1xuICAgIH1cblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneCcseCk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd5Jyx5KTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsYmFyT2Zmc2V0KTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3J4Jyxjb3JuZXJSYWRpdXMpOyAvLyBjb3JuZXIgcmFkaXVzXG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeScsY29ybmVyUmFkaXVzKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx3KTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsaCk7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneCcseCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd5Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx3KTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsaC10aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneCcsMCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd5Jyx5KTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsaCk7XG4gICAgfVxuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsYmFyT2Zmc2V0KTtcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeCcsY29ybmVyUmFkaXVzKTtcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeScsY29ybmVyUmFkaXVzKTtcblxuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAndmVydGljYWwnKSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeCcseCk7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx5KTtcbiAgICB9XG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgncicsdGhpcy5rbm9iRGF0YS5yKTtcblxuXG4gICAgaWYgKHRoaXMucG9zaXRpb24pIHtcbiAgICAgIHRoaXMucG9zaXRpb24ucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG4gICAgfVxuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIGlmICghdGhpcy5oYXNLbm9iKSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdmaWxsJywnbm9uZScpO1xuICAgIH1cblxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5jbGlja2VkKSB7XG4gICAgICB0aGlzLmtub2JEYXRhLnIgPSB0aGlzLnRoaWNrbmVzcyowLjc1O1xuICAgIH1cbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JEYXRhLnIpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZCp0aGlzLmhlaWdodDtcbiAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQgLSB0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd5Jyx0aGlzLmhlaWdodCAtIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZCp0aGlzLndpZHRoO1xuICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd4JywwKTtcbiAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfVxuICB9XG5cbiAgZG93bigpIHtcbiAgICB0aGlzLmNsaWNrZWQgPSB0cnVlO1xuICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzKjAuOTtcbiAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5zbGlkZSgpO1xuICB9XG5cbiAgc2xpZGUoKSB7XG4gICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5wb3NpdGlvbi51cGRhdGUodGhpcy5tb3VzZSk7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5fdmFsdWUudXBkYXRlTm9ybWFsKCB0aGlzLnBvc2l0aW9uLnZhbHVlICk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdXAoKSB7XG4gICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuICB9XG5cbiAgLyoqXG4gIFRoZSBzbGlkZXIncyBjdXJyZW50IHZhbHVlLiBJZiBzZXQgbWFudWFsbHksIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgc2xpZGVyLnZhbHVlID0gMTA7XG4gICovXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHYpIHtcbiAgICB0aGlzLl92YWx1ZS51cGRhdGUodik7XG4gICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBMb3dlciBsaW1pdCBvZiB0aGUgc2xpZGVycydzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBzbGlkZXIubWluID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1pbigpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWluO1xuICB9XG4gIHNldCBtaW4odikge1xuICAgIHRoaXMuX3ZhbHVlLm1pbiA9IHY7XG4gIH1cblxuICAvKipcbiAgVXBwZXIgbGltaXQgb2YgdGhlIHNsaWRlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBzbGlkZXIubWF4ID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWF4O1xuICB9XG4gIHNldCBtYXgodikge1xuICAgIHRoaXMuX3ZhbHVlLm1heCA9IHY7XG4gIH1cblxuICAvKipcbiAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBzbGlkZXIncyB2YWx1ZSBjaGFuZ2VzIGJ5LlxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBzbGlkZXIuc3RlcCA9IDU7XG4gICovXG4gIGdldCBzdGVwKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5zdGVwO1xuICB9XG4gIHNldCBzdGVwKHYpIHtcbiAgICB0aGlzLl92YWx1ZS5zdGVwID0gdjtcbiAgfVxuXG4gIC8qKlxuICBBYnNvbHV0ZSBtb2RlIChzbGlkZXIncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJyZWxhdGl2ZVwiLlxuICBAdHlwZSB7c3RyaW5nfVxuICBAZXhhbXBsZSBzbGlkZXIubW9kZSA9IFwicmVsYXRpdmVcIjtcbiAgKi9cbiAgZ2V0IG1vZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb24ubW9kZTtcbiAgfVxuICBzZXQgbW9kZSh2KSB7XG4gICAgdGhpcy5wb3NpdGlvbi5tb2RlID0gdjtcbiAgfVxuXG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9jb21wb25lbnRzL3NsaWRlcnRlbXBsYXRlLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcbmxldCBTdGVwID0gcmVxdWlyZSgnLi4vbW9kZWxzL3N0ZXAnKTtcbmltcG9ydCAqIGFzIEludGVyYWN0aW9uIGZyb20gJy4uL3V0aWwvaW50ZXJhY3Rpb24nO1xuXG4vKipcbiogUGFuXG4qXG4qIEBkZXNjcmlwdGlvbiBTdGVyZW8gY3Jvc3NmYWRlci5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJwYW5cIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBwYW4gPSBuZXcgTmV4dXMuUGFuKCcjdGFyZ2V0JylcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGludGVyZmFjZSdzIDxpPnZhbHVlPC9pPiAoLTEgdG8gMSksIGFzIHdlbGwgYXMgPGk+TDwvaT4gYW5kIDxpPlI8L2k+IGFtcGxpdHVkZSB2YWx1ZXMgKDAtMSkgZm9yIGxlZnQgYW5kIHJpZ2h0IHNwZWFrZXJzLCBjYWxjdWxhdGVkIGJ5IGEgc3F1YXJlLXJvb3QgY3Jvc3NmYWRlIGFsZ29yaXRobS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogcGFuLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhbiBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnc2NhbGUnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMTIwLDIwXSxcbiAgICAgICdvcmllbnRhdGlvbic6ICdob3Jpem9udGFsJyxcbiAgICAgICdtb2RlJzogJ3JlbGF0aXZlJyxcbiAgICAgICdzY2FsZSc6IFstMSwxXSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDAsXG4gICAgICAnaGFzS25vYic6IHRydWVcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5vcmllbnRhdGlvbiA9IHRoaXMuc2V0dGluZ3Mub3JpZW50YXRpb247XG5cbiAgICB0aGlzLm1vZGUgPSB0aGlzLnNldHRpbmdzLm1vZGU7XG5cbiAgICB0aGlzLmhhc0tub2IgPSB0aGlzLnNldHRpbmdzLmhhc0tub2I7XG5cbiAgICAvLyB0aGlzLnN0ZXAgc2hvdWxkIGV2ZW50dWFsbHkgYmUgZ2V0L3NldFxuICAgIC8vIHVwZGF0aW5nIGl0IHdpbGwgdXBkYXRlIHRoZSBfdmFsdWUgc3RlcCBtb2RlbFxuICAgIHRoaXMuc3RlcCA9IHRoaXMuc2V0dGluZ3Muc3RlcDsgLy8gZmxvYXRcblxuICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5zY2FsZVswXSwgdGhpcy5zZXR0aW5ncy5zY2FsZVsxXSwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5tb2RlLHRoaXMub3JpZW50YXRpb24sWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblxuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnZhbHVlKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLmJhciA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmtub2IgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBpZiAodGhpcy5wb3NpdGlvbikge1xuICAgICAgdGhpcy5wb3NpdGlvbi5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy53aWR0aCA8IHRoaXMuaGVpZ2h0KSB7XG4gICAgICB0aGlzLm9yaWVudGF0aW9uID0gJ3ZlcnRpY2FsJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcmllbnRhdGlvbiA9ICdob3Jpem9udGFsJztcbiAgICB9XG5cbiAgICBsZXQgeCwgeSwgdywgaCwgYmFyT2Zmc2V0LCBjb3JuZXJSYWRpdXM7XG4gICAgdGhpcy5rbm9iRGF0YSA9IHtcbiAgICAgIGxldmVsOiAwLFxuICAgICAgcjogMFxuICAgIH07XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy50aGlja25lc3MgPSB0aGlzLndpZHRoIC8gMjtcbiAgICBcdHggPSB0aGlzLndpZHRoLzI7XG4gICAgXHR5ID0gMDtcbiAgICBcdHcgPSB0aGlzLnRoaWNrbmVzcztcbiAgICBcdGggPSB0aGlzLmhlaWdodDtcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IGgtdGhpcy5rbm9iRGF0YS5yLXRoaXMubm9ybWFsaXplZCooaC10aGlzLmtub2JEYXRhLnIqMik7XG4gICAgICBiYXJPZmZzZXQgPSAndHJhbnNsYXRlKCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycsMCknO1xuICAgICAgY29ybmVyUmFkaXVzID0gdy8yO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMuaGVpZ2h0IC8gMjtcbiAgICBcdHggPSAwO1xuICAgIFx0eSA9IHRoaXMuaGVpZ2h0LzI7XG4gICAgXHR3ID0gdGhpcy53aWR0aDtcbiAgICBcdGggPSB0aGlzLnRoaWNrbmVzcztcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IHRoaXMubm9ybWFsaXplZCoody10aGlzLmtub2JEYXRhLnIqMikrdGhpcy5rbm9iRGF0YS5yO1xuICAgICAgYmFyT2Zmc2V0ID0gJ3RyYW5zbGF0ZSgwLCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycpJztcbiAgICAgIGNvcm5lclJhZGl1cyA9IGgvMjtcbiAgICB9XG5cbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3gnLHgpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneScseSk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGJhck9mZnNldCk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsY29ybmVyUmFkaXVzKTsgLy8gY29ybmVyIHJhZGl1c1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgncnknLGNvcm5lclJhZGl1cyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx4KTtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3knLHkpO1xuICAgIH1cbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JEYXRhLnIpO1xuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuXG4gICAgaWYgKCF0aGlzLmhhc0tub2IpIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCd0cmFuc3BhcmVudCcpO1xuICAgIH1cblxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5jbGlja2VkKSB7XG4gICAgICB0aGlzLmtub2JEYXRhLnIgPSB0aGlzLnRoaWNrbmVzcyowLjc1O1xuICAgIH1cbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JEYXRhLnIpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgXHQgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5rbm9iRGF0YS5yK3RoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQqKHRoaXMuaGVpZ2h0LXRoaXMua25vYkRhdGEucioyKTtcbiAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQgLSB0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICBcdCAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkKih0aGlzLndpZHRoLXRoaXMua25vYkRhdGEucioyKSt0aGlzLmtub2JEYXRhLnI7XG4gICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgIH1cbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MqMC45O1xuICAgIHRoaXMucG9zaXRpb24uYW5jaG9yID0gdGhpcy5tb3VzZTtcbiAgICB0aGlzLm1vdmUoKTtcbiAgfVxuXG4gIG1vdmUoKSB7XG4gICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5wb3NpdGlvbi51cGRhdGUodGhpcy5tb3VzZSk7XG5cbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS51cGRhdGVOb3JtYWwoIHRoaXMucG9zaXRpb24udmFsdWUgKTtcblxuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXG4gICAgICAgIEw6IE1hdGgucG93KCBtYXRoLnNjYWxlKHRoaXMudmFsdWUsLTEsMSwxLDApLCAyKSxcbiAgICAgICAgUjogTWF0aC5wb3coIG1hdGguc2NhbGUodGhpcy52YWx1ZSwtMSwxLDAsMSksIDIpXG4gICAgICB9KTtcblxuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBUaGUgcG9zaXRpb24gb2YgY3Jvc3NmYWRlciwgZnJvbSAtMSAobGVmdCkgdG8gMSAocmlnaHQpLiBTZXR0aW5nIHRoaXMgdmFsdWUgdXBkYXRlcyB0aGUgaW50ZXJmYWNlIGFuZCB0cmlnZ2VycyB0aGUgb3V0cHV0IGV2ZW50LlxuICBAdHlwZSB7bnVtYmVyfVxuICAqL1xuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuICB9XG5cbiAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgdGhpcy5fdmFsdWUudXBkYXRlKHZhbHVlKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXG4gICAgICBMOiBNYXRoLnBvdyggbWF0aC5zY2FsZSh0aGlzLnZhbHVlLC0xLDEsMSwwKSwgMiksXG4gICAgICBSOiBNYXRoLnBvdyggbWF0aC5zY2FsZSh0aGlzLnZhbHVlLC0xLDEsMCwxKSwgMilcbiAgICB9KTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgZ2V0IG5vcm1hbGl6ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvcGFuLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcblxuXG5sZXQgUG9pbnQgPSBmdW5jdGlvbihwb2ludCxlbnZlbG9wZSkge1xuXG4gIHRoaXMueCA9IHBvaW50Lng7XG4gIHRoaXMueSA9IHBvaW50Lnk7XG4gIHRoaXMuZW52ZWxvcGUgPSBlbnZlbG9wZTtcblxuICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnZmlsbCcsdGhpcy5lbnZlbG9wZS5jb2xvcnMuYWNjZW50KTtcblxuICB0aGlzLmVudmVsb3BlLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcblxuICB0aGlzLnJlc2l6ZSA9IGZ1bmN0aW9uKCkge1xuICAgIGxldCByID0gfn4oTWF0aC5taW4odGhpcy5lbnZlbG9wZS53aWR0aCx0aGlzLmVudmVsb3BlLmhlaWdodCkvNTApKzI7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgncicscik7XG4gIH07XG5cbiAgdGhpcy5tb3ZlID0gZnVuY3Rpb24oeCx5KSB7XG5cbiAgICB0aGlzLnggPSAoeCB8fCB4PT09MCkgPyB4IDogdGhpcy54O1xuICAgIHRoaXMueSA9ICh5IHx8IHk9PT0wKSA/IHkgOiB0aGlzLnk7XG5cbiAgICBpZiAodGhpcy5lbnZlbG9wZS5ub2Rlcy5pbmRleE9mKHRoaXMpPj0wKSB7XG5cbiAgICAgIGxldCBwcmV2SW5kZXggPSB0aGlzLmVudmVsb3BlLm5vZGVzLmluZGV4T2YodGhpcyktMTtcbiAgICAgIGxldCBuZXh0SW5kZXggPSB0aGlzLmVudmVsb3BlLm5vZGVzLmluZGV4T2YodGhpcykrMTtcblxuICAgICAgbGV0IHByZXZOb2RlID0gdGhpcy5lbnZlbG9wZS5ub2Rlc1twcmV2SW5kZXhdO1xuICAgICAgbGV0IG5leHROb2RlID0gdGhpcy5lbnZlbG9wZS5ub2Rlc1tuZXh0SW5kZXhdO1xuXG4gICAgICBsZXQgbG93WCA9IHByZXZJbmRleCA+PSAwID8gcHJldk5vZGUueCA6IDA7XG4gICAgICBsZXQgaGlnaFggPSBuZXh0SW5kZXggPCB0aGlzLmVudmVsb3BlLm5vZGVzLmxlbmd0aCA/IG5leHROb2RlLnggOiAxO1xuXG4gICAgICBpZiAodGhpcy54IDwgbG93WCkgeyB0aGlzLnggPSBsb3dYOyB9XG4gICAgICBpZiAodGhpcy54ID4gaGlnaFgpIHsgdGhpcy54ID0gaGlnaFg7IH1cblxuICAgIH1cblxuICAgIHRoaXMubG9jYXRpb24gPSB0aGlzLmdldENvb3JkaW5hdGVzKCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3gnLCB0aGlzLmxvY2F0aW9uLngpO1xuICAgIHRoaXMuZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2N5JywgdGhpcy5sb2NhdGlvbi55KTtcbiAgfTtcblxuICB0aGlzLmdldENvb3JkaW5hdGVzID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHRoaXMueCAqIHRoaXMuZW52ZWxvcGUud2lkdGgsXG4gICAgICB5OiAoMS10aGlzLnkpICogdGhpcy5lbnZlbG9wZS5oZWlnaHRcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMubW92ZSh0aGlzLngsdGhpcy55LHRydWUpO1xuICB0aGlzLnJlc2l6ZSgpO1xuXG4gIHRoaXMuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuZW52ZWxvcGUuZWxlbWVudC5yZW1vdmVDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICAgIHRoaXMuZW52ZWxvcGUubm9kZXMuc3BsaWNlKHRoaXMuZW52ZWxvcGUubm9kZXMuaW5kZXhPZih0aGlzKSwxKTtcbiAgfTtcblxuXG59O1xuXG5cbi8qKlxuKiBFbnZlbG9wZVxuKlxuKiBAZGVzY3JpcHRpb24gSW50ZXJhY3RpdmUgbGluZWFyIHJhbXAgdmlzdWFsaXphdGlvbi5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJlbnZlbG9wZVwiPjwvc3Bhbj5cbipcbiogQGV4YW1wbGVcbiogdmFyIGVudmVsb3BlID0gbmV3IE5leHVzLkVudmVsb3BlKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIGVudmVsb3BlID0gbmV3IE5leHVzLkVudmVsb3BlKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMzAwLDE1MF0sXG4qICAgJ3BvaW50cyc6IFtcbiogICAgIHtcbiogICAgICAgeDogMC4xLFxuKiAgICAgICB5OiAwLjRcbiogICAgIH0sXG4qICAgICB7XG4qICAgICAgIHg6IDAuMzUsXG4qICAgICAgIHk6IDAuNlxuKiAgICAgfSxcbiogICAgIHtcbiogICAgICAgeDogMC42NSxcbiogICAgICAgeTogMC4yXG4qICAgICB9LFxuKiAgICAge1xuKiAgICAgICB4OiAwLjksXG4qICAgICAgIHk6IDAuNFxuKiAgICAgfSxcbiogICBdXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIGEgbm9kZSBpcyBtb3ZlZC4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBhcnJheSBvZiBwb2ludCBsb2NhdGlvbnMuIEVhY2ggaXRlbSBpbiB0aGUgYXJyYXkgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgPGk+eDwvaT4gYW5kIDxpPnk8L2k+IHByb3BlcnRpZXMgZGVzY3JpYmluZyB0aGUgbG9jYXRpb24gb2YgYSBwb2ludCBvbiB0aGUgZW52ZWxvcGUuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIGVudmVsb3BlLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEVudmVsb3BlIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMzAwLDE1MF0sXG4gICAgICAncG9pbnRzJzogW1xuICBcdFx0XHR7XG4gIFx0XHRcdFx0eDogMC4xLFxuICBcdFx0XHRcdHk6IDAuNFxuICBcdFx0XHR9LFxuICBcdFx0XHR7XG4gIFx0XHRcdFx0eDogMC4zNSxcbiAgXHRcdFx0XHR5OiAwLjZcbiAgXHRcdFx0fSxcbiAgXHRcdFx0e1xuICBcdFx0XHRcdHg6IDAuNjUsXG4gIFx0XHRcdFx0eTogMC4yXG4gIFx0XHRcdH0sXG4gIFx0XHRcdHtcbiAgXHRcdFx0XHR4OiAwLjksXG4gIFx0XHRcdFx0eTogMC40XG4gIFx0XHRcdH1cbiAgXHRcdF1cbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5wb2ludHMgPSB0aGlzLnNldHRpbmdzLnBvaW50cztcblxuICAgIHRoaXMubm9kZXMgPSBbXTtcblxuICAgIHRoaXMuc2VsZWN0ZWQgPSBmYWxzZTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG5cbiAgICB0aGlzLnBvaW50cy5mb3JFYWNoKChwb2ludCkgPT4ge1xuICAgICAgbGV0IG5vZGUgPSBuZXcgUG9pbnQocG9pbnQsdGhpcyk7XG4gICAgICB0aGlzLm5vZGVzLnB1c2gobm9kZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNvcnRQb2ludHMoKTtcblxuICAgIHRoaXMubGluZSA9IHN2Zy5jcmVhdGUoJ3BvbHlsaW5lJyk7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJywgMik7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZSgnZmlsbCcsICdub25lJyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5saW5lKTtcblxuICAgIHRoaXMuZmlsbCA9IHN2Zy5jcmVhdGUoJ3BvbHlsaW5lJyk7XG4gICAgdGhpcy5maWxsLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywgJzAuMicpO1xuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuZmlsbCk7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBmb3IgKGxldCBpPTA7IGk8dGhpcy5ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5ub2Rlc1tpXS5yZXNpemUoKTtcbiAgICAgIHRoaXMubm9kZXNbaV0ubW92ZSgpO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB0aGlzLmZpbGwuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB0aGlzLm5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgIG5vZGUuZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgLy8gIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0ubW92ZSggdGhpcy5wb2ludHMgKVxuICAgIHRoaXMuY2FsY3VsYXRlUGF0aCgpO1xuICB9XG5cbiAgY2FsY3VsYXRlUG9pbnRzKCkge1xuICAgIHRoaXMucG9pbnRzID0gW107XG4gICAgdGhpcy5ub2Rlcy5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgICB0aGlzLnBvaW50cy5wdXNoKHsgeDogbm9kZS54LCB5OiBub2RlLnkgfSk7XG4gICAgfSk7XG4gIH1cblxuICBjYWxjdWxhdGVQYXRoKCkge1xuXG4gICAgLy9zdHJva2UgZGF0YVxuICAgIGxldCBkYXRhID0gJzAgJysgdGhpcy5ub2Rlc1swXS5sb2NhdGlvbi55KycsICc7XG5cbiAgICAvLyBkYXRhIHNob3VsZCBiZSByZS1vcmRlcmVkIGJhc2VkIG9uIHggbG9jYXRpb24uXG4gICAgLy8gd2hhdGV2ZXIgZnVuY3Rpb24gYWRkcyBhIG5vZGUgc2hvdWxkIGFkZCBpdCBhdCB0aGUgcmlnaHQgaW5kZXhcblxuICAgIHRoaXMubm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgIC8vICBsZXQgbG9jYXRpb24gPSBub2RlLmdldENvb3JkaW5hdGVzKCk7XG4gICAgICBkYXRhICs9IG5vZGUubG9jYXRpb24ueCArICcgJyArIG5vZGUubG9jYXRpb24ueSArICcsICc7XG4gICAgfSk7XG5cblxuICAvLyAgZGF0YSArPSBwb2ludC54KnRoaXMud2lkdGgrJyAnKyBwb2ludC55KnRoaXMuaGVpZ2h0KycsICc7XG4gICAgZGF0YSArPSB0aGlzLndpZHRoICsgJyAnKyB0aGlzLm5vZGVzW3RoaXMubm9kZXMubGVuZ3RoLTFdLmxvY2F0aW9uLnk7XG5cbiAgICB0aGlzLmxpbmUuc2V0QXR0cmlidXRlKCdwb2ludHMnLCBkYXRhKTtcblxuICAgIC8vIGZpbGwgZGF0YVxuICAgIC8vIGFkZCBib3R0b20gY29ybmVyc1xuXG4gICAgZGF0YSArPSAnLCAnK3RoaXMud2lkdGggKycgJyt0aGlzLmhlaWdodCsnLCAnO1xuICAgIGRhdGEgKz0gJzAgJyt0aGlzLmhlaWdodDtcblxuICAgIHRoaXMuZmlsbC5zZXRBdHRyaWJ1dGUoJ3BvaW50cycsIGRhdGEpO1xuXG4gIH1cblxuXG5cbiAgY2xpY2soKSB7XG4gIFx0Ly8gZmluZCBuZWFyZXN0IG5vZGUgYW5kIHNldCB0aGlzLnNlbGVjdGVkIChpbmRleClcbiAgICB0aGlzLmhhc01vdmVkID0gZmFsc2U7XG4gIFx0dGhpcy5zZWxlY3RlZCA9IHRoaXMuZmluZE5lYXJlc3ROb2RlKCk7XG5cbiAgICB0aGlzLm5vZGVzW3RoaXMuc2VsZWN0ZWRdLm1vdmUodGhpcy5tb3VzZS54L3RoaXMud2lkdGgsMS10aGlzLm1vdXNlLnkvdGhpcy5oZWlnaHQpO1xuICAgIHRoaXMuc2NhbGVOb2RlKHRoaXMuc2VsZWN0ZWQpO1xuXG4gICAgLy8gbXVzdCBkbyB0aGlzIGIvYyBuZXcgbm9kZSBtYXkgaGF2ZSBiZWVuIGNyZWF0ZWRcbiAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gIFx0dGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIG1vdmUoKSB7XG4gIFx0aWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5tb3VzZS54ID0gbWF0aC5jbGlwKHRoaXMubW91c2UueCwwLHRoaXMud2lkdGgpO1xuICAgICAgdGhpcy5oYXNNb3ZlZCA9IHRydWU7XG5cbiAgICAgIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0ubW92ZSh0aGlzLm1vdXNlLngvdGhpcy53aWR0aCwxLXRoaXMubW91c2UueS90aGlzLmhlaWdodCk7XG4gICAgXHR0aGlzLnNjYWxlTm9kZSh0aGlzLnNlbGVjdGVkKTtcblxuICAgICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcbiAgXHRcdHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gIFx0XHR0aGlzLnJlbmRlcigpO1xuICBcdH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG5cbiAgXHRpZiAoIXRoaXMuaGFzTW92ZWQpIHtcbiAgICAgIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0uZGVzdHJveSgpO1xuICBcdH1cblxuICAgIHRoaXMuY2FsY3VsYXRlUG9pbnRzKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMucG9pbnRzKTtcbiAgXHR0aGlzLnJlbmRlcigpO1xuXG4gIFx0Ly8gcmVzZXQgdGhpcy5zZWxlY3RlZFxuICBcdHRoaXMuc2VsZWN0ZWQgPSBudWxsO1xuICB9XG5cblxuICBmaW5kTmVhcmVzdE5vZGUoKSB7XG4gIFx0dmFyIG5lYXJlc3RJbmRleCA9IG51bGw7XG4gICAgLy8gc2V0IHRoaXMgdW5yZWFzb25hYmx5IGhpZ2ggc28gdGhhdCBldmVyeSBkaXN0YW5jZSB3aWxsIGJlIGxvd2VyIHRoYW4gaXQuXG4gIFx0dmFyIG5lYXJlc3REaXN0ID0gMTAwMDA7XG4gIFx0dmFyIGJlZm9yZSA9IGZhbHNlO1xuICAgIGxldCB4ID0gdGhpcy5tb3VzZS54L3RoaXMud2lkdGg7XG4gICAgbGV0IHkgPSAxLXRoaXMubW91c2UueS90aGlzLmhlaWdodDtcbiAgICBsZXQgbm9kZXMgPSB0aGlzLm5vZGVzO1xuICBcdGZvciAobGV0IGkgPSAwOyBpPG5vZGVzLmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgZGlzdGFuY2UgZnJvbSBtb3VzZSB0byB0aGlzIG5vZGUgdXNpbmcgcHl0aGFnb3JlYW4gdGhlb3JlbVxuICBcdFx0dmFyIGRpc3RhbmNlID0gTWF0aC5zcXJ0KCAgTWF0aC5wb3coIChub2Rlc1tpXS54IC0geCksIDIpICsgTWF0aC5wb3coKG5vZGVzW2ldLnkgLSB5KSwgMikgKTtcblxuICAgICAgLy8gaWYgdGhpcyBkaXN0YW5jZSBpcyBsZXNzIHRoYW4gdGhlIHByZXZpb3VzIHNob3J0ZXN0IGRpc3RhbmNlLCB1c2UgdGhpcyBpbmRleFxuICBcdFx0aWYgKGRpc3RhbmNlIDwgbmVhcmVzdERpc3QpIHtcbiAgXHRcdFx0bmVhcmVzdERpc3QgPSBkaXN0YW5jZTtcbiAgXHRcdFx0bmVhcmVzdEluZGV4ID0gaTtcbiAgXHRcdFx0YmVmb3JlID0geCA+IG5vZGVzW2ldLng7XG4gIFx0XHR9XG5cbiAgXHR9XG5cbiAgICAvLyBpZiBub3QgdmVyeSBjbG9zZSB0byBhbnkgbm9kZSwgY3JlYXRlIGEgbm9kZVxuICBcdGlmIChuZWFyZXN0RGlzdD4wLjA3KSB7XG5cbiAgICAgIG5lYXJlc3RJbmRleCA9IHRoaXMuZ2V0SW5kZXhGcm9tWCh0aGlzLm1vdXNlLngvdGhpcy53aWR0aCk7XG5cbiAgXHRcdHRoaXMubm9kZXMuc3BsaWNlKG5lYXJlc3RJbmRleCwwLCBuZXcgUG9pbnQoe1xuICBcdFx0XHR4OiB0aGlzLm1vdXNlLngvdGhpcy53aWR0aCxcbiAgXHRcdFx0eTogMS10aGlzLm1vdXNlLnkvdGhpcy5oZWlnaHRcbiAgXHRcdH0sIHRoaXMpKTtcbiAgICAgIHRoaXMuaGFzTW92ZWQgPSB0cnVlO1xuXG4gIFx0fVxuXG4gIFx0cmV0dXJuIG5lYXJlc3RJbmRleDtcbiAgfVxuXG4gIGdldEluZGV4RnJvbVgoeCkge1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgdGhpcy5ub2Rlcy5mb3JFYWNoKChub2RlLGkpID0+IHtcbiAgICAgIGlmICh0aGlzLm5vZGVzW2ldLnggPD0geCkge1xuICAgICAgICBpbmRleCA9IGkrMTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBzY2FsZU5vZGUoaSkge1xuXG4gIFx0bGV0IGNsaXBwZWRYID0gbWF0aC5jbGlwKHRoaXMubm9kZXNbaV0ueCwgMCwgMSk7XG4gIFx0bGV0IGNsaXBwZWRZID0gbWF0aC5jbGlwKHRoaXMubm9kZXNbaV0ueSwgMCwgMSk7XG5cbiAgICB0aGlzLm5vZGVzW2ldLm1vdmUoIGNsaXBwZWRYLCBjbGlwcGVkWSApO1xuXG4gIH1cblxuICAvKipcbiAgU29ydCB0aGUgdGhpcy5wb2ludHMgYXJyYXkgZnJvbSBsZWZ0LW1vc3QgcG9pbnQgdG8gcmlnaHQtbW9zdCBwb2ludC4gWW91IHNob3VsZCBub3QgcmVndWxhcmx5IG5lZWQgdG8gdXNlIHRoaXMsIGhvd2V2ZXIgaXQgbWF5IGJlIHVzZWZ1bCBpZiB0aGUgcG9pbnRzIGdldCB1bm9yZGVyZWQuXG4gICovXG4gIHNvcnRQb2ludHMoKSB7XG4gICAgdGhpcy5ub2Rlcy5zb3J0KGZ1bmN0aW9uKGEsIGIpe1xuICAgICAgcmV0dXJuIGEueCA+IGIueDtcbiAgICB9KTtcbiAgfVxuXG5cbiAgLyoqXG4gIEFkZCBhIGJyZWFrcG9pbnQgb24gdGhlIGVudmVsb3BlLlxuICBAcGFyYW0geCB7bnVtYmVyfSB4IGxvY2F0aW9uIG9mIHRoZSBwb2ludCwgbm9ybWFsaXplZCAoMC0xKVxuICBAcGFyYW0geSB7bnVtYmVyfSB5IGxvY2F0aW9uIG9mIHRoZSBwb2ludCwgbm9ybWFsaXplZCAoMC0xKVxuICAqL1xuICBhZGRQb2ludCh4LHkpIHtcbiAgICBsZXQgaW5kZXggPSB0aGlzLm5vZGVzLmxlbmd0aDtcblxuICAgIHRoaXMuc29ydFBvaW50cygpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGk8dGhpcy5ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHggPCB0aGlzLm5vZGVzW2ldLngpIHtcbiAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgXHR9XG5cbiAgICB0aGlzLm5vZGVzLnNwbGljZShpbmRleCwgMCwgbmV3IFBvaW50KHtcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5XG4gICAgfSwgdGhpcykpO1xuXG4gICAgdGhpcy5zY2FsZU5vZGUoaW5kZXgpO1xuXG4gICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5wb2ludHMpO1xuXG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIEZpbmQgdGhlIGxldmVsIGF0IGEgY2VydGFpbiB4IGxvY2F0aW9uIG9uIHRoZSBlbnZlbG9wZS5cbiAgQHBhcmFtIHgge251bWJlcn0gVGhlIHggbG9jYXRpb24gdG8gZmluZCB0aGUgbGV2ZWwgb2YsIG5vcm1hbGl6ZWQgMC0xXG4gICovXG4gIHNjYW4oeCkge1xuICAgIC8vIGZpbmQgc3Vycm91bmRpbmcgcG9pbnRzXG4gICAgbGV0IG5leHRJbmRleCA9IHRoaXMuZ2V0SW5kZXhGcm9tWCh4KTtcbiAgICBsZXQgcHJpb3JJbmRleCA9IG5leHRJbmRleC0xO1xuICAgIGlmIChwcmlvckluZGV4IDwgMCkge1xuICAgICAgcHJpb3JJbmRleCA9IDA7XG4gICAgfVxuICAgIGlmIChuZXh0SW5kZXggPj0gdGhpcy5ub2Rlcy5sZW5ndGgpIHtcbiAgICAgIG5leHRJbmRleCA9IHRoaXMubm9kZXMubGVuZ3RoLTE7XG4gICAgfVxuICAgIGxldCBwcmlvclBvaW50ID0gdGhpcy5ub2Rlc1twcmlvckluZGV4XTtcbiAgICBsZXQgbmV4dFBvaW50ID0gdGhpcy5ub2Rlc1tuZXh0SW5kZXhdO1xuICAgIGxldCBsb2MgPSBtYXRoLnNjYWxlKHgscHJpb3JQb2ludC54LCBuZXh0UG9pbnQueCwgMCwgMSk7XG4gICAgbGV0IHZhbHVlID0gbWF0aC5pbnRlcnAobG9jLHByaW9yUG9pbnQueSxuZXh0UG9pbnQueSk7XG4gICAgdGhpcy5lbWl0KCdzY2FuJyx2YWx1ZSk7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cblxuICAvKipcbiAgTW92ZSBhIGJyZWFrcG9pbnQgb24gdGhlIGVudmVsb3BlLlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBicmVha3BvaW50IHRvIG1vdmVcbiAgQHBhcmFtIHgge251bWJlcn0gTmV3IHggbG9jYXRpb24sIG5vcm1hbGl6ZWQgMC0xXG4gIEBwYXJhbSB5IHtudW1iZXJ9IE5ldyB5IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuICAqL1xuICBtb3ZlUG9pbnQoaW5kZXgseCx5KSB7XG4gICAgdGhpcy5ub2Rlc1tpbmRleF0ubW92ZSh4LHkpO1xuICAgIHRoaXMuc2NhbGVOb2RlKGluZGV4KTtcbiAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIE1vdmUgYSBicmVha3BvaW50IG9uIHRoZSBlbnZlbG9wZSBieSBhIGNlcnRhaW4gYW1vdW50LlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBicmVha3BvaW50IHRvIG1vdmVcbiAgQHBhcmFtIHhPZmZzZXQge251bWJlcn0gWCBkaXNwbGFjZW1lbnQsIG5vcm1hbGl6ZWQgMC0xXG4gIEBwYXJhbSB5T2Zmc2V0IHtudW1iZXJ9IFkgZGlzcGxhY2VtZW50LCBub3JtYWxpemVkIDAtMVxuICAqL1xuICBhZGp1c3RQb2ludChpbmRleCx4T2Zmc2V0LHlPZmZzZXQpIHtcbiAgICB0aGlzLm5vZGVzW2luZGV4XS5tb3ZlKHRoaXMubm9kZXNbaW5kZXhdLngreE9mZnNldCx0aGlzLm5vZGVzW2luZGV4XS55K3lPZmZzZXQpO1xuICAgIHRoaXMuc2NhbGVOb2RlKGluZGV4KTtcbiAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIFJlbW92ZSBhIGJyZWFrcG9pbnQgZnJvbSB0aGUgZW52ZWxvcGUuXG4gIEBwYXJhbSBpbmRleCB7bnVtYmVyfSBJbmRleCBvZiB0aGUgYnJlYWtwb2ludCB0byByZW1vdmVcbiAgKi9cbiAgZGVzdHJveVBvaW50KGluZGV4KSB7XG4gICAgdGhpcy5ub2Rlc1tpbmRleF0uZGVzdHJveSgpO1xuICAgIHRoaXMuY2FsY3VsYXRlUG9pbnRzKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMucG9pbnRzKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgUmVtb3ZlIGFsbCBleGlzdGluZyBicmVha3BvaW50cyBhbmQgYWRkIGFuIGVudGlyZWx5IG5ldyBzZXQgb2YgYnJlYWtwb2ludHMuXG4gIEBwYXJhbSBhbGxQb2ludHMge2FycmF5fSBBbiBhcnJheSBvZiBvYmplY3RzIHdpdGggeC95IHByb3BlcnRpZXMgKG5vcm1hbGl6ZWQgMC0xKS4gRWFjaCBvYmplY3QgaW4gdGhlIGFycmF5IHNwZWNpZmljZXMgdGhlIHgveSBsb2NhdGlvbiBvZiBhIG5ldyBicmVha3BvaW50IHRvIGJlIGFkZGVkLlxuICAqL1xuICBzZXRQb2ludHMoYWxsUG9pbnRzKSB7XG4gICAgd2hpbGUgKHRoaXMubm9kZXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLm5vZGVzWzBdLmRlc3Ryb3koKTtcbiAgICB9XG4gICAgYWxsUG9pbnRzLmZvckVhY2goKHBvaW50KSA9PiB7XG4gICAgICB0aGlzLmFkZFBvaW50KHBvaW50LngscG9pbnQueSk7XG4gICAgfSk7XG4gICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5wb2ludHMpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvZW52ZWxvcGUuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBkb20gPSByZXF1aXJlKCcuLi91dGlsL2RvbScpO1xuLy9sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5cbi8qKlxuKiBTcGVjdHJvZ3JhbVxuKlxuKiBAZGVzY3JpcHRpb24gQXVkaW8gc3BlY3RydW0gdmlzdWFsaXphdGlvblxuKlxuKiBAZGVtbyA8c3BhbiBuZXh1cy11aT1cInNwZWN0cm9ncmFtXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc3BlY3Ryb2dyYW0gPSBuZXcgTmV4dXMuU3BlY3Ryb2dyYW0oJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc3BlY3Ryb2dyYW0gPSBuZXcgTmV4dXMuU3BlY3Ryb2dyYW0oJyN0YXJnZXQnLHtcbiogICAnc2l6ZSc6IFszMDAsMTUwXVxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qICZuYnNwO1xuKiBObyBldmVudHNcbipcbiovXG5cbmltcG9ydCB7IGNvbnRleHQgfSBmcm9tICcuLi9tYWluJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3BlY3Ryb2dyYW0gZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3NjYWxlJywndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzMwMCwxNTBdXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgICB0aGlzLmFuYWx5c2VyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gICAgdGhpcy5hbmFseXNlci5mZnRTaXplID0gMjA0ODtcbiAgICB0aGlzLmJ1ZmZlckxlbmd0aCA9IHRoaXMuYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQ7XG4gICAgdGhpcy5kYXRhQXJyYXkgPSBuZXcgVWludDhBcnJheSh0aGlzLmJ1ZmZlckxlbmd0aCk7XG5cbiAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG5cbiAgICB0aGlzLnNvdXJjZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5jYW52YXMgPSBuZXcgZG9tLlNtYXJ0Q2FudmFzKHRoaXMucGFyZW50KTtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNhbnZhcy5lbGVtZW50O1xuICB9XG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5yZXNpemUodGhpcy53aWR0aCx0aGlzLmhlaWdodCk7XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gIH1cblxuICByZW5kZXIoKSB7XG5cbiAgICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlci5iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICB0aGlzLmFuYWx5c2VyLmdldEJ5dGVGcmVxdWVuY3lEYXRhKHRoaXMuZGF0YUFycmF5KTtcblxuICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KDAsIDAsIHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgsIHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0KTtcblxuICAgIGlmICh0aGlzLnNvdXJjZSAmJiB0aGlzLmRhdGFBcnJheSkge1xuXG4gICAgICAvL2NvbnNvbGUubG9nKHRoaXMuZGF0YUFycmF5KTtcblxuICAgICAgbGV0IGJhcldpZHRoID0gKHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGggLyB0aGlzLmJ1ZmZlckxlbmd0aCk7XG4gICAgICBsZXQgYmFySGVpZ2h0O1xuICAgICAgbGV0IHggPSAwO1xuXG4gICAgICBsZXQgZGVmaW5pdGlvbiA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgvNTA7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5idWZmZXJMZW5ndGg7IGkgPSBpK2RlZmluaXRpb24pIHtcbiAgICAgICAgYmFySGVpZ2h0ID0gTWF0aC5tYXguYXBwbHkobnVsbCwgdGhpcy5kYXRhQXJyYXkuc3ViYXJyYXkoaSxpK2RlZmluaXRpb24pKTtcbiAgICAgICAgYmFySGVpZ2h0IC89IDI1NTtcbiAgICAgICAgYmFySGVpZ2h0ICo9IHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0O1xuXG4gICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KHgsdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQtYmFySGVpZ2h0LGJhcldpZHRoKmRlZmluaXRpb24sYmFySGVpZ2h0KTtcblxuICAgICAgICB4ICs9IChiYXJXaWR0aCpkZWZpbml0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgRXF1aXZhbGVudCB0byBcInBhdGNoaW5nIGluXCIgYW4gYXVkaW8gbm9kZSB0byB2aXN1YWxpemUuIE5PVEU6IFlvdSBjYW5ub3QgY29ubmVjdCBhdWRpbyBub2RlcyBhY3Jvc3MgdHdvIGRpZmZlcmVudCBhdWRpbyBjb250ZXh0cy4gTmV4dXNVSSBydW5zIGl0cyBhdWRpbyBhbmFseXNpcyBvbiBpdHMgb3duIGF1ZGlvIGNvbnRleHQsIE5leHVzLmNvbnRleHQuIElmIHRoZSBhdWRpbyBub2RlIHlvdSBhcmUgdmlzdWFsaXppbmcgaXMgY3JlYXRlZCBvbiBhIGRpZmZlcmVudCBhdWRpbyBjb250ZXh0LCB5b3Ugd2lsbCBuZWVkIHRvIHRlbGwgTmV4dXNVSSB0byB1c2UgdGhhdCBjb250ZXh0IGluc3RlYWQ6IGkuZS4gTmV4dXMuY29udGV4dCA9IFlvdXJBdWRpb0NvbnRleHROYW1lLiBGb3IgZXhhbXBsZSwgaW4gVG9uZUpTIHByb2plY3RzLCB0aGUgbGluZSB3b3VsZCBiZTogTmV4dXMuY29udGV4dCA9IFRvbmUuY29udGV4dCAuIFdlIHJlY29tbWVuZCB0aGF0IHlvdSB3cml0ZSB0aGF0IGxpbmUgb2YgY29kZSBvbmx5IG9uY2UgYXQgdGhlIGJlZ2lubmluZyBvZiB5b3VyIHByb2plY3QuXG4gIEBwYXJhbSBub2RlIHtBdWRpb05vZGV9IFRoZSBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZVxuICBAZXhhbXBsZSBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC8vIG9yIGFub3RoZXIgYXVkaW8gY29udGV4dCB5b3UgaGF2ZSBjcmVhdGVkXG4gIHNwZWN0cm9ncmFtLmNvbm5lY3QoIFRvbmUuTWFzdGVyICk7XG4gICovXG4gIGNvbm5lY3Qobm9kZSkge1xuICAgIGlmICh0aGlzLnNvdXJjZSkge1xuICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgfVxuICAgIHRoaXMuc291cmNlID0gbm9kZTtcbiAgICB0aGlzLnNvdXJjZS5jb25uZWN0KHRoaXMuYW5hbHlzZXIpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKipcbiAgU3RvcCB2aXN1YWxpemluZyB0aGUgc291cmNlIG5vZGUgYW5kIGRpc2Nvbm5lY3QgaXQuXG4gICovXG4gIGRpc2Nvbm5lY3QoKSB7XG4gICAgdGhpcy5zb3VyY2UuZGlzY29ubmVjdCh0aGlzLmFuYWx5c2VyKTtcbiAgICB0aGlzLnNvdXJjZSA9IG51bGw7XG4gIH1cblxuICBjbGljaygpIHtcbiAgICB0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL3NwZWN0cm9ncmFtLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgZG9tID0gcmVxdWlyZSgnLi4vdXRpbC9kb20nKTtcbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcblxuXG4vKipcbiogTWV0ZXJcbipcbiogQGRlc2NyaXB0aW9uIFN0ZXJlbyBkZWNpYmVsIG1ldGVyXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwibWV0ZXJcIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBtZXRlciA9IG5ldyBOZXh1cy5NZXRlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBtZXRlciA9IG5ldyBOZXh1cy5NZXRlcignI3RhcmdldCcse1xuKiAgIHNpemU6IFs3NSw3NV1cbiogfSlcbipcbiogQG91dHB1dFxuKiAmbmJzcDtcbiogTm8gZXZlbnRzXG4qXG4qL1xuXG5pbXBvcnQgeyBjb250ZXh0IH0gZnJvbSAnLi4vbWFpbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1ldGVyIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWydzY2FsZScsJ3ZhbHVlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFszMCwxMDBdXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgICB0aGlzLmNoYW5uZWxzID0gMjtcblxuICAgIHRoaXMuc3BsaXR0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKCB0aGlzLmNoYW5uZWxzICk7XG5cbiAgICB0aGlzLmFuYWx5c2VycyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wOyBpPHRoaXMuY2hhbm5lbHM7IGkrKykge1xuICAgICAgbGV0IGFuYWx5c2VyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gICAgICB0aGlzLnNwbGl0dGVyLmNvbm5lY3QoYW5hbHlzZXIsaSk7XG4gICAgICBhbmFseXNlci5mZnRTaXplID0gMTAyNDtcbiAgICAgIGFuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IDE7XG4gICAgICB0aGlzLmFuYWx5c2Vycy5wdXNoKCBhbmFseXNlciApO1xuICAgIH1cbiAgICB0aGlzLmJ1ZmZlckxlbmd0aCA9IHRoaXMuYW5hbHlzZXJzWzBdLmZyZXF1ZW5jeUJpbkNvdW50O1xuICAgIHRoaXMuZGF0YUFycmF5ID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJ1ZmZlckxlbmd0aCk7XG5cbi8qXG4gICAgLy8gYWRkIGxpbmVhciBncmFkaWVudFxuICAgIHZhciBncmQgPSBjYW52YXNDdHguY3JlYXRlTGluZWFyR3JhZGllbnQoMCwgMCwgMCwgY2FudmFzLmhlaWdodCk7XG4gICAgLy8gbGlnaHQgYmx1ZVxuICAgIGdyZC5hZGRDb2xvclN0b3AoMCwgJyMwMDAnKTtcbiAgICBncmQuYWRkQ29sb3JTdG9wKDAuMiwgJyNiYmInKTtcbiAgICBncmQuYWRkQ29sb3JTdG9wKDAuNCwgJyNkMTgnKTtcbiAgICAvLyBkYXJrIGJsdWVcbiAgICBncmQuYWRkQ29sb3JTdG9wKDEsICcjZDE4Jyk7XG4gICAgY2FudmFzQ3R4LmZpbGxTdHlsZSA9IGdyZDsgKi9cblxuICAgIHRoaXMuYWN0aXZlID0gdHJ1ZTtcblxuICAgIHRoaXMuZGIgPSAtSW5maW5pdHk7XG5cbiAgICB0aGlzLmluaXQoKTtcblxuICAgIHRoaXMubWV0ZXJXaWR0aCA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgvdGhpcy5jaGFubmVscztcblxuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5jYW52YXMgPSBuZXcgZG9tLlNtYXJ0Q2FudmFzKHRoaXMucGFyZW50KTtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNhbnZhcy5lbGVtZW50O1xuICB9XG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5yZXNpemUodGhpcy53aWR0aCx0aGlzLmhlaWdodCk7XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gIH1cblxuICByZW5kZXIoKSB7XG5cbiAgICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlci5iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxTdHlsZSA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgdGhpcy5jYW52YXMuY29udGV4dC5maWxsUmVjdCgwLCAwLCB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoICwgdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQpO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5hbmFseXNlcnMubGVuZ3RoO2krKykge1xuXG4gICAgICBpZiAodGhpcy5zb3VyY2UpIHtcblxuICAgICAgICB0aGlzLmFuYWx5c2Vyc1tpXS5nZXRGbG9hdFRpbWVEb21haW5EYXRhKHRoaXMuZGF0YUFycmF5KTtcblxuICAgICAgICBsZXQgcm1zID0gMDtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZGF0YUFycmF5Lmxlbmd0aDsgaSsrKXtcbiAgICAgICAgICAgICBybXMgKz0gKHRoaXMuZGF0YUFycmF5W2ldICogdGhpcy5kYXRhQXJyYXlbaV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcm1zID0gTWF0aC5zcXJ0KHJtcyAvIHRoaXMuZGF0YUFycmF5Lmxlbmd0aCk7XG5cbiAgICAgICAgdGhpcy5kYiA9IDIwICogTWF0aC5sb2cxMChybXMpO1xuXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuZGIgPiAtMjAwICYmIHRoaXMuZGIgIT09IC1JbmZpbml0eSkge1xuICAgICAgICB0aGlzLmRiIC09IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRiID0gLUluZmluaXR5O1xuICAgICAgfVxuXG5cbiAgICAgIC8vY29uc29sZS5sb2coZGIpXG5cbiAgICAgIGlmICh0aGlzLmRiID4gLTcwKSB7XG5cbiAgICAgICAgbGV0IGxpbmVhciA9IG1hdGgubm9ybWFsaXplKHRoaXMuZGIsLTcwLDUpO1xuICAgICAgICBsZXQgZXhwID0gbGluZWFyICogbGluZWFyO1xuICAgICAgICBsZXQgeSA9IG1hdGguc2NhbGUoZXhwLDAsMSx0aGlzLmVsZW1lbnQuaGVpZ2h0LDApO1xuXG4gICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KHRoaXMubWV0ZXJXaWR0aCppLHksdGhpcy5tZXRlcldpZHRoLHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0IC0geSk7XG5cbiAgICAgICAgLy9jb25zb2xlLmxvZyhcInJlbmRlcmluZy4uLlwiKVxuXG4gICAgICB9XG5cbiAgICB9XG5cbiAgfVxuXG4gIC8qKlxuICBFcXVpdmFsZW50IHRvIFwicGF0Y2hpbmcgaW5cIiBhbiBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZS4gTk9URTogWW91IGNhbm5vdCBjb25uZWN0IGF1ZGlvIG5vZGVzIGFjcm9zcyB0d28gZGlmZmVyZW50IGF1ZGlvIGNvbnRleHRzLiBOZXh1c1VJIHJ1bnMgaXRzIGF1ZGlvIGFuYWx5c2lzIG9uIGl0cyBvd24gYXVkaW8gY29udGV4dCwgTmV4dXMuY29udGV4dC4gSWYgdGhlIGF1ZGlvIG5vZGUgeW91IGFyZSB2aXN1YWxpemluZyBpcyBjcmVhdGVkIG9uIGEgZGlmZmVyZW50IGF1ZGlvIGNvbnRleHQsIHlvdSB3aWxsIG5lZWQgdG8gdGVsbCBOZXh1c1VJIHRvIHVzZSB0aGF0IGNvbnRleHQgaW5zdGVhZDogaS5lLiBOZXh1cy5jb250ZXh0ID0gWW91ckF1ZGlvQ29udGV4dE5hbWUuIEZvciBleGFtcGxlLCBpbiBUb25lSlMgcHJvamVjdHMsIHRoZSBsaW5lIHdvdWxkIGJlOiBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC4gV2UgcmVjb21tZW5kIHRoYXQgeW91IHdyaXRlIHRoYXQgbGluZSBvZiBjb2RlIG9ubHkgb25jZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgcHJvamVjdC5cbiAgQHBhcmFtIG5vZGUge0F1ZGlvTm9kZX0gVGhlIGF1ZGlvIG5vZGUgdG8gdmlzdWFsaXplXG4gIEBwYXJhbSBjaGFubmVscyB7bnVtYmVyfSAob3B0aW9uYWwpIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIHNvdXJjZSBub2RlIHRvIHdhdGNoLiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgaW50ZXJmYWNlIHdpbGwgbG9vayBmb3IgYSAuY2hhbm5lbENvdW50IHByb3BlcnR5IG9uIHRoZSBpbnB1dCBub2RlLiBJZiBpdCBkb2VzIG5vdCBleGlzdCwgdGhlIGludGVyZmFjZSB3aWxsIGRlZmF1bHQgdG8gMSBjaGFubmVsLlxuICBAZXhhbXBsZSBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC8vIG9yIGFub3RoZXIgYXVkaW8gY29udGV4dCB5b3UgaGF2ZSBjcmVhdGVkXG4gIG1ldGVyLmNvbm5lY3QoIFRvbmUuTWFzdGVyLCAyICk7XG4gICovXG5cbiAgY29ubmVjdChub2RlLGNoYW5uZWxzKSB7XG4gICAgaWYgKHRoaXMuc291cmNlKSB7XG4gICAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG4gICAgLy90aGlzLmR1bW15LmRpc2Nvbm5lY3QodGhpcy5zcGxpdHRlcik7XG5cbiAgICBpZiAoY2hhbm5lbHMpIHtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVscztcbiAgICB9IGVsc2UgaWYgKG5vZGUuY2hhbm5lbENvdW50KSB7XG4gICAgICB0aGlzLmNoYW5uZWxzID0gbm9kZS5jaGFubmVsQ291bnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSAyO1xuICAgIH1cbiAgICB0aGlzLm1ldGVyV2lkdGggPSB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoL3RoaXMuY2hhbm5lbHM7XG5cbiAgICB0aGlzLnNvdXJjZSA9IG5vZGU7XG4gICAgdGhpcy5zb3VyY2UuY29ubmVjdCh0aGlzLnNwbGl0dGVyKTtcblxuICAvLyAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBTdG9wIHZpc3VhbGl6aW5nIHRoZSBzb3VyY2Ugbm9kZSBhbmQgZGlzY29ubmVjdCBpdC5cbiAgKi9cbiAgZGlzY29ubmVjdCgpIHtcblxuICAgIHRoaXMuc291cmNlLmRpc2Nvbm5lY3QodGhpcy5zcGxpdHRlcik7XG4gICAgdGhpcy5zb3VyY2UgPSBmYWxzZTtcbiAgLy8gIHRoaXMuZHVtbXkuY29ubmVjdCh0aGlzLnNwbGl0dGVyKTtcbiAgICB0aGlzLm1ldGVyV2lkdGggPSB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoL3RoaXMuY2hhbm5lbHM7XG5cbiAgfVxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBjdXN0b21EZXN0cm95KCkge1xuICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvbWV0ZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBkb20gPSByZXF1aXJlKCcuLi91dGlsL2RvbScpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5cbi8qKlxuKiBPc2NpbGxvc2NvcGVcbipcbiogQGRlc2NyaXB0aW9uIFZpc3VhbGl6ZXMgYSB3YXZlZm9ybSdzIHN0cmVhbSBvZiB2YWx1ZXMuXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwib3NjaWxsb3Njb3BlXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgb3NjaWxsb3Njb3BlID0gbmV3IE5leHVzLk9zY2lsbG9zY29wZSgnI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBvc2NpbGxvc2NvcGUgPSBuZXcgTmV4dXMuT3NjaWxsb3Njb3BlKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMzAwLDE1MF1cbiogfSlcbipcbiogQG91dHB1dFxuKiAmbmJzcDtcbiogTm8gZXZlbnRzXG4qXG4qL1xuXG5pbXBvcnQgeyBjb250ZXh0IH0gZnJvbSAnLi4vbWFpbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE9zY2lsbG9zY29wZSBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnc2NhbGUnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMzAwLDE1MF1cbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dCgpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuICAgIHRoaXMuYW5hbHlzZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgICB0aGlzLmFuYWx5c2VyLmZmdFNpemUgPSAyMDQ4O1xuICAgIHRoaXMuYnVmZmVyTGVuZ3RoID0gdGhpcy5hbmFseXNlci5mcmVxdWVuY3lCaW5Db3VudDtcbiAgICB0aGlzLmRhdGFBcnJheSA9IG5ldyBVaW50OEFycmF5KHRoaXMuYnVmZmVyTGVuZ3RoKTtcbiAgICB0aGlzLmFuYWx5c2VyLmdldEJ5dGVUaW1lRG9tYWluRGF0YSh0aGlzLmRhdGFBcnJheSk7XG5cbiAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG5cbiAgICB0aGlzLnNvdXJjZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmNhbnZhcyA9IG5ldyBkb20uU21hcnRDYW52YXModGhpcy5wYXJlbnQpO1xuICAgIHRoaXMuZWxlbWVudCA9IHRoaXMuY2FudmFzLmVsZW1lbnQ7XG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuICAgIHRoaXMuY2FudmFzLnJlc2l6ZSh0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuY2FudmFzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgfVxuXG4gIHJlbmRlcigpIHtcblxuICAgIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMucmVuZGVyLmJpbmQodGhpcykpO1xuICAgIH1cblxuICAgIHRoaXMuYW5hbHlzZXIuZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKHRoaXMuZGF0YUFycmF5KTtcblxuICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KDAsIDAsIHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgsIHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0KTtcblxuICAgIHRoaXMuY2FudmFzLmNvbnRleHQubGluZVdpZHRoID0gfn4odGhpcy5oZWlnaHQgLyAxMDAgKyAyKTtcbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LnN0cm9rZVN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuXG4gICAgdGhpcy5jYW52YXMuY29udGV4dC5iZWdpblBhdGgoKTtcblxuICAgIGlmICh0aGlzLnNvdXJjZSkge1xuXG4gICAgICB2YXIgc2xpY2VXaWR0aCA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGggKiAxLjAgLyB0aGlzLmJ1ZmZlckxlbmd0aDtcbiAgICAgIHZhciB4ID0gMDtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJ1ZmZlckxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgdmFyIHYgPSB0aGlzLmRhdGFBcnJheVtpXSAvIDEyOC4wO1xuICAgICAgICB2YXIgeSA9IHYgKiB0aGlzLmNhbnZhcy5lbGVtZW50LmhlaWdodCAvIDI7XG5cbiAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0Lm1vdmVUbyh4LCB5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmxpbmVUbyh4LCB5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHggKz0gc2xpY2VXaWR0aDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0Lm1vdmVUbygwLCB0aGlzLmNhbnZhcy5lbGVtZW50LmhlaWdodC8yKTtcbiAgICAgICAgdGhpcy5jYW52YXMuY29udGV4dC5saW5lVG8odGhpcy5jYW52YXMuZWxlbWVudC53aWR0aCwgdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQvMik7XG4gICAgfVxuXG4gICAgdGhpcy5jYW52YXMuY29udGV4dC5zdHJva2UoKTtcbiAgfVxuXG4gIC8qKlxuICBFcXVpdmFsZW50IHRvIFwicGF0Y2hpbmcgaW5cIiBhbiBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZS4gTk9URTogWW91IGNhbm5vdCBjb25uZWN0IGF1ZGlvIG5vZGVzIGFjcm9zcyB0d28gZGlmZmVyZW50IGF1ZGlvIGNvbnRleHRzLiBOZXh1c1VJIHJ1bnMgaXRzIGF1ZGlvIGFuYWx5c2lzIG9uIGl0cyBvd24gYXVkaW8gY29udGV4dCwgTmV4dXMuY29udGV4dC4gSWYgdGhlIGF1ZGlvIG5vZGUgeW91IGFyZSB2aXN1YWxpemluZyBpcyBjcmVhdGVkIG9uIGEgZGlmZmVyZW50IGF1ZGlvIGNvbnRleHQsIHlvdSB3aWxsIG5lZWQgdG8gdGVsbCBOZXh1c1VJIHRvIHVzZSB0aGF0IGNvbnRleHQgaW5zdGVhZDogaS5lLiBOZXh1cy5jb250ZXh0ID0gWW91ckF1ZGlvQ29udGV4dE5hbWUuIEZvciBleGFtcGxlLCBpbiBUb25lSlMgcHJvamVjdHMsIHRoZSBsaW5lIHdvdWxkIGJlOiBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC4gV2UgcmVjb21tZW5kIHRoYXQgeW91IHdyaXRlIHRoYXQgbGluZSBvZiBjb2RlIG9ubHkgb25jZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgcHJvamVjdC5cbiAgQHBhcmFtIG5vZGUge0F1ZGlvTm9kZX0gVGhlIGF1ZGlvIG5vZGUgdG8gdmlzdWFsaXplXG4gIEBleGFtcGxlIE5leHVzLmNvbnRleHQgPSBUb25lLmNvbnRleHQgLy8gb3IgYW5vdGhlciBhdWRpbyBjb250ZXh0IHlvdSBoYXZlIGNyZWF0ZWRcbiAgb3NjaWxsb3Njb3BlLmNvbm5lY3QoIFRvbmUuTWFzdGVyICk7XG4gICovXG5cbiAgY29ubmVjdChub2RlKSB7XG5cbiAgICBpZiAodGhpcy5zb3VyY2UpIHtcbiAgICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIH1cblxuICAgIHRoaXMuc291cmNlID0gbm9kZTtcbiAgICB0aGlzLnNvdXJjZS5jb25uZWN0KHRoaXMuYW5hbHlzZXIpO1xuXG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBTdG9wIHZpc3VhbGl6aW5nIHRoZSBzb3VyY2Ugbm9kZSBhbmQgZGlzY29ubmVjdCBpdC5cbiAgKi9cbiAgZGlzY29ubmVjdCgpIHtcbiAgICBpZiAodGhpcy5zb3VyY2UpIHtcbiAgICAgIHRoaXMuc291cmNlLmRpc2Nvbm5lY3QodGhpcy5hbmFseXNlcik7XG4gICAgICB0aGlzLnNvdXJjZSA9IG51bGw7XG4gICAgfVxuXG4gIH1cblxuICBjbGljaygpIHtcbiAgICB0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL29zY2lsbG9zY29wZS5qcyIsIi8qXG5NYWluIGNvbmNlcHQ6XG5zeW50aCA9IG5ldyBOZXh1cy5SYWNrKCdlbGVtZW50SUQnKTtcblxuVHJhbnNmb3JtIGFsbCBlbGVtZW50cyBpbnNpZGUgdGhlIGRpdlxuc3ludGguZWxlbWVudElEIHdpbGwgaG9sZCB0aGUgZmlyc3Qgc2xpZGVyIGludGVyZmFjZVxuXG4yKSBJbiBmdXR1cmUsIHBvdGVudGlhbGx5IHdyaXRpbmcgYSByYWNrIHRoYXQgaXMgcmUtdXNhYmxlP1xuQ291bGQgYWxzbyB0YWtlIEpTT05cblxubmV3IE5leHVzLlJhY2soJyN0YXJnZXQnLHtcbiAgcHJlOiAoKSA9PiB7XG4gICAgY3JlYXRlIHNvbWUgZGl2cyBoZXJlLCBvciBzb21lIGF1ZGlvIGNvZGVcbiAgfSxcbiAgaW50ZXJmYWNlOiB7XG4gICAgc2xpZGVyMTogTmV4dXMuYWRkLnNsaWRlcih7XG4gICAgICB0b3A6MTAsXG4gICAgICBsZWZ0OjEwLFxuICAgICAgd2lkdGg6NTAsXG4gICAgICBoZWlnaHQ6MTAwLFxuICAgICAgbWluOiAwLFxuICAgICAgbWF4OiAxMDAsXG4gICAgICBzdGVwOiAxXG4gICAgfSksXG4gICAgd2F2ZTE6IE5leHVzLmFkZC53YXZlZm9ybSh7XG4gICAgICBmaWxlOiAnLi9wYXRoL3RvL2ZpbGUubXAzJyxcbiAgICAgIHdpZHRoOjUwMCxcbiAgICAgIGhlaWdodDoxMDAsXG4gICAgICBtb2RlOiAncmFuZ2UnXG4gICAgfSlcbiAgfSxcbiAgaW5pdDogKCkgPT4ge1xuICAgIC8vIHNvbWUgYXVkaW8gaW5pdCBjb2RlIGdvZXMgaGVyZS4uLlxuICB9XG59KTtcblxuKi9cblxuaW1wb3J0ICogYXMgdHJhbnNmb3JtIGZyb20gJy4uL3V0aWwvdHJhbnNmb3JtJztcbmltcG9ydCBkb20gZnJvbSAnLi4vdXRpbC9kb20nO1xuXG5pbXBvcnQgeyBjb2xvcnMgfSBmcm9tICcuLi9tYWluJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmFjayB7XG5cbiAgY29uc3RydWN0b3IodGFyZ2V0LCBzZXR0aW5ncykge1xuXG4gICAgdGhpcy5tZXRhID0ge307XG4gICAgdGhpcy5tZXRhLnRhcmdldCA9IHRhcmdldDtcbiAgICB0aGlzLm1ldGEucGFyZW50ID0gZG9tLnBhcnNlRWxlbWVudCh0YXJnZXQpOyAvLyBzaG91bGQgYmUgYSBnZW5lcmljIGZ1bmN0aW9uIGZvciBwYXJzaW5nIGEgJ3RhcmdldCcgYXJndW1lbnQgdGhhdCBjaGVja3MgZm9yIHN0cmluZy9ET00valFVRVJZXG4gICAgdGhpcy5tZXRhLmNvbG9ycyA9IHt9O1xuXG4gICAgaWYgKHNldHRpbmdzKSB7XG4gICAgICB0aGlzLm1ldGEuYXR0cmlidXRlID0gc2V0dGluZ3MuYXR0cmlidXRlIHx8ICduZXh1cy11aSc7XG4gICAgICB0aGlzLm1ldGEudGl0bGUgPSBzZXR0aW5ncy5uYW1lIHx8IGZhbHNlO1xuICAgICAgdGhpcy5tZXRhLm9wZW4gPSBzZXR0aW5ncy5vcGVuIHx8IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1ldGEuYXR0cmlidXRlID0gJ25leHVzLXVpJztcbiAgICAgIHRoaXMubWV0YS50aXRsZSA9IGZhbHNlO1xuICAgICAgdGhpcy5tZXRhLm9wZW4gPSBmYWxzZTtcbiAgICB9XG5cbiAgICBsZXQgZGVmYXVsdENvbG9ycyA9IGNvbG9ycygpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgICB0aGlzLm1ldGEuY29sb3JzLmFjY2VudCA9IGRlZmF1bHRDb2xvcnMuYWNjZW50O1xuICAgIHRoaXMubWV0YS5jb2xvcnMuZmlsbCA9IGRlZmF1bHRDb2xvcnMuZmlsbDtcbiAgICB0aGlzLm1ldGEuY29sb3JzLmxpZ2h0ID0gZGVmYXVsdENvbG9ycy5saWdodDtcbiAgICB0aGlzLm1ldGEuY29sb3JzLmRhcmsgPSBkZWZhdWx0Q29sb3JzLmRhcms7XG4gICAgdGhpcy5tZXRhLmNvbG9ycy5tZWRpdW1MaWdodCA9IGRlZmF1bHRDb2xvcnMubWVkaXVtTGlnaHQ7XG4gICAgdGhpcy5tZXRhLmNvbG9ycy5tZWRpdW1EYXJrID0gZGVmYXVsdENvbG9ycy5tZWRpdW1EYXJrO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgICB0aGlzLmNvbG9ySW50ZXJmYWNlKCk7XG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcbiAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLmJveFNpemluZyA9ICdib3JkZXItYm94JztcbiAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLnVzZXJTZWxlY3QgPSAnbm9uZSc7XG4gICAgdGhpcy5tZXRhLnBhcmVudC5zdHlsZS5tb3pVc2VyU2VsZWN0ID0gJ25vbmUnO1xuICAgIHRoaXMubWV0YS5wYXJlbnQuc3R5bGUud2Via2l0VXNlclNlbGVjdCA9ICdub25lJztcblxuICAgIHRoaXMubWV0YS5jb250ZW50cyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG4gICAgd2hpbGUgKHRoaXMubWV0YS5wYXJlbnQuY2hpbGROb2Rlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMubWV0YS5jb250ZW50cy5hcHBlbmRDaGlsZCh0aGlzLm1ldGEucGFyZW50LmNoaWxkTm9kZXNbMF0pO1xuICAgIH1cblxuICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5wYWRkaW5nID0gJzBweCc7XG4gICAgdGhpcy5tZXRhLmNvbnRlbnRzLnN0eWxlLmJveFNpemluZyA9ICdib3JkZXItYm94JztcblxuICAgIGlmICh0aGlzLm1ldGEudGl0bGUpIHtcbiAgICAgIHRoaXMubWV0YS50aXRsZUJhciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLmlubmVySFRNTCA9IHRoaXMubWV0YS50aXRsZTtcbiAgICAgIHRoaXMubWV0YS50aXRsZUJhci5zdHlsZS5mb250RmFtaWx5ID0gJ2FyaWFsJztcbiAgICAgIHRoaXMubWV0YS50aXRsZUJhci5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgICB0aGlzLm1ldGEudGl0bGVCYXIuc3R5bGUuY29sb3IgPSAnIzg4OCc7XG4gICAgICB0aGlzLm1ldGEudGl0bGVCYXIuc3R5bGUucGFkZGluZyA9ICc3cHgnO1xuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLnN0eWxlLmZvbnRTaXplID0gJzEycHgnO1xuXG4gICAgICB0aGlzLm1ldGEuYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUudG9wID0gJzVweCcgO1xuICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5yaWdodCA9ICc1cHgnIDtcbiAgICAgIHRoaXMubWV0YS5idXR0b24uaW5uZXJIVE1MID0gJy0nO1xuICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5wYWRkaW5nID0gJzBweCA1cHggMnB4JztcbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUubGluZUhlaWdodCA9ICcxMnB4JztcbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUuZm9udFNpemUgPSAnMTVweCc7XG5cbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInO1xuXG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3ZlcicsICgpID0+IHtcbiAgICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLm1lZGl1bURhcms7XG4gICAgICB9KTtcbiAgICAgIHRoaXMubWV0YS5idXR0b24uYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLm1lZGl1bUxpZ2h0O1xuICAgICAgfSk7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tZXRhLm9wZW4pIHtcbiAgICAgICAgICB0aGlzLmhpZGUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNob3coKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cblxuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLmFwcGVuZENoaWxkKHRoaXMubWV0YS5idXR0b24pO1xuXG4gICAgICB0aGlzLm1ldGEucGFyZW50LmFwcGVuZENoaWxkKHRoaXMubWV0YS50aXRsZUJhcik7XG4gICAgfVxuICAgIHRoaXMubWV0YS5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5tZXRhLmNvbnRlbnRzKTtcblxuICAvLyAgdmFyIHdpZHRoID0gdGhpcy5tZXRhLnBhcmVudC5zdHlsZS53aWR0aCA9IGdldENvbXB1dGVkU3R5bGUodGhpcy5tZXRhLnBhcmVudCkuZ2V0UHJvcGVydHlWYWx1ZSgnd2lkdGgnKTtcbi8vICAgIHRoaXMubWV0YS5wYXJlbnQuc3R5bGUud2lkdGggPSB3aWR0aDtcblxuICAgIGxldCB1aSA9IHRyYW5zZm9ybS5zZWN0aW9uKHRoaXMubWV0YS50YXJnZXQsIHRoaXMubWV0YS5hdHRyaWJ1dGUpO1xuICAgIGZvciAodmFyIGtleSBpbiB1aSkge1xuICAgICAgdGhpc1trZXldID0gdWlba2V5XTtcbiAgICB9XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICBpZiAodGhpcy5tZXRhLnRpdGxlKSB7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMubWV0YS5jb2xvcnMubWVkaXVtTGlnaHQ7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLmJvcmRlciA9ICdzb2xpZCAwcHggJyt0aGlzLm1ldGEuY29sb3JzLmZpbGw7XG4gICAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLmJvcmRlciA9ICdzb2xpZCAxcHggJyt0aGlzLm1ldGEuY29sb3JzLm1lZGl1bUxpZ2h0O1xuICAgICAgdGhpcy5tZXRhLnBhcmVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLmxpZ2h0O1xuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMubWV0YS5jb2xvcnMuZmlsbDtcbiAgICB9XG4gIH1cblxuICBzaG93KCkge1xuICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICB0aGlzLm1ldGEub3BlbiA9IHRydWU7XG4gIH1cblxuICBoaWRlKCkge1xuICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHRoaXMubWV0YS5vcGVuID0gZmFsc2U7XG4gIH1cblxuICBjb2xvcml6ZSh0eXBlLGNvbG9yKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMpIHtcbiAgICAgIGlmICh0aGlzW2tleV0uY29sb3JpemUpIHtcbiAgICAgICAgdGhpc1trZXldLmNvbG9yaXplKHR5cGUsY29sb3IpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLm1ldGEuY29sb3JzW3R5cGVdID0gY29sb3I7XG4gICAgdGhpcy5jb2xvckludGVyZmFjZSgpO1xuICB9XG5cbiAgZW1wdHkoKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMpIHtcbiAgICAgIGlmICh0aGlzW2tleV0uZGVzdHJveSkge1xuICAgICAgICB0aGlzW2tleV0uZGVzdHJveSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvY29yZS9yYWNrLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgZG9tIGZyb20gJy4uL3V0aWwvZG9tJztcbmltcG9ydCBJbnRlcmZhY2VzIGZyb20gJy4uL2ludGVyZmFjZXMvJztcblxubGV0IGNyZWF0ZUludGVyZmFjZUlEID0gKHdpZGdldCxpbnRlcmZhY2VJRHMpID0+IHtcbiAgbGV0IHR5cGUgPSB3aWRnZXQudHlwZTtcbiAgaWYgKGludGVyZmFjZUlEc1t0eXBlXSkge1xuICAgIGludGVyZmFjZUlEc1t0eXBlXSsrO1xuICB9IGVsc2Uge1xuICAgIGludGVyZmFjZUlEc1t0eXBlXSA9IDE7XG4gIH1cbiAgcmV0dXJuICggdHlwZSArIGludGVyZmFjZUlEc1t0eXBlXSApO1xufTtcblxubGV0IGVsZW1lbnQgPSAoZWxlbWVudCx0eXBlLG9wdGlvbnMpID0+IHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudC5hdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKXtcbiAgICBsZXQgYXR0ID0gZWxlbWVudC5hdHRyaWJ1dGVzW2ldO1xuICAvLyAgdHJ5IHtcbiAgLy8gICAgb3B0aW9uc1thdHQubm9kZU5hbWVdID0gZXZhbChhdHQubm9kZVZhbHVlKTtcbiAgLy8gIH0gY2F0Y2goZSkge1xuICAgICAgb3B0aW9uc1thdHQubm9kZU5hbWVdID0gYXR0Lm5vZGVWYWx1ZTtcbiAgLy8gIH1cbiAgfVxuICB0eXBlID0gdHlwZVswXS50b1VwcGVyQ2FzZSgpICsgdHlwZS5zbGljZSgxKTtcbiAgbGV0IHdpZGdldCA9IG5ldyBJbnRlcmZhY2VzW3R5cGVdKGVsZW1lbnQsb3B0aW9ucyk7XG4gIHdpZGdldC5pZCA9IGVsZW1lbnQuaWQ7XG4gIHJldHVybiB3aWRnZXQ7XG59O1xuXG5cbmxldCBzZWN0aW9uID0gKHBhcmVudCxrZXl3b3JkKSA9PiB7XG5cbiAga2V5d29yZCA9IGtleXdvcmQgfHwgJ25leHVzLXVpJztcblxuICBsZXQgaW50ZXJmYWNlSURzID0ge307XG5cbiAgbGV0IGNvbnRhaW5lciA9IGRvbS5wYXJzZUVsZW1lbnQocGFyZW50KTtcblxuICBsZXQgdWkgPSB7fTtcblxuICBsZXQgaHRtbEVsZW1lbnRzID0gY29udGFpbmVyLmdldEVsZW1lbnRzQnlUYWdOYW1lKCcqJyk7XG4gIGxldCBlbGVtZW50cyA9IFtdO1xuICBmb3IgKGxldCBpPTA7IGk8aHRtbEVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgZWxlbWVudHMucHVzaChodG1sRWxlbWVudHNbaV0pO1xuICB9XG4gIGZvciAobGV0IGk9MDtpPGVsZW1lbnRzLmxlbmd0aDtpKyspIHtcbiAgICBsZXQgdHlwZSA9IGVsZW1lbnRzW2ldLmdldEF0dHJpYnV0ZShrZXl3b3JkKTtcbiAgICBpZiAodHlwZSkge1xuICAgICAgbGV0IGZvcm1hdHRlZFR5cGUgPSBmYWxzZTtcbiAgICAgIGZvciAobGV0IGtleSBpbiBJbnRlcmZhY2VzKSB7XG4gICAgICAgIGlmICh0eXBlLnRvTG93ZXJDYXNlKCk9PT1rZXkudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgIGZvcm1hdHRlZFR5cGUgPSBrZXk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnNvbGUubG9nKGZvcm1hdHRlZFR5cGUpO1xuICAgICAgbGV0IHdpZGdldCA9IGVsZW1lbnQoZWxlbWVudHNbaV0sZm9ybWF0dGVkVHlwZSk7XG4gICAgICBpZiAod2lkZ2V0LmlkKSB7XG4gICAgICAgIHVpW3dpZGdldC5pZF0gPSB3aWRnZXQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgaWQgPSBjcmVhdGVJbnRlcmZhY2VJRCh3aWRnZXQsaW50ZXJmYWNlSURzKTtcbiAgICAgICAgdWlbaWRdID0gd2lkZ2V0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1aTtcblxufTtcblxubGV0IGFkZCA9ICh0eXBlLHBhcmVudCxvcHRpb25zKSA9PiB7XG4gIGxldCB0YXJnZXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGlmIChwYXJlbnQpIHtcbiAgICBwYXJlbnQgPSBkb20ucGFyc2VFbGVtZW50KHBhcmVudCk7XG4gIH0gZWxzZSB7XG4gICAgcGFyZW50ID0gZG9jdW1lbnQuYm9keTtcbiAgfVxuICBwYXJlbnQuYXBwZW5kQ2hpbGQodGFyZ2V0KTtcbiAgb3B0aW9ucy50YXJnZXQgPSB0YXJnZXQ7XG4gIGlmIChvcHRpb25zLnNpemUpIHtcbiAgICB0YXJnZXQuc3R5bGUud2lkdGggPSBvcHRpb25zLnNpemVbMF0gKyAncHgnO1xuICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSBvcHRpb25zLnNpemVbMV0gKyAncHgnO1xuICB9XG4gIHJldHVybiBlbGVtZW50KHRhcmdldCx0eXBlLG9wdGlvbnMpO1xufTtcblxuZXhwb3J0IHsgZWxlbWVudCB9O1xuZXhwb3J0IHsgc2VjdGlvbiB9O1xuZXhwb3J0IHsgYWRkIH07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvdXRpbC90cmFuc2Zvcm0uanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFR1bmUge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gIFx0Ly8gdGhlIHNjYWxlIGFzIHJhdGlvc1xuICBcdHRoaXMuc2NhbGUgPSBbXTtcblxuICBcdC8vIGkvbyBtb2Rlc1xuICBcdHRoaXMubW9kZSA9IHtcbiAgXHRcdG91dHB1dDogJ2ZyZXF1ZW5jeScsXG4gIFx0XHRpbnB1dDogJ3N0ZXAnXG4gIFx0fTtcblxuICBcdC8vIEVUIG1ham9yXG4gIFx0dGhpcy5ldG1ham9yID0gWyAyNjEuNjI1NTgsXG4gIFx0XHQyOTMuNjY0NzY0LFxuICBcdFx0MzI5LjYyNzU2MyxcbiAgXHRcdDM0OS4yMjgyNDEsXG4gIFx0XHQzOTEuOTk1NDIyLFxuICBcdFx0NDQwLFxuICBcdFx0NDkzLjg4MzMwMSxcbiAgXHRcdDUyMy4yNTExNlxuICBcdF07XG5cbiAgXHQvLyBSb290IGZyZXF1ZW5jeS5cbiAgXHR0aGlzLnJvb3QgPSBtYXRoLm10b2YoNjApOyAgICAgLy8gKiBNYXRoLnBvdygyLCg2MC02OSkvMTIpO1xuXG4gICAgLy8gZGVmYXVsdCBpcyBhIG1ham9yIHNjYWxlXG4gICAgdGhpcy5jcmVhdGVTY2FsZSgwLDIsNCw1LDcsOSwxMSk7XG5cbiAgfVxuXG4gIC8qIFJldHVybiBkYXRhIGluIHRoZSBtb2RlIHlvdSBhcmUgaW4gKGZyZXEsIHJhdGlvLCBvciBtaWRpKSAqL1xuICBub3RlKGlucHV0LG9jdGF2ZSkge1xuXG4gIFx0bGV0IG5ld3ZhbHVlO1xuXG4gIFx0aWYgKHRoaXMubW9kZS5vdXRwdXQgPT09ICdmcmVxdWVuY3knKSB7XG4gIFx0XHRuZXd2YWx1ZSA9IHRoaXMuZnJlcXVlbmN5KGlucHV0LG9jdGF2ZSk7XG4gIFx0fSBlbHNlIGlmICh0aGlzLm1vZGUub3V0cHV0ID09PSAncmF0aW8nKSB7XG4gIFx0XHRuZXd2YWx1ZSA9IHRoaXMucmF0aW8oaW5wdXQsb2N0YXZlKTtcbiAgXHR9IGVsc2UgaWYgKHRoaXMubW9kZS5vdXRwdXQgPT09ICdNSURJJykge1xuICBcdFx0bmV3dmFsdWUgPSB0aGlzLk1JREkoaW5wdXQsb2N0YXZlKTtcbiAgXHR9IGVsc2Uge1xuICBcdFx0bmV3dmFsdWUgPSB0aGlzLmZyZXF1ZW5jeShpbnB1dCxvY3RhdmUpO1xuICBcdH1cblxuICBcdHJldHVybiBuZXd2YWx1ZTtcblxuICB9XG5cblxuICAvKiBSZXR1cm4gZnJlcSBkYXRhICovXG4gIGZyZXF1ZW5jeShzdGVwSW4sIG9jdGF2ZUluKSB7XG5cbiAgXHRpZiAodGhpcy5tb2RlLmlucHV0ID09PSAnbWlkaScgfHwgdGhpcy5tb2RlLmlucHV0ID09PSAnTUlESScgKSB7XG4gIFx0XHR0aGlzLnN0ZXBJbiArPSA2MDtcbiAgXHR9XG5cbiAgXHQvLyB3aGF0IG9jdGF2ZSBpcyBvdXIgaW5wdXRcbiAgXHRsZXQgb2N0YXZlID0gTWF0aC5mbG9vcihzdGVwSW4vdGhpcy5zY2FsZS5sZW5ndGgpO1xuXG4gIFx0aWYgKG9jdGF2ZUluKSB7XG4gIFx0XHRvY3RhdmUgKz0gb2N0YXZlSW47XG4gIFx0fVxuXG4gIFx0Ly8gd2hpY2ggc2NhbGUgZGVncmVlICgwIC0gc2NhbGUgbGVuZ3RoKSBpcyBvdXIgaW5wdXRcbiAgXHRsZXQgc2NhbGVEZWdyZWUgPSBzdGVwSW4gJSB0aGlzLnNjYWxlLmxlbmd0aDtcblxuICBcdHdoaWxlIChzY2FsZURlZ3JlZSA8IDApIHtcbiAgXHRcdHNjYWxlRGVncmVlICs9IHRoaXMuc2NhbGUubGVuZ3RoO1xuICBcdH1cblxuICAgIGxldCByYXRpbyA9IHRoaXMuc2NhbGVbc2NhbGVEZWdyZWVdO1xuXG4gIFx0bGV0IGZyZXEgPSB0aGlzLnJvb3QgKiByYXRpbztcblxuICBcdGZyZXEgPSBmcmVxKihNYXRoLnBvdygyLG9jdGF2ZSkpO1xuXG4gIFx0Ly8gdHJ1bmNhdGUgaXJyYXRpb25hbCBudW1iZXJzXG4gIFx0ZnJlcSA9IE1hdGguZmxvb3IoZnJlcSoxMDAwMDAwMDAwMDApLzEwMDAwMDAwMDAwMDtcblxuICBcdHJldHVybiBmcmVxO1xuXG4gIH1cblxuICAvKiBGb3JjZSByZXR1cm4gcmF0aW8gZGF0YSAqL1xuXG4gIHJhdGlvKHN0ZXBJbiwgb2N0YXZlSW4pIHtcblxuICBcdGlmICh0aGlzLm1vZGUuaW5wdXQgPT09ICdtaWRpJyB8fCB0aGlzLm1vZGUuaW5wdXQgPT09ICdNSURJJyApIHtcbiAgXHRcdHRoaXMuc3RlcEluICs9IDYwO1xuICBcdH1cblxuICBcdC8vIHdoYXQgb2N0YXZlIGlzIG91ciBpbnB1dFxuICBcdGxldCBvY3RhdmUgPSBNYXRoLmZsb29yKHN0ZXBJbi90aGlzLnNjYWxlLmxlbmd0aCk7XG5cbiAgXHRpZiAob2N0YXZlSW4pIHtcbiAgXHRcdG9jdGF2ZSArPSBvY3RhdmVJbjtcbiAgXHR9XG5cbiAgXHQvLyB3aGljaCBzY2FsZSBkZWdyZWUgKDAgLSBzY2FsZSBsZW5ndGgpIGlzIG91ciBpbnB1dFxuICBcdGxldCBzY2FsZURlZ3JlZSA9IHN0ZXBJbiAlIHRoaXMuc2NhbGUubGVuZ3RoO1xuXG4gIFx0Ly8gd2hhdCByYXRpbyBpcyBvdXIgaW5wdXQgdG8gb3VyIGtleVxuICBcdGxldCByYXRpbyA9IE1hdGgucG93KDIsb2N0YXZlKSp0aGlzLnNjYWxlW3NjYWxlRGVncmVlXTtcblxuICBcdHJhdGlvID0gTWF0aC5mbG9vcihyYXRpbyoxMDAwMDAwMDAwMDApLzEwMDAwMDAwMDAwMDtcblxuICBcdHJldHVybiByYXRpbztcblxuICB9XG5cbiAgLyogRm9yY2UgcmV0dXJuIGFkanVzdGVkIE1JREkgZGF0YSAqL1xuXG4gIE1JREkoc3RlcEluLG9jdGF2ZUluKSB7XG5cbiAgXHRsZXQgbmV3dmFsdWUgPSB0aGlzLmZyZXF1ZW5jeShzdGVwSW4sb2N0YXZlSW4pO1xuXG4gIFx0bGV0IG4gPSA2OSArIDEyKk1hdGgubG9nKG5ld3ZhbHVlLzQ0MCkvTWF0aC5sb2coMik7XG5cbiAgXHRuID0gTWF0aC5mbG9vcihuKjEwMDAwMDAwMDApLzEwMDAwMDAwMDA7XG5cbiAgXHRyZXR1cm4gbjtcblxuICB9XG5cbiAgY3JlYXRlU2NhbGUoKSB7XG4gICAgbGV0IG5ld1NjYWxlID0gW107XG4gICAgZm9yIChsZXQgaT0wO2k8YXJndW1lbnRzLmxlbmd0aDtpKyspIHtcbiAgICAgIG5ld1NjYWxlLnB1c2goIG1hdGgubXRvZiggNjAgKyBhcmd1bWVudHNbaV0gKSApO1xuICAgIH1cbiAgICB0aGlzLmxvYWRTY2FsZUZyb21GcmVxdWVuY2llcyhuZXdTY2FsZSk7XG4gIH1cblxuICBjcmVhdGVKSVNjYWxlKCkge1xuICAgIHRoaXMuc2NhbGUgPSBbXTtcbiAgICBmb3IgKGxldCBpPTA7aTxhcmd1bWVudHMubGVuZ3RoO2krKykge1xuICAgICAgdGhpcy5zY2FsZS5wdXNoKGFyZ3VtZW50c1tpXSk7XG4gICAgfVxuICB9XG5cbiAgbG9hZFNjYWxlRnJvbUZyZXF1ZW5jaWVzKGZyZXFzKSB7XG4gICAgdGhpcy5zY2FsZSA9IFtdO1xuICAgIGZvciAobGV0IGk9MDtpPGZyZXFzLmxlbmd0aC0xO2krKykge1xuICAgICAgdGhpcy5zY2FsZS5wdXNoKGZyZXFzW2ldL2ZyZXFzWzBdKTtcbiAgICB9XG4gIH1cblxuICAvKiBMb2FkIGEgbmV3IHNjYWxlICovXG5cbiAgbG9hZFNjYWxlKG5hbWUpe1xuXG4gIFx0LyogbG9hZCB0aGUgc2NhbGUgKi9cbiAgXHRsZXQgZnJlcXMgPSB0aGlzLnNjYWxlc1tuYW1lXS5mcmVxdWVuY2llcztcbiAgICB0aGlzLmxvYWRTY2FsZUZyb21GcmVxdWVuY2llcyhmcmVxcyk7XG5cbiAgfVxuXG4gIC8qIFNlYXJjaCB0aGUgbmFtZXMgb2YgdHVuaW5nc1xuICBcdCBSZXR1cm5zIGFuIGFycmF5IG9mIG5hbWVzIG9mIHR1bmluZ3MgKi9cblxuICBzZWFyY2gobGV0dGVycykge1xuICBcdGxldCBwb3NzaWJsZSA9IFtdO1xuICBcdGZvciAobGV0IGtleSBpbiB0aGlzLnNjYWxlcykge1xuICBcdFx0aWYgKGtleS50b0xvd2VyQ2FzZSgpLmluZGV4T2YobGV0dGVycy50b0xvd2VyQ2FzZSgpKSAhPT0gLTEpIHtcbiAgXHRcdFx0cG9zc2libGUucHVzaChrZXkpO1xuICBcdFx0fVxuICBcdH1cbiAgXHRyZXR1cm4gcG9zc2libGU7XG4gIH1cblxuICAvKiBSZXR1cm4gYSBjb2xsZWN0aW9uIG9mIG5vdGVzIGFzIGFuIGFycmF5ICovXG5cbiAgY2hvcmQobWlkaXMpIHtcbiAgXHRsZXQgb3V0cHV0ID0gW107XG4gIFx0Zm9yIChsZXQgaT0wO2k8bWlkaXMubGVuZ3RoO2krKykge1xuICBcdFx0b3V0cHV0LnB1c2godGhpcy5ub3RlKG1pZGlzW2ldKSk7XG4gIFx0fVxuICBcdHJldHVybiBvdXRwdXQ7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3R1bmluZy90dW5pbmcuanMiLCIndXNlIHN0cmljdCc7XG5cbi8vRGlzYWJsZSBqc2hpbnQgd2FybmluZyBjb25jZXJuaW5nIHRyYWlsaW5nIHJlZ3VsYXIgcGFyYW1zXG4vKmpzaGludCAtVzEzOCAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSYWRpbyB7XG4gICAgLy9pZiBub24tZXhpc3RlbnQgYnV0dG9ucyBhcmUgc3dpdGNoZWQsIHRoZXkgYXJlIGlnbm9yZWRcblxuICAgIGNvbnN0cnVjdG9yKGxlbmd0aCA9IDMsIC4uLm9uVmFscykge1xuICAgICAgICAvL2VhY2ggb3B0aW9uYWwgJ29uVmFscycgYXJndW1lbnQgc3dpdGNoZXMgb24gdGhhdCB2YWx1ZSBpbiB0aGUgUmFkaW8gaWYgaXQgZXhpc3RzXG4gICAgICAgIC8vSW4gdGhlIGV4YW1wbGUgYmVsb3csIGEgMy1idXR0b24gcmFkaW8gaXMgY3JlYXRlZCwgaW5kZXggMCBpcyBzd2l0Y2hlZCBvbiwgaW5kZXggMSBpcyBzd2l0Y2hlZCBvbiB0aGVuIHRoZW4gYXR0ZW1wdGVkIGFnYWluIHByb2R1Y2luZyBhbiB3YXJuaW5nLCBhbmQgdGhlIGZpbmFsIGFyZ3VtZW50IHByb2R1Y2VzIGEgd2FybmluZyBiZWNhdXNlIHRoZSBpbmRleCB2YWx1ZSBkb2VzIG5vdCBleGlzdC5cbiAgICAgICAgLy9FeGFtcGxlOlxuICAgICAgICAvL2AgIHJhZGlvID0gbmV3IFJhZGlvKDMsIDAsIDEsIDEsIDMpO1xuICAgICAgICAvL+KApiAgWzEsMSwwXVxuXG4gICAgICAgIGlmIChsZW5ndGggPCAwKSB7IGxlbmd0aCA9IDE7IH1cblxuICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcbiAgICAgICAgdGhpcy5vblZhbHMgPSBvblZhbHM7XG4gICAgICAgIHRoaXMuYXJyYXkgPSBuZXcgQXJyYXkobGVuZ3RoKS5maWxsKDApO1xuXG4gICAgICAgIGlmIChvblZhbHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5vbiguLi5vblZhbHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2VsZWN0KHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYXJyYXkuZmlsbCgwKTtcbiAgICAgICAgdGhpcy5hcnJheVt2YWx1ZV0gPSAxO1xuICAgICAgICByZXR1cm4gdGhpcy5hcnJheTtcbiAgICB9XG5cbiAgICBmbGlwKC4uLnZhbHVlcykge1xuICAgICAgICAvL2ZsaXBzIHRoZSBzcGVjaWZpZWQgdmFsdWVzLiBpZiBubyB2YWx1ZSBpcyBzcGVjaWZpZWQsIGZsaXBzIGFsbCBidXR0b25zXG4gICAgICAgIGxldCBhID0gdGhpcy5hcnJheTtcbiAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB2YWx1ZXMuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgICAgICAgICAgaWYgKHYgPiBhLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdXYXJuaW5nOiBBbm9uUmFkaW9bJyArIHYgKyAnXSBkb2VzIG5vdCBleGlzdCcpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFbdl0gPSAoYVt2XSA/IDAgOiAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGEuZm9yRWFjaChmdW5jdGlvbih2LCBpLCBhcnIpIHtcbiAgICAgICAgICAgICAgICBhcnJbaV0gPSAodiA/IDAgOiAxKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhO1xuICAgIH1cblxuICAgIG9uKC4uLnZhbHVlcykge1xuICAgICAgICAvL3N3aXRjaCBvbiB0aGUgc3BlY2lmaWVkIHZhbHVlcy4gaWYgbm8gdmFsdWUgc3BlY2lmaWVkLCBmbGlwcyBvbiBhbGwgYnV0dG9uc1xuICAgICAgICBsZXQgYSA9IHRoaXMuYXJyYXk7XG4gICAgICAgIGlmICh2YWx1ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdmFsdWVzLmZvckVhY2goZnVuY3Rpb24odikge1xuICAgICAgICAgICAgICAgIGlmICh2ID4gYS5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignV2FybmluZzogQW5vblJhZGlvWycgKyB2ICsgJ10gZXhjZWVkcyBzaXplIG9mIG9iamVjdCcpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhW3ZdID09PSAxKSB7IGNvbnNvbGUud2FybignV2FybmluZzogQW5vblJhZGlvWycgKyB2ICsgJ10gd2FzIGFscmVhZHkgb24uJyk7IH1cbiAgICAgICAgICAgICAgICAgICAgYVt2XSA9IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhLmZpbGwoMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgb2ZmKC4uLnZhbHVlcykge1xuICAgICAgICAvL3N3aXRjaCBvZmYgdGhlIHNwZWNpZmllZCB2YWx1ZXMuIGlmIG5vIHZhbHVlIHNwZWNpZmllZCwgZmxpcHMgb2ZmIGFsbCBidXR0b25zXG4gICAgICAgIGxldCBhID0gdGhpcy5hcnJheTtcbiAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB2YWx1ZXMuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgICAgICAgICAgYVt2XSA9IDA7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGEuZmlsbCgwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYTtcbiAgICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbW9kZWxzL3JhZGlvLmpzIiwidmFyIFdBQUNsb2NrID0gcmVxdWlyZSgnLi9saWIvV0FBQ2xvY2snKVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdBQUNsb2NrXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHdpbmRvdy5XQUFDbG9jayA9IFdBQUNsb2NrXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vd2FhY2xvY2svaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDQyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBpc0Jyb3dzZXIgPSAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpXG5cbnZhciBDTE9DS19ERUZBVUxUUyA9IHtcbiAgdG9sZXJhbmNlTGF0ZTogMC4xMCxcbiAgdG9sZXJhbmNlRWFybHk6IDAuMDAxXG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09IEV2ZW50ID09PT09PT09PT09PT09PT09PT09IC8vXG52YXIgRXZlbnQgPSBmdW5jdGlvbihjbG9jaywgZGVhZGxpbmUsIGZ1bmMpIHtcbiAgdGhpcy5jbG9jayA9IGNsb2NrXG4gIHRoaXMuZnVuYyA9IGZ1bmNcbiAgdGhpcy5fY2xlYXJlZCA9IGZhbHNlIC8vIEZsYWcgdXNlZCB0byBjbGVhciBhbiBldmVudCBpbnNpZGUgY2FsbGJhY2tcblxuICB0aGlzLnRvbGVyYW5jZUxhdGUgPSBjbG9jay50b2xlcmFuY2VMYXRlXG4gIHRoaXMudG9sZXJhbmNlRWFybHkgPSBjbG9jay50b2xlcmFuY2VFYXJseVxuICB0aGlzLl9sYXRlc3RUaW1lID0gbnVsbFxuICB0aGlzLl9lYXJsaWVzdFRpbWUgPSBudWxsXG4gIHRoaXMuZGVhZGxpbmUgPSBudWxsXG4gIHRoaXMucmVwZWF0VGltZSA9IG51bGxcblxuICB0aGlzLnNjaGVkdWxlKGRlYWRsaW5lKVxufVxuXG4vLyBVbnNjaGVkdWxlcyB0aGUgZXZlbnRcbkV2ZW50LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuICB0aGlzLl9jbGVhcmVkID0gdHJ1ZVxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBTZXRzIHRoZSBldmVudCB0byByZXBlYXQgZXZlcnkgYHRpbWVgIHNlY29uZHMuXG5FdmVudC5wcm90b3R5cGUucmVwZWF0ID0gZnVuY3Rpb24odGltZSkge1xuICBpZiAodGltZSA9PT0gMClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlbGF5IGNhbm5vdCBiZSAwJylcbiAgdGhpcy5yZXBlYXRUaW1lID0gdGltZVxuICBpZiAoIXRoaXMuY2xvY2suX2hhc0V2ZW50KHRoaXMpKVxuICAgIHRoaXMuc2NoZWR1bGUodGhpcy5kZWFkbGluZSArIHRoaXMucmVwZWF0VGltZSlcbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gU2V0cyB0aGUgdGltZSB0b2xlcmFuY2Ugb2YgdGhlIGV2ZW50LlxuLy8gVGhlIGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQgaW4gdGhlIGludGVydmFsIGBbZGVhZGxpbmUgLSBlYXJseSwgZGVhZGxpbmUgKyBsYXRlXWBcbi8vIElmIHRoZSBjbG9jayBmYWlscyB0byBleGVjdXRlIHRoZSBldmVudCBpbiB0aW1lLCB0aGUgZXZlbnQgd2lsbCBiZSBkcm9wcGVkLlxuRXZlbnQucHJvdG90eXBlLnRvbGVyYW5jZSA9IGZ1bmN0aW9uKHZhbHVlcykge1xuICBpZiAodHlwZW9mIHZhbHVlcy5sYXRlID09PSAnbnVtYmVyJylcbiAgICB0aGlzLnRvbGVyYW5jZUxhdGUgPSB2YWx1ZXMubGF0ZVxuICBpZiAodHlwZW9mIHZhbHVlcy5lYXJseSA9PT0gJ251bWJlcicpXG4gICAgdGhpcy50b2xlcmFuY2VFYXJseSA9IHZhbHVlcy5lYXJseVxuICB0aGlzLl9yZWZyZXNoRWFybHlMYXRlRGF0ZXMoKVxuICBpZiAodGhpcy5jbG9jay5faGFzRXZlbnQodGhpcykpIHtcbiAgICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuICAgIHRoaXMuY2xvY2suX2luc2VydEV2ZW50KHRoaXMpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBldmVudCBpcyByZXBlYXRlZCwgZmFsc2Ugb3RoZXJ3aXNlXG5FdmVudC5wcm90b3R5cGUuaXNSZXBlYXRlZCA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5yZXBlYXRUaW1lICE9PSBudWxsIH1cblxuLy8gU2NoZWR1bGVzIHRoZSBldmVudCB0byBiZSByYW4gYmVmb3JlIGBkZWFkbGluZWAuXG4vLyBJZiB0aGUgdGltZSBpcyB3aXRoaW4gdGhlIGV2ZW50IHRvbGVyYW5jZSwgd2UgaGFuZGxlIHRoZSBldmVudCBpbW1lZGlhdGVseS5cbi8vIElmIHRoZSBldmVudCB3YXMgYWxyZWFkeSBzY2hlZHVsZWQgYXQgYSBkaWZmZXJlbnQgdGltZSwgaXQgaXMgcmVzY2hlZHVsZWQuXG5FdmVudC5wcm90b3R5cGUuc2NoZWR1bGUgPSBmdW5jdGlvbihkZWFkbGluZSkge1xuICB0aGlzLl9jbGVhcmVkID0gZmFsc2VcbiAgdGhpcy5kZWFkbGluZSA9IGRlYWRsaW5lXG4gIHRoaXMuX3JlZnJlc2hFYXJseUxhdGVEYXRlcygpXG5cbiAgaWYgKHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSA+PSB0aGlzLl9lYXJsaWVzdFRpbWUpIHtcbiAgICB0aGlzLl9leGVjdXRlKClcbiAgXG4gIH0gZWxzZSBpZiAodGhpcy5jbG9jay5faGFzRXZlbnQodGhpcykpIHtcbiAgICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuICAgIHRoaXMuY2xvY2suX2luc2VydEV2ZW50KHRoaXMpXG4gIFxuICB9IGVsc2UgdGhpcy5jbG9jay5faW5zZXJ0RXZlbnQodGhpcylcbn1cblxuRXZlbnQucHJvdG90eXBlLnRpbWVTdHJldGNoID0gZnVuY3Rpb24odFJlZiwgcmF0aW8pIHtcbiAgaWYgKHRoaXMuaXNSZXBlYXRlZCgpKVxuICAgIHRoaXMucmVwZWF0VGltZSA9IHRoaXMucmVwZWF0VGltZSAqIHJhdGlvXG5cbiAgdmFyIGRlYWRsaW5lID0gdFJlZiArIHJhdGlvICogKHRoaXMuZGVhZGxpbmUgLSB0UmVmKVxuICAvLyBJZiB0aGUgZGVhZGxpbmUgaXMgdG9vIGNsb3NlIG9yIHBhc3QsIGFuZCB0aGUgZXZlbnQgaGFzIGEgcmVwZWF0LFxuICAvLyB3ZSBjYWxjdWxhdGUgdGhlIG5leHQgcmVwZWF0IHBvc3NpYmxlIGluIHRoZSBzdHJldGNoZWQgc3BhY2UuXG4gIGlmICh0aGlzLmlzUmVwZWF0ZWQoKSkge1xuICAgIHdoaWxlICh0aGlzLmNsb2NrLmNvbnRleHQuY3VycmVudFRpbWUgPj0gZGVhZGxpbmUgLSB0aGlzLnRvbGVyYW5jZUVhcmx5KVxuICAgICAgZGVhZGxpbmUgKz0gdGhpcy5yZXBlYXRUaW1lXG4gIH1cbiAgdGhpcy5zY2hlZHVsZShkZWFkbGluZSlcbn1cblxuLy8gRXhlY3V0ZXMgdGhlIGV2ZW50XG5FdmVudC5wcm90b3R5cGUuX2V4ZWN1dGUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuY2xvY2suX3N0YXJ0ZWQgPT09IGZhbHNlKSByZXR1cm5cbiAgdGhpcy5jbG9jay5fcmVtb3ZlRXZlbnQodGhpcylcblxuICBpZiAodGhpcy5jbG9jay5jb250ZXh0LmN1cnJlbnRUaW1lIDwgdGhpcy5fbGF0ZXN0VGltZSlcbiAgICB0aGlzLmZ1bmModGhpcylcbiAgZWxzZSB7XG4gICAgaWYgKHRoaXMub25leHBpcmVkKSB0aGlzLm9uZXhwaXJlZCh0aGlzKVxuICAgIGNvbnNvbGUud2FybignZXZlbnQgZXhwaXJlZCcpXG4gIH1cbiAgLy8gSW4gdGhlIGNhc2UgYHNjaGVkdWxlYCBpcyBjYWxsZWQgaW5zaWRlIGBmdW5jYCwgd2UgbmVlZCB0byBhdm9pZFxuICAvLyBvdmVycndyaXRpbmcgd2l0aCB5ZXQgYW5vdGhlciBgc2NoZWR1bGVgLlxuICBpZiAoIXRoaXMuY2xvY2suX2hhc0V2ZW50KHRoaXMpICYmIHRoaXMuaXNSZXBlYXRlZCgpICYmICF0aGlzLl9jbGVhcmVkKVxuICAgIHRoaXMuc2NoZWR1bGUodGhpcy5kZWFkbGluZSArIHRoaXMucmVwZWF0VGltZSkgXG59XG5cbi8vIFVwZGF0ZXMgY2FjaGVkIHRpbWVzXG5FdmVudC5wcm90b3R5cGUuX3JlZnJlc2hFYXJseUxhdGVEYXRlcyA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9sYXRlc3RUaW1lID0gdGhpcy5kZWFkbGluZSArIHRoaXMudG9sZXJhbmNlTGF0ZVxuICB0aGlzLl9lYXJsaWVzdFRpbWUgPSB0aGlzLmRlYWRsaW5lIC0gdGhpcy50b2xlcmFuY2VFYXJseVxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PSBXQUFDbG9jayA9PT09PT09PT09PT09PT09PT09PSAvL1xudmFyIFdBQUNsb2NrID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihjb250ZXh0LCBvcHRzKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBvcHRzID0gb3B0cyB8fCB7fVxuICB0aGlzLnRpY2tNZXRob2QgPSBvcHRzLnRpY2tNZXRob2QgfHwgJ1NjcmlwdFByb2Nlc3Nvck5vZGUnXG4gIHRoaXMudG9sZXJhbmNlRWFybHkgPSBvcHRzLnRvbGVyYW5jZUVhcmx5IHx8IENMT0NLX0RFRkFVTFRTLnRvbGVyYW5jZUVhcmx5XG4gIHRoaXMudG9sZXJhbmNlTGF0ZSA9IG9wdHMudG9sZXJhbmNlTGF0ZSB8fCBDTE9DS19ERUZBVUxUUy50b2xlcmFuY2VMYXRlXG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHRcbiAgdGhpcy5fZXZlbnRzID0gW11cbiAgdGhpcy5fc3RhcnRlZCA9IGZhbHNlXG59XG5cbi8vIC0tLS0tLS0tLS0gUHVibGljIEFQSSAtLS0tLS0tLS0tIC8vXG4vLyBTY2hlZHVsZXMgYGZ1bmNgIHRvIHJ1biBhZnRlciBgZGVsYXlgIHNlY29uZHMuXG5XQUFDbG9jay5wcm90b3R5cGUuc2V0VGltZW91dCA9IGZ1bmN0aW9uKGZ1bmMsIGRlbGF5KSB7XG4gIHJldHVybiB0aGlzLl9jcmVhdGVFdmVudChmdW5jLCB0aGlzLl9hYnNUaW1lKGRlbGF5KSlcbn1cblxuLy8gU2NoZWR1bGVzIGBmdW5jYCB0byBydW4gYmVmb3JlIGBkZWFkbGluZWAuXG5XQUFDbG9jay5wcm90b3R5cGUuY2FsbGJhY2tBdFRpbWUgPSBmdW5jdGlvbihmdW5jLCBkZWFkbGluZSkge1xuICByZXR1cm4gdGhpcy5fY3JlYXRlRXZlbnQoZnVuYywgZGVhZGxpbmUpXG59XG5cbi8vIFN0cmV0Y2hlcyBgZGVhZGxpbmVgIGFuZCBgcmVwZWF0YCBvZiBhbGwgc2NoZWR1bGVkIGBldmVudHNgIGJ5IGByYXRpb2AsIGtlZXBpbmdcbi8vIHRoZWlyIHJlbGF0aXZlIGRpc3RhbmNlIHRvIGB0UmVmYC4gSW4gZmFjdCB0aGlzIGlzIGVxdWl2YWxlbnQgdG8gY2hhbmdpbmcgdGhlIHRlbXBvLlxuV0FBQ2xvY2sucHJvdG90eXBlLnRpbWVTdHJldGNoID0gZnVuY3Rpb24odFJlZiwgZXZlbnRzLCByYXRpbykge1xuICBldmVudHMuZm9yRWFjaChmdW5jdGlvbihldmVudCkgeyBldmVudC50aW1lU3RyZXRjaCh0UmVmLCByYXRpbykgfSlcbiAgcmV0dXJuIGV2ZW50c1xufVxuXG4vLyBSZW1vdmVzIGFsbCBzY2hlZHVsZWQgZXZlbnRzIGFuZCBzdGFydHMgdGhlIGNsb2NrIFxuV0FBQ2xvY2sucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLl9zdGFydGVkID09PSBmYWxzZSkge1xuICAgIHZhciBzZWxmID0gdGhpc1xuICAgIHRoaXMuX3N0YXJ0ZWQgPSB0cnVlXG4gICAgdGhpcy5fZXZlbnRzID0gW11cblxuICAgIGlmICh0aGlzLnRpY2tNZXRob2QgPT09ICdTY3JpcHRQcm9jZXNzb3JOb2RlJykge1xuICAgICAgdmFyIGJ1ZmZlclNpemUgPSAyNTZcbiAgICAgIC8vIFdlIGhhdmUgdG8ga2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgbm9kZSB0byBhdm9pZCBnYXJiYWdlIGNvbGxlY3Rpb25cbiAgICAgIHRoaXMuX2Nsb2NrTm9kZSA9IHRoaXMuY29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IoYnVmZmVyU2l6ZSwgMSwgMSlcbiAgICAgIHRoaXMuX2Nsb2NrTm9kZS5jb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbilcbiAgICAgIHRoaXMuX2Nsb2NrTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbigpIHsgc2VsZi5fdGljaygpIH0pXG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0aGlzLnRpY2tNZXRob2QgPT09ICdtYW51YWwnKSBudWxsIC8vIF90aWNrIGlzIGNhbGxlZCBtYW51YWxseVxuXG4gICAgZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgdGlja01ldGhvZCAnICsgdGhpcy50aWNrTWV0aG9kKVxuICB9XG59XG5cbi8vIFN0b3BzIHRoZSBjbG9ja1xuV0FBQ2xvY2sucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuX3N0YXJ0ZWQgPT09IHRydWUpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2VcbiAgICB0aGlzLl9jbG9ja05vZGUuZGlzY29ubmVjdCgpXG4gIH0gIFxufVxuXG4vLyAtLS0tLS0tLS0tIFByaXZhdGUgLS0tLS0tLS0tLSAvL1xuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIHJhbiBwZXJpb2RpY2FsbHksIGFuZCBhdCBlYWNoIHRpY2sgaXQgZXhlY3V0ZXNcbi8vIGV2ZW50cyBmb3Igd2hpY2ggYGN1cnJlbnRUaW1lYCBpcyBpbmNsdWRlZCBpbiB0aGVpciB0b2xlcmFuY2UgaW50ZXJ2YWwuXG5XQUFDbG9jay5wcm90b3R5cGUuX3RpY2sgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGV2ZW50ID0gdGhpcy5fZXZlbnRzLnNoaWZ0KClcblxuICB3aGlsZShldmVudCAmJiBldmVudC5fZWFybGllc3RUaW1lIDw9IHRoaXMuY29udGV4dC5jdXJyZW50VGltZSkge1xuICAgIGV2ZW50Ll9leGVjdXRlKClcbiAgICBldmVudCA9IHRoaXMuX2V2ZW50cy5zaGlmdCgpXG4gIH1cblxuICAvLyBQdXQgYmFjayB0aGUgbGFzdCBldmVudFxuICBpZihldmVudCkgdGhpcy5fZXZlbnRzLnVuc2hpZnQoZXZlbnQpXG59XG5cbi8vIENyZWF0ZXMgYW4gZXZlbnQgYW5kIGluc2VydCBpdCB0byB0aGUgbGlzdFxuV0FBQ2xvY2sucHJvdG90eXBlLl9jcmVhdGVFdmVudCA9IGZ1bmN0aW9uKGZ1bmMsIGRlYWRsaW5lKSB7XG4gIHJldHVybiBuZXcgRXZlbnQodGhpcywgZGVhZGxpbmUsIGZ1bmMpXG59XG5cbi8vIEluc2VydHMgYW4gZXZlbnQgdG8gdGhlIGxpc3RcbldBQUNsb2NrLnByb3RvdHlwZS5faW5zZXJ0RXZlbnQgPSBmdW5jdGlvbihldmVudCkge1xuICB0aGlzLl9ldmVudHMuc3BsaWNlKHRoaXMuX2luZGV4QnlUaW1lKGV2ZW50Ll9lYXJsaWVzdFRpbWUpLCAwLCBldmVudClcbn1cblxuLy8gUmVtb3ZlcyBhbiBldmVudCBmcm9tIHRoZSBsaXN0XG5XQUFDbG9jay5wcm90b3R5cGUuX3JlbW92ZUV2ZW50ID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgdmFyIGluZCA9IHRoaXMuX2V2ZW50cy5pbmRleE9mKGV2ZW50KVxuICBpZiAoaW5kICE9PSAtMSkgdGhpcy5fZXZlbnRzLnNwbGljZShpbmQsIDEpXG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiBgZXZlbnRgIGlzIGluIHF1ZXVlLCBmYWxzZSBvdGhlcndpc2VcbldBQUNsb2NrLnByb3RvdHlwZS5faGFzRXZlbnQgPSBmdW5jdGlvbihldmVudCkge1xuIHJldHVybiB0aGlzLl9ldmVudHMuaW5kZXhPZihldmVudCkgIT09IC0xXG59XG5cbi8vIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBldmVudCB3aG9zZSBkZWFkbGluZSBpcyA+PSB0byBgZGVhZGxpbmVgXG5XQUFDbG9jay5wcm90b3R5cGUuX2luZGV4QnlUaW1lID0gZnVuY3Rpb24oZGVhZGxpbmUpIHtcbiAgLy8gcGVyZm9ybXMgYSBiaW5hcnkgc2VhcmNoXG4gIHZhciBsb3cgPSAwXG4gICAgLCBoaWdoID0gdGhpcy5fZXZlbnRzLmxlbmd0aFxuICAgICwgbWlkXG4gIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgbWlkID0gTWF0aC5mbG9vcigobG93ICsgaGlnaCkgLyAyKVxuICAgIGlmICh0aGlzLl9ldmVudHNbbWlkXS5fZWFybGllc3RUaW1lIDwgZGVhZGxpbmUpXG4gICAgICBsb3cgPSBtaWQgKyAxXG4gICAgZWxzZSBoaWdoID0gbWlkXG4gIH1cbiAgcmV0dXJuIGxvd1xufVxuXG4vLyBDb252ZXJ0cyBmcm9tIHJlbGF0aXZlIHRpbWUgdG8gYWJzb2x1dGUgdGltZVxuV0FBQ2xvY2sucHJvdG90eXBlLl9hYnNUaW1lID0gZnVuY3Rpb24ocmVsVGltZSkge1xuICByZXR1cm4gcmVsVGltZSArIHRoaXMuY29udGV4dC5jdXJyZW50VGltZVxufVxuXG4vLyBDb252ZXJ0cyBmcm9tIGFic29sdXRlIHRpbWUgdG8gcmVsYXRpdmUgdGltZSBcbldBQUNsb2NrLnByb3RvdHlwZS5fcmVsVGltZSA9IGZ1bmN0aW9uKGFic1RpbWUpIHtcbiAgcmV0dXJuIGFic1RpbWUgLSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWVcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vd2FhY2xvY2svbGliL1dBQUNsb2NrLmpzXG4vLyBtb2R1bGUgaWQgPSA0M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRPbmNlTGlzdGVuZXIgPSBub29wO1xuXG5wcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Byb2Nlc3MvYnJvd3Nlci5qc1xuLy8gbW9kdWxlIGlkID0gNDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBjbG9jayB9IGZyb20gJy4uL21haW4nO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJbnRlcnZhbCB7XG5cbiAgY29uc3RydWN0b3IocmF0ZSxmdW5jLG9uKSB7XG5cbiAgICB0aGlzLnJhdGUgPSByYXRlO1xuICAgIHRoaXMub24gPSBvbjtcbiAgICB0aGlzLmNsb2NrID0gY2xvY2soKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgICB0aGlzLnBhdHRlcm4gPSBbMV07XG4gICAgdGhpcy5pbmRleCA9IDA7XG5cbiAgICB0aGlzLmV2ZW50ID0gZnVuYyA/IGZ1bmMgOiBmdW5jdGlvbigpIHsgfTtcblxuICAgIGlmICh0aGlzLm9uKSB7XG4gICAgICB0aGlzLnN0YXJ0KCk7XG4gICAgfVxuXG4gIH1cblxuICBfZXZlbnQoZSkge1xuICAvLyAgaWYgKHRoaXMucGF0dGVyblt0aGlzLmluZGV4JXRoaXMucGF0dGVybi5sZW5ndGhdKSB7XG4gICAgICB0aGlzLmV2ZW50KGUpO1xuICAvLyAgfVxuICAgIHRoaXMuaW5kZXgrKztcbiAgfVxuXG4gIHN0b3AoKSB7XG4gICAgdGhpcy5vbiA9IGZhbHNlO1xuICAgIHRoaXMuaW50ZXJ2YWwuY2xlYXIoKTtcbiAgfVxuXG4gIHN0YXJ0KCkge1xuICAgIHRoaXMub24gPSB0cnVlO1xuICAgIHRoaXMuaW50ZXJ2YWwgPSB0aGlzLmNsb2NrLmNhbGxiYWNrQXRUaW1lKHRoaXMuX2V2ZW50LmJpbmQodGhpcyksIHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSkucmVwZWF0KHRoaXMucmF0ZS8xMDAwKS50b2xlcmFuY2Uoe2Vhcmx5OiAwLjEsIGxhdGU6MX0pO1xuICB9XG5cbiAgbXMobmV3cmF0ZSkge1xuICAgIGlmICh0aGlzLm9uKSB7XG4gICAgICB2YXIgcmF0aW8gPSBuZXdyYXRlL3RoaXMucmF0ZTtcbiAgICAgIHRoaXMucmF0ZSA9IG5ld3JhdGU7XG4gICAgICB0aGlzLmNsb2NrLnRpbWVTdHJldGNoKHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSwgW3RoaXMuaW50ZXJ2YWxdLCByYXRpbyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmF0ZSA9IG5ld3JhdGU7XG4gICAgfVxuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi90aW1lL2ludGVydmFsLmpzIl0sInNvdXJjZVJvb3QiOiIifQ==\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/nexusui/dist/NexusUI.js\n// module id = 56\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/object/assign\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/babel-runtime/core-js/object/assign.js\n// module id = 57\n// module chunks = 0","module.exports = require('./_global').document && document.documentElement;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_html.js\n// module id = 58\n// module chunks = 0","module.exports = !require('./_descriptors') && !require('./_fails')(function(){\n return Object.defineProperty(require('./_dom-create')('div'), 'a', {get: function(){ return 7; }}).a != 7;\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_ie8-dom-define.js\n// module id = 59\n// module chunks = 0","// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = require('./_cof');\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){\n return cof(it) == 'String' ? it.split('') : Object(it);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_iobject.js\n// module id = 60\n// module chunks = 0","// check on default Array iterator\nvar Iterators = require('./_iterators')\n , ITERATOR = require('./_wks')('iterator')\n , ArrayProto = Array.prototype;\n\nmodule.exports = function(it){\n return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_is-array-iter.js\n// module id = 61\n// module chunks = 0","// call something on iterator step with safe closing on error\nvar anObject = require('./_an-object');\nmodule.exports = function(iterator, fn, value, entries){\n try {\n return entries ? fn(anObject(value)[0], value[1]) : fn(value);\n // 7.4.6 IteratorClose(iterator, completion)\n } catch(e){\n var ret = iterator['return'];\n if(ret !== undefined)anObject(ret.call(iterator));\n throw e;\n }\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_iter-call.js\n// module id = 62\n// module chunks = 0","'use strict';\nvar LIBRARY = require('./_library')\n , $export = require('./_export')\n , redefine = require('./_redefine')\n , hide = require('./_hide')\n , has = require('./_has')\n , Iterators = require('./_iterators')\n , $iterCreate = require('./_iter-create')\n , setToStringTag = require('./_set-to-string-tag')\n , getPrototypeOf = require('./_object-gpo')\n , ITERATOR = require('./_wks')('iterator')\n , BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`\n , FF_ITERATOR = '@@iterator'\n , KEYS = 'keys'\n , VALUES = 'values';\n\nvar returnThis = function(){ return this; };\n\nmodule.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){\n $iterCreate(Constructor, NAME, next);\n var getMethod = function(kind){\n if(!BUGGY && kind in proto)return proto[kind];\n switch(kind){\n case KEYS: return function keys(){ return new Constructor(this, kind); };\n case VALUES: return function values(){ return new Constructor(this, kind); };\n } return function entries(){ return new Constructor(this, kind); };\n };\n var TAG = NAME + ' Iterator'\n , DEF_VALUES = DEFAULT == VALUES\n , VALUES_BUG = false\n , proto = Base.prototype\n , $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]\n , $default = $native || getMethod(DEFAULT)\n , $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined\n , $anyNative = NAME == 'Array' ? proto.entries || $native : $native\n , methods, key, IteratorPrototype;\n // Fix native\n if($anyNative){\n IteratorPrototype = getPrototypeOf($anyNative.call(new Base));\n if(IteratorPrototype !== Object.prototype){\n // Set @@toStringTag to native iterators\n setToStringTag(IteratorPrototype, TAG, true);\n // fix for some old engines\n if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis);\n }\n }\n // fix Array#{values, @@iterator}.name in V8 / FF\n if(DEF_VALUES && $native && $native.name !== VALUES){\n VALUES_BUG = true;\n $default = function values(){ return $native.call(this); };\n }\n // Define iterator\n if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){\n hide(proto, ITERATOR, $default);\n }\n // Plug for library\n Iterators[NAME] = $default;\n Iterators[TAG] = returnThis;\n if(DEFAULT){\n methods = {\n values: DEF_VALUES ? $default : getMethod(VALUES),\n keys: IS_SET ? $default : getMethod(KEYS),\n entries: $entries\n };\n if(FORCED)for(key in methods){\n if(!(key in proto))redefine(proto, key, methods[key]);\n } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);\n }\n return methods;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_iter-define.js\n// module id = 63\n// module chunks = 0","var ITERATOR = require('./_wks')('iterator')\n , SAFE_CLOSING = false;\n\ntry {\n var riter = [7][ITERATOR]();\n riter['return'] = function(){ SAFE_CLOSING = true; };\n Array.from(riter, function(){ throw 2; });\n} catch(e){ /* empty */ }\n\nmodule.exports = function(exec, skipClosing){\n if(!skipClosing && !SAFE_CLOSING)return false;\n var safe = false;\n try {\n var arr = [7]\n , iter = arr[ITERATOR]();\n iter.next = function(){ return {done: safe = true}; };\n arr[ITERATOR] = function(){ return iter; };\n exec(arr);\n } catch(e){ /* empty */ }\n return safe;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_iter-detect.js\n// module id = 64\n// module chunks = 0","// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = require('./_an-object')\n , dPs = require('./_object-dps')\n , enumBugKeys = require('./_enum-bug-keys')\n , IE_PROTO = require('./_shared-key')('IE_PROTO')\n , Empty = function(){ /* empty */ }\n , PROTOTYPE = 'prototype';\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function(){\n // Thrash, waste and sodomy: IE GC bug\n var iframe = require('./_dom-create')('iframe')\n , i = enumBugKeys.length\n , lt = '<'\n , gt = '>'\n , iframeDocument;\n iframe.style.display = 'none';\n require('./_html').appendChild(iframe);\n iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n // createDict = iframe.contentWindow.Object;\n // html.removeChild(iframe);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n iframeDocument.close();\n createDict = iframeDocument.F;\n while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]];\n return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties){\n var result;\n if(O !== null){\n Empty[PROTOTYPE] = anObject(O);\n result = new Empty;\n Empty[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = createDict();\n return Properties === undefined ? result : dPs(result, Properties);\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-create.js\n// module id = 65\n// module chunks = 0","// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)\nvar $keys = require('./_object-keys-internal')\n , hiddenKeys = require('./_enum-bug-keys').concat('length', 'prototype');\n\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O){\n return $keys(O, hiddenKeys);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-gopn.js\n// module id = 66\n// module chunks = 0","var has = require('./_has')\n , toIObject = require('./_to-iobject')\n , arrayIndexOf = require('./_array-includes')(false)\n , IE_PROTO = require('./_shared-key')('IE_PROTO');\n\nmodule.exports = function(object, names){\n var O = toIObject(object)\n , i = 0\n , result = []\n , key;\n for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key);\n // Don't enum bug & hidden keys\n while(names.length > i)if(has(O, key = names[i++])){\n ~arrayIndexOf(result, key) || result.push(key);\n }\n return result;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-keys-internal.js\n// module id = 67\n// module chunks = 0","module.exports = require('./_hide');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_redefine.js\n// module id = 68\n// module chunks = 0","var ctx = require('./_ctx')\n , invoke = require('./_invoke')\n , html = require('./_html')\n , cel = require('./_dom-create')\n , global = require('./_global')\n , process = global.process\n , setTask = global.setImmediate\n , clearTask = global.clearImmediate\n , MessageChannel = global.MessageChannel\n , counter = 0\n , queue = {}\n , ONREADYSTATECHANGE = 'onreadystatechange'\n , defer, channel, port;\nvar run = function(){\n var id = +this;\n if(queue.hasOwnProperty(id)){\n var fn = queue[id];\n delete queue[id];\n fn();\n }\n};\nvar listener = function(event){\n run.call(event.data);\n};\n// Node.js 0.9+ & IE10+ has setImmediate, otherwise:\nif(!setTask || !clearTask){\n setTask = function setImmediate(fn){\n var args = [], i = 1;\n while(arguments.length > i)args.push(arguments[i++]);\n queue[++counter] = function(){\n invoke(typeof fn == 'function' ? fn : Function(fn), args);\n };\n defer(counter);\n return counter;\n };\n clearTask = function clearImmediate(id){\n delete queue[id];\n };\n // Node.js 0.8-\n if(require('./_cof')(process) == 'process'){\n defer = function(id){\n process.nextTick(ctx(run, id, 1));\n };\n // Browsers with MessageChannel, includes WebWorkers\n } else if(MessageChannel){\n channel = new MessageChannel;\n port = channel.port2;\n channel.port1.onmessage = listener;\n defer = ctx(port.postMessage, port, 1);\n // Browsers with postMessage, skip WebWorkers\n // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'\n } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){\n defer = function(id){\n global.postMessage(id + '', '*');\n };\n global.addEventListener('message', listener, false);\n // IE8-\n } else if(ONREADYSTATECHANGE in cel('script')){\n defer = function(id){\n html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){\n html.removeChild(this);\n run.call(id);\n };\n };\n // Rest old browsers\n } else {\n defer = function(id){\n setTimeout(ctx(run, id, 1), 0);\n };\n }\n}\nmodule.exports = {\n set: setTask,\n clear: clearTask\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_task.js\n// module id = 69\n// module chunks = 0","var toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/isarray/index.js\n// module id = 71\n// module chunks = 0","'use strict';\n\nmodule.exports = Readable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar isArray = require('isarray');\n/*</replacement>*/\n\n/*<replacement>*/\nvar Duplex;\n/*</replacement>*/\n\nReadable.ReadableState = ReadableState;\n\n/*<replacement>*/\nvar EE = require('events').EventEmitter;\n\nvar EElistenerCount = function (emitter, type) {\n return emitter.listeners(type).length;\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream = require('./internal/streams/stream');\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar debugUtil = require('util');\nvar debug = void 0;\nif (debugUtil && debugUtil.debuglog) {\n debug = debugUtil.debuglog('stream');\n} else {\n debug = function () {};\n}\n/*</replacement>*/\n\nvar BufferList = require('./internal/streams/BufferList');\nvar StringDecoder;\n\nutil.inherits(Readable, Stream);\n\nvar kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];\n\nfunction prependListener(emitter, event, fn) {\n // Sadly this is not cacheable as some libraries bundle their own\n // event emitter implementation with them.\n if (typeof emitter.prependListener === 'function') {\n return emitter.prependListener(event, fn);\n } else {\n // This is a hack to make sure that our error handler is attached before any\n // userland ones. NEVER DO THIS. This is here only because this code needs\n // to continue to work with older versions of Node.js that do not include\n // the prependListener() method. The goal is to eventually remove this hack.\n if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];\n }\n}\n\nfunction ReadableState(options, stream) {\n Duplex = Duplex || require('./_stream_duplex');\n\n options = options || {};\n\n // object stream flag. Used to make read(n) ignore n and to\n // make all the buffer merging and length checks go away\n this.objectMode = !!options.objectMode;\n\n if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;\n\n // the point at which it stops calling _read() to fill the buffer\n // Note: 0 is a valid value, means \"don't call _read preemptively ever\"\n var hwm = options.highWaterMark;\n var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n // cast to ints.\n this.highWaterMark = ~~this.highWaterMark;\n\n // A linked list is used to store data chunks instead of an array because the\n // linked list can remove elements from the beginning faster than\n // array.shift()\n this.buffer = new BufferList();\n this.length = 0;\n this.pipes = null;\n this.pipesCount = 0;\n this.flowing = null;\n this.ended = false;\n this.endEmitted = false;\n this.reading = false;\n\n // a flag to be able to tell if the onwrite cb is called immediately,\n // or on a later tick. We set this to true at first, because any\n // actions that shouldn't happen until \"later\" should generally also\n // not happen before the first write call.\n this.sync = true;\n\n // whenever we return null, then we set a flag to say\n // that we're awaiting a 'readable' event emission.\n this.needReadable = false;\n this.emittedReadable = false;\n this.readableListening = false;\n this.resumeScheduled = false;\n\n // Crypto is kind of old and crusty. Historically, its default string\n // encoding is 'binary' so we have to make this configurable.\n // Everything else in the universe uses 'utf8', though.\n this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n // when piping, we only care about 'readable' events that happen\n // after read()ing all the bytes and not getting any pushback.\n this.ranOut = false;\n\n // the number of writers that are awaiting a drain event in .pipe()s\n this.awaitDrain = 0;\n\n // if true, a maybeReadMore has been scheduled\n this.readingMore = false;\n\n this.decoder = null;\n this.encoding = null;\n if (options.encoding) {\n if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n this.decoder = new StringDecoder(options.encoding);\n this.encoding = options.encoding;\n }\n}\n\nfunction Readable(options) {\n Duplex = Duplex || require('./_stream_duplex');\n\n if (!(this instanceof Readable)) return new Readable(options);\n\n this._readableState = new ReadableState(options, this);\n\n // legacy\n this.readable = true;\n\n if (options && typeof options.read === 'function') this._read = options.read;\n\n Stream.call(this);\n}\n\n// Manually shove something into the read() buffer.\n// This returns true if the highWaterMark has not been hit yet,\n// similar to how Writable.write() returns true if you should\n// write() some more.\nReadable.prototype.push = function (chunk, encoding) {\n var state = this._readableState;\n\n if (!state.objectMode && typeof chunk === 'string') {\n encoding = encoding || state.defaultEncoding;\n if (encoding !== state.encoding) {\n chunk = bufferShim.from(chunk, encoding);\n encoding = '';\n }\n }\n\n return readableAddChunk(this, state, chunk, encoding, false);\n};\n\n// Unshift should *always* be something directly out of read()\nReadable.prototype.unshift = function (chunk) {\n var state = this._readableState;\n return readableAddChunk(this, state, chunk, '', true);\n};\n\nReadable.prototype.isPaused = function () {\n return this._readableState.flowing === false;\n};\n\nfunction readableAddChunk(stream, state, chunk, encoding, addToFront) {\n var er = chunkInvalid(state, chunk);\n if (er) {\n stream.emit('error', er);\n } else if (chunk === null) {\n state.reading = false;\n onEofChunk(stream, state);\n } else if (state.objectMode || chunk && chunk.length > 0) {\n if (state.ended && !addToFront) {\n var e = new Error('stream.push() after EOF');\n stream.emit('error', e);\n } else if (state.endEmitted && addToFront) {\n var _e = new Error('stream.unshift() after end event');\n stream.emit('error', _e);\n } else {\n var skipAdd;\n if (state.decoder && !addToFront && !encoding) {\n chunk = state.decoder.write(chunk);\n skipAdd = !state.objectMode && chunk.length === 0;\n }\n\n if (!addToFront) state.reading = false;\n\n // Don't add to the buffer if we've decoded to an empty string chunk and\n // we're not in object mode\n if (!skipAdd) {\n // if we want the data now, just emit it.\n if (state.flowing && state.length === 0 && !state.sync) {\n stream.emit('data', chunk);\n stream.read(0);\n } else {\n // update the buffer info.\n state.length += state.objectMode ? 1 : chunk.length;\n if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);\n\n if (state.needReadable) emitReadable(stream);\n }\n }\n\n maybeReadMore(stream, state);\n }\n } else if (!addToFront) {\n state.reading = false;\n }\n\n return needMoreData(state);\n}\n\n// if it's past the high water mark, we can push in some more.\n// Also, if we have no data yet, we can stand some\n// more bytes. This is to work around cases where hwm=0,\n// such as the repl. Also, if the push() triggered a\n// readable event, and the user called read(largeNumber) such that\n// needReadable was set, then we ought to push more, so that another\n// 'readable' event will be triggered.\nfunction needMoreData(state) {\n return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);\n}\n\n// backwards compatibility.\nReadable.prototype.setEncoding = function (enc) {\n if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n this._readableState.decoder = new StringDecoder(enc);\n this._readableState.encoding = enc;\n return this;\n};\n\n// Don't raise the hwm > 8MB\nvar MAX_HWM = 0x800000;\nfunction computeNewHighWaterMark(n) {\n if (n >= MAX_HWM) {\n n = MAX_HWM;\n } else {\n // Get the next highest power of 2 to prevent increasing hwm excessively in\n // tiny amounts\n n--;\n n |= n >>> 1;\n n |= n >>> 2;\n n |= n >>> 4;\n n |= n >>> 8;\n n |= n >>> 16;\n n++;\n }\n return n;\n}\n\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction howMuchToRead(n, state) {\n if (n <= 0 || state.length === 0 && state.ended) return 0;\n if (state.objectMode) return 1;\n if (n !== n) {\n // Only flow one buffer at a time\n if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;\n }\n // If we're asking for more than the current hwm, then raise the hwm.\n if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);\n if (n <= state.length) return n;\n // Don't have enough\n if (!state.ended) {\n state.needReadable = true;\n return 0;\n }\n return state.length;\n}\n\n// you can override either this method, or the async _read(n) below.\nReadable.prototype.read = function (n) {\n debug('read', n);\n n = parseInt(n, 10);\n var state = this._readableState;\n var nOrig = n;\n\n if (n !== 0) state.emittedReadable = false;\n\n // if we're doing read(0) to trigger a readable event, but we\n // already have a bunch of data in the buffer, then just trigger\n // the 'readable' event and move on.\n if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {\n debug('read: emitReadable', state.length, state.ended);\n if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);\n return null;\n }\n\n n = howMuchToRead(n, state);\n\n // if we've ended, and we're now clear, then finish it up.\n if (n === 0 && state.ended) {\n if (state.length === 0) endReadable(this);\n return null;\n }\n\n // All the actual chunk generation logic needs to be\n // *below* the call to _read. The reason is that in certain\n // synthetic stream cases, such as passthrough streams, _read\n // may be a completely synchronous operation which may change\n // the state of the read buffer, providing enough data when\n // before there was *not* enough.\n //\n // So, the steps are:\n // 1. Figure out what the state of things will be after we do\n // a read from the buffer.\n //\n // 2. If that resulting state will trigger a _read, then call _read.\n // Note that this may be asynchronous, or synchronous. Yes, it is\n // deeply ugly to write APIs this way, but that still doesn't mean\n // that the Readable class should behave improperly, as streams are\n // designed to be sync/async agnostic.\n // Take note if the _read call is sync or async (ie, if the read call\n // has returned yet), so that we know whether or not it's safe to emit\n // 'readable' etc.\n //\n // 3. Actually pull the requested chunks out of the buffer and return.\n\n // if we need a readable event, then we need to do some reading.\n var doRead = state.needReadable;\n debug('need readable', doRead);\n\n // if we currently have less than the highWaterMark, then also read some\n if (state.length === 0 || state.length - n < state.highWaterMark) {\n doRead = true;\n debug('length less than watermark', doRead);\n }\n\n // however, if we've ended, then there's no point, and if we're already\n // reading, then it's unnecessary.\n if (state.ended || state.reading) {\n doRead = false;\n debug('reading or ended', doRead);\n } else if (doRead) {\n debug('do read');\n state.reading = true;\n state.sync = true;\n // if the length is currently zero, then we *need* a readable event.\n if (state.length === 0) state.needReadable = true;\n // call internal read method\n this._read(state.highWaterMark);\n state.sync = false;\n // If _read pushed data synchronously, then `reading` will be false,\n // and we need to re-evaluate how much data we can return to the user.\n if (!state.reading) n = howMuchToRead(nOrig, state);\n }\n\n var ret;\n if (n > 0) ret = fromList(n, state);else ret = null;\n\n if (ret === null) {\n state.needReadable = true;\n n = 0;\n } else {\n state.length -= n;\n }\n\n if (state.length === 0) {\n // If we have nothing in the buffer, then we want to know\n // as soon as we *do* get something into the buffer.\n if (!state.ended) state.needReadable = true;\n\n // If we tried to read() past the EOF, then emit end on the next tick.\n if (nOrig !== n && state.ended) endReadable(this);\n }\n\n if (ret !== null) this.emit('data', ret);\n\n return ret;\n};\n\nfunction chunkInvalid(state, chunk) {\n var er = null;\n if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {\n er = new TypeError('Invalid non-string/buffer chunk');\n }\n return er;\n}\n\nfunction onEofChunk(stream, state) {\n if (state.ended) return;\n if (state.decoder) {\n var chunk = state.decoder.end();\n if (chunk && chunk.length) {\n state.buffer.push(chunk);\n state.length += state.objectMode ? 1 : chunk.length;\n }\n }\n state.ended = true;\n\n // emit 'readable' now to make sure it gets picked up.\n emitReadable(stream);\n}\n\n// Don't emit readable right away in sync mode, because this can trigger\n// another read() call => stack overflow. This way, it might trigger\n// a nextTick recursion warning, but that's not so bad.\nfunction emitReadable(stream) {\n var state = stream._readableState;\n state.needReadable = false;\n if (!state.emittedReadable) {\n debug('emitReadable', state.flowing);\n state.emittedReadable = true;\n if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);\n }\n}\n\nfunction emitReadable_(stream) {\n debug('emit readable');\n stream.emit('readable');\n flow(stream);\n}\n\n// at this point, the user has presumably seen the 'readable' event,\n// and called read() to consume some data. that may have triggered\n// in turn another _read(n) call, in which case reading = true if\n// it's in progress.\n// However, if we're not ended, or reading, and the length < hwm,\n// then go ahead and try to read some more preemptively.\nfunction maybeReadMore(stream, state) {\n if (!state.readingMore) {\n state.readingMore = true;\n processNextTick(maybeReadMore_, stream, state);\n }\n}\n\nfunction maybeReadMore_(stream, state) {\n var len = state.length;\n while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {\n debug('maybeReadMore read 0');\n stream.read(0);\n if (len === state.length)\n // didn't get any data, stop spinning.\n break;else len = state.length;\n }\n state.readingMore = false;\n}\n\n// abstract method. to be overridden in specific implementation classes.\n// call cb(er, data) where data is <= n in length.\n// for virtual (non-string, non-buffer) streams, \"length\" is somewhat\n// arbitrary, and perhaps not very meaningful.\nReadable.prototype._read = function (n) {\n this.emit('error', new Error('_read() is not implemented'));\n};\n\nReadable.prototype.pipe = function (dest, pipeOpts) {\n var src = this;\n var state = this._readableState;\n\n switch (state.pipesCount) {\n case 0:\n state.pipes = dest;\n break;\n case 1:\n state.pipes = [state.pipes, dest];\n break;\n default:\n state.pipes.push(dest);\n break;\n }\n state.pipesCount += 1;\n debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);\n\n var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;\n\n var endFn = doEnd ? onend : cleanup;\n if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);\n\n dest.on('unpipe', onunpipe);\n function onunpipe(readable) {\n debug('onunpipe');\n if (readable === src) {\n cleanup();\n }\n }\n\n function onend() {\n debug('onend');\n dest.end();\n }\n\n // when the dest drains, it reduces the awaitDrain counter\n // on the source. This would be more elegant with a .once()\n // handler in flow(), but adding and removing repeatedly is\n // too slow.\n var ondrain = pipeOnDrain(src);\n dest.on('drain', ondrain);\n\n var cleanedUp = false;\n function cleanup() {\n debug('cleanup');\n // cleanup event handlers once the pipe is broken\n dest.removeListener('close', onclose);\n dest.removeListener('finish', onfinish);\n dest.removeListener('drain', ondrain);\n dest.removeListener('error', onerror);\n dest.removeListener('unpipe', onunpipe);\n src.removeListener('end', onend);\n src.removeListener('end', cleanup);\n src.removeListener('data', ondata);\n\n cleanedUp = true;\n\n // if the reader is waiting for a drain event from this\n // specific writer, then it would cause it to never start\n // flowing again.\n // So, if this is awaiting a drain, then we just call it now.\n // If we don't know, then assume that we are waiting for one.\n if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();\n }\n\n // If the user pushes more data while we're writing to dest then we'll end up\n // in ondata again. However, we only want to increase awaitDrain once because\n // dest will only emit one 'drain' event for the multiple writes.\n // => Introduce a guard on increasing awaitDrain.\n var increasedAwaitDrain = false;\n src.on('data', ondata);\n function ondata(chunk) {\n debug('ondata');\n increasedAwaitDrain = false;\n var ret = dest.write(chunk);\n if (false === ret && !increasedAwaitDrain) {\n // If the user unpiped during `dest.write()`, it is possible\n // to get stuck in a permanently paused state if that write\n // also returned false.\n // => Check whether `dest` is still a piping destination.\n if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {\n debug('false write response, pause', src._readableState.awaitDrain);\n src._readableState.awaitDrain++;\n increasedAwaitDrain = true;\n }\n src.pause();\n }\n }\n\n // if the dest has an error, then stop piping into it.\n // however, don't suppress the throwing behavior for this.\n function onerror(er) {\n debug('onerror', er);\n unpipe();\n dest.removeListener('error', onerror);\n if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);\n }\n\n // Make sure our error handler is attached before userland ones.\n prependListener(dest, 'error', onerror);\n\n // Both close and finish should trigger unpipe, but only once.\n function onclose() {\n dest.removeListener('finish', onfinish);\n unpipe();\n }\n dest.once('close', onclose);\n function onfinish() {\n debug('onfinish');\n dest.removeListener('close', onclose);\n unpipe();\n }\n dest.once('finish', onfinish);\n\n function unpipe() {\n debug('unpipe');\n src.unpipe(dest);\n }\n\n // tell the dest that it's being piped to\n dest.emit('pipe', src);\n\n // start the flow if it hasn't been started already.\n if (!state.flowing) {\n debug('pipe resume');\n src.resume();\n }\n\n return dest;\n};\n\nfunction pipeOnDrain(src) {\n return function () {\n var state = src._readableState;\n debug('pipeOnDrain', state.awaitDrain);\n if (state.awaitDrain) state.awaitDrain--;\n if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {\n state.flowing = true;\n flow(src);\n }\n };\n}\n\nReadable.prototype.unpipe = function (dest) {\n var state = this._readableState;\n\n // if we're not piping anywhere, then do nothing.\n if (state.pipesCount === 0) return this;\n\n // just one destination. most common case.\n if (state.pipesCount === 1) {\n // passed in one, but it's not the right one.\n if (dest && dest !== state.pipes) return this;\n\n if (!dest) dest = state.pipes;\n\n // got a match.\n state.pipes = null;\n state.pipesCount = 0;\n state.flowing = false;\n if (dest) dest.emit('unpipe', this);\n return this;\n }\n\n // slow case. multiple pipe destinations.\n\n if (!dest) {\n // remove all.\n var dests = state.pipes;\n var len = state.pipesCount;\n state.pipes = null;\n state.pipesCount = 0;\n state.flowing = false;\n\n for (var i = 0; i < len; i++) {\n dests[i].emit('unpipe', this);\n }return this;\n }\n\n // try to find the right one.\n var index = indexOf(state.pipes, dest);\n if (index === -1) return this;\n\n state.pipes.splice(index, 1);\n state.pipesCount -= 1;\n if (state.pipesCount === 1) state.pipes = state.pipes[0];\n\n dest.emit('unpipe', this);\n\n return this;\n};\n\n// set up data events if they are asked for\n// Ensure readable listeners eventually get something\nReadable.prototype.on = function (ev, fn) {\n var res = Stream.prototype.on.call(this, ev, fn);\n\n if (ev === 'data') {\n // Start flowing on next tick if stream isn't explicitly paused\n if (this._readableState.flowing !== false) this.resume();\n } else if (ev === 'readable') {\n var state = this._readableState;\n if (!state.endEmitted && !state.readableListening) {\n state.readableListening = state.needReadable = true;\n state.emittedReadable = false;\n if (!state.reading) {\n processNextTick(nReadingNextTick, this);\n } else if (state.length) {\n emitReadable(this, state);\n }\n }\n }\n\n return res;\n};\nReadable.prototype.addListener = Readable.prototype.on;\n\nfunction nReadingNextTick(self) {\n debug('readable nexttick read 0');\n self.read(0);\n}\n\n// pause() and resume() are remnants of the legacy readable stream API\n// If the user uses them, then switch into old mode.\nReadable.prototype.resume = function () {\n var state = this._readableState;\n if (!state.flowing) {\n debug('resume');\n state.flowing = true;\n resume(this, state);\n }\n return this;\n};\n\nfunction resume(stream, state) {\n if (!state.resumeScheduled) {\n state.resumeScheduled = true;\n processNextTick(resume_, stream, state);\n }\n}\n\nfunction resume_(stream, state) {\n if (!state.reading) {\n debug('resume read 0');\n stream.read(0);\n }\n\n state.resumeScheduled = false;\n state.awaitDrain = 0;\n stream.emit('resume');\n flow(stream);\n if (state.flowing && !state.reading) stream.read(0);\n}\n\nReadable.prototype.pause = function () {\n debug('call pause flowing=%j', this._readableState.flowing);\n if (false !== this._readableState.flowing) {\n debug('pause');\n this._readableState.flowing = false;\n this.emit('pause');\n }\n return this;\n};\n\nfunction flow(stream) {\n var state = stream._readableState;\n debug('flow', state.flowing);\n while (state.flowing && stream.read() !== null) {}\n}\n\n// wrap an old-style stream as the async data source.\n// This is *not* part of the readable stream interface.\n// It is an ugly unfortunate mess of history.\nReadable.prototype.wrap = function (stream) {\n var state = this._readableState;\n var paused = false;\n\n var self = this;\n stream.on('end', function () {\n debug('wrapped end');\n if (state.decoder && !state.ended) {\n var chunk = state.decoder.end();\n if (chunk && chunk.length) self.push(chunk);\n }\n\n self.push(null);\n });\n\n stream.on('data', function (chunk) {\n debug('wrapped data');\n if (state.decoder) chunk = state.decoder.write(chunk);\n\n // don't skip over falsy values in objectMode\n if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;\n\n var ret = self.push(chunk);\n if (!ret) {\n paused = true;\n stream.pause();\n }\n });\n\n // proxy all the other methods.\n // important when wrapping filters and duplexes.\n for (var i in stream) {\n if (this[i] === undefined && typeof stream[i] === 'function') {\n this[i] = function (method) {\n return function () {\n return stream[method].apply(stream, arguments);\n };\n }(i);\n }\n }\n\n // proxy certain important events.\n for (var n = 0; n < kProxyEvents.length; n++) {\n stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n]));\n }\n\n // when we try to consume some more bytes, simply unpause the\n // underlying stream.\n self._read = function (n) {\n debug('wrapped _read', n);\n if (paused) {\n paused = false;\n stream.resume();\n }\n };\n\n return self;\n};\n\n// exposed for testing purposes only.\nReadable._fromList = fromList;\n\n// Pluck off n bytes from an array of buffers.\n// Length is the combined lengths of all the buffers in the list.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromList(n, state) {\n // nothing buffered\n if (state.length === 0) return null;\n\n var ret;\n if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {\n // read it all, truncate the list\n if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);\n state.buffer.clear();\n } else {\n // read part of list\n ret = fromListPartial(n, state.buffer, state.decoder);\n }\n\n return ret;\n}\n\n// Extracts only enough buffered data to satisfy the amount requested.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromListPartial(n, list, hasStrings) {\n var ret;\n if (n < list.head.data.length) {\n // slice is the same for buffers and strings\n ret = list.head.data.slice(0, n);\n list.head.data = list.head.data.slice(n);\n } else if (n === list.head.data.length) {\n // first chunk is a perfect match\n ret = list.shift();\n } else {\n // result spans more than one buffer\n ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);\n }\n return ret;\n}\n\n// Copies a specified amount of characters from the list of buffered data\n// chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBufferString(n, list) {\n var p = list.head;\n var c = 1;\n var ret = p.data;\n n -= ret.length;\n while (p = p.next) {\n var str = p.data;\n var nb = n > str.length ? str.length : n;\n if (nb === str.length) ret += str;else ret += str.slice(0, n);\n n -= nb;\n if (n === 0) {\n if (nb === str.length) {\n ++c;\n if (p.next) list.head = p.next;else list.head = list.tail = null;\n } else {\n list.head = p;\n p.data = str.slice(nb);\n }\n break;\n }\n ++c;\n }\n list.length -= c;\n return ret;\n}\n\n// Copies a specified amount of bytes from the list of buffered data chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBuffer(n, list) {\n var ret = bufferShim.allocUnsafe(n);\n var p = list.head;\n var c = 1;\n p.data.copy(ret);\n n -= p.data.length;\n while (p = p.next) {\n var buf = p.data;\n var nb = n > buf.length ? buf.length : n;\n buf.copy(ret, ret.length - n, 0, nb);\n n -= nb;\n if (n === 0) {\n if (nb === buf.length) {\n ++c;\n if (p.next) list.head = p.next;else list.head = list.tail = null;\n } else {\n list.head = p;\n p.data = buf.slice(nb);\n }\n break;\n }\n ++c;\n }\n list.length -= c;\n return ret;\n}\n\nfunction endReadable(stream) {\n var state = stream._readableState;\n\n // If we get here before consuming all the bytes, then that is a\n // bug in node. Should never happen.\n if (state.length > 0) throw new Error('\"endReadable()\" called on non-empty stream');\n\n if (!state.endEmitted) {\n state.ended = true;\n processNextTick(endReadableNT, state, stream);\n }\n}\n\nfunction endReadableNT(state, stream) {\n // Check that we didn't get one last unshift.\n if (!state.endEmitted && state.length === 0) {\n state.endEmitted = true;\n stream.readable = false;\n stream.emit('end');\n }\n}\n\nfunction forEach(xs, f) {\n for (var i = 0, l = xs.length; i < l; i++) {\n f(xs[i], i);\n }\n}\n\nfunction indexOf(xs, x) {\n for (var i = 0, l = xs.length; i < l; i++) {\n if (xs[i] === x) return i;\n }\n return -1;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/readable-stream/lib/_stream_readable.js\n// module id = 72\n// module chunks = 0","// a transform stream is a readable/writable stream where you do\n// something with the data. Sometimes it's called a \"filter\",\n// but that's not a great name for it, since that implies a thing where\n// some bits pass through, and others are simply ignored. (That would\n// be a valid example of a transform, of course.)\n//\n// While the output is causally related to the input, it's not a\n// necessarily symmetric or synchronous transformation. For example,\n// a zlib stream might take multiple plain-text writes(), and then\n// emit a single compressed chunk some time in the future.\n//\n// Here's how this works:\n//\n// The Transform stream has all the aspects of the readable and writable\n// stream classes. When you write(chunk), that calls _write(chunk,cb)\n// internally, and returns false if there's a lot of pending writes\n// buffered up. When you call read(), that calls _read(n) until\n// there's enough pending readable data buffered up.\n//\n// In a transform stream, the written data is placed in a buffer. When\n// _read(n) is called, it transforms the queued up data, calling the\n// buffered _write cb's as it consumes chunks. If consuming a single\n// written chunk would result in multiple output chunks, then the first\n// outputted bit calls the readcb, and subsequent chunks just go into\n// the read buffer, and will cause it to emit 'readable' if necessary.\n//\n// This way, back-pressure is actually determined by the reading side,\n// since _read has to be called to start processing a new chunk. However,\n// a pathological inflate type of transform can cause excessive buffering\n// here. For example, imagine a stream where every byte of input is\n// interpreted as an integer from 0-255, and then results in that many\n// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in\n// 1kb of data being output. In this case, you could write a very small\n// amount of input, and end up with a very large amount of output. In\n// such a pathological inflating mechanism, there'd be no way to tell\n// the system to stop doing the transform. A single 4MB write could\n// cause the system to run out of memory.\n//\n// However, even in such a pathological case, only a single written chunk\n// would be consumed, and then the rest would wait (un-transformed) until\n// the results of the previous transformed chunk were consumed.\n\n'use strict';\n\nmodule.exports = Transform;\n\nvar Duplex = require('./_stream_duplex');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(Transform, Duplex);\n\nfunction TransformState(stream) {\n this.afterTransform = function (er, data) {\n return afterTransform(stream, er, data);\n };\n\n this.needTransform = false;\n this.transforming = false;\n this.writecb = null;\n this.writechunk = null;\n this.writeencoding = null;\n}\n\nfunction afterTransform(stream, er, data) {\n var ts = stream._transformState;\n ts.transforming = false;\n\n var cb = ts.writecb;\n\n if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));\n\n ts.writechunk = null;\n ts.writecb = null;\n\n if (data !== null && data !== undefined) stream.push(data);\n\n cb(er);\n\n var rs = stream._readableState;\n rs.reading = false;\n if (rs.needReadable || rs.length < rs.highWaterMark) {\n stream._read(rs.highWaterMark);\n }\n}\n\nfunction Transform(options) {\n if (!(this instanceof Transform)) return new Transform(options);\n\n Duplex.call(this, options);\n\n this._transformState = new TransformState(this);\n\n var stream = this;\n\n // start out asking for a readable event once data is transformed.\n this._readableState.needReadable = true;\n\n // we have implemented the _read method, and done the other things\n // that Readable wants before the first _read call, so unset the\n // sync guard flag.\n this._readableState.sync = false;\n\n if (options) {\n if (typeof options.transform === 'function') this._transform = options.transform;\n\n if (typeof options.flush === 'function') this._flush = options.flush;\n }\n\n // When the writable side finishes, then flush out anything remaining.\n this.once('prefinish', function () {\n if (typeof this._flush === 'function') this._flush(function (er, data) {\n done(stream, er, data);\n });else done(stream);\n });\n}\n\nTransform.prototype.push = function (chunk, encoding) {\n this._transformState.needTransform = false;\n return Duplex.prototype.push.call(this, chunk, encoding);\n};\n\n// This is the part where you do stuff!\n// override this function in implementation classes.\n// 'chunk' is an input chunk.\n//\n// Call `push(newChunk)` to pass along transformed output\n// to the readable side. You may call 'push' zero or more times.\n//\n// Call `cb(err)` when you are done with this chunk. If you pass\n// an error, then that'll put the hurt on the whole operation. If you\n// never call cb(), then you'll never get another chunk.\nTransform.prototype._transform = function (chunk, encoding, cb) {\n throw new Error('_transform() is not implemented');\n};\n\nTransform.prototype._write = function (chunk, encoding, cb) {\n var ts = this._transformState;\n ts.writecb = cb;\n ts.writechunk = chunk;\n ts.writeencoding = encoding;\n if (!ts.transforming) {\n var rs = this._readableState;\n if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);\n }\n};\n\n// Doesn't matter what the args are here.\n// _transform does all the work.\n// That we got here means that the readable side wants more data.\nTransform.prototype._read = function (n) {\n var ts = this._transformState;\n\n if (ts.writechunk !== null && ts.writecb && !ts.transforming) {\n ts.transforming = true;\n this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);\n } else {\n // mark that we need a transform, so that any data that comes in\n // will get processed, now that we've asked for it.\n ts.needTransform = true;\n }\n};\n\nfunction done(stream, er, data) {\n if (er) return stream.emit('error', er);\n\n if (data !== null && data !== undefined) stream.push(data);\n\n // if there's nothing in the write buffer, then that means\n // that nothing more will ever be provided\n var ws = stream._writableState;\n var ts = stream._transformState;\n\n if (ws.length) throw new Error('Calling transform done when ws.length != 0');\n\n if (ts.transforming) throw new Error('Calling transform done when still transforming');\n\n return stream.push(null);\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/readable-stream/lib/_stream_transform.js\n// module id = 73\n// module chunks = 0","module.exports = require('events').EventEmitter;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/readable-stream/lib/internal/streams/stream-browser.js\n// module id = 74\n// module chunks = 0","var apply = Function.prototype.apply;\n\n// DOM APIs, for completeness\n\nexports.setTimeout = function() {\n return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);\n};\nexports.setInterval = function() {\n return new Timeout(apply.call(setInterval, window, arguments), clearInterval);\n};\nexports.clearTimeout =\nexports.clearInterval = function(timeout) {\n if (timeout) {\n timeout.close();\n }\n};\n\nfunction Timeout(id, clearFn) {\n this._id = id;\n this._clearFn = clearFn;\n}\nTimeout.prototype.unref = Timeout.prototype.ref = function() {};\nTimeout.prototype.close = function() {\n this._clearFn.call(window, this._id);\n};\n\n// Does not start the time, just sets up the members needed.\nexports.enroll = function(item, msecs) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = msecs;\n};\n\nexports.unenroll = function(item) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = -1;\n};\n\nexports._unrefActive = exports.active = function(item) {\n clearTimeout(item._idleTimeoutId);\n\n var msecs = item._idleTimeout;\n if (msecs >= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// setimmediate attaches itself to the global object\nrequire(\"setimmediate\");\nexports.setImmediate = setImmediate;\nexports.clearImmediate = clearImmediate;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/timers-browserify/main.js\n// module id = 75\n// module chunks = 0","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.load = undefined;\n\nvar _promise = require(\"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar files = [\n// \"gun_violence\",\n\"mass_shootings_lite\", \"gun_violence_by_month\"];\nvar parse = require('csv-parse');\n\nvar dataPromises = files.map(function (name) {\n return fetch('./data/' + name + '.csv').then(function (rows) {\n return rows.text();\n }).then(function (text) {\n return new _promise2.default(function (resolve, reject) {\n parse(text, {}, function (_, lines) {\n return resolve(lines);\n });\n });\n }).then(function (lines) {\n // console.log(name, lines)\n var h = lines.shift();\n return {\n name: name,\n h: h,\n lines: lines.filter(function (s) {\n return !!s;\n })\n };\n });\n});\nvar allPromises = _promise2.default.all(dataPromises).then(function (data) {\n return data.reduce(function (a, b) {\n // console.log(b)\n a[b.name] = b;\n return a;\n }, {});\n});\nvar load = function load() {\n return allPromises;\n};\n\nexports.load = load;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/data.js\n// module id = 76\n// module chunks = 0","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar keys = {};\nvar key_numbers = {};\nvar letters = \"zxcvbnmasdfghjklqwertyuiop\";\nvar numbers = \"1234567890\";\n\nvar callback = function callback() {};\n\nletters.toUpperCase().split(\"\").map(function (k, i) {\n keys[k.charCodeAt(0)] = i;\n});\n\nnumbers.split(\"\").map(function (k, i) {\n keys[k.charCodeAt(0)] = i + letters.length;\n key_numbers[k.charCodeAt(0)] = true;\n});\n\nwindow.addEventListener(\"keydown\", keydown, true);\nfunction keydown(e) {\n if (e.altKey || e.ctrlKey || e.metaKey) {\n e.stopPropagation();\n return;\n }\n if (document.activeElement instanceof HTMLInputElement && e.keyCode in key_numbers) {\n e.stopPropagation();\n return;\n }\n if (!(e.keyCode in keys)) return;\n var index = keys[e.keyCode];\n if (e.shiftKey) index += letters.length;\n index -= 7;\n callback(index);\n}\n\nfunction listen(fn) {\n callback = fn;\n}\n\nexports.default = { listen: listen };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/keys.js\n// module id = 77\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.note_values = exports.MidiWriter = undefined;\n\nvar _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');\n\nvar _slicedToArray3 = _interopRequireDefault(_slicedToArray2);\n\nexports.midi_init = midi_init;\nexports.play_note = play_note;\nexports.play_midi_note = play_midi_note;\nexports.play_sequence = play_sequence;\nexports.play_interval_sequence = play_interval_sequence;\nexports.export_pattern_as_midi = export_pattern_as_midi;\n\nvar _tone = require('tone');\n\nvar _tone2 = _interopRequireDefault(_tone);\n\nvar _webmidi = require('webmidi');\n\nvar _webmidi2 = _interopRequireDefault(_webmidi);\n\nvar _scales = require('./scales');\n\nvar _scales2 = _interopRequireDefault(_scales);\n\nvar _util = require('./util');\n\nvar _kalimba = require('./kalimba');\n\nvar _kalimba2 = _interopRequireDefault(_kalimba);\n\nvar _FileSaver = require('file-saver/FileSaver');\n\nvar _ui = require('./ui');\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar midiDevice = void 0;\nvar sendPitchBend = false;\n\nvar MidiWriter = exports.MidiWriter = require('midi-writer-js');\n\nvar note_values = exports.note_values = [[8, '8 measures', 8 * 512], [4, '4 measures', 4 * 512], [2, '2 measures', 2 * 512], [1, 'whole note', 512], [1 / 2, 'half note', 256], [1 / 3, 'third note', [170, 170, 171]], [1 / 4, 'quarter note', 128], [1 / 5, 'fifth note', [51, 51, 51, 51, 52]], [1 / 6, 'sixth note', [85, 85, 86, 85, 85, 86]], [1 / 8, 'eighth note', 64], [1 / 10, 'tenth note', [25, 26, 26, 25, 26, 25, 26, 26, 25, 26]], [1 / 12, 'twelfth note', [21, 21, 22, 21, 21, 22, 21, 21, 22, 21, 21, 22]], [1 / 16, 'sixteenth note', 32], [1 / 32, 'thirtysecond note', 16]];\n\nfunction midi_init() {\n _webmidi2.default.enable(midi_ready);\n function midi_ready(err) {\n if (err) {\n console.error('webmidi failed to initialize');\n return;\n }\n if (!_webmidi2.default.outputs.length) {\n console.error('no MIDI output found');\n return;\n }\n console.log(_webmidi2.default.inputs);\n console.log(_webmidi2.default.outputs);\n if (_webmidi2.default.outputs.length > 1) {\n var filtered = _webmidi2.default.outputs.filter(function (output) {\n return output.name.match(/prodipe/i);\n });\n if (filtered.length) {\n // midiDevice = filtered[0]\n }\n }\n // midiDevice = midiDevice || WebMidi.outputs[0]\n // console.log(midiDevice.name)\n }\n}\n\n/* play a single note */\n\nfunction play_note(index, duration) {\n var channel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : \"all\";\n var exporting = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n var rest = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;\n var defer = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;\n\n // console.log(index)\n var scale = _scales2.default.current();\n var freq = scale.index(index + Math.round(_ui.nx.offset.value), _ui.nx.octave.value);\n var midi_note = (0, _util.ftom)(freq);\n var cents = midi_note % 1;\n if (cents > 0.5) {\n midi_note += 1;\n cents -= 1;\n }\n cents *= 2;\n midi_note = Math.floor(midi_note);\n if ((midiDevice || exporting) && midi_note > 127) return 0;\n var note = _tone2.default.Frequency(Math.floor(midi_note), \"midi\").toNote();\n var defer_time = 30000 / _tone2.default.Transport.bpm.value * defer / 128;\n console.log(defer, defer_time);\n if (exporting) {\n return note;\n }\n if (midiDevice) {\n duration = duration || 60000 / _tone2.default.Transport.bpm.value;\n if (!exporting) {\n if (defer) {\n setTimeout(function () {\n play_midi_note(note, cents, channel, duration);\n }, defer);\n } else {\n play_midi_note(note, cents, channel, duration);\n }\n }\n } else if (defer) {\n setTimeout(function () {\n _kalimba2.default.play(freq);\n }, defer_time);\n } else {\n _kalimba2.default.play(freq);\n }\n return note;\n}\n\nfunction play_midi_note(note, cents, channel, duration) {\n midiDevice.playNote(note, channel, { duration: duration });\n if (sendPitchBend) {\n midiDevice.sendPitchBend(cents, channel);\n }\n}\n\n/* play the next note in sequence */\n\nfunction play_sequence(i, bounds, diff, note_time) {\n var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : \"all\";\n var exporting = arguments[5];\n var rows = bounds.rows,\n min = bounds.min,\n max = bounds.max;\n\n var count = rows.length * rows[0].length;\n if (i >= count) i = 0;\n var y = Math.floor(i / rows[0].length);\n var x = i % rows[0].length;\n // if (!x) console.log(y)\n var n = rows[y][x];\n i += 1;\n if (i >= count) i = 0;\n var midi_note = play_note((0, _util.norm)(n, min, max) * _ui.nx.multiply.value, note_time, channel, exporting);\n return [i, [midi_note]];\n}\n\n/* play the next row as an interval */\n\nfunction play_interval_sequence(i, bounds, diff, note_time) {\n var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : \"all\";\n var exporting = arguments[5];\n var rows = bounds.rows,\n min = bounds.min,\n max = bounds.max;\n\n var count = rows.length;\n if (i >= count) i = 0;\n var y = i % count;\n var row = rows[y];\n if (!row) {\n i = 0;return;\n }\n var row_min = Math.min.apply(Math, row);\n // const row_max = Math.max.apply(Math, row)\n var row_f0 = (0, _util.norm)(row_min, min, max);\n var row_root = row_f0 * _ui.nx.multiply.value;\n var notes = row.map(function (n) {\n var note = row_root + (0, _util.norm)(n - row_min, diff.min, diff.max) * _ui.nx.interval.value;\n play_note(note, note_time, channel, exporting);\n });\n i += 1;\n return [i, notes];\n}\n\n/* generate a 1-track midi file by calling the play function repeatedly */\n\nfunction export_pattern_as_midi(datasetName, bounds, diff, tempo, timingIndex, play_fn) {\n // const behavior = document.querySelector('#behavior').value\n var rows = bounds.rows;\n // let count = behavior === 'sequence' ? rows[0].length * rows.length : rows.length\n\n var count = rows[0].length;\n var notes = void 0,\n timings = void 0,\n wait = void 0;\n var note_time = void 0;\n // let timing = note_values[timingIndex][2]\n var midi_track = new MidiWriter.Track();\n midi_track.setTempo(tempo);\n for (var i = 0, len = count; i < len; i++) {\n // if (timing.length) {\n // note_time = timing[i % timing.length]\n // } else {\n // note_time = timing\n // }\n // midi_track.addEvent(new MidiWriter.NoteEvent({ pitch: notes, duration: 't' + note_time }))\n var _play_fn = play_fn(i, bounds, note_time, \"all\", true);\n\n var _play_fn2 = (0, _slicedToArray3.default)(_play_fn, 4);\n\n i = _play_fn2[0];\n notes = _play_fn2[1];\n timings = _play_fn2[2];\n wait = _play_fn2[3];\n console.log(i, notes, timings, wait);\n for (var j = 0; j < notes.length; j++) {\n midi_track.addEvent(new MidiWriter.NoteEvent({\n pitch: notes[j],\n duration: 't' + timings[j],\n wait: j === 0 ? wait : 0\n }));\n }\n }\n var writer = new MidiWriter.Writer([midi_track]);\n var blob = (0, _util.dataURItoBlob)(writer.dataUri());\n (0, _FileSaver.saveAs)(blob, 'Recording - ' + datasetName + '.mid');\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/midi.js\n// module id = 78\n// module chunks = 0","\"use strict\";\n\nexports.__esModule = true;\n\nvar _from = require(\"../core-js/array/from\");\n\nvar _from2 = _interopRequireDefault(_from);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nexports.default = function (arr) {\n return Array.isArray(arr) ? arr : (0, _from2.default)(arr);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/babel-runtime/helpers/toArray.js\n// module id = 79\n// module chunks = 0","'use strict';\n\nvar _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');\n\nvar _slicedToArray3 = _interopRequireDefault(_slicedToArray2);\n\nvar _toArray2 = require('babel-runtime/helpers/toArray');\n\nvar _toArray3 = _interopRequireDefault(_toArray2);\n\nvar _tone = require('tone');\n\nvar _tone2 = _interopRequireDefault(_tone);\n\nvar _nexusui = require('nexusui');\n\nvar _nexusui2 = _interopRequireDefault(_nexusui);\n\nvar _keys = require('./lib/keys');\n\nvar _keys2 = _interopRequireDefault(_keys);\n\nvar _scales = require('./lib/scales');\n\nvar _scales2 = _interopRequireDefault(_scales);\n\nvar _kalimba = require('./lib/kalimba');\n\nvar _kalimba2 = _interopRequireDefault(_kalimba);\n\nvar _midi = require('./lib/midi');\n\nvar _util = require('./lib/util');\n\nvar _ui = require('./lib/ui');\n\nvar _data = require('./data');\n\nvar data = _interopRequireWildcard(_data);\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar DEFAULT_BPM = 60;\n\nvar recorder = null;\nvar recording = false;\n\n(0, _midi.midi_init)();\n\n/* initialization */\n\nvar mass_fields = [\"date\", \"timestamp\", \"fatalities\", \"injured\", \"total_victims\", \"age\", \"case\", \"weapon_type\", \"weapon_details\"].reduce(function (a, b, i) {\n a[b] = i;\n return a;\n}, {});\n\nvar i = 0,\n mass_i = 0,\n datasets = {},\n dataset = {},\n bounds = {},\n diff = [];\nvar play_fn = _midi.play_sequence;\ndata.load().then(function (lists) {\n console.log(lists);\n (0, _util.transpose)(lists.gun_violence_by_month.lines).forEach(function (row, i) {\n var name = lists.gun_violence_by_month.h[i];\n if (name === 'Date') return;\n console.log(name, row);\n datasets[name] = {\n name: name,\n h: [name],\n lines: [row.map(function (n) {\n return parseInt(n);\n })],\n play_fn: _midi.play_sequence\n };\n });\n datasets[\"Mass Shootings\"] = lists.mass_shootings_lite;\n datasets[\"Mass Shootings\"].name = \"Mass Shootings\";\n datasets[\"Mass Shootings\"].play_fn = play_mass_shootings;\n var lines = datasets[\"Mass Shootings\"].lines.reverse();\n\n var _lines$0$mass_fields$ = lines[0][mass_fields.date].split('/'),\n _lines$0$mass_fields$2 = (0, _toArray3.default)(_lines$0$mass_fields$),\n min_y = _lines$0$mass_fields$2[0],\n rest = _lines$0$mass_fields$2.slice(1);\n\n datasets[\"Mass Shootings\"].dates = lines.map(function (row) {\n var _row$mass_fields$date = row[mass_fields.date].split('/'),\n _row$mass_fields$date2 = (0, _slicedToArray3.default)(_row$mass_fields$date, 3),\n y = _row$mass_fields$date2[0],\n m = _row$mass_fields$date2[1],\n d = _row$mass_fields$date2[2];\n\n return (parseInt(y) - parseInt(min_y)) * 12 + parseInt(m);\n });\n datasets[\"Mass Shootings\"].data = lines;\n datasets[\"Mass Shootings\"].lines = [lines.map(function (row) {\n return row[mass_fields.total_victims];\n })];\n (0, _util.requestAudioContext)(ready);\n});\n\n/* play function for mass shooting data w/ custom timing */\n\nvar mass_rest = 0;\n\n// export const note_values = [\n// [8, '8 measures', 8 * 512],\n// [4, '4 measures', 4 * 512],\n// [2, '2 measures', 2 * 512],\n// [1, 'whole note', 512],\n// [1/2, 'half note', 256],\n// [1/3, 'third note', [170, 170, 171]],\n// [1/4, 'quarter note', 128],\n// [1/5, 'fifth note', [51,51,51,51,52]],\n// [1/6, 'sixth note', [85, 85, 86, 85, 85, 86]],\n// [1/8, 'eighth note', 64],\n// [1/10, 'tenth note', [25,26,26,25,26,25,26,26,25,26]],\n// [1/12, 'twelfth note', [21,21,22, 21,21,22, 21,21,22, 21,21,22]],\n// [1/16, 'sixteenth note', 32],\n// [1/32, 'thirtysecond note', 16],\n// ]\n\nfunction play_mass_shootings(i, bounds, diff, note_time) {\n var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : \"all\";\n var exporting = arguments[5];\n var rows = bounds.rows,\n min = bounds.min,\n max = bounds.max;\n\n var y = 0;\n var x = i % rows[0].length;\n var n = rows[y][x];\n var total = dataset.dates.length;\n var notes = [],\n midi_notes = [],\n cases = [],\n timings = void 0;\n console.log(i, mass_i, dataset.dates[mass_i]);\n while (i >= dataset.dates[mass_i] && mass_i < total) {\n notes.push(dataset.lines[0][mass_i]);\n cases.push(dataset.data[mass_i][mass_fields.date] + ' ' + dataset.data[mass_i][mass_fields.case] + \", \" + dataset.data[mass_i][mass_fields.fatalities] + ' dead, ' + dataset.data[mass_i][mass_fields.injured] + ' injured');\n console.log('push case', dataset.data[mass_i][mass_fields.date] + ' ' + dataset.data[mass_i][mass_fields.case]);\n mass_i += 1;\n }\n switch (notes.length) {\n default:\n case 0:\n mass_rest += 1;\n break;\n case 1:\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 128, channel, exporting, mass_rest, 0));\n timings = [128];\n break;\n case 2:\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 64, channel, exporting, mass_rest, 0));\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[1], min, max) * _ui.nx.multiply.value, 64, channel, exporting, 0, 64));\n timings = [64, 64];\n break;\n case 3:\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 43, channel, exporting, mass_rest, 0));\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[1], min, max) * _ui.nx.multiply.value, 43, channel, exporting, 0, 43));\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[2], min, max) * _ui.nx.multiply.value, 42, channel, exporting, 0, 85));\n timings = [43, 43, 42];\n break;\n case 4:\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 32, channel, exporting, mass_rest, 0));\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[1], min, max) * _ui.nx.multiply.value, 32, channel, exporting, 0, 32));\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[2], min, max) * _ui.nx.multiply.value, 32, channel, exporting, 0, 64));\n midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[3], min, max) * _ui.nx.multiply.value, 32, channel, exporting, 0, 96));\n timings = [32, 32, 32, 32];\n break;\n }\n if (cases.length) {\n document.querySelector('#cases').innerHTML = cases.join('<br>');\n }\n if (total <= mass_i) {\n mass_rest = 0;\n mass_i = 0;\n i = 0;\n } else {\n i += 1;\n }\n _kalimba2.default.play(220, -12);\n if (notes.length) {\n mass_rest = 0;\n return [i, midi_notes, timings, mass_rest];\n }\n mass_rest += 128;\n return [i, [], [], 0];\n}\n\n/* play next note according to sonification */\n\nfunction play_next() {\n var note_time = 120000 / _tone2.default.Transport.bpm.value * _midi.note_values[_ui.nx.timing.active][0];\n setTimeout(play_next, note_time);\n\n var _play_fn = play_fn(i, bounds, diff, note_time),\n _play_fn2 = (0, _slicedToArray3.default)(_play_fn, 3),\n new_i = _play_fn2[0],\n notes = _play_fn2[1],\n timings = _play_fn2[2];\n\n i = new_i;\n if (recording) {\n var timing = _midi.note_values[_ui.nx.timing.active][2];\n if (timing.length) timing = timing[i % timing.length];\n recorder.addEvent(new _midi.MidiWriter.NoteEvent({ pitch: notes, duration: 't' + timing }));\n }\n}\n\n/* bind selects */\n\nfunction pick_dataset(key) {\n console.log('pick dataset:', key, datasets[key]);\n i = 0;\n mass_i = 0;\n mass_rest = 0;\n dataset = datasets[key];\n bounds = (0, _util.get_bounds)(dataset);\n diff = (0, _util.get_diff_bounds)(bounds.rows);\n play_fn = dataset.play_fn;\n}\n\n/* build and bind the UI */\n\nfunction ready() {\n _scales2.default.build_options(document.querySelector('#scale'));\n (0, _ui.build_options)(document.querySelector('#dataset'), datasets, pick_dataset);\n\n var dial_size = [50, 50];\n\n _tone2.default.Transport.bpm.value = DEFAULT_BPM;\n _ui.nx.tempo = new _nexusui2.default.Dial('#tempo', {\n size: dial_size,\n min: 10,\n max: 300,\n step: 1,\n value: DEFAULT_BPM\n });\n (0, _ui.update_value_on_change)(_ui.nx.tempo, '#tempo', true, function (v) {\n return _tone2.default.Transport.bpm.value = v;\n });\n\n _ui.nx.timing = new _nexusui2.default.RadioButton('#timing', {\n size: [400, 25],\n numberOfButtons: _midi.note_values.length,\n active: 6\n });\n (0, _ui.update_radio_value_on_change)(_ui.nx.timing, '#timing', _midi.note_values);\n\n _ui.nx.duration = new _nexusui2.default.Dial('#duration', {\n size: dial_size,\n min: 0,\n max: 2,\n step: 0.01,\n value: 0.8\n });\n (0, _ui.update_value_on_change)(_ui.nx.duration, '#duration', false);\n\n _ui.nx.offset = new _nexusui2.default.Dial('#offset', {\n size: dial_size,\n min: -24,\n max: 24,\n step: 1,\n value: -5\n });\n (0, _ui.update_value_on_change)(_ui.nx.offset, '#offset', true);\n\n _ui.nx.octave = new _nexusui2.default.Dial('#octave', {\n size: dial_size,\n min: -4,\n max: 4,\n step: 1,\n value: 0\n });\n (0, _ui.update_value_on_change)(_ui.nx.octave, '#octave', true);\n\n _ui.nx.multiply = new _nexusui2.default.Dial('#multiply', {\n size: dial_size,\n min: -64,\n max: 64,\n step: 1,\n value: 17\n });\n (0, _ui.update_value_on_change)(_ui.nx.multiply, '#multiply', true);\n\n _ui.nx.interval = new _nexusui2.default.Dial('#interval', {\n size: dial_size,\n min: -64,\n max: 64,\n step: 1,\n value: 10\n });\n (0, _ui.update_value_on_change)(_ui.nx.interval, '#interval', true);\n\n var export_midi_button = document.querySelector('#export_midi');\n export_midi_button.addEventListener('click', function () {\n (0, _midi.export_pattern_as_midi)(dataset.name, bounds, diff, _ui.nx.tempo.value, _ui.nx.timing.active, play_fn);\n });\n\n var record_midi_button = document.querySelector('#record_midi');\n record_midi_button.addEventListener('click', function () {\n if (recording) {\n record_midi_button.innerHTML = 'Record MIDI';\n document.body.classList.remove('recording');\n recording = false;\n var writer = new _midi.MidiWriter.Writer([recorder]);\n var blob = (0, _util.dataURItoBlob)(writer.dataUri());\n saveAs(blob, 'Recording - ' + dataset.name + '.mid');\n } else {\n record_midi_button.innerHTML = 'Save Recording';\n document.body.classList.add('recording');\n recording = true;\n recorder = new _midi.MidiWriter.Track();\n recorder.setTempo(_ui.nx.tempo.value);\n }\n });\n\n document.querySelector('.loading').classList.remove('loading');\n\n document.querySelector('#dataset').value = 'Mass Shootings';\n pick_dataset('Mass Shootings');\n\n document.querySelector('#scale').value = '14';\n _scales2.default.pick(14);\n\n play_next();\n}\n\n/* keys */\n\n_keys2.default.listen(function (index) {\n _ui.nx.offset.value = index;\n _ui.nx.offset.update(index);\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/index.js\n// module id = 80\n// module chunks = 0","\"use strict\";\n\nvar _assign = require(\"babel-runtime/core-js/object/assign\");\n\nvar _assign2 = _interopRequireDefault(_assign);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nmodule.exports = function () {\n var Intonation = function Intonation(opt) {\n opt = this.opt = (0, _assign2.default)({\n name: \"\",\n root: 440,\n octave: 0,\n interval: 2,\n tet: 0,\n intervals: null\n }, opt || {});\n this.generate();\n };\n Intonation.prototype.generate = function (opt) {\n opt = (0, _assign2.default)(this.opt, opt || {});\n if (opt.scl) {\n this.generate_scl();\n } else if (opt.tet) {\n this.generate_tet();\n } else if (opt.intervals) {\n this.generate_intervals();\n }\n };\n Intonation.prototype.generate_intervals = function () {\n var root = this.opt.root;\n var interval_list = this.opt.intervals;\n if (typeof interval_list == \"string\") {\n interval_list = interval_list.split(\" \");\n }\n this.name = this.opt.name || \"interval list\";\n this.intervals = interval_list;\n this.interval = this.opt.interval = parseInterval.call(this, interval_list.pop());\n this.scale = interval_list.map(parseIntervalString.bind(this)).filter(function (v) {\n return !!v;\n });\n };\n Intonation.prototype.generate_tet = function () {\n var scale = this.scale = [];\n var root = this.opt.root;\n var tet = this.opt.tet;\n var interval = this.interval = this.opt.interval;\n var ratio = Math.pow(interval, 1 / tet);\n var n = root;\n scale.push(n);\n for (var i = 0; i < tet - 1; i++) {\n n *= ratio;\n scale.push(n);\n }\n this.name = this.opt.name || tet + \"-tone equal temperament\";\n this.intervals = null;\n };\n Intonation.prototype.generate_scl = function () {\n var root = this.opt.root;\n var scl = this.parse_scl(this.opt.scl);\n this.intervals = scl.notes;\n this.interval = scl.notes.pop();\n this.name = this.opt.name || scl.description;\n this.scale = scl.notes.map(function (v) {\n return v * root;\n });\n };\n Intonation.prototype.parse_scl = function (s) {\n var scl = {};\n scl.comments = [];\n scl.notes = [];\n s.trim().split(\"\\n\").forEach(function (line) {\n // Lines beginning with an exclamation mark are regarded as comments\n // and are to be ignored.\n if (line.indexOf(\"!\") !== -1) {\n scl.comments.push(line);\n }\n // The first (non comment) line contains a short description of the scale.\n // If there is no description, there should be an empty line. (nb: which is falsey)\n else if (!('description' in scl)) {\n scl.description = line;\n }\n // The second line contains the number of notes.\n // The first note of 1/1 or 0.0 cents is implicit and not in the files.\n else if (!scl.notes.length) {\n scl.notes.push(1);\n } else {\n // If the value contains a period, it is a cents value, otherwise a ratio.\n var note = line.replace(/^[^-\\.0-9]+/, \"\").replace(/[^-\\/\\.0-9]+$/, \"\");\n if (note.indexOf(\".\") !== -1) {\n note = Math.pow(2, parseFloat(note) / 1200);\n } else {\n note = parseInterval(note);\n }\n if (note) {\n scl.notes.push(note);\n }\n }\n });\n return scl;\n };\n Intonation.prototype.index = function (i, octave) {\n octave = octave || this.opt.octave;\n var f = this.scale[mod(i, this.scale.length) | 0];\n var pow = Math.floor(norm(i, 0, this.scale.length)) + octave;\n f *= Math.pow(this.interval, pow);\n return f;\n };\n Intonation.prototype.range = function (min, max) {\n var a = [];\n for (var i = min; i < max; i++) {\n a.push(this.index(i));\n }\n return a;\n };\n Intonation.prototype.set_root = function (f) {\n this.opt.root = f;\n this.generate();\n };\n Intonation.prototype.quantize_frequency = function (f) {\n if (f == 0) return 0;\n var scale_f = f;\n var pow = 0;\n var interval = this.interval;\n var scale = this.scale;\n while (scale_f < root) {\n scale_f *= interval;\n pow -= 1;\n }\n while (scale_f > root * interval) {\n scale_f /= interval;\n pow += 1;\n }\n for (var i = 0; i < scale.length; i++) {\n if (scale_f > scale[i]) continue;\n scale_f = scale[i];\n break;\n }\n scale_f *= Math.pow(2, pow);\n return scale_f;\n };\n Intonation.prototype.quantize_index = function (i) {\n return mod(index - 1, this.scale.length) | 0;\n };\n var parseInterval = Intonation.prototype.parse_interval = function (s) {\n if (typeof s == \"number\") return s;\n if (!s.indexOf(\"/\") == -1) return parseInt(s);\n var pp = s.split(\"/\");\n var num = parseInt(pp[0]);\n var den = parseInt(pp[1]);\n if (isNaN(num)) return 1;\n if (isNaN(den) || den == 0) return num;\n if (num == den) return 1;\n return num / den;\n };\n var parseIntervalString = Intonation.prototype.parse_interval_string = function (s) {\n if (s.indexOf(\"/\") !== -1) return parseInterval(s) * this.opt.root; // intervals\n if (s.indexOf(\"f\") !== -1) return parseFloat(s); // pure frequencies\n return parseFloat(s);\n };\n function norm(n, a, b) {\n return (n - a) / (b - a);\n }\n function mod(n, m) {\n return n - m * Math.floor(n / m);\n }\n\n return Intonation;\n}();\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/intonation.js\n// module id = 81\n// module chunks = 0","\"use strict\";\n\nvar _typeof2 = require(\"babel-runtime/helpers/typeof\");\n\nvar _typeof3 = _interopRequireDefault(_typeof2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * StartAudioContext.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2016 Yotam Mann\n */\n(function (root, factory) {\n if (typeof define === \"function\" && define.amd) {\n define([], factory);\n } else if ((typeof module === \"undefined\" ? \"undefined\" : (0, _typeof3.default)(module)) === 'object' && module.exports) {\n module.exports = factory();\n } else {\n root.StartAudioContext = factory();\n }\n})(undefined, function () {\n\n /**\n * The StartAudioContext object\n */\n var StartAudioContext = {\n /**\n * The audio context passed in by the user\n * @type {AudioContext}\n */\n context: null,\n /**\n * The TapListeners bound to the elements\n * @type {Array}\n * @private\n */\n _tapListeners: [],\n /**\n * Callbacks to invoke when the audio context is started\n * @type {Array}\n * @private\n */\n _onStarted: []\n };\n\n /**\n * Set the context\n * @param {AudioContext} ctx\n * @returns {StartAudioContext}\n */\n StartAudioContext.setContext = function (ctx) {\n StartAudioContext.context = ctx;\n return StartAudioContext;\n };\n\n /**\n * Add a tap listener to the audio context\n * @param {Array|Element|String|jQuery} element\n * @returns {StartAudioContext}\n */\n StartAudioContext.on = function (element) {\n if (Array.isArray(element) || NodeList && element instanceof NodeList) {\n for (var i = 0; i < element.length; i++) {\n StartAudioContext.on(element[i]);\n }\n } else if (typeof element === \"string\") {\n StartAudioContext.on(document.querySelectorAll(element));\n } else if (element.jquery && typeof element.toArray === \"function\") {\n StartAudioContext.on(element.toArray());\n } else if (Element && element instanceof Element) {\n //if it's an element, create a TapListener\n var tap = new TapListener(element, onTap);\n StartAudioContext._tapListeners.push(tap);\n }\n return StartAudioContext;\n };\n\n /**\n * Bind a callback to when the audio context is started. \n * @param {Function} cb\n * @return {StartAudioContext}\n */\n StartAudioContext.onStarted = function (cb) {\n //if it's already started, invoke the callback\n if (StartAudioContext.isStarted()) {\n cb();\n } else {\n StartAudioContext._onStarted.push(cb);\n }\n return StartAudioContext;\n };\n\n /**\n * returns true if the context is started\n * @return {Boolean}\n */\n StartAudioContext.isStarted = function () {\n return StartAudioContext.context !== null && StartAudioContext.context.state === \"running\";\n };\n\n /**\n * @class Listens for non-dragging tap ends on the given element\n * @param {Element} element\n * @internal\n */\n var TapListener = function TapListener(element) {\n\n this._dragged = false;\n\n this._element = element;\n\n this._bindedMove = this._moved.bind(this);\n this._bindedEnd = this._ended.bind(this);\n\n element.addEventListener(\"touchmove\", this._bindedMove);\n element.addEventListener(\"touchend\", this._bindedEnd);\n element.addEventListener(\"mouseup\", this._bindedEnd);\n };\n\n /**\n * drag move event\n */\n TapListener.prototype._moved = function (e) {\n this._dragged = true;\n };\n\n /**\n * tap ended listener\n */\n TapListener.prototype._ended = function (e) {\n if (!this._dragged) {\n onTap();\n }\n this._dragged = false;\n };\n\n /**\n * remove all the bound events\n */\n TapListener.prototype.dispose = function () {\n this._element.removeEventListener(\"touchmove\", this._bindedMove);\n this._element.removeEventListener(\"touchend\", this._bindedEnd);\n this._element.removeEventListener(\"mouseup\", this._bindedEnd);\n this._bindedMove = null;\n this._bindedEnd = null;\n this._element = null;\n };\n\n /**\n * Invoked the first time of the elements is tapped.\n * Creates a silent oscillator when a non-dragging touchend \n * event has been triggered.\n */\n function onTap() {\n //start the audio context with a silent oscillator\n if (StartAudioContext.context && !StartAudioContext.isStarted()) {\n var osc = StartAudioContext.context.createOscillator();\n var silent = StartAudioContext.context.createGain();\n silent.gain.value = 0;\n osc.connect(silent);\n silent.connect(StartAudioContext.context.destination);\n var now = StartAudioContext.context.currentTime;\n osc.start(now);\n osc.stop(now + 0.5);\n }\n\n //dispose all the tap listeners\n if (StartAudioContext._tapListeners) {\n for (var i = 0; i < StartAudioContext._tapListeners.length; i++) {\n StartAudioContext._tapListeners[i].dispose();\n }\n StartAudioContext._tapListeners = null;\n }\n //the onstarted callbacks\n if (StartAudioContext._onStarted) {\n for (var j = 0; j < StartAudioContext._onStarted.length; j++) {\n StartAudioContext._onStarted[j]();\n }\n StartAudioContext._onStarted = null;\n }\n }\n\n return StartAudioContext;\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/lib/startAudioContext.js\n// module id = 82\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/array/from\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/babel-runtime/core-js/array/from.js\n// module id = 83\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/get-iterator\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/babel-runtime/core-js/get-iterator.js\n// module id = 84\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/is-iterable\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/babel-runtime/core-js/is-iterable.js\n// module id = 85\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/math/log2\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/babel-runtime/core-js/math/log2.js\n// module id = 86\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/object/keys\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/babel-runtime/core-js/object/keys.js\n// module id = 87\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/promise\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/babel-runtime/core-js/promise.js\n// module id = 88\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/symbol\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/babel-runtime/core-js/symbol.js\n// module id = 89\n// module chunks = 0","module.exports = { \"default\": require(\"core-js/library/fn/symbol/iterator\"), __esModule: true };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/babel-runtime/core-js/symbol/iterator.js\n// module id = 90\n// module chunks = 0","\"use strict\";\n\nexports.__esModule = true;\n\nvar _iterator = require(\"../core-js/symbol/iterator\");\n\nvar _iterator2 = _interopRequireDefault(_iterator);\n\nvar _symbol = require(\"../core-js/symbol\");\n\nvar _symbol2 = _interopRequireDefault(_symbol);\n\nvar _typeof = typeof _symbol2.default === \"function\" && typeof _iterator2.default === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof _symbol2.default === \"function\" && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? \"symbol\" : typeof obj; };\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nexports.default = typeof _symbol2.default === \"function\" && _typeof(_iterator2.default) === \"symbol\" ? function (obj) {\n return typeof obj === \"undefined\" ? \"undefined\" : _typeof(obj);\n} : function (obj) {\n return obj && typeof _symbol2.default === \"function\" && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? \"symbol\" : typeof obj === \"undefined\" ? \"undefined\" : _typeof(obj);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/babel-runtime/helpers/typeof.js\n// module id = 91\n// module chunks = 0","'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction placeHoldersCount (b64) {\n var len = b64.length\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // the number of equal signs (place holders)\n // if there are two placeholders, than the two characters before it\n // represent one byte\n // if there is only one, then the three characters before it represent 2 bytes\n // this is just a cheap hack to not do indexOf twice\n return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0\n}\n\nfunction byteLength (b64) {\n // base64 is 4/3 + up to two characters of the original data\n return b64.length * 3 / 4 - placeHoldersCount(b64)\n}\n\nfunction toByteArray (b64) {\n var i, j, l, tmp, placeHolders, arr\n var len = b64.length\n placeHolders = placeHoldersCount(b64)\n\n arr = new Arr(len * 3 / 4 - placeHolders)\n\n // if there are placeholders, only get up to the last complete 4 chars\n l = placeHolders > 0 ? len - 4 : len\n\n var L = 0\n\n for (i = 0, j = 0; i < l; i += 4, j += 3) {\n tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]\n arr[L++] = (tmp >> 16) & 0xFF\n arr[L++] = (tmp >> 8) & 0xFF\n arr[L++] = tmp & 0xFF\n }\n\n if (placeHolders === 2) {\n tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[L++] = tmp & 0xFF\n } else if (placeHolders === 1) {\n tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[L++] = (tmp >> 8) & 0xFF\n arr[L++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var output = ''\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n output += lookup[tmp >> 2]\n output += lookup[(tmp << 4) & 0x3F]\n output += '=='\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + (uint8[len - 1])\n output += lookup[tmp >> 10]\n output += lookup[(tmp >> 4) & 0x3F]\n output += lookup[(tmp << 2) & 0x3F]\n output += '='\n }\n\n parts.push(output)\n\n return parts.join('')\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/base64-js/index.js\n// module id = 92\n// module chunks = 0","require('../../modules/es6.string.iterator');\nrequire('../../modules/es6.array.from');\nmodule.exports = require('../../modules/_core').Array.from;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/fn/array/from.js\n// module id = 93\n// module chunks = 0","require('../modules/web.dom.iterable');\nrequire('../modules/es6.string.iterator');\nmodule.exports = require('../modules/core.get-iterator');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/fn/get-iterator.js\n// module id = 94\n// module chunks = 0","require('../modules/web.dom.iterable');\nrequire('../modules/es6.string.iterator');\nmodule.exports = require('../modules/core.is-iterable');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/fn/is-iterable.js\n// module id = 95\n// module chunks = 0","require('../../modules/es6.math.log2');\nmodule.exports = require('../../modules/_core').Math.log2;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/fn/math/log2.js\n// module id = 96\n// module chunks = 0","require('../../modules/es6.object.assign');\nmodule.exports = require('../../modules/_core').Object.assign;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/fn/object/assign.js\n// module id = 97\n// module chunks = 0","require('../../modules/es6.object.keys');\nmodule.exports = require('../../modules/_core').Object.keys;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/fn/object/keys.js\n// module id = 98\n// module chunks = 0","require('../modules/es6.object.to-string');\nrequire('../modules/es6.string.iterator');\nrequire('../modules/web.dom.iterable');\nrequire('../modules/es6.promise');\nmodule.exports = require('../modules/_core').Promise;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/fn/promise.js\n// module id = 99\n// module chunks = 0","require('../../modules/es6.symbol');\nrequire('../../modules/es6.object.to-string');\nrequire('../../modules/es7.symbol.async-iterator');\nrequire('../../modules/es7.symbol.observable');\nmodule.exports = require('../../modules/_core').Symbol;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/fn/symbol/index.js\n// module id = 100\n// module chunks = 0","require('../../modules/es6.string.iterator');\nrequire('../../modules/web.dom.iterable');\nmodule.exports = require('../../modules/_wks-ext').f('iterator');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/fn/symbol/iterator.js\n// module id = 101\n// module chunks = 0","module.exports = function(){ /* empty */ };\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_add-to-unscopables.js\n// module id = 102\n// module chunks = 0","module.exports = function(it, Constructor, name, forbiddenField){\n if(!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)){\n throw TypeError(name + ': incorrect invocation!');\n } return it;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_an-instance.js\n// module id = 103\n// module chunks = 0","// false -> Array#indexOf\n// true -> Array#includes\nvar toIObject = require('./_to-iobject')\n , toLength = require('./_to-length')\n , toIndex = require('./_to-index');\nmodule.exports = function(IS_INCLUDES){\n return function($this, el, fromIndex){\n var O = toIObject($this)\n , length = toLength(O.length)\n , index = toIndex(fromIndex, length)\n , value;\n // Array#includes uses SameValueZero equality algorithm\n if(IS_INCLUDES && el != el)while(length > index){\n value = O[index++];\n if(value != value)return true;\n // Array#toIndex ignores holes, Array#includes - not\n } else for(;length > index; index++)if(IS_INCLUDES || index in O){\n if(O[index] === el)return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_array-includes.js\n// module id = 104\n// module chunks = 0","'use strict';\nvar $defineProperty = require('./_object-dp')\n , createDesc = require('./_property-desc');\n\nmodule.exports = function(object, index, value){\n if(index in object)$defineProperty.f(object, index, createDesc(0, value));\n else object[index] = value;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_create-property.js\n// module id = 105\n// module chunks = 0","// all enumerable object keys, includes symbols\nvar getKeys = require('./_object-keys')\n , gOPS = require('./_object-gops')\n , pIE = require('./_object-pie');\nmodule.exports = function(it){\n var result = getKeys(it)\n , getSymbols = gOPS.f;\n if(getSymbols){\n var symbols = getSymbols(it)\n , isEnum = pIE.f\n , i = 0\n , key;\n while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))result.push(key);\n } return result;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_enum-keys.js\n// module id = 106\n// module chunks = 0","var ctx = require('./_ctx')\n , call = require('./_iter-call')\n , isArrayIter = require('./_is-array-iter')\n , anObject = require('./_an-object')\n , toLength = require('./_to-length')\n , getIterFn = require('./core.get-iterator-method')\n , BREAK = {}\n , RETURN = {};\nvar exports = module.exports = function(iterable, entries, fn, that, ITERATOR){\n var iterFn = ITERATOR ? function(){ return iterable; } : getIterFn(iterable)\n , f = ctx(fn, that, entries ? 2 : 1)\n , index = 0\n , length, step, iterator, result;\n if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!');\n // fast case for arrays with default iterator\n if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){\n result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);\n if(result === BREAK || result === RETURN)return result;\n } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){\n result = call(iterator, f, step.value, entries);\n if(result === BREAK || result === RETURN)return result;\n }\n};\nexports.BREAK = BREAK;\nexports.RETURN = RETURN;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_for-of.js\n// module id = 107\n// module chunks = 0","// fast apply, http://jsperf.lnkit.com/fast-apply/5\nmodule.exports = function(fn, args, that){\n var un = that === undefined;\n switch(args.length){\n case 0: return un ? fn()\n : fn.call(that);\n case 1: return un ? fn(args[0])\n : fn.call(that, args[0]);\n case 2: return un ? fn(args[0], args[1])\n : fn.call(that, args[0], args[1]);\n case 3: return un ? fn(args[0], args[1], args[2])\n : fn.call(that, args[0], args[1], args[2]);\n case 4: return un ? fn(args[0], args[1], args[2], args[3])\n : fn.call(that, args[0], args[1], args[2], args[3]);\n } return fn.apply(that, args);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_invoke.js\n// module id = 108\n// module chunks = 0","// 7.2.2 IsArray(argument)\nvar cof = require('./_cof');\nmodule.exports = Array.isArray || function isArray(arg){\n return cof(arg) == 'Array';\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_is-array.js\n// module id = 109\n// module chunks = 0","'use strict';\nvar create = require('./_object-create')\n , descriptor = require('./_property-desc')\n , setToStringTag = require('./_set-to-string-tag')\n , IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\nrequire('./_hide')(IteratorPrototype, require('./_wks')('iterator'), function(){ return this; });\n\nmodule.exports = function(Constructor, NAME, next){\n Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)});\n setToStringTag(Constructor, NAME + ' Iterator');\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_iter-create.js\n// module id = 110\n// module chunks = 0","module.exports = function(done, value){\n return {value: value, done: !!done};\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_iter-step.js\n// module id = 111\n// module chunks = 0","var getKeys = require('./_object-keys')\n , toIObject = require('./_to-iobject');\nmodule.exports = function(object, el){\n var O = toIObject(object)\n , keys = getKeys(O)\n , length = keys.length\n , index = 0\n , key;\n while(length > index)if(O[key = keys[index++]] === el)return key;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_keyof.js\n// module id = 112\n// module chunks = 0","var META = require('./_uid')('meta')\n , isObject = require('./_is-object')\n , has = require('./_has')\n , setDesc = require('./_object-dp').f\n , id = 0;\nvar isExtensible = Object.isExtensible || function(){\n return true;\n};\nvar FREEZE = !require('./_fails')(function(){\n return isExtensible(Object.preventExtensions({}));\n});\nvar setMeta = function(it){\n setDesc(it, META, {value: {\n i: 'O' + ++id, // object ID\n w: {} // weak collections IDs\n }});\n};\nvar fastKey = function(it, create){\n // return primitive with prefix\n if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;\n if(!has(it, META)){\n // can't set metadata to uncaught frozen object\n if(!isExtensible(it))return 'F';\n // not necessary to add metadata\n if(!create)return 'E';\n // add missing metadata\n setMeta(it);\n // return object ID\n } return it[META].i;\n};\nvar getWeak = function(it, create){\n if(!has(it, META)){\n // can't set metadata to uncaught frozen object\n if(!isExtensible(it))return true;\n // not necessary to add metadata\n if(!create)return false;\n // add missing metadata\n setMeta(it);\n // return hash weak collections IDs\n } return it[META].w;\n};\n// add metadata on freeze-family methods calling\nvar onFreeze = function(it){\n if(FREEZE && meta.NEED && isExtensible(it) && !has(it, META))setMeta(it);\n return it;\n};\nvar meta = module.exports = {\n KEY: META,\n NEED: false,\n fastKey: fastKey,\n getWeak: getWeak,\n onFreeze: onFreeze\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_meta.js\n// module id = 113\n// module chunks = 0","var global = require('./_global')\n , macrotask = require('./_task').set\n , Observer = global.MutationObserver || global.WebKitMutationObserver\n , process = global.process\n , Promise = global.Promise\n , isNode = require('./_cof')(process) == 'process';\n\nmodule.exports = function(){\n var head, last, notify;\n\n var flush = function(){\n var parent, fn;\n if(isNode && (parent = process.domain))parent.exit();\n while(head){\n fn = head.fn;\n head = head.next;\n try {\n fn();\n } catch(e){\n if(head)notify();\n else last = undefined;\n throw e;\n }\n } last = undefined;\n if(parent)parent.enter();\n };\n\n // Node.js\n if(isNode){\n notify = function(){\n process.nextTick(flush);\n };\n // browsers with MutationObserver\n } else if(Observer){\n var toggle = true\n , node = document.createTextNode('');\n new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new\n notify = function(){\n node.data = toggle = !toggle;\n };\n // environments with maybe non-completely correct, but existent Promise\n } else if(Promise && Promise.resolve){\n var promise = Promise.resolve();\n notify = function(){\n promise.then(flush);\n };\n // for other environments - macrotask based on:\n // - setImmediate\n // - MessageChannel\n // - window.postMessag\n // - onreadystatechange\n // - setTimeout\n } else {\n notify = function(){\n // strange IE + webpack dev server bug - use .call(global)\n macrotask.call(global, flush);\n };\n }\n\n return function(fn){\n var task = {fn: fn, next: undefined};\n if(last)last.next = task;\n if(!head){\n head = task;\n notify();\n } last = task;\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_microtask.js\n// module id = 114\n// module chunks = 0","'use strict';\n// 19.1.2.1 Object.assign(target, source, ...)\nvar getKeys = require('./_object-keys')\n , gOPS = require('./_object-gops')\n , pIE = require('./_object-pie')\n , toObject = require('./_to-object')\n , IObject = require('./_iobject')\n , $assign = Object.assign;\n\n// should work with symbols and should have deterministic property order (V8 bug)\nmodule.exports = !$assign || require('./_fails')(function(){\n var A = {}\n , B = {}\n , S = Symbol()\n , K = 'abcdefghijklmnopqrst';\n A[S] = 7;\n K.split('').forEach(function(k){ B[k] = k; });\n return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;\n}) ? function assign(target, source){ // eslint-disable-line no-unused-vars\n var T = toObject(target)\n , aLen = arguments.length\n , index = 1\n , getSymbols = gOPS.f\n , isEnum = pIE.f;\n while(aLen > index){\n var S = IObject(arguments[index++])\n , keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S)\n , length = keys.length\n , j = 0\n , key;\n while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key];\n } return T;\n} : $assign;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-assign.js\n// module id = 115\n// module chunks = 0","var dP = require('./_object-dp')\n , anObject = require('./_an-object')\n , getKeys = require('./_object-keys');\n\nmodule.exports = require('./_descriptors') ? Object.defineProperties : function defineProperties(O, Properties){\n anObject(O);\n var keys = getKeys(Properties)\n , length = keys.length\n , i = 0\n , P;\n while(length > i)dP.f(O, P = keys[i++], Properties[P]);\n return O;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-dps.js\n// module id = 116\n// module chunks = 0","var pIE = require('./_object-pie')\n , createDesc = require('./_property-desc')\n , toIObject = require('./_to-iobject')\n , toPrimitive = require('./_to-primitive')\n , has = require('./_has')\n , IE8_DOM_DEFINE = require('./_ie8-dom-define')\n , gOPD = Object.getOwnPropertyDescriptor;\n\nexports.f = require('./_descriptors') ? gOPD : function getOwnPropertyDescriptor(O, P){\n O = toIObject(O);\n P = toPrimitive(P, true);\n if(IE8_DOM_DEFINE)try {\n return gOPD(O, P);\n } catch(e){ /* empty */ }\n if(has(O, P))return createDesc(!pIE.f.call(O, P), O[P]);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-gopd.js\n// module id = 117\n// module chunks = 0","// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window\nvar toIObject = require('./_to-iobject')\n , gOPN = require('./_object-gopn').f\n , toString = {}.toString;\n\nvar windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames\n ? Object.getOwnPropertyNames(window) : [];\n\nvar getWindowNames = function(it){\n try {\n return gOPN(it);\n } catch(e){\n return windowNames.slice();\n }\n};\n\nmodule.exports.f = function getOwnPropertyNames(it){\n return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it));\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-gopn-ext.js\n// module id = 118\n// module chunks = 0","// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\nvar has = require('./_has')\n , toObject = require('./_to-object')\n , IE_PROTO = require('./_shared-key')('IE_PROTO')\n , ObjectProto = Object.prototype;\n\nmodule.exports = Object.getPrototypeOf || function(O){\n O = toObject(O);\n if(has(O, IE_PROTO))return O[IE_PROTO];\n if(typeof O.constructor == 'function' && O instanceof O.constructor){\n return O.constructor.prototype;\n } return O instanceof Object ? ObjectProto : null;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-gpo.js\n// module id = 119\n// module chunks = 0","// most Object methods by ES6 should accept primitives\nvar $export = require('./_export')\n , core = require('./_core')\n , fails = require('./_fails');\nmodule.exports = function(KEY, exec){\n var fn = (core.Object || {})[KEY] || Object[KEY]\n , exp = {};\n exp[KEY] = exec(fn);\n $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_object-sap.js\n// module id = 120\n// module chunks = 0","var hide = require('./_hide');\nmodule.exports = function(target, src, safe){\n for(var key in src){\n if(safe && target[key])target[key] = src[key];\n else hide(target, key, src[key]);\n } return target;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_redefine-all.js\n// module id = 121\n// module chunks = 0","'use strict';\nvar global = require('./_global')\n , core = require('./_core')\n , dP = require('./_object-dp')\n , DESCRIPTORS = require('./_descriptors')\n , SPECIES = require('./_wks')('species');\n\nmodule.exports = function(KEY){\n var C = typeof core[KEY] == 'function' ? core[KEY] : global[KEY];\n if(DESCRIPTORS && C && !C[SPECIES])dP.f(C, SPECIES, {\n configurable: true,\n get: function(){ return this; }\n });\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_set-species.js\n// module id = 122\n// module chunks = 0","// 7.3.20 SpeciesConstructor(O, defaultConstructor)\nvar anObject = require('./_an-object')\n , aFunction = require('./_a-function')\n , SPECIES = require('./_wks')('species');\nmodule.exports = function(O, D){\n var C = anObject(O).constructor, S;\n return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_species-constructor.js\n// module id = 123\n// module chunks = 0","var toInteger = require('./_to-integer')\n , defined = require('./_defined');\n// true -> String#at\n// false -> String#codePointAt\nmodule.exports = function(TO_STRING){\n return function(that, pos){\n var s = String(defined(that))\n , i = toInteger(pos)\n , l = s.length\n , a, b;\n if(i < 0 || i >= l)return TO_STRING ? '' : undefined;\n a = s.charCodeAt(i);\n return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n ? TO_STRING ? s.charAt(i) : a\n : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_string-at.js\n// module id = 124\n// module chunks = 0","var toInteger = require('./_to-integer')\n , max = Math.max\n , min = Math.min;\nmodule.exports = function(index, length){\n index = toInteger(index);\n return index < 0 ? max(index + length, 0) : min(index, length);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/_to-index.js\n// module id = 125\n// module chunks = 0","var anObject = require('./_an-object')\n , get = require('./core.get-iterator-method');\nmodule.exports = require('./_core').getIterator = function(it){\n var iterFn = get(it);\n if(typeof iterFn != 'function')throw TypeError(it + ' is not iterable!');\n return anObject(iterFn.call(it));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/core.get-iterator.js\n// module id = 126\n// module chunks = 0","var classof = require('./_classof')\n , ITERATOR = require('./_wks')('iterator')\n , Iterators = require('./_iterators');\nmodule.exports = require('./_core').isIterable = function(it){\n var O = Object(it);\n return O[ITERATOR] !== undefined\n || '@@iterator' in O\n || Iterators.hasOwnProperty(classof(O));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/core.is-iterable.js\n// module id = 127\n// module chunks = 0","'use strict';\nvar ctx = require('./_ctx')\n , $export = require('./_export')\n , toObject = require('./_to-object')\n , call = require('./_iter-call')\n , isArrayIter = require('./_is-array-iter')\n , toLength = require('./_to-length')\n , createProperty = require('./_create-property')\n , getIterFn = require('./core.get-iterator-method');\n\n$export($export.S + $export.F * !require('./_iter-detect')(function(iter){ Array.from(iter); }), 'Array', {\n // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)\n from: function from(arrayLike/*, mapfn = undefined, thisArg = undefined*/){\n var O = toObject(arrayLike)\n , C = typeof this == 'function' ? this : Array\n , aLen = arguments.length\n , mapfn = aLen > 1 ? arguments[1] : undefined\n , mapping = mapfn !== undefined\n , index = 0\n , iterFn = getIterFn(O)\n , length, result, step, iterator;\n if(mapping)mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);\n // if object isn't iterable or it's array with default iterator - use simple case\n if(iterFn != undefined && !(C == Array && isArrayIter(iterFn))){\n for(iterator = iterFn.call(O), result = new C; !(step = iterator.next()).done; index++){\n createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value);\n }\n } else {\n length = toLength(O.length);\n for(result = new C(length); length > index; index++){\n createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);\n }\n }\n result.length = index;\n return result;\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/es6.array.from.js\n// module id = 128\n// module chunks = 0","'use strict';\nvar addToUnscopables = require('./_add-to-unscopables')\n , step = require('./_iter-step')\n , Iterators = require('./_iterators')\n , toIObject = require('./_to-iobject');\n\n// 22.1.3.4 Array.prototype.entries()\n// 22.1.3.13 Array.prototype.keys()\n// 22.1.3.29 Array.prototype.values()\n// 22.1.3.30 Array.prototype[@@iterator]()\nmodule.exports = require('./_iter-define')(Array, 'Array', function(iterated, kind){\n this._t = toIObject(iterated); // target\n this._i = 0; // next index\n this._k = kind; // kind\n// 22.1.5.2.1 %ArrayIteratorPrototype%.next()\n}, function(){\n var O = this._t\n , kind = this._k\n , index = this._i++;\n if(!O || index >= O.length){\n this._t = undefined;\n return step(1);\n }\n if(kind == 'keys' )return step(0, index);\n if(kind == 'values')return step(0, O[index]);\n return step(0, [index, O[index]]);\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)\nIterators.Arguments = Iterators.Array;\n\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/es6.array.iterator.js\n// module id = 129\n// module chunks = 0","// 20.2.2.22 Math.log2(x)\nvar $export = require('./_export');\n\n$export($export.S, 'Math', {\n log2: function log2(x){\n return Math.log(x) / Math.LN2;\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/es6.math.log2.js\n// module id = 130\n// module chunks = 0","// 19.1.3.1 Object.assign(target, source)\nvar $export = require('./_export');\n\n$export($export.S + $export.F, 'Object', {assign: require('./_object-assign')});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/es6.object.assign.js\n// module id = 131\n// module chunks = 0","// 19.1.2.14 Object.keys(O)\nvar toObject = require('./_to-object')\n , $keys = require('./_object-keys');\n\nrequire('./_object-sap')('keys', function(){\n return function keys(it){\n return $keys(toObject(it));\n };\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/es6.object.keys.js\n// module id = 132\n// module chunks = 0","'use strict';\nvar LIBRARY = require('./_library')\n , global = require('./_global')\n , ctx = require('./_ctx')\n , classof = require('./_classof')\n , $export = require('./_export')\n , isObject = require('./_is-object')\n , aFunction = require('./_a-function')\n , anInstance = require('./_an-instance')\n , forOf = require('./_for-of')\n , speciesConstructor = require('./_species-constructor')\n , task = require('./_task').set\n , microtask = require('./_microtask')()\n , PROMISE = 'Promise'\n , TypeError = global.TypeError\n , process = global.process\n , $Promise = global[PROMISE]\n , process = global.process\n , isNode = classof(process) == 'process'\n , empty = function(){ /* empty */ }\n , Internal, GenericPromiseCapability, Wrapper;\n\nvar USE_NATIVE = !!function(){\n try {\n // correct subclassing with @@species support\n var promise = $Promise.resolve(1)\n , FakePromise = (promise.constructor = {})[require('./_wks')('species')] = function(exec){ exec(empty, empty); };\n // unhandled rejections tracking support, NodeJS Promise without it fails @@species test\n return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise;\n } catch(e){ /* empty */ }\n}();\n\n// helpers\nvar sameConstructor = function(a, b){\n // with library wrapper special case\n return a === b || a === $Promise && b === Wrapper;\n};\nvar isThenable = function(it){\n var then;\n return isObject(it) && typeof (then = it.then) == 'function' ? then : false;\n};\nvar newPromiseCapability = function(C){\n return sameConstructor($Promise, C)\n ? new PromiseCapability(C)\n : new GenericPromiseCapability(C);\n};\nvar PromiseCapability = GenericPromiseCapability = function(C){\n var resolve, reject;\n this.promise = new C(function($$resolve, $$reject){\n if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor');\n resolve = $$resolve;\n reject = $$reject;\n });\n this.resolve = aFunction(resolve);\n this.reject = aFunction(reject);\n};\nvar perform = function(exec){\n try {\n exec();\n } catch(e){\n return {error: e};\n }\n};\nvar notify = function(promise, isReject){\n if(promise._n)return;\n promise._n = true;\n var chain = promise._c;\n microtask(function(){\n var value = promise._v\n , ok = promise._s == 1\n , i = 0;\n var run = function(reaction){\n var handler = ok ? reaction.ok : reaction.fail\n , resolve = reaction.resolve\n , reject = reaction.reject\n , domain = reaction.domain\n , result, then;\n try {\n if(handler){\n if(!ok){\n if(promise._h == 2)onHandleUnhandled(promise);\n promise._h = 1;\n }\n if(handler === true)result = value;\n else {\n if(domain)domain.enter();\n result = handler(value);\n if(domain)domain.exit();\n }\n if(result === reaction.promise){\n reject(TypeError('Promise-chain cycle'));\n } else if(then = isThenable(result)){\n then.call(result, resolve, reject);\n } else resolve(result);\n } else reject(value);\n } catch(e){\n reject(e);\n }\n };\n while(chain.length > i)run(chain[i++]); // variable length - can't use forEach\n promise._c = [];\n promise._n = false;\n if(isReject && !promise._h)onUnhandled(promise);\n });\n};\nvar onUnhandled = function(promise){\n task.call(global, function(){\n var value = promise._v\n , abrupt, handler, console;\n if(isUnhandled(promise)){\n abrupt = perform(function(){\n if(isNode){\n process.emit('unhandledRejection', value, promise);\n } else if(handler = global.onunhandledrejection){\n handler({promise: promise, reason: value});\n } else if((console = global.console) && console.error){\n console.error('Unhandled promise rejection', value);\n }\n });\n // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should\n promise._h = isNode || isUnhandled(promise) ? 2 : 1;\n } promise._a = undefined;\n if(abrupt)throw abrupt.error;\n });\n};\nvar isUnhandled = function(promise){\n if(promise._h == 1)return false;\n var chain = promise._a || promise._c\n , i = 0\n , reaction;\n while(chain.length > i){\n reaction = chain[i++];\n if(reaction.fail || !isUnhandled(reaction.promise))return false;\n } return true;\n};\nvar onHandleUnhandled = function(promise){\n task.call(global, function(){\n var handler;\n if(isNode){\n process.emit('rejectionHandled', promise);\n } else if(handler = global.onrejectionhandled){\n handler({promise: promise, reason: promise._v});\n }\n });\n};\nvar $reject = function(value){\n var promise = this;\n if(promise._d)return;\n promise._d = true;\n promise = promise._w || promise; // unwrap\n promise._v = value;\n promise._s = 2;\n if(!promise._a)promise._a = promise._c.slice();\n notify(promise, true);\n};\nvar $resolve = function(value){\n var promise = this\n , then;\n if(promise._d)return;\n promise._d = true;\n promise = promise._w || promise; // unwrap\n try {\n if(promise === value)throw TypeError(\"Promise can't be resolved itself\");\n if(then = isThenable(value)){\n microtask(function(){\n var wrapper = {_w: promise, _d: false}; // wrap\n try {\n then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));\n } catch(e){\n $reject.call(wrapper, e);\n }\n });\n } else {\n promise._v = value;\n promise._s = 1;\n notify(promise, false);\n }\n } catch(e){\n $reject.call({_w: promise, _d: false}, e); // wrap\n }\n};\n\n// constructor polyfill\nif(!USE_NATIVE){\n // 25.4.3.1 Promise(executor)\n $Promise = function Promise(executor){\n anInstance(this, $Promise, PROMISE, '_h');\n aFunction(executor);\n Internal.call(this);\n try {\n executor(ctx($resolve, this, 1), ctx($reject, this, 1));\n } catch(err){\n $reject.call(this, err);\n }\n };\n Internal = function Promise(executor){\n this._c = []; // <- awaiting reactions\n this._a = undefined; // <- checked in isUnhandled reactions\n this._s = 0; // <- state\n this._d = false; // <- done\n this._v = undefined; // <- value\n this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled\n this._n = false; // <- notify\n };\n Internal.prototype = require('./_redefine-all')($Promise.prototype, {\n // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)\n then: function then(onFulfilled, onRejected){\n var reaction = newPromiseCapability(speciesConstructor(this, $Promise));\n reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;\n reaction.fail = typeof onRejected == 'function' && onRejected;\n reaction.domain = isNode ? process.domain : undefined;\n this._c.push(reaction);\n if(this._a)this._a.push(reaction);\n if(this._s)notify(this, false);\n return reaction.promise;\n },\n // 25.4.5.1 Promise.prototype.catch(onRejected)\n 'catch': function(onRejected){\n return this.then(undefined, onRejected);\n }\n });\n PromiseCapability = function(){\n var promise = new Internal;\n this.promise = promise;\n this.resolve = ctx($resolve, promise, 1);\n this.reject = ctx($reject, promise, 1);\n };\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: $Promise});\nrequire('./_set-to-string-tag')($Promise, PROMISE);\nrequire('./_set-species')(PROMISE);\nWrapper = require('./_core')[PROMISE];\n\n// statics\n$export($export.S + $export.F * !USE_NATIVE, PROMISE, {\n // 25.4.4.5 Promise.reject(r)\n reject: function reject(r){\n var capability = newPromiseCapability(this)\n , $$reject = capability.reject;\n $$reject(r);\n return capability.promise;\n }\n});\n$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {\n // 25.4.4.6 Promise.resolve(x)\n resolve: function resolve(x){\n // instanceof instead of internal slot check because we should fix it without replacement native Promise core\n if(x instanceof $Promise && sameConstructor(x.constructor, this))return x;\n var capability = newPromiseCapability(this)\n , $$resolve = capability.resolve;\n $$resolve(x);\n return capability.promise;\n }\n});\n$export($export.S + $export.F * !(USE_NATIVE && require('./_iter-detect')(function(iter){\n $Promise.all(iter)['catch'](empty);\n})), PROMISE, {\n // 25.4.4.1 Promise.all(iterable)\n all: function all(iterable){\n var C = this\n , capability = newPromiseCapability(C)\n , resolve = capability.resolve\n , reject = capability.reject;\n var abrupt = perform(function(){\n var values = []\n , index = 0\n , remaining = 1;\n forOf(iterable, false, function(promise){\n var $index = index++\n , alreadyCalled = false;\n values.push(undefined);\n remaining++;\n C.resolve(promise).then(function(value){\n if(alreadyCalled)return;\n alreadyCalled = true;\n values[$index] = value;\n --remaining || resolve(values);\n }, reject);\n });\n --remaining || resolve(values);\n });\n if(abrupt)reject(abrupt.error);\n return capability.promise;\n },\n // 25.4.4.4 Promise.race(iterable)\n race: function race(iterable){\n var C = this\n , capability = newPromiseCapability(C)\n , reject = capability.reject;\n var abrupt = perform(function(){\n forOf(iterable, false, function(promise){\n C.resolve(promise).then(capability.resolve, reject);\n });\n });\n if(abrupt)reject(abrupt.error);\n return capability.promise;\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/es6.promise.js\n// module id = 133\n// module chunks = 0","'use strict';\n// ECMAScript 6 symbols shim\nvar global = require('./_global')\n , has = require('./_has')\n , DESCRIPTORS = require('./_descriptors')\n , $export = require('./_export')\n , redefine = require('./_redefine')\n , META = require('./_meta').KEY\n , $fails = require('./_fails')\n , shared = require('./_shared')\n , setToStringTag = require('./_set-to-string-tag')\n , uid = require('./_uid')\n , wks = require('./_wks')\n , wksExt = require('./_wks-ext')\n , wksDefine = require('./_wks-define')\n , keyOf = require('./_keyof')\n , enumKeys = require('./_enum-keys')\n , isArray = require('./_is-array')\n , anObject = require('./_an-object')\n , toIObject = require('./_to-iobject')\n , toPrimitive = require('./_to-primitive')\n , createDesc = require('./_property-desc')\n , _create = require('./_object-create')\n , gOPNExt = require('./_object-gopn-ext')\n , $GOPD = require('./_object-gopd')\n , $DP = require('./_object-dp')\n , $keys = require('./_object-keys')\n , gOPD = $GOPD.f\n , dP = $DP.f\n , gOPN = gOPNExt.f\n , $Symbol = global.Symbol\n , $JSON = global.JSON\n , _stringify = $JSON && $JSON.stringify\n , PROTOTYPE = 'prototype'\n , HIDDEN = wks('_hidden')\n , TO_PRIMITIVE = wks('toPrimitive')\n , isEnum = {}.propertyIsEnumerable\n , SymbolRegistry = shared('symbol-registry')\n , AllSymbols = shared('symbols')\n , OPSymbols = shared('op-symbols')\n , ObjectProto = Object[PROTOTYPE]\n , USE_NATIVE = typeof $Symbol == 'function'\n , QObject = global.QObject;\n// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173\nvar setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;\n\n// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687\nvar setSymbolDesc = DESCRIPTORS && $fails(function(){\n return _create(dP({}, 'a', {\n get: function(){ return dP(this, 'a', {value: 7}).a; }\n })).a != 7;\n}) ? function(it, key, D){\n var protoDesc = gOPD(ObjectProto, key);\n if(protoDesc)delete ObjectProto[key];\n dP(it, key, D);\n if(protoDesc && it !== ObjectProto)dP(ObjectProto, key, protoDesc);\n} : dP;\n\nvar wrap = function(tag){\n var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]);\n sym._k = tag;\n return sym;\n};\n\nvar isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function(it){\n return typeof it == 'symbol';\n} : function(it){\n return it instanceof $Symbol;\n};\n\nvar $defineProperty = function defineProperty(it, key, D){\n if(it === ObjectProto)$defineProperty(OPSymbols, key, D);\n anObject(it);\n key = toPrimitive(key, true);\n anObject(D);\n if(has(AllSymbols, key)){\n if(!D.enumerable){\n if(!has(it, HIDDEN))dP(it, HIDDEN, createDesc(1, {}));\n it[HIDDEN][key] = true;\n } else {\n if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false;\n D = _create(D, {enumerable: createDesc(0, false)});\n } return setSymbolDesc(it, key, D);\n } return dP(it, key, D);\n};\nvar $defineProperties = function defineProperties(it, P){\n anObject(it);\n var keys = enumKeys(P = toIObject(P))\n , i = 0\n , l = keys.length\n , key;\n while(l > i)$defineProperty(it, key = keys[i++], P[key]);\n return it;\n};\nvar $create = function create(it, P){\n return P === undefined ? _create(it) : $defineProperties(_create(it), P);\n};\nvar $propertyIsEnumerable = function propertyIsEnumerable(key){\n var E = isEnum.call(this, key = toPrimitive(key, true));\n if(this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return false;\n return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true;\n};\nvar $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){\n it = toIObject(it);\n key = toPrimitive(key, true);\n if(it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return;\n var D = gOPD(it, key);\n if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true;\n return D;\n};\nvar $getOwnPropertyNames = function getOwnPropertyNames(it){\n var names = gOPN(toIObject(it))\n , result = []\n , i = 0\n , key;\n while(names.length > i){\n if(!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META)result.push(key);\n } return result;\n};\nvar $getOwnPropertySymbols = function getOwnPropertySymbols(it){\n var IS_OP = it === ObjectProto\n , names = gOPN(IS_OP ? OPSymbols : toIObject(it))\n , result = []\n , i = 0\n , key;\n while(names.length > i){\n if(has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true))result.push(AllSymbols[key]);\n } return result;\n};\n\n// 19.4.1.1 Symbol([description])\nif(!USE_NATIVE){\n $Symbol = function Symbol(){\n if(this instanceof $Symbol)throw TypeError('Symbol is not a constructor!');\n var tag = uid(arguments.length > 0 ? arguments[0] : undefined);\n var $set = function(value){\n if(this === ObjectProto)$set.call(OPSymbols, value);\n if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false;\n setSymbolDesc(this, tag, createDesc(1, value));\n };\n if(DESCRIPTORS && setter)setSymbolDesc(ObjectProto, tag, {configurable: true, set: $set});\n return wrap(tag);\n };\n redefine($Symbol[PROTOTYPE], 'toString', function toString(){\n return this._k;\n });\n\n $GOPD.f = $getOwnPropertyDescriptor;\n $DP.f = $defineProperty;\n require('./_object-gopn').f = gOPNExt.f = $getOwnPropertyNames;\n require('./_object-pie').f = $propertyIsEnumerable;\n require('./_object-gops').f = $getOwnPropertySymbols;\n\n if(DESCRIPTORS && !require('./_library')){\n redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);\n }\n\n wksExt.f = function(name){\n return wrap(wks(name));\n }\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, {Symbol: $Symbol});\n\nfor(var symbols = (\n // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14\n 'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'\n).split(','), i = 0; symbols.length > i; )wks(symbols[i++]);\n\nfor(var symbols = $keys(wks.store), i = 0; symbols.length > i; )wksDefine(symbols[i++]);\n\n$export($export.S + $export.F * !USE_NATIVE, 'Symbol', {\n // 19.4.2.1 Symbol.for(key)\n 'for': function(key){\n return has(SymbolRegistry, key += '')\n ? SymbolRegistry[key]\n : SymbolRegistry[key] = $Symbol(key);\n },\n // 19.4.2.5 Symbol.keyFor(sym)\n keyFor: function keyFor(key){\n if(isSymbol(key))return keyOf(SymbolRegistry, key);\n throw TypeError(key + ' is not a symbol!');\n },\n useSetter: function(){ setter = true; },\n useSimple: function(){ setter = false; }\n});\n\n$export($export.S + $export.F * !USE_NATIVE, 'Object', {\n // 19.1.2.2 Object.create(O [, Properties])\n create: $create,\n // 19.1.2.4 Object.defineProperty(O, P, Attributes)\n defineProperty: $defineProperty,\n // 19.1.2.3 Object.defineProperties(O, Properties)\n defineProperties: $defineProperties,\n // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)\n getOwnPropertyDescriptor: $getOwnPropertyDescriptor,\n // 19.1.2.7 Object.getOwnPropertyNames(O)\n getOwnPropertyNames: $getOwnPropertyNames,\n // 19.1.2.8 Object.getOwnPropertySymbols(O)\n getOwnPropertySymbols: $getOwnPropertySymbols\n});\n\n// 24.3.2 JSON.stringify(value [, replacer [, space]])\n$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function(){\n var S = $Symbol();\n // MS Edge converts symbol values to JSON as {}\n // WebKit converts symbol values to JSON as null\n // V8 throws on boxed symbols\n return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}';\n})), 'JSON', {\n stringify: function stringify(it){\n if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined\n var args = [it]\n , i = 1\n , replacer, $replacer;\n while(arguments.length > i)args.push(arguments[i++]);\n replacer = args[1];\n if(typeof replacer == 'function')$replacer = replacer;\n if($replacer || !isArray(replacer))replacer = function(key, value){\n if($replacer)value = $replacer.call(this, key, value);\n if(!isSymbol(value))return value;\n };\n args[1] = replacer;\n return _stringify.apply($JSON, args);\n }\n});\n\n// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)\n$Symbol[PROTOTYPE][TO_PRIMITIVE] || require('./_hide')($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);\n// 19.4.3.5 Symbol.prototype[@@toStringTag]\nsetToStringTag($Symbol, 'Symbol');\n// 20.2.1.9 Math[@@toStringTag]\nsetToStringTag(Math, 'Math', true);\n// 24.3.3 JSON[@@toStringTag]\nsetToStringTag(global.JSON, 'JSON', true);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/es6.symbol.js\n// module id = 134\n// module chunks = 0","require('./_wks-define')('asyncIterator');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/es7.symbol.async-iterator.js\n// module id = 135\n// module chunks = 0","require('./_wks-define')('observable');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/library/modules/es7.symbol.observable.js\n// module id = 136\n// module chunks = 0","// Generated by CoffeeScript 2.3.1\n// # CSV Parser\n\n// This module provides a CSV parser tested and used against large datasets. Over\n// the year, it has been enhance and is now full of useful options.\n\n// Please look at the [README], the [project website][site] the [samples] and the\n// [tests] for additional information.\nvar Parser, StringDecoder, isObjLiteral, stream, util;\n\nstream = require('stream');\n\nutil = require('util');\n\nStringDecoder = require('string_decoder').StringDecoder;\n\n// ## Usage\n\n// Callback approach, for ease of use: \n\n// `parse(data, [options], callback)` \n\n// [Node.js Stream API][stream], for maximum of power: \n\n// `parse([options], [callback])` \nmodule.exports = function() {\n var callback, called, chunks, data, err, options, parser;\n if (arguments.length === 3) {\n data = arguments[0];\n options = arguments[1];\n callback = arguments[2];\n if (typeof callback !== 'function') {\n throw Error(`Invalid callback argument: ${JSON.stringify(callback)}`);\n }\n if (!(typeof data === 'string' || Buffer.isBuffer(arguments[0]))) {\n return callback(Error(`Invalid data argument: ${JSON.stringify(data)}`));\n }\n } else if (arguments.length === 2) {\n // 1st arg is data:string or options:object\n if (typeof arguments[0] === 'string' || Buffer.isBuffer(arguments[0])) {\n data = arguments[0];\n } else if (isObjLiteral(arguments[0])) {\n options = arguments[0];\n } else {\n err = `Invalid first argument: ${JSON.stringify(arguments[0])}`;\n }\n // 2nd arg is options:object or callback:function\n if (typeof arguments[1] === 'function') {\n callback = arguments[1];\n } else if (isObjLiteral(arguments[1])) {\n if (options) {\n err = 'Invalid arguments: got options twice as first and second arguments';\n } else {\n options = arguments[1];\n }\n } else {\n err = `Invalid first argument: ${JSON.stringify(arguments[1])}`;\n }\n if (err) {\n if (!callback) {\n throw Error(err);\n } else {\n return callback(Error(err));\n }\n }\n } else if (arguments.length === 1) {\n if (typeof arguments[0] === 'function') {\n callback = arguments[0];\n } else {\n options = arguments[0];\n }\n }\n if (options == null) {\n options = {};\n }\n parser = new Parser(options);\n if (data != null) {\n process.nextTick(function() {\n parser.write(data);\n return parser.end();\n });\n }\n if (callback) {\n called = false;\n chunks = options.objname ? {} : [];\n parser.on('readable', function() {\n var chunk, results;\n results = [];\n while (chunk = parser.read()) {\n if (options.objname) {\n results.push(chunks[chunk[0]] = chunk[1]);\n } else {\n results.push(chunks.push(chunk));\n }\n }\n return results;\n });\n parser.on('error', function(err) {\n called = true;\n return callback(err);\n });\n parser.on('end', function() {\n if (!called) {\n return callback(null, chunks);\n }\n });\n }\n return parser;\n};\n\n// ## `Parser([options])`\n\n// Options are documented [here](http://csv.adaltas.com/parse/).\nParser = function(options = {}) {\n var base, base1, base10, base11, base12, base13, base14, base15, base16, base17, base2, base3, base4, base5, base6, base7, base8, base9, k, v;\n // @options = options\n this.options = {};\n for (k in options) {\n v = options[k];\n this.options[k] = v;\n }\n this.options.objectMode = true;\n stream.Transform.call(this, this.options);\n if ((base = this.options).rowDelimiter == null) {\n base.rowDelimiter = null;\n }\n if (typeof this.options.rowDelimiter === 'string') {\n this.options.rowDelimiter = [this.options.rowDelimiter];\n }\n if ((base1 = this.options).delimiter == null) {\n base1.delimiter = ',';\n }\n if (this.options.quote !== void 0 && !this.options.quote) {\n this.options.quote = '';\n }\n if ((base2 = this.options).quote == null) {\n base2.quote = '\"';\n }\n if ((base3 = this.options).escape == null) {\n base3.escape = '\"';\n }\n if ((base4 = this.options).columns == null) {\n base4.columns = null;\n }\n if ((base5 = this.options).comment == null) {\n base5.comment = '';\n }\n if ((base6 = this.options).objname == null) {\n base6.objname = false;\n }\n if ((base7 = this.options).trim == null) {\n base7.trim = false;\n }\n if ((base8 = this.options).ltrim == null) {\n base8.ltrim = false;\n }\n if ((base9 = this.options).rtrim == null) {\n base9.rtrim = false;\n }\n if (this.options.auto_parse != null) {\n this.options.cast = this.options.auto_parse;\n }\n if ((base10 = this.options).cast == null) {\n base10.cast = false;\n }\n if (this.options.auto_parse_date != null) {\n this.options.cast_date = this.options.auto_parse_date;\n }\n if ((base11 = this.options).cast_date == null) {\n base11.cast_date = false;\n }\n if (this.options.cast_date === true) {\n this.options.cast_date = function(value) {\n var m;\n m = Date.parse(value);\n if (!isNaN(m)) {\n value = new Date(m);\n }\n return value;\n };\n }\n if ((base12 = this.options).relax == null) {\n base12.relax = false;\n }\n if ((base13 = this.options).relax_column_count == null) {\n base13.relax_column_count = false;\n }\n if ((base14 = this.options).skip_empty_lines == null) {\n base14.skip_empty_lines = false;\n }\n if ((base15 = this.options).max_limit_on_data_read == null) {\n base15.max_limit_on_data_read = 128000;\n }\n if ((base16 = this.options).skip_lines_with_empty_values == null) {\n base16.skip_lines_with_empty_values = false;\n }\n if ((base17 = this.options).skip_lines_with_error == null) {\n base17.skip_lines_with_error = false;\n }\n // Counters\n // lines = count + skipped_line_count + empty_line_count\n this.lines = 0; // Number of lines encountered in the source dataset\n this.count = 0; // Number of records being processed\n this.skipped_line_count = 0; // Number of records skipped due to errors\n this.empty_line_count = 0; // Number of empty lines\n // Constants\n this.is_int = /^(\\-|\\+)?([1-9]+[0-9]*)$/;\n // @is_float = /^(\\-|\\+)?([0-9]+(\\.[0-9]+)([eE][0-9]+)?|Infinity)$/\n // @is_float = /^(\\-|\\+)?((([0-9])|([1-9]+[0-9]*))(\\.[0-9]+)([eE][0-9]+)?|Infinity)$/\n this.is_float = function(value) {\n return (value - parseFloat(value) + 1) >= 0; // Borrowed from jquery\n };\n // Internal state\n this._ = {\n decoder: new StringDecoder(),\n quoting: false,\n commenting: false,\n field: null,\n nextChar: null,\n closingQuote: 0,\n line: [],\n chunks: [],\n rawBuf: '',\n buf: '',\n rowDelimiterLength: this.options.rowDelimiter ? Math.max(...this.options.rowDelimiter.map(function(v) {\n return v.length;\n })) : void 0,\n lineHasError: false,\n isEnded: false\n };\n return this;\n};\n\n// ## Internal API\n\n// The Parser implement a [`stream.Transform` class][transform].\n\n// ### Events\n\n// The library extends Node [EventEmitter][event] class and emit all\n// the events of the Writable and Readable [Stream API][stream]. \nutil.inherits(Parser, stream.Transform);\n\n// For extra flexibility, you can get access to the original Parser\n// class: `require('csv-parse').Parser`.\nmodule.exports.Parser = Parser;\n\n// ### `_transform(chunk, encoding, callback)`\n\n// * `chunk` Buffer | String \n// The chunk to be transformed. Will always be a buffer unless the decodeStrings option was set to false.\n// * `encoding` String \n// If the chunk is a string, then this is the encoding type. (Ignore if decodeStrings chunk is a buffer.)\n// * `callback` Function \n// Call this function (optionally with an error argument) when you are done processing the supplied chunk.\n\n// Implementation of the [`stream.Transform` API][transform]\nParser.prototype._transform = function(chunk, encoding, callback) {\n return setImmediate(() => {\n var err;\n if (chunk instanceof Buffer) {\n chunk = this._.decoder.write(chunk);\n }\n err = this.__write(chunk, false);\n if (err) {\n return this.emit('error', err);\n }\n return callback();\n });\n};\n\nParser.prototype._flush = function(callback) {\n return callback(this.__flush());\n};\n\nParser.prototype.__flush = function() {\n var err;\n err = this.__write(this._.decoder.end(), true);\n if (err) {\n return err;\n }\n if (this._.quoting) {\n err = this.error(`Quoted field not terminated at line ${this.lines + 1}`);\n return err;\n }\n if (this._.line.length > 0) {\n return this.__push(this._.line);\n }\n};\n\nParser.prototype.__push = function(line) {\n var call_column_udf, columns, err, field, i, j, len, lineAsColumns, record;\n if (this._.isEnded) {\n return;\n }\n if (this.options.skip_lines_with_empty_values && line.join('').trim() === '') {\n return;\n }\n record = null;\n if (this.options.columns === true) {\n this.options.columns = line;\n return;\n } else if (typeof this.options.columns === 'function') {\n call_column_udf = function(fn, line) {\n var columns, err;\n try {\n columns = fn.call(null, line);\n return [null, columns];\n } catch (error) {\n err = error;\n return [err];\n }\n };\n [err, columns] = call_column_udf(this.options.columns, line);\n if (err) {\n return err;\n }\n this.options.columns = columns;\n return;\n }\n if (!this._.line_length && line.length > 0) {\n this._.line_length = this.options.columns ? this.options.columns.length : line.length;\n }\n // Dont check column count on empty lines\n if (line.length === 1 && line[0] === '') {\n this.empty_line_count++;\n } else if (line.length !== this._.line_length) {\n // Dont check column count with relax_column_count\n if (this.options.relax_column_count) {\n this.count++;\n this.skipped_line_count++;\n } else if (this.options.columns != null) {\n // Suggest: Inconsistent header and column numbers: header is 1 and number of columns is 1 on line 1\n err = this.error(`Number of columns on line ${this.lines} does not match header`);\n return err;\n } else {\n err = this.error(`Number of columns is inconsistent on line ${this.lines}`);\n return err;\n }\n } else {\n this.count++;\n }\n if (this.options.columns != null) {\n lineAsColumns = {};\n for (i = j = 0, len = line.length; j < len; i = ++j) {\n field = line[i];\n if (this.options.columns[i] === false) {\n continue;\n }\n lineAsColumns[this.options.columns[i]] = field;\n }\n if (this.options.objname) {\n record = [lineAsColumns[this.options.objname], lineAsColumns];\n } else {\n record = lineAsColumns;\n }\n } else {\n record = line;\n }\n if (this.count < this.options.from) {\n return;\n }\n if (this.options.raw) {\n this.push({\n raw: this._.rawBuf,\n row: record\n });\n this._.rawBuf = '';\n } else {\n this.push(record);\n }\n if (this.listenerCount('record')) {\n this.emit('record', record);\n }\n // When to is reached set ignore any future calls\n if (this.count >= this.options.to) {\n this._.isEnded = true;\n return this.push(null);\n }\n return null;\n};\n\nParser.prototype.__write = function(chars, end) {\n var areNextCharsDelimiter, areNextCharsRowDelimiters, cast, char, err, escapeIsQuote, i, isDelimiter, isEscape, isNextCharAComment, isNextCharTrimable, isQuote, isRowDelimiter, isRowDelimiterLength, is_float, is_int, l, ltrim, nextCharPos, ref, ref1, ref2, ref3, ref4, ref5, ref6, remainingBuffer, rowDelimiter, rtrim, wasCommenting;\n is_int = (value) => {\n if (typeof this.is_int === 'function') {\n return this.is_int(value);\n } else {\n return this.is_int.test(value);\n }\n };\n is_float = (value) => {\n if (typeof this.is_float === 'function') {\n return this.is_float(value);\n } else {\n return this.is_float.test(value);\n }\n };\n cast = (value, context = {}) => {\n if (!this.options.cast) {\n return value;\n }\n if (context.quoting == null) {\n context.quoting = !!this._.closingQuote;\n }\n if (context.lines == null) {\n context.lines = this.lines;\n }\n if (context.count == null) {\n context.count = this.count;\n }\n if (context.index == null) {\n context.index = this._.line.length;\n }\n // context.header ?= if @options.column and @lines is 1 and @count is 0 then true else false\n if (context.header == null) {\n context.header = this.options.columns === true;\n }\n if (context.column == null) {\n context.column = Array.isArray(this.options.columns) ? this.options.columns[context.index] : context.index;\n }\n if (typeof this.options.cast === 'function') {\n return this.options.cast(value, context);\n }\n if (is_int(value)) {\n value = parseInt(value);\n } else if (is_float(value)) {\n value = parseFloat(value);\n } else if (this.options.cast_date) {\n value = this.options.cast_date(value, context);\n }\n return value;\n };\n ltrim = this.options.trim || this.options.ltrim;\n rtrim = this.options.trim || this.options.rtrim;\n chars = this._.buf + chars;\n l = chars.length;\n i = 0;\n if (this.lines === 0 && 0xFEFF === chars.charCodeAt(0)) {\n // Strip BOM header\n i++;\n }\n while (i < l) {\n // Ensure we get enough space to look ahead\n if (!end) {\n remainingBuffer = chars.substr(i, l - i);\n // (i+1000 >= l) or\n // Skip if the remaining buffer can be comment\n // Skip if the remaining buffer can be row delimiter\n if ((!this.options.rowDelimiter && i + 3 > l) || (!this._.commenting && l - i < this.options.comment.length && this.options.comment.substr(0, l - i) === remainingBuffer) || (this.options.rowDelimiter && l - i < this._.rowDelimiterLength && this.options.rowDelimiter.some(function(rd) {\n return rd.substr(0, l - i) === remainingBuffer;\n // Skip if the remaining buffer can be row delimiter following the closing quote\n })) || (this.options.rowDelimiter && this._.quoting && l - i < (this.options.quote.length + this._.rowDelimiterLength) && this.options.rowDelimiter.some((rd) => {\n return (this.options.quote + rd).substr(0, l - i) === remainingBuffer;\n // Skip if the remaining buffer can be delimiter\n // Skip if the remaining buffer can be escape sequence\n })) || (l - i <= this.options.delimiter.length && this.options.delimiter.substr(0, l - i) === remainingBuffer) || (l - i <= this.options.escape.length && this.options.escape.substr(0, l - i) === remainingBuffer)) {\n break;\n }\n }\n char = this._.nextChar ? this._.nextChar : chars.charAt(i);\n this._.nextChar = l > i + 1 ? chars.charAt(i + 1) : null;\n if (this.options.raw) {\n this._.rawBuf += char;\n }\n // Auto discovery of rowDelimiter, unix, mac and windows supported\n if (this.options.rowDelimiter == null) {\n nextCharPos = i;\n rowDelimiter = null;\n // First empty line\n if (!this._.quoting && (char === '\\n' || char === '\\r')) {\n rowDelimiter = char;\n nextCharPos += 1;\n } else if (this._.quoting && char === this.options.quote && ((ref = this._.nextChar) === '\\n' || ref === '\\r')) {\n rowDelimiter = this._.nextChar;\n nextCharPos += 2;\n }\n if (rowDelimiter) {\n if (rowDelimiter === '\\r' && chars.charAt(nextCharPos) === '\\n') {\n rowDelimiter += '\\n';\n }\n this.options.rowDelimiter = [rowDelimiter];\n this._.rowDelimiterLength = rowDelimiter.length;\n }\n }\n // Parse that damn char\n // Note, shouldn't we have sth like chars.substr(i, @options.escape.length)\n if (!this._.commenting && char === this.options.escape) {\n // Make sure the escape is really here for escaping:\n // If escape is same as quote, and escape is first char of a field \n // and it's not quoted, then it is a quote\n // Next char should be an escape or a quote\n escapeIsQuote = this.options.escape === this.options.quote;\n isEscape = this._.nextChar === this.options.escape;\n isQuote = this._.nextChar === this.options.quote;\n if (!(escapeIsQuote && !this._.field && !this._.quoting) && (isEscape || isQuote)) {\n i++;\n char = this._.nextChar;\n this._.nextChar = chars.charAt(i + 1);\n if (this._.field == null) {\n this._.field = '';\n }\n this._.field += char;\n // Since we're skipping the next one, better add it now if in raw mode.\n if (this.options.raw) {\n this._.rawBuf += char;\n }\n i++;\n continue;\n }\n }\n // Char match quote\n if (!this._.commenting && char === this.options.quote) {\n if (this._.acceptOnlyEmptyChars && (char !== ' ' && char !== '\\t')) {\n return this.error('Only trimable characters are accepted after quotes');\n }\n if (this._.quoting) {\n // Make sure a closing quote is followed by a delimiter\n // If we have a next character and \n // it isnt a rowDelimiter and \n // it isnt an column delimiter and\n // it isnt the begining of a comment\n // Otherwise, if this is not \"relax\" mode, throw an error\n isNextCharTrimable = rtrim && ((ref1 = this._.nextChar) === ' ' || ref1 === '\\t');\n areNextCharsRowDelimiters = this.options.rowDelimiter && this.options.rowDelimiter.some(function(rd) {\n return chars.substr(i + 1, rd.length) === rd;\n });\n areNextCharsDelimiter = chars.substr(i + 1, this.options.delimiter.length) === this.options.delimiter;\n isNextCharAComment = this._.nextChar === this.options.comment;\n if ((this._.nextChar != null) && !isNextCharTrimable && !areNextCharsRowDelimiters && !areNextCharsDelimiter && !isNextCharAComment) {\n if (this.options.relax) {\n this._.quoting = false;\n if (this._.field) {\n this._.field = `${this.options.quote}${this._.field}`;\n }\n } else {\n if (err = this.error(`Invalid closing quote at line ${this.lines + 1}; found ${JSON.stringify(this._.nextChar)} instead of delimiter ${JSON.stringify(this.options.delimiter)}`)) {\n return err;\n }\n }\n } else if ((this._.nextChar != null) && isNextCharTrimable) {\n i++;\n this._.quoting = false;\n this._.closingQuote = this.options.quote.length;\n this._.acceptOnlyEmptyChars = true;\n continue;\n } else {\n i++;\n this._.quoting = false;\n this._.closingQuote = this.options.quote.length;\n if (end && i === l) {\n this._.line.push(cast(this._.field || ''));\n this._.field = null;\n }\n continue;\n }\n } else if (!this._.field) {\n this._.quoting = true;\n i++;\n continue;\n } else if ((this._.field != null) && !this.options.relax) {\n if (err = this.error(`Invalid opening quote at line ${this.lines + 1}`)) {\n return err;\n }\n }\n }\n // Otherwise, treat quote as a regular character\n isRowDelimiter = this.options.rowDelimiter && this.options.rowDelimiter.some(function(rd) {\n return chars.substr(i, rd.length) === rd;\n });\n if (isRowDelimiter || (end && i === l - 1)) {\n this.lines++;\n }\n // Set the commenting flag\n wasCommenting = false;\n if (!this._.commenting && !this._.quoting && this.options.comment && chars.substr(i, this.options.comment.length) === this.options.comment) {\n this._.commenting = true;\n } else if (this._.commenting && isRowDelimiter) {\n wasCommenting = true;\n this._.commenting = false;\n }\n isDelimiter = chars.substr(i, this.options.delimiter.length) === this.options.delimiter;\n if (this._.acceptOnlyEmptyChars) {\n if (isDelimiter || isRowDelimiter) {\n this._.acceptOnlyEmptyChars = false;\n } else {\n if (char === ' ' || char === '\\t') {\n i++;\n continue;\n } else {\n return this.error('Only trimable characters are accepted after quotes');\n }\n }\n }\n if (!this._.commenting && !this._.quoting && (isDelimiter || isRowDelimiter)) {\n if (isRowDelimiter) {\n isRowDelimiterLength = this.options.rowDelimiter.filter(function(rd) {\n return chars.substr(i, rd.length) === rd;\n })[0].length;\n }\n // Empty lines\n if (isRowDelimiter && this._.line.length === 0 && (this._.field == null)) {\n if (wasCommenting || this.options.skip_empty_lines) {\n i += isRowDelimiterLength;\n this._.nextChar = chars.charAt(i);\n continue;\n }\n }\n if (rtrim) {\n if (!this._.closingQuote) {\n this._.field = (ref2 = this._.field) != null ? ref2.trimRight() : void 0;\n }\n }\n this._.line.push(cast(this._.field || ''));\n this._.closingQuote = 0;\n this._.field = null;\n if (isDelimiter) { // End of field\n i += this.options.delimiter.length;\n this._.nextChar = chars.charAt(i);\n if (end && !this._.nextChar) {\n isRowDelimiter = true;\n this._.line.push('');\n }\n }\n if (isRowDelimiter) { // End of record\n if (!this._.lineHasError) {\n err = this.__push(this._.line);\n if (err) {\n return err;\n }\n }\n if (this._.lineHasError) {\n this._.lineHasError = false;\n }\n // Some cleanup for the next record\n this._.line = [];\n i += isRowDelimiterLength;\n this._.nextChar = chars.charAt(i);\n continue;\n }\n } else if (!this._.commenting && !this._.quoting && (char === ' ' || char === '\\t')) {\n if (this._.field == null) {\n // Left trim unless we are quoting or field already filled\n this._.field = '';\n }\n if (!(ltrim && !this._.field)) {\n this._.field += char;\n }\n i++;\n } else if (!this._.commenting) {\n if (this._.field == null) {\n this._.field = '';\n }\n this._.field += char;\n i++;\n } else {\n i++;\n }\n if (!this._.commenting && ((ref3 = this._.field) != null ? ref3.length : void 0) > this.options.max_limit_on_data_read) {\n return Error(`Field exceeds max_limit_on_data_read setting (${this.options.max_limit_on_data_read}) ${JSON.stringify(this.options.delimiter)}`);\n }\n if (!this._.commenting && ((ref4 = this._.line) != null ? ref4.length : void 0) > this.options.max_limit_on_data_read) {\n return Error(`Row delimiter not found in the file ${JSON.stringify(this.options.rowDelimiter)}`);\n }\n }\n // Flush remaining fields and lines\n if (end) {\n if (l === 0) {\n this.lines++;\n }\n if (this._.field != null) {\n if (rtrim) {\n if (!this._.closingQuote) {\n this._.field = (ref5 = this._.field) != null ? ref5.trimRight() : void 0;\n }\n }\n this._.line.push(cast(this._.field || ''));\n this._.field = null;\n }\n if (((ref6 = this._.field) != null ? ref6.length : void 0) > this.options.max_limit_on_data_read) {\n return Error(`Delimiter not found in the file ${JSON.stringify(this.options.delimiter)}`);\n }\n if (this._.line.length > this.options.max_limit_on_data_read) {\n return Error(`Row delimiter not found in the file ${JSON.stringify(this.options.rowDelimiter)}`);\n }\n }\n // Store un-parsed chars for next call\n this._.buf = chars.substr(i);\n return null;\n};\n\nParser.prototype.error = function(msg) {\n var err;\n err = Error(msg);\n if (!this.options.skip_lines_with_error) {\n return err;\n } else {\n if (!this._.lineHasError) {\n this._.lineHasError = true;\n this.emit('skip', err);\n }\n }\n return null;\n};\n\n// ## Utils\nisObjLiteral = function(_obj) {\n var _test;\n _test = _obj;\n if (typeof _obj !== 'object' || _obj === null || Array.isArray(_obj)) {\n return false;\n } else {\n return (function() {\n while (!false) {\n if (Object.getPrototypeOf(_test = Object.getPrototypeOf(_test)) === null) {\n break;\n }\n }\n return Object.getPrototypeOf(_obj === _test);\n })();\n }\n};\n\n// [readme]: https://github.com/wdavidw/node-csv-parse\n// [site]: http://csv.adaltas.com/parse/\n// [samples]: https://github.com/wdavidw/node-csv-parse/tree/master/samples\n// [tests]: https://github.com/wdavidw/node-csv-parse/tree/master/test\n// [stream]: (http://nodejs.org/api/stream.html\n// [transform]: (http://nodejs.org/api/stream.html#stream_class_stream_transform_1)\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/csv-parse/lib/index.js\n// module id = 137\n// module chunks = 0","/* FileSaver.js\n * A saveAs() FileSaver implementation.\n * 1.3.2\n * 2016-06-16 18:25:19\n *\n * By Eli Grey, http://eligrey.com\n * License: MIT\n * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md\n */\n\n/*global self */\n/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */\n\n/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */\n\nvar saveAs = saveAs || (function(view) {\n\t\"use strict\";\n\t// IE <10 is explicitly unsupported\n\tif (typeof view === \"undefined\" || typeof navigator !== \"undefined\" && /MSIE [1-9]\\./.test(navigator.userAgent)) {\n\t\treturn;\n\t}\n\tvar\n\t\t doc = view.document\n\t\t // only get URL when necessary in case Blob.js hasn't overridden it yet\n\t\t, get_URL = function() {\n\t\t\treturn view.URL || view.webkitURL || view;\n\t\t}\n\t\t, save_link = doc.createElementNS(\"http://www.w3.org/1999/xhtml\", \"a\")\n\t\t, can_use_save_link = \"download\" in save_link\n\t\t, click = function(node) {\n\t\t\tvar event = new MouseEvent(\"click\");\n\t\t\tnode.dispatchEvent(event);\n\t\t}\n\t\t, is_safari = /constructor/i.test(view.HTMLElement) || view.safari\n\t\t, is_chrome_ios =/CriOS\\/[\\d]+/.test(navigator.userAgent)\n\t\t, throw_outside = function(ex) {\n\t\t\t(view.setImmediate || view.setTimeout)(function() {\n\t\t\t\tthrow ex;\n\t\t\t}, 0);\n\t\t}\n\t\t, force_saveable_type = \"application/octet-stream\"\n\t\t// the Blob API is fundamentally broken as there is no \"downloadfinished\" event to subscribe to\n\t\t, arbitrary_revoke_timeout = 1000 * 40 // in ms\n\t\t, revoke = function(file) {\n\t\t\tvar revoker = function() {\n\t\t\t\tif (typeof file === \"string\") { // file is an object URL\n\t\t\t\t\tget_URL().revokeObjectURL(file);\n\t\t\t\t} else { // file is a File\n\t\t\t\t\tfile.remove();\n\t\t\t\t}\n\t\t\t};\n\t\t\tsetTimeout(revoker, arbitrary_revoke_timeout);\n\t\t}\n\t\t, dispatch = function(filesaver, event_types, event) {\n\t\t\tevent_types = [].concat(event_types);\n\t\t\tvar i = event_types.length;\n\t\t\twhile (i--) {\n\t\t\t\tvar listener = filesaver[\"on\" + event_types[i]];\n\t\t\t\tif (typeof listener === \"function\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlistener.call(filesaver, event || filesaver);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\tthrow_outside(ex);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t, auto_bom = function(blob) {\n\t\t\t// prepend BOM for UTF-8 XML and text/* types (including HTML)\n\t\t\t// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF\n\t\t\tif (/^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(blob.type)) {\n\t\t\t\treturn new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});\n\t\t\t}\n\t\t\treturn blob;\n\t\t}\n\t\t, FileSaver = function(blob, name, no_auto_bom) {\n\t\t\tif (!no_auto_bom) {\n\t\t\t\tblob = auto_bom(blob);\n\t\t\t}\n\t\t\t// First try a.download, then web filesystem, then object URLs\n\t\t\tvar\n\t\t\t\t filesaver = this\n\t\t\t\t, type = blob.type\n\t\t\t\t, force = type === force_saveable_type\n\t\t\t\t, object_url\n\t\t\t\t, dispatch_all = function() {\n\t\t\t\t\tdispatch(filesaver, \"writestart progress write writeend\".split(\" \"));\n\t\t\t\t}\n\t\t\t\t// on any filesys errors revert to saving with object URLs\n\t\t\t\t, fs_error = function() {\n\t\t\t\t\tif ((is_chrome_ios || (force && is_safari)) && view.FileReader) {\n\t\t\t\t\t\t// Safari doesn't allow downloading of blob urls\n\t\t\t\t\t\tvar reader = new FileReader();\n\t\t\t\t\t\treader.onloadend = function() {\n\t\t\t\t\t\t\tvar url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');\n\t\t\t\t\t\t\tvar popup = view.open(url, '_blank');\n\t\t\t\t\t\t\tif(!popup) view.location.href = url;\n\t\t\t\t\t\t\turl=undefined; // release reference before dispatching\n\t\t\t\t\t\t\tfilesaver.readyState = filesaver.DONE;\n\t\t\t\t\t\t\tdispatch_all();\n\t\t\t\t\t\t};\n\t\t\t\t\t\treader.readAsDataURL(blob);\n\t\t\t\t\t\tfilesaver.readyState = filesaver.INIT;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// don't create more object URLs than needed\n\t\t\t\t\tif (!object_url) {\n\t\t\t\t\t\tobject_url = get_URL().createObjectURL(blob);\n\t\t\t\t\t}\n\t\t\t\t\tif (force) {\n\t\t\t\t\t\tview.location.href = object_url;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar opened = view.open(object_url, \"_blank\");\n\t\t\t\t\t\tif (!opened) {\n\t\t\t\t\t\t\t// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html\n\t\t\t\t\t\t\tview.location.href = object_url;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfilesaver.readyState = filesaver.DONE;\n\t\t\t\t\tdispatch_all();\n\t\t\t\t\trevoke(object_url);\n\t\t\t\t}\n\t\t\t;\n\t\t\tfilesaver.readyState = filesaver.INIT;\n\n\t\t\tif (can_use_save_link) {\n\t\t\t\tobject_url = get_URL().createObjectURL(blob);\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\tsave_link.href = object_url;\n\t\t\t\t\tsave_link.download = name;\n\t\t\t\t\tclick(save_link);\n\t\t\t\t\tdispatch_all();\n\t\t\t\t\trevoke(object_url);\n\t\t\t\t\tfilesaver.readyState = filesaver.DONE;\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfs_error();\n\t\t}\n\t\t, FS_proto = FileSaver.prototype\n\t\t, saveAs = function(blob, name, no_auto_bom) {\n\t\t\treturn new FileSaver(blob, name || blob.name || \"download\", no_auto_bom);\n\t\t}\n\t;\n\t// IE 10+ (native saveAs)\n\tif (typeof navigator !== \"undefined\" && navigator.msSaveOrOpenBlob) {\n\t\treturn function(blob, name, no_auto_bom) {\n\t\t\tname = name || blob.name || \"download\";\n\n\t\t\tif (!no_auto_bom) {\n\t\t\t\tblob = auto_bom(blob);\n\t\t\t}\n\t\t\treturn navigator.msSaveOrOpenBlob(blob, name);\n\t\t};\n\t}\n\n\tFS_proto.abort = function(){};\n\tFS_proto.readyState = FS_proto.INIT = 0;\n\tFS_proto.WRITING = 1;\n\tFS_proto.DONE = 2;\n\n\tFS_proto.error =\n\tFS_proto.onwritestart =\n\tFS_proto.onprogress =\n\tFS_proto.onwrite =\n\tFS_proto.onabort =\n\tFS_proto.onerror =\n\tFS_proto.onwriteend =\n\t\tnull;\n\n\treturn saveAs;\n}(\n\t typeof self !== \"undefined\" && self\n\t|| typeof window !== \"undefined\" && window\n\t|| this.content\n));\n// `self` is undefined in Firefox for Android content script context\n// while `this` is nsIContentFrameMessageManager\n// with an attribute `content` that corresponds to the window\n\nif (typeof module !== \"undefined\" && module.exports) {\n module.exports.saveAs = saveAs;\n} else if ((typeof define !== \"undefined\" && define !== null) && (define.amd !== null)) {\n define(\"FileSaver.js\", function() {\n return saveAs;\n });\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-saver/FileSaver.js\n// module id = 138\n// module chunks = 0","exports.read = function (buffer, offset, isLE, mLen, nBytes) {\n var e, m\n var eLen = nBytes * 8 - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var nBits = -7\n var i = isLE ? (nBytes - 1) : 0\n var d = isLE ? -1 : 1\n var s = buffer[offset + i]\n\n i += d\n\n e = s & ((1 << (-nBits)) - 1)\n s >>= (-nBits)\n nBits += eLen\n for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & ((1 << (-nBits)) - 1)\n e >>= (-nBits)\n nBits += mLen\n for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity)\n } else {\n m = m + Math.pow(2, mLen)\n e = e - eBias\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c\n var eLen = nBytes * 8 - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n var i = isLE ? 0 : (nBytes - 1)\n var d = isLE ? 1 : -1\n var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n value = Math.abs(value)\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0\n e = eMax\n } else {\n e = Math.floor(Math.log(value) / Math.LN2)\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--\n c *= 2\n }\n if (e + eBias >= 1) {\n value += rt / c\n } else {\n value += rt * Math.pow(2, 1 - eBias)\n }\n if (value * c >= 2) {\n e++\n c /= 2\n }\n\n if (e + eBias >= eMax) {\n m = 0\n e = eMax\n } else if (e + eBias >= 1) {\n m = (value * c - 1) * Math.pow(2, mLen)\n e = e + eBias\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n e = 0\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = (e << mLen) | m\n eLen += mLen\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/ieee754/index.js\n// module id = 139\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\nexports.Writer = exports.VexFlow = exports.Utils = exports.Track = exports.ProgramChangeEvent = exports.NoteOnEvent = exports.NoteOffEvent = exports.NoteEvent = exports.MetaEvent = exports.ControllerChangeEvent = exports.Constants = exports.Chunk = undefined;\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _tonalMidi = require('tonal-midi');\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Object representation of the chunk section of a MIDI file.\n * @param {object} fields - {type: number, data: array, size: array}\n * @return {Chunk}\n */\nvar Chunk = function Chunk(fields) {\n\t_classCallCheck(this, Chunk);\n\n\tthis.type = fields.type;\n\tthis.data = fields.data;\n\tthis.size = [0, 0, 0, fields.data.length];\n};\n\nexports.Chunk = Chunk;\n/**\n * MIDI file format constants, including note -> MIDI number translation.\n * @return {Constants}\n */\n\nvar Constants = {\n\tVERSION: '1.5.2',\n\tHEADER_CHUNK_TYPE: [0x4d, 0x54, 0x68, 0x64], // Mthd\n\tHEADER_CHUNK_LENGTH: [0x00, 0x00, 0x00, 0x06], // Header size for SMF\n\tHEADER_CHUNK_FORMAT0: [0x00, 0x00], // Midi Type 0 id\n\tHEADER_CHUNK_FORMAT1: [0x00, 0x01], // Midi Type 1 id\n\tHEADER_CHUNK_DIVISION: [0x00, 0x80], // Defaults to 128 ticks per beat\n\tTRACK_CHUNK_TYPE: [0x4d, 0x54, 0x72, 0x6b], // MTrk,\n\tMETA_EVENT_ID: 0xFF,\n\tMETA_TEXT_ID: 0x01,\n\tMETA_COPYRIGHT_ID: 0x02,\n\tMETA_TRACK_NAME_ID: 0x03,\n\tMETA_INSTRUMENT_NAME_ID: 0x04,\n\tMETA_LYRIC_ID: 0x05,\n\tMETA_MARKER_ID: 0x06,\n\tMETA_CUE_POINT: 0x07,\n\tMETA_TEMPO_ID: 0x51,\n\tMETA_SMTPE_OFFSET: 0x54,\n\tMETA_TIME_SIGNATURE_ID: 0x58,\n\tMETA_KEY_SIGNATURE_ID: 0x59,\n\tMETA_END_OF_TRACK_ID: [0x2F, 0x00],\n\tCONTROLLER_CHANGE_STATUS: 0xB0, // includes channel number (0)\n\tPROGRAM_CHANGE_STATUS: 0xC0 // includes channel number (0)\n};\n\nexports.Constants = Constants;\n/**\n * Holds all data for a \"controller change\" MIDI event\n * @param {object} fields {controllerNumber: integer, controllerValue: integer}\n * @return {ControllerChangeEvent}\n */\n\nvar ControllerChangeEvent = function ControllerChangeEvent(fields) {\n\t_classCallCheck(this, ControllerChangeEvent);\n\n\tthis.type = 'controller';\n\t// delta time defaults to 0.\n\tthis.data = Utils.numberToVariableLength(0x00).concat(Constants.CONTROLLER_CHANGE_STATUS, fields.controllerNumber, fields.controllerValue);\n};\n\nexports.ControllerChangeEvent = ControllerChangeEvent;\n/**\n * Object representation of a meta event.\n * @param {object} fields - type, data\n * @return {MetaEvent}\n */\n\nvar MetaEvent = function MetaEvent(fields) {\n\t_classCallCheck(this, MetaEvent);\n\n\tthis.type = 'meta';\n\tthis.data = Utils.numberToVariableLength(0x00); // Start with zero time delta\n\tthis.data = this.data.concat(Constants.META_EVENT_ID, fields.data);\n};\n\nexports.MetaEvent = MetaEvent;\n/**\n * Wrapper for noteOnEvent/noteOffEvent objects that builds both events.\n * @param {object} fields - {pitch: '[C4]', duration: '4', wait: '4', velocity: 1-100}\n * @return {NoteEvent}\n */\n\nvar NoteEvent = function () {\n\tfunction NoteEvent(fields) {\n\t\t_classCallCheck(this, NoteEvent);\n\n\t\tthis.type = 'note';\n\t\tthis.pitch = Utils.toArray(fields.pitch);\n\t\tthis.wait = fields.wait || 0;\n\t\tthis.duration = fields.duration;\n\t\tthis.sequential = fields.sequential || false;\n\t\tthis.velocity = fields.velocity || 50;\n\t\tthis.channel = fields.channel || 1;\n\t\tthis.repeat = fields.repeat || 1;\n\t\tthis.velocity = this.convertVelocity(this.velocity);\n\t\tthis.grace = fields.grace;\n\t\tthis.buildData();\n\t}\n\n\t/**\n * Builds int array for this event.\n * @return {NoteEvent}\n */\n\n\n\t_createClass(NoteEvent, [{\n\t\tkey: 'buildData',\n\t\tvalue: function buildData() {\n\t\t\tthis.data = [];\n\n\t\t\tvar tickDuration = this.getTickDuration(this.duration, 'note');\n\t\t\tvar restDuration = this.getTickDuration(this.wait, 'rest');\n\n\t\t\t// Apply grace note(s) and subtract ticks (currently 1 tick per grace note) from tickDuration so net value is the same\n\t\t\tif (this.grace) {\n\t\t\t\tvar graceDuration = 1;\n\t\t\t\tthis.grace = Utils.toArray(this.grace);\n\t\t\t\tthis.grace.forEach(function (pitch) {\n\t\t\t\t\tvar noteEvent = new NoteEvent({ pitch: this.grace, duration: 'T' + graceDuration });\n\t\t\t\t\tthis.data = this.data.concat(noteEvent.data);\n\n\t\t\t\t\ttickDuration -= graceDuration;\n\t\t\t\t}, this);\n\t\t\t}\n\n\t\t\t// fields.pitch could be an array of pitches.\n\t\t\t// If so create note events for each and apply the same duration.\n\t\t\tvar noteOn, noteOff;\n\t\t\tif (Array.isArray(this.pitch)) {\n\t\t\t\t// By default this is a chord if it's an array of notes that requires one NoteOnEvent.\n\t\t\t\t// If this.sequential === true then it's a sequential string of notes that requires separate NoteOnEvents.\n\t\t\t\tif (!this.sequential) {\n\t\t\t\t\t// Handle repeat\n\t\t\t\t\tfor (var j = 0; j < this.repeat; j++) {\n\t\t\t\t\t\t// Note on\n\t\t\t\t\t\tthis.pitch.forEach(function (p, i) {\n\t\t\t\t\t\t\tif (i == 0) {\n\t\t\t\t\t\t\t\tnoteOn = new NoteOnEvent({ data: Utils.numberToVariableLength(restDuration).concat(this.getNoteOnStatus(), Utils.getPitch(p), this.velocity) });\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Running status (can ommit the note on status)\n\t\t\t\t\t\t\t\tnoteOn = new NoteOnEvent({ data: [0, Utils.getPitch(p), this.velocity] });\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.data = this.data.concat(noteOn.data);\n\t\t\t\t\t\t}, this);\n\n\t\t\t\t\t\t// Note off\n\t\t\t\t\t\tthis.pitch.forEach(function (p, i) {\n\t\t\t\t\t\t\tif (i == 0) {\n\t\t\t\t\t\t\t\tnoteOff = new NoteOffEvent({ data: Utils.numberToVariableLength(tickDuration).concat(this.getNoteOffStatus(), Utils.getPitch(p), this.velocity) });\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Running status (can ommit the note off status)\n\t\t\t\t\t\t\t\tnoteOff = new NoteOffEvent({ data: [0, Utils.getPitch(p), this.velocity] });\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.data = this.data.concat(noteOff.data);\n\t\t\t\t\t\t}, this);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Handle repeat\n\t\t\t\t\tfor (var j = 0; j < this.repeat; j++) {\n\t\t\t\t\t\tthis.pitch.forEach(function (p, i) {\n\t\t\t\t\t\t\t// restDuration only applies to first note\n\t\t\t\t\t\t\tif (i > 0) {\n\t\t\t\t\t\t\t\trestDuration = 0;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// If duration is 8th triplets we need to make sure that the total ticks == quarter note.\n\t\t\t\t\t\t\t// So, the last one will need to be the remainder\n\t\t\t\t\t\t\tif (this.duration === '8t' && i == this.pitch.length - 1) {\n\t\t\t\t\t\t\t\tvar quarterTicks = Utils.numberFromBytes(Constants.HEADER_CHUNK_DIVISION);\n\t\t\t\t\t\t\t\ttickDuration = quarterTicks - tickDuration * 2;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tnoteOn = new NoteOnEvent({ data: Utils.numberToVariableLength(restDuration).concat([this.getNoteOnStatus(), Utils.getPitch(p), this.velocity]) });\n\t\t\t\t\t\t\tnoteOff = new NoteOffEvent({ data: Utils.numberToVariableLength(tickDuration).concat([this.getNoteOffStatus(), Utils.getPitch(p), this.velocity]) });\n\n\t\t\t\t\t\t\tthis.data = this.data.concat(noteOn.data, noteOff.data);\n\t\t\t\t\t\t}, this);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t}\n\n\t\t\tthrow 'pitch must be an array.';\n\t\t}\n\t}, {\n\t\tkey: 'convertVelocity',\n\n\n\t\t/**\n * Converts velocity to value 0-127\n * @param {number} velocity - Velocity value 1-100\n * @return {number}\n */\n\t\tvalue: function convertVelocity(velocity) {\n\t\t\t// Max passed value limited to 100\n\t\t\tvelocity = velocity > 100 ? 100 : velocity;\n\t\t\treturn Math.round(velocity / 100 * 127);\n\t\t}\n\t}, {\n\t\tkey: 'getTickDuration',\n\n\n\t\t/**\n * Gets the total number of ticks based on passed duration.\n * Note: type=='note' defaults to quarter note, type==='rest' defaults to 0\n * @param {(string|array)} duration\n * @param {string} type ['note', 'rest']\n * @return {number}\n */\n\t\tvalue: function getTickDuration(duration, type) {\n\t\t\tif (Array.isArray(duration)) {\n\t\t\t\t// Recursively execute this method for each item in the array and return the sum of tick durations.\n\t\t\t\treturn duration.map(function (value) {\n\t\t\t\t\treturn this.getTickDuration(value, type);\n\t\t\t\t}, this).reduce(function (a, b) {\n\t\t\t\t\treturn a + b;\n\t\t\t\t}, 0);\n\t\t\t}\n\n\t\t\tduration = duration.toString();\n\n\t\t\tif (duration.toLowerCase().charAt(0) === 't') {\n\t\t\t\t// If duration starts with 't' then the number that follows is an explicit tick count\n\t\t\t\treturn parseInt(duration.substring(1));\n\t\t\t}\n\n\t\t\t// Need to apply duration here. Quarter note == Constants.HEADER_CHUNK_DIVISION\n\t\t\t// Rounding only applies to triplets, which the remainder is handled below\n\t\t\tvar quarterTicks = Utils.numberFromBytes(Constants.HEADER_CHUNK_DIVISION);\n\t\t\treturn Math.round(quarterTicks * this.getDurationMultiplier(duration, type));\n\t\t}\n\n\t\t/**\n * Gets what to multiple ticks/quarter note by to get the specified duration.\n * Note: type=='note' defaults to quarter note, type==='rest' defaults to 0\n * @param {string} duration\n * @param {string} type ['note','rest']\n * @return {number}\n */\n\n\t}, {\n\t\tkey: 'getDurationMultiplier',\n\t\tvalue: function getDurationMultiplier(duration, type) {\n\t\t\t// Need to apply duration here. Quarter note == Constants.HEADER_CHUNK_DIVISION\n\t\t\tswitch (duration) {\n\t\t\t\tcase '0':\n\t\t\t\t\treturn 0;\n\t\t\t\tcase '1':\n\t\t\t\t\treturn 4;\n\t\t\t\tcase '2':\n\t\t\t\t\treturn 2;\n\t\t\t\tcase 'd2':\n\t\t\t\t\treturn 3;\n\t\t\t\tcase '4':\n\t\t\t\t\treturn 1;\n\t\t\t\tcase '4t':\n\t\t\t\t\treturn 0.666;\n\t\t\t\tcase 'd4':\n\t\t\t\t\treturn 1.5;\n\t\t\t\tcase '8':\n\t\t\t\t\treturn 0.5;\n\t\t\t\tcase '8t':\n\t\t\t\t\t// For 8th triplets, let's divide a quarter by 3, round to the nearest int, and substract the remainder to the last one.\n\t\t\t\t\treturn 0.33;\n\t\t\t\tcase 'd8':\n\t\t\t\t\treturn 0.75;\n\t\t\t\tcase '16':\n\t\t\t\t\treturn 0.25;\n\t\t\t\tcase '16t':\n\t\t\t\t\treturn 0.166;\n\t\t\t\tcase '32':\n\t\t\t\t\treturn 0.125;\n\t\t\t\tcase '64':\n\t\t\t\t\treturn 0.0625;\n\t\t\t\tdefault:\n\t\t\t\t// Notes default to a quarter, rests default to 0\n\t\t\t\t//return type === 'note' ? 1 : 0;\n\t\t\t}\n\n\t\t\tthrow duration + ' is not a valid duration.';\n\t\t}\n\t}, {\n\t\tkey: 'getNoteOnStatus',\n\n\n\t\t/**\n * Gets the note on status code based on the selected channel. 0x9{0-F}\n * Note on at channel 0 is 0x90 (144)\n * 0 = Ch 1\n * @return {number}\n */\n\t\tvalue: function getNoteOnStatus() {\n\t\t\treturn 144 + this.channel - 1;\n\t\t}\n\n\t\t/**\n * Gets the note off status code based on the selected channel. 0x8{0-F}\n * Note off at channel 0 is 0x80 (128)\n * 0 = Ch 1\n * @return {number}\n */\n\n\t}, {\n\t\tkey: 'getNoteOffStatus',\n\t\tvalue: function getNoteOffStatus() {\n\t\t\treturn 128 + this.channel - 1;\n\t\t}\n\t}]);\n\n\treturn NoteEvent;\n}();\n\nexports.NoteEvent = NoteEvent;\n/**\n * Holds all data for a \"note off\" MIDI event\n * @param {object} fields {data: []}\n * @return {NoteOffEvent}\n */\n\nvar NoteOffEvent = function NoteOffEvent(fields) {\n\t_classCallCheck(this, NoteOffEvent);\n\n\tthis.data = fields.data;\n};\n\nexports.NoteOffEvent = NoteOffEvent;\n/**\n * Holds all data for a \"note on\" MIDI event\n * @param {object} fields {data: []}\n * @return {NoteOnEvent}\n */\n\nvar NoteOnEvent = function NoteOnEvent(fields) {\n\t_classCallCheck(this, NoteOnEvent);\n\n\tthis.data = fields.data;\n};\n\nexports.NoteOnEvent = NoteOnEvent;\n/**\n * Holds all data for a \"program change\" MIDI event\n * @param {object} fields {instrument: integer}\n * @return {ProgramChangeEvent}\n */\n\nvar ProgramChangeEvent = function ProgramChangeEvent(fields) {\n\t_classCallCheck(this, ProgramChangeEvent);\n\n\tthis.type = 'program';\n\t// delta time defaults to 0.\n\tthis.data = Utils.numberToVariableLength(0x00).concat(Constants.PROGRAM_CHANGE_STATUS, fields.instrument);\n};\n\nexports.ProgramChangeEvent = ProgramChangeEvent;\n/**\n * Holds all data for a track.\n * @param {object} fields {type: number, data: array, size: array, events: array}\n * @return {Track}\n */\n\nvar Track = function () {\n\tfunction Track() {\n\t\t_classCallCheck(this, Track);\n\n\t\tthis.type = Constants.TRACK_CHUNK_TYPE;\n\t\tthis.data = [];\n\t\tthis.size = [];\n\t\tthis.events = [];\n\t}\n\n\t/**\n * Adds any event type to the track.\n * @param {(NoteEvent|MetaEvent|ProgramChangeEvent)} event - Event object.\n * @param {function} mapFunction - Callback which can be used to apply specific properties to all events. \n * @return {Track}\n */\n\n\n\t_createClass(Track, [{\n\t\tkey: 'addEvent',\n\t\tvalue: function addEvent(event, mapFunction) {\n\t\t\tif (Array.isArray(event)) {\n\t\t\t\tevent.forEach(function (e, i) {\n\t\t\t\t\t// Handle map function if provided\n\t\t\t\t\tif (typeof mapFunction === 'function' && e.type === 'note') {\n\t\t\t\t\t\tvar properties = mapFunction(i, e);\n\n\t\t\t\t\t\tif ((typeof properties === 'undefined' ? 'undefined' : _typeof(properties)) === 'object') {\n\t\t\t\t\t\t\tfor (var j in properties) {\n\t\t\t\t\t\t\t\tswitch (j) {\n\t\t\t\t\t\t\t\t\tcase 'duration':\n\t\t\t\t\t\t\t\t\t\te.duration = properties[j];\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'sequential':\n\t\t\t\t\t\t\t\t\t\te.sequential = properties[j];\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'velocity':\n\t\t\t\t\t\t\t\t\t\te.velocity = e.convertVelocity(properties[j]);\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Gotta build that data\n\t\t\t\t\t\t\te.buildData();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.data = this.data.concat(e.data);\n\t\t\t\t\tthis.size = Utils.numberToBytes(this.data.length, 4); // 4 bytes long\n\t\t\t\t\tthis.events.push(e);\n\t\t\t\t}, this);\n\t\t\t} else {\n\t\t\t\tthis.data = this.data.concat(event.data);\n\t\t\t\tthis.size = Utils.numberToBytes(this.data.length, 4); // 4 bytes long\n\t\t\t\tthis.events.push(event);\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\t/**\n * Sets tempo of the MIDI file.\n * @param {number} bpm - Tempo in beats per minute.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'setTempo',\n\t\tvalue: function setTempo(bpm) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_TEMPO_ID] });\n\t\t\tevent.data.push(0x03); // Size\n\t\t\tvar tempo = Math.round(60000000 / bpm);\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(tempo, 3)); // Tempo, 3 bytes\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Sets time signature.\n * @param {number} numerator - Top number of the time signature.\n * @param {number} denominator - Bottom number of the time signature.\n * @param {number} midiclockspertick - Defaults to 24.\n * @param {number} notespermidiclock - Defaults to 8.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'setTimeSignature',\n\t\tvalue: function setTimeSignature(numerator, denominator, midiclockspertick, notespermidiclock) {\n\t\t\tmidiclockspertick = midiclockspertick || 24;\n\t\t\tnotespermidiclock = notespermidiclock || 8;\n\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_TIME_SIGNATURE_ID] });\n\t\t\tevent.data.push(0x04); // Size\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(numerator, 1)); // Numerator, 1 bytes\n\n\t\t\tvar _denominator = Math.log2(denominator); // Denominator is expressed as pow of 2\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(_denominator, 1)); // Denominator, 1 bytes\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(midiclockspertick, 1)); // MIDI Clocks per tick, 1 bytes\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(notespermidiclock, 1)); // Number of 1/32 notes per MIDI clocks, 1 bytes\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Sets key signature.\n * @param {*} sf - \n * @param {*} mi -\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'setKeySignature',\n\t\tvalue: function setKeySignature(sf, mi) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_KEY_SIGNATURE_ID] });\n\t\t\tevent.data.push(0x02); // Size\n\n\t\t\tvar mode = mi || 0;\n\t\t\tsf = sf || 0;\n\n\t\t\t//\tFunction called with string notation\n\t\t\tif (typeof mi === 'undefined') {\n\t\t\t\tvar fifths = [['Cb', 'Gb', 'Db', 'Ab', 'Eb', 'Bb', 'F', 'C', 'G', 'D', 'A', 'E', 'B', 'F#', 'C#'], ['ab', 'eb', 'bb', 'f', 'c', 'g', 'd', 'a', 'e', 'b', 'f#', 'c#', 'g#', 'd#', 'a#']];\n\t\t\t\tvar _sflen = sf.length;\n\t\t\t\tvar note = sf || 'C';\n\n\t\t\t\tif (sf[0] === sf[0].toLowerCase()) mode = 1;\n\n\t\t\t\tif (_sflen > 1) {\n\t\t\t\t\tswitch (sf.charAt(_sflen - 1)) {\n\t\t\t\t\t\tcase 'm':\n\t\t\t\t\t\t\tmode = 1;\n\t\t\t\t\t\t\tnote = sf.charAt(0).toLowerCase();\n\t\t\t\t\t\t\tnote = note.concat(sf.substring(1, _sflen - 1));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '-':\n\t\t\t\t\t\t\tmode = 1;\n\t\t\t\t\t\t\tnote = sf.charAt(0).toLowerCase();\n\t\t\t\t\t\t\tnote = note.concat(sf.substring(1, _sflen - 1));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'M':\n\t\t\t\t\t\t\tmode = 0;\n\t\t\t\t\t\t\tnote = sf.charAt(0).toUpperCase();\n\t\t\t\t\t\t\tnote = note.concat(sf.substring(1, _sflen - 1));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '+':\n\t\t\t\t\t\t\tmode = 0;\n\t\t\t\t\t\t\tnote = sf.charAt(0).toUpperCase();\n\t\t\t\t\t\t\tnote = note.concat(sf.substring(1, _sflen - 1));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar fifthindex = fifths[mode].indexOf(note);\n\t\t\t\tsf = fifthindex === -1 ? 0 : fifthindex - 7;\n\t\t\t}\n\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(sf, 1)); // Number of sharp or flats ( < 0 flat; > 0 sharp)\n\t\t\tevent.data = event.data.concat(Utils.numberToBytes(mode, 1)); // Mode: 0 major, 1 minor\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Adds text to MIDI file.\n * @param {string} text - Text to add.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addText',\n\t\tvalue: function addText(text) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_TEXT_ID] });\n\t\t\tvar stringBytes = Utils.stringToBytes(text);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Text\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Adds copyright to MIDI file.\n * @param {string} text - Text of copyright line.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addCopyright',\n\t\tvalue: function addCopyright(text) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_COPYRIGHT_ID] });\n\t\t\tvar stringBytes = Utils.stringToBytes(text);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Text\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Adds Sequence/Track Name.\n * @param {string} text - Text of track name.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addTrackName',\n\t\tvalue: function addTrackName(text) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_TRACK_NAME_ID] });\n\t\t\tvar stringBytes = Utils.stringToBytes(text);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Text\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Sets instrument name of track.\n * @param {string} text - Name of instrument.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addInstrumentName',\n\t\tvalue: function addInstrumentName(text) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_INSTRUMENT_NAME_ID] });\n\t\t\tvar stringBytes = Utils.stringToBytes(text);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Text\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Adds marker to MIDI file.\n * @param {string} text - Marker text.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addMarker',\n\t\tvalue: function addMarker(text) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_MARKER_ID] });\n\t\t\tvar stringBytes = Utils.stringToBytes(text);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Text\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Adds cue point to MIDI file.\n * @param {string} text - Text of cue point.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addCuePoint',\n\t\tvalue: function addCuePoint(text) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_CUE_POINT] });\n\t\t\tvar stringBytes = Utils.stringToBytes(text);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Text\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Adds lyric to MIDI file.\n * @param {string} lyric - Lyric text to add.\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'addLyric',\n\t\tvalue: function addLyric(lyric) {\n\t\t\tvar event = new MetaEvent({ data: [Constants.META_LYRIC_ID] });\n\t\t\tvar stringBytes = Utils.stringToBytes(lyric);\n\t\t\tevent.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size\n\t\t\tevent.data = event.data.concat(stringBytes); // Lyric\n\t\t\treturn this.addEvent(event);\n\t\t}\n\n\t\t/**\n * Channel mode messages\n * @return {Track}\n */\n\n\t}, {\n\t\tkey: 'polyModeOn',\n\t\tvalue: function polyModeOn() {\n\t\t\tvar event = new NoteOnEvent({ data: [0x00, 0xB0, 0x7E, 0x00] });\n\t\t\treturn this.addEvent(event);\n\t\t}\n\t}]);\n\n\treturn Track;\n}();\n\nexports.Track = Track;\n\n/**\n * Static utility functions used throughout the library.\n */\nvar Utils = function () {\n\tfunction Utils() {\n\t\t_classCallCheck(this, Utils);\n\t}\n\n\t_createClass(Utils, null, [{\n\t\tkey: 'version',\n\n\n\t\t/**\n * Gets MidiWriterJS version number.\n * @return {string}\n */\n\t\tvalue: function version() {\n\t\t\treturn Constants.VERSION;\n\t\t}\n\n\t\t/**\n * Convert a string to an array of bytes\n * @param {string} string\n * @return {array}\n */\n\n\t}, {\n\t\tkey: 'stringToBytes',\n\t\tvalue: function stringToBytes(string) {\n\t\t\treturn string.split('').map(function (char) {\n\t\t\t\treturn char.charCodeAt();\n\t\t\t});\n\t\t}\n\n\t\t/**\n * Checks if argument is a valid number.\n * @param {*} n - Value to check\n * @return {boolean}\n */\n\n\t}, {\n\t\tkey: 'isNumeric',\n\t\tvalue: function isNumeric(n) {\n\t\t\treturn !isNaN(parseFloat(n)) && isFinite(n);\n\t\t}\n\n\t\t/**\n * Returns the correct MIDI number for the specified pitch.\n * Uses Tonal Midi - https://github.com/danigb/tonal/tree/master/packages/midi\n * @param {(string|number)} pitch - 'C#4' or midi note code\n * @return {number}\n */\n\n\t}, {\n\t\tkey: 'getPitch',\n\t\tvalue: function getPitch(pitch) {\n\t\t\treturn (0, _tonalMidi.toMidi)(pitch);\n\t\t}\n\n\t\t/**\n * Translates number of ticks to MIDI timestamp format, returning an array of\n * hex strings with the time values. Midi has a very particular time to express time,\n * take a good look at the spec before ever touching this function.\n * Thanks to https://github.com/sergi/jsmidi\n *\n * @param {number} ticks - Number of ticks to be translated\n * @return {array} - Bytes that form the MIDI time value\n */\n\n\t}, {\n\t\tkey: 'numberToVariableLength',\n\t\tvalue: function numberToVariableLength(ticks) {\n\t\t\tvar buffer = ticks & 0x7F;\n\n\t\t\twhile (ticks = ticks >> 7) {\n\t\t\t\tbuffer <<= 8;\n\t\t\t\tbuffer |= ticks & 0x7F | 0x80;\n\t\t\t}\n\n\t\t\tvar bList = [];\n\t\t\twhile (true) {\n\t\t\t\tbList.push(buffer & 0xff);\n\n\t\t\t\tif (buffer & 0x80) buffer >>= 8;else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn bList;\n\t\t}\n\n\t\t/**\n * Counts number of bytes in string\n * @param {string} s\n * @return {array}\n */\n\n\t}, {\n\t\tkey: 'stringByteCount',\n\t\tvalue: function stringByteCount(s) {\n\t\t\treturn encodeURI(s).split(/%..|./).length - 1;\n\t\t}\n\n\t\t/**\n * Get an int from an array of bytes.\n * @param {array} bytes\n * @return {number}\n */\n\n\t}, {\n\t\tkey: 'numberFromBytes',\n\t\tvalue: function numberFromBytes(bytes) {\n\t\t\tvar hex = '';\n\t\t\tvar stringResult;\n\n\t\t\tbytes.forEach(function (byte) {\n\t\t\t\tstringResult = byte.toString(16);\n\n\t\t\t\t// ensure string is 2 chars\n\t\t\t\tif (stringResult.length == 1) stringResult = \"0\" + stringResult;\n\n\t\t\t\thex += stringResult;\n\t\t\t});\n\n\t\t\treturn parseInt(hex, 16);\n\t\t}\n\n\t\t/**\n * Takes a number and splits it up into an array of bytes. Can be padded by passing a number to bytesNeeded\n * @param {number} number\n * @param {number} bytesNeeded\n * @return {array} - Array of bytes\n */\n\n\t}, {\n\t\tkey: 'numberToBytes',\n\t\tvalue: function numberToBytes(number, bytesNeeded) {\n\t\t\tbytesNeeded = bytesNeeded || 1;\n\n\t\t\tvar hexString = number.toString(16);\n\n\t\t\tif (hexString.length & 1) {\n\t\t\t\t// Make sure hex string is even number of chars\n\t\t\t\thexString = '0' + hexString;\n\t\t\t}\n\n\t\t\t// Split hex string into an array of two char elements\n\t\t\tvar hexArray = hexString.match(/.{2}/g);\n\n\t\t\t// Now parse them out as integers\n\t\t\thexArray = hexArray.map(function (item) {\n\t\t\t\treturn parseInt(item, 16);\n\t\t\t});\n\n\t\t\t// Prepend empty bytes if we don't have enough\n\t\t\tif (hexArray.length < bytesNeeded) {\n\t\t\t\twhile (bytesNeeded - hexArray.length > 0) {\n\t\t\t\t\thexArray.unshift(0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn hexArray;\n\t\t}\n\n\t\t/**\t\n * Converts value to array if needed.\n * @param {string} value\n * @return {array}\n */\n\n\t}, {\n\t\tkey: 'toArray',\n\t\tvalue: function toArray(value) {\n\t\t\tif (Array.isArray(value)) return value;\n\t\t\treturn [value];\n\t\t}\n\t}]);\n\n\treturn Utils;\n}();\n\nexports.Utils = Utils;\n\nvar VexFlow = function () {\n\tfunction VexFlow() {\n\t\t_classCallCheck(this, VexFlow);\n\t}\n\t// code...\n\n\n\t/**\n * Support for converting VexFlow voice into MidiWriterJS track\n * @return MidiWritier.Track object\n */\n\n\n\t_createClass(VexFlow, [{\n\t\tkey: 'trackFromVoice',\n\t\tvalue: function trackFromVoice(voice) {\n\t\t\tvar track = new Track();\n\t\t\tvar wait;\n\t\t\tvar pitches = [];\n\n\t\t\tvoice.tickables.forEach(function (tickable) {\n\t\t\t\tpitches = [];\n\n\t\t\t\tif (tickable.noteType === 'n') {\n\t\t\t\t\ttickable.keys.forEach(function (key) {\n\t\t\t\t\t\t// build array of pitches\n\t\t\t\t\t\tpitches.push(this.convertPitch(key));\n\t\t\t\t\t});\n\t\t\t\t} else if (tickable.noteType === 'r') {\n\t\t\t\t\t// move on to the next tickable and use this rest as a `wait` property for the next event\n\t\t\t\t\twait = this.convertDuration(tickable);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\ttrack.addEvent(new NoteEvent({ pitch: pitches, duration: this.convertDuration(tickable), wait: wait }));\n\n\t\t\t\t// reset wait\n\t\t\t\twait = 0;\n\t\t\t});\n\n\t\t\treturn track;\n\t\t}\n\n\t\t/**\n * Converts VexFlow pitch syntax to MidiWriterJS syntax\n * @param pitch string\n */\n\n\t}, {\n\t\tkey: 'convertPitch',\n\t\tvalue: function convertPitch(pitch) {\n\t\t\treturn pitch.replace('/', '');\n\t\t}\n\n\t\t/**\n * Converts VexFlow duration syntax to MidiWriterJS syntax\n * @param note struct from VexFlow\n */\n\n\t}, {\n\t\tkey: 'convertDuration',\n\t\tvalue: function convertDuration(note) {\n\t\t\tswitch (note.duration) {\n\t\t\t\tcase 'w':\n\t\t\t\t\treturn '1';\n\t\t\t\tcase 'h':\n\t\t\t\t\treturn note.isDotted() ? 'd2' : '2';\n\t\t\t\tcase 'q':\n\t\t\t\t\treturn note.isDotted() ? 'd4' : '4';\n\t\t\t\tcase '8':\n\t\t\t\t\treturn note.isDotted() ? 'd8' : '8';\n\t\t\t}\n\n\t\t\treturn note.duration;\n\t\t}\n\t}]);\n\n\treturn VexFlow;\n}();\n\nexports.VexFlow = VexFlow;\n/**\n * Object that puts together tracks and provides methods for file output.\n * @param {array} tracks - An array of {Track} objects.\n * @return {Writer}\n */\n\nvar Writer = function () {\n\tfunction Writer(tracks) {\n\t\t_classCallCheck(this, Writer);\n\n\t\tthis.data = [];\n\n\t\tvar trackType = tracks.length > 1 ? Constants.HEADER_CHUNK_FORMAT1 : Constants.HEADER_CHUNK_FORMAT0;\n\t\tvar numberOfTracks = Utils.numberToBytes(tracks.length, 2); // two bytes long\n\n\t\t// Header chunk\n\t\tthis.data.push(new Chunk({\n\t\t\ttype: Constants.HEADER_CHUNK_TYPE,\n\t\t\tdata: trackType.concat(numberOfTracks, Constants.HEADER_CHUNK_DIVISION) }));\n\n\t\t// Track chunks\n\t\ttracks.forEach(function (track, i) {\n\t\t\ttrack.addEvent(new MetaEvent({ data: Constants.META_END_OF_TRACK_ID }));\n\t\t\tthis.data.push(track);\n\t\t}, this);\n\t}\n\n\t/**\n * Builds the file into a Uint8Array\n * @return {Uint8Array}\n */\n\n\n\t_createClass(Writer, [{\n\t\tkey: 'buildFile',\n\t\tvalue: function buildFile() {\n\t\t\tvar build = [];\n\n\t\t\t// Data consists of chunks which consists of data\n\t\t\tthis.data.forEach(function (d) {\n\t\t\t\treturn build = build.concat(d.type, d.size, d.data);\n\t\t\t});\n\n\t\t\treturn new Uint8Array(build);\n\t\t}\n\n\t\t/**\n * Convert file buffer to a base64 string. Different methods depending on if browser or node.\n * @return {string}\n */\n\n\t}, {\n\t\tkey: 'base64',\n\t\tvalue: function base64() {\n\t\t\tif (typeof btoa === 'function') return btoa(String.fromCharCode.apply(null, this.buildFile()));\n\t\t\treturn new Buffer(this.buildFile()).toString('base64');\n\t\t}\n\n\t\t/**\n * Get the data URI.\n * @return {string}\n */\n\n\t}, {\n\t\tkey: 'dataUri',\n\t\tvalue: function dataUri() {\n\t\t\treturn 'data:audio/midi;base64,' + this.base64();\n\t\t}\n\n\t\t/**\n * Output to stdout\n * @return {string}\n */\n\n\t}, {\n\t\tkey: 'stdout',\n\t\tvalue: function stdout() {\n\t\t\treturn process.stdout.write(new Buffer(this.buildFile()));\n\t\t}\n\n\t\t/**\n * Save to MIDI file\n * @param {string} filename\n */\n\n\t}, {\n\t\tkey: 'saveMIDI',\n\t\tvalue: function saveMIDI(filename) {\n\t\t\tvar buffer = new Buffer(this.buildFile());\n\t\t\tfs.writeFile(filename + '.mid', buffer, function (err) {\n\t\t\t\tif (err) return console.log(err);\n\t\t\t});\n\t\t}\n\t}]);\n\n\treturn Writer;\n}();\n\nexports.Writer = Writer;\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbIkNodW5rIiwiZmllbGRzIiwidHlwZSIsImRhdGEiLCJzaXplIiwibGVuZ3RoIiwiQ29uc3RhbnRzIiwiVkVSU0lPTiIsIkhFQURFUl9DSFVOS19UWVBFIiwiSEVBREVSX0NIVU5LX0xFTkdUSCIsIkhFQURFUl9DSFVOS19GT1JNQVQwIiwiSEVBREVSX0NIVU5LX0ZPUk1BVDEiLCJIRUFERVJfQ0hVTktfRElWSVNJT04iLCJUUkFDS19DSFVOS19UWVBFIiwiTUVUQV9FVkVOVF9JRCIsIk1FVEFfVEVYVF9JRCIsIk1FVEFfQ09QWVJJR0hUX0lEIiwiTUVUQV9UUkFDS19OQU1FX0lEIiwiTUVUQV9JTlNUUlVNRU5UX05BTUVfSUQiLCJNRVRBX0xZUklDX0lEIiwiTUVUQV9NQVJLRVJfSUQiLCJNRVRBX0NVRV9QT0lOVCIsIk1FVEFfVEVNUE9fSUQiLCJNRVRBX1NNVFBFX09GRlNFVCIsIk1FVEFfVElNRV9TSUdOQVRVUkVfSUQiLCJNRVRBX0tFWV9TSUdOQVRVUkVfSUQiLCJNRVRBX0VORF9PRl9UUkFDS19JRCIsIkNPTlRST0xMRVJfQ0hBTkdFX1NUQVRVUyIsIlBST0dSQU1fQ0hBTkdFX1NUQVRVUyIsIkNvbnRyb2xsZXJDaGFuZ2VFdmVudCIsIlV0aWxzIiwibnVtYmVyVG9WYXJpYWJsZUxlbmd0aCIsImNvbmNhdCIsImNvbnRyb2xsZXJOdW1iZXIiLCJjb250cm9sbGVyVmFsdWUiLCJNZXRhRXZlbnQiLCJOb3RlRXZlbnQiLCJwaXRjaCIsInRvQXJyYXkiLCJ3YWl0IiwiZHVyYXRpb24iLCJzZXF1ZW50aWFsIiwidmVsb2NpdHkiLCJjaGFubmVsIiwicmVwZWF0IiwiY29udmVydFZlbG9jaXR5IiwiZ3JhY2UiLCJidWlsZERhdGEiLCJ0aWNrRHVyYXRpb24iLCJnZXRUaWNrRHVyYXRpb24iLCJyZXN0RHVyYXRpb24iLCJncmFjZUR1cmF0aW9uIiwiZm9yRWFjaCIsIm5vdGVFdmVudCIsIm5vdGVPbiIsIm5vdGVPZmYiLCJBcnJheSIsImlzQXJyYXkiLCJqIiwicCIsImkiLCJOb3RlT25FdmVudCIsImdldE5vdGVPblN0YXR1cyIsImdldFBpdGNoIiwiTm90ZU9mZkV2ZW50IiwiZ2V0Tm90ZU9mZlN0YXR1cyIsInF1YXJ0ZXJUaWNrcyIsIm51bWJlckZyb21CeXRlcyIsIk1hdGgiLCJyb3VuZCIsIm1hcCIsInZhbHVlIiwicmVkdWNlIiwiYSIsImIiLCJ0b1N0cmluZyIsInRvTG93ZXJDYXNlIiwiY2hhckF0IiwicGFyc2VJbnQiLCJzdWJzdHJpbmciLCJnZXREdXJhdGlvbk11bHRpcGxpZXIiLCJQcm9ncmFtQ2hhbmdlRXZlbnQiLCJpbnN0cnVtZW50IiwiVHJhY2siLCJldmVudHMiLCJldmVudCIsIm1hcEZ1bmN0aW9uIiwiZSIsInByb3BlcnRpZXMiLCJudW1iZXJUb0J5dGVzIiwicHVzaCIsImJwbSIsInRlbXBvIiwiYWRkRXZlbnQiLCJudW1lcmF0b3IiLCJkZW5vbWluYXRvciIsIm1pZGljbG9ja3NwZXJ0aWNrIiwibm90ZXNwZXJtaWRpY2xvY2siLCJfZGVub21pbmF0b3IiLCJsb2cyIiwic2YiLCJtaSIsIm1vZGUiLCJmaWZ0aHMiLCJfc2ZsZW4iLCJub3RlIiwidG9VcHBlckNhc2UiLCJmaWZ0aGluZGV4IiwiaW5kZXhPZiIsInRleHQiLCJzdHJpbmdCeXRlcyIsInN0cmluZ1RvQnl0ZXMiLCJseXJpYyIsInN0cmluZyIsInNwbGl0IiwiY2hhciIsImNoYXJDb2RlQXQiLCJuIiwiaXNOYU4iLCJwYXJzZUZsb2F0IiwiaXNGaW5pdGUiLCJ0aWNrcyIsImJ1ZmZlciIsImJMaXN0IiwicyIsImVuY29kZVVSSSIsImJ5dGVzIiwiaGV4Iiwic3RyaW5nUmVzdWx0IiwiYnl0ZSIsIm51bWJlciIsImJ5dGVzTmVlZGVkIiwiaGV4U3RyaW5nIiwiaGV4QXJyYXkiLCJtYXRjaCIsIml0ZW0iLCJ1bnNoaWZ0IiwiVmV4RmxvdyIsInZvaWNlIiwidHJhY2siLCJwaXRjaGVzIiwidGlja2FibGVzIiwidGlja2FibGUiLCJub3RlVHlwZSIsImtleXMiLCJrZXkiLCJjb252ZXJ0UGl0Y2giLCJjb252ZXJ0RHVyYXRpb24iLCJyZXBsYWNlIiwiaXNEb3R0ZWQiLCJXcml0ZXIiLCJ0cmFja3MiLCJ0cmFja1R5cGUiLCJudW1iZXJPZlRyYWNrcyIsImJ1aWxkIiwiZCIsIlVpbnQ4QXJyYXkiLCJidG9hIiwiU3RyaW5nIiwiZnJvbUNoYXJDb2RlIiwiYXBwbHkiLCJidWlsZEZpbGUiLCJCdWZmZXIiLCJiYXNlNjQiLCJwcm9jZXNzIiwic3Rkb3V0Iiwid3JpdGUiLCJmaWxlbmFtZSIsImZzIiwid3JpdGVGaWxlIiwiZXJyIiwiY29uc29sZSIsImxvZyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFza0JBOzs7O0FBdGtCQTs7Ozs7SUFLTUEsSyxHQUNMLGVBQVlDLE1BQVosRUFBb0I7QUFBQTs7QUFDbkIsTUFBS0MsSUFBTCxHQUFZRCxPQUFPQyxJQUFuQjtBQUNBLE1BQUtDLElBQUwsR0FBWUYsT0FBT0UsSUFBbkI7QUFDQSxNQUFLQyxJQUFMLEdBQVksQ0FBQyxDQUFELEVBQUksQ0FBSixFQUFPLENBQVAsRUFBVUgsT0FBT0UsSUFBUCxDQUFZRSxNQUF0QixDQUFaO0FBQ0EsQzs7UUFHTUwsSyxHQUFBQSxLO0FBQ1I7Ozs7O0FBS0EsSUFBSU0sWUFBWTtBQUNmQyxVQUFjLE9BREM7QUFFZkMsb0JBQXVCLENBQUMsSUFBRCxFQUFPLElBQVAsRUFBYSxJQUFiLEVBQW1CLElBQW5CLENBRlIsRUFFa0M7QUFDakRDLHNCQUF3QixDQUFDLElBQUQsRUFBTyxJQUFQLEVBQWEsSUFBYixFQUFtQixJQUFuQixDQUhULEVBR21DO0FBQ2xEQyx1QkFBMEIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQUpYLEVBSXlCO0FBQ3hDQyx1QkFBMEIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQUxYLEVBS3lCO0FBQ3hDQyx3QkFBMEIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQU5YLEVBTXlCO0FBQ3hDQyxtQkFBb0IsQ0FBQyxJQUFELEVBQU8sSUFBUCxFQUFh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QUFLQyxPQUFPQyxZQUFQLENBQW9CQyxLQUFwQixDQUEwQixJQUExQixFQUFnQyxLQUFLQyxTQUFMLEVBQWhDLENBQUwsQ0FBUDtBQUNoQyxVQUFPLElBQUlDLE1BQUosQ0FBVyxLQUFLRCxTQUFMLEVBQVgsRUFBNkJ0RixRQUE3QixDQUFzQyxRQUF0QyxDQUFQO0FBQ0E7O0FBRUU7Ozs7Ozs7NEJBSVU7QUFDVCxVQUFPLDRCQUE0QixLQUFLd0YsTUFBTCxFQUFuQztBQUNBOztBQUVKOzs7Ozs7OzJCQUlZO0FBQ1IsVUFBT0MsUUFBUUMsTUFBUixDQUFlQyxLQUFmLENBQXFCLElBQUlKLE1BQUosQ0FBVyxLQUFLRCxTQUFMLEVBQVgsQ0FBckIsQ0FBUDtBQUNBOztBQUVKOzs7Ozs7OzJCQUlTTSxRLEVBQVU7QUFDbEIsT0FBSTdDLFNBQVMsSUFBSXdDLE1BQUosQ0FBVyxLQUFLRCxTQUFMLEVBQVgsQ0FBYjtBQUNBTyxNQUFHQyxTQUFILENBQWFGLFdBQVcsTUFBeEIsRUFBZ0M3QyxNQUFoQyxFQUF3QyxVQUFVZ0QsR0FBVixFQUFlO0FBQ3RELFFBQUdBLEdBQUgsRUFBUSxPQUFPQyxRQUFRQyxHQUFSLENBQVlGLEdBQVosQ0FBUDtBQUNSLElBRkQ7QUFHQTs7Ozs7O1FBR01wQixNLEdBQUFBLE0iLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE9iamVjdCByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2h1bmsgc2VjdGlvbiBvZiBhIE1JREkgZmlsZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMgLSB7dHlwZTogbnVtYmVyLCBkYXRhOiBhcnJheSwgc2l6ZTogYXJyYXl9XG4gKiBAcmV0dXJuIHtDaHVua31cbiAqL1xuY2xhc3MgQ2h1bmsge1xuXHRjb25zdHJ1Y3RvcihmaWVsZHMpIHtcblx0XHR0aGlzLnR5cGUgPSBmaWVsZHMudHlwZTtcblx0XHR0aGlzLmRhdGEgPSBmaWVsZHMuZGF0YTtcblx0XHR0aGlzLnNpemUgPSBbMCwgMCwgMCwgZmllbGRzLmRhdGEubGVuZ3RoXTtcblx0fVxufVxuXG5leHBvcnQge0NodW5rfTtcbi8qKlxuICogTUlESSBmaWxlIGZvcm1hdCBjb25zdGFudHMsIGluY2x1ZGluZyBub3RlIC0+IE1JREkgbnVtYmVyIHRyYW5zbGF0aW9uLlxuICogQHJldHVybiB7Q29uc3RhbnRzfVxuICovXG5cbnZhciBDb25zdGFudHMgPSB7XG5cdFZFUlNJT05cdFx0XHRcdFx0OiAnMS41LjInLFxuXHRIRUFERVJfQ0hVTktfVFlQRSAgXHRcdDogWzB4NGQsIDB4NTQsIDB4NjgsIDB4NjRdLCAvLyBNdGhkXG5cdEhFQURFUl9DSFVOS19MRU5HVEggIFx0OiBbMHgwMCwgMHgwMCwgMHgwMCwgMHgwNl0sIC8vIEhlYWRlciBzaXplIGZvciBTTUZcblx0SEVBREVSX0NIVU5LX0ZPUk1BVDAgICAgOiBbMHgwMCwgMHgwMF0sIC8vIE1pZGkgVHlwZSAwIGlkXG5cdEhFQURFUl9DSFVOS19GT1JNQVQxICAgIDogWzB4MDAsIDB4MDFdLCAvLyBNaWRpIFR5cGUgMSBpZFxuXHRIRUFERVJfQ0hVTktfRElWSVNJT04gICA6IFsweDAwLCAweDgwXSwgLy8gRGVmYXVsdHMgdG8gMTI4IHRpY2tzIHBlciBiZWF0XG5cdFRSQUNLX0NIVU5LX1RZUEVcdFx0OiBbMHg0ZCwgMHg1NCwgMHg3MiwgMHg2Yl0sIC8vIE1UcmssXG5cdE1FVEFfRVZFTlRfSURcdFx0XHQ6IDB4RkYsXG5cdE1FVEFfVEVYVF9JRFx0XHRcdDogMHgwMSxcblx0TUVUQV9DT1BZUklHSFRfSURcdFx0OiAweDAyLFxuXHRNRVRBX1RSQUNLX05BTUVfSURcdFx0OiAweDAzLFxuXHRNRVRBX0lOU1RSVU1FTlRfTkFNRV9JRCA6IDB4MDQsXG5cdE1FVEFfTFlSSUNfSURcdFx0XHQ6IDB4MDUsXG5cdE1FVEFfTUFSS0VSX0lEXHRcdFx0OiAweDA2LFxuXHRNRVRBX0NVRV9QT0lOVFx0XHRcdDogMHgwNyxcblx0TUVUQV9URU1QT19JRFx0XHRcdDogMHg1MSxcblx0TUVUQV9TTVRQRV9PRkZTRVRcdFx0OiAweDU0LFxuXHRNRVRBX1RJTUVfU0lHTkFUVVJFX0lEXHQ6IDB4NTgsXG5cdE1FVEFfS0VZX1NJR05BVFVSRV9JRFx0OiAweDU5LFxuXHRNRVRBX0VORF9PRl9UUkFDS19JRFx0OiBbMHgyRiwgMHgwMF0sXG5cdENPTlRST0xMRVJfQ0hBTkdFX1NUQVRVUzogMHhCMCwgLy8gaW5jbHVkZXMgY2hhbm5lbCBudW1iZXIgKDApXG5cdFBST0dSQU1fQ0hBTkdFX1NUQVRVU1x0OiAweEMwLCAvLyBpbmNsdWRlcyBjaGFubmVsIG51bWJlciAoMClcbn07XG5cbmV4cG9ydCB7Q29uc3RhbnRzfTtcbi8qKlxuICogSG9sZHMgYWxsIGRhdGEgZm9yIGEgXCJjb250cm9sbGVyIGNoYW5nZVwiIE1JREkgZXZlbnRcbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMge2NvbnRyb2xsZXJOdW1iZXI6IGludGVnZXIsIGNvbnRyb2xsZXJWYWx1ZTogaW50ZWdlcn1cbiAqIEByZXR1cm4ge0NvbnRyb2xsZXJDaGFuZ2VFdmVudH1cbiAqL1xuY2xhc3MgQ29udHJvbGxlckNoYW5nZUV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy50eXBlID0gJ2NvbnRyb2xsZXInO1xuXHRcdC8vIGRlbHRhIHRpbWUgZGVmYXVsdHMgdG8gMC5cblx0XHR0aGlzLmRhdGEgPSBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKDB4MDApLmNvbmNhdChDb25zdGFudHMuQ09OVFJPTExFUl9DSEFOR0VfU1RBVFVTLCBmaWVsZHMuY29udHJvbGxlck51bWJlciwgZmllbGRzLmNvbnRyb2xsZXJWYWx1ZSk7XG5cdH1cbn1cblxuZXhwb3J0IHtDb250cm9sbGVyQ2hhbmdlRXZlbnR9O1xuLyoqXG4gKiBPYmplY3QgcmVwcmVzZW50YXRpb24gb2YgYSBtZXRhIGV2ZW50LlxuICogQHBhcmFtIHtvYmplY3R9IGZpZWxkcyAtIHR5cGUsIGRhdGFcbiAqIEByZXR1cm4ge01ldGFFdmVudH1cbiAqL1xuY2xhc3MgTWV0YUV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy50eXBlID0gJ21ldGEnO1xuXHRcdHRoaXMuZGF0YSA9IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoMHgwMCk7Ly8gU3RhcnQgd2l0aCB6ZXJvIHRpbWUgZGVsdGFcblx0XHR0aGlzLmRhdGEgPSB0aGlzLmRhdGEuY29uY2F0KENvbnN0YW50cy5NRVRBX0VWRU5UX0lELCBmaWVsZHMuZGF0YSk7XG5cdH1cbn1cblxuZXhwb3J0IHtNZXRhRXZlbnR9O1xuLyoqXG4gKiBXcmFwcGVyIGZvciBub3RlT25FdmVudC9ub3RlT2ZmRXZlbnQgb2JqZWN0cyB0aGF0IGJ1aWxkcyBib3RoIGV2ZW50cy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMgLSB7cGl0Y2g6ICdbQzRdJywgZHVyYXRpb246ICc0Jywgd2FpdDogJzQnLCB2ZWxvY2l0eTogMS0xMDB9XG4gKiBAcmV0dXJuIHtOb3RlRXZlbnR9XG4gKi9cbmNsYXNzIE5vdGVFdmVudCB7XG5cdGNvbnN0cnVjdG9yKGZpZWxkcykge1xuXHRcdHRoaXMudHlwZSBcdFx0PSAnbm90ZSc7XG5cdFx0dGhpcy5waXRjaCBcdFx0PSBVdGlscy50b0FycmF5KGZpZWxkcy5waXRjaCk7XG5cdFx0dGhpcy53YWl0IFx0XHQ9IGZpZWxkcy53YWl0IHx8IDA7XG5cdFx0dGhpcy5kdXJhdGlvbiBcdD0gZmllbGRzLmR1cmF0aW9uO1xuXHRcdHRoaXMuc2VxdWVudGlhbCA9IGZpZWxkcy5zZXF1ZW50aWFsIHx8IGZhbHNlO1xuXHRcdHRoaXMudmVsb2NpdHkgXHQ9IGZpZWxkcy52ZWxvY2l0eSB8fCA1MDtcblx0XHR0aGlzLmNoYW5uZWwgXHQ9IGZpZWxkcy5jaGFubmVsIHx8IDE7XG5cdFx0dGhpcy5yZXBlYXQgXHQ9IGZpZWxkcy5yZXBlYXQgfHwgMTtcblx0XHR0aGlzLnZlbG9jaXR5IFx0PSB0aGlzLmNvbnZlcnRWZWxvY2l0eSh0aGlzLnZlbG9jaXR5KTtcblx0XHR0aGlzLmdyYWNlXHRcdD0gZmllbGRzLmdyYWNlO1xuXHRcdHRoaXMuYnVpbGREYXRhKCk7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIGludCBhcnJheSBmb3IgdGhpcyBldmVudC5cblx0ICogQHJldHVybiB7Tm90ZUV2ZW50fVxuXHQgKi9cblx0YnVpbGREYXRhKCkge1xuXHRcdHRoaXMuZGF0YSA9IFtdO1xuXG5cdFx0dmFyIHRpY2tEdXJhdGlvbiA9IHRoaXMuZ2V0VGlja0R1cmF0aW9uKHRoaXMuZHVyYXRpb24sICdub3RlJyk7XG5cdFx0dmFyIHJlc3REdXJhdGlvbiA9IHRoaXMuZ2V0VGlja0R1cmF0aW9uKHRoaXMud2FpdCwgJ3Jlc3QnKTtcblxuXHRcdC8vIEFwcGx5IGdyYWNlIG5vdGUocykgYW5kIHN1YnRyYWN0IHRpY2tzIChjdXJyZW50bHkgMSB0aWNrIHBlciBncmFjZSBub3RlKSBmcm9tIHRpY2tEdXJhdGlvbiBzbyBuZXQgdmFsdWUgaXMgdGhlIHNhbWVcblx0XHRpZiAodGhpcy5ncmFjZSkge1xuXHRcdFx0bGV0IGdyYWNlRHVyYXRpb24gPSAxO1xuXHRcdFx0dGhpcy5ncmFjZSA9IFV0aWxzLnRvQXJyYXkodGhpcy5ncmFjZSk7XG5cdFx0XHR0aGlzLmdyYWNlLmZvckVhY2goZnVuY3Rpb24ocGl0Y2gpIHtcblx0XHRcdFx0bGV0IG5vdGVFdmVudCA9IG5ldyBOb3RlRXZlbnQoe3BpdGNoOnRoaXMuZ3JhY2UsIGR1cmF0aW9uOidUJyArIGdyYWNlRHVyYXRpb259KTtcblx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChub3RlRXZlbnQuZGF0YSlcblxuXHRcdFx0XHR0aWNrRHVyYXRpb24gLT0gZ3JhY2VEdXJhdGlvbjtcblx0XHRcdH0sIHRoaXMpO1xuXHRcdH1cblxuXHRcdC8vIGZpZWxkcy5waXRjaCBjb3VsZCBiZSBhbiBhcnJheSBvZiBwaXRjaGVzLlxuXHRcdC8vIElmIHNvIGNyZWF0ZSBub3RlIGV2ZW50cyBmb3IgZWFjaCBhbmQgYXBwbHkgdGhlIHNhbWUgZHVyYXRpb24uXG5cdFx0dmFyIG5vdGVPbiwgbm90ZU9mZjtcblx0XHRpZiAoQXJyYXkuaXNBcnJheSh0aGlzLnBpdGNoKSkge1xuXHRcdFx0Ly8gQnkgZGVmYXVsdCB0aGlzIGlzIGEgY2hvcmQgaWYgaXQncyBhbiBhcnJheSBvZiBub3RlcyB0aGF0IHJlcXVpcmVzIG9uZSBOb3RlT25FdmVudC5cblx0XHRcdC8vIElmIHRoaXMuc2VxdWVudGlhbCA9PT0gdHJ1ZSB0aGVuIGl0J3MgYSBzZXF1ZW50aWFsIHN0cmluZyBvZiBub3RlcyB0aGF0IHJlcXVpcmVzIHNlcGFyYXRlIE5vdGVPbkV2ZW50cy5cblx0XHRcdGlmICggISB0aGlzLnNlcXVlbnRpYWwpIHtcblx0XHRcdFx0Ly8gSGFuZGxlIHJlcGVhdFxuXHRcdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMucmVwZWF0OyBqKyspIHtcblx0XHRcdFx0XHQvLyBOb3RlIG9uXG5cdFx0XHRcdFx0dGhpcy5waXRjaC5mb3JFYWNoKGZ1bmN0aW9uKHAsIGkpIHtcblx0XHRcdFx0XHRcdGlmIChpID09IDApIHtcblx0XHRcdFx0XHRcdFx0bm90ZU9uID0gbmV3IE5vdGVPbkV2ZW50KHtkYXRhOiBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKHJlc3REdXJhdGlvbikuY29uY2F0KHRoaXMuZ2V0Tm90ZU9uU3RhdHVzKCksIFV0aWxzLmdldFBpdGNoKHApLCB0aGlzLnZlbG9jaXR5KX0pO1xuXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHQvLyBSdW5uaW5nIHN0YXR1cyAoY2FuIG9tbWl0IHRoZSBub3RlIG9uIHN0YXR1cylcblx0XHRcdFx0XHRcdFx0bm90ZU9uID0gbmV3IE5vdGVPbkV2ZW50KHtkYXRhOiBbMCwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHldfSk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQobm90ZU9uLmRhdGEpO1xuXHRcdFx0XHRcdH0sIHRoaXMpO1xuXG5cdFx0XHRcdFx0Ly8gTm90ZSBvZmZcblx0XHRcdFx0XHR0aGlzLnBpdGNoLmZvckVhY2goZnVuY3Rpb24ocCwgaSkge1xuXHRcdFx0XHRcdFx0aWYgKGkgPT0gMCkge1xuXHRcdFx0XHRcdFx0XHRub3RlT2ZmID0gbmV3IE5vdGVPZmZFdmVudCh7ZGF0YTogVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aCh0aWNrRHVyYXRpb24pLmNvbmNhdCh0aGlzLmdldE5vdGVPZmZTdGF0dXMoKSwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHkpfSk7XG5cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdC8vIFJ1bm5pbmcgc3RhdHVzIChjYW4gb21taXQgdGhlIG5vdGUgb2ZmIHN0YXR1cylcblx0XHRcdFx0XHRcdFx0bm90ZU9mZiA9IG5ldyBOb3RlT2ZmRXZlbnQoe2RhdGE6IFswLCBVdGlscy5nZXRQaXRjaChwKSwgdGhpcy52ZWxvY2l0eV19KTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChub3RlT2ZmLmRhdGEpO1xuXHRcdFx0XHRcdH0sIHRoaXMpO1xuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIEhhbmRsZSByZXBlYXRcblx0XHRcdFx0Zm9yICh2YXIgaiA9IDA7IGogPCB0aGlzLnJlcGVhdDsgaisrKSB7XG5cdFx0XHRcdFx0dGhpcy5waXRjaC5mb3JFYWNoKGZ1bmN0aW9uKHAsIGkpIHtcblx0XHRcdFx0XHRcdC8vIHJlc3REdXJhdGlvbiBvbmx5IGFwcGxpZXMgdG8gZmlyc3Qgbm90ZVxuXHRcdFx0XHRcdFx0aWYgKGkgPiAwKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3REdXJhdGlvbiA9IDA7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIElmIGR1cmF0aW9uIGlzIDh0aCB0cmlwbGV0cyB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSB0b3RhbCB0aWNrcyA9PSBxdWFydGVyIG5vdGUuXG5cdFx0XHRcdFx0XHQvLyBTbywgdGhlIGxhc3Qgb25lIHdpbGwgbmVlZCB0byBiZSB0aGUgcmVtYWluZGVyXG5cdFx0XHRcdFx0XHRpZiAodGhpcy5kdXJhdGlvbiA9PT0gJzh0JyAmJiBpID09IHRoaXMucGl0Y2gubGVuZ3RoIC0gMSkge1xuXHRcdFx0XHRcdFx0XHRsZXQgcXVhcnRlclRpY2tzID0gVXRpbHMubnVtYmVyRnJvbUJ5dGVzKENvbnN0YW50cy5IRUFERVJfQ0hVTktfRElWSVNJT04pO1xuXHRcdFx0XHRcdFx0XHR0aWNrRHVyYXRpb24gPSBxdWFydGVyVGlja3MgLSAodGlja0R1cmF0aW9uICogMik7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdG5vdGVPbiA9IG5ldyBOb3RlT25FdmVudCh7ZGF0YTogVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChyZXN0RHVyYXRpb24pLmNvbmNhdChbdGhpcy5nZXROb3RlT25TdGF0dXMoKSwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHldKX0pO1xuXHRcdFx0XHRcdFx0bm90ZU9mZiA9IG5ldyBOb3RlT2ZmRXZlbnQoe2RhdGE6IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgodGlja0R1cmF0aW9uKS5jb25jYXQoW3RoaXMuZ2V0Tm90ZU9mZlN0YXR1cygpLCBVdGlscy5nZXRQaXRjaChwKSwgdGhpcy52ZWxvY2l0eV0pfSk7XG5cblx0XHRcdFx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQobm90ZU9uLmRhdGEsIG5vdGVPZmYuZGF0YSk7XG5cdFx0XHRcdFx0fSwgdGhpcyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0dGhyb3cgJ3BpdGNoIG11c3QgYmUgYW4gYXJyYXkuJztcblx0fTtcblxuXHQvKipcblx0ICogQ29udmVydHMgdmVsb2NpdHkgdG8gdmFsdWUgMC0xMjdcblx0ICogQHBhcmFtIHtudW1iZXJ9IHZlbG9jaXR5IC0gVmVsb2NpdHkgdmFsdWUgMS0xMDBcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cblx0Y29udmVydFZlbG9jaXR5KHZlbG9jaXR5KSB7XG5cdFx0Ly8gTWF4IHBhc3NlZCB2YWx1ZSBsaW1pdGVkIHRvIDEwMFxuXHRcdHZlbG9jaXR5ID0gdmVsb2NpdHkgPiAxMDAgPyAxMDAgOiB2ZWxvY2l0eTtcblx0XHRyZXR1cm4gTWF0aC5yb3VuZCh2ZWxvY2l0eSAvIDEwMCAqIDEyNyk7XG5cdH07XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHRvdGFsIG51bWJlciBvZiB0aWNrcyBiYXNlZCBvbiBwYXNzZWQgZHVyYXRpb24uXG5cdCAqIE5vdGU6IHR5cGU9PSdub3RlJyBkZWZhdWx0cyB0byBxdWFydGVyIG5vdGUsIHR5cGU9PT0ncmVzdCcgZGVmYXVsdHMgdG8gMFxuXHQgKiBAcGFyYW0geyhzdHJpbmd8YXJyYXkpfSBkdXJhdGlvblxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBbJ25vdGUnLCAncmVzdCddXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdGdldFRpY2tEdXJhdGlvbihkdXJhdGlvbiwgdHlwZSkge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KGR1cmF0aW9uKSkge1xuXHRcdFx0Ly8gUmVjdXJzaXZlbHkgZXhlY3V0ZSB0aGlzIG1ldGhvZCBmb3IgZWFjaCBpdGVtIGluIHRoZSBhcnJheSBhbmQgcmV0dXJuIHRoZSBzdW0gb2YgdGljayBkdXJhdGlvbnMuXG5cdFx0XHRyZXR1cm4gZHVyYXRpb24ubWFwKGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLmdldFRpY2tEdXJhdGlvbih2YWx1ZSwgdHlwZSk7XG5cdFx0XHR9LCB0aGlzKS5yZWR1Y2UoZnVuY3Rpb24oYSwgYikge1xuXHRcdFx0XHRyZXR1cm4gYSArIGI7XG5cdFx0XHR9LCAwKTtcblx0XHR9XG5cblx0XHRkdXJhdGlvbiA9IGR1cmF0aW9uLnRvU3RyaW5nKCk7XG5cblx0XHRpZiAoZHVyYXRpb24udG9Mb3dlckNhc2UoKS5jaGFyQXQoMCkgPT09ICd0Jykge1xuXHRcdFx0Ly8gSWYgZHVyYXRpb24gc3RhcnRzIHdpdGggJ3QnIHRoZW4gdGhlIG51bWJlciB0aGF0IGZvbGxvd3MgaXMgYW4gZXhwbGljaXQgdGljayBjb3VudFxuXHRcdFx0cmV0dXJuIHBhcnNlSW50KGR1cmF0aW9uLnN1YnN0cmluZygxKSk7XG5cdFx0fVxuXG5cdFx0Ly8gTmVlZCB0byBhcHBseSBkdXJhdGlvbiBoZXJlLiAgUXVhcnRlciBub3RlID09IENvbnN0YW50cy5IRUFERVJfQ0hVTktfRElWSVNJT05cblx0XHQvLyBSb3VuZGluZyBvbmx5IGFwcGxpZXMgdG8gdHJpcGxldHMsIHdoaWNoIHRoZSByZW1haW5kZXIgaXMgaGFuZGxlZCBiZWxvd1xuXHRcdHZhciBxdWFydGVyVGlja3MgPSBVdGlscy5udW1iZXJGcm9tQnl0ZXMoQ29uc3RhbnRzLkhFQURFUl9DSFVOS19ESVZJU0lPTik7XG5cdFx0cmV0dXJuIE1hdGgucm91bmQocXVhcnRlclRpY2tzICogdGhpcy5nZXREdXJhdGlvbk11bHRpcGxpZXIoZHVyYXRpb24sIHR5cGUpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHdoYXQgdG8gbXVsdGlwbGUgdGlja3MvcXVhcnRlciBub3RlIGJ5IHRvIGdldCB0aGUgc3BlY2lmaWVkIGR1cmF0aW9uLlxuXHQgKiBOb3RlOiB0eXBlPT0nbm90ZScgZGVmYXVsdHMgdG8gcXVhcnRlciBub3RlLCB0eXBlPT09J3Jlc3QnIGRlZmF1bHRzIHRvIDBcblx0ICogQHBhcmFtIHtzdHJpbmd9IGR1cmF0aW9uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFsnbm90ZScsJ3Jlc3QnXVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXREdXJhdGlvbk11bHRpcGxpZXIoZHVyYXRpb24sIHR5cGUpIHtcblx0XHQvLyBOZWVkIHRvIGFwcGx5IGR1cmF0aW9uIGhlcmUuICBRdWFydGVyIG5vdGUgPT0gQ29uc3RhbnRzLkhFQURFUl9DSFVOS19ESVZJU0lPTlxuXHRcdHN3aXRjaCAoZHVyYXRpb24pIHtcblx0XHRcdGNhc2UgJzAnOlxuXHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdGNhc2UgJzEnOlxuXHRcdFx0XHRyZXR1cm4gNDtcblx0XHRcdGNhc2UgJzInOlxuXHRcdFx0XHRyZXR1cm4gMjtcblx0XHRcdGNhc2UgJ2QyJzpcblx0XHRcdFx0cmV0dXJuIDM7XG5cdFx0XHRjYXNlICc0Jzpcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHRjYXNlICc0dCc6XG5cdFx0XHRcdHJldHVybiAwLjY2Njtcblx0XHRcdGNhc2UgJ2Q0Jzpcblx0XHRcdFx0cmV0dXJuIDEuNTtcblx0XHRcdGNhc2UgJzgnOlxuXHRcdFx0XHRyZXR1cm4gMC41O1xuXHRcdFx0Y2FzZSAnOHQnOlxuXHRcdFx0XHQvLyBGb3IgOHRoIHRyaXBsZXRzLCBsZXQncyBkaXZpZGUgYSBxdWFydGVyIGJ5IDMsIHJvdW5kIHRvIHRoZSBuZWFyZXN0IGludCwgYW5kIHN1YnN0cmFjdCB0aGUgcmVtYWluZGVyIHRvIHRoZSBsYXN0IG9uZS5cblx0XHRcdFx0cmV0dXJuIDAuMzM7XG5cdFx0XHRjYXNlICdkOCc6XG5cdFx0XHRcdHJldHVybiAwLjc1O1xuXHRcdFx0Y2FzZSAnMTYnOlxuXHRcdFx0XHRyZXR1cm4gMC4yNTtcblx0XHRcdGNhc2UgJzE2dCc6XG5cdFx0XHRcdHJldHVybiAwLjE2Njtcblx0XHRcdGNhc2UgJzMyJzpcblx0XHRcdFx0cmV0dXJuIDAuMTI1O1xuXHRcdFx0Y2FzZSAnNjQnOlxuXHRcdFx0XHRyZXR1cm4gMC4wNjI1O1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0Ly8gTm90ZXMgZGVmYXVsdCB0byBhIHF1YXJ0ZXIsIHJlc3RzIGRlZmF1bHQgdG8gMFxuXHRcdFx0XHQvL3JldHVybiB0eXBlID09PSAnbm90ZScgPyAxIDogMDtcblx0XHR9XG5cblx0XHR0aHJvdyBkdXJhdGlvbiArICcgaXMgbm90IGEgdmFsaWQgZHVyYXRpb24uJztcblx0fTtcblxuXHQvKipcblx0ICogR2V0cyB0aGUgbm90ZSBvbiBzdGF0dXMgY29kZSBiYXNlZCBvbiB0aGUgc2VsZWN0ZWQgY2hhbm5lbC4gMHg5ezAtRn1cblx0ICogTm90ZSBvbiBhdCBjaGFubmVsIDAgaXMgMHg5MCAoMTQ0KVxuXHQgKiAwID0gQ2ggMVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXROb3RlT25TdGF0dXMoKSB7cmV0dXJuIDE0NCArIHRoaXMuY2hhbm5lbCAtIDF9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIG5vdGUgb2ZmIHN0YXR1cyBjb2RlIGJhc2VkIG9uIHRoZSBzZWxlY3RlZCBjaGFubmVsLiAweDh7MC1GfVxuXHQgKiBOb3RlIG9mZiBhdCBjaGFubmVsIDAgaXMgMHg4MCAoMTI4KVxuXHQgKiAwID0gQ2ggMVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXROb3RlT2ZmU3RhdHVzKCkge3JldHVybiAxMjggKyB0aGlzLmNoYW5uZWwgLSAxfVxufVxuXG5leHBvcnQge05vdGVFdmVudH07XG4vKipcbiAqIEhvbGRzIGFsbCBkYXRhIGZvciBhIFwibm90ZSBvZmZcIiBNSURJIGV2ZW50XG4gKiBAcGFyYW0ge29iamVjdH0gZmllbGRzIHtkYXRhOiBbXX1cbiAqIEByZXR1cm4ge05vdGVPZmZFdmVudH1cbiAqL1xuY2xhc3MgTm90ZU9mZkV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy5kYXRhID0gZmllbGRzLmRhdGE7XG5cdH1cbn1cblxuZXhwb3J0IHtOb3RlT2ZmRXZlbnR9O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSBcIm5vdGUgb25cIiBNSURJIGV2ZW50XG4gKiBAcGFyYW0ge29iamVjdH0gZmllbGRzIHtkYXRhOiBbXX1cbiAqIEByZXR1cm4ge05vdGVPbkV2ZW50fVxuICovXG5jbGFzcyBOb3RlT25FdmVudCB7XG5cdGNvbnN0cnVjdG9yKGZpZWxkcykge1xuXHRcdHRoaXMuZGF0YSA9IGZpZWxkcy5kYXRhO1xuXHR9XG59XG5cbmV4cG9ydCB7Tm90ZU9uRXZlbnR9O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSBcInByb2dyYW0gY2hhbmdlXCIgTUlESSBldmVudFxuICogQHBhcmFtIHtvYmplY3R9IGZpZWxkcyB7aW5zdHJ1bWVudDogaW50ZWdlcn1cbiAqIEByZXR1cm4ge1Byb2dyYW1DaGFuZ2VFdmVudH1cbiAqL1xuY2xhc3MgUHJvZ3JhbUNoYW5nZUV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy50eXBlID0gJ3Byb2dyYW0nO1xuXHRcdC8vIGRlbHRhIHRpbWUgZGVmYXVsdHMgdG8gMC5cblx0XHR0aGlzLmRhdGEgPSBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKDB4MDApLmNvbmNhdChDb25zdGFudHMuUFJPR1JBTV9DSEFOR0VfU1RBVFVTLCBmaWVsZHMuaW5zdHJ1bWVudCk7XG5cdH1cbn1cblxuZXhwb3J0IHtQcm9ncmFtQ2hhbmdlRXZlbnR9O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSB0cmFjay5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMge3R5cGU6IG51bWJlciwgZGF0YTogYXJyYXksIHNpemU6IGFycmF5LCBldmVudHM6IGFycmF5fVxuICogQHJldHVybiB7VHJhY2t9XG4gKi9cbmNsYXNzIFRyYWNrIHtcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0dGhpcy50eXBlID0gQ29uc3RhbnRzLlRSQUNLX0NIVU5LX1RZUEU7XG5cdFx0dGhpcy5kYXRhID0gW107XG5cdFx0dGhpcy5zaXplID0gW107XG5cdFx0dGhpcy5ldmVudHMgPSBbXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGFueSBldmVudCB0eXBlIHRvIHRoZSB0cmFjay5cblx0ICogQHBhcmFtIHsoTm90ZUV2ZW50fE1ldGFFdmVudHxQcm9ncmFtQ2hhbmdlRXZlbnQpfSBldmVudCAtIEV2ZW50IG9iamVjdC5cblx0ICogQHBhcmFtIHtmdW5jdGlvbn0gbWFwRnVuY3Rpb24gLSBDYWxsYmFjayB3aGljaCBjYW4gYmUgdXNlZCB0byBhcHBseSBzcGVjaWZpYyBwcm9wZXJ0aWVzIHRvIGFsbCBldmVudHMuIFxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZEV2ZW50KGV2ZW50LCBtYXBGdW5jdGlvbikge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KGV2ZW50KSkge1xuXHRcdFx0ZXZlbnQuZm9yRWFjaChmdW5jdGlvbihlLCBpKSB7XG5cdFx0XHRcdC8vIEhhbmRsZSBtYXAgZnVuY3Rpb24gaWYgcHJvdmlkZWRcblx0XHRcdFx0aWYgKHR5cGVvZiBtYXBGdW5jdGlvbiA9PT0gJ2Z1bmN0aW9uJyAmJiBlLnR5cGUgPT09ICdub3RlJykge1xuXHRcdFx0XHRcdHZhciBwcm9wZXJ0aWVzID0gbWFwRnVuY3Rpb24oaSwgZSk7XG5cblx0XHRcdFx0XHRpZiAodHlwZW9mIHByb3BlcnRpZXMgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdFx0XHRmb3IgKHZhciBqIGluIHByb3BlcnRpZXMpIHtcblx0XHRcdFx0XHRcdFx0c3dpdGNoKGopIHtcblx0XHRcdFx0XHRcdFx0XHRjYXNlICdkdXJhdGlvbic6XG5cdFx0XHRcdFx0XHRcdFx0XHRlLmR1cmF0aW9uID0gcHJvcGVydGllc1tqXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdGNhc2UgJ3NlcXVlbnRpYWwnOlxuXHRcdFx0XHRcdFx0XHRcdFx0ZS5zZXF1ZW50aWFsID0gcHJvcGVydGllc1tqXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdGNhc2UgJ3ZlbG9jaXR5Jzpcblx0XHRcdFx0XHRcdFx0XHRcdGUudmVsb2NpdHkgPSBlLmNvbnZlcnRWZWxvY2l0eShwcm9wZXJ0aWVzW2pdKTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XHRcdFxuXG5cdFx0XHRcdFx0XHQvLyBHb3R0YSBidWlsZCB0aGF0IGRhdGFcblx0XHRcdFx0XHRcdGUuYnVpbGREYXRhKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChlLmRhdGEpO1xuXHRcdFx0XHR0aGlzLnNpemUgPSBVdGlscy5udW1iZXJUb0J5dGVzKHRoaXMuZGF0YS5sZW5ndGgsIDQpOyAvLyA0IGJ5dGVzIGxvbmdcblx0XHRcdFx0dGhpcy5ldmVudHMucHVzaChlKTtcblx0XHRcdH0sIHRoaXMpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQoZXZlbnQuZGF0YSk7XG5cdFx0XHR0aGlzLnNpemUgPSBVdGlscy5udW1iZXJUb0J5dGVzKHRoaXMuZGF0YS5sZW5ndGgsIDQpOyAvLyA0IGJ5dGVzIGxvbmdcblx0XHRcdHRoaXMuZXZlbnRzLnB1c2goZXZlbnQpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGVtcG8gb2YgdGhlIE1JREkgZmlsZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGJwbSAtIFRlbXBvIGluIGJlYXRzIHBlciBtaW51dGUuXG5cdCAqIEByZXR1cm4ge1RyYWNrfVxuXHQgKi9cblx0c2V0VGVtcG8oYnBtKSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX1RFTVBPX0lEXX0pO1xuXHRcdGV2ZW50LmRhdGEucHVzaCgweDAzKTsgLy8gU2l6ZVxuXHRcdHZhciB0ZW1wbyA9IE1hdGgucm91bmQoNjAwMDAwMDAgLyBicG0pO1xuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKHRlbXBvLCAzKSk7IC8vIFRlbXBvLCAzIGJ5dGVzXG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGltZSBzaWduYXR1cmUuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBudW1lcmF0b3IgLSBUb3AgbnVtYmVyIG9mIHRoZSB0aW1lIHNpZ25hdHVyZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGRlbm9taW5hdG9yIC0gQm90dG9tIG51bWJlciBvZiB0aGUgdGltZSBzaWduYXR1cmUuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBtaWRpY2xvY2tzcGVydGljayAtIERlZmF1bHRzIHRvIDI0LlxuXHQgKiBAcGFyYW0ge251bWJlcn0gbm90ZXNwZXJtaWRpY2xvY2sgLSBEZWZhdWx0cyB0byA4LlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdHNldFRpbWVTaWduYXR1cmUobnVtZXJhdG9yLCBkZW5vbWluYXRvciwgbWlkaWNsb2Nrc3BlcnRpY2ssIG5vdGVzcGVybWlkaWNsb2NrKSB7XG5cdFx0bWlkaWNsb2Nrc3BlcnRpY2sgPSBtaWRpY2xvY2tzcGVydGljayB8fCAyNDtcblx0XHRub3Rlc3Blcm1pZGljbG9jayA9IG5vdGVzcGVybWlkaWNsb2NrIHx8IDg7XG5cdFx0XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX1RJTUVfU0lHTkFUVVJFX0lEXX0pO1xuXHRcdGV2ZW50LmRhdGEucHVzaCgweDA0KTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG51bWVyYXRvciwgMSkpOyAvLyBOdW1lcmF0b3IsIDEgYnl0ZXNcblx0XHRcblx0XHR2YXIgX2Rlbm9taW5hdG9yID0gTWF0aC5sb2cyKGRlbm9taW5hdG9yKTtcdC8vIERlbm9taW5hdG9yIGlzIGV4cHJlc3NlZCBhcyBwb3cgb2YgMlxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKF9kZW5vbWluYXRvciwgMSkpOyAvLyBEZW5vbWluYXRvciwgMSBieXRlc1xuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG1pZGljbG9ja3NwZXJ0aWNrLCAxKSk7IC8vIE1JREkgQ2xvY2tzIHBlciB0aWNrLCAxIGJ5dGVzXG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvQnl0ZXMobm90ZXNwZXJtaWRpY2xvY2ssIDEpKTsgLy8gTnVtYmVyIG9mIDEvMzIgbm90ZXMgcGVyIE1JREkgY2xvY2tzLCAxIGJ5dGVzXG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMga2V5IHNpZ25hdHVyZS5cblx0ICogQHBhcmFtIHsqfSBzZiAtIFxuXHQgKiBAcGFyYW0geyp9IG1pIC1cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRzZXRLZXlTaWduYXR1cmUoc2YsIG1pKSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX0tFWV9TSUdOQVRVUkVfSURdfSk7XG5cdFx0ZXZlbnQuZGF0YS5wdXNoKDB4MDIpOyAvLyBTaXplXG5cblx0XHR2YXIgbW9kZSA9IG1pIHx8IDA7XG5cdFx0c2YgPSBzZiB8fCAwO1xuXG5cdFx0Ly9cdEZ1bmN0aW9uIGNhbGxlZCB3aXRoIHN0cmluZyBub3RhdGlvblxuXHRcdGlmICh0eXBlb2YgbWkgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHR2YXIgZmlmdGhzID0gW1xuXHRcdFx0XHRbJ0NiJywgJ0diJywgJ0RiJywgJ0FiJywgJ0ViJywgJ0JiJywgJ0YnLCAnQycsICdHJywgJ0QnLCAnQScsICdFJywgJ0InLCAnRiMnLCAnQyMnXSxcblx0XHRcdFx0WydhYicsICdlYicsICdiYicsICdmJywgJ2MnLCAnZycsICdkJywgJ2EnLCAnZScsICdiJywgJ2YjJywgJ2MjJywgJ2cjJywgJ2QjJywgJ2EjJ11cblx0XHRcdF07XG5cdFx0XHR2YXIgX3NmbGVuID0gc2YubGVuZ3RoO1xuXHRcdFx0dmFyIG5vdGUgPSBzZiB8fCAnQyc7XG5cblx0XHRcdGlmIChzZlswXSA9PT0gc2ZbMF0udG9Mb3dlckNhc2UoKSkgbW9kZSA9IDFcblxuXHRcdFx0aWYgKF9zZmxlbiA+IDEpIHtcblx0XHRcdFx0c3dpdGNoIChzZi5jaGFyQXQoX3NmbGVuIC0gMSkpIHtcblx0XHRcdFx0XHRjYXNlICdtJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAxO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICctJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAxO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdNJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAwO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICcrJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAwO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgZmlmdGhpbmRleCA9IGZpZnRoc1ttb2RlXS5pbmRleE9mKG5vdGUpO1xuXHRcdFx0c2YgPSBmaWZ0aGluZGV4ID09PSAtMSA/IDAgOiBmaWZ0aGluZGV4IC0gNztcblx0XHR9XG5cblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9CeXRlcyhzZiwgMSkpOyAvLyBOdW1iZXIgb2Ygc2hhcnAgb3IgZmxhdHMgKCA8IDAgZmxhdDsgPiAwIHNoYXJwKVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG1vZGUsIDEpKTsgLy8gTW9kZTogMCBtYWpvciwgMSBtaW5vclxuXHRcdHJldHVybiB0aGlzLmFkZEV2ZW50KGV2ZW50KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIHRleHQgdG8gTUlESSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRleHQgdG8gYWRkLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZFRleHQodGV4dCkge1xuXHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoe2RhdGE6IFtDb25zdGFudHMuTUVUQV9URVhUX0lEXX0pO1xuXHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgY29weXJpZ2h0IHRvIE1JREkgZmlsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUZXh0IG9mIGNvcHlyaWdodCBsaW5lLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZENvcHlyaWdodCh0ZXh0KSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX0NPUFlSSUdIVF9JRF19KTtcblx0XHR2YXIgc3RyaW5nQnl0ZXMgPSBVdGlscy5zdHJpbmdUb0J5dGVzKHRleHQpO1xuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKHN0cmluZ0J5dGVzLmxlbmd0aCkpOyAvLyBTaXplXG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KHN0cmluZ0J5dGVzKTsgLy8gVGV4dFxuXHRcdHJldHVybiB0aGlzLmFkZEV2ZW50KGV2ZW50KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIFNlcXVlbmNlL1RyYWNrIE5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGV4dCBvZiB0cmFjayBuYW1lLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZFRyYWNrTmFtZSh0ZXh0KSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX1RSQUNLX05BTUVfSURdfSk7XG5cdFx0dmFyIHN0cmluZ0J5dGVzID0gVXRpbHMuc3RyaW5nVG9CeXRlcyh0ZXh0KTtcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIFRleHRcblx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBpbnN0cnVtZW50IG5hbWUgb2YgdHJhY2suXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gTmFtZSBvZiBpbnN0cnVtZW50LlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZEluc3RydW1lbnROYW1lKHRleHQpIHtcblx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHtkYXRhOiBbQ29uc3RhbnRzLk1FVEFfSU5TVFJVTUVOVF9OQU1FX0lEXX0pO1xuXHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgbWFya2VyIHRvIE1JREkgZmlsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBNYXJrZXIgdGV4dC5cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRhZGRNYXJrZXIodGV4dCkge1xuXHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoe2RhdGE6IFtDb25zdGFudHMuTUVUQV9NQVJLRVJfSURdfSk7XG5cdFx0dmFyIHN0cmluZ0J5dGVzID0gVXRpbHMuc3RyaW5nVG9CeXRlcyh0ZXh0KTtcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIFRleHRcblx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBjdWUgcG9pbnQgdG8gTUlESSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRleHQgb2YgY3VlIHBvaW50LlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZEN1ZVBvaW50KHRleHQpIHtcblx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHtkYXRhOiBbQ29uc3RhbnRzLk1FVEFfQ1VFX1BPSU5UXX0pO1xuXHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgbHlyaWMgdG8gTUlESSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbHlyaWMgLSBMeXJpYyB0ZXh0IHRvIGFkZC5cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRhZGRMeXJpYyhseXJpYykge1xuXHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoe2RhdGE6IFtDb25zdGFudHMuTUVUQV9MWVJJQ19JRF19KTtcblx0XHR2YXIgc3RyaW5nQnl0ZXMgPSBVdGlscy5zdHJpbmdUb0J5dGVzKGx5cmljKTtcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIEx5cmljXG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoYW5uZWwgbW9kZSBtZXNzYWdlc1xuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdHBvbHlNb2RlT24oKSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE5vdGVPbkV2ZW50KHtkYXRhOiBbMHgwMCwgMHhCMCwgMHg3RSwgMHgwMF19KTtcblx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdH1cblxufVxuXG5leHBvcnQge1RyYWNrfTtcbmltcG9ydCB7dG9NaWRpfSBmcm9tICd0b25hbC1taWRpJztcblxuLyoqXG4gKiBTdGF0aWMgdXRpbGl0eSBmdW5jdGlvbnMgdXNlZCB0aHJvdWdob3V0IHRoZSBsaWJyYXJ5LlxuICovXG5jbGFzcyBVdGlscyB7XG5cblx0LyoqXG5cdCAqIEdldHMgTWlkaVdyaXRlckpTIHZlcnNpb24gbnVtYmVyLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRzdGF0aWMgdmVyc2lvbigpIHtcblx0XHRyZXR1cm4gQ29uc3RhbnRzLlZFUlNJT047XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydCBhIHN0cmluZyB0byBhbiBhcnJheSBvZiBieXRlc1xuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG5cdCAqIEByZXR1cm4ge2FycmF5fVxuXHQgKi9cblx0c3RhdGljIHN0cmluZ1RvQnl0ZXMoc3RyaW5nKSB7XG5cdFx0cmV0dXJuIHN0cmluZy5zcGxpdCgnJykubWFwKGNoYXIgPT4gY2hhci5jaGFyQ29kZUF0KCkpXG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIGFyZ3VtZW50IGlzIGEgdmFsaWQgbnVtYmVyLlxuXHQgKiBAcGFyYW0geyp9IG4gLSBWYWx1ZSB0byBjaGVja1xuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0c3RhdGljIGlzTnVtZXJpYyhuKSB7XG5cdFx0cmV0dXJuICFpc05hTihwYXJzZUZsb2F0KG4pKSAmJiBpc0Zpbml0ZShuKVxuXHR9XG5cblx0LyoqXG4gICAgICogUmV0dXJucyB0aGUgY29ycmVjdCBNSURJIG51bWJlciBmb3IgdGhlIHNwZWNpZmllZCBwaXRjaC5cbiAgICAgKiBVc2VzIFRvbmFsIE1pZGkgLSBodHRwczovL2dpdGh1Yi5jb20vZGFuaWdiL3RvbmFsL3RyZWUvbWFzdGVyL3BhY2thZ2VzL21pZGlcbiAgICAgKiBAcGFyYW0geyhzdHJpbmd8bnVtYmVyKX0gcGl0Y2ggLSAnQyM0JyBvciBtaWRpIG5vdGUgY29kZVxuICAgICAqIEByZXR1cm4ge251bWJlcn1cbiAgICAgKi9cbiAgICAgc3RhdGljIGdldFBpdGNoKHBpdGNoKSB7XG4gICAgIFx0cmV0dXJuIHRvTWlkaShwaXRjaCk7XG4gICAgIH1cblxuXHQvKipcblx0ICogVHJhbnNsYXRlcyBudW1iZXIgb2YgdGlja3MgdG8gTUlESSB0aW1lc3RhbXAgZm9ybWF0LCByZXR1cm5pbmcgYW4gYXJyYXkgb2Zcblx0ICogaGV4IHN0cmluZ3Mgd2l0aCB0aGUgdGltZSB2YWx1ZXMuIE1pZGkgaGFzIGEgdmVyeSBwYXJ0aWN1bGFyIHRpbWUgdG8gZXhwcmVzcyB0aW1lLFxuXHQgKiB0YWtlIGEgZ29vZCBsb29rIGF0IHRoZSBzcGVjIGJlZm9yZSBldmVyIHRvdWNoaW5nIHRoaXMgZnVuY3Rpb24uXG5cdCAqIFRoYW5rcyB0byBodHRwczovL2dpdGh1Yi5jb20vc2VyZ2kvanNtaWRpXG5cdCAqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB0aWNrcyAtIE51bWJlciBvZiB0aWNrcyB0byBiZSB0cmFuc2xhdGVkXG5cdCAqIEByZXR1cm4ge2FycmF5fSAtIEJ5dGVzIHRoYXQgZm9ybSB0aGUgTUlESSB0aW1lIHZhbHVlXG5cdCAqL1xuXHRzdGF0aWMgbnVtYmVyVG9WYXJpYWJsZUxlbmd0aCh0aWNrcykge1xuXHQgICAgdmFyIGJ1ZmZlciA9IHRpY2tzICYgMHg3RjtcblxuXHQgICAgd2hpbGUgKHRpY2tzID0gdGlja3MgPj4gNykge1xuXHQgICAgICAgIGJ1ZmZlciA8PD0gODtcblx0ICAgICAgICBidWZmZXIgfD0gKCh0aWNrcyAmIDB4N0YpIHwgMHg4MCk7XG5cdCAgICB9XG5cblx0ICAgIHZhciBiTGlzdCA9IFtdO1xuXHQgICAgd2hpbGUgKHRydWUpIHtcblx0ICAgICAgICBiTGlzdC5wdXNoKGJ1ZmZlciAmIDB4ZmYpO1xuXG5cdCAgICAgICAgaWYgKGJ1ZmZlciAmIDB4ODApIGJ1ZmZlciA+Pj0gOFxuXHQgICAgICAgIGVsc2UgeyBicmVhazsgfVxuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gYkxpc3Q7XG5cdH1cblxuXHQvKipcblx0ICogQ291bnRzIG51bWJlciBvZiBieXRlcyBpbiBzdHJpbmdcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNcblx0ICogQHJldHVybiB7YXJyYXl9XG5cdCAqL1xuXHRzdGF0aWMgc3RyaW5nQnl0ZUNvdW50KHMpIHtcblx0XHRyZXR1cm4gZW5jb2RlVVJJKHMpLnNwbGl0KC8lLi58Li8pLmxlbmd0aCAtIDFcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgYW4gaW50IGZyb20gYW4gYXJyYXkgb2YgYnl0ZXMuXG5cdCAqIEBwYXJhbSB7YXJyYXl9IGJ5dGVzXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdHN0YXRpYyBudW1iZXJGcm9tQnl0ZXMoYnl0ZXMpIHtcblx0XHR2YXIgaGV4ID0gJyc7XG5cdFx0dmFyIHN0cmluZ1Jlc3VsdDtcblxuXHRcdGJ5dGVzLmZvckVhY2goZnVuY3Rpb24oYnl0ZSkge1xuXHRcdFx0c3RyaW5nUmVzdWx0ID0gYnl0ZS50b1N0cmluZygxNik7XG5cblx0XHRcdC8vIGVuc3VyZSBzdHJpbmcgaXMgMiBjaGFyc1xuXHRcdFx0aWYgKHN0cmluZ1Jlc3VsdC5sZW5ndGggPT0gMSkgc3RyaW5nUmVzdWx0ID0gXCIwXCIgKyBzdHJpbmdSZXN1bHRcblxuXHRcdFx0aGV4ICs9IHN0cmluZ1Jlc3VsdDtcblx0XHR9KTtcblxuXHRcdHJldHVybiBwYXJzZUludChoZXgsIDE2KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUYWtlcyBhIG51bWJlciBhbmQgc3BsaXRzIGl0IHVwIGludG8gYW4gYXJyYXkgb2YgYnl0ZXMuICBDYW4gYmUgcGFkZGVkIGJ5IHBhc3NpbmcgYSBudW1iZXIgdG8gYnl0ZXNOZWVkZWRcblx0ICogQHBhcmFtIHtudW1iZXJ9IG51bWJlclxuXHQgKiBAcGFyYW0ge251bWJlcn0gYnl0ZXNOZWVkZWRcblx0ICogQHJldHVybiB7YXJyYXl9IC0gQXJyYXkgb2YgYnl0ZXNcblx0ICovXG5cdHN0YXRpYyBudW1iZXJUb0J5dGVzKG51bWJlciwgYnl0ZXNOZWVkZWQpIHtcblx0XHRieXRlc05lZWRlZCA9IGJ5dGVzTmVlZGVkIHx8IDE7XG5cblx0XHR2YXIgaGV4U3RyaW5nID0gbnVtYmVyLnRvU3RyaW5nKDE2KTtcblxuXHRcdGlmIChoZXhTdHJpbmcubGVuZ3RoICYgMSkgeyAvLyBNYWtlIHN1cmUgaGV4IHN0cmluZyBpcyBldmVuIG51bWJlciBvZiBjaGFyc1xuXHRcdFx0aGV4U3RyaW5nID0gJzAnICsgaGV4U3RyaW5nO1xuXHRcdH1cblxuXHRcdC8vIFNwbGl0IGhleCBzdHJpbmcgaW50byBhbiBhcnJheSBvZiB0d28gY2hhciBlbGVtZW50c1xuXHRcdHZhciBoZXhBcnJheSA9IGhleFN0cmluZy5tYXRjaCgvLnsyfS9nKTtcblxuXHRcdC8vIE5vdyBwYXJzZSB0aGVtIG91dCBhcyBpbnRlZ2Vyc1xuXHRcdGhleEFycmF5ID0gaGV4QXJyYXkubWFwKGl0ZW0gPT4gcGFyc2VJbnQoaXRlbSwgMTYpKVxuXG5cdFx0Ly8gUHJlcGVuZCBlbXB0eSBieXRlcyBpZiB3ZSBkb24ndCBoYXZlIGVub3VnaFxuXHRcdGlmIChoZXhBcnJheS5sZW5ndGggPCBieXRlc05lZWRlZCkge1xuXHRcdFx0d2hpbGUgKGJ5dGVzTmVlZGVkIC0gaGV4QXJyYXkubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRoZXhBcnJheS51bnNoaWZ0KDApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBoZXhBcnJheTtcblx0fVxuXG5cdC8qKlx0XG5cdCAqIENvbnZlcnRzIHZhbHVlIHRvIGFycmF5IGlmIG5lZWRlZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG5cdCAqIEByZXR1cm4ge2FycmF5fVxuXHQgKi9cblx0c3RhdGljIHRvQXJyYXkodmFsdWUpIHtcblx0XHRpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB2YWx1ZTtcblx0XHRyZXR1cm4gW3ZhbHVlXTtcblx0fVxufVxuXG5leHBvcnQge1V0aWxzfTtcbmNsYXNzIFZleEZsb3cge1xuXHRcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0Ly8gY29kZS4uLlxuXHR9XG5cblx0LyoqXG5cdCAqIFN1cHBvcnQgZm9yIGNvbnZlcnRpbmcgVmV4RmxvdyB2b2ljZSBpbnRvIE1pZGlXcml0ZXJKUyB0cmFja1xuXHQgKiBAcmV0dXJuIE1pZGlXcml0aWVyLlRyYWNrIG9iamVjdFxuXHQgKi9cblx0dHJhY2tGcm9tVm9pY2Uodm9pY2UpIHtcblx0XHR2YXIgdHJhY2sgPSBuZXcgVHJhY2soKTtcblx0XHR2YXIgd2FpdDtcblx0XHR2YXIgcGl0Y2hlcyA9IFtdO1xuXG5cdFx0dm9pY2UudGlja2FibGVzLmZvckVhY2goZnVuY3Rpb24odGlja2FibGUpIHtcblx0XHRcdHBpdGNoZXMgPSBbXTtcblxuXHRcdFx0aWYgKHRpY2thYmxlLm5vdGVUeXBlID09PSAnbicpIHtcblx0XHRcdFx0dGlja2FibGUua2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuXHRcdFx0XHRcdC8vIGJ1aWxkIGFycmF5IG9mIHBpdGNoZXNcblx0XHRcdFx0XHRwaXRjaGVzLnB1c2godGhpcy5jb252ZXJ0UGl0Y2goa2V5KSk7XG5cdFx0XHRcdH0pO1xuXG5cdFx0XHR9IGVsc2UgaWYgKHRpY2thYmxlLm5vdGVUeXBlID09PSAncicpIHtcblx0XHRcdFx0Ly8gbW92ZSBvbiB0byB0aGUgbmV4dCB0aWNrYWJsZSBhbmQgdXNlIHRoaXMgcmVzdCBhcyBhIGB3YWl0YCBwcm9wZXJ0eSBmb3IgdGhlIG5leHQgZXZlbnRcblx0XHRcdFx0d2FpdCA9IHRoaXMuY29udmVydER1cmF0aW9uKHRpY2thYmxlKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR0cmFjay5hZGRFdmVudChuZXcgTm90ZUV2ZW50KHtwaXRjaDogcGl0Y2hlcywgZHVyYXRpb246IHRoaXMuY29udmVydER1cmF0aW9uKHRpY2thYmxlKSwgd2FpdDogd2FpdH0pKTtcblx0XHRcdFxuXHRcdFx0Ly8gcmVzZXQgd2FpdFxuXHRcdFx0d2FpdCA9IDA7XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gdHJhY2s7XG5cdH1cblxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBWZXhGbG93IHBpdGNoIHN5bnRheCB0byBNaWRpV3JpdGVySlMgc3ludGF4XG5cdCAqIEBwYXJhbSBwaXRjaCBzdHJpbmdcblx0ICovXG5cdGNvbnZlcnRQaXRjaChwaXRjaCkge1xuXHRcdHJldHVybiBwaXRjaC5yZXBsYWNlKCcvJywgJycpO1xuXHR9IFxuXG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIFZleEZsb3cgZHVyYXRpb24gc3ludGF4IHRvIE1pZGlXcml0ZXJKUyBzeW50YXhcblx0ICogQHBhcmFtIG5vdGUgc3RydWN0IGZyb20gVmV4Rmxvd1xuXHQgKi9cblx0Y29udmVydER1cmF0aW9uKG5vdGUpIHtcblx0XHRzd2l0Y2ggKG5vdGUuZHVyYXRpb24pIHtcblx0XHRcdGNhc2UgJ3cnOlxuXHRcdFx0XHRyZXR1cm4gJzEnO1xuXHRcdFx0Y2FzZSAnaCc6XG5cdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDInIDogJzInO1xuXHRcdFx0Y2FzZSAncSc6XG5cdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDQnIDogJzQnO1xuXHRcdFx0Y2FzZSAnOCc6XG5cdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDgnIDogJzgnO1xuXHRcdH1cblxuXHRcdHJldHVybiBub3RlLmR1cmF0aW9uO1xuXHR9O1xufVxuXG5leHBvcnQge1ZleEZsb3d9O1xuLyoqXG4gKiBPYmplY3QgdGhhdCBwdXRzIHRvZ2V0aGVyIHRyYWNrcyBhbmQgcHJvdmlkZXMgbWV0aG9kcyBmb3IgZmlsZSBvdXRwdXQuXG4gKiBAcGFyYW0ge2FycmF5fSB0cmFja3MgLSBBbiBhcnJheSBvZiB7VHJhY2t9IG9iamVjdHMuXG4gKiBAcmV0dXJuIHtXcml0ZXJ9XG4gKi9cbmNsYXNzIFdyaXRlciB7XG5cdGNvbnN0cnVjdG9yKHRyYWNrcykge1xuXHRcdHRoaXMuZGF0YSA9IFtdO1xuXG5cdFx0dmFyIHRyYWNrVHlwZSA9IHRyYWNrcy5sZW5ndGggPiAxID8gQ29uc3RhbnRzLkhFQURFUl9DSFVOS19GT1JNQVQxIDogQ29uc3RhbnRzLkhFQURFUl9DSFVOS19GT1JNQVQwO1xuXHRcdHZhciBudW1iZXJPZlRyYWNrcyA9IFV0aWxzLm51bWJlclRvQnl0ZXModHJhY2tzLmxlbmd0aCwgMik7IC8vIHR3byBieXRlcyBsb25nXG5cblx0XHQvLyBIZWFkZXIgY2h1bmtcblx0XHR0aGlzLmRhdGEucHVzaChuZXcgQ2h1bmsoe1xuXHRcdFx0XHRcdFx0XHRcdHR5cGU6IENvbnN0YW50cy5IRUFERVJfQ0hVTktfVFlQRSxcblx0XHRcdFx0XHRcdFx0XHRkYXRhOiB0cmFja1R5cGUuY29uY2F0KG51bWJlck9mVHJhY2tzLCBDb25zdGFudHMuSEVBREVSX0NIVU5LX0RJVklTSU9OKX0pKTtcblxuXHRcdC8vIFRyYWNrIGNodW5rc1xuXHRcdHRyYWNrcy5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrLCBpKSB7XG5cdFx0XHR0cmFjay5hZGRFdmVudChuZXcgTWV0YUV2ZW50KHtkYXRhOiBDb25zdGFudHMuTUVUQV9FTkRfT0ZfVFJBQ0tfSUR9KSk7XG5cdFx0XHR0aGlzLmRhdGEucHVzaCh0cmFjayk7XG5cdFx0fSwgdGhpcyk7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIHRoZSBmaWxlIGludG8gYSBVaW50OEFycmF5XG5cdCAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9XG5cdCAqL1xuXHRidWlsZEZpbGUoKSB7XG5cdFx0dmFyIGJ1aWxkID0gW107XG5cblx0XHQvLyBEYXRhIGNvbnNpc3RzIG9mIGNodW5rcyB3aGljaCBjb25zaXN0cyBvZiBkYXRhXG5cdFx0dGhpcy5kYXRhLmZvckVhY2goKGQpID0+IGJ1aWxkID0gYnVpbGQuY29uY2F0KGQudHlwZSwgZC5zaXplLCBkLmRhdGEpKTtcblxuXHRcdHJldHVybiBuZXcgVWludDhBcnJheShidWlsZCk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydCBmaWxlIGJ1ZmZlciB0byBhIGJhc2U2NCBzdHJpbmcuICBEaWZmZXJlbnQgbWV0aG9kcyBkZXBlbmRpbmcgb24gaWYgYnJvd3NlciBvciBub2RlLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRiYXNlNjQoKSB7XG5cdFx0aWYgKHR5cGVvZiBidG9hID09PSAnZnVuY3Rpb24nKSByZXR1cm4gYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIHRoaXMuYnVpbGRGaWxlKCkpKTtcblx0XHRyZXR1cm4gbmV3IEJ1ZmZlcih0aGlzLmJ1aWxkRmlsZSgpKS50b1N0cmluZygnYmFzZTY0Jyk7XG5cdH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZGF0YSBVUkkuXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqL1xuICAgIGRhdGFVcmkoKSB7XG4gICAgXHRyZXR1cm4gJ2RhdGE6YXVkaW8vbWlkaTtiYXNlNjQsJyArIHRoaXMuYmFzZTY0KCk7XG4gICAgfVxuXG5cdC8qKlxuXHQgKiBPdXRwdXQgdG8gc3Rkb3V0XG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG4gICAgc3Rkb3V0KCkge1xuICAgIFx0cmV0dXJuIHByb2Nlc3Muc3Rkb3V0LndyaXRlKG5ldyBCdWZmZXIodGhpcy5idWlsZEZpbGUoKSkpO1xuICAgIH1cblxuXHQvKipcblx0ICogU2F2ZSB0byBNSURJIGZpbGVcblx0ICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lXG5cdCAqL1xuXHRzYXZlTUlESShmaWxlbmFtZSkge1xuXHRcdHZhciBidWZmZXIgPSBuZXcgQnVmZmVyKHRoaXMuYnVpbGRGaWxlKCkpO1xuXHRcdGZzLndyaXRlRmlsZShmaWxlbmFtZSArICcubWlkJywgYnVmZmVyLCBmdW5jdGlvbiAoZXJyKSB7XG5cdFx0XHRpZihlcnIpIHJldHVybiBjb25zb2xlLmxvZyhlcnIpO1xuXHRcdH0pO1xuXHR9XG59XG5cbmV4cG9ydCB7V3JpdGVyfTtcbiJdfQ==\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/midi-writer-js/build/index.js\n// module id = 140\n// module chunks = 0","'use strict'\n\n// util\nfunction fillStr (s, num) { return Array(num + 1).join(s) }\nfunction isNum (x) { return typeof x === 'number' }\nfunction isStr (x) { return typeof x === 'string' }\nfunction isDef (x) { return typeof x !== 'undefined' }\nfunction midiToFreq (midi, tuning) {\n return Math.pow(2, (midi - 69) / 12) * (tuning || 440)\n}\n\nvar REGEX = /^([a-gA-G])(#{1,}|b{1,}|x{1,}|)(-?\\d*)\\s*(.*)\\s*$/\n/**\n * A regex for matching note strings in scientific notation.\n *\n * @name regex\n * @function\n * @return {RegExp} the regexp used to parse the note name\n *\n * The note string should have the form `letter[accidentals][octave][element]`\n * where:\n *\n * - letter: (Required) is a letter from A to G either upper or lower case\n * - accidentals: (Optional) can be one or more `b` (flats), `#` (sharps) or `x` (double sharps).\n * They can NOT be mixed.\n * - octave: (Optional) a positive or negative integer\n * - element: (Optional) additionally anything after the duration is considered to\n * be the element name (for example: 'C2 dorian')\n *\n * The executed regex contains (by array index):\n *\n * - 0: the complete string\n * - 1: the note letter\n * - 2: the optional accidentals\n * - 3: the optional octave\n * - 4: the rest of the string (trimmed)\n *\n * @example\n * var parser = require('note-parser')\n * parser.regex.exec('c#4')\n * // => ['c#4', 'c', '#', '4', '']\n * parser.regex.exec('c#4 major')\n * // => ['c#4major', 'c', '#', '4', 'major']\n * parser.regex().exec('CMaj7')\n * // => ['CMaj7', 'C', '', '', 'Maj7']\n */\nexport function regex () { return REGEX }\n\nvar SEMITONES = [0, 2, 4, 5, 7, 9, 11]\n/**\n * Parse a note name in scientific notation an return it's components,\n * and some numeric properties including midi number and frequency.\n *\n * @name parse\n * @function\n * @param {String} note - the note string to be parsed\n * @param {Boolean} isTonic - true the strings it's supposed to contain a note number\n * and some category (for example an scale: 'C# major'). It's false by default,\n * but when true, en extra tonicOf property is returned with the category ('major')\n * @param {Float} tunning - The frequency of A4 note to calculate frequencies.\n * By default it 440.\n * @return {Object} the parsed note name or null if not a valid note\n *\n * The parsed note name object will ALWAYS contains:\n * - letter: the uppercase letter of the note\n * - acc: the accidentals of the note (only sharps or flats)\n * - pc: the pitch class (letter + acc)\n * - step: s a numeric representation of the letter. It's an integer from 0 to 6\n * where 0 = C, 1 = D ... 6 = B\n * - alt: a numeric representation of the accidentals. 0 means no alteration,\n * positive numbers are for sharps and negative for flats\n * - chroma: a numeric representation of the pitch class. It's like midi for\n * pitch classes. 0 = C, 1 = C#, 2 = D ... 11 = B. Can be used to find enharmonics\n * since, for example, chroma of 'Cb' and 'B' are both 11\n *\n * If the note has octave, the parser object will contain:\n * - oct: the octave number (as integer)\n * - midi: the midi number\n * - freq: the frequency (using tuning parameter as base)\n *\n * If the parameter `isTonic` is set to true, the parsed object will contain:\n * - tonicOf: the rest of the string that follows note name (left and right trimmed)\n *\n * @example\n * var parse = require('note-parser').parse\n * parse('Cb4')\n * // => { letter: 'C', acc: 'b', pc: 'Cb', step: 0, alt: -1, chroma: -1,\n * oct: 4, midi: 59, freq: 246.94165062806206 }\n * // if no octave, no midi, no freq\n * parse('fx')\n * // => { letter: 'F', acc: '##', pc: 'F##', step: 3, alt: 2, chroma: 7 })\n */\nexport function parse (str, isTonic, tuning) {\n if (typeof str !== 'string') return null\n var m = REGEX.exec(str)\n if (!m || (!isTonic && m[4])) return null\n\n var p = { letter: m[1].toUpperCase(), acc: m[2].replace(/x/g, '##') }\n p.pc = p.letter + p.acc\n p.step = (p.letter.charCodeAt(0) + 3) % 7\n p.alt = p.acc[0] === 'b' ? -p.acc.length : p.acc.length\n var pos = SEMITONES[p.step] + p.alt\n p.chroma = pos < 0 ? 12 + pos : pos % 12\n if (m[3]) { // has octave\n p.oct = +m[3]\n p.midi = pos + 12 * (p.oct + 1)\n p.freq = midiToFreq(p.midi, tuning)\n }\n if (isTonic) p.tonicOf = m[4]\n return p\n}\n\nvar LETTERS = 'CDEFGAB'\nfunction accStr (n) { return !isNum(n) ? '' : n < 0 ? fillStr('b', -n) : fillStr('#', n) }\nfunction octStr (n) { return !isNum(n) ? '' : '' + n }\n\n/**\n * Create a string from a parsed object or `step, alteration, octave` parameters\n * @param {Object} obj - the parsed data object\n * @return {String} a note string or null if not valid parameters\n * @since 1.2\n * @example\n * parser.build(parser.parse('cb2')) // => 'Cb2'\n *\n * @example\n * // it accepts (step, alteration, octave) parameters:\n * parser.build(3) // => 'F'\n * parser.build(3, -1) // => 'Fb'\n * parser.build(3, -1, 4) // => 'Fb4'\n */\nexport function build (s, a, o) {\n if (s === null || typeof s === 'undefined') return null\n if (s.step) return build(s.step, s.alt, s.oct)\n if (s < 0 || s > 6) return null\n return LETTERS.charAt(s) + accStr(a) + octStr(o)\n}\n\n/**\n * Get midi of a note\n *\n * @name midi\n * @function\n * @param {String|Integer} note - the note name or midi number\n * @return {Integer} the midi number of the note or null if not a valid note\n * or the note does NOT contains octave\n * @example\n * var parser = require('note-parser')\n * parser.midi('A4') // => 69\n * parser.midi('A') // => null\n * @example\n * // midi numbers are bypassed (even as strings)\n * parser.midi(60) // => 60\n * parser.midi('60') // => 60\n */\nexport function midi (note) {\n if ((isNum(note) || isStr(note)) && note >= 0 && note < 128) return +note\n var p = parse(note)\n return p && isDef(p.midi) ? p.midi : null\n}\n\n/**\n * Get freq of a note in hertzs (in a well tempered 440Hz A4)\n *\n * @name freq\n * @function\n * @param {String} note - the note name or note midi number\n * @param {String} tuning - (Optional) the A4 frequency (440 by default)\n * @return {Float} the freq of the number if hertzs or null if not valid note\n * @example\n * var parser = require('note-parser')\n * parser.freq('A4') // => 440\n * parser.freq('A') // => null\n * @example\n * // can change tuning (440 by default)\n * parser.freq('A4', 444) // => 444\n * parser.freq('A3', 444) // => 222\n * @example\n * // it accepts midi numbers (as numbers and as strings)\n * parser.freq(69) // => 440\n * parser.freq('69', 442) // => 442\n */\nexport function freq (note, tuning) {\n var m = midi(note)\n return m === null ? null : midiToFreq(m, tuning)\n}\n\nexport function letter (src) { return (parse(src) || {}).letter }\nexport function acc (src) { return (parse(src) || {}).acc }\nexport function pc (src) { return (parse(src) || {}).pc }\nexport function step (src) { return (parse(src) || {}).step }\nexport function alt (src) { return (parse(src) || {}).alt }\nexport function chroma (src) { return (parse(src) || {}).chroma }\nexport function oct (src) { return (parse(src) || {}).oct }\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/note-parser/index.js\n// module id = 141\n// module chunks = 0","module.exports = require('./lib/_stream_duplex.js');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/readable-stream/duplex-browser.js\n// module id = 142\n// module chunks = 0","// a passthrough stream.\n// basically just the most minimal sort of Transform stream.\n// Every written chunk gets output as-is.\n\n'use strict';\n\nmodule.exports = PassThrough;\n\nvar Transform = require('./_stream_transform');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(PassThrough, Transform);\n\nfunction PassThrough(options) {\n if (!(this instanceof PassThrough)) return new PassThrough(options);\n\n Transform.call(this, options);\n}\n\nPassThrough.prototype._transform = function (chunk, encoding, cb) {\n cb(null, chunk);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/readable-stream/lib/_stream_passthrough.js\n// module id = 143\n// module chunks = 0","'use strict';\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nmodule.exports = BufferList;\n\nfunction BufferList() {\n this.head = null;\n this.tail = null;\n this.length = 0;\n}\n\nBufferList.prototype.push = function (v) {\n var entry = { data: v, next: null };\n if (this.length > 0) this.tail.next = entry;else this.head = entry;\n this.tail = entry;\n ++this.length;\n};\n\nBufferList.prototype.unshift = function (v) {\n var entry = { data: v, next: this.head };\n if (this.length === 0) this.tail = entry;\n this.head = entry;\n ++this.length;\n};\n\nBufferList.prototype.shift = function () {\n if (this.length === 0) return;\n var ret = this.head.data;\n if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;\n --this.length;\n return ret;\n};\n\nBufferList.prototype.clear = function () {\n this.head = this.tail = null;\n this.length = 0;\n};\n\nBufferList.prototype.join = function (s) {\n if (this.length === 0) return '';\n var p = this.head;\n var ret = '' + p.data;\n while (p = p.next) {\n ret += s + p.data;\n }return ret;\n};\n\nBufferList.prototype.concat = function (n) {\n if (this.length === 0) return bufferShim.alloc(0);\n if (this.length === 1) return this.head.data;\n var ret = bufferShim.allocUnsafe(n >>> 0);\n var p = this.head;\n var i = 0;\n while (p) {\n p.data.copy(ret, i);\n i += p.data.length;\n p = p.next;\n }\n return ret;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/readable-stream/lib/internal/streams/BufferList.js\n// module id = 144\n// module chunks = 0","module.exports = require('./readable').PassThrough\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/readable-stream/passthrough.js\n// module id = 145\n// module chunks = 0","module.exports = require('./readable').Transform\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/readable-stream/transform.js\n// module id = 146\n// module chunks = 0","module.exports = require('./lib/_stream_writable.js');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/readable-stream/writable-browser.js\n// module id = 147\n// module chunks = 0","(function (global, undefined) {\n \"use strict\";\n\n if (global.setImmediate) {\n return;\n }\n\n var nextHandle = 1; // Spec says greater than zero\n var tasksByHandle = {};\n var currentlyRunningATask = false;\n var doc = global.document;\n var registerImmediate;\n\n function setImmediate(callback) {\n // Callback can either be a function or a string\n if (typeof callback !== \"function\") {\n callback = new Function(\"\" + callback);\n }\n // Copy function arguments\n var args = new Array(arguments.length - 1);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i + 1];\n }\n // Store and register the task\n var task = { callback: callback, args: args };\n tasksByHandle[nextHandle] = task;\n registerImmediate(nextHandle);\n return nextHandle++;\n }\n\n function clearImmediate(handle) {\n delete tasksByHandle[handle];\n }\n\n function run(task) {\n var callback = task.callback;\n var args = task.args;\n switch (args.length) {\n case 0:\n callback();\n break;\n case 1:\n callback(args[0]);\n break;\n case 2:\n callback(args[0], args[1]);\n break;\n case 3:\n callback(args[0], args[1], args[2]);\n break;\n default:\n callback.apply(undefined, args);\n break;\n }\n }\n\n function runIfPresent(handle) {\n // From the spec: \"Wait until any invocations of this algorithm started before this one have completed.\"\n // So if we're currently running a task, we'll need to delay this invocation.\n if (currentlyRunningATask) {\n // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a\n // \"too much recursion\" error.\n setTimeout(runIfPresent, 0, handle);\n } else {\n var task = tasksByHandle[handle];\n if (task) {\n currentlyRunningATask = true;\n try {\n run(task);\n } finally {\n clearImmediate(handle);\n currentlyRunningATask = false;\n }\n }\n }\n }\n\n function installNextTickImplementation() {\n registerImmediate = function(handle) {\n process.nextTick(function () { runIfPresent(handle); });\n };\n }\n\n function canUsePostMessage() {\n // The test against `importScripts` prevents this implementation from being installed inside a web worker,\n // where `global.postMessage` means something completely different and can't be used for this purpose.\n if (global.postMessage && !global.importScripts) {\n var postMessageIsAsynchronous = true;\n var oldOnMessage = global.onmessage;\n global.onmessage = function() {\n postMessageIsAsynchronous = false;\n };\n global.postMessage(\"\", \"*\");\n global.onmessage = oldOnMessage;\n return postMessageIsAsynchronous;\n }\n }\n\n function installPostMessageImplementation() {\n // Installs an event handler on `global` for the `message` event: see\n // * https://developer.mozilla.org/en/DOM/window.postMessage\n // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages\n\n var messagePrefix = \"setImmediate$\" + Math.random() + \"$\";\n var onGlobalMessage = function(event) {\n if (event.source === global &&\n typeof event.data === \"string\" &&\n event.data.indexOf(messagePrefix) === 0) {\n runIfPresent(+event.data.slice(messagePrefix.length));\n }\n };\n\n if (global.addEventListener) {\n global.addEventListener(\"message\", onGlobalMessage, false);\n } else {\n global.attachEvent(\"onmessage\", onGlobalMessage);\n }\n\n registerImmediate = function(handle) {\n global.postMessage(messagePrefix + handle, \"*\");\n };\n }\n\n function installMessageChannelImplementation() {\n var channel = new MessageChannel();\n channel.port1.onmessage = function(event) {\n var handle = event.data;\n runIfPresent(handle);\n };\n\n registerImmediate = function(handle) {\n channel.port2.postMessage(handle);\n };\n }\n\n function installReadyStateChangeImplementation() {\n var html = doc.documentElement;\n registerImmediate = function(handle) {\n // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var script = doc.createElement(\"script\");\n script.onreadystatechange = function () {\n runIfPresent(handle);\n script.onreadystatechange = null;\n html.removeChild(script);\n script = null;\n };\n html.appendChild(script);\n };\n }\n\n function installSetTimeoutImplementation() {\n registerImmediate = function(handle) {\n setTimeout(runIfPresent, 0, handle);\n };\n }\n\n // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.\n var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);\n attachTo = attachTo && attachTo.setTimeout ? attachTo : global;\n\n // Don't get fooled by e.g. browserify environments.\n if ({}.toString.call(global.process) === \"[object process]\") {\n // For Node.js before 0.9\n installNextTickImplementation();\n\n } else if (canUsePostMessage()) {\n // For non-IE10 modern browsers\n installPostMessageImplementation();\n\n } else if (global.MessageChannel) {\n // For web workers, where supported\n installMessageChannelImplementation();\n\n } else if (doc && \"onreadystatechange\" in doc.createElement(\"script\")) {\n // For IE 6–8\n installReadyStateChangeImplementation();\n\n } else {\n // For older browsers\n installSetTimeoutImplementation();\n }\n\n attachTo.setImmediate = setImmediate;\n attachTo.clearImmediate = clearImmediate;\n}(typeof self === \"undefined\" ? typeof global === \"undefined\" ? this : global : self));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/setimmediate/setImmediate.js\n// module id = 148\n// module chunks = 0","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Stream;\n\nvar EE = require('events').EventEmitter;\nvar inherits = require('inherits');\n\ninherits(Stream, EE);\nStream.Readable = require('readable-stream/readable.js');\nStream.Writable = require('readable-stream/writable.js');\nStream.Duplex = require('readable-stream/duplex.js');\nStream.Transform = require('readable-stream/transform.js');\nStream.PassThrough = require('readable-stream/passthrough.js');\n\n// Backwards-compat with node 0.4.x\nStream.Stream = Stream;\n\n\n\n// old-style streams. Note that the pipe method (the only relevant\n// part of this class) is overridden in the Readable class.\n\nfunction Stream() {\n EE.call(this);\n}\n\nStream.prototype.pipe = function(dest, options) {\n var source = this;\n\n function ondata(chunk) {\n if (dest.writable) {\n if (false === dest.write(chunk) && source.pause) {\n source.pause();\n }\n }\n }\n\n source.on('data', ondata);\n\n function ondrain() {\n if (source.readable && source.resume) {\n source.resume();\n }\n }\n\n dest.on('drain', ondrain);\n\n // If the 'end' option is not supplied, dest.end() will be called when\n // source gets the 'end' or 'close' events. Only dest.end() once.\n if (!dest._isStdio && (!options || options.end !== false)) {\n source.on('end', onend);\n source.on('close', onclose);\n }\n\n var didOnEnd = false;\n function onend() {\n if (didOnEnd) return;\n didOnEnd = true;\n\n dest.end();\n }\n\n\n function onclose() {\n if (didOnEnd) return;\n didOnEnd = true;\n\n if (typeof dest.destroy === 'function') dest.destroy();\n }\n\n // don't leave dangling pipes when there are errors.\n function onerror(er) {\n cleanup();\n if (EE.listenerCount(this, 'error') === 0) {\n throw er; // Unhandled stream error in pipe.\n }\n }\n\n source.on('error', onerror);\n dest.on('error', onerror);\n\n // remove all the event listeners that were added.\n function cleanup() {\n source.removeListener('data', ondata);\n dest.removeListener('drain', ondrain);\n\n source.removeListener('end', onend);\n source.removeListener('close', onclose);\n\n source.removeListener('error', onerror);\n dest.removeListener('error', onerror);\n\n source.removeListener('end', cleanup);\n source.removeListener('close', cleanup);\n\n dest.removeListener('close', cleanup);\n }\n\n source.on('end', cleanup);\n source.on('close', cleanup);\n\n dest.on('close', cleanup);\n\n dest.emit('pipe', source);\n\n // Allow for unix-like usage: A.pipe(B).pipe(C)\n return dest;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stream-browserify/index.js\n// module id = 149\n// module chunks = 0","/**\n * A midi note number is a number representation of a note pitch. It can be\n * integers so it's equal tempered tuned, or float to indicate it's not\n * tuned into equal temepered scale.\n *\n * This module contains functions to convert to and from midi notes.\n *\n * @example\n * var midi = require('tonal-midi')\n * midi.toMidi('A4') // => 69\n * midi.note(69) // => 'A4'\n * midi.note(61) // => 'Db4'\n * midi.note(61, true) // => 'C#4'\n *\n * @module midi\n */\n\nimport { midi } from 'note-parser'\n\n/**\n * Convert the given note to a midi note number. If you pass a midi number it\n * will returned as is.\n *\n * @param {Array|String|Number} note - the note to get the midi number from\n * @return {Integer} the midi number or null if not valid pitch\n * @example\n * midi.toMidi('C4') // => 60\n * midi.toMidi(60) // => 60\n * midi.toMidi('60') // => 60\n */\nexport function toMidi (val) {\n if (Array.isArray(val) && val.length === 2) return val[0] * 7 + val[1] * 12 + 12\n return midi(val)\n}\n\nvar FLATS = 'C Db D Eb E F Gb G Ab A Bb B'.split(' ')\nvar SHARPS = 'C C# D D# E F F# G G# A A# B'.split(' ')\n\n/**\n * Given a midi number, returns a note name. The altered notes will have\n * flats unless explicitly set with the optional `useSharps` parameter.\n *\n * @function\n * @param {Integer} midi - the midi note number\n * @param {Boolean} useSharps - (Optional) set to true to use sharps instead of flats\n * @return {String} the note name\n * @example\n * var midi = require('tonal-midi')\n * midi.note(61) // => 'Db4'\n * midi.note(61, true) // => 'C#4'\n * // it rounds to nearest note\n * midi.note(61.7) // => 'D4'\n */\nexport function note (num, sharps) {\n if (num === true || num === false) return function (m) { return note(m, num) }\n num = Math.round(num)\n var pcs = sharps === true ? SHARPS : FLATS\n var pc = pcs[num % 12]\n var o = Math.floor(num / 12) - 1\n return pc + o\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/tonal-midi/index.js\n// module id = 150\n// module chunks = 0","\n/**\n * Module exports.\n */\n\nmodule.exports = deprecate;\n\n/**\n * Mark that a method should not be used.\n * Returns a modified function which warns once by default.\n *\n * If `localStorage.noDeprecation = true` is set, then it is a no-op.\n *\n * If `localStorage.throwDeprecation = true` is set, then deprecated functions\n * will throw an Error when invoked.\n *\n * If `localStorage.traceDeprecation = true` is set, then deprecated functions\n * will invoke `console.trace()` instead of `console.error()`.\n *\n * @param {Function} fn - the function to deprecate\n * @param {String} msg - the string to print to the console when `fn` is invoked\n * @returns {Function} a new \"deprecated\" version of `fn`\n * @api public\n */\n\nfunction deprecate (fn, msg) {\n if (config('noDeprecation')) {\n return fn;\n }\n\n var warned = false;\n function deprecated() {\n if (!warned) {\n if (config('throwDeprecation')) {\n throw new Error(msg);\n } else if (config('traceDeprecation')) {\n console.trace(msg);\n } else {\n console.warn(msg);\n }\n warned = true;\n }\n return fn.apply(this, arguments);\n }\n\n return deprecated;\n}\n\n/**\n * Checks `localStorage` for boolean values for the given `name`.\n *\n * @param {String} name\n * @returns {Boolean}\n * @api private\n */\n\nfunction config (name) {\n // accessing global.localStorage can trigger a DOMException in sandboxed iframes\n try {\n if (!global.localStorage) return false;\n } catch (_) {\n return false;\n }\n var val = global.localStorage[name];\n if (null == val) return false;\n return String(val).toLowerCase() === 'true';\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/util-deprecate/browser.js\n// module id = 151\n// module chunks = 0","if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/util/~/inherits/inherits_browser.js\n// module id = 152\n// module chunks = 0","module.exports = function isBuffer(arg) {\n return arg && typeof arg === 'object'\n && typeof arg.copy === 'function'\n && typeof arg.fill === 'function'\n && typeof arg.readUInt8 === 'function';\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/util/support/isBufferBrowser.js\n// module id = 153\n// module chunks = 0","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n if (!isString(f)) {\n var objects = [];\n for (var i = 0; i < arguments.length; i++) {\n objects.push(inspect(arguments[i]));\n }\n return objects.join(' ');\n }\n\n var i = 1;\n var args = arguments;\n var len = args.length;\n var str = String(f).replace(formatRegExp, function(x) {\n if (x === '%%') return '%';\n if (i >= len) return x;\n switch (x) {\n case '%s': return String(args[i++]);\n case '%d': return Number(args[i++]);\n case '%j':\n try {\n return JSON.stringify(args[i++]);\n } catch (_) {\n return '[Circular]';\n }\n default:\n return x;\n }\n });\n for (var x = args[i]; i < len; x = args[++i]) {\n if (isNull(x) || !isObject(x)) {\n str += ' ' + x;\n } else {\n str += ' ' + inspect(x);\n }\n }\n return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n // Allow for deprecating things in the process of starting up.\n if (isUndefined(global.process)) {\n return function() {\n return exports.deprecate(fn, msg).apply(this, arguments);\n };\n }\n\n if (process.noDeprecation === true) {\n return fn;\n }\n\n var warned = false;\n function deprecated() {\n if (!warned) {\n if (process.throwDeprecation) {\n throw new Error(msg);\n } else if (process.traceDeprecation) {\n console.trace(msg);\n } else {\n console.error(msg);\n }\n warned = true;\n }\n return fn.apply(this, arguments);\n }\n\n return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n if (isUndefined(debugEnviron))\n debugEnviron = process.env.NODE_DEBUG || '';\n set = set.toUpperCase();\n if (!debugs[set]) {\n if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n var pid = process.pid;\n debugs[set] = function() {\n var msg = exports.format.apply(exports, arguments);\n console.error('%s %d: %s', set, pid, msg);\n };\n } else {\n debugs[set] = function() {};\n }\n }\n return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n // default options\n var ctx = {\n seen: [],\n stylize: stylizeNoColor\n };\n // legacy...\n if (arguments.length >= 3) ctx.depth = arguments[2];\n if (arguments.length >= 4) ctx.colors = arguments[3];\n if (isBoolean(opts)) {\n // legacy...\n ctx.showHidden = opts;\n } else if (opts) {\n // got an \"options\" object\n exports._extend(ctx, opts);\n }\n // set default options\n if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n if (isUndefined(ctx.depth)) ctx.depth = 2;\n if (isUndefined(ctx.colors)) ctx.colors = false;\n if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n if (ctx.colors) ctx.stylize = stylizeWithColor;\n return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n 'bold' : [1, 22],\n 'italic' : [3, 23],\n 'underline' : [4, 24],\n 'inverse' : [7, 27],\n 'white' : [37, 39],\n 'grey' : [90, 39],\n 'black' : [30, 39],\n 'blue' : [34, 39],\n 'cyan' : [36, 39],\n 'green' : [32, 39],\n 'magenta' : [35, 39],\n 'red' : [31, 39],\n 'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n 'special': 'cyan',\n 'number': 'yellow',\n 'boolean': 'yellow',\n 'undefined': 'grey',\n 'null': 'bold',\n 'string': 'green',\n 'date': 'magenta',\n // \"name\": intentionally not styling\n 'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n var style = inspect.styles[styleType];\n\n if (style) {\n return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n '\\u001b[' + inspect.colors[style][1] + 'm';\n } else {\n return str;\n }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n return str;\n}\n\n\nfunction arrayToHash(array) {\n var hash = {};\n\n array.forEach(function(val, idx) {\n hash[val] = true;\n });\n\n return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (ctx.customInspect &&\n value &&\n isFunction(value.inspect) &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes, ctx);\n if (!isString(ret)) {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // Look up the keys of the object.\n var keys = Object.keys(value);\n var visibleKeys = arrayToHash(keys);\n\n if (ctx.showHidden) {\n keys = Object.getOwnPropertyNames(value);\n }\n\n // IE doesn't make error fields non-enumerable\n // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n if (isError(value)\n && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n return formatError(value);\n }\n\n // Some type of object without properties can be shortcutted.\n if (keys.length === 0) {\n if (isFunction(value)) {\n var name = value.name ? ': ' + value.name : '';\n return ctx.stylize('[Function' + name + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (isFunction(value)) {\n var n = value.name ? ': ' + value.name : '';\n base = ' [Function' + n + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n base = ' ' + formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n if (isUndefined(value))\n return ctx.stylize('undefined', 'undefined');\n if (isString(value)) {\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n }\n if (isNumber(value))\n return ctx.stylize('' + value, 'number');\n if (isBoolean(value))\n return ctx.stylize('' + value, 'boolean');\n // For some reason typeof null is \"object\", so special case here.\n if (isNull(value))\n return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (hasOwnProperty(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str, desc;\n desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n if (desc.get) {\n if (desc.set) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (desc.set) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n if (!hasOwnProperty(visibleKeys, key)) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(desc.value) < 0) {\n if (isNull(recurseTimes)) {\n str = formatValue(ctx, desc.value, null);\n } else {\n str = formatValue(ctx, desc.value, recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (isUndefined(name)) {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n return isObject(e) &&\n (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n return arg === null ||\n typeof arg === 'boolean' ||\n typeof arg === 'number' ||\n typeof arg === 'string' ||\n typeof arg === 'symbol' || // ES6 symbol\n typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n 'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n var d = new Date();\n var time = [pad(d.getHours()),\n pad(d.getMinutes()),\n pad(d.getSeconds())].join(':');\n return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n * prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n // Don't do anything if add isn't an object\n if (!add || !isObject(add)) return origin;\n\n var keys = Object.keys(add);\n var i = keys.length;\n while (i--) {\n origin[keys[i]] = add[keys[i]];\n }\n return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/util/util.js\n// module id = 154\n// module chunks = 0","/*\n\nWebMidi v2.2.0\n\nWebMidi.js helps you tame the Web MIDI API. Send and receive MIDI messages with ease. Control instruments with user-friendly functions (playNote, sendPitchBend, etc.). React to MIDI input with simple event listeners (noteon, pitchbend, controlchange, etc.).\nhttps://github.com/djipco/webmidi\n\n\nThe MIT License (MIT)\n\nCopyright (c) 2015-2018, Jean-Philippe Côté\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and\nassociated documentation files (the \"Software\"), to deal in the Software without restriction,\nincluding without limitation the rights to use, copy, modify, merge, publish, distribute,\nsublicense, and/or sell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial\nportions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\nNOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES\nOR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n*/\n\n!function(scope){\"use strict\";function WebMidi(){if(WebMidi.prototype._singleton)throw new Error(\"WebMidi is a singleton, it cannot be instantiated directly.\");WebMidi.prototype._singleton=this,this._inputs=[],this._outputs=[],this._userHandlers={},this._stateChangeQueue=[],this._processingStateChange=!1,this._midiInterfaceEvents=[\"connected\",\"disconnected\"],this._notes=[\"C\",\"C#\",\"D\",\"D#\",\"E\",\"F\",\"F#\",\"G\",\"G#\",\"A\",\"A#\",\"B\"],this._semitones={C:0,D:2,E:4,F:5,G:7,A:9,B:11},Object.defineProperties(this,{MIDI_SYSTEM_MESSAGES:{value:{sysex:240,timecode:241,songposition:242,songselect:243,tuningrequest:246,sysexend:247,clock:248,start:250,\"continue\":251,stop:252,activesensing:254,reset:255,midimessage:0,unknownsystemmessage:-1},writable:!1,enumerable:!0,configurable:!1},MIDI_CHANNEL_MESSAGES:{value:{noteoff:8,noteon:9,keyaftertouch:10,controlchange:11,channelmode:11,programchange:12,channelaftertouch:13,pitchbend:14},writable:!1,enumerable:!0,configurable:!1},MIDI_REGISTERED_PARAMETER:{value:{pitchbendrange:[0,0],channelfinetuning:[0,1],channelcoarsetuning:[0,2],tuningprogram:[0,3],tuningbank:[0,4],modulationrange:[0,5],azimuthangle:[61,0],elevationangle:[61,1],gain:[61,2],distanceratio:[61,3],maximumdistance:[61,4],maximumdistancegain:[61,5],referencedistanceratio:[61,6],panspreadangle:[61,7],rollangle:[61,8]},writable:!1,enumerable:!0,configurable:!1},MIDI_CONTROL_CHANGE_MESSAGES:{value:{bankselectcoarse:0,modulationwheelcoarse:1,breathcontrollercoarse:2,footcontrollercoarse:4,portamentotimecoarse:5,dataentrycoarse:6,volumecoarse:7,balancecoarse:8,pancoarse:10,expressioncoarse:11,effectcontrol1coarse:12,effectcontrol2coarse:13,generalpurposeslider1:16,generalpurposeslider2:17,generalpurposeslider3:18,generalpurposeslider4:19,bankselectfine:32,modulationwheelfine:33,breathcontrollerfine:34,footcontrollerfine:36,portamentotimefine:37,dataentryfine:38,volumefine:39,balancefine:40,panfine:42,expressionfine:43,effectcontrol1fine:44,effectcontrol2fine:45,holdpedal:64,portamento:65,sustenutopedal:66,softpedal:67,legatopedal:68,hold2pedal:69,soundvariation:70,resonance:71,soundreleasetime:72,soundattacktime:73,brightness:74,soundcontrol6:75,soundcontrol7:76,soundcontrol8:77,soundcontrol9:78,soundcontrol10:79,generalpurposebutton1:80,generalpurposebutton2:81,generalpurposebutton3:82,generalpurposebutton4:83,reverblevel:91,tremololevel:92,choruslevel:93,celestelevel:94,phaserlevel:95,databuttonincrement:96,databuttondecrement:97,nonregisteredparametercoarse:98,nonregisteredparameterfine:99,registeredparametercoarse:100,registeredparameterfine:101},writable:!1,enumerable:!0,configurable:!1},MIDI_CHANNEL_MODE_MESSAGES:{value:{allsoundoff:120,resetallcontrollers:121,localcontrol:122,allnotesoff:123,omnimodeoff:124,omnimodeon:125,monomodeon:126,polymodeon:127},writable:!1,enumerable:!0,configurable:!1},octaveOffset:{value:0,writable:!0,enumerable:!0,configurable:!1}}),Object.defineProperties(this,{supported:{enumerable:!0,get:function(){return\"requestMIDIAccess\"in navigator}},enabled:{enumerable:!0,get:function(){return void 0!==this[\"interface\"]}.bind(this)},inputs:{enumerable:!0,get:function(){return this._inputs}.bind(this)},outputs:{enumerable:!0,get:function(){return this._outputs}.bind(this)},sysexEnabled:{enumerable:!0,get:function(){return!(!this[\"interface\"]||!this[\"interface\"].sysexEnabled)}.bind(this)},time:{enumerable:!0,get:function(){return performance.now()}}})}function Input(midiInput){var that=this;this._userHandlers={channel:{},system:{}},this._midiInput=midiInput,Object.defineProperties(this,{connection:{enumerable:!0,get:function(){return that._midiInput.connection}},id:{enumerable:!0,get:function(){return that._midiInput.id}},manufacturer:{enumerable:!0,get:function(){return that._midiInput.manufacturer}},name:{enumerable:!0,get:function(){return that._midiInput.name}},state:{enumerable:!0,get:function(){return that._midiInput.state}},type:{enumerable:!0,get:function(){return that._midiInput.type}}}),this._initializeUserHandlers(),this._midiInput.onmidimessage=this._onMidiMessage.bind(this)}function Output(midiOutput){var that=this;this._midiOutput=midiOutput,Object.defineProperties(this,{connection:{enumerable:!0,get:function(){return that._midiOutput.connection}},id:{enumerable:!0,get:function(){return that._midiOutput.id}},manufacturer:{enumerable:!0,get:function(){return that._midiOutput.manufacturer}},name:{enumerable:!0,get:function(){return that._midiOutput.name}},state:{enumerable:!0,get:function(){return that._midiOutput.state}},type:{enumerable:!0,get:function(){return that._midiOutput.type}}})}var wm=new WebMidi;WebMidi.prototype.enable=function(callback,sysex){return this.enabled?void 0:this.supported?void navigator.requestMIDIAccess({sysex:sysex}).then(function(midiAccess){function onPortsOpen(){clearTimeout(promiseTimeout),this._updateInputsAndOutputs(),this[\"interface\"].onstatechange=this._onInterfaceStateChange.bind(this),\"function\"==typeof callback&&callback.call(this),events.forEach(function(event){this._onInterfaceStateChange(event)}.bind(this))}var promiseTimeout,events=[],promises=[];this[\"interface\"]=midiAccess,this._resetInterfaceUserHandlers(),this[\"interface\"].onstatechange=function(e){events.push(e)};for(var inputs=midiAccess.inputs.values(),input=inputs.next();input&&!input.done;input=inputs.next())promises.push(input.value.open());for(var outputs=midiAccess.outputs.values(),output=outputs.next();output&&!output.done;output=outputs.next())promises.push(output.value.open());promiseTimeout=setTimeout(onPortsOpen.bind(this),200),Promise&&Promise.all(promises)[\"catch\"](function(err){}).then(onPortsOpen.bind(this))}.bind(this),function(err){\"function\"==typeof callback&&callback.call(this,err)}.bind(this)):void(\"function\"==typeof callback&&callback(new Error(\"The Web MIDI API is not supported by your browser.\")))},WebMidi.prototype.disable=function(){if(!this.supported)throw new Error(\"The Web MIDI API is not supported by your browser.\");this[\"interface\"]&&(this[\"interface\"].onstatechange=void 0),this[\"interface\"]=void 0,this._inputs=[],this._outputs=[],this._resetInterfaceUserHandlers()},WebMidi.prototype.addListener=function(type,listener){if(!this.enabled)throw new Error(\"WebMidi must be enabled before adding event listeners.\");if(\"function\"!=typeof listener)throw new TypeError(\"The 'listener' parameter must be a function.\");if(!(this._midiInterfaceEvents.indexOf(type)>=0))throw new TypeError(\"The specified event type is not supported.\");return this._userHandlers[type].push(listener),this},WebMidi.prototype.hasListener=function(type,listener){if(!this.enabled)throw new Error(\"WebMidi must be enabled before checking event listeners.\");if(\"function\"!=typeof listener)throw new TypeError(\"The 'listener' parameter must be a function.\");if(!(this._midiInterfaceEvents.indexOf(type)>=0))throw new TypeError(\"The specified event type is not supported.\");for(var o=0;o<this._userHandlers[type].length;o++)if(this._userHandlers[type][o]===listener)return!0;return!1},WebMidi.prototype.removeListener=function(type,listener){if(!this.enabled)throw new Error(\"WebMidi must be enabled before removing event listeners.\");if(void 0!==listener&&\"function\"!=typeof listener)throw new TypeError(\"The 'listener' parameter must be a function.\");if(this._midiInterfaceEvents.indexOf(type)>=0)if(listener)for(var o=0;o<this._userHandlers[type].length;o++)this._userHandlers[type][o]===listener&&this._userHandlers[type].splice(o,1);else this._userHandlers[type]=[];else{if(void 0!==type)throw new TypeError(\"The specified event type is not supported.\");this._resetInterfaceUserHandlers()}return this},WebMidi.prototype.toMIDIChannels=function(channel){var channels;return channels=\"all\"===channel||void 0===channel?[\"all\"]:Array.isArray(channel)?channel:[channel],channels.indexOf(\"all\")>-1&&(channels=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]),channels.map(function(ch){return parseInt(ch)}).filter(function(ch){return ch>=1&&16>=ch})},WebMidi.prototype.getInputById=function(id){if(!this.enabled)throw new Error(\"WebMidi is not enabled.\");for(var i=0;i<this.inputs.length;i++)if(this.inputs[i].id===id)return this.inputs[i];return!1},WebMidi.prototype.getOutputById=function(id){if(!this.enabled)throw new Error(\"WebMidi is not enabled.\");for(var i=0;i<this.outputs.length;i++)if(this.outputs[i].id===id)return this.outputs[i];return!1},WebMidi.prototype.getInputByName=function(name){if(!this.enabled)throw new Error(\"WebMidi is not enabled.\");for(var i=0;i<this.inputs.length;i++)if(~this.inputs[i].name.indexOf(name))return this.inputs[i];return!1},WebMidi.prototype.getOctave=function(number){return null!=number&&number>=0&&127>=number?Math.floor(Math.floor(number)/12-1)+Math.floor(wm.octaveOffset):void 0},WebMidi.prototype.getOutputByName=function(name){if(!this.enabled)throw new Error(\"WebMidi is not enabled.\");for(var i=0;i<this.outputs.length;i++)if(~this.outputs[i].name.indexOf(name))return this.outputs[i];return!1},WebMidi.prototype.guessNoteNumber=function(input){var output=!1;if(input&&input.toFixed&&input>=0&&127>=input?output=Math.round(input):parseInt(input)>=0&&parseInt(input)<=127?output=parseInt(input):(\"string\"==typeof input||input instanceof String)&&(output=this.noteNameToNumber(input)),output===!1)throw new Error(\"Invalid input value (\"+input+\").\");return output},WebMidi.prototype.noteNameToNumber=function(name){\"string\"!=typeof name&&(name=\"\");var matches=name.match(/([CDEFGAB])(#{0,2}|b{0,2})(-?\\d+)/i);if(!matches)throw new RangeError(\"Invalid note name.\");var semitones=wm._semitones[matches[1].toUpperCase()],octave=parseInt(matches[3]),result=12*(octave+1-Math.floor(wm.octaveOffset))+semitones;if(matches[2].toLowerCase().indexOf(\"b\")>-1?result-=matches[2].length:matches[2].toLowerCase().indexOf(\"#\")>-1&&(result+=matches[2].length),0>result||result>127)throw new RangeError(\"Invalid note name or note outside valid range.\");return result},WebMidi.prototype._updateInputsAndOutputs=function(){this._updateInputs(),this._updateOutputs()},WebMidi.prototype._updateInputs=function(){for(var i=0;i<this._inputs.length;i++){for(var remove=!0,updated=this[\"interface\"].inputs.values(),input=updated.next();input&&!input.done;input=updated.next())if(this._inputs[i]._midiInput===input.value){remove=!1;break}remove&&this._inputs.splice(i,1)}this[\"interface\"]&&this[\"interface\"].inputs.forEach(function(nInput){for(var add=!0,j=0;j<this._inputs.length;j++)this._inputs[j]._midiInput===nInput&&(add=!1);add&&this._inputs.push(new Input(nInput))}.bind(this))},WebMidi.prototype._updateOutputs=function(){for(var i=0;i<this._outputs.length;i++){for(var remove=!0,updated=this[\"interface\"].outputs.values(),output=updated.next();output&&!output.done;output=updated.next())if(this._outputs[i]._midiOutput===output.value){remove=!1;break}remove&&this._outputs.splice(i,1)}this[\"interface\"]&&this[\"interface\"].outputs.forEach(function(nOutput){for(var add=!0,j=0;j<this._outputs.length;j++)this._outputs[j]._midiOutput===nOutput&&(add=!1);add&&this._outputs.push(new Output(nOutput))}.bind(this))},WebMidi.prototype._onInterfaceStateChange=function(e){this._updateInputsAndOutputs();var event={timestamp:e.timeStamp,type:e.port.state};this[\"interface\"]&&\"connected\"===e.port.state?\"output\"===e.port.type?event.port=this.getOutputById(e.port.id):\"input\"===e.port.type&&(event.port=this.getInputById(e.port.id)):event.port={connection:\"closed\",id:e.port.id,manufacturer:e.port.manufacturer,name:e.port.name,state:e.port.state,type:e.port.type},this._userHandlers[e.port.state].forEach(function(handler){handler(event)})},WebMidi.prototype._resetInterfaceUserHandlers=function(){for(var i=0;i<this._midiInterfaceEvents.length;i++)this._userHandlers[this._midiInterfaceEvents[i]]=[]},Input.prototype.addListener=function(type,channel,listener){var that=this;if(void 0===channel&&(channel=\"all\"),Array.isArray(channel)||(channel=[channel]),channel.forEach(function(item){if(\"all\"!==item&&!(item>=1&&16>=item))throw new RangeError(\"The 'channel' parameter is invalid.\")}),\"function\"!=typeof listener)throw new TypeError(\"The 'listener' parameter must be a function.\");if(void 0!==wm.MIDI_SYSTEM_MESSAGES[type])this._userHandlers.system[type]||(this._userHandlers.system[type]=[]),this._userHandlers.system[type].push(listener);else{if(void 0===wm.MIDI_CHANNEL_MESSAGES[type])throw new TypeError(\"The specified event type is not supported.\");if(channel.indexOf(\"all\")>-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}this._userHandlers.channel[type]||(this._userHandlers.channel[type]=[]),channel.forEach(function(ch){that._userHandlers.channel[type][ch]||(that._userHandlers.channel[type][ch]=[]),that._userHandlers.channel[type][ch].push(listener)})}return this},Input.prototype.on=Input.prototype.addListener,Input.prototype.hasListener=function(type,channel,listener){var that=this;if(\"function\"!=typeof listener)throw new TypeError(\"The 'listener' parameter must be a function.\");if(void 0===channel&&(channel=\"all\"),channel.constructor!==Array&&(channel=[channel]),void 0!==wm.MIDI_SYSTEM_MESSAGES[type]){for(var o=0;o<this._userHandlers.system[type].length;o++)if(this._userHandlers.system[type][o]===listener)return!0}else if(void 0!==wm.MIDI_CHANNEL_MESSAGES[type]){if(channel.indexOf(\"all\")>-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}return this._userHandlers.channel[type]?channel.every(function(chNum){var listeners=that._userHandlers.channel[type][chNum];return listeners&&listeners.indexOf(listener)>-1}):!1}return!1},Input.prototype.removeListener=function(type,channel,listener){var that=this;if(void 0!==listener&&\"function\"!=typeof listener)throw new TypeError(\"The 'listener' parameter must be a function.\");if(void 0===channel&&(channel=\"all\"),channel.constructor!==Array&&(channel=[channel]),void 0!==wm.MIDI_SYSTEM_MESSAGES[type])if(void 0===listener)this._userHandlers.system[type]=[];else for(var o=0;o<this._userHandlers.system[type].length;o++)this._userHandlers.system[type][o]===listener&&this._userHandlers.system[type].splice(o,1);else if(void 0!==wm.MIDI_CHANNEL_MESSAGES[type]){if(channel.indexOf(\"all\")>-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}if(!this._userHandlers.channel[type])return this;channel.forEach(function(chNum){var listeners=that._userHandlers.channel[type][chNum];if(listeners)if(void 0===listener)that._userHandlers.channel[type][chNum]=[];else for(var l=0;l<listeners.length;l++)listeners[l]===listener&&listeners.splice(l,1)})}else{if(void 0!==type)throw new TypeError(\"The specified event type is not supported.\");this._initializeUserHandlers()}return this},Input.prototype._initializeUserHandlers=function(){for(var prop1 in wm.MIDI_CHANNEL_MESSAGES)wm.MIDI_CHANNEL_MESSAGES.hasOwnProperty(prop1)&&(this._userHandlers.channel[prop1]={});for(var prop2 in wm.MIDI_SYSTEM_MESSAGES)wm.MIDI_SYSTEM_MESSAGES.hasOwnProperty(prop2)&&(this._userHandlers.system[prop2]=[])},Input.prototype._onMidiMessage=function(e){if(this._userHandlers.system.midimessage.length>0){var event={target:this,data:e.data,timestamp:e.timeStamp,type:\"midimessage\"};this._userHandlers.system.midimessage.forEach(function(callback){callback(event)})}e.data[0]<240?this._parseChannelEvent(e):e.data[0]<=255&&this._parseSystemEvent(e)},Input.prototype._parseChannelEvent=function(e){var data1,data2,command=e.data[0]>>4,channel=(15&e.data[0])+1;e.data.length>1&&(data1=e.data[1],data2=e.data.length>2?e.data[2]:void 0);var event={target:this,data:e.data,timestamp:e.timeStamp,channel:channel};command===wm.MIDI_CHANNEL_MESSAGES.noteoff||command===wm.MIDI_CHANNEL_MESSAGES.noteon&&0===data2?(event.type=\"noteoff\",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.velocity=data2/127,event.rawVelocity=data2):command===wm.MIDI_CHANNEL_MESSAGES.noteon?(event.type=\"noteon\",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.velocity=data2/127,event.rawVelocity=data2):command===wm.MIDI_CHANNEL_MESSAGES.keyaftertouch?(event.type=\"keyaftertouch\",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.value=data2/127):command===wm.MIDI_CHANNEL_MESSAGES.controlchange&&data1>=0&&119>=data1?(event.type=\"controlchange\",event.controller={number:data1,name:this.getCcNameByNumber(data1)},event.value=data2):command===wm.MIDI_CHANNEL_MESSAGES.channelmode&&data1>=120&&127>=data1?(event.type=\"channelmode\",event.controller={number:data1,name:this.getChannelModeByNumber(data1)},event.value=data2):command===wm.MIDI_CHANNEL_MESSAGES.programchange?(event.type=\"programchange\",event.value=data1):command===wm.MIDI_CHANNEL_MESSAGES.channelaftertouch?(event.type=\"channelaftertouch\",event.value=data1/127):command===wm.MIDI_CHANNEL_MESSAGES.pitchbend?(event.type=\"pitchbend\",event.value=((data2<<7)+data1-8192)/8192):event.type=\"unknownchannelmessage\",this._userHandlers.channel[event.type]&&this._userHandlers.channel[event.type][channel]&&this._userHandlers.channel[event.type][channel].forEach(function(callback){callback(event)})},Input.prototype.getCcNameByNumber=function(number){if(number=Math.floor(number),!(number>=0&&119>=number))throw new RangeError(\"The control change number must be between 0 and 119.\");for(var cc in wm.MIDI_CONTROL_CHANGE_MESSAGES)if(wm.MIDI_CONTROL_CHANGE_MESSAGES.hasOwnProperty(cc)&&number===wm.MIDI_CONTROL_CHANGE_MESSAGES[cc])return cc;return void 0},Input.prototype.getChannelModeByNumber=function(number){if(number=Math.floor(number),!(number>=120&&status<=127))throw new RangeError(\"The control change number must be between 120 and 127.\");for(var cm in wm.MIDI_CHANNEL_MODE_MESSAGES)if(wm.MIDI_CHANNEL_MODE_MESSAGES.hasOwnProperty(cm)&&number===wm.MIDI_CHANNEL_MODE_MESSAGES[cm])return cm},Input.prototype._parseSystemEvent=function(e){var command=e.data[0],event={target:this,data:e.data,timestamp:e.timeStamp};command===wm.MIDI_SYSTEM_MESSAGES.sysex?event.type=\"sysex\":command===wm.MIDI_SYSTEM_MESSAGES.timecode?event.type=\"timecode\":command===wm.MIDI_SYSTEM_MESSAGES.songposition?event.type=\"songposition\":command===wm.MIDI_SYSTEM_MESSAGES.songselect?(event.type=\"songselect\",event.song=e.data[1]):command===wm.MIDI_SYSTEM_MESSAGES.tuningrequest?event.type=\"tuningrequest\":command===wm.MIDI_SYSTEM_MESSAGES.clock?event.type=\"clock\":command===wm.MIDI_SYSTEM_MESSAGES.start?event.type=\"start\":command===wm.MIDI_SYSTEM_MESSAGES[\"continue\"]?event.type=\"continue\":command===wm.MIDI_SYSTEM_MESSAGES.stop?event.type=\"stop\":command===wm.MIDI_SYSTEM_MESSAGES.activesensing?event.type=\"activesensing\":command===wm.MIDI_SYSTEM_MESSAGES.reset?event.type=\"reset\":event.type=\"unknownsystemmessage\",this._userHandlers.system[event.type]&&this._userHandlers.system[event.type].forEach(function(callback){callback(event)})},Output.prototype.send=function(status,data,timestamp){if(!(status>=128&&255>=status))throw new RangeError(\"The status byte must be an integer between 128 (0x80) and 255 (0xFF).\");void 0===data&&(data=[]),Array.isArray(data)||(data=[data]);var message=[];return data.forEach(function(item,index){var parsed=Math.floor(item);if(!(parsed>=0&&255>=parsed))throw new RangeError(\"Data bytes must be integers between 0 (0x00) and 255 (0xFF).\");message.push(parsed)}),this._midiOutput.send([status].concat(message),parseFloat(timestamp)||0),this},Output.prototype.sendSysex=function(manufacturer,data,options){if(!wm.sysexEnabled)throw new Error(\"Sysex message support must first be activated.\");return options=options||{},manufacturer=[].concat(manufacturer),data.forEach(function(item){if(0>item||item>127)throw new RangeError(\"The data bytes of a sysex message must be integers between 0 (0x00) and 127 (0x7F).\")}),data=manufacturer.concat(data,wm.MIDI_SYSTEM_MESSAGES.sysexend),this.send(wm.MIDI_SYSTEM_MESSAGES.sysex,data,this._parseTimeParameter(options.time)),this},Output.prototype.sendTimecodeQuarterFrame=function(value,options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.timecode,value,this._parseTimeParameter(options.time)),this},Output.prototype.sendSongPosition=function(value,options){value=Math.floor(value)||0,options=options||{};var msb=value>>7&127,lsb=127&value;return this.send(wm.MIDI_SYSTEM_MESSAGES.songposition,[msb,lsb],this._parseTimeParameter(options.time)),this},Output.prototype.sendSongSelect=function(value,options){if(value=Math.floor(value),options=options||{},!(value>=0&&127>=value))throw new RangeError(\"The song number must be between 0 and 127.\");return this.send(wm.MIDI_SYSTEM_MESSAGES.songselect,[value],this._parseTimeParameter(options.time)),this},Output.prototype.sendTuningRequest=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.tuningrequest,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendClock=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.clock,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendStart=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.start,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendContinue=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES[\"continue\"],void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendStop=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.stop,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendActiveSensing=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.activesensing,[],this._parseTimeParameter(options.time)),this},Output.prototype.sendReset=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.reset,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.stopNote=function(note,channel,options){if(\"all\"===note)return this.sendChannelMode(\"allnotesoff\",0,channel,options);var nVelocity=64;return options=options||{},options.rawVelocity?!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=127&&(nVelocity=options.velocity):!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=1&&(nVelocity=127*options.velocity),this._convertNoteToArray(note).forEach(function(item){wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteoff<<4)+(ch-1),[item,Math.round(nVelocity)],this._parseTimeParameter(options.time))}.bind(this))}.bind(this)),this},Output.prototype.playNote=function(note,channel,options){var nVelocity=64;if(options=options||{},options.rawVelocity?!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=127&&(nVelocity=options.velocity):!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=1&&(nVelocity=127*options.velocity),options.time=this._parseTimeParameter(options.time),this._convertNoteToArray(note).forEach(function(item){wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteon<<4)+(ch-1),[item,Math.round(nVelocity)],options.time)}.bind(this))}.bind(this)),!isNaN(options.duration)){options.duration<=0&&(options.duration=0);var nRelease=64;options.rawVelocity?!isNaN(options.release)&&options.release>=0&&options.release<=127&&(nRelease=options.release):!isNaN(options.release)&&options.release>=0&&options.release<=1&&(nRelease=127*options.release),this._convertNoteToArray(note).forEach(function(item){wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteoff<<4)+(ch-1),[item,Math.round(nRelease)],(options.time||wm.time)+options.duration)}.bind(this))}.bind(this))}return this},Output.prototype.sendKeyAftertouch=function(note,channel,pressure,options){var that=this;if(options=options||{},1>channel||channel>16)throw new RangeError(\"The channel must be between 1 and 16.\");(isNaN(pressure)||0>pressure||pressure>1)&&(pressure=.5);var nPressure=Math.round(127*pressure);return this._convertNoteToArray(note).forEach(function(item){wm.toMIDIChannels(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.keyaftertouch<<4)+(ch-1),[item,nPressure],that._parseTimeParameter(options.time))})}),this},Output.prototype.sendControlChange=function(controller,value,channel,options){if(options=options||{},\"string\"==typeof controller){if(controller=wm.MIDI_CONTROL_CHANGE_MESSAGES[controller],!controller)throw new TypeError(\"Invalid controller name.\")}else if(controller=Math.floor(controller),!(controller>=0&&119>=controller))throw new RangeError(\"Controller numbers must be between 0 and 119.\");if(value=Math.floor(value)||0,!(value>=0&&127>=value))throw new RangeError(\"Controller value must be between 0 and 127.\");return wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.controlchange<<4)+(ch-1),[controller,value],this._parseTimeParameter(options.time))}.bind(this)),this},Output.prototype._selectRegisteredParameter=function(parameter,channel,time){var that=this;if(parameter[0]=Math.floor(parameter[0]),!(parameter[0]>=0&¶meter[0]<=127))throw new RangeError(\"The control65 value must be between 0 and 127\");if(parameter[1]=Math.floor(parameter[1]),!(parameter[1]>=0&¶meter[1]<=127))throw new RangeError(\"The control64 value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(101,parameter[0],channel,{time:time}),that.sendControlChange(100,parameter[1],channel,{time:time})}),this},Output.prototype._selectNonRegisteredParameter=function(parameter,channel,time){var that=this;if(parameter[0]=Math.floor(parameter[0]),!(parameter[0]>=0&¶meter[0]<=127))throw new RangeError(\"The control63 value must be between 0 and 127\");if(parameter[1]=Math.floor(parameter[1]),!(parameter[1]>=0&¶meter[1]<=127))throw new RangeError(\"The control62 value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(99,parameter[0],channel,{time:time}),that.sendControlChange(98,parameter[1],channel,{time:time})}),this},Output.prototype._setCurrentRegisteredParameter=function(data,channel,time){var that=this;if(data=[].concat(data),data[0]=Math.floor(data[0]),!(data[0]>=0&&data[0]<=127))throw new RangeError(\"The msb value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(6,data[0],channel,{time:time})}),data[1]=Math.floor(data[1]),data[1]>=0&&data[1]<=127&&wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(38,data[1],channel,{time:time})}),this},Output.prototype._deselectRegisteredParameter=function(channel,time){var that=this;return wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(101,127,channel,{time:time}),that.sendControlChange(100,127,channel,{time:time})}),this},Output.prototype.setRegisteredParameter=function(parameter,data,channel,options){var that=this;if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new Error(\"The specified parameter is not available.\");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return wm.toMIDIChannels(channel).forEach(function(ch){that._selectRegisteredParameter(parameter,channel,options.time),that._setCurrentRegisteredParameter(data,channel,options.time),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.setNonRegisteredParameter=function(parameter,data,channel,options){var that=this;if(options=options||{},!(parameter[0]>=0&¶meter[0]<=127&¶meter[1]>=0&¶meter[1]<=127))throw new Error(\"Position 0 and 1 of the 2-position parameter array must both be between 0 and 127.\");return data=[].concat(data),wm.toMIDIChannels(channel).forEach(function(ch){that._selectNonRegisteredParameter(parameter,channel,options.time),that._setCurrentRegisteredParameter(data,channel,options.time),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.incrementRegisteredParameter=function(parameter,channel,options){var that=this;if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new Error(\"The specified parameter is not available.\");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return wm.toMIDIChannels(channel).forEach(function(ch){that._selectRegisteredParameter(parameter,channel,options.time),that.sendControlChange(96,0,channel,{time:options.time}),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.decrementRegisteredParameter=function(parameter,channel,options){if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new TypeError(\"The specified parameter is not available.\");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return wm.toMIDIChannels(channel).forEach(function(ch){this._selectRegisteredParameter(parameter,channel,options.time),this.sendControlChange(97,0,channel,{time:options.time}),this._deselectRegisteredParameter(channel,options.time)}.bind(this)),this},Output.prototype.setPitchBendRange=function(semitones,cents,channel,options){var that=this;if(options=options||{},semitones=Math.floor(semitones)||0,!(semitones>=0&&127>=semitones))throw new RangeError(\"The semitones value must be between 0 and 127\");if(cents=Math.floor(cents)||0,!(cents>=0&&127>=cents))throw new RangeError(\"The cents value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter(\"pitchbendrange\",[semitones,cents],channel,{time:options.time})}),this},Output.prototype.setModulationRange=function(semitones,cents,channel,options){var that=this;if(options=options||{},semitones=Math.floor(semitones)||0,!(semitones>=0&&127>=semitones))throw new RangeError(\"The semitones value must be between 0 and 127\");if(cents=Math.floor(cents)||0,!(cents>=0&&127>=cents))throw new RangeError(\"The cents value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter(\"modulationrange\",[semitones,cents],channel,{time:options.time})}),this},Output.prototype.setMasterTuning=function(value,channel,options){var that=this;if(options=options||{},value=parseFloat(value)||0,-65>=value||value>=64)throw new RangeError(\"The value must be a decimal number larger than -65 and smaller than 64.\");var coarse=Math.floor(value)+64,fine=value-Math.floor(value);fine=Math.round((fine+1)/2*16383);var msb=fine>>7&127,lsb=127&fine;return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter(\"channelcoarsetuning\",coarse,channel,{time:options.time}),that.setRegisteredParameter(\"channelfinetuning\",[msb,lsb],channel,{time:options.time})}),this},Output.prototype.setTuningProgram=function(value,channel,options){var that=this;if(options=options||{},value=Math.floor(value),!(value>=0&&127>=value))throw new RangeError(\"The program value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter(\"tuningprogram\",value,channel,{time:options.time})}),this},Output.prototype.setTuningBank=function(value,channel,options){var that=this;if(options=options||{},value=Math.floor(value)||0,!(value>=0&&127>=value))throw new RangeError(\"The bank value must be between 0 and 127\");return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter(\"tuningbank\",value,channel,{time:options.time})}),this},Output.prototype.sendChannelMode=function(command,value,channel,options){if(options=options||{},\"string\"==typeof command){if(command=wm.MIDI_CHANNEL_MODE_MESSAGES[command],!command)throw new TypeError(\"Invalid channel mode message name.\")}else if(command=Math.floor(command),!(command>=120&&127>=command))throw new RangeError(\"Channel mode numerical identifiers must be between 120 and 127.\");if(value=Math.floor(value)||0,0>value||value>127)throw new RangeError(\"Value must be an integer between 0 and 127.\");return wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.channelmode<<4)+(ch-1),[command,value],this._parseTimeParameter(options.time))}.bind(this)),this},Output.prototype.sendProgramChange=function(program,channel,options){\nvar that=this;if(options=options||{},program=Math.floor(program),isNaN(program)||0>program||program>127)throw new RangeError(\"Program numbers must be between 0 and 127.\");return wm.toMIDIChannels(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.programchange<<4)+(ch-1),[program],that._parseTimeParameter(options.time))}),this},Output.prototype.sendChannelAftertouch=function(pressure,channel,options){var that=this;options=options||{},pressure=parseFloat(pressure),(isNaN(pressure)||0>pressure||pressure>1)&&(pressure=.5);var nPressure=Math.round(127*pressure);return wm.toMIDIChannels(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.channelaftertouch<<4)+(ch-1),[nPressure],that._parseTimeParameter(options.time))}),this},Output.prototype.sendPitchBend=function(bend,channel,options){var that=this;if(options=options||{},isNaN(bend)||-1>bend||bend>1)throw new RangeError(\"Pitch bend value must be between -1 and 1.\");var nLevel=Math.round((bend+1)/2*16383),msb=nLevel>>7&127,lsb=127&nLevel;return wm.toMIDIChannels(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.pitchbend<<4)+(ch-1),[lsb,msb],that._parseTimeParameter(options.time))}),this},Output.prototype._parseTimeParameter=function(time){var parsed,value;return\"string\"==typeof time&&\"+\"===time.substring(0,1)?(parsed=parseFloat(time),parsed&&parsed>0&&(value=wm.time+parsed)):(parsed=parseFloat(time),parsed>wm.time&&(value=parsed)),value},Output.prototype._convertNoteToArray=function(note){var notes=[];return Array.isArray(note)||(note=[note]),note.forEach(function(item){notes.push(wm.guessNoteNumber(item))}),notes},\"function\"==typeof define&&\"object\"==typeof define.amd?define([],function(){return wm}):\"undefined\"!=typeof module&&module.exports?module.exports=wm:scope.WebMidi||(scope.WebMidi=wm)}(this);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/webmidi/webmidi.min.js\n// module id = 155\n// module chunks = 0","module.exports = function() {\r\n\tthrow new Error(\"define cannot be used indirect\");\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/amd-define.js\n// module id = 156\n// module chunks = 0","/* globals __webpack_amd_options__ */\r\nmodule.exports = __webpack_amd_options__;\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/amd-options.js\n// module id = 157\n// module chunks = 0","/* (ignored) */\n\n\n//////////////////\n// WEBPACK FOOTER\n// util (ignored)\n// module id = 158\n// module chunks = 0"],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;A;;;;AChEA;AACA;;;;;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACVA;AACA;AACA;AACA;;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AC5vDA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACfA;AACA;AACA;AACA;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC5DA;AACA;AACA;AACA;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACnLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC1EA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACtBA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACnBA;AACA;AACA;;;;;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC7zvBA;;;;;;ACAA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACtLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AC3GA;AACA;AACA;AACA;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACtBA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;AACA;AACA;AACA;;;;;;ACHA;;;;;;ACAA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACRA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC7SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AC5NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC/hBA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC9HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACh5SA;;;;;;ACAA;;;;;;ACAA;AACA;AACA;;;;;;ACFA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AChBA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1EA;AACA;AACA;AACA;AACA;;;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACt6BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACrLA;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC5NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACpVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACzKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACzLA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACjHA;AACA;AACA;;;;;;ACFA;AACA;AACA;;;;;;ACFA;AACA;AACA;;;;;;ACFA;AACA;;;;;;ACDA;AACA;;;;;;ACDA;AACA;;;;;;ACDA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;;;;;;ACFA;;;;;;ACAA;AACA;AACA;AACA;AACA;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACfA;AACA;AACA;AACA;AACA;;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACZA;AACA;AACA;;;;;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACnEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACPA;AACA;AACA;AACA;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC1SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC1OA;;;;;;ACAA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACxtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;;;;;;;AC3LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACnFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;ACtgCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AChMA;;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC/DA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACzLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AC9HA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACzkBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC/BA;AACA;AACA;;;;;;;ACFA;AACA;;;;;;;;ACDA;;;A","sourceRoot":""}
\ No newline at end of file diff --git a/client/index.js b/client/index.js index 527fb64..2c9716a 100644 --- a/client/index.js +++ b/client/index.js @@ -125,13 +125,13 @@ function play_mass_shootings(i, bounds, diff, note_time, channel="all", exportin timings = [64, 64] break case 3: - midi_notes.push(play_note( norm(notes[0], min, max) * nx.multiply.value, 43, channel, exporting, mass_rest)) + midi_notes.push(play_note( norm(notes[0], min, max) * nx.multiply.value, 43, channel, exporting, mass_rest, 0)) midi_notes.push(play_note( norm(notes[1], min, max) * nx.multiply.value, 43, channel, exporting, 0, 43)) midi_notes.push(play_note( norm(notes[2], min, max) * nx.multiply.value, 42, channel, exporting, 0, 85)) timings = [43, 43 ,42] break case 4: - midi_notes.push(play_note( norm(notes[0], min, max) * nx.multiply.value, 32, channel, exporting, mass_rest)) + midi_notes.push(play_note( norm(notes[0], min, max) * nx.multiply.value, 32, channel, exporting, mass_rest, 0)) midi_notes.push(play_note( norm(notes[1], min, max) * nx.multiply.value, 32, channel, exporting, 0, 32)) midi_notes.push(play_note( norm(notes[2], min, max) * nx.multiply.value, 32, channel, exporting, 0, 64)) midi_notes.push(play_note( norm(notes[3], min, max) * nx.multiply.value, 32, channel, exporting, 0, 96)) diff --git a/client/lib/midi.js b/client/lib/midi.js index 3b07cb0..d51aeff 100644 --- a/client/lib/midi.js +++ b/client/lib/midi.js @@ -71,7 +71,10 @@ export function play_note(index, duration, channel="all", exporting=false, rest= const note = Tone.Frequency(Math.floor(midi_note), "midi").toNote() const defer_time = 30000 / Tone.Transport.bpm.value * defer / 128 console.log(defer, defer_time) - if (exporting || midiDevice) { + if (exporting) { + return note + } + if (midiDevice) { duration = duration || 60000 / Tone.Transport.bpm.value if (! exporting) { if (defer) { @@ -157,9 +160,13 @@ export function export_pattern_as_midi(datasetName, bounds, diff, tempo, timingI // note_time = timing // } // midi_track.addEvent(new MidiWriter.NoteEvent({ pitch: notes, duration: 't' + note_time })) - console.log(i, notes, timings) + console.log(i, notes, timings, wait) for (let j = 0; j < notes.length; j++) { - midi_track.addEvent(new MidiWriter.NoteEvent({ pitch: notes[j], duration: 't' + timings[j], wait })) + midi_track.addEvent(new MidiWriter.NoteEvent({ + pitch: notes[j], + duration: 't' + timings[j], + wait: (j === 0) ? wait : 0, + })) } } const writer = new MidiWriter.Writer([midi_track]) diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..9b7a3bb --- /dev/null +++ b/dist/index.js @@ -0,0 +1,46284 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 80); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +var core = module.exports = {version: '2.4.0'}; +if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +var store = __webpack_require__(40)('wks') + , uid = __webpack_require__(29) + , Symbol = __webpack_require__(2).Symbol + , USE_SYMBOL = typeof Symbol == 'function'; + +var $exports = module.exports = function(name){ + return store[name] || (store[name] = + USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); +}; + +$exports.store = store; + +/***/ }), +/* 2 */ +/***/ (function(module, exports) { + +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +var global = module.exports = typeof window != 'undefined' && window.Math == Math + ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); +if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(global) {/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org> + * @license MIT + */ +/* eslint-disable no-proto */ + + + +var base64 = __webpack_require__(92) +var ieee754 = __webpack_require__(139) +var isArray = __webpack_require__(71) + +exports.Buffer = Buffer +exports.SlowBuffer = SlowBuffer +exports.INSPECT_MAX_BYTES = 50 + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined + ? global.TYPED_ARRAY_SUPPORT + : typedArraySupport() + +/* + * Export kMaxLength after typed array support is determined. + */ +exports.kMaxLength = kMaxLength() + +function typedArraySupport () { + try { + var arr = new Uint8Array(1) + arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} + return arr.foo() === 42 && // typed array instances can be augmented + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + } catch (e) { + return false + } +} + +function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff +} + +function createBuffer (that, length) { + if (kMaxLength() < length) { + throw new RangeError('Invalid typed array length') + } + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = new Uint8Array(length) + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + if (that === null) { + that = new Buffer(length) + } + that.length = length + } + + return that +} + +/** + * The Buffer constructor returns instances of `Uint8Array` that have their + * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of + * `Uint8Array`, so the returned instances will have all the node `Buffer` methods + * and the `Uint8Array` methods. Square bracket notation works as expected -- it + * returns a single octet. + * + * The `Uint8Array` prototype remains unmodified. + */ + +function Buffer (arg, encodingOrOffset, length) { + if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { + return new Buffer(arg, encodingOrOffset, length) + } + + // Common case. + if (typeof arg === 'number') { + if (typeof encodingOrOffset === 'string') { + throw new Error( + 'If encoding is specified then the first argument must be a string' + ) + } + return allocUnsafe(this, arg) + } + return from(this, arg, encodingOrOffset, length) +} + +Buffer.poolSize = 8192 // not used by this implementation + +// TODO: Legacy, not needed anymore. Remove in next major version. +Buffer._augment = function (arr) { + arr.__proto__ = Buffer.prototype + return arr +} + +function from (that, value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number') + } + + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + return fromArrayBuffer(that, value, encodingOrOffset, length) + } + + if (typeof value === 'string') { + return fromString(that, value, encodingOrOffset) + } + + return fromObject(that, value) +} + +/** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + **/ +Buffer.from = function (value, encodingOrOffset, length) { + return from(null, value, encodingOrOffset, length) +} + +if (Buffer.TYPED_ARRAY_SUPPORT) { + Buffer.prototype.__proto__ = Uint8Array.prototype + Buffer.__proto__ = Uint8Array + if (typeof Symbol !== 'undefined' && Symbol.species && + Buffer[Symbol.species] === Buffer) { + // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 + Object.defineProperty(Buffer, Symbol.species, { + value: null, + configurable: true + }) + } +} + +function assertSize (size) { + if (typeof size !== 'number') { + throw new TypeError('"size" argument must be a number') + } else if (size < 0) { + throw new RangeError('"size" argument must not be negative') + } +} + +function alloc (that, size, fill, encoding) { + assertSize(size) + if (size <= 0) { + return createBuffer(that, size) + } + if (fill !== undefined) { + // Only pay attention to encoding if it's a string. This + // prevents accidentally sending in a number that would + // be interpretted as a start offset. + return typeof encoding === 'string' + ? createBuffer(that, size).fill(fill, encoding) + : createBuffer(that, size).fill(fill) + } + return createBuffer(that, size) +} + +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + **/ +Buffer.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) +} + +function allocUnsafe (that, size) { + assertSize(size) + that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < size; ++i) { + that[i] = 0 + } + } + return that +} + +/** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. + * */ +Buffer.allocUnsafe = function (size) { + return allocUnsafe(null, size) +} +/** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ +Buffer.allocUnsafeSlow = function (size) { + return allocUnsafe(null, size) +} + +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8' + } + + if (!Buffer.isEncoding(encoding)) { + throw new TypeError('"encoding" must be a valid string encoding') + } + + var length = byteLength(string, encoding) | 0 + that = createBuffer(that, length) + + var actual = that.write(string, encoding) + + if (actual !== length) { + // Writing a hex string, for example, that contains invalid characters will + // cause everything after the first invalid character to be ignored. (e.g. + // 'abxxcd' will be treated as 'ab') + that = that.slice(0, actual) + } + + return that +} + +function fromArrayLike (that, array) { + var length = array.length < 0 ? 0 : checked(array.length) | 0 + that = createBuffer(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +function fromArrayBuffer (that, array, byteOffset, length) { + array.byteLength // this throws if `array` is not a valid ArrayBuffer + + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('\'offset\' is out of bounds') + } + + if (array.byteLength < byteOffset + (length || 0)) { + throw new RangeError('\'length\' is out of bounds') + } + + if (byteOffset === undefined && length === undefined) { + array = new Uint8Array(array) + } else if (length === undefined) { + array = new Uint8Array(array, byteOffset) + } else { + array = new Uint8Array(array, byteOffset, length) + } + + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = array + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + that = fromArrayLike(that, array) + } + return that +} + +function fromObject (that, obj) { + if (Buffer.isBuffer(obj)) { + var len = checked(obj.length) | 0 + that = createBuffer(that, len) + + if (that.length === 0) { + return that + } + + obj.copy(that, 0, 0, len) + return that + } + + if (obj) { + if ((typeof ArrayBuffer !== 'undefined' && + obj.buffer instanceof ArrayBuffer) || 'length' in obj) { + if (typeof obj.length !== 'number' || isnan(obj.length)) { + return createBuffer(that, 0) + } + return fromArrayLike(that, obj) + } + + if (obj.type === 'Buffer' && isArray(obj.data)) { + return fromArrayLike(that, obj.data) + } + } + + throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') +} + +function checked (length) { + // Note: cannot use `length < kMaxLength()` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 +} + +function SlowBuffer (length) { + if (+length != length) { // eslint-disable-line eqeqeq + length = 0 + } + return Buffer.alloc(+length) +} + +Buffer.isBuffer = function isBuffer (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function compare (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) return 0 + + var x = a.length + var y = b.length + + for (var i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i] + y = b[i] + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'latin1': + case 'binary': + case 'base64': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} + +Buffer.concat = function concat (list, length) { + if (!isArray(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + + if (list.length === 0) { + return Buffer.alloc(0) + } + + var i + if (length === undefined) { + length = 0 + for (i = 0; i < list.length; ++i) { + length += list[i].length + } + } + + var buffer = Buffer.allocUnsafe(length) + var pos = 0 + for (i = 0; i < list.length; ++i) { + var buf = list[i] + if (!Buffer.isBuffer(buf)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + buf.copy(buffer, pos) + pos += buf.length + } + return buffer +} + +function byteLength (string, encoding) { + if (Buffer.isBuffer(string)) { + return string.length + } + if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && + (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { + return string.byteLength + } + if (typeof string !== 'string') { + string = '' + string + } + + var len = string.length + if (len === 0) return 0 + + // Use a for loop to avoid recursion + var loweredCase = false + for (;;) { + switch (encoding) { + case 'ascii': + case 'latin1': + case 'binary': + return len + case 'utf8': + case 'utf-8': + case undefined: + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} +Buffer.byteLength = byteLength + +function slowToString (encoding, start, end) { + var loweredCase = false + + // No need to verify that "this.length <= MAX_UINT32" since it's a read-only + // property of a typed array. + + // This behaves neither like String nor Uint8Array in that we set start/end + // to their upper/lower bounds if the value passed is out of range. + // undefined is handled specially as per ECMA-262 6th Edition, + // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. + if (start === undefined || start < 0) { + start = 0 + } + // Return early if start > this.length. Done here to prevent potential uint32 + // coercion fail below. + if (start > this.length) { + return '' + } + + if (end === undefined || end > this.length) { + end = this.length + } + + if (end <= 0) { + return '' + } + + // Force coersion to uint32. This will also coerce falsey/NaN values to 0. + end >>>= 0 + start >>>= 0 + + if (end <= start) { + return '' + } + + if (!encoding) encoding = 'utf8' + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'latin1': + case 'binary': + return latin1Slice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } + } +} + +// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect +// Buffer instances. +Buffer.prototype._isBuffer = true + +function swap (b, n, m) { + var i = b[n] + b[n] = b[m] + b[m] = i +} + +Buffer.prototype.swap16 = function swap16 () { + var len = this.length + if (len % 2 !== 0) { + throw new RangeError('Buffer size must be a multiple of 16-bits') + } + for (var i = 0; i < len; i += 2) { + swap(this, i, i + 1) + } + return this +} + +Buffer.prototype.swap32 = function swap32 () { + var len = this.length + if (len % 4 !== 0) { + throw new RangeError('Buffer size must be a multiple of 32-bits') + } + for (var i = 0; i < len; i += 4) { + swap(this, i, i + 3) + swap(this, i + 1, i + 2) + } + return this +} + +Buffer.prototype.swap64 = function swap64 () { + var len = this.length + if (len % 8 !== 0) { + throw new RangeError('Buffer size must be a multiple of 64-bits') + } + for (var i = 0; i < len; i += 8) { + swap(this, i, i + 7) + swap(this, i + 1, i + 6) + swap(this, i + 2, i + 5) + swap(this, i + 3, i + 4) + } + return this +} + +Buffer.prototype.toString = function toString () { + var length = this.length | 0 + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) +} + +Buffer.prototype.equals = function equals (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 +} + +Buffer.prototype.inspect = function inspect () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) str += ' ... ' + } + return '<Buffer ' + str + '>' +} + +Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { + if (!Buffer.isBuffer(target)) { + throw new TypeError('Argument must be a Buffer') + } + + if (start === undefined) { + start = 0 + } + if (end === undefined) { + end = target ? target.length : 0 + } + if (thisStart === undefined) { + thisStart = 0 + } + if (thisEnd === undefined) { + thisEnd = this.length + } + + if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { + throw new RangeError('out of range index') + } + + if (thisStart >= thisEnd && start >= end) { + return 0 + } + if (thisStart >= thisEnd) { + return -1 + } + if (start >= end) { + return 1 + } + + start >>>= 0 + end >>>= 0 + thisStart >>>= 0 + thisEnd >>>= 0 + + if (this === target) return 0 + + var x = thisEnd - thisStart + var y = end - start + var len = Math.min(x, y) + + var thisCopy = this.slice(thisStart, thisEnd) + var targetCopy = target.slice(start, end) + + for (var i = 0; i < len; ++i) { + if (thisCopy[i] !== targetCopy[i]) { + x = thisCopy[i] + y = targetCopy[i] + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, +// OR the last index of `val` in `buffer` at offset <= `byteOffset`. +// +// Arguments: +// - buffer - a Buffer to search +// - val - a string, Buffer, or number +// - byteOffset - an index into `buffer`; will be clamped to an int32 +// - encoding - an optional encoding, relevant is val is a string +// - dir - true for indexOf, false for lastIndexOf +function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { + // Empty buffer means no match + if (buffer.length === 0) return -1 + + // Normalize byteOffset + if (typeof byteOffset === 'string') { + encoding = byteOffset + byteOffset = 0 + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000 + } + byteOffset = +byteOffset // Coerce to Number. + if (isNaN(byteOffset)) { + // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer + byteOffset = dir ? 0 : (buffer.length - 1) + } + + // Normalize byteOffset: negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = buffer.length + byteOffset + if (byteOffset >= buffer.length) { + if (dir) return -1 + else byteOffset = buffer.length - 1 + } else if (byteOffset < 0) { + if (dir) byteOffset = 0 + else return -1 + } + + // Normalize val + if (typeof val === 'string') { + val = Buffer.from(val, encoding) + } + + // Finally, search either indexOf (if dir is true) or lastIndexOf + if (Buffer.isBuffer(val)) { + // Special case: looking for empty string/buffer always fails + if (val.length === 0) { + return -1 + } + return arrayIndexOf(buffer, val, byteOffset, encoding, dir) + } else if (typeof val === 'number') { + val = val & 0xFF // Search for a byte value [0-255] + if (Buffer.TYPED_ARRAY_SUPPORT && + typeof Uint8Array.prototype.indexOf === 'function') { + if (dir) { + return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) + } else { + return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) + } + } + return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) + } + + throw new TypeError('val must be string, number or Buffer') +} + +function arrayIndexOf (arr, val, byteOffset, encoding, dir) { + var indexSize = 1 + var arrLength = arr.length + var valLength = val.length + + if (encoding !== undefined) { + encoding = String(encoding).toLowerCase() + if (encoding === 'ucs2' || encoding === 'ucs-2' || + encoding === 'utf16le' || encoding === 'utf-16le') { + if (arr.length < 2 || val.length < 2) { + return -1 + } + indexSize = 2 + arrLength /= 2 + valLength /= 2 + byteOffset /= 2 + } + } + + function read (buf, i) { + if (indexSize === 1) { + return buf[i] + } else { + return buf.readUInt16BE(i * indexSize) + } + } + + var i + if (dir) { + var foundIndex = -1 + for (i = byteOffset; i < arrLength; i++) { + if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + if (foundIndex === -1) foundIndex = i + if (i - foundIndex + 1 === valLength) return foundIndex * indexSize + } else { + if (foundIndex !== -1) i -= i - foundIndex + foundIndex = -1 + } + } + } else { + if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength + for (i = byteOffset; i >= 0; i--) { + var found = true + for (var j = 0; j < valLength; j++) { + if (read(arr, i + j) !== read(val, j)) { + found = false + break + } + } + if (found) return i + } + } + + return -1 +} + +Buffer.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 +} + +Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true) +} + +Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false) +} + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; ++i) { + var parsed = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(parsed)) return i + buf[offset + i] = parsed + } + return i +} + +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} + +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} + +function latin1Write (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} + +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8' + length = this.length + offset = 0 + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset + length = this.length + offset = 0 + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0 + if (isFinite(length)) { + length = length | 0 + if (encoding === undefined) encoding = 'utf8' + } else { + encoding = length + length = undefined + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + throw new Error( + 'Buffer.write(string, encoding, offset[, length]) is no longer supported' + ) + } + + var remaining = this.length - offset + if (length === undefined || length > remaining) length = remaining + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('Attempt to write outside buffer bounds') + } + + if (!encoding) encoding = 'utf8' + + var loweredCase = false + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'latin1': + case 'binary': + return latin1Write(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end) + var res = [] + + var i = start + while (i < end) { + var firstByte = buf[i] + var codePoint = null + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1 + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte + } + break + case 2: + secondByte = buf[i + 1] + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint + } + } + break + case 3: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint + } + } + break + case 4: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + fourthByte = buf[i + 3] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint + } + } + } + } + + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD + bytesPerSequence = 1 + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000 + res.push(codePoint >>> 10 & 0x3FF | 0xD800) + codePoint = 0xDC00 | codePoint & 0x3FF + } + + res.push(codePoint) + i += bytesPerSequence + } + + return decodeCodePointsArray(res) +} + +// Based on http://stackoverflow.com/a/22747272/680742, the browser with +// the lowest limit is Chrome, with 0x10000 args. +// We go 1 magnitude less, for safety +var MAX_ARGUMENTS_LENGTH = 0x1000 + +function decodeCodePointsArray (codePoints) { + var len = codePoints.length + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } + + // Decode in chunks to avoid "call stack size exceeded". + var res = '' + var i = 0 + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ) + } + return res +} + +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i] & 0x7F) + } + return ret +} + +function latin1Slice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i]) + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length + + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len + + var out = '' + for (var i = start; i < end; ++i) { + out += toHex(buf[i]) + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res +} + +Buffer.prototype.slice = function slice (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end + + if (start < 0) { + start += len + if (start < 0) start = 0 + } else if (start > len) { + start = len + } + + if (end < 0) { + end += len + if (end < 0) end = 0 + } else if (end > len) { + end = len + } + + if (end < start) end = start + + var newBuf + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = this.subarray(start, end) + newBuf.__proto__ = Buffer.prototype + } else { + var sliceLen = end - start + newBuf = new Buffer(sliceLen, undefined) + for (var i = 0; i < sliceLen; ++i) { + newBuf[i] = this[i + start] + } + } + + return newBuf +} + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') +} + +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + + return val +} + +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + checkOffset(offset, byteLength, this.length) + } + + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul + } + + return val +} + +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + return this[offset] +} + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) +} + +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} + +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +} + +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +} + +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +} + +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} + +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +} + +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) +} + +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} + +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} + +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) +} + +function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') + if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') + if (offset + ext > buf.length) throw new RangeError('Index out of range') +} + +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } + + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } + + var i = byteLength - 1 + var mul = 1 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = (value & 0xff) + return offset + 1 +} + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = 0 + var mul = 1 + var sub = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { + sub = 1 + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = byteLength - 1 + var mul = 1 + var sub = 0 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { + sub = 1 + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + if (value < 0) value = 0xff + value + 1 + this[offset] = (value & 0xff) + return offset + 1 +} + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (offset + ext > buf.length) throw new RangeError('Index out of range') + if (offset < 0) throw new RangeError('Index out of range') +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +} + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (targetStart >= target.length) targetStart = target.length + if (!targetStart) targetStart = 0 + if (end > 0 && end < start) end = start + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start + } + + var len = end - start + var i + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; --i) { + target[i + targetStart] = this[i + start] + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; ++i) { + target[i + targetStart] = this[i + start] + } + } else { + Uint8Array.prototype.set.call( + target, + this.subarray(start, start + len), + targetStart + ) + } + + return len +} + +// Usage: +// buffer.fill(number[, offset[, end]]) +// buffer.fill(buffer[, offset[, end]]) +// buffer.fill(string[, offset[, end]][, encoding]) +Buffer.prototype.fill = function fill (val, start, end, encoding) { + // Handle string cases: + if (typeof val === 'string') { + if (typeof start === 'string') { + encoding = start + start = 0 + end = this.length + } else if (typeof end === 'string') { + encoding = end + end = this.length + } + if (val.length === 1) { + var code = val.charCodeAt(0) + if (code < 256) { + val = code + } + } + if (encoding !== undefined && typeof encoding !== 'string') { + throw new TypeError('encoding must be a string') + } + if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { + throw new TypeError('Unknown encoding: ' + encoding) + } + } else if (typeof val === 'number') { + val = val & 255 + } + + // Invalid ranges are not set to a default, so can range check early. + if (start < 0 || this.length < start || this.length < end) { + throw new RangeError('Out of range index') + } + + if (end <= start) { + return this + } + + start = start >>> 0 + end = end === undefined ? this.length : end >>> 0 + + if (!val) val = 0 + + var i + if (typeof val === 'number') { + for (i = start; i < end; ++i) { + this[i] = val + } + } else { + var bytes = Buffer.isBuffer(val) + ? val + : utf8ToBytes(new Buffer(val, encoding).toString()) + var len = bytes.length + for (i = 0; i < end - start; ++i) { + this[i + start] = bytes[i % len] + } + } + + return this +} + +// HELPER FUNCTIONS +// ================ + +var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str +} + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + + for (var i = 0; i < length; ++i) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } + + // valid lead + leadSurrogate = codePoint + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } + + // valid surrogate pair + codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + } + + leadSurrogate = null + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; ++i) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; ++i) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; ++i) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i] + } + return i +} + +function isnan (val) { + return val !== val // eslint-disable-line no-self-compare +} + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(23))) + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +var isObject = __webpack_require__(19); +module.exports = function(it){ + if(!isObject(it))throw TypeError(it + ' is not an object!'); + return it; +}; + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + +var anObject = __webpack_require__(4) + , IE8_DOM_DEFINE = __webpack_require__(59) + , toPrimitive = __webpack_require__(43) + , dP = Object.defineProperty; + +exports.f = __webpack_require__(6) ? Object.defineProperty : function defineProperty(O, P, Attributes){ + anObject(O); + P = toPrimitive(P, true); + anObject(Attributes); + if(IE8_DOM_DEFINE)try { + return dP(O, P, Attributes); + } catch(e){ /* empty */ } + if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!'); + if('value' in Attributes)O[P] = Attributes.value; + return O; +}; + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +// Thank's IE8 for his funny defineProperty +module.exports = !__webpack_require__(13)(function(){ + return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7; +}); + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +var global = __webpack_require__(2) + , core = __webpack_require__(0) + , ctx = __webpack_require__(18) + , hide = __webpack_require__(9) + , PROTOTYPE = 'prototype'; + +var $export = function(type, name, source){ + var IS_FORCED = type & $export.F + , IS_GLOBAL = type & $export.G + , IS_STATIC = type & $export.S + , IS_PROTO = type & $export.P + , IS_BIND = type & $export.B + , IS_WRAP = type & $export.W + , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) + , expProto = exports[PROTOTYPE] + , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] + , key, own, out; + if(IS_GLOBAL)source = name; + for(key in source){ + // contains in native + own = !IS_FORCED && target && target[key] !== undefined; + if(own && key in exports)continue; + // export native or passed + out = own ? target[key] : source[key]; + // prevent global pollution for namespaces + exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] + // bind timers to global for call from export context + : IS_BIND && own ? ctx(out, global) + // wrap global constructors for prevent change them in library + : IS_WRAP && target[key] == out ? (function(C){ + var F = function(a, b, c){ + if(this instanceof C){ + switch(arguments.length){ + case 0: return new C; + case 1: return new C(a); + case 2: return new C(a, b); + } return new C(a, b, c); + } return C.apply(this, arguments); + }; + F[PROTOTYPE] = C[PROTOTYPE]; + return F; + // make static versions for prototype methods + })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; + // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% + if(IS_PROTO){ + (exports.virtual || (exports.virtual = {}))[key] = out; + // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% + if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out); + } + } +}; +// type bitmap +$export.F = 1; // forced +$export.G = 2; // global +$export.S = 4; // static +$export.P = 8; // proto +$export.B = 16; // bind +$export.W = 32; // wrap +$export.U = 64; // safe +$export.R = 128; // real proto method for `library` +module.exports = $export; + +/***/ }), +/* 8 */ +/***/ (function(module, exports) { + +var hasOwnProperty = {}.hasOwnProperty; +module.exports = function(it, key){ + return hasOwnProperty.call(it, key); +}; + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +var dP = __webpack_require__(5) + , createDesc = __webpack_require__(20); +module.exports = __webpack_require__(6) ? function(object, key, value){ + return dP.f(object, key, createDesc(1, value)); +} : function(object, key, value){ + object[key] = value; + return object; +}; + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +// to indexed object, toObject with fallback for non-array-like ES3 strings +var IObject = __webpack_require__(60) + , defined = __webpack_require__(35); +module.exports = function(it){ + return IObject(defined(it)); +}; + +/***/ }), +/* 11 */ +/***/ (function(module, exports) { + +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + + + +/*<replacement>*/ + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + keys.push(key); + }return keys; +}; +/*</replacement>*/ + +module.exports = Duplex; + +/*<replacement>*/ +var processNextTick = __webpack_require__(49); +/*</replacement>*/ + +/*<replacement>*/ +var util = __webpack_require__(22); +util.inherits = __webpack_require__(16); +/*</replacement>*/ + +var Readable = __webpack_require__(72); +var Writable = __webpack_require__(50); + +util.inherits(Duplex, Readable); + +var keys = objectKeys(Writable.prototype); +for (var v = 0; v < keys.length; v++) { + var method = keys[v]; + if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; +} + +function Duplex(options) { + if (!(this instanceof Duplex)) return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) this.readable = false; + + if (options && options.writable === false) this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; + + this.once('end', onend); +} + +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) return; + + // no more data can be written. + // But allow more writes to happen in this tick. + processNextTick(onEndNT, this); +} + +function onEndNT(self) { + self.end(); +} + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +/***/ }), +/* 13 */ +/***/ (function(module, exports) { + +module.exports = function(exec){ + try { + return !!exec(); + } catch(e){ + return true; + } +}; + +/***/ }), +/* 14 */ +/***/ (function(module, exports) { + +module.exports = {}; + +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { + +// 19.1.2.14 / 15.2.3.14 Object.keys(O) +var $keys = __webpack_require__(67) + , enumBugKeys = __webpack_require__(37); + +module.exports = Object.keys || function keys(O){ + return $keys(O, enumBugKeys); +}; + +/***/ }), +/* 16 */ +/***/ (function(module, exports) { + +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + + +/***/ }), +/* 17 */ +/***/ (function(module, exports) { + +var toString = {}.toString; + +module.exports = function(it){ + return toString.call(it).slice(8, -1); +}; + +/***/ }), +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { + +// optional / simple context binding +var aFunction = __webpack_require__(33); +module.exports = function(fn, that, length){ + aFunction(fn); + if(that === undefined)return fn; + switch(length){ + case 1: return function(a){ + return fn.call(that, a); + }; + case 2: return function(a, b){ + return fn.call(that, a, b); + }; + case 3: return function(a, b, c){ + return fn.call(that, a, b, c); + }; + } + return function(/* ...args */){ + return fn.apply(that, arguments); + }; +}; + +/***/ }), +/* 19 */ +/***/ (function(module, exports) { + +module.exports = function(it){ + return typeof it === 'object' ? it !== null : typeof it === 'function'; +}; + +/***/ }), +/* 20 */ +/***/ (function(module, exports) { + +module.exports = function(bitmap, value){ + return { + enumerable : !(bitmap & 1), + configurable: !(bitmap & 2), + writable : !(bitmap & 4), + value : value + }; +}; + +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $at = __webpack_require__(124)(true); + +// 21.1.3.27 String.prototype[@@iterator]() +__webpack_require__(63)(String, 'String', function(iterated){ + this._t = String(iterated); // target + this._i = 0; // next index +// 21.1.5.2.1 %StringIteratorPrototype%.next() +}, function(){ + var O = this._t + , index = this._i + , point; + if(index >= O.length)return {value: undefined, done: true}; + point = $at(O, index); + this._i += point.length; + return {value: point, done: false}; +}); + +/***/ }), +/* 22 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. + +function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return objectToString(arg) === '[object Array]'; +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = Buffer.isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3).Buffer)) + +/***/ }), +/* 23 */ +/***/ (function(module, exports) { + +var g;
+
+// This works in non-strict mode
+g = (function() {
+ return this;
+})();
+
+try {
+ // This works if eval is allowed (see CSP)
+ g = g || Function("return this")() || (1,eval)("this");
+} catch(e) {
+ // This works if the window reference is available
+ if(typeof window === "object")
+ g = window;
+}
+
+// g can still be undefined, but nothing to do about it...
+// We return undefined, instead of nothing here, so it's
+// easier to handle this case. if(!global) { ...}
+
+module.exports = g;
+ + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { + +var __WEBPACK_AMD_DEFINE_RESULT__;(function(root, factory){ + + //UMD + if ( true ) { + !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { + return factory(); + }.call(exports, __webpack_require__, exports, module), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + } else if (typeof module === "object") { + module.exports = factory(); + } else { + root.Tone = factory(); + } + +}(this, function(){ + + "use strict"; + + var Tone; + //constructs the main Tone object + function Main(func){ + Tone = func(); + } + //invokes each of the modules with the main Tone object as the argument + function Module(func){ + func(Tone); + } /** + * Tone.js + * @author Yotam Mann + * @license http://opensource.org/licenses/MIT MIT License + * @copyright 2014-2018 Yotam Mann + */ + Main(function () { + + /////////////////////////////////////////////////////////////////////////// + // TONE + /////////////////////////////////////////////////////////////////////////// + /** + * @class Tone is the base class of all other classes. + * @constructor + */ + var Tone = function () { + if (!(this instanceof Tone)) { + throw new Error('constructor needs to be called with the \'new\' keyword'); + } + }; + /** + * @memberOf Tone# + * @returns {String} returns the name of the class as a string + */ + Tone.prototype.toString = function () { + for (var className in Tone) { + var isLetter = className[0].match(/^[A-Z]$/); + var sameConstructor = Tone[className] === this.constructor; + if (Tone.isFunction(Tone[className]) && isLetter && sameConstructor) { + return className; + } + } + return 'Tone'; + }; + /** + * @memberOf Tone# + * disconnect and dispose + * @returns {Tone} this + */ + Tone.prototype.dispose = function () { + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // GET/SET + /////////////////////////////////////////////////////////////////////////// + /** + * Set the parameters at once. Either pass in an + * object mapping parameters to values, or to set a + * single parameter, by passing in a string and value. + * The last argument is an optional ramp time which + * will ramp any signal values to their destination value + * over the duration of the rampTime. + * @param {Object|String} params + * @param {Number=} value + * @param {Time=} rampTime + * @returns {Tone} this + * @memberOf Tone# + * @example + * //set values using an object + * filter.set({ + * "frequency" : 300, + * "type" : highpass + * }); + * @example + * filter.set("type", "highpass"); + * @example + * //ramp to the value 220 over 3 seconds. + * oscillator.set({ + * "frequency" : 220 + * }, 3); + */ + Tone.prototype.set = function (params, value, rampTime) { + if (Tone.isObject(params)) { + rampTime = value; + } else if (Tone.isString(params)) { + var tmpObj = {}; + tmpObj[params] = value; + params = tmpObj; + } + paramLoop: + for (var attr in params) { + value = params[attr]; + var parent = this; + if (attr.indexOf('.') !== -1) { + var attrSplit = attr.split('.'); + for (var i = 0; i < attrSplit.length - 1; i++) { + parent = parent[attrSplit[i]]; + if (parent instanceof Tone) { + attrSplit.splice(0, i + 1); + var innerParam = attrSplit.join('.'); + parent.set(innerParam, value); + continue paramLoop; + } + } + attr = attrSplit[attrSplit.length - 1]; + } + var param = parent[attr]; + if (Tone.isUndef(param)) { + continue; + } + if (Tone.Signal && param instanceof Tone.Signal || Tone.Param && param instanceof Tone.Param) { + if (param.value !== value) { + if (Tone.isUndef(rampTime)) { + param.value = value; + } else { + param.rampTo(value, rampTime); + } + } + } else if (param instanceof AudioParam) { + if (param.value !== value) { + param.value = value; + } + } else if (Tone.TimeBase && param instanceof Tone.TimeBase) { + parent[attr] = value; + } else if (param instanceof Tone) { + param.set(value); + } else if (param !== value) { + parent[attr] = value; + } + } + return this; + }; + /** + * Get the object's attributes. Given no arguments get + * will return all available object properties and their corresponding + * values. Pass in a single attribute to retrieve or an array + * of attributes. The attribute strings can also include a "." + * to access deeper properties. + * @memberOf Tone# + * @example + * osc.get(); + * //returns {"type" : "sine", "frequency" : 440, ...etc} + * @example + * osc.get("type"); + * //returns { "type" : "sine"} + * @example + * //use dot notation to access deep properties + * synth.get(["envelope.attack", "envelope.release"]); + * //returns {"envelope" : {"attack" : 0.2, "release" : 0.4}} + * @param {Array=|string|undefined} params the parameters to get, otherwise will return + * all available. + * @returns {Object} + */ + Tone.prototype.get = function (params) { + if (Tone.isUndef(params)) { + params = this._collectDefaults(this.constructor); + } else if (Tone.isString(params)) { + params = [params]; + } + var ret = {}; + for (var i = 0; i < params.length; i++) { + var attr = params[i]; + var parent = this; + var subRet = ret; + if (attr.indexOf('.') !== -1) { + var attrSplit = attr.split('.'); + for (var j = 0; j < attrSplit.length - 1; j++) { + var subAttr = attrSplit[j]; + subRet[subAttr] = subRet[subAttr] || {}; + subRet = subRet[subAttr]; + parent = parent[subAttr]; + } + attr = attrSplit[attrSplit.length - 1]; + } + var param = parent[attr]; + if (Tone.isObject(params[attr])) { + subRet[attr] = param.get(); + } else if (Tone.Signal && param instanceof Tone.Signal) { + subRet[attr] = param.value; + } else if (Tone.Param && param instanceof Tone.Param) { + subRet[attr] = param.value; + } else if (param instanceof AudioParam) { + subRet[attr] = param.value; + } else if (param instanceof Tone) { + subRet[attr] = param.get(); + } else if (!Tone.isFunction(param) && Tone.isDefined(param)) { + subRet[attr] = param; + } + } + return ret; + }; + /** + * collect all of the default attributes in one + * @private + * @param {Function} constr the constructor to find the defaults from + * @return {Array} all of the attributes which belong to the class + */ + Tone.prototype._collectDefaults = function (constr) { + var ret = []; + if (Tone.isDefined(constr.defaults)) { + ret = Object.keys(constr.defaults); + } + if (Tone.isDefined(constr._super)) { + var superDefs = this._collectDefaults(constr._super); + //filter out repeats + for (var i = 0; i < superDefs.length; i++) { + if (ret.indexOf(superDefs[i]) === -1) { + ret.push(superDefs[i]); + } + } + } + return ret; + }; + /////////////////////////////////////////////////////////////////////////// + // DEFAULTS + /////////////////////////////////////////////////////////////////////////// + /** + * @memberOf Tone + * @param {Array} values The arguments array + * @param {Array} keys The names of the arguments + * @param {Function|Object} constr The class constructor + * @return {Object} An object composed of the defaults between the class' defaults + * and the passed in arguments. + */ + Tone.defaults = function (values, keys, constr) { + var options = {}; + if (values.length === 1 && Tone.isObject(values[0])) { + options = values[0]; + } else { + for (var i = 0; i < keys.length; i++) { + options[keys[i]] = values[i]; + } + } + if (Tone.isDefined(constr.defaults)) { + return Tone.defaultArg(options, constr.defaults); + } else if (Tone.isObject(constr)) { + return Tone.defaultArg(options, constr); + } else { + return options; + } + }; + /** + * If the `given` parameter is undefined, use the `fallback`. + * If both `given` and `fallback` are object literals, it will + * return a deep copy which includes all of the parameters from both + * objects. If a parameter is undefined in given, it will return + * the fallback property. + * <br><br> + * WARNING: if object is self referential, it will go into an an + * infinite recursive loop. + * @memberOf Tone + * @param {*} given + * @param {*} fallback + * @return {*} + */ + Tone.defaultArg = function (given, fallback) { + if (Tone.isObject(given) && Tone.isObject(fallback)) { + var ret = {}; + //make a deep copy of the given object + for (var givenProp in given) { + ret[givenProp] = Tone.defaultArg(fallback[givenProp], given[givenProp]); + } + for (var fallbackProp in fallback) { + ret[fallbackProp] = Tone.defaultArg(given[fallbackProp], fallback[fallbackProp]); + } + return ret; + } else { + return Tone.isUndef(given) ? fallback : given; + } + }; + /////////////////////////////////////////////////////////////////////////// + // CONNECTIONS + /////////////////////////////////////////////////////////////////////////// + /** + * connect together all of the arguments in series + * @param {...AudioParam|Tone|AudioNode} nodes + * @returns {Tone} + * @memberOf Tone + * @static + */ + Tone.connectSeries = function () { + var currentUnit = arguments[0]; + for (var i = 1; i < arguments.length; i++) { + var toUnit = arguments[i]; + currentUnit.connect(toUnit); + currentUnit = toUnit; + } + return Tone; + }; + /////////////////////////////////////////////////////////////////////////// + // TYPE CHECKING + /////////////////////////////////////////////////////////////////////////// + /** + * Test if the arg is undefined + * @param {*} arg the argument to test + * @returns {Boolean} true if the arg is undefined + * @static + * @memberOf Tone + */ + Tone.isUndef = function (val) { + return typeof val === 'undefined'; + }; + /** + * Test if the arg is not undefined + * @param {*} arg the argument to test + * @returns {Boolean} true if the arg is undefined + * @static + * @memberOf Tone + */ + Tone.isDefined = function (val) { + return !Tone.isUndef(val); + }; + /** + * Test if the arg is a function + * @param {*} arg the argument to test + * @returns {Boolean} true if the arg is a function + * @static + * @memberOf Tone + */ + Tone.isFunction = function (val) { + return typeof val === 'function'; + }; + /** + * Test if the argument is a number. + * @param {*} arg the argument to test + * @returns {Boolean} true if the arg is a number + * @static + * @memberOf Tone + */ + Tone.isNumber = function (arg) { + return typeof arg === 'number'; + }; + /** + * Test if the given argument is an object literal (i.e. `{}`); + * @param {*} arg the argument to test + * @returns {Boolean} true if the arg is an object literal. + * @static + * @memberOf Tone + */ + Tone.isObject = function (arg) { + return Object.prototype.toString.call(arg) === '[object Object]' && arg.constructor === Object; + }; + /** + * Test if the argument is a boolean. + * @param {*} arg the argument to test + * @returns {Boolean} true if the arg is a boolean + * @static + * @memberOf Tone + */ + Tone.isBoolean = function (arg) { + return typeof arg === 'boolean'; + }; + /** + * Test if the argument is an Array + * @param {*} arg the argument to test + * @returns {Boolean} true if the arg is an array + * @static + * @memberOf Tone + */ + Tone.isArray = function (arg) { + return Array.isArray(arg); + }; + /** + * Test if the argument is a string. + * @param {*} arg the argument to test + * @returns {Boolean} true if the arg is a string + * @static + * @memberOf Tone + */ + Tone.isString = function (arg) { + return typeof arg === 'string'; + }; + /** + * Test if the argument is in the form of a note in scientific pitch notation. + * e.g. "C4" + * @param {*} arg the argument to test + * @returns {Boolean} true if the arg is a string + * @static + * @memberOf Tone + */ + Tone.isNote = function (arg) { + return Tone.isString(arg) && /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i.test(arg); + }; + /** + * An empty function. + * @static + */ + Tone.noOp = function () { + }; + /** + * Make the property not writable. Internal use only. + * @private + * @param {String} property the property to make not writable + */ + Tone.prototype._readOnly = function (property) { + if (Array.isArray(property)) { + for (var i = 0; i < property.length; i++) { + this._readOnly(property[i]); + } + } else { + Object.defineProperty(this, property, { + writable: false, + enumerable: true + }); + } + }; + /** + * Make an attribute writeable. Interal use only. + * @private + * @param {String} property the property to make writable + */ + Tone.prototype._writable = function (property) { + if (Array.isArray(property)) { + for (var i = 0; i < property.length; i++) { + this._writable(property[i]); + } + } else { + Object.defineProperty(this, property, { writable: true }); + } + }; + /** + * Possible play states. + * @enum {String} + */ + Tone.State = { + Started: 'started', + Stopped: 'stopped', + Paused: 'paused' + }; + /////////////////////////////////////////////////////////////////////////// + // CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Equal power gain scale. Good for cross-fading. + * @param {NormalRange} percent (0-1) + * @return {Number} output gain (0-1) + * @static + * @memberOf Tone + */ + Tone.equalPowerScale = function (percent) { + var piFactor = 0.5 * Math.PI; + return Math.sin(percent * piFactor); + }; + /** + * Convert decibels into gain. + * @param {Decibels} db + * @return {Number} + * @static + * @memberOf Tone + */ + Tone.dbToGain = function (db) { + return Math.pow(10, db / 20); + }; + /** + * Convert gain to decibels. + * @param {Number} gain (0-1) + * @return {Decibels} + * @static + * @memberOf Tone + */ + Tone.gainToDb = function (gain) { + return 20 * (Math.log(gain) / Math.LN10); + }; + /** + * Convert an interval (in semitones) to a frequency ratio. + * @param {Interval} interval the number of semitones above the base note + * @return {Number} the frequency ratio + * @static + * @memberOf Tone + * @example + * tone.intervalToFrequencyRatio(0); // 1 + * tone.intervalToFrequencyRatio(12); // 2 + * tone.intervalToFrequencyRatio(-12); // 0.5 + */ + Tone.intervalToFrequencyRatio = function (interval) { + return Math.pow(2, interval / 12); + }; + /////////////////////////////////////////////////////////////////////////// + // TIMING + /////////////////////////////////////////////////////////////////////////// + /** + * Return the current time of the AudioContext clock. + * @return {Number} the currentTime from the AudioContext + * @memberOf Tone# + */ + Tone.prototype.now = function () { + return Tone.context.now(); + }; + /** + * Return the current time of the AudioContext clock. + * @return {Number} the currentTime from the AudioContext + * @static + * @memberOf Tone + */ + Tone.now = function () { + return Tone.context.now(); + }; + /////////////////////////////////////////////////////////////////////////// + // INHERITANCE + /////////////////////////////////////////////////////////////////////////// + /** + * have a child inherit all of Tone's (or a parent's) prototype + * to inherit the parent's properties, make sure to call + * Parent.call(this) in the child's constructor + * + * based on closure library's inherit function + * + * @memberOf Tone + * @static + * @param {Function} child + * @param {Function=} parent (optional) parent to inherit from + * if no parent is supplied, the child + * will inherit from Tone + */ + Tone.extend = function (child, parent) { + if (Tone.isUndef(parent)) { + parent = Tone; + } + function TempConstructor() { + } + TempConstructor.prototype = parent.prototype; + child.prototype = new TempConstructor(); + /** @override */ + child.prototype.constructor = child; + child._super = parent; + }; + /////////////////////////////////////////////////////////////////////////// + // CONTEXT + /////////////////////////////////////////////////////////////////////////// + /** + * Private reference to the global AudioContext + * @type {AudioContext} + * @private + */ + var audioContext = null; + /** + * A static pointer to the audio context accessible as Tone.context. + * @type {Tone.Context} + * @name context + * @memberOf Tone + */ + Object.defineProperty(Tone, 'context', { + get: function () { + return audioContext; + }, + set: function (context) { + if (Tone.Context && context instanceof Tone.Context) { + audioContext = context; + } else { + audioContext = new Tone.Context(context); + } + //initialize the new audio context + Tone.Context.emit('init', audioContext); + } + }); + /** + * The AudioContext + * @type {Tone.Context} + * @name context + * @memberOf Tone# + * @readOnly + */ + Object.defineProperty(Tone.prototype, 'context', { + get: function () { + return Tone.context; + } + }); + /** + * Tone automatically creates a context on init, but if you are working + * with other libraries which also create an AudioContext, it can be + * useful to set your own. If you are going to set your own context, + * be sure to do it at the start of your code, before creating any objects. + * @static + * @param {AudioContext} ctx The new audio context to set + */ + Tone.setContext = function (ctx) { + Tone.context = ctx; + }; + /////////////////////////////////////////////////////////////////////////// + // ATTRIBUTES + /////////////////////////////////////////////////////////////////////////// + /** + * The number of seconds of 1 processing block (128 samples) + * @type {Number} + * @name blockTime + * @memberOf Tone + * @static + * @readOnly + */ + Object.defineProperty(Tone.prototype, 'blockTime', { + get: function () { + return 128 / this.context.sampleRate; + } + }); + /** + * The duration in seconds of one sample. + * @type {Number} + * @name sampleTime + * @memberOf Tone + * @static + * @readOnly + */ + Object.defineProperty(Tone.prototype, 'sampleTime', { + get: function () { + return 1 / this.context.sampleRate; + } + }); + /** + * Whether or not all the technologies that Tone.js relies on are supported by the current browser. + * @type {Boolean} + * @name supported + * @memberOf Tone + * @readOnly + * @static + */ + Object.defineProperty(Tone, 'supported', { + get: function () { + var hasAudioContext = window.hasOwnProperty('AudioContext') || window.hasOwnProperty('webkitAudioContext'); + var hasPromises = window.hasOwnProperty('Promise'); + var hasWorkers = window.hasOwnProperty('Worker'); + return hasAudioContext && hasPromises && hasWorkers; + } + }); + /** + * Boolean value if the audio context has been initialized. + * @type {Boolean} + * @memberOf Tone + * @static + * @name initialized + */ + Object.defineProperty(Tone, 'initialized', { + get: function () { + return audioContext !== null; + } + }); + /** + * Get the context when it becomes available + * @param {Function} resolve Callback when the context is initialized + * @return {Tone} + */ + Tone.getContext = function (resolve) { + if (Tone.initialized) { + resolve(Tone.context); + } else { + var resCallback = function () { + resolve(Tone.context); + Tone.Context.off('init', resCallback); + }; + Tone.Context.on('init', resCallback); + } + return Tone; + }; + /** + * The version number + * @type {String} + * @static + */ + Tone.version = 'r12'; + return Tone; + }); + Module(function (Tone) { + + /** + * @class Tone.Emitter gives classes which extend it + * the ability to listen for and emit events. + * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js). + * MIT (c) 2011 Jerome Etienne. + * + * @extends {Tone} + */ + Tone.Emitter = function () { + Tone.call(this); + /** + * Contains all of the events. + * @private + * @type {Object} + */ + this._events = {}; + }; + Tone.extend(Tone.Emitter); + /** + * Bind a callback to a specific event. + * @param {String} event The name of the event to listen for. + * @param {Function} callback The callback to invoke when the + * event is emitted + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.on = function (event, callback) { + //split the event + var events = event.split(/\W+/); + for (var i = 0; i < events.length; i++) { + var eventName = events[i]; + if (!this._events.hasOwnProperty(eventName)) { + this._events[eventName] = []; + } + this._events[eventName].push(callback); + } + return this; + }; + /** + * Bind a callback which is only invoked once + * @param {String} event The name of the event to listen for. + * @param {Function} callback The callback to invoke when the + * event is emitted + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.once = function (event, callback) { + var boundCallback = function () { + //invoke the callback + callback.apply(this, arguments); + this.off(event, boundCallback); + }.bind(this); + this.on(event, boundCallback); + return this; + }; + /** + * Remove the event listener. + * @param {String} event The event to stop listening to. + * @param {Function=} callback The callback which was bound to + * the event with Tone.Emitter.on. + * If no callback is given, all callbacks + * events are removed. + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.off = function (event, callback) { + var events = event.split(/\W+/); + for (var ev = 0; ev < events.length; ev++) { + event = events[ev]; + if (this._events.hasOwnProperty(event)) { + if (Tone.isUndef(callback)) { + this._events[event] = []; + } else { + var eventList = this._events[event]; + for (var i = 0; i < eventList.length; i++) { + if (eventList[i] === callback) { + eventList.splice(i, 1); + } + } + } + } + } + return this; + }; + /** + * Invoke all of the callbacks bound to the event + * with any arguments passed in. + * @param {String} event The name of the event. + * @param {*} args... The arguments to pass to the functions listening. + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.emit = function (event) { + if (this._events) { + var args = Array.apply(null, arguments).slice(1); + if (this._events.hasOwnProperty(event)) { + var eventList = this._events[event].slice(0); + for (var i = 0, len = eventList.length; i < len; i++) { + eventList[i].apply(this, args); + } + } + } + return this; + }; + /** + * Add Emitter functions (on/off/emit) to the object + * @param {Object|Function} object The object or class to extend. + * @returns {Tone.Emitter} + */ + Tone.Emitter.mixin = function (object) { + var functions = [ + 'on', + 'once', + 'off', + 'emit' + ]; + object._events = {}; + for (var i = 0; i < functions.length; i++) { + var func = functions[i]; + var emitterFunc = Tone.Emitter.prototype[func]; + object[func] = emitterFunc; + } + return Tone.Emitter; + }; + /** + * Clean up + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._events = null; + return this; + }; + return Tone.Emitter; + }); + Module(function (Tone) { + + /** + * @class A Timeline class for scheduling and maintaining state + * along a timeline. All events must have a "time" property. + * Internally, events are stored in time order for fast + * retrieval. + * @extends {Tone} + * @param {Positive} [memory=Infinity] The number of previous events that are retained. + */ + Tone.Timeline = function () { + var options = Tone.defaults(arguments, ['memory'], Tone.Timeline); + Tone.call(this); + /** + * The array of scheduled timeline events + * @type {Array} + * @private + */ + this._timeline = []; + /** + * The memory of the timeline, i.e. + * how many events in the past it will retain + * @type {Positive} + */ + this.memory = options.memory; + }; + Tone.extend(Tone.Timeline); + /** + * the default parameters + * @static + * @const + */ + Tone.Timeline.defaults = { 'memory': Infinity }; + /** + * The number of items in the timeline. + * @type {Number} + * @memberOf Tone.Timeline# + * @name length + * @readOnly + */ + Object.defineProperty(Tone.Timeline.prototype, 'length', { + get: function () { + return this._timeline.length; + } + }); + /** + * Insert an event object onto the timeline. Events must have a "time" attribute. + * @param {Object} event The event object to insert into the + * timeline. + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.add = function (event) { + //the event needs to have a time attribute + if (Tone.isUndef(event.time)) { + throw new Error('Tone.Timeline: events must have a time attribute'); + } + event.time = event.time.valueOf(); + var index = this._search(event.time); + this._timeline.splice(index + 1, 0, event); + //if the length is more than the memory, remove the previous ones + if (this.length > this.memory) { + var diff = this.length - this.memory; + this._timeline.splice(0, diff); + } + return this; + }; + /** + * Remove an event from the timeline. + * @param {Object} event The event object to remove from the list. + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.remove = function (event) { + var index = this._timeline.indexOf(event); + if (index !== -1) { + this._timeline.splice(index, 1); + } + return this; + }; + /** + * Get the nearest event whose time is less than or equal to the given time. + * @param {Number} time The time to query. + * @param {String} comparator Which value in the object to compare + * @returns {Object} The event object set after that time. + */ + Tone.Timeline.prototype.get = function (time, comparator) { + comparator = Tone.defaultArg(comparator, 'time'); + var index = this._search(time, comparator); + if (index !== -1) { + return this._timeline[index]; + } else { + return null; + } + }; + /** + * Return the first event in the timeline without removing it + * @returns {Object} The first event object + */ + Tone.Timeline.prototype.peek = function () { + return this._timeline[0]; + }; + /** + * Return the first event in the timeline and remove it + * @returns {Object} The first event object + */ + Tone.Timeline.prototype.shift = function () { + return this._timeline.shift(); + }; + /** + * Get the event which is scheduled after the given time. + * @param {Number} time The time to query. + * @param {String} comparator Which value in the object to compare + * @returns {Object} The event object after the given time + */ + Tone.Timeline.prototype.getAfter = function (time, comparator) { + comparator = Tone.defaultArg(comparator, 'time'); + var index = this._search(time, comparator); + if (index + 1 < this._timeline.length) { + return this._timeline[index + 1]; + } else { + return null; + } + }; + /** + * Get the event before the event at the given time. + * @param {Number} time The time to query. + * @param {String} comparator Which value in the object to compare + * @returns {Object} The event object before the given time + */ + Tone.Timeline.prototype.getBefore = function (time, comparator) { + comparator = Tone.defaultArg(comparator, 'time'); + var len = this._timeline.length; + //if it's after the last item, return the last item + if (len > 0 && this._timeline[len - 1][comparator] < time) { + return this._timeline[len - 1]; + } + var index = this._search(time, comparator); + if (index - 1 >= 0) { + return this._timeline[index - 1]; + } else { + return null; + } + }; + /** + * Cancel events after the given time + * @param {Number} time The time to query. + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.cancel = function (after) { + if (this._timeline.length > 1) { + var index = this._search(after); + if (index >= 0) { + if (this._timeline[index].time === after) { + //get the first item with that time + for (var i = index; i >= 0; i--) { + if (this._timeline[i].time === after) { + index = i; + } else { + break; + } + } + this._timeline = this._timeline.slice(0, index); + } else { + this._timeline = this._timeline.slice(0, index + 1); + } + } else { + this._timeline = []; + } + } else if (this._timeline.length === 1) { + //the first item's time + if (this._timeline[0].time >= after) { + this._timeline = []; + } + } + return this; + }; + /** + * Cancel events before or equal to the given time. + * @param {Number} time The time to cancel before. + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.cancelBefore = function (time) { + var index = this._search(time); + if (index >= 0) { + this._timeline = this._timeline.slice(index + 1); + } + return this; + }; + /** + * Returns the previous event if there is one. null otherwise + * @param {Object} event The event to find the previous one of + * @return {Object} The event right before the given event + */ + Tone.Timeline.prototype.previousEvent = function (event) { + var index = this._timeline.indexOf(event); + if (index > 0) { + return this._timeline[index - 1]; + } else { + return null; + } + }; + /** + * Does a binary search on the timeline array and returns the + * nearest event index whose time is after or equal to the given time. + * If a time is searched before the first index in the timeline, -1 is returned. + * If the time is after the end, the index of the last item is returned. + * @param {Number} time + * @param {String} comparator Which value in the object to compare + * @return {Number} the index in the timeline array + * @private + */ + Tone.Timeline.prototype._search = function (time, comparator) { + if (this._timeline.length === 0) { + return -1; + } + comparator = Tone.defaultArg(comparator, 'time'); + var beginning = 0; + var len = this._timeline.length; + var end = len; + if (len > 0 && this._timeline[len - 1][comparator] <= time) { + return len - 1; + } + while (beginning < end) { + // calculate the midpoint for roughly equal partition + var midPoint = Math.floor(beginning + (end - beginning) / 2); + var event = this._timeline[midPoint]; + var nextEvent = this._timeline[midPoint + 1]; + if (event[comparator] === time) { + //choose the last one that has the same time + for (var i = midPoint; i < this._timeline.length; i++) { + var testEvent = this._timeline[i]; + if (testEvent[comparator] === time) { + midPoint = i; + } + } + return midPoint; + } else if (event[comparator] < time && nextEvent[comparator] > time) { + return midPoint; + } else if (event[comparator] > time) { + //search lower + end = midPoint; + } else { + //search upper + beginning = midPoint + 1; + } + } + return -1; + }; + /** + * Internal iterator. Applies extra safety checks for + * removing items from the array. + * @param {Function} callback + * @param {Number=} lowerBound + * @param {Number=} upperBound + * @private + */ + Tone.Timeline.prototype._iterate = function (callback, lowerBound, upperBound) { + lowerBound = Tone.defaultArg(lowerBound, 0); + upperBound = Tone.defaultArg(upperBound, this._timeline.length - 1); + this._timeline.slice(lowerBound, upperBound + 1).forEach(function (event) { + callback.call(this, event); + }.bind(this)); + }; + /** + * Iterate over everything in the array + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEach = function (callback) { + this._iterate(callback); + return this; + }; + /** + * Iterate over everything in the array at or before the given time. + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachBefore = function (time, callback) { + //iterate over the items in reverse so that removing an item doesn't break things + var upperBound = this._search(time); + if (upperBound !== -1) { + this._iterate(callback, 0, upperBound); + } + return this; + }; + /** + * Iterate over everything in the array after the given time. + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachAfter = function (time, callback) { + //iterate over the items in reverse so that removing an item doesn't break things + var lowerBound = this._search(time); + this._iterate(callback, lowerBound + 1); + return this; + }; + /** + * Iterate over everything in the array between the startTime and endTime. + * The timerange is inclusive of the startTime, but exclusive of the endTime. + * range = [startTime, endTime). + * @param {Number} startTime The time to check if items are before + * @param {Number} endTime The end of the test interval. + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachBetween = function (startTime, endTime, callback) { + var lowerBound = this._search(startTime); + var upperBound = this._search(endTime); + if (lowerBound !== -1 && upperBound !== -1) { + if (this._timeline[lowerBound].time !== startTime) { + lowerBound += 1; + } + //exclusive of the end time + if (this._timeline[upperBound].time === endTime) { + upperBound -= 1; + } + this._iterate(callback, lowerBound, upperBound); + } else if (lowerBound === -1) { + this._iterate(callback, 0, upperBound); + } + return this; + }; + /** + * Iterate over everything in the array at or after the given time. Similar to + * forEachAfter, but includes the item(s) at the given time. + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachFrom = function (time, callback) { + //iterate over the items in reverse so that removing an item doesn't break things + var lowerBound = this._search(time); + //work backwards until the event time is less than time + while (lowerBound >= 0 && this._timeline[lowerBound].time >= time) { + lowerBound--; + } + this._iterate(callback, lowerBound + 1); + return this; + }; + /** + * Iterate over everything in the array at the given time + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachAtTime = function (time, callback) { + //iterate over the items in reverse so that removing an item doesn't break things + var upperBound = this._search(time); + if (upperBound !== -1) { + this._iterate(function (event) { + if (event.time === time) { + callback.call(this, event); + } + }, 0, upperBound); + } + return this; + }; + /** + * Clean up. + * @return {Tone.Timeline} this + */ + Tone.Timeline.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._timeline = null; + return this; + }; + return Tone.Timeline; + }); + Module(function (Tone) { + if (Tone.supported) { + if (!window.hasOwnProperty('OfflineAudioContext') && window.hasOwnProperty('webkitOfflineAudioContext')) { + window.OfflineAudioContext = window.webkitOfflineAudioContext; + } + //returns promise? + var context = new OfflineAudioContext(1, 1, 44100); + var ret = context.startRendering(); + if (!(ret instanceof Promise)) { + OfflineAudioContext.prototype._native_startRendering = OfflineAudioContext.prototype.startRendering; + OfflineAudioContext.prototype.startRendering = function () { + return new Promise(function (done) { + this.oncomplete = function (e) { + done(e.renderedBuffer); + }; + this._native_startRendering(); + }.bind(this)); + }; + } + } + }); + Module(function (Tone) { + if (Tone.supported) { + if (!window.hasOwnProperty('AudioContext') && window.hasOwnProperty('webkitAudioContext')) { + window.AudioContext = window.webkitAudioContext; + } + //not functionally equivalent, but only an API placeholder + if (!AudioContext.prototype.close) { + AudioContext.prototype.close = function () { + if (Tone.isFunction(this.suspend)) { + this.suspend(); + } + return Promise.resolve(); + }; + } + //not functionally equivalent + if (!AudioContext.prototype.resume) { + AudioContext.prototype.resume = function () { + return Promise.resolve(); + }; + } + //createGain + if (!AudioContext.prototype.createGain && AudioContext.prototype.createGainNode) { + AudioContext.prototype.createGain = AudioContext.prototype.createGainNode; + } + //createDelay + if (!AudioContext.prototype.createDelay && AudioContext.prototype.createDelayNode) { + AudioContext.prototype.createDelay = AudioContext.prototype.createDelayNode; + } + //test decodeAudioData returns a promise + // https://github.com/mohayonao/web-audio-api-shim/blob/master/src/AudioContext.js + // MIT License (c) 2015 @mohayonao + var decodeAudioDataPromise = false; + var offlineContext = new OfflineAudioContext(1, 1, 44100); + var audioData = new Uint32Array([ + 1179011410, + 48, + 1163280727, + 544501094, + 16, + 131073, + 44100, + 176400, + 1048580, + 1635017060, + 8, + 0, + 0, + 0, + 0 + ]).buffer; + try { + var ret = offlineContext.decodeAudioData(audioData); + if (ret instanceof Promise) { + decodeAudioDataPromise = true; + } + } catch (e) { + decodeAudioDataPromise = false; + } + if (!decodeAudioDataPromise) { + AudioContext.prototype._native_decodeAudioData = AudioContext.prototype.decodeAudioData; + AudioContext.prototype.decodeAudioData = function (audioData) { + return new Promise(function (success, error) { + this._native_decodeAudioData(audioData, success, error); + }.bind(this)); + }; + } + } + }); + Module(function (Tone) { + /** + * @class Wrapper around the native AudioContext. + * @extends {Tone.Emitter} + * @param {AudioContext=} context optionally pass in a context + */ + Tone.Context = function () { + Tone.Emitter.call(this); + var options = Tone.defaults(arguments, ['context'], Tone.Context); + if (!options.context) { + options.context = new window.AudioContext(); + if (!options.context) { + throw new Error('could not create AudioContext. Possibly too many AudioContexts running already.'); + } + } + this._context = options.context; + // extend all of the methods + for (var prop in this._context) { + this._defineProperty(this._context, prop); + } + /** + * The default latency hint + * @type {String} + * @private + */ + this._latencyHint = options.latencyHint; + /** + * An object containing all of the constants AudioBufferSourceNodes + * @type {Object} + * @private + */ + this._constants = {}; + /////////////////////////////////////////////////////////////////////// + // WORKER + /////////////////////////////////////////////////////////////////////// + /** + * The amount of time events are scheduled + * into the future + * @type {Number} + */ + this.lookAhead = options.lookAhead; + /** + * A reference to the actual computed update interval + * @type {Number} + * @private + */ + this._computedUpdateInterval = 0; + /** + * A reliable callback method + * @private + * @type {Ticker} + */ + this._ticker = new Ticker(this.emit.bind(this, 'tick'), options.clockSource, options.updateInterval); + /////////////////////////////////////////////////////////////////////// + // TIMEOUTS + /////////////////////////////////////////////////////////////////////// + /** + * All of the setTimeout events. + * @type {Tone.Timeline} + * @private + */ + this._timeouts = new Tone.Timeline(); + /** + * The timeout id counter + * @private + * @type {Number} + */ + this._timeoutIds = 0; + this.on('tick', this._timeoutLoop.bind(this)); + }; + Tone.extend(Tone.Context, Tone.Emitter); + Tone.Emitter.mixin(Tone.Context); + /** + * defaults + * @static + * @type {Object} + */ + Tone.Context.defaults = { + 'clockSource': 'worker', + 'latencyHint': 'interactive', + 'lookAhead': 0.1, + 'updateInterval': 0.03 + }; + /** + * Define a property on this Tone.Context. + * This is used to extend the native AudioContext + * @param {AudioContext} context + * @param {String} prop + * @private + */ + Tone.Context.prototype._defineProperty = function (context, prop) { + if (Tone.isUndef(this[prop])) { + Object.defineProperty(this, prop, { + get: function () { + if (typeof context[prop] === 'function') { + return context[prop].bind(context); + } else { + return context[prop]; + } + }, + set: function (val) { + context[prop] = val; + } + }); + } + }; + /** + * The current audio context time + * @return {Number} + */ + Tone.Context.prototype.now = function () { + return this._context.currentTime + this.lookAhead; + }; + /** + * Promise which is invoked when the context is running. + * Tries to resume the context if it's not started. + * @return {Promise} + */ + Tone.Context.prototype.ready = function () { + return new Promise(function (done) { + if (this._context.state === 'running') { + done(); + } else { + this._context.resume().then(function () { + done(); + }); + } + }.bind(this)); + }; + /** + * Promise which is invoked when the context is running. + * Tries to resume the context if it's not started. + * @return {Promise} + */ + Tone.Context.prototype.close = function () { + return this._context.close().then(function () { + Tone.Context.emit('close', this); + }.bind(this)); + }; + /** + * Generate a looped buffer at some constant value. + * @param {Number} val + * @return {BufferSourceNode} + */ + Tone.Context.prototype.getConstant = function (val) { + if (this._constants[val]) { + return this._constants[val]; + } else { + var buffer = this._context.createBuffer(1, 128, this._context.sampleRate); + var arr = buffer.getChannelData(0); + for (var i = 0; i < arr.length; i++) { + arr[i] = val; + } + var constant = this._context.createBufferSource(); + constant.channelCount = 1; + constant.channelCountMode = 'explicit'; + constant.buffer = buffer; + constant.loop = true; + constant.start(0); + this._constants[val] = constant; + return constant; + } + }; + /** + * The private loop which keeps track of the context scheduled timeouts + * Is invoked from the clock source + * @private + */ + Tone.Context.prototype._timeoutLoop = function () { + var now = this.now(); + while (this._timeouts && this._timeouts.length && this._timeouts.peek().time <= now) { + this._timeouts.shift().callback(); + } + }; + /** + * A setTimeout which is gaurenteed by the clock source. + * Also runs in the offline context. + * @param {Function} fn The callback to invoke + * @param {Seconds} timeout The timeout in seconds + * @returns {Number} ID to use when invoking Tone.Context.clearTimeout + */ + Tone.Context.prototype.setTimeout = function (fn, timeout) { + this._timeoutIds++; + var now = this.now(); + this._timeouts.add({ + callback: fn, + time: now + timeout, + id: this._timeoutIds + }); + return this._timeoutIds; + }; + /** + * Clears a previously scheduled timeout with Tone.context.setTimeout + * @param {Number} id The ID returned from setTimeout + * @return {Tone.Context} this + */ + Tone.Context.prototype.clearTimeout = function (id) { + this._timeouts.forEach(function (event) { + if (event.id === id) { + this.remove(event); + } + }); + return this; + }; + /** + * How often the Web Worker callback is invoked. + * This number corresponds to how responsive the scheduling + * can be. Context.updateInterval + Context.lookAhead gives you the + * total latency between scheduling an event and hearing it. + * @type {Number} + * @memberOf Tone.Context# + * @name updateInterval + */ + Object.defineProperty(Tone.Context.prototype, 'updateInterval', { + get: function () { + return this._ticker.updateInterval; + }, + set: function (interval) { + this._ticker.updateInterval = interval; + } + }); + /** + * What the source of the clock is, either "worker" (Web Worker [default]), + * "timeout" (setTimeout), or "offline" (none). + * @type {String} + * @memberOf Tone.Context# + * @name clockSource + */ + Object.defineProperty(Tone.Context.prototype, 'clockSource', { + get: function () { + return this._ticker.type; + }, + set: function (type) { + this._ticker.type = type; + } + }); + /** + * The type of playback, which affects tradeoffs between audio + * output latency and responsiveness. + * + * In addition to setting the value in seconds, the latencyHint also + * accepts the strings "interactive" (prioritizes low latency), + * "playback" (prioritizes sustained playback), "balanced" (balances + * latency and performance), and "fastest" (lowest latency, might glitch more often). + * @type {String|Seconds} + * @memberOf Tone.Context# + * @name latencyHint + * @example + * //set the lookAhead to 0.3 seconds + * Tone.context.latencyHint = 0.3; + */ + Object.defineProperty(Tone.Context.prototype, 'latencyHint', { + get: function () { + return this._latencyHint; + }, + set: function (hint) { + var lookAhead = hint; + this._latencyHint = hint; + if (Tone.isString(hint)) { + switch (hint) { + case 'interactive': + lookAhead = 0.1; + this._context.latencyHint = hint; + break; + case 'playback': + lookAhead = 0.8; + this._context.latencyHint = hint; + break; + case 'balanced': + lookAhead = 0.25; + this._context.latencyHint = hint; + break; + case 'fastest': + this._context.latencyHint = 'interactive'; + lookAhead = 0.01; + break; + } + } + this.lookAhead = lookAhead; + this.updateInterval = lookAhead / 3; + } + }); + /** + * Unlike other dispose methods, this returns a Promise + * which executes when the context is closed and disposed + * @returns {Promise} this + */ + Tone.Context.prototype.dispose = function () { + return this.close().then(function () { + Tone.Emitter.prototype.dispose.call(this); + this._ticker.dispose(); + this._ticker = null; + this._timeouts.dispose(); + this._timeouts = null; + for (var con in this._constants) { + this._constants[con].disconnect(); + } + this._constants = null; + }.bind(this)); + }; + /** + * @class A class which provides a reliable callback using either + * a Web Worker, or if that isn't supported, falls back to setTimeout. + * @private + */ + var Ticker = function (callback, type, updateInterval) { + /** + * Either "worker" or "timeout" + * @type {String} + * @private + */ + this._type = type; + /** + * The update interval of the worker + * @private + * @type {Number} + */ + this._updateInterval = updateInterval; + /** + * The callback to invoke at regular intervals + * @type {Function} + * @private + */ + this._callback = Tone.defaultArg(callback, Tone.noOp); + //create the clock source for the first time + this._createClock(); + }; + /** + * The possible ticker types + * @private + * @type {Object} + */ + Ticker.Type = { + Worker: 'worker', + Timeout: 'timeout', + Offline: 'offline' + }; + /** + * Generate a web worker + * @return {WebWorker} + * @private + */ + Ticker.prototype._createWorker = function () { + //URL Shim + window.URL = window.URL || window.webkitURL; + var blob = new Blob([//the initial timeout time + 'var timeoutTime = ' + (this._updateInterval * 1000).toFixed(1) + ';' + //onmessage callback + 'self.onmessage = function(msg){' + '\ttimeoutTime = parseInt(msg.data);' + '};' + //the tick function which posts a message + //and schedules a new tick + 'function tick(){' + '\tsetTimeout(tick, timeoutTime);' + '\tself.postMessage(\'tick\');' + '}' + //call tick initially + 'tick();']); + var blobUrl = URL.createObjectURL(blob); + var worker = new Worker(blobUrl); + worker.onmessage = this._callback.bind(this); + this._worker = worker; + }; + /** + * Create a timeout loop + * @private + */ + Ticker.prototype._createTimeout = function () { + this._timeout = setTimeout(function () { + this._createTimeout(); + this._callback(); + }.bind(this), this._updateInterval * 1000); + }; + /** + * Create the clock source. + * @private + */ + Ticker.prototype._createClock = function () { + if (this._type === Ticker.Type.Worker) { + try { + this._createWorker(); + } catch (e) { + // workers not supported, fallback to timeout + this._type = Ticker.Type.Timeout; + this._createClock(); + } + } else if (this._type === Ticker.Type.Timeout) { + this._createTimeout(); + } + }; + /** + * @memberOf Ticker# + * @type {Number} + * @name updateInterval + * @private + */ + Object.defineProperty(Ticker.prototype, 'updateInterval', { + get: function () { + return this._updateInterval; + }, + set: function (interval) { + this._updateInterval = Math.max(interval, 128 / 44100); + if (this._type === Ticker.Type.Worker) { + this._worker.postMessage(Math.max(interval * 1000, 1)); + } + } + }); + /** + * The type of the ticker, either a worker or a timeout + * @memberOf Ticker# + * @type {Number} + * @name type + * @private + */ + Object.defineProperty(Ticker.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + this._disposeClock(); + this._type = type; + this._createClock(); + } + }); + /** + * Clean up the current clock source + * @private + */ + Ticker.prototype._disposeClock = function () { + if (this._timeout) { + clearTimeout(this._timeout); + this._timeout = null; + } + if (this._worker) { + this._worker.terminate(); + this._worker.onmessage = null; + this._worker = null; + } + }; + /** + * Clean up + * @private + */ + Ticker.prototype.dispose = function () { + this._disposeClock(); + this._callback = null; + }; + /** + * Shim all connect/disconnect and some deprecated methods which are still in + * some older implementations. + * @private + */ + Tone.getContext(function () { + var nativeConnect = AudioNode.prototype.connect; + var nativeDisconnect = AudioNode.prototype.disconnect; + //replace the old connect method + function toneConnect(B, outNum, inNum) { + if (B.input) { + inNum = Tone.defaultArg(inNum, 0); + if (Tone.isArray(B.input)) { + return this.connect(B.input[inNum]); + } else { + return this.connect(B.input, outNum, inNum); + } + } else { + try { + if (B instanceof AudioNode) { + nativeConnect.call(this, B, outNum, inNum); + return B; + } else { + nativeConnect.call(this, B, outNum); + return B; + } + } catch (e) { + throw new Error('error connecting to node: ' + B + '\n' + e); + } + } + } + //replace the old disconnect method + function toneDisconnect(B, outNum, inNum) { + if (B && B.input && Tone.isArray(B.input)) { + inNum = Tone.defaultArg(inNum, 0); + this.disconnect(B.input[inNum], outNum, 0); + } else if (B && B.input) { + this.disconnect(B.input, outNum, inNum); + } else { + try { + nativeDisconnect.apply(this, arguments); + } catch (e) { + throw new Error('error disconnecting node: ' + B + '\n' + e); + } + } + } + if (AudioNode.prototype.connect !== toneConnect) { + AudioNode.prototype.connect = toneConnect; + AudioNode.prototype.disconnect = toneDisconnect; + } + }); + // set the audio context initially, and if one is not already created + if (Tone.supported && !Tone.initialized) { + Tone.context = new Tone.Context(); + // log on first initialization + // allow optional silencing of this log + if (!window.TONE_SILENCE_VERSION_LOGGING) { + // eslint-disable-next-line no-console + console.log('%c * Tone.js ' + Tone.version + ' * ', 'background: #000; color: #fff'); + } + } else if (!Tone.supported) { + // eslint-disable-next-line no-console + console.warn('This browser does not support Tone.js'); + } + return Tone.Context; + }); + Module(function (Tone) { + /** + * @class Tone.AudioNode is the base class for classes which process audio. + * AudioNodes have inputs and outputs. + * @param {AudioContext=} context The audio context to use with the class + * @extends {Tone} + */ + Tone.AudioNode = function () { + Tone.call(this); + //use the default context if one is not passed in + var options = Tone.defaults(arguments, ['context'], { 'context': Tone.context }); + /** + * The AudioContext of this instance + * @private + * @type {AudioContext} + */ + this._context = options.context; + }; + Tone.extend(Tone.AudioNode); + /** + * Get the audio context belonging to this instance. + * @type {Tone.Context} + * @memberOf Tone.AudioNode# + * @name context + * @readOnly + */ + Object.defineProperty(Tone.AudioNode.prototype, 'context', { + get: function () { + return this._context; + } + }); + /** + * Create input and outputs for this object. + * @param {Number} [input=0] The number of inputs + * @param {Number} [outputs=0] The number of outputs + * @return {Tone.AudioNode} this + * @private + */ + Tone.AudioNode.prototype.createInsOuts = function (inputs, outputs) { + if (inputs === 1) { + this.input = this.context.createGain(); + } else if (inputs > 1) { + this.input = new Array(inputs); + } + if (outputs === 1) { + this.output = this.context.createGain(); + } else if (outputs > 1) { + this.output = new Array(outputs); + } + }; + /** + * channelCount is the number of channels used when up-mixing and down-mixing + * connections to any inputs to the node. The default value is 2 except for + * specific nodes where its value is specially determined. + * + * @memberof Tone.AudioNode# + * @type {Number} + * @name channelCount + * @readOnly + */ + Object.defineProperty(Tone.AudioNode.prototype, 'channelCount', { + get: function () { + return this.output.channelCount; + }, + set: function (c) { + return this.output.channelCount = c; + } + }); + /** + * channelCountMode determines how channels will be counted when up-mixing and + * down-mixing connections to any inputs to the node. + * The default value is "max". This attribute has no effect for nodes with no inputs. + * @memberof Tone.AudioNode# + * @type {String} + * @name channelCountMode + * @readOnly + */ + Object.defineProperty(Tone.AudioNode.prototype, 'channelCountMode', { + get: function () { + return this.output.channelCountMode; + }, + set: function (m) { + return this.output.channelCountMode = m; + } + }); + /** + * channelInterpretation determines how individual channels will be treated + * when up-mixing and down-mixing connections to any inputs to the node. + * The default value is "speakers". + * @memberof Tone.AudioNode# + * @type {String} + * @name channelInterpretation + * @readOnly + */ + Object.defineProperty(Tone.AudioNode.prototype, 'channelInterpretation', { + get: function () { + return this.output.channelInterpretation; + }, + set: function (i) { + return this.output.channelInterpretation = i; + } + }); + /** + * The number of inputs feeding into the AudioNode. + * For source nodes, this will be 0. + * @type {Number} + * @name numberOfInputs + * @memberof Tone.AudioNode# + * @readOnly + */ + Object.defineProperty(Tone.AudioNode.prototype, 'numberOfInputs', { + get: function () { + if (this.input) { + if (Tone.isArray(this.input)) { + return this.input.length; + } else { + return 1; + } + } else { + return 0; + } + } + }); + /** + * The number of outputs coming out of the AudioNode. + * @type {Number} + * @name numberOfOutputs + * @memberof Tone.AudioNode# + * @readOnly + */ + Object.defineProperty(Tone.AudioNode.prototype, 'numberOfOutputs', { + get: function () { + if (this.output) { + if (Tone.isArray(this.output)) { + return this.output.length; + } else { + return 1; + } + } else { + return 0; + } + } + }); + /** + * Called when an audio param connects to this node + * @private + */ + Tone.AudioNode.prototype._onConnect = function () { + }; + /** + * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode + * @param {Tone | AudioParam | AudioNode} unit + * @param {number} [outputNum=0] optionally which output to connect from + * @param {number} [inputNum=0] optionally which input to connect to + * @returns {Tone.AudioNode} this + */ + Tone.AudioNode.prototype.connect = function (unit, outputNum, inputNum) { + if (unit._onConnect) { + unit._onConnect(this); + } + if (Tone.isArray(this.output)) { + outputNum = Tone.defaultArg(outputNum, 0); + this.output[outputNum].connect(unit, 0, inputNum); + } else { + this.output.connect(unit, outputNum, inputNum); + } + return this; + }; + /** + * disconnect the output + * @param {Number|AudioNode} output Either the output index to disconnect + * if the output is an array, or the + * node to disconnect from. + * @returns {Tone.AudioNode} this + */ + Tone.AudioNode.prototype.disconnect = function (destination, outputNum, inputNum) { + if (Tone.isArray(this.output)) { + if (Tone.isNumber(destination)) { + this.output[destination].disconnect(); + } else { + outputNum = Tone.defaultArg(outputNum, 0); + this.output[outputNum].disconnect(destination, 0, inputNum); + } + } else { + this.output.disconnect.apply(this.output, arguments); + } + }; + /** + * Connect the output of this node to the rest of the nodes in series. + * @example + * //connect a node to an effect, panVol and then to the master output + * node.chain(effect, panVol, Tone.Master); + * @param {...AudioParam|Tone|AudioNode} nodes + * @returns {Tone.AudioNode} this + * @private + */ + Tone.AudioNode.prototype.chain = function () { + var currentUnit = this; + for (var i = 0; i < arguments.length; i++) { + var toUnit = arguments[i]; + currentUnit.connect(toUnit); + currentUnit = toUnit; + } + return this; + }; + /** + * connect the output of this node to the rest of the nodes in parallel. + * @param {...AudioParam|Tone|AudioNode} nodes + * @returns {Tone.AudioNode} this + * @private + */ + Tone.AudioNode.prototype.fan = function () { + for (var i = 0; i < arguments.length; i++) { + this.connect(arguments[i]); + } + return this; + }; + if (window.AudioNode) { + //give native nodes chain and fan methods + AudioNode.prototype.chain = Tone.AudioNode.prototype.chain; + AudioNode.prototype.fan = Tone.AudioNode.prototype.fan; + } + /** + * Dispose and disconnect + * @return {Tone.AudioNode} this + */ + Tone.AudioNode.prototype.dispose = function () { + if (Tone.isDefined(this.input)) { + if (this.input instanceof AudioNode) { + this.input.disconnect(); + } + this.input = null; + } + if (Tone.isDefined(this.output)) { + if (this.output instanceof AudioNode) { + this.output.disconnect(); + } + this.output = null; + } + this._context = null; + return this; + }; + return Tone.AudioNode; + }); + Module(function (Tone) { + + /** + * @class Base class for all Signals. Used Internally. + * + * @constructor + * @extends {Tone} + */ + Tone.SignalBase = function () { + Tone.AudioNode.call(this); + }; + Tone.extend(Tone.SignalBase, Tone.AudioNode); + /** + * When signals connect to other signals or AudioParams, + * they take over the output value of that signal or AudioParam. + * For all other nodes, the behavior is the same as a default <code>connect</code>. + * + * @override + * @param {AudioParam|AudioNode|Tone.Signal|Tone} node + * @param {number} [outputNumber=0] The output number to connect from. + * @param {number} [inputNumber=0] The input number to connect to. + * @returns {Tone.SignalBase} this + */ + Tone.SignalBase.prototype.connect = function (node, outputNumber, inputNumber) { + //zero it out so that the signal can have full control + if (Tone.Signal && Tone.Signal === node.constructor || Tone.Param && Tone.Param === node.constructor) { + //cancel changes + node._param.cancelScheduledValues(0); + //reset the value + node._param.value = 0; + //mark the value as overridden + node.overridden = true; + } else if (node instanceof AudioParam) { + node.cancelScheduledValues(0); + node.value = 0; + } + Tone.AudioNode.prototype.connect.call(this, node, outputNumber, inputNumber); + return this; + }; + return Tone.SignalBase; + }); + Module(function (Tone) { + if (Tone.supported) { + //fixes safari only bug which is still present in 11 + var ua = navigator.userAgent.toLowerCase(); + var isSafari = ua.includes('safari') && !ua.includes('chrome'); + if (isSafari) { + var WaveShaperNode = function (context) { + this._internalNode = this.input = this.output = context._native_createWaveShaper(); + this._curve = null; + for (var prop in this._internalNode) { + this._defineProperty(this._internalNode, prop); + } + }; + Object.defineProperty(WaveShaperNode.prototype, 'curve', { + get: function () { + return this._curve; + }, + set: function (curve) { + this._curve = curve; + var array = new Float32Array(curve.length + 1); + array.set(curve, 1); + array[0] = curve[0]; + this._internalNode.curve = array; + } + }); + WaveShaperNode.prototype._defineProperty = function (context, prop) { + if (Tone.isUndef(this[prop])) { + Object.defineProperty(this, prop, { + get: function () { + if (typeof context[prop] === 'function') { + return context[prop].bind(context); + } else { + return context[prop]; + } + }, + set: function (val) { + context[prop] = val; + } + }); + } + }; + AudioContext.prototype._native_createWaveShaper = AudioContext.prototype.createWaveShaper; + AudioContext.prototype.createWaveShaper = function () { + return new WaveShaperNode(this); + }; + } + } + }); + Module(function (Tone) { + + /** + * @class Wraps the native Web Audio API + * [WaveShaperNode](http://webaudio.github.io/web-audio-api/#the-waveshapernode-interface). + * + * @extends {Tone.SignalBase} + * @constructor + * @param {function|Array|Number} mapping The function used to define the values. + * The mapping function should take two arguments: + * the first is the value at the current position + * and the second is the array position. + * If the argument is an array, that array will be + * set as the wave shaping function. The input + * signal is an AudioRange [-1, 1] value and the output + * signal can take on any numerical values. + * + * @param {Number} [bufferLen=1024] The length of the WaveShaperNode buffer. + * @example + * var timesTwo = new Tone.WaveShaper(function(val){ + * return val * 2; + * }, 2048); + * @example + * //a waveshaper can also be constructed with an array of values + * var invert = new Tone.WaveShaper([1, -1]); + */ + Tone.WaveShaper = function (mapping, bufferLen) { + Tone.SignalBase.call(this); + /** + * the waveshaper + * @type {WaveShaperNode} + * @private + */ + this._shaper = this.input = this.output = this.context.createWaveShaper(); + /** + * the waveshapers curve + * @type {Float32Array} + * @private + */ + this._curve = null; + if (Array.isArray(mapping)) { + this.curve = mapping; + } else if (isFinite(mapping) || Tone.isUndef(mapping)) { + this._curve = new Float32Array(Tone.defaultArg(mapping, 1024)); + } else if (Tone.isFunction(mapping)) { + this._curve = new Float32Array(Tone.defaultArg(bufferLen, 1024)); + this.setMap(mapping); + } + }; + Tone.extend(Tone.WaveShaper, Tone.SignalBase); + /** + * Uses a mapping function to set the value of the curve. + * @param {function} mapping The function used to define the values. + * The mapping function take two arguments: + * the first is the value at the current position + * which goes from -1 to 1 over the number of elements + * in the curve array. The second argument is the array position. + * @returns {Tone.WaveShaper} this + * @example + * //map the input signal from [-1, 1] to [0, 10] + * shaper.setMap(function(val, index){ + * return (val + 1) * 5; + * }) + */ + Tone.WaveShaper.prototype.setMap = function (mapping) { + var array = new Array(this._curve.length); + for (var i = 0, len = this._curve.length; i < len; i++) { + var normalized = i / (len - 1) * 2 - 1; + array[i] = mapping(normalized, i); + } + this.curve = array; + return this; + }; + /** + * The array to set as the waveshaper curve. For linear curves + * array length does not make much difference, but for complex curves + * longer arrays will provide smoother interpolation. + * @memberOf Tone.WaveShaper# + * @type {Array} + * @name curve + */ + Object.defineProperty(Tone.WaveShaper.prototype, 'curve', { + get: function () { + return this._shaper.curve; + }, + set: function (mapping) { + this._curve = new Float32Array(mapping); + this._shaper.curve = this._curve; + } + }); + /** + * Specifies what type of oversampling (if any) should be used when + * applying the shaping curve. Can either be "none", "2x" or "4x". + * @memberOf Tone.WaveShaper# + * @type {string} + * @name oversample + */ + Object.defineProperty(Tone.WaveShaper.prototype, 'oversample', { + get: function () { + return this._shaper.oversample; + }, + set: function (oversampling) { + if ([ + 'none', + '2x', + '4x' + ].includes(oversampling)) { + this._shaper.oversample = oversampling; + } else { + throw new RangeError('Tone.WaveShaper: oversampling must be either \'none\', \'2x\', or \'4x\''); + } + } + }); + /** + * Clean up. + * @returns {Tone.WaveShaper} this + */ + Tone.WaveShaper.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._shaper.disconnect(); + this._shaper = null; + this._curve = null; + return this; + }; + return Tone.WaveShaper; + }); + Module(function (Tone) { + /** + * @class Tone.TimeBase is a flexible encoding of time + * which can be evaluated to and from a string. + * @extends {Tone} + * @param {Time} val The time value as a number or string + * @param {String=} units Unit values + * @example + * Tone.TimeBase(4, "n") + * Tone.TimeBase(2, "t") + * Tone.TimeBase("2t") + * Tone.TimeBase("2t") + Tone.TimeBase("4n"); + */ + Tone.TimeBase = function (val, units) { + //allows it to be constructed with or without 'new' + if (this instanceof Tone.TimeBase) { + /** + * The value + * @type {Number|String|Tone.TimeBase} + * @private + */ + this._val = val; + /** + * The units + * @type {String?} + * @private + */ + this._units = units; + //test if the value is a string representation of a number + if (Tone.isUndef(this._units) && Tone.isString(this._val) && // eslint-disable-next-line eqeqeq + parseFloat(this._val) == this._val && this._val.charAt(0) !== '+') { + this._val = parseFloat(this._val); + this._units = this._defaultUnits; + } else if (val && val.constructor === this.constructor) { + //if they're the same type, just copy values over + this._val = val._val; + this._units = val._units; + } else if (val instanceof Tone.TimeBase) { + switch (this._defaultUnits) { + case 's': + this._val = val.toSeconds(); + break; + case 'i': + this._val = val.toTicks(); + break; + case 'hz': + this._val = val.toFrequency(); + break; + case 'midi': + this._val = val.toMidi(); + break; + default: + throw new Error('Unrecognized default units ' + this._defaultUnits); + } + } + } else { + return new Tone.TimeBase(val, units); + } + }; + Tone.extend(Tone.TimeBase); + /////////////////////////////////////////////////////////////////////////// + // ABSTRACT SYNTAX TREE PARSER + /////////////////////////////////////////////////////////////////////////// + /** + * All the primary expressions. + * @private + * @type {Object} + */ + Tone.TimeBase.prototype._expressions = { + 'n': { + regexp: /^(\d+)n(\.?)$/i, + method: function (value, dot) { + value = parseInt(value); + var scalar = dot === '.' ? 1.5 : 1; + if (value === 1) { + return this._beatsToUnits(this._getTimeSignature()) * scalar; + } else { + return this._beatsToUnits(4 / value) * scalar; + } + } + }, + 't': { + regexp: /^(\d+)t$/i, + method: function (value) { + value = parseInt(value); + return this._beatsToUnits(8 / (parseInt(value) * 3)); + } + }, + 'm': { + regexp: /^(\d+)m$/i, + method: function (value) { + return this._beatsToUnits(parseInt(value) * this._getTimeSignature()); + } + }, + 'i': { + regexp: /^(\d+)i$/i, + method: function (value) { + return this._ticksToUnits(parseInt(value)); + } + }, + 'hz': { + regexp: /^(\d+(?:\.\d+)?)hz$/i, + method: function (value) { + return this._frequencyToUnits(parseFloat(value)); + } + }, + 'tr': { + regexp: /^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?$/, + method: function (m, q, s) { + var total = 0; + if (m && m !== '0') { + total += this._beatsToUnits(this._getTimeSignature() * parseFloat(m)); + } + if (q && q !== '0') { + total += this._beatsToUnits(parseFloat(q)); + } + if (s && s !== '0') { + total += this._beatsToUnits(parseFloat(s) / 4); + } + return total; + } + }, + 's': { + regexp: /^(\d+(?:\.\d+)?)s$/, + method: function (value) { + return this._secondsToUnits(parseFloat(value)); + } + }, + 'samples': { + regexp: /^(\d+)samples$/, + method: function (value) { + return parseInt(value) / this.context.sampleRate; + } + }, + 'default': { + regexp: /^(\d+(?:\.\d+)?)$/, + method: function (value) { + return this._expressions[this._defaultUnits].method.call(this, value); + } + } + }; + /** + * The default units if none are given. + * @type {String} + * @private + */ + Tone.TimeBase.prototype._defaultUnits = 's'; + /////////////////////////////////////////////////////////////////////////// + // TRANSPORT FALLBACKS + /////////////////////////////////////////////////////////////////////////// + /** + * Return the bpm, or 120 if Transport is not available + * @type {Number} + * @private + */ + Tone.TimeBase.prototype._getBpm = function () { + if (Tone.Transport) { + return Tone.Transport.bpm.value; + } else { + return 120; + } + }; + /** + * Return the timeSignature or 4 if Transport is not available + * @type {Number} + * @private + */ + Tone.TimeBase.prototype._getTimeSignature = function () { + if (Tone.Transport) { + return Tone.Transport.timeSignature; + } else { + return 4; + } + }; + /** + * Return the PPQ or 192 if Transport is not available + * @type {Number} + * @private + */ + Tone.TimeBase.prototype._getPPQ = function () { + if (Tone.Transport) { + return Tone.Transport.PPQ; + } else { + return 192; + } + }; + /** + * Return the current time in whichever context is relevant + * @type {Number} + * @private + */ + Tone.TimeBase.prototype._now = function () { + return this.now(); + }; + /////////////////////////////////////////////////////////////////////////// + // UNIT CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Returns the value of a frequency in the current units + * @param {Frequency} freq + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._frequencyToUnits = function (freq) { + return 1 / freq; + }; + /** + * Return the value of the beats in the current units + * @param {Number} beats + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._beatsToUnits = function (beats) { + return 60 / this._getBpm() * beats; + }; + /** + * Returns the value of a second in the current units + * @param {Seconds} seconds + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._secondsToUnits = function (seconds) { + return seconds; + }; + /** + * Returns the value of a tick in the current time units + * @param {Ticks} ticks + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._ticksToUnits = function (ticks) { + return ticks * (this._beatsToUnits(1) / this._getPPQ()); + }; + /** + * With no arguments, return 'now' + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._noArg = function () { + return this._now(); + }; + /////////////////////////////////////////////////////////////////////////// + // EXPRESSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Evaluate the time value. Returns the time + * in seconds. + * @return {Seconds} + */ + Tone.TimeBase.prototype.valueOf = function () { + if (Tone.isUndef(this._val)) { + return this._noArg(); + } else if (Tone.isString(this._val) && Tone.isUndef(this._units)) { + for (var units in this._expressions) { + if (this._expressions[units].regexp.test(this._val.trim())) { + this._units = units; + break; + } + } + } + if (Tone.isDefined(this._units)) { + var expr = this._expressions[this._units]; + var matching = this._val.toString().trim().match(expr.regexp); + if (matching) { + return expr.method.apply(this, matching.slice(1)); + } else { + return expr.method.call(this, parseFloat(this._val)); + } + } else { + return this._val; + } + }; + /** + * Return the value in seconds + * @return {Seconds} + */ + Tone.TimeBase.prototype.toSeconds = function () { + return this.valueOf(); + }; + /** + * Return the value in hertz + * @return {Frequency} + */ + Tone.TimeBase.prototype.toFrequency = function () { + return 1 / this.toSeconds(); + }; + /** + * Return the time in samples + * @return {Samples} + */ + Tone.TimeBase.prototype.toSamples = function () { + return this.toSeconds() * this.context.sampleRate; + }; + /** + * Return the time in milliseconds. + * @return {Milliseconds} + */ + Tone.TimeBase.prototype.toMilliseconds = function () { + return this.toSeconds() * 1000; + }; + /** + * Clean up + * @return {Tone.TimeBase} this + */ + Tone.TimeBase.prototype.dispose = function () { + this._val = null; + this._units = null; + }; + return Tone.TimeBase; + }); + Module(function (Tone) { + /** + * @class Tone.Frequency is a primitive type for encoding Frequency values. + * Eventually all time values are evaluated to hertz + * using the `eval` method. + * @constructor + * @extends {Tone.TimeBase} + * @param {String|Number} val The time value. + * @param {String=} units The units of the value. + * @example + * Tone.Frequency("C3") // 261 + * Tone.Frequency(38, "midi") // + * Tone.Frequency("C3").transpose(4); + */ + Tone.Frequency = function (val, units) { + if (this instanceof Tone.Frequency) { + Tone.TimeBase.call(this, val, units); + } else { + return new Tone.Frequency(val, units); + } + }; + Tone.extend(Tone.Frequency, Tone.TimeBase); + /////////////////////////////////////////////////////////////////////////// + // AUGMENT BASE EXPRESSIONS + /////////////////////////////////////////////////////////////////////////// + Tone.Frequency.prototype._expressions = Object.assign({}, Tone.TimeBase.prototype._expressions, { + 'midi': { + regexp: /^(\d+(?:\.\d+)?midi)/, + method: function (value) { + if (this._defaultUnits === 'midi') { + return value; + } else { + return Tone.Frequency.mtof(value); + } + } + }, + 'note': { + regexp: /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i, + method: function (pitch, octave) { + var index = noteToScaleIndex[pitch.toLowerCase()]; + var noteNumber = index + (parseInt(octave) + 1) * 12; + if (this._defaultUnits === 'midi') { + return noteNumber; + } else { + return Tone.Frequency.mtof(noteNumber); + } + } + }, + 'tr': { + regexp: /^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?/, + method: function (m, q, s) { + var total = 1; + if (m && m !== '0') { + total *= this._beatsToUnits(this._getTimeSignature() * parseFloat(m)); + } + if (q && q !== '0') { + total *= this._beatsToUnits(parseFloat(q)); + } + if (s && s !== '0') { + total *= this._beatsToUnits(parseFloat(s) / 4); + } + return total; + } + } + }); + /////////////////////////////////////////////////////////////////////////// + // EXPRESSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Transposes the frequency by the given number of semitones. + * @param {Interval} interval + * @return {Tone.Frequency} A new transposed frequency + * @example + * Tone.Frequency("A4").transpose(3); //"C5" + */ + Tone.Frequency.prototype.transpose = function (interval) { + return new this.constructor(this.valueOf() * Tone.intervalToFrequencyRatio(interval)); + }; + /** + * Takes an array of semitone intervals and returns + * an array of frequencies transposed by those intervals. + * @param {Array} intervals + * @return {Array<Tone.Frequency>} Returns an array of Frequencies + * @example + * Tone.Frequency("A4").harmonize([0, 3, 7]); //["A4", "C5", "E5"] + */ + Tone.Frequency.prototype.harmonize = function (intervals) { + return intervals.map(function (interval) { + return this.transpose(interval); + }.bind(this)); + }; + /////////////////////////////////////////////////////////////////////////// + // UNIT CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Return the value of the frequency as a MIDI note + * @return {MIDI} + * @example + * Tone.Frequency("C4").toMidi(); //60 + */ + Tone.Frequency.prototype.toMidi = function () { + return Tone.Frequency.ftom(this.valueOf()); + }; + /** + * Return the value of the frequency in Scientific Pitch Notation + * @return {Note} + * @example + * Tone.Frequency(69, "midi").toNote(); //"A4" + */ + Tone.Frequency.prototype.toNote = function () { + var freq = this.toFrequency(); + var log = Math.log2(freq / Tone.Frequency.A4); + var noteNumber = Math.round(12 * log) + 57; + var octave = Math.floor(noteNumber / 12); + if (octave < 0) { + noteNumber += -12 * octave; + } + var noteName = scaleIndexToNote[noteNumber % 12]; + return noteName + octave.toString(); + }; + /** + * Return the duration of one cycle in seconds. + * @return {Seconds} + */ + Tone.Frequency.prototype.toSeconds = function () { + return 1 / Tone.TimeBase.prototype.toSeconds.call(this); + }; + /** + * Return the value in Hertz + * @return {Frequency} + */ + Tone.Frequency.prototype.toFrequency = function () { + return Tone.TimeBase.prototype.toFrequency.call(this); + }; + /** + * Return the duration of one cycle in ticks + * @return {Ticks} + */ + Tone.Frequency.prototype.toTicks = function () { + var quarterTime = this._beatsToUnits(1); + var quarters = this.valueOf() / quarterTime; + return Math.floor(quarters * Tone.Transport.PPQ); + }; + /////////////////////////////////////////////////////////////////////////// + // UNIT CONVERSIONS HELPERS + /////////////////////////////////////////////////////////////////////////// + /** + * With no arguments, return 0 + * @return {Number} + * @private + */ + Tone.Frequency.prototype._noArg = function () { + return 0; + }; + /** + * Returns the value of a frequency in the current units + * @param {Frequency} freq + * @return {Number} + * @private + */ + Tone.Frequency.prototype._frequencyToUnits = function (freq) { + return freq; + }; + /** + * Returns the value of a tick in the current time units + * @param {Ticks} ticks + * @return {Number} + * @private + */ + Tone.Frequency.prototype._ticksToUnits = function (ticks) { + return 1 / (ticks * 60 / (Tone.Transport.bpm.value * Tone.Transport.PPQ)); + }; + /** + * Return the value of the beats in the current units + * @param {Number} beats + * @return {Number} + * @private + */ + Tone.Frequency.prototype._beatsToUnits = function (beats) { + return 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats); + }; + /** + * Returns the value of a second in the current units + * @param {Seconds} seconds + * @return {Number} + * @private + */ + Tone.Frequency.prototype._secondsToUnits = function (seconds) { + return 1 / seconds; + }; + /** + * The default units if none are given. + * @private + */ + Tone.Frequency.prototype._defaultUnits = 'hz'; + /////////////////////////////////////////////////////////////////////////// + // FREQUENCY CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Note to scale index + * @type {Object} + */ + var noteToScaleIndex = { + 'cbb': -2, + 'cb': -1, + 'c': 0, + 'c#': 1, + 'cx': 2, + 'dbb': 0, + 'db': 1, + 'd': 2, + 'd#': 3, + 'dx': 4, + 'ebb': 2, + 'eb': 3, + 'e': 4, + 'e#': 5, + 'ex': 6, + 'fbb': 3, + 'fb': 4, + 'f': 5, + 'f#': 6, + 'fx': 7, + 'gbb': 5, + 'gb': 6, + 'g': 7, + 'g#': 8, + 'gx': 9, + 'abb': 7, + 'ab': 8, + 'a': 9, + 'a#': 10, + 'ax': 11, + 'bbb': 9, + 'bb': 10, + 'b': 11, + 'b#': 12, + 'bx': 13 + }; + /** + * scale index to note (sharps) + * @type {Array} + */ + var scaleIndexToNote = [ + 'C', + 'C#', + 'D', + 'D#', + 'E', + 'F', + 'F#', + 'G', + 'G#', + 'A', + 'A#', + 'B' + ]; + /** + * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch) + * A4's values in Hertz. + * @type {Frequency} + * @static + */ + Tone.Frequency.A4 = 440; + /** + * Convert a MIDI note to frequency value. + * @param {MIDI} midi The midi number to convert. + * @return {Frequency} the corresponding frequency value + * @static + * @example + * Tone.Frequency.mtof(69); // returns 440 + */ + Tone.Frequency.mtof = function (midi) { + return Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12); + }; + /** + * Convert a frequency value to a MIDI note. + * @param {Frequency} frequency The value to frequency value to convert. + * @returns {MIDI} + * @static + * @example + * Tone.Frequency.ftom(440); // returns 69 + */ + Tone.Frequency.ftom = function (frequency) { + return 69 + Math.round(12 * Math.log2(frequency / Tone.Frequency.A4)); + }; + return Tone.Frequency; + }); + Module(function (Tone) { + /** + * @class Tone.Time is a primitive type for encoding Time values. + * Tone.Time can be constructed with or without the `new` keyword. Tone.Time can be passed + * into the parameter of any method which takes time as an argument. + * @constructor + * @extends {Tone.TimeBase} + * @param {String|Number} val The time value. + * @param {String=} units The units of the value. + * @example + * var t = Tone.Time("4n");//a quarter note + */ + Tone.Time = function (val, units) { + if (this instanceof Tone.Time) { + Tone.TimeBase.call(this, val, units); + } else { + return new Tone.Time(val, units); + } + }; + Tone.extend(Tone.Time, Tone.TimeBase); + /** + * Extend the base expressions + */ + Tone.Time.prototype._expressions = Object.assign({}, Tone.TimeBase.prototype._expressions, { + 'quantize': { + regexp: /^@(.+)/, + method: function (capture) { + if (Tone.Transport) { + var quantTo = new this.constructor(capture); + return Tone.Transport.nextSubdivision(quantTo); + } else { + return 0; + } + } + }, + 'now': { + regexp: /^\+(.+)/, + method: function (capture) { + return this._now() + new this.constructor(capture); + } + } + }); + /** + * Quantize the time by the given subdivision. Optionally add a + * percentage which will move the time value towards the ideal + * quantized value by that percentage. + * @param {Number|Time} val The subdivision to quantize to + * @param {NormalRange} [percent=1] Move the time value + * towards the quantized value by + * a percentage. + * @return {Number} this + * @example + * Tone.Time(21).quantize(2) //returns 22 + * Tone.Time(0.6).quantize("4n", 0.5) //returns 0.55 + */ + Tone.Time.prototype.quantize = function (subdiv, percent) { + percent = Tone.defaultArg(percent, 1); + var subdivision = new this.constructor(subdiv); + var value = this.valueOf(); + var multiple = Math.round(value / subdivision); + var ideal = multiple * subdivision; + var diff = ideal - value; + return value + diff * percent; + }; + /////////////////////////////////////////////////////////////////////////// + // CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Convert a Time to Notation. The notation values are will be the + * closest representation between 1m to 128th note. + * @return {Notation} + * @example + * //if the Transport is at 120bpm: + * Tone.Time(2).toNotation();//returns "1m" + */ + Tone.Time.prototype.toNotation = function () { + var time = this.toSeconds(); + var testNotations = ['1m']; + for (var power = 1; power < 8; power++) { + var subdiv = Math.pow(2, power); + testNotations.push(subdiv + 'n.'); + testNotations.push(subdiv + 'n'); + testNotations.push(subdiv + 't'); + } + testNotations.push('0'); + //find the closets notation representation + var closest = testNotations[0]; + var closestSeconds = Tone.Time(testNotations[0]).toSeconds(); + testNotations.forEach(function (notation) { + var notationSeconds = Tone.Time(notation).toSeconds(); + if (Math.abs(notationSeconds - time) < Math.abs(closestSeconds - time)) { + closest = notation; + closestSeconds = notationSeconds; + } + }); + return closest; + }; + /** + * Return the time encoded as Bars:Beats:Sixteenths. + * @return {BarsBeatsSixteenths} + */ + Tone.Time.prototype.toBarsBeatsSixteenths = function () { + var quarterTime = this._beatsToUnits(1); + var quarters = this.valueOf() / quarterTime; + var measures = Math.floor(quarters / this._getTimeSignature()); + var sixteenths = quarters % 1 * 4; + quarters = Math.floor(quarters) % this._getTimeSignature(); + sixteenths = sixteenths.toString(); + if (sixteenths.length > 3) { + // the additional parseFloat removes insignificant trailing zeroes + sixteenths = parseFloat(parseFloat(sixteenths).toFixed(3)); + } + var progress = [ + measures, + quarters, + sixteenths + ]; + return progress.join(':'); + }; + /** + * Return the time in ticks. + * @return {Ticks} + */ + Tone.Time.prototype.toTicks = function () { + var quarterTime = this._beatsToUnits(1); + var quarters = this.valueOf() / quarterTime; + return Math.round(quarters * this._getPPQ()); + }; + /** + * Return the time in seconds. + * @return {Seconds} + */ + Tone.Time.prototype.toSeconds = function () { + return this.valueOf(); + }; + /** + * Return the value as a midi note. + * @return {Midi} + */ + Tone.Time.prototype.toMidi = function () { + return Tone.Frequency.ftom(this.toFrequency()); + }; + return Tone.Time; + }); + Module(function (Tone) { + /** + * @class Tone.TransportTime is a the time along the Transport's + * timeline. It is similar to Tone.Time, but instead of evaluating + * against the AudioContext's clock, it is evaluated against + * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime). + * @constructor + * @param {Time} val The time value as a number or string + * @param {String=} units Unit values + * @extends {Tone.Time} + */ + Tone.TransportTime = function (val, units) { + if (this instanceof Tone.TransportTime) { + Tone.Time.call(this, val, units); + } else { + return new Tone.TransportTime(val, units); + } + }; + Tone.extend(Tone.TransportTime, Tone.Time); + /** + * Return the current time in whichever context is relevant + * @type {Number} + * @private + */ + Tone.TransportTime.prototype._now = function () { + return Tone.Transport.seconds; + }; + return Tone.TransportTime; + }); + Module(function (Tone) { + /////////////////////////////////////////////////////////////////////////// + // TYPES + /////////////////////////////////////////////////////////////////////////// + /** + * Units which a value can take on. + * @enum {String} + */ + Tone.Type = { + /** + * Default units + * @typedef {Default} + */ + Default: 'number', + /** + * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time). + * + * * Numbers, which will be taken literally as the time (in seconds). + * * Notation, ("4n", "8t") describes time in BPM and time signature relative values. + * * TransportTime, ("4:3:2") will also provide tempo and time signature relative times + * in the form BARS:QUARTERS:SIXTEENTHS. + * * Frequency, ("8hz") is converted to the length of the cycle in seconds. + * * Now-Relative, ("+1") prefix any of the above with "+" and it will be interpreted as + * "the current time plus whatever expression follows". + * * Expressions, ("3:0 + 2 - (1m / 7)") any of the above can also be combined + * into a mathematical expression which will be evaluated to compute the desired time. + * * No Argument, for methods which accept time, no argument will be interpreted as + * "now" (i.e. the currentTime). + * + * @typedef {Time} + */ + Time: 'time', + /** + * Frequency can be described similar to time, except ultimately the + * values are converted to frequency instead of seconds. A number + * is taken literally as the value in hertz. Additionally any of the + * Time encodings can be used. Note names in the form + * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their + * frequency value. + * @typedef {Frequency} + */ + Frequency: 'frequency', + /** + * TransportTime describes a position along the Transport's timeline. It is + * similar to Time in that it uses all the same encodings, but TransportTime specifically + * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. + * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime) + * @typedef {TransportTime} + */ + TransportTime: 'transportTime', + /** + * Ticks are the basic subunit of the Transport. They are + * the smallest unit of time that the Transport supports. + * @typedef {Ticks} + */ + Ticks: 'ticks', + /** + * Normal values are within the range [0, 1]. + * @typedef {NormalRange} + */ + NormalRange: 'normalRange', + /** + * AudioRange values are between [-1, 1]. + * @typedef {AudioRange} + */ + AudioRange: 'audioRange', + /** + * Decibels are a logarithmic unit of measurement which is useful for volume + * because of the logarithmic way that we perceive loudness. 0 decibels + * means no change in volume. -10db is approximately half as loud and 10db + * is twice is loud. + * @typedef {Decibels} + */ + Decibels: 'db', + /** + * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up. + * @typedef {Interval} + */ + Interval: 'interval', + /** + * Beats per minute. + * @typedef {BPM} + */ + BPM: 'bpm', + /** + * The value must be greater than or equal to 0. + * @typedef {Positive} + */ + Positive: 'positive', + /** + * Gain is the ratio between input and output of a signal. + * A gain of 0 is the same as silencing the signal. A gain of + * 1, causes no change to the incoming signal. + * @typedef {Gain} + */ + Gain: 'gain', + /** + * A cent is a hundredth of a semitone. + * @typedef {Cents} + */ + Cents: 'cents', + /** + * Angle between 0 and 360. + * @typedef {Degrees} + */ + Degrees: 'degrees', + /** + * A number representing a midi note. + * @typedef {MIDI} + */ + MIDI: 'midi', + /** + * A colon-separated representation of time in the form of + * Bars:Beats:Sixteenths. + * @typedef {BarsBeatsSixteenths} + */ + BarsBeatsSixteenths: 'barsBeatsSixteenths', + /** + * Sampling is the reduction of a continuous signal to a discrete signal. + * Audio is typically sampled 44100 times per second. + * @typedef {Samples} + */ + Samples: 'samples', + /** + * Hertz are a frequency representation defined as one cycle per second. + * @typedef {Hertz} + */ + Hertz: 'hertz', + /** + * A frequency represented by a letter name, + * accidental and octave. This system is known as + * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation). + * @typedef {Note} + */ + Note: 'note', + /** + * One millisecond is a thousandth of a second. + * @typedef {Milliseconds} + */ + Milliseconds: 'milliseconds', + /** + * Seconds are the time unit of the AudioContext. In the end, + * all values need to be evaluated to seconds. + * @typedef {Seconds} + */ + Seconds: 'seconds', + /** + * A string representing a duration relative to a measure. + * * "4n" = quarter note + * * "2m" = two measures + * * "8t" = eighth-note triplet + * @typedef {Notation} + */ + Notation: 'notation' + }; + /////////////////////////////////////////////////////////////////////////// + // AUGMENT TONE's PROTOTYPE + /////////////////////////////////////////////////////////////////////////// + /** + * Convert Time into seconds. + * + * Unlike the method which it overrides, this takes into account + * transporttime and musical notation. + * + * Time : 1.40 + * Notation: 4n or 1m or 2t + * Now Relative: +3n + * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1) + * + * @param {Time} time + * @return {Seconds} + */ + Tone.prototype.toSeconds = function (time) { + if (Tone.isNumber(time)) { + return time; + } else if (Tone.isUndef(time)) { + return this.now(); + } else if (Tone.isString(time)) { + return new Tone.Time(time).toSeconds(); + } else if (time instanceof Tone.TimeBase) { + return time.toSeconds(); + } + }; + /** + * Convert a frequency representation into a number. + * @param {Frequency} freq + * @return {Hertz} the frequency in hertz + */ + Tone.prototype.toFrequency = function (freq) { + if (Tone.isNumber(freq)) { + return freq; + } else if (Tone.isString(freq) || Tone.isUndef(freq)) { + return new Tone.Frequency(freq).valueOf(); + } else if (freq instanceof Tone.TimeBase) { + return freq.toFrequency(); + } + }; + /** + * Convert a time representation into ticks. + * @param {Time} time + * @return {Ticks} the time in ticks + */ + Tone.prototype.toTicks = function (time) { + if (Tone.isNumber(time) || Tone.isString(time)) { + return new Tone.TransportTime(time).toTicks(); + } else if (Tone.isUndef(time)) { + return Tone.Transport.ticks; + } else if (time instanceof Tone.TimeBase) { + return time.toTicks(); + } + }; + return Tone; + }); + Module(function (Tone) { + + /** + * @class Tone.Param wraps the native Web Audio's AudioParam to provide + * additional unit conversion functionality. It also + * serves as a base-class for classes which have a single, + * automatable parameter. + * @extends {Tone.AudioNode} + * @param {AudioParam} param The parameter to wrap. + * @param {Tone.Type} units The units of the audio param. + * @param {Boolean} convert If the param should be converted. + */ + Tone.Param = function () { + var options = Tone.defaults(arguments, [ + 'param', + 'units', + 'convert' + ], Tone.Param); + Tone.AudioNode.call(this); + /** + * The native parameter to control + * @type {AudioParam} + * @private + */ + this._param = this.input = options.param; + /** + * The units of the parameter + * @type {Tone.Type} + */ + this.units = options.units; + /** + * If the value should be converted or not + * @type {Boolean} + */ + this.convert = options.convert; + /** + * True if the signal value is being overridden by + * a connected signal. + * @readOnly + * @type {boolean} + * @private + */ + this.overridden = false; + /** + * The timeline which tracks all of the automations. + * @type {Tone.Timeline} + * @private + */ + this._events = new Tone.Timeline(1000); + if (Tone.isDefined(options.value) && this._param) { + this.value = options.value; + } + }; + Tone.extend(Tone.Param, Tone.AudioNode); + /** + * Defaults + * @type {Object} + * @const + */ + Tone.Param.defaults = { + 'units': Tone.Type.Default, + 'convert': true, + 'param': undefined + }; + /** + * The current value of the parameter. + * @memberOf Tone.Param# + * @type {Number} + * @name value + */ + Object.defineProperty(Tone.Param.prototype, 'value', { + get: function () { + var now = this.now(); + return this._toUnits(this.getValueAtTime(now)); + }, + set: function (value) { + this._initialValue = this._fromUnits(value); + this.cancelScheduledValues(this.context.currentTime); + this.setValueAtTime(value, this.context.currentTime); + } + }); + /** + * The minimum output value of the parameter + * @memberOf Tone.Param# + * @type {Number} + * @name value + */ + Object.defineProperty(Tone.Param.prototype, 'minValue', { + get: function () { + if (this.units === Tone.Type.Time || this.units === Tone.Type.Frequency || this.units === Tone.Type.NormalRange || this.units === Tone.Type.Positive || this.units === Tone.Type.BPM) { + return 0; + } else if (this.units === Tone.Type.AudioRange) { + return -1; + } else if (this.units === Tone.Type.Decibels) { + return -Infinity; + } else { + return this._param.minValue; + } + } + }); + /** + * The maximum output value of the parameter + * @memberOf Tone.Param# + * @type {Number} + * @name value + */ + Object.defineProperty(Tone.Param.prototype, 'maxValue', { + get: function () { + if (this.units === Tone.Type.NormalRange || this.units === Tone.Type.AudioRange) { + return 1; + } else { + return this._param.maxValue; + } + } + }); + /** + * Convert the given value from the type specified by Tone.Param.units + * into the destination value (such as Gain or Frequency). + * @private + * @param {*} val the value to convert + * @return {number} the number which the value should be set to + */ + Tone.Param.prototype._fromUnits = function (val) { + if ((this.convert || Tone.isUndef(this.convert)) && !this.overridden) { + switch (this.units) { + case Tone.Type.Time: + return this.toSeconds(val); + case Tone.Type.Frequency: + return this.toFrequency(val); + case Tone.Type.Decibels: + return Tone.dbToGain(val); + case Tone.Type.NormalRange: + return Math.min(Math.max(val, 0), 1); + case Tone.Type.AudioRange: + return Math.min(Math.max(val, -1), 1); + case Tone.Type.Positive: + return Math.max(val, 0); + default: + return val; + } + } else { + return val; + } + }; + /** + * Convert the parameters value into the units specified by Tone.Param.units. + * @private + * @param {number} val the value to convert + * @return {number} + */ + Tone.Param.prototype._toUnits = function (val) { + if (this.convert || Tone.isUndef(this.convert)) { + switch (this.units) { + case Tone.Type.Decibels: + return Tone.gainToDb(val); + default: + return val; + } + } else { + return val; + } + }; + /** + * the minimum output value + * @type {Number} + * @private + */ + Tone.Param.prototype._minOutput = 0.00001; + /** + * The event types + * @enum {String} + * @private + */ + Tone.Param.AutomationType = { + Linear: 'linearRampToValueAtTime', + Exponential: 'exponentialRampToValueAtTime', + Target: 'setTargetAtTime', + SetValue: 'setValueAtTime' + }; + /** + * Schedules a parameter value change at the given time. + * @param {*} value The value to set the signal. + * @param {Time} time The time when the change should occur. + * @returns {Tone.Param} this + * @example + * //set the frequency to "G4" in exactly 1 second from now. + * freq.setValueAtTime("G4", "+1"); + */ + Tone.Param.prototype.setValueAtTime = function (value, time) { + time = this.toSeconds(time); + value = this._fromUnits(value); + this._events.add({ + 'type': Tone.Param.AutomationType.SetValue, + 'value': value, + 'time': time + }); + this._param.setValueAtTime(value, time); + return this; + }; + /** + * Get the signals value at the given time. Subsequent scheduling + * may invalidate the returned value. + * @param {Time} time When to get the value + * @returns {Number} The value at the given time + */ + Tone.Param.prototype.getValueAtTime = function (time) { + time = this.toSeconds(time); + var after = this._events.getAfter(time); + var before = this._events.get(time); + var initialValue = Tone.defaultArg(this._initialValue, this._param.defaultValue); + var value = initialValue; + //if it was set by + if (before === null) { + value = initialValue; + } else if (before.type === Tone.Param.AutomationType.Target) { + var previous = this._events.getBefore(before.time); + var previousVal; + if (previous === null) { + previousVal = initialValue; + } else { + previousVal = previous.value; + } + value = this._exponentialApproach(before.time, previousVal, before.value, before.constant, time); + } else if (after === null) { + value = before.value; + } else if (after.type === Tone.Param.AutomationType.Linear) { + value = this._linearInterpolate(before.time, before.value, after.time, after.value, time); + } else if (after.type === Tone.Param.AutomationType.Exponential) { + value = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time); + } else { + value = before.value; + } + return value; + }; + /** + * Creates a schedule point with the current value at the current time. + * This is useful for creating an automation anchor point in order to + * schedule changes from the current value. + * + * @param {number=} now (Optionally) pass the now value in. + * @returns {Tone.Param} this + */ + Tone.Param.prototype.setRampPoint = function (time) { + time = this.toSeconds(time); + var currentVal = this.getValueAtTime(time); + this.cancelAndHoldAtTime(time); + if (currentVal === 0) { + currentVal = this._minOutput; + } + this.setValueAtTime(this._toUnits(currentVal), time); + return this; + }; + /** + * Schedules a linear continuous change in parameter value from the + * previous scheduled parameter value to the given value. + * + * @param {number} value + * @param {Time} endTime + * @returns {Tone.Param} this + */ + Tone.Param.prototype.linearRampToValueAtTime = function (value, endTime) { + value = this._fromUnits(value); + endTime = this.toSeconds(endTime); + this._events.add({ + 'type': Tone.Param.AutomationType.Linear, + 'value': value, + 'time': endTime + }); + this._param.linearRampToValueAtTime(value, endTime); + return this; + }; + /** + * Schedules an exponential continuous change in parameter value from + * the previous scheduled parameter value to the given value. + * + * @param {number} value + * @param {Time} endTime + * @returns {Tone.Param} this + */ + Tone.Param.prototype.exponentialRampToValueAtTime = function (value, endTime) { + value = this._fromUnits(value); + value = Math.max(this._minOutput, value); + endTime = this.toSeconds(endTime); + //store the event + this._events.add({ + 'type': Tone.Param.AutomationType.Exponential, + 'time': endTime, + 'value': value + }); + this._param.exponentialRampToValueAtTime(value, endTime); + return this; + }; + /** + * Schedules an exponential continuous change in parameter value from + * the current time and current value to the given value over the + * duration of the rampTime. + * + * @param {number} value The value to ramp to. + * @param {Time} rampTime the time that it takes the + * value to ramp from it's current value + * @param {Time} [startTime=now] When the ramp should start. + * @returns {Tone.Param} this + * @example + * //exponentially ramp to the value 2 over 4 seconds. + * signal.exponentialRampTo(2, 4); + */ + Tone.Param.prototype.exponentialRampTo = function (value, rampTime, startTime) { + startTime = this.toSeconds(startTime); + this.setRampPoint(startTime); + this.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime)); + return this; + }; + /** + * Schedules an linear continuous change in parameter value from + * the current time and current value to the given value over the + * duration of the rampTime. + * + * @param {number} value The value to ramp to. + * @param {Time} rampTime the time that it takes the + * value to ramp from it's current value + * @param {Time} [startTime=now] When the ramp should start. + * @returns {Tone.Param} this + * @example + * //linearly ramp to the value 4 over 3 seconds. + * signal.linearRampTo(4, 3); + */ + Tone.Param.prototype.linearRampTo = function (value, rampTime, startTime) { + startTime = this.toSeconds(startTime); + this.setRampPoint(startTime); + this.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime)); + return this; + }; + /** + * Start exponentially approaching the target value at the given time. Since it + * is an exponential approach it will continue approaching after the ramp duration. The + * rampTime is the time that it takes to reach over 99% of the way towards the value. + * @param {number} value The value to ramp to. + * @param {Time} rampTime the time that it takes the + * value to ramp from it's current value + * @param {Time} [startTime=now] When the ramp should start. + * @returns {Tone.Param} this + * @example + * //exponentially ramp to the value 2 over 4 seconds. + * signal.exponentialRampTo(2, 4); + */ + Tone.Param.prototype.targetRampTo = function (value, rampTime, startTime) { + startTime = this.toSeconds(startTime); + this.setRampPoint(startTime); + this.exponentialApproachValueAtTime(value, startTime, rampTime); + return this; + }; + /** + * Start exponentially approaching the target value at the given time. Since it + * is an exponential approach it will continue approaching after the ramp duration. The + * rampTime is the time that it takes to reach over 99% of the way towards the value. This methods + * is similar to setTargetAtTime except the third argument is a time instead of a 'timeConstant' + * @param {number} value The value to ramp to. + * @param {Time} time When the ramp should start. + * @param {Time} rampTime the time that it takes the + * value to ramp from it's current value + * @returns {Tone.Param} this + * @example + * //exponentially ramp to the value 2 over 4 seconds. + * signal.exponentialRampTo(2, 4); + */ + Tone.Param.prototype.exponentialApproachValueAtTime = function (value, time, rampTime) { + var timeConstant = Math.log(this.toSeconds(rampTime) + 1) / Math.log(200); + time = this.toSeconds(time); + return this.setTargetAtTime(value, time, timeConstant); + }; + /** + * Start exponentially approaching the target value at the given time with + * a rate having the given time constant. + * @param {number} value + * @param {Time} startTime + * @param {number} timeConstant + * @returns {Tone.Param} this + */ + Tone.Param.prototype.setTargetAtTime = function (value, startTime, timeConstant) { + value = this._fromUnits(value); + // The value will never be able to approach without timeConstant > 0. + if (timeConstant <= 0) { + throw new Error('timeConstant must be greater than 0'); + } + startTime = this.toSeconds(startTime); + this._events.add({ + 'type': Tone.Param.AutomationType.Target, + 'value': value, + 'time': startTime, + 'constant': timeConstant + }); + this._param.setTargetAtTime(value, startTime, timeConstant); + return this; + }; + /** + * Sets an array of arbitrary parameter values starting at the given time + * for the given duration. + * + * @param {Array} values + * @param {Time} startTime + * @param {Time} duration + * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value + * @returns {Tone.Param} this + */ + Tone.Param.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) { + scaling = Tone.defaultArg(scaling, 1); + duration = this.toSeconds(duration); + startTime = this.toSeconds(startTime); + this.setValueAtTime(values[0] * scaling, startTime); + var segTime = duration / (values.length - 1); + for (var i = 1; i < values.length; i++) { + this.linearRampToValueAtTime(values[i] * scaling, startTime + i * segTime); + } + return this; + }; + /** + * Cancels all scheduled parameter changes with times greater than or + * equal to startTime. + * + * @param {Time} time + * @returns {Tone.Param} this + */ + Tone.Param.prototype.cancelScheduledValues = function (time) { + time = this.toSeconds(time); + this._events.cancel(time); + this._param.cancelScheduledValues(time); + return this; + }; + /** + * This is similar to [cancelScheduledValues](#cancelScheduledValues) except + * it holds the automated value at time until the next automated event. + * @param {Time} time + * @returns {Tone.Param} this + */ + Tone.Param.prototype.cancelAndHoldAtTime = function (time) { + var valueAtTime = this.getValueAtTime(time); + //if there is an event at the given time + //and that even is not a "set" + var before = this._events.get(time); + var after = this._events.getAfter(time); + if (before && before.time === time) { + //remove everything after + if (after) { + this._events.cancel(after.time); + } else { + this._events.cancel(time + 0.000001); + } + } else if (after) { + //cancel the next event(s) + this._events.cancel(after.time); + if (!this._param.cancelAndHoldAtTime) { + this._param.cancelScheduledValues(time); + } + if (after.type === Tone.Param.AutomationType.Linear) { + if (!this._param.cancelAndHoldAtTime) { + this.linearRampToValueAtTime(valueAtTime, time); + } else { + this._events.add({ + 'type': Tone.Param.AutomationType.Linear, + 'value': valueAtTime, + 'time': time + }); + } + } else if (after.type === Tone.Param.AutomationType.Exponential) { + if (!this._param.cancelAndHoldAtTime) { + this.exponentialRampToValueAtTime(valueAtTime, time); + } else { + this._events.add({ + 'type': Tone.Param.AutomationType.Exponential, + 'value': valueAtTime, + 'time': time + }); + } + } + } + //set the value at the given time + this._events.add({ + 'type': Tone.Param.AutomationType.SetValue, + 'value': valueAtTime, + 'time': time + }); + if (this._param.cancelAndHoldAtTime) { + this._param.cancelAndHoldAtTime(time); + } else { + this._param.setValueAtTime(valueAtTime, time); + } + return this; + }; + /** + * Ramps to the given value over the duration of the rampTime. + * Automatically selects the best ramp type (exponential or linear) + * depending on the `units` of the signal + * + * @param {number} value + * @param {Time} rampTime The time that it takes the + * value to ramp from it's current value + * @param {Time} [startTime=now] When the ramp should start. + * @returns {Tone.Param} this + * @example + * //ramp to the value either linearly or exponentially + * //depending on the "units" value of the signal + * signal.rampTo(0, 10); + * @example + * //schedule it to ramp starting at a specific time + * signal.rampTo(0, 10, 5) + */ + Tone.Param.prototype.rampTo = function (value, rampTime, startTime) { + rampTime = Tone.defaultArg(rampTime, 0.1); + if (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels) { + this.exponentialRampTo(value, rampTime, startTime); + } else { + this.linearRampTo(value, rampTime, startTime); + } + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // AUTOMATION CURVE CALCULATIONS + // MIT License, copyright (c) 2014 Jordan Santell + /////////////////////////////////////////////////////////////////////////// + // Calculates the the value along the curve produced by setTargetAtTime + Tone.Param.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) { + return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant); + }; + // Calculates the the value along the curve produced by linearRampToValueAtTime + Tone.Param.prototype._linearInterpolate = function (t0, v0, t1, v1, t) { + return v0 + (v1 - v0) * ((t - t0) / (t1 - t0)); + }; + // Calculates the the value along the curve produced by exponentialRampToValueAtTime + Tone.Param.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) { + return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0)); + }; + /** + * Clean up + * @returns {Tone.Param} this + */ + Tone.Param.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._param = null; + this._events = null; + return this; + }; + return Tone.Param; + }); + Module(function (Tone) { + /** + * @class Wrapper around the OfflineAudioContext + * @extends {Tone.Context} + * @param {Number} channels The number of channels to render + * @param {Number} duration The duration to render in samples + * @param {Number} sampleRate the sample rate to render at + */ + Tone.OfflineContext = function (channels, duration, sampleRate) { + /** + * The offline context + * @private + * @type {OfflineAudioContext} + */ + var offlineContext = new OfflineAudioContext(channels, duration * sampleRate, sampleRate); + //wrap the methods/members + Tone.Context.call(this, { + 'context': offlineContext, + 'clockSource': 'offline', + 'lookAhead': 0, + 'updateInterval': 128 / sampleRate + }); + /** + * A private reference to the duration + * @private + * @type {Number} + */ + this._duration = duration; + /** + * An artificial clock source + * @type {Number} + * @private + */ + this._currentTime = 0; + }; + Tone.extend(Tone.OfflineContext, Tone.Context); + /** + * Override the now method to point to the internal clock time + * @return {Number} + */ + Tone.OfflineContext.prototype.now = function () { + return this._currentTime; + }; + /** + * Render the output of the OfflineContext + * @return {Promise} + */ + Tone.OfflineContext.prototype.render = function () { + while (this._duration - this._currentTime >= 0) { + //invoke all the callbacks on that time + this.emit('tick'); + //increment the clock + this._currentTime += this.blockTime; + } + return this._context.startRendering(); + }; + /** + * Close the context + * @return {Promise} + */ + Tone.OfflineContext.prototype.close = function () { + this._context = null; + return Promise.resolve(); + }; + return Tone.OfflineContext; + }); + Module(function (Tone) { + if (Tone.supported) { + var ua = navigator.userAgent.toLowerCase(); + var isMobileSafari = ua.includes('safari') && !ua.includes('chrome') && ua.includes('mobile'); + if (isMobileSafari) { + //mobile safari has a bizarre bug with the offline context + //when a BufferSourceNode is started, it starts the offline context + // + //deferring all BufferSource starts till the last possible moment + //reduces the likelihood of this happening + Tone.OfflineContext.prototype.createBufferSource = function () { + var bufferSource = this._context.createBufferSource(); + var _native_start = bufferSource.start; + bufferSource.start = function (time) { + this.setTimeout(function () { + _native_start.call(bufferSource, time); + }.bind(this), 0); + }.bind(this); + return bufferSource; + }; + } + } + }); + Module(function (Tone) { + + /** + * @class A thin wrapper around the Native Web Audio GainNode. + * The GainNode is a basic building block of the Web Audio + * API and is useful for routing audio and adjusting gains. + * @extends {Tone} + * @param {Number=} gain The initial gain of the GainNode + * @param {Tone.Type=} units The units of the gain parameter. + */ + Tone.Gain = function () { + var options = Tone.defaults(arguments, [ + 'gain', + 'units' + ], Tone.Gain); + Tone.AudioNode.call(this); + /** + * The GainNode + * @type {GainNode} + * @private + */ + this.input = this.output = this._gainNode = this.context.createGain(); + /** + * The gain parameter of the gain node. + * @type {Gain} + * @signal + */ + this.gain = new Tone.Param({ + 'param': this._gainNode.gain, + 'units': options.units, + 'value': options.gain, + 'convert': options.convert + }); + this._readOnly('gain'); + }; + Tone.extend(Tone.Gain, Tone.AudioNode); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Gain.defaults = { + 'gain': 1, + 'convert': true + }; + /** + * Clean up. + * @return {Tone.Gain} this + */ + Tone.Gain.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._gainNode.disconnect(); + this._gainNode = null; + this._writable('gain'); + this.gain.dispose(); + this.gain = null; + }; + return Tone.Gain; + }); + Module(function (Tone) { + if (Tone.supported && !AudioContext.prototype.createConstantSource) { + var ConstantSourceNode = function (context) { + this.context = context; + var buffer = context.createBuffer(1, 128, context.sampleRate); + var arr = buffer.getChannelData(0); + for (var i = 0; i < arr.length; i++) { + arr[i] = 1; + } + this._bufferSource = context.createBufferSource(); + this._bufferSource.channelCount = 1; + this._bufferSource.channelCountMode = 'explicit'; + this._bufferSource.buffer = buffer; + this._bufferSource.loop = true; + var gainNode = this._output = context.createGain(); + this.offset = gainNode.gain; + this._bufferSource.connect(gainNode); + }; + ConstantSourceNode.prototype.start = function (time) { + this._bufferSource.start(time); + return this; + }; + ConstantSourceNode.prototype.stop = function (time) { + this._bufferSource.stop(time); + return this; + }; + ConstantSourceNode.prototype.connect = function () { + this._output.connect.apply(this._output, arguments); + return this; + }; + ConstantSourceNode.prototype.disconnect = function () { + this._output.disconnect.apply(this._output, arguments); + return this; + }; + AudioContext.prototype.createConstantSource = function () { + return new ConstantSourceNode(this); + }; + Tone.Context.prototype.createConstantSource = function () { + return new ConstantSourceNode(this); + }; + } + }); + Module(function (Tone) { + + /** + * @class A signal is an audio-rate value. Tone.Signal is a core component of the library. + * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal + * has all of the methods available to native Web Audio + * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface) + * as well as additional conveniences. Read more about working with signals + * [here](https://github.com/Tonejs/Tone.js/wiki/Signals). + * + * @constructor + * @extends {Tone.Param} + * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam + * is passed in, that parameter will be wrapped + * and controlled by the Signal. + * @param {string} [units=Number] unit The units the signal is in. + * @example + * var signal = new Tone.Signal(10); + */ + Tone.Signal = function () { + var options = Tone.defaults(arguments, [ + 'value', + 'units' + ], Tone.Signal); + Tone.Param.call(this, options); + /** + * When a signal is connected to another signal or audio param, + * this signal becomes a proxy for it + * @type {Array} + * @private + */ + this._proxies = []; + /** + * Indicates if the constant source was started or not + * @private + * @type {Boolean} + */ + this._sourceStarted = false; + /** + * The constant source node which generates the signal + * @type {ConstantSourceNode} + * @private + */ + this._constantSource = this.context.createConstantSource(); + this._param = this._constantSource.offset; + this.value = options.value; + /** + * The node where the constant signal value is scaled. + * @type {GainNode} + * @private + */ + this.output = this._constantSource; + /** + * The node where the value is set. + * @type {Tone.Param} + * @private + */ + this.input = this._param = this.output.offset; + }; + Tone.extend(Tone.Signal, Tone.Param); + /** + * The default values + * @type {Object} + * @static + * @const + */ + Tone.Signal.defaults = { + 'value': 0, + 'units': Tone.Type.Default, + 'convert': true + }; + /** + * When signals connect to other signals or AudioParams, + * they take over the output value of that signal or AudioParam. + * For all other nodes, the behavior is the same as a default <code>connect</code>. + * + * @override + * @param {AudioParam|AudioNode|Tone.Signal|Tone} node + * @param {number} [outputNumber=0] The output number to connect from. + * @param {number} [inputNumber=0] The input number to connect to. + * @returns {Tone.Signal} this + * @method + */ + Tone.Signal.prototype.connect = function (node) { + //this is an optimization where this node will forward automations + //to connected nodes without any signal if possible. + if (this._isParam(node) && !this._sourceStarted) { + this._proxies.push(node); + node.overridden = true; + this._applyAutomations(node); + } else { + Tone.SignalBase.prototype.connect.apply(this, arguments); + if (!this._sourceStarted) { + this._sourceStarted = true; + this._constantSource.start(0); + } + } + return this; + }; + /** + * Takes a node as an argument and returns if it is a Param or AudioParam + * @param {*} node The node to test + * @return {Boolean} + * @private + */ + Tone.Signal.prototype._isParam = function (node) { + return Tone.Param && Tone.Param === node.constructor || node instanceof AudioParam; + }; + /** + * Discard the optimization and connect all of the proxies + * @private + */ + Tone.Signal.prototype._connectProxies = function () { + if (!this._sourceStarted) { + this._sourceStarted = true; + this._constantSource.start(0); + } + this._proxies.forEach(function (proxy) { + Tone.SignalBase.prototype.connect.call(this, proxy); + if (proxy._proxies) { + proxy._connectProxies(); + } + }.bind(this)); + }; + /** + * Invoked when a node is connected to this + * @param {AudioNode} from + * @private + */ + Tone.Signal.prototype._onConnect = function (from) { + if (!this._isParam(from)) { + //connect all the proxies + this._connectProxies(); + } + }; + /** + * Apply all the current automations to the given parameter + * @param {AudioParam} param + * @private + */ + Tone.Signal.prototype._applyAutomations = function (param) { + var now = this.context.currentTime; + param.cancelScheduledValues(now); + var currentVal = this.getValueAtTime(now); + param.setValueAtTime(currentVal, now); + this._events.forEachFrom(now, function (event) { + param[event.type](event.value, event.time, event.constant); + }); + }; + /** + * Disconnect from the given node or all nodes if no param is given. + * @param {AudioNode|AudioParam} node + * @return {Tone.Signal} this + */ + Tone.Signal.prototype.disconnect = function (node) { + if (this._proxies.includes(node)) { + var index = this._proxies.indexOf(node); + this._proxies.splice(index, 1); + } else if (!node) { + //no argument, disconnect everything + this._proxies = []; + } + return Tone.SignalBase.prototype.disconnect.apply(this, arguments); + }; + /** + * Return the current signal value at the given time. + * @param {Time} time When to get the signal value + * @return {Number} + */ + Tone.Signal.prototype.getValueAtTime = function (time) { + if (this._param.getValueAtTime) { + return this._param.getValueAtTime(time); + } else { + return Tone.Param.prototype.getValueAtTime.call(this, time); + } + }; + //wrap all of the automation methods + [ + 'setValueAtTime', + 'linearRampToValueAtTime', + 'exponentialRampToValueAtTime', + 'setTargetAtTime' + ].forEach(function (method) { + var previousMethod = Tone.Signal.prototype[method]; + Tone.Signal.prototype[method] = function () { + var args = arguments; + previousMethod.apply(this, arguments); + args[0] = this._fromUnits(args[0]); + args[1] = this.toSeconds(args[1]); + //apply it to the proxies + this._proxies.forEach(function (signal) { + signal[method].apply(signal, args); + }); + }; + }); + [ + 'cancelScheduledValues', + 'cancelAndHoldAtTime' + ].forEach(function (method) { + var previousMethod = Tone.Signal.prototype[method]; + Tone.Signal.prototype[method] = function () { + var args = arguments; + previousMethod.apply(this, arguments); + args[0] = this.toSeconds(args[0]); + //apply it to the proxies + this._proxies.forEach(function (signal) { + signal[method].apply(signal, args); + }); + }; + }); + /** + * dispose and disconnect + * @returns {Tone.Signal} this + */ + Tone.Signal.prototype.dispose = function () { + Tone.Param.prototype.dispose.call(this); + this._constantSource.disconnect(); + this._constantSource = null; + this._proxies = null; + return this; + }; + return Tone.Signal; + }); + Module(function (Tone) { + + /** + * @class Pow applies an exponent to the incoming signal. The incoming signal + * must be AudioRange. + * + * @extends {Tone.SignalBase} + * @constructor + * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. + * @example + * var pow = new Tone.Pow(2); + * var sig = new Tone.Signal(0.5).connect(pow); + * //output of pow is 0.25. + */ + Tone.Pow = function (exp) { + Tone.SignalBase.call(this); + /** + * the exponent + * @private + * @type {number} + */ + this._exp = Tone.defaultArg(exp, 1); + /** + * @type {WaveShaperNode} + * @private + */ + this._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192); + }; + Tone.extend(Tone.Pow, Tone.SignalBase); + /** + * The value of the exponent. + * @memberOf Tone.Pow# + * @type {number} + * @name value + */ + Object.defineProperty(Tone.Pow.prototype, 'value', { + get: function () { + return this._exp; + }, + set: function (exp) { + this._exp = exp; + this._expScaler.setMap(this._expFunc(this._exp)); + } + }); + /** + * the function which maps the waveshaper + * @param {number} exp + * @return {function} + * @private + */ + Tone.Pow.prototype._expFunc = function (exp) { + return function (val) { + return Math.pow(Math.abs(val), exp); + }; + }; + /** + * Clean up. + * @returns {Tone.Pow} this + */ + Tone.Pow.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._expScaler.dispose(); + this._expScaler = null; + return this; + }; + return Tone.Pow; + }); + Module(function (Tone) { + + /** + * @class Tone.Envelope is an [ADSR](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope) + * envelope generator. Tone.Envelope outputs a signal which + * can be connected to an AudioParam or Tone.Signal. + * <img src="https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg"> + * + * @constructor + * @extends {Tone.AudioNode} + * @param {Time} [attack] The amount of time it takes for the envelope to go from + * 0 to it's maximum value. + * @param {Time} [decay] The period of time after the attack that it takes for the envelope + * to fall to the sustain value. + * @param {NormalRange} [sustain] The percent of the maximum value that the envelope rests at until + * the release is triggered. + * @param {Time} [release] The amount of time after the release is triggered it takes to reach 0. + * @example + * //an amplitude envelope + * var gainNode = Tone.context.createGain(); + * var env = new Tone.Envelope({ + * "attack" : 0.1, + * "decay" : 0.2, + * "sustain" : 1, + * "release" : 0.8, + * }); + * env.connect(gainNode.gain); + */ + Tone.Envelope = function () { + //get all of the defaults + var options = Tone.defaults(arguments, [ + 'attack', + 'decay', + 'sustain', + 'release' + ], Tone.Envelope); + Tone.AudioNode.call(this); + /** + * When triggerAttack is called, the attack time is the amount of + * time it takes for the envelope to reach it's maximum value. + * @type {Time} + */ + this.attack = options.attack; + /** + * After the attack portion of the envelope, the value will fall + * over the duration of the decay time to it's sustain value. + * @type {Time} + */ + this.decay = options.decay; + /** + * The sustain value is the value + * which the envelope rests at after triggerAttack is + * called, but before triggerRelease is invoked. + * @type {NormalRange} + */ + this.sustain = options.sustain; + /** + * After triggerRelease is called, the envelope's + * value will fall to it's miminum value over the + * duration of the release time. + * @type {Time} + */ + this.release = options.release; + /** + * the next time the envelope is at standby + * @type {number} + * @private + */ + this._attackCurve = 'linear'; + /** + * the next time the envelope is at standby + * @type {number} + * @private + */ + this._releaseCurve = 'exponential'; + /** + * the signal + * @type {Tone.Signal} + * @private + */ + this._sig = this.output = new Tone.Signal(0); + //set the attackCurve initially + this.attackCurve = options.attackCurve; + this.releaseCurve = options.releaseCurve; + }; + Tone.extend(Tone.Envelope, Tone.AudioNode); + /** + * the default parameters + * @static + * @const + */ + Tone.Envelope.defaults = { + 'attack': 0.01, + 'decay': 0.1, + 'sustain': 0.5, + 'release': 1, + 'attackCurve': 'linear', + 'releaseCurve': 'exponential' + }; + /** + * Read the current value of the envelope. Useful for + * syncronizing visual output to the envelope. + * @memberOf Tone.Envelope# + * @type {Number} + * @name value + * @readOnly + */ + Object.defineProperty(Tone.Envelope.prototype, 'value', { + get: function () { + return this.getValueAtTime(this.now()); + } + }); + /** + * The shape of the attack. + * Can be any of these strings: + * <ul> + * <li>linear</li> + * <li>exponential</li> + * <li>sine</li> + * <li>cosine</li> + * <li>bounce</li> + * <li>ripple</li> + * <li>step</li> + * </ul> + * Can also be an array which describes the curve. Values + * in the array are evenly subdivided and linearly + * interpolated over the duration of the attack. + * @memberOf Tone.Envelope# + * @type {String|Array} + * @name attackCurve + * @example + * env.attackCurve = "linear"; + * @example + * //can also be an array + * env.attackCurve = [0, 0.2, 0.3, 0.4, 1] + */ + Object.defineProperty(Tone.Envelope.prototype, 'attackCurve', { + get: function () { + if (Tone.isString(this._attackCurve)) { + return this._attackCurve; + } else if (Tone.isArray(this._attackCurve)) { + //look up the name in the curves array + for (var type in Tone.Envelope.Type) { + if (Tone.Envelope.Type[type].In === this._attackCurve) { + return type; + } + } + //otherwise just return the array + return this._attackCurve; + } + }, + set: function (curve) { + //check if it's a valid type + if (Tone.Envelope.Type.hasOwnProperty(curve)) { + var curveDef = Tone.Envelope.Type[curve]; + if (Tone.isObject(curveDef)) { + this._attackCurve = curveDef.In; + } else { + this._attackCurve = curveDef; + } + } else if (Tone.isArray(curve)) { + this._attackCurve = curve; + } else { + throw new Error('Tone.Envelope: invalid curve: ' + curve); + } + } + }); + /** + * The shape of the release. See the attack curve types. + * @memberOf Tone.Envelope# + * @type {String|Array} + * @name releaseCurve + * @example + * env.releaseCurve = "linear"; + */ + Object.defineProperty(Tone.Envelope.prototype, 'releaseCurve', { + get: function () { + if (Tone.isString(this._releaseCurve)) { + return this._releaseCurve; + } else if (Tone.isArray(this._releaseCurve)) { + //look up the name in the curves array + for (var type in Tone.Envelope.Type) { + if (Tone.Envelope.Type[type].Out === this._releaseCurve) { + return type; + } + } + //otherwise just return the array + return this._releaseCurve; + } + }, + set: function (curve) { + //check if it's a valid type + if (Tone.Envelope.Type.hasOwnProperty(curve)) { + var curveDef = Tone.Envelope.Type[curve]; + if (Tone.isObject(curveDef)) { + this._releaseCurve = curveDef.Out; + } else { + this._releaseCurve = curveDef; + } + } else if (Tone.isArray(curve)) { + this._releaseCurve = curve; + } else { + throw new Error('Tone.Envelope: invalid curve: ' + curve); + } + } + }); + /** + * Trigger the attack/decay portion of the ADSR envelope. + * @param {Time} [time=now] When the attack should start. + * @param {NormalRange} [velocity=1] The velocity of the envelope scales the vales. + * number between 0-1 + * @returns {Tone.Envelope} this + * @example + * //trigger the attack 0.5 seconds from now with a velocity of 0.2 + * env.triggerAttack("+0.5", 0.2); + */ + Tone.Envelope.prototype.triggerAttack = function (time, velocity) { + time = this.toSeconds(time); + var originalAttack = this.toSeconds(this.attack); + var attack = originalAttack; + var decay = this.toSeconds(this.decay); + velocity = Tone.defaultArg(velocity, 1); + //check if it's not a complete attack + var currentValue = this.getValueAtTime(time); + if (currentValue > 0) { + //subtract the current value from the attack time + var attackRate = 1 / attack; + var remainingDistance = 1 - currentValue; + //the attack is now the remaining time + attack = remainingDistance / attackRate; + } + //attack + if (this._attackCurve === 'linear') { + this._sig.linearRampTo(velocity, attack, time); + } else if (this._attackCurve === 'exponential') { + this._sig.targetRampTo(velocity, attack, time); + } else if (attack > 0) { + this._sig.cancelAndHoldAtTime(time); + var curve = this._attackCurve; + //take only a portion of the curve + if (attack < originalAttack) { + var percentComplete = 1 - attack / originalAttack; + var sliceIndex = Math.floor(percentComplete * this._attackCurve.length); + curve = this._attackCurve.slice(sliceIndex); + //the first index is the current value + curve[0] = currentValue; + } + this._sig.setValueCurveAtTime(curve, time, attack, velocity); + } + //decay + if (decay) { + this._sig.targetRampTo(velocity * this.sustain, decay, attack + time); + } + return this; + }; + /** + * Triggers the release of the envelope. + * @param {Time} [time=now] When the release portion of the envelope should start. + * @returns {Tone.Envelope} this + * @example + * //trigger release immediately + * env.triggerRelease(); + */ + Tone.Envelope.prototype.triggerRelease = function (time) { + time = this.toSeconds(time); + var currentValue = this.getValueAtTime(time); + if (currentValue > 0) { + var release = this.toSeconds(this.release); + if (this._releaseCurve === 'linear') { + this._sig.linearRampTo(0, release, time); + } else if (this._releaseCurve === 'exponential') { + this._sig.targetRampTo(0, release, time); + } else { + var curve = this._releaseCurve; + if (Tone.isArray(curve)) { + this._sig.cancelAndHoldAtTime(time); + this._sig.setValueCurveAtTime(curve, time, release, currentValue); + } + } + } + return this; + }; + /** + * Get the scheduled value at the given time. This will + * return the unconverted (raw) value. + * @param {Number} time The time in seconds. + * @return {Number} The scheduled value at the given time. + */ + Tone.Envelope.prototype.getValueAtTime = function (time) { + return this._sig.getValueAtTime(time); + }; + /** + * triggerAttackRelease is shorthand for triggerAttack, then waiting + * some duration, then triggerRelease. + * @param {Time} duration The duration of the sustain. + * @param {Time} [time=now] When the attack should be triggered. + * @param {number} [velocity=1] The velocity of the envelope. + * @returns {Tone.Envelope} this + * @example + * //trigger the attack and then the release after 0.6 seconds. + * env.triggerAttackRelease(0.6); + */ + Tone.Envelope.prototype.triggerAttackRelease = function (duration, time, velocity) { + time = this.toSeconds(time); + this.triggerAttack(time, velocity); + this.triggerRelease(time + this.toSeconds(duration)); + return this; + }; + /** + * Cancels all scheduled envelope changes after the given time. + * @param {Time} after + * @returns {Tone.Envelope} this + */ + Tone.Envelope.prototype.cancel = function (after) { + this._sig.cancelScheduledValues(after); + return this; + }; + /** + * Borrows the connect method from Tone.Signal. + * @function + * @private + */ + Tone.Envelope.prototype.connect = Tone.SignalBase.prototype.connect; + /** + * Generate some complex envelope curves. + */ + (function _createCurves() { + var curveLen = 128; + var i, k; + //cosine curve + var cosineCurve = []; + for (i = 0; i < curveLen; i++) { + cosineCurve[i] = Math.sin(i / (curveLen - 1) * (Math.PI / 2)); + } + //ripple curve + var rippleCurve = []; + var rippleCurveFreq = 6.4; + for (i = 0; i < curveLen - 1; i++) { + k = i / (curveLen - 1); + var sineWave = Math.sin(k * (Math.PI * 2) * rippleCurveFreq - Math.PI / 2) + 1; + rippleCurve[i] = sineWave / 10 + k * 0.83; + } + rippleCurve[curveLen - 1] = 1; + //stairs curve + var stairsCurve = []; + var steps = 5; + for (i = 0; i < curveLen; i++) { + stairsCurve[i] = Math.ceil(i / (curveLen - 1) * steps) / steps; + } + //in-out easing curve + var sineCurve = []; + for (i = 0; i < curveLen; i++) { + k = i / (curveLen - 1); + sineCurve[i] = 0.5 * (1 - Math.cos(Math.PI * k)); + } + //a bounce curve + var bounceCurve = []; + for (i = 0; i < curveLen; i++) { + k = i / (curveLen - 1); + var freq = Math.pow(k, 3) * 4 + 0.2; + var val = Math.cos(freq * Math.PI * 2 * k); + bounceCurve[i] = Math.abs(val * (1 - k)); + } + /** + * Invert a value curve to make it work for the release + * @private + */ + function invertCurve(curve) { + var out = new Array(curve.length); + for (var j = 0; j < curve.length; j++) { + out[j] = 1 - curve[j]; + } + return out; + } + /** + * reverse the curve + * @private + */ + function reverseCurve(curve) { + return curve.slice(0).reverse(); + } + /** + * attack and release curve arrays + * @type {Object} + * @private + */ + Tone.Envelope.Type = { + 'linear': 'linear', + 'exponential': 'exponential', + 'bounce': { + In: invertCurve(bounceCurve), + Out: bounceCurve + }, + 'cosine': { + In: cosineCurve, + Out: reverseCurve(cosineCurve) + }, + 'step': { + In: stairsCurve, + Out: invertCurve(stairsCurve) + }, + 'ripple': { + In: rippleCurve, + Out: invertCurve(rippleCurve) + }, + 'sine': { + In: sineCurve, + Out: invertCurve(sineCurve) + } + }; + }()); + /** + * Disconnect and dispose. + * @returns {Tone.Envelope} this + */ + Tone.Envelope.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._sig.dispose(); + this._sig = null; + this._attackCurve = null; + this._releaseCurve = null; + return this; + }; + return Tone.Envelope; + }); + Module(function (Tone) { + + /** + * @class Tone.AmplitudeEnvelope is a Tone.Envelope connected to a gain node. + * Unlike Tone.Envelope, which outputs the envelope's value, Tone.AmplitudeEnvelope accepts + * an audio signal as the input and will apply the envelope to the amplitude + * of the signal. Read more about ADSR Envelopes on [Wikipedia](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope). + * + * @constructor + * @extends {Tone.Envelope} + * @param {Time|Object} [attack] The amount of time it takes for the envelope to go from + * 0 to it's maximum value. + * @param {Time} [decay] The period of time after the attack that it takes for the envelope + * to fall to the sustain value. + * @param {NormalRange} [sustain] The percent of the maximum value that the envelope rests at until + * the release is triggered. + * @param {Time} [release] The amount of time after the release is triggered it takes to reach 0. + * @example + * var ampEnv = new Tone.AmplitudeEnvelope({ + * "attack": 0.1, + * "decay": 0.2, + * "sustain": 1.0, + * "release": 0.8 + * }).toMaster(); + * //create an oscillator and connect it + * var osc = new Tone.Oscillator().connect(ampEnv).start(); + * //trigger the envelopes attack and release "8t" apart + * ampEnv.triggerAttackRelease("8t"); + */ + Tone.AmplitudeEnvelope = function () { + Tone.Envelope.apply(this, arguments); + /** + * the input node + * @type {GainNode} + * @private + */ + this.input = this.output = new Tone.Gain(); + this._sig.connect(this.output.gain); + }; + Tone.extend(Tone.AmplitudeEnvelope, Tone.Envelope); + /** + * Clean up + * @return {Tone.AmplitudeEnvelope} this + */ + Tone.AmplitudeEnvelope.prototype.dispose = function () { + Tone.Envelope.prototype.dispose.call(this); + return this; + }; + return Tone.AmplitudeEnvelope; + }); + Module(function (Tone) { + /** + * AnalyserNode.getFloatTimeDomainData polyfill + * @private + */ + if (Tone.supported) { + if (!AnalyserNode.prototype.getFloatTimeDomainData) { + //referenced https://github.com/mohayonao/get-float-time-domain-data + AnalyserNode.prototype.getFloatTimeDomainData = function (array) { + var uint8 = new Uint8Array(array.length); + this.getByteTimeDomainData(uint8); + for (var i = 0; i < uint8.length; i++) { + array[i] = (uint8[i] - 128) / 128; + } + }; + } + } + }); + Module(function (Tone) { + + /** + * @class Wrapper around the native Web Audio's + * [AnalyserNode](http://webaudio.github.io/web-audio-api/#idl-def-AnalyserNode). + * Extracts FFT or Waveform data from the incoming signal. + * @extends {Tone.AudioNode} + * @param {String=} type The return type of the analysis, either "fft", or "waveform". + * @param {Number=} size The size of the FFT. Value must be a power of + * two in the range 32 to 32768. + */ + Tone.Analyser = function () { + var options = Tone.defaults(arguments, [ + 'type', + 'size' + ], Tone.Analyser); + Tone.AudioNode.call(this); + /** + * The analyser node. + * @private + * @type {AnalyserNode} + */ + this._analyser = this.input = this.output = this.context.createAnalyser(); + /** + * The analysis type + * @type {String} + * @private + */ + this._type = options.type; + /** + * The buffer that the FFT data is written to + * @type {TypedArray} + * @private + */ + this._buffer = null; + //set the values initially + this.size = options.size; + this.type = options.type; + }; + Tone.extend(Tone.Analyser, Tone.AudioNode); + /** + * The default values. + * @type {Object} + * @const + */ + Tone.Analyser.defaults = { + 'size': 1024, + 'type': 'fft', + 'smoothing': 0.8 + }; + /** + * Possible return types of analyser.getValue() + * @enum {String} + */ + Tone.Analyser.Type = { + Waveform: 'waveform', + FFT: 'fft' + }; + /** + * Run the analysis given the current settings and return the + * result as a TypedArray. + * @returns {TypedArray} + */ + Tone.Analyser.prototype.getValue = function () { + if (this._type === Tone.Analyser.Type.FFT) { + this._analyser.getFloatFrequencyData(this._buffer); + } else if (this._type === Tone.Analyser.Type.Waveform) { + this._analyser.getFloatTimeDomainData(this._buffer); + } + return this._buffer; + }; + /** + * The size of analysis. This must be a power of two in the range 32 to 32768. + * @memberOf Tone.Analyser# + * @type {Number} + * @name size + */ + Object.defineProperty(Tone.Analyser.prototype, 'size', { + get: function () { + return this._analyser.frequencyBinCount; + }, + set: function (size) { + this._analyser.fftSize = size * 2; + this._buffer = new Float32Array(size); + } + }); + /** + * The analysis function returned by analyser.getValue(), either "fft" or "waveform". + * @memberOf Tone.Analyser# + * @type {String} + * @name type + */ + Object.defineProperty(Tone.Analyser.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + if (type !== Tone.Analyser.Type.Waveform && type !== Tone.Analyser.Type.FFT) { + throw new TypeError('Tone.Analyser: invalid type: ' + type); + } + this._type = type; + } + }); + /** + * 0 represents no time averaging with the last analysis frame. + * @memberOf Tone.Analyser# + * @type {NormalRange} + * @name smoothing + */ + Object.defineProperty(Tone.Analyser.prototype, 'smoothing', { + get: function () { + return this._analyser.smoothingTimeConstant; + }, + set: function (val) { + this._analyser.smoothingTimeConstant = val; + } + }); + /** + * Clean up. + * @return {Tone.Analyser} this + */ + Tone.Analyser.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._analyser.disconnect(); + this._analyser = null; + this._buffer = null; + }; + return Tone.Analyser; + }); + Module(function (Tone) { + + /** + * @class Tone.Compressor is a thin wrapper around the Web Audio + * [DynamicsCompressorNode](http://webaudio.github.io/web-audio-api/#the-dynamicscompressornode-interface). + * Compression reduces the volume of loud sounds or amplifies quiet sounds + * by narrowing or "compressing" an audio signal's dynamic range. + * Read more on [Wikipedia](https://en.wikipedia.org/wiki/Dynamic_range_compression). + * + * @extends {Tone.AudioNode} + * @constructor + * @param {Decibels|Object} [threshold] The value above which the compression starts to be applied. + * @param {Positive} [ratio] The gain reduction ratio. + * @example + * var comp = new Tone.Compressor(-30, 3); + */ + Tone.Compressor = function () { + var options = Tone.defaults(arguments, [ + 'threshold', + 'ratio' + ], Tone.Compressor); + Tone.AudioNode.call(this); + /** + * the compressor node + * @type {DynamicsCompressorNode} + * @private + */ + this._compressor = this.input = this.output = this.context.createDynamicsCompressor(); + /** + * the threshold vaue + * @type {Decibels} + * @signal + */ + this.threshold = new Tone.Param({ + 'param': this._compressor.threshold, + 'units': Tone.Type.Decibels, + 'convert': false + }); + /** + * The attack parameter + * @type {Time} + * @signal + */ + this.attack = new Tone.Param(this._compressor.attack, Tone.Type.Time); + /** + * The release parameter + * @type {Time} + * @signal + */ + this.release = new Tone.Param(this._compressor.release, Tone.Type.Time); + /** + * The knee parameter + * @type {Decibels} + * @signal + */ + this.knee = new Tone.Param({ + 'param': this._compressor.knee, + 'units': Tone.Type.Decibels, + 'convert': false + }); + /** + * The ratio value + * @type {Number} + * @signal + */ + this.ratio = new Tone.Param({ + 'param': this._compressor.ratio, + 'convert': false + }); + //set the defaults + this._readOnly([ + 'knee', + 'release', + 'attack', + 'ratio', + 'threshold' + ]); + this.set(options); + }; + Tone.extend(Tone.Compressor, Tone.AudioNode); + /** + * @static + * @const + * @type {Object} + */ + Tone.Compressor.defaults = { + 'ratio': 12, + 'threshold': -24, + 'release': 0.25, + 'attack': 0.003, + 'knee': 30 + }; + /** + * clean up + * @returns {Tone.Compressor} this + */ + Tone.Compressor.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._writable([ + 'knee', + 'release', + 'attack', + 'ratio', + 'threshold' + ]); + this._compressor.disconnect(); + this._compressor = null; + this.attack.dispose(); + this.attack = null; + this.release.dispose(); + this.release = null; + this.threshold.dispose(); + this.threshold = null; + this.ratio.dispose(); + this.ratio = null; + this.knee.dispose(); + this.knee = null; + return this; + }; + return Tone.Compressor; + }); + Module(function (Tone) { + + /** + * @class Add a signal and a number or two signals. When no value is + * passed into the constructor, Tone.Add will sum <code>input[0]</code> + * and <code>input[1]</code>. If a value is passed into the constructor, + * the it will be added to the input. + * + * @constructor + * @extends {Tone.Signal} + * @param {number=} value If no value is provided, Tone.Add will sum the first + * and second inputs. + * @example + * var signal = new Tone.Signal(2); + * var add = new Tone.Add(2); + * signal.connect(add); + * //the output of add equals 4 + * @example + * //if constructed with no arguments + * //it will add the first and second inputs + * var add = new Tone.Add(); + * var sig0 = new Tone.Signal(3).connect(add, 0, 0); + * var sig1 = new Tone.Signal(4).connect(add, 0, 1); + * //the output of add equals 7. + */ + Tone.Add = function (value) { + Tone.Signal.call(this); + this.createInsOuts(2, 0); + /** + * the summing node + * @type {GainNode} + * @private + */ + this._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain(); + /** + * @private + * @type {Tone.Signal} + */ + this._param = this.input[1] = new Tone.Signal(value); + this._param.connect(this._sum); + }; + Tone.extend(Tone.Add, Tone.Signal); + /** + * Clean up. + * @returns {Tone.Add} this + */ + Tone.Add.prototype.dispose = function () { + Tone.Signal.prototype.dispose.call(this); + this._sum.dispose(); + this._sum = null; + return this; + }; + return Tone.Add; + }); + Module(function (Tone) { + + /** + * @class Multiply two incoming signals. Or, if a number is given in the constructor, + * multiplies the incoming signal by that value. + * + * @constructor + * @extends {Tone.Signal} + * @param {number=} value Constant value to multiple. If no value is provided, + * it will return the product of the first and second inputs + * @example + * var mult = new Tone.Multiply(); + * var sigA = new Tone.Signal(3); + * var sigB = new Tone.Signal(4); + * sigA.connect(mult, 0, 0); + * sigB.connect(mult, 0, 1); + * //output of mult is 12. + * @example + * var mult = new Tone.Multiply(10); + * var sig = new Tone.Signal(2).connect(mult); + * //the output of mult is 20. + */ + Tone.Multiply = function (value) { + Tone.Signal.call(this); + this.createInsOuts(2, 0); + /** + * the input node is the same as the output node + * it is also the GainNode which handles the scaling of incoming signal + * + * @type {GainNode} + * @private + */ + this._mult = this.input[0] = this.output = new Tone.Gain(); + /** + * the scaling parameter + * @type {AudioParam} + * @private + */ + this._param = this.input[1] = this.output.gain; + this.value = Tone.defaultArg(value, 0); + }; + Tone.extend(Tone.Multiply, Tone.Signal); + /** + * clean up + * @returns {Tone.Multiply} this + */ + Tone.Multiply.prototype.dispose = function () { + Tone.Signal.prototype.dispose.call(this); + this._mult.dispose(); + this._mult = null; + this._param = null; + return this; + }; + return Tone.Multiply; + }); + Module(function (Tone) { + + /** + * @class Negate the incoming signal. i.e. an input signal of 10 will output -10 + * + * @constructor + * @extends {Tone.SignalBase} + * @example + * var neg = new Tone.Negate(); + * var sig = new Tone.Signal(-2).connect(neg); + * //output of neg is positive 2. + */ + Tone.Negate = function () { + Tone.SignalBase.call(this); + /** + * negation is done by multiplying by -1 + * @type {Tone.Multiply} + * @private + */ + this._multiply = this.input = this.output = new Tone.Multiply(-1); + }; + Tone.extend(Tone.Negate, Tone.SignalBase); + /** + * clean up + * @returns {Tone.Negate} this + */ + Tone.Negate.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._multiply.dispose(); + this._multiply = null; + return this; + }; + return Tone.Negate; + }); + Module(function (Tone) { + + /** + * @class Subtract the signal connected to <code>input[1]</code> from the signal connected + * to <code>input[0]</code>. If an argument is provided in the constructor, the + * signals <code>.value</code> will be subtracted from the incoming signal. + * + * @extends {Tone.Signal} + * @constructor + * @param {number=} value The value to subtract from the incoming signal. If the value + * is omitted, it will subtract the second signal from the first. + * @example + * var sub = new Tone.Subtract(1); + * var sig = new Tone.Signal(4).connect(sub); + * //the output of sub is 3. + * @example + * var sub = new Tone.Subtract(); + * var sigA = new Tone.Signal(10); + * var sigB = new Tone.Signal(2.5); + * sigA.connect(sub, 0, 0); + * sigB.connect(sub, 0, 1); + * //output of sub is 7.5 + */ + Tone.Subtract = function (value) { + Tone.Signal.call(this); + this.createInsOuts(2, 0); + /** + * the summing node + * @type {GainNode} + * @private + */ + this._sum = this.input[0] = this.output = new Tone.Gain(); + /** + * negate the input of the second input before connecting it + * to the summing node. + * @type {Tone.Negate} + * @private + */ + this._neg = new Tone.Negate(); + /** + * the node where the value is set + * @private + * @type {Tone.Signal} + */ + this._param = this.input[1] = new Tone.Signal(value); + this._param.chain(this._neg, this._sum); + }; + Tone.extend(Tone.Subtract, Tone.Signal); + /** + * Clean up. + * @returns {Tone.SignalBase} this + */ + Tone.Subtract.prototype.dispose = function () { + Tone.Signal.prototype.dispose.call(this); + this._neg.dispose(); + this._neg = null; + this._sum.disconnect(); + this._sum = null; + return this; + }; + return Tone.Subtract; + }); + Module(function (Tone) { + + /** + * @class Convert an incoming signal between 0, 1 to an equal power gain scale. + * + * @extends {Tone.SignalBase} + * @constructor + * @example + * var eqPowGain = new Tone.EqualPowerGain(); + */ + Tone.EqualPowerGain = function () { + Tone.SignalBase.call(this); + /** + * @type {Tone.WaveShaper} + * @private + */ + this._eqPower = this.input = this.output = new Tone.WaveShaper(function (val) { + if (Math.abs(val) < 0.001) { + //should output 0 when input is 0 + return 0; + } else { + return Tone.equalPowerScale(val); + } + }.bind(this), 4096); + }; + Tone.extend(Tone.EqualPowerGain, Tone.SignalBase); + /** + * clean up + * @returns {Tone.EqualPowerGain} this + */ + Tone.EqualPowerGain.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._eqPower.dispose(); + this._eqPower = null; + return this; + }; + return Tone.EqualPowerGain; + }); + Module(function (Tone) { + + /** + * @class Tone.Crossfade provides equal power fading between two inputs. + * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading). + * + * @constructor + * @extends {Tone.AudioNode} + * @param {NormalRange} [initialFade=0.5] + * @example + * var crossFade = new Tone.CrossFade(0.5); + * //connect effect A to crossfade from + * //effect output 0 to crossfade input 0 + * effectA.connect(crossFade, 0, 0); + * //connect effect B to crossfade from + * //effect output 0 to crossfade input 1 + * effectB.connect(crossFade, 0, 1); + * crossFade.fade.value = 0; + * // ^ only effectA is output + * crossFade.fade.value = 1; + * // ^ only effectB is output + * crossFade.fade.value = 0.5; + * // ^ the two signals are mixed equally. + */ + Tone.CrossFade = function (initialFade) { + Tone.AudioNode.call(this); + this.createInsOuts(2, 1); + /** + * Alias for <code>input[0]</code>. + * @type {Tone.Gain} + */ + this.a = this.input[0] = new Tone.Gain(); + /** + * Alias for <code>input[1]</code>. + * @type {Tone.Gain} + */ + this.b = this.input[1] = new Tone.Gain(); + /** + * The mix between the two inputs. A fade value of 0 + * will output 100% <code>input[0]</code> and + * a value of 1 will output 100% <code>input[1]</code>. + * @type {NormalRange} + * @signal + */ + this.fade = new Tone.Signal(Tone.defaultArg(initialFade, 0.5), Tone.Type.NormalRange); + /** + * equal power gain cross fade + * @private + * @type {Tone.EqualPowerGain} + */ + this._equalPowerA = new Tone.EqualPowerGain(); + /** + * equal power gain cross fade + * @private + * @type {Tone.EqualPowerGain} + */ + this._equalPowerB = new Tone.EqualPowerGain(); + /** + * invert the incoming signal + * @private + * @type {Tone} + */ + this._one = this.context.getConstant(1); + /** + * invert the incoming signal + * @private + * @type {Tone.Subtract} + */ + this._invert = new Tone.Subtract(); + //connections + this.a.connect(this.output); + this.b.connect(this.output); + this.fade.chain(this._equalPowerB, this.b.gain); + this._one.connect(this._invert, 0, 0); + this.fade.connect(this._invert, 0, 1); + this._invert.chain(this._equalPowerA, this.a.gain); + this._readOnly('fade'); + }; + Tone.extend(Tone.CrossFade, Tone.AudioNode); + /** + * clean up + * @returns {Tone.CrossFade} this + */ + Tone.CrossFade.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._writable('fade'); + this._equalPowerA.dispose(); + this._equalPowerA = null; + this._equalPowerB.dispose(); + this._equalPowerB = null; + this.fade.dispose(); + this.fade = null; + this._invert.dispose(); + this._invert = null; + this._one = null; + this.a.dispose(); + this.a = null; + this.b.dispose(); + this.b = null; + return this; + }; + return Tone.CrossFade; + }); + Module(function (Tone) { + + /** + * @class Tone.Filter is a filter which allows for all of the same native methods + * as the [BiquadFilterNode](http://webaudio.github.io/web-audio-api/#the-biquadfilternode-interface). + * Tone.Filter has the added ability to set the filter rolloff at -12 + * (default), -24 and -48. + * + * @constructor + * @extends {Tone.AudioNode} + * @param {Frequency|Object} [frequency] The cutoff frequency of the filter. + * @param {string=} type The type of filter. + * @param {number=} rolloff The drop in decibels per octave after the cutoff frequency. + * 3 choices: -12, -24, and -48 + * @example + * var filter = new Tone.Filter(200, "highpass"); + */ + Tone.Filter = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'type', + 'rolloff' + ], Tone.Filter); + Tone.AudioNode.call(this); + this.createInsOuts(1, 1); + /** + * the filter(s) + * @type {Array} + * @private + */ + this._filters = []; + /** + * The cutoff frequency of the filter. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune parameter + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(0, Tone.Type.Cents); + /** + * The gain of the filter, only used in certain filter types + * @type {Number} + * @signal + */ + this.gain = new Tone.Signal({ + 'value': options.gain, + 'convert': false + }); + /** + * The Q or Quality of the filter + * @type {Positive} + * @signal + */ + this.Q = new Tone.Signal(options.Q); + /** + * the type of the filter + * @type {string} + * @private + */ + this._type = options.type; + /** + * the rolloff value of the filter + * @type {number} + * @private + */ + this._rolloff = options.rolloff; + //set the rolloff; + this.rolloff = options.rolloff; + this._readOnly([ + 'detune', + 'frequency', + 'gain', + 'Q' + ]); + }; + Tone.extend(Tone.Filter, Tone.AudioNode); + /** + * the default parameters + * + * @static + * @type {Object} + */ + Tone.Filter.defaults = { + 'type': 'lowpass', + 'frequency': 350, + 'rolloff': -12, + 'Q': 1, + 'gain': 0 + }; + /** + * The type of the filter. Types: "lowpass", "highpass", + * "bandpass", "lowshelf", "highshelf", "notch", "allpass", or "peaking". + * @memberOf Tone.Filter# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.Filter.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + var types = [ + 'lowpass', + 'highpass', + 'bandpass', + 'lowshelf', + 'highshelf', + 'notch', + 'allpass', + 'peaking' + ]; + if (types.indexOf(type) === -1) { + throw new TypeError('Tone.Filter: invalid type ' + type); + } + this._type = type; + for (var i = 0; i < this._filters.length; i++) { + this._filters[i].type = type; + } + } + }); + /** + * The rolloff of the filter which is the drop in db + * per octave. Implemented internally by cascading filters. + * Only accepts the values -12, -24, -48 and -96. + * @memberOf Tone.Filter# + * @type {number} + * @name rolloff + */ + Object.defineProperty(Tone.Filter.prototype, 'rolloff', { + get: function () { + return this._rolloff; + }, + set: function (rolloff) { + rolloff = parseInt(rolloff, 10); + var possibilities = [ + -12, + -24, + -48, + -96 + ]; + var cascadingCount = possibilities.indexOf(rolloff); + //check the rolloff is valid + if (cascadingCount === -1) { + throw new RangeError('Tone.Filter: rolloff can only be -12, -24, -48 or -96'); + } + cascadingCount += 1; + this._rolloff = rolloff; + //first disconnect the filters and throw them away + this.input.disconnect(); + for (var i = 0; i < this._filters.length; i++) { + this._filters[i].disconnect(); + this._filters[i] = null; + } + this._filters = new Array(cascadingCount); + for (var count = 0; count < cascadingCount; count++) { + var filter = this.context.createBiquadFilter(); + filter.type = this._type; + this.frequency.connect(filter.frequency); + this.detune.connect(filter.detune); + this.Q.connect(filter.Q); + this.gain.connect(filter.gain); + this._filters[count] = filter; + } + //connect them up + var connectionChain = [this.input].concat(this._filters).concat([this.output]); + Tone.connectSeries.apply(Tone, connectionChain); + } + }); + /** + * Clean up. + * @return {Tone.Filter} this + */ + Tone.Filter.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + for (var i = 0; i < this._filters.length; i++) { + this._filters[i].disconnect(); + this._filters[i] = null; + } + this._filters = null; + this._writable([ + 'detune', + 'frequency', + 'gain', + 'Q' + ]); + this.frequency.dispose(); + this.Q.dispose(); + this.frequency = null; + this.Q = null; + this.detune.dispose(); + this.detune = null; + this.gain.dispose(); + this.gain = null; + return this; + }; + return Tone.Filter; + }); + Module(function (Tone) { + + /** + * @class Split the incoming signal into three bands (low, mid, high) + * with two crossover frequency controls. + * + * @extends {Tone.AudioNode} + * @constructor + * @param {Frequency|Object} [lowFrequency] the low/mid crossover frequency + * @param {Frequency} [highFrequency] the mid/high crossover frequency + */ + Tone.MultibandSplit = function () { + var options = Tone.defaults(arguments, [ + 'lowFrequency', + 'highFrequency' + ], Tone.MultibandSplit); + Tone.AudioNode.call(this); + /** + * the input + * @type {Tone.Gain} + * @private + */ + this.input = new Tone.Gain(); + /** + * the outputs + * @type {Array} + * @private + */ + this.output = new Array(3); + /** + * The low band. Alias for <code>output[0]</code> + * @type {Tone.Filter} + */ + this.low = this.output[0] = new Tone.Filter(0, 'lowpass'); + /** + * the lower filter of the mid band + * @type {Tone.Filter} + * @private + */ + this._lowMidFilter = new Tone.Filter(0, 'highpass'); + /** + * The mid band output. Alias for <code>output[1]</code> + * @type {Tone.Filter} + */ + this.mid = this.output[1] = new Tone.Filter(0, 'lowpass'); + /** + * The high band output. Alias for <code>output[2]</code> + * @type {Tone.Filter} + */ + this.high = this.output[2] = new Tone.Filter(0, 'highpass'); + /** + * The low/mid crossover frequency. + * @type {Frequency} + * @signal + */ + this.lowFrequency = new Tone.Signal(options.lowFrequency, Tone.Type.Frequency); + /** + * The mid/high crossover frequency. + * @type {Frequency} + * @signal + */ + this.highFrequency = new Tone.Signal(options.highFrequency, Tone.Type.Frequency); + /** + * The quality of all the filters + * @type {Number} + * @signal + */ + this.Q = new Tone.Signal(options.Q); + this.input.fan(this.low, this.high); + this.input.chain(this._lowMidFilter, this.mid); + //the frequency control signal + this.lowFrequency.connect(this.low.frequency); + this.lowFrequency.connect(this._lowMidFilter.frequency); + this.highFrequency.connect(this.mid.frequency); + this.highFrequency.connect(this.high.frequency); + //the Q value + this.Q.connect(this.low.Q); + this.Q.connect(this._lowMidFilter.Q); + this.Q.connect(this.mid.Q); + this.Q.connect(this.high.Q); + this._readOnly([ + 'high', + 'mid', + 'low', + 'highFrequency', + 'lowFrequency' + ]); + }; + Tone.extend(Tone.MultibandSplit, Tone.AudioNode); + /** + * @private + * @static + * @type {Object} + */ + Tone.MultibandSplit.defaults = { + 'lowFrequency': 400, + 'highFrequency': 2500, + 'Q': 1 + }; + /** + * Clean up. + * @returns {Tone.MultibandSplit} this + */ + Tone.MultibandSplit.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._writable([ + 'high', + 'mid', + 'low', + 'highFrequency', + 'lowFrequency' + ]); + this.low.dispose(); + this.low = null; + this._lowMidFilter.dispose(); + this._lowMidFilter = null; + this.mid.dispose(); + this.mid = null; + this.high.dispose(); + this.high = null; + this.lowFrequency.dispose(); + this.lowFrequency = null; + this.highFrequency.dispose(); + this.highFrequency = null; + this.Q.dispose(); + this.Q = null; + return this; + }; + return Tone.MultibandSplit; + }); + Module(function (Tone) { + + /** + * @class Tone.EQ3 is a three band EQ with control over low, mid, and high gain as + * well as the low and high crossover frequencies. + * + * @constructor + * @extends {Tone.AudioNode} + * + * @param {Decibels|Object} [lowLevel] The gain applied to the lows. + * @param {Decibels} [midLevel] The gain applied to the mid. + * @param {Decibels} [highLevel] The gain applied to the high. + * @example + * var eq = new Tone.EQ3(-10, 3, -20); + */ + Tone.EQ3 = function () { + var options = Tone.defaults(arguments, [ + 'low', + 'mid', + 'high' + ], Tone.EQ3); + Tone.AudioNode.call(this); + /** + * the output node + * @type {GainNode} + * @private + */ + this.output = new Tone.Gain(); + /** + * the multiband split + * @type {Tone.MultibandSplit} + * @private + */ + this._multibandSplit = this.input = new Tone.MultibandSplit({ + 'lowFrequency': options.lowFrequency, + 'highFrequency': options.highFrequency + }); + /** + * The gain for the lower signals + * @type {Tone.Gain} + * @private + */ + this._lowGain = new Tone.Gain(options.low, Tone.Type.Decibels); + /** + * The gain for the mid signals + * @type {Tone.Gain} + * @private + */ + this._midGain = new Tone.Gain(options.mid, Tone.Type.Decibels); + /** + * The gain in decibels of the high part + * @type {Tone.Gain} + * @private + */ + this._highGain = new Tone.Gain(options.high, Tone.Type.Decibels); + /** + * The gain in decibels of the low part + * @type {Decibels} + * @signal + */ + this.low = this._lowGain.gain; + /** + * The gain in decibels of the mid part + * @type {Decibels} + * @signal + */ + this.mid = this._midGain.gain; + /** + * The gain in decibels of the high part + * @type {Decibels} + * @signal + */ + this.high = this._highGain.gain; + /** + * The Q value for all of the filters. + * @type {Positive} + * @signal + */ + this.Q = this._multibandSplit.Q; + /** + * The low/mid crossover frequency. + * @type {Frequency} + * @signal + */ + this.lowFrequency = this._multibandSplit.lowFrequency; + /** + * The mid/high crossover frequency. + * @type {Frequency} + * @signal + */ + this.highFrequency = this._multibandSplit.highFrequency; + //the frequency bands + this._multibandSplit.low.chain(this._lowGain, this.output); + this._multibandSplit.mid.chain(this._midGain, this.output); + this._multibandSplit.high.chain(this._highGain, this.output); + this._readOnly([ + 'low', + 'mid', + 'high', + 'lowFrequency', + 'highFrequency' + ]); + }; + Tone.extend(Tone.EQ3, Tone.AudioNode); + /** + * the default values + */ + Tone.EQ3.defaults = { + 'low': 0, + 'mid': 0, + 'high': 0, + 'lowFrequency': 400, + 'highFrequency': 2500 + }; + /** + * clean up + * @returns {Tone.EQ3} this + */ + Tone.EQ3.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._writable([ + 'low', + 'mid', + 'high', + 'lowFrequency', + 'highFrequency' + ]); + this._multibandSplit.dispose(); + this._multibandSplit = null; + this.lowFrequency = null; + this.highFrequency = null; + this._lowGain.dispose(); + this._lowGain = null; + this._midGain.dispose(); + this._midGain = null; + this._highGain.dispose(); + this._highGain = null; + this.low = null; + this.mid = null; + this.high = null; + this.Q = null; + return this; + }; + return Tone.EQ3; + }); + Module(function (Tone) { + + /** + * @class Performs a linear scaling on an input signal. + * Scales a NormalRange input to between + * outputMin and outputMax. + * + * @constructor + * @extends {Tone.SignalBase} + * @param {number} [outputMin=0] The output value when the input is 0. + * @param {number} [outputMax=1] The output value when the input is 1. + * @example + * var scale = new Tone.Scale(50, 100); + * var signal = new Tone.Signal(0.5).connect(scale); + * //the output of scale equals 75 + */ + Tone.Scale = function (outputMin, outputMax) { + Tone.SignalBase.call(this); + /** + * @private + * @type {number} + */ + this._outputMin = Tone.defaultArg(outputMin, 0); + /** + * @private + * @type {number} + */ + this._outputMax = Tone.defaultArg(outputMax, 1); + /** + * @private + * @type {Tone.Multiply} + * @private + */ + this._scale = this.input = new Tone.Multiply(1); + /** + * @private + * @type {Tone.Add} + * @private + */ + this._add = this.output = new Tone.Add(0); + this._scale.connect(this._add); + this._setRange(); + }; + Tone.extend(Tone.Scale, Tone.SignalBase); + /** + * The minimum output value. This number is output when + * the value input value is 0. + * @memberOf Tone.Scale# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.Scale.prototype, 'min', { + get: function () { + return this._outputMin; + }, + set: function (min) { + this._outputMin = min; + this._setRange(); + } + }); + /** + * The maximum output value. This number is output when + * the value input value is 1. + * @memberOf Tone.Scale# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.Scale.prototype, 'max', { + get: function () { + return this._outputMax; + }, + set: function (max) { + this._outputMax = max; + this._setRange(); + } + }); + /** + * set the values + * @private + */ + Tone.Scale.prototype._setRange = function () { + this._add.value = this._outputMin; + this._scale.value = this._outputMax - this._outputMin; + }; + /** + * Clean up. + * @returns {Tone.Scale} this + */ + Tone.Scale.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._add.dispose(); + this._add = null; + this._scale.dispose(); + this._scale = null; + return this; + }; + return Tone.Scale; + }); + Module(function (Tone) { + /** + * @class Performs an exponential scaling on an input signal. + * Scales a NormalRange value [0,1] exponentially + * to the output range of outputMin to outputMax. + * + * @constructor + * @extends {Tone.SignalBase} + * @param {number} [outputMin=0] The output value when the input is 0. + * @param {number} [outputMax=1] The output value when the input is 1. + * @param {number} [exponent=2] The exponent which scales the incoming signal. + * @example + * var scaleExp = new Tone.ScaleExp(0, 100, 2); + * var signal = new Tone.Signal(0.5).connect(scaleExp); + */ + Tone.ScaleExp = function (outputMin, outputMax, exponent) { + Tone.SignalBase.call(this); + /** + * scale the input to the output range + * @type {Tone.Scale} + * @private + */ + this._scale = this.output = new Tone.Scale(outputMin, outputMax); + /** + * @private + * @type {Tone.Pow} + * @private + */ + this._exp = this.input = new Tone.Pow(Tone.defaultArg(exponent, 2)); + this._exp.connect(this._scale); + }; + Tone.extend(Tone.ScaleExp, Tone.SignalBase); + /** + * Instead of interpolating linearly between the <code>min</code> and + * <code>max</code> values, setting the exponent will interpolate between + * the two values with an exponential curve. + * @memberOf Tone.ScaleExp# + * @type {number} + * @name exponent + */ + Object.defineProperty(Tone.ScaleExp.prototype, 'exponent', { + get: function () { + return this._exp.value; + }, + set: function (exp) { + this._exp.value = exp; + } + }); + /** + * The minimum output value. This number is output when + * the value input value is 0. + * @memberOf Tone.ScaleExp# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.ScaleExp.prototype, 'min', { + get: function () { + return this._scale.min; + }, + set: function (min) { + this._scale.min = min; + } + }); + /** + * The maximum output value. This number is output when + * the value input value is 1. + * @memberOf Tone.ScaleExp# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.ScaleExp.prototype, 'max', { + get: function () { + return this._scale.max; + }, + set: function (max) { + this._scale.max = max; + } + }); + /** + * Clean up. + * @returns {Tone.ScaleExp} this + */ + Tone.ScaleExp.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._scale.dispose(); + this._scale = null; + this._exp.dispose(); + this._exp = null; + return this; + }; + return Tone.ScaleExp; + }); + Module(function (Tone) { + + /** + * @class Wrapper around Web Audio's native [DelayNode](http://webaudio.github.io/web-audio-api/#the-delaynode-interface). + * @extends {Tone} + * @param {Time=} delayTime The delay applied to the incoming signal. + * @param {Time=} maxDelay The maximum delay time. + */ + Tone.Delay = function () { + var options = Tone.defaults(arguments, [ + 'delayTime', + 'maxDelay' + ], Tone.Delay); + Tone.AudioNode.call(this); + /** + * The maximum delay time initialized with the node + * @type {Number} + * @private + */ + this._maxDelay = Math.max(this.toSeconds(options.maxDelay), this.toSeconds(options.delayTime)); + /** + * The native delay node + * @type {DelayNode} + * @private + */ + this._delayNode = this.input = this.output = this.context.createDelay(this._maxDelay); + /** + * The amount of time the incoming signal is + * delayed. + * @type {Time} + * @signal + */ + this.delayTime = new Tone.Param({ + 'param': this._delayNode.delayTime, + 'units': Tone.Type.Time, + 'value': options.delayTime + }); + this._readOnly('delayTime'); + }; + Tone.extend(Tone.Delay, Tone.AudioNode); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Delay.defaults = { + 'maxDelay': 1, + 'delayTime': 0 + }; + /** + * The maximum delay time. This cannot be changed. The value is passed into the constructor. + * @memberof Tone.Delay# + * @type {Time} + * @name maxDelay + * @readOnly + */ + Object.defineProperty(Tone.Delay.prototype, 'maxDelay', { + get: function () { + return this._maxDelay; + } + }); + /** + * Clean up. + * @return {Tone.Delay} this + */ + Tone.Delay.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._delayNode.disconnect(); + this._delayNode = null; + this._writable('delayTime'); + this.delayTime = null; + return this; + }; + return Tone.Delay; + }); + Module(function (Tone) { + + /** + * @class Comb filters are basic building blocks for physical modeling. Read more + * about comb filters on [CCRMA's website](https://ccrma.stanford.edu/~jos/pasp/Feedback_Comb_Filters.html). + * + * @extends {Tone.AudioNode} + * @constructor + * @param {Time|Object} [delayTime] The delay time of the filter. + * @param {NormalRange=} resonance The amount of feedback the filter has. + */ + Tone.FeedbackCombFilter = function () { + var options = Tone.defaults(arguments, [ + 'delayTime', + 'resonance' + ], Tone.FeedbackCombFilter); + Tone.AudioNode.call(this); + /** + * the delay node + * @type {DelayNode} + * @private + */ + this._delay = this.input = this.output = new Tone.Delay(options.delayTime); + /** + * The amount of delay of the comb filter. + * @type {Time} + * @signal + */ + this.delayTime = this._delay.delayTime; + /** + * the feedback node + * @type {GainNode} + * @private + */ + this._feedback = new Tone.Gain(options.resonance, Tone.Type.NormalRange); + /** + * The amount of feedback of the delayed signal. + * @type {NormalRange} + * @signal + */ + this.resonance = this._feedback.gain; + this._delay.chain(this._feedback, this._delay); + this._readOnly([ + 'resonance', + 'delayTime' + ]); + }; + Tone.extend(Tone.FeedbackCombFilter, Tone.AudioNode); + /** + * the default parameters + * @static + * @const + * @type {Object} + */ + Tone.FeedbackCombFilter.defaults = { + 'delayTime': 0.1, + 'resonance': 0.5 + }; + /** + * clean up + * @returns {Tone.FeedbackCombFilter} this + */ + Tone.FeedbackCombFilter.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._writable([ + 'resonance', + 'delayTime' + ]); + this._delay.dispose(); + this._delay = null; + this.delayTime = null; + this._feedback.dispose(); + this._feedback = null; + this.resonance = null; + return this; + }; + return Tone.FeedbackCombFilter; + }); + Module(function (Tone) { + /** + * @class Get the current waveform data of the connected audio source. + * @extends {Tone.AudioNode} + * @param {Number=} size The size of the FFT. Value must be a power of + * two in the range 32 to 32768. + */ + Tone.FFT = function () { + var options = Tone.defaults(arguments, ['size'], Tone.FFT); + options.type = Tone.Analyser.Type.FFT; + Tone.AudioNode.call(this); + /** + * The analyser node. + * @private + * @type {Tone.Analyser} + */ + this._analyser = this.input = this.output = new Tone.Analyser(options); + }; + Tone.extend(Tone.FFT, Tone.AudioNode); + /** + * The default values. + * @type {Object} + * @const + */ + Tone.FFT.defaults = { 'size': 1024 }; + /** + * Gets the waveform of the audio source. Returns the waveform data + * of length [size](#size) as a Float32Array with values between -1 and 1. + * @returns {TypedArray} + */ + Tone.FFT.prototype.getValue = function () { + return this._analyser.getValue(); + }; + /** + * The size of analysis. This must be a power of two in the range 32 to 32768. + * @memberOf Tone.FFT# + * @type {Number} + * @name size + */ + Object.defineProperty(Tone.FFT.prototype, 'size', { + get: function () { + return this._analyser.size; + }, + set: function (size) { + this._analyser.size = size; + } + }); + /** + * Clean up. + * @return {Tone.FFT} this + */ + Tone.FFT.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._analyser.dispose(); + this._analyser = null; + }; + return Tone.FFT; + }); + Module(function (Tone) { + + /** + * @class Return the absolute value of an incoming signal. + * + * @constructor + * @extends {Tone.SignalBase} + * @example + * var signal = new Tone.Signal(-1); + * var abs = new Tone.Abs(); + * signal.connect(abs); + * //the output of abs is 1. + */ + Tone.Abs = function () { + Tone.SignalBase.call(this); + /** + * @type {Tone.LessThan} + * @private + */ + this._abs = this.input = this.output = new Tone.WaveShaper(function (val) { + if (Math.abs(val) < 0.001) { + return 0; + } else { + return Math.abs(val); + } + }, 1024); + }; + Tone.extend(Tone.Abs, Tone.SignalBase); + /** + * dispose method + * @returns {Tone.Abs} this + */ + Tone.Abs.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._abs.dispose(); + this._abs = null; + return this; + }; + return Tone.Abs; + }); + Module(function (Tone) { + + /** + * @class Tone.Follower is a crude envelope follower which will follow + * the amplitude of an incoming signal. + * Take care with small (< 0.02) attack or decay values + * as follower has some ripple which is exaggerated + * at these values. Read more about envelope followers (also known + * as envelope detectors) on [Wikipedia](https://en.wikipedia.org/wiki/Envelope_detector). + * + * @constructor + * @extends {Tone.AudioNode} + * @param {Time|Object} [attack] The rate at which the follower rises. + * @param {Time=} release The rate at which the folower falls. + * @example + * var follower = new Tone.Follower(0.2, 0.4); + */ + Tone.Follower = function () { + var options = Tone.defaults(arguments, [ + 'attack', + 'release' + ], Tone.Follower); + Tone.AudioNode.call(this); + this.createInsOuts(1, 1); + /** + * @type {Tone.Abs} + * @private + */ + this._abs = new Tone.Abs(); + /** + * the lowpass filter which smooths the input + * @type {BiquadFilterNode} + * @private + */ + this._filter = this.context.createBiquadFilter(); + this._filter.type = 'lowpass'; + this._filter.frequency.value = 0; + this._filter.Q.value = -100; + /** + * @type {WaveShaperNode} + * @private + */ + this._frequencyValues = new Tone.WaveShaper(); + /** + * @type {Tone.Subtract} + * @private + */ + this._sub = new Tone.Subtract(); + /** + * @type {Tone.Delay} + * @private + */ + this._delay = new Tone.Delay(this.blockTime); + /** + * this keeps it far from 0, even for very small differences + * @type {Tone.Multiply} + * @private + */ + this._mult = new Tone.Multiply(10000); + /** + * @private + * @type {number} + */ + this._attack = options.attack; + /** + * @private + * @type {number} + */ + this._release = options.release; + //the smoothed signal to get the values + this.input.chain(this._abs, this._filter, this.output); + //the difference path + this._abs.connect(this._sub, 0, 1); + this._filter.chain(this._delay, this._sub); + //threshold the difference and use the thresh to set the frequency + this._sub.chain(this._mult, this._frequencyValues, this._filter.frequency); + //set the attack and release values in the table + this._setAttackRelease(this._attack, this._release); + }; + Tone.extend(Tone.Follower, Tone.AudioNode); + /** + * @static + * @type {Object} + */ + Tone.Follower.defaults = { + 'attack': 0.05, + 'release': 0.5 + }; + /** + * sets the attack and release times in the wave shaper + * @param {Time} attack + * @param {Time} release + * @private + */ + Tone.Follower.prototype._setAttackRelease = function (attack, release) { + var minTime = this.blockTime; + attack = Tone.Time(attack).toFrequency(); + release = Tone.Time(release).toFrequency(); + attack = Math.max(attack, minTime); + release = Math.max(release, minTime); + this._frequencyValues.setMap(function (val) { + if (val <= 0) { + return attack; + } else { + return release; + } + }); + }; + /** + * The attack time. + * @memberOf Tone.Follower# + * @type {Time} + * @name attack + */ + Object.defineProperty(Tone.Follower.prototype, 'attack', { + get: function () { + return this._attack; + }, + set: function (attack) { + this._attack = attack; + this._setAttackRelease(this._attack, this._release); + } + }); + /** + * The release time. + * @memberOf Tone.Follower# + * @type {Time} + * @name release + */ + Object.defineProperty(Tone.Follower.prototype, 'release', { + get: function () { + return this._release; + }, + set: function (release) { + this._release = release; + this._setAttackRelease(this._attack, this._release); + } + }); + /** + * Borrows the connect method from Signal so that the output can be used + * as a Tone.Signal control signal. + * @function + */ + Tone.Follower.prototype.connect = Tone.SignalBase.prototype.connect; + /** + * dispose + * @returns {Tone.Follower} this + */ + Tone.Follower.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._filter.disconnect(); + this._filter = null; + this._frequencyValues.disconnect(); + this._frequencyValues = null; + this._delay.dispose(); + this._delay = null; + this._sub.disconnect(); + this._sub = null; + this._abs.dispose(); + this._abs = null; + this._mult.dispose(); + this._mult = null; + this._curve = null; + return this; + }; + return Tone.Follower; + }); + Module(function (Tone) { + + /** + * @class Tone.ScaledEnvelop is an envelope which can be scaled + * to any range. It's useful for applying an envelope + * to a frequency or any other non-NormalRange signal + * parameter. + * + * @extends {Tone.Envelope} + * @constructor + * @param {Time|Object} [attack] the attack time in seconds + * @param {Time} [decay] the decay time in seconds + * @param {number} [sustain] a percentage (0-1) of the full amplitude + * @param {Time} [release] the release time in seconds + * @example + * var scaledEnv = new Tone.ScaledEnvelope({ + * "attack" : 0.2, + * "min" : 200, + * "max" : 2000 + * }); + * scaledEnv.connect(oscillator.frequency); + */ + Tone.ScaledEnvelope = function () { + //get all of the defaults + var options = Tone.defaults(arguments, [ + 'attack', + 'decay', + 'sustain', + 'release' + ], Tone.Envelope); + Tone.Envelope.call(this, options); + options = Tone.defaultArg(options, Tone.ScaledEnvelope.defaults); + /** + * scale the incoming signal by an exponent + * @type {Tone.Pow} + * @private + */ + this._exp = this.output = new Tone.Pow(options.exponent); + /** + * scale the signal to the desired range + * @type {Tone.Multiply} + * @private + */ + this._scale = this.output = new Tone.Scale(options.min, options.max); + this._sig.chain(this._exp, this._scale); + }; + Tone.extend(Tone.ScaledEnvelope, Tone.Envelope); + /** + * the default parameters + * @static + */ + Tone.ScaledEnvelope.defaults = { + 'min': 0, + 'max': 1, + 'exponent': 1 + }; + /** + * The envelope's min output value. This is the value which it + * starts at. + * @memberOf Tone.ScaledEnvelope# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.ScaledEnvelope.prototype, 'min', { + get: function () { + return this._scale.min; + }, + set: function (min) { + this._scale.min = min; + } + }); + /** + * The envelope's max output value. In other words, the value + * at the peak of the attack portion of the envelope. + * @memberOf Tone.ScaledEnvelope# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.ScaledEnvelope.prototype, 'max', { + get: function () { + return this._scale.max; + }, + set: function (max) { + this._scale.max = max; + } + }); + /** + * The envelope's exponent value. + * @memberOf Tone.ScaledEnvelope# + * @type {number} + * @name exponent + */ + Object.defineProperty(Tone.ScaledEnvelope.prototype, 'exponent', { + get: function () { + return this._exp.value; + }, + set: function (exp) { + this._exp.value = exp; + } + }); + /** + * clean up + * @returns {Tone.ScaledEnvelope} this + */ + Tone.ScaledEnvelope.prototype.dispose = function () { + Tone.Envelope.prototype.dispose.call(this); + this._scale.dispose(); + this._scale = null; + this._exp.dispose(); + this._exp = null; + return this; + }; + return Tone.ScaledEnvelope; + }); + Module(function (Tone) { + + /** + * @class Tone.FrequencyEnvelope is a Tone.ScaledEnvelope, but instead of `min` and `max` + * it's got a `baseFrequency` and `octaves` parameter. + * + * @extends {Tone.Envelope} + * @constructor + * @param {Time|Object} [attack] the attack time in seconds + * @param {Time} [decay] the decay time in seconds + * @param {number} [sustain] a percentage (0-1) of the full amplitude + * @param {Time} [release] the release time in seconds + * @example + * var freqEnv = new Tone.FrequencyEnvelope({ + * "attack" : 0.2, + * "baseFrequency" : "C2", + * "octaves" : 4 + * }); + * freqEnv.connect(oscillator.frequency); + */ + Tone.FrequencyEnvelope = function () { + var options = Tone.defaults(arguments, [ + 'attack', + 'decay', + 'sustain', + 'release' + ], Tone.Envelope); + Tone.ScaledEnvelope.call(this, options); + //merge it with the frequency envelope defaults + options = Tone.defaultArg(options, Tone.FrequencyEnvelope.defaults); + /** + * Stores the octave value + * @type {Positive} + * @private + */ + this._octaves = options.octaves; + //setup + this.baseFrequency = options.baseFrequency; + this.octaves = options.octaves; + }; + Tone.extend(Tone.FrequencyEnvelope, Tone.Envelope); + /** + * the default parameters + * @static + */ + Tone.FrequencyEnvelope.defaults = { + 'baseFrequency': 200, + 'octaves': 4, + 'exponent': 2 + }; + /** + * The envelope's mininum output value. This is the value which it + * starts at. + * @memberOf Tone.FrequencyEnvelope# + * @type {Frequency} + * @name baseFrequency + */ + Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'baseFrequency', { + get: function () { + return this._scale.min; + }, + set: function (min) { + this._scale.min = this.toFrequency(min); + //also update the octaves + this.octaves = this._octaves; + } + }); + /** + * The number of octaves above the baseFrequency that the + * envelope will scale to. + * @memberOf Tone.FrequencyEnvelope# + * @type {Positive} + * @name octaves + */ + Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (octaves) { + this._octaves = octaves; + this._scale.max = this.baseFrequency * Math.pow(2, octaves); + } + }); + /** + * The envelope's exponent value. + * @memberOf Tone.FrequencyEnvelope# + * @type {number} + * @name exponent + */ + Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'exponent', { + get: function () { + return this._exp.value; + }, + set: function (exp) { + this._exp.value = exp; + } + }); + /** + * clean up + * @returns {Tone.FrequencyEnvelope} this + */ + Tone.FrequencyEnvelope.prototype.dispose = function () { + Tone.ScaledEnvelope.prototype.dispose.call(this); + return this; + }; + return Tone.FrequencyEnvelope; + }); + Module(function (Tone) { + + /** + * @class GreaterThanZero outputs 1 when the input is strictly greater than zero + * + * @constructor + * @extends {Tone.SignalBase} + * @example + * var gt0 = new Tone.GreaterThanZero(); + * var sig = new Tone.Signal(0.01).connect(gt0); + * //the output of gt0 is 1. + * sig.value = 0; + * //the output of gt0 is 0. + */ + Tone.GreaterThanZero = function () { + Tone.SignalBase.call(this); + /** + * @type {Tone.WaveShaper} + * @private + */ + this._thresh = this.output = new Tone.WaveShaper(function (val) { + if (val <= 0) { + return 0; + } else { + return 1; + } + }, 127); + /** + * scale the first thresholded signal by a large value. + * this will help with values which are very close to 0 + * @type {Tone.Multiply} + * @private + */ + this._scale = this.input = new Tone.Multiply(10000); + //connections + this._scale.connect(this._thresh); + }; + Tone.extend(Tone.GreaterThanZero, Tone.SignalBase); + /** + * dispose method + * @returns {Tone.GreaterThanZero} this + */ + Tone.GreaterThanZero.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._scale.dispose(); + this._scale = null; + this._thresh.dispose(); + this._thresh = null; + return this; + }; + return Tone.GreaterThanZero; + }); + Module(function (Tone) { + + /** + * @class Output 1 if the signal is greater than the value, otherwise outputs 0. + * can compare two signals or a signal and a number. + * + * @constructor + * @extends {Tone.Signal} + * @param {number} [value=0] the value to compare to the incoming signal + * @example + * var gt = new Tone.GreaterThan(2); + * var sig = new Tone.Signal(4).connect(gt); + * //output of gt is equal 1. + */ + Tone.GreaterThan = function (value) { + Tone.Signal.call(this); + this.createInsOuts(2, 0); + /** + * subtract the amount from the incoming signal + * @type {Tone.Subtract} + * @private + */ + this._param = this.input[0] = new Tone.Subtract(value); + this.input[1] = this._param.input[1]; + /** + * compare that amount to zero + * @type {Tone.GreaterThanZero} + * @private + */ + this._gtz = this.output = new Tone.GreaterThanZero(); + //connect + this._param.connect(this._gtz); + }; + Tone.extend(Tone.GreaterThan, Tone.Signal); + /** + * dispose method + * @returns {Tone.GreaterThan} this + */ + Tone.GreaterThan.prototype.dispose = function () { + Tone.Signal.prototype.dispose.call(this); + this._gtz.dispose(); + this._gtz = null; + return this; + }; + return Tone.GreaterThan; + }); + Module(function (Tone) { + + /** + * @class Tone.Gate only passes a signal through when the incoming + * signal exceeds a specified threshold. To do this, Gate uses + * a Tone.Follower to follow the amplitude of the incoming signal. + * A common implementation of this class is a [Noise Gate](https://en.wikipedia.org/wiki/Noise_gate). + * + * @constructor + * @extends {Tone.AudioNode} + * @param {Decibels|Object} [threshold] The threshold above which the gate will open. + * @param {Time=} attack The follower's attack time + * @param {Time=} release The follower's release time + * @example + * var gate = new Tone.Gate(-30, 0.2, 0.3).toMaster(); + * var mic = new Tone.UserMedia().connect(gate); + * //the gate will only pass through the incoming + * //signal when it's louder than -30db + */ + Tone.Gate = function () { + var options = Tone.defaults(arguments, [ + 'threshold', + 'attack', + 'release' + ], Tone.Gate); + Tone.AudioNode.call(this); + this.createInsOuts(1, 1); + /** + * @type {Tone.Follower} + * @private + */ + this._follower = new Tone.Follower(options.attack, options.release); + /** + * @type {Tone.GreaterThan} + * @private + */ + this._gt = new Tone.GreaterThan(Tone.dbToGain(options.threshold)); + //the connections + this.input.connect(this.output); + //the control signal + this.input.chain(this._gt, this._follower, this.output.gain); + }; + Tone.extend(Tone.Gate, Tone.AudioNode); + /** + * @const + * @static + * @type {Object} + */ + Tone.Gate.defaults = { + 'attack': 0.1, + 'release': 0.1, + 'threshold': -40 + }; + /** + * The threshold of the gate in decibels + * @memberOf Tone.Gate# + * @type {Decibels} + * @name threshold + */ + Object.defineProperty(Tone.Gate.prototype, 'threshold', { + get: function () { + return Tone.gainToDb(this._gt.value); + }, + set: function (thresh) { + this._gt.value = Tone.dbToGain(thresh); + } + }); + /** + * The attack speed of the gate + * @memberOf Tone.Gate# + * @type {Time} + * @name attack + */ + Object.defineProperty(Tone.Gate.prototype, 'attack', { + get: function () { + return this._follower.attack; + }, + set: function (attackTime) { + this._follower.attack = attackTime; + } + }); + /** + * The release speed of the gate + * @memberOf Tone.Gate# + * @type {Time} + * @name release + */ + Object.defineProperty(Tone.Gate.prototype, 'release', { + get: function () { + return this._follower.release; + }, + set: function (releaseTime) { + this._follower.release = releaseTime; + } + }); + /** + * Clean up. + * @returns {Tone.Gate} this + */ + Tone.Gate.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._follower.dispose(); + this._gt.dispose(); + this._follower = null; + this._gt = null; + return this; + }; + return Tone.Gate; + }); + Module(function (Tone) { + /** + * @class Tone.TickSignal extends Tone.Signal, but adds the capability + * to calculate the number of elapsed ticks. exponential and target curves + * are approximated with multiple linear ramps. + * + * Thank you Bruno Dias, H. Sofia Pinto, and David M. Matos, for your [WAC paper](https://smartech.gatech.edu/bitstream/handle/1853/54588/WAC2016-49.pdf) + * describing integrating timing functions for tempo calculations. + * + * @param {Number} value The initial value of the signal + * @extends {Tone.Signal} + */ + Tone.TickSignal = function (value) { + value = Tone.defaultArg(value, 1); + Tone.Signal.call(this, { + 'units': Tone.Type.Ticks, + 'value': value + }); + //extend the memory + this._events.memory = Infinity; + //clear the clock from the beginning + this.cancelScheduledValues(0); + //set an initial event + this._events.add({ + 'type': Tone.Param.AutomationType.SetValue, + 'time': 0, + 'value': value + }); + }; + Tone.extend(Tone.TickSignal, Tone.Signal); + /** + * Wraps Tone.Signal methods so that they also + * record the ticks. + * @param {Function} method + * @return {Function} + * @private + */ + function _wrapScheduleMethods(method) { + return function (value, time) { + time = this.toSeconds(time); + method.apply(this, arguments); + var event = this._events.get(time); + var previousEvent = this._events.previousEvent(event); + var ticksUntilTime = this._getTicksUntilEvent(previousEvent, time); + event.ticks = Math.max(ticksUntilTime, 0); + return this; + }; + } + Tone.TickSignal.prototype.setValueAtTime = _wrapScheduleMethods(Tone.Signal.prototype.setValueAtTime); + Tone.TickSignal.prototype.linearRampToValueAtTime = _wrapScheduleMethods(Tone.Signal.prototype.linearRampToValueAtTime); + /** + * Start exponentially approaching the target value at the given time with + * a rate having the given time constant. + * @param {number} value + * @param {Time} startTime + * @param {number} timeConstant + * @returns {Tone.TickSignal} this + */ + Tone.TickSignal.prototype.setTargetAtTime = function (value, time, constant) { + //aproximate it with multiple linear ramps + time = this.toSeconds(time); + this.setRampPoint(time); + value = this._fromUnits(value); + //start from previously scheduled value + var prevEvent = this._events.get(time); + var segments = Math.round(Math.max(1 / constant, 1)); + for (var i = 0; i <= segments; i++) { + var segTime = constant * i + time; + var rampVal = this._exponentialApproach(prevEvent.time, prevEvent.value, value, constant, segTime); + this.linearRampToValueAtTime(this._toUnits(rampVal), segTime); + } + return this; + }; + /** + * Schedules an exponential continuous change in parameter value from + * the previous scheduled parameter value to the given value. + * @param {number} value + * @param {Time} endTime + * @returns {Tone.TickSignal} this + */ + Tone.TickSignal.prototype.exponentialRampToValueAtTime = function (value, time) { + //aproximate it with multiple linear ramps + time = this.toSeconds(time); + value = this._fromUnits(value); + //start from previously scheduled value + var prevEvent = this._events.get(time); + if (prevEvent === null) { + prevEvent = { + 'value': this._initialValue, + 'time': 0 + }; + } + //approx 10 segments per second + var segments = Math.round(Math.max((time - prevEvent.time) * 10, 1)); + var segmentDur = (time - prevEvent.time) / segments; + for (var i = 0; i <= segments; i++) { + var segTime = segmentDur * i + prevEvent.time; + var rampVal = this._exponentialInterpolate(prevEvent.time, prevEvent.value, time, value, segTime); + this.linearRampToValueAtTime(this._toUnits(rampVal), segTime); + } + return this; + }; + /** + * Returns the tick value at the time. Takes into account + * any automation curves scheduled on the signal. + * @private + * @param {Time} time The time to get the tick count at + * @return {Ticks} The number of ticks which have elapsed at the time + * given any automations. + */ + Tone.TickSignal.prototype._getTicksUntilEvent = function (event, time) { + if (event === null) { + event = { + 'ticks': 0, + 'time': 0 + }; + } else if (Tone.isUndef(event.ticks)) { + var previousEvent = this._events.previousEvent(event); + event.ticks = this._getTicksUntilEvent(previousEvent, event.time); + } + var val0 = this.getValueAtTime(event.time); + var val1 = this.getValueAtTime(time); + //if it's right on the line, take the previous value + if (this._events.get(time).time === time && this._events.get(time).type === Tone.Param.AutomationType.SetValue) { + val1 = this.getValueAtTime(time - this.sampleTime); + } + return 0.5 * (time - event.time) * (val0 + val1) + event.ticks; + }; + /** + * Returns the tick value at the time. Takes into account + * any automation curves scheduled on the signal. + * @param {Time} time The time to get the tick count at + * @return {Ticks} The number of ticks which have elapsed at the time + * given any automations. + */ + Tone.TickSignal.prototype.getTicksAtTime = function (time) { + time = this.toSeconds(time); + var event = this._events.get(time); + return Math.max(this._getTicksUntilEvent(event, time), 0); + }; + /** + * Return the elapsed time of the number of ticks from the given time + * @param {Ticks} ticks The number of ticks to calculate + * @param {Time} time The time to get the next tick from + * @return {Seconds} The duration of the number of ticks from the given time in seconds + */ + Tone.TickSignal.prototype.getDurationOfTicks = function (ticks, time) { + time = this.toSeconds(time); + var currentTick = this.getTicksAtTime(time); + return this.getTimeOfTick(currentTick + ticks) - time; + }; + /** + * Given a tick, returns the time that tick occurs at. + * @param {Ticks} tick + * @return {Time} The time that the tick occurs. + */ + Tone.TickSignal.prototype.getTimeOfTick = function (tick) { + var before = this._events.get(tick, 'ticks'); + var after = this._events.getAfter(tick, 'ticks'); + if (before && before.ticks === tick) { + return before.time; + } else if (before && after && after.type === Tone.Param.AutomationType.Linear && before.value !== after.value) { + var val0 = this.getValueAtTime(before.time); + var val1 = this.getValueAtTime(after.time); + var delta = (val1 - val0) / (after.time - before.time); + var k = Math.sqrt(Math.pow(val0, 2) - 2 * delta * (before.ticks - tick)); + var sol1 = (-val0 + k) / delta; + var sol2 = (-val0 - k) / delta; + return (sol1 > 0 ? sol1 : sol2) + before.time; + } else if (before) { + if (before.value === 0) { + return Infinity; + } else { + return before.time + (tick - before.ticks) / before.value; + } + } else { + return tick / this._initialValue; + } + }; + /** + * Convert some number of ticks their the duration in seconds accounting + * for any automation curves starting at the given time. + * @param {Ticks} ticks The number of ticks to convert to seconds. + * @param {Time} [when=now] When along the automation timeline to convert the ticks. + * @return {Tone.Time} The duration in seconds of the ticks. + */ + Tone.TickSignal.prototype.ticksToTime = function (ticks, when) { + when = this.toSeconds(when); + return new Tone.Time(this.getDurationOfTicks(ticks, when)); + }; + /** + * The inverse of [ticksToTime](#tickstotime). Convert a duration in + * seconds to the corresponding number of ticks accounting for any + * automation curves starting at the given time. + * @param {Time} duration The time interval to convert to ticks. + * @param {Time} [when=now] When along the automation timeline to convert the ticks. + * @return {Tone.Ticks} The duration in ticks. + */ + Tone.TickSignal.prototype.timeToTicks = function (duration, when) { + when = this.toSeconds(when); + duration = this.toSeconds(duration); + var startTicks = this.getTicksAtTime(when); + var endTicks = this.getTicksAtTime(when + duration); + return new Tone.Ticks(endTicks - startTicks); + }; + return Tone.TickSignal; + }); + Module(function (Tone) { + + /** + * @class A Timeline State. Provides the methods: <code>setStateAtTime("state", time)</code> + * and <code>getValueAtTime(time)</code>. + * + * @extends {Tone.Timeline} + * @param {String} initial The initial state of the TimelineState. + * Defaults to <code>undefined</code> + */ + Tone.TimelineState = function (initial) { + Tone.Timeline.call(this); + /** + * The initial state + * @private + * @type {String} + */ + this._initial = initial; + }; + Tone.extend(Tone.TimelineState, Tone.Timeline); + /** + * Returns the scheduled state scheduled before or at + * the given time. + * @param {Number} time The time to query. + * @return {String} The name of the state input in setStateAtTime. + */ + Tone.TimelineState.prototype.getValueAtTime = function (time) { + var event = this.get(time); + if (event !== null) { + return event.state; + } else { + return this._initial; + } + }; + /** + * Add a state to the timeline. + * @param {String} state The name of the state to set. + * @param {Number} time The time to query. + * @returns {Tone.TimelineState} this + */ + Tone.TimelineState.prototype.setStateAtTime = function (state, time) { + //all state changes need to be >= the previous state time + //TODO throw error if time < the previous event time + this.add({ + 'state': state, + 'time': time + }); + return this; + }; + /** + * Return the event before the time with the given state + * @param {Tone.State} state The state to look for + * @param {Time} time When to check before + * @return {Object} The event with the given state before the time + */ + Tone.TimelineState.prototype.getLastState = function (state, time) { + time = this.toSeconds(time); + var index = this._search(time); + for (var i = index; i >= 0; i--) { + var event = this._timeline[i]; + if (event.state === state) { + return event; + } + } + }; + /** + * Return the event after the time with the given state + * @param {Tone.State} state The state to look for + * @param {Time} time When to check from + * @return {Object} The event with the given state after the time + */ + Tone.TimelineState.prototype.getNextState = function (state, time) { + time = this.toSeconds(time); + var index = this._search(time); + if (index !== -1) { + for (var i = index; i < this._timeline.length; i++) { + var event = this._timeline[i]; + if (event.state === state) { + return event; + } + } + } + }; + return Tone.TimelineState; + }); + Module(function (Tone) { + + /** + * @class Uses [Tone.TickSignal](TickSignal) to track elapsed ticks with + * complex automation curves. + * + * @constructor + * @param {Frequency} frequency The initial frequency that the signal ticks at + * @extends {Tone} + */ + Tone.TickSource = function () { + var options = Tone.defaults(arguments, ['frequency'], Tone.TickSource); + /** + * The frequency the callback function should be invoked. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.TickSignal(options.frequency, Tone.Type.Frequency); + this._readOnly('frequency'); + /** + * The state timeline + * @type {Tone.TimelineState} + * @private + */ + this._state = new Tone.TimelineState(Tone.State.Stopped); + this._state.setStateAtTime(Tone.State.Stopped, 0); + /** + * The offset values of the ticks + * @type {Tone.Timeline} + * @private + */ + this._tickOffset = new Tone.Timeline(); + //add the first event + this.setTicksAtTime(0, 0); + }; + Tone.extend(Tone.TickSource); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.TickSource.defaults = { 'frequency': 1 }; + /** + * Returns the playback state of the source, either "started", "stopped" or "paused". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.TickSource# + * @name state + */ + Object.defineProperty(Tone.TickSource.prototype, 'state', { + get: function () { + return this._state.getValueAtTime(this.now()); + } + }); + /** + * Start the clock at the given time. Optionally pass in an offset + * of where to start the tick counter from. + * @param {Time=} time The time the clock should start + * @param {Ticks=0} offset The number of ticks to start the source at + * @return {Tone.TickSource} this + */ + Tone.TickSource.prototype.start = function (time, offset) { + time = this.toSeconds(time); + if (this._state.getValueAtTime(time) !== Tone.State.Started) { + this._state.setStateAtTime(Tone.State.Started, time); + if (Tone.isDefined(offset)) { + this.setTicksAtTime(offset, time); + } + } + return this; + }; + /** + * Stop the clock. Stopping the clock resets the tick counter to 0. + * @param {Time} [time=now] The time when the clock should stop. + * @returns {Tone.TickSource} this + * @example + * clock.stop(); + */ + Tone.TickSource.prototype.stop = function (time) { + time = this.toSeconds(time); + //cancel the previous stop + if (this._state.getValueAtTime(time) === Tone.State.Stopped) { + var event = this._state.get(time); + if (event.time > 0) { + this._tickOffset.cancel(event.time); + this._state.cancel(event.time); + } + } + this._state.cancel(time); + this._state.setStateAtTime(Tone.State.Stopped, time); + this.setTicksAtTime(0, time); + return this; + }; + /** + * Pause the clock. Pausing does not reset the tick counter. + * @param {Time} [time=now] The time when the clock should stop. + * @returns {Tone.TickSource} this + */ + Tone.TickSource.prototype.pause = function (time) { + time = this.toSeconds(time); + if (this._state.getValueAtTime(time) === Tone.State.Started) { + this._state.setStateAtTime(Tone.State.Paused, time); + } + return this; + }; + /** + * Cancel start/stop/pause and setTickAtTime events scheduled after the given time. + * @param {Time} [time=now] When to clear the events after + * @returns {Tone.TickSource} this + */ + Tone.TickSource.prototype.cancel = function (time) { + time = this.toSeconds(time); + this._state.cancel(time); + this._tickOffset.cancel(time); + return this; + }; + /** + * Get the elapsed ticks at the given time + * @param {Time} time When to get the tick value + * @return {Ticks} The number of ticks + */ + Tone.TickSource.prototype.getTicksAtTime = function (time) { + time = this.toSeconds(time); + var stopEvent = this._state.getLastState(Tone.State.Stopped, time); + //this event allows forEachBetween to iterate until the current time + var tmpEvent = { + state: Tone.State.Paused, + time: time + }; + this._state.add(tmpEvent); + //keep track of the previous offset event + var lastState = stopEvent; + var elapsedTicks = 0; + //iterate through all the events since the last stop + this._state.forEachBetween(stopEvent.time, time + this.sampleTime, function (e) { + var periodStartTime = lastState.time; + //if there is an offset event in this period use that + var offsetEvent = this._tickOffset.get(e.time); + if (offsetEvent.time >= lastState.time) { + elapsedTicks = offsetEvent.ticks; + periodStartTime = offsetEvent.time; + } + if (lastState.state === Tone.State.Started && e.state !== Tone.State.Started) { + elapsedTicks += this.frequency.getTicksAtTime(e.time) - this.frequency.getTicksAtTime(periodStartTime); + } + lastState = e; + }.bind(this)); + //remove the temporary event + this._state.remove(tmpEvent); + //return the ticks + return elapsedTicks; + }; + /** + * The number of times the callback was invoked. Starts counting at 0 + * and increments after the callback was invoked. Returns -1 when stopped. + * @memberOf Tone.TickSource# + * @name ticks + * @type {Ticks} + */ + Object.defineProperty(Tone.TickSource.prototype, 'ticks', { + get: function () { + return this.getTicksAtTime(this.now()); + }, + set: function (t) { + this.setTicksAtTime(t, this.now()); + } + }); + /** + * The time since ticks=0 that the TickSource has been running. Accounts + * for tempo curves + * @memberOf Tone.TickSource# + * @name seconds + * @type {Seconds} + */ + Object.defineProperty(Tone.TickSource.prototype, 'seconds', { + get: function () { + return this.getSecondsAtTime(this.now()); + }, + set: function (s) { + var now = this.now(); + var ticks = this.frequency.timeToTicks(s, now); + this.setTicksAtTime(ticks, now); + } + }); + /** + * Return the elapsed seconds at the given time. + * @param {Time} time When to get the elapsed seconds + * @return {Seconds} The number of elapsed seconds + */ + Tone.TickSource.prototype.getSecondsAtTime = function (time) { + time = this.toSeconds(time); + var stopEvent = this._state.getLastState(Tone.State.Stopped, time); + //this event allows forEachBetween to iterate until the current time + var tmpEvent = { + state: Tone.State.Paused, + time: time + }; + this._state.add(tmpEvent); + //keep track of the previous offset event + var lastState = stopEvent; + var elapsedSeconds = 0; + //iterate through all the events since the last stop + this._state.forEachBetween(stopEvent.time, time + this.sampleTime, function (e) { + var periodStartTime = lastState.time; + //if there is an offset event in this period use that + var offsetEvent = this._tickOffset.get(e.time); + if (offsetEvent.time >= lastState.time) { + elapsedSeconds = offsetEvent.seconds; + periodStartTime = offsetEvent.time; + } + if (lastState.state === Tone.State.Started && e.state !== Tone.State.Started) { + elapsedSeconds += e.time - periodStartTime; + } + lastState = e; + }.bind(this)); + //remove the temporary event + this._state.remove(tmpEvent); + //return the ticks + return elapsedSeconds; + }; + /** + * Set the clock's ticks at the given time. + * @param {Ticks} ticks The tick value to set + * @param {Time} time When to set the tick value + * @return {Tone.TickSource} this + */ + Tone.TickSource.prototype.setTicksAtTime = function (ticks, time) { + time = this.toSeconds(time); + this._tickOffset.cancel(time); + this._tickOffset.add({ + 'time': time, + 'ticks': ticks, + 'seconds': this.frequency.getDurationOfTicks(ticks, time) + }); + return this; + }; + /** + * Returns the scheduled state at the given time. + * @param {Time} time The time to query. + * @return {String} The name of the state input in setStateAtTime. + * @example + * source.start("+0.1"); + * source.getStateAtTime("+0.1"); //returns "started" + */ + Tone.TickSource.prototype.getStateAtTime = function (time) { + time = this.toSeconds(time); + return this._state.getValueAtTime(time); + }; + /** + * Get the time of the given tick. The second argument + * is when to test before. Since ticks can be set (with setTicksAtTime) + * there may be multiple times for a given tick value. + * @param {Ticks} ticks The tick number. + * @param {Time=} before When to measure the tick value from. + * @return {Time} The time of the tick + */ + Tone.TickSource.prototype.getTimeOfTick = function (tick, before) { + before = Tone.defaultArg(before, this.now()); + var offset = this._tickOffset.get(before); + var event = this._state.get(before); + var startTime = Math.max(offset.time, event.time); + var absoluteTicks = this.frequency.getTicksAtTime(startTime) + tick - offset.ticks; + return this.frequency.getTimeOfTick(absoluteTicks); + }; + /** + * Invoke the callback event at all scheduled ticks between the + * start time and the end time + * @param {Time} startTime The beginning of the search range + * @param {Time} endTime The end of the search range + * @param {Function<Time,Ticks>} callback The callback to invoke with each tick + * @return {Tone.TickSource} this + */ + Tone.TickSource.prototype.forEachTickBetween = function (startTime, endTime, callback) { + //only iterate through the sections where it is "started" + var lastStateEvent = this._state.get(startTime); + this._state.forEachBetween(startTime, endTime, function (event) { + if (lastStateEvent.state === Tone.State.Started && event.state !== Tone.State.Started) { + this.forEachTickBetween(Math.max(lastStateEvent.time, startTime), event.time - this.sampleTime, callback); + } + lastStateEvent = event; + }.bind(this)); + startTime = Math.max(lastStateEvent.time, startTime); + if (lastStateEvent.state === Tone.State.Started && this._state) { + //figure out the difference between the frequency ticks and the + var startTicks = this.frequency.getTicksAtTime(startTime); + var ticksAtStart = this.frequency.getTicksAtTime(lastStateEvent.time); + var diff = startTicks - ticksAtStart; + var offset = diff % 1; + if (offset !== 0) { + offset = 1 - offset; + } + var nextTickTime = this.frequency.getTimeOfTick(startTicks + offset); + var error = null; + while (nextTickTime < endTime && this._state) { + try { + callback(nextTickTime, Math.round(this.getTicksAtTime(nextTickTime))); + } catch (e) { + error = e; + break; + } + if (this._state) { + nextTickTime += this.frequency.getDurationOfTicks(1, nextTickTime); + } + } + } + if (error) { + throw error; + } + return this; + }; + /** + * Clean up + * @returns {Tone.TickSource} this + */ + Tone.TickSource.prototype.dispose = function () { + Tone.Param.prototype.dispose.call(this); + this._state.dispose(); + this._state = null; + this._tickOffset.dispose(); + this._tickOffset = null; + this._writable('frequency'); + this.frequency.dispose(); + this.frequency = null; + return this; + }; + return Tone.TickSource; + }); + Module(function (Tone) { + + /** + * @class A sample accurate clock which provides a callback at the given rate. + * While the callback is not sample-accurate (it is still susceptible to + * loose JS timing), the time passed in as the argument to the callback + * is precise. For most applications, it is better to use Tone.Transport + * instead of the Clock by itself since you can synchronize multiple callbacks. + * + * @constructor + * @extends {Tone.Emitter} + * @param {function} callback The callback to be invoked with the time of the audio event + * @param {Frequency} frequency The rate of the callback + * @example + * //the callback will be invoked approximately once a second + * //and will print the time exactly once a second apart. + * var clock = new Tone.Clock(function(time){ + * console.log(time); + * }, 1); + */ + Tone.Clock = function () { + var options = Tone.defaults(arguments, [ + 'callback', + 'frequency' + ], Tone.Clock); + Tone.Emitter.call(this); + /** + * The callback function to invoke at the scheduled tick. + * @type {Function} + */ + this.callback = options.callback; + /** + * The next time the callback is scheduled. + * @type {Number} + * @private + */ + this._nextTick = 0; + /** + * The tick counter + * @type {Tone.TickSource} + * @private + */ + this._tickSource = new Tone.TickSource(options.frequency); + /** + * The last time the loop callback was invoked + * @private + * @type {Number} + */ + this._lastUpdate = 0; + /** + * The rate the callback function should be invoked. + * @type {BPM} + * @signal + */ + this.frequency = this._tickSource.frequency; + this._readOnly('frequency'); + /** + * The state timeline + * @type {Tone.TimelineState} + * @private + */ + this._state = new Tone.TimelineState(Tone.State.Stopped); + //add an initial state + this._state.setStateAtTime(Tone.State.Stopped, 0); + /** + * The loop function bound to its context. + * This is necessary to remove the event in the end. + * @type {Function} + * @private + */ + this._boundLoop = this._loop.bind(this); + //bind a callback to the worker thread + this.context.on('tick', this._boundLoop); + }; + Tone.extend(Tone.Clock, Tone.Emitter); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Clock.defaults = { + 'callback': Tone.noOp, + 'frequency': 1 + }; + /** + * Returns the playback state of the source, either "started", "stopped" or "paused". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.Clock# + * @name state + */ + Object.defineProperty(Tone.Clock.prototype, 'state', { + get: function () { + return this._state.getValueAtTime(this.now()); + } + }); + /** + * Start the clock at the given time. Optionally pass in an offset + * of where to start the tick counter from. + * @param {Time=} time The time the clock should start + * @param {Ticks=} offset Where the tick counter starts counting from. + * @return {Tone.Clock} this + */ + Tone.Clock.prototype.start = function (time, offset) { + time = this.toSeconds(time); + if (this._state.getValueAtTime(time) !== Tone.State.Started) { + this._state.setStateAtTime(Tone.State.Started, time); + this._tickSource.start(time, offset); + if (time < this._lastUpdate) { + this.emit('start', time, offset); + } + } + return this; + }; + /** + * Stop the clock. Stopping the clock resets the tick counter to 0. + * @param {Time} [time=now] The time when the clock should stop. + * @returns {Tone.Clock} this + * @example + * clock.stop(); + */ + Tone.Clock.prototype.stop = function (time) { + time = this.toSeconds(time); + this._state.cancel(time); + this._state.setStateAtTime(Tone.State.Stopped, time); + this._tickSource.stop(time); + if (time < this._lastUpdate) { + this.emit('stop', time); + } + return this; + }; + /** + * Pause the clock. Pausing does not reset the tick counter. + * @param {Time} [time=now] The time when the clock should stop. + * @returns {Tone.Clock} this + */ + Tone.Clock.prototype.pause = function (time) { + time = this.toSeconds(time); + if (this._state.getValueAtTime(time) === Tone.State.Started) { + this._state.setStateAtTime(Tone.State.Paused, time); + this._tickSource.pause(time); + if (time < this._lastUpdate) { + this.emit('pause', time); + } + } + return this; + }; + /** + * The number of times the callback was invoked. Starts counting at 0 + * and increments after the callback was invoked. + * @type {Ticks} + */ + Object.defineProperty(Tone.Clock.prototype, 'ticks', { + get: function () { + return Math.ceil(this.getTicksAtTime(this.now())); + }, + set: function (t) { + this._tickSource.ticks = t; + } + }); + /** + * The time since ticks=0 that the Clock has been running. Accounts + * for tempo curves + * @type {Seconds} + */ + Object.defineProperty(Tone.Clock.prototype, 'seconds', { + get: function () { + return this._tickSource.seconds; + }, + set: function (s) { + this._tickSource.seconds = s; + } + }); + /** + * Return the elapsed seconds at the given time. + * @param {Time} time When to get the elapsed seconds + * @return {Seconds} The number of elapsed seconds + */ + Tone.Clock.prototype.getSecondsAtTime = function (time) { + return this._tickSource.getSecondsAtTime(time); + }; + /** + * Set the clock's ticks at the given time. + * @param {Ticks} ticks The tick value to set + * @param {Time} time When to set the tick value + * @return {Tone.Clock} this + */ + Tone.Clock.prototype.setTicksAtTime = function (ticks, time) { + this._tickSource.setTicksAtTime(ticks, time); + return this; + }; + /** + * Get the clock's ticks at the given time. + * @param {Time} time When to get the tick value + * @return {Ticks} The tick value at the given time. + */ + Tone.Clock.prototype.getTicksAtTime = function (time) { + return this._tickSource.getTicksAtTime(time); + }; + /** + * Get the time of the next tick + * @param {Ticks} ticks The tick number. + * @param {Time} before + * @return {Tone.Clock} this + */ + Tone.Clock.prototype.nextTickTime = function (offset, when) { + when = this.toSeconds(when); + var currentTick = this.getTicksAtTime(when); + return this._tickSource.getTimeOfTick(currentTick + offset, when); + }; + /** + * The scheduling loop. + * @private + */ + Tone.Clock.prototype._loop = function () { + var startTime = this._lastUpdate; + var endTime = this.now(); + this._lastUpdate = endTime; + if (startTime !== endTime) { + //the state change events + this._state.forEachBetween(startTime, endTime, function (e) { + switch (e.state) { + case Tone.State.Started: + var offset = this._tickSource.getTicksAtTime(e.time); + this.emit('start', e.time, offset); + break; + case Tone.State.Stopped: + if (e.time !== 0) { + this.emit('stop', e.time); + } + break; + case Tone.State.Paused: + this.emit('pause', e.time); + break; + } + }.bind(this)); + //the tick callbacks + this._tickSource.forEachTickBetween(startTime, endTime, function (time, ticks) { + this.callback(time, ticks); + }.bind(this)); + } + }; + /** + * Returns the scheduled state at the given time. + * @param {Time} time The time to query. + * @return {String} The name of the state input in setStateAtTime. + * @example + * clock.start("+0.1"); + * clock.getStateAtTime("+0.1"); //returns "started" + */ + Tone.Clock.prototype.getStateAtTime = function (time) { + time = this.toSeconds(time); + return this._state.getValueAtTime(time); + }; + /** + * Clean up + * @returns {Tone.Clock} this + */ + Tone.Clock.prototype.dispose = function () { + Tone.Emitter.prototype.dispose.call(this); + this.context.off('tick', this._boundLoop); + this._writable('frequency'); + this._tickSource.dispose(); + this._tickSource = null; + this.frequency = null; + this._boundLoop = null; + this._nextTick = Infinity; + this.callback = null; + this._state.dispose(); + this._state = null; + }; + return Tone.Clock; + }); + Module(function (Tone) { + + /** + * @class Similar to Tone.Timeline, but all events represent + * intervals with both "time" and "duration" times. The + * events are placed in a tree structure optimized + * for querying an intersection point with the timeline + * events. Internally uses an [Interval Tree](https://en.wikipedia.org/wiki/Interval_tree) + * to represent the data. + * @extends {Tone} + */ + Tone.IntervalTimeline = function () { + Tone.call(this); + /** + * The root node of the inteval tree + * @type {IntervalNode} + * @private + */ + this._root = null; + /** + * Keep track of the length of the timeline. + * @type {Number} + * @private + */ + this._length = 0; + }; + Tone.extend(Tone.IntervalTimeline); + /** + * The event to add to the timeline. All events must + * have a time and duration value + * @param {Object} event The event to add to the timeline + * @return {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.add = function (event) { + if (Tone.isUndef(event.time) || Tone.isUndef(event.duration)) { + throw new Error('Tone.IntervalTimeline: events must have time and duration parameters'); + } + event.time = event.time.valueOf(); + var node = new IntervalNode(event.time, event.time + event.duration, event); + if (this._root === null) { + this._root = node; + } else { + this._root.insert(node); + } + this._length++; + // Restructure tree to be balanced + while (node !== null) { + node.updateHeight(); + node.updateMax(); + this._rebalance(node); + node = node.parent; + } + return this; + }; + /** + * Remove an event from the timeline. + * @param {Object} event The event to remove from the timeline + * @return {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.remove = function (event) { + if (this._root !== null) { + var results = []; + this._root.search(event.time, results); + for (var i = 0; i < results.length; i++) { + var node = results[i]; + if (node.event === event) { + this._removeNode(node); + this._length--; + break; + } + } + } + return this; + }; + /** + * The number of items in the timeline. + * @type {Number} + * @memberOf Tone.IntervalTimeline# + * @name length + * @readOnly + */ + Object.defineProperty(Tone.IntervalTimeline.prototype, 'length', { + get: function () { + return this._length; + } + }); + /** + * Remove events whose time time is after the given time + * @param {Number} time The time to query. + * @returns {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.cancel = function (after) { + this.forEachFrom(after, function (event) { + this.remove(event); + }.bind(this)); + return this; + }; + /** + * Set the root node as the given node + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._setRoot = function (node) { + this._root = node; + if (this._root !== null) { + this._root.parent = null; + } + }; + /** + * Replace the references to the node in the node's parent + * with the replacement node. + * @param {IntervalNode} node + * @param {IntervalNode} replacement + * @private + */ + Tone.IntervalTimeline.prototype._replaceNodeInParent = function (node, replacement) { + if (node.parent !== null) { + if (node.isLeftChild()) { + node.parent.left = replacement; + } else { + node.parent.right = replacement; + } + this._rebalance(node.parent); + } else { + this._setRoot(replacement); + } + }; + /** + * Remove the node from the tree and replace it with + * a successor which follows the schema. + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._removeNode = function (node) { + if (node.left === null && node.right === null) { + this._replaceNodeInParent(node, null); + } else if (node.right === null) { + this._replaceNodeInParent(node, node.left); + } else if (node.left === null) { + this._replaceNodeInParent(node, node.right); + } else { + var balance = node.getBalance(); + var replacement, temp; + if (balance > 0) { + if (node.left.right === null) { + replacement = node.left; + replacement.right = node.right; + temp = replacement; + } else { + replacement = node.left.right; + while (replacement.right !== null) { + replacement = replacement.right; + } + replacement.parent.right = replacement.left; + temp = replacement.parent; + replacement.left = node.left; + replacement.right = node.right; + } + } else if (node.right.left === null) { + replacement = node.right; + replacement.left = node.left; + temp = replacement; + } else { + replacement = node.right.left; + while (replacement.left !== null) { + replacement = replacement.left; + } + replacement.parent = replacement.parent; + replacement.parent.left = replacement.right; + temp = replacement.parent; + replacement.left = node.left; + replacement.right = node.right; + } + if (node.parent !== null) { + if (node.isLeftChild()) { + node.parent.left = replacement; + } else { + node.parent.right = replacement; + } + } else { + this._setRoot(replacement); + } + // this._replaceNodeInParent(node, replacement); + this._rebalance(temp); + } + node.dispose(); + }; + /** + * Rotate the tree to the left + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._rotateLeft = function (node) { + var parent = node.parent; + var isLeftChild = node.isLeftChild(); + // Make node.right the new root of this sub tree (instead of node) + var pivotNode = node.right; + node.right = pivotNode.left; + pivotNode.left = node; + if (parent !== null) { + if (isLeftChild) { + parent.left = pivotNode; + } else { + parent.right = pivotNode; + } + } else { + this._setRoot(pivotNode); + } + }; + /** + * Rotate the tree to the right + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._rotateRight = function (node) { + var parent = node.parent; + var isLeftChild = node.isLeftChild(); + // Make node.left the new root of this sub tree (instead of node) + var pivotNode = node.left; + node.left = pivotNode.right; + pivotNode.right = node; + if (parent !== null) { + if (isLeftChild) { + parent.left = pivotNode; + } else { + parent.right = pivotNode; + } + } else { + this._setRoot(pivotNode); + } + }; + /** + * Balance the BST + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._rebalance = function (node) { + var balance = node.getBalance(); + if (balance > 1) { + if (node.left.getBalance() < 0) { + this._rotateLeft(node.left); + } else { + this._rotateRight(node); + } + } else if (balance < -1) { + if (node.right.getBalance() > 0) { + this._rotateRight(node.right); + } else { + this._rotateLeft(node); + } + } + }; + /** + * Get an event whose time and duration span the give time. Will + * return the match whose "time" value is closest to the given time. + * @param {Object} event The event to add to the timeline + * @return {Object} The event which spans the desired time + */ + Tone.IntervalTimeline.prototype.get = function (time) { + if (this._root !== null) { + var results = []; + this._root.search(time, results); + if (results.length > 0) { + var max = results[0]; + for (var i = 1; i < results.length; i++) { + if (results[i].low > max.low) { + max = results[i]; + } + } + return max.event; + } + } + return null; + }; + /** + * Iterate over everything in the timeline. + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.forEach = function (callback) { + if (this._root !== null) { + var allNodes = []; + this._root.traverse(function (node) { + allNodes.push(node); + }); + for (var i = 0; i < allNodes.length; i++) { + var ev = allNodes[i].event; + if (ev) { + callback(ev); + } + } + } + return this; + }; + /** + * Iterate over everything in the array in which the given time + * overlaps with the time and duration time of the event. + * @param {Number} time The time to check if items are overlapping + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.forEachAtTime = function (time, callback) { + if (this._root !== null) { + var results = []; + this._root.search(time, results); + for (var i = results.length - 1; i >= 0; i--) { + var ev = results[i].event; + if (ev) { + callback(ev); + } + } + } + return this; + }; + /** + * Iterate over everything in the array in which the time is greater + * than or equal to the given time. + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.forEachFrom = function (time, callback) { + if (this._root !== null) { + var results = []; + this._root.searchAfter(time, results); + for (var i = results.length - 1; i >= 0; i--) { + var ev = results[i].event; + callback(ev); + } + } + return this; + }; + /** + * Clean up + * @return {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.dispose = function () { + var allNodes = []; + if (this._root !== null) { + this._root.traverse(function (node) { + allNodes.push(node); + }); + } + for (var i = 0; i < allNodes.length; i++) { + allNodes[i].dispose(); + } + allNodes = null; + this._root = null; + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // INTERVAL NODE HELPER + /////////////////////////////////////////////////////////////////////////// + /** + * Represents a node in the binary search tree, with the addition + * of a "high" value which keeps track of the highest value of + * its children. + * References: + * https://brooknovak.wordpress.com/2013/12/07/augmented-interval-tree-in-c/ + * http://www.mif.vu.lt/~valdas/ALGORITMAI/LITERATURA/Cormen/Cormen.pdf + * @param {Number} low + * @param {Number} high + * @private + */ + var IntervalNode = function (low, high, event) { + //the event container + this.event = event; + //the low value + this.low = low; + //the high value + this.high = high; + //the high value for this and all child nodes + this.max = this.high; + //the nodes to the left + this._left = null; + //the nodes to the right + this._right = null; + //the parent node + this.parent = null; + //the number of child nodes + this.height = 0; + }; + /** + * Insert a node into the correct spot in the tree + * @param {IntervalNode} node + */ + IntervalNode.prototype.insert = function (node) { + if (node.low <= this.low) { + if (this.left === null) { + this.left = node; + } else { + this.left.insert(node); + } + } else if (this.right === null) { + this.right = node; + } else { + this.right.insert(node); + } + }; + /** + * Search the tree for nodes which overlap + * with the given point + * @param {Number} point The point to query + * @param {Array} results The array to put the results + */ + IntervalNode.prototype.search = function (point, results) { + // If p is to the right of the rightmost point of any interval + // in this node and all children, there won't be any matches. + if (point > this.max) { + return; + } + // Search left children + if (this.left !== null) { + this.left.search(point, results); + } + // Check this node + if (this.low <= point && this.high > point) { + results.push(this); + } + // If p is to the left of the time of this interval, + // then it can't be in any child to the right. + if (this.low > point) { + return; + } + // Search right children + if (this.right !== null) { + this.right.search(point, results); + } + }; + /** + * Search the tree for nodes which are less + * than the given point + * @param {Number} point The point to query + * @param {Array} results The array to put the results + */ + IntervalNode.prototype.searchAfter = function (point, results) { + // Check this node + if (this.low >= point) { + results.push(this); + if (this.left !== null) { + this.left.searchAfter(point, results); + } + } + // search the right side + if (this.right !== null) { + this.right.searchAfter(point, results); + } + }; + /** + * Invoke the callback on this element and both it's branches + * @param {Function} callback + */ + IntervalNode.prototype.traverse = function (callback) { + callback(this); + if (this.left !== null) { + this.left.traverse(callback); + } + if (this.right !== null) { + this.right.traverse(callback); + } + }; + /** + * Update the height of the node + */ + IntervalNode.prototype.updateHeight = function () { + if (this.left !== null && this.right !== null) { + this.height = Math.max(this.left.height, this.right.height) + 1; + } else if (this.right !== null) { + this.height = this.right.height + 1; + } else if (this.left !== null) { + this.height = this.left.height + 1; + } else { + this.height = 0; + } + }; + /** + * Update the height of the node + */ + IntervalNode.prototype.updateMax = function () { + this.max = this.high; + if (this.left !== null) { + this.max = Math.max(this.max, this.left.max); + } + if (this.right !== null) { + this.max = Math.max(this.max, this.right.max); + } + }; + /** + * The balance is how the leafs are distributed on the node + * @return {Number} Negative numbers are balanced to the right + */ + IntervalNode.prototype.getBalance = function () { + var balance = 0; + if (this.left !== null && this.right !== null) { + balance = this.left.height - this.right.height; + } else if (this.left !== null) { + balance = this.left.height + 1; + } else if (this.right !== null) { + balance = -(this.right.height + 1); + } + return balance; + }; + /** + * @returns {Boolean} true if this node is the left child + * of its parent + */ + IntervalNode.prototype.isLeftChild = function () { + return this.parent !== null && this.parent.left === this; + }; + /** + * get/set the left node + * @type {IntervalNode} + */ + Object.defineProperty(IntervalNode.prototype, 'left', { + get: function () { + return this._left; + }, + set: function (node) { + this._left = node; + if (node !== null) { + node.parent = this; + } + this.updateHeight(); + this.updateMax(); + } + }); + /** + * get/set the right node + * @type {IntervalNode} + */ + Object.defineProperty(IntervalNode.prototype, 'right', { + get: function () { + return this._right; + }, + set: function (node) { + this._right = node; + if (node !== null) { + node.parent = this; + } + this.updateHeight(); + this.updateMax(); + } + }); + /** + * null out references. + */ + IntervalNode.prototype.dispose = function () { + this.parent = null; + this._left = null; + this._right = null; + this.event = null; + }; + /////////////////////////////////////////////////////////////////////////// + // END INTERVAL NODE HELPER + /////////////////////////////////////////////////////////////////////////// + return Tone.IntervalTimeline; + }); + Module(function (Tone) { + /** + * @class Tone.Ticks is a primitive type for encoding Time values. + * Tone.Ticks can be constructed with or without the `new` keyword. Tone.Ticks can be passed + * into the parameter of any method which takes time as an argument. + * @constructor + * @extends {Tone.TransportTime} + * @param {String|Number} val The time value. + * @param {String=} units The units of the value. + * @example + * var t = Tone.Ticks("4n");//a quarter note + */ + Tone.Ticks = function (val, units) { + if (this instanceof Tone.Ticks) { + Tone.TransportTime.call(this, val, units); + } else { + return new Tone.Ticks(val, units); + } + }; + Tone.extend(Tone.Ticks, Tone.TransportTime); + /** + * The default units if none are given. + * @type {String} + * @private + */ + Tone.Ticks.prototype._defaultUnits = 'i'; + /** + * Get the current time in the given units + * @return {Ticks} + * @private + */ + Tone.Ticks.prototype._now = function () { + return Tone.Transport.ticks; + }; + /** + * Return the value of the beats in the current units + * @param {Number} beats + * @return {Number} + * @private + */ + Tone.Ticks.prototype._beatsToUnits = function (beats) { + return this._getPPQ() * beats; + }; + /** + * Returns the value of a second in the current units + * @param {Seconds} seconds + * @return {Number} + * @private + */ + Tone.Ticks.prototype._secondsToUnits = function (seconds) { + return seconds / (60 / this._getBpm()) * this._getPPQ(); + }; + /** + * Returns the value of a tick in the current time units + * @param {Ticks} ticks + * @return {Number} + * @private + */ + Tone.Ticks.prototype._ticksToUnits = function (ticks) { + return ticks; + }; + /** + * Return the time in ticks + * @return {Ticks} + */ + Tone.Ticks.prototype.toTicks = function () { + return this.valueOf(); + }; + /** + * Return the time in ticks + * @return {Ticks} + */ + Tone.Ticks.prototype.toSeconds = function () { + return this.valueOf() / this._getPPQ() * (60 / this._getBpm()); + }; + return Tone.Ticks; + }); + Module(function (Tone) { + /** + * @class Tone.TransportEvent is an internal class used by (Tone.Transport)[Transport] + * to schedule events. Do no invoke this class directly, it is + * handled from within Tone.Transport. + * @extends {Tone} + * @param {Object} options + */ + Tone.TransportEvent = function (Transport, options) { + options = Tone.defaultArg(options, Tone.TransportEvent.defaults); + Tone.call(this); + /** + * Reference to the Transport that created it + * @type {Tone.Transport} + */ + this.Transport = Transport; + /** + * The unique id of the event + * @type {Number} + */ + this.id = Tone.TransportEvent._eventId++; + /** + * The time the event starts + * @type {Ticks} + */ + this.time = Tone.Ticks(options.time); + /** + * The callback to invoke + * @type {Function} + */ + this.callback = options.callback; + /** + * If the event should be removed after being created. + * @type {Boolean} + * @private + */ + this._once = options.once; + }; + Tone.extend(Tone.TransportEvent); + /** + * The defaults + * @static + * @type {Object} + */ + Tone.TransportEvent.defaults = { + 'once': false, + 'callback': Tone.noOp + }; + /** + * Current ID counter + * @private + * @static + * @type {Number} + */ + Tone.TransportEvent._eventId = 0; + /** + * Invoke the event callback. + * @param {Time} time The AudioContext time in seconds of the event + */ + Tone.TransportEvent.prototype.invoke = function (time) { + if (this.callback) { + this.callback(time); + if (this._once && this.Transport) { + this.Transport.clear(this.id); + } + } + }; + /** + * Clean up + * @return {Tone.TransportEvent} this + */ + Tone.TransportEvent.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this.Transport = null; + this.callback = null; + this.time = null; + return this; + }; + return Tone.TransportEvent; + }); + Module(function (Tone) { + /** + * @class Tone.TransportRepeatEvent is an internal class used by Tone.Transport + * to schedule repeat events. This class should not be instantiated directly. + * @extends {Tone.TransportEvent} + * @param {Object} options + */ + Tone.TransportRepeatEvent = function (Transport, options) { + Tone.TransportEvent.call(this, Transport, options); + options = Tone.defaultArg(options, Tone.TransportRepeatEvent.defaults); + /** + * When the event should stop repeating + * @type {Ticks} + * @private + */ + this.duration = Tone.Ticks(options.duration); + /** + * The interval of the repeated event + * @type {Ticks} + * @private + */ + this._interval = Tone.Ticks(options.interval); + /** + * The ID of the current timeline event + * @type {Number} + * @private + */ + this._currentId = -1; + /** + * The ID of the next timeline event + * @type {Number} + * @private + */ + this._nextId = -1; + /** + * The time of the next event + * @type {Ticks} + * @private + */ + this._nextTick = this.time; + /** + * a reference to the bound start method + * @type {Function} + * @private + */ + this._boundRestart = this._restart.bind(this); + this.Transport.on('start loopStart', this._boundRestart); + this._restart(); + }; + Tone.extend(Tone.TransportRepeatEvent, Tone.TransportEvent); + /** + * The defaults + * @static + * @type {Object} + */ + Tone.TransportRepeatEvent.defaults = { + 'duration': Infinity, + 'interval': 1 + }; + /** + * Invoke the callback. Returns the tick time which + * the next event should be scheduled at. + * @param {Number} time The AudioContext time in seconds of the event + */ + Tone.TransportRepeatEvent.prototype.invoke = function (time) { + //create more events if necessary + this._createEvents(time); + //call the super class + Tone.TransportEvent.prototype.invoke.call(this, time); + }; + /** + * Push more events onto the timeline to keep up with the position of the timeline + * @private + */ + Tone.TransportRepeatEvent.prototype._createEvents = function (time) { + // schedule the next event + var ticks = this.Transport.getTicksAtTime(time); + if (ticks >= this.time && ticks >= this._nextTick && this._nextTick + this._interval < this.time + this.duration) { + this._nextTick += this._interval; + this._currentId = this._nextId; + this._nextId = this.Transport.scheduleOnce(this.invoke.bind(this), Tone.Ticks(this._nextTick)); + } + }; + /** + * Push more events onto the timeline to keep up with the position of the timeline + * @private + */ + Tone.TransportRepeatEvent.prototype._restart = function (time) { + this.Transport.clear(this._currentId); + this.Transport.clear(this._nextId); + this._nextTick = this.time; + var ticks = this.Transport.getTicksAtTime(time); + if (ticks > this.time) { + this._nextTick = this.time + Math.ceil((ticks - this.time) / this._interval) * this._interval; + } + this._currentId = this.Transport.scheduleOnce(this.invoke.bind(this), Tone.Ticks(this._nextTick)); + this._nextTick += this._interval; + this._nextId = this.Transport.scheduleOnce(this.invoke.bind(this), Tone.Ticks(this._nextTick)); + }; + /** + * Clean up + * @return {Tone.TransportRepeatEvent} this + */ + Tone.TransportRepeatEvent.prototype.dispose = function () { + this.Transport.clear(this._currentId); + this.Transport.clear(this._nextId); + this.Transport.off('start loopStart', this._boundRestart); + this._boundCreateEvents = null; + Tone.TransportEvent.prototype.dispose.call(this); + this.duration = null; + this._interval = null; + return this; + }; + return Tone.TransportRepeatEvent; + }); + Module(function (Tone) { + + /** + * @class Transport for timing musical events. + * Supports tempo curves and time changes. Unlike browser-based timing (setInterval, requestAnimationFrame) + * Tone.Transport timing events pass in the exact time of the scheduled event + * in the argument of the callback function. Pass that time value to the object + * you're scheduling. <br><br> + * A single transport is created for you when the library is initialized. + * <br><br> + * The transport emits the events: "start", "stop", "pause", and "loop" which are + * called with the time of that event as the argument. + * + * @extends {Tone.Emitter} + * @singleton + * @example + * //repeated event every 8th note + * Tone.Transport.scheduleRepeat(function(time){ + * //do something with the time + * }, "8n"); + * @example + * //schedule an event on the 16th measure + * Tone.Transport.schedule(function(time){ + * //do something with the time + * }, "16:0:0"); + */ + Tone.Transport = function () { + Tone.Emitter.call(this); + Tone.getContext(function () { + /////////////////////////////////////////////////////////////////////// + // LOOPING + ////////////////////////////////////////////////////////////////////// + /** + * If the transport loops or not. + * @type {boolean} + */ + this.loop = false; + /** + * The loop start position in ticks + * @type {Ticks} + * @private + */ + this._loopStart = 0; + /** + * The loop end position in ticks + * @type {Ticks} + * @private + */ + this._loopEnd = 0; + /////////////////////////////////////////////////////////////////////// + // CLOCK/TEMPO + ////////////////////////////////////////////////////////////////////// + /** + * Pulses per quarter is the number of ticks per quarter note. + * @private + * @type {Number} + */ + this._ppq = TransportConstructor.defaults.PPQ; + /** + * watches the main oscillator for timing ticks + * initially starts at 120bpm + * @private + * @type {Tone.Clock} + */ + this._clock = new Tone.Clock({ + 'callback': this._processTick.bind(this), + 'frequency': 0 + }); + this._bindClockEvents(); + /** + * The Beats Per Minute of the Transport. + * @type {BPM} + * @signal + * @example + * Tone.Transport.bpm.value = 80; + * //ramp the bpm to 120 over 10 seconds + * Tone.Transport.bpm.rampTo(120, 10); + */ + this.bpm = this._clock.frequency; + this.bpm._toUnits = this._toUnits.bind(this); + this.bpm._fromUnits = this._fromUnits.bind(this); + this.bpm.units = Tone.Type.BPM; + this.bpm.value = TransportConstructor.defaults.bpm; + this._readOnly('bpm'); + /** + * The time signature, or more accurately the numerator + * of the time signature over a denominator of 4. + * @type {Number} + * @private + */ + this._timeSignature = TransportConstructor.defaults.timeSignature; + /////////////////////////////////////////////////////////////////////// + // TIMELINE EVENTS + ////////////////////////////////////////////////////////////////////// + /** + * All the events in an object to keep track by ID + * @type {Object} + * @private + */ + this._scheduledEvents = {}; + /** + * The scheduled events. + * @type {Tone.Timeline} + * @private + */ + this._timeline = new Tone.Timeline(); + /** + * Repeated events + * @type {Array} + * @private + */ + this._repeatedEvents = new Tone.IntervalTimeline(); + /** + * All of the synced Signals + * @private + * @type {Array} + */ + this._syncedSignals = []; + /////////////////////////////////////////////////////////////////////// + // SWING + ////////////////////////////////////////////////////////////////////// + /** + * The subdivision of the swing + * @type {Ticks} + * @private + */ + this._swingTicks = TransportConstructor.defaults.PPQ / 2; + //8n + /** + * The swing amount + * @type {NormalRange} + * @private + */ + this._swingAmount = 0; + }.bind(this)); + }; + Tone.extend(Tone.Transport, Tone.Emitter); + /** + * the defaults + * @type {Object} + * @const + * @static + */ + Tone.Transport.defaults = { + 'bpm': 120, + 'swing': 0, + 'swingSubdivision': '8n', + 'timeSignature': 4, + 'loopStart': 0, + 'loopEnd': '4m', + 'PPQ': 192 + }; + /////////////////////////////////////////////////////////////////////////////// + // TICKS + /////////////////////////////////////////////////////////////////////////////// + /** + * called on every tick + * @param {number} tickTime clock relative tick time + * @private + */ + Tone.Transport.prototype._processTick = function (tickTime, ticks) { + //handle swing + if (this._swingAmount > 0 && ticks % this._ppq !== 0 && //not on a downbeat + ticks % (this._swingTicks * 2) !== 0) { + //add some swing + var progress = ticks % (this._swingTicks * 2) / (this._swingTicks * 2); + var amount = Math.sin(progress * Math.PI) * this._swingAmount; + tickTime += Tone.Ticks(this._swingTicks * 2 / 3).toSeconds() * amount; + } + //do the loop test + if (this.loop) { + if (ticks >= this._loopEnd) { + this.emit('loopEnd', tickTime); + this._clock.setTicksAtTime(this._loopStart, tickTime); + ticks = this._loopStart; + this.emit('loopStart', tickTime, this._clock.getSecondsAtTime(tickTime)); + this.emit('loop', tickTime); + } + } + //invoke the timeline events scheduled on this tick + this._timeline.forEachAtTime(ticks, function (event) { + event.invoke(tickTime); + }); + }; + /////////////////////////////////////////////////////////////////////////////// + // SCHEDULABLE EVENTS + /////////////////////////////////////////////////////////////////////////////// + /** + * Schedule an event along the timeline. + * @param {Function} callback The callback to be invoked at the time. + * @param {TransportTime} time The time to invoke the callback at. + * @return {Number} The id of the event which can be used for canceling the event. + * @example + * //trigger the callback when the Transport reaches the desired time + * Tone.Transport.schedule(function(time){ + * envelope.triggerAttack(time); + * }, "128i"); + */ + Tone.Transport.prototype.schedule = function (callback, time) { + var event = new Tone.TransportEvent(this, { + 'time': Tone.TransportTime(time), + 'callback': callback + }); + return this._addEvent(event, this._timeline); + }; + /** + * Schedule a repeated event along the timeline. The event will fire + * at the `interval` starting at the `startTime` and for the specified + * `duration`. + * @param {Function} callback The callback to invoke. + * @param {Time} interval The duration between successive + * callbacks. Must be a positive number. + * @param {TransportTime=} startTime When along the timeline the events should + * start being invoked. + * @param {Time} [duration=Infinity] How long the event should repeat. + * @return {Number} The ID of the scheduled event. Use this to cancel + * the event. + * @example + * //a callback invoked every eighth note after the first measure + * Tone.Transport.scheduleRepeat(callback, "8n", "1m"); + */ + Tone.Transport.prototype.scheduleRepeat = function (callback, interval, startTime, duration) { + var event = new Tone.TransportRepeatEvent(this, { + 'callback': callback, + 'interval': Tone.Time(interval), + 'time': Tone.TransportTime(startTime), + 'duration': Tone.Time(Tone.defaultArg(duration, Infinity)) + }); + //kick it off if the Transport is started + return this._addEvent(event, this._repeatedEvents); + }; + /** + * Schedule an event that will be removed after it is invoked. + * Note that if the given time is less than the current transport time, + * the event will be invoked immediately. + * @param {Function} callback The callback to invoke once. + * @param {TransportTime} time The time the callback should be invoked. + * @returns {Number} The ID of the scheduled event. + */ + Tone.Transport.prototype.scheduleOnce = function (callback, time) { + var event = new Tone.TransportEvent(this, { + 'time': Tone.TransportTime(time), + 'callback': callback, + 'once': true + }); + return this._addEvent(event, this._timeline); + }; + /** + * Clear the passed in event id from the timeline + * @param {Number} eventId The id of the event. + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.clear = function (eventId) { + if (this._scheduledEvents.hasOwnProperty(eventId)) { + var item = this._scheduledEvents[eventId.toString()]; + item.timeline.remove(item.event); + item.event.dispose(); + delete this._scheduledEvents[eventId.toString()]; + } + return this; + }; + /** + * Add an event to the correct timeline. Keep track of the + * timeline it was added to. + * @param {Tone.TransportEvent} event + * @param {Tone.Timeline} timeline + * @returns {Number} the event id which was just added + * @private + */ + Tone.Transport.prototype._addEvent = function (event, timeline) { + this._scheduledEvents[event.id.toString()] = { + 'event': event, + 'timeline': timeline + }; + timeline.add(event); + return event.id; + }; + /** + * Remove scheduled events from the timeline after + * the given time. Repeated events will be removed + * if their startTime is after the given time + * @param {TransportTime} [after=0] Clear all events after + * this time. + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.cancel = function (after) { + after = Tone.defaultArg(after, 0); + after = this.toTicks(after); + this._timeline.forEachFrom(after, function (event) { + this.clear(event.id); + }.bind(this)); + this._repeatedEvents.forEachFrom(after, function (event) { + this.clear(event.id); + }.bind(this)); + return this; + }; + /////////////////////////////////////////////////////////////////////////////// + // START/STOP/PAUSE + /////////////////////////////////////////////////////////////////////////////// + /** + * Bind start/stop/pause events from the clock and emit them. + * @private + */ + Tone.Transport.prototype._bindClockEvents = function () { + this._clock.on('start', function (time, offset) { + offset = Tone.Ticks(offset).toSeconds(); + this.emit('start', time, offset); + }.bind(this)); + this._clock.on('stop', function (time) { + this.emit('stop', time); + }.bind(this)); + this._clock.on('pause', function (time) { + this.emit('pause', time); + }.bind(this)); + }; + /** + * Returns the playback state of the source, either "started", "stopped", or "paused" + * @type {Tone.State} + * @readOnly + * @memberOf Tone.Transport# + * @name state + */ + Object.defineProperty(Tone.Transport.prototype, 'state', { + get: function () { + return this._clock.getStateAtTime(this.now()); + } + }); + /** + * Start the transport and all sources synced to the transport. + * @param {Time} [time=now] The time when the transport should start. + * @param {TransportTime=} offset The timeline offset to start the transport. + * @returns {Tone.Transport} this + * @example + * //start the transport in one second starting at beginning of the 5th measure. + * Tone.Transport.start("+1", "4:0:0"); + */ + Tone.Transport.prototype.start = function (time, offset) { + //start the clock + if (Tone.isDefined(offset)) { + offset = this.toTicks(offset); + } + this._clock.start(time, offset); + return this; + }; + /** + * Stop the transport and all sources synced to the transport. + * @param {Time} [time=now] The time when the transport should stop. + * @returns {Tone.Transport} this + * @example + * Tone.Transport.stop(); + */ + Tone.Transport.prototype.stop = function (time) { + this._clock.stop(time); + return this; + }; + /** + * Pause the transport and all sources synced to the transport. + * @param {Time} [time=now] + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.pause = function (time) { + this._clock.pause(time); + return this; + }; + /** + * Toggle the current state of the transport. If it is + * started, it will stop it, otherwise it will start the Transport. + * @param {Time=} time The time of the event + * @return {Tone.Transport} this + */ + Tone.Transport.prototype.toggle = function (time) { + time = this.toSeconds(time); + if (this._clock.getStateAtTime(time) !== Tone.State.Started) { + this.start(time); + } else { + this.stop(time); + } + return this; + }; + /////////////////////////////////////////////////////////////////////////////// + // SETTERS/GETTERS + /////////////////////////////////////////////////////////////////////////////// + /** + * The time signature as just the numerator over 4. + * For example 4/4 would be just 4 and 6/8 would be 3. + * @memberOf Tone.Transport# + * @type {Number|Array} + * @name timeSignature + * @example + * //common time + * Tone.Transport.timeSignature = 4; + * // 7/8 + * Tone.Transport.timeSignature = [7, 8]; + * //this will be reduced to a single number + * Tone.Transport.timeSignature; //returns 3.5 + */ + Object.defineProperty(Tone.Transport.prototype, 'timeSignature', { + get: function () { + return this._timeSignature; + }, + set: function (timeSig) { + if (Tone.isArray(timeSig)) { + timeSig = timeSig[0] / timeSig[1] * 4; + } + this._timeSignature = timeSig; + } + }); + /** + * When the Tone.Transport.loop = true, this is the starting position of the loop. + * @memberOf Tone.Transport# + * @type {Time} + * @name loopStart + */ + Object.defineProperty(Tone.Transport.prototype, 'loopStart', { + get: function () { + return Tone.Ticks(this._loopStart).toSeconds(); + }, + set: function (startPosition) { + this._loopStart = this.toTicks(startPosition); + } + }); + /** + * When the Tone.Transport.loop = true, this is the ending position of the loop. + * @memberOf Tone.Transport# + * @type {Time} + * @name loopEnd + */ + Object.defineProperty(Tone.Transport.prototype, 'loopEnd', { + get: function () { + return Tone.Ticks(this._loopEnd).toSeconds(); + }, + set: function (endPosition) { + this._loopEnd = this.toTicks(endPosition); + } + }); + /** + * Set the loop start and stop at the same time. + * @param {TransportTime} startPosition + * @param {TransportTime} endPosition + * @returns {Tone.Transport} this + * @example + * //loop over the first measure + * Tone.Transport.setLoopPoints(0, "1m"); + * Tone.Transport.loop = true; + */ + Tone.Transport.prototype.setLoopPoints = function (startPosition, endPosition) { + this.loopStart = startPosition; + this.loopEnd = endPosition; + return this; + }; + /** + * The swing value. Between 0-1 where 1 equal to + * the note + half the subdivision. + * @memberOf Tone.Transport# + * @type {NormalRange} + * @name swing + */ + Object.defineProperty(Tone.Transport.prototype, 'swing', { + get: function () { + return this._swingAmount; + }, + set: function (amount) { + //scale the values to a normal range + this._swingAmount = amount; + } + }); + /** + * Set the subdivision which the swing will be applied to. + * The default value is an 8th note. Value must be less + * than a quarter note. + * + * @memberOf Tone.Transport# + * @type {Time} + * @name swingSubdivision + */ + Object.defineProperty(Tone.Transport.prototype, 'swingSubdivision', { + get: function () { + return Tone.Ticks(this._swingTicks).toNotation(); + }, + set: function (subdivision) { + this._swingTicks = this.toTicks(subdivision); + } + }); + /** + * The Transport's position in Bars:Beats:Sixteenths. + * Setting the value will jump to that position right away. + * @memberOf Tone.Transport# + * @type {BarsBeatsSixteenths} + * @name position + */ + Object.defineProperty(Tone.Transport.prototype, 'position', { + get: function () { + var now = this.now(); + var ticks = this._clock.getTicksAtTime(now); + return Tone.Ticks(ticks).toBarsBeatsSixteenths(); + }, + set: function (progress) { + var ticks = this.toTicks(progress); + this.ticks = ticks; + } + }); + /** + * The Transport's position in seconds + * Setting the value will jump to that position right away. + * @memberOf Tone.Transport# + * @type {Seconds} + * @name seconds + */ + Object.defineProperty(Tone.Transport.prototype, 'seconds', { + get: function () { + return this._clock.seconds; + }, + set: function (s) { + var now = this.now(); + var ticks = this.bpm.timeToTicks(s, now); + this.ticks = ticks; + } + }); + /** + * The Transport's loop position as a normalized value. Always + * returns 0 if the transport if loop is not true. + * @memberOf Tone.Transport# + * @name progress + * @type {NormalRange} + */ + Object.defineProperty(Tone.Transport.prototype, 'progress', { + get: function () { + if (this.loop) { + var now = this.now(); + var ticks = this._clock.getTicksAtTime(now); + return (ticks - this._loopStart) / (this._loopEnd - this._loopStart); + } else { + return 0; + } + } + }); + /** + * The transports current tick position. + * + * @memberOf Tone.Transport# + * @type {Ticks} + * @name ticks + */ + Object.defineProperty(Tone.Transport.prototype, 'ticks', { + get: function () { + return this._clock.ticks; + }, + set: function (t) { + if (this._clock.ticks !== t) { + var now = this.now(); + //stop everything synced to the transport + if (this.state === Tone.State.Started) { + this.emit('stop', now); + this._clock.setTicksAtTime(t, now); + //restart it with the new time + this.emit('start', now, this.seconds); + } else { + this._clock.setTicksAtTime(t, now); + } + } + } + }); + /** + * Get the clock's ticks at the given time. + * @param {Time} time When to get the tick value + * @return {Ticks} The tick value at the given time. + */ + Tone.Transport.prototype.getTicksAtTime = function (time) { + return Math.round(this._clock.getTicksAtTime(time)); + }; + /** + * Return the elapsed seconds at the given time. + * @param {Time} time When to get the elapsed seconds + * @return {Seconds} The number of elapsed seconds + */ + Tone.Transport.prototype.getSecondsAtTime = function (time) { + return this._clock.getSecondsAtTime(time); + }; + /** + * Pulses Per Quarter note. This is the smallest resolution + * the Transport timing supports. This should be set once + * on initialization and not set again. Changing this value + * after other objects have been created can cause problems. + * + * @memberOf Tone.Transport# + * @type {Number} + * @name PPQ + */ + Object.defineProperty(Tone.Transport.prototype, 'PPQ', { + get: function () { + return this._ppq; + }, + set: function (ppq) { + var bpm = this.bpm.value; + this._ppq = ppq; + this.bpm.value = bpm; + } + }); + /** + * Convert from BPM to frequency (factoring in PPQ) + * @param {BPM} bpm The BPM value to convert to frequency + * @return {Frequency} The BPM as a frequency with PPQ factored in. + * @private + */ + Tone.Transport.prototype._fromUnits = function (bpm) { + return 1 / (60 / bpm / this.PPQ); + }; + /** + * Convert from frequency (with PPQ) into BPM + * @param {Frequency} freq The clocks frequency to convert to BPM + * @return {BPM} The frequency value as BPM. + * @private + */ + Tone.Transport.prototype._toUnits = function (freq) { + return freq / this.PPQ * 60; + }; + /////////////////////////////////////////////////////////////////////////////// + // SYNCING + /////////////////////////////////////////////////////////////////////////////// + /** + * Returns the time aligned to the next subdivision + * of the Transport. If the Transport is not started, + * it will return 0. + * Note: this will not work precisely during tempo ramps. + * @param {Time} subdivision The subdivision to quantize to + * @return {Number} The context time of the next subdivision. + * @example + * Tone.Transport.start(); //the transport must be started + * Tone.Transport.nextSubdivision("4n"); + */ + Tone.Transport.prototype.nextSubdivision = function (subdivision) { + subdivision = this.toTicks(subdivision); + if (this.state !== Tone.State.Started) { + //if the transport's not started, return 0 + return 0; + } else { + var now = this.now(); + //the remainder of the current ticks and the subdivision + var transportPos = this.getTicksAtTime(now); + var remainingTicks = subdivision - transportPos % subdivision; + return this._clock.nextTickTime(remainingTicks, now); + } + }; + /** + * Attaches the signal to the tempo control signal so that + * any changes in the tempo will change the signal in the same + * ratio. + * + * @param {Tone.Signal} signal + * @param {number=} ratio Optionally pass in the ratio between + * the two signals. Otherwise it will be computed + * based on their current values. + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.syncSignal = function (signal, ratio) { + if (!ratio) { + //get the sync ratio + var now = this.now(); + if (signal.getValueAtTime(now) !== 0) { + ratio = signal.getValueAtTime(now) / this.bpm.getValueAtTime(now); + } else { + ratio = 0; + } + } + var ratioSignal = new Tone.Gain(ratio); + this.bpm.chain(ratioSignal, signal._param); + this._syncedSignals.push({ + 'ratio': ratioSignal, + 'signal': signal, + 'initial': signal.value + }); + signal.value = 0; + return this; + }; + /** + * Unsyncs a previously synced signal from the transport's control. + * See Tone.Transport.syncSignal. + * @param {Tone.Signal} signal + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.unsyncSignal = function (signal) { + for (var i = this._syncedSignals.length - 1; i >= 0; i--) { + var syncedSignal = this._syncedSignals[i]; + if (syncedSignal.signal === signal) { + syncedSignal.ratio.dispose(); + syncedSignal.signal.value = syncedSignal.initial; + this._syncedSignals.splice(i, 1); + } + } + return this; + }; + /** + * Clean up. + * @returns {Tone.Transport} this + * @private + */ + Tone.Transport.prototype.dispose = function () { + Tone.Emitter.prototype.dispose.call(this); + this._clock.dispose(); + this._clock = null; + this._writable('bpm'); + this.bpm = null; + this._timeline.dispose(); + this._timeline = null; + this._repeatedEvents.dispose(); + this._repeatedEvents = null; + return this; + }; + /////////////////////////////////////////////////////////////////////////////// + // INITIALIZATION + /////////////////////////////////////////////////////////////////////////////// + var TransportConstructor = Tone.Transport; + Tone.Transport = new TransportConstructor(); + Tone.Context.on('init', function (context) { + if (context.Transport instanceof TransportConstructor) { + Tone.Transport = context.Transport; + } else { + Tone.Transport = new TransportConstructor(); + } + //store the Transport on the context so it can be retrieved later + context.Transport = Tone.Transport; + }); + Tone.Context.on('close', function (context) { + if (context.Transport instanceof TransportConstructor) { + context.Transport.dispose(); + } + }); + return Tone.Transport; + }); + Module(function (Tone) { + + /** + * @class Tone.Volume is a simple volume node, useful for creating a volume fader. + * + * @extends {Tone.AudioNode} + * @constructor + * @param {Decibels} [volume=0] the initial volume + * @example + * var vol = new Tone.Volume(-12); + * instrument.chain(vol, Tone.Master); + */ + Tone.Volume = function () { + var options = Tone.defaults(arguments, ['volume'], Tone.Volume); + Tone.AudioNode.call(this); + /** + * the output node + * @type {GainNode} + * @private + */ + this.output = this.input = new Tone.Gain(options.volume, Tone.Type.Decibels); + /** + * The unmuted volume + * @type {Decibels} + * @private + */ + this._unmutedVolume = options.volume; + /** + * The volume control in decibels. + * @type {Decibels} + * @signal + */ + this.volume = this.output.gain; + this._readOnly('volume'); + //set the mute initially + this.mute = options.mute; + }; + Tone.extend(Tone.Volume, Tone.AudioNode); + /** + * Defaults + * @type {Object} + * @const + * @static + */ + Tone.Volume.defaults = { + 'volume': 0, + 'mute': false + }; + /** + * Mute the output. + * @memberOf Tone.Volume# + * @type {boolean} + * @name mute + * @example + * //mute the output + * volume.mute = true; + */ + Object.defineProperty(Tone.Volume.prototype, 'mute', { + get: function () { + return this.volume.value === -Infinity; + }, + set: function (mute) { + if (!this.mute && mute) { + this._unmutedVolume = this.volume.value; + //maybe it should ramp here? + this.volume.value = -Infinity; + } else if (this.mute && !mute) { + this.volume.value = this._unmutedVolume; + } + } + }); + /** + * clean up + * @returns {Tone.Volume} this + */ + Tone.Volume.prototype.dispose = function () { + this.input.dispose(); + Tone.AudioNode.prototype.dispose.call(this); + this._writable('volume'); + this.volume.dispose(); + this.volume = null; + return this; + }; + return Tone.Volume; + }); + Module(function (Tone) { + + /** + * @class A single master output which is connected to the + * AudioDestinationNode (aka your speakers). + * It provides useful conveniences such as the ability + * to set the volume and mute the entire application. + * It also gives you the ability to apply master effects to your application. + * <br><br> + * Like Tone.Transport, A single Tone.Master is created + * on initialization and you do not need to explicitly construct one. + * + * @constructor + * @extends {Tone} + * @singleton + * @example + * //the audio will go from the oscillator to the speakers + * oscillator.connect(Tone.Master); + * //a convenience for connecting to the master output is also provided: + * oscillator.toMaster(); + * //the above two examples are equivalent. + */ + Tone.Master = function () { + Tone.AudioNode.call(this); + Tone.getContext(function () { + this.createInsOuts(1, 0); + /** + * The private volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(); + /** + * The volume of the master output. + * @type {Decibels} + * @signal + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + //connections + this.input.chain(this.output, this.context.destination); + }.bind(this)); + }; + Tone.extend(Tone.Master, Tone.AudioNode); + /** + * @type {Object} + * @const + */ + Tone.Master.defaults = { + 'volume': 0, + 'mute': false + }; + /** + * Mute the output. + * @memberOf Tone.Master# + * @type {boolean} + * @name mute + * @example + * //mute the output + * Tone.Master.mute = true; + */ + Object.defineProperty(Tone.Master.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + /** + * Add a master effects chain. NOTE: this will disconnect any nodes which were previously + * chained in the master effects chain. + * @param {AudioNode|Tone} args... All arguments will be connected in a row + * and the Master will be routed through it. + * @return {Tone.Master} this + * @example + * //some overall compression to keep the levels in check + * var masterCompressor = new Tone.Compressor({ + * "threshold" : -6, + * "ratio" : 3, + * "attack" : 0.5, + * "release" : 0.1 + * }); + * //give a little boost to the lows + * var lowBump = new Tone.Filter(200, "lowshelf"); + * //route everything through the filter + * //and compressor before going to the speakers + * Tone.Master.chain(lowBump, masterCompressor); + */ + Tone.Master.prototype.chain = function () { + this.input.disconnect(); + this.input.chain.apply(this.input, arguments); + arguments[arguments.length - 1].connect(this.output); + }; + /** + * Clean up + * @return {Tone.Master} this + */ + Tone.Master.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._writable('volume'); + this._volume.dispose(); + this._volume = null; + this.volume = null; + }; + /////////////////////////////////////////////////////////////////////////// + // AUGMENT TONE's PROTOTYPE + /////////////////////////////////////////////////////////////////////////// + /** + * Connect 'this' to the master output. Shorthand for this.connect(Tone.Master) + * @returns {Tone.AudioNode} this + * @example + * //connect an oscillator to the master output + * var osc = new Tone.Oscillator().toMaster(); + */ + Tone.AudioNode.prototype.toMaster = function () { + this.connect(Tone.Master); + return this; + }; + if (window.AudioNode) { + // Also augment AudioNode's prototype to include toMaster as a convenience + AudioNode.prototype.toMaster = function () { + this.connect(Tone.Master); + return this; + }; + } + /** + * initialize the module and listen for new audio contexts + */ + var MasterConstructor = Tone.Master; + Tone.Master = new MasterConstructor(); + Tone.Context.on('init', function (context) { + // if it already exists, just restore it + if (context.Master instanceof MasterConstructor) { + Tone.Master = context.Master; + } else { + Tone.Master = new MasterConstructor(); + } + context.Master = Tone.Master; + }); + Tone.Context.on('close', function (context) { + if (context.Master instanceof MasterConstructor) { + context.Master.dispose(); + } + }); + return Tone.Master; + }); + Module(function (Tone) { + + /** + * @class Base class for sources. Sources have start/stop methods + * and the ability to be synced to the + * start/stop of Tone.Transport. + * + * @constructor + * @extends {Tone.AudioNode} + * @example + * //Multiple state change events can be chained together, + * //but must be set in the correct order and with ascending times + * + * // OK + * state.start().stop("+0.2"); + * // AND + * state.start().stop("+0.2").start("+0.4").stop("+0.7") + * + * // BAD + * state.stop("+0.2").start(); + * // OR + * state.start("+0.3").stop("+0.2"); + * + */ + Tone.Source = function (options) { + options = Tone.defaultArg(options, Tone.Source.defaults); + Tone.AudioNode.call(this); + /** + * The output volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume of the output in decibels. + * @type {Decibels} + * @signal + * @example + * source.volume.value = -6; + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + /** + * Keep track of the scheduled state. + * @type {Tone.TimelineState} + * @private + */ + this._state = new Tone.TimelineState(Tone.State.Stopped); + this._state.memory = 100; + /** + * The synced `start` callback function from the transport + * @type {Function} + * @private + */ + this._synced = false; + /** + * Keep track of all of the scheduled event ids + * @type {Array} + * @private + */ + this._scheduled = []; + //make the output explicitly stereo + this._volume.output.output.channelCount = 2; + this._volume.output.output.channelCountMode = 'explicit'; + //mute initially + this.mute = options.mute; + }; + Tone.extend(Tone.Source, Tone.AudioNode); + /** + * The default parameters + * @static + * @const + * @type {Object} + */ + Tone.Source.defaults = { + 'volume': 0, + 'mute': false + }; + /** + * Returns the playback state of the source, either "started" or "stopped". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.Source# + * @name state + */ + Object.defineProperty(Tone.Source.prototype, 'state', { + get: function () { + if (this._synced) { + if (Tone.Transport.state === Tone.State.Started) { + return this._state.getValueAtTime(Tone.Transport.seconds); + } else { + return Tone.State.Stopped; + } + } else { + return this._state.getValueAtTime(this.now()); + } + } + }); + /** + * Mute the output. + * @memberOf Tone.Source# + * @type {boolean} + * @name mute + * @example + * //mute the output + * source.mute = true; + */ + Object.defineProperty(Tone.Source.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + //overwrite these functions + Tone.Source.prototype._start = Tone.noOp; + Tone.Source.prototype.restart = Tone.noOp; + Tone.Source.prototype._stop = Tone.noOp; + /** + * Start the source at the specified time. If no time is given, + * start the source now. + * @param {Time} [time=now] When the source should be started. + * @returns {Tone.Source} this + * @example + * source.start("+0.5"); //starts the source 0.5 seconds from now + */ + Tone.Source.prototype.start = function (time, offset, duration) { + if (Tone.isUndef(time) && this._synced) { + time = Tone.Transport.seconds; + } else { + time = this.toSeconds(time); + } + //if it's started, stop it and restart it + if (this._state.getValueAtTime(time) === Tone.State.Started) { + this._state.cancel(time); + this._state.setStateAtTime(Tone.State.Started, time); + this.restart(time, offset, duration); + } else { + this._state.setStateAtTime(Tone.State.Started, time); + if (this._synced) { + // add the offset time to the event + var event = this._state.get(time); + event.offset = Tone.defaultArg(offset, 0); + event.duration = duration; + var sched = Tone.Transport.schedule(function (t) { + this._start(t, offset, duration); + }.bind(this), time); + this._scheduled.push(sched); + //if it's already started + if (Tone.Transport.state === Tone.State.Started) { + this._syncedStart(this.now(), Tone.Transport.seconds); + } + } else { + this._start.apply(this, arguments); + } + } + return this; + }; + /** + * Stop the source at the specified time. If no time is given, + * stop the source now. + * @param {Time} [time=now] When the source should be stopped. + * @returns {Tone.Source} this + * @example + * source.stop(); // stops the source immediately + */ + Tone.Source.prototype.stop = function (time) { + if (Tone.isUndef(time) && this._synced) { + time = Tone.Transport.seconds; + } else { + time = this.toSeconds(time); + } + if (!this._synced) { + this._stop.apply(this, arguments); + } else { + var sched = Tone.Transport.schedule(this._stop.bind(this), time); + this._scheduled.push(sched); + } + this._state.cancel(time); + this._state.setStateAtTime(Tone.State.Stopped, time); + return this; + }; + /** + * Sync the source to the Transport so that all subsequent + * calls to `start` and `stop` are synced to the TransportTime + * instead of the AudioContext time. + * + * @returns {Tone.Source} this + * @example + * //sync the source so that it plays between 0 and 0.3 on the Transport's timeline + * source.sync().start(0).stop(0.3); + * //start the transport. + * Tone.Transport.start(); + * + * @example + * //start the transport with an offset and the sync'ed sources + * //will start in the correct position + * source.sync().start(0.1); + * //the source will be invoked with an offset of 0.4 + * Tone.Transport.start("+0.5", 0.5); + */ + Tone.Source.prototype.sync = function () { + this._synced = true; + this._syncedStart = function (time, offset) { + if (offset > 0) { + // get the playback state at that time + var stateEvent = this._state.get(offset); + // listen for start events which may occur in the middle of the sync'ed time + if (stateEvent && stateEvent.state === Tone.State.Started && stateEvent.time !== offset) { + // get the offset + var startOffset = offset - this.toSeconds(stateEvent.time); + var duration; + if (stateEvent.duration) { + duration = this.toSeconds(stateEvent.duration) - startOffset; + } + this._start(time, this.toSeconds(stateEvent.offset) + startOffset, duration); + } + } + }.bind(this); + this._syncedStop = function (time) { + var seconds = Tone.Transport.getSecondsAtTime(Math.max(time - this.sampleTime, 0)); + if (this._state.getValueAtTime(seconds) === Tone.State.Started) { + this._stop(time); + } + }.bind(this); + Tone.Transport.on('start loopStart', this._syncedStart); + Tone.Transport.on('stop pause loopEnd', this._syncedStop); + return this; + }; + /** + * Unsync the source to the Transport. See Tone.Source.sync + * @returns {Tone.Source} this + */ + Tone.Source.prototype.unsync = function () { + if (this._synced) { + Tone.Transport.off('stop pause loopEnd', this._syncedStop); + Tone.Transport.off('start loopStart', this._syncedStart); + } + this._synced = false; + // clear all of the scheduled ids + for (var i = 0; i < this._scheduled.length; i++) { + var id = this._scheduled[i]; + Tone.Transport.clear(id); + } + this._scheduled = []; + this._state.cancel(0); + return this; + }; + /** + * Clean up. + * @return {Tone.Source} this + */ + Tone.Source.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this.unsync(); + this._scheduled = null; + this._writable('volume'); + this._volume.dispose(); + this._volume = null; + this.volume = null; + this._state.dispose(); + this._state = null; + }; + return Tone.Source; + }); + Module(function (Tone) { + /** + * AudioBuffer.copyTo/FromChannel polyfill + * @private + */ + if (Tone.supported) { + if (!AudioBuffer.prototype.copyToChannel) { + AudioBuffer.prototype.copyToChannel = function (src, chanNum, start) { + var channel = this.getChannelData(chanNum); + start = start || 0; + for (var i = 0; i < channel.length; i++) { + channel[i + start] = src[i]; + } + }; + AudioBuffer.prototype.copyFromChannel = function (dest, chanNum, start) { + var channel = this.getChannelData(chanNum); + start = start || 0; + for (var i = 0; i < dest.length; i++) { + dest[i] = channel[i + start]; + } + }; + } + } + }); + Module(function (Tone) { + + /** + * @class Buffer loading and storage. Tone.Buffer is used internally by all + * classes that make requests for audio files such as Tone.Player, + * Tone.Sampler and Tone.Convolver. + * + * Aside from load callbacks from individual buffers, Tone.Buffer + * provides events which keep track of the loading progress + * of _all_ of the buffers. These are Tone.Buffer.on("load" / "progress" / "error") + * + * @constructor + * @extends {Tone} + * @param {AudioBuffer|String} url The url to load, or the audio buffer to set. + * @param {Function=} onload A callback which is invoked after the buffer is loaded. + * It's recommended to use `Tone.Buffer.on('load', callback)` instead + * since it will give you a callback when _all_ buffers are loaded. + * @param {Function=} onerror The callback to invoke if there is an error + * @example + * var buffer = new Tone.Buffer("path/to/sound.mp3", function(){ + * //the buffer is now available. + * var buff = buffer.get(); + * }); + * @example + * //can load provide fallback extension types if the first type is not supported. + * var buffer = new Tone.Buffer("path/to/sound.[mp3|ogg|wav]"); + */ + Tone.Buffer = function () { + var options = Tone.defaults(arguments, [ + 'url', + 'onload', + 'onerror' + ], Tone.Buffer); + Tone.call(this); + /** + * stores the loaded AudioBuffer + * @type {AudioBuffer} + * @private + */ + this._buffer = null; + /** + * indicates if the buffer should be reversed or not + * @type {Boolean} + * @private + */ + this._reversed = options.reverse; + /** + * The XHR + * @type {XMLHttpRequest} + * @private + */ + this._xhr = null; + /** + * Private callback when the buffer is loaded. + * @type {Function} + * @private + */ + this._onload = Tone.noOp; + if (options.url instanceof AudioBuffer || options.url instanceof Tone.Buffer) { + this.set(options.url); + // invoke the onload callback + if (options.onload) { + if (this.loaded) { + options.onload(this); + } else { + this._onload = options.onload; + } + } + } else if (Tone.isString(options.url)) { + this.load(options.url).then(options.onload).catch(options.onerror); + } + }; + Tone.extend(Tone.Buffer); + /** + * the default parameters + * @type {Object} + */ + Tone.Buffer.defaults = { + 'url': undefined, + 'reverse': false, + 'onload': Tone.noOp, + 'onerror': Tone.noOp + }; + /** + * Pass in an AudioBuffer or Tone.Buffer to set the value + * of this buffer. + * @param {AudioBuffer|Tone.Buffer} buffer the buffer + * @returns {Tone.Buffer} this + */ + Tone.Buffer.prototype.set = function (buffer) { + if (buffer instanceof Tone.Buffer) { + if (buffer.loaded) { + this._buffer = buffer.get(); + } else { + buffer._onload = function () { + this.set(buffer); + this._onload(this); + }.bind(this); + } + } else { + this._buffer = buffer; + } + return this; + }; + /** + * @return {AudioBuffer} The audio buffer stored in the object. + */ + Tone.Buffer.prototype.get = function () { + return this._buffer; + }; + /** + * Makes an xhr reqest for the selected url then decodes + * the file as an audio buffer. Invokes + * the callback once the audio buffer loads. + * @param {String} url The url of the buffer to load. + * filetype support depends on the + * browser. + * @returns {Promise} returns a Promise which resolves with the Tone.Buffer + */ + Tone.Buffer.prototype.load = function (url, onload, onerror) { + var promise = new Promise(function (load, error) { + this._xhr = Tone.Buffer.load(url, //success + function (buff) { + this._xhr = null; + this.set(buff); + load(this); + this._onload(this); + if (onload) { + onload(this); + } + }.bind(this), //error + function (err) { + this._xhr = null; + error(err); + if (onerror) { + onerror(err); + } + }.bind(this)); + }.bind(this)); + return promise; + }; + /** + * dispose and disconnect + * @returns {Tone.Buffer} this + */ + Tone.Buffer.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._buffer = null; + if (this._xhr) { + Tone.Buffer._removeFromDownloadQueue(this._xhr); + this._xhr.abort(); + this._xhr = null; + } + return this; + }; + /** + * If the buffer is loaded or not + * @memberOf Tone.Buffer# + * @type {Boolean} + * @name loaded + * @readOnly + */ + Object.defineProperty(Tone.Buffer.prototype, 'loaded', { + get: function () { + return this.length > 0; + } + }); + /** + * The duration of the buffer. + * @memberOf Tone.Buffer# + * @type {Number} + * @name duration + * @readOnly + */ + Object.defineProperty(Tone.Buffer.prototype, 'duration', { + get: function () { + if (this._buffer) { + return this._buffer.duration; + } else { + return 0; + } + } + }); + /** + * The length of the buffer in samples + * @memberOf Tone.Buffer# + * @type {Number} + * @name length + * @readOnly + */ + Object.defineProperty(Tone.Buffer.prototype, 'length', { + get: function () { + if (this._buffer) { + return this._buffer.length; + } else { + return 0; + } + } + }); + /** + * The number of discrete audio channels. Returns 0 if no buffer + * is loaded. + * @memberOf Tone.Buffer# + * @type {Number} + * @name numberOfChannels + * @readOnly + */ + Object.defineProperty(Tone.Buffer.prototype, 'numberOfChannels', { + get: function () { + if (this._buffer) { + return this._buffer.numberOfChannels; + } else { + return 0; + } + } + }); + /** + * Set the audio buffer from the array. To create a multichannel AudioBuffer, + * pass in a multidimensional array. + * @param {Float32Array} array The array to fill the audio buffer + * @return {Tone.Buffer} this + */ + Tone.Buffer.prototype.fromArray = function (array) { + var isMultidimensional = array[0].length > 0; + var channels = isMultidimensional ? array.length : 1; + var len = isMultidimensional ? array[0].length : array.length; + var buffer = this.context.createBuffer(channels, len, this.context.sampleRate); + if (!isMultidimensional && channels === 1) { + array = [array]; + } + for (var c = 0; c < channels; c++) { + buffer.copyToChannel(array[c], c); + } + this._buffer = buffer; + return this; + }; + /** + * Sums muliple channels into 1 channel + * @param {Number=} channel Optionally only copy a single channel from the array. + * @return {Array} + */ + Tone.Buffer.prototype.toMono = function (chanNum) { + if (Tone.isNumber(chanNum)) { + this.fromArray(this.toArray(chanNum)); + } else { + var outputArray = new Float32Array(this.length); + var numChannels = this.numberOfChannels; + for (var channel = 0; channel < numChannels; channel++) { + var channelArray = this.toArray(channel); + for (var i = 0; i < channelArray.length; i++) { + outputArray[i] += channelArray[i]; + } + } + //divide by the number of channels + outputArray = outputArray.map(function (sample) { + return sample / numChannels; + }); + this.fromArray(outputArray); + } + return this; + }; + /** + * Get the buffer as an array. Single channel buffers will return a 1-dimensional + * Float32Array, and multichannel buffers will return multidimensional arrays. + * @param {Number=} channel Optionally only copy a single channel from the array. + * @return {Array} + */ + Tone.Buffer.prototype.toArray = function (channel) { + if (Tone.isNumber(channel)) { + return this.getChannelData(channel); + } else if (this.numberOfChannels === 1) { + return this.toArray(0); + } else { + var ret = []; + for (var c = 0; c < this.numberOfChannels; c++) { + ret[c] = this.getChannelData(c); + } + return ret; + } + }; + /** + * Returns the Float32Array representing the PCM audio data for the specific channel. + * @param {Number} channel The channel number to return + * @return {Float32Array} The audio as a TypedArray + */ + Tone.Buffer.prototype.getChannelData = function (channel) { + return this._buffer.getChannelData(channel); + }; + /** + * Cut a subsection of the array and return a buffer of the + * subsection. Does not modify the original buffer + * @param {Time} start The time to start the slice + * @param {Time=} end The end time to slice. If none is given + * will default to the end of the buffer + * @return {Tone.Buffer} this + */ + Tone.Buffer.prototype.slice = function (start, end) { + end = Tone.defaultArg(end, this.duration); + var startSamples = Math.floor(this.context.sampleRate * this.toSeconds(start)); + var endSamples = Math.floor(this.context.sampleRate * this.toSeconds(end)); + var replacement = []; + for (var i = 0; i < this.numberOfChannels; i++) { + replacement[i] = this.toArray(i).slice(startSamples, endSamples); + } + var retBuffer = new Tone.Buffer().fromArray(replacement); + return retBuffer; + }; + /** + * Reverse the buffer. + * @private + * @return {Tone.Buffer} this + */ + Tone.Buffer.prototype._reverse = function () { + if (this.loaded) { + for (var i = 0; i < this.numberOfChannels; i++) { + Array.prototype.reverse.call(this.getChannelData(i)); + } + } + return this; + }; + /** + * Reverse the buffer. + * @memberOf Tone.Buffer# + * @type {Boolean} + * @name reverse + */ + Object.defineProperty(Tone.Buffer.prototype, 'reverse', { + get: function () { + return this._reversed; + }, + set: function (rev) { + if (this._reversed !== rev) { + this._reversed = rev; + this._reverse(); + } + } + }); + /////////////////////////////////////////////////////////////////////////// + // STATIC METHODS + /////////////////////////////////////////////////////////////////////////// + //statically inherits Emitter methods + Tone.Emitter.mixin(Tone.Buffer); + /** + * the static queue for all of the xhr requests + * @type {Array} + * @private + */ + Tone.Buffer._downloadQueue = []; + /** + * A path which is prefixed before every url. + * @type {String} + * @static + */ + Tone.Buffer.baseUrl = ''; + /** + * Create a Tone.Buffer from the array. To create a multichannel AudioBuffer, + * pass in a multidimensional array. + * @param {Float32Array} array The array to fill the audio buffer + * @return {Tone.Buffer} A Tone.Buffer created from the array + */ + Tone.Buffer.fromArray = function (array) { + return new Tone.Buffer().fromArray(array); + }; + /** + * Creates a Tone.Buffer from a URL, returns a promise + * which resolves to a Tone.Buffer + * @param {String} url The url to load. + * @return {Promise<Tone.Buffer>} A promise which resolves to a Tone.Buffer + */ + Tone.Buffer.fromUrl = function (url) { + var buffer = new Tone.Buffer(); + return buffer.load(url).then(function () { + return buffer; + }); + }; + /** + * Remove an xhr request from the download queue + * @private + */ + Tone.Buffer._removeFromDownloadQueue = function (request) { + var index = Tone.Buffer._downloadQueue.indexOf(request); + if (index !== -1) { + Tone.Buffer._downloadQueue.splice(index, 1); + } + }; + /** + * Loads a url using XMLHttpRequest. + * @param {String} url + * @param {Function} onload + * @param {Function} onerror + * @param {Function} onprogress + * @return {XMLHttpRequest} + */ + Tone.Buffer.load = function (url, onload, onerror) { + //default + onload = Tone.defaultArg(onload, Tone.noOp); + // test if the url contains multiple extensions + var matches = url.match(/\[(.+\|?)+\]$/); + if (matches) { + var extensions = matches[1].split('|'); + var extension = extensions[0]; + for (var i = 0; i < extensions.length; i++) { + if (Tone.Buffer.supportsType(extensions[i])) { + extension = extensions[i]; + break; + } + } + url = url.replace(matches[0], extension); + } + function onError(e) { + Tone.Buffer._removeFromDownloadQueue(request); + Tone.Buffer.emit('error', e); + if (onerror) { + onerror(e); + } else { + throw e; + } + } + function onProgress() { + //calculate the progress + var totalProgress = 0; + for (var i = 0; i < Tone.Buffer._downloadQueue.length; i++) { + totalProgress += Tone.Buffer._downloadQueue[i].progress; + } + Tone.Buffer.emit('progress', totalProgress / Tone.Buffer._downloadQueue.length); + } + var request = new XMLHttpRequest(); + request.open('GET', Tone.Buffer.baseUrl + url, true); + request.responseType = 'arraybuffer'; + //start out as 0 + request.progress = 0; + Tone.Buffer._downloadQueue.push(request); + request.addEventListener('load', function () { + if (request.status === 200) { + Tone.context.decodeAudioData(request.response).then(function (buff) { + request.progress = 1; + onProgress(); + onload(buff); + Tone.Buffer._removeFromDownloadQueue(request); + if (Tone.Buffer._downloadQueue.length === 0) { + //emit the event at the end + Tone.Buffer.emit('load'); + } + }).catch(function () { + Tone.Buffer._removeFromDownloadQueue(request); + onError('Tone.Buffer: could not decode audio data: ' + url); + }); + } else { + onError('Tone.Buffer: could not locate file: ' + url); + } + }); + request.addEventListener('error', onError); + request.addEventListener('progress', function (event) { + if (event.lengthComputable) { + //only go to 95%, the last 5% is when the audio is decoded + request.progress = event.loaded / event.total * 0.95; + onProgress(); + } + }); + request.send(); + return request; + }; + /** + * Stop all of the downloads in progress + * @return {Tone.Buffer} + * @static + */ + Tone.Buffer.cancelDownloads = function () { + Tone.Buffer._downloadQueue.slice().forEach(function (request) { + Tone.Buffer._removeFromDownloadQueue(request); + request.abort(); + }); + return Tone.Buffer; + }; + /** + * Checks a url's extension to see if the current browser can play that file type. + * @param {String} url The url/extension to test + * @return {Boolean} If the file extension can be played + * @static + * @example + * Tone.Buffer.supportsType("wav"); //returns true + * Tone.Buffer.supportsType("path/to/file.wav"); //returns true + */ + Tone.Buffer.supportsType = function (url) { + var extension = url.split('.'); + extension = extension[extension.length - 1]; + var response = document.createElement('audio').canPlayType('audio/' + extension); + return response !== ''; + }; + /** + * Returns a Promise which resolves when all of the buffers have loaded + * @return {Promise} + */ + Tone.loaded = function () { + var onload, onerror; + function removeEvents() { + //remove the events when it's resolved + Tone.Buffer.off('load', onload); + Tone.Buffer.off('error', onerror); + } + return new Promise(function (success, fail) { + onload = function () { + success(); + }; + onerror = function () { + fail(); + }; + //add the event listeners + Tone.Buffer.on('load', onload); + Tone.Buffer.on('error', onerror); + }).then(removeEvents).catch(function (e) { + removeEvents(); + throw new Error(e); + }); + }; + return Tone.Buffer; + }); + Module(function (Tone) { + /** + * @class Wrapper around the native fire-and-forget OscillatorNode. Adds the + * ability to reschedule the stop method. + * @extends {Tone.AudioNode} + * @param {AudioBuffer|Tone.Buffer} buffer The buffer to play + * @param {Function} onload The callback to invoke when the + * buffer is done playing. + */ + Tone.OscillatorNode = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'type' + ], Tone.OscillatorNode); + Tone.AudioNode.call(this, options); + /** + * The callback to invoke after the + * buffer source is done playing. + * @type {Function} + */ + this.onended = options.onended; + /** + * The oscillator start time + * @type {Number} + * @private + */ + this._startTime = -1; + /** + * The oscillator stop time + * @type {Number} + * @private + */ + this._stopTime = -1; + /** + * The gain node which envelopes the OscillatorNode + * @type {Tone.Gain} + * @private + */ + this._gainNode = this.output = new Tone.Gain(); + this._gainNode.gain.setValueAtTime(0, this.context.currentTime); + /** + * The oscillator + * @type {OscillatorNode} + * @private + */ + this._oscillator = this.context.createOscillator(); + this._oscillator.connect(this._gainNode); + this.type = options.type; + /** + * The frequency of the oscillator + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Param(this._oscillator.frequency, Tone.Type.Frequency); + this.frequency.value = options.frequency; + /** + * The detune of the oscillator + * @type {Frequency} + * @signal + */ + this.detune = new Tone.Param(this._oscillator.detune, Tone.Type.Cents); + this.detune.value = options.detune; + /** + * The value that the buffer ramps to + * @type {Gain} + * @private + */ + this._gain = 1; + }; + Tone.extend(Tone.OscillatorNode, Tone.AudioNode); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.OscillatorNode.defaults = { + 'frequency': 440, + 'detune': 0, + 'type': 'sine', + 'onended': Tone.noOp + }; + /** + * Returns the playback state of the oscillator, either "started" or "stopped". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.OscillatorNode# + * @name state + */ + Object.defineProperty(Tone.OscillatorNode.prototype, 'state', { + get: function () { + return this.getStateAtTime(this.now()); + } + }); + /** + * Get the playback state at the given time + * @param {Time} time The time to test the state at + * @return {Tone.State} The playback state. + */ + Tone.OscillatorNode.prototype.getStateAtTime = function (time) { + time = this.toSeconds(time); + if (this._startTime !== -1 && time >= this._startTime && (this._stopTime === -1 || time <= this._stopTime)) { + return Tone.State.Started; + } else { + return Tone.State.Stopped; + } + }; + /** + * Start the oscillator node at the given time + * @param {Time=} time When to start the oscillator + * @return {OscillatorNode} this + */ + Tone.OscillatorNode.prototype.start = function (time) { + if (this._startTime === -1) { + this._startTime = this.toSeconds(time); + this._oscillator.start(this._startTime); + var now = this.context.currentTime; + this._gainNode.gain.cancelScheduledValues(now); + this._gainNode.gain.setValueAtTime(0, now); + this._gainNode.gain.setValueAtTime(1, this._startTime); + } else { + throw new Error('cannot call OscillatorNode.start more than once'); + } + return this; + }; + /** + * Sets an arbitrary custom periodic waveform given a PeriodicWave. + * @param {PeriodicWave} periodicWave PeriodicWave should be created with context.createPeriodicWave + * @return {OscillatorNode} this + */ + Tone.OscillatorNode.prototype.setPeriodicWave = function (periodicWave) { + this._oscillator.setPeriodicWave(periodicWave); + return this; + }; + /** + * Stop the oscillator node at the given time + * @param {Time=} time When to stop the oscillator + * @return {OscillatorNode} this + */ + Tone.OscillatorNode.prototype.stop = function (time) { + //cancel the previous stop + this.cancelStop(); + //reschedule it + this._stopTime = this.toSeconds(time); + this._gainNode.gain.setValueAtTime(0, this._stopTime); + this.context.clearTimeout(this._timeout); + this._timeout = this.context.setTimeout(function () { + this._oscillator.stop(this.now()); + this.onended(); + }.bind(this), this._stopTime - this.now()); + return this; + }; + /** + * Cancel a scheduled stop event + * @return {Tone.OscillatorNode} this + */ + Tone.OscillatorNode.prototype.cancelStop = function () { + if (this._startTime !== -1) { + //cancel the stop envelope + this._gainNode.gain.cancelScheduledValues(this._startTime + this.sampleTime); + this._gainNode.gain.setValueAtTime(1, Math.max(this.now(), this._startTime)); + this.context.clearTimeout(this._timeout); + this._stopTime = -1; + } + return this; + }; + /** + * The oscillator type. Either 'sine', 'sawtooth', 'square', or 'triangle' + * @memberOf Tone.OscillatorNode# + * @type {Time} + * @name type + */ + Object.defineProperty(Tone.OscillatorNode.prototype, 'type', { + get: function () { + return this._oscillator.type; + }, + set: function (type) { + this._oscillator.type = type; + } + }); + /** + * Clean up. + * @return {Tone.OscillatorNode} this + */ + Tone.OscillatorNode.prototype.dispose = function () { + this.context.clearTimeout(this._timeout); + Tone.AudioNode.prototype.dispose.call(this); + this.onended = null; + this._oscillator.disconnect(); + this._oscillator = null; + this._gainNode.dispose(); + this._gainNode = null; + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + return this; + }; + return Tone.OscillatorNode; + }); + Module(function (Tone) { + + /** + * @class Tone.Oscillator supports a number of features including + * phase rotation, multiple oscillator types (see Tone.Oscillator.type), + * and Transport syncing (see Tone.Oscillator.syncFrequency). + * + * @constructor + * @extends {Tone.Source} + * @param {Frequency} [frequency] Starting frequency + * @param {string} [type] The oscillator type. Read more about type below. + * @example + * //make and start a 440hz sine tone + * var osc = new Tone.Oscillator(440, "sine").toMaster().start(); + */ + Tone.Oscillator = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'type' + ], Tone.Oscillator); + Tone.Source.call(this, options); + /** + * the main oscillator + * @type {OscillatorNode} + * @private + */ + this._oscillator = null; + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune control signal. + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * the periodic wave + * @type {PeriodicWave} + * @private + */ + this._wave = null; + /** + * The partials of the oscillator + * @type {Array} + * @private + */ + this._partials = Tone.defaultArg(options.partials, [1]); + /** + * the phase of the oscillator + * between 0 - 360 + * @type {number} + * @private + */ + this._phase = options.phase; + /** + * the type of the oscillator + * @type {string} + * @private + */ + this._type = null; + //setup + this.type = options.type; + this.phase = this._phase; + this._readOnly([ + 'frequency', + 'detune' + ]); + }; + Tone.extend(Tone.Oscillator, Tone.Source); + /** + * the default parameters + * @type {Object} + */ + Tone.Oscillator.defaults = { + 'type': 'sine', + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'partials': [] + }; + /** + * The Oscillator types + * @enum {String} + */ + Tone.Oscillator.Type = { + Sine: 'sine', + Triangle: 'triangle', + Sawtooth: 'sawtooth', + Square: 'square', + Custom: 'custom' + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.Oscillator.prototype._start = function (time) { + //new oscillator with previous values + this._oscillator = new Tone.OscillatorNode(); + if (this._wave) { + this._oscillator.setPeriodicWave(this._wave); + } else { + this._oscillator.type = this._type; + } + //connect the control signal to the oscillator frequency & detune + this._oscillator.connect(this.output); + this.frequency.connect(this._oscillator.frequency); + this.detune.connect(this._oscillator.detune); + //start the oscillator + time = this.toSeconds(time); + this._oscillator.start(time); + }; + /** + * stop the oscillator + * @private + * @param {Time} [time=now] (optional) timing parameter + * @returns {Tone.Oscillator} this + */ + Tone.Oscillator.prototype._stop = function (time) { + if (this._oscillator) { + time = this.toSeconds(time); + this._oscillator.stop(time); + } + return this; + }; + /** + * Restart the oscillator. Does not stop the oscillator, but instead + * just cancels any scheduled 'stop' from being invoked. + * @param {Time=} time + * @return {Tone.Oscillator} this + */ + Tone.Oscillator.prototype.restart = function (time) { + this._oscillator.cancelStop(); + this._state.cancel(this.toSeconds(time)); + return this; + }; + /** + * Sync the signal to the Transport's bpm. Any changes to the transports bpm, + * will also affect the oscillators frequency. + * @returns {Tone.Oscillator} this + * @example + * Tone.Transport.bpm.value = 120; + * osc.frequency.value = 440; + * //the ration between the bpm and the frequency will be maintained + * osc.syncFrequency(); + * Tone.Transport.bpm.value = 240; + * // the frequency of the oscillator is doubled to 880 + */ + Tone.Oscillator.prototype.syncFrequency = function () { + Tone.Transport.syncSignal(this.frequency); + return this; + }; + /** + * Unsync the oscillator's frequency from the Transport. + * See Tone.Oscillator.syncFrequency + * @returns {Tone.Oscillator} this + */ + Tone.Oscillator.prototype.unsyncFrequency = function () { + Tone.Transport.unsyncSignal(this.frequency); + return this; + }; + /** + * The type of the oscillator: either sine, square, triangle, or sawtooth. Also capable of + * setting the first x number of partials of the oscillator. For example: "sine4" would + * set be the first 4 partials of the sine wave and "triangle8" would set the first + * 8 partials of the triangle wave. + * <br><br> + * Uses PeriodicWave internally even for native types so that it can set the phase. + * PeriodicWave equations are from the + * [Webkit Web Audio implementation](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/modules/webaudio/PeriodicWave.cpp&sq=package:chromium). + * + * @memberOf Tone.Oscillator# + * @type {string} + * @name type + * @example + * //set it to a square wave + * osc.type = "square"; + * @example + * //set the first 6 partials of a sawtooth wave + * osc.type = "sawtooth6"; + */ + Object.defineProperty(Tone.Oscillator.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + var isBasicType = [ + Tone.Oscillator.Type.Sine, + Tone.Oscillator.Type.Square, + Tone.Oscillator.Type.Triangle, + Tone.Oscillator.Type.Sawtooth + ].includes(type); + if (this._phase === 0 && isBasicType) { + this._wave = null; + //just go with the basic approach + if (this._oscillator !== null) { + this._oscillator.type === type; + } + } else { + var coefs = this._getRealImaginary(type, this._phase); + var periodicWave = this.context.createPeriodicWave(coefs[0], coefs[1]); + this._wave = periodicWave; + if (this._oscillator !== null) { + this._oscillator.setPeriodicWave(this._wave); + } + } + this._type = type; + } + }); + /** + * Returns the real and imaginary components based + * on the oscillator type. + * @returns {Array} [real, imaginary] + * @private + */ + Tone.Oscillator.prototype._getRealImaginary = function (type, phase) { + var fftSize = 4096; + var periodicWaveSize = fftSize / 2; + var real = new Float32Array(periodicWaveSize); + var imag = new Float32Array(periodicWaveSize); + var partialCount = 1; + if (type === Tone.Oscillator.Type.Custom) { + partialCount = this._partials.length + 1; + periodicWaveSize = partialCount; + } else { + var partial = /^(sine|triangle|square|sawtooth)(\d+)$/.exec(type); + if (partial) { + partialCount = parseInt(partial[2]) + 1; + type = partial[1]; + partialCount = Math.max(partialCount, 2); + periodicWaveSize = partialCount; + } + } + for (var n = 1; n < periodicWaveSize; ++n) { + var piFactor = 2 / (n * Math.PI); + var b; + switch (type) { + case Tone.Oscillator.Type.Sine: + b = n <= partialCount ? 1 : 0; + break; + case Tone.Oscillator.Type.Square: + b = n & 1 ? 2 * piFactor : 0; + break; + case Tone.Oscillator.Type.Sawtooth: + b = piFactor * (n & 1 ? 1 : -1); + break; + case Tone.Oscillator.Type.Triangle: + if (n & 1) { + b = 2 * (piFactor * piFactor) * (n - 1 >> 1 & 1 ? -1 : 1); + } else { + b = 0; + } + break; + case Tone.Oscillator.Type.Custom: + b = this._partials[n - 1]; + break; + default: + throw new TypeError('Tone.Oscillator: invalid type: ' + type); + } + if (b !== 0) { + real[n] = -b * Math.sin(phase * n); + imag[n] = b * Math.cos(phase * n); + } else { + real[n] = 0; + imag[n] = 0; + } + } + return [ + real, + imag + ]; + }; + /** + * Compute the inverse FFT for a given phase. + * @param {Float32Array} real + * @param {Float32Array} imag + * @param {NormalRange} phase + * @return {AudioRange} + * @private + */ + Tone.Oscillator.prototype._inverseFFT = function (real, imag, phase) { + var sum = 0; + var len = real.length; + for (var i = 0; i < len; i++) { + sum += real[i] * Math.cos(i * phase) + imag[i] * Math.sin(i * phase); + } + return sum; + }; + /** + * Returns the initial value of the oscillator. + * @return {AudioRange} + * @private + */ + Tone.Oscillator.prototype._getInitialValue = function () { + var coefs = this._getRealImaginary(this._type, 0); + var real = coefs[0]; + var imag = coefs[1]; + var maxValue = 0; + var twoPi = Math.PI * 2; + //check for peaks in 8 places + for (var i = 0; i < 8; i++) { + maxValue = Math.max(this._inverseFFT(real, imag, i / 8 * twoPi), maxValue); + } + return -this._inverseFFT(real, imag, this._phase) / maxValue; + }; + /** + * The partials of the waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * @memberOf Tone.Oscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.Oscillator.prototype, 'partials', { + get: function () { + if (this._type !== Tone.Oscillator.Type.Custom) { + return []; + } else { + return this._partials; + } + }, + set: function (partials) { + this._partials = partials; + this.type = Tone.Oscillator.Type.Custom; + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.Oscillator# + * @type {Degrees} + * @name phase + * @example + * osc.phase = 180; //flips the phase of the oscillator + */ + Object.defineProperty(Tone.Oscillator.prototype, 'phase', { + get: function () { + return this._phase * (180 / Math.PI); + }, + set: function (phase) { + this._phase = phase * Math.PI / 180; + //reset the type + this.type = this._type; + } + }); + /** + * Dispose and disconnect. + * @return {Tone.Oscillator} this + */ + Tone.Oscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + if (this._oscillator !== null) { + this._oscillator.dispose(); + this._oscillator = null; + } + this._wave = null; + this._writable([ + 'frequency', + 'detune' + ]); + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + this._partials = null; + return this; + }; + return Tone.Oscillator; + }); + Module(function (Tone) { + + /** + * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. + * See Tone.GainToAudio. + * + * @extends {Tone.SignalBase} + * @constructor + * @example + * var a2g = new Tone.AudioToGain(); + */ + Tone.AudioToGain = function () { + Tone.SignalBase.call(this); + /** + * @type {WaveShaperNode} + * @private + */ + this._norm = this.input = this.output = new Tone.WaveShaper(function (x) { + return (x + 1) / 2; + }); + }; + Tone.extend(Tone.AudioToGain, Tone.SignalBase); + /** + * clean up + * @returns {Tone.AudioToGain} this + */ + Tone.AudioToGain.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._norm.dispose(); + this._norm = null; + return this; + }; + return Tone.AudioToGain; + }); + Module(function (Tone) { + /** + * @class Tone.Zero outputs 0's at audio-rate. The reason this has to be + * it's own class is that many browsers optimize out Tone.Signal + * with a value of 0 and will not process nodes further down the graph. + * @extends {Tone.SignalBase} + */ + Tone.Zero = function () { + Tone.SignalBase.call(this); + /** + * The gain node + * @type {Tone.Gain} + * @private + */ + this._gain = this.input = this.output = new Tone.Gain(); + this.context.getConstant(0).connect(this._gain); + }; + Tone.extend(Tone.Zero, Tone.SignalBase); + /** + * clean up + * @return {Tone.Zero} this + */ + Tone.Zero.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._gain.dispose(); + this._gain = null; + return this; + }; + return Tone.Zero; + }); + Module(function (Tone) { + + /** + * @class LFO stands for low frequency oscillator. Tone.LFO produces an output signal + * which can be attached to an AudioParam or Tone.Signal + * in order to modulate that parameter with an oscillator. The LFO can + * also be synced to the transport to start/stop and change when the tempo changes. + * + * @constructor + * @extends {Tone.AudioNode} + * @param {Frequency|Object} [frequency] The frequency of the oscillation. Typically, LFOs will be + * in the frequency range of 0.1 to 10 hertz. + * @param {number=} min The minimum output value of the LFO. + * @param {number=} max The maximum value of the LFO. + * @example + * var lfo = new Tone.LFO("4n", 400, 4000); + * lfo.connect(filter.frequency); + */ + Tone.LFO = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'min', + 'max' + ], Tone.LFO); + Tone.AudioNode.call(this); + /** + * The oscillator. + * @type {Tone.Oscillator} + * @private + */ + this._oscillator = new Tone.Oscillator({ + 'frequency': options.frequency, + 'type': options.type + }); + /** + * the lfo's frequency + * @type {Frequency} + * @signal + */ + this.frequency = this._oscillator.frequency; + /** + * The amplitude of the LFO, which controls the output range between + * the min and max output. For example if the min is -10 and the max + * is 10, setting the amplitude to 0.5 would make the LFO modulate + * between -5 and 5. + * @type {Number} + * @signal + */ + this.amplitude = this._oscillator.volume; + this.amplitude.units = Tone.Type.NormalRange; + this.amplitude.value = options.amplitude; + /** + * The signal which is output when the LFO is stopped + * @type {Tone.Signal} + * @private + */ + this._stoppedSignal = new Tone.Signal(0, Tone.Type.AudioRange); + /** + * Just outputs zeros. + * @type {Tone.Zero} + * @private + */ + this._zeros = new Tone.Zero(); + /** + * The value that the LFO outputs when it's stopped + * @type {AudioRange} + * @private + */ + this._stoppedValue = 0; + /** + * @type {Tone.AudioToGain} + * @private + */ + this._a2g = new Tone.AudioToGain(); + /** + * @type {Tone.Scale} + * @private + */ + this._scaler = this.output = new Tone.Scale(options.min, options.max); + /** + * the units of the LFO (used for converting) + * @type {Tone.Type} + * @private + */ + this._units = Tone.Type.Default; + this.units = options.units; + //connect it up + this._oscillator.chain(this._a2g, this._scaler); + this._zeros.connect(this._a2g); + this._stoppedSignal.connect(this._a2g); + this._readOnly([ + 'amplitude', + 'frequency' + ]); + this.phase = options.phase; + }; + Tone.extend(Tone.LFO, Tone.AudioNode); + /** + * the default parameters + * + * @static + * @const + * @type {Object} + */ + Tone.LFO.defaults = { + 'type': 'sine', + 'min': 0, + 'max': 1, + 'phase': 0, + 'frequency': '4n', + 'amplitude': 1, + 'units': Tone.Type.Default + }; + /** + * Start the LFO. + * @param {Time} [time=now] the time the LFO will start + * @returns {Tone.LFO} this + */ + Tone.LFO.prototype.start = function (time) { + time = this.toSeconds(time); + this._stoppedSignal.setValueAtTime(0, time); + this._oscillator.start(time); + return this; + }; + /** + * Stop the LFO. + * @param {Time} [time=now] the time the LFO will stop + * @returns {Tone.LFO} this + */ + Tone.LFO.prototype.stop = function (time) { + time = this.toSeconds(time); + this._stoppedSignal.setValueAtTime(this._stoppedValue, time); + this._oscillator.stop(time); + return this; + }; + /** + * Sync the start/stop/pause to the transport + * and the frequency to the bpm of the transport + * @returns {Tone.LFO} this + * @example + * lfo.frequency.value = "8n"; + * lfo.sync().start(0) + * //the rate of the LFO will always be an eighth note, + * //even as the tempo changes + */ + Tone.LFO.prototype.sync = function () { + this._oscillator.sync(); + this._oscillator.syncFrequency(); + return this; + }; + /** + * unsync the LFO from transport control + * @returns {Tone.LFO} this + */ + Tone.LFO.prototype.unsync = function () { + this._oscillator.unsync(); + this._oscillator.unsyncFrequency(); + return this; + }; + /** + * The miniumum output of the LFO. + * @memberOf Tone.LFO# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.LFO.prototype, 'min', { + get: function () { + return this._toUnits(this._scaler.min); + }, + set: function (min) { + min = this._fromUnits(min); + this._scaler.min = min; + } + }); + /** + * The maximum output of the LFO. + * @memberOf Tone.LFO# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.LFO.prototype, 'max', { + get: function () { + return this._toUnits(this._scaler.max); + }, + set: function (max) { + max = this._fromUnits(max); + this._scaler.max = max; + } + }); + /** + * The type of the oscillator: sine, square, sawtooth, triangle. + * @memberOf Tone.LFO# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.LFO.prototype, 'type', { + get: function () { + return this._oscillator.type; + }, + set: function (type) { + this._oscillator.type = type; + this._stoppedValue = this._oscillator._getInitialValue(); + this._stoppedSignal.value = this._stoppedValue; + } + }); + /** + * The phase of the LFO. + * @memberOf Tone.LFO# + * @type {number} + * @name phase + */ + Object.defineProperty(Tone.LFO.prototype, 'phase', { + get: function () { + return this._oscillator.phase; + }, + set: function (phase) { + this._oscillator.phase = phase; + this._stoppedValue = this._oscillator._getInitialValue(); + this._stoppedSignal.value = this._stoppedValue; + } + }); + /** + * The output units of the LFO. + * @memberOf Tone.LFO# + * @type {Tone.Type} + * @name units + */ + Object.defineProperty(Tone.LFO.prototype, 'units', { + get: function () { + return this._units; + }, + set: function (val) { + var currentMin = this.min; + var currentMax = this.max; + //convert the min and the max + this._units = val; + this.min = currentMin; + this.max = currentMax; + } + }); + /** + * Mute the output. + * @memberOf Tone.LFO# + * @type {Boolean} + * @name mute + */ + Object.defineProperty(Tone.LFO.prototype, 'mute', { + get: function () { + return this._oscillator.mute; + }, + set: function (mute) { + this._oscillator.mute = mute; + } + }); + /** + * Returns the playback state of the source, either "started" or "stopped". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.LFO# + * @name state + */ + Object.defineProperty(Tone.LFO.prototype, 'state', { + get: function () { + return this._oscillator.state; + } + }); + /** + * Connect the output of the LFO to an AudioParam, AudioNode, or Tone Node. + * Tone.LFO will automatically convert to the destination units of the + * will get the units from the connected node. + * @param {Tone | AudioParam | AudioNode} node + * @param {number} [outputNum=0] optionally which output to connect from + * @param {number} [inputNum=0] optionally which input to connect to + * @returns {Tone.LFO} this + * @private + */ + Tone.LFO.prototype.connect = function (node) { + if (node.constructor === Tone.Signal || node.constructor === Tone.Param) { + this.convert = node.convert; + this.units = node.units; + } + Tone.SignalBase.prototype.connect.apply(this, arguments); + return this; + }; + /** + * private method borrowed from Param converts + * units from their destination value + * @function + * @private + */ + Tone.LFO.prototype._fromUnits = Tone.Param.prototype._fromUnits; + /** + * private method borrowed from Param converts + * units to their destination value + * @function + * @private + */ + Tone.LFO.prototype._toUnits = Tone.Param.prototype._toUnits; + /** + * disconnect and dispose + * @returns {Tone.LFO} this + */ + Tone.LFO.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._writable([ + 'amplitude', + 'frequency' + ]); + this._oscillator.dispose(); + this._oscillator = null; + this._stoppedSignal.dispose(); + this._stoppedSignal = null; + this._zeros.dispose(); + this._zeros = null; + this._scaler.dispose(); + this._scaler = null; + this._a2g.dispose(); + this._a2g = null; + this.frequency = null; + this.amplitude = null; + return this; + }; + return Tone.LFO; + }); + Module(function (Tone) { + + /** + * @class Tone.Limiter will limit the loudness of an incoming signal. + * It is composed of a Tone.Compressor with a fast attack + * and release. Limiters are commonly used to safeguard against + * signal clipping. Unlike a compressor, limiters do not provide + * smooth gain reduction and almost completely prevent + * additional gain above the threshold. + * + * @extends {Tone.AudioNode} + * @constructor + * @param {number} threshold The theshold above which the limiting is applied. + * @example + * var limiter = new Tone.Limiter(-6); + */ + Tone.Limiter = function () { + var options = Tone.defaults(arguments, ['threshold'], Tone.Limiter); + Tone.AudioNode.call(this); + /** + * the compressor + * @private + * @type {Tone.Compressor} + */ + this._compressor = this.input = this.output = new Tone.Compressor({ + 'attack': 0.001, + 'decay': 0.001, + 'threshold': options.threshold + }); + /** + * The threshold of of the limiter + * @type {Decibel} + * @signal + */ + this.threshold = this._compressor.threshold; + this._readOnly('threshold'); + }; + Tone.extend(Tone.Limiter, Tone.AudioNode); + /** + * The default value + * @type {Object} + * @const + * @static + */ + Tone.Limiter.defaults = { 'threshold': -12 }; + /** + * Clean up. + * @returns {Tone.Limiter} this + */ + Tone.Limiter.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._compressor.dispose(); + this._compressor = null; + this._writable('threshold'); + this.threshold = null; + return this; + }; + return Tone.Limiter; + }); + Module(function (Tone) { + + /** + * @class Tone.Lowpass is a lowpass feedback comb filter. It is similar to + * Tone.FeedbackCombFilter, but includes a lowpass filter. + * + * @extends {Tone.AudioNode} + * @constructor + * @param {Time|Object} [delayTime] The delay time of the comb filter + * @param {NormalRange=} resonance The resonance (feedback) of the comb filter + * @param {Frequency=} dampening The cutoff of the lowpass filter dampens the + * signal as it is fedback. + */ + Tone.LowpassCombFilter = function () { + var options = Tone.defaults(arguments, [ + 'delayTime', + 'resonance', + 'dampening' + ], Tone.LowpassCombFilter); + Tone.AudioNode.call(this); + this.createInsOuts(1, 1); + /** + * the delay node + * @type {DelayNode} + * @private + */ + this._delay = this.input = new Tone.Delay(options.delayTime); + /** + * The delayTime of the comb filter. + * @type {Time} + * @signal + */ + this.delayTime = this._delay.delayTime; + /** + * the lowpass filter + * @type {BiquadFilterNode} + * @private + */ + this._lowpass = this.output = this.context.createBiquadFilter(); + this._lowpass.Q.value = -3.0102999566398125; + this._lowpass.type = 'lowpass'; + /** + * The dampening control of the feedback + * @type {Frequency} + * @signal + */ + this.dampening = new Tone.Param({ + 'param': this._lowpass.frequency, + 'units': Tone.Type.Frequency, + 'value': options.dampening + }); + /** + * the feedback gain + * @type {Tone.Gain} + * @private + */ + this._feedback = new Tone.Gain(options.resonance, Tone.Type.NormalRange); + /** + * The amount of feedback of the delayed signal. + * @type {NormalRange} + * @signal + */ + this.resonance = this._feedback.gain; + //connections + this._delay.chain(this._lowpass, this._feedback, this._delay); + this._readOnly([ + 'dampening', + 'resonance', + 'delayTime' + ]); + }; + Tone.extend(Tone.LowpassCombFilter, Tone.AudioNode); + /** + * the default parameters + * @static + * @const + * @type {Object} + */ + Tone.LowpassCombFilter.defaults = { + 'delayTime': 0.1, + 'resonance': 0.5, + 'dampening': 3000 + }; + /** + * Clean up. + * @returns {Tone.LowpassCombFilter} this + */ + Tone.LowpassCombFilter.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._writable([ + 'dampening', + 'resonance', + 'delayTime' + ]); + this.dampening.dispose(); + this.dampening = null; + this.resonance.dispose(); + this.resonance = null; + this._delay.dispose(); + this._delay = null; + this.delayTime = null; + this._lowpass.disconnect(); + this._lowpass = null; + this._feedback.disconnect(); + this._feedback = null; + return this; + }; + return Tone.LowpassCombFilter; + }); + Module(function (Tone) { + + /** + * @class Tone.Merge brings two signals into the left and right + * channels of a single stereo channel. + * + * @constructor + * @extends {Tone.AudioNode} + * @example + * var merge = new Tone.Merge().toMaster(); + * //routing a sine tone in the left channel + * //and noise in the right channel + * var osc = new Tone.Oscillator().connect(merge.left); + * var noise = new Tone.Noise().connect(merge.right); + * //starting our oscillators + * noise.start(); + * osc.start(); + */ + Tone.Merge = function () { + Tone.AudioNode.call(this); + this.createInsOuts(2, 0); + /** + * The left input channel. + * Alias for <code>input[0]</code> + * @type {GainNode} + */ + this.left = this.input[0] = new Tone.Gain(); + /** + * The right input channel. + * Alias for <code>input[1]</code>. + * @type {GainNode} + */ + this.right = this.input[1] = new Tone.Gain(); + /** + * the merger node for the two channels + * @type {ChannelMergerNode} + * @private + */ + this._merger = this.output = this.context.createChannelMerger(2); + //connections + this.left.connect(this._merger, 0, 0); + this.right.connect(this._merger, 0, 1); + this.left.channelCount = 1; + this.right.channelCount = 1; + this.left.channelCountMode = 'explicit'; + this.right.channelCountMode = 'explicit'; + }; + Tone.extend(Tone.Merge, Tone.AudioNode); + /** + * Clean up. + * @returns {Tone.Merge} this + */ + Tone.Merge.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this.left.dispose(); + this.left = null; + this.right.dispose(); + this.right = null; + this._merger.disconnect(); + this._merger = null; + return this; + }; + return Tone.Merge; + }); + Module(function (Tone) { + + /** + * @class Tone.Meter gets the [RMS](https://en.wikipedia.org/wiki/Root_mean_square) + * of an input signal with some averaging applied. It can also get the raw + * value of the input signal. + * + * @constructor + * @extends {Tone.AudioNode} + * @param {Number} smoothing The amount of smoothing applied between frames. + * @example + * var meter = new Tone.Meter(); + * var mic = new Tone.UserMedia().open(); + * //connect mic to the meter + * mic.connect(meter); + * //the current level of the mic input in decibels + * var level = meter.getValue(); + */ + Tone.Meter = function () { + var options = Tone.defaults(arguments, ['smoothing'], Tone.Meter); + Tone.AudioNode.call(this); + /** + * The analyser node which computes the levels. + * @private + * @type {Tone.Analyser} + */ + this.input = this.output = this._analyser = new Tone.Analyser('waveform', 1024); + /** + * The amount of carryover between the current and last frame. + * Only applied meter for "level" type. + * @type {Number} + */ + this.smoothing = options.smoothing; + }; + Tone.extend(Tone.Meter, Tone.AudioNode); + /** + * The defaults + * @type {Object} + * @static + * @const + */ + Tone.Meter.defaults = { 'smoothing': 0.8 }; + /** + * Get the current decibel value of the incoming signal + * @returns {Decibels} + */ + Tone.Meter.prototype.getLevel = function () { + this._analyser.type = 'fft'; + var values = this._analyser.getValue(); + var offset = 28; + // normalizes most signal levels + // TODO: compute loudness from FFT + return Math.max.apply(this, values) + offset; + }; + /** + * Get the signal value of the incoming signal + * @returns {Number} + */ + Tone.Meter.prototype.getValue = function () { + this._analyser.type = 'waveform'; + var value = this._analyser.getValue(); + return value[0]; + }; + /** + * A value from 0 -> 1 where 0 represents no time averaging with the last analysis frame. + * @memberOf Tone.Meter# + * @type {Number} + * @name smoothing + * @readOnly + */ + Object.defineProperty(Tone.Meter.prototype, 'smoothing', { + get: function () { + return this._analyser.smoothing; + }, + set: function (val) { + this._analyser.smoothing = val; + } + }); + /** + * Clean up. + * @returns {Tone.Meter} this + */ + Tone.Meter.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._analyser.dispose(); + this._analyser = null; + return this; + }; + return Tone.Meter; + }); + Module(function (Tone) { + + /** + * @class Tone.Split splits an incoming signal into left and right channels. + * + * @constructor + * @extends {Tone.AudioNode} + * @example + * var split = new Tone.Split(); + * stereoSignal.connect(split); + */ + Tone.Split = function () { + Tone.AudioNode.call(this); + this.createInsOuts(0, 2); + /** + * @type {ChannelSplitterNode} + * @private + */ + this._splitter = this.input = this.context.createChannelSplitter(2); + this._splitter.channelCount = 2; + this._splitter.channelCountMode = 'explicit'; + /** + * Left channel output. + * Alias for <code>output[0]</code> + * @type {Tone.Gain} + */ + this.left = this.output[0] = new Tone.Gain(); + /** + * Right channel output. + * Alias for <code>output[1]</code> + * @type {Tone.Gain} + */ + this.right = this.output[1] = new Tone.Gain(); + //connections + this._splitter.connect(this.left, 0, 0); + this._splitter.connect(this.right, 1, 0); + }; + Tone.extend(Tone.Split, Tone.AudioNode); + /** + * Clean up. + * @returns {Tone.Split} this + */ + Tone.Split.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._splitter.disconnect(); + this.left.dispose(); + this.left = null; + this.right.dispose(); + this.right = null; + this._splitter = null; + return this; + }; + return Tone.Split; + }); + Module(function (Tone) { + + /** + * @class Mid/Side processing separates the the 'mid' signal + * (which comes out of both the left and the right channel) + * and the 'side' (which only comes out of the the side channels). <br><br> + * <code> + * Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right<br> + * Side = (Left-Right)/sqrt(2); // obtain side-signal from left and righ<br> + * </code> + * + * @extends {Tone.AudioNode} + * @constructor + */ + Tone.MidSideSplit = function () { + Tone.AudioNode.call(this); + this.createInsOuts(0, 2); + /** + * split the incoming signal into left and right channels + * @type {Tone.Split} + * @private + */ + this._split = this.input = new Tone.Split(); + /** + * The mid send. Connect to mid processing. Alias for + * <code>output[0]</code> + * @type {Tone.Add} + */ + this._midAdd = new Tone.Add(); + /** + * Multiply the _midAdd by sqrt(1/2) + * @type {Tone.Multiply} + */ + this.mid = this.output[0] = new Tone.Multiply(Math.SQRT1_2); + /** + * The side output. Connect to side processing. Also Output 1 + * @type {Tone.Subtract} + */ + this._sideSubtract = new Tone.Subtract(); + /** + * Multiply the _midAdd by sqrt(1/2) + * @type {Tone.Multiply} + */ + this.side = this.output[1] = new Tone.Multiply(Math.SQRT1_2); + this._split.connect(this._midAdd, 0, 0); + this._split.connect(this._midAdd, 1, 1); + this._split.connect(this._sideSubtract, 0, 0); + this._split.connect(this._sideSubtract, 1, 1); + this._midAdd.connect(this.mid); + this._sideSubtract.connect(this.side); + }; + Tone.extend(Tone.MidSideSplit, Tone.AudioNode); + /** + * clean up + * @returns {Tone.MidSideSplit} this + */ + Tone.MidSideSplit.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this.mid.dispose(); + this.mid = null; + this.side.dispose(); + this.side = null; + this._midAdd.dispose(); + this._midAdd = null; + this._sideSubtract.dispose(); + this._sideSubtract = null; + this._split.dispose(); + this._split = null; + return this; + }; + return Tone.MidSideSplit; + }); + Module(function (Tone) { + + /** + * @class Mid/Side processing separates the the 'mid' signal + * (which comes out of both the left and the right channel) + * and the 'side' (which only comes out of the the side channels). + * MidSideMerge merges the mid and side signal after they've been seperated + * by Tone.MidSideSplit.<br><br> + * <code> + * Left = (Mid+Side)/sqrt(2); // obtain left signal from mid and side<br> + * Right = (Mid-Side)/sqrt(2); // obtain right signal from mid and side<br> + * </code> + * + * @extends {Tone.AudioNode} + * @constructor + */ + Tone.MidSideMerge = function () { + Tone.AudioNode.call(this); + this.createInsOuts(2, 0); + /** + * The mid signal input. Alias for + * <code>input[0]</code> + * @type {Tone.Gain} + */ + this.mid = this.input[0] = new Tone.Gain(); + /** + * recombine the mid/side into Left + * @type {Tone.Add} + * @private + */ + this._left = new Tone.Add(); + /** + * Multiply the left by sqrt(1/2) + * @type {Tone.Multiply} + */ + this._timesTwoLeft = new Tone.Multiply(Math.SQRT1_2); + /** + * The side signal input. Alias for + * <code>input[1]</code> + * @type {Tone.Gain} + */ + this.side = this.input[1] = new Tone.Gain(); + /** + * recombine the mid/side into Right + * @type {Tone.Subtract} + * @private + */ + this._right = new Tone.Subtract(); + /** + * Multiply the right by sqrt(1/2) + * @type {Tone.Multiply} + */ + this._timesTwoRight = new Tone.Multiply(Math.SQRT1_2); + /** + * Merge the left/right signal back into a stereo signal. + * @type {Tone.Merge} + * @private + */ + this._merge = this.output = new Tone.Merge(); + this.mid.connect(this._left, 0, 0); + this.side.connect(this._left, 0, 1); + this.mid.connect(this._right, 0, 0); + this.side.connect(this._right, 0, 1); + this._left.connect(this._timesTwoLeft); + this._right.connect(this._timesTwoRight); + this._timesTwoLeft.connect(this._merge, 0, 0); + this._timesTwoRight.connect(this._merge, 0, 1); + }; + Tone.extend(Tone.MidSideMerge, Tone.AudioNode); + /** + * clean up + * @returns {Tone.MidSideMerge} this + */ + Tone.MidSideMerge.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this.mid.dispose(); + this.mid = null; + this.side.dispose(); + this.side = null; + this._left.dispose(); + this._left = null; + this._timesTwoLeft.dispose(); + this._timesTwoLeft = null; + this._right.dispose(); + this._right = null; + this._timesTwoRight.dispose(); + this._timesTwoRight = null; + this._merge.dispose(); + this._merge = null; + return this; + }; + return Tone.MidSideMerge; + }); + Module(function (Tone) { + + /** + * @class Tone.MidSideCompressor applies two different compressors to the mid + * and side signal components. See Tone.MidSideSplit. + * + * @extends {Tone.AudioNode} + * @param {Object} options The options that are passed to the mid and side + * compressors. + * @constructor + */ + Tone.MidSideCompressor = function (options) { + Tone.AudioNode.call(this); + options = Tone.defaultArg(options, Tone.MidSideCompressor.defaults); + /** + * the mid/side split + * @type {Tone.MidSideSplit} + * @private + */ + this._midSideSplit = this.input = new Tone.MidSideSplit(); + /** + * the mid/side recombination + * @type {Tone.MidSideMerge} + * @private + */ + this._midSideMerge = this.output = new Tone.MidSideMerge(); + /** + * The compressor applied to the mid signal + * @type {Tone.Compressor} + */ + this.mid = new Tone.Compressor(options.mid); + /** + * The compressor applied to the side signal + * @type {Tone.Compressor} + */ + this.side = new Tone.Compressor(options.side); + this._midSideSplit.mid.chain(this.mid, this._midSideMerge.mid); + this._midSideSplit.side.chain(this.side, this._midSideMerge.side); + this._readOnly([ + 'mid', + 'side' + ]); + }; + Tone.extend(Tone.MidSideCompressor, Tone.AudioNode); + /** + * @const + * @static + * @type {Object} + */ + Tone.MidSideCompressor.defaults = { + 'mid': { + 'ratio': 3, + 'threshold': -24, + 'release': 0.03, + 'attack': 0.02, + 'knee': 16 + }, + 'side': { + 'ratio': 6, + 'threshold': -30, + 'release': 0.25, + 'attack': 0.03, + 'knee': 10 + } + }; + /** + * Clean up. + * @returns {Tone.MidSideCompressor} this + */ + Tone.MidSideCompressor.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._writable([ + 'mid', + 'side' + ]); + this.mid.dispose(); + this.mid = null; + this.side.dispose(); + this.side = null; + this._midSideSplit.dispose(); + this._midSideSplit = null; + this._midSideMerge.dispose(); + this._midSideMerge = null; + return this; + }; + return Tone.MidSideCompressor; + }); + Module(function (Tone) { + + /** + * @class Tone.Mono coerces the incoming mono or stereo signal into a mono signal + * where both left and right channels have the same value. This can be useful + * for [stereo imaging](https://en.wikipedia.org/wiki/Stereo_imaging). + * + * @extends {Tone.AudioNode} + * @constructor + */ + Tone.Mono = function () { + Tone.AudioNode.call(this); + this.createInsOuts(1, 0); + /** + * merge the signal + * @type {Tone.Merge} + * @private + */ + this._merge = this.output = new Tone.Merge(); + this.input.connect(this._merge, 0, 0); + this.input.connect(this._merge, 0, 1); + }; + Tone.extend(Tone.Mono, Tone.AudioNode); + /** + * clean up + * @returns {Tone.Mono} this + */ + Tone.Mono.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._merge.dispose(); + this._merge = null; + return this; + }; + return Tone.Mono; + }); + Module(function (Tone) { + + /** + * @class A compressor with seperate controls over low/mid/high dynamics + * + * @extends {Tone.AudioNode} + * @constructor + * @param {Object} options The low/mid/high compressor settings. + * @example + * var multiband = new Tone.MultibandCompressor({ + * "lowFrequency" : 200, + * "highFrequency" : 1300 + * "low" : { + * "threshold" : -12 + * } + * }) + */ + Tone.MultibandCompressor = function (options) { + Tone.AudioNode.call(this); + options = Tone.defaultArg(arguments, Tone.MultibandCompressor.defaults); + /** + * split the incoming signal into high/mid/low + * @type {Tone.MultibandSplit} + * @private + */ + this._splitter = this.input = new Tone.MultibandSplit({ + 'lowFrequency': options.lowFrequency, + 'highFrequency': options.highFrequency + }); + /** + * low/mid crossover frequency. + * @type {Frequency} + * @signal + */ + this.lowFrequency = this._splitter.lowFrequency; + /** + * mid/high crossover frequency. + * @type {Frequency} + * @signal + */ + this.highFrequency = this._splitter.highFrequency; + /** + * the output + * @type {Tone.Gain} + * @private + */ + this.output = new Tone.Gain(); + /** + * The compressor applied to the low frequencies. + * @type {Tone.Compressor} + */ + this.low = new Tone.Compressor(options.low); + /** + * The compressor applied to the mid frequencies. + * @type {Tone.Compressor} + */ + this.mid = new Tone.Compressor(options.mid); + /** + * The compressor applied to the high frequencies. + * @type {Tone.Compressor} + */ + this.high = new Tone.Compressor(options.high); + //connect the compressor + this._splitter.low.chain(this.low, this.output); + this._splitter.mid.chain(this.mid, this.output); + this._splitter.high.chain(this.high, this.output); + this._readOnly([ + 'high', + 'mid', + 'low', + 'highFrequency', + 'lowFrequency' + ]); + }; + Tone.extend(Tone.MultibandCompressor, Tone.AudioNode); + /** + * @const + * @static + * @type {Object} + */ + Tone.MultibandCompressor.defaults = { + 'low': Tone.Compressor.defaults, + 'mid': Tone.Compressor.defaults, + 'high': Tone.Compressor.defaults, + 'lowFrequency': 250, + 'highFrequency': 2000 + }; + /** + * clean up + * @returns {Tone.MultibandCompressor} this + */ + Tone.MultibandCompressor.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._splitter.dispose(); + this._writable([ + 'high', + 'mid', + 'low', + 'highFrequency', + 'lowFrequency' + ]); + this.low.dispose(); + this.mid.dispose(); + this.high.dispose(); + this._splitter = null; + this.low = null; + this.mid = null; + this.high = null; + this.lowFrequency = null; + this.highFrequency = null; + return this; + }; + return Tone.MultibandCompressor; + }); + Module(function (Tone) { + if (Tone.supported && !window.StereoPannerNode) { + /** + * @class Shimmed StereoPannerNode + * @param {AudioContext} context + * @private + */ + var StereoPannerNode = function (context) { + /** + * The audio context + * @type {AudioContext} + */ + this.context = context; + /** + * The left/right panning. [-1, 1] + * @type {AudioRange} + * @signal + */ + this.pan = new Tone.Signal(0, Tone.Type.AudioRange); + /** + * Equal power scaling of the right gain + * @type {Tone.WaveShaper} + */ + var rightWaveShaper = new Tone.WaveShaper(function (val) { + return Tone.equalPowerScale((val + 1) / 2); + }, 4096); + /** + * Equal power scaling of the left gain + * @type {Tone.WaveShaper} + * @private + */ + var leftWaveShaper = new Tone.WaveShaper(function (val) { + return Tone.equalPowerScale(1 - (val + 1) / 2); + }, 4096); + /** + * The left gain value + * @type {Tone.Gain} + * @private + */ + var leftGain = new Tone.Gain(); + /** + * The right gain value + * @type {Tone.Gain} + * @private + */ + var rightGain = new Tone.Gain(); + /** + * Split the incoming signal + * @type {Tone.Split} + * @private + */ + var split = this.input = new Tone.Split(); + /** + * Keeps the waveshapers from optimizing 0s + * @type {Tone.Zero} + * @private + */ + var zero = new Tone.Zero(); + zero.fan(rightWaveShaper, leftWaveShaper); + /** + * Merge the outgoing signal + * @type {Tone.Merge} + * @private + */ + var merge = this.output = new Tone.Merge(); + //connections + split.left.chain(leftGain, merge.left); + split.right.chain(rightGain, merge.right); + this.pan.chain(leftWaveShaper, leftGain.gain); + this.pan.chain(rightWaveShaper, rightGain.gain); + }; + StereoPannerNode.prototype.disconnect = function () { + this.output.disconnect.apply(this.output, arguments); + }; + StereoPannerNode.prototype.connect = function () { + this.output.connect.apply(this.output, arguments); + }; + //add it to the AudioContext + AudioContext.prototype.createStereoPanner = function () { + return new StereoPannerNode(this); + }; + Tone.Context.prototype.createStereoPanner = function () { + return new StereoPannerNode(this); + }; + } + }); + Module(function (Tone) { + + /** + * @class Tone.Panner is an equal power Left/Right Panner and does not + * support 3D. Panner uses the StereoPannerNode when available. + * + * @constructor + * @extends {Tone.AudioNode} + * @param {NormalRange} [initialPan=0] The initail panner value (center). + * @example + * //pan the input signal hard right. + * var panner = new Tone.Panner(1); + */ + Tone.Panner = function (initialPan) { + Tone.AudioNode.call(this); + /** + * the panner node + * @type {StereoPannerNode} + * @private + */ + this._panner = this.input = this.output = this.context.createStereoPanner(); + /** + * The pan control. -1 = hard left, 1 = hard right. + * @type {AudioRange} + * @signal + */ + this.pan = this._panner.pan; + //initial value + this.pan.value = Tone.defaultArg(initialPan, 0); + this._readOnly('pan'); + }; + Tone.extend(Tone.Panner, Tone.AudioNode); + /** + * Clean up. + * @returns {Tone.Panner} this + */ + Tone.Panner.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._writable('pan'); + this._panner.disconnect(); + this._panner = null; + this.pan = null; + return this; + }; + return Tone.Panner; + }); + Module(function (Tone) { + + /** + * @class A spatialized panner node which supports equalpower or HRTF panning. + * Tries to normalize the API across various browsers. See Tone.Listener + * + * @constructor + * @extends {Tone.AudioNode} + * @param {Number} positionX The initial x position. + * @param {Number} positionY The initial y position. + * @param {Number} positionZ The initial z position. + */ + Tone.Panner3D = function () { + var options = Tone.defaults(arguments, [ + 'positionX', + 'positionY', + 'positionZ' + ], Tone.Panner3D); + Tone.AudioNode.call(this); + /** + * The panner node + * @type {PannerNode} + * @private + */ + this._panner = this.input = this.output = this.context.createPanner(); + //set some values + this._panner.panningModel = options.panningModel; + this._panner.maxDistance = options.maxDistance; + this._panner.distanceModel = options.distanceModel; + this._panner.coneOuterGain = options.coneOuterGain; + this._panner.coneOuterAngle = options.coneOuterAngle; + this._panner.coneInnerAngle = options.coneInnerAngle; + this._panner.refDistance = options.refDistance; + this._panner.rolloffFactor = options.rolloffFactor; + /** + * Holds the current orientation + * @type {Array} + * @private + */ + this._orientation = [ + options.orientationX, + options.orientationY, + options.orientationZ + ]; + /** + * Holds the current position + * @type {Array} + * @private + */ + this._position = [ + options.positionX, + options.positionY, + options.positionZ + ]; + // set the default position/orientation + this.orientationX = options.orientationX; + this.orientationY = options.orientationY; + this.orientationZ = options.orientationZ; + this.positionX = options.positionX; + this.positionY = options.positionY; + this.positionZ = options.positionZ; + }; + Tone.extend(Tone.Panner3D, Tone.AudioNode); + /** + * Defaults according to the specification + * @static + * @const + * @type {Object} + */ + Tone.Panner3D.defaults = { + 'positionX': 0, + 'positionY': 0, + 'positionZ': 0, + 'orientationX': 0, + 'orientationY': 0, + 'orientationZ': 0, + 'panningModel': 'equalpower', + 'maxDistance': 10000, + 'distanceModel': 'inverse', + 'coneOuterGain': 0, + 'coneOuterAngle': 360, + 'coneInnerAngle': 360, + 'refDistance': 1, + 'rolloffFactor': 1 + }; + /** + * The ramp time which is applied to the setTargetAtTime + * @type {Number} + * @private + */ + Tone.Panner3D.prototype._rampTimeConstant = 0.01; + /** + * Sets the position of the source in 3d space. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @return {Tone.Panner3D} this + */ + Tone.Panner3D.prototype.setPosition = function (x, y, z) { + if (this._panner.positionX) { + var now = this.now(); + this._panner.positionX.setTargetAtTime(x, now, this._rampTimeConstant); + this._panner.positionY.setTargetAtTime(y, now, this._rampTimeConstant); + this._panner.positionZ.setTargetAtTime(z, now, this._rampTimeConstant); + } else { + this._panner.setPosition(x, y, z); + } + this._position = Array.prototype.slice.call(arguments); + return this; + }; + /** + * Sets the orientation of the source in 3d space. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @return {Tone.Panner3D} this + */ + Tone.Panner3D.prototype.setOrientation = function (x, y, z) { + if (this._panner.orientationX) { + var now = this.now(); + this._panner.orientationX.setTargetAtTime(x, now, this._rampTimeConstant); + this._panner.orientationY.setTargetAtTime(y, now, this._rampTimeConstant); + this._panner.orientationZ.setTargetAtTime(z, now, this._rampTimeConstant); + } else { + this._panner.setOrientation(x, y, z); + } + this._orientation = Array.prototype.slice.call(arguments); + return this; + }; + /** + * The x position of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name positionX + */ + Object.defineProperty(Tone.Panner3D.prototype, 'positionX', { + set: function (pos) { + this._position[0] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[0]; + } + }); + /** + * The y position of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name positionY + */ + Object.defineProperty(Tone.Panner3D.prototype, 'positionY', { + set: function (pos) { + this._position[1] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[1]; + } + }); + /** + * The z position of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name positionZ + */ + Object.defineProperty(Tone.Panner3D.prototype, 'positionZ', { + set: function (pos) { + this._position[2] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[2]; + } + }); + /** + * The x orientation of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name orientationX + */ + Object.defineProperty(Tone.Panner3D.prototype, 'orientationX', { + set: function (pos) { + this._orientation[0] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[0]; + } + }); + /** + * The y orientation of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name orientationY + */ + Object.defineProperty(Tone.Panner3D.prototype, 'orientationY', { + set: function (pos) { + this._orientation[1] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[1]; + } + }); + /** + * The z orientation of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name orientationZ + */ + Object.defineProperty(Tone.Panner3D.prototype, 'orientationZ', { + set: function (pos) { + this._orientation[2] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[2]; + } + }); + /** + * Proxy a property on the panner to an exposed public propery + * @param {String} prop + * @private + */ + Tone.Panner3D._aliasProperty = function (prop) { + Object.defineProperty(Tone.Panner3D.prototype, prop, { + set: function (val) { + this._panner[prop] = val; + }, + get: function () { + return this._panner[prop]; + } + }); + }; + /** + * The panning model. Either "equalpower" or "HRTF". + * @type {String} + * @memberOf Tone.Panner3D# + * @name panningModel + */ + Tone.Panner3D._aliasProperty('panningModel'); + /** + * A reference distance for reducing volume as source move further from the listener + * @type {Number} + * @memberOf Tone.Panner3D# + * @name refDistance + */ + Tone.Panner3D._aliasProperty('refDistance'); + /** + * Describes how quickly the volume is reduced as source moves away from listener. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name rolloffFactor + */ + Tone.Panner3D._aliasProperty('rolloffFactor'); + /** + * The distance model used by, "linear", "inverse", or "exponential". + * @type {String} + * @memberOf Tone.Panner3D# + * @name distanceModel + */ + Tone.Panner3D._aliasProperty('distanceModel'); + /** + * The angle, in degrees, inside of which there will be no volume reduction + * @type {Degrees} + * @memberOf Tone.Panner3D# + * @name coneInnerAngle + */ + Tone.Panner3D._aliasProperty('coneInnerAngle'); + /** + * The angle, in degrees, outside of which the volume will be reduced + * to a constant value of coneOuterGain + * @type {Degrees} + * @memberOf Tone.Panner3D# + * @name coneOuterAngle + */ + Tone.Panner3D._aliasProperty('coneOuterAngle'); + /** + * The gain outside of the coneOuterAngle + * @type {Gain} + * @memberOf Tone.Panner3D# + * @name coneOuterGain + */ + Tone.Panner3D._aliasProperty('coneOuterGain'); + /** + * The maximum distance between source and listener, + * after which the volume will not be reduced any further. + * @type {Positive} + * @memberOf Tone.Panner3D# + * @name maxDistance + */ + Tone.Panner3D._aliasProperty('maxDistance'); + /** + * Clean up. + * @returns {Tone.Panner3D} this + */ + Tone.Panner3D.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._panner.disconnect(); + this._panner = null; + this._orientation = null; + this._position = null; + return this; + }; + return Tone.Panner3D; + }); + Module(function (Tone) { + + /** + * @class Tone.PanVol is a Tone.Panner and Tone.Volume in one. + * + * @extends {Tone.AudioNode} + * @constructor + * @param {AudioRange} pan the initial pan + * @param {number} volume The output volume. + * @example + * //pan the incoming signal left and drop the volume + * var panVol = new Tone.PanVol(-0.25, -12); + */ + Tone.PanVol = function () { + var options = Tone.defaults(arguments, [ + 'pan', + 'volume' + ], Tone.PanVol); + Tone.AudioNode.call(this); + /** + * The panning node + * @type {Tone.Panner} + * @private + */ + this._panner = this.input = new Tone.Panner(options.pan); + /** + * The L/R panning control. + * @type {AudioRange} + * @signal + */ + this.pan = this._panner.pan; + /** + * The volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume control in decibels. + * @type {Decibels} + * @signal + */ + this.volume = this._volume.volume; + //connections + this._panner.connect(this._volume); + this.mute = options.mute; + this._readOnly([ + 'pan', + 'volume' + ]); + }; + Tone.extend(Tone.PanVol, Tone.AudioNode); + /** + * The defaults + * @type {Object} + * @const + * @static + */ + Tone.PanVol.defaults = { + 'pan': 0, + 'volume': 0, + 'mute': false + }; + /** + * Mute/unmute the volume + * @memberOf Tone.PanVol# + * @name mute + * @type {Boolean} + */ + Object.defineProperty(Tone.PanVol.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + /** + * clean up + * @returns {Tone.PanVol} this + */ + Tone.PanVol.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._writable([ + 'pan', + 'volume' + ]); + this._panner.dispose(); + this._panner = null; + this.pan = null; + this._volume.dispose(); + this._volume = null; + this.volume = null; + return this; + }; + return Tone.PanVol; + }); + Module(function (Tone) { + /** + * @class Tone.Solo lets you isolate a specific audio stream. When + * an instance is set to `solo=true`, it will mute all other instances. + * @extends {Tone.AudioNode} + * @example + * var soloA = new Tone.Solo() + * var soloB = new Tone.Solo() + * soloA.solo = true + * //no audio will pass through soloB + */ + Tone.Solo = function () { + var options = Tone.defaults(arguments, ['solo'], Tone.Solo); + Tone.AudioNode.call(this); + /** + * The input and output node + * @type {Tone.Gain} + */ + this.input = this.output = new Tone.Gain(); + /** + * A bound _soloed method + * @type {Function} + * @private + */ + this._soloBind = this._soloed.bind(this); + //listen for solo events class-wide. + this.context.on('solo', this._soloBind); + //set initially + this.solo = options.solo; + }; + Tone.extend(Tone.Solo, Tone.AudioNode); + /** + * The defaults + * @type {Object} + * @static + */ + Tone.Solo.defaults = { solo: false }; + /** + * Isolates this instance and mutes all other instances of Tone.Solo. + * Only one instance can be soloed at a time. A soloed + * instance will report `solo=false` when another instance is soloed. + * @memberOf Tone.Solo# + * @type {Boolean} + * @name solo + */ + Object.defineProperty(Tone.Solo.prototype, 'solo', { + get: function () { + return this._isSoloed(); + }, + set: function (solo) { + if (solo) { + this._addSolo(); + } else { + this._removeSolo(); + } + this.context.emit('solo', this); + } + }); + /** + * If the current instance is muted, i.e. another instance is soloed + * @memberOf Tone.Solo# + * @type {Boolean} + * @name muted + * @readOnly + */ + Object.defineProperty(Tone.Solo.prototype, 'muted', { + get: function () { + return this.input.gain.value === 0; + } + }); + /** + * Add this to the soloed array + * @private + */ + Tone.Solo.prototype._addSolo = function () { + if (!Tone.isArray(this.context._currentSolo)) { + this.context._currentSolo = []; + } + if (!this._isSoloed()) { + this.context._currentSolo.push(this); + } + }; + /** + * Remove this from the soloed array + * @private + */ + Tone.Solo.prototype._removeSolo = function () { + if (this._isSoloed()) { + var index = this.context._currentSolo.indexOf(this); + this.context._currentSolo.splice(index, 1); + } + }; + /** + * @return {Boolean} Is this on the soloed array + * @private + */ + Tone.Solo.prototype._isSoloed = function () { + if (Tone.isArray(this.context._currentSolo)) { + return this.context._currentSolo.length !== 0 && this.context._currentSolo.indexOf(this) !== -1; + } else { + return false; + } + }; + /** + * @return {Boolean} Returns true if no one is soloed + * @private + */ + Tone.Solo.prototype._noSolos = function () { + return !Tone.isArray(this.context._currentSolo) || this.context._currentSolo.length === 0; + }; + /** + * Solo the current instance and unsolo all other instances. + * @param {Tone.Solo} instance The instance which is being soloed/unsoloed. + * @private + */ + Tone.Solo.prototype._soloed = function () { + if (this._isSoloed()) { + this.input.gain.value = 1; + } else if (this._noSolos()) { + //no one is soloed + this.input.gain.value = 1; + } else { + this.input.gain.value = 0; + } + }; + /** + * Clean up + * @return {Tone.Solo} this + */ + Tone.Solo.prototype.dispose = function () { + this.context.off('solo', this._soloBind); + this._removeSolo(); + this._soloBind = null; + Tone.AudioNode.prototype.dispose.call(this); + return this; + }; + return Tone.Solo; + }); + Module(function (Tone) { + /** + * @class Get the current waveform data of the connected audio source. + * @extends {Tone.AudioNode} + * @param {Number=} size The size of the FFT. Value must be a power of + * two in the range 32 to 32768. + */ + Tone.Waveform = function () { + var options = Tone.defaults(arguments, ['size'], Tone.Waveform); + options.type = Tone.Analyser.Type.Waveform; + Tone.AudioNode.call(this); + /** + * The analyser node. + * @private + * @type {Tone.Analyser} + */ + this._analyser = this.input = this.output = new Tone.Analyser(options); + }; + Tone.extend(Tone.Waveform, Tone.AudioNode); + /** + * The default values. + * @type {Object} + * @const + */ + Tone.Waveform.defaults = { 'size': 1024 }; + /** + * Gets the waveform of the audio source. Returns the waveform data + * of length [size](#size) as a Float32Array with values between -1 and 1. + * @returns {TypedArray} + */ + Tone.Waveform.prototype.getValue = function () { + return this._analyser.getValue(); + }; + /** + * The size of analysis. This must be a power of two in the range 32 to 32768. + * @memberOf Tone.Waveform# + * @type {Number} + * @name size + */ + Object.defineProperty(Tone.Waveform.prototype, 'size', { + get: function () { + return this._analyser.size; + }, + set: function (size) { + this._analyser.size = size; + } + }); + /** + * Clean up. + * @return {Tone.Waveform} this + */ + Tone.Waveform.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._analyser.dispose(); + this._analyser = null; + }; + return Tone.Waveform; + }); + Module(function (Tone) { + + /** + * @class Tone.CtrlInterpolate will interpolate between given values based + * on the "index" property. Passing in an array or object literal + * will interpolate each of the parameters. Note (i.e. "C3") + * and Time (i.e. "4n + 2") can be interpolated. All other values are + * assumed to be numbers. + * @example + * var interp = new Tone.CtrlInterpolate([0, 2, 9, 4]); + * interp.index = 0.75; + * interp.value; //returns 1.5 + * + * @example + * var interp = new Tone.CtrlInterpolate([ + * [2, 4, 5], + * [9, 3, 2], + * ]); + * @param {Array} values The array of values to interpolate over + * @param {Positive} index The initial interpolation index. + * @extends {Tone} + */ + Tone.CtrlInterpolate = function () { + var options = Tone.defaults(arguments, [ + 'values', + 'index' + ], Tone.CtrlInterpolate); + Tone.call(this); + /** + * The values to interpolate between + * @type {Array} + */ + this.values = options.values; + /** + * The interpolated index between values. For example: a value of 1.5 + * would interpolate equally between the value at index 1 + * and the value at index 2. + * @example + * interp.index = 0; + * interp.value; //returns the value at 0 + * interp.index = 0.5; + * interp.value; //returns the value between indices 0 and 1. + * @type {Positive} + */ + this.index = options.index; + }; + Tone.extend(Tone.CtrlInterpolate); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.CtrlInterpolate.defaults = { + 'index': 0, + 'values': [] + }; + /** + * The current interpolated value based on the index + * @readOnly + * @memberOf Tone.CtrlInterpolate# + * @type {*} + * @name value + */ + Object.defineProperty(Tone.CtrlInterpolate.prototype, 'value', { + get: function () { + var index = this.index; + index = Math.min(index, this.values.length - 1); + var lowerPosition = Math.floor(index); + var lower = this.values[lowerPosition]; + var upper = this.values[Math.ceil(index)]; + return this._interpolate(index - lowerPosition, lower, upper); + } + }); + /** + * Internal interpolation routine + * @param {NormalRange} index The index between the lower and upper + * @param {*} lower + * @param {*} upper + * @return {*} The interpolated value + * @private + */ + Tone.CtrlInterpolate.prototype._interpolate = function (index, lower, upper) { + if (Tone.isArray(lower)) { + var retArray = []; + for (var i = 0; i < lower.length; i++) { + retArray[i] = this._interpolate(index, lower[i], upper[i]); + } + return retArray; + } else if (Tone.isObject(lower)) { + var retObj = {}; + for (var attr in lower) { + retObj[attr] = this._interpolate(index, lower[attr], upper[attr]); + } + return retObj; + } else { + lower = this._toNumber(lower); + upper = this._toNumber(upper); + return (1 - index) * lower + index * upper; + } + }; + /** + * Convert from the given type into a number + * @param {Number|String} value + * @return {Number} + * @private + */ + Tone.CtrlInterpolate.prototype._toNumber = function (val) { + if (Tone.isNumber(val)) { + return val; + } else { + //otherwise assume that it's Time... + return this.toSeconds(val); + } + }; + /** + * Clean up + * @return {Tone.CtrlInterpolate} this + */ + Tone.CtrlInterpolate.prototype.dispose = function () { + this.values = null; + }; + return Tone.CtrlInterpolate; + }); + Module(function (Tone) { + + /** + * @class Tone.CtrlMarkov represents a Markov Chain where each call + * to Tone.CtrlMarkov.next will move to the next state. If the next + * state choice is an array, the next state is chosen randomly with + * even probability for all of the choices. For a weighted probability + * of the next choices, pass in an object with "state" and "probability" attributes. + * The probabilities will be normalized and then chosen. If no next options + * are given for the current state, the state will stay there. + * @extends {Tone} + * @example + * var chain = new Tone.CtrlMarkov({ + * "beginning" : ["end", "middle"], + * "middle" : "end" + * }); + * chain.value = "beginning"; + * chain.next(); //returns "end" or "middle" with 50% probability + * + * @example + * var chain = new Tone.CtrlMarkov({ + * "beginning" : [{"value" : "end", "probability" : 0.8}, + * {"value" : "middle", "probability" : 0.2}], + * "middle" : "end" + * }); + * chain.value = "beginning"; + * chain.next(); //returns "end" with 80% probability or "middle" with 20%. + * @param {Object} values An object with the state names as the keys + * and the next state(s) as the values. + */ + Tone.CtrlMarkov = function (values, initial) { + Tone.call(this); + /** + * The Markov values with states as the keys + * and next state(s) as the values. + * @type {Object} + */ + this.values = Tone.defaultArg(values, {}); + /** + * The current state of the Markov values. The next + * state will be evaluated and returned when Tone.CtrlMarkov.next + * is invoked. + * @type {String} + */ + this.value = Tone.defaultArg(initial, Object.keys(this.values)[0]); + }; + Tone.extend(Tone.CtrlMarkov); + /** + * Returns the next state of the Markov values. + * @return {String} + */ + Tone.CtrlMarkov.prototype.next = function () { + if (this.values.hasOwnProperty(this.value)) { + var next = this.values[this.value]; + if (Tone.isArray(next)) { + var distribution = this._getProbDistribution(next); + var rand = Math.random(); + var total = 0; + for (var i = 0; i < distribution.length; i++) { + var dist = distribution[i]; + if (rand > total && rand < total + dist) { + var chosen = next[i]; + if (Tone.isObject(chosen)) { + this.value = chosen.value; + } else { + this.value = chosen; + } + } + total += dist; + } + } else { + this.value = next; + } + } + return this.value; + }; + /** + * Choose randomly from an array weighted options in the form + * {"state" : string, "probability" : number} or an array of values + * @param {Array} options + * @return {Array} The randomly selected choice + * @private + */ + Tone.CtrlMarkov.prototype._getProbDistribution = function (options) { + var distribution = []; + var total = 0; + var needsNormalizing = false; + for (var i = 0; i < options.length; i++) { + var option = options[i]; + if (Tone.isObject(option)) { + needsNormalizing = true; + distribution[i] = option.probability; + } else { + distribution[i] = 1 / options.length; + } + total += distribution[i]; + } + if (needsNormalizing) { + //normalize the values + for (var j = 0; j < distribution.length; j++) { + distribution[j] = distribution[j] / total; + } + } + return distribution; + }; + /** + * Clean up + * @return {Tone.CtrlMarkov} this + */ + Tone.CtrlMarkov.prototype.dispose = function () { + this.values = null; + }; + return Tone.CtrlMarkov; + }); + Module(function (Tone) { + + /** + * @class Generate patterns from an array of values. + * Has a number of arpeggiation and randomized + * selection patterns. + * <ul> + * <li>"up" - cycles upward</li> + * <li>"down" - cycles downward</li> + * <li>"upDown" - up then and down</li> + * <li>"downUp" - cycles down then and up</li> + * <li>"alternateUp" - jump up two and down one</li> + * <li>"alternateDown" - jump down two and up one</li> + * <li>"random" - randomly select an index</li> + * <li>"randomWalk" - randomly moves one index away from the current position</li> + * <li>"randomOnce" - randomly select an index without repeating until all values have been chosen.</li> + * </ul> + * @param {Array} values An array of options to choose from. + * @param {Tone.CtrlPattern.Type=} type The name of the pattern. + * @extends {Tone} + */ + Tone.CtrlPattern = function () { + var options = Tone.defaults(arguments, [ + 'values', + 'type' + ], Tone.CtrlPattern); + Tone.call(this); + /** + * The array of values to arpeggiate over + * @type {Array} + */ + this.values = options.values; + /** + * The current position in the values array + * @type {Number} + */ + this.index = 0; + /** + * The type placeholder + * @type {Tone.CtrlPattern.Type} + * @private + */ + this._type = null; + /** + * Shuffled values for the RandomOnce type + * @type {Array} + * @private + */ + this._shuffled = null; + /** + * The direction of the movement + * @type {String} + * @private + */ + this._direction = null; + this.type = options.type; + }; + Tone.extend(Tone.CtrlPattern); + /** + * The Control Patterns + * @type {Object} + * @static + */ + Tone.CtrlPattern.Type = { + Up: 'up', + Down: 'down', + UpDown: 'upDown', + DownUp: 'downUp', + AlternateUp: 'alternateUp', + AlternateDown: 'alternateDown', + Random: 'random', + RandomWalk: 'randomWalk', + RandomOnce: 'randomOnce' + }; + /** + * The default values. + * @type {Object} + */ + Tone.CtrlPattern.defaults = { + 'type': Tone.CtrlPattern.Type.Up, + 'values': [] + }; + /** + * The value at the current index of the pattern. + * @readOnly + * @memberOf Tone.CtrlPattern# + * @type {*} + * @name value + */ + Object.defineProperty(Tone.CtrlPattern.prototype, 'value', { + get: function () { + //some safeguards + if (this.values.length === 0) { + return; + } else if (this.values.length === 1) { + return this.values[0]; + } + this.index = Math.min(this.index, this.values.length - 1); + var val = this.values[this.index]; + if (this.type === Tone.CtrlPattern.Type.RandomOnce) { + if (this.values.length !== this._shuffled.length) { + this._shuffleValues(); + } + val = this.values[this._shuffled[this.index]]; + } + return val; + } + }); + /** + * The pattern used to select the next + * item from the values array + * @memberOf Tone.CtrlPattern# + * @type {Tone.CtrlPattern.Type} + * @name type + */ + Object.defineProperty(Tone.CtrlPattern.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + this._type = type; + this._shuffled = null; + //the first index + if (this._type === Tone.CtrlPattern.Type.Up || this._type === Tone.CtrlPattern.Type.UpDown || this._type === Tone.CtrlPattern.Type.RandomOnce || this._type === Tone.CtrlPattern.Type.AlternateUp) { + this.index = 0; + } else if (this._type === Tone.CtrlPattern.Type.Down || this._type === Tone.CtrlPattern.Type.DownUp || this._type === Tone.CtrlPattern.Type.AlternateDown) { + this.index = this.values.length - 1; + } + //the direction + if (this._type === Tone.CtrlPattern.Type.UpDown || this._type === Tone.CtrlPattern.Type.AlternateUp) { + this._direction = Tone.CtrlPattern.Type.Up; + } else if (this._type === Tone.CtrlPattern.Type.DownUp || this._type === Tone.CtrlPattern.Type.AlternateDown) { + this._direction = Tone.CtrlPattern.Type.Down; + } + //randoms + if (this._type === Tone.CtrlPattern.Type.RandomOnce) { + this._shuffleValues(); + } else if (this._type === Tone.CtrlPattern.Random) { + this.index = Math.floor(Math.random() * this.values.length); + } + } + }); + /** + * Return the next value given the current position + * and pattern. + * @return {*} The next value + */ + Tone.CtrlPattern.prototype.next = function () { + var type = this.type; + //choose the next index + if (type === Tone.CtrlPattern.Type.Up) { + this.index++; + if (this.index >= this.values.length) { + this.index = 0; + } + } else if (type === Tone.CtrlPattern.Type.Down) { + this.index--; + if (this.index < 0) { + this.index = this.values.length - 1; + } + } else if (type === Tone.CtrlPattern.Type.UpDown || type === Tone.CtrlPattern.Type.DownUp) { + if (this._direction === Tone.CtrlPattern.Type.Up) { + this.index++; + } else { + this.index--; + } + if (this.index < 0) { + this.index = 1; + this._direction = Tone.CtrlPattern.Type.Up; + } else if (this.index >= this.values.length) { + this.index = this.values.length - 2; + this._direction = Tone.CtrlPattern.Type.Down; + } + } else if (type === Tone.CtrlPattern.Type.Random) { + this.index = Math.floor(Math.random() * this.values.length); + } else if (type === Tone.CtrlPattern.Type.RandomWalk) { + if (Math.random() < 0.5) { + this.index--; + this.index = Math.max(this.index, 0); + } else { + this.index++; + this.index = Math.min(this.index, this.values.length - 1); + } + } else if (type === Tone.CtrlPattern.Type.RandomOnce) { + this.index++; + if (this.index >= this.values.length) { + this.index = 0; + //reshuffle the values for next time + this._shuffleValues(); + } + } else if (type === Tone.CtrlPattern.Type.AlternateUp) { + if (this._direction === Tone.CtrlPattern.Type.Up) { + this.index += 2; + this._direction = Tone.CtrlPattern.Type.Down; + } else { + this.index -= 1; + this._direction = Tone.CtrlPattern.Type.Up; + } + if (this.index >= this.values.length) { + this.index = 0; + this._direction = Tone.CtrlPattern.Type.Up; + } + } else if (type === Tone.CtrlPattern.Type.AlternateDown) { + if (this._direction === Tone.CtrlPattern.Type.Up) { + this.index += 1; + this._direction = Tone.CtrlPattern.Type.Down; + } else { + this.index -= 2; + this._direction = Tone.CtrlPattern.Type.Up; + } + if (this.index < 0) { + this.index = this.values.length - 1; + this._direction = Tone.CtrlPattern.Type.Down; + } + } + return this.value; + }; + /** + * Shuffles the values and places the results into the _shuffled + * @private + */ + Tone.CtrlPattern.prototype._shuffleValues = function () { + var copy = []; + this._shuffled = []; + for (var i = 0; i < this.values.length; i++) { + copy[i] = i; + } + while (copy.length > 0) { + var randVal = copy.splice(Math.floor(copy.length * Math.random()), 1); + this._shuffled.push(randVal[0]); + } + }; + /** + * Clean up + * @returns {Tone.CtrlPattern} this + */ + Tone.CtrlPattern.prototype.dispose = function () { + this._shuffled = null; + this.values = null; + }; + return Tone.CtrlPattern; + }); + Module(function (Tone) { + + /** + * @class Choose a random value. + * @extends {Tone} + * @example + * var randomWalk = new Tone.CtrlRandom({ + * "min" : 0, + * "max" : 10, + * "integer" : true + * }); + * randomWalk.eval(); + * + * @param {Number|Time=} min The minimum return value. + * @param {Number|Time=} max The maximum return value. + */ + Tone.CtrlRandom = function () { + var options = Tone.defaults(arguments, [ + 'min', + 'max' + ], Tone.CtrlRandom); + Tone.call(this); + /** + * The minimum return value + * @type {Number|Time} + */ + this.min = options.min; + /** + * The maximum return value + * @type {Number|Time} + */ + this.max = options.max; + /** + * If the return value should be an integer + * @type {Boolean} + */ + this.integer = options.integer; + }; + Tone.extend(Tone.CtrlRandom); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.CtrlRandom.defaults = { + 'min': 0, + 'max': 1, + 'integer': false + }; + /** + * Return a random value between min and max. + * @readOnly + * @memberOf Tone.CtrlRandom# + * @type {*} + * @name value + */ + Object.defineProperty(Tone.CtrlRandom.prototype, 'value', { + get: function () { + var min = this.toSeconds(this.min); + var max = this.toSeconds(this.max); + var rand = Math.random(); + var val = rand * min + (1 - rand) * max; + if (this.integer) { + val = Math.floor(val); + } + return val; + } + }); + return Tone.CtrlRandom; + }); + Module(function (Tone) { + /** + * @class A data structure for holding multiple buffers. + * + * @param {Object|Array} urls An object literal or array + * of urls to load. + * @param {Function=} callback The callback to invoke when + * the buffers are loaded. + * @extends {Tone} + * @example + * //load a whole bank of piano samples + * var pianoSamples = new Tone.Buffers({ + * "C4" : "path/to/C4.mp3" + * "C#4" : "path/to/C#4.mp3" + * "D4" : "path/to/D4.mp3" + * "D#4" : "path/to/D#4.mp3" + * ... + * }, function(){ + * //play one of the samples when they all load + * player.buffer = pianoSamples.get("C4"); + * player.start(); + * }); + * @example + * //To pass in additional parameters in the second parameter + * var buffers = new Tone.Buffers(urls, { + * "onload" : callback, + * "baseUrl" : "../path/to/audio/" + * }) + */ + Tone.Buffers = function (urls) { + //remove the urls from the options + var args = Array.prototype.slice.call(arguments); + args.shift(); + var options = Tone.defaults(args, [ + 'onload', + 'baseUrl' + ], Tone.Buffers); + Tone.call(this); + /** + * All of the buffers + * @type {Object} + * @private + */ + this._buffers = {}; + /** + * A path which is prefixed before every url. + * @type {String} + */ + this.baseUrl = options.baseUrl; + this._loadingCount = 0; + //add each one + for (var key in urls) { + this._loadingCount++; + this.add(key, urls[key], this._bufferLoaded.bind(this, options.onload)); + } + }; + Tone.extend(Tone.Buffers); + /** + * Defaults + * @type {Object} + */ + Tone.Buffers.defaults = { + 'onload': Tone.noOp, + 'baseUrl': '' + }; + /** + * True if the buffers object has a buffer by that name. + * @param {String|Number} name The key or index of the + * buffer. + * @return {Boolean} + */ + Tone.Buffers.prototype.has = function (name) { + return this._buffers.hasOwnProperty(name); + }; + /** + * Get a buffer by name. If an array was loaded, + * then use the array index. + * @param {String|Number} name The key or index of the + * buffer. + * @return {Tone.Buffer} + */ + Tone.Buffers.prototype.get = function (name) { + if (this.has(name)) { + return this._buffers[name]; + } else { + throw new Error('Tone.Buffers: no buffer named ' + name); + } + }; + /** + * A buffer was loaded. decrement the counter. + * @param {Function} callback + * @private + */ + Tone.Buffers.prototype._bufferLoaded = function (callback) { + this._loadingCount--; + if (this._loadingCount === 0 && callback) { + callback(this); + } + }; + /** + * If the buffers are loaded or not + * @memberOf Tone.Buffers# + * @type {Boolean} + * @name loaded + * @readOnly + */ + Object.defineProperty(Tone.Buffers.prototype, 'loaded', { + get: function () { + var isLoaded = true; + for (var buffName in this._buffers) { + var buff = this.get(buffName); + isLoaded = isLoaded && buff.loaded; + } + return isLoaded; + } + }); + /** + * Add a buffer by name and url to the Buffers + * @param {String} name A unique name to give + * the buffer + * @param {String|Tone.Buffer|Audiobuffer} url Either the url of the bufer, + * or a buffer which will be added + * with the given name. + * @param {Function=} callback The callback to invoke + * when the url is loaded. + */ + Tone.Buffers.prototype.add = function (name, url, callback) { + callback = Tone.defaultArg(callback, Tone.noOp); + if (url instanceof Tone.Buffer) { + this._buffers[name] = url; + callback(this); + } else if (url instanceof AudioBuffer) { + this._buffers[name] = new Tone.Buffer(url); + callback(this); + } else if (Tone.isString(url)) { + this._buffers[name] = new Tone.Buffer(this.baseUrl + url, callback); + } + return this; + }; + /** + * Clean up. + * @return {Tone.Buffers} this + */ + Tone.Buffers.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + for (var name in this._buffers) { + this._buffers[name].dispose(); + } + this._buffers = null; + return this; + }; + return Tone.Buffers; + }); + Module(function (Tone) { + + /** + * buses are another way of routing audio + * + * augments Tone.prototype to include send and recieve + */ + /** + * All of the routes + * + * @type {Object} + * @static + * @private + */ + var Buses = {}; + /** + * Send this signal to the channel name. + * @param {String} channelName A named channel to send the signal to. + * @param {Decibels} amount The amount of the source to send to the bus. + * @return {GainNode} The gain node which connects this node to the desired channel. + * Can be used to adjust the levels of the send. + * @example + * source.send("reverb", -12); + */ + Tone.prototype.send = function (channelName, amount) { + if (!Buses.hasOwnProperty(channelName)) { + Buses[channelName] = this.context.createGain(); + } + amount = Tone.defaultArg(amount, 0); + var sendKnob = new Tone.Gain(amount, Tone.Type.Decibels); + this.connect(sendKnob); + sendKnob.connect(Buses[channelName]); + return sendKnob; + }; + /** + * Recieve the input from the desired channelName to the input + * + * @param {String} channelName A named channel to send the signal to. + * @param {Number=} channelNumber The channel to connect to + * @returns {Tone} this + * @example + * reverbEffect.receive("reverb"); + */ + Tone.prototype.receive = function (channelName, inputNum) { + if (!Buses.hasOwnProperty(channelName)) { + Buses[channelName] = this.context.createGain(); + } + Buses[channelName].connect(this, 0, inputNum); + return this; + }; + //remove all the send/receives when a new audio context is passed in + Tone.Context.on('init', function (context) { + if (context.Buses) { + Buses = context.Buses; + } else { + Buses = {}; + context.Buses = Buses; + } + }); + return Tone; + }); + Module(function (Tone) { + + /** + * @class Tone.Draw is useful for synchronizing visuals and audio events. + * Callbacks from Tone.Transport or any of the Tone.Event classes + * always happen _before_ the scheduled time and are not synchronized + * to the animation frame so they are not good for triggering tightly + * synchronized visuals and sound. Tone.Draw makes it easy to schedule + * callbacks using the AudioContext time and uses requestAnimationFrame. + * + * @singleton + * @extends {Tone} + * @example + * Tone.Transport.schedule(function(time){ + * //use the time argument to schedule a callback with Tone.Draw + * Tone.Draw.schedule(function(){ + * //do drawing or DOM manipulation here + * }, time) + * }, "+0.5") + */ + Tone.Draw = function () { + Tone.call(this); + /** + * All of the events. + * @type {Tone.Timeline} + * @private + */ + this._events = new Tone.Timeline(); + /** + * The duration after which events are not invoked. + * @type {Number} + * @default 0.25 + */ + this.expiration = 0.25; + /** + * The amount of time before the scheduled time + * that the callback can be invoked. Default is + * half the time of an animation frame (0.008 seconds). + * @type {Number} + * @default 0.008 + */ + this.anticipation = 0.008; + /** + * The draw loop + * @type {Function} + * @private + */ + this._boundDrawLoop = this._drawLoop.bind(this); + }; + Tone.extend(Tone.Draw); + /** + * Schedule a function at the given time to be invoked + * on the nearest animation frame. + * @param {Function} callback Callback is invoked at the given time. + * @param {Time} time The time relative to the AudioContext time + * to invoke the callback. + * @return {Tone.Draw} this + */ + Tone.Draw.prototype.schedule = function (callback, time) { + this._events.add({ + callback: callback, + time: this.toSeconds(time) + }); + //start the draw loop on the first event + if (this._events.length === 1) { + requestAnimationFrame(this._boundDrawLoop); + } + return this; + }; + /** + * Cancel events scheduled after the given time + * @param {Time=} after Time after which scheduled events will + * be removed from the scheduling timeline. + * @return {Tone.Draw} this + */ + Tone.Draw.prototype.cancel = function (after) { + this._events.cancel(this.toSeconds(after)); + return this; + }; + /** + * The draw loop + * @private + */ + Tone.Draw.prototype._drawLoop = function () { + var now = Tone.now(); + while (this._events.length && this._events.peek().time - this.anticipation <= now) { + var event = this._events.shift(); + if (now - event.time <= this.expiration) { + event.callback(); + } + } + if (this._events.length > 0) { + requestAnimationFrame(this._boundDrawLoop); + } + }; + //make a singleton + Tone.Draw = new Tone.Draw(); + return Tone.Draw; + }); + Module(function (Tone) { + + /** + * @class Both Tone.Panner3D and Tone.Listener have a position in 3D space + * using a right-handed cartesian coordinate system. + * The units used in the coordinate system are not defined; + * these coordinates are independent/invariant of any particular + * units such as meters or feet. Tone.Panner3D objects have an forward + * vector representing the direction the sound is projecting. Additionally, + * they have a sound cone representing how directional the sound is. + * For example, the sound could be omnidirectional, in which case it would + * be heard anywhere regardless of its forward, or it can be more directional + * and heard only if it is facing the listener. Tone.Listener objects + * (representing a person's ears) have an forward and up vector + * representing in which direction the person is facing. Because both the + * source stream and the listener can be moving, they both have a velocity + * vector representing both the speed and direction of movement. Taken together, + * these two velocities can be used to generate a doppler shift effect which changes the pitch. + * <br><br> + * Note: the position of the Listener will have no effect on nodes not connected to a Tone.Panner3D + * + * @constructor + * @extends {Tone} + * @singleton + */ + Tone.Listener = function () { + Tone.call(this); + /** + * Holds the current forward orientation + * @type {Array} + * @private + */ + this._orientation = [ + 0, + 0, + 0, + 0, + 0, + 0 + ]; + /** + * Holds the current position + * @type {Array} + * @private + */ + this._position = [ + 0, + 0, + 0 + ]; + Tone.getContext(function () { + // set the default position/forward + this.set(ListenerConstructor.defaults); + }.bind(this)); + }; + Tone.extend(Tone.Listener); + /** + * Defaults according to the specification + * @static + * @const + * @type {Object} + */ + Tone.Listener.defaults = { + 'positionX': 0, + 'positionY': 0, + 'positionZ': 0, + 'forwardX': 0, + 'forwardY': 0, + 'forwardZ': 1, + 'upX': 0, + 'upY': 1, + 'upZ': 0 + }; + /** + * The ramp time which is applied to the setTargetAtTime + * @type {Number} + * @private + */ + Tone.Listener.prototype._rampTimeConstant = 0.01; + /** + * Sets the position of the listener in 3d space. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @return {Tone.Listener} this + */ + Tone.Listener.prototype.setPosition = function (x, y, z) { + if (this.context.listener.positionX) { + var now = this.now(); + this.context.listener.positionX.setTargetAtTime(x, now, this._rampTimeConstant); + this.context.listener.positionY.setTargetAtTime(y, now, this._rampTimeConstant); + this.context.listener.positionZ.setTargetAtTime(z, now, this._rampTimeConstant); + } else { + this.context.listener.setPosition(x, y, z); + } + this._position = Array.prototype.slice.call(arguments); + return this; + }; + /** + * Sets the orientation of the listener using two vectors, the forward + * vector (which direction the listener is facing) and the up vector + * (which the up direction of the listener). An up vector + * of 0, 0, 1 is equivalent to the listener standing up in the Z direction. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @param {Number} upX + * @param {Number} upY + * @param {Number} upZ + * @return {Tone.Listener} this + */ + Tone.Listener.prototype.setOrientation = function (x, y, z, upX, upY, upZ) { + if (this.context.listener.forwardX) { + var now = this.now(); + this.context.listener.forwardX.setTargetAtTime(x, now, this._rampTimeConstant); + this.context.listener.forwardY.setTargetAtTime(y, now, this._rampTimeConstant); + this.context.listener.forwardZ.setTargetAtTime(z, now, this._rampTimeConstant); + this.context.listener.upX.setTargetAtTime(upX, now, this._rampTimeConstant); + this.context.listener.upY.setTargetAtTime(upY, now, this._rampTimeConstant); + this.context.listener.upZ.setTargetAtTime(upZ, now, this._rampTimeConstant); + } else { + this.context.listener.setOrientation(x, y, z, upX, upY, upZ); + } + this._orientation = Array.prototype.slice.call(arguments); + return this; + }; + /** + * The x position of the panner object. + * @type {Number} + * @memberOf Tone.Listener# + * @name positionX + */ + Object.defineProperty(Tone.Listener.prototype, 'positionX', { + set: function (pos) { + this._position[0] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[0]; + } + }); + /** + * The y position of the panner object. + * @type {Number} + * @memberOf Tone.Listener# + * @name positionY + */ + Object.defineProperty(Tone.Listener.prototype, 'positionY', { + set: function (pos) { + this._position[1] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[1]; + } + }); + /** + * The z position of the panner object. + * @type {Number} + * @memberOf Tone.Listener# + * @name positionZ + */ + Object.defineProperty(Tone.Listener.prototype, 'positionZ', { + set: function (pos) { + this._position[2] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[2]; + } + }); + /** + * The x coordinate of the listeners front direction. i.e. + * which way they are facing. + * @type {Number} + * @memberOf Tone.Listener# + * @name forwardX + */ + Object.defineProperty(Tone.Listener.prototype, 'forwardX', { + set: function (pos) { + this._orientation[0] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[0]; + } + }); + /** + * The y coordinate of the listeners front direction. i.e. + * which way they are facing. + * @type {Number} + * @memberOf Tone.Listener# + * @name forwardY + */ + Object.defineProperty(Tone.Listener.prototype, 'forwardY', { + set: function (pos) { + this._orientation[1] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[1]; + } + }); + /** + * The z coordinate of the listeners front direction. i.e. + * which way they are facing. + * @type {Number} + * @memberOf Tone.Listener# + * @name forwardZ + */ + Object.defineProperty(Tone.Listener.prototype, 'forwardZ', { + set: function (pos) { + this._orientation[2] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[2]; + } + }); + /** + * The x coordinate of the listener's up direction. i.e. + * the direction the listener is standing in. + * @type {Number} + * @memberOf Tone.Listener# + * @name upX + */ + Object.defineProperty(Tone.Listener.prototype, 'upX', { + set: function (pos) { + this._orientation[3] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[3]; + } + }); + /** + * The y coordinate of the listener's up direction. i.e. + * the direction the listener is standing in. + * @type {Number} + * @memberOf Tone.Listener# + * @name upY + */ + Object.defineProperty(Tone.Listener.prototype, 'upY', { + set: function (pos) { + this._orientation[4] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[4]; + } + }); + /** + * The z coordinate of the listener's up direction. i.e. + * the direction the listener is standing in. + * @type {Number} + * @memberOf Tone.Listener# + * @name upZ + */ + Object.defineProperty(Tone.Listener.prototype, 'upZ', { + set: function (pos) { + this._orientation[5] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[5]; + } + }); + /** + * Clean up. + * @returns {Tone.Listener} this + */ + Tone.Listener.prototype.dispose = function () { + this._orientation = null; + this._position = null; + return this; + }; + //SINGLETON SETUP + var ListenerConstructor = Tone.Listener; + Tone.Listener = new ListenerConstructor(); + Tone.Context.on('init', function (context) { + if (context.Listener instanceof ListenerConstructor) { + //a single listener object + Tone.Listener = context.Listener; + } else { + //make new Listener insides + Tone.Listener = new ListenerConstructor(); + } + context.Listener = Tone.Listener; + }); + //END SINGLETON SETUP + return Tone.Listener; + }); + Module(function (Tone) { + /** + * Because of a bug in iOS causing the currentTime to increment + * before the rendering is started, sometimes it takes multiple + * attempts to render the audio correctly. + * @private + */ + function attemptRender(callback, duration, sampleRate, tries) { + tries = Tone.defaultArg(tries, 0); + var context = new Tone.OfflineContext(2, duration, sampleRate); + Tone.context = context; + //invoke the callback/scheduling + var response = callback(Tone.Transport); + if (context.currentTime > 0 && tries < 1000) { + return attemptRender(callback, duration, sampleRate, ++tries); + } else { + return { + 'response': response, + 'context': context + }; + } + } + /** + * Generate a buffer by rendering all of the Tone.js code within the callback using the OfflineAudioContext. + * The OfflineAudioContext is capable of rendering much faster than real time in many cases. + * The callback function also passes in an offline instance of Tone.Transport which can be used + * to schedule events along the Transport. **NOTE** OfflineAudioContext has the same restrictions + * as the AudioContext in that on certain platforms (like iOS) it must be invoked by an explicit + * user action like a click or tap. + * @param {Function} callback All Tone.js nodes which are created and scheduled within this callback are recorded into the output Buffer. + * @param {Time} duration the amount of time to record for. + * @return {Promise} The promise which is invoked with the Tone.Buffer of the recorded output. + * @example + * //render 2 seconds of the oscillator + * Tone.Offline(function(){ + * //only nodes created in this callback will be recorded + * var oscillator = new Tone.Oscillator().toMaster().start(0) + * //schedule their events + * }, 2).then(function(buffer){ + * //do something with the output buffer + * }) + * @example + * //can also schedule events along the Transport + * //using the passed in Offline Transport + * Tone.Offline(function(Transport){ + * var osc = new Tone.Oscillator().toMaster() + * Transport.schedule(function(time){ + * osc.start(time).stop(time + 0.1) + * }, 1) + * Transport.start(0.2) + * }, 4).then(function(buffer){ + * //do something with the output buffer + * }) + */ + Tone.Offline = function (callback, duration) { + //set the OfflineAudioContext + var sampleRate = Tone.context.sampleRate; + var originalContext = Tone.context; + var renderRet = attemptRender(callback, duration, sampleRate); + var response = renderRet.response; + var context = renderRet.context; + var ret; + if (response instanceof Promise) { + //wait for the promise to resolve + ret = response.then(function () { + //then render the audio + return context.render(); + }); + } else { + //process the audio + ret = context.render(); + } + //return the original AudioContext + Tone.context = originalContext; + //return the audio + return ret.then(function (buffer) { + //wrap it in a Tone.Buffer + return new Tone.Buffer(buffer); + }); + }; + return Tone.Offline; + }); + Module(function (Tone) { + + /** + * @class Tone.Effect is the base class for effects. Connect the effect between + * the effectSend and effectReturn GainNodes, then control the amount of + * effect which goes to the output using the wet control. + * + * @constructor + * @extends {Tone.AudioNode} + * @param {NormalRange|Object} [wet] The starting wet value. + */ + Tone.Effect = function () { + var options = Tone.defaults(arguments, ['wet'], Tone.Effect); + Tone.AudioNode.call(this); + this.createInsOuts(1, 1); + /** + * the drywet knob to control the amount of effect + * @type {Tone.CrossFade} + * @private + */ + this._dryWet = new Tone.CrossFade(options.wet); + /** + * The wet control is how much of the effected + * will pass through to the output. 1 = 100% effected + * signal, 0 = 100% dry signal. + * @type {NormalRange} + * @signal + */ + this.wet = this._dryWet.fade; + /** + * connect the effectSend to the input of hte effect + * @type {Tone.Gain} + * @private + */ + this.effectSend = new Tone.Gain(); + /** + * connect the output of the effect to the effectReturn + * @type {Tone.Gain} + * @private + */ + this.effectReturn = new Tone.Gain(); + //connections + this.input.connect(this._dryWet.a); + this.input.connect(this.effectSend); + this.effectReturn.connect(this._dryWet.b); + this._dryWet.connect(this.output); + this._readOnly(['wet']); + }; + Tone.extend(Tone.Effect, Tone.AudioNode); + /** + * @static + * @type {Object} + */ + Tone.Effect.defaults = { 'wet': 1 }; + /** + * chains the effect in between the effectSend and effectReturn + * @param {Tone} effect + * @private + * @returns {Tone.Effect} this + */ + Tone.Effect.prototype.connectEffect = function (effect) { + this.effectSend.chain(effect, this.effectReturn); + return this; + }; + /** + * Clean up. + * @returns {Tone.Effect} this + */ + Tone.Effect.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._dryWet.dispose(); + this._dryWet = null; + this.effectSend.dispose(); + this.effectSend = null; + this.effectReturn.dispose(); + this.effectReturn = null; + this._writable(['wet']); + this.wet = null; + return this; + }; + return Tone.Effect; + }); + Module(function (Tone) { + + /** + * @class Tone.AutoFilter is a Tone.Filter with a Tone.LFO connected to the filter cutoff frequency. + * Setting the LFO rate and depth allows for control over the filter modulation rate + * and depth. + * + * @constructor + * @extends {Tone.Effect} + * @param {Time|Object} [frequency] The rate of the LFO. + * @param {Frequency=} baseFrequency The lower value of the LFOs oscillation + * @param {Frequency=} octaves The number of octaves above the baseFrequency + * @example + * //create an autofilter and start it's LFO + * var autoFilter = new Tone.AutoFilter("4n").toMaster().start(); + * //route an oscillator through the filter and start it + * var oscillator = new Tone.Oscillator().connect(autoFilter).start(); + */ + Tone.AutoFilter = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'baseFrequency', + 'octaves' + ], Tone.AutoFilter); + Tone.Effect.call(this, options); + /** + * the lfo which drives the filter cutoff + * @type {Tone.LFO} + * @private + */ + this._lfo = new Tone.LFO({ + 'frequency': options.frequency, + 'amplitude': options.depth + }); + /** + * The range of the filter modulating between the min and max frequency. + * 0 = no modulation. 1 = full modulation. + * @type {NormalRange} + * @signal + */ + this.depth = this._lfo.amplitude; + /** + * How fast the filter modulates between min and max. + * @type {Frequency} + * @signal + */ + this.frequency = this._lfo.frequency; + /** + * The filter node + * @type {Tone.Filter} + */ + this.filter = new Tone.Filter(options.filter); + /** + * The octaves placeholder + * @type {Positive} + * @private + */ + this._octaves = 0; + //connections + this.connectEffect(this.filter); + this._lfo.connect(this.filter.frequency); + this.type = options.type; + this._readOnly([ + 'frequency', + 'depth' + ]); + this.octaves = options.octaves; + this.baseFrequency = options.baseFrequency; + }; + //extend Effect + Tone.extend(Tone.AutoFilter, Tone.Effect); + /** + * defaults + * @static + * @type {Object} + */ + Tone.AutoFilter.defaults = { + 'frequency': 1, + 'type': 'sine', + 'depth': 1, + 'baseFrequency': 200, + 'octaves': 2.6, + 'filter': { + 'type': 'lowpass', + 'rolloff': -12, + 'Q': 1 + } + }; + /** + * Start the effect. + * @param {Time} [time=now] When the LFO will start. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.start = function (time) { + this._lfo.start(time); + return this; + }; + /** + * Stop the effect. + * @param {Time} [time=now] When the LFO will stop. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.stop = function (time) { + this._lfo.stop(time); + return this; + }; + /** + * Sync the filter to the transport. + * @param {Time} [delay=0] Delay time before starting the effect after the + * Transport has started. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.sync = function (delay) { + this._lfo.sync(delay); + return this; + }; + /** + * Unsync the filter from the transport. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.unsync = function () { + this._lfo.unsync(); + return this; + }; + /** + * Type of oscillator attached to the AutoFilter. + * Possible values: "sine", "square", "triangle", "sawtooth". + * @memberOf Tone.AutoFilter# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.AutoFilter.prototype, 'type', { + get: function () { + return this._lfo.type; + }, + set: function (type) { + this._lfo.type = type; + } + }); + /** + * The minimum value of the filter's cutoff frequency. + * @memberOf Tone.AutoFilter# + * @type {Frequency} + * @name min + */ + Object.defineProperty(Tone.AutoFilter.prototype, 'baseFrequency', { + get: function () { + return this._lfo.min; + }, + set: function (freq) { + this._lfo.min = this.toFrequency(freq); + //and set the max + this.octaves = this._octaves; + } + }); + /** + * The maximum value of the filter's cutoff frequency. + * @memberOf Tone.AutoFilter# + * @type {Positive} + * @name octaves + */ + Object.defineProperty(Tone.AutoFilter.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (oct) { + this._octaves = oct; + this._lfo.max = this.baseFrequency * Math.pow(2, oct); + } + }); + /** + * Clean up. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._lfo.dispose(); + this._lfo = null; + this.filter.dispose(); + this.filter = null; + this._writable([ + 'frequency', + 'depth' + ]); + this.frequency = null; + this.depth = null; + return this; + }; + return Tone.AutoFilter; + }); + Module(function (Tone) { + + /** + * @class Tone.AutoPanner is a Tone.Panner with an LFO connected to the pan amount. + * More on using autopanners [here](https://www.ableton.com/en/blog/autopan-chopper-effect-and-more-liveschool/). + * + * @constructor + * @extends {Tone.Effect} + * @param {Frequency|Object} [frequency] Rate of left-right oscillation. + * @example + * //create an autopanner and start it's LFO + * var autoPanner = new Tone.AutoPanner("4n").toMaster().start(); + * //route an oscillator through the panner and start it + * var oscillator = new Tone.Oscillator().connect(autoPanner).start(); + */ + Tone.AutoPanner = function () { + var options = Tone.defaults(arguments, ['frequency'], Tone.AutoPanner); + Tone.Effect.call(this, options); + /** + * the lfo which drives the panning + * @type {Tone.LFO} + * @private + */ + this._lfo = new Tone.LFO({ + 'frequency': options.frequency, + 'amplitude': options.depth, + 'min': -1, + 'max': 1 + }); + /** + * The amount of panning between left and right. + * 0 = always center. 1 = full range between left and right. + * @type {NormalRange} + * @signal + */ + this.depth = this._lfo.amplitude; + /** + * the panner node which does the panning + * @type {Tone.Panner} + * @private + */ + this._panner = new Tone.Panner(); + /** + * How fast the panner modulates between left and right. + * @type {Frequency} + * @signal + */ + this.frequency = this._lfo.frequency; + //connections + this.connectEffect(this._panner); + this._lfo.connect(this._panner.pan); + this.type = options.type; + this._readOnly([ + 'depth', + 'frequency' + ]); + }; + //extend Effect + Tone.extend(Tone.AutoPanner, Tone.Effect); + /** + * defaults + * @static + * @type {Object} + */ + Tone.AutoPanner.defaults = { + 'frequency': 1, + 'type': 'sine', + 'depth': 1 + }; + /** + * Start the effect. + * @param {Time} [time=now] When the LFO will start. + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.start = function (time) { + this._lfo.start(time); + return this; + }; + /** + * Stop the effect. + * @param {Time} [time=now] When the LFO will stop. + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.stop = function (time) { + this._lfo.stop(time); + return this; + }; + /** + * Sync the panner to the transport. + * @param {Time} [delay=0] Delay time before starting the effect after the + * Transport has started. + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.sync = function (delay) { + this._lfo.sync(delay); + return this; + }; + /** + * Unsync the panner from the transport + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.unsync = function () { + this._lfo.unsync(); + return this; + }; + /** + * Type of oscillator attached to the AutoFilter. + * Possible values: "sine", "square", "triangle", "sawtooth". + * @memberOf Tone.AutoFilter# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.AutoPanner.prototype, 'type', { + get: function () { + return this._lfo.type; + }, + set: function (type) { + this._lfo.type = type; + } + }); + /** + * clean up + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._lfo.dispose(); + this._lfo = null; + this._panner.dispose(); + this._panner = null; + this._writable([ + 'depth', + 'frequency' + ]); + this.frequency = null; + this.depth = null; + return this; + }; + return Tone.AutoPanner; + }); + Module(function (Tone) { + + /** + * @class Tone.AutoWah connects a Tone.Follower to a bandpass filter (Tone.Filter). + * The frequency of the filter is adjusted proportionally to the + * incoming signal's amplitude. Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna). + * + * @constructor + * @extends {Tone.Effect} + * @param {Frequency|Object} [baseFrequency] The frequency the filter is set + * to at the low point of the wah + * @param {Positive} [octaves] The number of octaves above the baseFrequency + * the filter will sweep to when fully open + * @param {Decibels} [sensitivity] The decibel threshold sensitivity for + * the incoming signal. Normal range of -40 to 0. + * @example + * var autoWah = new Tone.AutoWah(50, 6, -30).toMaster(); + * //initialize the synth and connect to autowah + * var synth = new Synth.connect(autoWah); + * //Q value influences the effect of the wah - default is 2 + * autoWah.Q.value = 6; + * //more audible on higher notes + * synth.triggerAttackRelease("C4", "8n") + */ + Tone.AutoWah = function () { + var options = Tone.defaults(arguments, [ + 'baseFrequency', + 'octaves', + 'sensitivity' + ], Tone.AutoWah); + Tone.Effect.call(this, options); + /** + * The envelope follower. Set the attack/release + * timing to adjust how the envelope is followed. + * @type {Tone.Follower} + * @private + */ + this.follower = new Tone.Follower(options.follower); + /** + * scales the follower value to the frequency domain + * @type {Tone} + * @private + */ + this._sweepRange = new Tone.ScaleExp(0, 1, 0.5); + /** + * @type {number} + * @private + */ + this._baseFrequency = options.baseFrequency; + /** + * @type {number} + * @private + */ + this._octaves = options.octaves; + /** + * the input gain to adjust the sensitivity + * @type {Tone.Gain} + * @private + */ + this._inputBoost = new Tone.Gain(); + /** + * @type {BiquadFilterNode} + * @private + */ + this._bandpass = new Tone.Filter({ + 'rolloff': -48, + 'frequency': 0, + 'Q': options.Q + }); + /** + * @type {Tone.Filter} + * @private + */ + this._peaking = new Tone.Filter(0, 'peaking'); + this._peaking.gain.value = options.gain; + /** + * The gain of the filter. + * @type {Number} + * @signal + */ + this.gain = this._peaking.gain; + /** + * The quality of the filter. + * @type {Positive} + * @signal + */ + this.Q = this._bandpass.Q; + //the control signal path + this.effectSend.chain(this._inputBoost, this.follower, this._sweepRange); + this._sweepRange.connect(this._bandpass.frequency); + this._sweepRange.connect(this._peaking.frequency); + //the filtered path + this.effectSend.chain(this._bandpass, this._peaking, this.effectReturn); + //set the initial value + this._setSweepRange(); + this.sensitivity = options.sensitivity; + this._readOnly([ + 'gain', + 'Q' + ]); + }; + Tone.extend(Tone.AutoWah, Tone.Effect); + /** + * @static + * @type {Object} + */ + Tone.AutoWah.defaults = { + 'baseFrequency': 100, + 'octaves': 6, + 'sensitivity': 0, + 'Q': 2, + 'gain': 2, + 'follower': { + 'attack': 0.3, + 'release': 0.5 + } + }; + /** + * The number of octaves that the filter will sweep above the + * baseFrequency. + * @memberOf Tone.AutoWah# + * @type {Number} + * @name octaves + */ + Object.defineProperty(Tone.AutoWah.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (octaves) { + this._octaves = octaves; + this._setSweepRange(); + } + }); + /** + * The base frequency from which the sweep will start from. + * @memberOf Tone.AutoWah# + * @type {Frequency} + * @name baseFrequency + */ + Object.defineProperty(Tone.AutoWah.prototype, 'baseFrequency', { + get: function () { + return this._baseFrequency; + }, + set: function (baseFreq) { + this._baseFrequency = baseFreq; + this._setSweepRange(); + } + }); + /** + * The sensitivity to control how responsive to the input signal the filter is. + * @memberOf Tone.AutoWah# + * @type {Decibels} + * @name sensitivity + */ + Object.defineProperty(Tone.AutoWah.prototype, 'sensitivity', { + get: function () { + return Tone.gainToDb(1 / this._inputBoost.gain.value); + }, + set: function (sensitivy) { + this._inputBoost.gain.value = 1 / Tone.dbToGain(sensitivy); + } + }); + /** + * sets the sweep range of the scaler + * @private + */ + Tone.AutoWah.prototype._setSweepRange = function () { + this._sweepRange.min = this._baseFrequency; + this._sweepRange.max = Math.min(this._baseFrequency * Math.pow(2, this._octaves), this.context.sampleRate / 2); + }; + /** + * Clean up. + * @returns {Tone.AutoWah} this + */ + Tone.AutoWah.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this.follower.dispose(); + this.follower = null; + this._sweepRange.dispose(); + this._sweepRange = null; + this._bandpass.dispose(); + this._bandpass = null; + this._peaking.dispose(); + this._peaking = null; + this._inputBoost.dispose(); + this._inputBoost = null; + this._writable([ + 'gain', + 'Q' + ]); + this.gain = null; + this.Q = null; + return this; + }; + return Tone.AutoWah; + }); + Module(function (Tone) { + + /** + * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus + * values in the NormalRange. + * + * @constructor + * @extends {Tone.SignalBase} + * @param {NormalRange} modulus The modulus to apply. + * @example + * var mod = new Tone.Modulo(0.2) + * var sig = new Tone.Signal(0.5).connect(mod); + * //mod outputs 0.1 + */ + Tone.Modulo = function (modulus) { + Tone.SignalBase.call(this); + this.createInsOuts(1, 0); + /** + * A waveshaper gets the integer multiple of + * the input signal and the modulus. + * @private + * @type {Tone.WaveShaper} + */ + this._shaper = new Tone.WaveShaper(Math.pow(2, 16)); + /** + * the integer multiple is multiplied by the modulus + * @type {Tone.Multiply} + * @private + */ + this._multiply = new Tone.Multiply(); + /** + * and subtracted from the input signal + * @type {Tone.Subtract} + * @private + */ + this._subtract = this.output = new Tone.Subtract(); + /** + * the modulus signal + * @type {Tone.Signal} + * @private + */ + this._modSignal = new Tone.Signal(modulus); + //connections + this.input.fan(this._shaper, this._subtract); + this._modSignal.connect(this._multiply, 0, 0); + this._shaper.connect(this._multiply, 0, 1); + this._multiply.connect(this._subtract, 0, 1); + this._setWaveShaper(modulus); + }; + Tone.extend(Tone.Modulo, Tone.SignalBase); + /** + * @param {number} mod the modulus to apply + * @private + */ + Tone.Modulo.prototype._setWaveShaper = function (mod) { + this._shaper.setMap(function (val) { + var multiple = Math.floor((val + 0.0001) / mod); + return multiple; + }); + }; + /** + * The modulus value. + * @memberOf Tone.Modulo# + * @type {NormalRange} + * @name value + */ + Object.defineProperty(Tone.Modulo.prototype, 'value', { + get: function () { + return this._modSignal.value; + }, + set: function (mod) { + this._modSignal.value = mod; + this._setWaveShaper(mod); + } + }); + /** + * clean up + * @returns {Tone.Modulo} this + */ + Tone.Modulo.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._shaper.dispose(); + this._shaper = null; + this._multiply.dispose(); + this._multiply = null; + this._subtract.dispose(); + this._subtract = null; + this._modSignal.dispose(); + this._modSignal = null; + return this; + }; + return Tone.Modulo; + }); + Module(function (Tone) { + + /** + * @class Tone.Bitcrusher downsamples the incoming signal to a different bitdepth. + * Lowering the bitdepth of the signal creates distortion. Read more about Bitcrushing + * on [Wikipedia](https://en.wikipedia.org/wiki/Bitcrusher). + * + * @constructor + * @extends {Tone.Effect} + * @param {Number} bits The number of bits to downsample the signal. Nominal range + * of 1 to 8. + * @example + * //initialize crusher and route a synth through it + * var crusher = new Tone.BitCrusher(4).toMaster(); + * var synth = new Tone.MonoSynth().connect(crusher); + */ + Tone.BitCrusher = function () { + var options = Tone.defaults(arguments, ['bits'], Tone.BitCrusher); + Tone.Effect.call(this, options); + var invStepSize = 1 / Math.pow(2, options.bits - 1); + /** + * Subtract the input signal and the modulus of the input signal + * @type {Tone.Subtract} + * @private + */ + this._subtract = new Tone.Subtract(); + /** + * The mod function + * @type {Tone.Modulo} + * @private + */ + this._modulo = new Tone.Modulo(invStepSize); + /** + * keeps track of the bits + * @type {number} + * @private + */ + this._bits = options.bits; + //connect it up + this.effectSend.fan(this._subtract, this._modulo); + this._modulo.connect(this._subtract, 0, 1); + this._subtract.connect(this.effectReturn); + }; + Tone.extend(Tone.BitCrusher, Tone.Effect); + /** + * the default values + * @static + * @type {Object} + */ + Tone.BitCrusher.defaults = { 'bits': 4 }; + /** + * The bit depth of the effect. Nominal range of 1-8. + * @memberOf Tone.BitCrusher# + * @type {number} + * @name bits + */ + Object.defineProperty(Tone.BitCrusher.prototype, 'bits', { + get: function () { + return this._bits; + }, + set: function (bits) { + this._bits = bits; + var invStepSize = 1 / Math.pow(2, bits - 1); + this._modulo.value = invStepSize; + } + }); + /** + * Clean up. + * @returns {Tone.BitCrusher} this + */ + Tone.BitCrusher.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._subtract.dispose(); + this._subtract = null; + this._modulo.dispose(); + this._modulo = null; + return this; + }; + return Tone.BitCrusher; + }); + Module(function (Tone) { + + /** + * @class Tone.ChebyShev is a Chebyshev waveshaper, an effect which is good + * for making different types of distortion sounds. + * Note that odd orders sound very different from even ones, + * and order = 1 is no change. + * Read more at [music.columbia.edu](http://music.columbia.edu/cmc/musicandcomputers/chapter4/04_06.php). + * + * @extends {Tone.Effect} + * @constructor + * @param {Positive|Object} [order] The order of the chebyshev polynomial. Normal range between 1-100. + * @example + * //create a new cheby + * var cheby = new Tone.Chebyshev(50); + * //create a monosynth connected to our cheby + * synth = new Tone.MonoSynth().connect(cheby); + */ + Tone.Chebyshev = function () { + var options = Tone.defaults(arguments, ['order'], Tone.Chebyshev); + Tone.Effect.call(this, options); + /** + * @type {WaveShaperNode} + * @private + */ + this._shaper = new Tone.WaveShaper(4096); + /** + * holds onto the order of the filter + * @type {number} + * @private + */ + this._order = options.order; + this.connectEffect(this._shaper); + this.order = options.order; + this.oversample = options.oversample; + }; + Tone.extend(Tone.Chebyshev, Tone.Effect); + /** + * @static + * @const + * @type {Object} + */ + Tone.Chebyshev.defaults = { + 'order': 1, + 'oversample': 'none' + }; + /** + * get the coefficient for that degree + * @param {number} x the x value + * @param {number} degree + * @param {Object} memo memoize the computed value. + * this speeds up computation greatly. + * @return {number} the coefficient + * @private + */ + Tone.Chebyshev.prototype._getCoefficient = function (x, degree, memo) { + if (memo.hasOwnProperty(degree)) { + return memo[degree]; + } else if (degree === 0) { + memo[degree] = 0; + } else if (degree === 1) { + memo[degree] = x; + } else { + memo[degree] = 2 * x * this._getCoefficient(x, degree - 1, memo) - this._getCoefficient(x, degree - 2, memo); + } + return memo[degree]; + }; + /** + * The order of the Chebyshev polynomial which creates + * the equation which is applied to the incoming + * signal through a Tone.WaveShaper. The equations + * are in the form:<br> + * order 2: 2x^2 + 1<br> + * order 3: 4x^3 + 3x <br> + * @memberOf Tone.Chebyshev# + * @type {Positive} + * @name order + */ + Object.defineProperty(Tone.Chebyshev.prototype, 'order', { + get: function () { + return this._order; + }, + set: function (order) { + this._order = order; + var curve = new Array(4096); + var len = curve.length; + for (var i = 0; i < len; ++i) { + var x = i * 2 / len - 1; + if (x === 0) { + //should output 0 when input is 0 + curve[i] = 0; + } else { + curve[i] = this._getCoefficient(x, order, {}); + } + } + this._shaper.curve = curve; + } + }); + /** + * The oversampling of the effect. Can either be "none", "2x" or "4x". + * @memberOf Tone.Chebyshev# + * @type {string} + * @name oversample + */ + Object.defineProperty(Tone.Chebyshev.prototype, 'oversample', { + get: function () { + return this._shaper.oversample; + }, + set: function (oversampling) { + this._shaper.oversample = oversampling; + } + }); + /** + * Clean up. + * @returns {Tone.Chebyshev} this + */ + Tone.Chebyshev.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._shaper.dispose(); + this._shaper = null; + return this; + }; + return Tone.Chebyshev; + }); + Module(function (Tone) { + + /** + * @class Base class for Stereo effects. Provides effectSendL/R and effectReturnL/R. + * + * @constructor + * @extends {Tone.Effect} + */ + Tone.StereoEffect = function () { + //get the defaults + Tone.AudioNode.call(this); + var options = Tone.defaults(arguments, ['wet'], Tone.Effect); + this.createInsOuts(1, 1); + /** + * the drywet knob to control the amount of effect + * @type {Tone.CrossFade} + * @private + */ + this._dryWet = new Tone.CrossFade(options.wet); + /** + * The wet control, i.e. how much of the effected + * will pass through to the output. + * @type {NormalRange} + * @signal + */ + this.wet = this._dryWet.fade; + /** + * then split it + * @type {Tone.Split} + * @private + */ + this._split = new Tone.Split(); + /** + * the effects send LEFT + * @type {GainNode} + * @private + */ + this.effectSendL = this._split.left; + /** + * the effects send RIGHT + * @type {GainNode} + * @private + */ + this.effectSendR = this._split.right; + /** + * the stereo effect merger + * @type {Tone.Merge} + * @private + */ + this._merge = new Tone.Merge(); + /** + * the effect return LEFT + * @type {GainNode} + * @private + */ + this.effectReturnL = this._merge.left; + /** + * the effect return RIGHT + * @type {GainNode} + * @private + */ + this.effectReturnR = this._merge.right; + //connections + this.input.connect(this._split); + //dry wet connections + this.input.connect(this._dryWet, 0, 0); + this._merge.connect(this._dryWet, 0, 1); + this._dryWet.connect(this.output); + this._readOnly(['wet']); + }; + Tone.extend(Tone.StereoEffect, Tone.Effect); + /** + * Clean up. + * @returns {Tone.StereoEffect} this + */ + Tone.StereoEffect.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._dryWet.dispose(); + this._dryWet = null; + this._split.dispose(); + this._split = null; + this._merge.dispose(); + this._merge = null; + this.effectSendL = null; + this.effectSendR = null; + this.effectReturnL = null; + this.effectReturnR = null; + this._writable(['wet']); + this.wet = null; + return this; + }; + return Tone.StereoEffect; + }); + Module(function (Tone) { + + /** + * @class Tone.Chorus is a stereo chorus effect composed of + * a left and right delay with a Tone.LFO applied to the delayTime of each channel. + * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna/blob/master/tuna.js). + * Read more on the chorus effect on [SoundOnSound](http://www.soundonsound.com/sos/jun04/articles/synthsecrets.htm). + * + * @constructor + * @extends {Tone.StereoEffect} + * @param {Frequency|Object} [frequency] The frequency of the LFO. + * @param {Milliseconds} [delayTime] The delay of the chorus effect in ms. + * @param {NormalRange} [depth] The depth of the chorus. + * @example + * var chorus = new Tone.Chorus(4, 2.5, 0.5); + * var synth = new Tone.PolySynth(4, Tone.MonoSynth).connect(chorus); + * synth.triggerAttackRelease(["C3","E3","G3"], "8n"); + */ + Tone.Chorus = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'delayTime', + 'depth' + ], Tone.Chorus); + Tone.StereoEffect.call(this, options); + /** + * the depth of the chorus + * @type {number} + * @private + */ + this._depth = options.depth; + /** + * the delayTime + * @type {number} + * @private + */ + this._delayTime = options.delayTime / 1000; + /** + * the lfo which controls the delayTime + * @type {Tone.LFO} + * @private + */ + this._lfoL = new Tone.LFO({ + 'frequency': options.frequency, + 'min': 0, + 'max': 1 + }); + /** + * another LFO for the right side with a 180 degree phase diff + * @type {Tone.LFO} + * @private + */ + this._lfoR = new Tone.LFO({ + 'frequency': options.frequency, + 'min': 0, + 'max': 1, + 'phase': 180 + }); + /** + * delay for left + * @type {Tone.Delay} + * @private + */ + this._delayNodeL = new Tone.Delay(); + /** + * delay for right + * @type {Tone.Delay} + * @private + */ + this._delayNodeR = new Tone.Delay(); + /** + * The frequency of the LFO which modulates the delayTime. + * @type {Frequency} + * @signal + */ + this.frequency = this._lfoL.frequency; + //connections + this.effectSendL.chain(this._delayNodeL, this.effectReturnL); + this.effectSendR.chain(this._delayNodeR, this.effectReturnR); + //and pass through to make the detune apparent + this.effectSendL.connect(this.effectReturnL); + this.effectSendR.connect(this.effectReturnR); + //lfo setup + this._lfoL.connect(this._delayNodeL.delayTime); + this._lfoR.connect(this._delayNodeR.delayTime); + //start the lfo + this._lfoL.start(); + this._lfoR.start(); + //have one LFO frequency control the other + this._lfoL.frequency.connect(this._lfoR.frequency); + //set the initial values + this.depth = this._depth; + this.frequency.value = options.frequency; + this.type = options.type; + this._readOnly(['frequency']); + this.spread = options.spread; + }; + Tone.extend(Tone.Chorus, Tone.StereoEffect); + /** + * @static + * @type {Object} + */ + Tone.Chorus.defaults = { + 'frequency': 1.5, + 'delayTime': 3.5, + 'depth': 0.7, + 'type': 'sine', + 'spread': 180 + }; + /** + * The depth of the effect. A depth of 1 makes the delayTime + * modulate between 0 and 2*delayTime (centered around the delayTime). + * @memberOf Tone.Chorus# + * @type {NormalRange} + * @name depth + */ + Object.defineProperty(Tone.Chorus.prototype, 'depth', { + get: function () { + return this._depth; + }, + set: function (depth) { + this._depth = depth; + var deviation = this._delayTime * depth; + this._lfoL.min = Math.max(this._delayTime - deviation, 0); + this._lfoL.max = this._delayTime + deviation; + this._lfoR.min = Math.max(this._delayTime - deviation, 0); + this._lfoR.max = this._delayTime + deviation; + } + }); + /** + * The delayTime in milliseconds of the chorus. A larger delayTime + * will give a more pronounced effect. Nominal range a delayTime + * is between 2 and 20ms. + * @memberOf Tone.Chorus# + * @type {Milliseconds} + * @name delayTime + */ + Object.defineProperty(Tone.Chorus.prototype, 'delayTime', { + get: function () { + return this._delayTime * 1000; + }, + set: function (delayTime) { + this._delayTime = delayTime / 1000; + this.depth = this._depth; + } + }); + /** + * The oscillator type of the LFO. + * @memberOf Tone.Chorus# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.Chorus.prototype, 'type', { + get: function () { + return this._lfoL.type; + }, + set: function (type) { + this._lfoL.type = type; + this._lfoR.type = type; + } + }); + /** + * Amount of stereo spread. When set to 0, both LFO's will be panned centrally. + * When set to 180, LFO's will be panned hard left and right respectively. + * @memberOf Tone.Chorus# + * @type {Degrees} + * @name spread + */ + Object.defineProperty(Tone.Chorus.prototype, 'spread', { + get: function () { + return this._lfoR.phase - this._lfoL.phase; + }, + set: function (spread) { + this._lfoL.phase = 90 - spread / 2; + this._lfoR.phase = spread / 2 + 90; + } + }); + /** + * Clean up. + * @returns {Tone.Chorus} this + */ + Tone.Chorus.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._lfoL.dispose(); + this._lfoL = null; + this._lfoR.dispose(); + this._lfoR = null; + this._delayNodeL.dispose(); + this._delayNodeL = null; + this._delayNodeR.dispose(); + this._delayNodeR = null; + this._writable('frequency'); + this.frequency = null; + return this; + }; + return Tone.Chorus; + }); + Module(function (Tone) { + + /** + * @class Tone.Convolver is a wrapper around the Native Web Audio + * [ConvolverNode](http://webaudio.github.io/web-audio-api/#the-convolvernode-interface). + * Convolution is useful for reverb and filter emulation. Read more about convolution reverb on + * [Wikipedia](https://en.wikipedia.org/wiki/Convolution_reverb). + * + * @constructor + * @extends {Tone.Effect} + * @param {string|Tone.Buffer|Object} [url] The URL of the impulse response or the Tone.Buffer + * contianing the impulse response. + * @param {Function=} onload The callback to invoke when the url is loaded. + * @example + * //initializing the convolver with an impulse response + * var convolver = new Tone.Convolver("./path/to/ir.wav").toMaster(); + */ + Tone.Convolver = function () { + var options = Tone.defaults(arguments, [ + 'url', + 'onload' + ], Tone.Convolver); + Tone.Effect.call(this, options); + /** + * convolver node + * @type {ConvolverNode} + * @private + */ + this._convolver = this.context.createConvolver(); + /** + * the convolution buffer + * @type {Tone.Buffer} + * @private + */ + this._buffer = new Tone.Buffer(options.url, function (buffer) { + this._convolver.buffer = buffer.get(); + options.onload(); + }.bind(this)); + this.connectEffect(this._convolver); + }; + Tone.extend(Tone.Convolver, Tone.Effect); + /** + * @static + * @const + * @type {Object} + */ + Tone.Convolver.defaults = { 'onload': Tone.noOp }; + /** + * The convolver's buffer + * @memberOf Tone.Convolver# + * @type {AudioBuffer} + * @name buffer + */ + Object.defineProperty(Tone.Convolver.prototype, 'buffer', { + get: function () { + return this._buffer.get(); + }, + set: function (buffer) { + this._buffer.set(buffer); + this._convolver.buffer = this._buffer.get(); + } + }); + /** + * Load an impulse response url as an audio buffer. + * Decodes the audio asynchronously and invokes + * the callback once the audio buffer loads. + * @param {string} url The url of the buffer to load. + * filetype support depends on the + * browser. + * @param {function=} callback + * @returns {Promise} + */ + Tone.Convolver.prototype.load = function (url, callback) { + return this._buffer.load(url, function (buff) { + this.buffer = buff; + if (callback) { + callback(); + } + }.bind(this)); + }; + /** + * Clean up. + * @returns {Tone.Convolver} this + */ + Tone.Convolver.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._convolver.disconnect(); + this._convolver = null; + this._buffer.dispose(); + this._buffer = null; + return this; + }; + return Tone.Convolver; + }); + Module(function (Tone) { + + /** + * @class Tone.Distortion is a simple distortion effect using Tone.WaveShaper. + * Algorithm from [a stackoverflow answer](http://stackoverflow.com/a/22313408). + * + * @extends {Tone.Effect} + * @constructor + * @param {Number|Object} [distortion] The amount of distortion (nominal range of 0-1) + * @example + * var dist = new Tone.Distortion(0.8).toMaster(); + * var fm = new Tone.SimpleFM().connect(dist); + * //this sounds good on bass notes + * fm.triggerAttackRelease("A1", "8n"); + */ + Tone.Distortion = function () { + var options = Tone.defaults(arguments, ['distortion'], Tone.Distortion); + Tone.Effect.call(this, options); + /** + * @type {Tone.WaveShaper} + * @private + */ + this._shaper = new Tone.WaveShaper(4096); + /** + * holds the distortion amount + * @type {number} + * @private + */ + this._distortion = options.distortion; + this.connectEffect(this._shaper); + this.distortion = options.distortion; + this.oversample = options.oversample; + }; + Tone.extend(Tone.Distortion, Tone.Effect); + /** + * @static + * @const + * @type {Object} + */ + Tone.Distortion.defaults = { + 'distortion': 0.4, + 'oversample': 'none' + }; + /** + * The amount of distortion. + * @memberOf Tone.Distortion# + * @type {NormalRange} + * @name distortion + */ + Object.defineProperty(Tone.Distortion.prototype, 'distortion', { + get: function () { + return this._distortion; + }, + set: function (amount) { + this._distortion = amount; + var k = amount * 100; + var deg = Math.PI / 180; + this._shaper.setMap(function (x) { + if (Math.abs(x) < 0.001) { + //should output 0 when input is 0 + return 0; + } else { + return (3 + k) * x * 20 * deg / (Math.PI + k * Math.abs(x)); + } + }); + } + }); + /** + * The oversampling of the effect. Can either be "none", "2x" or "4x". + * @memberOf Tone.Distortion# + * @type {string} + * @name oversample + */ + Object.defineProperty(Tone.Distortion.prototype, 'oversample', { + get: function () { + return this._shaper.oversample; + }, + set: function (oversampling) { + this._shaper.oversample = oversampling; + } + }); + /** + * Clean up. + * @returns {Tone.Distortion} this + */ + Tone.Distortion.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._shaper.dispose(); + this._shaper = null; + return this; + }; + return Tone.Distortion; + }); + Module(function (Tone) { + + /** + * @class Tone.FeedbackEffect provides a loop between an + * audio source and its own output. This is a base-class + * for feedback effects. + * + * @constructor + * @extends {Tone.Effect} + * @param {NormalRange|Object} [feedback] The initial feedback value. + */ + Tone.FeedbackEffect = function () { + var options = Tone.defaults(arguments, ['feedback'], Tone.FeedbackEffect); + Tone.Effect.call(this, options); + /** + * the gain which controls the feedback + * @type {Tone.Gain} + * @private + */ + this._feedbackGain = new Tone.Gain(options.feedback, Tone.Type.NormalRange); + /** + * The amount of signal which is fed back into the effect input. + * @type {NormalRange} + * @signal + */ + this.feedback = this._feedbackGain.gain; + //the feedback loop + this.effectReturn.chain(this._feedbackGain, this.effectSend); + this._readOnly(['feedback']); + }; + Tone.extend(Tone.FeedbackEffect, Tone.Effect); + /** + * @static + * @type {Object} + */ + Tone.FeedbackEffect.defaults = { 'feedback': 0.125 }; + /** + * Clean up. + * @returns {Tone.FeedbackEffect} this + */ + Tone.FeedbackEffect.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._writable(['feedback']); + this._feedbackGain.dispose(); + this._feedbackGain = null; + this.feedback = null; + return this; + }; + return Tone.FeedbackEffect; + }); + Module(function (Tone) { + + /** + * @class Tone.FeedbackDelay is a DelayNode in which part of output + * signal is fed back into the delay. + * + * @constructor + * @extends {Tone.FeedbackEffect} + * @param {Time|Object} [delayTime] The delay applied to the incoming signal. + * @param {NormalRange=} feedback The amount of the effected signal which + * is fed back through the delay. + * @example + * var feedbackDelay = new Tone.FeedbackDelay("8n", 0.5).toMaster(); + * var tom = new Tone.DrumSynth({ + * "octaves" : 4, + * "pitchDecay" : 0.1 + * }).connect(feedbackDelay); + * tom.triggerAttackRelease("A2","32n"); + */ + Tone.FeedbackDelay = function () { + var options = Tone.defaults(arguments, [ + 'delayTime', + 'feedback' + ], Tone.FeedbackDelay); + Tone.FeedbackEffect.call(this, options); + /** + * the delay node + * @type {Tone.Delay} + * @private + */ + this._delayNode = new Tone.Delay(options.delayTime, options.maxDelay); + /** + * The delayTime of the DelayNode. + * @type {Time} + * @signal + */ + this.delayTime = this._delayNode.delayTime; + // connect it up + this.connectEffect(this._delayNode); + this._readOnly(['delayTime']); + }; + Tone.extend(Tone.FeedbackDelay, Tone.FeedbackEffect); + /** + * The default values. + * @const + * @static + * @type {Object} + */ + Tone.FeedbackDelay.defaults = { + 'delayTime': 0.25, + 'maxDelay': 1 + }; + /** + * clean up + * @returns {Tone.FeedbackDelay} this + */ + Tone.FeedbackDelay.prototype.dispose = function () { + Tone.FeedbackEffect.prototype.dispose.call(this); + this._delayNode.dispose(); + this._delayNode = null; + this._writable(['delayTime']); + this.delayTime = null; + return this; + }; + return Tone.FeedbackDelay; + }); + Module(function (Tone) { + + /** + * an array of comb filter delay values from Freeverb implementation + * @static + * @private + * @type {Array} + */ + var combFilterTunings = [ + 1557 / 44100, + 1617 / 44100, + 1491 / 44100, + 1422 / 44100, + 1277 / 44100, + 1356 / 44100, + 1188 / 44100, + 1116 / 44100 + ]; + /** + * an array of allpass filter frequency values from Freeverb implementation + * @private + * @static + * @type {Array} + */ + var allpassFilterFrequencies = [ + 225, + 556, + 441, + 341 + ]; + /** + * @class Tone.Freeverb is a reverb based on [Freeverb](https://ccrma.stanford.edu/~jos/pasp/Freeverb.html). + * Read more on reverb on [Sound On Sound](https://web.archive.org/web/20160404083902/http://www.soundonsound.com:80/sos/feb01/articles/synthsecrets.asp). + * + * @extends {Tone.Effect} + * @constructor + * @param {NormalRange|Object} [roomSize] Correlated to the decay time. + * @param {Frequency} [dampening] The cutoff frequency of a lowpass filter as part + * of the reverb. + * @example + * var freeverb = new Tone.Freeverb().toMaster(); + * freeverb.dampening.value = 1000; + * //routing synth through the reverb + * var synth = new Tone.AMSynth().connect(freeverb); + */ + Tone.Freeverb = function () { + var options = Tone.defaults(arguments, [ + 'roomSize', + 'dampening' + ], Tone.Freeverb); + Tone.StereoEffect.call(this, options); + /** + * The roomSize value between. A larger roomSize + * will result in a longer decay. + * @type {NormalRange} + * @signal + */ + this.roomSize = new Tone.Signal(options.roomSize, Tone.Type.NormalRange); + /** + * The amount of dampening of the reverberant signal. + * @type {Frequency} + * @signal + */ + this.dampening = new Tone.Signal(options.dampening, Tone.Type.Frequency); + /** + * the comb filters + * @type {Array} + * @private + */ + this._combFilters = []; + /** + * the allpass filters on the left + * @type {Array} + * @private + */ + this._allpassFiltersL = []; + /** + * the allpass filters on the right + * @type {Array} + * @private + */ + this._allpassFiltersR = []; + //make the allpass filters on the right + for (var l = 0; l < allpassFilterFrequencies.length; l++) { + var allpassL = this.context.createBiquadFilter(); + allpassL.type = 'allpass'; + allpassL.frequency.value = allpassFilterFrequencies[l]; + this._allpassFiltersL.push(allpassL); + } + //make the allpass filters on the left + for (var r = 0; r < allpassFilterFrequencies.length; r++) { + var allpassR = this.context.createBiquadFilter(); + allpassR.type = 'allpass'; + allpassR.frequency.value = allpassFilterFrequencies[r]; + this._allpassFiltersR.push(allpassR); + } + //make the comb filters + for (var c = 0; c < combFilterTunings.length; c++) { + var lfpf = new Tone.LowpassCombFilter(combFilterTunings[c]); + if (c < combFilterTunings.length / 2) { + this.effectSendL.chain(lfpf, this._allpassFiltersL[0]); + } else { + this.effectSendR.chain(lfpf, this._allpassFiltersR[0]); + } + this.roomSize.connect(lfpf.resonance); + this.dampening.connect(lfpf.dampening); + this._combFilters.push(lfpf); + } + //chain the allpass filters togetehr + Tone.connectSeries.apply(Tone, this._allpassFiltersL); + Tone.connectSeries.apply(Tone, this._allpassFiltersR); + this._allpassFiltersL[this._allpassFiltersL.length - 1].connect(this.effectReturnL); + this._allpassFiltersR[this._allpassFiltersR.length - 1].connect(this.effectReturnR); + this._readOnly([ + 'roomSize', + 'dampening' + ]); + }; + Tone.extend(Tone.Freeverb, Tone.StereoEffect); + /** + * @static + * @type {Object} + */ + Tone.Freeverb.defaults = { + 'roomSize': 0.7, + 'dampening': 3000 + }; + /** + * Clean up. + * @returns {Tone.Freeverb} this + */ + Tone.Freeverb.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + for (var al = 0; al < this._allpassFiltersL.length; al++) { + this._allpassFiltersL[al].disconnect(); + this._allpassFiltersL[al] = null; + } + this._allpassFiltersL = null; + for (var ar = 0; ar < this._allpassFiltersR.length; ar++) { + this._allpassFiltersR[ar].disconnect(); + this._allpassFiltersR[ar] = null; + } + this._allpassFiltersR = null; + for (var cf = 0; cf < this._combFilters.length; cf++) { + this._combFilters[cf].dispose(); + this._combFilters[cf] = null; + } + this._combFilters = null; + this._writable([ + 'roomSize', + 'dampening' + ]); + this.roomSize.dispose(); + this.roomSize = null; + this.dampening.dispose(); + this.dampening = null; + return this; + }; + return Tone.Freeverb; + }); + Module(function (Tone) { + + /** + * an array of the comb filter delay time values + * @private + * @static + * @type {Array} + */ + var combFilterDelayTimes = [ + 1687 / 25000, + 1601 / 25000, + 2053 / 25000, + 2251 / 25000 + ]; + /** + * the resonances of each of the comb filters + * @private + * @static + * @type {Array} + */ + var combFilterResonances = [ + 0.773, + 0.802, + 0.753, + 0.733 + ]; + /** + * the allpass filter frequencies + * @private + * @static + * @type {Array} + */ + var allpassFilterFreqs = [ + 347, + 113, + 37 + ]; + /** + * @class Tone.JCReverb is a simple [Schroeder Reverberator](https://ccrma.stanford.edu/~jos/pasp/Schroeder_Reverberators.html) + * tuned by John Chowning in 1970. + * It is made up of three allpass filters and four Tone.FeedbackCombFilter. + * + * + * @extends {Tone.Effect} + * @constructor + * @param {NormalRange|Object} [roomSize] Coorelates to the decay time. + * @example + * var reverb = new Tone.JCReverb(0.4).connect(Tone.Master); + * var delay = new Tone.FeedbackDelay(0.5); + * //connecting the synth to reverb through delay + * var synth = new Tone.DuoSynth().chain(delay, reverb); + * synth.triggerAttackRelease("A4","8n"); + */ + Tone.JCReverb = function () { + var options = Tone.defaults(arguments, ['roomSize'], Tone.JCReverb); + Tone.StereoEffect.call(this, options); + /** + * room size control values between [0,1] + * @type {NormalRange} + * @signal + */ + this.roomSize = new Tone.Signal(options.roomSize, Tone.Type.NormalRange); + /** + * scale the room size + * @type {Tone.Scale} + * @private + */ + this._scaleRoomSize = new Tone.Scale(-0.733, 0.197); + /** + * a series of allpass filters + * @type {Array} + * @private + */ + this._allpassFilters = []; + /** + * parallel feedback comb filters + * @type {Array} + * @private + */ + this._feedbackCombFilters = []; + //make the allpass filters + for (var af = 0; af < allpassFilterFreqs.length; af++) { + var allpass = this.context.createBiquadFilter(); + allpass.type = 'allpass'; + allpass.frequency.value = allpassFilterFreqs[af]; + this._allpassFilters.push(allpass); + } + //and the comb filters + for (var cf = 0; cf < combFilterDelayTimes.length; cf++) { + var fbcf = new Tone.FeedbackCombFilter(combFilterDelayTimes[cf], 0.1); + this._scaleRoomSize.connect(fbcf.resonance); + fbcf.resonance.value = combFilterResonances[cf]; + this._allpassFilters[this._allpassFilters.length - 1].connect(fbcf); + if (cf < combFilterDelayTimes.length / 2) { + fbcf.connect(this.effectReturnL); + } else { + fbcf.connect(this.effectReturnR); + } + this._feedbackCombFilters.push(fbcf); + } + //chain the allpass filters together + this.roomSize.connect(this._scaleRoomSize); + Tone.connectSeries.apply(Tone, this._allpassFilters); + this.effectSendL.connect(this._allpassFilters[0]); + this.effectSendR.connect(this._allpassFilters[0]); + this._readOnly(['roomSize']); + }; + Tone.extend(Tone.JCReverb, Tone.StereoEffect); + /** + * the default values + * @static + * @const + * @type {Object} + */ + Tone.JCReverb.defaults = { 'roomSize': 0.5 }; + /** + * Clean up. + * @returns {Tone.JCReverb} this + */ + Tone.JCReverb.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + for (var apf = 0; apf < this._allpassFilters.length; apf++) { + this._allpassFilters[apf].disconnect(); + this._allpassFilters[apf] = null; + } + this._allpassFilters = null; + for (var fbcf = 0; fbcf < this._feedbackCombFilters.length; fbcf++) { + this._feedbackCombFilters[fbcf].dispose(); + this._feedbackCombFilters[fbcf] = null; + } + this._feedbackCombFilters = null; + this._writable(['roomSize']); + this.roomSize.dispose(); + this.roomSize = null; + this._scaleRoomSize.dispose(); + this._scaleRoomSize = null; + return this; + }; + return Tone.JCReverb; + }); + Module(function (Tone) { + + /** + * @class Mid/Side processing separates the the 'mid' signal + * (which comes out of both the left and the right channel) + * and the 'side' (which only comes out of the the side channels) + * and effects them separately before being recombined. + * Applies a Mid/Side seperation and recombination. + * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587). + * <br><br> + * This is a base-class for Mid/Side Effects. + * + * @extends {Tone.Effect} + * @constructor + */ + Tone.MidSideEffect = function () { + Tone.Effect.apply(this, arguments); + /** + * The mid/side split + * @type {Tone.MidSideSplit} + * @private + */ + this._midSideSplit = new Tone.MidSideSplit(); + /** + * The mid/side merge + * @type {Tone.MidSideMerge} + * @private + */ + this._midSideMerge = new Tone.MidSideMerge(); + /** + * The mid send. Connect to mid processing + * @type {Tone} + * @private + */ + this.midSend = this._midSideSplit.mid; + /** + * The side send. Connect to side processing + * @type {Tone} + * @private + */ + this.sideSend = this._midSideSplit.side; + /** + * The mid return connection + * @type {GainNode} + * @private + */ + this.midReturn = this._midSideMerge.mid; + /** + * The side return connection + * @type {GainNode} + * @private + */ + this.sideReturn = this._midSideMerge.side; + //the connections + this.effectSend.connect(this._midSideSplit); + this._midSideMerge.connect(this.effectReturn); + }; + Tone.extend(Tone.MidSideEffect, Tone.Effect); + /** + * Clean up. + * @returns {Tone.MidSideEffect} this + */ + Tone.MidSideEffect.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._midSideSplit.dispose(); + this._midSideSplit = null; + this._midSideMerge.dispose(); + this._midSideMerge = null; + this.midSend = null; + this.sideSend = null; + this.midReturn = null; + this.sideReturn = null; + return this; + }; + return Tone.MidSideEffect; + }); + Module(function (Tone) { + + /** + * @class Tone.Phaser is a phaser effect. Phasers work by changing the phase + * of different frequency components of an incoming signal. Read more on + * [Wikipedia](https://en.wikipedia.org/wiki/Phaser_(effect)). + * Inspiration for this phaser comes from [Tuna.js](https://github.com/Dinahmoe/tuna/). + * + * @extends {Tone.StereoEffect} + * @constructor + * @param {Frequency|Object} [frequency] The speed of the phasing. + * @param {number} [octaves] The octaves of the effect. + * @param {Frequency} [baseFrequency] The base frequency of the filters. + * @example + * var phaser = new Tone.Phaser({ + * "frequency" : 15, + * "octaves" : 5, + * "baseFrequency" : 1000 + * }).toMaster(); + * var synth = new Tone.FMSynth().connect(phaser); + * synth.triggerAttackRelease("E3", "2n"); + */ + Tone.Phaser = function () { + //set the defaults + var options = Tone.defaults(arguments, [ + 'frequency', + 'octaves', + 'baseFrequency' + ], Tone.Phaser); + Tone.StereoEffect.call(this, options); + /** + * the lfo which controls the frequency on the left side + * @type {Tone.LFO} + * @private + */ + this._lfoL = new Tone.LFO(options.frequency, 0, 1); + /** + * the lfo which controls the frequency on the right side + * @type {Tone.LFO} + * @private + */ + this._lfoR = new Tone.LFO(options.frequency, 0, 1); + this._lfoR.phase = 180; + /** + * the base modulation frequency + * @type {number} + * @private + */ + this._baseFrequency = options.baseFrequency; + /** + * the octaves of the phasing + * @type {number} + * @private + */ + this._octaves = options.octaves; + /** + * The quality factor of the filters + * @type {Positive} + * @signal + */ + this.Q = new Tone.Signal(options.Q, Tone.Type.Positive); + /** + * the array of filters for the left side + * @type {Array} + * @private + */ + this._filtersL = this._makeFilters(options.stages, this._lfoL, this.Q); + /** + * the array of filters for the left side + * @type {Array} + * @private + */ + this._filtersR = this._makeFilters(options.stages, this._lfoR, this.Q); + /** + * the frequency of the effect + * @type {Tone.Signal} + */ + this.frequency = this._lfoL.frequency; + this.frequency.value = options.frequency; + //connect them up + this.effectSendL.connect(this._filtersL[0]); + this.effectSendR.connect(this._filtersR[0]); + this._filtersL[options.stages - 1].connect(this.effectReturnL); + this._filtersR[options.stages - 1].connect(this.effectReturnR); + //control the frequency with one LFO + this._lfoL.frequency.connect(this._lfoR.frequency); + //set the options + this.baseFrequency = options.baseFrequency; + this.octaves = options.octaves; + //start the lfo + this._lfoL.start(); + this._lfoR.start(); + this._readOnly([ + 'frequency', + 'Q' + ]); + }; + Tone.extend(Tone.Phaser, Tone.StereoEffect); + /** + * defaults + * @static + * @type {object} + */ + Tone.Phaser.defaults = { + 'frequency': 0.5, + 'octaves': 3, + 'stages': 10, + 'Q': 10, + 'baseFrequency': 350 + }; + /** + * @param {number} stages + * @returns {Array} the number of filters all connected together + * @private + */ + Tone.Phaser.prototype._makeFilters = function (stages, connectToFreq, Q) { + var filters = new Array(stages); + //make all the filters + for (var i = 0; i < stages; i++) { + var filter = this.context.createBiquadFilter(); + filter.type = 'allpass'; + Q.connect(filter.Q); + connectToFreq.connect(filter.frequency); + filters[i] = filter; + } + Tone.connectSeries.apply(Tone, filters); + return filters; + }; + /** + * The number of octaves the phase goes above + * the baseFrequency + * @memberOf Tone.Phaser# + * @type {Positive} + * @name octaves + */ + Object.defineProperty(Tone.Phaser.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (octaves) { + this._octaves = octaves; + var max = this._baseFrequency * Math.pow(2, octaves); + this._lfoL.max = max; + this._lfoR.max = max; + } + }); + /** + * The the base frequency of the filters. + * @memberOf Tone.Phaser# + * @type {number} + * @name baseFrequency + */ + Object.defineProperty(Tone.Phaser.prototype, 'baseFrequency', { + get: function () { + return this._baseFrequency; + }, + set: function (freq) { + this._baseFrequency = freq; + this._lfoL.min = freq; + this._lfoR.min = freq; + this.octaves = this._octaves; + } + }); + /** + * clean up + * @returns {Tone.Phaser} this + */ + Tone.Phaser.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'Q' + ]); + this.Q.dispose(); + this.Q = null; + this._lfoL.dispose(); + this._lfoL = null; + this._lfoR.dispose(); + this._lfoR = null; + for (var i = 0; i < this._filtersL.length; i++) { + this._filtersL[i].disconnect(); + this._filtersL[i] = null; + } + this._filtersL = null; + for (var j = 0; j < this._filtersR.length; j++) { + this._filtersR[j].disconnect(); + this._filtersR[j] = null; + } + this._filtersR = null; + this.frequency = null; + return this; + }; + return Tone.Phaser; + }); + Module(function (Tone) { + + /** + * @class Just like a stereo feedback effect, but the feedback is routed from left to right + * and right to left instead of on the same channel. + * + * @constructor + * @extends {Tone.StereoEffect} + */ + Tone.StereoXFeedbackEffect = function () { + var options = Tone.defaults(arguments, ['feedback'], Tone.FeedbackEffect); + Tone.StereoEffect.call(this, options); + /** + * The amount of feedback from the output + * back into the input of the effect (routed + * across left and right channels). + * @type {NormalRange} + * @signal + */ + this.feedback = new Tone.Signal(options.feedback, Tone.Type.NormalRange); + /** + * the left side feeback + * @type {Tone.Gain} + * @private + */ + this._feedbackLR = new Tone.Gain(); + /** + * the right side feeback + * @type {Tone.Gain} + * @private + */ + this._feedbackRL = new Tone.Gain(); + //connect it up + this.effectReturnL.chain(this._feedbackLR, this.effectSendR); + this.effectReturnR.chain(this._feedbackRL, this.effectSendL); + this.feedback.fan(this._feedbackLR.gain, this._feedbackRL.gain); + this._readOnly(['feedback']); + }; + Tone.extend(Tone.StereoXFeedbackEffect, Tone.StereoEffect); + /** + * clean up + * @returns {Tone.StereoXFeedbackEffect} this + */ + Tone.StereoXFeedbackEffect.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._writable(['feedback']); + this.feedback.dispose(); + this.feedback = null; + this._feedbackLR.dispose(); + this._feedbackLR = null; + this._feedbackRL.dispose(); + this._feedbackRL = null; + return this; + }; + return Tone.StereoXFeedbackEffect; + }); + Module(function (Tone) { + + /** + * @class Tone.PingPongDelay is a feedback delay effect where the echo is heard + * first in one channel and next in the opposite channel. In a stereo + * system these are the right and left channels. + * PingPongDelay in more simplified terms is two Tone.FeedbackDelays + * with independent delay values. Each delay is routed to one channel + * (left or right), and the channel triggered second will always + * trigger at the same interval after the first. + * + * @constructor + * @extends {Tone.StereoXFeedbackEffect} + * @param {Time|Object} [delayTime] The delayTime between consecutive echos. + * @param {NormalRange=} feedback The amount of the effected signal which + * is fed back through the delay. + * @example + * var pingPong = new Tone.PingPongDelay("4n", 0.2).toMaster(); + * var drum = new Tone.DrumSynth().connect(pingPong); + * drum.triggerAttackRelease("C4", "32n"); + */ + Tone.PingPongDelay = function () { + var options = Tone.defaults(arguments, [ + 'delayTime', + 'feedback' + ], Tone.PingPongDelay); + Tone.StereoXFeedbackEffect.call(this, options); + /** + * the delay node on the left side + * @type {Tone.Delay} + * @private + */ + this._leftDelay = new Tone.Delay(0, options.maxDelayTime); + /** + * the delay node on the right side + * @type {Tone.Delay} + * @private + */ + this._rightDelay = new Tone.Delay(0, options.maxDelayTime); + /** + * the predelay on the right side + * @type {Tone.Delay} + * @private + */ + this._rightPreDelay = new Tone.Delay(0, options.maxDelayTime); + /** + * the delay time signal + * @type {Time} + * @signal + */ + this.delayTime = new Tone.Signal(options.delayTime, Tone.Type.Time); + //connect it up + this.effectSendL.chain(this._leftDelay, this.effectReturnL); + this.effectSendR.chain(this._rightPreDelay, this._rightDelay, this.effectReturnR); + this.delayTime.fan(this._leftDelay.delayTime, this._rightDelay.delayTime, this._rightPreDelay.delayTime); + //rearranged the feedback to be after the rightPreDelay + this._feedbackLR.disconnect(); + this._feedbackLR.connect(this._rightDelay); + this._readOnly(['delayTime']); + }; + Tone.extend(Tone.PingPongDelay, Tone.StereoXFeedbackEffect); + /** + * @static + * @type {Object} + */ + Tone.PingPongDelay.defaults = { + 'delayTime': 0.25, + 'maxDelayTime': 1 + }; + /** + * Clean up. + * @returns {Tone.PingPongDelay} this + */ + Tone.PingPongDelay.prototype.dispose = function () { + Tone.StereoXFeedbackEffect.prototype.dispose.call(this); + this._leftDelay.dispose(); + this._leftDelay = null; + this._rightDelay.dispose(); + this._rightDelay = null; + this._rightPreDelay.dispose(); + this._rightPreDelay = null; + this._writable(['delayTime']); + this.delayTime.dispose(); + this.delayTime = null; + return this; + }; + return Tone.PingPongDelay; + }); + Module(function (Tone) { + + /** + * @class Tone.PitchShift does near-realtime pitch shifting to the incoming signal. + * The effect is achieved by speeding up or slowing down the delayTime + * of a DelayNode using a sawtooth wave. + * Algorithm found in [this pdf](http://dsp-book.narod.ru/soundproc.pdf). + * Additional reference by [Miller Pucket](http://msp.ucsd.edu/techniques/v0.11/book-html/node115.html). + * + * @extends {Tone.FeedbackEffect} + * @param {Interval=} pitch The interval to transpose the incoming signal by. + */ + Tone.PitchShift = function () { + var options = Tone.defaults(arguments, ['pitch'], Tone.PitchShift); + Tone.FeedbackEffect.call(this, options); + /** + * The pitch signal + * @type {Tone.Signal} + * @private + */ + this._frequency = new Tone.Signal(0); + /** + * Uses two DelayNodes to cover up the jump in + * the sawtooth wave. + * @type {DelayNode} + * @private + */ + this._delayA = new Tone.Delay(0, 1); + /** + * The first LFO. + * @type {Tone.LFO} + * @private + */ + this._lfoA = new Tone.LFO({ + 'min': 0, + 'max': 0.1, + 'type': 'sawtooth' + }).connect(this._delayA.delayTime); + /** + * The second DelayNode + * @type {DelayNode} + * @private + */ + this._delayB = new Tone.Delay(0, 1); + /** + * The first LFO. + * @type {Tone.LFO} + * @private + */ + this._lfoB = new Tone.LFO({ + 'min': 0, + 'max': 0.1, + 'type': 'sawtooth', + 'phase': 180 + }).connect(this._delayB.delayTime); + /** + * Crossfade quickly between the two delay lines + * to cover up the jump in the sawtooth wave + * @type {Tone.CrossFade} + * @private + */ + this._crossFade = new Tone.CrossFade(); + /** + * LFO which alternates between the two + * delay lines to cover up the disparity in the + * sawtooth wave. + * @type {Tone.LFO} + * @private + */ + this._crossFadeLFO = new Tone.LFO({ + 'min': 0, + 'max': 1, + 'type': 'triangle', + 'phase': 90 + }).connect(this._crossFade.fade); + /** + * The delay node + * @type {Tone.Delay} + * @private + */ + this._feedbackDelay = new Tone.Delay(options.delayTime); + /** + * The amount of delay on the input signal + * @type {Time} + * @signal + */ + this.delayTime = this._feedbackDelay.delayTime; + this._readOnly('delayTime'); + /** + * Hold the current pitch + * @type {Number} + * @private + */ + this._pitch = options.pitch; + /** + * Hold the current windowSize + * @type {Number} + * @private + */ + this._windowSize = options.windowSize; + //connect the two delay lines up + this._delayA.connect(this._crossFade.a); + this._delayB.connect(this._crossFade.b); + //connect the frequency + this._frequency.fan(this._lfoA.frequency, this._lfoB.frequency, this._crossFadeLFO.frequency); + //route the input + this.effectSend.fan(this._delayA, this._delayB); + this._crossFade.chain(this._feedbackDelay, this.effectReturn); + //start the LFOs at the same time + var now = this.now(); + this._lfoA.start(now); + this._lfoB.start(now); + this._crossFadeLFO.start(now); + //set the initial value + this.windowSize = this._windowSize; + }; + Tone.extend(Tone.PitchShift, Tone.FeedbackEffect); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.PitchShift.defaults = { + 'pitch': 0, + 'windowSize': 0.1, + 'delayTime': 0, + 'feedback': 0 + }; + /** + * Repitch the incoming signal by some interval (measured + * in semi-tones). + * @memberOf Tone.PitchShift# + * @type {Interval} + * @name pitch + * @example + * pitchShift.pitch = -12; //down one octave + * pitchShift.pitch = 7; //up a fifth + */ + Object.defineProperty(Tone.PitchShift.prototype, 'pitch', { + get: function () { + return this._pitch; + }, + set: function (interval) { + this._pitch = interval; + var factor = 0; + if (interval < 0) { + this._lfoA.min = 0; + this._lfoA.max = this._windowSize; + this._lfoB.min = 0; + this._lfoB.max = this._windowSize; + factor = Tone.intervalToFrequencyRatio(interval - 1) + 1; + } else { + this._lfoA.min = this._windowSize; + this._lfoA.max = 0; + this._lfoB.min = this._windowSize; + this._lfoB.max = 0; + factor = Tone.intervalToFrequencyRatio(interval) - 1; + } + this._frequency.value = factor * (1.2 / this._windowSize); + } + }); + /** + * The window size corresponds roughly to the sample length in a looping sampler. + * Smaller values are desirable for a less noticeable delay time of the pitch shifted + * signal, but larger values will result in smoother pitch shifting for larger intervals. + * A nominal range of 0.03 to 0.1 is recommended. + * @memberOf Tone.PitchShift# + * @type {Time} + * @name windowSize + * @example + * pitchShift.windowSize = 0.1; + */ + Object.defineProperty(Tone.PitchShift.prototype, 'windowSize', { + get: function () { + return this._windowSize; + }, + set: function (size) { + this._windowSize = this.toSeconds(size); + this.pitch = this._pitch; + } + }); + /** + * Clean up. + * @return {Tone.PitchShift} this + */ + Tone.PitchShift.prototype.dispose = function () { + Tone.FeedbackEffect.prototype.dispose.call(this); + this._frequency.dispose(); + this._frequency = null; + this._delayA.disconnect(); + this._delayA = null; + this._delayB.disconnect(); + this._delayB = null; + this._lfoA.dispose(); + this._lfoA = null; + this._lfoB.dispose(); + this._lfoB = null; + this._crossFade.dispose(); + this._crossFade = null; + this._crossFadeLFO.dispose(); + this._crossFadeLFO = null; + this._writable('delayTime'); + this._feedbackDelay.dispose(); + this._feedbackDelay = null; + this.delayTime = null; + return this; + }; + return Tone.PitchShift; + }); + Module(function (Tone) { + /** + * @class Wrapper around the native BufferSourceNode. + * @extends {Tone.AudioNode} + * @param {AudioBuffer|Tone.Buffer} buffer The buffer to play + * @param {Function} onload The callback to invoke when the + * buffer is done playing. + */ + Tone.BufferSource = function () { + var options = Tone.defaults(arguments, [ + 'buffer', + 'onload' + ], Tone.BufferSource); + Tone.AudioNode.call(this, options); + /** + * The callback to invoke after the + * buffer source is done playing. + * @type {Function} + */ + this.onended = options.onended; + /** + * The time that the buffer was started. + * @type {Number} + * @private + */ + this._startTime = -1; + /** + * An additional flag if the actual BufferSourceNode + * has been started. b/c stopping an unstarted buffer + * will throw it into an invalid state + * @type {Boolean} + * @private + */ + this._sourceStarted = false; + /** + * Flag if the source has already been stopped + * @type {Boolean} + * @private + */ + this._sourceStopped = false; + /** + * The time that the buffer is scheduled to stop. + * @type {Number} + * @private + */ + this._stopTime = -1; + /** + * The gain node which envelopes the BufferSource + * @type {Tone.Gain} + * @private + */ + this._gainNode = this.output = new Tone.Gain(); + /** + * The buffer source + * @type {AudioBufferSourceNode} + * @private + */ + this._source = this.context.createBufferSource(); + this._source.connect(this._gainNode); + this._source.onended = this._onended.bind(this); + /** + * The private buffer instance + * @type {Tone.Buffer} + * @private + */ + this._buffer = new Tone.Buffer(options.buffer, options.onload); + /** + * The playbackRate of the buffer + * @type {Positive} + * @signal + */ + this.playbackRate = new Tone.Param(this._source.playbackRate, Tone.Type.Positive); + /** + * The fadeIn time of the amplitude envelope. + * @type {Time} + */ + this.fadeIn = options.fadeIn; + /** + * The fadeOut time of the amplitude envelope. + * @type {Time} + */ + this.fadeOut = options.fadeOut; + /** + * The curve applied to the fades, either "linear" or "exponential" + * @type {String} + */ + this.curve = options.curve; + /** + * The value that the buffer ramps to + * @type {Gain} + * @private + */ + this._gain = 1; + /** + * The onended timeout + * @type {Number} + * @private + */ + this._onendedTimeout = -1; + //set some values initially + this.loop = options.loop; + this.loopStart = options.loopStart; + this.loopEnd = options.loopEnd; + this.playbackRate.value = options.playbackRate; + }; + Tone.extend(Tone.BufferSource, Tone.AudioNode); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.BufferSource.defaults = { + 'onended': Tone.noOp, + 'onload': Tone.noOp, + 'loop': false, + 'loopStart': 0, + 'loopEnd': 0, + 'fadeIn': 0, + 'fadeOut': 0, + 'curve': 'linear', + 'playbackRate': 1 + }; + /** + * Returns the playback state of the source, either "started" or "stopped". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.BufferSource# + * @name state + */ + Object.defineProperty(Tone.BufferSource.prototype, 'state', { + get: function () { + return this.getStateAtTime(this.now()); + } + }); + /** + * Get the playback state at the given time + * @param {Time} time The time to test the state at + * @return {Tone.State} The playback state. + */ + Tone.BufferSource.prototype.getStateAtTime = function (time) { + time = this.toSeconds(time); + if (this._startTime !== -1 && time >= this._startTime && !this._sourceStopped) { + return Tone.State.Started; + } else { + return Tone.State.Stopped; + } + }; + /** + * Start the buffer + * @param {Time} [startTime=now] When the player should start. + * @param {Time} [offset=0] The offset from the beginning of the sample + * to start at. + * @param {Time=} duration How long the sample should play. If no duration + * is given, it will default to the full length + * of the sample (minus any offset) + * @param {Gain} [gain=1] The gain to play the buffer back at. + * @param {Time=} fadeInTime The optional fadeIn ramp time. + * @return {Tone.BufferSource} this + */ + Tone.BufferSource.prototype.start = function (time, offset, duration, gain, fadeInTime) { + if (this._startTime !== -1) { + throw new Error('Tone.BufferSource can only be started once.'); + } + if (!this.buffer.loaded) { + throw new Error('Tone.BufferSource: buffer is either not set or not loaded.'); + } + time = this.toSeconds(time); + //if it's a loop the default offset is the loopstart point + if (this.loop) { + offset = Tone.defaultArg(offset, this.loopStart); + } else { + //otherwise the default offset is 0 + offset = Tone.defaultArg(offset, 0); + } + offset = this.toSeconds(offset); + gain = Tone.defaultArg(gain, 1); + this._gain = gain; + fadeInTime = this.toSeconds(Tone.defaultArg(fadeInTime, this.fadeIn)); + this.fadeIn = fadeInTime; + if (fadeInTime > 0) { + this._gainNode.gain.setValueAtTime(0, time); + if (this.curve === 'linear') { + this._gainNode.gain.linearRampToValueAtTime(this._gain, time + fadeInTime); + } else { + this._gainNode.gain.exponentialApproachValueAtTime(this._gain, time, fadeInTime); + } + } else { + this._gainNode.gain.setValueAtTime(gain, time); + } + this._startTime = time; + var computedDur = this.toSeconds(Tone.defaultArg(duration, this.buffer.duration - offset % this.buffer.duration)); + computedDur = Math.max(computedDur, 0); + if (Tone.isDefined(duration)) { + //clip the duration when not looping + if (!this.loop) { + computedDur = Math.min(computedDur, this.buffer.duration - offset % this.buffer.duration); + } + this.stop(time + computedDur, this.fadeOut); + } + //start the buffer source + if (this.loop) { + //modify the offset if it's greater than the loop time + var loopEnd = this.loopEnd || this.buffer.duration; + var loopStart = this.loopStart; + var loopDuration = loopEnd - loopStart; + //move the offset back + if (offset >= loopEnd) { + offset = (offset - loopStart) % loopDuration + loopStart; + } + } + this._source.buffer = this.buffer.get(); + this._source.loopEnd = this.loopEnd || this.buffer.duration; + if (offset < this.buffer.duration) { + this._sourceStarted = true; + this._source.start(time, offset); + } + return this; + }; + /** + * Stop the buffer. Optionally add a ramp time to fade the + * buffer out. + * @param {Time=} time The time the buffer should stop. + * @param {Time=} fadeOutTime How long the gain should fade out for + * @return {Tone.BufferSource} this + */ + Tone.BufferSource.prototype.stop = function (time, fadeOutTime) { + if (!this.buffer.loaded) { + throw new Error('Tone.BufferSource: buffer is either not set or not loaded.'); + } + if (this._sourceStopped) { + return; + } + time = this.toSeconds(time); + //if the event has already been scheduled, clear it + if (this._stopTime !== -1) { + this.cancelStop(); + } + //stop if it's schedule before the start time + if (time <= this._startTime) { + this._gainNode.gain.cancelScheduledValues(time); + this._gainNode.gain.value = 0; + return this; + } + time = Math.max(this._startTime + this.fadeIn + this.sampleTime, time); + //cancel the previous curve + this._gainNode.gain.cancelScheduledValues(time); + this._stopTime = time; + //the fadeOut time + fadeOutTime = this.toSeconds(Tone.defaultArg(fadeOutTime, this.fadeOut)); + var heldDuration = time - this._startTime - this.fadeIn - this.sampleTime; + if (!this.loop) { + //make sure the fade does not go beyond the length of the buffer + heldDuration = Math.min(heldDuration, this.buffer.duration); + } + fadeOutTime = Math.min(heldDuration, fadeOutTime); + var startFade = time - fadeOutTime; + if (fadeOutTime > this.sampleTime) { + this._gainNode.gain.setValueAtTime(this._gain, startFade); + if (this.curve === 'linear') { + this._gainNode.gain.linearRampToValueAtTime(0, time); + } else { + this._gainNode.gain.exponentialApproachValueAtTime(0, startFade, fadeOutTime); + } + } else { + this._gainNode.gain.setValueAtTime(0, time); + } + Tone.context.clearTimeout(this._onendedTimeout); + this._onendedTimeout = Tone.context.setTimeout(this._onended.bind(this), this._stopTime - this.now()); + return this; + }; + /** + * Cancel a scheduled stop event + * @return {Tone.BufferSource} this + */ + Tone.BufferSource.prototype.cancelStop = function () { + if (this._startTime !== -1 && !this._sourceStopped) { + //cancel the stop envelope + var fadeInTime = this.toSeconds(this.fadeIn); + this._gainNode.gain.cancelScheduledValues(this._startTime + fadeInTime + this.sampleTime); + this._gainNode.gain.setValueAtTime(1, Math.max(this.now(), this._startTime + fadeInTime + this.sampleTime)); + this.context.clearTimeout(this._onendedTimeout); + this._stopTime = -1; + } + return this; + }; + /** + * Internal callback when the buffer is ended. + * Invokes `onended` and disposes the node. + * @private + */ + Tone.BufferSource.prototype._onended = function () { + if (!this._sourceStopped) { + this._sourceStopped = true; + //allow additional time for the exponential curve to fully decay + var additionalTail = this.curve === 'exponential' ? this.fadeOut * 2 : 0; + if (this._sourceStarted && this._stopTime !== -1) { + this._source.stop(this._stopTime + additionalTail); + } + this.onended(this); + } + }; + /** + * If loop is true, the loop will start at this position. + * @memberOf Tone.BufferSource# + * @type {Time} + * @name loopStart + */ + Object.defineProperty(Tone.BufferSource.prototype, 'loopStart', { + get: function () { + return this._source.loopStart; + }, + set: function (loopStart) { + this._source.loopStart = this.toSeconds(loopStart); + } + }); + /** + * If loop is true, the loop will end at this position. + * @memberOf Tone.BufferSource# + * @type {Time} + * @name loopEnd + */ + Object.defineProperty(Tone.BufferSource.prototype, 'loopEnd', { + get: function () { + return this._source.loopEnd; + }, + set: function (loopEnd) { + this._source.loopEnd = this.toSeconds(loopEnd); + } + }); + /** + * The audio buffer belonging to the player. + * @memberOf Tone.BufferSource# + * @type {Tone.Buffer} + * @name buffer + */ + Object.defineProperty(Tone.BufferSource.prototype, 'buffer', { + get: function () { + return this._buffer; + }, + set: function (buffer) { + this._buffer.set(buffer); + } + }); + /** + * If the buffer should loop once it's over. + * @memberOf Tone.BufferSource# + * @type {Boolean} + * @name loop + */ + Object.defineProperty(Tone.BufferSource.prototype, 'loop', { + get: function () { + return this._source.loop; + }, + set: function (loop) { + this._source.loop = loop; + this.cancelStop(); + } + }); + /** + * Clean up. + * @return {Tone.BufferSource} this + */ + Tone.BufferSource.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this.onended = null; + this._source.onended = null; + this._source.disconnect(); + this._source = null; + this._gainNode.dispose(); + this._gainNode = null; + this._buffer.dispose(); + this._buffer = null; + this._startTime = -1; + this.playbackRate = null; + Tone.context.clearTimeout(this._onendedTimeout); + return this; + }; + return Tone.BufferSource; + }); + Module(function (Tone) { + + /** + * @class Tone.Noise is a noise generator. It uses looped noise buffers to save on performance. + * Tone.Noise supports the noise types: "pink", "white", and "brown". Read more about + * colors of noise on [Wikipedia](https://en.wikipedia.org/wiki/Colors_of_noise). + * + * @constructor + * @extends {Tone.Source} + * @param {string} type the noise type (white|pink|brown) + * @example + * //initialize the noise and start + * var noise = new Tone.Noise("pink").start(); + * + * //make an autofilter to shape the noise + * var autoFilter = new Tone.AutoFilter({ + * "frequency" : "8m", + * "min" : 800, + * "max" : 15000 + * }).connect(Tone.Master); + * + * //connect the noise + * noise.connect(autoFilter); + * //start the autofilter LFO + * autoFilter.start() + */ + Tone.Noise = function () { + var options = Tone.defaults(arguments, ['type'], Tone.Noise); + Tone.Source.call(this, options); + /** + * @private + * @type {AudioBufferSourceNode} + */ + this._source = null; + /** + * the buffer + * @private + * @type {AudioBuffer} + */ + this._type = options.type; + /** + * The playback rate of the noise. Affects + * the "frequency" of the noise. + * @type {Positive} + * @signal + */ + this._playbackRate = options.playbackRate; + }; + Tone.extend(Tone.Noise, Tone.Source); + /** + * the default parameters + * + * @static + * @const + * @type {Object} + */ + Tone.Noise.defaults = { + 'type': 'white', + 'playbackRate': 1 + }; + /** + * The type of the noise. Can be "white", "brown", or "pink". + * @memberOf Tone.Noise# + * @type {string} + * @name type + * @example + * noise.type = "white"; + */ + Object.defineProperty(Tone.Noise.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + if (this._type !== type) { + if (type in _noiseBuffers) { + this._type = type; + //if it's playing, stop and restart it + if (this.state === Tone.State.Started) { + var now = this.now(); + this._stop(now); + this._start(now); + } + } else { + throw new TypeError('Tone.Noise: invalid type: ' + type); + } + } + } + }); + /** + * The playback rate of the noise. Affects + * the "frequency" of the noise. + * @type {Positive} + * @signal + */ + Object.defineProperty(Tone.Noise.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + if (this._source) { + this._source.playbackRate.value = rate; + } + } + }); + /** + * internal start method + * + * @param {Time} time + * @private + */ + Tone.Noise.prototype._start = function (time) { + var buffer = _noiseBuffers[this._type]; + this._source = new Tone.BufferSource(buffer).connect(this.output); + this._source.loop = true; + this._source.playbackRate.value = this._playbackRate; + this._source.start(this.toSeconds(time), Math.random() * (buffer.duration - 0.001)); + }; + /** + * internal stop method + * + * @param {Time} time + * @private + */ + Tone.Noise.prototype._stop = function (time) { + if (this._source) { + this._source.stop(this.toSeconds(time)); + this._source = null; + } + }; + /** + * Restarts the noise. + * @param {[type]} time [description] + * @return {[type]} [description] + */ + Tone.Noise.prototype.restart = function (time) { + //TODO could be optimized by cancelling the buffer source 'stop' + //stop and restart + this._stop(time); + this._start(time); + }; + /** + * Clean up. + * @returns {Tone.Noise} this + */ + Tone.Noise.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + if (this._source !== null) { + this._source.disconnect(); + this._source = null; + } + this._buffer = null; + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // THE BUFFERS + /////////////////////////////////////////////////////////////////////////// + //Noise buffer stats + var bufferLength = 44100 * 5; + var channels = 2; + /** + * The noise arrays. Generated on initialization. + * borrowed heavily from https://github.com/zacharydenton/noise.js + * (c) 2013 Zach Denton (MIT) + * @static + * @private + * @type {Array} + */ + var _noiseArrays = { + 'pink': function () { + var buffer = []; + for (var channelNum = 0; channelNum < channels; channelNum++) { + var channel = new Float32Array(bufferLength); + buffer[channelNum] = channel; + var b0, b1, b2, b3, b4, b5, b6; + b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0; + for (var i = 0; i < bufferLength; i++) { + var white = Math.random() * 2 - 1; + b0 = 0.99886 * b0 + white * 0.0555179; + b1 = 0.99332 * b1 + white * 0.0750759; + b2 = 0.969 * b2 + white * 0.153852; + b3 = 0.8665 * b3 + white * 0.3104856; + b4 = 0.55 * b4 + white * 0.5329522; + b5 = -0.7616 * b5 - white * 0.016898; + channel[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362; + channel[i] *= 0.11; + // (roughly) compensate for gain + b6 = white * 0.115926; + } + } + return buffer; + }(), + 'brown': function () { + var buffer = []; + for (var channelNum = 0; channelNum < channels; channelNum++) { + var channel = new Float32Array(bufferLength); + buffer[channelNum] = channel; + var lastOut = 0; + for (var i = 0; i < bufferLength; i++) { + var white = Math.random() * 2 - 1; + channel[i] = (lastOut + 0.02 * white) / 1.02; + lastOut = channel[i]; + channel[i] *= 3.5; // (roughly) compensate for gain + } + } + return buffer; + }(), + 'white': function () { + var buffer = []; + for (var channelNum = 0; channelNum < channels; channelNum++) { + var channel = new Float32Array(bufferLength); + buffer[channelNum] = channel; + for (var i = 0; i < bufferLength; i++) { + channel[i] = Math.random() * 2 - 1; + } + } + return buffer; + }() + }; + /** + * static noise buffers + * @static + * @private + * @type {Tone.Buffer} + */ + var _noiseBuffers = {}; + //create the Tone.Buffers + function createBuffers() { + for (var type in _noiseArrays) { + _noiseBuffers[type] = new Tone.Buffer().fromArray(_noiseArrays[type]); + } + } + //create the noise buffers + Tone.getContext(createBuffers); + Tone.Context.on('init', createBuffers); + return Tone.Noise; + }); + Module(function (Tone) { + + /** + * @class Simple convolution created with decaying noise. + * Generates an Impulse Response Buffer + * with Tone.Offline then feeds the IR into ConvolverNode. + * Note: the Reverb will not make any sound until [generate](#generate) + * has been invoked and resolved. + * + * Inspiration from [ReverbGen](https://github.com/adelespinasse/reverbGen). + * Copyright (c) 2014 Alan deLespinasse Apache 2.0 License. + * + * @extends {Tone.Convolver} + * @param {Time=} decay The amount of time it will reverberate for. + */ + Tone.Reverb = function () { + var options = Tone.defaults(arguments, ['decay'], Tone.Reverb); + Tone.Effect.call(this, options); + /** + * Convolver node + * @type {ConvolverNode} + * @private + */ + this._convolver = this.context.createConvolver(); + /** + * The duration of the reverb + * @type {Time} + */ + this.decay = options.decay; + /** + * The amount of time before the reverb is fully + * ramped in. + * @type {Time} + */ + this.preDelay = options.preDelay; + this.connectEffect(this._convolver); + }; + Tone.extend(Tone.Reverb, Tone.Effect); + /** + * The defaults + * @type {Object} + * @static + */ + Tone.Reverb.defaults = { + 'decay': 1.5, + 'preDelay': 0.01 + }; + /** + * Generate the Impulse Response. Returns a promise while the IR is being + * generated. + * @return {Promise<Tone.Reverb>} Promise which returns this object. + */ + Tone.Reverb.prototype.generate = function () { + return Tone.Offline(function () { + //create a noise burst which decays over the duration + var noiseL = new Tone.Noise(); + var noiseR = new Tone.Noise(); + var merge = new Tone.Merge(); + noiseL.connect(merge.left); + noiseR.connect(merge.right); + var gainNode = new Tone.Gain().toMaster(); + merge.connect(gainNode); + noiseL.start(0); + noiseR.start(0); + //short fade in + gainNode.gain.setValueAtTime(0, 0); + gainNode.gain.linearRampToValueAtTime(1, this.preDelay); + //decay + gainNode.gain.exponentialApproachValueAtTime(0, this.preDelay, this.decay - this.preDelay); + }.bind(this), this.decay).then(function (buffer) { + this._convolver.buffer = buffer.get(); + return this; + }.bind(this)); + }; + /** + * Clean up. + * @return {Tone.Reverb} this + */ + Tone.Reverb.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._convolver.disconnect(); + this._convolver = null; + return this; + }; + return Tone.Reverb; + }); + Module(function (Tone) { + + /** + * @class Base class for stereo feedback effects where the effectReturn + * is fed back into the same channel. + * + * @constructor + * @extends {Tone.StereoEffect} + */ + Tone.StereoFeedbackEffect = function () { + var options = Tone.defaults(arguments, ['feedback'], Tone.FeedbackEffect); + Tone.StereoEffect.call(this, options); + /** + * controls the amount of feedback + * @type {NormalRange} + * @signal + */ + this.feedback = new Tone.Signal(options.feedback, Tone.Type.NormalRange); + /** + * the left side feeback + * @type {Tone.Gain} + * @private + */ + this._feedbackL = new Tone.Gain(); + /** + * the right side feeback + * @type {Tone.Gain} + * @private + */ + this._feedbackR = new Tone.Gain(); + //connect it up + this.effectReturnL.chain(this._feedbackL, this.effectSendL); + this.effectReturnR.chain(this._feedbackR, this.effectSendR); + this.feedback.fan(this._feedbackL.gain, this._feedbackR.gain); + this._readOnly(['feedback']); + }; + Tone.extend(Tone.StereoFeedbackEffect, Tone.StereoEffect); + /** + * clean up + * @returns {Tone.StereoFeedbackEffect} this + */ + Tone.StereoFeedbackEffect.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._writable(['feedback']); + this.feedback.dispose(); + this.feedback = null; + this._feedbackL.dispose(); + this._feedbackL = null; + this._feedbackR.dispose(); + this._feedbackR = null; + return this; + }; + return Tone.StereoFeedbackEffect; + }); + Module(function (Tone) { + + /** + * @class Applies a width factor to the mid/side seperation. + * 0 is all mid and 1 is all side. + * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587). + * <br><br> + * <code> + * Mid *= 2*(1-width)<br> + * Side *= 2*width + * </code> + * + * @extends {Tone.MidSideEffect} + * @constructor + * @param {NormalRange|Object} [width] The stereo width. A width of 0 is mono and 1 is stereo. 0.5 is no change. + */ + Tone.StereoWidener = function () { + var options = Tone.defaults(arguments, ['width'], Tone.StereoWidener); + Tone.MidSideEffect.call(this, options); + /** + * The width control. 0 = 100% mid. 1 = 100% side. 0.5 = no change. + * @type {NormalRange} + * @signal + */ + this.width = new Tone.Signal(options.width, Tone.Type.NormalRange); + this._readOnly(['width']); + /** + * Two times the (1-width) for the mid channel + * @type {Tone.Multiply} + * @private + */ + this._twoTimesWidthMid = new Tone.Multiply(2); + /** + * Two times the width for the side channel + * @type {Tone.Multiply} + * @private + */ + this._twoTimesWidthSide = new Tone.Multiply(2); + /** + * Mid multiplier + * @type {Tone.Multiply} + * @private + */ + this._midMult = new Tone.Multiply(); + this._twoTimesWidthMid.connect(this._midMult, 0, 1); + this.midSend.chain(this._midMult, this.midReturn); + /** + * 1 - width + * @type {Tone} + */ + this._oneMinusWidth = new Tone.Subtract(); + this._oneMinusWidth.connect(this._twoTimesWidthMid); + this.context.getConstant(1).connect(this._oneMinusWidth, 0, 0); + this.width.connect(this._oneMinusWidth, 0, 1); + /** + * Side multiplier + * @type {Tone.Multiply} + * @private + */ + this._sideMult = new Tone.Multiply(); + this.width.connect(this._twoTimesWidthSide); + this._twoTimesWidthSide.connect(this._sideMult, 0, 1); + this.sideSend.chain(this._sideMult, this.sideReturn); + }; + Tone.extend(Tone.StereoWidener, Tone.MidSideEffect); + /** + * the default values + * @static + * @type {Object} + */ + Tone.StereoWidener.defaults = { 'width': 0.5 }; + /** + * Clean up. + * @returns {Tone.StereoWidener} this + */ + Tone.StereoWidener.prototype.dispose = function () { + Tone.MidSideEffect.prototype.dispose.call(this); + this._writable(['width']); + this.width.dispose(); + this.width = null; + this._midMult.dispose(); + this._midMult = null; + this._sideMult.dispose(); + this._sideMult = null; + this._twoTimesWidthMid.dispose(); + this._twoTimesWidthMid = null; + this._twoTimesWidthSide.dispose(); + this._twoTimesWidthSide = null; + this._oneMinusWidth.dispose(); + this._oneMinusWidth = null; + return this; + }; + return Tone.StereoWidener; + }); + Module(function (Tone) { + + /** + * @class Tone.Tremolo modulates the amplitude of an incoming signal using a Tone.LFO. + * The type, frequency, and depth of the LFO is controllable. + * + * @extends {Tone.StereoEffect} + * @constructor + * @param {Frequency} [frequency] The rate of the effect. + * @param {NormalRange} [depth] The depth of the effect. + * @example + * //create a tremolo and start it's LFO + * var tremolo = new Tone.Tremolo(9, 0.75).toMaster().start(); + * //route an oscillator through the tremolo and start it + * var oscillator = new Tone.Oscillator().connect(tremolo).start(); + */ + Tone.Tremolo = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'depth' + ], Tone.Tremolo); + Tone.StereoEffect.call(this, options); + /** + * The tremelo LFO in the left channel + * @type {Tone.LFO} + * @private + */ + this._lfoL = new Tone.LFO({ + 'phase': options.spread, + 'min': 1, + 'max': 0 + }); + /** + * The tremelo LFO in the left channel + * @type {Tone.LFO} + * @private + */ + this._lfoR = new Tone.LFO({ + 'phase': options.spread, + 'min': 1, + 'max': 0 + }); + /** + * Where the gain is multiplied + * @type {Tone.Gain} + * @private + */ + this._amplitudeL = new Tone.Gain(); + /** + * Where the gain is multiplied + * @type {Tone.Gain} + * @private + */ + this._amplitudeR = new Tone.Gain(); + /** + * The frequency of the tremolo. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The depth of the effect. A depth of 0, has no effect + * on the amplitude, and a depth of 1 makes the amplitude + * modulate fully between 0 and 1. + * @type {NormalRange} + * @signal + */ + this.depth = new Tone.Signal(options.depth, Tone.Type.NormalRange); + this._readOnly([ + 'frequency', + 'depth' + ]); + this.effectSendL.chain(this._amplitudeL, this.effectReturnL); + this.effectSendR.chain(this._amplitudeR, this.effectReturnR); + this._lfoL.connect(this._amplitudeL.gain); + this._lfoR.connect(this._amplitudeR.gain); + this.frequency.fan(this._lfoL.frequency, this._lfoR.frequency); + this.depth.fan(this._lfoR.amplitude, this._lfoL.amplitude); + this.type = options.type; + this.spread = options.spread; + }; + Tone.extend(Tone.Tremolo, Tone.StereoEffect); + /** + * @static + * @const + * @type {Object} + */ + Tone.Tremolo.defaults = { + 'frequency': 10, + 'type': 'sine', + 'depth': 0.5, + 'spread': 180 + }; + /** + * Start the tremolo. + * @param {Time} [time=now] When the tremolo begins. + * @returns {Tone.Tremolo} this + */ + Tone.Tremolo.prototype.start = function (time) { + this._lfoL.start(time); + this._lfoR.start(time); + return this; + }; + /** + * Stop the tremolo. + * @param {Time} [time=now] When the tremolo stops. + * @returns {Tone.Tremolo} this + */ + Tone.Tremolo.prototype.stop = function (time) { + this._lfoL.stop(time); + this._lfoR.stop(time); + return this; + }; + /** + * Sync the effect to the transport. + * @param {Time} [delay=0] Delay time before starting the effect after the + * Transport has started. + * @returns {Tone.AutoFilter} this + */ + Tone.Tremolo.prototype.sync = function (delay) { + this._lfoL.sync(delay); + this._lfoR.sync(delay); + Tone.Transport.syncSignal(this.frequency); + return this; + }; + /** + * Unsync the filter from the transport + * @returns {Tone.Tremolo} this + */ + Tone.Tremolo.prototype.unsync = function () { + this._lfoL.unsync(); + this._lfoR.unsync(); + Tone.Transport.unsyncSignal(this.frequency); + return this; + }; + /** + * The Tremolo's oscillator type. + * @memberOf Tone.Tremolo# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.Tremolo.prototype, 'type', { + get: function () { + return this._lfoL.type; + }, + set: function (type) { + this._lfoL.type = type; + this._lfoR.type = type; + } + }); + /** + * Amount of stereo spread. When set to 0, both LFO's will be panned centrally. + * When set to 180, LFO's will be panned hard left and right respectively. + * @memberOf Tone.Tremolo# + * @type {Degrees} + * @name spread + */ + Object.defineProperty(Tone.Tremolo.prototype, 'spread', { + get: function () { + return this._lfoR.phase - this._lfoL.phase; //180 + }, + set: function (spread) { + this._lfoL.phase = 90 - spread / 2; + this._lfoR.phase = spread / 2 + 90; + } + }); + /** + * clean up + * @returns {Tone.Tremolo} this + */ + Tone.Tremolo.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'depth' + ]); + this._lfoL.dispose(); + this._lfoL = null; + this._lfoR.dispose(); + this._lfoR = null; + this._amplitudeL.dispose(); + this._amplitudeL = null; + this._amplitudeR.dispose(); + this._amplitudeR = null; + this.frequency = null; + this.depth = null; + return this; + }; + return Tone.Tremolo; + }); + Module(function (Tone) { + + /** + * @class A Vibrato effect composed of a Tone.Delay and a Tone.LFO. The LFO + * modulates the delayTime of the delay, causing the pitch to rise + * and fall. + * @extends {Tone.Effect} + * @param {Frequency} frequency The frequency of the vibrato. + * @param {NormalRange} depth The amount the pitch is modulated. + */ + Tone.Vibrato = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'depth' + ], Tone.Vibrato); + Tone.Effect.call(this, options); + /** + * The delay node used for the vibrato effect + * @type {Tone.Delay} + * @private + */ + this._delayNode = new Tone.Delay(0, options.maxDelay); + /** + * The LFO used to control the vibrato + * @type {Tone.LFO} + * @private + */ + this._lfo = new Tone.LFO({ + 'type': options.type, + 'min': 0, + 'max': options.maxDelay, + 'frequency': options.frequency, + 'phase': -90 //offse the phase so the resting position is in the center + }).start().connect(this._delayNode.delayTime); + /** + * The frequency of the vibrato + * @type {Frequency} + * @signal + */ + this.frequency = this._lfo.frequency; + /** + * The depth of the vibrato. + * @type {NormalRange} + * @signal + */ + this.depth = this._lfo.amplitude; + this.depth.value = options.depth; + this._readOnly([ + 'frequency', + 'depth' + ]); + this.effectSend.chain(this._delayNode, this.effectReturn); + }; + Tone.extend(Tone.Vibrato, Tone.Effect); + /** + * The defaults + * @type {Object} + * @const + */ + Tone.Vibrato.defaults = { + 'maxDelay': 0.005, + 'frequency': 5, + 'depth': 0.1, + 'type': 'sine' + }; + /** + * Type of oscillator attached to the Vibrato. + * @memberOf Tone.Vibrato# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.Vibrato.prototype, 'type', { + get: function () { + return this._lfo.type; + }, + set: function (type) { + this._lfo.type = type; + } + }); + /** + * Clean up. + * @returns {Tone.Vibrato} this + */ + Tone.Vibrato.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._delayNode.dispose(); + this._delayNode = null; + this._lfo.dispose(); + this._lfo = null; + this._writable([ + 'frequency', + 'depth' + ]); + this.frequency = null; + this.depth = null; + }; + return Tone.Vibrato; + }); + Module(function (Tone) { + + /** + * @class Tone.Event abstracts away Tone.Transport.schedule and provides a schedulable + * callback for a single or repeatable events along the timeline. + * + * @extends {Tone} + * @param {function} callback The callback to invoke at the time. + * @param {*} value The value or values which should be passed to + * the callback function on invocation. + * @example + * var chord = new Tone.Event(function(time, chord){ + * //the chord as well as the exact time of the event + * //are passed in as arguments to the callback function + * }, ["D4", "E4", "F4"]); + * //start the chord at the beginning of the transport timeline + * chord.start(); + * //loop it every measure for 8 measures + * chord.loop = 8; + * chord.loopEnd = "1m"; + */ + Tone.Event = function () { + var options = Tone.defaults(arguments, [ + 'callback', + 'value' + ], Tone.Event); + Tone.call(this); + /** + * Loop value + * @type {Boolean|Positive} + * @private + */ + this._loop = options.loop; + /** + * The callback to invoke. + * @type {Function} + */ + this.callback = options.callback; + /** + * The value which is passed to the + * callback function. + * @type {*} + * @private + */ + this.value = options.value; + /** + * When the note is scheduled to start. + * @type {Number} + * @private + */ + this._loopStart = this.toTicks(options.loopStart); + /** + * When the note is scheduled to start. + * @type {Number} + * @private + */ + this._loopEnd = this.toTicks(options.loopEnd); + /** + * Tracks the scheduled events + * @type {Tone.TimelineState} + * @private + */ + this._state = new Tone.TimelineState(Tone.State.Stopped); + /** + * The playback speed of the note. A speed of 1 + * is no change. + * @private + * @type {Positive} + */ + this._playbackRate = 1; + /** + * A delay time from when the event is scheduled to start + * @type {Ticks} + * @private + */ + this._startOffset = 0; + /** + * private holder of probability value + * @type {NormalRange} + * @private + */ + this._probability = options.probability; + /** + * the amount of variation from the + * given time. + * @type {Boolean|Time} + * @private + */ + this._humanize = options.humanize; + /** + * If mute is true, the callback won't be + * invoked. + * @type {Boolean} + */ + this.mute = options.mute; + //set the initial values + this.playbackRate = options.playbackRate; + }; + Tone.extend(Tone.Event); + /** + * The default values + * @type {Object} + * @const + */ + Tone.Event.defaults = { + 'callback': Tone.noOp, + 'loop': false, + 'loopEnd': '1m', + 'loopStart': 0, + 'playbackRate': 1, + 'value': null, + 'probability': 1, + 'mute': false, + 'humanize': false + }; + /** + * Reschedule all of the events along the timeline + * with the updated values. + * @param {Time} after Only reschedules events after the given time. + * @return {Tone.Event} this + * @private + */ + Tone.Event.prototype._rescheduleEvents = function (after) { + //if no argument is given, schedules all of the events + after = Tone.defaultArg(after, -1); + this._state.forEachFrom(after, function (event) { + var duration; + if (event.state === Tone.State.Started) { + if (Tone.isDefined(event.id)) { + Tone.Transport.clear(event.id); + } + var startTick = event.time + Math.round(this.startOffset / this._playbackRate); + if (this._loop) { + duration = Infinity; + if (Tone.isNumber(this._loop)) { + duration = this._loop * this._getLoopDuration(); + } + var nextEvent = this._state.getAfter(startTick); + if (nextEvent !== null) { + duration = Math.min(duration, nextEvent.time - startTick); + } + if (duration !== Infinity) { + //schedule a stop since it's finite duration + this._state.setStateAtTime(Tone.State.Stopped, startTick + duration + 1); + duration = Tone.Ticks(duration); + } + var interval = Tone.Ticks(this._getLoopDuration()); + event.id = Tone.Transport.scheduleRepeat(this._tick.bind(this), interval, Tone.Ticks(startTick), duration); + } else { + event.id = Tone.Transport.schedule(this._tick.bind(this), Tone.Ticks(startTick)); + } + } + }.bind(this)); + return this; + }; + /** + * Returns the playback state of the note, either "started" or "stopped". + * @type {String} + * @readOnly + * @memberOf Tone.Event# + * @name state + */ + Object.defineProperty(Tone.Event.prototype, 'state', { + get: function () { + return this._state.getValueAtTime(Tone.Transport.ticks); + } + }); + /** + * The start from the scheduled start time + * @type {Ticks} + * @memberOf Tone.Event# + * @name startOffset + * @private + */ + Object.defineProperty(Tone.Event.prototype, 'startOffset', { + get: function () { + return this._startOffset; + }, + set: function (offset) { + this._startOffset = offset; + } + }); + /** + * The probability of the notes being triggered. + * @memberOf Tone.Event# + * @type {NormalRange} + * @name probability + */ + Object.defineProperty(Tone.Event.prototype, 'probability', { + get: function () { + return this._probability; + }, + set: function (prob) { + this._probability = prob; + } + }); + /** + * If set to true, will apply small random variation + * to the callback time. If the value is given as a time, it will randomize + * by that amount. + * @example + * event.humanize = true; + * @type {Boolean|Time} + * @name humanize + */ + Object.defineProperty(Tone.Event.prototype, 'humanize', { + get: function () { + return this._humanize; + }, + set: function (variation) { + this._humanize = variation; + } + }); + /** + * Start the note at the given time. + * @param {TimelinePosition} time When the note should start. + * @return {Tone.Event} this + */ + Tone.Event.prototype.start = function (time) { + time = this.toTicks(time); + if (this._state.getValueAtTime(time) === Tone.State.Stopped) { + this._state.add({ + 'state': Tone.State.Started, + 'time': time, + 'id': undefined + }); + this._rescheduleEvents(time); + } + return this; + }; + /** + * Stop the Event at the given time. + * @param {TimelinePosition} time When the note should stop. + * @return {Tone.Event} this + */ + Tone.Event.prototype.stop = function (time) { + this.cancel(time); + time = this.toTicks(time); + if (this._state.getValueAtTime(time) === Tone.State.Started) { + this._state.setStateAtTime(Tone.State.Stopped, time); + var previousEvent = this._state.getBefore(time); + var reschedulTime = time; + if (previousEvent !== null) { + reschedulTime = previousEvent.time; + } + this._rescheduleEvents(reschedulTime); + } + return this; + }; + /** + * Cancel all scheduled events greater than or equal to the given time + * @param {TimelinePosition} [time=0] The time after which events will be cancel. + * @return {Tone.Event} this + */ + Tone.Event.prototype.cancel = function (time) { + time = Tone.defaultArg(time, -Infinity); + time = this.toTicks(time); + this._state.forEachFrom(time, function (event) { + Tone.Transport.clear(event.id); + }); + this._state.cancel(time); + return this; + }; + /** + * The callback function invoker. Also + * checks if the Event is done playing + * @param {Number} time The time of the event in seconds + * @private + */ + Tone.Event.prototype._tick = function (time) { + var ticks = Tone.Transport.getTicksAtTime(time); + if (!this.mute && this._state.getValueAtTime(ticks) === Tone.State.Started) { + if (this.probability < 1 && Math.random() > this.probability) { + return; + } + if (this.humanize) { + var variation = 0.02; + if (!Tone.isBoolean(this.humanize)) { + variation = this.toSeconds(this.humanize); + } + time += (Math.random() * 2 - 1) * variation; + } + this.callback(time, this.value); + } + }; + /** + * Get the duration of the loop. + * @return {Ticks} + * @private + */ + Tone.Event.prototype._getLoopDuration = function () { + return Math.round((this._loopEnd - this._loopStart) / this._playbackRate); + }; + /** + * If the note should loop or not + * between Tone.Event.loopStart and + * Tone.Event.loopEnd. An integer + * value corresponds to the number of + * loops the Event does after it starts. + * @memberOf Tone.Event# + * @type {Boolean|Positive} + * @name loop + */ + Object.defineProperty(Tone.Event.prototype, 'loop', { + get: function () { + return this._loop; + }, + set: function (loop) { + this._loop = loop; + this._rescheduleEvents(); + } + }); + /** + * The playback rate of the note. Defaults to 1. + * @memberOf Tone.Event# + * @type {Positive} + * @name playbackRate + * @example + * note.loop = true; + * //repeat the note twice as fast + * note.playbackRate = 2; + */ + Object.defineProperty(Tone.Event.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + this._rescheduleEvents(); + } + }); + /** + * The loopEnd point is the time the event will loop + * if Tone.Event.loop is true. + * @memberOf Tone.Event# + * @type {Time} + * @name loopEnd + */ + Object.defineProperty(Tone.Event.prototype, 'loopEnd', { + get: function () { + return Tone.Ticks(this._loopEnd).toSeconds(); + }, + set: function (loopEnd) { + this._loopEnd = this.toTicks(loopEnd); + if (this._loop) { + this._rescheduleEvents(); + } + } + }); + /** + * The time when the loop should start. + * @memberOf Tone.Event# + * @type {Time} + * @name loopStart + */ + Object.defineProperty(Tone.Event.prototype, 'loopStart', { + get: function () { + return Tone.Ticks(this._loopStart).toSeconds(); + }, + set: function (loopStart) { + this._loopStart = this.toTicks(loopStart); + if (this._loop) { + this._rescheduleEvents(); + } + } + }); + /** + * The current progress of the loop interval. + * Returns 0 if the event is not started yet or + * it is not set to loop. + * @memberOf Tone.Event# + * @type {NormalRange} + * @name progress + * @readOnly + */ + Object.defineProperty(Tone.Event.prototype, 'progress', { + get: function () { + if (this._loop) { + var ticks = Tone.Transport.ticks; + var lastEvent = this._state.get(ticks); + if (lastEvent !== null && lastEvent.state === Tone.State.Started) { + var loopDuration = this._getLoopDuration(); + var progress = (ticks - lastEvent.time) % loopDuration; + return progress / loopDuration; + } else { + return 0; + } + } else { + return 0; + } + } + }); + /** + * Clean up + * @return {Tone.Event} this + */ + Tone.Event.prototype.dispose = function () { + this.cancel(); + this._state.dispose(); + this._state = null; + this.callback = null; + this.value = null; + }; + return Tone.Event; + }); + Module(function (Tone) { + /** + * @class Tone.Loop creates a looped callback at the + * specified interval. The callback can be + * started, stopped and scheduled along + * the Transport's timeline. + * @example + * var loop = new Tone.Loop(function(time){ + * //triggered every eighth note. + * console.log(time); + * }, "8n").start(0); + * Tone.Transport.start(); + * @extends {Tone} + * @param {Function} callback The callback to invoke with the event. + * @param {Time} interval The time between successive callback calls. + */ + Tone.Loop = function () { + var options = Tone.defaults(arguments, [ + 'callback', + 'interval' + ], Tone.Loop); + Tone.call(this); + /** + * The event which produces the callbacks + */ + this._event = new Tone.Event({ + 'callback': this._tick.bind(this), + 'loop': true, + 'loopEnd': options.interval, + 'playbackRate': options.playbackRate, + 'probability': options.probability + }); + /** + * The callback to invoke with the next event in the pattern + * @type {Function} + */ + this.callback = options.callback; + //set the iterations + this.iterations = options.iterations; + }; + Tone.extend(Tone.Loop); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Loop.defaults = { + 'interval': '4n', + 'callback': Tone.noOp, + 'playbackRate': 1, + 'iterations': Infinity, + 'probability': true, + 'mute': false + }; + /** + * Start the loop at the specified time along the Transport's + * timeline. + * @param {TimelinePosition=} time When to start the Loop. + * @return {Tone.Loop} this + */ + Tone.Loop.prototype.start = function (time) { + this._event.start(time); + return this; + }; + /** + * Stop the loop at the given time. + * @param {TimelinePosition=} time When to stop the Arpeggio + * @return {Tone.Loop} this + */ + Tone.Loop.prototype.stop = function (time) { + this._event.stop(time); + return this; + }; + /** + * Cancel all scheduled events greater than or equal to the given time + * @param {TimelinePosition} [time=0] The time after which events will be cancel. + * @return {Tone.Loop} this + */ + Tone.Loop.prototype.cancel = function (time) { + this._event.cancel(time); + return this; + }; + /** + * Internal function called when the notes should be called + * @param {Number} time The time the event occurs + * @private + */ + Tone.Loop.prototype._tick = function (time) { + this.callback(time); + }; + /** + * The state of the Loop, either started or stopped. + * @memberOf Tone.Loop# + * @type {String} + * @name state + * @readOnly + */ + Object.defineProperty(Tone.Loop.prototype, 'state', { + get: function () { + return this._event.state; + } + }); + /** + * The progress of the loop as a value between 0-1. 0, when + * the loop is stopped or done iterating. + * @memberOf Tone.Loop# + * @type {NormalRange} + * @name progress + * @readOnly + */ + Object.defineProperty(Tone.Loop.prototype, 'progress', { + get: function () { + return this._event.progress; + } + }); + /** + * The time between successive callbacks. + * @example + * loop.interval = "8n"; //loop every 8n + * @memberOf Tone.Loop# + * @type {Time} + * @name interval + */ + Object.defineProperty(Tone.Loop.prototype, 'interval', { + get: function () { + return this._event.loopEnd; + }, + set: function (interval) { + this._event.loopEnd = interval; + } + }); + /** + * The playback rate of the loop. The normal playback rate is 1 (no change). + * A `playbackRate` of 2 would be twice as fast. + * @memberOf Tone.Loop# + * @type {Time} + * @name playbackRate + */ + Object.defineProperty(Tone.Loop.prototype, 'playbackRate', { + get: function () { + return this._event.playbackRate; + }, + set: function (rate) { + this._event.playbackRate = rate; + } + }); + /** + * Random variation +/-0.01s to the scheduled time. + * Or give it a time value which it will randomize by. + * @type {Boolean|Time} + * @memberOf Tone.Loop# + * @name humanize + */ + Object.defineProperty(Tone.Loop.prototype, 'humanize', { + get: function () { + return this._event.humanize; + }, + set: function (variation) { + this._event.humanize = variation; + } + }); + /** + * The probably of the callback being invoked. + * @memberOf Tone.Loop# + * @type {NormalRange} + * @name probability + */ + Object.defineProperty(Tone.Loop.prototype, 'probability', { + get: function () { + return this._event.probability; + }, + set: function (prob) { + this._event.probability = prob; + } + }); + /** + * Muting the Loop means that no callbacks are invoked. + * @memberOf Tone.Loop# + * @type {Boolean} + * @name mute + */ + Object.defineProperty(Tone.Loop.prototype, 'mute', { + get: function () { + return this._event.mute; + }, + set: function (mute) { + this._event.mute = mute; + } + }); + /** + * The number of iterations of the loop. The default + * value is Infinity (loop forever). + * @memberOf Tone.Loop# + * @type {Positive} + * @name iterations + */ + Object.defineProperty(Tone.Loop.prototype, 'iterations', { + get: function () { + if (this._event.loop === true) { + return Infinity; + } else { + return this._event.loop; + } + }, + set: function (iters) { + if (iters === Infinity) { + this._event.loop = true; + } else { + this._event.loop = iters; + } + } + }); + /** + * Clean up + * @return {Tone.Loop} this + */ + Tone.Loop.prototype.dispose = function () { + this._event.dispose(); + this._event = null; + this.callback = null; + }; + return Tone.Loop; + }); + Module(function (Tone) { + + /** + * @class Tone.Part is a collection Tone.Events which can be + * started/stopped and looped as a single unit. + * + * @extends {Tone.Event} + * @param {Function} callback The callback to invoke on each event + * @param {Array} events the array of events + * @example + * var part = new Tone.Part(function(time, note){ + * //the notes given as the second element in the array + * //will be passed in as the second argument + * synth.triggerAttackRelease(note, "8n", time); + * }, [[0, "C2"], ["0:2", "C3"], ["0:3:2", "G2"]]); + * @example + * //use an array of objects as long as the object has a "time" attribute + * var part = new Tone.Part(function(time, value){ + * //the value is an object which contains both the note and the velocity + * synth.triggerAttackRelease(value.note, "8n", time, value.velocity); + * }, [{"time" : 0, "note" : "C3", "velocity": 0.9}, + * {"time" : "0:2", "note" : "C4", "velocity": 0.5} + * ]).start(0); + */ + Tone.Part = function () { + var options = Tone.defaults(arguments, [ + 'callback', + 'events' + ], Tone.Part); + Tone.Event.call(this, options); + /** + * An array of Objects. + * @type {Array} + * @private + */ + this._events = []; + //add the events + for (var i = 0; i < options.events.length; i++) { + if (Array.isArray(options.events[i])) { + this.add(options.events[i][0], options.events[i][1]); + } else { + this.add(options.events[i]); + } + } + }; + Tone.extend(Tone.Part, Tone.Event); + /** + * The default values + * @type {Object} + * @const + */ + Tone.Part.defaults = { + 'callback': Tone.noOp, + 'loop': false, + 'loopEnd': '1m', + 'loopStart': 0, + 'playbackRate': 1, + 'probability': 1, + 'humanize': false, + 'mute': false, + 'events': [] + }; + /** + * Start the part at the given time. + * @param {TransportTime} time When to start the part. + * @param {Time=} offset The offset from the start of the part + * to begin playing at. + * @return {Tone.Part} this + */ + Tone.Part.prototype.start = function (time, offset) { + var ticks = this.toTicks(time); + if (this._state.getValueAtTime(ticks) !== Tone.State.Started) { + if (this._loop) { + offset = Tone.defaultArg(offset, this._loopStart); + } else { + offset = Tone.defaultArg(offset, 0); + } + offset = this.toTicks(offset); + this._state.add({ + 'state': Tone.State.Started, + 'time': ticks, + 'offset': offset + }); + this._forEach(function (event) { + this._startNote(event, ticks, offset); + }); + } + return this; + }; + /** + * Start the event in the given event at the correct time given + * the ticks and offset and looping. + * @param {Tone.Event} event + * @param {Ticks} ticks + * @param {Ticks} offset + * @private + */ + Tone.Part.prototype._startNote = function (event, ticks, offset) { + ticks -= offset; + if (this._loop) { + if (event.startOffset >= this._loopStart && event.startOffset < this._loopEnd) { + if (event.startOffset < offset) { + //start it on the next loop + ticks += this._getLoopDuration(); + } + event.start(Tone.Ticks(ticks)); + } else if (event.startOffset < this._loopStart && event.startOffset >= offset) { + event.loop = false; + event.start(Tone.Ticks(ticks)); + } + } else if (event.startOffset >= offset) { + event.start(Tone.Ticks(ticks)); + } + }; + /** + * The start from the scheduled start time + * @type {Ticks} + * @memberOf Tone.Part# + * @name startOffset + * @private + */ + Object.defineProperty(Tone.Part.prototype, 'startOffset', { + get: function () { + return this._startOffset; + }, + set: function (offset) { + this._startOffset = offset; + this._forEach(function (event) { + event.startOffset += this._startOffset; + }); + } + }); + /** + * Stop the part at the given time. + * @param {TimelinePosition} time When to stop the part. + * @return {Tone.Part} this + */ + Tone.Part.prototype.stop = function (time) { + var ticks = this.toTicks(time); + this._state.cancel(ticks); + this._state.setStateAtTime(Tone.State.Stopped, ticks); + this._forEach(function (event) { + event.stop(time); + }); + return this; + }; + /** + * Get/Set an Event's value at the given time. + * If a value is passed in and no event exists at + * the given time, one will be created with that value. + * If two events are at the same time, the first one will + * be returned. + * @example + * part.at("1m"); //returns the part at the first measure + * + * part.at("2m", "C2"); //set the value at "2m" to C2. + * //if an event didn't exist at that time, it will be created. + * @param {TransportTime} time The time of the event to get or set. + * @param {*=} value If a value is passed in, the value of the + * event at the given time will be set to it. + * @return {Tone.Event} the event at the time + */ + Tone.Part.prototype.at = function (time, value) { + time = Tone.TransportTime(time); + var tickTime = Tone.Ticks(1).toSeconds(); + for (var i = 0; i < this._events.length; i++) { + var event = this._events[i]; + if (Math.abs(time.toTicks() - event.startOffset) < tickTime) { + if (Tone.isDefined(value)) { + event.value = value; + } + return event; + } + } + //if there was no event at that time, create one + if (Tone.isDefined(value)) { + this.add(time, value); + //return the new event + return this._events[this._events.length - 1]; + } else { + return null; + } + }; + /** + * Add a an event to the part. + * @param {Time} time The time the note should start. + * If an object is passed in, it should + * have a 'time' attribute and the rest + * of the object will be used as the 'value'. + * @param {Tone.Event|*} value + * @returns {Tone.Part} this + * @example + * part.add("1m", "C#+11"); + */ + Tone.Part.prototype.add = function (time, value) { + //extract the parameters + if (time.hasOwnProperty('time')) { + value = time; + time = value.time; + } + time = this.toTicks(time); + var event; + if (value instanceof Tone.Event) { + event = value; + event.callback = this._tick.bind(this); + } else { + event = new Tone.Event({ + 'callback': this._tick.bind(this), + 'value': value + }); + } + //the start offset + event.startOffset = time; + //initialize the values + event.set({ + 'loopEnd': this.loopEnd, + 'loopStart': this.loopStart, + 'loop': this.loop, + 'humanize': this.humanize, + 'playbackRate': this.playbackRate, + 'probability': this.probability + }); + this._events.push(event); + //start the note if it should be played right now + this._restartEvent(event); + return this; + }; + /** + * Restart the given event + * @param {Tone.Event} event + * @private + */ + Tone.Part.prototype._restartEvent = function (event) { + this._state.forEach(function (stateEvent) { + if (stateEvent.state === Tone.State.Started) { + this._startNote(event, stateEvent.time, stateEvent.offset); + } else { + //stop the note + event.stop(Tone.Ticks(stateEvent.time)); + } + }.bind(this)); + }; + /** + * Remove an event from the part. Will recursively iterate + * into nested parts to find the event. + * @param {Time} time The time of the event + * @param {*} value Optionally select only a specific event value + * @return {Tone.Part} this + */ + Tone.Part.prototype.remove = function (time, value) { + //extract the parameters + if (time.hasOwnProperty('time')) { + value = time; + time = value.time; + } + time = this.toTicks(time); + for (var i = this._events.length - 1; i >= 0; i--) { + var event = this._events[i]; + if (event instanceof Tone.Part) { + event.remove(time, value); + } else if (event.startOffset === time) { + if (Tone.isUndef(value) || Tone.isDefined(value) && event.value === value) { + this._events.splice(i, 1); + event.dispose(); + } + } + } + return this; + }; + /** + * Remove all of the notes from the group. + * @return {Tone.Part} this + */ + Tone.Part.prototype.removeAll = function () { + this._forEach(function (event) { + event.dispose(); + }); + this._events = []; + return this; + }; + /** + * Cancel scheduled state change events: i.e. "start" and "stop". + * @param {TimelinePosition} after The time after which to cancel the scheduled events. + * @return {Tone.Part} this + */ + Tone.Part.prototype.cancel = function (after) { + this._forEach(function (event) { + event.cancel(after); + }); + this._state.cancel(this.toTicks(after)); + return this; + }; + /** + * Iterate over all of the events + * @param {Function} callback + * @param {Object} ctx The context + * @private + */ + Tone.Part.prototype._forEach = function (callback, ctx) { + if (this._events) { + ctx = Tone.defaultArg(ctx, this); + for (var i = this._events.length - 1; i >= 0; i--) { + var e = this._events[i]; + if (e instanceof Tone.Part) { + e._forEach(callback, ctx); + } else { + callback.call(ctx, e); + } + } + } + return this; + }; + /** + * Set the attribute of all of the events + * @param {String} attr the attribute to set + * @param {*} value The value to set it to + * @private + */ + Tone.Part.prototype._setAll = function (attr, value) { + this._forEach(function (event) { + event[attr] = value; + }); + }; + /** + * Internal tick method + * @param {Number} time The time of the event in seconds + * @private + */ + Tone.Part.prototype._tick = function (time, value) { + if (!this.mute) { + this.callback(time, value); + } + }; + /** + * Determine if the event should be currently looping + * given the loop boundries of this Part. + * @param {Tone.Event} event The event to test + * @private + */ + Tone.Part.prototype._testLoopBoundries = function (event) { + if (event.startOffset < this._loopStart || event.startOffset >= this._loopEnd) { + event.cancel(0); + } else if (event.state === Tone.State.Stopped) { + //reschedule it if it's stopped + this._restartEvent(event); + } + }; + /** + * The probability of the notes being triggered. + * @memberOf Tone.Part# + * @type {NormalRange} + * @name probability + */ + Object.defineProperty(Tone.Part.prototype, 'probability', { + get: function () { + return this._probability; + }, + set: function (prob) { + this._probability = prob; + this._setAll('probability', prob); + } + }); + /** + * If set to true, will apply small random variation + * to the callback time. If the value is given as a time, it will randomize + * by that amount. + * @example + * event.humanize = true; + * @type {Boolean|Time} + * @name humanize + */ + Object.defineProperty(Tone.Part.prototype, 'humanize', { + get: function () { + return this._humanize; + }, + set: function (variation) { + this._humanize = variation; + this._setAll('humanize', variation); + } + }); + /** + * If the part should loop or not + * between Tone.Part.loopStart and + * Tone.Part.loopEnd. An integer + * value corresponds to the number of + * loops the Part does after it starts. + * @memberOf Tone.Part# + * @type {Boolean|Positive} + * @name loop + * @example + * //loop the part 8 times + * part.loop = 8; + */ + Object.defineProperty(Tone.Part.prototype, 'loop', { + get: function () { + return this._loop; + }, + set: function (loop) { + this._loop = loop; + this._forEach(function (event) { + event._loopStart = this._loopStart; + event._loopEnd = this._loopEnd; + event.loop = loop; + this._testLoopBoundries(event); + }); + } + }); + /** + * The loopEnd point determines when it will + * loop if Tone.Part.loop is true. + * @memberOf Tone.Part# + * @type {Time} + * @name loopEnd + */ + Object.defineProperty(Tone.Part.prototype, 'loopEnd', { + get: function () { + return Tone.Ticks(this._loopEnd).toSeconds(); + }, + set: function (loopEnd) { + this._loopEnd = this.toTicks(loopEnd); + if (this._loop) { + this._forEach(function (event) { + event.loopEnd = loopEnd; + this._testLoopBoundries(event); + }); + } + } + }); + /** + * The loopStart point determines when it will + * loop if Tone.Part.loop is true. + * @memberOf Tone.Part# + * @type {Time} + * @name loopStart + */ + Object.defineProperty(Tone.Part.prototype, 'loopStart', { + get: function () { + return Tone.Ticks(this._loopStart).toSeconds(); + }, + set: function (loopStart) { + this._loopStart = this.toTicks(loopStart); + if (this._loop) { + this._forEach(function (event) { + event.loopStart = this.loopStart; + this._testLoopBoundries(event); + }); + } + } + }); + /** + * The playback rate of the part + * @memberOf Tone.Part# + * @type {Positive} + * @name playbackRate + */ + Object.defineProperty(Tone.Part.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + this._setAll('playbackRate', rate); + } + }); + /** + * The number of scheduled notes in the part. + * @memberOf Tone.Part# + * @type {Positive} + * @name length + * @readOnly + */ + Object.defineProperty(Tone.Part.prototype, 'length', { + get: function () { + return this._events.length; + } + }); + /** + * Clean up + * @return {Tone.Part} this + */ + Tone.Part.prototype.dispose = function () { + this.removeAll(); + this._state.dispose(); + this._state = null; + this.callback = null; + this._events = null; + return this; + }; + return Tone.Part; + }); + Module(function (Tone) { + /** + * @class Tone.Pattern arpeggiates between the given notes + * in a number of patterns. See Tone.CtrlPattern for + * a full list of patterns. + * @example + * var pattern = new Tone.Pattern(function(time, note){ + * //the order of the notes passed in depends on the pattern + * }, ["C2", "D4", "E5", "A6"], "upDown"); + * @extends {Tone.Loop} + * @param {Function} callback The callback to invoke with the + * event. + * @param {Array} values The values to arpeggiate over. + */ + Tone.Pattern = function () { + var options = Tone.defaults(arguments, [ + 'callback', + 'values', + 'pattern' + ], Tone.Pattern); + Tone.Loop.call(this, options); + /** + * The pattern manager + * @type {Tone.CtrlPattern} + * @private + */ + this._pattern = new Tone.CtrlPattern({ + 'values': options.values, + 'type': options.pattern, + 'index': options.index + }); + }; + Tone.extend(Tone.Pattern, Tone.Loop); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Pattern.defaults = { + 'pattern': Tone.CtrlPattern.Type.Up, + 'callback': Tone.noOp, + 'values': [] + }; + /** + * Internal function called when the notes should be called + * @param {Number} time The time the event occurs + * @private + */ + Tone.Pattern.prototype._tick = function (time) { + this.callback(time, this._pattern.value); + this._pattern.next(); + }; + /** + * The current index in the values array. + * @memberOf Tone.Pattern# + * @type {Positive} + * @name index + */ + Object.defineProperty(Tone.Pattern.prototype, 'index', { + get: function () { + return this._pattern.index; + }, + set: function (i) { + this._pattern.index = i; + } + }); + /** + * The array of events. + * @memberOf Tone.Pattern# + * @type {Array} + * @name values + */ + Object.defineProperty(Tone.Pattern.prototype, 'values', { + get: function () { + return this._pattern.values; + }, + set: function (vals) { + this._pattern.values = vals; + } + }); + /** + * The current value of the pattern. + * @memberOf Tone.Pattern# + * @type {*} + * @name value + * @readOnly + */ + Object.defineProperty(Tone.Pattern.prototype, 'value', { + get: function () { + return this._pattern.value; + } + }); + /** + * The pattern type. See Tone.CtrlPattern for the full list of patterns. + * @memberOf Tone.Pattern# + * @type {String} + * @name pattern + */ + Object.defineProperty(Tone.Pattern.prototype, 'pattern', { + get: function () { + return this._pattern.type; + }, + set: function (pattern) { + this._pattern.type = pattern; + } + }); + /** + * Clean up + * @return {Tone.Pattern} this + */ + Tone.Pattern.prototype.dispose = function () { + Tone.Loop.prototype.dispose.call(this); + this._pattern.dispose(); + this._pattern = null; + }; + return Tone.Pattern; + }); + Module(function (Tone) { + + /** + * @class A sequence is an alternate notation of a part. Instead + * of passing in an array of [time, event] pairs, pass + * in an array of events which will be spaced at the + * given subdivision. Sub-arrays will subdivide that beat + * by the number of items are in the array. + * Sequence notation inspiration from [Tidal](http://yaxu.org/tidal/) + * @param {Function} callback The callback to invoke with every note + * @param {Array} events The sequence + * @param {Time} subdivision The subdivision between which events are placed. + * @extends {Tone.Part} + * @example + * var seq = new Tone.Sequence(function(time, note){ + * console.log(note); + * //straight quater notes + * }, ["C4", "E4", "G4", "A4"], "4n"); + * @example + * var seq = new Tone.Sequence(function(time, note){ + * console.log(note); + * //subdivisions are given as subarrays + * }, ["C4", ["E4", "D4", "E4"], "G4", ["A4", "G4"]]); + */ + Tone.Sequence = function () { + var options = Tone.defaults(arguments, [ + 'callback', + 'events', + 'subdivision' + ], Tone.Sequence); + //remove the events + var events = options.events; + delete options.events; + Tone.Part.call(this, options); + /** + * The subdivison of each note + * @type {Ticks} + * @private + */ + this._subdivision = this.toTicks(options.subdivision); + //if no time was passed in, the loop end is the end of the cycle + if (Tone.isUndef(options.loopEnd) && Tone.isDefined(events)) { + this._loopEnd = events.length * this._subdivision; + } + //defaults to looping + this._loop = true; + //add all of the events + if (Tone.isDefined(events)) { + for (var i = 0; i < events.length; i++) { + this.add(i, events[i]); + } + } + }; + Tone.extend(Tone.Sequence, Tone.Part); + /** + * The default values. + * @type {Object} + */ + Tone.Sequence.defaults = { 'subdivision': '4n' }; + /** + * The subdivision of the sequence. This can only be + * set in the constructor. The subdivision is the + * interval between successive steps. + * @type {Time} + * @memberOf Tone.Sequence# + * @name subdivision + * @readOnly + */ + Object.defineProperty(Tone.Sequence.prototype, 'subdivision', { + get: function () { + return Tone.Ticks(this._subdivision).toSeconds(); + } + }); + /** + * Get/Set an index of the sequence. If the index contains a subarray, + * a Tone.Sequence representing that sub-array will be returned. + * @example + * var sequence = new Tone.Sequence(playNote, ["E4", "C4", "F#4", ["A4", "Bb3"]]) + * sequence.at(0)// => returns "E4" + * //set a value + * sequence.at(0, "G3"); + * //get a nested sequence + * sequence.at(3).at(1)// => returns "Bb3" + * @param {Positive} index The index to get or set + * @param {*} value Optionally pass in the value to set at the given index. + */ + Tone.Sequence.prototype.at = function (index, value) { + //if the value is an array, + if (Tone.isArray(value)) { + //remove the current event at that index + this.remove(index); + } + //call the parent's method + return Tone.Part.prototype.at.call(this, this._indexTime(index), value); + }; + /** + * Add an event at an index, if there's already something + * at that index, overwrite it. If `value` is an array, + * it will be parsed as a subsequence. + * @param {Number} index The index to add the event to + * @param {*} value The value to add at that index + * @returns {Tone.Sequence} this + */ + Tone.Sequence.prototype.add = function (index, value) { + if (value === null) { + return this; + } + if (Tone.isArray(value)) { + //make a subsequence and add that to the sequence + var subSubdivision = Math.round(this._subdivision / value.length); + value = new Tone.Sequence(this._tick.bind(this), value, Tone.Ticks(subSubdivision)); + } + Tone.Part.prototype.add.call(this, this._indexTime(index), value); + return this; + }; + /** + * Remove a value from the sequence by index + * @param {Number} index The index of the event to remove + * @returns {Tone.Sequence} this + */ + Tone.Sequence.prototype.remove = function (index, value) { + Tone.Part.prototype.remove.call(this, this._indexTime(index), value); + return this; + }; + /** + * Get the time of the index given the Sequence's subdivision + * @param {Number} index + * @return {Time} The time of that index + * @private + */ + Tone.Sequence.prototype._indexTime = function (index) { + if (index instanceof Tone.TransportTime) { + return index; + } else { + return Tone.Ticks(index * this._subdivision + this.startOffset).toSeconds(); + } + }; + /** + * Clean up. + * @return {Tone.Sequence} this + */ + Tone.Sequence.prototype.dispose = function () { + Tone.Part.prototype.dispose.call(this); + return this; + }; + return Tone.Sequence; + }); + Module(function (Tone) { + + /** + * @class Tone.PulseOscillator is a pulse oscillator with control over pulse width, + * also known as the duty cycle. At 50% duty cycle (width = 0.5) the wave is + * a square and only odd-numbered harmonics are present. At all other widths + * even-numbered harmonics are present. Read more + * [here](https://wigglewave.wordpress.com/2014/08/16/pulse-waveforms-and-harmonics/). + * + * @constructor + * @extends {Tone.Source} + * @param {Frequency} [frequency] The frequency of the oscillator + * @param {NormalRange} [width] The width of the pulse + * @example + * var pulse = new Tone.PulseOscillator("E5", 0.4).toMaster().start(); + */ + Tone.PulseOscillator = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'width' + ], Tone.Oscillator); + Tone.Source.call(this, options); + /** + * The width of the pulse. + * @type {NormalRange} + * @signal + */ + this.width = new Tone.Signal(options.width, Tone.Type.NormalRange); + /** + * gate the width amount + * @type {Tone.Gain} + * @private + */ + this._widthGate = new Tone.Gain(); + /** + * the sawtooth oscillator + * @type {Tone.Oscillator} + * @private + */ + this._sawtooth = new Tone.Oscillator({ + frequency: options.frequency, + detune: options.detune, + type: 'sawtooth', + phase: options.phase + }); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = this._sawtooth.frequency; + /** + * The detune in cents. + * @type {Cents} + * @signal + */ + this.detune = this._sawtooth.detune; + /** + * Threshold the signal to turn it into a square + * @type {Tone.WaveShaper} + * @private + */ + this._thresh = new Tone.WaveShaper(function (val) { + if (val < 0) { + return -1; + } else { + return 1; + } + }); + //connections + this._sawtooth.chain(this._thresh, this.output); + this.width.chain(this._widthGate, this._thresh); + this._readOnly([ + 'width', + 'frequency', + 'detune' + ]); + }; + Tone.extend(Tone.PulseOscillator, Tone.Source); + /** + * The default parameters. + * @static + * @const + * @type {Object} + */ + Tone.PulseOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'width': 0.2 + }; + /** + * start the oscillator + * @param {Time} time + * @private + */ + Tone.PulseOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._sawtooth.start(time); + this._widthGate.gain.setValueAtTime(1, time); + }; + /** + * stop the oscillator + * @param {Time} time + * @private + */ + Tone.PulseOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._sawtooth.stop(time); + //the width is still connected to the output. + //that needs to be stopped also + this._widthGate.gain.setValueAtTime(0, time); + }; + /** + * restart the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.PulseOscillator.prototype.restart = function (time) { + this._sawtooth.restart(time); + }; + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.PulseOscillator# + * @type {Degrees} + * @name phase + */ + Object.defineProperty(Tone.PulseOscillator.prototype, 'phase', { + get: function () { + return this._sawtooth.phase; + }, + set: function (phase) { + this._sawtooth.phase = phase; + } + }); + /** + * The type of the oscillator. Always returns "pulse". + * @readOnly + * @memberOf Tone.PulseOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.PulseOscillator.prototype, 'type', { + get: function () { + return 'pulse'; + } + }); + /** + * The partials of the waveform. Cannot set partials for this waveform type + * @memberOf Tone.PulseOscillator# + * @type {Array} + * @name partials + * @private + */ + Object.defineProperty(Tone.PulseOscillator.prototype, 'partials', { + get: function () { + return []; + } + }); + /** + * Clean up method. + * @return {Tone.PulseOscillator} this + */ + Tone.PulseOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._sawtooth.dispose(); + this._sawtooth = null; + this._writable([ + 'width', + 'frequency', + 'detune' + ]); + this.width.dispose(); + this.width = null; + this._widthGate.dispose(); + this._widthGate = null; + this._thresh.dispose(); + this._thresh = null; + this.frequency = null; + this.detune = null; + return this; + }; + return Tone.PulseOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.PWMOscillator modulates the width of a Tone.PulseOscillator + * at the modulationFrequency. This has the effect of continuously + * changing the timbre of the oscillator by altering the harmonics + * generated. + * + * @extends {Tone.Source} + * @constructor + * @param {Frequency} frequency The starting frequency of the oscillator. + * @param {Frequency} modulationFrequency The modulation frequency of the width of the pulse. + * @example + * var pwm = new Tone.PWMOscillator("Ab3", 0.3).toMaster().start(); + */ + Tone.PWMOscillator = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'modulationFrequency' + ], Tone.PWMOscillator); + Tone.Source.call(this, options); + /** + * the pulse oscillator + * @type {Tone.PulseOscillator} + * @private + */ + this._pulse = new Tone.PulseOscillator(options.modulationFrequency); + //change the pulse oscillator type + this._pulse._sawtooth.type = 'sine'; + /** + * the modulator + * @type {Tone.Oscillator} + * @private + */ + this._modulator = new Tone.Oscillator({ + 'frequency': options.frequency, + 'detune': options.detune, + 'phase': options.phase + }); + /** + * Scale the oscillator so it doesn't go silent + * at the extreme values. + * @type {Tone.Multiply} + * @private + */ + this._scale = new Tone.Multiply(2); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = this._modulator.frequency; + /** + * The detune of the oscillator. + * @type {Cents} + * @signal + */ + this.detune = this._modulator.detune; + /** + * The modulation rate of the oscillator. + * @type {Frequency} + * @signal + */ + this.modulationFrequency = this._pulse.frequency; + //connections + this._modulator.chain(this._scale, this._pulse.width); + this._pulse.connect(this.output); + this._readOnly([ + 'modulationFrequency', + 'frequency', + 'detune' + ]); + }; + Tone.extend(Tone.PWMOscillator, Tone.Source); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.PWMOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'modulationFrequency': 0.4 + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.PWMOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._modulator.start(time); + this._pulse.start(time); + }; + /** + * stop the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.PWMOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._modulator.stop(time); + this._pulse.stop(time); + }; + /** + * restart the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.PWMOscillator.prototype.restart = function (time) { + this._modulator.restart(time); + this._pulse.restart(time); + }; + /** + * The type of the oscillator. Always returns "pwm". + * @readOnly + * @memberOf Tone.PWMOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.PWMOscillator.prototype, 'type', { + get: function () { + return 'pwm'; + } + }); + /** + * The partials of the waveform. Cannot set partials for this waveform type + * @memberOf Tone.PWMOscillator# + * @type {Array} + * @name partials + * @private + */ + Object.defineProperty(Tone.PWMOscillator.prototype, 'partials', { + get: function () { + return []; + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.PWMOscillator# + * @type {number} + * @name phase + */ + Object.defineProperty(Tone.PWMOscillator.prototype, 'phase', { + get: function () { + return this._modulator.phase; + }, + set: function (phase) { + this._modulator.phase = phase; + } + }); + /** + * Clean up. + * @return {Tone.PWMOscillator} this + */ + Tone.PWMOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._pulse.dispose(); + this._pulse = null; + this._scale.dispose(); + this._scale = null; + this._modulator.dispose(); + this._modulator = null; + this._writable([ + 'modulationFrequency', + 'frequency', + 'detune' + ]); + this.frequency = null; + this.detune = null; + this.modulationFrequency = null; + return this; + }; + return Tone.PWMOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.FMOscillator + * + * @extends {Tone.Source} + * @constructor + * @param {Frequency} frequency The starting frequency of the oscillator. + * @param {String} type The type of the carrier oscillator. + * @param {String} modulationType The type of the modulator oscillator. + * @example + * //a sine oscillator frequency-modulated by a square wave + * var fmOsc = new Tone.FMOscillator("Ab3", "sine", "square").toMaster().start(); + */ + Tone.FMOscillator = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'type', + 'modulationType' + ], Tone.FMOscillator); + Tone.Source.call(this, options); + /** + * The carrier oscillator + * @type {Tone.Oscillator} + * @private + */ + this._carrier = new Tone.Oscillator(options.frequency, options.type); + /** + * The oscillator's frequency + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune control signal. + * @type {Cents} + * @signal + */ + this.detune = this._carrier.detune; + this.detune.value = options.detune; + /** + * The modulation index which is in essence the depth or amount of the modulation. In other terms it is the + * ratio of the frequency of the modulating signal (mf) to the amplitude of the + * modulating signal (ma) -- as in ma/mf. + * @type {Positive} + * @signal + */ + this.modulationIndex = new Tone.Multiply(options.modulationIndex); + this.modulationIndex.units = Tone.Type.Positive; + /** + * The modulating oscillator + * @type {Tone.Oscillator} + * @private + */ + this._modulator = new Tone.Oscillator(options.frequency, options.modulationType); + /** + * Harmonicity is the frequency ratio between the carrier and the modulator oscillators. + * A harmonicity of 1 gives both oscillators the same frequency. + * Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch the modulator an octave below carrier + * synth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + /** + * the node where the modulation happens + * @type {Tone.Gain} + * @private + */ + this._modulationNode = new Tone.Gain(0); + //connections + this.frequency.connect(this._carrier.frequency); + this.frequency.chain(this.harmonicity, this._modulator.frequency); + this.frequency.chain(this.modulationIndex, this._modulationNode); + this._modulator.connect(this._modulationNode.gain); + this._modulationNode.connect(this._carrier.frequency); + this._carrier.connect(this.output); + this.detune.connect(this._modulator.detune); + this.phase = options.phase; + this._readOnly([ + 'modulationIndex', + 'frequency', + 'detune', + 'harmonicity' + ]); + }; + Tone.extend(Tone.FMOscillator, Tone.Source); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.FMOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'modulationIndex': 2, + 'modulationType': 'square', + 'harmonicity': 1 + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.FMOscillator.prototype._start = function (time) { + this._modulator.start(time); + this._carrier.start(time); + }; + /** + * stop the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.FMOscillator.prototype._stop = function (time) { + this._modulator.stop(time); + this._carrier.stop(time); + }; + /** + * stop the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.FMOscillator.prototype.restart = function (time) { + this._modulator.restart(time); + this._carrier.restart(time); + }; + /** + * The type of the carrier oscillator + * @memberOf Tone.FMOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.FMOscillator.prototype, 'type', { + get: function () { + return this._carrier.type; + }, + set: function (type) { + this._carrier.type = type; + } + }); + /** + * The type of the modulator oscillator + * @memberOf Tone.FMOscillator# + * @type {String} + * @name modulationType + */ + Object.defineProperty(Tone.FMOscillator.prototype, 'modulationType', { + get: function () { + return this._modulator.type; + }, + set: function (type) { + this._modulator.type = type; + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.FMOscillator# + * @type {number} + * @name phase + */ + Object.defineProperty(Tone.FMOscillator.prototype, 'phase', { + get: function () { + return this._carrier.phase; + }, + set: function (phase) { + this._carrier.phase = phase; + this._modulator.phase = phase; + } + }); + /** + * The partials of the carrier waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * @memberOf Tone.FMOscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.FMOscillator.prototype, 'partials', { + get: function () { + return this._carrier.partials; + }, + set: function (partials) { + this._carrier.partials = partials; + } + }); + /** + * Clean up. + * @return {Tone.FMOscillator} this + */ + Tone.FMOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._writable([ + 'modulationIndex', + 'frequency', + 'detune', + 'harmonicity' + ]); + this.frequency.dispose(); + this.frequency = null; + this.detune = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this._carrier.dispose(); + this._carrier = null; + this._modulator.dispose(); + this._modulator = null; + this._modulationNode.dispose(); + this._modulationNode = null; + this.modulationIndex.dispose(); + this.modulationIndex = null; + return this; + }; + return Tone.FMOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.AMOscillator + * + * @extends {Tone.Oscillator} + * @constructor + * @param {Frequency} frequency The starting frequency of the oscillator. + * @param {String} type The type of the carrier oscillator. + * @param {String} modulationType The type of the modulator oscillator. + * @example + * //a sine oscillator frequency-modulated by a square wave + * var fmOsc = new Tone.AMOscillator("Ab3", "sine", "square").toMaster().start(); + */ + Tone.AMOscillator = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'type', + 'modulationType' + ], Tone.AMOscillator); + Tone.Source.call(this, options); + /** + * The carrier oscillator + * @type {Tone.Oscillator} + * @private + */ + this._carrier = new Tone.Oscillator(options.frequency, options.type); + /** + * The oscillator's frequency + * @type {Frequency} + * @signal + */ + this.frequency = this._carrier.frequency; + /** + * The detune control signal. + * @type {Cents} + * @signal + */ + this.detune = this._carrier.detune; + this.detune.value = options.detune; + /** + * The modulating oscillator + * @type {Tone.Oscillator} + * @private + */ + this._modulator = new Tone.Oscillator(options.frequency, options.modulationType); + /** + * convert the -1,1 output to 0,1 + * @type {Tone.AudioToGain} + * @private + */ + this._modulationScale = new Tone.AudioToGain(); + /** + * Harmonicity is the frequency ratio between the carrier and the modulator oscillators. + * A harmonicity of 1 gives both oscillators the same frequency. + * Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch the modulator an octave below carrier + * synth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + /** + * the node where the modulation happens + * @type {Tone.Gain} + * @private + */ + this._modulationNode = new Tone.Gain(0); + //connections + this.frequency.chain(this.harmonicity, this._modulator.frequency); + this.detune.connect(this._modulator.detune); + this._modulator.chain(this._modulationScale, this._modulationNode.gain); + this._carrier.chain(this._modulationNode, this.output); + this.phase = options.phase; + this._readOnly([ + 'frequency', + 'detune', + 'harmonicity' + ]); + }; + Tone.extend(Tone.AMOscillator, Tone.Oscillator); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.AMOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'modulationType': 'square', + 'harmonicity': 1 + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.AMOscillator.prototype._start = function (time) { + this._modulator.start(time); + this._carrier.start(time); + }; + /** + * stop the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.AMOscillator.prototype._stop = function (time) { + this._modulator.stop(time); + this._carrier.stop(time); + }; + /** + * restart the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.AMOscillator.prototype.restart = function (time) { + this._modulator.restart(time); + this._carrier.restart(time); + }; + /** + * The type of the carrier oscillator + * @memberOf Tone.AMOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.AMOscillator.prototype, 'type', { + get: function () { + return this._carrier.type; + }, + set: function (type) { + this._carrier.type = type; + } + }); + /** + * The type of the modulator oscillator + * @memberOf Tone.AMOscillator# + * @type {string} + * @name modulationType + */ + Object.defineProperty(Tone.AMOscillator.prototype, 'modulationType', { + get: function () { + return this._modulator.type; + }, + set: function (type) { + this._modulator.type = type; + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.AMOscillator# + * @type {number} + * @name phase + */ + Object.defineProperty(Tone.AMOscillator.prototype, 'phase', { + get: function () { + return this._carrier.phase; + }, + set: function (phase) { + this._carrier.phase = phase; + this._modulator.phase = phase; + } + }); + /** + * The partials of the carrier waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * @memberOf Tone.AMOscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.AMOscillator.prototype, 'partials', { + get: function () { + return this._carrier.partials; + }, + set: function (partials) { + this._carrier.partials = partials; + } + }); + /** + * Clean up. + * @return {Tone.AMOscillator} this + */ + Tone.AMOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'detune', + 'harmonicity' + ]); + this.frequency = null; + this.detune = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this._carrier.dispose(); + this._carrier = null; + this._modulator.dispose(); + this._modulator = null; + this._modulationNode.dispose(); + this._modulationNode = null; + this._modulationScale.dispose(); + this._modulationScale = null; + return this; + }; + return Tone.AMOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.FatOscillator + * + * @extends {Tone.Source} + * @constructor + * @param {Frequency} frequency The starting frequency of the oscillator. + * @param {String} type The type of the carrier oscillator. + * @param {String} modulationType The type of the modulator oscillator. + * @example + * //a sine oscillator frequency-modulated by a square wave + * var fmOsc = new Tone.FatOscillator("Ab3", "sine", "square").toMaster().start(); + */ + Tone.FatOscillator = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'type', + 'spread' + ], Tone.FatOscillator); + Tone.Source.call(this, options); + /** + * The oscillator's frequency + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune control signal. + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * The array of oscillators + * @type {Array} + * @private + */ + this._oscillators = []; + /** + * The total spread of the oscillators + * @type {Cents} + * @private + */ + this._spread = options.spread; + /** + * The type of the oscillator + * @type {String} + * @private + */ + this._type = options.type; + /** + * The phase of the oscillators + * @type {Degrees} + * @private + */ + this._phase = options.phase; + /** + * The partials array + * @type {Array} + * @private + */ + this._partials = Tone.defaultArg(options.partials, []); + //set the count initially + this.count = options.count; + this._readOnly([ + 'frequency', + 'detune' + ]); + }; + Tone.extend(Tone.FatOscillator, Tone.Source); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.FatOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'spread': 20, + 'count': 3, + 'type': 'sawtooth' + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.FatOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._forEach(function (osc) { + osc.start(time); + }); + }; + /** + * stop the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.FatOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._forEach(function (osc) { + osc.stop(time); + }); + }; + /** + * restart the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.FatOscillator.prototype.restart = function (time) { + time = this.toSeconds(time); + this._forEach(function (osc) { + osc.restart(time); + }); + }; + /** + * Iterate over all of the oscillators + * @param {Function} iterator The iterator function + * @private + */ + Tone.FatOscillator.prototype._forEach = function (iterator) { + for (var i = 0; i < this._oscillators.length; i++) { + iterator.call(this, this._oscillators[i], i); + } + }; + /** + * The type of the carrier oscillator + * @memberOf Tone.FatOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + this._type = type; + this._forEach(function (osc) { + osc.type = type; + }); + } + }); + /** + * The detune spread between the oscillators. If "count" is + * set to 3 oscillators and the "spread" is set to 40, + * the three oscillators would be detuned like this: [-20, 0, 20] + * for a total detune spread of 40 cents. + * @memberOf Tone.FatOscillator# + * @type {Cents} + * @name spread + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'spread', { + get: function () { + return this._spread; + }, + set: function (spread) { + this._spread = spread; + if (this._oscillators.length > 1) { + var start = -spread / 2; + var step = spread / (this._oscillators.length - 1); + this._forEach(function (osc, i) { + osc.detune.value = start + step * i; + }); + } + } + }); + /** + * The number of detuned oscillators + * @memberOf Tone.FatOscillator# + * @type {Number} + * @name count + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'count', { + get: function () { + return this._oscillators.length; + }, + set: function (count) { + count = Math.max(count, 1); + if (this._oscillators.length !== count) { + // var partials = this.partials; + // var type = this.type; + //dispose the previous oscillators + this._forEach(function (osc) { + osc.dispose(); + }); + this._oscillators = []; + for (var i = 0; i < count; i++) { + var osc = new Tone.Oscillator(); + if (this.type === Tone.Oscillator.Type.Custom) { + osc.partials = this._partials; + } else { + osc.type = this._type; + } + osc.phase = this._phase; + osc.volume.value = -6 - count * 1.1; + this.frequency.connect(osc.frequency); + this.detune.connect(osc.detune); + osc.connect(this.output); + this._oscillators[i] = osc; + } + //set the spread + this.spread = this._spread; + if (this.state === Tone.State.Started) { + this._forEach(function (osc) { + osc.start(); + }); + } + } + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.FatOscillator# + * @type {Number} + * @name phase + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'phase', { + get: function () { + return this._phase; + }, + set: function (phase) { + this._phase = phase; + this._forEach(function (osc) { + osc.phase = phase; + }); + } + }); + /** + * The partials of the carrier waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * @memberOf Tone.FatOscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'partials', { + get: function () { + return this._partials; + }, + set: function (partials) { + this._partials = partials; + this._type = Tone.Oscillator.Type.Custom; + this._forEach(function (osc) { + osc.partials = partials; + }); + } + }); + /** + * Clean up. + * @return {Tone.FatOscillator} this + */ + Tone.FatOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'detune' + ]); + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + this._forEach(function (osc) { + osc.dispose(); + }); + this._oscillators = null; + this._partials = null; + return this; + }; + return Tone.FatOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.OmniOscillator aggregates Tone.Oscillator, Tone.PulseOscillator, + * Tone.PWMOscillator, Tone.FMOscillator, Tone.AMOscillator, and Tone.FatOscillator + * into one class. The oscillator class can be changed by setting the `type`. + * `omniOsc.type = "pwm"` will set it to the Tone.PWMOscillator. Prefixing + * any of the basic types ("sine", "square4", etc.) with "fm", "am", or "fat" + * will use the FMOscillator, AMOscillator or FatOscillator respectively. + * For example: `omniOsc.type = "fatsawtooth"` will create set the oscillator + * to a FatOscillator of type "sawtooth". + * + * @extends {Tone.Source} + * @constructor + * @param {Frequency} frequency The initial frequency of the oscillator. + * @param {String} type The type of the oscillator. + * @example + * var omniOsc = new Tone.OmniOscillator("C#4", "pwm"); + */ + Tone.OmniOscillator = function () { + var options = Tone.defaults(arguments, [ + 'frequency', + 'type' + ], Tone.OmniOscillator); + Tone.Source.call(this, options); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune control + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * the type of the oscillator source + * @type {String} + * @private + */ + this._sourceType = undefined; + /** + * the oscillator + * @type {Tone.Oscillator} + * @private + */ + this._oscillator = null; + //set the oscillator + this.type = options.type; + this._readOnly([ + 'frequency', + 'detune' + ]); + //set the options + this.set(options); + }; + Tone.extend(Tone.OmniOscillator, Tone.Source); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.OmniOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'type': 'sine', + 'phase': 0 + }; + /** + * @enum {String} + * @private + */ + var OmniOscType = { + Pulse: 'PulseOscillator', + PWM: 'PWMOscillator', + Osc: 'Oscillator', + FM: 'FMOscillator', + AM: 'AMOscillator', + Fat: 'FatOscillator' + }; + /** + * start the oscillator + * @param {Time} [time=now] the time to start the oscillator + * @private + */ + Tone.OmniOscillator.prototype._start = function (time) { + this._oscillator.start(time); + }; + /** + * start the oscillator + * @param {Time} [time=now] the time to start the oscillator + * @private + */ + Tone.OmniOscillator.prototype._stop = function (time) { + this._oscillator.stop(time); + }; + Tone.OmniOscillator.prototype.restart = function (time) { + this._oscillator.restart(time); + }; + /** + * The type of the oscillator. Can be any of the basic types: sine, square, triangle, sawtooth. Or + * prefix the basic types with "fm", "am", or "fat" to use the FMOscillator, AMOscillator or FatOscillator + * types. The oscillator could also be set to "pwm" or "pulse". All of the parameters of the + * oscillator's class are accessible when the oscillator is set to that type, but throws an error + * when it's not. + * + * @memberOf Tone.OmniOscillator# + * @type {String} + * @name type + * @example + * omniOsc.type = "pwm"; + * //modulationFrequency is parameter which is available + * //only when the type is "pwm". + * omniOsc.modulationFrequency.value = 0.5; + * @example + * //an square wave frequency modulated by a sawtooth + * omniOsc.type = "fmsquare"; + * omniOsc.modulationType = "sawtooth"; + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'type', { + get: function () { + var prefix = ''; + if (this._sourceType === OmniOscType.FM) { + prefix = 'fm'; + } else if (this._sourceType === OmniOscType.AM) { + prefix = 'am'; + } else if (this._sourceType === OmniOscType.Fat) { + prefix = 'fat'; + } + return prefix + this._oscillator.type; + }, + set: function (type) { + if (type.substr(0, 2) === 'fm') { + this._createNewOscillator(OmniOscType.FM); + this._oscillator.type = type.substr(2); + } else if (type.substr(0, 2) === 'am') { + this._createNewOscillator(OmniOscType.AM); + this._oscillator.type = type.substr(2); + } else if (type.substr(0, 3) === 'fat') { + this._createNewOscillator(OmniOscType.Fat); + this._oscillator.type = type.substr(3); + } else if (type === 'pwm') { + this._createNewOscillator(OmniOscType.PWM); + } else if (type === 'pulse') { + this._createNewOscillator(OmniOscType.Pulse); + } else { + this._createNewOscillator(OmniOscType.Osc); + this._oscillator.type = type; + } + } + }); + /** + * The partials of the waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * This is not available on "pwm" and "pulse" oscillator types. + * @memberOf Tone.OmniOscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'partials', { + get: function () { + return this._oscillator.partials; + }, + set: function (partials) { + this._oscillator.partials = partials; + } + }); + /** + * Set a member/attribute of the oscillator. + * @param {Object|String} params + * @param {number=} value + * @param {Time=} rampTime + * @returns {Tone.OmniOscillator} this + */ + Tone.OmniOscillator.prototype.set = function (params, value) { + //make sure the type is set first + if (params === 'type') { + this.type = value; + } else if (Tone.isObject(params) && params.hasOwnProperty('type')) { + this.type = params.type; + } + //then set the rest + Tone.prototype.set.apply(this, arguments); + return this; + }; + /** + * connect the oscillator to the frequency and detune signals + * @private + */ + Tone.OmniOscillator.prototype._createNewOscillator = function (oscType) { + if (oscType !== this._sourceType) { + this._sourceType = oscType; + var OscillatorConstructor = Tone[oscType]; + //short delay to avoid clicks on the change + var now = this.now(); + if (this._oscillator !== null) { + var oldOsc = this._oscillator; + oldOsc.stop(now); + //dispose the old one + this.context.setTimeout(function () { + oldOsc.dispose(); + oldOsc = null; + }, this.blockTime); + } + this._oscillator = new OscillatorConstructor(); + this.frequency.connect(this._oscillator.frequency); + this.detune.connect(this._oscillator.detune); + this._oscillator.connect(this.output); + if (this.state === Tone.State.Started) { + this._oscillator.start(now); + } + } + }; + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.OmniOscillator# + * @type {Degrees} + * @name phase + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'phase', { + get: function () { + return this._oscillator.phase; + }, + set: function (phase) { + this._oscillator.phase = phase; + } + }); + /** + * The width of the oscillator (only if the oscillator is set to "pulse") + * @memberOf Tone.OmniOscillator# + * @type {NormalRange} + * @signal + * @name width + * @example + * var omniOsc = new Tone.OmniOscillator(440, "pulse"); + * //can access the width attribute only if type === "pulse" + * omniOsc.width.value = 0.2; + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'width', { + get: function () { + if (this._sourceType === OmniOscType.Pulse) { + return this._oscillator.width; + } + } + }); + /** + * The number of detuned oscillators + * @memberOf Tone.OmniOscillator# + * @type {Number} + * @name count + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'count', { + get: function () { + if (this._sourceType === OmniOscType.Fat) { + return this._oscillator.count; + } + }, + set: function (count) { + if (this._sourceType === OmniOscType.Fat) { + this._oscillator.count = count; + } + } + }); + /** + * The detune spread between the oscillators. If "count" is + * set to 3 oscillators and the "spread" is set to 40, + * the three oscillators would be detuned like this: [-20, 0, 20] + * for a total detune spread of 40 cents. See Tone.FatOscillator + * for more info. + * @memberOf Tone.OmniOscillator# + * @type {Cents} + * @name spread + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'spread', { + get: function () { + if (this._sourceType === OmniOscType.Fat) { + return this._oscillator.spread; + } + }, + set: function (spread) { + if (this._sourceType === OmniOscType.Fat) { + this._oscillator.spread = spread; + } + } + }); + /** + * The type of the modulator oscillator. Only if the oscillator + * is set to "am" or "fm" types. see. Tone.AMOscillator or Tone.FMOscillator + * for more info. + * @memberOf Tone.OmniOscillator# + * @type {String} + * @name modulationType + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationType', { + get: function () { + if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) { + return this._oscillator.modulationType; + } + }, + set: function (mType) { + if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) { + this._oscillator.modulationType = mType; + } + } + }); + /** + * The modulation index which is in essence the depth or amount of the modulation. In other terms it is the + * ratio of the frequency of the modulating signal (mf) to the amplitude of the + * modulating signal (ma) -- as in ma/mf. + * See Tone.FMOscillator for more info. + * @type {Positive} + * @signal + * @name modulationIndex + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationIndex', { + get: function () { + if (this._sourceType === OmniOscType.FM) { + return this._oscillator.modulationIndex; + } + } + }); + /** + * Harmonicity is the frequency ratio between the carrier and the modulator oscillators. + * A harmonicity of 1 gives both oscillators the same frequency. + * Harmonicity = 2 means a change of an octave. See Tone.AMOscillator or Tone.FMOscillator + * for more info. + * @memberOf Tone.OmniOscillator# + * @signal + * @type {Positive} + * @name harmonicity + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'harmonicity', { + get: function () { + if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) { + return this._oscillator.harmonicity; + } + } + }); + /** + * The modulationFrequency Signal of the oscillator + * (only if the oscillator type is set to pwm). See + * Tone.PWMOscillator for more info. + * @memberOf Tone.OmniOscillator# + * @type {Frequency} + * @signal + * @name modulationFrequency + * @example + * var omniOsc = new Tone.OmniOscillator(440, "pwm"); + * //can access the modulationFrequency attribute only if type === "pwm" + * omniOsc.modulationFrequency.value = 0.2; + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationFrequency', { + get: function () { + if (this._sourceType === OmniOscType.PWM) { + return this._oscillator.modulationFrequency; + } + } + }); + /** + * Clean up. + * @return {Tone.OmniOscillator} this + */ + Tone.OmniOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'detune' + ]); + this.detune.dispose(); + this.detune = null; + this.frequency.dispose(); + this.frequency = null; + this._oscillator.dispose(); + this._oscillator = null; + this._sourceType = null; + return this; + }; + return Tone.OmniOscillator; + }); + Module(function (Tone) { + + /** + * @class Base-class for all instruments + * + * @constructor + * @extends {Tone.AudioNode} + */ + Tone.Instrument = function (options) { + //get the defaults + options = Tone.defaultArg(options, Tone.Instrument.defaults); + Tone.AudioNode.call(this); + /** + * The output and volume triming node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume of the output in decibels. + * @type {Decibels} + * @signal + * @example + * source.volume.value = -6; + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + /** + * Keep track of all events scheduled to the transport + * when the instrument is 'synced' + * @type {Array<Number>} + * @private + */ + this._scheduledEvents = []; + }; + Tone.extend(Tone.Instrument, Tone.AudioNode); + /** + * the default attributes + * @type {object} + */ + Tone.Instrument.defaults = { + /** the volume of the output in decibels */ + 'volume': 0 + }; + /** + * @abstract + * @param {string|number} note the note to trigger + * @param {Time} [time=now] the time to trigger the ntoe + * @param {number} [velocity=1] the velocity to trigger the note + */ + Tone.Instrument.prototype.triggerAttack = Tone.noOp; + /** + * @abstract + * @param {Time} [time=now] when to trigger the release + */ + Tone.Instrument.prototype.triggerRelease = Tone.noOp; + /** + * Sync the instrument to the Transport. All subsequent calls of + * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease) + * will be scheduled along the transport. + * @example + * instrument.sync() + * //schedule 3 notes when the transport first starts + * instrument.triggerAttackRelease('C4', '8n', 0) + * instrument.triggerAttackRelease('E4', '8n', '8n') + * instrument.triggerAttackRelease('G4', '8n', '4n') + * //start the transport to hear the notes + * Transport.start() + * @returns {Tone.Instrument} this + */ + Tone.Instrument.prototype.sync = function () { + this._syncMethod('triggerAttack', 1); + this._syncMethod('triggerRelease', 0); + return this; + }; + /** + * Wrap the given method so that it can be synchronized + * @param {String} method Which method to wrap and sync + * @param {Number} timePosition What position the time argument appears in + * @private + */ + Tone.Instrument.prototype._syncMethod = function (method, timePosition) { + var originalMethod = this['_original_' + method] = this[method]; + this[method] = function () { + var args = Array.prototype.slice.call(arguments); + var time = args[timePosition]; + var id = Tone.Transport.schedule(function (t) { + args[timePosition] = t; + originalMethod.apply(this, args); + }.bind(this), time); + this._scheduledEvents.push(id); + }.bind(this); + }; + /** + * Unsync the instrument from the Transport + * @returns {Tone.Instrument} this + */ + Tone.Instrument.prototype.unsync = function () { + this._scheduledEvents.forEach(function (id) { + Tone.Transport.clear(id); + }); + this._scheduledEvents = []; + if (this._original_triggerAttack) { + this.triggerAttack = this._original_triggerAttack; + this.triggerRelease = this._original_triggerRelease; + } + return this; + }; + /** + * Trigger the attack and then the release after the duration. + * @param {Frequency} note The note to trigger. + * @param {Time} duration How long the note should be held for before + * triggering the release. This value must be greater than 0. + * @param {Time} [time=now] When the note should be triggered. + * @param {NormalRange} [velocity=1] The velocity the note should be triggered at. + * @returns {Tone.Instrument} this + * @example + * //trigger "C4" for the duration of an 8th note + * synth.triggerAttackRelease("C4", "8n"); + */ + Tone.Instrument.prototype.triggerAttackRelease = function (note, duration, time, velocity) { + time = this.toSeconds(time); + duration = this.toSeconds(duration); + this.triggerAttack(note, time, velocity); + this.triggerRelease(time + duration); + return this; + }; + /** + * clean up + * @returns {Tone.Instrument} this + */ + Tone.Instrument.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._volume.dispose(); + this._volume = null; + this._writable(['volume']); + this.volume = null; + this.unsync(); + this._scheduledEvents = null; + return this; + }; + return Tone.Instrument; + }); + Module(function (Tone) { + + /** + * @class This is an abstract base class for other monophonic instruments to + * extend. IMPORTANT: It does not make any sound on its own and + * shouldn't be directly instantiated. + * + * @constructor + * @abstract + * @extends {Tone.Instrument} + */ + Tone.Monophonic = function (options) { + //get the defaults + options = Tone.defaultArg(options, Tone.Monophonic.defaults); + Tone.Instrument.call(this, options); + /** + * The glide time between notes. + * @type {Time} + */ + this.portamento = options.portamento; + }; + Tone.extend(Tone.Monophonic, Tone.Instrument); + /** + * @static + * @const + * @type {Object} + */ + Tone.Monophonic.defaults = { 'portamento': 0 }; + /** + * Trigger the attack of the note optionally with a given velocity. + * + * + * @param {Frequency} note The note to trigger. + * @param {Time} [time=now] When the note should start. + * @param {number} [velocity=1] velocity The velocity scaler + * determines how "loud" the note + * will be triggered. + * @returns {Tone.Monophonic} this + * @example + * synth.triggerAttack("C4"); + * @example + * //trigger the note a half second from now at half velocity + * synth.triggerAttack("C4", "+0.5", 0.5); + */ + Tone.Monophonic.prototype.triggerAttack = function (note, time, velocity) { + time = this.toSeconds(time); + this._triggerEnvelopeAttack(time, velocity); + this.setNote(note, time); + return this; + }; + /** + * Trigger the release portion of the envelope + * @param {Time} [time=now] If no time is given, the release happens immediatly + * @returns {Tone.Monophonic} this + * @example + * synth.triggerRelease(); + */ + Tone.Monophonic.prototype.triggerRelease = function (time) { + time = this.toSeconds(time); + this._triggerEnvelopeRelease(time); + return this; + }; + /** + * override this method with the actual method + * @abstract + * @private + */ + Tone.Monophonic.prototype._triggerEnvelopeAttack = function () { + }; + /** + * override this method with the actual method + * @abstract + * @private + */ + Tone.Monophonic.prototype._triggerEnvelopeRelease = function () { + }; + /** + * Get the level of the output at the given time. Measures + * the envelope(s) value at the time. + * @param {Time} time The time to query the envelope value + * @return {NormalRange} The output level between 0-1 + */ + Tone.Monophonic.prototype.getLevelAtTime = function (time) { + time = this.toSeconds(time); + return this.envelope.getValueAtTime(time); + }; + /** + * Set the note at the given time. If no time is given, the note + * will set immediately. + * @param {Frequency} note The note to change to. + * @param {Time} [time=now] The time when the note should be set. + * @returns {Tone.Monophonic} this + * @example + * //change to F#6 in one quarter note from now. + * synth.setNote("F#6", "+4n"); + * @example + * //change to Bb4 right now + * synth.setNote("Bb4"); + */ + Tone.Monophonic.prototype.setNote = function (note, time) { + time = this.toSeconds(time); + if (this.portamento > 0 && this.getLevelAtTime(time) > 0.05) { + var portTime = this.toSeconds(this.portamento); + this.frequency.exponentialRampTo(note, portTime, time); + } else { + this.frequency.setValueAtTime(note, time); + } + return this; + }; + return Tone.Monophonic; + }); + Module(function (Tone) { + + /** + * @class Tone.Synth is composed simply of a Tone.OmniOscillator + * routed through a Tone.AmplitudeEnvelope. + * <img src="https://docs.google.com/drawings/d/1-1_0YW2Z1J2EPI36P8fNCMcZG7N1w1GZluPs4og4evo/pub?w=1163&h=231"> + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var synth = new Tone.Synth().toMaster(); + * synth.triggerAttackRelease("C4", "8n"); + */ + Tone.Synth = function (options) { + //get the defaults + options = Tone.defaultArg(options, Tone.Synth.defaults); + Tone.Monophonic.call(this, options); + /** + * The oscillator. + * @type {Tone.OmniOscillator} + */ + this.oscillator = new Tone.OmniOscillator(options.oscillator); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = this.oscillator.frequency; + /** + * The detune control. + * @type {Cents} + * @signal + */ + this.detune = this.oscillator.detune; + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + //connect the oscillators to the output + this.oscillator.chain(this.envelope, this.output); + this._readOnly([ + 'oscillator', + 'frequency', + 'detune', + 'envelope' + ]); + }; + Tone.extend(Tone.Synth, Tone.Monophonic); + /** + * @const + * @static + * @type {Object} + */ + Tone.Synth.defaults = { + 'oscillator': { 'type': 'triangle' }, + 'envelope': { + 'attack': 0.005, + 'decay': 0.1, + 'sustain': 0.3, + 'release': 1 + } + }; + /** + * start the attack portion of the envelope + * @param {Time} [time=now] the time the attack should start + * @param {number} [velocity=1] the velocity of the note (0-1) + * @returns {Tone.Synth} this + * @private + */ + Tone.Synth.prototype._triggerEnvelopeAttack = function (time, velocity) { + //the envelopes + this.envelope.triggerAttack(time, velocity); + this.oscillator.start(time); + //if there is no release portion, stop the oscillator + if (this.envelope.sustain === 0) { + this.oscillator.stop(time + this.envelope.attack + this.envelope.decay); + } + return this; + }; + /** + * start the release portion of the envelope + * @param {Time} [time=now] the time the release should start + * @returns {Tone.Synth} this + * @private + */ + Tone.Synth.prototype._triggerEnvelopeRelease = function (time) { + time = this.toSeconds(time); + this.envelope.triggerRelease(time); + this.oscillator.stop(time + this.envelope.release); + return this; + }; + /** + * clean up + * @returns {Tone.Synth} this + */ + Tone.Synth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'oscillator', + 'frequency', + 'detune', + 'envelope' + ]); + this.oscillator.dispose(); + this.oscillator = null; + this.envelope.dispose(); + this.envelope = null; + this.frequency = null; + this.detune = null; + return this; + }; + return Tone.Synth; + }); + Module(function (Tone) { + + /** + * @class AMSynth uses the output of one Tone.Synth to modulate the + * amplitude of another Tone.Synth. The harmonicity (the ratio between + * the two signals) affects the timbre of the output signal greatly. + * Read more about Amplitude Modulation Synthesis on + * [SoundOnSound](https://web.archive.org/web/20160404103653/http://www.soundonsound.com:80/sos/mar00/articles/synthsecrets.htm). + * <img src="https://docs.google.com/drawings/d/1TQu8Ed4iFr1YTLKpB3U1_hur-UwBrh5gdBXc8BxfGKw/pub?w=1009&h=457"> + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var synth = new Tone.AMSynth().toMaster(); + * synth.triggerAttackRelease("C4", "4n"); + */ + Tone.AMSynth = function (options) { + options = Tone.defaultArg(options, Tone.AMSynth.defaults); + Tone.Monophonic.call(this, options); + /** + * The carrier voice. + * @type {Tone.Synth} + * @private + */ + this._carrier = new Tone.Synth(); + this._carrier.volume.value = -10; + /** + * The carrier's oscillator + * @type {Tone.Oscillator} + */ + this.oscillator = this._carrier.oscillator; + /** + * The carrier's envelope + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = this._carrier.envelope.set(options.envelope); + /** + * The modulator voice. + * @type {Tone.Synth} + * @private + */ + this._modulator = new Tone.Synth(); + this._modulator.volume.value = -10; + /** + * The modulator's oscillator which is applied + * to the amplitude of the oscillator + * @type {Tone.Oscillator} + */ + this.modulation = this._modulator.oscillator.set(options.modulation); + /** + * The modulator's envelope + * @type {Tone.AmplitudeEnvelope} + */ + this.modulationEnvelope = this._modulator.envelope.set(options.modulationEnvelope); + /** + * The frequency. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(440, Tone.Type.Frequency); + /** + * The detune in cents + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * Harmonicity is the ratio between the two voices. A harmonicity of + * 1 is no change. Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch voice1 an octave below voice0 + * synth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + /** + * convert the -1,1 output to 0,1 + * @type {Tone.AudioToGain} + * @private + */ + this._modulationScale = new Tone.AudioToGain(); + /** + * the node where the modulation happens + * @type {Tone.Gain} + * @private + */ + this._modulationNode = new Tone.Gain(); + //control the two voices frequency + this.frequency.connect(this._carrier.frequency); + this.frequency.chain(this.harmonicity, this._modulator.frequency); + this.detune.fan(this._carrier.detune, this._modulator.detune); + this._modulator.chain(this._modulationScale, this._modulationNode.gain); + this._carrier.chain(this._modulationNode, this.output); + this._readOnly([ + 'frequency', + 'harmonicity', + 'oscillator', + 'envelope', + 'modulation', + 'modulationEnvelope', + 'detune' + ]); + }; + Tone.extend(Tone.AMSynth, Tone.Monophonic); + /** + * @static + * @type {Object} + */ + Tone.AMSynth.defaults = { + 'harmonicity': 3, + 'detune': 0, + 'oscillator': { 'type': 'sine' }, + 'envelope': { + 'attack': 0.01, + 'decay': 0.01, + 'sustain': 1, + 'release': 0.5 + }, + 'modulation': { 'type': 'square' }, + 'modulationEnvelope': { + 'attack': 0.5, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + } + }; + /** + * trigger the attack portion of the note + * + * @param {Time} [time=now] the time the note will occur + * @param {NormalRange} [velocity=1] the velocity of the note + * @private + * @returns {Tone.AMSynth} this + */ + Tone.AMSynth.prototype._triggerEnvelopeAttack = function (time, velocity) { + //the port glide + time = this.toSeconds(time); + //the envelopes + this._carrier._triggerEnvelopeAttack(time, velocity); + this._modulator._triggerEnvelopeAttack(time); + return this; + }; + /** + * trigger the release portion of the note + * + * @param {Time} [time=now] the time the note will release + * @private + * @returns {Tone.AMSynth} this + */ + Tone.AMSynth.prototype._triggerEnvelopeRelease = function (time) { + this._carrier._triggerEnvelopeRelease(time); + this._modulator._triggerEnvelopeRelease(time); + return this; + }; + /** + * clean up + * @returns {Tone.AMSynth} this + */ + Tone.AMSynth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'harmonicity', + 'oscillator', + 'envelope', + 'modulation', + 'modulationEnvelope', + 'detune' + ]); + this._carrier.dispose(); + this._carrier = null; + this._modulator.dispose(); + this._modulator = null; + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this._modulationScale.dispose(); + this._modulationScale = null; + this._modulationNode.dispose(); + this._modulationNode = null; + this.oscillator = null; + this.envelope = null; + this.modulationEnvelope = null; + this.modulation = null; + return this; + }; + return Tone.AMSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.MonoSynth is composed of one oscillator, one filter, and two envelopes. + * The amplitude of the Tone.Oscillator and the cutoff frequency of the + * Tone.Filter are controlled by Tone.Envelopes. + * <img src="https://docs.google.com/drawings/d/1gaY1DF9_Hzkodqf8JI1Cg2VZfwSElpFQfI94IQwad38/pub?w=924&h=240"> + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var synth = new Tone.MonoSynth({ + * "oscillator" : { + * "type" : "square" + * }, + * "envelope" : { + * "attack" : 0.1 + * } + * }).toMaster(); + * synth.triggerAttackRelease("C4", "8n"); + */ + Tone.MonoSynth = function (options) { + //get the defaults + options = Tone.defaultArg(options, Tone.MonoSynth.defaults); + Tone.Monophonic.call(this, options); + /** + * The oscillator. + * @type {Tone.OmniOscillator} + */ + this.oscillator = new Tone.OmniOscillator(options.oscillator); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = this.oscillator.frequency; + /** + * The detune control. + * @type {Cents} + * @signal + */ + this.detune = this.oscillator.detune; + /** + * The filter. + * @type {Tone.Filter} + */ + this.filter = new Tone.Filter(options.filter); + /** + * The filter envelope. + * @type {Tone.FrequencyEnvelope} + */ + this.filterEnvelope = new Tone.FrequencyEnvelope(options.filterEnvelope); + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + //connect the oscillators to the output + this.oscillator.chain(this.filter, this.envelope, this.output); + //connect the filter envelope + this.filterEnvelope.connect(this.filter.frequency); + this._readOnly([ + 'oscillator', + 'frequency', + 'detune', + 'filter', + 'filterEnvelope', + 'envelope' + ]); + }; + Tone.extend(Tone.MonoSynth, Tone.Monophonic); + /** + * @const + * @static + * @type {Object} + */ + Tone.MonoSynth.defaults = { + 'frequency': 'C4', + 'detune': 0, + 'oscillator': { 'type': 'square' }, + 'filter': { + 'Q': 6, + 'type': 'lowpass', + 'rolloff': -24 + }, + 'envelope': { + 'attack': 0.005, + 'decay': 0.1, + 'sustain': 0.9, + 'release': 1 + }, + 'filterEnvelope': { + 'attack': 0.06, + 'decay': 0.2, + 'sustain': 0.5, + 'release': 2, + 'baseFrequency': 200, + 'octaves': 7, + 'exponent': 2 + } + }; + /** + * start the attack portion of the envelope + * @param {Time} [time=now] the time the attack should start + * @param {NormalRange} [velocity=1] the velocity of the note (0-1) + * @returns {Tone.MonoSynth} this + * @private + */ + Tone.MonoSynth.prototype._triggerEnvelopeAttack = function (time, velocity) { + time = this.toSeconds(time); + //the envelopes + this.envelope.triggerAttack(time, velocity); + this.filterEnvelope.triggerAttack(time); + this.oscillator.start(time); + if (this.envelope.sustain === 0) { + this.oscillator.stop(time + this.envelope.attack + this.envelope.decay); + } + return this; + }; + /** + * start the release portion of the envelope + * @param {Time} [time=now] the time the release should start + * @returns {Tone.MonoSynth} this + * @private + */ + Tone.MonoSynth.prototype._triggerEnvelopeRelease = function (time) { + this.envelope.triggerRelease(time); + this.filterEnvelope.triggerRelease(time); + this.oscillator.stop(time + this.envelope.release); + return this; + }; + /** + * clean up + * @returns {Tone.MonoSynth} this + */ + Tone.MonoSynth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'oscillator', + 'frequency', + 'detune', + 'filter', + 'filterEnvelope', + 'envelope' + ]); + this.oscillator.dispose(); + this.oscillator = null; + this.envelope.dispose(); + this.envelope = null; + this.filterEnvelope.dispose(); + this.filterEnvelope = null; + this.filter.dispose(); + this.filter = null; + this.frequency = null; + this.detune = null; + return this; + }; + return Tone.MonoSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.DuoSynth is a monophonic synth composed of two + * MonoSynths run in parallel with control over the + * frequency ratio between the two voices and vibrato effect. + * <img src="https://docs.google.com/drawings/d/1bL4GXvfRMMlqS7XyBm9CjL9KJPSUKbcdBNpqOlkFLxk/pub?w=1012&h=448"> + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var duoSynth = new Tone.DuoSynth().toMaster(); + * duoSynth.triggerAttackRelease("C4", "2n"); + */ + Tone.DuoSynth = function (options) { + options = Tone.defaultArg(options, Tone.DuoSynth.defaults); + Tone.Monophonic.call(this, options); + /** + * the first voice + * @type {Tone.MonoSynth} + */ + this.voice0 = new Tone.MonoSynth(options.voice0); + this.voice0.volume.value = -10; + /** + * the second voice + * @type {Tone.MonoSynth} + */ + this.voice1 = new Tone.MonoSynth(options.voice1); + this.voice1.volume.value = -10; + /** + * The vibrato LFO. + * @type {Tone.LFO} + * @private + */ + this._vibrato = new Tone.LFO(options.vibratoRate, -50, 50); + this._vibrato.start(); + /** + * the vibrato frequency + * @type {Frequency} + * @signal + */ + this.vibratoRate = this._vibrato.frequency; + /** + * the vibrato gain + * @type {Tone.Gain} + * @private + */ + this._vibratoGain = new Tone.Gain(options.vibratoAmount, Tone.Type.Positive); + /** + * The amount of vibrato + * @type {Positive} + * @signal + */ + this.vibratoAmount = this._vibratoGain.gain; + /** + * the frequency control + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(440, Tone.Type.Frequency); + /** + * Harmonicity is the ratio between the two voices. A harmonicity of + * 1 is no change. Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch voice1 an octave below voice0 + * duoSynth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + //control the two voices frequency + this.frequency.connect(this.voice0.frequency); + this.frequency.chain(this.harmonicity, this.voice1.frequency); + this._vibrato.connect(this._vibratoGain); + this._vibratoGain.fan(this.voice0.detune, this.voice1.detune); + this.voice0.connect(this.output); + this.voice1.connect(this.output); + this._readOnly([ + 'voice0', + 'voice1', + 'frequency', + 'vibratoAmount', + 'vibratoRate' + ]); + }; + Tone.extend(Tone.DuoSynth, Tone.Monophonic); + /** + * @static + * @type {Object} + */ + Tone.DuoSynth.defaults = { + 'vibratoAmount': 0.5, + 'vibratoRate': 5, + 'harmonicity': 1.5, + 'voice0': { + 'volume': -10, + 'portamento': 0, + 'oscillator': { 'type': 'sine' }, + 'filterEnvelope': { + 'attack': 0.01, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + }, + 'envelope': { + 'attack': 0.01, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + } + }, + 'voice1': { + 'volume': -10, + 'portamento': 0, + 'oscillator': { 'type': 'sine' }, + 'filterEnvelope': { + 'attack': 0.01, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + }, + 'envelope': { + 'attack': 0.01, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + } + } + }; + /** + * start the attack portion of the envelopes + * + * @param {Time} [time=now] the time the attack should start + * @param {NormalRange} [velocity=1] the velocity of the note (0-1) + * @returns {Tone.DuoSynth} this + * @private + */ + Tone.DuoSynth.prototype._triggerEnvelopeAttack = function (time, velocity) { + time = this.toSeconds(time); + this.voice0._triggerEnvelopeAttack(time, velocity); + this.voice1._triggerEnvelopeAttack(time, velocity); + return this; + }; + /** + * start the release portion of the envelopes + * + * @param {Time} [time=now] the time the release should start + * @returns {Tone.DuoSynth} this + * @private + */ + Tone.DuoSynth.prototype._triggerEnvelopeRelease = function (time) { + this.voice0._triggerEnvelopeRelease(time); + this.voice1._triggerEnvelopeRelease(time); + return this; + }; + /** + * Get the level of the output at the given time. Measures + * the envelope(s) value at the time. + * @param {Time} time The time to query the envelope value + * @return {NormalRange} The output level between 0-1 + */ + Tone.DuoSynth.prototype.getLevelAtTime = function (time) { + return (this.voice0.getLevelAtTime(time) + this.voice1.getLevelAtTime(time)) / 2; + }; + /** + * clean up + * @returns {Tone.DuoSynth} this + */ + Tone.DuoSynth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'voice0', + 'voice1', + 'frequency', + 'vibratoAmount', + 'vibratoRate' + ]); + this.voice0.dispose(); + this.voice0 = null; + this.voice1.dispose(); + this.voice1 = null; + this.frequency.dispose(); + this.frequency = null; + this._vibratoGain.dispose(); + this._vibratoGain = null; + this._vibrato = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this.vibratoAmount.dispose(); + this.vibratoAmount = null; + this.vibratoRate = null; + return this; + }; + return Tone.DuoSynth; + }); + Module(function (Tone) { + + /** + * @class FMSynth is composed of two Tone.Synths where one Tone.Synth modulates + * the frequency of a second Tone.Synth. A lot of spectral content + * can be explored using the modulationIndex parameter. Read more about + * frequency modulation synthesis on Sound On Sound: [Part 1](https://web.archive.org/web/20160403123704/http://www.soundonsound.com/sos/apr00/articles/synthsecrets.htm), [Part 2](https://web.archive.org/web/20160403115835/http://www.soundonsound.com/sos/may00/articles/synth.htm). + * <img src="https://docs.google.com/drawings/d/1h0PUDZXPgi4Ikx6bVT6oncrYPLluFKy7lj53puxj-DM/pub?w=902&h=462"> + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var fmSynth = new Tone.FMSynth().toMaster(); + * fmSynth.triggerAttackRelease("C5", "4n"); + */ + Tone.FMSynth = function (options) { + options = Tone.defaultArg(options, Tone.FMSynth.defaults); + Tone.Monophonic.call(this, options); + /** + * The carrier voice. + * @type {Tone.Synth} + * @private + */ + this._carrier = new Tone.Synth(options.carrier); + this._carrier.volume.value = -10; + /** + * The carrier's oscillator + * @type {Tone.Oscillator} + */ + this.oscillator = this._carrier.oscillator; + /** + * The carrier's envelope + * @type {Tone.Oscillator} + */ + this.envelope = this._carrier.envelope.set(options.envelope); + /** + * The modulator voice. + * @type {Tone.Synth} + * @private + */ + this._modulator = new Tone.Synth(options.modulator); + this._modulator.volume.value = -10; + /** + * The modulator's oscillator which is applied + * to the amplitude of the oscillator + * @type {Tone.Oscillator} + */ + this.modulation = this._modulator.oscillator.set(options.modulation); + /** + * The modulator's envelope + * @type {Tone.Oscillator} + */ + this.modulationEnvelope = this._modulator.envelope.set(options.modulationEnvelope); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(440, Tone.Type.Frequency); + /** + * The detune in cents + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * Harmonicity is the ratio between the two voices. A harmonicity of + * 1 is no change. Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch voice1 an octave below voice0 + * synth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + /** + * The modulation index which essentially the depth or amount of the modulation. It is the + * ratio of the frequency of the modulating signal (mf) to the amplitude of the + * modulating signal (ma) -- as in ma/mf. + * @type {Positive} + * @signal + */ + this.modulationIndex = new Tone.Multiply(options.modulationIndex); + this.modulationIndex.units = Tone.Type.Positive; + /** + * the node where the modulation happens + * @type {GainNode} + * @private + */ + this._modulationNode = new Tone.Gain(0); + //control the two voices frequency + this.frequency.connect(this._carrier.frequency); + this.frequency.chain(this.harmonicity, this._modulator.frequency); + this.frequency.chain(this.modulationIndex, this._modulationNode); + this.detune.fan(this._carrier.detune, this._modulator.detune); + this._modulator.connect(this._modulationNode.gain); + this._modulationNode.connect(this._carrier.frequency); + this._carrier.connect(this.output); + this._readOnly([ + 'frequency', + 'harmonicity', + 'modulationIndex', + 'oscillator', + 'envelope', + 'modulation', + 'modulationEnvelope', + 'detune' + ]); + }; + Tone.extend(Tone.FMSynth, Tone.Monophonic); + /** + * @static + * @type {Object} + */ + Tone.FMSynth.defaults = { + 'harmonicity': 3, + 'modulationIndex': 10, + 'detune': 0, + 'oscillator': { 'type': 'sine' }, + 'envelope': { + 'attack': 0.01, + 'decay': 0.01, + 'sustain': 1, + 'release': 0.5 + }, + 'modulation': { 'type': 'square' }, + 'modulationEnvelope': { + 'attack': 0.5, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + } + }; + /** + * trigger the attack portion of the note + * + * @param {Time} [time=now] the time the note will occur + * @param {number} [velocity=1] the velocity of the note + * @returns {Tone.FMSynth} this + * @private + */ + Tone.FMSynth.prototype._triggerEnvelopeAttack = function (time, velocity) { + time = this.toSeconds(time); + //the envelopes + this._carrier._triggerEnvelopeAttack(time, velocity); + this._modulator._triggerEnvelopeAttack(time); + return this; + }; + /** + * trigger the release portion of the note + * + * @param {Time} [time=now] the time the note will release + * @returns {Tone.FMSynth} this + * @private + */ + Tone.FMSynth.prototype._triggerEnvelopeRelease = function (time) { + time = this.toSeconds(time); + this._carrier._triggerEnvelopeRelease(time); + this._modulator._triggerEnvelopeRelease(time); + return this; + }; + /** + * clean up + * @returns {Tone.FMSynth} this + */ + Tone.FMSynth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'harmonicity', + 'modulationIndex', + 'oscillator', + 'envelope', + 'modulation', + 'modulationEnvelope', + 'detune' + ]); + this._carrier.dispose(); + this._carrier = null; + this._modulator.dispose(); + this._modulator = null; + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + this.modulationIndex.dispose(); + this.modulationIndex = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this._modulationNode.dispose(); + this._modulationNode = null; + this.oscillator = null; + this.envelope = null; + this.modulationEnvelope = null; + this.modulation = null; + return this; + }; + return Tone.FMSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.MembraneSynth makes kick and tom sounds using a single oscillator + * with an amplitude envelope and frequency ramp. A Tone.OmniOscillator + * is routed through a Tone.AmplitudeEnvelope to the output. The drum + * quality of the sound comes from the frequency envelope applied + * during Tone.MembraneSynth.triggerAttack(note). The frequency envelope + * starts at <code>note * .octaves</code> and ramps to <code>note</code> + * over the duration of <code>.pitchDecay</code>. + * + * @constructor + * @extends {Tone.Instrument} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var synth = new Tone.MembraneSynth().toMaster(); + * synth.triggerAttackRelease("C2", "8n"); + */ + Tone.MembraneSynth = function (options) { + options = Tone.defaultArg(options, Tone.MembraneSynth.defaults); + Tone.Instrument.call(this, options); + /** + * The oscillator. + * @type {Tone.OmniOscillator} + */ + this.oscillator = new Tone.OmniOscillator(options.oscillator); + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + /** + * The number of octaves the pitch envelope ramps. + * @type {Positive} + */ + this.octaves = options.octaves; + /** + * The amount of time the frequency envelope takes. + * @type {Time} + */ + this.pitchDecay = options.pitchDecay; + this.oscillator.chain(this.envelope, this.output); + this._readOnly([ + 'oscillator', + 'envelope' + ]); + }; + Tone.extend(Tone.MembraneSynth, Tone.Instrument); + /** + * @static + * @type {Object} + */ + Tone.MembraneSynth.defaults = { + 'pitchDecay': 0.05, + 'octaves': 10, + 'oscillator': { 'type': 'sine' }, + 'envelope': { + 'attack': 0.001, + 'decay': 0.4, + 'sustain': 0.01, + 'release': 1.4, + 'attackCurve': 'exponential' + } + }; + /** + * Trigger the note at the given time with the given velocity. + * + * @param {Frequency} note the note + * @param {Time} [time=now] the time, if not given is now + * @param {number} [velocity=1] velocity defaults to 1 + * @returns {Tone.MembraneSynth} this + * @example + * kick.triggerAttack(60); + */ + Tone.MembraneSynth.prototype.triggerAttack = function (note, time, velocity) { + time = this.toSeconds(time); + note = this.toFrequency(note); + var maxNote = note * this.octaves; + this.oscillator.frequency.setValueAtTime(maxNote, time); + this.oscillator.frequency.exponentialRampToValueAtTime(note, time + this.toSeconds(this.pitchDecay)); + this.envelope.triggerAttack(time, velocity); + this.oscillator.start(time); + return this; + }; + /** + * Trigger the release portion of the note. + * + * @param {Time} [time=now] the time the note will release + * @returns {Tone.MembraneSynth} this + */ + Tone.MembraneSynth.prototype.triggerRelease = function (time) { + time = this.toSeconds(time); + this.envelope.triggerRelease(time); + this.oscillator.stop(time + this.envelope.release); + return this; + }; + /** + * Clean up. + * @returns {Tone.MembraneSynth} this + */ + Tone.MembraneSynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + this._writable([ + 'oscillator', + 'envelope' + ]); + this.oscillator.dispose(); + this.oscillator = null; + this.envelope.dispose(); + this.envelope = null; + return this; + }; + return Tone.MembraneSynth; + }); + Module(function (Tone) { + /** + * Inharmonic ratio of frequencies based on the Roland TR-808 + * Taken from https://ccrma.stanford.edu/papers/tr-808-cymbal-physically-informed-circuit-bendable-digital-model + * @private + * @static + * @type {Array} + */ + var inharmRatios = [ + 1, + 1.483, + 1.932, + 2.546, + 2.63, + 3.897 + ]; + /** + * @class A highly inharmonic and spectrally complex source with a highpass filter + * and amplitude envelope which is good for making metalophone sounds. Based + * on CymbalSynth by [@polyrhythmatic](https://github.com/polyrhythmatic). + * Inspiration from [Sound on Sound](https://web.archive.org/web/20160610143924/https://www.soundonsound.com/sos/jul02/articles/synthsecrets0702.asp). + * + * @constructor + * @extends {Tone.Instrument} + * @param {Object} [options] The options availble for the synth + * see defaults below + */ + Tone.MetalSynth = function (options) { + options = Tone.defaultArg(options, Tone.MetalSynth.defaults); + Tone.Instrument.call(this, options); + /** + * The frequency of the cymbal + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The array of FMOscillators + * @type {Array} + * @private + */ + this._oscillators = []; + /** + * The frequency multipliers + * @type {Array} + * @private + */ + this._freqMultipliers = []; + /** + * The amplitude for the body + * @type {Tone.Gain} + * @private + */ + this._amplitue = new Tone.Gain(0).connect(this.output); + /** + * highpass the output + * @type {Tone.Filter} + * @private + */ + this._highpass = new Tone.Filter({ + 'type': 'highpass', + 'Q': -3.0102999566398125 + }).connect(this._amplitue); + /** + * The number of octaves the highpass + * filter frequency ramps + * @type {Number} + * @private + */ + this._octaves = options.octaves; + /** + * Scale the body envelope + * for the bandpass + * @type {Tone.Scale} + * @private + */ + this._filterFreqScaler = new Tone.Scale(options.resonance, 7000); + /** + * The envelope which is connected both to the + * amplitude and highpass filter's cutoff frequency + * @type {Tone.Envelope} + */ + this.envelope = new Tone.Envelope({ + 'attack': options.envelope.attack, + 'attackCurve': 'linear', + 'decay': options.envelope.decay, + 'sustain': 0, + 'release': options.envelope.release + }).chain(this._filterFreqScaler, this._highpass.frequency); + this.envelope.connect(this._amplitue.gain); + for (var i = 0; i < inharmRatios.length; i++) { + var osc = new Tone.FMOscillator({ + 'type': 'square', + 'modulationType': 'square', + 'harmonicity': options.harmonicity, + 'modulationIndex': options.modulationIndex + }); + osc.connect(this._highpass); + this._oscillators[i] = osc; + var mult = new Tone.Multiply(inharmRatios[i]); + this._freqMultipliers[i] = mult; + this.frequency.chain(mult, osc.frequency); + } + //set the octaves + this.octaves = options.octaves; + }; + Tone.extend(Tone.MetalSynth, Tone.Instrument); + /** + * default values + * @static + * @const + * @type {Object} + */ + Tone.MetalSynth.defaults = { + 'frequency': 200, + 'envelope': { + 'attack': 0.001, + 'decay': 1.4, + 'release': 0.2 + }, + 'harmonicity': 5.1, + 'modulationIndex': 32, + 'resonance': 4000, + 'octaves': 1.5 + }; + /** + * Trigger the attack. + * @param {Time} time When the attack should be triggered. + * @param {NormalRange} [velocity=1] The velocity that the envelope should be triggered at. + * @return {Tone.MetalSynth} this + */ + Tone.MetalSynth.prototype.triggerAttack = function (time, vel) { + time = this.toSeconds(time); + vel = Tone.defaultArg(vel, 1); + this.envelope.triggerAttack(time, vel); + this._oscillators.forEach(function (osc) { + osc.start(time); + }); + //if the sustain is 0, stop the oscillator as well + if (this.envelope.sustain === 0) { + this._oscillators.forEach(function (osc) { + osc.stop(time + this.envelope.attack + this.envelope.decay); + }.bind(this)); + } + return this; + }; + /** + * Trigger the release of the envelope. + * @param {Time} time When the release should be triggered. + * @return {Tone.MetalSynth} this + */ + Tone.MetalSynth.prototype.triggerRelease = function (time) { + time = this.toSeconds(time); + this.envelope.triggerRelease(time); + this._oscillators.forEach(function (osc) { + osc.stop(time + this.envelope.release); + }.bind(this)); + return this; + }; + /** + * Sync the instrument to the Transport. All subsequent calls of + * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease) + * will be scheduled along the transport. + * @example + * synth.sync() + * //schedule 3 notes when the transport first starts + * synth.triggerAttackRelease('8n', 0) + * synth.triggerAttackRelease('8n', '8n') + * synth.triggerAttackRelease('8n', '4n') + * //start the transport to hear the notes + * Transport.start() + * @returns {Tone.Instrument} this + */ + Tone.MetalSynth.prototype.sync = function () { + this._syncMethod('triggerAttack', 0); + this._syncMethod('triggerRelease', 0); + return this; + }; + /** + * Trigger the attack and release of the envelope after the given + * duration. + * @param {Time} duration The duration before triggering the release + * @param {Time} time When the attack should be triggered. + * @param {NormalRange} [velocity=1] The velocity that the envelope should be triggered at. + * @return {Tone.MetalSynth} this + */ + Tone.MetalSynth.prototype.triggerAttackRelease = function (duration, time, velocity) { + time = this.toSeconds(time); + duration = this.toSeconds(duration); + this.triggerAttack(time, velocity); + this.triggerRelease(time + duration); + return this; + }; + /** + * The modulationIndex of the oscillators which make up the source. + * see Tone.FMOscillator.modulationIndex + * @memberOf Tone.MetalSynth# + * @type {Positive} + * @name modulationIndex + */ + Object.defineProperty(Tone.MetalSynth.prototype, 'modulationIndex', { + get: function () { + return this._oscillators[0].modulationIndex.value; + }, + set: function (val) { + for (var i = 0; i < this._oscillators.length; i++) { + this._oscillators[i].modulationIndex.value = val; + } + } + }); + /** + * The harmonicity of the oscillators which make up the source. + * see Tone.FMOscillator.harmonicity + * @memberOf Tone.MetalSynth# + * @type {Positive} + * @name harmonicity + */ + Object.defineProperty(Tone.MetalSynth.prototype, 'harmonicity', { + get: function () { + return this._oscillators[0].harmonicity.value; + }, + set: function (val) { + for (var i = 0; i < this._oscillators.length; i++) { + this._oscillators[i].harmonicity.value = val; + } + } + }); + /** + * The frequency of the highpass filter attached to the envelope + * @memberOf Tone.MetalSynth# + * @type {Frequency} + * @name resonance + */ + Object.defineProperty(Tone.MetalSynth.prototype, 'resonance', { + get: function () { + return this._filterFreqScaler.min; + }, + set: function (val) { + this._filterFreqScaler.min = val; + this.octaves = this._octaves; + } + }); + /** + * The number of octaves above the "resonance" frequency + * that the filter ramps during the attack/decay envelope + * @memberOf Tone.MetalSynth# + * @type {Number} + * @name octaves + */ + Object.defineProperty(Tone.MetalSynth.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (octs) { + this._octaves = octs; + this._filterFreqScaler.max = this._filterFreqScaler.min * Math.pow(2, octs); + } + }); + /** + * Clean up + * @returns {Tone.MetalSynth} this + */ + Tone.MetalSynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + for (var i = 0; i < this._oscillators.length; i++) { + this._oscillators[i].dispose(); + this._freqMultipliers[i].dispose(); + } + this._oscillators = null; + this._freqMultipliers = null; + this.frequency.dispose(); + this.frequency = null; + this._filterFreqScaler.dispose(); + this._filterFreqScaler = null; + this._amplitue.dispose(); + this._amplitue = null; + this.envelope.dispose(); + this.envelope = null; + this._highpass.dispose(); + this._highpass = null; + }; + return Tone.MetalSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.NoiseSynth is composed of a noise generator (Tone.Noise), one filter (Tone.Filter), + * and two envelopes (Tone.Envelop). One envelope controls the amplitude + * of the noise and the other is controls the cutoff frequency of the filter. + * <img src="https://docs.google.com/drawings/d/1rqzuX9rBlhT50MRvD2TKml9bnZhcZmzXF1rf_o7vdnE/pub?w=918&h=242"> + * + * @constructor + * @extends {Tone.Instrument} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var noiseSynth = new Tone.NoiseSynth().toMaster(); + * noiseSynth.triggerAttackRelease("8n"); + */ + Tone.NoiseSynth = function (options) { + //get the defaults + options = Tone.defaultArg(options, Tone.NoiseSynth.defaults); + Tone.Instrument.call(this, options); + /** + * The noise source. + * @type {Tone.Noise} + * @example + * noiseSynth.set("noise.type", "brown"); + */ + this.noise = new Tone.Noise(); + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + //connect the noise to the output + this.noise.chain(this.envelope, this.output); + this._readOnly([ + 'noise', + 'envelope' + ]); + }; + Tone.extend(Tone.NoiseSynth, Tone.Instrument); + /** + * @const + * @static + * @type {Object} + */ + Tone.NoiseSynth.defaults = { + 'noise': { 'type': 'white' }, + 'envelope': { + 'attack': 0.005, + 'decay': 0.1, + 'sustain': 0 + } + }; + /** + * Start the attack portion of the envelopes. Unlike other + * instruments, Tone.NoiseSynth doesn't have a note. + * @param {Time} [time=now] the time the attack should start + * @param {number} [velocity=1] the velocity of the note (0-1) + * @returns {Tone.NoiseSynth} this + * @example + * noiseSynth.triggerAttack(); + */ + Tone.NoiseSynth.prototype.triggerAttack = function (time, velocity) { + //the envelopes + this.envelope.triggerAttack(time, velocity); + //start the noise + this.noise.start(time); + if (this.envelope.sustain === 0) { + this.noise.stop(time = this.envelope.attack + this.envelope.decay); + } + return this; + }; + /** + * Start the release portion of the envelopes. + * @param {Time} [time=now] the time the release should start + * @returns {Tone.NoiseSynth} this + */ + Tone.NoiseSynth.prototype.triggerRelease = function (time) { + this.envelope.triggerRelease(time); + this.noise.stop(time + this.envelope.release); + return this; + }; + /** + * Sync the instrument to the Transport. All subsequent calls of + * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease) + * will be scheduled along the transport. + * @example + * synth.sync() + * //schedule 3 notes when the transport first starts + * synth.triggerAttackRelease('8n', 0) + * synth.triggerAttackRelease('8n', '8n') + * synth.triggerAttackRelease('8n', '4n') + * //start the transport to hear the notes + * Transport.start() + * @returns {Tone.Instrument} this + */ + Tone.NoiseSynth.prototype.sync = function () { + this._syncMethod('triggerAttack', 0); + this._syncMethod('triggerRelease', 0); + return this; + }; + /** + * Trigger the attack and then the release. + * @param {Time} duration the duration of the note + * @param {Time} [time=now] the time of the attack + * @param {number} [velocity=1] the velocity + * @returns {Tone.NoiseSynth} this + */ + Tone.NoiseSynth.prototype.triggerAttackRelease = function (duration, time, velocity) { + time = this.toSeconds(time); + duration = this.toSeconds(duration); + this.triggerAttack(time, velocity); + this.triggerRelease(time + duration); + return this; + }; + /** + * Clean up. + * @returns {Tone.NoiseSynth} this + */ + Tone.NoiseSynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + this._writable([ + 'noise', + 'envelope' + ]); + this.noise.dispose(); + this.noise = null; + this.envelope.dispose(); + this.envelope = null; + return this; + }; + return Tone.NoiseSynth; + }); + Module(function (Tone) { + + /** + * @class Karplus-String string synthesis. Often out of tune. + * Will change when the AudioWorkerNode is available across + * browsers. + * + * @constructor + * @extends {Tone.Instrument} + * @param {Object} [options] see the defaults + * @example + * var plucky = new Tone.PluckSynth().toMaster(); + * plucky.triggerAttack("C4"); + */ + Tone.PluckSynth = function (options) { + options = Tone.defaultArg(options, Tone.PluckSynth.defaults); + Tone.Instrument.call(this, options); + /** + * @type {Tone.Noise} + * @private + */ + this._noise = new Tone.Noise('pink'); + /** + * The amount of noise at the attack. + * Nominal range of [0.1, 20] + * @type {number} + */ + this.attackNoise = options.attackNoise; + /** + * the LFCF + * @type {Tone.LowpassCombFilter} + * @private + */ + this._lfcf = new Tone.LowpassCombFilter({ + 'resonance': options.resonance, + 'dampening': options.dampening + }); + /** + * The resonance control. + * @type {NormalRange} + * @signal + */ + this.resonance = this._lfcf.resonance; + /** + * The dampening control. i.e. the lowpass filter frequency of the comb filter + * @type {Frequency} + * @signal + */ + this.dampening = this._lfcf.dampening; + //connections + this._noise.connect(this._lfcf); + this._lfcf.connect(this.output); + this._readOnly([ + 'resonance', + 'dampening' + ]); + }; + Tone.extend(Tone.PluckSynth, Tone.Instrument); + /** + * @static + * @const + * @type {Object} + */ + Tone.PluckSynth.defaults = { + 'attackNoise': 1, + 'dampening': 4000, + 'resonance': 0.7 + }; + /** + * Trigger the note. + * @param {Frequency} note The note to trigger. + * @param {Time} [time=now] When the note should be triggered. + * @returns {Tone.PluckSynth} this + */ + Tone.PluckSynth.prototype.triggerAttack = function (note, time) { + note = this.toFrequency(note); + time = this.toSeconds(time); + var delayAmount = 1 / note; + this._lfcf.delayTime.setValueAtTime(delayAmount, time); + this._noise.start(time); + this._noise.stop(time + delayAmount * this.attackNoise); + return this; + }; + /** + * Clean up. + * @returns {Tone.PluckSynth} this + */ + Tone.PluckSynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + this._noise.dispose(); + this._lfcf.dispose(); + this._noise = null; + this._lfcf = null; + this._writable([ + 'resonance', + 'dampening' + ]); + this.dampening = null; + this.resonance = null; + return this; + }; + return Tone.PluckSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.PolySynth handles voice creation and allocation for any + * instruments passed in as the second paramter. PolySynth is + * not a synthesizer by itself, it merely manages voices of + * one of the other types of synths, allowing any of the + * monophonic synthesizers to be polyphonic. + * + * @constructor + * @extends {Tone.Instrument} + * @param {number|Object} [polyphony=4] The number of voices to create + * @param {function} [voice=Tone.Synth] The constructor of the voices + * uses Tone.Synth by default. + * @example + * //a polysynth composed of 6 Voices of Synth + * var synth = new Tone.PolySynth(6, Tone.Synth).toMaster(); + * //set the attributes using the set interface + * synth.set("detune", -1200); + * //play a chord + * synth.triggerAttackRelease(["C4", "E4", "A4"], "4n"); + */ + Tone.PolySynth = function () { + var options = Tone.defaults(arguments, [ + 'polyphony', + 'voice' + ], Tone.PolySynth); + Tone.Instrument.call(this, options); + options = Tone.defaultArg(options, Tone.Instrument.defaults); + //max polyphony + options.polyphony = Math.min(Tone.PolySynth.MAX_POLYPHONY, options.polyphony); + /** + * the array of voices + * @type {Array} + */ + this.voices = new Array(options.polyphony); + /** + * The queue of voices with data about last trigger + * and the triggered note + * @private + * @type {Array} + */ + this._triggers = new Array(options.polyphony); + /** + * The detune in cents + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + this._readOnly('detune'); + //create the voices + for (var i = 0; i < options.polyphony; i++) { + var v = new options.voice(arguments[2], arguments[3]); + if (!(v instanceof Tone.Monophonic)) { + throw new Error('Synth constructor must be instance of Tone.Monophonic'); + } + this.voices[i] = v; + v.connect(this.output); + if (v.hasOwnProperty('detune')) { + this.detune.connect(v.detune); + } + this._triggers[i] = { + release: -1, + note: null, + voice: v + }; + } + }; + Tone.extend(Tone.PolySynth, Tone.Instrument); + /** + * the defaults + * @const + * @static + * @type {Object} + */ + Tone.PolySynth.defaults = { + 'polyphony': 4, + 'volume': 0, + 'detune': 0, + 'voice': Tone.Synth + }; + /** + * Trigger the attack portion of the note + * @param {Frequency|Array} notes The notes to play. Accepts a single + * Frequency or an array of frequencies. + * @param {Time} [time=now] The start time of the note. + * @param {number} [velocity=1] The velocity of the note. + * @returns {Tone.PolySynth} this + * @example + * //trigger a chord immediately with a velocity of 0.2 + * poly.triggerAttack(["Ab3", "C4", "F5"], undefined, 0.2); + */ + Tone.PolySynth.prototype.triggerAttack = function (notes, time, velocity) { + if (!Array.isArray(notes)) { + notes = [notes]; + } + time = this.toSeconds(time); + for (var i = 0; i < notes.length; i++) { + var val = notes[i]; + //trigger the oldest voice + var oldest = this._triggers[0]; + for (var j = 1; j < this._triggers.length; j++) { + if (this._triggers[j].release < oldest.release) { + oldest = this._triggers[j]; + } + } + oldest.release = Infinity; + oldest.note = JSON.stringify(val); + oldest.voice.triggerAttack(val, time, velocity); + } + return this; + }; + /** + * Trigger the attack and release after the specified duration + * + * @param {Frequency|Array} notes The notes to play. Accepts a single + * Frequency or an array of frequencies. + * @param {Time} duration the duration of the note + * @param {Time} [time=now] if no time is given, defaults to now + * @param {number} [velocity=1] the velocity of the attack (0-1) + * @returns {Tone.PolySynth} this + * @example + * //trigger a chord for a duration of a half note + * poly.triggerAttackRelease(["Eb3", "G4", "C5"], "2n"); + * @example + * //can pass in an array of durations as well + * poly.triggerAttackRelease(["Eb3", "G4", "C5"], ["2n", "4n", "4n"]); + */ + Tone.PolySynth.prototype.triggerAttackRelease = function (notes, duration, time, velocity) { + time = this.toSeconds(time); + this.triggerAttack(notes, time, velocity); + if (Tone.isArray(duration) && Tone.isArray(notes)) { + for (var i = 0; i < notes.length; i++) { + var d = duration[Math.min(i, duration.length - 1)]; + this.triggerRelease(notes[i], time + this.toSeconds(d)); + } + } else { + this.triggerRelease(notes, time + this.toSeconds(duration)); + } + return this; + }; + /** + * Trigger the release of the note. Unlike monophonic instruments, + * a note (or array of notes) needs to be passed in as the first argument. + * @param {Frequency|Array} notes The notes to play. Accepts a single + * Frequency or an array of frequencies. + * @param {Time} [time=now] When the release will be triggered. + * @returns {Tone.PolySynth} this + * @example + * poly.triggerRelease(["Ab3", "C4", "F5"], "+2n"); + */ + Tone.PolySynth.prototype.triggerRelease = function (notes, time) { + if (!Array.isArray(notes)) { + notes = [notes]; + } + time = this.toSeconds(time); + for (var i = 0; i < notes.length; i++) { + //get the voice + var stringified = JSON.stringify(notes[i]); + for (var v = 0; v < this._triggers.length; v++) { + var desc = this._triggers[v]; + if (desc.note === stringified && desc.release > time) { + desc.voice.triggerRelease(time); + desc.release = time; + } + } + } + return this; + }; + /** + * Sync the instrument to the Transport. All subsequent calls of + * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease) + * will be scheduled along the transport. + * @example + * synth.sync() + * //schedule 3 notes when the transport first starts + * synth.triggerAttackRelease('8n', 0) + * synth.triggerAttackRelease('8n', '8n') + * synth.triggerAttackRelease('8n', '4n') + * //start the transport to hear the notes + * Transport.start() + * @returns {Tone.Instrument} this + */ + Tone.PolySynth.prototype.sync = function () { + this._syncMethod('triggerAttack', 1); + this._syncMethod('triggerRelease', 1); + return this; + }; + /** + * Set a member/attribute of the voices. + * @param {Object|string} params + * @param {number=} value + * @param {Time=} rampTime + * @returns {Tone.PolySynth} this + * @example + * poly.set({ + * "filter" : { + * "type" : "highpass" + * }, + * "envelope" : { + * "attack" : 0.25 + * } + * }); + */ + Tone.PolySynth.prototype.set = function (params, value, rampTime) { + for (var i = 0; i < this.voices.length; i++) { + this.voices[i].set(params, value, rampTime); + } + return this; + }; + /** + * Get the synth's attributes. Given no arguments get + * will return all available object properties and their corresponding + * values. Pass in a single attribute to retrieve or an array + * of attributes. The attribute strings can also include a "." + * to access deeper properties. + * @param {Array=} params the parameters to get, otherwise will return + * all available. + */ + Tone.PolySynth.prototype.get = function (params) { + return this.voices[0].get(params); + }; + /** + * Trigger the release portion of all the currently active voices. + * @param {Time} [time=now] When the notes should be released. + * @return {Tone.PolySynth} this + */ + Tone.PolySynth.prototype.releaseAll = function (time) { + time = this.toSeconds(time); + for (var i = 0; i < this._triggers.length; i++) { + var desc = this._triggers[i]; + if (desc.release > time) { + desc.release = time; + desc.voice.triggerRelease(time); + } + } + return this; + }; + /** + * Clean up. + * @returns {Tone.PolySynth} this + */ + Tone.PolySynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + for (var i = 0; i < this.voices.length; i++) { + this.voices[i].dispose(); + this.voices[i] = null; + } + this._writable('detune'); + this.detune.dispose(); + this.detune = null; + this.voices = null; + this._triggers = null; + return this; + }; + /** + * The maximum number of notes that can be allocated + * to a polysynth. + * @type {Number} + * @static + */ + Tone.PolySynth.MAX_POLYPHONY = 20; + return Tone.PolySynth; + }); + Module(function (Tone) { + /** + * @class Automatically interpolates between a set of pitched samples. Pass in an object which maps the note's pitch or midi value to the url, then you can trigger the attack and release of that note like other instruments. By automatically repitching the samples, it is possible to play pitches which were not explicitly included which can save loading time. + * For sample or buffer playback where repitching is not necessary, use [Tone.Player](https://tonejs.github.io/docs/Player). + * @param {Object} samples An object of samples mapping either Midi + * Note Numbers or Scientific Pitch Notation + * to the url of that sample. + * @param {Function=} onload The callback to invoke when all of the samples are loaded. + * @param {String=} baseUrl The root URL of all of the samples, which is prepended to all the URLs. + * @example + * var sampler = new Tone.Sampler({ + * "C3" : "path/to/C3.mp3", + * "D#3" : "path/to/Dsharp3.mp3", + * "F#3" : "path/to/Fsharp3.mp3", + * "A3" : "path/to/A3.mp3", + * }, function(){ + * //sampler will repitch the closest sample + * sampler.triggerAttack("D3") + * }) + * @extends {Tone.Instrument} + */ + Tone.Sampler = function (urls) { + // shift arguments over one. Those are the remainder of the options + var args = Array.prototype.slice.call(arguments); + args.shift(); + var options = Tone.defaults(args, [ + 'onload', + 'baseUrl' + ], Tone.Sampler); + Tone.Instrument.call(this, options); + var urlMap = {}; + for (var note in urls) { + if (Tone.isNote(note)) { + //convert the note name to MIDI + var mid = Tone.Frequency(note).toMidi(); + urlMap[mid] = urls[note]; + } else if (!isNaN(parseFloat(note))) { + //otherwise if it's numbers assume it's midi + urlMap[note] = urls[note]; + } else { + throw new Error('Tone.Sampler: url keys must be the note\'s pitch'); + } + } + /** + * The stored and loaded buffers + * @type {Tone.Buffers} + * @private + */ + this._buffers = new Tone.Buffers(urlMap, options.onload, options.baseUrl); + /** + * The object of all currently playing BufferSources + * @type {Object} + * @private + */ + this._activeSources = {}; + /** + * The envelope applied to the beginning of the sample. + * @type {Time} + */ + this.attack = options.attack; + /** + * The envelope applied to the end of the envelope. + * @type {Time} + */ + this.release = options.release; + }; + Tone.extend(Tone.Sampler, Tone.Instrument); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Sampler.defaults = { + attack: 0, + release: 0.1, + onload: Tone.noOp, + baseUrl: '' + }; + /** + * Returns the difference in steps between the given midi note at the closets sample. + * @param {Midi} midi + * @return {Interval} + * @private + */ + Tone.Sampler.prototype._findClosest = function (midi) { + //searches within 8 octaves of the given midi note + var MAX_INTERVAL = 96; + var interval = 0; + while (interval < MAX_INTERVAL) { + // check above and below + if (this._buffers.has(midi + interval)) { + return -interval; + } else if (this._buffers.has(midi - interval)) { + return interval; + } + interval++; + } + return null; + }; + /** + * @param {Frequency} note The note to play + * @param {Time=} time When to play the note + * @param {NormalRange=} velocity The velocity to play the sample back. + * @return {Tone.Sampler} this + */ + Tone.Sampler.prototype.triggerAttack = function (note, time, velocity) { + var midi = Tone.Frequency(note).toMidi(); + // find the closest note pitch + var difference = this._findClosest(midi); + if (difference !== null) { + var closestNote = midi - difference; + var buffer = this._buffers.get(closestNote); + // play that note + var source = new Tone.BufferSource({ + 'buffer': buffer, + 'playbackRate': Tone.intervalToFrequencyRatio(difference), + 'fadeIn': this.attack, + 'fadeOut': this.release, + 'curve': 'exponential' + }).connect(this.output); + source.start(time, 0, buffer.duration, velocity); + // add it to the active sources + if (!Tone.isArray(this._activeSources[midi])) { + this._activeSources[midi] = []; + } + this._activeSources[midi].push({ + note: midi, + source: source + }); + } + return this; + }; + /** + * @param {Frequency} note The note to release. + * @param {Time=} time When to release the note. + * @return {Tone.Sampler} this + */ + Tone.Sampler.prototype.triggerRelease = function (note, time) { + var midi = Tone.Frequency(note).toMidi(); + // find the note + if (this._activeSources[midi] && this._activeSources[midi].length) { + var source = this._activeSources[midi].shift().source; + time = this.toSeconds(time); + source.stop(time + this.release, this.release); + } + return this; + }; + /** + * Release all currently active notes. + * @param {Time=} time When to release the notes. + * @return {Tone.Sampler} this + */ + Tone.Sampler.prototype.releaseAll = function (time) { + time = this.toSeconds(time); + for (var note in this._activeSources) { + var sources = this._activeSources[note]; + while (sources.length) { + var source = sources.shift().source; + source.stop(time + this.release, this.release); + } + } + return this; + }; + /** + * Sync the instrument to the Transport. All subsequent calls of + * [triggerAttack](#triggerattack) and [triggerRelease](#triggerrelease) + * will be scheduled along the transport. + * @example + * synth.sync() + * //schedule 3 notes when the transport first starts + * synth.triggerAttackRelease('8n', 0) + * synth.triggerAttackRelease('8n', '8n') + * synth.triggerAttackRelease('8n', '4n') + * //start the transport to hear the notes + * Transport.start() + * @returns {Tone.Instrument} this + */ + Tone.Sampler.prototype.sync = function () { + this._syncMethod('triggerAttack', 1); + this._syncMethod('triggerRelease', 1); + return this; + }; + /** + * Invoke the attack phase, then after the duration, invoke the release. + * @param {Frequency} note The note to play + * @param {Time} duration The time the note should be held + * @param {Time=} time When to start the attack + * @param {NormalRange} [velocity=1] The velocity of the attack + * @return {Tone.Sampler} this + */ + Tone.Sampler.prototype.triggerAttackRelease = function (note, duration, time, velocity) { + time = this.toSeconds(time); + duration = this.toSeconds(duration); + this.triggerAttack(note, time, velocity); + this.triggerRelease(note, time + duration); + return this; + }; + /** + * Add a note to the sampler. + * @param {Note|Midi} note The buffer's pitch. + * @param {String|Tone.Buffer|Audiobuffer} url Either the url of the bufer, + * or a buffer which will be added + * with the given name. + * @param {Function=} callback The callback to invoke + * when the url is loaded. + */ + Tone.Sampler.prototype.add = function (note, url, callback) { + if (Tone.isNote(note)) { + //convert the note name to MIDI + var mid = Tone.Frequency(note).toMidi(); + this._buffers.add(mid, url, callback); + } else if (!isNaN(parseFloat(note))) { + //otherwise if it's numbers assume it's midi + this._buffers.add(note, url, callback); + } else { + throw new Error('Tone.Sampler: note must be the note\'s pitch. Instead got ' + note); + } + }; + /** + * If the buffers are loaded or not + * @memberOf Tone.Sampler# + * @type {Boolean} + * @name loaded + * @readOnly + */ + Object.defineProperty(Tone.Sampler.prototype, 'loaded', { + get: function () { + return this._buffers.loaded; + } + }); + /** + * Clean up + * @return {Tone.Sampler} this + */ + Tone.Sampler.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + this._buffers.dispose(); + this._buffers = null; + for (var midi in this._activeSources) { + this._activeSources[midi].forEach(function (event) { + event.source.dispose(); + }); + } + this._activeSources = null; + return this; + }; + return Tone.Sampler; + }); + Module(function (Tone) { + if (Tone.supported) { + if (!OscillatorNode.prototype.setPeriodicWave) { + OscillatorNode.prototype.setPeriodicWave = OscillatorNode.prototype.setWaveTable; + } + if (!AudioContext.prototype.createPeriodicWave) { + AudioContext.prototype.createPeriodicWave = AudioContext.prototype.createWaveTable; + } + } + }); + Module(function (Tone) { + + /** + * @class Maps a NormalRange [0, 1] to an AudioRange [-1, 1]. + * See also Tone.AudioToGain. + * + * @extends {Tone.SignalBase} + * @constructor + * @example + * var g2a = new Tone.GainToAudio(); + */ + Tone.GainToAudio = function () { + Tone.SignalBase.call(this); + /** + * @type {WaveShaperNode} + * @private + */ + this._norm = this.input = this.output = new Tone.WaveShaper(function (x) { + return Math.abs(x) * 2 - 1; + }); + }; + Tone.extend(Tone.GainToAudio, Tone.SignalBase); + /** + * clean up + * @returns {Tone.GainToAudio} this + */ + Tone.GainToAudio.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._norm.dispose(); + this._norm = null; + return this; + }; + return Tone.GainToAudio; + }); + Module(function (Tone) { + + /** + * @class Normalize takes an input min and max and maps it linearly to NormalRange [0,1] + * + * @extends {Tone.SignalBase} + * @constructor + * @param {number} inputMin the min input value + * @param {number} inputMax the max input value + * @example + * var norm = new Tone.Normalize(2, 4); + * var sig = new Tone.Signal(3).connect(norm); + * //output of norm is 0.5. + */ + Tone.Normalize = function (inputMin, inputMax) { + Tone.SignalBase.call(this); + /** + * the min input value + * @type {number} + * @private + */ + this._inputMin = Tone.defaultArg(inputMin, 0); + /** + * the max input value + * @type {number} + * @private + */ + this._inputMax = Tone.defaultArg(inputMax, 1); + /** + * subtract the min from the input + * @type {Tone.Add} + * @private + */ + this._sub = this.input = new Tone.Add(0); + /** + * divide by the difference between the input and output + * @type {Tone.Multiply} + * @private + */ + this._div = this.output = new Tone.Multiply(1); + this._sub.connect(this._div); + this._setRange(); + }; + Tone.extend(Tone.Normalize, Tone.SignalBase); + /** + * The minimum value the input signal will reach. + * @memberOf Tone.Normalize# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.Normalize.prototype, 'min', { + get: function () { + return this._inputMin; + }, + set: function (min) { + this._inputMin = min; + this._setRange(); + } + }); + /** + * The maximum value the input signal will reach. + * @memberOf Tone.Normalize# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.Normalize.prototype, 'max', { + get: function () { + return this._inputMax; + }, + set: function (max) { + this._inputMax = max; + this._setRange(); + } + }); + /** + * set the values + * @private + */ + Tone.Normalize.prototype._setRange = function () { + this._sub.value = -this._inputMin; + this._div.value = 1 / (this._inputMax - this._inputMin); + }; + /** + * clean up + * @returns {Tone.Normalize} this + */ + Tone.Normalize.prototype.dispose = function () { + Tone.SignalBase.prototype.dispose.call(this); + this._sub.dispose(); + this._sub = null; + this._div.dispose(); + this._div = null; + return this; + }; + return Tone.Normalize; + }); + Module(function (Tone) { + /** + * @class Tone.TransportTimelineSignal extends Tone.Signal, but adds the ability to synchronize the signal to the signal to the Tone.Transport + * @extends {Tone.Signal} + */ + Tone.TransportTimelineSignal = function () { + Tone.Signal.apply(this, arguments); + /** + * The real signal output + * @type {Tone.Signal} + * @private + */ + this.output = this._outputSig = new Tone.Signal(this._initialValue); + /** + * Keep track of the last value. (small optimization) + * @private + * @type {Number} + */ + this._lastVal = this.value; + /** + * The event id of the tick update loop + * @private + * @type {Number} + */ + this._synced = Tone.Transport.scheduleRepeat(this._onTick.bind(this), '1i'); + /** + * A bound version of the anchor value methods + * @type {Function} + * @private + */ + this._bindAnchorValue = this._anchorValue.bind(this); + Tone.Transport.on('start stop pause', this._bindAnchorValue); + this._events.memory = Infinity; + }; + Tone.extend(Tone.TransportTimelineSignal, Tone.Signal); + /** + * Callback which is invoked every tick. + * @private + * @param {Number} time + * @return {Tone.TransportTimelineSignal} this + */ + Tone.TransportTimelineSignal.prototype._onTick = function (time) { + var val = this.getValueAtTime(Tone.Transport.seconds); + if (this._lastVal !== val) { + this._lastVal = val; + //approximate ramp curves with linear ramps + this._outputSig.linearRampToValueAtTime(val, time); + } + }; + /** + * Anchor the value at the start and stop of the Transport + * @param {Number} time The time of the event + * @return {Tone.TransportTimelineSignal} this + * @private + */ + Tone.TransportTimelineSignal.prototype._anchorValue = function (time) { + var val = this.getValueAtTime(Tone.Transport.seconds); + this._lastVal = val; + this._outputSig.cancelScheduledValues(time); + this._outputSig.setValueAtTime(val, time); + return this; + }; + /** + * Get the scheduled value at the given time. This will + * return the unconverted (raw) value. + * @param {TransportTime} time The time in seconds. + * @return {Number} The scheduled value at the given time. + */ + Tone.TransportTimelineSignal.prototype.getValueAtTime = function (time) { + time = Tone.TransportTime(time); + return Tone.Signal.prototype.getValueAtTime.call(this, time); + }; + /** + * Set the output of the signal at the given time + * @param {Number} value The value to change to at the given time + * @param {TransportTime} time The time to change the signal + * @return {Tone.TransportTimelineSignal} this + */ + Tone.TransportTimelineSignal.prototype.setValueAtTime = function (value, time) { + time = Tone.TransportTime(time); + Tone.Signal.prototype.setValueAtTime.call(this, value, time); + return this; + }; + /** + * Linear ramp to the given value from the previous scheduled point to the given value + * @param {Number} value The value to change to at the given time + * @param {TransportTime} time The time to change the signal + * @return {Tone.TransportTimelineSignal} this + */ + Tone.TransportTimelineSignal.prototype.linearRampToValueAtTime = function (value, time) { + time = Tone.TransportTime(time); + Tone.Signal.prototype.linearRampToValueAtTime.call(this, value, time); + return this; + }; + /** + * Exponential ramp to the given value from the previous scheduled point to the given value + * @param {Number} value The value to change to at the given time + * @param {TransportTime} time The time to change the signal + * @return {Tone.TransportTimelineSignal} this + */ + Tone.TransportTimelineSignal.prototype.exponentialRampToValueAtTime = function (value, time) { + time = Tone.TransportTime(time); + Tone.Signal.prototype.exponentialRampToValueAtTime.call(this, value, time); + return this; + }; + /** + * Start exponentially approaching the target value at the given time with + * a rate having the given time constant. + * @param {number} value + * @param {TransportTime} startTime + * @param {number} timeConstant + * @return {Tone.TransportTimelineSignal} this + */ + Tone.TransportTimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) { + startTime = Tone.TransportTime(startTime); + Tone.Signal.prototype.setTargetAtTime.call(this, value, startTime, timeConstant); + return this; + }; + /** + * Cancels all scheduled parameter changes with times greater than or + * equal to startTime. + * @param {TransportTime} startTime + * @returns {Tone.Param} this + */ + Tone.TransportTimelineSignal.prototype.cancelScheduledValues = function (startTime) { + startTime = Tone.TransportTime(startTime); + Tone.Signal.prototype.cancelScheduledValues.call(this, startTime); + return this; + }; + /** + * Set an array of arbitrary values starting at the given time for the given duration. + * @param {Float32Array} values + * @param {Time} startTime + * @param {Time} duration + * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value + * @returns {Tone.Signal} this + */ + Tone.TransportTimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) { + startTime = Tone.TransportTime(startTime); + duration = Tone.TransportTime(duration); + Tone.Signal.prototype.setValueCurveAtTime.call(this, values, startTime, duration, scaling); + return this; + }; + /** + * This is similar to [cancelScheduledValues](#cancelScheduledValues) except + * it holds the automated value at time until the next automated event. + * @param {Time} time + * @returns {Tone.TransportTimelineSignal} this + */ + Tone.TransportTimelineSignal.prototype.cancelAndHoldAtTime = function (time) { + return Tone.Signal.prototype.cancelAndHoldAtTime.call(this, Tone.TransportTime(time)); + }; + /** + * Dispose and disconnect + * @return {Tone.TransportTimelineSignal} this + */ + Tone.TransportTimelineSignal.prototype.dispose = function () { + Tone.Transport.clear(this._synced); + Tone.Transport.off('start stop pause', this._syncedCallback); + this._events.cancel(0); + Tone.Signal.prototype.dispose.call(this); + this._outputSig.dispose(); + this._outputSig = null; + }; + return Tone.TransportTimelineSignal; + }); + Module(function (Tone) { + /** + * @class Tone.GrainPlayer implements [granular synthesis](https://en.wikipedia.org/wiki/Granular_synthesis). + * Granular Synthesis enables you to adjust pitch and playback rate independently. The grainSize is the + * amount of time each small chunk of audio is played for and the overlap is the + * amount of crossfading transition time between successive grains. + * @extends {Tone.Source} + * @param {String|Tone.Buffer} url The url to load, or the Tone.Buffer to play. + * @param {Function=} callback The callback to invoke after the url is loaded. + */ + Tone.GrainPlayer = function () { + var options = Tone.defaults(arguments, [ + 'url', + 'onload' + ], Tone.GrainPlayer); + Tone.Source.call(this, options); + /** + * The audio buffer belonging to the player. + * @type {Tone.Buffer} + */ + this.buffer = new Tone.Buffer(options.url, options.onload); + /** + * Create a repeating tick to schedule + * the grains. + * @type {Tone.Clock} + * @private + */ + this._clock = new Tone.Clock(this._tick.bind(this), options.grainSize); + /** + * @type {Number} + * @private + */ + this._loopStart = 0; + /** + * @type {Number} + * @private + */ + this._loopEnd = 0; + /** + * All of the currently playing BufferSources + * @type {Array} + * @private + */ + this._activeSources = []; + /** + * @type {Number} + * @private + */ + this._playbackRate = options.playbackRate; + /** + * @type {Number} + * @private + */ + this._grainSize = options.grainSize; + /** + * @private + * @type {Number} + */ + this._overlap = options.overlap; + /** + * Adjust the pitch independently of the playbackRate. + * @type {Cents} + */ + this.detune = options.detune; + //setup + this.overlap = options.overlap; + this.loop = options.loop; + this.playbackRate = options.playbackRate; + this.grainSize = options.grainSize; + this.loopStart = options.loopStart; + this.loopEnd = options.loopEnd; + this.reverse = options.reverse; + this._clock.on('stop', this._onstop.bind(this)); + }; + Tone.extend(Tone.GrainPlayer, Tone.Source); + /** + * the default parameters + * @static + * @const + * @type {Object} + */ + Tone.GrainPlayer.defaults = { + 'onload': Tone.noOp, + 'overlap': 0.1, + 'grainSize': 0.2, + 'playbackRate': 1, + 'detune': 0, + 'loop': false, + 'loopStart': 0, + 'loopEnd': 0, + 'reverse': false + }; + /** + * Play the buffer at the given startTime. Optionally add an offset + * and/or duration which will play the buffer from a position + * within the buffer for the given duration. + * + * @param {Time} [startTime=now] When the player should start. + * @param {Time} [offset=0] The offset from the beginning of the sample + * to start at. + * @param {Time=} duration How long the sample should play. If no duration + * is given, it will default to the full length + * of the sample (minus any offset) + * @returns {Tone.GrainPlayer} this + * @memberOf Tone.GrainPlayer# + * @method start + * @name start + */ + /** + * Internal start method + * @param {Time} time + * @param {Time} offset + * @private + */ + Tone.GrainPlayer.prototype._start = function (time, offset, duration) { + offset = Tone.defaultArg(offset, 0); + offset = this.toSeconds(offset); + time = this.toSeconds(time); + this._offset = offset; + this._clock.start(time); + if (duration) { + this.stop(time + this.toSeconds(duration)); + } + }; + /** + * Internal start method + * @param {Time} time + * @private + */ + Tone.GrainPlayer.prototype._stop = function (time) { + this._clock.stop(time); + }; + /** + * Invoked when the clock is stopped + * @param {Number} time + * @private + */ + Tone.GrainPlayer.prototype._onstop = function (time) { + //stop the players + this._activeSources.forEach(function (source) { + source.stop(time, 0); + }); + }; + /** + * Invoked on each clock tick. scheduled a new + * grain at this time. + * @param {Time} time + * @private + */ + Tone.GrainPlayer.prototype._tick = function (time) { + var fadeIn = this._offset < this._overlap ? 0 : this._overlap; + var source = new Tone.BufferSource({ + 'buffer': this.buffer, + 'fadeIn': fadeIn, + 'fadeOut': this._overlap, + 'loop': this.loop, + 'loopStart': this._loopStart, + 'loopEnd': this._loopEnd, + 'playbackRate': Tone.intervalToFrequencyRatio(this.detune / 100) + }).connect(this.output); + source.start(time, this._offset); + this._offset += this.grainSize; + source.stop(time + this.grainSize); + //add it to the active sources + this._activeSources.push(source); + //remove it when it's done + source.onended = function () { + var index = this._activeSources.indexOf(source); + if (index !== -1) { + this._activeSources.splice(index, 1); + } + }.bind(this); + }; + /** + * Jump to a specific time and play it. + * @param {Time} offset The offset to jump to. + * @param {Time=} time When to make the jump. + * @return {Tone.GrainPlayer} this + */ + Tone.GrainPlayer.prototype.seek = function (offset, time) { + this._offset = this.toSeconds(offset); + this._tick(this.toSeconds(time)); + return this; + }; + /** + * The playback rate of the sample + * @memberOf Tone.GrainPlayer# + * @type {Positive} + * @name playbackRate + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + this.grainSize = this._grainSize; + } + }); + /** + * The loop start time. + * @memberOf Tone.GrainPlayer# + * @type {Time} + * @name loopStart + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'loopStart', { + get: function () { + return this._loopStart; + }, + set: function (time) { + this._loopStart = this.toSeconds(time); + } + }); + /** + * The loop end time. + * @memberOf Tone.GrainPlayer# + * @type {Time} + * @name loopEnd + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'loopEnd', { + get: function () { + return this._loopEnd; + }, + set: function (time) { + this._loopEnd = this.toSeconds(time); + } + }); + /** + * The direction the buffer should play in + * @memberOf Tone.GrainPlayer# + * @type {boolean} + * @name reverse + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'reverse', { + get: function () { + return this.buffer.reverse; + }, + set: function (rev) { + this.buffer.reverse = rev; + } + }); + /** + * The size of each chunk of audio that the + * buffer is chopped into and played back at. + * @memberOf Tone.GrainPlayer# + * @type {Time} + * @name grainSize + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'grainSize', { + get: function () { + return this._grainSize; + }, + set: function (size) { + this._grainSize = this.toSeconds(size); + this._clock.frequency.value = this._playbackRate / this._grainSize; + } + }); + /** + * This is the duration of the cross-fade between + * sucessive grains. + * @memberOf Tone.GrainPlayer# + * @type {Time} + * @name overlap + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'overlap', { + get: function () { + return this._overlap; + }, + set: function (time) { + this._overlap = this.toSeconds(time); + } + }); + /** + * Clean up + * @return {Tone.GrainPlayer} this + */ + Tone.GrainPlayer.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this.buffer.dispose(); + this.buffer = null; + this._clock.dispose(); + this._clock = null; + this._activeSources.forEach(function (source) { + source.dispose(); + }); + this._activeSources = null; + return this; + }; + return Tone.GrainPlayer; + }); + Module(function (Tone) { + + /** + * @class Tone.Player is an audio file player with start, loop, and stop functions. + * + * @constructor + * @extends {Tone.Source} + * @param {string|AudioBuffer} url Either the AudioBuffer or the url from + * which to load the AudioBuffer + * @param {Function=} onload The function to invoke when the buffer is loaded. + * Recommended to use Tone.Buffer.on('load') instead. + * @example + * var player = new Tone.Player("./path/to/sample.mp3").toMaster(); + * //play as soon as the buffer is loaded + * player.autostart = true; + */ + Tone.Player = function (url) { + var options; + if (url instanceof Tone.Buffer && url.loaded) { + url = url.get(); + options = Tone.Player.defaults; + } else { + options = Tone.defaults(arguments, [ + 'url', + 'onload' + ], Tone.Player); + } + Tone.Source.call(this, options); + /** + * If the file should play as soon + * as the buffer is loaded. + * @type {Boolean} + * @example + * //will play as soon as it's loaded + * var player = new Tone.Player({ + * "url" : "./path/to/sample.mp3", + * "autostart" : true, + * }).toMaster(); + */ + this.autostart = options.autostart; + /** + * the buffer + * @private + * @type {Tone.Buffer} + */ + this._buffer = new Tone.Buffer({ + 'url': options.url, + 'onload': this._onload.bind(this, options.onload), + 'reverse': options.reverse + }); + if (url instanceof AudioBuffer) { + this._buffer.set(url); + } + /** + * if the buffer should loop once it's over + * @type {Boolean} + * @private + */ + this._loop = options.loop; + /** + * if 'loop' is true, the loop will start at this position + * @type {Time} + * @private + */ + this._loopStart = options.loopStart; + /** + * if 'loop' is true, the loop will end at this position + * @type {Time} + * @private + */ + this._loopEnd = options.loopEnd; + /** + * the playback rate + * @private + * @type {Number} + */ + this._playbackRate = options.playbackRate; + /** + * All of the active buffer source nodes + * @type {Array<Tone.BufferSource>} + * @private + */ + this._activeSources = []; + /** + * The elapsed time counter. + * @type {Tone.TickSource} + * @private + */ + this._elapsedTime = new Tone.TickSource(options.playbackRate); + /** + * The fadeIn time of the amplitude envelope. + * @type {Time} + */ + this.fadeIn = options.fadeIn; + /** + * The fadeOut time of the amplitude envelope. + * @type {Time} + */ + this.fadeOut = options.fadeOut; + }; + Tone.extend(Tone.Player, Tone.Source); + /** + * the default parameters + * @static + * @const + * @type {Object} + */ + Tone.Player.defaults = { + 'onload': Tone.noOp, + 'playbackRate': 1, + 'loop': false, + 'autostart': false, + 'loopStart': 0, + 'loopEnd': 0, + 'retrigger': false, + 'reverse': false, + 'fadeIn': 0, + 'fadeOut': 0 + }; + /** + * Load the audio file as an audio buffer. + * Decodes the audio asynchronously and invokes + * the callback once the audio buffer loads. + * Note: this does not need to be called if a url + * was passed in to the constructor. Only use this + * if you want to manually load a new url. + * @param {string} url The url of the buffer to load. + * Filetype support depends on the + * browser. + * @param {Function=} callback The function to invoke once + * the sample is loaded. + * @returns {Promise} + */ + Tone.Player.prototype.load = function (url, callback) { + return this._buffer.load(url, this._onload.bind(this, callback)); + }; + /** + * Internal callback when the buffer is loaded. + * @private + */ + Tone.Player.prototype._onload = function (callback) { + callback = Tone.defaultArg(callback, Tone.noOp); + callback(this); + if (this.autostart) { + this.start(); + } + }; + /** + * Internal callback when the buffer is done playing. + * @private + */ + Tone.Player.prototype._onSourceEnd = function (source) { + var index = this._activeSources.indexOf(source); + this._activeSources.splice(index, 1); + }; + /** + * Play the buffer at the given startTime. Optionally add an offset + * and/or duration which will play the buffer from a position + * within the buffer for the given duration. + * + * @param {Time} [startTime=now] When the player should start. + * @param {Time} [offset=0] The offset from the beginning of the sample + * to start at. + * @param {Time=} duration How long the sample should play. If no duration + * is given, it will default to the full length + * of the sample (minus any offset) + * @returns {Tone.Player} this + * @memberOf Tone.Player# + * @method start + * @name start + */ + /** + * Internal start method + * @private + */ + Tone.Player.prototype._start = function (startTime, offset, duration) { + //if it's a loop the default offset is the loopstart point + if (this._loop) { + offset = Tone.defaultArg(offset, this._loopStart); + } else { + //otherwise the default offset is 0 + offset = Tone.defaultArg(offset, 0); + } + //compute the values in seconds + offset = this.toSeconds(offset); + var computedDuration = Tone.defaultArg(duration, Math.max(this._buffer.duration - offset, 0)); + computedDuration = this.toSeconds(computedDuration); + startTime = this.toSeconds(startTime); + //start the elapsed time counter + this._elapsedTime.start(startTime, offset); + //make the source + var source = new Tone.BufferSource({ + 'buffer': this._buffer, + 'loop': this._loop, + 'loopStart': this._loopStart, + 'loopEnd': this._loopEnd, + 'onended': this._onSourceEnd.bind(this), + 'playbackRate': this._playbackRate, + 'fadeIn': this.fadeIn, + 'fadeOut': this.fadeOut + }).connect(this.output); + //set the looping properties + if (!this._loop && !this._synced) { + //if it's not looping, set the state change at the end of the sample + this._state.setStateAtTime(Tone.State.Stopped, startTime + computedDuration / this._playbackRate); + } + //add it to the array of active sources + this._activeSources.push(source); + //start it + if (this._loop && Tone.isUndef(duration)) { + source.start(startTime, offset); + } else { + source.start(startTime, offset, computedDuration); + } + return this; + }; + /** + * Stop playback. + * @private + * @param {Time} [time=now] + * @returns {Tone.Player} this + */ + Tone.Player.prototype._stop = function (time) { + time = this.toSeconds(time); + this._elapsedTime.stop(time); + this._activeSources.forEach(function (source) { + source.stop(time); + }); + return this; + }; + /** + * Stop and then restart the player from the beginning (or offset) + * @param {Time} [startTime=now] When the player should start. + * @param {Time} [offset=0] The offset from the beginning of the sample + * to start at. + * @param {Time=} duration How long the sample should play. If no duration + * is given, it will default to the full length + * of the sample (minus any offset) + * @returns {Tone.Player} this + */ + Tone.Player.prototype.restart = function (time, offset, duration) { + this._stop(time); + this._start(time, offset, duration); + return this; + }; + /** + * Seek to a specific time in the player's buffer. If the + * source is no longer playing at that time, it will stop. + * If you seek to a time that + * @param {Time} offset The time to seek to. + * @param {Time=} time The time for the seek event to occur. + * @return {Tone.Player} this + * @example + * source.start(0.2); + * source.stop(0.4); + */ + Tone.Player.prototype.seek = function (offset, time) { + time = this.toSeconds(time); + if (this._state.getValueAtTime(time) === Tone.State.Started) { + offset = this.toSeconds(offset); + // if it's currently playing, stop it + this._stop(time); + //restart it at the given time + this._start(time, offset); + } + return this; + }; + /** + * Set the loop start and end. Will only loop if loop is + * set to true. + * @param {Time} loopStart The loop end time + * @param {Time} loopEnd The loop end time + * @returns {Tone.Player} this + * @example + * //loop 0.1 seconds of the file. + * player.setLoopPoints(0.2, 0.3); + * player.loop = true; + */ + Tone.Player.prototype.setLoopPoints = function (loopStart, loopEnd) { + this.loopStart = loopStart; + this.loopEnd = loopEnd; + return this; + }; + /** + * If loop is true, the loop will start at this position. + * @memberOf Tone.Player# + * @type {Time} + * @name loopStart + */ + Object.defineProperty(Tone.Player.prototype, 'loopStart', { + get: function () { + return this._loopStart; + }, + set: function (loopStart) { + this._loopStart = loopStart; + //get the current source + this._activeSources.forEach(function (source) { + source.loopStart = loopStart; + }); + } + }); + /** + * If loop is true, the loop will end at this position. + * @memberOf Tone.Player# + * @type {Time} + * @name loopEnd + */ + Object.defineProperty(Tone.Player.prototype, 'loopEnd', { + get: function () { + return this._loopEnd; + }, + set: function (loopEnd) { + this._loopEnd = loopEnd; + //get the current source + this._activeSources.forEach(function (source) { + source.loopEnd = loopEnd; + }); + } + }); + /** + * The audio buffer belonging to the player. + * @memberOf Tone.Player# + * @type {Tone.Buffer} + * @name buffer + */ + Object.defineProperty(Tone.Player.prototype, 'buffer', { + get: function () { + return this._buffer; + }, + set: function (buffer) { + this._buffer.set(buffer); + } + }); + /** + * If the buffer should loop once it's over. + * @memberOf Tone.Player# + * @type {Boolean} + * @name loop + */ + Object.defineProperty(Tone.Player.prototype, 'loop', { + get: function () { + return this._loop; + }, + set: function (loop) { + //if no change, do nothing + if (this._loop === loop) { + return; + } + this._loop = loop; + var now = this.now(); + if (!loop) { + //stop the playback on the next cycle + this._stopAtNextIteration(now); + } else { + //remove the next stopEvent + var stopEvent = this._state.getNextState(Tone.State.Stopped, now); + if (stopEvent) { + this._activeSources.forEach(function (source) { + source.loop = loop; + }); + this._state.cancel(stopEvent.time); + this._elapsedTime.cancel(stopEvent.time); + } + } + } + }); + /** + * Schedules a stop event at the next full iteration. Used + * for scheduling stop when the loop state or playbackRate changes + * @param {Number} now The current time + * @private + */ + Tone.Player.prototype._stopAtNextIteration = function (now) { + if (this._state.getValueAtTime(now) === Tone.State.Started) { + var nextStop = this._state.getNextState(Tone.State.Stopped, now); + var position = this._elapsedTime.getTicksAtTime(now); + var iterations = Math.max(Math.ceil(position / this.buffer.duration), 1); + var stopTime = this._elapsedTime.getTimeOfTick(iterations * this.buffer.duration, nextStop ? nextStop.time - this.sampleTime : Infinity); + this.stop(stopTime); + } + }; + /** + * The playback speed. 1 is normal speed. This is not a signal because + * Safari and iOS currently don't support playbackRate as a signal. + * @memberOf Tone.Player# + * @type {Number} + * @name playbackRate + */ + Object.defineProperty(Tone.Player.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + var now = this.now(); + this._elapsedTime.frequency.setValueAtTime(rate, now); + //if it's not looping + if (!this._loop) { + this._stopAtNextIteration(now); + } + //set all the sources + this._activeSources.forEach(function (source) { + source.playbackRate.setValueAtTime(rate, now); + }); + } + }); + /** + * The current playback position of the buffer. + * @memberOf Tone.Player# + * @type {Number} + * @name position + */ + Object.defineProperty(Tone.Player.prototype, 'position', { + get: function () { + var now = this.now(); + if (this._state.getValueAtTime(now) === Tone.State.Started && this.loaded) { + var duration = this.buffer.duration; + var position = this._elapsedTime.getTicksAtTime(now); + return position % duration; + } else { + return 0; + } + } + }); + /** + * The direction the buffer should play in + * @memberOf Tone.Player# + * @type {Boolean} + * @name reverse + */ + Object.defineProperty(Tone.Player.prototype, 'reverse', { + get: function () { + return this._buffer.reverse; + }, + set: function (rev) { + this._buffer.reverse = rev; + } + }); + /** + * If all the buffer is loaded + * @memberOf Tone.Player# + * @type {Boolean} + * @name loaded + * @readOnly + */ + Object.defineProperty(Tone.Player.prototype, 'loaded', { + get: function () { + return this._buffer.loaded; + } + }); + /** + * Dispose and disconnect. + * @return {Tone.Player} this + */ + Tone.Player.prototype.dispose = function () { + //disconnect all of the players + this._activeSources.forEach(function (source) { + source.dispose(); + }); + this._activeSources = null; + Tone.Source.prototype.dispose.call(this); + this._buffer.dispose(); + this._buffer = null; + this._elapsedTime.dispose(); + this._elapsedTime = null; + return this; + }; + return Tone.Player; + }); + Module(function (Tone) { + + /** + * @class Tone.Players combines multiple [Tone.Player](Player) objects. + * + * @constructor + * @extends {Tone.AudioNode} + * @param {Object} urls An object mapping a name to a url. + * @param {function=} onload The function to invoke when all buffers are loaded. + */ + Tone.Players = function (urls) { + var args = Array.prototype.slice.call(arguments); + args.shift(); + var options = Tone.defaults(args, ['onload'], Tone.Players); + Tone.call(this); + /** + * The output volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume of the output in decibels. + * @type {Decibels} + * @signal + * @example + * source.volume.value = -6; + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + //make the output explicitly stereo + this._volume.output.output.channelCount = 2; + this._volume.output.output.channelCountMode = 'explicit'; + //mute initially + this.mute = options.mute; + /** + * The container of all of the players + * @type {Object} + * @private + */ + this._players = {}; + /** + * The loading count + * @type {Number} + * @private + */ + this._loadingCount = 0; + /** + * private holder of the fadeIn time + * @type {Time} + * @private + */ + this._fadeIn = options.fadeIn; + /** + * private holder of the fadeOut time + * @type {Time} + * @private + */ + this._fadeOut = options.fadeOut; + //add all of the players + for (var name in urls) { + this._loadingCount++; + this.add(name, urls[name], this._bufferLoaded.bind(this, options.onload)); + } + }; + Tone.extend(Tone.Players, Tone.AudioNode); + /** + * The default values + * @type {Object} + */ + Tone.Players.defaults = { + 'volume': 0, + 'mute': false, + 'onload': Tone.noOp, + 'fadeIn': 0, + 'fadeOut': 0 + }; + /** + * A buffer was loaded. decrement the counter. + * @param {Function} callback + * @private + */ + Tone.Players.prototype._bufferLoaded = function (callback) { + this._loadingCount--; + if (this._loadingCount === 0 && callback) { + callback(this); + } + }; + /** + * Mute the output. + * @memberOf Tone.Source# + * @type {boolean} + * @name mute + * @example + * //mute the output + * source.mute = true; + */ + Object.defineProperty(Tone.Players.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + /** + * The fadeIn time of the amplitude envelope. + * @memberOf Tone.Source# + * @type {Time} + * @name fadeIn + */ + Object.defineProperty(Tone.Players.prototype, 'fadeIn', { + get: function () { + return this._fadeIn; + }, + set: function (fadeIn) { + this._fadeIn = fadeIn; + this._forEach(function (player) { + player.fadeIn = fadeIn; + }); + } + }); + /** + * The fadeOut time of the amplitude envelope. + * @memberOf Tone.Source# + * @type {Time} + * @name fadeOut + */ + Object.defineProperty(Tone.Players.prototype, 'fadeOut', { + get: function () { + return this._fadeOut; + }, + set: function (fadeOut) { + this._fadeOut = fadeOut; + this._forEach(function (player) { + player.fadeOut = fadeOut; + }); + } + }); + /** + * The state of the players object. Returns "started" if any of the players are playing. + * @memberOf Tone.Players# + * @type {String} + * @name state + * @readOnly + */ + Object.defineProperty(Tone.Players.prototype, 'state', { + get: function () { + var playing = false; + this._forEach(function (player) { + playing = playing || player.state === Tone.State.Started; + }); + return playing ? Tone.State.Started : Tone.State.Stopped; + } + }); + /** + * True if the buffers object has a buffer by that name. + * @param {String|Number} name The key or index of the + * buffer. + * @return {Boolean} + */ + Tone.Players.prototype.has = function (name) { + return this._players.hasOwnProperty(name); + }; + /** + * Get a player by name. + * @param {String} name The players name as defined in + * the constructor object or `add` method. + * @return {Tone.Player} + */ + Tone.Players.prototype.get = function (name) { + if (this.has(name)) { + return this._players[name]; + } else { + throw new Error('Tone.Players: no player named ' + name); + } + }; + /** + * Iterate over all of the players + * @param {Function} callback + * @return {Tone.Players} this + * @private + */ + Tone.Players.prototype._forEach = function (callback) { + for (var playerName in this._players) { + callback(this._players[playerName], playerName); + } + return this; + }; + /** + * If all the buffers are loaded or not + * @memberOf Tone.Players# + * @type {Boolean} + * @name loaded + * @readOnly + */ + Object.defineProperty(Tone.Players.prototype, 'loaded', { + get: function () { + var isLoaded = true; + this._forEach(function (player) { + isLoaded = isLoaded && player.loaded; + }); + return isLoaded; + } + }); + /** + * Add a player by name and url to the Players + * @param {String} name A unique name to give the player + * @param {String|Tone.Buffer|Audiobuffer} url Either the url of the bufer, + * or a buffer which will be added + * with the given name. + * @param {Function=} callback The callback to invoke + * when the url is loaded. + */ + Tone.Players.prototype.add = function (name, url, callback) { + this._players[name] = new Tone.Player(url, callback).connect(this.output); + this._players[name].fadeIn = this._fadeIn; + this._players[name].fadeOut = this._fadeOut; + return this; + }; + /** + * Stop all of the players at the given time + * @param {Time} time The time to stop all of the players. + * @return {Tone.Players} this + */ + Tone.Players.prototype.stopAll = function (time) { + this._forEach(function (player) { + player.stop(time); + }); + }; + /** + * Dispose and disconnect. + * @return {Tone.Players} this + */ + Tone.Players.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this._volume.dispose(); + this._volume = null; + this._writable('volume'); + this.volume = null; + this.output = null; + this._forEach(function (player) { + player.dispose(); + }); + this._players = null; + return this; + }; + return Tone.Players; + }); + Module(function (Tone) { + + /** + * @class Tone.UserMedia uses MediaDevices.getUserMedia to open up + * and external microphone or audio input. Check + * [MediaDevices API Support](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia) + * to see which browsers are supported. Access to an external input + * is limited to secure (HTTPS) connections. + * + * @constructor + * @extends {Tone.AudioNode} + * @param {Decibels=} volume The level of the input + * @example + * //list the inputs and open the third one + * var motu = new Tone.UserMedia(); + * + * //opening the input asks the user to activate their mic + * motu.open().then(function(){ + * //promise resolves when input is available + * }); + */ + Tone.UserMedia = function () { + var options = Tone.defaults(arguments, ['volume'], Tone.UserMedia); + Tone.AudioNode.call(this); + /** + * The MediaStreamNode + * @type {MediaStreamAudioSourceNode} + * @private + */ + this._mediaStream = null; + /** + * The media stream created by getUserMedia. + * @type {LocalMediaStream} + * @private + */ + this._stream = null; + /** + * The open device + * @type {MediaDeviceInfo} + * @private + */ + this._device = null; + /** + * The output volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume of the output in decibels. + * @type {Decibels} + * @signal + * @example + * input.volume.value = -6; + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + this.mute = options.mute; + }; + Tone.extend(Tone.UserMedia, Tone.AudioNode); + /** + * the default parameters + * @type {Object} + */ + Tone.UserMedia.defaults = { + 'volume': 0, + 'mute': false + }; + /** + * Open the media stream. If a string is passed in, it is assumed + * to be the label or id of the stream, if a number is passed in, + * it is the input number of the stream. + * @param {String|Number} [labelOrId="default"] The label or id of the audio input media device. + * With no argument, the default stream is opened. + * @return {Promise} The promise is resolved when the stream is open. + */ + Tone.UserMedia.prototype.open = function (labelOrId) { + return Tone.UserMedia.enumerateDevices().then(function (devices) { + var device; + if (Tone.isNumber(labelOrId)) { + device = devices[labelOrId]; + } else { + device = devices.find(function (device) { + return device.label === labelOrId || device.deviceId === labelOrId; + }); + //didn't find a matching device + if (!device && devices.length > 0) { + device = devices[0]; + } else if (!device && Tone.isDefined(labelOrId)) { + throw new Error('Tone.UserMedia: no matching device: ' + labelOrId); + } + } + this._device = device; + //do getUserMedia + var constraints = { + audio: { + 'echoCancellation': false, + 'sampleRate': this.context.sampleRate + } + }; + if (device) { + constraints.audio.deviceId = device.deviceId; + } + return navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { + //start a new source only if the previous one is closed + if (!this._stream) { + this._stream = stream; + //Wrap a MediaStreamSourceNode around the live input stream. + this._mediaStream = this.context.createMediaStreamSource(stream); + //Connect the MediaStreamSourceNode to a gate gain node + this._mediaStream.connect(this.output); + } + return this; + }.bind(this)); + }.bind(this)); + }; + /** + * Close the media stream + * @return {Tone.UserMedia} this + */ + Tone.UserMedia.prototype.close = function () { + if (this._stream) { + this._stream.getAudioTracks().forEach(function (track) { + track.stop(); + }); + this._stream = null; + //remove the old media stream + this._mediaStream.disconnect(); + this._mediaStream = null; + } + this._device = null; + return this; + }; + /** + * Returns a promise which resolves with the list of audio input devices available. + * @return {Promise} The promise that is resolved with the devices + * @static + * @example + * Tone.UserMedia.enumerateDevices().then(function(devices){ + * console.log(devices) + * }) + */ + Tone.UserMedia.enumerateDevices = function () { + return navigator.mediaDevices.enumerateDevices().then(function (devices) { + return devices.filter(function (device) { + return device.kind === 'audioinput'; + }); + }); + }; + /** + * Returns the playback state of the source, "started" when the microphone is open + * and "stopped" when the mic is closed. + * @type {Tone.State} + * @readOnly + * @memberOf Tone.UserMedia# + * @name state + */ + Object.defineProperty(Tone.UserMedia.prototype, 'state', { + get: function () { + return this._stream && this._stream.active ? Tone.State.Started : Tone.State.Stopped; + } + }); + /** + * Returns an identifier for the represented device that is + * persisted across sessions. It is un-guessable by other applications and + * unique to the origin of the calling application. It is reset when the + * user clears cookies (for Private Browsing, a different identifier is + * used that is not persisted across sessions). Returns undefined when the + * device is not open. + * @type {String} + * @readOnly + * @memberOf Tone.UserMedia# + * @name deviceId + */ + Object.defineProperty(Tone.UserMedia.prototype, 'deviceId', { + get: function () { + if (this._device) { + return this._device.deviceId; + } + } + }); + /** + * Returns a group identifier. Two devices have the + * same group identifier if they belong to the same physical device. + * Returns undefined when the device is not open. + * @type {String} + * @readOnly + * @memberOf Tone.UserMedia# + * @name groupId + */ + Object.defineProperty(Tone.UserMedia.prototype, 'groupId', { + get: function () { + if (this._device) { + return this._device.groupId; + } + } + }); + /** + * Returns a label describing this device (for example "Built-in Microphone"). + * Returns undefined when the device is not open or label is not available + * because of permissions. + * @type {String} + * @readOnly + * @memberOf Tone.UserMedia# + * @name groupId + */ + Object.defineProperty(Tone.UserMedia.prototype, 'label', { + get: function () { + if (this._device) { + return this._device.label; + } + } + }); + /** + * Mute the output. + * @memberOf Tone.UserMedia# + * @type {boolean} + * @name mute + * @example + * //mute the output + * userMedia.mute = true; + */ + Object.defineProperty(Tone.UserMedia.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + /** + * Clean up. + * @return {Tone.UserMedia} this + */ + Tone.UserMedia.prototype.dispose = function () { + Tone.AudioNode.prototype.dispose.call(this); + this.close(); + this._writable('volume'); + this._volume.dispose(); + this._volume = null; + this.volume = null; + return this; + }; + /** + * If getUserMedia is supported by the browser. + * @type {Boolean} + * @memberOf Tone.UserMedia# + * @name supported + * @static + * @readOnly + */ + Object.defineProperty(Tone.UserMedia, 'supported', { + get: function () { + return Tone.isDefined(navigator.mediaDevices) && Tone.isFunction(navigator.mediaDevices.getUserMedia); + } + }); + return Tone.UserMedia; + }); + Module(function (Tone) { + /** + * @class Tone.Midi is a primitive type for encoding Time values. + * Tone.Midi can be constructed with or without the `new` keyword. Tone.Midi can be passed + * into the parameter of any method which takes time as an argument. + * @constructor + * @extends {Tone.Frequency} + * @param {String|Number} val The time value. + * @param {String=} units The units of the value. + * @example + * var t = Tone.Midi("4n");//a quarter note + */ + Tone.Midi = function (val, units) { + if (this instanceof Tone.Midi) { + Tone.Frequency.call(this, val, units); + } else { + return new Tone.Midi(val, units); + } + }; + Tone.extend(Tone.Midi, Tone.Frequency); + /** + * The default units if none are given. + * @type {String} + * @private + */ + Tone.Midi.prototype._defaultUnits = 'midi'; + /** + * Returns the value of a frequency in the current units + * @param {Frequency} freq + * @return {Number} + * @private + */ + Tone.Midi.prototype._frequencyToUnits = function (freq) { + return Tone.Frequency.ftom(Tone.Frequency.prototype._frequencyToUnits.call(this, freq)); + }; + /** + * Returns the value of a tick in the current time units + * @param {Ticks} ticks + * @return {Number} + * @private + */ + Tone.Midi.prototype._ticksToUnits = function (ticks) { + return Tone.Frequency.ftom(Tone.Frequency.prototype._ticksToUnits.call(this, ticks)); + }; + /** + * Return the value of the beats in the current units + * @param {Number} beats + * @return {Number} + * @private + */ + Tone.Midi.prototype._beatsToUnits = function (beats) { + return Tone.Frequency.ftom(Tone.Frequency.prototype._beatsToUnits.call(this, beats)); + }; + /** + * Returns the value of a second in the current units + * @param {Seconds} seconds + * @return {Number} + * @private + */ + Tone.Midi.prototype._secondsToUnits = function (seconds) { + return Tone.Frequency.ftom(Tone.Frequency.prototype._secondsToUnits.call(this, seconds)); + }; + /** + * Return the value of the frequency as a MIDI note + * @return {MIDI} + * @example + * Tone.Midi(60).toMidi(); //60 + */ + Tone.Midi.prototype.toMidi = function () { + return this.valueOf(); + }; + /** + * Return the value of the frequency as a MIDI note + * @return {MIDI} + * @example + * Tone.Midi(60).toMidi(); //60 + */ + Tone.Midi.prototype.toFrequency = function () { + return Tone.Frequency.mtof(this.toMidi()); + }; + /** + * Transposes the frequency by the given number of semitones. + * @param {Interval} interval + * @return {Tone.Frequency} A new transposed frequency + * @example + * Tone.Frequency("A4").transpose(3); //"C5" + */ + Tone.Midi.prototype.transpose = function (interval) { + return new this.constructor(this.toMidi() + interval); + }; + return Tone.Midi; + }); + + return Tone; +})); + +/***/ }), +/* 25 */ +/***/ (function(module, exports) { + +module.exports = true; + +/***/ }), +/* 26 */ +/***/ (function(module, exports) { + +exports.f = {}.propertyIsEnumerable; + +/***/ }), +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { + +var def = __webpack_require__(5).f + , has = __webpack_require__(8) + , TAG = __webpack_require__(1)('toStringTag'); + +module.exports = function(it, tag, stat){ + if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag}); +}; + +/***/ }), +/* 28 */ +/***/ (function(module, exports, __webpack_require__) { + +// 7.1.13 ToObject(argument) +var defined = __webpack_require__(35); +module.exports = function(it){ + return Object(defined(it)); +}; + +/***/ }), +/* 29 */ +/***/ (function(module, exports) { + +var id = 0 + , px = Math.random(); +module.exports = function(key){ + return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); +}; + +/***/ }), +/* 30 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(129); +var global = __webpack_require__(2) + , hide = __webpack_require__(9) + , Iterators = __webpack_require__(14) + , TO_STRING_TAG = __webpack_require__(1)('toStringTag'); + +for(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){ + var NAME = collections[i] + , Collection = global[NAME] + , proto = Collection && Collection.prototype; + if(proto && !proto[TO_STRING_TAG])hide(proto, TO_STRING_TAG, NAME); + Iterators[NAME] = Iterators.Array; +} + +/***/ }), +/* 31 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.browser = exports.isDesktop = exports.isMobile = exports.isAndroid = exports.isIpad = exports.isIphone = undefined; + +var _log = __webpack_require__(86); + +var _log2 = _interopRequireDefault(_log); + +var _assign = __webpack_require__(57); + +var _assign2 = _interopRequireDefault(_assign); + +exports.choice = choice; +exports.mod = mod; +exports.norm = norm; +exports.requestAudioContext = requestAudioContext; +exports.dataURItoBlob = dataURItoBlob; +exports.ftom = ftom; +exports.mtof = mtof; +exports.tap = tap; +exports.get_diff_bounds = get_diff_bounds; +exports.get_bounds = get_bounds; +exports.transpose = transpose; + +var _tone = __webpack_require__(24); + +var _tone2 = _interopRequireDefault(_tone); + +var _startAudioContext = __webpack_require__(82); + +var _startAudioContext2 = _interopRequireDefault(_startAudioContext); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var isIphone = exports.isIphone = navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i); +var isIpad = exports.isIpad = navigator.userAgent.match(/iPad/i); +var isAndroid = exports.isAndroid = navigator.userAgent.match(/Android/i); +var isMobile = exports.isMobile = isIphone || isIpad || isAndroid; +var isDesktop = exports.isDesktop = !isMobile; + +document.body.classList.add(isMobile ? 'mobile' : 'desktop'); + +var browser = exports.browser = { isIphone: isIphone, isIpad: isIpad, isMobile: isMobile, isDesktop: isDesktop }; + +function choice(a) { + return a[Math.floor(Math.random() * a.length)]; +} +function mod(n, m) { + return n - m * Math.floor(n / m); +} +function norm(n, min, max) { + return (n - min) / (max - min); +} + +function requestAudioContext(fn) { + if (isMobile) { + var container = document.createElement('div'); + var button = document.createElement('div'); + button.innerHTML = 'Tap to start - please unmute your phone'; + (0, _assign2.default)(container.style, { + position: 'absolute', + width: '100%', + height: '100%', + zIndex: '10000', + top: '0px', + left: '0px', + backgroundColor: 'rgba(0, 0, 0, 0.8)' + }); + (0, _assign2.default)(button.style, { + position: 'absolute', + left: '50%', + top: '50%', + padding: '20px', + backgroundColor: '#7F33ED', + color: 'white', + fontFamily: 'monospace', + borderRadius: '3px', + transform: 'translate3D(-50%,-50%,0)', + textAlign: 'center', + lineHeight: '1.5' + }); + container.appendChild(button); + document.body.appendChild(container); + _startAudioContext2.default.setContext(_tone2.default.context); + _startAudioContext2.default.on(button); + _startAudioContext2.default.onStarted(function (_) { + container.remove(); + fn(); + }); + } else { + fn(); + } +} + +function dataURItoBlob(dataURI) { + // convert base64 to raw binary data held in a string + // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this + var byteString = atob(dataURI.split(',')[1]); + + // separate out the mime component + var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; + + // write the bytes of the string to an ArrayBuffer + var ab = new ArrayBuffer(byteString.length); + + // create a view into the buffer + var ia = new Uint8Array(ab); + + // set the bytes of the buffer to the correct values + for (var i = 0; i < byteString.length; i++) { + ia[i] = byteString.charCodeAt(i); + } + + // write the ArrayBuffer to a blob, and you're done + var blob = new Blob([ab], { type: mimeString }); + return blob; +} +function ftom(f) { + // return (Math.log(f) - Math.log(261.626)) / Math.log(2) + 4.0 + return 69 + 12 * (0, _log2.default)(f / 440); +} +function mtof(m) { + return 440 * Math.pow(2, (m - 69) / 12); +} +function tap(fn) { + return function (e) { + if (browser.isMobile) fn();else if (e.press) fn(); + }; +} + +/* get minimum and maximum variance from row-to-row */ + +function get_diff_bounds(rows) { + var diffs = rows.map(function (row) { + var row_min = Math.min.apply(Math, row); + var row_max = Math.max.apply(Math, row); + return row_max - row_min; + }); + var min = Math.min.apply(Math, diffs); + var max = Math.max.apply(Math, diffs); + return { min: min, max: max }; +} + +/* get minimum and maximum values from a dataset */ + +function get_bounds(dataset) { + var rows = dataset.lines; + // rows.forEach(row => row.shift()) + rows = rows.map(function (a) { + return a.map(function (n) { + return parseFloat(n); + }); + }); + var max = rows.reduce(function (a, b) { + return b.reduce(function (z, bb) { + return Math.max(z, bb); + }, a); + }, -Infinity); + var min = rows.reduce(function (a, b) { + return b.reduce(function (z, bb) { + return Math.min(z, bb); + }, a); + }, Infinity); + return { rows: rows, max: max, min: min }; +} + +/* transpose a 2D array */ + +function transpose(a) { + var i_len = a[0].length; + var j_len = a.length; + var T = new Array(i_len); + for (var i = 0; i < i_len; i++) { + T[i] = new Array(j_len); + for (var j = 0; j < j_len; j++) { + T[i][j] = a[j][i]; + } + } + return T; +} + +/***/ }), +/* 32 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(global) { + +var buffer = __webpack_require__(3); +var Buffer = buffer.Buffer; +var SlowBuffer = buffer.SlowBuffer; +var MAX_LEN = buffer.kMaxLength || 2147483647; +exports.alloc = function alloc(size, fill, encoding) { + if (typeof Buffer.alloc === 'function') { + return Buffer.alloc(size, fill, encoding); + } + if (typeof encoding === 'number') { + throw new TypeError('encoding must not be number'); + } + if (typeof size !== 'number') { + throw new TypeError('size must be a number'); + } + if (size > MAX_LEN) { + throw new RangeError('size is too large'); + } + var enc = encoding; + var _fill = fill; + if (_fill === undefined) { + enc = undefined; + _fill = 0; + } + var buf = new Buffer(size); + if (typeof _fill === 'string') { + var fillBuf = new Buffer(_fill, enc); + var flen = fillBuf.length; + var i = -1; + while (++i < size) { + buf[i] = fillBuf[i % flen]; + } + } else { + buf.fill(_fill); + } + return buf; +} +exports.allocUnsafe = function allocUnsafe(size) { + if (typeof Buffer.allocUnsafe === 'function') { + return Buffer.allocUnsafe(size); + } + if (typeof size !== 'number') { + throw new TypeError('size must be a number'); + } + if (size > MAX_LEN) { + throw new RangeError('size is too large'); + } + return new Buffer(size); +} +exports.from = function from(value, encodingOrOffset, length) { + if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) { + return Buffer.from(value, encodingOrOffset, length); + } + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number'); + } + if (typeof value === 'string') { + return new Buffer(value, encodingOrOffset); + } + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + var offset = encodingOrOffset; + if (arguments.length === 1) { + return new Buffer(value); + } + if (typeof offset === 'undefined') { + offset = 0; + } + var len = length; + if (typeof len === 'undefined') { + len = value.byteLength - offset; + } + if (offset >= value.byteLength) { + throw new RangeError('\'offset\' is out of bounds'); + } + if (len > value.byteLength - offset) { + throw new RangeError('\'length\' is out of bounds'); + } + return new Buffer(value.slice(offset, offset + len)); + } + if (Buffer.isBuffer(value)) { + var out = new Buffer(value.length); + value.copy(out, 0, 0, value.length); + return out; + } + if (value) { + if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) { + return new Buffer(value); + } + if (value.type === 'Buffer' && Array.isArray(value.data)) { + return new Buffer(value.data); + } + } + + throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.'); +} +exports.allocUnsafeSlow = function allocUnsafeSlow(size) { + if (typeof Buffer.allocUnsafeSlow === 'function') { + return Buffer.allocUnsafeSlow(size); + } + if (typeof size !== 'number') { + throw new TypeError('size must be a number'); + } + if (size >= MAX_LEN) { + throw new RangeError('size is too large'); + } + return new SlowBuffer(size); +} + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(23))) + +/***/ }), +/* 33 */ +/***/ (function(module, exports) { + +module.exports = function(it){ + if(typeof it != 'function')throw TypeError(it + ' is not a function!'); + return it; +}; + +/***/ }), +/* 34 */ +/***/ (function(module, exports, __webpack_require__) { + +// getting tag from 19.1.3.6 Object.prototype.toString() +var cof = __webpack_require__(17) + , TAG = __webpack_require__(1)('toStringTag') + // ES3 wrong here + , ARG = cof(function(){ return arguments; }()) == 'Arguments'; + +// fallback for IE11 Script Access Denied error +var tryGet = function(it, key){ + try { + return it[key]; + } catch(e){ /* empty */ } +}; + +module.exports = function(it){ + var O, T, B; + return it === undefined ? 'Undefined' : it === null ? 'Null' + // @@toStringTag case + : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T + // builtinTag case + : ARG ? cof(O) + // ES3 arguments fallback + : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; +}; + +/***/ }), +/* 35 */ +/***/ (function(module, exports) { + +// 7.2.1 RequireObjectCoercible(argument) +module.exports = function(it){ + if(it == undefined)throw TypeError("Can't call method on " + it); + return it; +}; + +/***/ }), +/* 36 */ +/***/ (function(module, exports, __webpack_require__) { + +var isObject = __webpack_require__(19) + , document = __webpack_require__(2).document + // in old IE typeof document.createElement is 'object' + , is = isObject(document) && isObject(document.createElement); +module.exports = function(it){ + return is ? document.createElement(it) : {}; +}; + +/***/ }), +/* 37 */ +/***/ (function(module, exports) { + +// IE 8- don't enum bug keys +module.exports = ( + 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' +).split(','); + +/***/ }), +/* 38 */ +/***/ (function(module, exports) { + +exports.f = Object.getOwnPropertySymbols; + +/***/ }), +/* 39 */ +/***/ (function(module, exports, __webpack_require__) { + +var shared = __webpack_require__(40)('keys') + , uid = __webpack_require__(29); +module.exports = function(key){ + return shared[key] || (shared[key] = uid(key)); +}; + +/***/ }), +/* 40 */ +/***/ (function(module, exports, __webpack_require__) { + +var global = __webpack_require__(2) + , SHARED = '__core-js_shared__' + , store = global[SHARED] || (global[SHARED] = {}); +module.exports = function(key){ + return store[key] || (store[key] = {}); +}; + +/***/ }), +/* 41 */ +/***/ (function(module, exports) { + +// 7.1.4 ToInteger +var ceil = Math.ceil + , floor = Math.floor; +module.exports = function(it){ + return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); +}; + +/***/ }), +/* 42 */ +/***/ (function(module, exports, __webpack_require__) { + +// 7.1.15 ToLength +var toInteger = __webpack_require__(41) + , min = Math.min; +module.exports = function(it){ + return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 +}; + +/***/ }), +/* 43 */ +/***/ (function(module, exports, __webpack_require__) { + +// 7.1.1 ToPrimitive(input [, PreferredType]) +var isObject = __webpack_require__(19); +// instead of the ES6 spec version, we didn't implement @@toPrimitive case +// and the second argument - flag - preferred type is a string +module.exports = function(it, S){ + if(!isObject(it))return it; + var fn, val; + if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; + if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val; + if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; + throw TypeError("Can't convert object to primitive value"); +}; + +/***/ }), +/* 44 */ +/***/ (function(module, exports, __webpack_require__) { + +var global = __webpack_require__(2) + , core = __webpack_require__(0) + , LIBRARY = __webpack_require__(25) + , wksExt = __webpack_require__(45) + , defineProperty = __webpack_require__(5).f; +module.exports = function(name){ + var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {}); + if(name.charAt(0) != '_' && !(name in $Symbol))defineProperty($Symbol, name, {value: wksExt.f(name)}); +}; + +/***/ }), +/* 45 */ +/***/ (function(module, exports, __webpack_require__) { + +exports.f = __webpack_require__(1); + +/***/ }), +/* 46 */ +/***/ (function(module, exports, __webpack_require__) { + +var classof = __webpack_require__(34) + , ITERATOR = __webpack_require__(1)('iterator') + , Iterators = __webpack_require__(14); +module.exports = __webpack_require__(0).getIteratorMethod = function(it){ + if(it != undefined)return it[ITERATOR] + || it['@@iterator'] + || Iterators[classof(it)]; +}; + +/***/ }), +/* 47 */ +/***/ (function(module, exports) { + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } else { + // At least give some kind of context to the user + var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); + err.context = er; + throw err; + } + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + } else if (isObject(handler)) { + args = Array.prototype.slice.call(arguments, 1); + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.prototype.listenerCount = function(type) { + if (this._events) { + var evlistener = this._events[type]; + + if (isFunction(evlistener)) + return 1; + else if (evlistener) + return evlistener.length; + } + return 0; +}; + +EventEmitter.listenerCount = function(emitter, type) { + return emitter.listenerCount(type); +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + + +/***/ }), +/* 48 */ +/***/ (function(module, exports, __webpack_require__) { + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var Buffer = __webpack_require__(3).Buffer; + +var isBufferEncoding = Buffer.isEncoding + || function(encoding) { + switch (encoding && encoding.toLowerCase()) { + case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; + default: return false; + } + } + + +function assertEncoding(encoding) { + if (encoding && !isBufferEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} + +// StringDecoder provides an interface for efficiently splitting a series of +// buffers into a series of JS strings without breaking apart multi-byte +// characters. CESU-8 is handled as part of the UTF-8 encoding. +// +// @TODO Handling all encodings inside a single object makes it very difficult +// to reason about this code, so it should be split up in the future. +// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code +// points as used by CESU-8. +var StringDecoder = exports.StringDecoder = function(encoding) { + this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); + assertEncoding(encoding); + switch (this.encoding) { + case 'utf8': + // CESU-8 represents each of Surrogate Pair by 3-bytes + this.surrogateSize = 3; + break; + case 'ucs2': + case 'utf16le': + // UTF-16 represents each of Surrogate Pair by 2-bytes + this.surrogateSize = 2; + this.detectIncompleteChar = utf16DetectIncompleteChar; + break; + case 'base64': + // Base-64 stores 3 bytes in 4 chars, and pads the remainder. + this.surrogateSize = 3; + this.detectIncompleteChar = base64DetectIncompleteChar; + break; + default: + this.write = passThroughWrite; + return; + } + + // Enough space to store all bytes of a single character. UTF-8 needs 4 + // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). + this.charBuffer = new Buffer(6); + // Number of bytes received for the current incomplete multi-byte character. + this.charReceived = 0; + // Number of bytes expected for the current incomplete multi-byte character. + this.charLength = 0; +}; + + +// write decodes the given buffer and returns it as JS string that is +// guaranteed to not contain any partial multi-byte characters. Any partial +// character found at the end of the buffer is buffered up, and will be +// returned when calling write again with the remaining bytes. +// +// Note: Converting a Buffer containing an orphan surrogate to a String +// currently works, but converting a String to a Buffer (via `new Buffer`, or +// Buffer#write) will replace incomplete surrogates with the unicode +// replacement character. See https://codereview.chromium.org/121173009/ . +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + // if our last write ended with an incomplete multibyte character + while (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var available = (buffer.length >= this.charLength - this.charReceived) ? + this.charLength - this.charReceived : + buffer.length; + + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, 0, available); + this.charReceived += available; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } + + // remove bytes belonging to the current character from the buffer + buffer = buffer.slice(available, buffer.length); + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + var charCode = charStr.charCodeAt(charStr.length - 1); + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + this.charLength += this.surrogateSize; + charStr = ''; + continue; + } + this.charReceived = this.charLength = 0; + + // if there are no more bytes in this buffer, just emit our char + if (buffer.length === 0) { + return charStr; + } + break; + } + + // determine and set charLength / charReceived + this.detectIncompleteChar(buffer); + + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); + end -= this.charReceived; + } + + charStr += buffer.toString(this.encoding, 0, end); + + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + var size = this.surrogateSize; + this.charLength += size; + this.charReceived += size; + this.charBuffer.copy(this.charBuffer, size, 0, size); + buffer.copy(this.charBuffer, 0, 0, size); + return charStr.substring(0, end); + } + + // or just emit the charStr + return charStr; +}; + +// detectIncompleteChar determines if there is an incomplete UTF-8 character at +// the end of the given buffer. If so, it sets this.charLength to the byte +// length that character, and sets this.charReceived to the number of bytes +// that are available for this character. +StringDecoder.prototype.detectIncompleteChar = function(buffer) { + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) ? 3 : buffer.length; + + // Figure out if one of the last i bytes of our buffer announces an + // incomplete char. + for (; i > 0; i--) { + var c = buffer[buffer.length - i]; + + // See http://en.wikipedia.org/wiki/UTF-8#Description + + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; + } + + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; + } + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; + } + } + this.charReceived = i; +}; + +StringDecoder.prototype.end = function(buffer) { + var res = ''; + if (buffer && buffer.length) + res = this.write(buffer); + + if (this.charReceived) { + var cr = this.charReceived; + var buf = this.charBuffer; + var enc = this.encoding; + res += buf.slice(0, cr).toString(enc); + } + + return res; +}; + +function passThroughWrite(buffer) { + return buffer.toString(this.encoding); +} + +function utf16DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 2; + this.charLength = this.charReceived ? 2 : 0; +} + +function base64DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 3; + this.charLength = this.charReceived ? 3 : 0; +} + + +/***/ }), +/* 49 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(process) { + +if (!process.version || + process.version.indexOf('v0.') === 0 || + process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { + module.exports = nextTick; +} else { + module.exports = process.nextTick; +} + +function nextTick(fn, arg1, arg2, arg3) { + if (typeof fn !== 'function') { + throw new TypeError('"callback" argument must be a function'); + } + var len = arguments.length; + var args, i; + switch (len) { + case 0: + case 1: + return process.nextTick(fn); + case 2: + return process.nextTick(function afterTickOne() { + fn.call(null, arg1); + }); + case 3: + return process.nextTick(function afterTickTwo() { + fn.call(null, arg1, arg2); + }); + case 4: + return process.nextTick(function afterTickThree() { + fn.call(null, arg1, arg2, arg3); + }); + default: + args = new Array(len - 1); + i = 0; + while (i < args.length) { + args[i++] = arguments[i]; + } + return process.nextTick(function afterTick() { + fn.apply(null, args); + }); + } +} + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(11))) + +/***/ }), +/* 50 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(process, setImmediate) {// A bit simpler than readable streams. +// Implement an async ._write(chunk, encoding, cb), and it'll handle all +// the drain event emission and buffering. + + + +module.exports = Writable; + +/*<replacement>*/ +var processNextTick = __webpack_require__(49); +/*</replacement>*/ + +/*<replacement>*/ +var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; +/*</replacement>*/ + +/*<replacement>*/ +var Duplex; +/*</replacement>*/ + +Writable.WritableState = WritableState; + +/*<replacement>*/ +var util = __webpack_require__(22); +util.inherits = __webpack_require__(16); +/*</replacement>*/ + +/*<replacement>*/ +var internalUtil = { + deprecate: __webpack_require__(151) +}; +/*</replacement>*/ + +/*<replacement>*/ +var Stream = __webpack_require__(74); +/*</replacement>*/ + +var Buffer = __webpack_require__(3).Buffer; +/*<replacement>*/ +var bufferShim = __webpack_require__(32); +/*</replacement>*/ + +util.inherits(Writable, Stream); + +function nop() {} + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; + this.next = null; +} + +function WritableState(options, stream) { + Duplex = Duplex || __webpack_require__(12); + + options = options || {}; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + // drain event flag. + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function (er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.bufferedRequest = null; + this.lastBufferedRequest = null; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; + + // count buffered requests + this.bufferedRequestCount = 0; + + // allocate the first CorkedRequest, there is always + // one allocated and free to use, and we maintain at most two + this.corkedRequestsFree = new CorkedRequest(this); +} + +WritableState.prototype.getBuffer = function getBuffer() { + var current = this.bufferedRequest; + var out = []; + while (current) { + out.push(current); + current = current.next; + } + return out; +}; + +(function () { + try { + Object.defineProperty(WritableState.prototype, 'buffer', { + get: internalUtil.deprecate(function () { + return this.getBuffer(); + }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.') + }); + } catch (_) {} +})(); + +// Test _writableState for inheritance to account for Duplex streams, +// whose prototype chain only points to Readable. +var realHasInstance; +if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { + realHasInstance = Function.prototype[Symbol.hasInstance]; + Object.defineProperty(Writable, Symbol.hasInstance, { + value: function (object) { + if (realHasInstance.call(this, object)) return true; + + return object && object._writableState instanceof WritableState; + } + }); +} else { + realHasInstance = function (object) { + return object instanceof this; + }; +} + +function Writable(options) { + Duplex = Duplex || __webpack_require__(12); + + // Writable ctor is applied to Duplexes, too. + // `realHasInstance` is necessary because using plain `instanceof` + // would return false, as no `_writableState` property is attached. + + // Trying to use the custom `instanceof` for Writable here will also break the + // Node.js LazyTransform implementation, which has a non-trivial getter for + // `_writableState` that would lead to infinite recursion. + if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) { + return new Writable(options); + } + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + if (options) { + if (typeof options.write === 'function') this._write = options.write; + + if (typeof options.writev === 'function') this._writev = options.writev; + } + + Stream.call(this); +} + +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function () { + this.emit('error', new Error('Cannot pipe, not readable')); +}; + +function writeAfterEnd(stream, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + processNextTick(cb, er); +} + +// Checks that a user-supplied chunk is valid, especially for the particular +// mode the stream is in. Currently this means that `null` is never accepted +// and undefined/non-string values are only allowed in object mode. +function validChunk(stream, state, chunk, cb) { + var valid = true; + var er = false; + + if (chunk === null) { + er = new TypeError('May not write null values to stream'); + } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + if (er) { + stream.emit('error', er); + processNextTick(cb, er); + valid = false; + } + return valid; +} + +Writable.prototype.write = function (chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + var isBuf = Buffer.isBuffer(chunk); + + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; + + if (typeof cb !== 'function') cb = nop; + + if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); + } + + return ret; +}; + +Writable.prototype.cork = function () { + var state = this._writableState; + + state.corked++; +}; + +Writable.prototype.uncork = function () { + var state = this._writableState; + + if (state.corked) { + state.corked--; + + if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); + } +}; + +Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { + // node::ParseEncoding() requires lower case. + if (typeof encoding === 'string') encoding = encoding.toLowerCase(); + if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); + this._writableState.defaultEncoding = encoding; + return this; +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { + chunk = bufferShim.from(chunk, encoding); + } + return chunk; +} + +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { + if (!isBuf) { + chunk = decodeChunk(state, chunk, encoding); + if (Buffer.isBuffer(chunk)) encoding = 'buffer'; + } + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) state.needDrain = true; + + if (state.writing || state.corked) { + var last = state.lastBufferedRequest; + state.lastBufferedRequest = new WriteReq(chunk, encoding, cb); + if (last) { + last.next = state.lastBufferedRequest; + } else { + state.bufferedRequest = state.lastBufferedRequest; + } + state.bufferedRequestCount += 1; + } else { + doWrite(stream, state, false, len, chunk, encoding, cb); + } + + return ret; +} + +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + --state.pendingcb; + if (sync) processNextTick(cb, er);else cb(er); + + stream._writableState.errorEmitted = true; + stream.emit('error', er); +} + +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; +} + +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + + onwriteStateUpdate(state); + + if (er) onwriteError(stream, state, sync, er, cb);else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(state); + + if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { + clearBuffer(stream, state); + } + + if (sync) { + /*<replacement>*/ + asyncWrite(afterWrite, stream, state, finished, cb); + /*</replacement>*/ + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); +} + +// Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } +} + +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + var entry = state.bufferedRequest; + + if (stream._writev && entry && entry.next) { + // Fast case, write everything using _writev() + var l = state.bufferedRequestCount; + var buffer = new Array(l); + var holder = state.corkedRequestsFree; + holder.entry = entry; + + var count = 0; + while (entry) { + buffer[count] = entry; + entry = entry.next; + count += 1; + } + + doWrite(stream, state, true, state.length, buffer, '', holder.finish); + + // doWrite is almost always async, defer these to save a bit of time + // as the hot path ends with doWrite + state.pendingcb++; + state.lastBufferedRequest = null; + if (holder.next) { + state.corkedRequestsFree = holder.next; + holder.next = null; + } else { + state.corkedRequestsFree = new CorkedRequest(state); + } + } else { + // Slow case, write chunks one-by-one + while (entry) { + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, false, len, chunk, encoding, cb); + entry = entry.next; + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + break; + } + } + + if (entry === null) state.lastBufferedRequest = null; + } + + state.bufferedRequestCount = 0; + state.bufferedRequest = entry; + state.bufferProcessing = false; +} + +Writable.prototype._write = function (chunk, encoding, cb) { + cb(new Error('_write() is not implemented')); +}; + +Writable.prototype._writev = null; + +Writable.prototype.end = function (chunk, encoding, cb) { + var state = this._writableState; + + if (typeof chunk === 'function') { + cb = chunk; + chunk = null; + encoding = null; + } else if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); + + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) endWritable(this, state, cb); +}; + +function needFinish(state) { + return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; +} + +function prefinish(stream, state) { + if (!state.prefinished) { + state.prefinished = true; + stream.emit('prefinish'); + } +} + +function finishMaybe(stream, state) { + var need = needFinish(state); + if (need) { + if (state.pendingcb === 0) { + prefinish(stream, state); + state.finished = true; + stream.emit('finish'); + } else { + prefinish(stream, state); + } + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) processNextTick(cb);else stream.once('finish', cb); + } + state.ended = true; + stream.writable = false; +} + +// It seems a linked list but it is not +// there will be only 2 of these for each stream +function CorkedRequest(state) { + var _this = this; + + this.next = null; + this.entry = null; + this.finish = function (err) { + var entry = _this.entry; + _this.entry = null; + while (entry) { + var cb = entry.callback; + state.pendingcb--; + cb(err); + entry = entry.next; + } + if (state.corkedRequestsFree) { + state.corkedRequestsFree.next = _this; + } else { + state.corkedRequestsFree = _this; + } + }; +} +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(11), __webpack_require__(75).setImmediate)) + +/***/ }), +/* 51 */ +/***/ (function(module, exports, __webpack_require__) { + +exports = module.exports = __webpack_require__(72); +exports.Stream = exports; +exports.Readable = exports; +exports.Writable = __webpack_require__(50); +exports.Duplex = __webpack_require__(12); +exports.Transform = __webpack_require__(73); +exports.PassThrough = __webpack_require__(143); + + +/***/ }), +/* 52 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _tone = __webpack_require__(24); + +var _tone2 = _interopRequireDefault(_tone); + +var _util = __webpack_require__(31); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var player_count = 2; +var sample_index = 0; + +var compressor = new _tone2.default.Compressor(-30, 3).toMaster(); + +var samples = [{ root: 226, fn: 'samples/380737__cabled-mess__sansula-01-a-raw.mp3' }, { root: 267, fn: 'samples/380736__cabled-mess__sansula-02-c-raw.mp3' }, { root: 340, fn: 'samples/380735__cabled-mess__sansula-03-e-raw.mp3' }, { root: 452, fn: 'samples/380733__cabled-mess__sansula-06-a-02-raw.mp3' }]; + +samples.forEach(function (sample) { + sample.players = []; + sample.index = -1; + for (var i = 0; i < player_count; i++) { + var fn = sample.fn; + if (window.location.href.match(/asdf.us/)) { + fn = '//asdf.us/kalimba/' + fn; + } + var player = new _tone2.default.Player({ + url: fn, + retrigger: true, + playbackRate: 1 + }); + player.connect(compressor); + sample.players.push(player); + } +}); + +function play(freq) { + var volume = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.0; + + var best = { sample: samples[sample_index] }; + sample_index = (sample_index + 1) % samples.length; + best.sample.index = (best.sample.index + 1) % player_count; + + var player = best.sample.players[best.sample.index]; + player.playbackRate = freq / best.sample.root; + // console.log(player) + player.volume.value = volume; + setTimeout(function () { + player.start(); + }, 0); +} + +exports.default = { play: play }; + +/***/ }), +/* 53 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _intonation = __webpack_require__(81); + +var _intonation2 = _interopRequireDefault(_intonation); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var meantone = '! meanquar.scl\n!\n1/4-comma meantone scale. Pietro Aaron\'s temperament (1523)\n 12\n!\n 76.04900\n 193.15686\n 310.26471\n 5/4\n 503.42157\n 579.47057\n 696.57843\n 25/16\n 889.73529\n 1006.84314\n 1082.89214\n 2/1\n'; + +var shares = '! shares.scl\n!\nA scale based on shares of wealth\n!\n1.\n5.\n15.\n32.\n52.\n78.\n116.\n182.\n521.\n1000.\n'; + +var shares_sum = '! shares_sum.scl\n!\nA scale based on summing shares of wealth\n!\n1\n6.0\n21.0\n53.0\n105.0\n183.0\n299.0\n481.0\n1002.0\n2/1\n'; + +var mavila = '! mavila12.scl\n!\nA 12-note mavila scale (for warping meantone-based music), 5-limit TOP\n 12\n!\n-30.99719\n 163.50770\n 358.01258\n 327.01540\n 521.52028\n 490.52310\n 685.02798\n 654.03080\n 848.53568\n 1043.04057\n 1012.04338\n 1206.54826\n'; + +var carlos_alpha = '! carlos_alpha.scl\n!\nWendy Carlos\' Alpha scale with perfect fifth divided in nine\n 18\n!\n 78.00000\n 156.00000\n 234.00000\n 312.00000\n 390.00000\n 468.00000\n 546.00000\n 624.00000\n 702.00000\n 780.00000\n 858.00000\n 936.00000\n 1014.00000\n 1092.00000\n 1170.00000\n 1248.00000\n 1326.00000\n 1404.00000\n'; + +var lamonte = '! young-lm_piano.scl\n!\nLaMonte Young\'s Well-Tempered Piano\n12\n!\n567/512\n9/8\n147/128\n21/16\n1323/1024\n189/128\n3/2\n49/32\n7/4\n441/256\n63/32\n2/1\n'; + +var colundi = '! colundi.scl\n!\nColundi scale\n10\n!\n9/8\n171/140\n137/112\n43/35\n3/2\n421/280\n213/140\n263/150\n66/35\n2/1\n'; + +var liu_major = '! liu_major.scl\n!\nLinus Liu\'s Major Scale, see his 1978 book, "Intonation Theory" \n 7\n!\n 10/9\n 100/81\n 4/3\n 3/2\n 5/3\n 50/27\n 2/1\n'; +var liu_pentatonic = '! liu_pent.scl\n!\nLinus Liu\'s "pentatonic scale" \n 7\n!\n 9/8\n 81/64\n 27/20\n 3/2\n 27/16\n 243/128\n 81/40\n'; + +var liu_minor = '! LIU_MINor.scl\n!\nLinus Liu\'s Harmonic Minor \n 7\n!\n 10/9\n 6/5\n 4/3\n 40/27\n 8/5\n 50/27\n 2/1\n'; + +var liu_melodic_minor = '! liu_mel.scl\n!\nLinus Liu\'s Melodic Minor, use 5 and 7 descending and 6 and 8 ascending \n 9\n!\n 10/9\n 6/5\n 4/3\n 3/2\n 81/50\n 5/3\n 9/5\n 50/27\n 2/1\n'; + +var scales = [{ + intervals: '1/1 9/8 5/4 4/3 3/2 5/3 15/8 2/1', + name: "harmonic scale" +}, { + root: 450, + intervals: '1/1 9/8 5/4 4/3 3/2 5/3 15/8 2/1', + name: "harmonic scale @ 450" +}, { + tet: 5 +}, { + tet: 12 +}, { + tet: 17 +}, { + intervals: '1/1 81/80 33/32 21/20 16/15 12/11 11/10 10/9 9/8 8/7 7/6 32/27 6/5 11/9 5/4 14/11 9/7 21/16 4/3 27/20 11/8 7/5 10/7 16/11 40/27 3/2 32/21 14/9 11/7 8/5 18/11 5/3 27/16 12/7 7/4 16/9 9/5 20/11 11/6 15/8 40/21 64/33 160/81 2/1', + name: "harry partch scale" +}, { + scl: lamonte +}, { + scl: meantone +}, { + scl: mavila +}, { + scl: carlos_alpha +}, { + scl: colundi +}, { + scl: shares +}, { + scl: shares_sum +}, { + scl: liu_major +}, { + scl: liu_minor +}, { + scl: liu_melodic_minor +}, { + scl: liu_pentatonic +}].map(function (opt) { + return new _intonation2.default(opt); +}); + +var scale = scales[0]; +var handleChange = function handleChange() {}; + +function build() { + scales.forEach(function (scale, i) { + scale.heading = document.createElement('div'); + scale.heading.innerHTML = scale.name; + scale.heading.classList.add('heading'); + scale.heading.addEventListener('click', function () { + pick(i); + }); + scale_list.appendChild(scale.heading); + }); + pick(0); +} +function build_options(el) { + scales.forEach(function (scale, i) { + var option = document.createElement('option'); + option.innerHTML = scale.name; + option.value = i; + el.appendChild(option); + }); + el.addEventListener('input', function (e) { + pick(e.target.value); + }); + pick(0); +} + +function pick(i) { + if (scale) { + scale.heading && scale.heading.classList.remove('selected'); + } + scale = scales[i]; + scale.heading && scale.heading.classList.add('selected'); + handleChange(scale); +} + +function current() { + return scale; +} + +function onChange(fn) { + handleChange = fn; +} + +function names() { + return scales.map(function (scale) { + return scale.name; + }); +} + +exports.default = { scales: scales, current: current, build: build, build_options: build_options, pick: pick, names: names, onChange: onChange }; + +/***/ }), +/* 54 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.nx = undefined; + +var _keys = __webpack_require__(87); + +var _keys2 = _interopRequireDefault(_keys); + +exports.update_value_on_change = update_value_on_change; +exports.update_radio_value_on_change = update_radio_value_on_change; +exports.build_options = build_options; + +var _nexusui = __webpack_require__(56); + +var _nexusui2 = _interopRequireDefault(_nexusui); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var nx = exports.nx = window.nx = {}; + +/* ui - update an int/float value */ + +function update_value_on_change(el, id, is_int, fn) { + var label = document.querySelector(id + ' + .val'); + var update = function update(v) { + label.innerHTML = is_int ? parseInt(v) : v.toFixed(2); + fn && fn(v); + }; + el.on('change', update); + update(el.value); + el.update = update; +} + +/* ui - update a radio button */ + +function update_radio_value_on_change(el, id, values, fn) { + var old_v = el.active; + var label = document.querySelector(id + ' + .val'); + var update = function update(v) { + if (v === -1) { + v = el.active = old_v; + } else { + old_v = v; + } + label.innerHTML = values[v][1]; + fn && fn(v); + }; + el.on('change', update); + update(el.active); + el.update = update; +} + +/* ui - bind/build a select dropdown */ + +function build_options(el, lists, fn) { + (0, _keys2.default)(lists).forEach(function (key) { + var list = lists[key]; + var option = document.createElement('option'); + option.innerHTML = list.name; + option.value = key; + el.appendChild(option); + }); + el.addEventListener('input', function (e) { + fn(e.target.value); + }); +} + +/***/ }), +/* 55 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; + +var _isIterable2 = __webpack_require__(85); + +var _isIterable3 = _interopRequireDefault(_isIterable2); + +var _getIterator2 = __webpack_require__(84); + +var _getIterator3 = _interopRequireDefault(_getIterator2); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = function () { + function sliceIterator(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = (0, _getIterator3.default)(arr), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"]) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + return function (arr, i) { + if (Array.isArray(arr)) { + return arr; + } else if ((0, _isIterable3.default)(Object(arr))) { + return sliceIterator(arr, i); + } else { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + }; +}(); + +/***/ }), +/* 56 */ +/***/ (function(module, exports, __webpack_require__) { + +(function webpackUniversalModuleDefinition(root, factory) { + if(true) + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["Nexus"] = factory(); + else + root["Nexus"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; + + var NexusUI = _interopRequire(__webpack_require__(1)); + + module.exports = NexusUI; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; }; + + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + exports.colors = colors; + exports.context = context; + exports.clock = clock; + Object.defineProperty(exports, "__esModule", { + value: true + }); + "use strict"; + + var Interfaces = _interopRequire(__webpack_require__(2)); + + var math = _interopRequire(__webpack_require__(5)); + + var Rack = _interopRequire(__webpack_require__(38)); + + var Tune = _interopRequire(__webpack_require__(40)); + + var Transform = _interopRequireWildcard(__webpack_require__(39)); + + var Counter = __webpack_require__(28); + var Radio = __webpack_require__(41); + var Drunk = __webpack_require__(27); + var Sequence = __webpack_require__(26); + var Matrix = __webpack_require__(25); + + var WAAClock = _interopRequire(__webpack_require__(42)); + + var Interval = _interopRequire(__webpack_require__(45)); + + /** + NexusUI => created as Nexus + */ + + var NexusUI = (function () { + function NexusUI(context) { + _classCallCheck(this, NexusUI); + + for (var key in Interfaces) { + this[key] = Interfaces[key]; + } + + for (var key in math) { + this[key] = math[key]; + } + + var Core = { + Rack: Rack + }; + + var Models = { + Counter: Counter, + Radio: Radio, + Drunk: Drunk, + Sequence: Sequence, + Matrix: Matrix + }; + + for (var key in Models) { + this[key] = Models[key]; + } + + for (var key in Core) { + this[key] = Core[key]; + } + + var DefaultContext = window.AudioContext || window.webkitAudioContext; + this._context = context || new DefaultContext(); + + this.tune = new Tune(); + this.note = this.tune.note.bind(this.tune); + + this.clock = new WAAClock(this._context); + this.clock.start(); + this.Interval = Interval; + + this.colors = { + accent: "#2bb", + fill: "#eee", + light: "#fff", + dark: "#333", + mediumLight: "#ccc", + mediumDark: "#666" + }; + + this.transform = Transform; + this.add = Transform.add; + + this.Add = {}; + for (var key in Interfaces) { + this.Add[key] = Transform.add.bind(this, key); + } + + /* create default component size */ + /* jshint ignore:start */ + var existingStylesheets = document.getElementsByTagName("style"); + var defaultSizeDeclaration = "[nexus-ui]{height:5000px;width:5000px}"; + var defaultStyleNode = document.createElement("style"); + defaultStyleNode.type = "text/css"; + defaultStyleNode.innerHTML = defaultSizeDeclaration; + if (existingStylesheets.length > 0) { + var parent = existingStylesheets[0].parentNode; + parent.insertBefore(defaultStyleNode, existingStylesheets[0]); + } else { + document.write("<style>" + defaultSizeDeclaration + "</style>"); + } + /* jshint ignore:end */ + } + + _createClass(NexusUI, { + context: { + get: function () { + return this._context; + }, + set: function (ctx) { + this.clock.stop(); + this._context = ctx; + this.clock = new WAAClock(this.context); + this.clock.start(); + } + } + }); + + return NexusUI; + })(); + + var Nexus = new NexusUI(); + + function colors() { + return Nexus.colors; + } + + function context() { + return Nexus.context; + } + + function clock() { + return Nexus.clock; + } + + exports["default"] = Nexus; + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + module.exports = { + Position: __webpack_require__(3), + Slider: __webpack_require__(14), + Toggle: __webpack_require__(15), + /* Range: require('./rangeslider'), + Waveform: require('./waveform'), */ + Button: __webpack_require__(16), + TextButton: __webpack_require__(18), + RadioButton: __webpack_require__(19), + Number: __webpack_require__(20), + Select: __webpack_require__(21), + Dial: __webpack_require__(22), + Piano: __webpack_require__(23), + Sequencer: __webpack_require__(24), + Pan2D: __webpack_require__(29), + Tilt: __webpack_require__(30), + Multislider: __webpack_require__(31), + Pan: __webpack_require__(33), + Envelope: __webpack_require__(34), + Spectrogram: __webpack_require__(35), + Meter: __webpack_require__(36), + Oscilloscope: __webpack_require__(37) + }; + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + + + "use strict"; + + var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var svg = __webpack_require__(4); + var Interface = __webpack_require__(6); + var Step = __webpack_require__(11); + + var Interaction = _interopRequireWildcard(__webpack_require__(12)); + + /** + * Position + * + * @description Two-dimensional touch slider. + * + * @demo <span nexus-ui="position"></span> + * + * @example + * var position = new Nexus.Position('#target') + * + * @example + * var position = new Nexus.Position('#target',{ + * 'size': [200,200], + * 'mode': 'absolute', // "absolute" or "relative" + * 'x': 0.5, // initial x value + * 'minX': 0, + * 'maxX': 1, + * 'stepX': 0, + * 'y': 0.5, // initial y value + * 'minY': 0, + * 'maxY': 1, + * 'stepY': 0 + * }) + * + * @output + * change + * Fires any time the interface's value changes. <br> + * The event data is an object with x and y properties containing the x and y values of the interface. + * + * @outputexample + * position.on('change',function(v) { + * console.log(v); + * }) + * + * + */ + + var Position = (function (_Interface) { + function Position() { + _classCallCheck(this, Position); + + var options = ["value"]; + + var defaults = { + size: [200, 200], + mode: "absolute", + minX: 0, + maxX: 1, + stepX: 0, + x: 0.5, + minY: 0, + maxY: 1, + stepY: 0, + y: 0.5 + }; + + _get(Object.getPrototypeOf(Position.prototype), "constructor", this).call(this, arguments, options, defaults); + + this._x = new Step(this.settings.minX, this.settings.maxX, this.settings.stepX, this.settings.x); + this._y = new Step(this.settings.minY, this.settings.maxY, this.settings.stepY, this.settings.y); + + this.position = { + x: new Interaction.Handle(this.settings.mode, "horizontal", [0, this.width], [this.height, 0]), + y: new Interaction.Handle(this.settings.mode, "vertical", [0, this.width], [this.height, 0]) + }; + this.position.x.value = this._x.normalized; + this.position.y.value = this._y.normalized; + + this.init(); + this.render(); + } + + _inherits(Position, _Interface); + + _createClass(Position, { + buildInterface: { + value: function buildInterface() { + + this.knob = svg.create("circle"); + this.element.appendChild(this.knob); + } + }, + sizeInterface: { + value: function sizeInterface() { + + this.position.x.resize([0, this.width], [this.height, 0]); + this.position.y.resize([0, this.width], [this.height, 0]); + + this._minDimension = Math.min(this.width, this.height); + + this.knobRadius = { + off: ~ ~(this._minDimension / 100) * 5 + 5 }; + this.knobRadius.on = this.knobRadius.off * 2; + + this.knob.setAttribute("cx", this.width / 2); + this.knob.setAttribute("cy", this.height / 2); + this.knob.setAttribute("r", this.knobRadius.off); + } + }, + colorInterface: { + value: function colorInterface() { + this.element.style.backgroundColor = this.colors.fill; + this.knob.setAttribute("fill", this.colors.accent); + } + }, + render: { + value: function render() { + if (this.clicked) { + // this.knobRadius = 30; + this.knob.setAttribute("r", this.knobRadius.on); + } else { + // this.knobRadius = 15; + this.knob.setAttribute("r", this.knobRadius.off); + } + + this.knobCoordinates = { + x: this._x.normalized * this.width, + y: this.height - this._y.normalized * this.height + }; + + this.knob.setAttribute("cx", this.knobCoordinates.x); + this.knob.setAttribute("cy", this.knobCoordinates.y); + } + }, + click: { + value: function click() { + this.position.x.anchor = this.mouse; + this.position.y.anchor = this.mouse; + this.move(); + } + }, + move: { + value: function move() { + if (this.clicked) { + this.position.x.update(this.mouse); + this.position.y.update(this.mouse); + this._x.updateNormal(this.position.x.value); + this._y.updateNormal(this.position.y.value); + this.emit("change", { + x: this._x.value, + y: this._y.value + }); + this.render(); + } + } + }, + release: { + value: function release() { + this.render(); + } + }, + x: { + + /** + * The interface's x value. When set, it will automatically adjust to fit min/max/step settings of the interface. + * @type {object} + * @example position.x = 0.5; + */ + + get: function () { + return this._x.value; + }, + set: function (value) { + this._x.update(value); + this.emit("change", { + x: this._x.value, + y: this._y.value + }); + this.render(); + } + }, + y: { + + /** + * The interface's y values. When set, it will automatically adjust to fit min/max/step settings of the interface. + * @type {object} + * @example position.x = 0.5; + */ + + get: function () { + return this._y.value; + }, + set: function (value) { + this._y.update(value); + this.emit("change", { + x: this._x.value, + y: this._y.value + }); + this.render(); + } + }, + normalized: { + get: function () { + return { + x: this._x.normalized, + y: this._y.normalized + }; + } + }, + minX: { + + /** + * The lower limit of value on the x axis + * @type {object} + */ + + get: function () { + return this._x.min; + }, + set: function (v) { + this._x.min = v; + this.render(); + } + }, + minY: { + + /** + * The lower limit of value on the y axis + * @type {object} + */ + + get: function () { + return this._y.min; + }, + set: function (v) { + this._y.min = v; + this.render(); + } + }, + maxX: { + + /** + * The upper limit of value on the x axis + * @type {object} + */ + + get: function () { + return this._x.max; + }, + set: function (v) { + this._x.max = v; + this.render(); + } + }, + maxY: { + + /** + * The upper limit of value on the y axis + * @type {object} + */ + + get: function () { + return this._y.max; + }, + set: function (v) { + this._y.max = v; + this.render(); + } + }, + stepX: { + + /** + * The incremental step of values on the x axis + * @type {object} + */ + + get: function () { + return this._x.step; + }, + set: function (v) { + this._x.step = v; + this.render(); + } + }, + stepY: { + + /** + * The incremental step of values on the y axis + * @type {object} + */ + + get: function () { + return this._y.step; + }, + set: function (v) { + this._y.step = v; + this.render(); + } + }, + mode: { + + /** + Absolute mode (position's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: "absolute". + @type {string} + @example position.mode = "relative"; + */ + + get: function () { + return this.position.x.mode; + }, + set: function (v) { + this.position.x.mode = v; + this.position.y.mode = v; + } + } + }); + + return Position; + })(Interface); + + module.exports = Position; + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var math = __webpack_require__(5); + + module.exports = { + + create: function (type) { + return document.createElementNS("http://www.w3.org/2000/svg", type); + }, + + arc: function (x, y, radius, startAngle, endAngle) { + + var start = math.toCartesian(radius, endAngle); + var end = math.toCartesian(radius, startAngle); + + var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1"; + + var d = ["M", start.x + x, start.y + y, "A", radius, radius, 0, largeArcFlag, 0, end.x + x, end.y + y].join(" "); + + return d; + }, + + radialGradient: function (defs, numberOfStops) { + + var id = "gradient" + math.ri(100000000000); + var stops = []; + + var gradient = document.createElementNS("http://www.w3.org/2000/svg", "radialGradient"); + gradient.setAttribute("id", id); + gradient.setAttribute("cx", "50%"); + gradient.setAttribute("cy", "50%"); + gradient.setAttribute("r", "50%"); + + defs.appendChild(gradient); + + for (var i = 0; i < numberOfStops; i++) { + var _stop = document.createElementNS("http://www.w3.org/2000/svg", "stop"); + _stop.setAttribute("id", "stop" + i); + //stop.setAttribute('offset', '70%'); + //stop.setAttribute('stop-color', 'White'); + gradient.appendChild(_stop); + stops.push(_stop); + } + + return { + id: id, + stops: stops, + element: gradient + }; + } + + }; + +/***/ }), +/* 5 */ +/***/ (function(module, exports) { + + "use strict"; + + /** + * Limit a number to within a minimum and maximum + * @param {number} value Input value + * @param {number} min Lower limit + * @param {number} max Upper limit + * @return {number} The input value constrained within the lower and upper limits + * @example + * Nexus.clip(11,0,10) // returns 10 + * Nexus.clip(-1,0,10) // returns 0 + * Nexus.clip(5,0,10) // returns 5 + */ + + exports.clip = function (value, min, max) { + return Math.min(Math.max(value, min), max); + }; + + exports.normalize = function (value, min, max) { + return (value - min) / (max - min); + }; + + /** + * Scale a value from one range to another range. + * @param {number} inNum Input value + * @param {number} inMin Input range minimum + * @param {number} inMax Input range maximum + * @param {number} outMin Output range minimum + * @param {number} outMax Output range maximum + * @return {number} The input value scaled to its new range + * @example + * Nexus.scale(0.5,0,1,0,10) // returns 5 + * Nexus.scale(0.9,0,1,1,0) // returns 0.1 + */ + exports.scale = function (inNum, inMin, inMax, outMin, outMax) { + if (inMin === inMax) { + return outMin; + } + return (inNum - inMin) * (outMax - outMin) / (inMax - inMin) + outMin; + }; + + exports.toPolar = function (x, y) { + var r = Math.sqrt(x * x + y * y); + + var theta = Math.atan2(y, x); + if (theta < 0) { + theta = theta + 2 * Math.PI; + } + return { radius: r, angle: theta }; + }; + + exports.toCartesian = function (radius, angle) { + var cos = Math.cos(angle); + var sin = Math.sin(angle); + return { x: radius * cos, y: radius * sin * -1 }; + }; + /* + exports.polarToCartesian(centerX, centerY, radius, angleInDegrees) { + var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0; + + return { + x: centerX + (radius * Math.cos(angleInRadians)), + y: centerY + (radius * Math.sin(angleInRadians)) + }; + } */ + + exports.prune = function (data, scale) { + return parseFloat(data.toFixed(scale)); + }; + + exports.invert = function (inNum) { + return exports.scale(inNum, 1, 0, 0, 1); + }; + + /** + * Convert a MIDi note number to a frequency value in equal temperament. + * @param {number} midi MIDI note value + * @return {number} Frequence value + * @example + * Nexus.mtof(60) // returns the frequency number of Middle C + */ + exports.mtof = function (midi) { + return Math.pow(2, (midi - 69) / 12) * 440; + }; + + /** + * Interpolate between two numbers + * @param {number} loc Interpolation index (0-1) + * @param {number} min Lower value + * @param {number} max Upper value + * @return {number} Interpolated value + * @example + * Nexus.interp(0.5,2,4) // returns 3 + * Nexus.interp(0.1,0,10) // returns 1 + */ + exports.interp = function (loc, min, max) { + return loc * (max - min) + min; + }; + + /** + * Return a random choice from a list of arguments + * @return {various} One random argument + * @example + * Nexus.pick(1,2,3,4) // returns 1, 2, 3, or 4 + * Nexus.pick(function1,function2) // returns either function1 or function2 + */ + exports.pick = function () { + return arguments[~ ~(Math.random() * arguments.length)]; + }; + + /** + * Returns an octave multiplier for frequency values + * @param {number} num Relative octave number (e.g. -1 for one octave down, 1 for one octave up) + * @return {number} Octave multiplier + * @example + * Nexus.octave(-1) // returns 0.5 + * Nexus.octave(0) // returns 1 + * Nexus.octave(1) // returns 2 + * Nexus.octave(2) // returns 4 + */ + exports.octave = function (num) { + return Math.pow(2, num); + }; + + /** + * Random integer generator. If no second argument is given, will return random integer from 0 to bound1. + * @param {number} bound1 Minimum random value + * @param {number} bound2 Maximum random value + * @return {number} Random integer between lower and upper boundary + * @example + * Nexus.ri(10) // returns random int from 0 to 10 + * Nexus.ri(20,2000) // returns random int from 20 to 2000 + */ + exports.ri = function (bound1, bound2) { + if (!bound2) { + bound2 = bound1; + bound1 = 0; + } + var low = Math.min(bound1, bound2); + var high = Math.max(bound1, bound2); + return Math.floor(Math.random() * (high - low) + low); + }; + + /** + * Random float number generator. If no second argument is given, will return random float from 0 to bound1. + * @param {number} bound1 Minimum random value + * @param {number} bound2 Maximum random value + * @return {number} Random float between lower and upper boundary + * @example + * Nexus.rf(1) // returns random float from 0 to 1 + * Nexus.rf(1,2) // returns random float from 1 to 2 + */ + exports.rf = function (bound1, bound2) { + if (!bound2) { + bound2 = bound1; + bound1 = 0; + } + var low = Math.min(bound1, bound2); + var high = Math.max(bound1, bound2); + return Math.random() * (high - low) + low; + }; + + exports.cycle = function (input, min, max) { + input++; + if (input >= max) { + input = min; + } + return input; + }; + + /** + * Average an array of numbers + * @param {Array} data Array of numbers to average + * @return {number} Average of the input data + * @example + * Nexus.average([0,2,4,6,8,10]) // returns 5 + */ + exports.average = function (data) { + var total = 0; + for (var i = 0; i < data.length; i++) { + total += data[i]; + } + return total / data.length; + }; + + /** + * Get the distance from one (x,y) point to another (x,y) point + * @param {number} x1 x of first point + * @param {number} y1 y of first point + * @param {number} x2 x of second point + * @param {number} y2 y of second poiny + * @return {number} Distance + * @example + * Nexus.distance(0,0,3,4) // returns 5 + */ + exports.distance = function (x1, y1, x2, y2) { + var a = x1 - x2; + var b = y1 - y2; + return Math.sqrt(a * a + b * b); + }; + + exports.gainToDB = function (gain) { + return 20 * Math.log10(gain); + }; + + /** + * Flip a coin, returning either 0 or 1 according to a probability + * @param {number} [odds=0.5] Likelihood of returning 1 + * @return {number} 1 or 0 + * @example + * Nexus.coin(0.1) // returns 1 (10% of the time) or 0 (90% of the time) + */ + exports.coin = function () { + var odds = arguments[0] === undefined ? 0.5 : arguments[0]; + + if (exports.rf(0, 1) < odds) { + return 1; + } else { + return 0; + } + }; + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var svg = __webpack_require__(4); + var dom = __webpack_require__(7); + var util = __webpack_require__(8); + var touch = __webpack_require__(9); + var EventEmitter = __webpack_require__(10); + + var colors = __webpack_require__(1).colors; + + /** + Interface + */ + + var Interface = (function (_EventEmitter) { + function Interface(args, options, defaults) { + _classCallCheck(this, Interface); + + _get(Object.getPrototypeOf(Interface.prototype), "constructor", this).call(this); + this.type = this.constructor.name; + this.settings = this.parseSettings(args, options, defaults); + this.mouse = {}; + this.wait = false; + this.colors = {}; + var defaultColors = colors(); // jshint ignore:line + this.colors.accent = defaultColors.accent; + this.colors.fill = defaultColors.fill; + this.colors.light = defaultColors.light; + this.colors.dark = defaultColors.dark; + this.colors.mediumLight = defaultColors.mediumLight; + this.colors.mediumDark = defaultColors.mediumDark; + } + + _inherits(Interface, _EventEmitter); + + _createClass(Interface, { + parseSettings: { + value: function parseSettings(args, options, defaults) { + + options.unshift("target"); + defaults.defaultSize = defaults.size.splice(0, 2); + defaults.size = false; + + var settings = { + target: document.body, + colors: {}, // should inherit from a colors module, + snapWithParent: true, + event: function event() {}, + component: false + }; + + for (var key in defaults) { + settings[key] = defaults[key]; + } + + for (var i = 0; i < args.length; i++) { + // grabs the next argument + var setting = args[i]; + // if it's an object, it must be the settings object + if (util.isObject(setting)) { + for (var key in setting) { + settings[key] = setting[key]; + } + // if it's a function, it must be the event setting + } else if (typeof setting === "function") { + settings.event = setting; + // otherwise, consider it one of the widget's custom options + } else if (options.length >= 1) { + // grab the first option -- i.e. 'target' + var key = options.splice(0, 1)[0]; + settings[key] = setting; + } + } + + /* handle common settings */ + + // target + this.parent = dom.parseElement(settings.target); + + // nexus-ui attribute + if (this.parent && this.parent instanceof HTMLElement && !settings.component) { + if (!this.parent.hasAttribute("nexus-ui")) { + this.parent.setAttribute("nexus-ui", ""); + } + } + + // size + + if (settings.size && Array.isArray(settings.size) && settings.snapWithParent) { + this.width = settings.size[0]; + this.height = settings.size[1]; + this.parent.style.width = this.width + "px"; + this.parent.style.height = this.height + "px"; + } else if (settings.snapWithParent && !settings.component) { + + this.width = parseFloat(window.getComputedStyle(this.parent, null).getPropertyValue("width").replace("px", "")); + this.height = parseFloat(window.getComputedStyle(this.parent, null).getPropertyValue("height").replace("px", "")); + + if (this.width == 5000) { + this.width = settings.defaultSize[0]; + this.parent.style.width = this.parent.width = this.width + "px"; + } + if (this.height == 5000) { + this.height = settings.defaultSize[1]; + this.parent.style.height = this.parent.height = this.height + "px"; + } + } else { + settings.size = settings.defaultSize; + this.width = settings.size[0]; + this.height = settings.size[1]; + } + + // event + if (settings.event) { + this.event = this.on("change", settings.event); + } else { + this.event = false; + } + + return settings; + } + }, + init: { + value: function init() { + this.buildFrame(); + this.buildInterface(); + this.sizeInterface(); + this.attachListeners(); + this.colorInterface(); + this.finalTouches(); + } + }, + buildFrame: { + value: function buildFrame() { + this.element = svg.create("svg"); + this.element.setAttribute("width", this.width); + this.element.setAttribute("height", this.height); + this.parent.appendChild(this.element); + } + }, + buildInterface: { + value: function buildInterface() {} + }, + sizeInterface: { + value: function sizeInterface() {} + }, + colorInterface: { + value: function colorInterface() {} + }, + attachListeners: { + value: function attachListeners() { + var _this = this; + + this.interactionTarget = this.interactionTarget || this.element; + + // Setup interaction + if (touch.exists) { + this.interactionTarget.addEventListener("touchstart", function (evt) { + return _this.preTouch(evt); + }); + this.interactionTarget.addEventListener("touchmove", function (evt) { + return _this.preTouchMove(evt); + }); + this.interactionTarget.addEventListener("touchend", function (evt) { + return _this.preTouchRelease(evt); + }); + } + this.boundPreMove = function (evt) { + return _this.preMove(evt); + }; + this.boundPreRelease = function (evt) { + return _this.preRelease(evt); + }; + this.interactionTarget.addEventListener("mousedown", function (evt) { + return _this.preClick(evt); + }); + } + }, + finalTouches: { + value: function finalTouches() { + this.element.style.cursor = "pointer"; + } + }, + preClick: { + value: function preClick(e) { + // 10000 getComputedStyle calls takes 100 ms. + // .:. one takes about .01ms + if (this.element instanceof HTMLElement) { + this.width = window.getComputedStyle(this.element, null).getPropertyValue("width").replace("px", ""); + } + // 10000 getComputedStyle calls takes 40 ms. + // .:. one takes about .004ms + this.offset = dom.findPosition(this.element); + this.mouse = dom.locateMouse(e, this.offset); + this.clicked = true; + this.click(); + this.moveEvent = document.addEventListener("mousemove", this.boundPreMove); + this.releaseEvent = document.addEventListener("mouseup", this.boundPreRelease); + this.emit("click"); + e.preventDefault(); + e.stopPropagation(); + } + }, + preMove: { + value: function preMove(e) { + var _this = this; + + if (!this.wait) { + this.mouse = dom.locateMouse(e, this.offset); + this.move(); + this.wait = true; + setTimeout(function () { + _this.wait = false; + }, 25); + } + e.preventDefault(); + e.stopPropagation(); + } + }, + preRelease: { + value: function preRelease(e) { + this.mouse = dom.locateMouse(e, this.offset); + this.clicked = false; + this.release(); + this.emit("release"); + document.removeEventListener("mousemove", this.boundPreMove); + document.removeEventListener("mouseup", this.boundPreRelease); + e.preventDefault(); + e.stopPropagation(); + } + }, + click: { + value: function click() {} + }, + move: { + value: function move() {} + }, + release: { + value: function release() {} + }, + preTouch: { + + /* touch */ + + value: function preTouch(e) { + if (this.element instanceof HTMLElement) { + this.width = window.getComputedStyle(this.element, null).getPropertyValue("width").replace("px", ""); + } + this.offset = dom.findPosition(this.element); + this.mouse = dom.locateTouch(e, this.offset); + this.clicked = true; + this.touch(e); + this.emit("click"); + e.preventDefault(); + e.stopPropagation(); + } + }, + preTouchMove: { + value: function preTouchMove(e) { + if (this.clicked) { + this.mouse = dom.locateTouch(e, this.offset); + this.touchMove(); + e.preventDefault(); + e.stopPropagation(); + } + } + }, + preTouchRelease: { + value: function preTouchRelease(e) { + this.mouse = dom.locateTouch(e, this.offset); + this.clicked = false; + this.touchRelease(); + this.emit("release"); + e.preventDefault(); + e.stopPropagation(); + } + }, + touch: { + value: function touch() { + this.click(); + } + }, + touchMove: { + value: function touchMove() { + this.move(); + } + }, + touchRelease: { + value: function touchRelease() { + this.release(); + } + }, + resize: { + + /** + * Resize the interface + * @param width {number} New width in pixels + * @param height {number} New height in pixels + * + * @example + * button.resize(100,100); + */ + + value: function resize(width, height) { + this.width = width; + this.height = height; + this.parent.style.width = this.width + "px"; + this.parent.style.height = this.height + "px"; + this.element.setAttribute("width", this.width); + this.element.setAttribute("height", this.height); + this.sizeInterface(); + } + }, + empty: { + value: function empty() { + while (this.element.lastChild) { + this.element.removeChild(this.element.lastChild); + } + } + }, + destroy: { + + /** + * Remove the interface from the page and cancel its event listener(s). + * + * @example + * button.destroy(); + */ + + value: function destroy() { + this.empty(); + this.parent.removeChild(this.element); + this.removeAllListeners(); + if (this.instrument) { + delete this.instrument[this.id]; + } + this.customDestroy(); + } + }, + customDestroy: { + value: function customDestroy() {} + }, + colorize: { + value: function colorize(type, color) { + this.colors[type] = color; + this.colorInterface(); + } + } + }); + + return Interface; + })(EventEmitter); + + module.exports = Interface; + +/***/ }), +/* 7 */ +/***/ (function(module, exports) { + + "use strict"; + + exports.findPosition = function (el) { + var viewportOffset = el.getBoundingClientRect(); + var top = viewportOffset.top + window.scrollY; + var left = viewportOffset.left + window.scrollX; + return { top: top, left: left }; + }; + + exports.parseElement = function (parent) { + if (typeof parent === "string") { + parent = document.getElementById(parent.replace("#", "")); + } + + if (parent instanceof HTMLElement || parent instanceof SVGElement) { + return parent; + } else { + return "No valid parent argument"; + } + }; + + exports.locateMouse = function (e, offset) { + return { + x: e.pageX - offset.left, + y: e.pageY - offset.top + }; + }; + + exports.locateTouch = function (e, offset) { + return { + x: e.targetTouches.length ? e.targetTouches[0].pageX - offset.left : false, + y: e.targetTouches.length ? e.targetTouches[0].pageY - offset.top : false + }; + }; + + exports.SmartCanvas = function (parent) { + var _this = this; + + this.element = document.createElement("canvas"); + this.context = this.element.getContext("2d"); + parent.appendChild(this.element); + + this.resize = function (w, h) { + _this.element.width = w * 2; + _this.element.height = h * 2; + _this.element.style.width = w + "px"; + _this.element.style.height = h + "px"; + }; + }; + +/***/ }), +/* 8 */ +/***/ (function(module, exports) { + + "use strict"; + + exports.isObject = function (obj) { + if (typeof obj === "object" && !Array.isArray(obj) && obj !== null && obj instanceof SVGElement === false && obj instanceof HTMLElement === false) { + return true; + } else { + return false; + } + }; + +/***/ }), +/* 9 */ +/***/ (function(module, exports) { + + "use strict"; + + exports.exists = "ontouchstart" in document.documentElement; + +/***/ }), +/* 10 */ +/***/ (function(module, exports) { + + // Copyright Joyent, Inc. and other Node contributors. + // + // Permission is hereby granted, free of charge, to any person obtaining a + // copy of this software and associated documentation files (the + // "Software"), to deal in the Software without restriction, including + // without limitation the rights to use, copy, modify, merge, publish, + // distribute, sublicense, and/or sell copies of the Software, and to permit + // persons to whom the Software is furnished to do so, subject to the + // following conditions: + // + // The above copyright notice and this permission notice shall be included + // in all copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; + } + module.exports = EventEmitter; + + // Backwards-compat with node 0.10.x + EventEmitter.EventEmitter = EventEmitter; + + EventEmitter.prototype._events = undefined; + EventEmitter.prototype._maxListeners = undefined; + + // By default EventEmitters will print a warning if more than 10 listeners are + // added to it. This is a useful default which helps finding memory leaks. + EventEmitter.defaultMaxListeners = 10; + + // Obviously not all Emitters should be limited to 10. This function allows + // that to be increased. Set to zero for unlimited. + EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; + }; + + EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } else { + // At least give some kind of context to the user + var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); + err.context = er; + throw err; + } + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + } else if (isObject(handler)) { + args = Array.prototype.slice.call(arguments, 1); + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; + }; + + EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; + }; + + EventEmitter.prototype.on = EventEmitter.prototype.addListener; + + EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; + }; + + // emits a 'removeListener' event iff the listener was removed + EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; + }; + + EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; + }; + + EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; + }; + + EventEmitter.prototype.listenerCount = function(type) { + if (this._events) { + var evlistener = this._events[type]; + + if (isFunction(evlistener)) + return 1; + else if (evlistener) + return evlistener.length; + } + return 0; + }; + + EventEmitter.listenerCount = function(emitter, type) { + return emitter.listenerCount(type); + }; + + function isFunction(arg) { + return typeof arg === 'function'; + } + + function isNumber(arg) { + return typeof arg === 'number'; + } + + function isObject(arg) { + return typeof arg === 'object' && arg !== null; + } + + function isUndefined(arg) { + return arg === void 0; + } + + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var math = __webpack_require__(5); + + /** + Creates a steppable value with minimum, maximum, and step size. This is used in many interfaces to constrict their values to certain ranges. + @param {number} [min=0] minimum + @param {number} [max=1] maximum + @param {number} [step=0] + @param {number} [value=0] initial value + @returns {Object} Step + */ + + var Step = (function () { + function Step() { + var min = arguments[0] === undefined ? 0 : arguments[0]; + var max = arguments[1] === undefined ? 1 : arguments[1]; + var step = arguments[2] === undefined ? 0 : arguments[2]; + var value = arguments[3] === undefined ? 0 : arguments[3]; + + _classCallCheck(this, Step); + + //Object.assign(this,{min,max,step}); + //Cannot use Object.assign because not supported in Safari. + //I would expect for Babel to take care of this but it is not. + this.min = min; + this.max = max; + this.step = step; + this.value = value; + this.changed = false; + this.oldValue = false; + this.update(this.value); + } + + _createClass(Step, { + update: { + + /** + Update with a new value. The value will be auto-adjusted to fit the min/max/step. + @param {number} value + */ + + value: function update(value) { + if (this.step) { + // this.value = math.clip(Math.round(value / (this.step)) * this.step, this.min,this.max); + this.value = math.clip(Math.round((value - this.min) / this.step) * this.step + this.min, this.min, this.max); + } else { + this.value = math.clip(value, this.min, this.max); + } + if (this.oldValue !== this.value) { + this.oldValue = this.value; + this.changed = true; + } else { + this.changed = false; + } + return this.value; + } + }, + updateNormal: { + + /** + Update with a normalized value 0-1. + @param {number} value + */ + + value: function updateNormal(value) { + this.value = math.scale(value, 0, 1, this.min, this.max); + return this.update(this.value); + } + }, + normalized: { + + /** + Get a normalized version of this.value . Not settable. + */ + + get: function () { + return math.normalize(this.value, this.min, this.max); + } + } + }); + + return Step; + })(); + + module.exports = Step; + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + "use strict"; + + var math = _interopRequire(__webpack_require__(5)); + + var ToggleModel = _interopRequire(__webpack_require__(13)); + + /* + how to use : + + dial.interaction = new Handle('radial','relative',this.width,this.height); + // dial.interaction.mode = 'relative' + // dial.interaction.direction = 'radial' + + on click: + dial.interaction.anchor = this.mouse; + + on move: + dial.interaction.update(this.mouse); + + console.log( dial.interaction.value ); should be a normalized value. + + */ + + /* + absolute/relative are property: mode + radial/vertical/horizontal/2d are property: direction + + plan : + + if relative -- + NO on click, get value offset between current value and click value. + NO on move, use click value - offset + INSTEAD + use delta -- bc vertical motion on dial is impossible otherwise + also allow to set sensitivity + + */ + + var Handle = exports.Handle = (function () { + function Handle() { + var mode = arguments[0] === undefined ? "absolute" : arguments[0]; + var direction = arguments[1] === undefined ? "vertical" : arguments[1]; + var xbound = arguments[2] === undefined ? [0, 100] : arguments[2]; + var ybound = arguments[3] === undefined ? [0, 100] : arguments[3]; + + _classCallCheck(this, Handle); + + this.mode = mode; + this.direction = direction; + this.previous = 0; + this.value = 0; + this.sensitivity = 1; + this.resize(xbound, ybound); + } + + _createClass(Handle, { + resize: { + value: function resize(xbound, ybound) { + this.boundary = { + min: { + x: xbound[0], + y: ybound[0] + }, + max: { + x: xbound[1], + y: ybound[1] + }, + center: { + x: (xbound[1] - xbound[0]) / 2 + xbound[0], + y: (ybound[1] - ybound[0]) / 2 + ybound[0] + } + }; + } + }, + anchor: { + set: function (mouse) { + this._anchor = this.convertPositionToValue(mouse); + }, + get: function () { + return this._anchor; + } + }, + update: { + value: function update(mouse) { + if (this.mode === "relative") { + var increment = this.convertPositionToValue(mouse) - this.anchor; + if (Math.abs(increment) > 0.5) { + increment = 0; + } + this.anchor = mouse; + this.value = this.value + increment * this.sensitivity; + } else { + this.value = this.convertPositionToValue(mouse); + } + this.value = math.clip(this.value, 0, 1); + } + }, + convertPositionToValue: { + value: function convertPositionToValue(current) { + switch (this.direction) { + case "radial": + var position = math.toPolar(current.x - this.boundary.center.x, current.y - this.boundary.center.y); + position = position.angle / (Math.PI * 2); + position = (position - 0.25 + 1) % 1; + return position; + case "vertical": + return math.scale(current.y, this.boundary.min.y, this.boundary.max.y, 0, 1); + case "horizontal": + return math.scale(current.x, this.boundary.min.x, this.boundary.max.x, 0, 1); + } + } + } + }); + + return Handle; + })(); + + var Button = exports.Button = (function () { + function Button() { + var mode = arguments[0] === undefined ? "button" : arguments[0]; + + _classCallCheck(this, Button); + + this.mode = mode; + this.state = new ToggleModel(); + this.paintbrush = false; + } + + _createClass(Button, { + click: { + value: function click() { + switch (this.mode) { + case "impulse": + this.state.on(); + if (this.timeout) { + clearTimeout(this.timeout); + } + this.timeout = setTimeout(this.state.off.bind(this), 30); + this.emit("change", this.state); + break; + case "button": + this.turnOn(); + this.emit("change", this.state); + break; + case "aftertouch": + this.position = { + x: math.clip(this.mouse.x / this.width, 0, 1), + y: math.clip(1 - this.mouse.y / this.height, 0, 1) + }; + this.turnOn(); + this.emit("change", { + state: this.state, + x: this.position.x, + y: this.position.y }); + break; + case "toggle": + this.flip(); + this.emit("change", this.state); + break; + } + } + }, + move: { + value: function move() { + if (this.mode === "aftertouch") { + this.position = { + x: math.clip(this.mouse.x / this.width, 0, 1), + y: math.clip(1 - this.mouse.y / this.height, 0, 1) + }; + this.emit("change", { + state: this.state, + x: this.position.x, + y: this.position.y }); + this.render(); + } + } + }, + release: { + value: function release() { + switch (this.mode) { + case "button": + this.turnOff(); + this.emit("change", this.state); + break; + case "aftertouch": + this.turnOff(); + this.position = { + x: this.mouse.x / this.width, + y: 1 - this.mouse.y / this.height + }; + this.emit("change", { + state: this.state, + x: this.position.x, + y: this.position.y }); + break; + } + } + } + }); + + return Button; + })(); + +/***/ }), +/* 13 */ +/***/ (function(module, exports) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var Toggle = (function () { + function Toggle(state) { + _classCallCheck(this, Toggle); + + this.state = state || false; + } + + _createClass(Toggle, { + flip: { + value: function flip(state) { + if (state || state === false) { + this.state = state; + } else { + this.state = !this.state; + } + } + }, + on: { + value: function on() { + this.state = true; + } + }, + off: { + value: function off() { + this.state = false; + } + } + }); + + return Toggle; + })(); + + module.exports = Toggle; + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var svg = __webpack_require__(4); + var Interface = __webpack_require__(6); + var Step = __webpack_require__(11); + + var Interaction = _interopRequireWildcard(__webpack_require__(12)); + + /** + * Slider + * + * @description Horizontal or vertical slider with settable interaction modes. + * + * @demo <span nexus-ui="slider" step=0.2></span> + * + * @example + * var slider = new Nexus.Slider('#target') + * + * @example + * var slider = new Nexus.Slider('#target',{ + * 'size': [120,20], + * 'mode': 'relative', // 'relative' or 'absolute' + * 'min': 0, + * 'max': 1, + * 'step': 0, + * 'value': 0 + * }) + * + * @output + * change + * Fires when the interface's value changes. <br> + * Event data: <i>number</i> The number value of the interface. + * + * @outputexample + * slider.on('change',function(v) { + * console.log(v); + * }) + * + * + */ + + var Slider = (function (_Interface) { + function Slider() { + _classCallCheck(this, Slider); + + var options = ["min", "max", "value"]; + + var defaults = { + size: [120, 20], + mode: "relative", // 'relative' or 'absolute' + min: 0, + max: 1, + step: 0, + value: 0 + }; + + _get(Object.getPrototypeOf(Slider.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.orientation = "vertical"; // This will change automatically to 'horizontal'if the interface is wider than it is tall. + + this._value = new Step(this.settings.min, this.settings.max, this.settings.step, this.settings.value); + + this.position = new Interaction.Handle(this.settings.mode, this.orientation, [0, this.width], [this.height, 0]); + this.position.value = this._value.normalized; + + this.init(); + + this.position.direction = this.orientation; + + this.emit("change", this.value); + } + + _inherits(Slider, _Interface); + + _createClass(Slider, { + buildInterface: { + value: function buildInterface() { + + this.bar = svg.create("rect"); + this.fillbar = svg.create("rect"); + this.knob = svg.create("circle"); + + this.element.appendChild(this.bar); + this.element.appendChild(this.fillbar); + this.element.appendChild(this.knob); + } + }, + sizeInterface: { + value: function sizeInterface() { + + if (this.width < this.height) { + this.orientation = "vertical"; + } else { + this.orientation = "horizontal"; + } + + if (this.position) { + this.position.resize([0, this.width], [this.height, 0]); + } + + var x = undefined, + y = undefined, + w = undefined, + h = undefined, + barOffset = undefined, + cornerRadius = undefined; + this.knobData = { + level: 0, + r: 0 + }; + + if (this.orientation === "vertical") { + this.thickness = this.width / 2; + x = this.width / 2; + y = 0; + w = this.thickness; + h = this.height; + this.knobData.r = this.thickness * 0.8; + this.knobData.level = h - this.knobData.r - this.normalized * (h - this.knobData.r * 2); + barOffset = "translate(" + this.thickness * -1 / 2 + ",0)"; + cornerRadius = w / 2; + } else { + this.thickness = this.height / 2; + x = 0; + y = this.height / 2; + w = this.width; + h = this.thickness; + this.knobData.r = this.thickness * 0.8; + this.knobData.level = this.normalized * (w - this.knobData.r * 2) + this.knobData.r; + barOffset = "translate(0," + this.thickness * -1 / 2 + ")"; + cornerRadius = h / 2; + } + + this.bar.setAttribute("x", x); + this.bar.setAttribute("y", y); + this.bar.setAttribute("transform", barOffset); + this.bar.setAttribute("rx", cornerRadius); // corner radius + this.bar.setAttribute("ry", cornerRadius); + this.bar.setAttribute("width", w); + this.bar.setAttribute("height", h); + + if (this.orientation === "vertical") { + this.fillbar.setAttribute("x", x); + this.fillbar.setAttribute("y", this.knobData.level); + this.fillbar.setAttribute("width", w); + this.fillbar.setAttribute("height", h - this.knobData.level); + } else { + this.fillbar.setAttribute("x", 0); + this.fillbar.setAttribute("y", y); + this.fillbar.setAttribute("width", this.knobData.level); + this.fillbar.setAttribute("height", h); + } + this.fillbar.setAttribute("transform", barOffset); + this.fillbar.setAttribute("rx", cornerRadius); + this.fillbar.setAttribute("ry", cornerRadius); + + if (this.orientation === "vertical") { + this.knob.setAttribute("cx", x); + this.knob.setAttribute("cy", this.knobData.level); + } else { + this.knob.setAttribute("cx", this.knobData.level); + this.knob.setAttribute("cy", y); + } + this.knob.setAttribute("r", this.knobData.r); + } + }, + colorInterface: { + value: function colorInterface() { + this.bar.setAttribute("fill", this.colors.fill); + this.fillbar.setAttribute("fill", this.colors.accent); + this.knob.setAttribute("fill", this.colors.accent); + } + }, + render: { + value: function render() { + if (!this.clicked) { + this.knobData.r = this.thickness * 0.75; + } + this.knob.setAttribute("r", this.knobData.r); + + if (this.orientation === "vertical") { + this.knobData.level = this.knobData.r + this._value.normalized * (this.height - this.knobData.r * 2); + this.knob.setAttribute("cy", this.height - this.knobData.level); + this.fillbar.setAttribute("y", this.height - this.knobData.level); + this.fillbar.setAttribute("height", this.knobData.level); + } else { + this.knobData.level = this._value.normalized * (this.width - this.knobData.r * 2) + this.knobData.r; + this.knob.setAttribute("cx", this.knobData.level); + this.fillbar.setAttribute("x", 0); + this.fillbar.setAttribute("width", this.knobData.level); + } + } + }, + click: { + value: function click() { + this.knobData.r = this.thickness * 0.9; + this.position.anchor = this.mouse; + this.move(); + } + }, + move: { + value: function move() { + if (this.clicked) { + this.position.update(this.mouse); + this._value.updateNormal(this.position.value); + this.emit("change", this._value.value); + this.render(); + } + } + }, + release: { + value: function release() { + this.render(); + } + }, + normalized: { + get: function () { + return this._value.normalized; + } + }, + value: { + + /** + The slider's current value. If set manually, will update the interface and trigger the output event. + @type {number} + @example slider.value = 10; + */ + + get: function () { + return this._value.value; + }, + set: function (v) { + this._value.update(v); + this.position.value = this._value.normalized; + this.emit("change", this._value.value); + this.render(); + } + }, + min: { + + /** + Lower limit of the sliders's output range + @type {number} + @example slider.min = 1000; + */ + + get: function () { + return this._value.min; + }, + set: function (v) { + this._value.min = v; + } + }, + max: { + + /** + Upper limit of the slider's output range + @type {number} + @example slider.max = 1000; + */ + + get: function () { + return this._value.max; + }, + set: function (v) { + this._value.max = v; + } + }, + step: { + + /** + The increment that the slider's value changes by. + @type {number} + @example slider.step = 5; + */ + + get: function () { + return this._value.step; + }, + set: function (v) { + this._value.step = v; + } + }, + mode: { + + /** + Absolute mode (slider's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: "relative". + @type {string} + @example slider.mode = "relative"; + */ + + get: function () { + return this.position.mode; + }, + set: function (v) { + this.position.mode = v; + } + } + }); + + return Slider; + })(Interface); + + module.exports = Slider; + +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var svg = __webpack_require__(4); + var ToggleModel = __webpack_require__(13); + var Interface = __webpack_require__(6); + + /** + * Toggle + * + * @description Binary switch + * + * @demo <span nexus-ui="toggle"></span> + * + * @example + * var toggle = new Nexus.Toggle('#target') + * + * @example + * var toggle = new Nexus.Toggle('#target',{ + * 'size': [40,20], + * 'state': false + * }) + * + * @output + * change + * Fires any time the interface's value changes. <br> + * Parameter: The boolean state of the interface. + * + * @outputexample + * toggle.on('change',function(v) { + * console.log(v); + * }) + * + * + */ + + var Toggle = (function (_Interface) { + function Toggle() { + _classCallCheck(this, Toggle); + + var options = ["value"]; + + var defaults = { + size: [40, 20], + target: false, + state: false + }; + + _get(Object.getPrototypeOf(Toggle.prototype), "constructor", this).call(this, arguments, options, defaults); + + this._state = new ToggleModel(this.settings.state); + + this.init(); + } + + _inherits(Toggle, _Interface); + + _createClass(Toggle, { + buildInterface: { + value: function buildInterface() { + + this.bar = svg.create("rect"); + this.knob = svg.create("circle"); + this.element.appendChild(this.bar); + this.element.appendChild(this.knob); + } + }, + sizeInterface: { + value: function sizeInterface() { + + if (this.height < this.width / 2) { + this.knobSize = this.height / 2; + } else { + this.knobSize = this.width / 4; + } + + this.bar.setAttribute("x", this.width / 2 - this.knobSize * 1.5); + this.bar.setAttribute("y", this.height / 2 - this.knobSize / 2); + this.bar.setAttribute("rx", this.knobSize / 2); + this.bar.setAttribute("ry", this.knobSize / 2); + this.bar.setAttribute("width", this.knobSize * 3); + this.bar.setAttribute("height", this.knobSize); + + this.knob.setAttribute("cx", this.width / 2 - this.knobSize); + this.knob.setAttribute("cy", this.height / 2); + this.knob.setAttribute("r", this.knobSize); + } + }, + colorInterface: { + value: function colorInterface() { + this.knob.setAttribute("fill", this.colors.accent); + this.render(); + } + }, + render: { + value: function render() { + if (!this.state) { + this.knob.setAttribute("cx", this.width / 2 - this.knobSize); + this.bar.setAttribute("fill", this.colors.fill); + } else { + this.knob.setAttribute("cx", this.width / 2 + this.knobSize); + this.bar.setAttribute("fill", this.colors.accent); + } + } + }, + click: { + value: function click() { + this.flip(); + this.render(); + this.emit("change", this.state); + } + }, + state: { + + /** + Whether the toggle is currently on or off. Setting this property will update the toggle interface and trigger the output event. + @type {boolean} + @example toggle.state = false; + */ + + get: function () { + return this._state.state; + }, + set: function (value) { + this._state.flip(value); + this.emit("change", this.state); + this.render(); + } + }, + flip: { + + /** + * Switch the toggle state to its opposite state + * @example + * toggle.flip(); + */ + + value: function flip() { + this._state.flip(); + this.render(); + } + } + }); + + return Toggle; + })(Interface); + + module.exports = Toggle; + +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var svg = __webpack_require__(4); + var ButtonTemplate = __webpack_require__(17); + + /** + * Button + * + * @description Circular button with optional aftertouch. + * + * @demo <span nexus-ui="button"></span> + * + * @example + * var button = new Nexus.Button('#target') + * + * @example + * var button = new Nexus.Button('#target',{ + * 'size': [80,80], + * 'mode': 'aftertouch', + * 'state': false + * }) + * + * @output + * change + * Fires any time the interface's value changes. <br> + * In <b>button mode</b>, <b>toggle mode</b>, and <b>impulse mode</b>, the output data is a boolean describing the state of the button.<br> + * In <b>aftertouch mode</b>, the output data is an object containing x (0-1) and y (0-1) positions of aftertouch. + * + * @outputexample + * button.on('change',function(v) { + * // v is the value of the button + * console.log(v); + * }) + * + */ + + var Button = (function (_ButtonTemplate) { + function Button() { + _classCallCheck(this, Button); + + var options = ["mode"]; + + var defaults = { + size: [80, 80], + mode: "aftertouch", // button, aftertouch, impulse, toggle + state: false + }; + + _get(Object.getPrototypeOf(Button.prototype), "constructor", this).call(this, arguments, options, defaults); + + /** + * Interaction mode: supports "button", "aftertouch", "impulse", or "toggle" + * @type {string} + * @example button.mode = 'toggle'; + */ + this.mode = this.settings.mode; + + this.init(); + this.render(); + } + + _inherits(Button, _ButtonTemplate); + + _createClass(Button, { + buildInterface: { + value: function buildInterface() { + this.pad = svg.create("circle"); + this.element.appendChild(this.pad); + + this.interactionTarget = this.pad; + + // only used if in 'aftertouch' mode + this.defs = svg.create("defs"); + this.element.appendChild(this.defs); + + this.gradient = svg.radialGradient(this.defs, 2); + + this.gradient.stops[0].setAttribute("offset", "30%"); + + this.gradient.stops[1].setAttribute("offset", "100%"); + } + }, + sizeInterface: { + value: function sizeInterface() { + + this.pad.setAttribute("cx", this.width / 2); + this.pad.setAttribute("cy", this.height / 2); + this.pad.setAttribute("r", Math.min(this.width, this.height) / 2 - this.width / 40); + this.pad.setAttribute("stroke-width", this.width / 20); + } + }, + colorInterface: { + value: function colorInterface() { + + this.gradient.stops[0].setAttribute("stop-color", this.colors.accent); + this.gradient.stops[1].setAttribute("stop-color", this.colors.fill); + this.render(); + } + }, + render: { + + /* + * Update the visual interface using its current state + * + * @example + * button.render(); + */ + + value: function render() { + if (!this.state) { + this.pad.setAttribute("fill", this.colors.fill); + this.pad.setAttribute("stroke", this.colors.mediumLight); + } else { + if (this.mode === "aftertouch") { + this.pad.setAttribute("stroke", "url(#" + this.gradient.id + ")"); + this.gradient.element.setAttribute("cx", this.position.x * 100 + "%"); + this.gradient.element.setAttribute("cy", (1 - this.position.y) * 100 + "%"); + } else { + this.pad.setAttribute("stroke", this.colors.accent); + } + this.pad.setAttribute("fill", this.colors.accent); + } + } + } + }); + + return Button; + })(ButtonTemplate); + + module.exports = Button; + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var svg = __webpack_require__(4); + var math = __webpack_require__(5); + var ToggleModel = __webpack_require__(13); + var Interface = __webpack_require__(6); + + /** + Button Template + */ + + var ButtonTemplate = (function (_Interface) { + function ButtonTemplate(args, options, defaults) { + _classCallCheck(this, ButtonTemplate); + + _get(Object.getPrototypeOf(ButtonTemplate.prototype), "constructor", this).call(this, args, options, defaults); + + this.mode = this.settings.mode || "button"; + + this.position = { + x: 0, + y: 0 + }; + + this._state = new ToggleModel(this.settings.state); + } + + _inherits(ButtonTemplate, _Interface); + + _createClass(ButtonTemplate, { + buildInterface: { + value: function buildInterface() { + this.pad = svg.create("circle"); + this.pad.setAttribute("fill", "#d18"); + this.pad.setAttribute("stroke", "#d18"); + this.pad.setAttribute("stroke-width", 4); + + this.element.appendChild(this.pad); + + this.interactionTarget = this.pad; + + this.sizeInterface(); + } + }, + sizeInterface: { + value: function sizeInterface() { + this.pad.setAttribute("cx", this.width / 2); + this.pad.setAttribute("cy", this.height / 2); + this.pad.setAttribute("r", Math.min(this.width, this.height) / 2 - 2); + } + }, + render: { + value: function render() { + if (!this.state) { + this.pad.setAttribute("fill", this.colors.fill); + this.pad.setAttribute("stroke", this.colors.mediumLight); + } else { + this.pad.setAttribute("fill", this.colors.accent); + this.pad.setAttribute("stroke", this.colors.accent); + } + } + }, + down: { + value: function down(paintbrush) { + switch (this.mode) { + case "impulse": + this.turnOn(); + if (this.timeout) { + clearTimeout(this.timeout); + } + this.timeout = setTimeout(this.turnOff.bind(this), 30); + // this.emit('change',this.state); + break; + case "button": + this.turnOn(); + // this.emit('change',this.state); + break; + case "aftertouch": + this.position = { + x: math.clip(this.mouse.x / this.width, 0, 1), + y: math.clip(1 - this.mouse.y / this.height, 0, 1) + }; + this.turnOn(); + // this.emit('change',{ + // state: this.state, + // x: this.position.x, + // y: this.position.y, + // }); + break; + case "toggle": + this.flip(paintbrush); + // this.emit('change',this.state); + break; + } + } + }, + bend: { + value: function bend(mouse) { + if (this.mode === "aftertouch") { + this.mouse = mouse || this.mouse; + this.position = { + x: math.clip(this.mouse.x / this.width, 0, 1), + y: math.clip(1 - this.mouse.y / this.height, 0, 1) + }; + this.emit("change", { + state: this.state, + x: this.position.x, + y: this.position.y }); + this.render(); + } + } + }, + up: { + value: function up() { + switch (this.mode) { + case "button": + this.turnOff(); + // this.emit('change',this.state); + break; + case "aftertouch": + this.turnOff(); + this.position = { + x: math.clip(this.mouse.x / this.width, 0, 1), + y: math.clip(1 - this.mouse.y / this.height, 0, 1) + }; + // this.emit('change',{ + // state: this.state, + // x: this.position.x, + // y: this.position.y, + // }); + break; + } + } + }, + click: { + + /* overwritable interaction handlers */ + + value: function click() { + this.down(); + } + }, + move: { + value: function move() { + this.bend(); + } + }, + release: { + value: function release() { + this.up(); + } + }, + state: { + + /** + Whether the button is on (pressed) or off (not pressed) + @type {boolean} + @example button.state = true; + */ + + get: function () { + return this._state.state; + }, + set: function (value) { + this._state.flip(value); + if (this.mode === "aftertouch") { + this.emit("change", { + state: this.state, + x: this.position.x, + y: this.position.y }); + } else { + this.emit("change", this.state); + } + this.render(); + } + }, + flip: { + + /** + Change the button to its alternate state (off=>on, on=>off), or flip it to a specified state. + @param value {boolean} (Optional) State to flip to. + @example button.flip(); + */ + + value: function flip(value) { + this._state.flip(value); + if (this.mode === "aftertouch") { + this.emit("change", { + state: this.state, + x: this.position.x, + y: this.position.y }); + } else { + this.emit("change", this.state); + } + this.render(); + } + }, + turnOn: { + + /** + Turn the button's state to true. + @example button.turnOn(); + */ + + value: function turnOn(emitting) { + this._state.on(); + if (emitting !== false) { + if (this.mode === "aftertouch") { + this.emit("change", { + state: this.state, + x: this.position.x, + y: this.position.y }); + } else { + this.emit("change", this.state); + } + } + this.render(); + } + }, + turnOff: { + + /** + Turn the button's state to false. + @example button.turnOff(); + */ + + value: function turnOff(emitting) { + this._state.off(); + if (emitting !== false) { + if (this.mode === "aftertouch") { + this.emit("change", { + state: this.state, + x: this.position.x, + y: this.position.y }); + } else { + this.emit("change", this.state); + } + } + this.render(); + } + } + }); + + return ButtonTemplate; + })(Interface); + + module.exports = ButtonTemplate; + +/***/ }), +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var ButtonTemplate = __webpack_require__(17); + + /** + * TextButton + * + * @description Text button + * + * @demo <span nexus-ui="textButton"></span> + * + * @example + * var textbutton = new Nexus.TextButton('#target') + * + * @example + * var textbutton = new Nexus.TextButton('#target',{ + * 'size': [150,50], + * 'state': false, + * 'text': 'Play', + * 'alternateText': 'Stop' + * }) + * + * @output + * change + * Fires any time the interface's value changes. <br> + * The event data is a <i>string</i> of the text on the button at the moment it was clicked. + * + * @outputexample + * textbutton.on('change',function(v) { + * console.log(v); + * }) + * + */ + + var TextButton = (function (_ButtonTemplate) { + function TextButton() { + _classCallCheck(this, TextButton); + + var options = ["value"]; + + var defaults = { + size: [150, 50], + state: false, + text: "Play" + }; + + _get(Object.getPrototypeOf(TextButton.prototype), "constructor", this).call(this, arguments, options, defaults); + + this._text = this.settings.text; + + if (this.settings.alternate) { + //TODO: Remove this conditional in a breaking-changes release + this.settings.alternateText = this.settings.alternate; + console.warn("'alternate' initiator is deprecated. Use 'alternateText' instead."); + } + this._alternateText = this.settings.alternateText; + this.mode = this.settings.alternateText ? "toggle" : "button"; + this.init(); + this.render(); + + this.state = this.settings.state; + } + + _inherits(TextButton, _ButtonTemplate); + + _createClass(TextButton, { + buildFrame: { + value: function buildFrame() { + + this.element = document.createElement("div"); + this.parent.appendChild(this.element); + + this.textElement = document.createElement("div"); + this.textElement.innerHTML = this._text; + this.element.appendChild(this.textElement); + } + }, + buildInterface: { + value: function buildInterface() {} + }, + colorInterface: { + value: function colorInterface() { + this.element.style.color = this.colors.dark; + this.render(); + } + }, + sizeInterface: { + value: function sizeInterface() { + var textsize = this.height / 3; + var textsize2 = this.width / (this._text.length + 2); + textsize = Math.min(textsize, textsize2); + if (this.alternateText) { + var textsize3 = this.width / (this.alternateText.length + 2); + textsize = Math.min(textsize, textsize3); + } + var styles = "width: " + this.width + "px;"; + styles += "height: " + this.height + "px;"; + styles += "padding: " + (this.height - textsize) / 2 + "px 0px;"; + styles += "box-sizing: border-box;"; + styles += "text-align: center;"; + styles += "font-family: inherit;"; + styles += "font-weight: 700;"; + styles += "opacity: 1;"; + styles += "font-size:" + textsize + "px;"; + this.textElement.style.cssText = styles; + this.render(); + } + }, + render: { + value: function render() { + if (!this.state) { + this.element.style.backgroundColor = this.colors.fill; + this.textElement.style.color = this.colors.dark; + this.textElement.innerHTML = this._text; + } else { + this.element.style.backgroundColor = this.colors.accent; + this.textElement.style.color = this.colors.fill; + if (this.alternateText) { + this.textElement.innerHTML = this._alternateText; + } else { + this.textElement.innerHTML = this._text; + } + } + } + }, + alternateText: { + + /** + The text to display when the button is in its "on" state. If set, this puts the button in "toggle" mode. + @type {String} + */ + + get: function () { + return this._alternateText; + }, + set: function (text) { + if (text) { + this.mode = "toggle"; + } else { + this.mode = "button"; + } + this._alternateText = text; + this.render(); + } + }, + text: { + + /** + The text to display. (If .alternateText exists, then this .text will only be displayed when the button is in its "off" state.) + @type {String} + */ + + get: function () { + return this._text; + }, + set: function (text) { + this._text = text; + this.sizeInterface(); + this.render(); + } + } + }); + + return TextButton; + })(ButtonTemplate); + + module.exports = TextButton; + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + //let svg = require('../util/svg'); + var Interface = __webpack_require__(6); + var Button = __webpack_require__(16); + + /** + * RadioButton + * + * @description An array of buttons. By default, selecting one button will deselect all other buttons, but this can be customized using the API below. + * + * @demo <div nexus-ui="RadioButton"></div> + * + * @example + * var radiobutton = new Nexus.RadioButton('#target') + * + * @example + * var radiobutton = new Nexus.RadioButton('#target',{ + * 'size': [120,25], + * 'numberOfButtons': 4, + * 'active': -1 + * }) + * + * @output + * change + * Fires any time the interface's value changes. <br> + * The event data an <i>integer</i>, the index of the button that is currently on. If no button is selected, the value will be -1. + * + * @outputexample + * radiobutton.on('change',function(v) { + * console.log(v); + * }) + * + */ + + var RadioButton = (function (_Interface) { + function RadioButton() { + _classCallCheck(this, RadioButton); + + var options = ["value"]; + + var defaults = { + size: [120, 25], + numberOfButtons: 4, + active: -1 + }; + + _get(Object.getPrototypeOf(RadioButton.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.buttons = []; + this._numberOfButtons = this.settings.numberOfButtons; + this.active = this.settings.active; + + this.init(); + this.render(); + } + + _inherits(RadioButton, _Interface); + + _createClass(RadioButton, { + buildFrame: { + value: function buildFrame() { + this.element = document.createElement("div"); + this.parent.appendChild(this.element); + } + }, + buildInterface: { + value: function buildInterface() { + + for (var i = 0; i < this._numberOfButtons; i++) { + var container = document.createElement("span"); + + var button = new Button(container, { + mode: "toggle", + component: true }, this.update.bind(this, i)); + + this.buttons.push(button); + this.element.appendChild(container); + } + } + }, + sizeInterface: { + value: function sizeInterface() { + + var buttonWidth = this.width / this._numberOfButtons; + var buttonHeight = this.height; + + for (var i = 0; i < this._numberOfButtons; i++) { + this.buttons[i].resize(buttonWidth, buttonHeight); + } + } + }, + colorInterface: { + value: function colorInterface() { + for (var i = 0; i < this._numberOfButtons; i++) { + this.buttons[i].colors = this.colors; + this.buttons[i].render(); + } + } + }, + update: { + value: function update(index) { + if (this.buttons[index].state) { + this.select(index); + } else { + this.deselect(); + } + // this.render(); + } + }, + render: { + value: function render() { + for (var i = 0; i < this.buttons.length; i++) { + if (i === this.active) { + this.buttons[i].turnOn(false); + } else { + this.buttons[i].turnOff(false); + } + } + } + }, + select: { + + /** + Select one button and deselect all other buttons. + @param index {number} The index of the button to select + */ + + value: function select(index) { + if (index >= 0 && index < this.buttons.length) { + this.active = index; + this.emit("change", this.active); + this.render(); + } + } + }, + deselect: { + + /** + Deselect all buttons. + */ + + value: function deselect() { + this.active = -1; + this.emit("change", this.active); + this.render(); + } + }, + numberOfButtons: { + get: function () { + return this._numberOfButtons; + }, + + /** + * Update how many buttons are in the interface + * @param {number} buttons How many buttons are in the interface + */ + set: function (buttons) { + this._numberOfButtons = buttons; + for (var i = 0; i < this.buttons.length; i++) { + this.buttons[i].destroy(); + } + this.buttons = []; + // for (let i=0;i<this.buttons.length;i++) { + // this.buttons[i].destroy(); + // } + this.empty(); + this.buildInterface(); + } + } + }); + + return RadioButton; + })(Interface); + + module.exports = RadioButton; + +/***/ }), +/* 20 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var Interface = __webpack_require__(6); + var Step = __webpack_require__(11); + var math = __webpack_require__(5); + + /** + * Number + * + * @description Number interface which is controllable by dragging or typing. + * + * @demo <span nexus-ui="number"></span> + * + * @example + * var number = new Nexus.Number('#target') + * + * @example + * var number = new Nexus.Number('#target',{ + * 'size': [60,30], + * 'value': 0, + * 'min': 0, + * 'max': 20000, + * 'step': 1 + * }) + * + * @output + * change + * Fires any time the interface's value changes. <br> + * The event data is the number value of the interface. + * + * @outputexample + * number.on('change',function(v) { + * console.log(v); + * }) + * + * + */ + + var Number = (function (_Interface) { + function Number() { + _classCallCheck(this, Number); + + var options = ["value"]; + + var defaults = { + size: [60, 30], + value: 0, + min: 0, + max: 20000, + step: 1 + }; + + _get(Object.getPrototypeOf(Number.prototype), "constructor", this).call(this, arguments, options, defaults); + + this._value = new Step(this.settings.min, this.settings.max, this.settings.step, this.settings.value); + + /* + Default: 2. How many decimal places to clip the number's visual rendering to. This does not affect number's actual value output -- for that, set the step property to .01, .1, or 1. + @type {number} + @example number.decimalPlaces = 2; + */ + this.decimalPlaces = 2; + this.actual = 0; + + this.max = this._value.max; + + this.min = this._value.min; + + this.step = this._value.step; + + this.init(); + this.render(); + } + + _inherits(Number, _Interface); + + _createClass(Number, { + buildFrame: { + value: function buildFrame() { + this.element = document.createElement("input"); + this.element.type = "text"; + + this.element.addEventListener("blur", (function () { + this.element.style.backgroundColor = this.colors.fill; + this.element.style.color = this.colors.dark; + if (this.element.value !== this.value) { + this.value = parseFloat(this.element.value); + this.render(); + } + }).bind(this)); + + this.element.addEventListener("keydown", (function (e) { + if (e.which < 48 || e.which > 57) { + if (e.which !== 189 && e.which !== 190 && e.which !== 8) { + e.preventDefault(); + } + } + if (e.which === 13) { + this.element.blur(); + this.value = this.element.value; + this.emit("change", this.value); + this.render(); + } + }).bind(this)); + + this.parent.appendChild(this.element); + } + }, + sizeInterface: { + value: function sizeInterface() { + + this._minDimension = Math.min(this.width, this.height); + + var styles = "width: " + this.width + "px;"; + styles += "height: " + this.height + "px;"; + styles += "background-color: #e7e7e7;"; + styles += "color: #333;"; + styles += "font-family: arial;"; + styles += "font-weight: 500;"; + styles += "font-size:" + this._minDimension / 2 + "px;"; + // styles += 'highlight: #d18;'; + styles += "border: none;"; + styles += "outline: none;"; + styles += "padding: " + this._minDimension / 4 + "px " + this._minDimension / 4 + "px;"; + styles += "box-sizing: border-box;"; + styles += "userSelect: text;"; + styles += "mozUserSelect: text;"; + styles += "webkitUserSelect: text;"; + this.element.style.cssText += styles; + + // to add eventually + // var css = '#'+this.elementID+'::selection{ background-color: transparent }'; + + this.element.value = this.value; + } + }, + colorInterface: { + value: function colorInterface() { + this.element.style.backgroundColor = this.colors.fill; + this.element.style.color = this.colors.dark; + } + }, + render: { + value: function render() { + + this.element.value = math.prune(this.value, this.decimalPlaces); + } + }, + click: { + value: function click() { + this.hasMoved = false; + this.element.readOnly = true; + this.actual = this.value; + this.initial = { y: this.mouse.y }; + this.changeFactor = math.invert(this.mouse.x / this.width); + console.log(this.changeFactor); + } + }, + move: { + value: function move() { + this.hasMoved = true; + if (this.clicked) { + + var newvalue = this.actual - (this.mouse.y - this.initial.y) * (math.clip(this.max - this.min, 0, 1000) / 200) * Math.pow(this.changeFactor, 2); + this.value = newvalue; + + this.render(); + if (this._value.changed) { + this.emit("change", this.value); + } + } + } + }, + release: { + value: function release() { + if (!this.hasMoved) { + this.element.readOnly = false; + this.element.focus(); + this.element.setSelectionRange(0, this.element.value.length); + this.element.style.backgroundColor = this.colors.accent; + this.element.style.color = this.colors.light; + } else { + document.body.focus(); + } + } + }, + link: { + + /** + Connect this number interface to a dial or slider + @param {Interface} element Element to connect to. + @example number.link(slider) + */ + + value: function link(destination) { + var _this = this; + + this.min = destination.min; + this.max = destination.max; + this.step = destination.step; + destination.on("change", function (v) { + _this.passiveUpdate(v); + }); + this.on("change", function (v) { + destination.value = v; + }); + this.value = destination.value; + /* return { + listener1: listener1, + listener2: listener2, + destroy: () => { + listener1.remove() (or similar) + listener2.remove() (or similar) + } + } */ + } + }, + passiveUpdate: { + value: function passiveUpdate(v) { + this._value.update(v); + this.render(); + } + }, + value: { + + /** + The interface's current value. If set manually, will update the interface and trigger the output event. + @type {number} + @example number.value = 10; + */ + + get: function () { + return this._value.value; + }, + set: function (v) { + this._value.update(v); + this.emit("change", this.value); + this.render(); + } + }, + min: { + + /** + Lower limit of the number's output range + @type {number} + @example number.min = 1000; + */ + + get: function () { + return this._value.min; + }, + set: function (v) { + this._value.min = v; + } + }, + max: { + + /** + Upper limit of the number's output range + @type {number} + @example number.max = 1000; + */ + + get: function () { + return this._value.max; + }, + set: function (v) { + this._value.max = v; + } + }, + step: { + + /** + The increment that the number's value changes by. + @type {number} + @example number.step = 5; + */ + + get: function () { + return this._value.step; + }, + set: function (v) { + this._value.step = v; + } + } + }); + + return Number; + })(Interface); + + module.exports = Number; + +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var Interface = __webpack_require__(6); + + /** + * Select + * + * @description Dropdown menu + * + * @demo <span nexus-ui="select"></span> + * + * @example + * var select = new Nexus.Select('#target') + * + * @example + * var select = new Nexus.Select('#target',{ + * 'size': [100,30], + * 'options': ['default','options'] + * }) + * + * @output + * change + * Fires any time the interface's value changes. <br> + * The event data is an object containing the text value of the selected option, as well as the numeric index of the selection. + * + * @outputexample + * select.on('change',function(v) { + * console.log(v); + * }) + * + * + */ + + var Select = (function (_Interface) { + function Select() { + _classCallCheck(this, Select); + + var options = ["value"]; + + var defaults = { + size: [100, 30], + options: ["default", "options"] + }; + + _get(Object.getPrototypeOf(Select.prototype), "constructor", this).call(this, arguments, options, defaults); + + this._selectedIndex = -1; + this._value = false; + + this._options = this.settings.options; + + this.init(); + this.render(); + } + + _inherits(Select, _Interface); + + _createClass(Select, { + buildFrame: { + value: function buildFrame() { + this.element = document.createElement("select"); + this.element.style.fontSize = this.height / 2 + "px"; + this.element.style.outline = "none"; + this.element.style.highlight = "none"; + this.element.style.width = this.width + "px"; + this.element.style.height = this.height + "px"; + + this.boundRender = this.render.bind(this); + + this.element.addEventListener("change", this.boundRender); + + this.parent.appendChild(this.element); + } + }, + attachListeners: { + value: function attachListeners() {} + }, + buildInterface: { + value: function buildInterface() { + + this.defineOptions(); + } + }, + colorInterface: { + value: function colorInterface() { + this.element.style.backgroundColor = this.colors.fill; + this.element.style.color = this.colors.dark; + this.element.style.border = "solid 0px " + this.colors.mediumLight; + } + }, + render: { + value: function render() { + + this._value = this.element.options[this.element.selectedIndex].text; + this._selectedIndex = this.element.selectedIndex; + this.emit("change", { + value: this._value, + index: this._selectedIndex + }); + } + }, + click: { + value: function click() {} + }, + move: { + value: function move() {} + }, + release: { + value: function release() {} + }, + defineOptions: { + + /** + * Update the list of options. This removes all existing options and creates a new list of options. + * @param {array} options New array of options + */ + + value: function defineOptions(options) { + + /* function removeOptions(selectbox) + { + var i; + for(i = selectbox.options.length - 1 ; i >= 0 ; i--) + { + selectbox.remove(i); + } + } + //using the function: + removeOptions(document.getElementById("mySelectObject")); */ + + if (options) { + this._options = options; + } + + for (var i = this.element.options.length - 1; i >= 0; i--) { + this.element.remove(i); + } + + for (var i = 0; i < this._options.length; i++) { + this.element.options.add(new Option(this._options[i], i)); + } + } + }, + value: { + + /** + The text of the option that is currently selected. If set, will update the interface and trigger the output event. + @type {String} + @example select.value = "sawtooth"; + */ + + get: function () { + return this._value; + }, + set: function (v) { + this._value = v; + for (var i = 0; i < this.element.options.length; i++) { + if (v === this.element.options[i].text) { + this.selectedIndex = i; + break; + } + } + } + }, + selectedIndex: { + + /** + The numeric index of the option that is currently selected. If set, will update the interface and trigger the output event. + @type {number} + @example select.selectedIndex = 2; + */ + + get: function () { + return this._selectedIndex; + }, + set: function (v) { + this._selectedIndex = v; + this.element.selectedIndex = v; + this.render(); + } + }, + customDestroy: { + value: function customDestroy() { + this.element.removeEventListener("change", this.boundRender); + } + } + }); + + return Select; + })(Interface); + + module.exports = Select; + +/***/ }), +/* 22 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var svg = __webpack_require__(4); + var math = __webpack_require__(5); + var Interface = __webpack_require__(6); + var Step = __webpack_require__(11); + + var Interaction = _interopRequireWildcard(__webpack_require__(12)); + + /** + * Dial + * + * + * @description Dial with radial or linear interaction. + * + * @demo <span nexus-ui="dial"></span> + * + * @example + * var dial = new Nexus.Dial('#target') + * + * @example + * var dial = new Nexus.Dial('#target',{ + * 'size': [75,75], + * 'interaction': 'radial', // "radial", "vertical", or "horizontal" + * 'mode': 'relative', // "absolute" or "relative" + * 'min': 0, + * 'max': 1, + * 'step': 0, + * 'value': 0 + * }) + * + * @output + * change + * Fires any time the interface's value changes. <br> + * The event data is the number value of the interface. + * + * @outputexample + * dial.on('change',function(v) { + * console.log(v); + * }) + * + * @tutorial + * Dial + * ygGMxq + * + */ + + var Dial = (function (_Interface) { + function Dial() { + _classCallCheck(this, Dial); + + var options = ["min", "max", "value"]; + + var defaults = { + size: [75, 75], + interaction: "radial", // radial, vertical, horizontal + mode: "relative", // absolute, relative + min: 0, + max: 1, + step: 0, + value: 0 + }; + + _get(Object.getPrototypeOf(Dial.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.interaction = this.settings.interaction; + + this._value = new Step(this.settings.min, this.settings.max, this.settings.step, this.settings.value); + + this.position = new Interaction.Handle(this.settings.mode, this.interaction, [0, this.width], [this.height, 0]); + + this.init(); + + this.value = this._value.value; + + this.position.value = this._value.normalized; + + this.previousAngle = false; + + this.emit("change", this.value); + } + + _inherits(Dial, _Interface); + + _createClass(Dial, { + buildInterface: { + value: function buildInterface() { + + this.background = svg.create("circle"); + this.screw = svg.create("circle"); + this.handle = svg.create("path"); + this.handle2 = svg.create("path"); + this.handleFill = svg.create("path"); + this.handle2Fill = svg.create("path"); + this.handleLine = svg.create("path"); + + this.element.appendChild(this.background); + this.element.appendChild(this.handle); + this.element.appendChild(this.handle2); + this.element.appendChild(this.handleFill); + this.element.appendChild(this.handle2Fill); + this.element.appendChild(this.handleLine); + this.element.appendChild(this.screw); + } + }, + sizeInterface: { + value: function sizeInterface() { + + this.position.resize([0, this.width], [this.height, 0]); + + var center = { + x: this.width / 2, + y: this.height / 2 + }; + + var diameter = Math.min(this.width, this.height); + + this.background.setAttribute("cx", center.x); + this.background.setAttribute("cy", center.y); + this.background.setAttribute("r", diameter / 2 - diameter / 40); + + this.screw.setAttribute("cx", center.x); + this.screw.setAttribute("cy", center.y); + this.screw.setAttribute("r", diameter / 12); + + var value = this.value; + + var handlePoints = { + start: Math.PI * 1.5, + end: math.clip(math.scale(value, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5) + }; + var handle2Points = { + start: Math.PI * 2.5, + end: math.clip(math.scale(value, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5) + }; + + var handlePath = svg.arc(center.x, center.y, diameter / 2 - diameter / 40, handlePoints.start, handlePoints.end); + var handle2Path = svg.arc(center.x, center.y, diameter / 2 - diameter / 40, handle2Points.start, handle2Points.end); + + this.handle.setAttribute("d", handlePath); + this.handle.setAttribute("stroke-width", diameter / 20); + this.handle.setAttribute("fill", "none"); + + this.handle2.setAttribute("d", handle2Path); + this.handle2.setAttribute("stroke-width", diameter / 20); + this.handle2.setAttribute("fill", "none"); + + handlePath += " L " + center.x + " " + center.y; + + this.handleFill.setAttribute("d", handlePath); + this.handleFill.setAttribute("fill-opacity", "0.3"); + + handle2Path += " L " + center.x + " " + center.y; + + this.handle2Fill.setAttribute("d", handle2Path); + this.handle2Fill.setAttribute("fill-opacity", "0.3"); + + var arcEndingA = undefined; + if (value < 0.5) { + arcEndingA = handlePoints.end; + } else { + arcEndingA = handle2Points.end; + } + + var arcEndingX = center.x + Math.cos(arcEndingA) * (diameter / 2); + var arcEndingY = center.y + Math.sin(arcEndingA) * (diameter / 2) * -1; + + this.handleLine.setAttribute("d", "M " + center.x + " " + center.y + " L " + arcEndingX + " " + arcEndingY); + this.handleLine.setAttribute("stroke-width", diameter / 20); + } + }, + colorInterface: { + value: function colorInterface() { + this.background.setAttribute("fill", this.colors.fill); + this.screw.setAttribute("fill", this.colors.accent); + this.handle.setAttribute("stroke", this.colors.accent); + this.handle2.setAttribute("stroke", this.colors.accent); + this.handleFill.setAttribute("fill", this.colors.accent); + this.handle2Fill.setAttribute("fill", this.colors.accent); + this.handleLine.setAttribute("stroke", this.colors.accent); + } + }, + render: { + value: function render() { + var value = this._value.normalized; + + var center = { + x: this.width / 2, + y: this.height / 2 + }; + + var diameter = Math.min(this.width, this.height); + + var handlePoints = { + start: Math.PI * 1.5, + end: math.clip(math.scale(value, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5) + }; + var handle2Points = { + start: Math.PI * 2.5, + end: math.clip(math.scale(value, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5) + }; + + var handlePath = svg.arc(center.x, center.y, diameter / 2 - diameter / 40, handlePoints.start, handlePoints.end); + var handle2Path = svg.arc(center.x, center.y, diameter / 2 - diameter / 40, handle2Points.start, handle2Points.end); + + this.handle.setAttribute("d", handlePath); + this.handle2.setAttribute("d", handle2Path); + + handlePath += " L " + center.x + " " + center.y; + + this.handleFill.setAttribute("d", handlePath); + + handle2Path += " L " + center.x + " " + center.y; + + this.handle2Fill.setAttribute("d", handle2Path); + + var arcEndingA = undefined; + if (value <= 0.5) { + arcEndingA = handlePoints.end; + } else { + arcEndingA = handle2Points.end; + } + + var arcEndingX = center.x + Math.cos(arcEndingA) * (diameter / 2); + var arcEndingY = center.y + Math.sin(arcEndingA) * (diameter / 2) * -1; + + this.handleLine.setAttribute("d", "M " + center.x + " " + center.y + " L " + arcEndingX + " " + arcEndingY); + } + }, + click: { + value: function click() { + if (this.mode === "relative") { + this.previousAngle = false; + } + this.position.anchor = this.mouse; + this.position.value = this._value.normalized; + this.move(); + } + }, + move: { + value: function move() { + if (this.clicked) { + + this.position.update(this.mouse); + + var angle = this.position.value * Math.PI * 2; + + if (angle < 0) { + angle += Math.PI * 2; + } + + if (this.mode === "relative") { + if (this.previousAngle !== false && Math.abs(this.previousAngle - angle) > 2) { + if (this.previousAngle > 3) { + angle = Math.PI * 2; + } else { + angle = 0; + } + } + } /* else { + if (this.previousAngle !== false && Math.abs(this.previousAngle - angle) > 2) { + if (this.previousAngle > 3) { + angle = Math.PI*2; + } else { + angle = 0; + } + } + } */ + this.previousAngle = angle; + + var realValue = angle / (Math.PI * 2); + + this.value = this._value.updateNormal(realValue); + + if (this.mode === "relative") { + this.position.value = realValue; + } + + this.emit("change", this._value.value); + + this.render(); + } + } + }, + release: { + value: function release() {} + }, + value: { + + /* + Dial's value. When set, it will automatically be adjust to fit min/max/step settings of the interface. + @type {number} + @example dial.value = 10; + get value() { + return this._value.value; + } + set value(value) { + this._value.update(value); + this.emit('change',this.value); + this.render(); + } + */ + + /** + Dial's value. When set, it will automatically be adjust to fit min/max/step settings of the interface. + @type {number} + @example dial.value = 10; + */ + + get: function () { + return this._value.value; + }, + set: function (v) { + this._value.update(v); + this.position.value = this._value.normalized; + this.emit("change", this._value.value); + this.render(); + } + }, + min: { + + /** + Lower limit of the dial's output range + @type {number} + @example dial.min = 1000; + */ + + get: function () { + return this._value.min; + }, + set: function (v) { + this._value.min = v; + } + }, + max: { + + /** + Upper limit of the dial's output range + @type {number} + @example dial.max = 1000; + */ + + get: function () { + return this._value.max; + }, + set: function (v) { + this._value.max = v; + } + }, + step: { + + /** + The increment that the dial's value changes by. + @type {number} + @example dial.step = 5; + */ + + get: function () { + return this._value.step; + }, + set: function (v) { + this._value.step = v; + } + }, + mode: { + + /** + Absolute mode (dial's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: "relative". + @type {string} + @example dial.mode = "relative"; + */ + + get: function () { + return this.position.mode; + }, + set: function (v) { + this.position.mode = v; + } + }, + normalized: { + + /** + Normalized value of the dial. + @type {number} + @example dial.normalized = 0.5; + */ + + get: function () { + return this._value.normalized; + }, + set: function (v) { + this._value.updateNormal(v); + this.emit("change", this.value); + } + } + }); + + return Dial; + })(Interface); + + module.exports = Dial; + +/***/ }), +/* 23 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var svg = __webpack_require__(4); + var Interface = __webpack_require__(6); + var ButtonTemplate = __webpack_require__(17); + var touch = __webpack_require__(9); + + var PianoKey = (function (_ButtonTemplate) { + function PianoKey() { + _classCallCheck(this, PianoKey); + + var options = ["value", "note", "color"]; + + var defaults = { + size: [80, 80], + target: false, + mode: "button", + value: 0 + }; + + _get(Object.getPrototypeOf(PianoKey.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.note = this.settings.note; + this.color = this.settings.color; + + this.colors = { + w: "#fff", + b: "#666" }; + + this.init(); + this.render(); + } + + _inherits(PianoKey, _ButtonTemplate); + + _createClass(PianoKey, { + buildFrame: { + value: function buildFrame() { + this.element = svg.create("svg"); + this.element.setAttribute("width", this.width); + this.element.setAttribute("height", this.height); + this.parent.appendChild(this.element); + } + }, + buildInterface: { + value: function buildInterface() { + var _this = this; + + this.pad = svg.create("rect"); + + this.element.appendChild(this.pad); + + this.interactionTarget = this.pad; + + /* events */ + + if (!touch.exists) { + + this.click = function () { + // console.log('click'); + _this.piano.interacting = true; + _this.piano.paintbrush = !_this.state; + _this.down(_this.piano.paintbrush); + }; + + this.pad.addEventListener("mouseover", function () { + if (_this.piano.interacting) { + // console.log('mouseover'); + _this.down(_this.piano.paintbrush); + } + }); + + this.move = function () { + if (_this.piano.interacting) { + // console.log('move'); + _this.bend(); + } + }; + + this.release = function () { + _this.piano.interacting = false; + // console.log('release'); + // this.up(); + }; + this.pad.addEventListener("mouseup", function () { + if (_this.piano.interacting) { + // console.log('mouseup'); + _this.up(); + } + }); + this.pad.addEventListener("mouseout", function () { + if (_this.piano.interacting) { + // console.log('mouseout'); + _this.up(); + } + }); + } + } + }, + sizeInterface: { + value: function sizeInterface() { + + //let radius = Math.min(this.width,this.height) / 5; + var radius = 0; + + this.pad.setAttribute("x", 0.5); + this.pad.setAttribute("y", 0.5); + if (this.width > 2) { + this.pad.setAttribute("width", this.width - 1); + } else { + this.pad.setAttribute("width", this.width); + } + if (this.height > 2) { + this.pad.setAttribute("height", this.height); + } else { + this.pad.setAttribute("height", this.height); + } + this.pad.setAttribute("rx", radius); + this.pad.setAttribute("ry", radius); + } + }, + render: { + value: function render() { + if (!this.state) { + this.pad.setAttribute("fill", this.colors[this.color]); + } else { + this.pad.setAttribute("fill", this.colors.accent); + } + } + } + }); + + return PianoKey; + })(ButtonTemplate); + + /** + * Piano + * + * @description Piano keyboard interface + * + * @demo <div nexus-ui="piano"></div> + * + * @example + * var piano = new Nexus.Piano('#target') + * + * @example + * var piano = new Nexus.Piano('#target',{ + * 'size': [500,125], + * 'mode': 'button', // 'button', 'toggle', or 'impulse' + * 'lowNote': 24, + * 'highNote': 60 + * }) + * + * @output + * change + * Fires any time a new key is pressed or released <br> + * The event data is an object containing <i>note</i> and <i>state</i> properties. + * + * @outputexample + * piano.on('change',function(v) { + * console.log(v); + * }) + * + */ + + var Piano = (function (_Interface) { + function Piano() { + _classCallCheck(this, Piano); + + var options = ["value"]; + + var defaults = { + size: [500, 125], + lowNote: 24, + highNote: 60, + mode: "button" + }; + + _get(Object.getPrototypeOf(Piano.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.keyPattern = ["w", "b", "w", "b", "w", "w", "b", "w", "b", "w", "b", "w"]; + + this.paintbrush = false; + + this.mode = this.settings.mode; + + this.range = { + low: this.settings.lowNote, + high: this.settings.highNote + }; + + this.range.size = this.range.high - this.range.low; + + this.keys = []; + + this.toggleTo = false; + + this.init(); + this.render(); + } + + _inherits(Piano, _Interface); + + _createClass(Piano, { + buildFrame: { + value: function buildFrame() { + this.element = document.createElement("div"); + this.element.style.position = "relative"; + this.element.style.borderRadius = "0px"; + this.element.style.display = "block"; + this.element.style.width = "100%"; + this.element.style.height = "100%"; + this.parent.appendChild(this.element); + } + }, + buildInterface: { + value: function buildInterface() { + + this.keys = []; + + for (var i = 0; i < this.range.high - this.range.low; i++) { + + var container = document.createElement("span"); + var scaleIndex = (i + this.range.low) % this.keyPattern.length; + + var key = new PianoKey(container, { + component: true, + note: i + this.range.low, + color: this.keyPattern[scaleIndex], + mode: this.mode + }, this.keyChange.bind(this, i + this.range.low)); + + key.piano = this; + + if (touch.exists) { + key.pad.index = i; + key.preClick = key.preMove = key.preRelease = function () {}; + key.click = key.move = key.release = function () {}; + key.preTouch = key.preTouchMove = key.preTouchRelease = function () {}; + key.touch = key.touchMove = key.touchRelease = function () {}; + } + + this.keys.push(key); + this.element.appendChild(container); + } + if (touch.exists) { + this.addTouchListeners(); + } + } + }, + sizeInterface: { + value: function sizeInterface() { + + var keyX = 0; + + var keyPositions = []; + + for (var i = 0; i < this.range.high - this.range.low; i++) { + + keyPositions.push(keyX); + + var scaleIndex = (i + this.range.low) % this.keyPattern.length; + var nextScaleIndex = (i + 1 + this.range.low) % this.keyPattern.length; + if (i + 1 + this.range.low >= this.range.high) { + keyX += 1; + } else if (this.keyPattern[scaleIndex] === "w" && this.keyPattern[nextScaleIndex] === "w") { + keyX += 1; + } else { + keyX += 0.5; + } + } + var keysWide = keyX; + + // let padding = this.width / 120; + var padding = 1; + var buttonWidth = (this.width - padding * 2) / keysWide; + var buttonHeight = (this.height - padding * 2) / 2; + + for (var i = 0; i < this.keys.length; i++) { + + var container = this.keys[i].parent; + container.style.position = "absolute"; + container.style.left = keyPositions[i] * buttonWidth + padding + "px"; + if (this.keys[i].color === "w") { + container.style.top = padding + "px"; + this.keys[i].resize(buttonWidth, buttonHeight * 2); + } else { + container.style.zIndex = 1; + container.style.top = padding + "px"; + this.keys[i].resize(buttonWidth, buttonHeight * 1.1); + } + } + } + }, + colorInterface: { + value: function colorInterface() { + + // Piano keys don't actually have a stroke border + // They have space between them, which shows the Piano bg color + this.element.style.backgroundColor = this.colors.mediumLight; + + for (var i = 0; i < this.keys.length; i++) { + this.keys[i].colors = { + w: this.colors.light, + b: this.colors.dark, + accent: this.colors.accent, + border: this.colors.mediumLight + }; + this.keys[i].colorInterface(); + this.keys[i].render(); + } + } + }, + keyChange: { + value: function keyChange(note, on) { + // emit data for any key turning on/off + // "note" is the note value + // "on" is a boolean whether it is on or off + // in aftertouch mode, "on: is an object with state/x/y properties + var data = { + note: note + }; + if (typeof on === "object") { + data.state = on.state; + // data.x = on.x + // data.y = on.y + } else { + data.state = on; + } + this.emit("change", data); + } + }, + render: { + + /* drag(note,on) { + this.emit('change',{ + note: note, + state: on + }); + } */ + + value: function render() {} + }, + addTouchListeners: { + value: function addTouchListeners() { + var _this = this; + + this.preClick = this.preMove = this.preRelease = function () {}; + this.click = this.move = this.release = function () {}; + this.preTouch = this.preTouchMove = this.preTouchRelease = function () {}; + this.touch = this.touchMove = this.touchRelease = function () {}; + + this.currentElement = false; + + this.element.addEventListener("touchstart", function (e) { + console.log("touchstart"); + var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY); + var key = _this.keys[element.index]; + _this.paintbrush = !key.state; + key.down(_this.paintbrush); + _this.currentElement = element.index; + e.preventDefault(); + e.stopPropagation(); + }); + + this.element.addEventListener("touchmove", function (e) { + var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY); + var key = _this.keys[element.index]; + if (element.index !== _this.currentElement) { + if (_this.currentElement) { + var pastKey = _this.keys[_this.currentElement]; + pastKey.up(); + } + key.down(_this.paintbrush); + } else { + key.bend(); + } + _this.currentElement = element.index; + e.preventDefault(); + e.stopPropagation(); + }); + + this.element.addEventListener("touchend", function (e) { + // no touches to calculate because none remaining + var key = _this.keys[_this.currentElement]; + key.up(); + _this.interacting = false; + _this.currentElement = false; + e.preventDefault(); + e.stopPropagation(); + }); + } + }, + setRange: { + + /** + Define the pitch range (lowest and highest note) of the piano keyboard. + @param low {number} MIDI note value of the lowest note on the keyboard + @param high {number} MIDI note value of the highest note on the keyboard + */ + + value: function setRange(low, high) { + this.range.low = low; + this.range.high = high; + this.empty(); + this.buildInterface(); + } + }, + toggleKey: { + + /** + Turn a key on or off using its MIDI note value; + @param note {number} MIDI note value of the key to change + @param on {boolean} Whether the note should turn on or off + */ + + value: function toggleKey(note, on) { + this.keys[note - this.range.low].flip(on); + } + }, + toggleIndex: { + + /** + Turn a key on or off using its key index on the piano interface. + @param index {number} Index of the key to change + @param on {boolean} Whether the note should turn on or off + */ + + value: function toggleIndex(index, on) { + this.keys[index].flip(on); + } + } + }); + + return Piano; + })(Interface); + + module.exports = Piano; + + // loop through and render the keys? + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var svg = __webpack_require__(4); + var dom = __webpack_require__(7); + var Interface = __webpack_require__(6); + var ButtonTemplate = __webpack_require__(17); + var MatrixModel = __webpack_require__(25); + var CounterModel = __webpack_require__(28); + var touch = __webpack_require__(9); + + var MatrixCell = (function (_ButtonTemplate) { + function MatrixCell() { + _classCallCheck(this, MatrixCell); + + var options = ["value"]; + + var defaults = { + size: [80, 80], + target: false, + mode: "toggle", + value: 0 + }; + + _get(Object.getPrototypeOf(MatrixCell.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.index = this.settings.index; + this.row = this.settings.row; + this.column = this.settings.column; + + this.matrix = this.settings.matrix; + + this.interacting = false; + this.paintbrush = false; + + this.init(); + this.render(); + } + + _inherits(MatrixCell, _ButtonTemplate); + + _createClass(MatrixCell, { + buildFrame: { + value: function buildFrame() { + this.element = svg.create("svg"); + this.element.setAttribute("width", this.width); + this.element.setAttribute("height", this.height); + this.element.style.top = "0px"; + this.element.style.left = "0px"; + this.element.style.position = "absolute"; + this.parent.appendChild(this.element); + } + }, + buildInterface: { + value: function buildInterface() { + var _this = this; + + this.pad = svg.create("rect"); + this.element.appendChild(this.pad); + + this.interactionTarget = this.pad; + + /* events */ + + if (!touch.exists) { + + this.click = function () { + _this.matrix.interacting = true; + _this.matrix.paintbrush = !_this.state; + _this.down(_this.matrix.paintbrush); + }; + this.pad.addEventListener("mouseover", function () { + if (_this.matrix.interacting) { + _this.down(_this.matrix.paintbrush); + } + }); + + this.move = function () {}; + this.pad.addEventListener("mousemove", function (e) { + if (_this.matrix.interacting) { + if (!_this.offset) { + _this.offset = dom.findPosition(_this.element); + } + _this.mouse = dom.locateMouse(e, _this.offset); + _this.bend(); + } + }); + + this.release = function () { + _this.matrix.interacting = false; + }; + this.pad.addEventListener("mouseup", function () { + if (_this.matrix.interacting) { + _this.up(); + } + }); + this.pad.addEventListener("mouseout", function () { + if (_this.matrix.interacting) { + _this.up(); + } + }); + } + } + }, + sizeInterface: { + value: function sizeInterface() { + + this.pad.setAttribute("x", 1); + this.pad.setAttribute("y", 1); + if (this.width > 2) { + this.pad.setAttribute("width", this.width - 2); + } else { + this.pad.setAttribute("width", this.width); + } + if (this.height > 2) { + this.pad.setAttribute("height", this.height - 2); + } else { + this.pad.setAttribute("height", this.height); + } + //this.pad.setAttribute('height', this.height - 2); + this.pad.setAttribute("fill", this.matrix.colors.fill); + } + }, + render: { + value: function render() { + if (!this.state) { + this.pad.setAttribute("fill", this.matrix.colors.fill); + } else { + this.pad.setAttribute("fill", this.matrix.colors.accent); + } + } + } + }); + + return MatrixCell; + })(ButtonTemplate); + + /** + * Sequencer + * + * @description Grid of buttons with built-in step sequencer. + * + * @demo <div nexus-ui="sequencer" style="width:400px;height:200px;"></div> + * + * @example + * var sequencer = new Nexus.Sequencer('#target') + * + * @example + * var sequencer = new Nexus.Sequencer('#target',{ + * 'size': [400,200], + * 'mode': 'toggle', + * 'rows': 5, + * 'columns': 10 + *}) + * + * @output + * change + * Fires any time the interface's matrix changes. <br> + * The event data is an object containing <i>row</i> (number), <i>column</i> (number), and <i>state</i> (boolean) properties. + * + * @outputexample + * sequencer.on('change',function(v) { + * console.log(v); + * }) + * + * @output + * step + * Fires any time the sequencer steps to the next column, in sequece mode. <br> + * The event data is an <i>array</i> containing all values in the column, <i>bottom row first</i>. + * + * @outputexample + * sequencer.on('step',function(v) { + * console.log(v); + * }) + */ + + var Sequencer = (function (_Interface) { + function Sequencer() { + _classCallCheck(this, Sequencer); + + var options = ["value"]; + + var defaults = { + size: [400, 200], + mode: "toggle", + rows: 5, + columns: 10 + }; + + _get(Object.getPrototypeOf(Sequencer.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.active = -1; + + /** + * Button interaction mode: see Button + * @type {string} + * @example button.mode = 'toggle'; + */ + this.mode = this.settings.mode; + + /** + * The interval object which controls timing and sequence scheduling. + * @type {interval} + */ + this.interval = new Nexus.Interval(200, function () {}, false); // jshint ignore:line + + /** + * A Matrix model containing methods for manipulating the sequencer's array of values. To learn how to manipulate the matrix, read about the matrix model. + * @type {matrix} + */ + this.matrix = new MatrixModel(this.settings.rows, this.settings.columns); + this.matrix.ui = this; + + /** + * A Counter model which the sequencer steps through. For example, you could use this model to step through the sequencer in reverse, randomly, or in a drunk walk. + * @type {counter} + */ + this.stepper = new CounterModel(0, this.columns); + + this.init(); + } + + _inherits(Sequencer, _Interface); + + _createClass(Sequencer, { + buildFrame: { + value: function buildFrame() { + this.element = document.createElement("div"); + this.element.style.position = "relative"; + this.element.style.display = "block"; + this.element.style.width = "100%"; + this.element.style.height = "100%"; + this.parent.appendChild(this.element); + if (touch.exists) { + this.addTouchListeners(); + } + } + }, + buildInterface: { + value: function buildInterface() { + + this.cells = []; + for (var i = 0; i < this.matrix.length; i++) { + + var _location = this.matrix.locate(i); + // returns {row,col} + + var container = document.createElement("span"); + container.style.position = "absolute"; + + var cell = new MatrixCell(container, { + component: true, + index: i, + row: _location.row, + column: _location.column, + mode: this.mode, + matrix: this + }, this.keyChange.bind(this, i)); + + // cell.matrix = this; + if (touch.exists) { + cell.pad.index = i; + cell.preClick = cell.preMove = cell.preRelease = function () {}; + cell.click = cell.move = cell.release = function () {}; + cell.preTouch = cell.preTouchMove = cell.preTouchRelease = function () {}; + cell.touch = cell.touchMove = cell.touchRelease = function () {}; + } + + this.cells.push(cell); + this.element.appendChild(container); + } + this.sizeInterface(); + } + }, + sizeInterface: { + value: function sizeInterface() { + + var cellWidth = this.width / this.columns; + var cellHeight = this.height / this.rows; + + for (var i = 0; i < this.cells.length; i++) { + var container = this.cells[i].parent; + container.style.left = this.cells[i].column * cellWidth + "px"; + container.style.top = this.cells[i].row * cellHeight + "px"; + this.cells[i].resize(cellWidth, cellHeight); + } + } + }, + colorInterface: { + value: function colorInterface() { + for (var i = 0; i < this.cells.length; i++) { + this.cells[i].render(); + } + } + }, + update: { + value: function update() { + var _this = this; + + // console.log("updating...") + //on = on || false; + this.matrix.iterate(function (r, c, i) { + // console.log(this.matrix.pattern[r][c], this.cells[i].state); + if (_this.matrix.pattern[r][c] !== _this.cells[i].state) { + if (_this.matrix.pattern[r][c] > 0) { + _this.cells[i].turnOn(); + } else { + _this.cells[i].turnOff(); + } + } + }); + } + }, + keyChange: { + + // update => cell.turnOn => cell.emit => keyChange (seq.emit) => matrix.set.cell => update + // + // interaction => keyChange => matrix.set.cell => update => cell.turnOn + // => emit + // + // set.cell => update => needs to emit. + + value: function keyChange(note, on) { + // emit data for any key turning on/off + // i is the note index + // v is whether it is on or off + var cell = this.matrix.locate(note); + // this.matrix.set.cell(cell.column,cell.row,on); + this.matrix.pattern[cell.row][cell.column] = on; + var data = { + row: cell.row, + column: cell.column, + state: on + }; + this.emit("change", data); + } + }, + render: { + value: function render() { + var _this = this; + + if (this.stepper.value >= 0) { + this.matrix.iterate(function (r, c, i) { + if (c === _this.stepper.value) { + _this.cells[i].pad.setAttribute("stroke", _this.colors.mediumLight); + _this.cells[i].pad.setAttribute("stroke-width", "1"); + _this.cells[i].pad.setAttribute("stroke-opacity", "1"); + } else { + _this.cells[i].pad.setAttribute("stroke", "none"); + } + }); + } + } + }, + start: { + + /** + * Start sequencing + * @param {number} ms Beat tempo in milliseconds + */ + + value: function start(ms) { + this.interval.event = this.next.bind(this); + if (ms) { + this.interval.ms(ms); + } + this.interval.start(); + } + }, + stop: { + + /** + Stop sequencing + */ + + value: function stop() { + this.interval.stop(); + } + }, + next: { + + /** + Manually jump to the next column and trigger the 'change' event. The "next" column is determined by your mode of sequencing. + */ + + value: function next() { + this.stepper.next(); + this.emit("step", this.matrix.column(this.stepper.value).reverse()); + this.render(); + } + }, + addTouchListeners: { + value: function addTouchListeners() { + var _this = this; + + this.preClick = this.preMove = this.preRelease = function () {}; + this.click = this.move = this.release = function () {}; + this.preTouch = this.preTouchMove = this.preTouchRelease = function () {}; + this.touch = this.touchMove = this.touchRelease = function () {}; + + this.currentElement = false; + + this.element.addEventListener("touchstart", function (e) { + var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY); + var cell = _this.cells[element.index]; + _this.paintbrush = !cell.state; + cell.down(_this.paintbrush); + _this.currentElement = element.index; + e.preventDefault(); + e.stopPropagation(); + }); + + this.element.addEventListener("touchmove", function (e) { + var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY); + var cell = _this.cells[element.index]; + if (element.index !== _this.currentElement) { + if (_this.currentElement >= 0) { + var pastCell = _this.cells[_this.currentElement]; + pastCell.up(); + } + cell.down(_this.paintbrush); + } else { + cell.bend(); + } + _this.currentElement = element.index; + e.preventDefault(); + e.stopPropagation(); + }); + + this.element.addEventListener("touchend", function (e) { + // no touches to calculate because none remaining + var cell = _this.cells[_this.currentElement]; + cell.up(); + _this.interacting = false; + _this.currentElement = false; + e.preventDefault(); + e.stopPropagation(); + }); + } + }, + rows: { + + /** + Number of rows in the sequencer + @type {number} + */ + + get: function () { + return this.matrix.rows; + }, + set: function (v) { + this.matrix.rows = v; + this.empty(); + this.buildInterface(); + this.update(); + } + }, + columns: { + + /** + Number of columns in the sequencer + @type {number} + */ + + get: function () { + return this.matrix.columns; + }, + set: function (v) { + this.matrix.columns = v; + this.stepper.max = v; + this.empty(); + this.buildInterface(); + this.update(); + } + } + }); + + return Sequencer; + })(Interface); + + module.exports = Sequencer; + +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var math = _interopRequire(__webpack_require__(5)); + + var Sequence = _interopRequire(__webpack_require__(26)); + + // For the tutorial, looking at + + //Pattern section: + // .create(), .rows, .columns, + // .pattern, .length, .formatAsText(), .log(), + // .locate(i), .indexOf(c,r) + // row(), column() (returns contents of row or colum) + + //Control section: + // toggle x3 + // set x4 + // rotate x3 + // populate x3 + // erase x3 + + // should some version of this have a float value for each cell? + // could be like a mirror .pattern that has values. by default, everything is 1, but could be set... + // not a good way to do that on interface, but as a model it would be nice... + // for .formatAsText(), could multiply by 100 and floor, so each cell is an int from 0 to 9 + + var Matrix = (function () { + function Matrix(rows, columns) { + var _this = this; + + _classCallCheck(this, Matrix); + + // should also have ability to create using an existing matrix (2d array) + this.pattern = []; + this.create(rows, columns); + + this.toggle = { + cell: function (column, row) { + _this.pattern[row][column] = !_this.pattern[row][column]; // math.invert(this.pattern[row][column]); + if (_this.ui) { + _this.ui.update(); + } + return _this.pattern[row][column]; + }, + all: function () { + _this.iterate(function (r, c) { + _this.toggle.cell(c, r); + }); + if (_this.ui) { + _this.ui.update(); + } + }, + row: function (row) { + for (var i = 0; i < _this.columns; i++) { + _this.toggle.cell(i, row); + } + if (_this.ui) { + _this.ui.update(); + } + }, + column: function (column) { + for (var i = 0; i < _this.rows; i++) { + _this.toggle.cell(column, i); + } + if (_this.ui) { + _this.ui.update(); + } + } + }; + + this.set = { + cell: function (column, row, value) { + _this.pattern[row][column] = value; + if (_this.ui) { + _this.ui.update(); + } + }, + all: function (values) { + // set the whole matrix using a 2d array as input + // this should also resize the array? + _this.pattern = values; + if (_this.ui) { + _this.ui.update(); + } + }, + row: function (row, values) { + // set a row using an array as input + _this.pattern[row] = values; + if (_this.ui) { + _this.ui.update(); + } + }, + column: function (column, values) { + // set a column using an array as input + _this.pattern.forEach(function (row, i) { + _this.pattern[i][column] = values[i]; + }); + if (_this.ui) { + _this.ui.update(); + } + } + }; + + this.rotate = { + //should eventually do (amountX, amountY) here + // could just use a loop and this.rotate.row(i,amountX); + all: function (amount) { + if (!amount && amount !== 0) { + amount = 1; + } + amount %= _this.pattern[0].length; + if (amount < 0) { + amount = _this.pattern[0].length + amount; + } + for (var i = 0; i < _this.rows; i++) { + var cut = _this.pattern[i].splice(_this.pattern[i].length - amount, amount); + _this.pattern[i] = cut.concat(_this.pattern[i]); + } + if (_this.ui) { + _this.ui.update(); + } + }, + row: function (row, amount) { + if (!amount && amount !== 0) { + amount = 1; + } + amount %= _this.pattern[0].length; + if (amount < 0) { + amount = _this.pattern[0].length + amount; + } + var cut = _this.pattern[row].splice(_this.pattern[row].length - amount, amount); + _this.pattern[row] = cut.concat(_this.pattern[row]); + if (_this.ui) { + _this.ui.update(); + } + }, + column: function (column, amount) { + if (!amount && amount !== 0) { + amount = 1; + } + amount %= _this.pattern.length; + if (amount < 0) { + amount = _this.pattern.length + amount; + } + var proxy = []; + _this.pattern.forEach(function (row) { + proxy.push(row[column]); + }); + var cut = proxy.splice(proxy.length - amount, amount); + proxy = cut.concat(proxy); + _this.pattern.forEach(function (row, i) { + row[column] = proxy[i]; + }); + if (_this.ui) { + _this.ui.update(); + } + } + }; + + // the idea behind populate is to be able to set a whole row or column to 0 or 1 + // IF the value is a float, such as 0.7, then it would become a probability + // so populate(0.7) would give each cell a 70% chance of being 1 + this.populate = { + all: function (odds) { + var oddsSequence = new Sequence(odds); + _this.iterate(function (r, c) { + _this.pattern[r][c] = math.coin(oddsSequence.next()); + }); + // This could be used so that each row has same odds pattern, even if row length is not divisibly by sequence length. + //,() => { + // odds.pos = -1; + // } + if (_this.ui) { + _this.ui.update(); + } + }, + row: function () { + var row = arguments[0] === undefined ? 0 : arguments[0]; + var odds = arguments[1] === undefined ? 1 : arguments[1]; + + var oddsSequence = new Sequence(odds); + _this.pattern[row].forEach(function (cell, i) { + _this.pattern[row][i] = math.coin(oddsSequence.next()); + }); + if (_this.ui) { + _this.ui.update(); + } + }, + column: function () { + var column = arguments[0] === undefined ? 0 : arguments[0]; + var odds = arguments[1] === undefined ? 1 : arguments[1]; + + var oddsSequence = new Sequence(odds); + _this.pattern.forEach(function (row, i) { + _this.pattern[i][column] = math.coin(oddsSequence.next()); + }); + if (_this.ui) { + _this.ui.update(); + } + } + }; + + // essentiall populate(0) so i'm not sure if this is necessary but is nice + this.erase = { + all: function () { + _this.set.all(0); + }, + row: function (row) { + _this.set.row(row, 0); + }, + column: function (column) { + _this.set.column(column, 0); + } + }; + + // end constructor + } + + _createClass(Matrix, { + create: { + value: function create(rows, columns) { + var _this = this; + + this.pattern = []; + for (var row = 0; row < rows; row++) { + var arr = new Array(columns); + this.pattern.push(arr); + } + this.iterate(function (r, c) { + _this.pattern[r][c] = false; + }); + } + }, + iterate: { + value: function iterate(f, f2) { + var i = 0; + for (var row = 0; row < this.rows; row++) { + if (f2) { + f2(row); + } + for (var column = 0; column < this.columns; column++) { + f(row, column, i); + i++; + } + } + } + }, + formatAsText: { + value: function formatAsText() { + var _this = this; + + var patternString = ""; + this.iterate(function (r, c) { + patternString += (_this.pattern[r][c] ? 1 : 0) + " "; + }, function () { + patternString += "\n"; + }); + return patternString; + } + }, + log: { + value: function log() { + console.log(this.formatAsText()); + } + }, + update: { + value: function update(pattern) { + this.pattern = pattern || this.pattern; + } + }, + length: { + get: function () { + return this.rows * this.columns; + } + }, + locate: { + value: function locate(index) { + // returns row and column of cell by index + return { + row: ~ ~(index / this.columns), + column: index % this.columns + }; + } + }, + indexOf: { + value: function indexOf(row, column) { + return column + row * this.columns; + // returns index of cell by row and column + } + }, + row: { + value: (function (_row) { + var _rowWrapper = function row(_x) { + return _row.apply(this, arguments); + }; + + _rowWrapper.toString = function () { + return _row.toString(); + }; + + return _rowWrapper; + })(function (row) { + var data = []; + for (var i = 0; i < this.columns; i++) { + data.push(this.pattern[row] ? 1 : 0); + } + return data; + }) + }, + column: { + value: (function (_column) { + var _columnWrapper = function column(_x2) { + return _column.apply(this, arguments); + }; + + _columnWrapper.toString = function () { + return _column.toString(); + }; + + return _columnWrapper; + })(function (column) { + var data = []; + for (var i = 0; i < this.rows; i++) { + data.push(this.pattern[i][column] ? 1 : 0); + } + return data; + }) + }, + rows: { + get: function () { + return this.pattern.length; + }, + set: function (v) { + var _this = this; + + var previous = this.pattern.slice(0); + this.create(v, this.columns); + this.iterate(function (r, c) { + if (previous[r] && previous[r][c]) { + _this.pattern[r][c] = previous[r][c]; + } + }); + } + }, + columns: { + get: function () { + return this.pattern[0].length; + }, + set: function (v) { + var _this = this; + + var previous = this.pattern.slice(0); + this.create(this.rows, v); + this.iterate(function (r, c) { + if (previous[r] && previous[r][c]) { + _this.pattern[r][c] = previous[r][c]; + } + }); + } + } + }); + + return Matrix; + })(); + + module.exports = Matrix; + +/***/ }), +/* 26 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var math = _interopRequire(__webpack_require__(5)); + + var Drunk = _interopRequire(__webpack_require__(27)); + + var Sequence = (function () { + function Sequence() { + var sequence = arguments[0] === undefined ? [0, 10, 20, 30] : arguments[0]; + var mode = arguments[1] === undefined ? "up" : arguments[1]; + var position = arguments[2] === undefined ? false : arguments[2]; + + _classCallCheck(this, Sequence); + + this.values = sequence; + if (!Array.isArray(this.values)) { + this.values = [this.values]; + } + this._mode = mode; + this.position = position; + + this.drunkWalk = new Drunk(0, this.values.length - 1); + + this.startValues = { + up: 0, + down: this.values.length - 1, + drunk: ~ ~(this.values.length / 2), + random: math.ri(this.values.length) + }; + + if (this.position !== false) { + this.next = this[this._mode]; + } else { + this.next = this.first; + } + } + + _createClass(Sequence, { + mode: { + get: function () { + return this._mode; + }, + set: function (mode) { + if (!(mode === "up" || mode === "down" || mode === "random" || mode === "drunk")) { + console.error("The only modes currently allowed are: up, down, random, drunk"); + return; + } + this._mode = mode; + if (this.position) { + this.next = this[this._mode]; + } + } + }, + value: { + get: function () { + return this.values[this.position]; + }, + set: function (v) { + this.position = this.values.indexOf(v); + } + }, + first: { + value: function first() { + if (this.position !== false) { + this.next = this[this._mode]; + return this.next(); + } + this.position = this.startValues[this._mode]; + this.next = this[this._mode]; + return this.value; + } + }, + up: { + value: function up() { + this.position++; + this.position %= this.values.length; + return this.value; + } + }, + down: { + value: function down() { + this.position--; + if (this.position < 0) { + this.position = (this.position + this.values.length) % this.values.length; + } + return this.value; + } + }, + random: { + value: function random() { + this.position = math.ri(0, this.values.length); + return this.value; + } + }, + drunk: { + value: function drunk() { + this.drunkWalk.max = this.values.length; + this.drunkWalk.value = this.position; + this.position = this.drunkWalk.next(); + return this.value; + } + + /* future methods
+ .group(start,stop) -- outputs a group of n items from the list, with wrapping
+ .loop(start,stop) -- confines sequencing to a subset of the values
+ (could even have a distinction between .originalValues and the array of values being used)
+ */ + + } + }); + + return Sequence; + })(); + + module.exports = Sequence; + +/***/ }), +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var math = _interopRequire(__webpack_require__(5)); + + var Drunk = (function () { + function Drunk() { + var min = arguments[0] === undefined ? 0 : arguments[0]; + var max = arguments[1] === undefined ? 9 : arguments[1]; + var value = arguments[2] === undefined ? 0 : arguments[2]; + var increment = arguments[3] === undefined ? 1 : arguments[3]; + var loop = arguments[4] === undefined ? false : arguments[4]; + + _classCallCheck(this, Drunk); + + this.min = min; + this.max = max; + this.value = value; + this.increment = increment; + this.loop = loop; + } + + _createClass(Drunk, { + next: { + value: function next() { + this.value += math.pick(-1 * this.increment, this.increment); + if (this.value > this.max) { + if (this.loop) { + this.value = this.min; + } else { + this.value = this.max - this.increment; + } + } + + if (this.value < this.min) { + if (this.loop) { + this.value = this.max; + } else { + this.value = this.min + this.increment; + } + } + return this.value; + } + } + }); + + return Drunk; + })(); + + module.exports = Drunk; + +/***/ }), +/* 28 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var math = _interopRequire(__webpack_require__(5)); + + var Drunk = _interopRequire(__webpack_require__(27)); + + var Counter = (function () { + function Counter() { + var min = arguments[0] === undefined ? 0 : arguments[0]; + var max = arguments[1] === undefined ? 10 : arguments[1]; + var mode = arguments[2] === undefined ? "up" : arguments[2]; + var value = arguments[3] === undefined ? false : arguments[3]; + + _classCallCheck(this, Counter); + + this.min = min; + this.max = max; + this.value = value; + this.mode = mode; + this.drunkWalk = new Drunk(this.min, this.max); + if (this.value !== false) { + this.next = this[this._mode]; + } else { + this.next = this.first; + } + } + + _createClass(Counter, { + mode: { + set: function (mode) { + if (!(mode === "up" || mode === "down" || mode === "random" || mode === "drunk")) { + console.error("The only modes currently allowed are: up, down, random, drunk"); + return; + } + this._mode = mode; + if (this.value) { + this.next = this[this._mode]; + } + }, + get: function () { + return this._mode; + } + }, + first: { + value: function first() { + if (this.value !== false) { + this.next = this[this._mode]; + return this.next(); + } + this.startValues = { + up: this.min, + down: this.max, + drunk: ~ ~math.average(this.min, this.max), + random: math.ri(this.min, this.max) + }; + this.value = this.startValues[this._mode]; + this.next = this[this._mode]; + return this.value; + } + }, + up: { + value: function up() { + this.value++; + if (this.value >= this.max) { + this.value = this.min; + } + return this.value; + } + }, + down: { + value: function down() { + this.value--; + if (this.value < this.min) { + this.value = this.max; + } + return this.value; + } + }, + random: { + value: function random() { + this.value = math.ri(this.min, this.max); + return this.value; + } + }, + drunk: { + value: function drunk() { + this.drunkWalk.min = this.min; + this.drunkWalk.max = this.max; + this.drunkWalk.value = this.value; + this.value = this.drunkWalk.next(); + return this.value; + } + } + }); + + return Counter; + })(); + + module.exports = Counter; + +/***/ }), +/* 29 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var svg = __webpack_require__(4); + var math = __webpack_require__(5); + var Interface = __webpack_require__(6); + var Step = __webpack_require__(11); + + var Interaction = _interopRequireWildcard(__webpack_require__(12)); + + /** + * Pan2D + * + * @description Interface for moving a sound around an array of speakers. Speaker locations can be customized. The interface calculates the closeness of the sound source to each speaker and returns that distance as a numeric value. + * + * @demo <span nexus-ui="pan2D"></span> + * + * @example + * var pan2d = new Nexus.Pan2d('#target') + * + * @example + * var pan2d = new Nexus.Pan2D('#target',{ + * 'size': [200,200], + * 'range': 0.5, // detection radius of each speaker + * 'mode': 'absolute', // 'absolute' or 'relative' sound movement + * 'speakers': [ // the speaker [x,y] positions + * [0.5,0.2], + * [0.75,0.25], + * [0.8,0.5], + * [0.75,0.75], + * [0.5,0.8], + * [0.25,0.75] + * [0.2,0.5], + * [0.25,0.25] + * ] + * }) + * + * @output + * change + * Fires any time the "source" node's position changes. <br> + * The event data is an array of the amplitudes (0-1), representing the level of each speaker (as calculated by its distance to the audio source). + * + * @outputexample + * pan2d.on('change',function(v) { + * console.log(v); + * }) + * + */ + + var Pan2D = (function (_Interface) { + function Pan2D() { + _classCallCheck(this, Pan2D); + + var options = ["range"]; + + var defaults = { + size: [200, 200], + range: 0.5, + mode: "absolute", + speakers: [[0.5, 0.2], [0.75, 0.25], [0.8, 0.5], [0.75, 0.75], [0.5, 0.8], [0.25, 0.75], [0.2, 0.5], [0.25, 0.25]] + }; + + _get(Object.getPrototypeOf(Pan2D.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.value = { + x: new Step(0, 1, 0, 0.5), + y: new Step(0, 1, 0, 0.5) + }; + + /** + Absolute or relative mouse interaction. In "absolute" mode, the source node will jump to your mouse position on mouse click. In "relative" mode, it does not. + */ + this.mode = this.settings.mode; + + this.position = { + x: new Interaction.Handle(this.mode, "horizontal", [0, this.width], [this.height, 0]), + y: new Interaction.Handle(this.mode, "vertical", [0, this.width], [this.height, 0]) + }; + this.position.x.value = this.value.x.normalized; + this.position.y.value = this.value.y.normalized; + + /** + An array of speaker locations. Update this with .moveSpeaker() or .moveAllSpeakers() + */ + this.speakers = this.settings.speakers; + + /** + Rewrite: The maximum distance from a speaker that the source node can be for it to be heard from that speaker. A low range (0.1) will result in speakers only playing when the sound is very close it. Default is 0.5 (half of the interface). + */ + this.range = this.settings.range; + + /** + The current levels for each speaker. This is calculated when a source node or speaker node is moved through interaction or programatically. + */ + this.levels = []; + + this.init(); + + this.calculateLevels(); + this.render(); + } + + _inherits(Pan2D, _Interface); + + _createClass(Pan2D, { + buildInterface: { + value: function buildInterface() { + + this.knob = svg.create("circle"); + + this.element.appendChild(this.knob); + + // add speakers + this.speakerElements = []; + + for (var i = 0; i < this.speakers.length; i++) { + var speakerElement = svg.create("circle"); + + this.element.appendChild(speakerElement); + + this.speakerElements.push(speakerElement); + } + } + }, + sizeInterface: { + value: function sizeInterface() { + + this._minDimension = Math.min(this.width, this.height); + + this.knobRadius = { + off: ~ ~(this._minDimension / 100) * 3 + 5 }; + this.knobRadius.on = this.knobRadius.off * 2; + + this.knob.setAttribute("cx", this.width / 2); + this.knob.setAttribute("cy", this.height / 2); + this.knob.setAttribute("r", this.knobRadius.off); + + for (var i = 0; i < this.speakers.length; i++) { + var speakerElement = this.speakerElements[i]; + var speaker = this.speakers[i]; + speakerElement.setAttribute("cx", speaker[0] * this.width); + speakerElement.setAttribute("cy", speaker[1] * this.height); + speakerElement.setAttribute("r", this._minDimension / 20 + 5); + speakerElement.setAttribute("fill-opacity", "0"); + } + + this.position.x.resize([0, this.width], [this.height, 0]); + this.position.y.resize([0, this.width], [this.height, 0]); + + // next, need to + // resize positions + // calculate speaker distances + this.calculateLevels(); + this.render(); + } + }, + colorInterface: { + value: function colorInterface() { + + this.element.style.backgroundColor = this.colors.fill; + this.knob.setAttribute("fill", this.colors.mediumLight); + + for (var i = 0; i < this.speakers.length; i++) { + var speakerElement = this.speakerElements[i]; + speakerElement.setAttribute("fill", this.colors.accent); + speakerElement.setAttribute("stroke", this.colors.accent); + } + } + }, + render: { + value: function render() { + this.knobCoordinates = { + x: this.value.x.normalized * this.width, + y: this.height - this.value.y.normalized * this.height + }; + + this.knob.setAttribute("cx", this.knobCoordinates.x); + this.knob.setAttribute("cy", this.knobCoordinates.y); + } + }, + click: { + value: function click() { + this.position.x.anchor = this.mouse; + this.position.y.anchor = this.mouse; + this.move(); + } + }, + move: { + value: function move() { + if (this.clicked) { + this.position.x.update(this.mouse); + this.position.y.update(this.mouse); + // position.x and position.y are normalized + // so are the levels + // likely don't need this.value at all -- only used for drawing + // not going to be a 'step' or 'min' and 'max' in this one. + this.calculateLevels(); + this.emit("change", this.levels); + this.render(); + } + } + }, + release: { + value: function release() { + this.render(); + } + }, + normalized: { + get: function () { + return { + x: this.value.x.normalized, + y: this.value.y.normalized + }; + } + }, + calculateLevels: { + value: function calculateLevels() { + var _this = this; + + this.value.x.updateNormal(this.position.x.value); + this.value.y.updateNormal(this.position.y.value); + this.levels = []; + this.speakers.forEach(function (s, i) { + var distance = math.distance(s[0] * _this.width, s[1] * _this.height, _this.position.x.value * _this.width, (1 - _this.position.y.value) * _this.height); + var level = math.clip(1 - distance / (_this.range * _this.width), 0, 1); + _this.levels.push(level); + _this.speakerElements[i].setAttribute("fill-opacity", level); + }); + } + }, + moveSource: { + + /** + Move the audio source node and trigger the output event. + @param x {number} New x location, normalized 0-1 + @param y {number} New y location, normalized 0-1 + */ + + value: function moveSource(x, y) { + var location = { + x: x * this.width, + y: y * this.height + }; + this.position.x.update(location); + this.position.y.update(location); + this.calculateLevels(); + this.emit("change", this.levels); + this.render(); + } + }, + moveSpeaker: { + + /** + Move a speaker node and trigger the output event. + @param index {number} Index of the speaker to move + @param x {number} New x location, normalized 0-1 + @param y {number} New y location, normalized 0-1 + */ + + value: function moveSpeaker(index, x, y) { + + this.speakers[index] = [x, y]; + this.speakerElements[index].setAttribute("cx", x * this.width); + this.speakerElements[index].setAttribute("cy", y * this.height); + this.calculateLevels(); + this.emit("change", this.levels); + this.render(); + } + + /** + Set all speaker locations + @param locations {Array} Array of speaker locations. Each item in the array should be an array of normalized x and y coordinates. + setSpeakers(locations) { + } + */ + + } + }); + + return Pan2D; + })(Interface); + + module.exports = Pan2D; + +/***/ }), +/* 30 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var math = __webpack_require__(5); + var svg = __webpack_require__(4); + var Interface = __webpack_require__(6); + + /** + * Tilt + * + * @description Device tilt sensor with 2 or 3 axes (depending on your device and browser). + * + * @demo <span nexus-ui='tilt'></span> + * + * @example + * var tilt = new Nexus.Tilt('#target') + * + * @output + * change + * Fires at a regular interval, as long as this interface is active (see the interface's <i>.active</i> property)<br> + * The event data is an <i>object</i> containing x (number) and y (number) properties which represent the current tilt state of the device. + * + * @outputexample + * tilt.on('change',function(v) { + * console.log(v); + * }) + * + * + */ + + var Tilt = (function (_Interface) { + function Tilt() { + _classCallCheck(this, Tilt); + + var options = ["value"]; + + var defaults = { + size: [80, 80] + }; + + _get(Object.getPrototypeOf(Tilt.prototype), "constructor", this).call(this, arguments, options, defaults); + + this._active = true; + + this.init(); + + // add event listener for device orientation + + this.boundUpdate = this.update.bind(this); + // this.boundMozTilt = this.mozTilt.bind(this) + + if (window.DeviceOrientationEvent) { + this.orientationListener = window.addEventListener("deviceorientation", this.boundUpdate, false); + } else { + this._active = false; + this.colorInterface(); + } + + /*else if (window.OrientationEvent) { + // window.addEventListener('MozOrientation', this.boundMozTilt, false); + } else { + console.log('Not supported on your device or browser.'); + } */ + } + + _inherits(Tilt, _Interface); + + _createClass(Tilt, { + buildInterface: { + value: function buildInterface() { + + this.title = svg.create("text"); + this.circleX = svg.create("circle"); + this.circleY = svg.create("circle"); + this.circleZ = svg.create("circle"); + + this.barX = svg.create("path"); + this.barY = svg.create("path"); + this.barZ = svg.create("path"); + + this.barX2 = svg.create("path"); + this.barY2 = svg.create("path"); + this.barZ2 = svg.create("path"); + + this.barX.setAttribute("opacity", "0.8"); + this.barY.setAttribute("opacity", "0.8"); + this.barZ.setAttribute("opacity", "0.8"); + this.barX2.setAttribute("opacity", "0.8"); + this.barY2.setAttribute("opacity", "0.8"); + this.barZ2.setAttribute("opacity", "0.8"); + + this.circleX.setAttribute("cx", this.width * 3 / 12); + this.circleX.setAttribute("cy", this.height * 3 / 4); + this.circleX.setAttribute("r", this.height / 10); + this.circleX.setAttribute("opacity", "0.4"); + + this.circleY.setAttribute("cx", this.width * 6 / 12); + this.circleY.setAttribute("cy", this.height * 3 / 4); + this.circleY.setAttribute("r", this.height / 10); + this.circleY.setAttribute("opacity", "0.4"); + + this.circleZ.setAttribute("cx", this.width * 9 / 12); + this.circleZ.setAttribute("cy", this.height * 3 / 4); + this.circleZ.setAttribute("r", this.height / 10); + this.circleZ.setAttribute("opacity", "0.4"); + + this.barX.setAttribute("stroke-width", Math.round(this.height / 30)); + this.barY.setAttribute("stroke-width", Math.round(this.height / 30)); + this.barZ.setAttribute("stroke-width", Math.round(this.height / 30)); + + this.barX.setAttribute("fill", "none"); + this.barY.setAttribute("fill", "none"); + this.barZ.setAttribute("fill", "none"); + + this.barX2.setAttribute("stroke-width", Math.round(this.height / 30)); + this.barY2.setAttribute("stroke-width", Math.round(this.height / 30)); + this.barZ2.setAttribute("stroke-width", Math.round(this.height / 30)); + + this.barX2.setAttribute("fill", "none"); + this.barY2.setAttribute("fill", "none"); + this.barZ2.setAttribute("fill", "none"); + + this.title.setAttribute("x", this.width / 2); + this.title.setAttribute("y", this.height / 3 + 7); + this.title.setAttribute("font-size", "15px"); + this.title.setAttribute("font-weight", "bold"); + this.title.setAttribute("letter-spacing", "2px"); + this.title.setAttribute("opacity", "0.7"); + this.title.setAttribute("text-anchor", "middle"); + this.title.textContent = "TILT"; + + this.element.appendChild(this.circleX); + this.element.appendChild(this.circleY); + this.element.appendChild(this.circleZ); + + this.element.appendChild(this.barX); + this.element.appendChild(this.barY); + this.element.appendChild(this.barZ); + + this.element.appendChild(this.barX2); + this.element.appendChild(this.barY2); + this.element.appendChild(this.barZ2); + + this.element.appendChild(this.title); + } + }, + colorInterface: { + value: function colorInterface() { + + if (this._active) { + this.element.style.backgroundColor = this.colors.accent; + this.circleX.setAttribute("fill", this.colors.light); + this.circleY.setAttribute("fill", this.colors.light); + this.circleZ.setAttribute("fill", this.colors.light); + this.circleX.setAttribute("stroke", this.colors.light); + this.circleY.setAttribute("stroke", this.colors.light); + this.circleZ.setAttribute("stroke", this.colors.light); + this.barX.setAttribute("stroke", this.colors.light); + this.barY.setAttribute("stroke", this.colors.light); + this.barZ.setAttribute("stroke", this.colors.light); + this.barX2.setAttribute("stroke", this.colors.light); + this.barY2.setAttribute("stroke", this.colors.light); + this.barZ2.setAttribute("stroke", this.colors.light); + this.title.setAttribute("fill", this.colors.light); + } else { + this.element.style.backgroundColor = this.colors.fill; + this.circleX.setAttribute("fill", this.colors.mediumLight); + this.circleY.setAttribute("fill", this.colors.mediumLight); + this.circleZ.setAttribute("fill", this.colors.mediumLight); + this.circleX.setAttribute("stroke", this.colors.mediumLight); + this.circleY.setAttribute("stroke", this.colors.mediumLight); + this.circleZ.setAttribute("stroke", this.colors.mediumLight); + this.barX.setAttribute("stroke", this.colors.mediumLight); + this.barY.setAttribute("stroke", this.colors.mediumLight); + this.barZ.setAttribute("stroke", this.colors.mediumLight); + this.barX2.setAttribute("stroke", this.colors.mediumLight); + this.barY2.setAttribute("stroke", this.colors.mediumLight); + this.barZ2.setAttribute("stroke", this.colors.mediumLight); + this.title.setAttribute("fill", this.colors.mediumLight); + } + } + }, + update: { + value: function update(v) { + if (this._active) { + + var y = v.beta; + var x = v.gamma; + var z = v.alpha; + + // take the original -90 to 90 scale and normalize it 0-1 + x = math.scale(x, -90, 90, 0, 1); + y = math.scale(y, -90, 90, 0, 1); + z = math.scale(z, 0, 360, 0, 1); + + var handlePoints = { + start: Math.PI * 1.5, + end: math.clip(math.scale(x, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5) + }; + var handle2Points = { + start: Math.PI * 2.5, + end: math.clip(math.scale(x, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5) + }; + + var handlePath = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value, handlePoints.start, handlePoints.end); + var handle2Path = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value, handle2Points.start, handle2Points.end); + + this.barX.setAttribute("d", handlePath); + this.barX2.setAttribute("d", handle2Path); + + handlePoints = { + start: Math.PI * 1.5, + end: math.clip(math.scale(y, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5) + }; + handle2Points = { + start: Math.PI * 2.5, + end: math.clip(math.scale(y, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5) + }; + + handlePath = svg.arc(this.circleY.cx.baseVal.value, this.circleY.cy.baseVal.value, this.circleY.r.baseVal.value, handlePoints.start, handlePoints.end); + handle2Path = svg.arc(this.circleY.cx.baseVal.value, this.circleY.cy.baseVal.value, this.circleY.r.baseVal.value, handle2Points.start, handle2Points.end); + + this.barY.setAttribute("d", handlePath); + this.barY2.setAttribute("d", handle2Path); + + handlePoints = { + start: Math.PI * 1.5, + end: math.clip(math.scale(z, 0, 0.5, Math.PI * 1.5, Math.PI * 0.5), Math.PI * 0.5, Math.PI * 1.5) + }; + handle2Points = { + start: Math.PI * 2.5, + end: math.clip(math.scale(z, 0.5, 1, Math.PI * 2.5, Math.PI * 1.5), Math.PI * 1.5, Math.PI * 2.5) + }; + + handlePath = svg.arc(this.circleZ.cx.baseVal.value, this.circleZ.cy.baseVal.value, this.circleZ.r.baseVal.value, handlePoints.start, handlePoints.end); + handle2Path = svg.arc(this.circleZ.cx.baseVal.value, this.circleZ.cy.baseVal.value, this.circleZ.r.baseVal.value, handle2Points.start, handle2Points.end); + + this.barZ.setAttribute("d", handlePath); + this.barZ2.setAttribute("d", handle2Path); + + /* + let pointsX = { + start: 0, + end: math.scale( x, 0, 1, 0, Math.PI*2 ) + }; + // console.log(this.circleX.cx.baseVal.value); + let pathX = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value*2, pointsX.start, pointsX.end); + this.barX.setAttribute('d',pathX); */ + + //this.textH.textContent = math.prune(x,2); + //this.textV.textContent = math.prune(y,2); + // + // this.circleX.setAttribute('opacity',x); + // this.circleY.setAttribute('opacity',y); + // this.circleZ.setAttribute('opacity',z); + + this.emit("change", { + x: x, + y: y, + z: z + }); + } + } + }, + click: { + value: function click() { + if (window.DeviceOrientationEvent) { + this.active = !this.active; + } + } + }, + active: { + + /** + Whether the interface is on (emitting values) or off (paused & not emitting values). Setting this property will update it. + @type {boolean} + */ + + get: function () { + return this._active; + }, + set: function (on) { + this._active = on; + this.colorInterface(); + } + }, + customDestroy: { + value: function customDestroy() { + window.removeEventListener("deviceorientation", this.boundUpdate, false); + } + } + }); + + return Tilt; + })(Interface); + + module.exports = Tilt; + +/***/ }), +/* 31 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var dom = __webpack_require__(7); + var math = __webpack_require__(5); + var Interface = __webpack_require__(6); + var SliderTemplate = __webpack_require__(32); + var touch = __webpack_require__(9); + + var SingleSlider = (function (_SliderTemplate) { + function SingleSlider() { + var _this = this; + + _classCallCheck(this, SingleSlider); + + var options = ["scale", "value"]; + + var defaults = { + size: [120, 20], + orientation: "vertical", + mode: "absolute", + scale: [0, 1], + step: 0, + value: 0, + hasKnob: true + }; + + _get(Object.getPrototypeOf(SingleSlider.prototype), "constructor", this).call(this, arguments, options, defaults); + + /* events */ + + if (!touch.exists) { + + this.click = function () { + _this.multislider.interacting = true; + _this.multislider.interpolation = { + index: _this.index, + value: _this.value + }; + _this.down(); + _this.multislider.values[_this.index] = _this.value; + }; + this.element.addEventListener("mouseover", function (e) { + if (_this.multislider.interacting) { + if (!_this.offset) { + _this.offset = dom.findPosition(_this.element); + } + _this.mouse = dom.locateMouse(e, _this.offset); + _this.down(); + _this.multislider.values[_this.index] = _this.value; + if (_this.multislider.interpolation) { + var distance = Math.abs(_this.multislider.interpolation.index - _this.index); + if (distance > 1) { + var low = Math.min(_this.multislider.interpolation.index, _this.index); + var high = Math.max(_this.multislider.interpolation.index, _this.index); + var lowValue = _this.multislider.sliders[low].value; + var highValue = _this.multislider.sliders[high].value; + for (var i = low; i < high; i++) { + _this.multislider.sliders[i].value = math.interp((i - low) / distance, lowValue, highValue); + var smoothedValue = _this.multislider.sliders[i].value; + _this.multislider.values[i] = smoothedValue; + _this.multislider.update(i, smoothedValue); + } + } + } + + _this.multislider.interpolation = { + index: _this.index, + value: _this.value + }; + } + }); + + this.move = function () {}; + this.element.addEventListener("mousemove", function (e) { + if (_this.multislider.interacting) { + if (!_this.offset) { + _this.offset = dom.findPosition(_this.element); + } + _this.mouse = dom.locateMouse(e, _this.offset); + _this.slide(); + _this.multislider.values[_this.index] = _this.value; + } + }); + + this.release = function () { + _this.multislider.interacting = false; + _this.multislider.interpolation = false; + }; + this.element.addEventListener("mouseup", function () { + if (_this.multislider.interacting) { + _this.up(); + _this.multislider.interpolation = false; + _this.multislider.values[_this.index] = _this.value; + } + }); + this.element.addEventListener("mouseout", function () { + if (_this.multislider.interacting) { + _this.up(); + _this.multislider.values[_this.index] = _this.value; + } + }); + } + + this.customStyle(); + } + + _inherits(SingleSlider, _SliderTemplate); + + _createClass(SingleSlider, { + customStyle: { + value: function customStyle() { + + /* style changes */ + + this.bar.setAttribute("x", 0); + this.bar.setAttribute("transform", "translate(0,0)"); + this.bar.setAttribute("rx", 0); // corner radius + this.bar.setAttribute("ry", 0); + this.bar.setAttribute("width", this.width); + this.bar.setAttribute("height", this.height); + + this.fillbar.setAttribute("x", 0); + this.fillbar.setAttribute("transform", "translate(0,0)"); + this.fillbar.setAttribute("rx", 0); // corner radius + this.fillbar.setAttribute("ry", 0); + this.fillbar.setAttribute("width", this.width); + this.fillbar.setAttribute("height", this.height); + } + } + }); + + return SingleSlider; + })(SliderTemplate); + + /** + * Multislider + * + * @description Multislider + * + * @demo <span nexus-ui="multislider"></span> + * + * @example + * var multislider = new Nexus.Multislider('#target') + * + * @example + * var multislider = new Nexus.Multislider('#target',{ + * 'size': [200,100], + * 'numberOfSliders': 5, + * 'min': 0, + * 'max': 1, + * 'step': 0, + * 'values': [0.7,0.7,0.7,0.7,0.7] + * }) + * + * @output + * change + * Fires any time the interface's value changes. <br> + * The event data an object containing <i>index</i> and <i>value</i> properties + * + * @outputexample + * multislider.on('change',function(v) { + * console.log(v); + * }) + * + */ + + /* + Properties + .values + + */ + + var Multislider = (function (_Interface) { + function Multislider() { + _classCallCheck(this, Multislider); + + var options = ["value"]; + + var defaults = { + size: [200, 100], + numberOfSliders: 5, + min: 0, + max: 1, + step: 0, + values: [0.7, 0.7, 0.7, 0.7, 0.7] + }; + + _get(Object.getPrototypeOf(Multislider.prototype), "constructor", this).call(this, arguments, options, defaults); + + this._numberOfSliders = this.settings.numberOfSliders; + this.values = this.settings.values; + + this.sliders = []; + + this.interacting = false; + + this.init(); + } + + _inherits(Multislider, _Interface); + + _createClass(Multislider, { + buildFrame: { + value: function buildFrame() { + this.element = document.createElement("div"); + this.parent.appendChild(this.element); + } + }, + buildInterface: { + value: function buildInterface() { + + var min = this.settings.min; + var max = this.settings.max; + var step = this.settings.step; + + if (this.sliders.length) { + min = this.sliders[0].min; + max = this.sliders[0].max; + step = this.sliders[0].step; + } + + this.sliders = []; + + for (var i = 0; i < this._numberOfSliders; i++) { + var container = document.createElement("span"); + + var slider = new SingleSlider(container, { + scale: [min, max], + step: step, + mode: "absolute", + orientation: "vertical", + value: this.values[i], + hasKnob: false, + component: true }, this.update.bind(this, i)); + slider.multislider = this; + + slider.index = i; + if (touch.exists) { + slider.bar.index = i; + slider.fillbar.index = i; + slider.preClick = slider.preMove = slider.preRelease = function () {}; + slider.click = slider.move = slider.release = function () {}; + slider.preTouch = slider.preTouchMove = slider.preTouchRelease = function () {}; + slider.touch = slider.touchMove = slider.touchRelease = function () {}; + } + + this.sliders.push(slider); + this.element.appendChild(container); + } + if (touch.exists) { + this.addTouchListeners(); + } + } + }, + colorInterface: { + value: function colorInterface() { + for (var i = 0; i < this.sliders.length; i++) { + this.sliders[i].colors = this.colors; + this.sliders[i].colorInterface(); + } + } + }, + sizeInterface: { + value: function sizeInterface() { + + var sliderWidth = this.width / this.sliders.length; + var sliderHeight = this.height; + + for (var i = 0; i < this.sliders.length; i++) { + this.sliders[i].resize(sliderWidth, sliderHeight); + this.sliders[i].customStyle(); + } + } + }, + update: { + value: function update(index, value) { + this.emit("change", { + index: index, + value: value + }); + } + }, + addTouchListeners: { + value: function addTouchListeners() { + var _this = this; + + this.preClick = this.preMove = this.preRelease = function () {}; + this.click = this.move = this.release = function () {}; + this.preTouch = this.preTouchMove = this.preTouchRelease = function () {}; + this.touch = this.touchMove = this.touchRelease = function () {}; + + this.currentElement = false; + + this.element.addEventListener("touchstart", function (e) { + var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY); + var slider = _this.sliders[element.index]; + if (!slider.offset) { + slider.offset = dom.findPosition(slider.element); + } + slider.mouse = dom.locateMouse(e, slider.offset); + slider.down(); + _this.currentElement = element.index; + e.preventDefault(); + e.stopPropagation(); + }); + + this.element.addEventListener("touchmove", function (e) { + var element = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY); + var slider = _this.sliders[element.index]; + if (!slider.offset) { + slider.offset = dom.findPosition(slider.element); + } + slider.mouse = dom.locateMouse(e, slider.offset); + if (element.index !== _this.currentElement) { + if (_this.currentElement >= 0) { + var pastslider = _this.sliders[_this.currentElement]; + pastslider.up(); + } + slider.down(); + } else { + slider.slide(); + } + _this.currentElement = element.index; + e.preventDefault(); + e.stopPropagation(); + }); + + this.element.addEventListener("touchend", function (e) { + // no touches to calculate because none remaining + var slider = _this.sliders[_this.currentElement]; + slider.up(); + _this.interacting = false; + _this.currentElement = false; + e.preventDefault(); + e.stopPropagation(); + }); + } + }, + numberOfSliders: { + + /** + Get or set the number of sliders + @type {Number} + */ + + get: function () { + return this.sliders.length; + }, + set: function (v) { + if (v === this.sliders.length) { + return; + } + this.sliders.forEach(function (slider) { + slider.destroy(); + }); + this.empty(); + this._numberOfSliders = v; + this.buildInterface(); + } + }, + min: { + + /** + Lower limit of the multislider's output range + @type {number} + @example multislider.min = 1000; + */ + + get: function () { + return this.sliders[0].min; + }, + set: function (v) { + this.sliders.forEach(function (slider) { + slider.min = v; + }); + } + }, + max: { + + /** + Upper limit of the multislider's output range + @type {number} + @example multislider.max = 1000; + */ + + get: function () { + return this.sliders[0].max; + }, + set: function (v) { + this.sliders.forEach(function (slider) { + slider.max = v; + }); + } + }, + step: { + + /** + The increment that the multislider's value changes by. + @type {number} + @example multislider.step = 5; + */ + + get: function () { + return this.sliders[0].step; + }, + set: function (v) { + this.sliders.forEach(function (slider) { + slider.step = v; + }); + } + }, + setSlider: { + + /** + Set the value of an individual slider + @param index {number} Slider index + @param value {number} New slider value + @example + // Set the first slider to value 0.5 + multislider.setSlider(0,0.5) + */ + + value: function setSlider(index, value) { + this.sliders[index].value = value; + this.emit("change", { + index: index, + value: value + }); + } + }, + setAllSliders: { + + /** + Set the value of all sliders at once. If the size of the input array does not match the current number of sliders, the value array will repeat until all sliders have been set. I.e. an input array of length 1 will set all sliders to that value. + @param values {Array} All slider values + @example + multislider.setAllSliders([0.2,0.3,0.4,0.5,0.6]) + */ + + value: function setAllSliders(values) { + var _this = this; + + this.values = values; + this.sliders.forEach(function (slider, i) { + slider.value = values[i % values.length]; + _this.emit("change", { + index: i, + value: slider.value + }); + }); + } + } + }); + + return Multislider; + })(Interface); + + module.exports = Multislider; + +/***/ }), +/* 32 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var svg = __webpack_require__(4); + var Interface = __webpack_require__(6); + var Step = __webpack_require__(11); + + var Interaction = _interopRequireWildcard(__webpack_require__(12)); + + var SliderTemplate = (function (_Interface) { + function SliderTemplate(args, options, defaults) { + _classCallCheck(this, SliderTemplate); + + _get(Object.getPrototypeOf(SliderTemplate.prototype), "constructor", this).call(this, args, options, defaults); + + this.orientation = this.settings.orientation; + + // this.mode = this.settings.mode; + + this.hasKnob = this.settings.hasKnob; + + // this.step should eventually be get/set + // updating it will update the _value step model + // this.step = this.settings.step; // float + + this._value = new Step(this.settings.scale[0], this.settings.scale[1], this.settings.step, this.settings.value); + + this.init(); + + this.position = new Interaction.Handle(this.settings.mode, this.orientation, [0, this.width], [this.height, 0]); + this.position.value = this._value.normalized; + + this.value = this._value.value; + + this.emit("change", this.value); + } + + _inherits(SliderTemplate, _Interface); + + _createClass(SliderTemplate, { + buildInterface: { + value: function buildInterface() { + + this.bar = svg.create("rect"); + this.fillbar = svg.create("rect"); + this.knob = svg.create("circle"); + + this.element.appendChild(this.bar); + this.element.appendChild(this.fillbar); + this.element.appendChild(this.knob); + + this.sizeInterface(); + } + }, + sizeInterface: { + value: function sizeInterface() { + + if (!this.settings.orientation) { + if (this.width < this.height) { + this.orientation = "vertical"; + } else { + this.orientation = "horizontal"; + } + } + + var x = undefined, + y = undefined, + w = undefined, + h = undefined, + barOffset = undefined, + cornerRadius = undefined; + this.knobData = { + level: 0, + r: 0 + }; + + if (this.orientation === "vertical") { + this.thickness = this.width / 2; + x = this.width / 2; + y = 0; + w = this.thickness; + h = this.height; + this.knobData.r = this.thickness * 0.8; + this.knobData.level = h - this.normalized * h; + barOffset = "translate(" + this.thickness * -1 / 2 + ",0)"; + cornerRadius = w / 2; + } else { + this.thickness = this.height / 2; + x = 0; + y = this.height / 2; + w = this.width; + h = this.thickness; + this.knobData.r = this.thickness * 0.8; + this.knobData.level = this.normalized * w; + barOffset = "translate(0," + this.thickness * -1 / 2 + ")"; + cornerRadius = h / 2; + } + + this.bar.setAttribute("x", x); + this.bar.setAttribute("y", y); + this.bar.setAttribute("transform", barOffset); + this.bar.setAttribute("rx", cornerRadius); // corner radius + this.bar.setAttribute("ry", cornerRadius); + this.bar.setAttribute("width", w); + this.bar.setAttribute("height", h); + + if (this.orientation === "vertical") { + this.fillbar.setAttribute("x", x); + this.fillbar.setAttribute("y", this.knobData.level); + this.fillbar.setAttribute("width", w); + this.fillbar.setAttribute("height", h - this.knobData.level); + } else { + this.fillbar.setAttribute("x", 0); + this.fillbar.setAttribute("y", y); + this.fillbar.setAttribute("width", this.knobData.level); + this.fillbar.setAttribute("height", h); + } + this.fillbar.setAttribute("transform", barOffset); + this.fillbar.setAttribute("rx", cornerRadius); + this.fillbar.setAttribute("ry", cornerRadius); + + if (this.orientation === "vertical") { + this.knob.setAttribute("cx", x); + this.knob.setAttribute("cy", this.knobData.level); + } else { + this.knob.setAttribute("cx", this.knobData.level); + this.knob.setAttribute("cy", y); + } + this.knob.setAttribute("r", this.knobData.r); + + if (this.position) { + this.position.resize([0, this.width], [this.height, 0]); + } + } + }, + colorInterface: { + value: function colorInterface() { + + this.bar.setAttribute("fill", this.colors.fill); + this.fillbar.setAttribute("fill", this.colors.accent); + this.knob.setAttribute("fill", this.colors.accent); + if (!this.hasKnob) { + this.knob.setAttribute("fill", "none"); + } + } + }, + render: { + value: function render() { + if (!this.clicked) { + this.knobData.r = this.thickness * 0.75; + } + this.knob.setAttribute("r", this.knobData.r); + + if (this.orientation === "vertical") { + this.knobData.level = this._value.normalized * this.height; + this.knob.setAttribute("cy", this.height - this.knobData.level); + this.fillbar.setAttribute("y", this.height - this.knobData.level); + this.fillbar.setAttribute("height", this.knobData.level); + } else { + this.knobData.level = this._value.normalized * this.width; + this.knob.setAttribute("cx", this.knobData.level); + this.fillbar.setAttribute("x", 0); + this.fillbar.setAttribute("width", this.knobData.level); + } + } + }, + down: { + value: function down() { + this.clicked = true; + this.knobData.r = this.thickness * 0.9; + this.position.anchor = this.mouse; + this.slide(); + } + }, + slide: { + value: function slide() { + if (this.clicked) { + this.position.update(this.mouse); + this.value = this._value.updateNormal(this.position.value); + this.emit("change", this.value); + } + } + }, + up: { + value: function up() { + this.clicked = false; + this.render(); + } + }, + normalized: { + get: function () { + return this._value.normalized; + } + }, + value: { + + /** + The slider's current value. If set manually, will update the interface and trigger the output event. + @type {number} + @example slider.value = 10; + */ + + get: function () { + return this._value.value; + }, + set: function (v) { + this._value.update(v); + this.position.value = this._value.normalized; + this.render(); + } + }, + min: { + + /** + Lower limit of the sliders's output range + @type {number} + @example slider.min = 1000; + */ + + get: function () { + return this._value.min; + }, + set: function (v) { + this._value.min = v; + } + }, + max: { + + /** + Upper limit of the slider's output range + @type {number} + @example slider.max = 1000; + */ + + get: function () { + return this._value.max; + }, + set: function (v) { + this._value.max = v; + } + }, + step: { + + /** + The increment that the slider's value changes by. + @type {number} + @example slider.step = 5; + */ + + get: function () { + return this._value.step; + }, + set: function (v) { + this._value.step = v; + } + }, + mode: { + + /** + Absolute mode (slider's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: "relative". + @type {string} + @example slider.mode = "relative"; + */ + + get: function () { + return this.position.mode; + }, + set: function (v) { + this.position.mode = v; + } + } + }); + + return SliderTemplate; + })(Interface); + + module.exports = SliderTemplate; + +/***/ }), +/* 33 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var svg = __webpack_require__(4); + var math = __webpack_require__(5); + var Interface = __webpack_require__(6); + var Step = __webpack_require__(11); + + var Interaction = _interopRequireWildcard(__webpack_require__(12)); + + /** + * Pan + * + * @description Stereo crossfader. + * + * @demo <span nexus-ui="pan"></span> + * + * @example + * var pan = new Nexus.Pan('#target') + * + * @output + * change + * Fires any time the interface's value changes. <br> + * The event data is an object containing the interface's <i>value</i> (-1 to 1), as well as <i>L</i> and <i>R</i> amplitude values (0-1) for left and right speakers, calculated by a square-root crossfade algorithm. + * + * @outputexample + * pan.on('change',function(v) { + * console.log(v); + * }) + * + * + */ + + var Pan = (function (_Interface) { + function Pan() { + _classCallCheck(this, Pan); + + var options = ["scale", "value"]; + + var defaults = { + size: [120, 20], + orientation: "horizontal", + mode: "relative", + scale: [-1, 1], + step: 0, + value: 0, + hasKnob: true + }; + + _get(Object.getPrototypeOf(Pan.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.orientation = this.settings.orientation; + + this.mode = this.settings.mode; + + this.hasKnob = this.settings.hasKnob; + + // this.step should eventually be get/set + // updating it will update the _value step model + this.step = this.settings.step; // float + + this._value = new Step(this.settings.scale[0], this.settings.scale[1], this.settings.step, this.settings.value); + + this.init(); + + this.position = new Interaction.Handle(this.mode, this.orientation, [0, this.width], [this.height, 0]); + this.position.value = this._value.normalized; + + this.value = this._value.value; + + this.emit("change", this.value); + } + + _inherits(Pan, _Interface); + + _createClass(Pan, { + buildInterface: { + value: function buildInterface() { + + this.bar = svg.create("rect"); + this.knob = svg.create("circle"); + + this.element.appendChild(this.bar); + this.element.appendChild(this.knob); + } + }, + sizeInterface: { + value: function sizeInterface() { + + if (this.position) { + this.position.resize([0, this.width], [this.height, 0]); + } + + if (this.width < this.height) { + this.orientation = "vertical"; + } else { + this.orientation = "horizontal"; + } + + var x = undefined, + y = undefined, + w = undefined, + h = undefined, + barOffset = undefined, + cornerRadius = undefined; + this.knobData = { + level: 0, + r: 0 + }; + + if (this.orientation === "vertical") { + this.thickness = this.width / 2; + x = this.width / 2; + y = 0; + w = this.thickness; + h = this.height; + this.knobData.r = this.thickness * 0.8; + this.knobData.level = h - this.knobData.r - this.normalized * (h - this.knobData.r * 2); + barOffset = "translate(" + this.thickness * -1 / 2 + ",0)"; + cornerRadius = w / 2; + } else { + this.thickness = this.height / 2; + x = 0; + y = this.height / 2; + w = this.width; + h = this.thickness; + this.knobData.r = this.thickness * 0.8; + this.knobData.level = this.normalized * (w - this.knobData.r * 2) + this.knobData.r; + barOffset = "translate(0," + this.thickness * -1 / 2 + ")"; + cornerRadius = h / 2; + } + + this.bar.setAttribute("x", x); + this.bar.setAttribute("y", y); + this.bar.setAttribute("transform", barOffset); + this.bar.setAttribute("rx", cornerRadius); // corner radius + this.bar.setAttribute("ry", cornerRadius); + this.bar.setAttribute("width", w); + this.bar.setAttribute("height", h); + + if (this.orientation === "vertical") { + this.knob.setAttribute("cx", x); + this.knob.setAttribute("cy", this.knobData.level); + } else { + this.knob.setAttribute("cx", this.knobData.level); + this.knob.setAttribute("cy", y); + } + this.knob.setAttribute("r", this.knobData.r); + } + }, + colorInterface: { + value: function colorInterface() { + + this.bar.setAttribute("fill", this.colors.fill); + this.knob.setAttribute("fill", this.colors.accent); + + if (!this.hasKnob) { + this.knob.setAttribute("fill", "transparent"); + } + } + }, + render: { + value: function render() { + if (!this.clicked) { + this.knobData.r = this.thickness * 0.75; + } + this.knob.setAttribute("r", this.knobData.r); + + if (this.orientation === "vertical") { + this.knobData.level = this.knobData.r + this._value.normalized * (this.height - this.knobData.r * 2); + this.knob.setAttribute("cy", this.height - this.knobData.level); + } else { + this.knobData.level = this._value.normalized * (this.width - this.knobData.r * 2) + this.knobData.r; + this.knob.setAttribute("cx", this.knobData.level); + } + } + }, + click: { + value: function click() { + this.knobData.r = this.thickness * 0.9; + this.position.anchor = this.mouse; + this.move(); + } + }, + move: { + value: function move() { + if (this.clicked) { + this.position.update(this.mouse); + + this.value = this._value.updateNormal(this.position.value); + + this.emit("change", { + value: this.value, + L: Math.pow(math.scale(this.value, -1, 1, 1, 0), 2), + R: Math.pow(math.scale(this.value, -1, 1, 0, 1), 2) + }); + } + } + }, + release: { + value: function release() { + this.render(); + } + }, + value: { + + /** + The position of crossfader, from -1 (left) to 1 (right). Setting this value updates the interface and triggers the output event. + @type {number} + */ + + get: function () { + return this._value.value; + }, + set: function (value) { + this._value.update(value); + this.position.value = this._value.normalized; + this.emit("change", { + value: this.value, + L: Math.pow(math.scale(this.value, -1, 1, 1, 0), 2), + R: Math.pow(math.scale(this.value, -1, 1, 0, 1), 2) + }); + this.render(); + } + }, + normalized: { + get: function () { + return this._value.normalized; + } + } + }); + + return Pan; + })(Interface); + + module.exports = Pan; + +/***/ }), +/* 34 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var math = __webpack_require__(5); + var svg = __webpack_require__(4); + var Interface = __webpack_require__(6); + + var Point = function Point(point, envelope) { + + this.x = point.x; + this.y = point.y; + this.envelope = envelope; + + this.element = svg.create("circle"); + this.element.setAttribute("fill", this.envelope.colors.accent); + + this.envelope.element.appendChild(this.element); + + this.resize = function () { + var r = ~ ~(Math.min(this.envelope.width, this.envelope.height) / 50) + 2; + this.element.setAttribute("r", r); + }; + + this.move = function (x, y) { + + this.x = x || x === 0 ? x : this.x; + this.y = y || y === 0 ? y : this.y; + + if (this.envelope.nodes.indexOf(this) >= 0) { + + var prevIndex = this.envelope.nodes.indexOf(this) - 1; + var nextIndex = this.envelope.nodes.indexOf(this) + 1; + + var prevNode = this.envelope.nodes[prevIndex]; + var nextNode = this.envelope.nodes[nextIndex]; + + var lowX = prevIndex >= 0 ? prevNode.x : 0; + var highX = nextIndex < this.envelope.nodes.length ? nextNode.x : 1; + + if (this.x < lowX) { + this.x = lowX; + } + if (this.x > highX) { + this.x = highX; + } + } + + this.location = this.getCoordinates(); + this.element.setAttribute("cx", this.location.x); + this.element.setAttribute("cy", this.location.y); + }; + + this.getCoordinates = function () { + return { + x: this.x * this.envelope.width, + y: (1 - this.y) * this.envelope.height + }; + }; + + this.move(this.x, this.y, true); + this.resize(); + + this.destroy = function () { + this.envelope.element.removeChild(this.element); + this.envelope.nodes.splice(this.envelope.nodes.indexOf(this), 1); + }; + }; + + /** + * Envelope + * + * @description Interactive linear ramp visualization. + * + * @demo <span nexus-ui="envelope"></span> + * + * @example + * var envelope = new Nexus.Envelope('#target') + * + * @example + * var envelope = new Nexus.Envelope('#target',{ + * 'size': [300,150], + * 'points': [ + * { + * x: 0.1, + * y: 0.4 + * }, + * { + * x: 0.35, + * y: 0.6 + * }, + * { + * x: 0.65, + * y: 0.2 + * }, + * { + * x: 0.9, + * y: 0.4 + * }, + * ] + * }) + * + * @output + * change + * Fires any time a node is moved. <br> + * The event data is an array of point locations. Each item in the array is an object containing <i>x</i> and <i>y</i> properties describing the location of a point on the envelope. + * + * @outputexample + * envelope.on('change',function(v) { + * console.log(v); + * }) + * + */ + + var Envelope = (function (_Interface) { + function Envelope() { + _classCallCheck(this, Envelope); + + var options = ["value"]; + + var defaults = { + size: [300, 150], + points: [{ + x: 0.1, + y: 0.4 + }, { + x: 0.35, + y: 0.6 + }, { + x: 0.65, + y: 0.2 + }, { + x: 0.9, + y: 0.4 + }] + }; + + _get(Object.getPrototypeOf(Envelope.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.points = this.settings.points; + + this.nodes = []; + + this.selected = false; + + this.init(); + } + + _inherits(Envelope, _Interface); + + _createClass(Envelope, { + buildInterface: { + value: function buildInterface() { + var _this = this; + + this.points.forEach(function (point) { + var node = new Point(point, _this); + _this.nodes.push(node); + }); + + this.sortPoints(); + + this.line = svg.create("polyline"); + this.line.setAttribute("stroke-width", 2); + this.line.setAttribute("fill", "none"); + + this.element.appendChild(this.line); + + this.fill = svg.create("polyline"); + this.fill.setAttribute("fill-opacity", "0.2"); + + this.element.appendChild(this.fill); + } + }, + sizeInterface: { + value: function sizeInterface() { + + for (var i = 0; i < this.nodes.length; i++) { + this.nodes[i].resize(); + this.nodes[i].move(); + } + + this.render(); + } + }, + colorInterface: { + value: function colorInterface() { + var _this = this; + + this.element.style.backgroundColor = this.colors.fill; + this.line.setAttribute("stroke", this.colors.accent); + this.fill.setAttribute("fill", this.colors.accent); + this.nodes.forEach(function (node) { + node.element.setAttribute("fill", _this.colors.accent); + }); + } + }, + render: { + value: function render() { + // this.nodes[this.selected].move( this.points ) + this.calculatePath(); + } + }, + calculatePoints: { + value: function calculatePoints() { + var _this = this; + + this.points = []; + this.nodes.forEach(function (node) { + _this.points.push({ x: node.x, y: node.y }); + }); + } + }, + calculatePath: { + value: function calculatePath() { + + //stroke data + var data = "0 " + this.nodes[0].location.y + ", "; + + // data should be re-ordered based on x location. + // whatever function adds a node should add it at the right index + + this.nodes.forEach(function (node) { + // let location = node.getCoordinates(); + data += node.location.x + " " + node.location.y + ", "; + }); + + // data += point.x*this.width+' '+ point.y*this.height+', '; + data += this.width + " " + this.nodes[this.nodes.length - 1].location.y; + + this.line.setAttribute("points", data); + + // fill data + // add bottom corners + + data += ", " + this.width + " " + this.height + ", "; + data += "0 " + this.height; + + this.fill.setAttribute("points", data); + } + }, + click: { + value: function click() { + // find nearest node and set this.selected (index) + this.hasMoved = false; + this.selected = this.findNearestNode(); + + this.nodes[this.selected].move(this.mouse.x / this.width, 1 - this.mouse.y / this.height); + this.scaleNode(this.selected); + + // must do this b/c new node may have been created + this.calculatePoints(); + this.emit("change", this.points); + this.render(); + } + }, + move: { + value: function move() { + if (this.clicked) { + this.mouse.x = math.clip(this.mouse.x, 0, this.width); + this.hasMoved = true; + + this.nodes[this.selected].move(this.mouse.x / this.width, 1 - this.mouse.y / this.height); + this.scaleNode(this.selected); + + this.calculatePoints(); + this.emit("change", this.points); + this.render(); + } + } + }, + release: { + value: function release() { + + if (!this.hasMoved) { + this.nodes[this.selected].destroy(); + } + + this.calculatePoints(); + this.emit("change", this.points); + this.render(); + + // reset this.selected + this.selected = null; + } + }, + findNearestNode: { + value: function findNearestNode() { + var nearestIndex = null; + // set this unreasonably high so that every distance will be lower than it. + var nearestDist = 10000; + var before = false; + var x = this.mouse.x / this.width; + var y = 1 - this.mouse.y / this.height; + var nodes = this.nodes; + for (var i = 0; i < nodes.length; i++) { + + // calculate the distance from mouse to this node using pythagorean theorem + var distance = Math.sqrt(Math.pow(nodes[i].x - x, 2) + Math.pow(nodes[i].y - y, 2)); + + // if this distance is less than the previous shortest distance, use this index + if (distance < nearestDist) { + nearestDist = distance; + nearestIndex = i; + before = x > nodes[i].x; + } + } + + // if not very close to any node, create a node + if (nearestDist > 0.07) { + + nearestIndex = this.getIndexFromX(this.mouse.x / this.width); + + this.nodes.splice(nearestIndex, 0, new Point({ + x: this.mouse.x / this.width, + y: 1 - this.mouse.y / this.height + }, this)); + this.hasMoved = true; + } + + return nearestIndex; + } + }, + getIndexFromX: { + value: function getIndexFromX(x) { + var _this = this; + + var index = 0; + this.nodes.forEach(function (node, i) { + if (_this.nodes[i].x <= x) { + index = i + 1; + } + }); + return index; + } + }, + scaleNode: { + value: function scaleNode(i) { + + var clippedX = math.clip(this.nodes[i].x, 0, 1); + var clippedY = math.clip(this.nodes[i].y, 0, 1); + + this.nodes[i].move(clippedX, clippedY); + } + }, + sortPoints: { + + /** + Sort the this.points array from left-most point to right-most point. You should not regularly need to use this, however it may be useful if the points get unordered. + */ + + value: function sortPoints() { + this.nodes.sort(function (a, b) { + return a.x > b.x; + }); + } + }, + addPoint: { + + /** + Add a breakpoint on the envelope. + @param x {number} x location of the point, normalized (0-1) + @param y {number} y location of the point, normalized (0-1) + */ + + value: function addPoint(x, y) { + var index = this.nodes.length; + + this.sortPoints(); + + for (var i = 0; i < this.nodes.length; i++) { + if (x < this.nodes[i].x) { + index = i; + break; + } + } + + this.nodes.splice(index, 0, new Point({ + x: x, + y: y + }, this)); + + this.scaleNode(index); + + this.calculatePoints(); + this.emit("change", this.points); + + this.render(); + } + }, + scan: { + + /** + Find the level at a certain x location on the envelope. + @param x {number} The x location to find the level of, normalized 0-1 + */ + + value: function scan(x) { + // find surrounding points + var nextIndex = this.getIndexFromX(x); + var priorIndex = nextIndex - 1; + if (priorIndex < 0) { + priorIndex = 0; + } + if (nextIndex >= this.nodes.length) { + nextIndex = this.nodes.length - 1; + } + var priorPoint = this.nodes[priorIndex]; + var nextPoint = this.nodes[nextIndex]; + var loc = math.scale(x, priorPoint.x, nextPoint.x, 0, 1); + var value = math.interp(loc, priorPoint.y, nextPoint.y); + this.emit("scan", value); + return value; + } + }, + movePoint: { + + /** + Move a breakpoint on the envelope. + @param index {number} The index of the breakpoint to move + @param x {number} New x location, normalized 0-1 + @param y {number} New y location, normalized 0-1 + */ + + value: function movePoint(index, x, y) { + this.nodes[index].move(x, y); + this.scaleNode(index); + this.calculatePoints(); + this.emit("change", this.points); + this.render(); + } + }, + adjustPoint: { + + /** + Move a breakpoint on the envelope by a certain amount. + @param index {number} The index of the breakpoint to move + @param xOffset {number} X displacement, normalized 0-1 + @param yOffset {number} Y displacement, normalized 0-1 + */ + + value: function adjustPoint(index, xOffset, yOffset) { + this.nodes[index].move(this.nodes[index].x + xOffset, this.nodes[index].y + yOffset); + this.scaleNode(index); + this.calculatePoints(); + this.emit("change", this.points); + this.render(); + } + }, + destroyPoint: { + + /** + Remove a breakpoint from the envelope. + @param index {number} Index of the breakpoint to remove + */ + + value: function destroyPoint(index) { + this.nodes[index].destroy(); + this.calculatePoints(); + this.emit("change", this.points); + this.render(); + } + }, + setPoints: { + + /** + Remove all existing breakpoints and add an entirely new set of breakpoints. + @param allPoints {array} An array of objects with x/y properties (normalized 0-1). Each object in the array specifices the x/y location of a new breakpoint to be added. + */ + + value: function setPoints(allPoints) { + var _this = this; + + while (this.nodes.length) { + this.nodes[0].destroy(); + } + allPoints.forEach(function (point) { + _this.addPoint(point.x, point.y); + }); + this.calculatePoints(); + this.emit("change", this.points); + this.render(); + } + } + }); + + return Envelope; + })(Interface); + + module.exports = Envelope; + +/***/ }), +/* 35 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var dom = __webpack_require__(7); + //let math = require('../util/math'); + var Interface = __webpack_require__(6); + + /** + * Spectrogram + * + * @description Audio spectrum visualization + * + * @demo <span nexus-ui="spectrogram"></span> + * + * @example + * var spectrogram = new Nexus.Spectrogram('#target') + * + * @example + * var spectrogram = new Nexus.Spectrogram('#target',{ + * 'size': [300,150] + * }) + * + * @output + * + * No events + * + */ + + var context = __webpack_require__(1).context; + + var Spectrogram = (function (_Interface) { + function Spectrogram() { + _classCallCheck(this, Spectrogram); + + var options = ["scale", "value"]; + + var defaults = { + size: [300, 150] + }; + + _get(Object.getPrototypeOf(Spectrogram.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.context = context(); // jshint ignore:line + + this.analyser = this.context.createAnalyser(); + this.analyser.fftSize = 2048; + this.bufferLength = this.analyser.frequencyBinCount; + this.dataArray = new Uint8Array(this.bufferLength); + + this.active = true; + + this.source = false; + + this.init(); + } + + _inherits(Spectrogram, _Interface); + + _createClass(Spectrogram, { + buildFrame: { + value: function buildFrame() { + this.canvas = new dom.SmartCanvas(this.parent); + this.element = this.canvas.element; + } + }, + sizeInterface: { + value: function sizeInterface() { + this.canvas.resize(this.width, this.height); + } + }, + colorInterface: { + value: function colorInterface() { + this.canvas.element.style.backgroundColor = this.colors.fill; + } + }, + render: { + value: function render() { + + if (this.active) { + requestAnimationFrame(this.render.bind(this)); + } + + this.analyser.getByteFrequencyData(this.dataArray); + + this.canvas.context.fillStyle = this.colors.fill; + this.canvas.context.fillRect(0, 0, this.canvas.element.width, this.canvas.element.height); + + if (this.source && this.dataArray) { + + //console.log(this.dataArray); + + var barWidth = this.canvas.element.width / this.bufferLength; + var barHeight = undefined; + var x = 0; + + var definition = this.canvas.element.width / 50; + + for (var i = 0; i < this.bufferLength; i = i + definition) { + barHeight = Math.max.apply(null, this.dataArray.subarray(i, i + definition)); + barHeight /= 255; + barHeight *= this.canvas.element.height; + + this.canvas.context.fillStyle = this.colors.accent; + this.canvas.context.fillRect(x, this.canvas.element.height - barHeight, barWidth * definition, barHeight); + + x += barWidth * definition; + } + } + } + }, + connect: { + + /** + Equivalent to "patching in" an audio node to visualize. NOTE: You cannot connect audio nodes across two different audio contexts. NexusUI runs its audio analysis on its own audio context, Nexus.context. If the audio node you are visualizing is created on a different audio context, you will need to tell NexusUI to use that context instead: i.e. Nexus.context = YourAudioContextName. For example, in ToneJS projects, the line would be: Nexus.context = Tone.context . We recommend that you write that line of code only once at the beginning of your project. + @param node {AudioNode} The audio node to visualize + @example Nexus.context = Tone.context // or another audio context you have created + spectrogram.connect( Tone.Master ); + */ + + value: function connect(node) { + if (this.source) { + this.disconnect(); + } + this.source = node; + this.source.connect(this.analyser); + this.render(); + } + }, + disconnect: { + + /** + Stop visualizing the source node and disconnect it. + */ + + value: function disconnect() { + this.source.disconnect(this.analyser); + this.source = null; + } + }, + click: { + value: function click() { + this.active = !this.active; + this.render(); + } + }, + customDestroy: { + value: function customDestroy() { + this.active = false; + } + } + }); + + return Spectrogram; + })(Interface); + + module.exports = Spectrogram; + +/***/ }), +/* 36 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var dom = __webpack_require__(7); + var math = __webpack_require__(5); + var Interface = __webpack_require__(6); + + /** + * Meter + * + * @description Stereo decibel meter + * + * @demo <span nexus-ui="meter"></span> + * + * @example + * var meter = new Nexus.Meter('#target') + * + * @example + * var meter = new Nexus.Meter('#target',{ + * size: [75,75] + * }) + * + * @output + * + * No events + * + */ + + var context = __webpack_require__(1).context; + + var Meter = (function (_Interface) { + function Meter() { + _classCallCheck(this, Meter); + + var options = ["scale", "value"]; + + var defaults = { + size: [30, 100] + }; + + _get(Object.getPrototypeOf(Meter.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.context = context(); // jshint ignore:line + + this.channels = 2; + + this.splitter = this.context.createChannelSplitter(this.channels); + + this.analysers = []; + + for (var i = 0; i < this.channels; i++) { + var analyser = this.context.createAnalyser(); + this.splitter.connect(analyser, i); + analyser.fftSize = 1024; + analyser.smoothingTimeConstant = 1; + this.analysers.push(analyser); + } + this.bufferLength = this.analysers[0].frequencyBinCount; + this.dataArray = new Float32Array(this.bufferLength); + + /* + // add linear gradient + var grd = canvasCtx.createLinearGradient(0, 0, 0, canvas.height); + // light blue + grd.addColorStop(0, '#000'); + grd.addColorStop(0.2, '#bbb'); + grd.addColorStop(0.4, '#d18'); + // dark blue + grd.addColorStop(1, '#d18'); + canvasCtx.fillStyle = grd; */ + + this.active = true; + + this.db = -Infinity; + + this.init(); + + this.meterWidth = this.canvas.element.width / this.channels; + + this.render(); + } + + _inherits(Meter, _Interface); + + _createClass(Meter, { + buildFrame: { + value: function buildFrame() { + this.canvas = new dom.SmartCanvas(this.parent); + this.element = this.canvas.element; + } + }, + sizeInterface: { + value: function sizeInterface() { + this.canvas.resize(this.width, this.height); + } + }, + colorInterface: { + value: function colorInterface() { + this.canvas.element.style.backgroundColor = this.colors.fill; + } + }, + render: { + value: function render() { + + if (this.active) { + requestAnimationFrame(this.render.bind(this)); + } + + this.canvas.context.fillStyle = this.colors.fill; + this.canvas.context.fillRect(0, 0, this.canvas.element.width, this.canvas.element.height); + + for (var i = 0; i < this.analysers.length; i++) { + + if (this.source) { + + this.analysers[i].getFloatTimeDomainData(this.dataArray); + + var rms = 0; + + for (var _i = 0; _i < this.dataArray.length; _i++) { + rms += this.dataArray[_i] * this.dataArray[_i]; + } + + rms = Math.sqrt(rms / this.dataArray.length); + + this.db = 20 * Math.log10(rms); + } else if (this.db > -200 && this.db !== -Infinity) { + this.db -= 1; + } else { + this.db = -Infinity; + } + + //console.log(db) + + if (this.db > -70) { + + var linear = math.normalize(this.db, -70, 5); + var exp = linear * linear; + var y = math.scale(exp, 0, 1, this.element.height, 0); + + this.canvas.context.fillStyle = this.colors.accent; + this.canvas.context.fillRect(this.meterWidth * i, y, this.meterWidth, this.canvas.element.height - y); + + //console.log("rendering...") + } + } + } + }, + connect: { + + /** + Equivalent to "patching in" an audio node to visualize. NOTE: You cannot connect audio nodes across two different audio contexts. NexusUI runs its audio analysis on its own audio context, Nexus.context. If the audio node you are visualizing is created on a different audio context, you will need to tell NexusUI to use that context instead: i.e. Nexus.context = YourAudioContextName. For example, in ToneJS projects, the line would be: Nexus.context = Tone.context . We recommend that you write that line of code only once at the beginning of your project. + @param node {AudioNode} The audio node to visualize + @param channels {number} (optional) The number of channels in the source node to watch. If not specified, the interface will look for a .channelCount property on the input node. If it does not exist, the interface will default to 1 channel. + @example Nexus.context = Tone.context // or another audio context you have created + meter.connect( Tone.Master, 2 ); + */ + + value: function connect(node, channels) { + if (this.source) { + this.disconnect(); + } + //this.dummy.disconnect(this.splitter); + + if (channels) { + this.channels = channels; + } else if (node.channelCount) { + this.channels = node.channelCount; + } else { + this.channels = 2; + } + this.meterWidth = this.canvas.element.width / this.channels; + + this.source = node; + this.source.connect(this.splitter); + + // this.render(); + } + }, + disconnect: { + + /** + Stop visualizing the source node and disconnect it. + */ + + value: function disconnect() { + + this.source.disconnect(this.splitter); + this.source = false; + // this.dummy.connect(this.splitter); + this.meterWidth = this.canvas.element.width / this.channels; + } + }, + click: { + value: function click() { + this.active = !this.active; + this.render(); + } + }, + customDestroy: { + value: function customDestroy() { + this.active = false; + } + } + }); + + return Meter; + })(Interface); + + module.exports = Meter; + +/***/ }), +/* 37 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var dom = __webpack_require__(7); + var Interface = __webpack_require__(6); + + /** + * Oscilloscope + * + * @description Visualizes a waveform's stream of values. + * + * @demo <span nexus-ui="oscilloscope"></span> + * + * @example + * var oscilloscope = new Nexus.Oscilloscope('#target') + * + * @example + * var oscilloscope = new Nexus.Oscilloscope('#target',{ + * 'size': [300,150] + * }) + * + * @output + * + * No events + * + */ + + var context = __webpack_require__(1).context; + + var Oscilloscope = (function (_Interface) { + function Oscilloscope() { + _classCallCheck(this, Oscilloscope); + + var options = ["scale", "value"]; + + var defaults = { + size: [300, 150] + }; + + _get(Object.getPrototypeOf(Oscilloscope.prototype), "constructor", this).call(this, arguments, options, defaults); + + this.context = context(); // jshint ignore:line + + this.analyser = this.context.createAnalyser(); + this.analyser.fftSize = 2048; + this.bufferLength = this.analyser.frequencyBinCount; + this.dataArray = new Uint8Array(this.bufferLength); + this.analyser.getByteTimeDomainData(this.dataArray); + + this.active = true; + + this.source = false; + + this.init(); + + this.render(); + } + + _inherits(Oscilloscope, _Interface); + + _createClass(Oscilloscope, { + buildFrame: { + value: function buildFrame() { + this.canvas = new dom.SmartCanvas(this.parent); + this.element = this.canvas.element; + } + }, + sizeInterface: { + value: function sizeInterface() { + this.canvas.resize(this.width, this.height); + } + }, + colorInterface: { + value: function colorInterface() { + this.canvas.element.style.backgroundColor = this.colors.fill; + } + }, + render: { + value: function render() { + + if (this.active) { + requestAnimationFrame(this.render.bind(this)); + } + + this.analyser.getByteTimeDomainData(this.dataArray); + + this.canvas.context.fillStyle = this.colors.fill; + this.canvas.context.fillRect(0, 0, this.canvas.element.width, this.canvas.element.height); + + this.canvas.context.lineWidth = ~ ~(this.height / 100 + 2); + this.canvas.context.strokeStyle = this.colors.accent; + + this.canvas.context.beginPath(); + + if (this.source) { + + var sliceWidth = this.canvas.element.width * 1 / this.bufferLength; + var x = 0; + + for (var i = 0; i < this.bufferLength; i++) { + + var v = this.dataArray[i] / 128; + var y = v * this.canvas.element.height / 2; + + if (i === 0) { + this.canvas.context.moveTo(x, y); + } else { + this.canvas.context.lineTo(x, y); + } + + x += sliceWidth; + } + } else { + this.canvas.context.moveTo(0, this.canvas.element.height / 2); + this.canvas.context.lineTo(this.canvas.element.width, this.canvas.element.height / 2); + } + + this.canvas.context.stroke(); + } + }, + connect: { + + /** + Equivalent to "patching in" an audio node to visualize. NOTE: You cannot connect audio nodes across two different audio contexts. NexusUI runs its audio analysis on its own audio context, Nexus.context. If the audio node you are visualizing is created on a different audio context, you will need to tell NexusUI to use that context instead: i.e. Nexus.context = YourAudioContextName. For example, in ToneJS projects, the line would be: Nexus.context = Tone.context . We recommend that you write that line of code only once at the beginning of your project. + @param node {AudioNode} The audio node to visualize + @example Nexus.context = Tone.context // or another audio context you have created + oscilloscope.connect( Tone.Master ); + */ + + value: function connect(node) { + + if (this.source) { + this.disconnect(); + } + + this.source = node; + this.source.connect(this.analyser); + + this.render(); + } + }, + disconnect: { + + /** + Stop visualizing the source node and disconnect it. + */ + + value: function disconnect() { + if (this.source) { + this.source.disconnect(this.analyser); + this.source = null; + } + } + }, + click: { + value: function click() { + this.active = !this.active; + this.render(); + } + }, + customDestroy: { + value: function customDestroy() { + this.active = false; + } + } + }); + + return Oscilloscope; + })(Interface); + + module.exports = Oscilloscope; + +/***/ }), +/* 38 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; + + var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + /* + Main concept: + synth = new Nexus.Rack('elementID'); + + Transform all elements inside the div + synth.elementID will hold the first slider interface + + 2) In future, potentially writing a rack that is re-usable? + Could also take JSON + + new Nexus.Rack('#target',{ + pre: () => { + create some divs here, or some audio code + }, + interface: { + slider1: Nexus.add.slider({ + top:10, + left:10, + width:50, + height:100, + min: 0, + max: 100, + step: 1 + }), + wave1: Nexus.add.waveform({ + file: './path/to/file.mp3', + width:500, + height:100, + mode: 'range' + }) + }, + init: () => { + // some audio init code goes here... + } + }); + + */ + + var transform = _interopRequireWildcard(__webpack_require__(39)); + + var dom = _interopRequire(__webpack_require__(7)); + + var colors = __webpack_require__(1).colors; + + var Rack = (function () { + function Rack(target, settings) { + _classCallCheck(this, Rack); + + this.meta = {}; + this.meta.target = target; + this.meta.parent = dom.parseElement(target); // should be a generic function for parsing a 'target' argument that checks for string/DOM/jQUERY + this.meta.colors = {}; + + if (settings) { + this.meta.attribute = settings.attribute || "nexus-ui"; + this.meta.title = settings.name || false; + this.meta.open = settings.open || false; + } else { + this.meta.attribute = "nexus-ui"; + this.meta.title = false; + this.meta.open = false; + } + + var defaultColors = colors(); // jshint ignore:line + this.meta.colors.accent = defaultColors.accent; + this.meta.colors.fill = defaultColors.fill; + this.meta.colors.light = defaultColors.light; + this.meta.colors.dark = defaultColors.dark; + this.meta.colors.mediumLight = defaultColors.mediumLight; + this.meta.colors.mediumDark = defaultColors.mediumDark; + this.buildInterface(); + this.colorInterface(); + } + + _createClass(Rack, { + buildInterface: { + value: function buildInterface() { + var _this = this; + + this.meta.parent.style.boxSizing = "border-box"; + this.meta.parent.style.userSelect = "none"; + this.meta.parent.style.mozUserSelect = "none"; + this.meta.parent.style.webkitUserSelect = "none"; + + this.meta.contents = document.createElement("div"); + + while (this.meta.parent.childNodes.length > 0) { + this.meta.contents.appendChild(this.meta.parent.childNodes[0]); + } + + this.meta.contents.style.padding = "0px"; + this.meta.contents.style.boxSizing = "border-box"; + + if (this.meta.title) { + this.meta.titleBar = document.createElement("div"); + this.meta.titleBar.innerHTML = this.meta.title; + this.meta.titleBar.style.fontFamily = "arial"; + this.meta.titleBar.style.position = "relative"; + this.meta.titleBar.style.color = "#888"; + this.meta.titleBar.style.padding = "7px"; + this.meta.titleBar.style.fontSize = "12px"; + + this.meta.button = document.createElement("div"); + this.meta.button.style.position = "absolute"; + this.meta.button.style.top = "5px"; + this.meta.button.style.right = "5px"; + this.meta.button.innerHTML = "-"; + this.meta.button.style.padding = "0px 5px 2px"; + this.meta.button.style.lineHeight = "12px"; + this.meta.button.style.fontSize = "15px"; + + this.meta.button.style.cursor = "pointer"; + + this.meta.button.addEventListener("mouseover", function () { + _this.meta.button.style.backgroundColor = _this.meta.colors.mediumDark; + }); + this.meta.button.addEventListener("mouseleave", function () { + _this.meta.button.style.backgroundColor = _this.meta.colors.mediumLight; + }); + this.meta.button.addEventListener("click", function () { + if (_this.meta.open) { + _this.hide(); + } else { + _this.show(); + } + }); + + this.meta.titleBar.appendChild(this.meta.button); + + this.meta.parent.appendChild(this.meta.titleBar); + } + this.meta.parent.appendChild(this.meta.contents); + + // var width = this.meta.parent.style.width = getComputedStyle(this.meta.parent).getPropertyValue('width'); + // this.meta.parent.style.width = width; + + var ui = transform.section(this.meta.target, this.meta.attribute); + for (var key in ui) { + this[key] = ui[key]; + } + } + }, + colorInterface: { + value: function colorInterface() { + if (this.meta.title) { + this.meta.button.style.backgroundColor = this.meta.colors.mediumLight; + this.meta.button.style.border = "solid 0px " + this.meta.colors.fill; + this.meta.parent.style.border = "solid 1px " + this.meta.colors.mediumLight; + this.meta.parent.style.backgroundColor = this.meta.colors.light; + this.meta.titleBar.style.backgroundColor = this.meta.colors.fill; + } + } + }, + show: { + value: function show() { + this.meta.contents.style.display = "block"; + this.meta.open = true; + } + }, + hide: { + value: function hide() { + this.meta.contents.style.display = "none"; + this.meta.open = false; + } + }, + colorize: { + value: function colorize(type, color) { + for (var key in this) { + if (this[key].colorize) { + this[key].colorize(type, color); + } + } + this.meta.colors[type] = color; + this.colorInterface(); + } + }, + empty: { + value: function empty() { + for (var key in this) { + if (this[key].destroy) { + this[key].destroy(); + } + } + } + } + }); + + return Rack; + })(); + + module.exports = Rack; + +/***/ }), +/* 39 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + "use strict"; + + var dom = _interopRequire(__webpack_require__(7)); + + var Interfaces = _interopRequire(__webpack_require__(2)); + + var createInterfaceID = function (widget, interfaceIDs) { + var type = widget.type; + if (interfaceIDs[type]) { + interfaceIDs[type]++; + } else { + interfaceIDs[type] = 1; + } + return type + interfaceIDs[type]; + }; + + var element = function (element, type, options) { + options = options || {}; + for (var i = 0; i < element.attributes.length; i++) { + var att = element.attributes[i]; + // try { + // options[att.nodeName] = eval(att.nodeValue); + // } catch(e) { + options[att.nodeName] = att.nodeValue; + // } + } + type = type[0].toUpperCase() + type.slice(1); + var widget = new Interfaces[type](element, options); + widget.id = element.id; + return widget; + }; + + var section = function (parent, keyword) { + + keyword = keyword || "nexus-ui"; + + var interfaceIDs = {}; + + var container = dom.parseElement(parent); + + var ui = {}; + + var htmlElements = container.getElementsByTagName("*"); + var elements = []; + for (var i = 0; i < htmlElements.length; i++) { + elements.push(htmlElements[i]); + } + for (var i = 0; i < elements.length; i++) { + var type = elements[i].getAttribute(keyword); + if (type) { + var formattedType = false; + for (var key in Interfaces) { + if (type.toLowerCase() === key.toLowerCase()) { + formattedType = key; + } + } + console.log(formattedType); + var widget = element(elements[i], formattedType); + if (widget.id) { + ui[widget.id] = widget; + } else { + var id = createInterfaceID(widget, interfaceIDs); + ui[id] = widget; + } + } + } + + return ui; + }; + + var add = function (type, parent, options) { + var target = document.createElement("div"); + options = options || {}; + if (parent) { + parent = dom.parseElement(parent); + } else { + parent = document.body; + } + parent.appendChild(target); + options.target = target; + if (options.size) { + target.style.width = options.size[0] + "px"; + target.style.height = options.size[1] + "px"; + } + return element(target, type, options); + }; + + exports.element = element; + exports.section = section; + exports.add = add; + +/***/ }), +/* 40 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var math = _interopRequire(__webpack_require__(5)); + + var Tune = (function () { + function Tune() { + _classCallCheck(this, Tune); + + // the scale as ratios + this.scale = []; + + // i/o modes + this.mode = { + output: "frequency", + input: "step" + }; + + // ET major + this.etmajor = [261.62558, 293.664764, 329.627563, 349.228241, 391.995422, 440, 493.883301, 523.25116]; + + // Root frequency. + this.root = math.mtof(60); // * Math.pow(2,(60-69)/12); + + // default is a major scale + this.createScale(0, 2, 4, 5, 7, 9, 11); + } + + _createClass(Tune, { + note: { + + /* Return data in the mode you are in (freq, ratio, or midi) */ + + value: function note(input, octave) { + + var newvalue = undefined; + + if (this.mode.output === "frequency") { + newvalue = this.frequency(input, octave); + } else if (this.mode.output === "ratio") { + newvalue = this.ratio(input, octave); + } else if (this.mode.output === "MIDI") { + newvalue = this.MIDI(input, octave); + } else { + newvalue = this.frequency(input, octave); + } + + return newvalue; + } + }, + frequency: { + + /* Return freq data */ + + value: function frequency(stepIn, octaveIn) { + + if (this.mode.input === "midi" || this.mode.input === "MIDI") { + this.stepIn += 60; + } + + // what octave is our input + var octave = Math.floor(stepIn / this.scale.length); + + if (octaveIn) { + octave += octaveIn; + } + + // which scale degree (0 - scale length) is our input + var scaleDegree = stepIn % this.scale.length; + + while (scaleDegree < 0) { + scaleDegree += this.scale.length; + } + + var ratio = this.scale[scaleDegree]; + + var freq = this.root * ratio; + + freq = freq * Math.pow(2, octave); + + // truncate irrational numbers + freq = Math.floor(freq * 100000000000) / 100000000000; + + return freq; + } + }, + ratio: { + + /* Force return ratio data */ + + value: function ratio(stepIn, octaveIn) { + + if (this.mode.input === "midi" || this.mode.input === "MIDI") { + this.stepIn += 60; + } + + // what octave is our input + var octave = Math.floor(stepIn / this.scale.length); + + if (octaveIn) { + octave += octaveIn; + } + + // which scale degree (0 - scale length) is our input + var scaleDegree = stepIn % this.scale.length; + + // what ratio is our input to our key + var ratio = Math.pow(2, octave) * this.scale[scaleDegree]; + + ratio = Math.floor(ratio * 100000000000) / 100000000000; + + return ratio; + } + }, + MIDI: { + + /* Force return adjusted MIDI data */ + + value: function MIDI(stepIn, octaveIn) { + + var newvalue = this.frequency(stepIn, octaveIn); + + var n = 69 + 12 * Math.log(newvalue / 440) / Math.log(2); + + n = Math.floor(n * 1000000000) / 1000000000; + + return n; + } + }, + createScale: { + value: function createScale() { + var newScale = []; + for (var i = 0; i < arguments.length; i++) { + newScale.push(math.mtof(60 + arguments[i])); + } + this.loadScaleFromFrequencies(newScale); + } + }, + createJIScale: { + value: function createJIScale() { + this.scale = []; + for (var i = 0; i < arguments.length; i++) { + this.scale.push(arguments[i]); + } + } + }, + loadScaleFromFrequencies: { + value: function loadScaleFromFrequencies(freqs) { + this.scale = []; + for (var i = 0; i < freqs.length - 1; i++) { + this.scale.push(freqs[i] / freqs[0]); + } + } + }, + loadScale: { + + /* Load a new scale */ + + value: function loadScale(name) { + + /* load the scale */ + var freqs = this.scales[name].frequencies; + this.loadScaleFromFrequencies(freqs); + } + }, + search: { + + /* Search the names of tunings + Returns an array of names of tunings */ + + value: function search(letters) { + var possible = []; + for (var key in this.scales) { + if (key.toLowerCase().indexOf(letters.toLowerCase()) !== -1) { + possible.push(key); + } + } + return possible; + } + }, + chord: { + + /* Return a collection of notes as an array */ + + value: function chord(midis) { + var output = []; + for (var i = 0; i < midis.length; i++) { + output.push(this.note(midis[i])); + } + return output; + } + } + }); + + return Tune; + })(); + + module.exports = Tune; + +/***/ }), +/* 41 */ +/***/ (function(module, exports) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + //Disable jshint warning concerning trailing regular params + /*jshint -W138 */ + + var Radio = (function () { + //if non-existent buttons are switched, they are ignored + + function Radio() { + for (var _len = arguments.length, onVals = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + onVals[_key - 1] = arguments[_key]; + } + + var length = arguments[0] === undefined ? 3 : arguments[0]; + + _classCallCheck(this, Radio); + + //each optional 'onVals' argument switches on that value in the Radio if it exists + //In the example below, a 3-button radio is created, index 0 is switched on, index 1 is switched on then then attempted again producing an warning, and the final argument produces a warning because the index value does not exist. + //Example: + //` radio = new Radio(3, 0, 1, 1, 3); + //… [1,1,0] + + if (length < 0) { + length = 1; + } + + this.length = length; + this.onVals = onVals; + this.array = new Array(length).fill(0); + + if (onVals.length > 0) { + this.on.apply(this, onVals); + } + } + + _createClass(Radio, { + select: { + value: function select(value) { + this.array.fill(0); + this.array[value] = 1; + return this.array; + } + }, + flip: { + value: function flip() { + for (var _len = arguments.length, values = Array(_len), _key = 0; _key < _len; _key++) { + values[_key] = arguments[_key]; + } + + //flips the specified values. if no value is specified, flips all buttons + var a = this.array; + if (values.length > 0) { + values.forEach(function (v) { + if (v > a.length - 1) { + console.warn("Warning: AnonRadio[" + v + "] does not exist"); + } else { + a[v] = a[v] ? 0 : 1; + } + }); + } else { + a.forEach(function (v, i, arr) { + arr[i] = v ? 0 : 1; + }); + } + return a; + } + }, + on: { + value: function on() { + for (var _len = arguments.length, values = Array(_len), _key = 0; _key < _len; _key++) { + values[_key] = arguments[_key]; + } + + //switch on the specified values. if no value specified, flips on all buttons + var a = this.array; + if (values.length > 0) { + values.forEach(function (v) { + if (v > a.length - 1) { + console.warn("Warning: AnonRadio[" + v + "] exceeds size of object"); + } else { + if (a[v] === 1) { + console.warn("Warning: AnonRadio[" + v + "] was already on."); + } + a[v] = 1; + } + }); + } else { + a.fill(1); + } + return a; + } + }, + off: { + value: function off() { + for (var _len = arguments.length, values = Array(_len), _key = 0; _key < _len; _key++) { + values[_key] = arguments[_key]; + } + + //switch off the specified values. if no value specified, flips off all buttons + var a = this.array; + if (values.length > 0) { + values.forEach(function (v) { + a[v] = 0; + }); + } else { + a.fill(0); + } + return a; + } + } + }); + + return Radio; + })(); + + module.exports = Radio; + +/***/ }), +/* 42 */ +/***/ (function(module, exports, __webpack_require__) { + + var WAAClock = __webpack_require__(43) + + module.exports = WAAClock + if (typeof window !== 'undefined') window.WAAClock = WAAClock + + +/***/ }), +/* 43 */ +/***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(process) {var isBrowser = (typeof window !== 'undefined') + + var CLOCK_DEFAULTS = { + toleranceLate: 0.10, + toleranceEarly: 0.001 + } + + // ==================== Event ==================== // + var Event = function(clock, deadline, func) { + this.clock = clock + this.func = func + this._cleared = false // Flag used to clear an event inside callback + + this.toleranceLate = clock.toleranceLate + this.toleranceEarly = clock.toleranceEarly + this._latestTime = null + this._earliestTime = null + this.deadline = null + this.repeatTime = null + + this.schedule(deadline) + } + + // Unschedules the event + Event.prototype.clear = function() { + this.clock._removeEvent(this) + this._cleared = true + return this + } + + // Sets the event to repeat every `time` seconds. + Event.prototype.repeat = function(time) { + if (time === 0) + throw new Error('delay cannot be 0') + this.repeatTime = time + if (!this.clock._hasEvent(this)) + this.schedule(this.deadline + this.repeatTime) + return this + } + + // Sets the time tolerance of the event. + // The event will be executed in the interval `[deadline - early, deadline + late]` + // If the clock fails to execute the event in time, the event will be dropped. + Event.prototype.tolerance = function(values) { + if (typeof values.late === 'number') + this.toleranceLate = values.late + if (typeof values.early === 'number') + this.toleranceEarly = values.early + this._refreshEarlyLateDates() + if (this.clock._hasEvent(this)) { + this.clock._removeEvent(this) + this.clock._insertEvent(this) + } + return this + } + + // Returns true if the event is repeated, false otherwise + Event.prototype.isRepeated = function() { return this.repeatTime !== null } + + // Schedules the event to be ran before `deadline`. + // If the time is within the event tolerance, we handle the event immediately. + // If the event was already scheduled at a different time, it is rescheduled. + Event.prototype.schedule = function(deadline) { + this._cleared = false + this.deadline = deadline + this._refreshEarlyLateDates() + + if (this.clock.context.currentTime >= this._earliestTime) { + this._execute() + + } else if (this.clock._hasEvent(this)) { + this.clock._removeEvent(this) + this.clock._insertEvent(this) + + } else this.clock._insertEvent(this) + } + + Event.prototype.timeStretch = function(tRef, ratio) { + if (this.isRepeated()) + this.repeatTime = this.repeatTime * ratio + + var deadline = tRef + ratio * (this.deadline - tRef) + // If the deadline is too close or past, and the event has a repeat, + // we calculate the next repeat possible in the stretched space. + if (this.isRepeated()) { + while (this.clock.context.currentTime >= deadline - this.toleranceEarly) + deadline += this.repeatTime + } + this.schedule(deadline) + } + + // Executes the event + Event.prototype._execute = function() { + if (this.clock._started === false) return + this.clock._removeEvent(this) + + if (this.clock.context.currentTime < this._latestTime) + this.func(this) + else { + if (this.onexpired) this.onexpired(this) + console.warn('event expired') + } + // In the case `schedule` is called inside `func`, we need to avoid + // overrwriting with yet another `schedule`. + if (!this.clock._hasEvent(this) && this.isRepeated() && !this._cleared) + this.schedule(this.deadline + this.repeatTime) + } + + // Updates cached times + Event.prototype._refreshEarlyLateDates = function() { + this._latestTime = this.deadline + this.toleranceLate + this._earliestTime = this.deadline - this.toleranceEarly + } + + // ==================== WAAClock ==================== // + var WAAClock = module.exports = function(context, opts) { + var self = this + opts = opts || {} + this.tickMethod = opts.tickMethod || 'ScriptProcessorNode' + this.toleranceEarly = opts.toleranceEarly || CLOCK_DEFAULTS.toleranceEarly + this.toleranceLate = opts.toleranceLate || CLOCK_DEFAULTS.toleranceLate + this.context = context + this._events = [] + this._started = false + } + + // ---------- Public API ---------- // + // Schedules `func` to run after `delay` seconds. + WAAClock.prototype.setTimeout = function(func, delay) { + return this._createEvent(func, this._absTime(delay)) + } + + // Schedules `func` to run before `deadline`. + WAAClock.prototype.callbackAtTime = function(func, deadline) { + return this._createEvent(func, deadline) + } + + // Stretches `deadline` and `repeat` of all scheduled `events` by `ratio`, keeping + // their relative distance to `tRef`. In fact this is equivalent to changing the tempo. + WAAClock.prototype.timeStretch = function(tRef, events, ratio) { + events.forEach(function(event) { event.timeStretch(tRef, ratio) }) + return events + } + + // Removes all scheduled events and starts the clock + WAAClock.prototype.start = function() { + if (this._started === false) { + var self = this + this._started = true + this._events = [] + + if (this.tickMethod === 'ScriptProcessorNode') { + var bufferSize = 256 + // We have to keep a reference to the node to avoid garbage collection + this._clockNode = this.context.createScriptProcessor(bufferSize, 1, 1) + this._clockNode.connect(this.context.destination) + this._clockNode.onaudioprocess = function () { + process.nextTick(function() { self._tick() }) + } + } else if (this.tickMethod === 'manual') null // _tick is called manually + + else throw new Error('invalid tickMethod ' + this.tickMethod) + } + } + + // Stops the clock + WAAClock.prototype.stop = function() { + if (this._started === true) { + this._started = false + this._clockNode.disconnect() + } + } + + // ---------- Private ---------- // + + // This function is ran periodically, and at each tick it executes + // events for which `currentTime` is included in their tolerance interval. + WAAClock.prototype._tick = function() { + var event = this._events.shift() + + while(event && event._earliestTime <= this.context.currentTime) { + event._execute() + event = this._events.shift() + } + + // Put back the last event + if(event) this._events.unshift(event) + } + + // Creates an event and insert it to the list + WAAClock.prototype._createEvent = function(func, deadline) { + return new Event(this, deadline, func) + } + + // Inserts an event to the list + WAAClock.prototype._insertEvent = function(event) { + this._events.splice(this._indexByTime(event._earliestTime), 0, event) + } + + // Removes an event from the list + WAAClock.prototype._removeEvent = function(event) { + var ind = this._events.indexOf(event) + if (ind !== -1) this._events.splice(ind, 1) + } + + // Returns true if `event` is in queue, false otherwise + WAAClock.prototype._hasEvent = function(event) { + return this._events.indexOf(event) !== -1 + } + + // Returns the index of the first event whose deadline is >= to `deadline` + WAAClock.prototype._indexByTime = function(deadline) { + // performs a binary search + var low = 0 + , high = this._events.length + , mid + while (low < high) { + mid = Math.floor((low + high) / 2) + if (this._events[mid]._earliestTime < deadline) + low = mid + 1 + else high = mid + } + return low + } + + // Converts from relative time to absolute time + WAAClock.prototype._absTime = function(relTime) { + return relTime + this.context.currentTime + } + + // Converts from absolute time to relative time + WAAClock.prototype._relTime = function(absTime) { + return absTime - this.context.currentTime + } + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(44))) + +/***/ }), +/* 44 */ +/***/ (function(module, exports) { + + // shim for using process in browser + var process = module.exports = {}; + + // cached from whatever global is present so that test runners that stub it + // don't break things. But we need to wrap it in a try catch in case it is + // wrapped in strict mode code which doesn't define any globals. It's inside a + // function because try/catches deoptimize in certain engines. + + var cachedSetTimeout; + var cachedClearTimeout; + + function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); + } + function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); + } + (function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } + } ()) + function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + + } + function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + + } + var queue = []; + var draining = false; + var currentQueue; + var queueIndex = -1; + + function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } + } + + function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); + } + + process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } + }; + + // v8 likes predictible objects + function Item(fun, array) { + this.fun = fun; + this.array = array; + } + Item.prototype.run = function () { + this.fun.apply(null, this.array); + }; + process.title = 'browser'; + process.browser = true; + process.env = {}; + process.argv = []; + process.version = ''; // empty string to avoid regexp issues + process.versions = {}; + + function noop() {} + + process.on = noop; + process.addListener = noop; + process.once = noop; + process.off = noop; + process.removeListener = noop; + process.removeAllListeners = noop; + process.emit = noop; + process.prependListener = noop; + process.prependOnceListener = noop; + + process.listeners = function (name) { return [] } + + process.binding = function (name) { + throw new Error('process.binding is not supported'); + }; + + process.cwd = function () { return '/' }; + process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); + }; + process.umask = function() { return 0; }; + + +/***/ }), +/* 45 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + var clock = __webpack_require__(1).clock; + + var Interval = (function () { + function Interval(rate, func, on) { + _classCallCheck(this, Interval); + + this.rate = rate; + this.on = on; + this.clock = clock(); // jshint ignore:line + + this.pattern = [1]; + this.index = 0; + + this.event = func ? func : function () {}; + + if (this.on) { + this.start(); + } + } + + _createClass(Interval, { + _event: { + value: function _event(e) { + // if (this.pattern[this.index%this.pattern.length]) { + this.event(e); + // } + this.index++; + } + }, + stop: { + value: function stop() { + this.on = false; + this.interval.clear(); + } + }, + start: { + value: function start() { + this.on = true; + this.interval = this.clock.callbackAtTime(this._event.bind(this), this.clock.context.currentTime).repeat(this.rate / 1000).tolerance({ early: 0.1, late: 1 }); + } + }, + ms: { + value: function ms(newrate) { + if (this.on) { + var ratio = newrate / this.rate; + this.rate = newrate; + this.clock.timeStretch(this.clock.context.currentTime, [this.interval], ratio); + } else { + this.rate = newrate; + } + } + } + }); + + return Interval; + })(); + + module.exports = Interval; + +/***/ }) +/******/ ]) +}); +; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovLy93ZWJwYWNrL2Jvb3RzdHJhcCBiMjY5YWNlZjhjYWRhNzA4NDUwMiIsIndlYnBhY2s6Ly8vLi9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvbWFpbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9wb3NpdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC9zdmcuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwvbWF0aC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvY29yZS9pbnRlcmZhY2UuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwvZG9tLmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsL3V0aWwuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwvdG91Y2guanMiLCJ3ZWJwYWNrOi8vLy4vfi9ldmVudHMvZXZlbnRzLmpzIiwid2VicGFjazovLy8uL2xpYi9tb2RlbHMvc3RlcC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC9pbnRlcmFjdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvbW9kZWxzL3RvZ2dsZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zbGlkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2ludGVyZmFjZXMvdG9nZ2xlLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL2J1dHRvbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvY29tcG9uZW50cy9idXR0b250ZW1wbGF0ZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy90ZXh0YnV0dG9uLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL3JhZGlvYnV0dG9uLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL251bWJlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zZWxlY3QuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2ludGVyZmFjZXMvZGlhbC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9waWFuby5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zZXF1ZW5jZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21vZGVscy9tYXRyaXguanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21vZGVscy9zZXF1ZW5jZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvbW9kZWxzL2RydW5rLmpzIiwid2VicGFjazovLy8uL2xpYi9tb2RlbHMvY291bnRlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9wYW4yZC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy90aWx0LmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL211bHRpc2xpZGVyLmpzIiwid2VicGFjazovLy8uL2xpYi9jb21wb25lbnRzL3NsaWRlcnRlbXBsYXRlLmpzIiwid2VicGFjazovLy8uL2xpYi9pbnRlcmZhY2VzL3Bhbi5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9lbnZlbG9wZS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9zcGVjdHJvZ3JhbS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9tZXRlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvaW50ZXJmYWNlcy9vc2NpbGxvc2NvcGUuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2NvcmUvcmFjay5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC90cmFuc2Zvcm0uanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3R1bmluZy90dW5pbmcuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21vZGVscy9yYWRpby5qcyIsIndlYnBhY2s6Ly8vLi9+L3dhYWNsb2NrL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vd2FhY2xvY2svbGliL1dBQUNsb2NrLmpzIiwid2VicGFjazovLy8uL34vcHJvY2Vzcy9icm93c2VyLmpzIiwid2VicGFjazovLy8uL2xpYi90aW1lL2ludGVydmFsLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRCxPO0FDVkE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQWU7QUFDZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7OztBQ3RDQSxhQUFZLENBQUM7Ozs7S0FFTixPQUFPLHVDQUFNLENBQVk7O2tCQUVqQixPQUFPLEM7Ozs7Ozs7Ozs7Ozs7Ozs7U0NtSE4sTUFBTSxHQUFOLE1BQU07U0FHTixPQUFPLEdBQVAsT0FBTztTQUdQLEtBQUssR0FBTCxLQUFLOzs7O0FBN0hyQixhQUFZLENBQUM7O0tBRU4sVUFBVSx1Q0FBTSxDQUFlOztLQUMvQixJQUFJLHVDQUFNLENBQWE7O0tBQ3ZCLElBQUksdUNBQU0sRUFBYTs7S0FDdkIsSUFBSSx1Q0FBTSxFQUFpQjs7S0FDdEIsU0FBUywrQ0FBTSxFQUFrQjs7QUFFN0MsS0FBSSxPQUFPLEdBQUcsbUJBQU8sQ0FBQyxFQUFrQixDQUFDLENBQUM7QUFDMUMsS0FBSSxLQUFLLEdBQUcsbUJBQU8sQ0FBQyxFQUFnQixDQUFDLENBQUM7QUFDdEMsS0FBSSxLQUFLLEdBQUcsbUJBQU8sQ0FBQyxFQUFnQixDQUFDLENBQUM7QUFDdEMsS0FBSSxRQUFRLEdBQUcsbUJBQU8sQ0FBQyxFQUFtQixDQUFDLENBQUM7QUFDNUMsS0FBSSxNQUFNLEdBQUcsbUJBQU8sQ0FBQyxFQUFpQixDQUFDLENBQUM7O0tBRWpDLFFBQVEsdUNBQU0sRUFBVTs7S0FDeEIsUUFBUSx1Q0FBTSxFQUFpQjs7Ozs7O0tBT2hDLE9BQU87QUFFRSxZQUZULE9BQU8sQ0FFRyxPQUFPLEVBQUU7MkJBRm5CLE9BQU87O0FBSUwsVUFBSyxJQUFJLEdBQUcsSUFBSSxVQUFVLEVBQUU7QUFDeEIsV0FBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztNQUMvQjs7QUFFRCxVQUFLLElBQUksR0FBRyxJQUFJLElBQUksRUFBRTtBQUNsQixXQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO01BQ3pCOztBQUVELFNBQUksSUFBSSxHQUFHO0FBQ1QsYUFBUSxJQUFJO01BQ2IsQ0FBQzs7QUFFRixTQUFJLE1BQU0sR0FBRztBQUNYLGdCQUFXLE9BQU87QUFDbEIsY0FBUyxLQUFLO0FBQ2QsY0FBUyxLQUFLO0FBQ2QsaUJBQVksUUFBUTtBQUNwQixlQUFVLE1BQU07TUFDakIsQ0FBQzs7QUFFRixVQUFLLElBQUksR0FBRyxJQUFJLE1BQU0sRUFBRTtBQUN0QixXQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO01BQ3pCOztBQUVELFVBQUssSUFBSSxHQUFHLElBQUksSUFBSSxFQUFFO0FBQ3BCLFdBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7TUFDdkI7O0FBRUQsU0FBSSxjQUFjLEdBQUcsTUFBTSxDQUFDLFlBQVksSUFBSSxNQUFNLENBQUMsa0JBQWtCLENBQUM7QUFDdEUsU0FBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLElBQUksSUFBSSxjQUFjLEVBQUUsQ0FBQzs7QUFFaEQsU0FBSSxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO0FBQ3ZCLFNBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzs7QUFFM0MsU0FBSSxDQUFDLEtBQUssR0FBRyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDekMsU0FBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUNuQixTQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQzs7QUFFekIsU0FBSSxDQUFDLE1BQU0sR0FBRztBQUNaLGFBQU0sRUFBRSxNQUFNO0FBQ2QsV0FBSSxFQUFFLE1BQU07QUFDWixZQUFLLEVBQUUsTUFBTTtBQUNiLFdBQUksRUFBRSxNQUFNO0FBQ1osa0JBQVcsRUFBRSxNQUFNO0FBQ25CLGlCQUFVLEVBQUUsTUFBTTtNQUNuQixDQUFDOztBQUVGLFNBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO0FBQzNCLFNBQUksQ0FBQyxHQUFHLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQzs7QUFHekIsU0FBSSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDZCxVQUFLLElBQUksR0FBRyxJQUFJLFVBQVUsRUFBRTtBQUMxQixXQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBQyxHQUFHLENBQUMsQ0FBQztNQUM5Qzs7OztBQU9ELFNBQUksbUJBQW1CLEdBQUcsUUFBUSxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ2pFLFNBQUksc0JBQXNCLEdBQUcsd0NBQXdDLENBQUM7QUFDdEUsU0FBSSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3ZELHFCQUFnQixDQUFDLElBQUksR0FBRyxVQUFVLENBQUM7QUFDbkMscUJBQWdCLENBQUMsU0FBUyxHQUFHLHNCQUFzQixDQUFDO0FBQ3BELFNBQUksbUJBQW1CLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUNsQyxXQUFJLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVO0FBQzlDLGFBQU0sQ0FBQyxZQUFZLENBQUUsZ0JBQWdCLEVBQUUsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7TUFDL0QsTUFBTTtBQUNMLGVBQVEsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFDLHNCQUFzQixHQUFDLFVBQVcsQ0FBQyxDQUFDO01BQzlEOztJQUdKO0FBSEk7Z0JBM0VILE9BQU87QUFvRkwsWUFBTztZQUpBLFlBQUc7QUFDWixnQkFBTyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQ3RCO1lBRVUsVUFBQyxHQUFHLEVBQUU7QUFDZixhQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ2xCLGFBQUksQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDO0FBQ3BCLGFBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3hDLGFBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDcEI7Ozs7VUF6RkMsT0FBTzs7O0FBK0ZiLEtBQUksS0FBSyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7O0FBRW5CLFVBQVMsTUFBTSxHQUFHO0FBQ3JCLFVBQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQztFQUN2Qjs7QUFDTSxVQUFTLE9BQU8sR0FBRztBQUN0QixVQUFPLEtBQUssQ0FBQyxPQUFPLENBQUM7RUFDeEI7O0FBQ00sVUFBUyxLQUFLLEdBQUc7QUFDcEIsVUFBTyxLQUFLLENBQUMsS0FBSyxDQUFDO0VBQ3RCOztzQkFFYyxLQUFLLEM7Ozs7Ozs7O2tCQ2pJTDtBQUNiLFdBQVEsRUFBRSxtQkFBTyxDQUFDLENBQVksQ0FBQztBQUMvQixTQUFNLEVBQUUsbUJBQU8sQ0FBQyxFQUFVLENBQUM7QUFDM0IsU0FBTSxFQUFFLG1CQUFPLENBQUMsRUFBVSxDQUFDOzs7QUFHM0IsU0FBTSxFQUFFLG1CQUFPLENBQUMsRUFBVSxDQUFDO0FBQzNCLGFBQVUsRUFBRSxtQkFBTyxDQUFDLEVBQWMsQ0FBQztBQUNuQyxjQUFXLEVBQUUsbUJBQU8sQ0FBQyxFQUFlLENBQUM7QUFDckMsU0FBTSxFQUFFLG1CQUFPLENBQUMsRUFBVSxDQUFDO0FBQzNCLFNBQU0sRUFBRSxtQkFBTyxDQUFDLEVBQVUsQ0FBQztBQUMzQixPQUFJLEVBQUUsbUJBQU8sQ0FBQyxFQUFRLENBQUM7QUFDdkIsUUFBSyxFQUFFLG1CQUFPLENBQUMsRUFBUyxDQUFDO0FBQ3pCLFlBQVMsRUFBRSxtQkFBTyxDQUFDLEVBQWEsQ0FBQztBQUNqQyxRQUFLLEVBQUUsbUJBQU8sQ0FBQyxFQUFTLENBQUM7QUFDekIsT0FBSSxFQUFFLG1CQUFPLENBQUMsRUFBUSxDQUFDO0FBQ3ZCLGNBQVcsRUFBRSxtQkFBTyxDQUFDLEVBQWUsQ0FBQztBQUNyQyxNQUFHLEVBQUUsbUJBQU8sQ0FBQyxFQUFPLENBQUM7QUFDckIsV0FBUSxFQUFFLG1CQUFPLENBQUMsRUFBWSxDQUFDO0FBQy9CLGNBQVcsRUFBRSxtQkFBTyxDQUFDLEVBQWUsQ0FBQztBQUNyQyxRQUFLLEVBQUUsbUJBQU8sQ0FBQyxFQUFTLENBQUM7QUFDekIsZUFBWSxFQUFFLG1CQUFPLENBQUMsRUFBZ0IsQ0FBQztFQUN4QyxDOzs7Ozs7O0FDckJELGFBQVksQ0FBQzs7Ozs7Ozs7Ozs7O0FBRWIsS0FBSSxHQUFHLEdBQUcsbUJBQU8sQ0FBQyxDQUFhLENBQUMsQ0FBQztBQUNqQyxLQUFJLFNBQVMsR0FBRyxtQkFBTyxDQUFDLENBQW1CLENBQUMsQ0FBQztBQUM3QyxLQUFJLElBQUksR0FBRyxtQkFBTyxDQUFDLEVBQWdCLENBQUMsQ0FBQzs7S0FDekIsV0FBVywrQ0FBTSxFQUFxQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0tBdUM3QixRQUFRO0FBRWhCLFlBRlEsUUFBUSxHQUViOzJCQUZLLFFBQVE7O0FBSXpCLFNBQUksT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7O0FBRXhCLFNBQUksUUFBUSxHQUFHO0FBQ2IsYUFBUSxDQUFDLEdBQUcsRUFBQyxHQUFHLENBQUM7QUFDakIsYUFBUSxVQUFVO0FBQ2xCLGFBQVEsQ0FBQztBQUNULGFBQVEsQ0FBQztBQUNULGNBQVMsQ0FBQztBQUNWLFVBQUssR0FBRztBQUNSLGFBQVEsQ0FBQztBQUNULGFBQVEsQ0FBQztBQUNULGNBQVMsQ0FBQztBQUNWLFVBQUssR0FBRztNQUNULENBQUM7O0FBRUYsZ0NBbkJpQixRQUFRLDZDQW1CbkIsU0FBUyxFQUFDLE9BQU8sRUFBQyxRQUFRLEVBQUU7O0FBR2xDLFNBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxJQUFJLENBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUUsQ0FBQztBQUNuRyxTQUFJLENBQUMsRUFBRSxHQUFHLElBQUksSUFBSSxDQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFFLENBQUM7O0FBRW5HLFNBQUksQ0FBQyxRQUFRLEdBQUc7QUFDZCxRQUFDLEVBQUUsSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFDLFlBQVksRUFBQyxDQUFDLENBQUMsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pGLFFBQUMsRUFBRSxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUMsVUFBVSxFQUFDLENBQUMsQ0FBQyxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUMsQ0FBQyxDQUFDLENBQUM7TUFDeEYsQ0FBQztBQUNGLFNBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQztBQUMzQyxTQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUM7O0FBRTNDLFNBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNaLFNBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUVmOzthQW5Da0IsUUFBUTs7Z0JBQVIsUUFBUTtBQXFDM0IsbUJBQWM7Y0FBQSwwQkFBRzs7QUFFZixhQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDakMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXJDOztBQUVELGtCQUFhO2NBQUEseUJBQUc7O0FBRVosYUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2RCxhQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFDOztBQUV2RCxhQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7O0FBRXRELGFBQUksQ0FBQyxVQUFVLEdBQUc7QUFDaEIsY0FBRyxFQUFFLEVBQUMsRUFBRSxJQUFJLENBQUMsYUFBYSxHQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQ3hDLENBQUM7QUFDRixhQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7O0FBRTdDLGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBQyxJQUFJLENBQUMsS0FBSyxHQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFDLGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBQyxJQUFJLENBQUMsTUFBTSxHQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNDLGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25EOztBQUVELG1CQUFjO2NBQUEsMEJBQUc7QUFDYixhQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDdEQsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEQ7O0FBRUQsV0FBTTtjQUFBLGtCQUFHO0FBQ1AsYUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFOztBQUVoQixlQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztVQUNoRCxNQUFNOztBQUVMLGVBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1VBQ2pEOztBQUVELGFBQUksQ0FBQyxlQUFlLEdBQUc7QUFDckIsWUFBQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLO0FBQ2xDLFlBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNO1VBQ2xELENBQUM7O0FBRUYsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDcEQsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckQ7O0FBR0QsVUFBSztjQUFBLGlCQUFHO0FBQ04sYUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7QUFDcEMsYUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7QUFDcEMsYUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2I7O0FBRUQsU0FBSTtjQUFBLGdCQUFHO0FBQ0wsYUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO0FBQ2hCLGVBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbkMsZUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNuQyxlQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUUsQ0FBQztBQUM5QyxlQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUUsQ0FBQztBQUM5QyxlQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQztBQUNqQixjQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLO0FBQ2hCLGNBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUs7WUFDakIsQ0FBQyxDQUFDO0FBQ0gsZUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1VBQ2Y7UUFDRjs7QUFFRCxZQUFPO2NBQUEsbUJBQUc7QUFDUixhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZjs7QUFZRyxNQUFDOzs7Ozs7OztZQUpBLFlBQUc7QUFDTixnQkFBTyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztRQUN0QjtZQUVJLFVBQUMsS0FBSyxFQUFFO0FBQ1gsYUFBSSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDdEIsYUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUM7QUFDakIsWUFBQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSztBQUNoQixZQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLO1VBQ2pCLENBQUMsQ0FBQztBQUNILGFBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNmOztBQVlHLE1BQUM7Ozs7Ozs7O1lBSkEsWUFBRztBQUNOLGdCQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDO1FBQ3RCO1lBRUksVUFBQyxLQUFLLEVBQUU7QUFDWCxhQUFJLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN0QixhQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQztBQUNqQixZQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLO0FBQ2hCLFlBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUs7VUFDakIsQ0FBQyxDQUFDO0FBQ0gsYUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2Y7O0FBSUcsZUFBVTtZQUFBLFlBQUc7QUFDZixnQkFBTztBQUNMLFlBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVU7QUFDckIsWUFBQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVTtVQUN0QixDQUFDO1FBQ0g7O0FBVUcsU0FBSTs7Ozs7OztZQUpBLFlBQUc7QUFDVCxnQkFBTyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQztRQUNwQjtZQUVPLFVBQUMsQ0FBQyxFQUFFO0FBQ1YsYUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQ2hCLGFBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNmOztBQVVHLFNBQUk7Ozs7Ozs7WUFKQSxZQUFHO0FBQ1QsZ0JBQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUM7UUFDcEI7WUFFTyxVQUFDLENBQUMsRUFBRTtBQUNWLGFBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUNoQixhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZjs7QUFXRyxTQUFJOzs7Ozs7O1lBSkEsWUFBRztBQUNULGdCQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDO1FBQ3BCO1lBRU8sVUFBQyxDQUFDLEVBQUU7QUFDVixhQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDaEIsYUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2Y7O0FBV0csU0FBSTs7Ozs7OztZQUpBLFlBQUc7QUFDVCxnQkFBTyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQztRQUNwQjtZQUVPLFVBQUMsQ0FBQyxFQUFFO0FBQ1YsYUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQ2hCLGFBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNmOztBQVdHLFVBQUs7Ozs7Ozs7WUFKQSxZQUFHO0FBQ1YsZ0JBQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUM7UUFDckI7WUFFUSxVQUFDLENBQUMsRUFBRTtBQUNYLGFBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztBQUNqQixhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZjs7QUFXRyxVQUFLOzs7Ozs7O1lBSkEsWUFBRztBQUNWLGdCQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDO1FBQ3JCO1lBRVEsVUFBQyxDQUFDLEVBQUU7QUFDWCxhQUFJLENBQUMsRUFBRSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7QUFDakIsYUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2Y7O0FBV0csU0FBSTs7Ozs7Ozs7WUFIQSxZQUFHO0FBQ1QsZ0JBQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQzdCO1lBQ08sVUFBQyxDQUFDLEVBQUU7QUFDVixhQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLGFBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7UUFDMUI7Ozs7VUExUGtCLFFBQVE7SUFBUyxTQUFTOztrQkFBMUIsUUFBUSxDOzs7Ozs7QUM3QzdCLGFBQVksQ0FBQzs7QUFFYixLQUFJLElBQUksR0FBRyxtQkFBTyxDQUFDLENBQWMsQ0FBQyxDQUFDOztrQkFFcEI7O0FBRWIsU0FBTSxFQUFFLFVBQUMsSUFBSSxFQUFLO0FBQ2hCLFlBQU8sUUFBUSxDQUFDLGVBQWUsQ0FBQyw0QkFBNEIsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNyRTs7QUFFRCxNQUFHLEVBQUUsVUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFLOztBQUUzQyxTQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztBQUMvQyxTQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQzs7QUFFL0MsU0FBSSxZQUFZLEdBQUcsUUFBUSxHQUFHLFVBQVUsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQzs7QUFFNUQsU0FBSSxDQUFDLEdBQUcsQ0FDSixHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUMsR0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsR0FBQyxDQUFDLEVBQ3pCLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxZQUFZLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUMsQ0FBQyxDQUM1RCxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQzs7QUFFWixZQUFPLENBQUMsQ0FBQztJQUNWOztBQUVELGlCQUFjLEVBQUUsVUFBQyxJQUFJLEVBQUMsYUFBYSxFQUFLOztBQUV0QyxTQUFJLEVBQUUsR0FBRyxVQUFVLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUM1QyxTQUFJLEtBQUssR0FBRyxFQUFFLENBQUM7O0FBRWYsU0FBSSxRQUFRLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQyw0QkFBNEIsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0FBQ3hGLGFBQVEsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ2hDLGFBQVEsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ25DLGFBQVEsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ25DLGFBQVEsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDOztBQUVsQyxTQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDOztBQUUzQixVQUFLLElBQUksQ0FBQyxHQUFDLENBQUMsRUFBQyxDQUFDLEdBQUMsYUFBYSxFQUFDLENBQUMsRUFBRSxFQUFFO0FBQ2hDLFdBQUksS0FBSSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsNEJBQTRCLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDMUUsWUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxHQUFDLENBQUMsQ0FBQyxDQUFDOzs7QUFHbEMsZUFBUSxDQUFDLFdBQVcsQ0FBQyxLQUFJLENBQUMsQ0FBQztBQUMzQixZQUFLLENBQUMsSUFBSSxDQUFDLEtBQUksQ0FBQyxDQUFDO01BQ2xCOztBQUVELFlBQU87QUFDTCxTQUFFLEVBQUUsRUFBRTtBQUNOLFlBQUssRUFBRSxLQUFLO0FBQ1osY0FBTyxFQUFFLFFBQVE7TUFDbEIsQ0FBQztJQUVIOztFQUVGLEM7Ozs7OztBQ3ZERCxhQUFZLENBQUM7Ozs7Ozs7Ozs7Ozs7O0FBY2IsUUFBTyxDQUFDLElBQUksR0FBRyxVQUFDLEtBQUssRUFBQyxHQUFHLEVBQUMsR0FBRyxFQUFLO0FBQ2hDLFVBQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBQyxHQUFHLENBQUMsRUFBQyxHQUFHLENBQUMsQ0FBQztFQUMxQyxDQUFDOztBQUVGLFFBQU8sQ0FBQyxTQUFTLEdBQUcsVUFBQyxLQUFLLEVBQUMsR0FBRyxFQUFDLEdBQUcsRUFBSztBQUNyQyxVQUFTLENBQUMsS0FBSyxHQUFDLEdBQUcsS0FBSyxHQUFHLEdBQUMsR0FBRyxDQUFDLENBQUc7RUFDcEMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7QUFjRixRQUFPLENBQUMsS0FBSyxHQUFHLFVBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBSztBQUN2RCxPQUFJLEtBQUssS0FBSyxLQUFLLEVBQUU7QUFDbkIsWUFBTyxNQUFNLENBQUM7SUFDZjtBQUNELFVBQVMsQ0FBQyxLQUFLLEdBQUcsS0FBSyxLQUFLLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSyxLQUFLLEdBQUcsS0FBSyxDQUFDLEdBQUksTUFBTSxDQUFDO0VBQzNFLENBQUM7O0FBRUYsUUFBTyxDQUFDLE9BQU8sR0FBRyxVQUFDLENBQUMsRUFBQyxDQUFDLEVBQUs7QUFDekIsT0FBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUMsQ0FBQyxHQUFHLENBQUMsR0FBQyxDQUFDLENBQUMsQ0FBQzs7QUFFN0IsT0FBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUIsT0FBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFO0FBQ2IsVUFBSyxHQUFHLEtBQUssR0FBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUcsQ0FBQztJQUMvQjtBQUNELFVBQU8sRUFBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUMsQ0FBQztFQUNsQyxDQUFDOztBQUVGLFFBQU8sQ0FBQyxXQUFXLEdBQUcsVUFBUyxNQUFNLEVBQUUsS0FBSyxFQUFDO0FBQzNDLE9BQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDMUIsT0FBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMxQixVQUFPLEVBQUMsQ0FBQyxFQUFFLE1BQU0sR0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLE1BQU0sR0FBQyxHQUFHLEdBQUMsQ0FBQyxDQUFDLEVBQUMsQ0FBQztFQUMxQyxDQUFDOzs7Ozs7Ozs7OztBQWFGLFFBQU8sQ0FBQyxLQUFLLEdBQUcsVUFBUyxJQUFJLEVBQUUsS0FBSyxFQUFFO0FBQ3BDLFVBQU8sVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztFQUN4QyxDQUFDOztBQUVGLFFBQU8sQ0FBQyxNQUFNLEdBQUcsVUFBVSxLQUFLLEVBQUU7QUFDaEMsVUFBTyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztFQUN6QyxDQUFDOzs7Ozs7Ozs7QUFTRixRQUFPLENBQUMsSUFBSSxHQUFHLFVBQVMsSUFBSSxFQUFFO0FBQzVCLFVBQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUcsQ0FBQyxJQUFJLEdBQUMsRUFBRSxJQUFFLEVBQUUsQ0FBRSxHQUFHLEdBQUcsQ0FBQztFQUMxQyxDQUFDOzs7Ozs7Ozs7Ozs7QUFZRixRQUFPLENBQUMsTUFBTSxHQUFHLFVBQVMsR0FBRyxFQUFDLEdBQUcsRUFBQyxHQUFHLEVBQUU7QUFDckMsVUFBTyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztFQUNoQyxDQUFDOzs7Ozs7Ozs7QUFTRixRQUFPLENBQUMsSUFBSSxHQUFHLFlBQVc7QUFDeEIsVUFBTyxTQUFTLENBQUMsRUFBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztFQUN0RCxDQUFDOzs7Ozs7Ozs7Ozs7QUFZRixRQUFPLENBQUMsTUFBTSxHQUFHLFVBQVMsR0FBRyxFQUFFO0FBQzdCLFVBQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUMsR0FBRyxDQUFDLENBQUM7RUFDeEIsQ0FBQzs7Ozs7Ozs7Ozs7QUFXRixRQUFPLENBQUMsRUFBRSxHQUFHLFVBQVMsTUFBTSxFQUFDLE1BQU0sRUFBRTtBQUNuQyxPQUFJLENBQUMsTUFBTSxFQUFFO0FBQ1gsV0FBTSxHQUFHLE1BQU0sQ0FBQztBQUNoQixXQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ1o7QUFDRCxPQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBQyxNQUFNLENBQUMsQ0FBQztBQUNsQyxPQUFJLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBQyxNQUFNLENBQUMsQ0FBQztBQUNuQyxVQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFFLElBQUksR0FBQyxHQUFHLENBQUMsR0FBQyxHQUFHLENBQUMsQ0FBQztFQUNqRCxDQUFDOzs7Ozs7Ozs7OztBQVdGLFFBQU8sQ0FBQyxFQUFFLEdBQUcsVUFBUyxNQUFNLEVBQUMsTUFBTSxFQUFFO0FBQ25DLE9BQUksQ0FBQyxNQUFNLEVBQUU7QUFDWCxXQUFNLEdBQUcsTUFBTSxDQUFDO0FBQ2hCLFdBQU0sR0FBRyxDQUFDLENBQUM7SUFDWjtBQUNELE9BQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ2xDLE9BQUksSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ25DLFVBQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFFLElBQUksR0FBQyxHQUFHLENBQUMsR0FBQyxHQUFHLENBQUM7RUFDckMsQ0FBQzs7QUFHRixRQUFPLENBQUMsS0FBSyxHQUFHLFVBQVMsS0FBSyxFQUFDLEdBQUcsRUFBQyxHQUFHLEVBQUU7QUFDdEMsUUFBSyxFQUFFLENBQUM7QUFDUixPQUFJLEtBQUssSUFBSSxHQUFHLEVBQUU7QUFDaEIsVUFBSyxHQUFHLEdBQUcsQ0FBQztJQUNiO0FBQ0QsVUFBTyxLQUFLLENBQUM7RUFDZCxDQUFDOzs7Ozs7Ozs7QUFTRixRQUFPLENBQUMsT0FBTyxHQUFHLFVBQVMsSUFBSSxFQUFFO0FBQy9CLE9BQUksS0FBSyxHQUFHLENBQUMsQ0FBQztBQUNkLFFBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsTUFBTSxFQUFDLENBQUMsRUFBRSxFQUFFO0FBQzlCLFVBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEI7QUFDRCxVQUFPLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0VBQzVCLENBQUM7Ozs7Ozs7Ozs7OztBQVlGLFFBQU8sQ0FBQyxRQUFRLEdBQUcsVUFBUyxFQUFFLEVBQUMsRUFBRSxFQUFDLEVBQUUsRUFBQyxFQUFFLEVBQUU7QUFDdkMsT0FBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNoQixPQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2hCLFVBQU8sSUFBSSxDQUFDLElBQUksQ0FBRSxDQUFDLEdBQUMsQ0FBQyxHQUFHLENBQUMsR0FBQyxDQUFDLENBQUUsQ0FBQztFQUMvQixDQUFDOztBQUVGLFFBQU8sQ0FBQyxRQUFRLEdBQUcsVUFBUyxJQUFJLEVBQUU7QUFDaEMsVUFBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztFQUM5QixDQUFDOzs7Ozs7Ozs7QUFTRixRQUFPLENBQUMsSUFBSSxHQUFHLFlBQW1CO09BQVYsSUFBSSxnQ0FBQyxHQUFHOztBQUM5QixPQUFJLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRTtBQUMxQixZQUFPLENBQUMsQ0FBQztJQUNWLE1BQU07QUFDTCxZQUFPLENBQUMsQ0FBQztJQUNWO0VBQ0YsQzs7Ozs7O0FDN05ELGFBQVksQ0FBQzs7Ozs7Ozs7OztBQUViLEtBQUksR0FBRyxHQUFHLG1CQUFPLENBQUMsQ0FBYSxDQUFDLENBQUM7QUFDakMsS0FBSSxHQUFHLEdBQUcsbUJBQU8sQ0FBQyxDQUFhLENBQUMsQ0FBQztBQUNqQyxLQUFJLElBQUksR0FBRyxtQkFBTyxDQUFDLENBQWMsQ0FBQyxDQUFDO0FBQ25DLEtBQUksS0FBSyxHQUFHLG1CQUFPLENBQUMsQ0FBZSxDQUFDLENBQUM7QUFDckMsS0FBTSxZQUFZLEdBQUcsbUJBQU8sQ0FBQyxFQUFRLENBQUMsQ0FBQzs7S0FFOUIsTUFBTSx1QkFBUSxDQUFTLEVBQXZCLE1BQU07Ozs7OztLQUtNLFNBQVM7QUFFakIsWUFGUSxTQUFTLENBRWhCLElBQUksRUFBQyxPQUFPLEVBQUMsUUFBUSxFQUFFOzJCQUZoQixTQUFTOztBQUcxQixnQ0FIaUIsU0FBUyw2Q0FHbEI7QUFDUixTQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDO0FBQ2xDLFNBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUMsT0FBTyxFQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzFELFNBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO0FBQ2hCLFNBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO0FBQ2xCLFNBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO0FBQ2pCLFNBQUksYUFBYSxHQUFHLE1BQU0sRUFBRSxDQUFDO0FBQzdCLFNBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUM7QUFDMUMsU0FBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQztBQUN0QyxTQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDO0FBQ3hDLFNBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUM7QUFDdEMsU0FBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEdBQUcsYUFBYSxDQUFDLFdBQVcsQ0FBQztBQUNwRCxTQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsR0FBRyxhQUFhLENBQUMsVUFBVSxDQUFDO0lBQ25EOzthQWhCa0IsU0FBUzs7Z0JBQVQsU0FBUztBQWtCNUIsa0JBQWE7Y0FBQSx1QkFBQyxJQUFJLEVBQUMsT0FBTyxFQUFDLFFBQVEsRUFBRTs7QUFFbkMsZ0JBQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDMUIsaUJBQVEsQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pELGlCQUFRLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQzs7QUFFdEIsYUFBSSxRQUFRLEdBQUc7QUFDYixtQkFBVSxRQUFRLENBQUMsSUFBSTtBQUN2QixtQkFBVSxFQUFFO0FBQ1osMkJBQWtCLElBQUk7QUFDdEIsa0JBQVMsaUJBQVcsRUFBRTtBQUN0QixzQkFBYSxLQUFLO1VBQ25CLENBQUM7O0FBRUYsY0FBSyxJQUFJLEdBQUcsSUFBSSxRQUFRLEVBQUU7QUFDeEIsbUJBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7VUFDL0I7O0FBRUQsY0FBSyxJQUFJLENBQUMsR0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7O0FBRWhDLGVBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzs7QUFFdEIsZUFBSyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFHO0FBQzVCLGtCQUFNLElBQUksR0FBRyxJQUFJLE9BQU8sRUFBRztBQUN6Qix1QkFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztjQUM5Qjs7QUFBQSxZQUVGLE1BQU0sSUFBSSxPQUFPLE9BQU8sS0FBSyxVQUFVLEVBQUU7QUFDeEMscUJBQVEsQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDOztZQUUxQixNQUFNLElBQUksT0FBTyxDQUFDLE1BQU0sSUFBRSxDQUFDLEVBQUU7O0FBRTVCLGlCQUFJLEdBQUcsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQyxxQkFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQztZQUN6QjtVQUNGOzs7OztBQUtELGFBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7OztBQUdoRCxhQUFJLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sWUFBWSxXQUFXLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFO0FBQzVFLGVBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsRUFBRTtBQUN6QyxpQkFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3pDO1VBQ0Y7Ozs7QUFJRCxhQUFJLFFBQVEsQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksUUFBUSxDQUFDLGNBQWMsRUFBRTtBQUM1RSxlQUFJLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDOUIsZUFBSSxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLGVBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztBQUM1QyxlQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7VUFDL0MsTUFBTSxJQUFJLFFBQVEsQ0FBQyxjQUFjLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFOztBQUV6RCxlQUFJLENBQUMsS0FBSyxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDL0csZUFBSSxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBQyxFQUFFLENBQUMsQ0FBQyxDQUFDOztBQUVqSCxlQUFJLElBQUksQ0FBQyxLQUFLLElBQUUsSUFBSSxFQUFFO0FBQ3BCLGlCQUFJLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckMsaUJBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztZQUNqRTtBQUNELGVBQUksSUFBSSxDQUFDLE1BQU0sSUFBRSxJQUFJLEVBQUU7QUFDckIsaUJBQUksQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QyxpQkFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1lBQ3BFO1VBRUYsTUFBTTtBQUNMLG1CQUFRLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUM7QUFDckMsZUFBSSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlCLGVBQUksQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztVQUNoQzs7O0FBR0QsYUFBSSxRQUFRLENBQUMsS0FBSyxFQUFFO0FBQ2xCLGVBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1VBQ2hELE1BQU07QUFDTCxlQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztVQUNwQjs7QUFFRCxnQkFBTyxRQUFRLENBQUM7UUFFakI7O0FBRUQsU0FBSTtjQUFBLGdCQUFHO0FBQ0wsYUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0FBQ2xCLGFBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztBQUN0QixhQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7QUFDckIsYUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO0FBQ3ZCLGFBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztBQUN0QixhQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDckI7O0FBRUQsZUFBVTtjQUFBLHNCQUFHO0FBQ1gsYUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2pDLGFBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDOUMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNoRCxhQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdkM7O0FBRUQsbUJBQWM7Y0FBQSwwQkFBRyxFQUFFOztBQUNuQixrQkFBYTtjQUFBLHlCQUFHLEVBQUU7O0FBQ2xCLG1CQUFjO2NBQUEsMEJBQUcsRUFBRTs7QUFFbkIsb0JBQWU7Y0FBQSwyQkFBRzs7O0FBRWhCLGFBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQzs7O0FBR2hFLGFBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtBQUNoQixlQUFJLENBQUMsaUJBQWlCLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLGFBQUc7b0JBQUksTUFBSyxRQUFRLENBQUMsR0FBRyxDQUFDO1lBQUEsQ0FBQyxDQUFDO0FBQ2pGLGVBQUksQ0FBQyxpQkFBaUIsQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsYUFBRztvQkFBSSxNQUFLLFlBQVksQ0FBQyxHQUFHLENBQUM7WUFBQSxDQUFDLENBQUM7QUFDcEYsZUFBSSxDQUFDLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxhQUFHO29CQUFJLE1BQUssZUFBZSxDQUFDLEdBQUcsQ0FBQztZQUFBLENBQUMsQ0FBQztVQUN2RjtBQUNELGFBQUksQ0FBQyxZQUFZLEdBQUcsYUFBRztrQkFBSSxNQUFLLE9BQU8sQ0FBQyxHQUFHLENBQUM7VUFBQSxDQUFDO0FBQzdDLGFBQUksQ0FBQyxlQUFlLEdBQUcsYUFBRztrQkFBSSxNQUFLLFVBQVUsQ0FBQyxHQUFHLENBQUM7VUFBQSxDQUFDO0FBQ25ELGFBQUksQ0FBQyxpQkFBaUIsQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsYUFBRztrQkFBSSxNQUFLLFFBQVEsQ0FBQyxHQUFHLENBQUM7VUFBQSxDQUFDLENBQUM7UUFDakY7O0FBRUQsaUJBQVk7Y0FBQSx3QkFBRztBQUNiLGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7UUFDdkM7O0FBRUQsYUFBUTtjQUFBLGtCQUFDLENBQUMsRUFBRTs7O0FBR1YsYUFBSSxJQUFJLENBQUMsT0FBTyxZQUFZLFdBQVcsRUFBRTtBQUN2QyxlQUFJLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUMsRUFBRSxDQUFDLENBQUM7VUFDckc7OztBQUdELGFBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDN0MsYUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDNUMsYUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7QUFDcEIsYUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ2IsYUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUMzRSxhQUFJLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBQy9FLGFBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDbkIsVUFBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBQ25CLFVBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUNyQjs7QUFFRCxZQUFPO2NBQUEsaUJBQUMsQ0FBQyxFQUFFOzs7QUFDVCxhQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtBQUNkLGVBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzVDLGVBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNaLGVBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ2pCLHFCQUFVLENBQUMsWUFBTTtBQUFFLG1CQUFLLElBQUksR0FBRyxLQUFLLENBQUM7WUFBRSxFQUFDLEVBQUUsQ0FBQyxDQUFDO1VBQzdDO0FBQ0QsVUFBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBQ25CLFVBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUNyQjs7QUFFRCxlQUFVO2NBQUEsb0JBQUMsQ0FBQyxFQUFFO0FBQ1osYUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDNUMsYUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7QUFDckIsYUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ2YsYUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUNyQixpQkFBUSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDNUQsaUJBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBQzdELFVBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztBQUNuQixVQUFDLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDckI7O0FBRUQsVUFBSztjQUFBLGlCQUFHLEVBRVA7O0FBRUQsU0FBSTtjQUFBLGdCQUFHLEVBRU47O0FBRUQsWUFBTztjQUFBLG1CQUFHLEVBRVQ7O0FBS0QsYUFBUTs7OztjQUFBLGtCQUFDLENBQUMsRUFBRTtBQUNWLGFBQUksSUFBSSxDQUFDLE9BQU8sWUFBWSxXQUFXLEVBQUU7QUFDdkMsZUFBSSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFDLEVBQUUsQ0FBQyxDQUFDO1VBQ3JHO0FBQ0QsYUFBSSxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM3QyxhQUFJLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM1QyxhQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztBQUNwQixhQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsYUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNuQixVQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDbkIsVUFBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3JCOztBQUVELGlCQUFZO2NBQUEsc0JBQUMsQ0FBQyxFQUFFO0FBQ2QsYUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO0FBQ2hCLGVBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzVDLGVBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUNqQixZQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDbkIsWUFBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO1VBQ3JCO1FBQ0Y7O0FBRUQsb0JBQWU7Y0FBQSx5QkFBQyxDQUFDLEVBQUU7QUFDakIsYUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDN0MsYUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7QUFDckIsYUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0FBQ3BCLGFBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDckIsVUFBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBQ25CLFVBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUNyQjs7QUFFRCxVQUFLO2NBQUEsaUJBQUc7QUFDTixhQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDZDs7QUFFRCxjQUFTO2NBQUEscUJBQUc7QUFDVixhQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDYjs7QUFFRCxpQkFBWTtjQUFBLHdCQUFHO0FBQ2IsYUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2hCOztBQVVELFdBQU07Ozs7Ozs7Ozs7O2NBQUEsZ0JBQUMsS0FBSyxFQUFDLE1BQU0sRUFBRTtBQUNuQixhQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztBQUNuQixhQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztBQUNyQixhQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBQyxJQUFJLENBQUM7QUFDMUMsYUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUMsSUFBSSxDQUFDO0FBQzVDLGFBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDOUMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNoRCxhQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDdEI7O0FBRUQsVUFBSztjQUFBLGlCQUFHO0FBQ04sZ0JBQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUU7QUFDN0IsZUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztVQUNsRDtRQUNGOztBQVFELFlBQU87Ozs7Ozs7OztjQUFBLG1CQUFHO0FBQ1IsYUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ2IsYUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3RDLGFBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0FBQzFCLGFBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtBQUNuQixrQkFBTyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztVQUNqQztBQUNELGFBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN0Qjs7QUFFRCxrQkFBYTtjQUFBLHlCQUFHLEVBRWY7O0FBRUQsYUFBUTtjQUFBLGtCQUFDLElBQUksRUFBQyxLQUFLLEVBQUU7QUFDbkIsYUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDMUIsYUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCOzs7O1VBbFNrQixTQUFTO0lBQVMsWUFBWTs7a0JBQTlCLFNBQVMsQzs7Ozs7O0FDYjlCLGFBQVksQ0FBQzs7QUFFYixRQUFPLENBQUMsWUFBWSxHQUFHLFVBQUMsRUFBRSxFQUFLO0FBQzdCLE9BQUksY0FBYyxHQUFHLEVBQUUsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO0FBQ2hELE9BQUksR0FBRyxHQUFHLGNBQWMsQ0FBQyxHQUFHLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztBQUM5QyxPQUFJLElBQUksR0FBRyxjQUFjLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUM7QUFDaEQsVUFBTyxFQUFDLEdBQUcsRUFBSCxHQUFHLEVBQUMsSUFBSSxFQUFKLElBQUksRUFBQyxDQUFDO0VBQ25CLENBQUM7O0FBRUYsUUFBTyxDQUFDLFlBQVksR0FBRyxVQUFDLE1BQU0sRUFBSztBQUNqQyxPQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRTtBQUM5QixXQUFNLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzFEOztBQUVELE9BQUksTUFBTSxZQUFZLFdBQVcsSUFBSSxNQUFNLFlBQVksVUFBVSxFQUFDO0FBQ2hFLFlBQU8sTUFBTSxDQUFDO0lBQ2YsTUFBTTtBQUNMLFlBQU8sMEJBQTBCLENBQUM7SUFDbkM7RUFDRixDQUFDOztBQUVGLFFBQU8sQ0FBQyxXQUFXLEdBQUcsVUFBQyxDQUFDLEVBQUMsTUFBTSxFQUFLO0FBQ2xDLFVBQU87QUFDTCxNQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSTtBQUN4QixNQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsR0FBRztJQUN4QixDQUFDO0VBQ0gsQ0FBQzs7QUFFRixRQUFPLENBQUMsV0FBVyxHQUFHLFVBQUMsQ0FBQyxFQUFDLE1BQU0sRUFBSztBQUNsQyxVQUFPO0FBQ0wsTUFBQyxFQUFFLENBQUMsQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLEdBQUcsS0FBSztBQUMxRSxNQUFDLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLEdBQUcsR0FBRyxLQUFLO0lBQzFFLENBQUM7RUFDSCxDQUFDOztBQUVGLFFBQU8sQ0FBQyxXQUFXLEdBQUcsVUFBUyxNQUFNLEVBQUU7OztBQUVyQyxPQUFJLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDaEQsT0FBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM3QyxTQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQzs7QUFFakMsT0FBSSxDQUFDLE1BQU0sR0FBRyxVQUFDLENBQUMsRUFBQyxDQUFDLEVBQUs7QUFDckIsV0FBSyxPQUFPLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBQyxDQUFDLENBQUM7QUFDekIsV0FBSyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBQyxDQUFDLENBQUM7QUFDMUIsV0FBSyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLEdBQUMsSUFBSSxDQUFDO0FBQ2xDLFdBQUssT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxHQUFDLElBQUksQ0FBQztJQUNwQyxDQUFDO0VBRUgsQzs7Ozs7O0FDaERELGFBQVksQ0FBQzs7QUFFYixRQUFPLENBQUMsUUFBUSxHQUFHLFVBQUMsR0FBRyxFQUFLO0FBQzFCLE9BQUksT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsWUFBWSxVQUFVLEtBQUssS0FBSyxJQUFJLEdBQUcsWUFBWSxXQUFXLEtBQUssS0FBSyxFQUFHO0FBQ2xKLFlBQU8sSUFBSSxDQUFDO0lBQ2IsTUFBTTtBQUNMLFlBQU8sS0FBSyxDQUFDO0lBQ2Q7RUFDRixDOzs7Ozs7QUNSRCxhQUFZLENBQUM7O0FBRWIsUUFBTyxDQUFDLE1BQU0sR0FBSSxjQUFjLElBQUksUUFBUSxDQUFDLGVBQWdCLEM7Ozs7OztBQ0Y3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBaUI7QUFDakIsUUFBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxnQkFBZSxTQUFTO0FBQ3hCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxJQUFHO0FBQ0gscUJBQW9CLFNBQVM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7Ozs7QUM3U0EsYUFBWSxDQUFDOzs7Ozs7QUFFYixLQUFJLElBQUksR0FBRyxtQkFBTyxDQUFDLENBQWMsQ0FBQyxDQUFDOzs7Ozs7Ozs7OztLQVdkLElBQUk7QUFFWixZQUZRLElBQUksR0FFeUI7U0FBcEMsR0FBRyxnQ0FBRyxDQUFDO1NBQUMsR0FBRyxnQ0FBRyxDQUFDO1NBQUMsSUFBSSxnQ0FBRyxDQUFDO1NBQUMsS0FBSyxnQ0FBRyxDQUFDOzsyQkFGM0IsSUFBSTs7Ozs7QUFNckIsU0FBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDZixTQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNmLFNBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ2pCLFNBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0FBQ25CLFNBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO0FBQ3JCLFNBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO0FBQ3RCLFNBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pCOztnQkFia0IsSUFBSTtBQW9CdkIsV0FBTTs7Ozs7OztjQUFBLGdCQUFDLEtBQUssRUFBRTtBQUNaLGFBQUksSUFBSSxDQUFDLElBQUksRUFBRTs7QUFFYixlQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssR0FBQyxJQUFJLENBQUMsR0FBRyxJQUFLLElBQUksQ0FBQyxJQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7VUFDOUcsTUFBTTtBQUNMLGVBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUMsSUFBSSxDQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7VUFDakQ7QUFDRCxhQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDLEtBQUssRUFBRTtBQUNoQyxlQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7QUFDM0IsZUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7VUFDckIsTUFBTTtBQUNMLGVBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1VBQ3RCO0FBQ0QsZ0JBQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNuQjs7QUFNRCxpQkFBWTs7Ozs7OztjQUFBLHNCQUFDLEtBQUssRUFBRTtBQUNsQixhQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFDLENBQUMsRUFBQyxDQUFDLEVBQUMsSUFBSSxDQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDckQsZ0JBQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEM7O0FBS0csZUFBVTs7Ozs7O1lBQUEsWUFBRztBQUNmLGdCQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQyxJQUFJLENBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNyRDs7OztVQWxEa0IsSUFBSTs7O2tCQUFKLElBQUksQzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNiekIsYUFBWSxDQUFDOztLQUVOLElBQUksdUNBQU0sQ0FBYzs7S0FDeEIsV0FBVyx1Q0FBTSxFQUFrQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQW1DN0IsTUFBTSxXQUFOLE1BQU07QUFFTixZQUZBLE1BQU0sR0FFK0Q7U0FBcEUsSUFBSSxnQ0FBQyxVQUFVO1NBQUMsU0FBUyxnQ0FBQyxVQUFVO1NBQUMsTUFBTSxnQ0FBQyxDQUFDLENBQUMsRUFBQyxHQUFHLENBQUM7U0FBQyxNQUFNLGdDQUFDLENBQUMsQ0FBQyxFQUFDLEdBQUcsQ0FBQzs7MkJBRm5FLE1BQU07O0FBR2YsU0FBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7QUFDakIsU0FBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7QUFDM0IsU0FBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFDbEIsU0FBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7QUFDZixTQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQztBQUNyQixTQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBQyxNQUFNLENBQUMsQ0FBQztJQUM1Qjs7Z0JBVFUsTUFBTTtBQVdqQixXQUFNO2NBQUEsZ0JBQUMsTUFBTSxFQUFDLE1BQU0sRUFBRTtBQUNwQixhQUFJLENBQUMsUUFBUSxHQUFHO0FBQ2QsY0FBRyxFQUFFO0FBQ0gsY0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDWixjQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNiO0FBQ0QsY0FBRyxFQUFFO0FBQ0gsY0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDWixjQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNiO0FBQ0QsaUJBQU0sRUFBRTtBQUNOLGNBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDeEMsY0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUN6QztVQUNGLENBQUM7UUFDSDs7QUFNRyxXQUFNO1lBSkEsVUFBQyxLQUFLLEVBQUU7QUFDaEIsYUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkQ7WUFFUyxZQUFHO0FBQ1gsZ0JBQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUNyQjs7QUFHRCxXQUFNO2NBQUEsZ0JBQUMsS0FBSyxFQUFFO0FBQ1osYUFBSSxJQUFJLENBQUMsSUFBSSxLQUFHLFVBQVUsRUFBRTtBQUMxQixlQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUNqRSxlQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsR0FBRyxFQUFFO0FBQUUsc0JBQVMsR0FBRyxDQUFDLENBQUM7WUFBRTtBQUNqRCxlQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztBQUNwQixlQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7VUFDeEQsTUFBTTtBQUNMLGVBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxDQUFDO1VBQ2pEO0FBQ0QsYUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDOztBQUVELDJCQUFzQjtjQUFBLGdDQUFDLE9BQU8sRUFBRTtBQUM5QixpQkFBTyxJQUFJLENBQUMsU0FBUztBQUNuQixnQkFBSyxRQUFRO0FBQ1gsaUJBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwRyxxQkFBUSxHQUFHLFFBQVEsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEVBQUUsR0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QyxxQkFBUSxHQUFHLENBQUUsUUFBUSxHQUFHLElBQUksR0FBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3ZDLG9CQUFPLFFBQVEsQ0FBQztBQUNsQixnQkFBSyxVQUFVO0FBQ2Isb0JBQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNFLGdCQUFLLFlBQVk7QUFDZixvQkFBTyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUM7QUFBQSxVQUM1RTtRQUNGOzs7O1VBN0RVLE1BQU07OztLQWtFTixNQUFNLFdBQU4sTUFBTTtBQUVOLFlBRkEsTUFBTSxHQUVVO1NBQWYsSUFBSSxnQ0FBQyxRQUFROzsyQkFGZCxNQUFNOztBQUdmLFNBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ2pCLFNBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztBQUMvQixTQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztJQUN6Qjs7Z0JBTlUsTUFBTTtBQVFqQixVQUFLO2NBQUEsaUJBQUc7QUFDTixpQkFBUSxJQUFJLENBQUMsSUFBSTtBQUNmLGdCQUFLLFNBQVM7QUFDWixpQkFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQztBQUNoQixpQkFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO0FBQ2hCLDJCQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2NBQzVCO0FBQ0QsaUJBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBQyxFQUFFLENBQUMsQ0FBQztBQUN4RCxpQkFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQy9CLG1CQUFNO0FBQ1IsZ0JBQUssUUFBUTtBQUNYLGlCQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDZCxpQkFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQy9CLG1CQUFNO0FBQ1IsZ0JBQUssWUFBWTtBQUNmLGlCQUFJLENBQUMsUUFBUSxHQUFHO0FBQ2QsZ0JBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQztBQUMzQyxnQkFBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQztjQUNqRCxDQUFDO0FBQ0YsaUJBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUNkLGlCQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQztBQUNqQixvQkFBSyxFQUFFLElBQUksQ0FBQyxLQUFLO0FBQ2pCLGdCQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2xCLGdCQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQ25CLENBQUMsQ0FBQztBQUNILG1CQUFNO0FBQ1IsZ0JBQUssUUFBUTtBQUNYLGlCQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDWixpQkFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQy9CLG1CQUFNO0FBQUEsVUFDVDtRQUVGOztBQUVELFNBQUk7Y0FBQSxnQkFBRztBQUNMLGFBQUksSUFBSSxDQUFDLElBQUksS0FBRyxZQUFZLEVBQUU7QUFDNUIsZUFBSSxDQUFDLFFBQVEsR0FBRztBQUNkLGNBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQztBQUMzQyxjQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDO1lBQ2pELENBQUM7QUFDRixlQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQztBQUNqQixrQkFBSyxFQUFFLElBQUksQ0FBQyxLQUFLO0FBQ2pCLGNBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDbEIsY0FBQyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUNuQixDQUFDLENBQUM7QUFDSCxlQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7VUFDZjtRQUNGOztBQUVELFlBQU87Y0FBQSxtQkFBRztBQUNSLGlCQUFRLElBQUksQ0FBQyxJQUFJO0FBQ2YsZ0JBQUssUUFBUTtBQUNYLGlCQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDZixpQkFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQy9CLG1CQUFNO0FBQ1IsZ0JBQUssWUFBWTtBQUNmLGlCQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDZixpQkFBSSxDQUFDLFFBQVEsR0FBRztBQUNkLGdCQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUs7QUFDNUIsZ0JBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU07Y0FDbEMsQ0FBQztBQUNGLGlCQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQztBQUNqQixvQkFBSyxFQUFFLElBQUksQ0FBQyxLQUFLO0FBQ2pCLGdCQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2xCLGdCQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQ25CLENBQUMsQ0FBQztBQUNILG1CQUFNO0FBQUEsVUFDVDtRQUNGOzs7O1VBNUVVLE1BQU07Ozs7Ozs7QUN4R25CLGFBQVksQ0FBQzs7Ozs7O0tBRVEsTUFBTTtBQUVkLFlBRlEsTUFBTSxDQUViLEtBQUssRUFBRTsyQkFGQSxNQUFNOztBQUd2QixTQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssSUFBSSxLQUFLLENBQUM7SUFDN0I7O2dCQUprQixNQUFNO0FBTXpCLFNBQUk7Y0FBQSxjQUFDLEtBQUssRUFBRTtBQUNWLGFBQUksS0FBSyxJQUFJLEtBQUssS0FBSyxLQUFLLEVBQUU7QUFDNUIsZUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7VUFDcEIsTUFBTTtBQUNMLGVBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1VBQzFCO1FBQ0Y7O0FBRUQsT0FBRTtjQUFBLGNBQUc7QUFDSCxhQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUNuQjs7QUFFRCxRQUFHO2NBQUEsZUFBRztBQUNKLGFBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ3BCOzs7O1VBcEJrQixNQUFNOzs7a0JBQU4sTUFBTSxDOzs7Ozs7QUNGM0IsYUFBWSxDQUFDOzs7Ozs7Ozs7Ozs7QUFFYixLQUFJLEdBQUcsR0FBRyxtQkFBTyxDQUFDLENBQWEsQ0FBQyxDQUFDO0FBQ2pDLEtBQUksU0FBUyxHQUFHLG1CQUFPLENBQUMsQ0FBbUIsQ0FBQyxDQUFDO0FBQzdDLEtBQUksSUFBSSxHQUFHLG1CQUFPLENBQUMsRUFBZ0IsQ0FBQyxDQUFDOztLQUN6QixXQUFXLCtDQUFNLEVBQXFCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQW1DN0IsTUFBTTtBQUVkLFlBRlEsTUFBTSxHQUVYOzJCQUZLLE1BQU07O0FBSXZCLFNBQUksT0FBTyxHQUFHLENBQUMsS0FBSyxFQUFDLEtBQUssRUFBQyxPQUFPLENBQUMsQ0FBQzs7QUFFcEMsU0FBSSxRQUFRLEdBQUc7QUFDYixhQUFRLENBQUMsR0FBRyxFQUFDLEVBQUUsQ0FBQztBQUNoQixhQUFRLFVBQVU7QUFDbEIsWUFBTyxDQUFDO0FBQ1IsWUFBTyxDQUFDO0FBQ1IsYUFBUSxDQUFDO0FBQ1QsY0FBUyxDQUFDO01BQ1gsQ0FBQzs7QUFFRixnQ0FmaUIsTUFBTSw2Q0FlakIsU0FBUyxFQUFDLE9BQU8sRUFBQyxRQUFRLEVBQUU7O0FBRWxDLFNBQUksQ0FBQyxXQUFXLEdBQUcsVUFBVSxDQUFDOztBQUU5QixTQUFJLENBQUMsTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7O0FBRXRHLFNBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFDLElBQUksQ0FBQyxXQUFXLEVBQUMsQ0FBQyxDQUFDLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNHLFNBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDOztBQUU3QyxTQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7O0FBRVosU0FBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQzs7QUFFM0MsU0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRWhDOzthQTlCa0IsTUFBTTs7Z0JBQU4sTUFBTTtBQWdDekIsbUJBQWM7Y0FBQSwwQkFBRzs7QUFFZixhQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDOUIsYUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ2xDLGFBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQzs7QUFFakMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ25DLGFBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUN2QyxhQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFckM7O0FBRUQsa0JBQWE7Y0FBQSx5QkFBRzs7QUFFZCxhQUFJLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRTtBQUM1QixlQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQztVQUMvQixNQUFNO0FBQ0wsZUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFZLENBQUM7VUFDakM7O0FBRUQsYUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO0FBQ2pCLGVBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztVQUN0RDs7QUFFRCxhQUFJLENBQUM7YUFBRSxDQUFDO2FBQUUsQ0FBQzthQUFFLENBQUM7YUFBRSxTQUFTO2FBQUUsWUFBWSxhQUFDO0FBQ3hDLGFBQUksQ0FBQyxRQUFRLEdBQUc7QUFDZCxnQkFBSyxFQUFFLENBQUM7QUFDUixZQUFDLEVBQUUsQ0FBQztVQUNMLENBQUM7O0FBRUYsYUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLFVBQVUsRUFBRTtBQUNuQyxlQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLFlBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFDLENBQUMsQ0FBQztBQUNqQixZQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ04sWUFBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7QUFDbkIsWUFBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDZixlQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQztBQUN4QyxlQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxDQUFDLEdBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUMsSUFBSSxDQUFDLFVBQVUsSUFBRSxDQUFDLEdBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0Usb0JBQVMsR0FBRyxZQUFZLEdBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRSxDQUFDLENBQUUsR0FBQyxDQUFDLEdBQUMsS0FBSyxDQUFDO0FBQ3JELHVCQUFZLEdBQUcsQ0FBQyxHQUFDLENBQUMsQ0FBQztVQUNwQixNQUFNO0FBQ0wsZUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztBQUNsQyxZQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ04sWUFBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUMsQ0FBQyxDQUFDO0FBQ2xCLFlBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO0FBQ2YsWUFBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7QUFDbEIsZUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxHQUFHLENBQUM7QUFDeEMsZUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsSUFBRSxDQUFDLEdBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUMsQ0FBQyxDQUFDLEdBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDM0Usb0JBQVMsR0FBRyxjQUFjLEdBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRSxDQUFDLENBQUUsR0FBQyxDQUFDLEdBQUMsR0FBRyxDQUFDO0FBQ3JELHVCQUFZLEdBQUcsQ0FBQyxHQUFDLENBQUMsQ0FBQztVQUNwQjs7QUFFRCxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0IsYUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdCLGFBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBQyxTQUFTLENBQUMsQ0FBQztBQUM3QyxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUMsWUFBWSxDQUFDLENBQUM7QUFDekMsYUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ3pDLGFBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBQyxDQUFDLENBQUMsQ0FBQztBQUNqQyxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRWxDLGFBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxVQUFVLEVBQUU7QUFDbkMsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pDLGVBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ25ELGVBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBQyxDQUFDLENBQUMsQ0FBQztBQUNyQyxlQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUMsQ0FBQyxHQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7VUFDM0QsTUFBTTtBQUNMLGVBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxDQUFDLENBQUMsQ0FBQztBQUNqQyxlQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakMsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDdkQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLENBQUMsQ0FBQyxDQUFDO1VBQ3ZDO0FBQ0QsYUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQ2pELGFBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksRUFBQyxZQUFZLENBQUMsQ0FBQztBQUM3QyxhQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUMsWUFBWSxDQUFDLENBQUM7O0FBRTdDLGFBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxVQUFVLEVBQUU7QUFDbkMsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLGVBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1VBQ2xELE1BQU07QUFDTCxlQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNqRCxlQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUMsQ0FBQyxDQUFDLENBQUM7VUFDaEM7QUFDRCxhQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU3Qzs7QUFFRCxtQkFBYztjQUFBLDBCQUFHO0FBQ2YsYUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDaEQsYUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDdEQsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDcEQ7O0FBR0QsV0FBTTtjQUFBLGtCQUFHO0FBQ1AsYUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUU7QUFDakIsZUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBQyxJQUFJLENBQUM7VUFDdkM7QUFDRCxhQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQzs7QUFFNUMsYUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLFVBQVUsRUFBRTtBQUNuQyxlQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBRSxJQUFJLENBQUMsTUFBTSxHQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVGLGVBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDL0QsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNqRSxlQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztVQUMxRCxNQUFNO0FBQ0wsZUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLElBQUUsSUFBSSxDQUFDLEtBQUssR0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBQyxDQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztBQUMzRixlQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNqRCxlQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakMsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7VUFDekQ7UUFDRjs7QUFHRCxVQUFLO2NBQUEsaUJBQUc7QUFDTixhQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxHQUFDLEdBQUcsQ0FBQztBQUNyQyxhQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO0FBQ2xDLGFBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNiOztBQUVELFNBQUk7Y0FBQSxnQkFBRztBQUNMLGFBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtBQUNoQixlQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDakMsZUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUUsQ0FBQztBQUNoRCxlQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3RDLGVBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztVQUVmO1FBQ0Y7O0FBRUQsWUFBTztjQUFBLG1CQUFHO0FBQ1IsYUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2Y7O0FBRUcsZUFBVTtZQUFBLFlBQUc7QUFDZixnQkFBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQztRQUMvQjs7QUFVRyxVQUFLOzs7Ozs7OztZQUhBLFlBQUc7QUFDVixnQkFBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztRQUMxQjtZQUNRLFVBQUMsQ0FBQyxFQUFFO0FBQ1gsYUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsYUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7QUFDN0MsYUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN0QyxhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZjs7QUFVRyxRQUFHOzs7Ozs7OztZQUhBLFlBQUc7QUFDUixnQkFBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQztRQUN4QjtZQUNNLFVBQUMsQ0FBQyxFQUFFO0FBQ1QsYUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCOztBQVVHLFFBQUc7Ozs7Ozs7O1lBSEEsWUFBRztBQUNSLGdCQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO1FBQ3hCO1lBQ00sVUFBQyxDQUFDLEVBQUU7QUFDVCxhQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDckI7O0FBVUcsU0FBSTs7Ozs7Ozs7WUFIQSxZQUFHO0FBQ1QsZ0JBQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFDekI7WUFDTyxVQUFDLENBQUMsRUFBRTtBQUNWLGFBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztRQUN0Qjs7QUFVRyxTQUFJOzs7Ozs7OztZQUhBLFlBQUc7QUFDVCxnQkFBTyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztRQUMzQjtZQUNPLFVBQUMsQ0FBQyxFQUFFO0FBQ1YsYUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ3hCOzs7O1VBdE9rQixNQUFNO0lBQVMsU0FBUzs7a0JBQXhCLE1BQU0sQzs7Ozs7O0FDeEMzQixhQUFZLENBQUM7Ozs7Ozs7Ozs7QUFFYixLQUFJLEdBQUcsR0FBRyxtQkFBTyxDQUFDLENBQWEsQ0FBQyxDQUFDO0FBQ2pDLEtBQUksV0FBVyxHQUFHLG1CQUFPLENBQUMsRUFBa0IsQ0FBQyxDQUFDO0FBQzlDLEtBQUksU0FBUyxHQUFHLG1CQUFPLENBQUMsQ0FBbUIsQ0FBQyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0tBOEJ4QixNQUFNO0FBRWQsWUFGUSxNQUFNLEdBRVg7MkJBRkssTUFBTTs7QUFJdkIsU0FBSSxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQzs7QUFFeEIsU0FBSSxRQUFRLEdBQUc7QUFDYixhQUFRLENBQUMsRUFBRSxFQUFDLEVBQUUsQ0FBQztBQUNmLGVBQVUsS0FBSztBQUNmLGNBQVMsS0FBSztNQUNmLENBQUM7O0FBRUYsZ0NBWmlCLE1BQU0sNkNBWWpCLFNBQVMsRUFBQyxPQUFPLEVBQUMsUUFBUSxFQUFFOztBQUVsQyxTQUFJLENBQUMsTUFBTSxHQUFHLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7O0FBRW5ELFNBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUViOzthQWxCa0IsTUFBTTs7Z0JBQU4sTUFBTTtBQW9CekIsbUJBQWM7Y0FBQSwwQkFBRzs7QUFFZixhQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDOUIsYUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2pDLGFBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNuQyxhQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFckM7O0FBRUQsa0JBQWE7Y0FBQSx5QkFBRzs7QUFFZCxhQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBQyxDQUFDLEVBQUU7QUFDOUIsZUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFDLENBQUMsQ0FBQztVQUMvQixNQUFNO0FBQ0wsZUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFDLENBQUMsQ0FBQztVQUM5Qjs7QUFFRCxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUMsSUFBSSxDQUFDLEtBQUssR0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBQyxHQUFHLENBQUMsQ0FBQztBQUM1RCxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUMsSUFBSSxDQUFDLE1BQU0sR0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBQyxDQUFDLENBQUMsQ0FBQztBQUMzRCxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLFFBQVEsR0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QyxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLFFBQVEsR0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QyxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUMsSUFBSSxDQUFDLFFBQVEsR0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQyxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDOztBQUU5QyxhQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLEtBQUssR0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzFELGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBQyxJQUFJLENBQUMsTUFBTSxHQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNDLGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFM0M7O0FBRUQsbUJBQWM7Y0FBQSwwQkFBRztBQUNmLGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ25ELGFBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNmOztBQUVELFdBQU07Y0FBQSxrQkFBRztBQUNQLGFBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFO0FBQ2YsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFDLElBQUksQ0FBQyxLQUFLLEdBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUMxRCxlQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztVQUNqRCxNQUFNO0FBQ0wsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFDLElBQUksQ0FBQyxLQUFLLEdBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUMxRCxlQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztVQUNuRDtRQUNGOztBQUVELFVBQUs7Y0FBQSxpQkFBRztBQUNOLGFBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNaLGFBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUNkLGFBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoQzs7QUFVRyxVQUFLOzs7Ozs7OztZQUhBLFlBQUc7QUFDVixnQkFBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztRQUMxQjtZQUNRLFVBQUMsS0FBSyxFQUFFO0FBQ2YsYUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDeEIsYUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQy9CLGFBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNmOztBQVFELFNBQUk7Ozs7Ozs7O2NBQUEsZ0JBQUc7QUFDTCxhQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ25CLGFBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNmOzs7O1VBOUZrQixNQUFNO0lBQVMsU0FBUzs7a0JBQXhCLE1BQU0sQzs7Ozs7O0FDbEMzQixhQUFZLENBQUM7Ozs7Ozs7Ozs7QUFFYixLQUFJLEdBQUcsR0FBRyxtQkFBTyxDQUFDLENBQWEsQ0FBQyxDQUFDO0FBQ2pDLEtBQUksY0FBYyxHQUFHLG1CQUFPLENBQUMsRUFBOEIsQ0FBQyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7S0FpQ3hDLE1BQU07QUFFZCxZQUZRLE1BQU0sR0FFWDsyQkFGSyxNQUFNOztBQUl2QixTQUFJLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDOztBQUd2QixTQUFJLFFBQVEsR0FBRztBQUNiLGFBQVEsQ0FBQyxFQUFFLEVBQUMsRUFBRSxDQUFDO0FBQ2YsYUFBUSxZQUFZO0FBQ3BCLGNBQVMsS0FBSztNQUNmLENBQUM7O0FBRUYsZ0NBYmlCLE1BQU0sNkNBYWpCLFNBQVMsRUFBQyxPQUFPLEVBQUMsUUFBUSxFQUFFOzs7Ozs7O0FBUWxDLFNBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7O0FBRS9CLFNBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNaLFNBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUVmOzthQTFCa0IsTUFBTTs7Z0JBQU4sTUFBTTtBQTRCekIsbUJBQWM7Y0FBQSwwQkFBRztBQUNmLGFBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNoQyxhQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7O0FBRW5DLGFBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDOzs7QUFHbEMsYUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQy9CLGFBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzs7QUFFcEMsYUFBSSxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRWhELGFBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7O0FBRXJELGFBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFdkQ7O0FBRUQsa0JBQWE7Y0FBQSx5QkFBRzs7QUFFZCxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLEtBQUssR0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6QyxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLE1BQU0sR0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxQyxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBQyxFQUFFLENBQUMsQ0FBQztBQUNqRixhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLEtBQUssR0FBQyxFQUFFLENBQUMsQ0FBQztRQUN0RDs7QUFFRCxtQkFBYztjQUFBLDBCQUFHOztBQUVmLGFBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN0RSxhQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDcEUsYUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2Y7O0FBUUQsV0FBTTs7Ozs7Ozs7O2NBQUEsa0JBQUc7QUFDUCxhQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRTtBQUNmLGVBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2hELGVBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1VBQzFELE1BQU07QUFDTCxlQUFJLElBQUksQ0FBQyxJQUFJLEtBQUcsWUFBWSxFQUFFO0FBQzVCLGlCQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsT0FBTyxHQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzlELGlCQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFDLEdBQUcsR0FBRSxHQUFHLENBQUMsQ0FBQztBQUNwRSxpQkFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRyxDQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBRSxHQUFHLEdBQUUsR0FBRyxDQUFDLENBQUM7WUFDekUsTUFBTTtBQUNMLGlCQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyRDtBQUNELGVBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1VBQ25EO1FBQ0Y7Ozs7VUFqRmtCLE1BQU07SUFBUyxjQUFjOztrQkFBN0IsTUFBTSxDOzs7Ozs7QUNwQzNCLGFBQVksQ0FBQzs7Ozs7Ozs7OztBQUViLEtBQUksR0FBRyxHQUFHLG1CQUFPLENBQUMsQ0FBYSxDQUFDLENBQUM7QUFDakMsS0FBSSxJQUFJLEdBQUcsbUJBQU8sQ0FBQyxDQUFjLENBQUMsQ0FBQztBQUNuQyxLQUFJLFdBQVcsR0FBRyxtQkFBTyxDQUFDLEVBQWtCLENBQUMsQ0FBQztBQUM5QyxLQUFJLFNBQVMsR0FBRyxtQkFBTyxDQUFDLENBQW1CLENBQUMsQ0FBQzs7Ozs7O0tBTXhCLGNBQWM7QUFFdEIsWUFGUSxjQUFjLENBRXJCLElBQUksRUFBQyxPQUFPLEVBQUMsUUFBUSxFQUFFOzJCQUZoQixjQUFjOztBQUkvQixnQ0FKaUIsY0FBYyw2Q0FJekIsSUFBSSxFQUFDLE9BQU8sRUFBQyxRQUFRLEVBQUU7O0FBRTdCLFNBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksUUFBUSxDQUFDOztBQUUzQyxTQUFJLENBQUMsUUFBUSxHQUFHO0FBQ2QsUUFBQyxFQUFFLENBQUM7QUFDSixRQUFDLEVBQUUsQ0FBQztNQUNMLENBQUM7O0FBRUYsU0FBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRXBEOzthQWZrQixjQUFjOztnQkFBZCxjQUFjO0FBaUJqQyxtQkFBYztjQUFBLDBCQUFHO0FBQ2YsYUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2hDLGFBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN0QyxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDeEMsYUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDOztBQUV6QyxhQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7O0FBRW5DLGFBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDOztBQUVsQyxhQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDdEI7O0FBRUQsa0JBQWE7Y0FBQSx5QkFBRztBQUNkLGFBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksRUFBQyxJQUFJLENBQUMsS0FBSyxHQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pDLGFBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksRUFBQyxJQUFJLENBQUMsTUFBTSxHQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFDLGFBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN0RTs7QUFFRCxXQUFNO2NBQUEsa0JBQUc7QUFDUCxhQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRTtBQUNmLGVBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2hELGVBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1VBQzFELE1BQU07QUFDTCxlQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNsRCxlQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztVQUNyRDtRQUNGOztBQUVELFNBQUk7Y0FBQSxjQUFDLFVBQVUsRUFBRTtBQUNmLGlCQUFRLElBQUksQ0FBQyxJQUFJO0FBQ2YsZ0JBQUssU0FBUztBQUNaLGlCQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDZCxpQkFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO0FBQ2hCLDJCQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2NBQzVCO0FBQ0QsaUJBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFDLEVBQUUsQ0FBQyxDQUFDOztBQUV0RCxtQkFBTTtBQUNSLGdCQUFLLFFBQVE7QUFDWCxpQkFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDOztBQUVkLG1CQUFNO0FBQ1IsZ0JBQUssWUFBWTtBQUNmLGlCQUFJLENBQUMsUUFBUSxHQUFHO0FBQ2QsZ0JBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQztBQUMzQyxnQkFBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQztjQUMvQyxDQUFDO0FBQ0YsaUJBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQzs7Ozs7O0FBTWQsbUJBQU07QUFDUixnQkFBSyxRQUFRO0FBQ1gsaUJBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7O0FBRXRCLG1CQUFNO0FBQUEsVUFDVDtRQUVGOztBQUVELFNBQUk7Y0FBQSxjQUFDLEtBQUssRUFBRTtBQUNWLGFBQUksSUFBSSxDQUFDLElBQUksS0FBRyxZQUFZLEVBQUU7QUFDNUIsZUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQztBQUNqQyxlQUFJLENBQUMsUUFBUSxHQUFHO0FBQ2QsY0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDO0FBQzNDLGNBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7WUFDakQsQ0FBQztBQUNGLGVBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDO0FBQ2pCLGtCQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7QUFDakIsY0FBQyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNsQixjQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQ25CLENBQUMsQ0FBQztBQUNILGVBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztVQUNmO1FBQ0Y7O0FBRUQsT0FBRTtjQUFBLGNBQUc7QUFDSCxpQkFBUSxJQUFJLENBQUMsSUFBSTtBQUNmLGdCQUFLLFFBQVE7QUFDWCxpQkFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDOztBQUVmLG1CQUFNO0FBQ1IsZ0JBQUssWUFBWTtBQUNmLGlCQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDZixpQkFBSSxDQUFDLFFBQVEsR0FBRztBQUNkLGdCQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7QUFDM0MsZ0JBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7Y0FDakQsQ0FBQzs7Ozs7O0FBTUYsbUJBQU07QUFBQSxVQUNUO1FBQ0Y7O0FBSUQsVUFBSzs7OztjQUFBLGlCQUFHO0FBQ04sYUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2I7O0FBQ0QsU0FBSTtjQUFBLGdCQUFHO0FBQ0wsYUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2I7O0FBQ0QsWUFBTztjQUFBLG1CQUFHO0FBQ1IsYUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ1g7O0FBVUcsVUFBSzs7Ozs7Ozs7WUFIQSxZQUFHO0FBQ1YsZ0JBQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7UUFDMUI7WUFDUSxVQUFDLEtBQUssRUFBRTtBQUNmLGFBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3hCLGFBQUksSUFBSSxDQUFDLElBQUksS0FBRyxZQUFZLEVBQUU7QUFDNUIsZUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUM7QUFDakIsa0JBQUssRUFBRSxJQUFJLENBQUMsS0FBSztBQUNqQixjQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2xCLGNBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFDbkIsQ0FBQyxDQUFDO1VBQ0osTUFBTTtBQUNMLGVBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztVQUNoQztBQUNELGFBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNmOztBQU9ELFNBQUk7Ozs7Ozs7O2NBQUEsY0FBQyxLQUFLLEVBQUU7QUFDVixhQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN4QixhQUFJLElBQUksQ0FBQyxJQUFJLEtBQUcsWUFBWSxFQUFFO0FBQzVCLGVBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDO0FBQ2pCLGtCQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7QUFDakIsY0FBQyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNsQixjQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQ25CLENBQUMsQ0FBQztVQUNKLE1BQU07QUFDTCxlQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7VUFDaEM7QUFDRCxhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZjs7QUFNRCxXQUFNOzs7Ozs7O2NBQUEsZ0JBQUMsUUFBUSxFQUFFO0FBQ2YsYUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQztBQUNqQixhQUFJLFFBQVEsS0FBRyxLQUFLLEVBQUU7QUFDcEIsZUFBSSxJQUFJLENBQUMsSUFBSSxLQUFHLFlBQVksRUFBRTtBQUM1QixpQkFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUM7QUFDakIsb0JBQUssRUFBRSxJQUFJLENBQUMsS0FBSztBQUNqQixnQkFBQyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNsQixnQkFBQyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUNuQixDQUFDLENBQUM7WUFDSixNQUFNO0FBQ0wsaUJBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNoQztVQUNGO0FBQ0QsYUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2Y7O0FBTUQsWUFBTzs7Ozs7OztjQUFBLGlCQUFDLFFBQVEsRUFBRTtBQUNoQixhQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLGFBQUksUUFBUSxLQUFHLEtBQUssRUFBRTtBQUNwQixlQUFJLElBQUksQ0FBQyxJQUFJLEtBQUcsWUFBWSxFQUFFO0FBQzVCLGlCQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQztBQUNqQixvQkFBSyxFQUFFLElBQUksQ0FBQyxLQUFLO0FBQ2pCLGdCQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2xCLGdCQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQ25CLENBQUMsQ0FBQztZQUNKLE1BQU07QUFDTCxpQkFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hDO1VBQ0Y7QUFDRCxhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZjs7OztVQWhOa0IsY0FBYztJQUFTLFNBQVM7O2tCQUFoQyxjQUFjLEM7Ozs7OztBQ1huQyxhQUFZLENBQUM7Ozs7Ozs7Ozs7QUFFYixLQUFJLGNBQWMsR0FBRyxtQkFBTyxDQUFDLEVBQThCLENBQUMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7S0FnQ3hDLFVBQVU7QUFFbEIsWUFGUSxVQUFVLEdBRWY7MkJBRkssVUFBVTs7QUFJM0IsU0FBSSxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQzs7QUFFeEIsU0FBSSxRQUFRLEdBQUc7QUFDYixhQUFRLENBQUMsR0FBRyxFQUFDLEVBQUUsQ0FBQztBQUNoQixjQUFTLEtBQUs7QUFDZCxhQUFRLE1BQU07TUFDZixDQUFDOztBQUVGLGdDQVppQixVQUFVLDZDQVlyQixTQUFTLEVBQUMsT0FBTyxFQUFDLFFBQVEsRUFBRTs7QUFFbEMsU0FBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQzs7QUFFaEMsU0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBQzs7QUFDekIsV0FBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7QUFDdEQsY0FBTyxDQUFDLElBQUksQ0FBQyxtRUFBbUUsQ0FBQyxDQUFDO01BQ25GO0FBQ0QsU0FBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQztBQUNsRCxTQUFJLENBQUMsSUFBSSxHQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxHQUFJLFFBQVEsR0FBRyxRQUFRLENBQUM7QUFDaEUsU0FBSSxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ1osU0FBSSxDQUFDLE1BQU0sRUFBRSxDQUFDOztBQUVkLFNBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7SUFFbEM7O2FBM0JrQixVQUFVOztnQkFBVixVQUFVO0FBNkI3QixlQUFVO2NBQUEsc0JBQUc7O0FBRVgsYUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzdDLGFBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQzs7QUFFdEMsYUFBSSxDQUFDLFdBQVcsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2pELGFBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7QUFDeEMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzVDOztBQUVELG1CQUFjO2NBQUEsMEJBQUcsRUFFaEI7O0FBRUQsbUJBQWM7Y0FBQSwwQkFBRztBQUNmLGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztBQUM1QyxhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZjs7QUFFRCxrQkFBYTtjQUFBLHlCQUFHO0FBQ1osYUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBQyxDQUFDLENBQUM7QUFDN0IsYUFBSSxTQUFTLEdBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUcsQ0FBQztBQUN4RCxpQkFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQ3hDLGFBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtBQUN0QixlQUFJLFNBQVMsR0FBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBRyxDQUFDO0FBQ2hFLG1CQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUMsU0FBUyxDQUFDLENBQUM7VUFDekM7QUFDRCxhQUFJLE1BQU0sR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7QUFDNUMsZUFBTSxJQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztBQUMzQyxlQUFNLElBQUksV0FBVyxHQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBQyxRQUFRLElBQUUsQ0FBQyxHQUFDLFNBQVMsQ0FBQztBQUN6RCxlQUFNLElBQUkseUJBQXlCLENBQUM7QUFDcEMsZUFBTSxJQUFJLHFCQUFxQixDQUFDO0FBQ2hDLGVBQU0sSUFBSSx1QkFBdUIsQ0FBQztBQUNsQyxlQUFNLElBQUksbUJBQW1CLENBQUM7QUFDOUIsZUFBTSxJQUFJLGFBQWEsQ0FBQztBQUN4QixlQUFNLElBQUksWUFBWSxHQUFHLFFBQVEsR0FBRyxLQUFLLENBQUM7QUFDMUMsYUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztBQUN4QyxhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDakI7O0FBRUQsV0FBTTtjQUFBLGtCQUFHO0FBQ1AsYUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUU7QUFDZixlQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDdEQsZUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO0FBQ2hELGVBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7VUFDekMsTUFBTTtBQUNMLGVBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztBQUN4RCxlQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDaEQsZUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO0FBQ3RCLGlCQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1lBQ2xELE1BQU07QUFDTCxpQkFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUN6QztVQUNGO1FBQ0Y7O0FBVUcsa0JBQWE7Ozs7Ozs7WUFKQSxZQUFHO0FBQ2xCLGdCQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDNUI7WUFFZ0IsVUFBQyxJQUFJLEVBQUU7QUFDdEIsYUFBSSxJQUFJLEVBQUU7QUFDUixlQUFJLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBQztVQUN0QixNQUFNO0FBQ0wsZUFBSSxDQUFDLElBQUksR0FBRyxRQUFRLENBQUM7VUFDdEI7QUFDRCxhQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztBQUMzQixhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZjs7QUFXRyxTQUFJOzs7Ozs7O1lBSkEsWUFBRztBQUNULGdCQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDbkI7WUFFTyxVQUFDLElBQUksRUFBRTtBQUNiLGFBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ2xCLGFBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztBQUNyQixhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZjs7OztVQXBIa0IsVUFBVTtJQUFTLGNBQWM7O2tCQUFqQyxVQUFVLEM7Ozs7OztBQ2xDL0IsYUFBWSxDQUFDOzs7Ozs7Ozs7OztBQUdiLEtBQUksU0FBUyxHQUFHLG1CQUFPLENBQUMsQ0FBbUIsQ0FBQyxDQUFDO0FBQzdDLEtBQUksTUFBTSxHQUFHLG1CQUFPLENBQUMsRUFBc0IsQ0FBQyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0tBK0J4QixXQUFXO0FBRW5CLFlBRlEsV0FBVyxHQUVoQjsyQkFGSyxXQUFXOztBQUk1QixTQUFJLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDOztBQUV4QixTQUFJLFFBQVEsR0FBRztBQUNiLGFBQVEsQ0FBQyxHQUFHLEVBQUMsRUFBRSxDQUFDO0FBQ2hCLHdCQUFtQixDQUFDO0FBQ3BCLGVBQVUsQ0FBQyxDQUFDO01BQ2IsQ0FBQzs7QUFFRixnQ0FaaUIsV0FBVyw2Q0FZdEIsU0FBUyxFQUFDLE9BQU8sRUFBQyxRQUFRLEVBQUU7O0FBRWxDLFNBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLFNBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQztBQUN0RCxTQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDOztBQUVuQyxTQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDWixTQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFFZjs7YUFyQmtCLFdBQVc7O2dCQUFYLFdBQVc7QUF1QjlCLGVBQVU7Y0FBQSxzQkFBRztBQUNYLGFBQUksQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM3QyxhQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdkM7O0FBRUQsbUJBQWM7Y0FBQSwwQkFBRzs7QUFFZixjQUFLLElBQUksQ0FBQyxHQUFDLENBQUMsRUFBQyxDQUFDLEdBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFDLENBQUMsRUFBRSxFQUFFO0FBQ3hDLGVBQUksU0FBUyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7O0FBRS9DLGVBQUksTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLFNBQVMsRUFBRTtBQUMvQixpQkFBSSxFQUFFLFFBQVE7QUFDZCxzQkFBUyxFQUFFLElBQUksRUFDaEIsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzs7QUFFL0IsZUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDMUIsZUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7VUFDckM7UUFFRjs7QUFFRCxrQkFBYTtjQUFBLHlCQUFHOztBQUVkLGFBQUksV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO0FBQ3JELGFBQUksWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7O0FBRS9CLGNBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUMsQ0FBQyxFQUFFLEVBQUU7QUFDeEMsZUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFDLFlBQVksQ0FBQyxDQUFDO1VBQ2xEO1FBRUY7O0FBRUQsbUJBQWM7Y0FBQSwwQkFBRztBQUNmLGNBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUMsQ0FBQyxFQUFFLEVBQUU7QUFDeEMsZUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUNyQyxlQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1VBQzFCO1FBQ0Y7O0FBRUQsV0FBTTtjQUFBLGdCQUFDLEtBQUssRUFBRTtBQUNaLGFBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUU7QUFDN0IsZUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztVQUNwQixNQUFNO0FBQ0wsZUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1VBQ2pCOztBQUFBLFFBRUY7O0FBRUQsV0FBTTtjQUFBLGtCQUFHO0FBQ1AsY0FBSyxJQUFJLENBQUMsR0FBQyxDQUFDLEVBQUMsQ0FBQyxHQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFDLENBQUMsRUFBRSxFQUFFO0FBQ3RDLGVBQUksQ0FBQyxLQUFHLElBQUksQ0FBQyxNQUFNLEVBQUU7QUFDbkIsaUJBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQy9CLE1BQU07QUFDTCxpQkFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEM7VUFDRjtRQUNGOztBQU1ELFdBQU07Ozs7Ozs7Y0FBQSxnQkFBQyxLQUFLLEVBQUU7QUFDWixhQUFJLEtBQUssSUFBRSxDQUFDLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFO0FBQzNDLGVBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO0FBQ3BCLGVBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNoQyxlQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7VUFDZjtRQUNGOztBQUtELGFBQVE7Ozs7OztjQUFBLG9CQUFHO0FBQ1QsYUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNqQixhQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDaEMsYUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2Y7O0FBVUcsb0JBQWU7WUFSQSxZQUFHO0FBQ3BCLGdCQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztRQUM5Qjs7Ozs7O1lBTWtCLFVBQUMsT0FBTyxFQUFFO0FBQzNCLGFBQUksQ0FBQyxnQkFBZ0IsR0FBRyxPQUFPLENBQUM7QUFDaEMsY0FBSyxJQUFJLENBQUMsR0FBQyxDQUFDLEVBQUMsQ0FBQyxHQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFDLENBQUMsRUFBRSxFQUFFO0FBQ3RDLGVBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7VUFDM0I7QUFDRCxhQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQzs7OztBQUlsQixhQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDYixhQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdkI7Ozs7VUF6SGtCLFdBQVc7SUFBUyxTQUFTOztrQkFBN0IsV0FBVyxDOzs7Ozs7QUNuQ2hDLGFBQVksQ0FBQzs7Ozs7Ozs7OztBQUViLEtBQUksU0FBUyxHQUFHLG1CQUFPLENBQUMsQ0FBbUIsQ0FBQyxDQUFDO0FBQzdDLEtBQUksSUFBSSxHQUFHLG1CQUFPLENBQUMsRUFBZ0IsQ0FBQyxDQUFDO0FBQ3JDLEtBQUksSUFBSSxHQUFHLG1CQUFPLENBQUMsQ0FBYyxDQUFDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7S0FtQ2QsTUFBTTtBQUVkLFlBRlEsTUFBTSxHQUVYOzJCQUZLLE1BQU07O0FBSXZCLFNBQUksT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7O0FBRXhCLFNBQUksUUFBUSxHQUFHO0FBQ2IsYUFBUSxDQUFDLEVBQUUsRUFBQyxFQUFFLENBQUM7QUFDZixjQUFTLENBQUM7QUFDVixZQUFPLENBQUM7QUFDUixZQUFPLEtBQUs7QUFDWixhQUFRLENBQUM7TUFDVixDQUFDOztBQUVGLGdDQWRpQixNQUFNLDZDQWNqQixTQUFTLEVBQUMsT0FBTyxFQUFDLFFBQVEsRUFBRTs7QUFFbEMsU0FBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDOzs7Ozs7O0FBT25HLFNBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZCLFNBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDOztBQUVoQixTQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDOztBQUUzQixTQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDOztBQUUzQixTQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDOztBQUU3QixTQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDWixTQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFFZjs7YUFuQ2tCLE1BQU07O2dCQUFOLE1BQU07QUFxQ3pCLGVBQVU7Y0FBQSxzQkFBRztBQUNYLGFBQUksQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUMvQyxhQUFJLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxNQUFNLENBQUM7O0FBRTNCLGFBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLGFBQVk7QUFDakQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO0FBQ3RELGVBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztBQUM1QyxlQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUU7QUFDcEMsaUJBQUksQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDNUMsaUJBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNoQjtVQUNGLEVBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7O0FBR2IsYUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsV0FBVSxDQUFDLEVBQUU7QUFDckQsZUFBSSxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsRUFBRTtBQUNqQyxpQkFBSSxDQUFDLENBQUMsS0FBSyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsS0FBSyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsS0FBSyxLQUFLLENBQUMsRUFBRTtBQUN4RCxnQkFBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO2NBQ25CO1lBQ0Q7QUFDRCxlQUFJLENBQUMsQ0FBQyxLQUFLLEtBQUcsRUFBRSxFQUFFO0FBQ2pCLGlCQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ2xCLGlCQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO0FBQ2hDLGlCQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDL0IsaUJBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNoQjtVQUNGLEVBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7O0FBRWIsYUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXZDOztBQUVELGtCQUFhO2NBQUEseUJBQUc7O0FBRWQsYUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDOztBQUV0RCxhQUFJLE1BQU0sR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7QUFDNUMsZUFBTSxJQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztBQUMzQyxlQUFNLElBQUksNEJBQTRCLENBQUM7QUFDdkMsZUFBTSxJQUFJLGNBQWMsQ0FBQztBQUN6QixlQUFNLElBQUkscUJBQXFCLENBQUM7QUFDaEMsZUFBTSxJQUFJLG1CQUFtQixDQUFDO0FBQzlCLGVBQU0sSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsR0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDOztBQUV0RCxlQUFNLElBQUksZUFBZSxDQUFDO0FBQzFCLGVBQU0sSUFBSSxnQkFBZ0IsQ0FBQztBQUMzQixlQUFNLElBQUksV0FBVyxHQUFDLElBQUksQ0FBQyxhQUFhLEdBQUMsQ0FBQyxHQUFDLEtBQUssR0FBQyxJQUFJLENBQUMsYUFBYSxHQUFDLENBQUMsR0FBQyxLQUFLLENBQUM7QUFDNUUsZUFBTSxJQUFJLHlCQUF5QixDQUFDO0FBQ3BDLGVBQU0sSUFBSSxtQkFBbUIsQ0FBQztBQUM5QixlQUFNLElBQUksc0JBQXNCLENBQUM7QUFDakMsZUFBTSxJQUFJLHlCQUF5QixDQUFDO0FBQ3BDLGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUM7Ozs7O0FBS3JDLGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFFakM7O0FBRUQsbUJBQWM7Y0FBQSwwQkFBRztBQUNiLGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztBQUN0RCxhQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFDL0M7O0FBRUQsV0FBTTtjQUFBLGtCQUFHOztBQUVQLGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFaEU7O0FBRUQsVUFBSztjQUFBLGlCQUFHO0FBQ04sYUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7QUFDdEIsYUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQzlCLGFBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztBQUN4QixhQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDbkMsYUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUUsQ0FBQztBQUM3RCxnQkFBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDaEM7O0FBRUQsU0FBSTtjQUFBLGdCQUFHO0FBQ0wsYUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7QUFDckIsYUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFOztBQUVoQixlQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQU0sSUFBSSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsR0FBRyxHQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBRSxHQUFHLEdBQUcsQ0FBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBQyxDQUFDLENBQUMsQ0FBQztBQUNqSixlQUFJLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQzs7QUFFeEIsZUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ1osZUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRTtBQUN2QixpQkFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hDO1VBRUg7UUFDRDs7QUFFRCxZQUFPO2NBQUEsbUJBQUc7QUFDUixhQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtBQUNsQixlQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7QUFDaEMsZUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUNyQixlQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM3RCxlQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUM7QUFDeEQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO1VBQzVDLE1BQU07QUFDTCxtQkFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztVQUN2QjtRQUNGOztBQU9ELFNBQUk7Ozs7Ozs7O2NBQUEsY0FBQyxXQUFXLEVBQUU7OztBQUNoQixhQUFJLENBQUMsR0FBRyxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUM7QUFDM0IsYUFBSSxDQUFDLEdBQUcsR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDO0FBQzNCLGFBQUksQ0FBQyxJQUFJLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQztBQUM3QixvQkFBVyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUMsVUFBQyxDQUFDLEVBQUs7QUFDN0IsaUJBQUssYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1VBQ3ZCLENBQUMsQ0FBQztBQUNILGFBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFDLFVBQUMsQ0FBQyxFQUFLO0FBQ3RCLHNCQUFXLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztVQUN2QixDQUFDLENBQUM7QUFDSCxhQUFJLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7Ozs7OztRQVNoQzs7QUFFRCxrQkFBYTtjQUFBLHVCQUFDLENBQUMsRUFBRTtBQUNmLGFBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLGFBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNmOztBQVVHLFVBQUs7Ozs7Ozs7O1lBSEEsWUFBRztBQUNWLGdCQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO1FBQzFCO1lBQ1EsVUFBQyxDQUFDLEVBQUU7QUFDWCxhQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixhQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDL0IsYUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2Y7O0FBVUcsUUFBRzs7Ozs7Ozs7WUFIQSxZQUFHO0FBQ1IsZ0JBQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7UUFDeEI7WUFDTSxVQUFDLENBQUMsRUFBRTtBQUNULGFBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNyQjs7QUFVRyxRQUFHOzs7Ozs7OztZQUhBLFlBQUc7QUFDUixnQkFBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQztRQUN4QjtZQUNNLFVBQUMsQ0FBQyxFQUFFO0FBQ1QsYUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCOztBQVVHLFNBQUk7Ozs7Ozs7O1lBSEEsWUFBRztBQUNULGdCQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO1FBQ3pCO1lBQ08sVUFBQyxDQUFDLEVBQUU7QUFDVixhQUFJLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7UUFDdEI7Ozs7VUEvTmtCLE1BQU07SUFBUyxTQUFTOztrQkFBeEIsTUFBTSxDOzs7Ozs7QUN2QzNCLGFBQVksQ0FBQzs7Ozs7Ozs7OztBQUViLEtBQUksU0FBUyxHQUFHLG1CQUFPLENBQUMsQ0FBbUIsQ0FBQyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0tBZ0N4QixNQUFNO0FBRWQsWUFGUSxNQUFNLEdBRVg7MkJBRkssTUFBTTs7QUFJdkIsU0FBSSxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQzs7QUFFeEIsU0FBSSxRQUFRLEdBQUc7QUFDWixhQUFRLENBQUMsR0FBRyxFQUFDLEVBQUUsQ0FBQztBQUNoQixnQkFBVyxDQUFDLFNBQVMsRUFBQyxTQUFTLENBQUM7TUFDbEMsQ0FBQzs7QUFFRixnQ0FYaUIsTUFBTSw2Q0FXakIsU0FBUyxFQUFDLE9BQU8sRUFBQyxRQUFRLEVBQUU7O0FBRWxDLFNBQUksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDekIsU0FBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7O0FBRXBCLFNBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7O0FBRXRDLFNBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNaLFNBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUVmOzthQXJCa0IsTUFBTTs7Z0JBQU4sTUFBTTtBQXVCekIsZUFBVTtjQUFBLHNCQUFHO0FBQ1gsYUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2hELGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFDLENBQUMsR0FBQyxJQUFJLENBQUM7QUFDakQsYUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztBQUNwQyxhQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDO0FBQ3RDLGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFDLElBQUksQ0FBQztBQUMzQyxhQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBQyxJQUFJLENBQUM7O0FBRTdDLGFBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7O0FBRTFDLGFBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQzs7QUFFMUQsYUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXZDOztBQUVELG9CQUFlO2NBQUEsMkJBQUcsRUFFakI7O0FBRUQsbUJBQWM7Y0FBQSwwQkFBRzs7QUFFZixhQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFFdEI7O0FBRUQsbUJBQWM7Y0FBQSwwQkFBRztBQUNmLGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztBQUN0RCxhQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDNUMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLFlBQVksR0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQztRQUNsRTs7QUFFRCxXQUFNO2NBQUEsa0JBQUc7O0FBRVAsYUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUNwRSxhQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDO0FBQ2pELGFBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDO0FBQ2pCLGdCQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU07QUFDbEIsZ0JBQUssRUFBRSxJQUFJLENBQUMsY0FBYztVQUMzQixDQUFDLENBQUM7UUFFSjs7QUFFRCxVQUFLO2NBQUEsaUJBQUcsRUFFUDs7QUFFRCxTQUFJO2NBQUEsZ0JBQUcsRUFFTjs7QUFFRCxZQUFPO2NBQUEsbUJBQUcsRUFFVDs7QUFPRCxrQkFBYTs7Ozs7OztjQUFBLHVCQUFDLE9BQU8sRUFBRTs7Ozs7Ozs7Ozs7OztBQWNyQixhQUFJLE9BQU8sRUFBRTtBQUNYLGVBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1VBQ3pCOztBQUVELGNBQUksSUFBSSxDQUFDLEdBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQ3BELGVBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1VBQ3hCOztBQUVELGNBQUksSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBQyxDQUFDLEVBQUUsRUFBRTtBQUN0QyxlQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1VBQzNEO1FBRUY7O0FBV0csVUFBSzs7Ozs7Ozs7WUFIQSxZQUFHO0FBQ1YsZ0JBQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNwQjtZQUNRLFVBQUMsQ0FBQyxFQUFFO0FBQ1gsYUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDaEIsY0FBSSxJQUFJLENBQUMsR0FBQyxDQUFDLEVBQUMsQ0FBQyxHQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBQyxDQUFDLEVBQUUsRUFBRTtBQUM3QyxlQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUU7QUFDdEMsaUJBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZCLG1CQUFNO1lBQ1A7VUFDRjtRQUNGOztBQVdHLGtCQUFhOzs7Ozs7OztZQUhBLFlBQUc7QUFDbEIsZ0JBQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUM1QjtZQUNnQixVQUFDLENBQUMsRUFBRTtBQUNuQixhQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQztBQUN4QixhQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUM7QUFDL0IsYUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2Y7O0FBRUQsa0JBQWE7Y0FBQSx5QkFBRztBQUNkLGFBQUksQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUM5RDs7OztVQW5Ka0IsTUFBTTtJQUFTLFNBQVM7O2tCQUF4QixNQUFNLEM7Ozs7OztBQ2xDM0IsYUFBWSxDQUFDOzs7Ozs7Ozs7Ozs7QUFFYixLQUFJLEdBQUcsR0FBRyxtQkFBTyxDQUFDLENBQWEsQ0FBQyxDQUFDO0FBQ2pDLEtBQUksSUFBSSxHQUFHLG1CQUFPLENBQUMsQ0FBYyxDQUFDLENBQUM7QUFDbkMsS0FBSSxTQUFTLEdBQUcsbUJBQU8sQ0FBQyxDQUFtQixDQUFDLENBQUM7QUFDN0MsS0FBSSxJQUFJLEdBQUcsbUJBQU8sQ0FBQyxFQUFnQixDQUFDLENBQUM7O0tBQ3pCLFdBQVcsK0NBQU0sRUFBcUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7S0F3QzdCLElBQUk7QUFFWixZQUZRLElBQUksR0FFVDsyQkFGSyxJQUFJOztBQUlyQixTQUFJLE9BQU8sR0FBRyxDQUFDLEtBQUssRUFBQyxLQUFLLEVBQUMsT0FBTyxDQUFDLENBQUM7O0FBRXBDLFNBQUksUUFBUSxHQUFHO0FBQ2IsYUFBUSxDQUFDLEVBQUUsRUFBQyxFQUFFLENBQUM7QUFDZixvQkFBZSxRQUFRO0FBQ3ZCLGFBQVEsVUFBVTtBQUNsQixZQUFPLENBQUM7QUFDUixZQUFPLENBQUM7QUFDUixhQUFRLENBQUM7QUFDVCxjQUFTLENBQUM7TUFDWCxDQUFDOztBQUVGLGdDQWhCaUIsSUFBSSw2Q0FnQmYsU0FBUyxFQUFDLE9BQU8sRUFBQyxRQUFRLEVBQUU7O0FBRWxDLFNBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUM7O0FBRTdDLFNBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQzs7QUFFdEcsU0FBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLFdBQVcsRUFBQyxDQUFDLENBQUMsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRTNHLFNBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQzs7QUFFWixTQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDOztBQUUvQixTQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQzs7QUFFN0MsU0FBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7O0FBRTNCLFNBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUVoQzs7YUFsQ2tCLElBQUk7O2dCQUFKLElBQUk7QUFvQ3ZCLG1CQUFjO2NBQUEsMEJBQUc7O0FBRWYsYUFBSSxDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3ZDLGFBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNsQyxhQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDakMsYUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ2xDLGFBQUksQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNyQyxhQUFJLENBQUMsV0FBVyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDdEMsYUFBSSxDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDOztBQUVyQyxhQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDMUMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3RDLGFBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUN2QyxhQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDMUMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzNDLGFBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUMxQyxhQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdEM7O0FBR0Qsa0JBQWE7Y0FBQSx5QkFBRzs7QUFFZCxhQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRXJELGFBQUksTUFBTSxHQUFHO0FBQ1gsWUFBQyxFQUFFLElBQUksQ0FBQyxLQUFLLEdBQUMsQ0FBQztBQUNmLFlBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFDLENBQUM7VUFDakIsQ0FBQzs7QUFFRixhQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDOztBQUVoRCxhQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdDLGFBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0MsYUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLFFBQVEsR0FBQyxDQUFDLEdBQUMsUUFBUSxHQUFDLEVBQUUsQ0FBQyxDQUFDOztBQUUxRCxhQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hDLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDeEMsYUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLFFBQVEsR0FBQyxFQUFFLENBQUMsQ0FBQzs7QUFFMUMsYUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQzs7QUFFdkIsYUFBSSxZQUFZLEdBQUc7QUFDakIsZ0JBQUssRUFBRSxJQUFJLENBQUMsRUFBRSxHQUFDLEdBQUc7QUFDbEIsY0FBRyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUMsQ0FBQyxFQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsRUFBRSxHQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsRUFBRSxHQUFDLEdBQUcsQ0FBQyxFQUFHLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxDQUFFO1VBQzdGLENBQUM7QUFDRixhQUFJLGFBQWEsR0FBRztBQUNsQixnQkFBSyxFQUFFLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRztBQUNsQixjQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBQyxHQUFHLEVBQUMsQ0FBQyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxDQUFDLEVBQUcsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLENBQUU7VUFDN0YsQ0FBQzs7QUFFRixhQUFJLFVBQVUsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxRQUFRLEdBQUMsQ0FBQyxHQUFDLFFBQVEsR0FBQyxFQUFFLEVBQUUsWUFBWSxDQUFDLEtBQUssRUFBRSxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0csYUFBSSxXQUFXLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsUUFBUSxHQUFDLENBQUMsR0FBQyxRQUFRLEdBQUMsRUFBRSxFQUFFLGFBQWEsQ0FBQyxLQUFLLEVBQUUsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDOztBQUU5RyxhQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUMsVUFBVSxDQUFDLENBQUM7QUFDekMsYUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLFFBQVEsR0FBQyxFQUFFLENBQUMsQ0FBQztBQUN0RCxhQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7O0FBRXpDLGFBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxXQUFXLENBQUMsQ0FBQztBQUMzQyxhQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUUsUUFBUSxHQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZELGFBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQzs7QUFFMUMsbUJBQVUsSUFBSSxLQUFLLEdBQUMsTUFBTSxDQUFDLENBQUMsR0FBQyxHQUFHLEdBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzs7QUFFMUMsYUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQzdDLGFBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxLQUFLLENBQUMsQ0FBQzs7QUFFcEQsb0JBQVcsSUFBSSxLQUFLLEdBQUMsTUFBTSxDQUFDLENBQUMsR0FBQyxHQUFHLEdBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzs7QUFFM0MsYUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQy9DLGFBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxLQUFLLENBQUMsQ0FBQzs7QUFFckQsYUFBSSxVQUFVLGFBQUM7QUFDZixhQUFJLEtBQUssR0FBRyxHQUFHLEVBQUU7QUFDZixxQkFBVSxHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUM7VUFDL0IsTUFBTTtBQUNMLHFCQUFVLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQztVQUNoQzs7QUFFRCxhQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksUUFBUSxHQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hFLGFBQUksVUFBVSxHQUFHLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxRQUFRLEdBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7O0FBRXJFLGFBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxJQUFJLEdBQUMsTUFBTSxDQUFDLENBQUMsR0FBQyxHQUFHLEdBQUMsTUFBTSxDQUFDLENBQUMsR0FBQyxLQUFLLEdBQUMsVUFBVSxHQUFDLEdBQUcsR0FBQyxVQUFVLENBQUMsQ0FBQztBQUM3RixhQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUUsUUFBUSxHQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRTNEOztBQUVELG1CQUFjO2NBQUEsMEJBQUc7QUFDZixhQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN2RCxhQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNwRCxhQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN2RCxhQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN4RCxhQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN6RCxhQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMxRCxhQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUU1RDs7QUFFRCxXQUFNO2NBQUEsa0JBQUc7QUFDUCxhQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQzs7QUFFbkMsYUFBSSxNQUFNLEdBQUc7QUFDWCxZQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssR0FBQyxDQUFDO0FBQ2YsWUFBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEdBQUMsQ0FBQztVQUNqQixDQUFDOztBQUVGLGFBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7O0FBRWhELGFBQUksWUFBWSxHQUFHO0FBQ2pCLGdCQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHO0FBQ2xCLGNBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFDLENBQUMsRUFBQyxHQUFHLEVBQUMsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLEVBQUMsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLENBQUMsRUFBRyxJQUFJLENBQUMsRUFBRSxHQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsRUFBRSxHQUFDLEdBQUcsQ0FBRTtVQUM3RixDQUFDO0FBQ0YsYUFBSSxhQUFhLEdBQUc7QUFDbEIsZ0JBQUssRUFBRSxJQUFJLENBQUMsRUFBRSxHQUFFLEdBQUc7QUFDbkIsY0FBRyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUMsR0FBRyxFQUFDLENBQUMsRUFBQyxJQUFJLENBQUMsRUFBRSxHQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsRUFBRSxHQUFDLEdBQUcsQ0FBQyxFQUFHLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxDQUFFO1VBQzdGLENBQUM7O0FBRUYsYUFBSSxVQUFVLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsUUFBUSxHQUFDLENBQUMsR0FBQyxRQUFRLEdBQUMsRUFBRSxFQUFFLFlBQVksQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzNHLGFBQUksV0FBVyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLFFBQVEsR0FBQyxDQUFDLEdBQUMsUUFBUSxHQUFDLEVBQUUsRUFBRSxhQUFhLENBQUMsS0FBSyxFQUFFLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7QUFFOUcsYUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3pDLGFBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxXQUFXLENBQUMsQ0FBQzs7QUFHM0MsbUJBQVUsSUFBSSxLQUFLLEdBQUMsTUFBTSxDQUFDLENBQUMsR0FBQyxHQUFHLEdBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzs7QUFFMUMsYUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLFVBQVUsQ0FBQyxDQUFDOztBQUU3QyxvQkFBVyxJQUFJLEtBQUssR0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFDLEdBQUcsR0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDOztBQUUzQyxhQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUMsV0FBVyxDQUFDLENBQUM7O0FBRS9DLGFBQUksVUFBVSxhQUFDO0FBQ2YsYUFBSSxLQUFLLElBQUksR0FBRyxFQUFFO0FBQ2hCLHFCQUFVLEdBQUcsWUFBWSxDQUFDLEdBQUcsQ0FBQztVQUMvQixNQUFNO0FBQ0wscUJBQVUsR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDO1VBQ2hDOztBQUVELGFBQUksVUFBVSxHQUFHLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxRQUFRLEdBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEUsYUFBSSxVQUFVLEdBQUcsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLFFBQVEsR0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQzs7QUFFckUsYUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLElBQUksR0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFDLEdBQUcsR0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFDLEtBQUssR0FBQyxVQUFVLEdBQUMsR0FBRyxHQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRTlGOztBQUdELFVBQUs7Y0FBQSxpQkFBRztBQUNOLGFBQUksSUFBSSxDQUFDLElBQUksS0FBRyxVQUFVLEVBQUU7QUFDMUIsZUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7VUFDNUI7QUFDRCxhQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO0FBQ2xDLGFBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO0FBQzdDLGFBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNaOztBQUVGLFNBQUk7Y0FBQSxnQkFBRztBQUNMLGFBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTs7QUFFaEIsZUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDOztBQUVqQyxlQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBQyxJQUFJLENBQUMsRUFBRSxHQUFDLENBQUMsQ0FBQzs7QUFFMUMsZUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFHO0FBQUUsa0JBQUssSUFBSyxJQUFJLENBQUMsRUFBRSxHQUFDLENBQUUsQ0FBQztZQUFFOztBQUV6QyxlQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO0FBQzVCLGlCQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssS0FBSyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUU7QUFDNUUsbUJBQUksSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLEVBQUU7QUFDMUIsc0JBQUssR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFDLENBQUMsQ0FBQztnQkFDbkIsTUFBTTtBQUNMLHNCQUFLLEdBQUcsQ0FBQyxDQUFDO2dCQUNYO2NBQ0Y7WUFDRjs7Ozs7Ozs7O0FBU0QsZUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7O0FBRTNCLGVBQUksU0FBUyxHQUFHLEtBQUssSUFBSSxJQUFJLENBQUMsRUFBRSxHQUFDLENBQUMsQ0FBQyxDQUFDOztBQUVwQyxlQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFFLFNBQVMsQ0FBRSxDQUFDOztBQUVuRCxlQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO0FBQzVCLGlCQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUM7WUFDakM7O0FBRUQsZUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQzs7QUFFdEMsZUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1VBRWY7UUFDRjs7QUFFRCxZQUFPO2NBQUEsbUJBQUcsRUFDVDs7QUEwQkssVUFBSzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztZQUhBLFlBQUc7QUFDVixnQkFBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztRQUMxQjtZQUNRLFVBQUMsQ0FBQyxFQUFFO0FBQ1gsYUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsYUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7QUFDN0MsYUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN0QyxhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZjs7QUFVRyxRQUFHOzs7Ozs7OztZQUhBLFlBQUc7QUFDUixnQkFBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQztRQUN4QjtZQUNNLFVBQUMsQ0FBQyxFQUFFO0FBQ1QsYUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCOztBQVVHLFFBQUc7Ozs7Ozs7O1lBSEEsWUFBRztBQUNSLGdCQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO1FBQ3hCO1lBQ00sVUFBQyxDQUFDLEVBQUU7QUFDVCxhQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDckI7O0FBVUcsU0FBSTs7Ozs7Ozs7WUFIQSxZQUFHO0FBQ1QsZ0JBQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFDekI7WUFDTyxVQUFDLENBQUMsRUFBRTtBQUNWLGFBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztRQUN0Qjs7QUFVRyxTQUFJOzs7Ozs7OztZQUhBLFlBQUc7QUFDVCxnQkFBTyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztRQUMzQjtZQUNPLFVBQUMsQ0FBQyxFQUFFO0FBQ1YsYUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ3hCOztBQVlDLGVBQVU7Ozs7Ozs7O1lBSkEsWUFBRztBQUNmLGdCQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO1FBQy9CO1lBRWEsVUFBQyxDQUFDLEVBQUU7QUFDaEIsYUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUIsYUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hDOzs7O1VBMVVrQixJQUFJO0lBQVMsU0FBUzs7a0JBQXRCLElBQUksQzs7Ozs7O0FDOUN6QixhQUFZLENBQUM7Ozs7Ozs7Ozs7QUFFYixLQUFJLEdBQUcsR0FBRyxtQkFBTyxDQUFDLENBQWEsQ0FBQyxDQUFDO0FBQ2pDLEtBQUksU0FBUyxHQUFHLG1CQUFPLENBQUMsQ0FBbUIsQ0FBQyxDQUFDO0FBQzdDLEtBQUksY0FBYyxHQUFHLG1CQUFPLENBQUMsRUFBOEIsQ0FBQyxDQUFDO0FBQzdELEtBQUksS0FBSyxHQUFHLG1CQUFPLENBQUMsQ0FBZSxDQUFDLENBQUM7O0tBRS9CLFFBQVE7QUFFRCxZQUZQLFFBQVEsR0FFRTsyQkFGVixRQUFROztBQUlWLFNBQUksT0FBTyxHQUFHLENBQUMsT0FBTyxFQUFDLE1BQU0sRUFBQyxPQUFPLENBQUMsQ0FBQzs7QUFFdkMsU0FBSSxRQUFRLEdBQUc7QUFDYixhQUFRLENBQUMsRUFBRSxFQUFDLEVBQUUsQ0FBQztBQUNmLGVBQVUsS0FBSztBQUNmLGFBQVEsUUFBUTtBQUNoQixjQUFTLENBQUM7TUFDWCxDQUFDOztBQUVGLGdDQWJFLFFBQVEsNkNBYUosU0FBUyxFQUFDLE9BQU8sRUFBQyxRQUFRLEVBQUU7O0FBRWxDLFNBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7QUFDL0IsU0FBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQzs7QUFFakMsU0FBSSxDQUFDLE1BQU0sR0FBRztBQUNaLFVBQUssTUFBTTtBQUNYLFVBQUssTUFBTSxFQUNaLENBQUM7O0FBRUYsU0FBSSxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ1osU0FBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBRWY7O2FBMUJHLFFBQVE7O2dCQUFSLFFBQVE7QUE0QlosZUFBVTtjQUFBLHNCQUFHO0FBQ1gsYUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2pDLGFBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDOUMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNoRCxhQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdkM7O0FBRUQsbUJBQWM7Y0FBQSwwQkFBRzs7O0FBRWYsYUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDOztBQUU5QixhQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7O0FBRW5DLGFBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDOzs7O0FBSWxDLGFBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFOztBQUVqQixlQUFJLENBQUMsS0FBSyxHQUFHLFlBQU07O0FBRWpCLG1CQUFLLEtBQUssQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0FBQzlCLG1CQUFLLEtBQUssQ0FBQyxVQUFVLEdBQUcsQ0FBQyxNQUFLLEtBQUssQ0FBQztBQUNwQyxtQkFBSyxJQUFJLENBQUMsTUFBSyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDbEMsQ0FBQzs7QUFFRixlQUFJLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxZQUFNO0FBQzNDLGlCQUFJLE1BQUssS0FBSyxDQUFDLFdBQVcsRUFBRTs7QUFFMUIscUJBQUssSUFBSSxDQUFDLE1BQUssS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2NBQ2xDO1lBQ0YsQ0FBQyxDQUFDOztBQUdILGVBQUksQ0FBQyxJQUFJLEdBQUcsWUFBTTtBQUNoQixpQkFBSSxNQUFLLEtBQUssQ0FBQyxXQUFXLEVBQUU7O0FBRTFCLHFCQUFLLElBQUksRUFBRSxDQUFDO2NBQ2I7WUFDRixDQUFDOztBQUdGLGVBQUksQ0FBQyxPQUFPLEdBQUcsWUFBTTtBQUNuQixtQkFBSyxLQUFLLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQzs7O1lBR2hDLENBQUM7QUFDRixlQUFJLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxZQUFNO0FBQ3pDLGlCQUFJLE1BQUssS0FBSyxDQUFDLFdBQVcsRUFBRTs7QUFFMUIscUJBQUssRUFBRSxFQUFFLENBQUM7Y0FDWDtZQUNGLENBQUMsQ0FBQztBQUNILGVBQUksQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLFlBQU07QUFDMUMsaUJBQUksTUFBSyxLQUFLLENBQUMsV0FBVyxFQUFFOztBQUUxQixxQkFBSyxFQUFFLEVBQUUsQ0FBQztjQUNYO1lBQ0YsQ0FBQyxDQUFDO1VBRUo7UUFFRjs7QUFFRCxrQkFBYTtjQUFBLHlCQUFHOzs7QUFHVixhQUFJLE1BQU0sR0FBRyxDQUFDLENBQUM7O0FBRWYsYUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQy9CLGFBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxHQUFHLENBQUMsQ0FBQztBQUMvQixhQUFJLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFO0FBQ2xCLGVBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO1VBQ2hELE1BQU07QUFDTCxlQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1VBQzVDO0FBQ0QsYUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUNuQixlQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1VBQzlDLE1BQU07QUFDTCxlQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1VBQzlDO0FBQ0QsYUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3BDLGFBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUV6Qzs7QUFFRCxXQUFNO2NBQUEsa0JBQUc7QUFDUCxhQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRTtBQUNmLGVBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1VBQ3hELE1BQU07QUFDTCxlQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztVQUNuRDtRQUNGOzs7O1VBeEhHLFFBQVE7SUFBUyxjQUFjOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQTBKaEIsS0FBSztBQUViLFlBRlEsS0FBSyxHQUVWOzJCQUZLLEtBQUs7O0FBSXRCLFNBQUksT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7O0FBRXhCLFNBQUksUUFBUSxHQUFHO0FBQ2IsYUFBUSxDQUFDLEdBQUcsRUFBQyxHQUFHLENBQUM7QUFDakIsZ0JBQVcsRUFBRTtBQUNiLGlCQUFZLEVBQUU7QUFDZCxhQUFRLFFBQVE7TUFDakIsQ0FBQzs7QUFFRixnQ0FiaUIsS0FBSyw2Q0FhaEIsU0FBUyxFQUFDLE9BQU8sRUFBQyxRQUFRLEVBQUU7O0FBRWxDLFNBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxHQUFHLEVBQUMsR0FBRyxFQUFDLEdBQUcsRUFBQyxHQUFHLEVBQUMsR0FBRyxFQUFDLEdBQUcsRUFBQyxHQUFHLEVBQUMsR0FBRyxFQUFDLEdBQUcsRUFBQyxHQUFHLEVBQUMsR0FBRyxFQUFDLEdBQUcsQ0FBQyxDQUFDOztBQUVwRSxTQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQzs7QUFFeEIsU0FBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQzs7QUFFL0IsU0FBSSxDQUFDLEtBQUssR0FBRztBQUNYLFVBQUcsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU87QUFDMUIsV0FBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUTtNQUM3QixDQUFDOztBQUVGLFNBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDOztBQUVuRCxTQUFJLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQzs7QUFFZixTQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQzs7QUFFdEIsU0FBSSxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ1osU0FBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBRWY7O2FBbkNrQixLQUFLOztnQkFBTCxLQUFLO0FBcUN4QixlQUFVO2NBQUEsc0JBQUc7QUFDWCxhQUFJLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDN0MsYUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQztBQUN6QyxhQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO0FBQ3hDLGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7QUFDckMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQztBQUNsQyxhQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0FBQ25DLGFBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN2Qzs7QUFFRCxtQkFBYztjQUFBLDBCQUFHOztBQUVmLGFBQUksQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDOztBQUVmLGNBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBQyxDQUFDLEVBQUUsRUFBRTs7QUFFbkQsZUFBSSxTQUFTLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMvQyxlQUFJLFVBQVUsR0FBRyxDQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQzs7QUFFN0QsZUFBSSxHQUFHLEdBQUcsSUFBSSxRQUFRLENBQUMsU0FBUyxFQUFFO0FBQzlCLHNCQUFTLEVBQUUsSUFBSTtBQUNmLGlCQUFJLEVBQUUsQ0FBQyxHQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRztBQUN0QixrQkFBSyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDO0FBQ2xDLGlCQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDaEIsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUMsQ0FBQyxHQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQzs7QUFFakQsY0FBRyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7O0FBRWpCLGVBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtBQUNoQixnQkFBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO0FBQ2xCLGdCQUFHLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQyxPQUFPLEdBQUcsR0FBRyxDQUFDLFVBQVUsR0FBRyxZQUFNLEVBQUUsQ0FBQztBQUN2RCxnQkFBRyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxPQUFPLEdBQUcsWUFBTSxFQUFFLENBQUM7QUFDOUMsZ0JBQUcsQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDLFlBQVksR0FBRyxHQUFHLENBQUMsZUFBZSxHQUFHLFlBQU0sRUFBRSxDQUFDO0FBQ2pFLGdCQUFHLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDLFlBQVksR0FBRyxZQUFNLEVBQUUsQ0FBQztZQUN6RDs7QUFFRCxlQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixlQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztVQUVyQztBQUNELGFBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtBQUNoQixlQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztVQUMxQjtRQUVGOztBQUVELGtCQUFhO2NBQUEseUJBQUc7O0FBRWQsYUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDOztBQUViLGFBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQzs7QUFFdEIsY0FBSyxJQUFJLENBQUMsR0FBQyxDQUFDLEVBQUMsQ0FBQyxHQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFDLENBQUMsRUFBRSxFQUFFOztBQUVuRCx1QkFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzs7QUFFeEIsZUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDLEdBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUM7QUFDN0QsZUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFDLEdBQUMsQ0FBQyxHQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDO0FBQ25FLGVBQUksQ0FBQyxHQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRTtBQUN6QyxpQkFBSSxJQUFJLENBQUMsQ0FBQztZQUNYLE1BQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEdBQUcsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEdBQUcsRUFBRTtBQUN6RixpQkFBSSxJQUFJLENBQUMsQ0FBQztZQUNYLE1BQU07QUFDTCxpQkFBSSxJQUFJLEdBQUcsQ0FBQztZQUNiO1VBQ0Y7QUFDRCxhQUFJLFFBQVEsR0FBRyxJQUFJLENBQUM7OztBQUlwQixhQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7QUFDaEIsYUFBSSxXQUFXLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFDLE9BQU8sR0FBQyxDQUFDLElBQUksUUFBUSxDQUFDO0FBQ3BELGFBQUksWUFBWSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBQyxPQUFPLEdBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQzs7QUFFL0MsY0FBSyxJQUFJLENBQUMsR0FBQyxDQUFDLEVBQUMsQ0FBQyxHQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFDLENBQUMsRUFBRSxFQUFFOztBQUVuQyxlQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUNwQyxvQkFBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsVUFBVSxDQUFDO0FBQ3RDLG9CQUFTLENBQUMsS0FBSyxDQUFDLElBQUksR0FBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLEdBQUMsV0FBVyxHQUFDLE9BQU8sR0FBSSxJQUFJLENBQUM7QUFDcEUsZUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxHQUFHLEVBQUU7QUFDOUIsc0JBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFJLE9BQU8sR0FBSSxJQUFJLENBQUM7QUFDdkMsaUJBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxZQUFZLEdBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEQsTUFBTTtBQUNMLHNCQUFTLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDM0Isc0JBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLE9BQU8sR0FBQyxJQUFJLENBQUM7QUFDbkMsaUJBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxZQUFZLEdBQUMsR0FBRyxDQUFDLENBQUM7WUFDcEQ7VUFFRjtRQUVGOztBQUVELG1CQUFjO2NBQUEsMEJBQUc7Ozs7QUFJZixhQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUM7O0FBRTdELGNBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBQyxDQUFDLEVBQUUsRUFBRTtBQUNuQyxlQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRztBQUNwQixnQkFBSyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUs7QUFDdEIsZ0JBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJO0FBQ3JCLHFCQUFVLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTTtBQUM1QixxQkFBVSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVc7WUFDbEMsQ0FBQztBQUNGLGVBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDOUIsZUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztVQUN2QjtRQUdGOztBQUVELGNBQVM7Y0FBQSxtQkFBQyxJQUFJLEVBQUMsRUFBRSxFQUFFOzs7OztBQUtqQixhQUFJLElBQUksR0FBRztBQUNULGVBQUksRUFBRSxJQUFJO1VBQ1gsQ0FBQztBQUNGLGFBQUksT0FBTyxFQUFFLEtBQUssUUFBUSxFQUFFO0FBQzFCLGVBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQzs7O1VBR3ZCLE1BQU07QUFDTCxlQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztVQUNqQjtBQUNELGFBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFCOztBQVNELFdBQU07Ozs7Ozs7OztjQUFBLGtCQUFHLEVBRVI7O0FBR0Qsc0JBQWlCO2NBQUEsNkJBQUc7OztBQUVsQixhQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsR0FBRyxZQUFNLEVBQUUsQ0FBQztBQUMxRCxhQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxZQUFNLEVBQUUsQ0FBQztBQUNqRCxhQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsR0FBRyxZQUFNLEVBQUUsQ0FBQztBQUNwRSxhQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFNLEVBQUUsQ0FBQzs7QUFFM0QsYUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7O0FBRTVCLGFBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLFVBQUMsQ0FBQyxFQUFLO0FBQ2pELGtCQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQzFCLGVBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQy9GLGVBQUksR0FBRyxHQUFHLE1BQUssSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNuQyxpQkFBSyxVQUFVLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDO0FBQzdCLGNBQUcsQ0FBQyxJQUFJLENBQUMsTUFBSyxVQUFVLENBQUMsQ0FBQztBQUMxQixpQkFBSyxjQUFjLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztBQUNwQyxZQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDbkIsWUFBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO1VBQ3JCLENBQUMsQ0FBQzs7QUFFSCxhQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxVQUFDLENBQUMsRUFBSztBQUNoRCxlQUFJLE9BQU8sR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUMvRixlQUFJLEdBQUcsR0FBRyxNQUFLLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbkMsZUFBSSxPQUFPLENBQUMsS0FBSyxLQUFHLE1BQUssY0FBYyxFQUFFO0FBQ3ZDLGlCQUFJLE1BQUssY0FBYyxFQUFFO0FBQ3ZCLG1CQUFJLE9BQU8sR0FBRyxNQUFLLElBQUksQ0FBQyxNQUFLLGNBQWMsQ0FBQyxDQUFDO0FBQzdDLHNCQUFPLENBQUMsRUFBRSxFQUFFLENBQUM7Y0FDZDtBQUNELGdCQUFHLENBQUMsSUFBSSxDQUFDLE1BQUssVUFBVSxDQUFDLENBQUM7WUFDM0IsTUFBTTtBQUNMLGdCQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDWjtBQUNELGlCQUFLLGNBQWMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDO0FBQ3BDLFlBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztBQUNuQixZQUFDLENBQUMsZUFBZSxFQUFFLENBQUM7VUFDckIsQ0FBQyxDQUFDOztBQUVILGFBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLFVBQUMsQ0FBQyxFQUFLOztBQUUvQyxlQUFJLEdBQUcsR0FBRyxNQUFLLElBQUksQ0FBQyxNQUFLLGNBQWMsQ0FBQyxDQUFDO0FBQ3pDLGNBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztBQUNULGlCQUFLLFdBQVcsR0FBRyxLQUFLLENBQUM7QUFDekIsaUJBQUssY0FBYyxHQUFHLEtBQUssQ0FBQztBQUM1QixZQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDbkIsWUFBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO1VBQ3JCLENBQUMsQ0FBQztRQUVKOztBQU9ELGFBQVE7Ozs7Ozs7O2NBQUEsa0JBQUMsR0FBRyxFQUFDLElBQUksRUFBRTtBQUNqQixhQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDckIsYUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ3ZCLGFBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUNiLGFBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN2Qjs7QUFPRCxjQUFTOzs7Ozs7OztjQUFBLG1CQUFDLElBQUksRUFBRSxFQUFFLEVBQUU7QUFDbEIsYUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDekM7O0FBT0QsZ0JBQVc7Ozs7Ozs7O2NBQUEscUJBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtBQUNyQixhQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMzQjs7OztVQWhRa0IsS0FBSztJQUFTLFNBQVM7O2tCQUF2QixLQUFLOzs7Ozs7OztBQ2pLMUIsYUFBWSxDQUFDOzs7Ozs7Ozs7O0FBRWIsS0FBSSxHQUFHLEdBQUcsbUJBQU8sQ0FBQyxDQUFhLENBQUMsQ0FBQztBQUNqQyxLQUFJLEdBQUcsR0FBRyxtQkFBTyxDQUFDLENBQWEsQ0FBQyxDQUFDO0FBQ2pDLEtBQUksU0FBUyxHQUFHLG1CQUFPLENBQUMsQ0FBbUIsQ0FBQyxDQUFDO0FBQzdDLEtBQUksY0FBYyxHQUFHLG1CQUFPLENBQUMsRUFBOEIsQ0FBQyxDQUFDO0FBQzdELEtBQUksV0FBVyxHQUFHLG1CQUFPLENBQUMsRUFBa0IsQ0FBQyxDQUFDO0FBQzlDLEtBQUksWUFBWSxHQUFHLG1CQUFPLENBQUMsRUFBbUIsQ0FBQyxDQUFDO0FBQ2hELEtBQUksS0FBSyxHQUFHLG1CQUFPLENBQUMsQ0FBZSxDQUFDLENBQUM7O0tBSS9CLFVBQVU7QUFFSCxZQUZQLFVBQVUsR0FFQTsyQkFGVixVQUFVOztBQUlaLFNBQUksT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFFLENBQUM7O0FBRXpCLFNBQUksUUFBUSxHQUFHO0FBQ2IsYUFBUSxDQUFDLEVBQUUsRUFBQyxFQUFFLENBQUM7QUFDZixlQUFVLEtBQUs7QUFDZixhQUFRLFFBQVE7QUFDaEIsY0FBUyxDQUFDO01BQ1gsQ0FBQzs7QUFFRixnQ0FiRSxVQUFVLDZDQWFOLFNBQVMsRUFBQyxPQUFPLEVBQUMsUUFBUSxFQUFFOztBQUVsQyxTQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO0FBQ2pDLFNBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7QUFDN0IsU0FBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQzs7QUFFbkMsU0FBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQzs7QUFFbkMsU0FBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7QUFDekIsU0FBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7O0FBRXhCLFNBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNaLFNBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUVmOzthQTNCRyxVQUFVOztnQkFBVixVQUFVO0FBNkJkLGVBQVU7Y0FBQSxzQkFBRztBQUNYLGFBQUksQ0FBQyxPQUFPLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNqQyxhQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzlDLGFBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDaEQsYUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQztBQUMvQixhQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO0FBQ2hDLGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUM7QUFDekMsYUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZDOztBQUVELG1CQUFjO2NBQUEsMEJBQUc7OztBQUVmLGFBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM5QixhQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7O0FBRW5DLGFBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDOzs7O0FBSWxDLGFBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFOztBQUVqQixlQUFJLENBQUMsS0FBSyxHQUFHLFlBQU07QUFDakIsbUJBQUssTUFBTSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7QUFDL0IsbUJBQUssTUFBTSxDQUFDLFVBQVUsR0FBRyxDQUFDLE1BQUssS0FBSyxDQUFDO0FBQ3JDLG1CQUFLLElBQUksQ0FBQyxNQUFLLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNuQyxDQUFDO0FBQ0YsZUFBSSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsWUFBTTtBQUMzQyxpQkFBSSxNQUFLLE1BQU0sQ0FBQyxXQUFXLEVBQUU7QUFDM0IscUJBQUssSUFBSSxDQUFDLE1BQUssTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2NBQ25DO1lBQ0YsQ0FBQyxDQUFDOztBQUdILGVBQUksQ0FBQyxJQUFJLEdBQUcsWUFBTSxFQUNqQixDQUFDO0FBQ0YsZUFBSSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsVUFBQyxDQUFDLEVBQUs7QUFDNUMsaUJBQUksTUFBSyxNQUFNLENBQUMsV0FBVyxFQUFFO0FBQzNCLG1CQUFJLENBQUMsTUFBSyxNQUFNLEVBQUU7QUFDaEIsdUJBQUssTUFBTSxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBSyxPQUFPLENBQUMsQ0FBQztnQkFDOUM7QUFDRCxxQkFBSyxLQUFLLEdBQUcsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUMsTUFBSyxNQUFNLENBQUMsQ0FBQztBQUM1QyxxQkFBSyxJQUFJLEVBQUUsQ0FBQztjQUNiO1lBQ0YsQ0FBQyxDQUFDOztBQUdILGVBQUksQ0FBQyxPQUFPLEdBQUcsWUFBTTtBQUNuQixtQkFBSyxNQUFNLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztZQUNqQyxDQUFDO0FBQ0YsZUFBSSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsWUFBTTtBQUN6QyxpQkFBSSxNQUFLLE1BQU0sQ0FBQyxXQUFXLEVBQUU7QUFDM0IscUJBQUssRUFBRSxFQUFFLENBQUM7Y0FDWDtZQUNGLENBQUMsQ0FBQztBQUNILGVBQUksQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLFlBQU07QUFDMUMsaUJBQUksTUFBSyxNQUFNLENBQUMsV0FBVyxFQUFFO0FBQzNCLHFCQUFLLEVBQUUsRUFBRSxDQUFDO2NBQ1g7WUFDRixDQUFDLENBQUM7VUFDSjtRQUVGOztBQUVELGtCQUFhO2NBQUEseUJBQUc7O0FBRWQsYUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdCLGFBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixhQUFJLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFO0FBQ2xCLGVBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO1VBQ2hELE1BQU07QUFDTCxlQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1VBQzVDO0FBQ0QsYUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUNuQixlQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztVQUNsRCxNQUFNO0FBQ0wsZUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztVQUM5Qzs7QUFFRCxhQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFeEQ7O0FBRUQsV0FBTTtjQUFBLGtCQUFHO0FBQ1AsYUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUU7QUFDZixlQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7VUFDeEQsTUFBTTtBQUNMLGVBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztVQUMxRDtRQUNGOzs7O1VBckhHLFVBQVU7SUFBUyxjQUFjOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQWdLbEIsU0FBUztBQUVqQixZQUZRLFNBQVMsR0FFZDsyQkFGSyxTQUFTOztBQUkxQixTQUFJLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDOztBQUV4QixTQUFJLFFBQVEsR0FBRztBQUNiLGFBQVEsQ0FBQyxHQUFHLEVBQUMsR0FBRyxDQUFDO0FBQ2pCLGFBQVEsUUFBUTtBQUNoQixhQUFRLENBQUM7QUFDVCxnQkFBVyxFQUFFO01BQ2QsQ0FBQzs7QUFFRixnQ0FiaUIsU0FBUyw2Q0FhcEIsU0FBUyxFQUFDLE9BQU8sRUFBQyxRQUFRLEVBQUU7O0FBRWxDLFNBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7Ozs7Ozs7QUFPakIsU0FBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQzs7Ozs7O0FBTS9CLFNBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBQyxZQUFXLEVBQUUsRUFBQyxLQUFLLENBQUMsQ0FBQzs7Ozs7O0FBTTVELFNBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUN4RSxTQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUM7Ozs7OztBQU10QixTQUFJLENBQUMsT0FBTyxHQUFHLElBQUksWUFBWSxDQUFDLENBQUMsRUFBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7O0FBRWhELFNBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUViOzthQTdDa0IsU0FBUzs7Z0JBQVQsU0FBUztBQStDNUIsZUFBVTtjQUFBLHNCQUFHO0FBQ1gsYUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzdDLGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUM7QUFDekMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztBQUNyQyxhQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDO0FBQ2xDLGFBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7QUFDbkMsYUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3RDLGFBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtBQUNoQixlQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztVQUMxQjtRQUNGOztBQUVELG1CQUFjO2NBQUEsMEJBQUc7O0FBRWYsYUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7QUFDaEIsY0FBSyxJQUFJLENBQUMsR0FBQyxDQUFDLEVBQUMsQ0FBQyxHQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFDLENBQUMsRUFBRSxFQUFFOztBQUVyQyxlQUFJLFNBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQzs7O0FBR3JDLGVBQUksU0FBUyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDL0Msb0JBQVMsQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQzs7QUFHdEMsZUFBSSxJQUFJLEdBQUcsSUFBSSxVQUFVLENBQUMsU0FBUyxFQUFFO0FBQ2pDLHNCQUFTLEVBQUUsSUFBSTtBQUNmLGtCQUFLLEVBQUUsQ0FBQztBQUNSLGdCQUFHLEVBQUUsU0FBUSxDQUFDLEdBQUc7QUFDakIsbUJBQU0sRUFBRSxTQUFRLENBQUMsTUFBTTtBQUN2QixpQkFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO0FBQ2YsbUJBQU0sRUFBRSxJQUFJO1lBQ2IsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzs7O0FBR2xDLGVBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtBQUNoQixpQkFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO0FBQ25CLGlCQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsR0FBRyxZQUFNLEVBQUUsQ0FBQztBQUMxRCxpQkFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsWUFBTSxFQUFFLENBQUM7QUFDakQsaUJBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsZUFBZSxHQUFHLFlBQU0sRUFBRSxDQUFDO0FBQ3BFLGlCQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFNLEVBQUUsQ0FBQztZQUM1RDs7QUFFRCxlQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN0QixlQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztVQUVyQztBQUNELGFBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN0Qjs7QUFFRCxrQkFBYTtjQUFBLHlCQUFHOztBQUVkLGFBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztBQUMxQyxhQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7O0FBRXpDLGNBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFFLENBQUMsR0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUN0QyxlQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUNyQyxvQkFBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQztBQUMvRCxvQkFBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsVUFBVSxHQUFHLElBQUksQ0FBQztBQUM1RCxlQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUMsVUFBVSxDQUFDLENBQUM7VUFDNUM7UUFHRjs7QUFFRCxtQkFBYztjQUFBLDBCQUFHO0FBQ2YsY0FBSyxJQUFJLENBQUMsR0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQ3RDLGVBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7VUFDeEI7UUFDRjs7QUFFRCxXQUFNO2NBQUEsa0JBQUc7Ozs7O0FBR1AsYUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsVUFBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUMsRUFBSzs7QUFFN0IsZUFBSSxNQUFLLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssTUFBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFO0FBQ3JELGlCQUFJLE1BQUssTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUU7QUFDakMscUJBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO2NBQ3hCLE1BQU07QUFDTCxxQkFBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7Y0FDekI7WUFDRjtVQUNGLENBQUMsQ0FBQztRQUNKOztBQVNELGNBQVM7Ozs7Ozs7OztjQUFBLG1CQUFDLElBQUksRUFBQyxFQUFFLEVBQUU7Ozs7QUFJakIsYUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7O0FBRXBDLGFBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hELGFBQUksSUFBSSxHQUFHO0FBQ1QsY0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHO0FBQ2IsaUJBQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtBQUNuQixnQkFBSyxFQUFFLEVBQUU7VUFDVixDQUFDO0FBQ0YsYUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUI7O0FBRUQsV0FBTTtjQUFBLGtCQUFHOzs7QUFDUCxhQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxJQUFJLENBQUMsRUFBRTtBQUMzQixlQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFDLENBQUMsRUFBQyxDQUFDLEVBQUMsQ0FBQyxFQUFLO0FBQzdCLGlCQUFJLENBQUMsS0FBRyxNQUFLLE9BQU8sQ0FBQyxLQUFLLEVBQUU7QUFDMUIscUJBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLE1BQUssTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ2pFLHFCQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBQyxHQUFHLENBQUMsQ0FBQztBQUNuRCxxQkFBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsRUFBQyxHQUFHLENBQUMsQ0FBQztjQUN0RCxNQUFNO0FBQ0wscUJBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLE1BQU0sQ0FBQyxDQUFDO2NBQ2pEO1lBQ0YsQ0FBQyxDQUFDO1VBQ0o7UUFDRjs7QUFNRCxVQUFLOzs7Ozs7O2NBQUEsZUFBQyxFQUFFLEVBQUU7QUFDUixhQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMzQyxhQUFJLEVBQUUsRUFBRTtBQUNOLGVBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1VBQ3RCO0FBQ0QsYUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN2Qjs7QUFLRCxTQUFJOzs7Ozs7Y0FBQSxnQkFBRztBQUNMLGFBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdEI7O0FBS0QsU0FBSTs7Ozs7O2NBQUEsZ0JBQUc7QUFDTCxhQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ3BCLGFBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztBQUNuRSxhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZjs7QUFFRCxzQkFBaUI7Y0FBQSw2QkFBRzs7O0FBRWxCLGFBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLFlBQU0sRUFBRSxDQUFDO0FBQzFELGFBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLFlBQU0sRUFBRSxDQUFDO0FBQ2pELGFBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsZUFBZSxHQUFHLFlBQU0sRUFBRSxDQUFDO0FBQ3BFLGFBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQU0sRUFBRSxDQUFDOztBQUUzRCxhQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQzs7QUFFNUIsYUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLEVBQUUsVUFBQyxDQUFDLEVBQUs7QUFDakQsZUFBSSxPQUFPLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDL0YsZUFBSSxJQUFJLEdBQUcsTUFBSyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3JDLGlCQUFLLFVBQVUsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7QUFDOUIsZUFBSSxDQUFDLElBQUksQ0FBQyxNQUFLLFVBQVUsQ0FBQyxDQUFDO0FBQzNCLGlCQUFLLGNBQWMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDO0FBQ3BDLFlBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztBQUNuQixZQUFDLENBQUMsZUFBZSxFQUFFLENBQUM7VUFDckIsQ0FBQyxDQUFDOztBQUVILGFBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLFVBQUMsQ0FBQyxFQUFLO0FBQ2hELGVBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQy9GLGVBQUksSUFBSSxHQUFHLE1BQUssS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNyQyxlQUFJLE9BQU8sQ0FBQyxLQUFLLEtBQUcsTUFBSyxjQUFjLEVBQUU7QUFDdkMsaUJBQUksTUFBSyxjQUFjLElBQUksQ0FBQyxFQUFFO0FBQzVCLG1CQUFJLFFBQVEsR0FBRyxNQUFLLEtBQUssQ0FBQyxNQUFLLGNBQWMsQ0FBQyxDQUFDO0FBQy9DLHVCQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7Y0FDZjtBQUNELGlCQUFJLENBQUMsSUFBSSxDQUFDLE1BQUssVUFBVSxDQUFDLENBQUM7WUFDNUIsTUFBTTtBQUNMLGlCQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDYjtBQUNELGlCQUFLLGNBQWMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDO0FBQ3BDLFlBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztBQUNuQixZQUFDLENBQUMsZUFBZSxFQUFFLENBQUM7VUFDckIsQ0FBQyxDQUFDOztBQUVILGFBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLFVBQUMsQ0FBQyxFQUFLOztBQUUvQyxlQUFJLElBQUksR0FBRyxNQUFLLEtBQUssQ0FBQyxNQUFLLGNBQWMsQ0FBQyxDQUFDO0FBQzNDLGVBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztBQUNWLGlCQUFLLFdBQVcsR0FBRyxLQUFLLENBQUM7QUFDekIsaUJBQUssY0FBYyxHQUFHLEtBQUssQ0FBQztBQUM1QixZQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDbkIsWUFBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO1VBQ3JCLENBQUMsQ0FBQztRQUVKOztBQVVHLFNBQUk7Ozs7Ozs7WUFKQSxZQUFHO0FBQ1QsZ0JBQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFDekI7WUFFTyxVQUFDLENBQUMsRUFBRTtBQUNWLGFBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztBQUNyQixhQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDYixhQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDdEIsYUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2Y7O0FBVUcsWUFBTzs7Ozs7OztZQUpBLFlBQUc7QUFDWixnQkFBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQztRQUM1QjtZQUVVLFVBQUMsQ0FBQyxFQUFFO0FBQ2IsYUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCLGFBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUNyQixhQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDYixhQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDdEIsYUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2Y7Ozs7VUFqUmtCLFNBQVM7SUFBUyxTQUFTOztrQkFBM0IsU0FBUyxDOzs7Ozs7QUM1SzlCLGFBQVksQ0FBQzs7Ozs7Ozs7S0FFTixJQUFJLHVDQUFNLENBQWM7O0tBQ3hCLFFBQVEsdUNBQU0sRUFBb0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7S0F1QnBCLE1BQU07QUFFZCxZQUZRLE1BQU0sQ0FFYixJQUFJLEVBQUMsT0FBTyxFQUFFOzs7MkJBRlAsTUFBTTs7O0FBSXZCLFNBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLFNBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFDLE9BQU8sQ0FBQyxDQUFDOztBQUUxQixTQUFJLENBQUMsTUFBTSxHQUFHO0FBQ1osV0FBSSxFQUFFLFVBQUMsTUFBTSxFQUFFLEdBQUcsRUFBSztBQUNyQixlQUFLLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQUssT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3ZELGFBQUksTUFBSyxFQUFFLEVBQUU7QUFBRSxpQkFBSyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7VUFBRTtBQUNsQyxnQkFBTyxNQUFLLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsQztBQUNELFVBQUcsRUFBRSxZQUFNO0FBQ1QsZUFBSyxPQUFPLENBQUMsVUFBQyxDQUFDLEVBQUMsQ0FBQyxFQUFLO0FBQUUsaUJBQUssTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUM7VUFBRSxDQUFDLENBQUM7QUFDbEQsYUFBSSxNQUFLLEVBQUUsRUFBRTtBQUFFLGlCQUFLLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztVQUFFO1FBQ25DO0FBQ0QsVUFBRyxFQUFFLFVBQUMsR0FBRyxFQUFLO0FBQ1osY0FBSyxJQUFJLENBQUMsR0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFDLE1BQUssT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQ2pDLGlCQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDLEdBQUcsQ0FBQyxDQUFDO1VBQ3pCO0FBQ0QsYUFBSSxNQUFLLEVBQUUsRUFBRTtBQUFFLGlCQUFLLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztVQUFFO1FBQ25DO0FBQ0QsYUFBTSxFQUFFLFVBQUMsTUFBTSxFQUFLO0FBQ2xCLGNBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFFLENBQUMsR0FBQyxNQUFLLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUM5QixpQkFBSyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBQyxDQUFDLENBQUMsQ0FBQztVQUM1QjtBQUNELGFBQUksTUFBSyxFQUFFLEVBQUU7QUFBRSxpQkFBSyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7VUFBRTtRQUNuQztNQUNGLENBQUM7O0FBRUYsU0FBSSxDQUFDLEdBQUcsR0FBRztBQUNULFdBQUksRUFBRSxVQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFLO0FBQzVCLGVBQUssT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUNsQyxhQUFJLE1BQUssRUFBRSxFQUFFO0FBQUUsaUJBQUssRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO1VBQUU7UUFDbkM7QUFDRCxVQUFHLEVBQUUsVUFBQyxNQUFNLEVBQUs7OztBQUdmLGVBQUssT0FBTyxHQUFHLE1BQU0sQ0FBQztBQUN0QixhQUFJLE1BQUssRUFBRSxFQUFFO0FBQUUsaUJBQUssRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO1VBQUU7UUFDbkM7QUFDRCxVQUFHLEVBQUUsVUFBQyxHQUFHLEVBQUMsTUFBTSxFQUFLOztBQUVuQixlQUFLLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUM7QUFDM0IsYUFBSSxNQUFLLEVBQUUsRUFBRTtBQUFFLGlCQUFLLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztVQUFFO1FBQ25DO0FBQ0QsYUFBTSxFQUFFLFVBQUMsTUFBTSxFQUFDLE1BQU0sRUFBSzs7QUFFekIsZUFBSyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQUMsR0FBRyxFQUFDLENBQUMsRUFBSztBQUM5QixpQkFBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1VBQ3JDLENBQUMsQ0FBQztBQUNILGFBQUksTUFBSyxFQUFFLEVBQUU7QUFBRSxpQkFBSyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7VUFBRTtRQUNuQztNQUNGLENBQUM7O0FBRUYsU0FBSSxDQUFDLE1BQU0sR0FBRzs7O0FBR1osVUFBRyxFQUFFLFVBQUMsTUFBTSxFQUFLO0FBQ2YsYUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLEtBQUcsQ0FBQyxFQUFFO0FBQ3pCLGlCQUFNLEdBQUcsQ0FBQyxDQUFDO1VBQ1o7QUFDRCxlQUFNLElBQUksTUFBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0FBQ2pDLGFBQUksTUFBTSxHQUFHLENBQUMsRUFBRTtBQUNkLGlCQUFNLEdBQUcsTUFBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztVQUMxQztBQUNELGNBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFFLENBQUMsR0FBQyxNQUFLLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUM5QixlQUFJLEdBQUcsR0FBRyxNQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUUsTUFBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLE1BQU0sRUFBRSxNQUFNLENBQUUsQ0FBQztBQUM1RSxpQkFBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBRSxNQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBRSxDQUFDO1VBQ2pEO0FBQ0QsYUFBSSxNQUFLLEVBQUUsRUFBRTtBQUFFLGlCQUFLLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztVQUFFO1FBQ25DO0FBQ0QsVUFBRyxFQUFFLFVBQUMsR0FBRyxFQUFDLE1BQU0sRUFBSztBQUNuQixhQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sS0FBRyxDQUFDLEVBQUU7QUFDekIsaUJBQU0sR0FBRyxDQUFDLENBQUM7VUFDWjtBQUNELGVBQU0sSUFBSSxNQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7QUFDakMsYUFBSSxNQUFNLEdBQUcsQ0FBQyxFQUFFO0FBQ2QsaUJBQU0sR0FBRyxNQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1VBQzFDO0FBQ0QsYUFBSSxHQUFHLEdBQUcsTUFBSyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFFLE1BQUssT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sR0FBRyxNQUFNLEVBQUUsTUFBTSxDQUFFLENBQUM7QUFDaEYsZUFBSyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBRSxNQUFLLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBRSxDQUFDO0FBQ3BELGFBQUksTUFBSyxFQUFFLEVBQUU7QUFBRSxpQkFBSyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7VUFBRTtRQUNuQztBQUNELGFBQU0sRUFBRSxVQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUs7QUFDMUIsYUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLEtBQUcsQ0FBQyxFQUFFO0FBQ3pCLGlCQUFNLEdBQUcsQ0FBQyxDQUFDO1VBQ1o7QUFDRCxlQUFNLElBQUksTUFBSyxPQUFPLENBQUMsTUFBTSxDQUFDO0FBQzlCLGFBQUksTUFBTSxHQUFHLENBQUMsRUFBRTtBQUNkLGlCQUFNLEdBQUcsTUFBSyxPQUFPLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztVQUN2QztBQUNELGFBQUksS0FBSyxHQUFHLEVBQUUsQ0FBQztBQUNmLGVBQUssT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFDLEdBQUcsRUFBSztBQUM1QixnQkFBSyxDQUFDLElBQUksQ0FBRSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUUsQ0FBQztVQUMzQixDQUFDLENBQUM7QUFDSCxhQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFFLEtBQUssQ0FBQyxNQUFNLEdBQUcsTUFBTSxFQUFFLE1BQU0sQ0FBRSxDQUFDO0FBQ3hELGNBQUssR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFFLEtBQUssQ0FBRSxDQUFDO0FBQzVCLGVBQUssT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFDLEdBQUcsRUFBQyxDQUFDLEVBQUs7QUFDOUIsY0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztVQUN4QixDQUFDLENBQUM7QUFDSCxhQUFJLE1BQUssRUFBRSxFQUFFO0FBQUUsaUJBQUssRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO1VBQUU7UUFDbkM7TUFDRixDQUFDOzs7OztBQUtGLFNBQUksQ0FBQyxRQUFRLEdBQUc7QUFDZCxVQUFHLEVBQUUsVUFBQyxJQUFJLEVBQUs7QUFDYixhQUFJLFlBQVksR0FBRyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN0QyxlQUFLLE9BQU8sQ0FBQyxVQUFDLENBQUMsRUFBQyxDQUFDLEVBQUs7QUFDcEIsaUJBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7VUFDckQsQ0FBQyxDQUFDOzs7OztBQUtILGFBQUksTUFBSyxFQUFFLEVBQUU7QUFBRSxpQkFBSyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7VUFBRTtRQUNuQztBQUNELFVBQUcsRUFBRSxZQUFrQjthQUFqQixHQUFHLGdDQUFDLENBQUM7YUFBQyxJQUFJLGdDQUFDLENBQUM7O0FBQ2hCLGFBQUksWUFBWSxHQUFHLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3RDLGVBQUssT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFDLElBQUksRUFBQyxDQUFDLEVBQUs7QUFDcEMsaUJBQUssT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7VUFDdkQsQ0FBQyxDQUFDO0FBQ0gsYUFBSSxNQUFLLEVBQUUsRUFBRTtBQUFFLGlCQUFLLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztVQUFFO1FBQ25DO0FBQ0QsYUFBTSxFQUFFLFlBQXFCO2FBQXBCLE1BQU0sZ0NBQUMsQ0FBQzthQUFDLElBQUksZ0NBQUMsQ0FBQzs7QUFDdEIsYUFBSSxZQUFZLEdBQUcsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDdEMsZUFBSyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQUMsR0FBRyxFQUFDLENBQUMsRUFBSztBQUM5QixpQkFBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztVQUMxRCxDQUFDLENBQUM7QUFDSCxhQUFJLE1BQUssRUFBRSxFQUFFO0FBQUUsaUJBQUssRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO1VBQUU7UUFDbkM7TUFDRixDQUFDOzs7QUFHRixTQUFJLENBQUMsS0FBSyxHQUFHO0FBQ1gsVUFBRyxFQUFFLFlBQU07QUFDVCxlQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakI7QUFDRCxVQUFHLEVBQUUsVUFBQyxHQUFHLEVBQUs7QUFDWixlQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCO0FBQ0QsYUFBTSxFQUFFLFVBQUMsTUFBTSxFQUFLO0FBQ2xCLGVBQUssR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0I7TUFDRixDQUFDOzs7SUFHSDs7Z0JBdkprQixNQUFNO0FBMEp6QixXQUFNO2NBQUEsZ0JBQUMsSUFBSSxFQUFDLE9BQU8sRUFBRTs7O0FBQ25CLGFBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLGNBQU0sSUFBSSxHQUFHLEdBQUMsQ0FBQyxFQUFFLEdBQUcsR0FBRyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUc7QUFDbkMsZUFBSSxHQUFHLEdBQUcsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDN0IsZUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7VUFDeEI7QUFDRCxhQUFJLENBQUMsT0FBTyxDQUFDLFVBQUMsQ0FBQyxFQUFDLENBQUMsRUFBSztBQUFFLGlCQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7VUFBRSxDQUFDLENBQUM7UUFDeEQ7O0FBRUQsWUFBTztjQUFBLGlCQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7QUFDYixhQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDVixjQUFNLElBQUksR0FBRyxHQUFDLENBQUMsRUFBRSxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRztBQUN4QyxlQUFJLEVBQUUsRUFBRTtBQUFFLGVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUFFO0FBQ3BCLGdCQUFNLElBQUksTUFBTSxHQUFDLENBQUMsRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRztBQUNwRCxjQUFDLENBQUMsR0FBRyxFQUFDLE1BQU0sRUFBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixjQUFDLEVBQUUsQ0FBQztZQUNMO1VBQ0Y7UUFDRjs7QUFFRCxpQkFBWTtjQUFBLHdCQUFHOzs7QUFDYixhQUFJLGFBQWEsR0FBRyxFQUFFLENBQUM7QUFDdkIsYUFBSSxDQUFDLE9BQU8sQ0FDVixVQUFDLENBQUMsRUFBQyxDQUFDLEVBQUs7QUFBRSx3QkFBYSxJQUFJLENBQUMsTUFBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUM7VUFBRSxFQUNqRSxZQUFNO0FBQUUsd0JBQWEsSUFBSSxJQUFJLENBQUM7VUFBRSxDQUNqQyxDQUFDO0FBQ0YsZ0JBQU8sYUFBYSxDQUFDO1FBQ3RCOztBQUVELFFBQUc7Y0FBQSxlQUFHO0FBQ0osZ0JBQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7UUFDbEM7O0FBRUQsV0FBTTtjQUFBLGdCQUFDLE9BQU8sRUFBRTtBQUNkLGFBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDeEM7O0FBRUcsV0FBTTtZQUFBLFlBQUc7QUFDWCxnQkFBTyxJQUFJLENBQUMsSUFBSSxHQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDL0I7O0FBRUQsV0FBTTtjQUFBLGdCQUFDLEtBQUssRUFBRTs7QUFFWixnQkFBTztBQUNMLGNBQUcsRUFBRSxFQUFDLEVBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUU7QUFDL0IsaUJBQU0sRUFBRSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU87VUFDN0IsQ0FBQztRQUNIOztBQUVELFlBQU87Y0FBQSxpQkFBQyxHQUFHLEVBQUMsTUFBTSxFQUFFO0FBQ2xCLGdCQUFPLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQzs7UUFFcEM7O0FBRUQsUUFBRzs7Ozs7Ozs7Ozs7VUFBQSxVQUFDLEdBQUcsRUFBRTtBQUNQLGFBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUNkLGNBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFFLENBQUMsR0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQ2pDLGVBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7VUFDdEM7QUFDRCxnQkFBTyxJQUFJLENBQUM7UUFDYjs7QUFFRCxXQUFNOzs7Ozs7Ozs7OztVQUFBLFVBQUMsTUFBTSxFQUFFO0FBQ2IsYUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDO0FBQ2QsY0FBSyxJQUFJLENBQUMsR0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDOUIsZUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztVQUM1QztBQUNELGdCQUFPLElBQUksQ0FBQztRQUNiOztBQUtHLFNBQUk7WUFIQSxZQUFHO0FBQ1QsZ0JBQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDNUI7WUFDTyxVQUFDLENBQUMsRUFBRTs7O0FBQ1YsYUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckMsYUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzVCLGFBQUksQ0FBQyxPQUFPLENBQUMsVUFBQyxDQUFDLEVBQUMsQ0FBQyxFQUFLO0FBQ3BCLGVBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUNqQyxtQkFBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JDO1VBQ0YsQ0FBQyxDQUFDO1FBQ0o7O0FBS0csWUFBTztZQUhBLFlBQUc7QUFDWixnQkFBTyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUMvQjtZQUNVLFVBQUMsQ0FBQyxFQUFFOzs7QUFDYixhQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNyQyxhQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUMsQ0FBQyxDQUFDLENBQUM7QUFDekIsYUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFDLENBQUMsRUFBQyxDQUFDLEVBQUs7QUFDcEIsZUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ2pDLG1CQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckM7VUFDRixDQUFDLENBQUM7UUFDSjs7OztVQXhQa0IsTUFBTTs7O2tCQUFOLE1BQU0sQzs7Ozs7O0FDMUIzQixhQUFZLENBQUM7Ozs7Ozs7O0tBRU4sSUFBSSx1Q0FBTSxDQUFjOztLQUN4QixLQUFLLHVDQUFNLEVBQVM7O0tBRU4sUUFBUTtBQUVkLFlBRk0sUUFBUSxHQUV1QztTQUFwRCxRQUFRLGdDQUFHLENBQUMsQ0FBQyxFQUFDLEVBQUUsRUFBQyxFQUFFLEVBQUMsRUFBRSxDQUFDO1NBQUUsSUFBSSxnQ0FBQyxJQUFJO1NBQUUsUUFBUSxnQ0FBQyxLQUFLOzsyQkFGN0MsUUFBUTs7QUFHckIsU0FBSSxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUM7QUFDdkIsU0FBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFO0FBQy9CLFdBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7TUFDN0I7QUFDRCxTQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztBQUNsQixTQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQzs7QUFFekIsU0FBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7O0FBRXRELFNBQUksQ0FBQyxXQUFXLEdBQUc7QUFDakIsV0FBTSxDQUFDO0FBQ1AsYUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDO0FBQzlCLGNBQVMsRUFBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFDLENBQUMsQ0FBQztBQUNqQyxlQUFVLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUM7TUFDdEMsQ0FBQzs7QUFFRixTQUFJLElBQUksQ0FBQyxRQUFRLEtBQUcsS0FBSyxFQUFFO0FBQ3pCLFdBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztNQUM5QixNQUFNO0FBQ0wsV0FBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO01BQ3hCO0lBR0o7O2dCQTFCZ0IsUUFBUTtBQWdDckIsU0FBSTtZQUpBLFlBQUc7QUFDVCxnQkFBTyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ25CO1lBRU8sVUFBQyxJQUFJLEVBQUU7QUFDWCxhQUFJLEVBQUUsSUFBSSxLQUFLLElBQUksSUFBSSxJQUFJLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxRQUFRLElBQUksSUFBSSxLQUFLLE9BQU8sQ0FBQyxFQUFFO0FBQzlFLGtCQUFPLENBQUMsS0FBSyxDQUFDLCtEQUErRCxDQUFDLENBQUM7QUFDL0Usa0JBQU87VUFDVjtBQUNELGFBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ2xCLGFBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtBQUNqQixlQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7VUFDOUI7UUFDSjs7QUFNRyxVQUFLO1lBSkEsWUFBRztBQUNWLGdCQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ25DO1lBRVEsVUFBQyxDQUFDLEVBQUU7QUFDWCxhQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDOztBQUVELFVBQUs7Y0FBQSxpQkFBRztBQUNOLGFBQUksSUFBSSxDQUFDLFFBQVEsS0FBRyxLQUFLLEVBQUU7QUFDekIsZUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzdCLGtCQUFPLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztVQUNwQjtBQUNELGFBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDN0MsYUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzdCLGdCQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDbkI7O0FBRUQsT0FBRTtjQUFBLGNBQUc7QUFDSCxhQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDaEIsYUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztBQUNwQyxnQkFBTyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ25COztBQUVELFNBQUk7Y0FBQSxnQkFBRztBQUNMLGFBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUNoQixhQUFJLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxFQUFFO0FBQ3JCLGVBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDO1VBQzNFO0FBQ0QsZ0JBQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNuQjs7QUFFRCxXQUFNO2NBQUEsa0JBQUc7QUFDUCxhQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDL0MsZ0JBQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNuQjs7QUFFRCxVQUFLO2NBQUEsaUJBQUc7QUFDTixhQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztBQUN4QyxhQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQ3JDLGFBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUN0QyxnQkFBTyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ25COzs7Ozs7O0FBQUE7Ozs7VUFyRmdCLFFBQVE7OztrQkFBUixRQUFRLEM7Ozs7OztBQ0w3QixhQUFZLENBQUM7Ozs7Ozs7O0tBRU4sSUFBSSx1Q0FBTSxDQUFjOztLQUVWLEtBQUs7QUFFWCxjQUZNLEtBQUssR0FFc0M7YUFBaEQsR0FBRyxnQ0FBQyxDQUFDO2FBQUUsR0FBRyxnQ0FBQyxDQUFDO2FBQUUsS0FBSyxnQ0FBQyxDQUFDO2FBQUUsU0FBUyxnQ0FBQyxDQUFDO2FBQUUsSUFBSSxnQ0FBQyxLQUFLOzsrQkFGekMsS0FBSzs7QUFHbEIsYUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDZixhQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNmLGFBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0FBQ25CLGFBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO0FBQzNCLGFBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO01BQ3BCOztrQkFSZ0IsS0FBSztBQVV0QixhQUFJO29CQUFBLGdCQUFHO0FBQ0gscUJBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUM3RCxxQkFBSSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUU7QUFDdkIseUJBQUksSUFBSSxDQUFDLElBQUksRUFBRTtBQUNYLDZCQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7c0JBQ3pCLE1BQU07QUFDSCw2QkFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7c0JBQzFDO2tCQUNKOztBQUVELHFCQUFJLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRTtBQUN2Qix5QkFBSSxJQUFJLENBQUMsSUFBSSxFQUFFO0FBQ1gsNkJBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztzQkFDekIsTUFBTTtBQUNILDZCQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztzQkFDMUM7a0JBQ0o7QUFDRCx3QkFBTyxJQUFJLENBQUMsS0FBSyxDQUFDO2NBQ3JCOzs7O1lBNUJnQixLQUFLOzs7a0JBQUwsS0FBSyxDOzs7Ozs7QUNKMUIsYUFBWSxDQUFDOzs7Ozs7OztLQUVOLElBQUksdUNBQU0sQ0FBYzs7S0FDeEIsS0FBSyx1Q0FBTSxFQUFTOztLQUVOLE9BQU87QUFFYixjQUZNLE9BQU8sR0FFMkI7YUFBdkMsR0FBRyxnQ0FBQyxDQUFDO2FBQUUsR0FBRyxnQ0FBQyxFQUFFO2FBQUUsSUFBSSxnQ0FBQyxJQUFJO2FBQUUsS0FBSyxnQ0FBQyxLQUFLOzsrQkFGaEMsT0FBTzs7QUFHcEIsYUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDZixhQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNmLGFBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0FBQ25CLGFBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ2pCLGFBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDL0MsYUFBSSxJQUFJLENBQUMsS0FBSyxLQUFHLEtBQUssRUFBRTtBQUN0QixpQkFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1VBQzlCLE1BQU07QUFDTCxpQkFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1VBQ3hCO01BQ0o7O2tCQWJnQixPQUFPO0FBMEJwQixhQUFJO2tCQVhBLFVBQUMsSUFBSSxFQUFFO0FBQ1gscUJBQUksRUFBRSxJQUFJLEtBQUssSUFBSSxJQUFJLElBQUksS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLFFBQVEsSUFBSSxJQUFJLEtBQUssT0FBTyxDQUFDLEVBQUU7QUFDOUUsNEJBQU8sQ0FBQyxLQUFLLENBQUMsK0RBQStELENBQUMsQ0FBQztBQUMvRSw0QkFBTztrQkFDVjtBQUNELHFCQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztBQUNsQixxQkFBSSxJQUFJLENBQUMsS0FBSyxFQUFFO0FBQ2QseUJBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztrQkFDOUI7Y0FDSjtrQkFFTyxZQUFHO0FBQ1Asd0JBQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztjQUNyQjs7QUFFRCxjQUFLO29CQUFBLGlCQUFHO0FBQ04scUJBQUksSUFBSSxDQUFDLEtBQUssS0FBRyxLQUFLLEVBQUU7QUFDdEIseUJBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM3Qiw0QkFBTyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7a0JBQ3BCO0FBQ0QscUJBQUksQ0FBQyxXQUFXLEdBQUc7QUFDakIseUJBQU0sSUFBSSxDQUFDLEdBQUc7QUFDZCwyQkFBUSxJQUFJLENBQUMsR0FBRztBQUNoQiw0QkFBUyxFQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7QUFDMUMsNkJBQVUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7a0JBQ3JDLENBQUM7QUFDRixxQkFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMxQyxxQkFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzdCLHdCQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7Y0FDbkI7O0FBRUQsV0FBRTtvQkFBQSxjQUFHO0FBQ0QscUJBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUNiLHFCQUFJLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRTtBQUN4Qix5QkFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO2tCQUN6QjtBQUNELHdCQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7Y0FDckI7O0FBRUQsYUFBSTtvQkFBQSxnQkFBRztBQUNILHFCQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDYixxQkFBSSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUU7QUFDdkIseUJBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztrQkFDekI7QUFDRCx3QkFBTyxJQUFJLENBQUMsS0FBSyxDQUFDO2NBQ3JCOztBQUVELGVBQU07b0JBQUEsa0JBQUc7QUFDTCxxQkFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pDLHdCQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7Y0FDckI7O0FBRUQsY0FBSztvQkFBQSxpQkFBRztBQUNKLHFCQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO0FBQzlCLHFCQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO0FBQzlCLHFCQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO0FBQ2xDLHFCQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDbkMsd0JBQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztjQUNyQjs7OztZQXpFZ0IsT0FBTzs7O2tCQUFQLE9BQU8sQzs7Ozs7O0FDTDVCLGFBQVksQ0FBQzs7Ozs7Ozs7Ozs7O0FBRWIsS0FBSSxHQUFHLEdBQUcsbUJBQU8sQ0FBQyxDQUFhLENBQUMsQ0FBQztBQUNqQyxLQUFJLElBQUksR0FBRyxtQkFBTyxDQUFDLENBQWMsQ0FBQyxDQUFDO0FBQ25DLEtBQUksU0FBUyxHQUFHLG1CQUFPLENBQUMsQ0FBbUIsQ0FBQyxDQUFDO0FBQzdDLEtBQUksSUFBSSxHQUFHLG1CQUFPLENBQUMsRUFBZ0IsQ0FBQyxDQUFDOztLQUN6QixXQUFXLCtDQUFNLEVBQXFCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQXlDN0IsS0FBSztBQUViLFlBRlEsS0FBSyxHQUVWOzJCQUZLLEtBQUs7O0FBSXRCLFNBQUksT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7O0FBRXhCLFNBQUksUUFBUSxHQUFHO0FBQ2IsYUFBUSxDQUFDLEdBQUcsRUFBQyxHQUFHLENBQUM7QUFDakIsY0FBUyxHQUFHO0FBQ1osYUFBUSxVQUFVO0FBQ2xCLGlCQUFZLENBQ1YsQ0FBQyxHQUFHLEVBQUMsR0FBRyxDQUFDLEVBQ1QsQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLEVBQ1gsQ0FBQyxHQUFHLEVBQUMsR0FBRyxDQUFDLEVBQ1QsQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLEVBQ1gsQ0FBQyxHQUFHLEVBQUMsR0FBRyxDQUFDLEVBQ1QsQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLEVBQ1gsQ0FBQyxHQUFHLEVBQUMsR0FBRyxDQUFDLEVBQ1QsQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLENBQ1o7TUFDRixDQUFDOztBQUVGLGdDQXRCaUIsS0FBSyw2Q0FzQmhCLFNBQVMsRUFBQyxPQUFPLEVBQUMsUUFBUSxFQUFFOztBQUVsQyxTQUFJLENBQUMsS0FBSyxHQUFHO0FBQ1gsUUFBQyxFQUFFLElBQUksSUFBSSxDQUFDLENBQUMsRUFBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLEdBQUcsQ0FBQztBQUN0QixRQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsQ0FBQyxFQUFDLENBQUMsRUFBQyxDQUFDLEVBQUMsR0FBRyxDQUFDO01BQ3ZCLENBQUM7Ozs7O0FBS0YsU0FBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQzs7QUFFL0IsU0FBSSxDQUFDLFFBQVEsR0FBRztBQUNkLFFBQUMsRUFBRSxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBQyxZQUFZLEVBQUMsQ0FBQyxDQUFDLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBQyxDQUFDLENBQUMsQ0FBQztBQUNoRixRQUFDLEVBQUUsSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUMsVUFBVSxFQUFDLENBQUMsQ0FBQyxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUMsQ0FBQyxDQUFDLENBQUM7TUFDL0UsQ0FBQztBQUNGLFNBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7QUFDaEQsU0FBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQzs7Ozs7QUFLaEQsU0FBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQzs7Ozs7QUFLdkMsU0FBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQzs7Ozs7QUFLakMsU0FBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7O0FBRWpCLFNBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQzs7QUFFWixTQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7QUFDdkIsU0FBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBRWY7O2FBN0RrQixLQUFLOztnQkFBTCxLQUFLO0FBK0R4QixtQkFBYztjQUFBLDBCQUFHOztBQUVmLGFBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQzs7QUFHakMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDOzs7QUFJcEMsYUFBSSxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUM7O0FBRTFCLGNBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBQyxDQUFDLEVBQUUsRUFBRTtBQUN2QyxlQUFJLGNBQWMsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDOztBQUUxQyxlQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsQ0FBQzs7QUFFekMsZUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7VUFDM0M7UUFFRjs7QUFFRCxrQkFBYTtjQUFBLHlCQUFHOztBQUVWLGFBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzs7QUFFdEQsYUFBSSxDQUFDLFVBQVUsR0FBRztBQUNoQixjQUFHLEVBQUUsRUFBQyxFQUFFLElBQUksQ0FBQyxhQUFhLEdBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFDeEMsQ0FBQztBQUNGLGFBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQzs7QUFFN0MsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFDLElBQUksQ0FBQyxLQUFLLEdBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUMsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFDLElBQUksQ0FBQyxNQUFNLEdBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0MsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7O0FBRWhELGNBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBQyxDQUFDLEVBQUUsRUFBRTtBQUN2QyxlQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdDLGVBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IseUJBQWMsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDeEQseUJBQWMsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDekQseUJBQWMsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxhQUFhLEdBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzNELHlCQUFjLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxHQUFHLENBQUMsQ0FBQztVQUNsRDs7QUFFSCxhQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZELGFBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Ozs7O0FBS3ZELGFBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztBQUN2QixhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFakI7O0FBRUQsbUJBQWM7Y0FBQSwwQkFBRzs7QUFFZixhQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDdEQsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7O0FBRXhELGNBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBQyxDQUFDLEVBQUUsRUFBRTtBQUN2QyxlQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdDLHlCQUFjLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3hELHlCQUFjLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1VBQzNEO1FBRUY7O0FBRUQsV0FBTTtjQUFBLGtCQUFHO0FBQ1AsYUFBSSxDQUFDLGVBQWUsR0FBRztBQUNyQixZQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLO0FBQ3ZDLFlBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTTtVQUN2RCxDQUFDOztBQUVGLGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BELGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JEOztBQUdELFVBQUs7Y0FBQSxpQkFBRztBQUNOLGFBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO0FBQ3BDLGFBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO0FBQ3BDLGFBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNiOztBQUVELFNBQUk7Y0FBQSxnQkFBRztBQUNMLGFBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtBQUNoQixlQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ25DLGVBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Ozs7O0FBS25DLGVBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztBQUN2QixlQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDaEMsZUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1VBQ2Y7UUFDRjs7QUFFRCxZQUFPO2NBQUEsbUJBQUc7QUFDUixhQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZjs7QUFFRyxlQUFVO1lBQUEsWUFBRztBQUNmLGdCQUFPO0FBQ0wsWUFBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFVBQVU7QUFDMUIsWUFBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFVBQVU7VUFDM0IsQ0FBQztRQUNIOztBQUVELG9CQUFlO2NBQUEsMkJBQUc7OztBQUNoQixhQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFFLENBQUM7QUFDbkQsYUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBRSxDQUFDO0FBQ25ELGFBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO0FBQ2pCLGFBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFVBQUMsQ0FBQyxFQUFDLENBQUMsRUFBSztBQUM3QixlQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBQyxNQUFLLEtBQUssRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUMsTUFBSyxNQUFNLEVBQUMsTUFBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBQyxNQUFLLEtBQUssRUFBQyxDQUFDLENBQUMsR0FBQyxNQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFFLE1BQUssTUFBTSxDQUFDLENBQUM7QUFDdEksZUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUMsUUFBUSxJQUFFLE1BQUssS0FBSyxHQUFDLE1BQUssS0FBSyxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlELGlCQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDeEIsaUJBQUssZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUUsS0FBSyxDQUFDLENBQUM7VUFDN0QsQ0FBQyxDQUFDO1FBQ0o7O0FBT0QsZUFBVTs7Ozs7Ozs7Y0FBQSxvQkFBQyxDQUFDLEVBQUMsQ0FBQyxFQUFFO0FBQ2QsYUFBSSxRQUFRLEdBQUc7QUFDYixZQUFDLEVBQUUsQ0FBQyxHQUFDLElBQUksQ0FBQyxLQUFLO0FBQ2YsWUFBQyxFQUFFLENBQUMsR0FBQyxJQUFJLENBQUMsTUFBTTtVQUNqQixDQUFDO0FBQ0YsYUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2pDLGFBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNqQyxhQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7QUFDdkIsYUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ2hDLGFBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNmOztBQVFELGdCQUFXOzs7Ozs7Ozs7Y0FBQSxxQkFBQyxLQUFLLEVBQUMsQ0FBQyxFQUFDLENBQUMsRUFBRTs7QUFFckIsYUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixhQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM3RCxhQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM5RCxhQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7QUFDdkIsYUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ2hDLGFBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUVmOzs7Ozs7Ozs7QUFBQTs7O1VBeE5rQixLQUFLO0lBQVMsU0FBUzs7a0JBQXZCLEtBQUssQzs7Ozs7O0FDL0MxQixhQUFZLENBQUM7Ozs7Ozs7Ozs7QUFFYixLQUFJLElBQUksR0FBRyxtQkFBTyxDQUFDLENBQWMsQ0FBQyxDQUFDO0FBQ25DLEtBQUksR0FBRyxHQUFHLG1CQUFPLENBQUMsQ0FBYSxDQUFDLENBQUM7QUFDakMsS0FBSSxTQUFTLEdBQUcsbUJBQU8sQ0FBQyxDQUFtQixDQUFDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7S0F5QnhCLElBQUk7QUFFWixZQUZRLElBQUksR0FFVDsyQkFGSyxJQUFJOztBQUlyQixTQUFJLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDOztBQUV4QixTQUFJLFFBQVEsR0FBRztBQUNiLGFBQVEsQ0FBQyxFQUFFLEVBQUMsRUFBRSxDQUFDO01BQ2hCLENBQUM7O0FBRUYsZ0NBVmlCLElBQUksNkNBVWYsU0FBUyxFQUFDLE9BQU8sRUFBQyxRQUFRLEVBQUU7O0FBRWxDLFNBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDOztBQUVwQixTQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Ozs7QUFJYixTQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDOzs7QUFHMUMsU0FBSSxNQUFNLENBQUMsc0JBQXNCLEVBQUU7QUFDbEMsV0FBSSxDQUFDLG1CQUFtQixHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxDQUFDO01BQ2pHLE1BQU07QUFDSixXQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztBQUNyQixXQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7TUFDdkI7Ozs7Ozs7SUFXRjtBQVhFO2FBMUJnQixJQUFJOztnQkFBSixJQUFJO0FBd0N2QixtQkFBYztjQUFBLDBCQUFHOztBQUVmLGFBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNoQyxhQUFJLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDcEMsYUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3BDLGFBQUksQ0FBQyxPQUFPLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQzs7QUFFcEMsYUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQy9CLGFBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMvQixhQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7O0FBRS9CLGFBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNoQyxhQUFJLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDaEMsYUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDOztBQUVoQyxhQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUMsS0FBSyxDQUFDLENBQUM7QUFDeEMsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3hDLGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBQyxLQUFLLENBQUMsQ0FBQztBQUN4QyxhQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUMsS0FBSyxDQUFDLENBQUM7QUFDekMsYUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3pDLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBQyxLQUFLLENBQUMsQ0FBQzs7QUFFekMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFDLElBQUksQ0FBQyxLQUFLLEdBQUMsQ0FBQyxHQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2hELGFBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksRUFBQyxJQUFJLENBQUMsTUFBTSxHQUFDLENBQUMsR0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoRCxhQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUMsSUFBSSxDQUFDLE1BQU0sR0FBQyxFQUFFLENBQUMsQ0FBQztBQUM5QyxhQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUMsS0FBSyxDQUFDLENBQUM7O0FBRTNDLGFBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksRUFBQyxJQUFJLENBQUMsS0FBSyxHQUFDLENBQUMsR0FBQyxFQUFFLENBQUMsQ0FBQztBQUNoRCxhQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLE1BQU0sR0FBQyxDQUFDLEdBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEQsYUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxNQUFNLEdBQUMsRUFBRSxDQUFDLENBQUM7QUFDOUMsYUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFDLEtBQUssQ0FBQyxDQUFDOztBQUUzQyxhQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLEtBQUssR0FBQyxDQUFDLEdBQUMsRUFBRSxDQUFDLENBQUM7QUFDaEQsYUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFDLElBQUksQ0FBQyxNQUFNLEdBQUMsQ0FBQyxHQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hELGFBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxJQUFJLENBQUMsTUFBTSxHQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzlDLGFBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBQyxLQUFLLENBQUMsQ0FBQzs7QUFHM0MsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2xFLGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNsRSxhQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7O0FBRWxFLGFBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN2QyxhQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDdkMsYUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDOztBQUV2QyxhQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDbkUsYUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ25FLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzs7QUFFbkUsYUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3hDLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN4QyxhQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7O0FBR3hDLGFBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBQyxJQUFJLENB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Q0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ25ELGVBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ25ELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELGVBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1VBQ25ELE1BQU07QUFDTCxlQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDdEQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDNUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDNUQsZUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDNUQsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekQsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekQsZUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsZUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7VUFDekQ7UUFFRjs7QUFFRCxXQUFNO2NBQUEsZ0JBQUMsQ0FBQyxFQUFFO0FBQ1IsYUFBSSxJQUFJLENBQUMsT0FBTyxFQUFDOztBQUVmLGVBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDZixlQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ2hCLGVBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUM7OztBQUdoQixZQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFFLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixZQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFFLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixZQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLEdBQUcsRUFBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRzVCLGVBQUksWUFBWSxHQUFHO0FBQ2pCLGtCQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHO0FBQ2xCLGdCQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQyxDQUFDLEVBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxDQUFDLEVBQUcsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLENBQUU7WUFDekYsQ0FBQztBQUNGLGVBQUksYUFBYSxHQUFHO0FBQ2xCLGtCQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHO0FBQ2xCLGdCQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQyxHQUFHLEVBQUMsQ0FBQyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLEdBQUMsR0FBRyxDQUFDLEVBQUcsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBQyxHQUFHLENBQUU7WUFDekYsQ0FBQzs7QUFFRixlQUFJLFVBQVUsR0FBRyxHQUFHLENBQUMsR0FB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QUFJLENBQUMsSUFBSSxDQUFDLEtBQUcsQ0FBQyxHQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDOztBQUVuQyxTQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBRSxDQUFDLEVBQUU7O0FBRXhDLFdBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBQyxDQUFDLENBQUM7QUFDcEQsV0FBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFDLENBQUMsQ0FBQzs7QUFFcEQsV0FBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDOUMsV0FBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7O0FBRTlDLFdBQUksSUFBSSxHQUFHLFNBQVMsSUFBSSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0MsV0FBSSxLQUFLLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7QUFFcEUsV0FBSSxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRTtBQUFFLGFBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQUU7QUFDckMsV0FBSSxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssRUFBRTtBQUFFLGFBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQUU7TUFFeEM7O0FBRUQsU0FBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDdEMsU0FBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFR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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQ0FBeUM7O0FBRXpDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsSUFBRztBQUNIO0FBQ0E7O0FBRUEsSUFBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBa0MsaUNBQWlDO0FBQ25FO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFxQyxlQUFlO0FBQ3BEO0FBQ0EsTUFBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEk7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7Ozs7QUN6T0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQSxFQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdCQUF1QixzQkFBc0I7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBcUI7QUFDckI7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNDQUFxQzs7QUFFckM7QUFDQTtBQUNBOztBQUVBLDRCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQSw2QkFBNEIsVUFBVTs7Ozs7OztBQ3ZMdEMsYUFBWSxDQUFDOzs7Ozs7S0FFSixLQUFLLHVCQUFRLENBQVMsRUFBdEIsS0FBSzs7S0FFTyxRQUFRO0FBRWhCLFlBRlEsUUFBUSxDQUVmLElBQUksRUFBQyxJQUFJLEVBQUMsRUFBRSxFQUFFOzJCQUZQLFFBQVE7O0FBSXpCLFNBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ2pCLFNBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2IsU0FBSSxDQUFDLEtBQUssR0FBRyxLQUFLLEVBQUUsQ0FBQzs7QUFFckIsU0FBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25CLFNBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDOztBQUVmLFNBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxZQUFXLEVBQUcsQ0FBQzs7QUFFMUMsU0FBSSxJQUFJLENBQUMsRUFBRSxFQUFFO0FBQ1gsV0FBSSxDQUFDLEtBQUssRUFBRSxDQUFDO01BQ2Q7SUFFRjs7Z0JBakJrQixRQUFRO0FBbUIzQixXQUFNO2NBQUEsZ0JBQUMsQ0FBQyxFQUFFOztBQUVOLGFBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRWhCLGFBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNkOztBQUVELFNBQUk7Y0FBQSxnQkFBRztBQUNMLGFBQUksQ0FBQyxFQUFFLEdBQUcsS0FBSyxDQUFDO0FBQ2hCLGFBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkI7O0FBRUQsVUFBSztjQUFBLGlCQUFHO0FBQ04sYUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDZixhQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7UUFDMUo7O0FBRUQsT0FBRTtjQUFBLFlBQUMsT0FBTyxFQUFFO0FBQ1YsYUFBSSxJQUFJLENBQUMsRUFBRSxFQUFFO0FBQ1gsZUFBSSxLQUFLLEdBQUcsT0FBTyxHQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDOUIsZUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7QUFDcEIsZUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1VBQ2hGLE1BQU07QUFDTCxlQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQztVQUNyQjtRQUNGOzs7O1VBNUNrQixRQUFROzs7a0JBQVIsUUFBUSxDIiwiZmlsZSI6Ii4vZGlzdC9OZXh1c1VJLmpzIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wiTmV4dXNcIl0gPSBmYWN0b3J5KCk7XG5cdGVsc2Vcblx0XHRyb290W1wiTmV4dXNcIl0gPSBmYWN0b3J5KCk7XG59KSh0aGlzLCBmdW5jdGlvbigpIHtcbnJldHVybiBcblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pXG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG5cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGV4cG9ydHM6IHt9LFxuIFx0XHRcdGlkOiBtb2R1bGVJZCxcbiBcdFx0XHRsb2FkZWQ6IGZhbHNlXG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oMCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay9ib290c3RyYXAgYjI2OWFjZWY4Y2FkYTcwODQ1MDIiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBOZXh1c1VJIGZyb20gJy4vbGliL21haW4nO1xuXG5leHBvcnQgZGVmYXVsdCBOZXh1c1VJO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vaW5kZXguanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBJbnRlcmZhY2VzIGZyb20gJy4vaW50ZXJmYWNlcy8nO1xuaW1wb3J0IG1hdGggZnJvbSAnLi91dGlsL21hdGgnO1xuaW1wb3J0IFJhY2sgZnJvbSAnLi9jb3JlL3JhY2snO1xuaW1wb3J0IFR1bmUgZnJvbSAnLi90dW5pbmcvdHVuaW5nJztcbmltcG9ydCAqIGFzIFRyYW5zZm9ybSBmcm9tICcuL3V0aWwvdHJhbnNmb3JtJztcblxubGV0IENvdW50ZXIgPSByZXF1aXJlKCcuL21vZGVscy9jb3VudGVyJyk7XG5sZXQgUmFkaW8gPSByZXF1aXJlKCcuL21vZGVscy9yYWRpbycpO1xubGV0IERydW5rID0gcmVxdWlyZSgnLi9tb2RlbHMvZHJ1bmsnKTtcbmxldCBTZXF1ZW5jZSA9IHJlcXVpcmUoJy4vbW9kZWxzL3NlcXVlbmNlJyk7XG5sZXQgTWF0cml4ID0gcmVxdWlyZSgnLi9tb2RlbHMvbWF0cml4Jyk7XG5cbmltcG9ydCBXQUFDbG9jayBmcm9tICd3YWFjbG9jayc7XG5pbXBvcnQgSW50ZXJ2YWwgZnJvbSAnLi90aW1lL2ludGVydmFsJztcblxuXG4vKipcbk5leHVzVUkgPT4gY3JlYXRlZCBhcyBOZXh1c1xuKi9cblxuY2xhc3MgTmV4dXNVSSB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0KSB7XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIEludGVyZmFjZXMpIHtcbiAgICAgICAgICAgIHRoaXNba2V5XSA9IEludGVyZmFjZXNba2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGtleSBpbiBtYXRoKSB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSBtYXRoW2tleV07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgQ29yZSA9IHtcbiAgICAgICAgICAnUmFjayc6IFJhY2tcbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgTW9kZWxzID0ge1xuICAgICAgICAgICdDb3VudGVyJzogQ291bnRlcixcbiAgICAgICAgICAnUmFkaW8nOiBSYWRpbyxcbiAgICAgICAgICAnRHJ1bmsnOiBEcnVuayxcbiAgICAgICAgICAnU2VxdWVuY2UnOiBTZXF1ZW5jZSxcbiAgICAgICAgICAnTWF0cml4JzogTWF0cml4XG4gICAgICAgIH07XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIE1vZGVscykge1xuICAgICAgICAgIHRoaXNba2V5XSA9IE1vZGVsc1trZXldO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIENvcmUpIHtcbiAgICAgICAgICB0aGlzW2tleV0gPSBDb3JlW2tleV07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgRGVmYXVsdENvbnRleHQgPSB3aW5kb3cuQXVkaW9Db250ZXh0IHx8IHdpbmRvdy53ZWJraXRBdWRpb0NvbnRleHQ7XG4gICAgICAgIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0IHx8IG5ldyBEZWZhdWx0Q29udGV4dCgpO1xuXG4gICAgICAgIHRoaXMudHVuZSA9IG5ldyBUdW5lKCk7XG4gICAgICAgIHRoaXMubm90ZSA9IHRoaXMudHVuZS5ub3RlLmJpbmQodGhpcy50dW5lKTtcblxuICAgICAgICB0aGlzLmNsb2NrID0gbmV3IFdBQUNsb2NrKHRoaXMuX2NvbnRleHQpO1xuICAgICAgICB0aGlzLmNsb2NrLnN0YXJ0KCk7XG4gICAgICAgIHRoaXMuSW50ZXJ2YWwgPSBJbnRlcnZhbDtcblxuICAgICAgICB0aGlzLmNvbG9ycyA9IHtcbiAgICAgICAgICBhY2NlbnQ6ICcjMmJiJyxcbiAgICAgICAgICBmaWxsOiAnI2VlZScsXG4gICAgICAgICAgbGlnaHQ6ICcjZmZmJyxcbiAgICAgICAgICBkYXJrOiAnIzMzMycsXG4gICAgICAgICAgbWVkaXVtTGlnaHQ6ICcjY2NjJyxcbiAgICAgICAgICBtZWRpdW1EYXJrOiAnIzY2NidcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnRyYW5zZm9ybSA9IFRyYW5zZm9ybTtcbiAgICAgICAgdGhpcy5hZGQgPSBUcmFuc2Zvcm0uYWRkO1xuXG5cbiAgICAgICAgdGhpcy5BZGQgPSB7fTtcbiAgICAgICAgZm9yIChsZXQga2V5IGluIEludGVyZmFjZXMpIHtcbiAgICAgICAgICB0aGlzLkFkZFtrZXldID0gVHJhbnNmb3JtLmFkZC5iaW5kKHRoaXMsa2V5KTtcbiAgICAgICAgfVxuXG5cblxuXG4gICAgICAgIC8qIGNyZWF0ZSBkZWZhdWx0IGNvbXBvbmVudCBzaXplICovXG4gICAgICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICAgICAgdmFyIGV4aXN0aW5nU3R5bGVzaGVldHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcInN0eWxlXCIpO1xuICAgICAgICB2YXIgZGVmYXVsdFNpemVEZWNsYXJhdGlvbiA9ICdbbmV4dXMtdWlde2hlaWdodDo1MDAwcHg7d2lkdGg6NTAwMHB4fSc7XG4gICAgICAgIHZhciBkZWZhdWx0U3R5bGVOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICAgICAgZGVmYXVsdFN0eWxlTm9kZS50eXBlID0gJ3RleHQvY3NzJztcbiAgICAgICAgZGVmYXVsdFN0eWxlTm9kZS5pbm5lckhUTUwgPSBkZWZhdWx0U2l6ZURlY2xhcmF0aW9uO1xuICAgICAgICBpZiAoZXhpc3RpbmdTdHlsZXNoZWV0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdmFyIHBhcmVudCA9IGV4aXN0aW5nU3R5bGVzaGVldHNbMF0ucGFyZW50Tm9kZVxuICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoIGRlZmF1bHRTdHlsZU5vZGUsIGV4aXN0aW5nU3R5bGVzaGVldHNbMF0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoJzxzdHlsZT4nK2RlZmF1bHRTaXplRGVjbGFyYXRpb24rJzxcXC9zdHlsZT4nKTtcbiAgICAgICAgfVxuICAgICAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG4gICAgfVxuXG4gICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY29udGV4dDtcbiAgICB9XG5cbiAgICBzZXQgY29udGV4dChjdHgpIHtcbiAgICAgIHRoaXMuY2xvY2suc3RvcCgpO1xuICAgICAgdGhpcy5fY29udGV4dCA9IGN0eDtcbiAgICAgIHRoaXMuY2xvY2sgPSBuZXcgV0FBQ2xvY2sodGhpcy5jb250ZXh0KTtcbiAgICAgIHRoaXMuY2xvY2suc3RhcnQoKTtcbiAgICB9XG5cblxuXG59XG5cbmxldCBOZXh1cyA9IG5ldyBOZXh1c1VJKCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBjb2xvcnMoKSB7XG4gICAgcmV0dXJuIE5leHVzLmNvbG9ycztcbn1cbmV4cG9ydCBmdW5jdGlvbiBjb250ZXh0KCkge1xuICAgIHJldHVybiBOZXh1cy5jb250ZXh0O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNsb2NrKCkge1xuICAgIHJldHVybiBOZXh1cy5jbG9jaztcbn1cblxuZXhwb3J0IGRlZmF1bHQgTmV4dXM7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbWFpbi5qcyIsImV4cG9ydCBkZWZhdWx0IHtcbiAgUG9zaXRpb246IHJlcXVpcmUoJy4vcG9zaXRpb24nKSxcbiAgU2xpZGVyOiByZXF1aXJlKCcuL3NsaWRlcicpLFxuICBUb2dnbGU6IHJlcXVpcmUoJy4vdG9nZ2xlJyksXG4vKiAgUmFuZ2U6IHJlcXVpcmUoJy4vcmFuZ2VzbGlkZXInKSxcbiAgV2F2ZWZvcm06IHJlcXVpcmUoJy4vd2F2ZWZvcm0nKSwgKi9cbiAgQnV0dG9uOiByZXF1aXJlKCcuL2J1dHRvbicpLFxuICBUZXh0QnV0dG9uOiByZXF1aXJlKCcuL3RleHRidXR0b24nKSxcbiAgUmFkaW9CdXR0b246IHJlcXVpcmUoJy4vcmFkaW9idXR0b24nKSxcbiAgTnVtYmVyOiByZXF1aXJlKCcuL251bWJlcicpLFxuICBTZWxlY3Q6IHJlcXVpcmUoJy4vc2VsZWN0JyksXG4gIERpYWw6IHJlcXVpcmUoJy4vZGlhbCcpLFxuICBQaWFubzogcmVxdWlyZSgnLi9waWFubycpLFxuICBTZXF1ZW5jZXI6IHJlcXVpcmUoJy4vc2VxdWVuY2VyJyksXG4gIFBhbjJEOiByZXF1aXJlKCcuL3BhbjJkJyksXG4gIFRpbHQ6IHJlcXVpcmUoJy4vdGlsdCcpLFxuICBNdWx0aXNsaWRlcjogcmVxdWlyZSgnLi9tdWx0aXNsaWRlcicpLFxuICBQYW46IHJlcXVpcmUoJy4vcGFuJyksXG4gIEVudmVsb3BlOiByZXF1aXJlKCcuL2VudmVsb3BlJyksXG4gIFNwZWN0cm9ncmFtOiByZXF1aXJlKCcuL3NwZWN0cm9ncmFtJyksXG4gIE1ldGVyOiByZXF1aXJlKCcuL21ldGVyJyksXG4gIE9zY2lsbG9zY29wZTogcmVxdWlyZSgnLi9vc2NpbGxvc2NvcGUnKVxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL2luZGV4LmpzIiwiXG4ndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgU3RlcCA9IHJlcXVpcmUoJy4uL21vZGVscy9zdGVwJyk7XG5pbXBvcnQgKiBhcyBJbnRlcmFjdGlvbiBmcm9tICcuLi91dGlsL2ludGVyYWN0aW9uJztcblxuLyoqXG4qIFBvc2l0aW9uXG4qXG4qIEBkZXNjcmlwdGlvbiBUd28tZGltZW5zaW9uYWwgdG91Y2ggc2xpZGVyLlxuKlxuKiBAZGVtbyA8c3BhbiBuZXh1cy11aT1cInBvc2l0aW9uXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcG9zaXRpb24gPSBuZXcgTmV4dXMuUG9zaXRpb24oJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcG9zaXRpb24gPSBuZXcgTmV4dXMuUG9zaXRpb24oJyN0YXJnZXQnLHtcbiogICAnc2l6ZSc6IFsyMDAsMjAwXSxcbiogICAnbW9kZSc6ICdhYnNvbHV0ZScsICAvLyBcImFic29sdXRlXCIgb3IgXCJyZWxhdGl2ZVwiXG4qICAgJ3gnOiAwLjUsICAvLyBpbml0aWFsIHggdmFsdWVcbiogICAnbWluWCc6IDAsXG4qICAgJ21heFgnOiAxLFxuKiAgICdzdGVwWCc6IDAsXG4qICAgJ3knOiAwLjUsICAvLyBpbml0aWFsIHkgdmFsdWVcbiogICAnbWluWSc6IDAsXG4qICAgJ21heFknOiAxLFxuKiAgICdzdGVwWSc6IDBcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgaXMgYW4gb2JqZWN0IHdpdGggeCBhbmQgeSBwcm9wZXJ0aWVzIGNvbnRhaW5pbmcgdGhlIHggYW5kIHkgdmFsdWVzIG9mIHRoZSBpbnRlcmZhY2UuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIHBvc2l0aW9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBvc2l0aW9uIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMjAwLDIwMF0sXG4gICAgICAnbW9kZSc6ICdhYnNvbHV0ZScsXG4gICAgICAnbWluWCc6IDAsXG4gICAgICAnbWF4WCc6IDEsXG4gICAgICAnc3RlcFgnOiAwLFxuICAgICAgJ3gnOiAwLjUsXG4gICAgICAnbWluWSc6IDAsXG4gICAgICAnbWF4WSc6IDEsXG4gICAgICAnc3RlcFknOiAwLFxuICAgICAgJ3knOiAwLjVcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG5cbiAgICB0aGlzLl94ID0gbmV3IFN0ZXAoIHRoaXMuc2V0dGluZ3MubWluWCwgdGhpcy5zZXR0aW5ncy5tYXhYLCB0aGlzLnNldHRpbmdzLnN0ZXBYLCB0aGlzLnNldHRpbmdzLnggKTtcbiAgICB0aGlzLl95ID0gbmV3IFN0ZXAoIHRoaXMuc2V0dGluZ3MubWluWSwgdGhpcy5zZXR0aW5ncy5tYXhZLCB0aGlzLnNldHRpbmdzLnN0ZXBZLCB0aGlzLnNldHRpbmdzLnkgKTtcblxuICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICB4OiBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMuc2V0dGluZ3MubW9kZSwnaG9yaXpvbnRhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKSxcbiAgICAgIHk6IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLCd2ZXJ0aWNhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKVxuICAgIH07XG4gICAgdGhpcy5wb3NpdGlvbi54LnZhbHVlID0gdGhpcy5feC5ub3JtYWxpemVkO1xuICAgIHRoaXMucG9zaXRpb24ueS52YWx1ZSA9IHRoaXMuX3kubm9ybWFsaXplZDtcblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG4gICAgXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgICB0aGlzLnBvc2l0aW9uLngucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG4gICAgICB0aGlzLnBvc2l0aW9uLnkucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG5cbiAgICAgIHRoaXMuX21pbkRpbWVuc2lvbiA9IE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpO1xuXG4gICAgICB0aGlzLmtub2JSYWRpdXMgPSB7XG4gICAgICAgIG9mZjogfn4odGhpcy5fbWluRGltZW5zaW9uLzEwMCkgKiA1ICsgNSxcbiAgICAgIH07XG4gICAgICB0aGlzLmtub2JSYWRpdXMub24gPSB0aGlzLmtub2JSYWRpdXMub2ZmICogMjtcblxuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMud2lkdGgvMik7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQvMik7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JSYWRpdXMub2ZmKTtcbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAodGhpcy5jbGlja2VkKSB7XG4gICAgLy8gIHRoaXMua25vYlJhZGl1cyA9IDMwO1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgncicsdGhpcy5rbm9iUmFkaXVzLm9uKTtcbiAgICB9IGVsc2Uge1xuICAgIC8vICB0aGlzLmtub2JSYWRpdXMgPSAxNTtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYlJhZGl1cy5vZmYpO1xuICAgIH1cblxuICAgIHRoaXMua25vYkNvb3JkaW5hdGVzID0ge1xuICAgICAgeDogdGhpcy5feC5ub3JtYWxpemVkICogdGhpcy53aWR0aCxcbiAgICAgIHk6IHRoaXMuaGVpZ2h0IC0gdGhpcy5feS5ub3JtYWxpemVkICogdGhpcy5oZWlnaHRcbiAgICB9O1xuXG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkNvb3JkaW5hdGVzLngpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmtub2JDb29yZGluYXRlcy55KTtcbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgdGhpcy5wb3NpdGlvbi54LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5wb3NpdGlvbi55LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMucG9zaXRpb24ueC51cGRhdGUodGhpcy5tb3VzZSk7XG4gICAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKHRoaXMubW91c2UpO1xuICAgICAgdGhpcy5feC51cGRhdGVOb3JtYWwoIHRoaXMucG9zaXRpb24ueC52YWx1ZSApO1xuICAgICAgdGhpcy5feS51cGRhdGVOb3JtYWwoIHRoaXMucG9zaXRpb24ueS52YWx1ZSApO1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgeDogdGhpcy5feC52YWx1ZSxcbiAgICAgICAgeTogdGhpcy5feS52YWx1ZVxuICAgICAgfSk7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFRoZSBpbnRlcmZhY2UncyB4IHZhbHVlLiBXaGVuIHNldCwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IGFkanVzdCB0byBmaXQgbWluL21heC9zdGVwIHNldHRpbmdzIG9mIHRoZSBpbnRlcmZhY2UuXG4gICogQHR5cGUge29iamVjdH1cbiAgKiBAZXhhbXBsZSBwb3NpdGlvbi54ID0gMC41O1xuICAqL1xuXG4gIGdldCB4KCkge1xuICAgIHJldHVybiB0aGlzLl94LnZhbHVlO1xuICB9XG5cbiAgc2V0IHgodmFsdWUpIHtcbiAgICB0aGlzLl94LnVwZGF0ZSh2YWx1ZSk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgIHg6IHRoaXMuX3gudmFsdWUsXG4gICAgICB5OiB0aGlzLl95LnZhbHVlXG4gICAgfSk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFRoZSBpbnRlcmZhY2UncyB5IHZhbHVlcy4gV2hlbiBzZXQsIGl0IHdpbGwgYXV0b21hdGljYWxseSBhZGp1c3QgdG8gZml0IG1pbi9tYXgvc3RlcCBzZXR0aW5ncyBvZiB0aGUgaW50ZXJmYWNlLlxuICAqIEB0eXBlIHtvYmplY3R9XG4gICogQGV4YW1wbGUgcG9zaXRpb24ueCA9IDAuNTtcbiAgKi9cblxuICBnZXQgeSgpIHtcbiAgICByZXR1cm4gdGhpcy5feS52YWx1ZTtcbiAgfVxuXG4gIHNldCB5KHZhbHVlKSB7XG4gICAgdGhpcy5feS51cGRhdGUodmFsdWUpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICB4OiB0aGlzLl94LnZhbHVlLFxuICAgICAgeTogdGhpcy5feS52YWx1ZVxuICAgIH0pO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuXG5cbiAgZ2V0IG5vcm1hbGl6ZWQoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHRoaXMuX3gubm9ybWFsaXplZCxcbiAgICAgIHk6IHRoaXMuX3kubm9ybWFsaXplZFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgKiBUaGUgbG93ZXIgbGltaXQgb2YgdmFsdWUgb24gdGhlIHggYXhpc1xuICAqIEB0eXBlIHtvYmplY3R9XG4gICovXG4gIGdldCBtaW5YKCkge1xuICAgIHJldHVybiB0aGlzLl94Lm1pbjtcbiAgfVxuXG4gIHNldCBtaW5YKHYpIHtcbiAgICB0aGlzLl94Lm1pbiA9IHY7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFRoZSBsb3dlciBsaW1pdCBvZiB2YWx1ZSBvbiB0aGUgeSBheGlzXG4gICogQHR5cGUge29iamVjdH1cbiAgKi9cbiAgZ2V0IG1pblkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3kubWluO1xuICB9XG5cbiAgc2V0IG1pblkodikge1xuICAgIHRoaXMuX3kubWluID0gdjtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgKiBUaGUgdXBwZXIgbGltaXQgb2YgdmFsdWUgb24gdGhlIHggYXhpc1xuICAqIEB0eXBlIHtvYmplY3R9XG4gICovXG4gIGdldCBtYXhYKCkge1xuICAgIHJldHVybiB0aGlzLl94Lm1heDtcbiAgfVxuXG4gIHNldCBtYXhYKHYpIHtcbiAgICB0aGlzLl94Lm1heCA9IHY7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gICogVGhlIHVwcGVyIGxpbWl0IG9mIHZhbHVlIG9uIHRoZSB5IGF4aXNcbiAgKiBAdHlwZSB7b2JqZWN0fVxuICAqL1xuICBnZXQgbWF4WSgpIHtcbiAgICByZXR1cm4gdGhpcy5feS5tYXg7XG4gIH1cblxuICBzZXQgbWF4WSh2KSB7XG4gICAgdGhpcy5feS5tYXggPSB2O1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuXG4gIC8qKlxuICAqIFRoZSBpbmNyZW1lbnRhbCBzdGVwIG9mIHZhbHVlcyBvbiB0aGUgeCBheGlzXG4gICogQHR5cGUge29iamVjdH1cbiAgKi9cbiAgZ2V0IHN0ZXBYKCkge1xuICAgIHJldHVybiB0aGlzLl94LnN0ZXA7XG4gIH1cblxuICBzZXQgc3RlcFgodikge1xuICAgIHRoaXMuX3guc3RlcCA9IHY7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gICogVGhlIGluY3JlbWVudGFsIHN0ZXAgb2YgdmFsdWVzIG9uIHRoZSB5IGF4aXNcbiAgKiBAdHlwZSB7b2JqZWN0fVxuICAqL1xuICBnZXQgc3RlcFkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3kuc3RlcDtcbiAgfVxuXG4gIHNldCBzdGVwWSh2KSB7XG4gICAgdGhpcy5feS5zdGVwID0gdjtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgQWJzb2x1dGUgbW9kZSAocG9zaXRpb24ncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJhYnNvbHV0ZVwiLlxuICBAdHlwZSB7c3RyaW5nfVxuICBAZXhhbXBsZSBwb3NpdGlvbi5tb2RlID0gXCJyZWxhdGl2ZVwiO1xuICAqL1xuICBnZXQgbW9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi54Lm1vZGU7XG4gIH1cbiAgc2V0IG1vZGUodikge1xuICAgIHRoaXMucG9zaXRpb24ueC5tb2RlID0gdjtcbiAgICB0aGlzLnBvc2l0aW9uLnkubW9kZSA9IHY7XG4gIH1cblxuXG5cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvcG9zaXRpb24uanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5cbmV4cG9ydCBkZWZhdWx0IHtcblxuICBjcmVhdGU6ICh0eXBlKSA9PiB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCB0eXBlKTtcbiAgfSxcblxuICBhcmM6ICh4LCB5LCByYWRpdXMsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlKSA9PiB7XG5cbiAgICB2YXIgc3RhcnQgPSBtYXRoLnRvQ2FydGVzaWFuKHJhZGl1cywgZW5kQW5nbGUpO1xuICAgIHZhciBlbmQgPSBtYXRoLnRvQ2FydGVzaWFuKHJhZGl1cywgc3RhcnRBbmdsZSk7XG5cbiAgICB2YXIgbGFyZ2VBcmNGbGFnID0gZW5kQW5nbGUgLSBzdGFydEFuZ2xlIDw9IDE4MCA/ICcwJyA6ICcxJztcblxuICAgIHZhciBkID0gW1xuICAgICAgICAnTScsIHN0YXJ0LngreCwgc3RhcnQueSt5LFxuICAgICAgICAnQScsIHJhZGl1cywgcmFkaXVzLCAwLCBsYXJnZUFyY0ZsYWcsIDAsIGVuZC54K3gsIGVuZC55K3lcbiAgICBdLmpvaW4oJyAnKTtcblxuICAgIHJldHVybiBkO1xuICB9LFxuXG4gIHJhZGlhbEdyYWRpZW50OiAoZGVmcyxudW1iZXJPZlN0b3BzKSA9PiB7XG5cbiAgICBsZXQgaWQgPSAnZ3JhZGllbnQnICsgbWF0aC5yaSgxMDAwMDAwMDAwMDApO1xuICAgIGxldCBzdG9wcyA9IFtdO1xuXG4gICAgbGV0IGdyYWRpZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsICdyYWRpYWxHcmFkaWVudCcpO1xuICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZSgnaWQnLCBpZCk7XG4gICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlKCdjeCcsICc1MCUnKTtcbiAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGUoJ2N5JywgJzUwJScpO1xuICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZSgncicsICc1MCUnKTtcblxuICAgIGRlZnMuYXBwZW5kQ2hpbGQoZ3JhZGllbnQpO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8bnVtYmVyT2ZTdG9wcztpKyspIHtcbiAgICAgIGxldCBzdG9wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsICdzdG9wJyk7XG4gICAgICBzdG9wLnNldEF0dHJpYnV0ZSgnaWQnLCAnc3RvcCcraSk7XG4gICAgICAvL3N0b3Auc2V0QXR0cmlidXRlKCdvZmZzZXQnLCAnNzAlJyk7XG4gICAgICAvL3N0b3Auc2V0QXR0cmlidXRlKCdzdG9wLWNvbG9yJywgJ1doaXRlJyk7XG4gICAgICBncmFkaWVudC5hcHBlbmRDaGlsZChzdG9wKTtcbiAgICAgIHN0b3BzLnB1c2goc3RvcCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBpZCxcbiAgICAgIHN0b3BzOiBzdG9wcyxcbiAgICAgIGVsZW1lbnQ6IGdyYWRpZW50XG4gICAgfTtcblxuICB9XG5cbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvdXRpbC9zdmcuanMiLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogTGltaXQgYSBudW1iZXIgdG8gd2l0aGluIGEgbWluaW11bSBhbmQgbWF4aW11bVxuICogQHBhcmFtICB7bnVtYmVyfSB2YWx1ZSBJbnB1dCB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBtaW4gICBMb3dlciBsaW1pdFxuICogQHBhcmFtICB7bnVtYmVyfSBtYXggICBVcHBlciBsaW1pdFxuICogQHJldHVybiB7bnVtYmVyfSAgICAgICBUaGUgaW5wdXQgdmFsdWUgY29uc3RyYWluZWQgd2l0aGluIHRoZSBsb3dlciBhbmQgdXBwZXIgbGltaXRzXG4gKiBAZXhhbXBsZVxuICogTmV4dXMuY2xpcCgxMSwwLDEwKSAgIC8vIHJldHVybnMgMTBcbiAqIE5leHVzLmNsaXAoLTEsMCwxMCkgICAvLyByZXR1cm5zIDBcbiAqIE5leHVzLmNsaXAoNSwwLDEwKSAgICAvLyByZXR1cm5zIDVcbiAqL1xuXG5leHBvcnRzLmNsaXAgPSAodmFsdWUsbWluLG1heCkgPT4ge1xuICByZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgodmFsdWUsbWluKSxtYXgpO1xufTtcblxuZXhwb3J0cy5ub3JtYWxpemUgPSAodmFsdWUsbWluLG1heCkgPT4ge1xuICByZXR1cm4gKCAodmFsdWUtbWluKSAvIChtYXgtbWluKSApO1xufTtcblxuLyoqXG4gKiBTY2FsZSBhIHZhbHVlIGZyb20gb25lIHJhbmdlIHRvIGFub3RoZXIgcmFuZ2UuXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGluTnVtICBJbnB1dCB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBpbk1pbiAgSW5wdXQgcmFuZ2UgbWluaW11bVxuICogQHBhcmFtICB7bnVtYmVyfSBpbk1heCAgSW5wdXQgcmFuZ2UgbWF4aW11bVxuICogQHBhcmFtICB7bnVtYmVyfSBvdXRNaW4gT3V0cHV0IHJhbmdlIG1pbmltdW1cbiAqIEBwYXJhbSAge251bWJlcn0gb3V0TWF4IE91dHB1dCByYW5nZSBtYXhpbXVtXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgICBUaGUgaW5wdXQgdmFsdWUgc2NhbGVkIHRvIGl0cyBuZXcgcmFuZ2VcbiAqIEBleGFtcGxlXG4gKiBOZXh1cy5zY2FsZSgwLjUsMCwxLDAsMTApICAgLy8gcmV0dXJucyA1XG4gKiBOZXh1cy5zY2FsZSgwLjksMCwxLDEsMCkgICAgLy8gcmV0dXJucyAwLjFcbiAqL1xuZXhwb3J0cy5zY2FsZSA9IChpbk51bSwgaW5NaW4sIGluTWF4LCBvdXRNaW4sIG91dE1heCkgPT4ge1xuICBpZiAoaW5NaW4gPT09IGluTWF4KSB7XG4gICAgcmV0dXJuIG91dE1pbjtcbiAgfVxuICByZXR1cm4gKCgoaW5OdW0gLSBpbk1pbikgKiAob3V0TWF4IC0gb3V0TWluKSkgLyAoaW5NYXggLSBpbk1pbikpICsgb3V0TWluO1xufTtcblxuZXhwb3J0cy50b1BvbGFyID0gKHgseSkgPT4ge1xuICB2YXIgciA9IE1hdGguc3FydCh4KnggKyB5KnkpO1xuXG4gIHZhciB0aGV0YSA9IE1hdGguYXRhbjIoeSx4KTtcbiAgaWYgKHRoZXRhIDwgMCkge1xuICAgIHRoZXRhID0gdGhldGEgKyAoMiAqIE1hdGguUEkpO1xuICB9XG4gIHJldHVybiB7cmFkaXVzOiByLCBhbmdsZTogdGhldGF9O1xufTtcblxuZXhwb3J0cy50b0NhcnRlc2lhbiA9IGZ1bmN0aW9uKHJhZGl1cywgYW5nbGUpe1xuICB2YXIgY29zID0gTWF0aC5jb3MoYW5nbGUpO1xuICB2YXIgc2luID0gTWF0aC5zaW4oYW5nbGUpO1xuICByZXR1cm4ge3g6IHJhZGl1cypjb3MsIHk6IHJhZGl1cypzaW4qLTF9O1xufTtcbi8qXG5leHBvcnRzLnBvbGFyVG9DYXJ0ZXNpYW4oY2VudGVyWCwgY2VudGVyWSwgcmFkaXVzLCBhbmdsZUluRGVncmVlcykge1xuICB2YXIgYW5nbGVJblJhZGlhbnMgPSAoYW5nbGVJbkRlZ3JlZXMtOTApICogTWF0aC5QSSAvIDE4MC4wO1xuXG4gIHJldHVybiB7XG4gICAgeDogY2VudGVyWCArIChyYWRpdXMgKiBNYXRoLmNvcyhhbmdsZUluUmFkaWFucykpLFxuICAgIHk6IGNlbnRlclkgKyAocmFkaXVzICogTWF0aC5zaW4oYW5nbGVJblJhZGlhbnMpKVxuICB9O1xufSAgKi9cblxuXG5cbmV4cG9ydHMucHJ1bmUgPSBmdW5jdGlvbihkYXRhLCBzY2FsZSkge1xuICByZXR1cm4gcGFyc2VGbG9hdChkYXRhLnRvRml4ZWQoc2NhbGUpKTtcbn07XG5cbmV4cG9ydHMuaW52ZXJ0ID0gZnVuY3Rpb24gKGluTnVtKSB7XG4gIHJldHVybiBleHBvcnRzLnNjYWxlKGluTnVtLCAxLCAwLCAwLCAxKTtcbn07XG5cbi8qKlxuICogQ29udmVydCBhIE1JRGkgbm90ZSBudW1iZXIgdG8gYSBmcmVxdWVuY3kgdmFsdWUgaW4gZXF1YWwgdGVtcGVyYW1lbnQuXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG1pZGkgTUlESSBub3RlIHZhbHVlXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgRnJlcXVlbmNlIHZhbHVlXG4gKiBAZXhhbXBsZVxuICogTmV4dXMubXRvZig2MCkgIC8vIHJldHVybnMgdGhlIGZyZXF1ZW5jeSBudW1iZXIgb2YgTWlkZGxlIENcbiAqL1xuZXhwb3J0cy5tdG9mID0gZnVuY3Rpb24obWlkaSkge1xuICByZXR1cm4gTWF0aC5wb3coMiwgKChtaWRpLTY5KS8xMikpICogNDQwO1xufTtcblxuLyoqXG4gKiBJbnRlcnBvbGF0ZSBiZXR3ZWVuIHR3byBudW1iZXJzXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGxvYyBJbnRlcnBvbGF0aW9uIGluZGV4ICgwLTEpXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG1pbiBMb3dlciB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBtYXggVXBwZXIgdmFsdWVcbiAqIEByZXR1cm4ge251bWJlcn0gICAgIEludGVycG9sYXRlZCB2YWx1ZVxuICogQGV4YW1wbGVcbiAqIE5leHVzLmludGVycCgwLjUsMiw0KSAgIC8vIHJldHVybnMgM1xuICogTmV4dXMuaW50ZXJwKDAuMSwwLDEwKSAgICAgLy8gcmV0dXJucyAxXG4gKi9cbmV4cG9ydHMuaW50ZXJwID0gZnVuY3Rpb24obG9jLG1pbixtYXgpIHtcbiAgcmV0dXJuIGxvYyAqIChtYXggLSBtaW4pICsgbWluO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYSByYW5kb20gY2hvaWNlIGZyb20gYSBsaXN0IG9mIGFyZ3VtZW50c1xuICogQHJldHVybiB7dmFyaW91c30gT25lIHJhbmRvbSBhcmd1bWVudFxuICogQGV4YW1wbGVcbiAqIE5leHVzLnBpY2soMSwyLDMsNCkgICAvLyByZXR1cm5zIDEsIDIsIDMsIG9yIDRcbiAqIE5leHVzLnBpY2soZnVuY3Rpb24xLGZ1bmN0aW9uMikgICAvLyByZXR1cm5zIGVpdGhlciBmdW5jdGlvbjEgb3IgZnVuY3Rpb24yXG4gKi9cbmV4cG9ydHMucGljayA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gYXJndW1lbnRzW35+KE1hdGgucmFuZG9tKCkqYXJndW1lbnRzLmxlbmd0aCldO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGFuIG9jdGF2ZSBtdWx0aXBsaWVyIGZvciBmcmVxdWVuY3kgdmFsdWVzXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG51bSBSZWxhdGl2ZSBvY3RhdmUgbnVtYmVyIChlLmcuIC0xIGZvciBvbmUgb2N0YXZlIGRvd24sIDEgZm9yIG9uZSBvY3RhdmUgdXApXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICBPY3RhdmUgbXVsdGlwbGllclxuICogQGV4YW1wbGVcbiAqIE5leHVzLm9jdGF2ZSgtMSkgIC8vIHJldHVybnMgMC41XG4gKiBOZXh1cy5vY3RhdmUoMCkgICAvLyByZXR1cm5zIDFcbiAqIE5leHVzLm9jdGF2ZSgxKSAgIC8vIHJldHVybnMgMlxuICogTmV4dXMub2N0YXZlKDIpICAgLy8gcmV0dXJucyA0XG4gKi9cbmV4cG9ydHMub2N0YXZlID0gZnVuY3Rpb24obnVtKSB7XG4gIHJldHVybiBNYXRoLnBvdygyLG51bSk7XG59O1xuXG4vKipcbiAqIFJhbmRvbSBpbnRlZ2VyIGdlbmVyYXRvci4gSWYgbm8gc2Vjb25kIGFyZ3VtZW50IGlzIGdpdmVuLCB3aWxsIHJldHVybiByYW5kb20gaW50ZWdlciBmcm9tIDAgdG8gYm91bmQxLlxuICogQHBhcmFtICB7bnVtYmVyfSBib3VuZDEgTWluaW11bSByYW5kb20gdmFsdWVcbiAqIEBwYXJhbSAge251bWJlcn0gYm91bmQyIE1heGltdW0gcmFuZG9tIHZhbHVlXG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgICBSYW5kb20gaW50ZWdlciBiZXR3ZWVuIGxvd2VyIGFuZCB1cHBlciBib3VuZGFyeVxuICogQGV4YW1wbGVcbiAqIE5leHVzLnJpKDEwKSAgICAvLyByZXR1cm5zIHJhbmRvbSBpbnQgZnJvbSAwIHRvIDEwXG4gKiBOZXh1cy5yaSgyMCwyMDAwKSAvLyByZXR1cm5zIHJhbmRvbSBpbnQgZnJvbSAyMCB0byAyMDAwXG4gKi9cbmV4cG9ydHMucmkgPSBmdW5jdGlvbihib3VuZDEsYm91bmQyKSB7XG4gIGlmICghYm91bmQyKSB7XG4gICAgYm91bmQyID0gYm91bmQxO1xuICAgIGJvdW5kMSA9IDA7XG4gIH1cbiAgdmFyIGxvdyA9IE1hdGgubWluKGJvdW5kMSxib3VuZDIpO1xuICB2YXIgaGlnaCA9IE1hdGgubWF4KGJvdW5kMSxib3VuZDIpO1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpKihoaWdoLWxvdykrbG93KTtcbn07XG5cbi8qKlxuICogUmFuZG9tIGZsb2F0IG51bWJlciBnZW5lcmF0b3IuIElmIG5vIHNlY29uZCBhcmd1bWVudCBpcyBnaXZlbiwgd2lsbCByZXR1cm4gcmFuZG9tIGZsb2F0IGZyb20gMCB0byBib3VuZDEuXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGJvdW5kMSBNaW5pbXVtIHJhbmRvbSB2YWx1ZVxuICogQHBhcmFtICB7bnVtYmVyfSBib3VuZDIgTWF4aW11bSByYW5kb20gdmFsdWVcbiAqIEByZXR1cm4ge251bWJlcn0gICAgICAgIFJhbmRvbSBmbG9hdCBiZXR3ZWVuIGxvd2VyIGFuZCB1cHBlciBib3VuZGFyeVxuICogQGV4YW1wbGVcbiAqIE5leHVzLnJmKDEpICAgIC8vIHJldHVybnMgcmFuZG9tIGZsb2F0IGZyb20gMCB0byAxXG4gKiBOZXh1cy5yZigxLDIpIC8vIHJldHVybnMgcmFuZG9tIGZsb2F0IGZyb20gMSB0byAyXG4gKi9cbmV4cG9ydHMucmYgPSBmdW5jdGlvbihib3VuZDEsYm91bmQyKSB7XG4gIGlmICghYm91bmQyKSB7XG4gICAgYm91bmQyID0gYm91bmQxO1xuICAgIGJvdW5kMSA9IDA7XG4gIH1cbiAgdmFyIGxvdyA9IE1hdGgubWluKGJvdW5kMSxib3VuZDIpO1xuICB2YXIgaGlnaCA9IE1hdGgubWF4KGJvdW5kMSxib3VuZDIpO1xuICByZXR1cm4gTWF0aC5yYW5kb20oKSooaGlnaC1sb3cpK2xvdztcbn07XG5cblxuZXhwb3J0cy5jeWNsZSA9IGZ1bmN0aW9uKGlucHV0LG1pbixtYXgpIHtcbiAgaW5wdXQrKztcbiAgaWYgKGlucHV0ID49IG1heCkge1xuICAgIGlucHV0ID0gbWluO1xuICB9XG4gIHJldHVybiBpbnB1dDtcbn07XG5cbi8qKlxuICogQXZlcmFnZSBhbiBhcnJheSBvZiBudW1iZXJzXG4gKiBAcGFyYW0gIHtBcnJheX0gZGF0YSBBcnJheSBvZiBudW1iZXJzIHRvIGF2ZXJhZ2VcbiAqIEByZXR1cm4ge251bWJlcn0gICAgICBBdmVyYWdlIG9mIHRoZSBpbnB1dCBkYXRhXG4gKiBAZXhhbXBsZVxuICogTmV4dXMuYXZlcmFnZShbMCwyLDQsNiw4LDEwXSkgICAvLyByZXR1cm5zIDVcbiAqL1xuZXhwb3J0cy5hdmVyYWdlID0gZnVuY3Rpb24oZGF0YSkge1xuICBsZXQgdG90YWwgPSAwO1xuICBmb3IgKHZhciBpPTA7aTxkYXRhLmxlbmd0aDtpKyspIHtcbiAgICB0b3RhbCArPSBkYXRhW2ldO1xuICB9XG4gIHJldHVybiB0b3RhbCAvIGRhdGEubGVuZ3RoO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGRpc3RhbmNlIGZyb20gb25lICh4LHkpIHBvaW50IHRvIGFub3RoZXIgKHgseSkgcG9pbnRcbiAqIEBwYXJhbSAge251bWJlcn0geDEgeCBvZiBmaXJzdCBwb2ludFxuICogQHBhcmFtICB7bnVtYmVyfSB5MSB5IG9mIGZpcnN0IHBvaW50XG4gKiBAcGFyYW0gIHtudW1iZXJ9IHgyIHggb2Ygc2Vjb25kIHBvaW50XG4gKiBAcGFyYW0gIHtudW1iZXJ9IHkyIHkgb2Ygc2Vjb25kIHBvaW55XG4gKiBAcmV0dXJuIHtudW1iZXJ9ICAgIERpc3RhbmNlXG4gKiBAZXhhbXBsZVxuICogTmV4dXMuZGlzdGFuY2UoMCwwLDMsNCkgICAvLyByZXR1cm5zIDVcbiAqL1xuZXhwb3J0cy5kaXN0YW5jZSA9IGZ1bmN0aW9uKHgxLHkxLHgyLHkyKSB7XG4gIGxldCBhID0geDEgLSB4MjtcbiAgbGV0IGIgPSB5MSAtIHkyO1xuICByZXR1cm4gTWF0aC5zcXJ0KCBhKmEgKyBiKmIgKTtcbn07XG5cbmV4cG9ydHMuZ2FpblRvREIgPSBmdW5jdGlvbihnYWluKSB7XG4gIHJldHVybiAyMCAqIE1hdGgubG9nMTAoZ2Fpbik7XG59O1xuXG4vKipcbiAqIEZsaXAgYSBjb2luLCByZXR1cm5pbmcgZWl0aGVyIDAgb3IgMSBhY2NvcmRpbmcgdG8gYSBwcm9iYWJpbGl0eVxuICogQHBhcmFtICB7bnVtYmVyfSBbb2Rkcz0wLjVdIExpa2VsaWhvb2Qgb2YgcmV0dXJuaW5nIDFcbiAqIEByZXR1cm4ge251bWJlcn0gICAgICAgICAgICAxIG9yIDBcbiAqIEBleGFtcGxlXG4gKiBOZXh1cy5jb2luKDAuMSkgICAvLyByZXR1cm5zIDEgKDEwJSBvZiB0aGUgdGltZSkgb3IgMCAoOTAlIG9mIHRoZSB0aW1lKVxuICovXG5leHBvcnRzLmNvaW4gPSBmdW5jdGlvbihvZGRzPTAuNSkge1xuICBpZiAoZXhwb3J0cy5yZigwLDEpIDwgb2Rkcykge1xuICAgIHJldHVybiAxO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAwO1xuICB9XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3V0aWwvbWF0aC5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgZG9tID0gcmVxdWlyZSgnLi4vdXRpbC9kb20nKTtcbmxldCB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbC91dGlsJyk7XG5sZXQgdG91Y2ggPSByZXF1aXJlKCcuLi91dGlsL3RvdWNoJyk7XG5jb25zdCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKTtcblxuaW1wb3J0IHsgY29sb3JzIH0gZnJvbSAnLi4vbWFpbic7XG5cbi8qKlxuSW50ZXJmYWNlXG4qL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSW50ZXJmYWNlIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcblxuICBjb25zdHJ1Y3RvcihhcmdzLG9wdGlvbnMsZGVmYXVsdHMpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMudHlwZSA9IHRoaXMuY29uc3RydWN0b3IubmFtZTtcbiAgICB0aGlzLnNldHRpbmdzID0gdGhpcy5wYXJzZVNldHRpbmdzKGFyZ3Msb3B0aW9ucyxkZWZhdWx0cyk7XG4gICAgdGhpcy5tb3VzZSA9IHt9O1xuICAgIHRoaXMud2FpdCA9IGZhbHNlO1xuICAgIHRoaXMuY29sb3JzID0ge307XG4gICAgbGV0IGRlZmF1bHRDb2xvcnMgPSBjb2xvcnMoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gICAgdGhpcy5jb2xvcnMuYWNjZW50ID0gZGVmYXVsdENvbG9ycy5hY2NlbnQ7XG4gICAgdGhpcy5jb2xvcnMuZmlsbCA9IGRlZmF1bHRDb2xvcnMuZmlsbDtcbiAgICB0aGlzLmNvbG9ycy5saWdodCA9IGRlZmF1bHRDb2xvcnMubGlnaHQ7XG4gICAgdGhpcy5jb2xvcnMuZGFyayA9IGRlZmF1bHRDb2xvcnMuZGFyaztcbiAgICB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCA9IGRlZmF1bHRDb2xvcnMubWVkaXVtTGlnaHQ7XG4gICAgdGhpcy5jb2xvcnMubWVkaXVtRGFyayA9IGRlZmF1bHRDb2xvcnMubWVkaXVtRGFyaztcbiAgfVxuXG4gIHBhcnNlU2V0dGluZ3MoYXJncyxvcHRpb25zLGRlZmF1bHRzKSB7XG5cbiAgICBvcHRpb25zLnVuc2hpZnQoJ3RhcmdldCcpO1xuICAgIGRlZmF1bHRzLmRlZmF1bHRTaXplID0gZGVmYXVsdHMuc2l6ZS5zcGxpY2UoMCwyKTtcbiAgICBkZWZhdWx0cy5zaXplID0gZmFsc2U7XG5cbiAgICBsZXQgc2V0dGluZ3MgPSB7XG4gICAgICAndGFyZ2V0JzogZG9jdW1lbnQuYm9keSxcbiAgICAgICdjb2xvcnMnOiB7fSwgLy8gc2hvdWxkIGluaGVyaXQgZnJvbSBhIGNvbG9ycyBtb2R1bGUsXG4gICAgICAnc25hcFdpdGhQYXJlbnQnOiB0cnVlLFxuICAgICAgJ2V2ZW50JzogZnVuY3Rpb24oKSB7fSxcbiAgICAgICdjb21wb25lbnQnOiBmYWxzZVxuICAgIH07XG5cbiAgICBmb3IgKGxldCBrZXkgaW4gZGVmYXVsdHMpIHtcbiAgICAgIHNldHRpbmdzW2tleV0gPSBkZWZhdWx0c1trZXldO1xuICAgIH1cblxuICAgIGZvciAobGV0IGk9MDsgaTxhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBncmFicyB0aGUgbmV4dCBhcmd1bWVudFxuICAgICAgbGV0IHNldHRpbmcgPSBhcmdzW2ldO1xuICAgICAgLy8gaWYgaXQncyBhbiBvYmplY3QsIGl0IG11c3QgYmUgdGhlIHNldHRpbmdzIG9iamVjdFxuICAgICAgaWYgKCB1dGlsLmlzT2JqZWN0KHNldHRpbmcpICkge1xuICAgICAgICBmb3IgKCBsZXQga2V5IGluIHNldHRpbmcgKSB7XG4gICAgICAgICAgc2V0dGluZ3Nba2V5XSA9IHNldHRpbmdba2V5XTtcbiAgICAgICAgfVxuICAgICAgLy8gaWYgaXQncyBhIGZ1bmN0aW9uLCBpdCBtdXN0IGJlIHRoZSBldmVudCBzZXR0aW5nXG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXR0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHNldHRpbmdzLmV2ZW50ID0gc2V0dGluZztcbiAgICAgIC8vIG90aGVyd2lzZSwgY29uc2lkZXIgaXQgb25lIG9mIHRoZSB3aWRnZXQncyBjdXN0b20gb3B0aW9uc1xuICAgICAgfSBlbHNlIGlmIChvcHRpb25zLmxlbmd0aD49MSkge1xuICAgICAgICAvLyBncmFiIHRoZSBmaXJzdCBvcHRpb24gLS0gaS5lLiAndGFyZ2V0J1xuICAgICAgICBsZXQga2V5ID0gb3B0aW9ucy5zcGxpY2UoMCwxKVswXTtcbiAgICAgICAgc2V0dGluZ3Nba2V5XSA9IHNldHRpbmc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyogIGhhbmRsZSBjb21tb24gc2V0dGluZ3MgICovXG5cbiAgICAvLyB0YXJnZXRcbiAgICB0aGlzLnBhcmVudCA9IGRvbS5wYXJzZUVsZW1lbnQoc2V0dGluZ3MudGFyZ2V0KTtcblxuICAgIC8vIG5leHVzLXVpIGF0dHJpYnV0ZVxuICAgIGlmICh0aGlzLnBhcmVudCAmJiB0aGlzLnBhcmVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmICFzZXR0aW5ncy5jb21wb25lbnQpIHtcbiAgICAgIGlmICghdGhpcy5wYXJlbnQuaGFzQXR0cmlidXRlKCduZXh1cy11aScpKSB7XG4gICAgICAgIHRoaXMucGFyZW50LnNldEF0dHJpYnV0ZSgnbmV4dXMtdWknLCcnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzaXplXG5cbiAgICBpZiAoc2V0dGluZ3Muc2l6ZSAmJiBBcnJheS5pc0FycmF5KHNldHRpbmdzLnNpemUpICYmIHNldHRpbmdzLnNuYXBXaXRoUGFyZW50KSB7XG4gICAgICB0aGlzLndpZHRoID0gc2V0dGluZ3Muc2l6ZVswXTtcbiAgICAgIHRoaXMuaGVpZ2h0ID0gc2V0dGluZ3Muc2l6ZVsxXTtcbiAgICAgIHRoaXMucGFyZW50LnN0eWxlLndpZHRoID0gdGhpcy53aWR0aCArICdweCc7XG4gICAgICB0aGlzLnBhcmVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmhlaWdodCArICdweCc7XG4gICAgfSBlbHNlIGlmIChzZXR0aW5ncy5zbmFwV2l0aFBhcmVudCAmJiAhc2V0dGluZ3MuY29tcG9uZW50KSB7XG5cbiAgICAgIHRoaXMud2lkdGggPSBwYXJzZUZsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMucGFyZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCd3aWR0aCcpLnJlcGxhY2UoJ3B4JywnJykpO1xuICAgICAgdGhpcy5oZWlnaHQgPSBwYXJzZUZsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMucGFyZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCdoZWlnaHQnKS5yZXBsYWNlKCdweCcsJycpKTtcblxuICAgICAgaWYgKHRoaXMud2lkdGg9PTUwMDApIHtcbiAgICAgICAgdGhpcy53aWR0aCA9IHNldHRpbmdzLmRlZmF1bHRTaXplWzBdO1xuICAgICAgICB0aGlzLnBhcmVudC5zdHlsZS53aWR0aCA9IHRoaXMucGFyZW50LndpZHRoID0gdGhpcy53aWR0aCArICdweCc7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5oZWlnaHQ9PTUwMDApIHtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBzZXR0aW5ncy5kZWZhdWx0U2l6ZVsxXTtcbiAgICAgICAgdGhpcy5wYXJlbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5wYXJlbnQuaGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyAncHgnO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIHNldHRpbmdzLnNpemUgPSBzZXR0aW5ncy5kZWZhdWx0U2l6ZTtcbiAgICAgIHRoaXMud2lkdGggPSBzZXR0aW5ncy5zaXplWzBdO1xuICAgICAgdGhpcy5oZWlnaHQgPSBzZXR0aW5ncy5zaXplWzFdO1xuICAgIH1cblxuICAgIC8vIGV2ZW50XG4gICAgaWYgKHNldHRpbmdzLmV2ZW50KSB7XG4gICAgICB0aGlzLmV2ZW50ID0gdGhpcy5vbignY2hhbmdlJywgc2V0dGluZ3MuZXZlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmV2ZW50ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNldHRpbmdzO1xuXG4gIH1cblxuICBpbml0KCkge1xuICAgIHRoaXMuYnVpbGRGcmFtZSgpO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgICB0aGlzLnNpemVJbnRlcmZhY2UoKTtcbiAgICB0aGlzLmF0dGFjaExpc3RlbmVycygpO1xuICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcbiAgICB0aGlzLmZpbmFsVG91Y2hlcygpO1xuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge31cbiAgc2l6ZUludGVyZmFjZSgpIHt9XG4gIGNvbG9ySW50ZXJmYWNlKCkge31cblxuICBhdHRhY2hMaXN0ZW5lcnMoKSB7XG5cbiAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0ID0gdGhpcy5pbnRlcmFjdGlvblRhcmdldCB8fCB0aGlzLmVsZW1lbnQ7XG5cbiAgICAvLyBTZXR1cCBpbnRlcmFjdGlvblxuICAgIGlmICh0b3VjaC5leGlzdHMpIHtcbiAgICAgIHRoaXMuaW50ZXJhY3Rpb25UYXJnZXQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGV2dCA9PiB0aGlzLnByZVRvdWNoKGV2dCkpO1xuICAgICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCBldnQgPT4gdGhpcy5wcmVUb3VjaE1vdmUoZXZ0KSk7XG4gICAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgZXZ0ID0+IHRoaXMucHJlVG91Y2hSZWxlYXNlKGV2dCkpO1xuICAgIH1cbiAgICB0aGlzLmJvdW5kUHJlTW92ZSA9IGV2dCA9PiB0aGlzLnByZU1vdmUoZXZ0KTtcbiAgICB0aGlzLmJvdW5kUHJlUmVsZWFzZSA9IGV2dCA9PiB0aGlzLnByZVJlbGVhc2UoZXZ0KTtcbiAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGV2dCA9PiB0aGlzLnByZUNsaWNrKGV2dCkpO1xuICB9XG5cbiAgZmluYWxUb3VjaGVzKCkge1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5jdXJzb3IgPSAncG9pbnRlcic7XG4gIH1cblxuICBwcmVDbGljayhlKSB7XG4gICAgLy8gMTAwMDAgZ2V0Q29tcHV0ZWRTdHlsZSBjYWxscyB0YWtlcyAxMDAgbXMuXG4gICAgLy8gLjouIG9uZSB0YWtlcyBhYm91dCAuMDFtc1xuICAgIGlmICh0aGlzLmVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgdGhpcy53aWR0aCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuZWxlbWVudCwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZSgnd2lkdGgnKS5yZXBsYWNlKCdweCcsJycpO1xuICAgIH1cbiAgICAvLyAxMDAwMCBnZXRDb21wdXRlZFN0eWxlIGNhbGxzIHRha2VzIDQwIG1zLlxuICAgIC8vIC46LiBvbmUgdGFrZXMgYWJvdXQgLjAwNG1zXG4gICAgdGhpcy5vZmZzZXQgPSBkb20uZmluZFBvc2l0aW9uKHRoaXMuZWxlbWVudCk7XG4gICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVNb3VzZShlLHRoaXMub2Zmc2V0KTtcbiAgICB0aGlzLmNsaWNrZWQgPSB0cnVlO1xuICAgIHRoaXMuY2xpY2soKTtcbiAgICB0aGlzLm1vdmVFdmVudCA9IGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuYm91bmRQcmVNb3ZlKTtcbiAgICB0aGlzLnJlbGVhc2VFdmVudCA9IGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLmJvdW5kUHJlUmVsZWFzZSk7XG4gICAgdGhpcy5lbWl0KCdjbGljaycpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgcHJlTW92ZShlKSB7XG4gICAgaWYgKCF0aGlzLndhaXQpIHtcbiAgICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSx0aGlzLm9mZnNldCk7XG4gICAgICB0aGlzLm1vdmUoKTtcbiAgICAgIHRoaXMud2FpdCA9IHRydWU7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHsgdGhpcy53YWl0ID0gZmFsc2U7IH0sMjUpO1xuICAgIH1cbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHByZVJlbGVhc2UoZSkge1xuICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSx0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG4gICAgdGhpcy5yZWxlYXNlKCk7XG4gICAgdGhpcy5lbWl0KCdyZWxlYXNlJyk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJyx0aGlzLmJvdW5kUHJlTW92ZSk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsdGhpcy5ib3VuZFByZVJlbGVhc2UpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgY2xpY2soKSB7XG5cbiAgfVxuXG4gIG1vdmUoKSB7XG5cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG5cbiAgfVxuXG5cbiAgLyogdG91Y2ggKi9cblxuICBwcmVUb3VjaChlKSB7XG4gICAgaWYgKHRoaXMuZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICB0aGlzLndpZHRoID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbGVtZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKCd3aWR0aCcpLnJlcGxhY2UoJ3B4JywnJyk7XG4gICAgfVxuICAgIHRoaXMub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbih0aGlzLmVsZW1lbnQpO1xuICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlVG91Y2goZSx0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5jbGlja2VkID0gdHJ1ZTtcbiAgICB0aGlzLnRvdWNoKGUpO1xuICAgIHRoaXMuZW1pdCgnY2xpY2snKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHByZVRvdWNoTW92ZShlKSB7XG4gICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVUb3VjaChlLHRoaXMub2Zmc2V0KTtcbiAgICAgIHRoaXMudG91Y2hNb3ZlKCk7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIHByZVRvdWNoUmVsZWFzZShlKSB7XG4gICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVUb3VjaChlLCB0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG4gICAgdGhpcy50b3VjaFJlbGVhc2UoKTtcbiAgICB0aGlzLmVtaXQoJ3JlbGVhc2UnKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHRvdWNoKCkge1xuICAgIHRoaXMuY2xpY2soKTtcbiAgfVxuXG4gIHRvdWNoTW92ZSgpIHtcbiAgICB0aGlzLm1vdmUoKTtcbiAgfVxuXG4gIHRvdWNoUmVsZWFzZSgpIHtcbiAgICB0aGlzLnJlbGVhc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAqIFJlc2l6ZSB0aGUgaW50ZXJmYWNlXG4gICogQHBhcmFtIHdpZHRoIHtudW1iZXJ9IE5ldyB3aWR0aCBpbiBwaXhlbHNcbiAgKiBAcGFyYW0gaGVpZ2h0IHtudW1iZXJ9IE5ldyBoZWlnaHQgaW4gcGl4ZWxzXG4gICpcbiAgKiBAZXhhbXBsZVxuICAqIGJ1dHRvbi5yZXNpemUoMTAwLDEwMCk7XG4gICovXG4gIHJlc2l6ZSh3aWR0aCxoZWlnaHQpIHtcbiAgICB0aGlzLndpZHRoID0gd2lkdGg7XG4gICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgdGhpcy5wYXJlbnQuc3R5bGUud2lkdGggPSB0aGlzLndpZHRoKydweCc7XG4gICAgdGhpcy5wYXJlbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5oZWlnaHQrJ3B4JztcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG4gIH1cblxuICBlbXB0eSgpIHtcbiAgICB3aGlsZSAodGhpcy5lbGVtZW50Lmxhc3RDaGlsZCkge1xuICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudC5sYXN0Q2hpbGQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAqIFJlbW92ZSB0aGUgaW50ZXJmYWNlIGZyb20gdGhlIHBhZ2UgYW5kIGNhbmNlbCBpdHMgZXZlbnQgbGlzdGVuZXIocykuXG4gICpcbiAgKiBAZXhhbXBsZVxuICAqIGJ1dHRvbi5kZXN0cm95KCk7XG4gICovXG4gIGRlc3Ryb3koKSB7XG4gICAgdGhpcy5lbXB0eSgpO1xuICAgIHRoaXMucGFyZW50LnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudCk7XG4gICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICBpZiAodGhpcy5pbnN0cnVtZW50KSB7XG4gICAgICBkZWxldGUgdGhpcy5pbnN0cnVtZW50W3RoaXMuaWRdO1xuICAgIH1cbiAgICB0aGlzLmN1c3RvbURlc3Ryb3koKTtcbiAgfVxuXG4gIGN1c3RvbURlc3Ryb3koKSB7XG5cbiAgfVxuXG4gIGNvbG9yaXplKHR5cGUsY29sb3IpIHtcbiAgICB0aGlzLmNvbG9yc1t0eXBlXSA9IGNvbG9yO1xuICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvY29yZS9pbnRlcmZhY2UuanMiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuZmluZFBvc2l0aW9uID0gKGVsKSA9PiB7XG4gIGxldCB2aWV3cG9ydE9mZnNldCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBsZXQgdG9wID0gdmlld3BvcnRPZmZzZXQudG9wICsgd2luZG93LnNjcm9sbFk7XG4gIGxldCBsZWZ0ID0gdmlld3BvcnRPZmZzZXQubGVmdCArIHdpbmRvdy5zY3JvbGxYO1xuICByZXR1cm4ge3RvcCxsZWZ0fTtcbn07XG5cbmV4cG9ydHMucGFyc2VFbGVtZW50ID0gKHBhcmVudCkgPT4ge1xuICBpZiAodHlwZW9mIHBhcmVudCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChwYXJlbnQucmVwbGFjZSgnIycsJycpKTtcbiAgfVxuXG4gIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCB8fCBwYXJlbnQgaW5zdGFuY2VvZiBTVkdFbGVtZW50KXtcbiAgICByZXR1cm4gcGFyZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAnTm8gdmFsaWQgcGFyZW50IGFyZ3VtZW50JztcbiAgfVxufTtcblxuZXhwb3J0cy5sb2NhdGVNb3VzZSA9IChlLG9mZnNldCkgPT4ge1xuICByZXR1cm4ge1xuICAgIHg6IGUucGFnZVggLSBvZmZzZXQubGVmdCxcbiAgICB5OiBlLnBhZ2VZIC0gb2Zmc2V0LnRvcFxuICB9O1xufTtcblxuZXhwb3J0cy5sb2NhdGVUb3VjaCA9IChlLG9mZnNldCkgPT4ge1xuICByZXR1cm4ge1xuICAgIHg6IGUudGFyZ2V0VG91Y2hlcy5sZW5ndGggPyBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVggLSBvZmZzZXQubGVmdCA6IGZhbHNlLFxuICAgIHk6IGUudGFyZ2V0VG91Y2hlcy5sZW5ndGggPyBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVkgLSBvZmZzZXQudG9wIDogZmFsc2VcbiAgfTtcbn07XG5cbmV4cG9ydHMuU21hcnRDYW52YXMgPSBmdW5jdGlvbihwYXJlbnQpIHtcblxuICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgdGhpcy5jb250ZXh0ID0gdGhpcy5lbGVtZW50LmdldENvbnRleHQoJzJkJyk7XG4gIHBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXG4gIHRoaXMucmVzaXplID0gKHcsaCkgPT4ge1xuICAgIHRoaXMuZWxlbWVudC53aWR0aCA9IHcqMjtcbiAgICB0aGlzLmVsZW1lbnQuaGVpZ2h0ID0gaCoyO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9IHcrJ3B4JztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gaCsncHgnO1xuICB9O1xuXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3V0aWwvZG9tLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLmlzT2JqZWN0ID0gKG9iaikgPT4ge1xuICBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkob2JqKSAmJiBvYmogIT09IG51bGwgJiYgb2JqIGluc3RhbmNlb2YgU1ZHRWxlbWVudCA9PT0gZmFsc2UgJiYgb2JqIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgPT09IGZhbHNlICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi91dGlsL3V0aWwuanMiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuZXhpc3RzID0gKCdvbnRvdWNoc3RhcnQnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvdXRpbC90b3VjaC5qcyIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gIHRoaXMuX2V2ZW50cyA9IHRoaXMuX2V2ZW50cyB8fCB7fTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxuRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24obikge1xuICBpZiAoIWlzTnVtYmVyKG4pIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IFR5cGVFcnJvcignbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcbiAgICBpZiAoIXRoaXMuX2V2ZW50cy5lcnJvciB8fFxuICAgICAgICAoaXNPYmplY3QodGhpcy5fZXZlbnRzLmVycm9yKSAmJiAhdGhpcy5fZXZlbnRzLmVycm9yLmxlbmd0aCkpIHtcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuY2F1Z2h0LCB1bnNwZWNpZmllZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNVbmRlZmluZWQoaGFuZGxlcikpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgICBjYXNlIDE6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICBoYW5kbGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc09iamVjdChoYW5kbGVyKSkge1xuICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBtO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gIGlmICh0aGlzLl9ldmVudHMubmV3TGlzdGVuZXIpXG4gICAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG4gICAgICAgICAgICAgIGlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpID9cbiAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gIGVsc2UgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcbiAgZWxzZVxuICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFt0aGlzLl9ldmVudHNbdHlwZV0sIGxpc3RlbmVyXTtcblxuICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSAmJiAhdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCkge1xuICAgIGlmICghaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSkge1xuICAgICAgbSA9IHRoaXMuX21heExpc3RlbmVycztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGlmIChtICYmIG0gPiAwICYmIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGggPiBtKSB7XG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJyhub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5ICcgK1xuICAgICAgICAgICAgICAgICAgICAnbGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ1VzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO1xuICAgICAgaWYgKHR5cGVvZiBjb25zb2xlLnRyYWNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgaW4gSUUgMTBcbiAgICAgICAgY29uc29sZS50cmFjZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICB2YXIgZmlyZWQgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBnKCkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgZyk7XG5cbiAgICBpZiAoIWZpcmVkKSB7XG4gICAgICBmaXJlZCA9IHRydWU7XG4gICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfVxuXG4gIGcubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgdGhpcy5vbih0eXBlLCBnKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZmYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGxpc3QsIHBvc2l0aW9uLCBsZW5ndGgsIGk7XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgbGlzdCA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgbGVuZ3RoID0gbGlzdC5sZW5ndGg7XG4gIHBvc2l0aW9uID0gLTE7XG5cbiAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8XG4gICAgICAoaXNGdW5jdGlvbihsaXN0Lmxpc3RlbmVyKSAmJiBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuXG4gIH0gZWxzZSBpZiAoaXNPYmplY3QobGlzdCkpIHtcbiAgICBmb3IgKGkgPSBsZW5ndGg7IGktLSA+IDA7KSB7XG4gICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHxcbiAgICAgICAgICAobGlzdFtpXS5saXN0ZW5lciAmJiBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpc3Quc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBrZXksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gIGlmICghdGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChrZXkgaW4gdGhpcy5fZXZlbnRzKSB7XG4gICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGxpc3RlbmVycykpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gIH0gZWxzZSBpZiAobGlzdGVuZXJzKSB7XG4gICAgLy8gTElGTyBvcmRlclxuICAgIHdoaWxlIChsaXN0ZW5lcnMubGVuZ3RoKVxuICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbbGlzdGVuZXJzLmxlbmd0aCAtIDFdKTtcbiAgfVxuICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gW107XG4gIGVsc2UgaWYgKGlzRnVuY3Rpb24odGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICByZXQgPSBbdGhpcy5fZXZlbnRzW3R5cGVdXTtcbiAgZWxzZVxuICAgIHJldCA9IHRoaXMuX2V2ZW50c1t0eXBlXS5zbGljZSgpO1xuICByZXR1cm4gcmV0O1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24odHlwZSkge1xuICBpZiAodGhpcy5fZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgICBpZiAoaXNGdW5jdGlvbihldmxpc3RlbmVyKSlcbiAgICAgIHJldHVybiAxO1xuICAgIGVsc2UgaWYgKGV2bGlzdGVuZXIpXG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gIH1cbiAgcmV0dXJuIDA7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJDb3VudCh0eXBlKTtcbn07XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9ldmVudHMvZXZlbnRzLmpzXG4vLyBtb2R1bGUgaWQgPSAxMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG5cbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5cbi8qKlxuICBDcmVhdGVzIGEgc3RlcHBhYmxlIHZhbHVlIHdpdGggbWluaW11bSwgbWF4aW11bSwgYW5kIHN0ZXAgc2l6ZS4gVGhpcyBpcyB1c2VkIGluIG1hbnkgaW50ZXJmYWNlcyB0byBjb25zdHJpY3QgdGhlaXIgdmFsdWVzIHRvIGNlcnRhaW4gcmFuZ2VzLlxuICBAcGFyYW0ge251bWJlcn0gW21pbj0wXSBtaW5pbXVtXG4gIEBwYXJhbSB7bnVtYmVyfSBbbWF4PTFdIG1heGltdW1cbiAgQHBhcmFtIHtudW1iZXJ9IFtzdGVwPTBdXG4gIEBwYXJhbSB7bnVtYmVyfSBbdmFsdWU9MF0gaW5pdGlhbCB2YWx1ZVxuICBAcmV0dXJucyB7T2JqZWN0fSBTdGVwXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdGVwIHtcblxuICBjb25zdHJ1Y3RvcihtaW4gPSAwLG1heCA9IDEsc3RlcCA9IDAsdmFsdWUgPSAwKSB7XG4gICAgLy9PYmplY3QuYXNzaWduKHRoaXMse21pbixtYXgsc3RlcH0pO1xuICAgIC8vQ2Fubm90IHVzZSBPYmplY3QuYXNzaWduIGJlY2F1c2Ugbm90IHN1cHBvcnRlZCBpbiBTYWZhcmkuXG4gICAgLy9JIHdvdWxkIGV4cGVjdCBmb3IgQmFiZWwgdG8gdGFrZSBjYXJlIG9mIHRoaXMgYnV0IGl0IGlzIG5vdC5cbiAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICB0aGlzLm1heCA9IG1heDtcbiAgICB0aGlzLnN0ZXAgPSBzdGVwO1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmNoYW5nZWQgPSBmYWxzZTtcbiAgICB0aGlzLm9sZFZhbHVlID0gZmFsc2U7XG4gICAgdGhpcy51cGRhdGUodGhpcy52YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICBVcGRhdGUgd2l0aCBhIG5ldyB2YWx1ZS4gVGhlIHZhbHVlIHdpbGwgYmUgYXV0by1hZGp1c3RlZCB0byBmaXQgdGhlIG1pbi9tYXgvc3RlcC5cbiAgICBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAgKi9cblxuICB1cGRhdGUodmFsdWUpIHtcbiAgICBpZiAodGhpcy5zdGVwKSB7XG4gICAgICAvLyB0aGlzLnZhbHVlID0gbWF0aC5jbGlwKE1hdGgucm91bmQodmFsdWUgLyAodGhpcy5zdGVwKSkgKiB0aGlzLnN0ZXAsIHRoaXMubWluLHRoaXMubWF4KTtcbiAgICAgIHRoaXMudmFsdWUgPSBtYXRoLmNsaXAoTWF0aC5yb3VuZCgodmFsdWUtdGhpcy5taW4pIC8gKHRoaXMuc3RlcCkpICogdGhpcy5zdGVwICsgdGhpcy5taW4sIHRoaXMubWluLHRoaXMubWF4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52YWx1ZSA9IG1hdGguY2xpcCh2YWx1ZSx0aGlzLm1pbix0aGlzLm1heCk7XG4gICAgfVxuICAgIGlmICh0aGlzLm9sZFZhbHVlICE9PSB0aGlzLnZhbHVlKSB7XG4gICAgICB0aGlzLm9sZFZhbHVlID0gdGhpcy52YWx1ZTtcbiAgICAgIHRoaXMuY2hhbmdlZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hhbmdlZCA9IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgIFVwZGF0ZSB3aXRoIGEgbm9ybWFsaXplZCB2YWx1ZSAwLTEuXG4gICAgQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gICovXG4gIHVwZGF0ZU5vcm1hbCh2YWx1ZSkge1xuICAgIHRoaXMudmFsdWUgPSBtYXRoLnNjYWxlKHZhbHVlLDAsMSx0aGlzLm1pbix0aGlzLm1heCk7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlKHRoaXMudmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAgR2V0IGEgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIHRoaXMudmFsdWUgLiBOb3Qgc2V0dGFibGUuXG4gICovXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiBtYXRoLm5vcm1hbGl6ZSh0aGlzLnZhbHVlLHRoaXMubWluLHRoaXMubWF4KTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbW9kZWxzL3N0ZXAuanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5pbXBvcnQgVG9nZ2xlTW9kZWwgZnJvbSAnLi4vbW9kZWxzL3RvZ2dsZSc7XG5cblxuLypcbmhvdyB0byB1c2UgOlxuXG5kaWFsLmludGVyYWN0aW9uID0gbmV3IEhhbmRsZSgncmFkaWFsJywncmVsYXRpdmUnLHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpO1xuLy8gZGlhbC5pbnRlcmFjdGlvbi5tb2RlID0gJ3JlbGF0aXZlJ1xuLy8gZGlhbC5pbnRlcmFjdGlvbi5kaXJlY3Rpb24gPSAncmFkaWFsJ1xuXG5vbiBjbGljazpcbmRpYWwuaW50ZXJhY3Rpb24uYW5jaG9yID0gdGhpcy5tb3VzZTtcblxub24gbW92ZTpcbmRpYWwuaW50ZXJhY3Rpb24udXBkYXRlKHRoaXMubW91c2UpO1xuXG5jb25zb2xlLmxvZyggZGlhbC5pbnRlcmFjdGlvbi52YWx1ZSApOyBzaG91bGQgYmUgYSBub3JtYWxpemVkIHZhbHVlLlxuXG4qL1xuXG4vKlxuICBhYnNvbHV0ZS9yZWxhdGl2ZSBhcmUgcHJvcGVydHk6IG1vZGVcbiAgcmFkaWFsL3ZlcnRpY2FsL2hvcml6b250YWwvMmQgYXJlIHByb3BlcnR5OiBkaXJlY3Rpb25cblxuICBwbGFuIDpcblxuICBpZiByZWxhdGl2ZSAtLVxuICBOTyBvbiBjbGljaywgZ2V0IHZhbHVlIG9mZnNldCBiZXR3ZWVuIGN1cnJlbnQgdmFsdWUgYW5kIGNsaWNrIHZhbHVlLlxuICBOTyBvbiBtb3ZlLCB1c2UgY2xpY2sgdmFsdWUgLSBvZmZzZXRcbiAgSU5TVEVBRFxuICB1c2UgZGVsdGEgLS0gYmMgdmVydGljYWwgbW90aW9uIG9uIGRpYWwgaXMgaW1wb3NzaWJsZSBvdGhlcndpc2VcbiAgYWxzbyBhbGxvdyB0byBzZXQgc2Vuc2l0aXZpdHlcblxuKi9cblxuZXhwb3J0IGNsYXNzIEhhbmRsZSB7XG5cbiAgY29uc3RydWN0b3IobW9kZT0nYWJzb2x1dGUnLGRpcmVjdGlvbj0ndmVydGljYWwnLHhib3VuZD1bMCwxMDBdLHlib3VuZD1bMCwxMDBdKSB7XG4gICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICB0aGlzLmRpcmVjdGlvbiA9IGRpcmVjdGlvbjtcbiAgICB0aGlzLnByZXZpb3VzID0gMDtcbiAgICB0aGlzLnZhbHVlID0gMDtcbiAgICB0aGlzLnNlbnNpdGl2aXR5ID0gMTtcbiAgICB0aGlzLnJlc2l6ZSh4Ym91bmQseWJvdW5kKTtcbiAgfVxuXG4gIHJlc2l6ZSh4Ym91bmQseWJvdW5kKSB7XG4gICAgdGhpcy5ib3VuZGFyeSA9IHtcbiAgICAgIG1pbjoge1xuICAgICAgICB4OiB4Ym91bmRbMF0sXG4gICAgICAgIHk6IHlib3VuZFswXVxuICAgICAgfSxcbiAgICAgIG1heDoge1xuICAgICAgICB4OiB4Ym91bmRbMV0sXG4gICAgICAgIHk6IHlib3VuZFsxXVxuICAgICAgfSxcbiAgICAgIGNlbnRlcjoge1xuICAgICAgICB4OiAoeGJvdW5kWzFdIC0geGJvdW5kWzBdKS8yICsgeGJvdW5kWzBdLFxuICAgICAgICB5OiAoeWJvdW5kWzFdIC0geWJvdW5kWzBdKS8yICsgeWJvdW5kWzBdXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHNldCBhbmNob3IobW91c2UpIHtcbiAgICB0aGlzLl9hbmNob3IgPSB0aGlzLmNvbnZlcnRQb3NpdGlvblRvVmFsdWUobW91c2UpO1xuICB9XG5cbiAgZ2V0IGFuY2hvcigpIHtcbiAgICByZXR1cm4gdGhpcy5fYW5jaG9yO1xuICB9XG5cblxuICB1cGRhdGUobW91c2UpIHtcbiAgICBpZiAodGhpcy5tb2RlPT09J3JlbGF0aXZlJykge1xuICAgICAgbGV0IGluY3JlbWVudCA9IHRoaXMuY29udmVydFBvc2l0aW9uVG9WYWx1ZShtb3VzZSkgLSB0aGlzLmFuY2hvcjtcbiAgICAgIGlmIChNYXRoLmFicyhpbmNyZW1lbnQpID4gMC41KSB7IGluY3JlbWVudCA9IDA7IH1cbiAgICAgIHRoaXMuYW5jaG9yID0gbW91c2U7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy52YWx1ZSArIGluY3JlbWVudCAqIHRoaXMuc2Vuc2l0aXZpdHk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLmNvbnZlcnRQb3NpdGlvblRvVmFsdWUobW91c2UpO1xuICAgIH1cbiAgICB0aGlzLnZhbHVlID0gbWF0aC5jbGlwKHRoaXMudmFsdWUsMCwxKTtcbiAgfVxuXG4gIGNvbnZlcnRQb3NpdGlvblRvVmFsdWUoY3VycmVudCkge1xuICAgIHN3aXRjaCh0aGlzLmRpcmVjdGlvbikge1xuICAgICAgY2FzZSAncmFkaWFsJzpcbiAgICAgICAgbGV0IHBvc2l0aW9uID0gbWF0aC50b1BvbGFyKGN1cnJlbnQueCAtIHRoaXMuYm91bmRhcnkuY2VudGVyLngsIGN1cnJlbnQueSAtIHRoaXMuYm91bmRhcnkuY2VudGVyLnkpO1xuICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uLmFuZ2xlIC8gKE1hdGguUEkqMik7XG4gICAgICAgIHBvc2l0aW9uID0gKChwb3NpdGlvbiAtIDAuMjUpICsgMSkgJSAxO1xuICAgICAgICByZXR1cm4gcG9zaXRpb247XG4gICAgICBjYXNlICd2ZXJ0aWNhbCc6XG4gICAgICAgIHJldHVybiBtYXRoLnNjYWxlKGN1cnJlbnQueSx0aGlzLmJvdW5kYXJ5Lm1pbi55LHRoaXMuYm91bmRhcnkubWF4LnksMCwxKTtcbiAgICAgIGNhc2UgJ2hvcml6b250YWwnOlxuICAgICAgICByZXR1cm4gbWF0aC5zY2FsZShjdXJyZW50LngsdGhpcy5ib3VuZGFyeS5taW4ueCx0aGlzLmJvdW5kYXJ5Lm1heC54LDAsMSk7XG4gICAgfVxuICB9XG5cbn1cblxuXG5leHBvcnQgY2xhc3MgQnV0dG9uIHtcblxuICBjb25zdHJ1Y3Rvcihtb2RlPSdidXR0b24nKSB7XG4gICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICB0aGlzLnN0YXRlID0gbmV3IFRvZ2dsZU1vZGVsKCk7XG4gICAgdGhpcy5wYWludGJydXNoID0gZmFsc2U7XG4gIH1cblxuICBjbGljaygpIHtcbiAgICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuICAgICAgY2FzZSAnaW1wdWxzZSc6XG4gICAgICAgIHRoaXMuc3RhdGUub24oKTtcbiAgICAgICAgaWYgKHRoaXMudGltZW91dCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudGltZW91dCA9IHNldFRpbWVvdXQodGhpcy5zdGF0ZS5vZmYuYmluZCh0aGlzKSwzMCk7XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdidXR0b24nOlxuICAgICAgICB0aGlzLnR1cm5PbigpO1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgICB5OiBtYXRoLmNsaXAoMSAtIHRoaXMubW91c2UueSAvIHRoaXMuaGVpZ2h0LDAsMSlcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy50dXJuT24oKTtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG4gICAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd0b2dnbGUnOlxuICAgICAgICB0aGlzLmZsaXAoKTtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgfVxuXG4gIG1vdmUoKSB7XG4gICAgaWYgKHRoaXMubW9kZT09PSdhZnRlcnRvdWNoJykge1xuICAgICAgdGhpcy5wb3NpdGlvbiA9IHtcbiAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICB9O1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgc3dpdGNoICh0aGlzLm1vZGUpIHtcbiAgICAgIGNhc2UgJ2J1dHRvbic6XG4gICAgICAgIHRoaXMudHVybk9mZigpO1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMudHVybk9mZigpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uID0ge1xuICAgICAgICAgIHg6IHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsXG4gICAgICAgICAgeTogMSAtIHRoaXMubW91c2UueSAvIHRoaXMuaGVpZ2h0XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgICAgICAgIHk6IHRoaXMucG9zaXRpb24ueSxcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3V0aWwvaW50ZXJhY3Rpb24uanMiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRvZ2dsZSB7XG5cbiAgY29uc3RydWN0b3Ioc3RhdGUpIHtcbiAgICB0aGlzLnN0YXRlID0gc3RhdGUgfHwgZmFsc2U7XG4gIH1cblxuICBmbGlwKHN0YXRlKSB7XG4gICAgaWYgKHN0YXRlIHx8IHN0YXRlID09PSBmYWxzZSkge1xuICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0YXRlID0gIXRoaXMuc3RhdGU7XG4gICAgfVxuICB9XG5cbiAgb24oKSB7XG4gICAgdGhpcy5zdGF0ZSA9IHRydWU7XG4gIH1cblxuICBvZmYoKSB7XG4gICAgdGhpcy5zdGF0ZSA9IGZhbHNlO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9tb2RlbHMvdG9nZ2xlLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbi8qKlxuKiBTbGlkZXJcbipcbiogQGRlc2NyaXB0aW9uIEhvcml6b250YWwgb3IgdmVydGljYWwgc2xpZGVyIHdpdGggc2V0dGFibGUgaW50ZXJhY3Rpb24gbW9kZXMuXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwic2xpZGVyXCIgc3RlcD0wLjI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc2xpZGVyID0gbmV3IE5leHVzLlNsaWRlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBzbGlkZXIgPSBuZXcgTmV4dXMuU2xpZGVyKCcjdGFyZ2V0Jyx7XG4qICAgICAnc2l6ZSc6IFsxMjAsMjBdLFxuKiAgICAgJ21vZGUnOiAncmVsYXRpdmUnLCAgLy8gJ3JlbGF0aXZlJyBvciAnYWJzb2x1dGUnXG4qICAgICAnbWluJzogMCxcbiogICAgICdtYXgnOiAxLFxuKiAgICAgJ3N0ZXAnOiAwLFxuKiAgICAgJ3ZhbHVlJzogMFxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyB3aGVuIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIEV2ZW50IGRhdGE6IDxpPm51bWJlcjwvaT4gVGhlIG51bWJlciB2YWx1ZSBvZiB0aGUgaW50ZXJmYWNlLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiBzbGlkZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2xpZGVyIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWydtaW4nLCdtYXgnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMTIwLDIwXSxcbiAgICAgICdtb2RlJzogJ3JlbGF0aXZlJywgIC8vICdyZWxhdGl2ZScgb3IgJ2Fic29sdXRlJ1xuICAgICAgJ21pbic6IDAsXG4gICAgICAnbWF4JzogMSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDBcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5vcmllbnRhdGlvbiA9ICd2ZXJ0aWNhbCc7IC8vIFRoaXMgd2lsbCBjaGFuZ2UgYXV0b21hdGljYWxseSB0byAnaG9yaXpvbnRhbCdpZiB0aGUgaW50ZXJmYWNlIGlzIHdpZGVyIHRoYW4gaXQgaXMgdGFsbC5cblxuICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5taW4sIHRoaXMuc2V0dGluZ3MubWF4LCB0aGlzLnNldHRpbmdzLnN0ZXAsIHRoaXMuc2V0dGluZ3MudmFsdWUpO1xuXG4gICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLHRoaXMub3JpZW50YXRpb24sWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbi5kaXJlY3Rpb24gPSB0aGlzLm9yaWVudGF0aW9uO1xuXG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuXG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyID0gc3ZnLmNyZWF0ZSgncmVjdCcpO1xuICAgIHRoaXMuZmlsbGJhciA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmtub2IgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuZmlsbGJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBpZiAodGhpcy53aWR0aCA8IHRoaXMuaGVpZ2h0KSB7XG4gICAgICB0aGlzLm9yaWVudGF0aW9uID0gJ3ZlcnRpY2FsJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcmllbnRhdGlvbiA9ICdob3Jpem9udGFsJztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wb3NpdGlvbikge1xuICAgICAgdGhpcy5wb3NpdGlvbi5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB9XG5cbiAgICBsZXQgeCwgeSwgdywgaCwgYmFyT2Zmc2V0LCBjb3JuZXJSYWRpdXM7XG4gICAgdGhpcy5rbm9iRGF0YSA9IHtcbiAgICAgIGxldmVsOiAwLFxuICAgICAgcjogMFxuICAgIH07XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy50aGlja25lc3MgPSB0aGlzLndpZHRoIC8gMjtcbiAgICBcdHggPSB0aGlzLndpZHRoLzI7XG4gICAgXHR5ID0gMDtcbiAgICBcdHcgPSB0aGlzLnRoaWNrbmVzcztcbiAgICBcdGggPSB0aGlzLmhlaWdodDtcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IGgtdGhpcy5rbm9iRGF0YS5yLXRoaXMubm9ybWFsaXplZCooaC10aGlzLmtub2JEYXRhLnIqMik7XG4gICAgICBiYXJPZmZzZXQgPSAndHJhbnNsYXRlKCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycsMCknO1xuICAgICAgY29ybmVyUmFkaXVzID0gdy8yO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMuaGVpZ2h0IC8gMjtcbiAgICBcdHggPSAwO1xuICAgIFx0eSA9IHRoaXMuaGVpZ2h0LzI7XG4gICAgXHR3ID0gdGhpcy53aWR0aDtcbiAgICBcdGggPSB0aGlzLnRoaWNrbmVzcztcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IHRoaXMubm9ybWFsaXplZCoody10aGlzLmtub2JEYXRhLnIqMikrdGhpcy5rbm9iRGF0YS5yO1xuICAgICAgYmFyT2Zmc2V0ID0gJ3RyYW5zbGF0ZSgwLCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycpJztcbiAgICAgIGNvcm5lclJhZGl1cyA9IGgvMjtcbiAgICB9XG5cbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3gnLHgpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneScseSk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGJhck9mZnNldCk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsY29ybmVyUmFkaXVzKTsgLy8gY29ybmVyIHJhZGl1c1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgncnknLGNvcm5lclJhZGl1cyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3gnLHgpO1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneScsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdyk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgtdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3gnLDApO1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneScseSk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgpO1xuICAgIH1cbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGJhck9mZnNldCk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgncngnLGNvcm5lclJhZGl1cyk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgncnknLGNvcm5lclJhZGl1cyk7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHgpO1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScseSk7XG4gICAgfVxuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYkRhdGEucik7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICB9XG5cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKCF0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzKjAuNzU7XG4gICAgfVxuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYkRhdGEucik7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICBcdCAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLmtub2JEYXRhLnIrdGhpcy5fdmFsdWUubm9ybWFsaXplZCoodGhpcy5oZWlnaHQtdGhpcy5rbm9iRGF0YS5yKjIpO1xuICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmhlaWdodCAtIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3knLHRoaXMuaGVpZ2h0IC0gdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICBcdCAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkKih0aGlzLndpZHRoLXRoaXMua25vYkRhdGEucioyKSt0aGlzLmtub2JEYXRhLnI7XG4gICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3gnLDApO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9XG4gIH1cblxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzKjAuOTtcbiAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMucG9zaXRpb24udXBkYXRlKHRoaXMubW91c2UpO1xuICAgICAgdGhpcy5fdmFsdWUudXBkYXRlTm9ybWFsKCB0aGlzLnBvc2l0aW9uLnZhbHVlICk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5fdmFsdWUudmFsdWUpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuICB9XG5cbiAgLyoqXG4gIFRoZSBzbGlkZXIncyBjdXJyZW50IHZhbHVlLiBJZiBzZXQgbWFudWFsbHksIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgc2xpZGVyLnZhbHVlID0gMTA7XG4gICovXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHYpIHtcbiAgICB0aGlzLl92YWx1ZS51cGRhdGUodik7XG4gICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuX3ZhbHVlLnZhbHVlKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIExvd2VyIGxpbWl0IG9mIHRoZSBzbGlkZXJzJ3Mgb3V0cHV0IHJhbmdlXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNsaWRlci5taW4gPSAxMDAwO1xuICAqL1xuICBnZXQgbWluKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5taW47XG4gIH1cbiAgc2V0IG1pbih2KSB7XG4gICAgdGhpcy5fdmFsdWUubWluID0gdjtcbiAgfVxuXG4gIC8qKlxuICBVcHBlciBsaW1pdCBvZiB0aGUgc2xpZGVyJ3Mgb3V0cHV0IHJhbmdlXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNsaWRlci5tYXggPSAxMDAwO1xuICAqL1xuICBnZXQgbWF4KCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5tYXg7XG4gIH1cbiAgc2V0IG1heCh2KSB7XG4gICAgdGhpcy5fdmFsdWUubWF4ID0gdjtcbiAgfVxuXG4gIC8qKlxuICBUaGUgaW5jcmVtZW50IHRoYXQgdGhlIHNsaWRlcidzIHZhbHVlIGNoYW5nZXMgYnkuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNsaWRlci5zdGVwID0gNTtcbiAgKi9cbiAgZ2V0IHN0ZXAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnN0ZXA7XG4gIH1cbiAgc2V0IHN0ZXAodikge1xuICAgIHRoaXMuX3ZhbHVlLnN0ZXAgPSB2O1xuICB9XG5cbiAgLyoqXG4gIEFic29sdXRlIG1vZGUgKHNsaWRlcidzIHZhbHVlIGp1bXBzIHRvIG1vdXNlIGNsaWNrIHBvc2l0aW9uKSBvciByZWxhdGl2ZSBtb2RlIChtb3VzZSBkcmFnIGNoYW5nZXMgdmFsdWUgcmVsYXRpdmUgdG8gaXRzIGN1cnJlbnQgcG9zaXRpb24pLiBEZWZhdWx0OiBcInJlbGF0aXZlXCIuXG4gIEB0eXBlIHtzdHJpbmd9XG4gIEBleGFtcGxlIHNsaWRlci5tb2RlID0gXCJyZWxhdGl2ZVwiO1xuICAqL1xuICBnZXQgbW9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi5tb2RlO1xuICB9XG4gIHNldCBtb2RlKHYpIHtcbiAgICB0aGlzLnBvc2l0aW9uLm1vZGUgPSB2O1xuICB9XG5cblxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9zbGlkZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IFRvZ2dsZU1vZGVsID0gcmVxdWlyZSgnLi4vbW9kZWxzL3RvZ2dsZScpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5cbi8qKlxuKiBUb2dnbGVcbipcbiogQGRlc2NyaXB0aW9uIEJpbmFyeSBzd2l0Y2hcbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJ0b2dnbGVcIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciB0b2dnbGUgPSBuZXcgTmV4dXMuVG9nZ2xlKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHRvZ2dsZSA9IG5ldyBOZXh1cy5Ub2dnbGUoJyN0YXJnZXQnLHtcbiogICAgICdzaXplJzogWzQwLDIwXSxcbiogICAgICdzdGF0ZSc6IGZhbHNlXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIFBhcmFtZXRlcjogVGhlIGJvb2xlYW4gc3RhdGUgb2YgdGhlIGludGVyZmFjZS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogdG9nZ2xlLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbipcbiovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUb2dnbGUgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3ZhbHVlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFs0MCwyMF0sXG4gICAgICAndGFyZ2V0JzogZmFsc2UsXG4gICAgICAnc3RhdGUnOiBmYWxzZVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLl9zdGF0ZSA9IG5ldyBUb2dnbGVNb2RlbCh0aGlzLnNldHRpbmdzLnN0YXRlKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyID0gc3ZnLmNyZWF0ZSgncmVjdCcpO1xuICAgIHRoaXMua25vYiA9IHN2Zy5jcmVhdGUoJ2NpcmNsZScpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBpZiAodGhpcy5oZWlnaHQgPCB0aGlzLndpZHRoLzIpIHtcbiAgICAgIHRoaXMua25vYlNpemUgPSB0aGlzLmhlaWdodC8yO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmtub2JTaXplID0gdGhpcy53aWR0aC80O1xuICAgIH1cblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneCcsdGhpcy53aWR0aC8yIC0gdGhpcy5rbm9iU2l6ZSoxLjUpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneScsdGhpcy5oZWlnaHQvMiAtIHRoaXMua25vYlNpemUvMik7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsdGhpcy5rbm9iU2l6ZS8yKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3J5Jyx0aGlzLmtub2JTaXplLzIpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnd2lkdGgnLHRoaXMua25vYlNpemUqMyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLHRoaXMua25vYlNpemUpO1xuXG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMud2lkdGgvMiAtIHRoaXMua25vYlNpemUpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmhlaWdodC8yKTtcbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JTaXplKTtcblxuICB9XG5cbiAgY29sb3JJbnRlcmZhY2UoKSB7XG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIgLSB0aGlzLmtub2JTaXplKTtcbiAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeCcsdGhpcy53aWR0aC8yICsgdGhpcy5rbm9iU2l6ZSk7XG4gICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIH1cbiAgfVxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMuZmxpcCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICB9XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIHRvZ2dsZSBpcyBjdXJyZW50bHkgb24gb3Igb2ZmLiBTZXR0aW5nIHRoaXMgcHJvcGVydHkgd2lsbCB1cGRhdGUgdGhlIHRvZ2dsZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge2Jvb2xlYW59XG4gIEBleGFtcGxlIHRvZ2dsZS5zdGF0ZSA9IGZhbHNlO1xuICAqL1xuICBnZXQgc3RhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlLnN0YXRlO1xuICB9XG4gIHNldCBzdGF0ZSh2YWx1ZSkge1xuICAgIHRoaXMuX3N0YXRlLmZsaXAodmFsdWUpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgKiBTd2l0Y2ggdGhlIHRvZ2dsZSBzdGF0ZSB0byBpdHMgb3Bwb3NpdGUgc3RhdGVcbiAgKiBAZXhhbXBsZVxuICAqIHRvZ2dsZS5mbGlwKCk7XG4gICovXG4gIGZsaXAoKSB7XG4gICAgdGhpcy5fc3RhdGUuZmxpcCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvdG9nZ2xlLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBCdXR0b25UZW1wbGF0ZSA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvYnV0dG9udGVtcGxhdGUnKTtcblxuLyoqXG4qIEJ1dHRvblxuKlxuKiBAZGVzY3JpcHRpb24gQ2lyY3VsYXIgYnV0dG9uIHdpdGggb3B0aW9uYWwgYWZ0ZXJ0b3VjaC5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJidXR0b25cIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBidXR0b24gPSBuZXcgTmV4dXMuQnV0dG9uKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIGJ1dHRvbiA9IG5ldyBOZXh1cy5CdXR0b24oJyN0YXJnZXQnLHtcbiogICAnc2l6ZSc6IFs4MCw4MF0sXG4qICAgJ21vZGUnOiAnYWZ0ZXJ0b3VjaCcsXG4qICAgJ3N0YXRlJzogZmFsc2VcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogSW4gPGI+YnV0dG9uIG1vZGU8L2I+LCA8Yj50b2dnbGUgbW9kZTwvYj4sIGFuZCA8Yj5pbXB1bHNlIG1vZGU8L2I+LCB0aGUgb3V0cHV0IGRhdGEgaXMgYSBib29sZWFuIGRlc2NyaWJpbmcgdGhlIHN0YXRlIG9mIHRoZSBidXR0b24uPGJyPlxuKiBJbiA8Yj5hZnRlcnRvdWNoIG1vZGU8L2I+LCB0aGUgb3V0cHV0IGRhdGEgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgeCAoMC0xKSBhbmQgeSAoMC0xKSBwb3NpdGlvbnMgb2YgYWZ0ZXJ0b3VjaC5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogYnV0dG9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICAvLyB2IGlzIHRoZSB2YWx1ZSBvZiB0aGUgYnV0dG9uXG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCdXR0b24gZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnbW9kZSddO1xuXG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFs4MCw4MF0sXG4gICAgICAnbW9kZSc6ICdhZnRlcnRvdWNoJywgLy8gYnV0dG9uLCBhZnRlcnRvdWNoLCBpbXB1bHNlLCB0b2dnbGVcbiAgICAgICdzdGF0ZSc6IGZhbHNlXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuXG4gICAgLyoqXG4gICAgKiBJbnRlcmFjdGlvbiBtb2RlOiBzdXBwb3J0cyBcImJ1dHRvblwiLCBcImFmdGVydG91Y2hcIiwgXCJpbXB1bHNlXCIsIG9yIFwidG9nZ2xlXCJcbiAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgKiBAZXhhbXBsZSBidXR0b24ubW9kZSA9ICd0b2dnbGUnO1xuICAgICovXG4gICAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG4gICAgdGhpcy5wYWQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wYWQpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXG4gICAgLy8gb25seSB1c2VkIGlmIGluICdhZnRlcnRvdWNoJyBtb2RlXG4gICAgdGhpcy5kZWZzID0gc3ZnLmNyZWF0ZSgnZGVmcycpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmRlZnMpO1xuXG4gICAgdGhpcy5ncmFkaWVudCA9IHN2Zy5yYWRpYWxHcmFkaWVudCh0aGlzLmRlZnMsMik7XG5cbiAgICB0aGlzLmdyYWRpZW50LnN0b3BzWzBdLnNldEF0dHJpYnV0ZSgnb2Zmc2V0JywgJzMwJScpO1xuXG4gICAgdGhpcy5ncmFkaWVudC5zdG9wc1sxXS5zZXRBdHRyaWJ1dGUoJ29mZnNldCcsICcxMDAlJyk7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMuaGVpZ2h0LzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgncicsIE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpIC8gMiAtIHRoaXMud2lkdGgvNDApO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJywgdGhpcy53aWR0aC8yMCk7XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuZ3JhZGllbnQuc3RvcHNbMF0uc2V0QXR0cmlidXRlKCdzdG9wLWNvbG9yJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB0aGlzLmdyYWRpZW50LnN0b3BzWzFdLnNldEF0dHJpYnV0ZSgnc3RvcC1jb2xvcicsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKlxuICAqIFVwZGF0ZSB0aGUgdmlzdWFsIGludGVyZmFjZSB1c2luZyBpdHMgY3VycmVudCBzdGF0ZVxuICAqXG4gICogQGV4YW1wbGVcbiAgKiBidXR0b24ucmVuZGVyKCk7XG4gICovXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2UnLCB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLm1vZGU9PT0nYWZ0ZXJ0b3VjaCcpIHtcbiAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2UnLCAndXJsKCMnK3RoaXMuZ3JhZGllbnQuaWQrJyknKTtcbiAgICAgICAgdGhpcy5ncmFkaWVudC5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3gnLCAodGhpcy5wb3NpdGlvbi54KjEwMCkrJyUnKTtcbiAgICAgICAgdGhpcy5ncmFkaWVudC5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3knLCAoKDEtdGhpcy5wb3NpdGlvbi55KSoxMDApKyclJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgICB9XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIH1cbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9idXR0b24uanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IG1hdGggPSByZXF1aXJlKCcuLi91dGlsL21hdGgnKTtcbmxldCBUb2dnbGVNb2RlbCA9IHJlcXVpcmUoJy4uL21vZGVscy90b2dnbGUnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xuXG4vKipcbkJ1dHRvbiBUZW1wbGF0ZVxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnV0dG9uVGVtcGxhdGUgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKGFyZ3Msb3B0aW9ucyxkZWZhdWx0cykge1xuXG4gICAgc3VwZXIoYXJncyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZSB8fCAnYnV0dG9uJztcblxuICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICB4OiAwLFxuICAgICAgeTogMFxuICAgIH07XG5cbiAgICB0aGlzLl9zdGF0ZSA9IG5ldyBUb2dnbGVNb2RlbCh0aGlzLnNldHRpbmdzLnN0YXRlKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG4gICAgdGhpcy5wYWQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAnI2QxOCcpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgJyNkMTgnKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsIDQpO1xuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMucGFkKTtcblxuICAgIHRoaXMuaW50ZXJhY3Rpb25UYXJnZXQgPSB0aGlzLnBhZDtcblxuICAgIHRoaXMuc2l6ZUludGVyZmFjZSgpO1xuICB9XG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMuaGVpZ2h0LzIpO1xuICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgncicsIE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpIC8gMiAtIDIpO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5zdGF0ZSkge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuZmlsbCk7XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB9XG4gIH1cblxuICBkb3duKHBhaW50YnJ1c2gpIHtcbiAgICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuICAgICAgY2FzZSAnaW1wdWxzZSc6XG4gICAgICAgIHRoaXMudHVybk9uKCk7XG4gICAgICAgIGlmICh0aGlzLnRpbWVvdXQpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRpbWVvdXQgPSBzZXRUaW1lb3V0KHRoaXMudHVybk9mZi5iaW5kKHRoaXMpLDMwKTtcbiAgICAvLyAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYnV0dG9uJzpcbiAgICAgICAgdGhpcy50dXJuT24oKTtcbiAgICAvLyAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgICB5OiBtYXRoLmNsaXAoMS10aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMudHVybk9uKCk7XG4gICAgLy8gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAvLyAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgIC8vICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgIC8vICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgIC8vICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3RvZ2dsZSc6XG4gICAgICAgIHRoaXMuZmxpcChwYWludGJydXNoKTtcbiAgICAvLyAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICB9XG5cbiAgYmVuZChtb3VzZSkge1xuICAgIGlmICh0aGlzLm1vZGU9PT0nYWZ0ZXJ0b3VjaCcpIHtcbiAgICAgIHRoaXMubW91c2UgPSBtb3VzZSB8fCB0aGlzLm1vdXNlO1xuICAgICAgdGhpcy5wb3NpdGlvbiA9IHtcbiAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsMCwxKSxcbiAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICB9O1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIHVwKCkge1xuICAgIHN3aXRjaCAodGhpcy5tb2RlKSB7XG4gICAgICBjYXNlICdidXR0b24nOlxuICAgICAgICB0aGlzLnR1cm5PZmYoKTtcbiAgICAgIC8vICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5zdGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWZ0ZXJ0b3VjaCc6XG4gICAgICAgIHRoaXMudHVybk9mZigpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uID0ge1xuICAgICAgICAgIHg6IG1hdGguY2xpcCh0aGlzLm1vdXNlLnggLyB0aGlzLndpZHRoLDAsMSksXG4gICAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwwLDEpXG4gICAgICAgIH07XG4gICAgICAvLyAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgIC8vICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgLy8gICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgICAgLy8gICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgLy8gIH0pO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvKiBvdmVyd3JpdGFibGUgaW50ZXJhY3Rpb24gaGFuZGxlcnMgKi9cblxuICBjbGljaygpIHtcbiAgICB0aGlzLmRvd24oKTtcbiAgfVxuICBtb3ZlKCkge1xuICAgIHRoaXMuYmVuZCgpO1xuICB9XG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy51cCgpO1xuICB9XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIGJ1dHRvbiBpcyBvbiAocHJlc3NlZCkgb3Igb2ZmIChub3QgcHJlc3NlZClcbiAgQHR5cGUge2Jvb2xlYW59XG4gIEBleGFtcGxlIGJ1dHRvbi5zdGF0ZSA9IHRydWU7XG4gICovXG4gIGdldCBzdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGUuc3RhdGU7XG4gIH1cbiAgc2V0IHN0YXRlKHZhbHVlKSB7XG4gICAgdGhpcy5fc3RhdGUuZmxpcCh2YWx1ZSk7XG4gICAgaWYgKHRoaXMubW9kZT09PSdhZnRlcnRvdWNoJykge1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICB9XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBDaGFuZ2UgdGhlIGJ1dHRvbiB0byBpdHMgYWx0ZXJuYXRlIHN0YXRlIChvZmY9Pm9uLCBvbj0+b2ZmKSwgb3IgZmxpcCBpdCB0byBhIHNwZWNpZmllZCBzdGF0ZS5cbiAgQHBhcmFtIHZhbHVlIHtib29sZWFufSAoT3B0aW9uYWwpIFN0YXRlIHRvIGZsaXAgdG8uXG4gIEBleGFtcGxlIGJ1dHRvbi5mbGlwKCk7XG4gICovXG4gIGZsaXAodmFsdWUpIHtcbiAgICB0aGlzLl9zdGF0ZS5mbGlwKHZhbHVlKTtcbiAgICBpZiAodGhpcy5tb2RlPT09J2FmdGVydG91Y2gnKSB7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuICAgICAgICB5OiB0aGlzLnBvc2l0aW9uLnksXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICAgIH1cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIFR1cm4gdGhlIGJ1dHRvbidzIHN0YXRlIHRvIHRydWUuXG4gIEBleGFtcGxlIGJ1dHRvbi50dXJuT24oKTtcbiAgKi9cbiAgdHVybk9uKGVtaXR0aW5nKSB7XG4gICAgdGhpcy5fc3RhdGUub24oKTtcbiAgICBpZiAoZW1pdHRpbmchPT1mYWxzZSkge1xuICAgICAgaWYgKHRoaXMubW9kZT09PSdhZnRlcnRvdWNoJykge1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcbiAgICAgICAgICB5OiB0aGlzLnBvc2l0aW9uLnksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIFR1cm4gdGhlIGJ1dHRvbidzIHN0YXRlIHRvIGZhbHNlLlxuICBAZXhhbXBsZSBidXR0b24udHVybk9mZigpO1xuICAqL1xuICB0dXJuT2ZmKGVtaXR0aW5nKSB7XG4gICAgdGhpcy5fc3RhdGUub2ZmKCk7XG4gICAgaWYgKGVtaXR0aW5nIT09ZmFsc2UpIHtcbiAgICAgIGlmICh0aGlzLm1vZGU9PT0nYWZ0ZXJ0b3VjaCcpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG4gICAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55LFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvY29tcG9uZW50cy9idXR0b250ZW1wbGF0ZS5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IEJ1dHRvblRlbXBsYXRlID0gcmVxdWlyZSgnLi4vY29tcG9uZW50cy9idXR0b250ZW1wbGF0ZScpO1xuXG4vKipcbiogVGV4dEJ1dHRvblxuKlxuKiBAZGVzY3JpcHRpb24gVGV4dCBidXR0b25cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJ0ZXh0QnV0dG9uXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgdGV4dGJ1dHRvbiA9IG5ldyBOZXh1cy5UZXh0QnV0dG9uKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHRleHRidXR0b24gPSBuZXcgTmV4dXMuVGV4dEJ1dHRvbignI3RhcmdldCcse1xuKiAgICAgJ3NpemUnOiBbMTUwLDUwXSxcbiogICAgICdzdGF0ZSc6IGZhbHNlLFxuKiAgICAgJ3RleHQnOiAnUGxheScsXG4qICAgICAnYWx0ZXJuYXRlVGV4dCc6ICdTdG9wJ1xuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhIDxpPnN0cmluZzwvaT4gb2YgdGhlIHRleHQgb24gdGhlIGJ1dHRvbiBhdCB0aGUgbW9tZW50IGl0IHdhcyBjbGlja2VkLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiB0ZXh0YnV0dG9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRleHRCdXR0b24gZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzE1MCw1MF0sXG4gICAgICAnc3RhdGUnOiBmYWxzZSxcbiAgICAgICd0ZXh0JzogJ1BsYXknXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuX3RleHQgPSB0aGlzLnNldHRpbmdzLnRleHQ7XG5cbiAgICBpZih0aGlzLnNldHRpbmdzLmFsdGVybmF0ZSl7IC8vVE9ETzogUmVtb3ZlIHRoaXMgY29uZGl0aW9uYWwgaW4gYSBicmVha2luZy1jaGFuZ2VzIHJlbGVhc2VcbiAgICAgIHRoaXMuc2V0dGluZ3MuYWx0ZXJuYXRlVGV4dCA9IHRoaXMuc2V0dGluZ3MuYWx0ZXJuYXRlO1xuICAgICAgY29uc29sZS53YXJuKFwiJ2FsdGVybmF0ZScgaW5pdGlhdG9yIGlzIGRlcHJlY2F0ZWQuIFVzZSAnYWx0ZXJuYXRlVGV4dCcgaW5zdGVhZC5cIik7XG4gICAgfVxuICAgIHRoaXMuX2FsdGVybmF0ZVRleHQgPSB0aGlzLnNldHRpbmdzLmFsdGVybmF0ZVRleHQ7XG4gICAgdGhpcy5tb2RlID0gKHRoaXMuc2V0dGluZ3MuYWx0ZXJuYXRlVGV4dCkgPyAndG9nZ2xlJyA6ICdidXR0b24nO1xuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICB0aGlzLnN0YXRlID0gdGhpcy5zZXR0aW5ncy5zdGF0ZTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcblxuICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG5cbiAgICB0aGlzLnRleHRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl90ZXh0O1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnRleHRFbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY29sb3IgPSB0aGlzLmNvbG9ycy5kYXJrO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuICAgICAgbGV0IHRleHRzaXplID0gdGhpcy5oZWlnaHQvMztcbiAgICAgIGxldCB0ZXh0c2l6ZTIgPSAodGhpcy53aWR0aCAvICh0aGlzLl90ZXh0Lmxlbmd0aCArIDIpICk7XG4gICAgICB0ZXh0c2l6ZSA9IE1hdGgubWluKHRleHRzaXplLHRleHRzaXplMik7XG4gICAgICBpZiAodGhpcy5hbHRlcm5hdGVUZXh0KSB7XG4gICAgICAgIGxldCB0ZXh0c2l6ZTMgPSAodGhpcy53aWR0aCAvICh0aGlzLmFsdGVybmF0ZVRleHQubGVuZ3RoICsgMikgKTtcbiAgICAgICAgdGV4dHNpemUgPSBNYXRoLm1pbih0ZXh0c2l6ZSx0ZXh0c2l6ZTMpO1xuICAgICAgfVxuICAgICAgbGV0IHN0eWxlcyA9ICd3aWR0aDogJyArIHRoaXMud2lkdGggKyAncHg7JztcbiAgICAgIHN0eWxlcyArPSAnaGVpZ2h0OiAnICsgdGhpcy5oZWlnaHQgKyAncHg7JztcbiAgICAgIHN0eWxlcyArPSAncGFkZGluZzogJysodGhpcy5oZWlnaHQtdGV4dHNpemUpLzIrJ3B4IDBweDsnO1xuICAgICAgc3R5bGVzICs9ICdib3gtc2l6aW5nOiBib3JkZXItYm94Oyc7XG4gICAgICBzdHlsZXMgKz0gJ3RleHQtYWxpZ246IGNlbnRlcjsnO1xuICAgICAgc3R5bGVzICs9ICdmb250LWZhbWlseTogaW5oZXJpdDsnO1xuICAgICAgc3R5bGVzICs9ICdmb250LXdlaWdodDogNzAwOyc7XG4gICAgICBzdHlsZXMgKz0gJ29wYWNpdHk6IDE7JztcbiAgICAgIHN0eWxlcyArPSAnZm9udC1zaXplOicgKyB0ZXh0c2l6ZSArICdweDsnO1xuICAgICAgdGhpcy50ZXh0RWxlbWVudC5zdHlsZS5jc3NUZXh0ID0gc3R5bGVzO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5maWxsO1xuICAgICAgdGhpcy50ZXh0RWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG4gICAgICB0aGlzLnRleHRFbGVtZW50LmlubmVySFRNTCA9IHRoaXMuX3RleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG4gICAgICB0aGlzLnRleHRFbGVtZW50LnN0eWxlLmNvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICAgIGlmICh0aGlzLmFsdGVybmF0ZVRleHQpIHtcbiAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl9hbHRlcm5hdGVUZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl90ZXh0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICBUaGUgdGV4dCB0byBkaXNwbGF5IHdoZW4gdGhlIGJ1dHRvbiBpcyBpbiBpdHMgXCJvblwiIHN0YXRlLiBJZiBzZXQsIHRoaXMgcHV0cyB0aGUgYnV0dG9uIGluIFwidG9nZ2xlXCIgbW9kZS5cbiAgQHR5cGUge1N0cmluZ31cbiAgKi9cbiAgZ2V0IGFsdGVybmF0ZVRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsdGVybmF0ZVRleHQ7XG4gIH1cblxuICBzZXQgYWx0ZXJuYXRlVGV4dCh0ZXh0KSB7XG4gICAgaWYgKHRleHQpIHtcbiAgICAgIHRoaXMubW9kZSA9ICd0b2dnbGUnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1vZGUgPSAnYnV0dG9uJztcbiAgICB9XG4gICAgdGhpcy5fYWx0ZXJuYXRlVGV4dCA9IHRleHQ7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIFRoZSB0ZXh0IHRvIGRpc3BsYXkuIChJZiAuYWx0ZXJuYXRlVGV4dCBleGlzdHMsIHRoZW4gdGhpcyAudGV4dCB3aWxsIG9ubHkgYmUgZGlzcGxheWVkIHdoZW4gdGhlIGJ1dHRvbiBpcyBpbiBpdHMgXCJvZmZcIiBzdGF0ZS4pXG4gIEB0eXBlIHtTdHJpbmd9XG4gICovXG4gIGdldCB0ZXh0KCkge1xuICAgIHJldHVybiB0aGlzLl90ZXh0O1xuICB9XG5cbiAgc2V0IHRleHQodGV4dCkge1xuICAgIHRoaXMuX3RleHQgPSB0ZXh0O1xuICAgIHRoaXMuc2l6ZUludGVyZmFjZSgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy90ZXh0YnV0dG9uLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG4vL2xldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgQnV0dG9uID0gcmVxdWlyZSgnLi4vaW50ZXJmYWNlcy9idXR0b24nKTtcblxuLyoqXG4qIFJhZGlvQnV0dG9uXG4qXG4qIEBkZXNjcmlwdGlvbiBBbiBhcnJheSBvZiBidXR0b25zLiBCeSBkZWZhdWx0LCBzZWxlY3Rpbmcgb25lIGJ1dHRvbiB3aWxsIGRlc2VsZWN0IGFsbCBvdGhlciBidXR0b25zLCBidXQgdGhpcyBjYW4gYmUgY3VzdG9taXplZCB1c2luZyB0aGUgQVBJIGJlbG93LlxuKlxuKiBAZGVtbyA8ZGl2IG5leHVzLXVpPVwiUmFkaW9CdXR0b25cIj48L2Rpdj5cbipcbiogQGV4YW1wbGVcbiogdmFyIHJhZGlvYnV0dG9uID0gbmV3IE5leHVzLlJhZGlvQnV0dG9uKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHJhZGlvYnV0dG9uID0gbmV3IE5leHVzLlJhZGlvQnV0dG9uKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMTIwLDI1XSxcbiogICAnbnVtYmVyT2ZCdXR0b25zJzogNCxcbiogICAnYWN0aXZlJzogLTFcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgYW4gPGk+aW50ZWdlcjwvaT4sIHRoZSBpbmRleCBvZiB0aGUgYnV0dG9uIHRoYXQgaXMgY3VycmVudGx5IG9uLiBJZiBubyBidXR0b24gaXMgc2VsZWN0ZWQsIHRoZSB2YWx1ZSB3aWxsIGJlIC0xLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiByYWRpb2J1dHRvbi5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSYWRpb0J1dHRvbiBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzEyMCwyNV0sXG4gICAgICAnbnVtYmVyT2ZCdXR0b25zJzogNCxcbiAgICAgICdhY3RpdmUnOiAtMVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLmJ1dHRvbnMgPSBbXTtcbiAgICB0aGlzLl9udW1iZXJPZkJ1dHRvbnMgPSB0aGlzLnNldHRpbmdzLm51bWJlck9mQnV0dG9ucztcbiAgICB0aGlzLmFjdGl2ZSA9IHRoaXMuc2V0dGluZ3MuYWN0aXZlO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLl9udW1iZXJPZkJ1dHRvbnM7aSsrKSB7XG4gICAgICBsZXQgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuXG4gICAgICBsZXQgYnV0dG9uID0gbmV3IEJ1dHRvbihjb250YWluZXIsIHtcbiAgICAgICAgICBtb2RlOiAndG9nZ2xlJyxcbiAgICAgICAgICBjb21wb25lbnQ6IHRydWUsXG4gICAgICAgIH0sIHRoaXMudXBkYXRlLmJpbmQodGhpcyxpKSk7XG5cbiAgICAgIHRoaXMuYnV0dG9ucy5wdXNoKGJ1dHRvbik7XG4gICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgICB9XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBsZXQgYnV0dG9uV2lkdGggPSB0aGlzLndpZHRoIC8gdGhpcy5fbnVtYmVyT2ZCdXR0b25zO1xuICAgIGxldCBidXR0b25IZWlnaHQgPSB0aGlzLmhlaWdodDtcblxuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuX251bWJlck9mQnV0dG9ucztpKyspIHtcbiAgICAgIHRoaXMuYnV0dG9uc1tpXS5yZXNpemUoYnV0dG9uV2lkdGgsYnV0dG9uSGVpZ2h0KTtcbiAgICB9XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuX251bWJlck9mQnV0dG9ucztpKyspIHtcbiAgICAgIHRoaXMuYnV0dG9uc1tpXS5jb2xvcnMgPSB0aGlzLmNvbG9ycztcbiAgICAgIHRoaXMuYnV0dG9uc1tpXS5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGUoaW5kZXgpIHtcbiAgICBpZiAodGhpcy5idXR0b25zW2luZGV4XS5zdGF0ZSkge1xuICAgICAgdGhpcy5zZWxlY3QoaW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlc2VsZWN0KCk7XG4gICAgfVxuICAvLyAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLmJ1dHRvbnMubGVuZ3RoO2krKykge1xuICAgICAgaWYgKGk9PT10aGlzLmFjdGl2ZSkge1xuICAgICAgICB0aGlzLmJ1dHRvbnNbaV0udHVybk9uKGZhbHNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYnV0dG9uc1tpXS50dXJuT2ZmKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgU2VsZWN0IG9uZSBidXR0b24gYW5kIGRlc2VsZWN0IGFsbCBvdGhlciBidXR0b25zLlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBidXR0b24gdG8gc2VsZWN0XG4gICovXG4gIHNlbGVjdChpbmRleCkge1xuICAgIGlmIChpbmRleD49MCAmJiBpbmRleCA8IHRoaXMuYnV0dG9ucy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuYWN0aXZlID0gaW5kZXg7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5hY3RpdmUpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgRGVzZWxlY3QgYWxsIGJ1dHRvbnMuXG4gICovXG4gIGRlc2VsZWN0KCkge1xuICAgIHRoaXMuYWN0aXZlID0gLTE7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuYWN0aXZlKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgZ2V0IG51bWJlck9mQnV0dG9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5fbnVtYmVyT2ZCdXR0b25zO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBob3cgbWFueSBidXR0b25zIGFyZSBpbiB0aGUgaW50ZXJmYWNlXG4gICAqIEBwYXJhbSAge251bWJlcn0gYnV0dG9ucyBIb3cgbWFueSBidXR0b25zIGFyZSBpbiB0aGUgaW50ZXJmYWNlXG4gICAqL1xuICBzZXQgbnVtYmVyT2ZCdXR0b25zKGJ1dHRvbnMpIHtcbiAgICB0aGlzLl9udW1iZXJPZkJ1dHRvbnMgPSBidXR0b25zO1xuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuYnV0dG9ucy5sZW5ndGg7aSsrKSB7XG4gICAgICB0aGlzLmJ1dHRvbnNbaV0uZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLmJ1dHRvbnMgPSBbXTtcbiAgLy8gIGZvciAobGV0IGk9MDtpPHRoaXMuYnV0dG9ucy5sZW5ndGg7aSsrKSB7XG4gIC8vICAgIHRoaXMuYnV0dG9uc1tpXS5kZXN0cm95KCk7XG4gIC8vICB9XG4gICAgdGhpcy5lbXB0eSgpO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9yYWRpb2J1dHRvbi5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgU3RlcCA9IHJlcXVpcmUoJy4uL21vZGVscy9zdGVwJyk7XG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xuXG4vKipcbiogTnVtYmVyXG4qXG4qIEBkZXNjcmlwdGlvbiBOdW1iZXIgaW50ZXJmYWNlIHdoaWNoIGlzIGNvbnRyb2xsYWJsZSBieSBkcmFnZ2luZyBvciB0eXBpbmcuXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwibnVtYmVyXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgbnVtYmVyID0gbmV3IE5leHVzLk51bWJlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBudW1iZXIgPSBuZXcgTmV4dXMuTnVtYmVyKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbNjAsMzBdLFxuKiAgICd2YWx1ZSc6IDAsXG4qICAgJ21pbic6IDAsXG4qICAgJ21heCc6IDIwMDAwLFxuKiAgICdzdGVwJzogMVxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyB0aGUgbnVtYmVyIHZhbHVlIG9mIHRoZSBpbnRlcmZhY2UuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIG51bWJlci5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qXG4qL1xuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE51bWJlciBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzYwLDMwXSxcbiAgICAgICd2YWx1ZSc6IDAsXG4gICAgICAnbWluJzogMCxcbiAgICAgICdtYXgnOiAyMDAwMCxcbiAgICAgICdzdGVwJzogMVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLl92YWx1ZSA9IG5ldyBTdGVwKHRoaXMuc2V0dGluZ3MubWluLHRoaXMuc2V0dGluZ3MubWF4LHRoaXMuc2V0dGluZ3Muc3RlcCx0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIC8qXG4gICAgRGVmYXVsdDogMi4gSG93IG1hbnkgZGVjaW1hbCBwbGFjZXMgdG8gY2xpcCB0aGUgbnVtYmVyJ3MgdmlzdWFsIHJlbmRlcmluZyB0by4gVGhpcyBkb2VzIG5vdCBhZmZlY3QgbnVtYmVyJ3MgYWN0dWFsIHZhbHVlIG91dHB1dCAtLSBmb3IgdGhhdCwgc2V0IHRoZSBzdGVwIHByb3BlcnR5IHRvIC4wMSwgLjEsIG9yIDEuXG4gICAgQHR5cGUge251bWJlcn1cbiAgICBAZXhhbXBsZSBudW1iZXIuZGVjaW1hbFBsYWNlcyA9IDI7XG4gICAgKi9cbiAgICB0aGlzLmRlY2ltYWxQbGFjZXMgPSAyO1xuICAgIHRoaXMuYWN0dWFsID0gMDtcblxuICAgIHRoaXMubWF4ID0gdGhpcy5fdmFsdWUubWF4O1xuXG4gICAgdGhpcy5taW4gPSB0aGlzLl92YWx1ZS5taW47XG5cbiAgICB0aGlzLnN0ZXAgPSB0aGlzLl92YWx1ZS5zdGVwO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgIHRoaXMuZWxlbWVudC50eXBlID0gJ3RleHQnO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCBmdW5jdGlvbiAoKSB7XG4gIFx0ICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgXHQgIHRoaXMuZWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG4gIFx0ICBpZiAodGhpcy5lbGVtZW50LnZhbHVlICE9PSB0aGlzLnZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBwYXJzZUZsb2F0KHRoaXMuZWxlbWVudC52YWx1ZSk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gIFx0ICB9XG4gIFx0fS5iaW5kKHRoaXMpKTtcblxuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBmdW5jdGlvbiAoZSkge1xuICBcdCAgaWYgKGUud2hpY2ggPCA0OCB8fCBlLndoaWNoID4gNTcpIHtcbiAgXHQgIFx0aWYgKGUud2hpY2ggIT09IDE4OSAmJiBlLndoaWNoICE9PSAxOTAgJiYgZS53aGljaCAhPT0gOCkge1xuICBcdCAgXHRcdGUucHJldmVudERlZmF1bHQoKTtcbiAgXHQgIFx0fVxuICBcdCAgfVxuICBcdCAgaWYgKGUud2hpY2g9PT0xMykge1xuICBcdCAgXHR0aGlzLmVsZW1lbnQuYmx1cigpO1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5lbGVtZW50LnZhbHVlO1xuICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gIFx0ICB9XG4gIFx0fS5iaW5kKHRoaXMpKTtcblxuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLl9taW5EaW1lbnNpb24gPSBNYXRoLm1pbih0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcblxuICAgIGxldCBzdHlsZXMgPSAnd2lkdGg6ICcgKyB0aGlzLndpZHRoICsgJ3B4Oyc7XG4gICAgc3R5bGVzICs9ICdoZWlnaHQ6ICcgKyB0aGlzLmhlaWdodCArICdweDsnO1xuICAgIHN0eWxlcyArPSAnYmFja2dyb3VuZC1jb2xvcjogI2U3ZTdlNzsnO1xuICAgIHN0eWxlcyArPSAnY29sb3I6ICMzMzM7JztcbiAgICBzdHlsZXMgKz0gJ2ZvbnQtZmFtaWx5OiBhcmlhbDsnO1xuICAgIHN0eWxlcyArPSAnZm9udC13ZWlnaHQ6IDUwMDsnO1xuICAgIHN0eWxlcyArPSAnZm9udC1zaXplOicgKyB0aGlzLl9taW5EaW1lbnNpb24vMiArICdweDsnO1xuICAvLyAgc3R5bGVzICs9ICdoaWdobGlnaHQ6ICNkMTg7JztcbiAgICBzdHlsZXMgKz0gJ2JvcmRlcjogbm9uZTsnO1xuICAgIHN0eWxlcyArPSAnb3V0bGluZTogbm9uZTsnO1xuICAgIHN0eWxlcyArPSAncGFkZGluZzogJyt0aGlzLl9taW5EaW1lbnNpb24vNCsncHggJyt0aGlzLl9taW5EaW1lbnNpb24vNCsncHg7JztcbiAgICBzdHlsZXMgKz0gJ2JveC1zaXppbmc6IGJvcmRlci1ib3g7JztcbiAgICBzdHlsZXMgKz0gJ3VzZXJTZWxlY3Q6IHRleHQ7JztcbiAgICBzdHlsZXMgKz0gJ21velVzZXJTZWxlY3Q6IHRleHQ7JztcbiAgICBzdHlsZXMgKz0gJ3dlYmtpdFVzZXJTZWxlY3Q6IHRleHQ7JztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY3NzVGV4dCArPSBzdHlsZXM7XG5cbiAgICAvLyB0byBhZGQgZXZlbnR1YWxseVxuICAgIC8vIHZhciBjc3MgPSAnIycrdGhpcy5lbGVtZW50SUQrJzo6c2VsZWN0aW9ueyBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudCB9JztcblxuICAgIHRoaXMuZWxlbWVudC52YWx1ZSA9IHRoaXMudmFsdWU7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY29sb3IgPSB0aGlzLmNvbG9ycy5kYXJrO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuXG4gICAgdGhpcy5lbGVtZW50LnZhbHVlID0gbWF0aC5wcnVuZSh0aGlzLnZhbHVlLHRoaXMuZGVjaW1hbFBsYWNlcyk7XG5cbiAgfVxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMuaGFzTW92ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmVsZW1lbnQucmVhZE9ubHkgPSB0cnVlO1xuXHQgIHRoaXMuYWN0dWFsID0gdGhpcy52YWx1ZTtcbiAgICB0aGlzLmluaXRpYWwgPSB7IHk6IHRoaXMubW91c2UueSB9O1xuICAgIHRoaXMuY2hhbmdlRmFjdG9yID0gbWF0aC5pbnZlcnQoIHRoaXMubW91c2UueCAvIHRoaXMud2lkdGggKTtcbiAgICBjb25zb2xlLmxvZyh0aGlzLmNoYW5nZUZhY3Rvcik7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIHRoaXMuaGFzTW92ZWQgPSB0cnVlO1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcblxuICAgICAgbGV0IG5ld3ZhbHVlID0gdGhpcy5hY3R1YWwgLSAodGhpcy5tb3VzZS55IC0gdGhpcy5pbml0aWFsLnkpICogKCBtYXRoLmNsaXAoIHRoaXMubWF4LXRoaXMubWluLCAwLCAxMDAwICkgLyAyMDAgKSAqIE1hdGgucG93KHRoaXMuY2hhbmdlRmFjdG9yLDIpO1xuICAgICAgdGhpcy52YWx1ZSA9IG5ld3ZhbHVlO1xuXG4gIFx0XHR0aGlzLnJlbmRlcigpO1xuICAgICAgaWYgKHRoaXMuX3ZhbHVlLmNoYW5nZWQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuICAgICAgfVxuXG4gIFx0fVxuICB9XG5cbiAgcmVsZWFzZSgpIHtcbiAgICBpZiAoIXRoaXMuaGFzTW92ZWQpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5yZWFkT25seSA9IGZhbHNlO1xuICBcdFx0dGhpcy5lbGVtZW50LmZvY3VzKCk7XG4gIFx0XHR0aGlzLmVsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UoMCwgdGhpcy5lbGVtZW50LnZhbHVlLmxlbmd0aCk7XG4gIFx0XHR0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuICBcdFx0dGhpcy5lbGVtZW50LnN0eWxlLmNvbG9yID0gdGhpcy5jb2xvcnMubGlnaHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRvY3VtZW50LmJvZHkuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgQ29ubmVjdCB0aGlzIG51bWJlciBpbnRlcmZhY2UgdG8gYSBkaWFsIG9yIHNsaWRlclxuICBAcGFyYW0ge0ludGVyZmFjZX0gZWxlbWVudCBFbGVtZW50IHRvIGNvbm5lY3QgdG8uXG4gIEBleGFtcGxlIG51bWJlci5saW5rKHNsaWRlcilcbiAgKi9cbiAgbGluayhkZXN0aW5hdGlvbikge1xuICAgIHRoaXMubWluID0gZGVzdGluYXRpb24ubWluO1xuICAgIHRoaXMubWF4ID0gZGVzdGluYXRpb24ubWF4O1xuICAgIHRoaXMuc3RlcCA9IGRlc3RpbmF0aW9uLnN0ZXA7XG4gICAgZGVzdGluYXRpb24ub24oJ2NoYW5nZScsKHYpID0+IHtcbiAgICAgIHRoaXMucGFzc2l2ZVVwZGF0ZSh2KTtcbiAgICB9KTtcbiAgICB0aGlzLm9uKCdjaGFuZ2UnLCh2KSA9PiB7XG4gICAgICBkZXN0aW5hdGlvbi52YWx1ZSA9IHY7XG4gICAgfSk7XG4gICAgdGhpcy52YWx1ZSA9IGRlc3RpbmF0aW9uLnZhbHVlO1xuICAvKiAgcmV0dXJuIHtcbiAgICAgIGxpc3RlbmVyMTogbGlzdGVuZXIxLFxuICAgICAgbGlzdGVuZXIyOiBsaXN0ZW5lcjIsXG4gICAgICBkZXN0cm95OiAoKSA9PiB7XG4gICAgICAgIGxpc3RlbmVyMS5yZW1vdmUoKSAob3Igc2ltaWxhcilcbiAgICAgICAgbGlzdGVuZXIyLnJlbW92ZSgpIChvciBzaW1pbGFyKVxuICAgICAgfVxuICAgIH0gKi9cbiAgfVxuXG4gIHBhc3NpdmVVcGRhdGUodikge1xuICAgIHRoaXMuX3ZhbHVlLnVwZGF0ZSh2KTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqXG4gIFRoZSBpbnRlcmZhY2UncyBjdXJyZW50IHZhbHVlLiBJZiBzZXQgbWFudWFsbHksIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgbnVtYmVyLnZhbHVlID0gMTA7XG4gICovXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHYpIHtcbiAgICB0aGlzLl92YWx1ZS51cGRhdGUodik7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKipcbiAgTG93ZXIgbGltaXQgb2YgdGhlIG51bWJlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBudW1iZXIubWluID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1pbigpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWluO1xuICB9XG4gIHNldCBtaW4odikge1xuICAgIHRoaXMuX3ZhbHVlLm1pbiA9IHY7XG4gIH1cblxuICAvKipcbiAgVXBwZXIgbGltaXQgb2YgdGhlIG51bWJlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBudW1iZXIubWF4ID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWF4O1xuICB9XG4gIHNldCBtYXgodikge1xuICAgIHRoaXMuX3ZhbHVlLm1heCA9IHY7XG4gIH1cblxuICAvKipcbiAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBudW1iZXIncyB2YWx1ZSBjaGFuZ2VzIGJ5LlxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBudW1iZXIuc3RlcCA9IDU7XG4gICovXG4gIGdldCBzdGVwKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5zdGVwO1xuICB9XG4gIHNldCBzdGVwKHYpIHtcbiAgICB0aGlzLl92YWx1ZS5zdGVwID0gdjtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9udW1iZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xuXG4vKipcbiogU2VsZWN0XG4qXG4qIEBkZXNjcmlwdGlvbiBEcm9wZG93biBtZW51XG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwic2VsZWN0XCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc2VsZWN0ID0gbmV3IE5leHVzLlNlbGVjdCgnI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBzZWxlY3QgPSBuZXcgTmV4dXMuU2VsZWN0KCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMTAwLDMwXSxcbiogICAnb3B0aW9ucyc6IFsnZGVmYXVsdCcsJ29wdGlvbnMnXVxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIGNoYW5nZVxuKiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgdGV4dCB2YWx1ZSBvZiB0aGUgc2VsZWN0ZWQgb3B0aW9uLCBhcyB3ZWxsIGFzIHRoZSBudW1lcmljIGluZGV4IG9mIHRoZSBzZWxlY3Rpb24uXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIHNlbGVjdC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qXG4qL1xuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNlbGVjdCBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICAnc2l6ZSc6IFsxMDAsMzBdLFxuICAgICAgICdvcHRpb25zJzogWydkZWZhdWx0Jywnb3B0aW9ucyddXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSAtMTtcbiAgICB0aGlzLl92YWx1ZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5fb3B0aW9ucyA9IHRoaXMuc2V0dGluZ3Mub3B0aW9ucztcblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2VsZWN0Jyk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmZvbnRTaXplID0gdGhpcy5oZWlnaHQvMisncHgnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5vdXRsaW5lID0gJ25vbmUnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5oaWdobGlnaHQgPSAnbm9uZSc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLndpZHRoID0gdGhpcy53aWR0aCsncHgnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmhlaWdodCsncHgnO1xuXG4gICAgdGhpcy5ib3VuZFJlbmRlciA9IHRoaXMucmVuZGVyLmJpbmQodGhpcyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5ib3VuZFJlbmRlcik7XG5cbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXG4gIH1cblxuICBhdHRhY2hMaXN0ZW5lcnMoKSB7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5kZWZpbmVPcHRpb25zKCk7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5maWxsO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmJvcmRlciA9ICdzb2xpZCAwcHggJyt0aGlzLmNvbG9ycy5tZWRpdW1MaWdodDtcbiAgfVxuXG4gIHJlbmRlcigpIHtcblxuICAgIHRoaXMuX3ZhbHVlID0gdGhpcy5lbGVtZW50Lm9wdGlvbnNbdGhpcy5lbGVtZW50LnNlbGVjdGVkSW5kZXhdLnRleHQ7XG4gICAgdGhpcy5fc2VsZWN0ZWRJbmRleCA9IHRoaXMuZWxlbWVudC5zZWxlY3RlZEluZGV4O1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICB2YWx1ZTogdGhpcy5fdmFsdWUsXG4gICAgICBpbmRleDogdGhpcy5fc2VsZWN0ZWRJbmRleFxuICAgIH0pO1xuXG4gIH1cblxuICBjbGljaygpIHtcblxuICB9XG5cbiAgbW92ZSgpIHtcblxuICB9XG5cbiAgcmVsZWFzZSgpIHtcblxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgbGlzdCBvZiBvcHRpb25zLiBUaGlzIHJlbW92ZXMgYWxsIGV4aXN0aW5nIG9wdGlvbnMgYW5kIGNyZWF0ZXMgYSBuZXcgbGlzdCBvZiBvcHRpb25zLlxuICAgKiBAcGFyYW0gIHthcnJheX0gb3B0aW9ucyBOZXcgYXJyYXkgb2Ygb3B0aW9uc1xuICAgKi9cblxuICBkZWZpbmVPcHRpb25zKG9wdGlvbnMpIHtcblxuICAvKiAgZnVuY3Rpb24gcmVtb3ZlT3B0aW9ucyhzZWxlY3Rib3gpXG4gICAge1xuICAgICAgICB2YXIgaTtcbiAgICAgICAgZm9yKGkgPSBzZWxlY3Rib3gub3B0aW9ucy5sZW5ndGggLSAxIDsgaSA+PSAwIDsgaS0tKVxuICAgICAgICB7XG4gICAgICAgICAgICBzZWxlY3Rib3gucmVtb3ZlKGkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vdXNpbmcgdGhlIGZ1bmN0aW9uOlxuICAgIHJlbW92ZU9wdGlvbnMoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJteVNlbGVjdE9iamVjdFwiKSk7ICovXG5cblxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcbiAgICB9XG5cbiAgICBmb3IobGV0IGk9dGhpcy5lbGVtZW50Lm9wdGlvbnMubGVuZ3RoLTE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB0aGlzLmVsZW1lbnQucmVtb3ZlKGkpO1xuICAgIH1cblxuICAgIGZvcihsZXQgaT0wO2k8dGhpcy5fb3B0aW9ucy5sZW5ndGg7aSsrKSB7XG4gICAgICB0aGlzLmVsZW1lbnQub3B0aW9ucy5hZGQobmV3IE9wdGlvbih0aGlzLl9vcHRpb25zW2ldLCBpKSk7XG4gICAgfVxuXG4gIH1cblxuXG4gIC8qKlxuICBUaGUgdGV4dCBvZiB0aGUgb3B0aW9uIHRoYXQgaXMgY3VycmVudGx5IHNlbGVjdGVkLiBJZiBzZXQsIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge1N0cmluZ31cbiAgQGV4YW1wbGUgc2VsZWN0LnZhbHVlID0gXCJzYXd0b290aFwiO1xuICAqL1xuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICB9XG4gIHNldCB2YWx1ZSh2KSB7XG4gICAgdGhpcy5fdmFsdWUgPSB2O1xuICAgIGZvcihsZXQgaT0wO2k8dGhpcy5lbGVtZW50Lm9wdGlvbnMubGVuZ3RoO2krKykge1xuICAgICAgaWYgKHYgPT09IHRoaXMuZWxlbWVudC5vcHRpb25zW2ldLnRleHQpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgVGhlIG51bWVyaWMgaW5kZXggb2YgdGhlIG9wdGlvbiB0aGF0IGlzIGN1cnJlbnRseSBzZWxlY3RlZC4gSWYgc2V0LCB3aWxsIHVwZGF0ZSB0aGUgaW50ZXJmYWNlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIHNlbGVjdC5zZWxlY3RlZEluZGV4ID0gMjtcbiAgKi9cbiAgZ2V0IHNlbGVjdGVkSW5kZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkSW5kZXg7XG4gIH1cbiAgc2V0IHNlbGVjdGVkSW5kZXgodikge1xuICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSB2O1xuICAgIHRoaXMuZWxlbWVudC5zZWxlY3RlZEluZGV4ID0gdjtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5ib3VuZFJlbmRlcik7XG4gIH1cblxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9zZWxlY3QuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IG1hdGggPSByZXF1aXJlKCcuLi91dGlsL21hdGgnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbi8qKlxuKiBEaWFsXG4qXG4qXG4qIEBkZXNjcmlwdGlvbiBEaWFsIHdpdGggcmFkaWFsIG9yIGxpbmVhciBpbnRlcmFjdGlvbi5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJkaWFsXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgZGlhbCA9IG5ldyBOZXh1cy5EaWFsKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIGRpYWwgPSBuZXcgTmV4dXMuRGlhbCgnI3RhcmdldCcse1xuKiAgICdzaXplJzogWzc1LDc1XSxcbiogICAnaW50ZXJhY3Rpb24nOiAncmFkaWFsJywgLy8gXCJyYWRpYWxcIiwgXCJ2ZXJ0aWNhbFwiLCBvciBcImhvcml6b250YWxcIlxuKiAgICdtb2RlJzogJ3JlbGF0aXZlJywgLy8gXCJhYnNvbHV0ZVwiIG9yIFwicmVsYXRpdmVcIlxuKiAgICdtaW4nOiAwLFxuKiAgICdtYXgnOiAxLFxuKiAgICdzdGVwJzogMCxcbiogICAndmFsdWUnOiAwXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIFRoZSBldmVudCBkYXRhIGlzIHRoZSBudW1iZXIgdmFsdWUgb2YgdGhlIGludGVyZmFjZS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogZGlhbC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qIEB0dXRvcmlhbFxuKiBEaWFsXG4qIHlnR014cVxuKlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGlhbCBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnbWluJywnbWF4JywndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzc1LDc1XSxcbiAgICAgICdpbnRlcmFjdGlvbic6ICdyYWRpYWwnLCAvLyByYWRpYWwsIHZlcnRpY2FsLCBob3Jpem9udGFsXG4gICAgICAnbW9kZSc6ICdyZWxhdGl2ZScsIC8vIGFic29sdXRlLCByZWxhdGl2ZVxuICAgICAgJ21pbic6IDAsXG4gICAgICAnbWF4JzogMSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDBcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvbiA9IHRoaXMuc2V0dGluZ3MuaW50ZXJhY3Rpb247XG5cbiAgICB0aGlzLl92YWx1ZSA9IG5ldyBTdGVwKHRoaXMuc2V0dGluZ3MubWluLCB0aGlzLnNldHRpbmdzLm1heCwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIHRoaXMucG9zaXRpb24gPSBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMuc2V0dGluZ3MubW9kZSx0aGlzLmludGVyYWN0aW9uLFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG5cbiAgICB0aGlzLmluaXQoKTtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblxuICAgIHRoaXMucG9zaXRpb24udmFsdWUgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXG4gICAgdGhpcy5wcmV2aW91c0FuZ2xlID0gZmFsc2U7XG5cbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5iYWNrZ3JvdW5kID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG4gICAgdGhpcy5zY3JldyA9IHN2Zy5jcmVhdGUoJ2NpcmNsZScpO1xuICAgIHRoaXMuaGFuZGxlID0gc3ZnLmNyZWF0ZSgncGF0aCcpO1xuICAgIHRoaXMuaGFuZGxlMiA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmhhbmRsZUZpbGwgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG4gICAgdGhpcy5oYW5kbGUyRmlsbCA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmhhbmRsZUxpbmUgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYWNrZ3JvdW5kKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5oYW5kbGUpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZTIpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZUZpbGwpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZTJGaWxsKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5oYW5kbGVMaW5lKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5zY3Jldyk7XG5cbiAgfVxuXG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcblxuICAgIHRoaXMucG9zaXRpb24ucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG5cbiAgICBsZXQgY2VudGVyID0ge1xuICAgICAgeDogdGhpcy53aWR0aC8yLFxuICAgICAgeTogdGhpcy5oZWlnaHQvMlxuICAgIH07XG5cbiAgICBsZXQgZGlhbWV0ZXIgPSBNYXRoLm1pbih0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcblxuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ2N4JywgY2VudGVyLngpO1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ2N5JywgY2VudGVyLnkpO1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ3InLCBkaWFtZXRlci8yLWRpYW1ldGVyLzQwKTtcblxuICAgIHRoaXMuc2NyZXcuc2V0QXR0cmlidXRlKCdjeCcsIGNlbnRlci54KTtcbiAgICB0aGlzLnNjcmV3LnNldEF0dHJpYnV0ZSgnY3knLCBjZW50ZXIueSk7XG4gICAgdGhpcy5zY3Jldy5zZXRBdHRyaWJ1dGUoJ3InLCBkaWFtZXRlci8xMik7XG5cbiAgICBsZXQgdmFsdWUgPSB0aGlzLnZhbHVlO1xuXG4gICAgbGV0IGhhbmRsZVBvaW50cyA9IHtcbiAgICAgIHN0YXJ0OiBNYXRoLlBJKjEuNSxcbiAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHZhbHVlLDAsMC41LE1hdGguUEkqMS41LE1hdGguUEkqMC41KSAsIE1hdGguUEkqMC41LCBNYXRoLlBJKjEuNSApXG4gICAgfTtcbiAgICBsZXQgaGFuZGxlMlBvaW50cyA9IHtcbiAgICAgIHN0YXJ0OiBNYXRoLlBJKjIuNSxcbiAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHZhbHVlLDAuNSwxLE1hdGguUEkqMi41LE1hdGguUEkqMS41KSAsIE1hdGguUEkqMS41LCBNYXRoLlBJKjIuNSApXG4gICAgfTtcblxuICAgIGxldCBoYW5kbGVQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZVBvaW50cy5zdGFydCwgaGFuZGxlUG9pbnRzLmVuZCk7XG4gICAgbGV0IGhhbmRsZTJQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgIHRoaXMuaGFuZGxlLnNldEF0dHJpYnV0ZSgnZCcsaGFuZGxlUGF0aCk7XG4gICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBkaWFtZXRlci8yMCk7XG4gICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcblxuICAgIHRoaXMuaGFuZGxlMi5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZTJQYXRoKTtcbiAgICB0aGlzLmhhbmRsZTIuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBkaWFtZXRlci8yMCk7XG4gICAgdGhpcy5oYW5kbGUyLnNldEF0dHJpYnV0ZSgnZmlsbCcsICdub25lJyk7XG5cbiAgICBoYW5kbGVQYXRoICs9ICcgTCAnK2NlbnRlci54KycgJytjZW50ZXIueTtcblxuICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZVBhdGgpO1xuICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwtb3BhY2l0eScsICcwLjMnKTtcblxuICAgIGhhbmRsZTJQYXRoICs9ICcgTCAnK2NlbnRlci54KycgJytjZW50ZXIueTtcblxuICAgIHRoaXMuaGFuZGxlMkZpbGwuc2V0QXR0cmlidXRlKCdkJyxoYW5kbGUyUGF0aCk7XG4gICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwtb3BhY2l0eScsICcwLjMnKTtcblxuICAgIGxldCBhcmNFbmRpbmdBO1xuICAgIGlmICh2YWx1ZSA8IDAuNSkge1xuICAgICAgYXJjRW5kaW5nQSA9IGhhbmRsZVBvaW50cy5lbmQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFyY0VuZGluZ0EgPSBoYW5kbGUyUG9pbnRzLmVuZDtcbiAgICB9XG5cbiAgICBsZXQgYXJjRW5kaW5nWCA9IGNlbnRlci54ICsgTWF0aC5jb3MoYXJjRW5kaW5nQSkgKiAoZGlhbWV0ZXIvMik7XG4gICAgbGV0IGFyY0VuZGluZ1kgPSBjZW50ZXIueSArIE1hdGguc2luKGFyY0VuZGluZ0EpICogKGRpYW1ldGVyLzIpICogLTE7XG5cbiAgICB0aGlzLmhhbmRsZUxpbmUuc2V0QXR0cmlidXRlKCdkJywnTSAnK2NlbnRlci54KycgJytjZW50ZXIueSsnIEwgJythcmNFbmRpbmdYKycgJythcmNFbmRpbmdZKTtcbiAgICB0aGlzLmhhbmRsZUxpbmUuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBkaWFtZXRlci8yMCk7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5maWxsKTtcbiAgICB0aGlzLnNjcmV3LnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKCdzdHJva2UnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMuaGFuZGxlMi5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5oYW5kbGVGaWxsLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMuaGFuZGxlTGluZS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXG4gICAgbGV0IGNlbnRlciA9IHtcbiAgICAgIHg6IHRoaXMud2lkdGgvMixcbiAgICAgIHk6IHRoaXMuaGVpZ2h0LzJcbiAgICB9O1xuXG4gICAgbGV0IGRpYW1ldGVyID0gTWF0aC5taW4odGhpcy53aWR0aCx0aGlzLmhlaWdodCk7XG5cbiAgICBsZXQgaGFuZGxlUG9pbnRzID0ge1xuICAgICAgc3RhcnQ6IE1hdGguUEkqMS41LFxuICAgICAgZW5kOiBtYXRoLmNsaXAoIG1hdGguc2NhbGUodmFsdWUsMCwwLjUsTWF0aC5QSSoxLjUsTWF0aC5QSSowLjUpICwgTWF0aC5QSSowLjUsIE1hdGguUEkqMS41IClcbiAgICB9O1xuICAgIGxldCBoYW5kbGUyUG9pbnRzID0ge1xuICAgICAgc3RhcnQ6IE1hdGguUEkgKjIuNSxcbiAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHZhbHVlLDAuNSwxLE1hdGguUEkqMi41LE1hdGguUEkqMS41KSAsIE1hdGguUEkqMS41LCBNYXRoLlBJKjIuNSApXG4gICAgfTtcblxuICAgIGxldCBoYW5kbGVQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZVBvaW50cy5zdGFydCwgaGFuZGxlUG9pbnRzLmVuZCk7XG4gICAgbGV0IGhhbmRsZTJQYXRoID0gc3ZnLmFyYyhjZW50ZXIueCwgY2VudGVyLnksIGRpYW1ldGVyLzItZGlhbWV0ZXIvNDAsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgIHRoaXMuaGFuZGxlLnNldEF0dHJpYnV0ZSgnZCcsaGFuZGxlUGF0aCk7XG4gICAgdGhpcy5oYW5kbGUyLnNldEF0dHJpYnV0ZSgnZCcsaGFuZGxlMlBhdGgpO1xuXG5cbiAgICBoYW5kbGVQYXRoICs9ICcgTCAnK2NlbnRlci54KycgJytjZW50ZXIueTtcblxuICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZVBhdGgpO1xuXG4gICAgaGFuZGxlMlBhdGggKz0gJyBMICcrY2VudGVyLngrJyAnK2NlbnRlci55O1xuXG4gICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoJ2QnLGhhbmRsZTJQYXRoKTtcblxuICAgIGxldCBhcmNFbmRpbmdBO1xuICAgIGlmICh2YWx1ZSA8PSAwLjUpIHtcbiAgICAgIGFyY0VuZGluZ0EgPSBoYW5kbGVQb2ludHMuZW5kO1xuICAgIH0gZWxzZSB7XG4gICAgICBhcmNFbmRpbmdBID0gaGFuZGxlMlBvaW50cy5lbmQ7XG4gICAgfVxuXG4gICAgbGV0IGFyY0VuZGluZ1ggPSBjZW50ZXIueCArIE1hdGguY29zKGFyY0VuZGluZ0EpICogKGRpYW1ldGVyLzIpO1xuICAgIGxldCBhcmNFbmRpbmdZID0gY2VudGVyLnkgKyBNYXRoLnNpbihhcmNFbmRpbmdBKSAqIChkaWFtZXRlci8yKSAqIC0xO1xuXG4gICAgdGhpcy5oYW5kbGVMaW5lLnNldEF0dHJpYnV0ZSgnZCcsJ00gJytjZW50ZXIueCsnICcrY2VudGVyLnkrJyBMICcrYXJjRW5kaW5nWCsnICcrYXJjRW5kaW5nWSk7XG5cbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgaWYgKHRoaXMubW9kZT09PSdyZWxhdGl2ZScpIHtcbiAgICAgIHRoaXMucHJldmlvdXNBbmdsZSA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5tb3ZlKCk7XG4gICB9XG5cbiAgbW92ZSgpIHtcbiAgICBpZiAodGhpcy5jbGlja2VkKSB7XG5cbiAgICAgIHRoaXMucG9zaXRpb24udXBkYXRlKHRoaXMubW91c2UpO1xuXG4gICAgICBsZXQgYW5nbGUgPSB0aGlzLnBvc2l0aW9uLnZhbHVlKk1hdGguUEkqMjtcblxuICAgICAgaWYgKGFuZ2xlIDwgMCApIHsgYW5nbGUgKz0gKE1hdGguUEkqMik7IH1cblxuICAgICAgaWYgKHRoaXMubW9kZSA9PT0gJ3JlbGF0aXZlJykge1xuICAgICAgICBpZiAodGhpcy5wcmV2aW91c0FuZ2xlICE9PSBmYWxzZSAmJiBNYXRoLmFicyh0aGlzLnByZXZpb3VzQW5nbGUgLSBhbmdsZSkgPiAyKSB7XG4gICAgICAgICAgaWYgKHRoaXMucHJldmlvdXNBbmdsZSA+IDMpIHtcbiAgICAgICAgICAgIGFuZ2xlID0gTWF0aC5QSSoyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbmdsZSA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IC8qIGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5wcmV2aW91c0FuZ2xlICE9PSBmYWxzZSAmJiBNYXRoLmFicyh0aGlzLnByZXZpb3VzQW5nbGUgLSBhbmdsZSkgPiAyKSB7XG4gICAgICAgICAgaWYgKHRoaXMucHJldmlvdXNBbmdsZSA+IDMpIHtcbiAgICAgICAgICAgIGFuZ2xlID0gTWF0aC5QSSoyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbmdsZSA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9ICovXG4gICAgICB0aGlzLnByZXZpb3VzQW5nbGUgPSBhbmdsZTtcblxuICAgICAgbGV0IHJlYWxWYWx1ZSA9IGFuZ2xlIC8gKE1hdGguUEkqMik7XG5cbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS51cGRhdGVOb3JtYWwoIHJlYWxWYWx1ZSApO1xuXG4gICAgICBpZiAodGhpcy5tb2RlID09PSAncmVsYXRpdmUnKSB7XG4gICAgICAgIHRoaXMucG9zaXRpb24udmFsdWUgPSByZWFsVmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLl92YWx1ZS52YWx1ZSk7XG5cbiAgICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICB9XG4gIH1cblxuICByZWxlYXNlKCkge1xuICB9XG5cbiAgLypcbiAgRGlhbCdzIHZhbHVlLiBXaGVuIHNldCwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGFkanVzdCB0byBmaXQgbWluL21heC9zdGVwIHNldHRpbmdzIG9mIHRoZSBpbnRlcmZhY2UuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIGRpYWwudmFsdWUgPSAxMDtcblxuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuICB9XG5cbiAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgdGhpcy5fdmFsdWUudXBkYXRlKHZhbHVlKTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuKi9cblxuICAgIC8qKlxuICAgIERpYWwncyB2YWx1ZS4gV2hlbiBzZXQsIGl0IHdpbGwgYXV0b21hdGljYWxseSBiZSBhZGp1c3QgdG8gZml0IG1pbi9tYXgvc3RlcCBzZXR0aW5ncyBvZiB0aGUgaW50ZXJmYWNlLlxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC52YWx1ZSA9IDEwO1xuICAgICovXG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuICAgIH1cbiAgICBzZXQgdmFsdWUodikge1xuICAgICAgdGhpcy5fdmFsdWUudXBkYXRlKHYpO1xuICAgICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5fdmFsdWUudmFsdWUpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICBMb3dlciBsaW1pdCBvZiB0aGUgZGlhbCdzIG91dHB1dCByYW5nZVxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC5taW4gPSAxMDAwO1xuICAgICovXG4gICAgZ2V0IG1pbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5taW47XG4gICAgfVxuICAgIHNldCBtaW4odikge1xuICAgICAgdGhpcy5fdmFsdWUubWluID0gdjtcbiAgICB9XG5cbiAgICAvKipcbiAgICBVcHBlciBsaW1pdCBvZiB0aGUgZGlhbCdzIG91dHB1dCByYW5nZVxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC5tYXggPSAxMDAwO1xuICAgICovXG4gICAgZ2V0IG1heCgpIHtcbiAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5tYXg7XG4gICAgfVxuICAgIHNldCBtYXgodikge1xuICAgICAgdGhpcy5fdmFsdWUubWF4ID0gdjtcbiAgICB9XG5cbiAgICAvKipcbiAgICBUaGUgaW5jcmVtZW50IHRoYXQgdGhlIGRpYWwncyB2YWx1ZSBjaGFuZ2VzIGJ5LlxuICAgIEB0eXBlIHtudW1iZXJ9XG4gICAgQGV4YW1wbGUgZGlhbC5zdGVwID0gNTtcbiAgICAqL1xuICAgIGdldCBzdGVwKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnN0ZXA7XG4gICAgfVxuICAgIHNldCBzdGVwKHYpIHtcbiAgICAgIHRoaXMuX3ZhbHVlLnN0ZXAgPSB2O1xuICAgIH1cblxuICAgIC8qKlxuICAgIEFic29sdXRlIG1vZGUgKGRpYWwncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJyZWxhdGl2ZVwiLlxuICAgIEB0eXBlIHtzdHJpbmd9XG4gICAgQGV4YW1wbGUgZGlhbC5tb2RlID0gXCJyZWxhdGl2ZVwiO1xuICAgICovXG4gICAgZ2V0IG1vZGUoKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi5tb2RlO1xuICAgIH1cbiAgICBzZXQgbW9kZSh2KSB7XG4gICAgICB0aGlzLnBvc2l0aW9uLm1vZGUgPSB2O1xuICAgIH1cblxuXG4gIC8qKlxuICBOb3JtYWxpemVkIHZhbHVlIG9mIHRoZSBkaWFsLlxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBkaWFsLm5vcm1hbGl6ZWQgPSAwLjU7XG4gICovXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuICB9XG5cbiAgc2V0IG5vcm1hbGl6ZWQodikge1xuICAgIHRoaXMuX3ZhbHVlLnVwZGF0ZU5vcm1hbCh2KTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvZGlhbC5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcbmxldCBCdXR0b25UZW1wbGF0ZSA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvYnV0dG9udGVtcGxhdGUnKTtcbmxldCB0b3VjaCA9IHJlcXVpcmUoJy4uL3V0aWwvdG91Y2gnKTtcblxuY2xhc3MgUGlhbm9LZXkgZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnLCdub3RlJywnY29sb3InXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzgwLDgwXSxcbiAgICAgICd0YXJnZXQnOiBmYWxzZSxcbiAgICAgICdtb2RlJzogJ2J1dHRvbicsXG4gICAgICAndmFsdWUnOiAwXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMubm90ZSA9IHRoaXMuc2V0dGluZ3Mubm90ZTtcbiAgICB0aGlzLmNvbG9yID0gdGhpcy5zZXR0aW5ncy5jb2xvcjtcblxuICAgIHRoaXMuY29sb3JzID0ge1xuICAgICAgJ3cnOiAnI2ZmZicsXG4gICAgICAnYic6ICcjNjY2JyxcbiAgICB9O1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5wYWQgPSBzdmcuY3JlYXRlKCdyZWN0Jyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wYWQpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXG4gICAgLyogZXZlbnRzICovXG5cbiAgICBpZiAoIXRvdWNoLmV4aXN0cykge1xuXG4gICAgICB0aGlzLmNsaWNrID0gKCkgPT4ge1xuICAgICAgLy8gIGNvbnNvbGUubG9nKCdjbGljaycpO1xuICAgICAgICB0aGlzLnBpYW5vLmludGVyYWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5waWFuby5wYWludGJydXNoID0gIXRoaXMuc3RhdGU7XG4gICAgICAgIHRoaXMuZG93bih0aGlzLnBpYW5vLnBhaW50YnJ1c2gpO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5waWFuby5pbnRlcmFjdGluZykge1xuICAgICAgLy8gICAgY29uc29sZS5sb2coJ21vdXNlb3ZlcicpO1xuICAgICAgICAgIHRoaXMuZG93bih0aGlzLnBpYW5vLnBhaW50YnJ1c2gpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuXG4gICAgICB0aGlzLm1vdmUgPSAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnBpYW5vLmludGVyYWN0aW5nKSB7XG4gICAgICAgIC8vICBjb25zb2xlLmxvZygnbW92ZScpO1xuICAgICAgICAgIHRoaXMuYmVuZCgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG5cbiAgICAgIHRoaXMucmVsZWFzZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5waWFuby5pbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgICAgLy8gIGNvbnNvbGUubG9nKCdyZWxlYXNlJyk7XG4gICAgICAvLyAgdGhpcy51cCgpO1xuICAgICAgfTtcbiAgICAgIHRoaXMucGFkLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnBpYW5vLmludGVyYWN0aW5nKSB7XG4gICAgICAgIC8vICBjb25zb2xlLmxvZygnbW91c2V1cCcpO1xuICAgICAgICAgIHRoaXMudXAoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLnBhZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMucGlhbm8uaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgLy8gIGNvbnNvbGUubG9nKCdtb3VzZW91dCcpO1xuICAgICAgICAgIHRoaXMudXAoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICB9XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICAgICAgLy9sZXQgcmFkaXVzID0gTWF0aC5taW4odGhpcy53aWR0aCx0aGlzLmhlaWdodCkgLyA1O1xuICAgICAgICBsZXQgcmFkaXVzID0gMDtcblxuICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3gnLDAuNSk7XG4gICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgneScsMC41KTtcbiAgICAgICAgaWYgKHRoaXMud2lkdGggPiAyKSB7XG4gICAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMud2lkdGggLSAxKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgdGhpcy53aWR0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaGVpZ2h0ID4gMikge1xuICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgncngnLCByYWRpdXMpO1xuICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3J5JywgcmFkaXVzKTtcblxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5zdGF0ZSkge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnNbdGhpcy5jb2xvcl0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIH1cbiAgfVxuXG59XG5cbi8qKlxuKiBQaWFub1xuKlxuKiBAZGVzY3JpcHRpb24gUGlhbm8ga2V5Ym9hcmQgaW50ZXJmYWNlXG4qXG4qIEBkZW1vIDxkaXYgbmV4dXMtdWk9XCJwaWFub1wiPjwvZGl2PlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcGlhbm8gPSBuZXcgTmV4dXMuUGlhbm8oJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgcGlhbm8gPSBuZXcgTmV4dXMuUGlhbm8oJyN0YXJnZXQnLHtcbiogICAgICdzaXplJzogWzUwMCwxMjVdLFxuKiAgICAgJ21vZGUnOiAnYnV0dG9uJywgIC8vICdidXR0b24nLCAndG9nZ2xlJywgb3IgJ2ltcHVsc2UnXG4qICAgICAnbG93Tm90ZSc6IDI0LFxuKiAgICAgJ2hpZ2hOb3RlJzogNjBcbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgYSBuZXcga2V5IGlzIHByZXNzZWQgb3IgcmVsZWFzZWQgPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyA8aT5ub3RlPC9pPiBhbmQgPGk+c3RhdGU8L2k+IHByb3BlcnRpZXMuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIHBpYW5vLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBpYW5vIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbNTAwLDEyNV0sXG4gICAgICAnbG93Tm90ZSc6IDI0LFxuICAgICAgJ2hpZ2hOb3RlJzogNjAsXG4gICAgICAnbW9kZSc6ICdidXR0b24nXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMua2V5UGF0dGVybiA9IFsndycsJ2InLCd3JywnYicsJ3cnLCd3JywnYicsJ3cnLCdiJywndycsJ2InLCd3J107XG5cbiAgICB0aGlzLnBhaW50YnJ1c2ggPSBmYWxzZTtcblxuICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZTtcblxuICAgIHRoaXMucmFuZ2UgPSB7XG4gICAgICBsb3c6IHRoaXMuc2V0dGluZ3MubG93Tm90ZSxcbiAgICAgIGhpZ2g6IHRoaXMuc2V0dGluZ3MuaGlnaE5vdGVcbiAgICB9O1xuXG4gICAgdGhpcy5yYW5nZS5zaXplID0gdGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7XG5cbiAgICB0aGlzLmtleXMgPSBbXTtcblxuICAgIHRoaXMudG9nZ2xlVG8gPSBmYWxzZTtcblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYm9yZGVyUmFkaXVzID0gJzBweCc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcblxuICAgIHRoaXMua2V5cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7aSsrKSB7XG5cbiAgICAgIGxldCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICBsZXQgc2NhbGVJbmRleCA9IChpK3RoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG5cbiAgICAgIGxldCBrZXkgPSBuZXcgUGlhbm9LZXkoY29udGFpbmVyLCB7XG4gICAgICAgICAgY29tcG9uZW50OiB0cnVlLFxuICAgICAgICAgIG5vdGU6IGkrdGhpcy5yYW5nZS5sb3csXG4gICAgICAgICAgY29sb3I6IHRoaXMua2V5UGF0dGVybltzY2FsZUluZGV4XSxcbiAgICAgICAgICBtb2RlOiB0aGlzLm1vZGVcbiAgICAgICAgfSwgdGhpcy5rZXlDaGFuZ2UuYmluZCh0aGlzLGkrdGhpcy5yYW5nZS5sb3cpKTtcblxuICAgICAga2V5LnBpYW5vID0gdGhpcztcblxuICAgICAgaWYgKHRvdWNoLmV4aXN0cykge1xuICAgICAgICBrZXkucGFkLmluZGV4ID0gaTtcbiAgICAgICAga2V5LnByZUNsaWNrID0ga2V5LnByZU1vdmUgPSBrZXkucHJlUmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgICBrZXkuY2xpY2sgPSBrZXkubW92ZSA9IGtleS5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgICAgIGtleS5wcmVUb3VjaCA9IGtleS5wcmVUb3VjaE1vdmUgPSBrZXkucHJlVG91Y2hSZWxlYXNlID0gKCkgPT4ge307XG4gICAgICAgIGtleS50b3VjaCA9IGtleS50b3VjaE1vdmUgPSBrZXkudG91Y2hSZWxlYXNlID0gKCkgPT4ge307XG4gICAgICB9XG5cbiAgICAgIHRoaXMua2V5cy5wdXNoKGtleSk7XG4gICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblxuICAgIH1cbiAgICBpZiAodG91Y2guZXhpc3RzKSB7XG4gICAgICB0aGlzLmFkZFRvdWNoTGlzdGVuZXJzKCk7XG4gICAgfVxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgbGV0IGtleVggPSAwO1xuXG4gICAgbGV0IGtleVBvc2l0aW9ucyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7aSsrKSB7XG5cbiAgICAgIGtleVBvc2l0aW9ucy5wdXNoKGtleVgpO1xuXG4gICAgICBsZXQgc2NhbGVJbmRleCA9IChpK3RoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG4gICAgICBsZXQgbmV4dFNjYWxlSW5kZXggPSAoaSsxK3RoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG4gICAgICBpZiAoaSsxK3RoaXMucmFuZ2UubG93ID49IHRoaXMucmFuZ2UuaGlnaCkge1xuICAgICAgICBrZXlYICs9IDE7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMua2V5UGF0dGVybltzY2FsZUluZGV4XSA9PT0gJ3cnICYmIHRoaXMua2V5UGF0dGVybltuZXh0U2NhbGVJbmRleF0gPT09ICd3Jykge1xuICAgICAgICBrZXlYICs9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBrZXlYICs9IDAuNTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IGtleXNXaWRlID0ga2V5WDtcblxuXG4gIC8vICBsZXQgcGFkZGluZyA9IHRoaXMud2lkdGggLyAxMjA7XG4gICAgbGV0IHBhZGRpbmcgPSAxO1xuICAgIGxldCBidXR0b25XaWR0aCA9ICh0aGlzLndpZHRoLXBhZGRpbmcqMikgLyBrZXlzV2lkZTtcbiAgICBsZXQgYnV0dG9uSGVpZ2h0ID0gKHRoaXMuaGVpZ2h0LXBhZGRpbmcqMikgLyAyO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5rZXlzLmxlbmd0aDtpKyspIHtcblxuICAgICAgbGV0IGNvbnRhaW5lciA9IHRoaXMua2V5c1tpXS5wYXJlbnQ7XG4gICAgICBjb250YWluZXIuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgY29udGFpbmVyLnN0eWxlLmxlZnQgPSAoa2V5UG9zaXRpb25zW2ldKmJ1dHRvbldpZHRoK3BhZGRpbmcpICsgJ3B4JztcbiAgICAgIGlmICh0aGlzLmtleXNbaV0uY29sb3IgPT09ICd3Jykge1xuICAgICAgICBjb250YWluZXIuc3R5bGUudG9wID0gKHBhZGRpbmcpICsgJ3B4JztcbiAgICAgICAgdGhpcy5rZXlzW2ldLnJlc2l6ZShidXR0b25XaWR0aCwgYnV0dG9uSGVpZ2h0KjIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGFpbmVyLnN0eWxlLnpJbmRleCA9IDE7XG4gICAgICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSBwYWRkaW5nKydweCc7XG4gICAgICAgIHRoaXMua2V5c1tpXS5yZXNpemUoYnV0dG9uV2lkdGgsIGJ1dHRvbkhlaWdodCoxLjEpO1xuICAgICAgfVxuXG4gICAgfVxuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIC8vIFBpYW5vIGtleXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSBhIHN0cm9rZSBib3JkZXJcbiAgICAvLyBUaGV5IGhhdmUgc3BhY2UgYmV0d2VlbiB0aGVtLCB3aGljaCBzaG93cyB0aGUgUGlhbm8gYmcgY29sb3JcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQ7XG5cbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLmtleXMubGVuZ3RoO2krKykge1xuICAgICAgdGhpcy5rZXlzW2ldLmNvbG9ycyA9IHtcbiAgICAgICAgJ3cnOiB0aGlzLmNvbG9ycy5saWdodCxcbiAgICAgICAgJ2InOiB0aGlzLmNvbG9ycy5kYXJrLFxuICAgICAgICAnYWNjZW50JzogdGhpcy5jb2xvcnMuYWNjZW50LFxuICAgICAgICAnYm9yZGVyJzogdGhpcy5jb2xvcnMubWVkaXVtTGlnaHRcbiAgICAgIH07XG4gICAgICB0aGlzLmtleXNbaV0uY29sb3JJbnRlcmZhY2UoKTtcbiAgICAgIHRoaXMua2V5c1tpXS5yZW5kZXIoKTtcbiAgICB9XG5cblxuICB9XG5cbiAga2V5Q2hhbmdlKG5vdGUsb24pIHtcbiAgICAvLyBlbWl0IGRhdGEgZm9yIGFueSBrZXkgdHVybmluZyBvbi9vZmZcbiAgICAvLyBcIm5vdGVcIiBpcyB0aGUgbm90ZSB2YWx1ZVxuICAgIC8vIFwib25cIiBpcyBhIGJvb2xlYW4gd2hldGhlciBpdCBpcyBvbiBvciBvZmZcbiAgICAvLyBpbiBhZnRlcnRvdWNoIG1vZGUsIFwib246IGlzIGFuIG9iamVjdCB3aXRoIHN0YXRlL3gveSBwcm9wZXJ0aWVzXG4gICAgdmFyIGRhdGEgPSB7XG4gICAgICBub3RlOiBub3RlXG4gICAgfTtcbiAgICBpZiAodHlwZW9mIG9uID09PSAnb2JqZWN0Jykge1xuICAgICAgZGF0YS5zdGF0ZSA9IG9uLnN0YXRlO1xuICAgIC8vICBkYXRhLnggPSBvbi54XG4gICAgLy8gIGRhdGEueSA9IG9uLnlcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YS5zdGF0ZSA9IG9uO1xuICAgIH1cbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsZGF0YSk7XG4gIH1cblxuICAvKiBkcmFnKG5vdGUsb24pIHtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgbm90ZTogbm90ZSxcbiAgICAgIHN0YXRlOiBvblxuICAgIH0pO1xuICB9ICovXG5cbiAgcmVuZGVyKCkge1xuICAgIC8vIGxvb3AgdGhyb3VnaCBhbmQgcmVuZGVyIHRoZSBrZXlzP1xuICB9XG5cblxuICBhZGRUb3VjaExpc3RlbmVycygpIHtcblxuICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuXG4gICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGZhbHNlO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoZSkgPT4ge1xuICAgICAgY29uc29sZS5sb2coJ3RvdWNoc3RhcnQnKTtcbiAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCxlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG4gICAgICBsZXQga2V5ID0gdGhpcy5rZXlzW2VsZW1lbnQuaW5kZXhdO1xuICAgICAgdGhpcy5wYWludGJydXNoID0gIWtleS5zdGF0ZTtcbiAgICAgIGtleS5kb3duKHRoaXMucGFpbnRicnVzaCk7XG4gICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZWxlbWVudC5pbmRleDtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgKGUpID0+IHtcbiAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCxlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG4gICAgICBsZXQga2V5ID0gdGhpcy5rZXlzW2VsZW1lbnQuaW5kZXhdO1xuICAgICAgaWYgKGVsZW1lbnQuaW5kZXghPT10aGlzLmN1cnJlbnRFbGVtZW50KSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgbGV0IHBhc3RLZXkgPSB0aGlzLmtleXNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICAgICAgcGFzdEtleS51cCgpO1xuICAgICAgICB9XG4gICAgICAgIGtleS5kb3duKHRoaXMucGFpbnRicnVzaCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBrZXkuYmVuZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGVsZW1lbnQuaW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgKGUpID0+IHtcbiAgICAgIC8vIG5vIHRvdWNoZXMgdG8gY2FsY3VsYXRlIGJlY2F1c2Ugbm9uZSByZW1haW5pbmdcbiAgICAgIGxldCBrZXkgPSB0aGlzLmtleXNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICBrZXkudXAoKTtcbiAgICAgIHRoaXMuaW50ZXJhY3RpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBmYWxzZTtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIC8qKlxuICBEZWZpbmUgdGhlIHBpdGNoIHJhbmdlIChsb3dlc3QgYW5kIGhpZ2hlc3Qgbm90ZSkgb2YgdGhlIHBpYW5vIGtleWJvYXJkLlxuICBAcGFyYW0gbG93IHtudW1iZXJ9IE1JREkgbm90ZSB2YWx1ZSBvZiB0aGUgbG93ZXN0IG5vdGUgb24gdGhlIGtleWJvYXJkXG4gIEBwYXJhbSBoaWdoIHtudW1iZXJ9IE1JREkgbm90ZSB2YWx1ZSBvZiB0aGUgaGlnaGVzdCBub3RlIG9uIHRoZSBrZXlib2FyZFxuICAqL1xuICBzZXRSYW5nZShsb3csaGlnaCkge1xuICAgIHRoaXMucmFuZ2UubG93ID0gbG93O1xuICAgIHRoaXMucmFuZ2UuaGlnaCA9IGhpZ2g7XG4gICAgdGhpcy5lbXB0eSgpO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgfVxuXG4gIC8qKlxuICBUdXJuIGEga2V5IG9uIG9yIG9mZiB1c2luZyBpdHMgTUlESSBub3RlIHZhbHVlO1xuICBAcGFyYW0gbm90ZSB7bnVtYmVyfSBNSURJIG5vdGUgdmFsdWUgb2YgdGhlIGtleSB0byBjaGFuZ2VcbiAgQHBhcmFtIG9uIHtib29sZWFufSBXaGV0aGVyIHRoZSBub3RlIHNob3VsZCB0dXJuIG9uIG9yIG9mZlxuICAqL1xuICB0b2dnbGVLZXkobm90ZSwgb24pIHtcbiAgICB0aGlzLmtleXNbbm90ZS10aGlzLnJhbmdlLmxvd10uZmxpcChvbik7XG4gIH1cblxuICAvKipcbiAgVHVybiBhIGtleSBvbiBvciBvZmYgdXNpbmcgaXRzIGtleSBpbmRleCBvbiB0aGUgcGlhbm8gaW50ZXJmYWNlLlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gSW5kZXggb2YgdGhlIGtleSB0byBjaGFuZ2VcbiAgQHBhcmFtIG9uIHtib29sZWFufSBXaGV0aGVyIHRoZSBub3RlIHNob3VsZCB0dXJuIG9uIG9yIG9mZlxuICAqL1xuICB0b2dnbGVJbmRleChpbmRleCwgb24pIHtcbiAgICB0aGlzLmtleXNbaW5kZXhdLmZsaXAob24pO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL3BpYW5vLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBkb20gPSByZXF1aXJlKCcuLi91dGlsL2RvbScpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgQnV0dG9uVGVtcGxhdGUgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL2J1dHRvbnRlbXBsYXRlJyk7XG5sZXQgTWF0cml4TW9kZWwgPSByZXF1aXJlKCcuLi9tb2RlbHMvbWF0cml4Jyk7XG5sZXQgQ291bnRlck1vZGVsID0gcmVxdWlyZSgnLi4vbW9kZWxzL2NvdW50ZXInKTtcbmxldCB0b3VjaCA9IHJlcXVpcmUoJy4uL3V0aWwvdG91Y2gnKTtcblxuXG5cbmNsYXNzIE1hdHJpeENlbGwgZXh0ZW5kcyBCdXR0b25UZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnLF07XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFs4MCw4MF0sXG4gICAgICAndGFyZ2V0JzogZmFsc2UsXG4gICAgICAnbW9kZSc6ICd0b2dnbGUnLFxuICAgICAgJ3ZhbHVlJzogMFxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLmluZGV4ID0gdGhpcy5zZXR0aW5ncy5pbmRleDtcbiAgICB0aGlzLnJvdyA9IHRoaXMuc2V0dGluZ3Mucm93O1xuICAgIHRoaXMuY29sdW1uID0gdGhpcy5zZXR0aW5ncy5jb2x1bW47XG5cbiAgICB0aGlzLm1hdHJpeCA9IHRoaXMuc2V0dGluZ3MubWF0cml4O1xuXG4gICAgdGhpcy5pbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgIHRoaXMucGFpbnRicnVzaCA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy53aWR0aCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx0aGlzLmhlaWdodCk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnRvcCA9ICcwcHgnO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5sZWZ0ID0gJzBweCc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLnBhZCA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wYWQpO1xuXG4gICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXG4gICAgLyogZXZlbnRzICovXG5cbiAgICBpZiAoIXRvdWNoLmV4aXN0cykge1xuXG4gICAgICB0aGlzLmNsaWNrID0gKCkgPT4ge1xuICAgICAgICB0aGlzLm1hdHJpeC5pbnRlcmFjdGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMubWF0cml4LnBhaW50YnJ1c2ggPSAhdGhpcy5zdGF0ZTtcbiAgICAgICAgdGhpcy5kb3duKHRoaXMubWF0cml4LnBhaW50YnJ1c2gpO1xuICAgICAgfTtcbiAgICAgIHRoaXMucGFkLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3ZlcicsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubWF0cml4LmludGVyYWN0aW5nKSB7XG4gICAgICAgICAgdGhpcy5kb3duKHRoaXMubWF0cml4LnBhaW50YnJ1c2gpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuXG4gICAgICB0aGlzLm1vdmUgPSAoKSA9PiB7XG4gICAgICB9O1xuICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGUpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubWF0cml4LmludGVyYWN0aW5nKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLm9mZnNldCkge1xuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBkb20uZmluZFBvc2l0aW9uKHRoaXMuZWxlbWVudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSx0aGlzLm9mZnNldCk7XG4gICAgICAgICAgdGhpcy5iZW5kKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG5cbiAgICAgIHRoaXMucmVsZWFzZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5tYXRyaXguaW50ZXJhY3RpbmcgPSBmYWxzZTtcbiAgICAgIH07XG4gICAgICB0aGlzLnBhZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tYXRyaXguaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdXQnLCAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLm1hdHJpeC5pbnRlcmFjdGluZykge1xuICAgICAgICAgIHRoaXMudXAoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd4JywxKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ3knLDEpO1xuICAgIGlmICh0aGlzLndpZHRoID4gMikge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMud2lkdGggLSAyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMud2lkdGgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5oZWlnaHQgPiAyKSB7XG4gICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIHRoaXMuaGVpZ2h0IC0gMik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQpO1xuICAgIH1cbiAgICAvL3RoaXMucGFkLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5oZWlnaHQgLSAyKTtcbiAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLm1hdHJpeC5jb2xvcnMuZmlsbCk7XG5cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUpIHtcbiAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMubWF0cml4LmNvbG9ycy5maWxsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5tYXRyaXguY29sb3JzLmFjY2VudCk7XG4gICAgfVxuICB9XG5cbn1cblxuLyoqXG4qIFNlcXVlbmNlclxuKlxuKiBAZGVzY3JpcHRpb24gR3JpZCBvZiBidXR0b25zIHdpdGggYnVpbHQtaW4gc3RlcCBzZXF1ZW5jZXIuXG4qXG4qIEBkZW1vIDxkaXYgbmV4dXMtdWk9XCJzZXF1ZW5jZXJcIiBzdHlsZT1cIndpZHRoOjQwMHB4O2hlaWdodDoyMDBweDtcIj48L2Rpdj5cbipcbiogQGV4YW1wbGVcbiogdmFyIHNlcXVlbmNlciA9IG5ldyBOZXh1cy5TZXF1ZW5jZXIoJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc2VxdWVuY2VyID0gbmV3IE5leHVzLlNlcXVlbmNlcignI3RhcmdldCcse1xuKiAgJ3NpemUnOiBbNDAwLDIwMF0sXG4qICAnbW9kZSc6ICd0b2dnbGUnLFxuKiAgJ3Jvd3MnOiA1LFxuKiAgJ2NvbHVtbnMnOiAxMFxuKn0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyBtYXRyaXggY2hhbmdlcy4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyA8aT5yb3c8L2k+IChudW1iZXIpLCA8aT5jb2x1bW48L2k+IChudW1iZXIpLCBhbmQgPGk+c3RhdGU8L2k+IChib29sZWFuKSBwcm9wZXJ0aWVzLlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiBzZXF1ZW5jZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKiBAb3V0cHV0XG4qIHN0ZXBcbiogRmlyZXMgYW55IHRpbWUgdGhlIHNlcXVlbmNlciBzdGVwcyB0byB0aGUgbmV4dCBjb2x1bW4sIGluIHNlcXVlY2UgbW9kZS4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiA8aT5hcnJheTwvaT4gY29udGFpbmluZyBhbGwgdmFsdWVzIGluIHRoZSBjb2x1bW4sIDxpPmJvdHRvbSByb3cgZmlyc3Q8L2k+LlxuKlxuKiBAb3V0cHV0ZXhhbXBsZVxuKiBzZXF1ZW5jZXIub24oJ3N0ZXAnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNlcXVlbmNlciBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzQwMCwyMDBdLFxuICAgICAgJ21vZGUnOiAndG9nZ2xlJyxcbiAgICAgICdyb3dzJzogNSxcbiAgICAgICdjb2x1bW5zJzogMTBcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5hY3RpdmUgPSAtMTtcblxuICAgIC8qKlxuICAgICogQnV0dG9uIGludGVyYWN0aW9uIG1vZGU6IHNlZSBCdXR0b25cbiAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgKiBAZXhhbXBsZSBidXR0b24ubW9kZSA9ICd0b2dnbGUnO1xuICAgICovXG4gICAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXG4gICAgLyoqXG4gICAgKiBUaGUgaW50ZXJ2YWwgb2JqZWN0IHdoaWNoIGNvbnRyb2xzIHRpbWluZyBhbmQgc2VxdWVuY2Ugc2NoZWR1bGluZy5cbiAgICAqIEB0eXBlIHtpbnRlcnZhbH1cbiAgICAqL1xuICAgIHRoaXMuaW50ZXJ2YWwgPSBuZXcgTmV4dXMuSW50ZXJ2YWwoMjAwLGZ1bmN0aW9uKCkge30sZmFsc2UpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuICAgIC8qKlxuICAgICogQSBNYXRyaXggbW9kZWwgY29udGFpbmluZyBtZXRob2RzIGZvciBtYW5pcHVsYXRpbmcgdGhlIHNlcXVlbmNlcidzIGFycmF5IG9mIHZhbHVlcy4gVG8gbGVhcm4gaG93IHRvIG1hbmlwdWxhdGUgdGhlIG1hdHJpeCwgcmVhZCBhYm91dCB0aGUgbWF0cml4IG1vZGVsLlxuICAgICogQHR5cGUge21hdHJpeH1cbiAgICAqL1xuICAgIHRoaXMubWF0cml4ID0gbmV3IE1hdHJpeE1vZGVsKHRoaXMuc2V0dGluZ3Mucm93cyx0aGlzLnNldHRpbmdzLmNvbHVtbnMpO1xuICAgIHRoaXMubWF0cml4LnVpID0gdGhpcztcblxuICAgIC8qKlxuICAgICogQSBDb3VudGVyIG1vZGVsIHdoaWNoIHRoZSBzZXF1ZW5jZXIgc3RlcHMgdGhyb3VnaC4gRm9yIGV4YW1wbGUsIHlvdSBjb3VsZCB1c2UgdGhpcyBtb2RlbCB0byBzdGVwIHRocm91Z2ggdGhlIHNlcXVlbmNlciBpbiByZXZlcnNlLCByYW5kb21seSwgb3IgaW4gYSBkcnVuayB3YWxrLlxuICAgICogQHR5cGUge2NvdW50ZXJ9XG4gICAgKi9cbiAgICB0aGlzLnN0ZXBwZXIgPSBuZXcgQ291bnRlck1vZGVsKDAsdGhpcy5jb2x1bW5zKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gIH1cblxuICBidWlsZEZyYW1lKCkge1xuICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG4gICAgaWYgKHRvdWNoLmV4aXN0cykge1xuICAgICAgdGhpcy5hZGRUb3VjaExpc3RlbmVycygpO1xuICAgIH1cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5jZWxscyA9IFtdO1xuICAgIGZvciAobGV0IGk9MDtpPHRoaXMubWF0cml4Lmxlbmd0aDtpKyspIHtcblxuICAgICAgbGV0IGxvY2F0aW9uID0gdGhpcy5tYXRyaXgubG9jYXRlKGkpO1xuICAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJucyB7cm93LGNvbH1cblxuICAgICAgbGV0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgIGNvbnRhaW5lci5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG5cblxuICAgICAgbGV0IGNlbGwgPSBuZXcgTWF0cml4Q2VsbChjb250YWluZXIsIHtcbiAgICAgICAgICBjb21wb25lbnQ6IHRydWUsXG4gICAgICAgICAgaW5kZXg6IGksXG4gICAgICAgICAgcm93OiBsb2NhdGlvbi5yb3csXG4gICAgICAgICAgY29sdW1uOiBsb2NhdGlvbi5jb2x1bW4sXG4gICAgICAgICAgbW9kZTogdGhpcy5tb2RlLFxuICAgICAgICAgIG1hdHJpeDogdGhpc1xuICAgICAgICB9LCB0aGlzLmtleUNoYW5nZS5iaW5kKHRoaXMsaSkpO1xuXG4gICAgLy8gIGNlbGwubWF0cml4ID0gdGhpcztcbiAgICAgIGlmICh0b3VjaC5leGlzdHMpIHtcbiAgICAgICAgY2VsbC5wYWQuaW5kZXggPSBpO1xuICAgICAgICBjZWxsLnByZUNsaWNrID0gY2VsbC5wcmVNb3ZlID0gY2VsbC5wcmVSZWxlYXNlID0gKCkgPT4ge307XG4gICAgICAgIGNlbGwuY2xpY2sgPSBjZWxsLm1vdmUgPSBjZWxsLnJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgICAgY2VsbC5wcmVUb3VjaCA9IGNlbGwucHJlVG91Y2hNb3ZlID0gY2VsbC5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgICAgY2VsbC50b3VjaCA9IGNlbGwudG91Y2hNb3ZlID0gY2VsbC50b3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5jZWxscy5wdXNoKGNlbGwpO1xuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cbiAgICB9XG4gICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgbGV0IGNlbGxXaWR0aCA9IHRoaXMud2lkdGggLyB0aGlzLmNvbHVtbnM7XG4gICAgbGV0IGNlbGxIZWlnaHQgPSB0aGlzLmhlaWdodCAvIHRoaXMucm93cztcblxuICAgIGZvciAobGV0IGk9MDsgaTx0aGlzLmNlbGxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgY29udGFpbmVyID0gdGhpcy5jZWxsc1tpXS5wYXJlbnQ7XG4gICAgICBjb250YWluZXIuc3R5bGUubGVmdCA9IHRoaXMuY2VsbHNbaV0uY29sdW1uICogY2VsbFdpZHRoICsgJ3B4JztcbiAgICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSB0aGlzLmNlbGxzW2ldLnJvdyAqIGNlbGxIZWlnaHQgKyAncHgnO1xuICAgICAgdGhpcy5jZWxsc1tpXS5yZXNpemUoY2VsbFdpZHRoLGNlbGxIZWlnaHQpO1xuICAgIH1cblxuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICBmb3IgKHZhciBpPTA7IGk8dGhpcy5jZWxscy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5jZWxsc1tpXS5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGUoKSB7XG4gIC8vICBjb25zb2xlLmxvZyhcInVwZGF0aW5nLi4uXCIpXG4gICAgLy9vbiA9IG9uIHx8IGZhbHNlO1xuICAgIHRoaXMubWF0cml4Lml0ZXJhdGUoKHIsYyxpKSA9PiB7XG4gICAgICAvLyAgY29uc29sZS5sb2codGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSwgdGhpcy5jZWxsc1tpXS5zdGF0ZSk7XG4gICAgICBpZiAodGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSAhPT0gdGhpcy5jZWxsc1tpXS5zdGF0ZSkge1xuICAgICAgICBpZiAodGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSA+IDApIHtcbiAgICAgICAgICB0aGlzLmNlbGxzW2ldLnR1cm5PbigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuY2VsbHNbaV0udHVybk9mZigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuLy8gdXBkYXRlID0+IGNlbGwudHVybk9uID0+IGNlbGwuZW1pdCA9PiBrZXlDaGFuZ2UgKHNlcS5lbWl0KSA9PiBtYXRyaXguc2V0LmNlbGwgPT4gdXBkYXRlXG4vL1xuLy8gaW50ZXJhY3Rpb24gPT4ga2V5Q2hhbmdlID0+IG1hdHJpeC5zZXQuY2VsbCA9PiB1cGRhdGUgPT4gY2VsbC50dXJuT25cbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gZW1pdFxuLy9cbi8vIHNldC5jZWxsID0+IHVwZGF0ZSA9PiBuZWVkcyB0byBlbWl0LlxuXG4gIGtleUNoYW5nZShub3RlLG9uKSB7XG4gICAgLy8gZW1pdCBkYXRhIGZvciBhbnkga2V5IHR1cm5pbmcgb24vb2ZmXG4gICAgLy8gaSBpcyB0aGUgbm90ZSBpbmRleFxuICAgIC8vIHYgaXMgd2hldGhlciBpdCBpcyBvbiBvciBvZmZcbiAgICBsZXQgY2VsbCA9IHRoaXMubWF0cml4LmxvY2F0ZShub3RlKTtcbiAgLy8gIHRoaXMubWF0cml4LnNldC5jZWxsKGNlbGwuY29sdW1uLGNlbGwucm93LG9uKTtcbiAgICB0aGlzLm1hdHJpeC5wYXR0ZXJuW2NlbGwucm93XVtjZWxsLmNvbHVtbl0gPSBvbjtcbiAgICB2YXIgZGF0YSA9IHtcbiAgICAgIHJvdzogY2VsbC5yb3csXG4gICAgICBjb2x1bW46IGNlbGwuY29sdW1uLFxuICAgICAgc3RhdGU6IG9uXG4gICAgfTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsZGF0YSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKHRoaXMuc3RlcHBlci52YWx1ZSA+PSAwKSB7XG4gICAgICB0aGlzLm1hdHJpeC5pdGVyYXRlKChyLGMsaSkgPT4ge1xuICAgICAgICBpZiAoYz09PXRoaXMuc3RlcHBlci52YWx1ZSkge1xuICAgICAgICAgIHRoaXMuY2VsbHNbaV0ucGFkLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgICAgICAgdGhpcy5jZWxsc1tpXS5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCcxJyk7XG4gICAgICAgICAgdGhpcy5jZWxsc1tpXS5wYWQuc2V0QXR0cmlidXRlKCdzdHJva2Utb3BhY2l0eScsJzEnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNlbGxzW2ldLnBhZC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsJ25vbmUnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHNlcXVlbmNpbmdcbiAgICogQHBhcmFtICB7bnVtYmVyfSBtcyBCZWF0IHRlbXBvIGluIG1pbGxpc2Vjb25kc1xuICAgKi9cbiAgc3RhcnQobXMpIHtcbiAgICB0aGlzLmludGVydmFsLmV2ZW50ID0gdGhpcy5uZXh0LmJpbmQodGhpcyk7XG4gICAgaWYgKG1zKSB7XG4gICAgICB0aGlzLmludGVydmFsLm1zKG1zKTtcbiAgICB9XG4gICAgdGhpcy5pbnRlcnZhbC5zdGFydCgpO1xuICB9XG5cbiAgLyoqXG4gIFN0b3Agc2VxdWVuY2luZ1xuICAqL1xuICBzdG9wKCkge1xuICAgIHRoaXMuaW50ZXJ2YWwuc3RvcCgpO1xuICB9XG5cbiAgLyoqXG4gIE1hbnVhbGx5IGp1bXAgdG8gdGhlIG5leHQgY29sdW1uIGFuZCB0cmlnZ2VyIHRoZSAnY2hhbmdlJyBldmVudC4gVGhlIFwibmV4dFwiIGNvbHVtbiBpcyBkZXRlcm1pbmVkIGJ5IHlvdXIgbW9kZSBvZiBzZXF1ZW5jaW5nLlxuICAqL1xuICBuZXh0KCkge1xuICAgIHRoaXMuc3RlcHBlci5uZXh0KCk7XG4gICAgdGhpcy5lbWl0KCdzdGVwJyx0aGlzLm1hdHJpeC5jb2x1bW4odGhpcy5zdGVwcGVyLnZhbHVlKS5yZXZlcnNlKCkpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBhZGRUb3VjaExpc3RlbmVycygpIHtcblxuICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuXG4gICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGZhbHNlO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoZSkgPT4ge1xuICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRYLGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRZKTtcbiAgICAgIGxldCBjZWxsID0gdGhpcy5jZWxsc1tlbGVtZW50LmluZGV4XTtcbiAgICAgIHRoaXMucGFpbnRicnVzaCA9ICFjZWxsLnN0YXRlO1xuICAgICAgY2VsbC5kb3duKHRoaXMucGFpbnRicnVzaCk7XG4gICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZWxlbWVudC5pbmRleDtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgKGUpID0+IHtcbiAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCxlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG4gICAgICBsZXQgY2VsbCA9IHRoaXMuY2VsbHNbZWxlbWVudC5pbmRleF07XG4gICAgICBpZiAoZWxlbWVudC5pbmRleCE9PXRoaXMuY3VycmVudEVsZW1lbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEVsZW1lbnQgPj0gMCkge1xuICAgICAgICAgIGxldCBwYXN0Q2VsbCA9IHRoaXMuY2VsbHNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICAgICAgcGFzdENlbGwudXAoKTtcbiAgICAgICAgfVxuICAgICAgICBjZWxsLmRvd24odGhpcy5wYWludGJydXNoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNlbGwuYmVuZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGVsZW1lbnQuaW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgKGUpID0+IHtcbiAgICAgIC8vIG5vIHRvdWNoZXMgdG8gY2FsY3VsYXRlIGJlY2F1c2Ugbm9uZSByZW1haW5pbmdcbiAgICAgIGxldCBjZWxsID0gdGhpcy5jZWxsc1t0aGlzLmN1cnJlbnRFbGVtZW50XTtcbiAgICAgIGNlbGwudXAoKTtcbiAgICAgIHRoaXMuaW50ZXJhY3RpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBmYWxzZTtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIC8qKlxuICBOdW1iZXIgb2Ygcm93cyBpbiB0aGUgc2VxdWVuY2VyXG4gIEB0eXBlIHtudW1iZXJ9XG4gICovXG4gIGdldCByb3dzKCkge1xuICAgIHJldHVybiB0aGlzLm1hdHJpeC5yb3dzO1xuICB9XG5cbiAgc2V0IHJvd3Modikge1xuICAgIHRoaXMubWF0cml4LnJvd3MgPSB2O1xuICAgIHRoaXMuZW1wdHkoKTtcbiAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICBOdW1iZXIgb2YgY29sdW1ucyBpbiB0aGUgc2VxdWVuY2VyXG4gIEB0eXBlIHtudW1iZXJ9XG4gICovXG4gIGdldCBjb2x1bW5zKCkge1xuICAgIHJldHVybiB0aGlzLm1hdHJpeC5jb2x1bW5zO1xuICB9XG5cbiAgc2V0IGNvbHVtbnModikge1xuICAgIHRoaXMubWF0cml4LmNvbHVtbnMgPSB2O1xuICAgIHRoaXMuc3RlcHBlci5tYXggPSB2O1xuICAgIHRoaXMuZW1wdHkoKTtcbiAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvaW50ZXJmYWNlcy9zZXF1ZW5jZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5pbXBvcnQgU2VxdWVuY2UgZnJvbSAnLi4vbW9kZWxzL3NlcXVlbmNlJztcblxuLy8gRm9yIHRoZSB0dXRvcmlhbCwgbG9va2luZyBhdFxuXG4vL1BhdHRlcm4gc2VjdGlvbjpcbi8vIC5jcmVhdGUoKSwgLnJvd3MsIC5jb2x1bW5zLFxuLy8gLnBhdHRlcm4sIC5sZW5ndGgsIC5mb3JtYXRBc1RleHQoKSwgLmxvZygpLFxuLy8gLmxvY2F0ZShpKSwgLmluZGV4T2YoYyxyKVxuLy8gcm93KCksIGNvbHVtbigpIChyZXR1cm5zIGNvbnRlbnRzIG9mIHJvdyBvciBjb2x1bSlcblxuLy9Db250cm9sIHNlY3Rpb246XG4vLyB0b2dnbGUgeDNcbi8vIHNldCB4NFxuLy8gcm90YXRlIHgzXG4vLyBwb3B1bGF0ZSB4M1xuLy8gZXJhc2UgeDNcblxuXG4vLyBzaG91bGQgc29tZSB2ZXJzaW9uIG9mIHRoaXMgaGF2ZSBhIGZsb2F0IHZhbHVlIGZvciBlYWNoIGNlbGw/XG4vLyBjb3VsZCBiZSBsaWtlIGEgbWlycm9yIC5wYXR0ZXJuIHRoYXQgaGFzIHZhbHVlcy4gYnkgZGVmYXVsdCwgZXZlcnl0aGluZyBpcyAxLCBidXQgY291bGQgYmUgc2V0Li4uXG4vLyBub3QgYSBnb29kIHdheSB0byBkbyB0aGF0IG9uIGludGVyZmFjZSwgYnV0IGFzIGEgbW9kZWwgaXQgd291bGQgYmUgbmljZS4uLlxuLy8gZm9yIC5mb3JtYXRBc1RleHQoKSwgY291bGQgbXVsdGlwbHkgYnkgMTAwIGFuZCBmbG9vciwgc28gZWFjaCBjZWxsIGlzIGFuIGludCBmcm9tIDAgdG8gOVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNYXRyaXgge1xuXG4gIGNvbnN0cnVjdG9yKHJvd3MsY29sdW1ucykge1xuICAgIC8vIHNob3VsZCBhbHNvIGhhdmUgYWJpbGl0eSB0byBjcmVhdGUgdXNpbmcgYW4gZXhpc3RpbmcgbWF0cml4ICgyZCBhcnJheSlcbiAgICB0aGlzLnBhdHRlcm4gPSBbXTtcbiAgICB0aGlzLmNyZWF0ZShyb3dzLGNvbHVtbnMpO1xuXG4gICAgdGhpcy50b2dnbGUgPSB7XG4gICAgICBjZWxsOiAoY29sdW1uLCByb3cpID0+IHtcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3Jvd11bY29sdW1uXSA9ICF0aGlzLnBhdHRlcm5bcm93XVtjb2x1bW5dOyAvLyBtYXRoLmludmVydCh0aGlzLnBhdHRlcm5bcm93XVtjb2x1bW5dKTtcbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgICByZXR1cm4gdGhpcy5wYXR0ZXJuW3Jvd11bY29sdW1uXTtcbiAgICAgIH0sXG4gICAgICBhbGw6ICgpID0+IHtcbiAgICAgICAgdGhpcy5pdGVyYXRlKChyLGMpID0+IHsgdGhpcy50b2dnbGUuY2VsbChjLHIpOyB9KTtcbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgfSxcbiAgICAgIHJvdzogKHJvdykgPT4ge1xuICAgICAgICBmb3IgKGxldCBpPTA7IGk8dGhpcy5jb2x1bW5zOyBpKyspIHtcbiAgICAgICAgICB0aGlzLnRvZ2dsZS5jZWxsKGkscm93KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9LFxuICAgICAgY29sdW1uOiAoY29sdW1uKSA9PiB7XG4gICAgICAgIGZvciAobGV0IGk9MDsgaTx0aGlzLnJvd3M7IGkrKykge1xuICAgICAgICAgIHRoaXMudG9nZ2xlLmNlbGwoY29sdW1uLGkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5zZXQgPSB7XG4gICAgICBjZWxsOiAoY29sdW1uLCByb3csIHZhbHVlKSA9PiB7XG4gICAgICAgIHRoaXMucGF0dGVybltyb3ddW2NvbHVtbl0gPSB2YWx1ZTtcbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgfSxcbiAgICAgIGFsbDogKHZhbHVlcykgPT4ge1xuICAgICAgICAvLyBzZXQgdGhlIHdob2xlIG1hdHJpeCB1c2luZyBhIDJkIGFycmF5IGFzIGlucHV0XG4gICAgICAgIC8vIHRoaXMgc2hvdWxkIGFsc28gcmVzaXplIHRoZSBhcnJheT9cbiAgICAgICAgdGhpcy5wYXR0ZXJuID0gdmFsdWVzO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9LFxuICAgICAgcm93OiAocm93LHZhbHVlcykgPT4ge1xuICAgICAgICAvLyBzZXQgYSByb3cgdXNpbmcgYW4gYXJyYXkgYXMgaW5wdXRcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3Jvd10gPSB2YWx1ZXM7XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH0sXG4gICAgICBjb2x1bW46IChjb2x1bW4sdmFsdWVzKSA9PiB7XG4gICAgICAgIC8vIHNldCBhIGNvbHVtbiB1c2luZyBhbiBhcnJheSBhcyBpbnB1dFxuICAgICAgICB0aGlzLnBhdHRlcm4uZm9yRWFjaCgocm93LGkpID0+IHtcbiAgICAgICAgICB0aGlzLnBhdHRlcm5baV1bY29sdW1uXSA9IHZhbHVlc1tpXTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5yb3RhdGUgPSB7XG4gICAgICAvL3Nob3VsZCBldmVudHVhbGx5IGRvIChhbW91bnRYLCBhbW91bnRZKSBoZXJlXG4gICAgICAvLyBjb3VsZCBqdXN0IHVzZSBhIGxvb3AgYW5kIHRoaXMucm90YXRlLnJvdyhpLGFtb3VudFgpO1xuICAgICAgYWxsOiAoYW1vdW50KSA9PiB7XG4gICAgICAgIGlmICghYW1vdW50ICYmIGFtb3VudCE9PTApIHtcbiAgICAgICAgICBhbW91bnQgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGFtb3VudCAlPSB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuICAgICAgICBpZiAoYW1vdW50IDwgMCkge1xuICAgICAgICAgIGFtb3VudCA9IHRoaXMucGF0dGVyblswXS5sZW5ndGggKyBhbW91bnQ7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaT0wOyBpPHRoaXMucm93czsgaSsrKSB7XG4gICAgICAgICAgbGV0IGN1dCA9IHRoaXMucGF0dGVybltpXS5zcGxpY2UoIHRoaXMucGF0dGVybltpXS5sZW5ndGggLSBhbW91bnQsIGFtb3VudCApO1xuICAgICAgICAgIHRoaXMucGF0dGVybltpXSA9IGN1dC5jb25jYXQoIHRoaXMucGF0dGVybltpXSApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH0sXG4gICAgICByb3c6IChyb3csYW1vdW50KSA9PiB7XG4gICAgICAgIGlmICghYW1vdW50ICYmIGFtb3VudCE9PTApIHtcbiAgICAgICAgICBhbW91bnQgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGFtb3VudCAlPSB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuICAgICAgICBpZiAoYW1vdW50IDwgMCkge1xuICAgICAgICAgIGFtb3VudCA9IHRoaXMucGF0dGVyblswXS5sZW5ndGggKyBhbW91bnQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGN1dCA9IHRoaXMucGF0dGVybltyb3ddLnNwbGljZSggdGhpcy5wYXR0ZXJuW3Jvd10ubGVuZ3RoIC0gYW1vdW50LCBhbW91bnQgKTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3Jvd10gPSBjdXQuY29uY2F0KCB0aGlzLnBhdHRlcm5bcm93XSApO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9LFxuICAgICAgY29sdW1uOiAoY29sdW1uLCBhbW91bnQpID0+IHtcbiAgICAgICAgaWYgKCFhbW91bnQgJiYgYW1vdW50IT09MCkge1xuICAgICAgICAgIGFtb3VudCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgYW1vdW50ICU9IHRoaXMucGF0dGVybi5sZW5ndGg7XG4gICAgICAgIGlmIChhbW91bnQgPCAwKSB7XG4gICAgICAgICAgYW1vdW50ID0gdGhpcy5wYXR0ZXJuLmxlbmd0aCArIGFtb3VudDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcHJveHkgPSBbXTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuLmZvckVhY2goKHJvdykgPT4ge1xuICAgICAgICAgIHByb3h5LnB1c2goIHJvd1tjb2x1bW5dICk7XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgY3V0ID0gcHJveHkuc3BsaWNlKCBwcm94eS5sZW5ndGggLSBhbW91bnQsIGFtb3VudCApO1xuICAgICAgICBwcm94eSA9IGN1dC5jb25jYXQoIHByb3h5ICk7XG4gICAgICAgIHRoaXMucGF0dGVybi5mb3JFYWNoKChyb3csaSkgPT4ge1xuICAgICAgICAgIHJvd1tjb2x1bW5dID0gcHJveHlbaV07XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIHRoZSBpZGVhIGJlaGluZCBwb3B1bGF0ZSBpcyB0byBiZSBhYmxlIHRvIHNldCBhIHdob2xlIHJvdyBvciBjb2x1bW4gdG8gMCBvciAxXG4gICAgLy8gSUYgdGhlIHZhbHVlIGlzIGEgZmxvYXQsIHN1Y2ggYXMgMC43LCB0aGVuIGl0IHdvdWxkIGJlY29tZSBhIHByb2JhYmlsaXR5XG4gICAgLy8gc28gcG9wdWxhdGUoMC43KSB3b3VsZCBnaXZlIGVhY2ggY2VsbCBhIDcwJSBjaGFuY2Ugb2YgYmVpbmcgMVxuICAgIHRoaXMucG9wdWxhdGUgPSB7XG4gICAgICBhbGw6IChvZGRzKSA9PiB7XG4gICAgICAgIGxldCBvZGRzU2VxdWVuY2UgPSBuZXcgU2VxdWVuY2Uob2Rkcyk7XG4gICAgICAgIHRoaXMuaXRlcmF0ZSgocixjKSA9PiB7XG4gICAgICAgICAgdGhpcy5wYXR0ZXJuW3JdW2NdID0gbWF0aC5jb2luKG9kZHNTZXF1ZW5jZS5uZXh0KCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gVGhpcyBjb3VsZCBiZSB1c2VkIHNvIHRoYXQgZWFjaCByb3cgaGFzIHNhbWUgb2RkcyBwYXR0ZXJuLCBldmVuIGlmIHJvdyBsZW5ndGggaXMgbm90IGRpdmlzaWJseSBieSBzZXF1ZW5jZSBsZW5ndGguXG4gICAgICAgIC8vLCgpID0+IHtcbiAgICAgICAgLy8gIG9kZHMucG9zID0gLTE7XG4gICAgICAgIC8vIH1cbiAgICAgICAgaWYgKHRoaXMudWkpIHsgdGhpcy51aS51cGRhdGUoKTsgfVxuICAgICAgfSxcbiAgICAgIHJvdzogKHJvdz0wLG9kZHM9MSkgPT4ge1xuICAgICAgICBsZXQgb2Rkc1NlcXVlbmNlID0gbmV3IFNlcXVlbmNlKG9kZHMpO1xuICAgICAgICB0aGlzLnBhdHRlcm5bcm93XS5mb3JFYWNoKChjZWxsLGkpID0+IHtcbiAgICAgICAgICB0aGlzLnBhdHRlcm5bcm93XVtpXSA9IG1hdGguY29pbihvZGRzU2VxdWVuY2UubmV4dCgpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLnVpKSB7IHRoaXMudWkudXBkYXRlKCk7IH1cbiAgICAgIH0sXG4gICAgICBjb2x1bW46IChjb2x1bW49MCxvZGRzPTEpID0+IHtcbiAgICAgICAgbGV0IG9kZHNTZXF1ZW5jZSA9IG5ldyBTZXF1ZW5jZShvZGRzKTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuLmZvckVhY2goKHJvdyxpKSA9PiB7XG4gICAgICAgICAgdGhpcy5wYXR0ZXJuW2ldW2NvbHVtbl0gPSBtYXRoLmNvaW4ob2Rkc1NlcXVlbmNlLm5leHQoKSk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy51aSkgeyB0aGlzLnVpLnVwZGF0ZSgpOyB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIGVzc2VudGlhbGwgcG9wdWxhdGUoMCkgc28gaSdtIG5vdCBzdXJlIGlmIHRoaXMgaXMgbmVjZXNzYXJ5IGJ1dCBpcyBuaWNlXG4gICAgdGhpcy5lcmFzZSA9IHtcbiAgICAgIGFsbDogKCkgPT4ge1xuICAgICAgICB0aGlzLnNldC5hbGwoMCk7XG4gICAgICB9LFxuICAgICAgcm93OiAocm93KSA9PiB7XG4gICAgICAgIHRoaXMuc2V0LnJvdyhyb3csMCk7XG4gICAgICB9LFxuICAgICAgY29sdW1uOiAoY29sdW1uKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0LmNvbHVtbihjb2x1bW4sMCk7XG4gICAgICB9XG4gICAgfTtcblxuICAvLyBlbmQgY29uc3RydWN0b3JcbiAgfVxuXG5cbiAgY3JlYXRlKHJvd3MsY29sdW1ucykge1xuICAgIHRoaXMucGF0dGVybiA9IFtdO1xuICAgIGZvciAoIGxldCByb3c9MDsgcm93IDwgcm93czsgcm93KysgKSB7XG4gICAgICBsZXQgYXJyID0gbmV3IEFycmF5KGNvbHVtbnMpO1xuICAgICAgdGhpcy5wYXR0ZXJuLnB1c2goYXJyKTtcbiAgICB9XG4gICAgdGhpcy5pdGVyYXRlKChyLGMpID0+IHsgdGhpcy5wYXR0ZXJuW3JdW2NdID0gZmFsc2U7IH0pO1xuICB9XG5cbiAgaXRlcmF0ZShmLCBmMikge1xuICAgIGxldCBpID0gMDtcbiAgICBmb3IgKCBsZXQgcm93PTA7IHJvdyA8IHRoaXMucm93czsgcm93KysgKSB7XG4gICAgICBpZiAoZjIpIHsgZjIocm93KTsgfVxuICAgICAgZm9yICggbGV0IGNvbHVtbj0wOyBjb2x1bW4gPCB0aGlzLmNvbHVtbnM7IGNvbHVtbisrICkge1xuICAgICAgICBmKHJvdyxjb2x1bW4saSk7XG4gICAgICAgIGkrKztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3JtYXRBc1RleHQoKSB7XG4gICAgbGV0IHBhdHRlcm5TdHJpbmcgPSAnJztcbiAgICB0aGlzLml0ZXJhdGUoXG4gICAgICAocixjKSA9PiB7IHBhdHRlcm5TdHJpbmcgKz0gKHRoaXMucGF0dGVybltyXVtjXSA/IDEgOiAwKSArICcgJzsgfSxcbiAgICAgICgpID0+IHsgcGF0dGVyblN0cmluZyArPSAnXFxuJzsgfVxuICAgICk7XG4gICAgcmV0dXJuIHBhdHRlcm5TdHJpbmc7XG4gIH1cblxuICBsb2coKSB7XG4gICAgY29uc29sZS5sb2codGhpcy5mb3JtYXRBc1RleHQoKSk7XG4gIH1cblxuICB1cGRhdGUocGF0dGVybikge1xuICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm4gfHwgdGhpcy5wYXR0ZXJuO1xuICB9XG5cbiAgZ2V0IGxlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5yb3dzKnRoaXMuY29sdW1ucztcbiAgfVxuXG4gIGxvY2F0ZShpbmRleCkge1xuICAgIC8vIHJldHVybnMgcm93IGFuZCBjb2x1bW4gb2YgY2VsbCBieSBpbmRleFxuICAgIHJldHVybiB7XG4gICAgICByb3c6IH5+KCBpbmRleCAvIHRoaXMuY29sdW1ucyApLFxuICAgICAgY29sdW1uOiBpbmRleCAlIHRoaXMuY29sdW1uc1xuICAgIH07XG4gIH1cblxuICBpbmRleE9mKHJvdyxjb2x1bW4pIHtcbiAgICByZXR1cm4gY29sdW1uICsgcm93ICogdGhpcy5jb2x1bW5zO1xuICAgIC8vIHJldHVybnMgaW5kZXggb2YgY2VsbCBieSByb3cgYW5kIGNvbHVtblxuICB9XG5cbiAgcm93KHJvdykge1xuICAgIGxldCBkYXRhID0gW107XG4gICAgZm9yIChsZXQgaT0wOyBpPHRoaXMuY29sdW1uczsgaSsrKSB7XG4gICAgICBkYXRhLnB1c2godGhpcy5wYXR0ZXJuW3Jvd10gPyAxIDogMCk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgY29sdW1uKGNvbHVtbikge1xuICAgIGxldCBkYXRhID0gW107XG4gICAgZm9yIChsZXQgaT0wOyBpPHRoaXMucm93czsgaSsrKSB7XG4gICAgICBkYXRhLnB1c2godGhpcy5wYXR0ZXJuW2ldW2NvbHVtbl0gPyAxIDogMCk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgZ2V0IHJvd3MoKSB7XG4gICAgcmV0dXJuIHRoaXMucGF0dGVybi5sZW5ndGg7XG4gIH1cbiAgc2V0IHJvd3Modikge1xuICAgIGxldCBwcmV2aW91cyA9IHRoaXMucGF0dGVybi5zbGljZSgwKTtcbiAgICB0aGlzLmNyZWF0ZSh2LHRoaXMuY29sdW1ucyk7XG4gICAgdGhpcy5pdGVyYXRlKChyLGMpID0+IHtcbiAgICAgIGlmIChwcmV2aW91c1tyXSAmJiBwcmV2aW91c1tyXVtjXSkge1xuICAgICAgICB0aGlzLnBhdHRlcm5bcl1bY10gPSBwcmV2aW91c1tyXVtjXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGdldCBjb2x1bW5zKCkge1xuICAgIHJldHVybiB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuICB9XG4gIHNldCBjb2x1bW5zKHYpIHtcbiAgICBsZXQgcHJldmlvdXMgPSB0aGlzLnBhdHRlcm4uc2xpY2UoMCk7XG4gICAgdGhpcy5jcmVhdGUodGhpcy5yb3dzLHYpO1xuICAgIHRoaXMuaXRlcmF0ZSgocixjKSA9PiB7XG4gICAgICBpZiAocHJldmlvdXNbcl0gJiYgcHJldmlvdXNbcl1bY10pIHtcbiAgICAgICAgdGhpcy5wYXR0ZXJuW3JdW2NdID0gcHJldmlvdXNbcl1bY107XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL21vZGVscy9tYXRyaXguanMiLCIndXNlIHN0cmljdCc7XHJcblxyXG5pbXBvcnQgbWF0aCBmcm9tICcuLi91dGlsL21hdGgnO1xyXG5pbXBvcnQgRHJ1bmsgZnJvbSAnLi9kcnVuayc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTZXF1ZW5jZSB7XHJcblxyXG4gICAgY29uc3RydWN0b3Ioc2VxdWVuY2UgPSBbMCwxMCwyMCwzMF0sIG1vZGU9J3VwJywgcG9zaXRpb249ZmFsc2UpIHtcclxuICAgICAgICB0aGlzLnZhbHVlcyA9IHNlcXVlbmNlO1xyXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLnZhbHVlcykpIHtcclxuICAgICAgICAgIHRoaXMudmFsdWVzID0gW3RoaXMudmFsdWVzXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fbW9kZSA9IG1vZGU7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xyXG5cclxuICAgICAgICB0aGlzLmRydW5rV2FsayA9IG5ldyBEcnVuaygwLCB0aGlzLnZhbHVlcy5sZW5ndGggLSAxKTtcclxuXHJcbiAgICAgICAgdGhpcy5zdGFydFZhbHVlcyA9IHtcclxuICAgICAgICAgICd1cCc6IDAsXHJcbiAgICAgICAgICAnZG93bic6IHRoaXMudmFsdWVzLmxlbmd0aCAtIDEsXHJcbiAgICAgICAgICAnZHJ1bmsnOiB+fih0aGlzLnZhbHVlcy5sZW5ndGgvMiksXHJcbiAgICAgICAgICAncmFuZG9tJzogbWF0aC5yaSh0aGlzLnZhbHVlcy5sZW5ndGgpXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMucG9zaXRpb24hPT1mYWxzZSkge1xyXG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpcy5maXJzdDtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgIH1cclxuXHJcbiAgICBnZXQgbW9kZSgpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX21vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IG1vZGUobW9kZSkge1xyXG4gICAgICAgIGlmICghKG1vZGUgPT09ICd1cCcgfHwgbW9kZSA9PT0gJ2Rvd24nIHx8IG1vZGUgPT09ICdyYW5kb20nIHx8IG1vZGUgPT09ICdkcnVuaycpKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBvbmx5IG1vZGVzIGN1cnJlbnRseSBhbGxvd2VkIGFyZTogdXAsIGRvd24sIHJhbmRvbSwgZHJ1bmsnKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9tb2RlID0gbW9kZTtcclxuICAgICAgICBpZiAodGhpcy5wb3NpdGlvbikge1xyXG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHZhbHVlKCkge1xyXG4gICAgICByZXR1cm4gdGhpcy52YWx1ZXNbdGhpcy5wb3NpdGlvbl07XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IHZhbHVlKHYpIHtcclxuICAgICAgdGhpcy5wb3NpdGlvbiA9IHRoaXMudmFsdWVzLmluZGV4T2Yodik7XHJcbiAgICB9XHJcblxyXG4gICAgZmlyc3QoKSB7XHJcbiAgICAgIGlmICh0aGlzLnBvc2l0aW9uIT09ZmFsc2UpIHtcclxuICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xyXG4gICAgICAgIHJldHVybiB0aGlzLm5leHQoKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLnBvc2l0aW9uID0gdGhpcy5zdGFydFZhbHVlc1t0aGlzLl9tb2RlXTtcclxuICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcclxuICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgdXAoKSB7XHJcbiAgICAgIHRoaXMucG9zaXRpb24rKztcclxuICAgICAgdGhpcy5wb3NpdGlvbiAlPSB0aGlzLnZhbHVlcy5sZW5ndGg7XHJcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGRvd24oKSB7XHJcbiAgICAgIHRoaXMucG9zaXRpb24tLTtcclxuICAgICAgaWYgKHRoaXMucG9zaXRpb24gPCAwKSB7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbiA9ICh0aGlzLnBvc2l0aW9uICsgdGhpcy52YWx1ZXMubGVuZ3RoKSAlIHRoaXMudmFsdWVzLmxlbmd0aDtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdGhpcy52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICByYW5kb20oKSB7XHJcbiAgICAgIHRoaXMucG9zaXRpb24gPSBtYXRoLnJpKDAsIHRoaXMudmFsdWVzLmxlbmd0aCk7XHJcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGRydW5rKCkge1xyXG4gICAgICB0aGlzLmRydW5rV2Fsay5tYXggPSB0aGlzLnZhbHVlcy5sZW5ndGg7XHJcbiAgICAgIHRoaXMuZHJ1bmtXYWxrLnZhbHVlID0gdGhpcy5wb3NpdGlvbjtcclxuICAgICAgdGhpcy5wb3NpdGlvbiA9IHRoaXMuZHJ1bmtXYWxrLm5leHQoKTtcclxuICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyogZnV0dXJlIG1ldGhvZHNcclxuICAgIC5ncm91cChzdGFydCxzdG9wKSAtLSBvdXRwdXRzIGEgZ3JvdXAgb2YgbiBpdGVtcyBmcm9tIHRoZSBsaXN0LCB3aXRoIHdyYXBwaW5nXHJcbiAgICAubG9vcChzdGFydCxzdG9wKSAtLSBjb25maW5lcyBzZXF1ZW5jaW5nIHRvIGEgc3Vic2V0IG9mIHRoZSB2YWx1ZXNcclxuICAgICAgICAoY291bGQgZXZlbiBoYXZlIGEgZGlzdGluY3Rpb24gYmV0d2VlbiAub3JpZ2luYWxWYWx1ZXMgYW5kIHRoZSBhcnJheSBvZiB2YWx1ZXMgYmVpbmcgdXNlZClcclxuICAgICovXHJcbn1cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL21vZGVscy9zZXF1ZW5jZS5qcyIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IG1hdGggZnJvbSAnLi4vdXRpbC9tYXRoJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRHJ1bmsge1xuXG4gICAgY29uc3RydWN0b3IobWluPTAsIG1heD05LCB2YWx1ZT0wLCBpbmNyZW1lbnQ9MSwgbG9vcD1mYWxzZSkge1xuICAgICAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5pbmNyZW1lbnQgPSBpbmNyZW1lbnQ7XG4gICAgICAgIHRoaXMubG9vcCA9IGxvb3A7XG4gICAgfVxuXG4gICAgbmV4dCgpIHtcbiAgICAgICAgdGhpcy52YWx1ZSArPSBtYXRoLnBpY2soLTEgKiB0aGlzLmluY3JlbWVudCwgdGhpcy5pbmNyZW1lbnQpO1xuICAgICAgICBpZiAodGhpcy52YWx1ZSA+IHRoaXMubWF4KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5sb29wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5tYXggLSB0aGlzLmluY3JlbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnZhbHVlIDwgdGhpcy5taW4pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5tYXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLm1pbiArIHRoaXMuaW5jcmVtZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9tb2RlbHMvZHJ1bmsuanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5pbXBvcnQgRHJ1bmsgZnJvbSAnLi9kcnVuayc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENvdW50ZXIge1xuXG4gICAgY29uc3RydWN0b3IobWluPTAsIG1heD0xMCwgbW9kZT0ndXAnLCB2YWx1ZT1mYWxzZSkge1xuICAgICAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICAgICAgdGhpcy5kcnVua1dhbGsgPSBuZXcgRHJ1bmsodGhpcy5taW4sIHRoaXMubWF4KTtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUhPT1mYWxzZSkge1xuICAgICAgICAgIHRoaXMubmV4dCA9IHRoaXNbdGhpcy5fbW9kZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5uZXh0ID0gdGhpcy5maXJzdDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldCBtb2RlKG1vZGUpIHtcbiAgICAgICAgaWYgKCEobW9kZSA9PT0gJ3VwJyB8fCBtb2RlID09PSAnZG93bicgfHwgbW9kZSA9PT0gJ3JhbmRvbScgfHwgbW9kZSA9PT0gJ2RydW5rJykpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBvbmx5IG1vZGVzIGN1cnJlbnRseSBhbGxvd2VkIGFyZTogdXAsIGRvd24sIHJhbmRvbSwgZHJ1bmsnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9tb2RlID0gbW9kZTtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUpIHtcbiAgICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IG1vZGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb2RlO1xuICAgIH1cblxuICAgIGZpcnN0KCkge1xuICAgICAgaWYgKHRoaXMudmFsdWUhPT1mYWxzZSkge1xuICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xuICAgICAgICByZXR1cm4gdGhpcy5uZXh0KCk7XG4gICAgICB9XG4gICAgICB0aGlzLnN0YXJ0VmFsdWVzID0ge1xuICAgICAgICAndXAnOiB0aGlzLm1pbixcbiAgICAgICAgJ2Rvd24nOiB0aGlzLm1heCxcbiAgICAgICAgJ2RydW5rJzogfn5tYXRoLmF2ZXJhZ2UodGhpcy5taW4sdGhpcy5tYXgpLFxuICAgICAgICAncmFuZG9tJzogbWF0aC5yaSh0aGlzLm1pbix0aGlzLm1heClcbiAgICAgIH07XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5zdGFydFZhbHVlc1t0aGlzLl9tb2RlXTtcbiAgICAgIHRoaXMubmV4dCA9IHRoaXNbdGhpcy5fbW9kZV07XG4gICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG5cbiAgICB1cCgpIHtcbiAgICAgICAgdGhpcy52YWx1ZSsrO1xuICAgICAgICBpZiAodGhpcy52YWx1ZSA+PSB0aGlzLm1heCkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIGRvd24oKSB7XG4gICAgICAgIHRoaXMudmFsdWUtLTtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUgPCB0aGlzLm1pbikge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWF4O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIHJhbmRvbSgpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IG1hdGgucmkodGhpcy5taW4sIHRoaXMubWF4KTtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgZHJ1bmsoKSB7XG4gICAgICAgIHRoaXMuZHJ1bmtXYWxrLm1pbiA9IHRoaXMubWluO1xuICAgICAgICB0aGlzLmRydW5rV2Fsay5tYXggPSB0aGlzLm1heDtcbiAgICAgICAgdGhpcy5kcnVua1dhbGsudmFsdWUgPSB0aGlzLnZhbHVlO1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5kcnVua1dhbGsubmV4dCgpO1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbW9kZWxzL2NvdW50ZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xubGV0IG1hdGggPSByZXF1aXJlKCcuLi91dGlsL21hdGgnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbi8qKlxuKiBQYW4yRFxuKlxuKiBAZGVzY3JpcHRpb24gSW50ZXJmYWNlIGZvciBtb3ZpbmcgYSBzb3VuZCBhcm91bmQgYW4gYXJyYXkgb2Ygc3BlYWtlcnMuIFNwZWFrZXIgbG9jYXRpb25zIGNhbiBiZSBjdXN0b21pemVkLiBUaGUgaW50ZXJmYWNlIGNhbGN1bGF0ZXMgdGhlIGNsb3NlbmVzcyBvZiB0aGUgc291bmQgc291cmNlIHRvIGVhY2ggc3BlYWtlciBhbmQgcmV0dXJucyB0aGF0IGRpc3RhbmNlIGFzIGEgbnVtZXJpYyB2YWx1ZS5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJwYW4yRFwiPjwvc3Bhbj5cbipcbiogQGV4YW1wbGVcbiogdmFyIHBhbjJkID0gbmV3IE5leHVzLlBhbjJkKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIHBhbjJkID0gbmV3IE5leHVzLlBhbjJEKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMjAwLDIwMF0sXG4qICAgJ3JhbmdlJzogMC41LCAgLy8gZGV0ZWN0aW9uIHJhZGl1cyBvZiBlYWNoIHNwZWFrZXJcbiogICAnbW9kZSc6ICdhYnNvbHV0ZScsICAgLy8gJ2Fic29sdXRlJyBvciAncmVsYXRpdmUnIHNvdW5kIG1vdmVtZW50XG4qICAgJ3NwZWFrZXJzJzogWyAgLy8gdGhlIHNwZWFrZXIgW3gseV0gcG9zaXRpb25zXG4qICAgICAgIFswLjUsMC4yXSxcbiogICAgICAgWzAuNzUsMC4yNV0sXG4qICAgICAgIFswLjgsMC41XSxcbiogICAgICAgWzAuNzUsMC43NV0sXG4qICAgICAgIFswLjUsMC44XSxcbiogICAgICAgWzAuMjUsMC43NV1cbiogICAgICAgWzAuMiwwLjVdLFxuKiAgICAgICBbMC4yNSwwLjI1XVxuKiAgIF1cbiogfSlcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIFwic291cmNlXCIgbm9kZSdzIHBvc2l0aW9uIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgaXMgYW4gYXJyYXkgb2YgdGhlIGFtcGxpdHVkZXMgKDAtMSksIHJlcHJlc2VudGluZyB0aGUgbGV2ZWwgb2YgZWFjaCBzcGVha2VyIChhcyBjYWxjdWxhdGVkIGJ5IGl0cyBkaXN0YW5jZSB0byB0aGUgYXVkaW8gc291cmNlKS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogcGFuMmQub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUGFuMkQgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3JhbmdlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFsyMDAsMjAwXSxcbiAgICAgICdyYW5nZSc6IDAuNSxcbiAgICAgICdtb2RlJzogJ2Fic29sdXRlJyxcbiAgICAgICdzcGVha2Vycyc6IFtcbiAgICAgICAgWzAuNSwwLjJdLFxuICAgICAgICBbMC43NSwwLjI1XSxcbiAgICAgICAgWzAuOCwwLjVdLFxuICAgICAgICBbMC43NSwwLjc1XSxcbiAgICAgICAgWzAuNSwwLjhdLFxuICAgICAgICBbMC4yNSwwLjc1XSxcbiAgICAgICAgWzAuMiwwLjVdLFxuICAgICAgICBbMC4yNSwwLjI1XVxuICAgICAgXVxuICAgIH07XG5cbiAgICBzdXBlcihhcmd1bWVudHMsb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLnZhbHVlID0ge1xuICAgICAgeDogbmV3IFN0ZXAoMCwxLDAsMC41KSxcbiAgICAgIHk6IG5ldyBTdGVwKDAsMSwwLDAuNSlcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgQWJzb2x1dGUgb3IgcmVsYXRpdmUgbW91c2UgaW50ZXJhY3Rpb24uIEluIFwiYWJzb2x1dGVcIiBtb2RlLCB0aGUgc291cmNlIG5vZGUgd2lsbCBqdW1wIHRvIHlvdXIgbW91c2UgcG9zaXRpb24gb24gbW91c2UgY2xpY2suIEluIFwicmVsYXRpdmVcIiBtb2RlLCBpdCBkb2VzIG5vdC5cbiAgICAqL1xuICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZTtcblxuICAgIHRoaXMucG9zaXRpb24gPSB7XG4gICAgICB4OiBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMubW9kZSwnaG9yaXpvbnRhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKSxcbiAgICAgIHk6IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5tb2RlLCd2ZXJ0aWNhbCcsWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKVxuICAgIH07XG4gICAgdGhpcy5wb3NpdGlvbi54LnZhbHVlID0gdGhpcy52YWx1ZS54Lm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5wb3NpdGlvbi55LnZhbHVlID0gdGhpcy52YWx1ZS55Lm5vcm1hbGl6ZWQ7XG5cbiAgICAvKipcbiAgICBBbiBhcnJheSBvZiBzcGVha2VyIGxvY2F0aW9ucy4gVXBkYXRlIHRoaXMgd2l0aCAubW92ZVNwZWFrZXIoKSBvciAubW92ZUFsbFNwZWFrZXJzKClcbiAgICAqL1xuICAgIHRoaXMuc3BlYWtlcnMgPSB0aGlzLnNldHRpbmdzLnNwZWFrZXJzO1xuXG4gICAgLyoqXG4gICAgUmV3cml0ZTogVGhlIG1heGltdW0gZGlzdGFuY2UgZnJvbSBhIHNwZWFrZXIgdGhhdCB0aGUgc291cmNlIG5vZGUgY2FuIGJlIGZvciBpdCB0byBiZSBoZWFyZCBmcm9tIHRoYXQgc3BlYWtlci4gQSBsb3cgcmFuZ2UgKDAuMSkgd2lsbCByZXN1bHQgaW4gc3BlYWtlcnMgb25seSBwbGF5aW5nIHdoZW4gdGhlIHNvdW5kIGlzIHZlcnkgY2xvc2UgaXQuIERlZmF1bHQgaXMgMC41IChoYWxmIG9mIHRoZSBpbnRlcmZhY2UpLlxuICAgICovXG4gICAgdGhpcy5yYW5nZSA9IHRoaXMuc2V0dGluZ3MucmFuZ2U7XG5cbiAgICAvKipcbiAgICBUaGUgY3VycmVudCBsZXZlbHMgZm9yIGVhY2ggc3BlYWtlci4gVGhpcyBpcyBjYWxjdWxhdGVkIHdoZW4gYSBzb3VyY2Ugbm9kZSBvciBzcGVha2VyIG5vZGUgaXMgbW92ZWQgdGhyb3VnaCBpbnRlcmFjdGlvbiBvciBwcm9ncmFtYXRpY2FsbHkuXG4gICAgKi9cbiAgICB0aGlzLmxldmVscyA9IFtdO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgICB0aGlzLmNhbGN1bGF0ZUxldmVscygpO1xuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG5cblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmtub2IpO1xuXG5cbiAgICAvLyBhZGQgc3BlYWtlcnNcbiAgICB0aGlzLnNwZWFrZXJFbGVtZW50cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5zcGVha2Vycy5sZW5ndGg7aSsrKSB7XG4gICAgICBsZXQgc3BlYWtlckVsZW1lbnQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHNwZWFrZXJFbGVtZW50KTtcblxuICAgICAgdGhpcy5zcGVha2VyRWxlbWVudHMucHVzaChzcGVha2VyRWxlbWVudCk7XG4gICAgfVxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG4gICAgICAgIHRoaXMuX21pbkRpbWVuc2lvbiA9IE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpO1xuXG4gICAgICAgIHRoaXMua25vYlJhZGl1cyA9IHtcbiAgICAgICAgICBvZmY6IH5+KHRoaXMuX21pbkRpbWVuc2lvbi8xMDApICogMyArIDUsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMua25vYlJhZGl1cy5vbiA9IHRoaXMua25vYlJhZGl1cy5vZmYgKiAyO1xuXG4gICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoLzIpO1xuICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQvMik7XG4gICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMua25vYlJhZGl1cy5vZmYpO1xuXG4gICAgICAgIGZvciAobGV0IGk9MDtpPHRoaXMuc3BlYWtlcnMubGVuZ3RoO2krKykge1xuICAgICAgICAgIGxldCBzcGVha2VyRWxlbWVudCA9IHRoaXMuc3BlYWtlckVsZW1lbnRzW2ldO1xuICAgICAgICAgIGxldCBzcGVha2VyID0gdGhpcy5zcGVha2Vyc1tpXTtcbiAgICAgICAgICBzcGVha2VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2N4JyxzcGVha2VyWzBdKnRoaXMud2lkdGgpO1xuICAgICAgICAgIHNwZWFrZXJFbGVtZW50LnNldEF0dHJpYnV0ZSgnY3knLHNwZWFrZXJbMV0qdGhpcy5oZWlnaHQpO1xuICAgICAgICAgIHNwZWFrZXJFbGVtZW50LnNldEF0dHJpYnV0ZSgncicsdGhpcy5fbWluRGltZW5zaW9uLzIwICsgNSk7XG4gICAgICAgICAgc3BlYWtlckVsZW1lbnQuc2V0QXR0cmlidXRlKCdmaWxsLW9wYWNpdHknLCAnMCcpO1xuICAgICAgICB9XG5cbiAgICAgIHRoaXMucG9zaXRpb24ueC5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICAgIHRoaXMucG9zaXRpb24ueS5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcblxuICAgICAgICAvLyBuZXh0LCBuZWVkIHRvXG4gICAgICAgIC8vIHJlc2l6ZSBwb3NpdGlvbnNcbiAgICAgICAgLy8gY2FsY3VsYXRlIHNwZWFrZXIgZGlzdGFuY2VzXG4gICAgICB0aGlzLmNhbGN1bGF0ZUxldmVscygpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICB9XG5cbiAgY29sb3JJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5zcGVha2Vycy5sZW5ndGg7aSsrKSB7XG4gICAgICBsZXQgc3BlYWtlckVsZW1lbnQgPSB0aGlzLnNwZWFrZXJFbGVtZW50c1tpXTtcbiAgICAgIHNwZWFrZXJFbGVtZW50LnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgICBzcGVha2VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgfVxuXG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgdGhpcy5rbm9iQ29vcmRpbmF0ZXMgPSB7XG4gICAgICB4OiB0aGlzLnZhbHVlLngubm9ybWFsaXplZCAqIHRoaXMud2lkdGgsXG4gICAgICB5OiB0aGlzLmhlaWdodCAtIHRoaXMudmFsdWUueS5ub3JtYWxpemVkICogdGhpcy5oZWlnaHRcbiAgICB9O1xuXG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkNvb3JkaW5hdGVzLngpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmtub2JDb29yZGluYXRlcy55KTtcbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgdGhpcy5wb3NpdGlvbi54LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5wb3NpdGlvbi55LmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBtb3ZlKCkge1xuICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcbiAgICAgIHRoaXMucG9zaXRpb24ueC51cGRhdGUodGhpcy5tb3VzZSk7XG4gICAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKHRoaXMubW91c2UpO1xuICAgICAgLy8gcG9zaXRpb24ueCBhbmQgcG9zaXRpb24ueSBhcmUgbm9ybWFsaXplZFxuICAgICAgLy8gc28gYXJlIHRoZSBsZXZlbHNcbiAgICAgIC8vIGxpa2VseSBkb24ndCBuZWVkIHRoaXMudmFsdWUgYXQgYWxsIC0tIG9ubHkgdXNlZCBmb3IgZHJhd2luZ1xuICAgICAgLy8gbm90IGdvaW5nIHRvIGJlIGEgJ3N0ZXAnIG9yICdtaW4nIGFuZCAnbWF4JyBpbiB0aGlzIG9uZS5cbiAgICAgIHRoaXMuY2FsY3VsYXRlTGV2ZWxzKCk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5sZXZlbHMpO1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG4gIH1cblxuICByZWxlYXNlKCkge1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBnZXQgbm9ybWFsaXplZCgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogdGhpcy52YWx1ZS54Lm5vcm1hbGl6ZWQsXG4gICAgICB5OiB0aGlzLnZhbHVlLnkubm9ybWFsaXplZFxuICAgIH07XG4gIH1cblxuICBjYWxjdWxhdGVMZXZlbHMoKSB7XG4gICAgdGhpcy52YWx1ZS54LnVwZGF0ZU5vcm1hbCggdGhpcy5wb3NpdGlvbi54LnZhbHVlICk7XG4gICAgdGhpcy52YWx1ZS55LnVwZGF0ZU5vcm1hbCggdGhpcy5wb3NpdGlvbi55LnZhbHVlICk7XG4gICAgdGhpcy5sZXZlbHMgPSBbXTtcbiAgICB0aGlzLnNwZWFrZXJzLmZvckVhY2goKHMsaSkgPT4ge1xuICAgICAgbGV0IGRpc3RhbmNlID0gbWF0aC5kaXN0YW5jZShzWzBdKnRoaXMud2lkdGgsc1sxXSp0aGlzLmhlaWdodCx0aGlzLnBvc2l0aW9uLngudmFsdWUqdGhpcy53aWR0aCwoMS10aGlzLnBvc2l0aW9uLnkudmFsdWUpKnRoaXMuaGVpZ2h0KTtcbiAgICAgIGxldCBsZXZlbCA9IG1hdGguY2xpcCgxLWRpc3RhbmNlLyh0aGlzLnJhbmdlKnRoaXMud2lkdGgpLDAsMSk7XG4gICAgICB0aGlzLmxldmVscy5wdXNoKGxldmVsKTtcbiAgICAgIHRoaXMuc3BlYWtlckVsZW1lbnRzW2ldLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywgbGV2ZWwpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gIE1vdmUgdGhlIGF1ZGlvIHNvdXJjZSBub2RlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG4gIEBwYXJhbSB4IHtudW1iZXJ9IE5ldyB4IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuICBAcGFyYW0geSB7bnVtYmVyfSBOZXcgeSBsb2NhdGlvbiwgbm9ybWFsaXplZCAwLTFcbiAgKi9cbiAgbW92ZVNvdXJjZSh4LHkpIHtcbiAgICBsZXQgbG9jYXRpb24gPSB7XG4gICAgICB4OiB4KnRoaXMud2lkdGgsXG4gICAgICB5OiB5KnRoaXMuaGVpZ2h0XG4gICAgfTtcbiAgICB0aGlzLnBvc2l0aW9uLngudXBkYXRlKGxvY2F0aW9uKTtcbiAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKGxvY2F0aW9uKTtcbiAgICB0aGlzLmNhbGN1bGF0ZUxldmVscygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLmxldmVscyk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBNb3ZlIGEgc3BlYWtlciBub2RlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG4gIEBwYXJhbSBpbmRleCB7bnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlYWtlciB0byBtb3ZlXG4gIEBwYXJhbSB4IHtudW1iZXJ9IE5ldyB4IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuICBAcGFyYW0geSB7bnVtYmVyfSBOZXcgeSBsb2NhdGlvbiwgbm9ybWFsaXplZCAwLTFcbiAgKi9cbiAgbW92ZVNwZWFrZXIoaW5kZXgseCx5KSB7XG5cbiAgICB0aGlzLnNwZWFrZXJzW2luZGV4XSA9IFt4LHldO1xuICAgIHRoaXMuc3BlYWtlckVsZW1lbnRzW2luZGV4XS5zZXRBdHRyaWJ1dGUoJ2N4JywgeCp0aGlzLndpZHRoKTtcbiAgICB0aGlzLnNwZWFrZXJFbGVtZW50c1tpbmRleF0uc2V0QXR0cmlidXRlKCdjeScsIHkqdGhpcy5oZWlnaHQpO1xuICAgIHRoaXMuY2FsY3VsYXRlTGV2ZWxzKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMubGV2ZWxzKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuXG4gIH1cblxuICAvKipcbiAgU2V0IGFsbCBzcGVha2VyIGxvY2F0aW9uc1xuICBAcGFyYW0gbG9jYXRpb25zIHtBcnJheX0gQXJyYXkgb2Ygc3BlYWtlciBsb2NhdGlvbnMuIEVhY2ggaXRlbSBpbiB0aGUgYXJyYXkgc2hvdWxkIGJlIGFuIGFycmF5IG9mIG5vcm1hbGl6ZWQgeCBhbmQgeSBjb29yZGluYXRlcy5cblxuICBzZXRTcGVha2Vycyhsb2NhdGlvbnMpIHtcblxuICB9XG4gICovXG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL3BhbjJkLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcblxuLyoqXG4qIFRpbHRcbipcbiogQGRlc2NyaXB0aW9uIERldmljZSB0aWx0IHNlbnNvciB3aXRoIDIgb3IgMyBheGVzIChkZXBlbmRpbmcgb24geW91ciBkZXZpY2UgYW5kIGJyb3dzZXIpLlxuKlxuKiBAZGVtbyA8c3BhbiBuZXh1cy11aT0ndGlsdCc+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgdGlsdCA9IG5ldyBOZXh1cy5UaWx0KCcjdGFyZ2V0JylcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYXQgYSByZWd1bGFyIGludGVydmFsLCBhcyBsb25nIGFzIHRoaXMgaW50ZXJmYWNlIGlzIGFjdGl2ZSAoc2VlIHRoZSBpbnRlcmZhY2UncyA8aT4uYWN0aXZlPC9pPiBwcm9wZXJ0eSk8YnI+XG4qIFRoZSBldmVudCBkYXRhIGlzIGFuIDxpPm9iamVjdDwvaT4gY29udGFpbmluZyB4IChudW1iZXIpIGFuZCB5IChudW1iZXIpIHByb3BlcnRpZXMgd2hpY2ggcmVwcmVzZW50IHRoZSBjdXJyZW50IHRpbHQgc3RhdGUgb2YgdGhlIGRldmljZS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogdGlsdC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG4qICAgY29uc29sZS5sb2codik7XG4qIH0pXG4qXG4qXG4qL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUaWx0IGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbODAsODBdXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuX2FjdGl2ZSA9IHRydWU7XG5cbiAgICB0aGlzLmluaXQoKTtcblxuICAgIC8vIGFkZCBldmVudCBsaXN0ZW5lciBmb3IgZGV2aWNlIG9yaWVudGF0aW9uXG5cbiAgXHR0aGlzLmJvdW5kVXBkYXRlID0gdGhpcy51cGRhdGUuYmluZCh0aGlzKTtcbiAgLy9cdHRoaXMuYm91bmRNb3pUaWx0ID0gdGhpcy5tb3pUaWx0LmJpbmQodGhpcylcblxuICBcdGlmICh3aW5kb3cuRGV2aWNlT3JpZW50YXRpb25FdmVudCkge1xuICBcdFx0dGhpcy5vcmllbnRhdGlvbkxpc3RlbmVyID0gd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2RldmljZW9yaWVudGF0aW9uJywgdGhpcy5ib3VuZFVwZGF0ZSwgZmFsc2UpO1xuICBcdH0gZWxzZSB7XG4gICAgICB0aGlzLl9hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcbiAgICB9XG5cblxuXG4gICAgICAvKmVsc2UgaWYgKHdpbmRvdy5PcmllbnRhdGlvbkV2ZW50KSB7XG4gIC8vXHQgIFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ01vek9yaWVudGF0aW9uJywgdGhpcy5ib3VuZE1velRpbHQsIGZhbHNlKTtcbiAgXHR9IGVsc2Uge1xuICBcdCAgXHRjb25zb2xlLmxvZygnTm90IHN1cHBvcnRlZCBvbiB5b3VyIGRldmljZSBvciBicm93c2VyLicpO1xuICBcdH0gKi9cblxuXG4gIH1cblxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy50aXRsZSA9IHN2Zy5jcmVhdGUoJ3RleHQnKTtcbiAgICB0aGlzLmNpcmNsZVggPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLmNpcmNsZVkgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgICB0aGlzLmNpcmNsZVogPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgIHRoaXMuYmFyWCA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmJhclkgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG4gICAgdGhpcy5iYXJaID0gc3ZnLmNyZWF0ZSgncGF0aCcpO1xuXG4gICAgdGhpcy5iYXJYMiA9IHN2Zy5jcmVhdGUoJ3BhdGgnKTtcbiAgICB0aGlzLmJhclkyID0gc3ZnLmNyZWF0ZSgncGF0aCcpO1xuICAgIHRoaXMuYmFyWjIgPSBzdmcuY3JlYXRlKCdwYXRoJyk7XG5cbiAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC44Jyk7XG4gICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScsJzAuOCcpO1xuICAgIHRoaXMuYmFyWi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLCcwLjgnKTtcbiAgICB0aGlzLmJhclgyLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScsJzAuOCcpO1xuICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC44Jyk7XG4gICAgdGhpcy5iYXJaMi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLCcwLjgnKTtcblxuICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLndpZHRoKjMvMTIpO1xuICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmhlaWdodCozLzQpO1xuICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ3InLHRoaXMuaGVpZ2h0LzEwKTtcbiAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC40Jyk7XG5cbiAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdjeCcsdGhpcy53aWR0aCo2LzEyKTtcbiAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQqMy80KTtcbiAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmhlaWdodC8xMCk7XG4gICAgdGhpcy5jaXJjbGVZLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScsJzAuNCcpO1xuXG4gICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMud2lkdGgqOS8xMik7XG4gICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgnY3knLHRoaXMuaGVpZ2h0KjMvNCk7XG4gICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgncicsdGhpcy5oZWlnaHQvMTApO1xuICAgIHRoaXMuY2lyY2xlWi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLCcwLjQnKTtcblxuXG4gICAgdGhpcy5iYXJYLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG4gICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG4gICAgdGhpcy5iYXJaLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG5cbiAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICB0aGlzLmJhclkuc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcblxuICAgIHRoaXMuYmFyWDIuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLE1hdGgucm91bmQodGhpcy5oZWlnaHQvMzApKTtcbiAgICB0aGlzLmJhclkyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJyxNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0LzMwKSk7XG4gICAgdGhpcy5iYXJaMi5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsTWF0aC5yb3VuZCh0aGlzLmhlaWdodC8zMCkpO1xuXG4gICAgdGhpcy5iYXJYMi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAnbm9uZScpO1xuICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZSgnZmlsbCcsICdub25lJyk7XG5cblxuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCd4Jyx0aGlzLndpZHRoLzIpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCd5Jyx0aGlzLmhlaWdodC8zKzcpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdmb250LXNpemUnLCcxNXB4Jyk7XG4gICAgdGhpcy50aXRsZS5zZXRBdHRyaWJ1dGUoJ2ZvbnQtd2VpZ2h0JywnYm9sZCcpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdsZXR0ZXItc3BhY2luZycsJzJweCcpO1xuICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdvcGFjaXR5JywnMC43Jyk7XG4gICAgdGhpcy50aXRsZS5zZXRBdHRyaWJ1dGUoJ3RleHQtYW5jaG9yJywnbWlkZGxlJyk7XG4gICAgdGhpcy50aXRsZS50ZXh0Q29udGVudCA9ICdUSUxUJztcblxuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2lyY2xlWCk7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2lyY2xlWSk7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2lyY2xlWik7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJYKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJZKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJaKTtcblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhclgyKTtcbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJZMik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuYmFyWjIpO1xuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudGl0bGUpO1xuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIGlmICh0aGlzLl9hY3RpdmUpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG4gICAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLmxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubGlnaHQpO1xuICAgICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLmxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubGlnaHQpO1xuICAgICAgdGhpcy5iYXJaLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhclgyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhclkyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5saWdodCk7XG4gICAgICB0aGlzLnRpdGxlLnNldEF0dHJpYnV0ZSgnZmlsbCcsdGhpcy5jb2xvcnMubGlnaHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuICAgICAgdGhpcy5jaXJjbGVZLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuICAgICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWDIuc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMuYmFyWjIuc2V0QXR0cmlidXRlKCdzdHJva2UnLHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcbiAgICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKCdmaWxsJyx0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG4gICAgfVxuXG4gIH1cblxuICB1cGRhdGUodikge1xuICAgIGlmICh0aGlzLl9hY3RpdmUpe1xuXG4gICAgICBsZXQgeSA9IHYuYmV0YTtcbiAgICAgIGxldCB4ID0gdi5nYW1tYTtcbiAgICAgIGxldCB6ID0gdi5hbHBoYTtcblxuICAgICAgLy8gdGFrZSB0aGUgb3JpZ2luYWwgLTkwIHRvIDkwIHNjYWxlIGFuZCBub3JtYWxpemUgaXQgMC0xXG4gICAgICB4ID0gbWF0aC5zY2FsZSh4LC05MCw5MCwwLDEpO1xuICAgICAgeSA9IG1hdGguc2NhbGUoeSwtOTAsOTAsMCwxKTtcbiAgICAgIHogPSBtYXRoLnNjYWxlKHosMCwzNjAsMCwxKTtcblxuXG4gICAgICBsZXQgaGFuZGxlUG9pbnRzID0ge1xuICAgICAgICBzdGFydDogTWF0aC5QSSoxLjUsXG4gICAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHgsMCwwLjUsTWF0aC5QSSoxLjUsTWF0aC5QSSowLjUpICwgTWF0aC5QSSowLjUsIE1hdGguUEkqMS41IClcbiAgICAgIH07XG4gICAgICBsZXQgaGFuZGxlMlBvaW50cyA9IHtcbiAgICAgICAgc3RhcnQ6IE1hdGguUEkqMi41LFxuICAgICAgICBlbmQ6IG1hdGguY2xpcCggbWF0aC5zY2FsZSh4LDAuNSwxLE1hdGguUEkqMi41LE1hdGguUEkqMS41KSAsIE1hdGguUEkqMS41LCBNYXRoLlBJKjIuNSApXG4gICAgICB9O1xuXG4gICAgICBsZXQgaGFuZGxlUGF0aCA9IHN2Zy5hcmModGhpcy5jaXJjbGVYLmN4LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWC5jeS5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVguci5iYXNlVmFsLnZhbHVlLCBoYW5kbGVQb2ludHMuc3RhcnQsIGhhbmRsZVBvaW50cy5lbmQpO1xuICAgICAgbGV0IGhhbmRsZTJQYXRoID0gc3ZnLmFyYyh0aGlzLmNpcmNsZVguY3guYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVYLmN5LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWC5yLmJhc2VWYWwudmFsdWUsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgICAgdGhpcy5iYXJYLnNldEF0dHJpYnV0ZSgnZCcsIGhhbmRsZVBhdGgpO1xuICAgICAgdGhpcy5iYXJYMi5zZXRBdHRyaWJ1dGUoJ2QnLCBoYW5kbGUyUGF0aCk7XG5cblxuXG5cblxuICAgICAgaGFuZGxlUG9pbnRzID0ge1xuICAgICAgICBzdGFydDogTWF0aC5QSSoxLjUsXG4gICAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHksMCwwLjUsTWF0aC5QSSoxLjUsTWF0aC5QSSowLjUpICwgTWF0aC5QSSowLjUsIE1hdGguUEkqMS41IClcbiAgICAgIH07XG4gICAgICBoYW5kbGUyUG9pbnRzID0ge1xuICAgICAgICBzdGFydDogTWF0aC5QSSoyLjUsXG4gICAgICAgIGVuZDogbWF0aC5jbGlwKCBtYXRoLnNjYWxlKHksMC41LDEsTWF0aC5QSSoyLjUsTWF0aC5QSSoxLjUpICwgTWF0aC5QSSoxLjUsIE1hdGguUEkqMi41IClcbiAgICAgIH07XG5cbiAgICAgIGhhbmRsZVBhdGggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWS5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVkuY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVZLnIuYmFzZVZhbC52YWx1ZSwgaGFuZGxlUG9pbnRzLnN0YXJ0LCBoYW5kbGVQb2ludHMuZW5kKTtcbiAgICAgIGhhbmRsZTJQYXRoID0gc3ZnLmFyYyh0aGlzLmNpcmNsZVkuY3guYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVZLmN5LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWS5yLmJhc2VWYWwudmFsdWUsIGhhbmRsZTJQb2ludHMuc3RhcnQsIGhhbmRsZTJQb2ludHMuZW5kKTtcblxuICAgICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZSgnZCcsIGhhbmRsZVBhdGgpO1xuICAgICAgdGhpcy5iYXJZMi5zZXRBdHRyaWJ1dGUoJ2QnLCBoYW5kbGUyUGF0aCk7XG5cblxuXG5cblxuXG4gICAgICBoYW5kbGVQb2ludHMgPSB7XG4gICAgICAgIHN0YXJ0OiBNYXRoLlBJKjEuNSxcbiAgICAgICAgZW5kOiBtYXRoLmNsaXAoIG1hdGguc2NhbGUoeiwwLDAuNSxNYXRoLlBJKjEuNSxNYXRoLlBJKjAuNSkgLCBNYXRoLlBJKjAuNSwgTWF0aC5QSSoxLjUgKVxuICAgICAgfTtcbiAgICAgIGhhbmRsZTJQb2ludHMgPSB7XG4gICAgICAgIHN0YXJ0OiBNYXRoLlBJKjIuNSxcbiAgICAgICAgZW5kOiBtYXRoLmNsaXAoIG1hdGguc2NhbGUoeiwwLjUsMSxNYXRoLlBJKjIuNSxNYXRoLlBJKjEuNSkgLCBNYXRoLlBJKjEuNSwgTWF0aC5QSSoyLjUgKVxuICAgICAgfTtcblxuICAgICAgaGFuZGxlUGF0aCA9IHN2Zy5hcmModGhpcy5jaXJjbGVaLmN4LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWi5jeS5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVouci5iYXNlVmFsLnZhbHVlLCBoYW5kbGVQb2ludHMuc3RhcnQsIGhhbmRsZVBvaW50cy5lbmQpO1xuICAgICAgaGFuZGxlMlBhdGggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWi5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVouY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVaLnIuYmFzZVZhbC52YWx1ZSwgaGFuZGxlMlBvaW50cy5zdGFydCwgaGFuZGxlMlBvaW50cy5lbmQpO1xuXG4gICAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKCdkJywgaGFuZGxlUGF0aCk7XG4gICAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZSgnZCcsIGhhbmRsZTJQYXRoKTtcblxuXG4gICAgICAvKlxuXG4gICAgICBsZXQgcG9pbnRzWCA9IHtcbiAgICAgICAgc3RhcnQ6IDAsXG4gICAgICAgIGVuZDogbWF0aC5zY2FsZSggeCwgMCwgMSwgMCwgTWF0aC5QSSoyIClcbiAgICAgIH07XG5cbiAgICAvLyAgY29uc29sZS5sb2codGhpcy5jaXJjbGVYLmN4LmJhc2VWYWwudmFsdWUpO1xuXG4gICAgICBsZXQgcGF0aFggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWC5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVguY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVYLnIuYmFzZVZhbC52YWx1ZSoyLCBwb2ludHNYLnN0YXJ0LCBwb2ludHNYLmVuZCk7XG5cbiAgICAgIHRoaXMuYmFyWC5zZXRBdHRyaWJ1dGUoJ2QnLHBhdGhYKTsgKi9cblxuICAgICAgLy90aGlzLnRleHRILnRleHRDb250ZW50ID0gbWF0aC5wcnVuZSh4LDIpO1xuICAgICAgLy90aGlzLnRleHRWLnRleHRDb250ZW50ID0gbWF0aC5wcnVuZSh5LDIpO1xuICAgICAgLy9cbiAgICAvLyAgdGhpcy5jaXJjbGVYLnNldEF0dHJpYnV0ZSgnb3BhY2l0eScseCk7XG4gICAgLy8gIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLHkpO1xuICAgIC8vICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKCdvcGFjaXR5Jyx6KTtcblxuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLCB7XG4gICAgICAgIHg6IHgsXG4gICAgICAgIHk6IHksXG4gICAgICAgIHo6IHpcbiAgICAgIH0pO1xuXG4gICAgfVxuXG4gIH1cblxuICBjbGljaygpIHtcbiAgICBpZiAod2luZG93LkRldmljZU9yaWVudGF0aW9uRXZlbnQpIHtcbiAgICAgIHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICBXaGV0aGVyIHRoZSBpbnRlcmZhY2UgaXMgb24gKGVtaXR0aW5nIHZhbHVlcykgb3Igb2ZmIChwYXVzZWQgJiBub3QgZW1pdHRpbmcgdmFsdWVzKS4gU2V0dGluZyB0aGlzIHByb3BlcnR5IHdpbGwgdXBkYXRlIGl0LlxuICBAdHlwZSB7Ym9vbGVhbn1cbiAgKi9cblxuICBnZXQgYWN0aXZlKCkge1xuICAgIHJldHVybiB0aGlzLl9hY3RpdmU7XG4gIH1cblxuICBzZXQgYWN0aXZlKG9uKSB7XG4gICAgdGhpcy5fYWN0aXZlID0gb247XG4gICAgdGhpcy5jb2xvckludGVyZmFjZSgpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGV2aWNlb3JpZW50YXRpb24nLCB0aGlzLmJvdW5kVXBkYXRlLCBmYWxzZSk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvdGlsdC5qcyIsIid1c2Ugc3RyaWN0JztcblxubGV0IGRvbSA9IHJlcXVpcmUoJy4uL3V0aWwvZG9tJyk7XG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5sZXQgU2xpZGVyVGVtcGxhdGUgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL3NsaWRlcnRlbXBsYXRlJyk7XG5sZXQgdG91Y2ggPSByZXF1aXJlKCcuLi91dGlsL3RvdWNoJyk7XG5cblxuXG5jbGFzcyBTaW5nbGVTbGlkZXIgZXh0ZW5kcyBTbGlkZXJUZW1wbGF0ZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnc2NhbGUnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMTIwLDIwXSxcbiAgICAgICdvcmllbnRhdGlvbic6ICd2ZXJ0aWNhbCcsXG4gICAgICAnbW9kZSc6ICdhYnNvbHV0ZScsXG4gICAgICAnc2NhbGUnOiBbMCwxXSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDAsXG4gICAgICAnaGFzS25vYic6IHRydWVcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG5cbiAgICAvKiBldmVudHMgKi9cblxuICAgIGlmICghdG91Y2guZXhpc3RzKSB7XG5cbiAgICAgIHRoaXMuY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgIHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24gPSB7XG4gICAgICAgICAgaW5kZXg6IHRoaXMuaW5kZXgsXG4gICAgICAgICAgdmFsdWU6IHRoaXMudmFsdWVcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5kb3duKCk7XG4gICAgICAgIHRoaXMubXVsdGlzbGlkZXIudmFsdWVzW3RoaXMuaW5kZXhdID0gdGhpcy52YWx1ZTtcbiAgICAgIH07XG4gICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgKGUpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICBpZiAoIXRoaXMub2Zmc2V0KSB7XG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IGRvbS5maW5kUG9zaXRpb24odGhpcy5lbGVtZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVNb3VzZShlLHRoaXMub2Zmc2V0KTtcbiAgICAgICAgICB0aGlzLmRvd24oKTtcbiAgICAgICAgICB0aGlzLm11bHRpc2xpZGVyLnZhbHVlc1t0aGlzLmluZGV4XSA9IHRoaXMudmFsdWU7XG4gICAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJwb2xhdGlvbikge1xuICAgICAgICAgICAgbGV0IGRpc3RhbmNlID0gTWF0aC5hYnModGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uLmluZGV4LXRoaXMuaW5kZXgpO1xuICAgICAgICAgICAgaWYgKCBkaXN0YW5jZSA+IDEgKSB7XG4gICAgICAgICAgICAgIGxldCBsb3cgPSBNYXRoLm1pbih0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24uaW5kZXgsdGhpcy5pbmRleCk7XG4gICAgICAgICAgICAgIGxldCBoaWdoID0gTWF0aC5tYXgodGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uLmluZGV4LHRoaXMuaW5kZXgpO1xuICAgICAgICAgICAgICBsZXQgbG93VmFsdWUgPSB0aGlzLm11bHRpc2xpZGVyLnNsaWRlcnNbbG93XS52YWx1ZTtcbiAgICAgICAgICAgICAgbGV0IGhpZ2hWYWx1ZSA9IHRoaXMubXVsdGlzbGlkZXIuc2xpZGVyc1toaWdoXS52YWx1ZTtcbiAgICAgICAgICAgICAgZm9yIChsZXQgaT1sb3c7aTxoaWdoO2krKykge1xuICAgICAgICAgICAgICAgIHRoaXMubXVsdGlzbGlkZXIuc2xpZGVyc1tpXS52YWx1ZSA9IG1hdGguaW50ZXJwKCAoaS1sb3cpL2Rpc3RhbmNlLCBsb3dWYWx1ZSwgaGlnaFZhbHVlICk7XG4gICAgICAgICAgICAgICAgbGV0IHNtb290aGVkVmFsdWUgPSB0aGlzLm11bHRpc2xpZGVyLnNsaWRlcnNbaV0udmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbaV0gPSBzbW9vdGhlZFZhbHVlO1xuICAgICAgICAgICAgICAgIHRoaXMubXVsdGlzbGlkZXIudXBkYXRlKGksc21vb3RoZWRWYWx1ZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24gPSB7XG4gICAgICAgICAgICBpbmRleDogdGhpcy5pbmRleCxcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cblxuICAgICAgdGhpcy5tb3ZlID0gKCkgPT4ge1xuICAgICAgfTtcbiAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCAoZSkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tdWx0aXNsaWRlci5pbnRlcmFjdGluZykge1xuICAgICAgICAgIGlmICghdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbih0aGlzLmVsZW1lbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLm1vdXNlID0gZG9tLmxvY2F0ZU1vdXNlKGUsdGhpcy5vZmZzZXQpO1xuICAgICAgICAgIHRoaXMuc2xpZGUoKTtcbiAgICAgICAgICB0aGlzLm11bHRpc2xpZGVyLnZhbHVlc1t0aGlzLmluZGV4XSA9IHRoaXMudmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG5cbiAgICAgIHRoaXMucmVsZWFzZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5tdWx0aXNsaWRlci5pbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24gPSBmYWxzZTtcbiAgICAgIH07XG4gICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbdGhpcy5pbmRleF0gPSB0aGlzLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgICAgdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbdGhpcy5pbmRleF0gPSB0aGlzLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIH1cblxuICAgIHRoaXMuY3VzdG9tU3R5bGUoKTtcbiAgfVxuXG4gIGN1c3RvbVN0eWxlKCkge1xuXG4gICAgLyogc3R5bGUgY2hhbmdlcyAqL1xuXG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd4JywwKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsJ3RyYW5zbGF0ZSgwLDApJyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsMCk7IC8vIGNvcm5lciByYWRpdXNcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3J5JywwKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx0aGlzLndpZHRoKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsdGhpcy5oZWlnaHQpO1xuXG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneCcsMCk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywndHJhbnNsYXRlKDAsMCknKTtcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeCcsMCk7IC8vIGNvcm5lciByYWRpdXNcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeScsMCk7XG4gICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgnd2lkdGgnLHRoaXMud2lkdGgpO1xuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsdGhpcy5oZWlnaHQpO1xuXG4gIH1cblxufVxuXG4vKipcbiogTXVsdGlzbGlkZXJcbipcbiogQGRlc2NyaXB0aW9uIE11bHRpc2xpZGVyXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwibXVsdGlzbGlkZXJcIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBtdWx0aXNsaWRlciA9IG5ldyBOZXh1cy5NdWx0aXNsaWRlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBtdWx0aXNsaWRlciA9IG5ldyBOZXh1cy5NdWx0aXNsaWRlcignI3RhcmdldCcse1xuKiAgJ3NpemUnOiBbMjAwLDEwMF0sXG4qICAnbnVtYmVyT2ZTbGlkZXJzJzogNSxcbiogICdtaW4nOiAwLFxuKiAgJ21heCc6IDEsXG4qICAnc3RlcCc6IDAsXG4qICAndmFsdWVzJzogWzAuNywwLjcsMC43LDAuNywwLjddXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG4qIFRoZSBldmVudCBkYXRhIGFuIG9iamVjdCBjb250YWluaW5nIDxpPmluZGV4PC9pPiBhbmQgPGk+dmFsdWU8L2k+IHByb3BlcnRpZXNcbipcbiogQG91dHB1dGV4YW1wbGVcbiogbXVsdGlzbGlkZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuKiAgIGNvbnNvbGUubG9nKHYpO1xuKiB9KVxuKlxuKi9cblxuLypcblByb3BlcnRpZXNcbi52YWx1ZXNcblxuKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTXVsdGlzbGlkZXIgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3ZhbHVlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFsyMDAsMTAwXSxcbiAgICAgICdudW1iZXJPZlNsaWRlcnMnOiA1LFxuICAgICAgJ21pbic6IDAsXG4gICAgICAnbWF4JzogMSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZXMnOiBbMC43LDAuNywwLjcsMC43LDAuN11cbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5fbnVtYmVyT2ZTbGlkZXJzID0gdGhpcy5zZXR0aW5ncy5udW1iZXJPZlNsaWRlcnM7XG4gICAgdGhpcy52YWx1ZXMgPSB0aGlzLnNldHRpbmdzLnZhbHVlcztcblxuICAgIHRoaXMuc2xpZGVycyA9IFtdO1xuXG4gICAgdGhpcy5pbnRlcmFjdGluZyA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG4gICAgbGV0IG1pbiA9IHRoaXMuc2V0dGluZ3MubWluO1xuICAgIGxldCBtYXggPSB0aGlzLnNldHRpbmdzLm1heDtcbiAgICBsZXQgc3RlcCA9IHRoaXMuc2V0dGluZ3Muc3RlcDtcblxuICAgIGlmICh0aGlzLnNsaWRlcnMubGVuZ3RoKSB7XG4gICAgICBtaW4gPSB0aGlzLnNsaWRlcnNbMF0ubWluO1xuICAgICAgbWF4ID0gdGhpcy5zbGlkZXJzWzBdLm1heDtcbiAgICAgIHN0ZXAgPSB0aGlzLnNsaWRlcnNbMF0uc3RlcDtcbiAgICB9XG5cbiAgICB0aGlzLnNsaWRlcnMgPSBbXTtcblxuICAgIGZvciAobGV0IGk9MDtpPHRoaXMuX251bWJlck9mU2xpZGVycztpKyspIHtcbiAgICAgIGxldCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG5cbiAgICAgIGxldCBzbGlkZXIgPSBuZXcgU2luZ2xlU2xpZGVyKGNvbnRhaW5lciwge1xuICAgICAgICAgIHNjYWxlOiBbbWluLG1heF0sXG4gICAgICAgICAgc3RlcDogc3RlcCxcbiAgICAgICAgICBtb2RlOiAnYWJzb2x1dGUnLFxuICAgICAgICAgIG9yaWVudGF0aW9uOiAndmVydGljYWwnLFxuICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlc1tpXSxcbiAgICAgICAgICBoYXNLbm9iOiBmYWxzZSxcbiAgICAgICAgICBjb21wb25lbnQ6IHRydWUsXG4gICAgICAgIH0sdGhpcy51cGRhdGUuYmluZCh0aGlzLGkpKTtcbiAgICAgIHNsaWRlci5tdWx0aXNsaWRlciA9IHRoaXM7XG5cbiAgICAgIHNsaWRlci5pbmRleCA9IGk7XG4gICAgICBpZiAodG91Y2guZXhpc3RzKSB7XG4gICAgICAgIHNsaWRlci5iYXIuaW5kZXggPSBpO1xuICAgICAgICBzbGlkZXIuZmlsbGJhci5pbmRleCA9IGk7XG4gICAgICAgIHNsaWRlci5wcmVDbGljayA9IHNsaWRlci5wcmVNb3ZlID0gc2xpZGVyLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICAgICAgc2xpZGVyLmNsaWNrID0gc2xpZGVyLm1vdmUgPSBzbGlkZXIucmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgICBzbGlkZXIucHJlVG91Y2ggPSBzbGlkZXIucHJlVG91Y2hNb3ZlID0gc2xpZGVyLnByZVRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgICBzbGlkZXIudG91Y2ggPSBzbGlkZXIudG91Y2hNb3ZlID0gc2xpZGVyLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNsaWRlcnMucHVzaChzbGlkZXIpO1xuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cbiAgICB9XG4gICAgaWYgKHRvdWNoLmV4aXN0cykge1xuICAgICAgdGhpcy5hZGRUb3VjaExpc3RlbmVycygpO1xuICAgIH1cblxuICB9XG5cbiAgY29sb3JJbnRlcmZhY2UoKSB7XG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5zbGlkZXJzLmxlbmd0aDtpKyspIHtcbiAgICAgIHRoaXMuc2xpZGVyc1tpXS5jb2xvcnMgPSB0aGlzLmNvbG9ycztcbiAgICAgIHRoaXMuc2xpZGVyc1tpXS5jb2xvckludGVyZmFjZSgpO1xuICAgIH1cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBsZXQgc2xpZGVyV2lkdGggPSB0aGlzLndpZHRoIC8gdGhpcy5zbGlkZXJzLmxlbmd0aDtcbiAgICBsZXQgc2xpZGVySGVpZ2h0ID0gdGhpcy5oZWlnaHQ7XG5cbiAgICBmb3IgKGxldCBpPTA7aTx0aGlzLnNsaWRlcnMubGVuZ3RoO2krKykge1xuICAgICAgdGhpcy5zbGlkZXJzW2ldLnJlc2l6ZShzbGlkZXJXaWR0aCxzbGlkZXJIZWlnaHQpO1xuICAgICAgdGhpcy5zbGlkZXJzW2ldLmN1c3RvbVN0eWxlKCk7XG4gICAgfVxuXG5cbiAgfVxuXG4gIHVwZGF0ZShpbmRleCx2YWx1ZSkge1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG4gICAgICAnaW5kZXgnOiBpbmRleCxcbiAgICAgICd2YWx1ZSc6IHZhbHVlXG4gICAgfSk7XG4gIH1cblxuICBhZGRUb3VjaExpc3RlbmVycygpIHtcblxuICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gKCkgPT4ge307XG4gICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSAoKSA9PiB7fTtcbiAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9ICgpID0+IHt9O1xuXG4gICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGZhbHNlO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoZSkgPT4ge1xuICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRYLGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRZKTtcbiAgICAgIGxldCBzbGlkZXIgPSB0aGlzLnNsaWRlcnNbZWxlbWVudC5pbmRleF07XG4gICAgICBpZiAoIXNsaWRlci5vZmZzZXQpIHtcbiAgICAgICAgc2xpZGVyLm9mZnNldCA9IGRvbS5maW5kUG9zaXRpb24oc2xpZGVyLmVsZW1lbnQpO1xuICAgICAgfVxuICAgICAgc2xpZGVyLm1vdXNlID0gZG9tLmxvY2F0ZU1vdXNlKGUsc2xpZGVyLm9mZnNldCk7XG4gICAgICBzbGlkZXIuZG93bigpO1xuICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGVsZW1lbnQuaW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIChlKSA9PiB7XG4gICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFgsZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFkpO1xuICAgICAgbGV0IHNsaWRlciA9IHRoaXMuc2xpZGVyc1tlbGVtZW50LmluZGV4XTtcbiAgICAgIGlmICghc2xpZGVyLm9mZnNldCkge1xuICAgICAgICBzbGlkZXIub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbihzbGlkZXIuZWxlbWVudCk7XG4gICAgICB9XG4gICAgICBzbGlkZXIubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSxzbGlkZXIub2Zmc2V0KTtcbiAgICAgIGlmIChlbGVtZW50LmluZGV4IT09dGhpcy5jdXJyZW50RWxlbWVudCkge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50RWxlbWVudCA+PSAwKSB7XG4gICAgICAgICAgbGV0IHBhc3RzbGlkZXIgPSB0aGlzLnNsaWRlcnNbdGhpcy5jdXJyZW50RWxlbWVudF07XG4gICAgICAgICAgcGFzdHNsaWRlci51cCgpO1xuICAgICAgICB9XG4gICAgICAgIHNsaWRlci5kb3duKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzbGlkZXIuc2xpZGUoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBlbGVtZW50LmluZGV4O1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9KTtcblxuICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIChlKSA9PiB7XG4gICAgICAvLyBubyB0b3VjaGVzIHRvIGNhbGN1bGF0ZSBiZWNhdXNlIG5vbmUgcmVtYWluaW5nXG4gICAgICBsZXQgc2xpZGVyID0gdGhpcy5zbGlkZXJzW3RoaXMuY3VycmVudEVsZW1lbnRdO1xuICAgICAgc2xpZGVyLnVwKCk7XG4gICAgICB0aGlzLmludGVyYWN0aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZmFsc2U7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gIH1cblxuICAvKipcbiAgR2V0IG9yIHNldCB0aGUgbnVtYmVyIG9mIHNsaWRlcnNcbiAgQHR5cGUge051bWJlcn1cbiAgKi9cbiAgZ2V0IG51bWJlck9mU2xpZGVycygpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXJzLmxlbmd0aDtcbiAgfVxuXG4gIHNldCBudW1iZXJPZlNsaWRlcnModikge1xuICAgIGlmICh2PT09dGhpcy5zbGlkZXJzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNsaWRlcnMuZm9yRWFjaCgoc2xpZGVyKT0+e1xuICAgICAgc2xpZGVyLmRlc3Ryb3koKTtcbiAgICB9KTtcbiAgICB0aGlzLmVtcHR5KCk7XG4gICAgdGhpcy5fbnVtYmVyT2ZTbGlkZXJzID0gdjtcbiAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG4gIH1cblxuXG5cbiAgLyoqXG4gIExvd2VyIGxpbWl0IG9mIHRoZSBtdWx0aXNsaWRlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBtdWx0aXNsaWRlci5taW4gPSAxMDAwO1xuICAqL1xuICBnZXQgbWluKCkge1xuICAgIHJldHVybiB0aGlzLnNsaWRlcnNbMF0ubWluO1xuICB9XG4gIHNldCBtaW4odikge1xuICAgIHRoaXMuc2xpZGVycy5mb3JFYWNoKChzbGlkZXIpPT57XG4gICAgICBzbGlkZXIubWluID0gdjtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICBVcHBlciBsaW1pdCBvZiB0aGUgbXVsdGlzbGlkZXIncyBvdXRwdXQgcmFuZ2VcbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgbXVsdGlzbGlkZXIubWF4ID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXJzWzBdLm1heDtcbiAgfVxuICBzZXQgbWF4KHYpIHtcbiAgICB0aGlzLnNsaWRlcnMuZm9yRWFjaCgoc2xpZGVyKT0+e1xuICAgICAgc2xpZGVyLm1heCA9IHY7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBtdWx0aXNsaWRlcidzIHZhbHVlIGNoYW5nZXMgYnkuXG4gIEB0eXBlIHtudW1iZXJ9XG4gIEBleGFtcGxlIG11bHRpc2xpZGVyLnN0ZXAgPSA1O1xuICAqL1xuICBnZXQgc3RlcCgpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXJzWzBdLnN0ZXA7XG4gIH1cbiAgc2V0IHN0ZXAodikge1xuICAgIHRoaXMuc2xpZGVycy5mb3JFYWNoKChzbGlkZXIpPT57XG4gICAgICBzbGlkZXIuc3RlcCA9IHY7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgU2V0IHRoZSB2YWx1ZSBvZiBhbiBpbmRpdmlkdWFsIHNsaWRlclxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gU2xpZGVyIGluZGV4XG4gIEBwYXJhbSB2YWx1ZSB7bnVtYmVyfSBOZXcgc2xpZGVyIHZhbHVlXG4gIEBleGFtcGxlXG4gIC8vIFNldCB0aGUgZmlyc3Qgc2xpZGVyIHRvIHZhbHVlIDAuNVxuICBtdWx0aXNsaWRlci5zZXRTbGlkZXIoMCwwLjUpXG4gICovXG4gIHNldFNsaWRlcihpbmRleCx2YWx1ZSkge1xuICAgIHRoaXMuc2xpZGVyc1tpbmRleF0udmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgJ2luZGV4JzogaW5kZXgsXG4gICAgICAndmFsdWUnOiB2YWx1ZVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gIFNldCB0aGUgdmFsdWUgb2YgYWxsIHNsaWRlcnMgYXQgb25jZS4gSWYgdGhlIHNpemUgb2YgdGhlIGlucHV0IGFycmF5IGRvZXMgbm90IG1hdGNoIHRoZSBjdXJyZW50IG51bWJlciBvZiBzbGlkZXJzLCB0aGUgdmFsdWUgYXJyYXkgd2lsbCByZXBlYXQgdW50aWwgYWxsIHNsaWRlcnMgaGF2ZSBiZWVuIHNldC4gSS5lLiBhbiBpbnB1dCBhcnJheSBvZiBsZW5ndGggMSB3aWxsIHNldCBhbGwgc2xpZGVycyB0byB0aGF0IHZhbHVlLlxuICBAcGFyYW0gdmFsdWVzIHtBcnJheX0gQWxsIHNsaWRlciB2YWx1ZXNcbiAgQGV4YW1wbGVcbiAgbXVsdGlzbGlkZXIuc2V0QWxsU2xpZGVycyhbMC4yLDAuMywwLjQsMC41LDAuNl0pXG4gICovXG4gIHNldEFsbFNsaWRlcnModmFsdWVzKSB7XG4gICAgdGhpcy52YWx1ZXMgPSB2YWx1ZXM7XG4gICAgdGhpcy5zbGlkZXJzLmZvckVhY2goKHNsaWRlcixpKT0+e1xuICAgICAgc2xpZGVyLnZhbHVlID0gdmFsdWVzW2kldmFsdWVzLmxlbmd0aF07XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgICAnaW5kZXgnOiBpLFxuICAgICAgICAndmFsdWUnOiBzbGlkZXIudmFsdWVcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL211bHRpc2xpZGVyLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBJbnRlcmZhY2UgPSByZXF1aXJlKCcuLi9jb3JlL2ludGVyZmFjZScpO1xubGV0IFN0ZXAgPSByZXF1aXJlKCcuLi9tb2RlbHMvc3RlcCcpO1xuaW1wb3J0ICogYXMgSW50ZXJhY3Rpb24gZnJvbSAnLi4vdXRpbC9pbnRlcmFjdGlvbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNsaWRlclRlbXBsYXRlIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcihhcmdzLG9wdGlvbnMsZGVmYXVsdHMpIHtcblxuICAgIHN1cGVyKGFyZ3Msb3B0aW9ucyxkZWZhdWx0cyk7XG5cbiAgICB0aGlzLm9yaWVudGF0aW9uID0gdGhpcy5zZXR0aW5ncy5vcmllbnRhdGlvbjtcblxuICAvLyAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXG4gICAgdGhpcy5oYXNLbm9iID0gdGhpcy5zZXR0aW5ncy5oYXNLbm9iO1xuXG4gICAgLy8gdGhpcy5zdGVwIHNob3VsZCBldmVudHVhbGx5IGJlIGdldC9zZXRcbiAgICAvLyB1cGRhdGluZyBpdCB3aWxsIHVwZGF0ZSB0aGUgX3ZhbHVlIHN0ZXAgbW9kZWxcbiAgLy8gIHRoaXMuc3RlcCA9IHRoaXMuc2V0dGluZ3Muc3RlcDsgLy8gZmxvYXRcblxuICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5zY2FsZVswXSwgdGhpcy5zZXR0aW5ncy5zY2FsZVsxXSwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLHRoaXMub3JpZW50YXRpb24sWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblxuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnZhbHVlKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLmJhciA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmZpbGxiYXIgPSBzdmcuY3JlYXRlKCdyZWN0Jyk7XG4gICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZSgnY2lyY2xlJyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXIpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmZpbGxiYXIpO1xuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmtub2IpO1xuXG4gICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG5cblxuXG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuXG5cbiAgICBpZiAoIXRoaXMuc2V0dGluZ3Mub3JpZW50YXRpb24pIHtcbiAgICAgIGlmICh0aGlzLndpZHRoIDwgdGhpcy5oZWlnaHQpIHtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvbiA9ICd2ZXJ0aWNhbCc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uID0gJ2hvcml6b250YWwnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCB4LCB5LCB3LCBoLCBiYXJPZmZzZXQsIGNvcm5lclJhZGl1cztcbiAgICB0aGlzLmtub2JEYXRhID0ge1xuICAgICAgbGV2ZWw6IDAsXG4gICAgICByOiAwXG4gICAgfTtcblxuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAndmVydGljYWwnKSB7XG4gICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMud2lkdGggLyAyO1xuICAgIFx0eCA9IHRoaXMud2lkdGgvMjtcbiAgICBcdHkgPSAwO1xuICAgIFx0dyA9IHRoaXMudGhpY2tuZXNzO1xuICAgIFx0aCA9IHRoaXMuaGVpZ2h0O1xuICAgICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MgKiAwLjg7XG4gICAgXHR0aGlzLmtub2JEYXRhLmxldmVsID0gaC10aGlzLm5vcm1hbGl6ZWQqaDtcbiAgICAgIGJhck9mZnNldCA9ICd0cmFuc2xhdGUoJyt0aGlzLnRoaWNrbmVzcyooLTEpLzIrJywwKSc7XG4gICAgICBjb3JuZXJSYWRpdXMgPSB3LzI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGhpY2tuZXNzID0gdGhpcy5oZWlnaHQgLyAyO1xuICAgIFx0eCA9IDA7XG4gICAgXHR5ID0gdGhpcy5oZWlnaHQvMjtcbiAgICBcdHcgPSB0aGlzLndpZHRoO1xuICAgIFx0aCA9IHRoaXMudGhpY2tuZXNzO1xuICAgICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MgKiAwLjg7XG4gICAgXHR0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5ub3JtYWxpemVkKnc7XG4gICAgICBiYXJPZmZzZXQgPSAndHJhbnNsYXRlKDAsJyt0aGlzLnRoaWNrbmVzcyooLTEpLzIrJyknO1xuICAgICAgY29ybmVyUmFkaXVzID0gaC8yO1xuICAgIH1cblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneCcseCk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd5Jyx5KTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsYmFyT2Zmc2V0KTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3J4Jyxjb3JuZXJSYWRpdXMpOyAvLyBjb3JuZXIgcmFkaXVzXG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeScsY29ybmVyUmFkaXVzKTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx3KTtcbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsaCk7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneCcseCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd5Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx3KTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsaC10aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZSgneCcsMCk7XG4gICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd5Jyx5KTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsaCk7XG4gICAgfVxuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsYmFyT2Zmc2V0KTtcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeCcsY29ybmVyUmFkaXVzKTtcbiAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCdyeScsY29ybmVyUmFkaXVzKTtcblxuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAndmVydGljYWwnKSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeCcseCk7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx5KTtcbiAgICB9XG4gICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgncicsdGhpcy5rbm9iRGF0YS5yKTtcblxuXG4gICAgaWYgKHRoaXMucG9zaXRpb24pIHtcbiAgICAgIHRoaXMucG9zaXRpb24ucmVzaXplKFswLHRoaXMud2lkdGhdLFt0aGlzLmhlaWdodCwwXSk7XG4gICAgfVxuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuICAgIGlmICghdGhpcy5oYXNLbm9iKSB7XG4gICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdmaWxsJywnbm9uZScpO1xuICAgIH1cblxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5jbGlja2VkKSB7XG4gICAgICB0aGlzLmtub2JEYXRhLnIgPSB0aGlzLnRoaWNrbmVzcyowLjc1O1xuICAgIH1cbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JEYXRhLnIpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZCp0aGlzLmhlaWdodDtcbiAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQgLSB0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd5Jyx0aGlzLmhlaWdodCAtIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZCp0aGlzLndpZHRoO1xuICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd4JywwKTtcbiAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG4gICAgfVxuICB9XG5cbiAgZG93bigpIHtcbiAgICB0aGlzLmNsaWNrZWQgPSB0cnVlO1xuICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzKjAuOTtcbiAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG4gICAgdGhpcy5zbGlkZSgpO1xuICB9XG5cbiAgc2xpZGUoKSB7XG4gICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5wb3NpdGlvbi51cGRhdGUodGhpcy5tb3VzZSk7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5fdmFsdWUudXBkYXRlTm9ybWFsKCB0aGlzLnBvc2l0aW9uLnZhbHVlICk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy52YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdXAoKSB7XG4gICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIGdldCBub3JtYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuICB9XG5cbiAgLyoqXG4gIFRoZSBzbGlkZXIncyBjdXJyZW50IHZhbHVlLiBJZiBzZXQgbWFudWFsbHksIHdpbGwgdXBkYXRlIHRoZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cbiAgQHR5cGUge251bWJlcn1cbiAgQGV4YW1wbGUgc2xpZGVyLnZhbHVlID0gMTA7XG4gICovXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHYpIHtcbiAgICB0aGlzLl92YWx1ZS51cGRhdGUodik7XG4gICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBMb3dlciBsaW1pdCBvZiB0aGUgc2xpZGVycydzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBzbGlkZXIubWluID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1pbigpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWluO1xuICB9XG4gIHNldCBtaW4odikge1xuICAgIHRoaXMuX3ZhbHVlLm1pbiA9IHY7XG4gIH1cblxuICAvKipcbiAgVXBwZXIgbGltaXQgb2YgdGhlIHNsaWRlcidzIG91dHB1dCByYW5nZVxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBzbGlkZXIubWF4ID0gMTAwMDtcbiAgKi9cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWUubWF4O1xuICB9XG4gIHNldCBtYXgodikge1xuICAgIHRoaXMuX3ZhbHVlLm1heCA9IHY7XG4gIH1cblxuICAvKipcbiAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBzbGlkZXIncyB2YWx1ZSBjaGFuZ2VzIGJ5LlxuICBAdHlwZSB7bnVtYmVyfVxuICBAZXhhbXBsZSBzbGlkZXIuc3RlcCA9IDU7XG4gICovXG4gIGdldCBzdGVwKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZS5zdGVwO1xuICB9XG4gIHNldCBzdGVwKHYpIHtcbiAgICB0aGlzLl92YWx1ZS5zdGVwID0gdjtcbiAgfVxuXG4gIC8qKlxuICBBYnNvbHV0ZSBtb2RlIChzbGlkZXIncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJyZWxhdGl2ZVwiLlxuICBAdHlwZSB7c3RyaW5nfVxuICBAZXhhbXBsZSBzbGlkZXIubW9kZSA9IFwicmVsYXRpdmVcIjtcbiAgKi9cbiAgZ2V0IG1vZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb24ubW9kZTtcbiAgfVxuICBzZXQgbW9kZSh2KSB7XG4gICAgdGhpcy5wb3NpdGlvbi5tb2RlID0gdjtcbiAgfVxuXG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9jb21wb25lbnRzL3NsaWRlcnRlbXBsYXRlLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgc3ZnID0gcmVxdWlyZSgnLi4vdXRpbC9zdmcnKTtcbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcbmxldCBTdGVwID0gcmVxdWlyZSgnLi4vbW9kZWxzL3N0ZXAnKTtcbmltcG9ydCAqIGFzIEludGVyYWN0aW9uIGZyb20gJy4uL3V0aWwvaW50ZXJhY3Rpb24nO1xuXG4vKipcbiogUGFuXG4qXG4qIEBkZXNjcmlwdGlvbiBTdGVyZW8gY3Jvc3NmYWRlci5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJwYW5cIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBwYW4gPSBuZXcgTmV4dXMuUGFuKCcjdGFyZ2V0JylcbipcbiogQG91dHB1dFxuKiBjaGFuZ2VcbiogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cbiogVGhlIGV2ZW50IGRhdGEgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGludGVyZmFjZSdzIDxpPnZhbHVlPC9pPiAoLTEgdG8gMSksIGFzIHdlbGwgYXMgPGk+TDwvaT4gYW5kIDxpPlI8L2k+IGFtcGxpdHVkZSB2YWx1ZXMgKDAtMSkgZm9yIGxlZnQgYW5kIHJpZ2h0IHNwZWFrZXJzLCBjYWxjdWxhdGVkIGJ5IGEgc3F1YXJlLXJvb3QgY3Jvc3NmYWRlIGFsZ29yaXRobS5cbipcbiogQG91dHB1dGV4YW1wbGVcbiogcGFuLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhbiBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnc2NhbGUnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMTIwLDIwXSxcbiAgICAgICdvcmllbnRhdGlvbic6ICdob3Jpem9udGFsJyxcbiAgICAgICdtb2RlJzogJ3JlbGF0aXZlJyxcbiAgICAgICdzY2FsZSc6IFstMSwxXSxcbiAgICAgICdzdGVwJzogMCxcbiAgICAgICd2YWx1ZSc6IDAsXG4gICAgICAnaGFzS25vYic6IHRydWVcbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5vcmllbnRhdGlvbiA9IHRoaXMuc2V0dGluZ3Mub3JpZW50YXRpb247XG5cbiAgICB0aGlzLm1vZGUgPSB0aGlzLnNldHRpbmdzLm1vZGU7XG5cbiAgICB0aGlzLmhhc0tub2IgPSB0aGlzLnNldHRpbmdzLmhhc0tub2I7XG5cbiAgICAvLyB0aGlzLnN0ZXAgc2hvdWxkIGV2ZW50dWFsbHkgYmUgZ2V0L3NldFxuICAgIC8vIHVwZGF0aW5nIGl0IHdpbGwgdXBkYXRlIHRoZSBfdmFsdWUgc3RlcCBtb2RlbFxuICAgIHRoaXMuc3RlcCA9IHRoaXMuc2V0dGluZ3Muc3RlcDsgLy8gZmxvYXRcblxuICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5zY2FsZVswXSwgdGhpcy5zZXR0aW5ncy5zY2FsZVsxXSwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5tb2RlLHRoaXMub3JpZW50YXRpb24sWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblxuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnZhbHVlKTtcblxuICB9XG5cbiAgYnVpbGRJbnRlcmZhY2UoKSB7XG5cbiAgICB0aGlzLmJhciA9IHN2Zy5jcmVhdGUoJ3JlY3QnKTtcbiAgICB0aGlzLmtub2IgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcblxuICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBpZiAodGhpcy5wb3NpdGlvbikge1xuICAgICAgdGhpcy5wb3NpdGlvbi5yZXNpemUoWzAsdGhpcy53aWR0aF0sW3RoaXMuaGVpZ2h0LDBdKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy53aWR0aCA8IHRoaXMuaGVpZ2h0KSB7XG4gICAgICB0aGlzLm9yaWVudGF0aW9uID0gJ3ZlcnRpY2FsJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcmllbnRhdGlvbiA9ICdob3Jpem9udGFsJztcbiAgICB9XG5cbiAgICBsZXQgeCwgeSwgdywgaCwgYmFyT2Zmc2V0LCBjb3JuZXJSYWRpdXM7XG4gICAgdGhpcy5rbm9iRGF0YSA9IHtcbiAgICAgIGxldmVsOiAwLFxuICAgICAgcjogMFxuICAgIH07XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy50aGlja25lc3MgPSB0aGlzLndpZHRoIC8gMjtcbiAgICBcdHggPSB0aGlzLndpZHRoLzI7XG4gICAgXHR5ID0gMDtcbiAgICBcdHcgPSB0aGlzLnRoaWNrbmVzcztcbiAgICBcdGggPSB0aGlzLmhlaWdodDtcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IGgtdGhpcy5rbm9iRGF0YS5yLXRoaXMubm9ybWFsaXplZCooaC10aGlzLmtub2JEYXRhLnIqMik7XG4gICAgICBiYXJPZmZzZXQgPSAndHJhbnNsYXRlKCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycsMCknO1xuICAgICAgY29ybmVyUmFkaXVzID0gdy8yO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMuaGVpZ2h0IC8gMjtcbiAgICBcdHggPSAwO1xuICAgIFx0eSA9IHRoaXMuaGVpZ2h0LzI7XG4gICAgXHR3ID0gdGhpcy53aWR0aDtcbiAgICBcdGggPSB0aGlzLnRoaWNrbmVzcztcbiAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuICAgIFx0dGhpcy5rbm9iRGF0YS5sZXZlbCA9IHRoaXMubm9ybWFsaXplZCoody10aGlzLmtub2JEYXRhLnIqMikrdGhpcy5rbm9iRGF0YS5yO1xuICAgICAgYmFyT2Zmc2V0ID0gJ3RyYW5zbGF0ZSgwLCcrdGhpcy50aGlja25lc3MqKC0xKS8yKycpJztcbiAgICAgIGNvcm5lclJhZGl1cyA9IGgvMjtcbiAgICB9XG5cbiAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoJ3gnLHgpO1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgneScseSk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGJhck9mZnNldCk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdyeCcsY29ybmVyUmFkaXVzKTsgLy8gY29ybmVyIHJhZGl1c1xuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgncnknLGNvcm5lclJhZGl1cyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsdyk7XG4gICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLGgpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N4Jyx4KTtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2N5Jyx0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3knLHkpO1xuICAgIH1cbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JEYXRhLnIpO1xuXG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcblxuICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZSgnZmlsbCcsIHRoaXMuY29sb3JzLmZpbGwpO1xuICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuXG4gICAgaWYgKCF0aGlzLmhhc0tub2IpIHtcbiAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCd0cmFuc3BhcmVudCcpO1xuICAgIH1cblxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICghdGhpcy5jbGlja2VkKSB7XG4gICAgICB0aGlzLmtub2JEYXRhLnIgPSB0aGlzLnRoaWNrbmVzcyowLjc1O1xuICAgIH1cbiAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdyJyx0aGlzLmtub2JEYXRhLnIpO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgXHQgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5rbm9iRGF0YS5yK3RoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQqKHRoaXMuaGVpZ2h0LXRoaXMua25vYkRhdGEucioyKTtcbiAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKCdjeScsdGhpcy5oZWlnaHQgLSB0aGlzLmtub2JEYXRhLmxldmVsKTtcbiAgICB9IGVsc2Uge1xuICBcdCAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkKih0aGlzLndpZHRoLXRoaXMua25vYkRhdGEucioyKSt0aGlzLmtub2JEYXRhLnI7XG4gICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZSgnY3gnLHRoaXMua25vYkRhdGEubGV2ZWwpO1xuICAgIH1cbiAgfVxuXG5cbiAgY2xpY2soKSB7XG4gICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MqMC45O1xuICAgIHRoaXMucG9zaXRpb24uYW5jaG9yID0gdGhpcy5tb3VzZTtcbiAgICB0aGlzLm1vdmUoKTtcbiAgfVxuXG4gIG1vdmUoKSB7XG4gICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5wb3NpdGlvbi51cGRhdGUodGhpcy5tb3VzZSk7XG5cbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS51cGRhdGVOb3JtYWwoIHRoaXMucG9zaXRpb24udmFsdWUgKTtcblxuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHtcbiAgICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXG4gICAgICAgIEw6IE1hdGgucG93KCBtYXRoLnNjYWxlKHRoaXMudmFsdWUsLTEsMSwxLDApLCAyKSxcbiAgICAgICAgUjogTWF0aC5wb3coIG1hdGguc2NhbGUodGhpcy52YWx1ZSwtMSwxLDAsMSksIDIpXG4gICAgICB9KTtcblxuICAgIH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBUaGUgcG9zaXRpb24gb2YgY3Jvc3NmYWRlciwgZnJvbSAtMSAobGVmdCkgdG8gMSAocmlnaHQpLiBTZXR0aW5nIHRoaXMgdmFsdWUgdXBkYXRlcyB0aGUgaW50ZXJmYWNlIGFuZCB0cmlnZ2VycyB0aGUgb3V0cHV0IGV2ZW50LlxuICBAdHlwZSB7bnVtYmVyfVxuICAqL1xuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuICB9XG5cbiAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgdGhpcy5fdmFsdWUudXBkYXRlKHZhbHVlKTtcbiAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXG4gICAgICBMOiBNYXRoLnBvdyggbWF0aC5zY2FsZSh0aGlzLnZhbHVlLC0xLDEsMSwwKSwgMiksXG4gICAgICBSOiBNYXRoLnBvdyggbWF0aC5zY2FsZSh0aGlzLnZhbHVlLC0xLDEsMCwxKSwgMilcbiAgICB9KTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgZ2V0IG5vcm1hbGl6ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvcGFuLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IHN2ZyA9IHJlcXVpcmUoJy4uL3V0aWwvc3ZnJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcblxuXG5sZXQgUG9pbnQgPSBmdW5jdGlvbihwb2ludCxlbnZlbG9wZSkge1xuXG4gIHRoaXMueCA9IHBvaW50Lng7XG4gIHRoaXMueSA9IHBvaW50Lnk7XG4gIHRoaXMuZW52ZWxvcGUgPSBlbnZlbG9wZTtcblxuICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKCdjaXJjbGUnKTtcbiAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnZmlsbCcsdGhpcy5lbnZlbG9wZS5jb2xvcnMuYWNjZW50KTtcblxuICB0aGlzLmVudmVsb3BlLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcblxuICB0aGlzLnJlc2l6ZSA9IGZ1bmN0aW9uKCkge1xuICAgIGxldCByID0gfn4oTWF0aC5taW4odGhpcy5lbnZlbG9wZS53aWR0aCx0aGlzLmVudmVsb3BlLmhlaWdodCkvNTApKzI7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgncicscik7XG4gIH07XG5cbiAgdGhpcy5tb3ZlID0gZnVuY3Rpb24oeCx5KSB7XG5cbiAgICB0aGlzLnggPSAoeCB8fCB4PT09MCkgPyB4IDogdGhpcy54O1xuICAgIHRoaXMueSA9ICh5IHx8IHk9PT0wKSA/IHkgOiB0aGlzLnk7XG5cbiAgICBpZiAodGhpcy5lbnZlbG9wZS5ub2Rlcy5pbmRleE9mKHRoaXMpPj0wKSB7XG5cbiAgICAgIGxldCBwcmV2SW5kZXggPSB0aGlzLmVudmVsb3BlLm5vZGVzLmluZGV4T2YodGhpcyktMTtcbiAgICAgIGxldCBuZXh0SW5kZXggPSB0aGlzLmVudmVsb3BlLm5vZGVzLmluZGV4T2YodGhpcykrMTtcblxuICAgICAgbGV0IHByZXZOb2RlID0gdGhpcy5lbnZlbG9wZS5ub2Rlc1twcmV2SW5kZXhdO1xuICAgICAgbGV0IG5leHROb2RlID0gdGhpcy5lbnZlbG9wZS5ub2Rlc1tuZXh0SW5kZXhdO1xuXG4gICAgICBsZXQgbG93WCA9IHByZXZJbmRleCA+PSAwID8gcHJldk5vZGUueCA6IDA7XG4gICAgICBsZXQgaGlnaFggPSBuZXh0SW5kZXggPCB0aGlzLmVudmVsb3BlLm5vZGVzLmxlbmd0aCA/IG5leHROb2RlLnggOiAxO1xuXG4gICAgICBpZiAodGhpcy54IDwgbG93WCkgeyB0aGlzLnggPSBsb3dYOyB9XG4gICAgICBpZiAodGhpcy54ID4gaGlnaFgpIHsgdGhpcy54ID0gaGlnaFg7IH1cblxuICAgIH1cblxuICAgIHRoaXMubG9jYXRpb24gPSB0aGlzLmdldENvb3JkaW5hdGVzKCk7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3gnLCB0aGlzLmxvY2F0aW9uLngpO1xuICAgIHRoaXMuZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2N5JywgdGhpcy5sb2NhdGlvbi55KTtcbiAgfTtcblxuICB0aGlzLmdldENvb3JkaW5hdGVzID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHRoaXMueCAqIHRoaXMuZW52ZWxvcGUud2lkdGgsXG4gICAgICB5OiAoMS10aGlzLnkpICogdGhpcy5lbnZlbG9wZS5oZWlnaHRcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMubW92ZSh0aGlzLngsdGhpcy55LHRydWUpO1xuICB0aGlzLnJlc2l6ZSgpO1xuXG4gIHRoaXMuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuZW52ZWxvcGUuZWxlbWVudC5yZW1vdmVDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICAgIHRoaXMuZW52ZWxvcGUubm9kZXMuc3BsaWNlKHRoaXMuZW52ZWxvcGUubm9kZXMuaW5kZXhPZih0aGlzKSwxKTtcbiAgfTtcblxuXG59O1xuXG5cbi8qKlxuKiBFbnZlbG9wZVxuKlxuKiBAZGVzY3JpcHRpb24gSW50ZXJhY3RpdmUgbGluZWFyIHJhbXAgdmlzdWFsaXphdGlvbi5cbipcbiogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJlbnZlbG9wZVwiPjwvc3Bhbj5cbipcbiogQGV4YW1wbGVcbiogdmFyIGVudmVsb3BlID0gbmV3IE5leHVzLkVudmVsb3BlKCcjdGFyZ2V0JylcbipcbiogQGV4YW1wbGVcbiogdmFyIGVudmVsb3BlID0gbmV3IE5leHVzLkVudmVsb3BlKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMzAwLDE1MF0sXG4qICAgJ3BvaW50cyc6IFtcbiogICAgIHtcbiogICAgICAgeDogMC4xLFxuKiAgICAgICB5OiAwLjRcbiogICAgIH0sXG4qICAgICB7XG4qICAgICAgIHg6IDAuMzUsXG4qICAgICAgIHk6IDAuNlxuKiAgICAgfSxcbiogICAgIHtcbiogICAgICAgeDogMC42NSxcbiogICAgICAgeTogMC4yXG4qICAgICB9LFxuKiAgICAge1xuKiAgICAgICB4OiAwLjksXG4qICAgICAgIHk6IDAuNFxuKiAgICAgfSxcbiogICBdXG4qIH0pXG4qXG4qIEBvdXRwdXRcbiogY2hhbmdlXG4qIEZpcmVzIGFueSB0aW1lIGEgbm9kZSBpcyBtb3ZlZC4gPGJyPlxuKiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBhcnJheSBvZiBwb2ludCBsb2NhdGlvbnMuIEVhY2ggaXRlbSBpbiB0aGUgYXJyYXkgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgPGk+eDwvaT4gYW5kIDxpPnk8L2k+IHByb3BlcnRpZXMgZGVzY3JpYmluZyB0aGUgbG9jYXRpb24gb2YgYSBwb2ludCBvbiB0aGUgZW52ZWxvcGUuXG4qXG4qIEBvdXRwdXRleGFtcGxlXG4qIGVudmVsb3BlLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcbiogICBjb25zb2xlLmxvZyh2KTtcbiogfSlcbipcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEVudmVsb3BlIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWyd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMzAwLDE1MF0sXG4gICAgICAncG9pbnRzJzogW1xuICBcdFx0XHR7XG4gIFx0XHRcdFx0eDogMC4xLFxuICBcdFx0XHRcdHk6IDAuNFxuICBcdFx0XHR9LFxuICBcdFx0XHR7XG4gIFx0XHRcdFx0eDogMC4zNSxcbiAgXHRcdFx0XHR5OiAwLjZcbiAgXHRcdFx0fSxcbiAgXHRcdFx0e1xuICBcdFx0XHRcdHg6IDAuNjUsXG4gIFx0XHRcdFx0eTogMC4yXG4gIFx0XHRcdH0sXG4gIFx0XHRcdHtcbiAgXHRcdFx0XHR4OiAwLjksXG4gIFx0XHRcdFx0eTogMC40XG4gIFx0XHRcdH1cbiAgXHRcdF1cbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5wb2ludHMgPSB0aGlzLnNldHRpbmdzLnBvaW50cztcblxuICAgIHRoaXMubm9kZXMgPSBbXTtcblxuICAgIHRoaXMuc2VsZWN0ZWQgPSBmYWxzZTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG5cbiAgfVxuXG4gIGJ1aWxkSW50ZXJmYWNlKCkge1xuXG5cbiAgICB0aGlzLnBvaW50cy5mb3JFYWNoKChwb2ludCkgPT4ge1xuICAgICAgbGV0IG5vZGUgPSBuZXcgUG9pbnQocG9pbnQsdGhpcyk7XG4gICAgICB0aGlzLm5vZGVzLnB1c2gobm9kZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNvcnRQb2ludHMoKTtcblxuICAgIHRoaXMubGluZSA9IHN2Zy5jcmVhdGUoJ3BvbHlsaW5lJyk7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJywgMik7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZSgnZmlsbCcsICdub25lJyk7XG5cbiAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5saW5lKTtcblxuICAgIHRoaXMuZmlsbCA9IHN2Zy5jcmVhdGUoJ3BvbHlsaW5lJyk7XG4gICAgdGhpcy5maWxsLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywgJzAuMicpO1xuXG4gICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuZmlsbCk7XG5cbiAgfVxuXG4gIHNpemVJbnRlcmZhY2UoKSB7XG5cbiAgICBmb3IgKGxldCBpPTA7IGk8dGhpcy5ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5ub2Rlc1tpXS5yZXNpemUoKTtcbiAgICAgIHRoaXMubm9kZXNbaV0ubW92ZSgpO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuXG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB0aGlzLmZpbGwuc2V0QXR0cmlidXRlKCdmaWxsJywgdGhpcy5jb2xvcnMuYWNjZW50KTtcbiAgICB0aGlzLm5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgIG5vZGUuZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLHRoaXMuY29sb3JzLmFjY2VudCk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgLy8gIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0ubW92ZSggdGhpcy5wb2ludHMgKVxuICAgIHRoaXMuY2FsY3VsYXRlUGF0aCgpO1xuICB9XG5cbiAgY2FsY3VsYXRlUG9pbnRzKCkge1xuICAgIHRoaXMucG9pbnRzID0gW107XG4gICAgdGhpcy5ub2Rlcy5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgICB0aGlzLnBvaW50cy5wdXNoKHsgeDogbm9kZS54LCB5OiBub2RlLnkgfSk7XG4gICAgfSk7XG4gIH1cblxuICBjYWxjdWxhdGVQYXRoKCkge1xuXG4gICAgLy9zdHJva2UgZGF0YVxuICAgIGxldCBkYXRhID0gJzAgJysgdGhpcy5ub2Rlc1swXS5sb2NhdGlvbi55KycsICc7XG5cbiAgICAvLyBkYXRhIHNob3VsZCBiZSByZS1vcmRlcmVkIGJhc2VkIG9uIHggbG9jYXRpb24uXG4gICAgLy8gd2hhdGV2ZXIgZnVuY3Rpb24gYWRkcyBhIG5vZGUgc2hvdWxkIGFkZCBpdCBhdCB0aGUgcmlnaHQgaW5kZXhcblxuICAgIHRoaXMubm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgIC8vICBsZXQgbG9jYXRpb24gPSBub2RlLmdldENvb3JkaW5hdGVzKCk7XG4gICAgICBkYXRhICs9IG5vZGUubG9jYXRpb24ueCArICcgJyArIG5vZGUubG9jYXRpb24ueSArICcsICc7XG4gICAgfSk7XG5cblxuICAvLyAgZGF0YSArPSBwb2ludC54KnRoaXMud2lkdGgrJyAnKyBwb2ludC55KnRoaXMuaGVpZ2h0KycsICc7XG4gICAgZGF0YSArPSB0aGlzLndpZHRoICsgJyAnKyB0aGlzLm5vZGVzW3RoaXMubm9kZXMubGVuZ3RoLTFdLmxvY2F0aW9uLnk7XG5cbiAgICB0aGlzLmxpbmUuc2V0QXR0cmlidXRlKCdwb2ludHMnLCBkYXRhKTtcblxuICAgIC8vIGZpbGwgZGF0YVxuICAgIC8vIGFkZCBib3R0b20gY29ybmVyc1xuXG4gICAgZGF0YSArPSAnLCAnK3RoaXMud2lkdGggKycgJyt0aGlzLmhlaWdodCsnLCAnO1xuICAgIGRhdGEgKz0gJzAgJyt0aGlzLmhlaWdodDtcblxuICAgIHRoaXMuZmlsbC5zZXRBdHRyaWJ1dGUoJ3BvaW50cycsIGRhdGEpO1xuXG4gIH1cblxuXG5cbiAgY2xpY2soKSB7XG4gIFx0Ly8gZmluZCBuZWFyZXN0IG5vZGUgYW5kIHNldCB0aGlzLnNlbGVjdGVkIChpbmRleClcbiAgICB0aGlzLmhhc01vdmVkID0gZmFsc2U7XG4gIFx0dGhpcy5zZWxlY3RlZCA9IHRoaXMuZmluZE5lYXJlc3ROb2RlKCk7XG5cbiAgICB0aGlzLm5vZGVzW3RoaXMuc2VsZWN0ZWRdLm1vdmUodGhpcy5tb3VzZS54L3RoaXMud2lkdGgsMS10aGlzLm1vdXNlLnkvdGhpcy5oZWlnaHQpO1xuICAgIHRoaXMuc2NhbGVOb2RlKHRoaXMuc2VsZWN0ZWQpO1xuXG4gICAgLy8gbXVzdCBkbyB0aGlzIGIvYyBuZXcgbm9kZSBtYXkgaGF2ZSBiZWVuIGNyZWF0ZWRcbiAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gIFx0dGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIG1vdmUoKSB7XG4gIFx0aWYgKHRoaXMuY2xpY2tlZCkge1xuICAgICAgdGhpcy5tb3VzZS54ID0gbWF0aC5jbGlwKHRoaXMubW91c2UueCwwLHRoaXMud2lkdGgpO1xuICAgICAgdGhpcy5oYXNNb3ZlZCA9IHRydWU7XG5cbiAgICAgIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0ubW92ZSh0aGlzLm1vdXNlLngvdGhpcy53aWR0aCwxLXRoaXMubW91c2UueS90aGlzLmhlaWdodCk7XG4gICAgXHR0aGlzLnNjYWxlTm9kZSh0aGlzLnNlbGVjdGVkKTtcblxuICAgICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcbiAgXHRcdHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gIFx0XHR0aGlzLnJlbmRlcigpO1xuICBcdH1cbiAgfVxuXG4gIHJlbGVhc2UoKSB7XG5cbiAgXHRpZiAoIXRoaXMuaGFzTW92ZWQpIHtcbiAgICAgIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0uZGVzdHJveSgpO1xuICBcdH1cblxuICAgIHRoaXMuY2FsY3VsYXRlUG9pbnRzKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMucG9pbnRzKTtcbiAgXHR0aGlzLnJlbmRlcigpO1xuXG4gIFx0Ly8gcmVzZXQgdGhpcy5zZWxlY3RlZFxuICBcdHRoaXMuc2VsZWN0ZWQgPSBudWxsO1xuICB9XG5cblxuICBmaW5kTmVhcmVzdE5vZGUoKSB7XG4gIFx0dmFyIG5lYXJlc3RJbmRleCA9IG51bGw7XG4gICAgLy8gc2V0IHRoaXMgdW5yZWFzb25hYmx5IGhpZ2ggc28gdGhhdCBldmVyeSBkaXN0YW5jZSB3aWxsIGJlIGxvd2VyIHRoYW4gaXQuXG4gIFx0dmFyIG5lYXJlc3REaXN0ID0gMTAwMDA7XG4gIFx0dmFyIGJlZm9yZSA9IGZhbHNlO1xuICAgIGxldCB4ID0gdGhpcy5tb3VzZS54L3RoaXMud2lkdGg7XG4gICAgbGV0IHkgPSAxLXRoaXMubW91c2UueS90aGlzLmhlaWdodDtcbiAgICBsZXQgbm9kZXMgPSB0aGlzLm5vZGVzO1xuICBcdGZvciAobGV0IGkgPSAwOyBpPG5vZGVzLmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgZGlzdGFuY2UgZnJvbSBtb3VzZSB0byB0aGlzIG5vZGUgdXNpbmcgcHl0aGFnb3JlYW4gdGhlb3JlbVxuICBcdFx0dmFyIGRpc3RhbmNlID0gTWF0aC5zcXJ0KCAgTWF0aC5wb3coIChub2Rlc1tpXS54IC0geCksIDIpICsgTWF0aC5wb3coKG5vZGVzW2ldLnkgLSB5KSwgMikgKTtcblxuICAgICAgLy8gaWYgdGhpcyBkaXN0YW5jZSBpcyBsZXNzIHRoYW4gdGhlIHByZXZpb3VzIHNob3J0ZXN0IGRpc3RhbmNlLCB1c2UgdGhpcyBpbmRleFxuICBcdFx0aWYgKGRpc3RhbmNlIDwgbmVhcmVzdERpc3QpIHtcbiAgXHRcdFx0bmVhcmVzdERpc3QgPSBkaXN0YW5jZTtcbiAgXHRcdFx0bmVhcmVzdEluZGV4ID0gaTtcbiAgXHRcdFx0YmVmb3JlID0geCA+IG5vZGVzW2ldLng7XG4gIFx0XHR9XG5cbiAgXHR9XG5cbiAgICAvLyBpZiBub3QgdmVyeSBjbG9zZSB0byBhbnkgbm9kZSwgY3JlYXRlIGEgbm9kZVxuICBcdGlmIChuZWFyZXN0RGlzdD4wLjA3KSB7XG5cbiAgICAgIG5lYXJlc3RJbmRleCA9IHRoaXMuZ2V0SW5kZXhGcm9tWCh0aGlzLm1vdXNlLngvdGhpcy53aWR0aCk7XG5cbiAgXHRcdHRoaXMubm9kZXMuc3BsaWNlKG5lYXJlc3RJbmRleCwwLCBuZXcgUG9pbnQoe1xuICBcdFx0XHR4OiB0aGlzLm1vdXNlLngvdGhpcy53aWR0aCxcbiAgXHRcdFx0eTogMS10aGlzLm1vdXNlLnkvdGhpcy5oZWlnaHRcbiAgXHRcdH0sIHRoaXMpKTtcbiAgICAgIHRoaXMuaGFzTW92ZWQgPSB0cnVlO1xuXG4gIFx0fVxuXG4gIFx0cmV0dXJuIG5lYXJlc3RJbmRleDtcbiAgfVxuXG4gIGdldEluZGV4RnJvbVgoeCkge1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgdGhpcy5ub2Rlcy5mb3JFYWNoKChub2RlLGkpID0+IHtcbiAgICAgIGlmICh0aGlzLm5vZGVzW2ldLnggPD0geCkge1xuICAgICAgICBpbmRleCA9IGkrMTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBzY2FsZU5vZGUoaSkge1xuXG4gIFx0bGV0IGNsaXBwZWRYID0gbWF0aC5jbGlwKHRoaXMubm9kZXNbaV0ueCwgMCwgMSk7XG4gIFx0bGV0IGNsaXBwZWRZID0gbWF0aC5jbGlwKHRoaXMubm9kZXNbaV0ueSwgMCwgMSk7XG5cbiAgICB0aGlzLm5vZGVzW2ldLm1vdmUoIGNsaXBwZWRYLCBjbGlwcGVkWSApO1xuXG4gIH1cblxuICAvKipcbiAgU29ydCB0aGUgdGhpcy5wb2ludHMgYXJyYXkgZnJvbSBsZWZ0LW1vc3QgcG9pbnQgdG8gcmlnaHQtbW9zdCBwb2ludC4gWW91IHNob3VsZCBub3QgcmVndWxhcmx5IG5lZWQgdG8gdXNlIHRoaXMsIGhvd2V2ZXIgaXQgbWF5IGJlIHVzZWZ1bCBpZiB0aGUgcG9pbnRzIGdldCB1bm9yZGVyZWQuXG4gICovXG4gIHNvcnRQb2ludHMoKSB7XG4gICAgdGhpcy5ub2Rlcy5zb3J0KGZ1bmN0aW9uKGEsIGIpe1xuICAgICAgcmV0dXJuIGEueCA+IGIueDtcbiAgICB9KTtcbiAgfVxuXG5cbiAgLyoqXG4gIEFkZCBhIGJyZWFrcG9pbnQgb24gdGhlIGVudmVsb3BlLlxuICBAcGFyYW0geCB7bnVtYmVyfSB4IGxvY2F0aW9uIG9mIHRoZSBwb2ludCwgbm9ybWFsaXplZCAoMC0xKVxuICBAcGFyYW0geSB7bnVtYmVyfSB5IGxvY2F0aW9uIG9mIHRoZSBwb2ludCwgbm9ybWFsaXplZCAoMC0xKVxuICAqL1xuICBhZGRQb2ludCh4LHkpIHtcbiAgICBsZXQgaW5kZXggPSB0aGlzLm5vZGVzLmxlbmd0aDtcblxuICAgIHRoaXMuc29ydFBvaW50cygpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGk8dGhpcy5ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHggPCB0aGlzLm5vZGVzW2ldLngpIHtcbiAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgXHR9XG5cbiAgICB0aGlzLm5vZGVzLnNwbGljZShpbmRleCwgMCwgbmV3IFBvaW50KHtcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5XG4gICAgfSwgdGhpcykpO1xuXG4gICAgdGhpcy5zY2FsZU5vZGUoaW5kZXgpO1xuXG4gICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5wb2ludHMpO1xuXG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIEZpbmQgdGhlIGxldmVsIGF0IGEgY2VydGFpbiB4IGxvY2F0aW9uIG9uIHRoZSBlbnZlbG9wZS5cbiAgQHBhcmFtIHgge251bWJlcn0gVGhlIHggbG9jYXRpb24gdG8gZmluZCB0aGUgbGV2ZWwgb2YsIG5vcm1hbGl6ZWQgMC0xXG4gICovXG4gIHNjYW4oeCkge1xuICAgIC8vIGZpbmQgc3Vycm91bmRpbmcgcG9pbnRzXG4gICAgbGV0IG5leHRJbmRleCA9IHRoaXMuZ2V0SW5kZXhGcm9tWCh4KTtcbiAgICBsZXQgcHJpb3JJbmRleCA9IG5leHRJbmRleC0xO1xuICAgIGlmIChwcmlvckluZGV4IDwgMCkge1xuICAgICAgcHJpb3JJbmRleCA9IDA7XG4gICAgfVxuICAgIGlmIChuZXh0SW5kZXggPj0gdGhpcy5ub2Rlcy5sZW5ndGgpIHtcbiAgICAgIG5leHRJbmRleCA9IHRoaXMubm9kZXMubGVuZ3RoLTE7XG4gICAgfVxuICAgIGxldCBwcmlvclBvaW50ID0gdGhpcy5ub2Rlc1twcmlvckluZGV4XTtcbiAgICBsZXQgbmV4dFBvaW50ID0gdGhpcy5ub2Rlc1tuZXh0SW5kZXhdO1xuICAgIGxldCBsb2MgPSBtYXRoLnNjYWxlKHgscHJpb3JQb2ludC54LCBuZXh0UG9pbnQueCwgMCwgMSk7XG4gICAgbGV0IHZhbHVlID0gbWF0aC5pbnRlcnAobG9jLHByaW9yUG9pbnQueSxuZXh0UG9pbnQueSk7XG4gICAgdGhpcy5lbWl0KCdzY2FuJyx2YWx1ZSk7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cblxuICAvKipcbiAgTW92ZSBhIGJyZWFrcG9pbnQgb24gdGhlIGVudmVsb3BlLlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBicmVha3BvaW50IHRvIG1vdmVcbiAgQHBhcmFtIHgge251bWJlcn0gTmV3IHggbG9jYXRpb24sIG5vcm1hbGl6ZWQgMC0xXG4gIEBwYXJhbSB5IHtudW1iZXJ9IE5ldyB5IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuICAqL1xuICBtb3ZlUG9pbnQoaW5kZXgseCx5KSB7XG4gICAgdGhpcy5ub2Rlc1tpbmRleF0ubW92ZSh4LHkpO1xuICAgIHRoaXMuc2NhbGVOb2RlKGluZGV4KTtcbiAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIE1vdmUgYSBicmVha3BvaW50IG9uIHRoZSBlbnZlbG9wZSBieSBhIGNlcnRhaW4gYW1vdW50LlxuICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBicmVha3BvaW50IHRvIG1vdmVcbiAgQHBhcmFtIHhPZmZzZXQge251bWJlcn0gWCBkaXNwbGFjZW1lbnQsIG5vcm1hbGl6ZWQgMC0xXG4gIEBwYXJhbSB5T2Zmc2V0IHtudW1iZXJ9IFkgZGlzcGxhY2VtZW50LCBub3JtYWxpemVkIDAtMVxuICAqL1xuICBhZGp1c3RQb2ludChpbmRleCx4T2Zmc2V0LHlPZmZzZXQpIHtcbiAgICB0aGlzLm5vZGVzW2luZGV4XS5tb3ZlKHRoaXMubm9kZXNbaW5kZXhdLngreE9mZnNldCx0aGlzLm5vZGVzW2luZGV4XS55K3lPZmZzZXQpO1xuICAgIHRoaXMuc2NhbGVOb2RlKGluZGV4KTtcbiAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnBvaW50cyk7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG5cbiAgLyoqXG4gIFJlbW92ZSBhIGJyZWFrcG9pbnQgZnJvbSB0aGUgZW52ZWxvcGUuXG4gIEBwYXJhbSBpbmRleCB7bnVtYmVyfSBJbmRleCBvZiB0aGUgYnJlYWtwb2ludCB0byByZW1vdmVcbiAgKi9cbiAgZGVzdHJveVBvaW50KGluZGV4KSB7XG4gICAgdGhpcy5ub2Rlc1tpbmRleF0uZGVzdHJveSgpO1xuICAgIHRoaXMuY2FsY3VsYXRlUG9pbnRzKCk7XG4gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMucG9pbnRzKTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cblxuICAvKipcbiAgUmVtb3ZlIGFsbCBleGlzdGluZyBicmVha3BvaW50cyBhbmQgYWRkIGFuIGVudGlyZWx5IG5ldyBzZXQgb2YgYnJlYWtwb2ludHMuXG4gIEBwYXJhbSBhbGxQb2ludHMge2FycmF5fSBBbiBhcnJheSBvZiBvYmplY3RzIHdpdGggeC95IHByb3BlcnRpZXMgKG5vcm1hbGl6ZWQgMC0xKS4gRWFjaCBvYmplY3QgaW4gdGhlIGFycmF5IHNwZWNpZmljZXMgdGhlIHgveSBsb2NhdGlvbiBvZiBhIG5ldyBicmVha3BvaW50IHRvIGJlIGFkZGVkLlxuICAqL1xuICBzZXRQb2ludHMoYWxsUG9pbnRzKSB7XG4gICAgd2hpbGUgKHRoaXMubm9kZXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLm5vZGVzWzBdLmRlc3Ryb3koKTtcbiAgICB9XG4gICAgYWxsUG9pbnRzLmZvckVhY2goKHBvaW50KSA9PiB7XG4gICAgICB0aGlzLmFkZFBvaW50KHBvaW50LngscG9pbnQueSk7XG4gICAgfSk7XG4gICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScsdGhpcy5wb2ludHMpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvZW52ZWxvcGUuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBkb20gPSByZXF1aXJlKCcuLi91dGlsL2RvbScpO1xuLy9sZXQgbWF0aCA9IHJlcXVpcmUoJy4uL3V0aWwvbWF0aCcpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5cbi8qKlxuKiBTcGVjdHJvZ3JhbVxuKlxuKiBAZGVzY3JpcHRpb24gQXVkaW8gc3BlY3RydW0gdmlzdWFsaXphdGlvblxuKlxuKiBAZGVtbyA8c3BhbiBuZXh1cy11aT1cInNwZWN0cm9ncmFtXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc3BlY3Ryb2dyYW0gPSBuZXcgTmV4dXMuU3BlY3Ryb2dyYW0oJyN0YXJnZXQnKVxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgc3BlY3Ryb2dyYW0gPSBuZXcgTmV4dXMuU3BlY3Ryb2dyYW0oJyN0YXJnZXQnLHtcbiogICAnc2l6ZSc6IFszMDAsMTUwXVxuKiB9KVxuKlxuKiBAb3V0cHV0XG4qICZuYnNwO1xuKiBObyBldmVudHNcbipcbiovXG5cbmltcG9ydCB7IGNvbnRleHQgfSBmcm9tICcuLi9tYWluJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3BlY3Ryb2dyYW0gZXh0ZW5kcyBJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgbGV0IG9wdGlvbnMgPSBbJ3NjYWxlJywndmFsdWUnXTtcblxuICAgIGxldCBkZWZhdWx0cyA9IHtcbiAgICAgICdzaXplJzogWzMwMCwxNTBdXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgICB0aGlzLmFuYWx5c2VyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gICAgdGhpcy5hbmFseXNlci5mZnRTaXplID0gMjA0ODtcbiAgICB0aGlzLmJ1ZmZlckxlbmd0aCA9IHRoaXMuYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQ7XG4gICAgdGhpcy5kYXRhQXJyYXkgPSBuZXcgVWludDhBcnJheSh0aGlzLmJ1ZmZlckxlbmd0aCk7XG5cbiAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG5cbiAgICB0aGlzLnNvdXJjZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5jYW52YXMgPSBuZXcgZG9tLlNtYXJ0Q2FudmFzKHRoaXMucGFyZW50KTtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNhbnZhcy5lbGVtZW50O1xuICB9XG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5yZXNpemUodGhpcy53aWR0aCx0aGlzLmhlaWdodCk7XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gIH1cblxuICByZW5kZXIoKSB7XG5cbiAgICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlci5iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICB0aGlzLmFuYWx5c2VyLmdldEJ5dGVGcmVxdWVuY3lEYXRhKHRoaXMuZGF0YUFycmF5KTtcblxuICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KDAsIDAsIHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgsIHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0KTtcblxuICAgIGlmICh0aGlzLnNvdXJjZSAmJiB0aGlzLmRhdGFBcnJheSkge1xuXG4gICAgICAvL2NvbnNvbGUubG9nKHRoaXMuZGF0YUFycmF5KTtcblxuICAgICAgbGV0IGJhcldpZHRoID0gKHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGggLyB0aGlzLmJ1ZmZlckxlbmd0aCk7XG4gICAgICBsZXQgYmFySGVpZ2h0O1xuICAgICAgbGV0IHggPSAwO1xuXG4gICAgICBsZXQgZGVmaW5pdGlvbiA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgvNTA7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5idWZmZXJMZW5ndGg7IGkgPSBpK2RlZmluaXRpb24pIHtcbiAgICAgICAgYmFySGVpZ2h0ID0gTWF0aC5tYXguYXBwbHkobnVsbCwgdGhpcy5kYXRhQXJyYXkuc3ViYXJyYXkoaSxpK2RlZmluaXRpb24pKTtcbiAgICAgICAgYmFySGVpZ2h0IC89IDI1NTtcbiAgICAgICAgYmFySGVpZ2h0ICo9IHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0O1xuXG4gICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KHgsdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQtYmFySGVpZ2h0LGJhcldpZHRoKmRlZmluaXRpb24sYmFySGVpZ2h0KTtcblxuICAgICAgICB4ICs9IChiYXJXaWR0aCpkZWZpbml0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgRXF1aXZhbGVudCB0byBcInBhdGNoaW5nIGluXCIgYW4gYXVkaW8gbm9kZSB0byB2aXN1YWxpemUuIE5PVEU6IFlvdSBjYW5ub3QgY29ubmVjdCBhdWRpbyBub2RlcyBhY3Jvc3MgdHdvIGRpZmZlcmVudCBhdWRpbyBjb250ZXh0cy4gTmV4dXNVSSBydW5zIGl0cyBhdWRpbyBhbmFseXNpcyBvbiBpdHMgb3duIGF1ZGlvIGNvbnRleHQsIE5leHVzLmNvbnRleHQuIElmIHRoZSBhdWRpbyBub2RlIHlvdSBhcmUgdmlzdWFsaXppbmcgaXMgY3JlYXRlZCBvbiBhIGRpZmZlcmVudCBhdWRpbyBjb250ZXh0LCB5b3Ugd2lsbCBuZWVkIHRvIHRlbGwgTmV4dXNVSSB0byB1c2UgdGhhdCBjb250ZXh0IGluc3RlYWQ6IGkuZS4gTmV4dXMuY29udGV4dCA9IFlvdXJBdWRpb0NvbnRleHROYW1lLiBGb3IgZXhhbXBsZSwgaW4gVG9uZUpTIHByb2plY3RzLCB0aGUgbGluZSB3b3VsZCBiZTogTmV4dXMuY29udGV4dCA9IFRvbmUuY29udGV4dCAuIFdlIHJlY29tbWVuZCB0aGF0IHlvdSB3cml0ZSB0aGF0IGxpbmUgb2YgY29kZSBvbmx5IG9uY2UgYXQgdGhlIGJlZ2lubmluZyBvZiB5b3VyIHByb2plY3QuXG4gIEBwYXJhbSBub2RlIHtBdWRpb05vZGV9IFRoZSBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZVxuICBAZXhhbXBsZSBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC8vIG9yIGFub3RoZXIgYXVkaW8gY29udGV4dCB5b3UgaGF2ZSBjcmVhdGVkXG4gIHNwZWN0cm9ncmFtLmNvbm5lY3QoIFRvbmUuTWFzdGVyICk7XG4gICovXG4gIGNvbm5lY3Qobm9kZSkge1xuICAgIGlmICh0aGlzLnNvdXJjZSkge1xuICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgfVxuICAgIHRoaXMuc291cmNlID0gbm9kZTtcbiAgICB0aGlzLnNvdXJjZS5jb25uZWN0KHRoaXMuYW5hbHlzZXIpO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKipcbiAgU3RvcCB2aXN1YWxpemluZyB0aGUgc291cmNlIG5vZGUgYW5kIGRpc2Nvbm5lY3QgaXQuXG4gICovXG4gIGRpc2Nvbm5lY3QoKSB7XG4gICAgdGhpcy5zb3VyY2UuZGlzY29ubmVjdCh0aGlzLmFuYWx5c2VyKTtcbiAgICB0aGlzLnNvdXJjZSA9IG51bGw7XG4gIH1cblxuICBjbGljaygpIHtcbiAgICB0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL3NwZWN0cm9ncmFtLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgZG9tID0gcmVxdWlyZSgnLi4vdXRpbC9kb20nKTtcbmxldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5sZXQgSW50ZXJmYWNlID0gcmVxdWlyZSgnLi4vY29yZS9pbnRlcmZhY2UnKTtcblxuXG4vKipcbiogTWV0ZXJcbipcbiogQGRlc2NyaXB0aW9uIFN0ZXJlbyBkZWNpYmVsIG1ldGVyXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwibWV0ZXJcIj48L3NwYW4+XG4qXG4qIEBleGFtcGxlXG4qIHZhciBtZXRlciA9IG5ldyBOZXh1cy5NZXRlcignI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBtZXRlciA9IG5ldyBOZXh1cy5NZXRlcignI3RhcmdldCcse1xuKiAgIHNpemU6IFs3NSw3NV1cbiogfSlcbipcbiogQG91dHB1dFxuKiAmbmJzcDtcbiogTm8gZXZlbnRzXG4qXG4qL1xuXG5pbXBvcnQgeyBjb250ZXh0IH0gZnJvbSAnLi4vbWFpbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1ldGVyIGV4dGVuZHMgSW50ZXJmYWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIGxldCBvcHRpb25zID0gWydzY2FsZScsJ3ZhbHVlJ107XG5cbiAgICBsZXQgZGVmYXVsdHMgPSB7XG4gICAgICAnc2l6ZSc6IFszMCwxMDBdXG4gICAgfTtcblxuICAgIHN1cGVyKGFyZ3VtZW50cyxvcHRpb25zLGRlZmF1bHRzKTtcblxuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgICB0aGlzLmNoYW5uZWxzID0gMjtcblxuICAgIHRoaXMuc3BsaXR0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKCB0aGlzLmNoYW5uZWxzICk7XG5cbiAgICB0aGlzLmFuYWx5c2VycyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaT0wOyBpPHRoaXMuY2hhbm5lbHM7IGkrKykge1xuICAgICAgbGV0IGFuYWx5c2VyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gICAgICB0aGlzLnNwbGl0dGVyLmNvbm5lY3QoYW5hbHlzZXIsaSk7XG4gICAgICBhbmFseXNlci5mZnRTaXplID0gMTAyNDtcbiAgICAgIGFuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IDE7XG4gICAgICB0aGlzLmFuYWx5c2Vycy5wdXNoKCBhbmFseXNlciApO1xuICAgIH1cbiAgICB0aGlzLmJ1ZmZlckxlbmd0aCA9IHRoaXMuYW5hbHlzZXJzWzBdLmZyZXF1ZW5jeUJpbkNvdW50O1xuICAgIHRoaXMuZGF0YUFycmF5ID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJ1ZmZlckxlbmd0aCk7XG5cbi8qXG4gICAgLy8gYWRkIGxpbmVhciBncmFkaWVudFxuICAgIHZhciBncmQgPSBjYW52YXNDdHguY3JlYXRlTGluZWFyR3JhZGllbnQoMCwgMCwgMCwgY2FudmFzLmhlaWdodCk7XG4gICAgLy8gbGlnaHQgYmx1ZVxuICAgIGdyZC5hZGRDb2xvclN0b3AoMCwgJyMwMDAnKTtcbiAgICBncmQuYWRkQ29sb3JTdG9wKDAuMiwgJyNiYmInKTtcbiAgICBncmQuYWRkQ29sb3JTdG9wKDAuNCwgJyNkMTgnKTtcbiAgICAvLyBkYXJrIGJsdWVcbiAgICBncmQuYWRkQ29sb3JTdG9wKDEsICcjZDE4Jyk7XG4gICAgY2FudmFzQ3R4LmZpbGxTdHlsZSA9IGdyZDsgKi9cblxuICAgIHRoaXMuYWN0aXZlID0gdHJ1ZTtcblxuICAgIHRoaXMuZGIgPSAtSW5maW5pdHk7XG5cbiAgICB0aGlzLmluaXQoKTtcblxuICAgIHRoaXMubWV0ZXJXaWR0aCA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgvdGhpcy5jaGFubmVscztcblxuICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgfVxuXG4gIGJ1aWxkRnJhbWUoKSB7XG4gICAgdGhpcy5jYW52YXMgPSBuZXcgZG9tLlNtYXJ0Q2FudmFzKHRoaXMucGFyZW50KTtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNhbnZhcy5lbGVtZW50O1xuICB9XG5cbiAgc2l6ZUludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5yZXNpemUodGhpcy53aWR0aCx0aGlzLmhlaWdodCk7XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICB0aGlzLmNhbnZhcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG4gIH1cblxuICByZW5kZXIoKSB7XG5cbiAgICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlci5iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxTdHlsZSA9IHRoaXMuY29sb3JzLmZpbGw7XG4gICAgdGhpcy5jYW52YXMuY29udGV4dC5maWxsUmVjdCgwLCAwLCB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoICwgdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQpO1xuXG4gICAgZm9yIChsZXQgaT0wO2k8dGhpcy5hbmFseXNlcnMubGVuZ3RoO2krKykge1xuXG4gICAgICBpZiAodGhpcy5zb3VyY2UpIHtcblxuICAgICAgICB0aGlzLmFuYWx5c2Vyc1tpXS5nZXRGbG9hdFRpbWVEb21haW5EYXRhKHRoaXMuZGF0YUFycmF5KTtcblxuICAgICAgICBsZXQgcm1zID0gMDtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZGF0YUFycmF5Lmxlbmd0aDsgaSsrKXtcbiAgICAgICAgICAgICBybXMgKz0gKHRoaXMuZGF0YUFycmF5W2ldICogdGhpcy5kYXRhQXJyYXlbaV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcm1zID0gTWF0aC5zcXJ0KHJtcyAvIHRoaXMuZGF0YUFycmF5Lmxlbmd0aCk7XG5cbiAgICAgICAgdGhpcy5kYiA9IDIwICogTWF0aC5sb2cxMChybXMpO1xuXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuZGIgPiAtMjAwICYmIHRoaXMuZGIgIT09IC1JbmZpbml0eSkge1xuICAgICAgICB0aGlzLmRiIC09IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRiID0gLUluZmluaXR5O1xuICAgICAgfVxuXG5cbiAgICAgIC8vY29uc29sZS5sb2coZGIpXG5cbiAgICAgIGlmICh0aGlzLmRiID4gLTcwKSB7XG5cbiAgICAgICAgbGV0IGxpbmVhciA9IG1hdGgubm9ybWFsaXplKHRoaXMuZGIsLTcwLDUpO1xuICAgICAgICBsZXQgZXhwID0gbGluZWFyICogbGluZWFyO1xuICAgICAgICBsZXQgeSA9IG1hdGguc2NhbGUoZXhwLDAsMSx0aGlzLmVsZW1lbnQuaGVpZ2h0LDApO1xuXG4gICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KHRoaXMubWV0ZXJXaWR0aCppLHksdGhpcy5tZXRlcldpZHRoLHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0IC0geSk7XG5cbiAgICAgICAgLy9jb25zb2xlLmxvZyhcInJlbmRlcmluZy4uLlwiKVxuXG4gICAgICB9XG5cbiAgICB9XG5cbiAgfVxuXG4gIC8qKlxuICBFcXVpdmFsZW50IHRvIFwicGF0Y2hpbmcgaW5cIiBhbiBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZS4gTk9URTogWW91IGNhbm5vdCBjb25uZWN0IGF1ZGlvIG5vZGVzIGFjcm9zcyB0d28gZGlmZmVyZW50IGF1ZGlvIGNvbnRleHRzLiBOZXh1c1VJIHJ1bnMgaXRzIGF1ZGlvIGFuYWx5c2lzIG9uIGl0cyBvd24gYXVkaW8gY29udGV4dCwgTmV4dXMuY29udGV4dC4gSWYgdGhlIGF1ZGlvIG5vZGUgeW91IGFyZSB2aXN1YWxpemluZyBpcyBjcmVhdGVkIG9uIGEgZGlmZmVyZW50IGF1ZGlvIGNvbnRleHQsIHlvdSB3aWxsIG5lZWQgdG8gdGVsbCBOZXh1c1VJIHRvIHVzZSB0aGF0IGNvbnRleHQgaW5zdGVhZDogaS5lLiBOZXh1cy5jb250ZXh0ID0gWW91ckF1ZGlvQ29udGV4dE5hbWUuIEZvciBleGFtcGxlLCBpbiBUb25lSlMgcHJvamVjdHMsIHRoZSBsaW5lIHdvdWxkIGJlOiBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC4gV2UgcmVjb21tZW5kIHRoYXQgeW91IHdyaXRlIHRoYXQgbGluZSBvZiBjb2RlIG9ubHkgb25jZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgcHJvamVjdC5cbiAgQHBhcmFtIG5vZGUge0F1ZGlvTm9kZX0gVGhlIGF1ZGlvIG5vZGUgdG8gdmlzdWFsaXplXG4gIEBwYXJhbSBjaGFubmVscyB7bnVtYmVyfSAob3B0aW9uYWwpIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIHNvdXJjZSBub2RlIHRvIHdhdGNoLiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgaW50ZXJmYWNlIHdpbGwgbG9vayBmb3IgYSAuY2hhbm5lbENvdW50IHByb3BlcnR5IG9uIHRoZSBpbnB1dCBub2RlLiBJZiBpdCBkb2VzIG5vdCBleGlzdCwgdGhlIGludGVyZmFjZSB3aWxsIGRlZmF1bHQgdG8gMSBjaGFubmVsLlxuICBAZXhhbXBsZSBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC8vIG9yIGFub3RoZXIgYXVkaW8gY29udGV4dCB5b3UgaGF2ZSBjcmVhdGVkXG4gIG1ldGVyLmNvbm5lY3QoIFRvbmUuTWFzdGVyLCAyICk7XG4gICovXG5cbiAgY29ubmVjdChub2RlLGNoYW5uZWxzKSB7XG4gICAgaWYgKHRoaXMuc291cmNlKSB7XG4gICAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG4gICAgLy90aGlzLmR1bW15LmRpc2Nvbm5lY3QodGhpcy5zcGxpdHRlcik7XG5cbiAgICBpZiAoY2hhbm5lbHMpIHtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVscztcbiAgICB9IGVsc2UgaWYgKG5vZGUuY2hhbm5lbENvdW50KSB7XG4gICAgICB0aGlzLmNoYW5uZWxzID0gbm9kZS5jaGFubmVsQ291bnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSAyO1xuICAgIH1cbiAgICB0aGlzLm1ldGVyV2lkdGggPSB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoL3RoaXMuY2hhbm5lbHM7XG5cbiAgICB0aGlzLnNvdXJjZSA9IG5vZGU7XG4gICAgdGhpcy5zb3VyY2UuY29ubmVjdCh0aGlzLnNwbGl0dGVyKTtcblxuICAvLyAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBTdG9wIHZpc3VhbGl6aW5nIHRoZSBzb3VyY2Ugbm9kZSBhbmQgZGlzY29ubmVjdCBpdC5cbiAgKi9cbiAgZGlzY29ubmVjdCgpIHtcblxuICAgIHRoaXMuc291cmNlLmRpc2Nvbm5lY3QodGhpcy5zcGxpdHRlcik7XG4gICAgdGhpcy5zb3VyY2UgPSBmYWxzZTtcbiAgLy8gIHRoaXMuZHVtbXkuY29ubmVjdCh0aGlzLnNwbGl0dGVyKTtcbiAgICB0aGlzLm1ldGVyV2lkdGggPSB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoL3RoaXMuY2hhbm5lbHM7XG5cbiAgfVxuXG4gIGNsaWNrKCkge1xuICAgIHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBjdXN0b21EZXN0cm95KCkge1xuICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL2ludGVyZmFjZXMvbWV0ZXIuanMiLCIndXNlIHN0cmljdCc7XG5cbmxldCBkb20gPSByZXF1aXJlKCcuLi91dGlsL2RvbScpO1xubGV0IEludGVyZmFjZSA9IHJlcXVpcmUoJy4uL2NvcmUvaW50ZXJmYWNlJyk7XG5cbi8qKlxuKiBPc2NpbGxvc2NvcGVcbipcbiogQGRlc2NyaXB0aW9uIFZpc3VhbGl6ZXMgYSB3YXZlZm9ybSdzIHN0cmVhbSBvZiB2YWx1ZXMuXG4qXG4qIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwib3NjaWxsb3Njb3BlXCI+PC9zcGFuPlxuKlxuKiBAZXhhbXBsZVxuKiB2YXIgb3NjaWxsb3Njb3BlID0gbmV3IE5leHVzLk9zY2lsbG9zY29wZSgnI3RhcmdldCcpXG4qXG4qIEBleGFtcGxlXG4qIHZhciBvc2NpbGxvc2NvcGUgPSBuZXcgTmV4dXMuT3NjaWxsb3Njb3BlKCcjdGFyZ2V0Jyx7XG4qICAgJ3NpemUnOiBbMzAwLDE1MF1cbiogfSlcbipcbiogQG91dHB1dFxuKiAmbmJzcDtcbiogTm8gZXZlbnRzXG4qXG4qL1xuXG5pbXBvcnQgeyBjb250ZXh0IH0gZnJvbSAnLi4vbWFpbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE9zY2lsbG9zY29wZSBleHRlbmRzIEludGVyZmFjZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgICBsZXQgb3B0aW9ucyA9IFsnc2NhbGUnLCd2YWx1ZSddO1xuXG4gICAgbGV0IGRlZmF1bHRzID0ge1xuICAgICAgJ3NpemUnOiBbMzAwLDE1MF1cbiAgICB9O1xuXG4gICAgc3VwZXIoYXJndW1lbnRzLG9wdGlvbnMsZGVmYXVsdHMpO1xuXG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dCgpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuICAgIHRoaXMuYW5hbHlzZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgICB0aGlzLmFuYWx5c2VyLmZmdFNpemUgPSAyMDQ4O1xuICAgIHRoaXMuYnVmZmVyTGVuZ3RoID0gdGhpcy5hbmFseXNlci5mcmVxdWVuY3lCaW5Db3VudDtcbiAgICB0aGlzLmRhdGFBcnJheSA9IG5ldyBVaW50OEFycmF5KHRoaXMuYnVmZmVyTGVuZ3RoKTtcbiAgICB0aGlzLmFuYWx5c2VyLmdldEJ5dGVUaW1lRG9tYWluRGF0YSh0aGlzLmRhdGFBcnJheSk7XG5cbiAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG5cbiAgICB0aGlzLnNvdXJjZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbml0KCk7XG5cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgYnVpbGRGcmFtZSgpIHtcbiAgICB0aGlzLmNhbnZhcyA9IG5ldyBkb20uU21hcnRDYW52YXModGhpcy5wYXJlbnQpO1xuICAgIHRoaXMuZWxlbWVudCA9IHRoaXMuY2FudmFzLmVsZW1lbnQ7XG4gIH1cblxuICBzaXplSW50ZXJmYWNlKCkge1xuICAgIHRoaXMuY2FudmFzLnJlc2l6ZSh0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcbiAgfVxuXG4gIGNvbG9ySW50ZXJmYWNlKCkge1xuICAgIHRoaXMuY2FudmFzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgfVxuXG4gIHJlbmRlcigpIHtcblxuICAgIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMucmVuZGVyLmJpbmQodGhpcykpO1xuICAgIH1cblxuICAgIHRoaXMuYW5hbHlzZXIuZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKHRoaXMuZGF0YUFycmF5KTtcblxuICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuZmlsbDtcbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KDAsIDAsIHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgsIHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0KTtcblxuICAgIHRoaXMuY2FudmFzLmNvbnRleHQubGluZVdpZHRoID0gfn4odGhpcy5oZWlnaHQgLyAxMDAgKyAyKTtcbiAgICB0aGlzLmNhbnZhcy5jb250ZXh0LnN0cm9rZVN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuXG4gICAgdGhpcy5jYW52YXMuY29udGV4dC5iZWdpblBhdGgoKTtcblxuICAgIGlmICh0aGlzLnNvdXJjZSkge1xuXG4gICAgICB2YXIgc2xpY2VXaWR0aCA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGggKiAxLjAgLyB0aGlzLmJ1ZmZlckxlbmd0aDtcbiAgICAgIHZhciB4ID0gMDtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJ1ZmZlckxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgdmFyIHYgPSB0aGlzLmRhdGFBcnJheVtpXSAvIDEyOC4wO1xuICAgICAgICB2YXIgeSA9IHYgKiB0aGlzLmNhbnZhcy5lbGVtZW50LmhlaWdodCAvIDI7XG5cbiAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0Lm1vdmVUbyh4LCB5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmxpbmVUbyh4LCB5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHggKz0gc2xpY2VXaWR0aDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0Lm1vdmVUbygwLCB0aGlzLmNhbnZhcy5lbGVtZW50LmhlaWdodC8yKTtcbiAgICAgICAgdGhpcy5jYW52YXMuY29udGV4dC5saW5lVG8odGhpcy5jYW52YXMuZWxlbWVudC53aWR0aCwgdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQvMik7XG4gICAgfVxuXG4gICAgdGhpcy5jYW52YXMuY29udGV4dC5zdHJva2UoKTtcbiAgfVxuXG4gIC8qKlxuICBFcXVpdmFsZW50IHRvIFwicGF0Y2hpbmcgaW5cIiBhbiBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZS4gTk9URTogWW91IGNhbm5vdCBjb25uZWN0IGF1ZGlvIG5vZGVzIGFjcm9zcyB0d28gZGlmZmVyZW50IGF1ZGlvIGNvbnRleHRzLiBOZXh1c1VJIHJ1bnMgaXRzIGF1ZGlvIGFuYWx5c2lzIG9uIGl0cyBvd24gYXVkaW8gY29udGV4dCwgTmV4dXMuY29udGV4dC4gSWYgdGhlIGF1ZGlvIG5vZGUgeW91IGFyZSB2aXN1YWxpemluZyBpcyBjcmVhdGVkIG9uIGEgZGlmZmVyZW50IGF1ZGlvIGNvbnRleHQsIHlvdSB3aWxsIG5lZWQgdG8gdGVsbCBOZXh1c1VJIHRvIHVzZSB0aGF0IGNvbnRleHQgaW5zdGVhZDogaS5lLiBOZXh1cy5jb250ZXh0ID0gWW91ckF1ZGlvQ29udGV4dE5hbWUuIEZvciBleGFtcGxlLCBpbiBUb25lSlMgcHJvamVjdHMsIHRoZSBsaW5lIHdvdWxkIGJlOiBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC4gV2UgcmVjb21tZW5kIHRoYXQgeW91IHdyaXRlIHRoYXQgbGluZSBvZiBjb2RlIG9ubHkgb25jZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgcHJvamVjdC5cbiAgQHBhcmFtIG5vZGUge0F1ZGlvTm9kZX0gVGhlIGF1ZGlvIG5vZGUgdG8gdmlzdWFsaXplXG4gIEBleGFtcGxlIE5leHVzLmNvbnRleHQgPSBUb25lLmNvbnRleHQgLy8gb3IgYW5vdGhlciBhdWRpbyBjb250ZXh0IHlvdSBoYXZlIGNyZWF0ZWRcbiAgb3NjaWxsb3Njb3BlLmNvbm5lY3QoIFRvbmUuTWFzdGVyICk7XG4gICovXG5cbiAgY29ubmVjdChub2RlKSB7XG5cbiAgICBpZiAodGhpcy5zb3VyY2UpIHtcbiAgICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIH1cblxuICAgIHRoaXMuc291cmNlID0gbm9kZTtcbiAgICB0aGlzLnNvdXJjZS5jb25uZWN0KHRoaXMuYW5hbHlzZXIpO1xuXG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICBTdG9wIHZpc3VhbGl6aW5nIHRoZSBzb3VyY2Ugbm9kZSBhbmQgZGlzY29ubmVjdCBpdC5cbiAgKi9cbiAgZGlzY29ubmVjdCgpIHtcbiAgICBpZiAodGhpcy5zb3VyY2UpIHtcbiAgICAgIHRoaXMuc291cmNlLmRpc2Nvbm5lY3QodGhpcy5hbmFseXNlcik7XG4gICAgICB0aGlzLnNvdXJjZSA9IG51bGw7XG4gICAgfVxuXG4gIH1cblxuICBjbGljaygpIHtcbiAgICB0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgY3VzdG9tRGVzdHJveSgpIHtcbiAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi9pbnRlcmZhY2VzL29zY2lsbG9zY29wZS5qcyIsIi8qXG5NYWluIGNvbmNlcHQ6XG5zeW50aCA9IG5ldyBOZXh1cy5SYWNrKCdlbGVtZW50SUQnKTtcblxuVHJhbnNmb3JtIGFsbCBlbGVtZW50cyBpbnNpZGUgdGhlIGRpdlxuc3ludGguZWxlbWVudElEIHdpbGwgaG9sZCB0aGUgZmlyc3Qgc2xpZGVyIGludGVyZmFjZVxuXG4yKSBJbiBmdXR1cmUsIHBvdGVudGlhbGx5IHdyaXRpbmcgYSByYWNrIHRoYXQgaXMgcmUtdXNhYmxlP1xuQ291bGQgYWxzbyB0YWtlIEpTT05cblxubmV3IE5leHVzLlJhY2soJyN0YXJnZXQnLHtcbiAgcHJlOiAoKSA9PiB7XG4gICAgY3JlYXRlIHNvbWUgZGl2cyBoZXJlLCBvciBzb21lIGF1ZGlvIGNvZGVcbiAgfSxcbiAgaW50ZXJmYWNlOiB7XG4gICAgc2xpZGVyMTogTmV4dXMuYWRkLnNsaWRlcih7XG4gICAgICB0b3A6MTAsXG4gICAgICBsZWZ0OjEwLFxuICAgICAgd2lkdGg6NTAsXG4gICAgICBoZWlnaHQ6MTAwLFxuICAgICAgbWluOiAwLFxuICAgICAgbWF4OiAxMDAsXG4gICAgICBzdGVwOiAxXG4gICAgfSksXG4gICAgd2F2ZTE6IE5leHVzLmFkZC53YXZlZm9ybSh7XG4gICAgICBmaWxlOiAnLi9wYXRoL3RvL2ZpbGUubXAzJyxcbiAgICAgIHdpZHRoOjUwMCxcbiAgICAgIGhlaWdodDoxMDAsXG4gICAgICBtb2RlOiAncmFuZ2UnXG4gICAgfSlcbiAgfSxcbiAgaW5pdDogKCkgPT4ge1xuICAgIC8vIHNvbWUgYXVkaW8gaW5pdCBjb2RlIGdvZXMgaGVyZS4uLlxuICB9XG59KTtcblxuKi9cblxuaW1wb3J0ICogYXMgdHJhbnNmb3JtIGZyb20gJy4uL3V0aWwvdHJhbnNmb3JtJztcbmltcG9ydCBkb20gZnJvbSAnLi4vdXRpbC9kb20nO1xuXG5pbXBvcnQgeyBjb2xvcnMgfSBmcm9tICcuLi9tYWluJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmFjayB7XG5cbiAgY29uc3RydWN0b3IodGFyZ2V0LCBzZXR0aW5ncykge1xuXG4gICAgdGhpcy5tZXRhID0ge307XG4gICAgdGhpcy5tZXRhLnRhcmdldCA9IHRhcmdldDtcbiAgICB0aGlzLm1ldGEucGFyZW50ID0gZG9tLnBhcnNlRWxlbWVudCh0YXJnZXQpOyAvLyBzaG91bGQgYmUgYSBnZW5lcmljIGZ1bmN0aW9uIGZvciBwYXJzaW5nIGEgJ3RhcmdldCcgYXJndW1lbnQgdGhhdCBjaGVja3MgZm9yIHN0cmluZy9ET00valFVRVJZXG4gICAgdGhpcy5tZXRhLmNvbG9ycyA9IHt9O1xuXG4gICAgaWYgKHNldHRpbmdzKSB7XG4gICAgICB0aGlzLm1ldGEuYXR0cmlidXRlID0gc2V0dGluZ3MuYXR0cmlidXRlIHx8ICduZXh1cy11aSc7XG4gICAgICB0aGlzLm1ldGEudGl0bGUgPSBzZXR0aW5ncy5uYW1lIHx8IGZhbHNlO1xuICAgICAgdGhpcy5tZXRhLm9wZW4gPSBzZXR0aW5ncy5vcGVuIHx8IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1ldGEuYXR0cmlidXRlID0gJ25leHVzLXVpJztcbiAgICAgIHRoaXMubWV0YS50aXRsZSA9IGZhbHNlO1xuICAgICAgdGhpcy5tZXRhLm9wZW4gPSBmYWxzZTtcbiAgICB9XG5cbiAgICBsZXQgZGVmYXVsdENvbG9ycyA9IGNvbG9ycygpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgICB0aGlzLm1ldGEuY29sb3JzLmFjY2VudCA9IGRlZmF1bHRDb2xvcnMuYWNjZW50O1xuICAgIHRoaXMubWV0YS5jb2xvcnMuZmlsbCA9IGRlZmF1bHRDb2xvcnMuZmlsbDtcbiAgICB0aGlzLm1ldGEuY29sb3JzLmxpZ2h0ID0gZGVmYXVsdENvbG9ycy5saWdodDtcbiAgICB0aGlzLm1ldGEuY29sb3JzLmRhcmsgPSBkZWZhdWx0Q29sb3JzLmRhcms7XG4gICAgdGhpcy5tZXRhLmNvbG9ycy5tZWRpdW1MaWdodCA9IGRlZmF1bHRDb2xvcnMubWVkaXVtTGlnaHQ7XG4gICAgdGhpcy5tZXRhLmNvbG9ycy5tZWRpdW1EYXJrID0gZGVmYXVsdENvbG9ycy5tZWRpdW1EYXJrO1xuICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcbiAgICB0aGlzLmNvbG9ySW50ZXJmYWNlKCk7XG4gIH1cblxuICBidWlsZEludGVyZmFjZSgpIHtcbiAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLmJveFNpemluZyA9ICdib3JkZXItYm94JztcbiAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLnVzZXJTZWxlY3QgPSAnbm9uZSc7XG4gICAgdGhpcy5tZXRhLnBhcmVudC5zdHlsZS5tb3pVc2VyU2VsZWN0ID0gJ25vbmUnO1xuICAgIHRoaXMubWV0YS5wYXJlbnQuc3R5bGUud2Via2l0VXNlclNlbGVjdCA9ICdub25lJztcblxuICAgIHRoaXMubWV0YS5jb250ZW50cyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG4gICAgd2hpbGUgKHRoaXMubWV0YS5wYXJlbnQuY2hpbGROb2Rlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMubWV0YS5jb250ZW50cy5hcHBlbmRDaGlsZCh0aGlzLm1ldGEucGFyZW50LmNoaWxkTm9kZXNbMF0pO1xuICAgIH1cblxuICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5wYWRkaW5nID0gJzBweCc7XG4gICAgdGhpcy5tZXRhLmNvbnRlbnRzLnN0eWxlLmJveFNpemluZyA9ICdib3JkZXItYm94JztcblxuICAgIGlmICh0aGlzLm1ldGEudGl0bGUpIHtcbiAgICAgIHRoaXMubWV0YS50aXRsZUJhciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLmlubmVySFRNTCA9IHRoaXMubWV0YS50aXRsZTtcbiAgICAgIHRoaXMubWV0YS50aXRsZUJhci5zdHlsZS5mb250RmFtaWx5ID0gJ2FyaWFsJztcbiAgICAgIHRoaXMubWV0YS50aXRsZUJhci5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgICB0aGlzLm1ldGEudGl0bGVCYXIuc3R5bGUuY29sb3IgPSAnIzg4OCc7XG4gICAgICB0aGlzLm1ldGEudGl0bGVCYXIuc3R5bGUucGFkZGluZyA9ICc3cHgnO1xuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLnN0eWxlLmZvbnRTaXplID0gJzEycHgnO1xuXG4gICAgICB0aGlzLm1ldGEuYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUudG9wID0gJzVweCcgO1xuICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5yaWdodCA9ICc1cHgnIDtcbiAgICAgIHRoaXMubWV0YS5idXR0b24uaW5uZXJIVE1MID0gJy0nO1xuICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5wYWRkaW5nID0gJzBweCA1cHggMnB4JztcbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUubGluZUhlaWdodCA9ICcxMnB4JztcbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUuZm9udFNpemUgPSAnMTVweCc7XG5cbiAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInO1xuXG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3ZlcicsICgpID0+IHtcbiAgICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLm1lZGl1bURhcms7XG4gICAgICB9KTtcbiAgICAgIHRoaXMubWV0YS5idXR0b24uYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLm1lZGl1bUxpZ2h0O1xuICAgICAgfSk7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tZXRhLm9wZW4pIHtcbiAgICAgICAgICB0aGlzLmhpZGUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNob3coKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cblxuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLmFwcGVuZENoaWxkKHRoaXMubWV0YS5idXR0b24pO1xuXG4gICAgICB0aGlzLm1ldGEucGFyZW50LmFwcGVuZENoaWxkKHRoaXMubWV0YS50aXRsZUJhcik7XG4gICAgfVxuICAgIHRoaXMubWV0YS5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5tZXRhLmNvbnRlbnRzKTtcblxuICAvLyAgdmFyIHdpZHRoID0gdGhpcy5tZXRhLnBhcmVudC5zdHlsZS53aWR0aCA9IGdldENvbXB1dGVkU3R5bGUodGhpcy5tZXRhLnBhcmVudCkuZ2V0UHJvcGVydHlWYWx1ZSgnd2lkdGgnKTtcbi8vICAgIHRoaXMubWV0YS5wYXJlbnQuc3R5bGUud2lkdGggPSB3aWR0aDtcblxuICAgIGxldCB1aSA9IHRyYW5zZm9ybS5zZWN0aW9uKHRoaXMubWV0YS50YXJnZXQsIHRoaXMubWV0YS5hdHRyaWJ1dGUpO1xuICAgIGZvciAodmFyIGtleSBpbiB1aSkge1xuICAgICAgdGhpc1trZXldID0gdWlba2V5XTtcbiAgICB9XG4gIH1cblxuICBjb2xvckludGVyZmFjZSgpIHtcbiAgICBpZiAodGhpcy5tZXRhLnRpdGxlKSB7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMubWV0YS5jb2xvcnMubWVkaXVtTGlnaHQ7XG4gICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLmJvcmRlciA9ICdzb2xpZCAwcHggJyt0aGlzLm1ldGEuY29sb3JzLmZpbGw7XG4gICAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLmJvcmRlciA9ICdzb2xpZCAxcHggJyt0aGlzLm1ldGEuY29sb3JzLm1lZGl1bUxpZ2h0O1xuICAgICAgdGhpcy5tZXRhLnBhcmVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLmxpZ2h0O1xuICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMubWV0YS5jb2xvcnMuZmlsbDtcbiAgICB9XG4gIH1cblxuICBzaG93KCkge1xuICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICB0aGlzLm1ldGEub3BlbiA9IHRydWU7XG4gIH1cblxuICBoaWRlKCkge1xuICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHRoaXMubWV0YS5vcGVuID0gZmFsc2U7XG4gIH1cblxuICBjb2xvcml6ZSh0eXBlLGNvbG9yKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMpIHtcbiAgICAgIGlmICh0aGlzW2tleV0uY29sb3JpemUpIHtcbiAgICAgICAgdGhpc1trZXldLmNvbG9yaXplKHR5cGUsY29sb3IpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLm1ldGEuY29sb3JzW3R5cGVdID0gY29sb3I7XG4gICAgdGhpcy5jb2xvckludGVyZmFjZSgpO1xuICB9XG5cbiAgZW1wdHkoKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMpIHtcbiAgICAgIGlmICh0aGlzW2tleV0uZGVzdHJveSkge1xuICAgICAgICB0aGlzW2tleV0uZGVzdHJveSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvY29yZS9yYWNrLmpzIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgZG9tIGZyb20gJy4uL3V0aWwvZG9tJztcbmltcG9ydCBJbnRlcmZhY2VzIGZyb20gJy4uL2ludGVyZmFjZXMvJztcblxubGV0IGNyZWF0ZUludGVyZmFjZUlEID0gKHdpZGdldCxpbnRlcmZhY2VJRHMpID0+IHtcbiAgbGV0IHR5cGUgPSB3aWRnZXQudHlwZTtcbiAgaWYgKGludGVyZmFjZUlEc1t0eXBlXSkge1xuICAgIGludGVyZmFjZUlEc1t0eXBlXSsrO1xuICB9IGVsc2Uge1xuICAgIGludGVyZmFjZUlEc1t0eXBlXSA9IDE7XG4gIH1cbiAgcmV0dXJuICggdHlwZSArIGludGVyZmFjZUlEc1t0eXBlXSApO1xufTtcblxubGV0IGVsZW1lbnQgPSAoZWxlbWVudCx0eXBlLG9wdGlvbnMpID0+IHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudC5hdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKXtcbiAgICBsZXQgYXR0ID0gZWxlbWVudC5hdHRyaWJ1dGVzW2ldO1xuICAvLyAgdHJ5IHtcbiAgLy8gICAgb3B0aW9uc1thdHQubm9kZU5hbWVdID0gZXZhbChhdHQubm9kZVZhbHVlKTtcbiAgLy8gIH0gY2F0Y2goZSkge1xuICAgICAgb3B0aW9uc1thdHQubm9kZU5hbWVdID0gYXR0Lm5vZGVWYWx1ZTtcbiAgLy8gIH1cbiAgfVxuICB0eXBlID0gdHlwZVswXS50b1VwcGVyQ2FzZSgpICsgdHlwZS5zbGljZSgxKTtcbiAgbGV0IHdpZGdldCA9IG5ldyBJbnRlcmZhY2VzW3R5cGVdKGVsZW1lbnQsb3B0aW9ucyk7XG4gIHdpZGdldC5pZCA9IGVsZW1lbnQuaWQ7XG4gIHJldHVybiB3aWRnZXQ7XG59O1xuXG5cbmxldCBzZWN0aW9uID0gKHBhcmVudCxrZXl3b3JkKSA9PiB7XG5cbiAga2V5d29yZCA9IGtleXdvcmQgfHwgJ25leHVzLXVpJztcblxuICBsZXQgaW50ZXJmYWNlSURzID0ge307XG5cbiAgbGV0IGNvbnRhaW5lciA9IGRvbS5wYXJzZUVsZW1lbnQocGFyZW50KTtcblxuICBsZXQgdWkgPSB7fTtcblxuICBsZXQgaHRtbEVsZW1lbnRzID0gY29udGFpbmVyLmdldEVsZW1lbnRzQnlUYWdOYW1lKCcqJyk7XG4gIGxldCBlbGVtZW50cyA9IFtdO1xuICBmb3IgKGxldCBpPTA7IGk8aHRtbEVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgZWxlbWVudHMucHVzaChodG1sRWxlbWVudHNbaV0pO1xuICB9XG4gIGZvciAobGV0IGk9MDtpPGVsZW1lbnRzLmxlbmd0aDtpKyspIHtcbiAgICBsZXQgdHlwZSA9IGVsZW1lbnRzW2ldLmdldEF0dHJpYnV0ZShrZXl3b3JkKTtcbiAgICBpZiAodHlwZSkge1xuICAgICAgbGV0IGZvcm1hdHRlZFR5cGUgPSBmYWxzZTtcbiAgICAgIGZvciAobGV0IGtleSBpbiBJbnRlcmZhY2VzKSB7XG4gICAgICAgIGlmICh0eXBlLnRvTG93ZXJDYXNlKCk9PT1rZXkudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgIGZvcm1hdHRlZFR5cGUgPSBrZXk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnNvbGUubG9nKGZvcm1hdHRlZFR5cGUpO1xuICAgICAgbGV0IHdpZGdldCA9IGVsZW1lbnQoZWxlbWVudHNbaV0sZm9ybWF0dGVkVHlwZSk7XG4gICAgICBpZiAod2lkZ2V0LmlkKSB7XG4gICAgICAgIHVpW3dpZGdldC5pZF0gPSB3aWRnZXQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgaWQgPSBjcmVhdGVJbnRlcmZhY2VJRCh3aWRnZXQsaW50ZXJmYWNlSURzKTtcbiAgICAgICAgdWlbaWRdID0gd2lkZ2V0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1aTtcblxufTtcblxubGV0IGFkZCA9ICh0eXBlLHBhcmVudCxvcHRpb25zKSA9PiB7XG4gIGxldCB0YXJnZXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGlmIChwYXJlbnQpIHtcbiAgICBwYXJlbnQgPSBkb20ucGFyc2VFbGVtZW50KHBhcmVudCk7XG4gIH0gZWxzZSB7XG4gICAgcGFyZW50ID0gZG9jdW1lbnQuYm9keTtcbiAgfVxuICBwYXJlbnQuYXBwZW5kQ2hpbGQodGFyZ2V0KTtcbiAgb3B0aW9ucy50YXJnZXQgPSB0YXJnZXQ7XG4gIGlmIChvcHRpb25zLnNpemUpIHtcbiAgICB0YXJnZXQuc3R5bGUud2lkdGggPSBvcHRpb25zLnNpemVbMF0gKyAncHgnO1xuICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSBvcHRpb25zLnNpemVbMV0gKyAncHgnO1xuICB9XG4gIHJldHVybiBlbGVtZW50KHRhcmdldCx0eXBlLG9wdGlvbnMpO1xufTtcblxuZXhwb3J0IHsgZWxlbWVudCB9O1xuZXhwb3J0IHsgc2VjdGlvbiB9O1xuZXhwb3J0IHsgYWRkIH07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvdXRpbC90cmFuc2Zvcm0uanMiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBtYXRoIGZyb20gJy4uL3V0aWwvbWF0aCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFR1bmUge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gIFx0Ly8gdGhlIHNjYWxlIGFzIHJhdGlvc1xuICBcdHRoaXMuc2NhbGUgPSBbXTtcblxuICBcdC8vIGkvbyBtb2Rlc1xuICBcdHRoaXMubW9kZSA9IHtcbiAgXHRcdG91dHB1dDogJ2ZyZXF1ZW5jeScsXG4gIFx0XHRpbnB1dDogJ3N0ZXAnXG4gIFx0fTtcblxuICBcdC8vIEVUIG1ham9yXG4gIFx0dGhpcy5ldG1ham9yID0gWyAyNjEuNjI1NTgsXG4gIFx0XHQyOTMuNjY0NzY0LFxuICBcdFx0MzI5LjYyNzU2MyxcbiAgXHRcdDM0OS4yMjgyNDEsXG4gIFx0XHQzOTEuOTk1NDIyLFxuICBcdFx0NDQwLFxuICBcdFx0NDkzLjg4MzMwMSxcbiAgXHRcdDUyMy4yNTExNlxuICBcdF07XG5cbiAgXHQvLyBSb290IGZyZXF1ZW5jeS5cbiAgXHR0aGlzLnJvb3QgPSBtYXRoLm10b2YoNjApOyAgICAgLy8gKiBNYXRoLnBvdygyLCg2MC02OSkvMTIpO1xuXG4gICAgLy8gZGVmYXVsdCBpcyBhIG1ham9yIHNjYWxlXG4gICAgdGhpcy5jcmVhdGVTY2FsZSgwLDIsNCw1LDcsOSwxMSk7XG5cbiAgfVxuXG4gIC8qIFJldHVybiBkYXRhIGluIHRoZSBtb2RlIHlvdSBhcmUgaW4gKGZyZXEsIHJhdGlvLCBvciBtaWRpKSAqL1xuICBub3RlKGlucHV0LG9jdGF2ZSkge1xuXG4gIFx0bGV0IG5ld3ZhbHVlO1xuXG4gIFx0aWYgKHRoaXMubW9kZS5vdXRwdXQgPT09ICdmcmVxdWVuY3knKSB7XG4gIFx0XHRuZXd2YWx1ZSA9IHRoaXMuZnJlcXVlbmN5KGlucHV0LG9jdGF2ZSk7XG4gIFx0fSBlbHNlIGlmICh0aGlzLm1vZGUub3V0cHV0ID09PSAncmF0aW8nKSB7XG4gIFx0XHRuZXd2YWx1ZSA9IHRoaXMucmF0aW8oaW5wdXQsb2N0YXZlKTtcbiAgXHR9IGVsc2UgaWYgKHRoaXMubW9kZS5vdXRwdXQgPT09ICdNSURJJykge1xuICBcdFx0bmV3dmFsdWUgPSB0aGlzLk1JREkoaW5wdXQsb2N0YXZlKTtcbiAgXHR9IGVsc2Uge1xuICBcdFx0bmV3dmFsdWUgPSB0aGlzLmZyZXF1ZW5jeShpbnB1dCxvY3RhdmUpO1xuICBcdH1cblxuICBcdHJldHVybiBuZXd2YWx1ZTtcblxuICB9XG5cblxuICAvKiBSZXR1cm4gZnJlcSBkYXRhICovXG4gIGZyZXF1ZW5jeShzdGVwSW4sIG9jdGF2ZUluKSB7XG5cbiAgXHRpZiAodGhpcy5tb2RlLmlucHV0ID09PSAnbWlkaScgfHwgdGhpcy5tb2RlLmlucHV0ID09PSAnTUlESScgKSB7XG4gIFx0XHR0aGlzLnN0ZXBJbiArPSA2MDtcbiAgXHR9XG5cbiAgXHQvLyB3aGF0IG9jdGF2ZSBpcyBvdXIgaW5wdXRcbiAgXHRsZXQgb2N0YXZlID0gTWF0aC5mbG9vcihzdGVwSW4vdGhpcy5zY2FsZS5sZW5ndGgpO1xuXG4gIFx0aWYgKG9jdGF2ZUluKSB7XG4gIFx0XHRvY3RhdmUgKz0gb2N0YXZlSW47XG4gIFx0fVxuXG4gIFx0Ly8gd2hpY2ggc2NhbGUgZGVncmVlICgwIC0gc2NhbGUgbGVuZ3RoKSBpcyBvdXIgaW5wdXRcbiAgXHRsZXQgc2NhbGVEZWdyZWUgPSBzdGVwSW4gJSB0aGlzLnNjYWxlLmxlbmd0aDtcblxuICBcdHdoaWxlIChzY2FsZURlZ3JlZSA8IDApIHtcbiAgXHRcdHNjYWxlRGVncmVlICs9IHRoaXMuc2NhbGUubGVuZ3RoO1xuICBcdH1cblxuICAgIGxldCByYXRpbyA9IHRoaXMuc2NhbGVbc2NhbGVEZWdyZWVdO1xuXG4gIFx0bGV0IGZyZXEgPSB0aGlzLnJvb3QgKiByYXRpbztcblxuICBcdGZyZXEgPSBmcmVxKihNYXRoLnBvdygyLG9jdGF2ZSkpO1xuXG4gIFx0Ly8gdHJ1bmNhdGUgaXJyYXRpb25hbCBudW1iZXJzXG4gIFx0ZnJlcSA9IE1hdGguZmxvb3IoZnJlcSoxMDAwMDAwMDAwMDApLzEwMDAwMDAwMDAwMDtcblxuICBcdHJldHVybiBmcmVxO1xuXG4gIH1cblxuICAvKiBGb3JjZSByZXR1cm4gcmF0aW8gZGF0YSAqL1xuXG4gIHJhdGlvKHN0ZXBJbiwgb2N0YXZlSW4pIHtcblxuICBcdGlmICh0aGlzLm1vZGUuaW5wdXQgPT09ICdtaWRpJyB8fCB0aGlzLm1vZGUuaW5wdXQgPT09ICdNSURJJyApIHtcbiAgXHRcdHRoaXMuc3RlcEluICs9IDYwO1xuICBcdH1cblxuICBcdC8vIHdoYXQgb2N0YXZlIGlzIG91ciBpbnB1dFxuICBcdGxldCBvY3RhdmUgPSBNYXRoLmZsb29yKHN0ZXBJbi90aGlzLnNjYWxlLmxlbmd0aCk7XG5cbiAgXHRpZiAob2N0YXZlSW4pIHtcbiAgXHRcdG9jdGF2ZSArPSBvY3RhdmVJbjtcbiAgXHR9XG5cbiAgXHQvLyB3aGljaCBzY2FsZSBkZWdyZWUgKDAgLSBzY2FsZSBsZW5ndGgpIGlzIG91ciBpbnB1dFxuICBcdGxldCBzY2FsZURlZ3JlZSA9IHN0ZXBJbiAlIHRoaXMuc2NhbGUubGVuZ3RoO1xuXG4gIFx0Ly8gd2hhdCByYXRpbyBpcyBvdXIgaW5wdXQgdG8gb3VyIGtleVxuICBcdGxldCByYXRpbyA9IE1hdGgucG93KDIsb2N0YXZlKSp0aGlzLnNjYWxlW3NjYWxlRGVncmVlXTtcblxuICBcdHJhdGlvID0gTWF0aC5mbG9vcihyYXRpbyoxMDAwMDAwMDAwMDApLzEwMDAwMDAwMDAwMDtcblxuICBcdHJldHVybiByYXRpbztcblxuICB9XG5cbiAgLyogRm9yY2UgcmV0dXJuIGFkanVzdGVkIE1JREkgZGF0YSAqL1xuXG4gIE1JREkoc3RlcEluLG9jdGF2ZUluKSB7XG5cbiAgXHRsZXQgbmV3dmFsdWUgPSB0aGlzLmZyZXF1ZW5jeShzdGVwSW4sb2N0YXZlSW4pO1xuXG4gIFx0bGV0IG4gPSA2OSArIDEyKk1hdGgubG9nKG5ld3ZhbHVlLzQ0MCkvTWF0aC5sb2coMik7XG5cbiAgXHRuID0gTWF0aC5mbG9vcihuKjEwMDAwMDAwMDApLzEwMDAwMDAwMDA7XG5cbiAgXHRyZXR1cm4gbjtcblxuICB9XG5cbiAgY3JlYXRlU2NhbGUoKSB7XG4gICAgbGV0IG5ld1NjYWxlID0gW107XG4gICAgZm9yIChsZXQgaT0wO2k8YXJndW1lbnRzLmxlbmd0aDtpKyspIHtcbiAgICAgIG5ld1NjYWxlLnB1c2goIG1hdGgubXRvZiggNjAgKyBhcmd1bWVudHNbaV0gKSApO1xuICAgIH1cbiAgICB0aGlzLmxvYWRTY2FsZUZyb21GcmVxdWVuY2llcyhuZXdTY2FsZSk7XG4gIH1cblxuICBjcmVhdGVKSVNjYWxlKCkge1xuICAgIHRoaXMuc2NhbGUgPSBbXTtcbiAgICBmb3IgKGxldCBpPTA7aTxhcmd1bWVudHMubGVuZ3RoO2krKykge1xuICAgICAgdGhpcy5zY2FsZS5wdXNoKGFyZ3VtZW50c1tpXSk7XG4gICAgfVxuICB9XG5cbiAgbG9hZFNjYWxlRnJvbUZyZXF1ZW5jaWVzKGZyZXFzKSB7XG4gICAgdGhpcy5zY2FsZSA9IFtdO1xuICAgIGZvciAobGV0IGk9MDtpPGZyZXFzLmxlbmd0aC0xO2krKykge1xuICAgICAgdGhpcy5zY2FsZS5wdXNoKGZyZXFzW2ldL2ZyZXFzWzBdKTtcbiAgICB9XG4gIH1cblxuICAvKiBMb2FkIGEgbmV3IHNjYWxlICovXG5cbiAgbG9hZFNjYWxlKG5hbWUpe1xuXG4gIFx0LyogbG9hZCB0aGUgc2NhbGUgKi9cbiAgXHRsZXQgZnJlcXMgPSB0aGlzLnNjYWxlc1tuYW1lXS5mcmVxdWVuY2llcztcbiAgICB0aGlzLmxvYWRTY2FsZUZyb21GcmVxdWVuY2llcyhmcmVxcyk7XG5cbiAgfVxuXG4gIC8qIFNlYXJjaCB0aGUgbmFtZXMgb2YgdHVuaW5nc1xuICBcdCBSZXR1cm5zIGFuIGFycmF5IG9mIG5hbWVzIG9mIHR1bmluZ3MgKi9cblxuICBzZWFyY2gobGV0dGVycykge1xuICBcdGxldCBwb3NzaWJsZSA9IFtdO1xuICBcdGZvciAobGV0IGtleSBpbiB0aGlzLnNjYWxlcykge1xuICBcdFx0aWYgKGtleS50b0xvd2VyQ2FzZSgpLmluZGV4T2YobGV0dGVycy50b0xvd2VyQ2FzZSgpKSAhPT0gLTEpIHtcbiAgXHRcdFx0cG9zc2libGUucHVzaChrZXkpO1xuICBcdFx0fVxuICBcdH1cbiAgXHRyZXR1cm4gcG9zc2libGU7XG4gIH1cblxuICAvKiBSZXR1cm4gYSBjb2xsZWN0aW9uIG9mIG5vdGVzIGFzIGFuIGFycmF5ICovXG5cbiAgY2hvcmQobWlkaXMpIHtcbiAgXHRsZXQgb3V0cHV0ID0gW107XG4gIFx0Zm9yIChsZXQgaT0wO2k8bWlkaXMubGVuZ3RoO2krKykge1xuICBcdFx0b3V0cHV0LnB1c2godGhpcy5ub3RlKG1pZGlzW2ldKSk7XG4gIFx0fVxuICBcdHJldHVybiBvdXRwdXQ7XG4gIH1cblxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vfi9qc2hpbnQtbG9hZGVyIS4vbGliL3R1bmluZy90dW5pbmcuanMiLCIndXNlIHN0cmljdCc7XG5cbi8vRGlzYWJsZSBqc2hpbnQgd2FybmluZyBjb25jZXJuaW5nIHRyYWlsaW5nIHJlZ3VsYXIgcGFyYW1zXG4vKmpzaGludCAtVzEzOCAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSYWRpbyB7XG4gICAgLy9pZiBub24tZXhpc3RlbnQgYnV0dG9ucyBhcmUgc3dpdGNoZWQsIHRoZXkgYXJlIGlnbm9yZWRcblxuICAgIGNvbnN0cnVjdG9yKGxlbmd0aCA9IDMsIC4uLm9uVmFscykge1xuICAgICAgICAvL2VhY2ggb3B0aW9uYWwgJ29uVmFscycgYXJndW1lbnQgc3dpdGNoZXMgb24gdGhhdCB2YWx1ZSBpbiB0aGUgUmFkaW8gaWYgaXQgZXhpc3RzXG4gICAgICAgIC8vSW4gdGhlIGV4YW1wbGUgYmVsb3csIGEgMy1idXR0b24gcmFkaW8gaXMgY3JlYXRlZCwgaW5kZXggMCBpcyBzd2l0Y2hlZCBvbiwgaW5kZXggMSBpcyBzd2l0Y2hlZCBvbiB0aGVuIHRoZW4gYXR0ZW1wdGVkIGFnYWluIHByb2R1Y2luZyBhbiB3YXJuaW5nLCBhbmQgdGhlIGZpbmFsIGFyZ3VtZW50IHByb2R1Y2VzIGEgd2FybmluZyBiZWNhdXNlIHRoZSBpbmRleCB2YWx1ZSBkb2VzIG5vdCBleGlzdC5cbiAgICAgICAgLy9FeGFtcGxlOlxuICAgICAgICAvL2AgIHJhZGlvID0gbmV3IFJhZGlvKDMsIDAsIDEsIDEsIDMpO1xuICAgICAgICAvL+KApiAgWzEsMSwwXVxuXG4gICAgICAgIGlmIChsZW5ndGggPCAwKSB7IGxlbmd0aCA9IDE7IH1cblxuICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcbiAgICAgICAgdGhpcy5vblZhbHMgPSBvblZhbHM7XG4gICAgICAgIHRoaXMuYXJyYXkgPSBuZXcgQXJyYXkobGVuZ3RoKS5maWxsKDApO1xuXG4gICAgICAgIGlmIChvblZhbHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5vbiguLi5vblZhbHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2VsZWN0KHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYXJyYXkuZmlsbCgwKTtcbiAgICAgICAgdGhpcy5hcnJheVt2YWx1ZV0gPSAxO1xuICAgICAgICByZXR1cm4gdGhpcy5hcnJheTtcbiAgICB9XG5cbiAgICBmbGlwKC4uLnZhbHVlcykge1xuICAgICAgICAvL2ZsaXBzIHRoZSBzcGVjaWZpZWQgdmFsdWVzLiBpZiBubyB2YWx1ZSBpcyBzcGVjaWZpZWQsIGZsaXBzIGFsbCBidXR0b25zXG4gICAgICAgIGxldCBhID0gdGhpcy5hcnJheTtcbiAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB2YWx1ZXMuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgICAgICAgICAgaWYgKHYgPiBhLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdXYXJuaW5nOiBBbm9uUmFkaW9bJyArIHYgKyAnXSBkb2VzIG5vdCBleGlzdCcpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFbdl0gPSAoYVt2XSA/IDAgOiAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGEuZm9yRWFjaChmdW5jdGlvbih2LCBpLCBhcnIpIHtcbiAgICAgICAgICAgICAgICBhcnJbaV0gPSAodiA/IDAgOiAxKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhO1xuICAgIH1cblxuICAgIG9uKC4uLnZhbHVlcykge1xuICAgICAgICAvL3N3aXRjaCBvbiB0aGUgc3BlY2lmaWVkIHZhbHVlcy4gaWYgbm8gdmFsdWUgc3BlY2lmaWVkLCBmbGlwcyBvbiBhbGwgYnV0dG9uc1xuICAgICAgICBsZXQgYSA9IHRoaXMuYXJyYXk7XG4gICAgICAgIGlmICh2YWx1ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdmFsdWVzLmZvckVhY2goZnVuY3Rpb24odikge1xuICAgICAgICAgICAgICAgIGlmICh2ID4gYS5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignV2FybmluZzogQW5vblJhZGlvWycgKyB2ICsgJ10gZXhjZWVkcyBzaXplIG9mIG9iamVjdCcpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhW3ZdID09PSAxKSB7IGNvbnNvbGUud2FybignV2FybmluZzogQW5vblJhZGlvWycgKyB2ICsgJ10gd2FzIGFscmVhZHkgb24uJyk7IH1cbiAgICAgICAgICAgICAgICAgICAgYVt2XSA9IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhLmZpbGwoMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgb2ZmKC4uLnZhbHVlcykge1xuICAgICAgICAvL3N3aXRjaCBvZmYgdGhlIHNwZWNpZmllZCB2YWx1ZXMuIGlmIG5vIHZhbHVlIHNwZWNpZmllZCwgZmxpcHMgb2ZmIGFsbCBidXR0b25zXG4gICAgICAgIGxldCBhID0gdGhpcy5hcnJheTtcbiAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB2YWx1ZXMuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgICAgICAgICAgYVt2XSA9IDA7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGEuZmlsbCgwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYTtcbiAgICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9+L2pzaGludC1sb2FkZXIhLi9saWIvbW9kZWxzL3JhZGlvLmpzIiwidmFyIFdBQUNsb2NrID0gcmVxdWlyZSgnLi9saWIvV0FBQ2xvY2snKVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdBQUNsb2NrXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHdpbmRvdy5XQUFDbG9jayA9IFdBQUNsb2NrXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vd2FhY2xvY2svaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDQyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBpc0Jyb3dzZXIgPSAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpXG5cbnZhciBDTE9DS19ERUZBVUxUUyA9IHtcbiAgdG9sZXJhbmNlTGF0ZTogMC4xMCxcbiAgdG9sZXJhbmNlRWFybHk6IDAuMDAxXG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09IEV2ZW50ID09PT09PT09PT09PT09PT09PT09IC8vXG52YXIgRXZlbnQgPSBmdW5jdGlvbihjbG9jaywgZGVhZGxpbmUsIGZ1bmMpIHtcbiAgdGhpcy5jbG9jayA9IGNsb2NrXG4gIHRoaXMuZnVuYyA9IGZ1bmNcbiAgdGhpcy5fY2xlYXJlZCA9IGZhbHNlIC8vIEZsYWcgdXNlZCB0byBjbGVhciBhbiBldmVudCBpbnNpZGUgY2FsbGJhY2tcblxuICB0aGlzLnRvbGVyYW5jZUxhdGUgPSBjbG9jay50b2xlcmFuY2VMYXRlXG4gIHRoaXMudG9sZXJhbmNlRWFybHkgPSBjbG9jay50b2xlcmFuY2VFYXJseVxuICB0aGlzLl9sYXRlc3RUaW1lID0gbnVsbFxuICB0aGlzLl9lYXJsaWVzdFRpbWUgPSBudWxsXG4gIHRoaXMuZGVhZGxpbmUgPSBudWxsXG4gIHRoaXMucmVwZWF0VGltZSA9IG51bGxcblxuICB0aGlzLnNjaGVkdWxlKGRlYWRsaW5lKVxufVxuXG4vLyBVbnNjaGVkdWxlcyB0aGUgZXZlbnRcbkV2ZW50LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuICB0aGlzLl9jbGVhcmVkID0gdHJ1ZVxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBTZXRzIHRoZSBldmVudCB0byByZXBlYXQgZXZlcnkgYHRpbWVgIHNlY29uZHMuXG5FdmVudC5wcm90b3R5cGUucmVwZWF0ID0gZnVuY3Rpb24odGltZSkge1xuICBpZiAodGltZSA9PT0gMClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlbGF5IGNhbm5vdCBiZSAwJylcbiAgdGhpcy5yZXBlYXRUaW1lID0gdGltZVxuICBpZiAoIXRoaXMuY2xvY2suX2hhc0V2ZW50KHRoaXMpKVxuICAgIHRoaXMuc2NoZWR1bGUodGhpcy5kZWFkbGluZSArIHRoaXMucmVwZWF0VGltZSlcbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gU2V0cyB0aGUgdGltZSB0b2xlcmFuY2Ugb2YgdGhlIGV2ZW50LlxuLy8gVGhlIGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQgaW4gdGhlIGludGVydmFsIGBbZGVhZGxpbmUgLSBlYXJseSwgZGVhZGxpbmUgKyBsYXRlXWBcbi8vIElmIHRoZSBjbG9jayBmYWlscyB0byBleGVjdXRlIHRoZSBldmVudCBpbiB0aW1lLCB0aGUgZXZlbnQgd2lsbCBiZSBkcm9wcGVkLlxuRXZlbnQucHJvdG90eXBlLnRvbGVyYW5jZSA9IGZ1bmN0aW9uKHZhbHVlcykge1xuICBpZiAodHlwZW9mIHZhbHVlcy5sYXRlID09PSAnbnVtYmVyJylcbiAgICB0aGlzLnRvbGVyYW5jZUxhdGUgPSB2YWx1ZXMubGF0ZVxuICBpZiAodHlwZW9mIHZhbHVlcy5lYXJseSA9PT0gJ251bWJlcicpXG4gICAgdGhpcy50b2xlcmFuY2VFYXJseSA9IHZhbHVlcy5lYXJseVxuICB0aGlzLl9yZWZyZXNoRWFybHlMYXRlRGF0ZXMoKVxuICBpZiAodGhpcy5jbG9jay5faGFzRXZlbnQodGhpcykpIHtcbiAgICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuICAgIHRoaXMuY2xvY2suX2luc2VydEV2ZW50KHRoaXMpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBldmVudCBpcyByZXBlYXRlZCwgZmFsc2Ugb3RoZXJ3aXNlXG5FdmVudC5wcm90b3R5cGUuaXNSZXBlYXRlZCA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5yZXBlYXRUaW1lICE9PSBudWxsIH1cblxuLy8gU2NoZWR1bGVzIHRoZSBldmVudCB0byBiZSByYW4gYmVmb3JlIGBkZWFkbGluZWAuXG4vLyBJZiB0aGUgdGltZSBpcyB3aXRoaW4gdGhlIGV2ZW50IHRvbGVyYW5jZSwgd2UgaGFuZGxlIHRoZSBldmVudCBpbW1lZGlhdGVseS5cbi8vIElmIHRoZSBldmVudCB3YXMgYWxyZWFkeSBzY2hlZHVsZWQgYXQgYSBkaWZmZXJlbnQgdGltZSwgaXQgaXMgcmVzY2hlZHVsZWQuXG5FdmVudC5wcm90b3R5cGUuc2NoZWR1bGUgPSBmdW5jdGlvbihkZWFkbGluZSkge1xuICB0aGlzLl9jbGVhcmVkID0gZmFsc2VcbiAgdGhpcy5kZWFkbGluZSA9IGRlYWRsaW5lXG4gIHRoaXMuX3JlZnJlc2hFYXJseUxhdGVEYXRlcygpXG5cbiAgaWYgKHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSA+PSB0aGlzLl9lYXJsaWVzdFRpbWUpIHtcbiAgICB0aGlzLl9leGVjdXRlKClcbiAgXG4gIH0gZWxzZSBpZiAodGhpcy5jbG9jay5faGFzRXZlbnQodGhpcykpIHtcbiAgICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuICAgIHRoaXMuY2xvY2suX2luc2VydEV2ZW50KHRoaXMpXG4gIFxuICB9IGVsc2UgdGhpcy5jbG9jay5faW5zZXJ0RXZlbnQodGhpcylcbn1cblxuRXZlbnQucHJvdG90eXBlLnRpbWVTdHJldGNoID0gZnVuY3Rpb24odFJlZiwgcmF0aW8pIHtcbiAgaWYgKHRoaXMuaXNSZXBlYXRlZCgpKVxuICAgIHRoaXMucmVwZWF0VGltZSA9IHRoaXMucmVwZWF0VGltZSAqIHJhdGlvXG5cbiAgdmFyIGRlYWRsaW5lID0gdFJlZiArIHJhdGlvICogKHRoaXMuZGVhZGxpbmUgLSB0UmVmKVxuICAvLyBJZiB0aGUgZGVhZGxpbmUgaXMgdG9vIGNsb3NlIG9yIHBhc3QsIGFuZCB0aGUgZXZlbnQgaGFzIGEgcmVwZWF0LFxuICAvLyB3ZSBjYWxjdWxhdGUgdGhlIG5leHQgcmVwZWF0IHBvc3NpYmxlIGluIHRoZSBzdHJldGNoZWQgc3BhY2UuXG4gIGlmICh0aGlzLmlzUmVwZWF0ZWQoKSkge1xuICAgIHdoaWxlICh0aGlzLmNsb2NrLmNvbnRleHQuY3VycmVudFRpbWUgPj0gZGVhZGxpbmUgLSB0aGlzLnRvbGVyYW5jZUVhcmx5KVxuICAgICAgZGVhZGxpbmUgKz0gdGhpcy5yZXBlYXRUaW1lXG4gIH1cbiAgdGhpcy5zY2hlZHVsZShkZWFkbGluZSlcbn1cblxuLy8gRXhlY3V0ZXMgdGhlIGV2ZW50XG5FdmVudC5wcm90b3R5cGUuX2V4ZWN1dGUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuY2xvY2suX3N0YXJ0ZWQgPT09IGZhbHNlKSByZXR1cm5cbiAgdGhpcy5jbG9jay5fcmVtb3ZlRXZlbnQodGhpcylcblxuICBpZiAodGhpcy5jbG9jay5jb250ZXh0LmN1cnJlbnRUaW1lIDwgdGhpcy5fbGF0ZXN0VGltZSlcbiAgICB0aGlzLmZ1bmModGhpcylcbiAgZWxzZSB7XG4gICAgaWYgKHRoaXMub25leHBpcmVkKSB0aGlzLm9uZXhwaXJlZCh0aGlzKVxuICAgIGNvbnNvbGUud2FybignZXZlbnQgZXhwaXJlZCcpXG4gIH1cbiAgLy8gSW4gdGhlIGNhc2UgYHNjaGVkdWxlYCBpcyBjYWxsZWQgaW5zaWRlIGBmdW5jYCwgd2UgbmVlZCB0byBhdm9pZFxuICAvLyBvdmVycndyaXRpbmcgd2l0aCB5ZXQgYW5vdGhlciBgc2NoZWR1bGVgLlxuICBpZiAoIXRoaXMuY2xvY2suX2hhc0V2ZW50KHRoaXMpICYmIHRoaXMuaXNSZXBlYXRlZCgpICYmICF0aGlzLl9jbGVhcmVkKVxuICAgIHRoaXMuc2NoZWR1bGUodGhpcy5kZWFkbGluZSArIHRoaXMucmVwZWF0VGltZSkgXG59XG5cbi8vIFVwZGF0ZXMgY2FjaGVkIHRpbWVzXG5FdmVudC5wcm90b3R5cGUuX3JlZnJlc2hFYXJseUxhdGVEYXRlcyA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9sYXRlc3RUaW1lID0gdGhpcy5kZWFkbGluZSArIHRoaXMudG9sZXJhbmNlTGF0ZVxuICB0aGlzLl9lYXJsaWVzdFRpbWUgPSB0aGlzLmRlYWRsaW5lIC0gdGhpcy50b2xlcmFuY2VFYXJseVxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PSBXQUFDbG9jayA9PT09PT09PT09PT09PT09PT09PSAvL1xudmFyIFdBQUNsb2NrID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihjb250ZXh0LCBvcHRzKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBvcHRzID0gb3B0cyB8fCB7fVxuICB0aGlzLnRpY2tNZXRob2QgPSBvcHRzLnRpY2tNZXRob2QgfHwgJ1NjcmlwdFByb2Nlc3Nvck5vZGUnXG4gIHRoaXMudG9sZXJhbmNlRWFybHkgPSBvcHRzLnRvbGVyYW5jZUVhcmx5IHx8IENMT0NLX0RFRkFVTFRTLnRvbGVyYW5jZUVhcmx5XG4gIHRoaXMudG9sZXJhbmNlTGF0ZSA9IG9wdHMudG9sZXJhbmNlTGF0ZSB8fCBDTE9DS19ERUZBVUxUUy50b2xlcmFuY2VMYXRlXG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHRcbiAgdGhpcy5fZXZlbnRzID0gW11cbiAgdGhpcy5fc3RhcnRlZCA9IGZhbHNlXG59XG5cbi8vIC0tLS0tLS0tLS0gUHVibGljIEFQSSAtLS0tLS0tLS0tIC8vXG4vLyBTY2hlZHVsZXMgYGZ1bmNgIHRvIHJ1biBhZnRlciBgZGVsYXlgIHNlY29uZHMuXG5XQUFDbG9jay5wcm90b3R5cGUuc2V0VGltZW91dCA9IGZ1bmN0aW9uKGZ1bmMsIGRlbGF5KSB7XG4gIHJldHVybiB0aGlzLl9jcmVhdGVFdmVudChmdW5jLCB0aGlzLl9hYnNUaW1lKGRlbGF5KSlcbn1cblxuLy8gU2NoZWR1bGVzIGBmdW5jYCB0byBydW4gYmVmb3JlIGBkZWFkbGluZWAuXG5XQUFDbG9jay5wcm90b3R5cGUuY2FsbGJhY2tBdFRpbWUgPSBmdW5jdGlvbihmdW5jLCBkZWFkbGluZSkge1xuICByZXR1cm4gdGhpcy5fY3JlYXRlRXZlbnQoZnVuYywgZGVhZGxpbmUpXG59XG5cbi8vIFN0cmV0Y2hlcyBgZGVhZGxpbmVgIGFuZCBgcmVwZWF0YCBvZiBhbGwgc2NoZWR1bGVkIGBldmVudHNgIGJ5IGByYXRpb2AsIGtlZXBpbmdcbi8vIHRoZWlyIHJlbGF0aXZlIGRpc3RhbmNlIHRvIGB0UmVmYC4gSW4gZmFjdCB0aGlzIGlzIGVxdWl2YWxlbnQgdG8gY2hhbmdpbmcgdGhlIHRlbXBvLlxuV0FBQ2xvY2sucHJvdG90eXBlLnRpbWVTdHJldGNoID0gZnVuY3Rpb24odFJlZiwgZXZlbnRzLCByYXRpbykge1xuICBldmVudHMuZm9yRWFjaChmdW5jdGlvbihldmVudCkgeyBldmVudC50aW1lU3RyZXRjaCh0UmVmLCByYXRpbykgfSlcbiAgcmV0dXJuIGV2ZW50c1xufVxuXG4vLyBSZW1vdmVzIGFsbCBzY2hlZHVsZWQgZXZlbnRzIGFuZCBzdGFydHMgdGhlIGNsb2NrIFxuV0FBQ2xvY2sucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLl9zdGFydGVkID09PSBmYWxzZSkge1xuICAgIHZhciBzZWxmID0gdGhpc1xuICAgIHRoaXMuX3N0YXJ0ZWQgPSB0cnVlXG4gICAgdGhpcy5fZXZlbnRzID0gW11cblxuICAgIGlmICh0aGlzLnRpY2tNZXRob2QgPT09ICdTY3JpcHRQcm9jZXNzb3JOb2RlJykge1xuICAgICAgdmFyIGJ1ZmZlclNpemUgPSAyNTZcbiAgICAgIC8vIFdlIGhhdmUgdG8ga2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgbm9kZSB0byBhdm9pZCBnYXJiYWdlIGNvbGxlY3Rpb25cbiAgICAgIHRoaXMuX2Nsb2NrTm9kZSA9IHRoaXMuY29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IoYnVmZmVyU2l6ZSwgMSwgMSlcbiAgICAgIHRoaXMuX2Nsb2NrTm9kZS5jb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbilcbiAgICAgIHRoaXMuX2Nsb2NrTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbigpIHsgc2VsZi5fdGljaygpIH0pXG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0aGlzLnRpY2tNZXRob2QgPT09ICdtYW51YWwnKSBudWxsIC8vIF90aWNrIGlzIGNhbGxlZCBtYW51YWxseVxuXG4gICAgZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgdGlja01ldGhvZCAnICsgdGhpcy50aWNrTWV0aG9kKVxuICB9XG59XG5cbi8vIFN0b3BzIHRoZSBjbG9ja1xuV0FBQ2xvY2sucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuX3N0YXJ0ZWQgPT09IHRydWUpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2VcbiAgICB0aGlzLl9jbG9ja05vZGUuZGlzY29ubmVjdCgpXG4gIH0gIFxufVxuXG4vLyAtLS0tLS0tLS0tIFByaXZhdGUgLS0tLS0tLS0tLSAvL1xuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIHJhbiBwZXJpb2RpY2FsbHksIGFuZCBhdCBlYWNoIHRpY2sgaXQgZXhlY3V0ZXNcbi8vIGV2ZW50cyBmb3Igd2hpY2ggYGN1cnJlbnRUaW1lYCBpcyBpbmNsdWRlZCBpbiB0aGVpciB0b2xlcmFuY2UgaW50ZXJ2YWwuXG5XQUFDbG9jay5wcm90b3R5cGUuX3RpY2sgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGV2ZW50ID0gdGhpcy5fZXZlbnRzLnNoaWZ0KClcblxuICB3aGlsZShldmVudCAmJiBldmVudC5fZWFybGllc3RUaW1lIDw9IHRoaXMuY29udGV4dC5jdXJyZW50VGltZSkge1xuICAgIGV2ZW50Ll9leGVjdXRlKClcbiAgICBldmVudCA9IHRoaXMuX2V2ZW50cy5zaGlmdCgpXG4gIH1cblxuICAvLyBQdXQgYmFjayB0aGUgbGFzdCBldmVudFxuICBpZihldmVudCkgdGhpcy5fZXZlbnRzLnVuc2hpZnQoZXZlbnQpXG59XG5cbi8vIENyZWF0ZXMgYW4gZXZlbnQgYW5kIGluc2VydCBpdCB0byB0aGUgbGlzdFxuV0FBQ2xvY2sucHJvdG90eXBlLl9jcmVhdGVFdmVudCA9IGZ1bmN0aW9uKGZ1bmMsIGRlYWRsaW5lKSB7XG4gIHJldHVybiBuZXcgRXZlbnQodGhpcywgZGVhZGxpbmUsIGZ1bmMpXG59XG5cbi8vIEluc2VydHMgYW4gZXZlbnQgdG8gdGhlIGxpc3RcbldBQUNsb2NrLnByb3RvdHlwZS5faW5zZXJ0RXZlbnQgPSBmdW5jdGlvbihldmVudCkge1xuICB0aGlzLl9ldmVudHMuc3BsaWNlKHRoaXMuX2luZGV4QnlUaW1lKGV2ZW50Ll9lYXJsaWVzdFRpbWUpLCAwLCBldmVudClcbn1cblxuLy8gUmVtb3ZlcyBhbiBldmVudCBmcm9tIHRoZSBsaXN0XG5XQUFDbG9jay5wcm90b3R5cGUuX3JlbW92ZUV2ZW50ID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgdmFyIGluZCA9IHRoaXMuX2V2ZW50cy5pbmRleE9mKGV2ZW50KVxuICBpZiAoaW5kICE9PSAtMSkgdGhpcy5fZXZlbnRzLnNwbGljZShpbmQsIDEpXG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiBgZXZlbnRgIGlzIGluIHF1ZXVlLCBmYWxzZSBvdGhlcndpc2VcbldBQUNsb2NrLnByb3RvdHlwZS5faGFzRXZlbnQgPSBmdW5jdGlvbihldmVudCkge1xuIHJldHVybiB0aGlzLl9ldmVudHMuaW5kZXhPZihldmVudCkgIT09IC0xXG59XG5cbi8vIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBldmVudCB3aG9zZSBkZWFkbGluZSBpcyA+PSB0byBgZGVhZGxpbmVgXG5XQUFDbG9jay5wcm90b3R5cGUuX2luZGV4QnlUaW1lID0gZnVuY3Rpb24oZGVhZGxpbmUpIHtcbiAgLy8gcGVyZm9ybXMgYSBiaW5hcnkgc2VhcmNoXG4gIHZhciBsb3cgPSAwXG4gICAgLCBoaWdoID0gdGhpcy5fZXZlbnRzLmxlbmd0aFxuICAgICwgbWlkXG4gIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgbWlkID0gTWF0aC5mbG9vcigobG93ICsgaGlnaCkgLyAyKVxuICAgIGlmICh0aGlzLl9ldmVudHNbbWlkXS5fZWFybGllc3RUaW1lIDwgZGVhZGxpbmUpXG4gICAgICBsb3cgPSBtaWQgKyAxXG4gICAgZWxzZSBoaWdoID0gbWlkXG4gIH1cbiAgcmV0dXJuIGxvd1xufVxuXG4vLyBDb252ZXJ0cyBmcm9tIHJlbGF0aXZlIHRpbWUgdG8gYWJzb2x1dGUgdGltZVxuV0FBQ2xvY2sucHJvdG90eXBlLl9hYnNUaW1lID0gZnVuY3Rpb24ocmVsVGltZSkge1xuICByZXR1cm4gcmVsVGltZSArIHRoaXMuY29udGV4dC5jdXJyZW50VGltZVxufVxuXG4vLyBDb252ZXJ0cyBmcm9tIGFic29sdXRlIHRpbWUgdG8gcmVsYXRpdmUgdGltZSBcbldBQUNsb2NrLnByb3RvdHlwZS5fcmVsVGltZSA9IGZ1bmN0aW9uKGFic1RpbWUpIHtcbiAgcmV0dXJuIGFic1RpbWUgLSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWVcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vd2FhY2xvY2svbGliL1dBQUNsb2NrLmpzXG4vLyBtb2R1bGUgaWQgPSA0M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRPbmNlTGlzdGVuZXIgPSBub29wO1xuXG5wcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Byb2Nlc3MvYnJvd3Nlci5qc1xuLy8gbW9kdWxlIGlkID0gNDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBjbG9jayB9IGZyb20gJy4uL21haW4nO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJbnRlcnZhbCB7XG5cbiAgY29uc3RydWN0b3IocmF0ZSxmdW5jLG9uKSB7XG5cbiAgICB0aGlzLnJhdGUgPSByYXRlO1xuICAgIHRoaXMub24gPSBvbjtcbiAgICB0aGlzLmNsb2NrID0gY2xvY2soKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgICB0aGlzLnBhdHRlcm4gPSBbMV07XG4gICAgdGhpcy5pbmRleCA9IDA7XG5cbiAgICB0aGlzLmV2ZW50ID0gZnVuYyA/IGZ1bmMgOiBmdW5jdGlvbigpIHsgfTtcblxuICAgIGlmICh0aGlzLm9uKSB7XG4gICAgICB0aGlzLnN0YXJ0KCk7XG4gICAgfVxuXG4gIH1cblxuICBfZXZlbnQoZSkge1xuICAvLyAgaWYgKHRoaXMucGF0dGVyblt0aGlzLmluZGV4JXRoaXMucGF0dGVybi5sZW5ndGhdKSB7XG4gICAgICB0aGlzLmV2ZW50KGUpO1xuICAvLyAgfVxuICAgIHRoaXMuaW5kZXgrKztcbiAgfVxuXG4gIHN0b3AoKSB7XG4gICAgdGhpcy5vbiA9IGZhbHNlO1xuICAgIHRoaXMuaW50ZXJ2YWwuY2xlYXIoKTtcbiAgfVxuXG4gIHN0YXJ0KCkge1xuICAgIHRoaXMub24gPSB0cnVlO1xuICAgIHRoaXMuaW50ZXJ2YWwgPSB0aGlzLmNsb2NrLmNhbGxiYWNrQXRUaW1lKHRoaXMuX2V2ZW50LmJpbmQodGhpcyksIHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSkucmVwZWF0KHRoaXMucmF0ZS8xMDAwKS50b2xlcmFuY2Uoe2Vhcmx5OiAwLjEsIGxhdGU6MX0pO1xuICB9XG5cbiAgbXMobmV3cmF0ZSkge1xuICAgIGlmICh0aGlzLm9uKSB7XG4gICAgICB2YXIgcmF0aW8gPSBuZXdyYXRlL3RoaXMucmF0ZTtcbiAgICAgIHRoaXMucmF0ZSA9IG5ld3JhdGU7XG4gICAgICB0aGlzLmNsb2NrLnRpbWVTdHJldGNoKHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSwgW3RoaXMuaW50ZXJ2YWxdLCByYXRpbyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmF0ZSA9IG5ld3JhdGU7XG4gICAgfVxuICB9XG5cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL34vanNoaW50LWxvYWRlciEuL2xpYi90aW1lL2ludGVydmFsLmpzIl0sInNvdXJjZVJvb3QiOiIifQ== + +/***/ }), +/* 57 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(97), __esModule: true }; + +/***/ }), +/* 58 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(2).document && document.documentElement; + +/***/ }), +/* 59 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = !__webpack_require__(6) && !__webpack_require__(13)(function(){ + return Object.defineProperty(__webpack_require__(36)('div'), 'a', {get: function(){ return 7; }}).a != 7; +}); + +/***/ }), +/* 60 */ +/***/ (function(module, exports, __webpack_require__) { + +// fallback for non-array-like ES3 and non-enumerable old V8 strings +var cof = __webpack_require__(17); +module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){ + return cof(it) == 'String' ? it.split('') : Object(it); +}; + +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { + +// check on default Array iterator +var Iterators = __webpack_require__(14) + , ITERATOR = __webpack_require__(1)('iterator') + , ArrayProto = Array.prototype; + +module.exports = function(it){ + return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); +}; + +/***/ }), +/* 62 */ +/***/ (function(module, exports, __webpack_require__) { + +// call something on iterator step with safe closing on error +var anObject = __webpack_require__(4); +module.exports = function(iterator, fn, value, entries){ + try { + return entries ? fn(anObject(value)[0], value[1]) : fn(value); + // 7.4.6 IteratorClose(iterator, completion) + } catch(e){ + var ret = iterator['return']; + if(ret !== undefined)anObject(ret.call(iterator)); + throw e; + } +}; + +/***/ }), +/* 63 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var LIBRARY = __webpack_require__(25) + , $export = __webpack_require__(7) + , redefine = __webpack_require__(68) + , hide = __webpack_require__(9) + , has = __webpack_require__(8) + , Iterators = __webpack_require__(14) + , $iterCreate = __webpack_require__(110) + , setToStringTag = __webpack_require__(27) + , getPrototypeOf = __webpack_require__(119) + , ITERATOR = __webpack_require__(1)('iterator') + , BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next` + , FF_ITERATOR = '@@iterator' + , KEYS = 'keys' + , VALUES = 'values'; + +var returnThis = function(){ return this; }; + +module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){ + $iterCreate(Constructor, NAME, next); + var getMethod = function(kind){ + if(!BUGGY && kind in proto)return proto[kind]; + switch(kind){ + case KEYS: return function keys(){ return new Constructor(this, kind); }; + case VALUES: return function values(){ return new Constructor(this, kind); }; + } return function entries(){ return new Constructor(this, kind); }; + }; + var TAG = NAME + ' Iterator' + , DEF_VALUES = DEFAULT == VALUES + , VALUES_BUG = false + , proto = Base.prototype + , $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT] + , $default = $native || getMethod(DEFAULT) + , $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined + , $anyNative = NAME == 'Array' ? proto.entries || $native : $native + , methods, key, IteratorPrototype; + // Fix native + if($anyNative){ + IteratorPrototype = getPrototypeOf($anyNative.call(new Base)); + if(IteratorPrototype !== Object.prototype){ + // Set @@toStringTag to native iterators + setToStringTag(IteratorPrototype, TAG, true); + // fix for some old engines + if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis); + } + } + // fix Array#{values, @@iterator}.name in V8 / FF + if(DEF_VALUES && $native && $native.name !== VALUES){ + VALUES_BUG = true; + $default = function values(){ return $native.call(this); }; + } + // Define iterator + if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){ + hide(proto, ITERATOR, $default); + } + // Plug for library + Iterators[NAME] = $default; + Iterators[TAG] = returnThis; + if(DEFAULT){ + methods = { + values: DEF_VALUES ? $default : getMethod(VALUES), + keys: IS_SET ? $default : getMethod(KEYS), + entries: $entries + }; + if(FORCED)for(key in methods){ + if(!(key in proto))redefine(proto, key, methods[key]); + } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); + } + return methods; +}; + +/***/ }), +/* 64 */ +/***/ (function(module, exports, __webpack_require__) { + +var ITERATOR = __webpack_require__(1)('iterator') + , SAFE_CLOSING = false; + +try { + var riter = [7][ITERATOR](); + riter['return'] = function(){ SAFE_CLOSING = true; }; + Array.from(riter, function(){ throw 2; }); +} catch(e){ /* empty */ } + +module.exports = function(exec, skipClosing){ + if(!skipClosing && !SAFE_CLOSING)return false; + var safe = false; + try { + var arr = [7] + , iter = arr[ITERATOR](); + iter.next = function(){ return {done: safe = true}; }; + arr[ITERATOR] = function(){ return iter; }; + exec(arr); + } catch(e){ /* empty */ } + return safe; +}; + +/***/ }), +/* 65 */ +/***/ (function(module, exports, __webpack_require__) { + +// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) +var anObject = __webpack_require__(4) + , dPs = __webpack_require__(116) + , enumBugKeys = __webpack_require__(37) + , IE_PROTO = __webpack_require__(39)('IE_PROTO') + , Empty = function(){ /* empty */ } + , PROTOTYPE = 'prototype'; + +// Create object with fake `null` prototype: use iframe Object with cleared prototype +var createDict = function(){ + // Thrash, waste and sodomy: IE GC bug + var iframe = __webpack_require__(36)('iframe') + , i = enumBugKeys.length + , lt = '<' + , gt = '>' + , iframeDocument; + iframe.style.display = 'none'; + __webpack_require__(58).appendChild(iframe); + iframe.src = 'javascript:'; // eslint-disable-line no-script-url + // createDict = iframe.contentWindow.Object; + // html.removeChild(iframe); + iframeDocument = iframe.contentWindow.document; + iframeDocument.open(); + iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); + iframeDocument.close(); + createDict = iframeDocument.F; + while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]]; + return createDict(); +}; + +module.exports = Object.create || function create(O, Properties){ + var result; + if(O !== null){ + Empty[PROTOTYPE] = anObject(O); + result = new Empty; + Empty[PROTOTYPE] = null; + // add "__proto__" for Object.getPrototypeOf polyfill + result[IE_PROTO] = O; + } else result = createDict(); + return Properties === undefined ? result : dPs(result, Properties); +}; + + +/***/ }), +/* 66 */ +/***/ (function(module, exports, __webpack_require__) { + +// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O) +var $keys = __webpack_require__(67) + , hiddenKeys = __webpack_require__(37).concat('length', 'prototype'); + +exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O){ + return $keys(O, hiddenKeys); +}; + +/***/ }), +/* 67 */ +/***/ (function(module, exports, __webpack_require__) { + +var has = __webpack_require__(8) + , toIObject = __webpack_require__(10) + , arrayIndexOf = __webpack_require__(104)(false) + , IE_PROTO = __webpack_require__(39)('IE_PROTO'); + +module.exports = function(object, names){ + var O = toIObject(object) + , i = 0 + , result = [] + , key; + for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key); + // Don't enum bug & hidden keys + while(names.length > i)if(has(O, key = names[i++])){ + ~arrayIndexOf(result, key) || result.push(key); + } + return result; +}; + +/***/ }), +/* 68 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(9); + +/***/ }), +/* 69 */ +/***/ (function(module, exports, __webpack_require__) { + +var ctx = __webpack_require__(18) + , invoke = __webpack_require__(108) + , html = __webpack_require__(58) + , cel = __webpack_require__(36) + , global = __webpack_require__(2) + , process = global.process + , setTask = global.setImmediate + , clearTask = global.clearImmediate + , MessageChannel = global.MessageChannel + , counter = 0 + , queue = {} + , ONREADYSTATECHANGE = 'onreadystatechange' + , defer, channel, port; +var run = function(){ + var id = +this; + if(queue.hasOwnProperty(id)){ + var fn = queue[id]; + delete queue[id]; + fn(); + } +}; +var listener = function(event){ + run.call(event.data); +}; +// Node.js 0.9+ & IE10+ has setImmediate, otherwise: +if(!setTask || !clearTask){ + setTask = function setImmediate(fn){ + var args = [], i = 1; + while(arguments.length > i)args.push(arguments[i++]); + queue[++counter] = function(){ + invoke(typeof fn == 'function' ? fn : Function(fn), args); + }; + defer(counter); + return counter; + }; + clearTask = function clearImmediate(id){ + delete queue[id]; + }; + // Node.js 0.8- + if(__webpack_require__(17)(process) == 'process'){ + defer = function(id){ + process.nextTick(ctx(run, id, 1)); + }; + // Browsers with MessageChannel, includes WebWorkers + } else if(MessageChannel){ + channel = new MessageChannel; + port = channel.port2; + channel.port1.onmessage = listener; + defer = ctx(port.postMessage, port, 1); + // Browsers with postMessage, skip WebWorkers + // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' + } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){ + defer = function(id){ + global.postMessage(id + '', '*'); + }; + global.addEventListener('message', listener, false); + // IE8- + } else if(ONREADYSTATECHANGE in cel('script')){ + defer = function(id){ + html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){ + html.removeChild(this); + run.call(id); + }; + }; + // Rest old browsers + } else { + defer = function(id){ + setTimeout(ctx(run, id, 1), 0); + }; + } +} +module.exports = { + set: setTask, + clear: clearTask +}; + +/***/ }), +/* 70 */ +/***/ (function(module, exports) { + + + +/***/ }), +/* 71 */ +/***/ (function(module, exports) { + +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + + +/***/ }), +/* 72 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(process) { + +module.exports = Readable; + +/*<replacement>*/ +var processNextTick = __webpack_require__(49); +/*</replacement>*/ + +/*<replacement>*/ +var isArray = __webpack_require__(71); +/*</replacement>*/ + +/*<replacement>*/ +var Duplex; +/*</replacement>*/ + +Readable.ReadableState = ReadableState; + +/*<replacement>*/ +var EE = __webpack_require__(47).EventEmitter; + +var EElistenerCount = function (emitter, type) { + return emitter.listeners(type).length; +}; +/*</replacement>*/ + +/*<replacement>*/ +var Stream = __webpack_require__(74); +/*</replacement>*/ + +var Buffer = __webpack_require__(3).Buffer; +/*<replacement>*/ +var bufferShim = __webpack_require__(32); +/*</replacement>*/ + +/*<replacement>*/ +var util = __webpack_require__(22); +util.inherits = __webpack_require__(16); +/*</replacement>*/ + +/*<replacement>*/ +var debugUtil = __webpack_require__(158); +var debug = void 0; +if (debugUtil && debugUtil.debuglog) { + debug = debugUtil.debuglog('stream'); +} else { + debug = function () {}; +} +/*</replacement>*/ + +var BufferList = __webpack_require__(144); +var StringDecoder; + +util.inherits(Readable, Stream); + +var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; + +function prependListener(emitter, event, fn) { + // Sadly this is not cacheable as some libraries bundle their own + // event emitter implementation with them. + if (typeof emitter.prependListener === 'function') { + return emitter.prependListener(event, fn); + } else { + // This is a hack to make sure that our error handler is attached before any + // userland ones. NEVER DO THIS. This is here only because this code needs + // to continue to work with older versions of Node.js that do not include + // the prependListener() method. The goal is to eventually remove this hack. + if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; + } +} + +function ReadableState(options, stream) { + Duplex = Duplex || __webpack_require__(12); + + options = options || {}; + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + // A linked list is used to store data chunks instead of an array because the + // linked list can remove elements from the beginning faster than + // array.shift() + this.buffer = new BufferList(); + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + this.resumeScheduled = false; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) StringDecoder = __webpack_require__(48).StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } +} + +function Readable(options) { + Duplex = Duplex || __webpack_require__(12); + + if (!(this instanceof Readable)) return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + if (options && typeof options.read === 'function') this._read = options.read; + + Stream.call(this); +} + +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function (chunk, encoding) { + var state = this._readableState; + + if (!state.objectMode && typeof chunk === 'string') { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = bufferShim.from(chunk, encoding); + encoding = ''; + } + } + + return readableAddChunk(this, state, chunk, encoding, false); +}; + +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function (chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); +}; + +Readable.prototype.isPaused = function () { + return this._readableState.flowing === false; +}; + +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (chunk === null) { + state.reading = false; + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var _e = new Error('stream.unshift() after end event'); + stream.emit('error', _e); + } else { + var skipAdd; + if (state.decoder && !addToFront && !encoding) { + chunk = state.decoder.write(chunk); + skipAdd = !state.objectMode && chunk.length === 0; + } + + if (!addToFront) state.reading = false; + + // Don't add to the buffer if we've decoded to an empty string chunk and + // we're not in object mode + if (!skipAdd) { + // if we want the data now, just emit it. + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); + + if (state.needReadable) emitReadable(stream); + } + } + + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; + } + + return needMoreData(state); +} + +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); +} + +// backwards compatibility. +Readable.prototype.setEncoding = function (enc) { + if (!StringDecoder) StringDecoder = __webpack_require__(48).StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; +}; + +// Don't raise the hwm > 8MB +var MAX_HWM = 0x800000; +function computeNewHighWaterMark(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 to prevent increasing hwm excessively in + // tiny amounts + n--; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + n++; + } + return n; +} + +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function howMuchToRead(n, state) { + if (n <= 0 || state.length === 0 && state.ended) return 0; + if (state.objectMode) return 1; + if (n !== n) { + // Only flow one buffer at a time + if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; + } + // If we're asking for more than the current hwm, then raise the hwm. + if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); + if (n <= state.length) return n; + // Don't have enough + if (!state.ended) { + state.needReadable = true; + return 0; + } + return state.length; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function (n) { + debug('read', n); + n = parseInt(n, 10); + var state = this._readableState; + var nOrig = n; + + if (n !== 0) state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) endReadable(this); + return null; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } else if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (!state.reading) n = howMuchToRead(nOrig, state); + } + + var ret; + if (n > 0) ret = fromList(n, state);else ret = null; + + if (ret === null) { + state.needReadable = true; + n = 0; + } else { + state.length -= n; + } + + if (state.length === 0) { + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (!state.ended) state.needReadable = true; + + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended) endReadable(this); + } + + if (ret !== null) this.emit('data', ret); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + +function onEofChunk(stream, state) { + if (state.ended) return; + if (state.decoder) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); +} + +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); + } +} + +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); +} + +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + processNextTick(maybeReadMore_, stream, state); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break;else len = state.length; + } + state.readingMore = false; +} + +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function (n) { + this.emit('error', new Error('_read() is not implemented')); +}; + +Readable.prototype.pipe = function (dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + debug('onunpipe'); + if (readable === src) { + cleanup(); + } + } + + function onend() { + debug('onend'); + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + + var cleanedUp = false; + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', cleanup); + src.removeListener('data', ondata); + + cleanedUp = true; + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); + } + + // If the user pushes more data while we're writing to dest then we'll end up + // in ondata again. However, we only want to increase awaitDrain once because + // dest will only emit one 'drain' event for the multiple writes. + // => Introduce a guard on increasing awaitDrain. + var increasedAwaitDrain = false; + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + increasedAwaitDrain = false; + var ret = dest.write(chunk); + if (false === ret && !increasedAwaitDrain) { + // If the user unpiped during `dest.write()`, it is possible + // to get stuck in a permanently paused state if that write + // also returned false. + // => Check whether `dest` is still a piping destination. + if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { + debug('false write response, pause', src._readableState.awaitDrain); + src._readableState.awaitDrain++; + increasedAwaitDrain = true; + } + src.pause(); + } + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); + } + + // Make sure our error handler is attached before userland ones. + prependListener(dest, 'error', onerror); + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function () { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) state.awaitDrain--; + if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; +} + +Readable.prototype.unpipe = function (dest) { + var state = this._readableState; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) return this; + + if (!dest) dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) dest.emit('unpipe', this); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var i = 0; i < len; i++) { + dests[i].emit('unpipe', this); + }return this; + } + + // try to find the right one. + var index = indexOf(state.pipes, dest); + if (index === -1) return this; + + state.pipes.splice(index, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) state.pipes = state.pipes[0]; + + dest.emit('unpipe', this); + + return this; +}; + +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function (ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + if (ev === 'data') { + // Start flowing on next tick if stream isn't explicitly paused + if (this._readableState.flowing !== false) this.resume(); + } else if (ev === 'readable') { + var state = this._readableState; + if (!state.endEmitted && !state.readableListening) { + state.readableListening = state.needReadable = true; + state.emittedReadable = false; + if (!state.reading) { + processNextTick(nReadingNextTick, this); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +function nReadingNextTick(self) { + debug('readable nexttick read 0'); + self.read(0); +} + +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function () { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + resume(this, state); + } + return this; +}; + +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + processNextTick(resume_, stream, state); + } +} + +function resume_(stream, state) { + if (!state.reading) { + debug('resume read 0'); + stream.read(0); + } + + state.resumeScheduled = false; + state.awaitDrain = 0; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) stream.read(0); +} + +Readable.prototype.pause = function () { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + return this; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + while (state.flowing && stream.read() !== null) {} +} + +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function (stream) { + var state = this._readableState; + var paused = false; + + var self = this; + stream.on('end', function () { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) self.push(chunk); + } + + self.push(null); + }); + + stream.on('data', function (chunk) { + debug('wrapped data'); + if (state.decoder) chunk = state.decoder.write(chunk); + + // don't skip over falsy values in objectMode + if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; + + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (this[i] === undefined && typeof stream[i] === 'function') { + this[i] = function (method) { + return function () { + return stream[method].apply(stream, arguments); + }; + }(i); + } + } + + // proxy certain important events. + for (var n = 0; n < kProxyEvents.length; n++) { + stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n])); + } + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function (n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; +}; + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function fromList(n, state) { + // nothing buffered + if (state.length === 0) return null; + + var ret; + if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { + // read it all, truncate the list + if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); + state.buffer.clear(); + } else { + // read part of list + ret = fromListPartial(n, state.buffer, state.decoder); + } + + return ret; +} + +// Extracts only enough buffered data to satisfy the amount requested. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function fromListPartial(n, list, hasStrings) { + var ret; + if (n < list.head.data.length) { + // slice is the same for buffers and strings + ret = list.head.data.slice(0, n); + list.head.data = list.head.data.slice(n); + } else if (n === list.head.data.length) { + // first chunk is a perfect match + ret = list.shift(); + } else { + // result spans more than one buffer + ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); + } + return ret; +} + +// Copies a specified amount of characters from the list of buffered data +// chunks. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function copyFromBufferString(n, list) { + var p = list.head; + var c = 1; + var ret = p.data; + n -= ret.length; + while (p = p.next) { + var str = p.data; + var nb = n > str.length ? str.length : n; + if (nb === str.length) ret += str;else ret += str.slice(0, n); + n -= nb; + if (n === 0) { + if (nb === str.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = str.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; +} + +// Copies a specified amount of bytes from the list of buffered data chunks. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function copyFromBuffer(n, list) { + var ret = bufferShim.allocUnsafe(n); + var p = list.head; + var c = 1; + p.data.copy(ret); + n -= p.data.length; + while (p = p.next) { + var buf = p.data; + var nb = n > buf.length ? buf.length : n; + buf.copy(ret, ret.length - n, 0, nb); + n -= nb; + if (n === 0) { + if (nb === buf.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = buf.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); + + if (!state.endEmitted) { + state.ended = true; + processNextTick(endReadableNT, state, stream); + } +} + +function endReadableNT(state, stream) { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } +} + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +function indexOf(xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; +} +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(11))) + +/***/ }), +/* 73 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + + + +module.exports = Transform; + +var Duplex = __webpack_require__(12); + +/*<replacement>*/ +var util = __webpack_require__(22); +util.inherits = __webpack_require__(16); +/*</replacement>*/ + +util.inherits(Transform, Duplex); + +function TransformState(stream) { + this.afterTransform = function (er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; + this.writeencoding = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (data !== null && data !== undefined) stream.push(data); + + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + +function Transform(options) { + if (!(this instanceof Transform)) return new Transform(options); + + Duplex.call(this, options); + + this._transformState = new TransformState(this); + + var stream = this; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + if (options) { + if (typeof options.transform === 'function') this._transform = options.transform; + + if (typeof options.flush === 'function') this._flush = options.flush; + } + + // When the writable side finishes, then flush out anything remaining. + this.once('prefinish', function () { + if (typeof this._flush === 'function') this._flush(function (er, data) { + done(stream, er, data); + });else done(stream); + }); +} + +Transform.prototype.push = function (chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; + +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function (chunk, encoding, cb) { + throw new Error('_transform() is not implemented'); +}; + +Transform.prototype._write = function (chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); + } +}; + +// Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. +Transform.prototype._read = function (n) { + var ts = this._transformState; + + if (ts.writechunk !== null && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } +}; + +function done(stream, er, data) { + if (er) return stream.emit('error', er); + + if (data !== null && data !== undefined) stream.push(data); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var ts = stream._transformState; + + if (ws.length) throw new Error('Calling transform done when ws.length != 0'); + + if (ts.transforming) throw new Error('Calling transform done when still transforming'); + + return stream.push(null); +} + +/***/ }), +/* 74 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(47).EventEmitter; + + +/***/ }), +/* 75 */ +/***/ (function(module, exports, __webpack_require__) { + +var apply = Function.prototype.apply; + +// DOM APIs, for completeness + +exports.setTimeout = function() { + return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout); +}; +exports.setInterval = function() { + return new Timeout(apply.call(setInterval, window, arguments), clearInterval); +}; +exports.clearTimeout = +exports.clearInterval = function(timeout) { + if (timeout) { + timeout.close(); + } +}; + +function Timeout(id, clearFn) { + this._id = id; + this._clearFn = clearFn; +} +Timeout.prototype.unref = Timeout.prototype.ref = function() {}; +Timeout.prototype.close = function() { + this._clearFn.call(window, this._id); +}; + +// Does not start the time, just sets up the members needed. +exports.enroll = function(item, msecs) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = msecs; +}; + +exports.unenroll = function(item) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = -1; +}; + +exports._unrefActive = exports.active = function(item) { + clearTimeout(item._idleTimeoutId); + + var msecs = item._idleTimeout; + if (msecs >= 0) { + item._idleTimeoutId = setTimeout(function onTimeout() { + if (item._onTimeout) + item._onTimeout(); + }, msecs); + } +}; + +// setimmediate attaches itself to the global object +__webpack_require__(148); +exports.setImmediate = setImmediate; +exports.clearImmediate = clearImmediate; + + +/***/ }), +/* 76 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = undefined; + +var _promise = __webpack_require__(88); + +var _promise2 = _interopRequireDefault(_promise); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var files = [ +// "gun_violence", +"mass_shootings_lite", "gun_violence_by_month"]; +var parse = __webpack_require__(137); + +var dataPromises = files.map(function (name) { + return fetch('./data/' + name + '.csv').then(function (rows) { + return rows.text(); + }).then(function (text) { + return new _promise2.default(function (resolve, reject) { + parse(text, {}, function (_, lines) { + return resolve(lines); + }); + }); + }).then(function (lines) { + // console.log(name, lines) + var h = lines.shift(); + return { + name: name, + h: h, + lines: lines.filter(function (s) { + return !!s; + }) + }; + }); +}); +var allPromises = _promise2.default.all(dataPromises).then(function (data) { + return data.reduce(function (a, b) { + // console.log(b) + a[b.name] = b; + return a; + }, {}); +}); +var load = function load() { + return allPromises; +}; + +exports.load = load; + +/***/ }), +/* 77 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var keys = {}; +var key_numbers = {}; +var letters = "zxcvbnmasdfghjklqwertyuiop"; +var numbers = "1234567890"; + +var callback = function callback() {}; + +letters.toUpperCase().split("").map(function (k, i) { + keys[k.charCodeAt(0)] = i; +}); + +numbers.split("").map(function (k, i) { + keys[k.charCodeAt(0)] = i + letters.length; + key_numbers[k.charCodeAt(0)] = true; +}); + +window.addEventListener("keydown", keydown, true); +function keydown(e) { + if (e.altKey || e.ctrlKey || e.metaKey) { + e.stopPropagation(); + return; + } + if (document.activeElement instanceof HTMLInputElement && e.keyCode in key_numbers) { + e.stopPropagation(); + return; + } + if (!(e.keyCode in keys)) return; + var index = keys[e.keyCode]; + if (e.shiftKey) index += letters.length; + index -= 7; + callback(index); +} + +function listen(fn) { + callback = fn; +} + +exports.default = { listen: listen }; + +/***/ }), +/* 78 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.note_values = exports.MidiWriter = undefined; + +var _slicedToArray2 = __webpack_require__(55); + +var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); + +exports.midi_init = midi_init; +exports.play_note = play_note; +exports.play_midi_note = play_midi_note; +exports.play_sequence = play_sequence; +exports.play_interval_sequence = play_interval_sequence; +exports.export_pattern_as_midi = export_pattern_as_midi; + +var _tone = __webpack_require__(24); + +var _tone2 = _interopRequireDefault(_tone); + +var _webmidi = __webpack_require__(155); + +var _webmidi2 = _interopRequireDefault(_webmidi); + +var _scales = __webpack_require__(53); + +var _scales2 = _interopRequireDefault(_scales); + +var _util = __webpack_require__(31); + +var _kalimba = __webpack_require__(52); + +var _kalimba2 = _interopRequireDefault(_kalimba); + +var _FileSaver = __webpack_require__(138); + +var _ui = __webpack_require__(54); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var midiDevice = void 0; +var sendPitchBend = false; + +var MidiWriter = exports.MidiWriter = __webpack_require__(140); + +var note_values = exports.note_values = [[8, '8 measures', 8 * 512], [4, '4 measures', 4 * 512], [2, '2 measures', 2 * 512], [1, 'whole note', 512], [1 / 2, 'half note', 256], [1 / 3, 'third note', [170, 170, 171]], [1 / 4, 'quarter note', 128], [1 / 5, 'fifth note', [51, 51, 51, 51, 52]], [1 / 6, 'sixth note', [85, 85, 86, 85, 85, 86]], [1 / 8, 'eighth note', 64], [1 / 10, 'tenth note', [25, 26, 26, 25, 26, 25, 26, 26, 25, 26]], [1 / 12, 'twelfth note', [21, 21, 22, 21, 21, 22, 21, 21, 22, 21, 21, 22]], [1 / 16, 'sixteenth note', 32], [1 / 32, 'thirtysecond note', 16]]; + +function midi_init() { + _webmidi2.default.enable(midi_ready); + function midi_ready(err) { + if (err) { + console.error('webmidi failed to initialize'); + return; + } + if (!_webmidi2.default.outputs.length) { + console.error('no MIDI output found'); + return; + } + console.log(_webmidi2.default.inputs); + console.log(_webmidi2.default.outputs); + if (_webmidi2.default.outputs.length > 1) { + var filtered = _webmidi2.default.outputs.filter(function (output) { + return output.name.match(/prodipe/i); + }); + if (filtered.length) { + // midiDevice = filtered[0] + } + } + // midiDevice = midiDevice || WebMidi.outputs[0] + // console.log(midiDevice.name) + } +} + +/* play a single note */ + +function play_note(index, duration) { + var channel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "all"; + var exporting = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + var rest = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; + var defer = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; + + // console.log(index) + var scale = _scales2.default.current(); + var freq = scale.index(index + Math.round(_ui.nx.offset.value), _ui.nx.octave.value); + var midi_note = (0, _util.ftom)(freq); + var cents = midi_note % 1; + if (cents > 0.5) { + midi_note += 1; + cents -= 1; + } + cents *= 2; + midi_note = Math.floor(midi_note); + if ((midiDevice || exporting) && midi_note > 127) return 0; + var note = _tone2.default.Frequency(Math.floor(midi_note), "midi").toNote(); + var defer_time = 30000 / _tone2.default.Transport.bpm.value * defer / 128; + console.log(defer, defer_time); + if (exporting) { + return note; + } + if (midiDevice) { + duration = duration || 60000 / _tone2.default.Transport.bpm.value; + if (!exporting) { + if (defer) { + setTimeout(function () { + play_midi_note(note, cents, channel, duration); + }, defer); + } else { + play_midi_note(note, cents, channel, duration); + } + } + } else if (defer) { + setTimeout(function () { + _kalimba2.default.play(freq); + }, defer_time); + } else { + _kalimba2.default.play(freq); + } + return note; +} + +function play_midi_note(note, cents, channel, duration) { + midiDevice.playNote(note, channel, { duration: duration }); + if (sendPitchBend) { + midiDevice.sendPitchBend(cents, channel); + } +} + +/* play the next note in sequence */ + +function play_sequence(i, bounds, diff, note_time) { + var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : "all"; + var exporting = arguments[5]; + var rows = bounds.rows, + min = bounds.min, + max = bounds.max; + + var count = rows.length * rows[0].length; + if (i >= count) i = 0; + var y = Math.floor(i / rows[0].length); + var x = i % rows[0].length; + // if (!x) console.log(y) + var n = rows[y][x]; + i += 1; + if (i >= count) i = 0; + var midi_note = play_note((0, _util.norm)(n, min, max) * _ui.nx.multiply.value, note_time, channel, exporting); + return [i, [midi_note]]; +} + +/* play the next row as an interval */ + +function play_interval_sequence(i, bounds, diff, note_time) { + var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : "all"; + var exporting = arguments[5]; + var rows = bounds.rows, + min = bounds.min, + max = bounds.max; + + var count = rows.length; + if (i >= count) i = 0; + var y = i % count; + var row = rows[y]; + if (!row) { + i = 0;return; + } + var row_min = Math.min.apply(Math, row); + // const row_max = Math.max.apply(Math, row) + var row_f0 = (0, _util.norm)(row_min, min, max); + var row_root = row_f0 * _ui.nx.multiply.value; + var notes = row.map(function (n) { + var note = row_root + (0, _util.norm)(n - row_min, diff.min, diff.max) * _ui.nx.interval.value; + play_note(note, note_time, channel, exporting); + }); + i += 1; + return [i, notes]; +} + +/* generate a 1-track midi file by calling the play function repeatedly */ + +function export_pattern_as_midi(datasetName, bounds, diff, tempo, timingIndex, play_fn) { + // const behavior = document.querySelector('#behavior').value + var rows = bounds.rows; + // let count = behavior === 'sequence' ? rows[0].length * rows.length : rows.length + + var count = rows[0].length; + var notes = void 0, + timings = void 0, + wait = void 0; + var note_time = void 0; + // let timing = note_values[timingIndex][2] + var midi_track = new MidiWriter.Track(); + midi_track.setTempo(tempo); + for (var i = 0, len = count; i < len; i++) { + // if (timing.length) { + // note_time = timing[i % timing.length] + // } else { + // note_time = timing + // } + // midi_track.addEvent(new MidiWriter.NoteEvent({ pitch: notes, duration: 't' + note_time })) + var _play_fn = play_fn(i, bounds, note_time, "all", true); + + var _play_fn2 = (0, _slicedToArray3.default)(_play_fn, 4); + + i = _play_fn2[0]; + notes = _play_fn2[1]; + timings = _play_fn2[2]; + wait = _play_fn2[3]; + console.log(i, notes, timings, wait); + for (var j = 0; j < notes.length; j++) { + midi_track.addEvent(new MidiWriter.NoteEvent({ + pitch: notes[j], + duration: 't' + timings[j], + wait: j === 0 ? wait : 0 + })); + } + } + var writer = new MidiWriter.Writer([midi_track]); + var blob = (0, _util.dataURItoBlob)(writer.dataUri()); + (0, _FileSaver.saveAs)(blob, 'Recording - ' + datasetName + '.mid'); +} + +/***/ }), +/* 79 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; + +var _from = __webpack_require__(83); + +var _from2 = _interopRequireDefault(_from); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = function (arr) { + return Array.isArray(arr) ? arr : (0, _from2.default)(arr); +}; + +/***/ }), +/* 80 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _slicedToArray2 = __webpack_require__(55); + +var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); + +var _toArray2 = __webpack_require__(79); + +var _toArray3 = _interopRequireDefault(_toArray2); + +var _tone = __webpack_require__(24); + +var _tone2 = _interopRequireDefault(_tone); + +var _nexusui = __webpack_require__(56); + +var _nexusui2 = _interopRequireDefault(_nexusui); + +var _keys = __webpack_require__(77); + +var _keys2 = _interopRequireDefault(_keys); + +var _scales = __webpack_require__(53); + +var _scales2 = _interopRequireDefault(_scales); + +var _kalimba = __webpack_require__(52); + +var _kalimba2 = _interopRequireDefault(_kalimba); + +var _midi = __webpack_require__(78); + +var _util = __webpack_require__(31); + +var _ui = __webpack_require__(54); + +var _data = __webpack_require__(76); + +var data = _interopRequireWildcard(_data); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var DEFAULT_BPM = 60; + +var recorder = null; +var recording = false; + +(0, _midi.midi_init)(); + +/* initialization */ + +var mass_fields = ["date", "timestamp", "fatalities", "injured", "total_victims", "age", "case", "weapon_type", "weapon_details"].reduce(function (a, b, i) { + a[b] = i; + return a; +}, {}); + +var i = 0, + mass_i = 0, + datasets = {}, + dataset = {}, + bounds = {}, + diff = []; +var play_fn = _midi.play_sequence; +data.load().then(function (lists) { + console.log(lists); + (0, _util.transpose)(lists.gun_violence_by_month.lines).forEach(function (row, i) { + var name = lists.gun_violence_by_month.h[i]; + if (name === 'Date') return; + console.log(name, row); + datasets[name] = { + name: name, + h: [name], + lines: [row.map(function (n) { + return parseInt(n); + })], + play_fn: _midi.play_sequence + }; + }); + datasets["Mass Shootings"] = lists.mass_shootings_lite; + datasets["Mass Shootings"].name = "Mass Shootings"; + datasets["Mass Shootings"].play_fn = play_mass_shootings; + var lines = datasets["Mass Shootings"].lines.reverse(); + + var _lines$0$mass_fields$ = lines[0][mass_fields.date].split('/'), + _lines$0$mass_fields$2 = (0, _toArray3.default)(_lines$0$mass_fields$), + min_y = _lines$0$mass_fields$2[0], + rest = _lines$0$mass_fields$2.slice(1); + + datasets["Mass Shootings"].dates = lines.map(function (row) { + var _row$mass_fields$date = row[mass_fields.date].split('/'), + _row$mass_fields$date2 = (0, _slicedToArray3.default)(_row$mass_fields$date, 3), + y = _row$mass_fields$date2[0], + m = _row$mass_fields$date2[1], + d = _row$mass_fields$date2[2]; + + return (parseInt(y) - parseInt(min_y)) * 12 + parseInt(m); + }); + datasets["Mass Shootings"].data = lines; + datasets["Mass Shootings"].lines = [lines.map(function (row) { + return row[mass_fields.total_victims]; + })]; + (0, _util.requestAudioContext)(ready); +}); + +/* play function for mass shooting data w/ custom timing */ + +var mass_rest = 0; + +// export const note_values = [ +// [8, '8 measures', 8 * 512], +// [4, '4 measures', 4 * 512], +// [2, '2 measures', 2 * 512], +// [1, 'whole note', 512], +// [1/2, 'half note', 256], +// [1/3, 'third note', [170, 170, 171]], +// [1/4, 'quarter note', 128], +// [1/5, 'fifth note', [51,51,51,51,52]], +// [1/6, 'sixth note', [85, 85, 86, 85, 85, 86]], +// [1/8, 'eighth note', 64], +// [1/10, 'tenth note', [25,26,26,25,26,25,26,26,25,26]], +// [1/12, 'twelfth note', [21,21,22, 21,21,22, 21,21,22, 21,21,22]], +// [1/16, 'sixteenth note', 32], +// [1/32, 'thirtysecond note', 16], +// ] + +function play_mass_shootings(i, bounds, diff, note_time) { + var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : "all"; + var exporting = arguments[5]; + var rows = bounds.rows, + min = bounds.min, + max = bounds.max; + + var y = 0; + var x = i % rows[0].length; + var n = rows[y][x]; + var total = dataset.dates.length; + var notes = [], + midi_notes = [], + cases = [], + timings = void 0; + console.log(i, mass_i, dataset.dates[mass_i]); + while (i >= dataset.dates[mass_i] && mass_i < total) { + notes.push(dataset.lines[0][mass_i]); + cases.push(dataset.data[mass_i][mass_fields.date] + ' ' + dataset.data[mass_i][mass_fields.case] + ", " + dataset.data[mass_i][mass_fields.fatalities] + ' dead, ' + dataset.data[mass_i][mass_fields.injured] + ' injured'); + console.log('push case', dataset.data[mass_i][mass_fields.date] + ' ' + dataset.data[mass_i][mass_fields.case]); + mass_i += 1; + } + switch (notes.length) { + default: + case 0: + mass_rest += 1; + break; + case 1: + midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 128, channel, exporting, mass_rest, 0)); + timings = [128]; + break; + case 2: + midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 64, channel, exporting, mass_rest, 0)); + midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[1], min, max) * _ui.nx.multiply.value, 64, channel, exporting, 0, 64)); + timings = [64, 64]; + break; + case 3: + midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 43, channel, exporting, mass_rest, 0)); + midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[1], min, max) * _ui.nx.multiply.value, 43, channel, exporting, 0, 43)); + midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[2], min, max) * _ui.nx.multiply.value, 42, channel, exporting, 0, 85)); + timings = [43, 43, 42]; + break; + case 4: + midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[0], min, max) * _ui.nx.multiply.value, 32, channel, exporting, mass_rest, 0)); + midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[1], min, max) * _ui.nx.multiply.value, 32, channel, exporting, 0, 32)); + midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[2], min, max) * _ui.nx.multiply.value, 32, channel, exporting, 0, 64)); + midi_notes.push((0, _midi.play_note)((0, _util.norm)(notes[3], min, max) * _ui.nx.multiply.value, 32, channel, exporting, 0, 96)); + timings = [32, 32, 32, 32]; + break; + } + if (cases.length) { + document.querySelector('#cases').innerHTML = cases.join('<br>'); + } + if (total <= mass_i) { + mass_rest = 0; + mass_i = 0; + i = 0; + } else { + i += 1; + } + _kalimba2.default.play(220, -12); + if (notes.length) { + mass_rest = 0; + return [i, midi_notes, timings, mass_rest]; + } + mass_rest += 128; + return [i, [], [], 0]; +} + +/* play next note according to sonification */ + +function play_next() { + var note_time = 120000 / _tone2.default.Transport.bpm.value * _midi.note_values[_ui.nx.timing.active][0]; + setTimeout(play_next, note_time); + + var _play_fn = play_fn(i, bounds, diff, note_time), + _play_fn2 = (0, _slicedToArray3.default)(_play_fn, 3), + new_i = _play_fn2[0], + notes = _play_fn2[1], + timings = _play_fn2[2]; + + i = new_i; + if (recording) { + var timing = _midi.note_values[_ui.nx.timing.active][2]; + if (timing.length) timing = timing[i % timing.length]; + recorder.addEvent(new _midi.MidiWriter.NoteEvent({ pitch: notes, duration: 't' + timing })); + } +} + +/* bind selects */ + +function pick_dataset(key) { + console.log('pick dataset:', key, datasets[key]); + i = 0; + mass_i = 0; + mass_rest = 0; + dataset = datasets[key]; + bounds = (0, _util.get_bounds)(dataset); + diff = (0, _util.get_diff_bounds)(bounds.rows); + play_fn = dataset.play_fn; +} + +/* build and bind the UI */ + +function ready() { + _scales2.default.build_options(document.querySelector('#scale')); + (0, _ui.build_options)(document.querySelector('#dataset'), datasets, pick_dataset); + + var dial_size = [50, 50]; + + _tone2.default.Transport.bpm.value = DEFAULT_BPM; + _ui.nx.tempo = new _nexusui2.default.Dial('#tempo', { + size: dial_size, + min: 10, + max: 300, + step: 1, + value: DEFAULT_BPM + }); + (0, _ui.update_value_on_change)(_ui.nx.tempo, '#tempo', true, function (v) { + return _tone2.default.Transport.bpm.value = v; + }); + + _ui.nx.timing = new _nexusui2.default.RadioButton('#timing', { + size: [400, 25], + numberOfButtons: _midi.note_values.length, + active: 6 + }); + (0, _ui.update_radio_value_on_change)(_ui.nx.timing, '#timing', _midi.note_values); + + _ui.nx.duration = new _nexusui2.default.Dial('#duration', { + size: dial_size, + min: 0, + max: 2, + step: 0.01, + value: 0.8 + }); + (0, _ui.update_value_on_change)(_ui.nx.duration, '#duration', false); + + _ui.nx.offset = new _nexusui2.default.Dial('#offset', { + size: dial_size, + min: -24, + max: 24, + step: 1, + value: -5 + }); + (0, _ui.update_value_on_change)(_ui.nx.offset, '#offset', true); + + _ui.nx.octave = new _nexusui2.default.Dial('#octave', { + size: dial_size, + min: -4, + max: 4, + step: 1, + value: 0 + }); + (0, _ui.update_value_on_change)(_ui.nx.octave, '#octave', true); + + _ui.nx.multiply = new _nexusui2.default.Dial('#multiply', { + size: dial_size, + min: -64, + max: 64, + step: 1, + value: 17 + }); + (0, _ui.update_value_on_change)(_ui.nx.multiply, '#multiply', true); + + _ui.nx.interval = new _nexusui2.default.Dial('#interval', { + size: dial_size, + min: -64, + max: 64, + step: 1, + value: 10 + }); + (0, _ui.update_value_on_change)(_ui.nx.interval, '#interval', true); + + var export_midi_button = document.querySelector('#export_midi'); + export_midi_button.addEventListener('click', function () { + (0, _midi.export_pattern_as_midi)(dataset.name, bounds, diff, _ui.nx.tempo.value, _ui.nx.timing.active, play_fn); + }); + + var record_midi_button = document.querySelector('#record_midi'); + record_midi_button.addEventListener('click', function () { + if (recording) { + record_midi_button.innerHTML = 'Record MIDI'; + document.body.classList.remove('recording'); + recording = false; + var writer = new _midi.MidiWriter.Writer([recorder]); + var blob = (0, _util.dataURItoBlob)(writer.dataUri()); + saveAs(blob, 'Recording - ' + dataset.name + '.mid'); + } else { + record_midi_button.innerHTML = 'Save Recording'; + document.body.classList.add('recording'); + recording = true; + recorder = new _midi.MidiWriter.Track(); + recorder.setTempo(_ui.nx.tempo.value); + } + }); + + document.querySelector('.loading').classList.remove('loading'); + + document.querySelector('#dataset').value = 'Mass Shootings'; + pick_dataset('Mass Shootings'); + + document.querySelector('#scale').value = '14'; + _scales2.default.pick(14); + + play_next(); +} + +/* keys */ + +_keys2.default.listen(function (index) { + _ui.nx.offset.value = index; + _ui.nx.offset.update(index); +}); + +/***/ }), +/* 81 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _assign = __webpack_require__(57); + +var _assign2 = _interopRequireDefault(_assign); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +module.exports = function () { + var Intonation = function Intonation(opt) { + opt = this.opt = (0, _assign2.default)({ + name: "", + root: 440, + octave: 0, + interval: 2, + tet: 0, + intervals: null + }, opt || {}); + this.generate(); + }; + Intonation.prototype.generate = function (opt) { + opt = (0, _assign2.default)(this.opt, opt || {}); + if (opt.scl) { + this.generate_scl(); + } else if (opt.tet) { + this.generate_tet(); + } else if (opt.intervals) { + this.generate_intervals(); + } + }; + Intonation.prototype.generate_intervals = function () { + var root = this.opt.root; + var interval_list = this.opt.intervals; + if (typeof interval_list == "string") { + interval_list = interval_list.split(" "); + } + this.name = this.opt.name || "interval list"; + this.intervals = interval_list; + this.interval = this.opt.interval = parseInterval.call(this, interval_list.pop()); + this.scale = interval_list.map(parseIntervalString.bind(this)).filter(function (v) { + return !!v; + }); + }; + Intonation.prototype.generate_tet = function () { + var scale = this.scale = []; + var root = this.opt.root; + var tet = this.opt.tet; + var interval = this.interval = this.opt.interval; + var ratio = Math.pow(interval, 1 / tet); + var n = root; + scale.push(n); + for (var i = 0; i < tet - 1; i++) { + n *= ratio; + scale.push(n); + } + this.name = this.opt.name || tet + "-tone equal temperament"; + this.intervals = null; + }; + Intonation.prototype.generate_scl = function () { + var root = this.opt.root; + var scl = this.parse_scl(this.opt.scl); + this.intervals = scl.notes; + this.interval = scl.notes.pop(); + this.name = this.opt.name || scl.description; + this.scale = scl.notes.map(function (v) { + return v * root; + }); + }; + Intonation.prototype.parse_scl = function (s) { + var scl = {}; + scl.comments = []; + scl.notes = []; + s.trim().split("\n").forEach(function (line) { + // Lines beginning with an exclamation mark are regarded as comments + // and are to be ignored. + if (line.indexOf("!") !== -1) { + scl.comments.push(line); + } + // The first (non comment) line contains a short description of the scale. + // If there is no description, there should be an empty line. (nb: which is falsey) + else if (!('description' in scl)) { + scl.description = line; + } + // The second line contains the number of notes. + // The first note of 1/1 or 0.0 cents is implicit and not in the files. + else if (!scl.notes.length) { + scl.notes.push(1); + } else { + // If the value contains a period, it is a cents value, otherwise a ratio. + var note = line.replace(/^[^-\.0-9]+/, "").replace(/[^-\/\.0-9]+$/, ""); + if (note.indexOf(".") !== -1) { + note = Math.pow(2, parseFloat(note) / 1200); + } else { + note = parseInterval(note); + } + if (note) { + scl.notes.push(note); + } + } + }); + return scl; + }; + Intonation.prototype.index = function (i, octave) { + octave = octave || this.opt.octave; + var f = this.scale[mod(i, this.scale.length) | 0]; + var pow = Math.floor(norm(i, 0, this.scale.length)) + octave; + f *= Math.pow(this.interval, pow); + return f; + }; + Intonation.prototype.range = function (min, max) { + var a = []; + for (var i = min; i < max; i++) { + a.push(this.index(i)); + } + return a; + }; + Intonation.prototype.set_root = function (f) { + this.opt.root = f; + this.generate(); + }; + Intonation.prototype.quantize_frequency = function (f) { + if (f == 0) return 0; + var scale_f = f; + var pow = 0; + var interval = this.interval; + var scale = this.scale; + while (scale_f < root) { + scale_f *= interval; + pow -= 1; + } + while (scale_f > root * interval) { + scale_f /= interval; + pow += 1; + } + for (var i = 0; i < scale.length; i++) { + if (scale_f > scale[i]) continue; + scale_f = scale[i]; + break; + } + scale_f *= Math.pow(2, pow); + return scale_f; + }; + Intonation.prototype.quantize_index = function (i) { + return mod(index - 1, this.scale.length) | 0; + }; + var parseInterval = Intonation.prototype.parse_interval = function (s) { + if (typeof s == "number") return s; + if (!s.indexOf("/") == -1) return parseInt(s); + var pp = s.split("/"); + var num = parseInt(pp[0]); + var den = parseInt(pp[1]); + if (isNaN(num)) return 1; + if (isNaN(den) || den == 0) return num; + if (num == den) return 1; + return num / den; + }; + var parseIntervalString = Intonation.prototype.parse_interval_string = function (s) { + if (s.indexOf("/") !== -1) return parseInterval(s) * this.opt.root; // intervals + if (s.indexOf("f") !== -1) return parseFloat(s); // pure frequencies + return parseFloat(s); + }; + function norm(n, a, b) { + return (n - a) / (b - a); + } + function mod(n, m) { + return n - m * Math.floor(n / m); + } + + return Intonation; +}(); + +/***/ }), +/* 82 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; + +var _typeof2 = __webpack_require__(91); + +var _typeof3 = _interopRequireDefault(_typeof2); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * StartAudioContext.js + * @author Yotam Mann + * @license http://opensource.org/licenses/MIT MIT License + * @copyright 2016 Yotam Mann + */ +(function (root, factory) { + if (true) { + !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), + __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? + (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + } else if ((typeof module === "undefined" ? "undefined" : (0, _typeof3.default)(module)) === 'object' && module.exports) { + module.exports = factory(); + } else { + root.StartAudioContext = factory(); + } +})(undefined, function () { + + /** + * The StartAudioContext object + */ + var StartAudioContext = { + /** + * The audio context passed in by the user + * @type {AudioContext} + */ + context: null, + /** + * The TapListeners bound to the elements + * @type {Array} + * @private + */ + _tapListeners: [], + /** + * Callbacks to invoke when the audio context is started + * @type {Array} + * @private + */ + _onStarted: [] + }; + + /** + * Set the context + * @param {AudioContext} ctx + * @returns {StartAudioContext} + */ + StartAudioContext.setContext = function (ctx) { + StartAudioContext.context = ctx; + return StartAudioContext; + }; + + /** + * Add a tap listener to the audio context + * @param {Array|Element|String|jQuery} element + * @returns {StartAudioContext} + */ + StartAudioContext.on = function (element) { + if (Array.isArray(element) || NodeList && element instanceof NodeList) { + for (var i = 0; i < element.length; i++) { + StartAudioContext.on(element[i]); + } + } else if (typeof element === "string") { + StartAudioContext.on(document.querySelectorAll(element)); + } else if (element.jquery && typeof element.toArray === "function") { + StartAudioContext.on(element.toArray()); + } else if (Element && element instanceof Element) { + //if it's an element, create a TapListener + var tap = new TapListener(element, onTap); + StartAudioContext._tapListeners.push(tap); + } + return StartAudioContext; + }; + + /** + * Bind a callback to when the audio context is started. + * @param {Function} cb + * @return {StartAudioContext} + */ + StartAudioContext.onStarted = function (cb) { + //if it's already started, invoke the callback + if (StartAudioContext.isStarted()) { + cb(); + } else { + StartAudioContext._onStarted.push(cb); + } + return StartAudioContext; + }; + + /** + * returns true if the context is started + * @return {Boolean} + */ + StartAudioContext.isStarted = function () { + return StartAudioContext.context !== null && StartAudioContext.context.state === "running"; + }; + + /** + * @class Listens for non-dragging tap ends on the given element + * @param {Element} element + * @internal + */ + var TapListener = function TapListener(element) { + + this._dragged = false; + + this._element = element; + + this._bindedMove = this._moved.bind(this); + this._bindedEnd = this._ended.bind(this); + + element.addEventListener("touchmove", this._bindedMove); + element.addEventListener("touchend", this._bindedEnd); + element.addEventListener("mouseup", this._bindedEnd); + }; + + /** + * drag move event + */ + TapListener.prototype._moved = function (e) { + this._dragged = true; + }; + + /** + * tap ended listener + */ + TapListener.prototype._ended = function (e) { + if (!this._dragged) { + onTap(); + } + this._dragged = false; + }; + + /** + * remove all the bound events + */ + TapListener.prototype.dispose = function () { + this._element.removeEventListener("touchmove", this._bindedMove); + this._element.removeEventListener("touchend", this._bindedEnd); + this._element.removeEventListener("mouseup", this._bindedEnd); + this._bindedMove = null; + this._bindedEnd = null; + this._element = null; + }; + + /** + * Invoked the first time of the elements is tapped. + * Creates a silent oscillator when a non-dragging touchend + * event has been triggered. + */ + function onTap() { + //start the audio context with a silent oscillator + if (StartAudioContext.context && !StartAudioContext.isStarted()) { + var osc = StartAudioContext.context.createOscillator(); + var silent = StartAudioContext.context.createGain(); + silent.gain.value = 0; + osc.connect(silent); + silent.connect(StartAudioContext.context.destination); + var now = StartAudioContext.context.currentTime; + osc.start(now); + osc.stop(now + 0.5); + } + + //dispose all the tap listeners + if (StartAudioContext._tapListeners) { + for (var i = 0; i < StartAudioContext._tapListeners.length; i++) { + StartAudioContext._tapListeners[i].dispose(); + } + StartAudioContext._tapListeners = null; + } + //the onstarted callbacks + if (StartAudioContext._onStarted) { + for (var j = 0; j < StartAudioContext._onStarted.length; j++) { + StartAudioContext._onStarted[j](); + } + StartAudioContext._onStarted = null; + } + } + + return StartAudioContext; +}); + +/***/ }), +/* 83 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(93), __esModule: true }; + +/***/ }), +/* 84 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(94), __esModule: true }; + +/***/ }), +/* 85 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(95), __esModule: true }; + +/***/ }), +/* 86 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(96), __esModule: true }; + +/***/ }), +/* 87 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(98), __esModule: true }; + +/***/ }), +/* 88 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(99), __esModule: true }; + +/***/ }), +/* 89 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(100), __esModule: true }; + +/***/ }), +/* 90 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(101), __esModule: true }; + +/***/ }), +/* 91 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; + +var _iterator = __webpack_require__(90); + +var _iterator2 = _interopRequireDefault(_iterator); + +var _symbol = __webpack_require__(89); + +var _symbol2 = _interopRequireDefault(_symbol); + +var _typeof = typeof _symbol2.default === "function" && typeof _iterator2.default === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof _symbol2.default === "function" && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? "symbol" : typeof obj; }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = typeof _symbol2.default === "function" && _typeof(_iterator2.default) === "symbol" ? function (obj) { + return typeof obj === "undefined" ? "undefined" : _typeof(obj); +} : function (obj) { + return obj && typeof _symbol2.default === "function" && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? "symbol" : typeof obj === "undefined" ? "undefined" : _typeof(obj); +}; + +/***/ }), +/* 92 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.byteLength = byteLength +exports.toByteArray = toByteArray +exports.fromByteArray = fromByteArray + +var lookup = [] +var revLookup = [] +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array + +var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' +for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i] + revLookup[code.charCodeAt(i)] = i +} + +revLookup['-'.charCodeAt(0)] = 62 +revLookup['_'.charCodeAt(0)] = 63 + +function placeHoldersCount (b64) { + var len = b64.length + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 +} + +function byteLength (b64) { + // base64 is 4/3 + up to two characters of the original data + return b64.length * 3 / 4 - placeHoldersCount(b64) +} + +function toByteArray (b64) { + var i, j, l, tmp, placeHolders, arr + var len = b64.length + placeHolders = placeHoldersCount(b64) + + arr = new Arr(len * 3 / 4 - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? len - 4 : len + + var L = 0 + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] + arr[L++] = (tmp >> 16) & 0xFF + arr[L++] = (tmp >> 8) & 0xFF + arr[L++] = tmp & 0xFF + } + + if (placeHolders === 2) { + tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) + arr[L++] = tmp & 0xFF + } else if (placeHolders === 1) { + tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) + arr[L++] = (tmp >> 8) & 0xFF + arr[L++] = tmp & 0xFF + } + + return arr +} + +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] +} + +function encodeChunk (uint8, start, end) { + var tmp + var output = [] + for (var i = start; i < end; i += 3) { + tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output.push(tripletToBase64(tmp)) + } + return output.join('') +} + +function fromByteArray (uint8) { + var tmp + var len = uint8.length + var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes + var output = '' + var parts = [] + var maxChunkLength = 16383 // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1] + output += lookup[tmp >> 2] + output += lookup[(tmp << 4) & 0x3F] + output += '==' + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) + output += lookup[tmp >> 10] + output += lookup[(tmp >> 4) & 0x3F] + output += lookup[(tmp << 2) & 0x3F] + output += '=' + } + + parts.push(output) + + return parts.join('') +} + + +/***/ }), +/* 93 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(21); +__webpack_require__(128); +module.exports = __webpack_require__(0).Array.from; + +/***/ }), +/* 94 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(30); +__webpack_require__(21); +module.exports = __webpack_require__(126); + +/***/ }), +/* 95 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(30); +__webpack_require__(21); +module.exports = __webpack_require__(127); + +/***/ }), +/* 96 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(130); +module.exports = __webpack_require__(0).Math.log2; + +/***/ }), +/* 97 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(131); +module.exports = __webpack_require__(0).Object.assign; + +/***/ }), +/* 98 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(132); +module.exports = __webpack_require__(0).Object.keys; + +/***/ }), +/* 99 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(70); +__webpack_require__(21); +__webpack_require__(30); +__webpack_require__(133); +module.exports = __webpack_require__(0).Promise; + +/***/ }), +/* 100 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(134); +__webpack_require__(70); +__webpack_require__(135); +__webpack_require__(136); +module.exports = __webpack_require__(0).Symbol; + +/***/ }), +/* 101 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(21); +__webpack_require__(30); +module.exports = __webpack_require__(45).f('iterator'); + +/***/ }), +/* 102 */ +/***/ (function(module, exports) { + +module.exports = function(){ /* empty */ }; + +/***/ }), +/* 103 */ +/***/ (function(module, exports) { + +module.exports = function(it, Constructor, name, forbiddenField){ + if(!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)){ + throw TypeError(name + ': incorrect invocation!'); + } return it; +}; + +/***/ }), +/* 104 */ +/***/ (function(module, exports, __webpack_require__) { + +// false -> Array#indexOf +// true -> Array#includes +var toIObject = __webpack_require__(10) + , toLength = __webpack_require__(42) + , toIndex = __webpack_require__(125); +module.exports = function(IS_INCLUDES){ + return function($this, el, fromIndex){ + var O = toIObject($this) + , length = toLength(O.length) + , index = toIndex(fromIndex, length) + , value; + // Array#includes uses SameValueZero equality algorithm + if(IS_INCLUDES && el != el)while(length > index){ + value = O[index++]; + if(value != value)return true; + // Array#toIndex ignores holes, Array#includes - not + } else for(;length > index; index++)if(IS_INCLUDES || index in O){ + if(O[index] === el)return IS_INCLUDES || index || 0; + } return !IS_INCLUDES && -1; + }; +}; + +/***/ }), +/* 105 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $defineProperty = __webpack_require__(5) + , createDesc = __webpack_require__(20); + +module.exports = function(object, index, value){ + if(index in object)$defineProperty.f(object, index, createDesc(0, value)); + else object[index] = value; +}; + +/***/ }), +/* 106 */ +/***/ (function(module, exports, __webpack_require__) { + +// all enumerable object keys, includes symbols +var getKeys = __webpack_require__(15) + , gOPS = __webpack_require__(38) + , pIE = __webpack_require__(26); +module.exports = function(it){ + var result = getKeys(it) + , getSymbols = gOPS.f; + if(getSymbols){ + var symbols = getSymbols(it) + , isEnum = pIE.f + , i = 0 + , key; + while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))result.push(key); + } return result; +}; + +/***/ }), +/* 107 */ +/***/ (function(module, exports, __webpack_require__) { + +var ctx = __webpack_require__(18) + , call = __webpack_require__(62) + , isArrayIter = __webpack_require__(61) + , anObject = __webpack_require__(4) + , toLength = __webpack_require__(42) + , getIterFn = __webpack_require__(46) + , BREAK = {} + , RETURN = {}; +var exports = module.exports = function(iterable, entries, fn, that, ITERATOR){ + var iterFn = ITERATOR ? function(){ return iterable; } : getIterFn(iterable) + , f = ctx(fn, that, entries ? 2 : 1) + , index = 0 + , length, step, iterator, result; + if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!'); + // fast case for arrays with default iterator + if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){ + result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); + if(result === BREAK || result === RETURN)return result; + } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){ + result = call(iterator, f, step.value, entries); + if(result === BREAK || result === RETURN)return result; + } +}; +exports.BREAK = BREAK; +exports.RETURN = RETURN; + +/***/ }), +/* 108 */ +/***/ (function(module, exports) { + +// fast apply, http://jsperf.lnkit.com/fast-apply/5 +module.exports = function(fn, args, that){ + var un = that === undefined; + switch(args.length){ + case 0: return un ? fn() + : fn.call(that); + case 1: return un ? fn(args[0]) + : fn.call(that, args[0]); + case 2: return un ? fn(args[0], args[1]) + : fn.call(that, args[0], args[1]); + case 3: return un ? fn(args[0], args[1], args[2]) + : fn.call(that, args[0], args[1], args[2]); + case 4: return un ? fn(args[0], args[1], args[2], args[3]) + : fn.call(that, args[0], args[1], args[2], args[3]); + } return fn.apply(that, args); +}; + +/***/ }), +/* 109 */ +/***/ (function(module, exports, __webpack_require__) { + +// 7.2.2 IsArray(argument) +var cof = __webpack_require__(17); +module.exports = Array.isArray || function isArray(arg){ + return cof(arg) == 'Array'; +}; + +/***/ }), +/* 110 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var create = __webpack_require__(65) + , descriptor = __webpack_require__(20) + , setToStringTag = __webpack_require__(27) + , IteratorPrototype = {}; + +// 25.1.2.1.1 %IteratorPrototype%[@@iterator]() +__webpack_require__(9)(IteratorPrototype, __webpack_require__(1)('iterator'), function(){ return this; }); + +module.exports = function(Constructor, NAME, next){ + Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)}); + setToStringTag(Constructor, NAME + ' Iterator'); +}; + +/***/ }), +/* 111 */ +/***/ (function(module, exports) { + +module.exports = function(done, value){ + return {value: value, done: !!done}; +}; + +/***/ }), +/* 112 */ +/***/ (function(module, exports, __webpack_require__) { + +var getKeys = __webpack_require__(15) + , toIObject = __webpack_require__(10); +module.exports = function(object, el){ + var O = toIObject(object) + , keys = getKeys(O) + , length = keys.length + , index = 0 + , key; + while(length > index)if(O[key = keys[index++]] === el)return key; +}; + +/***/ }), +/* 113 */ +/***/ (function(module, exports, __webpack_require__) { + +var META = __webpack_require__(29)('meta') + , isObject = __webpack_require__(19) + , has = __webpack_require__(8) + , setDesc = __webpack_require__(5).f + , id = 0; +var isExtensible = Object.isExtensible || function(){ + return true; +}; +var FREEZE = !__webpack_require__(13)(function(){ + return isExtensible(Object.preventExtensions({})); +}); +var setMeta = function(it){ + setDesc(it, META, {value: { + i: 'O' + ++id, // object ID + w: {} // weak collections IDs + }}); +}; +var fastKey = function(it, create){ + // return primitive with prefix + if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; + if(!has(it, META)){ + // can't set metadata to uncaught frozen object + if(!isExtensible(it))return 'F'; + // not necessary to add metadata + if(!create)return 'E'; + // add missing metadata + setMeta(it); + // return object ID + } return it[META].i; +}; +var getWeak = function(it, create){ + if(!has(it, META)){ + // can't set metadata to uncaught frozen object + if(!isExtensible(it))return true; + // not necessary to add metadata + if(!create)return false; + // add missing metadata + setMeta(it); + // return hash weak collections IDs + } return it[META].w; +}; +// add metadata on freeze-family methods calling +var onFreeze = function(it){ + if(FREEZE && meta.NEED && isExtensible(it) && !has(it, META))setMeta(it); + return it; +}; +var meta = module.exports = { + KEY: META, + NEED: false, + fastKey: fastKey, + getWeak: getWeak, + onFreeze: onFreeze +}; + +/***/ }), +/* 114 */ +/***/ (function(module, exports, __webpack_require__) { + +var global = __webpack_require__(2) + , macrotask = __webpack_require__(69).set + , Observer = global.MutationObserver || global.WebKitMutationObserver + , process = global.process + , Promise = global.Promise + , isNode = __webpack_require__(17)(process) == 'process'; + +module.exports = function(){ + var head, last, notify; + + var flush = function(){ + var parent, fn; + if(isNode && (parent = process.domain))parent.exit(); + while(head){ + fn = head.fn; + head = head.next; + try { + fn(); + } catch(e){ + if(head)notify(); + else last = undefined; + throw e; + } + } last = undefined; + if(parent)parent.enter(); + }; + + // Node.js + if(isNode){ + notify = function(){ + process.nextTick(flush); + }; + // browsers with MutationObserver + } else if(Observer){ + var toggle = true + , node = document.createTextNode(''); + new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new + notify = function(){ + node.data = toggle = !toggle; + }; + // environments with maybe non-completely correct, but existent Promise + } else if(Promise && Promise.resolve){ + var promise = Promise.resolve(); + notify = function(){ + promise.then(flush); + }; + // for other environments - macrotask based on: + // - setImmediate + // - MessageChannel + // - window.postMessag + // - onreadystatechange + // - setTimeout + } else { + notify = function(){ + // strange IE + webpack dev server bug - use .call(global) + macrotask.call(global, flush); + }; + } + + return function(fn){ + var task = {fn: fn, next: undefined}; + if(last)last.next = task; + if(!head){ + head = task; + notify(); + } last = task; + }; +}; + +/***/ }), +/* 115 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// 19.1.2.1 Object.assign(target, source, ...) +var getKeys = __webpack_require__(15) + , gOPS = __webpack_require__(38) + , pIE = __webpack_require__(26) + , toObject = __webpack_require__(28) + , IObject = __webpack_require__(60) + , $assign = Object.assign; + +// should work with symbols and should have deterministic property order (V8 bug) +module.exports = !$assign || __webpack_require__(13)(function(){ + var A = {} + , B = {} + , S = Symbol() + , K = 'abcdefghijklmnopqrst'; + A[S] = 7; + K.split('').forEach(function(k){ B[k] = k; }); + return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K; +}) ? function assign(target, source){ // eslint-disable-line no-unused-vars + var T = toObject(target) + , aLen = arguments.length + , index = 1 + , getSymbols = gOPS.f + , isEnum = pIE.f; + while(aLen > index){ + var S = IObject(arguments[index++]) + , keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S) + , length = keys.length + , j = 0 + , key; + while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key]; + } return T; +} : $assign; + +/***/ }), +/* 116 */ +/***/ (function(module, exports, __webpack_require__) { + +var dP = __webpack_require__(5) + , anObject = __webpack_require__(4) + , getKeys = __webpack_require__(15); + +module.exports = __webpack_require__(6) ? Object.defineProperties : function defineProperties(O, Properties){ + anObject(O); + var keys = getKeys(Properties) + , length = keys.length + , i = 0 + , P; + while(length > i)dP.f(O, P = keys[i++], Properties[P]); + return O; +}; + +/***/ }), +/* 117 */ +/***/ (function(module, exports, __webpack_require__) { + +var pIE = __webpack_require__(26) + , createDesc = __webpack_require__(20) + , toIObject = __webpack_require__(10) + , toPrimitive = __webpack_require__(43) + , has = __webpack_require__(8) + , IE8_DOM_DEFINE = __webpack_require__(59) + , gOPD = Object.getOwnPropertyDescriptor; + +exports.f = __webpack_require__(6) ? gOPD : function getOwnPropertyDescriptor(O, P){ + O = toIObject(O); + P = toPrimitive(P, true); + if(IE8_DOM_DEFINE)try { + return gOPD(O, P); + } catch(e){ /* empty */ } + if(has(O, P))return createDesc(!pIE.f.call(O, P), O[P]); +}; + +/***/ }), +/* 118 */ +/***/ (function(module, exports, __webpack_require__) { + +// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window +var toIObject = __webpack_require__(10) + , gOPN = __webpack_require__(66).f + , toString = {}.toString; + +var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames + ? Object.getOwnPropertyNames(window) : []; + +var getWindowNames = function(it){ + try { + return gOPN(it); + } catch(e){ + return windowNames.slice(); + } +}; + +module.exports.f = function getOwnPropertyNames(it){ + return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it)); +}; + + +/***/ }), +/* 119 */ +/***/ (function(module, exports, __webpack_require__) { + +// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) +var has = __webpack_require__(8) + , toObject = __webpack_require__(28) + , IE_PROTO = __webpack_require__(39)('IE_PROTO') + , ObjectProto = Object.prototype; + +module.exports = Object.getPrototypeOf || function(O){ + O = toObject(O); + if(has(O, IE_PROTO))return O[IE_PROTO]; + if(typeof O.constructor == 'function' && O instanceof O.constructor){ + return O.constructor.prototype; + } return O instanceof Object ? ObjectProto : null; +}; + +/***/ }), +/* 120 */ +/***/ (function(module, exports, __webpack_require__) { + +// most Object methods by ES6 should accept primitives +var $export = __webpack_require__(7) + , core = __webpack_require__(0) + , fails = __webpack_require__(13); +module.exports = function(KEY, exec){ + var fn = (core.Object || {})[KEY] || Object[KEY] + , exp = {}; + exp[KEY] = exec(fn); + $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp); +}; + +/***/ }), +/* 121 */ +/***/ (function(module, exports, __webpack_require__) { + +var hide = __webpack_require__(9); +module.exports = function(target, src, safe){ + for(var key in src){ + if(safe && target[key])target[key] = src[key]; + else hide(target, key, src[key]); + } return target; +}; + +/***/ }), +/* 122 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var global = __webpack_require__(2) + , core = __webpack_require__(0) + , dP = __webpack_require__(5) + , DESCRIPTORS = __webpack_require__(6) + , SPECIES = __webpack_require__(1)('species'); + +module.exports = function(KEY){ + var C = typeof core[KEY] == 'function' ? core[KEY] : global[KEY]; + if(DESCRIPTORS && C && !C[SPECIES])dP.f(C, SPECIES, { + configurable: true, + get: function(){ return this; } + }); +}; + +/***/ }), +/* 123 */ +/***/ (function(module, exports, __webpack_require__) { + +// 7.3.20 SpeciesConstructor(O, defaultConstructor) +var anObject = __webpack_require__(4) + , aFunction = __webpack_require__(33) + , SPECIES = __webpack_require__(1)('species'); +module.exports = function(O, D){ + var C = anObject(O).constructor, S; + return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); +}; + +/***/ }), +/* 124 */ +/***/ (function(module, exports, __webpack_require__) { + +var toInteger = __webpack_require__(41) + , defined = __webpack_require__(35); +// true -> String#at +// false -> String#codePointAt +module.exports = function(TO_STRING){ + return function(that, pos){ + var s = String(defined(that)) + , i = toInteger(pos) + , l = s.length + , a, b; + if(i < 0 || i >= l)return TO_STRING ? '' : undefined; + a = s.charCodeAt(i); + return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff + ? TO_STRING ? s.charAt(i) : a + : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; + }; +}; + +/***/ }), +/* 125 */ +/***/ (function(module, exports, __webpack_require__) { + +var toInteger = __webpack_require__(41) + , max = Math.max + , min = Math.min; +module.exports = function(index, length){ + index = toInteger(index); + return index < 0 ? max(index + length, 0) : min(index, length); +}; + +/***/ }), +/* 126 */ +/***/ (function(module, exports, __webpack_require__) { + +var anObject = __webpack_require__(4) + , get = __webpack_require__(46); +module.exports = __webpack_require__(0).getIterator = function(it){ + var iterFn = get(it); + if(typeof iterFn != 'function')throw TypeError(it + ' is not iterable!'); + return anObject(iterFn.call(it)); +}; + +/***/ }), +/* 127 */ +/***/ (function(module, exports, __webpack_require__) { + +var classof = __webpack_require__(34) + , ITERATOR = __webpack_require__(1)('iterator') + , Iterators = __webpack_require__(14); +module.exports = __webpack_require__(0).isIterable = function(it){ + var O = Object(it); + return O[ITERATOR] !== undefined + || '@@iterator' in O + || Iterators.hasOwnProperty(classof(O)); +}; + +/***/ }), +/* 128 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var ctx = __webpack_require__(18) + , $export = __webpack_require__(7) + , toObject = __webpack_require__(28) + , call = __webpack_require__(62) + , isArrayIter = __webpack_require__(61) + , toLength = __webpack_require__(42) + , createProperty = __webpack_require__(105) + , getIterFn = __webpack_require__(46); + +$export($export.S + $export.F * !__webpack_require__(64)(function(iter){ Array.from(iter); }), 'Array', { + // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined) + from: function from(arrayLike/*, mapfn = undefined, thisArg = undefined*/){ + var O = toObject(arrayLike) + , C = typeof this == 'function' ? this : Array + , aLen = arguments.length + , mapfn = aLen > 1 ? arguments[1] : undefined + , mapping = mapfn !== undefined + , index = 0 + , iterFn = getIterFn(O) + , length, result, step, iterator; + if(mapping)mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2); + // if object isn't iterable or it's array with default iterator - use simple case + if(iterFn != undefined && !(C == Array && isArrayIter(iterFn))){ + for(iterator = iterFn.call(O), result = new C; !(step = iterator.next()).done; index++){ + createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value); + } + } else { + length = toLength(O.length); + for(result = new C(length); length > index; index++){ + createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]); + } + } + result.length = index; + return result; + } +}); + + +/***/ }), +/* 129 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var addToUnscopables = __webpack_require__(102) + , step = __webpack_require__(111) + , Iterators = __webpack_require__(14) + , toIObject = __webpack_require__(10); + +// 22.1.3.4 Array.prototype.entries() +// 22.1.3.13 Array.prototype.keys() +// 22.1.3.29 Array.prototype.values() +// 22.1.3.30 Array.prototype[@@iterator]() +module.exports = __webpack_require__(63)(Array, 'Array', function(iterated, kind){ + this._t = toIObject(iterated); // target + this._i = 0; // next index + this._k = kind; // kind +// 22.1.5.2.1 %ArrayIteratorPrototype%.next() +}, function(){ + var O = this._t + , kind = this._k + , index = this._i++; + if(!O || index >= O.length){ + this._t = undefined; + return step(1); + } + if(kind == 'keys' )return step(0, index); + if(kind == 'values')return step(0, O[index]); + return step(0, [index, O[index]]); +}, 'values'); + +// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) +Iterators.Arguments = Iterators.Array; + +addToUnscopables('keys'); +addToUnscopables('values'); +addToUnscopables('entries'); + +/***/ }), +/* 130 */ +/***/ (function(module, exports, __webpack_require__) { + +// 20.2.2.22 Math.log2(x) +var $export = __webpack_require__(7); + +$export($export.S, 'Math', { + log2: function log2(x){ + return Math.log(x) / Math.LN2; + } +}); + +/***/ }), +/* 131 */ +/***/ (function(module, exports, __webpack_require__) { + +// 19.1.3.1 Object.assign(target, source) +var $export = __webpack_require__(7); + +$export($export.S + $export.F, 'Object', {assign: __webpack_require__(115)}); + +/***/ }), +/* 132 */ +/***/ (function(module, exports, __webpack_require__) { + +// 19.1.2.14 Object.keys(O) +var toObject = __webpack_require__(28) + , $keys = __webpack_require__(15); + +__webpack_require__(120)('keys', function(){ + return function keys(it){ + return $keys(toObject(it)); + }; +}); + +/***/ }), +/* 133 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var LIBRARY = __webpack_require__(25) + , global = __webpack_require__(2) + , ctx = __webpack_require__(18) + , classof = __webpack_require__(34) + , $export = __webpack_require__(7) + , isObject = __webpack_require__(19) + , aFunction = __webpack_require__(33) + , anInstance = __webpack_require__(103) + , forOf = __webpack_require__(107) + , speciesConstructor = __webpack_require__(123) + , task = __webpack_require__(69).set + , microtask = __webpack_require__(114)() + , PROMISE = 'Promise' + , TypeError = global.TypeError + , process = global.process + , $Promise = global[PROMISE] + , process = global.process + , isNode = classof(process) == 'process' + , empty = function(){ /* empty */ } + , Internal, GenericPromiseCapability, Wrapper; + +var USE_NATIVE = !!function(){ + try { + // correct subclassing with @@species support + var promise = $Promise.resolve(1) + , FakePromise = (promise.constructor = {})[__webpack_require__(1)('species')] = function(exec){ exec(empty, empty); }; + // unhandled rejections tracking support, NodeJS Promise without it fails @@species test + return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise; + } catch(e){ /* empty */ } +}(); + +// helpers +var sameConstructor = function(a, b){ + // with library wrapper special case + return a === b || a === $Promise && b === Wrapper; +}; +var isThenable = function(it){ + var then; + return isObject(it) && typeof (then = it.then) == 'function' ? then : false; +}; +var newPromiseCapability = function(C){ + return sameConstructor($Promise, C) + ? new PromiseCapability(C) + : new GenericPromiseCapability(C); +}; +var PromiseCapability = GenericPromiseCapability = function(C){ + var resolve, reject; + this.promise = new C(function($$resolve, $$reject){ + if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor'); + resolve = $$resolve; + reject = $$reject; + }); + this.resolve = aFunction(resolve); + this.reject = aFunction(reject); +}; +var perform = function(exec){ + try { + exec(); + } catch(e){ + return {error: e}; + } +}; +var notify = function(promise, isReject){ + if(promise._n)return; + promise._n = true; + var chain = promise._c; + microtask(function(){ + var value = promise._v + , ok = promise._s == 1 + , i = 0; + var run = function(reaction){ + var handler = ok ? reaction.ok : reaction.fail + , resolve = reaction.resolve + , reject = reaction.reject + , domain = reaction.domain + , result, then; + try { + if(handler){ + if(!ok){ + if(promise._h == 2)onHandleUnhandled(promise); + promise._h = 1; + } + if(handler === true)result = value; + else { + if(domain)domain.enter(); + result = handler(value); + if(domain)domain.exit(); + } + if(result === reaction.promise){ + reject(TypeError('Promise-chain cycle')); + } else if(then = isThenable(result)){ + then.call(result, resolve, reject); + } else resolve(result); + } else reject(value); + } catch(e){ + reject(e); + } + }; + while(chain.length > i)run(chain[i++]); // variable length - can't use forEach + promise._c = []; + promise._n = false; + if(isReject && !promise._h)onUnhandled(promise); + }); +}; +var onUnhandled = function(promise){ + task.call(global, function(){ + var value = promise._v + , abrupt, handler, console; + if(isUnhandled(promise)){ + abrupt = perform(function(){ + if(isNode){ + process.emit('unhandledRejection', value, promise); + } else if(handler = global.onunhandledrejection){ + handler({promise: promise, reason: value}); + } else if((console = global.console) && console.error){ + console.error('Unhandled promise rejection', value); + } + }); + // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should + promise._h = isNode || isUnhandled(promise) ? 2 : 1; + } promise._a = undefined; + if(abrupt)throw abrupt.error; + }); +}; +var isUnhandled = function(promise){ + if(promise._h == 1)return false; + var chain = promise._a || promise._c + , i = 0 + , reaction; + while(chain.length > i){ + reaction = chain[i++]; + if(reaction.fail || !isUnhandled(reaction.promise))return false; + } return true; +}; +var onHandleUnhandled = function(promise){ + task.call(global, function(){ + var handler; + if(isNode){ + process.emit('rejectionHandled', promise); + } else if(handler = global.onrejectionhandled){ + handler({promise: promise, reason: promise._v}); + } + }); +}; +var $reject = function(value){ + var promise = this; + if(promise._d)return; + promise._d = true; + promise = promise._w || promise; // unwrap + promise._v = value; + promise._s = 2; + if(!promise._a)promise._a = promise._c.slice(); + notify(promise, true); +}; +var $resolve = function(value){ + var promise = this + , then; + if(promise._d)return; + promise._d = true; + promise = promise._w || promise; // unwrap + try { + if(promise === value)throw TypeError("Promise can't be resolved itself"); + if(then = isThenable(value)){ + microtask(function(){ + var wrapper = {_w: promise, _d: false}; // wrap + try { + then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); + } catch(e){ + $reject.call(wrapper, e); + } + }); + } else { + promise._v = value; + promise._s = 1; + notify(promise, false); + } + } catch(e){ + $reject.call({_w: promise, _d: false}, e); // wrap + } +}; + +// constructor polyfill +if(!USE_NATIVE){ + // 25.4.3.1 Promise(executor) + $Promise = function Promise(executor){ + anInstance(this, $Promise, PROMISE, '_h'); + aFunction(executor); + Internal.call(this); + try { + executor(ctx($resolve, this, 1), ctx($reject, this, 1)); + } catch(err){ + $reject.call(this, err); + } + }; + Internal = function Promise(executor){ + this._c = []; // <- awaiting reactions + this._a = undefined; // <- checked in isUnhandled reactions + this._s = 0; // <- state + this._d = false; // <- done + this._v = undefined; // <- value + this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled + this._n = false; // <- notify + }; + Internal.prototype = __webpack_require__(121)($Promise.prototype, { + // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) + then: function then(onFulfilled, onRejected){ + var reaction = newPromiseCapability(speciesConstructor(this, $Promise)); + reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; + reaction.fail = typeof onRejected == 'function' && onRejected; + reaction.domain = isNode ? process.domain : undefined; + this._c.push(reaction); + if(this._a)this._a.push(reaction); + if(this._s)notify(this, false); + return reaction.promise; + }, + // 25.4.5.1 Promise.prototype.catch(onRejected) + 'catch': function(onRejected){ + return this.then(undefined, onRejected); + } + }); + PromiseCapability = function(){ + var promise = new Internal; + this.promise = promise; + this.resolve = ctx($resolve, promise, 1); + this.reject = ctx($reject, promise, 1); + }; +} + +$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: $Promise}); +__webpack_require__(27)($Promise, PROMISE); +__webpack_require__(122)(PROMISE); +Wrapper = __webpack_require__(0)[PROMISE]; + +// statics +$export($export.S + $export.F * !USE_NATIVE, PROMISE, { + // 25.4.4.5 Promise.reject(r) + reject: function reject(r){ + var capability = newPromiseCapability(this) + , $$reject = capability.reject; + $$reject(r); + return capability.promise; + } +}); +$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, { + // 25.4.4.6 Promise.resolve(x) + resolve: function resolve(x){ + // instanceof instead of internal slot check because we should fix it without replacement native Promise core + if(x instanceof $Promise && sameConstructor(x.constructor, this))return x; + var capability = newPromiseCapability(this) + , $$resolve = capability.resolve; + $$resolve(x); + return capability.promise; + } +}); +$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(64)(function(iter){ + $Promise.all(iter)['catch'](empty); +})), PROMISE, { + // 25.4.4.1 Promise.all(iterable) + all: function all(iterable){ + var C = this + , capability = newPromiseCapability(C) + , resolve = capability.resolve + , reject = capability.reject; + var abrupt = perform(function(){ + var values = [] + , index = 0 + , remaining = 1; + forOf(iterable, false, function(promise){ + var $index = index++ + , alreadyCalled = false; + values.push(undefined); + remaining++; + C.resolve(promise).then(function(value){ + if(alreadyCalled)return; + alreadyCalled = true; + values[$index] = value; + --remaining || resolve(values); + }, reject); + }); + --remaining || resolve(values); + }); + if(abrupt)reject(abrupt.error); + return capability.promise; + }, + // 25.4.4.4 Promise.race(iterable) + race: function race(iterable){ + var C = this + , capability = newPromiseCapability(C) + , reject = capability.reject; + var abrupt = perform(function(){ + forOf(iterable, false, function(promise){ + C.resolve(promise).then(capability.resolve, reject); + }); + }); + if(abrupt)reject(abrupt.error); + return capability.promise; + } +}); + +/***/ }), +/* 134 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// ECMAScript 6 symbols shim +var global = __webpack_require__(2) + , has = __webpack_require__(8) + , DESCRIPTORS = __webpack_require__(6) + , $export = __webpack_require__(7) + , redefine = __webpack_require__(68) + , META = __webpack_require__(113).KEY + , $fails = __webpack_require__(13) + , shared = __webpack_require__(40) + , setToStringTag = __webpack_require__(27) + , uid = __webpack_require__(29) + , wks = __webpack_require__(1) + , wksExt = __webpack_require__(45) + , wksDefine = __webpack_require__(44) + , keyOf = __webpack_require__(112) + , enumKeys = __webpack_require__(106) + , isArray = __webpack_require__(109) + , anObject = __webpack_require__(4) + , toIObject = __webpack_require__(10) + , toPrimitive = __webpack_require__(43) + , createDesc = __webpack_require__(20) + , _create = __webpack_require__(65) + , gOPNExt = __webpack_require__(118) + , $GOPD = __webpack_require__(117) + , $DP = __webpack_require__(5) + , $keys = __webpack_require__(15) + , gOPD = $GOPD.f + , dP = $DP.f + , gOPN = gOPNExt.f + , $Symbol = global.Symbol + , $JSON = global.JSON + , _stringify = $JSON && $JSON.stringify + , PROTOTYPE = 'prototype' + , HIDDEN = wks('_hidden') + , TO_PRIMITIVE = wks('toPrimitive') + , isEnum = {}.propertyIsEnumerable + , SymbolRegistry = shared('symbol-registry') + , AllSymbols = shared('symbols') + , OPSymbols = shared('op-symbols') + , ObjectProto = Object[PROTOTYPE] + , USE_NATIVE = typeof $Symbol == 'function' + , QObject = global.QObject; +// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173 +var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild; + +// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 +var setSymbolDesc = DESCRIPTORS && $fails(function(){ + return _create(dP({}, 'a', { + get: function(){ return dP(this, 'a', {value: 7}).a; } + })).a != 7; +}) ? function(it, key, D){ + var protoDesc = gOPD(ObjectProto, key); + if(protoDesc)delete ObjectProto[key]; + dP(it, key, D); + if(protoDesc && it !== ObjectProto)dP(ObjectProto, key, protoDesc); +} : dP; + +var wrap = function(tag){ + var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]); + sym._k = tag; + return sym; +}; + +var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function(it){ + return typeof it == 'symbol'; +} : function(it){ + return it instanceof $Symbol; +}; + +var $defineProperty = function defineProperty(it, key, D){ + if(it === ObjectProto)$defineProperty(OPSymbols, key, D); + anObject(it); + key = toPrimitive(key, true); + anObject(D); + if(has(AllSymbols, key)){ + if(!D.enumerable){ + if(!has(it, HIDDEN))dP(it, HIDDEN, createDesc(1, {})); + it[HIDDEN][key] = true; + } else { + if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false; + D = _create(D, {enumerable: createDesc(0, false)}); + } return setSymbolDesc(it, key, D); + } return dP(it, key, D); +}; +var $defineProperties = function defineProperties(it, P){ + anObject(it); + var keys = enumKeys(P = toIObject(P)) + , i = 0 + , l = keys.length + , key; + while(l > i)$defineProperty(it, key = keys[i++], P[key]); + return it; +}; +var $create = function create(it, P){ + return P === undefined ? _create(it) : $defineProperties(_create(it), P); +}; +var $propertyIsEnumerable = function propertyIsEnumerable(key){ + var E = isEnum.call(this, key = toPrimitive(key, true)); + if(this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return false; + return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true; +}; +var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){ + it = toIObject(it); + key = toPrimitive(key, true); + if(it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return; + var D = gOPD(it, key); + if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true; + return D; +}; +var $getOwnPropertyNames = function getOwnPropertyNames(it){ + var names = gOPN(toIObject(it)) + , result = [] + , i = 0 + , key; + while(names.length > i){ + if(!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META)result.push(key); + } return result; +}; +var $getOwnPropertySymbols = function getOwnPropertySymbols(it){ + var IS_OP = it === ObjectProto + , names = gOPN(IS_OP ? OPSymbols : toIObject(it)) + , result = [] + , i = 0 + , key; + while(names.length > i){ + if(has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true))result.push(AllSymbols[key]); + } return result; +}; + +// 19.4.1.1 Symbol([description]) +if(!USE_NATIVE){ + $Symbol = function Symbol(){ + if(this instanceof $Symbol)throw TypeError('Symbol is not a constructor!'); + var tag = uid(arguments.length > 0 ? arguments[0] : undefined); + var $set = function(value){ + if(this === ObjectProto)$set.call(OPSymbols, value); + if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false; + setSymbolDesc(this, tag, createDesc(1, value)); + }; + if(DESCRIPTORS && setter)setSymbolDesc(ObjectProto, tag, {configurable: true, set: $set}); + return wrap(tag); + }; + redefine($Symbol[PROTOTYPE], 'toString', function toString(){ + return this._k; + }); + + $GOPD.f = $getOwnPropertyDescriptor; + $DP.f = $defineProperty; + __webpack_require__(66).f = gOPNExt.f = $getOwnPropertyNames; + __webpack_require__(26).f = $propertyIsEnumerable; + __webpack_require__(38).f = $getOwnPropertySymbols; + + if(DESCRIPTORS && !__webpack_require__(25)){ + redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true); + } + + wksExt.f = function(name){ + return wrap(wks(name)); + } +} + +$export($export.G + $export.W + $export.F * !USE_NATIVE, {Symbol: $Symbol}); + +for(var symbols = ( + // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14 + 'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables' +).split(','), i = 0; symbols.length > i; )wks(symbols[i++]); + +for(var symbols = $keys(wks.store), i = 0; symbols.length > i; )wksDefine(symbols[i++]); + +$export($export.S + $export.F * !USE_NATIVE, 'Symbol', { + // 19.4.2.1 Symbol.for(key) + 'for': function(key){ + return has(SymbolRegistry, key += '') + ? SymbolRegistry[key] + : SymbolRegistry[key] = $Symbol(key); + }, + // 19.4.2.5 Symbol.keyFor(sym) + keyFor: function keyFor(key){ + if(isSymbol(key))return keyOf(SymbolRegistry, key); + throw TypeError(key + ' is not a symbol!'); + }, + useSetter: function(){ setter = true; }, + useSimple: function(){ setter = false; } +}); + +$export($export.S + $export.F * !USE_NATIVE, 'Object', { + // 19.1.2.2 Object.create(O [, Properties]) + create: $create, + // 19.1.2.4 Object.defineProperty(O, P, Attributes) + defineProperty: $defineProperty, + // 19.1.2.3 Object.defineProperties(O, Properties) + defineProperties: $defineProperties, + // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P) + getOwnPropertyDescriptor: $getOwnPropertyDescriptor, + // 19.1.2.7 Object.getOwnPropertyNames(O) + getOwnPropertyNames: $getOwnPropertyNames, + // 19.1.2.8 Object.getOwnPropertySymbols(O) + getOwnPropertySymbols: $getOwnPropertySymbols +}); + +// 24.3.2 JSON.stringify(value [, replacer [, space]]) +$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function(){ + var S = $Symbol(); + // MS Edge converts symbol values to JSON as {} + // WebKit converts symbol values to JSON as null + // V8 throws on boxed symbols + return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}'; +})), 'JSON', { + stringify: function stringify(it){ + if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined + var args = [it] + , i = 1 + , replacer, $replacer; + while(arguments.length > i)args.push(arguments[i++]); + replacer = args[1]; + if(typeof replacer == 'function')$replacer = replacer; + if($replacer || !isArray(replacer))replacer = function(key, value){ + if($replacer)value = $replacer.call(this, key, value); + if(!isSymbol(value))return value; + }; + args[1] = replacer; + return _stringify.apply($JSON, args); + } +}); + +// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint) +$Symbol[PROTOTYPE][TO_PRIMITIVE] || __webpack_require__(9)($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf); +// 19.4.3.5 Symbol.prototype[@@toStringTag] +setToStringTag($Symbol, 'Symbol'); +// 20.2.1.9 Math[@@toStringTag] +setToStringTag(Math, 'Math', true); +// 24.3.3 JSON[@@toStringTag] +setToStringTag(global.JSON, 'JSON', true); + +/***/ }), +/* 135 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(44)('asyncIterator'); + +/***/ }), +/* 136 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(44)('observable'); + +/***/ }), +/* 137 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(Buffer, process, setImmediate) {// Generated by CoffeeScript 2.3.1 +// # CSV Parser + +// This module provides a CSV parser tested and used against large datasets. Over +// the year, it has been enhance and is now full of useful options. + +// Please look at the [README], the [project website][site] the [samples] and the +// [tests] for additional information. +var Parser, StringDecoder, isObjLiteral, stream, util; + +stream = __webpack_require__(149); + +util = __webpack_require__(154); + +StringDecoder = __webpack_require__(48).StringDecoder; + +// ## Usage + +// Callback approach, for ease of use: + +// `parse(data, [options], callback)` + +// [Node.js Stream API][stream], for maximum of power: + +// `parse([options], [callback])` +module.exports = function() { + var callback, called, chunks, data, err, options, parser; + if (arguments.length === 3) { + data = arguments[0]; + options = arguments[1]; + callback = arguments[2]; + if (typeof callback !== 'function') { + throw Error(`Invalid callback argument: ${JSON.stringify(callback)}`); + } + if (!(typeof data === 'string' || Buffer.isBuffer(arguments[0]))) { + return callback(Error(`Invalid data argument: ${JSON.stringify(data)}`)); + } + } else if (arguments.length === 2) { + // 1st arg is data:string or options:object + if (typeof arguments[0] === 'string' || Buffer.isBuffer(arguments[0])) { + data = arguments[0]; + } else if (isObjLiteral(arguments[0])) { + options = arguments[0]; + } else { + err = `Invalid first argument: ${JSON.stringify(arguments[0])}`; + } + // 2nd arg is options:object or callback:function + if (typeof arguments[1] === 'function') { + callback = arguments[1]; + } else if (isObjLiteral(arguments[1])) { + if (options) { + err = 'Invalid arguments: got options twice as first and second arguments'; + } else { + options = arguments[1]; + } + } else { + err = `Invalid first argument: ${JSON.stringify(arguments[1])}`; + } + if (err) { + if (!callback) { + throw Error(err); + } else { + return callback(Error(err)); + } + } + } else if (arguments.length === 1) { + if (typeof arguments[0] === 'function') { + callback = arguments[0]; + } else { + options = arguments[0]; + } + } + if (options == null) { + options = {}; + } + parser = new Parser(options); + if (data != null) { + process.nextTick(function() { + parser.write(data); + return parser.end(); + }); + } + if (callback) { + called = false; + chunks = options.objname ? {} : []; + parser.on('readable', function() { + var chunk, results; + results = []; + while (chunk = parser.read()) { + if (options.objname) { + results.push(chunks[chunk[0]] = chunk[1]); + } else { + results.push(chunks.push(chunk)); + } + } + return results; + }); + parser.on('error', function(err) { + called = true; + return callback(err); + }); + parser.on('end', function() { + if (!called) { + return callback(null, chunks); + } + }); + } + return parser; +}; + +// ## `Parser([options])` + +// Options are documented [here](http://csv.adaltas.com/parse/). +Parser = function(options = {}) { + var base, base1, base10, base11, base12, base13, base14, base15, base16, base17, base2, base3, base4, base5, base6, base7, base8, base9, k, v; + // @options = options + this.options = {}; + for (k in options) { + v = options[k]; + this.options[k] = v; + } + this.options.objectMode = true; + stream.Transform.call(this, this.options); + if ((base = this.options).rowDelimiter == null) { + base.rowDelimiter = null; + } + if (typeof this.options.rowDelimiter === 'string') { + this.options.rowDelimiter = [this.options.rowDelimiter]; + } + if ((base1 = this.options).delimiter == null) { + base1.delimiter = ','; + } + if (this.options.quote !== void 0 && !this.options.quote) { + this.options.quote = ''; + } + if ((base2 = this.options).quote == null) { + base2.quote = '"'; + } + if ((base3 = this.options).escape == null) { + base3.escape = '"'; + } + if ((base4 = this.options).columns == null) { + base4.columns = null; + } + if ((base5 = this.options).comment == null) { + base5.comment = ''; + } + if ((base6 = this.options).objname == null) { + base6.objname = false; + } + if ((base7 = this.options).trim == null) { + base7.trim = false; + } + if ((base8 = this.options).ltrim == null) { + base8.ltrim = false; + } + if ((base9 = this.options).rtrim == null) { + base9.rtrim = false; + } + if (this.options.auto_parse != null) { + this.options.cast = this.options.auto_parse; + } + if ((base10 = this.options).cast == null) { + base10.cast = false; + } + if (this.options.auto_parse_date != null) { + this.options.cast_date = this.options.auto_parse_date; + } + if ((base11 = this.options).cast_date == null) { + base11.cast_date = false; + } + if (this.options.cast_date === true) { + this.options.cast_date = function(value) { + var m; + m = Date.parse(value); + if (!isNaN(m)) { + value = new Date(m); + } + return value; + }; + } + if ((base12 = this.options).relax == null) { + base12.relax = false; + } + if ((base13 = this.options).relax_column_count == null) { + base13.relax_column_count = false; + } + if ((base14 = this.options).skip_empty_lines == null) { + base14.skip_empty_lines = false; + } + if ((base15 = this.options).max_limit_on_data_read == null) { + base15.max_limit_on_data_read = 128000; + } + if ((base16 = this.options).skip_lines_with_empty_values == null) { + base16.skip_lines_with_empty_values = false; + } + if ((base17 = this.options).skip_lines_with_error == null) { + base17.skip_lines_with_error = false; + } + // Counters + // lines = count + skipped_line_count + empty_line_count + this.lines = 0; // Number of lines encountered in the source dataset + this.count = 0; // Number of records being processed + this.skipped_line_count = 0; // Number of records skipped due to errors + this.empty_line_count = 0; // Number of empty lines + // Constants + this.is_int = /^(\-|\+)?([1-9]+[0-9]*)$/; + // @is_float = /^(\-|\+)?([0-9]+(\.[0-9]+)([eE][0-9]+)?|Infinity)$/ + // @is_float = /^(\-|\+)?((([0-9])|([1-9]+[0-9]*))(\.[0-9]+)([eE][0-9]+)?|Infinity)$/ + this.is_float = function(value) { + return (value - parseFloat(value) + 1) >= 0; // Borrowed from jquery + }; + // Internal state + this._ = { + decoder: new StringDecoder(), + quoting: false, + commenting: false, + field: null, + nextChar: null, + closingQuote: 0, + line: [], + chunks: [], + rawBuf: '', + buf: '', + rowDelimiterLength: this.options.rowDelimiter ? Math.max(...this.options.rowDelimiter.map(function(v) { + return v.length; + })) : void 0, + lineHasError: false, + isEnded: false + }; + return this; +}; + +// ## Internal API + +// The Parser implement a [`stream.Transform` class][transform]. + +// ### Events + +// The library extends Node [EventEmitter][event] class and emit all +// the events of the Writable and Readable [Stream API][stream]. +util.inherits(Parser, stream.Transform); + +// For extra flexibility, you can get access to the original Parser +// class: `require('csv-parse').Parser`. +module.exports.Parser = Parser; + +// ### `_transform(chunk, encoding, callback)` + +// * `chunk` Buffer | String +// The chunk to be transformed. Will always be a buffer unless the decodeStrings option was set to false. +// * `encoding` String +// If the chunk is a string, then this is the encoding type. (Ignore if decodeStrings chunk is a buffer.) +// * `callback` Function +// Call this function (optionally with an error argument) when you are done processing the supplied chunk. + +// Implementation of the [`stream.Transform` API][transform] +Parser.prototype._transform = function(chunk, encoding, callback) { + return setImmediate(() => { + var err; + if (chunk instanceof Buffer) { + chunk = this._.decoder.write(chunk); + } + err = this.__write(chunk, false); + if (err) { + return this.emit('error', err); + } + return callback(); + }); +}; + +Parser.prototype._flush = function(callback) { + return callback(this.__flush()); +}; + +Parser.prototype.__flush = function() { + var err; + err = this.__write(this._.decoder.end(), true); + if (err) { + return err; + } + if (this._.quoting) { + err = this.error(`Quoted field not terminated at line ${this.lines + 1}`); + return err; + } + if (this._.line.length > 0) { + return this.__push(this._.line); + } +}; + +Parser.prototype.__push = function(line) { + var call_column_udf, columns, err, field, i, j, len, lineAsColumns, record; + if (this._.isEnded) { + return; + } + if (this.options.skip_lines_with_empty_values && line.join('').trim() === '') { + return; + } + record = null; + if (this.options.columns === true) { + this.options.columns = line; + return; + } else if (typeof this.options.columns === 'function') { + call_column_udf = function(fn, line) { + var columns, err; + try { + columns = fn.call(null, line); + return [null, columns]; + } catch (error) { + err = error; + return [err]; + } + }; + [err, columns] = call_column_udf(this.options.columns, line); + if (err) { + return err; + } + this.options.columns = columns; + return; + } + if (!this._.line_length && line.length > 0) { + this._.line_length = this.options.columns ? this.options.columns.length : line.length; + } + // Dont check column count on empty lines + if (line.length === 1 && line[0] === '') { + this.empty_line_count++; + } else if (line.length !== this._.line_length) { + // Dont check column count with relax_column_count + if (this.options.relax_column_count) { + this.count++; + this.skipped_line_count++; + } else if (this.options.columns != null) { + // Suggest: Inconsistent header and column numbers: header is 1 and number of columns is 1 on line 1 + err = this.error(`Number of columns on line ${this.lines} does not match header`); + return err; + } else { + err = this.error(`Number of columns is inconsistent on line ${this.lines}`); + return err; + } + } else { + this.count++; + } + if (this.options.columns != null) { + lineAsColumns = {}; + for (i = j = 0, len = line.length; j < len; i = ++j) { + field = line[i]; + if (this.options.columns[i] === false) { + continue; + } + lineAsColumns[this.options.columns[i]] = field; + } + if (this.options.objname) { + record = [lineAsColumns[this.options.objname], lineAsColumns]; + } else { + record = lineAsColumns; + } + } else { + record = line; + } + if (this.count < this.options.from) { + return; + } + if (this.options.raw) { + this.push({ + raw: this._.rawBuf, + row: record + }); + this._.rawBuf = ''; + } else { + this.push(record); + } + if (this.listenerCount('record')) { + this.emit('record', record); + } + // When to is reached set ignore any future calls + if (this.count >= this.options.to) { + this._.isEnded = true; + return this.push(null); + } + return null; +}; + +Parser.prototype.__write = function(chars, end) { + var areNextCharsDelimiter, areNextCharsRowDelimiters, cast, char, err, escapeIsQuote, i, isDelimiter, isEscape, isNextCharAComment, isNextCharTrimable, isQuote, isRowDelimiter, isRowDelimiterLength, is_float, is_int, l, ltrim, nextCharPos, ref, ref1, ref2, ref3, ref4, ref5, ref6, remainingBuffer, rowDelimiter, rtrim, wasCommenting; + is_int = (value) => { + if (typeof this.is_int === 'function') { + return this.is_int(value); + } else { + return this.is_int.test(value); + } + }; + is_float = (value) => { + if (typeof this.is_float === 'function') { + return this.is_float(value); + } else { + return this.is_float.test(value); + } + }; + cast = (value, context = {}) => { + if (!this.options.cast) { + return value; + } + if (context.quoting == null) { + context.quoting = !!this._.closingQuote; + } + if (context.lines == null) { + context.lines = this.lines; + } + if (context.count == null) { + context.count = this.count; + } + if (context.index == null) { + context.index = this._.line.length; + } + // context.header ?= if @options.column and @lines is 1 and @count is 0 then true else false + if (context.header == null) { + context.header = this.options.columns === true; + } + if (context.column == null) { + context.column = Array.isArray(this.options.columns) ? this.options.columns[context.index] : context.index; + } + if (typeof this.options.cast === 'function') { + return this.options.cast(value, context); + } + if (is_int(value)) { + value = parseInt(value); + } else if (is_float(value)) { + value = parseFloat(value); + } else if (this.options.cast_date) { + value = this.options.cast_date(value, context); + } + return value; + }; + ltrim = this.options.trim || this.options.ltrim; + rtrim = this.options.trim || this.options.rtrim; + chars = this._.buf + chars; + l = chars.length; + i = 0; + if (this.lines === 0 && 0xFEFF === chars.charCodeAt(0)) { + // Strip BOM header + i++; + } + while (i < l) { + // Ensure we get enough space to look ahead + if (!end) { + remainingBuffer = chars.substr(i, l - i); + // (i+1000 >= l) or + // Skip if the remaining buffer can be comment + // Skip if the remaining buffer can be row delimiter + if ((!this.options.rowDelimiter && i + 3 > l) || (!this._.commenting && l - i < this.options.comment.length && this.options.comment.substr(0, l - i) === remainingBuffer) || (this.options.rowDelimiter && l - i < this._.rowDelimiterLength && this.options.rowDelimiter.some(function(rd) { + return rd.substr(0, l - i) === remainingBuffer; + // Skip if the remaining buffer can be row delimiter following the closing quote + })) || (this.options.rowDelimiter && this._.quoting && l - i < (this.options.quote.length + this._.rowDelimiterLength) && this.options.rowDelimiter.some((rd) => { + return (this.options.quote + rd).substr(0, l - i) === remainingBuffer; + // Skip if the remaining buffer can be delimiter + // Skip if the remaining buffer can be escape sequence + })) || (l - i <= this.options.delimiter.length && this.options.delimiter.substr(0, l - i) === remainingBuffer) || (l - i <= this.options.escape.length && this.options.escape.substr(0, l - i) === remainingBuffer)) { + break; + } + } + char = this._.nextChar ? this._.nextChar : chars.charAt(i); + this._.nextChar = l > i + 1 ? chars.charAt(i + 1) : null; + if (this.options.raw) { + this._.rawBuf += char; + } + // Auto discovery of rowDelimiter, unix, mac and windows supported + if (this.options.rowDelimiter == null) { + nextCharPos = i; + rowDelimiter = null; + // First empty line + if (!this._.quoting && (char === '\n' || char === '\r')) { + rowDelimiter = char; + nextCharPos += 1; + } else if (this._.quoting && char === this.options.quote && ((ref = this._.nextChar) === '\n' || ref === '\r')) { + rowDelimiter = this._.nextChar; + nextCharPos += 2; + } + if (rowDelimiter) { + if (rowDelimiter === '\r' && chars.charAt(nextCharPos) === '\n') { + rowDelimiter += '\n'; + } + this.options.rowDelimiter = [rowDelimiter]; + this._.rowDelimiterLength = rowDelimiter.length; + } + } + // Parse that damn char + // Note, shouldn't we have sth like chars.substr(i, @options.escape.length) + if (!this._.commenting && char === this.options.escape) { + // Make sure the escape is really here for escaping: + // If escape is same as quote, and escape is first char of a field + // and it's not quoted, then it is a quote + // Next char should be an escape or a quote + escapeIsQuote = this.options.escape === this.options.quote; + isEscape = this._.nextChar === this.options.escape; + isQuote = this._.nextChar === this.options.quote; + if (!(escapeIsQuote && !this._.field && !this._.quoting) && (isEscape || isQuote)) { + i++; + char = this._.nextChar; + this._.nextChar = chars.charAt(i + 1); + if (this._.field == null) { + this._.field = ''; + } + this._.field += char; + // Since we're skipping the next one, better add it now if in raw mode. + if (this.options.raw) { + this._.rawBuf += char; + } + i++; + continue; + } + } + // Char match quote + if (!this._.commenting && char === this.options.quote) { + if (this._.acceptOnlyEmptyChars && (char !== ' ' && char !== '\t')) { + return this.error('Only trimable characters are accepted after quotes'); + } + if (this._.quoting) { + // Make sure a closing quote is followed by a delimiter + // If we have a next character and + // it isnt a rowDelimiter and + // it isnt an column delimiter and + // it isnt the begining of a comment + // Otherwise, if this is not "relax" mode, throw an error + isNextCharTrimable = rtrim && ((ref1 = this._.nextChar) === ' ' || ref1 === '\t'); + areNextCharsRowDelimiters = this.options.rowDelimiter && this.options.rowDelimiter.some(function(rd) { + return chars.substr(i + 1, rd.length) === rd; + }); + areNextCharsDelimiter = chars.substr(i + 1, this.options.delimiter.length) === this.options.delimiter; + isNextCharAComment = this._.nextChar === this.options.comment; + if ((this._.nextChar != null) && !isNextCharTrimable && !areNextCharsRowDelimiters && !areNextCharsDelimiter && !isNextCharAComment) { + if (this.options.relax) { + this._.quoting = false; + if (this._.field) { + this._.field = `${this.options.quote}${this._.field}`; + } + } else { + if (err = this.error(`Invalid closing quote at line ${this.lines + 1}; found ${JSON.stringify(this._.nextChar)} instead of delimiter ${JSON.stringify(this.options.delimiter)}`)) { + return err; + } + } + } else if ((this._.nextChar != null) && isNextCharTrimable) { + i++; + this._.quoting = false; + this._.closingQuote = this.options.quote.length; + this._.acceptOnlyEmptyChars = true; + continue; + } else { + i++; + this._.quoting = false; + this._.closingQuote = this.options.quote.length; + if (end && i === l) { + this._.line.push(cast(this._.field || '')); + this._.field = null; + } + continue; + } + } else if (!this._.field) { + this._.quoting = true; + i++; + continue; + } else if ((this._.field != null) && !this.options.relax) { + if (err = this.error(`Invalid opening quote at line ${this.lines + 1}`)) { + return err; + } + } + } + // Otherwise, treat quote as a regular character + isRowDelimiter = this.options.rowDelimiter && this.options.rowDelimiter.some(function(rd) { + return chars.substr(i, rd.length) === rd; + }); + if (isRowDelimiter || (end && i === l - 1)) { + this.lines++; + } + // Set the commenting flag + wasCommenting = false; + if (!this._.commenting && !this._.quoting && this.options.comment && chars.substr(i, this.options.comment.length) === this.options.comment) { + this._.commenting = true; + } else if (this._.commenting && isRowDelimiter) { + wasCommenting = true; + this._.commenting = false; + } + isDelimiter = chars.substr(i, this.options.delimiter.length) === this.options.delimiter; + if (this._.acceptOnlyEmptyChars) { + if (isDelimiter || isRowDelimiter) { + this._.acceptOnlyEmptyChars = false; + } else { + if (char === ' ' || char === '\t') { + i++; + continue; + } else { + return this.error('Only trimable characters are accepted after quotes'); + } + } + } + if (!this._.commenting && !this._.quoting && (isDelimiter || isRowDelimiter)) { + if (isRowDelimiter) { + isRowDelimiterLength = this.options.rowDelimiter.filter(function(rd) { + return chars.substr(i, rd.length) === rd; + })[0].length; + } + // Empty lines + if (isRowDelimiter && this._.line.length === 0 && (this._.field == null)) { + if (wasCommenting || this.options.skip_empty_lines) { + i += isRowDelimiterLength; + this._.nextChar = chars.charAt(i); + continue; + } + } + if (rtrim) { + if (!this._.closingQuote) { + this._.field = (ref2 = this._.field) != null ? ref2.trimRight() : void 0; + } + } + this._.line.push(cast(this._.field || '')); + this._.closingQuote = 0; + this._.field = null; + if (isDelimiter) { // End of field + i += this.options.delimiter.length; + this._.nextChar = chars.charAt(i); + if (end && !this._.nextChar) { + isRowDelimiter = true; + this._.line.push(''); + } + } + if (isRowDelimiter) { // End of record + if (!this._.lineHasError) { + err = this.__push(this._.line); + if (err) { + return err; + } + } + if (this._.lineHasError) { + this._.lineHasError = false; + } + // Some cleanup for the next record + this._.line = []; + i += isRowDelimiterLength; + this._.nextChar = chars.charAt(i); + continue; + } + } else if (!this._.commenting && !this._.quoting && (char === ' ' || char === '\t')) { + if (this._.field == null) { + // Left trim unless we are quoting or field already filled + this._.field = ''; + } + if (!(ltrim && !this._.field)) { + this._.field += char; + } + i++; + } else if (!this._.commenting) { + if (this._.field == null) { + this._.field = ''; + } + this._.field += char; + i++; + } else { + i++; + } + if (!this._.commenting && ((ref3 = this._.field) != null ? ref3.length : void 0) > this.options.max_limit_on_data_read) { + return Error(`Field exceeds max_limit_on_data_read setting (${this.options.max_limit_on_data_read}) ${JSON.stringify(this.options.delimiter)}`); + } + if (!this._.commenting && ((ref4 = this._.line) != null ? ref4.length : void 0) > this.options.max_limit_on_data_read) { + return Error(`Row delimiter not found in the file ${JSON.stringify(this.options.rowDelimiter)}`); + } + } + // Flush remaining fields and lines + if (end) { + if (l === 0) { + this.lines++; + } + if (this._.field != null) { + if (rtrim) { + if (!this._.closingQuote) { + this._.field = (ref5 = this._.field) != null ? ref5.trimRight() : void 0; + } + } + this._.line.push(cast(this._.field || '')); + this._.field = null; + } + if (((ref6 = this._.field) != null ? ref6.length : void 0) > this.options.max_limit_on_data_read) { + return Error(`Delimiter not found in the file ${JSON.stringify(this.options.delimiter)}`); + } + if (this._.line.length > this.options.max_limit_on_data_read) { + return Error(`Row delimiter not found in the file ${JSON.stringify(this.options.rowDelimiter)}`); + } + } + // Store un-parsed chars for next call + this._.buf = chars.substr(i); + return null; +}; + +Parser.prototype.error = function(msg) { + var err; + err = Error(msg); + if (!this.options.skip_lines_with_error) { + return err; + } else { + if (!this._.lineHasError) { + this._.lineHasError = true; + this.emit('skip', err); + } + } + return null; +}; + +// ## Utils +isObjLiteral = function(_obj) { + var _test; + _test = _obj; + if (typeof _obj !== 'object' || _obj === null || Array.isArray(_obj)) { + return false; + } else { + return (function() { + while (!false) { + if (Object.getPrototypeOf(_test = Object.getPrototypeOf(_test)) === null) { + break; + } + } + return Object.getPrototypeOf(_obj === _test); + })(); + } +}; + +// [readme]: https://github.com/wdavidw/node-csv-parse +// [site]: http://csv.adaltas.com/parse/ +// [samples]: https://github.com/wdavidw/node-csv-parse/tree/master/samples +// [tests]: https://github.com/wdavidw/node-csv-parse/tree/master/test +// [stream]: (http://nodejs.org/api/stream.html +// [transform]: (http://nodejs.org/api/stream.html#stream_class_stream_transform_1) + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3).Buffer, __webpack_require__(11), __webpack_require__(75).setImmediate)) + +/***/ }), +/* 138 */ +/***/ (function(module, exports, __webpack_require__) { + +var __WEBPACK_AMD_DEFINE_RESULT__;/* FileSaver.js + * A saveAs() FileSaver implementation. + * 1.3.2 + * 2016-06-16 18:25:19 + * + * By Eli Grey, http://eligrey.com + * License: MIT + * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md + */ + +/*global self */ +/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ + +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ + +var saveAs = saveAs || (function(view) { + "use strict"; + // IE <10 is explicitly unsupported + if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { + return; + } + var + doc = view.document + // only get URL when necessary in case Blob.js hasn't overridden it yet + , get_URL = function() { + return view.URL || view.webkitURL || view; + } + , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") + , can_use_save_link = "download" in save_link + , click = function(node) { + var event = new MouseEvent("click"); + node.dispatchEvent(event); + } + , is_safari = /constructor/i.test(view.HTMLElement) || view.safari + , is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent) + , throw_outside = function(ex) { + (view.setImmediate || view.setTimeout)(function() { + throw ex; + }, 0); + } + , force_saveable_type = "application/octet-stream" + // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to + , arbitrary_revoke_timeout = 1000 * 40 // in ms + , revoke = function(file) { + var revoker = function() { + if (typeof file === "string") { // file is an object URL + get_URL().revokeObjectURL(file); + } else { // file is a File + file.remove(); + } + }; + setTimeout(revoker, arbitrary_revoke_timeout); + } + , dispatch = function(filesaver, event_types, event) { + event_types = [].concat(event_types); + var i = event_types.length; + while (i--) { + var listener = filesaver["on" + event_types[i]]; + if (typeof listener === "function") { + try { + listener.call(filesaver, event || filesaver); + } catch (ex) { + throw_outside(ex); + } + } + } + } + , auto_bom = function(blob) { + // prepend BOM for UTF-8 XML and text/* types (including HTML) + // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF + if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { + return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type}); + } + return blob; + } + , FileSaver = function(blob, name, no_auto_bom) { + if (!no_auto_bom) { + blob = auto_bom(blob); + } + // First try a.download, then web filesystem, then object URLs + var + filesaver = this + , type = blob.type + , force = type === force_saveable_type + , object_url + , dispatch_all = function() { + dispatch(filesaver, "writestart progress write writeend".split(" ")); + } + // on any filesys errors revert to saving with object URLs + , fs_error = function() { + if ((is_chrome_ios || (force && is_safari)) && view.FileReader) { + // Safari doesn't allow downloading of blob urls + var reader = new FileReader(); + reader.onloadend = function() { + var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;'); + var popup = view.open(url, '_blank'); + if(!popup) view.location.href = url; + url=undefined; // release reference before dispatching + filesaver.readyState = filesaver.DONE; + dispatch_all(); + }; + reader.readAsDataURL(blob); + filesaver.readyState = filesaver.INIT; + return; + } + // don't create more object URLs than needed + if (!object_url) { + object_url = get_URL().createObjectURL(blob); + } + if (force) { + view.location.href = object_url; + } else { + var opened = view.open(object_url, "_blank"); + if (!opened) { + // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html + view.location.href = object_url; + } + } + filesaver.readyState = filesaver.DONE; + dispatch_all(); + revoke(object_url); + } + ; + filesaver.readyState = filesaver.INIT; + + if (can_use_save_link) { + object_url = get_URL().createObjectURL(blob); + setTimeout(function() { + save_link.href = object_url; + save_link.download = name; + click(save_link); + dispatch_all(); + revoke(object_url); + filesaver.readyState = filesaver.DONE; + }); + return; + } + + fs_error(); + } + , FS_proto = FileSaver.prototype + , saveAs = function(blob, name, no_auto_bom) { + return new FileSaver(blob, name || blob.name || "download", no_auto_bom); + } + ; + // IE 10+ (native saveAs) + if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { + return function(blob, name, no_auto_bom) { + name = name || blob.name || "download"; + + if (!no_auto_bom) { + blob = auto_bom(blob); + } + return navigator.msSaveOrOpenBlob(blob, name); + }; + } + + FS_proto.abort = function(){}; + FS_proto.readyState = FS_proto.INIT = 0; + FS_proto.WRITING = 1; + FS_proto.DONE = 2; + + FS_proto.error = + FS_proto.onwritestart = + FS_proto.onprogress = + FS_proto.onwrite = + FS_proto.onabort = + FS_proto.onerror = + FS_proto.onwriteend = + null; + + return saveAs; +}( + typeof self !== "undefined" && self + || typeof window !== "undefined" && window + || this.content +)); +// `self` is undefined in Firefox for Android content script context +// while `this` is nsIContentFrameMessageManager +// with an attribute `content` that corresponds to the window + +if (typeof module !== "undefined" && module.exports) { + module.exports.saveAs = saveAs; +} else if (("function" !== "undefined" && __webpack_require__(156) !== null) && (__webpack_require__(157) !== null)) { + !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { + return saveAs; + }.call(exports, __webpack_require__, exports, module), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); +} + + +/***/ }), +/* 139 */ +/***/ (function(module, exports) { + +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + + value = Math.abs(value) + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } + + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128 +} + + +/***/ }), +/* 140 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(Buffer, process) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Writer = exports.VexFlow = exports.Utils = exports.Track = exports.ProgramChangeEvent = exports.NoteOnEvent = exports.NoteOffEvent = exports.NoteEvent = exports.MetaEvent = exports.ControllerChangeEvent = exports.Constants = exports.Chunk = undefined; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _tonalMidi = __webpack_require__(150); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Object representation of the chunk section of a MIDI file. + * @param {object} fields - {type: number, data: array, size: array} + * @return {Chunk} + */ +var Chunk = function Chunk(fields) { + _classCallCheck(this, Chunk); + + this.type = fields.type; + this.data = fields.data; + this.size = [0, 0, 0, fields.data.length]; +}; + +exports.Chunk = Chunk; +/** + * MIDI file format constants, including note -> MIDI number translation. + * @return {Constants} + */ + +var Constants = { + VERSION: '1.5.2', + HEADER_CHUNK_TYPE: [0x4d, 0x54, 0x68, 0x64], // Mthd + HEADER_CHUNK_LENGTH: [0x00, 0x00, 0x00, 0x06], // Header size for SMF + HEADER_CHUNK_FORMAT0: [0x00, 0x00], // Midi Type 0 id + HEADER_CHUNK_FORMAT1: [0x00, 0x01], // Midi Type 1 id + HEADER_CHUNK_DIVISION: [0x00, 0x80], // Defaults to 128 ticks per beat + TRACK_CHUNK_TYPE: [0x4d, 0x54, 0x72, 0x6b], // MTrk, + META_EVENT_ID: 0xFF, + META_TEXT_ID: 0x01, + META_COPYRIGHT_ID: 0x02, + META_TRACK_NAME_ID: 0x03, + META_INSTRUMENT_NAME_ID: 0x04, + META_LYRIC_ID: 0x05, + META_MARKER_ID: 0x06, + META_CUE_POINT: 0x07, + META_TEMPO_ID: 0x51, + META_SMTPE_OFFSET: 0x54, + META_TIME_SIGNATURE_ID: 0x58, + META_KEY_SIGNATURE_ID: 0x59, + META_END_OF_TRACK_ID: [0x2F, 0x00], + CONTROLLER_CHANGE_STATUS: 0xB0, // includes channel number (0) + PROGRAM_CHANGE_STATUS: 0xC0 // includes channel number (0) +}; + +exports.Constants = Constants; +/** + * Holds all data for a "controller change" MIDI event + * @param {object} fields {controllerNumber: integer, controllerValue: integer} + * @return {ControllerChangeEvent} + */ + +var ControllerChangeEvent = function ControllerChangeEvent(fields) { + _classCallCheck(this, ControllerChangeEvent); + + this.type = 'controller'; + // delta time defaults to 0. + this.data = Utils.numberToVariableLength(0x00).concat(Constants.CONTROLLER_CHANGE_STATUS, fields.controllerNumber, fields.controllerValue); +}; + +exports.ControllerChangeEvent = ControllerChangeEvent; +/** + * Object representation of a meta event. + * @param {object} fields - type, data + * @return {MetaEvent} + */ + +var MetaEvent = function MetaEvent(fields) { + _classCallCheck(this, MetaEvent); + + this.type = 'meta'; + this.data = Utils.numberToVariableLength(0x00); // Start with zero time delta + this.data = this.data.concat(Constants.META_EVENT_ID, fields.data); +}; + +exports.MetaEvent = MetaEvent; +/** + * Wrapper for noteOnEvent/noteOffEvent objects that builds both events. + * @param {object} fields - {pitch: '[C4]', duration: '4', wait: '4', velocity: 1-100} + * @return {NoteEvent} + */ + +var NoteEvent = function () { + function NoteEvent(fields) { + _classCallCheck(this, NoteEvent); + + this.type = 'note'; + this.pitch = Utils.toArray(fields.pitch); + this.wait = fields.wait || 0; + this.duration = fields.duration; + this.sequential = fields.sequential || false; + this.velocity = fields.velocity || 50; + this.channel = fields.channel || 1; + this.repeat = fields.repeat || 1; + this.velocity = this.convertVelocity(this.velocity); + this.grace = fields.grace; + this.buildData(); + } + + /** + * Builds int array for this event. + * @return {NoteEvent} + */ + + + _createClass(NoteEvent, [{ + key: 'buildData', + value: function buildData() { + this.data = []; + + var tickDuration = this.getTickDuration(this.duration, 'note'); + var restDuration = this.getTickDuration(this.wait, 'rest'); + + // Apply grace note(s) and subtract ticks (currently 1 tick per grace note) from tickDuration so net value is the same + if (this.grace) { + var graceDuration = 1; + this.grace = Utils.toArray(this.grace); + this.grace.forEach(function (pitch) { + var noteEvent = new NoteEvent({ pitch: this.grace, duration: 'T' + graceDuration }); + this.data = this.data.concat(noteEvent.data); + + tickDuration -= graceDuration; + }, this); + } + + // fields.pitch could be an array of pitches. + // If so create note events for each and apply the same duration. + var noteOn, noteOff; + if (Array.isArray(this.pitch)) { + // By default this is a chord if it's an array of notes that requires one NoteOnEvent. + // If this.sequential === true then it's a sequential string of notes that requires separate NoteOnEvents. + if (!this.sequential) { + // Handle repeat + for (var j = 0; j < this.repeat; j++) { + // Note on + this.pitch.forEach(function (p, i) { + if (i == 0) { + noteOn = new NoteOnEvent({ data: Utils.numberToVariableLength(restDuration).concat(this.getNoteOnStatus(), Utils.getPitch(p), this.velocity) }); + } else { + // Running status (can ommit the note on status) + noteOn = new NoteOnEvent({ data: [0, Utils.getPitch(p), this.velocity] }); + } + + this.data = this.data.concat(noteOn.data); + }, this); + + // Note off + this.pitch.forEach(function (p, i) { + if (i == 0) { + noteOff = new NoteOffEvent({ data: Utils.numberToVariableLength(tickDuration).concat(this.getNoteOffStatus(), Utils.getPitch(p), this.velocity) }); + } else { + // Running status (can ommit the note off status) + noteOff = new NoteOffEvent({ data: [0, Utils.getPitch(p), this.velocity] }); + } + + this.data = this.data.concat(noteOff.data); + }, this); + } + } else { + // Handle repeat + for (var j = 0; j < this.repeat; j++) { + this.pitch.forEach(function (p, i) { + // restDuration only applies to first note + if (i > 0) { + restDuration = 0; + } + + // If duration is 8th triplets we need to make sure that the total ticks == quarter note. + // So, the last one will need to be the remainder + if (this.duration === '8t' && i == this.pitch.length - 1) { + var quarterTicks = Utils.numberFromBytes(Constants.HEADER_CHUNK_DIVISION); + tickDuration = quarterTicks - tickDuration * 2; + } + + noteOn = new NoteOnEvent({ data: Utils.numberToVariableLength(restDuration).concat([this.getNoteOnStatus(), Utils.getPitch(p), this.velocity]) }); + noteOff = new NoteOffEvent({ data: Utils.numberToVariableLength(tickDuration).concat([this.getNoteOffStatus(), Utils.getPitch(p), this.velocity]) }); + + this.data = this.data.concat(noteOn.data, noteOff.data); + }, this); + } + } + + return this; + } + + throw 'pitch must be an array.'; + } + }, { + key: 'convertVelocity', + + + /** + * Converts velocity to value 0-127 + * @param {number} velocity - Velocity value 1-100 + * @return {number} + */ + value: function convertVelocity(velocity) { + // Max passed value limited to 100 + velocity = velocity > 100 ? 100 : velocity; + return Math.round(velocity / 100 * 127); + } + }, { + key: 'getTickDuration', + + + /** + * Gets the total number of ticks based on passed duration. + * Note: type=='note' defaults to quarter note, type==='rest' defaults to 0 + * @param {(string|array)} duration + * @param {string} type ['note', 'rest'] + * @return {number} + */ + value: function getTickDuration(duration, type) { + if (Array.isArray(duration)) { + // Recursively execute this method for each item in the array and return the sum of tick durations. + return duration.map(function (value) { + return this.getTickDuration(value, type); + }, this).reduce(function (a, b) { + return a + b; + }, 0); + } + + duration = duration.toString(); + + if (duration.toLowerCase().charAt(0) === 't') { + // If duration starts with 't' then the number that follows is an explicit tick count + return parseInt(duration.substring(1)); + } + + // Need to apply duration here. Quarter note == Constants.HEADER_CHUNK_DIVISION + // Rounding only applies to triplets, which the remainder is handled below + var quarterTicks = Utils.numberFromBytes(Constants.HEADER_CHUNK_DIVISION); + return Math.round(quarterTicks * this.getDurationMultiplier(duration, type)); + } + + /** + * Gets what to multiple ticks/quarter note by to get the specified duration. + * Note: type=='note' defaults to quarter note, type==='rest' defaults to 0 + * @param {string} duration + * @param {string} type ['note','rest'] + * @return {number} + */ + + }, { + key: 'getDurationMultiplier', + value: function getDurationMultiplier(duration, type) { + // Need to apply duration here. Quarter note == Constants.HEADER_CHUNK_DIVISION + switch (duration) { + case '0': + return 0; + case '1': + return 4; + case '2': + return 2; + case 'd2': + return 3; + case '4': + return 1; + case '4t': + return 0.666; + case 'd4': + return 1.5; + case '8': + return 0.5; + case '8t': + // For 8th triplets, let's divide a quarter by 3, round to the nearest int, and substract the remainder to the last one. + return 0.33; + case 'd8': + return 0.75; + case '16': + return 0.25; + case '16t': + return 0.166; + case '32': + return 0.125; + case '64': + return 0.0625; + default: + // Notes default to a quarter, rests default to 0 + //return type === 'note' ? 1 : 0; + } + + throw duration + ' is not a valid duration.'; + } + }, { + key: 'getNoteOnStatus', + + + /** + * Gets the note on status code based on the selected channel. 0x9{0-F} + * Note on at channel 0 is 0x90 (144) + * 0 = Ch 1 + * @return {number} + */ + value: function getNoteOnStatus() { + return 144 + this.channel - 1; + } + + /** + * Gets the note off status code based on the selected channel. 0x8{0-F} + * Note off at channel 0 is 0x80 (128) + * 0 = Ch 1 + * @return {number} + */ + + }, { + key: 'getNoteOffStatus', + value: function getNoteOffStatus() { + return 128 + this.channel - 1; + } + }]); + + return NoteEvent; +}(); + +exports.NoteEvent = NoteEvent; +/** + * Holds all data for a "note off" MIDI event + * @param {object} fields {data: []} + * @return {NoteOffEvent} + */ + +var NoteOffEvent = function NoteOffEvent(fields) { + _classCallCheck(this, NoteOffEvent); + + this.data = fields.data; +}; + +exports.NoteOffEvent = NoteOffEvent; +/** + * Holds all data for a "note on" MIDI event + * @param {object} fields {data: []} + * @return {NoteOnEvent} + */ + +var NoteOnEvent = function NoteOnEvent(fields) { + _classCallCheck(this, NoteOnEvent); + + this.data = fields.data; +}; + +exports.NoteOnEvent = NoteOnEvent; +/** + * Holds all data for a "program change" MIDI event + * @param {object} fields {instrument: integer} + * @return {ProgramChangeEvent} + */ + +var ProgramChangeEvent = function ProgramChangeEvent(fields) { + _classCallCheck(this, ProgramChangeEvent); + + this.type = 'program'; + // delta time defaults to 0. + this.data = Utils.numberToVariableLength(0x00).concat(Constants.PROGRAM_CHANGE_STATUS, fields.instrument); +}; + +exports.ProgramChangeEvent = ProgramChangeEvent; +/** + * Holds all data for a track. + * @param {object} fields {type: number, data: array, size: array, events: array} + * @return {Track} + */ + +var Track = function () { + function Track() { + _classCallCheck(this, Track); + + this.type = Constants.TRACK_CHUNK_TYPE; + this.data = []; + this.size = []; + this.events = []; + } + + /** + * Adds any event type to the track. + * @param {(NoteEvent|MetaEvent|ProgramChangeEvent)} event - Event object. + * @param {function} mapFunction - Callback which can be used to apply specific properties to all events. + * @return {Track} + */ + + + _createClass(Track, [{ + key: 'addEvent', + value: function addEvent(event, mapFunction) { + if (Array.isArray(event)) { + event.forEach(function (e, i) { + // Handle map function if provided + if (typeof mapFunction === 'function' && e.type === 'note') { + var properties = mapFunction(i, e); + + if ((typeof properties === 'undefined' ? 'undefined' : _typeof(properties)) === 'object') { + for (var j in properties) { + switch (j) { + case 'duration': + e.duration = properties[j]; + break; + case 'sequential': + e.sequential = properties[j]; + break; + case 'velocity': + e.velocity = e.convertVelocity(properties[j]); + break; + } + } + + // Gotta build that data + e.buildData(); + } + } + + this.data = this.data.concat(e.data); + this.size = Utils.numberToBytes(this.data.length, 4); // 4 bytes long + this.events.push(e); + }, this); + } else { + this.data = this.data.concat(event.data); + this.size = Utils.numberToBytes(this.data.length, 4); // 4 bytes long + this.events.push(event); + } + + return this; + } + + /** + * Sets tempo of the MIDI file. + * @param {number} bpm - Tempo in beats per minute. + * @return {Track} + */ + + }, { + key: 'setTempo', + value: function setTempo(bpm) { + var event = new MetaEvent({ data: [Constants.META_TEMPO_ID] }); + event.data.push(0x03); // Size + var tempo = Math.round(60000000 / bpm); + event.data = event.data.concat(Utils.numberToBytes(tempo, 3)); // Tempo, 3 bytes + return this.addEvent(event); + } + + /** + * Sets time signature. + * @param {number} numerator - Top number of the time signature. + * @param {number} denominator - Bottom number of the time signature. + * @param {number} midiclockspertick - Defaults to 24. + * @param {number} notespermidiclock - Defaults to 8. + * @return {Track} + */ + + }, { + key: 'setTimeSignature', + value: function setTimeSignature(numerator, denominator, midiclockspertick, notespermidiclock) { + midiclockspertick = midiclockspertick || 24; + notespermidiclock = notespermidiclock || 8; + + var event = new MetaEvent({ data: [Constants.META_TIME_SIGNATURE_ID] }); + event.data.push(0x04); // Size + event.data = event.data.concat(Utils.numberToBytes(numerator, 1)); // Numerator, 1 bytes + + var _denominator = Math.log2(denominator); // Denominator is expressed as pow of 2 + event.data = event.data.concat(Utils.numberToBytes(_denominator, 1)); // Denominator, 1 bytes + event.data = event.data.concat(Utils.numberToBytes(midiclockspertick, 1)); // MIDI Clocks per tick, 1 bytes + event.data = event.data.concat(Utils.numberToBytes(notespermidiclock, 1)); // Number of 1/32 notes per MIDI clocks, 1 bytes + return this.addEvent(event); + } + + /** + * Sets key signature. + * @param {*} sf - + * @param {*} mi - + * @return {Track} + */ + + }, { + key: 'setKeySignature', + value: function setKeySignature(sf, mi) { + var event = new MetaEvent({ data: [Constants.META_KEY_SIGNATURE_ID] }); + event.data.push(0x02); // Size + + var mode = mi || 0; + sf = sf || 0; + + // Function called with string notation + if (typeof mi === 'undefined') { + var fifths = [['Cb', 'Gb', 'Db', 'Ab', 'Eb', 'Bb', 'F', 'C', 'G', 'D', 'A', 'E', 'B', 'F#', 'C#'], ['ab', 'eb', 'bb', 'f', 'c', 'g', 'd', 'a', 'e', 'b', 'f#', 'c#', 'g#', 'd#', 'a#']]; + var _sflen = sf.length; + var note = sf || 'C'; + + if (sf[0] === sf[0].toLowerCase()) mode = 1; + + if (_sflen > 1) { + switch (sf.charAt(_sflen - 1)) { + case 'm': + mode = 1; + note = sf.charAt(0).toLowerCase(); + note = note.concat(sf.substring(1, _sflen - 1)); + break; + case '-': + mode = 1; + note = sf.charAt(0).toLowerCase(); + note = note.concat(sf.substring(1, _sflen - 1)); + break; + case 'M': + mode = 0; + note = sf.charAt(0).toUpperCase(); + note = note.concat(sf.substring(1, _sflen - 1)); + break; + case '+': + mode = 0; + note = sf.charAt(0).toUpperCase(); + note = note.concat(sf.substring(1, _sflen - 1)); + break; + } + } + + var fifthindex = fifths[mode].indexOf(note); + sf = fifthindex === -1 ? 0 : fifthindex - 7; + } + + event.data = event.data.concat(Utils.numberToBytes(sf, 1)); // Number of sharp or flats ( < 0 flat; > 0 sharp) + event.data = event.data.concat(Utils.numberToBytes(mode, 1)); // Mode: 0 major, 1 minor + return this.addEvent(event); + } + + /** + * Adds text to MIDI file. + * @param {string} text - Text to add. + * @return {Track} + */ + + }, { + key: 'addText', + value: function addText(text) { + var event = new MetaEvent({ data: [Constants.META_TEXT_ID] }); + var stringBytes = Utils.stringToBytes(text); + event.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size + event.data = event.data.concat(stringBytes); // Text + return this.addEvent(event); + } + + /** + * Adds copyright to MIDI file. + * @param {string} text - Text of copyright line. + * @return {Track} + */ + + }, { + key: 'addCopyright', + value: function addCopyright(text) { + var event = new MetaEvent({ data: [Constants.META_COPYRIGHT_ID] }); + var stringBytes = Utils.stringToBytes(text); + event.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size + event.data = event.data.concat(stringBytes); // Text + return this.addEvent(event); + } + + /** + * Adds Sequence/Track Name. + * @param {string} text - Text of track name. + * @return {Track} + */ + + }, { + key: 'addTrackName', + value: function addTrackName(text) { + var event = new MetaEvent({ data: [Constants.META_TRACK_NAME_ID] }); + var stringBytes = Utils.stringToBytes(text); + event.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size + event.data = event.data.concat(stringBytes); // Text + return this.addEvent(event); + } + + /** + * Sets instrument name of track. + * @param {string} text - Name of instrument. + * @return {Track} + */ + + }, { + key: 'addInstrumentName', + value: function addInstrumentName(text) { + var event = new MetaEvent({ data: [Constants.META_INSTRUMENT_NAME_ID] }); + var stringBytes = Utils.stringToBytes(text); + event.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size + event.data = event.data.concat(stringBytes); // Text + return this.addEvent(event); + } + + /** + * Adds marker to MIDI file. + * @param {string} text - Marker text. + * @return {Track} + */ + + }, { + key: 'addMarker', + value: function addMarker(text) { + var event = new MetaEvent({ data: [Constants.META_MARKER_ID] }); + var stringBytes = Utils.stringToBytes(text); + event.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size + event.data = event.data.concat(stringBytes); // Text + return this.addEvent(event); + } + + /** + * Adds cue point to MIDI file. + * @param {string} text - Text of cue point. + * @return {Track} + */ + + }, { + key: 'addCuePoint', + value: function addCuePoint(text) { + var event = new MetaEvent({ data: [Constants.META_CUE_POINT] }); + var stringBytes = Utils.stringToBytes(text); + event.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size + event.data = event.data.concat(stringBytes); // Text + return this.addEvent(event); + } + + /** + * Adds lyric to MIDI file. + * @param {string} lyric - Lyric text to add. + * @return {Track} + */ + + }, { + key: 'addLyric', + value: function addLyric(lyric) { + var event = new MetaEvent({ data: [Constants.META_LYRIC_ID] }); + var stringBytes = Utils.stringToBytes(lyric); + event.data = event.data.concat(Utils.numberToVariableLength(stringBytes.length)); // Size + event.data = event.data.concat(stringBytes); // Lyric + return this.addEvent(event); + } + + /** + * Channel mode messages + * @return {Track} + */ + + }, { + key: 'polyModeOn', + value: function polyModeOn() { + var event = new NoteOnEvent({ data: [0x00, 0xB0, 0x7E, 0x00] }); + return this.addEvent(event); + } + }]); + + return Track; +}(); + +exports.Track = Track; + +/** + * Static utility functions used throughout the library. + */ +var Utils = function () { + function Utils() { + _classCallCheck(this, Utils); + } + + _createClass(Utils, null, [{ + key: 'version', + + + /** + * Gets MidiWriterJS version number. + * @return {string} + */ + value: function version() { + return Constants.VERSION; + } + + /** + * Convert a string to an array of bytes + * @param {string} string + * @return {array} + */ + + }, { + key: 'stringToBytes', + value: function stringToBytes(string) { + return string.split('').map(function (char) { + return char.charCodeAt(); + }); + } + + /** + * Checks if argument is a valid number. + * @param {*} n - Value to check + * @return {boolean} + */ + + }, { + key: 'isNumeric', + value: function isNumeric(n) { + return !isNaN(parseFloat(n)) && isFinite(n); + } + + /** + * Returns the correct MIDI number for the specified pitch. + * Uses Tonal Midi - https://github.com/danigb/tonal/tree/master/packages/midi + * @param {(string|number)} pitch - 'C#4' or midi note code + * @return {number} + */ + + }, { + key: 'getPitch', + value: function getPitch(pitch) { + return (0, _tonalMidi.toMidi)(pitch); + } + + /** + * Translates number of ticks to MIDI timestamp format, returning an array of + * hex strings with the time values. Midi has a very particular time to express time, + * take a good look at the spec before ever touching this function. + * Thanks to https://github.com/sergi/jsmidi + * + * @param {number} ticks - Number of ticks to be translated + * @return {array} - Bytes that form the MIDI time value + */ + + }, { + key: 'numberToVariableLength', + value: function numberToVariableLength(ticks) { + var buffer = ticks & 0x7F; + + while (ticks = ticks >> 7) { + buffer <<= 8; + buffer |= ticks & 0x7F | 0x80; + } + + var bList = []; + while (true) { + bList.push(buffer & 0xff); + + if (buffer & 0x80) buffer >>= 8;else { + break; + } + } + + return bList; + } + + /** + * Counts number of bytes in string + * @param {string} s + * @return {array} + */ + + }, { + key: 'stringByteCount', + value: function stringByteCount(s) { + return encodeURI(s).split(/%..|./).length - 1; + } + + /** + * Get an int from an array of bytes. + * @param {array} bytes + * @return {number} + */ + + }, { + key: 'numberFromBytes', + value: function numberFromBytes(bytes) { + var hex = ''; + var stringResult; + + bytes.forEach(function (byte) { + stringResult = byte.toString(16); + + // ensure string is 2 chars + if (stringResult.length == 1) stringResult = "0" + stringResult; + + hex += stringResult; + }); + + return parseInt(hex, 16); + } + + /** + * Takes a number and splits it up into an array of bytes. Can be padded by passing a number to bytesNeeded + * @param {number} number + * @param {number} bytesNeeded + * @return {array} - Array of bytes + */ + + }, { + key: 'numberToBytes', + value: function numberToBytes(number, bytesNeeded) { + bytesNeeded = bytesNeeded || 1; + + var hexString = number.toString(16); + + if (hexString.length & 1) { + // Make sure hex string is even number of chars + hexString = '0' + hexString; + } + + // Split hex string into an array of two char elements + var hexArray = hexString.match(/.{2}/g); + + // Now parse them out as integers + hexArray = hexArray.map(function (item) { + return parseInt(item, 16); + }); + + // Prepend empty bytes if we don't have enough + if (hexArray.length < bytesNeeded) { + while (bytesNeeded - hexArray.length > 0) { + hexArray.unshift(0); + } + } + + return hexArray; + } + + /** + * Converts value to array if needed. + * @param {string} value + * @return {array} + */ + + }, { + key: 'toArray', + value: function toArray(value) { + if (Array.isArray(value)) return value; + return [value]; + } + }]); + + return Utils; +}(); + +exports.Utils = Utils; + +var VexFlow = function () { + function VexFlow() { + _classCallCheck(this, VexFlow); + } + // code... + + + /** + * Support for converting VexFlow voice into MidiWriterJS track + * @return MidiWritier.Track object + */ + + + _createClass(VexFlow, [{ + key: 'trackFromVoice', + value: function trackFromVoice(voice) { + var track = new Track(); + var wait; + var pitches = []; + + voice.tickables.forEach(function (tickable) { + pitches = []; + + if (tickable.noteType === 'n') { + tickable.keys.forEach(function (key) { + // build array of pitches + pitches.push(this.convertPitch(key)); + }); + } else if (tickable.noteType === 'r') { + // move on to the next tickable and use this rest as a `wait` property for the next event + wait = this.convertDuration(tickable); + return; + } + + track.addEvent(new NoteEvent({ pitch: pitches, duration: this.convertDuration(tickable), wait: wait })); + + // reset wait + wait = 0; + }); + + return track; + } + + /** + * Converts VexFlow pitch syntax to MidiWriterJS syntax + * @param pitch string + */ + + }, { + key: 'convertPitch', + value: function convertPitch(pitch) { + return pitch.replace('/', ''); + } + + /** + * Converts VexFlow duration syntax to MidiWriterJS syntax + * @param note struct from VexFlow + */ + + }, { + key: 'convertDuration', + value: function convertDuration(note) { + switch (note.duration) { + case 'w': + return '1'; + case 'h': + return note.isDotted() ? 'd2' : '2'; + case 'q': + return note.isDotted() ? 'd4' : '4'; + case '8': + return note.isDotted() ? 'd8' : '8'; + } + + return note.duration; + } + }]); + + return VexFlow; +}(); + +exports.VexFlow = VexFlow; +/** + * Object that puts together tracks and provides methods for file output. + * @param {array} tracks - An array of {Track} objects. + * @return {Writer} + */ + +var Writer = function () { + function Writer(tracks) { + _classCallCheck(this, Writer); + + this.data = []; + + var trackType = tracks.length > 1 ? Constants.HEADER_CHUNK_FORMAT1 : Constants.HEADER_CHUNK_FORMAT0; + var numberOfTracks = Utils.numberToBytes(tracks.length, 2); // two bytes long + + // Header chunk + this.data.push(new Chunk({ + type: Constants.HEADER_CHUNK_TYPE, + data: trackType.concat(numberOfTracks, Constants.HEADER_CHUNK_DIVISION) })); + + // Track chunks + tracks.forEach(function (track, i) { + track.addEvent(new MetaEvent({ data: Constants.META_END_OF_TRACK_ID })); + this.data.push(track); + }, this); + } + + /** + * Builds the file into a Uint8Array + * @return {Uint8Array} + */ + + + _createClass(Writer, [{ + key: 'buildFile', + value: function buildFile() { + var build = []; + + // Data consists of chunks which consists of data + this.data.forEach(function (d) { + return build = build.concat(d.type, d.size, d.data); + }); + + return new Uint8Array(build); + } + + /** + * Convert file buffer to a base64 string. Different methods depending on if browser or node. + * @return {string} + */ + + }, { + key: 'base64', + value: function base64() { + if (typeof btoa === 'function') return btoa(String.fromCharCode.apply(null, this.buildFile())); + return new Buffer(this.buildFile()).toString('base64'); + } + + /** + * Get the data URI. + * @return {string} + */ + + }, { + key: 'dataUri', + value: function dataUri() { + return 'data:audio/midi;base64,' + this.base64(); + } + + /** + * Output to stdout + * @return {string} + */ + + }, { + key: 'stdout', + value: function stdout() { + return process.stdout.write(new Buffer(this.buildFile())); + } + + /** + * Save to MIDI file + * @param {string} filename + */ + + }, { + key: 'saveMIDI', + value: function saveMIDI(filename) { + var buffer = new Buffer(this.buildFile()); + fs.writeFile(filename + '.mid', buffer, function (err) { + if (err) return console.log(err); + }); + } + }]); + + return Writer; +}(); + +exports.Writer = Writer; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbIkNodW5rIiwiZmllbGRzIiwidHlwZSIsImRhdGEiLCJzaXplIiwibGVuZ3RoIiwiQ29uc3RhbnRzIiwiVkVSU0lPTiIsIkhFQURFUl9DSFVOS19UWVBFIiwiSEVBREVSX0NIVU5LX0xFTkdUSCIsIkhFQURFUl9DSFVOS19GT1JNQVQwIiwiSEVBREVSX0NIVU5LX0ZPUk1BVDEiLCJIRUFERVJfQ0hVTktfRElWSVNJT04iLCJUUkFDS19DSFVOS19UWVBFIiwiTUVUQV9FVkVOVF9JRCIsIk1FVEFfVEVYVF9JRCIsIk1FVEFfQ09QWVJJR0hUX0lEIiwiTUVUQV9UUkFDS19OQU1FX0lEIiwiTUVUQV9JTlNUUlVNRU5UX05BTUVfSUQiLCJNRVRBX0xZUklDX0lEIiwiTUVUQV9NQVJLRVJfSUQiLCJNRVRBX0NVRV9QT0lOVCIsIk1FVEFfVEVNUE9fSUQiLCJNRVRBX1NNVFBFX09GRlNFVCIsIk1FVEFfVElNRV9TSUdOQVRVUkVfSUQiLCJNRVRBX0tFWV9TSUdOQVRVUkVfSUQiLCJNRVRBX0VORF9PRl9UUkFDS19JRCIsIkNPTlRST0xMRVJfQ0hBTkdFX1NUQVRVUyIsIlBST0dSQU1fQ0hBTkdFX1NUQVRVUyIsIkNvbnRyb2xsZXJDaGFuZ2VFdmVudCIsIlV0aWxzIiwibnVtYmVyVG9WYXJpYWJsZUxlbmd0aCIsImNvbmNhdCIsImNvbnRyb2xsZXJOdW1iZXIiLCJjb250cm9sbGVyVmFsdWUiLCJNZXRhRXZlbnQiLCJOb3RlRXZlbnQiLCJwaXRjaCIsInRvQXJyYXkiLCJ3YWl0IiwiZHVyYXRpb24iLCJzZXF1ZW50aWFsIiwidmVsb2NpdHkiLCJjaGFubmVsIiwicmVwZWF0IiwiY29udmVydFZlbG9jaXR5IiwiZ3JhY2UiLCJidWlsZERhdGEiLCJ0aWNrRHVyYXRpb24iLCJnZXRUaWNrRHVyYXRpb24iLCJyZXN0RHVyYXRpb24iLCJncmFjZUR1cmF0aW9uIiwiZm9yRWFjaCIsIm5vdGVFdmVudCIsIm5vdGVPbiIsIm5vdGVPZmYiLCJBcnJheSIsImlzQXJyYXkiLCJqIiwicCIsImkiLCJOb3RlT25FdmVudCIsImdldE5vdGVPblN0YXR1cyIsImdldFBpdGNoIiwiTm90ZU9mZkV2ZW50IiwiZ2V0Tm90ZU9mZlN0YXR1cyIsInF1YXJ0ZXJUaWNrcyIsIm51bWJlckZyb21CeXRlcyIsIk1hdGgiLCJyb3VuZCIsIm1hcCIsInZhbHVlIiwicmVkdWNlIiwiYSIsImIiLCJ0b1N0cmluZyIsInRvTG93ZXJDYXNlIiwiY2hhckF0IiwicGFyc2VJbnQiLCJzdWJzdHJpbmciLCJnZXREdXJhdGlvbk11bHRpcGxpZXIiLCJQcm9ncmFtQ2hhbmdlRXZlbnQiLCJpbnN0cnVtZW50IiwiVHJhY2siLCJldmVudHMiLCJldmVudCIsIm1hcEZ1bmN0aW9uIiwiZSIsInByb3BlcnRpZXMiLCJudW1iZXJUb0J5dGVzIiwicHVzaCIsImJwbSIsInRlbXBvIiwiYWRkRXZlbnQiLCJudW1lcmF0b3IiLCJkZW5vbWluYXRvciIsIm1pZGljbG9ja3NwZXJ0aWNrIiwibm90ZXNwZXJtaWRpY2xvY2siLCJfZGVub21pbmF0b3IiLCJsb2cyIiwic2YiLCJtaSIsIm1vZGUiLCJmaWZ0aHMiLCJfc2ZsZW4iLCJub3RlIiwidG9VcHBlckNhc2UiLCJmaWZ0aGluZGV4IiwiaW5kZXhPZiIsInRleHQiLCJzdHJpbmdCeXRlcyIsInN0cmluZ1RvQnl0ZXMiLCJseXJpYyIsInN0cmluZyIsInNwbGl0IiwiY2hhciIsImNoYXJDb2RlQXQiLCJuIiwiaXNOYU4iLCJwYXJzZUZsb2F0IiwiaXNGaW5pdGUiLCJ0aWNrcyIsImJ1ZmZlciIsImJMaXN0IiwicyIsImVuY29kZVVSSSIsImJ5dGVzIiwiaGV4Iiwic3RyaW5nUmVzdWx0IiwiYnl0ZSIsIm51bWJlciIsImJ5dGVzTmVlZGVkIiwiaGV4U3RyaW5nIiwiaGV4QXJyYXkiLCJtYXRjaCIsIml0ZW0iLCJ1bnNoaWZ0IiwiVmV4RmxvdyIsInZvaWNlIiwidHJhY2siLCJwaXRjaGVzIiwidGlja2FibGVzIiwidGlja2FibGUiLCJub3RlVHlwZSIsImtleXMiLCJrZXkiLCJjb252ZXJ0UGl0Y2giLCJjb252ZXJ0RHVyYXRpb24iLCJyZXBsYWNlIiwiaXNEb3R0ZWQiLCJXcml0ZXIiLCJ0cmFja3MiLCJ0cmFja1R5cGUiLCJudW1iZXJPZlRyYWNrcyIsImJ1aWxkIiwiZCIsIlVpbnQ4QXJyYXkiLCJidG9hIiwiU3RyaW5nIiwiZnJvbUNoYXJDb2RlIiwiYXBwbHkiLCJidWlsZEZpbGUiLCJCdWZmZXIiLCJiYXNlNjQiLCJwcm9jZXNzIiwic3Rkb3V0Iiwid3JpdGUiLCJmaWxlbmFtZSIsImZzIiwid3JpdGVGaWxlIiwiZXJyIiwiY29uc29sZSIsImxvZyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFza0JBOzs7O0FBdGtCQTs7Ozs7SUFLTUEsSyxHQUNMLGVBQVlDLE1BQVosRUFBb0I7QUFBQTs7QUFDbkIsTUFBS0MsSUFBTCxHQUFZRCxPQUFPQyxJQUFuQjtBQUNBLE1BQUtDLElBQUwsR0FBWUYsT0FBT0UsSUFBbkI7QUFDQSxNQUFLQyxJQUFMLEdBQVksQ0FBQyxDQUFELEVBQUksQ0FBSixFQUFPLENBQVAsRUFBVUgsT0FBT0UsSUFBUCxDQUFZRSxNQUF0QixDQUFaO0FBQ0EsQzs7UUFHTUwsSyxHQUFBQSxLO0FBQ1I7Ozs7O0FBS0EsSUFBSU0sWUFBWTtBQUNmQyxVQUFjLE9BREM7QUFFZkMsb0JBQXVCLENBQUMsSUFBRCxFQUFPLElBQVAsRUFBYSxJQUFiLEVBQW1CLElBQW5CLENBRlIsRUFFa0M7QUFDakRDLHNCQUF3QixDQUFDLElBQUQsRUFBTyxJQUFQLEVBQWEsSUFBYixFQUFtQixJQUFuQixDQUhULEVBR21DO0FBQ2xEQyx1QkFBMEIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQUpYLEVBSXlCO0FBQ3hDQyx1QkFBMEIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQUxYLEVBS3lCO0FBQ3hDQyx3QkFBMEIsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQU5YLEVBTXlCO0FBQ3hDQyxtQkFBb0IsQ0FBQyxJQUFELEVBQU8sSUFBUCxFQUFh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QUFLQyxPQUFPQyxZQUFQLENBQW9CQyxLQUFwQixDQUEwQixJQUExQixFQUFnQyxLQUFLQyxTQUFMLEVBQWhDLENBQUwsQ0FBUDtBQUNoQyxVQUFPLElBQUlDLE1BQUosQ0FBVyxLQUFLRCxTQUFMLEVBQVgsRUFBNkJ0RixRQUE3QixDQUFzQyxRQUF0QyxDQUFQO0FBQ0E7O0FBRUU7Ozs7Ozs7NEJBSVU7QUFDVCxVQUFPLDRCQUE0QixLQUFLd0YsTUFBTCxFQUFuQztBQUNBOztBQUVKOzs7Ozs7OzJCQUlZO0FBQ1IsVUFBT0MsUUFBUUMsTUFBUixDQUFlQyxLQUFmLENBQXFCLElBQUlKLE1BQUosQ0FBVyxLQUFLRCxTQUFMLEVBQVgsQ0FBckIsQ0FBUDtBQUNBOztBQUVKOzs7Ozs7OzJCQUlTTSxRLEVBQVU7QUFDbEIsT0FBSTdDLFNBQVMsSUFBSXdDLE1BQUosQ0FBVyxLQUFLRCxTQUFMLEVBQVgsQ0FBYjtBQUNBTyxNQUFHQyxTQUFILENBQWFGLFdBQVcsTUFBeEIsRUFBZ0M3QyxNQUFoQyxFQUF3QyxVQUFVZ0QsR0FBVixFQUFlO0FBQ3RELFFBQUdBLEdBQUgsRUFBUSxPQUFPQyxRQUFRQyxHQUFSLENBQVlGLEdBQVosQ0FBUDtBQUNSLElBRkQ7QUFHQTs7Ozs7O1FBR01wQixNLEdBQUFBLE0iLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE9iamVjdCByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2h1bmsgc2VjdGlvbiBvZiBhIE1JREkgZmlsZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMgLSB7dHlwZTogbnVtYmVyLCBkYXRhOiBhcnJheSwgc2l6ZTogYXJyYXl9XG4gKiBAcmV0dXJuIHtDaHVua31cbiAqL1xuY2xhc3MgQ2h1bmsge1xuXHRjb25zdHJ1Y3RvcihmaWVsZHMpIHtcblx0XHR0aGlzLnR5cGUgPSBmaWVsZHMudHlwZTtcblx0XHR0aGlzLmRhdGEgPSBmaWVsZHMuZGF0YTtcblx0XHR0aGlzLnNpemUgPSBbMCwgMCwgMCwgZmllbGRzLmRhdGEubGVuZ3RoXTtcblx0fVxufVxuXG5leHBvcnQge0NodW5rfTtcbi8qKlxuICogTUlESSBmaWxlIGZvcm1hdCBjb25zdGFudHMsIGluY2x1ZGluZyBub3RlIC0+IE1JREkgbnVtYmVyIHRyYW5zbGF0aW9uLlxuICogQHJldHVybiB7Q29uc3RhbnRzfVxuICovXG5cbnZhciBDb25zdGFudHMgPSB7XG5cdFZFUlNJT05cdFx0XHRcdFx0OiAnMS41LjInLFxuXHRIRUFERVJfQ0hVTktfVFlQRSAgXHRcdDogWzB4NGQsIDB4NTQsIDB4NjgsIDB4NjRdLCAvLyBNdGhkXG5cdEhFQURFUl9DSFVOS19MRU5HVEggIFx0OiBbMHgwMCwgMHgwMCwgMHgwMCwgMHgwNl0sIC8vIEhlYWRlciBzaXplIGZvciBTTUZcblx0SEVBREVSX0NIVU5LX0ZPUk1BVDAgICAgOiBbMHgwMCwgMHgwMF0sIC8vIE1pZGkgVHlwZSAwIGlkXG5cdEhFQURFUl9DSFVOS19GT1JNQVQxICAgIDogWzB4MDAsIDB4MDFdLCAvLyBNaWRpIFR5cGUgMSBpZFxuXHRIRUFERVJfQ0hVTktfRElWSVNJT04gICA6IFsweDAwLCAweDgwXSwgLy8gRGVmYXVsdHMgdG8gMTI4IHRpY2tzIHBlciBiZWF0XG5cdFRSQUNLX0NIVU5LX1RZUEVcdFx0OiBbMHg0ZCwgMHg1NCwgMHg3MiwgMHg2Yl0sIC8vIE1UcmssXG5cdE1FVEFfRVZFTlRfSURcdFx0XHQ6IDB4RkYsXG5cdE1FVEFfVEVYVF9JRFx0XHRcdDogMHgwMSxcblx0TUVUQV9DT1BZUklHSFRfSURcdFx0OiAweDAyLFxuXHRNRVRBX1RSQUNLX05BTUVfSURcdFx0OiAweDAzLFxuXHRNRVRBX0lOU1RSVU1FTlRfTkFNRV9JRCA6IDB4MDQsXG5cdE1FVEFfTFlSSUNfSURcdFx0XHQ6IDB4MDUsXG5cdE1FVEFfTUFSS0VSX0lEXHRcdFx0OiAweDA2LFxuXHRNRVRBX0NVRV9QT0lOVFx0XHRcdDogMHgwNyxcblx0TUVUQV9URU1QT19JRFx0XHRcdDogMHg1MSxcblx0TUVUQV9TTVRQRV9PRkZTRVRcdFx0OiAweDU0LFxuXHRNRVRBX1RJTUVfU0lHTkFUVVJFX0lEXHQ6IDB4NTgsXG5cdE1FVEFfS0VZX1NJR05BVFVSRV9JRFx0OiAweDU5LFxuXHRNRVRBX0VORF9PRl9UUkFDS19JRFx0OiBbMHgyRiwgMHgwMF0sXG5cdENPTlRST0xMRVJfQ0hBTkdFX1NUQVRVUzogMHhCMCwgLy8gaW5jbHVkZXMgY2hhbm5lbCBudW1iZXIgKDApXG5cdFBST0dSQU1fQ0hBTkdFX1NUQVRVU1x0OiAweEMwLCAvLyBpbmNsdWRlcyBjaGFubmVsIG51bWJlciAoMClcbn07XG5cbmV4cG9ydCB7Q29uc3RhbnRzfTtcbi8qKlxuICogSG9sZHMgYWxsIGRhdGEgZm9yIGEgXCJjb250cm9sbGVyIGNoYW5nZVwiIE1JREkgZXZlbnRcbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMge2NvbnRyb2xsZXJOdW1iZXI6IGludGVnZXIsIGNvbnRyb2xsZXJWYWx1ZTogaW50ZWdlcn1cbiAqIEByZXR1cm4ge0NvbnRyb2xsZXJDaGFuZ2VFdmVudH1cbiAqL1xuY2xhc3MgQ29udHJvbGxlckNoYW5nZUV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy50eXBlID0gJ2NvbnRyb2xsZXInO1xuXHRcdC8vIGRlbHRhIHRpbWUgZGVmYXVsdHMgdG8gMC5cblx0XHR0aGlzLmRhdGEgPSBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKDB4MDApLmNvbmNhdChDb25zdGFudHMuQ09OVFJPTExFUl9DSEFOR0VfU1RBVFVTLCBmaWVsZHMuY29udHJvbGxlck51bWJlciwgZmllbGRzLmNvbnRyb2xsZXJWYWx1ZSk7XG5cdH1cbn1cblxuZXhwb3J0IHtDb250cm9sbGVyQ2hhbmdlRXZlbnR9O1xuLyoqXG4gKiBPYmplY3QgcmVwcmVzZW50YXRpb24gb2YgYSBtZXRhIGV2ZW50LlxuICogQHBhcmFtIHtvYmplY3R9IGZpZWxkcyAtIHR5cGUsIGRhdGFcbiAqIEByZXR1cm4ge01ldGFFdmVudH1cbiAqL1xuY2xhc3MgTWV0YUV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy50eXBlID0gJ21ldGEnO1xuXHRcdHRoaXMuZGF0YSA9IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoMHgwMCk7Ly8gU3RhcnQgd2l0aCB6ZXJvIHRpbWUgZGVsdGFcblx0XHR0aGlzLmRhdGEgPSB0aGlzLmRhdGEuY29uY2F0KENvbnN0YW50cy5NRVRBX0VWRU5UX0lELCBmaWVsZHMuZGF0YSk7XG5cdH1cbn1cblxuZXhwb3J0IHtNZXRhRXZlbnR9O1xuLyoqXG4gKiBXcmFwcGVyIGZvciBub3RlT25FdmVudC9ub3RlT2ZmRXZlbnQgb2JqZWN0cyB0aGF0IGJ1aWxkcyBib3RoIGV2ZW50cy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMgLSB7cGl0Y2g6ICdbQzRdJywgZHVyYXRpb246ICc0Jywgd2FpdDogJzQnLCB2ZWxvY2l0eTogMS0xMDB9XG4gKiBAcmV0dXJuIHtOb3RlRXZlbnR9XG4gKi9cbmNsYXNzIE5vdGVFdmVudCB7XG5cdGNvbnN0cnVjdG9yKGZpZWxkcykge1xuXHRcdHRoaXMudHlwZSBcdFx0PSAnbm90ZSc7XG5cdFx0dGhpcy5waXRjaCBcdFx0PSBVdGlscy50b0FycmF5KGZpZWxkcy5waXRjaCk7XG5cdFx0dGhpcy53YWl0IFx0XHQ9IGZpZWxkcy53YWl0IHx8IDA7XG5cdFx0dGhpcy5kdXJhdGlvbiBcdD0gZmllbGRzLmR1cmF0aW9uO1xuXHRcdHRoaXMuc2VxdWVudGlhbCA9IGZpZWxkcy5zZXF1ZW50aWFsIHx8IGZhbHNlO1xuXHRcdHRoaXMudmVsb2NpdHkgXHQ9IGZpZWxkcy52ZWxvY2l0eSB8fCA1MDtcblx0XHR0aGlzLmNoYW5uZWwgXHQ9IGZpZWxkcy5jaGFubmVsIHx8IDE7XG5cdFx0dGhpcy5yZXBlYXQgXHQ9IGZpZWxkcy5yZXBlYXQgfHwgMTtcblx0XHR0aGlzLnZlbG9jaXR5IFx0PSB0aGlzLmNvbnZlcnRWZWxvY2l0eSh0aGlzLnZlbG9jaXR5KTtcblx0XHR0aGlzLmdyYWNlXHRcdD0gZmllbGRzLmdyYWNlO1xuXHRcdHRoaXMuYnVpbGREYXRhKCk7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIGludCBhcnJheSBmb3IgdGhpcyBldmVudC5cblx0ICogQHJldHVybiB7Tm90ZUV2ZW50fVxuXHQgKi9cblx0YnVpbGREYXRhKCkge1xuXHRcdHRoaXMuZGF0YSA9IFtdO1xuXG5cdFx0dmFyIHRpY2tEdXJhdGlvbiA9IHRoaXMuZ2V0VGlja0R1cmF0aW9uKHRoaXMuZHVyYXRpb24sICdub3RlJyk7XG5cdFx0dmFyIHJlc3REdXJhdGlvbiA9IHRoaXMuZ2V0VGlja0R1cmF0aW9uKHRoaXMud2FpdCwgJ3Jlc3QnKTtcblxuXHRcdC8vIEFwcGx5IGdyYWNlIG5vdGUocykgYW5kIHN1YnRyYWN0IHRpY2tzIChjdXJyZW50bHkgMSB0aWNrIHBlciBncmFjZSBub3RlKSBmcm9tIHRpY2tEdXJhdGlvbiBzbyBuZXQgdmFsdWUgaXMgdGhlIHNhbWVcblx0XHRpZiAodGhpcy5ncmFjZSkge1xuXHRcdFx0bGV0IGdyYWNlRHVyYXRpb24gPSAxO1xuXHRcdFx0dGhpcy5ncmFjZSA9IFV0aWxzLnRvQXJyYXkodGhpcy5ncmFjZSk7XG5cdFx0XHR0aGlzLmdyYWNlLmZvckVhY2goZnVuY3Rpb24ocGl0Y2gpIHtcblx0XHRcdFx0bGV0IG5vdGVFdmVudCA9IG5ldyBOb3RlRXZlbnQoe3BpdGNoOnRoaXMuZ3JhY2UsIGR1cmF0aW9uOidUJyArIGdyYWNlRHVyYXRpb259KTtcblx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChub3RlRXZlbnQuZGF0YSlcblxuXHRcdFx0XHR0aWNrRHVyYXRpb24gLT0gZ3JhY2VEdXJhdGlvbjtcblx0XHRcdH0sIHRoaXMpO1xuXHRcdH1cblxuXHRcdC8vIGZpZWxkcy5waXRjaCBjb3VsZCBiZSBhbiBhcnJheSBvZiBwaXRjaGVzLlxuXHRcdC8vIElmIHNvIGNyZWF0ZSBub3RlIGV2ZW50cyBmb3IgZWFjaCBhbmQgYXBwbHkgdGhlIHNhbWUgZHVyYXRpb24uXG5cdFx0dmFyIG5vdGVPbiwgbm90ZU9mZjtcblx0XHRpZiAoQXJyYXkuaXNBcnJheSh0aGlzLnBpdGNoKSkge1xuXHRcdFx0Ly8gQnkgZGVmYXVsdCB0aGlzIGlzIGEgY2hvcmQgaWYgaXQncyBhbiBhcnJheSBvZiBub3RlcyB0aGF0IHJlcXVpcmVzIG9uZSBOb3RlT25FdmVudC5cblx0XHRcdC8vIElmIHRoaXMuc2VxdWVudGlhbCA9PT0gdHJ1ZSB0aGVuIGl0J3MgYSBzZXF1ZW50aWFsIHN0cmluZyBvZiBub3RlcyB0aGF0IHJlcXVpcmVzIHNlcGFyYXRlIE5vdGVPbkV2ZW50cy5cblx0XHRcdGlmICggISB0aGlzLnNlcXVlbnRpYWwpIHtcblx0XHRcdFx0Ly8gSGFuZGxlIHJlcGVhdFxuXHRcdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMucmVwZWF0OyBqKyspIHtcblx0XHRcdFx0XHQvLyBOb3RlIG9uXG5cdFx0XHRcdFx0dGhpcy5waXRjaC5mb3JFYWNoKGZ1bmN0aW9uKHAsIGkpIHtcblx0XHRcdFx0XHRcdGlmIChpID09IDApIHtcblx0XHRcdFx0XHRcdFx0bm90ZU9uID0gbmV3IE5vdGVPbkV2ZW50KHtkYXRhOiBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKHJlc3REdXJhdGlvbikuY29uY2F0KHRoaXMuZ2V0Tm90ZU9uU3RhdHVzKCksIFV0aWxzLmdldFBpdGNoKHApLCB0aGlzLnZlbG9jaXR5KX0pO1xuXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHQvLyBSdW5uaW5nIHN0YXR1cyAoY2FuIG9tbWl0IHRoZSBub3RlIG9uIHN0YXR1cylcblx0XHRcdFx0XHRcdFx0bm90ZU9uID0gbmV3IE5vdGVPbkV2ZW50KHtkYXRhOiBbMCwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHldfSk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQobm90ZU9uLmRhdGEpO1xuXHRcdFx0XHRcdH0sIHRoaXMpO1xuXG5cdFx0XHRcdFx0Ly8gTm90ZSBvZmZcblx0XHRcdFx0XHR0aGlzLnBpdGNoLmZvckVhY2goZnVuY3Rpb24ocCwgaSkge1xuXHRcdFx0XHRcdFx0aWYgKGkgPT0gMCkge1xuXHRcdFx0XHRcdFx0XHRub3RlT2ZmID0gbmV3IE5vdGVPZmZFdmVudCh7ZGF0YTogVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aCh0aWNrRHVyYXRpb24pLmNvbmNhdCh0aGlzLmdldE5vdGVPZmZTdGF0dXMoKSwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHkpfSk7XG5cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdC8vIFJ1bm5pbmcgc3RhdHVzIChjYW4gb21taXQgdGhlIG5vdGUgb2ZmIHN0YXR1cylcblx0XHRcdFx0XHRcdFx0bm90ZU9mZiA9IG5ldyBOb3RlT2ZmRXZlbnQoe2RhdGE6IFswLCBVdGlscy5nZXRQaXRjaChwKSwgdGhpcy52ZWxvY2l0eV19KTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChub3RlT2ZmLmRhdGEpO1xuXHRcdFx0XHRcdH0sIHRoaXMpO1xuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIEhhbmRsZSByZXBlYXRcblx0XHRcdFx0Zm9yICh2YXIgaiA9IDA7IGogPCB0aGlzLnJlcGVhdDsgaisrKSB7XG5cdFx0XHRcdFx0dGhpcy5waXRjaC5mb3JFYWNoKGZ1bmN0aW9uKHAsIGkpIHtcblx0XHRcdFx0XHRcdC8vIHJlc3REdXJhdGlvbiBvbmx5IGFwcGxpZXMgdG8gZmlyc3Qgbm90ZVxuXHRcdFx0XHRcdFx0aWYgKGkgPiAwKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3REdXJhdGlvbiA9IDA7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIElmIGR1cmF0aW9uIGlzIDh0aCB0cmlwbGV0cyB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSB0b3RhbCB0aWNrcyA9PSBxdWFydGVyIG5vdGUuXG5cdFx0XHRcdFx0XHQvLyBTbywgdGhlIGxhc3Qgb25lIHdpbGwgbmVlZCB0byBiZSB0aGUgcmVtYWluZGVyXG5cdFx0XHRcdFx0XHRpZiAodGhpcy5kdXJhdGlvbiA9PT0gJzh0JyAmJiBpID09IHRoaXMucGl0Y2gubGVuZ3RoIC0gMSkge1xuXHRcdFx0XHRcdFx0XHRsZXQgcXVhcnRlclRpY2tzID0gVXRpbHMubnVtYmVyRnJvbUJ5dGVzKENvbnN0YW50cy5IRUFERVJfQ0hVTktfRElWSVNJT04pO1xuXHRcdFx0XHRcdFx0XHR0aWNrRHVyYXRpb24gPSBxdWFydGVyVGlja3MgLSAodGlja0R1cmF0aW9uICogMik7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdG5vdGVPbiA9IG5ldyBOb3RlT25FdmVudCh7ZGF0YTogVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChyZXN0RHVyYXRpb24pLmNvbmNhdChbdGhpcy5nZXROb3RlT25TdGF0dXMoKSwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHldKX0pO1xuXHRcdFx0XHRcdFx0bm90ZU9mZiA9IG5ldyBOb3RlT2ZmRXZlbnQoe2RhdGE6IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgodGlja0R1cmF0aW9uKS5jb25jYXQoW3RoaXMuZ2V0Tm90ZU9mZlN0YXR1cygpLCBVdGlscy5nZXRQaXRjaChwKSwgdGhpcy52ZWxvY2l0eV0pfSk7XG5cblx0XHRcdFx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQobm90ZU9uLmRhdGEsIG5vdGVPZmYuZGF0YSk7XG5cdFx0XHRcdFx0fSwgdGhpcyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0dGhyb3cgJ3BpdGNoIG11c3QgYmUgYW4gYXJyYXkuJztcblx0fTtcblxuXHQvKipcblx0ICogQ29udmVydHMgdmVsb2NpdHkgdG8gdmFsdWUgMC0xMjdcblx0ICogQHBhcmFtIHtudW1iZXJ9IHZlbG9jaXR5IC0gVmVsb2NpdHkgdmFsdWUgMS0xMDBcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cblx0Y29udmVydFZlbG9jaXR5KHZlbG9jaXR5KSB7XG5cdFx0Ly8gTWF4IHBhc3NlZCB2YWx1ZSBsaW1pdGVkIHRvIDEwMFxuXHRcdHZlbG9jaXR5ID0gdmVsb2NpdHkgPiAxMDAgPyAxMDAgOiB2ZWxvY2l0eTtcblx0XHRyZXR1cm4gTWF0aC5yb3VuZCh2ZWxvY2l0eSAvIDEwMCAqIDEyNyk7XG5cdH07XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHRvdGFsIG51bWJlciBvZiB0aWNrcyBiYXNlZCBvbiBwYXNzZWQgZHVyYXRpb24uXG5cdCAqIE5vdGU6IHR5cGU9PSdub3RlJyBkZWZhdWx0cyB0byBxdWFydGVyIG5vdGUsIHR5cGU9PT0ncmVzdCcgZGVmYXVsdHMgdG8gMFxuXHQgKiBAcGFyYW0geyhzdHJpbmd8YXJyYXkpfSBkdXJhdGlvblxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBbJ25vdGUnLCAncmVzdCddXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdGdldFRpY2tEdXJhdGlvbihkdXJhdGlvbiwgdHlwZSkge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KGR1cmF0aW9uKSkge1xuXHRcdFx0Ly8gUmVjdXJzaXZlbHkgZXhlY3V0ZSB0aGlzIG1ldGhvZCBmb3IgZWFjaCBpdGVtIGluIHRoZSBhcnJheSBhbmQgcmV0dXJuIHRoZSBzdW0gb2YgdGljayBkdXJhdGlvbnMuXG5cdFx0XHRyZXR1cm4gZHVyYXRpb24ubWFwKGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLmdldFRpY2tEdXJhdGlvbih2YWx1ZSwgdHlwZSk7XG5cdFx0XHR9LCB0aGlzKS5yZWR1Y2UoZnVuY3Rpb24oYSwgYikge1xuXHRcdFx0XHRyZXR1cm4gYSArIGI7XG5cdFx0XHR9LCAwKTtcblx0XHR9XG5cblx0XHRkdXJhdGlvbiA9IGR1cmF0aW9uLnRvU3RyaW5nKCk7XG5cblx0XHRpZiAoZHVyYXRpb24udG9Mb3dlckNhc2UoKS5jaGFyQXQoMCkgPT09ICd0Jykge1xuXHRcdFx0Ly8gSWYgZHVyYXRpb24gc3RhcnRzIHdpdGggJ3QnIHRoZW4gdGhlIG51bWJlciB0aGF0IGZvbGxvd3MgaXMgYW4gZXhwbGljaXQgdGljayBjb3VudFxuXHRcdFx0cmV0dXJuIHBhcnNlSW50KGR1cmF0aW9uLnN1YnN0cmluZygxKSk7XG5cdFx0fVxuXG5cdFx0Ly8gTmVlZCB0byBhcHBseSBkdXJhdGlvbiBoZXJlLiAgUXVhcnRlciBub3RlID09IENvbnN0YW50cy5IRUFERVJfQ0hVTktfRElWSVNJT05cblx0XHQvLyBSb3VuZGluZyBvbmx5IGFwcGxpZXMgdG8gdHJpcGxldHMsIHdoaWNoIHRoZSByZW1haW5kZXIgaXMgaGFuZGxlZCBiZWxvd1xuXHRcdHZhciBxdWFydGVyVGlja3MgPSBVdGlscy5udW1iZXJGcm9tQnl0ZXMoQ29uc3RhbnRzLkhFQURFUl9DSFVOS19ESVZJU0lPTik7XG5cdFx0cmV0dXJuIE1hdGgucm91bmQocXVhcnRlclRpY2tzICogdGhpcy5nZXREdXJhdGlvbk11bHRpcGxpZXIoZHVyYXRpb24sIHR5cGUpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHdoYXQgdG8gbXVsdGlwbGUgdGlja3MvcXVhcnRlciBub3RlIGJ5IHRvIGdldCB0aGUgc3BlY2lmaWVkIGR1cmF0aW9uLlxuXHQgKiBOb3RlOiB0eXBlPT0nbm90ZScgZGVmYXVsdHMgdG8gcXVhcnRlciBub3RlLCB0eXBlPT09J3Jlc3QnIGRlZmF1bHRzIHRvIDBcblx0ICogQHBhcmFtIHtzdHJpbmd9IGR1cmF0aW9uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFsnbm90ZScsJ3Jlc3QnXVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXREdXJhdGlvbk11bHRpcGxpZXIoZHVyYXRpb24sIHR5cGUpIHtcblx0XHQvLyBOZWVkIHRvIGFwcGx5IGR1cmF0aW9uIGhlcmUuICBRdWFydGVyIG5vdGUgPT0gQ29uc3RhbnRzLkhFQURFUl9DSFVOS19ESVZJU0lPTlxuXHRcdHN3aXRjaCAoZHVyYXRpb24pIHtcblx0XHRcdGNhc2UgJzAnOlxuXHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdGNhc2UgJzEnOlxuXHRcdFx0XHRyZXR1cm4gNDtcblx0XHRcdGNhc2UgJzInOlxuXHRcdFx0XHRyZXR1cm4gMjtcblx0XHRcdGNhc2UgJ2QyJzpcblx0XHRcdFx0cmV0dXJuIDM7XG5cdFx0XHRjYXNlICc0Jzpcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHRjYXNlICc0dCc6XG5cdFx0XHRcdHJldHVybiAwLjY2Njtcblx0XHRcdGNhc2UgJ2Q0Jzpcblx0XHRcdFx0cmV0dXJuIDEuNTtcblx0XHRcdGNhc2UgJzgnOlxuXHRcdFx0XHRyZXR1cm4gMC41O1xuXHRcdFx0Y2FzZSAnOHQnOlxuXHRcdFx0XHQvLyBGb3IgOHRoIHRyaXBsZXRzLCBsZXQncyBkaXZpZGUgYSBxdWFydGVyIGJ5IDMsIHJvdW5kIHRvIHRoZSBuZWFyZXN0IGludCwgYW5kIHN1YnN0cmFjdCB0aGUgcmVtYWluZGVyIHRvIHRoZSBsYXN0IG9uZS5cblx0XHRcdFx0cmV0dXJuIDAuMzM7XG5cdFx0XHRjYXNlICdkOCc6XG5cdFx0XHRcdHJldHVybiAwLjc1O1xuXHRcdFx0Y2FzZSAnMTYnOlxuXHRcdFx0XHRyZXR1cm4gMC4yNTtcblx0XHRcdGNhc2UgJzE2dCc6XG5cdFx0XHRcdHJldHVybiAwLjE2Njtcblx0XHRcdGNhc2UgJzMyJzpcblx0XHRcdFx0cmV0dXJuIDAuMTI1O1xuXHRcdFx0Y2FzZSAnNjQnOlxuXHRcdFx0XHRyZXR1cm4gMC4wNjI1O1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0Ly8gTm90ZXMgZGVmYXVsdCB0byBhIHF1YXJ0ZXIsIHJlc3RzIGRlZmF1bHQgdG8gMFxuXHRcdFx0XHQvL3JldHVybiB0eXBlID09PSAnbm90ZScgPyAxIDogMDtcblx0XHR9XG5cblx0XHR0aHJvdyBkdXJhdGlvbiArICcgaXMgbm90IGEgdmFsaWQgZHVyYXRpb24uJztcblx0fTtcblxuXHQvKipcblx0ICogR2V0cyB0aGUgbm90ZSBvbiBzdGF0dXMgY29kZSBiYXNlZCBvbiB0aGUgc2VsZWN0ZWQgY2hhbm5lbC4gMHg5ezAtRn1cblx0ICogTm90ZSBvbiBhdCBjaGFubmVsIDAgaXMgMHg5MCAoMTQ0KVxuXHQgKiAwID0gQ2ggMVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXROb3RlT25TdGF0dXMoKSB7cmV0dXJuIDE0NCArIHRoaXMuY2hhbm5lbCAtIDF9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIG5vdGUgb2ZmIHN0YXR1cyBjb2RlIGJhc2VkIG9uIHRoZSBzZWxlY3RlZCBjaGFubmVsLiAweDh7MC1GfVxuXHQgKiBOb3RlIG9mZiBhdCBjaGFubmVsIDAgaXMgMHg4MCAoMTI4KVxuXHQgKiAwID0gQ2ggMVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXROb3RlT2ZmU3RhdHVzKCkge3JldHVybiAxMjggKyB0aGlzLmNoYW5uZWwgLSAxfVxufVxuXG5leHBvcnQge05vdGVFdmVudH07XG4vKipcbiAqIEhvbGRzIGFsbCBkYXRhIGZvciBhIFwibm90ZSBvZmZcIiBNSURJIGV2ZW50XG4gKiBAcGFyYW0ge29iamVjdH0gZmllbGRzIHtkYXRhOiBbXX1cbiAqIEByZXR1cm4ge05vdGVPZmZFdmVudH1cbiAqL1xuY2xhc3MgTm90ZU9mZkV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy5kYXRhID0gZmllbGRzLmRhdGE7XG5cdH1cbn1cblxuZXhwb3J0IHtOb3RlT2ZmRXZlbnR9O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSBcIm5vdGUgb25cIiBNSURJIGV2ZW50XG4gKiBAcGFyYW0ge29iamVjdH0gZmllbGRzIHtkYXRhOiBbXX1cbiAqIEByZXR1cm4ge05vdGVPbkV2ZW50fVxuICovXG5jbGFzcyBOb3RlT25FdmVudCB7XG5cdGNvbnN0cnVjdG9yKGZpZWxkcykge1xuXHRcdHRoaXMuZGF0YSA9IGZpZWxkcy5kYXRhO1xuXHR9XG59XG5cbmV4cG9ydCB7Tm90ZU9uRXZlbnR9O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSBcInByb2dyYW0gY2hhbmdlXCIgTUlESSBldmVudFxuICogQHBhcmFtIHtvYmplY3R9IGZpZWxkcyB7aW5zdHJ1bWVudDogaW50ZWdlcn1cbiAqIEByZXR1cm4ge1Byb2dyYW1DaGFuZ2VFdmVudH1cbiAqL1xuY2xhc3MgUHJvZ3JhbUNoYW5nZUV2ZW50IHtcblx0Y29uc3RydWN0b3IoZmllbGRzKSB7XG5cdFx0dGhpcy50eXBlID0gJ3Byb2dyYW0nO1xuXHRcdC8vIGRlbHRhIHRpbWUgZGVmYXVsdHMgdG8gMC5cblx0XHR0aGlzLmRhdGEgPSBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKDB4MDApLmNvbmNhdChDb25zdGFudHMuUFJPR1JBTV9DSEFOR0VfU1RBVFVTLCBmaWVsZHMuaW5zdHJ1bWVudCk7XG5cdH1cbn1cblxuZXhwb3J0IHtQcm9ncmFtQ2hhbmdlRXZlbnR9O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSB0cmFjay5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMge3R5cGU6IG51bWJlciwgZGF0YTogYXJyYXksIHNpemU6IGFycmF5LCBldmVudHM6IGFycmF5fVxuICogQHJldHVybiB7VHJhY2t9XG4gKi9cbmNsYXNzIFRyYWNrIHtcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0dGhpcy50eXBlID0gQ29uc3RhbnRzLlRSQUNLX0NIVU5LX1RZUEU7XG5cdFx0dGhpcy5kYXRhID0gW107XG5cdFx0dGhpcy5zaXplID0gW107XG5cdFx0dGhpcy5ldmVudHMgPSBbXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGFueSBldmVudCB0eXBlIHRvIHRoZSB0cmFjay5cblx0ICogQHBhcmFtIHsoTm90ZUV2ZW50fE1ldGFFdmVudHxQcm9ncmFtQ2hhbmdlRXZlbnQpfSBldmVudCAtIEV2ZW50IG9iamVjdC5cblx0ICogQHBhcmFtIHtmdW5jdGlvbn0gbWFwRnVuY3Rpb24gLSBDYWxsYmFjayB3aGljaCBjYW4gYmUgdXNlZCB0byBhcHBseSBzcGVjaWZpYyBwcm9wZXJ0aWVzIHRvIGFsbCBldmVudHMuIFxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZEV2ZW50KGV2ZW50LCBtYXBGdW5jdGlvbikge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KGV2ZW50KSkge1xuXHRcdFx0ZXZlbnQuZm9yRWFjaChmdW5jdGlvbihlLCBpKSB7XG5cdFx0XHRcdC8vIEhhbmRsZSBtYXAgZnVuY3Rpb24gaWYgcHJvdmlkZWRcblx0XHRcdFx0aWYgKHR5cGVvZiBtYXBGdW5jdGlvbiA9PT0gJ2Z1bmN0aW9uJyAmJiBlLnR5cGUgPT09ICdub3RlJykge1xuXHRcdFx0XHRcdHZhciBwcm9wZXJ0aWVzID0gbWFwRnVuY3Rpb24oaSwgZSk7XG5cblx0XHRcdFx0XHRpZiAodHlwZW9mIHByb3BlcnRpZXMgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdFx0XHRmb3IgKHZhciBqIGluIHByb3BlcnRpZXMpIHtcblx0XHRcdFx0XHRcdFx0c3dpdGNoKGopIHtcblx0XHRcdFx0XHRcdFx0XHRjYXNlICdkdXJhdGlvbic6XG5cdFx0XHRcdFx0XHRcdFx0XHRlLmR1cmF0aW9uID0gcHJvcGVydGllc1tqXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdGNhc2UgJ3NlcXVlbnRpYWwnOlxuXHRcdFx0XHRcdFx0XHRcdFx0ZS5zZXF1ZW50aWFsID0gcHJvcGVydGllc1tqXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdGNhc2UgJ3ZlbG9jaXR5Jzpcblx0XHRcdFx0XHRcdFx0XHRcdGUudmVsb2NpdHkgPSBlLmNvbnZlcnRWZWxvY2l0eShwcm9wZXJ0aWVzW2pdKTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XHRcdFxuXG5cdFx0XHRcdFx0XHQvLyBHb3R0YSBidWlsZCB0aGF0IGRhdGFcblx0XHRcdFx0XHRcdGUuYnVpbGREYXRhKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChlLmRhdGEpO1xuXHRcdFx0XHR0aGlzLnNpemUgPSBVdGlscy5udW1iZXJUb0J5dGVzKHRoaXMuZGF0YS5sZW5ndGgsIDQpOyAvLyA0IGJ5dGVzIGxvbmdcblx0XHRcdFx0dGhpcy5ldmVudHMucHVzaChlKTtcblx0XHRcdH0sIHRoaXMpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQoZXZlbnQuZGF0YSk7XG5cdFx0XHR0aGlzLnNpemUgPSBVdGlscy5udW1iZXJUb0J5dGVzKHRoaXMuZGF0YS5sZW5ndGgsIDQpOyAvLyA0IGJ5dGVzIGxvbmdcblx0XHRcdHRoaXMuZXZlbnRzLnB1c2goZXZlbnQpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGVtcG8gb2YgdGhlIE1JREkgZmlsZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGJwbSAtIFRlbXBvIGluIGJlYXRzIHBlciBtaW51dGUuXG5cdCAqIEByZXR1cm4ge1RyYWNrfVxuXHQgKi9cblx0c2V0VGVtcG8oYnBtKSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX1RFTVBPX0lEXX0pO1xuXHRcdGV2ZW50LmRhdGEucHVzaCgweDAzKTsgLy8gU2l6ZVxuXHRcdHZhciB0ZW1wbyA9IE1hdGgucm91bmQoNjAwMDAwMDAgLyBicG0pO1xuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKHRlbXBvLCAzKSk7IC8vIFRlbXBvLCAzIGJ5dGVzXG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGltZSBzaWduYXR1cmUuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBudW1lcmF0b3IgLSBUb3AgbnVtYmVyIG9mIHRoZSB0aW1lIHNpZ25hdHVyZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGRlbm9taW5hdG9yIC0gQm90dG9tIG51bWJlciBvZiB0aGUgdGltZSBzaWduYXR1cmUuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBtaWRpY2xvY2tzcGVydGljayAtIERlZmF1bHRzIHRvIDI0LlxuXHQgKiBAcGFyYW0ge251bWJlcn0gbm90ZXNwZXJtaWRpY2xvY2sgLSBEZWZhdWx0cyB0byA4LlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdHNldFRpbWVTaWduYXR1cmUobnVtZXJhdG9yLCBkZW5vbWluYXRvciwgbWlkaWNsb2Nrc3BlcnRpY2ssIG5vdGVzcGVybWlkaWNsb2NrKSB7XG5cdFx0bWlkaWNsb2Nrc3BlcnRpY2sgPSBtaWRpY2xvY2tzcGVydGljayB8fCAyNDtcblx0XHRub3Rlc3Blcm1pZGljbG9jayA9IG5vdGVzcGVybWlkaWNsb2NrIHx8IDg7XG5cdFx0XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX1RJTUVfU0lHTkFUVVJFX0lEXX0pO1xuXHRcdGV2ZW50LmRhdGEucHVzaCgweDA0KTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG51bWVyYXRvciwgMSkpOyAvLyBOdW1lcmF0b3IsIDEgYnl0ZXNcblx0XHRcblx0XHR2YXIgX2Rlbm9taW5hdG9yID0gTWF0aC5sb2cyKGRlbm9taW5hdG9yKTtcdC8vIERlbm9taW5hdG9yIGlzIGV4cHJlc3NlZCBhcyBwb3cgb2YgMlxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKF9kZW5vbWluYXRvciwgMSkpOyAvLyBEZW5vbWluYXRvciwgMSBieXRlc1xuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG1pZGljbG9ja3NwZXJ0aWNrLCAxKSk7IC8vIE1JREkgQ2xvY2tzIHBlciB0aWNrLCAxIGJ5dGVzXG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvQnl0ZXMobm90ZXNwZXJtaWRpY2xvY2ssIDEpKTsgLy8gTnVtYmVyIG9mIDEvMzIgbm90ZXMgcGVyIE1JREkgY2xvY2tzLCAxIGJ5dGVzXG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMga2V5IHNpZ25hdHVyZS5cblx0ICogQHBhcmFtIHsqfSBzZiAtIFxuXHQgKiBAcGFyYW0geyp9IG1pIC1cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRzZXRLZXlTaWduYXR1cmUoc2YsIG1pKSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX0tFWV9TSUdOQVRVUkVfSURdfSk7XG5cdFx0ZXZlbnQuZGF0YS5wdXNoKDB4MDIpOyAvLyBTaXplXG5cblx0XHR2YXIgbW9kZSA9IG1pIHx8IDA7XG5cdFx0c2YgPSBzZiB8fCAwO1xuXG5cdFx0Ly9cdEZ1bmN0aW9uIGNhbGxlZCB3aXRoIHN0cmluZyBub3RhdGlvblxuXHRcdGlmICh0eXBlb2YgbWkgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHR2YXIgZmlmdGhzID0gW1xuXHRcdFx0XHRbJ0NiJywgJ0diJywgJ0RiJywgJ0FiJywgJ0ViJywgJ0JiJywgJ0YnLCAnQycsICdHJywgJ0QnLCAnQScsICdFJywgJ0InLCAnRiMnLCAnQyMnXSxcblx0XHRcdFx0WydhYicsICdlYicsICdiYicsICdmJywgJ2MnLCAnZycsICdkJywgJ2EnLCAnZScsICdiJywgJ2YjJywgJ2MjJywgJ2cjJywgJ2QjJywgJ2EjJ11cblx0XHRcdF07XG5cdFx0XHR2YXIgX3NmbGVuID0gc2YubGVuZ3RoO1xuXHRcdFx0dmFyIG5vdGUgPSBzZiB8fCAnQyc7XG5cblx0XHRcdGlmIChzZlswXSA9PT0gc2ZbMF0udG9Mb3dlckNhc2UoKSkgbW9kZSA9IDFcblxuXHRcdFx0aWYgKF9zZmxlbiA+IDEpIHtcblx0XHRcdFx0c3dpdGNoIChzZi5jaGFyQXQoX3NmbGVuIC0gMSkpIHtcblx0XHRcdFx0XHRjYXNlICdtJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAxO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICctJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAxO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdNJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAwO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICcrJzpcblx0XHRcdFx0XHRcdG1vZGUgPSAwO1xuXHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgZmlmdGhpbmRleCA9IGZpZnRoc1ttb2RlXS5pbmRleE9mKG5vdGUpO1xuXHRcdFx0c2YgPSBmaWZ0aGluZGV4ID09PSAtMSA/IDAgOiBmaWZ0aGluZGV4IC0gNztcblx0XHR9XG5cblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9CeXRlcyhzZiwgMSkpOyAvLyBOdW1iZXIgb2Ygc2hhcnAgb3IgZmxhdHMgKCA8IDAgZmxhdDsgPiAwIHNoYXJwKVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG1vZGUsIDEpKTsgLy8gTW9kZTogMCBtYWpvciwgMSBtaW5vclxuXHRcdHJldHVybiB0aGlzLmFkZEV2ZW50KGV2ZW50KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIHRleHQgdG8gTUlESSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRleHQgdG8gYWRkLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZFRleHQodGV4dCkge1xuXHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoe2RhdGE6IFtDb25zdGFudHMuTUVUQV9URVhUX0lEXX0pO1xuXHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgY29weXJpZ2h0IHRvIE1JREkgZmlsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUZXh0IG9mIGNvcHlyaWdodCBsaW5lLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZENvcHlyaWdodCh0ZXh0KSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX0NPUFlSSUdIVF9JRF19KTtcblx0XHR2YXIgc3RyaW5nQnl0ZXMgPSBVdGlscy5zdHJpbmdUb0J5dGVzKHRleHQpO1xuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKHN0cmluZ0J5dGVzLmxlbmd0aCkpOyAvLyBTaXplXG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KHN0cmluZ0J5dGVzKTsgLy8gVGV4dFxuXHRcdHJldHVybiB0aGlzLmFkZEV2ZW50KGV2ZW50KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIFNlcXVlbmNlL1RyYWNrIE5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGV4dCBvZiB0cmFjayBuYW1lLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZFRyYWNrTmFtZSh0ZXh0KSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7ZGF0YTogW0NvbnN0YW50cy5NRVRBX1RSQUNLX05BTUVfSURdfSk7XG5cdFx0dmFyIHN0cmluZ0J5dGVzID0gVXRpbHMuc3RyaW5nVG9CeXRlcyh0ZXh0KTtcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIFRleHRcblx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBpbnN0cnVtZW50IG5hbWUgb2YgdHJhY2suXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gTmFtZSBvZiBpbnN0cnVtZW50LlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZEluc3RydW1lbnROYW1lKHRleHQpIHtcblx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHtkYXRhOiBbQ29uc3RhbnRzLk1FVEFfSU5TVFJVTUVOVF9OQU1FX0lEXX0pO1xuXHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgbWFya2VyIHRvIE1JREkgZmlsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBNYXJrZXIgdGV4dC5cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRhZGRNYXJrZXIodGV4dCkge1xuXHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoe2RhdGE6IFtDb25zdGFudHMuTUVUQV9NQVJLRVJfSURdfSk7XG5cdFx0dmFyIHN0cmluZ0J5dGVzID0gVXRpbHMuc3RyaW5nVG9CeXRlcyh0ZXh0KTtcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIFRleHRcblx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBjdWUgcG9pbnQgdG8gTUlESSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRleHQgb2YgY3VlIHBvaW50LlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGFkZEN1ZVBvaW50KHRleHQpIHtcblx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHtkYXRhOiBbQ29uc3RhbnRzLk1FVEFfQ1VFX1BPSU5UXX0pO1xuXHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgbHlyaWMgdG8gTUlESSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbHlyaWMgLSBMeXJpYyB0ZXh0IHRvIGFkZC5cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRhZGRMeXJpYyhseXJpYykge1xuXHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoe2RhdGE6IFtDb25zdGFudHMuTUVUQV9MWVJJQ19JRF19KTtcblx0XHR2YXIgc3RyaW5nQnl0ZXMgPSBVdGlscy5zdHJpbmdUb0J5dGVzKGx5cmljKTtcblx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIEx5cmljXG5cdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoYW5uZWwgbW9kZSBtZXNzYWdlc1xuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdHBvbHlNb2RlT24oKSB7XG5cdFx0dmFyIGV2ZW50ID0gbmV3IE5vdGVPbkV2ZW50KHtkYXRhOiBbMHgwMCwgMHhCMCwgMHg3RSwgMHgwMF19KTtcblx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdH1cblxufVxuXG5leHBvcnQge1RyYWNrfTtcbmltcG9ydCB7dG9NaWRpfSBmcm9tICd0b25hbC1taWRpJztcblxuLyoqXG4gKiBTdGF0aWMgdXRpbGl0eSBmdW5jdGlvbnMgdXNlZCB0aHJvdWdob3V0IHRoZSBsaWJyYXJ5LlxuICovXG5jbGFzcyBVdGlscyB7XG5cblx0LyoqXG5cdCAqIEdldHMgTWlkaVdyaXRlckpTIHZlcnNpb24gbnVtYmVyLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRzdGF0aWMgdmVyc2lvbigpIHtcblx0XHRyZXR1cm4gQ29uc3RhbnRzLlZFUlNJT047XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydCBhIHN0cmluZyB0byBhbiBhcnJheSBvZiBieXRlc1xuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG5cdCAqIEByZXR1cm4ge2FycmF5fVxuXHQgKi9cblx0c3RhdGljIHN0cmluZ1RvQnl0ZXMoc3RyaW5nKSB7XG5cdFx0cmV0dXJuIHN0cmluZy5zcGxpdCgnJykubWFwKGNoYXIgPT4gY2hhci5jaGFyQ29kZUF0KCkpXG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIGFyZ3VtZW50IGlzIGEgdmFsaWQgbnVtYmVyLlxuXHQgKiBAcGFyYW0geyp9IG4gLSBWYWx1ZSB0byBjaGVja1xuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0c3RhdGljIGlzTnVtZXJpYyhuKSB7XG5cdFx0cmV0dXJuICFpc05hTihwYXJzZUZsb2F0KG4pKSAmJiBpc0Zpbml0ZShuKVxuXHR9XG5cblx0LyoqXG4gICAgICogUmV0dXJucyB0aGUgY29ycmVjdCBNSURJIG51bWJlciBmb3IgdGhlIHNwZWNpZmllZCBwaXRjaC5cbiAgICAgKiBVc2VzIFRvbmFsIE1pZGkgLSBodHRwczovL2dpdGh1Yi5jb20vZGFuaWdiL3RvbmFsL3RyZWUvbWFzdGVyL3BhY2thZ2VzL21pZGlcbiAgICAgKiBAcGFyYW0geyhzdHJpbmd8bnVtYmVyKX0gcGl0Y2ggLSAnQyM0JyBvciBtaWRpIG5vdGUgY29kZVxuICAgICAqIEByZXR1cm4ge251bWJlcn1cbiAgICAgKi9cbiAgICAgc3RhdGljIGdldFBpdGNoKHBpdGNoKSB7XG4gICAgIFx0cmV0dXJuIHRvTWlkaShwaXRjaCk7XG4gICAgIH1cblxuXHQvKipcblx0ICogVHJhbnNsYXRlcyBudW1iZXIgb2YgdGlja3MgdG8gTUlESSB0aW1lc3RhbXAgZm9ybWF0LCByZXR1cm5pbmcgYW4gYXJyYXkgb2Zcblx0ICogaGV4IHN0cmluZ3Mgd2l0aCB0aGUgdGltZSB2YWx1ZXMuIE1pZGkgaGFzIGEgdmVyeSBwYXJ0aWN1bGFyIHRpbWUgdG8gZXhwcmVzcyB0aW1lLFxuXHQgKiB0YWtlIGEgZ29vZCBsb29rIGF0IHRoZSBzcGVjIGJlZm9yZSBldmVyIHRvdWNoaW5nIHRoaXMgZnVuY3Rpb24uXG5cdCAqIFRoYW5rcyB0byBodHRwczovL2dpdGh1Yi5jb20vc2VyZ2kvanNtaWRpXG5cdCAqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB0aWNrcyAtIE51bWJlciBvZiB0aWNrcyB0byBiZSB0cmFuc2xhdGVkXG5cdCAqIEByZXR1cm4ge2FycmF5fSAtIEJ5dGVzIHRoYXQgZm9ybSB0aGUgTUlESSB0aW1lIHZhbHVlXG5cdCAqL1xuXHRzdGF0aWMgbnVtYmVyVG9WYXJpYWJsZUxlbmd0aCh0aWNrcykge1xuXHQgICAgdmFyIGJ1ZmZlciA9IHRpY2tzICYgMHg3RjtcblxuXHQgICAgd2hpbGUgKHRpY2tzID0gdGlja3MgPj4gNykge1xuXHQgICAgICAgIGJ1ZmZlciA8PD0gODtcblx0ICAgICAgICBidWZmZXIgfD0gKCh0aWNrcyAmIDB4N0YpIHwgMHg4MCk7XG5cdCAgICB9XG5cblx0ICAgIHZhciBiTGlzdCA9IFtdO1xuXHQgICAgd2hpbGUgKHRydWUpIHtcblx0ICAgICAgICBiTGlzdC5wdXNoKGJ1ZmZlciAmIDB4ZmYpO1xuXG5cdCAgICAgICAgaWYgKGJ1ZmZlciAmIDB4ODApIGJ1ZmZlciA+Pj0gOFxuXHQgICAgICAgIGVsc2UgeyBicmVhazsgfVxuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gYkxpc3Q7XG5cdH1cblxuXHQvKipcblx0ICogQ291bnRzIG51bWJlciBvZiBieXRlcyBpbiBzdHJpbmdcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNcblx0ICogQHJldHVybiB7YXJyYXl9XG5cdCAqL1xuXHRzdGF0aWMgc3RyaW5nQnl0ZUNvdW50KHMpIHtcblx0XHRyZXR1cm4gZW5jb2RlVVJJKHMpLnNwbGl0KC8lLi58Li8pLmxlbmd0aCAtIDFcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgYW4gaW50IGZyb20gYW4gYXJyYXkgb2YgYnl0ZXMuXG5cdCAqIEBwYXJhbSB7YXJyYXl9IGJ5dGVzXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdHN0YXRpYyBudW1iZXJGcm9tQnl0ZXMoYnl0ZXMpIHtcblx0XHR2YXIgaGV4ID0gJyc7XG5cdFx0dmFyIHN0cmluZ1Jlc3VsdDtcblxuXHRcdGJ5dGVzLmZvckVhY2goZnVuY3Rpb24oYnl0ZSkge1xuXHRcdFx0c3RyaW5nUmVzdWx0ID0gYnl0ZS50b1N0cmluZygxNik7XG5cblx0XHRcdC8vIGVuc3VyZSBzdHJpbmcgaXMgMiBjaGFyc1xuXHRcdFx0aWYgKHN0cmluZ1Jlc3VsdC5sZW5ndGggPT0gMSkgc3RyaW5nUmVzdWx0ID0gXCIwXCIgKyBzdHJpbmdSZXN1bHRcblxuXHRcdFx0aGV4ICs9IHN0cmluZ1Jlc3VsdDtcblx0XHR9KTtcblxuXHRcdHJldHVybiBwYXJzZUludChoZXgsIDE2KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUYWtlcyBhIG51bWJlciBhbmQgc3BsaXRzIGl0IHVwIGludG8gYW4gYXJyYXkgb2YgYnl0ZXMuICBDYW4gYmUgcGFkZGVkIGJ5IHBhc3NpbmcgYSBudW1iZXIgdG8gYnl0ZXNOZWVkZWRcblx0ICogQHBhcmFtIHtudW1iZXJ9IG51bWJlclxuXHQgKiBAcGFyYW0ge251bWJlcn0gYnl0ZXNOZWVkZWRcblx0ICogQHJldHVybiB7YXJyYXl9IC0gQXJyYXkgb2YgYnl0ZXNcblx0ICovXG5cdHN0YXRpYyBudW1iZXJUb0J5dGVzKG51bWJlciwgYnl0ZXNOZWVkZWQpIHtcblx0XHRieXRlc05lZWRlZCA9IGJ5dGVzTmVlZGVkIHx8IDE7XG5cblx0XHR2YXIgaGV4U3RyaW5nID0gbnVtYmVyLnRvU3RyaW5nKDE2KTtcblxuXHRcdGlmIChoZXhTdHJpbmcubGVuZ3RoICYgMSkgeyAvLyBNYWtlIHN1cmUgaGV4IHN0cmluZyBpcyBldmVuIG51bWJlciBvZiBjaGFyc1xuXHRcdFx0aGV4U3RyaW5nID0gJzAnICsgaGV4U3RyaW5nO1xuXHRcdH1cblxuXHRcdC8vIFNwbGl0IGhleCBzdHJpbmcgaW50byBhbiBhcnJheSBvZiB0d28gY2hhciBlbGVtZW50c1xuXHRcdHZhciBoZXhBcnJheSA9IGhleFN0cmluZy5tYXRjaCgvLnsyfS9nKTtcblxuXHRcdC8vIE5vdyBwYXJzZSB0aGVtIG91dCBhcyBpbnRlZ2Vyc1xuXHRcdGhleEFycmF5ID0gaGV4QXJyYXkubWFwKGl0ZW0gPT4gcGFyc2VJbnQoaXRlbSwgMTYpKVxuXG5cdFx0Ly8gUHJlcGVuZCBlbXB0eSBieXRlcyBpZiB3ZSBkb24ndCBoYXZlIGVub3VnaFxuXHRcdGlmIChoZXhBcnJheS5sZW5ndGggPCBieXRlc05lZWRlZCkge1xuXHRcdFx0d2hpbGUgKGJ5dGVzTmVlZGVkIC0gaGV4QXJyYXkubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRoZXhBcnJheS51bnNoaWZ0KDApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBoZXhBcnJheTtcblx0fVxuXG5cdC8qKlx0XG5cdCAqIENvbnZlcnRzIHZhbHVlIHRvIGFycmF5IGlmIG5lZWRlZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG5cdCAqIEByZXR1cm4ge2FycmF5fVxuXHQgKi9cblx0c3RhdGljIHRvQXJyYXkodmFsdWUpIHtcblx0XHRpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB2YWx1ZTtcblx0XHRyZXR1cm4gW3ZhbHVlXTtcblx0fVxufVxuXG5leHBvcnQge1V0aWxzfTtcbmNsYXNzIFZleEZsb3cge1xuXHRcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0Ly8gY29kZS4uLlxuXHR9XG5cblx0LyoqXG5cdCAqIFN1cHBvcnQgZm9yIGNvbnZlcnRpbmcgVmV4RmxvdyB2b2ljZSBpbnRvIE1pZGlXcml0ZXJKUyB0cmFja1xuXHQgKiBAcmV0dXJuIE1pZGlXcml0aWVyLlRyYWNrIG9iamVjdFxuXHQgKi9cblx0dHJhY2tGcm9tVm9pY2Uodm9pY2UpIHtcblx0XHR2YXIgdHJhY2sgPSBuZXcgVHJhY2soKTtcblx0XHR2YXIgd2FpdDtcblx0XHR2YXIgcGl0Y2hlcyA9IFtdO1xuXG5cdFx0dm9pY2UudGlja2FibGVzLmZvckVhY2goZnVuY3Rpb24odGlja2FibGUpIHtcblx0XHRcdHBpdGNoZXMgPSBbXTtcblxuXHRcdFx0aWYgKHRpY2thYmxlLm5vdGVUeXBlID09PSAnbicpIHtcblx0XHRcdFx0dGlja2FibGUua2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuXHRcdFx0XHRcdC8vIGJ1aWxkIGFycmF5IG9mIHBpdGNoZXNcblx0XHRcdFx0XHRwaXRjaGVzLnB1c2godGhpcy5jb252ZXJ0UGl0Y2goa2V5KSk7XG5cdFx0XHRcdH0pO1xuXG5cdFx0XHR9IGVsc2UgaWYgKHRpY2thYmxlLm5vdGVUeXBlID09PSAncicpIHtcblx0XHRcdFx0Ly8gbW92ZSBvbiB0byB0aGUgbmV4dCB0aWNrYWJsZSBhbmQgdXNlIHRoaXMgcmVzdCBhcyBhIGB3YWl0YCBwcm9wZXJ0eSBmb3IgdGhlIG5leHQgZXZlbnRcblx0XHRcdFx0d2FpdCA9IHRoaXMuY29udmVydER1cmF0aW9uKHRpY2thYmxlKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR0cmFjay5hZGRFdmVudChuZXcgTm90ZUV2ZW50KHtwaXRjaDogcGl0Y2hlcywgZHVyYXRpb246IHRoaXMuY29udmVydER1cmF0aW9uKHRpY2thYmxlKSwgd2FpdDogd2FpdH0pKTtcblx0XHRcdFxuXHRcdFx0Ly8gcmVzZXQgd2FpdFxuXHRcdFx0d2FpdCA9IDA7XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gdHJhY2s7XG5cdH1cblxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBWZXhGbG93IHBpdGNoIHN5bnRheCB0byBNaWRpV3JpdGVySlMgc3ludGF4XG5cdCAqIEBwYXJhbSBwaXRjaCBzdHJpbmdcblx0ICovXG5cdGNvbnZlcnRQaXRjaChwaXRjaCkge1xuXHRcdHJldHVybiBwaXRjaC5yZXBsYWNlKCcvJywgJycpO1xuXHR9IFxuXG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIFZleEZsb3cgZHVyYXRpb24gc3ludGF4IHRvIE1pZGlXcml0ZXJKUyBzeW50YXhcblx0ICogQHBhcmFtIG5vdGUgc3RydWN0IGZyb20gVmV4Rmxvd1xuXHQgKi9cblx0Y29udmVydER1cmF0aW9uKG5vdGUpIHtcblx0XHRzd2l0Y2ggKG5vdGUuZHVyYXRpb24pIHtcblx0XHRcdGNhc2UgJ3cnOlxuXHRcdFx0XHRyZXR1cm4gJzEnO1xuXHRcdFx0Y2FzZSAnaCc6XG5cdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDInIDogJzInO1xuXHRcdFx0Y2FzZSAncSc6XG5cdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDQnIDogJzQnO1xuXHRcdFx0Y2FzZSAnOCc6XG5cdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDgnIDogJzgnO1xuXHRcdH1cblxuXHRcdHJldHVybiBub3RlLmR1cmF0aW9uO1xuXHR9O1xufVxuXG5leHBvcnQge1ZleEZsb3d9O1xuLyoqXG4gKiBPYmplY3QgdGhhdCBwdXRzIHRvZ2V0aGVyIHRyYWNrcyBhbmQgcHJvdmlkZXMgbWV0aG9kcyBmb3IgZmlsZSBvdXRwdXQuXG4gKiBAcGFyYW0ge2FycmF5fSB0cmFja3MgLSBBbiBhcnJheSBvZiB7VHJhY2t9IG9iamVjdHMuXG4gKiBAcmV0dXJuIHtXcml0ZXJ9XG4gKi9cbmNsYXNzIFdyaXRlciB7XG5cdGNvbnN0cnVjdG9yKHRyYWNrcykge1xuXHRcdHRoaXMuZGF0YSA9IFtdO1xuXG5cdFx0dmFyIHRyYWNrVHlwZSA9IHRyYWNrcy5sZW5ndGggPiAxID8gQ29uc3RhbnRzLkhFQURFUl9DSFVOS19GT1JNQVQxIDogQ29uc3RhbnRzLkhFQURFUl9DSFVOS19GT1JNQVQwO1xuXHRcdHZhciBudW1iZXJPZlRyYWNrcyA9IFV0aWxzLm51bWJlclRvQnl0ZXModHJhY2tzLmxlbmd0aCwgMik7IC8vIHR3byBieXRlcyBsb25nXG5cblx0XHQvLyBIZWFkZXIgY2h1bmtcblx0XHR0aGlzLmRhdGEucHVzaChuZXcgQ2h1bmsoe1xuXHRcdFx0XHRcdFx0XHRcdHR5cGU6IENvbnN0YW50cy5IRUFERVJfQ0hVTktfVFlQRSxcblx0XHRcdFx0XHRcdFx0XHRkYXRhOiB0cmFja1R5cGUuY29uY2F0KG51bWJlck9mVHJhY2tzLCBDb25zdGFudHMuSEVBREVSX0NIVU5LX0RJVklTSU9OKX0pKTtcblxuXHRcdC8vIFRyYWNrIGNodW5rc1xuXHRcdHRyYWNrcy5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrLCBpKSB7XG5cdFx0XHR0cmFjay5hZGRFdmVudChuZXcgTWV0YUV2ZW50KHtkYXRhOiBDb25zdGFudHMuTUVUQV9FTkRfT0ZfVFJBQ0tfSUR9KSk7XG5cdFx0XHR0aGlzLmRhdGEucHVzaCh0cmFjayk7XG5cdFx0fSwgdGhpcyk7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIHRoZSBmaWxlIGludG8gYSBVaW50OEFycmF5XG5cdCAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9XG5cdCAqL1xuXHRidWlsZEZpbGUoKSB7XG5cdFx0dmFyIGJ1aWxkID0gW107XG5cblx0XHQvLyBEYXRhIGNvbnNpc3RzIG9mIGNodW5rcyB3aGljaCBjb25zaXN0cyBvZiBkYXRhXG5cdFx0dGhpcy5kYXRhLmZvckVhY2goKGQpID0+IGJ1aWxkID0gYnVpbGQuY29uY2F0KGQudHlwZSwgZC5zaXplLCBkLmRhdGEpKTtcblxuXHRcdHJldHVybiBuZXcgVWludDhBcnJheShidWlsZCk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydCBmaWxlIGJ1ZmZlciB0byBhIGJhc2U2NCBzdHJpbmcuICBEaWZmZXJlbnQgbWV0aG9kcyBkZXBlbmRpbmcgb24gaWYgYnJvd3NlciBvciBub2RlLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRiYXNlNjQoKSB7XG5cdFx0aWYgKHR5cGVvZiBidG9hID09PSAnZnVuY3Rpb24nKSByZXR1cm4gYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIHRoaXMuYnVpbGRGaWxlKCkpKTtcblx0XHRyZXR1cm4gbmV3IEJ1ZmZlcih0aGlzLmJ1aWxkRmlsZSgpKS50b1N0cmluZygnYmFzZTY0Jyk7XG5cdH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZGF0YSBVUkkuXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqL1xuICAgIGRhdGFVcmkoKSB7XG4gICAgXHRyZXR1cm4gJ2RhdGE6YXVkaW8vbWlkaTtiYXNlNjQsJyArIHRoaXMuYmFzZTY0KCk7XG4gICAgfVxuXG5cdC8qKlxuXHQgKiBPdXRwdXQgdG8gc3Rkb3V0XG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG4gICAgc3Rkb3V0KCkge1xuICAgIFx0cmV0dXJuIHByb2Nlc3Muc3Rkb3V0LndyaXRlKG5ldyBCdWZmZXIodGhpcy5idWlsZEZpbGUoKSkpO1xuICAgIH1cblxuXHQvKipcblx0ICogU2F2ZSB0byBNSURJIGZpbGVcblx0ICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lXG5cdCAqL1xuXHRzYXZlTUlESShmaWxlbmFtZSkge1xuXHRcdHZhciBidWZmZXIgPSBuZXcgQnVmZmVyKHRoaXMuYnVpbGRGaWxlKCkpO1xuXHRcdGZzLndyaXRlRmlsZShmaWxlbmFtZSArICcubWlkJywgYnVmZmVyLCBmdW5jdGlvbiAoZXJyKSB7XG5cdFx0XHRpZihlcnIpIHJldHVybiBjb25zb2xlLmxvZyhlcnIpO1xuXHRcdH0pO1xuXHR9XG59XG5cbmV4cG9ydCB7V3JpdGVyfTtcbiJdfQ== + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3).Buffer, __webpack_require__(11))) + +/***/ }), +/* 141 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* unused harmony export regex */ +/* unused harmony export parse */ +/* unused harmony export build */ +/* harmony export (immutable) */ __webpack_exports__["a"] = midi; +/* unused harmony export freq */ +/* unused harmony export letter */ +/* unused harmony export acc */ +/* unused harmony export pc */ +/* unused harmony export step */ +/* unused harmony export alt */ +/* unused harmony export chroma */ +/* unused harmony export oct */ + + +// util +function fillStr (s, num) { return Array(num + 1).join(s) } +function isNum (x) { return typeof x === 'number' } +function isStr (x) { return typeof x === 'string' } +function isDef (x) { return typeof x !== 'undefined' } +function midiToFreq (midi, tuning) { + return Math.pow(2, (midi - 69) / 12) * (tuning || 440) +} + +var REGEX = /^([a-gA-G])(#{1,}|b{1,}|x{1,}|)(-?\d*)\s*(.*)\s*$/ +/** + * A regex for matching note strings in scientific notation. + * + * @name regex + * @function + * @return {RegExp} the regexp used to parse the note name + * + * The note string should have the form `letter[accidentals][octave][element]` + * where: + * + * - letter: (Required) is a letter from A to G either upper or lower case + * - accidentals: (Optional) can be one or more `b` (flats), `#` (sharps) or `x` (double sharps). + * They can NOT be mixed. + * - octave: (Optional) a positive or negative integer + * - element: (Optional) additionally anything after the duration is considered to + * be the element name (for example: 'C2 dorian') + * + * The executed regex contains (by array index): + * + * - 0: the complete string + * - 1: the note letter + * - 2: the optional accidentals + * - 3: the optional octave + * - 4: the rest of the string (trimmed) + * + * @example + * var parser = require('note-parser') + * parser.regex.exec('c#4') + * // => ['c#4', 'c', '#', '4', ''] + * parser.regex.exec('c#4 major') + * // => ['c#4major', 'c', '#', '4', 'major'] + * parser.regex().exec('CMaj7') + * // => ['CMaj7', 'C', '', '', 'Maj7'] + */ +function regex () { return REGEX } + +var SEMITONES = [0, 2, 4, 5, 7, 9, 11] +/** + * Parse a note name in scientific notation an return it's components, + * and some numeric properties including midi number and frequency. + * + * @name parse + * @function + * @param {String} note - the note string to be parsed + * @param {Boolean} isTonic - true the strings it's supposed to contain a note number + * and some category (for example an scale: 'C# major'). It's false by default, + * but when true, en extra tonicOf property is returned with the category ('major') + * @param {Float} tunning - The frequency of A4 note to calculate frequencies. + * By default it 440. + * @return {Object} the parsed note name or null if not a valid note + * + * The parsed note name object will ALWAYS contains: + * - letter: the uppercase letter of the note + * - acc: the accidentals of the note (only sharps or flats) + * - pc: the pitch class (letter + acc) + * - step: s a numeric representation of the letter. It's an integer from 0 to 6 + * where 0 = C, 1 = D ... 6 = B + * - alt: a numeric representation of the accidentals. 0 means no alteration, + * positive numbers are for sharps and negative for flats + * - chroma: a numeric representation of the pitch class. It's like midi for + * pitch classes. 0 = C, 1 = C#, 2 = D ... 11 = B. Can be used to find enharmonics + * since, for example, chroma of 'Cb' and 'B' are both 11 + * + * If the note has octave, the parser object will contain: + * - oct: the octave number (as integer) + * - midi: the midi number + * - freq: the frequency (using tuning parameter as base) + * + * If the parameter `isTonic` is set to true, the parsed object will contain: + * - tonicOf: the rest of the string that follows note name (left and right trimmed) + * + * @example + * var parse = require('note-parser').parse + * parse('Cb4') + * // => { letter: 'C', acc: 'b', pc: 'Cb', step: 0, alt: -1, chroma: -1, + * oct: 4, midi: 59, freq: 246.94165062806206 } + * // if no octave, no midi, no freq + * parse('fx') + * // => { letter: 'F', acc: '##', pc: 'F##', step: 3, alt: 2, chroma: 7 }) + */ +function parse (str, isTonic, tuning) { + if (typeof str !== 'string') return null + var m = REGEX.exec(str) + if (!m || (!isTonic && m[4])) return null + + var p = { letter: m[1].toUpperCase(), acc: m[2].replace(/x/g, '##') } + p.pc = p.letter + p.acc + p.step = (p.letter.charCodeAt(0) + 3) % 7 + p.alt = p.acc[0] === 'b' ? -p.acc.length : p.acc.length + var pos = SEMITONES[p.step] + p.alt + p.chroma = pos < 0 ? 12 + pos : pos % 12 + if (m[3]) { // has octave + p.oct = +m[3] + p.midi = pos + 12 * (p.oct + 1) + p.freq = midiToFreq(p.midi, tuning) + } + if (isTonic) p.tonicOf = m[4] + return p +} + +var LETTERS = 'CDEFGAB' +function accStr (n) { return !isNum(n) ? '' : n < 0 ? fillStr('b', -n) : fillStr('#', n) } +function octStr (n) { return !isNum(n) ? '' : '' + n } + +/** + * Create a string from a parsed object or `step, alteration, octave` parameters + * @param {Object} obj - the parsed data object + * @return {String} a note string or null if not valid parameters + * @since 1.2 + * @example + * parser.build(parser.parse('cb2')) // => 'Cb2' + * + * @example + * // it accepts (step, alteration, octave) parameters: + * parser.build(3) // => 'F' + * parser.build(3, -1) // => 'Fb' + * parser.build(3, -1, 4) // => 'Fb4' + */ +function build (s, a, o) { + if (s === null || typeof s === 'undefined') return null + if (s.step) return build(s.step, s.alt, s.oct) + if (s < 0 || s > 6) return null + return LETTERS.charAt(s) + accStr(a) + octStr(o) +} + +/** + * Get midi of a note + * + * @name midi + * @function + * @param {String|Integer} note - the note name or midi number + * @return {Integer} the midi number of the note or null if not a valid note + * or the note does NOT contains octave + * @example + * var parser = require('note-parser') + * parser.midi('A4') // => 69 + * parser.midi('A') // => null + * @example + * // midi numbers are bypassed (even as strings) + * parser.midi(60) // => 60 + * parser.midi('60') // => 60 + */ +function midi (note) { + if ((isNum(note) || isStr(note)) && note >= 0 && note < 128) return +note + var p = parse(note) + return p && isDef(p.midi) ? p.midi : null +} + +/** + * Get freq of a note in hertzs (in a well tempered 440Hz A4) + * + * @name freq + * @function + * @param {String} note - the note name or note midi number + * @param {String} tuning - (Optional) the A4 frequency (440 by default) + * @return {Float} the freq of the number if hertzs or null if not valid note + * @example + * var parser = require('note-parser') + * parser.freq('A4') // => 440 + * parser.freq('A') // => null + * @example + * // can change tuning (440 by default) + * parser.freq('A4', 444) // => 444 + * parser.freq('A3', 444) // => 222 + * @example + * // it accepts midi numbers (as numbers and as strings) + * parser.freq(69) // => 440 + * parser.freq('69', 442) // => 442 + */ +function freq (note, tuning) { + var m = midi(note) + return m === null ? null : midiToFreq(m, tuning) +} + +function letter (src) { return (parse(src) || {}).letter } +function acc (src) { return (parse(src) || {}).acc } +function pc (src) { return (parse(src) || {}).pc } +function step (src) { return (parse(src) || {}).step } +function alt (src) { return (parse(src) || {}).alt } +function chroma (src) { return (parse(src) || {}).chroma } +function oct (src) { return (parse(src) || {}).oct } + + +/***/ }), +/* 142 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(12); + + +/***/ }), +/* 143 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + + + +module.exports = PassThrough; + +var Transform = __webpack_require__(73); + +/*<replacement>*/ +var util = __webpack_require__(22); +util.inherits = __webpack_require__(16); +/*</replacement>*/ + +util.inherits(PassThrough, Transform); + +function PassThrough(options) { + if (!(this instanceof PassThrough)) return new PassThrough(options); + + Transform.call(this, options); +} + +PassThrough.prototype._transform = function (chunk, encoding, cb) { + cb(null, chunk); +}; + +/***/ }), +/* 144 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var Buffer = __webpack_require__(3).Buffer; +/*<replacement>*/ +var bufferShim = __webpack_require__(32); +/*</replacement>*/ + +module.exports = BufferList; + +function BufferList() { + this.head = null; + this.tail = null; + this.length = 0; +} + +BufferList.prototype.push = function (v) { + var entry = { data: v, next: null }; + if (this.length > 0) this.tail.next = entry;else this.head = entry; + this.tail = entry; + ++this.length; +}; + +BufferList.prototype.unshift = function (v) { + var entry = { data: v, next: this.head }; + if (this.length === 0) this.tail = entry; + this.head = entry; + ++this.length; +}; + +BufferList.prototype.shift = function () { + if (this.length === 0) return; + var ret = this.head.data; + if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; + --this.length; + return ret; +}; + +BufferList.prototype.clear = function () { + this.head = this.tail = null; + this.length = 0; +}; + +BufferList.prototype.join = function (s) { + if (this.length === 0) return ''; + var p = this.head; + var ret = '' + p.data; + while (p = p.next) { + ret += s + p.data; + }return ret; +}; + +BufferList.prototype.concat = function (n) { + if (this.length === 0) return bufferShim.alloc(0); + if (this.length === 1) return this.head.data; + var ret = bufferShim.allocUnsafe(n >>> 0); + var p = this.head; + var i = 0; + while (p) { + p.data.copy(ret, i); + i += p.data.length; + p = p.next; + } + return ret; +}; + +/***/ }), +/* 145 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(51).PassThrough + + +/***/ }), +/* 146 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(51).Transform + + +/***/ }), +/* 147 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(50); + + +/***/ }), +/* 148 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) { + "use strict"; + + if (global.setImmediate) { + return; + } + + var nextHandle = 1; // Spec says greater than zero + var tasksByHandle = {}; + var currentlyRunningATask = false; + var doc = global.document; + var registerImmediate; + + function setImmediate(callback) { + // Callback can either be a function or a string + if (typeof callback !== "function") { + callback = new Function("" + callback); + } + // Copy function arguments + var args = new Array(arguments.length - 1); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i + 1]; + } + // Store and register the task + var task = { callback: callback, args: args }; + tasksByHandle[nextHandle] = task; + registerImmediate(nextHandle); + return nextHandle++; + } + + function clearImmediate(handle) { + delete tasksByHandle[handle]; + } + + function run(task) { + var callback = task.callback; + var args = task.args; + switch (args.length) { + case 0: + callback(); + break; + case 1: + callback(args[0]); + break; + case 2: + callback(args[0], args[1]); + break; + case 3: + callback(args[0], args[1], args[2]); + break; + default: + callback.apply(undefined, args); + break; + } + } + + function runIfPresent(handle) { + // From the spec: "Wait until any invocations of this algorithm started before this one have completed." + // So if we're currently running a task, we'll need to delay this invocation. + if (currentlyRunningATask) { + // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a + // "too much recursion" error. + setTimeout(runIfPresent, 0, handle); + } else { + var task = tasksByHandle[handle]; + if (task) { + currentlyRunningATask = true; + try { + run(task); + } finally { + clearImmediate(handle); + currentlyRunningATask = false; + } + } + } + } + + function installNextTickImplementation() { + registerImmediate = function(handle) { + process.nextTick(function () { runIfPresent(handle); }); + }; + } + + function canUsePostMessage() { + // The test against `importScripts` prevents this implementation from being installed inside a web worker, + // where `global.postMessage` means something completely different and can't be used for this purpose. + if (global.postMessage && !global.importScripts) { + var postMessageIsAsynchronous = true; + var oldOnMessage = global.onmessage; + global.onmessage = function() { + postMessageIsAsynchronous = false; + }; + global.postMessage("", "*"); + global.onmessage = oldOnMessage; + return postMessageIsAsynchronous; + } + } + + function installPostMessageImplementation() { + // Installs an event handler on `global` for the `message` event: see + // * https://developer.mozilla.org/en/DOM/window.postMessage + // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages + + var messagePrefix = "setImmediate$" + Math.random() + "$"; + var onGlobalMessage = function(event) { + if (event.source === global && + typeof event.data === "string" && + event.data.indexOf(messagePrefix) === 0) { + runIfPresent(+event.data.slice(messagePrefix.length)); + } + }; + + if (global.addEventListener) { + global.addEventListener("message", onGlobalMessage, false); + } else { + global.attachEvent("onmessage", onGlobalMessage); + } + + registerImmediate = function(handle) { + global.postMessage(messagePrefix + handle, "*"); + }; + } + + function installMessageChannelImplementation() { + var channel = new MessageChannel(); + channel.port1.onmessage = function(event) { + var handle = event.data; + runIfPresent(handle); + }; + + registerImmediate = function(handle) { + channel.port2.postMessage(handle); + }; + } + + function installReadyStateChangeImplementation() { + var html = doc.documentElement; + registerImmediate = function(handle) { + // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted + // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. + var script = doc.createElement("script"); + script.onreadystatechange = function () { + runIfPresent(handle); + script.onreadystatechange = null; + html.removeChild(script); + script = null; + }; + html.appendChild(script); + }; + } + + function installSetTimeoutImplementation() { + registerImmediate = function(handle) { + setTimeout(runIfPresent, 0, handle); + }; + } + + // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live. + var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global); + attachTo = attachTo && attachTo.setTimeout ? attachTo : global; + + // Don't get fooled by e.g. browserify environments. + if ({}.toString.call(global.process) === "[object process]") { + // For Node.js before 0.9 + installNextTickImplementation(); + + } else if (canUsePostMessage()) { + // For non-IE10 modern browsers + installPostMessageImplementation(); + + } else if (global.MessageChannel) { + // For web workers, where supported + installMessageChannelImplementation(); + + } else if (doc && "onreadystatechange" in doc.createElement("script")) { + // For IE 6–8 + installReadyStateChangeImplementation(); + + } else { + // For older browsers + installSetTimeoutImplementation(); + } + + attachTo.setImmediate = setImmediate; + attachTo.clearImmediate = clearImmediate; +}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self)); + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(23), __webpack_require__(11))) + +/***/ }), +/* 149 */ +/***/ (function(module, exports, __webpack_require__) { + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +module.exports = Stream; + +var EE = __webpack_require__(47).EventEmitter; +var inherits = __webpack_require__(16); + +inherits(Stream, EE); +Stream.Readable = __webpack_require__(51); +Stream.Writable = __webpack_require__(147); +Stream.Duplex = __webpack_require__(142); +Stream.Transform = __webpack_require__(146); +Stream.PassThrough = __webpack_require__(145); + +// Backwards-compat with node 0.4.x +Stream.Stream = Stream; + + + +// old-style streams. Note that the pipe method (the only relevant +// part of this class) is overridden in the Readable class. + +function Stream() { + EE.call(this); +} + +Stream.prototype.pipe = function(dest, options) { + var source = this; + + function ondata(chunk) { + if (dest.writable) { + if (false === dest.write(chunk) && source.pause) { + source.pause(); + } + } + } + + source.on('data', ondata); + + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } + } + + dest.on('drain', ondrain); + + // If the 'end' option is not supplied, dest.end() will be called when + // source gets the 'end' or 'close' events. Only dest.end() once. + if (!dest._isStdio && (!options || options.end !== false)) { + source.on('end', onend); + source.on('close', onclose); + } + + var didOnEnd = false; + function onend() { + if (didOnEnd) return; + didOnEnd = true; + + dest.end(); + } + + + function onclose() { + if (didOnEnd) return; + didOnEnd = true; + + if (typeof dest.destroy === 'function') dest.destroy(); + } + + // don't leave dangling pipes when there are errors. + function onerror(er) { + cleanup(); + if (EE.listenerCount(this, 'error') === 0) { + throw er; // Unhandled stream error in pipe. + } + } + + source.on('error', onerror); + dest.on('error', onerror); + + // remove all the event listeners that were added. + function cleanup() { + source.removeListener('data', ondata); + dest.removeListener('drain', ondrain); + + source.removeListener('end', onend); + source.removeListener('close', onclose); + + source.removeListener('error', onerror); + dest.removeListener('error', onerror); + + source.removeListener('end', cleanup); + source.removeListener('close', cleanup); + + dest.removeListener('close', cleanup); + } + + source.on('end', cleanup); + source.on('close', cleanup); + + dest.on('close', cleanup); + + dest.emit('pipe', source); + + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; +}; + + +/***/ }), +/* 150 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_note_parser__ = __webpack_require__(141); +/* harmony export (immutable) */ __webpack_exports__["toMidi"] = toMidi; +/* harmony export (immutable) */ __webpack_exports__["note"] = note; +/** + * A midi note number is a number representation of a note pitch. It can be + * integers so it's equal tempered tuned, or float to indicate it's not + * tuned into equal temepered scale. + * + * This module contains functions to convert to and from midi notes. + * + * @example + * var midi = require('tonal-midi') + * midi.toMidi('A4') // => 69 + * midi.note(69) // => 'A4' + * midi.note(61) // => 'Db4' + * midi.note(61, true) // => 'C#4' + * + * @module midi + */ + + + +/** + * Convert the given note to a midi note number. If you pass a midi number it + * will returned as is. + * + * @param {Array|String|Number} note - the note to get the midi number from + * @return {Integer} the midi number or null if not valid pitch + * @example + * midi.toMidi('C4') // => 60 + * midi.toMidi(60) // => 60 + * midi.toMidi('60') // => 60 + */ +function toMidi (val) { + if (Array.isArray(val) && val.length === 2) return val[0] * 7 + val[1] * 12 + 12 + return __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0_note_parser__["a" /* midi */])(val) +} + +var FLATS = 'C Db D Eb E F Gb G Ab A Bb B'.split(' ') +var SHARPS = 'C C# D D# E F F# G G# A A# B'.split(' ') + +/** + * Given a midi number, returns a note name. The altered notes will have + * flats unless explicitly set with the optional `useSharps` parameter. + * + * @function + * @param {Integer} midi - the midi note number + * @param {Boolean} useSharps - (Optional) set to true to use sharps instead of flats + * @return {String} the note name + * @example + * var midi = require('tonal-midi') + * midi.note(61) // => 'Db4' + * midi.note(61, true) // => 'C#4' + * // it rounds to nearest note + * midi.note(61.7) // => 'D4' + */ +function note (num, sharps) { + if (num === true || num === false) return function (m) { return note(m, num) } + num = Math.round(num) + var pcs = sharps === true ? SHARPS : FLATS + var pc = pcs[num % 12] + var o = Math.floor(num / 12) - 1 + return pc + o +} + + +/***/ }), +/* 151 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(global) { +/** + * Module exports. + */ + +module.exports = deprecate; + +/** + * Mark that a method should not be used. + * Returns a modified function which warns once by default. + * + * If `localStorage.noDeprecation = true` is set, then it is a no-op. + * + * If `localStorage.throwDeprecation = true` is set, then deprecated functions + * will throw an Error when invoked. + * + * If `localStorage.traceDeprecation = true` is set, then deprecated functions + * will invoke `console.trace()` instead of `console.error()`. + * + * @param {Function} fn - the function to deprecate + * @param {String} msg - the string to print to the console when `fn` is invoked + * @returns {Function} a new "deprecated" version of `fn` + * @api public + */ + +function deprecate (fn, msg) { + if (config('noDeprecation')) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (config('throwDeprecation')) { + throw new Error(msg); + } else if (config('traceDeprecation')) { + console.trace(msg); + } else { + console.warn(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +} + +/** + * Checks `localStorage` for boolean values for the given `name`. + * + * @param {String} name + * @returns {Boolean} + * @api private + */ + +function config (name) { + // accessing global.localStorage can trigger a DOMException in sandboxed iframes + try { + if (!global.localStorage) return false; + } catch (_) { + return false; + } + var val = global.localStorage[name]; + if (null == val) return false; + return String(val).toLowerCase() === 'true'; +} + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(23))) + +/***/ }), +/* 152 */ +/***/ (function(module, exports) { + +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + + +/***/ }), +/* 153 */ +/***/ (function(module, exports) { + +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} + +/***/ }), +/* 154 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = __webpack_require__(153); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = __webpack_require__(152); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(23), __webpack_require__(11))) + +/***/ }), +/* 155 */ +/***/ (function(module, exports, __webpack_require__) { + +var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* + +WebMidi v2.2.0 + +WebMidi.js helps you tame the Web MIDI API. Send and receive MIDI messages with ease. Control instruments with user-friendly functions (playNote, sendPitchBend, etc.). React to MIDI input with simple event listeners (noteon, pitchbend, controlchange, etc.). +https://github.com/djipco/webmidi + + +The MIT License (MIT) + +Copyright (c) 2015-2018, Jean-Philippe Côté + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES +OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +!function(scope){"use strict";function WebMidi(){if(WebMidi.prototype._singleton)throw new Error("WebMidi is a singleton, it cannot be instantiated directly.");WebMidi.prototype._singleton=this,this._inputs=[],this._outputs=[],this._userHandlers={},this._stateChangeQueue=[],this._processingStateChange=!1,this._midiInterfaceEvents=["connected","disconnected"],this._notes=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],this._semitones={C:0,D:2,E:4,F:5,G:7,A:9,B:11},Object.defineProperties(this,{MIDI_SYSTEM_MESSAGES:{value:{sysex:240,timecode:241,songposition:242,songselect:243,tuningrequest:246,sysexend:247,clock:248,start:250,"continue":251,stop:252,activesensing:254,reset:255,midimessage:0,unknownsystemmessage:-1},writable:!1,enumerable:!0,configurable:!1},MIDI_CHANNEL_MESSAGES:{value:{noteoff:8,noteon:9,keyaftertouch:10,controlchange:11,channelmode:11,programchange:12,channelaftertouch:13,pitchbend:14},writable:!1,enumerable:!0,configurable:!1},MIDI_REGISTERED_PARAMETER:{value:{pitchbendrange:[0,0],channelfinetuning:[0,1],channelcoarsetuning:[0,2],tuningprogram:[0,3],tuningbank:[0,4],modulationrange:[0,5],azimuthangle:[61,0],elevationangle:[61,1],gain:[61,2],distanceratio:[61,3],maximumdistance:[61,4],maximumdistancegain:[61,5],referencedistanceratio:[61,6],panspreadangle:[61,7],rollangle:[61,8]},writable:!1,enumerable:!0,configurable:!1},MIDI_CONTROL_CHANGE_MESSAGES:{value:{bankselectcoarse:0,modulationwheelcoarse:1,breathcontrollercoarse:2,footcontrollercoarse:4,portamentotimecoarse:5,dataentrycoarse:6,volumecoarse:7,balancecoarse:8,pancoarse:10,expressioncoarse:11,effectcontrol1coarse:12,effectcontrol2coarse:13,generalpurposeslider1:16,generalpurposeslider2:17,generalpurposeslider3:18,generalpurposeslider4:19,bankselectfine:32,modulationwheelfine:33,breathcontrollerfine:34,footcontrollerfine:36,portamentotimefine:37,dataentryfine:38,volumefine:39,balancefine:40,panfine:42,expressionfine:43,effectcontrol1fine:44,effectcontrol2fine:45,holdpedal:64,portamento:65,sustenutopedal:66,softpedal:67,legatopedal:68,hold2pedal:69,soundvariation:70,resonance:71,soundreleasetime:72,soundattacktime:73,brightness:74,soundcontrol6:75,soundcontrol7:76,soundcontrol8:77,soundcontrol9:78,soundcontrol10:79,generalpurposebutton1:80,generalpurposebutton2:81,generalpurposebutton3:82,generalpurposebutton4:83,reverblevel:91,tremololevel:92,choruslevel:93,celestelevel:94,phaserlevel:95,databuttonincrement:96,databuttondecrement:97,nonregisteredparametercoarse:98,nonregisteredparameterfine:99,registeredparametercoarse:100,registeredparameterfine:101},writable:!1,enumerable:!0,configurable:!1},MIDI_CHANNEL_MODE_MESSAGES:{value:{allsoundoff:120,resetallcontrollers:121,localcontrol:122,allnotesoff:123,omnimodeoff:124,omnimodeon:125,monomodeon:126,polymodeon:127},writable:!1,enumerable:!0,configurable:!1},octaveOffset:{value:0,writable:!0,enumerable:!0,configurable:!1}}),Object.defineProperties(this,{supported:{enumerable:!0,get:function(){return"requestMIDIAccess"in navigator}},enabled:{enumerable:!0,get:function(){return void 0!==this["interface"]}.bind(this)},inputs:{enumerable:!0,get:function(){return this._inputs}.bind(this)},outputs:{enumerable:!0,get:function(){return this._outputs}.bind(this)},sysexEnabled:{enumerable:!0,get:function(){return!(!this["interface"]||!this["interface"].sysexEnabled)}.bind(this)},time:{enumerable:!0,get:function(){return performance.now()}}})}function Input(midiInput){var that=this;this._userHandlers={channel:{},system:{}},this._midiInput=midiInput,Object.defineProperties(this,{connection:{enumerable:!0,get:function(){return that._midiInput.connection}},id:{enumerable:!0,get:function(){return that._midiInput.id}},manufacturer:{enumerable:!0,get:function(){return that._midiInput.manufacturer}},name:{enumerable:!0,get:function(){return that._midiInput.name}},state:{enumerable:!0,get:function(){return that._midiInput.state}},type:{enumerable:!0,get:function(){return that._midiInput.type}}}),this._initializeUserHandlers(),this._midiInput.onmidimessage=this._onMidiMessage.bind(this)}function Output(midiOutput){var that=this;this._midiOutput=midiOutput,Object.defineProperties(this,{connection:{enumerable:!0,get:function(){return that._midiOutput.connection}},id:{enumerable:!0,get:function(){return that._midiOutput.id}},manufacturer:{enumerable:!0,get:function(){return that._midiOutput.manufacturer}},name:{enumerable:!0,get:function(){return that._midiOutput.name}},state:{enumerable:!0,get:function(){return that._midiOutput.state}},type:{enumerable:!0,get:function(){return that._midiOutput.type}}})}var wm=new WebMidi;WebMidi.prototype.enable=function(callback,sysex){return this.enabled?void 0:this.supported?void navigator.requestMIDIAccess({sysex:sysex}).then(function(midiAccess){function onPortsOpen(){clearTimeout(promiseTimeout),this._updateInputsAndOutputs(),this["interface"].onstatechange=this._onInterfaceStateChange.bind(this),"function"==typeof callback&&callback.call(this),events.forEach(function(event){this._onInterfaceStateChange(event)}.bind(this))}var promiseTimeout,events=[],promises=[];this["interface"]=midiAccess,this._resetInterfaceUserHandlers(),this["interface"].onstatechange=function(e){events.push(e)};for(var inputs=midiAccess.inputs.values(),input=inputs.next();input&&!input.done;input=inputs.next())promises.push(input.value.open());for(var outputs=midiAccess.outputs.values(),output=outputs.next();output&&!output.done;output=outputs.next())promises.push(output.value.open());promiseTimeout=setTimeout(onPortsOpen.bind(this),200),Promise&&Promise.all(promises)["catch"](function(err){}).then(onPortsOpen.bind(this))}.bind(this),function(err){"function"==typeof callback&&callback.call(this,err)}.bind(this)):void("function"==typeof callback&&callback(new Error("The Web MIDI API is not supported by your browser.")))},WebMidi.prototype.disable=function(){if(!this.supported)throw new Error("The Web MIDI API is not supported by your browser.");this["interface"]&&(this["interface"].onstatechange=void 0),this["interface"]=void 0,this._inputs=[],this._outputs=[],this._resetInterfaceUserHandlers()},WebMidi.prototype.addListener=function(type,listener){if(!this.enabled)throw new Error("WebMidi must be enabled before adding event listeners.");if("function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(!(this._midiInterfaceEvents.indexOf(type)>=0))throw new TypeError("The specified event type is not supported.");return this._userHandlers[type].push(listener),this},WebMidi.prototype.hasListener=function(type,listener){if(!this.enabled)throw new Error("WebMidi must be enabled before checking event listeners.");if("function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(!(this._midiInterfaceEvents.indexOf(type)>=0))throw new TypeError("The specified event type is not supported.");for(var o=0;o<this._userHandlers[type].length;o++)if(this._userHandlers[type][o]===listener)return!0;return!1},WebMidi.prototype.removeListener=function(type,listener){if(!this.enabled)throw new Error("WebMidi must be enabled before removing event listeners.");if(void 0!==listener&&"function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(this._midiInterfaceEvents.indexOf(type)>=0)if(listener)for(var o=0;o<this._userHandlers[type].length;o++)this._userHandlers[type][o]===listener&&this._userHandlers[type].splice(o,1);else this._userHandlers[type]=[];else{if(void 0!==type)throw new TypeError("The specified event type is not supported.");this._resetInterfaceUserHandlers()}return this},WebMidi.prototype.toMIDIChannels=function(channel){var channels;return channels="all"===channel||void 0===channel?["all"]:Array.isArray(channel)?channel:[channel],channels.indexOf("all")>-1&&(channels=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]),channels.map(function(ch){return parseInt(ch)}).filter(function(ch){return ch>=1&&16>=ch})},WebMidi.prototype.getInputById=function(id){if(!this.enabled)throw new Error("WebMidi is not enabled.");for(var i=0;i<this.inputs.length;i++)if(this.inputs[i].id===id)return this.inputs[i];return!1},WebMidi.prototype.getOutputById=function(id){if(!this.enabled)throw new Error("WebMidi is not enabled.");for(var i=0;i<this.outputs.length;i++)if(this.outputs[i].id===id)return this.outputs[i];return!1},WebMidi.prototype.getInputByName=function(name){if(!this.enabled)throw new Error("WebMidi is not enabled.");for(var i=0;i<this.inputs.length;i++)if(~this.inputs[i].name.indexOf(name))return this.inputs[i];return!1},WebMidi.prototype.getOctave=function(number){return null!=number&&number>=0&&127>=number?Math.floor(Math.floor(number)/12-1)+Math.floor(wm.octaveOffset):void 0},WebMidi.prototype.getOutputByName=function(name){if(!this.enabled)throw new Error("WebMidi is not enabled.");for(var i=0;i<this.outputs.length;i++)if(~this.outputs[i].name.indexOf(name))return this.outputs[i];return!1},WebMidi.prototype.guessNoteNumber=function(input){var output=!1;if(input&&input.toFixed&&input>=0&&127>=input?output=Math.round(input):parseInt(input)>=0&&parseInt(input)<=127?output=parseInt(input):("string"==typeof input||input instanceof String)&&(output=this.noteNameToNumber(input)),output===!1)throw new Error("Invalid input value ("+input+").");return output},WebMidi.prototype.noteNameToNumber=function(name){"string"!=typeof name&&(name="");var matches=name.match(/([CDEFGAB])(#{0,2}|b{0,2})(-?\d+)/i);if(!matches)throw new RangeError("Invalid note name.");var semitones=wm._semitones[matches[1].toUpperCase()],octave=parseInt(matches[3]),result=12*(octave+1-Math.floor(wm.octaveOffset))+semitones;if(matches[2].toLowerCase().indexOf("b")>-1?result-=matches[2].length:matches[2].toLowerCase().indexOf("#")>-1&&(result+=matches[2].length),0>result||result>127)throw new RangeError("Invalid note name or note outside valid range.");return result},WebMidi.prototype._updateInputsAndOutputs=function(){this._updateInputs(),this._updateOutputs()},WebMidi.prototype._updateInputs=function(){for(var i=0;i<this._inputs.length;i++){for(var remove=!0,updated=this["interface"].inputs.values(),input=updated.next();input&&!input.done;input=updated.next())if(this._inputs[i]._midiInput===input.value){remove=!1;break}remove&&this._inputs.splice(i,1)}this["interface"]&&this["interface"].inputs.forEach(function(nInput){for(var add=!0,j=0;j<this._inputs.length;j++)this._inputs[j]._midiInput===nInput&&(add=!1);add&&this._inputs.push(new Input(nInput))}.bind(this))},WebMidi.prototype._updateOutputs=function(){for(var i=0;i<this._outputs.length;i++){for(var remove=!0,updated=this["interface"].outputs.values(),output=updated.next();output&&!output.done;output=updated.next())if(this._outputs[i]._midiOutput===output.value){remove=!1;break}remove&&this._outputs.splice(i,1)}this["interface"]&&this["interface"].outputs.forEach(function(nOutput){for(var add=!0,j=0;j<this._outputs.length;j++)this._outputs[j]._midiOutput===nOutput&&(add=!1);add&&this._outputs.push(new Output(nOutput))}.bind(this))},WebMidi.prototype._onInterfaceStateChange=function(e){this._updateInputsAndOutputs();var event={timestamp:e.timeStamp,type:e.port.state};this["interface"]&&"connected"===e.port.state?"output"===e.port.type?event.port=this.getOutputById(e.port.id):"input"===e.port.type&&(event.port=this.getInputById(e.port.id)):event.port={connection:"closed",id:e.port.id,manufacturer:e.port.manufacturer,name:e.port.name,state:e.port.state,type:e.port.type},this._userHandlers[e.port.state].forEach(function(handler){handler(event)})},WebMidi.prototype._resetInterfaceUserHandlers=function(){for(var i=0;i<this._midiInterfaceEvents.length;i++)this._userHandlers[this._midiInterfaceEvents[i]]=[]},Input.prototype.addListener=function(type,channel,listener){var that=this;if(void 0===channel&&(channel="all"),Array.isArray(channel)||(channel=[channel]),channel.forEach(function(item){if("all"!==item&&!(item>=1&&16>=item))throw new RangeError("The 'channel' parameter is invalid.")}),"function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(void 0!==wm.MIDI_SYSTEM_MESSAGES[type])this._userHandlers.system[type]||(this._userHandlers.system[type]=[]),this._userHandlers.system[type].push(listener);else{if(void 0===wm.MIDI_CHANNEL_MESSAGES[type])throw new TypeError("The specified event type is not supported.");if(channel.indexOf("all")>-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}this._userHandlers.channel[type]||(this._userHandlers.channel[type]=[]),channel.forEach(function(ch){that._userHandlers.channel[type][ch]||(that._userHandlers.channel[type][ch]=[]),that._userHandlers.channel[type][ch].push(listener)})}return this},Input.prototype.on=Input.prototype.addListener,Input.prototype.hasListener=function(type,channel,listener){var that=this;if("function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(void 0===channel&&(channel="all"),channel.constructor!==Array&&(channel=[channel]),void 0!==wm.MIDI_SYSTEM_MESSAGES[type]){for(var o=0;o<this._userHandlers.system[type].length;o++)if(this._userHandlers.system[type][o]===listener)return!0}else if(void 0!==wm.MIDI_CHANNEL_MESSAGES[type]){if(channel.indexOf("all")>-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}return this._userHandlers.channel[type]?channel.every(function(chNum){var listeners=that._userHandlers.channel[type][chNum];return listeners&&listeners.indexOf(listener)>-1}):!1}return!1},Input.prototype.removeListener=function(type,channel,listener){var that=this;if(void 0!==listener&&"function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(void 0===channel&&(channel="all"),channel.constructor!==Array&&(channel=[channel]),void 0!==wm.MIDI_SYSTEM_MESSAGES[type])if(void 0===listener)this._userHandlers.system[type]=[];else for(var o=0;o<this._userHandlers.system[type].length;o++)this._userHandlers.system[type][o]===listener&&this._userHandlers.system[type].splice(o,1);else if(void 0!==wm.MIDI_CHANNEL_MESSAGES[type]){if(channel.indexOf("all")>-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}if(!this._userHandlers.channel[type])return this;channel.forEach(function(chNum){var listeners=that._userHandlers.channel[type][chNum];if(listeners)if(void 0===listener)that._userHandlers.channel[type][chNum]=[];else for(var l=0;l<listeners.length;l++)listeners[l]===listener&&listeners.splice(l,1)})}else{if(void 0!==type)throw new TypeError("The specified event type is not supported.");this._initializeUserHandlers()}return this},Input.prototype._initializeUserHandlers=function(){for(var prop1 in wm.MIDI_CHANNEL_MESSAGES)wm.MIDI_CHANNEL_MESSAGES.hasOwnProperty(prop1)&&(this._userHandlers.channel[prop1]={});for(var prop2 in wm.MIDI_SYSTEM_MESSAGES)wm.MIDI_SYSTEM_MESSAGES.hasOwnProperty(prop2)&&(this._userHandlers.system[prop2]=[])},Input.prototype._onMidiMessage=function(e){if(this._userHandlers.system.midimessage.length>0){var event={target:this,data:e.data,timestamp:e.timeStamp,type:"midimessage"};this._userHandlers.system.midimessage.forEach(function(callback){callback(event)})}e.data[0]<240?this._parseChannelEvent(e):e.data[0]<=255&&this._parseSystemEvent(e)},Input.prototype._parseChannelEvent=function(e){var data1,data2,command=e.data[0]>>4,channel=(15&e.data[0])+1;e.data.length>1&&(data1=e.data[1],data2=e.data.length>2?e.data[2]:void 0);var event={target:this,data:e.data,timestamp:e.timeStamp,channel:channel};command===wm.MIDI_CHANNEL_MESSAGES.noteoff||command===wm.MIDI_CHANNEL_MESSAGES.noteon&&0===data2?(event.type="noteoff",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.velocity=data2/127,event.rawVelocity=data2):command===wm.MIDI_CHANNEL_MESSAGES.noteon?(event.type="noteon",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.velocity=data2/127,event.rawVelocity=data2):command===wm.MIDI_CHANNEL_MESSAGES.keyaftertouch?(event.type="keyaftertouch",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.value=data2/127):command===wm.MIDI_CHANNEL_MESSAGES.controlchange&&data1>=0&&119>=data1?(event.type="controlchange",event.controller={number:data1,name:this.getCcNameByNumber(data1)},event.value=data2):command===wm.MIDI_CHANNEL_MESSAGES.channelmode&&data1>=120&&127>=data1?(event.type="channelmode",event.controller={number:data1,name:this.getChannelModeByNumber(data1)},event.value=data2):command===wm.MIDI_CHANNEL_MESSAGES.programchange?(event.type="programchange",event.value=data1):command===wm.MIDI_CHANNEL_MESSAGES.channelaftertouch?(event.type="channelaftertouch",event.value=data1/127):command===wm.MIDI_CHANNEL_MESSAGES.pitchbend?(event.type="pitchbend",event.value=((data2<<7)+data1-8192)/8192):event.type="unknownchannelmessage",this._userHandlers.channel[event.type]&&this._userHandlers.channel[event.type][channel]&&this._userHandlers.channel[event.type][channel].forEach(function(callback){callback(event)})},Input.prototype.getCcNameByNumber=function(number){if(number=Math.floor(number),!(number>=0&&119>=number))throw new RangeError("The control change number must be between 0 and 119.");for(var cc in wm.MIDI_CONTROL_CHANGE_MESSAGES)if(wm.MIDI_CONTROL_CHANGE_MESSAGES.hasOwnProperty(cc)&&number===wm.MIDI_CONTROL_CHANGE_MESSAGES[cc])return cc;return void 0},Input.prototype.getChannelModeByNumber=function(number){if(number=Math.floor(number),!(number>=120&&status<=127))throw new RangeError("The control change number must be between 120 and 127.");for(var cm in wm.MIDI_CHANNEL_MODE_MESSAGES)if(wm.MIDI_CHANNEL_MODE_MESSAGES.hasOwnProperty(cm)&&number===wm.MIDI_CHANNEL_MODE_MESSAGES[cm])return cm},Input.prototype._parseSystemEvent=function(e){var command=e.data[0],event={target:this,data:e.data,timestamp:e.timeStamp};command===wm.MIDI_SYSTEM_MESSAGES.sysex?event.type="sysex":command===wm.MIDI_SYSTEM_MESSAGES.timecode?event.type="timecode":command===wm.MIDI_SYSTEM_MESSAGES.songposition?event.type="songposition":command===wm.MIDI_SYSTEM_MESSAGES.songselect?(event.type="songselect",event.song=e.data[1]):command===wm.MIDI_SYSTEM_MESSAGES.tuningrequest?event.type="tuningrequest":command===wm.MIDI_SYSTEM_MESSAGES.clock?event.type="clock":command===wm.MIDI_SYSTEM_MESSAGES.start?event.type="start":command===wm.MIDI_SYSTEM_MESSAGES["continue"]?event.type="continue":command===wm.MIDI_SYSTEM_MESSAGES.stop?event.type="stop":command===wm.MIDI_SYSTEM_MESSAGES.activesensing?event.type="activesensing":command===wm.MIDI_SYSTEM_MESSAGES.reset?event.type="reset":event.type="unknownsystemmessage",this._userHandlers.system[event.type]&&this._userHandlers.system[event.type].forEach(function(callback){callback(event)})},Output.prototype.send=function(status,data,timestamp){if(!(status>=128&&255>=status))throw new RangeError("The status byte must be an integer between 128 (0x80) and 255 (0xFF).");void 0===data&&(data=[]),Array.isArray(data)||(data=[data]);var message=[];return data.forEach(function(item,index){var parsed=Math.floor(item);if(!(parsed>=0&&255>=parsed))throw new RangeError("Data bytes must be integers between 0 (0x00) and 255 (0xFF).");message.push(parsed)}),this._midiOutput.send([status].concat(message),parseFloat(timestamp)||0),this},Output.prototype.sendSysex=function(manufacturer,data,options){if(!wm.sysexEnabled)throw new Error("Sysex message support must first be activated.");return options=options||{},manufacturer=[].concat(manufacturer),data.forEach(function(item){if(0>item||item>127)throw new RangeError("The data bytes of a sysex message must be integers between 0 (0x00) and 127 (0x7F).")}),data=manufacturer.concat(data,wm.MIDI_SYSTEM_MESSAGES.sysexend),this.send(wm.MIDI_SYSTEM_MESSAGES.sysex,data,this._parseTimeParameter(options.time)),this},Output.prototype.sendTimecodeQuarterFrame=function(value,options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.timecode,value,this._parseTimeParameter(options.time)),this},Output.prototype.sendSongPosition=function(value,options){value=Math.floor(value)||0,options=options||{};var msb=value>>7&127,lsb=127&value;return this.send(wm.MIDI_SYSTEM_MESSAGES.songposition,[msb,lsb],this._parseTimeParameter(options.time)),this},Output.prototype.sendSongSelect=function(value,options){if(value=Math.floor(value),options=options||{},!(value>=0&&127>=value))throw new RangeError("The song number must be between 0 and 127.");return this.send(wm.MIDI_SYSTEM_MESSAGES.songselect,[value],this._parseTimeParameter(options.time)),this},Output.prototype.sendTuningRequest=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.tuningrequest,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendClock=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.clock,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendStart=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.start,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendContinue=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES["continue"],void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendStop=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.stop,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendActiveSensing=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.activesensing,[],this._parseTimeParameter(options.time)),this},Output.prototype.sendReset=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.reset,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.stopNote=function(note,channel,options){if("all"===note)return this.sendChannelMode("allnotesoff",0,channel,options);var nVelocity=64;return options=options||{},options.rawVelocity?!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=127&&(nVelocity=options.velocity):!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=1&&(nVelocity=127*options.velocity),this._convertNoteToArray(note).forEach(function(item){wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteoff<<4)+(ch-1),[item,Math.round(nVelocity)],this._parseTimeParameter(options.time))}.bind(this))}.bind(this)),this},Output.prototype.playNote=function(note,channel,options){var nVelocity=64;if(options=options||{},options.rawVelocity?!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=127&&(nVelocity=options.velocity):!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=1&&(nVelocity=127*options.velocity),options.time=this._parseTimeParameter(options.time),this._convertNoteToArray(note).forEach(function(item){wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteon<<4)+(ch-1),[item,Math.round(nVelocity)],options.time)}.bind(this))}.bind(this)),!isNaN(options.duration)){options.duration<=0&&(options.duration=0);var nRelease=64;options.rawVelocity?!isNaN(options.release)&&options.release>=0&&options.release<=127&&(nRelease=options.release):!isNaN(options.release)&&options.release>=0&&options.release<=1&&(nRelease=127*options.release),this._convertNoteToArray(note).forEach(function(item){wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteoff<<4)+(ch-1),[item,Math.round(nRelease)],(options.time||wm.time)+options.duration)}.bind(this))}.bind(this))}return this},Output.prototype.sendKeyAftertouch=function(note,channel,pressure,options){var that=this;if(options=options||{},1>channel||channel>16)throw new RangeError("The channel must be between 1 and 16.");(isNaN(pressure)||0>pressure||pressure>1)&&(pressure=.5);var nPressure=Math.round(127*pressure);return this._convertNoteToArray(note).forEach(function(item){wm.toMIDIChannels(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.keyaftertouch<<4)+(ch-1),[item,nPressure],that._parseTimeParameter(options.time))})}),this},Output.prototype.sendControlChange=function(controller,value,channel,options){if(options=options||{},"string"==typeof controller){if(controller=wm.MIDI_CONTROL_CHANGE_MESSAGES[controller],!controller)throw new TypeError("Invalid controller name.")}else if(controller=Math.floor(controller),!(controller>=0&&119>=controller))throw new RangeError("Controller numbers must be between 0 and 119.");if(value=Math.floor(value)||0,!(value>=0&&127>=value))throw new RangeError("Controller value must be between 0 and 127.");return wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.controlchange<<4)+(ch-1),[controller,value],this._parseTimeParameter(options.time))}.bind(this)),this},Output.prototype._selectRegisteredParameter=function(parameter,channel,time){var that=this;if(parameter[0]=Math.floor(parameter[0]),!(parameter[0]>=0&¶meter[0]<=127))throw new RangeError("The control65 value must be between 0 and 127");if(parameter[1]=Math.floor(parameter[1]),!(parameter[1]>=0&¶meter[1]<=127))throw new RangeError("The control64 value must be between 0 and 127");return wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(101,parameter[0],channel,{time:time}),that.sendControlChange(100,parameter[1],channel,{time:time})}),this},Output.prototype._selectNonRegisteredParameter=function(parameter,channel,time){var that=this;if(parameter[0]=Math.floor(parameter[0]),!(parameter[0]>=0&¶meter[0]<=127))throw new RangeError("The control63 value must be between 0 and 127");if(parameter[1]=Math.floor(parameter[1]),!(parameter[1]>=0&¶meter[1]<=127))throw new RangeError("The control62 value must be between 0 and 127");return wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(99,parameter[0],channel,{time:time}),that.sendControlChange(98,parameter[1],channel,{time:time})}),this},Output.prototype._setCurrentRegisteredParameter=function(data,channel,time){var that=this;if(data=[].concat(data),data[0]=Math.floor(data[0]),!(data[0]>=0&&data[0]<=127))throw new RangeError("The msb value must be between 0 and 127");return wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(6,data[0],channel,{time:time})}),data[1]=Math.floor(data[1]),data[1]>=0&&data[1]<=127&&wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(38,data[1],channel,{time:time})}),this},Output.prototype._deselectRegisteredParameter=function(channel,time){var that=this;return wm.toMIDIChannels(channel).forEach(function(ch){that.sendControlChange(101,127,channel,{time:time}),that.sendControlChange(100,127,channel,{time:time})}),this},Output.prototype.setRegisteredParameter=function(parameter,data,channel,options){var that=this;if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new Error("The specified parameter is not available.");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return wm.toMIDIChannels(channel).forEach(function(ch){that._selectRegisteredParameter(parameter,channel,options.time),that._setCurrentRegisteredParameter(data,channel,options.time),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.setNonRegisteredParameter=function(parameter,data,channel,options){var that=this;if(options=options||{},!(parameter[0]>=0&¶meter[0]<=127&¶meter[1]>=0&¶meter[1]<=127))throw new Error("Position 0 and 1 of the 2-position parameter array must both be between 0 and 127.");return data=[].concat(data),wm.toMIDIChannels(channel).forEach(function(ch){that._selectNonRegisteredParameter(parameter,channel,options.time),that._setCurrentRegisteredParameter(data,channel,options.time),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.incrementRegisteredParameter=function(parameter,channel,options){var that=this;if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new Error("The specified parameter is not available.");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return wm.toMIDIChannels(channel).forEach(function(ch){that._selectRegisteredParameter(parameter,channel,options.time),that.sendControlChange(96,0,channel,{time:options.time}),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.decrementRegisteredParameter=function(parameter,channel,options){if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new TypeError("The specified parameter is not available.");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return wm.toMIDIChannels(channel).forEach(function(ch){this._selectRegisteredParameter(parameter,channel,options.time),this.sendControlChange(97,0,channel,{time:options.time}),this._deselectRegisteredParameter(channel,options.time)}.bind(this)),this},Output.prototype.setPitchBendRange=function(semitones,cents,channel,options){var that=this;if(options=options||{},semitones=Math.floor(semitones)||0,!(semitones>=0&&127>=semitones))throw new RangeError("The semitones value must be between 0 and 127");if(cents=Math.floor(cents)||0,!(cents>=0&&127>=cents))throw new RangeError("The cents value must be between 0 and 127");return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter("pitchbendrange",[semitones,cents],channel,{time:options.time})}),this},Output.prototype.setModulationRange=function(semitones,cents,channel,options){var that=this;if(options=options||{},semitones=Math.floor(semitones)||0,!(semitones>=0&&127>=semitones))throw new RangeError("The semitones value must be between 0 and 127");if(cents=Math.floor(cents)||0,!(cents>=0&&127>=cents))throw new RangeError("The cents value must be between 0 and 127");return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter("modulationrange",[semitones,cents],channel,{time:options.time})}),this},Output.prototype.setMasterTuning=function(value,channel,options){var that=this;if(options=options||{},value=parseFloat(value)||0,-65>=value||value>=64)throw new RangeError("The value must be a decimal number larger than -65 and smaller than 64.");var coarse=Math.floor(value)+64,fine=value-Math.floor(value);fine=Math.round((fine+1)/2*16383);var msb=fine>>7&127,lsb=127&fine;return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter("channelcoarsetuning",coarse,channel,{time:options.time}),that.setRegisteredParameter("channelfinetuning",[msb,lsb],channel,{time:options.time})}),this},Output.prototype.setTuningProgram=function(value,channel,options){var that=this;if(options=options||{},value=Math.floor(value),!(value>=0&&127>=value))throw new RangeError("The program value must be between 0 and 127");return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter("tuningprogram",value,channel,{time:options.time})}),this},Output.prototype.setTuningBank=function(value,channel,options){var that=this;if(options=options||{},value=Math.floor(value)||0,!(value>=0&&127>=value))throw new RangeError("The bank value must be between 0 and 127");return wm.toMIDIChannels(channel).forEach(function(ch){that.setRegisteredParameter("tuningbank",value,channel,{time:options.time})}),this},Output.prototype.sendChannelMode=function(command,value,channel,options){if(options=options||{},"string"==typeof command){if(command=wm.MIDI_CHANNEL_MODE_MESSAGES[command],!command)throw new TypeError("Invalid channel mode message name.")}else if(command=Math.floor(command),!(command>=120&&127>=command))throw new RangeError("Channel mode numerical identifiers must be between 120 and 127.");if(value=Math.floor(value)||0,0>value||value>127)throw new RangeError("Value must be an integer between 0 and 127.");return wm.toMIDIChannels(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.channelmode<<4)+(ch-1),[command,value],this._parseTimeParameter(options.time))}.bind(this)),this},Output.prototype.sendProgramChange=function(program,channel,options){ +var that=this;if(options=options||{},program=Math.floor(program),isNaN(program)||0>program||program>127)throw new RangeError("Program numbers must be between 0 and 127.");return wm.toMIDIChannels(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.programchange<<4)+(ch-1),[program],that._parseTimeParameter(options.time))}),this},Output.prototype.sendChannelAftertouch=function(pressure,channel,options){var that=this;options=options||{},pressure=parseFloat(pressure),(isNaN(pressure)||0>pressure||pressure>1)&&(pressure=.5);var nPressure=Math.round(127*pressure);return wm.toMIDIChannels(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.channelaftertouch<<4)+(ch-1),[nPressure],that._parseTimeParameter(options.time))}),this},Output.prototype.sendPitchBend=function(bend,channel,options){var that=this;if(options=options||{},isNaN(bend)||-1>bend||bend>1)throw new RangeError("Pitch bend value must be between -1 and 1.");var nLevel=Math.round((bend+1)/2*16383),msb=nLevel>>7&127,lsb=127&nLevel;return wm.toMIDIChannels(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.pitchbend<<4)+(ch-1),[lsb,msb],that._parseTimeParameter(options.time))}),this},Output.prototype._parseTimeParameter=function(time){var parsed,value;return"string"==typeof time&&"+"===time.substring(0,1)?(parsed=parseFloat(time),parsed&&parsed>0&&(value=wm.time+parsed)):(parsed=parseFloat(time),parsed>wm.time&&(value=parsed)),value},Output.prototype._convertNoteToArray=function(note){var notes=[];return Array.isArray(note)||(note=[note]),note.forEach(function(item){notes.push(wm.guessNoteNumber(item))}),notes}, true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function(){return wm}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):"undefined"!=typeof module&&module.exports?module.exports=wm:scope.WebMidi||(scope.WebMidi=wm)}(this); + +/***/ }), +/* 156 */ +/***/ (function(module, exports) { + +module.exports = function() {
+ throw new Error("define cannot be used indirect");
+};
+ + +/***/ }), +/* 157 */ +/***/ (function(module, exports) { + +/* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {/* globals __webpack_amd_options__ */
+module.exports = __webpack_amd_options__;
+ +/* WEBPACK VAR INJECTION */}.call(exports, {})) + +/***/ }), +/* 158 */ +/***/ (function(module, exports) { + +/* (ignored) */ + +/***/ }) +/******/ ]); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgMGRhOTg4YjI5ZTQ0ZTdlYjJlYTMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fY29yZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL193a3MuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fZ2xvYmFsLmpzIiwid2VicGFjazovLy8uL34vYnVmZmVyL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2FuLW9iamVjdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19vYmplY3QtZHAuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fZXhwb3J0LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2hhcy5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19oaWRlLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3RvLWlvYmplY3QuanMiLCJ3ZWJwYWNrOi8vLy4vfi9wcm9jZXNzL2Jyb3dzZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fZHVwbGV4LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2ZhaWxzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2l0ZXJhdG9ycy5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19vYmplY3Qta2V5cy5qcyIsIndlYnBhY2s6Ly8vLi9+L2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fY29mLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2N0eC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pcy1vYmplY3QuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fcHJvcGVydHktZGVzYy5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3IuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLXV0aWwtaXMvbGliL3V0aWwuanMiLCJ3ZWJwYWNrOi8vLyh3ZWJwYWNrKS9idWlsZGluL2dsb2JhbC5qcyIsIndlYnBhY2s6Ly8vLi9+L3RvbmUvYnVpbGQvVG9uZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19saWJyYXJ5LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX29iamVjdC1waWUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fdG8tb2JqZWN0LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3VpZC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2xpYi91dGlsLmpzIiwid2VicGFjazovLy8uL34vYnVmZmVyLXNoaW1zL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2EtZnVuY3Rpb24uanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fY2xhc3NvZi5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19kZWZpbmVkLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2RvbS1jcmVhdGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fZW51bS1idWcta2V5cy5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19vYmplY3QtZ29wcy5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19zaGFyZWQta2V5LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3NoYXJlZC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL190by1pbnRlZ2VyLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3RvLWxlbmd0aC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL190by1wcmltaXRpdmUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fd2tzLWRlZmluZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL193a3MtZXh0LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kLmpzIiwid2VicGFjazovLy8uL34vZXZlbnRzL2V2ZW50cy5qcyIsIndlYnBhY2s6Ly8vLi9+L25vZGUtbGlicy1icm93c2VyL34vc3RyaW5nX2RlY29kZXIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9wcm9jZXNzLW5leHRpY2stYXJncy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV93cml0YWJsZS5qcyIsIndlYnBhY2s6Ly8vLi9+L3JlYWRhYmxlLXN0cmVhbS9yZWFkYWJsZS1icm93c2VyLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9saWIva2FsaW1iYS5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvbGliL3NjYWxlcy5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvbGliL3VpLmpzIiwid2VicGFjazovLy8uL34vYmFiZWwtcnVudGltZS9oZWxwZXJzL3NsaWNlZFRvQXJyYXkuanMiLCJ3ZWJwYWNrOi8vLy4vfi9uZXh1c3VpL2Rpc3QvTmV4dXNVSS5qcyIsIndlYnBhY2s6Ly8vLi9+L2JhYmVsLXJ1bnRpbWUvY29yZS1qcy9vYmplY3QvYXNzaWduLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2h0bWwuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9faWU4LWRvbS1kZWZpbmUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9faW9iamVjdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pcy1hcnJheS1pdGVyLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2l0ZXItY2FsbC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pdGVyLWRlZmluZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pdGVyLWRldGVjdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX29iamVjdC1nb3BuLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX29iamVjdC1rZXlzLWludGVybmFsLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3JlZGVmaW5lLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3Rhc2suanMiLCJ3ZWJwYWNrOi8vLy4vfi9pc2FycmF5L2luZGV4LmpzIiwid2VicGFjazovLy8uL34vcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzIiwid2VicGFjazovLy8uL34vcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qcyIsIndlYnBhY2s6Ly8vLi9+L3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0tYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly8vLi9+L3RpbWVycy1icm93c2VyaWZ5L21haW4uanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2RhdGEuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2xpYi9rZXlzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9saWIvbWlkaS5qcyIsIndlYnBhY2s6Ly8vLi9+L2JhYmVsLXJ1bnRpbWUvaGVscGVycy90b0FycmF5LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvbGliL2ludG9uYXRpb24uanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2xpYi9zdGFydEF1ZGlvQ29udGV4dC5qcyIsIndlYnBhY2s6Ly8vLi9+L2JhYmVsLXJ1bnRpbWUvY29yZS1qcy9hcnJheS9mcm9tLmpzIiwid2VicGFjazovLy8uL34vYmFiZWwtcnVudGltZS9jb3JlLWpzL2dldC1pdGVyYXRvci5qcyIsIndlYnBhY2s6Ly8vLi9+L2JhYmVsLXJ1bnRpbWUvY29yZS1qcy9pcy1pdGVyYWJsZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2JhYmVsLXJ1bnRpbWUvY29yZS1qcy9tYXRoL2xvZzIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9iYWJlbC1ydW50aW1lL2NvcmUtanMvb2JqZWN0L2tleXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9iYWJlbC1ydW50aW1lL2NvcmUtanMvcHJvbWlzZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2JhYmVsLXJ1bnRpbWUvY29yZS1qcy9zeW1ib2wuanMiLCJ3ZWJwYWNrOi8vLy4vfi9iYWJlbC1ydW50aW1lL2NvcmUtanMvc3ltYm9sL2l0ZXJhdG9yLmpzIiwid2VicGFjazovLy8uL34vYmFiZWwtcnVudGltZS9oZWxwZXJzL3R5cGVvZi5qcyIsIndlYnBhY2s6Ly8vLi9+L2Jhc2U2NC1qcy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9mbi9hcnJheS9mcm9tLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L2ZuL2dldC1pdGVyYXRvci5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9mbi9pcy1pdGVyYWJsZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9mbi9tYXRoL2xvZzIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvZm4vb2JqZWN0L2Fzc2lnbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9mbi9vYmplY3Qva2V5cy5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9mbi9wcm9taXNlLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L2ZuL3N5bWJvbC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9mbi9zeW1ib2wvaXRlcmF0b3IuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fYWRkLXRvLXVuc2NvcGFibGVzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2FuLWluc3RhbmNlLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2FycmF5LWluY2x1ZGVzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2NyZWF0ZS1wcm9wZXJ0eS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19lbnVtLWtleXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fZm9yLW9mLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2ludm9rZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pcy1hcnJheS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pdGVyLWNyZWF0ZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pdGVyLXN0ZXAuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fa2V5b2YuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fbWV0YS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19taWNyb3Rhc2suanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fb2JqZWN0LWFzc2lnbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19vYmplY3QtZHBzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX29iamVjdC1nb3BkLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX29iamVjdC1nb3BuLWV4dC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19vYmplY3QtZ3BvLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX29iamVjdC1zYXAuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fcmVkZWZpbmUtYWxsLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3NldC1zcGVjaWVzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3NwZWNpZXMtY29uc3RydWN0b3IuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fc3RyaW5nLWF0LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3RvLWluZGV4LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvY29yZS5nZXQtaXRlcmF0b3IuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9jb3JlLmlzLWl0ZXJhYmxlLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM2LmFycmF5LmZyb20uanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYuYXJyYXkuaXRlcmF0b3IuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYubWF0aC5sb2cyLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24uanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYub2JqZWN0LmtleXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYucHJvbWlzZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zeW1ib2wuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczcuc3ltYm9sLmFzeW5jLWl0ZXJhdG9yLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM3LnN5bWJvbC5vYnNlcnZhYmxlLmpzIiwid2VicGFjazovLy8uL34vY3N2LXBhcnNlL2xpYi9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2ZpbGUtc2F2ZXIvRmlsZVNhdmVyLmpzIiwid2VicGFjazovLy8uL34vaWVlZTc1NC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L21pZGktd3JpdGVyLWpzL2J1aWxkL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vbm90ZS1wYXJzZXIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vZHVwbGV4LWJyb3dzZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vbGliL2ludGVybmFsL3N0cmVhbXMvQnVmZmVyTGlzdC5qcyIsIndlYnBhY2s6Ly8vLi9+L3JlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qcyIsIndlYnBhY2s6Ly8vLi9+L3JlYWRhYmxlLXN0cmVhbS90cmFuc2Zvcm0uanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUtYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly8vLi9+L3NldGltbWVkaWF0ZS9zZXRJbW1lZGlhdGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9zdHJlYW0tYnJvd3NlcmlmeS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L3RvbmFsLW1pZGkvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi91dGlsLWRlcHJlY2F0ZS9icm93c2VyLmpzIiwid2VicGFjazovLy8uL34vdXRpbC9+L2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi91dGlsL3N1cHBvcnQvaXNCdWZmZXJCcm93c2VyLmpzIiwid2VicGFjazovLy8uL34vdXRpbC91dGlsLmpzIiwid2VicGFjazovLy8uL34vd2VibWlkaS93ZWJtaWRpLm1pbi5qcyIsIndlYnBhY2s6Ly8vKHdlYnBhY2spL2J1aWxkaW4vYW1kLWRlZmluZS5qcyIsIndlYnBhY2s6Ly8vKHdlYnBhY2spL2J1aWxkaW4vYW1kLW9wdGlvbnMuanMiLCJ3ZWJwYWNrOi8vL3V0aWwgKGlnbm9yZWQpIl0sIm5hbWVzIjpbImNob2ljZSIsIm1vZCIsIm5vcm0iLCJyZXF1ZXN0QXVkaW9Db250ZXh0IiwiZGF0YVVSSXRvQmxvYiIsImZ0b20iLCJtdG9mIiwidGFwIiwiZ2V0X2RpZmZfYm91bmRzIiwiZ2V0X2JvdW5kcyIsInRyYW5zcG9zZSIsImlzSXBob25lIiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwibWF0Y2giLCJpc0lwYWQiLCJpc0FuZHJvaWQiLCJpc01vYmlsZSIsImlzRGVza3RvcCIsImRvY3VtZW50IiwiYm9keSIsImNsYXNzTGlzdCIsImFkZCIsImJyb3dzZXIiLCJhIiwiTWF0aCIsImZsb29yIiwicmFuZG9tIiwibGVuZ3RoIiwibiIsIm0iLCJtaW4iLCJtYXgiLCJmbiIsImNvbnRhaW5lciIsImNyZWF0ZUVsZW1lbnQiLCJidXR0b24iLCJpbm5lckhUTUwiLCJzdHlsZSIsInBvc2l0aW9uIiwid2lkdGgiLCJoZWlnaHQiLCJ6SW5kZXgiLCJ0b3AiLCJsZWZ0IiwiYmFja2dyb3VuZENvbG9yIiwicGFkZGluZyIsImNvbG9yIiwiZm9udEZhbWlseSIsImJvcmRlclJhZGl1cyIsInRyYW5zZm9ybSIsInRleHRBbGlnbiIsImxpbmVIZWlnaHQiLCJhcHBlbmRDaGlsZCIsIlN0YXJ0QXVkaW9Db250ZXh0Iiwic2V0Q29udGV4dCIsIlRvbmUiLCJjb250ZXh0Iiwib24iLCJvblN0YXJ0ZWQiLCJyZW1vdmUiLCJkYXRhVVJJIiwiYnl0ZVN0cmluZyIsImF0b2IiLCJzcGxpdCIsIm1pbWVTdHJpbmciLCJhYiIsIkFycmF5QnVmZmVyIiwiaWEiLCJVaW50OEFycmF5IiwiaSIsImNoYXJDb2RlQXQiLCJibG9iIiwiQmxvYiIsInR5cGUiLCJmIiwicG93IiwiZSIsInByZXNzIiwicm93cyIsImRpZmZzIiwibWFwIiwicm93X21pbiIsImFwcGx5Iiwicm93Iiwicm93X21heCIsImRhdGFzZXQiLCJsaW5lcyIsInBhcnNlRmxvYXQiLCJyZWR1Y2UiLCJiIiwieiIsImJiIiwiSW5maW5pdHkiLCJpX2xlbiIsImpfbGVuIiwiVCIsIkFycmF5IiwiaiIsInBsYXllcl9jb3VudCIsInNhbXBsZV9pbmRleCIsImNvbXByZXNzb3IiLCJDb21wcmVzc29yIiwidG9NYXN0ZXIiLCJzYW1wbGVzIiwicm9vdCIsImZvckVhY2giLCJzYW1wbGUiLCJwbGF5ZXJzIiwiaW5kZXgiLCJ3aW5kb3ciLCJsb2NhdGlvbiIsImhyZWYiLCJwbGF5ZXIiLCJQbGF5ZXIiLCJ1cmwiLCJyZXRyaWdnZXIiLCJwbGF5YmFja1JhdGUiLCJjb25uZWN0IiwicHVzaCIsInBsYXkiLCJmcmVxIiwidm9sdW1lIiwiYmVzdCIsInZhbHVlIiwic2V0VGltZW91dCIsInN0YXJ0IiwibWVhbnRvbmUiLCJzaGFyZXMiLCJzaGFyZXNfc3VtIiwibWF2aWxhIiwiY2FybG9zX2FscGhhIiwibGFtb250ZSIsImNvbHVuZGkiLCJsaXVfbWFqb3IiLCJsaXVfcGVudGF0b25pYyIsImxpdV9taW5vciIsImxpdV9tZWxvZGljX21pbm9yIiwic2NhbGVzIiwiaW50ZXJ2YWxzIiwibmFtZSIsInRldCIsInNjbCIsIm9wdCIsIkludG9uYXRpb24iLCJzY2FsZSIsImhhbmRsZUNoYW5nZSIsImJ1aWxkIiwiaGVhZGluZyIsImFkZEV2ZW50TGlzdGVuZXIiLCJwaWNrIiwic2NhbGVfbGlzdCIsImJ1aWxkX29wdGlvbnMiLCJlbCIsIm9wdGlvbiIsInRhcmdldCIsImN1cnJlbnQiLCJvbkNoYW5nZSIsIm5hbWVzIiwidXBkYXRlX3ZhbHVlX29uX2NoYW5nZSIsInVwZGF0ZV9yYWRpb192YWx1ZV9vbl9jaGFuZ2UiLCJueCIsImlkIiwiaXNfaW50IiwibGFiZWwiLCJxdWVyeVNlbGVjdG9yIiwidXBkYXRlIiwicGFyc2VJbnQiLCJ2IiwidG9GaXhlZCIsInZhbHVlcyIsIm9sZF92IiwiYWN0aXZlIiwibGlzdHMiLCJsaXN0Iiwia2V5IiwiZmlsZXMiLCJwYXJzZSIsInJlcXVpcmUiLCJkYXRhUHJvbWlzZXMiLCJmZXRjaCIsInRoZW4iLCJ0ZXh0IiwicmVzb2x2ZSIsInJlamVjdCIsIl8iLCJoIiwic2hpZnQiLCJmaWx0ZXIiLCJzIiwiYWxsUHJvbWlzZXMiLCJhbGwiLCJkYXRhIiwibG9hZCIsImtleXMiLCJrZXlfbnVtYmVycyIsImxldHRlcnMiLCJudW1iZXJzIiwiY2FsbGJhY2siLCJ0b1VwcGVyQ2FzZSIsImsiLCJrZXlkb3duIiwiYWx0S2V5IiwiY3RybEtleSIsIm1ldGFLZXkiLCJzdG9wUHJvcGFnYXRpb24iLCJhY3RpdmVFbGVtZW50IiwiSFRNTElucHV0RWxlbWVudCIsImtleUNvZGUiLCJzaGlmdEtleSIsImxpc3RlbiIsIm1pZGlfaW5pdCIsInBsYXlfbm90ZSIsInBsYXlfbWlkaV9ub3RlIiwicGxheV9zZXF1ZW5jZSIsInBsYXlfaW50ZXJ2YWxfc2VxdWVuY2UiLCJleHBvcnRfcGF0dGVybl9hc19taWRpIiwibWlkaURldmljZSIsInNlbmRQaXRjaEJlbmQiLCJNaWRpV3JpdGVyIiwibm90ZV92YWx1ZXMiLCJXZWJNaWRpIiwiZW5hYmxlIiwibWlkaV9yZWFkeSIsImVyciIsImNvbnNvbGUiLCJlcnJvciIsIm91dHB1dHMiLCJsb2ciLCJpbnB1dHMiLCJmaWx0ZXJlZCIsIm91dHB1dCIsImR1cmF0aW9uIiwiY2hhbm5lbCIsImV4cG9ydGluZyIsInJlc3QiLCJkZWZlciIsInJvdW5kIiwib2Zmc2V0Iiwib2N0YXZlIiwibWlkaV9ub3RlIiwiY2VudHMiLCJub3RlIiwiRnJlcXVlbmN5IiwidG9Ob3RlIiwiZGVmZXJfdGltZSIsIlRyYW5zcG9ydCIsImJwbSIsImthbGltYmEiLCJwbGF5Tm90ZSIsImJvdW5kcyIsImRpZmYiLCJub3RlX3RpbWUiLCJjb3VudCIsInkiLCJ4IiwibXVsdGlwbHkiLCJyb3dfZjAiLCJyb3dfcm9vdCIsIm5vdGVzIiwiaW50ZXJ2YWwiLCJkYXRhc2V0TmFtZSIsInRlbXBvIiwidGltaW5nSW5kZXgiLCJwbGF5X2ZuIiwidGltaW5ncyIsIndhaXQiLCJtaWRpX3RyYWNrIiwiVHJhY2siLCJzZXRUZW1wbyIsImxlbiIsImFkZEV2ZW50IiwiTm90ZUV2ZW50IiwicGl0Y2giLCJ3cml0ZXIiLCJXcml0ZXIiLCJkYXRhVXJpIiwiREVGQVVMVF9CUE0iLCJyZWNvcmRlciIsInJlY29yZGluZyIsIm1hc3NfZmllbGRzIiwibWFzc19pIiwiZGF0YXNldHMiLCJndW5fdmlvbGVuY2VfYnlfbW9udGgiLCJtYXNzX3Nob290aW5nc19saXRlIiwicGxheV9tYXNzX3Nob290aW5ncyIsInJldmVyc2UiLCJkYXRlIiwibWluX3kiLCJkYXRlcyIsImQiLCJ0b3RhbF92aWN0aW1zIiwicmVhZHkiLCJtYXNzX3Jlc3QiLCJ0b3RhbCIsIm1pZGlfbm90ZXMiLCJjYXNlcyIsImNhc2UiLCJmYXRhbGl0aWVzIiwiaW5qdXJlZCIsImpvaW4iLCJwbGF5X25leHQiLCJ0aW1pbmciLCJuZXdfaSIsInBpY2tfZGF0YXNldCIsImRpYWxfc2l6ZSIsIk5leHVzIiwiRGlhbCIsInNpemUiLCJzdGVwIiwiUmFkaW9CdXR0b24iLCJudW1iZXJPZkJ1dHRvbnMiLCJleHBvcnRfbWlkaV9idXR0b24iLCJyZWNvcmRfbWlkaV9idXR0b24iLCJzYXZlQXMiLCJtb2R1bGUiLCJleHBvcnRzIiwiZ2VuZXJhdGUiLCJwcm90b3R5cGUiLCJnZW5lcmF0ZV9zY2wiLCJnZW5lcmF0ZV90ZXQiLCJnZW5lcmF0ZV9pbnRlcnZhbHMiLCJpbnRlcnZhbF9saXN0IiwicGFyc2VJbnRlcnZhbCIsImNhbGwiLCJwb3AiLCJwYXJzZUludGVydmFsU3RyaW5nIiwiYmluZCIsInJhdGlvIiwicGFyc2Vfc2NsIiwiZGVzY3JpcHRpb24iLCJjb21tZW50cyIsInRyaW0iLCJsaW5lIiwiaW5kZXhPZiIsInJlcGxhY2UiLCJyYW5nZSIsInNldF9yb290IiwicXVhbnRpemVfZnJlcXVlbmN5Iiwic2NhbGVfZiIsInF1YW50aXplX2luZGV4IiwicGFyc2VfaW50ZXJ2YWwiLCJwcCIsIm51bSIsImRlbiIsImlzTmFOIiwicGFyc2VfaW50ZXJ2YWxfc3RyaW5nIiwiZmFjdG9yeSIsImRlZmluZSIsIl90YXBMaXN0ZW5lcnMiLCJfb25TdGFydGVkIiwiY3R4IiwiZWxlbWVudCIsImlzQXJyYXkiLCJOb2RlTGlzdCIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJqcXVlcnkiLCJ0b0FycmF5IiwiRWxlbWVudCIsIlRhcExpc3RlbmVyIiwib25UYXAiLCJjYiIsImlzU3RhcnRlZCIsInN0YXRlIiwiX2RyYWdnZWQiLCJfZWxlbWVudCIsIl9iaW5kZWRNb3ZlIiwiX21vdmVkIiwiX2JpbmRlZEVuZCIsIl9lbmRlZCIsImRpc3Bvc2UiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwib3NjIiwiY3JlYXRlT3NjaWxsYXRvciIsInNpbGVudCIsImNyZWF0ZUdhaW4iLCJnYWluIiwiZGVzdGluYXRpb24iLCJub3ciLCJjdXJyZW50VGltZSIsInN0b3AiXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsbURBQTJDLGNBQWM7O0FBRXpEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUNBQTJCLDBCQUEwQixFQUFFO0FBQ3ZELHlDQUFpQyxlQUFlO0FBQ2hEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDhEQUFzRCwrREFBK0Q7O0FBRXJIO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7OztBQ2hFQSw2QkFBNkI7QUFDN0IscUNBQXFDLGdDOzs7Ozs7QUNEckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsdUI7Ozs7OztBQ1ZBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QyxnQzs7Ozs7OztBQ0h2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixtREFBbUQ7QUFDeEU7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixVQUFVO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixZQUFZO0FBQzdCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsdUNBQXVDLFNBQVM7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLGlCQUFpQjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsRUFBRTtBQUNsRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsZUFBZTtBQUN2QztBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBLHFCQUFxQixlQUFlO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixZQUFZO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBcUIsU0FBUztBQUM5QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGtCQUFrQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsbUJBQW1CLGNBQWM7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVEQUF1RCxPQUFPO0FBQzlEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1REFBdUQsT0FBTztBQUM5RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQkFBcUIsUUFBUTtBQUM3QjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQWlCO0FBQ2hDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLFlBQVk7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlCQUFpQixnQkFBZ0I7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsZ0JBQWdCO0FBQ2pDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixZQUFZO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7OztBQzV2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNKQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLFVBQVU7QUFDYjtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNmQTtBQUNBO0FBQ0EsaUNBQWlDLFFBQVEsZ0JBQWdCLFVBQVUsR0FBRztBQUN0RSxDQUFDLEU7Ozs7OztBQ0hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtRUFBbUU7QUFDbkU7QUFDQSxxRkFBcUY7QUFDckY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2QsY0FBYztBQUNkLGNBQWM7QUFDZCxjQUFjO0FBQ2QsZUFBZTtBQUNmLGVBQWU7QUFDZixlQUFlO0FBQ2YsZ0JBQWdCO0FBQ2hCLHlCOzs7Ozs7QUM1REEsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQSxFOzs7Ozs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsRTs7Ozs7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7OztBQ0xBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsc0JBQXNCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLFVBQVU7Ozs7Ozs7O0FDbkx0QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQ0FBZ0MsT0FBTztBQUN2QztBQUNBO0FBQ0EsQzs7Ozs7O0FDMUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsRTs7Ozs7O0FDTkEsb0I7Ozs7OztBQ0FBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRTs7Ozs7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUN0QkEsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0EsRTs7Ozs7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNuQkE7QUFDQTtBQUNBLEU7Ozs7OztBQ0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRTs7Ozs7OztBQ1BBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QixjQUFjO0FBQ2Q7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7QUFDQSxVQUFVO0FBQ1YsQ0FBQyxFOzs7Ozs7QUNoQkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDMUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0Q0FBNEM7O0FBRTVDOzs7Ozs7O0FDcEJBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUFBO0FBQ0gsRUFBRTtBQUNGO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUEsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixLQUFLO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLGNBQWM7QUFDNUIsY0FBYyxRQUFRO0FBQ3RCLGNBQWMsTUFBTTtBQUNwQixnQkFBZ0IsS0FBSztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLDBCQUEwQjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGNBQWM7QUFDOUIsY0FBYyx3QkFBd0I7QUFDdEM7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLG1CQUFtQjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDBCQUEwQjtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBLGNBQWM7QUFDZDtBQUNBLGNBQWM7QUFDZDtBQUNBLGNBQWM7QUFDZDtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxTQUFTO0FBQ3ZCLGVBQWUsTUFBTTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsc0JBQXNCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsTUFBTTtBQUNyQixlQUFlLE1BQU07QUFDckIsY0FBYyxnQkFBZ0I7QUFDOUIsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWLDRCQUE0QixpQkFBaUI7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixlQUFlLEVBQUU7QUFDakIsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyw2QkFBNkI7QUFDM0MsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0Isc0JBQXNCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEVBQUU7QUFDaEIsZ0JBQWdCLFFBQVE7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsRUFBRTtBQUNoQixnQkFBZ0IsUUFBUTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxFQUFFO0FBQ2hCLGdCQUFnQixRQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEVBQUU7QUFDaEIsZ0JBQWdCLFFBQVE7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrREFBK0Q7QUFDL0QsY0FBYyxFQUFFO0FBQ2hCLGdCQUFnQixRQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEVBQUU7QUFDaEIsZ0JBQWdCLFFBQVE7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsRUFBRTtBQUNoQixnQkFBZ0IsUUFBUTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxFQUFFO0FBQ2hCLGdCQUFnQixRQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsRUFBRTtBQUNoQixnQkFBZ0IsUUFBUTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUErQyxFQUFFO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixxQkFBcUI7QUFDakQ7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIscUJBQXFCO0FBQ2pEO0FBQ0E7QUFDQSxVQUFVO0FBQ1Ysb0RBQW9ELGlCQUFpQjtBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxZQUFZO0FBQzNCLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEIsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQztBQUN0Qyx1Q0FBdUM7QUFDdkMsd0NBQXdDO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEIsZUFBZSxVQUFVO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsYUFBYTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFF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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLGNBQWMsY0FBYztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxhQUFhO0FBQzVCLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQixlQUFlLEtBQUs7QUFDcEIsZUFBZSxRQUFRO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQixlQUFlLFFBQVE7QUFDdkIsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0Es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QUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQixjQUFjLEtBQUs7QUFDbkI7QUFDQSxjQUFjLEtBQUs7QUFDbkI7QUFDQSxjQUFjLFlBQVk7QUFDMUI7QUFDQSxjQUFjLEtBQUs7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFD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O0FBQ25CO0FBQ0EsY0FBYyxZQUFZO0FBQzFCO0FBQ0EsY0FBYyxLQUFLO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQix1QkFBdUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0Msa0JBQWtCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEIsY0FBYyxRQUFRO0FBQ3RCLGNBQWMsUUFBUTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxnQkFBZ0IsY0FBYztBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0EsY0FBYyxnQkFBZ0I7QUFDOUIsY0FBYyxTQUFTO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGdCQUFnQjtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQixjQUFjLFFBQVE7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixTQUFTO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQixjQUFjLFFBQVE7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsY0FBYztBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0EsY0FBYyxRQUFRO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGdCQUFnQjtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0Isb0JBQW9CO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZixhQUFhLFlBQVk7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsZUFBZTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLGNBQWMsaUJBQWlCO0FBQy9CLGNBQWMsUUFBUTtBQUN0QixjQUFjLFFBQVE7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLDBCQUEwQjtBQUN0RDtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsMEJBQTBCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHdCQUF3QjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGVBQWUsWUFBWTtBQUMzQjtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsMEJBQTBCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBLGNBQWMsaUJBQWlCO0FBQy9CLGNBQWMsVUFBVTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBLGNBQWMsZ0JBQWdCO0FBQzlCLGNBQWMsU0FBUztBQUN2QixjQUFjLFNBQVM7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixTQUFTO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEIsY0FBYyxPQUFPO0FBQ3JCLGNBQWMsT0FBTztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixXQUFXO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLGNBQWMsT0FBTztBQUNyQixjQUFjLE9BQU87QUFDckIsY0FBYyxPQUFPO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxnQkFBZ0IsY0FBYztBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLGNBQWMsTUFBTTtBQUNwQixjQUFjLE1BQU07QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsZ0JBQWdCLFdBQVc7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxjQUFjLFlBQVk7QUFDMUIsY0FBYyxhQUFhO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHdCQUF3QjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEIsY0FBYyxRQUFRO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGdCQUFnQixTQUFTO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsU0FBUztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQixjQUFjLFlBQVk7QUFDMUIsY0FBYyxNQUFNO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLEtBQUs7QUFDckIsZ0JBQWdCLEtBQUs7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixjQUFjO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBLGNBQWMsWUFBWTtBQUMxQixjQUFjLEtBQUs7QUFDbkIsY0FBYyxPQUFPO0FBQ3JCLGNBQWMsS0FBSztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGdCQUFnQixvQkFBb0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxjQUFjLFlBQVk7QUFDMUIsY0FBYyxLQUFLO0FBQ25CLGNBQWMsT0FBTztBQUNyQixjQUFjLEtBQUs7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGdCQUFnQix1QkFBdUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHFCQUFxQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLGNBQWMsT0FBTztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGlCQUFpQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLGNBQWMsZ0JBQWdCO0FBQzlCLGNBQWMsTUFBTTtBQUNwQixjQUFjLE1BQU07QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsZ0JBQWdCLFVBQVU7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFNBQVM7QUFDdkIsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsT0FBTztBQUNyQixjQUFjLEtBQUs7QUFDbkIsY0FBYyxPQUFPO0FBQ3JCLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLGVBQWU7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsS0FBSztBQUNwQixnQkFBZ0IsZ0JBQWdCO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLGVBQWU7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEtBQUs7QUFDbkIsY0FBYyxNQUFNO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsS0FBSztBQUNuQixjQUFjLE1BQU07QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxNQUFNO0FBQ25CLGNBQWMsS0FBSztBQUNuQixjQUFjLFFBQVE7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsTUFBTTtBQUNwQixjQUFjLEtBQUs7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLE1BQU07QUFDcEIsY0FBYyxLQUFLO0FBQ25CLGNBQWMsVUFBVTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEtBQUs7QUFDbkIsY0FBYyxLQUFLO0FBQ25CLGNBQWMsV0FBVztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEIsY0FBYyxPQUFPO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGdCQUFnQixPQUFPO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZ0JBQWdCLG1CQUFtQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsV0FBVztBQUN6QixlQUFlLEtBQUs7QUFDcEIsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsUUFBUTtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxXQUFXO0FBQ3pCLGVBQWUsS0FBSztBQUNwQixnQkFBZ0IsT0FBTztBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDJCQUEyQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsVUFBVTtBQUMzQixnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxlQUFlLE1BQU07QUFDckIsY0FBYyxRQUFRO0FBQ3RCLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEtBQUs7QUFDbkIsZ0JBQWdCLGdCQUFnQjtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxLQUFLO0FBQ25CLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEtBQUs7QUFDbkIsZ0JBQWdCLGdCQUFnQjtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEtBQUs7QUFDbkIsY0FBYyxNQUFNO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsZUFBZSxLQUFLO0FBQ3BCLGdCQUFnQixRQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLE1BQU07QUFDcEIsY0FBYyxLQUFLO0FBQ25CLGNBQWMsZ0JBQWdCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEtBQUs7QUFDcEIsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTtBQUNBLG1DQUFtQztBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLE1BQU07QUFDcEIsY0FBYyxNQUFNO0FBQ3BCLGNBQWMsS0FBSztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEtBQUs7QUFDcEIsZUFBZSxLQUFLO0FBQ3BCLGVBQWUscUJBQXFCO0FBQ3BDLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsZ0JBQWdCO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEIsY0FBYyxTQUFTO0FBQ3ZCLGNBQWMsVUFBVTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLGVBQWUsTUFBTTtBQUNyQixlQUFlLE9BQU87QUFDdEIsZ0JBQWdCLFdBQVc7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsS0FBSztBQUNuQixnQkFBZ0IsV0FBVztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEtBQUs7QUFDbkIsZ0JBQWdCLFdBQVc7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxlQUFlLEtBQUs7QUFDcEIsZ0JBQWdCLFFBQVE7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxNQUFNO0FBQ3BCLGNBQWMsS0FBSztBQUNuQixjQUFjLFdBQVc7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEtBQUs7QUFDbkIsY0FBYyxNQUFNO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsTUFBTTtBQUNwQixjQUFjLEtBQUs7QUFDbkIsY0FBYyxXQUFXO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQixnQkFBZ0IsT0FBTztBQUN2QjtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFdBQVc7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGdCQUFnQixzQkFBc0I7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsZ0JBQWdCLHNCQUFzQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLG9CQUFvQjtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGdCQUFnQixzQkFBc0I7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLGFBQWE7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsYUFBYTtBQUM1QixlQUFlLGFBQWE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGFBQWE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBLFVBQVU7QUFDVjtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxhQUFhO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGFBQWE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsYUFBYTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0Msb0JBQW9CO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEIsZ0JBQWdCLHNCQUFzQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2QsNEJBQTRCLHFCQUFxQjtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsU0FBUztBQUN4QixnQkFBZ0Isc0JBQXNCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsUUFBUTtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsU0FBUztBQUN4QixnQkFBZ0Isc0JBQXNCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsUUFBUTtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHNCQUFzQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQSx3QkFBd0IscUJBQXFCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxPQUFPO0FBQ3JCLGNBQWMsT0FBTztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsYUFBYTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsTUFBTTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE1BQU07QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQSxVQUFVO0FBQ1Y7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixPQUFPO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixRQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQixlQUFlLGNBQWM7QUFDN0IsZUFBZSxRQUFRO0FBQ3ZCO0FBQ0EsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxPQUFPO0FBQ3JCLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsUUFBUTtBQUN0QixnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLE1BQU07QUFDcEIsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEIsY0FBYyxPQUFPO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsS0FBSztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxvQkFBb0I7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLGNBQWMsT0FBTztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLE9BQU87QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsMEJBQTBCO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsT0FBTztBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxTQUFTO0FBQ3ZCLGNBQWMsY0FBYztBQUM1QixlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEIsZUFBZSxLQUFLO0FBQ3BCO0FBQ0EsZUFBZSxlQUFlO0FBQzlCO0FBQ0EsY0FBYyxLQUFLO0FBQ25CLGdCQUFnQixPQUFPO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFNBQVM7QUFDdkIsY0FBYyxjQUFjO0FBQzVCLGdCQUFnQixPQUFPO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsT0FBTztBQUNyQixnQkFBZ0IsZUFBZTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsb0JBQW9CO0FBQ2pDLGFBQWEsY0FBYztBQUMzQixlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsY0FBYztBQUM1QjtBQUNBLGdCQUFnQixlQUFlO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsZUFBZSxLQUFLO0FBQ3BCLGVBQWUsZUFBZTtBQUM5QixnQkFBZ0IsZUFBZTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxLQUFLO0FBQ3BCLGdCQUFnQixlQUFlO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQixnQkFBZ0IsZUFBZTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxNQUFNO0FBQ3BCLGNBQWMsZUFBZTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGNBQWMsY0FBYztBQUM1QixjQUFjLGNBQWM7QUFDNUIsZ0JBQWdCLGVBQWU7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGNBQWMsS0FBSztBQUNuQixjQUFjLE1BQU07QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxLQUFLO0FBQ3BCLGdCQUFnQixRQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxlQUFlLElBQUk7QUFDbkIsZ0JBQWdCLFVBQVU7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsZ0JBQWdCLElBQUk7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEtBQUs7QUFDcEIsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxZQUFZO0FBQzNCLGNBQWMsUUFBUTtBQUN0QjtBQUNBO0FBQ0EsZ0JBQWdCLGVBQWU7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsWUFBWTtBQUMzQixnQkFBZ0IsZUFBZTtBQUMvQjtBQUNBO0FBQ0EscURBQXFELFFBQVE7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixlQUFlO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBLGNBQWMsU0FBUztBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGdCQUFnQixZQUFZO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLGNBQWMsZUFBZTtBQUM3QjtBQUNBLGdCQUFnQixZQUFZO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsZUFBZTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEtBQUs7QUFDcEIsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEtBQUs7QUFDcEIsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3Qiw0QkFBNEI7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxZQUFZO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLG9CQUFvQjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsaUJBQWlCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEIsY0FBYyxtQkFBbUI7QUFDakMsY0FBYyxVQUFVO0FBQ3hCO0FBQ0E7QUFDQSxjQUFjLFVBQVU7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLHdCQUF3QjtBQUN0QyxnQkFBZ0IsWUFBWTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxZQUFZO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLE9BQU87QUFDckI7QUFDQTtBQUNBLGdCQUFnQixRQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2QsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLGNBQWMsYUFBYTtBQUMzQixlQUFlLFlBQVk7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLGNBQWM7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFFBQVE7QUFDdEIsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxrQ0FBa0MsdUJBQXVCO0FBQ3pEO0FBQ0EsZ0NBQWdDLHlCQUF5QjtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFFBQVE7QUFDdEIsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0EsVUFBVTtBQUNWO0FBQ0EsNEJBQTRCLDJCQUEyQjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixnQkFBZ0IsYUFBYTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsS0FBSztBQUNuQixjQUFjLE1BQU07QUFDcEI7QUFDQSxlQUFlLFlBQVk7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLDJCQUEyQjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxZQUFZO0FBQzNCO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QiwyQkFBMkI7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsYUFBYTtBQUMzQixlQUFlLFlBQVk7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLE9BQU87QUFDckIsY0FBYyxxQkFBcUI7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsT0FBTztBQUNyQixjQUFjLFNBQVM7QUFDdkIsY0FBYyxTQUFTO0FBQ3ZCLGNBQWMsU0FBUztBQUN2QixlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLHVCQUF1QjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLHVDQUF1QztBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQixjQUFjO0FBQ2Q7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsT0FBTztBQUNyQixlQUFlLFFBQVE7QUFDdkI7QUFDQTtBQUNBLHFDQUFxQztBQUNyQyxrREFBa0Q7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEIsZUFBZSx3QkFBd0I7QUFDdkMsZUFBZSxTQUFTO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQixnQkFBZ0IsV0FBVztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsTUFBTTtBQUN2QixpQkFBaUIsZUFBZTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGFBQWE7QUFDOUIsaUJBQWlCLGVBQWU7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsTUFBTTtBQUN2QixpQkFBaUIsZUFBZTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxnQkFBZ0Isb0JBQW9CO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQixjQUFjLFVBQVU7QUFDeEIsY0FBYyxPQUFPO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEtBQUs7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEtBQUs7QUFDcEIsZ0JBQWdCLGdCQUFnQjtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxNQUFNO0FBQ3BCLGNBQWMsZ0JBQWdCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGdCQUFnQjtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsTUFBTTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0Isc0JBQXNCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsYUFBYTtBQUM1QixlQUFlLGFBQWE7QUFDNUIsZUFBZSxZQUFZO0FBQzNCLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLFNBQVM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixPQUFPO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsZUFBZSxnQkFBZ0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixpQkFBaUI7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixVQUFVO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEIsY0FBYyxpQkFBaUI7QUFDL0I7QUFDQSxjQUFjLFFBQVE7QUFDdEIsY0FBYyxRQUFRO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxLQUFLO0FBQ3BCLGdCQUFnQixTQUFTO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQixnQkFBZ0IsU0FBUztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixTQUFTO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFNBQVM7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsOEJBQThCO0FBQzdDLGNBQWMsT0FBTztBQUNyQixjQUFjLE9BQU87QUFDckIsZ0JBQWdCLFNBQVM7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixTQUFTO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxjQUFjLE9BQU87QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0EsZ0JBQWdCLGFBQWE7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxjQUFjLFlBQVk7QUFDMUIsY0FBYyxhQUFhO0FBQzNCLGNBQWMsV0FBVztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQix1QkFBdUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsV0FBVztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLGNBQWMsT0FBTztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsdUJBQXVCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixVQUFVO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0EsY0FBYyxPQUFPO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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Q0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtB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QUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7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QUFDTjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsZ0JBQWdCLGNBQWM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLEVB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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsYUFBYTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLGNBQWMsWUFBWTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFD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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxNQUFNO0FBQ3JCLGVBQWUsTUFBTTtBQUNyQixnQkFBZ0Isa0JBQWtCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0Isa0JBQWtCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGdCQUFnQixhQUFhO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQixjQUFjLFNBQVM7QUFDdkIsY0FBYyxFQUFFO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEtBQUs7QUFDbkIsZ0JBQWdCLFdBQVc7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEMsZ0JBQWdCLFdBQVc7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFpQjtBQUNoQyxnQkFBZ0IsV0FBVztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEMsZ0JBQWdCLFdBQVc7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxnQkFBZ0IsV0FBVztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxn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O0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxnQkFBZ0IsVUFBVTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7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QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEtBQUs7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGVBQWUscUJBQXFCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxLQUFLO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEtBQUs7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsZUFBZSxrQkFBa0I7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QkFBZ0I7QUFDaEI7QUFDQSxjQUFjLFVBQVU7QUFDeEIsY0FBYyxPQUFPO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsS0FBSztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsS0FBSztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0EsY0FBYztBQUNkO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsS0FBSztBQUNuQixjQUFjLFlBQVk7QUFDMUIsZ0JBQWdCLGVBQWU7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxLQUFLO0FBQ25CLGdCQUFnQixlQUFlO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGVBQWU7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLGNBQWMsT0FBTztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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Q0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxLQUFLO0FBQ3BCLGVBQWUsS0FBSztBQUNwQjtBQUNBLGVBQWUsTUFBTTtBQUNyQjtBQUNBO0FBQ0EsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEtBQUs7QUFDcEIsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQTtBQUNBO0FB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Q0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGVBQWUsY0FBYztBQUM3QjtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsU0FBUztBQUN2QixjQUFjLGFBQWE7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLCtCQUErQjtBQUM5QztBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxLQUFLO0FBQ2xCLGNBQWMsYUFBYTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxlQUFlLGFBQWE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQixjQUFjLFVBQVU7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGNBQWM7QUFDN0I7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZCxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsZUFBZSxlQUFlO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZCxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLGNBQWMsZUFBZTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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Ozs7Ozs4Q0M1SUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7OztBQzNHQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixrQkFBa0IsRUFBRTs7QUFFN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLFVBQVU7QUFDYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNOQTtBQUNBO0FBQ0E7QUFDQSxhOzs7Ozs7QUNIQSx5Qzs7Ozs7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNKQTtBQUNBO0FBQ0EsbURBQW1EO0FBQ25EO0FBQ0EsdUNBQXVDO0FBQ3ZDLEU7Ozs7OztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRDtBQUMzRCxFOzs7Ozs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRTs7Ozs7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQTBELHNCQUFzQjtBQUNoRixnRkFBZ0Ysc0JBQXNCO0FBQ3RHLEU7Ozs7OztBQ1JBLG1DOzs7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7OztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQixPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsR0FBRztBQUNILG9CQUFvQixTQUFTO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7O0FDN1NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFRLE9BQU87QUFDZjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7OytDQzVOQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOzs7Ozs7Ozs7QUMxQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMLEdBQUc7QUFDSCxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQ0FBaUM7O0FBRWpDOztBQUVBLDJDQUEyQztBQUMzQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRDtBQUNuRDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQ0FBb0M7O0FBRXBDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsb0RBQW9EO0FBQ3BEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0Q0FBNEM7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsQzs7Ozs7OztBQy9oQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxNQUFNO0FBQ047O0FBRUE7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7O0FBRUE7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCOztBQUVBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047O0FBRUE7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7O0FBRUE7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCOztBQUVBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047O0FBRUE7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0EsRUFBRTs7QUFFRjs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0EsSUFBSTs7QUFFSjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsb0JBQW9CLG1CQUFtQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTztBQUNQO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQixhQUFhLE9BQU87QUFDcEIsYUFBYSxPQUFPO0FBQ3BCLGFBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQixhQUFhLE9BQU87QUFDcEIsYUFBYSxPQUFPO0FBQ3BCLGFBQWEsT0FBTztBQUNwQixhQUFhLE9BQU87QUFDcEIsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLE9BQU87QUFDcEIsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCLGFBQWEsT0FBTztBQUNwQixhQUFhLE9BQU87QUFDcEIsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQixhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLE9BQU87QUFDcEIsYUFBYSxPQUFPO0FBQ3BCLGFBQWEsT0FBTztBQUNwQjtB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCLE9BQU87QUFDOUIsd0JBQXdCLE9BQU87QUFDL0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBLEVBQUU7O0FBRUY7O0FBRUEsT0FBTztBQUNQO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBLE9BQU87QUFDUDtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQixRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixTQUFTO0FBQ3pCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxJQUFJO0FBQ0oscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBLE9BQU87QUFDUDtBQUNBOztBQUVBOztBQUVBLGtDQUFrQywyQ0FBMkMseUJBQXlCLHVCQUF1QiwwQkFBMEIsc0NBQXNDLEVBQUUsd0NBQXdDLEVBQUUseURBQXlELHFFQUFxRSw2REFBNkQsb0JBQW9CLEdBQUcsRUFBRTs7QUFFN2IseURBQXlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFL0o7O0FBRUE7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixhQUFhLE9BQU87QUFDcEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLDJCQUEyQixhQUFhO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlCQUFpQixPQUFPO0FBQ3hCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047O0FBRUE7QUFDQTtBQUNBLGlCQUFpQixPQUFPO0FBQ3hCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQSxFQUFFOztBQUVGOztBQUVBLE9BQU87QUFDUDtBQUNBOztBQUVBOztBQUVBLHVDQUF1QyxxREFBcUQ7O0FBRTVGLGtDQUFrQywyQ0FBMkMseUJBQXlCLHVCQUF1QiwwQkFBMEIsc0NBQXNDLEVBQUUsd0NBQXdDLEVBQUUseURBQXlELHFFQUFxRSw2REFBNkQsb0JBQW9CLEdBQUcsRUFBRTs7QUFFN2IseURBQXlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFL0o7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsdUNBQXVDOztBQUV2Qzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQztBQUNqQztBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0EsRUFBRTs7QUFFRixPQUFPO0FBQ1A7QUFDQTs7QUFFQTs7QUFFQSxrQ0FBa0MsMkNBQTJDLHlCQUF5Qix1QkFBdUIsMEJBQTBCLHNDQUFzQyxFQUFFLHdDQUF3QyxFQUFFLHlEQUF5RCxxRUFBcUUsNkRBQTZELG9CQUFvQixHQUFHLEVBQUU7O0FBRTdiLHlEQUF5RCwwQ0FBMEMsMERBQTBELEVBQUU7O0FBRS9KO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0EsRUFBRTs7QUFFRjs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTs7QUFFQSwrQ0FBK0MsdUNBQXVDLGtCQUFrQjs7QUFFeEcsa0NBQWtDLDJDQUEyQyx5QkFBeUIsdUJBQXVCLDBCQUEwQixzQ0FBc0MsRUFBRSx3Q0FBd0MsRUFBRSx5REFBeUQscUVBQXFFLDZEQUE2RCxvQkFBb0IsR0FBRyxFQUFFOztBQUU3YixzREFBc0QsOERBQThELDBCQUEwQiw0Q0FBNEMsdUJBQXVCLGtCQUFrQixFQUFFLE9BQU8sd0NBQXdDLEVBQUUsRUFBRSw2Q0FBNkMsbUJBQW1CLEVBQUUsT0FBTyx1QkFBdUIsNEJBQTRCLGtCQUFrQixFQUFFLDhCQUE4QixFQUFFOztBQUV4YyxrREFBa0QsK0RBQStELHFHQUFxRyxFQUFFLHlFQUF5RSxlQUFlLHlFQUF5RSxFQUFFLEVBQUUsaURBQWlEOztBQUU5YSx5REFBeUQsMENBQTBDLDBEQUEwRCxFQUFFOztBQUUvSjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsbUNBQW1DOztBQUVuQzs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbURBQW1EO0FBQ25EO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNB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QTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047O0FBRUE7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0EsY0FBYztBQUNk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QUNOO0FBQ0E7QUFDQSx3QkFBd0IsdUJBQXVCO0FBQy9DO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsT0FBTztBQUMxQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTs7QUFFVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7O0FBRVY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBLEVBQUU7O0FBRUY7O0FBRUEsT0FBTztBQUNQO0FBQ0E7O0FBRUE7O0FBRUEsdUNBQXVDLHFEQUFxRDs7QUFFNUYsa0NBQWtDLDJDQUEyQyx5QkFBeUIsdUJBQXVCLDBCQUEwQixzQ0FBc0MsRUFBRSx3Q0FBd0MsRUFBRSx5REFBeUQscUVBQXFFLDZEQUE2RCxvQkFBb0IsR0FBRyxFQUFFOztBQUU3Yix5REFBeUQsMENBQTBDLDBEQUEwRCxFQUFFOztBQUUvSjs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrRUFBa0U7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLHdCQUF3QixtQkFBbUI7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLHdCQUF3QixnQkFBZ0I7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsZ0JBQWdCO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCLFlBQVk7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsaUJBQWlCO0FBQzNDO0FBQ0E7QUFDQTtBQUNBLCtCQUErQix1QkFBdUI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxN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ZUFBZSx5RUFBeUUsRUFBRSxFQUFFLGlEQUFpRDs7QUFFOWEseURBQXlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFL0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxVQUFVO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFROztBQUVSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTs7QUFFUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSx3Q0FBd0M7QUFDeEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0Q0FBNEM7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7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QUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0EsUUFBUTtBQUNSOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsVUFBVTs7QUFFVjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUEsd0JBQXdCLHVCQUF1QjtBQUMvQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOEJBQThCLHVCQUF1QjtBQUNyRCxVQUFVO0FBQ1Y7QUFDQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsVUFBVTs7QUFF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QTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaURBQWlEO0FBQ2pEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBLFlBQVk7O0FBRVo7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBLEVBQUU7O0FBRUY7O0FBRUEsT0FBTztBQUNQO0FBQ0E7O0FBRUE7O0FBRUEsdUNBQXVDLHFEQUFxRDs7QUFFNUY7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0JBQWtCLCtCQUErQjtBQUNqRDtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0Esa0JBQWtCLHlCQUF5QjtBQUMzQztBQUNBO0FBQ0Esa0JBQWtCLHFCQUFxQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLE9BQU87QUFDUDtBQUNBOztBQUVBOztBQUVBLHVDQUF1QyxxREFBcUQ7O0FBRTVGLGtDQUFrQywyQ0FBMkMseUJBQXlCLHVCQUF1QiwwQkFBMEIsc0NBQXNDLEVBQUUsd0NBQXdDLEVBQUUseURBQXlELHFFQUFxRSw2REFBNkQsb0JBQW9CLEdBQUcsRUFBRTs7QUFFN2IseURBQXlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFL0o7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsK0JBQStCOztBQUUvQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0EsVUFBVTtBQUNWO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixzQkFBc0I7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLHNCQUFzQjtBQUM5QztBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLHNCQUFzQjtBQUM5QztBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047O0FBRUE7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QixrQkFBa0I7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQSxFQUFFOztBQUVGOztBQUVBLE9BQU87QUFDUDtBQUNBOztBQUVBOztBQUVBLGtDQUFrQywyQ0FBMkMseUJBQXlCLHVCQUF1QiwwQkFBMEIsc0NBQXNDLEVBQUUsd0NBQXdDLEVBQUUseURBQXlELHFFQUFxRSw2REFBNkQsb0JBQW9CLEdBQUcsRUFBRTs7QUFFN2IseURBQXlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFL0o7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsNkZBQTZGLGFBQWE7QUFDMUc7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLGtGQUFrRixhQUFhO0FBQy9GO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCO0FBQzFCO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEIsa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxrRkFBa0YsYUFBYTtBQUMvRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0Esa0ZBQWtGLGFBQWE7QUFDL0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTs7QUFFTjtBQUNBLEVBQUU7O0FBRUY7O0FBRUEsT0FBTztBQUNQO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7O0FBR0EsT0FBTztBQUNQO0FBQ0E7O0FBRUEsZ0RBQWdEOztBQUVoRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMENBQTBDOztBQUUxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7QUFDSjtBQUNBOztBQUVBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLGlDQUFpQztBQUNwRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MsZUFBZTtBQUNyRDtBQUNBLE1BQU07O0FBRU47QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qjs7QUFFN0IsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixzQkFBc0I7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNDQUFzQzs7QUFFdEM7QUFDQTtB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0Esc0RBQXNEOztBQUV0RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0RUFBNEU7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZEQUE2RDtBQUM3RDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esc0NBQXNDOztBQUV0QztBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJEO0FBQzNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLCtDQUErQzs7QUFFL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNEVBQTRFOztBQUU1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIseUJBQXlCO0FBQzFDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1EQUFtRDtBQUNuRDtBQUNBLG1EQUFtRCxpRUFBaUU7QUFDcEg7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUM7QUFDdkMsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUM7QUFDdkMsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdDQUFnQyxPQUFPO0FBQ3ZDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdDQUFnQyxPQUFPO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBLEM7Ozs7Ozs7O0FDdDZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxZQUFZO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCLGlCQUFpQjtBQUNqQiw4QkFBOEI7QUFDOUIsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0Q7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDREQUE0RCxlQUFlO0FBQzNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0Esb0RBQW9ELFdBQVc7QUFDL0Q7QUFDQSxLQUFLO0FBQ0wsb0VBQW9FLFdBQVc7QUFDL0U7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyxTQUFTO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMENBQTBDLHNCQUFzQixFQUFFO0FBQ2xFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxVQUFVO0FBQ1Y7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOzs7Ozs7OztBQ3pMRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7Ozs7QUFJQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNB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QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNENBQTRDLEtBQUs7O0FBRWpEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQSxtQ0FBbUMsT0FBTztBQUMxQztBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOzs7QUFHQTtBQUNBO0FBQ0EseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYLFNBQVM7QUFDVDtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7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T0FBTyxxREFBcUQsaUJBQWlCLHlMQUF5TCxxREFBcUQsYUFBYSxzRUFBc0UscUNBQXFDLFFBQVEsdUZBQTZFLFVBQVU7QUFBQSxvTUFBaUcsTzs7Ozs7O0FDOUJ4eEQ7QUFDQTtBQUNBOzs7Ozs7O0FDRkE7QUFDQTs7Ozs7Ozs7QUNEQSxlIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbiBcdFx0fVxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2UsXG4gXHRcdFx0ZXhwb3J0czoge31cbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gaWRlbnRpdHkgZnVuY3Rpb24gZm9yIGNhbGxpbmcgaGFybW9ueSBpbXBvcnRzIHdpdGggdGhlIGNvcnJlY3QgY29udGV4dFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5pID0gZnVuY3Rpb24odmFsdWUpIHsgcmV0dXJuIHZhbHVlOyB9O1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbiBcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbiBcdFx0XHR9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSA4MCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay9ib290c3RyYXAgMGRhOTg4YjI5ZTQ0ZTdlYjJlYTMiLCJ2YXIgY29yZSA9IG1vZHVsZS5leHBvcnRzID0ge3ZlcnNpb246ICcyLjQuMCd9O1xuaWYodHlwZW9mIF9fZSA9PSAnbnVtYmVyJylfX2UgPSBjb3JlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19jb3JlLmpzXG4vLyBtb2R1bGUgaWQgPSAwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBzdG9yZSAgICAgID0gcmVxdWlyZSgnLi9fc2hhcmVkJykoJ3drcycpXG4gICwgdWlkICAgICAgICA9IHJlcXVpcmUoJy4vX3VpZCcpXG4gICwgU3ltYm9sICAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLlN5bWJvbFxuICAsIFVTRV9TWU1CT0wgPSB0eXBlb2YgU3ltYm9sID09ICdmdW5jdGlvbic7XG5cbnZhciAkZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24obmFtZSl7XG4gIHJldHVybiBzdG9yZVtuYW1lXSB8fCAoc3RvcmVbbmFtZV0gPVxuICAgIFVTRV9TWU1CT0wgJiYgU3ltYm9sW25hbWVdIHx8IChVU0VfU1lNQk9MID8gU3ltYm9sIDogdWlkKSgnU3ltYm9sLicgKyBuYW1lKSk7XG59O1xuXG4kZXhwb3J0cy5zdG9yZSA9IHN0b3JlO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fd2tzLmpzXG4vLyBtb2R1bGUgaWQgPSAxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy84NiNpc3N1ZWNvbW1lbnQtMTE1NzU5MDI4XG52YXIgZ2xvYmFsID0gbW9kdWxlLmV4cG9ydHMgPSB0eXBlb2Ygd2luZG93ICE9ICd1bmRlZmluZWQnICYmIHdpbmRvdy5NYXRoID09IE1hdGhcbiAgPyB3aW5kb3cgOiB0eXBlb2Ygc2VsZiAhPSAndW5kZWZpbmVkJyAmJiBzZWxmLk1hdGggPT0gTWF0aCA/IHNlbGYgOiBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuaWYodHlwZW9mIF9fZyA9PSAnbnVtYmVyJylfX2cgPSBnbG9iYWw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2dsb2JhbC5qc1xuLy8gbW9kdWxlIGlkID0gMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xuXG4ndXNlIHN0cmljdCdcblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5JylcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IFNsb3dCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUICE9PSB1bmRlZmluZWRcbiAgPyBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVFxuICA6IHR5cGVkQXJyYXlTdXBwb3J0KClcblxuLypcbiAqIEV4cG9ydCBrTWF4TGVuZ3RoIGFmdGVyIHR5cGVkIGFycmF5IHN1cHBvcnQgaXMgZGV0ZXJtaW5lZC5cbiAqL1xuZXhwb3J0cy5rTWF4TGVuZ3RoID0ga01heExlbmd0aCgpXG5cbmZ1bmN0aW9uIHR5cGVkQXJyYXlTdXBwb3J0ICgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMSlcbiAgICBhcnIuX19wcm90b19fID0ge19fcHJvdG9fXzogVWludDhBcnJheS5wcm90b3R5cGUsIGZvbzogZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfX1cbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MiAmJiAvLyB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG5mdW5jdGlvbiBjcmVhdGVCdWZmZXIgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoa01heExlbmd0aCgpIDwgbGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgdHlwZWQgYXJyYXkgbGVuZ3RoJylcbiAgfVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICBpZiAodGhhdCA9PT0gbnVsbCkge1xuICAgICAgdGhhdCA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuICAgIH1cbiAgICB0aGF0Lmxlbmd0aCA9IGxlbmd0aFxuICB9XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuLyoqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGhhdmUgdGhlaXJcbiAqIHByb3RvdHlwZSBjaGFuZ2VkIHRvIGBCdWZmZXIucHJvdG90eXBlYC4gRnVydGhlcm1vcmUsIGBCdWZmZXJgIGlzIGEgc3ViY2xhc3Mgb2ZcbiAqIGBVaW50OEFycmF5YCwgc28gdGhlIHJldHVybmVkIGluc3RhbmNlcyB3aWxsIGhhdmUgYWxsIHRoZSBub2RlIGBCdWZmZXJgIG1ldGhvZHNcbiAqIGFuZCB0aGUgYFVpbnQ4QXJyYXlgIG1ldGhvZHMuIFNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0XG4gKiByZXR1cm5zIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIFRoZSBgVWludDhBcnJheWAgcHJvdG90eXBlIHJlbWFpbnMgdW5tb2RpZmllZC5cbiAqL1xuXG5mdW5jdGlvbiBCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0lmIGVuY29kaW5nIGlzIHNwZWNpZmllZCB0aGVuIHRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nJ1xuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gYWxsb2NVbnNhZmUodGhpcywgYXJnKVxuICB9XG4gIHJldHVybiBmcm9tKHRoaXMsIGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuLy8gVE9ETzogTGVnYWN5LCBub3QgbmVlZGVkIGFueW1vcmUuIFJlbW92ZSBpbiBuZXh0IG1ham9yIHZlcnNpb24uXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiAoYXJyKSB7XG4gIGFyci5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gZnJvbSAodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldClcbiAgfVxuXG4gIHJldHVybiBmcm9tT2JqZWN0KHRoYXQsIHZhbHVlKVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIEJ1ZmZlcihhcmcsIGVuY29kaW5nKSBidXQgdGhyb3dzIGEgVHlwZUVycm9yXG4gKiBpZiB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEJ1ZmZlci5mcm9tKHN0clssIGVuY29kaW5nXSlcbiAqIEJ1ZmZlci5mcm9tKGFycmF5KVxuICogQnVmZmVyLmZyb20oYnVmZmVyKVxuICogQnVmZmVyLmZyb20oYXJyYXlCdWZmZXJbLCBieXRlT2Zmc2V0WywgbGVuZ3RoXV0pXG4gKiovXG5CdWZmZXIuZnJvbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBmcm9tKG51bGwsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbmlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICBCdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXkucHJvdG90eXBlXG4gIEJ1ZmZlci5fX3Byb3RvX18gPSBVaW50OEFycmF5XG4gIGlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wuc3BlY2llcyAmJlxuICAgICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gICAgLy8gRml4IHN1YmFycmF5KCkgaW4gRVMyMDE2LiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvOTdcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLCBTeW1ib2wuc3BlY2llcywge1xuICAgICAgdmFsdWU6IG51bGwsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9IGVsc2UgaWYgKHNpemUgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIG5lZ2F0aXZlJylcbiAgfVxufVxuXG5mdW5jdGlvbiBhbGxvYyAodGhhdCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICBpZiAoc2l6ZSA8PSAwKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxuICB9XG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPbmx5IHBheSBhdHRlbnRpb24gdG8gZW5jb2RpbmcgaWYgaXQncyBhIHN0cmluZy4gVGhpc1xuICAgIC8vIHByZXZlbnRzIGFjY2lkZW50YWxseSBzZW5kaW5nIGluIGEgbnVtYmVyIHRoYXQgd291bGRcbiAgICAvLyBiZSBpbnRlcnByZXR0ZWQgYXMgYSBzdGFydCBvZmZzZXQuXG4gICAgcmV0dXJuIHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZydcbiAgICAgID8gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgICA6IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKS5maWxsKGZpbGwpXG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqIGFsbG9jKHNpemVbLCBmaWxsWywgZW5jb2RpbmddXSlcbiAqKi9cbkJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICByZXR1cm4gYWxsb2MobnVsbCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpXG59XG5cbmZ1bmN0aW9uIGFsbG9jVW5zYWZlICh0aGF0LCBzaXplKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplIDwgMCA/IDAgOiBjaGVja2VkKHNpemUpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7XG4gICAgICB0aGF0W2ldID0gMFxuICAgIH1cbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gQnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsIHNpemUpXG59XG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gU2xvd0J1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICovXG5CdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsIHNpemUpXG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgfVxuXG4gIGlmICghQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJlbmNvZGluZ1wiIG11c3QgYmUgYSB2YWxpZCBzdHJpbmcgZW5jb2RpbmcnKVxuICB9XG5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuXG4gIHZhciBhY3R1YWwgPSB0aGF0LndyaXRlKHN0cmluZywgZW5jb2RpbmcpXG5cbiAgaWYgKGFjdHVhbCAhPT0gbGVuZ3RoKSB7XG4gICAgLy8gV3JpdGluZyBhIGhleCBzdHJpbmcsIGZvciBleGFtcGxlLCB0aGF0IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVycyB3aWxsXG4gICAgLy8gY2F1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgZmlyc3QgaW52YWxpZCBjaGFyYWN0ZXIgdG8gYmUgaWdub3JlZC4gKGUuZy5cbiAgICAvLyAnYWJ4eGNkJyB3aWxsIGJlIHRyZWF0ZWQgYXMgJ2FiJylcbiAgICB0aGF0ID0gdGhhdC5zbGljZSgwLCBhY3R1YWwpXG4gIH1cblxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlMaWtlICh0aGF0LCBhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyICh0aGF0LCBhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gIGFycmF5LmJ5dGVMZW5ndGggLy8gdGhpcyB0aHJvd3MgaWYgYGFycmF5YCBpcyBub3QgYSB2YWxpZCBBcnJheUJ1ZmZlclxuXG4gIGlmIChieXRlT2Zmc2V0IDwgMCB8fCBhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdvZmZzZXRcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQgKyAobGVuZ3RoIHx8IDApKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ2xlbmd0aFxcJyBpcyBvdXQgb2YgYm91bmRzJylcbiAgfVxuXG4gIGlmIChieXRlT2Zmc2V0ID09PSB1bmRlZmluZWQgJiYgbGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5KVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldClcbiAgfSBlbHNlIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gYXJyYXlcbiAgICB0aGF0Ll9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgdGhhdCA9IGZyb21BcnJheUxpa2UodGhhdCwgYXJyYXkpXG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbU9iamVjdCAodGhhdCwgb2JqKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIob2JqKSkge1xuICAgIHZhciBsZW4gPSBjaGVja2VkKG9iai5sZW5ndGgpIHwgMFxuICAgIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuKVxuXG4gICAgaWYgKHRoYXQubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdGhhdFxuICAgIH1cblxuICAgIG9iai5jb3B5KHRoYXQsIDAsIDAsIGxlbilcbiAgICByZXR1cm4gdGhhdFxuICB9XG5cbiAgaWYgKG9iaikge1xuICAgIGlmICgodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICBvYmouYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHx8ICdsZW5ndGgnIGluIG9iaikge1xuICAgICAgaWYgKHR5cGVvZiBvYmoubGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBpc25hbihvYmoubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIDApXG4gICAgICB9XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmopXG4gICAgfVxuXG4gICAgaWYgKG9iai50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iai5kYXRhKSkge1xuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCwgb2JqLmRhdGEpXG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksIG9yIGFycmF5LWxpa2Ugb2JqZWN0LicpXG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBrTWF4TGVuZ3RoKClgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0ga01heExlbmd0aCgpKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIGtNYXhMZW5ndGgoKS50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKCtsZW5ndGggIT0gbGVuZ3RoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG4gICAgbGVuZ3RoID0gMFxuICB9XG4gIHJldHVybiBCdWZmZXIuYWxsb2MoK2xlbmd0aClcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldXG4gICAgICB5ID0gYltpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnbGF0aW4xJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgYnVmID0gbGlzdFtpXVxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gICAgfVxuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKVxuICAgIHBvcyArPSBidWYubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSkge1xuICAgIHJldHVybiBzdHJpbmcubGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldyA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpIHx8IHN0cmluZyBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkge1xuICAgIHJldHVybiBzdHJpbmcuYnl0ZUxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykge1xuICAgIHN0cmluZyA9ICcnICsgc3RyaW5nXG4gIH1cblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgY2FzZSB1bmRlZmluZWQ6XG4gICAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIGxlbiAqIDJcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBsZW4gPj4+IDFcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aCAvLyBhc3N1bWUgdXRmOFxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuQnVmZmVyLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICAvLyBObyBuZWVkIHRvIHZlcmlmeSB0aGF0IFwidGhpcy5sZW5ndGggPD0gTUFYX1VJTlQzMlwiIHNpbmNlIGl0J3MgYSByZWFkLW9ubHlcbiAgLy8gcHJvcGVydHkgb2YgYSB0eXBlZCBhcnJheS5cblxuICAvLyBUaGlzIGJlaGF2ZXMgbmVpdGhlciBsaWtlIFN0cmluZyBub3IgVWludDhBcnJheSBpbiB0aGF0IHdlIHNldCBzdGFydC9lbmRcbiAgLy8gdG8gdGhlaXIgdXBwZXIvbG93ZXIgYm91bmRzIGlmIHRoZSB2YWx1ZSBwYXNzZWQgaXMgb3V0IG9mIHJhbmdlLlxuICAvLyB1bmRlZmluZWQgaXMgaGFuZGxlZCBzcGVjaWFsbHkgYXMgcGVyIEVDTUEtMjYyIDZ0aCBFZGl0aW9uLFxuICAvLyBTZWN0aW9uIDEzLjMuMy43IFJ1bnRpbWUgU2VtYW50aWNzOiBLZXllZEJpbmRpbmdJbml0aWFsaXphdGlvbi5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQgfHwgc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgLy8gUmV0dXJuIGVhcmx5IGlmIHN0YXJ0ID4gdGhpcy5sZW5ndGguIERvbmUgaGVyZSB0byBwcmV2ZW50IHBvdGVudGlhbCB1aW50MzJcbiAgLy8gY29lcmNpb24gZmFpbCBiZWxvdy5cbiAgaWYgKHN0YXJ0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoZW5kIDw9IDApIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIC8vIEZvcmNlIGNvZXJzaW9uIHRvIHVpbnQzMi4gVGhpcyB3aWxsIGFsc28gY29lcmNlIGZhbHNleS9OYU4gdmFsdWVzIHRvIDAuXG4gIGVuZCA+Pj49IDBcbiAgc3RhcnQgPj4+PSAwXG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbi8vIFRoZSBwcm9wZXJ0eSBpcyB1c2VkIGJ5IGBCdWZmZXIuaXNCdWZmZXJgIGFuZCBgaXMtYnVmZmVyYCAoaW4gU2FmYXJpIDUtNykgdG8gZGV0ZWN0XG4vLyBCdWZmZXIgaW5zdGFuY2VzLlxuQnVmZmVyLnByb3RvdHlwZS5faXNCdWZmZXIgPSB0cnVlXG5cbmZ1bmN0aW9uIHN3YXAgKGIsIG4sIG0pIHtcbiAgdmFyIGkgPSBiW25dXG4gIGJbbl0gPSBiW21dXG4gIGJbbV0gPSBpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDE2ID0gZnVuY3Rpb24gc3dhcDE2ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSAyICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMSlcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAzMiA9IGZ1bmN0aW9uIHN3YXAzMiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgNCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMzItYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDMpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDIpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwNjQgPSBmdW5jdGlvbiBzd2FwNjQgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDggIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDY0LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDgpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyA3KVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyA2KVxuICAgIHN3YXAodGhpcywgaSArIDIsIGkgKyA1KVxuICAgIHN3YXAodGhpcywgaSArIDMsIGkgKyA0KVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlICh0YXJnZXQsIHN0YXJ0LCBlbmQsIHRoaXNTdGFydCwgdGhpc0VuZCkge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIH1cblxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuZCA9IHRhcmdldCA/IHRhcmdldC5sZW5ndGggOiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc1N0YXJ0ID0gMFxuICB9XG4gIGlmICh0aGlzRW5kID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzRW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChzdGFydCA8IDAgfHwgZW5kID4gdGFyZ2V0Lmxlbmd0aCB8fCB0aGlzU3RhcnQgPCAwIHx8IHRoaXNFbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdvdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kICYmIHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kKSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cbiAgaWYgKHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAxXG4gIH1cblxuICBzdGFydCA+Pj49IDBcbiAgZW5kID4+Pj0gMFxuICB0aGlzU3RhcnQgPj4+PSAwXG4gIHRoaXNFbmQgPj4+PSAwXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCkgcmV0dXJuIDBcblxuICB2YXIgeCA9IHRoaXNFbmQgLSB0aGlzU3RhcnRcbiAgdmFyIHkgPSBlbmQgLSBzdGFydFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcblxuICB2YXIgdGhpc0NvcHkgPSB0aGlzLnNsaWNlKHRoaXNTdGFydCwgdGhpc0VuZClcbiAgdmFyIHRhcmdldENvcHkgPSB0YXJnZXQuc2xpY2Uoc3RhcnQsIGVuZClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKHRoaXNDb3B5W2ldICE9PSB0YXJnZXRDb3B5W2ldKSB7XG4gICAgICB4ID0gdGhpc0NvcHlbaV1cbiAgICAgIHkgPSB0YXJnZXRDb3B5W2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuLy8gRmluZHMgZWl0aGVyIHRoZSBmaXJzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPj0gYGJ5dGVPZmZzZXRgLFxuLy8gT1IgdGhlIGxhc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0IDw9IGBieXRlT2Zmc2V0YC5cbi8vXG4vLyBBcmd1bWVudHM6XG4vLyAtIGJ1ZmZlciAtIGEgQnVmZmVyIHRvIHNlYXJjaFxuLy8gLSB2YWwgLSBhIHN0cmluZywgQnVmZmVyLCBvciBudW1iZXJcbi8vIC0gYnl0ZU9mZnNldCAtIGFuIGluZGV4IGludG8gYGJ1ZmZlcmA7IHdpbGwgYmUgY2xhbXBlZCB0byBhbiBpbnQzMlxuLy8gLSBlbmNvZGluZyAtIGFuIG9wdGlvbmFsIGVuY29kaW5nLCByZWxldmFudCBpcyB2YWwgaXMgYSBzdHJpbmdcbi8vIC0gZGlyIC0gdHJ1ZSBmb3IgaW5kZXhPZiwgZmFsc2UgZm9yIGxhc3RJbmRleE9mXG5mdW5jdGlvbiBiaWRpcmVjdGlvbmFsSW5kZXhPZiAoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgLy8gRW1wdHkgYnVmZmVyIG1lYW5zIG5vIG1hdGNoXG4gIGlmIChidWZmZXIubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldFxuICBpZiAodHlwZW9mIGJ5dGVPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBieXRlT2Zmc2V0XG4gICAgYnl0ZU9mZnNldCA9IDBcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0ID4gMHg3ZmZmZmZmZikge1xuICAgIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IC0weDgwMDAwMDAwKSB7XG4gICAgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIH1cbiAgYnl0ZU9mZnNldCA9ICtieXRlT2Zmc2V0ICAvLyBDb2VyY2UgdG8gTnVtYmVyLlxuICBpZiAoaXNOYU4oYnl0ZU9mZnNldCkpIHtcbiAgICAvLyBieXRlT2Zmc2V0OiBpdCBpdCdzIHVuZGVmaW5lZCwgbnVsbCwgTmFOLCBcImZvb1wiLCBldGMsIHNlYXJjaCB3aG9sZSBidWZmZXJcbiAgICBieXRlT2Zmc2V0ID0gZGlyID8gMCA6IChidWZmZXIubGVuZ3RoIC0gMSlcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0OiBuZWdhdGl2ZSBvZmZzZXRzIHN0YXJ0IGZyb20gdGhlIGVuZCBvZiB0aGUgYnVmZmVyXG4gIGlmIChieXRlT2Zmc2V0IDwgMCkgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggKyBieXRlT2Zmc2V0XG4gIGlmIChieXRlT2Zmc2V0ID49IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICBpZiAoZGlyKSByZXR1cm4gLTFcbiAgICBlbHNlIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoIC0gMVxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAwKSB7XG4gICAgaWYgKGRpcikgYnl0ZU9mZnNldCA9IDBcbiAgICBlbHNlIHJldHVybiAtMVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIHZhbFxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICB2YWwgPSBCdWZmZXIuZnJvbSh2YWwsIGVuY29kaW5nKVxuICB9XG5cbiAgLy8gRmluYWxseSwgc2VhcmNoIGVpdGhlciBpbmRleE9mIChpZiBkaXIgaXMgdHJ1ZSkgb3IgbGFzdEluZGV4T2ZcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWwpKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcvYnVmZmVyIGFsd2F5cyBmYWlsc1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDB4RkYgLy8gU2VhcmNoIGZvciBhIGJ5dGUgdmFsdWUgWzAtMjU1XVxuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJlxuICAgICAgICB0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKGRpcikge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCBbIHZhbCBdLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICB2YXIgaW5kZXhTaXplID0gMVxuICB2YXIgYXJyTGVuZ3RoID0gYXJyLmxlbmd0aFxuICB2YXIgdmFsTGVuZ3RoID0gdmFsLmxlbmd0aFxuXG4gIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICBpZiAoZW5jb2RpbmcgPT09ICd1Y3MyJyB8fCBlbmNvZGluZyA9PT0gJ3Vjcy0yJyB8fFxuICAgICAgICBlbmNvZGluZyA9PT0gJ3V0ZjE2bGUnIHx8IGVuY29kaW5nID09PSAndXRmLTE2bGUnKSB7XG4gICAgICBpZiAoYXJyLmxlbmd0aCA8IDIgfHwgdmFsLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9XG4gICAgICBpbmRleFNpemUgPSAyXG4gICAgICBhcnJMZW5ndGggLz0gMlxuICAgICAgdmFsTGVuZ3RoIC89IDJcbiAgICAgIGJ5dGVPZmZzZXQgLz0gMlxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWQgKGJ1ZiwgaSkge1xuICAgIGlmIChpbmRleFNpemUgPT09IDEpIHtcbiAgICAgIHJldHVybiBidWZbaV1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGJ1Zi5yZWFkVUludDE2QkUoaSAqIGluZGV4U2l6ZSlcbiAgICB9XG4gIH1cblxuICB2YXIgaVxuICBpZiAoZGlyKSB7XG4gICAgdmFyIGZvdW5kSW5kZXggPSAtMVxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPCBhcnJMZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHJlYWQoYXJyLCBpKSA9PT0gcmVhZCh2YWwsIGZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4KSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbExlbmd0aCkgcmV0dXJuIGZvdW5kSW5kZXggKiBpbmRleFNpemVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ICE9PSAtMSkgaSAtPSBpIC0gZm91bmRJbmRleFxuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGJ5dGVPZmZzZXQgKyB2YWxMZW5ndGggPiBhcnJMZW5ndGgpIGJ5dGVPZmZzZXQgPSBhcnJMZW5ndGggLSB2YWxMZW5ndGhcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIGZvdW5kID0gdHJ1ZVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB2YWxMZW5ndGg7IGorKykge1xuICAgICAgICBpZiAocmVhZChhcnIsIGkgKyBqKSAhPT0gcmVhZCh2YWwsIGopKSB7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uIGluY2x1ZGVzICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiB0aGlzLmluZGV4T2YodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykgIT09IC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIHRydWUpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUubGFzdEluZGV4T2YgPSBmdW5jdGlvbiBsYXN0SW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG5cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgaWYgKGlzTmFOKHBhcnNlZCkpIHJldHVybiBpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBsYXRpbjFXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCB8IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICAvLyBsZWdhY3kgd3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpIC0gcmVtb3ZlIGluIHYwLjEzXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0J1ZmZlci53cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXRbLCBsZW5ndGhdKSBpcyBubyBsb25nZXIgc3VwcG9ydGVkJ1xuICAgIClcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gbGF0aW4xU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIG5ld0J1ZiA9IHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZClcbiAgICBuZXdCdWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgbmV3QnVmID0gbmV3IEJ1ZmZlcihzbGljZUxlbiwgdW5kZWZpbmVkKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpY2VMZW47ICsraSkge1xuICAgICAgbmV3QnVmW2ldID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZmZlclwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKVxuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDIpOyBpIDwgajsgKytpKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSkpKSA+Pj5cbiAgICAgIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpICogOFxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7ICsraSkge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSAtIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSArIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcbiAgdmFyIGlcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKGkgPSBsZW4gLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSBpZiAobGVuIDwgMTAwMCB8fCAhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBhc2NlbmRpbmcgY29weSBmcm9tIHN0YXJ0XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBVaW50OEFycmF5LnByb3RvdHlwZS5zZXQuY2FsbChcbiAgICAgIHRhcmdldCxcbiAgICAgIHRoaXMuc3ViYXJyYXkoc3RhcnQsIHN0YXJ0ICsgbGVuKSxcbiAgICAgIHRhcmdldFN0YXJ0XG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBVc2FnZTpcbi8vICAgIGJ1ZmZlci5maWxsKG51bWJlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoYnVmZmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChzdHJpbmdbLCBvZmZzZXRbLCBlbmRdXVssIGVuY29kaW5nXSlcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbCwgc3RhcnQsIGVuZCwgZW5jb2RpbmcpIHtcbiAgLy8gSGFuZGxlIHN0cmluZyBjYXNlczpcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHR5cGVvZiBzdGFydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gc3RhcnRcbiAgICAgIHN0YXJ0ID0gMFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbmQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuZFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZhciBjb2RlID0gdmFsLmNoYXJDb2RlQXQoMClcbiAgICAgIGlmIChjb2RlIDwgMjU2KSB7XG4gICAgICAgIHZhbCA9IGNvZGVcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnICYmICFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAyNTVcbiAgfVxuXG4gIC8vIEludmFsaWQgcmFuZ2VzIGFyZSBub3Qgc2V0IHRvIGEgZGVmYXVsdCwgc28gY2FuIHJhbmdlIGNoZWNrIGVhcmx5LlxuICBpZiAoc3RhcnQgPCAwIHx8IHRoaXMubGVuZ3RoIDwgc3RhcnQgfHwgdGhpcy5sZW5ndGggPCBlbmQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignT3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgc3RhcnQgPSBzdGFydCA+Pj4gMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IHRoaXMubGVuZ3RoIDogZW5kID4+PiAwXG5cbiAgaWYgKCF2YWwpIHZhbCA9IDBcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgICB0aGlzW2ldID0gdmFsXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBieXRlcyA9IEJ1ZmZlci5pc0J1ZmZlcih2YWwpXG4gICAgICA/IHZhbFxuICAgICAgOiB1dGY4VG9CeXRlcyhuZXcgQnVmZmVyKHZhbCwgZW5jb2RpbmcpLnRvU3RyaW5nKCkpXG4gICAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aFxuICAgIGZvciAoaSA9IDA7IGkgPCBlbmQgLSBzdGFydDsgKytpKSB7XG4gICAgICB0aGlzW2kgKyBzdGFydF0gPSBieXRlc1tpICUgbGVuXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teK1xcLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gKGxlYWRTdXJyb2dhdGUgLSAweEQ4MDAgPDwgMTAgfCBjb2RlUG9pbnQgLSAweERDMDApICsgMHgxMDAwMFxuICAgIH0gZWxzZSBpZiAobGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgLy8gdmFsaWQgYm1wIGNoYXIsIGJ1dCBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgfVxuXG4gICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcblxuICAgIC8vIGVuY29kZSB1dGY4XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4ODApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMSkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChjb2RlUG9pbnQpXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2IHwgMHhDMCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyB8IDB4RTAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDQpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDEyIHwgMHhGMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2RlIHBvaW50JylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnl0ZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0ciwgdW5pdHMpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIGlzbmFuICh2YWwpIHtcbiAgcmV0dXJuIHZhbCAhPT0gdmFsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vYnVmZmVyL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIGlmKCFpc09iamVjdChpdCkpdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYW4gb2JqZWN0IScpO1xuICByZXR1cm4gaXQ7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXG4vLyBtb2R1bGUgaWQgPSA0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBhbk9iamVjdCAgICAgICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgSUU4X0RPTV9ERUZJTkUgPSByZXF1aXJlKCcuL19pZTgtZG9tLWRlZmluZScpXG4gICwgdG9QcmltaXRpdmUgICAgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKVxuICAsIGRQICAgICAgICAgICAgID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xuXG5leHBvcnRzLmYgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gT2JqZWN0LmRlZmluZVByb3BlcnR5IDogZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkoTywgUCwgQXR0cmlidXRlcyl7XG4gIGFuT2JqZWN0KE8pO1xuICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XG4gIGFuT2JqZWN0KEF0dHJpYnV0ZXMpO1xuICBpZihJRThfRE9NX0RFRklORSl0cnkge1xuICAgIHJldHVybiBkUChPLCBQLCBBdHRyaWJ1dGVzKTtcbiAgfSBjYXRjaChlKXsgLyogZW1wdHkgKi8gfVxuICBpZignZ2V0JyBpbiBBdHRyaWJ1dGVzIHx8ICdzZXQnIGluIEF0dHJpYnV0ZXMpdGhyb3cgVHlwZUVycm9yKCdBY2Nlc3NvcnMgbm90IHN1cHBvcnRlZCEnKTtcbiAgaWYoJ3ZhbHVlJyBpbiBBdHRyaWJ1dGVzKU9bUF0gPSBBdHRyaWJ1dGVzLnZhbHVlO1xuICByZXR1cm4gTztcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19vYmplY3QtZHAuanNcbi8vIG1vZHVsZSBpZCA9IDVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gVGhhbmsncyBJRTggZm9yIGhpcyBmdW5ueSBkZWZpbmVQcm9wZXJ0eVxubW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbigpe1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnYScsIHtnZXQ6IGZ1bmN0aW9uKCl7IHJldHVybiA3OyB9fSkuYSAhPSA3O1xufSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19kZXNjcmlwdG9ycy5qc1xuLy8gbW9kdWxlIGlkID0gNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgZ2xvYmFsICAgID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCBjb3JlICAgICAgPSByZXF1aXJlKCcuL19jb3JlJylcbiAgLCBjdHggICAgICAgPSByZXF1aXJlKCcuL19jdHgnKVxuICAsIGhpZGUgICAgICA9IHJlcXVpcmUoJy4vX2hpZGUnKVxuICAsIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xuXG52YXIgJGV4cG9ydCA9IGZ1bmN0aW9uKHR5cGUsIG5hbWUsIHNvdXJjZSl7XG4gIHZhciBJU19GT1JDRUQgPSB0eXBlICYgJGV4cG9ydC5GXG4gICAgLCBJU19HTE9CQUwgPSB0eXBlICYgJGV4cG9ydC5HXG4gICAgLCBJU19TVEFUSUMgPSB0eXBlICYgJGV4cG9ydC5TXG4gICAgLCBJU19QUk9UTyAgPSB0eXBlICYgJGV4cG9ydC5QXG4gICAgLCBJU19CSU5EICAgPSB0eXBlICYgJGV4cG9ydC5CXG4gICAgLCBJU19XUkFQICAgPSB0eXBlICYgJGV4cG9ydC5XXG4gICAgLCBleHBvcnRzICAgPSBJU19HTE9CQUwgPyBjb3JlIDogY29yZVtuYW1lXSB8fCAoY29yZVtuYW1lXSA9IHt9KVxuICAgICwgZXhwUHJvdG8gID0gZXhwb3J0c1tQUk9UT1RZUEVdXG4gICAgLCB0YXJnZXQgICAgPSBJU19HTE9CQUwgPyBnbG9iYWwgOiBJU19TVEFUSUMgPyBnbG9iYWxbbmFtZV0gOiAoZ2xvYmFsW25hbWVdIHx8IHt9KVtQUk9UT1RZUEVdXG4gICAgLCBrZXksIG93biwgb3V0O1xuICBpZihJU19HTE9CQUwpc291cmNlID0gbmFtZTtcbiAgZm9yKGtleSBpbiBzb3VyY2Upe1xuICAgIC8vIGNvbnRhaW5zIGluIG5hdGl2ZVxuICAgIG93biA9ICFJU19GT1JDRUQgJiYgdGFyZ2V0ICYmIHRhcmdldFtrZXldICE9PSB1bmRlZmluZWQ7XG4gICAgaWYob3duICYmIGtleSBpbiBleHBvcnRzKWNvbnRpbnVlO1xuICAgIC8vIGV4cG9ydCBuYXRpdmUgb3IgcGFzc2VkXG4gICAgb3V0ID0gb3duID8gdGFyZ2V0W2tleV0gOiBzb3VyY2Vba2V5XTtcbiAgICAvLyBwcmV2ZW50IGdsb2JhbCBwb2xsdXRpb24gZm9yIG5hbWVzcGFjZXNcbiAgICBleHBvcnRzW2tleV0gPSBJU19HTE9CQUwgJiYgdHlwZW9mIHRhcmdldFtrZXldICE9ICdmdW5jdGlvbicgPyBzb3VyY2Vba2V5XVxuICAgIC8vIGJpbmQgdGltZXJzIHRvIGdsb2JhbCBmb3IgY2FsbCBmcm9tIGV4cG9ydCBjb250ZXh0XG4gICAgOiBJU19CSU5EICYmIG93biA/IGN0eChvdXQsIGdsb2JhbClcbiAgICAvLyB3cmFwIGdsb2JhbCBjb25zdHJ1Y3RvcnMgZm9yIHByZXZlbnQgY2hhbmdlIHRoZW0gaW4gbGlicmFyeVxuICAgIDogSVNfV1JBUCAmJiB0YXJnZXRba2V5XSA9PSBvdXQgPyAoZnVuY3Rpb24oQyl7XG4gICAgICB2YXIgRiA9IGZ1bmN0aW9uKGEsIGIsIGMpe1xuICAgICAgICBpZih0aGlzIGluc3RhbmNlb2YgQyl7XG4gICAgICAgICAgc3dpdGNoKGFyZ3VtZW50cy5sZW5ndGgpe1xuICAgICAgICAgICAgY2FzZSAwOiByZXR1cm4gbmV3IEM7XG4gICAgICAgICAgICBjYXNlIDE6IHJldHVybiBuZXcgQyhhKTtcbiAgICAgICAgICAgIGNhc2UgMjogcmV0dXJuIG5ldyBDKGEsIGIpO1xuICAgICAgICAgIH0gcmV0dXJuIG5ldyBDKGEsIGIsIGMpO1xuICAgICAgICB9IHJldHVybiBDLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgICAgRltQUk9UT1RZUEVdID0gQ1tQUk9UT1RZUEVdO1xuICAgICAgcmV0dXJuIEY7XG4gICAgLy8gbWFrZSBzdGF0aWMgdmVyc2lvbnMgZm9yIHByb3RvdHlwZSBtZXRob2RzXG4gICAgfSkob3V0KSA6IElTX1BST1RPICYmIHR5cGVvZiBvdXQgPT0gJ2Z1bmN0aW9uJyA/IGN0eChGdW5jdGlvbi5jYWxsLCBvdXQpIDogb3V0O1xuICAgIC8vIGV4cG9ydCBwcm90byBtZXRob2RzIHRvIGNvcmUuJUNPTlNUUlVDVE9SJS5tZXRob2RzLiVOQU1FJVxuICAgIGlmKElTX1BST1RPKXtcbiAgICAgIChleHBvcnRzLnZpcnR1YWwgfHwgKGV4cG9ydHMudmlydHVhbCA9IHt9KSlba2V5XSA9IG91dDtcbiAgICAgIC8vIGV4cG9ydCBwcm90byBtZXRob2RzIHRvIGNvcmUuJUNPTlNUUlVDVE9SJS5wcm90b3R5cGUuJU5BTUUlXG4gICAgICBpZih0eXBlICYgJGV4cG9ydC5SICYmIGV4cFByb3RvICYmICFleHBQcm90b1trZXldKWhpZGUoZXhwUHJvdG8sIGtleSwgb3V0KTtcbiAgICB9XG4gIH1cbn07XG4vLyB0eXBlIGJpdG1hcFxuJGV4cG9ydC5GID0gMTsgICAvLyBmb3JjZWRcbiRleHBvcnQuRyA9IDI7ICAgLy8gZ2xvYmFsXG4kZXhwb3J0LlMgPSA0OyAgIC8vIHN0YXRpY1xuJGV4cG9ydC5QID0gODsgICAvLyBwcm90b1xuJGV4cG9ydC5CID0gMTY7ICAvLyBiaW5kXG4kZXhwb3J0LlcgPSAzMjsgIC8vIHdyYXBcbiRleHBvcnQuVSA9IDY0OyAgLy8gc2FmZVxuJGV4cG9ydC5SID0gMTI4OyAvLyByZWFsIHByb3RvIG1ldGhvZCBmb3IgYGxpYnJhcnlgIFxubW9kdWxlLmV4cG9ydHMgPSAkZXhwb3J0O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fZXhwb3J0LmpzXG4vLyBtb2R1bGUgaWQgPSA3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBoYXNPd25Qcm9wZXJ0eSA9IHt9Lmhhc093blByb3BlcnR5O1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCwga2V5KXtcbiAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoaXQsIGtleSk7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9faGFzLmpzXG4vLyBtb2R1bGUgaWQgPSA4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBkUCAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJylcbiAgLCBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gZnVuY3Rpb24ob2JqZWN0LCBrZXksIHZhbHVlKXtcbiAgcmV0dXJuIGRQLmYob2JqZWN0LCBrZXksIGNyZWF0ZURlc2MoMSwgdmFsdWUpKTtcbn0gOiBmdW5jdGlvbihvYmplY3QsIGtleSwgdmFsdWUpe1xuICBvYmplY3Rba2V5XSA9IHZhbHVlO1xuICByZXR1cm4gb2JqZWN0O1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2hpZGUuanNcbi8vIG1vZHVsZSBpZCA9IDlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gdG8gaW5kZXhlZCBvYmplY3QsIHRvT2JqZWN0IHdpdGggZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBzdHJpbmdzXG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKVxuICAsIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIElPYmplY3QoZGVmaW5lZChpdCkpO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3RvLWlvYmplY3QuanNcbi8vIG1vZHVsZSBpZCA9IDEwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG4vLyBjYWNoZWQgZnJvbSB3aGF0ZXZlciBnbG9iYWwgaXMgcHJlc2VudCBzbyB0aGF0IHRlc3QgcnVubmVycyB0aGF0IHN0dWIgaXRcbi8vIGRvbid0IGJyZWFrIHRoaW5ncy4gIEJ1dCB3ZSBuZWVkIHRvIHdyYXAgaXQgaW4gYSB0cnkgY2F0Y2ggaW4gY2FzZSBpdCBpc1xuLy8gd3JhcHBlZCBpbiBzdHJpY3QgbW9kZSBjb2RlIHdoaWNoIGRvZXNuJ3QgZGVmaW5lIGFueSBnbG9iYWxzLiAgSXQncyBpbnNpZGUgYVxuLy8gZnVuY3Rpb24gYmVjYXVzZSB0cnkvY2F0Y2hlcyBkZW9wdGltaXplIGluIGNlcnRhaW4gZW5naW5lcy5cblxudmFyIGNhY2hlZFNldFRpbWVvdXQ7XG52YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O1xuXG5mdW5jdGlvbiBkZWZhdWx0U2V0VGltb3V0KCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2V0VGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuZnVuY3Rpb24gZGVmYXVsdENsZWFyVGltZW91dCAoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbihmdW5jdGlvbiAoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXRUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBjbGVhclRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgfVxufSAoKSlcbmZ1bmN0aW9uIHJ1blRpbWVvdXQoZnVuKSB7XG4gICAgaWYgKGNhY2hlZFNldFRpbWVvdXQgPT09IHNldFRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIC8vIGlmIHNldFRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRTZXRUaW1lb3V0ID09PSBkZWZhdWx0U2V0VGltb3V0IHx8ICFjYWNoZWRTZXRUaW1lb3V0KSAmJiBzZXRUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfSBjYXRjaChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbChudWxsLCBmdW4sIDApO1xuICAgICAgICB9IGNhdGNoKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3JcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwodGhpcywgZnVuLCAwKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG59XG5mdW5jdGlvbiBydW5DbGVhclRpbWVvdXQobWFya2VyKSB7XG4gICAgaWYgKGNhY2hlZENsZWFyVGltZW91dCA9PT0gY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIC8vIGlmIGNsZWFyVGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZENsZWFyVGltZW91dCA9PT0gZGVmYXVsdENsZWFyVGltZW91dCB8fCAhY2FjaGVkQ2xlYXJUaW1lb3V0KSAmJiBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0ICB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKG51bGwsIG1hcmtlcik7XG4gICAgICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3IuXG4gICAgICAgICAgICAvLyBTb21lIHZlcnNpb25zIG9mIEkuRS4gaGF2ZSBkaWZmZXJlbnQgcnVsZXMgZm9yIGNsZWFyVGltZW91dCB2cyBzZXRUaW1lb3V0XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwodGhpcywgbWFya2VyKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG5cbn1cbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG52YXIgY3VycmVudFF1ZXVlO1xudmFyIHF1ZXVlSW5kZXggPSAtMTtcblxuZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCkge1xuICAgIGlmICghZHJhaW5pbmcgfHwgIWN1cnJlbnRRdWV1ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgaWYgKGN1cnJlbnRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcXVldWUgPSBjdXJyZW50UXVldWUuY29uY2F0KHF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgfVxuICAgIGlmIChxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgZHJhaW5RdWV1ZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhaW5RdWV1ZSgpIHtcbiAgICBpZiAoZHJhaW5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgdGltZW91dCA9IHJ1blRpbWVvdXQoY2xlYW5VcE5leHRUaWNrKTtcbiAgICBkcmFpbmluZyA9IHRydWU7XG5cbiAgICB2YXIgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIHdoaWxlKGxlbikge1xuICAgICAgICBjdXJyZW50UXVldWUgPSBxdWV1ZTtcbiAgICAgICAgcXVldWUgPSBbXTtcbiAgICAgICAgd2hpbGUgKCsrcXVldWVJbmRleCA8IGxlbikge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRRdWV1ZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgY3VycmVudFF1ZXVlID0gbnVsbDtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIHJ1bkNsZWFyVGltZW91dCh0aW1lb3V0KTtcbn1cblxucHJvY2Vzcy5uZXh0VGljayA9IGZ1bmN0aW9uIChmdW4pIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBxdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1biwgYXJncykpO1xuICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG4gICAgICAgIHJ1blRpbWVvdXQoZHJhaW5RdWV1ZSk7XG4gICAgfVxufTtcblxuLy8gdjggbGlrZXMgcHJlZGljdGlibGUgb2JqZWN0c1xuZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG4gICAgdGhpcy5mdW4gPSBmdW47XG4gICAgdGhpcy5hcnJheSA9IGFycmF5O1xufVxuSXRlbS5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZnVuLmFwcGx5KG51bGwsIHRoaXMuYXJyYXkpO1xufTtcbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xucHJvY2Vzcy52ZXJzaW9uID0gJyc7IC8vIGVtcHR5IHN0cmluZyB0byBhdm9pZCByZWdleHAgaXNzdWVzXG5wcm9jZXNzLnZlcnNpb25zID0ge307XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5wcm9jZXNzLm9uID0gbm9vcDtcbnByb2Nlc3MuYWRkTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5vbmNlID0gbm9vcDtcbnByb2Nlc3Mub2ZmID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xucHJvY2Vzcy5lbWl0ID0gbm9vcDtcblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vcHJvY2Vzcy9icm93c2VyLmpzXG4vLyBtb2R1bGUgaWQgPSAxMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBhIGR1cGxleCBzdHJlYW0gaXMganVzdCBhIHN0cmVhbSB0aGF0IGlzIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLlxuLy8gU2luY2UgSlMgZG9lc24ndCBoYXZlIG11bHRpcGxlIHByb3RvdHlwYWwgaW5oZXJpdGFuY2UsIHRoaXMgY2xhc3Ncbi8vIHByb3RvdHlwYWxseSBpbmhlcml0cyBmcm9tIFJlYWRhYmxlLCBhbmQgdGhlbiBwYXJhc2l0aWNhbGx5IGZyb21cbi8vIFdyaXRhYmxlLlxuXG4ndXNlIHN0cmljdCc7XG5cbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iaikge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAga2V5cy5wdXNoKGtleSk7XG4gIH1yZXR1cm4ga2V5cztcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxubW9kdWxlLmV4cG9ydHMgPSBEdXBsZXg7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgcHJvY2Vzc05leHRUaWNrID0gcmVxdWlyZSgncHJvY2Vzcy1uZXh0aWNrLWFyZ3MnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBSZWFkYWJsZSA9IHJlcXVpcmUoJy4vX3N0cmVhbV9yZWFkYWJsZScpO1xudmFyIFdyaXRhYmxlID0gcmVxdWlyZSgnLi9fc3RyZWFtX3dyaXRhYmxlJyk7XG5cbnV0aWwuaW5oZXJpdHMoRHVwbGV4LCBSZWFkYWJsZSk7XG5cbnZhciBrZXlzID0gb2JqZWN0S2V5cyhXcml0YWJsZS5wcm90b3R5cGUpO1xuZm9yICh2YXIgdiA9IDA7IHYgPCBrZXlzLmxlbmd0aDsgdisrKSB7XG4gIHZhciBtZXRob2QgPSBrZXlzW3ZdO1xuICBpZiAoIUR1cGxleC5wcm90b3R5cGVbbWV0aG9kXSkgRHVwbGV4LnByb3RvdHlwZVttZXRob2RdID0gV3JpdGFibGUucHJvdG90eXBlW21ldGhvZF07XG59XG5cbmZ1bmN0aW9uIER1cGxleChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKSByZXR1cm4gbmV3IER1cGxleChvcHRpb25zKTtcblxuICBSZWFkYWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICBXcml0YWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMucmVhZGFibGUgPT09IGZhbHNlKSB0aGlzLnJlYWRhYmxlID0gZmFsc2U7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy53cml0YWJsZSA9PT0gZmFsc2UpIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcblxuICB0aGlzLmFsbG93SGFsZk9wZW4gPSB0cnVlO1xuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmFsbG93SGFsZk9wZW4gPT09IGZhbHNlKSB0aGlzLmFsbG93SGFsZk9wZW4gPSBmYWxzZTtcblxuICB0aGlzLm9uY2UoJ2VuZCcsIG9uZW5kKTtcbn1cblxuLy8gdGhlIG5vLWhhbGYtb3BlbiBlbmZvcmNlclxuZnVuY3Rpb24gb25lbmQoKSB7XG4gIC8vIGlmIHdlIGFsbG93IGhhbGYtb3BlbiBzdGF0ZSwgb3IgaWYgdGhlIHdyaXRhYmxlIHNpZGUgZW5kZWQsXG4gIC8vIHRoZW4gd2UncmUgb2suXG4gIGlmICh0aGlzLmFsbG93SGFsZk9wZW4gfHwgdGhpcy5fd3JpdGFibGVTdGF0ZS5lbmRlZCkgcmV0dXJuO1xuXG4gIC8vIG5vIG1vcmUgZGF0YSBjYW4gYmUgd3JpdHRlbi5cbiAgLy8gQnV0IGFsbG93IG1vcmUgd3JpdGVzIHRvIGhhcHBlbiBpbiB0aGlzIHRpY2suXG4gIHByb2Nlc3NOZXh0VGljayhvbkVuZE5ULCB0aGlzKTtcbn1cblxuZnVuY3Rpb24gb25FbmROVChzZWxmKSB7XG4gIHNlbGYuZW5kKCk7XG59XG5cbmZ1bmN0aW9uIGZvckVhY2goeHMsIGYpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBmKHhzW2ldLCBpKTtcbiAgfVxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fZHVwbGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAxMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGV4ZWMpe1xuICB0cnkge1xuICAgIHJldHVybiAhIWV4ZWMoKTtcbiAgfSBjYXRjaChlKXtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2ZhaWxzLmpzXG4vLyBtb2R1bGUgaWQgPSAxM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9faXRlcmF0b3JzLmpzXG4vLyBtb2R1bGUgaWQgPSAxNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyAxOS4xLjIuMTQgLyAxNS4yLjMuMTQgT2JqZWN0LmtleXMoTylcbnZhciAka2V5cyAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzLWludGVybmFsJylcbiAgLCBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiBrZXlzKE8pe1xuICByZXR1cm4gJGtleXMoTywgZW51bUJ1Z0tleXMpO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX29iamVjdC1rZXlzLmpzXG4vLyBtb2R1bGUgaWQgPSAxNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzXG4vLyBtb2R1bGUgaWQgPSAxNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKGl0KS5zbGljZSg4LCAtMSk7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fY29mLmpzXG4vLyBtb2R1bGUgaWQgPSAxN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBvcHRpb25hbCAvIHNpbXBsZSBjb250ZXh0IGJpbmRpbmdcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZuLCB0aGF0LCBsZW5ndGgpe1xuICBhRnVuY3Rpb24oZm4pO1xuICBpZih0aGF0ID09PSB1bmRlZmluZWQpcmV0dXJuIGZuO1xuICBzd2l0Y2gobGVuZ3RoKXtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbihhKXtcbiAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQsIGEpO1xuICAgIH07XG4gICAgY2FzZSAyOiByZXR1cm4gZnVuY3Rpb24oYSwgYil7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKGEsIGIsIGMpe1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYiwgYyk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24oLyogLi4uYXJncyAqLyl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoYXQsIGFyZ3VtZW50cyk7XG4gIH07XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fY3R4LmpzXG4vLyBtb2R1bGUgaWQgPSAxOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIHR5cGVvZiBpdCA9PT0gJ29iamVjdCcgPyBpdCAhPT0gbnVsbCA6IHR5cGVvZiBpdCA9PT0gJ2Z1bmN0aW9uJztcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pcy1vYmplY3QuanNcbi8vIG1vZHVsZSBpZCA9IDE5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYml0bWFwLCB2YWx1ZSl7XG4gIHJldHVybiB7XG4gICAgZW51bWVyYWJsZSAgOiAhKGJpdG1hcCAmIDEpLFxuICAgIGNvbmZpZ3VyYWJsZTogIShiaXRtYXAgJiAyKSxcbiAgICB3cml0YWJsZSAgICA6ICEoYml0bWFwICYgNCksXG4gICAgdmFsdWUgICAgICAgOiB2YWx1ZVxuICB9O1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3Byb3BlcnR5LWRlc2MuanNcbi8vIG1vZHVsZSBpZCA9IDIwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIid1c2Ugc3RyaWN0JztcbnZhciAkYXQgID0gcmVxdWlyZSgnLi9fc3RyaW5nLWF0JykodHJ1ZSk7XG5cbi8vIDIxLjEuMy4yNyBTdHJpbmcucHJvdG90eXBlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoU3RyaW5nLCAnU3RyaW5nJywgZnVuY3Rpb24oaXRlcmF0ZWQpe1xuICB0aGlzLl90ID0gU3RyaW5nKGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4vLyAyMS4xLjUuMi4xICVTdHJpbmdJdGVyYXRvclByb3RvdHlwZSUubmV4dCgpXG59LCBmdW5jdGlvbigpe1xuICB2YXIgTyAgICAgPSB0aGlzLl90XG4gICAgLCBpbmRleCA9IHRoaXMuX2lcbiAgICAsIHBvaW50O1xuICBpZihpbmRleCA+PSBPLmxlbmd0aClyZXR1cm4ge3ZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWV9O1xuICBwb2ludCA9ICRhdChPLCBpbmRleCk7XG4gIHRoaXMuX2kgKz0gcG9pbnQubGVuZ3RoO1xuICByZXR1cm4ge3ZhbHVlOiBwb2ludCwgZG9uZTogZmFsc2V9O1xufSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3IuanNcbi8vIG1vZHVsZSBpZCA9IDIxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBOT1RFOiBUaGVzZSB0eXBlIGNoZWNraW5nIGZ1bmN0aW9ucyBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBgaW5zdGFuY2VvZmBcbi8vIGJlY2F1c2UgaXQgaXMgZnJhZ2lsZSBhbmQgY2FuIGJlIGVhc2lseSBmYWtlZCB3aXRoIGBPYmplY3QuY3JlYXRlKClgLlxuXG5mdW5jdGlvbiBpc0FycmF5KGFyZykge1xuICBpZiAoQXJyYXkuaXNBcnJheSkge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KGFyZyk7XG4gIH1cbiAgcmV0dXJuIG9iamVjdFRvU3RyaW5nKGFyZykgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59XG5leHBvcnRzLmlzQXJyYXkgPSBpc0FycmF5O1xuXG5mdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnYm9vbGVhbic7XG59XG5leHBvcnRzLmlzQm9vbGVhbiA9IGlzQm9vbGVhbjtcblxuZnVuY3Rpb24gaXNOdWxsKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGwgPSBpc051bGw7XG5cbmZ1bmN0aW9uIGlzTnVsbE9yVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbE9yVW5kZWZpbmVkID0gaXNOdWxsT3JVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5leHBvcnRzLmlzTnVtYmVyID0gaXNOdW1iZXI7XG5cbmZ1bmN0aW9uIGlzU3RyaW5nKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N0cmluZyc7XG59XG5leHBvcnRzLmlzU3RyaW5nID0gaXNTdHJpbmc7XG5cbmZ1bmN0aW9uIGlzU3ltYm9sKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCc7XG59XG5leHBvcnRzLmlzU3ltYm9sID0gaXNTeW1ib2w7XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG5leHBvcnRzLmlzVW5kZWZpbmVkID0gaXNVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzUmVnRXhwKHJlKSB7XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuZXhwb3J0cy5pc1JlZ0V4cCA9IGlzUmVnRXhwO1xuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5leHBvcnRzLmlzRGF0ZSA9IGlzRGF0ZTtcblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiAob2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXScgfHwgZSBpbnN0YW5jZW9mIEVycm9yKTtcbn1cbmV4cG9ydHMuaXNFcnJvciA9IGlzRXJyb3I7XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGwgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3ltYm9sJyB8fCAgLy8gRVM2IHN5bWJvbFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3VuZGVmaW5lZCc7XG59XG5leHBvcnRzLmlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmU7XG5cbmV4cG9ydHMuaXNCdWZmZXIgPSBCdWZmZXIuaXNCdWZmZXI7XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLXV0aWwtaXMvbGliL3V0aWwuanNcbi8vIG1vZHVsZSBpZCA9IDIyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBnO1xyXG5cclxuLy8gVGhpcyB3b3JrcyBpbiBub24tc3RyaWN0IG1vZGVcclxuZyA9IChmdW5jdGlvbigpIHtcclxuXHRyZXR1cm4gdGhpcztcclxufSkoKTtcclxuXHJcbnRyeSB7XHJcblx0Ly8gVGhpcyB3b3JrcyBpZiBldmFsIGlzIGFsbG93ZWQgKHNlZSBDU1ApXHJcblx0ZyA9IGcgfHwgRnVuY3Rpb24oXCJyZXR1cm4gdGhpc1wiKSgpIHx8ICgxLGV2YWwpKFwidGhpc1wiKTtcclxufSBjYXRjaChlKSB7XHJcblx0Ly8gVGhpcyB3b3JrcyBpZiB0aGUgd2luZG93IHJlZmVyZW5jZSBpcyBhdmFpbGFibGVcclxuXHRpZih0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiKVxyXG5cdFx0ZyA9IHdpbmRvdztcclxufVxyXG5cclxuLy8gZyBjYW4gc3RpbGwgYmUgdW5kZWZpbmVkLCBidXQgbm90aGluZyB0byBkbyBhYm91dCBpdC4uLlxyXG4vLyBXZSByZXR1cm4gdW5kZWZpbmVkLCBpbnN0ZWFkIG9mIG5vdGhpbmcgaGVyZSwgc28gaXQnc1xyXG4vLyBlYXNpZXIgdG8gaGFuZGxlIHRoaXMgY2FzZS4gaWYoIWdsb2JhbCkgeyAuLi59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGc7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vICh3ZWJwYWNrKS9idWlsZGluL2dsb2JhbC5qc1xuLy8gbW9kdWxlIGlkID0gMjNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiKGZ1bmN0aW9uKHJvb3QsIGZhY3Rvcnkpe1xuXG5cdC8vVU1EXG5cdGlmICggdHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQgKSB7XG5cdFx0ZGVmaW5lKGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGZhY3RvcnkoKTtcblx0XHR9KTtcblx0fSBlbHNlIGlmICh0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiKSB7XG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XG4gXHR9IGVsc2Uge1xuXHRcdHJvb3QuVG9uZSA9IGZhY3RvcnkoKTtcblx0fVxuXG59KHRoaXMsIGZ1bmN0aW9uKCl7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgVG9uZTtcblx0Ly9jb25zdHJ1Y3RzIHRoZSBtYWluIFRvbmUgb2JqZWN0XG5cdGZ1bmN0aW9uIE1haW4oZnVuYyl7XG5cdFx0VG9uZSA9IGZ1bmMoKTtcblx0fVxuXHQvL2ludm9rZXMgZWFjaCBvZiB0aGUgbW9kdWxlcyB3aXRoIHRoZSBtYWluIFRvbmUgb2JqZWN0IGFzIHRoZSBhcmd1bWVudFxuXHRmdW5jdGlvbiBNb2R1bGUoZnVuYyl7XG5cdFx0ZnVuYyhUb25lKTtcblx0fVx0LyoqXG5cdCAqICBUb25lLmpzXG5cdCAqICBAYXV0aG9yIFlvdGFtIE1hbm5cblx0ICogIEBsaWNlbnNlIGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQgTUlUIExpY2Vuc2Vcblx0ICogIEBjb3B5cmlnaHQgMjAxNC0yMDE4IFlvdGFtIE1hbm5cblx0ICovXG5cdE1haW4oZnVuY3Rpb24gKCkge1xuXHQgICAgXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRUT05FXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIFRvbmUgaXMgdGhlIGJhc2UgY2xhc3Mgb2YgYWxsIG90aGVyIGNsYXNzZXMuXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqL1xuXHQgICAgdmFyIFRvbmUgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFRvbmUpKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignY29uc3RydWN0b3IgbmVlZHMgdG8gYmUgY2FsbGVkIHdpdGggdGhlIFxcJ25ld1xcJyBrZXl3b3JkJyk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZSNcblx0XHQgKiAgQHJldHVybnMge1N0cmluZ30gcmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgYXMgYSBzdHJpbmdcblx0XHQgKi9cblx0ICAgIFRvbmUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGZvciAodmFyIGNsYXNzTmFtZSBpbiBUb25lKSB7XG5cdCAgICAgICAgICAgIHZhciBpc0xldHRlciA9IGNsYXNzTmFtZVswXS5tYXRjaCgvXltBLVpdJC8pO1xuXHQgICAgICAgICAgICB2YXIgc2FtZUNvbnN0cnVjdG9yID0gVG9uZVtjbGFzc05hbWVdID09PSB0aGlzLmNvbnN0cnVjdG9yO1xuXHQgICAgICAgICAgICBpZiAoVG9uZS5pc0Z1bmN0aW9uKFRvbmVbY2xhc3NOYW1lXSkgJiYgaXNMZXR0ZXIgJiYgc2FtZUNvbnN0cnVjdG9yKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY2xhc3NOYW1lO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiAnVG9uZSc7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lI1xuXHRcdCAqICBkaXNjb25uZWN0IGFuZCBkaXNwb3NlXG5cdFx0ICogIEByZXR1cm5zIHtUb25lfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLy9cdEdFVC9TRVRcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLyoqXG5cdFx0ICogIFNldCB0aGUgcGFyYW1ldGVycyBhdCBvbmNlLiBFaXRoZXIgcGFzcyBpbiBhblxuXHRcdCAqICBvYmplY3QgbWFwcGluZyBwYXJhbWV0ZXJzIHRvIHZhbHVlcywgb3IgdG8gc2V0IGFcblx0XHQgKiAgc2luZ2xlIHBhcmFtZXRlciwgYnkgcGFzc2luZyBpbiBhIHN0cmluZyBhbmQgdmFsdWUuXG5cdFx0ICogIFRoZSBsYXN0IGFyZ3VtZW50IGlzIGFuIG9wdGlvbmFsIHJhbXAgdGltZSB3aGljaFxuXHRcdCAqICB3aWxsIHJhbXAgYW55IHNpZ25hbCB2YWx1ZXMgdG8gdGhlaXIgZGVzdGluYXRpb24gdmFsdWVcblx0XHQgKiAgb3ZlciB0aGUgZHVyYXRpb24gb2YgdGhlIHJhbXBUaW1lLlxuXHRcdCAqICBAcGFyYW0ge09iamVjdHxTdHJpbmd9IHBhcmFtc1xuXHRcdCAqICBAcGFyYW0ge051bWJlcj19IHZhbHVlXG5cdFx0ICogIEBwYXJhbSB7VGltZT19IHJhbXBUaW1lXG5cdFx0ICogIEByZXR1cm5zIHtUb25lfSB0aGlzXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lI1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vc2V0IHZhbHVlcyB1c2luZyBhbiBvYmplY3Rcblx0XHQgKiBmaWx0ZXIuc2V0KHtcblx0XHQgKiBcdFwiZnJlcXVlbmN5XCIgOiAzMDAsXG5cdFx0ICogXHRcInR5cGVcIiA6IGhpZ2hwYXNzXG5cdFx0ICogfSk7XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogZmlsdGVyLnNldChcInR5cGVcIiwgXCJoaWdocGFzc1wiKTtcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL3JhbXAgdG8gdGhlIHZhbHVlIDIyMCBvdmVyIDMgc2Vjb25kcy5cblx0XHQgKiBvc2NpbGxhdG9yLnNldCh7XG5cdFx0ICogXHRcImZyZXF1ZW5jeVwiIDogMjIwXG5cdFx0ICogfSwgMyk7XG5cdFx0ICovXG5cdCAgICBUb25lLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAocGFyYW1zLCB2YWx1ZSwgcmFtcFRpbWUpIHtcblx0ICAgICAgICBpZiAoVG9uZS5pc09iamVjdChwYXJhbXMpKSB7XG5cdCAgICAgICAgICAgIHJhbXBUaW1lID0gdmFsdWU7XG5cdCAgICAgICAgfSBlbHNlIGlmIChUb25lLmlzU3RyaW5nKHBhcmFtcykpIHtcblx0ICAgICAgICAgICAgdmFyIHRtcE9iaiA9IHt9O1xuXHQgICAgICAgICAgICB0bXBPYmpbcGFyYW1zXSA9IHZhbHVlO1xuXHQgICAgICAgICAgICBwYXJhbXMgPSB0bXBPYmo7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHBhcmFtTG9vcDpcblx0ICAgICAgICAgICAgZm9yICh2YXIgYXR0ciBpbiBwYXJhbXMpIHtcblx0ICAgICAgICAgICAgICAgIHZhbHVlID0gcGFyYW1zW2F0dHJdO1xuXHQgICAgICAgICAgICAgICAgdmFyIHBhcmVudCA9IHRoaXM7XG5cdCAgICAgICAgICAgICAgICBpZiAoYXR0ci5pbmRleE9mKCcuJykgIT09IC0xKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJTcGxpdCA9IGF0dHIuc3BsaXQoJy4nKTtcblx0ICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJTcGxpdC5sZW5ndGggLSAxOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gcGFyZW50W2F0dHJTcGxpdFtpXV07XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBUb25lKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyU3BsaXQuc3BsaWNlKDAsIGkgKyAxKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbm5lclBhcmFtID0gYXR0clNwbGl0LmpvaW4oJy4nKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5zZXQoaW5uZXJQYXJhbSwgdmFsdWUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgcGFyYW1Mb29wO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgIGF0dHIgPSBhdHRyU3BsaXRbYXR0clNwbGl0Lmxlbmd0aCAtIDFdO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgdmFyIHBhcmFtID0gcGFyZW50W2F0dHJdO1xuXHQgICAgICAgICAgICAgICAgaWYgKFRvbmUuaXNVbmRlZihwYXJhbSkpIHtcblx0ICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGlmIChUb25lLlNpZ25hbCAmJiBwYXJhbSBpbnN0YW5jZW9mIFRvbmUuU2lnbmFsIHx8IFRvbmUuUGFyYW0gJiYgcGFyYW0gaW5zdGFuY2VvZiBUb25lLlBhcmFtKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmFtLnZhbHVlICE9PSB2YWx1ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBpZiAoVG9uZS5pc1VuZGVmKHJhbXBUaW1lKSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW0udmFsdWUgPSB2YWx1ZTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtLnJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJhbSBpbnN0YW5jZW9mIEF1ZGlvUGFyYW0pIHtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAocGFyYW0udmFsdWUgIT09IHZhbHVlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtLnZhbHVlID0gdmFsdWU7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChUb25lLlRpbWVCYXNlICYmIHBhcmFtIGluc3RhbmNlb2YgVG9uZS5UaW1lQmFzZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHBhcmVudFthdHRyXSA9IHZhbHVlO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJhbSBpbnN0YW5jZW9mIFRvbmUpIHtcblx0ICAgICAgICAgICAgICAgICAgICBwYXJhbS5zZXQodmFsdWUpO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJhbSAhPT0gdmFsdWUpIHtcblx0ICAgICAgICAgICAgICAgICAgICBwYXJlbnRbYXR0cl0gPSB2YWx1ZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBHZXQgdGhlIG9iamVjdCdzIGF0dHJpYnV0ZXMuIEdpdmVuIG5vIGFyZ3VtZW50cyBnZXRcblx0XHQgKiAgd2lsbCByZXR1cm4gYWxsIGF2YWlsYWJsZSBvYmplY3QgcHJvcGVydGllcyBhbmQgdGhlaXIgY29ycmVzcG9uZGluZ1xuXHRcdCAqICB2YWx1ZXMuIFBhc3MgaW4gYSBzaW5nbGUgYXR0cmlidXRlIHRvIHJldHJpZXZlIG9yIGFuIGFycmF5XG5cdFx0ICogIG9mIGF0dHJpYnV0ZXMuIFRoZSBhdHRyaWJ1dGUgc3RyaW5ncyBjYW4gYWxzbyBpbmNsdWRlIGEgXCIuXCJcblx0XHQgKiAgdG8gYWNjZXNzIGRlZXBlciBwcm9wZXJ0aWVzLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZSNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBvc2MuZ2V0KCk7XG5cdFx0ICogLy9yZXR1cm5zIHtcInR5cGVcIiA6IFwic2luZVwiLCBcImZyZXF1ZW5jeVwiIDogNDQwLCAuLi5ldGN9XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogb3NjLmdldChcInR5cGVcIik7XG5cdFx0ICogLy9yZXR1cm5zIHsgXCJ0eXBlXCIgOiBcInNpbmVcIn1cblx0XHQgKiBAZXhhbXBsZVxuXHRcdCAqIC8vdXNlIGRvdCBub3RhdGlvbiB0byBhY2Nlc3MgZGVlcCBwcm9wZXJ0aWVzXG5cdFx0ICogc3ludGguZ2V0KFtcImVudmVsb3BlLmF0dGFja1wiLCBcImVudmVsb3BlLnJlbGVhc2VcIl0pO1xuXHRcdCAqIC8vcmV0dXJucyB7XCJlbnZlbG9wZVwiIDoge1wiYXR0YWNrXCIgOiAwLjIsIFwicmVsZWFzZVwiIDogMC40fX1cblx0XHQgKiAgQHBhcmFtIHtBcnJheT18c3RyaW5nfHVuZGVmaW5lZH0gcGFyYW1zIHRoZSBwYXJhbWV0ZXJzIHRvIGdldCwgb3RoZXJ3aXNlIHdpbGwgcmV0dXJuXG5cdFx0ICogIFx0XHRcdFx0XHQgICAgICAgICAgICAgICAgICBhbGwgYXZhaWxhYmxlLlxuXHRcdCAqICBAcmV0dXJucyB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKHBhcmFtcykge1xuXHQgICAgICAgIGlmIChUb25lLmlzVW5kZWYocGFyYW1zKSkge1xuXHQgICAgICAgICAgICBwYXJhbXMgPSB0aGlzLl9jb2xsZWN0RGVmYXVsdHModGhpcy5jb25zdHJ1Y3Rvcik7XG5cdCAgICAgICAgfSBlbHNlIGlmIChUb25lLmlzU3RyaW5nKHBhcmFtcykpIHtcblx0ICAgICAgICAgICAgcGFyYW1zID0gW3BhcmFtc107XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHZhciByZXQgPSB7fTtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBhcmFtcy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICB2YXIgYXR0ciA9IHBhcmFtc1tpXTtcblx0ICAgICAgICAgICAgdmFyIHBhcmVudCA9IHRoaXM7XG5cdCAgICAgICAgICAgIHZhciBzdWJSZXQgPSByZXQ7XG5cdCAgICAgICAgICAgIGlmIChhdHRyLmluZGV4T2YoJy4nKSAhPT0gLTEpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBhdHRyU3BsaXQgPSBhdHRyLnNwbGl0KCcuJyk7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGF0dHJTcGxpdC5sZW5ndGggLSAxOyBqKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgc3ViQXR0ciA9IGF0dHJTcGxpdFtqXTtcblx0ICAgICAgICAgICAgICAgICAgICBzdWJSZXRbc3ViQXR0cl0gPSBzdWJSZXRbc3ViQXR0cl0gfHwge307XG5cdCAgICAgICAgICAgICAgICAgICAgc3ViUmV0ID0gc3ViUmV0W3N1YkF0dHJdO1xuXHQgICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudFtzdWJBdHRyXTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGF0dHIgPSBhdHRyU3BsaXRbYXR0clNwbGl0Lmxlbmd0aCAtIDFdO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHZhciBwYXJhbSA9IHBhcmVudFthdHRyXTtcblx0ICAgICAgICAgICAgaWYgKFRvbmUuaXNPYmplY3QocGFyYW1zW2F0dHJdKSkge1xuXHQgICAgICAgICAgICAgICAgc3ViUmV0W2F0dHJdID0gcGFyYW0uZ2V0KCk7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAoVG9uZS5TaWduYWwgJiYgcGFyYW0gaW5zdGFuY2VvZiBUb25lLlNpZ25hbCkge1xuXHQgICAgICAgICAgICAgICAgc3ViUmV0W2F0dHJdID0gcGFyYW0udmFsdWU7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAoVG9uZS5QYXJhbSAmJiBwYXJhbSBpbnN0YW5jZW9mIFRvbmUuUGFyYW0pIHtcblx0ICAgICAgICAgICAgICAgIHN1YlJldFthdHRyXSA9IHBhcmFtLnZhbHVlO1xuXHQgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmFtIGluc3RhbmNlb2YgQXVkaW9QYXJhbSkge1xuXHQgICAgICAgICAgICAgICAgc3ViUmV0W2F0dHJdID0gcGFyYW0udmFsdWU7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAocGFyYW0gaW5zdGFuY2VvZiBUb25lKSB7XG5cdCAgICAgICAgICAgICAgICBzdWJSZXRbYXR0cl0gPSBwYXJhbS5nZXQoKTtcblx0ICAgICAgICAgICAgfSBlbHNlIGlmICghVG9uZS5pc0Z1bmN0aW9uKHBhcmFtKSAmJiBUb25lLmlzRGVmaW5lZChwYXJhbSkpIHtcblx0ICAgICAgICAgICAgICAgIHN1YlJldFthdHRyXSA9IHBhcmFtO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiByZXQ7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIGNvbGxlY3QgYWxsIG9mIHRoZSBkZWZhdWx0IGF0dHJpYnV0ZXMgaW4gb25lXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICogIEBwYXJhbSB7RnVuY3Rpb259IGNvbnN0ciB0aGUgY29uc3RydWN0b3IgdG8gZmluZCB0aGUgZGVmYXVsdHMgZnJvbVxuXHRcdCAqICBAcmV0dXJuIHtBcnJheX0gYWxsIG9mIHRoZSBhdHRyaWJ1dGVzIHdoaWNoIGJlbG9uZyB0byB0aGUgY2xhc3Ncblx0XHQgKi9cblx0ICAgIFRvbmUucHJvdG90eXBlLl9jb2xsZWN0RGVmYXVsdHMgPSBmdW5jdGlvbiAoY29uc3RyKSB7XG5cdCAgICAgICAgdmFyIHJldCA9IFtdO1xuXHQgICAgICAgIGlmIChUb25lLmlzRGVmaW5lZChjb25zdHIuZGVmYXVsdHMpKSB7XG5cdCAgICAgICAgICAgIHJldCA9IE9iamVjdC5rZXlzKGNvbnN0ci5kZWZhdWx0cyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChUb25lLmlzRGVmaW5lZChjb25zdHIuX3N1cGVyKSkge1xuXHQgICAgICAgICAgICB2YXIgc3VwZXJEZWZzID0gdGhpcy5fY29sbGVjdERlZmF1bHRzKGNvbnN0ci5fc3VwZXIpO1xuXHQgICAgICAgICAgICAvL2ZpbHRlciBvdXQgcmVwZWF0c1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN1cGVyRGVmcy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgaWYgKHJldC5pbmRleE9mKHN1cGVyRGVmc1tpXSkgPT09IC0xKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0LnB1c2goc3VwZXJEZWZzW2ldKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gcmV0O1xuXHQgICAgfTtcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLy9cdERFRkFVTFRTXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZVxuXHRcdCAqICBAcGFyYW0gIHtBcnJheX0gIHZhbHVlcyAgVGhlIGFyZ3VtZW50cyBhcnJheVxuXHRcdCAqICBAcGFyYW0gIHtBcnJheX0gIGtleXMgICAgVGhlIG5hbWVzIG9mIHRoZSBhcmd1bWVudHNcblx0XHQgKiAgQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R9IGNvbnN0ciBUaGUgY2xhc3MgY29uc3RydWN0b3Jcblx0XHQgKiAgQHJldHVybiAge09iamVjdH0gIEFuIG9iamVjdCBjb21wb3NlZCBvZiB0aGUgIGRlZmF1bHRzIGJldHdlZW4gdGhlIGNsYXNzJyBkZWZhdWx0c1xuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgYW5kIHRoZSBwYXNzZWQgaW4gYXJndW1lbnRzLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5kZWZhdWx0cyA9IGZ1bmN0aW9uICh2YWx1ZXMsIGtleXMsIGNvbnN0cikge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0ge307XG5cdCAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPT09IDEgJiYgVG9uZS5pc09iamVjdCh2YWx1ZXNbMF0pKSB7XG5cdCAgICAgICAgICAgIG9wdGlvbnMgPSB2YWx1ZXNbMF07XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBvcHRpb25zW2tleXNbaV1dID0gdmFsdWVzW2ldO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChUb25lLmlzRGVmaW5lZChjb25zdHIuZGVmYXVsdHMpKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBUb25lLmRlZmF1bHRBcmcob3B0aW9ucywgY29uc3RyLmRlZmF1bHRzKTtcblx0ICAgICAgICB9IGVsc2UgaWYgKFRvbmUuaXNPYmplY3QoY29uc3RyKSkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5kZWZhdWx0QXJnKG9wdGlvbnMsIGNvbnN0cik7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnM7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBJZiB0aGUgYGdpdmVuYCBwYXJhbWV0ZXIgaXMgdW5kZWZpbmVkLCB1c2UgdGhlIGBmYWxsYmFja2AuXG5cdFx0ICogIElmIGJvdGggYGdpdmVuYCBhbmQgYGZhbGxiYWNrYCBhcmUgb2JqZWN0IGxpdGVyYWxzLCBpdCB3aWxsXG5cdFx0ICogIHJldHVybiBhIGRlZXAgY29weSB3aGljaCBpbmNsdWRlcyBhbGwgb2YgdGhlIHBhcmFtZXRlcnMgZnJvbSBib3RoXG5cdFx0ICogIG9iamVjdHMuIElmIGEgcGFyYW1ldGVyIGlzIHVuZGVmaW5lZCBpbiBnaXZlbiwgaXQgd2lsbCByZXR1cm5cblx0XHQgKiAgdGhlIGZhbGxiYWNrIHByb3BlcnR5LlxuXHRcdCAqICA8YnI+PGJyPlxuXHRcdCAqICBXQVJOSU5HOiBpZiBvYmplY3QgaXMgc2VsZiByZWZlcmVudGlhbCwgaXQgd2lsbCBnbyBpbnRvIGFuIGFuXG5cdFx0ICogIGluZmluaXRlIHJlY3Vyc2l2ZSBsb29wLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZVxuXHRcdCAqICBAcGFyYW0gIHsqfSBnaXZlblxuXHRcdCAqICBAcGFyYW0gIHsqfSBmYWxsYmFja1xuXHRcdCAqICBAcmV0dXJuIHsqfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5kZWZhdWx0QXJnID0gZnVuY3Rpb24gKGdpdmVuLCBmYWxsYmFjaykge1xuXHQgICAgICAgIGlmIChUb25lLmlzT2JqZWN0KGdpdmVuKSAmJiBUb25lLmlzT2JqZWN0KGZhbGxiYWNrKSkge1xuXHQgICAgICAgICAgICB2YXIgcmV0ID0ge307XG5cdCAgICAgICAgICAgIC8vbWFrZSBhIGRlZXAgY29weSBvZiB0aGUgZ2l2ZW4gb2JqZWN0XG5cdCAgICAgICAgICAgIGZvciAodmFyIGdpdmVuUHJvcCBpbiBnaXZlbikge1xuXHQgICAgICAgICAgICAgICAgcmV0W2dpdmVuUHJvcF0gPSBUb25lLmRlZmF1bHRBcmcoZmFsbGJhY2tbZ2l2ZW5Qcm9wXSwgZ2l2ZW5bZ2l2ZW5Qcm9wXSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgZm9yICh2YXIgZmFsbGJhY2tQcm9wIGluIGZhbGxiYWNrKSB7XG5cdCAgICAgICAgICAgICAgICByZXRbZmFsbGJhY2tQcm9wXSA9IFRvbmUuZGVmYXVsdEFyZyhnaXZlbltmYWxsYmFja1Byb3BdLCBmYWxsYmFja1tmYWxsYmFja1Byb3BdKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICByZXR1cm4gcmV0O1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHJldHVybiBUb25lLmlzVW5kZWYoZ2l2ZW4pID8gZmFsbGJhY2sgOiBnaXZlbjtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvL1x0Q09OTkVDVElPTlNcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLyoqXG5cdFx0ICogIGNvbm5lY3QgdG9nZXRoZXIgYWxsIG9mIHRoZSBhcmd1bWVudHMgaW4gc2VyaWVzXG5cdFx0ICogIEBwYXJhbSB7Li4uQXVkaW9QYXJhbXxUb25lfEF1ZGlvTm9kZX0gbm9kZXNcblx0XHQgKiAgQHJldHVybnMge1RvbmV9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKi9cblx0ICAgIFRvbmUuY29ubmVjdFNlcmllcyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgY3VycmVudFVuaXQgPSBhcmd1bWVudHNbMF07XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgdmFyIHRvVW5pdCA9IGFyZ3VtZW50c1tpXTtcblx0ICAgICAgICAgICAgY3VycmVudFVuaXQuY29ubmVjdCh0b1VuaXQpO1xuXHQgICAgICAgICAgICBjdXJyZW50VW5pdCA9IHRvVW5pdDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIFRvbmU7XG5cdCAgICB9O1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvLyBUWVBFIENIRUNLSU5HXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBUZXN0IGlmIHRoZSBhcmcgaXMgdW5kZWZpbmVkXG5cdFx0ICogIEBwYXJhbSB7Kn0gYXJnIHRoZSBhcmd1bWVudCB0byB0ZXN0XG5cdFx0ICogIEByZXR1cm5zIHtCb29sZWFufSB0cnVlIGlmIHRoZSBhcmcgaXMgdW5kZWZpbmVkXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQG1lbWJlck9mIFRvbmVcblx0XHQgKi9cblx0ICAgIFRvbmUuaXNVbmRlZiA9IGZ1bmN0aW9uICh2YWwpIHtcblx0ICAgICAgICByZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ3VuZGVmaW5lZCc7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRlc3QgaWYgdGhlIGFyZyBpcyBub3QgdW5kZWZpbmVkXG5cdFx0ICogIEBwYXJhbSB7Kn0gYXJnIHRoZSBhcmd1bWVudCB0byB0ZXN0XG5cdFx0ICogIEByZXR1cm5zIHtCb29sZWFufSB0cnVlIGlmIHRoZSBhcmcgaXMgdW5kZWZpbmVkXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQG1lbWJlck9mIFRvbmVcblx0XHQgKi9cblx0ICAgIFRvbmUuaXNEZWZpbmVkID0gZnVuY3Rpb24gKHZhbCkge1xuXHQgICAgICAgIHJldHVybiAhVG9uZS5pc1VuZGVmKHZhbCk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRlc3QgaWYgdGhlIGFyZyBpcyBhIGZ1bmN0aW9uXG5cdFx0ICogIEBwYXJhbSB7Kn0gYXJnIHRoZSBhcmd1bWVudCB0byB0ZXN0XG5cdFx0ICogIEByZXR1cm5zIHtCb29sZWFufSB0cnVlIGlmIHRoZSBhcmcgaXMgYSBmdW5jdGlvblxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lXG5cdFx0ICovXG5cdCAgICBUb25lLmlzRnVuY3Rpb24gPSBmdW5jdGlvbiAodmFsKSB7XG5cdCAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdmdW5jdGlvbic7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRlc3QgaWYgdGhlIGFyZ3VtZW50IGlzIGEgbnVtYmVyLlxuXHRcdCAqICBAcGFyYW0geyp9IGFyZyB0aGUgYXJndW1lbnQgdG8gdGVzdFxuXHRcdCAqICBAcmV0dXJucyB7Qm9vbGVhbn0gdHJ1ZSBpZiB0aGUgYXJnIGlzIGEgbnVtYmVyXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQG1lbWJlck9mIFRvbmVcblx0XHQgKi9cblx0ICAgIFRvbmUuaXNOdW1iZXIgPSBmdW5jdGlvbiAoYXJnKSB7XG5cdCAgICAgICAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUZXN0IGlmIHRoZSBnaXZlbiBhcmd1bWVudCBpcyBhbiBvYmplY3QgbGl0ZXJhbCAoaS5lLiBge31gKTtcblx0XHQgKiAgQHBhcmFtIHsqfSBhcmcgdGhlIGFyZ3VtZW50IHRvIHRlc3Rcblx0XHQgKiAgQHJldHVybnMge0Jvb2xlYW59IHRydWUgaWYgdGhlIGFyZyBpcyBhbiBvYmplY3QgbGl0ZXJhbC5cblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAbWVtYmVyT2YgVG9uZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5pc09iamVjdCA9IGZ1bmN0aW9uIChhcmcpIHtcblx0ICAgICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZykgPT09ICdbb2JqZWN0IE9iamVjdF0nICYmIGFyZy5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0O1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUZXN0IGlmIHRoZSBhcmd1bWVudCBpcyBhIGJvb2xlYW4uXG5cdFx0ICogIEBwYXJhbSB7Kn0gYXJnIHRoZSBhcmd1bWVudCB0byB0ZXN0XG5cdFx0ICogIEByZXR1cm5zIHtCb29sZWFufSB0cnVlIGlmIHRoZSBhcmcgaXMgYSBib29sZWFuXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQG1lbWJlck9mIFRvbmVcblx0XHQgKi9cblx0ICAgIFRvbmUuaXNCb29sZWFuID0gZnVuY3Rpb24gKGFyZykge1xuXHQgICAgICAgIHJldHVybiB0eXBlb2YgYXJnID09PSAnYm9vbGVhbic7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRlc3QgaWYgdGhlIGFyZ3VtZW50IGlzIGFuIEFycmF5XG5cdFx0ICogIEBwYXJhbSB7Kn0gYXJnIHRoZSBhcmd1bWVudCB0byB0ZXN0XG5cdFx0ICogIEByZXR1cm5zIHtCb29sZWFufSB0cnVlIGlmIHRoZSBhcmcgaXMgYW4gYXJyYXlcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAbWVtYmVyT2YgVG9uZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5pc0FycmF5ID0gZnVuY3Rpb24gKGFyZykge1xuXHQgICAgICAgIHJldHVybiBBcnJheS5pc0FycmF5KGFyZyk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRlc3QgaWYgdGhlIGFyZ3VtZW50IGlzIGEgc3RyaW5nLlxuXHRcdCAqICBAcGFyYW0geyp9IGFyZyB0aGUgYXJndW1lbnQgdG8gdGVzdFxuXHRcdCAqICBAcmV0dXJucyB7Qm9vbGVhbn0gdHJ1ZSBpZiB0aGUgYXJnIGlzIGEgc3RyaW5nXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQG1lbWJlck9mIFRvbmVcblx0XHQgKi9cblx0ICAgIFRvbmUuaXNTdHJpbmcgPSBmdW5jdGlvbiAoYXJnKSB7XG5cdCAgICAgICAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUZXN0IGlmIHRoZSBhcmd1bWVudCBpcyBpbiB0aGUgZm9ybSBvZiBhIG5vdGUgaW4gc2NpZW50aWZpYyBwaXRjaCBub3RhdGlvbi5cblx0XHQgKiAgZS5nLiBcIkM0XCJcblx0XHQgKiAgQHBhcmFtIHsqfSBhcmcgdGhlIGFyZ3VtZW50IHRvIHRlc3Rcblx0XHQgKiAgQHJldHVybnMge0Jvb2xlYW59IHRydWUgaWYgdGhlIGFyZyBpcyBhIHN0cmluZ1xuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lXG5cdFx0ICovXG5cdCAgICBUb25lLmlzTm90ZSA9IGZ1bmN0aW9uIChhcmcpIHtcblx0ICAgICAgICByZXR1cm4gVG9uZS5pc1N0cmluZyhhcmcpICYmIC9eKFthLWddezF9KD86YnwjfHh8YmIpPykoLT9bMC05XSspL2kudGVzdChhcmcpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBBbiBlbXB0eSBmdW5jdGlvbi5cblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqL1xuXHQgICAgVG9uZS5ub09wID0gZnVuY3Rpb24gKCkge1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBNYWtlIHRoZSBwcm9wZXJ0eSBub3Qgd3JpdGFibGUuIEludGVybmFsIHVzZSBvbmx5LlxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd9ICBwcm9wZXJ0eSAgdGhlIHByb3BlcnR5IHRvIG1ha2Ugbm90IHdyaXRhYmxlXG5cdFx0ICovXG5cdCAgICBUb25lLnByb3RvdHlwZS5fcmVhZE9ubHkgPSBmdW5jdGlvbiAocHJvcGVydHkpIHtcblx0ICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwcm9wZXJ0eSkpIHtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wZXJ0eS5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fcmVhZE9ubHkocHJvcGVydHlbaV0pO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIHByb3BlcnR5LCB7XG5cdCAgICAgICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgTWFrZSBhbiBhdHRyaWJ1dGUgd3JpdGVhYmxlLiBJbnRlcmFsIHVzZSBvbmx5LlxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd9ICBwcm9wZXJ0eSAgdGhlIHByb3BlcnR5IHRvIG1ha2Ugd3JpdGFibGVcblx0XHQgKi9cblx0ICAgIFRvbmUucHJvdG90eXBlLl93cml0YWJsZSA9IGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuXHQgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHByb3BlcnR5KSkge1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BlcnR5Lmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl93cml0YWJsZShwcm9wZXJ0eVtpXSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgcHJvcGVydHksIHsgd3JpdGFibGU6IHRydWUgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFBvc3NpYmxlIHBsYXkgc3RhdGVzLlxuXHRcdCAqIEBlbnVtIHtTdHJpbmd9XG5cdFx0ICovXG5cdCAgICBUb25lLlN0YXRlID0ge1xuXHQgICAgICAgIFN0YXJ0ZWQ6ICdzdGFydGVkJyxcblx0ICAgICAgICBTdG9wcGVkOiAnc3RvcHBlZCcsXG5cdCAgICAgICAgUGF1c2VkOiAncGF1c2VkJ1xuXHQgICAgfTtcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLy8gQ09OVkVSU0lPTlNcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLyoqXG5cdFx0ICogIEVxdWFsIHBvd2VyIGdhaW4gc2NhbGUuIEdvb2QgZm9yIGNyb3NzLWZhZGluZy5cblx0XHQgKiAgQHBhcmFtICB7Tm9ybWFsUmFuZ2V9IHBlcmNlbnQgKDAtMSlcblx0XHQgKiAgQHJldHVybiB7TnVtYmVyfSAgICAgICAgIG91dHB1dCBnYWluICgwLTEpXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQG1lbWJlck9mIFRvbmVcblx0XHQgKi9cblx0ICAgIFRvbmUuZXF1YWxQb3dlclNjYWxlID0gZnVuY3Rpb24gKHBlcmNlbnQpIHtcblx0ICAgICAgICB2YXIgcGlGYWN0b3IgPSAwLjUgKiBNYXRoLlBJO1xuXHQgICAgICAgIHJldHVybiBNYXRoLnNpbihwZXJjZW50ICogcGlGYWN0b3IpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDb252ZXJ0IGRlY2liZWxzIGludG8gZ2Fpbi5cblx0XHQgKiAgQHBhcmFtICB7RGVjaWJlbHN9IGRiXG5cdFx0ICogIEByZXR1cm4ge051bWJlcn1cblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAbWVtYmVyT2YgVG9uZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5kYlRvR2FpbiA9IGZ1bmN0aW9uIChkYikge1xuXHQgICAgICAgIHJldHVybiBNYXRoLnBvdygxMCwgZGIgLyAyMCk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENvbnZlcnQgZ2FpbiB0byBkZWNpYmVscy5cblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSBnYWluICgwLTEpXG5cdFx0ICogIEByZXR1cm4ge0RlY2liZWxzfVxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lXG5cdFx0ICovXG5cdCAgICBUb25lLmdhaW5Ub0RiID0gZnVuY3Rpb24gKGdhaW4pIHtcblx0ICAgICAgICByZXR1cm4gMjAgKiAoTWF0aC5sb2coZ2FpbikgLyBNYXRoLkxOMTApO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDb252ZXJ0IGFuIGludGVydmFsIChpbiBzZW1pdG9uZXMpIHRvIGEgZnJlcXVlbmN5IHJhdGlvLlxuXHRcdCAqICBAcGFyYW0gIHtJbnRlcnZhbH0gaW50ZXJ2YWwgdGhlIG51bWJlciBvZiBzZW1pdG9uZXMgYWJvdmUgdGhlIGJhc2Ugbm90ZVxuXHRcdCAqICBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgICAgIHRoZSBmcmVxdWVuY3kgcmF0aW9cblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAbWVtYmVyT2YgVG9uZVxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHRvbmUuaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKDApOyAvLyAxXG5cdFx0ICogdG9uZS5pbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oMTIpOyAvLyAyXG5cdFx0ICogdG9uZS5pbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oLTEyKTsgLy8gMC41XG5cdFx0ICovXG5cdCAgICBUb25lLmludGVydmFsVG9GcmVxdWVuY3lSYXRpbyA9IGZ1bmN0aW9uIChpbnRlcnZhbCkge1xuXHQgICAgICAgIHJldHVybiBNYXRoLnBvdygyLCBpbnRlcnZhbCAvIDEyKTtcblx0ICAgIH07XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRUSU1JTkdcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybiB0aGUgY3VycmVudCB0aW1lIG9mIHRoZSBBdWRpb0NvbnRleHQgY2xvY2suXG5cdFx0ICogIEByZXR1cm4ge051bWJlcn0gdGhlIGN1cnJlbnRUaW1lIGZyb20gdGhlIEF1ZGlvQ29udGV4dFxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZSNcblx0XHQgKi9cblx0ICAgIFRvbmUucHJvdG90eXBlLm5vdyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gVG9uZS5jb250ZXh0Lm5vdygpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm4gdGhlIGN1cnJlbnQgdGltZSBvZiB0aGUgQXVkaW9Db250ZXh0IGNsb2NrLlxuXHRcdCAqICBAcmV0dXJuIHtOdW1iZXJ9IHRoZSBjdXJyZW50VGltZSBmcm9tIHRoZSBBdWRpb0NvbnRleHRcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAbWVtYmVyT2YgVG9uZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5ub3cgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIFRvbmUuY29udGV4dC5ub3coKTtcblx0ICAgIH07XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRJTkhFUklUQU5DRVxuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvKipcblx0XHQgKiAgaGF2ZSBhIGNoaWxkIGluaGVyaXQgYWxsIG9mIFRvbmUncyAob3IgYSBwYXJlbnQncykgcHJvdG90eXBlXG5cdFx0ICogIHRvIGluaGVyaXQgdGhlIHBhcmVudCdzIHByb3BlcnRpZXMsIG1ha2Ugc3VyZSB0byBjYWxsXG5cdFx0ICogIFBhcmVudC5jYWxsKHRoaXMpIGluIHRoZSBjaGlsZCdzIGNvbnN0cnVjdG9yXG5cdFx0ICpcblx0XHQgKiAgYmFzZWQgb24gY2xvc3VyZSBsaWJyYXJ5J3MgaW5oZXJpdCBmdW5jdGlvblxuXHRcdCAqXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHBhcmFtICB7RnVuY3Rpb259IFx0Y2hpbGRcblx0XHQgKiAgQHBhcmFtICB7RnVuY3Rpb249fSBwYXJlbnQgKG9wdGlvbmFsKSBwYXJlbnQgdG8gaW5oZXJpdCBmcm9tXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vIHBhcmVudCBpcyBzdXBwbGllZCwgdGhlIGNoaWxkXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgaW5oZXJpdCBmcm9tIFRvbmVcblx0XHQgKi9cblx0ICAgIFRvbmUuZXh0ZW5kID0gZnVuY3Rpb24gKGNoaWxkLCBwYXJlbnQpIHtcblx0ICAgICAgICBpZiAoVG9uZS5pc1VuZGVmKHBhcmVudCkpIHtcblx0ICAgICAgICAgICAgcGFyZW50ID0gVG9uZTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZnVuY3Rpb24gVGVtcENvbnN0cnVjdG9yKCkge1xuXHQgICAgICAgIH1cblx0ICAgICAgICBUZW1wQ29uc3RydWN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTtcblx0ICAgICAgICBjaGlsZC5wcm90b3R5cGUgPSBuZXcgVGVtcENvbnN0cnVjdG9yKCk7XG5cdCAgICAgICAgLyoqIEBvdmVycmlkZSAqL1xuXHQgICAgICAgIGNoaWxkLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGNoaWxkO1xuXHQgICAgICAgIGNoaWxkLl9zdXBlciA9IHBhcmVudDtcblx0ICAgIH07XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRDT05URVhUXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBQcml2YXRlIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIEF1ZGlvQ29udGV4dFxuXHRcdCAqICBAdHlwZSB7QXVkaW9Db250ZXh0fVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgdmFyIGF1ZGlvQ29udGV4dCA9IG51bGw7XG5cdCAgICAvKipcblx0XHQgKiAgQSBzdGF0aWMgcG9pbnRlciB0byB0aGUgYXVkaW8gY29udGV4dCBhY2Nlc3NpYmxlIGFzIFRvbmUuY29udGV4dC5cblx0XHQgKiAgQHR5cGUge1RvbmUuQ29udGV4dH1cblx0XHQgKiAgQG5hbWUgY29udGV4dFxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUsICdjb250ZXh0Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gYXVkaW9Db250ZXh0O1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuXHQgICAgICAgICAgICBpZiAoVG9uZS5Db250ZXh0ICYmIGNvbnRleHQgaW5zdGFuY2VvZiBUb25lLkNvbnRleHQpIHtcblx0ICAgICAgICAgICAgICAgIGF1ZGlvQ29udGV4dCA9IGNvbnRleHQ7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBhdWRpb0NvbnRleHQgPSBuZXcgVG9uZS5Db250ZXh0KGNvbnRleHQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIC8vaW5pdGlhbGl6ZSB0aGUgbmV3IGF1ZGlvIGNvbnRleHRcblx0ICAgICAgICAgICAgVG9uZS5Db250ZXh0LmVtaXQoJ2luaXQnLCBhdWRpb0NvbnRleHQpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBBdWRpb0NvbnRleHRcblx0XHQgKiAgQHR5cGUge1RvbmUuQ29udGV4dH1cblx0XHQgKiAgQG5hbWUgY29udGV4dFxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZSNcblx0XHQgKiAgQHJlYWRPbmx5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5wcm90b3R5cGUsICdjb250ZXh0Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5jb250ZXh0O1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRvbmUgYXV0b21hdGljYWxseSBjcmVhdGVzIGEgY29udGV4dCBvbiBpbml0LCBidXQgaWYgeW91IGFyZSB3b3JraW5nXG5cdFx0ICogIHdpdGggb3RoZXIgbGlicmFyaWVzIHdoaWNoIGFsc28gY3JlYXRlIGFuIEF1ZGlvQ29udGV4dCwgaXQgY2FuIGJlXG5cdFx0ICogIHVzZWZ1bCB0byBzZXQgeW91ciBvd24uIElmIHlvdSBhcmUgZ29pbmcgdG8gc2V0IHlvdXIgb3duIGNvbnRleHQsXG5cdFx0ICogIGJlIHN1cmUgdG8gZG8gaXQgYXQgdGhlIHN0YXJ0IG9mIHlvdXIgY29kZSwgYmVmb3JlIGNyZWF0aW5nIGFueSBvYmplY3RzLlxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBwYXJhbSB7QXVkaW9Db250ZXh0fSBjdHggVGhlIG5ldyBhdWRpbyBjb250ZXh0IHRvIHNldFxuXHRcdCAqL1xuXHQgICAgVG9uZS5zZXRDb250ZXh0ID0gZnVuY3Rpb24gKGN0eCkge1xuXHQgICAgICAgIFRvbmUuY29udGV4dCA9IGN0eDtcblx0ICAgIH07XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRBVFRSSUJVVEVTXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgbnVtYmVyIG9mIHNlY29uZHMgb2YgMSBwcm9jZXNzaW5nIGJsb2NrICgxMjggc2FtcGxlcylcblx0XHQgKiAgQHR5cGUge051bWJlcn1cblx0XHQgKiAgQG5hbWUgYmxvY2tUaW1lXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHJlYWRPbmx5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5wcm90b3R5cGUsICdibG9ja1RpbWUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiAxMjggLyB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgZHVyYXRpb24gaW4gc2Vjb25kcyBvZiBvbmUgc2FtcGxlLlxuXHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqICBAbmFtZSBzYW1wbGVUaW1lXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHJlYWRPbmx5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5wcm90b3R5cGUsICdzYW1wbGVUaW1lJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gMSAvIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFdoZXRoZXIgb3Igbm90IGFsbCB0aGUgdGVjaG5vbG9naWVzIHRoYXQgVG9uZS5qcyByZWxpZXMgb24gYXJlIHN1cHBvcnRlZCBieSB0aGUgY3VycmVudCBicm93c2VyLlxuXHRcdCAqICBAdHlwZSB7Qm9vbGVhbn1cblx0XHQgKiAgQG5hbWUgc3VwcG9ydGVkXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lXG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZSwgJ3N1cHBvcnRlZCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGhhc0F1ZGlvQ29udGV4dCA9IHdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnQXVkaW9Db250ZXh0JykgfHwgd2luZG93Lmhhc093blByb3BlcnR5KCd3ZWJraXRBdWRpb0NvbnRleHQnKTtcblx0ICAgICAgICAgICAgdmFyIGhhc1Byb21pc2VzID0gd2luZG93Lmhhc093blByb3BlcnR5KCdQcm9taXNlJyk7XG5cdCAgICAgICAgICAgIHZhciBoYXNXb3JrZXJzID0gd2luZG93Lmhhc093blByb3BlcnR5KCdXb3JrZXInKTtcblx0ICAgICAgICAgICAgcmV0dXJuIGhhc0F1ZGlvQ29udGV4dCAmJiBoYXNQcm9taXNlcyAmJiBoYXNXb3JrZXJzO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIEJvb2xlYW4gdmFsdWUgaWYgdGhlIGF1ZGlvIGNvbnRleHQgaGFzIGJlZW4gaW5pdGlhbGl6ZWQuXG5cdFx0ICogIEB0eXBlIHtCb29sZWFufVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZVxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBuYW1lIGluaXRpYWxpemVkXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZSwgJ2luaXRpYWxpemVkJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gYXVkaW9Db250ZXh0ICE9PSBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIEdldCB0aGUgY29udGV4dCB3aGVuIGl0IGJlY29tZXMgYXZhaWxhYmxlXG5cdFx0ICogIEBwYXJhbSAge0Z1bmN0aW9ufSAgcmVzb2x2ZSAgQ2FsbGJhY2sgd2hlbiB0aGUgY29udGV4dCBpcyBpbml0aWFsaXplZFxuXHRcdCAqICBAcmV0dXJuICB7VG9uZX1cblx0XHQgKi9cblx0ICAgIFRvbmUuZ2V0Q29udGV4dCA9IGZ1bmN0aW9uIChyZXNvbHZlKSB7XG5cdCAgICAgICAgaWYgKFRvbmUuaW5pdGlhbGl6ZWQpIHtcblx0ICAgICAgICAgICAgcmVzb2x2ZShUb25lLmNvbnRleHQpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHZhciByZXNDYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIHJlc29sdmUoVG9uZS5jb250ZXh0KTtcblx0ICAgICAgICAgICAgICAgIFRvbmUuQ29udGV4dC5vZmYoJ2luaXQnLCByZXNDYWxsYmFjayk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIFRvbmUuQ29udGV4dC5vbignaW5pdCcsIHJlc0NhbGxiYWNrKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIFRvbmU7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHZlcnNpb24gbnVtYmVyXG5cdFx0ICogQHR5cGUge1N0cmluZ31cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdCAgICBUb25lLnZlcnNpb24gPSAncjEyJztcblx0ICAgIHJldHVybiBUb25lO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5FbWl0dGVyIGdpdmVzIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIGl0XG5cdFx0ICogICAgICAgICB0aGUgYWJpbGl0eSB0byBsaXN0ZW4gZm9yIGFuZCBlbWl0IGV2ZW50cy5cblx0XHQgKiAgICAgICAgIEluc3BpcmF0aW9uIGFuZCByZWZlcmVuY2UgZnJvbSBKZXJvbWUgRXRpZW5uZSdzIFtNaWNyb0V2ZW50XShodHRwczovL2dpdGh1Yi5jb20vamVyb21lZXRpZW5uZS9taWNyb2V2ZW50LmpzKS5cblx0XHQgKiAgICAgICAgIE1JVCAoYykgMjAxMSBKZXJvbWUgRXRpZW5uZS5cblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZX1cblx0XHQgKi9cblx0ICAgIFRvbmUuRW1pdHRlciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQ29udGFpbnMgYWxsIG9mIHRoZSBldmVudHMuXG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqICBAdHlwZSAge09iamVjdH1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuRW1pdHRlcik7XG5cdCAgICAvKipcblx0XHQgKiAgQmluZCBhIGNhbGxiYWNrIHRvIGEgc3BlY2lmaWMgZXZlbnQuXG5cdFx0ICogIEBwYXJhbSAge1N0cmluZ30gICAgZXZlbnQgICAgIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBsaXN0ZW4gZm9yLlxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbn0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gdGhlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50IGlzIGVtaXR0ZWRcblx0XHQgKiAgQHJldHVybiAge1RvbmUuRW1pdHRlcn0gICAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5FbWl0dGVyLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgY2FsbGJhY2spIHtcblx0ICAgICAgICAvL3NwbGl0IHRoZSBldmVudFxuXHQgICAgICAgIHZhciBldmVudHMgPSBldmVudC5zcGxpdCgvXFxXKy8pO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgIHZhciBldmVudE5hbWUgPSBldmVudHNbaV07XG5cdCAgICAgICAgICAgIGlmICghdGhpcy5fZXZlbnRzLmhhc093blByb3BlcnR5KGV2ZW50TmFtZSkpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1tldmVudE5hbWVdID0gW107XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5fZXZlbnRzW2V2ZW50TmFtZV0ucHVzaChjYWxsYmFjayk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBCaW5kIGEgY2FsbGJhY2sgd2hpY2ggaXMgb25seSBpbnZva2VkIG9uY2Vcblx0XHQgKiAgQHBhcmFtICB7U3RyaW5nfSAgICBldmVudCAgICAgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGxpc3RlbiBmb3IuXG5cdFx0ICogIEBwYXJhbSAge0Z1bmN0aW9ufSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQgaXMgZW1pdHRlZFxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5FbWl0dGVyfSAgICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGNhbGxiYWNrKSB7XG5cdCAgICAgICAgdmFyIGJvdW5kQ2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vaW52b2tlIHRoZSBjYWxsYmFja1xuXHQgICAgICAgICAgICBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXHQgICAgICAgICAgICB0aGlzLm9mZihldmVudCwgYm91bmRDYWxsYmFjayk7XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpO1xuXHQgICAgICAgIHRoaXMub24oZXZlbnQsIGJvdW5kQ2FsbGJhY2spO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZW1vdmUgdGhlIGV2ZW50IGxpc3RlbmVyLlxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd9ICAgIGV2ZW50ICAgICBUaGUgZXZlbnQgdG8gc3RvcCBsaXN0ZW5pbmcgdG8uXG5cdFx0ICogIEBwYXJhbSAge0Z1bmN0aW9uPX0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgd2hpY2ggd2FzIGJvdW5kIHRvXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBldmVudCB3aXRoIFRvbmUuRW1pdHRlci5vbi5cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYgbm8gY2FsbGJhY2sgaXMgZ2l2ZW4sIGFsbCBjYWxsYmFja3Ncblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzIGFyZSByZW1vdmVkLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5FbWl0dGVyfSAgICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudCwgY2FsbGJhY2spIHtcblx0ICAgICAgICB2YXIgZXZlbnRzID0gZXZlbnQuc3BsaXQoL1xcVysvKTtcblx0ICAgICAgICBmb3IgKHZhciBldiA9IDA7IGV2IDwgZXZlbnRzLmxlbmd0aDsgZXYrKykge1xuXHQgICAgICAgICAgICBldmVudCA9IGV2ZW50c1tldl07XG5cdCAgICAgICAgICAgIGlmICh0aGlzLl9ldmVudHMuaGFzT3duUHJvcGVydHkoZXZlbnQpKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoVG9uZS5pc1VuZGVmKGNhbGxiYWNrKSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1tldmVudF0gPSBbXTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIGV2ZW50TGlzdCA9IHRoaXMuX2V2ZW50c1tldmVudF07XG5cdCAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldmVudExpc3QubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50TGlzdFtpXSA9PT0gY2FsbGJhY2spIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50TGlzdC5zcGxpY2UoaSwgMSk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEludm9rZSBhbGwgb2YgdGhlIGNhbGxiYWNrcyBib3VuZCB0byB0aGUgZXZlbnRcblx0XHQgKiAgd2l0aCBhbnkgYXJndW1lbnRzIHBhc3NlZCBpbi5cblx0XHQgKiAgQHBhcmFtICB7U3RyaW5nfSAgZXZlbnQgIFRoZSBuYW1lIG9mIHRoZSBldmVudC5cblx0XHQgKiAgQHBhcmFtIHsqfSBhcmdzLi4uIFRoZSBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgZnVuY3Rpb25zIGxpc3RlbmluZy5cblx0XHQgKiAgQHJldHVybiAge1RvbmUuRW1pdHRlcn0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgIGlmICh0aGlzLl9ldmVudHMpIHtcblx0ICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5hcHBseShudWxsLCBhcmd1bWVudHMpLnNsaWNlKDEpO1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fZXZlbnRzLmhhc093blByb3BlcnR5KGV2ZW50KSkge1xuXHQgICAgICAgICAgICAgICAgdmFyIGV2ZW50TGlzdCA9IHRoaXMuX2V2ZW50c1tldmVudF0uc2xpY2UoMCk7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gZXZlbnRMaXN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgZXZlbnRMaXN0W2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBBZGQgRW1pdHRlciBmdW5jdGlvbnMgKG9uL29mZi9lbWl0KSB0byB0aGUgb2JqZWN0XG5cdFx0ICogIEBwYXJhbSAge09iamVjdHxGdW5jdGlvbn0gIG9iamVjdCAgVGhlIG9iamVjdCBvciBjbGFzcyB0byBleHRlbmQuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkVtaXR0ZXJ9XG5cdFx0ICovXG5cdCAgICBUb25lLkVtaXR0ZXIubWl4aW4gPSBmdW5jdGlvbiAob2JqZWN0KSB7XG5cdCAgICAgICAgdmFyIGZ1bmN0aW9ucyA9IFtcblx0ICAgICAgICAgICAgJ29uJyxcblx0ICAgICAgICAgICAgJ29uY2UnLFxuXHQgICAgICAgICAgICAnb2ZmJyxcblx0ICAgICAgICAgICAgJ2VtaXQnXG5cdCAgICAgICAgXTtcblx0ICAgICAgICBvYmplY3QuX2V2ZW50cyA9IHt9O1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZnVuY3Rpb25zLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgIHZhciBmdW5jID0gZnVuY3Rpb25zW2ldO1xuXHQgICAgICAgICAgICB2YXIgZW1pdHRlckZ1bmMgPSBUb25lLkVtaXR0ZXIucHJvdG90eXBlW2Z1bmNdO1xuXHQgICAgICAgICAgICBvYmplY3RbZnVuY10gPSBlbWl0dGVyRnVuYztcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIFRvbmUuRW1pdHRlcjtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXBcblx0XHQgKiAgQHJldHVybiAge1RvbmUuRW1pdHRlcn0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuRW1pdHRlci5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fZXZlbnRzID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5FbWl0dGVyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgQSBUaW1lbGluZSBjbGFzcyBmb3Igc2NoZWR1bGluZyBhbmQgbWFpbnRhaW5pbmcgc3RhdGVcblx0XHQgKiAgICAgICAgIGFsb25nIGEgdGltZWxpbmUuIEFsbCBldmVudHMgbXVzdCBoYXZlIGEgXCJ0aW1lXCIgcHJvcGVydHkuXG5cdFx0ICogICAgICAgICBJbnRlcm5hbGx5LCBldmVudHMgYXJlIHN0b3JlZCBpbiB0aW1lIG9yZGVyIGZvciBmYXN0XG5cdFx0ICogICAgICAgICByZXRyaWV2YWwuXG5cdFx0ICogIEBleHRlbmRzIHtUb25lfVxuXHRcdCAqICBAcGFyYW0ge1Bvc2l0aXZlfSBbbWVtb3J5PUluZmluaXR5XSBUaGUgbnVtYmVyIG9mIHByZXZpb3VzIGV2ZW50cyB0aGF0IGFyZSByZXRhaW5lZC5cblx0XHQgKi9cblx0ICAgIFRvbmUuVGltZWxpbmUgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgWydtZW1vcnknXSwgVG9uZS5UaW1lbGluZSk7XG5cdCAgICAgICAgVG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhcnJheSBvZiBzY2hlZHVsZWQgdGltZWxpbmUgZXZlbnRzXG5cdFx0XHQgKiAgQHR5cGUgIHtBcnJheX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBbXTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbWVtb3J5IG9mIHRoZSB0aW1lbGluZSwgaS5lLlxuXHRcdFx0ICogIGhvdyBtYW55IGV2ZW50cyBpbiB0aGUgcGFzdCBpdCB3aWxsIHJldGFpblxuXHRcdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubWVtb3J5ID0gb3B0aW9ucy5tZW1vcnk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5UaW1lbGluZSk7XG5cdCAgICAvKipcblx0XHQgKiAgdGhlIGRlZmF1bHQgcGFyYW1ldGVyc1xuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBjb25zdFxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lbGluZS5kZWZhdWx0cyA9IHsgJ21lbW9yeSc6IEluZmluaXR5IH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIG51bWJlciBvZiBpdGVtcyBpbiB0aGUgdGltZWxpbmUuXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlRpbWVsaW5lI1xuXHRcdCAqICBAbmFtZSBsZW5ndGhcblx0XHQgKiAgQHJlYWRPbmx5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5UaW1lbGluZS5wcm90b3R5cGUsICdsZW5ndGgnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZS5sZW5ndGg7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgSW5zZXJ0IGFuIGV2ZW50IG9iamVjdCBvbnRvIHRoZSB0aW1lbGluZS4gRXZlbnRzIG11c3QgaGF2ZSBhIFwidGltZVwiIGF0dHJpYnV0ZS5cblx0XHQgKiAgQHBhcmFtICB7T2JqZWN0fSAgZXZlbnQgIFRoZSBldmVudCBvYmplY3QgdG8gaW5zZXJ0IGludG8gdGhlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lbGluZS5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuVGltZWxpbmV9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVGltZWxpbmUucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgIC8vdGhlIGV2ZW50IG5lZWRzIHRvIGhhdmUgYSB0aW1lIGF0dHJpYnV0ZVxuXHQgICAgICAgIGlmIChUb25lLmlzVW5kZWYoZXZlbnQudGltZSkpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUb25lLlRpbWVsaW5lOiBldmVudHMgbXVzdCBoYXZlIGEgdGltZSBhdHRyaWJ1dGUnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZXZlbnQudGltZSA9IGV2ZW50LnRpbWUudmFsdWVPZigpO1xuXHQgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX3NlYXJjaChldmVudC50aW1lKTtcblx0ICAgICAgICB0aGlzLl90aW1lbGluZS5zcGxpY2UoaW5kZXggKyAxLCAwLCBldmVudCk7XG5cdCAgICAgICAgLy9pZiB0aGUgbGVuZ3RoIGlzIG1vcmUgdGhhbiB0aGUgbWVtb3J5LCByZW1vdmUgdGhlIHByZXZpb3VzIG9uZXNcblx0ICAgICAgICBpZiAodGhpcy5sZW5ndGggPiB0aGlzLm1lbW9yeSkge1xuXHQgICAgICAgICAgICB2YXIgZGlmZiA9IHRoaXMubGVuZ3RoIC0gdGhpcy5tZW1vcnk7XG5cdCAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lLnNwbGljZSgwLCBkaWZmKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJlbW92ZSBhbiBldmVudCBmcm9tIHRoZSB0aW1lbGluZS5cblx0XHQgKiAgQHBhcmFtICB7T2JqZWN0fSAgZXZlbnQgIFRoZSBldmVudCBvYmplY3QgdG8gcmVtb3ZlIGZyb20gdGhlIGxpc3QuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRpbWVsaW5lfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVsaW5lLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAoZXZlbnQpIHtcblx0ICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl90aW1lbGluZS5pbmRleE9mKGV2ZW50KTtcblx0ICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lLnNwbGljZShpbmRleCwgMSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBHZXQgdGhlIG5lYXJlc3QgZXZlbnQgd2hvc2UgdGltZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd9ICBjb21wYXJhdG9yIFdoaWNoIHZhbHVlIGluIHRoZSBvYmplY3QgdG8gY29tcGFyZVxuXHRcdCAqICBAcmV0dXJucyB7T2JqZWN0fSBUaGUgZXZlbnQgb2JqZWN0IHNldCBhZnRlciB0aGF0IHRpbWUuXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVsaW5lLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAodGltZSwgY29tcGFyYXRvcikge1xuXHQgICAgICAgIGNvbXBhcmF0b3IgPSBUb25lLmRlZmF1bHRBcmcoY29tcGFyYXRvciwgJ3RpbWUnKTtcblx0ICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9zZWFyY2godGltZSwgY29tcGFyYXRvcik7XG5cdCAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbaW5kZXhdO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHJldHVybiBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJuIHRoZSBmaXJzdCBldmVudCBpbiB0aGUgdGltZWxpbmUgd2l0aG91dCByZW1vdmluZyBpdFxuXHRcdCAqICBAcmV0dXJucyB7T2JqZWN0fSBUaGUgZmlyc3QgZXZlbnQgb2JqZWN0XG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVsaW5lLnByb3RvdHlwZS5wZWVrID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVswXTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJuIHRoZSBmaXJzdCBldmVudCBpbiB0aGUgdGltZWxpbmUgYW5kIHJlbW92ZSBpdFxuXHRcdCAqICBAcmV0dXJucyB7T2JqZWN0fSBUaGUgZmlyc3QgZXZlbnQgb2JqZWN0XG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVsaW5lLnByb3RvdHlwZS5zaGlmdCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmUuc2hpZnQoKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgR2V0IHRoZSBldmVudCB3aGljaCBpcyBzY2hlZHVsZWQgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd9ICBjb21wYXJhdG9yIFdoaWNoIHZhbHVlIGluIHRoZSBvYmplY3QgdG8gY29tcGFyZVxuXHRcdCAqICBAcmV0dXJucyB7T2JqZWN0fSBUaGUgZXZlbnQgb2JqZWN0IGFmdGVyIHRoZSBnaXZlbiB0aW1lXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVsaW5lLnByb3RvdHlwZS5nZXRBZnRlciA9IGZ1bmN0aW9uICh0aW1lLCBjb21wYXJhdG9yKSB7XG5cdCAgICAgICAgY29tcGFyYXRvciA9IFRvbmUuZGVmYXVsdEFyZyhjb21wYXJhdG9yLCAndGltZScpO1xuXHQgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lLCBjb21wYXJhdG9yKTtcblx0ICAgICAgICBpZiAoaW5kZXggKyAxIDwgdGhpcy5fdGltZWxpbmUubGVuZ3RoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtpbmRleCArIDFdO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHJldHVybiBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgR2V0IHRoZSBldmVudCBiZWZvcmUgdGhlIGV2ZW50IGF0IHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cblx0XHQgKiAgQHBhcmFtICB7U3RyaW5nfSAgY29tcGFyYXRvciBXaGljaCB2YWx1ZSBpbiB0aGUgb2JqZWN0IHRvIGNvbXBhcmVcblx0XHQgKiAgQHJldHVybnMge09iamVjdH0gVGhlIGV2ZW50IG9iamVjdCBiZWZvcmUgdGhlIGdpdmVuIHRpbWVcblx0XHQgKi9cblx0ICAgIFRvbmUuVGltZWxpbmUucHJvdG90eXBlLmdldEJlZm9yZSA9IGZ1bmN0aW9uICh0aW1lLCBjb21wYXJhdG9yKSB7XG5cdCAgICAgICAgY29tcGFyYXRvciA9IFRvbmUuZGVmYXVsdEFyZyhjb21wYXJhdG9yLCAndGltZScpO1xuXHQgICAgICAgIHZhciBsZW4gPSB0aGlzLl90aW1lbGluZS5sZW5ndGg7XG5cdCAgICAgICAgLy9pZiBpdCdzIGFmdGVyIHRoZSBsYXN0IGl0ZW0sIHJldHVybiB0aGUgbGFzdCBpdGVtXG5cdCAgICAgICAgaWYgKGxlbiA+IDAgJiYgdGhpcy5fdGltZWxpbmVbbGVuIC0gMV1bY29tcGFyYXRvcl0gPCB0aW1lKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtsZW4gLSAxXTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUsIGNvbXBhcmF0b3IpO1xuXHQgICAgICAgIGlmIChpbmRleCAtIDEgPj0gMCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbaW5kZXggLSAxXTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICByZXR1cm4gbnVsbDtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENhbmNlbCBldmVudHMgYWZ0ZXIgdGhlIGdpdmVuIHRpbWVcblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRpbWVsaW5lfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVsaW5lLnByb3RvdHlwZS5jYW5jZWwgPSBmdW5jdGlvbiAoYWZ0ZXIpIHtcblx0ICAgICAgICBpZiAodGhpcy5fdGltZWxpbmUubGVuZ3RoID4gMSkge1xuXHQgICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9zZWFyY2goYWZ0ZXIpO1xuXHQgICAgICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuXHQgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3RpbWVsaW5lW2luZGV4XS50aW1lID09PSBhZnRlcikge1xuXHQgICAgICAgICAgICAgICAgICAgIC8vZ2V0IHRoZSBmaXJzdCBpdGVtIHdpdGggdGhhdCB0aW1lXG5cdCAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IGluZGV4OyBpID49IDA7IGktLSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fdGltZWxpbmVbaV0udGltZSA9PT0gYWZ0ZXIpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gaTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gdGhpcy5fdGltZWxpbmUuc2xpY2UoMCwgaW5kZXgpO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl90aW1lbGluZSA9IHRoaXMuX3RpbWVsaW5lLnNsaWNlKDAsIGluZGV4ICsgMSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl90aW1lbGluZSA9IFtdO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSBlbHNlIGlmICh0aGlzLl90aW1lbGluZS5sZW5ndGggPT09IDEpIHtcblx0ICAgICAgICAgICAgLy90aGUgZmlyc3QgaXRlbSdzIHRpbWVcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3RpbWVsaW5lWzBdLnRpbWUgPj0gYWZ0ZXIpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gW107XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENhbmNlbCBldmVudHMgYmVmb3JlIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICB0aW1lICBUaGUgdGltZSB0byBjYW5jZWwgYmVmb3JlLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5UaW1lbGluZX0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lbGluZS5wcm90b3R5cGUuY2FuY2VsQmVmb3JlID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9zZWFyY2godGltZSk7XG5cdCAgICAgICAgaWYgKGluZGV4ID49IDApIHtcblx0ICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUgPSB0aGlzLl90aW1lbGluZS5zbGljZShpbmRleCArIDEpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBSZXR1cm5zIHRoZSBwcmV2aW91cyBldmVudCBpZiB0aGVyZSBpcyBvbmUuIG51bGwgb3RoZXJ3aXNlXG5cdFx0ICogQHBhcmFtICB7T2JqZWN0fSBldmVudCBUaGUgZXZlbnQgdG8gZmluZCB0aGUgcHJldmlvdXMgb25lIG9mXG5cdFx0ICogQHJldHVybiB7T2JqZWN0fSAgICAgICBUaGUgZXZlbnQgcmlnaHQgYmVmb3JlIHRoZSBnaXZlbiBldmVudFxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lbGluZS5wcm90b3R5cGUucHJldmlvdXNFdmVudCA9IGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX3RpbWVsaW5lLmluZGV4T2YoZXZlbnQpO1xuXHQgICAgICAgIGlmIChpbmRleCA+IDApIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lW2luZGV4IC0gMV07XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBEb2VzIGEgYmluYXJ5IHNlYXJjaCBvbiB0aGUgdGltZWxpbmUgYXJyYXkgYW5kIHJldHVybnMgdGhlXG5cdFx0ICogIG5lYXJlc3QgZXZlbnQgaW5kZXggd2hvc2UgdGltZSBpcyBhZnRlciBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gdGltZS5cblx0XHQgKiAgSWYgYSB0aW1lIGlzIHNlYXJjaGVkIGJlZm9yZSB0aGUgZmlyc3QgaW5kZXggaW4gdGhlIHRpbWVsaW5lLCAtMSBpcyByZXR1cm5lZC5cblx0XHQgKiAgSWYgdGhlIHRpbWUgaXMgYWZ0ZXIgdGhlIGVuZCwgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGl0ZW0gaXMgcmV0dXJuZWQuXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWVcblx0XHQgKiAgQHBhcmFtICB7U3RyaW5nfSAgY29tcGFyYXRvciBXaGljaCB2YWx1ZSBpbiB0aGUgb2JqZWN0IHRvIGNvbXBhcmVcblx0XHQgKiAgQHJldHVybiAge051bWJlcn0gdGhlIGluZGV4IGluIHRoZSB0aW1lbGluZSBhcnJheVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lbGluZS5wcm90b3R5cGUuX3NlYXJjaCA9IGZ1bmN0aW9uICh0aW1lLCBjb21wYXJhdG9yKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuX3RpbWVsaW5lLmxlbmd0aCA9PT0gMCkge1xuXHQgICAgICAgICAgICByZXR1cm4gLTE7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNvbXBhcmF0b3IgPSBUb25lLmRlZmF1bHRBcmcoY29tcGFyYXRvciwgJ3RpbWUnKTtcblx0ICAgICAgICB2YXIgYmVnaW5uaW5nID0gMDtcblx0ICAgICAgICB2YXIgbGVuID0gdGhpcy5fdGltZWxpbmUubGVuZ3RoO1xuXHQgICAgICAgIHZhciBlbmQgPSBsZW47XG5cdCAgICAgICAgaWYgKGxlbiA+IDAgJiYgdGhpcy5fdGltZWxpbmVbbGVuIC0gMV1bY29tcGFyYXRvcl0gPD0gdGltZSkge1xuXHQgICAgICAgICAgICByZXR1cm4gbGVuIC0gMTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgd2hpbGUgKGJlZ2lubmluZyA8IGVuZCkge1xuXHQgICAgICAgICAgICAvLyBjYWxjdWxhdGUgdGhlIG1pZHBvaW50IGZvciByb3VnaGx5IGVxdWFsIHBhcnRpdGlvblxuXHQgICAgICAgICAgICB2YXIgbWlkUG9pbnQgPSBNYXRoLmZsb29yKGJlZ2lubmluZyArIChlbmQgLSBiZWdpbm5pbmcpIC8gMik7XG5cdCAgICAgICAgICAgIHZhciBldmVudCA9IHRoaXMuX3RpbWVsaW5lW21pZFBvaW50XTtcblx0ICAgICAgICAgICAgdmFyIG5leHRFdmVudCA9IHRoaXMuX3RpbWVsaW5lW21pZFBvaW50ICsgMV07XG5cdCAgICAgICAgICAgIGlmIChldmVudFtjb21wYXJhdG9yXSA9PT0gdGltZSkge1xuXHQgICAgICAgICAgICAgICAgLy9jaG9vc2UgdGhlIGxhc3Qgb25lIHRoYXQgaGFzIHRoZSBzYW1lIHRpbWVcblx0ICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSBtaWRQb2ludDsgaSA8IHRoaXMuX3RpbWVsaW5lLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHRlc3RFdmVudCA9IHRoaXMuX3RpbWVsaW5lW2ldO1xuXHQgICAgICAgICAgICAgICAgICAgIGlmICh0ZXN0RXZlbnRbY29tcGFyYXRvcl0gPT09IHRpbWUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgbWlkUG9pbnQgPSBpO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHJldHVybiBtaWRQb2ludDtcblx0ICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudFtjb21wYXJhdG9yXSA8IHRpbWUgJiYgbmV4dEV2ZW50W2NvbXBhcmF0b3JdID4gdGltZSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG1pZFBvaW50O1xuXHQgICAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50W2NvbXBhcmF0b3JdID4gdGltZSkge1xuXHQgICAgICAgICAgICAgICAgLy9zZWFyY2ggbG93ZXJcblx0ICAgICAgICAgICAgICAgIGVuZCA9IG1pZFBvaW50O1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgLy9zZWFyY2ggdXBwZXJcblx0ICAgICAgICAgICAgICAgIGJlZ2lubmluZyA9IG1pZFBvaW50ICsgMTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gLTE7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEludGVybmFsIGl0ZXJhdG9yLiBBcHBsaWVzIGV4dHJhIHNhZmV0eSBjaGVja3MgZm9yXG5cdFx0ICogIHJlbW92aW5nIGl0ZW1zIGZyb20gdGhlIGFycmF5LlxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbn0gIGNhbGxiYWNrXG5cdFx0ICogIEBwYXJhbSAge051bWJlcj19ICAgIGxvd2VyQm91bmRcblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyPX0gICAgdXBwZXJCb3VuZFxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lbGluZS5wcm90b3R5cGUuX2l0ZXJhdGUgPSBmdW5jdGlvbiAoY2FsbGJhY2ssIGxvd2VyQm91bmQsIHVwcGVyQm91bmQpIHtcblx0ICAgICAgICBsb3dlckJvdW5kID0gVG9uZS5kZWZhdWx0QXJnKGxvd2VyQm91bmQsIDApO1xuXHQgICAgICAgIHVwcGVyQm91bmQgPSBUb25lLmRlZmF1bHRBcmcodXBwZXJCb3VuZCwgdGhpcy5fdGltZWxpbmUubGVuZ3RoIC0gMSk7XG5cdCAgICAgICAgdGhpcy5fdGltZWxpbmUuc2xpY2UobG93ZXJCb3VuZCwgdXBwZXJCb3VuZCArIDEpLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG5cdCAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwodGhpcywgZXZlbnQpO1xuXHQgICAgICAgIH0uYmluZCh0aGlzKSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheVxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbn0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRpbWVsaW5lfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVsaW5lLnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG5cdCAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjayk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBhdCBvciBiZWZvcmUgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbn0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRpbWVsaW5lfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVsaW5lLnByb3RvdHlwZS5mb3JFYWNoQmVmb3JlID0gZnVuY3Rpb24gKHRpbWUsIGNhbGxiYWNrKSB7XG5cdCAgICAgICAgLy9pdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG5cdCAgICAgICAgdmFyIHVwcGVyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG5cdCAgICAgICAgaWYgKHVwcGVyQm91bmQgIT09IC0xKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2ssIDAsIHVwcGVyQm91bmQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICB0aW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcblx0XHQgKiAgQHBhcmFtICB7RnVuY3Rpb259ICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5UaW1lbGluZX0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lbGluZS5wcm90b3R5cGUuZm9yRWFjaEFmdGVyID0gZnVuY3Rpb24gKHRpbWUsIGNhbGxiYWNrKSB7XG5cdCAgICAgICAgLy9pdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG5cdCAgICAgICAgdmFyIGxvd2VyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG5cdCAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgbG93ZXJCb3VuZCArIDEpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgYmV0d2VlbiB0aGUgc3RhcnRUaW1lIGFuZCBlbmRUaW1lLiBcblx0XHQgKiAgVGhlIHRpbWVyYW5nZSBpcyBpbmNsdXNpdmUgb2YgdGhlIHN0YXJ0VGltZSwgYnV0IGV4Y2x1c2l2ZSBvZiB0aGUgZW5kVGltZS4gXG5cdFx0ICogIHJhbmdlID0gW3N0YXJ0VGltZSwgZW5kVGltZSkuIFxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICBzdGFydFRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICBlbmRUaW1lIFRoZSBlbmQgb2YgdGhlIHRlc3QgaW50ZXJ2YWwuIFxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbn0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRpbWVsaW5lfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVsaW5lLnByb3RvdHlwZS5mb3JFYWNoQmV0d2VlbiA9IGZ1bmN0aW9uIChzdGFydFRpbWUsIGVuZFRpbWUsIGNhbGxiYWNrKSB7XG5cdCAgICAgICAgdmFyIGxvd2VyQm91bmQgPSB0aGlzLl9zZWFyY2goc3RhcnRUaW1lKTtcblx0ICAgICAgICB2YXIgdXBwZXJCb3VuZCA9IHRoaXMuX3NlYXJjaChlbmRUaW1lKTtcblx0ICAgICAgICBpZiAobG93ZXJCb3VuZCAhPT0gLTEgJiYgdXBwZXJCb3VuZCAhPT0gLTEpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3RpbWVsaW5lW2xvd2VyQm91bmRdLnRpbWUgIT09IHN0YXJ0VGltZSkge1xuXHQgICAgICAgICAgICAgICAgbG93ZXJCb3VuZCArPSAxO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIC8vZXhjbHVzaXZlIG9mIHRoZSBlbmQgdGltZVxuXHQgICAgICAgICAgICBpZiAodGhpcy5fdGltZWxpbmVbdXBwZXJCb3VuZF0udGltZSA9PT0gZW5kVGltZSkge1xuXHQgICAgICAgICAgICAgICAgdXBwZXJCb3VuZCAtPSAxO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2ssIGxvd2VyQm91bmQsIHVwcGVyQm91bmQpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAobG93ZXJCb3VuZCA9PT0gLTEpIHtcblx0ICAgICAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgMCwgdXBwZXJCb3VuZCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgYXQgb3IgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuIFNpbWlsYXIgdG9cblx0XHQgKiAgZm9yRWFjaEFmdGVyLCBidXQgaW5jbHVkZXMgdGhlIGl0ZW0ocykgYXQgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbn0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRpbWVsaW5lfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVsaW5lLnByb3RvdHlwZS5mb3JFYWNoRnJvbSA9IGZ1bmN0aW9uICh0aW1lLCBjYWxsYmFjaykge1xuXHQgICAgICAgIC8vaXRlcmF0ZSBvdmVyIHRoZSBpdGVtcyBpbiByZXZlcnNlIHNvIHRoYXQgcmVtb3ZpbmcgYW4gaXRlbSBkb2Vzbid0IGJyZWFrIHRoaW5nc1xuXHQgICAgICAgIHZhciBsb3dlckJvdW5kID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuXHQgICAgICAgIC8vd29yayBiYWNrd2FyZHMgdW50aWwgdGhlIGV2ZW50IHRpbWUgaXMgbGVzcyB0aGFuIHRpbWVcblx0ICAgICAgICB3aGlsZSAobG93ZXJCb3VuZCA+PSAwICYmIHRoaXMuX3RpbWVsaW5lW2xvd2VyQm91bmRdLnRpbWUgPj0gdGltZSkge1xuXHQgICAgICAgICAgICBsb3dlckJvdW5kLS07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2ssIGxvd2VyQm91bmQgKyAxKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGF0IHRoZSBnaXZlbiB0aW1lXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbn0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRpbWVsaW5lfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVsaW5lLnByb3RvdHlwZS5mb3JFYWNoQXRUaW1lID0gZnVuY3Rpb24gKHRpbWUsIGNhbGxiYWNrKSB7XG5cdCAgICAgICAgLy9pdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG5cdCAgICAgICAgdmFyIHVwcGVyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG5cdCAgICAgICAgaWYgKHVwcGVyQm91bmQgIT09IC0xKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2l0ZXJhdGUoZnVuY3Rpb24gKGV2ZW50KSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoZXZlbnQudGltZSA9PT0gdGltZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwodGhpcywgZXZlbnQpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9LCAwLCB1cHBlckJvdW5kKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5UaW1lbGluZX0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVGltZWxpbmUucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5UaW1lbGluZTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgaWYgKFRvbmUuc3VwcG9ydGVkKSB7XG5cdCAgICAgICAgaWYgKCF3aW5kb3cuaGFzT3duUHJvcGVydHkoJ09mZmxpbmVBdWRpb0NvbnRleHQnKSAmJiB3aW5kb3cuaGFzT3duUHJvcGVydHkoJ3dlYmtpdE9mZmxpbmVBdWRpb0NvbnRleHQnKSkge1xuXHQgICAgICAgICAgICB3aW5kb3cuT2ZmbGluZUF1ZGlvQ29udGV4dCA9IHdpbmRvdy53ZWJraXRPZmZsaW5lQXVkaW9Db250ZXh0O1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL3JldHVybnMgcHJvbWlzZT9cblx0ICAgICAgICB2YXIgY29udGV4dCA9IG5ldyBPZmZsaW5lQXVkaW9Db250ZXh0KDEsIDEsIDQ0MTAwKTtcblx0ICAgICAgICB2YXIgcmV0ID0gY29udGV4dC5zdGFydFJlbmRlcmluZygpO1xuXHQgICAgICAgIGlmICghKHJldCBpbnN0YW5jZW9mIFByb21pc2UpKSB7XG5cdCAgICAgICAgICAgIE9mZmxpbmVBdWRpb0NvbnRleHQucHJvdG90eXBlLl9uYXRpdmVfc3RhcnRSZW5kZXJpbmcgPSBPZmZsaW5lQXVkaW9Db250ZXh0LnByb3RvdHlwZS5zdGFydFJlbmRlcmluZztcblx0ICAgICAgICAgICAgT2ZmbGluZUF1ZGlvQ29udGV4dC5wcm90b3R5cGUuc3RhcnRSZW5kZXJpbmcgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGRvbmUpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLm9uY29tcGxldGUgPSBmdW5jdGlvbiAoZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBkb25lKGUucmVuZGVyZWRCdWZmZXIpO1xuXHQgICAgICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlX3N0YXJ0UmVuZGVyaW5nKCk7XG5cdCAgICAgICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgaWYgKFRvbmUuc3VwcG9ydGVkKSB7XG5cdCAgICAgICAgaWYgKCF3aW5kb3cuaGFzT3duUHJvcGVydHkoJ0F1ZGlvQ29udGV4dCcpICYmIHdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnd2Via2l0QXVkaW9Db250ZXh0JykpIHtcblx0ICAgICAgICAgICAgd2luZG93LkF1ZGlvQ29udGV4dCA9IHdpbmRvdy53ZWJraXRBdWRpb0NvbnRleHQ7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vbm90IGZ1bmN0aW9uYWxseSBlcXVpdmFsZW50LCBidXQgb25seSBhbiBBUEkgcGxhY2Vob2xkZXJcblx0ICAgICAgICBpZiAoIUF1ZGlvQ29udGV4dC5wcm90b3R5cGUuY2xvc2UpIHtcblx0ICAgICAgICAgICAgQXVkaW9Db250ZXh0LnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChUb25lLmlzRnVuY3Rpb24odGhpcy5zdXNwZW5kKSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuc3VzcGVuZCgpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL25vdCBmdW5jdGlvbmFsbHkgZXF1aXZhbGVudFxuXHQgICAgICAgIGlmICghQXVkaW9Db250ZXh0LnByb3RvdHlwZS5yZXN1bWUpIHtcblx0ICAgICAgICAgICAgQXVkaW9Db250ZXh0LnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vY3JlYXRlR2FpblxuXHQgICAgICAgIGlmICghQXVkaW9Db250ZXh0LnByb3RvdHlwZS5jcmVhdGVHYWluICYmIEF1ZGlvQ29udGV4dC5wcm90b3R5cGUuY3JlYXRlR2Fpbk5vZGUpIHtcblx0ICAgICAgICAgICAgQXVkaW9Db250ZXh0LnByb3RvdHlwZS5jcmVhdGVHYWluID0gQXVkaW9Db250ZXh0LnByb3RvdHlwZS5jcmVhdGVHYWluTm9kZTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgLy9jcmVhdGVEZWxheVxuXHQgICAgICAgIGlmICghQXVkaW9Db250ZXh0LnByb3RvdHlwZS5jcmVhdGVEZWxheSAmJiBBdWRpb0NvbnRleHQucHJvdG90eXBlLmNyZWF0ZURlbGF5Tm9kZSkge1xuXHQgICAgICAgICAgICBBdWRpb0NvbnRleHQucHJvdG90eXBlLmNyZWF0ZURlbGF5ID0gQXVkaW9Db250ZXh0LnByb3RvdHlwZS5jcmVhdGVEZWxheU5vZGU7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vdGVzdCBkZWNvZGVBdWRpb0RhdGEgcmV0dXJucyBhIHByb21pc2Vcblx0ICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbW9oYXlvbmFvL3dlYi1hdWRpby1hcGktc2hpbS9ibG9iL21hc3Rlci9zcmMvQXVkaW9Db250ZXh0LmpzXG5cdCAgICAgICAgLy8gTUlUIExpY2Vuc2UgKGMpIDIwMTUgQG1vaGF5b25hb1xuXHQgICAgICAgIHZhciBkZWNvZGVBdWRpb0RhdGFQcm9taXNlID0gZmFsc2U7XG5cdCAgICAgICAgdmFyIG9mZmxpbmVDb250ZXh0ID0gbmV3IE9mZmxpbmVBdWRpb0NvbnRleHQoMSwgMSwgNDQxMDApO1xuXHQgICAgICAgIHZhciBhdWRpb0RhdGEgPSBuZXcgVWludDMyQXJyYXkoW1xuXHQgICAgICAgICAgICAxMTc5MDExNDEwLFxuXHQgICAgICAgICAgICA0OCxcblx0ICAgICAgICAgICAgMTE2MzI4MDcyNyxcblx0ICAgICAgICAgICAgNTQ0NTAxMDk0LFxuXHQgICAgICAgICAgICAxNixcblx0ICAgICAgICAgICAgMTMxMDczLFxuXHQgICAgICAgICAgICA0NDEwMCxcblx0ICAgICAgICAgICAgMTc2NDAwLFxuXHQgICAgICAgICAgICAxMDQ4NTgwLFxuXHQgICAgICAgICAgICAxNjM1MDE3MDYwLFxuXHQgICAgICAgICAgICA4LFxuXHQgICAgICAgICAgICAwLFxuXHQgICAgICAgICAgICAwLFxuXHQgICAgICAgICAgICAwLFxuXHQgICAgICAgICAgICAwXG5cdCAgICAgICAgXSkuYnVmZmVyO1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIHZhciByZXQgPSBvZmZsaW5lQ29udGV4dC5kZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhKTtcblx0ICAgICAgICAgICAgaWYgKHJldCBpbnN0YW5jZW9mIFByb21pc2UpIHtcblx0ICAgICAgICAgICAgICAgIGRlY29kZUF1ZGlvRGF0YVByb21pc2UgPSB0cnVlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSBjYXRjaCAoZSkge1xuXHQgICAgICAgICAgICBkZWNvZGVBdWRpb0RhdGFQcm9taXNlID0gZmFsc2U7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICghZGVjb2RlQXVkaW9EYXRhUHJvbWlzZSkge1xuXHQgICAgICAgICAgICBBdWRpb0NvbnRleHQucHJvdG90eXBlLl9uYXRpdmVfZGVjb2RlQXVkaW9EYXRhID0gQXVkaW9Db250ZXh0LnByb3RvdHlwZS5kZWNvZGVBdWRpb0RhdGE7XG5cdCAgICAgICAgICAgIEF1ZGlvQ29udGV4dC5wcm90b3R5cGUuZGVjb2RlQXVkaW9EYXRhID0gZnVuY3Rpb24gKGF1ZGlvRGF0YSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChzdWNjZXNzLCBlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZV9kZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhLCBzdWNjZXNzLCBlcnJvcik7XG5cdCAgICAgICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBXcmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIEF1ZGlvQ29udGV4dC5cblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuRW1pdHRlcn1cblx0XHQgKiAgQHBhcmFtIHtBdWRpb0NvbnRleHQ9fSBjb250ZXh0IG9wdGlvbmFsbHkgcGFzcyBpbiBhIGNvbnRleHRcblx0XHQgKi9cblx0ICAgIFRvbmUuQ29udGV4dCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkVtaXR0ZXIuY2FsbCh0aGlzKTtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbJ2NvbnRleHQnXSwgVG9uZS5Db250ZXh0KTtcblx0ICAgICAgICBpZiAoIW9wdGlvbnMuY29udGV4dCkge1xuXHQgICAgICAgICAgICBvcHRpb25zLmNvbnRleHQgPSBuZXcgd2luZG93LkF1ZGlvQ29udGV4dCgpO1xuXHQgICAgICAgICAgICBpZiAoIW9wdGlvbnMuY29udGV4dCkge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgY3JlYXRlIEF1ZGlvQ29udGV4dC4gUG9zc2libHkgdG9vIG1hbnkgQXVkaW9Db250ZXh0cyBydW5uaW5nIGFscmVhZHkuJyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5fY29udGV4dCA9IG9wdGlvbnMuY29udGV4dDtcblx0ICAgICAgICAvLyBleHRlbmQgYWxsIG9mIHRoZSBtZXRob2RzXG5cdCAgICAgICAgZm9yICh2YXIgcHJvcCBpbiB0aGlzLl9jb250ZXh0KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2RlZmluZVByb3BlcnR5KHRoaXMuX2NvbnRleHQsIHByb3ApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZGVmYXVsdCBsYXRlbmN5IGhpbnRcblx0XHRcdCAqICBAdHlwZSAge1N0cmluZ31cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbGF0ZW5jeUhpbnQgPSBvcHRpb25zLmxhdGVuY3lIaW50O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBvZiB0aGUgY29uc3RhbnRzIEF1ZGlvQnVmZmVyU291cmNlTm9kZXNcblx0XHRcdCAqICBAdHlwZSAge09iamVjdH1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fY29uc3RhbnRzID0ge307XG5cdCAgICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgICAgICAvLyBXT1JLRVJcblx0ICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhbW91bnQgb2YgdGltZSBldmVudHMgYXJlIHNjaGVkdWxlZFxuXHRcdFx0ICogIGludG8gdGhlIGZ1dHVyZVxuXHRcdFx0ICogIEB0eXBlICB7TnVtYmVyfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5sb29rQWhlYWQgPSBvcHRpb25zLmxvb2tBaGVhZDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBBIHJlZmVyZW5jZSB0byB0aGUgYWN0dWFsIGNvbXB1dGVkIHVwZGF0ZSBpbnRlcnZhbFxuXHRcdFx0ICogIEB0eXBlICB7TnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9jb21wdXRlZFVwZGF0ZUludGVydmFsID0gMDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBBIHJlbGlhYmxlIGNhbGxiYWNrIG1ldGhvZFxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUgIHtUaWNrZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl90aWNrZXIgPSBuZXcgVGlja2VyKHRoaXMuZW1pdC5iaW5kKHRoaXMsICd0aWNrJyksIG9wdGlvbnMuY2xvY2tTb3VyY2UsIG9wdGlvbnMudXBkYXRlSW50ZXJ2YWwpO1xuXHQgICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAgICAgLy8gVElNRU9VVFNcblx0ICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEFsbCBvZiB0aGUgc2V0VGltZW91dCBldmVudHMuXG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLlRpbWVsaW5lfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl90aW1lb3V0cyA9IG5ldyBUb25lLlRpbWVsaW5lKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHRpbWVvdXQgaWQgY291bnRlclxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge051bWJlcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3RpbWVvdXRJZHMgPSAwO1xuXHQgICAgICAgIHRoaXMub24oJ3RpY2snLCB0aGlzLl90aW1lb3V0TG9vcC5iaW5kKHRoaXMpKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkNvbnRleHQsIFRvbmUuRW1pdHRlcik7XG5cdCAgICBUb25lLkVtaXR0ZXIubWl4aW4oVG9uZS5Db250ZXh0KTtcblx0ICAgIC8qKlxuXHRcdCAqIGRlZmF1bHRzXG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkNvbnRleHQuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2Nsb2NrU291cmNlJzogJ3dvcmtlcicsXG5cdCAgICAgICAgJ2xhdGVuY3lIaW50JzogJ2ludGVyYWN0aXZlJyxcblx0ICAgICAgICAnbG9va0FoZWFkJzogMC4xLFxuXHQgICAgICAgICd1cGRhdGVJbnRlcnZhbCc6IDAuMDNcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgRGVmaW5lIGEgcHJvcGVydHkgb24gdGhpcyBUb25lLkNvbnRleHQuXG5cdFx0ICogIFRoaXMgaXMgdXNlZCB0byBleHRlbmQgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHRcblx0XHQgKiAgQHBhcmFtICB7QXVkaW9Db250ZXh0fSAgY29udGV4dFxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd9ICBwcm9wXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkNvbnRleHQucHJvdG90eXBlLl9kZWZpbmVQcm9wZXJ0eSA9IGZ1bmN0aW9uIChjb250ZXh0LCBwcm9wKSB7XG5cdCAgICAgICAgaWYgKFRvbmUuaXNVbmRlZih0aGlzW3Byb3BdKSkge1xuXHQgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgcHJvcCwge1xuXHQgICAgICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjb250ZXh0W3Byb3BdID09PSAnZnVuY3Rpb24nKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0W3Byb3BdLmJpbmQoY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHRbcHJvcF07XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbCkge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnRleHRbcHJvcF0gPSB2YWw7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGN1cnJlbnQgYXVkaW8gY29udGV4dCB0aW1lXG5cdFx0ICogIEByZXR1cm4gIHtOdW1iZXJ9XG5cdFx0ICovXG5cdCAgICBUb25lLkNvbnRleHQucHJvdG90eXBlLm5vdyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jdXJyZW50VGltZSArIHRoaXMubG9va0FoZWFkO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBQcm9taXNlIHdoaWNoIGlzIGludm9rZWQgd2hlbiB0aGUgY29udGV4dCBpcyBydW5uaW5nLlxuXHRcdCAqICBUcmllcyB0byByZXN1bWUgdGhlIGNvbnRleHQgaWYgaXQncyBub3Qgc3RhcnRlZC5cblx0XHQgKiAgQHJldHVybiAge1Byb21pc2V9XG5cdFx0ICovXG5cdCAgICBUb25lLkNvbnRleHQucHJvdG90eXBlLnJlYWR5ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoZG9uZSkge1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fY29udGV4dC5zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG5cdCAgICAgICAgICAgICAgICBkb25lKCk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9jb250ZXh0LnJlc3VtZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcblx0ICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUHJvbWlzZSB3aGljaCBpcyBpbnZva2VkIHdoZW4gdGhlIGNvbnRleHQgaXMgcnVubmluZy5cblx0XHQgKiAgVHJpZXMgdG8gcmVzdW1lIHRoZSBjb250ZXh0IGlmIGl0J3Mgbm90IHN0YXJ0ZWQuXG5cdFx0ICogIEByZXR1cm4gIHtQcm9taXNlfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Db250ZXh0LnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jbG9zZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBUb25lLkNvbnRleHQuZW1pdCgnY2xvc2UnLCB0aGlzKTtcblx0ICAgICAgICB9LmJpbmQodGhpcykpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBHZW5lcmF0ZSBhIGxvb3BlZCBidWZmZXIgYXQgc29tZSBjb25zdGFudCB2YWx1ZS5cblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgdmFsXG5cdFx0ICogIEByZXR1cm4gIHtCdWZmZXJTb3VyY2VOb2RlfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Db250ZXh0LnByb3RvdHlwZS5nZXRDb25zdGFudCA9IGZ1bmN0aW9uICh2YWwpIHtcblx0ICAgICAgICBpZiAodGhpcy5fY29uc3RhbnRzW3ZhbF0pIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnN0YW50c1t2YWxdO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHZhciBidWZmZXIgPSB0aGlzLl9jb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAxMjgsIHRoaXMuX2NvbnRleHQuc2FtcGxlUmF0ZSk7XG5cdCAgICAgICAgICAgIHZhciBhcnIgPSBidWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBhcnJbaV0gPSB2YWw7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdmFyIGNvbnN0YW50ID0gdGhpcy5fY29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcblx0ICAgICAgICAgICAgY29uc3RhbnQuY2hhbm5lbENvdW50ID0gMTtcblx0ICAgICAgICAgICAgY29uc3RhbnQuY2hhbm5lbENvdW50TW9kZSA9ICdleHBsaWNpdCc7XG5cdCAgICAgICAgICAgIGNvbnN0YW50LmJ1ZmZlciA9IGJ1ZmZlcjtcblx0ICAgICAgICAgICAgY29uc3RhbnQubG9vcCA9IHRydWU7XG5cdCAgICAgICAgICAgIGNvbnN0YW50LnN0YXJ0KDApO1xuXHQgICAgICAgICAgICB0aGlzLl9jb25zdGFudHNbdmFsXSA9IGNvbnN0YW50O1xuXHQgICAgICAgICAgICByZXR1cm4gY29uc3RhbnQ7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgcHJpdmF0ZSBsb29wIHdoaWNoIGtlZXBzIHRyYWNrIG9mIHRoZSBjb250ZXh0IHNjaGVkdWxlZCB0aW1lb3V0c1xuXHRcdCAqICBJcyBpbnZva2VkIGZyb20gdGhlIGNsb2NrIHNvdXJjZVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Db250ZXh0LnByb3RvdHlwZS5fdGltZW91dExvb3AgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG5vdyA9IHRoaXMubm93KCk7XG5cdCAgICAgICAgd2hpbGUgKHRoaXMuX3RpbWVvdXRzICYmIHRoaXMuX3RpbWVvdXRzLmxlbmd0aCAmJiB0aGlzLl90aW1lb3V0cy5wZWVrKCkudGltZSA8PSBub3cpIHtcblx0ICAgICAgICAgICAgdGhpcy5fdGltZW91dHMuc2hpZnQoKS5jYWxsYmFjaygpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQSBzZXRUaW1lb3V0IHdoaWNoIGlzIGdhdXJlbnRlZWQgYnkgdGhlIGNsb2NrIHNvdXJjZS5cblx0XHQgKiAgQWxzbyBydW5zIGluIHRoZSBvZmZsaW5lIGNvbnRleHQuXG5cdFx0ICogIEBwYXJhbSAge0Z1bmN0aW9ufSAgZm4gICAgICAgVGhlIGNhbGxiYWNrIHRvIGludm9rZVxuXHRcdCAqICBAcGFyYW0gIHtTZWNvbmRzfSAgICB0aW1lb3V0ICBUaGUgdGltZW91dCBpbiBzZWNvbmRzXG5cdFx0ICogIEByZXR1cm5zIHtOdW1iZXJ9IElEIHRvIHVzZSB3aGVuIGludm9raW5nIFRvbmUuQ29udGV4dC5jbGVhclRpbWVvdXRcblx0XHQgKi9cblx0ICAgIFRvbmUuQ29udGV4dC5wcm90b3R5cGUuc2V0VGltZW91dCA9IGZ1bmN0aW9uIChmbiwgdGltZW91dCkge1xuXHQgICAgICAgIHRoaXMuX3RpbWVvdXRJZHMrKztcblx0ICAgICAgICB2YXIgbm93ID0gdGhpcy5ub3coKTtcblx0ICAgICAgICB0aGlzLl90aW1lb3V0cy5hZGQoe1xuXHQgICAgICAgICAgICBjYWxsYmFjazogZm4sXG5cdCAgICAgICAgICAgIHRpbWU6IG5vdyArIHRpbWVvdXQsXG5cdCAgICAgICAgICAgIGlkOiB0aGlzLl90aW1lb3V0SWRzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVvdXRJZHM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFycyBhIHByZXZpb3VzbHkgc2NoZWR1bGVkIHRpbWVvdXQgd2l0aCBUb25lLmNvbnRleHQuc2V0VGltZW91dFxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICBpZCAgVGhlIElEIHJldHVybmVkIGZyb20gc2V0VGltZW91dFxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5Db250ZXh0fSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Db250ZXh0LnByb3RvdHlwZS5jbGVhclRpbWVvdXQgPSBmdW5jdGlvbiAoaWQpIHtcblx0ICAgICAgICB0aGlzLl90aW1lb3V0cy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgICAgICBpZiAoZXZlbnQuaWQgPT09IGlkKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZShldmVudCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgSG93IG9mdGVuIHRoZSBXZWIgV29ya2VyIGNhbGxiYWNrIGlzIGludm9rZWQuXG5cdFx0ICogIFRoaXMgbnVtYmVyIGNvcnJlc3BvbmRzIHRvIGhvdyByZXNwb25zaXZlIHRoZSBzY2hlZHVsaW5nXG5cdFx0ICogIGNhbiBiZS4gQ29udGV4dC51cGRhdGVJbnRlcnZhbCArIENvbnRleHQubG9va0FoZWFkIGdpdmVzIHlvdSB0aGVcblx0XHQgKiAgdG90YWwgbGF0ZW5jeSBiZXR3ZWVuIHNjaGVkdWxpbmcgYW4gZXZlbnQgYW5kIGhlYXJpbmcgaXQuXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkNvbnRleHQjXG5cdFx0ICogIEBuYW1lIHVwZGF0ZUludGVydmFsXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5Db250ZXh0LnByb3RvdHlwZSwgJ3VwZGF0ZUludGVydmFsJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fdGlja2VyLnVwZGF0ZUludGVydmFsO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoaW50ZXJ2YWwpIHtcblx0ICAgICAgICAgICAgdGhpcy5fdGlja2VyLnVwZGF0ZUludGVydmFsID0gaW50ZXJ2YWw7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgV2hhdCB0aGUgc291cmNlIG9mIHRoZSBjbG9jayBpcywgZWl0aGVyIFwid29ya2VyXCIgKFdlYiBXb3JrZXIgW2RlZmF1bHRdKSxcblx0XHQgKiAgXCJ0aW1lb3V0XCIgKHNldFRpbWVvdXQpLCBvciBcIm9mZmxpbmVcIiAobm9uZSkuXG5cdFx0ICogIEB0eXBlIHtTdHJpbmd9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkNvbnRleHQjXG5cdFx0ICogIEBuYW1lIGNsb2NrU291cmNlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5Db250ZXh0LnByb3RvdHlwZSwgJ2Nsb2NrU291cmNlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fdGlja2VyLnR5cGU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh0eXBlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3RpY2tlci50eXBlID0gdHlwZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgdHlwZSBvZiBwbGF5YmFjaywgd2hpY2ggYWZmZWN0cyB0cmFkZW9mZnMgYmV0d2VlbiBhdWRpb1xuXHRcdCAqICBvdXRwdXQgbGF0ZW5jeSBhbmQgcmVzcG9uc2l2ZW5lc3MuXG5cdFx0ICpcblx0XHQgKiAgSW4gYWRkaXRpb24gdG8gc2V0dGluZyB0aGUgdmFsdWUgaW4gc2Vjb25kcywgdGhlIGxhdGVuY3lIaW50IGFsc29cblx0XHQgKiAgYWNjZXB0cyB0aGUgc3RyaW5ncyBcImludGVyYWN0aXZlXCIgKHByaW9yaXRpemVzIGxvdyBsYXRlbmN5KSxcblx0XHQgKiAgXCJwbGF5YmFja1wiIChwcmlvcml0aXplcyBzdXN0YWluZWQgcGxheWJhY2spLCBcImJhbGFuY2VkXCIgKGJhbGFuY2VzXG5cdFx0ICogIGxhdGVuY3kgYW5kIHBlcmZvcm1hbmNlKSwgYW5kIFwiZmFzdGVzdFwiIChsb3dlc3QgbGF0ZW5jeSwgbWlnaHQgZ2xpdGNoIG1vcmUgb2Z0ZW4pLlxuXHRcdCAqICBAdHlwZSB7U3RyaW5nfFNlY29uZHN9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkNvbnRleHQjXG5cdFx0ICogIEBuYW1lIGxhdGVuY3lIaW50XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9zZXQgdGhlIGxvb2tBaGVhZCB0byAwLjMgc2Vjb25kc1xuXHRcdCAqIFRvbmUuY29udGV4dC5sYXRlbmN5SGludCA9IDAuMztcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkNvbnRleHQucHJvdG90eXBlLCAnbGF0ZW5jeUhpbnQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9sYXRlbmN5SGludDtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGhpbnQpIHtcblx0ICAgICAgICAgICAgdmFyIGxvb2tBaGVhZCA9IGhpbnQ7XG5cdCAgICAgICAgICAgIHRoaXMuX2xhdGVuY3lIaW50ID0gaGludDtcblx0ICAgICAgICAgICAgaWYgKFRvbmUuaXNTdHJpbmcoaGludCkpIHtcblx0ICAgICAgICAgICAgICAgIHN3aXRjaCAoaGludCkge1xuXHQgICAgICAgICAgICAgICAgY2FzZSAnaW50ZXJhY3RpdmUnOlxuXHQgICAgICAgICAgICAgICAgICAgIGxvb2tBaGVhZCA9IDAuMTtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl9jb250ZXh0LmxhdGVuY3lIaW50ID0gaGludDtcblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIGNhc2UgJ3BsYXliYWNrJzpcblx0ICAgICAgICAgICAgICAgICAgICBsb29rQWhlYWQgPSAwLjg7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29udGV4dC5sYXRlbmN5SGludCA9IGhpbnQ7XG5cdCAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgICAgICAgICBjYXNlICdiYWxhbmNlZCc6XG5cdCAgICAgICAgICAgICAgICAgICAgbG9va0FoZWFkID0gMC4yNTtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl9jb250ZXh0LmxhdGVuY3lIaW50ID0gaGludDtcblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIGNhc2UgJ2Zhc3Rlc3QnOlxuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NvbnRleHQubGF0ZW5jeUhpbnQgPSAnaW50ZXJhY3RpdmUnO1xuXHQgICAgICAgICAgICAgICAgICAgIGxvb2tBaGVhZCA9IDAuMDE7XG5cdCAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5sb29rQWhlYWQgPSBsb29rQWhlYWQ7XG5cdCAgICAgICAgICAgIHRoaXMudXBkYXRlSW50ZXJ2YWwgPSBsb29rQWhlYWQgLyAzO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFVubGlrZSBvdGhlciBkaXNwb3NlIG1ldGhvZHMsIHRoaXMgcmV0dXJucyBhIFByb21pc2Vcblx0XHQgKiAgd2hpY2ggZXhlY3V0ZXMgd2hlbiB0aGUgY29udGV4dCBpcyBjbG9zZWQgYW5kIGRpc3Bvc2VkXG5cdFx0ICogIEByZXR1cm5zIHtQcm9taXNlfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkNvbnRleHQucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuY2xvc2UoKS50aGVuKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgVG9uZS5FbWl0dGVyLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgICAgIHRoaXMuX3RpY2tlci5kaXNwb3NlKCk7XG5cdCAgICAgICAgICAgIHRoaXMuX3RpY2tlciA9IG51bGw7XG5cdCAgICAgICAgICAgIHRoaXMuX3RpbWVvdXRzLmRpc3Bvc2UoKTtcblx0ICAgICAgICAgICAgdGhpcy5fdGltZW91dHMgPSBudWxsO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBjb24gaW4gdGhpcy5fY29uc3RhbnRzKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9jb25zdGFudHNbY29uXS5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5fY29uc3RhbnRzID0gbnVsbDtcblx0ICAgICAgICB9LmJpbmQodGhpcykpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIEBjbGFzcyBBIGNsYXNzIHdoaWNoIHByb3ZpZGVzIGEgcmVsaWFibGUgY2FsbGJhY2sgdXNpbmcgZWl0aGVyXG5cdFx0ICogICAgICAgIGEgV2ViIFdvcmtlciwgb3IgaWYgdGhhdCBpc24ndCBzdXBwb3J0ZWQsIGZhbGxzIGJhY2sgdG8gc2V0VGltZW91dC5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgdmFyIFRpY2tlciA9IGZ1bmN0aW9uIChjYWxsYmFjaywgdHlwZSwgdXBkYXRlSW50ZXJ2YWwpIHtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIEVpdGhlciBcIndvcmtlclwiIG9yIFwidGltZW91dFwiXG5cdFx0XHQgKiBAdHlwZSB7U3RyaW5nfVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIHVwZGF0ZSBpbnRlcnZhbCBvZiB0aGUgd29ya2VyXG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICogQHR5cGUge051bWJlcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3VwZGF0ZUludGVydmFsID0gdXBkYXRlSW50ZXJ2YWw7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIGF0IHJlZ3VsYXIgaW50ZXJ2YWxzXG5cdFx0XHQgKiBAdHlwZSB7RnVuY3Rpb259XG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fY2FsbGJhY2sgPSBUb25lLmRlZmF1bHRBcmcoY2FsbGJhY2ssIFRvbmUubm9PcCk7XG5cdCAgICAgICAgLy9jcmVhdGUgdGhlIGNsb2NrIHNvdXJjZSBmb3IgdGhlIGZpcnN0IHRpbWVcblx0ICAgICAgICB0aGlzLl9jcmVhdGVDbG9jaygpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBwb3NzaWJsZSB0aWNrZXIgdHlwZXNcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUaWNrZXIuVHlwZSA9IHtcblx0ICAgICAgICBXb3JrZXI6ICd3b3JrZXInLFxuXHQgICAgICAgIFRpbWVvdXQ6ICd0aW1lb3V0Jyxcblx0ICAgICAgICBPZmZsaW5lOiAnb2ZmbGluZSdcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgR2VuZXJhdGUgYSB3ZWIgd29ya2VyXG5cdFx0ICogIEByZXR1cm4gIHtXZWJXb3JrZXJ9XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUaWNrZXIucHJvdG90eXBlLl9jcmVhdGVXb3JrZXIgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgLy9VUkwgU2hpbVxuXHQgICAgICAgIHdpbmRvdy5VUkwgPSB3aW5kb3cuVVJMIHx8IHdpbmRvdy53ZWJraXRVUkw7XG5cdCAgICAgICAgdmFyIGJsb2IgPSBuZXcgQmxvYihbLy90aGUgaW5pdGlhbCB0aW1lb3V0IHRpbWVcblx0ICAgICAgICAgICAgJ3ZhciB0aW1lb3V0VGltZSA9ICcgKyAodGhpcy5fdXBkYXRlSW50ZXJ2YWwgKiAxMDAwKS50b0ZpeGVkKDEpICsgJzsnICsgLy9vbm1lc3NhZ2UgY2FsbGJhY2tcblx0ICAgICAgICAgICAgJ3NlbGYub25tZXNzYWdlID0gZnVuY3Rpb24obXNnKXsnICsgJ1xcdHRpbWVvdXRUaW1lID0gcGFyc2VJbnQobXNnLmRhdGEpOycgKyAnfTsnICsgLy90aGUgdGljayBmdW5jdGlvbiB3aGljaCBwb3N0cyBhIG1lc3NhZ2Vcblx0ICAgICAgICAgICAgLy9hbmQgc2NoZWR1bGVzIGEgbmV3IHRpY2tcblx0ICAgICAgICAgICAgJ2Z1bmN0aW9uIHRpY2soKXsnICsgJ1xcdHNldFRpbWVvdXQodGljaywgdGltZW91dFRpbWUpOycgKyAnXFx0c2VsZi5wb3N0TWVzc2FnZShcXCd0aWNrXFwnKTsnICsgJ30nICsgLy9jYWxsIHRpY2sgaW5pdGlhbGx5XG5cdCAgICAgICAgICAgICd0aWNrKCk7J10pO1xuXHQgICAgICAgIHZhciBibG9iVXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcblx0ICAgICAgICB2YXIgd29ya2VyID0gbmV3IFdvcmtlcihibG9iVXJsKTtcblx0ICAgICAgICB3b3JrZXIub25tZXNzYWdlID0gdGhpcy5fY2FsbGJhY2suYmluZCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl93b3JrZXIgPSB3b3JrZXI7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogQ3JlYXRlIGEgdGltZW91dCBsb29wXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRpY2tlci5wcm90b3R5cGUuX2NyZWF0ZVRpbWVvdXQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB0aGlzLl9jcmVhdGVUaW1lb3V0KCk7XG5cdCAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrKCk7XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpLCB0aGlzLl91cGRhdGVJbnRlcnZhbCAqIDEwMDApO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIENyZWF0ZSB0aGUgY2xvY2sgc291cmNlLlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUaWNrZXIucHJvdG90eXBlLl9jcmVhdGVDbG9jayA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gVGlja2VyLlR5cGUuV29ya2VyKSB7XG5cdCAgICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVXb3JrZXIoKTtcblx0ICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuXHQgICAgICAgICAgICAgICAgLy8gd29ya2VycyBub3Qgc3VwcG9ydGVkLCBmYWxsYmFjayB0byB0aW1lb3V0XG5cdCAgICAgICAgICAgICAgICB0aGlzLl90eXBlID0gVGlja2VyLlR5cGUuVGltZW91dDtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUNsb2NrKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3R5cGUgPT09IFRpY2tlci5UeXBlLlRpbWVvdXQpIHtcblx0ICAgICAgICAgICAgdGhpcy5fY3JlYXRlVGltZW91dCgpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBAbWVtYmVyT2YgVGlja2VyI1xuXHRcdCAqIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogQG5hbWUgdXBkYXRlSW50ZXJ2YWxcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRpY2tlci5wcm90b3R5cGUsICd1cGRhdGVJbnRlcnZhbCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZUludGVydmFsO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoaW50ZXJ2YWwpIHtcblx0ICAgICAgICAgICAgdGhpcy5fdXBkYXRlSW50ZXJ2YWwgPSBNYXRoLm1heChpbnRlcnZhbCwgMTI4IC8gNDQxMDApO1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gVGlja2VyLlR5cGUuV29ya2VyKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl93b3JrZXIucG9zdE1lc3NhZ2UoTWF0aC5tYXgoaW50ZXJ2YWwgKiAxMDAwLCAxKSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSB0eXBlIG9mIHRoZSB0aWNrZXIsIGVpdGhlciBhIHdvcmtlciBvciBhIHRpbWVvdXRcblx0XHQgKiBAbWVtYmVyT2YgVGlja2VyI1xuXHRcdCAqIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogQG5hbWUgdHlwZVxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVGlja2VyLnByb3RvdHlwZSwgJ3R5cGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodHlwZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9kaXNwb3NlQ2xvY2soKTtcblx0ICAgICAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG5cdCAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUNsb2NrKCk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBDbGVhbiB1cCB0aGUgY3VycmVudCBjbG9jayBzb3VyY2Vcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVGlja2VyLnByb3RvdHlwZS5fZGlzcG9zZUNsb2NrID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGlmICh0aGlzLl90aW1lb3V0KSB7XG5cdCAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0KTtcblx0ICAgICAgICAgICAgdGhpcy5fdGltZW91dCA9IG51bGw7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICh0aGlzLl93b3JrZXIpIHtcblx0ICAgICAgICAgICAgdGhpcy5fd29ya2VyLnRlcm1pbmF0ZSgpO1xuXHQgICAgICAgICAgICB0aGlzLl93b3JrZXIub25tZXNzYWdlID0gbnVsbDtcblx0ICAgICAgICAgICAgdGhpcy5fd29ya2VyID0gbnVsbDtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogQ2xlYW4gdXBcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVGlja2VyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuX2Rpc3Bvc2VDbG9jaygpO1xuXHQgICAgICAgIHRoaXMuX2NhbGxiYWNrID0gbnVsbDtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU2hpbSBhbGwgY29ubmVjdC9kaXNjb25uZWN0IGFuZCBzb21lIGRlcHJlY2F0ZWQgbWV0aG9kcyB3aGljaCBhcmUgc3RpbGwgaW5cblx0XHQgKiAgc29tZSBvbGRlciBpbXBsZW1lbnRhdGlvbnMuXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLmdldENvbnRleHQoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBuYXRpdmVDb25uZWN0ID0gQXVkaW9Ob2RlLnByb3RvdHlwZS5jb25uZWN0O1xuXHQgICAgICAgIHZhciBuYXRpdmVEaXNjb25uZWN0ID0gQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNjb25uZWN0O1xuXHQgICAgICAgIC8vcmVwbGFjZSB0aGUgb2xkIGNvbm5lY3QgbWV0aG9kXG5cdCAgICAgICAgZnVuY3Rpb24gdG9uZUNvbm5lY3QoQiwgb3V0TnVtLCBpbk51bSkge1xuXHQgICAgICAgICAgICBpZiAoQi5pbnB1dCkge1xuXHQgICAgICAgICAgICAgICAgaW5OdW0gPSBUb25lLmRlZmF1bHRBcmcoaW5OdW0sIDApO1xuXHQgICAgICAgICAgICAgICAgaWYgKFRvbmUuaXNBcnJheShCLmlucHV0KSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3QoQi5pbnB1dFtpbk51bV0pO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0KEIuaW5wdXQsIG91dE51bSwgaW5OdW0pO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAoQiBpbnN0YW5jZW9mIEF1ZGlvTm9kZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVDb25uZWN0LmNhbGwodGhpcywgQiwgb3V0TnVtLCBpbk51bSk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBCO1xuXHQgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNvbm5lY3QuY2FsbCh0aGlzLCBCLCBvdXROdW0pO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQjtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdlcnJvciBjb25uZWN0aW5nIHRvIG5vZGU6ICcgKyBCICsgJ1xcbicgKyBlKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICAvL3JlcGxhY2UgdGhlIG9sZCBkaXNjb25uZWN0IG1ldGhvZFxuXHQgICAgICAgIGZ1bmN0aW9uIHRvbmVEaXNjb25uZWN0KEIsIG91dE51bSwgaW5OdW0pIHtcblx0ICAgICAgICAgICAgaWYgKEIgJiYgQi5pbnB1dCAmJiBUb25lLmlzQXJyYXkoQi5pbnB1dCkpIHtcblx0ICAgICAgICAgICAgICAgIGluTnVtID0gVG9uZS5kZWZhdWx0QXJnKGluTnVtLCAwKTtcblx0ICAgICAgICAgICAgICAgIHRoaXMuZGlzY29ubmVjdChCLmlucHV0W2luTnVtXSwgb3V0TnVtLCAwKTtcblx0ICAgICAgICAgICAgfSBlbHNlIGlmIChCICYmIEIuaW5wdXQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuZGlzY29ubmVjdChCLmlucHV0LCBvdXROdW0sIGluTnVtKTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgICAgICAgICAgbmF0aXZlRGlzY29ubmVjdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXHQgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZXJyb3IgZGlzY29ubmVjdGluZyBub2RlOiAnICsgQiArICdcXG4nICsgZSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKEF1ZGlvTm9kZS5wcm90b3R5cGUuY29ubmVjdCAhPT0gdG9uZUNvbm5lY3QpIHtcblx0ICAgICAgICAgICAgQXVkaW9Ob2RlLnByb3RvdHlwZS5jb25uZWN0ID0gdG9uZUNvbm5lY3Q7XG5cdCAgICAgICAgICAgIEF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzY29ubmVjdCA9IHRvbmVEaXNjb25uZWN0O1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLy8gc2V0IHRoZSBhdWRpbyBjb250ZXh0IGluaXRpYWxseSwgYW5kIGlmIG9uZSBpcyBub3QgYWxyZWFkeSBjcmVhdGVkXG5cdCAgICBpZiAoVG9uZS5zdXBwb3J0ZWQgJiYgIVRvbmUuaW5pdGlhbGl6ZWQpIHtcblx0ICAgICAgICBUb25lLmNvbnRleHQgPSBuZXcgVG9uZS5Db250ZXh0KCk7XG5cdCAgICAgICAgLy8gbG9nIG9uIGZpcnN0IGluaXRpYWxpemF0aW9uXG5cdCAgICAgICAgLy8gYWxsb3cgb3B0aW9uYWwgc2lsZW5jaW5nIG9mIHRoaXMgbG9nXG5cdCAgICAgICAgaWYgKCF3aW5kb3cuVE9ORV9TSUxFTkNFX1ZFUlNJT05fTE9HR0lORykge1xuXHQgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuXHQgICAgICAgICAgICBjb25zb2xlLmxvZygnJWMgKiBUb25lLmpzICcgKyBUb25lLnZlcnNpb24gKyAnICogJywgJ2JhY2tncm91bmQ6ICMwMDA7IGNvbG9yOiAjZmZmJyk7XG5cdCAgICAgICAgfVxuXHQgICAgfSBlbHNlIGlmICghVG9uZS5zdXBwb3J0ZWQpIHtcblx0ICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuXHQgICAgICAgIGNvbnNvbGUud2FybignVGhpcyBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgVG9uZS5qcycpO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuIFRvbmUuQ29udGV4dDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBUb25lLkF1ZGlvTm9kZSBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgY2xhc3NlcyB3aGljaCBwcm9jZXNzIGF1ZGlvLlxuXHRcdCAqICAgICAgICAgQXVkaW9Ob2RlcyBoYXZlIGlucHV0cyBhbmQgb3V0cHV0cy5cblx0XHQgKiAgQHBhcmFtXHR7QXVkaW9Db250ZXh0PX0gY29udGV4dFx0VGhlIGF1ZGlvIGNvbnRleHQgdG8gdXNlIHdpdGggdGhlIGNsYXNzXG5cdFx0ICogIEBleHRlbmRzIHtUb25lfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5BdWRpb05vZGUgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8vdXNlIHRoZSBkZWZhdWx0IGNvbnRleHQgaWYgb25lIGlzIG5vdCBwYXNzZWQgaW5cblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbJ2NvbnRleHQnXSwgeyAnY29udGV4dCc6IFRvbmUuY29udGV4dCB9KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBBdWRpb0NvbnRleHQgb2YgdGhpcyBpbnN0YW5jZVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqIEB0eXBlIHtBdWRpb0NvbnRleHR9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9jb250ZXh0ID0gb3B0aW9ucy5jb250ZXh0O1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqIEdldCB0aGUgYXVkaW8gY29udGV4dCBiZWxvbmdpbmcgdG8gdGhpcyBpbnN0YW5jZS5cblx0XHQgKiBAdHlwZSB7VG9uZS5Db250ZXh0fVxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkF1ZGlvTm9kZSNcblx0XHQgKiBAbmFtZSBjb250ZXh0XG5cdFx0ICogQHJlYWRPbmx5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLCAnY29udGV4dCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQ7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQ3JlYXRlIGlucHV0IGFuZCBvdXRwdXRzIGZvciB0aGlzIG9iamVjdC5cblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgW2lucHV0PTBdICAgVGhlIG51bWJlciBvZiBpbnB1dHNcblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgW291dHB1dHM9MF0gIFRoZSBudW1iZXIgb2Ygb3V0cHV0c1xuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5BdWRpb05vZGV9ICB0aGlzXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuY3JlYXRlSW5zT3V0cyA9IGZ1bmN0aW9uIChpbnB1dHMsIG91dHB1dHMpIHtcblx0ICAgICAgICBpZiAoaW5wdXRzID09PSAxKSB7XG5cdCAgICAgICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlR2FpbigpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAoaW5wdXRzID4gMSkge1xuXHQgICAgICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEFycmF5KGlucHV0cyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChvdXRwdXRzID09PSAxKSB7XG5cdCAgICAgICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUdhaW4oKTtcblx0ICAgICAgICB9IGVsc2UgaWYgKG91dHB1dHMgPiAxKSB7XG5cdCAgICAgICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEFycmF5KG91dHB1dHMpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgY2hhbm5lbENvdW50IGlzIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMgdXNlZCB3aGVuIHVwLW1peGluZyBhbmQgZG93bi1taXhpbmdcblx0XHQgKiAgY29ubmVjdGlvbnMgdG8gYW55IGlucHV0cyB0byB0aGUgbm9kZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgMiBleGNlcHQgZm9yXG5cdFx0ICogIHNwZWNpZmljIG5vZGVzIHdoZXJlIGl0cyB2YWx1ZSBpcyBzcGVjaWFsbHkgZGV0ZXJtaW5lZC5cblx0XHQgKlxuXHRcdCAqICBAbWVtYmVyb2YgVG9uZS5BdWRpb05vZGUjXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBuYW1lIGNoYW5uZWxDb3VudFxuXHRcdCAqICBAcmVhZE9ubHlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUsICdjaGFubmVsQ291bnQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLm91dHB1dC5jaGFubmVsQ291bnQ7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChjKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLm91dHB1dC5jaGFubmVsQ291bnQgPSBjO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIGNoYW5uZWxDb3VudE1vZGUgZGV0ZXJtaW5lcyBob3cgY2hhbm5lbHMgd2lsbCBiZSBjb3VudGVkIHdoZW4gdXAtbWl4aW5nIGFuZFxuXHRcdCAqICBkb3duLW1peGluZyBjb25uZWN0aW9ucyB0byBhbnkgaW5wdXRzIHRvIHRoZSBub2RlLlxuXHRcdCAqICBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBcIm1heFwiLiBUaGlzIGF0dHJpYnV0ZSBoYXMgbm8gZWZmZWN0IGZvciBub2RlcyB3aXRoIG5vIGlucHV0cy5cblx0XHQgKiAgQG1lbWJlcm9mIFRvbmUuQXVkaW9Ob2RlI1xuXHRcdCAqICBAdHlwZSB7U3RyaW5nfVxuXHRcdCAqICBAbmFtZSBjaGFubmVsQ291bnRNb2RlXG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLm91dHB1dC5jaGFubmVsQ291bnRNb2RlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobSkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5vdXRwdXQuY2hhbm5lbENvdW50TW9kZSA9IG07XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgY2hhbm5lbEludGVycHJldGF0aW9uIGRldGVybWluZXMgaG93IGluZGl2aWR1YWwgY2hhbm5lbHMgd2lsbCBiZSB0cmVhdGVkXG5cdFx0ICogIHdoZW4gdXAtbWl4aW5nIGFuZCBkb3duLW1peGluZyBjb25uZWN0aW9ucyB0byBhbnkgaW5wdXRzIHRvIHRoZSBub2RlLlxuXHRcdCAqICBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBcInNwZWFrZXJzXCIuXG5cdFx0ICogIEBtZW1iZXJvZiBUb25lLkF1ZGlvTm9kZSNcblx0XHQgKiAgQHR5cGUge1N0cmluZ31cblx0XHQgKiAgQG5hbWUgY2hhbm5lbEludGVycHJldGF0aW9uXG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZSwgJ2NoYW5uZWxJbnRlcnByZXRhdGlvbicsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMub3V0cHV0LmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGkpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMub3V0cHV0LmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IGk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIG51bWJlciBvZiBpbnB1dHMgZmVlZGluZyBpbnRvIHRoZSBBdWRpb05vZGUuXG5cdFx0ICogIEZvciBzb3VyY2Ugbm9kZXMsIHRoaXMgd2lsbCBiZSAwLlxuXHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqICBAbmFtZSBudW1iZXJPZklucHV0c1xuXHRcdCAqICBAbWVtYmVyb2YgVG9uZS5BdWRpb05vZGUjXG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZSwgJ251bWJlck9mSW5wdXRzJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBpZiAodGhpcy5pbnB1dCkge1xuXHQgICAgICAgICAgICAgICAgaWYgKFRvbmUuaXNBcnJheSh0aGlzLmlucHV0KSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmlucHV0Lmxlbmd0aDtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gMDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBudW1iZXIgb2Ygb3V0cHV0cyBjb21pbmcgb3V0IG9mIHRoZSBBdWRpb05vZGUuXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBuYW1lIG51bWJlck9mT3V0cHV0c1xuXHRcdCAqICBAbWVtYmVyb2YgVG9uZS5BdWRpb05vZGUjXG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZSwgJ251bWJlck9mT3V0cHV0cycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMub3V0cHV0KSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoVG9uZS5pc0FycmF5KHRoaXMub3V0cHV0KSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm91dHB1dC5sZW5ndGg7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiAxO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIENhbGxlZCB3aGVuIGFuIGF1ZGlvIHBhcmFtIGNvbm5lY3RzIHRvIHRoaXMgbm9kZVxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuX29uQ29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgY29ubmVjdCB0aGUgb3V0cHV0IG9mIGEgVG9uZU5vZGUgdG8gYW4gQXVkaW9QYXJhbSwgQXVkaW9Ob2RlLCBvciBUb25lTm9kZVxuXHRcdCAqICBAcGFyYW0gIHtUb25lIHwgQXVkaW9QYXJhbSB8IEF1ZGlvTm9kZX0gdW5pdFxuXHRcdCAqICBAcGFyYW0ge251bWJlcn0gW291dHB1dE51bT0wXSBvcHRpb25hbGx5IHdoaWNoIG91dHB1dCB0byBjb25uZWN0IGZyb21cblx0XHQgKiAgQHBhcmFtIHtudW1iZXJ9IFtpbnB1dE51bT0wXSBvcHRpb25hbGx5IHdoaWNoIGlucHV0IHRvIGNvbm5lY3QgdG9cblx0XHQgKiAgQHJldHVybnMge1RvbmUuQXVkaW9Ob2RlfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uICh1bml0LCBvdXRwdXROdW0sIGlucHV0TnVtKSB7XG5cdCAgICAgICAgaWYgKHVuaXQuX29uQ29ubmVjdCkge1xuXHQgICAgICAgICAgICB1bml0Ll9vbkNvbm5lY3QodGhpcyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChUb25lLmlzQXJyYXkodGhpcy5vdXRwdXQpKSB7XG5cdCAgICAgICAgICAgIG91dHB1dE51bSA9IFRvbmUuZGVmYXVsdEFyZyhvdXRwdXROdW0sIDApO1xuXHQgICAgICAgICAgICB0aGlzLm91dHB1dFtvdXRwdXROdW1dLmNvbm5lY3QodW5pdCwgMCwgaW5wdXROdW0pO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRoaXMub3V0cHV0LmNvbm5lY3QodW5pdCwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBkaXNjb25uZWN0IHRoZSBvdXRwdXRcblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ8QXVkaW9Ob2RlfSBvdXRwdXQgRWl0aGVyIHRoZSBvdXRwdXQgaW5kZXggdG8gZGlzY29ubmVjdFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiB0aGUgb3V0cHV0IGlzIGFuIGFycmF5LCBvciB0aGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSB0byBkaXNjb25uZWN0IGZyb20uXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkF1ZGlvTm9kZX0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbiAoZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pIHtcblx0ICAgICAgICBpZiAoVG9uZS5pc0FycmF5KHRoaXMub3V0cHV0KSkge1xuXHQgICAgICAgICAgICBpZiAoVG9uZS5pc051bWJlcihkZXN0aW5hdGlvbikpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0W2Rlc3RpbmF0aW9uXS5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBvdXRwdXROdW0gPSBUb25lLmRlZmF1bHRBcmcob3V0cHV0TnVtLCAwKTtcblx0ICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0W291dHB1dE51bV0uZGlzY29ubmVjdChkZXN0aW5hdGlvbiwgMCwgaW5wdXROdW0pO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGhpcy5vdXRwdXQuZGlzY29ubmVjdC5hcHBseSh0aGlzLm91dHB1dCwgYXJndW1lbnRzKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENvbm5lY3QgdGhlIG91dHB1dCBvZiB0aGlzIG5vZGUgdG8gdGhlIHJlc3Qgb2YgdGhlIG5vZGVzIGluIHNlcmllcy5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAgLy9jb25uZWN0IGEgbm9kZSB0byBhbiBlZmZlY3QsIHBhblZvbCBhbmQgdGhlbiB0byB0aGUgbWFzdGVyIG91dHB1dFxuXHRcdCAqICBub2RlLmNoYWluKGVmZmVjdCwgcGFuVm9sLCBUb25lLk1hc3Rlcik7XG5cdFx0ICogIEBwYXJhbSB7Li4uQXVkaW9QYXJhbXxUb25lfEF1ZGlvTm9kZX0gbm9kZXNcblx0XHQgKiAgQHJldHVybnMge1RvbmUuQXVkaW9Ob2RlfSB0aGlzXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuY2hhaW4gPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIGN1cnJlbnRVbml0ID0gdGhpcztcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICB2YXIgdG9Vbml0ID0gYXJndW1lbnRzW2ldO1xuXHQgICAgICAgICAgICBjdXJyZW50VW5pdC5jb25uZWN0KHRvVW5pdCk7XG5cdCAgICAgICAgICAgIGN1cnJlbnRVbml0ID0gdG9Vbml0O1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgY29ubmVjdCB0aGUgb3V0cHV0IG9mIHRoaXMgbm9kZSB0byB0aGUgcmVzdCBvZiB0aGUgbm9kZXMgaW4gcGFyYWxsZWwuXG5cdFx0ICogIEBwYXJhbSB7Li4uQXVkaW9QYXJhbXxUb25lfEF1ZGlvTm9kZX0gbm9kZXNcblx0XHQgKiAgQHJldHVybnMge1RvbmUuQXVkaW9Ob2RlfSB0aGlzXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZmFuID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgIHRoaXMuY29ubmVjdChhcmd1bWVudHNbaV0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICBpZiAod2luZG93LkF1ZGlvTm9kZSkge1xuXHQgICAgICAgIC8vZ2l2ZSBuYXRpdmUgbm9kZXMgY2hhaW4gYW5kIGZhbiBtZXRob2RzXG5cdCAgICAgICAgQXVkaW9Ob2RlLnByb3RvdHlwZS5jaGFpbiA9IFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5jaGFpbjtcblx0ICAgICAgICBBdWRpb05vZGUucHJvdG90eXBlLmZhbiA9IFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5mYW47XG5cdCAgICB9XG5cdCAgICAvKipcblx0XHQgKiBEaXNwb3NlIGFuZCBkaXNjb25uZWN0XG5cdFx0ICogQHJldHVybiB7VG9uZS5BdWRpb05vZGV9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGlmIChUb25lLmlzRGVmaW5lZCh0aGlzLmlucHV0KSkge1xuXHQgICAgICAgICAgICBpZiAodGhpcy5pbnB1dCBpbnN0YW5jZW9mIEF1ZGlvTm9kZSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5pbnB1dCA9IG51bGw7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChUb25lLmlzRGVmaW5lZCh0aGlzLm91dHB1dCkpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMub3V0cHV0IGluc3RhbmNlb2YgQXVkaW9Ob2RlKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLm91dHB1dC5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5vdXRwdXQgPSBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl9jb250ZXh0ID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5BdWRpb05vZGU7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgQmFzZSBjbGFzcyBmb3IgYWxsIFNpZ25hbHMuIFVzZWQgSW50ZXJuYWxseS5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmV9XG5cdFx0ICovXG5cdCAgICBUb25lLlNpZ25hbEJhc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlNpZ25hbEJhc2UsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBXaGVuIHNpZ25hbHMgY29ubmVjdCB0byBvdGhlciBzaWduYWxzIG9yIEF1ZGlvUGFyYW1zLFxuXHRcdCAqICB0aGV5IHRha2Ugb3ZlciB0aGUgb3V0cHV0IHZhbHVlIG9mIHRoYXQgc2lnbmFsIG9yIEF1ZGlvUGFyYW0uXG5cdFx0ICogIEZvciBhbGwgb3RoZXIgbm9kZXMsIHRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyBhIGRlZmF1bHQgPGNvZGU+Y29ubmVjdDwvY29kZT4uXG5cdFx0ICpcblx0XHQgKiAgQG92ZXJyaWRlXG5cdFx0ICogIEBwYXJhbSB7QXVkaW9QYXJhbXxBdWRpb05vZGV8VG9uZS5TaWduYWx8VG9uZX0gbm9kZVxuXHRcdCAqICBAcGFyYW0ge251bWJlcn0gW291dHB1dE51bWJlcj0wXSBUaGUgb3V0cHV0IG51bWJlciB0byBjb25uZWN0IGZyb20uXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSBbaW5wdXROdW1iZXI9MF0gVGhlIGlucHV0IG51bWJlciB0byBjb25uZWN0IHRvLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5TaWduYWxCYXNlfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlNpZ25hbEJhc2UucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbiAobm9kZSwgb3V0cHV0TnVtYmVyLCBpbnB1dE51bWJlcikge1xuXHQgICAgICAgIC8vemVybyBpdCBvdXQgc28gdGhhdCB0aGUgc2lnbmFsIGNhbiBoYXZlIGZ1bGwgY29udHJvbFxuXHQgICAgICAgIGlmIChUb25lLlNpZ25hbCAmJiBUb25lLlNpZ25hbCA9PT0gbm9kZS5jb25zdHJ1Y3RvciB8fCBUb25lLlBhcmFtICYmIFRvbmUuUGFyYW0gPT09IG5vZGUuY29uc3RydWN0b3IpIHtcblx0ICAgICAgICAgICAgLy9jYW5jZWwgY2hhbmdlc1xuXHQgICAgICAgICAgICBub2RlLl9wYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoMCk7XG5cdCAgICAgICAgICAgIC8vcmVzZXQgdGhlIHZhbHVlXG5cdCAgICAgICAgICAgIG5vZGUuX3BhcmFtLnZhbHVlID0gMDtcblx0ICAgICAgICAgICAgLy9tYXJrIHRoZSB2YWx1ZSBhcyBvdmVycmlkZGVuXG5cdCAgICAgICAgICAgIG5vZGUub3ZlcnJpZGRlbiA9IHRydWU7XG5cdCAgICAgICAgfSBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgQXVkaW9QYXJhbSkge1xuXHQgICAgICAgICAgICBub2RlLmNhbmNlbFNjaGVkdWxlZFZhbHVlcygwKTtcblx0ICAgICAgICAgICAgbm9kZS52YWx1ZSA9IDA7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5jb25uZWN0LmNhbGwodGhpcywgbm9kZSwgb3V0cHV0TnVtYmVyLCBpbnB1dE51bWJlcik7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuU2lnbmFsQmFzZTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgaWYgKFRvbmUuc3VwcG9ydGVkKSB7XG5cdCAgICAgICAgLy9maXhlcyBzYWZhcmkgb25seSBidWcgd2hpY2ggaXMgc3RpbGwgcHJlc2VudCBpbiAxMVxuXHQgICAgICAgIHZhciB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKTtcblx0ICAgICAgICB2YXIgaXNTYWZhcmkgPSB1YS5pbmNsdWRlcygnc2FmYXJpJykgJiYgIXVhLmluY2x1ZGVzKCdjaHJvbWUnKTtcblx0ICAgICAgICBpZiAoaXNTYWZhcmkpIHtcblx0ICAgICAgICAgICAgdmFyIFdhdmVTaGFwZXJOb2RlID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2ludGVybmFsTm9kZSA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IGNvbnRleHQuX25hdGl2ZV9jcmVhdGVXYXZlU2hhcGVyKCk7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9jdXJ2ZSA9IG51bGw7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBwcm9wIGluIHRoaXMuX2ludGVybmFsTm9kZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX2RlZmluZVByb3BlcnR5KHRoaXMuX2ludGVybmFsTm9kZSwgcHJvcCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXYXZlU2hhcGVyTm9kZS5wcm90b3R5cGUsICdjdXJ2ZScsIHtcblx0ICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9jdXJ2ZTtcblx0ICAgICAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChjdXJ2ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1cnZlID0gY3VydmU7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIGFycmF5ID0gbmV3IEZsb2F0MzJBcnJheShjdXJ2ZS5sZW5ndGggKyAxKTtcblx0ICAgICAgICAgICAgICAgICAgICBhcnJheS5zZXQoY3VydmUsIDEpO1xuXHQgICAgICAgICAgICAgICAgICAgIGFycmF5WzBdID0gY3VydmVbMF07XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5faW50ZXJuYWxOb2RlLmN1cnZlID0gYXJyYXk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICBXYXZlU2hhcGVyTm9kZS5wcm90b3R5cGUuX2RlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKGNvbnRleHQsIHByb3ApIHtcblx0ICAgICAgICAgICAgICAgIGlmIChUb25lLmlzVW5kZWYodGhpc1twcm9wXSkpIHtcblx0ICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgcHJvcCwge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dFtwcm9wXSA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0W3Byb3BdLmJpbmQoY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0W3Byb3BdO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWwpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHRbcHJvcF0gPSB2YWw7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgQXVkaW9Db250ZXh0LnByb3RvdHlwZS5fbmF0aXZlX2NyZWF0ZVdhdmVTaGFwZXIgPSBBdWRpb0NvbnRleHQucHJvdG90eXBlLmNyZWF0ZVdhdmVTaGFwZXI7XG5cdCAgICAgICAgICAgIEF1ZGlvQ29udGV4dC5wcm90b3R5cGUuY3JlYXRlV2F2ZVNoYXBlciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBuZXcgV2F2ZVNoYXBlck5vZGUodGhpcyk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgV3JhcHMgdGhlIG5hdGl2ZSBXZWIgQXVkaW8gQVBJXG5cdFx0ICogICAgICAgICBbV2F2ZVNoYXBlck5vZGVdKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jdGhlLXdhdmVzaGFwZXJub2RlLWludGVyZmFjZSkuXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuU2lnbmFsQmFzZX1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBwYXJhbSB7ZnVuY3Rpb258QXJyYXl8TnVtYmVyfSBtYXBwaW5nIFRoZSBmdW5jdGlvbiB1c2VkIHRvIGRlZmluZSB0aGUgdmFsdWVzLlxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhlIG1hcHBpbmcgZnVuY3Rpb24gc2hvdWxkIHRha2UgdHdvIGFyZ3VtZW50czpcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmaXJzdCBpcyB0aGUgdmFsdWUgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb25cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZCB0aGUgc2Vjb25kIGlzIHRoZSBhcnJheSBwb3NpdGlvbi5cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIHRoZSBhcmd1bWVudCBpcyBhbiBhcnJheSwgdGhhdCBhcnJheSB3aWxsIGJlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXQgYXMgdGhlIHdhdmUgc2hhcGluZyBmdW5jdGlvbi4gVGhlIGlucHV0XG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduYWwgaXMgYW4gQXVkaW9SYW5nZSBbLTEsIDFdIHZhbHVlIGFuZCB0aGUgb3V0cHV0XG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduYWwgY2FuIHRha2Ugb24gYW55IG51bWVyaWNhbCB2YWx1ZXMuXG5cdFx0ICpcblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ9IFtidWZmZXJMZW49MTAyNF0gVGhlIGxlbmd0aCBvZiB0aGUgV2F2ZVNoYXBlck5vZGUgYnVmZmVyLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciB0aW1lc1R3byA9IG5ldyBUb25lLldhdmVTaGFwZXIoZnVuY3Rpb24odmFsKXtcblx0XHQgKiBcdHJldHVybiB2YWwgKiAyO1xuXHRcdCAqIH0sIDIwNDgpO1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vYSB3YXZlc2hhcGVyIGNhbiBhbHNvIGJlIGNvbnN0cnVjdGVkIHdpdGggYW4gYXJyYXkgb2YgdmFsdWVzXG5cdFx0ICogdmFyIGludmVydCA9IG5ldyBUb25lLldhdmVTaGFwZXIoWzEsIC0xXSk7XG5cdFx0ICovXG5cdCAgICBUb25lLldhdmVTaGFwZXIgPSBmdW5jdGlvbiAobWFwcGluZywgYnVmZmVyTGVuKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWxCYXNlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIHdhdmVzaGFwZXJcblx0XHRcdCAqICBAdHlwZSB7V2F2ZVNoYXBlck5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3NoYXBlciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuY29udGV4dC5jcmVhdGVXYXZlU2hhcGVyKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIHdhdmVzaGFwZXJzIGN1cnZlXG5cdFx0XHQgKiAgQHR5cGUge0Zsb2F0MzJBcnJheX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fY3VydmUgPSBudWxsO1xuXHQgICAgICAgIGlmIChBcnJheS5pc0FycmF5KG1hcHBpbmcpKSB7XG5cdCAgICAgICAgICAgIHRoaXMuY3VydmUgPSBtYXBwaW5nO1xuXHQgICAgICAgIH0gZWxzZSBpZiAoaXNGaW5pdGUobWFwcGluZykgfHwgVG9uZS5pc1VuZGVmKG1hcHBpbmcpKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2N1cnZlID0gbmV3IEZsb2F0MzJBcnJheShUb25lLmRlZmF1bHRBcmcobWFwcGluZywgMTAyNCkpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAoVG9uZS5pc0Z1bmN0aW9uKG1hcHBpbmcpKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2N1cnZlID0gbmV3IEZsb2F0MzJBcnJheShUb25lLmRlZmF1bHRBcmcoYnVmZmVyTGVuLCAxMDI0KSk7XG5cdCAgICAgICAgICAgIHRoaXMuc2V0TWFwKG1hcHBpbmcpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLldhdmVTaGFwZXIsIFRvbmUuU2lnbmFsQmFzZSk7XG5cdCAgICAvKipcblx0XHQgKiAgVXNlcyBhIG1hcHBpbmcgZnVuY3Rpb24gdG8gc2V0IHRoZSB2YWx1ZSBvZiB0aGUgY3VydmUuXG5cdFx0ICogIEBwYXJhbSB7ZnVuY3Rpb259IG1hcHBpbmcgVGhlIGZ1bmN0aW9uIHVzZWQgdG8gZGVmaW5lIHRoZSB2YWx1ZXMuXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhlIG1hcHBpbmcgZnVuY3Rpb24gdGFrZSB0d28gYXJndW1lbnRzOlxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmaXJzdCBpcyB0aGUgdmFsdWUgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb25cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaCBnb2VzIGZyb20gLTEgdG8gMSBvdmVyIHRoZSBudW1iZXIgb2YgZWxlbWVudHNcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbiB0aGUgY3VydmUgYXJyYXkuIFRoZSBzZWNvbmQgYXJndW1lbnQgaXMgdGhlIGFycmF5IHBvc2l0aW9uLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5XYXZlU2hhcGVyfSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9tYXAgdGhlIGlucHV0IHNpZ25hbCBmcm9tIFstMSwgMV0gdG8gWzAsIDEwXVxuXHRcdCAqIHNoYXBlci5zZXRNYXAoZnVuY3Rpb24odmFsLCBpbmRleCl7XG5cdFx0ICogXHRyZXR1cm4gKHZhbCArIDEpICogNTtcblx0XHQgKiB9KVxuXHRcdCAqL1xuXHQgICAgVG9uZS5XYXZlU2hhcGVyLnByb3RvdHlwZS5zZXRNYXAgPSBmdW5jdGlvbiAobWFwcGluZykge1xuXHQgICAgICAgIHZhciBhcnJheSA9IG5ldyBBcnJheSh0aGlzLl9jdXJ2ZS5sZW5ndGgpO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0aGlzLl9jdXJ2ZS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuXHQgICAgICAgICAgICB2YXIgbm9ybWFsaXplZCA9IGkgLyAobGVuIC0gMSkgKiAyIC0gMTtcblx0ICAgICAgICAgICAgYXJyYXlbaV0gPSBtYXBwaW5nKG5vcm1hbGl6ZWQsIGkpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLmN1cnZlID0gYXJyYXk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIGFycmF5IHRvIHNldCBhcyB0aGUgd2F2ZXNoYXBlciBjdXJ2ZS4gRm9yIGxpbmVhciBjdXJ2ZXNcblx0XHQgKiBhcnJheSBsZW5ndGggZG9lcyBub3QgbWFrZSBtdWNoIGRpZmZlcmVuY2UsIGJ1dCBmb3IgY29tcGxleCBjdXJ2ZXNcblx0XHQgKiBsb25nZXIgYXJyYXlzIHdpbGwgcHJvdmlkZSBzbW9vdGhlciBpbnRlcnBvbGF0aW9uLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLldhdmVTaGFwZXIjXG5cdFx0ICogQHR5cGUge0FycmF5fVxuXHRcdCAqIEBuYW1lIGN1cnZlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5XYXZlU2hhcGVyLnByb3RvdHlwZSwgJ2N1cnZlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fc2hhcGVyLmN1cnZlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobWFwcGluZykge1xuXHQgICAgICAgICAgICB0aGlzLl9jdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkobWFwcGluZyk7XG5cdCAgICAgICAgICAgIHRoaXMuX3NoYXBlci5jdXJ2ZSA9IHRoaXMuX2N1cnZlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogU3BlY2lmaWVzIHdoYXQgdHlwZSBvZiBvdmVyc2FtcGxpbmcgKGlmIGFueSkgc2hvdWxkIGJlIHVzZWQgd2hlblxuXHRcdCAqIGFwcGx5aW5nIHRoZSBzaGFwaW5nIGN1cnZlLiBDYW4gZWl0aGVyIGJlIFwibm9uZVwiLCBcIjJ4XCIgb3IgXCI0eFwiLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLldhdmVTaGFwZXIjXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAbmFtZSBvdmVyc2FtcGxlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5XYXZlU2hhcGVyLnByb3RvdHlwZSwgJ292ZXJzYW1wbGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKG92ZXJzYW1wbGluZykge1xuXHQgICAgICAgICAgICBpZiAoW1xuXHQgICAgICAgICAgICAgICAgICAgICdub25lJyxcblx0ICAgICAgICAgICAgICAgICAgICAnMngnLFxuXHQgICAgICAgICAgICAgICAgICAgICc0eCdcblx0ICAgICAgICAgICAgICAgIF0uaW5jbHVkZXMob3ZlcnNhbXBsaW5nKSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGUgPSBvdmVyc2FtcGxpbmc7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVG9uZS5XYXZlU2hhcGVyOiBvdmVyc2FtcGxpbmcgbXVzdCBiZSBlaXRoZXIgXFwnbm9uZVxcJywgXFwnMnhcXCcsIG9yIFxcJzR4XFwnJyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuV2F2ZVNoYXBlcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5XYXZlU2hhcGVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuU2lnbmFsQmFzZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3NoYXBlci5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgdGhpcy5fc2hhcGVyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9jdXJ2ZSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuV2F2ZVNoYXBlcjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBUb25lLlRpbWVCYXNlIGlzIGEgZmxleGlibGUgZW5jb2Rpbmcgb2YgdGltZVxuXHRcdCAqICAgICAgICAgd2hpY2ggY2FuIGJlIGV2YWx1YXRlZCB0byBhbmQgZnJvbSBhIHN0cmluZy5cblx0XHQgKiAgQGV4dGVuZHMge1RvbmV9XG5cdFx0ICogIEBwYXJhbSAge1RpbWV9ICB2YWwgICAgVGhlIHRpbWUgdmFsdWUgYXMgYSBudW1iZXIgb3Igc3RyaW5nXG5cdFx0ICogIEBwYXJhbSAge1N0cmluZz19ICB1bml0cyAgVW5pdCB2YWx1ZXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBUb25lLlRpbWVCYXNlKDQsIFwiblwiKVxuXHRcdCAqIFRvbmUuVGltZUJhc2UoMiwgXCJ0XCIpXG5cdFx0ICogVG9uZS5UaW1lQmFzZShcIjJ0XCIpXG5cdFx0ICogVG9uZS5UaW1lQmFzZShcIjJ0XCIpICsgVG9uZS5UaW1lQmFzZShcIjRuXCIpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lQmFzZSA9IGZ1bmN0aW9uICh2YWwsIHVuaXRzKSB7XG5cdCAgICAgICAgLy9hbGxvd3MgaXQgdG8gYmUgY29uc3RydWN0ZWQgd2l0aCBvciB3aXRob3V0ICduZXcnXG5cdCAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBUb25lLlRpbWVCYXNlKSB7XG5cdCAgICAgICAgICAgIC8qKlxuXHRcdFx0XHQgKiAgVGhlIHZhbHVlXG5cdFx0XHRcdCAqICBAdHlwZSAge051bWJlcnxTdHJpbmd8VG9uZS5UaW1lQmFzZX1cblx0XHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHRcdCAqL1xuXHQgICAgICAgICAgICB0aGlzLl92YWwgPSB2YWw7XG5cdCAgICAgICAgICAgIC8qKlxuXHRcdFx0XHQgKiBUaGUgdW5pdHNcblx0XHRcdFx0ICogQHR5cGUge1N0cmluZz99XG5cdFx0XHRcdCAqIEBwcml2YXRlXG5cdFx0XHRcdCAqL1xuXHQgICAgICAgICAgICB0aGlzLl91bml0cyA9IHVuaXRzO1xuXHQgICAgICAgICAgICAvL3Rlc3QgaWYgdGhlIHZhbHVlIGlzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgbnVtYmVyXG5cdCAgICAgICAgICAgIGlmIChUb25lLmlzVW5kZWYodGhpcy5fdW5pdHMpICYmIFRvbmUuaXNTdHJpbmcodGhpcy5fdmFsKSAmJiAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdCAgICAgICAgICAgICAgICBwYXJzZUZsb2F0KHRoaXMuX3ZhbCkgPT0gdGhpcy5fdmFsICYmIHRoaXMuX3ZhbC5jaGFyQXQoMCkgIT09ICcrJykge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fdmFsID0gcGFyc2VGbG9hdCh0aGlzLl92YWwpO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fdW5pdHMgPSB0aGlzLl9kZWZhdWx0VW5pdHM7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsICYmIHZhbC5jb25zdHJ1Y3RvciA9PT0gdGhpcy5jb25zdHJ1Y3Rvcikge1xuXHQgICAgICAgICAgICAgICAgLy9pZiB0aGV5J3JlIHRoZSBzYW1lIHR5cGUsIGp1c3QgY29weSB2YWx1ZXMgb3ZlclxuXHQgICAgICAgICAgICAgICAgdGhpcy5fdmFsID0gdmFsLl92YWw7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl91bml0cyA9IHZhbC5fdW5pdHM7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsIGluc3RhbmNlb2YgVG9uZS5UaW1lQmFzZSkge1xuXHQgICAgICAgICAgICAgICAgc3dpdGNoICh0aGlzLl9kZWZhdWx0VW5pdHMpIHtcblx0ICAgICAgICAgICAgICAgIGNhc2UgJ3MnOlxuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbCA9IHZhbC50b1NlY29uZHMoKTtcblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIGNhc2UgJ2knOlxuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbCA9IHZhbC50b1RpY2tzKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgICAgICAgICBjYXNlICdoeic6XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsID0gdmFsLnRvRnJlcXVlbmN5KCk7XG5cdCAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgICAgICAgICBjYXNlICdtaWRpJzpcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWwgPSB2YWwudG9NaWRpKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgICAgICAgICBkZWZhdWx0OlxuXHQgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5yZWNvZ25pemVkIGRlZmF1bHQgdW5pdHMgJyArIHRoaXMuX2RlZmF1bHRVbml0cyk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICByZXR1cm4gbmV3IFRvbmUuVGltZUJhc2UodmFsLCB1bml0cyk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuVGltZUJhc2UpO1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvL1x0QUJTVFJBQ1QgU1lOVEFYIFRSRUUgUEFSU0VSXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBBbGwgdGhlIHByaW1hcnkgZXhwcmVzc2lvbnMuXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICogIEB0eXBlICB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lQmFzZS5wcm90b3R5cGUuX2V4cHJlc3Npb25zID0ge1xuXHQgICAgICAgICduJzoge1xuXHQgICAgICAgICAgICByZWdleHA6IC9eKFxcZCspbihcXC4/KSQvaSxcblx0ICAgICAgICAgICAgbWV0aG9kOiBmdW5jdGlvbiAodmFsdWUsIGRvdCkge1xuXHQgICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUludCh2YWx1ZSk7XG5cdCAgICAgICAgICAgICAgICB2YXIgc2NhbGFyID0gZG90ID09PSAnLicgPyAxLjUgOiAxO1xuXHQgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSAxKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyh0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkpICogc2NhbGFyO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYmVhdHNUb1VuaXRzKDQgLyB2YWx1ZSkgKiBzY2FsYXI7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXHQgICAgICAgICd0Jzoge1xuXHQgICAgICAgICAgICByZWdleHA6IC9eKFxcZCspdCQvaSxcblx0ICAgICAgICAgICAgbWV0aG9kOiBmdW5jdGlvbiAodmFsdWUpIHtcblx0ICAgICAgICAgICAgICAgIHZhbHVlID0gcGFyc2VJbnQodmFsdWUpO1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyg4IC8gKHBhcnNlSW50KHZhbHVlKSAqIDMpKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgJ20nOiB7XG5cdCAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyltJC9pLFxuXHQgICAgICAgICAgICBtZXRob2Q6IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyhwYXJzZUludCh2YWx1ZSkgKiB0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICAnaSc6IHtcblx0ICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKWkkL2ksXG5cdCAgICAgICAgICAgIG1ldGhvZDogZnVuY3Rpb24gKHZhbHVlKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdGlja3NUb1VuaXRzKHBhcnNlSW50KHZhbHVlKSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXHQgICAgICAgICdoeic6IHtcblx0ICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KWh6JC9pLFxuXHQgICAgICAgICAgICBtZXRob2Q6IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeVRvVW5pdHMocGFyc2VGbG9hdCh2YWx1ZSkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICAndHInOiB7XG5cdCAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyg/OlxcLlxcZCspPyk6KFxcZCsoPzpcXC5cXGQrKT8pOj8oXFxkKyg/OlxcLlxcZCspPyk/JC8sXG5cdCAgICAgICAgICAgIG1ldGhvZDogZnVuY3Rpb24gKG0sIHEsIHMpIHtcblx0ICAgICAgICAgICAgICAgIHZhciB0b3RhbCA9IDA7XG5cdCAgICAgICAgICAgICAgICBpZiAobSAmJiBtICE9PSAnMCcpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0aGlzLl9iZWF0c1RvVW5pdHModGhpcy5fZ2V0VGltZVNpZ25hdHVyZSgpICogcGFyc2VGbG9hdChtKSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBpZiAocSAmJiBxICE9PSAnMCcpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VGbG9hdChxKSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBpZiAocyAmJiBzICE9PSAnMCcpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VGbG9hdChzKSAvIDQpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRvdGFsO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICAncyc6IHtcblx0ICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KXMkLyxcblx0ICAgICAgICAgICAgbWV0aG9kOiBmdW5jdGlvbiAodmFsdWUpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9zZWNvbmRzVG9Vbml0cyhwYXJzZUZsb2F0KHZhbHVlKSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXHQgICAgICAgICdzYW1wbGVzJzoge1xuXHQgICAgICAgICAgICByZWdleHA6IC9eKFxcZCspc2FtcGxlcyQvLFxuXHQgICAgICAgICAgICBtZXRob2Q6IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KHZhbHVlKSAvIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICAnZGVmYXVsdCc6IHtcblx0ICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KSQvLFxuXHQgICAgICAgICAgICBtZXRob2Q6IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V4cHJlc3Npb25zW3RoaXMuX2RlZmF1bHRVbml0c10ubWV0aG9kLmNhbGwodGhpcywgdmFsdWUpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgZGVmYXVsdCB1bml0cyBpZiBub25lIGFyZSBnaXZlbi5cblx0XHQgKiAgQHR5cGUge1N0cmluZ31cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuVGltZUJhc2UucHJvdG90eXBlLl9kZWZhdWx0VW5pdHMgPSAncyc7XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRUUkFOU1BPUlQgRkFMTEJBQ0tTXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqIFJldHVybiB0aGUgYnBtLCBvciAxMjAgaWYgVHJhbnNwb3J0IGlzIG5vdCBhdmFpbGFibGVcblx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVCYXNlLnByb3RvdHlwZS5fZ2V0QnBtID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGlmIChUb25lLlRyYW5zcG9ydCkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5UcmFuc3BvcnQuYnBtLnZhbHVlO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHJldHVybiAxMjA7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFJldHVybiB0aGUgdGltZVNpZ25hdHVyZSBvciA0IGlmIFRyYW5zcG9ydCBpcyBub3QgYXZhaWxhYmxlXG5cdFx0ICogQHR5cGUge051bWJlcn1cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lQmFzZS5wcm90b3R5cGUuX2dldFRpbWVTaWduYXR1cmUgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgaWYgKFRvbmUuVHJhbnNwb3J0KSB7XG5cdCAgICAgICAgICAgIHJldHVybiBUb25lLlRyYW5zcG9ydC50aW1lU2lnbmF0dXJlO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHJldHVybiA0O1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBSZXR1cm4gdGhlIFBQUSBvciAxOTIgaWYgVHJhbnNwb3J0IGlzIG5vdCBhdmFpbGFibGVcblx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVCYXNlLnByb3RvdHlwZS5fZ2V0UFBRID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGlmIChUb25lLlRyYW5zcG9ydCkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5UcmFuc3BvcnQuUFBRO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHJldHVybiAxOTI7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFJldHVybiB0aGUgY3VycmVudCB0aW1lIGluIHdoaWNoZXZlciBjb250ZXh0IGlzIHJlbGV2YW50XG5cdFx0ICogQHR5cGUge051bWJlcn1cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lQmFzZS5wcm90b3R5cGUuX25vdyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5ub3coKTtcblx0ICAgIH07XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRVTklUIENPTlZFUlNJT05TXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIGZyZXF1ZW5jeSBpbiB0aGUgY3VycmVudCB1bml0c1xuXHRcdCAqICBAcGFyYW0ge0ZyZXF1ZW5jeX0gZnJlcVxuXHRcdCAqICBAcmV0dXJuICB7TnVtYmVyfVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lQmFzZS5wcm90b3R5cGUuX2ZyZXF1ZW5jeVRvVW5pdHMgPSBmdW5jdGlvbiAoZnJlcSkge1xuXHQgICAgICAgIHJldHVybiAxIC8gZnJlcTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYmVhdHMgaW4gdGhlIGN1cnJlbnQgdW5pdHNcblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ9IGJlYXRzXG5cdFx0ICogIEByZXR1cm4gIHtOdW1iZXJ9XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVCYXNlLnByb3RvdHlwZS5fYmVhdHNUb1VuaXRzID0gZnVuY3Rpb24gKGJlYXRzKSB7XG5cdCAgICAgICAgcmV0dXJuIDYwIC8gdGhpcy5fZ2V0QnBtKCkgKiBiZWF0cztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzZWNvbmQgaW4gdGhlIGN1cnJlbnQgdW5pdHNcblx0XHQgKiAgQHBhcmFtIHtTZWNvbmRzfSBzZWNvbmRzXG5cdFx0ICogIEByZXR1cm4gIHtOdW1iZXJ9XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVCYXNlLnByb3RvdHlwZS5fc2Vjb25kc1RvVW5pdHMgPSBmdW5jdGlvbiAoc2Vjb25kcykge1xuXHQgICAgICAgIHJldHVybiBzZWNvbmRzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHRpY2sgaW4gdGhlIGN1cnJlbnQgdGltZSB1bml0c1xuXHRcdCAqICBAcGFyYW0ge1RpY2tzfSB0aWNrc1xuXHRcdCAqICBAcmV0dXJuICB7TnVtYmVyfVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lQmFzZS5wcm90b3R5cGUuX3RpY2tzVG9Vbml0cyA9IGZ1bmN0aW9uICh0aWNrcykge1xuXHQgICAgICAgIHJldHVybiB0aWNrcyAqICh0aGlzLl9iZWF0c1RvVW5pdHMoMSkgLyB0aGlzLl9nZXRQUFEoKSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogV2l0aCBubyBhcmd1bWVudHMsIHJldHVybiAnbm93J1xuXHRcdCAqICBAcmV0dXJuICB7TnVtYmVyfVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lQmFzZS5wcm90b3R5cGUuX25vQXJnID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9ub3coKTtcblx0ICAgIH07XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRFWFBSRVNTSU9OU1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvKipcblx0XHQgKiAgRXZhbHVhdGUgdGhlIHRpbWUgdmFsdWUuIFJldHVybnMgdGhlIHRpbWVcblx0XHQgKiAgaW4gc2Vjb25kcy5cblx0XHQgKiAgQHJldHVybiAge1NlY29uZHN9XG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVCYXNlLnByb3RvdHlwZS52YWx1ZU9mID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGlmIChUb25lLmlzVW5kZWYodGhpcy5fdmFsKSkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fbm9BcmcoKTtcblx0ICAgICAgICB9IGVsc2UgaWYgKFRvbmUuaXNTdHJpbmcodGhpcy5fdmFsKSAmJiBUb25lLmlzVW5kZWYodGhpcy5fdW5pdHMpKSB7XG5cdCAgICAgICAgICAgIGZvciAodmFyIHVuaXRzIGluIHRoaXMuX2V4cHJlc3Npb25zKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAodGhpcy5fZXhwcmVzc2lvbnNbdW5pdHNdLnJlZ2V4cC50ZXN0KHRoaXMuX3ZhbC50cmltKCkpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fdW5pdHMgPSB1bml0cztcblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAoVG9uZS5pc0RlZmluZWQodGhpcy5fdW5pdHMpKSB7XG5cdCAgICAgICAgICAgIHZhciBleHByID0gdGhpcy5fZXhwcmVzc2lvbnNbdGhpcy5fdW5pdHNdO1xuXHQgICAgICAgICAgICB2YXIgbWF0Y2hpbmcgPSB0aGlzLl92YWwudG9TdHJpbmcoKS50cmltKCkubWF0Y2goZXhwci5yZWdleHApO1xuXHQgICAgICAgICAgICBpZiAobWF0Y2hpbmcpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBleHByLm1ldGhvZC5hcHBseSh0aGlzLCBtYXRjaGluZy5zbGljZSgxKSk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gZXhwci5tZXRob2QuY2FsbCh0aGlzLCBwYXJzZUZsb2F0KHRoaXMuX3ZhbCkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbDtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybiB0aGUgdmFsdWUgaW4gc2Vjb25kc1xuXHRcdCAqICBAcmV0dXJuIHtTZWNvbmRzfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lQmFzZS5wcm90b3R5cGUudG9TZWNvbmRzID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJuIHRoZSB2YWx1ZSBpbiBoZXJ0elxuXHRcdCAqICBAcmV0dXJuIHtGcmVxdWVuY3l9XG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVCYXNlLnByb3RvdHlwZS50b0ZyZXF1ZW5jeSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gMSAvIHRoaXMudG9TZWNvbmRzKCk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybiB0aGUgdGltZSBpbiBzYW1wbGVzXG5cdFx0ICogIEByZXR1cm4gIHtTYW1wbGVzfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lQmFzZS5wcm90b3R5cGUudG9TYW1wbGVzID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLnRvU2Vjb25kcygpICogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybiB0aGUgdGltZSBpbiBtaWxsaXNlY29uZHMuXG5cdFx0ICogIEByZXR1cm4gIHtNaWxsaXNlY29uZHN9XG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVCYXNlLnByb3RvdHlwZS50b01pbGxpc2Vjb25kcyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy50b1NlY29uZHMoKSAqIDEwMDA7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwXG5cdFx0ICogIEByZXR1cm4ge1RvbmUuVGltZUJhc2V9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVGltZUJhc2UucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fdmFsID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl91bml0cyA9IG51bGw7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuVGltZUJhc2U7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5GcmVxdWVuY3kgaXMgYSBwcmltaXRpdmUgdHlwZSBmb3IgZW5jb2RpbmcgRnJlcXVlbmN5IHZhbHVlcy5cblx0XHQgKiAgICAgICAgIEV2ZW50dWFsbHkgYWxsIHRpbWUgdmFsdWVzIGFyZSBldmFsdWF0ZWQgdG8gaGVydHpcblx0XHQgKiAgICAgICAgIHVzaW5nIHRoZSBgZXZhbGAgbWV0aG9kLlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuVGltZUJhc2V9XG5cdFx0ICogIEBwYXJhbSAge1N0cmluZ3xOdW1iZXJ9ICB2YWwgICAgVGhlIHRpbWUgdmFsdWUuXG5cdFx0ICogIEBwYXJhbSAge1N0cmluZz19ICB1bml0cyAgVGhlIHVuaXRzIG9mIHRoZSB2YWx1ZS5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBUb25lLkZyZXF1ZW5jeShcIkMzXCIpIC8vIDI2MVxuXHRcdCAqIFRvbmUuRnJlcXVlbmN5KDM4LCBcIm1pZGlcIikgLy9cblx0XHQgKiBUb25lLkZyZXF1ZW5jeShcIkMzXCIpLnRyYW5zcG9zZSg0KTtcblx0XHQgKi9cblx0ICAgIFRvbmUuRnJlcXVlbmN5ID0gZnVuY3Rpb24gKHZhbCwgdW5pdHMpIHtcblx0ICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFRvbmUuRnJlcXVlbmN5KSB7XG5cdCAgICAgICAgICAgIFRvbmUuVGltZUJhc2UuY2FsbCh0aGlzLCB2YWwsIHVuaXRzKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICByZXR1cm4gbmV3IFRvbmUuRnJlcXVlbmN5KHZhbCwgdW5pdHMpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkZyZXF1ZW5jeSwgVG9uZS5UaW1lQmFzZSk7XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRBVUdNRU5UIEJBU0UgRVhQUkVTU0lPTlNcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgVG9uZS5GcmVxdWVuY3kucHJvdG90eXBlLl9leHByZXNzaW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIFRvbmUuVGltZUJhc2UucHJvdG90eXBlLl9leHByZXNzaW9ucywge1xuXHQgICAgICAgICdtaWRpJzoge1xuXHQgICAgICAgICAgICByZWdleHA6IC9eKFxcZCsoPzpcXC5cXGQrKT9taWRpKS8sXG5cdCAgICAgICAgICAgIG1ldGhvZDogZnVuY3Rpb24gKHZhbHVlKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAodGhpcy5fZGVmYXVsdFVuaXRzID09PSAnbWlkaScpIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBUb25lLkZyZXF1ZW5jeS5tdG9mKHZhbHVlKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgJ25vdGUnOiB7XG5cdCAgICAgICAgICAgIHJlZ2V4cDogL14oW2EtZ117MX0oPzpifCN8eHxiYik/KSgtP1swLTldKykvaSxcblx0ICAgICAgICAgICAgbWV0aG9kOiBmdW5jdGlvbiAocGl0Y2gsIG9jdGF2ZSkge1xuXHQgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gbm90ZVRvU2NhbGVJbmRleFtwaXRjaC50b0xvd2VyQ2FzZSgpXTtcblx0ICAgICAgICAgICAgICAgIHZhciBub3RlTnVtYmVyID0gaW5kZXggKyAocGFyc2VJbnQob2N0YXZlKSArIDEpICogMTI7XG5cdCAgICAgICAgICAgICAgICBpZiAodGhpcy5fZGVmYXVsdFVuaXRzID09PSAnbWlkaScpIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm90ZU51bWJlcjtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRvbmUuRnJlcXVlbmN5Lm10b2Yobm90ZU51bWJlcik7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXHQgICAgICAgICd0cic6IHtcblx0ICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KTooXFxkKyg/OlxcLlxcZCspPyk6PyhcXGQrKD86XFwuXFxkKyk/KT8vLFxuXHQgICAgICAgICAgICBtZXRob2Q6IGZ1bmN0aW9uIChtLCBxLCBzKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgdG90YWwgPSAxO1xuXHQgICAgICAgICAgICAgICAgaWYgKG0gJiYgbSAhPT0gJzAnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdG90YWwgKj0gdGhpcy5fYmVhdHNUb1VuaXRzKHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKSAqIHBhcnNlRmxvYXQobSkpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgaWYgKHEgJiYgcSAhPT0gJzAnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdG90YWwgKj0gdGhpcy5fYmVhdHNUb1VuaXRzKHBhcnNlRmxvYXQocSkpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgaWYgKHMgJiYgcyAhPT0gJzAnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdG90YWwgKj0gdGhpcy5fYmVhdHNUb1VuaXRzKHBhcnNlRmxvYXQocykgLyA0KTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHJldHVybiB0b3RhbDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvL1x0RVhQUkVTU0lPTlNcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLyoqXG5cdFx0ICogIFRyYW5zcG9zZXMgdGhlIGZyZXF1ZW5jeSBieSB0aGUgZ2l2ZW4gbnVtYmVyIG9mIHNlbWl0b25lcy5cblx0XHQgKiAgQHBhcmFtICB7SW50ZXJ2YWx9ICBpbnRlcnZhbFxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5GcmVxdWVuY3l9IEEgbmV3IHRyYW5zcG9zZWQgZnJlcXVlbmN5XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogVG9uZS5GcmVxdWVuY3koXCJBNFwiKS50cmFuc3Bvc2UoMyk7IC8vXCJDNVwiXG5cdFx0ICovXG5cdCAgICBUb25lLkZyZXF1ZW5jeS5wcm90b3R5cGUudHJhbnNwb3NlID0gZnVuY3Rpb24gKGludGVydmFsKSB7XG5cdCAgICAgICAgcmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMudmFsdWVPZigpICogVG9uZS5pbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oaW50ZXJ2YWwpKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGFrZXMgYW4gYXJyYXkgb2Ygc2VtaXRvbmUgaW50ZXJ2YWxzIGFuZCByZXR1cm5zXG5cdFx0ICogIGFuIGFycmF5IG9mIGZyZXF1ZW5jaWVzIHRyYW5zcG9zZWQgYnkgdGhvc2UgaW50ZXJ2YWxzLlxuXHRcdCAqICBAcGFyYW0gIHtBcnJheX0gIGludGVydmFsc1xuXHRcdCAqICBAcmV0dXJuICB7QXJyYXk8VG9uZS5GcmVxdWVuY3k+fSBSZXR1cm5zIGFuIGFycmF5IG9mIEZyZXF1ZW5jaWVzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogVG9uZS5GcmVxdWVuY3koXCJBNFwiKS5oYXJtb25pemUoWzAsIDMsIDddKTsgLy9bXCJBNFwiLCBcIkM1XCIsIFwiRTVcIl1cblx0XHQgKi9cblx0ICAgIFRvbmUuRnJlcXVlbmN5LnByb3RvdHlwZS5oYXJtb25pemUgPSBmdW5jdGlvbiAoaW50ZXJ2YWxzKSB7XG5cdCAgICAgICAgcmV0dXJuIGludGVydmFscy5tYXAoZnVuY3Rpb24gKGludGVydmFsKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zcG9zZShpbnRlcnZhbCk7XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgIH07XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRVTklUIENPTlZFUlNJT05TXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmcmVxdWVuY3kgYXMgYSBNSURJIG5vdGVcblx0XHQgKiAgQHJldHVybiAge01JREl9XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogVG9uZS5GcmVxdWVuY3koXCJDNFwiKS50b01pZGkoKTsgLy82MFxuXHRcdCAqL1xuXHQgICAgVG9uZS5GcmVxdWVuY3kucHJvdG90eXBlLnRvTWlkaSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gVG9uZS5GcmVxdWVuY3kuZnRvbSh0aGlzLnZhbHVlT2YoKSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZyZXF1ZW5jeSBpbiBTY2llbnRpZmljIFBpdGNoIE5vdGF0aW9uXG5cdFx0ICogIEByZXR1cm4gIHtOb3RlfVxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIFRvbmUuRnJlcXVlbmN5KDY5LCBcIm1pZGlcIikudG9Ob3RlKCk7IC8vXCJBNFwiXG5cdFx0ICovXG5cdCAgICBUb25lLkZyZXF1ZW5jeS5wcm90b3R5cGUudG9Ob3RlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBmcmVxID0gdGhpcy50b0ZyZXF1ZW5jeSgpO1xuXHQgICAgICAgIHZhciBsb2cgPSBNYXRoLmxvZzIoZnJlcSAvIFRvbmUuRnJlcXVlbmN5LkE0KTtcblx0ICAgICAgICB2YXIgbm90ZU51bWJlciA9IE1hdGgucm91bmQoMTIgKiBsb2cpICsgNTc7XG5cdCAgICAgICAgdmFyIG9jdGF2ZSA9IE1hdGguZmxvb3Iobm90ZU51bWJlciAvIDEyKTtcblx0ICAgICAgICBpZiAob2N0YXZlIDwgMCkge1xuXHQgICAgICAgICAgICBub3RlTnVtYmVyICs9IC0xMiAqIG9jdGF2ZTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdmFyIG5vdGVOYW1lID0gc2NhbGVJbmRleFRvTm90ZVtub3RlTnVtYmVyICUgMTJdO1xuXHQgICAgICAgIHJldHVybiBub3RlTmFtZSArIG9jdGF2ZS50b1N0cmluZygpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm4gdGhlIGR1cmF0aW9uIG9mIG9uZSBjeWNsZSBpbiBzZWNvbmRzLlxuXHRcdCAqICBAcmV0dXJuICB7U2Vjb25kc31cblx0XHQgKi9cblx0ICAgIFRvbmUuRnJlcXVlbmN5LnByb3RvdHlwZS50b1NlY29uZHMgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIDEgLyBUb25lLlRpbWVCYXNlLnByb3RvdHlwZS50b1NlY29uZHMuY2FsbCh0aGlzKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJuIHRoZSB2YWx1ZSBpbiBIZXJ0elxuXHRcdCAqICBAcmV0dXJuICB7RnJlcXVlbmN5fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5GcmVxdWVuY3kucHJvdG90eXBlLnRvRnJlcXVlbmN5ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiBUb25lLlRpbWVCYXNlLnByb3RvdHlwZS50b0ZyZXF1ZW5jeS5jYWxsKHRoaXMpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm4gdGhlIGR1cmF0aW9uIG9mIG9uZSBjeWNsZSBpbiB0aWNrc1xuXHRcdCAqICBAcmV0dXJuICB7VGlja3N9XG5cdFx0ICovXG5cdCAgICBUb25lLkZyZXF1ZW5jeS5wcm90b3R5cGUudG9UaWNrcyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgcXVhcnRlclRpbWUgPSB0aGlzLl9iZWF0c1RvVW5pdHMoMSk7XG5cdCAgICAgICAgdmFyIHF1YXJ0ZXJzID0gdGhpcy52YWx1ZU9mKCkgLyBxdWFydGVyVGltZTtcblx0ICAgICAgICByZXR1cm4gTWF0aC5mbG9vcihxdWFydGVycyAqIFRvbmUuVHJhbnNwb3J0LlBQUSk7XG5cdCAgICB9O1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvL1x0VU5JVCBDT05WRVJTSU9OUyBIRUxQRVJTXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBXaXRoIG5vIGFyZ3VtZW50cywgcmV0dXJuIDBcblx0XHQgKiAgQHJldHVybiAge051bWJlcn1cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuRnJlcXVlbmN5LnByb3RvdHlwZS5fbm9BcmcgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIDA7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgZnJlcXVlbmN5IGluIHRoZSBjdXJyZW50IHVuaXRzXG5cdFx0ICogIEBwYXJhbSB7RnJlcXVlbmN5fSBmcmVxXG5cdFx0ICogIEByZXR1cm4gIHtOdW1iZXJ9XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkZyZXF1ZW5jeS5wcm90b3R5cGUuX2ZyZXF1ZW5jeVRvVW5pdHMgPSBmdW5jdGlvbiAoZnJlcSkge1xuXHQgICAgICAgIHJldHVybiBmcmVxO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHRpY2sgaW4gdGhlIGN1cnJlbnQgdGltZSB1bml0c1xuXHRcdCAqICBAcGFyYW0ge1RpY2tzfSB0aWNrc1xuXHRcdCAqICBAcmV0dXJuICB7TnVtYmVyfVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5GcmVxdWVuY3kucHJvdG90eXBlLl90aWNrc1RvVW5pdHMgPSBmdW5jdGlvbiAodGlja3MpIHtcblx0ICAgICAgICByZXR1cm4gMSAvICh0aWNrcyAqIDYwIC8gKFRvbmUuVHJhbnNwb3J0LmJwbS52YWx1ZSAqIFRvbmUuVHJhbnNwb3J0LlBQUSkpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBiZWF0cyBpbiB0aGUgY3VycmVudCB1bml0c1xuXHRcdCAqICBAcGFyYW0ge051bWJlcn0gYmVhdHNcblx0XHQgKiAgQHJldHVybiAge051bWJlcn1cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuRnJlcXVlbmN5LnByb3RvdHlwZS5fYmVhdHNUb1VuaXRzID0gZnVuY3Rpb24gKGJlYXRzKSB7XG5cdCAgICAgICAgcmV0dXJuIDEgLyBUb25lLlRpbWVCYXNlLnByb3RvdHlwZS5fYmVhdHNUb1VuaXRzLmNhbGwodGhpcywgYmVhdHMpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNlY29uZCBpbiB0aGUgY3VycmVudCB1bml0c1xuXHRcdCAqICBAcGFyYW0ge1NlY29uZHN9IHNlY29uZHNcblx0XHQgKiAgQHJldHVybiAge051bWJlcn1cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuRnJlcXVlbmN5LnByb3RvdHlwZS5fc2Vjb25kc1RvVW5pdHMgPSBmdW5jdGlvbiAoc2Vjb25kcykge1xuXHQgICAgICAgIHJldHVybiAxIC8gc2Vjb25kcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGRlZmF1bHQgdW5pdHMgaWYgbm9uZSBhcmUgZ2l2ZW4uXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkZyZXF1ZW5jeS5wcm90b3R5cGUuX2RlZmF1bHRVbml0cyA9ICdoeic7XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRGUkVRVUVOQ1kgQ09OVkVSU0lPTlNcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLyoqXG5cdFx0ICogIE5vdGUgdG8gc2NhbGUgaW5kZXhcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICB2YXIgbm90ZVRvU2NhbGVJbmRleCA9IHtcblx0ICAgICAgICAnY2JiJzogLTIsXG5cdCAgICAgICAgJ2NiJzogLTEsXG5cdCAgICAgICAgJ2MnOiAwLFxuXHQgICAgICAgICdjIyc6IDEsXG5cdCAgICAgICAgJ2N4JzogMixcblx0ICAgICAgICAnZGJiJzogMCxcblx0ICAgICAgICAnZGInOiAxLFxuXHQgICAgICAgICdkJzogMixcblx0ICAgICAgICAnZCMnOiAzLFxuXHQgICAgICAgICdkeCc6IDQsXG5cdCAgICAgICAgJ2ViYic6IDIsXG5cdCAgICAgICAgJ2ViJzogMyxcblx0ICAgICAgICAnZSc6IDQsXG5cdCAgICAgICAgJ2UjJzogNSxcblx0ICAgICAgICAnZXgnOiA2LFxuXHQgICAgICAgICdmYmInOiAzLFxuXHQgICAgICAgICdmYic6IDQsXG5cdCAgICAgICAgJ2YnOiA1LFxuXHQgICAgICAgICdmIyc6IDYsXG5cdCAgICAgICAgJ2Z4JzogNyxcblx0ICAgICAgICAnZ2JiJzogNSxcblx0ICAgICAgICAnZ2InOiA2LFxuXHQgICAgICAgICdnJzogNyxcblx0ICAgICAgICAnZyMnOiA4LFxuXHQgICAgICAgICdneCc6IDksXG5cdCAgICAgICAgJ2FiYic6IDcsXG5cdCAgICAgICAgJ2FiJzogOCxcblx0ICAgICAgICAnYSc6IDksXG5cdCAgICAgICAgJ2EjJzogMTAsXG5cdCAgICAgICAgJ2F4JzogMTEsXG5cdCAgICAgICAgJ2JiYic6IDksXG5cdCAgICAgICAgJ2JiJzogMTAsXG5cdCAgICAgICAgJ2InOiAxMSxcblx0ICAgICAgICAnYiMnOiAxMixcblx0ICAgICAgICAnYngnOiAxM1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBzY2FsZSBpbmRleCB0byBub3RlIChzaGFycHMpXG5cdFx0ICogIEB0eXBlICB7QXJyYXl9XG5cdFx0ICovXG5cdCAgICB2YXIgc2NhbGVJbmRleFRvTm90ZSA9IFtcblx0ICAgICAgICAnQycsXG5cdCAgICAgICAgJ0MjJyxcblx0ICAgICAgICAnRCcsXG5cdCAgICAgICAgJ0QjJyxcblx0ICAgICAgICAnRScsXG5cdCAgICAgICAgJ0YnLFxuXHQgICAgICAgICdGIycsXG5cdCAgICAgICAgJ0cnLFxuXHQgICAgICAgICdHIycsXG5cdCAgICAgICAgJ0EnLFxuXHQgICAgICAgICdBIycsXG5cdCAgICAgICAgJ0InXG5cdCAgICBdO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBbY29uY2VydCBwaXRjaF0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29uY2VydF9waXRjaClcblx0XHQgKiAgQTQncyB2YWx1ZXMgaW4gSGVydHouXG5cdFx0ICogIEB0eXBlIHtGcmVxdWVuY3l9XG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKi9cblx0ICAgIFRvbmUuRnJlcXVlbmN5LkE0ID0gNDQwO1xuXHQgICAgLyoqXG5cdFx0ICogIENvbnZlcnQgYSBNSURJIG5vdGUgdG8gZnJlcXVlbmN5IHZhbHVlLlxuXHRcdCAqICBAcGFyYW0gIHtNSURJfSBtaWRpIFRoZSBtaWRpIG51bWJlciB0byBjb252ZXJ0LlxuXHRcdCAqICBAcmV0dXJuIHtGcmVxdWVuY3l9IHRoZSBjb3JyZXNwb25kaW5nIGZyZXF1ZW5jeSB2YWx1ZVxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogVG9uZS5GcmVxdWVuY3kubXRvZig2OSk7IC8vIHJldHVybnMgNDQwXG5cdFx0ICovXG5cdCAgICBUb25lLkZyZXF1ZW5jeS5tdG9mID0gZnVuY3Rpb24gKG1pZGkpIHtcblx0ICAgICAgICByZXR1cm4gVG9uZS5GcmVxdWVuY3kuQTQgKiBNYXRoLnBvdygyLCAobWlkaSAtIDY5KSAvIDEyKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ29udmVydCBhIGZyZXF1ZW5jeSB2YWx1ZSB0byBhIE1JREkgbm90ZS5cblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l9IGZyZXF1ZW5jeSBUaGUgdmFsdWUgdG8gZnJlcXVlbmN5IHZhbHVlIHRvIGNvbnZlcnQuXG5cdFx0ICogIEByZXR1cm5zICB7TUlESX1cblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIFRvbmUuRnJlcXVlbmN5LmZ0b20oNDQwKTsgLy8gcmV0dXJucyA2OVxuXHRcdCAqL1xuXHQgICAgVG9uZS5GcmVxdWVuY3kuZnRvbSA9IGZ1bmN0aW9uIChmcmVxdWVuY3kpIHtcblx0ICAgICAgICByZXR1cm4gNjkgKyBNYXRoLnJvdW5kKDEyICogTWF0aC5sb2cyKGZyZXF1ZW5jeSAvIFRvbmUuRnJlcXVlbmN5LkE0KSk7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuRnJlcXVlbmN5O1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuVGltZSBpcyBhIHByaW1pdGl2ZSB0eXBlIGZvciBlbmNvZGluZyBUaW1lIHZhbHVlcy5cblx0XHQgKiAgICAgICAgIFRvbmUuVGltZSBjYW4gYmUgY29uc3RydWN0ZWQgd2l0aCBvciB3aXRob3V0IHRoZSBgbmV3YCBrZXl3b3JkLiBUb25lLlRpbWUgY2FuIGJlIHBhc3NlZFxuXHRcdCAqICAgICAgICAgaW50byB0aGUgcGFyYW1ldGVyIG9mIGFueSBtZXRob2Qgd2hpY2ggdGFrZXMgdGltZSBhcyBhbiBhcmd1bWVudC5cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlRpbWVCYXNlfVxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd8TnVtYmVyfSAgdmFsICAgIFRoZSB0aW1lIHZhbHVlLlxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmc9fSAgdW5pdHMgIFRoZSB1bml0cyBvZiB0aGUgdmFsdWUuXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHQgPSBUb25lLlRpbWUoXCI0blwiKTsvL2EgcXVhcnRlciBub3RlXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWUgPSBmdW5jdGlvbiAodmFsLCB1bml0cykge1xuXHQgICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgVG9uZS5UaW1lKSB7XG5cdCAgICAgICAgICAgIFRvbmUuVGltZUJhc2UuY2FsbCh0aGlzLCB2YWwsIHVuaXRzKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICByZXR1cm4gbmV3IFRvbmUuVGltZSh2YWwsIHVuaXRzKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5UaW1lLCBUb25lLlRpbWVCYXNlKTtcblx0ICAgIC8qKlxuXHRcdCAqIEV4dGVuZCB0aGUgYmFzZSBleHByZXNzaW9uc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lLnByb3RvdHlwZS5fZXhwcmVzc2lvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBUb25lLlRpbWVCYXNlLnByb3RvdHlwZS5fZXhwcmVzc2lvbnMsIHtcblx0ICAgICAgICAncXVhbnRpemUnOiB7XG5cdCAgICAgICAgICAgIHJlZ2V4cDogL15AKC4rKS8sXG5cdCAgICAgICAgICAgIG1ldGhvZDogZnVuY3Rpb24gKGNhcHR1cmUpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChUb25lLlRyYW5zcG9ydCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBxdWFudFRvID0gbmV3IHRoaXMuY29uc3RydWN0b3IoY2FwdHVyZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRvbmUuVHJhbnNwb3J0Lm5leHRTdWJkaXZpc2lvbihxdWFudFRvKTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXHQgICAgICAgICdub3cnOiB7XG5cdCAgICAgICAgICAgIHJlZ2V4cDogL15cXCsoLispLyxcblx0ICAgICAgICAgICAgbWV0aG9kOiBmdW5jdGlvbiAoY2FwdHVyZSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25vdygpICsgbmV3IHRoaXMuY29uc3RydWN0b3IoY2FwdHVyZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBRdWFudGl6ZSB0aGUgdGltZSBieSB0aGUgZ2l2ZW4gc3ViZGl2aXNpb24uIE9wdGlvbmFsbHkgYWRkIGFcblx0XHQgKiAgcGVyY2VudGFnZSB3aGljaCB3aWxsIG1vdmUgdGhlIHRpbWUgdmFsdWUgdG93YXJkcyB0aGUgaWRlYWxcblx0XHQgKiAgcXVhbnRpemVkIHZhbHVlIGJ5IHRoYXQgcGVyY2VudGFnZS5cblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfFRpbWV9ICB2YWwgICAgVGhlIHN1YmRpdmlzaW9uIHRvIHF1YW50aXplIHRvXG5cdFx0ICogIEBwYXJhbSAge05vcm1hbFJhbmdlfSAgW3BlcmNlbnQ9MV0gIE1vdmUgdGhlIHRpbWUgdmFsdWVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG93YXJkcyB0aGUgcXVhbnRpemVkIHZhbHVlIGJ5XG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgcGVyY2VudGFnZS5cblx0XHQgKiAgQHJldHVybiAge051bWJlcn0gIHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBUb25lLlRpbWUoMjEpLnF1YW50aXplKDIpIC8vcmV0dXJucyAyMlxuXHRcdCAqIFRvbmUuVGltZSgwLjYpLnF1YW50aXplKFwiNG5cIiwgMC41KSAvL3JldHVybnMgMC41NVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lLnByb3RvdHlwZS5xdWFudGl6ZSA9IGZ1bmN0aW9uIChzdWJkaXYsIHBlcmNlbnQpIHtcblx0ICAgICAgICBwZXJjZW50ID0gVG9uZS5kZWZhdWx0QXJnKHBlcmNlbnQsIDEpO1xuXHQgICAgICAgIHZhciBzdWJkaXZpc2lvbiA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKHN1YmRpdik7XG5cdCAgICAgICAgdmFyIHZhbHVlID0gdGhpcy52YWx1ZU9mKCk7XG5cdCAgICAgICAgdmFyIG11bHRpcGxlID0gTWF0aC5yb3VuZCh2YWx1ZSAvIHN1YmRpdmlzaW9uKTtcblx0ICAgICAgICB2YXIgaWRlYWwgPSBtdWx0aXBsZSAqIHN1YmRpdmlzaW9uO1xuXHQgICAgICAgIHZhciBkaWZmID0gaWRlYWwgLSB2YWx1ZTtcblx0ICAgICAgICByZXR1cm4gdmFsdWUgKyBkaWZmICogcGVyY2VudDtcblx0ICAgIH07XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vIENPTlZFUlNJT05TXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBDb252ZXJ0IGEgVGltZSB0byBOb3RhdGlvbi4gVGhlIG5vdGF0aW9uIHZhbHVlcyBhcmUgd2lsbCBiZSB0aGVcblx0XHQgKiAgY2xvc2VzdCByZXByZXNlbnRhdGlvbiBiZXR3ZWVuIDFtIHRvIDEyOHRoIG5vdGUuXG5cdFx0ICogIEByZXR1cm4ge05vdGF0aW9ufVxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vaWYgdGhlIFRyYW5zcG9ydCBpcyBhdCAxMjBicG06XG5cdFx0ICogVG9uZS5UaW1lKDIpLnRvTm90YXRpb24oKTsvL3JldHVybnMgXCIxbVwiXG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWUucHJvdG90eXBlLnRvTm90YXRpb24gPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIHRpbWUgPSB0aGlzLnRvU2Vjb25kcygpO1xuXHQgICAgICAgIHZhciB0ZXN0Tm90YXRpb25zID0gWycxbSddO1xuXHQgICAgICAgIGZvciAodmFyIHBvd2VyID0gMTsgcG93ZXIgPCA4OyBwb3dlcisrKSB7XG5cdCAgICAgICAgICAgIHZhciBzdWJkaXYgPSBNYXRoLnBvdygyLCBwb3dlcik7XG5cdCAgICAgICAgICAgIHRlc3ROb3RhdGlvbnMucHVzaChzdWJkaXYgKyAnbi4nKTtcblx0ICAgICAgICAgICAgdGVzdE5vdGF0aW9ucy5wdXNoKHN1YmRpdiArICduJyk7XG5cdCAgICAgICAgICAgIHRlc3ROb3RhdGlvbnMucHVzaChzdWJkaXYgKyAndCcpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0ZXN0Tm90YXRpb25zLnB1c2goJzAnKTtcblx0ICAgICAgICAvL2ZpbmQgdGhlIGNsb3NldHMgbm90YXRpb24gcmVwcmVzZW50YXRpb25cblx0ICAgICAgICB2YXIgY2xvc2VzdCA9IHRlc3ROb3RhdGlvbnNbMF07XG5cdCAgICAgICAgdmFyIGNsb3Nlc3RTZWNvbmRzID0gVG9uZS5UaW1lKHRlc3ROb3RhdGlvbnNbMF0pLnRvU2Vjb25kcygpO1xuXHQgICAgICAgIHRlc3ROb3RhdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAobm90YXRpb24pIHtcblx0ICAgICAgICAgICAgdmFyIG5vdGF0aW9uU2Vjb25kcyA9IFRvbmUuVGltZShub3RhdGlvbikudG9TZWNvbmRzKCk7XG5cdCAgICAgICAgICAgIGlmIChNYXRoLmFicyhub3RhdGlvblNlY29uZHMgLSB0aW1lKSA8IE1hdGguYWJzKGNsb3Nlc3RTZWNvbmRzIC0gdGltZSkpIHtcblx0ICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSBub3RhdGlvbjtcblx0ICAgICAgICAgICAgICAgIGNsb3Nlc3RTZWNvbmRzID0gbm90YXRpb25TZWNvbmRzO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIGNsb3Nlc3Q7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybiB0aGUgdGltZSBlbmNvZGVkIGFzIEJhcnM6QmVhdHM6U2l4dGVlbnRocy5cblx0XHQgKiAgQHJldHVybiAge0JhcnNCZWF0c1NpeHRlZW50aHN9XG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWUucHJvdG90eXBlLnRvQmFyc0JlYXRzU2l4dGVlbnRocyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgcXVhcnRlclRpbWUgPSB0aGlzLl9iZWF0c1RvVW5pdHMoMSk7XG5cdCAgICAgICAgdmFyIHF1YXJ0ZXJzID0gdGhpcy52YWx1ZU9mKCkgLyBxdWFydGVyVGltZTtcblx0ICAgICAgICB2YXIgbWVhc3VyZXMgPSBNYXRoLmZsb29yKHF1YXJ0ZXJzIC8gdGhpcy5fZ2V0VGltZVNpZ25hdHVyZSgpKTtcblx0ICAgICAgICB2YXIgc2l4dGVlbnRocyA9IHF1YXJ0ZXJzICUgMSAqIDQ7XG5cdCAgICAgICAgcXVhcnRlcnMgPSBNYXRoLmZsb29yKHF1YXJ0ZXJzKSAlIHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKTtcblx0ICAgICAgICBzaXh0ZWVudGhzID0gc2l4dGVlbnRocy50b1N0cmluZygpO1xuXHQgICAgICAgIGlmIChzaXh0ZWVudGhzLmxlbmd0aCA+IDMpIHtcblx0ICAgICAgICAgICAgLy8gdGhlIGFkZGl0aW9uYWwgcGFyc2VGbG9hdCByZW1vdmVzIGluc2lnbmlmaWNhbnQgdHJhaWxpbmcgemVyb2VzXG5cdCAgICAgICAgICAgIHNpeHRlZW50aHMgPSBwYXJzZUZsb2F0KHBhcnNlRmxvYXQoc2l4dGVlbnRocykudG9GaXhlZCgzKSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHZhciBwcm9ncmVzcyA9IFtcblx0ICAgICAgICAgICAgbWVhc3VyZXMsXG5cdCAgICAgICAgICAgIHF1YXJ0ZXJzLFxuXHQgICAgICAgICAgICBzaXh0ZWVudGhzXG5cdCAgICAgICAgXTtcblx0ICAgICAgICByZXR1cm4gcHJvZ3Jlc3Muam9pbignOicpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm4gdGhlIHRpbWUgaW4gdGlja3MuXG5cdFx0ICogIEByZXR1cm4gIHtUaWNrc31cblx0XHQgKi9cblx0ICAgIFRvbmUuVGltZS5wcm90b3R5cGUudG9UaWNrcyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgcXVhcnRlclRpbWUgPSB0aGlzLl9iZWF0c1RvVW5pdHMoMSk7XG5cdCAgICAgICAgdmFyIHF1YXJ0ZXJzID0gdGhpcy52YWx1ZU9mKCkgLyBxdWFydGVyVGltZTtcblx0ICAgICAgICByZXR1cm4gTWF0aC5yb3VuZChxdWFydGVycyAqIHRoaXMuX2dldFBQUSgpKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJuIHRoZSB0aW1lIGluIHNlY29uZHMuXG5cdFx0ICogIEByZXR1cm4gIHtTZWNvbmRzfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lLnByb3RvdHlwZS50b1NlY29uZHMgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVPZigpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm4gdGhlIHZhbHVlIGFzIGEgbWlkaSBub3RlLlxuXHRcdCAqICBAcmV0dXJuICB7TWlkaX1cblx0XHQgKi9cblx0ICAgIFRvbmUuVGltZS5wcm90b3R5cGUudG9NaWRpID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiBUb25lLkZyZXF1ZW5jeS5mdG9tKHRoaXMudG9GcmVxdWVuY3koKSk7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuVGltZTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBUb25lLlRyYW5zcG9ydFRpbWUgaXMgYSB0aGUgdGltZSBhbG9uZyB0aGUgVHJhbnNwb3J0J3Ncblx0XHQgKiAgICAgICAgIHRpbWVsaW5lLiBJdCBpcyBzaW1pbGFyIHRvIFRvbmUuVGltZSwgYnV0IGluc3RlYWQgb2YgZXZhbHVhdGluZ1xuXHRcdCAqICAgICAgICAgYWdhaW5zdCB0aGUgQXVkaW9Db250ZXh0J3MgY2xvY2ssIGl0IGlzIGV2YWx1YXRlZCBhZ2FpbnN0XG5cdFx0ICogICAgICAgICB0aGUgVHJhbnNwb3J0J3MgcG9zaXRpb24uIFNlZSBbVHJhbnNwb3J0VGltZSB3aWtpXShodHRwczovL2dpdGh1Yi5jb20vVG9uZWpzL1RvbmUuanMvd2lraS9UcmFuc3BvcnRUaW1lKS5cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9ICB2YWwgICAgVGhlIHRpbWUgdmFsdWUgYXMgYSBudW1iZXIgb3Igc3RyaW5nXG5cdFx0ICogIEBwYXJhbSAge1N0cmluZz19ICB1bml0cyAgVW5pdCB2YWx1ZXNcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuVGltZX1cblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0VGltZSA9IGZ1bmN0aW9uICh2YWwsIHVuaXRzKSB7XG5cdCAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBUb25lLlRyYW5zcG9ydFRpbWUpIHtcblx0ICAgICAgICAgICAgVG9uZS5UaW1lLmNhbGwodGhpcywgdmFsLCB1bml0cyk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgcmV0dXJuIG5ldyBUb25lLlRyYW5zcG9ydFRpbWUodmFsLCB1bml0cyk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuVHJhbnNwb3J0VGltZSwgVG9uZS5UaW1lKTtcblx0ICAgIC8qKlxuXHRcdCAqIFJldHVybiB0aGUgY3VycmVudCB0aW1lIGluIHdoaWNoZXZlciBjb250ZXh0IGlzIHJlbGV2YW50XG5cdFx0ICogQHR5cGUge051bWJlcn1cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnRUaW1lLnByb3RvdHlwZS5fbm93ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiBUb25lLlRyYW5zcG9ydC5zZWNvbmRzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlRyYW5zcG9ydFRpbWU7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLy9cdFRZUEVTXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqIFVuaXRzIHdoaWNoIGEgdmFsdWUgY2FuIHRha2Ugb24uXG5cdFx0ICogQGVudW0ge1N0cmluZ31cblx0XHQgKi9cblx0ICAgIFRvbmUuVHlwZSA9IHtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBEZWZhdWx0IHVuaXRzXG5cdFx0XHQgKiAgQHR5cGVkZWYge0RlZmF1bHR9XG5cdFx0XHQgKi9cblx0ICAgICAgICBEZWZhdWx0OiAnbnVtYmVyJyxcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaW1lIGNhbiBiZSBkZXNjcmliZWQgaW4gYSBudW1iZXIgb2Ygd2F5cy4gUmVhZCBtb3JlIFtUaW1lXShodHRwczovL2dpdGh1Yi5jb20vVG9uZWpzL1RvbmUuanMvd2lraS9UaW1lKS5cblx0XHRcdCAqXG5cdFx0XHQgKiAgKiBOdW1iZXJzLCB3aGljaCB3aWxsIGJlIHRha2VuIGxpdGVyYWxseSBhcyB0aGUgdGltZSAoaW4gc2Vjb25kcykuXG5cdFx0XHQgKiAgKiBOb3RhdGlvbiwgKFwiNG5cIiwgXCI4dFwiKSBkZXNjcmliZXMgdGltZSBpbiBCUE0gYW5kIHRpbWUgc2lnbmF0dXJlIHJlbGF0aXZlIHZhbHVlcy5cblx0XHRcdCAqICAqIFRyYW5zcG9ydFRpbWUsIChcIjQ6MzoyXCIpIHdpbGwgYWxzbyBwcm92aWRlIHRlbXBvIGFuZCB0aW1lIHNpZ25hdHVyZSByZWxhdGl2ZSB0aW1lc1xuXHRcdFx0ICogIGluIHRoZSBmb3JtIEJBUlM6UVVBUlRFUlM6U0lYVEVFTlRIUy5cblx0XHRcdCAqICAqIEZyZXF1ZW5jeSwgKFwiOGh6XCIpIGlzIGNvbnZlcnRlZCB0byB0aGUgbGVuZ3RoIG9mIHRoZSBjeWNsZSBpbiBzZWNvbmRzLlxuXHRcdFx0ICogICogTm93LVJlbGF0aXZlLCAoXCIrMVwiKSBwcmVmaXggYW55IG9mIHRoZSBhYm92ZSB3aXRoIFwiK1wiIGFuZCBpdCB3aWxsIGJlIGludGVycHJldGVkIGFzXG5cdFx0XHQgKiAgXCJ0aGUgY3VycmVudCB0aW1lIHBsdXMgd2hhdGV2ZXIgZXhwcmVzc2lvbiBmb2xsb3dzXCIuXG5cdFx0XHQgKiAgKiBFeHByZXNzaW9ucywgKFwiMzowICsgMiAtICgxbSAvIDcpXCIpIGFueSBvZiB0aGUgYWJvdmUgY2FuIGFsc28gYmUgY29tYmluZWRcblx0XHRcdCAqICBpbnRvIGEgbWF0aGVtYXRpY2FsIGV4cHJlc3Npb24gd2hpY2ggd2lsbCBiZSBldmFsdWF0ZWQgdG8gY29tcHV0ZSB0aGUgZGVzaXJlZCB0aW1lLlxuXHRcdFx0ICogICogTm8gQXJndW1lbnQsIGZvciBtZXRob2RzIHdoaWNoIGFjY2VwdCB0aW1lLCBubyBhcmd1bWVudCB3aWxsIGJlIGludGVycHJldGVkIGFzXG5cdFx0XHQgKiAgXCJub3dcIiAoaS5lLiB0aGUgY3VycmVudFRpbWUpLlxuXHRcdFx0ICpcblx0XHRcdCAqICBAdHlwZWRlZiB7VGltZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIFRpbWU6ICd0aW1lJyxcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBGcmVxdWVuY3kgY2FuIGJlIGRlc2NyaWJlZCBzaW1pbGFyIHRvIHRpbWUsIGV4Y2VwdCB1bHRpbWF0ZWx5IHRoZVxuXHRcdFx0ICogIHZhbHVlcyBhcmUgY29udmVydGVkIHRvIGZyZXF1ZW5jeSBpbnN0ZWFkIG9mIHNlY29uZHMuIEEgbnVtYmVyXG5cdFx0XHQgKiAgaXMgdGFrZW4gbGl0ZXJhbGx5IGFzIHRoZSB2YWx1ZSBpbiBoZXJ0ei4gQWRkaXRpb25hbGx5IGFueSBvZiB0aGVcblx0XHRcdCAqICBUaW1lIGVuY29kaW5ncyBjYW4gYmUgdXNlZC4gTm90ZSBuYW1lcyBpbiB0aGUgZm9ybVxuXHRcdFx0ICogIG9mIE5PVEUgT0NUQVZFIChpLmUuIEM0KSBhcmUgYWxzbyBhY2NlcHRlZCBhbmQgY29udmVydGVkIHRvIHRoZWlyXG5cdFx0XHQgKiAgZnJlcXVlbmN5IHZhbHVlLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtGcmVxdWVuY3l9XG5cdFx0XHQgKi9cblx0ICAgICAgICBGcmVxdWVuY3k6ICdmcmVxdWVuY3knLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRyYW5zcG9ydFRpbWUgZGVzY3JpYmVzIGEgcG9zaXRpb24gYWxvbmcgdGhlIFRyYW5zcG9ydCdzIHRpbWVsaW5lLiBJdCBpc1xuXHRcdFx0ICogIHNpbWlsYXIgdG8gVGltZSBpbiB0aGF0IGl0IHVzZXMgYWxsIHRoZSBzYW1lIGVuY29kaW5ncywgYnV0IFRyYW5zcG9ydFRpbWUgc3BlY2lmaWNhbGx5XG5cdFx0XHQgKiAgcGVydGFpbnMgdG8gdGhlIFRyYW5zcG9ydCdzIHRpbWVsaW5lLCB3aGljaCBpcyBzdGFydGFibGUsIHN0b3BwYWJsZSwgbG9vcGFibGUsIGFuZCBzZWVrYWJsZS5cblx0XHRcdCAqICBbUmVhZCBtb3JlXShodHRwczovL2dpdGh1Yi5jb20vVG9uZWpzL1RvbmUuanMvd2lraS9UcmFuc3BvcnRUaW1lKVxuXHRcdFx0ICogIEB0eXBlZGVmIHtUcmFuc3BvcnRUaW1lfVxuXHRcdFx0ICovXG5cdCAgICAgICAgVHJhbnNwb3J0VGltZTogJ3RyYW5zcG9ydFRpbWUnLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRpY2tzIGFyZSB0aGUgYmFzaWMgc3VidW5pdCBvZiB0aGUgVHJhbnNwb3J0LiBUaGV5IGFyZVxuXHRcdFx0ICogIHRoZSBzbWFsbGVzdCB1bml0IG9mIHRpbWUgdGhhdCB0aGUgVHJhbnNwb3J0IHN1cHBvcnRzLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtUaWNrc31cblx0XHRcdCAqL1xuXHQgICAgICAgIFRpY2tzOiAndGlja3MnLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIE5vcm1hbCB2YWx1ZXMgYXJlIHdpdGhpbiB0aGUgcmFuZ2UgWzAsIDFdLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtOb3JtYWxSYW5nZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIE5vcm1hbFJhbmdlOiAnbm9ybWFsUmFuZ2UnLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEF1ZGlvUmFuZ2UgdmFsdWVzIGFyZSBiZXR3ZWVuIFstMSwgMV0uXG5cdFx0XHQgKiAgQHR5cGVkZWYge0F1ZGlvUmFuZ2V9XG5cdFx0XHQgKi9cblx0ICAgICAgICBBdWRpb1JhbmdlOiAnYXVkaW9SYW5nZScsXG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgRGVjaWJlbHMgYXJlIGEgbG9nYXJpdGhtaWMgdW5pdCBvZiBtZWFzdXJlbWVudCB3aGljaCBpcyB1c2VmdWwgZm9yIHZvbHVtZVxuXHRcdFx0ICogIGJlY2F1c2Ugb2YgdGhlIGxvZ2FyaXRobWljIHdheSB0aGF0IHdlIHBlcmNlaXZlIGxvdWRuZXNzLiAwIGRlY2liZWxzXG5cdFx0XHQgKiAgbWVhbnMgbm8gY2hhbmdlIGluIHZvbHVtZS4gLTEwZGIgaXMgYXBwcm94aW1hdGVseSBoYWxmIGFzIGxvdWQgYW5kIDEwZGJcblx0XHRcdCAqICBpcyB0d2ljZSBpcyBsb3VkLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtEZWNpYmVsc31cblx0XHRcdCAqL1xuXHQgICAgICAgIERlY2liZWxzOiAnZGInLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEhhbGYtc3RlcCBub3RlIGluY3JlbWVudHMsIGkuZS4gMTIgaXMgYW4gb2N0YXZlIGFib3ZlIHRoZSByb290LiBhbmQgMSBpcyBhIGhhbGYtc3RlcCB1cC5cblx0XHRcdCAqICBAdHlwZWRlZiB7SW50ZXJ2YWx9XG5cdFx0XHQgKi9cblx0ICAgICAgICBJbnRlcnZhbDogJ2ludGVydmFsJyxcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBCZWF0cyBwZXIgbWludXRlLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtCUE19XG5cdFx0XHQgKi9cblx0ICAgICAgICBCUE06ICdicG0nLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSB2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtQb3NpdGl2ZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIFBvc2l0aXZlOiAncG9zaXRpdmUnLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEdhaW4gaXMgdGhlIHJhdGlvIGJldHdlZW4gaW5wdXQgYW5kIG91dHB1dCBvZiBhIHNpZ25hbC5cblx0XHRcdCAqICBBIGdhaW4gb2YgMCBpcyB0aGUgc2FtZSBhcyBzaWxlbmNpbmcgdGhlIHNpZ25hbC4gQSBnYWluIG9mXG5cdFx0XHQgKiAgMSwgY2F1c2VzIG5vIGNoYW5nZSB0byB0aGUgaW5jb21pbmcgc2lnbmFsLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtHYWlufVxuXHRcdFx0ICovXG5cdCAgICAgICAgR2FpbjogJ2dhaW4nLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEEgY2VudCBpcyBhIGh1bmRyZWR0aCBvZiBhIHNlbWl0b25lLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtDZW50c31cblx0XHRcdCAqL1xuXHQgICAgICAgIENlbnRzOiAnY2VudHMnLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEFuZ2xlIGJldHdlZW4gMCBhbmQgMzYwLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtEZWdyZWVzfVxuXHRcdFx0ICovXG5cdCAgICAgICAgRGVncmVlczogJ2RlZ3JlZXMnLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEEgbnVtYmVyIHJlcHJlc2VudGluZyBhIG1pZGkgbm90ZS5cblx0XHRcdCAqICBAdHlwZWRlZiB7TUlESX1cblx0XHRcdCAqL1xuXHQgICAgICAgIE1JREk6ICdtaWRpJyxcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBBIGNvbG9uLXNlcGFyYXRlZCByZXByZXNlbnRhdGlvbiBvZiB0aW1lIGluIHRoZSBmb3JtIG9mXG5cdFx0XHQgKiAgQmFyczpCZWF0czpTaXh0ZWVudGhzLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtCYXJzQmVhdHNTaXh0ZWVudGhzfVxuXHRcdFx0ICovXG5cdCAgICAgICAgQmFyc0JlYXRzU2l4dGVlbnRoczogJ2JhcnNCZWF0c1NpeHRlZW50aHMnLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFNhbXBsaW5nIGlzIHRoZSByZWR1Y3Rpb24gb2YgYSBjb250aW51b3VzIHNpZ25hbCB0byBhIGRpc2NyZXRlIHNpZ25hbC5cblx0XHRcdCAqICBBdWRpbyBpcyB0eXBpY2FsbHkgc2FtcGxlZCA0NDEwMCB0aW1lcyBwZXIgc2Vjb25kLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtTYW1wbGVzfVxuXHRcdFx0ICovXG5cdCAgICAgICAgU2FtcGxlczogJ3NhbXBsZXMnLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEhlcnR6IGFyZSBhIGZyZXF1ZW5jeSByZXByZXNlbnRhdGlvbiBkZWZpbmVkIGFzIG9uZSBjeWNsZSBwZXIgc2Vjb25kLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtIZXJ0en1cblx0XHRcdCAqL1xuXHQgICAgICAgIEhlcnR6OiAnaGVydHonLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEEgZnJlcXVlbmN5IHJlcHJlc2VudGVkIGJ5IGEgbGV0dGVyIG5hbWUsXG5cdFx0XHQgKiAgYWNjaWRlbnRhbCBhbmQgb2N0YXZlLiBUaGlzIHN5c3RlbSBpcyBrbm93biBhc1xuXHRcdFx0ICogIFtTY2llbnRpZmljIFBpdGNoIE5vdGF0aW9uXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TY2llbnRpZmljX3BpdGNoX25vdGF0aW9uKS5cblx0XHRcdCAqICBAdHlwZWRlZiB7Tm90ZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIE5vdGU6ICdub3RlJyxcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBPbmUgbWlsbGlzZWNvbmQgaXMgYSB0aG91c2FuZHRoIG9mIGEgc2Vjb25kLlxuXHRcdFx0ICogIEB0eXBlZGVmIHtNaWxsaXNlY29uZHN9XG5cdFx0XHQgKi9cblx0ICAgICAgICBNaWxsaXNlY29uZHM6ICdtaWxsaXNlY29uZHMnLFxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFNlY29uZHMgYXJlIHRoZSB0aW1lIHVuaXQgb2YgdGhlIEF1ZGlvQ29udGV4dC4gSW4gdGhlIGVuZCxcblx0XHRcdCAqICBhbGwgdmFsdWVzIG5lZWQgdG8gYmUgZXZhbHVhdGVkIHRvIHNlY29uZHMuXG5cdFx0XHQgKiAgQHR5cGVkZWYge1NlY29uZHN9XG5cdFx0XHQgKi9cblx0ICAgICAgICBTZWNvbmRzOiAnc2Vjb25kcycsXG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQSBzdHJpbmcgcmVwcmVzZW50aW5nIGEgZHVyYXRpb24gcmVsYXRpdmUgdG8gYSBtZWFzdXJlLlxuXHRcdFx0ICogICogXCI0blwiID0gcXVhcnRlciBub3RlXG5cdFx0XHQgKiAgKiBcIjJtXCIgPSB0d28gbWVhc3VyZXNcblx0XHRcdCAqICAqIFwiOHRcIiA9IGVpZ2h0aC1ub3RlIHRyaXBsZXRcblx0XHRcdCAqICBAdHlwZWRlZiB7Tm90YXRpb259XG5cdFx0XHQgKi9cblx0ICAgICAgICBOb3RhdGlvbjogJ25vdGF0aW9uJ1xuXHQgICAgfTtcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLy8gQVVHTUVOVCBUT05FJ3MgUFJPVE9UWVBFXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBDb252ZXJ0IFRpbWUgaW50byBzZWNvbmRzLlxuXHRcdCAqXG5cdFx0ICogIFVubGlrZSB0aGUgbWV0aG9kIHdoaWNoIGl0IG92ZXJyaWRlcywgdGhpcyB0YWtlcyBpbnRvIGFjY291bnRcblx0XHQgKiAgdHJhbnNwb3J0dGltZSBhbmQgbXVzaWNhbCBub3RhdGlvbi5cblx0XHQgKlxuXHRcdCAqICBUaW1lIDogMS40MFxuXHRcdCAqICBOb3RhdGlvbjogNG4gb3IgMW0gb3IgMnRcblx0XHQgKiAgTm93IFJlbGF0aXZlOiArM25cblx0XHQgKiAgTWF0aDogM24rMTZuIG9yIGV2ZW4gY29tcGxpY2F0ZWQgZXhwcmVzc2lvbnMgKCgzbioyKS82ICsgMSlcblx0XHQgKlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSB0aW1lXG5cdFx0ICogIEByZXR1cm4ge1NlY29uZHN9XG5cdFx0ICovXG5cdCAgICBUb25lLnByb3RvdHlwZS50b1NlY29uZHMgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIGlmIChUb25lLmlzTnVtYmVyKHRpbWUpKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aW1lO1xuXHQgICAgICAgIH0gZWxzZSBpZiAoVG9uZS5pc1VuZGVmKHRpbWUpKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLm5vdygpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAoVG9uZS5pc1N0cmluZyh0aW1lKSkge1xuXHQgICAgICAgICAgICByZXR1cm4gbmV3IFRvbmUuVGltZSh0aW1lKS50b1NlY29uZHMoKTtcblx0ICAgICAgICB9IGVsc2UgaWYgKHRpbWUgaW5zdGFuY2VvZiBUb25lLlRpbWVCYXNlKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aW1lLnRvU2Vjb25kcygpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ29udmVydCBhIGZyZXF1ZW5jeSByZXByZXNlbnRhdGlvbiBpbnRvIGEgbnVtYmVyLlxuXHRcdCAqICBAcGFyYW0gIHtGcmVxdWVuY3l9IGZyZXFcblx0XHQgKiAgQHJldHVybiB7SGVydHp9ICAgICAgdGhlIGZyZXF1ZW5jeSBpbiBoZXJ0elxuXHRcdCAqL1xuXHQgICAgVG9uZS5wcm90b3R5cGUudG9GcmVxdWVuY3kgPSBmdW5jdGlvbiAoZnJlcSkge1xuXHQgICAgICAgIGlmIChUb25lLmlzTnVtYmVyKGZyZXEpKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBmcmVxO1xuXHQgICAgICAgIH0gZWxzZSBpZiAoVG9uZS5pc1N0cmluZyhmcmVxKSB8fCBUb25lLmlzVW5kZWYoZnJlcSkpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIG5ldyBUb25lLkZyZXF1ZW5jeShmcmVxKS52YWx1ZU9mKCk7XG5cdCAgICAgICAgfSBlbHNlIGlmIChmcmVxIGluc3RhbmNlb2YgVG9uZS5UaW1lQmFzZSkge1xuXHQgICAgICAgICAgICByZXR1cm4gZnJlcS50b0ZyZXF1ZW5jeSgpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ29udmVydCBhIHRpbWUgcmVwcmVzZW50YXRpb24gaW50byB0aWNrcy5cblx0XHQgKiAgQHBhcmFtICB7VGltZX0gdGltZVxuXHRcdCAqICBAcmV0dXJuIHtUaWNrc30gIHRoZSB0aW1lIGluIHRpY2tzXG5cdFx0ICovXG5cdCAgICBUb25lLnByb3RvdHlwZS50b1RpY2tzID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICBpZiAoVG9uZS5pc051bWJlcih0aW1lKSB8fCBUb25lLmlzU3RyaW5nKHRpbWUpKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgVG9uZS5UcmFuc3BvcnRUaW1lKHRpbWUpLnRvVGlja3MoKTtcblx0ICAgICAgICB9IGVsc2UgaWYgKFRvbmUuaXNVbmRlZih0aW1lKSkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5UcmFuc3BvcnQudGlja3M7XG5cdCAgICAgICAgfSBlbHNlIGlmICh0aW1lIGluc3RhbmNlb2YgVG9uZS5UaW1lQmFzZSkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGltZS50b1RpY2tzKCk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5QYXJhbSB3cmFwcyB0aGUgbmF0aXZlIFdlYiBBdWRpbydzIEF1ZGlvUGFyYW0gdG8gcHJvdmlkZVxuXHRcdCAqICAgICAgICAgYWRkaXRpb25hbCB1bml0IGNvbnZlcnNpb24gZnVuY3Rpb25hbGl0eS4gSXQgYWxzb1xuXHRcdCAqICAgICAgICAgc2VydmVzIGFzIGEgYmFzZS1jbGFzcyBmb3IgY2xhc3NlcyB3aGljaCBoYXZlIGEgc2luZ2xlLFxuXHRcdCAqICAgICAgICAgYXV0b21hdGFibGUgcGFyYW1ldGVyLlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBwYXJhbSAge0F1ZGlvUGFyYW19ICBwYXJhbSAgVGhlIHBhcmFtZXRlciB0byB3cmFwLlxuXHRcdCAqICBAcGFyYW0gIHtUb25lLlR5cGV9IHVuaXRzIFRoZSB1bml0cyBvZiB0aGUgYXVkaW8gcGFyYW0uXG5cdFx0ICogIEBwYXJhbSAge0Jvb2xlYW59IGNvbnZlcnQgSWYgdGhlIHBhcmFtIHNob3VsZCBiZSBjb252ZXJ0ZWQuXG5cdFx0ICovXG5cdCAgICBUb25lLlBhcmFtID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ3BhcmFtJyxcblx0ICAgICAgICAgICAgJ3VuaXRzJyxcblx0ICAgICAgICAgICAgJ2NvbnZlcnQnXG5cdCAgICAgICAgXSwgVG9uZS5QYXJhbSk7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbmF0aXZlIHBhcmFtZXRlciB0byBjb250cm9sXG5cdFx0XHQgKiAgQHR5cGUgIHtBdWRpb1BhcmFtfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9wYXJhbSA9IHRoaXMuaW5wdXQgPSBvcHRpb25zLnBhcmFtO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSB1bml0cyBvZiB0aGUgcGFyYW1ldGVyXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuVHlwZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMudW5pdHMgPSBvcHRpb25zLnVuaXRzO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIElmIHRoZSB2YWx1ZSBzaG91bGQgYmUgY29udmVydGVkIG9yIG5vdFxuXHRcdFx0ICogIEB0eXBlIHtCb29sZWFufVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5jb252ZXJ0ID0gb3B0aW9ucy5jb252ZXJ0O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRydWUgaWYgdGhlIHNpZ25hbCB2YWx1ZSBpcyBiZWluZyBvdmVycmlkZGVuIGJ5XG5cdFx0XHQgKiAgYSBjb25uZWN0ZWQgc2lnbmFsLlxuXHRcdFx0ICogIEByZWFkT25seVxuXHRcdFx0ICogIEB0eXBlICB7Ym9vbGVhbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5vdmVycmlkZGVuID0gZmFsc2U7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBUaGUgdGltZWxpbmUgd2hpY2ggdHJhY2tzIGFsbCBvZiB0aGUgYXV0b21hdGlvbnMuXG5cdFx0XHQgKiBAdHlwZSB7VG9uZS5UaW1lbGluZX1cblx0XHRcdCAqIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgVG9uZS5UaW1lbGluZSgxMDAwKTtcblx0ICAgICAgICBpZiAoVG9uZS5pc0RlZmluZWQob3B0aW9ucy52YWx1ZSkgJiYgdGhpcy5fcGFyYW0pIHtcblx0ICAgICAgICAgICAgdGhpcy52YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuUGFyYW0sIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBEZWZhdWx0c1xuXHRcdCAqICBAdHlwZSAge09iamVjdH1cblx0XHQgKiAgQGNvbnN0XG5cdFx0ICovXG5cdCAgICBUb25lLlBhcmFtLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICd1bml0cyc6IFRvbmUuVHlwZS5EZWZhdWx0LFxuXHQgICAgICAgICdjb252ZXJ0JzogdHJ1ZSxcblx0ICAgICAgICAncGFyYW0nOiB1bmRlZmluZWRcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlBhcmFtI1xuXHRcdCAqIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogQG5hbWUgdmFsdWVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBhcmFtLnByb3RvdHlwZSwgJ3ZhbHVlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgbm93ID0gdGhpcy5ub3coKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RvVW5pdHModGhpcy5nZXRWYWx1ZUF0VGltZShub3cpKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2luaXRpYWxWYWx1ZSA9IHRoaXMuX2Zyb21Vbml0cyh2YWx1ZSk7XG5cdCAgICAgICAgICAgIHRoaXMuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRoaXMuY29udGV4dC5jdXJyZW50VGltZSk7XG5cdCAgICAgICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgbWluaW11bSBvdXRwdXQgdmFsdWUgb2YgdGhlIHBhcmFtZXRlclxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlBhcmFtI1xuXHRcdCAqIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogQG5hbWUgdmFsdWVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBhcmFtLnByb3RvdHlwZSwgJ21pblZhbHVlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBpZiAodGhpcy51bml0cyA9PT0gVG9uZS5UeXBlLlRpbWUgfHwgdGhpcy51bml0cyA9PT0gVG9uZS5UeXBlLkZyZXF1ZW5jeSB8fCB0aGlzLnVuaXRzID09PSBUb25lLlR5cGUuTm9ybWFsUmFuZ2UgfHwgdGhpcy51bml0cyA9PT0gVG9uZS5UeXBlLlBvc2l0aXZlIHx8IHRoaXMudW5pdHMgPT09IFRvbmUuVHlwZS5CUE0pIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiAwO1xuXHQgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMudW5pdHMgPT09IFRvbmUuVHlwZS5BdWRpb1JhbmdlKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gLTE7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy51bml0cyA9PT0gVG9uZS5UeXBlLkRlY2liZWxzKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gLUluZmluaXR5O1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLm1pblZhbHVlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgbWF4aW11bSBvdXRwdXQgdmFsdWUgb2YgdGhlIHBhcmFtZXRlclxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlBhcmFtI1xuXHRcdCAqIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogQG5hbWUgdmFsdWVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBhcmFtLnByb3RvdHlwZSwgJ21heFZhbHVlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBpZiAodGhpcy51bml0cyA9PT0gVG9uZS5UeXBlLk5vcm1hbFJhbmdlIHx8IHRoaXMudW5pdHMgPT09IFRvbmUuVHlwZS5BdWRpb1JhbmdlKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gMTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5tYXhWYWx1ZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENvbnZlcnQgdGhlIGdpdmVuIHZhbHVlIGZyb20gdGhlIHR5cGUgc3BlY2lmaWVkIGJ5IFRvbmUuUGFyYW0udW5pdHNcblx0XHQgKiAgaW50byB0aGUgZGVzdGluYXRpb24gdmFsdWUgKHN1Y2ggYXMgR2FpbiBvciBGcmVxdWVuY3kpLlxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqICBAcGFyYW0gIHsqfSB2YWwgdGhlIHZhbHVlIHRvIGNvbnZlcnRcblx0XHQgKiAgQHJldHVybiB7bnVtYmVyfSAgICAgdGhlIG51bWJlciB3aGljaCB0aGUgdmFsdWUgc2hvdWxkIGJlIHNldCB0b1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYXJhbS5wcm90b3R5cGUuX2Zyb21Vbml0cyA9IGZ1bmN0aW9uICh2YWwpIHtcblx0ICAgICAgICBpZiAoKHRoaXMuY29udmVydCB8fCBUb25lLmlzVW5kZWYodGhpcy5jb252ZXJ0KSkgJiYgIXRoaXMub3ZlcnJpZGRlbikge1xuXHQgICAgICAgICAgICBzd2l0Y2ggKHRoaXMudW5pdHMpIHtcblx0ICAgICAgICAgICAgY2FzZSBUb25lLlR5cGUuVGltZTpcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvU2Vjb25kcyh2YWwpO1xuXHQgICAgICAgICAgICBjYXNlIFRvbmUuVHlwZS5GcmVxdWVuY3k6XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0ZyZXF1ZW5jeSh2YWwpO1xuXHQgICAgICAgICAgICBjYXNlIFRvbmUuVHlwZS5EZWNpYmVsczpcblx0ICAgICAgICAgICAgICAgIHJldHVybiBUb25lLmRiVG9HYWluKHZhbCk7XG5cdCAgICAgICAgICAgIGNhc2UgVG9uZS5UeXBlLk5vcm1hbFJhbmdlOlxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIE1hdGgubWluKE1hdGgubWF4KHZhbCwgMCksIDEpO1xuXHQgICAgICAgICAgICBjYXNlIFRvbmUuVHlwZS5BdWRpb1JhbmdlOlxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIE1hdGgubWluKE1hdGgubWF4KHZhbCwgLTEpLCAxKTtcblx0ICAgICAgICAgICAgY2FzZSBUb25lLlR5cGUuUG9zaXRpdmU6XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gTWF0aC5tYXgodmFsLCAwKTtcblx0ICAgICAgICAgICAgZGVmYXVsdDpcblx0ICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICByZXR1cm4gdmFsO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBDb252ZXJ0IHRoZSBwYXJhbWV0ZXJzIHZhbHVlIGludG8gdGhlIHVuaXRzIHNwZWNpZmllZCBieSBUb25lLlBhcmFtLnVuaXRzLlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICogQHBhcmFtICB7bnVtYmVyfSB2YWwgdGhlIHZhbHVlIHRvIGNvbnZlcnRcblx0XHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdFx0ICovXG5cdCAgICBUb25lLlBhcmFtLnByb3RvdHlwZS5fdG9Vbml0cyA9IGZ1bmN0aW9uICh2YWwpIHtcblx0ICAgICAgICBpZiAodGhpcy5jb252ZXJ0IHx8IFRvbmUuaXNVbmRlZih0aGlzLmNvbnZlcnQpKSB7XG5cdCAgICAgICAgICAgIHN3aXRjaCAodGhpcy51bml0cykge1xuXHQgICAgICAgICAgICBjYXNlIFRvbmUuVHlwZS5EZWNpYmVsczpcblx0ICAgICAgICAgICAgICAgIHJldHVybiBUb25lLmdhaW5Ub0RiKHZhbCk7XG5cdCAgICAgICAgICAgIGRlZmF1bHQ6XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHZhbDtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIHRoZSBtaW5pbXVtIG91dHB1dCB2YWx1ZVxuXHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QYXJhbS5wcm90b3R5cGUuX21pbk91dHB1dCA9IDAuMDAwMDE7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGV2ZW50IHR5cGVzXG5cdFx0ICogIEBlbnVtIHtTdHJpbmd9XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlBhcmFtLkF1dG9tYXRpb25UeXBlID0ge1xuXHQgICAgICAgIExpbmVhcjogJ2xpbmVhclJhbXBUb1ZhbHVlQXRUaW1lJyxcblx0ICAgICAgICBFeHBvbmVudGlhbDogJ2V4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUnLFxuXHQgICAgICAgIFRhcmdldDogJ3NldFRhcmdldEF0VGltZScsXG5cdCAgICAgICAgU2V0VmFsdWU6ICdzZXRWYWx1ZUF0VGltZSdcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU2NoZWR1bGVzIGEgcGFyYW1ldGVyIHZhbHVlIGNoYW5nZSBhdCB0aGUgZ2l2ZW4gdGltZS5cblx0XHQgKiAgQHBhcmFtIHsqfVx0dmFsdWUgVGhlIHZhbHVlIHRvIHNldCB0aGUgc2lnbmFsLlxuXHRcdCAqICBAcGFyYW0ge1RpbWV9ICB0aW1lIFRoZSB0aW1lIHdoZW4gdGhlIGNoYW5nZSBzaG91bGQgb2NjdXIuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBhcmFtfSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9zZXQgdGhlIGZyZXF1ZW5jeSB0byBcIkc0XCIgaW4gZXhhY3RseSAxIHNlY29uZCBmcm9tIG5vdy5cblx0XHQgKiBmcmVxLnNldFZhbHVlQXRUaW1lKFwiRzRcIiwgXCIrMVwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFyYW0ucHJvdG90eXBlLnNldFZhbHVlQXRUaW1lID0gZnVuY3Rpb24gKHZhbHVlLCB0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHZhbHVlID0gdGhpcy5fZnJvbVVuaXRzKHZhbHVlKTtcblx0ICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcblx0ICAgICAgICAgICAgJ3R5cGUnOiBUb25lLlBhcmFtLkF1dG9tYXRpb25UeXBlLlNldFZhbHVlLFxuXHQgICAgICAgICAgICAndmFsdWUnOiB2YWx1ZSxcblx0ICAgICAgICAgICAgJ3RpbWUnOiB0aW1lXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdGhpcy5fcGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBHZXQgdGhlIHNpZ25hbHMgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuIFN1YnNlcXVlbnQgc2NoZWR1bGluZ1xuXHRcdCAqICBtYXkgaW52YWxpZGF0ZSB0aGUgcmV0dXJuZWQgdmFsdWUuXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gdGltZSBXaGVuIHRvIGdldCB0aGUgdmFsdWVcblx0XHQgKiAgQHJldHVybnMge051bWJlcn0gVGhlIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lXG5cdFx0ICovXG5cdCAgICBUb25lLlBhcmFtLnByb3RvdHlwZS5nZXRWYWx1ZUF0VGltZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHZhciBhZnRlciA9IHRoaXMuX2V2ZW50cy5nZXRBZnRlcih0aW1lKTtcblx0ICAgICAgICB2YXIgYmVmb3JlID0gdGhpcy5fZXZlbnRzLmdldCh0aW1lKTtcblx0ICAgICAgICB2YXIgaW5pdGlhbFZhbHVlID0gVG9uZS5kZWZhdWx0QXJnKHRoaXMuX2luaXRpYWxWYWx1ZSwgdGhpcy5fcGFyYW0uZGVmYXVsdFZhbHVlKTtcblx0ICAgICAgICB2YXIgdmFsdWUgPSBpbml0aWFsVmFsdWU7XG5cdCAgICAgICAgLy9pZiBpdCB3YXMgc2V0IGJ5XG5cdCAgICAgICAgaWYgKGJlZm9yZSA9PT0gbnVsbCkge1xuXHQgICAgICAgICAgICB2YWx1ZSA9IGluaXRpYWxWYWx1ZTtcblx0ICAgICAgICB9IGVsc2UgaWYgKGJlZm9yZS50eXBlID09PSBUb25lLlBhcmFtLkF1dG9tYXRpb25UeXBlLlRhcmdldCkge1xuXHQgICAgICAgICAgICB2YXIgcHJldmlvdXMgPSB0aGlzLl9ldmVudHMuZ2V0QmVmb3JlKGJlZm9yZS50aW1lKTtcblx0ICAgICAgICAgICAgdmFyIHByZXZpb3VzVmFsO1xuXHQgICAgICAgICAgICBpZiAocHJldmlvdXMgPT09IG51bGwpIHtcblx0ICAgICAgICAgICAgICAgIHByZXZpb3VzVmFsID0gaW5pdGlhbFZhbHVlO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcHJldmlvdXNWYWwgPSBwcmV2aW91cy52YWx1ZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB2YWx1ZSA9IHRoaXMuX2V4cG9uZW50aWFsQXBwcm9hY2goYmVmb3JlLnRpbWUsIHByZXZpb3VzVmFsLCBiZWZvcmUudmFsdWUsIGJlZm9yZS5jb25zdGFudCwgdGltZSk7XG5cdCAgICAgICAgfSBlbHNlIGlmIChhZnRlciA9PT0gbnVsbCkge1xuXHQgICAgICAgICAgICB2YWx1ZSA9IGJlZm9yZS52YWx1ZTtcblx0ICAgICAgICB9IGVsc2UgaWYgKGFmdGVyLnR5cGUgPT09IFRvbmUuUGFyYW0uQXV0b21hdGlvblR5cGUuTGluZWFyKSB7XG5cdCAgICAgICAgICAgIHZhbHVlID0gdGhpcy5fbGluZWFySW50ZXJwb2xhdGUoYmVmb3JlLnRpbWUsIGJlZm9yZS52YWx1ZSwgYWZ0ZXIudGltZSwgYWZ0ZXIudmFsdWUsIHRpbWUpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAoYWZ0ZXIudHlwZSA9PT0gVG9uZS5QYXJhbS5BdXRvbWF0aW9uVHlwZS5FeHBvbmVudGlhbCkge1xuXHQgICAgICAgICAgICB2YWx1ZSA9IHRoaXMuX2V4cG9uZW50aWFsSW50ZXJwb2xhdGUoYmVmb3JlLnRpbWUsIGJlZm9yZS52YWx1ZSwgYWZ0ZXIudGltZSwgYWZ0ZXIudmFsdWUsIHRpbWUpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHZhbHVlID0gYmVmb3JlLnZhbHVlO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdmFsdWU7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENyZWF0ZXMgYSBzY2hlZHVsZSBwb2ludCB3aXRoIHRoZSBjdXJyZW50IHZhbHVlIGF0IHRoZSBjdXJyZW50IHRpbWUuXG5cdFx0ICogIFRoaXMgaXMgdXNlZnVsIGZvciBjcmVhdGluZyBhbiBhdXRvbWF0aW9uIGFuY2hvciBwb2ludCBpbiBvcmRlciB0b1xuXHRcdCAqICBzY2hlZHVsZSBjaGFuZ2VzIGZyb20gdGhlIGN1cnJlbnQgdmFsdWUuXG5cdFx0ICpcblx0XHQgKiAgQHBhcmFtIHtudW1iZXI9fSBub3cgKE9wdGlvbmFsbHkpIHBhc3MgdGhlIG5vdyB2YWx1ZSBpbi5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuUGFyYW19IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFyYW0ucHJvdG90eXBlLnNldFJhbXBQb2ludCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHZhciBjdXJyZW50VmFsID0gdGhpcy5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcblx0ICAgICAgICB0aGlzLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG5cdCAgICAgICAgaWYgKGN1cnJlbnRWYWwgPT09IDApIHtcblx0ICAgICAgICAgICAgY3VycmVudFZhbCA9IHRoaXMuX21pbk91dHB1dDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZSh0aGlzLl90b1VuaXRzKGN1cnJlbnRWYWwpLCB0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU2NoZWR1bGVzIGEgbGluZWFyIGNvbnRpbnVvdXMgY2hhbmdlIGluIHBhcmFtZXRlciB2YWx1ZSBmcm9tIHRoZVxuXHRcdCAqICBwcmV2aW91cyBzY2hlZHVsZWQgcGFyYW1ldGVyIHZhbHVlIHRvIHRoZSBnaXZlbiB2YWx1ZS5cblx0XHQgKlxuXHRcdCAqICBAcGFyYW0gIHtudW1iZXJ9IHZhbHVlXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IGVuZFRpbWVcblx0XHQgKiAgQHJldHVybnMge1RvbmUuUGFyYW19IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFyYW0ucHJvdG90eXBlLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lID0gZnVuY3Rpb24gKHZhbHVlLCBlbmRUaW1lKSB7XG5cdCAgICAgICAgdmFsdWUgPSB0aGlzLl9mcm9tVW5pdHModmFsdWUpO1xuXHQgICAgICAgIGVuZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhlbmRUaW1lKTtcblx0ICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcblx0ICAgICAgICAgICAgJ3R5cGUnOiBUb25lLlBhcmFtLkF1dG9tYXRpb25UeXBlLkxpbmVhcixcblx0ICAgICAgICAgICAgJ3ZhbHVlJzogdmFsdWUsXG5cdCAgICAgICAgICAgICd0aW1lJzogZW5kVGltZVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRoaXMuX3BhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU2NoZWR1bGVzIGFuIGV4cG9uZW50aWFsIGNvbnRpbnVvdXMgY2hhbmdlIGluIHBhcmFtZXRlciB2YWx1ZSBmcm9tXG5cdFx0ICogIHRoZSBwcmV2aW91cyBzY2hlZHVsZWQgcGFyYW1ldGVyIHZhbHVlIHRvIHRoZSBnaXZlbiB2YWx1ZS5cblx0XHQgKlxuXHRcdCAqICBAcGFyYW0gIHtudW1iZXJ9IHZhbHVlXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IGVuZFRpbWVcblx0XHQgKiAgQHJldHVybnMge1RvbmUuUGFyYW19IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFyYW0ucHJvdG90eXBlLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUgPSBmdW5jdGlvbiAodmFsdWUsIGVuZFRpbWUpIHtcblx0ICAgICAgICB2YWx1ZSA9IHRoaXMuX2Zyb21Vbml0cyh2YWx1ZSk7XG5cdCAgICAgICAgdmFsdWUgPSBNYXRoLm1heCh0aGlzLl9taW5PdXRwdXQsIHZhbHVlKTtcblx0ICAgICAgICBlbmRUaW1lID0gdGhpcy50b1NlY29uZHMoZW5kVGltZSk7XG5cdCAgICAgICAgLy9zdG9yZSB0aGUgZXZlbnRcblx0ICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcblx0ICAgICAgICAgICAgJ3R5cGUnOiBUb25lLlBhcmFtLkF1dG9tYXRpb25UeXBlLkV4cG9uZW50aWFsLFxuXHQgICAgICAgICAgICAndGltZSc6IGVuZFRpbWUsXG5cdCAgICAgICAgICAgICd2YWx1ZSc6IHZhbHVlXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdGhpcy5fcGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFNjaGVkdWxlcyBhbiBleHBvbmVudGlhbCBjb250aW51b3VzIGNoYW5nZSBpbiBwYXJhbWV0ZXIgdmFsdWUgZnJvbVxuXHRcdCAqICB0aGUgY3VycmVudCB0aW1lIGFuZCBjdXJyZW50IHZhbHVlIHRvIHRoZSBnaXZlbiB2YWx1ZSBvdmVyIHRoZVxuXHRcdCAqICBkdXJhdGlvbiBvZiB0aGUgcmFtcFRpbWUuXG5cdFx0ICpcblx0XHQgKiAgQHBhcmFtICB7bnVtYmVyfSB2YWx1ZSAgIFRoZSB2YWx1ZSB0byByYW1wIHRvLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSByYW1wVGltZSB0aGUgdGltZSB0aGF0IGl0IHRha2VzIHRoZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIHRvIHJhbXAgZnJvbSBpdCdzIGN1cnJlbnQgdmFsdWVcblx0XHQgKiAgQHBhcmFtIHtUaW1lfVx0W3N0YXJ0VGltZT1ub3ddIFx0V2hlbiB0aGUgcmFtcCBzaG91bGQgc3RhcnQuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBhcmFtfSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9leHBvbmVudGlhbGx5IHJhbXAgdG8gdGhlIHZhbHVlIDIgb3ZlciA0IHNlY29uZHMuXG5cdFx0ICogc2lnbmFsLmV4cG9uZW50aWFsUmFtcFRvKDIsIDQpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYXJhbS5wcm90b3R5cGUuZXhwb25lbnRpYWxSYW1wVG8gPSBmdW5jdGlvbiAodmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcblx0ICAgICAgICBzdGFydFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuXHQgICAgICAgIHRoaXMuc2V0UmFtcFBvaW50KHN0YXJ0VGltZSk7XG5cdCAgICAgICAgdGhpcy5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBzdGFydFRpbWUgKyB0aGlzLnRvU2Vjb25kcyhyYW1wVGltZSkpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTY2hlZHVsZXMgYW4gbGluZWFyIGNvbnRpbnVvdXMgY2hhbmdlIGluIHBhcmFtZXRlciB2YWx1ZSBmcm9tXG5cdFx0ICogIHRoZSBjdXJyZW50IHRpbWUgYW5kIGN1cnJlbnQgdmFsdWUgdG8gdGhlIGdpdmVuIHZhbHVlIG92ZXIgdGhlXG5cdFx0ICogIGR1cmF0aW9uIG9mIHRoZSByYW1wVGltZS5cblx0XHQgKlxuXHRcdCAqICBAcGFyYW0gIHtudW1iZXJ9IHZhbHVlICAgVGhlIHZhbHVlIHRvIHJhbXAgdG8uXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IHJhbXBUaW1lIHRoZSB0aW1lIHRoYXQgaXQgdGFrZXMgdGhlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgdG8gcmFtcCBmcm9tIGl0J3MgY3VycmVudCB2YWx1ZVxuXHRcdCAqICBAcGFyYW0ge1RpbWV9XHRbc3RhcnRUaW1lPW5vd10gXHRXaGVuIHRoZSByYW1wIHNob3VsZCBzdGFydC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuUGFyYW19IHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL2xpbmVhcmx5IHJhbXAgdG8gdGhlIHZhbHVlIDQgb3ZlciAzIHNlY29uZHMuXG5cdFx0ICogc2lnbmFsLmxpbmVhclJhbXBUbyg0LCAzKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFyYW0ucHJvdG90eXBlLmxpbmVhclJhbXBUbyA9IGZ1bmN0aW9uICh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuXHQgICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG5cdCAgICAgICAgdGhpcy5zZXRSYW1wUG9pbnQoc3RhcnRUaW1lKTtcblx0ICAgICAgICB0aGlzLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBzdGFydFRpbWUgKyB0aGlzLnRvU2Vjb25kcyhyYW1wVGltZSkpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTdGFydCBleHBvbmVudGlhbGx5IGFwcHJvYWNoaW5nIHRoZSB0YXJnZXQgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuIFNpbmNlIGl0XG5cdFx0ICogIGlzIGFuIGV4cG9uZW50aWFsIGFwcHJvYWNoIGl0IHdpbGwgY29udGludWUgYXBwcm9hY2hpbmcgYWZ0ZXIgdGhlIHJhbXAgZHVyYXRpb24uIFRoZVxuXHRcdCAqICByYW1wVGltZSBpcyB0aGUgdGltZSB0aGF0IGl0IHRha2VzIHRvIHJlYWNoIG92ZXIgOTklIG9mIHRoZSB3YXkgdG93YXJkcyB0aGUgdmFsdWUuXG5cdFx0ICogIEBwYXJhbSAge251bWJlcn0gdmFsdWUgICBUaGUgdmFsdWUgdG8gcmFtcCB0by5cblx0XHQgKiAgQHBhcmFtICB7VGltZX0gcmFtcFRpbWUgdGhlIHRpbWUgdGhhdCBpdCB0YWtlcyB0aGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSB0byByYW1wIGZyb20gaXQncyBjdXJyZW50IHZhbHVlXG5cdFx0ICogIEBwYXJhbSB7VGltZX1cdFtzdGFydFRpbWU9bm93XSBcdFdoZW4gdGhlIHJhbXAgc2hvdWxkIHN0YXJ0LlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5QYXJhbX0gdGhpc1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vZXhwb25lbnRpYWxseSByYW1wIHRvIHRoZSB2YWx1ZSAyIG92ZXIgNCBzZWNvbmRzLlxuXHRcdCAqIHNpZ25hbC5leHBvbmVudGlhbFJhbXBUbygyLCA0KTtcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFyYW0ucHJvdG90eXBlLnRhcmdldFJhbXBUbyA9IGZ1bmN0aW9uICh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuXHQgICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG5cdCAgICAgICAgdGhpcy5zZXRSYW1wUG9pbnQoc3RhcnRUaW1lKTtcblx0ICAgICAgICB0aGlzLmV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lLCByYW1wVGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFN0YXJ0IGV4cG9uZW50aWFsbHkgYXBwcm9hY2hpbmcgdGhlIHRhcmdldCB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZS4gU2luY2UgaXRcblx0XHQgKiAgaXMgYW4gZXhwb25lbnRpYWwgYXBwcm9hY2ggaXQgd2lsbCBjb250aW51ZSBhcHByb2FjaGluZyBhZnRlciB0aGUgcmFtcCBkdXJhdGlvbi4gVGhlXG5cdFx0ICogIHJhbXBUaW1lIGlzIHRoZSB0aW1lIHRoYXQgaXQgdGFrZXMgdG8gcmVhY2ggb3ZlciA5OSUgb2YgdGhlIHdheSB0b3dhcmRzIHRoZSB2YWx1ZS4gVGhpcyBtZXRob2RzXG5cdFx0ICogIGlzIHNpbWlsYXIgdG8gc2V0VGFyZ2V0QXRUaW1lIGV4Y2VwdCB0aGUgdGhpcmQgYXJndW1lbnQgaXMgYSB0aW1lIGluc3RlYWQgb2YgYSAndGltZUNvbnN0YW50J1xuXHRcdCAqICBAcGFyYW0gIHtudW1iZXJ9IHZhbHVlICAgVGhlIHZhbHVlIHRvIHJhbXAgdG8uXG5cdFx0ICogIEBwYXJhbSB7VGltZX1cdHRpbWUgXHRXaGVuIHRoZSByYW1wIHNob3VsZCBzdGFydC5cblx0XHQgKiAgQHBhcmFtICB7VGltZX0gcmFtcFRpbWUgdGhlIHRpbWUgdGhhdCBpdCB0YWtlcyB0aGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSB0byByYW1wIGZyb20gaXQncyBjdXJyZW50IHZhbHVlXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBhcmFtfSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9leHBvbmVudGlhbGx5IHJhbXAgdG8gdGhlIHZhbHVlIDIgb3ZlciA0IHNlY29uZHMuXG5cdFx0ICogc2lnbmFsLmV4cG9uZW50aWFsUmFtcFRvKDIsIDQpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYXJhbS5wcm90b3R5cGUuZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lID0gZnVuY3Rpb24gKHZhbHVlLCB0aW1lLCByYW1wVGltZSkge1xuXHQgICAgICAgIHZhciB0aW1lQ29uc3RhbnQgPSBNYXRoLmxvZyh0aGlzLnRvU2Vjb25kcyhyYW1wVGltZSkgKyAxKSAvIE1hdGgubG9nKDIwMCk7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHJldHVybiB0aGlzLnNldFRhcmdldEF0VGltZSh2YWx1ZSwgdGltZSwgdGltZUNvbnN0YW50KTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU3RhcnQgZXhwb25lbnRpYWxseSBhcHByb2FjaGluZyB0aGUgdGFyZ2V0IHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lIHdpdGhcblx0XHQgKiAgYSByYXRlIGhhdmluZyB0aGUgZ2l2ZW4gdGltZSBjb25zdGFudC5cblx0XHQgKiAgQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gc3RhcnRUaW1lXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSB0aW1lQ29uc3RhbnRcblx0XHQgKiAgQHJldHVybnMge1RvbmUuUGFyYW19IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFyYW0ucHJvdG90eXBlLnNldFRhcmdldEF0VGltZSA9IGZ1bmN0aW9uICh2YWx1ZSwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpIHtcblx0ICAgICAgICB2YWx1ZSA9IHRoaXMuX2Zyb21Vbml0cyh2YWx1ZSk7XG5cdCAgICAgICAgLy8gVGhlIHZhbHVlIHdpbGwgbmV2ZXIgYmUgYWJsZSB0byBhcHByb2FjaCB3aXRob3V0IHRpbWVDb25zdGFudCA+IDAuXG5cdCAgICAgICAgaWYgKHRpbWVDb25zdGFudCA8PSAwKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndGltZUNvbnN0YW50IG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgc3RhcnRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcblx0ICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcblx0ICAgICAgICAgICAgJ3R5cGUnOiBUb25lLlBhcmFtLkF1dG9tYXRpb25UeXBlLlRhcmdldCxcblx0ICAgICAgICAgICAgJ3ZhbHVlJzogdmFsdWUsXG5cdCAgICAgICAgICAgICd0aW1lJzogc3RhcnRUaW1lLFxuXHQgICAgICAgICAgICAnY29uc3RhbnQnOiB0aW1lQ29uc3RhbnRcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0aGlzLl9wYXJhbS5zZXRUYXJnZXRBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU2V0cyBhbiBhcnJheSBvZiBhcmJpdHJhcnkgcGFyYW1ldGVyIHZhbHVlcyBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gdGltZVxuXHRcdCAqICBmb3IgdGhlIGdpdmVuIGR1cmF0aW9uLlxuXHRcdCAqXG5cdFx0ICogIEBwYXJhbSB7QXJyYXl9IHZhbHVlc1xuXHRcdCAqICBAcGFyYW0ge1RpbWV9IHN0YXJ0VGltZVxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IGR1cmF0aW9uXG5cdFx0ICogIEBwYXJhbSB7Tm9ybWFsUmFuZ2V9IFtzY2FsaW5nPTFdIElmIHRoZSB2YWx1ZXMgaW4gdGhlIGN1cnZlIHNob3VsZCBiZSBzY2FsZWQgYnkgc29tZSB2YWx1ZVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5QYXJhbX0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYXJhbS5wcm90b3R5cGUuc2V0VmFsdWVDdXJ2ZUF0VGltZSA9IGZ1bmN0aW9uICh2YWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24sIHNjYWxpbmcpIHtcblx0ICAgICAgICBzY2FsaW5nID0gVG9uZS5kZWZhdWx0QXJnKHNjYWxpbmcsIDEpO1xuXHQgICAgICAgIGR1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuXHQgICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG5cdCAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZSh2YWx1ZXNbMF0gKiBzY2FsaW5nLCBzdGFydFRpbWUpO1xuXHQgICAgICAgIHZhciBzZWdUaW1lID0gZHVyYXRpb24gLyAodmFsdWVzLmxlbmd0aCAtIDEpO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWVzW2ldICogc2NhbGluZywgc3RhcnRUaW1lICsgaSAqIHNlZ1RpbWUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2FuY2VscyBhbGwgc2NoZWR1bGVkIHBhcmFtZXRlciBjaGFuZ2VzIHdpdGggdGltZXMgZ3JlYXRlciB0aGFuIG9yXG5cdFx0ICogIGVxdWFsIHRvIHN0YXJ0VGltZS5cblx0XHQgKlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSB0aW1lXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBhcmFtfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlBhcmFtLnByb3RvdHlwZS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKHRpbWUpO1xuXHQgICAgICAgIHRoaXMuX3BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhpcyBpcyBzaW1pbGFyIHRvIFtjYW5jZWxTY2hlZHVsZWRWYWx1ZXNdKCNjYW5jZWxTY2hlZHVsZWRWYWx1ZXMpIGV4Y2VwdFxuXHRcdCAqICBpdCBob2xkcyB0aGUgYXV0b21hdGVkIHZhbHVlIGF0IHRpbWUgdW50aWwgdGhlIG5leHQgYXV0b21hdGVkIGV2ZW50LlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSB0aW1lXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBhcmFtfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlBhcmFtLnByb3RvdHlwZS5jYW5jZWxBbmRIb2xkQXRUaW1lID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB2YXIgdmFsdWVBdFRpbWUgPSB0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuXHQgICAgICAgIC8vaWYgdGhlcmUgaXMgYW4gZXZlbnQgYXQgdGhlIGdpdmVuIHRpbWVcblx0ICAgICAgICAvL2FuZCB0aGF0IGV2ZW4gaXMgbm90IGEgXCJzZXRcIlxuXHQgICAgICAgIHZhciBiZWZvcmUgPSB0aGlzLl9ldmVudHMuZ2V0KHRpbWUpO1xuXHQgICAgICAgIHZhciBhZnRlciA9IHRoaXMuX2V2ZW50cy5nZXRBZnRlcih0aW1lKTtcblx0ICAgICAgICBpZiAoYmVmb3JlICYmIGJlZm9yZS50aW1lID09PSB0aW1lKSB7XG5cdCAgICAgICAgICAgIC8vcmVtb3ZlIGV2ZXJ5dGhpbmcgYWZ0ZXJcblx0ICAgICAgICAgICAgaWYgKGFmdGVyKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKGFmdGVyLnRpbWUpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmNhbmNlbCh0aW1lICsgMC4wMDAwMDEpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSBlbHNlIGlmIChhZnRlcikge1xuXHQgICAgICAgICAgICAvL2NhbmNlbCB0aGUgbmV4dCBldmVudChzKVxuXHQgICAgICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKGFmdGVyLnRpbWUpO1xuXHQgICAgICAgICAgICBpZiAoIXRoaXMuX3BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBpZiAoYWZ0ZXIudHlwZSA9PT0gVG9uZS5QYXJhbS5BdXRvbWF0aW9uVHlwZS5MaW5lYXIpIHtcblx0ICAgICAgICAgICAgICAgIGlmICghdGhpcy5fcGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWVBdFRpbWUsIHRpbWUpO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgJ3R5cGUnOiBUb25lLlBhcmFtLkF1dG9tYXRpb25UeXBlLkxpbmVhcixcblx0ICAgICAgICAgICAgICAgICAgICAgICAgJ3ZhbHVlJzogdmFsdWVBdFRpbWUsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICd0aW1lJzogdGltZVxuXHQgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9IGVsc2UgaWYgKGFmdGVyLnR5cGUgPT09IFRvbmUuUGFyYW0uQXV0b21hdGlvblR5cGUuRXhwb25lbnRpYWwpIHtcblx0ICAgICAgICAgICAgICAgIGlmICghdGhpcy5fcGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZUF0VGltZSwgdGltZSk7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoe1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAndHlwZSc6IFRvbmUuUGFyYW0uQXV0b21hdGlvblR5cGUuRXhwb25lbnRpYWwsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICd2YWx1ZSc6IHZhbHVlQXRUaW1lLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAndGltZSc6IHRpbWVcblx0ICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICAvL3NldCB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWVcblx0ICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcblx0ICAgICAgICAgICAgJ3R5cGUnOiBUb25lLlBhcmFtLkF1dG9tYXRpb25UeXBlLlNldFZhbHVlLFxuXHQgICAgICAgICAgICAndmFsdWUnOiB2YWx1ZUF0VGltZSxcblx0ICAgICAgICAgICAgJ3RpbWUnOiB0aW1lXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgaWYgKHRoaXMuX3BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0aGlzLl9wYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZUF0VGltZSwgdGltZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSYW1wcyB0byB0aGUgZ2l2ZW4gdmFsdWUgb3ZlciB0aGUgZHVyYXRpb24gb2YgdGhlIHJhbXBUaW1lLlxuXHRcdCAqICBBdXRvbWF0aWNhbGx5IHNlbGVjdHMgdGhlIGJlc3QgcmFtcCB0eXBlIChleHBvbmVudGlhbCBvciBsaW5lYXIpXG5cdFx0ICogIGRlcGVuZGluZyBvbiB0aGUgYHVuaXRzYCBvZiB0aGUgc2lnbmFsXG5cdFx0ICpcblx0XHQgKiAgQHBhcmFtICB7bnVtYmVyfSB2YWx1ZVxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSByYW1wVGltZSBcdFRoZSB0aW1lIHRoYXQgaXQgdGFrZXMgdGhlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSB0byByYW1wIGZyb20gaXQncyBjdXJyZW50IHZhbHVlXG5cdFx0ICogIEBwYXJhbSB7VGltZX1cdFtzdGFydFRpbWU9bm93XSBcdFdoZW4gdGhlIHJhbXAgc2hvdWxkIHN0YXJ0LlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5QYXJhbX0gdGhpc1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vcmFtcCB0byB0aGUgdmFsdWUgZWl0aGVyIGxpbmVhcmx5IG9yIGV4cG9uZW50aWFsbHlcblx0XHQgKiAvL2RlcGVuZGluZyBvbiB0aGUgXCJ1bml0c1wiIHZhbHVlIG9mIHRoZSBzaWduYWxcblx0XHQgKiBzaWduYWwucmFtcFRvKDAsIDEwKTtcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL3NjaGVkdWxlIGl0IHRvIHJhbXAgc3RhcnRpbmcgYXQgYSBzcGVjaWZpYyB0aW1lXG5cdFx0ICogc2lnbmFsLnJhbXBUbygwLCAxMCwgNSlcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFyYW0ucHJvdG90eXBlLnJhbXBUbyA9IGZ1bmN0aW9uICh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuXHQgICAgICAgIHJhbXBUaW1lID0gVG9uZS5kZWZhdWx0QXJnKHJhbXBUaW1lLCAwLjEpO1xuXHQgICAgICAgIGlmICh0aGlzLnVuaXRzID09PSBUb25lLlR5cGUuRnJlcXVlbmN5IHx8IHRoaXMudW5pdHMgPT09IFRvbmUuVHlwZS5CUE0gfHwgdGhpcy51bml0cyA9PT0gVG9uZS5UeXBlLkRlY2liZWxzKSB7XG5cdCAgICAgICAgICAgIHRoaXMuZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvL1x0QVVUT01BVElPTiBDVVJWRSBDQUxDVUxBVElPTlNcblx0ICAgIC8vXHRNSVQgTGljZW5zZSwgY29weXJpZ2h0IChjKSAyMDE0IEpvcmRhbiBTYW50ZWxsXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vIENhbGN1bGF0ZXMgdGhlIHRoZSB2YWx1ZSBhbG9uZyB0aGUgY3VydmUgcHJvZHVjZWQgYnkgc2V0VGFyZ2V0QXRUaW1lXG5cdCAgICBUb25lLlBhcmFtLnByb3RvdHlwZS5fZXhwb25lbnRpYWxBcHByb2FjaCA9IGZ1bmN0aW9uICh0MCwgdjAsIHYxLCB0aW1lQ29uc3RhbnQsIHQpIHtcblx0ICAgICAgICByZXR1cm4gdjEgKyAodjAgLSB2MSkgKiBNYXRoLmV4cCgtKHQgLSB0MCkgLyB0aW1lQ29uc3RhbnQpO1xuXHQgICAgfTtcblx0ICAgIC8vIENhbGN1bGF0ZXMgdGhlIHRoZSB2YWx1ZSBhbG9uZyB0aGUgY3VydmUgcHJvZHVjZWQgYnkgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcblx0ICAgIFRvbmUuUGFyYW0ucHJvdG90eXBlLl9saW5lYXJJbnRlcnBvbGF0ZSA9IGZ1bmN0aW9uICh0MCwgdjAsIHQxLCB2MSwgdCkge1xuXHQgICAgICAgIHJldHVybiB2MCArICh2MSAtIHYwKSAqICgodCAtIHQwKSAvICh0MSAtIHQwKSk7XG5cdCAgICB9O1xuXHQgICAgLy8gQ2FsY3VsYXRlcyB0aGUgdGhlIHZhbHVlIGFsb25nIHRoZSBjdXJ2ZSBwcm9kdWNlZCBieSBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lXG5cdCAgICBUb25lLlBhcmFtLnByb3RvdHlwZS5fZXhwb25lbnRpYWxJbnRlcnBvbGF0ZSA9IGZ1bmN0aW9uICh0MCwgdjAsIHQxLCB2MSwgdCkge1xuXHQgICAgICAgIHJldHVybiB2MCAqIE1hdGgucG93KHYxIC8gdjAsICh0IC0gdDApIC8gKHQxIC0gdDApKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXBcblx0XHQgKiAgQHJldHVybnMge1RvbmUuUGFyYW19IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFyYW0ucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9wYXJhbSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fZXZlbnRzID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5QYXJhbTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBXcmFwcGVyIGFyb3VuZCB0aGUgT2ZmbGluZUF1ZGlvQ29udGV4dFxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5Db250ZXh0fVxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICBjaGFubmVscyAgVGhlIG51bWJlciBvZiBjaGFubmVscyB0byByZW5kZXJcblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgZHVyYXRpb24gIFRoZSBkdXJhdGlvbiB0byByZW5kZXIgaW4gc2FtcGxlc1xuXHRcdCAqICBAcGFyYW0ge051bWJlcn0gc2FtcGxlUmF0ZSB0aGUgc2FtcGxlIHJhdGUgdG8gcmVuZGVyIGF0XG5cdFx0ICovXG5cdCAgICBUb25lLk9mZmxpbmVDb250ZXh0ID0gZnVuY3Rpb24gKGNoYW5uZWxzLCBkdXJhdGlvbiwgc2FtcGxlUmF0ZSkge1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBvZmZsaW5lIGNvbnRleHRcblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICogIEB0eXBlICB7T2ZmbGluZUF1ZGlvQ29udGV4dH1cblx0XHRcdCAqL1xuXHQgICAgICAgIHZhciBvZmZsaW5lQ29udGV4dCA9IG5ldyBPZmZsaW5lQXVkaW9Db250ZXh0KGNoYW5uZWxzLCBkdXJhdGlvbiAqIHNhbXBsZVJhdGUsIHNhbXBsZVJhdGUpO1xuXHQgICAgICAgIC8vd3JhcCB0aGUgbWV0aG9kcy9tZW1iZXJzXG5cdCAgICAgICAgVG9uZS5Db250ZXh0LmNhbGwodGhpcywge1xuXHQgICAgICAgICAgICAnY29udGV4dCc6IG9mZmxpbmVDb250ZXh0LFxuXHQgICAgICAgICAgICAnY2xvY2tTb3VyY2UnOiAnb2ZmbGluZScsXG5cdCAgICAgICAgICAgICdsb29rQWhlYWQnOiAwLFxuXHQgICAgICAgICAgICAndXBkYXRlSW50ZXJ2YWwnOiAxMjggLyBzYW1wbGVSYXRlXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQSBwcml2YXRlIHJlZmVyZW5jZSB0byB0aGUgZHVyYXRpb25cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICogIEB0eXBlICB7TnVtYmVyfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZHVyYXRpb24gPSBkdXJhdGlvbjtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBBbiBhcnRpZmljaWFsIGNsb2NrIHNvdXJjZVxuXHRcdFx0ICogIEB0eXBlICB7TnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9jdXJyZW50VGltZSA9IDA7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5PZmZsaW5lQ29udGV4dCwgVG9uZS5Db250ZXh0KTtcblx0ICAgIC8qKlxuXHRcdCAqICBPdmVycmlkZSB0aGUgbm93IG1ldGhvZCB0byBwb2ludCB0byB0aGUgaW50ZXJuYWwgY2xvY2sgdGltZVxuXHRcdCAqICBAcmV0dXJuICB7TnVtYmVyfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5PZmZsaW5lQ29udGV4dC5wcm90b3R5cGUubm93ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9jdXJyZW50VGltZTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmVuZGVyIHRoZSBvdXRwdXQgb2YgdGhlIE9mZmxpbmVDb250ZXh0XG5cdFx0ICogIEByZXR1cm4gIHtQcm9taXNlfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5PZmZsaW5lQ29udGV4dC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHdoaWxlICh0aGlzLl9kdXJhdGlvbiAtIHRoaXMuX2N1cnJlbnRUaW1lID49IDApIHtcblx0ICAgICAgICAgICAgLy9pbnZva2UgYWxsIHRoZSBjYWxsYmFja3Mgb24gdGhhdCB0aW1lXG5cdCAgICAgICAgICAgIHRoaXMuZW1pdCgndGljaycpO1xuXHQgICAgICAgICAgICAvL2luY3JlbWVudCB0aGUgY2xvY2tcblx0ICAgICAgICAgICAgdGhpcy5fY3VycmVudFRpbWUgKz0gdGhpcy5ibG9ja1RpbWU7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LnN0YXJ0UmVuZGVyaW5nKCk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsb3NlIHRoZSBjb250ZXh0XG5cdFx0ICogIEByZXR1cm4gIHtQcm9taXNlfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5PZmZsaW5lQ29udGV4dC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fY29udGV4dCA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLk9mZmxpbmVDb250ZXh0O1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBpZiAoVG9uZS5zdXBwb3J0ZWQpIHtcblx0ICAgICAgICB2YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7XG5cdCAgICAgICAgdmFyIGlzTW9iaWxlU2FmYXJpID0gdWEuaW5jbHVkZXMoJ3NhZmFyaScpICYmICF1YS5pbmNsdWRlcygnY2hyb21lJykgJiYgdWEuaW5jbHVkZXMoJ21vYmlsZScpO1xuXHQgICAgICAgIGlmIChpc01vYmlsZVNhZmFyaSkge1xuXHQgICAgICAgICAgICAvL21vYmlsZSBzYWZhcmkgaGFzIGEgYml6YXJyZSBidWcgd2l0aCB0aGUgb2ZmbGluZSBjb250ZXh0XG5cdCAgICAgICAgICAgIC8vd2hlbiBhIEJ1ZmZlclNvdXJjZU5vZGUgaXMgc3RhcnRlZCwgaXQgc3RhcnRzIHRoZSBvZmZsaW5lIGNvbnRleHRcblx0ICAgICAgICAgICAgLy9cblx0ICAgICAgICAgICAgLy9kZWZlcnJpbmcgYWxsIEJ1ZmZlclNvdXJjZSBzdGFydHMgdGlsbCB0aGUgbGFzdCBwb3NzaWJsZSBtb21lbnRcblx0ICAgICAgICAgICAgLy9yZWR1Y2VzIHRoZSBsaWtlbGlob29kIG9mIHRoaXMgaGFwcGVuaW5nXG5cdCAgICAgICAgICAgIFRvbmUuT2ZmbGluZUNvbnRleHQucHJvdG90eXBlLmNyZWF0ZUJ1ZmZlclNvdXJjZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBidWZmZXJTb3VyY2UgPSB0aGlzLl9jb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuXHQgICAgICAgICAgICAgICAgdmFyIF9uYXRpdmVfc3RhcnQgPSBidWZmZXJTb3VyY2Uuc3RhcnQ7XG5cdCAgICAgICAgICAgICAgICBidWZmZXJTb3VyY2Uuc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIF9uYXRpdmVfc3RhcnQuY2FsbChidWZmZXJTb3VyY2UsIHRpbWUpO1xuXHQgICAgICAgICAgICAgICAgICAgIH0uYmluZCh0aGlzKSwgMCk7XG5cdCAgICAgICAgICAgICAgICB9LmJpbmQodGhpcyk7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gYnVmZmVyU291cmNlO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIEEgdGhpbiB3cmFwcGVyIGFyb3VuZCB0aGUgTmF0aXZlIFdlYiBBdWRpbyBHYWluTm9kZS5cblx0XHQgKiAgICAgICAgIFRoZSBHYWluTm9kZSBpcyBhIGJhc2ljIGJ1aWxkaW5nIGJsb2NrIG9mIHRoZSBXZWIgQXVkaW9cblx0XHQgKiAgICAgICAgIEFQSSBhbmQgaXMgdXNlZnVsIGZvciByb3V0aW5nIGF1ZGlvIGFuZCBhZGp1c3RpbmcgZ2FpbnMuXG5cdFx0ICogIEBleHRlbmRzIHtUb25lfVxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXI9fSAgZ2FpbiAgVGhlIGluaXRpYWwgZ2FpbiBvZiB0aGUgR2Fpbk5vZGVcblx0XHQgKiAgQHBhcmFtIHtUb25lLlR5cGU9fSB1bml0cyBUaGUgdW5pdHMgb2YgdGhlIGdhaW4gcGFyYW1ldGVyLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5HYWluID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ2dhaW4nLFxuXHQgICAgICAgICAgICAndW5pdHMnXG5cdCAgICAgICAgXSwgVG9uZS5HYWluKTtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBHYWluTm9kZVxuXHRcdFx0ICogIEB0eXBlICB7R2Fpbk5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuX2dhaW5Ob2RlID0gdGhpcy5jb250ZXh0LmNyZWF0ZUdhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZ2FpbiBwYXJhbWV0ZXIgb2YgdGhlIGdhaW4gbm9kZS5cblx0XHRcdCAqICBAdHlwZSB7R2Fpbn1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmdhaW4gPSBuZXcgVG9uZS5QYXJhbSh7XG5cdCAgICAgICAgICAgICdwYXJhbSc6IHRoaXMuX2dhaW5Ob2RlLmdhaW4sXG5cdCAgICAgICAgICAgICd1bml0cyc6IG9wdGlvbnMudW5pdHMsXG5cdCAgICAgICAgICAgICd2YWx1ZSc6IG9wdGlvbnMuZ2Fpbixcblx0ICAgICAgICAgICAgJ2NvbnZlcnQnOiBvcHRpb25zLmNvbnZlcnRcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seSgnZ2FpbicpO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuR2FpbiwgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0c1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkdhaW4uZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2dhaW4nOiAxLFxuXHQgICAgICAgICdjb252ZXJ0JzogdHJ1ZVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybiAge1RvbmUuR2Fpbn0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuR2Fpbi5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcblx0ICAgICAgICB0aGlzLl9nYWluTm9kZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoJ2dhaW4nKTtcblx0ICAgICAgICB0aGlzLmdhaW4uZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZ2FpbiA9IG51bGw7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuR2Fpbjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgaWYgKFRvbmUuc3VwcG9ydGVkICYmICFBdWRpb0NvbnRleHQucHJvdG90eXBlLmNyZWF0ZUNvbnN0YW50U291cmNlKSB7XG5cdCAgICAgICAgdmFyIENvbnN0YW50U291cmNlTm9kZSA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG5cdCAgICAgICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG5cdCAgICAgICAgICAgIHZhciBidWZmZXIgPSBjb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAxMjgsIGNvbnRleHQuc2FtcGxlUmF0ZSk7XG5cdCAgICAgICAgICAgIHZhciBhcnIgPSBidWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBhcnJbaV0gPSAxO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuX2J1ZmZlclNvdXJjZSA9IGNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG5cdCAgICAgICAgICAgIHRoaXMuX2J1ZmZlclNvdXJjZS5jaGFubmVsQ291bnQgPSAxO1xuXHQgICAgICAgICAgICB0aGlzLl9idWZmZXJTb3VyY2UuY2hhbm5lbENvdW50TW9kZSA9ICdleHBsaWNpdCc7XG5cdCAgICAgICAgICAgIHRoaXMuX2J1ZmZlclNvdXJjZS5idWZmZXIgPSBidWZmZXI7XG5cdCAgICAgICAgICAgIHRoaXMuX2J1ZmZlclNvdXJjZS5sb29wID0gdHJ1ZTtcblx0ICAgICAgICAgICAgdmFyIGdhaW5Ob2RlID0gdGhpcy5fb3V0cHV0ID0gY29udGV4dC5jcmVhdGVHYWluKCk7XG5cdCAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gZ2Fpbk5vZGUuZ2Fpbjtcblx0ICAgICAgICAgICAgdGhpcy5fYnVmZmVyU291cmNlLmNvbm5lY3QoZ2Fpbk5vZGUpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgQ29uc3RhbnRTb3VyY2VOb2RlLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2J1ZmZlclNvdXJjZS5zdGFydCh0aW1lKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICBDb25zdGFudFNvdXJjZU5vZGUucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9idWZmZXJTb3VyY2Uuc3RvcCh0aW1lKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICBDb25zdGFudFNvdXJjZU5vZGUucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX291dHB1dC5jb25uZWN0LmFwcGx5KHRoaXMuX291dHB1dCwgYXJndW1lbnRzKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICBDb25zdGFudFNvdXJjZU5vZGUucHJvdG90eXBlLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX291dHB1dC5kaXNjb25uZWN0LmFwcGx5KHRoaXMuX291dHB1dCwgYXJndW1lbnRzKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICBBdWRpb0NvbnRleHQucHJvdG90eXBlLmNyZWF0ZUNvbnN0YW50U291cmNlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gbmV3IENvbnN0YW50U291cmNlTm9kZSh0aGlzKTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIFRvbmUuQ29udGV4dC5wcm90b3R5cGUuY3JlYXRlQ29uc3RhbnRTb3VyY2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgQ29uc3RhbnRTb3VyY2VOb2RlKHRoaXMpO1xuXHQgICAgICAgIH07XG5cdCAgICB9XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgQSBzaWduYWwgaXMgYW4gYXVkaW8tcmF0ZSB2YWx1ZS4gVG9uZS5TaWduYWwgaXMgYSBjb3JlIGNvbXBvbmVudCBvZiB0aGUgbGlicmFyeS5cblx0XHQgKiAgICAgICAgICBVbmxpa2UgYSBudW1iZXIsIFNpZ25hbHMgY2FuIGJlIHNjaGVkdWxlZCB3aXRoIHNhbXBsZS1sZXZlbCBhY2N1cmFjeS4gVG9uZS5TaWduYWxcblx0XHQgKiAgICAgICAgICBoYXMgYWxsIG9mIHRoZSBtZXRob2RzIGF2YWlsYWJsZSB0byBuYXRpdmUgV2ViIEF1ZGlvXG5cdFx0ICogICAgICAgICAgW0F1ZGlvUGFyYW1dKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jdGhlLWF1ZGlvcGFyYW0taW50ZXJmYWNlKVxuXHRcdCAqICAgICAgICAgIGFzIHdlbGwgYXMgYWRkaXRpb25hbCBjb252ZW5pZW5jZXMuIFJlYWQgbW9yZSBhYm91dCB3b3JraW5nIHdpdGggc2lnbmFsc1xuXHRcdCAqICAgICAgICAgIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vVG9uZWpzL1RvbmUuanMvd2lraS9TaWduYWxzKS5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuUGFyYW19XG5cdFx0ICogIEBwYXJhbSB7TnVtYmVyfEF1ZGlvUGFyYW19IFt2YWx1ZV0gSW5pdGlhbCB2YWx1ZSBvZiB0aGUgc2lnbmFsLiBJZiBhbiBBdWRpb1BhcmFtXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgcGFzc2VkIGluLCB0aGF0IHBhcmFtZXRlciB3aWxsIGJlIHdyYXBwZWRcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgY29udHJvbGxlZCBieSB0aGUgU2lnbmFsLlxuXHRcdCAqICBAcGFyYW0ge3N0cmluZ30gW3VuaXRzPU51bWJlcl0gdW5pdCBUaGUgdW5pdHMgdGhlIHNpZ25hbCBpcyBpbi5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKDEwKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuU2lnbmFsID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ3ZhbHVlJyxcblx0ICAgICAgICAgICAgJ3VuaXRzJ1xuXHQgICAgICAgIF0sIFRvbmUuU2lnbmFsKTtcblx0ICAgICAgICBUb25lLlBhcmFtLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQqIFdoZW4gYSBzaWduYWwgaXMgY29ubmVjdGVkIHRvIGFub3RoZXIgc2lnbmFsIG9yIGF1ZGlvIHBhcmFtLFxuXHRcdFx0KiB0aGlzIHNpZ25hbCBiZWNvbWVzIGEgcHJveHkgZm9yIGl0XG5cdFx0XHQqIEB0eXBlIHtBcnJheX1cblx0XHRcdCogQHByaXZhdGVcblx0XHRcdCovXG5cdCAgICAgICAgdGhpcy5fcHJveGllcyA9IFtdO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0KiBJbmRpY2F0ZXMgaWYgdGhlIGNvbnN0YW50IHNvdXJjZSB3YXMgc3RhcnRlZCBvciBub3Rcblx0XHRcdCogQHByaXZhdGVcblx0XHRcdCogQHR5cGUge0Jvb2xlYW59XG5cdFx0XHQqL1xuXHQgICAgICAgIHRoaXMuX3NvdXJjZVN0YXJ0ZWQgPSBmYWxzZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBjb25zdGFudCBzb3VyY2Ugbm9kZSB3aGljaCBnZW5lcmF0ZXMgdGhlIHNpZ25hbFxuXHRcdFx0ICogQHR5cGUge0NvbnN0YW50U291cmNlTm9kZX1cblx0XHRcdCAqIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZSA9IHRoaXMuY29udGV4dC5jcmVhdGVDb25zdGFudFNvdXJjZSgpO1xuXHQgICAgICAgIHRoaXMuX3BhcmFtID0gdGhpcy5fY29uc3RhbnRTb3VyY2Uub2Zmc2V0O1xuXHQgICAgICAgIHRoaXMudmFsdWUgPSBvcHRpb25zLnZhbHVlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIG5vZGUgd2hlcmUgdGhlIGNvbnN0YW50IHNpZ25hbCB2YWx1ZSBpcyBzY2FsZWQuXG5cdFx0XHQgKiBAdHlwZSB7R2Fpbk5vZGV9XG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9jb25zdGFudFNvdXJjZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBub2RlIHdoZXJlIHRoZSB2YWx1ZSBpcyBzZXQuXG5cdFx0XHQgKiBAdHlwZSB7VG9uZS5QYXJhbX1cblx0XHRcdCAqIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fcGFyYW0gPSB0aGlzLm91dHB1dC5vZmZzZXQ7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5TaWduYWwsIFRvbmUuUGFyYW0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0IHZhbHVlc1xuXHRcdCAqICBAdHlwZSAge09iamVjdH1cblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKi9cblx0ICAgIFRvbmUuU2lnbmFsLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICd2YWx1ZSc6IDAsXG5cdCAgICAgICAgJ3VuaXRzJzogVG9uZS5UeXBlLkRlZmF1bHQsXG5cdCAgICAgICAgJ2NvbnZlcnQnOiB0cnVlXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFdoZW4gc2lnbmFscyBjb25uZWN0IHRvIG90aGVyIHNpZ25hbHMgb3IgQXVkaW9QYXJhbXMsXG5cdFx0ICogIHRoZXkgdGFrZSBvdmVyIHRoZSBvdXRwdXQgdmFsdWUgb2YgdGhhdCBzaWduYWwgb3IgQXVkaW9QYXJhbS5cblx0XHQgKiAgRm9yIGFsbCBvdGhlciBub2RlcywgdGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIGEgZGVmYXVsdCA8Y29kZT5jb25uZWN0PC9jb2RlPi5cblx0XHQgKlxuXHRcdCAqICBAb3ZlcnJpZGVcblx0XHQgKiAgQHBhcmFtIHtBdWRpb1BhcmFtfEF1ZGlvTm9kZXxUb25lLlNpZ25hbHxUb25lfSBub2RlXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSBbb3V0cHV0TnVtYmVyPTBdIFRoZSBvdXRwdXQgbnVtYmVyIHRvIGNvbm5lY3QgZnJvbS5cblx0XHQgKiAgQHBhcmFtIHtudW1iZXJ9IFtpbnB1dE51bWJlcj0wXSBUaGUgaW5wdXQgbnVtYmVyIHRvIGNvbm5lY3QgdG8uXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlNpZ25hbH0gdGhpc1xuXHRcdCAqICBAbWV0aG9kXG5cdFx0ICovXG5cdCAgICBUb25lLlNpZ25hbC5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uIChub2RlKSB7XG5cdCAgICAgICAgLy90aGlzIGlzIGFuIG9wdGltaXphdGlvbiB3aGVyZSB0aGlzIG5vZGUgd2lsbCBmb3J3YXJkIGF1dG9tYXRpb25zXG5cdCAgICAgICAgLy90byBjb25uZWN0ZWQgbm9kZXMgd2l0aG91dCBhbnkgc2lnbmFsIGlmIHBvc3NpYmxlLlxuXHQgICAgICAgIGlmICh0aGlzLl9pc1BhcmFtKG5vZGUpICYmICF0aGlzLl9zb3VyY2VTdGFydGVkKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3Byb3hpZXMucHVzaChub2RlKTtcblx0ICAgICAgICAgICAgbm9kZS5vdmVycmlkZGVuID0gdHJ1ZTtcblx0ICAgICAgICAgICAgdGhpcy5fYXBwbHlBdXRvbWF0aW9ucyhub2RlKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBUb25lLlNpZ25hbEJhc2UucHJvdG90eXBlLmNvbm5lY3QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0ICAgICAgICAgICAgaWYgKCF0aGlzLl9zb3VyY2VTdGFydGVkKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9zb3VyY2VTdGFydGVkID0gdHJ1ZTtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLnN0YXJ0KDApO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFRha2VzIGEgbm9kZSBhcyBhbiBhcmd1bWVudCBhbmQgcmV0dXJucyBpZiBpdCBpcyBhIFBhcmFtIG9yIEF1ZGlvUGFyYW1cblx0XHQgKiBAcGFyYW0gIHsqfSBub2RlIFRoZSBub2RlIHRvIHRlc3Rcblx0XHQgKiBAcmV0dXJuIHtCb29sZWFufVxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlNpZ25hbC5wcm90b3R5cGUuX2lzUGFyYW0gPSBmdW5jdGlvbiAobm9kZSkge1xuXHQgICAgICAgIHJldHVybiBUb25lLlBhcmFtICYmIFRvbmUuUGFyYW0gPT09IG5vZGUuY29uc3RydWN0b3IgfHwgbm9kZSBpbnN0YW5jZW9mIEF1ZGlvUGFyYW07XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogRGlzY2FyZCB0aGUgb3B0aW1pemF0aW9uIGFuZCBjb25uZWN0IGFsbCBvZiB0aGUgcHJveGllc1xuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlNpZ25hbC5wcm90b3R5cGUuX2Nvbm5lY3RQcm94aWVzID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGlmICghdGhpcy5fc291cmNlU3RhcnRlZCkge1xuXHQgICAgICAgICAgICB0aGlzLl9zb3VyY2VTdGFydGVkID0gdHJ1ZTtcblx0ICAgICAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2Uuc3RhcnQoMCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuX3Byb3hpZXMuZm9yRWFjaChmdW5jdGlvbiAocHJveHkpIHtcblx0ICAgICAgICAgICAgVG9uZS5TaWduYWxCYXNlLnByb3RvdHlwZS5jb25uZWN0LmNhbGwodGhpcywgcHJveHkpO1xuXHQgICAgICAgICAgICBpZiAocHJveHkuX3Byb3hpZXMpIHtcblx0ICAgICAgICAgICAgICAgIHByb3h5Ll9jb25uZWN0UHJveGllcygpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBJbnZva2VkIHdoZW4gYSBub2RlIGlzIGNvbm5lY3RlZCB0byB0aGlzXG5cdFx0ICogQHBhcmFtICB7QXVkaW9Ob2RlfSBmcm9tXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuU2lnbmFsLnByb3RvdHlwZS5fb25Db25uZWN0ID0gZnVuY3Rpb24gKGZyb20pIHtcblx0ICAgICAgICBpZiAoIXRoaXMuX2lzUGFyYW0oZnJvbSkpIHtcblx0ICAgICAgICAgICAgLy9jb25uZWN0IGFsbCB0aGUgcHJveGllc1xuXHQgICAgICAgICAgICB0aGlzLl9jb25uZWN0UHJveGllcygpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBBcHBseSBhbGwgdGhlIGN1cnJlbnQgYXV0b21hdGlvbnMgdG8gdGhlIGdpdmVuIHBhcmFtZXRlclxuXHRcdCAqIEBwYXJhbSAge0F1ZGlvUGFyYW19IHBhcmFtXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuU2lnbmFsLnByb3RvdHlwZS5fYXBwbHlBdXRvbWF0aW9ucyA9IGZ1bmN0aW9uIChwYXJhbSkge1xuXHQgICAgICAgIHZhciBub3cgPSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XG5cdCAgICAgICAgcGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKG5vdyk7XG5cdCAgICAgICAgdmFyIGN1cnJlbnRWYWwgPSB0aGlzLmdldFZhbHVlQXRUaW1lKG5vdyk7XG5cdCAgICAgICAgcGFyYW0uc2V0VmFsdWVBdFRpbWUoY3VycmVudFZhbCwgbm93KTtcblx0ICAgICAgICB0aGlzLl9ldmVudHMuZm9yRWFjaEZyb20obm93LCBmdW5jdGlvbiAoZXZlbnQpIHtcblx0ICAgICAgICAgICAgcGFyYW1bZXZlbnQudHlwZV0oZXZlbnQudmFsdWUsIGV2ZW50LnRpbWUsIGV2ZW50LmNvbnN0YW50KTtcblx0ICAgICAgICB9KTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBEaXNjb25uZWN0IGZyb20gdGhlIGdpdmVuIG5vZGUgb3IgYWxsIG5vZGVzIGlmIG5vIHBhcmFtIGlzIGdpdmVuLlxuXHRcdCAqIEBwYXJhbSAge0F1ZGlvTm9kZXxBdWRpb1BhcmFtfSBub2RlXG5cdFx0ICogQHJldHVybiB7VG9uZS5TaWduYWx9ICAgICAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5TaWduYWwucHJvdG90eXBlLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbiAobm9kZSkge1xuXHQgICAgICAgIGlmICh0aGlzLl9wcm94aWVzLmluY2x1ZGVzKG5vZGUpKSB7XG5cdCAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX3Byb3hpZXMuaW5kZXhPZihub2RlKTtcblx0ICAgICAgICAgICAgdGhpcy5fcHJveGllcy5zcGxpY2UoaW5kZXgsIDEpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAoIW5vZGUpIHtcblx0ICAgICAgICAgICAgLy9ubyBhcmd1bWVudCwgZGlzY29ubmVjdCBldmVyeXRoaW5nXG5cdCAgICAgICAgICAgIHRoaXMuX3Byb3hpZXMgPSBbXTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIFRvbmUuU2lnbmFsQmFzZS5wcm90b3R5cGUuZGlzY29ubmVjdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFJldHVybiB0aGUgY3VycmVudCBzaWduYWwgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogQHBhcmFtICB7VGltZX0gdGltZSBXaGVuIHRvIGdldCB0aGUgc2lnbmFsIHZhbHVlXG5cdFx0ICogQHJldHVybiB7TnVtYmVyfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5TaWduYWwucHJvdG90eXBlLmdldFZhbHVlQXRUaW1lID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICBpZiAodGhpcy5fcGFyYW0uZ2V0VmFsdWVBdFRpbWUpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHJldHVybiBUb25lLlBhcmFtLnByb3RvdHlwZS5nZXRWYWx1ZUF0VGltZS5jYWxsKHRoaXMsIHRpbWUpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvL3dyYXAgYWxsIG9mIHRoZSBhdXRvbWF0aW9uIG1ldGhvZHNcblx0ICAgIFtcblx0ICAgICAgICAnc2V0VmFsdWVBdFRpbWUnLFxuXHQgICAgICAgICdsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZScsXG5cdCAgICAgICAgJ2V4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUnLFxuXHQgICAgICAgICdzZXRUYXJnZXRBdFRpbWUnXG5cdCAgICBdLmZvckVhY2goZnVuY3Rpb24gKG1ldGhvZCkge1xuXHQgICAgICAgIHZhciBwcmV2aW91c01ldGhvZCA9IFRvbmUuU2lnbmFsLnByb3RvdHlwZVttZXRob2RdO1xuXHQgICAgICAgIFRvbmUuU2lnbmFsLnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcblx0ICAgICAgICAgICAgcHJldmlvdXNNZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0ICAgICAgICAgICAgYXJnc1swXSA9IHRoaXMuX2Zyb21Vbml0cyhhcmdzWzBdKTtcblx0ICAgICAgICAgICAgYXJnc1sxXSA9IHRoaXMudG9TZWNvbmRzKGFyZ3NbMV0pO1xuXHQgICAgICAgICAgICAvL2FwcGx5IGl0IHRvIHRoZSBwcm94aWVzXG5cdCAgICAgICAgICAgIHRoaXMuX3Byb3hpZXMuZm9yRWFjaChmdW5jdGlvbiAoc2lnbmFsKSB7XG5cdCAgICAgICAgICAgICAgICBzaWduYWxbbWV0aG9kXS5hcHBseShzaWduYWwsIGFyZ3MpO1xuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgfSk7XG5cdCAgICBbXG5cdCAgICAgICAgJ2NhbmNlbFNjaGVkdWxlZFZhbHVlcycsXG5cdCAgICAgICAgJ2NhbmNlbEFuZEhvbGRBdFRpbWUnXG5cdCAgICBdLmZvckVhY2goZnVuY3Rpb24gKG1ldGhvZCkge1xuXHQgICAgICAgIHZhciBwcmV2aW91c01ldGhvZCA9IFRvbmUuU2lnbmFsLnByb3RvdHlwZVttZXRob2RdO1xuXHQgICAgICAgIFRvbmUuU2lnbmFsLnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcblx0ICAgICAgICAgICAgcHJldmlvdXNNZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0ICAgICAgICAgICAgYXJnc1swXSA9IHRoaXMudG9TZWNvbmRzKGFyZ3NbMF0pO1xuXHQgICAgICAgICAgICAvL2FwcGx5IGl0IHRvIHRoZSBwcm94aWVzXG5cdCAgICAgICAgICAgIHRoaXMuX3Byb3hpZXMuZm9yRWFjaChmdW5jdGlvbiAoc2lnbmFsKSB7XG5cdCAgICAgICAgICAgICAgICBzaWduYWxbbWV0aG9kXS5hcHBseShzaWduYWwsIGFyZ3MpO1xuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgZGlzcG9zZSBhbmQgZGlzY29ubmVjdFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5TaWduYWx9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuU2lnbmFsLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuUGFyYW0ucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2UgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3Byb3hpZXMgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlNpZ25hbDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFBvdyBhcHBsaWVzIGFuIGV4cG9uZW50IHRvIHRoZSBpbmNvbWluZyBzaWduYWwuIFRoZSBpbmNvbWluZyBzaWduYWxcblx0XHQgKiAgICAgICAgIG11c3QgYmUgQXVkaW9SYW5nZS5cblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5TaWduYWxCYXNlfVxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQHBhcmFtIHtQb3NpdGl2ZX0gZXhwIFRoZSBleHBvbmVudCB0byBhcHBseSB0byB0aGUgaW5jb21pbmcgc2lnbmFsLCBtdXN0IGJlIGF0IGxlYXN0IDIuIFxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBwb3cgPSBuZXcgVG9uZS5Qb3coMik7XG5cdFx0ICogdmFyIHNpZyA9IG5ldyBUb25lLlNpZ25hbCgwLjUpLmNvbm5lY3QocG93KTtcblx0XHQgKiAvL291dHB1dCBvZiBwb3cgaXMgMC4yNS4gXG5cdFx0ICovXG5cdCAgICBUb25lLlBvdyA9IGZ1bmN0aW9uIChleHApIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIHRoZSBleHBvbmVudFxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqIEB0eXBlIHtudW1iZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9leHAgPSBUb25lLmRlZmF1bHRBcmcoZXhwLCAxKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAdHlwZSB7V2F2ZVNoYXBlck5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2V4cFNjYWxlciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLldhdmVTaGFwZXIodGhpcy5fZXhwRnVuYyh0aGlzLl9leHApLCA4MTkyKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlBvdywgVG9uZS5TaWduYWxCYXNlKTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSB2YWx1ZSBvZiB0aGUgZXhwb25lbnQuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuUG93I1xuXHRcdCAqIEB0eXBlIHtudW1iZXJ9XG5cdFx0ICogQG5hbWUgdmFsdWVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBvdy5wcm90b3R5cGUsICd2YWx1ZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V4cDtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGV4cCkge1xuXHQgICAgICAgICAgICB0aGlzLl9leHAgPSBleHA7XG5cdCAgICAgICAgICAgIHRoaXMuX2V4cFNjYWxlci5zZXRNYXAodGhpcy5fZXhwRnVuYyh0aGlzLl9leHApKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICB0aGUgZnVuY3Rpb24gd2hpY2ggbWFwcyB0aGUgd2F2ZXNoYXBlclxuXHRcdCAqICBAcGFyYW0gICB7bnVtYmVyfSBleHBcblx0XHQgKiAgQHJldHVybiB7ZnVuY3Rpb259XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlBvdy5wcm90b3R5cGUuX2V4cEZ1bmMgPSBmdW5jdGlvbiAoZXhwKSB7XG5cdCAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWwpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIE1hdGgucG93KE1hdGguYWJzKHZhbCksIGV4cCk7XG5cdCAgICAgICAgfTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBvd30gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Qb3cucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWxCYXNlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fZXhwU2NhbGVyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9leHBTY2FsZXIgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlBvdztcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBUb25lLkVudmVsb3BlIGlzIGFuIFtBRFNSXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TeW50aGVzaXplciNBRFNSX2VudmVsb3BlKVxuXHRcdCAqICAgICAgICAgIGVudmVsb3BlIGdlbmVyYXRvci4gVG9uZS5FbnZlbG9wZSBvdXRwdXRzIGEgc2lnbmFsIHdoaWNoXG5cdFx0ICogICAgICAgICAgY2FuIGJlIGNvbm5lY3RlZCB0byBhbiBBdWRpb1BhcmFtIG9yIFRvbmUuU2lnbmFsLlxuXHRcdCAqICAgICAgICAgIDxpbWcgc3JjPVwiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy9lL2VhL0FEU1JfcGFyYW1ldGVyLnN2Z1wiPlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW2F0dGFja10gVGhlIGFtb3VudCBvZiB0aW1lIGl0IHRha2VzIGZvciB0aGUgZW52ZWxvcGUgdG8gZ28gZnJvbVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgIDAgdG8gaXQncyBtYXhpbXVtIHZhbHVlLlxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IFtkZWNheV1cdFRoZSBwZXJpb2Qgb2YgdGltZSBhZnRlciB0aGUgYXR0YWNrIHRoYXQgaXQgdGFrZXMgZm9yIHRoZSBlbnZlbG9wZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICBcdHRvIGZhbGwgdG8gdGhlIHN1c3RhaW4gdmFsdWUuXG5cdFx0ICogIEBwYXJhbSB7Tm9ybWFsUmFuZ2V9IFtzdXN0YWluXVx0VGhlIHBlcmNlbnQgb2YgdGhlIG1heGltdW0gdmFsdWUgdGhhdCB0aGUgZW52ZWxvcGUgcmVzdHMgYXQgdW50aWxcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXHR0aGUgcmVsZWFzZSBpcyB0cmlnZ2VyZWQuXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW3JlbGVhc2VdXHRUaGUgYW1vdW50IG9mIHRpbWUgYWZ0ZXIgdGhlIHJlbGVhc2UgaXMgdHJpZ2dlcmVkIGl0IHRha2VzIHRvIHJlYWNoIDAuXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9hbiBhbXBsaXR1ZGUgZW52ZWxvcGVcblx0XHQgKiB2YXIgZ2Fpbk5vZGUgPSBUb25lLmNvbnRleHQuY3JlYXRlR2FpbigpO1xuXHRcdCAqIHZhciBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSh7XG5cdFx0ICogXHRcImF0dGFja1wiIDogMC4xLFxuXHRcdCAqIFx0XCJkZWNheVwiIDogMC4yLFxuXHRcdCAqIFx0XCJzdXN0YWluXCIgOiAxLFxuXHRcdCAqIFx0XCJyZWxlYXNlXCIgOiAwLjgsXG5cdFx0ICogfSk7XG5cdFx0ICogZW52LmNvbm5lY3QoZ2Fpbk5vZGUuZ2Fpbik7XG5cdFx0ICovXG5cdCAgICBUb25lLkVudmVsb3BlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIC8vZ2V0IGFsbCBvZiB0aGUgZGVmYXVsdHNcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdhdHRhY2snLFxuXHQgICAgICAgICAgICAnZGVjYXknLFxuXHQgICAgICAgICAgICAnc3VzdGFpbicsXG5cdCAgICAgICAgICAgICdyZWxlYXNlJ1xuXHQgICAgICAgIF0sIFRvbmUuRW52ZWxvcGUpO1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgV2hlbiB0cmlnZ2VyQXR0YWNrIGlzIGNhbGxlZCwgdGhlIGF0dGFjayB0aW1lIGlzIHRoZSBhbW91bnQgb2Zcblx0XHRcdCAqICB0aW1lIGl0IHRha2VzIGZvciB0aGUgZW52ZWxvcGUgdG8gcmVhY2ggaXQncyBtYXhpbXVtIHZhbHVlLlxuXHRcdFx0ICogIEB0eXBlIHtUaW1lfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5hdHRhY2sgPSBvcHRpb25zLmF0dGFjaztcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBBZnRlciB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlLCB0aGUgdmFsdWUgd2lsbCBmYWxsXG5cdFx0XHQgKiAgb3ZlciB0aGUgZHVyYXRpb24gb2YgdGhlIGRlY2F5IHRpbWUgdG8gaXQncyBzdXN0YWluIHZhbHVlLlxuXHRcdFx0ICogIEB0eXBlIHtUaW1lfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZWNheSA9IG9wdGlvbnMuZGVjYXk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBcdFRoZSBzdXN0YWluIHZhbHVlIGlzIHRoZSB2YWx1ZVxuXHRcdFx0ICogXHR3aGljaCB0aGUgZW52ZWxvcGUgcmVzdHMgYXQgYWZ0ZXIgdHJpZ2dlckF0dGFjayBpc1xuXHRcdFx0ICogXHRjYWxsZWQsIGJ1dCBiZWZvcmUgdHJpZ2dlclJlbGVhc2UgaXMgaW52b2tlZC5cblx0XHRcdCAqICBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnN1c3RhaW4gPSBvcHRpb25zLnN1c3RhaW47XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQWZ0ZXIgdHJpZ2dlclJlbGVhc2UgaXMgY2FsbGVkLCB0aGUgZW52ZWxvcGUnc1xuXHRcdFx0ICogIHZhbHVlIHdpbGwgZmFsbCB0byBpdCdzIG1pbWludW0gdmFsdWUgb3ZlciB0aGVcblx0XHRcdCAqICBkdXJhdGlvbiBvZiB0aGUgcmVsZWFzZSB0aW1lLlxuXHRcdFx0ICogIEB0eXBlIHtUaW1lfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5yZWxlYXNlID0gb3B0aW9ucy5yZWxlYXNlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBuZXh0IHRpbWUgdGhlIGVudmVsb3BlIGlzIGF0IHN0YW5kYnlcblx0XHRcdCAqICBAdHlwZSB7bnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9hdHRhY2tDdXJ2ZSA9ICdsaW5lYXInO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBuZXh0IHRpbWUgdGhlIGVudmVsb3BlIGlzIGF0IHN0YW5kYnlcblx0XHRcdCAqICBAdHlwZSB7bnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9yZWxlYXNlQ3VydmUgPSAnZXhwb25lbnRpYWwnO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBzaWduYWxcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5TaWduYWx9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3NpZyA9IHRoaXMub3V0cHV0ID0gbmV3IFRvbmUuU2lnbmFsKDApO1xuXHQgICAgICAgIC8vc2V0IHRoZSBhdHRhY2tDdXJ2ZSBpbml0aWFsbHlcblx0ICAgICAgICB0aGlzLmF0dGFja0N1cnZlID0gb3B0aW9ucy5hdHRhY2tDdXJ2ZTtcblx0ICAgICAgICB0aGlzLnJlbGVhc2VDdXJ2ZSA9IG9wdGlvbnMucmVsZWFzZUN1cnZlO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuRW52ZWxvcGUsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICB0aGUgZGVmYXVsdCBwYXJhbWV0ZXJzXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQGNvbnN0XG5cdFx0ICovXG5cdCAgICBUb25lLkVudmVsb3BlLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdhdHRhY2snOiAwLjAxLFxuXHQgICAgICAgICdkZWNheSc6IDAuMSxcblx0ICAgICAgICAnc3VzdGFpbic6IDAuNSxcblx0ICAgICAgICAncmVsZWFzZSc6IDEsXG5cdCAgICAgICAgJ2F0dGFja0N1cnZlJzogJ2xpbmVhcicsXG5cdCAgICAgICAgJ3JlbGVhc2VDdXJ2ZSc6ICdleHBvbmVudGlhbCdcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBSZWFkIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBlbnZlbG9wZS4gVXNlZnVsIGZvclxuXHRcdCAqIHN5bmNyb25pemluZyB2aXN1YWwgb3V0cHV0IHRvIHRoZSBlbnZlbG9wZS5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5FbnZlbG9wZSNcblx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqIEBuYW1lIHZhbHVlXG5cdFx0ICogQHJlYWRPbmx5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5FbnZlbG9wZS5wcm90b3R5cGUsICd2YWx1ZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWVBdFRpbWUodGhpcy5ub3coKSk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgc2hhcGUgb2YgdGhlIGF0dGFjay5cblx0XHQgKiBDYW4gYmUgYW55IG9mIHRoZXNlIHN0cmluZ3M6XG5cdFx0ICogPHVsPlxuXHRcdCAqICAgPGxpPmxpbmVhcjwvbGk+XG5cdFx0ICogICA8bGk+ZXhwb25lbnRpYWw8L2xpPlxuXHRcdCAqICAgPGxpPnNpbmU8L2xpPlxuXHRcdCAqICAgPGxpPmNvc2luZTwvbGk+XG5cdFx0ICogICA8bGk+Ym91bmNlPC9saT5cblx0XHQgKiAgIDxsaT5yaXBwbGU8L2xpPlxuXHRcdCAqICAgPGxpPnN0ZXA8L2xpPlxuXHRcdCAqIDwvdWw+XG5cdFx0ICogQ2FuIGFsc28gYmUgYW4gYXJyYXkgd2hpY2ggZGVzY3JpYmVzIHRoZSBjdXJ2ZS4gVmFsdWVzXG5cdFx0ICogaW4gdGhlIGFycmF5IGFyZSBldmVubHkgc3ViZGl2aWRlZCBhbmQgbGluZWFybHlcblx0XHQgKiBpbnRlcnBvbGF0ZWQgb3ZlciB0aGUgZHVyYXRpb24gb2YgdGhlIGF0dGFjay5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5FbnZlbG9wZSNcblx0XHQgKiBAdHlwZSB7U3RyaW5nfEFycmF5fVxuXHRcdCAqIEBuYW1lIGF0dGFja0N1cnZlXG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiBlbnYuYXR0YWNrQ3VydmUgPSBcImxpbmVhclwiO1xuXHRcdCAqIEBleGFtcGxlXG5cdFx0ICogLy9jYW4gYWxzbyBiZSBhbiBhcnJheVxuXHRcdCAqIGVudi5hdHRhY2tDdXJ2ZSA9IFswLCAwLjIsIDAuMywgMC40LCAxXVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuRW52ZWxvcGUucHJvdG90eXBlLCAnYXR0YWNrQ3VydmUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIGlmIChUb25lLmlzU3RyaW5nKHRoaXMuX2F0dGFja0N1cnZlKSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2F0dGFja0N1cnZlO1xuXHQgICAgICAgICAgICB9IGVsc2UgaWYgKFRvbmUuaXNBcnJheSh0aGlzLl9hdHRhY2tDdXJ2ZSkpIHtcblx0ICAgICAgICAgICAgICAgIC8vbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgY3VydmVzIGFycmF5XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciB0eXBlIGluIFRvbmUuRW52ZWxvcGUuVHlwZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGlmIChUb25lLkVudmVsb3BlLlR5cGVbdHlwZV0uSW4gPT09IHRoaXMuX2F0dGFja0N1cnZlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIC8vb3RoZXJ3aXNlIGp1c3QgcmV0dXJuIHRoZSBhcnJheVxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2F0dGFja0N1cnZlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChjdXJ2ZSkge1xuXHQgICAgICAgICAgICAvL2NoZWNrIGlmIGl0J3MgYSB2YWxpZCB0eXBlXG5cdCAgICAgICAgICAgIGlmIChUb25lLkVudmVsb3BlLlR5cGUuaGFzT3duUHJvcGVydHkoY3VydmUpKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgY3VydmVEZWYgPSBUb25lLkVudmVsb3BlLlR5cGVbY3VydmVdO1xuXHQgICAgICAgICAgICAgICAgaWYgKFRvbmUuaXNPYmplY3QoY3VydmVEZWYpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXR0YWNrQ3VydmUgPSBjdXJ2ZURlZi5Jbjtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXR0YWNrQ3VydmUgPSBjdXJ2ZURlZjtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSBlbHNlIGlmIChUb25lLmlzQXJyYXkoY3VydmUpKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9hdHRhY2tDdXJ2ZSA9IGN1cnZlO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUb25lLkVudmVsb3BlOiBpbnZhbGlkIGN1cnZlOiAnICsgY3VydmUpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgc2hhcGUgb2YgdGhlIHJlbGVhc2UuIFNlZSB0aGUgYXR0YWNrIGN1cnZlIHR5cGVzLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkVudmVsb3BlI1xuXHRcdCAqIEB0eXBlIHtTdHJpbmd8QXJyYXl9XG5cdFx0ICogQG5hbWUgcmVsZWFzZUN1cnZlXG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiBlbnYucmVsZWFzZUN1cnZlID0gXCJsaW5lYXJcIjtcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkVudmVsb3BlLnByb3RvdHlwZSwgJ3JlbGVhc2VDdXJ2ZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKFRvbmUuaXNTdHJpbmcodGhpcy5fcmVsZWFzZUN1cnZlKSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JlbGVhc2VDdXJ2ZTtcblx0ICAgICAgICAgICAgfSBlbHNlIGlmIChUb25lLmlzQXJyYXkodGhpcy5fcmVsZWFzZUN1cnZlKSkge1xuXHQgICAgICAgICAgICAgICAgLy9sb29rIHVwIHRoZSBuYW1lIGluIHRoZSBjdXJ2ZXMgYXJyYXlcblx0ICAgICAgICAgICAgICAgIGZvciAodmFyIHR5cGUgaW4gVG9uZS5FbnZlbG9wZS5UeXBlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKFRvbmUuRW52ZWxvcGUuVHlwZVt0eXBlXS5PdXQgPT09IHRoaXMuX3JlbGVhc2VDdXJ2ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHlwZTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAvL290aGVyd2lzZSBqdXN0IHJldHVybiB0aGUgYXJyYXlcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZWxlYXNlQ3VydmU7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGN1cnZlKSB7XG5cdCAgICAgICAgICAgIC8vY2hlY2sgaWYgaXQncyBhIHZhbGlkIHR5cGVcblx0ICAgICAgICAgICAgaWYgKFRvbmUuRW52ZWxvcGUuVHlwZS5oYXNPd25Qcm9wZXJ0eShjdXJ2ZSkpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBjdXJ2ZURlZiA9IFRvbmUuRW52ZWxvcGUuVHlwZVtjdXJ2ZV07XG5cdCAgICAgICAgICAgICAgICBpZiAoVG9uZS5pc09iamVjdChjdXJ2ZURlZikpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZWxlYXNlQ3VydmUgPSBjdXJ2ZURlZi5PdXQ7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlbGVhc2VDdXJ2ZSA9IGN1cnZlRGVmO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9IGVsc2UgaWYgKFRvbmUuaXNBcnJheShjdXJ2ZSkpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3JlbGVhc2VDdXJ2ZSA9IGN1cnZlO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUb25lLkVudmVsb3BlOiBpbnZhbGlkIGN1cnZlOiAnICsgY3VydmUpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVHJpZ2dlciB0aGUgYXR0YWNrL2RlY2F5IHBvcnRpb24gb2YgdGhlIEFEU1IgZW52ZWxvcGUuXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IFt0aW1lPW5vd10gV2hlbiB0aGUgYXR0YWNrIHNob3VsZCBzdGFydC5cblx0XHQgKiAgQHBhcmFtIHtOb3JtYWxSYW5nZX0gW3ZlbG9jaXR5PTFdIFRoZSB2ZWxvY2l0eSBvZiB0aGUgZW52ZWxvcGUgc2NhbGVzIHRoZSB2YWxlcy5cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXIgYmV0d2VlbiAwLTFcblx0XHQgKiAgQHJldHVybnMge1RvbmUuRW52ZWxvcGV9IHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAgLy90cmlnZ2VyIHRoZSBhdHRhY2sgMC41IHNlY29uZHMgZnJvbSBub3cgd2l0aCBhIHZlbG9jaXR5IG9mIDAuMlxuXHRcdCAqICBlbnYudHJpZ2dlckF0dGFjayhcIiswLjVcIiwgMC4yKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuRW52ZWxvcGUucHJvdG90eXBlLnRyaWdnZXJBdHRhY2sgPSBmdW5jdGlvbiAodGltZSwgdmVsb2NpdHkpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdmFyIG9yaWdpbmFsQXR0YWNrID0gdGhpcy50b1NlY29uZHModGhpcy5hdHRhY2spO1xuXHQgICAgICAgIHZhciBhdHRhY2sgPSBvcmlnaW5hbEF0dGFjaztcblx0ICAgICAgICB2YXIgZGVjYXkgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmRlY2F5KTtcblx0ICAgICAgICB2ZWxvY2l0eSA9IFRvbmUuZGVmYXVsdEFyZyh2ZWxvY2l0eSwgMSk7XG5cdCAgICAgICAgLy9jaGVjayBpZiBpdCdzIG5vdCBhIGNvbXBsZXRlIGF0dGFja1xuXHQgICAgICAgIHZhciBjdXJyZW50VmFsdWUgPSB0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuXHQgICAgICAgIGlmIChjdXJyZW50VmFsdWUgPiAwKSB7XG5cdCAgICAgICAgICAgIC8vc3VidHJhY3QgdGhlIGN1cnJlbnQgdmFsdWUgZnJvbSB0aGUgYXR0YWNrIHRpbWVcblx0ICAgICAgICAgICAgdmFyIGF0dGFja1JhdGUgPSAxIC8gYXR0YWNrO1xuXHQgICAgICAgICAgICB2YXIgcmVtYWluaW5nRGlzdGFuY2UgPSAxIC0gY3VycmVudFZhbHVlO1xuXHQgICAgICAgICAgICAvL3RoZSBhdHRhY2sgaXMgbm93IHRoZSByZW1haW5pbmcgdGltZVxuXHQgICAgICAgICAgICBhdHRhY2sgPSByZW1haW5pbmdEaXN0YW5jZSAvIGF0dGFja1JhdGU7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vYXR0YWNrXG5cdCAgICAgICAgaWYgKHRoaXMuX2F0dGFja0N1cnZlID09PSAnbGluZWFyJykge1xuXHQgICAgICAgICAgICB0aGlzLl9zaWcubGluZWFyUmFtcFRvKHZlbG9jaXR5LCBhdHRhY2ssIHRpbWUpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYXR0YWNrQ3VydmUgPT09ICdleHBvbmVudGlhbCcpIHtcblx0ICAgICAgICAgICAgdGhpcy5fc2lnLnRhcmdldFJhbXBUbyh2ZWxvY2l0eSwgYXR0YWNrLCB0aW1lKTtcblx0ICAgICAgICB9IGVsc2UgaWYgKGF0dGFjayA+IDApIHtcblx0ICAgICAgICAgICAgdGhpcy5fc2lnLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG5cdCAgICAgICAgICAgIHZhciBjdXJ2ZSA9IHRoaXMuX2F0dGFja0N1cnZlO1xuXHQgICAgICAgICAgICAvL3Rha2Ugb25seSBhIHBvcnRpb24gb2YgdGhlIGN1cnZlXG5cdCAgICAgICAgICAgIGlmIChhdHRhY2sgPCBvcmlnaW5hbEF0dGFjaykge1xuXHQgICAgICAgICAgICAgICAgdmFyIHBlcmNlbnRDb21wbGV0ZSA9IDEgLSBhdHRhY2sgLyBvcmlnaW5hbEF0dGFjaztcblx0ICAgICAgICAgICAgICAgIHZhciBzbGljZUluZGV4ID0gTWF0aC5mbG9vcihwZXJjZW50Q29tcGxldGUgKiB0aGlzLl9hdHRhY2tDdXJ2ZS5sZW5ndGgpO1xuXHQgICAgICAgICAgICAgICAgY3VydmUgPSB0aGlzLl9hdHRhY2tDdXJ2ZS5zbGljZShzbGljZUluZGV4KTtcblx0ICAgICAgICAgICAgICAgIC8vdGhlIGZpcnN0IGluZGV4IGlzIHRoZSBjdXJyZW50IHZhbHVlXG5cdCAgICAgICAgICAgICAgICBjdXJ2ZVswXSA9IGN1cnJlbnRWYWx1ZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aGlzLl9zaWcuc2V0VmFsdWVDdXJ2ZUF0VGltZShjdXJ2ZSwgdGltZSwgYXR0YWNrLCB2ZWxvY2l0eSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vZGVjYXlcblx0ICAgICAgICBpZiAoZGVjYXkpIHtcblx0ICAgICAgICAgICAgdGhpcy5fc2lnLnRhcmdldFJhbXBUbyh2ZWxvY2l0eSAqIHRoaXMuc3VzdGFpbiwgZGVjYXksIGF0dGFjayArIHRpbWUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVHJpZ2dlcnMgdGhlIHJlbGVhc2Ugb2YgdGhlIGVudmVsb3BlLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddIFdoZW4gdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGUgc2hvdWxkIHN0YXJ0LlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5FbnZlbG9wZX0gdGhpc1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqICAvL3RyaWdnZXIgcmVsZWFzZSBpbW1lZGlhdGVseVxuXHRcdCAqICBlbnYudHJpZ2dlclJlbGVhc2UoKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuRW52ZWxvcGUucHJvdG90eXBlLnRyaWdnZXJSZWxlYXNlID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdmFyIGN1cnJlbnRWYWx1ZSA9IHRoaXMuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG5cdCAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA+IDApIHtcblx0ICAgICAgICAgICAgdmFyIHJlbGVhc2UgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLnJlbGVhc2UpO1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fcmVsZWFzZUN1cnZlID09PSAnbGluZWFyJykge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fc2lnLmxpbmVhclJhbXBUbygwLCByZWxlYXNlLCB0aW1lKTtcblx0ICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9yZWxlYXNlQ3VydmUgPT09ICdleHBvbmVudGlhbCcpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3NpZy50YXJnZXRSYW1wVG8oMCwgcmVsZWFzZSwgdGltZSk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgY3VydmUgPSB0aGlzLl9yZWxlYXNlQ3VydmU7XG5cdCAgICAgICAgICAgICAgICBpZiAoVG9uZS5pc0FycmF5KGN1cnZlKSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5zZXRWYWx1ZUN1cnZlQXRUaW1lKGN1cnZlLCB0aW1lLCByZWxlYXNlLCBjdXJyZW50VmFsdWUpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBHZXQgdGhlIHNjaGVkdWxlZCB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZS4gVGhpcyB3aWxsXG5cdFx0ICogIHJldHVybiB0aGUgdW5jb252ZXJ0ZWQgKHJhdykgdmFsdWUuXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWUgIFRoZSB0aW1lIGluIHNlY29uZHMuXG5cdFx0ICogIEByZXR1cm4gIHtOdW1iZXJ9ICBUaGUgc2NoZWR1bGVkIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5FbnZlbG9wZS5wcm90b3R5cGUuZ2V0VmFsdWVBdFRpbWUgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9zaWcuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIHRyaWdnZXJBdHRhY2tSZWxlYXNlIGlzIHNob3J0aGFuZCBmb3IgdHJpZ2dlckF0dGFjaywgdGhlbiB3YWl0aW5nXG5cdFx0ICogIHNvbWUgZHVyYXRpb24sIHRoZW4gdHJpZ2dlclJlbGVhc2UuXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gZHVyYXRpb24gVGhlIGR1cmF0aW9uIG9mIHRoZSBzdXN0YWluLlxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IFt0aW1lPW5vd10gV2hlbiB0aGUgYXR0YWNrIHNob3VsZCBiZSB0cmlnZ2VyZWQuXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSBbdmVsb2NpdHk9MV0gVGhlIHZlbG9jaXR5IG9mIHRoZSBlbnZlbG9wZS5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuRW52ZWxvcGV9IHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL3RyaWdnZXIgdGhlIGF0dGFjayBhbmQgdGhlbiB0aGUgcmVsZWFzZSBhZnRlciAwLjYgc2Vjb25kcy5cblx0XHQgKiBlbnYudHJpZ2dlckF0dGFja1JlbGVhc2UoMC42KTtcblx0XHQgKi9cblx0ICAgIFRvbmUuRW52ZWxvcGUucHJvdG90eXBlLnRyaWdnZXJBdHRhY2tSZWxlYXNlID0gZnVuY3Rpb24gKGR1cmF0aW9uLCB0aW1lLCB2ZWxvY2l0eSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuXHQgICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2UodGltZSArIHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENhbmNlbHMgYWxsIHNjaGVkdWxlZCBlbnZlbG9wZSBjaGFuZ2VzIGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBhZnRlclxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5FbnZlbG9wZX0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5FbnZlbG9wZS5wcm90b3R5cGUuY2FuY2VsID0gZnVuY3Rpb24gKGFmdGVyKSB7XG5cdCAgICAgICAgdGhpcy5fc2lnLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyhhZnRlcik7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEJvcnJvd3MgdGhlIGNvbm5lY3QgbWV0aG9kIGZyb20gVG9uZS5TaWduYWwuXG5cdFx0ICogIEBmdW5jdGlvblxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5FbnZlbG9wZS5wcm90b3R5cGUuY29ubmVjdCA9IFRvbmUuU2lnbmFsQmFzZS5wcm90b3R5cGUuY29ubmVjdDtcblx0ICAgIC8qKlxuXHQgXHQgKiAgR2VuZXJhdGUgc29tZSBjb21wbGV4IGVudmVsb3BlIGN1cnZlcy5cblx0IFx0ICovXG5cdCAgICAoZnVuY3Rpb24gX2NyZWF0ZUN1cnZlcygpIHtcblx0ICAgICAgICB2YXIgY3VydmVMZW4gPSAxMjg7XG5cdCAgICAgICAgdmFyIGksIGs7XG5cdCAgICAgICAgLy9jb3NpbmUgY3VydmVcblx0ICAgICAgICB2YXIgY29zaW5lQ3VydmUgPSBbXTtcblx0ICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY3VydmVMZW47IGkrKykge1xuXHQgICAgICAgICAgICBjb3NpbmVDdXJ2ZVtpXSA9IE1hdGguc2luKGkgLyAoY3VydmVMZW4gLSAxKSAqIChNYXRoLlBJIC8gMikpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL3JpcHBsZSBjdXJ2ZVxuXHQgICAgICAgIHZhciByaXBwbGVDdXJ2ZSA9IFtdO1xuXHQgICAgICAgIHZhciByaXBwbGVDdXJ2ZUZyZXEgPSA2LjQ7XG5cdCAgICAgICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuIC0gMTsgaSsrKSB7XG5cdCAgICAgICAgICAgIGsgPSBpIC8gKGN1cnZlTGVuIC0gMSk7XG5cdCAgICAgICAgICAgIHZhciBzaW5lV2F2ZSA9IE1hdGguc2luKGsgKiAoTWF0aC5QSSAqIDIpICogcmlwcGxlQ3VydmVGcmVxIC0gTWF0aC5QSSAvIDIpICsgMTtcblx0ICAgICAgICAgICAgcmlwcGxlQ3VydmVbaV0gPSBzaW5lV2F2ZSAvIDEwICsgayAqIDAuODM7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJpcHBsZUN1cnZlW2N1cnZlTGVuIC0gMV0gPSAxO1xuXHQgICAgICAgIC8vc3RhaXJzIGN1cnZlXG5cdCAgICAgICAgdmFyIHN0YWlyc0N1cnZlID0gW107XG5cdCAgICAgICAgdmFyIHN0ZXBzID0gNTtcblx0ICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY3VydmVMZW47IGkrKykge1xuXHQgICAgICAgICAgICBzdGFpcnNDdXJ2ZVtpXSA9IE1hdGguY2VpbChpIC8gKGN1cnZlTGVuIC0gMSkgKiBzdGVwcykgLyBzdGVwcztcblx0ICAgICAgICB9XG5cdCAgICAgICAgLy9pbi1vdXQgZWFzaW5nIGN1cnZlXG5cdCAgICAgICAgdmFyIHNpbmVDdXJ2ZSA9IFtdO1xuXHQgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjdXJ2ZUxlbjsgaSsrKSB7XG5cdCAgICAgICAgICAgIGsgPSBpIC8gKGN1cnZlTGVuIC0gMSk7XG5cdCAgICAgICAgICAgIHNpbmVDdXJ2ZVtpXSA9IDAuNSAqICgxIC0gTWF0aC5jb3MoTWF0aC5QSSAqIGspKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgLy9hIGJvdW5jZSBjdXJ2ZVxuXHQgICAgICAgIHZhciBib3VuY2VDdXJ2ZSA9IFtdO1xuXHQgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjdXJ2ZUxlbjsgaSsrKSB7XG5cdCAgICAgICAgICAgIGsgPSBpIC8gKGN1cnZlTGVuIC0gMSk7XG5cdCAgICAgICAgICAgIHZhciBmcmVxID0gTWF0aC5wb3coaywgMykgKiA0ICsgMC4yO1xuXHQgICAgICAgICAgICB2YXIgdmFsID0gTWF0aC5jb3MoZnJlcSAqIE1hdGguUEkgKiAyICogayk7XG5cdCAgICAgICAgICAgIGJvdW5jZUN1cnZlW2ldID0gTWF0aC5hYnModmFsICogKDEgLSBrKSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEludmVydCBhIHZhbHVlIGN1cnZlIHRvIG1ha2UgaXQgd29yayBmb3IgdGhlIHJlbGVhc2Vcblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgZnVuY3Rpb24gaW52ZXJ0Q3VydmUoY3VydmUpIHtcblx0ICAgICAgICAgICAgdmFyIG91dCA9IG5ldyBBcnJheShjdXJ2ZS5sZW5ndGgpO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGN1cnZlLmxlbmd0aDsgaisrKSB7XG5cdCAgICAgICAgICAgICAgICBvdXRbal0gPSAxIC0gY3VydmVbal07XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgcmV0dXJuIG91dDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgcmV2ZXJzZSB0aGUgY3VydmVcblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgZnVuY3Rpb24gcmV2ZXJzZUN1cnZlKGN1cnZlKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjdXJ2ZS5zbGljZSgwKS5yZXZlcnNlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGF0dGFjayBhbmQgcmVsZWFzZSBjdXJ2ZSBhcnJheXNcblx0XHRcdCAqICBAdHlwZSAge09iamVjdH1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgVG9uZS5FbnZlbG9wZS5UeXBlID0ge1xuXHQgICAgICAgICAgICAnbGluZWFyJzogJ2xpbmVhcicsXG5cdCAgICAgICAgICAgICdleHBvbmVudGlhbCc6ICdleHBvbmVudGlhbCcsXG5cdCAgICAgICAgICAgICdib3VuY2UnOiB7XG5cdCAgICAgICAgICAgICAgICBJbjogaW52ZXJ0Q3VydmUoYm91bmNlQ3VydmUpLFxuXHQgICAgICAgICAgICAgICAgT3V0OiBib3VuY2VDdXJ2ZVxuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICAnY29zaW5lJzoge1xuXHQgICAgICAgICAgICAgICAgSW46IGNvc2luZUN1cnZlLFxuXHQgICAgICAgICAgICAgICAgT3V0OiByZXZlcnNlQ3VydmUoY29zaW5lQ3VydmUpXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgICdzdGVwJzoge1xuXHQgICAgICAgICAgICAgICAgSW46IHN0YWlyc0N1cnZlLFxuXHQgICAgICAgICAgICAgICAgT3V0OiBpbnZlcnRDdXJ2ZShzdGFpcnNDdXJ2ZSlcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgJ3JpcHBsZSc6IHtcblx0ICAgICAgICAgICAgICAgIEluOiByaXBwbGVDdXJ2ZSxcblx0ICAgICAgICAgICAgICAgIE91dDogaW52ZXJ0Q3VydmUocmlwcGxlQ3VydmUpXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgICdzaW5lJzoge1xuXHQgICAgICAgICAgICAgICAgSW46IHNpbmVDdXJ2ZSxcblx0ICAgICAgICAgICAgICAgIE91dDogaW52ZXJ0Q3VydmUoc2luZUN1cnZlKVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH0oKSk7XG5cdCAgICAvKipcblx0XHQgKiAgRGlzY29ubmVjdCBhbmQgZGlzcG9zZS5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuRW52ZWxvcGV9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuRW52ZWxvcGUucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9zaWcuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3NpZyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fYXR0YWNrQ3VydmUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3JlbGVhc2VDdXJ2ZSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuRW52ZWxvcGU7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZSBpcyBhIFRvbmUuRW52ZWxvcGUgY29ubmVjdGVkIHRvIGEgZ2FpbiBub2RlLlxuXHRcdCAqICAgICAgICAgIFVubGlrZSBUb25lLkVudmVsb3BlLCB3aGljaCBvdXRwdXRzIHRoZSBlbnZlbG9wZSdzIHZhbHVlLCBUb25lLkFtcGxpdHVkZUVudmVsb3BlIGFjY2VwdHNcblx0XHQgKiAgICAgICAgICBhbiBhdWRpbyBzaWduYWwgYXMgdGhlIGlucHV0IGFuZCB3aWxsIGFwcGx5IHRoZSBlbnZlbG9wZSB0byB0aGUgYW1wbGl0dWRlXG5cdFx0ICogICAgICAgICAgb2YgdGhlIHNpZ25hbC4gUmVhZCBtb3JlIGFib3V0IEFEU1IgRW52ZWxvcGVzIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N5bnRoZXNpemVyI0FEU1JfZW52ZWxvcGUpLlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5FbnZlbG9wZX1cblx0XHQgKiAgQHBhcmFtIHtUaW1lfE9iamVjdH0gW2F0dGFja10gVGhlIGFtb3VudCBvZiB0aW1lIGl0IHRha2VzIGZvciB0aGUgZW52ZWxvcGUgdG8gZ28gZnJvbVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgdG8gaXQncyBtYXhpbXVtIHZhbHVlLlxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IFtkZWNheV1cdFRoZSBwZXJpb2Qgb2YgdGltZSBhZnRlciB0aGUgYXR0YWNrIHRoYXQgaXQgdGFrZXMgZm9yIHRoZSBlbnZlbG9wZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICBcdHRvIGZhbGwgdG8gdGhlIHN1c3RhaW4gdmFsdWUuXG5cdFx0ICogIEBwYXJhbSB7Tm9ybWFsUmFuZ2V9IFtzdXN0YWluXVx0VGhlIHBlcmNlbnQgb2YgdGhlIG1heGltdW0gdmFsdWUgdGhhdCB0aGUgZW52ZWxvcGUgcmVzdHMgYXQgdW50aWxcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXHR0aGUgcmVsZWFzZSBpcyB0cmlnZ2VyZWQuXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW3JlbGVhc2VdXHRUaGUgYW1vdW50IG9mIHRpbWUgYWZ0ZXIgdGhlIHJlbGVhc2UgaXMgdHJpZ2dlcmVkIGl0IHRha2VzIHRvIHJlYWNoIDAuXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIGFtcEVudiA9IG5ldyBUb25lLkFtcGxpdHVkZUVudmVsb3BlKHtcblx0XHQgKiBcdFwiYXR0YWNrXCI6IDAuMSxcblx0XHQgKiBcdFwiZGVjYXlcIjogMC4yLFxuXHRcdCAqIFx0XCJzdXN0YWluXCI6IDEuMCxcblx0XHQgKiBcdFwicmVsZWFzZVwiOiAwLjhcblx0XHQgKiB9KS50b01hc3RlcigpO1xuXHRcdCAqIC8vY3JlYXRlIGFuIG9zY2lsbGF0b3IgYW5kIGNvbm5lY3QgaXRcblx0XHQgKiB2YXIgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QoYW1wRW52KS5zdGFydCgpO1xuXHRcdCAqIC8vdHJpZ2dlciB0aGUgZW52ZWxvcGVzIGF0dGFjayBhbmQgcmVsZWFzZSBcIjh0XCIgYXBhcnRcblx0XHQgKiBhbXBFbnYudHJpZ2dlckF0dGFja1JlbGVhc2UoXCI4dFwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5FbnZlbG9wZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBpbnB1dCBub2RlXG5cdFx0XHQgKiAgQHR5cGUge0dhaW5Ob2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZS5HYWluKCk7XG5cdCAgICAgICAgdGhpcy5fc2lnLmNvbm5lY3QodGhpcy5vdXRwdXQuZ2Fpbik7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZSwgVG9uZS5FbnZlbG9wZSk7XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXBcblx0XHQgKiAgQHJldHVybiAge1RvbmUuQW1wbGl0dWRlRW52ZWxvcGV9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkFtcGxpdHVkZUVudmVsb3BlLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuRW52ZWxvcGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgLyoqXG5cdFx0ICogIEFuYWx5c2VyTm9kZS5nZXRGbG9hdFRpbWVEb21haW5EYXRhIHBvbHlmaWxsXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBpZiAoVG9uZS5zdXBwb3J0ZWQpIHtcblx0ICAgICAgICBpZiAoIUFuYWx5c2VyTm9kZS5wcm90b3R5cGUuZ2V0RmxvYXRUaW1lRG9tYWluRGF0YSkge1xuXHQgICAgICAgICAgICAvL3JlZmVyZW5jZWQgaHR0cHM6Ly9naXRodWIuY29tL21vaGF5b25hby9nZXQtZmxvYXQtdGltZS1kb21haW4tZGF0YVxuXHQgICAgICAgICAgICBBbmFseXNlck5vZGUucHJvdG90eXBlLmdldEZsb2F0VGltZURvbWFpbkRhdGEgPSBmdW5jdGlvbiAoYXJyYXkpIHtcblx0ICAgICAgICAgICAgICAgIHZhciB1aW50OCA9IG5ldyBVaW50OEFycmF5KGFycmF5Lmxlbmd0aCk7XG5cdCAgICAgICAgICAgICAgICB0aGlzLmdldEJ5dGVUaW1lRG9tYWluRGF0YSh1aW50OCk7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHVpbnQ4Lmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgYXJyYXlbaV0gPSAodWludDhbaV0gLSAxMjgpIC8gMTI4O1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBXcmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIFdlYiBBdWRpbydzXG5cdFx0ICogICAgICAgICAgW0FuYWx5c2VyTm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyNpZGwtZGVmLUFuYWx5c2VyTm9kZSkuXG5cdFx0ICogICAgICAgICAgRXh0cmFjdHMgRkZUIG9yIFdhdmVmb3JtIGRhdGEgZnJvbSB0aGUgaW5jb21pbmcgc2lnbmFsLlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBwYXJhbSB7U3RyaW5nPX0gdHlwZSBUaGUgcmV0dXJuIHR5cGUgb2YgdGhlIGFuYWx5c2lzLCBlaXRoZXIgXCJmZnRcIiwgb3IgXCJ3YXZlZm9ybVwiLlxuXHRcdCAqICBAcGFyYW0ge051bWJlcj19IHNpemUgVGhlIHNpemUgb2YgdGhlIEZGVC4gVmFsdWUgbXVzdCBiZSBhIHBvd2VyIG9mXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgIHR3byBpbiB0aGUgcmFuZ2UgMzIgdG8gMzI3NjguXG5cdFx0ICovXG5cdCAgICBUb25lLkFuYWx5c2VyID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ3R5cGUnLFxuXHQgICAgICAgICAgICAnc2l6ZSdcblx0ICAgICAgICBdLCBUb25lLkFuYWx5c2VyKTtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhbmFseXNlciBub2RlLlxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge0FuYWx5c2VyTm9kZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2FuYWx5c2VyID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGFuYWx5c2lzIHR5cGVcblx0XHRcdCAqICBAdHlwZSB7U3RyaW5nfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl90eXBlID0gb3B0aW9ucy50eXBlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBidWZmZXIgdGhhdCB0aGUgRkZUIGRhdGEgaXMgd3JpdHRlbiB0b1xuXHRcdFx0ICogIEB0eXBlIHtUeXBlZEFycmF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9idWZmZXIgPSBudWxsO1xuXHQgICAgICAgIC8vc2V0IHRoZSB2YWx1ZXMgaW5pdGlhbGx5XG5cdCAgICAgICAgdGhpcy5zaXplID0gb3B0aW9ucy5zaXplO1xuXHQgICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkFuYWx5c2VyLCBUb25lLkF1ZGlvTm9kZSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGRlZmF1bHQgdmFsdWVzLlxuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqICBAY29uc3Rcblx0XHQgKi9cblx0ICAgIFRvbmUuQW5hbHlzZXIuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ3NpemUnOiAxMDI0LFxuXHQgICAgICAgICd0eXBlJzogJ2ZmdCcsXG5cdCAgICAgICAgJ3Ntb290aGluZyc6IDAuOFxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBQb3NzaWJsZSByZXR1cm4gdHlwZXMgb2YgYW5hbHlzZXIuZ2V0VmFsdWUoKVxuXHRcdCAqICBAZW51bSB7U3RyaW5nfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5BbmFseXNlci5UeXBlID0ge1xuXHQgICAgICAgIFdhdmVmb3JtOiAnd2F2ZWZvcm0nLFxuXHQgICAgICAgIEZGVDogJ2ZmdCdcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUnVuIHRoZSBhbmFseXNpcyBnaXZlbiB0aGUgY3VycmVudCBzZXR0aW5ncyBhbmQgcmV0dXJuIHRoZVxuXHRcdCAqICByZXN1bHQgYXMgYSBUeXBlZEFycmF5LlxuXHRcdCAqICBAcmV0dXJucyB7VHlwZWRBcnJheX1cblx0XHQgKi9cblx0ICAgIFRvbmUuQW5hbHlzZXIucHJvdG90eXBlLmdldFZhbHVlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGlmICh0aGlzLl90eXBlID09PSBUb25lLkFuYWx5c2VyLlR5cGUuRkZUKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2FuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YSh0aGlzLl9idWZmZXIpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fdHlwZSA9PT0gVG9uZS5BbmFseXNlci5UeXBlLldhdmVmb3JtKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2FuYWx5c2VyLmdldEZsb2F0VGltZURvbWFpbkRhdGEodGhpcy5fYnVmZmVyKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHNpemUgb2YgYW5hbHlzaXMuIFRoaXMgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBpbiB0aGUgcmFuZ2UgMzIgdG8gMzI3NjguXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkFuYWx5c2VyI1xuXHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqICBAbmFtZSBzaXplXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5BbmFseXNlci5wcm90b3R5cGUsICdzaXplJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQ7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChzaXplKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2FuYWx5c2VyLmZmdFNpemUgPSBzaXplICogMjtcblx0ICAgICAgICAgICAgdGhpcy5fYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShzaXplKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgYW5hbHlzaXMgZnVuY3Rpb24gcmV0dXJuZWQgYnkgYW5hbHlzZXIuZ2V0VmFsdWUoKSwgZWl0aGVyIFwiZmZ0XCIgb3IgXCJ3YXZlZm9ybVwiLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5BbmFseXNlciNcblx0XHQgKiAgQHR5cGUge1N0cmluZ31cblx0XHQgKiAgQG5hbWUgdHlwZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQW5hbHlzZXIucHJvdG90eXBlLCAndHlwZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh0eXBlKSB7XG5cdCAgICAgICAgICAgIGlmICh0eXBlICE9PSBUb25lLkFuYWx5c2VyLlR5cGUuV2F2ZWZvcm0gJiYgdHlwZSAhPT0gVG9uZS5BbmFseXNlci5UeXBlLkZGVCkge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVG9uZS5BbmFseXNlcjogaW52YWxpZCB0eXBlOiAnICsgdHlwZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgMCByZXByZXNlbnRzIG5vIHRpbWUgYXZlcmFnaW5nIHdpdGggdGhlIGxhc3QgYW5hbHlzaXMgZnJhbWUuXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkFuYWx5c2VyI1xuXHRcdCAqICBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0ICogIEBuYW1lIHNtb290aGluZ1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQW5hbHlzZXIucHJvdG90eXBlLCAnc21vb3RoaW5nJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuc21vb3RoaW5nVGltZUNvbnN0YW50O1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2FuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IHZhbDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybiAge1RvbmUuQW5hbHlzZXJ9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkFuYWx5c2VyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fYW5hbHlzZXIuZGlzY29ubmVjdCgpO1xuXHQgICAgICAgIHRoaXMuX2FuYWx5c2VyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9idWZmZXIgPSBudWxsO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkFuYWx5c2VyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5Db21wcmVzc29yIGlzIGEgdGhpbiB3cmFwcGVyIGFyb3VuZCB0aGUgV2ViIEF1ZGlvXG5cdFx0ICogICAgICAgICBbRHluYW1pY3NDb21wcmVzc29yTm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtZHluYW1pY3Njb21wcmVzc29ybm9kZS1pbnRlcmZhY2UpLlxuXHRcdCAqICAgICAgICAgQ29tcHJlc3Npb24gcmVkdWNlcyB0aGUgdm9sdW1lIG9mIGxvdWQgc291bmRzIG9yIGFtcGxpZmllcyBxdWlldCBzb3VuZHNcblx0XHQgKiAgICAgICAgIGJ5IG5hcnJvd2luZyBvciBcImNvbXByZXNzaW5nXCIgYW4gYXVkaW8gc2lnbmFsJ3MgZHluYW1pYyByYW5nZS5cblx0XHQgKiAgICAgICAgIFJlYWQgbW9yZSBvbiBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EeW5hbWljX3JhbmdlX2NvbXByZXNzaW9uKS5cblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAcGFyYW0ge0RlY2liZWxzfE9iamVjdH0gW3RocmVzaG9sZF0gVGhlIHZhbHVlIGFib3ZlIHdoaWNoIHRoZSBjb21wcmVzc2lvbiBzdGFydHMgdG8gYmUgYXBwbGllZC5cblx0XHQgKiAgQHBhcmFtIHtQb3NpdGl2ZX0gW3JhdGlvXSBUaGUgZ2FpbiByZWR1Y3Rpb24gcmF0aW8uXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIGNvbXAgPSBuZXcgVG9uZS5Db21wcmVzc29yKC0zMCwgMyk7XG5cdFx0ICovXG5cdCAgICBUb25lLkNvbXByZXNzb3IgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAndGhyZXNob2xkJyxcblx0ICAgICAgICAgICAgJ3JhdGlvJ1xuXHQgICAgICAgIF0sIFRvbmUuQ29tcHJlc3Nvcik7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgY29tcHJlc3NvciBub2RlXG5cdFx0XHQgKiAgQHR5cGUge0R5bmFtaWNzQ29tcHJlc3Nvck5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2NvbXByZXNzb3IgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIHRocmVzaG9sZCB2YXVlXG5cdFx0XHQgKiAgQHR5cGUge0RlY2liZWxzfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMudGhyZXNob2xkID0gbmV3IFRvbmUuUGFyYW0oe1xuXHQgICAgICAgICAgICAncGFyYW0nOiB0aGlzLl9jb21wcmVzc29yLnRocmVzaG9sZCxcblx0ICAgICAgICAgICAgJ3VuaXRzJzogVG9uZS5UeXBlLkRlY2liZWxzLFxuXHQgICAgICAgICAgICAnY29udmVydCc6IGZhbHNlXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGF0dGFjayBwYXJhbWV0ZXJcblx0XHRcdCAqICBAdHlwZSB7VGltZX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmF0dGFjayA9IG5ldyBUb25lLlBhcmFtKHRoaXMuX2NvbXByZXNzb3IuYXR0YWNrLCBUb25lLlR5cGUuVGltZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHJlbGVhc2UgcGFyYW1ldGVyXG5cdFx0XHQgKiAgQHR5cGUge1RpbWV9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5yZWxlYXNlID0gbmV3IFRvbmUuUGFyYW0odGhpcy5fY29tcHJlc3Nvci5yZWxlYXNlLCBUb25lLlR5cGUuVGltZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGtuZWUgcGFyYW1ldGVyXG5cdFx0XHQgKiAgQHR5cGUge0RlY2liZWxzfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMua25lZSA9IG5ldyBUb25lLlBhcmFtKHtcblx0ICAgICAgICAgICAgJ3BhcmFtJzogdGhpcy5fY29tcHJlc3Nvci5rbmVlLFxuXHQgICAgICAgICAgICAndW5pdHMnOiBUb25lLlR5cGUuRGVjaWJlbHMsXG5cdCAgICAgICAgICAgICdjb252ZXJ0JzogZmFsc2Vcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgcmF0aW8gdmFsdWVcblx0XHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMucmF0aW8gPSBuZXcgVG9uZS5QYXJhbSh7XG5cdCAgICAgICAgICAgICdwYXJhbSc6IHRoaXMuX2NvbXByZXNzb3IucmF0aW8sXG5cdCAgICAgICAgICAgICdjb252ZXJ0JzogZmFsc2Vcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvL3NldCB0aGUgZGVmYXVsdHNcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdrbmVlJyxcblx0ICAgICAgICAgICAgJ3JlbGVhc2UnLFxuXHQgICAgICAgICAgICAnYXR0YWNrJyxcblx0ICAgICAgICAgICAgJ3JhdGlvJyxcblx0ICAgICAgICAgICAgJ3RocmVzaG9sZCdcblx0ICAgICAgICBdKTtcblx0ICAgICAgICB0aGlzLnNldChvcHRpb25zKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkNvbXByZXNzb3IsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBjb25zdFxuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Db21wcmVzc29yLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdyYXRpbyc6IDEyLFxuXHQgICAgICAgICd0aHJlc2hvbGQnOiAtMjQsXG5cdCAgICAgICAgJ3JlbGVhc2UnOiAwLjI1LFxuXHQgICAgICAgICdhdHRhY2snOiAwLjAwMyxcblx0ICAgICAgICAna25lZSc6IDMwXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkNvbXByZXNzb3J9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuQ29tcHJlc3Nvci5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ2tuZWUnLFxuXHQgICAgICAgICAgICAncmVsZWFzZScsXG5cdCAgICAgICAgICAgICdhdHRhY2snLFxuXHQgICAgICAgICAgICAncmF0aW8nLFxuXHQgICAgICAgICAgICAndGhyZXNob2xkJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMuX2NvbXByZXNzb3IuZGlzY29ubmVjdCgpO1xuXHQgICAgICAgIHRoaXMuX2NvbXByZXNzb3IgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuYXR0YWNrLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmF0dGFjayA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5yZWxlYXNlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLnJlbGVhc2UgPSBudWxsO1xuXHQgICAgICAgIHRoaXMudGhyZXNob2xkLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLnRocmVzaG9sZCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5yYXRpby5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5yYXRpbyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5rbmVlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmtuZWUgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkNvbXByZXNzb3I7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBBZGQgYSBzaWduYWwgYW5kIGEgbnVtYmVyIG9yIHR3byBzaWduYWxzLiBXaGVuIG5vIHZhbHVlIGlzXG5cdFx0ICogICAgICAgICBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IsIFRvbmUuQWRkIHdpbGwgc3VtIDxjb2RlPmlucHV0WzBdPC9jb2RlPlxuXHRcdCAqICAgICAgICAgYW5kIDxjb2RlPmlucHV0WzFdPC9jb2RlPi4gSWYgYSB2YWx1ZSBpcyBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IsIFxuXHRcdCAqICAgICAgICAgdGhlIGl0IHdpbGwgYmUgYWRkZWQgdG8gdGhlIGlucHV0LlxuXHRcdCAqICBcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlNpZ25hbH1cblx0XHQgKiAgQHBhcmFtIHtudW1iZXI9fSB2YWx1ZSBJZiBubyB2YWx1ZSBpcyBwcm92aWRlZCwgVG9uZS5BZGQgd2lsbCBzdW0gdGhlIGZpcnN0XG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgYW5kIHNlY29uZCBpbnB1dHMuIFxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMik7XG5cdFx0ICogdmFyIGFkZCA9IG5ldyBUb25lLkFkZCgyKTtcblx0XHQgKiBzaWduYWwuY29ubmVjdChhZGQpO1xuXHRcdCAqIC8vdGhlIG91dHB1dCBvZiBhZGQgZXF1YWxzIDRcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL2lmIGNvbnN0cnVjdGVkIHdpdGggbm8gYXJndW1lbnRzXG5cdFx0ICogLy9pdCB3aWxsIGFkZCB0aGUgZmlyc3QgYW5kIHNlY29uZCBpbnB1dHNcblx0XHQgKiB2YXIgYWRkID0gbmV3IFRvbmUuQWRkKCk7XG5cdFx0ICogdmFyIHNpZzAgPSBuZXcgVG9uZS5TaWduYWwoMykuY29ubmVjdChhZGQsIDAsIDApO1xuXHRcdCAqIHZhciBzaWcxID0gbmV3IFRvbmUuU2lnbmFsKDQpLmNvbm5lY3QoYWRkLCAwLCAxKTtcblx0XHQgKiAvL3RoZSBvdXRwdXQgb2YgYWRkIGVxdWFscyA3LiBcblx0XHQgKi9cblx0ICAgIFRvbmUuQWRkID0gZnVuY3Rpb24gKHZhbHVlKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWwuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLmNyZWF0ZUluc091dHMoMiwgMCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIHN1bW1pbmcgbm9kZVxuXHRcdFx0ICogIEB0eXBlIHtHYWluTm9kZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3VtID0gdGhpcy5pbnB1dFswXSA9IHRoaXMuaW5wdXRbMV0gPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLlNpZ25hbH1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3BhcmFtID0gdGhpcy5pbnB1dFsxXSA9IG5ldyBUb25lLlNpZ25hbCh2YWx1ZSk7XG5cdCAgICAgICAgdGhpcy5fcGFyYW0uY29ubmVjdCh0aGlzLl9zdW0pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuQWRkLCBUb25lLlNpZ25hbCk7XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkFkZH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5BZGQucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWwucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9zdW0uZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3N1bSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuQWRkO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIE11bHRpcGx5IHR3byBpbmNvbWluZyBzaWduYWxzLiBPciwgaWYgYSBudW1iZXIgaXMgZ2l2ZW4gaW4gdGhlIGNvbnN0cnVjdG9yLFxuXHRcdCAqICAgICAgICAgIG11bHRpcGxpZXMgdGhlIGluY29taW5nIHNpZ25hbCBieSB0aGF0IHZhbHVlLlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5TaWduYWx9XG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyPX0gdmFsdWUgQ29uc3RhbnQgdmFsdWUgdG8gbXVsdGlwbGUuIElmIG5vIHZhbHVlIGlzIHByb3ZpZGVkLFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgIGl0IHdpbGwgcmV0dXJuIHRoZSBwcm9kdWN0IG9mIHRoZSBmaXJzdCBhbmQgc2Vjb25kIGlucHV0c1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBtdWx0ID0gbmV3IFRvbmUuTXVsdGlwbHkoKTtcblx0XHQgKiB2YXIgc2lnQSA9IG5ldyBUb25lLlNpZ25hbCgzKTtcblx0XHQgKiB2YXIgc2lnQiA9IG5ldyBUb25lLlNpZ25hbCg0KTtcblx0XHQgKiBzaWdBLmNvbm5lY3QobXVsdCwgMCwgMCk7XG5cdFx0ICogc2lnQi5jb25uZWN0KG11bHQsIDAsIDEpO1xuXHRcdCAqIC8vb3V0cHV0IG9mIG11bHQgaXMgMTIuXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIG11bHQgPSBuZXcgVG9uZS5NdWx0aXBseSgxMCk7XG5cdFx0ICogdmFyIHNpZyA9IG5ldyBUb25lLlNpZ25hbCgyKS5jb25uZWN0KG11bHQpO1xuXHRcdCAqIC8vdGhlIG91dHB1dCBvZiBtdWx0IGlzIDIwLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5NdWx0aXBseSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHQgICAgICAgIFRvbmUuU2lnbmFsLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5jcmVhdGVJbnNPdXRzKDIsIDApO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBpbnB1dCBub2RlIGlzIHRoZSBzYW1lIGFzIHRoZSBvdXRwdXQgbm9kZVxuXHRcdFx0ICogIGl0IGlzIGFsc28gdGhlIEdhaW5Ob2RlIHdoaWNoIGhhbmRsZXMgdGhlIHNjYWxpbmcgb2YgaW5jb21pbmcgc2lnbmFsXG5cdFx0XHQgKlxuXHRcdFx0ICogIEB0eXBlIHtHYWluTm9kZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbXVsdCA9IHRoaXMuaW5wdXRbMF0gPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgc2NhbGluZyBwYXJhbWV0ZXJcblx0XHRcdCAqICBAdHlwZSB7QXVkaW9QYXJhbX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fcGFyYW0gPSB0aGlzLmlucHV0WzFdID0gdGhpcy5vdXRwdXQuZ2Fpbjtcblx0ICAgICAgICB0aGlzLnZhbHVlID0gVG9uZS5kZWZhdWx0QXJnKHZhbHVlLCAwKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLk11bHRpcGx5LCBUb25lLlNpZ25hbCk7XG5cdCAgICAvKipcblx0XHQgKiAgY2xlYW4gdXBcblx0XHQgKiAgQHJldHVybnMge1RvbmUuTXVsdGlwbHl9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTXVsdGlwbHkucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWwucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9tdWx0LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9tdWx0ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9wYXJhbSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuTXVsdGlwbHk7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBOZWdhdGUgdGhlIGluY29taW5nIHNpZ25hbC4gaS5lLiBhbiBpbnB1dCBzaWduYWwgb2YgMTAgd2lsbCBvdXRwdXQgLTEwXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlNpZ25hbEJhc2V9XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIG5lZyA9IG5ldyBUb25lLk5lZ2F0ZSgpO1xuXHRcdCAqIHZhciBzaWcgPSBuZXcgVG9uZS5TaWduYWwoLTIpLmNvbm5lY3QobmVnKTtcblx0XHQgKiAvL291dHB1dCBvZiBuZWcgaXMgcG9zaXRpdmUgMi4gXG5cdFx0ICovXG5cdCAgICBUb25lLk5lZ2F0ZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBuZWdhdGlvbiBpcyBkb25lIGJ5IG11bHRpcGx5aW5nIGJ5IC0xXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuTXVsdGlwbHl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX211bHRpcGx5ID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gbmV3IFRvbmUuTXVsdGlwbHkoLTEpO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuTmVnYXRlLCBUb25lLlNpZ25hbEJhc2UpO1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk5lZ2F0ZX0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5OZWdhdGUucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWxCYXNlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fbXVsdGlwbHkuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX211bHRpcGx5ID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5OZWdhdGU7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBTdWJ0cmFjdCB0aGUgc2lnbmFsIGNvbm5lY3RlZCB0byA8Y29kZT5pbnB1dFsxXTwvY29kZT4gZnJvbSB0aGUgc2lnbmFsIGNvbm5lY3RlZCBcblx0XHQgKiAgICAgICAgIHRvIDxjb2RlPmlucHV0WzBdPC9jb2RlPi4gSWYgYW4gYXJndW1lbnQgaXMgcHJvdmlkZWQgaW4gdGhlIGNvbnN0cnVjdG9yLCB0aGUgXG5cdFx0ICogICAgICAgICBzaWduYWxzIDxjb2RlPi52YWx1ZTwvY29kZT4gd2lsbCBiZSBzdWJ0cmFjdGVkIGZyb20gdGhlIGluY29taW5nIHNpZ25hbC5cblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5TaWduYWx9XG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAcGFyYW0ge251bWJlcj19IHZhbHVlIFRoZSB2YWx1ZSB0byBzdWJ0cmFjdCBmcm9tIHRoZSBpbmNvbWluZyBzaWduYWwuIElmIHRoZSB2YWx1ZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgIGlzIG9taXR0ZWQsIGl0IHdpbGwgc3VidHJhY3QgdGhlIHNlY29uZCBzaWduYWwgZnJvbSB0aGUgZmlyc3QuXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHN1YiA9IG5ldyBUb25lLlN1YnRyYWN0KDEpO1xuXHRcdCAqIHZhciBzaWcgPSBuZXcgVG9uZS5TaWduYWwoNCkuY29ubmVjdChzdWIpO1xuXHRcdCAqIC8vdGhlIG91dHB1dCBvZiBzdWIgaXMgMy4gXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHN1YiA9IG5ldyBUb25lLlN1YnRyYWN0KCk7XG5cdFx0ICogdmFyIHNpZ0EgPSBuZXcgVG9uZS5TaWduYWwoMTApO1xuXHRcdCAqIHZhciBzaWdCID0gbmV3IFRvbmUuU2lnbmFsKDIuNSk7XG5cdFx0ICogc2lnQS5jb25uZWN0KHN1YiwgMCwgMCk7XG5cdFx0ICogc2lnQi5jb25uZWN0KHN1YiwgMCwgMSk7XG5cdFx0ICogLy9vdXRwdXQgb2Ygc3ViIGlzIDcuNVxuXHRcdCAqL1xuXHQgICAgVG9uZS5TdWJ0cmFjdCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHQgICAgICAgIFRvbmUuU2lnbmFsLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5jcmVhdGVJbnNPdXRzKDIsIDApO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBzdW1taW5nIG5vZGVcblx0XHRcdCAqICBAdHlwZSB7R2Fpbk5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3N1bSA9IHRoaXMuaW5wdXRbMF0gPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBuZWdhdGUgdGhlIGlucHV0IG9mIHRoZSBzZWNvbmQgaW5wdXQgYmVmb3JlIGNvbm5lY3RpbmcgaXRcblx0XHRcdCAqICB0byB0aGUgc3VtbWluZyBub2RlLlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLk5lZ2F0ZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbmVnID0gbmV3IFRvbmUuTmVnYXRlKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIG5vZGUgd2hlcmUgdGhlIHZhbHVlIGlzIHNldFxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuU2lnbmFsfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fcGFyYW0gPSB0aGlzLmlucHV0WzFdID0gbmV3IFRvbmUuU2lnbmFsKHZhbHVlKTtcblx0ICAgICAgICB0aGlzLl9wYXJhbS5jaGFpbih0aGlzLl9uZWcsIHRoaXMuX3N1bSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5TdWJ0cmFjdCwgVG9uZS5TaWduYWwpO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5TaWduYWxCYXNlfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlN1YnRyYWN0LnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuU2lnbmFsLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fbmVnLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9uZWcgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3N1bS5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgdGhpcy5fc3VtID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5TdWJ0cmFjdDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIENvbnZlcnQgYW4gaW5jb21pbmcgc2lnbmFsIGJldHdlZW4gMCwgMSB0byBhbiBlcXVhbCBwb3dlciBnYWluIHNjYWxlLlxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlNpZ25hbEJhc2V9XG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBlcVBvd0dhaW4gPSBuZXcgVG9uZS5FcXVhbFBvd2VyR2FpbigpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5FcXVhbFBvd2VyR2FpbiA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5XYXZlU2hhcGVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9lcVBvd2VyID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gbmV3IFRvbmUuV2F2ZVNoYXBlcihmdW5jdGlvbiAodmFsKSB7XG5cdCAgICAgICAgICAgIGlmIChNYXRoLmFicyh2YWwpIDwgMC4wMDEpIHtcblx0ICAgICAgICAgICAgICAgIC8vc2hvdWxkIG91dHB1dCAwIHdoZW4gaW5wdXQgaXMgMFxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gVG9uZS5lcXVhbFBvd2VyU2NhbGUodmFsKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0uYmluZCh0aGlzKSwgNDA5Nik7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5FcXVhbFBvd2VyR2FpbiwgVG9uZS5TaWduYWxCYXNlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBjbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5FcXVhbFBvd2VyR2Fpbn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5FcXVhbFBvd2VyR2Fpbi5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9lcVBvd2VyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9lcVBvd2VyID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5FcXVhbFBvd2VyR2Fpbjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiBAY2xhc3MgIFRvbmUuQ3Jvc3NmYWRlIHByb3ZpZGVzIGVxdWFsIHBvd2VyIGZhZGluZyBiZXR3ZWVuIHR3byBpbnB1dHMuXG5cdFx0ICogICAgICAgICBNb3JlIG9uIGNyb3NzZmFkaW5nIHRlY2huaXF1ZSBbaGVyZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRmFkZV8oYXVkaW9fZW5naW5lZXJpbmcpI0Nyb3NzZmFkaW5nKS5cblx0XHQgKlxuXHRcdCAqIEBjb25zdHJ1Y3RvclxuXHRcdCAqIEBleHRlbmRzIHtUb25lLkF1ZGlvTm9kZX1cblx0XHQgKiBAcGFyYW0ge05vcm1hbFJhbmdlfSBbaW5pdGlhbEZhZGU9MC41XVxuXHRcdCAqIEBleGFtcGxlXG5cdFx0ICogdmFyIGNyb3NzRmFkZSA9IG5ldyBUb25lLkNyb3NzRmFkZSgwLjUpO1xuXHRcdCAqIC8vY29ubmVjdCBlZmZlY3QgQSB0byBjcm9zc2ZhZGUgZnJvbVxuXHRcdCAqIC8vZWZmZWN0IG91dHB1dCAwIHRvIGNyb3NzZmFkZSBpbnB1dCAwXG5cdFx0ICogZWZmZWN0QS5jb25uZWN0KGNyb3NzRmFkZSwgMCwgMCk7XG5cdFx0ICogLy9jb25uZWN0IGVmZmVjdCBCIHRvIGNyb3NzZmFkZSBmcm9tXG5cdFx0ICogLy9lZmZlY3Qgb3V0cHV0IDAgdG8gY3Jvc3NmYWRlIGlucHV0IDFcblx0XHQgKiBlZmZlY3RCLmNvbm5lY3QoY3Jvc3NGYWRlLCAwLCAxKTtcblx0XHQgKiBjcm9zc0ZhZGUuZmFkZS52YWx1ZSA9IDA7XG5cdFx0ICogLy8gXiBvbmx5IGVmZmVjdEEgaXMgb3V0cHV0XG5cdFx0ICogY3Jvc3NGYWRlLmZhZGUudmFsdWUgPSAxO1xuXHRcdCAqIC8vIF4gb25seSBlZmZlY3RCIGlzIG91dHB1dFxuXHRcdCAqIGNyb3NzRmFkZS5mYWRlLnZhbHVlID0gMC41O1xuXHRcdCAqIC8vIF4gdGhlIHR3byBzaWduYWxzIGFyZSBtaXhlZCBlcXVhbGx5LlxuXHRcdCAqL1xuXHQgICAgVG9uZS5Dcm9zc0ZhZGUgPSBmdW5jdGlvbiAoaW5pdGlhbEZhZGUpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuY3JlYXRlSW5zT3V0cygyLCAxKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBBbGlhcyBmb3IgPGNvZGU+aW5wdXRbMF08L2NvZGU+LlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkdhaW59XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmEgPSB0aGlzLmlucHV0WzBdID0gbmV3IFRvbmUuR2FpbigpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEFsaWFzIGZvciA8Y29kZT5pbnB1dFsxXTwvY29kZT4uXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuR2Fpbn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuYiA9IHRoaXMuaW5wdXRbMV0gPSBuZXcgVG9uZS5HYWluKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBcdFRoZSBtaXggYmV0d2VlbiB0aGUgdHdvIGlucHV0cy4gQSBmYWRlIHZhbHVlIG9mIDBcblx0XHRcdCAqIFx0d2lsbCBvdXRwdXQgMTAwJSA8Y29kZT5pbnB1dFswXTwvY29kZT4gYW5kXG5cdFx0XHQgKiBcdGEgdmFsdWUgb2YgMSB3aWxsIG91dHB1dCAxMDAlIDxjb2RlPmlucHV0WzFdPC9jb2RlPi5cblx0XHRcdCAqICBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5mYWRlID0gbmV3IFRvbmUuU2lnbmFsKFRvbmUuZGVmYXVsdEFyZyhpbml0aWFsRmFkZSwgMC41KSwgVG9uZS5UeXBlLk5vcm1hbFJhbmdlKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBlcXVhbCBwb3dlciBnYWluIGNyb3NzIGZhZGVcblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkVxdWFsUG93ZXJHYWlufVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZXF1YWxQb3dlckEgPSBuZXcgVG9uZS5FcXVhbFBvd2VyR2FpbigpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGVxdWFsIHBvd2VyIGdhaW4gY3Jvc3MgZmFkZVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuRXF1YWxQb3dlckdhaW59XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9lcXVhbFBvd2VyQiA9IG5ldyBUb25lLkVxdWFsUG93ZXJHYWluKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgaW52ZXJ0IHRoZSBpbmNvbWluZyBzaWduYWxcblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fb25lID0gdGhpcy5jb250ZXh0LmdldENvbnN0YW50KDEpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGludmVydCB0aGUgaW5jb21pbmcgc2lnbmFsXG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5TdWJ0cmFjdH1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ludmVydCA9IG5ldyBUb25lLlN1YnRyYWN0KCk7XG5cdCAgICAgICAgLy9jb25uZWN0aW9uc1xuXHQgICAgICAgIHRoaXMuYS5jb25uZWN0KHRoaXMub3V0cHV0KTtcblx0ICAgICAgICB0aGlzLmIuY29ubmVjdCh0aGlzLm91dHB1dCk7XG5cdCAgICAgICAgdGhpcy5mYWRlLmNoYWluKHRoaXMuX2VxdWFsUG93ZXJCLCB0aGlzLmIuZ2Fpbik7XG5cdCAgICAgICAgdGhpcy5fb25lLmNvbm5lY3QodGhpcy5faW52ZXJ0LCAwLCAwKTtcblx0ICAgICAgICB0aGlzLmZhZGUuY29ubmVjdCh0aGlzLl9pbnZlcnQsIDAsIDEpO1xuXHQgICAgICAgIHRoaXMuX2ludmVydC5jaGFpbih0aGlzLl9lcXVhbFBvd2VyQSwgdGhpcy5hLmdhaW4pO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KCdmYWRlJyk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5Dcm9zc0ZhZGUsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBjbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5Dcm9zc0ZhZGV9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuQ3Jvc3NGYWRlLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoJ2ZhZGUnKTtcblx0ICAgICAgICB0aGlzLl9lcXVhbFBvd2VyQS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fZXF1YWxQb3dlckEgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2VxdWFsUG93ZXJCLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9lcXVhbFBvd2VyQiA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5mYWRlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmZhZGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2ludmVydC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5faW52ZXJ0ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9vbmUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuYS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5hID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmIuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuYiA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuQ3Jvc3NGYWRlO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIFRvbmUuRmlsdGVyIGlzIGEgZmlsdGVyIHdoaWNoIGFsbG93cyBmb3IgYWxsIG9mIHRoZSBzYW1lIG5hdGl2ZSBtZXRob2RzXG5cdFx0ICogICAgICAgICAgYXMgdGhlIFtCaXF1YWRGaWx0ZXJOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1iaXF1YWRmaWx0ZXJub2RlLWludGVyZmFjZSkuXG5cdFx0ICogICAgICAgICAgVG9uZS5GaWx0ZXIgaGFzIHRoZSBhZGRlZCBhYmlsaXR5IHRvIHNldCB0aGUgZmlsdGVyIHJvbGxvZmYgYXQgLTEyXG5cdFx0ICogICAgICAgICAgKGRlZmF1bHQpLCAtMjQgYW5kIC00OC5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuQXVkaW9Ob2RlfVxuXHRcdCAqICBAcGFyYW0ge0ZyZXF1ZW5jeXxPYmplY3R9IFtmcmVxdWVuY3ldIFRoZSBjdXRvZmYgZnJlcXVlbmN5IG9mIHRoZSBmaWx0ZXIuXG5cdFx0ICogIEBwYXJhbSB7c3RyaW5nPX0gdHlwZSBUaGUgdHlwZSBvZiBmaWx0ZXIuXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyPX0gcm9sbG9mZiBUaGUgZHJvcCBpbiBkZWNpYmVscyBwZXIgb2N0YXZlIGFmdGVyIHRoZSBjdXRvZmYgZnJlcXVlbmN5LlxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIDMgY2hvaWNlczogLTEyLCAtMjQsIGFuZCAtNDhcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAgdmFyIGZpbHRlciA9IG5ldyBUb25lLkZpbHRlcigyMDAsIFwiaGlnaHBhc3NcIik7XG5cdFx0ICovXG5cdCAgICBUb25lLkZpbHRlciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAndHlwZScsXG5cdCAgICAgICAgICAgICdyb2xsb2ZmJ1xuXHQgICAgICAgIF0sIFRvbmUuRmlsdGVyKTtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuY3JlYXRlSW5zT3V0cygxLCAxKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgZmlsdGVyKHMpXG5cdFx0XHQgKiAgQHR5cGUge0FycmF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9maWx0ZXJzID0gW107XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGN1dG9mZiBmcmVxdWVuY3kgb2YgdGhlIGZpbHRlci5cblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFRvbmUuU2lnbmFsKG9wdGlvbnMuZnJlcXVlbmN5LCBUb25lLlR5cGUuRnJlcXVlbmN5KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZGV0dW5lIHBhcmFtZXRlclxuXHRcdFx0ICogIEB0eXBlIHtDZW50c31cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBUb25lLlNpZ25hbCgwLCBUb25lLlR5cGUuQ2VudHMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBnYWluIG9mIHRoZSBmaWx0ZXIsIG9ubHkgdXNlZCBpbiBjZXJ0YWluIGZpbHRlciB0eXBlc1xuXHRcdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5nYWluID0gbmV3IFRvbmUuU2lnbmFsKHtcblx0ICAgICAgICAgICAgJ3ZhbHVlJzogb3B0aW9ucy5nYWluLFxuXHQgICAgICAgICAgICAnY29udmVydCc6IGZhbHNlXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIFEgb3IgUXVhbGl0eSBvZiB0aGUgZmlsdGVyXG5cdFx0XHQgKiAgQHR5cGUge1Bvc2l0aXZlfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuUSA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLlEpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSB0eXBlIG9mIHRoZSBmaWx0ZXJcblx0XHRcdCAqICBAdHlwZSB7c3RyaW5nfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl90eXBlID0gb3B0aW9ucy50eXBlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSByb2xsb2ZmIHZhbHVlIG9mIHRoZSBmaWx0ZXJcblx0XHRcdCAqICBAdHlwZSB7bnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9yb2xsb2ZmID0gb3B0aW9ucy5yb2xsb2ZmO1xuXHQgICAgICAgIC8vc2V0IHRoZSByb2xsb2ZmO1xuXHQgICAgICAgIHRoaXMucm9sbG9mZiA9IG9wdGlvbnMucm9sbG9mZjtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdkZXR1bmUnLFxuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2dhaW4nLFxuXHQgICAgICAgICAgICAnUSdcblx0ICAgICAgICBdKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkZpbHRlciwgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIHRoZSBkZWZhdWx0IHBhcmFtZXRlcnNcblx0XHQgKlxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkZpbHRlci5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAndHlwZSc6ICdsb3dwYXNzJyxcblx0ICAgICAgICAnZnJlcXVlbmN5JzogMzUwLFxuXHQgICAgICAgICdyb2xsb2ZmJzogLTEyLFxuXHQgICAgICAgICdRJzogMSxcblx0ICAgICAgICAnZ2Fpbic6IDBcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgdHlwZSBvZiB0aGUgZmlsdGVyLiBUeXBlczogXCJsb3dwYXNzXCIsIFwiaGlnaHBhc3NcIixcblx0XHQgKiBcImJhbmRwYXNzXCIsIFwibG93c2hlbGZcIiwgXCJoaWdoc2hlbGZcIiwgXCJub3RjaFwiLCBcImFsbHBhc3NcIiwgb3IgXCJwZWFraW5nXCIuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuRmlsdGVyI1xuXHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0ICogQG5hbWUgdHlwZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuRmlsdGVyLnByb3RvdHlwZSwgJ3R5cGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodHlwZSkge1xuXHQgICAgICAgICAgICB2YXIgdHlwZXMgPSBbXG5cdCAgICAgICAgICAgICAgICAnbG93cGFzcycsXG5cdCAgICAgICAgICAgICAgICAnaGlnaHBhc3MnLFxuXHQgICAgICAgICAgICAgICAgJ2JhbmRwYXNzJyxcblx0ICAgICAgICAgICAgICAgICdsb3dzaGVsZicsXG5cdCAgICAgICAgICAgICAgICAnaGlnaHNoZWxmJyxcblx0ICAgICAgICAgICAgICAgICdub3RjaCcsXG5cdCAgICAgICAgICAgICAgICAnYWxscGFzcycsXG5cdCAgICAgICAgICAgICAgICAncGVha2luZydcblx0ICAgICAgICAgICAgXTtcblx0ICAgICAgICAgICAgaWYgKHR5cGVzLmluZGV4T2YodHlwZSkgPT09IC0xKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUb25lLkZpbHRlcjogaW52YWxpZCB0eXBlICcgKyB0eXBlKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLl9maWx0ZXJzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9maWx0ZXJzW2ldLnR5cGUgPSB0eXBlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcm9sbG9mZiBvZiB0aGUgZmlsdGVyIHdoaWNoIGlzIHRoZSBkcm9wIGluIGRiXG5cdFx0ICogcGVyIG9jdGF2ZS4gSW1wbGVtZW50ZWQgaW50ZXJuYWxseSBieSBjYXNjYWRpbmcgZmlsdGVycy5cblx0XHQgKiBPbmx5IGFjY2VwdHMgdGhlIHZhbHVlcyAtMTIsIC0yNCwgLTQ4IGFuZCAtOTYuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuRmlsdGVyI1xuXHRcdCAqIEB0eXBlIHtudW1iZXJ9XG5cdFx0ICogQG5hbWUgcm9sbG9mZlxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuRmlsdGVyLnByb3RvdHlwZSwgJ3JvbGxvZmYnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9yb2xsb2ZmO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocm9sbG9mZikge1xuXHQgICAgICAgICAgICByb2xsb2ZmID0gcGFyc2VJbnQocm9sbG9mZiwgMTApO1xuXHQgICAgICAgICAgICB2YXIgcG9zc2liaWxpdGllcyA9IFtcblx0ICAgICAgICAgICAgICAgIC0xMixcblx0ICAgICAgICAgICAgICAgIC0yNCxcblx0ICAgICAgICAgICAgICAgIC00OCxcblx0ICAgICAgICAgICAgICAgIC05NlxuXHQgICAgICAgICAgICBdO1xuXHQgICAgICAgICAgICB2YXIgY2FzY2FkaW5nQ291bnQgPSBwb3NzaWJpbGl0aWVzLmluZGV4T2Yocm9sbG9mZik7XG5cdCAgICAgICAgICAgIC8vY2hlY2sgdGhlIHJvbGxvZmYgaXMgdmFsaWRcblx0ICAgICAgICAgICAgaWYgKGNhc2NhZGluZ0NvdW50ID09PSAtMSkge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RvbmUuRmlsdGVyOiByb2xsb2ZmIGNhbiBvbmx5IGJlIC0xMiwgLTI0LCAtNDggb3IgLTk2Jyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY2FzY2FkaW5nQ291bnQgKz0gMTtcblx0ICAgICAgICAgICAgdGhpcy5fcm9sbG9mZiA9IHJvbGxvZmY7XG5cdCAgICAgICAgICAgIC8vZmlyc3QgZGlzY29ubmVjdCB0aGUgZmlsdGVycyBhbmQgdGhyb3cgdGhlbSBhd2F5XG5cdCAgICAgICAgICAgIHRoaXMuaW5wdXQuZGlzY29ubmVjdCgpO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX2ZpbHRlcnMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2ZpbHRlcnNbaV0uZGlzY29ubmVjdCgpO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fZmlsdGVyc1tpXSA9IG51bGw7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5fZmlsdGVycyA9IG5ldyBBcnJheShjYXNjYWRpbmdDb3VudCk7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGNvdW50ID0gMDsgY291bnQgPCBjYXNjYWRpbmdDb3VudDsgY291bnQrKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcblx0ICAgICAgICAgICAgICAgIGZpbHRlci50eXBlID0gdGhpcy5fdHlwZTtcblx0ICAgICAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QoZmlsdGVyLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgICAgICAgICB0aGlzLmRldHVuZS5jb25uZWN0KGZpbHRlci5kZXR1bmUpO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5RLmNvbm5lY3QoZmlsdGVyLlEpO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5nYWluLmNvbm5lY3QoZmlsdGVyLmdhaW4pO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fZmlsdGVyc1tjb3VudF0gPSBmaWx0ZXI7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgLy9jb25uZWN0IHRoZW0gdXBcblx0ICAgICAgICAgICAgdmFyIGNvbm5lY3Rpb25DaGFpbiA9IFt0aGlzLmlucHV0XS5jb25jYXQodGhpcy5fZmlsdGVycykuY29uY2F0KFt0aGlzLm91dHB1dF0pO1xuXHQgICAgICAgICAgICBUb25lLmNvbm5lY3RTZXJpZXMuYXBwbHkoVG9uZSwgY29ubmVjdGlvbkNoYWluKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybiB7VG9uZS5GaWx0ZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuRmlsdGVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLl9maWx0ZXJzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2ZpbHRlcnNbaV0uZGlzY29ubmVjdCgpO1xuXHQgICAgICAgICAgICB0aGlzLl9maWx0ZXJzW2ldID0gbnVsbDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5fZmlsdGVycyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoW1xuXHQgICAgICAgICAgICAnZGV0dW5lJyxcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdnYWluJyxcblx0ICAgICAgICAgICAgJ1EnXG5cdCAgICAgICAgXSk7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuUS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuUSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZGV0dW5lID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmdhaW4uZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZ2FpbiA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuRmlsdGVyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgU3BsaXQgdGhlIGluY29taW5nIHNpZ25hbCBpbnRvIHRocmVlIGJhbmRzIChsb3csIG1pZCwgaGlnaClcblx0XHQgKiAgICAgICAgIHdpdGggdHdvIGNyb3Nzb3ZlciBmcmVxdWVuY3kgY29udHJvbHMuXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuQXVkaW9Ob2RlfVxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l8T2JqZWN0fSBbbG93RnJlcXVlbmN5XSB0aGUgbG93L21pZCBjcm9zc292ZXIgZnJlcXVlbmN5XG5cdFx0ICogIEBwYXJhbSB7RnJlcXVlbmN5fSBbaGlnaEZyZXF1ZW5jeV0gdGhlIG1pZC9oaWdoIGNyb3Nzb3ZlciBmcmVxdWVuY3lcblx0XHQgKi9cblx0ICAgIFRvbmUuTXVsdGliYW5kU3BsaXQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAnbG93RnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2hpZ2hGcmVxdWVuY3knXG5cdCAgICAgICAgXSwgVG9uZS5NdWx0aWJhbmRTcGxpdCk7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgaW5wdXRcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5HYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmlucHV0ID0gbmV3IFRvbmUuR2FpbigpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBvdXRwdXRzXG5cdFx0XHQgKiAgQHR5cGUge0FycmF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBBcnJheSgzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbG93IGJhbmQuIEFsaWFzIGZvciA8Y29kZT5vdXRwdXRbMF08L2NvZGU+XG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuRmlsdGVyfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5sb3cgPSB0aGlzLm91dHB1dFswXSA9IG5ldyBUb25lLkZpbHRlcigwLCAnbG93cGFzcycpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBsb3dlciBmaWx0ZXIgb2YgdGhlIG1pZCBiYW5kXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuRmlsdGVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9sb3dNaWRGaWx0ZXIgPSBuZXcgVG9uZS5GaWx0ZXIoMCwgJ2hpZ2hwYXNzJyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG1pZCBiYW5kIG91dHB1dC4gQWxpYXMgZm9yIDxjb2RlPm91dHB1dFsxXTwvY29kZT5cblx0XHRcdCAqICBAdHlwZSB7VG9uZS5GaWx0ZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLm1pZCA9IHRoaXMub3V0cHV0WzFdID0gbmV3IFRvbmUuRmlsdGVyKDAsICdsb3dwYXNzJyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGhpZ2ggYmFuZCBvdXRwdXQuIEFsaWFzIGZvciA8Y29kZT5vdXRwdXRbMl08L2NvZGU+XG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuRmlsdGVyfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5oaWdoID0gdGhpcy5vdXRwdXRbMl0gPSBuZXcgVG9uZS5GaWx0ZXIoMCwgJ2hpZ2hwYXNzJyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGxvdy9taWQgY3Jvc3NvdmVyIGZyZXF1ZW5jeS5cblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubG93RnJlcXVlbmN5ID0gbmV3IFRvbmUuU2lnbmFsKG9wdGlvbnMubG93RnJlcXVlbmN5LCBUb25lLlR5cGUuRnJlcXVlbmN5KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbWlkL2hpZ2ggY3Jvc3NvdmVyIGZyZXF1ZW5jeS5cblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeSA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLmhpZ2hGcmVxdWVuY3ksIFRvbmUuVHlwZS5GcmVxdWVuY3kpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBxdWFsaXR5IG9mIGFsbCB0aGUgZmlsdGVyc1xuXHRcdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5RID0gbmV3IFRvbmUuU2lnbmFsKG9wdGlvbnMuUSk7XG5cdCAgICAgICAgdGhpcy5pbnB1dC5mYW4odGhpcy5sb3csIHRoaXMuaGlnaCk7XG5cdCAgICAgICAgdGhpcy5pbnB1dC5jaGFpbih0aGlzLl9sb3dNaWRGaWx0ZXIsIHRoaXMubWlkKTtcblx0ICAgICAgICAvL3RoZSBmcmVxdWVuY3kgY29udHJvbCBzaWduYWxcblx0ICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeS5jb25uZWN0KHRoaXMubG93LmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgdGhpcy5sb3dGcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9sb3dNaWRGaWx0ZXIuZnJlcXVlbmN5KTtcblx0ICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kuY29ubmVjdCh0aGlzLm1pZC5mcmVxdWVuY3kpO1xuXHQgICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuaGlnaC5mcmVxdWVuY3kpO1xuXHQgICAgICAgIC8vdGhlIFEgdmFsdWVcblx0ICAgICAgICB0aGlzLlEuY29ubmVjdCh0aGlzLmxvdy5RKTtcblx0ICAgICAgICB0aGlzLlEuY29ubmVjdCh0aGlzLl9sb3dNaWRGaWx0ZXIuUSk7XG5cdCAgICAgICAgdGhpcy5RLmNvbm5lY3QodGhpcy5taWQuUSk7XG5cdCAgICAgICAgdGhpcy5RLmNvbm5lY3QodGhpcy5oaWdoLlEpO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFtcblx0ICAgICAgICAgICAgJ2hpZ2gnLFxuXHQgICAgICAgICAgICAnbWlkJyxcblx0ICAgICAgICAgICAgJ2xvdycsXG5cdCAgICAgICAgICAgICdoaWdoRnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2xvd0ZyZXF1ZW5jeSdcblx0ICAgICAgICBdKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLk11bHRpYmFuZFNwbGl0LCBUb25lLkF1ZGlvTm9kZSk7XG5cdCAgICAvKipcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5NdWx0aWJhbmRTcGxpdC5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnbG93RnJlcXVlbmN5JzogNDAwLFxuXHQgICAgICAgICdoaWdoRnJlcXVlbmN5JzogMjUwMCxcblx0ICAgICAgICAnUSc6IDFcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk11bHRpYmFuZFNwbGl0fSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk11bHRpYmFuZFNwbGl0LnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoW1xuXHQgICAgICAgICAgICAnaGlnaCcsXG5cdCAgICAgICAgICAgICdtaWQnLFxuXHQgICAgICAgICAgICAnbG93Jyxcblx0ICAgICAgICAgICAgJ2hpZ2hGcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnbG93RnJlcXVlbmN5J1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMubG93LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmxvdyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fbG93TWlkRmlsdGVyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9sb3dNaWRGaWx0ZXIgPSBudWxsO1xuXHQgICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLm1pZCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5oaWdoLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmhpZ2ggPSBudWxsO1xuXHQgICAgICAgIHRoaXMubG93RnJlcXVlbmN5LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuUS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5RID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5NdWx0aWJhbmRTcGxpdDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuRVEzIGlzIGEgdGhyZWUgYmFuZCBFUSB3aXRoIGNvbnRyb2wgb3ZlciBsb3csIG1pZCwgYW5kIGhpZ2ggZ2FpbiBhc1xuXHRcdCAqICAgICAgICAgd2VsbCBhcyB0aGUgbG93IGFuZCBoaWdoIGNyb3Nzb3ZlciBmcmVxdWVuY2llcy5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuQXVkaW9Ob2RlfVxuXHRcdCAqXG5cdFx0ICogIEBwYXJhbSB7RGVjaWJlbHN8T2JqZWN0fSBbbG93TGV2ZWxdIFRoZSBnYWluIGFwcGxpZWQgdG8gdGhlIGxvd3MuXG5cdFx0ICogIEBwYXJhbSB7RGVjaWJlbHN9IFttaWRMZXZlbF0gVGhlIGdhaW4gYXBwbGllZCB0byB0aGUgbWlkLlxuXHRcdCAqICBAcGFyYW0ge0RlY2liZWxzfSBbaGlnaExldmVsXSBUaGUgZ2FpbiBhcHBsaWVkIHRvIHRoZSBoaWdoLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBlcSA9IG5ldyBUb25lLkVRMygtMTAsIDMsIC0yMCk7XG5cdFx0ICovXG5cdCAgICBUb25lLkVRMyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdsb3cnLFxuXHQgICAgICAgICAgICAnbWlkJyxcblx0ICAgICAgICAgICAgJ2hpZ2gnXG5cdCAgICAgICAgXSwgVG9uZS5FUTMpO1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIG91dHB1dCBub2RlXG5cdFx0XHQgKiAgQHR5cGUge0dhaW5Ob2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbXVsdGliYW5kIHNwbGl0XG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuTXVsdGliYW5kU3BsaXR9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX211bHRpYmFuZFNwbGl0ID0gdGhpcy5pbnB1dCA9IG5ldyBUb25lLk11bHRpYmFuZFNwbGl0KHtcblx0ICAgICAgICAgICAgJ2xvd0ZyZXF1ZW5jeSc6IG9wdGlvbnMubG93RnJlcXVlbmN5LFxuXHQgICAgICAgICAgICAnaGlnaEZyZXF1ZW5jeSc6IG9wdGlvbnMuaGlnaEZyZXF1ZW5jeVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBnYWluIGZvciB0aGUgbG93ZXIgc2lnbmFsc1xuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5HYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9sb3dHYWluID0gbmV3IFRvbmUuR2FpbihvcHRpb25zLmxvdywgVG9uZS5UeXBlLkRlY2liZWxzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZ2FpbiBmb3IgdGhlIG1pZCBzaWduYWxzXG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLkdhaW59XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX21pZEdhaW4gPSBuZXcgVG9uZS5HYWluKG9wdGlvbnMubWlkLCBUb25lLlR5cGUuRGVjaWJlbHMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIGdhaW4gaW4gZGVjaWJlbHMgb2YgdGhlIGhpZ2ggcGFydFxuXHRcdFx0ICogQHR5cGUge1RvbmUuR2Fpbn1cblx0XHRcdCAqIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9oaWdoR2FpbiA9IG5ldyBUb25lLkdhaW4ob3B0aW9ucy5oaWdoLCBUb25lLlR5cGUuRGVjaWJlbHMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIGdhaW4gaW4gZGVjaWJlbHMgb2YgdGhlIGxvdyBwYXJ0XG5cdFx0XHQgKiBAdHlwZSB7RGVjaWJlbHN9XG5cdFx0XHQgKiBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmxvdyA9IHRoaXMuX2xvd0dhaW4uZ2Fpbjtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBnYWluIGluIGRlY2liZWxzIG9mIHRoZSBtaWQgcGFydFxuXHRcdFx0ICogQHR5cGUge0RlY2liZWxzfVxuXHRcdFx0ICogQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5taWQgPSB0aGlzLl9taWRHYWluLmdhaW47XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBUaGUgZ2FpbiBpbiBkZWNpYmVscyBvZiB0aGUgaGlnaCBwYXJ0XG5cdFx0XHQgKiBAdHlwZSB7RGVjaWJlbHN9XG5cdFx0XHQgKiBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmhpZ2ggPSB0aGlzLl9oaWdoR2Fpbi5nYWluO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBRIHZhbHVlIGZvciBhbGwgb2YgdGhlIGZpbHRlcnMuXG5cdFx0XHQgKiAgQHR5cGUge1Bvc2l0aXZlfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuUSA9IHRoaXMuX211bHRpYmFuZFNwbGl0LlE7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGxvdy9taWQgY3Jvc3NvdmVyIGZyZXF1ZW5jeS5cblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubG93RnJlcXVlbmN5ID0gdGhpcy5fbXVsdGliYW5kU3BsaXQubG93RnJlcXVlbmN5O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBtaWQvaGlnaCBjcm9zc292ZXIgZnJlcXVlbmN5LlxuXHRcdFx0ICogIEB0eXBlIHtGcmVxdWVuY3l9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5ID0gdGhpcy5fbXVsdGliYW5kU3BsaXQuaGlnaEZyZXF1ZW5jeTtcblx0ICAgICAgICAvL3RoZSBmcmVxdWVuY3kgYmFuZHNcblx0ICAgICAgICB0aGlzLl9tdWx0aWJhbmRTcGxpdC5sb3cuY2hhaW4odGhpcy5fbG93R2FpbiwgdGhpcy5vdXRwdXQpO1xuXHQgICAgICAgIHRoaXMuX211bHRpYmFuZFNwbGl0Lm1pZC5jaGFpbih0aGlzLl9taWRHYWluLCB0aGlzLm91dHB1dCk7XG5cdCAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQuaGlnaC5jaGFpbih0aGlzLl9oaWdoR2FpbiwgdGhpcy5vdXRwdXQpO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFtcblx0ICAgICAgICAgICAgJ2xvdycsXG5cdCAgICAgICAgICAgICdtaWQnLFxuXHQgICAgICAgICAgICAnaGlnaCcsXG5cdCAgICAgICAgICAgICdsb3dGcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnaGlnaEZyZXF1ZW5jeSdcblx0ICAgICAgICBdKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkVRMywgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIHRoZSBkZWZhdWx0IHZhbHVlc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5FUTMuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2xvdyc6IDAsXG5cdCAgICAgICAgJ21pZCc6IDAsXG5cdCAgICAgICAgJ2hpZ2gnOiAwLFxuXHQgICAgICAgICdsb3dGcmVxdWVuY3knOiA0MDAsXG5cdCAgICAgICAgJ2hpZ2hGcmVxdWVuY3knOiAyNTAwXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkVRM30gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5FUTMucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbXG5cdCAgICAgICAgICAgICdsb3cnLFxuXHQgICAgICAgICAgICAnbWlkJyxcblx0ICAgICAgICAgICAgJ2hpZ2gnLFxuXHQgICAgICAgICAgICAnbG93RnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2hpZ2hGcmVxdWVuY3knXG5cdCAgICAgICAgXSk7XG5cdCAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX211bHRpYmFuZFNwbGl0ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9sb3dHYWluLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9sb3dHYWluID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9taWRHYWluLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9taWRHYWluID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9oaWdoR2Fpbi5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5faGlnaEdhaW4gPSBudWxsO1xuXHQgICAgICAgIHRoaXMubG93ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLm1pZCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5oaWdoID0gbnVsbDtcblx0ICAgICAgICB0aGlzLlEgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkVRMztcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBQZXJmb3JtcyBhIGxpbmVhciBzY2FsaW5nIG9uIGFuIGlucHV0IHNpZ25hbC5cblx0XHQgKiAgICAgICAgICBTY2FsZXMgYSBOb3JtYWxSYW5nZSBpbnB1dCB0byBiZXR3ZWVuXG5cdFx0ICogICAgICAgICAgb3V0cHV0TWluIGFuZCBvdXRwdXRNYXguXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlNpZ25hbEJhc2V9XG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSBbb3V0cHV0TWluPTBdIFRoZSBvdXRwdXQgdmFsdWUgd2hlbiB0aGUgaW5wdXQgaXMgMC4gXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSBbb3V0cHV0TWF4PTFdXHRUaGUgb3V0cHV0IHZhbHVlIHdoZW4gdGhlIGlucHV0IGlzIDEuIFxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBzY2FsZSA9IG5ldyBUb25lLlNjYWxlKDUwLCAxMDApO1xuXHRcdCAqIHZhciBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMC41KS5jb25uZWN0KHNjYWxlKTtcblx0XHQgKiAvL3RoZSBvdXRwdXQgb2Ygc2NhbGUgZXF1YWxzIDc1XG5cdFx0ICovXG5cdCAgICBUb25lLlNjYWxlID0gZnVuY3Rpb24gKG91dHB1dE1pbiwgb3V0cHV0TWF4KSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWxCYXNlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqIFxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge251bWJlcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX291dHB1dE1pbiA9IFRvbmUuZGVmYXVsdEFyZyhvdXRwdXRNaW4sIDApO1xuXHQgICAgICAgIC8qKiBcblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICogIEB0eXBlIHtudW1iZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9vdXRwdXRNYXggPSBUb25lLmRlZmF1bHRBcmcob3V0cHV0TWF4LCAxKTtcblx0ICAgICAgICAvKiogXG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5NdWx0aXBseX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc2NhbGUgPSB0aGlzLmlucHV0ID0gbmV3IFRvbmUuTXVsdGlwbHkoMSk7XG5cdCAgICAgICAgLyoqIFxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQWRkfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9hZGQgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLkFkZCgwKTtcblx0ICAgICAgICB0aGlzLl9zY2FsZS5jb25uZWN0KHRoaXMuX2FkZCk7XG5cdCAgICAgICAgdGhpcy5fc2V0UmFuZ2UoKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlNjYWxlLCBUb25lLlNpZ25hbEJhc2UpO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIG1pbmltdW0gb3V0cHV0IHZhbHVlLiBUaGlzIG51bWJlciBpcyBvdXRwdXQgd2hlbiBcblx0XHQgKiB0aGUgdmFsdWUgaW5wdXQgdmFsdWUgaXMgMC4gXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuU2NhbGUjXG5cdFx0ICogQHR5cGUge251bWJlcn1cblx0XHQgKiBAbmFtZSBtaW5cblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlNjYWxlLnByb3RvdHlwZSwgJ21pbicsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX291dHB1dE1pbjtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKG1pbikge1xuXHQgICAgICAgICAgICB0aGlzLl9vdXRwdXRNaW4gPSBtaW47XG5cdCAgICAgICAgICAgIHRoaXMuX3NldFJhbmdlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgbWF4aW11bSBvdXRwdXQgdmFsdWUuIFRoaXMgbnVtYmVyIGlzIG91dHB1dCB3aGVuIFxuXHRcdCAqIHRoZSB2YWx1ZSBpbnB1dCB2YWx1ZSBpcyAxLiBcblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5TY2FsZSNcblx0XHQgKiBAdHlwZSB7bnVtYmVyfVxuXHRcdCAqIEBuYW1lIG1heFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuU2NhbGUucHJvdG90eXBlLCAnbWF4Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fb3V0cHV0TWF4O1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobWF4KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX291dHB1dE1heCA9IG1heDtcblx0ICAgICAgICAgICAgdGhpcy5fc2V0UmFuZ2UoKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBzZXQgdGhlIHZhbHVlc1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5TY2FsZS5wcm90b3R5cGUuX3NldFJhbmdlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuX2FkZC52YWx1ZSA9IHRoaXMuX291dHB1dE1pbjtcblx0ICAgICAgICB0aGlzLl9zY2FsZS52YWx1ZSA9IHRoaXMuX291dHB1dE1heCAtIHRoaXMuX291dHB1dE1pbjtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlNjYWxlfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlNjYWxlLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuU2lnbmFsQmFzZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX2FkZC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fYWRkID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9zY2FsZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fc2NhbGUgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlNjYWxlO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBQZXJmb3JtcyBhbiBleHBvbmVudGlhbCBzY2FsaW5nIG9uIGFuIGlucHV0IHNpZ25hbC5cblx0XHQgKiAgICAgICAgICBTY2FsZXMgYSBOb3JtYWxSYW5nZSB2YWx1ZSBbMCwxXSBleHBvbmVudGlhbGx5XG5cdFx0ICogICAgICAgICAgdG8gdGhlIG91dHB1dCByYW5nZSBvZiBvdXRwdXRNaW4gdG8gb3V0cHV0TWF4LlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5TaWduYWxCYXNlfVxuXHRcdCAqICBAcGFyYW0ge251bWJlcn0gW291dHB1dE1pbj0wXSBUaGUgb3V0cHV0IHZhbHVlIHdoZW4gdGhlIGlucHV0IGlzIDAuXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSBbb3V0cHV0TWF4PTFdXHRUaGUgb3V0cHV0IHZhbHVlIHdoZW4gdGhlIGlucHV0IGlzIDEuXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSBbZXhwb25lbnQ9Ml0gVGhlIGV4cG9uZW50IHdoaWNoIHNjYWxlcyB0aGUgaW5jb21pbmcgc2lnbmFsLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBzY2FsZUV4cCA9IG5ldyBUb25lLlNjYWxlRXhwKDAsIDEwMCwgMik7XG5cdFx0ICogdmFyIHNpZ25hbCA9IG5ldyBUb25lLlNpZ25hbCgwLjUpLmNvbm5lY3Qoc2NhbGVFeHApO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5TY2FsZUV4cCA9IGZ1bmN0aW9uIChvdXRwdXRNaW4sIG91dHB1dE1heCwgZXhwb25lbnQpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBzY2FsZSB0aGUgaW5wdXQgdG8gdGhlIG91dHB1dCByYW5nZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLlNjYWxlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9zY2FsZSA9IHRoaXMub3V0cHV0ID0gbmV3IFRvbmUuU2NhbGUob3V0cHV0TWluLCBvdXRwdXRNYXgpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuUG93fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9leHAgPSB0aGlzLmlucHV0ID0gbmV3IFRvbmUuUG93KFRvbmUuZGVmYXVsdEFyZyhleHBvbmVudCwgMikpO1xuXHQgICAgICAgIHRoaXMuX2V4cC5jb25uZWN0KHRoaXMuX3NjYWxlKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlNjYWxlRXhwLCBUb25lLlNpZ25hbEJhc2UpO1xuXHQgICAgLyoqXG5cdFx0ICogSW5zdGVhZCBvZiBpbnRlcnBvbGF0aW5nIGxpbmVhcmx5IGJldHdlZW4gdGhlIDxjb2RlPm1pbjwvY29kZT4gYW5kXG5cdFx0ICogPGNvZGU+bWF4PC9jb2RlPiB2YWx1ZXMsIHNldHRpbmcgdGhlIGV4cG9uZW50IHdpbGwgaW50ZXJwb2xhdGUgYmV0d2VlblxuXHRcdCAqIHRoZSB0d28gdmFsdWVzIHdpdGggYW4gZXhwb25lbnRpYWwgY3VydmUuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuU2NhbGVFeHAjXG5cdFx0ICogQHR5cGUge251bWJlcn1cblx0XHQgKiBAbmFtZSBleHBvbmVudFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuU2NhbGVFeHAucHJvdG90eXBlLCAnZXhwb25lbnQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9leHAudmFsdWU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChleHApIHtcblx0ICAgICAgICAgICAgdGhpcy5fZXhwLnZhbHVlID0gZXhwO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIG1pbmltdW0gb3V0cHV0IHZhbHVlLiBUaGlzIG51bWJlciBpcyBvdXRwdXQgd2hlblxuXHRcdCAqIHRoZSB2YWx1ZSBpbnB1dCB2YWx1ZSBpcyAwLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlNjYWxlRXhwI1xuXHRcdCAqIEB0eXBlIHtudW1iZXJ9XG5cdFx0ICogQG5hbWUgbWluXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5TY2FsZUV4cC5wcm90b3R5cGUsICdtaW4nLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9zY2FsZS5taW47XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChtaW4pIHtcblx0ICAgICAgICAgICAgdGhpcy5fc2NhbGUubWluID0gbWluO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIG1heGltdW0gb3V0cHV0IHZhbHVlLiBUaGlzIG51bWJlciBpcyBvdXRwdXQgd2hlblxuXHRcdCAqIHRoZSB2YWx1ZSBpbnB1dCB2YWx1ZSBpcyAxLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlNjYWxlRXhwI1xuXHRcdCAqIEB0eXBlIHtudW1iZXJ9XG5cdFx0ICogQG5hbWUgbWF4XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5TY2FsZUV4cC5wcm90b3R5cGUsICdtYXgnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9zY2FsZS5tYXg7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChtYXgpIHtcblx0ICAgICAgICAgICAgdGhpcy5fc2NhbGUubWF4ID0gbWF4O1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5TY2FsZUV4cH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5TY2FsZUV4cC5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9zY2FsZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fc2NhbGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2V4cC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fZXhwID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5TY2FsZUV4cDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFdyYXBwZXIgYXJvdW5kIFdlYiBBdWRpbydzIG5hdGl2ZSBbRGVsYXlOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1kZWxheW5vZGUtaW50ZXJmYWNlKS5cblx0XHQgKiAgQGV4dGVuZHMge1RvbmV9XG5cdFx0ICogIEBwYXJhbSB7VGltZT19IGRlbGF5VGltZSBUaGUgZGVsYXkgYXBwbGllZCB0byB0aGUgaW5jb21pbmcgc2lnbmFsLlxuXHRcdCAqICBAcGFyYW0ge1RpbWU9fSBtYXhEZWxheSBUaGUgbWF4aW11bSBkZWxheSB0aW1lLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5EZWxheSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdkZWxheVRpbWUnLFxuXHQgICAgICAgICAgICAnbWF4RGVsYXknXG5cdCAgICAgICAgXSwgVG9uZS5EZWxheSk7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBtYXhpbXVtIGRlbGF5IHRpbWUgaW5pdGlhbGl6ZWQgd2l0aCB0aGUgbm9kZVxuXHRcdFx0ICogQHR5cGUge051bWJlcn1cblx0XHRcdCAqIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9tYXhEZWxheSA9IE1hdGgubWF4KHRoaXMudG9TZWNvbmRzKG9wdGlvbnMubWF4RGVsYXkpLCB0aGlzLnRvU2Vjb25kcyhvcHRpb25zLmRlbGF5VGltZSkpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBuYXRpdmUgZGVsYXkgbm9kZVxuXHRcdFx0ICogIEB0eXBlIHtEZWxheU5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2RlbGF5Tm9kZSA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuY29udGV4dC5jcmVhdGVEZWxheSh0aGlzLl9tYXhEZWxheSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGFtb3VudCBvZiB0aW1lIHRoZSBpbmNvbWluZyBzaWduYWwgaXNcblx0XHRcdCAqICBkZWxheWVkLlxuXHRcdFx0ICogIEB0eXBlIHtUaW1lfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZGVsYXlUaW1lID0gbmV3IFRvbmUuUGFyYW0oe1xuXHQgICAgICAgICAgICAncGFyYW0nOiB0aGlzLl9kZWxheU5vZGUuZGVsYXlUaW1lLFxuXHQgICAgICAgICAgICAndW5pdHMnOiBUb25lLlR5cGUuVGltZSxcblx0ICAgICAgICAgICAgJ3ZhbHVlJzogb3B0aW9ucy5kZWxheVRpbWVcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seSgnZGVsYXlUaW1lJyk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5EZWxheSwgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0c1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkRlbGF5LmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdtYXhEZWxheSc6IDEsXG5cdCAgICAgICAgJ2RlbGF5VGltZSc6IDBcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgbWF4aW11bSBkZWxheSB0aW1lLiBUaGlzIGNhbm5vdCBiZSBjaGFuZ2VkLiBUaGUgdmFsdWUgaXMgcGFzc2VkIGludG8gdGhlIGNvbnN0cnVjdG9yLlxuXHRcdCAqIEBtZW1iZXJvZiBUb25lLkRlbGF5I1xuXHRcdCAqIEB0eXBlIHtUaW1lfVxuXHRcdCAqIEBuYW1lIG1heERlbGF5XG5cdFx0ICogQHJlYWRPbmx5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5EZWxheS5wcm90b3R5cGUsICdtYXhEZWxheScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21heERlbGF5O1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5EZWxheX0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuRGVsYXkucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9kZWxheU5vZGUuZGlzY29ubmVjdCgpO1xuXHQgICAgICAgIHRoaXMuX2RlbGF5Tm9kZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoJ2RlbGF5VGltZScpO1xuXHQgICAgICAgIHRoaXMuZGVsYXlUaW1lID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5EZWxheTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIENvbWIgZmlsdGVycyBhcmUgYmFzaWMgYnVpbGRpbmcgYmxvY2tzIGZvciBwaHlzaWNhbCBtb2RlbGluZy4gUmVhZCBtb3JlXG5cdFx0ICogICAgICAgICBhYm91dCBjb21iIGZpbHRlcnMgb24gW0NDUk1BJ3Mgd2Vic2l0ZV0oaHR0cHM6Ly9jY3JtYS5zdGFuZm9yZC5lZHUvfmpvcy9wYXNwL0ZlZWRiYWNrX0NvbWJfRmlsdGVycy5odG1sKS5cblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAcGFyYW0ge1RpbWV8T2JqZWN0fSBbZGVsYXlUaW1lXSBUaGUgZGVsYXkgdGltZSBvZiB0aGUgZmlsdGVyLlxuXHRcdCAqICBAcGFyYW0ge05vcm1hbFJhbmdlPX0gcmVzb25hbmNlIFRoZSBhbW91bnQgb2YgZmVlZGJhY2sgdGhlIGZpbHRlciBoYXMuXG5cdFx0ICovXG5cdCAgICBUb25lLkZlZWRiYWNrQ29tYkZpbHRlciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdkZWxheVRpbWUnLFxuXHQgICAgICAgICAgICAncmVzb25hbmNlJ1xuXHQgICAgICAgIF0sIFRvbmUuRmVlZGJhY2tDb21iRmlsdGVyKTtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBkZWxheSBub2RlXG5cdFx0XHQgKiAgQHR5cGUge0RlbGF5Tm9kZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZGVsYXkgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZS5EZWxheShvcHRpb25zLmRlbGF5VGltZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGFtb3VudCBvZiBkZWxheSBvZiB0aGUgY29tYiBmaWx0ZXIuXG5cdFx0XHQgKiAgQHR5cGUge1RpbWV9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZWxheVRpbWUgPSB0aGlzLl9kZWxheS5kZWxheVRpbWU7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGZlZWRiYWNrIG5vZGVcblx0XHRcdCAqICBAdHlwZSB7R2Fpbk5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ZlZWRiYWNrID0gbmV3IFRvbmUuR2FpbihvcHRpb25zLnJlc29uYW5jZSwgVG9uZS5UeXBlLk5vcm1hbFJhbmdlKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgYW1vdW50IG9mIGZlZWRiYWNrIG9mIHRoZSBkZWxheWVkIHNpZ25hbC5cblx0XHRcdCAqICBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5yZXNvbmFuY2UgPSB0aGlzLl9mZWVkYmFjay5nYWluO1xuXHQgICAgICAgIHRoaXMuX2RlbGF5LmNoYWluKHRoaXMuX2ZlZWRiYWNrLCB0aGlzLl9kZWxheSk7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoW1xuXHQgICAgICAgICAgICAncmVzb25hbmNlJyxcblx0ICAgICAgICAgICAgJ2RlbGF5VGltZSdcblx0ICAgICAgICBdKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkZlZWRiYWNrQ29tYkZpbHRlciwgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIHRoZSBkZWZhdWx0IHBhcmFtZXRlcnNcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuRmVlZGJhY2tDb21iRmlsdGVyLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdkZWxheVRpbWUnOiAwLjEsXG5cdCAgICAgICAgJ3Jlc29uYW5jZSc6IDAuNVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBjbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5GZWVkYmFja0NvbWJGaWx0ZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuRmVlZGJhY2tDb21iRmlsdGVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoW1xuXHQgICAgICAgICAgICAncmVzb25hbmNlJyxcblx0ICAgICAgICAgICAgJ2RlbGF5VGltZSdcblx0ICAgICAgICBdKTtcblx0ICAgICAgICB0aGlzLl9kZWxheS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fZGVsYXkgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZGVsYXlUaW1lID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9mZWVkYmFjay5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fZmVlZGJhY2sgPSBudWxsO1xuXHQgICAgICAgIHRoaXMucmVzb25hbmNlID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5GZWVkYmFja0NvbWJGaWx0ZXI7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIEdldCB0aGUgY3VycmVudCB3YXZlZm9ybSBkYXRhIG9mIHRoZSBjb25uZWN0ZWQgYXVkaW8gc291cmNlLlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBwYXJhbSB7TnVtYmVyPX0gc2l6ZSBUaGUgc2l6ZSBvZiB0aGUgRkZULiBWYWx1ZSBtdXN0IGJlIGEgcG93ZXIgb2Zcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgdHdvIGluIHRoZSByYW5nZSAzMiB0byAzMjc2OC5cblx0XHQgKi9cblx0ICAgIFRvbmUuRkZUID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFsnc2l6ZSddLCBUb25lLkZGVCk7XG5cdCAgICAgICAgb3B0aW9ucy50eXBlID0gVG9uZS5BbmFseXNlci5UeXBlLkZGVDtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhbmFseXNlciBub2RlLlxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQW5hbHlzZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9hbmFseXNlciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLkFuYWx5c2VyKG9wdGlvbnMpO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuRkZULCBUb25lLkF1ZGlvTm9kZSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGRlZmF1bHQgdmFsdWVzLlxuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqICBAY29uc3Rcblx0XHQgKi9cblx0ICAgIFRvbmUuRkZULmRlZmF1bHRzID0geyAnc2l6ZSc6IDEwMjQgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBHZXRzIHRoZSB3YXZlZm9ybSBvZiB0aGUgYXVkaW8gc291cmNlLiBSZXR1cm5zIHRoZSB3YXZlZm9ybSBkYXRhXG5cdFx0ICogIG9mIGxlbmd0aCBbc2l6ZV0oI3NpemUpIGFzIGEgRmxvYXQzMkFycmF5IHdpdGggdmFsdWVzIGJldHdlZW4gLTEgYW5kIDEuXG5cdFx0ICogIEByZXR1cm5zIHtUeXBlZEFycmF5fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5GRlQucHJvdG90eXBlLmdldFZhbHVlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlci5nZXRWYWx1ZSgpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgc2l6ZSBvZiBhbmFseXNpcy4gVGhpcyBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGluIHRoZSByYW5nZSAzMiB0byAzMjc2OC5cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuRkZUI1xuXHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqICBAbmFtZSBzaXplXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5GRlQucHJvdG90eXBlLCAnc2l6ZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2VyLnNpemU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChzaXplKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2FuYWx5c2VyLnNpemUgPSBzaXplO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5GRlR9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkZGVC5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX2FuYWx5c2VyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9hbmFseXNlciA9IG51bGw7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuRkZUO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgUmV0dXJuIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiBhbiBpbmNvbWluZyBzaWduYWwuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlNpZ25hbEJhc2V9XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHNpZ25hbCA9IG5ldyBUb25lLlNpZ25hbCgtMSk7XG5cdFx0ICogdmFyIGFicyA9IG5ldyBUb25lLkFicygpO1xuXHRcdCAqIHNpZ25hbC5jb25uZWN0KGFicyk7XG5cdFx0ICogLy90aGUgb3V0cHV0IG9mIGFicyBpcyAxLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5BYnMgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWxCYXNlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuTGVzc1RoYW59XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2FicyA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLldhdmVTaGFwZXIoZnVuY3Rpb24gKHZhbCkge1xuXHQgICAgICAgICAgICBpZiAoTWF0aC5hYnModmFsKSA8IDAuMDAxKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gMDtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLmFicyh2YWwpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSwgMTAyNCk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5BYnMsIFRvbmUuU2lnbmFsQmFzZSk7XG5cdCAgICAvKipcblx0XHQgKiAgZGlzcG9zZSBtZXRob2Rcblx0XHQgKiAgQHJldHVybnMge1RvbmUuQWJzfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkFicy5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9hYnMuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2FicyA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuQWJzO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIFRvbmUuRm9sbG93ZXIgaXMgYSAgY3J1ZGUgZW52ZWxvcGUgZm9sbG93ZXIgd2hpY2ggd2lsbCBmb2xsb3dcblx0XHQgKiAgICAgICAgICB0aGUgYW1wbGl0dWRlIG9mIGFuIGluY29taW5nIHNpZ25hbC5cblx0XHQgKiAgICAgICAgICBUYWtlIGNhcmUgd2l0aCBzbWFsbCAoPCAwLjAyKSBhdHRhY2sgb3IgZGVjYXkgdmFsdWVzXG5cdFx0ICogICAgICAgICAgYXMgZm9sbG93ZXIgaGFzIHNvbWUgcmlwcGxlIHdoaWNoIGlzIGV4YWdnZXJhdGVkXG5cdFx0ICogICAgICAgICAgYXQgdGhlc2UgdmFsdWVzLiBSZWFkIG1vcmUgYWJvdXQgZW52ZWxvcGUgZm9sbG93ZXJzIChhbHNvIGtub3duXG5cdFx0ICogICAgICAgICAgYXMgZW52ZWxvcGUgZGV0ZWN0b3JzKSBvbiBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FbnZlbG9wZV9kZXRlY3RvcikuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkF1ZGlvTm9kZX1cblx0XHQgKiAgQHBhcmFtIHtUaW1lfE9iamVjdH0gW2F0dGFja10gVGhlIHJhdGUgYXQgd2hpY2ggdGhlIGZvbGxvd2VyIHJpc2VzLlxuXHRcdCAqICBAcGFyYW0ge1RpbWU9fSByZWxlYXNlIFRoZSByYXRlIGF0IHdoaWNoIHRoZSBmb2xvd2VyIGZhbGxzLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBmb2xsb3dlciA9IG5ldyBUb25lLkZvbGxvd2VyKDAuMiwgMC40KTtcblx0XHQgKi9cblx0ICAgIFRvbmUuRm9sbG93ZXIgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAnYXR0YWNrJyxcblx0ICAgICAgICAgICAgJ3JlbGVhc2UnXG5cdCAgICAgICAgXSwgVG9uZS5Gb2xsb3dlcik7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLmNyZWF0ZUluc091dHMoMSwgMSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQWJzfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9hYnMgPSBuZXcgVG9uZS5BYnMoKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbG93cGFzcyBmaWx0ZXIgd2hpY2ggc21vb3RocyB0aGUgaW5wdXRcblx0XHRcdCAqICBAdHlwZSB7QmlxdWFkRmlsdGVyTm9kZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZmlsdGVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuXHQgICAgICAgIHRoaXMuX2ZpbHRlci50eXBlID0gJ2xvd3Bhc3MnO1xuXHQgICAgICAgIHRoaXMuX2ZpbHRlci5mcmVxdWVuY3kudmFsdWUgPSAwO1xuXHQgICAgICAgIHRoaXMuX2ZpbHRlci5RLnZhbHVlID0gLTEwMDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAdHlwZSB7V2F2ZVNoYXBlck5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ZyZXF1ZW5jeVZhbHVlcyA9IG5ldyBUb25lLldhdmVTaGFwZXIoKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5TdWJ0cmFjdH1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3ViID0gbmV3IFRvbmUuU3VidHJhY3QoKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5EZWxheX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZGVsYXkgPSBuZXcgVG9uZS5EZWxheSh0aGlzLmJsb2NrVGltZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhpcyBrZWVwcyBpdCBmYXIgZnJvbSAwLCBldmVuIGZvciB2ZXJ5IHNtYWxsIGRpZmZlcmVuY2VzXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuTXVsdGlwbHl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX211bHQgPSBuZXcgVG9uZS5NdWx0aXBseSgxMDAwMCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqICBAdHlwZSB7bnVtYmVyfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYXR0YWNrID0gb3B0aW9ucy5hdHRhY2s7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqICBAdHlwZSB7bnVtYmVyfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fcmVsZWFzZSA9IG9wdGlvbnMucmVsZWFzZTtcblx0ICAgICAgICAvL3RoZSBzbW9vdGhlZCBzaWduYWwgdG8gZ2V0IHRoZSB2YWx1ZXNcblx0ICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2FicywgdGhpcy5fZmlsdGVyLCB0aGlzLm91dHB1dCk7XG5cdCAgICAgICAgLy90aGUgZGlmZmVyZW5jZSBwYXRoXG5cdCAgICAgICAgdGhpcy5fYWJzLmNvbm5lY3QodGhpcy5fc3ViLCAwLCAxKTtcblx0ICAgICAgICB0aGlzLl9maWx0ZXIuY2hhaW4odGhpcy5fZGVsYXksIHRoaXMuX3N1Yik7XG5cdCAgICAgICAgLy90aHJlc2hvbGQgdGhlIGRpZmZlcmVuY2UgYW5kIHVzZSB0aGUgdGhyZXNoIHRvIHNldCB0aGUgZnJlcXVlbmN5XG5cdCAgICAgICAgdGhpcy5fc3ViLmNoYWluKHRoaXMuX211bHQsIHRoaXMuX2ZyZXF1ZW5jeVZhbHVlcywgdGhpcy5fZmlsdGVyLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgLy9zZXQgdGhlIGF0dGFjayBhbmQgcmVsZWFzZSB2YWx1ZXMgaW4gdGhlIHRhYmxlXG5cdCAgICAgICAgdGhpcy5fc2V0QXR0YWNrUmVsZWFzZSh0aGlzLl9hdHRhY2ssIHRoaXMuX3JlbGVhc2UpO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuRm9sbG93ZXIsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkZvbGxvd2VyLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdhdHRhY2snOiAwLjA1LFxuXHQgICAgICAgICdyZWxlYXNlJzogMC41XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIHNldHMgdGhlIGF0dGFjayBhbmQgcmVsZWFzZSB0aW1lcyBpbiB0aGUgd2F2ZSBzaGFwZXJcblx0XHQgKiAgQHBhcmFtICAge1RpbWV9IGF0dGFja1xuXHRcdCAqICBAcGFyYW0gICB7VGltZX0gcmVsZWFzZVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Gb2xsb3dlci5wcm90b3R5cGUuX3NldEF0dGFja1JlbGVhc2UgPSBmdW5jdGlvbiAoYXR0YWNrLCByZWxlYXNlKSB7XG5cdCAgICAgICAgdmFyIG1pblRpbWUgPSB0aGlzLmJsb2NrVGltZTtcblx0ICAgICAgICBhdHRhY2sgPSBUb25lLlRpbWUoYXR0YWNrKS50b0ZyZXF1ZW5jeSgpO1xuXHQgICAgICAgIHJlbGVhc2UgPSBUb25lLlRpbWUocmVsZWFzZSkudG9GcmVxdWVuY3koKTtcblx0ICAgICAgICBhdHRhY2sgPSBNYXRoLm1heChhdHRhY2ssIG1pblRpbWUpO1xuXHQgICAgICAgIHJlbGVhc2UgPSBNYXRoLm1heChyZWxlYXNlLCBtaW5UaW1lKTtcblx0ICAgICAgICB0aGlzLl9mcmVxdWVuY3lWYWx1ZXMuc2V0TWFwKGZ1bmN0aW9uICh2YWwpIHtcblx0ICAgICAgICAgICAgaWYgKHZhbCA8PSAwKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gYXR0YWNrO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHJlbGVhc2U7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgYXR0YWNrIHRpbWUuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuRm9sbG93ZXIjXG5cdFx0ICogQHR5cGUge1RpbWV9XG5cdFx0ICogQG5hbWUgYXR0YWNrXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5Gb2xsb3dlci5wcm90b3R5cGUsICdhdHRhY2snLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9hdHRhY2s7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChhdHRhY2spIHtcblx0ICAgICAgICAgICAgdGhpcy5fYXR0YWNrID0gYXR0YWNrO1xuXHQgICAgICAgICAgICB0aGlzLl9zZXRBdHRhY2tSZWxlYXNlKHRoaXMuX2F0dGFjaywgdGhpcy5fcmVsZWFzZSk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcmVsZWFzZSB0aW1lLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkZvbGxvd2VyI1xuXHRcdCAqIEB0eXBlIHtUaW1lfVxuXHRcdCAqIEBuYW1lIHJlbGVhc2Vcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkZvbGxvd2VyLnByb3RvdHlwZSwgJ3JlbGVhc2UnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZWxlYXNlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocmVsZWFzZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9yZWxlYXNlID0gcmVsZWFzZTtcblx0ICAgICAgICAgICAgdGhpcy5fc2V0QXR0YWNrUmVsZWFzZSh0aGlzLl9hdHRhY2ssIHRoaXMuX3JlbGVhc2UpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIEJvcnJvd3MgdGhlIGNvbm5lY3QgbWV0aG9kIGZyb20gU2lnbmFsIHNvIHRoYXQgdGhlIG91dHB1dCBjYW4gYmUgdXNlZFxuXHRcdCAqICBhcyBhIFRvbmUuU2lnbmFsIGNvbnRyb2wgc2lnbmFsLlxuXHRcdCAqICBAZnVuY3Rpb25cblx0XHQgKi9cblx0ICAgIFRvbmUuRm9sbG93ZXIucHJvdG90eXBlLmNvbm5lY3QgPSBUb25lLlNpZ25hbEJhc2UucHJvdG90eXBlLmNvbm5lY3Q7XG5cdCAgICAvKipcblx0XHQgKiAgZGlzcG9zZVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5Gb2xsb3dlcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Gb2xsb3dlci5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX2ZpbHRlci5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgdGhpcy5fZmlsdGVyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9mcmVxdWVuY3lWYWx1ZXMuZGlzY29ubmVjdCgpO1xuXHQgICAgICAgIHRoaXMuX2ZyZXF1ZW5jeVZhbHVlcyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fZGVsYXkuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2RlbGF5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9zdWIuZGlzY29ubmVjdCgpO1xuXHQgICAgICAgIHRoaXMuX3N1YiA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fYWJzLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9hYnMgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX211bHQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX211bHQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2N1cnZlID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5Gb2xsb3dlcjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuU2NhbGVkRW52ZWxvcCBpcyBhbiBlbnZlbG9wZSB3aGljaCBjYW4gYmUgc2NhbGVkXG5cdFx0ICogICAgICAgICB0byBhbnkgcmFuZ2UuIEl0J3MgdXNlZnVsIGZvciBhcHBseWluZyBhbiBlbnZlbG9wZVxuXHRcdCAqICAgICAgICAgdG8gYSBmcmVxdWVuY3kgb3IgYW55IG90aGVyIG5vbi1Ob3JtYWxSYW5nZSBzaWduYWxcblx0XHQgKiAgICAgICAgIHBhcmFtZXRlci5cblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5FbnZlbG9wZX1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBwYXJhbSB7VGltZXxPYmplY3R9IFthdHRhY2tdXHR0aGUgYXR0YWNrIHRpbWUgaW4gc2Vjb25kc1xuXHRcdCAqICBAcGFyYW0ge1RpbWV9IFtkZWNheV1cdHRoZSBkZWNheSB0aW1lIGluIHNlY29uZHNcblx0XHQgKiAgQHBhcmFtIHtudW1iZXJ9IFtzdXN0YWluXSBcdGEgcGVyY2VudGFnZSAoMC0xKSBvZiB0aGUgZnVsbCBhbXBsaXR1ZGVcblx0XHQgKiAgQHBhcmFtIHtUaW1lfSBbcmVsZWFzZV1cdHRoZSByZWxlYXNlIHRpbWUgaW4gc2Vjb25kc1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqICB2YXIgc2NhbGVkRW52ID0gbmV3IFRvbmUuU2NhbGVkRW52ZWxvcGUoe1xuXHRcdCAqICBcdFwiYXR0YWNrXCIgOiAwLjIsXG5cdFx0ICogIFx0XCJtaW5cIiA6IDIwMCxcblx0XHQgKiAgXHRcIm1heFwiIDogMjAwMFxuXHRcdCAqICB9KTtcblx0XHQgKiAgc2NhbGVkRW52LmNvbm5lY3Qob3NjaWxsYXRvci5mcmVxdWVuY3kpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5TY2FsZWRFbnZlbG9wZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAvL2dldCBhbGwgb2YgdGhlIGRlZmF1bHRzXG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAnYXR0YWNrJyxcblx0ICAgICAgICAgICAgJ2RlY2F5Jyxcblx0ICAgICAgICAgICAgJ3N1c3RhaW4nLFxuXHQgICAgICAgICAgICAncmVsZWFzZSdcblx0ICAgICAgICBdLCBUb25lLkVudmVsb3BlKTtcblx0ICAgICAgICBUb25lLkVudmVsb3BlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdEFyZyhvcHRpb25zLCBUb25lLlNjYWxlZEVudmVsb3BlLmRlZmF1bHRzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBzY2FsZSB0aGUgaW5jb21pbmcgc2lnbmFsIGJ5IGFuIGV4cG9uZW50XG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuUG93fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9leHAgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLlBvdyhvcHRpb25zLmV4cG9uZW50KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBzY2FsZSB0aGUgc2lnbmFsIHRvIHRoZSBkZXNpcmVkIHJhbmdlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuTXVsdGlwbHl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3NjYWxlID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZS5TY2FsZShvcHRpb25zLm1pbiwgb3B0aW9ucy5tYXgpO1xuXHQgICAgICAgIHRoaXMuX3NpZy5jaGFpbih0aGlzLl9leHAsIHRoaXMuX3NjYWxlKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlNjYWxlZEVudmVsb3BlLCBUb25lLkVudmVsb3BlKTtcblx0ICAgIC8qKlxuXHRcdCAqICB0aGUgZGVmYXVsdCBwYXJhbWV0ZXJzXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKi9cblx0ICAgIFRvbmUuU2NhbGVkRW52ZWxvcGUuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ21pbic6IDAsXG5cdCAgICAgICAgJ21heCc6IDEsXG5cdCAgICAgICAgJ2V4cG9uZW50JzogMVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBlbnZlbG9wZSdzIG1pbiBvdXRwdXQgdmFsdWUuIFRoaXMgaXMgdGhlIHZhbHVlIHdoaWNoIGl0XG5cdFx0ICogc3RhcnRzIGF0LlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlNjYWxlZEVudmVsb3BlI1xuXHRcdCAqIEB0eXBlIHtudW1iZXJ9XG5cdFx0ICogQG5hbWUgbWluXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5TY2FsZWRFbnZlbG9wZS5wcm90b3R5cGUsICdtaW4nLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9zY2FsZS5taW47XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChtaW4pIHtcblx0ICAgICAgICAgICAgdGhpcy5fc2NhbGUubWluID0gbWluO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIGVudmVsb3BlJ3MgbWF4IG91dHB1dCB2YWx1ZS4gSW4gb3RoZXIgd29yZHMsIHRoZSB2YWx1ZVxuXHRcdCAqIGF0IHRoZSBwZWFrIG9mIHRoZSBhdHRhY2sgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGUuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuU2NhbGVkRW52ZWxvcGUjXG5cdFx0ICogQHR5cGUge251bWJlcn1cblx0XHQgKiBAbmFtZSBtYXhcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlNjYWxlZEVudmVsb3BlLnByb3RvdHlwZSwgJ21heCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NjYWxlLm1heDtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKG1heCkge1xuXHQgICAgICAgICAgICB0aGlzLl9zY2FsZS5tYXggPSBtYXg7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgZW52ZWxvcGUncyBleHBvbmVudCB2YWx1ZS5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5TY2FsZWRFbnZlbG9wZSNcblx0XHQgKiBAdHlwZSB7bnVtYmVyfVxuXHRcdCAqIEBuYW1lIGV4cG9uZW50XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5TY2FsZWRFbnZlbG9wZS5wcm90b3R5cGUsICdleHBvbmVudCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V4cC52YWx1ZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGV4cCkge1xuXHQgICAgICAgICAgICB0aGlzLl9leHAudmFsdWUgPSBleHA7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgY2xlYW4gdXBcblx0XHQgKiAgQHJldHVybnMge1RvbmUuU2NhbGVkRW52ZWxvcGV9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuU2NhbGVkRW52ZWxvcGUucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5FbnZlbG9wZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3NjYWxlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9zY2FsZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fZXhwLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9leHAgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlNjYWxlZEVudmVsb3BlO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5GcmVxdWVuY3lFbnZlbG9wZSBpcyBhIFRvbmUuU2NhbGVkRW52ZWxvcGUsIGJ1dCBpbnN0ZWFkIG9mIGBtaW5gIGFuZCBgbWF4YFxuXHRcdCAqICAgICAgICAgaXQncyBnb3QgYSBgYmFzZUZyZXF1ZW5jeWAgYW5kIGBvY3RhdmVzYCBwYXJhbWV0ZXIuXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuRW52ZWxvcGV9XG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAcGFyYW0ge1RpbWV8T2JqZWN0fSBbYXR0YWNrXVx0dGhlIGF0dGFjayB0aW1lIGluIHNlY29uZHNcblx0XHQgKiAgQHBhcmFtIHtUaW1lfSBbZGVjYXldXHR0aGUgZGVjYXkgdGltZSBpbiBzZWNvbmRzXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSBbc3VzdGFpbl0gXHRhIHBlcmNlbnRhZ2UgKDAtMSkgb2YgdGhlIGZ1bGwgYW1wbGl0dWRlXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW3JlbGVhc2VdXHR0aGUgcmVsZWFzZSB0aW1lIGluIHNlY29uZHNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAgdmFyIGZyZXFFbnYgPSBuZXcgVG9uZS5GcmVxdWVuY3lFbnZlbG9wZSh7XG5cdFx0ICogIFx0XCJhdHRhY2tcIiA6IDAuMixcblx0XHQgKiAgXHRcImJhc2VGcmVxdWVuY3lcIiA6IFwiQzJcIixcblx0XHQgKiAgXHRcIm9jdGF2ZXNcIiA6IDRcblx0XHQgKiAgfSk7XG5cdFx0ICogIGZyZXFFbnYuY29ubmVjdChvc2NpbGxhdG9yLmZyZXF1ZW5jeSk7XG5cdFx0ICovXG5cdCAgICBUb25lLkZyZXF1ZW5jeUVudmVsb3BlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ2F0dGFjaycsXG5cdCAgICAgICAgICAgICdkZWNheScsXG5cdCAgICAgICAgICAgICdzdXN0YWluJyxcblx0ICAgICAgICAgICAgJ3JlbGVhc2UnXG5cdCAgICAgICAgXSwgVG9uZS5FbnZlbG9wZSk7XG5cdCAgICAgICAgVG9uZS5TY2FsZWRFbnZlbG9wZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8vbWVyZ2UgaXQgd2l0aCB0aGUgZnJlcXVlbmN5IGVudmVsb3BlIGRlZmF1bHRzXG5cdCAgICAgICAgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdEFyZyhvcHRpb25zLCBUb25lLkZyZXF1ZW5jeUVudmVsb3BlLmRlZmF1bHRzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBTdG9yZXMgdGhlIG9jdGF2ZSB2YWx1ZVxuXHRcdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcblx0ICAgICAgICAvL3NldHVwXG5cdCAgICAgICAgdGhpcy5iYXNlRnJlcXVlbmN5ID0gb3B0aW9ucy5iYXNlRnJlcXVlbmN5O1xuXHQgICAgICAgIHRoaXMub2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkZyZXF1ZW5jeUVudmVsb3BlLCBUb25lLkVudmVsb3BlKTtcblx0ICAgIC8qKlxuXHRcdCAqICB0aGUgZGVmYXVsdCBwYXJhbWV0ZXJzXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKi9cblx0ICAgIFRvbmUuRnJlcXVlbmN5RW52ZWxvcGUuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2Jhc2VGcmVxdWVuY3knOiAyMDAsXG5cdCAgICAgICAgJ29jdGF2ZXMnOiA0LFxuXHQgICAgICAgICdleHBvbmVudCc6IDJcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgZW52ZWxvcGUncyBtaW5pbnVtIG91dHB1dCB2YWx1ZS4gVGhpcyBpcyB0aGUgdmFsdWUgd2hpY2ggaXRcblx0XHQgKiBzdGFydHMgYXQuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuRnJlcXVlbmN5RW52ZWxvcGUjXG5cdFx0ICogQHR5cGUge0ZyZXF1ZW5jeX1cblx0XHQgKiBAbmFtZSBiYXNlRnJlcXVlbmN5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5GcmVxdWVuY3lFbnZlbG9wZS5wcm90b3R5cGUsICdiYXNlRnJlcXVlbmN5Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fc2NhbGUubWluO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobWluKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3NjYWxlLm1pbiA9IHRoaXMudG9GcmVxdWVuY3kobWluKTtcblx0ICAgICAgICAgICAgLy9hbHNvIHVwZGF0ZSB0aGUgb2N0YXZlc1xuXHQgICAgICAgICAgICB0aGlzLm9jdGF2ZXMgPSB0aGlzLl9vY3RhdmVzO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIG51bWJlciBvZiBvY3RhdmVzIGFib3ZlIHRoZSBiYXNlRnJlcXVlbmN5IHRoYXQgdGhlXG5cdFx0ICogZW52ZWxvcGUgd2lsbCBzY2FsZSB0by5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5GcmVxdWVuY3lFbnZlbG9wZSNcblx0XHQgKiBAdHlwZSB7UG9zaXRpdmV9XG5cdFx0ICogQG5hbWUgb2N0YXZlc1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuRnJlcXVlbmN5RW52ZWxvcGUucHJvdG90eXBlLCAnb2N0YXZlcycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChvY3RhdmVzKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvY3RhdmVzO1xuXHQgICAgICAgICAgICB0aGlzLl9zY2FsZS5tYXggPSB0aGlzLmJhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCBvY3RhdmVzKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBlbnZlbG9wZSdzIGV4cG9uZW50IHZhbHVlLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkZyZXF1ZW5jeUVudmVsb3BlI1xuXHRcdCAqIEB0eXBlIHtudW1iZXJ9XG5cdFx0ICogQG5hbWUgZXhwb25lbnRcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkZyZXF1ZW5jeUVudmVsb3BlLnByb3RvdHlwZSwgJ2V4cG9uZW50Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXhwLnZhbHVlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoZXhwKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2V4cC52YWx1ZSA9IGV4cDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBjbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5GcmVxdWVuY3lFbnZlbG9wZX0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5GcmVxdWVuY3lFbnZlbG9wZS5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNjYWxlZEVudmVsb3BlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuRnJlcXVlbmN5RW52ZWxvcGU7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgR3JlYXRlclRoYW5aZXJvIG91dHB1dHMgMSB3aGVuIHRoZSBpbnB1dCBpcyBzdHJpY3RseSBncmVhdGVyIHRoYW4gemVyb1xuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5TaWduYWxCYXNlfVxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBndDAgPSBuZXcgVG9uZS5HcmVhdGVyVGhhblplcm8oKTtcblx0XHQgKiB2YXIgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDAuMDEpLmNvbm5lY3QoZ3QwKTtcblx0XHQgKiAvL3RoZSBvdXRwdXQgb2YgZ3QwIGlzIDEuXG5cdFx0ICogc2lnLnZhbHVlID0gMDtcblx0XHQgKiAvL3RoZSBvdXRwdXQgb2YgZ3QwIGlzIDAuXG5cdFx0ICovXG5cdCAgICBUb25lLkdyZWF0ZXJUaGFuWmVybyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5XYXZlU2hhcGVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl90aHJlc2ggPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLldhdmVTaGFwZXIoZnVuY3Rpb24gKHZhbCkge1xuXHQgICAgICAgICAgICBpZiAodmFsIDw9IDApIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiAwO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIDE7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LCAxMjcpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHNjYWxlIHRoZSBmaXJzdCB0aHJlc2hvbGRlZCBzaWduYWwgYnkgYSBsYXJnZSB2YWx1ZS5cblx0XHRcdCAqICB0aGlzIHdpbGwgaGVscCB3aXRoIHZhbHVlcyB3aGljaCBhcmUgdmVyeSBjbG9zZSB0byAwXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuTXVsdGlwbHl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3NjYWxlID0gdGhpcy5pbnB1dCA9IG5ldyBUb25lLk11bHRpcGx5KDEwMDAwKTtcblx0ICAgICAgICAvL2Nvbm5lY3Rpb25zXG5cdCAgICAgICAgdGhpcy5fc2NhbGUuY29ubmVjdCh0aGlzLl90aHJlc2gpO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuR3JlYXRlclRoYW5aZXJvLCBUb25lLlNpZ25hbEJhc2UpO1xuXHQgICAgLyoqXG5cdFx0ICogIGRpc3Bvc2UgbWV0aG9kXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkdyZWF0ZXJUaGFuWmVyb30gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5HcmVhdGVyVGhhblplcm8ucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWxCYXNlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fc2NhbGUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3NjYWxlID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl90aHJlc2guZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3RocmVzaCA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuR3JlYXRlclRoYW5aZXJvO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIE91dHB1dCAxIGlmIHRoZSBzaWduYWwgaXMgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSwgb3RoZXJ3aXNlIG91dHB1dHMgMC5cblx0XHQgKiAgICAgICAgICBjYW4gY29tcGFyZSB0d28gc2lnbmFscyBvciBhIHNpZ25hbCBhbmQgYSBudW1iZXIuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlNpZ25hbH1cblx0XHQgKiAgQHBhcmFtIHtudW1iZXJ9IFt2YWx1ZT0wXSB0aGUgdmFsdWUgdG8gY29tcGFyZSB0byB0aGUgaW5jb21pbmcgc2lnbmFsXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIGd0ID0gbmV3IFRvbmUuR3JlYXRlclRoYW4oMik7XG5cdFx0ICogdmFyIHNpZyA9IG5ldyBUb25lLlNpZ25hbCg0KS5jb25uZWN0KGd0KTtcblx0XHQgKiAvL291dHB1dCBvZiBndCBpcyBlcXVhbCAxLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5HcmVhdGVyVGhhbiA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHQgICAgICAgIFRvbmUuU2lnbmFsLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5jcmVhdGVJbnNPdXRzKDIsIDApO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHN1YnRyYWN0IHRoZSBhbW91bnQgZnJvbSB0aGUgaW5jb21pbmcgc2lnbmFsXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuU3VidHJhY3R9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3BhcmFtID0gdGhpcy5pbnB1dFswXSA9IG5ldyBUb25lLlN1YnRyYWN0KHZhbHVlKTtcblx0ICAgICAgICB0aGlzLmlucHV0WzFdID0gdGhpcy5fcGFyYW0uaW5wdXRbMV07XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgY29tcGFyZSB0aGF0IGFtb3VudCB0byB6ZXJvXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuR3JlYXRlclRoYW5aZXJvfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9ndHogPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLkdyZWF0ZXJUaGFuWmVybygpO1xuXHQgICAgICAgIC8vY29ubmVjdFxuXHQgICAgICAgIHRoaXMuX3BhcmFtLmNvbm5lY3QodGhpcy5fZ3R6KTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkdyZWF0ZXJUaGFuLCBUb25lLlNpZ25hbCk7XG5cdCAgICAvKipcblx0XHQgKiAgZGlzcG9zZSBtZXRob2Rcblx0XHQgKiAgQHJldHVybnMge1RvbmUuR3JlYXRlclRoYW59IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuR3JlYXRlclRoYW4ucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWwucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9ndHouZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2d0eiA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuR3JlYXRlclRoYW47XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgVG9uZS5HYXRlIG9ubHkgcGFzc2VzIGEgc2lnbmFsIHRocm91Z2ggd2hlbiB0aGUgaW5jb21pbmdcblx0XHQgKiAgICAgICAgICBzaWduYWwgZXhjZWVkcyBhIHNwZWNpZmllZCB0aHJlc2hvbGQuIFRvIGRvIHRoaXMsIEdhdGUgdXNlc1xuXHRcdCAqICAgICAgICAgIGEgVG9uZS5Gb2xsb3dlciB0byBmb2xsb3cgdGhlIGFtcGxpdHVkZSBvZiB0aGUgaW5jb21pbmcgc2lnbmFsLlxuXHRcdCAqICAgICAgICAgIEEgY29tbW9uIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgY2xhc3MgaXMgYSBbTm9pc2UgR2F0ZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTm9pc2VfZ2F0ZSkuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkF1ZGlvTm9kZX1cblx0XHQgKiAgQHBhcmFtIHtEZWNpYmVsc3xPYmplY3R9IFt0aHJlc2hvbGRdIFRoZSB0aHJlc2hvbGQgYWJvdmUgd2hpY2ggdGhlIGdhdGUgd2lsbCBvcGVuLlxuXHRcdCAqICBAcGFyYW0ge1RpbWU9fSBhdHRhY2sgVGhlIGZvbGxvd2VyJ3MgYXR0YWNrIHRpbWVcblx0XHQgKiAgQHBhcmFtIHtUaW1lPX0gcmVsZWFzZSBUaGUgZm9sbG93ZXIncyByZWxlYXNlIHRpbWVcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgZ2F0ZSA9IG5ldyBUb25lLkdhdGUoLTMwLCAwLjIsIDAuMykudG9NYXN0ZXIoKTtcblx0XHQgKiB2YXIgbWljID0gbmV3IFRvbmUuVXNlck1lZGlhKCkuY29ubmVjdChnYXRlKTtcblx0XHQgKiAvL3RoZSBnYXRlIHdpbGwgb25seSBwYXNzIHRocm91Z2ggdGhlIGluY29taW5nXG5cdFx0ICogLy9zaWduYWwgd2hlbiBpdCdzIGxvdWRlciB0aGFuIC0zMGRiXG5cdFx0ICovXG5cdCAgICBUb25lLkdhdGUgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAndGhyZXNob2xkJyxcblx0ICAgICAgICAgICAgJ2F0dGFjaycsXG5cdCAgICAgICAgICAgICdyZWxlYXNlJ1xuXHQgICAgICAgIF0sIFRvbmUuR2F0ZSk7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLmNyZWF0ZUluc091dHMoMSwgMSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuRm9sbG93ZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ZvbGxvd2VyID0gbmV3IFRvbmUuRm9sbG93ZXIob3B0aW9ucy5hdHRhY2ssIG9wdGlvbnMucmVsZWFzZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuR3JlYXRlclRoYW59XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2d0ID0gbmV3IFRvbmUuR3JlYXRlclRoYW4oVG9uZS5kYlRvR2FpbihvcHRpb25zLnRocmVzaG9sZCkpO1xuXHQgICAgICAgIC8vdGhlIGNvbm5lY3Rpb25zXG5cdCAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMub3V0cHV0KTtcblx0ICAgICAgICAvL3RoZSBjb250cm9sIHNpZ25hbFxuXHQgICAgICAgIHRoaXMuaW5wdXQuY2hhaW4odGhpcy5fZ3QsIHRoaXMuX2ZvbGxvd2VyLCB0aGlzLm91dHB1dC5nYWluKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkdhdGUsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5HYXRlLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdhdHRhY2snOiAwLjEsXG5cdCAgICAgICAgJ3JlbGVhc2UnOiAwLjEsXG5cdCAgICAgICAgJ3RocmVzaG9sZCc6IC00MFxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSB0aHJlc2hvbGQgb2YgdGhlIGdhdGUgaW4gZGVjaWJlbHNcblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5HYXRlI1xuXHRcdCAqIEB0eXBlIHtEZWNpYmVsc31cblx0XHQgKiBAbmFtZSB0aHJlc2hvbGRcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkdhdGUucHJvdG90eXBlLCAndGhyZXNob2xkJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5nYWluVG9EYih0aGlzLl9ndC52YWx1ZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh0aHJlc2gpIHtcblx0ICAgICAgICAgICAgdGhpcy5fZ3QudmFsdWUgPSBUb25lLmRiVG9HYWluKHRocmVzaCk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgYXR0YWNrIHNwZWVkIG9mIHRoZSBnYXRlXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuR2F0ZSNcblx0XHQgKiBAdHlwZSB7VGltZX1cblx0XHQgKiBAbmFtZSBhdHRhY2tcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkdhdGUucHJvdG90eXBlLCAnYXR0YWNrJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fZm9sbG93ZXIuYXR0YWNrO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoYXR0YWNrVGltZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9mb2xsb3dlci5hdHRhY2sgPSBhdHRhY2tUaW1lO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHJlbGVhc2Ugc3BlZWQgb2YgdGhlIGdhdGVcblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5HYXRlI1xuXHRcdCAqIEB0eXBlIHtUaW1lfVxuXHRcdCAqIEBuYW1lIHJlbGVhc2Vcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkdhdGUucHJvdG90eXBlLCAncmVsZWFzZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZvbGxvd2VyLnJlbGVhc2U7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChyZWxlYXNlVGltZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9mb2xsb3dlci5yZWxlYXNlID0gcmVsZWFzZVRpbWU7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkdhdGV9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuR2F0ZS5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX2ZvbGxvd2VyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9ndC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fZm9sbG93ZXIgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2d0ID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5HYXRlO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICAvKipcblx0XHQgKiBAY2xhc3MgVG9uZS5UaWNrU2lnbmFsIGV4dGVuZHMgVG9uZS5TaWduYWwsIGJ1dCBhZGRzIHRoZSBjYXBhYmlsaXR5XG5cdFx0ICogICAgICAgIHRvIGNhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIGVsYXBzZWQgdGlja3MuIGV4cG9uZW50aWFsIGFuZCB0YXJnZXQgY3VydmVzXG5cdFx0ICogICAgICAgIGFyZSBhcHByb3hpbWF0ZWQgd2l0aCBtdWx0aXBsZSBsaW5lYXIgcmFtcHMuXG5cdFx0ICpcblx0XHQgKiAgICAgICAgVGhhbmsgeW91IEJydW5vIERpYXMsIEguIFNvZmlhIFBpbnRvLCBhbmQgRGF2aWQgTS4gTWF0b3MsIGZvciB5b3VyIFtXQUMgcGFwZXJdKGh0dHBzOi8vc21hcnRlY2guZ2F0ZWNoLmVkdS9iaXRzdHJlYW0vaGFuZGxlLzE4NTMvNTQ1ODgvV0FDMjAxNi00OS5wZGYpXG5cdFx0ICogICAgICAgIGRlc2NyaWJpbmcgaW50ZWdyYXRpbmcgdGltaW5nIGZ1bmN0aW9ucyBmb3IgdGVtcG8gY2FsY3VsYXRpb25zLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtOdW1iZXJ9IHZhbHVlIFRoZSBpbml0aWFsIHZhbHVlIG9mIHRoZSBzaWduYWxcblx0XHQgKiBAZXh0ZW5kcyB7VG9uZS5TaWduYWx9XG5cdFx0ICovXG5cdCAgICBUb25lLlRpY2tTaWduYWwgPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0ICAgICAgICB2YWx1ZSA9IFRvbmUuZGVmYXVsdEFyZyh2YWx1ZSwgMSk7XG5cdCAgICAgICAgVG9uZS5TaWduYWwuY2FsbCh0aGlzLCB7XG5cdCAgICAgICAgICAgICd1bml0cyc6IFRvbmUuVHlwZS5UaWNrcyxcblx0ICAgICAgICAgICAgJ3ZhbHVlJzogdmFsdWVcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvL2V4dGVuZCB0aGUgbWVtb3J5XG5cdCAgICAgICAgdGhpcy5fZXZlbnRzLm1lbW9yeSA9IEluZmluaXR5O1xuXHQgICAgICAgIC8vY2xlYXIgdGhlIGNsb2NrIGZyb20gdGhlIGJlZ2lubmluZ1xuXHQgICAgICAgIHRoaXMuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKDApO1xuXHQgICAgICAgIC8vc2V0IGFuIGluaXRpYWwgZXZlbnRcblx0ICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcblx0ICAgICAgICAgICAgJ3R5cGUnOiBUb25lLlBhcmFtLkF1dG9tYXRpb25UeXBlLlNldFZhbHVlLFxuXHQgICAgICAgICAgICAndGltZSc6IDAsXG5cdCAgICAgICAgICAgICd2YWx1ZSc6IHZhbHVlXG5cdCAgICAgICAgfSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5UaWNrU2lnbmFsLCBUb25lLlNpZ25hbCk7XG5cdCAgICAvKipcblx0XHQgKiBXcmFwcyBUb25lLlNpZ25hbCBtZXRob2RzIHNvIHRoYXQgdGhleSBhbHNvXG5cdFx0ICogcmVjb3JkIHRoZSB0aWNrcy5cblx0XHQgKiBAcGFyYW0gIHtGdW5jdGlvbn0gbWV0aG9kXG5cdFx0ICogQHJldHVybiB7RnVuY3Rpb259XG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIGZ1bmN0aW9uIF93cmFwU2NoZWR1bGVNZXRob2RzKG1ldGhvZCkge1xuXHQgICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIHRpbWUpIHtcblx0ICAgICAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgICAgICBtZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0ICAgICAgICAgICAgdmFyIGV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldCh0aW1lKTtcblx0ICAgICAgICAgICAgdmFyIHByZXZpb3VzRXZlbnQgPSB0aGlzLl9ldmVudHMucHJldmlvdXNFdmVudChldmVudCk7XG5cdCAgICAgICAgICAgIHZhciB0aWNrc1VudGlsVGltZSA9IHRoaXMuX2dldFRpY2tzVW50aWxFdmVudChwcmV2aW91c0V2ZW50LCB0aW1lKTtcblx0ICAgICAgICAgICAgZXZlbnQudGlja3MgPSBNYXRoLm1heCh0aWNrc1VudGlsVGltZSwgMCk7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH07XG5cdCAgICB9XG5cdCAgICBUb25lLlRpY2tTaWduYWwucHJvdG90eXBlLnNldFZhbHVlQXRUaW1lID0gX3dyYXBTY2hlZHVsZU1ldGhvZHMoVG9uZS5TaWduYWwucHJvdG90eXBlLnNldFZhbHVlQXRUaW1lKTtcblx0ICAgIFRvbmUuVGlja1NpZ25hbC5wcm90b3R5cGUubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUgPSBfd3JhcFNjaGVkdWxlTWV0aG9kcyhUb25lLlNpZ25hbC5wcm90b3R5cGUubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUpO1xuXHQgICAgLyoqXG5cdFx0ICogIFN0YXJ0IGV4cG9uZW50aWFsbHkgYXBwcm9hY2hpbmcgdGhlIHRhcmdldCB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZSB3aXRoXG5cdFx0ICogIGEgcmF0ZSBoYXZpbmcgdGhlIGdpdmVuIHRpbWUgY29uc3RhbnQuXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IHN0YXJ0VGltZVxuXHRcdCAqICBAcGFyYW0ge251bWJlcn0gdGltZUNvbnN0YW50XG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRpY2tTaWduYWx9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVGlja1NpZ25hbC5wcm90b3R5cGUuc2V0VGFyZ2V0QXRUaW1lID0gZnVuY3Rpb24gKHZhbHVlLCB0aW1lLCBjb25zdGFudCkge1xuXHQgICAgICAgIC8vYXByb3hpbWF0ZSBpdCB3aXRoIG11bHRpcGxlIGxpbmVhciByYW1wc1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLnNldFJhbXBQb2ludCh0aW1lKTtcblx0ICAgICAgICB2YWx1ZSA9IHRoaXMuX2Zyb21Vbml0cyh2YWx1ZSk7XG5cdCAgICAgICAgLy9zdGFydCBmcm9tIHByZXZpb3VzbHkgc2NoZWR1bGVkIHZhbHVlXG5cdCAgICAgICAgdmFyIHByZXZFdmVudCA9IHRoaXMuX2V2ZW50cy5nZXQodGltZSk7XG5cdCAgICAgICAgdmFyIHNlZ21lbnRzID0gTWF0aC5yb3VuZChNYXRoLm1heCgxIC8gY29uc3RhbnQsIDEpKTtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8PSBzZWdtZW50czsgaSsrKSB7XG5cdCAgICAgICAgICAgIHZhciBzZWdUaW1lID0gY29uc3RhbnQgKiBpICsgdGltZTtcblx0ICAgICAgICAgICAgdmFyIHJhbXBWYWwgPSB0aGlzLl9leHBvbmVudGlhbEFwcHJvYWNoKHByZXZFdmVudC50aW1lLCBwcmV2RXZlbnQudmFsdWUsIHZhbHVlLCBjb25zdGFudCwgc2VnVGltZSk7XG5cdCAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5fdG9Vbml0cyhyYW1wVmFsKSwgc2VnVGltZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTY2hlZHVsZXMgYW4gZXhwb25lbnRpYWwgY29udGludW91cyBjaGFuZ2UgaW4gcGFyYW1ldGVyIHZhbHVlIGZyb21cblx0XHQgKiAgdGhlIHByZXZpb3VzIHNjaGVkdWxlZCBwYXJhbWV0ZXIgdmFsdWUgdG8gdGhlIGdpdmVuIHZhbHVlLlxuXHRcdCAqICBAcGFyYW0gIHtudW1iZXJ9IHZhbHVlXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IGVuZFRpbWVcblx0XHQgKiAgQHJldHVybnMge1RvbmUuVGlja1NpZ25hbH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UaWNrU2lnbmFsLnByb3RvdHlwZS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lID0gZnVuY3Rpb24gKHZhbHVlLCB0aW1lKSB7XG5cdCAgICAgICAgLy9hcHJveGltYXRlIGl0IHdpdGggbXVsdGlwbGUgbGluZWFyIHJhbXBzXG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHZhbHVlID0gdGhpcy5fZnJvbVVuaXRzKHZhbHVlKTtcblx0ICAgICAgICAvL3N0YXJ0IGZyb20gcHJldmlvdXNseSBzY2hlZHVsZWQgdmFsdWVcblx0ICAgICAgICB2YXIgcHJldkV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldCh0aW1lKTtcblx0ICAgICAgICBpZiAocHJldkV2ZW50ID09PSBudWxsKSB7XG5cdCAgICAgICAgICAgIHByZXZFdmVudCA9IHtcblx0ICAgICAgICAgICAgICAgICd2YWx1ZSc6IHRoaXMuX2luaXRpYWxWYWx1ZSxcblx0ICAgICAgICAgICAgICAgICd0aW1lJzogMFxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL2FwcHJveCAxMCBzZWdtZW50cyBwZXIgc2Vjb25kXG5cdCAgICAgICAgdmFyIHNlZ21lbnRzID0gTWF0aC5yb3VuZChNYXRoLm1heCgodGltZSAtIHByZXZFdmVudC50aW1lKSAqIDEwLCAxKSk7XG5cdCAgICAgICAgdmFyIHNlZ21lbnREdXIgPSAodGltZSAtIHByZXZFdmVudC50aW1lKSAvIHNlZ21lbnRzO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDw9IHNlZ21lbnRzOyBpKyspIHtcblx0ICAgICAgICAgICAgdmFyIHNlZ1RpbWUgPSBzZWdtZW50RHVyICogaSArIHByZXZFdmVudC50aW1lO1xuXHQgICAgICAgICAgICB2YXIgcmFtcFZhbCA9IHRoaXMuX2V4cG9uZW50aWFsSW50ZXJwb2xhdGUocHJldkV2ZW50LnRpbWUsIHByZXZFdmVudC52YWx1ZSwgdGltZSwgdmFsdWUsIHNlZ1RpbWUpO1xuXHQgICAgICAgICAgICB0aGlzLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHRoaXMuX3RvVW5pdHMocmFtcFZhbCksIHNlZ1RpbWUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBSZXR1cm5zIHRoZSB0aWNrIHZhbHVlIGF0IHRoZSB0aW1lLiBUYWtlcyBpbnRvIGFjY291bnRcblx0XHQgKiBhbnkgYXV0b21hdGlvbiBjdXJ2ZXMgc2NoZWR1bGVkIG9uIHRoZSBzaWduYWwuXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKiBAcGFyYW0gIHtUaW1lfSB0aW1lIFRoZSB0aW1lIHRvIGdldCB0aGUgdGljayBjb3VudCBhdFxuXHRcdCAqIEByZXR1cm4ge1RpY2tzfSAgICAgIFRoZSBudW1iZXIgb2YgdGlja3Mgd2hpY2ggaGF2ZSBlbGFwc2VkIGF0IHRoZSB0aW1lXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgIGdpdmVuIGFueSBhdXRvbWF0aW9ucy5cblx0XHQgKi9cblx0ICAgIFRvbmUuVGlja1NpZ25hbC5wcm90b3R5cGUuX2dldFRpY2tzVW50aWxFdmVudCA9IGZ1bmN0aW9uIChldmVudCwgdGltZSkge1xuXHQgICAgICAgIGlmIChldmVudCA9PT0gbnVsbCkge1xuXHQgICAgICAgICAgICBldmVudCA9IHtcblx0ICAgICAgICAgICAgICAgICd0aWNrcyc6IDAsXG5cdCAgICAgICAgICAgICAgICAndGltZSc6IDBcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9IGVsc2UgaWYgKFRvbmUuaXNVbmRlZihldmVudC50aWNrcykpIHtcblx0ICAgICAgICAgICAgdmFyIHByZXZpb3VzRXZlbnQgPSB0aGlzLl9ldmVudHMucHJldmlvdXNFdmVudChldmVudCk7XG5cdCAgICAgICAgICAgIGV2ZW50LnRpY2tzID0gdGhpcy5fZ2V0VGlja3NVbnRpbEV2ZW50KHByZXZpb3VzRXZlbnQsIGV2ZW50LnRpbWUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB2YXIgdmFsMCA9IHRoaXMuZ2V0VmFsdWVBdFRpbWUoZXZlbnQudGltZSk7XG5cdCAgICAgICAgdmFyIHZhbDEgPSB0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuXHQgICAgICAgIC8vaWYgaXQncyByaWdodCBvbiB0aGUgbGluZSwgdGFrZSB0aGUgcHJldmlvdXMgdmFsdWVcblx0ICAgICAgICBpZiAodGhpcy5fZXZlbnRzLmdldCh0aW1lKS50aW1lID09PSB0aW1lICYmIHRoaXMuX2V2ZW50cy5nZXQodGltZSkudHlwZSA9PT0gVG9uZS5QYXJhbS5BdXRvbWF0aW9uVHlwZS5TZXRWYWx1ZSkge1xuXHQgICAgICAgICAgICB2YWwxID0gdGhpcy5nZXRWYWx1ZUF0VGltZSh0aW1lIC0gdGhpcy5zYW1wbGVUaW1lKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIDAuNSAqICh0aW1lIC0gZXZlbnQudGltZSkgKiAodmFsMCArIHZhbDEpICsgZXZlbnQudGlja3M7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogUmV0dXJucyB0aGUgdGljayB2YWx1ZSBhdCB0aGUgdGltZS4gVGFrZXMgaW50byBhY2NvdW50XG5cdFx0ICogYW55IGF1dG9tYXRpb24gY3VydmVzIHNjaGVkdWxlZCBvbiB0aGUgc2lnbmFsLlxuXHRcdCAqIEBwYXJhbSAge1RpbWV9IHRpbWUgVGhlIHRpbWUgdG8gZ2V0IHRoZSB0aWNrIGNvdW50IGF0XG5cdFx0ICogQHJldHVybiB7VGlja3N9ICAgICAgVGhlIG51bWJlciBvZiB0aWNrcyB3aGljaCBoYXZlIGVsYXBzZWQgYXQgdGhlIHRpbWVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgZ2l2ZW4gYW55IGF1dG9tYXRpb25zLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaWNrU2lnbmFsLnByb3RvdHlwZS5nZXRUaWNrc0F0VGltZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHZhciBldmVudCA9IHRoaXMuX2V2ZW50cy5nZXQodGltZSk7XG5cdCAgICAgICAgcmV0dXJuIE1hdGgubWF4KHRoaXMuX2dldFRpY2tzVW50aWxFdmVudChldmVudCwgdGltZSksIDApO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFJldHVybiB0aGUgZWxhcHNlZCB0aW1lIG9mIHRoZSBudW1iZXIgb2YgdGlja3MgZnJvbSB0aGUgZ2l2ZW4gdGltZVxuXHRcdCAqIEBwYXJhbSB7VGlja3N9IHRpY2tzIFRoZSBudW1iZXIgb2YgdGlja3MgdG8gY2FsY3VsYXRlXG5cdFx0ICogQHBhcmFtICB7VGltZX0gdGltZSBUaGUgdGltZSB0byBnZXQgdGhlIG5leHQgdGljayBmcm9tXG5cdFx0ICogQHJldHVybiB7U2Vjb25kc30gVGhlIGR1cmF0aW9uIG9mIHRoZSBudW1iZXIgb2YgdGlja3MgZnJvbSB0aGUgZ2l2ZW4gdGltZSBpbiBzZWNvbmRzXG5cdFx0ICovXG5cdCAgICBUb25lLlRpY2tTaWduYWwucHJvdG90eXBlLmdldER1cmF0aW9uT2ZUaWNrcyA9IGZ1bmN0aW9uICh0aWNrcywgdGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB2YXIgY3VycmVudFRpY2sgPSB0aGlzLmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuXHQgICAgICAgIHJldHVybiB0aGlzLmdldFRpbWVPZlRpY2soY3VycmVudFRpY2sgKyB0aWNrcykgLSB0aW1lO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIEdpdmVuIGEgdGljaywgcmV0dXJucyB0aGUgdGltZSB0aGF0IHRpY2sgb2NjdXJzIGF0LlxuXHRcdCAqIEBwYXJhbSAge1RpY2tzfSB0aWNrXG5cdFx0ICogQHJldHVybiB7VGltZX0gICAgICBUaGUgdGltZSB0aGF0IHRoZSB0aWNrIG9jY3Vycy5cblx0XHQgKi9cblx0ICAgIFRvbmUuVGlja1NpZ25hbC5wcm90b3R5cGUuZ2V0VGltZU9mVGljayA9IGZ1bmN0aW9uICh0aWNrKSB7XG5cdCAgICAgICAgdmFyIGJlZm9yZSA9IHRoaXMuX2V2ZW50cy5nZXQodGljaywgJ3RpY2tzJyk7XG5cdCAgICAgICAgdmFyIGFmdGVyID0gdGhpcy5fZXZlbnRzLmdldEFmdGVyKHRpY2ssICd0aWNrcycpO1xuXHQgICAgICAgIGlmIChiZWZvcmUgJiYgYmVmb3JlLnRpY2tzID09PSB0aWNrKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBiZWZvcmUudGltZTtcblx0ICAgICAgICB9IGVsc2UgaWYgKGJlZm9yZSAmJiBhZnRlciAmJiBhZnRlci50eXBlID09PSBUb25lLlBhcmFtLkF1dG9tYXRpb25UeXBlLkxpbmVhciAmJiBiZWZvcmUudmFsdWUgIT09IGFmdGVyLnZhbHVlKSB7XG5cdCAgICAgICAgICAgIHZhciB2YWwwID0gdGhpcy5nZXRWYWx1ZUF0VGltZShiZWZvcmUudGltZSk7XG5cdCAgICAgICAgICAgIHZhciB2YWwxID0gdGhpcy5nZXRWYWx1ZUF0VGltZShhZnRlci50aW1lKTtcblx0ICAgICAgICAgICAgdmFyIGRlbHRhID0gKHZhbDEgLSB2YWwwKSAvIChhZnRlci50aW1lIC0gYmVmb3JlLnRpbWUpO1xuXHQgICAgICAgICAgICB2YXIgayA9IE1hdGguc3FydChNYXRoLnBvdyh2YWwwLCAyKSAtIDIgKiBkZWx0YSAqIChiZWZvcmUudGlja3MgLSB0aWNrKSk7XG5cdCAgICAgICAgICAgIHZhciBzb2wxID0gKC12YWwwICsgaykgLyBkZWx0YTtcblx0ICAgICAgICAgICAgdmFyIHNvbDIgPSAoLXZhbDAgLSBrKSAvIGRlbHRhO1xuXHQgICAgICAgICAgICByZXR1cm4gKHNvbDEgPiAwID8gc29sMSA6IHNvbDIpICsgYmVmb3JlLnRpbWU7XG5cdCAgICAgICAgfSBlbHNlIGlmIChiZWZvcmUpIHtcblx0ICAgICAgICAgICAgaWYgKGJlZm9yZS52YWx1ZSA9PT0gMCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIEluZmluaXR5O1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGJlZm9yZS50aW1lICsgKHRpY2sgLSBiZWZvcmUudGlja3MpIC8gYmVmb3JlLnZhbHVlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRpY2sgLyB0aGlzLl9pbml0aWFsVmFsdWU7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIENvbnZlcnQgc29tZSBudW1iZXIgb2YgdGlja3MgdGhlaXIgdGhlIGR1cmF0aW9uIGluIHNlY29uZHMgYWNjb3VudGluZ1xuXHRcdCAqIGZvciBhbnkgYXV0b21hdGlvbiBjdXJ2ZXMgc3RhcnRpbmcgYXQgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogQHBhcmFtICB7VGlja3N9IHRpY2tzIFRoZSBudW1iZXIgb2YgdGlja3MgdG8gY29udmVydCB0byBzZWNvbmRzLlxuXHRcdCAqIEBwYXJhbSAge1RpbWV9IFt3aGVuPW5vd10gIFdoZW4gYWxvbmcgdGhlIGF1dG9tYXRpb24gdGltZWxpbmUgdG8gY29udmVydCB0aGUgdGlja3MuXG5cdFx0ICogQHJldHVybiB7VG9uZS5UaW1lfSAgICAgICBUaGUgZHVyYXRpb24gaW4gc2Vjb25kcyBvZiB0aGUgdGlja3MuXG5cdFx0ICovXG5cdCAgICBUb25lLlRpY2tTaWduYWwucHJvdG90eXBlLnRpY2tzVG9UaW1lID0gZnVuY3Rpb24gKHRpY2tzLCB3aGVuKSB7XG5cdCAgICAgICAgd2hlbiA9IHRoaXMudG9TZWNvbmRzKHdoZW4pO1xuXHQgICAgICAgIHJldHVybiBuZXcgVG9uZS5UaW1lKHRoaXMuZ2V0RHVyYXRpb25PZlRpY2tzKHRpY2tzLCB3aGVuKSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIGludmVyc2Ugb2YgW3RpY2tzVG9UaW1lXSgjdGlja3N0b3RpbWUpLiBDb252ZXJ0IGEgZHVyYXRpb24gaW5cblx0XHQgKiBzZWNvbmRzIHRvIHRoZSBjb3JyZXNwb25kaW5nIG51bWJlciBvZiB0aWNrcyBhY2NvdW50aW5nIGZvciBhbnlcblx0XHQgKiBhdXRvbWF0aW9uIGN1cnZlcyBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gdGltZS5cblx0XHQgKiBAcGFyYW0gIHtUaW1lfSBkdXJhdGlvbiBUaGUgdGltZSBpbnRlcnZhbCB0byBjb252ZXJ0IHRvIHRpY2tzLlxuXHRcdCAqIEBwYXJhbSAge1RpbWV9IFt3aGVuPW5vd10gICAgIFdoZW4gYWxvbmcgdGhlIGF1dG9tYXRpb24gdGltZWxpbmUgdG8gY29udmVydCB0aGUgdGlja3MuXG5cdFx0ICogQHJldHVybiB7VG9uZS5UaWNrc30gICAgICAgICAgVGhlIGR1cmF0aW9uIGluIHRpY2tzLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaWNrU2lnbmFsLnByb3RvdHlwZS50aW1lVG9UaWNrcyA9IGZ1bmN0aW9uIChkdXJhdGlvbiwgd2hlbikge1xuXHQgICAgICAgIHdoZW4gPSB0aGlzLnRvU2Vjb25kcyh3aGVuKTtcblx0ICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcblx0ICAgICAgICB2YXIgc3RhcnRUaWNrcyA9IHRoaXMuZ2V0VGlja3NBdFRpbWUod2hlbik7XG5cdCAgICAgICAgdmFyIGVuZFRpY2tzID0gdGhpcy5nZXRUaWNrc0F0VGltZSh3aGVuICsgZHVyYXRpb24pO1xuXHQgICAgICAgIHJldHVybiBuZXcgVG9uZS5UaWNrcyhlbmRUaWNrcyAtIHN0YXJ0VGlja3MpO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlRpY2tTaWduYWw7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgQSBUaW1lbGluZSBTdGF0ZS4gUHJvdmlkZXMgdGhlIG1ldGhvZHM6IDxjb2RlPnNldFN0YXRlQXRUaW1lKFwic3RhdGVcIiwgdGltZSk8L2NvZGU+XG5cdFx0ICogICAgICAgICAgYW5kIDxjb2RlPmdldFZhbHVlQXRUaW1lKHRpbWUpPC9jb2RlPi5cblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5UaW1lbGluZX1cblx0XHQgKiAgQHBhcmFtIHtTdHJpbmd9IGluaXRpYWwgVGhlIGluaXRpYWwgc3RhdGUgb2YgdGhlIFRpbWVsaW5lU3RhdGUuIFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0cyB0byA8Y29kZT51bmRlZmluZWQ8L2NvZGU+XG5cdFx0ICovXG5cdCAgICBUb25lLlRpbWVsaW5lU3RhdGUgPSBmdW5jdGlvbiAoaW5pdGlhbCkge1xuXHQgICAgICAgIFRvbmUuVGltZWxpbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgaW5pdGlhbCBzdGF0ZVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge1N0cmluZ31cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2luaXRpYWwgPSBpbml0aWFsO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuVGltZWxpbmVTdGF0ZSwgVG9uZS5UaW1lbGluZSk7XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJucyB0aGUgc2NoZWR1bGVkIHN0YXRlIHNjaGVkdWxlZCBiZWZvcmUgb3IgYXRcblx0XHQgKiAgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuXHRcdCAqICBAcmV0dXJuICB7U3RyaW5nfSAgVGhlIG5hbWUgb2YgdGhlIHN0YXRlIGlucHV0IGluIHNldFN0YXRlQXRUaW1lLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lbGluZVN0YXRlLnByb3RvdHlwZS5nZXRWYWx1ZUF0VGltZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdmFyIGV2ZW50ID0gdGhpcy5nZXQodGltZSk7XG5cdCAgICAgICAgaWYgKGV2ZW50ICE9PSBudWxsKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBldmVudC5zdGF0ZTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5faW5pdGlhbDtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEFkZCBhIHN0YXRlIHRvIHRoZSB0aW1lbGluZS5cblx0XHQgKiAgQHBhcmFtICB7U3RyaW5nfSAgc3RhdGUgVGhlIG5hbWUgb2YgdGhlIHN0YXRlIHRvIHNldC5cblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRpbWVsaW5lU3RhdGV9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVGltZWxpbmVTdGF0ZS5wcm90b3R5cGUuc2V0U3RhdGVBdFRpbWUgPSBmdW5jdGlvbiAoc3RhdGUsIHRpbWUpIHtcblx0ICAgICAgICAvL2FsbCBzdGF0ZSBjaGFuZ2VzIG5lZWQgdG8gYmUgPj0gdGhlIHByZXZpb3VzIHN0YXRlIHRpbWVcblx0ICAgICAgICAvL1RPRE8gdGhyb3cgZXJyb3IgaWYgdGltZSA8IHRoZSBwcmV2aW91cyBldmVudCB0aW1lXG5cdCAgICAgICAgdGhpcy5hZGQoe1xuXHQgICAgICAgICAgICAnc3RhdGUnOiBzdGF0ZSxcblx0ICAgICAgICAgICAgJ3RpbWUnOiB0aW1lXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybiB0aGUgZXZlbnQgYmVmb3JlIHRoZSB0aW1lIHdpdGggdGhlIGdpdmVuIHN0YXRlXG5cdFx0ICogIEBwYXJhbSB7VG9uZS5TdGF0ZX0gc3RhdGUgVGhlIHN0YXRlIHRvIGxvb2sgZm9yXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9ICB0aW1lICBXaGVuIHRvIGNoZWNrIGJlZm9yZVx0XHRcdFxuXHRcdCAqICBAcmV0dXJuICB7T2JqZWN0fSAgVGhlIGV2ZW50IHdpdGggdGhlIGdpdmVuIHN0YXRlIGJlZm9yZSB0aGUgdGltZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaW1lbGluZVN0YXRlLnByb3RvdHlwZS5nZXRMYXN0U3RhdGUgPSBmdW5jdGlvbiAoc3RhdGUsIHRpbWUpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSBpbmRleDsgaSA+PSAwOyBpLS0pIHtcblx0ICAgICAgICAgICAgdmFyIGV2ZW50ID0gdGhpcy5fdGltZWxpbmVbaV07XG5cdCAgICAgICAgICAgIGlmIChldmVudC5zdGF0ZSA9PT0gc3RhdGUpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBldmVudDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJuIHRoZSBldmVudCBhZnRlciB0aGUgdGltZSB3aXRoIHRoZSBnaXZlbiBzdGF0ZVxuXHRcdCAqICBAcGFyYW0ge1RvbmUuU3RhdGV9IHN0YXRlIFRoZSBzdGF0ZSB0byBsb29rIGZvclxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSAgdGltZSAgV2hlbiB0byBjaGVjayBmcm9tXG5cdFx0ICogIEByZXR1cm4gIHtPYmplY3R9ICBUaGUgZXZlbnQgd2l0aCB0aGUgZ2l2ZW4gc3RhdGUgYWZ0ZXIgdGhlIHRpbWVcblx0XHQgKi9cblx0ICAgIFRvbmUuVGltZWxpbmVTdGF0ZS5wcm90b3R5cGUuZ2V0TmV4dFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlLCB0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcblx0ICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSBpbmRleDsgaSA8IHRoaXMuX3RpbWVsaW5lLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgZXZlbnQgPSB0aGlzLl90aW1lbGluZVtpXTtcblx0ICAgICAgICAgICAgICAgIGlmIChldmVudC5zdGF0ZSA9PT0gc3RhdGUpIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQ7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuVGltZWxpbmVTdGF0ZTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBVc2VzIFtUb25lLlRpY2tTaWduYWxdKFRpY2tTaWduYWwpIHRvIHRyYWNrIGVsYXBzZWQgdGlja3Mgd2l0aFxuXHRcdCAqICBcdFx0Y29tcGxleCBhdXRvbWF0aW9uIGN1cnZlcy5cblx0XHQgKlxuXHRcdCAqIFx0QGNvbnN0cnVjdG9yXG5cdCAgICAgKiAgQHBhcmFtIHtGcmVxdWVuY3l9IGZyZXF1ZW5jeSBUaGUgaW5pdGlhbCBmcmVxdWVuY3kgdGhhdCB0aGUgc2lnbmFsIHRpY2tzIGF0XG5cdFx0ICogIEBleHRlbmRzIHtUb25lfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaWNrU291cmNlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFsnZnJlcXVlbmN5J10sIFRvbmUuVGlja1NvdXJjZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGZyZXF1ZW5jeSB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gc2hvdWxkIGJlIGludm9rZWQuXG5cdFx0XHQgKiAgQHR5cGUgIHtGcmVxdWVuY3l9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgVG9uZS5UaWNrU2lnbmFsKG9wdGlvbnMuZnJlcXVlbmN5LCBUb25lLlR5cGUuRnJlcXVlbmN5KTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seSgnZnJlcXVlbmN5Jyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHN0YXRlIHRpbWVsaW5lXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuVGltZWxpbmVTdGF0ZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3RhdGUgPSBuZXcgVG9uZS5UaW1lbGluZVN0YXRlKFRvbmUuU3RhdGUuU3RvcHBlZCk7XG5cdCAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoVG9uZS5TdGF0ZS5TdG9wcGVkLCAwKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBvZmZzZXQgdmFsdWVzIG9mIHRoZSB0aWNrc1xuXHRcdFx0ICogQHR5cGUge1RvbmUuVGltZWxpbmV9XG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fdGlja09mZnNldCA9IG5ldyBUb25lLlRpbWVsaW5lKCk7XG5cdCAgICAgICAgLy9hZGQgdGhlIGZpcnN0IGV2ZW50XG5cdCAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZSgwLCAwKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlRpY2tTb3VyY2UpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0c1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLlRpY2tTb3VyY2UuZGVmYXVsdHMgPSB7ICdmcmVxdWVuY3knOiAxIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiLCBcInN0b3BwZWRcIiBvciBcInBhdXNlZFwiLlxuXHRcdCAqICBAdHlwZSB7VG9uZS5TdGF0ZX1cblx0XHQgKiAgQHJlYWRPbmx5XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlRpY2tTb3VyY2UjXG5cdFx0ICogIEBuYW1lIHN0YXRlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5UaWNrU291cmNlLnByb3RvdHlwZSwgJ3N0YXRlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGhpcy5ub3coKSk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgU3RhcnQgdGhlIGNsb2NrIGF0IHRoZSBnaXZlbiB0aW1lLiBPcHRpb25hbGx5IHBhc3MgaW4gYW4gb2Zmc2V0XG5cdFx0ICogIG9mIHdoZXJlIHRvIHN0YXJ0IHRoZSB0aWNrIGNvdW50ZXIgZnJvbS5cblx0XHQgKiAgQHBhcmFtICB7VGltZT19ICB0aW1lICAgIFRoZSB0aW1lIHRoZSBjbG9jayBzaG91bGQgc3RhcnRcblx0XHQgKiAgQHBhcmFtIHtUaWNrcz0wfSBvZmZzZXQgVGhlIG51bWJlciBvZiB0aWNrcyB0byBzdGFydCB0aGUgc291cmNlIGF0XG5cdFx0ICogIEByZXR1cm4gIHtUb25lLlRpY2tTb3VyY2V9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRpY2tTb3VyY2UucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24gKHRpbWUsIG9mZnNldCkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGltZSkgIT09IFRvbmUuU3RhdGUuU3RhcnRlZCkge1xuXHQgICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShUb25lLlN0YXRlLlN0YXJ0ZWQsIHRpbWUpO1xuXHQgICAgICAgICAgICBpZiAoVG9uZS5pc0RlZmluZWQob2Zmc2V0KSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZShvZmZzZXQsIHRpbWUpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTdG9wIHRoZSBjbG9jay4gU3RvcHBpbmcgdGhlIGNsb2NrIHJlc2V0cyB0aGUgdGljayBjb3VudGVyIHRvIDAuXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW3RpbWU9bm93XSBUaGUgdGltZSB3aGVuIHRoZSBjbG9jayBzaG91bGQgc3RvcC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuVGlja1NvdXJjZX0gdGhpc1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIGNsb2NrLnN0b3AoKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuVGlja1NvdXJjZS5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIC8vY2FuY2VsIHRoZSBwcmV2aW91cyBzdG9wXG5cdCAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpbWUpID09PSBUb25lLlN0YXRlLlN0b3BwZWQpIHtcblx0ICAgICAgICAgICAgdmFyIGV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KHRpbWUpO1xuXHQgICAgICAgICAgICBpZiAoZXZlbnQudGltZSA+IDApIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuY2FuY2VsKGV2ZW50LnRpbWUpO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGV2ZW50LnRpbWUpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShUb25lLlN0YXRlLlN0b3BwZWQsIHRpbWUpO1xuXHQgICAgICAgIHRoaXMuc2V0VGlja3NBdFRpbWUoMCwgdGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFBhdXNlIHRoZSBjbG9jay4gUGF1c2luZyBkb2VzIG5vdCByZXNldCB0aGUgdGljayBjb3VudGVyLlxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IFt0aW1lPW5vd10gVGhlIHRpbWUgd2hlbiB0aGUgY2xvY2sgc2hvdWxkIHN0b3AuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRpY2tTb3VyY2V9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVGlja1NvdXJjZS5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGltZSkgPT09IFRvbmUuU3RhdGUuU3RhcnRlZCkge1xuXHQgICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShUb25lLlN0YXRlLlBhdXNlZCwgdGltZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDYW5jZWwgc3RhcnQvc3RvcC9wYXVzZSBhbmQgc2V0VGlja0F0VGltZSBldmVudHMgc2NoZWR1bGVkIGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IFt0aW1lPW5vd10gV2hlbiB0byBjbGVhciB0aGUgZXZlbnRzIGFmdGVyXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRpY2tTb3VyY2V9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVGlja1NvdXJjZS5wcm90b3R5cGUuY2FuY2VsID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHRpbWUpO1xuXHQgICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuY2FuY2VsKHRpbWUpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIEdldCB0aGUgZWxhcHNlZCB0aWNrcyBhdCB0aGUgZ2l2ZW4gdGltZVxuXHRcdCAqIEBwYXJhbSAge1RpbWV9IHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSB0aWNrIHZhbHVlXG5cdFx0ICogQHJldHVybiB7VGlja3N9ICAgICBUaGUgbnVtYmVyIG9mIHRpY2tzXG5cdFx0ICovXG5cdCAgICBUb25lLlRpY2tTb3VyY2UucHJvdG90eXBlLmdldFRpY2tzQXRUaW1lID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdmFyIHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldExhc3RTdGF0ZShUb25lLlN0YXRlLlN0b3BwZWQsIHRpbWUpO1xuXHQgICAgICAgIC8vdGhpcyBldmVudCBhbGxvd3MgZm9yRWFjaEJldHdlZW4gdG8gaXRlcmF0ZSB1bnRpbCB0aGUgY3VycmVudCB0aW1lXG5cdCAgICAgICAgdmFyIHRtcEV2ZW50ID0ge1xuXHQgICAgICAgICAgICBzdGF0ZTogVG9uZS5TdGF0ZS5QYXVzZWQsXG5cdCAgICAgICAgICAgIHRpbWU6IHRpbWVcblx0ICAgICAgICB9O1xuXHQgICAgICAgIHRoaXMuX3N0YXRlLmFkZCh0bXBFdmVudCk7XG5cdCAgICAgICAgLy9rZWVwIHRyYWNrIG9mIHRoZSBwcmV2aW91cyBvZmZzZXQgZXZlbnRcblx0ICAgICAgICB2YXIgbGFzdFN0YXRlID0gc3RvcEV2ZW50O1xuXHQgICAgICAgIHZhciBlbGFwc2VkVGlja3MgPSAwO1xuXHQgICAgICAgIC8vaXRlcmF0ZSB0aHJvdWdoIGFsbCB0aGUgZXZlbnRzIHNpbmNlIHRoZSBsYXN0IHN0b3Bcblx0ICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoQmV0d2VlbihzdG9wRXZlbnQudGltZSwgdGltZSArIHRoaXMuc2FtcGxlVGltZSwgZnVuY3Rpb24gKGUpIHtcblx0ICAgICAgICAgICAgdmFyIHBlcmlvZFN0YXJ0VGltZSA9IGxhc3RTdGF0ZS50aW1lO1xuXHQgICAgICAgICAgICAvL2lmIHRoZXJlIGlzIGFuIG9mZnNldCBldmVudCBpbiB0aGlzIHBlcmlvZCB1c2UgdGhhdFxuXHQgICAgICAgICAgICB2YXIgb2Zmc2V0RXZlbnQgPSB0aGlzLl90aWNrT2Zmc2V0LmdldChlLnRpbWUpO1xuXHQgICAgICAgICAgICBpZiAob2Zmc2V0RXZlbnQudGltZSA+PSBsYXN0U3RhdGUudGltZSkge1xuXHQgICAgICAgICAgICAgICAgZWxhcHNlZFRpY2tzID0gb2Zmc2V0RXZlbnQudGlja3M7XG5cdCAgICAgICAgICAgICAgICBwZXJpb2RTdGFydFRpbWUgPSBvZmZzZXRFdmVudC50aW1lO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChsYXN0U3RhdGUuc3RhdGUgPT09IFRvbmUuU3RhdGUuU3RhcnRlZCAmJiBlLnN0YXRlICE9PSBUb25lLlN0YXRlLlN0YXJ0ZWQpIHtcblx0ICAgICAgICAgICAgICAgIGVsYXBzZWRUaWNrcyArPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShlLnRpbWUpIC0gdGhpcy5mcmVxdWVuY3kuZ2V0VGlja3NBdFRpbWUocGVyaW9kU3RhcnRUaW1lKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBsYXN0U3RhdGUgPSBlO1xuXHQgICAgICAgIH0uYmluZCh0aGlzKSk7XG5cdCAgICAgICAgLy9yZW1vdmUgdGhlIHRlbXBvcmFyeSBldmVudFxuXHQgICAgICAgIHRoaXMuX3N0YXRlLnJlbW92ZSh0bXBFdmVudCk7XG5cdCAgICAgICAgLy9yZXR1cm4gdGhlIHRpY2tzXG5cdCAgICAgICAgcmV0dXJuIGVsYXBzZWRUaWNrcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIG51bWJlciBvZiB0aW1lcyB0aGUgY2FsbGJhY2sgd2FzIGludm9rZWQuIFN0YXJ0cyBjb3VudGluZyBhdCAwXG5cdFx0ICogIGFuZCBpbmNyZW1lbnRzIGFmdGVyIHRoZSBjYWxsYmFjayB3YXMgaW52b2tlZC4gUmV0dXJucyAtMSB3aGVuIHN0b3BwZWQuXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlRpY2tTb3VyY2UjXG5cdFx0ICogIEBuYW1lIHRpY2tzXG5cdFx0ICogIEB0eXBlIHtUaWNrc31cblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlRpY2tTb3VyY2UucHJvdG90eXBlLCAndGlja3MnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLmdldFRpY2tzQXRUaW1lKHRoaXMubm93KCkpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodCkge1xuXHQgICAgICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKHQsIHRoaXMubm93KCkpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSB0aW1lIHNpbmNlIHRpY2tzPTAgdGhhdCB0aGUgVGlja1NvdXJjZSBoYXMgYmVlbiBydW5uaW5nLiBBY2NvdW50c1xuXHRcdCAqICBmb3IgdGVtcG8gY3VydmVzXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlRpY2tTb3VyY2UjXG5cdFx0ICogIEBuYW1lIHNlY29uZHNcblx0XHQgKiAgQHR5cGUge1NlY29uZHN9XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5UaWNrU291cmNlLnByb3RvdHlwZSwgJ3NlY29uZHMnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLmdldFNlY29uZHNBdFRpbWUodGhpcy5ub3coKSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChzKSB7XG5cdCAgICAgICAgICAgIHZhciBub3cgPSB0aGlzLm5vdygpO1xuXHQgICAgICAgICAgICB2YXIgdGlja3MgPSB0aGlzLmZyZXF1ZW5jeS50aW1lVG9UaWNrcyhzLCBub3cpO1xuXHQgICAgICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKHRpY2tzLCBub3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybiB0aGUgZWxhcHNlZCBzZWNvbmRzIGF0IHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSAgdGltZSAgV2hlbiB0byBnZXQgdGhlIGVsYXBzZWQgc2Vjb25kc1xuXHRcdCAqICBAcmV0dXJuICB7U2Vjb25kc30gIFRoZSBudW1iZXIgb2YgZWxhcHNlZCBzZWNvbmRzXG5cdFx0ICovXG5cdCAgICBUb25lLlRpY2tTb3VyY2UucHJvdG90eXBlLmdldFNlY29uZHNBdFRpbWUgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB2YXIgc3RvcEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0TGFzdFN0YXRlKFRvbmUuU3RhdGUuU3RvcHBlZCwgdGltZSk7XG5cdCAgICAgICAgLy90aGlzIGV2ZW50IGFsbG93cyBmb3JFYWNoQmV0d2VlbiB0byBpdGVyYXRlIHVudGlsIHRoZSBjdXJyZW50IHRpbWVcblx0ICAgICAgICB2YXIgdG1wRXZlbnQgPSB7XG5cdCAgICAgICAgICAgIHN0YXRlOiBUb25lLlN0YXRlLlBhdXNlZCxcblx0ICAgICAgICAgICAgdGltZTogdGltZVxuXHQgICAgICAgIH07XG5cdCAgICAgICAgdGhpcy5fc3RhdGUuYWRkKHRtcEV2ZW50KTtcblx0ICAgICAgICAvL2tlZXAgdHJhY2sgb2YgdGhlIHByZXZpb3VzIG9mZnNldCBldmVudFxuXHQgICAgICAgIHZhciBsYXN0U3RhdGUgPSBzdG9wRXZlbnQ7XG5cdCAgICAgICAgdmFyIGVsYXBzZWRTZWNvbmRzID0gMDtcblx0ICAgICAgICAvL2l0ZXJhdGUgdGhyb3VnaCBhbGwgdGhlIGV2ZW50cyBzaW5jZSB0aGUgbGFzdCBzdG9wXG5cdCAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaEJldHdlZW4oc3RvcEV2ZW50LnRpbWUsIHRpbWUgKyB0aGlzLnNhbXBsZVRpbWUsIGZ1bmN0aW9uIChlKSB7XG5cdCAgICAgICAgICAgIHZhciBwZXJpb2RTdGFydFRpbWUgPSBsYXN0U3RhdGUudGltZTtcblx0ICAgICAgICAgICAgLy9pZiB0aGVyZSBpcyBhbiBvZmZzZXQgZXZlbnQgaW4gdGhpcyBwZXJpb2QgdXNlIHRoYXRcblx0ICAgICAgICAgICAgdmFyIG9mZnNldEV2ZW50ID0gdGhpcy5fdGlja09mZnNldC5nZXQoZS50aW1lKTtcblx0ICAgICAgICAgICAgaWYgKG9mZnNldEV2ZW50LnRpbWUgPj0gbGFzdFN0YXRlLnRpbWUpIHtcblx0ICAgICAgICAgICAgICAgIGVsYXBzZWRTZWNvbmRzID0gb2Zmc2V0RXZlbnQuc2Vjb25kcztcblx0ICAgICAgICAgICAgICAgIHBlcmlvZFN0YXJ0VGltZSA9IG9mZnNldEV2ZW50LnRpbWU7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKGxhc3RTdGF0ZS5zdGF0ZSA9PT0gVG9uZS5TdGF0ZS5TdGFydGVkICYmIGUuc3RhdGUgIT09IFRvbmUuU3RhdGUuU3RhcnRlZCkge1xuXHQgICAgICAgICAgICAgICAgZWxhcHNlZFNlY29uZHMgKz0gZS50aW1lIC0gcGVyaW9kU3RhcnRUaW1lO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGxhc3RTdGF0ZSA9IGU7XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgICAgICAvL3JlbW92ZSB0aGUgdGVtcG9yYXJ5IGV2ZW50XG5cdCAgICAgICAgdGhpcy5fc3RhdGUucmVtb3ZlKHRtcEV2ZW50KTtcblx0ICAgICAgICAvL3JldHVybiB0aGUgdGlja3Ncblx0ICAgICAgICByZXR1cm4gZWxhcHNlZFNlY29uZHM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogU2V0IHRoZSBjbG9jaydzIHRpY2tzIGF0IHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqIEBwYXJhbSAge1RpY2tzfSB0aWNrcyBUaGUgdGljayB2YWx1ZSB0byBzZXRcblx0XHQgKiBAcGFyYW0gIHtUaW1lfSB0aW1lICBXaGVuIHRvIHNldCB0aGUgdGljayB2YWx1ZVxuXHRcdCAqIEByZXR1cm4ge1RvbmUuVGlja1NvdXJjZX0gICAgICAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UaWNrU291cmNlLnByb3RvdHlwZS5zZXRUaWNrc0F0VGltZSA9IGZ1bmN0aW9uICh0aWNrcywgdGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmNhbmNlbCh0aW1lKTtcblx0ICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmFkZCh7XG5cdCAgICAgICAgICAgICd0aW1lJzogdGltZSxcblx0ICAgICAgICAgICAgJ3RpY2tzJzogdGlja3MsXG5cdCAgICAgICAgICAgICdzZWNvbmRzJzogdGhpcy5mcmVxdWVuY3kuZ2V0RHVyYXRpb25PZlRpY2tzKHRpY2tzLCB0aW1lKVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm5zIHRoZSBzY2hlZHVsZWQgc3RhdGUgYXQgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9ICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cblx0XHQgKiAgQHJldHVybiAge1N0cmluZ30gIFRoZSBuYW1lIG9mIHRoZSBzdGF0ZSBpbnB1dCBpbiBzZXRTdGF0ZUF0VGltZS5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBzb3VyY2Uuc3RhcnQoXCIrMC4xXCIpO1xuXHRcdCAqIHNvdXJjZS5nZXRTdGF0ZUF0VGltZShcIiswLjFcIik7IC8vcmV0dXJucyBcInN0YXJ0ZWRcIlxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaWNrU291cmNlLnByb3RvdHlwZS5nZXRTdGF0ZUF0VGltZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBHZXQgdGhlIHRpbWUgb2YgdGhlIGdpdmVuIHRpY2suIFRoZSBzZWNvbmQgYXJndW1lbnRcblx0XHQgKiBpcyB3aGVuIHRvIHRlc3QgYmVmb3JlLiBTaW5jZSB0aWNrcyBjYW4gYmUgc2V0ICh3aXRoIHNldFRpY2tzQXRUaW1lKVxuXHRcdCAqIHRoZXJlIG1heSBiZSBtdWx0aXBsZSB0aW1lcyBmb3IgYSBnaXZlbiB0aWNrIHZhbHVlLiBcblx0XHQgKiBAcGFyYW0gIHtUaWNrc30gdGlja3MgVGhlIHRpY2sgbnVtYmVyLlxuXHRcdCAqIEBwYXJhbSAge1RpbWU9fSBiZWZvcmUgV2hlbiB0byBtZWFzdXJlIHRoZSB0aWNrIHZhbHVlIGZyb20uIFxuXHRcdCAqIEByZXR1cm4ge1RpbWV9ICAgICAgIFRoZSB0aW1lIG9mIHRoZSB0aWNrXG5cdFx0ICovXG5cdCAgICBUb25lLlRpY2tTb3VyY2UucHJvdG90eXBlLmdldFRpbWVPZlRpY2sgPSBmdW5jdGlvbiAodGljaywgYmVmb3JlKSB7XG5cdCAgICAgICAgYmVmb3JlID0gVG9uZS5kZWZhdWx0QXJnKGJlZm9yZSwgdGhpcy5ub3coKSk7XG5cdCAgICAgICAgdmFyIG9mZnNldCA9IHRoaXMuX3RpY2tPZmZzZXQuZ2V0KGJlZm9yZSk7XG5cdCAgICAgICAgdmFyIGV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KGJlZm9yZSk7XG5cdCAgICAgICAgdmFyIHN0YXJ0VGltZSA9IE1hdGgubWF4KG9mZnNldC50aW1lLCBldmVudC50aW1lKTtcblx0ICAgICAgICB2YXIgYWJzb2x1dGVUaWNrcyA9IHRoaXMuZnJlcXVlbmN5LmdldFRpY2tzQXRUaW1lKHN0YXJ0VGltZSkgKyB0aWNrIC0gb2Zmc2V0LnRpY2tzO1xuXHQgICAgICAgIHJldHVybiB0aGlzLmZyZXF1ZW5jeS5nZXRUaW1lT2ZUaWNrKGFic29sdXRlVGlja3MpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBJbnZva2UgdGhlIGNhbGxiYWNrIGV2ZW50IGF0IGFsbCBzY2hlZHVsZWQgdGlja3MgYmV0d2VlbiB0aGUgXG5cdFx0ICogIHN0YXJ0IHRpbWUgYW5kIHRoZSBlbmQgdGltZVxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSAgICBzdGFydFRpbWUgIFRoZSBiZWdpbm5pbmcgb2YgdGhlIHNlYXJjaCByYW5nZVxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSAgICBlbmRUaW1lICAgIFRoZSBlbmQgb2YgdGhlIHNlYXJjaCByYW5nZVxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbjxUaW1lLFRpY2tzPn0gIGNhbGxiYWNrICAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGVhY2ggdGlja1xuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5UaWNrU291cmNlfSAgICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRpY2tTb3VyY2UucHJvdG90eXBlLmZvckVhY2hUaWNrQmV0d2VlbiA9IGZ1bmN0aW9uIChzdGFydFRpbWUsIGVuZFRpbWUsIGNhbGxiYWNrKSB7XG5cdCAgICAgICAgLy9vbmx5IGl0ZXJhdGUgdGhyb3VnaCB0aGUgc2VjdGlvbnMgd2hlcmUgaXQgaXMgXCJzdGFydGVkXCJcblx0ICAgICAgICB2YXIgbGFzdFN0YXRlRXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXQoc3RhcnRUaW1lKTtcblx0ICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoQmV0d2VlbihzdGFydFRpbWUsIGVuZFRpbWUsIGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgICAgICBpZiAobGFzdFN0YXRlRXZlbnQuc3RhdGUgPT09IFRvbmUuU3RhdGUuU3RhcnRlZCAmJiBldmVudC5zdGF0ZSAhPT0gVG9uZS5TdGF0ZS5TdGFydGVkKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLmZvckVhY2hUaWNrQmV0d2VlbihNYXRoLm1heChsYXN0U3RhdGVFdmVudC50aW1lLCBzdGFydFRpbWUpLCBldmVudC50aW1lIC0gdGhpcy5zYW1wbGVUaW1lLCBjYWxsYmFjayk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgbGFzdFN0YXRlRXZlbnQgPSBldmVudDtcblx0ICAgICAgICB9LmJpbmQodGhpcykpO1xuXHQgICAgICAgIHN0YXJ0VGltZSA9IE1hdGgubWF4KGxhc3RTdGF0ZUV2ZW50LnRpbWUsIHN0YXJ0VGltZSk7XG5cdCAgICAgICAgaWYgKGxhc3RTdGF0ZUV2ZW50LnN0YXRlID09PSBUb25lLlN0YXRlLlN0YXJ0ZWQgJiYgdGhpcy5fc3RhdGUpIHtcblx0ICAgICAgICAgICAgLy9maWd1cmUgb3V0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGZyZXF1ZW5jeSB0aWNrcyBhbmQgdGhlIFxuXHQgICAgICAgICAgICB2YXIgc3RhcnRUaWNrcyA9IHRoaXMuZnJlcXVlbmN5LmdldFRpY2tzQXRUaW1lKHN0YXJ0VGltZSk7XG5cdCAgICAgICAgICAgIHZhciB0aWNrc0F0U3RhcnQgPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShsYXN0U3RhdGVFdmVudC50aW1lKTtcblx0ICAgICAgICAgICAgdmFyIGRpZmYgPSBzdGFydFRpY2tzIC0gdGlja3NBdFN0YXJ0O1xuXHQgICAgICAgICAgICB2YXIgb2Zmc2V0ID0gZGlmZiAlIDE7XG5cdCAgICAgICAgICAgIGlmIChvZmZzZXQgIT09IDApIHtcblx0ICAgICAgICAgICAgICAgIG9mZnNldCA9IDEgLSBvZmZzZXQ7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdmFyIG5leHRUaWNrVGltZSA9IHRoaXMuZnJlcXVlbmN5LmdldFRpbWVPZlRpY2soc3RhcnRUaWNrcyArIG9mZnNldCk7XG5cdCAgICAgICAgICAgIHZhciBlcnJvciA9IG51bGw7XG5cdCAgICAgICAgICAgIHdoaWxlIChuZXh0VGlja1RpbWUgPCBlbmRUaW1lICYmIHRoaXMuX3N0YXRlKSB7XG5cdCAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG5leHRUaWNrVGltZSwgTWF0aC5yb3VuZCh0aGlzLmdldFRpY2tzQXRUaW1lKG5leHRUaWNrVGltZSkpKTtcblx0ICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGU7XG5cdCAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUpIHtcblx0ICAgICAgICAgICAgICAgICAgICBuZXh0VGlja1RpbWUgKz0gdGhpcy5mcmVxdWVuY3kuZ2V0RHVyYXRpb25PZlRpY2tzKDEsIG5leHRUaWNrVGltZSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKGVycm9yKSB7XG5cdCAgICAgICAgICAgIHRocm93IGVycm9yO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXBcblx0XHQgKiAgQHJldHVybnMge1RvbmUuVGlja1NvdXJjZX0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UaWNrU291cmNlLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuUGFyYW0ucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3RpY2tPZmZzZXQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKCdmcmVxdWVuY3knKTtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlRpY2tTb3VyY2U7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgQSBzYW1wbGUgYWNjdXJhdGUgY2xvY2sgd2hpY2ggcHJvdmlkZXMgYSBjYWxsYmFjayBhdCB0aGUgZ2l2ZW4gcmF0ZS5cblx0XHQgKiAgICAgICAgICBXaGlsZSB0aGUgY2FsbGJhY2sgaXMgbm90IHNhbXBsZS1hY2N1cmF0ZSAoaXQgaXMgc3RpbGwgc3VzY2VwdGlibGUgdG9cblx0XHQgKiAgICAgICAgICBsb29zZSBKUyB0aW1pbmcpLCB0aGUgdGltZSBwYXNzZWQgaW4gYXMgdGhlIGFyZ3VtZW50IHRvIHRoZSBjYWxsYmFja1xuXHRcdCAqICAgICAgICAgIGlzIHByZWNpc2UuIEZvciBtb3N0IGFwcGxpY2F0aW9ucywgaXQgaXMgYmV0dGVyIHRvIHVzZSBUb25lLlRyYW5zcG9ydFxuXHRcdCAqICAgICAgICAgIGluc3RlYWQgb2YgdGhlIENsb2NrIGJ5IGl0c2VsZiBzaW5jZSB5b3UgY2FuIHN5bmNocm9uaXplIG11bHRpcGxlIGNhbGxiYWNrcy5cblx0XHQgKlxuXHRcdCAqIFx0QGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkVtaXR0ZXJ9XG5cdFx0ICogXHRAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gYmUgaW52b2tlZCB3aXRoIHRoZSB0aW1lIG9mIHRoZSBhdWRpbyBldmVudFxuXHRcdCAqIFx0QHBhcmFtIHtGcmVxdWVuY3l9IGZyZXF1ZW5jeSBUaGUgcmF0ZSBvZiB0aGUgY2FsbGJhY2tcblx0XHQgKiBcdEBleGFtcGxlXG5cdFx0ICogLy90aGUgY2FsbGJhY2sgd2lsbCBiZSBpbnZva2VkIGFwcHJveGltYXRlbHkgb25jZSBhIHNlY29uZFxuXHRcdCAqIC8vYW5kIHdpbGwgcHJpbnQgdGhlIHRpbWUgZXhhY3RseSBvbmNlIGEgc2Vjb25kIGFwYXJ0LlxuXHRcdCAqIHZhciBjbG9jayA9IG5ldyBUb25lLkNsb2NrKGZ1bmN0aW9uKHRpbWUpe1xuXHRcdCAqIFx0Y29uc29sZS5sb2codGltZSk7XG5cdFx0ICogfSwgMSk7XG5cdFx0ICovXG5cdCAgICBUb25lLkNsb2NrID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ2NhbGxiYWNrJyxcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeSdcblx0ICAgICAgICBdLCBUb25lLkNsb2NrKTtcblx0ICAgICAgICBUb25lLkVtaXR0ZXIuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gaW52b2tlIGF0IHRoZSBzY2hlZHVsZWQgdGljay5cblx0XHRcdCAqICBAdHlwZSAge0Z1bmN0aW9ufVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5jYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG5leHQgdGltZSB0aGUgY2FsbGJhY2sgaXMgc2NoZWR1bGVkLlxuXHRcdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX25leHRUaWNrID0gMDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgdGljayBjb3VudGVyXG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLlRpY2tTb3VyY2V9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3RpY2tTb3VyY2UgPSBuZXcgVG9uZS5UaWNrU291cmNlKG9wdGlvbnMuZnJlcXVlbmN5KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbGFzdCB0aW1lIHRoZSBsb29wIGNhbGxiYWNrIHdhcyBpbnZva2VkXG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbGFzdFVwZGF0ZSA9IDA7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHJhdGUgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHNob3VsZCBiZSBpbnZva2VkLlxuXHRcdFx0ICogIEB0eXBlICB7QlBNfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fdGlja1NvdXJjZS5mcmVxdWVuY3k7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoJ2ZyZXF1ZW5jeScpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBzdGF0ZSB0aW1lbGluZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLlRpbWVsaW5lU3RhdGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFRvbmUuVGltZWxpbmVTdGF0ZShUb25lLlN0YXRlLlN0b3BwZWQpO1xuXHQgICAgICAgIC8vYWRkIGFuIGluaXRpYWwgc3RhdGVcblx0ICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShUb25lLlN0YXRlLlN0b3BwZWQsIDApO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBsb29wIGZ1bmN0aW9uIGJvdW5kIHRvIGl0cyBjb250ZXh0LlxuXHRcdFx0ICogIFRoaXMgaXMgbmVjZXNzYXJ5IHRvIHJlbW92ZSB0aGUgZXZlbnQgaW4gdGhlIGVuZC5cblx0XHRcdCAqICBAdHlwZSB7RnVuY3Rpb259XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2JvdW5kTG9vcCA9IHRoaXMuX2xvb3AuYmluZCh0aGlzKTtcblx0ICAgICAgICAvL2JpbmQgYSBjYWxsYmFjayB0byB0aGUgd29ya2VyIHRocmVhZFxuXHQgICAgICAgIHRoaXMuY29udGV4dC5vbigndGljaycsIHRoaXMuX2JvdW5kTG9vcCk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5DbG9jaywgVG9uZS5FbWl0dGVyKTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgZGVmYXVsdHNcblx0XHQgKiAgQGNvbnN0XG5cdFx0ICogIEB0eXBlICB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5DbG9jay5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnY2FsbGJhY2snOiBUb25lLm5vT3AsXG5cdCAgICAgICAgJ2ZyZXF1ZW5jeSc6IDFcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiLCBcInN0b3BwZWRcIiBvciBcInBhdXNlZFwiLlxuXHRcdCAqICBAdHlwZSB7VG9uZS5TdGF0ZX1cblx0XHQgKiAgQHJlYWRPbmx5XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkNsb2NrI1xuXHRcdCAqICBAbmFtZSBzdGF0ZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQ2xvY2sucHJvdG90eXBlLCAnc3RhdGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aGlzLm5vdygpKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBTdGFydCB0aGUgY2xvY2sgYXQgdGhlIGdpdmVuIHRpbWUuIE9wdGlvbmFsbHkgcGFzcyBpbiBhbiBvZmZzZXRcblx0XHQgKiAgb2Ygd2hlcmUgdG8gc3RhcnQgdGhlIHRpY2sgY291bnRlciBmcm9tLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lPX0gIHRpbWUgICAgVGhlIHRpbWUgdGhlIGNsb2NrIHNob3VsZCBzdGFydFxuXHRcdCAqICBAcGFyYW0gIHtUaWNrcz19ICBvZmZzZXQgIFdoZXJlIHRoZSB0aWNrIGNvdW50ZXIgc3RhcnRzIGNvdW50aW5nIGZyb20uXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLkNsb2NrfSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5DbG9jay5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAodGltZSwgb2Zmc2V0KSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aW1lKSAhPT0gVG9uZS5TdGF0ZS5TdGFydGVkKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFRvbmUuU3RhdGUuU3RhcnRlZCwgdGltZSk7XG5cdCAgICAgICAgICAgIHRoaXMuX3RpY2tTb3VyY2Uuc3RhcnQodGltZSwgb2Zmc2V0KTtcblx0ICAgICAgICAgICAgaWYgKHRpbWUgPCB0aGlzLl9sYXN0VXBkYXRlKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ3N0YXJ0JywgdGltZSwgb2Zmc2V0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU3RvcCB0aGUgY2xvY2suIFN0b3BwaW5nIHRoZSBjbG9jayByZXNldHMgdGhlIHRpY2sgY291bnRlciB0byAwLlxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IFt0aW1lPW5vd10gVGhlIHRpbWUgd2hlbiB0aGUgY2xvY2sgc2hvdWxkIHN0b3AuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkNsb2NrfSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogY2xvY2suc3RvcCgpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5DbG9jay5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShUb25lLlN0YXRlLlN0b3BwZWQsIHRpbWUpO1xuXHQgICAgICAgIHRoaXMuX3RpY2tTb3VyY2Uuc3RvcCh0aW1lKTtcblx0ICAgICAgICBpZiAodGltZSA8IHRoaXMuX2xhc3RVcGRhdGUpIHtcblx0ICAgICAgICAgICAgdGhpcy5lbWl0KCdzdG9wJywgdGltZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBQYXVzZSB0aGUgY2xvY2suIFBhdXNpbmcgZG9lcyBub3QgcmVzZXQgdGhlIHRpY2sgY291bnRlci5cblx0XHQgKiAgQHBhcmFtIHtUaW1lfSBbdGltZT1ub3ddIFRoZSB0aW1lIHdoZW4gdGhlIGNsb2NrIHNob3VsZCBzdG9wLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5DbG9ja30gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5DbG9jay5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGltZSkgPT09IFRvbmUuU3RhdGUuU3RhcnRlZCkge1xuXHQgICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShUb25lLlN0YXRlLlBhdXNlZCwgdGltZSk7XG5cdCAgICAgICAgICAgIHRoaXMuX3RpY2tTb3VyY2UucGF1c2UodGltZSk7XG5cdCAgICAgICAgICAgIGlmICh0aW1lIDwgdGhpcy5fbGFzdFVwZGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdwYXVzZScsIHRpbWUpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgbnVtYmVyIG9mIHRpbWVzIHRoZSBjYWxsYmFjayB3YXMgaW52b2tlZC4gU3RhcnRzIGNvdW50aW5nIGF0IDBcblx0XHQgKiAgYW5kIGluY3JlbWVudHMgYWZ0ZXIgdGhlIGNhbGxiYWNrIHdhcyBpbnZva2VkLlxuXHRcdCAqICBAdHlwZSB7VGlja3N9XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5DbG9jay5wcm90b3R5cGUsICd0aWNrcycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIE1hdGguY2VpbCh0aGlzLmdldFRpY2tzQXRUaW1lKHRoaXMubm93KCkpKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHQpIHtcblx0ICAgICAgICAgICAgdGhpcy5fdGlja1NvdXJjZS50aWNrcyA9IHQ7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHRpbWUgc2luY2UgdGlja3M9MCB0aGF0IHRoZSBDbG9jayBoYXMgYmVlbiBydW5uaW5nLiBBY2NvdW50c1xuXHRcdCAqICBmb3IgdGVtcG8gY3VydmVzXG5cdFx0ICogIEB0eXBlIHtTZWNvbmRzfVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQ2xvY2sucHJvdG90eXBlLCAnc2Vjb25kcycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2Uuc2Vjb25kcztcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHMpIHtcblx0ICAgICAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5zZWNvbmRzID0gcztcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm4gdGhlIGVsYXBzZWQgc2Vjb25kcyBhdCB0aGUgZ2l2ZW4gdGltZS5cblx0XHQgKiAgQHBhcmFtICB7VGltZX0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSBlbGFwc2VkIHNlY29uZHNcblx0XHQgKiAgQHJldHVybiAge1NlY29uZHN9ICBUaGUgbnVtYmVyIG9mIGVsYXBzZWQgc2Vjb25kc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5DbG9jay5wcm90b3R5cGUuZ2V0U2Vjb25kc0F0VGltZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2UuZ2V0U2Vjb25kc0F0VGltZSh0aW1lKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBTZXQgdGhlIGNsb2NrJ3MgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogQHBhcmFtICB7VGlja3N9IHRpY2tzIFRoZSB0aWNrIHZhbHVlIHRvIHNldFxuXHRcdCAqIEBwYXJhbSAge1RpbWV9IHRpbWUgIFdoZW4gdG8gc2V0IHRoZSB0aWNrIHZhbHVlXG5cdFx0ICogQHJldHVybiB7VG9uZS5DbG9ja30gICAgICAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5DbG9jay5wcm90b3R5cGUuc2V0VGlja3NBdFRpbWUgPSBmdW5jdGlvbiAodGlja3MsIHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl90aWNrU291cmNlLnNldFRpY2tzQXRUaW1lKHRpY2tzLCB0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBHZXQgdGhlIGNsb2NrJ3MgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogQHBhcmFtICB7VGltZX0gdGltZSAgV2hlbiB0byBnZXQgdGhlIHRpY2sgdmFsdWVcblx0XHQgKiBAcmV0dXJuIHtUaWNrc30gICAgICAgVGhlIHRpY2sgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICovXG5cdCAgICBUb25lLkNsb2NrLnByb3RvdHlwZS5nZXRUaWNrc0F0VGltZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2UuZ2V0VGlja3NBdFRpbWUodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogR2V0IHRoZSB0aW1lIG9mIHRoZSBuZXh0IHRpY2tcblx0XHQgKiBAcGFyYW0gIHtUaWNrc30gdGlja3MgVGhlIHRpY2sgbnVtYmVyLlxuXHRcdCAqIEBwYXJhbSAge1RpbWV9IGJlZm9yZSBcblx0XHQgKiBAcmV0dXJuIHtUb25lLkNsb2NrfSAgICAgICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkNsb2NrLnByb3RvdHlwZS5uZXh0VGlja1RpbWUgPSBmdW5jdGlvbiAob2Zmc2V0LCB3aGVuKSB7XG5cdCAgICAgICAgd2hlbiA9IHRoaXMudG9TZWNvbmRzKHdoZW4pO1xuXHQgICAgICAgIHZhciBjdXJyZW50VGljayA9IHRoaXMuZ2V0VGlja3NBdFRpbWUod2hlbik7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2UuZ2V0VGltZU9mVGljayhjdXJyZW50VGljayArIG9mZnNldCwgd2hlbik7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBzY2hlZHVsaW5nIGxvb3AuXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkNsb2NrLnByb3RvdHlwZS5fbG9vcCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgc3RhcnRUaW1lID0gdGhpcy5fbGFzdFVwZGF0ZTtcblx0ICAgICAgICB2YXIgZW5kVGltZSA9IHRoaXMubm93KCk7XG5cdCAgICAgICAgdGhpcy5fbGFzdFVwZGF0ZSA9IGVuZFRpbWU7XG5cdCAgICAgICAgaWYgKHN0YXJ0VGltZSAhPT0gZW5kVGltZSkge1xuXHQgICAgICAgICAgICAvL3RoZSBzdGF0ZSBjaGFuZ2UgZXZlbnRzXG5cdCAgICAgICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgZnVuY3Rpb24gKGUpIHtcblx0ICAgICAgICAgICAgICAgIHN3aXRjaCAoZS5zdGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgY2FzZSBUb25lLlN0YXRlLlN0YXJ0ZWQ6XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIG9mZnNldCA9IHRoaXMuX3RpY2tTb3VyY2UuZ2V0VGlja3NBdFRpbWUoZS50aW1lKTtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ3N0YXJ0JywgZS50aW1lLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXHQgICAgICAgICAgICAgICAgY2FzZSBUb25lLlN0YXRlLlN0b3BwZWQ6XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKGUudGltZSAhPT0gMCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ3N0b3AnLCBlLnRpbWUpO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIGNhc2UgVG9uZS5TdGF0ZS5QYXVzZWQ6XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdwYXVzZScsIGUudGltZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0uYmluZCh0aGlzKSk7XG5cdCAgICAgICAgICAgIC8vdGhlIHRpY2sgY2FsbGJhY2tzXG5cdCAgICAgICAgICAgIHRoaXMuX3RpY2tTb3VyY2UuZm9yRWFjaFRpY2tCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgZnVuY3Rpb24gKHRpbWUsIHRpY2tzKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUsIHRpY2tzKTtcblx0ICAgICAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybnMgdGhlIHNjaGVkdWxlZCBzdGF0ZSBhdCB0aGUgZ2l2ZW4gdGltZS5cblx0XHQgKiAgQHBhcmFtICB7VGltZX0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuXHRcdCAqICBAcmV0dXJuICB7U3RyaW5nfSAgVGhlIG5hbWUgb2YgdGhlIHN0YXRlIGlucHV0IGluIHNldFN0YXRlQXRUaW1lLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIGNsb2NrLnN0YXJ0KFwiKzAuMVwiKTtcblx0XHQgKiBjbG9jay5nZXRTdGF0ZUF0VGltZShcIiswLjFcIik7IC8vcmV0dXJucyBcInN0YXJ0ZWRcIlxuXHRcdCAqL1xuXHQgICAgVG9uZS5DbG9jay5wcm90b3R5cGUuZ2V0U3RhdGVBdFRpbWUgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkNsb2NrfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkNsb2NrLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuRW1pdHRlci5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuY29udGV4dC5vZmYoJ3RpY2snLCB0aGlzLl9ib3VuZExvb3ApO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKCdmcmVxdWVuY3knKTtcblx0ICAgICAgICB0aGlzLl90aWNrU291cmNlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl90aWNrU291cmNlID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fYm91bmRMb29wID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9uZXh0VGljayA9IEluZmluaXR5O1xuXHQgICAgICAgIHRoaXMuY2FsbGJhY2sgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3N0YXRlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuQ2xvY2s7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBTaW1pbGFyIHRvIFRvbmUuVGltZWxpbmUsIGJ1dCBhbGwgZXZlbnRzIHJlcHJlc2VudFxuXHRcdCAqICAgICAgICAgaW50ZXJ2YWxzIHdpdGggYm90aCBcInRpbWVcIiBhbmQgXCJkdXJhdGlvblwiIHRpbWVzLiBUaGVcblx0XHQgKiAgICAgICAgIGV2ZW50cyBhcmUgcGxhY2VkIGluIGEgdHJlZSBzdHJ1Y3R1cmUgb3B0aW1pemVkXG5cdFx0ICogICAgICAgICBmb3IgcXVlcnlpbmcgYW4gaW50ZXJzZWN0aW9uIHBvaW50IHdpdGggdGhlIHRpbWVsaW5lXG5cdFx0ICogICAgICAgICBldmVudHMuIEludGVybmFsbHkgdXNlcyBhbiBbSW50ZXJ2YWwgVHJlZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSW50ZXJ2YWxfdHJlZSlcblx0XHQgKiAgICAgICAgIHRvIHJlcHJlc2VudCB0aGUgZGF0YS5cblx0XHQgKiAgQGV4dGVuZHMge1RvbmV9XG5cdFx0ICovXG5cdCAgICBUb25lLkludGVydmFsVGltZWxpbmUgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSByb290IG5vZGUgb2YgdGhlIGludGV2YWwgdHJlZVxuXHRcdFx0ICogIEB0eXBlICB7SW50ZXJ2YWxOb2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9yb290ID0gbnVsbDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBLZWVwIHRyYWNrIG9mIHRoZSBsZW5ndGggb2YgdGhlIHRpbWVsaW5lLlxuXHRcdFx0ICogIEB0eXBlICB7TnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9sZW5ndGggPSAwO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuSW50ZXJ2YWxUaW1lbGluZSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGV2ZW50IHRvIGFkZCB0byB0aGUgdGltZWxpbmUuIEFsbCBldmVudHMgbXVzdFxuXHRcdCAqICBoYXZlIGEgdGltZSBhbmQgZHVyYXRpb24gdmFsdWVcblx0XHQgKiAgQHBhcmFtICB7T2JqZWN0fSAgZXZlbnQgIFRoZSBldmVudCB0byBhZGQgdG8gdGhlIHRpbWVsaW5lXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLkludGVydmFsVGltZWxpbmV9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkludGVydmFsVGltZWxpbmUucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgIGlmIChUb25lLmlzVW5kZWYoZXZlbnQudGltZSkgfHwgVG9uZS5pc1VuZGVmKGV2ZW50LmR1cmF0aW9uKSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RvbmUuSW50ZXJ2YWxUaW1lbGluZTogZXZlbnRzIG11c3QgaGF2ZSB0aW1lIGFuZCBkdXJhdGlvbiBwYXJhbWV0ZXJzJyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGV2ZW50LnRpbWUgPSBldmVudC50aW1lLnZhbHVlT2YoKTtcblx0ICAgICAgICB2YXIgbm9kZSA9IG5ldyBJbnRlcnZhbE5vZGUoZXZlbnQudGltZSwgZXZlbnQudGltZSArIGV2ZW50LmR1cmF0aW9uLCBldmVudCk7XG5cdCAgICAgICAgaWYgKHRoaXMuX3Jvb3QgPT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdGhpcy5fcm9vdCA9IG5vZGU7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGhpcy5fcm9vdC5pbnNlcnQobm9kZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuX2xlbmd0aCsrO1xuXHQgICAgICAgIC8vIFJlc3RydWN0dXJlIHRyZWUgdG8gYmUgYmFsYW5jZWRcblx0ICAgICAgICB3aGlsZSAobm9kZSAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICBub2RlLnVwZGF0ZUhlaWdodCgpO1xuXHQgICAgICAgICAgICBub2RlLnVwZGF0ZU1heCgpO1xuXHQgICAgICAgICAgICB0aGlzLl9yZWJhbGFuY2Uobm9kZSk7XG5cdCAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJlbW92ZSBhbiBldmVudCBmcm9tIHRoZSB0aW1lbGluZS5cblx0XHQgKiAgQHBhcmFtICB7T2JqZWN0fSAgZXZlbnQgIFRoZSBldmVudCB0byByZW1vdmUgZnJvbSB0aGUgdGltZWxpbmVcblx0XHQgKiAgQHJldHVybiAge1RvbmUuSW50ZXJ2YWxUaW1lbGluZX0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuSW50ZXJ2YWxUaW1lbGluZS5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKGV2ZW50KSB7XG5cdCAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdmFyIHJlc3VsdHMgPSBbXTtcblx0ICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2goZXZlbnQudGltZSwgcmVzdWx0cyk7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzdWx0cy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSByZXN1bHRzW2ldO1xuXHQgICAgICAgICAgICAgICAgaWYgKG5vZGUuZXZlbnQgPT09IGV2ZW50KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlTm9kZShub2RlKTtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl9sZW5ndGgtLTtcblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIG51bWJlciBvZiBpdGVtcyBpbiB0aGUgdGltZWxpbmUuXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkludGVydmFsVGltZWxpbmUjXG5cdFx0ICogIEBuYW1lIGxlbmd0aFxuXHRcdCAqICBAcmVhZE9ubHlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkludGVydmFsVGltZWxpbmUucHJvdG90eXBlLCAnbGVuZ3RoJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fbGVuZ3RoO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFJlbW92ZSBldmVudHMgd2hvc2UgdGltZSB0aW1lIGlzIGFmdGVyIHRoZSBnaXZlbiB0aW1lXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5JbnRlcnZhbFRpbWVsaW5lfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkludGVydmFsVGltZWxpbmUucHJvdG90eXBlLmNhbmNlbCA9IGZ1bmN0aW9uIChhZnRlcikge1xuXHQgICAgICAgIHRoaXMuZm9yRWFjaEZyb20oYWZ0ZXIsIGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgICAgICB0aGlzLnJlbW92ZShldmVudCk7XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU2V0IHRoZSByb290IG5vZGUgYXMgdGhlIGdpdmVuIG5vZGVcblx0XHQgKiAgQHBhcmFtIHtJbnRlcnZhbE5vZGV9IG5vZGVcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuSW50ZXJ2YWxUaW1lbGluZS5wcm90b3R5cGUuX3NldFJvb3QgPSBmdW5jdGlvbiAobm9kZSkge1xuXHQgICAgICAgIHRoaXMuX3Jvb3QgPSBub2RlO1xuXHQgICAgICAgIGlmICh0aGlzLl9yb290ICE9PSBudWxsKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3Jvb3QucGFyZW50ID0gbnVsbDtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJlcGxhY2UgdGhlIHJlZmVyZW5jZXMgdG8gdGhlIG5vZGUgaW4gdGhlIG5vZGUncyBwYXJlbnRcblx0XHQgKiAgd2l0aCB0aGUgcmVwbGFjZW1lbnQgbm9kZS5cblx0XHQgKiAgQHBhcmFtICB7SW50ZXJ2YWxOb2RlfSAgbm9kZVxuXHRcdCAqICBAcGFyYW0gIHtJbnRlcnZhbE5vZGV9ICByZXBsYWNlbWVudFxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5JbnRlcnZhbFRpbWVsaW5lLnByb3RvdHlwZS5fcmVwbGFjZU5vZGVJblBhcmVudCA9IGZ1bmN0aW9uIChub2RlLCByZXBsYWNlbWVudCkge1xuXHQgICAgICAgIGlmIChub2RlLnBhcmVudCAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICBpZiAobm9kZS5pc0xlZnRDaGlsZCgpKSB7XG5cdCAgICAgICAgICAgICAgICBub2RlLnBhcmVudC5sZWZ0ID0gcmVwbGFjZW1lbnQ7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBub2RlLnBhcmVudC5yaWdodCA9IHJlcGxhY2VtZW50O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuX3JlYmFsYW5jZShub2RlLnBhcmVudCk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGhpcy5fc2V0Um9vdChyZXBsYWNlbWVudCk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZW1vdmUgdGhlIG5vZGUgZnJvbSB0aGUgdHJlZSBhbmQgcmVwbGFjZSBpdCB3aXRoXG5cdFx0ICogIGEgc3VjY2Vzc29yIHdoaWNoIGZvbGxvd3MgdGhlIHNjaGVtYS5cblx0XHQgKiAgQHBhcmFtICB7SW50ZXJ2YWxOb2RlfSAgbm9kZVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5JbnRlcnZhbFRpbWVsaW5lLnByb3RvdHlwZS5fcmVtb3ZlTm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7XG5cdCAgICAgICAgaWYgKG5vZGUubGVmdCA9PT0gbnVsbCAmJiBub2RlLnJpZ2h0ID09PSBudWxsKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3JlcGxhY2VOb2RlSW5QYXJlbnQobm9kZSwgbnVsbCk7XG5cdCAgICAgICAgfSBlbHNlIGlmIChub2RlLnJpZ2h0ID09PSBudWxsKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3JlcGxhY2VOb2RlSW5QYXJlbnQobm9kZSwgbm9kZS5sZWZ0KTtcblx0ICAgICAgICB9IGVsc2UgaWYgKG5vZGUubGVmdCA9PT0gbnVsbCkge1xuXHQgICAgICAgICAgICB0aGlzLl9yZXBsYWNlTm9kZUluUGFyZW50KG5vZGUsIG5vZGUucmlnaHQpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHZhciBiYWxhbmNlID0gbm9kZS5nZXRCYWxhbmNlKCk7XG5cdCAgICAgICAgICAgIHZhciByZXBsYWNlbWVudCwgdGVtcDtcblx0ICAgICAgICAgICAgaWYgKGJhbGFuY2UgPiAwKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAobm9kZS5sZWZ0LnJpZ2h0ID09PSBudWxsKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSBub2RlLmxlZnQ7XG5cdCAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucmlnaHQgPSBub2RlLnJpZ2h0O1xuXHQgICAgICAgICAgICAgICAgICAgIHRlbXAgPSByZXBsYWNlbWVudDtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSBub2RlLmxlZnQucmlnaHQ7XG5cdCAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJlcGxhY2VtZW50LnJpZ2h0ICE9PSBudWxsKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gcmVwbGFjZW1lbnQucmlnaHQ7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LnBhcmVudC5yaWdodCA9IHJlcGxhY2VtZW50LmxlZnQ7XG5cdCAgICAgICAgICAgICAgICAgICAgdGVtcCA9IHJlcGxhY2VtZW50LnBhcmVudDtcblx0ICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5sZWZ0ID0gbm9kZS5sZWZ0O1xuXHQgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LnJpZ2h0ID0gbm9kZS5yaWdodDtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSBlbHNlIGlmIChub2RlLnJpZ2h0LmxlZnQgPT09IG51bGwpIHtcblx0ICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gbm9kZS5yaWdodDtcblx0ICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LmxlZnQgPSBub2RlLmxlZnQ7XG5cdCAgICAgICAgICAgICAgICB0ZW1wID0gcmVwbGFjZW1lbnQ7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IG5vZGUucmlnaHQubGVmdDtcblx0ICAgICAgICAgICAgICAgIHdoaWxlIChyZXBsYWNlbWVudC5sZWZ0ICE9PSBudWxsKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSByZXBsYWNlbWVudC5sZWZ0O1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucGFyZW50ID0gcmVwbGFjZW1lbnQucGFyZW50O1xuXHQgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucGFyZW50LmxlZnQgPSByZXBsYWNlbWVudC5yaWdodDtcblx0ICAgICAgICAgICAgICAgIHRlbXAgPSByZXBsYWNlbWVudC5wYXJlbnQ7XG5cdCAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5sZWZ0ID0gbm9kZS5sZWZ0O1xuXHQgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucmlnaHQgPSBub2RlLnJpZ2h0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChub2RlLnBhcmVudCAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICAgICAgaWYgKG5vZGUuaXNMZWZ0Q2hpbGQoKSkge1xuXHQgICAgICAgICAgICAgICAgICAgIG5vZGUucGFyZW50LmxlZnQgPSByZXBsYWNlbWVudDtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQucmlnaHQgPSByZXBsYWNlbWVudDtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocmVwbGFjZW1lbnQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIC8vIHRoaXMuX3JlcGxhY2VOb2RlSW5QYXJlbnQobm9kZSwgcmVwbGFjZW1lbnQpO1xuXHQgICAgICAgICAgICB0aGlzLl9yZWJhbGFuY2UodGVtcCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIG5vZGUuZGlzcG9zZSgpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSb3RhdGUgdGhlIHRyZWUgdG8gdGhlIGxlZnRcblx0XHQgKiAgQHBhcmFtICB7SW50ZXJ2YWxOb2RlfSAgbm9kZVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5JbnRlcnZhbFRpbWVsaW5lLnByb3RvdHlwZS5fcm90YXRlTGVmdCA9IGZ1bmN0aW9uIChub2RlKSB7XG5cdCAgICAgICAgdmFyIHBhcmVudCA9IG5vZGUucGFyZW50O1xuXHQgICAgICAgIHZhciBpc0xlZnRDaGlsZCA9IG5vZGUuaXNMZWZ0Q2hpbGQoKTtcblx0ICAgICAgICAvLyBNYWtlIG5vZGUucmlnaHQgdGhlIG5ldyByb290IG9mIHRoaXMgc3ViIHRyZWUgKGluc3RlYWQgb2Ygbm9kZSlcblx0ICAgICAgICB2YXIgcGl2b3ROb2RlID0gbm9kZS5yaWdodDtcblx0ICAgICAgICBub2RlLnJpZ2h0ID0gcGl2b3ROb2RlLmxlZnQ7XG5cdCAgICAgICAgcGl2b3ROb2RlLmxlZnQgPSBub2RlO1xuXHQgICAgICAgIGlmIChwYXJlbnQgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgaWYgKGlzTGVmdENoaWxkKSB7XG5cdCAgICAgICAgICAgICAgICBwYXJlbnQubGVmdCA9IHBpdm90Tm9kZTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHBhcmVudC5yaWdodCA9IHBpdm90Tm9kZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocGl2b3ROb2RlKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJvdGF0ZSB0aGUgdHJlZSB0byB0aGUgcmlnaHRcblx0XHQgKiAgQHBhcmFtICB7SW50ZXJ2YWxOb2RlfSAgbm9kZVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5JbnRlcnZhbFRpbWVsaW5lLnByb3RvdHlwZS5fcm90YXRlUmlnaHQgPSBmdW5jdGlvbiAobm9kZSkge1xuXHQgICAgICAgIHZhciBwYXJlbnQgPSBub2RlLnBhcmVudDtcblx0ICAgICAgICB2YXIgaXNMZWZ0Q2hpbGQgPSBub2RlLmlzTGVmdENoaWxkKCk7XG5cdCAgICAgICAgLy8gTWFrZSBub2RlLmxlZnQgdGhlIG5ldyByb290IG9mIHRoaXMgc3ViIHRyZWUgKGluc3RlYWQgb2Ygbm9kZSlcblx0ICAgICAgICB2YXIgcGl2b3ROb2RlID0gbm9kZS5sZWZ0O1xuXHQgICAgICAgIG5vZGUubGVmdCA9IHBpdm90Tm9kZS5yaWdodDtcblx0ICAgICAgICBwaXZvdE5vZGUucmlnaHQgPSBub2RlO1xuXHQgICAgICAgIGlmIChwYXJlbnQgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgaWYgKGlzTGVmdENoaWxkKSB7XG5cdCAgICAgICAgICAgICAgICBwYXJlbnQubGVmdCA9IHBpdm90Tm9kZTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHBhcmVudC5yaWdodCA9IHBpdm90Tm9kZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocGl2b3ROb2RlKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEJhbGFuY2UgdGhlIEJTVFxuXHRcdCAqICBAcGFyYW0gIHtJbnRlcnZhbE5vZGV9ICBub2RlXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkludGVydmFsVGltZWxpbmUucHJvdG90eXBlLl9yZWJhbGFuY2UgPSBmdW5jdGlvbiAobm9kZSkge1xuXHQgICAgICAgIHZhciBiYWxhbmNlID0gbm9kZS5nZXRCYWxhbmNlKCk7XG5cdCAgICAgICAgaWYgKGJhbGFuY2UgPiAxKSB7XG5cdCAgICAgICAgICAgIGlmIChub2RlLmxlZnQuZ2V0QmFsYW5jZSgpIDwgMCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fcm90YXRlTGVmdChub2RlLmxlZnQpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fcm90YXRlUmlnaHQobm9kZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2UgaWYgKGJhbGFuY2UgPCAtMSkge1xuXHQgICAgICAgICAgICBpZiAobm9kZS5yaWdodC5nZXRCYWxhbmNlKCkgPiAwKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9yb3RhdGVSaWdodChub2RlLnJpZ2h0KTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3JvdGF0ZUxlZnQobm9kZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEdldCBhbiBldmVudCB3aG9zZSB0aW1lIGFuZCBkdXJhdGlvbiBzcGFuIHRoZSBnaXZlIHRpbWUuIFdpbGxcblx0XHQgKiAgcmV0dXJuIHRoZSBtYXRjaCB3aG9zZSBcInRpbWVcIiB2YWx1ZSBpcyBjbG9zZXN0IHRvIHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqICBAcGFyYW0gIHtPYmplY3R9ICBldmVudCAgVGhlIGV2ZW50IHRvIGFkZCB0byB0aGUgdGltZWxpbmVcblx0XHQgKiAgQHJldHVybiAge09iamVjdH0gIFRoZSBldmVudCB3aGljaCBzcGFucyB0aGUgZGVzaXJlZCB0aW1lXG5cdFx0ICovXG5cdCAgICBUb25lLkludGVydmFsVGltZWxpbmUucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdmFyIHJlc3VsdHMgPSBbXTtcblx0ICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2godGltZSwgcmVzdWx0cyk7XG5cdCAgICAgICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcblx0ICAgICAgICAgICAgICAgIHZhciBtYXggPSByZXN1bHRzWzBdO1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCByZXN1bHRzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdHNbaV0ubG93ID4gbWF4Lmxvdykge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBtYXggPSByZXN1bHRzW2ldO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHJldHVybiBtYXguZXZlbnQ7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIG51bGw7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSB0aW1lbGluZS5cblx0XHQgKiAgQHBhcmFtICB7RnVuY3Rpb259ICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5JbnRlcnZhbFRpbWVsaW5lfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkludGVydmFsVGltZWxpbmUucHJvdG90eXBlLmZvckVhY2ggPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcblx0ICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICB2YXIgYWxsTm9kZXMgPSBbXTtcblx0ICAgICAgICAgICAgdGhpcy5fcm9vdC50cmF2ZXJzZShmdW5jdGlvbiAobm9kZSkge1xuXHQgICAgICAgICAgICAgICAgYWxsTm9kZXMucHVzaChub2RlKTtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYWxsTm9kZXMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHZhciBldiA9IGFsbE5vZGVzW2ldLmV2ZW50O1xuXHQgICAgICAgICAgICAgICAgaWYgKGV2KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZXYpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgaW4gd2hpY2ggdGhlIGdpdmVuIHRpbWVcblx0XHQgKiAgb3ZlcmxhcHMgd2l0aCB0aGUgdGltZSBhbmQgZHVyYXRpb24gdGltZSBvZiB0aGUgZXZlbnQuXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIG92ZXJsYXBwaW5nXG5cdFx0ICogIEBwYXJhbSAge0Z1bmN0aW9ufSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cblx0XHQgKiAgQHJldHVybnMge1RvbmUuSW50ZXJ2YWxUaW1lbGluZX0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5JbnRlcnZhbFRpbWVsaW5lLnByb3RvdHlwZS5mb3JFYWNoQXRUaW1lID0gZnVuY3Rpb24gKHRpbWUsIGNhbGxiYWNrKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdmFyIHJlc3VsdHMgPSBbXTtcblx0ICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2godGltZSwgcmVzdWx0cyk7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSByZXN1bHRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgZXYgPSByZXN1bHRzW2ldLmV2ZW50O1xuXHQgICAgICAgICAgICAgICAgaWYgKGV2KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZXYpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgaW4gd2hpY2ggdGhlIHRpbWUgaXMgZ3JlYXRlclxuXHRcdCAqICB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICB0aW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcblx0XHQgKiAgQHBhcmFtICB7RnVuY3Rpb259ICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5JbnRlcnZhbFRpbWVsaW5lfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkludGVydmFsVGltZWxpbmUucHJvdG90eXBlLmZvckVhY2hGcm9tID0gZnVuY3Rpb24gKHRpbWUsIGNhbGxiYWNrKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdmFyIHJlc3VsdHMgPSBbXTtcblx0ICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2hBZnRlcih0aW1lLCByZXN1bHRzKTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IHJlc3VsdHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcblx0ICAgICAgICAgICAgICAgIHZhciBldiA9IHJlc3VsdHNbaV0uZXZlbnQ7XG5cdCAgICAgICAgICAgICAgICBjYWxsYmFjayhldik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLkludGVydmFsVGltZWxpbmV9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkludGVydmFsVGltZWxpbmUucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIGFsbE5vZGVzID0gW107XG5cdCAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdGhpcy5fcm9vdC50cmF2ZXJzZShmdW5jdGlvbiAobm9kZSkge1xuXHQgICAgICAgICAgICAgICAgYWxsTm9kZXMucHVzaChub2RlKTtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYWxsTm9kZXMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgYWxsTm9kZXNbaV0uZGlzcG9zZSgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBhbGxOb2RlcyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fcm9vdCA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvL1x0SU5URVJWQUwgTk9ERSBIRUxQRVJcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLyoqXG5cdFx0ICogIFJlcHJlc2VudHMgYSBub2RlIGluIHRoZSBiaW5hcnkgc2VhcmNoIHRyZWUsIHdpdGggdGhlIGFkZGl0aW9uXG5cdFx0ICogIG9mIGEgXCJoaWdoXCIgdmFsdWUgd2hpY2gga2VlcHMgdHJhY2sgb2YgdGhlIGhpZ2hlc3QgdmFsdWUgb2Zcblx0XHQgKiAgaXRzIGNoaWxkcmVuLlxuXHRcdCAqICBSZWZlcmVuY2VzOlxuXHRcdCAqICBodHRwczovL2Jyb29rbm92YWsud29yZHByZXNzLmNvbS8yMDEzLzEyLzA3L2F1Z21lbnRlZC1pbnRlcnZhbC10cmVlLWluLWMvXG5cdFx0ICogIGh0dHA6Ly93d3cubWlmLnZ1Lmx0L352YWxkYXMvQUxHT1JJVE1BSS9MSVRFUkFUVVJBL0Nvcm1lbi9Db3JtZW4ucGRmXG5cdFx0ICogIEBwYXJhbSB7TnVtYmVyfSBsb3dcblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ9IGhpZ2hcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIHZhciBJbnRlcnZhbE5vZGUgPSBmdW5jdGlvbiAobG93LCBoaWdoLCBldmVudCkge1xuXHQgICAgICAgIC8vdGhlIGV2ZW50IGNvbnRhaW5lclxuXHQgICAgICAgIHRoaXMuZXZlbnQgPSBldmVudDtcblx0ICAgICAgICAvL3RoZSBsb3cgdmFsdWVcblx0ICAgICAgICB0aGlzLmxvdyA9IGxvdztcblx0ICAgICAgICAvL3RoZSBoaWdoIHZhbHVlXG5cdCAgICAgICAgdGhpcy5oaWdoID0gaGlnaDtcblx0ICAgICAgICAvL3RoZSBoaWdoIHZhbHVlIGZvciB0aGlzIGFuZCBhbGwgY2hpbGQgbm9kZXNcblx0ICAgICAgICB0aGlzLm1heCA9IHRoaXMuaGlnaDtcblx0ICAgICAgICAvL3RoZSBub2RlcyB0byB0aGUgbGVmdFxuXHQgICAgICAgIHRoaXMuX2xlZnQgPSBudWxsO1xuXHQgICAgICAgIC8vdGhlIG5vZGVzIHRvIHRoZSByaWdodFxuXHQgICAgICAgIHRoaXMuX3JpZ2h0ID0gbnVsbDtcblx0ICAgICAgICAvL3RoZSBwYXJlbnQgbm9kZVxuXHQgICAgICAgIHRoaXMucGFyZW50ID0gbnVsbDtcblx0ICAgICAgICAvL3RoZSBudW1iZXIgb2YgY2hpbGQgbm9kZXNcblx0ICAgICAgICB0aGlzLmhlaWdodCA9IDA7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEluc2VydCBhIG5vZGUgaW50byB0aGUgY29ycmVjdCBzcG90IGluIHRoZSB0cmVlXG5cdFx0ICogIEBwYXJhbSAge0ludGVydmFsTm9kZX0gIG5vZGVcblx0XHQgKi9cblx0ICAgIEludGVydmFsTm9kZS5wcm90b3R5cGUuaW5zZXJ0ID0gZnVuY3Rpb24gKG5vZGUpIHtcblx0ICAgICAgICBpZiAobm9kZS5sb3cgPD0gdGhpcy5sb3cpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMubGVmdCA9PT0gbnVsbCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5sZWZ0ID0gbm9kZTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMubGVmdC5pbnNlcnQobm9kZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2UgaWYgKHRoaXMucmlnaHQgPT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdGhpcy5yaWdodCA9IG5vZGU7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGhpcy5yaWdodC5pbnNlcnQobm9kZSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTZWFyY2ggdGhlIHRyZWUgZm9yIG5vZGVzIHdoaWNoIG92ZXJsYXBcblx0XHQgKiAgd2l0aCB0aGUgZ2l2ZW4gcG9pbnRcblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgcG9pbnQgIFRoZSBwb2ludCB0byBxdWVyeVxuXHRcdCAqICBAcGFyYW0gIHtBcnJheX0gIHJlc3VsdHMgIFRoZSBhcnJheSB0byBwdXQgdGhlIHJlc3VsdHNcblx0XHQgKi9cblx0ICAgIEludGVydmFsTm9kZS5wcm90b3R5cGUuc2VhcmNoID0gZnVuY3Rpb24gKHBvaW50LCByZXN1bHRzKSB7XG5cdCAgICAgICAgLy8gSWYgcCBpcyB0byB0aGUgcmlnaHQgb2YgdGhlIHJpZ2h0bW9zdCBwb2ludCBvZiBhbnkgaW50ZXJ2YWxcblx0ICAgICAgICAvLyBpbiB0aGlzIG5vZGUgYW5kIGFsbCBjaGlsZHJlbiwgdGhlcmUgd29uJ3QgYmUgYW55IG1hdGNoZXMuXG5cdCAgICAgICAgaWYgKHBvaW50ID4gdGhpcy5tYXgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvLyBTZWFyY2ggbGVmdCBjaGlsZHJlblxuXHQgICAgICAgIGlmICh0aGlzLmxlZnQgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdGhpcy5sZWZ0LnNlYXJjaChwb2ludCwgcmVzdWx0cyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vIENoZWNrIHRoaXMgbm9kZVxuXHQgICAgICAgIGlmICh0aGlzLmxvdyA8PSBwb2ludCAmJiB0aGlzLmhpZ2ggPiBwb2ludCkge1xuXHQgICAgICAgICAgICByZXN1bHRzLnB1c2godGhpcyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vIElmIHAgaXMgdG8gdGhlIGxlZnQgb2YgdGhlIHRpbWUgb2YgdGhpcyBpbnRlcnZhbCxcblx0ICAgICAgICAvLyB0aGVuIGl0IGNhbid0IGJlIGluIGFueSBjaGlsZCB0byB0aGUgcmlnaHQuXG5cdCAgICAgICAgaWYgKHRoaXMubG93ID4gcG9pbnQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvLyBTZWFyY2ggcmlnaHQgY2hpbGRyZW5cblx0ICAgICAgICBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICB0aGlzLnJpZ2h0LnNlYXJjaChwb2ludCwgcmVzdWx0cyk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTZWFyY2ggdGhlIHRyZWUgZm9yIG5vZGVzIHdoaWNoIGFyZSBsZXNzXG5cdFx0ICogIHRoYW4gdGhlIGdpdmVuIHBvaW50XG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHBvaW50ICBUaGUgcG9pbnQgdG8gcXVlcnlcblx0XHQgKiAgQHBhcmFtICB7QXJyYXl9ICByZXN1bHRzICBUaGUgYXJyYXkgdG8gcHV0IHRoZSByZXN1bHRzXG5cdFx0ICovXG5cdCAgICBJbnRlcnZhbE5vZGUucHJvdG90eXBlLnNlYXJjaEFmdGVyID0gZnVuY3Rpb24gKHBvaW50LCByZXN1bHRzKSB7XG5cdCAgICAgICAgLy8gQ2hlY2sgdGhpcyBub2RlXG5cdCAgICAgICAgaWYgKHRoaXMubG93ID49IHBvaW50KSB7XG5cdCAgICAgICAgICAgIHJlc3VsdHMucHVzaCh0aGlzKTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5sZWZ0LnNlYXJjaEFmdGVyKHBvaW50LCByZXN1bHRzKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICAvLyBzZWFyY2ggdGhlIHJpZ2h0IHNpZGVcblx0ICAgICAgICBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICB0aGlzLnJpZ2h0LnNlYXJjaEFmdGVyKHBvaW50LCByZXN1bHRzKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEludm9rZSB0aGUgY2FsbGJhY2sgb24gdGhpcyBlbGVtZW50IGFuZCBib3RoIGl0J3MgYnJhbmNoZXNcblx0XHQgKiAgQHBhcmFtICB7RnVuY3Rpb259ICBjYWxsYmFja1xuXHRcdCAqL1xuXHQgICAgSW50ZXJ2YWxOb2RlLnByb3RvdHlwZS50cmF2ZXJzZSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuXHQgICAgICAgIGNhbGxiYWNrKHRoaXMpO1xuXHQgICAgICAgIGlmICh0aGlzLmxlZnQgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdGhpcy5sZWZ0LnRyYXZlcnNlKGNhbGxiYWNrKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdGhpcy5yaWdodC50cmF2ZXJzZShjYWxsYmFjayk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBVcGRhdGUgdGhlIGhlaWdodCBvZiB0aGUgbm9kZVxuXHRcdCAqL1xuXHQgICAgSW50ZXJ2YWxOb2RlLnByb3RvdHlwZS51cGRhdGVIZWlnaHQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCAmJiB0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG5cdCAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gTWF0aC5tYXgodGhpcy5sZWZ0LmhlaWdodCwgdGhpcy5yaWdodC5oZWlnaHQpICsgMTtcblx0ICAgICAgICB9IGVsc2UgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLnJpZ2h0LmhlaWdodCArIDE7XG5cdCAgICAgICAgfSBlbHNlIGlmICh0aGlzLmxlZnQgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLmxlZnQuaGVpZ2h0ICsgMTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0aGlzLmhlaWdodCA9IDA7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBVcGRhdGUgdGhlIGhlaWdodCBvZiB0aGUgbm9kZVxuXHRcdCAqL1xuXHQgICAgSW50ZXJ2YWxOb2RlLnByb3RvdHlwZS51cGRhdGVNYXggPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5tYXggPSB0aGlzLmhpZ2g7XG5cdCAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICB0aGlzLm1heCA9IE1hdGgubWF4KHRoaXMubWF4LCB0aGlzLmxlZnQubWF4KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdGhpcy5tYXggPSBNYXRoLm1heCh0aGlzLm1heCwgdGhpcy5yaWdodC5tYXgpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGJhbGFuY2UgaXMgaG93IHRoZSBsZWFmcyBhcmUgZGlzdHJpYnV0ZWQgb24gdGhlIG5vZGVcblx0XHQgKiAgQHJldHVybiAge051bWJlcn0gIE5lZ2F0aXZlIG51bWJlcnMgYXJlIGJhbGFuY2VkIHRvIHRoZSByaWdodFxuXHRcdCAqL1xuXHQgICAgSW50ZXJ2YWxOb2RlLnByb3RvdHlwZS5nZXRCYWxhbmNlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBiYWxhbmNlID0gMDtcblx0ICAgICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsICYmIHRoaXMucmlnaHQgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgYmFsYW5jZSA9IHRoaXMubGVmdC5oZWlnaHQgLSB0aGlzLnJpZ2h0LmhlaWdodDtcblx0ICAgICAgICB9IGVsc2UgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICBiYWxhbmNlID0gdGhpcy5sZWZ0LmhlaWdodCArIDE7XG5cdCAgICAgICAgfSBlbHNlIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG5cdCAgICAgICAgICAgIGJhbGFuY2UgPSAtKHRoaXMucmlnaHQuaGVpZ2h0ICsgMSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBiYWxhbmNlO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBAcmV0dXJucyB7Qm9vbGVhbn0gdHJ1ZSBpZiB0aGlzIG5vZGUgaXMgdGhlIGxlZnQgY2hpbGRcblx0XHQgKiAgb2YgaXRzIHBhcmVudFxuXHRcdCAqL1xuXHQgICAgSW50ZXJ2YWxOb2RlLnByb3RvdHlwZS5pc0xlZnRDaGlsZCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQgIT09IG51bGwgJiYgdGhpcy5wYXJlbnQubGVmdCA9PT0gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgZ2V0L3NldCB0aGUgbGVmdCBub2RlXG5cdFx0ICogIEB0eXBlIHtJbnRlcnZhbE5vZGV9XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoSW50ZXJ2YWxOb2RlLnByb3RvdHlwZSwgJ2xlZnQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9sZWZ0O1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobm9kZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9sZWZ0ID0gbm9kZTtcblx0ICAgICAgICAgICAgaWYgKG5vZGUgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgICAgIG5vZGUucGFyZW50ID0gdGhpcztcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xuXHQgICAgICAgICAgICB0aGlzLnVwZGF0ZU1heCgpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIGdldC9zZXQgdGhlIHJpZ2h0IG5vZGVcblx0XHQgKiAgQHR5cGUge0ludGVydmFsTm9kZX1cblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnRlcnZhbE5vZGUucHJvdG90eXBlLCAncmlnaHQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9yaWdodDtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKG5vZGUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fcmlnaHQgPSBub2RlO1xuXHQgICAgICAgICAgICBpZiAobm9kZSAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQgPSB0aGlzO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XG5cdCAgICAgICAgICAgIHRoaXMudXBkYXRlTWF4KCk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgbnVsbCBvdXQgcmVmZXJlbmNlcy5cblx0XHQgKi9cblx0ICAgIEludGVydmFsTm9kZS5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB0aGlzLnBhcmVudCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fbGVmdCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fcmlnaHQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZXZlbnQgPSBudWxsO1xuXHQgICAgfTtcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLy9cdEVORCBJTlRFUlZBTCBOT0RFIEhFTFBFUlxuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICByZXR1cm4gVG9uZS5JbnRlcnZhbFRpbWVsaW5lO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuVGlja3MgaXMgYSBwcmltaXRpdmUgdHlwZSBmb3IgZW5jb2RpbmcgVGltZSB2YWx1ZXMuXG5cdFx0ICogICAgICAgICBUb25lLlRpY2tzIGNhbiBiZSBjb25zdHJ1Y3RlZCB3aXRoIG9yIHdpdGhvdXQgdGhlIGBuZXdgIGtleXdvcmQuIFRvbmUuVGlja3MgY2FuIGJlIHBhc3NlZFxuXHRcdCAqICAgICAgICAgaW50byB0aGUgcGFyYW1ldGVyIG9mIGFueSBtZXRob2Qgd2hpY2ggdGFrZXMgdGltZSBhcyBhbiBhcmd1bWVudC5cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlRyYW5zcG9ydFRpbWV9XG5cdFx0ICogIEBwYXJhbSAge1N0cmluZ3xOdW1iZXJ9ICB2YWwgICAgVGhlIHRpbWUgdmFsdWUuXG5cdFx0ICogIEBwYXJhbSAge1N0cmluZz19ICB1bml0cyAgVGhlIHVuaXRzIG9mIHRoZSB2YWx1ZS5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgdCA9IFRvbmUuVGlja3MoXCI0blwiKTsvL2EgcXVhcnRlciBub3RlXG5cdFx0ICovXG5cdCAgICBUb25lLlRpY2tzID0gZnVuY3Rpb24gKHZhbCwgdW5pdHMpIHtcblx0ICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFRvbmUuVGlja3MpIHtcblx0ICAgICAgICAgICAgVG9uZS5UcmFuc3BvcnRUaW1lLmNhbGwodGhpcywgdmFsLCB1bml0cyk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgcmV0dXJuIG5ldyBUb25lLlRpY2tzKHZhbCwgdW5pdHMpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlRpY2tzLCBUb25lLlRyYW5zcG9ydFRpbWUpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0IHVuaXRzIGlmIG5vbmUgYXJlIGdpdmVuLlxuXHRcdCAqICBAdHlwZSB7U3RyaW5nfVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaWNrcy5wcm90b3R5cGUuX2RlZmF1bHRVbml0cyA9ICdpJztcblx0ICAgIC8qKlxuXHRcdCAqIEdldCB0aGUgY3VycmVudCB0aW1lIGluIHRoZSBnaXZlbiB1bml0c1xuXHRcdCAqIEByZXR1cm4ge1RpY2tzfVxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlRpY2tzLnByb3RvdHlwZS5fbm93ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiBUb25lLlRyYW5zcG9ydC50aWNrcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYmVhdHMgaW4gdGhlIGN1cnJlbnQgdW5pdHNcblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ9IGJlYXRzXG5cdFx0ICogIEByZXR1cm4gIHtOdW1iZXJ9XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlRpY2tzLnByb3RvdHlwZS5fYmVhdHNUb1VuaXRzID0gZnVuY3Rpb24gKGJlYXRzKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2dldFBQUSgpICogYmVhdHM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgc2Vjb25kIGluIHRoZSBjdXJyZW50IHVuaXRzXG5cdFx0ICogIEBwYXJhbSB7U2Vjb25kc30gc2Vjb25kc1xuXHRcdCAqICBAcmV0dXJuICB7TnVtYmVyfVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaWNrcy5wcm90b3R5cGUuX3NlY29uZHNUb1VuaXRzID0gZnVuY3Rpb24gKHNlY29uZHMpIHtcblx0ICAgICAgICByZXR1cm4gc2Vjb25kcyAvICg2MCAvIHRoaXMuX2dldEJwbSgpKSAqIHRoaXMuX2dldFBQUSgpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHRpY2sgaW4gdGhlIGN1cnJlbnQgdGltZSB1bml0c1xuXHRcdCAqICBAcGFyYW0ge1RpY2tzfSB0aWNrc1xuXHRcdCAqICBAcmV0dXJuICB7TnVtYmVyfVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaWNrcy5wcm90b3R5cGUuX3RpY2tzVG9Vbml0cyA9IGZ1bmN0aW9uICh0aWNrcykge1xuXHQgICAgICAgIHJldHVybiB0aWNrcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJuIHRoZSB0aW1lIGluIHRpY2tzXG5cdFx0ICogIEByZXR1cm4gIHtUaWNrc31cblx0XHQgKi9cblx0ICAgIFRvbmUuVGlja3MucHJvdG90eXBlLnRvVGlja3MgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVPZigpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm4gdGhlIHRpbWUgaW4gdGlja3Ncblx0XHQgKiAgQHJldHVybiAge1RpY2tzfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UaWNrcy5wcm90b3R5cGUudG9TZWNvbmRzID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKSAvIHRoaXMuX2dldFBQUSgpICogKDYwIC8gdGhpcy5fZ2V0QnBtKCkpO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlRpY2tzO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuVHJhbnNwb3J0RXZlbnQgaXMgYW4gaW50ZXJuYWwgY2xhc3MgdXNlZCBieSAoVG9uZS5UcmFuc3BvcnQpW1RyYW5zcG9ydF1cblx0XHQgKiAgICAgICAgIHRvIHNjaGVkdWxlIGV2ZW50cy4gRG8gbm8gaW52b2tlIHRoaXMgY2xhc3MgZGlyZWN0bHksIGl0IGlzXG5cdFx0ICogICAgICAgICBoYW5kbGVkIGZyb20gd2l0aGluIFRvbmUuVHJhbnNwb3J0LlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZX1cblx0XHQgKiAgQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0RXZlbnQgPSBmdW5jdGlvbiAoVHJhbnNwb3J0LCBvcHRpb25zKSB7XG5cdCAgICAgICAgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdEFyZyhvcHRpb25zLCBUb25lLlRyYW5zcG9ydEV2ZW50LmRlZmF1bHRzKTtcblx0ICAgICAgICBUb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBSZWZlcmVuY2UgdG8gdGhlIFRyYW5zcG9ydCB0aGF0IGNyZWF0ZWQgaXRcblx0XHRcdCAqIEB0eXBlIHtUb25lLlRyYW5zcG9ydH1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuVHJhbnNwb3J0ID0gVHJhbnNwb3J0O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIHVuaXF1ZSBpZCBvZiB0aGUgZXZlbnRcblx0XHRcdCAqIEB0eXBlIHtOdW1iZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmlkID0gVG9uZS5UcmFuc3BvcnRFdmVudC5fZXZlbnRJZCsrO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIHRpbWUgdGhlIGV2ZW50IHN0YXJ0c1xuXHRcdFx0ICogQHR5cGUge1RpY2tzfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy50aW1lID0gVG9uZS5UaWNrcyhvcHRpb25zLnRpbWUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIGNhbGxiYWNrIHRvIGludm9rZVxuXHRcdFx0ICogQHR5cGUge0Z1bmN0aW9ufVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5jYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBJZiB0aGUgZXZlbnQgc2hvdWxkIGJlIHJlbW92ZWQgYWZ0ZXIgYmVpbmcgY3JlYXRlZC5cblx0XHRcdCAqIEB0eXBlIHtCb29sZWFufVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX29uY2UgPSBvcHRpb25zLm9uY2U7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5UcmFuc3BvcnRFdmVudCk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgZGVmYXVsdHNcblx0XHQgKiBAc3RhdGljXG5cdFx0ICogQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0RXZlbnQuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ29uY2UnOiBmYWxzZSxcblx0ICAgICAgICAnY2FsbGJhY2snOiBUb25lLm5vT3Bcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBDdXJyZW50IElEIGNvdW50ZXJcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnRFdmVudC5fZXZlbnRJZCA9IDA7XG5cdCAgICAvKipcblx0XHQgKiBJbnZva2UgdGhlIGV2ZW50IGNhbGxiYWNrLlxuXHRcdCAqIEBwYXJhbSAge1RpbWV9IHRpbWUgIFRoZSBBdWRpb0NvbnRleHQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBldmVudFxuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnRFdmVudC5wcm90b3R5cGUuaW52b2tlID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICBpZiAodGhpcy5jYWxsYmFjaykge1xuXHQgICAgICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUpO1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fb25jZSAmJiB0aGlzLlRyYW5zcG9ydCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5UcmFuc3BvcnQuY2xlYXIodGhpcy5pZCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogQ2xlYW4gdXBcblx0XHQgKiBAcmV0dXJuIHtUb25lLlRyYW5zcG9ydEV2ZW50fSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRyYW5zcG9ydEV2ZW50LnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLlRyYW5zcG9ydCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5jYWxsYmFjayA9IG51bGw7XG5cdCAgICAgICAgdGhpcy50aW1lID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5UcmFuc3BvcnRFdmVudDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBUb25lLlRyYW5zcG9ydFJlcGVhdEV2ZW50IGlzIGFuIGludGVybmFsIGNsYXNzIHVzZWQgYnkgVG9uZS5UcmFuc3BvcnRcblx0XHQgKiAgICAgICAgIHRvIHNjaGVkdWxlIHJlcGVhdCBldmVudHMuIFRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQgZGlyZWN0bHkuXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlRyYW5zcG9ydEV2ZW50fVxuXHRcdCAqICBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnRSZXBlYXRFdmVudCA9IGZ1bmN0aW9uIChUcmFuc3BvcnQsIG9wdGlvbnMpIHtcblx0ICAgICAgICBUb25lLlRyYW5zcG9ydEV2ZW50LmNhbGwodGhpcywgVHJhbnNwb3J0LCBvcHRpb25zKTtcblx0ICAgICAgICBvcHRpb25zID0gVG9uZS5kZWZhdWx0QXJnKG9wdGlvbnMsIFRvbmUuVHJhbnNwb3J0UmVwZWF0RXZlbnQuZGVmYXVsdHMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogV2hlbiB0aGUgZXZlbnQgc2hvdWxkIHN0b3AgcmVwZWF0aW5nXG5cdFx0XHQgKiBAdHlwZSB7VGlja3N9XG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kdXJhdGlvbiA9IFRvbmUuVGlja3Mob3B0aW9ucy5kdXJhdGlvbik7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBUaGUgaW50ZXJ2YWwgb2YgdGhlIHJlcGVhdGVkIGV2ZW50XG5cdFx0XHQgKiBAdHlwZSB7VGlja3N9XG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5faW50ZXJ2YWwgPSBUb25lLlRpY2tzKG9wdGlvbnMuaW50ZXJ2YWwpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIElEIG9mIHRoZSBjdXJyZW50IHRpbWVsaW5lIGV2ZW50XG5cdFx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2N1cnJlbnRJZCA9IC0xO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIElEIG9mIHRoZSBuZXh0IHRpbWVsaW5lIGV2ZW50XG5cdFx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX25leHRJZCA9IC0xO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICAqIFRoZSB0aW1lIG9mIHRoZSBuZXh0IGV2ZW50XG5cdFx0XHQgICogQHR5cGUge1RpY2tzfVxuXHRcdFx0ICAqIEBwcml2YXRlXG5cdFx0XHQgICovXG5cdCAgICAgICAgdGhpcy5fbmV4dFRpY2sgPSB0aGlzLnRpbWU7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBhIHJlZmVyZW5jZSB0byB0aGUgYm91bmQgc3RhcnQgbWV0aG9kXG5cdFx0XHQgKiBAdHlwZSB7RnVuY3Rpb259XG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYm91bmRSZXN0YXJ0ID0gdGhpcy5fcmVzdGFydC5iaW5kKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuVHJhbnNwb3J0Lm9uKCdzdGFydCBsb29wU3RhcnQnLCB0aGlzLl9ib3VuZFJlc3RhcnQpO1xuXHQgICAgICAgIHRoaXMuX3Jlc3RhcnQoKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlRyYW5zcG9ydFJlcGVhdEV2ZW50LCBUb25lLlRyYW5zcG9ydEV2ZW50KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBkZWZhdWx0c1xuXHRcdCAqIEBzdGF0aWNcblx0XHQgKiBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnRSZXBlYXRFdmVudC5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnZHVyYXRpb24nOiBJbmZpbml0eSxcblx0ICAgICAgICAnaW50ZXJ2YWwnOiAxXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogSW52b2tlIHRoZSBjYWxsYmFjay4gUmV0dXJucyB0aGUgdGljayB0aW1lIHdoaWNoXG5cdFx0ICogdGhlIG5leHQgZXZlbnQgc2hvdWxkIGJlIHNjaGVkdWxlZCBhdC5cblx0XHQgKiBAcGFyYW0gIHtOdW1iZXJ9IHRpbWUgIFRoZSBBdWRpb0NvbnRleHQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBldmVudFxuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnRSZXBlYXRFdmVudC5wcm90b3R5cGUuaW52b2tlID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICAvL2NyZWF0ZSBtb3JlIGV2ZW50cyBpZiBuZWNlc3Nhcnlcblx0ICAgICAgICB0aGlzLl9jcmVhdGVFdmVudHModGltZSk7XG5cdCAgICAgICAgLy9jYWxsIHRoZSBzdXBlciBjbGFzc1xuXHQgICAgICAgIFRvbmUuVHJhbnNwb3J0RXZlbnQucHJvdG90eXBlLmludm9rZS5jYWxsKHRoaXMsIHRpbWUpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFB1c2ggbW9yZSBldmVudHMgb250byB0aGUgdGltZWxpbmUgdG8ga2VlcCB1cCB3aXRoIHRoZSBwb3NpdGlvbiBvZiB0aGUgdGltZWxpbmVcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnRSZXBlYXRFdmVudC5wcm90b3R5cGUuX2NyZWF0ZUV2ZW50cyA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgLy8gc2NoZWR1bGUgdGhlIG5leHQgZXZlbnRcblx0ICAgICAgICB2YXIgdGlja3MgPSB0aGlzLlRyYW5zcG9ydC5nZXRUaWNrc0F0VGltZSh0aW1lKTtcblx0ICAgICAgICBpZiAodGlja3MgPj0gdGhpcy50aW1lICYmIHRpY2tzID49IHRoaXMuX25leHRUaWNrICYmIHRoaXMuX25leHRUaWNrICsgdGhpcy5faW50ZXJ2YWwgPCB0aGlzLnRpbWUgKyB0aGlzLmR1cmF0aW9uKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX25leHRUaWNrICs9IHRoaXMuX2ludGVydmFsO1xuXHQgICAgICAgICAgICB0aGlzLl9jdXJyZW50SWQgPSB0aGlzLl9uZXh0SWQ7XG5cdCAgICAgICAgICAgIHRoaXMuX25leHRJZCA9IHRoaXMuVHJhbnNwb3J0LnNjaGVkdWxlT25jZSh0aGlzLmludm9rZS5iaW5kKHRoaXMpLCBUb25lLlRpY2tzKHRoaXMuX25leHRUaWNrKSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFB1c2ggbW9yZSBldmVudHMgb250byB0aGUgdGltZWxpbmUgdG8ga2VlcCB1cCB3aXRoIHRoZSBwb3NpdGlvbiBvZiB0aGUgdGltZWxpbmVcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnRSZXBlYXRFdmVudC5wcm90b3R5cGUuX3Jlc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRoaXMuVHJhbnNwb3J0LmNsZWFyKHRoaXMuX2N1cnJlbnRJZCk7XG5cdCAgICAgICAgdGhpcy5UcmFuc3BvcnQuY2xlYXIodGhpcy5fbmV4dElkKTtcblx0ICAgICAgICB0aGlzLl9uZXh0VGljayA9IHRoaXMudGltZTtcblx0ICAgICAgICB2YXIgdGlja3MgPSB0aGlzLlRyYW5zcG9ydC5nZXRUaWNrc0F0VGltZSh0aW1lKTtcblx0ICAgICAgICBpZiAodGlja3MgPiB0aGlzLnRpbWUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fbmV4dFRpY2sgPSB0aGlzLnRpbWUgKyBNYXRoLmNlaWwoKHRpY2tzIC0gdGhpcy50aW1lKSAvIHRoaXMuX2ludGVydmFsKSAqIHRoaXMuX2ludGVydmFsO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl9jdXJyZW50SWQgPSB0aGlzLlRyYW5zcG9ydC5zY2hlZHVsZU9uY2UodGhpcy5pbnZva2UuYmluZCh0aGlzKSwgVG9uZS5UaWNrcyh0aGlzLl9uZXh0VGljaykpO1xuXHQgICAgICAgIHRoaXMuX25leHRUaWNrICs9IHRoaXMuX2ludGVydmFsO1xuXHQgICAgICAgIHRoaXMuX25leHRJZCA9IHRoaXMuVHJhbnNwb3J0LnNjaGVkdWxlT25jZSh0aGlzLmludm9rZS5iaW5kKHRoaXMpLCBUb25lLlRpY2tzKHRoaXMuX25leHRUaWNrKSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogQ2xlYW4gdXBcblx0XHQgKiBAcmV0dXJuIHtUb25lLlRyYW5zcG9ydFJlcGVhdEV2ZW50fSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRyYW5zcG9ydFJlcGVhdEV2ZW50LnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuVHJhbnNwb3J0LmNsZWFyKHRoaXMuX2N1cnJlbnRJZCk7XG5cdCAgICAgICAgdGhpcy5UcmFuc3BvcnQuY2xlYXIodGhpcy5fbmV4dElkKTtcblx0ICAgICAgICB0aGlzLlRyYW5zcG9ydC5vZmYoJ3N0YXJ0IGxvb3BTdGFydCcsIHRoaXMuX2JvdW5kUmVzdGFydCk7XG5cdCAgICAgICAgdGhpcy5fYm91bmRDcmVhdGVFdmVudHMgPSBudWxsO1xuXHQgICAgICAgIFRvbmUuVHJhbnNwb3J0RXZlbnQucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLmR1cmF0aW9uID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9pbnRlcnZhbCA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuVHJhbnNwb3J0UmVwZWF0RXZlbnQ7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgVHJhbnNwb3J0IGZvciB0aW1pbmcgbXVzaWNhbCBldmVudHMuXG5cdFx0ICogICAgICAgICAgU3VwcG9ydHMgdGVtcG8gY3VydmVzIGFuZCB0aW1lIGNoYW5nZXMuIFVubGlrZSBicm93c2VyLWJhc2VkIHRpbWluZyAoc2V0SW50ZXJ2YWwsIHJlcXVlc3RBbmltYXRpb25GcmFtZSlcblx0XHQgKiAgICAgICAgICBUb25lLlRyYW5zcG9ydCB0aW1pbmcgZXZlbnRzIHBhc3MgaW4gdGhlIGV4YWN0IHRpbWUgb2YgdGhlIHNjaGVkdWxlZCBldmVudFxuXHRcdCAqICAgICAgICAgIGluIHRoZSBhcmd1bWVudCBvZiB0aGUgY2FsbGJhY2sgZnVuY3Rpb24uIFBhc3MgdGhhdCB0aW1lIHZhbHVlIHRvIHRoZSBvYmplY3Rcblx0XHQgKiAgICAgICAgICB5b3UncmUgc2NoZWR1bGluZy4gPGJyPjxicj5cblx0XHQgKiAgICAgICAgICBBIHNpbmdsZSB0cmFuc3BvcnQgaXMgY3JlYXRlZCBmb3IgeW91IHdoZW4gdGhlIGxpYnJhcnkgaXMgaW5pdGlhbGl6ZWQuXG5cdFx0ICogICAgICAgICAgPGJyPjxicj5cblx0XHQgKiAgICAgICAgICBUaGUgdHJhbnNwb3J0IGVtaXRzIHRoZSBldmVudHM6IFwic3RhcnRcIiwgXCJzdG9wXCIsIFwicGF1c2VcIiwgYW5kIFwibG9vcFwiIHdoaWNoIGFyZVxuXHRcdCAqICAgICAgICAgIGNhbGxlZCB3aXRoIHRoZSB0aW1lIG9mIHRoYXQgZXZlbnQgYXMgdGhlIGFyZ3VtZW50LlxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkVtaXR0ZXJ9XG5cdFx0ICogIEBzaW5nbGV0b25cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL3JlcGVhdGVkIGV2ZW50IGV2ZXJ5IDh0aCBub3RlXG5cdFx0ICogVG9uZS5UcmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQoZnVuY3Rpb24odGltZSl7XG5cdFx0ICogXHQvL2RvIHNvbWV0aGluZyB3aXRoIHRoZSB0aW1lXG5cdFx0ICogfSwgXCI4blwiKTtcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL3NjaGVkdWxlIGFuIGV2ZW50IG9uIHRoZSAxNnRoIG1lYXN1cmVcblx0XHQgKiBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZShmdW5jdGlvbih0aW1lKXtcblx0XHQgKiBcdC8vZG8gc29tZXRoaW5nIHdpdGggdGhlIHRpbWVcblx0XHQgKiB9LCBcIjE2OjA6MFwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuRW1pdHRlci5jYWxsKHRoaXMpO1xuXHQgICAgICAgIFRvbmUuZ2V0Q29udGV4dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAgICAgICAgIC8vXHRMT09QSU5HXG5cdCAgICAgICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgICAgICAgICAgLyoqXG5cdFx0XHRcdCAqIFx0SWYgdGhlIHRyYW5zcG9ydCBsb29wcyBvciBub3QuXG5cdFx0XHRcdCAqICBAdHlwZSB7Ym9vbGVhbn1cblx0XHRcdFx0ICovXG5cdCAgICAgICAgICAgIHRoaXMubG9vcCA9IGZhbHNlO1xuXHQgICAgICAgICAgICAvKipcblx0XHRcdFx0ICogXHRUaGUgbG9vcCBzdGFydCBwb3NpdGlvbiBpbiB0aWNrc1xuXHRcdFx0XHQgKiAgQHR5cGUge1RpY2tzfVxuXHRcdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdFx0ICovXG5cdCAgICAgICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IDA7XG5cdCAgICAgICAgICAgIC8qKlxuXHRcdFx0XHQgKiBcdFRoZSBsb29wIGVuZCBwb3NpdGlvbiBpbiB0aWNrc1xuXHRcdFx0XHQgKiAgQHR5cGUge1RpY2tzfVxuXHRcdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdFx0ICovXG5cdCAgICAgICAgICAgIHRoaXMuX2xvb3BFbmQgPSAwO1xuXHQgICAgICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgICAgICAgICAvL1x0Q0xPQ0svVEVNUE9cblx0ICAgICAgICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgICAgICAgICAvKipcblx0XHRcdFx0ICogIFB1bHNlcyBwZXIgcXVhcnRlciBpcyB0aGUgbnVtYmVyIG9mIHRpY2tzIHBlciBxdWFydGVyIG5vdGUuXG5cdFx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0XHQgKiAgQHR5cGUgIHtOdW1iZXJ9XG5cdFx0XHRcdCAqL1xuXHQgICAgICAgICAgICB0aGlzLl9wcHEgPSBUcmFuc3BvcnRDb25zdHJ1Y3Rvci5kZWZhdWx0cy5QUFE7XG5cdCAgICAgICAgICAgIC8qKlxuXHRcdFx0XHQgKiAgd2F0Y2hlcyB0aGUgbWFpbiBvc2NpbGxhdG9yIGZvciB0aW1pbmcgdGlja3Ncblx0XHRcdFx0ICogIGluaXRpYWxseSBzdGFydHMgYXQgMTIwYnBtXG5cdFx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0XHQgKiAgQHR5cGUge1RvbmUuQ2xvY2t9XG5cdFx0XHRcdCAqL1xuXHQgICAgICAgICAgICB0aGlzLl9jbG9jayA9IG5ldyBUb25lLkNsb2NrKHtcblx0ICAgICAgICAgICAgICAgICdjYWxsYmFjayc6IHRoaXMuX3Byb2Nlc3NUaWNrLmJpbmQodGhpcyksXG5cdCAgICAgICAgICAgICAgICAnZnJlcXVlbmN5JzogMFxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgdGhpcy5fYmluZENsb2NrRXZlbnRzKCk7XG5cdCAgICAgICAgICAgIC8qKlxuXHRcdFx0XHQgKiAgVGhlIEJlYXRzIFBlciBNaW51dGUgb2YgdGhlIFRyYW5zcG9ydC5cblx0XHRcdFx0ICogIEB0eXBlIHtCUE19XG5cdFx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHRcdCAqICBAZXhhbXBsZVxuXHRcdFx0XHQgKiBUb25lLlRyYW5zcG9ydC5icG0udmFsdWUgPSA4MDtcblx0XHRcdFx0ICogLy9yYW1wIHRoZSBicG0gdG8gMTIwIG92ZXIgMTAgc2Vjb25kc1xuXHRcdFx0XHQgKiBUb25lLlRyYW5zcG9ydC5icG0ucmFtcFRvKDEyMCwgMTApO1xuXHRcdFx0XHQgKi9cblx0ICAgICAgICAgICAgdGhpcy5icG0gPSB0aGlzLl9jbG9jay5mcmVxdWVuY3k7XG5cdCAgICAgICAgICAgIHRoaXMuYnBtLl90b1VuaXRzID0gdGhpcy5fdG9Vbml0cy5iaW5kKHRoaXMpO1xuXHQgICAgICAgICAgICB0aGlzLmJwbS5fZnJvbVVuaXRzID0gdGhpcy5fZnJvbVVuaXRzLmJpbmQodGhpcyk7XG5cdCAgICAgICAgICAgIHRoaXMuYnBtLnVuaXRzID0gVG9uZS5UeXBlLkJQTTtcblx0ICAgICAgICAgICAgdGhpcy5icG0udmFsdWUgPSBUcmFuc3BvcnRDb25zdHJ1Y3Rvci5kZWZhdWx0cy5icG07XG5cdCAgICAgICAgICAgIHRoaXMuX3JlYWRPbmx5KCdicG0nKTtcblx0ICAgICAgICAgICAgLyoqXG5cdFx0XHRcdCAqICBUaGUgdGltZSBzaWduYXR1cmUsIG9yIG1vcmUgYWNjdXJhdGVseSB0aGUgbnVtZXJhdG9yXG5cdFx0XHRcdCAqICBvZiB0aGUgdGltZSBzaWduYXR1cmUgb3ZlciBhIGRlbm9taW5hdG9yIG9mIDQuXG5cdFx0XHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdFx0ICovXG5cdCAgICAgICAgICAgIHRoaXMuX3RpbWVTaWduYXR1cmUgPSBUcmFuc3BvcnRDb25zdHJ1Y3Rvci5kZWZhdWx0cy50aW1lU2lnbmF0dXJlO1xuXHQgICAgICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgICAgICAgICAvL1x0VElNRUxJTkUgRVZFTlRTXG5cdCAgICAgICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgICAgICAgICAgLyoqXG5cdFx0XHRcdCAqICBBbGwgdGhlIGV2ZW50cyBpbiBhbiBvYmplY3QgdG8ga2VlcCB0cmFjayBieSBJRFxuXHRcdFx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHRcdCAqL1xuXHQgICAgICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSB7fTtcblx0ICAgICAgICAgICAgLyoqXG5cdFx0XHRcdCAqIFx0VGhlIHNjaGVkdWxlZCBldmVudHMuXG5cdFx0XHRcdCAqICBAdHlwZSB7VG9uZS5UaW1lbGluZX1cblx0XHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHRcdCAqL1xuXHQgICAgICAgICAgICB0aGlzLl90aW1lbGluZSA9IG5ldyBUb25lLlRpbWVsaW5lKCk7XG5cdCAgICAgICAgICAgIC8qKlxuXHRcdFx0XHQgKiAgUmVwZWF0ZWQgZXZlbnRzXG5cdFx0XHRcdCAqICBAdHlwZSB7QXJyYXl9XG5cdFx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0XHQgKi9cblx0ICAgICAgICAgICAgdGhpcy5fcmVwZWF0ZWRFdmVudHMgPSBuZXcgVG9uZS5JbnRlcnZhbFRpbWVsaW5lKCk7XG5cdCAgICAgICAgICAgIC8qKlxuXHRcdFx0XHQgKiAgQWxsIG9mIHRoZSBzeW5jZWQgU2lnbmFsc1xuXHRcdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdFx0ICogIEB0eXBlIHtBcnJheX1cblx0XHRcdFx0ICovXG5cdCAgICAgICAgICAgIHRoaXMuX3N5bmNlZFNpZ25hbHMgPSBbXTtcblx0ICAgICAgICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgICAgICAgICAgLy9cdFNXSU5HXG5cdCAgICAgICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgICAgICAgICAgLyoqXG5cdFx0XHRcdCAqICBUaGUgc3ViZGl2aXNpb24gb2YgdGhlIHN3aW5nXG5cdFx0XHRcdCAqICBAdHlwZSAge1RpY2tzfVxuXHRcdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdFx0ICovXG5cdCAgICAgICAgICAgIHRoaXMuX3N3aW5nVGlja3MgPSBUcmFuc3BvcnRDb25zdHJ1Y3Rvci5kZWZhdWx0cy5QUFEgLyAyO1xuXHQgICAgICAgICAgICAvLzhuXG5cdCAgICAgICAgICAgIC8qKlxuXHRcdFx0XHQgKiAgVGhlIHN3aW5nIGFtb3VudFxuXHRcdFx0XHQgKiAgQHR5cGUge05vcm1hbFJhbmdlfVxuXHRcdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdFx0ICovXG5cdCAgICAgICAgICAgIHRoaXMuX3N3aW5nQW1vdW50ID0gMDtcblx0ICAgICAgICB9LmJpbmQodGhpcykpO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuVHJhbnNwb3J0LCBUb25lLkVtaXR0ZXIpO1xuXHQgICAgLyoqXG5cdFx0ICogIHRoZSBkZWZhdWx0c1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnQuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2JwbSc6IDEyMCxcblx0ICAgICAgICAnc3dpbmcnOiAwLFxuXHQgICAgICAgICdzd2luZ1N1YmRpdmlzaW9uJzogJzhuJyxcblx0ICAgICAgICAndGltZVNpZ25hdHVyZSc6IDQsXG5cdCAgICAgICAgJ2xvb3BTdGFydCc6IDAsXG5cdCAgICAgICAgJ2xvb3BFbmQnOiAnNG0nLFxuXHQgICAgICAgICdQUFEnOiAxOTJcblx0ICAgIH07XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvL1x0VElDS1Ncblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBjYWxsZWQgb24gZXZlcnkgdGlja1xuXHRcdCAqICBAcGFyYW0gICB7bnVtYmVyfSB0aWNrVGltZSBjbG9jayByZWxhdGl2ZSB0aWNrIHRpbWVcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0LnByb3RvdHlwZS5fcHJvY2Vzc1RpY2sgPSBmdW5jdGlvbiAodGlja1RpbWUsIHRpY2tzKSB7XG5cdCAgICAgICAgLy9oYW5kbGUgc3dpbmdcblx0ICAgICAgICBpZiAodGhpcy5fc3dpbmdBbW91bnQgPiAwICYmIHRpY2tzICUgdGhpcy5fcHBxICE9PSAwICYmIC8vbm90IG9uIGEgZG93bmJlYXRcblx0ICAgICAgICAgICAgdGlja3MgJSAodGhpcy5fc3dpbmdUaWNrcyAqIDIpICE9PSAwKSB7XG5cdCAgICAgICAgICAgIC8vYWRkIHNvbWUgc3dpbmdcblx0ICAgICAgICAgICAgdmFyIHByb2dyZXNzID0gdGlja3MgJSAodGhpcy5fc3dpbmdUaWNrcyAqIDIpIC8gKHRoaXMuX3N3aW5nVGlja3MgKiAyKTtcblx0ICAgICAgICAgICAgdmFyIGFtb3VudCA9IE1hdGguc2luKHByb2dyZXNzICogTWF0aC5QSSkgKiB0aGlzLl9zd2luZ0Ftb3VudDtcblx0ICAgICAgICAgICAgdGlja1RpbWUgKz0gVG9uZS5UaWNrcyh0aGlzLl9zd2luZ1RpY2tzICogMiAvIDMpLnRvU2Vjb25kcygpICogYW1vdW50O1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL2RvIHRoZSBsb29wIHRlc3Rcblx0ICAgICAgICBpZiAodGhpcy5sb29wKSB7XG5cdCAgICAgICAgICAgIGlmICh0aWNrcyA+PSB0aGlzLl9sb29wRW5kKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2xvb3BFbmQnLCB0aWNrVGltZSk7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9jbG9jay5zZXRUaWNrc0F0VGltZSh0aGlzLl9sb29wU3RhcnQsIHRpY2tUaW1lKTtcblx0ICAgICAgICAgICAgICAgIHRpY2tzID0gdGhpcy5fbG9vcFN0YXJ0O1xuXHQgICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdsb29wU3RhcnQnLCB0aWNrVGltZSwgdGhpcy5fY2xvY2suZ2V0U2Vjb25kc0F0VGltZSh0aWNrVGltZSkpO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdsb29wJywgdGlja1RpbWUpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vaW52b2tlIHRoZSB0aW1lbGluZSBldmVudHMgc2NoZWR1bGVkIG9uIHRoaXMgdGlja1xuXHQgICAgICAgIHRoaXMuX3RpbWVsaW5lLmZvckVhY2hBdFRpbWUodGlja3MsIGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgICAgICBldmVudC5pbnZva2UodGlja1RpbWUpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgfTtcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRTQ0hFRFVMQUJMRSBFVkVOVFNcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBTY2hlZHVsZSBhbiBldmVudCBhbG9uZyB0aGUgdGltZWxpbmUuXG5cdFx0ICogIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBiZSBpbnZva2VkIGF0IHRoZSB0aW1lLlxuXHRcdCAqICBAcGFyYW0ge1RyYW5zcG9ydFRpbWV9ICB0aW1lIFRoZSB0aW1lIHRvIGludm9rZSB0aGUgY2FsbGJhY2sgYXQuXG5cdFx0ICogIEByZXR1cm4ge051bWJlcn0gVGhlIGlkIG9mIHRoZSBldmVudCB3aGljaCBjYW4gYmUgdXNlZCBmb3IgY2FuY2VsaW5nIHRoZSBldmVudC5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL3RyaWdnZXIgdGhlIGNhbGxiYWNrIHdoZW4gdGhlIFRyYW5zcG9ydCByZWFjaGVzIHRoZSBkZXNpcmVkIHRpbWVcblx0XHQgKiBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZShmdW5jdGlvbih0aW1lKXtcblx0XHQgKiBcdGVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSk7XG5cdFx0ICogfSwgXCIxMjhpXCIpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnQucHJvdG90eXBlLnNjaGVkdWxlID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aW1lKSB7XG5cdCAgICAgICAgdmFyIGV2ZW50ID0gbmV3IFRvbmUuVHJhbnNwb3J0RXZlbnQodGhpcywge1xuXHQgICAgICAgICAgICAndGltZSc6IFRvbmUuVHJhbnNwb3J0VGltZSh0aW1lKSxcblx0ICAgICAgICAgICAgJ2NhbGxiYWNrJzogY2FsbGJhY2tcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fYWRkRXZlbnQoZXZlbnQsIHRoaXMuX3RpbWVsaW5lKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU2NoZWR1bGUgYSByZXBlYXRlZCBldmVudCBhbG9uZyB0aGUgdGltZWxpbmUuIFRoZSBldmVudCB3aWxsIGZpcmVcblx0XHQgKiAgYXQgdGhlIGBpbnRlcnZhbGAgc3RhcnRpbmcgYXQgdGhlIGBzdGFydFRpbWVgIGFuZCBmb3IgdGhlIHNwZWNpZmllZFxuXHRcdCAqICBgZHVyYXRpb25gLlxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbn0gIGNhbGxiYWNrICAgVGhlIGNhbGxiYWNrIHRvIGludm9rZS5cblx0XHQgKiAgQHBhcmFtICB7VGltZX0gICAgaW50ZXJ2YWwgICBUaGUgZHVyYXRpb24gYmV0d2VlbiBzdWNjZXNzaXZlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzLiBNdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyLlxuXHRcdCAqICBAcGFyYW0gIHtUcmFuc3BvcnRUaW1lPX0gICAgc3RhcnRUaW1lICBXaGVuIGFsb25nIHRoZSB0aW1lbGluZSB0aGUgZXZlbnRzIHNob3VsZFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0IGJlaW5nIGludm9rZWQuXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW2R1cmF0aW9uPUluZmluaXR5XSBIb3cgbG9uZyB0aGUgZXZlbnQgc2hvdWxkIHJlcGVhdC5cblx0XHQgKiAgQHJldHVybiAge051bWJlcn0gICAgVGhlIElEIG9mIHRoZSBzY2hlZHVsZWQgZXZlbnQuIFVzZSB0aGlzIHRvIGNhbmNlbFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGV2ZW50LlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vYSBjYWxsYmFjayBpbnZva2VkIGV2ZXJ5IGVpZ2h0aCBub3RlIGFmdGVyIHRoZSBmaXJzdCBtZWFzdXJlXG5cdFx0ICogVG9uZS5UcmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQoY2FsbGJhY2ssIFwiOG5cIiwgXCIxbVwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0LnByb3RvdHlwZS5zY2hlZHVsZVJlcGVhdCA9IGZ1bmN0aW9uIChjYWxsYmFjaywgaW50ZXJ2YWwsIHN0YXJ0VGltZSwgZHVyYXRpb24pIHtcblx0ICAgICAgICB2YXIgZXZlbnQgPSBuZXcgVG9uZS5UcmFuc3BvcnRSZXBlYXRFdmVudCh0aGlzLCB7XG5cdCAgICAgICAgICAgICdjYWxsYmFjayc6IGNhbGxiYWNrLFxuXHQgICAgICAgICAgICAnaW50ZXJ2YWwnOiBUb25lLlRpbWUoaW50ZXJ2YWwpLFxuXHQgICAgICAgICAgICAndGltZSc6IFRvbmUuVHJhbnNwb3J0VGltZShzdGFydFRpbWUpLFxuXHQgICAgICAgICAgICAnZHVyYXRpb24nOiBUb25lLlRpbWUoVG9uZS5kZWZhdWx0QXJnKGR1cmF0aW9uLCBJbmZpbml0eSkpXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLy9raWNrIGl0IG9mZiBpZiB0aGUgVHJhbnNwb3J0IGlzIHN0YXJ0ZWRcblx0ICAgICAgICByZXR1cm4gdGhpcy5fYWRkRXZlbnQoZXZlbnQsIHRoaXMuX3JlcGVhdGVkRXZlbnRzKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU2NoZWR1bGUgYW4gZXZlbnQgdGhhdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgaW52b2tlZC5cblx0XHQgKiAgTm90ZSB0aGF0IGlmIHRoZSBnaXZlbiB0aW1lIGlzIGxlc3MgdGhhbiB0aGUgY3VycmVudCB0cmFuc3BvcnQgdGltZSxcblx0XHQgKiAgdGhlIGV2ZW50IHdpbGwgYmUgaW52b2tlZCBpbW1lZGlhdGVseS5cblx0XHQgKiAgQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSBvbmNlLlxuXHRcdCAqICBAcGFyYW0ge1RyYW5zcG9ydFRpbWV9IHRpbWUgVGhlIHRpbWUgdGhlIGNhbGxiYWNrIHNob3VsZCBiZSBpbnZva2VkLlxuXHRcdCAqICBAcmV0dXJucyB7TnVtYmVyfSBUaGUgSUQgb2YgdGhlIHNjaGVkdWxlZCBldmVudC5cblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0LnByb3RvdHlwZS5zY2hlZHVsZU9uY2UgPSBmdW5jdGlvbiAoY2FsbGJhY2ssIHRpbWUpIHtcblx0ICAgICAgICB2YXIgZXZlbnQgPSBuZXcgVG9uZS5UcmFuc3BvcnRFdmVudCh0aGlzLCB7XG5cdCAgICAgICAgICAgICd0aW1lJzogVG9uZS5UcmFuc3BvcnRUaW1lKHRpbWUpLFxuXHQgICAgICAgICAgICAnY2FsbGJhY2snOiBjYWxsYmFjayxcblx0ICAgICAgICAgICAgJ29uY2UnOiB0cnVlXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2FkZEV2ZW50KGV2ZW50LCB0aGlzLl90aW1lbGluZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFyIHRoZSBwYXNzZWQgaW4gZXZlbnQgaWQgZnJvbSB0aGUgdGltZWxpbmVcblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ9IGV2ZW50SWQgVGhlIGlkIG9mIHRoZSBldmVudC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuVHJhbnNwb3J0fSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRyYW5zcG9ydC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoZXZlbnRJZCkge1xuXHQgICAgICAgIGlmICh0aGlzLl9zY2hlZHVsZWRFdmVudHMuaGFzT3duUHJvcGVydHkoZXZlbnRJZCkpIHtcblx0ICAgICAgICAgICAgdmFyIGl0ZW0gPSB0aGlzLl9zY2hlZHVsZWRFdmVudHNbZXZlbnRJZC50b1N0cmluZygpXTtcblx0ICAgICAgICAgICAgaXRlbS50aW1lbGluZS5yZW1vdmUoaXRlbS5ldmVudCk7XG5cdCAgICAgICAgICAgIGl0ZW0uZXZlbnQuZGlzcG9zZSgpO1xuXHQgICAgICAgICAgICBkZWxldGUgdGhpcy5fc2NoZWR1bGVkRXZlbnRzW2V2ZW50SWQudG9TdHJpbmcoKV07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIEFkZCBhbiBldmVudCB0byB0aGUgY29ycmVjdCB0aW1lbGluZS4gS2VlcCB0cmFjayBvZiB0aGVcblx0XHQgKiB0aW1lbGluZSBpdCB3YXMgYWRkZWQgdG8uXG5cdFx0ICogQHBhcmFtIHtUb25lLlRyYW5zcG9ydEV2ZW50fVx0ZXZlbnRcblx0XHQgKiBAcGFyYW0ge1RvbmUuVGltZWxpbmV9IHRpbWVsaW5lXG5cdFx0ICogQHJldHVybnMge051bWJlcn0gdGhlIGV2ZW50IGlkIHdoaWNoIHdhcyBqdXN0IGFkZGVkXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0LnByb3RvdHlwZS5fYWRkRXZlbnQgPSBmdW5jdGlvbiAoZXZlbnQsIHRpbWVsaW5lKSB7XG5cdCAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzW2V2ZW50LmlkLnRvU3RyaW5nKCldID0ge1xuXHQgICAgICAgICAgICAnZXZlbnQnOiBldmVudCxcblx0ICAgICAgICAgICAgJ3RpbWVsaW5lJzogdGltZWxpbmVcblx0ICAgICAgICB9O1xuXHQgICAgICAgIHRpbWVsaW5lLmFkZChldmVudCk7XG5cdCAgICAgICAgcmV0dXJuIGV2ZW50LmlkO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZW1vdmUgc2NoZWR1bGVkIGV2ZW50cyBmcm9tIHRoZSB0aW1lbGluZSBhZnRlclxuXHRcdCAqICB0aGUgZ2l2ZW4gdGltZS4gUmVwZWF0ZWQgZXZlbnRzIHdpbGwgYmUgcmVtb3ZlZFxuXHRcdCAqICBpZiB0aGVpciBzdGFydFRpbWUgaXMgYWZ0ZXIgdGhlIGdpdmVuIHRpbWVcblx0XHQgKiAgQHBhcmFtIHtUcmFuc3BvcnRUaW1lfSBbYWZ0ZXI9MF0gQ2xlYXIgYWxsIGV2ZW50cyBhZnRlclxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIHRpbWUuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRyYW5zcG9ydH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnQucHJvdG90eXBlLmNhbmNlbCA9IGZ1bmN0aW9uIChhZnRlcikge1xuXHQgICAgICAgIGFmdGVyID0gVG9uZS5kZWZhdWx0QXJnKGFmdGVyLCAwKTtcblx0ICAgICAgICBhZnRlciA9IHRoaXMudG9UaWNrcyhhZnRlcik7XG5cdCAgICAgICAgdGhpcy5fdGltZWxpbmUuZm9yRWFjaEZyb20oYWZ0ZXIsIGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgICAgICB0aGlzLmNsZWFyKGV2ZW50LmlkKTtcblx0ICAgICAgICB9LmJpbmQodGhpcykpO1xuXHQgICAgICAgIHRoaXMuX3JlcGVhdGVkRXZlbnRzLmZvckVhY2hGcm9tKGFmdGVyLCBmdW5jdGlvbiAoZXZlbnQpIHtcblx0ICAgICAgICAgICAgdGhpcy5jbGVhcihldmVudC5pZCk7XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvL1x0U1RBUlQvU1RPUC9QQVVTRVxuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgLyoqXG5cdFx0ICogIEJpbmQgc3RhcnQvc3RvcC9wYXVzZSBldmVudHMgZnJvbSB0aGUgY2xvY2sgYW5kIGVtaXQgdGhlbS5cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0LnByb3RvdHlwZS5fYmluZENsb2NrRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuX2Nsb2NrLm9uKCdzdGFydCcsIGZ1bmN0aW9uICh0aW1lLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgb2Zmc2V0ID0gVG9uZS5UaWNrcyhvZmZzZXQpLnRvU2Vjb25kcygpO1xuXHQgICAgICAgICAgICB0aGlzLmVtaXQoJ3N0YXJ0JywgdGltZSwgb2Zmc2V0KTtcblx0ICAgICAgICB9LmJpbmQodGhpcykpO1xuXHQgICAgICAgIHRoaXMuX2Nsb2NrLm9uKCdzdG9wJywgZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICAgICAgdGhpcy5lbWl0KCdzdG9wJywgdGltZSk7XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLl9jbG9jay5vbigncGF1c2UnLCBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgICAgICB0aGlzLmVtaXQoJ3BhdXNlJywgdGltZSk7XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiLCBcInN0b3BwZWRcIiwgb3IgXCJwYXVzZWRcIlxuXHRcdCAqICBAdHlwZSB7VG9uZS5TdGF0ZX1cblx0XHQgKiAgQHJlYWRPbmx5XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlRyYW5zcG9ydCNcblx0XHQgKiAgQG5hbWUgc3RhdGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlRyYW5zcG9ydC5wcm90b3R5cGUsICdzdGF0ZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLmdldFN0YXRlQXRUaW1lKHRoaXMubm93KCkpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFN0YXJ0IHRoZSB0cmFuc3BvcnQgYW5kIGFsbCBzb3VyY2VzIHN5bmNlZCB0byB0aGUgdHJhbnNwb3J0LlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddIFRoZSB0aW1lIHdoZW4gdGhlIHRyYW5zcG9ydCBzaG91bGQgc3RhcnQuXG5cdFx0ICogIEBwYXJhbSAge1RyYW5zcG9ydFRpbWU9fSBvZmZzZXQgVGhlIHRpbWVsaW5lIG9mZnNldCB0byBzdGFydCB0aGUgdHJhbnNwb3J0LlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5UcmFuc3BvcnR9IHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL3N0YXJ0IHRoZSB0cmFuc3BvcnQgaW4gb25lIHNlY29uZCBzdGFydGluZyBhdCBiZWdpbm5pbmcgb2YgdGhlIDV0aCBtZWFzdXJlLlxuXHRcdCAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KFwiKzFcIiwgXCI0OjA6MFwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0LnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICh0aW1lLCBvZmZzZXQpIHtcblx0ICAgICAgICAvL3N0YXJ0IHRoZSBjbG9ja1xuXHQgICAgICAgIGlmIChUb25lLmlzRGVmaW5lZChvZmZzZXQpKSB7XG5cdCAgICAgICAgICAgIG9mZnNldCA9IHRoaXMudG9UaWNrcyhvZmZzZXQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl9jbG9jay5zdGFydCh0aW1lLCBvZmZzZXQpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTdG9wIHRoZSB0cmFuc3BvcnQgYW5kIGFsbCBzb3VyY2VzIHN5bmNlZCB0byB0aGUgdHJhbnNwb3J0LlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddIFRoZSB0aW1lIHdoZW4gdGhlIHRyYW5zcG9ydCBzaG91bGQgc3RvcC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuVHJhbnNwb3J0fSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogVG9uZS5UcmFuc3BvcnQuc3RvcCgpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnQucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRoaXMuX2Nsb2NrLnN0b3AodGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFBhdXNlIHRoZSB0cmFuc3BvcnQgYW5kIGFsbCBzb3VyY2VzIHN5bmNlZCB0byB0aGUgdHJhbnNwb3J0LlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRyYW5zcG9ydH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnQucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9jbG9jay5wYXVzZSh0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUb2dnbGUgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHRyYW5zcG9ydC4gSWYgaXQgaXNcblx0XHQgKiBzdGFydGVkLCBpdCB3aWxsIHN0b3AgaXQsIG90aGVyd2lzZSBpdCB3aWxsIHN0YXJ0IHRoZSBUcmFuc3BvcnQuXG5cdFx0ICogQHBhcmFtICB7VGltZT19IHRpbWUgVGhlIHRpbWUgb2YgdGhlIGV2ZW50XG5cdFx0ICogQHJldHVybiB7VG9uZS5UcmFuc3BvcnR9ICAgICAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnQucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIGlmICh0aGlzLl9jbG9jay5nZXRTdGF0ZUF0VGltZSh0aW1lKSAhPT0gVG9uZS5TdGF0ZS5TdGFydGVkKSB7XG5cdCAgICAgICAgICAgIHRoaXMuc3RhcnQodGltZSk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGhpcy5zdG9wKHRpbWUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvL1x0U0VUVEVSUy9HRVRURVJTXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHRpbWUgc2lnbmF0dXJlIGFzIGp1c3QgdGhlIG51bWVyYXRvciBvdmVyIDQuXG5cdFx0ICogIEZvciBleGFtcGxlIDQvNCB3b3VsZCBiZSBqdXN0IDQgYW5kIDYvOCB3b3VsZCBiZSAzLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5UcmFuc3BvcnQjXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ8QXJyYXl9XG5cdFx0ICogIEBuYW1lIHRpbWVTaWduYXR1cmVcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL2NvbW1vbiB0aW1lXG5cdFx0ICogVG9uZS5UcmFuc3BvcnQudGltZVNpZ25hdHVyZSA9IDQ7XG5cdFx0ICogLy8gNy84XG5cdFx0ICogVG9uZS5UcmFuc3BvcnQudGltZVNpZ25hdHVyZSA9IFs3LCA4XTtcblx0XHQgKiAvL3RoaXMgd2lsbCBiZSByZWR1Y2VkIHRvIGEgc2luZ2xlIG51bWJlclxuXHRcdCAqIFRvbmUuVHJhbnNwb3J0LnRpbWVTaWduYXR1cmU7IC8vcmV0dXJucyAzLjVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlRyYW5zcG9ydC5wcm90b3R5cGUsICd0aW1lU2lnbmF0dXJlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZVNpZ25hdHVyZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHRpbWVTaWcpIHtcblx0ICAgICAgICAgICAgaWYgKFRvbmUuaXNBcnJheSh0aW1lU2lnKSkge1xuXHQgICAgICAgICAgICAgICAgdGltZVNpZyA9IHRpbWVTaWdbMF0gLyB0aW1lU2lnWzFdICogNDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aGlzLl90aW1lU2lnbmF0dXJlID0gdGltZVNpZztcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFdoZW4gdGhlIFRvbmUuVHJhbnNwb3J0Lmxvb3AgPSB0cnVlLCB0aGlzIGlzIHRoZSBzdGFydGluZyBwb3NpdGlvbiBvZiB0aGUgbG9vcC5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5UcmFuc3BvcnQjXG5cdFx0ICogQHR5cGUge1RpbWV9XG5cdFx0ICogQG5hbWUgbG9vcFN0YXJ0XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5UcmFuc3BvcnQucHJvdG90eXBlLCAnbG9vcFN0YXJ0Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5UaWNrcyh0aGlzLl9sb29wU3RhcnQpLnRvU2Vjb25kcygpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoc3RhcnRQb3NpdGlvbikge1xuXHQgICAgICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSB0aGlzLnRvVGlja3Moc3RhcnRQb3NpdGlvbik7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBXaGVuIHRoZSBUb25lLlRyYW5zcG9ydC5sb29wID0gdHJ1ZSwgdGhpcyBpcyB0aGUgZW5kaW5nIHBvc2l0aW9uIG9mIHRoZSBsb29wLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlRyYW5zcG9ydCNcblx0XHQgKiBAdHlwZSB7VGltZX1cblx0XHQgKiBAbmFtZSBsb29wRW5kXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5UcmFuc3BvcnQucHJvdG90eXBlLCAnbG9vcEVuZCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIFRvbmUuVGlja3ModGhpcy5fbG9vcEVuZCkudG9TZWNvbmRzKCk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChlbmRQb3NpdGlvbikge1xuXHQgICAgICAgICAgICB0aGlzLl9sb29wRW5kID0gdGhpcy50b1RpY2tzKGVuZFBvc2l0aW9uKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBTZXQgdGhlIGxvb3Agc3RhcnQgYW5kIHN0b3AgYXQgdGhlIHNhbWUgdGltZS5cblx0XHQgKiAgQHBhcmFtIHtUcmFuc3BvcnRUaW1lfSBzdGFydFBvc2l0aW9uXG5cdFx0ICogIEBwYXJhbSB7VHJhbnNwb3J0VGltZX0gZW5kUG9zaXRpb25cblx0XHQgKiAgQHJldHVybnMge1RvbmUuVHJhbnNwb3J0fSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9sb29wIG92ZXIgdGhlIGZpcnN0IG1lYXN1cmVcblx0XHQgKiBUb25lLlRyYW5zcG9ydC5zZXRMb29wUG9pbnRzKDAsIFwiMW1cIik7XG5cdFx0ICogVG9uZS5UcmFuc3BvcnQubG9vcCA9IHRydWU7XG5cdFx0ICovXG5cdCAgICBUb25lLlRyYW5zcG9ydC5wcm90b3R5cGUuc2V0TG9vcFBvaW50cyA9IGZ1bmN0aW9uIChzdGFydFBvc2l0aW9uLCBlbmRQb3NpdGlvbikge1xuXHQgICAgICAgIHRoaXMubG9vcFN0YXJ0ID0gc3RhcnRQb3NpdGlvbjtcblx0ICAgICAgICB0aGlzLmxvb3BFbmQgPSBlbmRQb3NpdGlvbjtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHN3aW5nIHZhbHVlLiBCZXR3ZWVuIDAtMSB3aGVyZSAxIGVxdWFsIHRvXG5cdFx0ICogIHRoZSBub3RlICsgaGFsZiB0aGUgc3ViZGl2aXNpb24uXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlRyYW5zcG9ydCNcblx0XHQgKiAgQHR5cGUge05vcm1hbFJhbmdlfVxuXHRcdCAqICBAbmFtZSBzd2luZ1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuVHJhbnNwb3J0LnByb3RvdHlwZSwgJ3N3aW5nJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fc3dpbmdBbW91bnQ7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChhbW91bnQpIHtcblx0ICAgICAgICAgICAgLy9zY2FsZSB0aGUgdmFsdWVzIHRvIGEgbm9ybWFsIHJhbmdlXG5cdCAgICAgICAgICAgIHRoaXMuX3N3aW5nQW1vdW50ID0gYW1vdW50O1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFNldCB0aGUgc3ViZGl2aXNpb24gd2hpY2ggdGhlIHN3aW5nIHdpbGwgYmUgYXBwbGllZCB0by5cblx0XHQgKiAgVGhlIGRlZmF1bHQgdmFsdWUgaXMgYW4gOHRoIG5vdGUuIFZhbHVlIG11c3QgYmUgbGVzc1xuXHRcdCAqICB0aGFuIGEgcXVhcnRlciBub3RlLlxuXHRcdCAqXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlRyYW5zcG9ydCNcblx0XHQgKiAgQHR5cGUge1RpbWV9XG5cdFx0ICogIEBuYW1lIHN3aW5nU3ViZGl2aXNpb25cblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlRyYW5zcG9ydC5wcm90b3R5cGUsICdzd2luZ1N1YmRpdmlzaW9uJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5UaWNrcyh0aGlzLl9zd2luZ1RpY2tzKS50b05vdGF0aW9uKCk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChzdWJkaXZpc2lvbikge1xuXHQgICAgICAgICAgICB0aGlzLl9zd2luZ1RpY2tzID0gdGhpcy50b1RpY2tzKHN1YmRpdmlzaW9uKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgVHJhbnNwb3J0J3MgcG9zaXRpb24gaW4gQmFyczpCZWF0czpTaXh0ZWVudGhzLlxuXHRcdCAqICBTZXR0aW5nIHRoZSB2YWx1ZSB3aWxsIGp1bXAgdG8gdGhhdCBwb3NpdGlvbiByaWdodCBhd2F5LlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5UcmFuc3BvcnQjXG5cdFx0ICogIEB0eXBlIHtCYXJzQmVhdHNTaXh0ZWVudGhzfVxuXHRcdCAqICBAbmFtZSBwb3NpdGlvblxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuVHJhbnNwb3J0LnByb3RvdHlwZSwgJ3Bvc2l0aW9uJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgbm93ID0gdGhpcy5ub3coKTtcblx0ICAgICAgICAgICAgdmFyIHRpY2tzID0gdGhpcy5fY2xvY2suZ2V0VGlja3NBdFRpbWUobm93KTtcblx0ICAgICAgICAgICAgcmV0dXJuIFRvbmUuVGlja3ModGlja3MpLnRvQmFyc0JlYXRzU2l4dGVlbnRocygpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocHJvZ3Jlc3MpIHtcblx0ICAgICAgICAgICAgdmFyIHRpY2tzID0gdGhpcy50b1RpY2tzKHByb2dyZXNzKTtcblx0ICAgICAgICAgICAgdGhpcy50aWNrcyA9IHRpY2tzO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBUcmFuc3BvcnQncyBwb3NpdGlvbiBpbiBzZWNvbmRzXG5cdFx0ICogIFNldHRpbmcgdGhlIHZhbHVlIHdpbGwganVtcCB0byB0aGF0IHBvc2l0aW9uIHJpZ2h0IGF3YXkuXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlRyYW5zcG9ydCNcblx0XHQgKiAgQHR5cGUge1NlY29uZHN9XG5cdFx0ICogIEBuYW1lIHNlY29uZHNcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlRyYW5zcG9ydC5wcm90b3R5cGUsICdzZWNvbmRzJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2suc2Vjb25kcztcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHMpIHtcblx0ICAgICAgICAgICAgdmFyIG5vdyA9IHRoaXMubm93KCk7XG5cdCAgICAgICAgICAgIHZhciB0aWNrcyA9IHRoaXMuYnBtLnRpbWVUb1RpY2tzKHMsIG5vdyk7XG5cdCAgICAgICAgICAgIHRoaXMudGlja3MgPSB0aWNrcztcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgVHJhbnNwb3J0J3MgbG9vcCBwb3NpdGlvbiBhcyBhIG5vcm1hbGl6ZWQgdmFsdWUuIEFsd2F5c1xuXHRcdCAqICByZXR1cm5zIDAgaWYgdGhlIHRyYW5zcG9ydCBpZiBsb29wIGlzIG5vdCB0cnVlLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5UcmFuc3BvcnQjXG5cdFx0ICogIEBuYW1lIHByb2dyZXNzXG5cdFx0ICogIEB0eXBlIHtOb3JtYWxSYW5nZX1cblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlRyYW5zcG9ydC5wcm90b3R5cGUsICdwcm9ncmVzcycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMubG9vcCkge1xuXHQgICAgICAgICAgICAgICAgdmFyIG5vdyA9IHRoaXMubm93KCk7XG5cdCAgICAgICAgICAgICAgICB2YXIgdGlja3MgPSB0aGlzLl9jbG9jay5nZXRUaWNrc0F0VGltZShub3cpO1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuICh0aWNrcyAtIHRoaXMuX2xvb3BTdGFydCkgLyAodGhpcy5fbG9vcEVuZCAtIHRoaXMuX2xvb3BTdGFydCk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gMDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSB0cmFuc3BvcnRzIGN1cnJlbnQgdGljayBwb3NpdGlvbi5cblx0XHQgKlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5UcmFuc3BvcnQjXG5cdFx0ICogIEB0eXBlIHtUaWNrc31cblx0XHQgKiAgQG5hbWUgdGlja3Ncblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlRyYW5zcG9ydC5wcm90b3R5cGUsICd0aWNrcycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLnRpY2tzO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodCkge1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fY2xvY2sudGlja3MgIT09IHQpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBub3cgPSB0aGlzLm5vdygpO1xuXHQgICAgICAgICAgICAgICAgLy9zdG9wIGV2ZXJ5dGhpbmcgc3luY2VkIHRvIHRoZSB0cmFuc3BvcnRcblx0ICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBUb25lLlN0YXRlLlN0YXJ0ZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ3N0b3AnLCBub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX2Nsb2NrLnNldFRpY2tzQXRUaW1lKHQsIG5vdyk7XG5cdCAgICAgICAgICAgICAgICAgICAgLy9yZXN0YXJ0IGl0IHdpdGggdGhlIG5ldyB0aW1lXG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdzdGFydCcsIG5vdywgdGhpcy5zZWNvbmRzKTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2xvY2suc2V0VGlja3NBdFRpbWUodCwgbm93KTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogR2V0IHRoZSBjbG9jaydzIHRpY2tzIGF0IHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqIEBwYXJhbSAge1RpbWV9IHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSB0aWNrIHZhbHVlXG5cdFx0ICogQHJldHVybiB7VGlja3N9ICAgICAgIFRoZSB0aWNrIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnQucHJvdG90eXBlLmdldFRpY2tzQXRUaW1lID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCh0aGlzLl9jbG9jay5nZXRUaWNrc0F0VGltZSh0aW1lKSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybiB0aGUgZWxhcHNlZCBzZWNvbmRzIGF0IHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSAgdGltZSAgV2hlbiB0byBnZXQgdGhlIGVsYXBzZWQgc2Vjb25kc1xuXHRcdCAqICBAcmV0dXJuICB7U2Vjb25kc30gIFRoZSBudW1iZXIgb2YgZWxhcHNlZCBzZWNvbmRzXG5cdFx0ICovXG5cdCAgICBUb25lLlRyYW5zcG9ydC5wcm90b3R5cGUuZ2V0U2Vjb25kc0F0VGltZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLmdldFNlY29uZHNBdFRpbWUodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFB1bHNlcyBQZXIgUXVhcnRlciBub3RlLiBUaGlzIGlzIHRoZSBzbWFsbGVzdCByZXNvbHV0aW9uXG5cdFx0ICogIHRoZSBUcmFuc3BvcnQgdGltaW5nIHN1cHBvcnRzLiBUaGlzIHNob3VsZCBiZSBzZXQgb25jZVxuXHRcdCAqICBvbiBpbml0aWFsaXphdGlvbiBhbmQgbm90IHNldCBhZ2Fpbi4gQ2hhbmdpbmcgdGhpcyB2YWx1ZVxuXHRcdCAqICBhZnRlciBvdGhlciBvYmplY3RzIGhhdmUgYmVlbiBjcmVhdGVkIGNhbiBjYXVzZSBwcm9ibGVtcy5cblx0XHQgKlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5UcmFuc3BvcnQjXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBuYW1lIFBQUVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuVHJhbnNwb3J0LnByb3RvdHlwZSwgJ1BQUScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BwcTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHBwcSkge1xuXHQgICAgICAgICAgICB2YXIgYnBtID0gdGhpcy5icG0udmFsdWU7XG5cdCAgICAgICAgICAgIHRoaXMuX3BwcSA9IHBwcTtcblx0ICAgICAgICAgICAgdGhpcy5icG0udmFsdWUgPSBicG07XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQ29udmVydCBmcm9tIEJQTSB0byBmcmVxdWVuY3kgKGZhY3RvcmluZyBpbiBQUFEpXG5cdFx0ICogIEBwYXJhbSAge0JQTX0gIGJwbSBUaGUgQlBNIHZhbHVlIHRvIGNvbnZlcnQgdG8gZnJlcXVlbmN5XG5cdFx0ICogIEByZXR1cm4gIHtGcmVxdWVuY3l9ICBUaGUgQlBNIGFzIGEgZnJlcXVlbmN5IHdpdGggUFBRIGZhY3RvcmVkIGluLlxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnQucHJvdG90eXBlLl9mcm9tVW5pdHMgPSBmdW5jdGlvbiAoYnBtKSB7XG5cdCAgICAgICAgcmV0dXJuIDEgLyAoNjAgLyBicG0gLyB0aGlzLlBQUSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENvbnZlcnQgZnJvbSBmcmVxdWVuY3kgKHdpdGggUFBRKSBpbnRvIEJQTVxuXHRcdCAqICBAcGFyYW0gIHtGcmVxdWVuY3l9ICBmcmVxIFRoZSBjbG9ja3MgZnJlcXVlbmN5IHRvIGNvbnZlcnQgdG8gQlBNXG5cdFx0ICogIEByZXR1cm4gIHtCUE19ICBUaGUgZnJlcXVlbmN5IHZhbHVlIGFzIEJQTS5cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0LnByb3RvdHlwZS5fdG9Vbml0cyA9IGZ1bmN0aW9uIChmcmVxKSB7XG5cdCAgICAgICAgcmV0dXJuIGZyZXEgLyB0aGlzLlBQUSAqIDYwO1xuXHQgICAgfTtcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRTWU5DSU5HXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJucyB0aGUgdGltZSBhbGlnbmVkIHRvIHRoZSBuZXh0IHN1YmRpdmlzaW9uXG5cdFx0ICogIG9mIHRoZSBUcmFuc3BvcnQuIElmIHRoZSBUcmFuc3BvcnQgaXMgbm90IHN0YXJ0ZWQsXG5cdFx0ICogIGl0IHdpbGwgcmV0dXJuIDAuXG5cdFx0ICogIE5vdGU6IHRoaXMgd2lsbCBub3Qgd29yayBwcmVjaXNlbHkgZHVyaW5nIHRlbXBvIHJhbXBzLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSAgc3ViZGl2aXNpb24gIFRoZSBzdWJkaXZpc2lvbiB0byBxdWFudGl6ZSB0b1xuXHRcdCAqICBAcmV0dXJuICB7TnVtYmVyfSAgVGhlIGNvbnRleHQgdGltZSBvZiB0aGUgbmV4dCBzdWJkaXZpc2lvbi5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpOyAvL3RoZSB0cmFuc3BvcnQgbXVzdCBiZSBzdGFydGVkXG5cdFx0ICogVG9uZS5UcmFuc3BvcnQubmV4dFN1YmRpdmlzaW9uKFwiNG5cIik7XG5cdFx0ICovXG5cdCAgICBUb25lLlRyYW5zcG9ydC5wcm90b3R5cGUubmV4dFN1YmRpdmlzaW9uID0gZnVuY3Rpb24gKHN1YmRpdmlzaW9uKSB7XG5cdCAgICAgICAgc3ViZGl2aXNpb24gPSB0aGlzLnRvVGlja3Moc3ViZGl2aXNpb24pO1xuXHQgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBUb25lLlN0YXRlLlN0YXJ0ZWQpIHtcblx0ICAgICAgICAgICAgLy9pZiB0aGUgdHJhbnNwb3J0J3Mgbm90IHN0YXJ0ZWQsIHJldHVybiAwXG5cdCAgICAgICAgICAgIHJldHVybiAwO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHZhciBub3cgPSB0aGlzLm5vdygpO1xuXHQgICAgICAgICAgICAvL3RoZSByZW1haW5kZXIgb2YgdGhlIGN1cnJlbnQgdGlja3MgYW5kIHRoZSBzdWJkaXZpc2lvblxuXHQgICAgICAgICAgICB2YXIgdHJhbnNwb3J0UG9zID0gdGhpcy5nZXRUaWNrc0F0VGltZShub3cpO1xuXHQgICAgICAgICAgICB2YXIgcmVtYWluaW5nVGlja3MgPSBzdWJkaXZpc2lvbiAtIHRyYW5zcG9ydFBvcyAlIHN1YmRpdmlzaW9uO1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2submV4dFRpY2tUaW1lKHJlbWFpbmluZ1RpY2tzLCBub3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQXR0YWNoZXMgdGhlIHNpZ25hbCB0byB0aGUgdGVtcG8gY29udHJvbCBzaWduYWwgc28gdGhhdFxuXHRcdCAqICBhbnkgY2hhbmdlcyBpbiB0aGUgdGVtcG8gd2lsbCBjaGFuZ2UgdGhlIHNpZ25hbCBpbiB0aGUgc2FtZVxuXHRcdCAqICByYXRpby5cblx0XHQgKlxuXHRcdCAqICBAcGFyYW0gIHtUb25lLlNpZ25hbH0gc2lnbmFsXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyPX0gcmF0aW8gT3B0aW9uYWxseSBwYXNzIGluIHRoZSByYXRpbyBiZXR3ZWVuXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHR3byBzaWduYWxzLiBPdGhlcndpc2UgaXQgd2lsbCBiZSBjb21wdXRlZFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VkIG9uIHRoZWlyIGN1cnJlbnQgdmFsdWVzLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5UcmFuc3BvcnR9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0LnByb3RvdHlwZS5zeW5jU2lnbmFsID0gZnVuY3Rpb24gKHNpZ25hbCwgcmF0aW8pIHtcblx0ICAgICAgICBpZiAoIXJhdGlvKSB7XG5cdCAgICAgICAgICAgIC8vZ2V0IHRoZSBzeW5jIHJhdGlvXG5cdCAgICAgICAgICAgIHZhciBub3cgPSB0aGlzLm5vdygpO1xuXHQgICAgICAgICAgICBpZiAoc2lnbmFsLmdldFZhbHVlQXRUaW1lKG5vdykgIT09IDApIHtcblx0ICAgICAgICAgICAgICAgIHJhdGlvID0gc2lnbmFsLmdldFZhbHVlQXRUaW1lKG5vdykgLyB0aGlzLmJwbS5nZXRWYWx1ZUF0VGltZShub3cpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmF0aW8gPSAwO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHZhciByYXRpb1NpZ25hbCA9IG5ldyBUb25lLkdhaW4ocmF0aW8pO1xuXHQgICAgICAgIHRoaXMuYnBtLmNoYWluKHJhdGlvU2lnbmFsLCBzaWduYWwuX3BhcmFtKTtcblx0ICAgICAgICB0aGlzLl9zeW5jZWRTaWduYWxzLnB1c2goe1xuXHQgICAgICAgICAgICAncmF0aW8nOiByYXRpb1NpZ25hbCxcblx0ICAgICAgICAgICAgJ3NpZ25hbCc6IHNpZ25hbCxcblx0ICAgICAgICAgICAgJ2luaXRpYWwnOiBzaWduYWwudmFsdWVcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBzaWduYWwudmFsdWUgPSAwO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBVbnN5bmNzIGEgcHJldmlvdXNseSBzeW5jZWQgc2lnbmFsIGZyb20gdGhlIHRyYW5zcG9ydCdzIGNvbnRyb2wuXG5cdFx0ICogIFNlZSBUb25lLlRyYW5zcG9ydC5zeW5jU2lnbmFsLlxuXHRcdCAqICBAcGFyYW0gIHtUb25lLlNpZ25hbH0gc2lnbmFsXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRyYW5zcG9ydH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnQucHJvdG90eXBlLnVuc3luY1NpZ25hbCA9IGZ1bmN0aW9uIChzaWduYWwpIHtcblx0ICAgICAgICBmb3IgKHZhciBpID0gdGhpcy5fc3luY2VkU2lnbmFscy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuXHQgICAgICAgICAgICB2YXIgc3luY2VkU2lnbmFsID0gdGhpcy5fc3luY2VkU2lnbmFsc1tpXTtcblx0ICAgICAgICAgICAgaWYgKHN5bmNlZFNpZ25hbC5zaWduYWwgPT09IHNpZ25hbCkge1xuXHQgICAgICAgICAgICAgICAgc3luY2VkU2lnbmFsLnJhdGlvLmRpc3Bvc2UoKTtcblx0ICAgICAgICAgICAgICAgIHN5bmNlZFNpZ25hbC5zaWduYWwudmFsdWUgPSBzeW5jZWRTaWduYWwuaW5pdGlhbDtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNlZFNpZ25hbHMuc3BsaWNlKGksIDEpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuVHJhbnNwb3J0fSB0aGlzXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlRyYW5zcG9ydC5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkVtaXR0ZXIucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9jbG9jay5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fY2xvY2sgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKCdicG0nKTtcblx0ICAgICAgICB0aGlzLmJwbSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fdGltZWxpbmUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9yZXBlYXRlZEV2ZW50cy5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fcmVwZWF0ZWRFdmVudHMgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8vXHRJTklUSUFMSVpBVElPTlxuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQgICAgdmFyIFRyYW5zcG9ydENvbnN0cnVjdG9yID0gVG9uZS5UcmFuc3BvcnQ7XG5cdCAgICBUb25lLlRyYW5zcG9ydCA9IG5ldyBUcmFuc3BvcnRDb25zdHJ1Y3RvcigpO1xuXHQgICAgVG9uZS5Db250ZXh0Lm9uKCdpbml0JywgZnVuY3Rpb24gKGNvbnRleHQpIHtcblx0ICAgICAgICBpZiAoY29udGV4dC5UcmFuc3BvcnQgaW5zdGFuY2VvZiBUcmFuc3BvcnRDb25zdHJ1Y3Rvcikge1xuXHQgICAgICAgICAgICBUb25lLlRyYW5zcG9ydCA9IGNvbnRleHQuVHJhbnNwb3J0O1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIFRvbmUuVHJhbnNwb3J0ID0gbmV3IFRyYW5zcG9ydENvbnN0cnVjdG9yKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vc3RvcmUgdGhlIFRyYW5zcG9ydCBvbiB0aGUgY29udGV4dCBzbyBpdCBjYW4gYmUgcmV0cmlldmVkIGxhdGVyXG5cdCAgICAgICAgY29udGV4dC5UcmFuc3BvcnQgPSBUb25lLlRyYW5zcG9ydDtcblx0ICAgIH0pO1xuXHQgICAgVG9uZS5Db250ZXh0Lm9uKCdjbG9zZScsIGZ1bmN0aW9uIChjb250ZXh0KSB7XG5cdCAgICAgICAgaWYgKGNvbnRleHQuVHJhbnNwb3J0IGluc3RhbmNlb2YgVHJhbnNwb3J0Q29uc3RydWN0b3IpIHtcblx0ICAgICAgICAgICAgY29udGV4dC5UcmFuc3BvcnQuZGlzcG9zZSgpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgcmV0dXJuIFRvbmUuVHJhbnNwb3J0O1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5Wb2x1bWUgaXMgYSBzaW1wbGUgdm9sdW1lIG5vZGUsIHVzZWZ1bCBmb3IgY3JlYXRpbmcgYSB2b2x1bWUgZmFkZXIuXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuQXVkaW9Ob2RlfVxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQHBhcmFtIHtEZWNpYmVsc30gW3ZvbHVtZT0wXSB0aGUgaW5pdGlhbCB2b2x1bWVcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgdm9sID0gbmV3IFRvbmUuVm9sdW1lKC0xMik7XG5cdFx0ICogaW5zdHJ1bWVudC5jaGFpbih2b2wsIFRvbmUuTWFzdGVyKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuVm9sdW1lID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFsndm9sdW1lJ10sIFRvbmUuVm9sdW1lKTtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogdGhlIG91dHB1dCBub2RlXG5cdFx0XHQgKiBAdHlwZSB7R2Fpbk5vZGV9XG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLmlucHV0ID0gbmV3IFRvbmUuR2FpbihvcHRpb25zLnZvbHVtZSwgVG9uZS5UeXBlLkRlY2liZWxzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSB1bm11dGVkIHZvbHVtZVxuXHRcdFx0ICogQHR5cGUge0RlY2liZWxzfVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3VubXV0ZWRWb2x1bWUgPSBvcHRpb25zLnZvbHVtZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgdm9sdW1lIGNvbnRyb2wgaW4gZGVjaWJlbHMuXG5cdFx0XHQgKiAgQHR5cGUge0RlY2liZWxzfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5vdXRwdXQuZ2Fpbjtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seSgndm9sdW1lJyk7XG5cdCAgICAgICAgLy9zZXQgdGhlIG11dGUgaW5pdGlhbGx5XG5cdCAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuVm9sdW1lLCBUb25lLkF1ZGlvTm9kZSk7XG5cdCAgICAvKipcblx0XHQgKiAgRGVmYXVsdHNcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICogIEBjb25zdFxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICovXG5cdCAgICBUb25lLlZvbHVtZS5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAndm9sdW1lJzogMCxcblx0ICAgICAgICAnbXV0ZSc6IGZhbHNlXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogTXV0ZSB0aGUgb3V0cHV0LlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlZvbHVtZSNcblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAbmFtZSBtdXRlXG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiAvL211dGUgdGhlIG91dHB1dFxuXHRcdCAqIHZvbHVtZS5tdXRlID0gdHJ1ZTtcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlZvbHVtZS5wcm90b3R5cGUsICdtdXRlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy52b2x1bWUudmFsdWUgPT09IC1JbmZpbml0eTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKG11dGUpIHtcblx0ICAgICAgICAgICAgaWYgKCF0aGlzLm11dGUgJiYgbXV0ZSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fdW5tdXRlZFZvbHVtZSA9IHRoaXMudm9sdW1lLnZhbHVlO1xuXHQgICAgICAgICAgICAgICAgLy9tYXliZSBpdCBzaG91bGQgcmFtcCBoZXJlP1xuXHQgICAgICAgICAgICAgICAgdGhpcy52b2x1bWUudmFsdWUgPSAtSW5maW5pdHk7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5tdXRlICYmICFtdXRlKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnZvbHVtZS52YWx1ZSA9IHRoaXMuX3VubXV0ZWRWb2x1bWU7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBjbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5Wb2x1bWV9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVm9sdW1lLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoJ3ZvbHVtZScpO1xuXHQgICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLnZvbHVtZSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuVm9sdW1lO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIEEgc2luZ2xlIG1hc3RlciBvdXRwdXQgd2hpY2ggaXMgY29ubmVjdGVkIHRvIHRoZVxuXHRcdCAqICAgICAgICAgIEF1ZGlvRGVzdGluYXRpb25Ob2RlIChha2EgeW91ciBzcGVha2VycykuXG5cdFx0ICogICAgICAgICAgSXQgcHJvdmlkZXMgdXNlZnVsIGNvbnZlbmllbmNlcyBzdWNoIGFzIHRoZSBhYmlsaXR5XG5cdFx0ICogICAgICAgICAgdG8gc2V0IHRoZSB2b2x1bWUgYW5kIG11dGUgdGhlIGVudGlyZSBhcHBsaWNhdGlvbi5cblx0XHQgKiAgICAgICAgICBJdCBhbHNvIGdpdmVzIHlvdSB0aGUgYWJpbGl0eSB0byBhcHBseSBtYXN0ZXIgZWZmZWN0cyB0byB5b3VyIGFwcGxpY2F0aW9uLlxuXHRcdCAqICAgICAgICAgIDxicj48YnI+XG5cdFx0ICogICAgICAgICAgTGlrZSBUb25lLlRyYW5zcG9ydCwgQSBzaW5nbGUgVG9uZS5NYXN0ZXIgaXMgY3JlYXRlZFxuXHRcdCAqICAgICAgICAgIG9uIGluaXRpYWxpemF0aW9uIGFuZCB5b3UgZG8gbm90IG5lZWQgdG8gZXhwbGljaXRseSBjb25zdHJ1Y3Qgb25lLlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZX1cblx0XHQgKiAgQHNpbmdsZXRvblxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vdGhlIGF1ZGlvIHdpbGwgZ28gZnJvbSB0aGUgb3NjaWxsYXRvciB0byB0aGUgc3BlYWtlcnNcblx0XHQgKiBvc2NpbGxhdG9yLmNvbm5lY3QoVG9uZS5NYXN0ZXIpO1xuXHRcdCAqIC8vYSBjb252ZW5pZW5jZSBmb3IgY29ubmVjdGluZyB0byB0aGUgbWFzdGVyIG91dHB1dCBpcyBhbHNvIHByb3ZpZGVkOlxuXHRcdCAqIG9zY2lsbGF0b3IudG9NYXN0ZXIoKTtcblx0XHQgKiAvL3RoZSBhYm92ZSB0d28gZXhhbXBsZXMgYXJlIGVxdWl2YWxlbnQuXG5cdFx0ICovXG5cdCAgICBUb25lLk1hc3RlciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIFRvbmUuZ2V0Q29udGV4dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHRoaXMuY3JlYXRlSW5zT3V0cygxLCAwKTtcblx0ICAgICAgICAgICAgLyoqXG5cdFx0XHRcdCAqICBUaGUgcHJpdmF0ZSB2b2x1bWUgbm9kZVxuXHRcdFx0XHQgKiAgQHR5cGUgIHtUb25lLlZvbHVtZX1cblx0XHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHRcdCAqL1xuXHQgICAgICAgICAgICB0aGlzLl92b2x1bWUgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLlZvbHVtZSgpO1xuXHQgICAgICAgICAgICAvKipcblx0XHRcdFx0ICogVGhlIHZvbHVtZSBvZiB0aGUgbWFzdGVyIG91dHB1dC5cblx0XHRcdFx0ICogQHR5cGUge0RlY2liZWxzfVxuXHRcdFx0XHQgKiBAc2lnbmFsXG5cdFx0XHRcdCAqL1xuXHQgICAgICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3ZvbHVtZS52b2x1bWU7XG5cdCAgICAgICAgICAgIHRoaXMuX3JlYWRPbmx5KCd2b2x1bWUnKTtcblx0ICAgICAgICAgICAgLy9jb25uZWN0aW9uc1xuXHQgICAgICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMub3V0cHV0LCB0aGlzLmNvbnRleHQuZGVzdGluYXRpb24pO1xuXHQgICAgICAgIH0uYmluZCh0aGlzKSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5NYXN0ZXIsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqICBAY29uc3Rcblx0XHQgKi9cblx0ICAgIFRvbmUuTWFzdGVyLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICd2b2x1bWUnOiAwLFxuXHQgICAgICAgICdtdXRlJzogZmFsc2Vcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBNdXRlIHRoZSBvdXRwdXQuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuTWFzdGVyI1xuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBuYW1lIG11dGVcblx0XHQgKiBAZXhhbXBsZVxuXHRcdCAqIC8vbXV0ZSB0aGUgb3V0cHV0XG5cdFx0ICogVG9uZS5NYXN0ZXIubXV0ZSA9IHRydWU7XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5NYXN0ZXIucHJvdG90eXBlLCAnbXV0ZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZvbHVtZS5tdXRlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobXV0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl92b2x1bWUubXV0ZSA9IG11dGU7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQWRkIGEgbWFzdGVyIGVmZmVjdHMgY2hhaW4uIE5PVEU6IHRoaXMgd2lsbCBkaXNjb25uZWN0IGFueSBub2RlcyB3aGljaCB3ZXJlIHByZXZpb3VzbHlcblx0XHQgKiAgY2hhaW5lZCBpbiB0aGUgbWFzdGVyIGVmZmVjdHMgY2hhaW4uXG5cdFx0ICogIEBwYXJhbSB7QXVkaW9Ob2RlfFRvbmV9IGFyZ3MuLi4gQWxsIGFyZ3VtZW50cyB3aWxsIGJlIGNvbm5lY3RlZCBpbiBhIHJvd1xuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZCB0aGUgTWFzdGVyIHdpbGwgYmUgcm91dGVkIHRocm91Z2ggaXQuXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLk1hc3Rlcn0gIHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL3NvbWUgb3ZlcmFsbCBjb21wcmVzc2lvbiB0byBrZWVwIHRoZSBsZXZlbHMgaW4gY2hlY2tcblx0XHQgKiB2YXIgbWFzdGVyQ29tcHJlc3NvciA9IG5ldyBUb25lLkNvbXByZXNzb3Ioe1xuXHRcdCAqIFx0XCJ0aHJlc2hvbGRcIiA6IC02LFxuXHRcdCAqIFx0XCJyYXRpb1wiIDogMyxcblx0XHQgKiBcdFwiYXR0YWNrXCIgOiAwLjUsXG5cdFx0ICogXHRcInJlbGVhc2VcIiA6IDAuMVxuXHRcdCAqIH0pO1xuXHRcdCAqIC8vZ2l2ZSBhIGxpdHRsZSBib29zdCB0byB0aGUgbG93c1xuXHRcdCAqIHZhciBsb3dCdW1wID0gbmV3IFRvbmUuRmlsdGVyKDIwMCwgXCJsb3dzaGVsZlwiKTtcblx0XHQgKiAvL3JvdXRlIGV2ZXJ5dGhpbmcgdGhyb3VnaCB0aGUgZmlsdGVyXG5cdFx0ICogLy9hbmQgY29tcHJlc3NvciBiZWZvcmUgZ29pbmcgdG8gdGhlIHNwZWFrZXJzXG5cdFx0ICogVG9uZS5NYXN0ZXIuY2hhaW4obG93QnVtcCwgbWFzdGVyQ29tcHJlc3Nvcik7XG5cdFx0ICovXG5cdCAgICBUb25lLk1hc3Rlci5wcm90b3R5cGUuY2hhaW4gPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgdGhpcy5pbnB1dC5jaGFpbi5hcHBseSh0aGlzLmlucHV0LCBhcmd1bWVudHMpO1xuXHQgICAgICAgIGFyZ3VtZW50c1thcmd1bWVudHMubGVuZ3RoIC0gMV0uY29ubmVjdCh0aGlzLm91dHB1dCk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLk1hc3Rlcn0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTWFzdGVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoJ3ZvbHVtZScpO1xuXHQgICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fdm9sdW1lID0gbnVsbDtcblx0ICAgICAgICB0aGlzLnZvbHVtZSA9IG51bGw7XG5cdCAgICB9O1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvL1x0QVVHTUVOVCBUT05FJ3MgUFJPVE9UWVBFXG5cdCAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0ICAgIC8qKlxuXHRcdCAqICBDb25uZWN0ICd0aGlzJyB0byB0aGUgbWFzdGVyIG91dHB1dC4gU2hvcnRoYW5kIGZvciB0aGlzLmNvbm5lY3QoVG9uZS5NYXN0ZXIpXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkF1ZGlvTm9kZX0gdGhpc1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vY29ubmVjdCBhbiBvc2NpbGxhdG9yIHRvIHRoZSBtYXN0ZXIgb3V0cHV0XG5cdFx0ICogdmFyIG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b01hc3RlcigpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLnRvTWFzdGVyID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuY29ubmVjdChUb25lLk1hc3Rlcik7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgaWYgKHdpbmRvdy5BdWRpb05vZGUpIHtcblx0ICAgICAgICAvLyBBbHNvIGF1Z21lbnQgQXVkaW9Ob2RlJ3MgcHJvdG90eXBlIHRvIGluY2x1ZGUgdG9NYXN0ZXIgYXMgYSBjb252ZW5pZW5jZVxuXHQgICAgICAgIEF1ZGlvTm9kZS5wcm90b3R5cGUudG9NYXN0ZXIgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHRoaXMuY29ubmVjdChUb25lLk1hc3Rlcik7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0XHQgKiAgaW5pdGlhbGl6ZSB0aGUgbW9kdWxlIGFuZCBsaXN0ZW4gZm9yIG5ldyBhdWRpbyBjb250ZXh0c1xuXHRcdCAqL1xuXHQgICAgdmFyIE1hc3RlckNvbnN0cnVjdG9yID0gVG9uZS5NYXN0ZXI7XG5cdCAgICBUb25lLk1hc3RlciA9IG5ldyBNYXN0ZXJDb25zdHJ1Y3RvcigpO1xuXHQgICAgVG9uZS5Db250ZXh0Lm9uKCdpbml0JywgZnVuY3Rpb24gKGNvbnRleHQpIHtcblx0ICAgICAgICAvLyBpZiBpdCBhbHJlYWR5IGV4aXN0cywganVzdCByZXN0b3JlIGl0XG5cdCAgICAgICAgaWYgKGNvbnRleHQuTWFzdGVyIGluc3RhbmNlb2YgTWFzdGVyQ29uc3RydWN0b3IpIHtcblx0ICAgICAgICAgICAgVG9uZS5NYXN0ZXIgPSBjb250ZXh0Lk1hc3Rlcjtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBUb25lLk1hc3RlciA9IG5ldyBNYXN0ZXJDb25zdHJ1Y3RvcigpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb250ZXh0Lk1hc3RlciA9IFRvbmUuTWFzdGVyO1xuXHQgICAgfSk7XG5cdCAgICBUb25lLkNvbnRleHQub24oJ2Nsb3NlJywgZnVuY3Rpb24gKGNvbnRleHQpIHtcblx0ICAgICAgICBpZiAoY29udGV4dC5NYXN0ZXIgaW5zdGFuY2VvZiBNYXN0ZXJDb25zdHJ1Y3Rvcikge1xuXHQgICAgICAgICAgICBjb250ZXh0Lk1hc3Rlci5kaXNwb3NlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICByZXR1cm4gVG9uZS5NYXN0ZXI7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgQmFzZSBjbGFzcyBmb3Igc291cmNlcy4gU291cmNlcyBoYXZlIHN0YXJ0L3N0b3AgbWV0aG9kc1xuXHRcdCAqICAgICAgICAgIGFuZCB0aGUgYWJpbGl0eSB0byBiZSBzeW5jZWQgdG8gdGhlXG5cdFx0ICogICAgICAgICAgc3RhcnQvc3RvcCBvZiBUb25lLlRyYW5zcG9ydC5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuQXVkaW9Ob2RlfVxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vTXVsdGlwbGUgc3RhdGUgY2hhbmdlIGV2ZW50cyBjYW4gYmUgY2hhaW5lZCB0b2dldGhlcixcblx0XHQgKiAvL2J1dCBtdXN0IGJlIHNldCBpbiB0aGUgY29ycmVjdCBvcmRlciBhbmQgd2l0aCBhc2NlbmRpbmcgdGltZXNcblx0XHQgKlxuXHRcdCAqIC8vIE9LXG5cdFx0ICogc3RhdGUuc3RhcnQoKS5zdG9wKFwiKzAuMlwiKTtcblx0XHQgKiAvLyBBTkRcblx0XHQgKiBzdGF0ZS5zdGFydCgpLnN0b3AoXCIrMC4yXCIpLnN0YXJ0KFwiKzAuNFwiKS5zdG9wKFwiKzAuN1wiKVxuXHRcdCAqXG5cdFx0ICogLy8gQkFEXG5cdFx0ICogc3RhdGUuc3RvcChcIiswLjJcIikuc3RhcnQoKTtcblx0XHQgKiAvLyBPUlxuXHRcdCAqIHN0YXRlLnN0YXJ0KFwiKzAuM1wiKS5zdG9wKFwiKzAuMlwiKTtcblx0XHQgKlxuXHRcdCAqL1xuXHQgICAgVG9uZS5Tb3VyY2UgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuXHQgICAgICAgIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRBcmcob3B0aW9ucywgVG9uZS5Tb3VyY2UuZGVmYXVsdHMpO1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG91dHB1dCB2b2x1bWUgbm9kZVxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5Wb2x1bWV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFRvbmUuVm9sdW1lKG9wdGlvbnMudm9sdW1lKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSB2b2x1bWUgb2YgdGhlIG91dHB1dCBpbiBkZWNpYmVscy5cblx0XHRcdCAqIEB0eXBlIHtEZWNpYmVsc31cblx0XHRcdCAqIEBzaWduYWxcblx0XHRcdCAqIEBleGFtcGxlXG5cdFx0XHQgKiBzb3VyY2Uudm9sdW1lLnZhbHVlID0gLTY7XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3ZvbHVtZS52b2x1bWU7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoJ3ZvbHVtZScpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogXHRLZWVwIHRyYWNrIG9mIHRoZSBzY2hlZHVsZWQgc3RhdGUuXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuVGltZWxpbmVTdGF0ZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3RhdGUgPSBuZXcgVG9uZS5UaW1lbGluZVN0YXRlKFRvbmUuU3RhdGUuU3RvcHBlZCk7XG5cdCAgICAgICAgdGhpcy5fc3RhdGUubWVtb3J5ID0gMTAwO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBzeW5jZWQgYHN0YXJ0YCBjYWxsYmFjayBmdW5jdGlvbiBmcm9tIHRoZSB0cmFuc3BvcnRcblx0XHRcdCAqICBAdHlwZSB7RnVuY3Rpb259XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3N5bmNlZCA9IGZhbHNlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEtlZXAgdHJhY2sgb2YgYWxsIG9mIHRoZSBzY2hlZHVsZWQgZXZlbnQgaWRzXG5cdFx0XHQgKiAgQHR5cGUgIHtBcnJheX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc2NoZWR1bGVkID0gW107XG5cdCAgICAgICAgLy9tYWtlIHRoZSBvdXRwdXQgZXhwbGljaXRseSBzdGVyZW9cblx0ICAgICAgICB0aGlzLl92b2x1bWUub3V0cHV0Lm91dHB1dC5jaGFubmVsQ291bnQgPSAyO1xuXHQgICAgICAgIHRoaXMuX3ZvbHVtZS5vdXRwdXQub3V0cHV0LmNoYW5uZWxDb3VudE1vZGUgPSAnZXhwbGljaXQnO1xuXHQgICAgICAgIC8vbXV0ZSBpbml0aWFsbHlcblx0ICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5Tb3VyY2UsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgZGVmYXVsdCBwYXJhbWV0ZXJzXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQGNvbnN0XG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLlNvdXJjZS5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAndm9sdW1lJzogMCxcblx0ICAgICAgICAnbXV0ZSc6IGZhbHNlXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIGVpdGhlciBcInN0YXJ0ZWRcIiBvciBcInN0b3BwZWRcIi5cblx0XHQgKiAgQHR5cGUge1RvbmUuU3RhdGV9XG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5Tb3VyY2UjXG5cdFx0ICogIEBuYW1lIHN0YXRlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5Tb3VyY2UucHJvdG90eXBlLCAnc3RhdGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIGlmICh0aGlzLl9zeW5jZWQpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChUb25lLlRyYW5zcG9ydC5zdGF0ZSA9PT0gVG9uZS5TdGF0ZS5TdGFydGVkKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKFRvbmUuVHJhbnNwb3J0LnNlY29uZHMpO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gVG9uZS5TdGF0ZS5TdG9wcGVkO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRoaXMubm93KCkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBNdXRlIHRoZSBvdXRwdXQuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuU291cmNlI1xuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBuYW1lIG11dGVcblx0XHQgKiBAZXhhbXBsZVxuXHRcdCAqIC8vbXV0ZSB0aGUgb3V0cHV0XG5cdFx0ICogc291cmNlLm11dGUgPSB0cnVlO1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuU291cmNlLnByb3RvdHlwZSwgJ211dGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl92b2x1bWUubXV0ZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKG11dGUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fdm9sdW1lLm11dGUgPSBtdXRlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLy9vdmVyd3JpdGUgdGhlc2UgZnVuY3Rpb25zXG5cdCAgICBUb25lLlNvdXJjZS5wcm90b3R5cGUuX3N0YXJ0ID0gVG9uZS5ub09wO1xuXHQgICAgVG9uZS5Tb3VyY2UucHJvdG90eXBlLnJlc3RhcnQgPSBUb25lLm5vT3A7XG5cdCAgICBUb25lLlNvdXJjZS5wcm90b3R5cGUuX3N0b3AgPSBUb25lLm5vT3A7XG5cdCAgICAvKipcblx0XHQgKiAgU3RhcnQgdGhlIHNvdXJjZSBhdCB0aGUgc3BlY2lmaWVkIHRpbWUuIElmIG5vIHRpbWUgaXMgZ2l2ZW4sXG5cdFx0ICogIHN0YXJ0IHRoZSBzb3VyY2Ugbm93LlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddIFdoZW4gdGhlIHNvdXJjZSBzaG91bGQgYmUgc3RhcnRlZC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuU291cmNlfSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogc291cmNlLnN0YXJ0KFwiKzAuNVwiKTsgLy9zdGFydHMgdGhlIHNvdXJjZSAwLjUgc2Vjb25kcyBmcm9tIG5vd1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Tb3VyY2UucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24gKHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcblx0ICAgICAgICBpZiAoVG9uZS5pc1VuZGVmKHRpbWUpICYmIHRoaXMuX3N5bmNlZCkge1xuXHQgICAgICAgICAgICB0aW1lID0gVG9uZS5UcmFuc3BvcnQuc2Vjb25kcztcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vaWYgaXQncyBzdGFydGVkLCBzdG9wIGl0IGFuZCByZXN0YXJ0IGl0XG5cdCAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpbWUpID09PSBUb25lLlN0YXRlLlN0YXJ0ZWQpIHtcblx0ICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHRpbWUpO1xuXHQgICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShUb25lLlN0YXRlLlN0YXJ0ZWQsIHRpbWUpO1xuXHQgICAgICAgICAgICB0aGlzLnJlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoVG9uZS5TdGF0ZS5TdGFydGVkLCB0aW1lKTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuXHQgICAgICAgICAgICAgICAgLy8gYWRkIHRoZSBvZmZzZXQgdGltZSB0byB0aGUgZXZlbnRcblx0ICAgICAgICAgICAgICAgIHZhciBldmVudCA9IHRoaXMuX3N0YXRlLmdldCh0aW1lKTtcblx0ICAgICAgICAgICAgICAgIGV2ZW50Lm9mZnNldCA9IFRvbmUuZGVmYXVsdEFyZyhvZmZzZXQsIDApO1xuXHQgICAgICAgICAgICAgICAgZXZlbnQuZHVyYXRpb24gPSBkdXJhdGlvbjtcblx0ICAgICAgICAgICAgICAgIHZhciBzY2hlZCA9IFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlKGZ1bmN0aW9uICh0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQodCwgb2Zmc2V0LCBkdXJhdGlvbik7XG5cdCAgICAgICAgICAgICAgICB9LmJpbmQodGhpcyksIHRpbWUpO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGVkLnB1c2goc2NoZWQpO1xuXHQgICAgICAgICAgICAgICAgLy9pZiBpdCdzIGFscmVhZHkgc3RhcnRlZFxuXHQgICAgICAgICAgICAgICAgaWYgKFRvbmUuVHJhbnNwb3J0LnN0YXRlID09PSBUb25lLlN0YXRlLlN0YXJ0ZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl9zeW5jZWRTdGFydCh0aGlzLm5vdygpLCBUb25lLlRyYW5zcG9ydC5zZWNvbmRzKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFN0b3AgdGhlIHNvdXJjZSBhdCB0aGUgc3BlY2lmaWVkIHRpbWUuIElmIG5vIHRpbWUgaXMgZ2l2ZW4sXG5cdFx0ICogIHN0b3AgdGhlIHNvdXJjZSBub3cuXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IFt0aW1lPW5vd10gV2hlbiB0aGUgc291cmNlIHNob3VsZCBiZSBzdG9wcGVkLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5Tb3VyY2V9IHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBzb3VyY2Uuc3RvcCgpOyAvLyBzdG9wcyB0aGUgc291cmNlIGltbWVkaWF0ZWx5XG5cdFx0ICovXG5cdCAgICBUb25lLlNvdXJjZS5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgaWYgKFRvbmUuaXNVbmRlZih0aW1lKSAmJiB0aGlzLl9zeW5jZWQpIHtcblx0ICAgICAgICAgICAgdGltZSA9IFRvbmUuVHJhbnNwb3J0LnNlY29uZHM7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAoIXRoaXMuX3N5bmNlZCkge1xuXHQgICAgICAgICAgICB0aGlzLl9zdG9wLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdmFyIHNjaGVkID0gVG9uZS5UcmFuc3BvcnQuc2NoZWR1bGUodGhpcy5fc3RvcC5iaW5kKHRoaXMpLCB0aW1lKTtcblx0ICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGVkLnB1c2goc2NoZWQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGltZSk7XG5cdCAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoVG9uZS5TdGF0ZS5TdG9wcGVkLCB0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU3luYyB0aGUgc291cmNlIHRvIHRoZSBUcmFuc3BvcnQgc28gdGhhdCBhbGwgc3Vic2VxdWVudFxuXHRcdCAqICBjYWxscyB0byBgc3RhcnRgIGFuZCBgc3RvcGAgYXJlIHN5bmNlZCB0byB0aGUgVHJhbnNwb3J0VGltZVxuXHRcdCAqICBpbnN0ZWFkIG9mIHRoZSBBdWRpb0NvbnRleHQgdGltZS5cblx0XHQgKlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5Tb3VyY2V9IHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL3N5bmMgdGhlIHNvdXJjZSBzbyB0aGF0IGl0IHBsYXlzIGJldHdlZW4gMCBhbmQgMC4zIG9uIHRoZSBUcmFuc3BvcnQncyB0aW1lbGluZVxuXHRcdCAqIHNvdXJjZS5zeW5jKCkuc3RhcnQoMCkuc3RvcCgwLjMpO1xuXHRcdCAqIC8vc3RhcnQgdGhlIHRyYW5zcG9ydC5cblx0XHQgKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuXHRcdCAqXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9zdGFydCB0aGUgdHJhbnNwb3J0IHdpdGggYW4gb2Zmc2V0IGFuZCB0aGUgc3luYydlZCBzb3VyY2VzXG5cdFx0ICogLy93aWxsIHN0YXJ0IGluIHRoZSBjb3JyZWN0IHBvc2l0aW9uXG5cdFx0ICogc291cmNlLnN5bmMoKS5zdGFydCgwLjEpO1xuXHRcdCAqIC8vdGhlIHNvdXJjZSB3aWxsIGJlIGludm9rZWQgd2l0aCBhbiBvZmZzZXQgb2YgMC40XG5cdFx0ICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoXCIrMC41XCIsIDAuNSk7XG5cdFx0ICovXG5cdCAgICBUb25lLlNvdXJjZS5wcm90b3R5cGUuc3luYyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB0aGlzLl9zeW5jZWQgPSB0cnVlO1xuXHQgICAgICAgIHRoaXMuX3N5bmNlZFN0YXJ0ID0gZnVuY3Rpb24gKHRpbWUsIG9mZnNldCkge1xuXHQgICAgICAgICAgICBpZiAob2Zmc2V0ID4gMCkge1xuXHQgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBwbGF5YmFjayBzdGF0ZSBhdCB0aGF0IHRpbWVcblx0ICAgICAgICAgICAgICAgIHZhciBzdGF0ZUV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KG9mZnNldCk7XG5cdCAgICAgICAgICAgICAgICAvLyBsaXN0ZW4gZm9yIHN0YXJ0IGV2ZW50cyB3aGljaCBtYXkgb2NjdXIgaW4gdGhlIG1pZGRsZSBvZiB0aGUgc3luYydlZCB0aW1lXG5cdCAgICAgICAgICAgICAgICBpZiAoc3RhdGVFdmVudCAmJiBzdGF0ZUV2ZW50LnN0YXRlID09PSBUb25lLlN0YXRlLlN0YXJ0ZWQgJiYgc3RhdGVFdmVudC50aW1lICE9PSBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIG9mZnNldFxuXHQgICAgICAgICAgICAgICAgICAgIHZhciBzdGFydE9mZnNldCA9IG9mZnNldCAtIHRoaXMudG9TZWNvbmRzKHN0YXRlRXZlbnQudGltZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIGR1cmF0aW9uO1xuXHQgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZUV2ZW50LmR1cmF0aW9uKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoc3RhdGVFdmVudC5kdXJhdGlvbikgLSBzdGFydE9mZnNldDtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQodGltZSwgdGhpcy50b1NlY29uZHMoc3RhdGVFdmVudC5vZmZzZXQpICsgc3RhcnRPZmZzZXQsIGR1cmF0aW9uKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0uYmluZCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9zeW5jZWRTdG9wID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICAgICAgdmFyIHNlY29uZHMgPSBUb25lLlRyYW5zcG9ydC5nZXRTZWNvbmRzQXRUaW1lKE1hdGgubWF4KHRpbWUgLSB0aGlzLnNhbXBsZVRpbWUsIDApKTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHNlY29uZHMpID09PSBUb25lLlN0YXRlLlN0YXJ0ZWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3N0b3AodGltZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LmJpbmQodGhpcyk7XG5cdCAgICAgICAgVG9uZS5UcmFuc3BvcnQub24oJ3N0YXJ0IGxvb3BTdGFydCcsIHRoaXMuX3N5bmNlZFN0YXJ0KTtcblx0ICAgICAgICBUb25lLlRyYW5zcG9ydC5vbignc3RvcCBwYXVzZSBsb29wRW5kJywgdGhpcy5fc3luY2VkU3RvcCk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFVuc3luYyB0aGUgc291cmNlIHRvIHRoZSBUcmFuc3BvcnQuIFNlZSBUb25lLlNvdXJjZS5zeW5jXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlNvdXJjZX0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Tb3VyY2UucHJvdG90eXBlLnVuc3luYyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBpZiAodGhpcy5fc3luY2VkKSB7XG5cdCAgICAgICAgICAgIFRvbmUuVHJhbnNwb3J0Lm9mZignc3RvcCBwYXVzZSBsb29wRW5kJywgdGhpcy5fc3luY2VkU3RvcCk7XG5cdCAgICAgICAgICAgIFRvbmUuVHJhbnNwb3J0Lm9mZignc3RhcnQgbG9vcFN0YXJ0JywgdGhpcy5fc3luY2VkU3RhcnQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl9zeW5jZWQgPSBmYWxzZTtcblx0ICAgICAgICAvLyBjbGVhciBhbGwgb2YgdGhlIHNjaGVkdWxlZCBpZHNcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX3NjaGVkdWxlZC5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICB2YXIgaWQgPSB0aGlzLl9zY2hlZHVsZWRbaV07XG5cdCAgICAgICAgICAgIFRvbmUuVHJhbnNwb3J0LmNsZWFyKGlkKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5fc2NoZWR1bGVkID0gW107XG5cdCAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKDApO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqXHRDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybiB7VG9uZS5Tb3VyY2V9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuU291cmNlLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy51bnN5bmMoKTtcblx0ICAgICAgICB0aGlzLl9zY2hlZHVsZWQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKCd2b2x1bWUnKTtcblx0ICAgICAgICB0aGlzLl92b2x1bWUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3ZvbHVtZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy52b2x1bWUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3N0YXRlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuU291cmNlO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICAvKipcblx0XHQgKiAgQXVkaW9CdWZmZXIuY29weVRvL0Zyb21DaGFubmVsIHBvbHlmaWxsXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBpZiAoVG9uZS5zdXBwb3J0ZWQpIHtcblx0ICAgICAgICBpZiAoIUF1ZGlvQnVmZmVyLnByb3RvdHlwZS5jb3B5VG9DaGFubmVsKSB7XG5cdCAgICAgICAgICAgIEF1ZGlvQnVmZmVyLnByb3RvdHlwZS5jb3B5VG9DaGFubmVsID0gZnVuY3Rpb24gKHNyYywgY2hhbk51bSwgc3RhcnQpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBjaGFubmVsID0gdGhpcy5nZXRDaGFubmVsRGF0YShjaGFuTnVtKTtcblx0ICAgICAgICAgICAgICAgIHN0YXJ0ID0gc3RhcnQgfHwgMDtcblx0ICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hhbm5lbC5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxbaSArIHN0YXJ0XSA9IHNyY1tpXTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgQXVkaW9CdWZmZXIucHJvdG90eXBlLmNvcHlGcm9tQ2hhbm5lbCA9IGZ1bmN0aW9uIChkZXN0LCBjaGFuTnVtLCBzdGFydCkge1xuXHQgICAgICAgICAgICAgICAgdmFyIGNoYW5uZWwgPSB0aGlzLmdldENoYW5uZWxEYXRhKGNoYW5OdW0pO1xuXHQgICAgICAgICAgICAgICAgc3RhcnQgPSBzdGFydCB8fCAwO1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkZXN0Lmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgZGVzdFtpXSA9IGNoYW5uZWxbaSArIHN0YXJ0XTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgQnVmZmVyIGxvYWRpbmcgYW5kIHN0b3JhZ2UuIFRvbmUuQnVmZmVyIGlzIHVzZWQgaW50ZXJuYWxseSBieSBhbGxcblx0XHQgKiAgICAgICAgICBjbGFzc2VzIHRoYXQgbWFrZSByZXF1ZXN0cyBmb3IgYXVkaW8gZmlsZXMgc3VjaCBhcyBUb25lLlBsYXllcixcblx0XHQgKiAgICAgICAgICBUb25lLlNhbXBsZXIgYW5kIFRvbmUuQ29udm9sdmVyLlxuXHRcdCAqXG5cdFx0ICogICAgICAgICAgQXNpZGUgZnJvbSBsb2FkIGNhbGxiYWNrcyBmcm9tIGluZGl2aWR1YWwgYnVmZmVycywgVG9uZS5CdWZmZXJcblx0XHQgKiAgXHRcdHByb3ZpZGVzIGV2ZW50cyB3aGljaCBrZWVwIHRyYWNrIG9mIHRoZSBsb2FkaW5nIHByb2dyZXNzXG5cdFx0ICogIFx0XHRvZiBfYWxsXyBvZiB0aGUgYnVmZmVycy4gVGhlc2UgYXJlIFRvbmUuQnVmZmVyLm9uKFwibG9hZFwiIC8gXCJwcm9ncmVzc1wiIC8gXCJlcnJvclwiKVxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZX1cblx0XHQgKiAgQHBhcmFtIHtBdWRpb0J1ZmZlcnxTdHJpbmd9IHVybCBUaGUgdXJsIHRvIGxvYWQsIG9yIHRoZSBhdWRpbyBidWZmZXIgdG8gc2V0LlxuXHRcdCAqICBAcGFyYW0ge0Z1bmN0aW9uPX0gb25sb2FkIEEgY2FsbGJhY2sgd2hpY2ggaXMgaW52b2tlZCBhZnRlciB0aGUgYnVmZmVyIGlzIGxvYWRlZC5cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdCdzIHJlY29tbWVuZGVkIHRvIHVzZSBgVG9uZS5CdWZmZXIub24oJ2xvYWQnLCBjYWxsYmFjaylgIGluc3RlYWRcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaW5jZSBpdCB3aWxsIGdpdmUgeW91IGEgY2FsbGJhY2sgd2hlbiBfYWxsXyBidWZmZXJzIGFyZSBsb2FkZWQuXG5cdFx0ICogIEBwYXJhbSB7RnVuY3Rpb249fSBvbmVycm9yIFRoZSBjYWxsYmFjayB0byBpbnZva2UgaWYgdGhlcmUgaXMgYW4gZXJyb3Jcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgYnVmZmVyID0gbmV3IFRvbmUuQnVmZmVyKFwicGF0aC90by9zb3VuZC5tcDNcIiwgZnVuY3Rpb24oKXtcblx0XHQgKiBcdC8vdGhlIGJ1ZmZlciBpcyBub3cgYXZhaWxhYmxlLlxuXHRcdCAqIFx0dmFyIGJ1ZmYgPSBidWZmZXIuZ2V0KCk7XG5cdFx0ICogfSk7XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9jYW4gbG9hZCBwcm92aWRlIGZhbGxiYWNrIGV4dGVuc2lvbiB0eXBlcyBpZiB0aGUgZmlyc3QgdHlwZSBpcyBub3Qgc3VwcG9ydGVkLlxuXHRcdCAqIHZhciBidWZmZXIgPSBuZXcgVG9uZS5CdWZmZXIoXCJwYXRoL3RvL3NvdW5kLlttcDN8b2dnfHdhdl1cIik7XG5cdFx0ICovXG5cdCAgICBUb25lLkJ1ZmZlciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICd1cmwnLFxuXHQgICAgICAgICAgICAnb25sb2FkJyxcblx0ICAgICAgICAgICAgJ29uZXJyb3InXG5cdCAgICAgICAgXSwgVG9uZS5CdWZmZXIpO1xuXHQgICAgICAgIFRvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBzdG9yZXMgdGhlIGxvYWRlZCBBdWRpb0J1ZmZlclxuXHRcdFx0ICogIEB0eXBlIHtBdWRpb0J1ZmZlcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYnVmZmVyID0gbnVsbDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBpbmRpY2F0ZXMgaWYgdGhlIGJ1ZmZlciBzaG91bGQgYmUgcmV2ZXJzZWQgb3Igbm90XG5cdFx0XHQgKiAgQHR5cGUge0Jvb2xlYW59XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3JldmVyc2VkID0gb3B0aW9ucy5yZXZlcnNlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBYSFJcblx0XHRcdCAqICBAdHlwZSAge1hNTEh0dHBSZXF1ZXN0fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl94aHIgPSBudWxsO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogUHJpdmF0ZSBjYWxsYmFjayB3aGVuIHRoZSBidWZmZXIgaXMgbG9hZGVkLlxuXHRcdFx0ICogQHR5cGUge0Z1bmN0aW9ufVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX29ubG9hZCA9IFRvbmUubm9PcDtcblx0ICAgICAgICBpZiAob3B0aW9ucy51cmwgaW5zdGFuY2VvZiBBdWRpb0J1ZmZlciB8fCBvcHRpb25zLnVybCBpbnN0YW5jZW9mIFRvbmUuQnVmZmVyKSB7XG5cdCAgICAgICAgICAgIHRoaXMuc2V0KG9wdGlvbnMudXJsKTtcblx0ICAgICAgICAgICAgLy8gaW52b2tlIHRoZSBvbmxvYWQgY2FsbGJhY2tcblx0ICAgICAgICAgICAgaWYgKG9wdGlvbnMub25sb2FkKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAodGhpcy5sb2FkZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICBvcHRpb25zLm9ubG9hZCh0aGlzKTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fb25sb2FkID0gb3B0aW9ucy5vbmxvYWQ7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2UgaWYgKFRvbmUuaXNTdHJpbmcob3B0aW9ucy51cmwpKSB7XG5cdCAgICAgICAgICAgIHRoaXMubG9hZChvcHRpb25zLnVybCkudGhlbihvcHRpb25zLm9ubG9hZCkuY2F0Y2gob3B0aW9ucy5vbmVycm9yKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5CdWZmZXIpO1xuXHQgICAgLyoqXG5cdFx0ICogIHRoZSBkZWZhdWx0IHBhcmFtZXRlcnNcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuQnVmZmVyLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICd1cmwnOiB1bmRlZmluZWQsXG5cdCAgICAgICAgJ3JldmVyc2UnOiBmYWxzZSxcblx0ICAgICAgICAnb25sb2FkJzogVG9uZS5ub09wLFxuXHQgICAgICAgICdvbmVycm9yJzogVG9uZS5ub09wXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFBhc3MgaW4gYW4gQXVkaW9CdWZmZXIgb3IgVG9uZS5CdWZmZXIgdG8gc2V0IHRoZSB2YWx1ZVxuXHRcdCAqICBvZiB0aGlzIGJ1ZmZlci5cblx0XHQgKiAgQHBhcmFtIHtBdWRpb0J1ZmZlcnxUb25lLkJ1ZmZlcn0gYnVmZmVyIHRoZSBidWZmZXJcblx0XHQgKiAgQHJldHVybnMge1RvbmUuQnVmZmVyfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkJ1ZmZlci5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGJ1ZmZlcikge1xuXHQgICAgICAgIGlmIChidWZmZXIgaW5zdGFuY2VvZiBUb25lLkJ1ZmZlcikge1xuXHQgICAgICAgICAgICBpZiAoYnVmZmVyLmxvYWRlZCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyID0gYnVmZmVyLmdldCgpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgYnVmZmVyLl9vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXQoYnVmZmVyKTtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl9vbmxvYWQodGhpcyk7XG5cdCAgICAgICAgICAgICAgICB9LmJpbmQodGhpcyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0aGlzLl9idWZmZXIgPSBidWZmZXI7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBAcmV0dXJuIHtBdWRpb0J1ZmZlcn0gVGhlIGF1ZGlvIGJ1ZmZlciBzdG9yZWQgaW4gdGhlIG9iamVjdC5cblx0XHQgKi9cblx0ICAgIFRvbmUuQnVmZmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgTWFrZXMgYW4geGhyIHJlcWVzdCBmb3IgdGhlIHNlbGVjdGVkIHVybCB0aGVuIGRlY29kZXNcblx0XHQgKiAgdGhlIGZpbGUgYXMgYW4gYXVkaW8gYnVmZmVyLiBJbnZva2VzXG5cdFx0ICogIHRoZSBjYWxsYmFjayBvbmNlIHRoZSBhdWRpbyBidWZmZXIgbG9hZHMuXG5cdFx0ICogIEBwYXJhbSB7U3RyaW5nfSB1cmwgVGhlIHVybCBvZiB0aGUgYnVmZmVyIHRvIGxvYWQuXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgZmlsZXR5cGUgc3VwcG9ydCBkZXBlbmRzIG9uIHRoZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgIGJyb3dzZXIuXG5cdFx0ICogIEByZXR1cm5zIHtQcm9taXNlfSByZXR1cm5zIGEgUHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aXRoIHRoZSBUb25lLkJ1ZmZlclxuXHRcdCAqL1xuXHQgICAgVG9uZS5CdWZmZXIucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAodXJsLCBvbmxvYWQsIG9uZXJyb3IpIHtcblx0ICAgICAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChsb2FkLCBlcnJvcikge1xuXHQgICAgICAgICAgICB0aGlzLl94aHIgPSBUb25lLkJ1ZmZlci5sb2FkKHVybCwgLy9zdWNjZXNzXG5cdCAgICAgICAgICAgIGZ1bmN0aW9uIChidWZmKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl94aHIgPSBudWxsO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5zZXQoYnVmZik7XG5cdCAgICAgICAgICAgICAgICBsb2FkKHRoaXMpO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fb25sb2FkKHRoaXMpO1xuXHQgICAgICAgICAgICAgICAgaWYgKG9ubG9hZCkge1xuXHQgICAgICAgICAgICAgICAgICAgIG9ubG9hZCh0aGlzKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfS5iaW5kKHRoaXMpLCAvL2Vycm9yXG5cdCAgICAgICAgICAgIGZ1bmN0aW9uIChlcnIpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3hociA9IG51bGw7XG5cdCAgICAgICAgICAgICAgICBlcnJvcihlcnIpO1xuXHQgICAgICAgICAgICAgICAgaWYgKG9uZXJyb3IpIHtcblx0ICAgICAgICAgICAgICAgICAgICBvbmVycm9yKGVycik7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0uYmluZCh0aGlzKSk7XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgICAgICByZXR1cm4gcHJvbWlzZTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgZGlzcG9zZSBhbmQgZGlzY29ubmVjdFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5CdWZmZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuQnVmZmVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9idWZmZXIgPSBudWxsO1xuXHQgICAgICAgIGlmICh0aGlzLl94aHIpIHtcblx0ICAgICAgICAgICAgVG9uZS5CdWZmZXIuX3JlbW92ZUZyb21Eb3dubG9hZFF1ZXVlKHRoaXMuX3hocik7XG5cdCAgICAgICAgICAgIHRoaXMuX3hoci5hYm9ydCgpO1xuXHQgICAgICAgICAgICB0aGlzLl94aHIgPSBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBJZiB0aGUgYnVmZmVyIGlzIGxvYWRlZCBvciBub3Rcblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5CdWZmZXIjXG5cdFx0ICogQHR5cGUge0Jvb2xlYW59XG5cdFx0ICogQG5hbWUgbG9hZGVkXG5cdFx0ICogQHJlYWRPbmx5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5CdWZmZXIucHJvdG90eXBlLCAnbG9hZGVkJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5sZW5ndGggPiAwO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIGR1cmF0aW9uIG9mIHRoZSBidWZmZXIuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuQnVmZmVyI1xuXHRcdCAqIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogQG5hbWUgZHVyYXRpb25cblx0XHQgKiBAcmVhZE9ubHlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkJ1ZmZlci5wcm90b3R5cGUsICdkdXJhdGlvbicsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5kdXJhdGlvbjtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiAwO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgbGVuZ3RoIG9mIHRoZSBidWZmZXIgaW4gc2FtcGxlc1xuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkJ1ZmZlciNcblx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqIEBuYW1lIGxlbmd0aFxuXHRcdCAqIEByZWFkT25seVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQnVmZmVyLnByb3RvdHlwZSwgJ2xlbmd0aCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5sZW5ndGg7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gMDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIG51bWJlciBvZiBkaXNjcmV0ZSBhdWRpbyBjaGFubmVscy4gUmV0dXJucyAwIGlmIG5vIGJ1ZmZlclxuXHRcdCAqIGlzIGxvYWRlZC5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5CdWZmZXIjXG5cdFx0ICogQHR5cGUge051bWJlcn1cblx0XHQgKiBAbmFtZSBudW1iZXJPZkNoYW5uZWxzXG5cdFx0ICogQHJlYWRPbmx5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5CdWZmZXIucHJvdG90eXBlLCAnbnVtYmVyT2ZDaGFubmVscycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5udW1iZXJPZkNoYW5uZWxzO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBTZXQgdGhlIGF1ZGlvIGJ1ZmZlciBmcm9tIHRoZSBhcnJheS4gVG8gY3JlYXRlIGEgbXVsdGljaGFubmVsIEF1ZGlvQnVmZmVyLFxuXHRcdCAqICBwYXNzIGluIGEgbXVsdGlkaW1lbnNpb25hbCBhcnJheS5cblx0XHQgKiAgQHBhcmFtIHtGbG9hdDMyQXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmaWxsIHRoZSBhdWRpbyBidWZmZXJcblx0XHQgKiAgQHJldHVybiB7VG9uZS5CdWZmZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuQnVmZmVyLnByb3RvdHlwZS5mcm9tQXJyYXkgPSBmdW5jdGlvbiAoYXJyYXkpIHtcblx0ICAgICAgICB2YXIgaXNNdWx0aWRpbWVuc2lvbmFsID0gYXJyYXlbMF0ubGVuZ3RoID4gMDtcblx0ICAgICAgICB2YXIgY2hhbm5lbHMgPSBpc011bHRpZGltZW5zaW9uYWwgPyBhcnJheS5sZW5ndGggOiAxO1xuXHQgICAgICAgIHZhciBsZW4gPSBpc011bHRpZGltZW5zaW9uYWwgPyBhcnJheVswXS5sZW5ndGggOiBhcnJheS5sZW5ndGg7XG5cdCAgICAgICAgdmFyIGJ1ZmZlciA9IHRoaXMuY29udGV4dC5jcmVhdGVCdWZmZXIoY2hhbm5lbHMsIGxlbiwgdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUpO1xuXHQgICAgICAgIGlmICghaXNNdWx0aWRpbWVuc2lvbmFsICYmIGNoYW5uZWxzID09PSAxKSB7XG5cdCAgICAgICAgICAgIGFycmF5ID0gW2FycmF5XTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZm9yICh2YXIgYyA9IDA7IGMgPCBjaGFubmVsczsgYysrKSB7XG5cdCAgICAgICAgICAgIGJ1ZmZlci5jb3B5VG9DaGFubmVsKGFycmF5W2NdLCBjKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5fYnVmZmVyID0gYnVmZmVyO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFx0U3VtcyBtdWxpcGxlIGNoYW5uZWxzIGludG8gMSBjaGFubmVsXG5cdFx0ICogIEBwYXJhbSB7TnVtYmVyPX0gY2hhbm5lbCBPcHRpb25hbGx5IG9ubHkgY29weSBhIHNpbmdsZSBjaGFubmVsIGZyb20gdGhlIGFycmF5LlxuXHRcdCAqICBAcmV0dXJuIHtBcnJheX1cblx0XHQgKi9cblx0ICAgIFRvbmUuQnVmZmVyLnByb3RvdHlwZS50b01vbm8gPSBmdW5jdGlvbiAoY2hhbk51bSkge1xuXHQgICAgICAgIGlmIChUb25lLmlzTnVtYmVyKGNoYW5OdW0pKSB7XG5cdCAgICAgICAgICAgIHRoaXMuZnJvbUFycmF5KHRoaXMudG9BcnJheShjaGFuTnVtKSk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdmFyIG91dHB1dEFycmF5ID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmxlbmd0aCk7XG5cdCAgICAgICAgICAgIHZhciBudW1DaGFubmVscyA9IHRoaXMubnVtYmVyT2ZDaGFubmVscztcblx0ICAgICAgICAgICAgZm9yICh2YXIgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCBudW1DaGFubmVsczsgY2hhbm5lbCsrKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgY2hhbm5lbEFycmF5ID0gdGhpcy50b0FycmF5KGNoYW5uZWwpO1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGFubmVsQXJyYXkubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICBvdXRwdXRBcnJheVtpXSArPSBjaGFubmVsQXJyYXlbaV07XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgLy9kaXZpZGUgYnkgdGhlIG51bWJlciBvZiBjaGFubmVsc1xuXHQgICAgICAgICAgICBvdXRwdXRBcnJheSA9IG91dHB1dEFycmF5Lm1hcChmdW5jdGlvbiAoc2FtcGxlKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gc2FtcGxlIC8gbnVtQ2hhbm5lbHM7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICB0aGlzLmZyb21BcnJheShvdXRwdXRBcnJheSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFx0R2V0IHRoZSBidWZmZXIgYXMgYW4gYXJyYXkuIFNpbmdsZSBjaGFubmVsIGJ1ZmZlcnMgd2lsbCByZXR1cm4gYSAxLWRpbWVuc2lvbmFsXG5cdFx0ICogXHRGbG9hdDMyQXJyYXksIGFuZCBtdWx0aWNoYW5uZWwgYnVmZmVycyB3aWxsIHJldHVybiBtdWx0aWRpbWVuc2lvbmFsIGFycmF5cy5cblx0XHQgKiAgQHBhcmFtIHtOdW1iZXI9fSBjaGFubmVsIE9wdGlvbmFsbHkgb25seSBjb3B5IGEgc2luZ2xlIGNoYW5uZWwgZnJvbSB0aGUgYXJyYXkuXG5cdFx0ICogIEByZXR1cm4ge0FycmF5fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5CdWZmZXIucHJvdG90eXBlLnRvQXJyYXkgPSBmdW5jdGlvbiAoY2hhbm5lbCkge1xuXHQgICAgICAgIGlmIChUb25lLmlzTnVtYmVyKGNoYW5uZWwpKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLmdldENoYW5uZWxEYXRhKGNoYW5uZWwpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAodGhpcy5udW1iZXJPZkNoYW5uZWxzID09PSAxKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQXJyYXkoMCk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdmFyIHJldCA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBjID0gMDsgYyA8IHRoaXMubnVtYmVyT2ZDaGFubmVsczsgYysrKSB7XG5cdCAgICAgICAgICAgICAgICByZXRbY10gPSB0aGlzLmdldENoYW5uZWxEYXRhKGMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHJldHVybiByZXQ7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm5zIHRoZSBGbG9hdDMyQXJyYXkgcmVwcmVzZW50aW5nIHRoZSBQQ00gYXVkaW8gZGF0YSBmb3IgdGhlIHNwZWNpZmljIGNoYW5uZWwuXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIGNoYW5uZWwgIFRoZSBjaGFubmVsIG51bWJlciB0byByZXR1cm5cblx0XHQgKiAgQHJldHVybiAge0Zsb2F0MzJBcnJheX0gIFRoZSBhdWRpbyBhcyBhIFR5cGVkQXJyYXlcblx0XHQgKi9cblx0ICAgIFRvbmUuQnVmZmVyLnByb3RvdHlwZS5nZXRDaGFubmVsRGF0YSA9IGZ1bmN0aW9uIChjaGFubmVsKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5nZXRDaGFubmVsRGF0YShjaGFubmVsKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ3V0IGEgc3Vic2VjdGlvbiBvZiB0aGUgYXJyYXkgYW5kIHJldHVybiBhIGJ1ZmZlciBvZiB0aGVcblx0XHQgKiAgc3Vic2VjdGlvbi4gRG9lcyBub3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCBidWZmZXJcblx0XHQgKiAgQHBhcmFtIHtUaW1lfSBzdGFydCBUaGUgdGltZSB0byBzdGFydCB0aGUgc2xpY2Vcblx0XHQgKiAgQHBhcmFtIHtUaW1lPX0gZW5kIFRoZSBlbmQgdGltZSB0byBzbGljZS4gSWYgbm9uZSBpcyBnaXZlblxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgd2lsbCBkZWZhdWx0IHRvIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuXHRcdCAqICBAcmV0dXJuIHtUb25lLkJ1ZmZlcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gKHN0YXJ0LCBlbmQpIHtcblx0ICAgICAgICBlbmQgPSBUb25lLmRlZmF1bHRBcmcoZW5kLCB0aGlzLmR1cmF0aW9uKTtcblx0ICAgICAgICB2YXIgc3RhcnRTYW1wbGVzID0gTWF0aC5mbG9vcih0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSAqIHRoaXMudG9TZWNvbmRzKHN0YXJ0KSk7XG5cdCAgICAgICAgdmFyIGVuZFNhbXBsZXMgPSBNYXRoLmZsb29yKHRoaXMuY29udGV4dC5zYW1wbGVSYXRlICogdGhpcy50b1NlY29uZHMoZW5kKSk7XG5cdCAgICAgICAgdmFyIHJlcGxhY2VtZW50ID0gW107XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm51bWJlck9mQ2hhbm5lbHM7IGkrKykge1xuXHQgICAgICAgICAgICByZXBsYWNlbWVudFtpXSA9IHRoaXMudG9BcnJheShpKS5zbGljZShzdGFydFNhbXBsZXMsIGVuZFNhbXBsZXMpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB2YXIgcmV0QnVmZmVyID0gbmV3IFRvbmUuQnVmZmVyKCkuZnJvbUFycmF5KHJlcGxhY2VtZW50KTtcblx0ICAgICAgICByZXR1cm4gcmV0QnVmZmVyO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXZlcnNlIHRoZSBidWZmZXIuXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICogIEByZXR1cm4ge1RvbmUuQnVmZmVyfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkJ1ZmZlci5wcm90b3R5cGUuX3JldmVyc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgaWYgKHRoaXMubG9hZGVkKSB7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5udW1iZXJPZkNoYW5uZWxzOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5yZXZlcnNlLmNhbGwodGhpcy5nZXRDaGFubmVsRGF0YShpKSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogUmV2ZXJzZSB0aGUgYnVmZmVyLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkJ1ZmZlciNcblx0XHQgKiBAdHlwZSB7Qm9vbGVhbn1cblx0XHQgKiBAbmFtZSByZXZlcnNlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5CdWZmZXIucHJvdG90eXBlLCAncmV2ZXJzZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JldmVyc2VkO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocmV2KSB7XG5cdCAgICAgICAgICAgIGlmICh0aGlzLl9yZXZlcnNlZCAhPT0gcmV2KSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9yZXZlcnNlZCA9IHJldjtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3JldmVyc2UoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvLyBTVEFUSUMgTUVUSE9EU1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvL3N0YXRpY2FsbHkgaW5oZXJpdHMgRW1pdHRlciBtZXRob2RzXG5cdCAgICBUb25lLkVtaXR0ZXIubWl4aW4oVG9uZS5CdWZmZXIpO1xuXHQgICAgLyoqXG5cdFx0ICogIHRoZSBzdGF0aWMgcXVldWUgZm9yIGFsbCBvZiB0aGUgeGhyIHJlcXVlc3RzXG5cdFx0ICogIEB0eXBlIHtBcnJheX1cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuQnVmZmVyLl9kb3dubG9hZFF1ZXVlID0gW107XG5cdCAgICAvKipcblx0XHQgKiAgQSBwYXRoIHdoaWNoIGlzIHByZWZpeGVkIGJlZm9yZSBldmVyeSB1cmwuXG5cdFx0ICogIEB0eXBlICB7U3RyaW5nfVxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICovXG5cdCAgICBUb25lLkJ1ZmZlci5iYXNlVXJsID0gJyc7XG5cdCAgICAvKipcblx0XHQgKiAgQ3JlYXRlIGEgVG9uZS5CdWZmZXIgZnJvbSB0aGUgYXJyYXkuIFRvIGNyZWF0ZSBhIG11bHRpY2hhbm5lbCBBdWRpb0J1ZmZlcixcblx0XHQgKiAgcGFzcyBpbiBhIG11bHRpZGltZW5zaW9uYWwgYXJyYXkuXG5cdFx0ICogIEBwYXJhbSB7RmxvYXQzMkFycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmlsbCB0aGUgYXVkaW8gYnVmZmVyXG5cdFx0ICogIEByZXR1cm4ge1RvbmUuQnVmZmVyfSBBIFRvbmUuQnVmZmVyIGNyZWF0ZWQgZnJvbSB0aGUgYXJyYXlcblx0XHQgKi9cblx0ICAgIFRvbmUuQnVmZmVyLmZyb21BcnJheSA9IGZ1bmN0aW9uIChhcnJheSkge1xuXHQgICAgICAgIHJldHVybiBuZXcgVG9uZS5CdWZmZXIoKS5mcm9tQXJyYXkoYXJyYXkpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIENyZWF0ZXMgYSBUb25lLkJ1ZmZlciBmcm9tIGEgVVJMLCByZXR1cm5zIGEgcHJvbWlzZVxuXHRcdCAqIHdoaWNoIHJlc29sdmVzIHRvIGEgVG9uZS5CdWZmZXJcblx0XHQgKiBAcGFyYW0gIHtTdHJpbmd9IHVybCBUaGUgdXJsIHRvIGxvYWQuXG5cdFx0ICogQHJldHVybiB7UHJvbWlzZTxUb25lLkJ1ZmZlcj59ICAgICBBIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgdG8gYSBUb25lLkJ1ZmZlclxuXHRcdCAqL1xuXHQgICAgVG9uZS5CdWZmZXIuZnJvbVVybCA9IGZ1bmN0aW9uICh1cmwpIHtcblx0ICAgICAgICB2YXIgYnVmZmVyID0gbmV3IFRvbmUuQnVmZmVyKCk7XG5cdCAgICAgICAgcmV0dXJuIGJ1ZmZlci5sb2FkKHVybCkudGhlbihmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBidWZmZXI7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogUmVtb3ZlIGFuIHhociByZXF1ZXN0IGZyb20gdGhlIGRvd25sb2FkIHF1ZXVlXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuQnVmZmVyLl9yZW1vdmVGcm9tRG93bmxvYWRRdWV1ZSA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG5cdCAgICAgICAgdmFyIGluZGV4ID0gVG9uZS5CdWZmZXIuX2Rvd25sb2FkUXVldWUuaW5kZXhPZihyZXF1ZXN0KTtcblx0ICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG5cdCAgICAgICAgICAgIFRvbmUuQnVmZmVyLl9kb3dubG9hZFF1ZXVlLnNwbGljZShpbmRleCwgMSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBMb2FkcyBhIHVybCB1c2luZyBYTUxIdHRwUmVxdWVzdC5cblx0XHQgKiAgQHBhcmFtIHtTdHJpbmd9IHVybFxuXHRcdCAqICBAcGFyYW0ge0Z1bmN0aW9ufSBvbmxvYWRcblx0XHQgKiAgQHBhcmFtIHtGdW5jdGlvbn0gb25lcnJvclxuXHRcdCAqICBAcGFyYW0ge0Z1bmN0aW9ufSBvbnByb2dyZXNzXG5cdFx0ICogIEByZXR1cm4ge1hNTEh0dHBSZXF1ZXN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5CdWZmZXIubG9hZCA9IGZ1bmN0aW9uICh1cmwsIG9ubG9hZCwgb25lcnJvcikge1xuXHQgICAgICAgIC8vZGVmYXVsdFxuXHQgICAgICAgIG9ubG9hZCA9IFRvbmUuZGVmYXVsdEFyZyhvbmxvYWQsIFRvbmUubm9PcCk7XG5cdCAgICAgICAgLy8gdGVzdCBpZiB0aGUgdXJsIGNvbnRhaW5zIG11bHRpcGxlIGV4dGVuc2lvbnNcblx0ICAgICAgICB2YXIgbWF0Y2hlcyA9IHVybC5tYXRjaCgvXFxbKC4rXFx8PykrXFxdJC8pO1xuXHQgICAgICAgIGlmIChtYXRjaGVzKSB7XG5cdCAgICAgICAgICAgIHZhciBleHRlbnNpb25zID0gbWF0Y2hlc1sxXS5zcGxpdCgnfCcpO1xuXHQgICAgICAgICAgICB2YXIgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uc1swXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBleHRlbnNpb25zLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoVG9uZS5CdWZmZXIuc3VwcG9ydHNUeXBlKGV4dGVuc2lvbnNbaV0pKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uc1tpXTtcblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB1cmwgPSB1cmwucmVwbGFjZShtYXRjaGVzWzBdLCBleHRlbnNpb24pO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBmdW5jdGlvbiBvbkVycm9yKGUpIHtcblx0ICAgICAgICAgICAgVG9uZS5CdWZmZXIuX3JlbW92ZUZyb21Eb3dubG9hZFF1ZXVlKHJlcXVlc3QpO1xuXHQgICAgICAgICAgICBUb25lLkJ1ZmZlci5lbWl0KCdlcnJvcicsIGUpO1xuXHQgICAgICAgICAgICBpZiAob25lcnJvcikge1xuXHQgICAgICAgICAgICAgICAgb25lcnJvcihlKTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IGU7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgZnVuY3Rpb24gb25Qcm9ncmVzcygpIHtcblx0ICAgICAgICAgICAgLy9jYWxjdWxhdGUgdGhlIHByb2dyZXNzXG5cdCAgICAgICAgICAgIHZhciB0b3RhbFByb2dyZXNzID0gMDtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBUb25lLkJ1ZmZlci5fZG93bmxvYWRRdWV1ZS5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdG90YWxQcm9ncmVzcyArPSBUb25lLkJ1ZmZlci5fZG93bmxvYWRRdWV1ZVtpXS5wcm9ncmVzcztcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBUb25lLkJ1ZmZlci5lbWl0KCdwcm9ncmVzcycsIHRvdGFsUHJvZ3Jlc3MgLyBUb25lLkJ1ZmZlci5fZG93bmxvYWRRdWV1ZS5sZW5ndGgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB2YXIgcmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuXHQgICAgICAgIHJlcXVlc3Qub3BlbignR0VUJywgVG9uZS5CdWZmZXIuYmFzZVVybCArIHVybCwgdHJ1ZSk7XG5cdCAgICAgICAgcmVxdWVzdC5yZXNwb25zZVR5cGUgPSAnYXJyYXlidWZmZXInO1xuXHQgICAgICAgIC8vc3RhcnQgb3V0IGFzIDBcblx0ICAgICAgICByZXF1ZXN0LnByb2dyZXNzID0gMDtcblx0ICAgICAgICBUb25lLkJ1ZmZlci5fZG93bmxvYWRRdWV1ZS5wdXNoKHJlcXVlc3QpO1xuXHQgICAgICAgIHJlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHJlcXVlc3Quc3RhdHVzID09PSAyMDApIHtcblx0ICAgICAgICAgICAgICAgIFRvbmUuY29udGV4dC5kZWNvZGVBdWRpb0RhdGEocmVxdWVzdC5yZXNwb25zZSkudGhlbihmdW5jdGlvbiAoYnVmZikge1xuXHQgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QucHJvZ3Jlc3MgPSAxO1xuXHQgICAgICAgICAgICAgICAgICAgIG9uUHJvZ3Jlc3MoKTtcblx0ICAgICAgICAgICAgICAgICAgICBvbmxvYWQoYnVmZik7XG5cdCAgICAgICAgICAgICAgICAgICAgVG9uZS5CdWZmZXIuX3JlbW92ZUZyb21Eb3dubG9hZFF1ZXVlKHJlcXVlc3QpO1xuXHQgICAgICAgICAgICAgICAgICAgIGlmIChUb25lLkJ1ZmZlci5fZG93bmxvYWRRdWV1ZS5sZW5ndGggPT09IDApIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgLy9lbWl0IHRoZSBldmVudCBhdCB0aGUgZW5kXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIFRvbmUuQnVmZmVyLmVtaXQoJ2xvYWQnKTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9KS5jYXRjaChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgVG9uZS5CdWZmZXIuX3JlbW92ZUZyb21Eb3dubG9hZFF1ZXVlKHJlcXVlc3QpO1xuXHQgICAgICAgICAgICAgICAgICAgIG9uRXJyb3IoJ1RvbmUuQnVmZmVyOiBjb3VsZCBub3QgZGVjb2RlIGF1ZGlvIGRhdGE6ICcgKyB1cmwpO1xuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBvbkVycm9yKCdUb25lLkJ1ZmZlcjogY291bGQgbm90IGxvY2F0ZSBmaWxlOiAnICsgdXJsKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCBvbkVycm9yKTtcblx0ICAgICAgICByZXF1ZXN0LmFkZEV2ZW50TGlzdGVuZXIoJ3Byb2dyZXNzJywgZnVuY3Rpb24gKGV2ZW50KSB7XG5cdCAgICAgICAgICAgIGlmIChldmVudC5sZW5ndGhDb21wdXRhYmxlKSB7XG5cdCAgICAgICAgICAgICAgICAvL29ubHkgZ28gdG8gOTUlLCB0aGUgbGFzdCA1JSBpcyB3aGVuIHRoZSBhdWRpbyBpcyBkZWNvZGVkXG5cdCAgICAgICAgICAgICAgICByZXF1ZXN0LnByb2dyZXNzID0gZXZlbnQubG9hZGVkIC8gZXZlbnQudG90YWwgKiAwLjk1O1xuXHQgICAgICAgICAgICAgICAgb25Qcm9ncmVzcygpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmVxdWVzdC5zZW5kKCk7XG5cdCAgICAgICAgcmV0dXJuIHJlcXVlc3Q7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFN0b3AgYWxsIG9mIHRoZSBkb3dubG9hZHMgaW4gcHJvZ3Jlc3Ncblx0XHQgKiAgQHJldHVybiB7VG9uZS5CdWZmZXJ9XG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKi9cblx0ICAgIFRvbmUuQnVmZmVyLmNhbmNlbERvd25sb2FkcyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkJ1ZmZlci5fZG93bmxvYWRRdWV1ZS5zbGljZSgpLmZvckVhY2goZnVuY3Rpb24gKHJlcXVlc3QpIHtcblx0ICAgICAgICAgICAgVG9uZS5CdWZmZXIuX3JlbW92ZUZyb21Eb3dubG9hZFF1ZXVlKHJlcXVlc3QpO1xuXHQgICAgICAgICAgICByZXF1ZXN0LmFib3J0KCk7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIFRvbmUuQnVmZmVyO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDaGVja3MgYSB1cmwncyBleHRlbnNpb24gdG8gc2VlIGlmIHRoZSBjdXJyZW50IGJyb3dzZXIgY2FuIHBsYXkgdGhhdCBmaWxlIHR5cGUuXG5cdFx0ICogIEBwYXJhbSB7U3RyaW5nfSB1cmwgVGhlIHVybC9leHRlbnNpb24gdG8gdGVzdFxuXHRcdCAqICBAcmV0dXJuIHtCb29sZWFufSBJZiB0aGUgZmlsZSBleHRlbnNpb24gY2FuIGJlIHBsYXllZFxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogVG9uZS5CdWZmZXIuc3VwcG9ydHNUeXBlKFwid2F2XCIpOyAvL3JldHVybnMgdHJ1ZVxuXHRcdCAqIFRvbmUuQnVmZmVyLnN1cHBvcnRzVHlwZShcInBhdGgvdG8vZmlsZS53YXZcIik7IC8vcmV0dXJucyB0cnVlXG5cdFx0ICovXG5cdCAgICBUb25lLkJ1ZmZlci5zdXBwb3J0c1R5cGUgPSBmdW5jdGlvbiAodXJsKSB7XG5cdCAgICAgICAgdmFyIGV4dGVuc2lvbiA9IHVybC5zcGxpdCgnLicpO1xuXHQgICAgICAgIGV4dGVuc2lvbiA9IGV4dGVuc2lvbltleHRlbnNpb24ubGVuZ3RoIC0gMV07XG5cdCAgICAgICAgdmFyIHJlc3BvbnNlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYXVkaW8nKS5jYW5QbGF5VHlwZSgnYXVkaW8vJyArIGV4dGVuc2lvbik7XG5cdCAgICAgICAgcmV0dXJuIHJlc3BvbnNlICE9PSAnJztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJucyBhIFByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiBhbGwgb2YgdGhlIGJ1ZmZlcnMgaGF2ZSBsb2FkZWRcblx0XHQgKiAgQHJldHVybiB7UHJvbWlzZX1cblx0XHQgKi9cblx0ICAgIFRvbmUubG9hZGVkID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvbmxvYWQsIG9uZXJyb3I7XG5cdCAgICAgICAgZnVuY3Rpb24gcmVtb3ZlRXZlbnRzKCkge1xuXHQgICAgICAgICAgICAvL3JlbW92ZSB0aGUgZXZlbnRzIHdoZW4gaXQncyByZXNvbHZlZFxuXHQgICAgICAgICAgICBUb25lLkJ1ZmZlci5vZmYoJ2xvYWQnLCBvbmxvYWQpO1xuXHQgICAgICAgICAgICBUb25lLkJ1ZmZlci5vZmYoJ2Vycm9yJywgb25lcnJvcik7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoc3VjY2VzcywgZmFpbCkge1xuXHQgICAgICAgICAgICBvbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICBzdWNjZXNzKCk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIG9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICBmYWlsKCk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIC8vYWRkIHRoZSBldmVudCBsaXN0ZW5lcnNcblx0ICAgICAgICAgICAgVG9uZS5CdWZmZXIub24oJ2xvYWQnLCBvbmxvYWQpO1xuXHQgICAgICAgICAgICBUb25lLkJ1ZmZlci5vbignZXJyb3InLCBvbmVycm9yKTtcblx0ICAgICAgICB9KS50aGVuKHJlbW92ZUV2ZW50cykuY2F0Y2goZnVuY3Rpb24gKGUpIHtcblx0ICAgICAgICAgICAgcmVtb3ZlRXZlbnRzKCk7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlKTtcblx0ICAgICAgICB9KTtcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5CdWZmZXI7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgV3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBmaXJlLWFuZC1mb3JnZXQgT3NjaWxsYXRvck5vZGUuIEFkZHMgdGhlXG5cdFx0ICogICAgIGFiaWxpdHkgdG8gcmVzY2hlZHVsZSB0aGUgc3RvcCBtZXRob2QuXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkF1ZGlvTm9kZX1cblx0XHQgKiAgQHBhcmFtICB7QXVkaW9CdWZmZXJ8VG9uZS5CdWZmZXJ9ICBidWZmZXIgICBUaGUgYnVmZmVyIHRvIHBsYXlcblx0XHQgKiAgQHBhcmFtICB7RnVuY3Rpb259ICBvbmxvYWQgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIgaXMgZG9uZSBwbGF5aW5nLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5Pc2NpbGxhdG9yTm9kZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAndHlwZSdcblx0ICAgICAgICBdLCBUb25lLk9zY2lsbGF0b3JOb2RlKTtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBjYWxsYmFjayB0byBpbnZva2UgYWZ0ZXIgdGhlXG5cdFx0XHQgKiAgYnVmZmVyIHNvdXJjZSBpcyBkb25lIHBsYXlpbmcuXG5cdFx0XHQgKiAgQHR5cGUgIHtGdW5jdGlvbn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMub25lbmRlZCA9IG9wdGlvbnMub25lbmRlZDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgb3NjaWxsYXRvciBzdGFydCB0aW1lXG5cdFx0XHQgKiAgQHR5cGUgIHtOdW1iZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3N0YXJ0VGltZSA9IC0xO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBvc2NpbGxhdG9yIHN0b3AgdGltZVxuXHRcdFx0ICogIEB0eXBlICB7TnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9zdG9wVGltZSA9IC0xO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBnYWluIG5vZGUgd2hpY2ggZW52ZWxvcGVzIHRoZSBPc2NpbGxhdG9yTm9kZVxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5HYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9nYWluTm9kZSA9IHRoaXMub3V0cHV0ID0gbmV3IFRvbmUuR2FpbigpO1xuXHQgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgb3NjaWxsYXRvclxuXHRcdFx0ICogIEB0eXBlICB7T3NjaWxsYXRvck5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLmNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3IuY29ubmVjdCh0aGlzLl9nYWluTm9kZSk7XG5cdCAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBmcmVxdWVuY3kgb2YgdGhlIG9zY2lsbGF0b3Jcblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFRvbmUuUGFyYW0odGhpcy5fb3NjaWxsYXRvci5mcmVxdWVuY3ksIFRvbmUuVHlwZS5GcmVxdWVuY3kpO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5LnZhbHVlID0gb3B0aW9ucy5mcmVxdWVuY3k7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGRldHVuZSBvZiB0aGUgb3NjaWxsYXRvclxuXHRcdFx0ICogIEB0eXBlIHtGcmVxdWVuY3l9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgVG9uZS5QYXJhbSh0aGlzLl9vc2NpbGxhdG9yLmRldHVuZSwgVG9uZS5UeXBlLkNlbnRzKTtcblx0ICAgICAgICB0aGlzLmRldHVuZS52YWx1ZSA9IG9wdGlvbnMuZGV0dW5lO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSB2YWx1ZSB0aGF0IHRoZSBidWZmZXIgcmFtcHMgdG9cblx0XHRcdCAqICBAdHlwZSB7R2Fpbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZ2FpbiA9IDE7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5Pc2NpbGxhdG9yTm9kZSwgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0c1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLk9zY2lsbGF0b3JOb2RlLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdmcmVxdWVuY3knOiA0NDAsXG5cdCAgICAgICAgJ2RldHVuZSc6IDAsXG5cdCAgICAgICAgJ3R5cGUnOiAnc2luZScsXG5cdCAgICAgICAgJ29uZW5kZWQnOiBUb25lLm5vT3Bcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIG9zY2lsbGF0b3IsIGVpdGhlciBcInN0YXJ0ZWRcIiBvciBcInN0b3BwZWRcIi5cblx0XHQgKiAgQHR5cGUge1RvbmUuU3RhdGV9XG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5Pc2NpbGxhdG9yTm9kZSNcblx0XHQgKiAgQG5hbWUgc3RhdGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLk9zY2lsbGF0b3JOb2RlLnByb3RvdHlwZSwgJ3N0YXRlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRTdGF0ZUF0VGltZSh0aGlzLm5vdygpKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBHZXQgdGhlIHBsYXliYWNrIHN0YXRlIGF0IHRoZSBnaXZlbiB0aW1lXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9ICB0aW1lICBUaGUgdGltZSB0byB0ZXN0IHRoZSBzdGF0ZSBhdFxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5TdGF0ZX0gIFRoZSBwbGF5YmFjayBzdGF0ZS4gXG5cdFx0ICovXG5cdCAgICBUb25lLk9zY2lsbGF0b3JOb2RlLnByb3RvdHlwZS5nZXRTdGF0ZUF0VGltZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIGlmICh0aGlzLl9zdGFydFRpbWUgIT09IC0xICYmIHRpbWUgPj0gdGhpcy5fc3RhcnRUaW1lICYmICh0aGlzLl9zdG9wVGltZSA9PT0gLTEgfHwgdGltZSA8PSB0aGlzLl9zdG9wVGltZSkpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIFRvbmUuU3RhdGUuU3RhcnRlZDtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5TdGF0ZS5TdG9wcGVkO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0ICAgICAqIFN0YXJ0IHRoZSBvc2NpbGxhdG9yIG5vZGUgYXQgdGhlIGdpdmVuIHRpbWVcblx0ICAgICAqIEBwYXJhbSAge1RpbWU9fSB0aW1lIFdoZW4gdG8gc3RhcnQgdGhlIG9zY2lsbGF0b3Jcblx0ICAgICAqIEByZXR1cm4ge09zY2lsbGF0b3JOb2RlfSAgICAgIHRoaXNcblx0ICAgICAqL1xuXHQgICAgVG9uZS5Pc2NpbGxhdG9yTm9kZS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIGlmICh0aGlzLl9zdGFydFRpbWUgPT09IC0xKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3N0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0YXJ0KHRoaXMuX3N0YXJ0VGltZSk7XG5cdCAgICAgICAgICAgIHZhciBub3cgPSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XG5cdCAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKG5vdyk7XG5cdCAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgbm93KTtcblx0ICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCB0aGlzLl9zdGFydFRpbWUpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGNhbGwgT3NjaWxsYXRvck5vZGUuc3RhcnQgbW9yZSB0aGFuIG9uY2UnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdCAgICAgKiBTZXRzIGFuIGFyYml0cmFyeSBjdXN0b20gcGVyaW9kaWMgd2F2ZWZvcm0gZ2l2ZW4gYSBQZXJpb2RpY1dhdmUuXG5cdCAgICAgKiBAcGFyYW0gIHtQZXJpb2RpY1dhdmV9IHBlcmlvZGljV2F2ZSBQZXJpb2RpY1dhdmUgc2hvdWxkIGJlIGNyZWF0ZWQgd2l0aCBjb250ZXh0LmNyZWF0ZVBlcmlvZGljV2F2ZVxuXHQgICAgICogQHJldHVybiB7T3NjaWxsYXRvck5vZGV9IHRoaXNcblx0ICAgICAqL1xuXHQgICAgVG9uZS5Pc2NpbGxhdG9yTm9kZS5wcm90b3R5cGUuc2V0UGVyaW9kaWNXYXZlID0gZnVuY3Rpb24gKHBlcmlvZGljV2F2ZSkge1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc2V0UGVyaW9kaWNXYXZlKHBlcmlvZGljV2F2ZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdCAgICAgKiBTdG9wIHRoZSBvc2NpbGxhdG9yIG5vZGUgYXQgdGhlIGdpdmVuIHRpbWVcblx0ICAgICAqIEBwYXJhbSAge1RpbWU9fSB0aW1lIFdoZW4gdG8gc3RvcCB0aGUgb3NjaWxsYXRvclxuXHQgICAgICogQHJldHVybiB7T3NjaWxsYXRvck5vZGV9ICAgICAgdGhpc1xuXHQgICAgICovXG5cdCAgICBUb25lLk9zY2lsbGF0b3JOb2RlLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICAvL2NhbmNlbCB0aGUgcHJldmlvdXMgc3RvcFxuXHQgICAgICAgIHRoaXMuY2FuY2VsU3RvcCgpO1xuXHQgICAgICAgIC8vcmVzY2hlZHVsZSBpdFxuXHQgICAgICAgIHRoaXMuX3N0b3BUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgwLCB0aGlzLl9zdG9wVGltZSk7XG5cdCAgICAgICAgdGhpcy5jb250ZXh0LmNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0KTtcblx0ICAgICAgICB0aGlzLl90aW1lb3V0ID0gdGhpcy5jb250ZXh0LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0b3AodGhpcy5ub3coKSk7XG5cdCAgICAgICAgICAgIHRoaXMub25lbmRlZCgpO1xuXHQgICAgICAgIH0uYmluZCh0aGlzKSwgdGhpcy5fc3RvcFRpbWUgLSB0aGlzLm5vdygpKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2FuY2VsIGEgc2NoZWR1bGVkIHN0b3AgZXZlbnRcblx0XHQgKiAgQHJldHVybiAge1RvbmUuT3NjaWxsYXRvck5vZGV9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk9zY2lsbGF0b3JOb2RlLnByb3RvdHlwZS5jYW5jZWxTdG9wID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGlmICh0aGlzLl9zdGFydFRpbWUgIT09IC0xKSB7XG5cdCAgICAgICAgICAgIC8vY2FuY2VsIHRoZSBzdG9wIGVudmVsb3BlXG5cdCAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRoaXMuX3N0YXJ0VGltZSArIHRoaXMuc2FtcGxlVGltZSk7XG5cdCAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMSwgTWF0aC5tYXgodGhpcy5ub3coKSwgdGhpcy5fc3RhcnRUaW1lKSk7XG5cdCAgICAgICAgICAgIHRoaXMuY29udGV4dC5jbGVhclRpbWVvdXQodGhpcy5fdGltZW91dCk7XG5cdCAgICAgICAgICAgIHRoaXMuX3N0b3BUaW1lID0gLTE7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBvc2NpbGxhdG9yIHR5cGUuIEVpdGhlciAnc2luZScsICdzYXd0b290aCcsICdzcXVhcmUnLCBvciAndHJpYW5nbGUnXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuT3NjaWxsYXRvck5vZGUjXG5cdFx0ICogQHR5cGUge1RpbWV9XG5cdFx0ICogQG5hbWUgdHlwZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuT3NjaWxsYXRvck5vZGUucHJvdG90eXBlLCAndHlwZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IudHlwZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHR5cGUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybiAge1RvbmUuT3NjaWxsYXRvck5vZGV9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk9zY2lsbGF0b3JOb2RlLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuY29udGV4dC5jbGVhclRpbWVvdXQodGhpcy5fdGltZW91dCk7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLm9uZW5kZWQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3IuZGlzY29ubmVjdCgpO1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9nYWluTm9kZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLk9zY2lsbGF0b3JOb2RlO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5Pc2NpbGxhdG9yIHN1cHBvcnRzIGEgbnVtYmVyIG9mIGZlYXR1cmVzIGluY2x1ZGluZ1xuXHRcdCAqICAgICAgICAgcGhhc2Ugcm90YXRpb24sIG11bHRpcGxlIG9zY2lsbGF0b3IgdHlwZXMgKHNlZSBUb25lLk9zY2lsbGF0b3IudHlwZSksXG5cdFx0ICogICAgICAgICBhbmQgVHJhbnNwb3J0IHN5bmNpbmcgKHNlZSBUb25lLk9zY2lsbGF0b3Iuc3luY0ZyZXF1ZW5jeSkuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlNvdXJjZX1cblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l9IFtmcmVxdWVuY3ldIFN0YXJ0aW5nIGZyZXF1ZW5jeVxuXHRcdCAqICBAcGFyYW0ge3N0cmluZ30gW3R5cGVdIFRoZSBvc2NpbGxhdG9yIHR5cGUuIFJlYWQgbW9yZSBhYm91dCB0eXBlIGJlbG93LlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vbWFrZSBhbmQgc3RhcnQgYSA0NDBoeiBzaW5lIHRvbmVcblx0XHQgKiB2YXIgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcig0NDAsIFwic2luZVwiKS50b01hc3RlcigpLnN0YXJ0KCk7XG5cdFx0ICovXG5cdCAgICBUb25lLk9zY2lsbGF0b3IgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ3R5cGUnXG5cdCAgICAgICAgXSwgVG9uZS5Pc2NpbGxhdG9yKTtcblx0ICAgICAgICBUb25lLlNvdXJjZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBtYWluIG9zY2lsbGF0b3Jcblx0XHRcdCAqICBAdHlwZSB7T3NjaWxsYXRvck5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSBudWxsO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBmcmVxdWVuY3kgY29udHJvbC5cblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFRvbmUuU2lnbmFsKG9wdGlvbnMuZnJlcXVlbmN5LCBUb25lLlR5cGUuRnJlcXVlbmN5KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZGV0dW5lIGNvbnRyb2wgc2lnbmFsLlxuXHRcdFx0ICogIEB0eXBlIHtDZW50c31cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLmRldHVuZSwgVG9uZS5UeXBlLkNlbnRzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgcGVyaW9kaWMgd2F2ZVxuXHRcdFx0ICogIEB0eXBlIHtQZXJpb2RpY1dhdmV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3dhdmUgPSBudWxsO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBwYXJ0aWFscyBvZiB0aGUgb3NjaWxsYXRvclxuXHRcdFx0ICogIEB0eXBlIHtBcnJheX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBUb25lLmRlZmF1bHRBcmcob3B0aW9ucy5wYXJ0aWFscywgWzFdKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgcGhhc2Ugb2YgdGhlIG9zY2lsbGF0b3Jcblx0XHRcdCAqICBiZXR3ZWVuIDAgLSAzNjBcblx0XHRcdCAqICBAdHlwZSB7bnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9waGFzZSA9IG9wdGlvbnMucGhhc2U7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3Jcblx0XHRcdCAqICBAdHlwZSB7c3RyaW5nfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl90eXBlID0gbnVsbDtcblx0ICAgICAgICAvL3NldHVwXG5cdCAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuXHQgICAgICAgIHRoaXMucGhhc2UgPSB0aGlzLl9waGFzZTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnZGV0dW5lJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuT3NjaWxsYXRvciwgVG9uZS5Tb3VyY2UpO1xuXHQgICAgLyoqXG5cdFx0ICogIHRoZSBkZWZhdWx0IHBhcmFtZXRlcnNcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuT3NjaWxsYXRvci5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAndHlwZSc6ICdzaW5lJyxcblx0ICAgICAgICAnZnJlcXVlbmN5JzogNDQwLFxuXHQgICAgICAgICdkZXR1bmUnOiAwLFxuXHQgICAgICAgICdwaGFzZSc6IDAsXG5cdCAgICAgICAgJ3BhcnRpYWxzJzogW11cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIE9zY2lsbGF0b3IgdHlwZXNcblx0XHQgKiAgQGVudW0ge1N0cmluZ31cblx0XHQgKi9cblx0ICAgIFRvbmUuT3NjaWxsYXRvci5UeXBlID0ge1xuXHQgICAgICAgIFNpbmU6ICdzaW5lJyxcblx0ICAgICAgICBUcmlhbmdsZTogJ3RyaWFuZ2xlJyxcblx0ICAgICAgICBTYXd0b290aDogJ3Nhd3Rvb3RoJyxcblx0ICAgICAgICBTcXVhcmU6ICdzcXVhcmUnLFxuXHQgICAgICAgIEN1c3RvbTogJ2N1c3RvbSdcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgc3RhcnQgdGhlIG9zY2lsbGF0b3Jcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gW3RpbWU9bm93XVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Pc2NpbGxhdG9yLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIC8vbmV3IG9zY2lsbGF0b3Igd2l0aCBwcmV2aW91cyB2YWx1ZXNcblx0ICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvck5vZGUoKTtcblx0ICAgICAgICBpZiAodGhpcy5fd2F2ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnNldFBlcmlvZGljV2F2ZSh0aGlzLl93YXZlKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0aGlzLl90eXBlO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL2Nvbm5lY3QgdGhlIGNvbnRyb2wgc2lnbmFsIHRvIHRoZSBvc2NpbGxhdG9yIGZyZXF1ZW5jeSAmIGRldHVuZVxuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3IuY29ubmVjdCh0aGlzLm91dHB1dCk7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLmRldHVuZSk7XG5cdCAgICAgICAgLy9zdGFydCB0aGUgb3NjaWxsYXRvclxuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0YXJ0KHRpbWUpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBzdG9wIHRoZSBvc2NpbGxhdG9yXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IFt0aW1lPW5vd10gKG9wdGlvbmFsKSB0aW1pbmcgcGFyYW1ldGVyXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk9zY2lsbGF0b3J9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuT3NjaWxsYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yKSB7XG5cdCAgICAgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdG9wKHRpbWUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBSZXN0YXJ0IHRoZSBvc2NpbGxhdG9yLiBEb2VzIG5vdCBzdG9wIHRoZSBvc2NpbGxhdG9yLCBidXQgaW5zdGVhZFxuXHRcdCAqIGp1c3QgY2FuY2VscyBhbnkgc2NoZWR1bGVkICdzdG9wJyBmcm9tIGJlaW5nIGludm9rZWQuXG5cdFx0ICogQHBhcmFtICB7VGltZT19IHRpbWVcblx0XHQgKiBAcmV0dXJuIHtUb25lLk9zY2lsbGF0b3J9ICAgICAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Pc2NpbGxhdG9yLnByb3RvdHlwZS5yZXN0YXJ0ID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNhbmNlbFN0b3AoKTtcblx0ICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGhpcy50b1NlY29uZHModGltZSkpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTeW5jIHRoZSBzaWduYWwgdG8gdGhlIFRyYW5zcG9ydCdzIGJwbS4gQW55IGNoYW5nZXMgdG8gdGhlIHRyYW5zcG9ydHMgYnBtLFxuXHRcdCAqICB3aWxsIGFsc28gYWZmZWN0IHRoZSBvc2NpbGxhdG9ycyBmcmVxdWVuY3kuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk9zY2lsbGF0b3J9IHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBUb25lLlRyYW5zcG9ydC5icG0udmFsdWUgPSAxMjA7XG5cdFx0ICogb3NjLmZyZXF1ZW5jeS52YWx1ZSA9IDQ0MDtcblx0XHQgKiAvL3RoZSByYXRpb24gYmV0d2VlbiB0aGUgYnBtIGFuZCB0aGUgZnJlcXVlbmN5IHdpbGwgYmUgbWFpbnRhaW5lZFxuXHRcdCAqIG9zYy5zeW5jRnJlcXVlbmN5KCk7XG5cdFx0ICogVG9uZS5UcmFuc3BvcnQuYnBtLnZhbHVlID0gMjQwO1xuXHRcdCAqIC8vIHRoZSBmcmVxdWVuY3kgb2YgdGhlIG9zY2lsbGF0b3IgaXMgZG91YmxlZCB0byA4ODBcblx0XHQgKi9cblx0ICAgIFRvbmUuT3NjaWxsYXRvci5wcm90b3R5cGUuc3luY0ZyZXF1ZW5jeSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlRyYW5zcG9ydC5zeW5jU2lnbmFsKHRoaXMuZnJlcXVlbmN5KTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVW5zeW5jIHRoZSBvc2NpbGxhdG9yJ3MgZnJlcXVlbmN5IGZyb20gdGhlIFRyYW5zcG9ydC5cblx0XHQgKiAgU2VlIFRvbmUuT3NjaWxsYXRvci5zeW5jRnJlcXVlbmN5XG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk9zY2lsbGF0b3J9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuT3NjaWxsYXRvci5wcm90b3R5cGUudW5zeW5jRnJlcXVlbmN5ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuVHJhbnNwb3J0LnVuc3luY1NpZ25hbCh0aGlzLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3I6IGVpdGhlciBzaW5lLCBzcXVhcmUsIHRyaWFuZ2xlLCBvciBzYXd0b290aC4gQWxzbyBjYXBhYmxlIG9mXG5cdFx0ICogc2V0dGluZyB0aGUgZmlyc3QgeCBudW1iZXIgb2YgcGFydGlhbHMgb2YgdGhlIG9zY2lsbGF0b3IuIEZvciBleGFtcGxlOiBcInNpbmU0XCIgd291bGRcblx0XHQgKiBzZXQgYmUgdGhlIGZpcnN0IDQgcGFydGlhbHMgb2YgdGhlIHNpbmUgd2F2ZSBhbmQgXCJ0cmlhbmdsZThcIiB3b3VsZCBzZXQgdGhlIGZpcnN0XG5cdFx0ICogOCBwYXJ0aWFscyBvZiB0aGUgdHJpYW5nbGUgd2F2ZS5cblx0XHQgKiA8YnI+PGJyPlxuXHRcdCAqIFVzZXMgUGVyaW9kaWNXYXZlIGludGVybmFsbHkgZXZlbiBmb3IgbmF0aXZlIHR5cGVzIHNvIHRoYXQgaXQgY2FuIHNldCB0aGUgcGhhc2UuXG5cdFx0ICogUGVyaW9kaWNXYXZlIGVxdWF0aW9ucyBhcmUgZnJvbSB0aGVcblx0XHQgKiBbV2Via2l0IFdlYiBBdWRpbyBpbXBsZW1lbnRhdGlvbl0oaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jaHJvbWl1bS9jb2Rlc2VhcmNoI2Nocm9taXVtL3NyYy90aGlyZF9wYXJ0eS9XZWJLaXQvU291cmNlL21vZHVsZXMvd2ViYXVkaW8vUGVyaW9kaWNXYXZlLmNwcCZzcT1wYWNrYWdlOmNocm9taXVtKS5cblx0XHQgKlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLk9zY2lsbGF0b3IjXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAbmFtZSB0eXBlXG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiAvL3NldCBpdCB0byBhIHNxdWFyZSB3YXZlXG5cdFx0ICogb3NjLnR5cGUgPSBcInNxdWFyZVwiO1xuXHRcdCAqIEBleGFtcGxlXG5cdFx0ICogLy9zZXQgdGhlIGZpcnN0IDYgcGFydGlhbHMgb2YgYSBzYXd0b290aCB3YXZlXG5cdFx0ICogb3NjLnR5cGUgPSBcInNhd3Rvb3RoNlwiO1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuT3NjaWxsYXRvci5wcm90b3R5cGUsICd0eXBlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHR5cGUpIHtcblx0ICAgICAgICAgICAgdmFyIGlzQmFzaWNUeXBlID0gW1xuXHQgICAgICAgICAgICAgICAgVG9uZS5Pc2NpbGxhdG9yLlR5cGUuU2luZSxcblx0ICAgICAgICAgICAgICAgIFRvbmUuT3NjaWxsYXRvci5UeXBlLlNxdWFyZSxcblx0ICAgICAgICAgICAgICAgIFRvbmUuT3NjaWxsYXRvci5UeXBlLlRyaWFuZ2xlLFxuXHQgICAgICAgICAgICAgICAgVG9uZS5Pc2NpbGxhdG9yLlR5cGUuU2F3dG9vdGhcblx0ICAgICAgICAgICAgXS5pbmNsdWRlcyh0eXBlKTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3BoYXNlID09PSAwICYmIGlzQmFzaWNUeXBlKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl93YXZlID0gbnVsbDtcblx0ICAgICAgICAgICAgICAgIC8vanVzdCBnbyB3aXRoIHRoZSBiYXNpYyBhcHByb2FjaFxuXHQgICAgICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPT09IHR5cGU7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgY29lZnMgPSB0aGlzLl9nZXRSZWFsSW1hZ2luYXJ5KHR5cGUsIHRoaXMuX3BoYXNlKTtcblx0ICAgICAgICAgICAgICAgIHZhciBwZXJpb2RpY1dhdmUgPSB0aGlzLmNvbnRleHQuY3JlYXRlUGVyaW9kaWNXYXZlKGNvZWZzWzBdLCBjb2Vmc1sxXSk7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl93YXZlID0gcGVyaW9kaWNXYXZlO1xuXHQgICAgICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnNldFBlcmlvZGljV2F2ZSh0aGlzLl93YXZlKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm5zIHRoZSByZWFsIGFuZCBpbWFnaW5hcnkgY29tcG9uZW50cyBiYXNlZFxuXHRcdCAqICBvbiB0aGUgb3NjaWxsYXRvciB0eXBlLlxuXHRcdCAqICBAcmV0dXJucyB7QXJyYXl9IFtyZWFsLCBpbWFnaW5hcnldXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLk9zY2lsbGF0b3IucHJvdG90eXBlLl9nZXRSZWFsSW1hZ2luYXJ5ID0gZnVuY3Rpb24gKHR5cGUsIHBoYXNlKSB7XG5cdCAgICAgICAgdmFyIGZmdFNpemUgPSA0MDk2O1xuXHQgICAgICAgIHZhciBwZXJpb2RpY1dhdmVTaXplID0gZmZ0U2l6ZSAvIDI7XG5cdCAgICAgICAgdmFyIHJlYWwgPSBuZXcgRmxvYXQzMkFycmF5KHBlcmlvZGljV2F2ZVNpemUpO1xuXHQgICAgICAgIHZhciBpbWFnID0gbmV3IEZsb2F0MzJBcnJheShwZXJpb2RpY1dhdmVTaXplKTtcblx0ICAgICAgICB2YXIgcGFydGlhbENvdW50ID0gMTtcblx0ICAgICAgICBpZiAodHlwZSA9PT0gVG9uZS5Pc2NpbGxhdG9yLlR5cGUuQ3VzdG9tKSB7XG5cdCAgICAgICAgICAgIHBhcnRpYWxDb3VudCA9IHRoaXMuX3BhcnRpYWxzLmxlbmd0aCArIDE7XG5cdCAgICAgICAgICAgIHBlcmlvZGljV2F2ZVNpemUgPSBwYXJ0aWFsQ291bnQ7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdmFyIHBhcnRpYWwgPSAvXihzaW5lfHRyaWFuZ2xlfHNxdWFyZXxzYXd0b290aCkoXFxkKykkLy5leGVjKHR5cGUpO1xuXHQgICAgICAgICAgICBpZiAocGFydGlhbCkge1xuXHQgICAgICAgICAgICAgICAgcGFydGlhbENvdW50ID0gcGFyc2VJbnQocGFydGlhbFsyXSkgKyAxO1xuXHQgICAgICAgICAgICAgICAgdHlwZSA9IHBhcnRpYWxbMV07XG5cdCAgICAgICAgICAgICAgICBwYXJ0aWFsQ291bnQgPSBNYXRoLm1heChwYXJ0aWFsQ291bnQsIDIpO1xuXHQgICAgICAgICAgICAgICAgcGVyaW9kaWNXYXZlU2l6ZSA9IHBhcnRpYWxDb3VudDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBmb3IgKHZhciBuID0gMTsgbiA8IHBlcmlvZGljV2F2ZVNpemU7ICsrbikge1xuXHQgICAgICAgICAgICB2YXIgcGlGYWN0b3IgPSAyIC8gKG4gKiBNYXRoLlBJKTtcblx0ICAgICAgICAgICAgdmFyIGI7XG5cdCAgICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuXHQgICAgICAgICAgICBjYXNlIFRvbmUuT3NjaWxsYXRvci5UeXBlLlNpbmU6XG5cdCAgICAgICAgICAgICAgICBiID0gbiA8PSBwYXJ0aWFsQ291bnQgPyAxIDogMDtcblx0ICAgICAgICAgICAgICAgIGJyZWFrO1xuXHQgICAgICAgICAgICBjYXNlIFRvbmUuT3NjaWxsYXRvci5UeXBlLlNxdWFyZTpcblx0ICAgICAgICAgICAgICAgIGIgPSBuICYgMSA/IDIgKiBwaUZhY3RvciA6IDA7XG5cdCAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgY2FzZSBUb25lLk9zY2lsbGF0b3IuVHlwZS5TYXd0b290aDpcblx0ICAgICAgICAgICAgICAgIGIgPSBwaUZhY3RvciAqIChuICYgMSA/IDEgOiAtMSk7XG5cdCAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgY2FzZSBUb25lLk9zY2lsbGF0b3IuVHlwZS5UcmlhbmdsZTpcblx0ICAgICAgICAgICAgICAgIGlmIChuICYgMSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGIgPSAyICogKHBpRmFjdG9yICogcGlGYWN0b3IpICogKG4gLSAxID4+IDEgJiAxID8gLTEgOiAxKTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgYiA9IDA7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgY2FzZSBUb25lLk9zY2lsbGF0b3IuVHlwZS5DdXN0b206XG5cdCAgICAgICAgICAgICAgICBiID0gdGhpcy5fcGFydGlhbHNbbiAtIDFdO1xuXHQgICAgICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgICAgIGRlZmF1bHQ6XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUb25lLk9zY2lsbGF0b3I6IGludmFsaWQgdHlwZTogJyArIHR5cGUpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChiICE9PSAwKSB7XG5cdCAgICAgICAgICAgICAgICByZWFsW25dID0gLWIgKiBNYXRoLnNpbihwaGFzZSAqIG4pO1xuXHQgICAgICAgICAgICAgICAgaW1hZ1tuXSA9IGIgKiBNYXRoLmNvcyhwaGFzZSAqIG4pO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmVhbFtuXSA9IDA7XG5cdCAgICAgICAgICAgICAgICBpbWFnW25dID0gMDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gW1xuXHQgICAgICAgICAgICByZWFsLFxuXHQgICAgICAgICAgICBpbWFnXG5cdCAgICAgICAgXTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ29tcHV0ZSB0aGUgaW52ZXJzZSBGRlQgZm9yIGEgZ2l2ZW4gcGhhc2UuXG5cdFx0ICogIEBwYXJhbSAge0Zsb2F0MzJBcnJheX0gIHJlYWxcblx0XHQgKiAgQHBhcmFtICB7RmxvYXQzMkFycmF5fSAgaW1hZ1xuXHRcdCAqICBAcGFyYW0gIHtOb3JtYWxSYW5nZX0gIHBoYXNlXG5cdFx0ICogIEByZXR1cm4gIHtBdWRpb1JhbmdlfVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Pc2NpbGxhdG9yLnByb3RvdHlwZS5faW52ZXJzZUZGVCA9IGZ1bmN0aW9uIChyZWFsLCBpbWFnLCBwaGFzZSkge1xuXHQgICAgICAgIHZhciBzdW0gPSAwO1xuXHQgICAgICAgIHZhciBsZW4gPSByZWFsLmxlbmd0aDtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdCAgICAgICAgICAgIHN1bSArPSByZWFsW2ldICogTWF0aC5jb3MoaSAqIHBoYXNlKSArIGltYWdbaV0gKiBNYXRoLnNpbihpICogcGhhc2UpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gc3VtO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm5zIHRoZSBpbml0aWFsIHZhbHVlIG9mIHRoZSBvc2NpbGxhdG9yLlxuXHRcdCAqICBAcmV0dXJuICB7QXVkaW9SYW5nZX1cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuT3NjaWxsYXRvci5wcm90b3R5cGUuX2dldEluaXRpYWxWYWx1ZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgY29lZnMgPSB0aGlzLl9nZXRSZWFsSW1hZ2luYXJ5KHRoaXMuX3R5cGUsIDApO1xuXHQgICAgICAgIHZhciByZWFsID0gY29lZnNbMF07XG5cdCAgICAgICAgdmFyIGltYWcgPSBjb2Vmc1sxXTtcblx0ICAgICAgICB2YXIgbWF4VmFsdWUgPSAwO1xuXHQgICAgICAgIHZhciB0d29QaSA9IE1hdGguUEkgKiAyO1xuXHQgICAgICAgIC8vY2hlY2sgZm9yIHBlYWtzIGluIDggcGxhY2VzXG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4OyBpKyspIHtcblx0ICAgICAgICAgICAgbWF4VmFsdWUgPSBNYXRoLm1heCh0aGlzLl9pbnZlcnNlRkZUKHJlYWwsIGltYWcsIGkgLyA4ICogdHdvUGkpLCBtYXhWYWx1ZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiAtdGhpcy5faW52ZXJzZUZGVChyZWFsLCBpbWFnLCB0aGlzLl9waGFzZSkgLyBtYXhWYWx1ZTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcGFydGlhbHMgb2YgdGhlIHdhdmVmb3JtLiBBIHBhcnRpYWwgcmVwcmVzZW50c1xuXHRcdCAqIHRoZSBhbXBsaXR1ZGUgYXQgYSBoYXJtb25pYy4gVGhlIGZpcnN0IGhhcm1vbmljIGlzIHRoZVxuXHRcdCAqIGZ1bmRhbWVudGFsIGZyZXF1ZW5jeSwgdGhlIHNlY29uZCBpcyB0aGUgb2N0YXZlIGFuZCBzbyBvblxuXHRcdCAqIGZvbGxvd2luZyB0aGUgaGFybW9uaWMgc2VyaWVzLlxuXHRcdCAqIFNldHRpbmcgdGhpcyB2YWx1ZSB3aWxsIGF1dG9tYXRpY2FsbHkgc2V0IHRoZSB0eXBlIHRvIFwiY3VzdG9tXCIuXG5cdFx0ICogVGhlIHZhbHVlIGlzIGFuIGVtcHR5IGFycmF5IHdoZW4gdGhlIHR5cGUgaXMgbm90IFwiY3VzdG9tXCIuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuT3NjaWxsYXRvciNcblx0XHQgKiBAdHlwZSB7QXJyYXl9XG5cdFx0ICogQG5hbWUgcGFydGlhbHNcblx0XHQgKiBAZXhhbXBsZVxuXHRcdCAqIG9zYy5wYXJ0aWFscyA9IFsxLCAwLjIsIDAuMDFdO1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuT3NjaWxsYXRvci5wcm90b3R5cGUsICdwYXJ0aWFscycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3R5cGUgIT09IFRvbmUuT3NjaWxsYXRvci5UeXBlLkN1c3RvbSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnRpYWxzO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwYXJ0aWFscykge1xuXHQgICAgICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IHBhcnRpYWxzO1xuXHQgICAgICAgICAgICB0aGlzLnR5cGUgPSBUb25lLk9zY2lsbGF0b3IuVHlwZS5DdXN0b207XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcGhhc2Ugb2YgdGhlIG9zY2lsbGF0b3IgaW4gZGVncmVlcy5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5Pc2NpbGxhdG9yI1xuXHRcdCAqIEB0eXBlIHtEZWdyZWVzfVxuXHRcdCAqIEBuYW1lIHBoYXNlXG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiBvc2MucGhhc2UgPSAxODA7IC8vZmxpcHMgdGhlIHBoYXNlIG9mIHRoZSBvc2NpbGxhdG9yXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5Pc2NpbGxhdG9yLnByb3RvdHlwZSwgJ3BoYXNlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fcGhhc2UgKiAoMTgwIC8gTWF0aC5QSSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwaGFzZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9waGFzZSA9IHBoYXNlICogTWF0aC5QSSAvIDE4MDtcblx0ICAgICAgICAgICAgLy9yZXNldCB0aGUgdHlwZVxuXHQgICAgICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLl90eXBlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIERpc3Bvc2UgYW5kIGRpc2Nvbm5lY3QuXG5cdFx0ICogIEByZXR1cm4ge1RvbmUuT3NjaWxsYXRvcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Pc2NpbGxhdG9yLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuU291cmNlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5kaXNwb3NlKCk7XG5cdCAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl93YXZlID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnZGV0dW5lJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZGV0dW5lID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuT3NjaWxsYXRvcjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIEF1ZGlvVG9HYWluIGNvbnZlcnRzIGFuIGlucHV0IGluIEF1ZGlvUmFuZ2UgWy0xLDFdIHRvIE5vcm1hbFJhbmdlIFswLDFdLiBcblx0XHQgKiAgICAgICAgIFNlZSBUb25lLkdhaW5Ub0F1ZGlvLlxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlNpZ25hbEJhc2V9XG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqICB2YXIgYTJnID0gbmV3IFRvbmUuQXVkaW9Ub0dhaW4oKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuQXVkaW9Ub0dhaW4gPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWxCYXNlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQHR5cGUge1dhdmVTaGFwZXJOb2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9ub3JtID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gbmV3IFRvbmUuV2F2ZVNoYXBlcihmdW5jdGlvbiAoeCkge1xuXHQgICAgICAgICAgICByZXR1cm4gKHggKyAxKSAvIDI7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5BdWRpb1RvR2FpbiwgVG9uZS5TaWduYWxCYXNlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBjbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5BdWRpb1RvR2Fpbn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5BdWRpb1RvR2Fpbi5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9ub3JtLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9ub3JtID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5BdWRpb1RvR2Fpbjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBUb25lLlplcm8gb3V0cHV0cyAwJ3MgYXQgYXVkaW8tcmF0ZS4gVGhlIHJlYXNvbiB0aGlzIGhhcyB0byBiZVxuXHRcdCAqICAgICAgICAgaXQncyBvd24gY2xhc3MgaXMgdGhhdCBtYW55IGJyb3dzZXJzIG9wdGltaXplIG91dCBUb25lLlNpZ25hbFxuXHRcdCAqICAgICAgICAgd2l0aCBhIHZhbHVlIG9mIDAgYW5kIHdpbGwgbm90IHByb2Nlc3Mgbm9kZXMgZnVydGhlciBkb3duIHRoZSBncmFwaC5cblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuU2lnbmFsQmFzZX1cblx0XHQgKi9cblx0ICAgIFRvbmUuWmVybyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZ2FpbiBub2RlXG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLkdhaW59XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2dhaW4gPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZS5HYWluKCk7XG5cdCAgICAgICAgdGhpcy5jb250ZXh0LmdldENvbnN0YW50KDApLmNvbm5lY3QodGhpcy5fZ2Fpbik7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5aZXJvLCBUb25lLlNpZ25hbEJhc2UpO1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLlplcm99ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlplcm8ucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWxCYXNlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fZ2Fpbi5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fZ2FpbiA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuWmVybztcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBMRk8gc3RhbmRzIGZvciBsb3cgZnJlcXVlbmN5IG9zY2lsbGF0b3IuIFRvbmUuTEZPIHByb2R1Y2VzIGFuIG91dHB1dCBzaWduYWxcblx0XHQgKiAgICAgICAgICB3aGljaCBjYW4gYmUgYXR0YWNoZWQgdG8gYW4gQXVkaW9QYXJhbSBvciBUb25lLlNpZ25hbFxuXHRcdCAqICAgICAgICAgIGluIG9yZGVyIHRvIG1vZHVsYXRlIHRoYXQgcGFyYW1ldGVyIHdpdGggYW4gb3NjaWxsYXRvci4gVGhlIExGTyBjYW5cblx0XHQgKiAgICAgICAgICBhbHNvIGJlIHN5bmNlZCB0byB0aGUgdHJhbnNwb3J0IHRvIHN0YXJ0L3N0b3AgYW5kIGNoYW5nZSB3aGVuIHRoZSB0ZW1wbyBjaGFuZ2VzLlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBwYXJhbSB7RnJlcXVlbmN5fE9iamVjdH0gW2ZyZXF1ZW5jeV0gVGhlIGZyZXF1ZW5jeSBvZiB0aGUgb3NjaWxsYXRpb24uIFR5cGljYWxseSwgTEZPcyB3aWxsIGJlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gdGhlIGZyZXF1ZW5jeSByYW5nZSBvZiAwLjEgdG8gMTAgaGVydHouXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyPX0gbWluIFRoZSBtaW5pbXVtIG91dHB1dCB2YWx1ZSBvZiB0aGUgTEZPLlxuXHRcdCAqICBAcGFyYW0ge251bWJlcj19IG1heCBUaGUgbWF4aW11bSB2YWx1ZSBvZiB0aGUgTEZPLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBsZm8gPSBuZXcgVG9uZS5MRk8oXCI0blwiLCA0MDAsIDQwMDApO1xuXHRcdCAqIGxmby5jb25uZWN0KGZpbHRlci5mcmVxdWVuY3kpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5MRk8gPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ21pbicsXG5cdCAgICAgICAgICAgICdtYXgnXG5cdCAgICAgICAgXSwgVG9uZS5MRk8pO1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG9zY2lsbGF0b3IuXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuT3NjaWxsYXRvcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3Ioe1xuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jzogb3B0aW9ucy5mcmVxdWVuY3ksXG5cdCAgICAgICAgICAgICd0eXBlJzogb3B0aW9ucy50eXBlXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGxmbydzIGZyZXF1ZW5jeVxuXHRcdFx0ICogIEB0eXBlIHtGcmVxdWVuY3l9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9vc2NpbGxhdG9yLmZyZXF1ZW5jeTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBhbXBsaXR1ZGUgb2YgdGhlIExGTywgd2hpY2ggY29udHJvbHMgdGhlIG91dHB1dCByYW5nZSBiZXR3ZWVuXG5cdFx0XHQgKiB0aGUgbWluIGFuZCBtYXggb3V0cHV0LiBGb3IgZXhhbXBsZSBpZiB0aGUgbWluIGlzIC0xMCBhbmQgdGhlIG1heFxuXHRcdFx0ICogaXMgMTAsIHNldHRpbmcgdGhlIGFtcGxpdHVkZSB0byAwLjUgd291bGQgbWFrZSB0aGUgTEZPIG1vZHVsYXRlXG5cdFx0XHQgKiBiZXR3ZWVuIC01IGFuZCA1LlxuXHRcdFx0ICogQHR5cGUge051bWJlcn1cblx0XHRcdCAqIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuYW1wbGl0dWRlID0gdGhpcy5fb3NjaWxsYXRvci52b2x1bWU7XG5cdCAgICAgICAgdGhpcy5hbXBsaXR1ZGUudW5pdHMgPSBUb25lLlR5cGUuTm9ybWFsUmFuZ2U7XG5cdCAgICAgICAgdGhpcy5hbXBsaXR1ZGUudmFsdWUgPSBvcHRpb25zLmFtcGxpdHVkZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgc2lnbmFsIHdoaWNoIGlzIG91dHB1dCB3aGVuIHRoZSBMRk8gaXMgc3RvcHBlZFxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5TaWduYWx9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMCwgVG9uZS5UeXBlLkF1ZGlvUmFuZ2UpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEp1c3Qgb3V0cHV0cyB6ZXJvcy5cblx0XHRcdCAqICBAdHlwZSB7VG9uZS5aZXJvfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl96ZXJvcyA9IG5ldyBUb25lLlplcm8oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgdmFsdWUgdGhhdCB0aGUgTEZPIG91dHB1dHMgd2hlbiBpdCdzIHN0b3BwZWRcblx0XHRcdCAqICBAdHlwZSB7QXVkaW9SYW5nZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3RvcHBlZFZhbHVlID0gMDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5BdWRpb1RvR2Fpbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYTJnID0gbmV3IFRvbmUuQXVkaW9Ub0dhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5TY2FsZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc2NhbGVyID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZS5TY2FsZShvcHRpb25zLm1pbiwgb3B0aW9ucy5tYXgpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSB1bml0cyBvZiB0aGUgTEZPICh1c2VkIGZvciBjb252ZXJ0aW5nKVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLlR5cGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3VuaXRzID0gVG9uZS5UeXBlLkRlZmF1bHQ7XG5cdCAgICAgICAgdGhpcy51bml0cyA9IG9wdGlvbnMudW5pdHM7XG5cdCAgICAgICAgLy9jb25uZWN0IGl0IHVwXG5cdCAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5jaGFpbih0aGlzLl9hMmcsIHRoaXMuX3NjYWxlcik7XG5cdCAgICAgICAgdGhpcy5femVyb3MuY29ubmVjdCh0aGlzLl9hMmcpO1xuXHQgICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwuY29ubmVjdCh0aGlzLl9hMmcpO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFtcblx0ICAgICAgICAgICAgJ2FtcGxpdHVkZScsXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knXG5cdCAgICAgICAgXSk7XG5cdCAgICAgICAgdGhpcy5waGFzZSA9IG9wdGlvbnMucGhhc2U7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5MRk8sIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICB0aGUgZGVmYXVsdCBwYXJhbWV0ZXJzXG5cdFx0ICpcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuTEZPLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICd0eXBlJzogJ3NpbmUnLFxuXHQgICAgICAgICdtaW4nOiAwLFxuXHQgICAgICAgICdtYXgnOiAxLFxuXHQgICAgICAgICdwaGFzZSc6IDAsXG5cdCAgICAgICAgJ2ZyZXF1ZW5jeSc6ICc0bicsXG5cdCAgICAgICAgJ2FtcGxpdHVkZSc6IDEsXG5cdCAgICAgICAgJ3VuaXRzJzogVG9uZS5UeXBlLkRlZmF1bHRcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU3RhcnQgdGhlIExGTy5cblx0XHQgKiAgQHBhcmFtICB7VGltZX0gW3RpbWU9bm93XSB0aGUgdGltZSB0aGUgTEZPIHdpbGwgc3RhcnRcblx0XHQgKiAgQHJldHVybnMge1RvbmUuTEZPfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkxGTy5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9zdG9wcGVkU2lnbmFsLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQodGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFN0b3AgdGhlIExGTy5cblx0XHQgKiAgQHBhcmFtICB7VGltZX0gW3RpbWU9bm93XSB0aGUgdGltZSB0aGUgTEZPIHdpbGwgc3RvcFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5MRk99IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTEZPLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5zZXRWYWx1ZUF0VGltZSh0aGlzLl9zdG9wcGVkVmFsdWUsIHRpbWUpO1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RvcCh0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU3luYyB0aGUgc3RhcnQvc3RvcC9wYXVzZSB0byB0aGUgdHJhbnNwb3J0XG5cdFx0ICogIGFuZCB0aGUgZnJlcXVlbmN5IHRvIHRoZSBicG0gb2YgdGhlIHRyYW5zcG9ydFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5MRk99IHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAgbGZvLmZyZXF1ZW5jeS52YWx1ZSA9IFwiOG5cIjtcblx0XHQgKiAgbGZvLnN5bmMoKS5zdGFydCgwKVxuXHRcdCAqICAvL3RoZSByYXRlIG9mIHRoZSBMRk8gd2lsbCBhbHdheXMgYmUgYW4gZWlnaHRoIG5vdGUsXG5cdFx0ICogIC8vZXZlbiBhcyB0aGUgdGVtcG8gY2hhbmdlc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5MRk8ucHJvdG90eXBlLnN5bmMgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zeW5jKCk7XG5cdCAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zeW5jRnJlcXVlbmN5KCk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIHVuc3luYyB0aGUgTEZPIGZyb20gdHJhbnNwb3J0IGNvbnRyb2xcblx0XHQgKiAgQHJldHVybnMge1RvbmUuTEZPfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkxGTy5wcm90b3R5cGUudW5zeW5jID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudW5zeW5jKCk7XG5cdCAgICAgICAgdGhpcy5fb3NjaWxsYXRvci51bnN5bmNGcmVxdWVuY3koKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgbWluaXVtdW0gb3V0cHV0IG9mIHRoZSBMRk8uXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuTEZPI1xuXHRcdCAqIEB0eXBlIHtudW1iZXJ9XG5cdFx0ICogQG5hbWUgbWluXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5MRk8ucHJvdG90eXBlLCAnbWluJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fdG9Vbml0cyh0aGlzLl9zY2FsZXIubWluKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKG1pbikge1xuXHQgICAgICAgICAgICBtaW4gPSB0aGlzLl9mcm9tVW5pdHMobWluKTtcblx0ICAgICAgICAgICAgdGhpcy5fc2NhbGVyLm1pbiA9IG1pbjtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBtYXhpbXVtIG91dHB1dCBvZiB0aGUgTEZPLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkxGTyNcblx0XHQgKiBAdHlwZSB7bnVtYmVyfVxuXHRcdCAqIEBuYW1lIG1heFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuTEZPLnByb3RvdHlwZSwgJ21heCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RvVW5pdHModGhpcy5fc2NhbGVyLm1heCk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChtYXgpIHtcblx0ICAgICAgICAgICAgbWF4ID0gdGhpcy5fZnJvbVVuaXRzKG1heCk7XG5cdCAgICAgICAgICAgIHRoaXMuX3NjYWxlci5tYXggPSBtYXg7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvcjogc2luZSwgc3F1YXJlLCBzYXd0b290aCwgdHJpYW5nbGUuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuTEZPI1xuXHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0ICogQG5hbWUgdHlwZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuTEZPLnByb3RvdHlwZSwgJ3R5cGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnR5cGU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh0eXBlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGU7XG5cdCAgICAgICAgICAgIHRoaXMuX3N0b3BwZWRWYWx1ZSA9IHRoaXMuX29zY2lsbGF0b3IuX2dldEluaXRpYWxWYWx1ZSgpO1xuXHQgICAgICAgICAgICB0aGlzLl9zdG9wcGVkU2lnbmFsLnZhbHVlID0gdGhpcy5fc3RvcHBlZFZhbHVlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHBoYXNlIG9mIHRoZSBMRk8uXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuTEZPI1xuXHRcdCAqIEB0eXBlIHtudW1iZXJ9XG5cdFx0ICogQG5hbWUgcGhhc2Vcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkxGTy5wcm90b3R5cGUsICdwaGFzZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IucGhhc2U7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwaGFzZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnBoYXNlID0gcGhhc2U7XG5cdCAgICAgICAgICAgIHRoaXMuX3N0b3BwZWRWYWx1ZSA9IHRoaXMuX29zY2lsbGF0b3IuX2dldEluaXRpYWxWYWx1ZSgpO1xuXHQgICAgICAgICAgICB0aGlzLl9zdG9wcGVkU2lnbmFsLnZhbHVlID0gdGhpcy5fc3RvcHBlZFZhbHVlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIG91dHB1dCB1bml0cyBvZiB0aGUgTEZPLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkxGTyNcblx0XHQgKiBAdHlwZSB7VG9uZS5UeXBlfVxuXHRcdCAqIEBuYW1lIHVuaXRzXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5MRk8ucHJvdG90eXBlLCAndW5pdHMnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl91bml0cztcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbCkge1xuXHQgICAgICAgICAgICB2YXIgY3VycmVudE1pbiA9IHRoaXMubWluO1xuXHQgICAgICAgICAgICB2YXIgY3VycmVudE1heCA9IHRoaXMubWF4O1xuXHQgICAgICAgICAgICAvL2NvbnZlcnQgdGhlIG1pbiBhbmQgdGhlIG1heFxuXHQgICAgICAgICAgICB0aGlzLl91bml0cyA9IHZhbDtcblx0ICAgICAgICAgICAgdGhpcy5taW4gPSBjdXJyZW50TWluO1xuXHQgICAgICAgICAgICB0aGlzLm1heCA9IGN1cnJlbnRNYXg7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBNdXRlIHRoZSBvdXRwdXQuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuTEZPI1xuXHRcdCAqIEB0eXBlIHtCb29sZWFufVxuXHRcdCAqIEBuYW1lIG11dGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkxGTy5wcm90b3R5cGUsICdtdXRlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5tdXRlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobXV0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLm11dGUgPSBtdXRlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIGVpdGhlciBcInN0YXJ0ZWRcIiBvciBcInN0b3BwZWRcIi5cblx0XHQgKiAgQHR5cGUge1RvbmUuU3RhdGV9XG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5MRk8jXG5cdFx0ICogIEBuYW1lIHN0YXRlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5MRk8ucHJvdG90eXBlLCAnc3RhdGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnN0YXRlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENvbm5lY3QgdGhlIG91dHB1dCBvZiB0aGUgTEZPIHRvIGFuIEF1ZGlvUGFyYW0sIEF1ZGlvTm9kZSwgb3IgVG9uZSBOb2RlLlxuXHRcdCAqICBUb25lLkxGTyB3aWxsIGF1dG9tYXRpY2FsbHkgY29udmVydCB0byB0aGUgZGVzdGluYXRpb24gdW5pdHMgb2YgdGhlXG5cdFx0ICogIHdpbGwgZ2V0IHRoZSB1bml0cyBmcm9tIHRoZSBjb25uZWN0ZWQgbm9kZS5cblx0XHQgKiAgQHBhcmFtICB7VG9uZSB8IEF1ZGlvUGFyYW0gfCBBdWRpb05vZGV9IG5vZGVcblx0XHQgKiAgQHBhcmFtIHtudW1iZXJ9IFtvdXRwdXROdW09MF0gb3B0aW9uYWxseSB3aGljaCBvdXRwdXQgdG8gY29ubmVjdCBmcm9tXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSBbaW5wdXROdW09MF0gb3B0aW9uYWxseSB3aGljaCBpbnB1dCB0byBjb25uZWN0IHRvXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkxGT30gdGhpc1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5MRk8ucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbiAobm9kZSkge1xuXHQgICAgICAgIGlmIChub2RlLmNvbnN0cnVjdG9yID09PSBUb25lLlNpZ25hbCB8fCBub2RlLmNvbnN0cnVjdG9yID09PSBUb25lLlBhcmFtKSB7XG5cdCAgICAgICAgICAgIHRoaXMuY29udmVydCA9IG5vZGUuY29udmVydDtcblx0ICAgICAgICAgICAgdGhpcy51bml0cyA9IG5vZGUudW5pdHM7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIFRvbmUuU2lnbmFsQmFzZS5wcm90b3R5cGUuY29ubmVjdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBwcml2YXRlIG1ldGhvZCBib3Jyb3dlZCBmcm9tIFBhcmFtIGNvbnZlcnRzXG5cdFx0ICogIHVuaXRzIGZyb20gdGhlaXIgZGVzdGluYXRpb24gdmFsdWVcblx0XHQgKiAgQGZ1bmN0aW9uXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkxGTy5wcm90b3R5cGUuX2Zyb21Vbml0cyA9IFRvbmUuUGFyYW0ucHJvdG90eXBlLl9mcm9tVW5pdHM7XG5cdCAgICAvKipcblx0XHQgKiAgcHJpdmF0ZSBtZXRob2QgYm9ycm93ZWQgZnJvbSBQYXJhbSBjb252ZXJ0c1xuXHRcdCAqICB1bml0cyB0byB0aGVpciBkZXN0aW5hdGlvbiB2YWx1ZVxuXHRcdCAqICBAZnVuY3Rpb25cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuTEZPLnByb3RvdHlwZS5fdG9Vbml0cyA9IFRvbmUuUGFyYW0ucHJvdG90eXBlLl90b1VuaXRzO1xuXHQgICAgLyoqXG5cdFx0ICogIGRpc2Nvbm5lY3QgYW5kIGRpc3Bvc2Vcblx0XHQgKiAgQHJldHVybnMge1RvbmUuTEZPfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkxGTy5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ2FtcGxpdHVkZScsXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knXG5cdCAgICAgICAgXSk7XG5cdCAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5femVyb3MuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3plcm9zID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9zY2FsZXIuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3NjYWxlciA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fYTJnLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9hMmcgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmFtcGxpdHVkZSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuTEZPO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5MaW1pdGVyIHdpbGwgbGltaXQgdGhlIGxvdWRuZXNzIG9mIGFuIGluY29taW5nIHNpZ25hbC5cblx0XHQgKiAgICAgICAgIEl0IGlzIGNvbXBvc2VkIG9mIGEgVG9uZS5Db21wcmVzc29yIHdpdGggYSBmYXN0IGF0dGFja1xuXHRcdCAqICAgICAgICAgYW5kIHJlbGVhc2UuIExpbWl0ZXJzIGFyZSBjb21tb25seSB1c2VkIHRvIHNhZmVndWFyZCBhZ2FpbnN0XG5cdFx0ICogICAgICAgICBzaWduYWwgY2xpcHBpbmcuIFVubGlrZSBhIGNvbXByZXNzb3IsIGxpbWl0ZXJzIGRvIG5vdCBwcm92aWRlXG5cdFx0ICogICAgICAgICBzbW9vdGggZ2FpbiByZWR1Y3Rpb24gYW5kIGFsbW9zdCBjb21wbGV0ZWx5IHByZXZlbnRcblx0XHQgKiAgICAgICAgIGFkZGl0aW9uYWwgZ2FpbiBhYm92ZSB0aGUgdGhyZXNob2xkLlxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkF1ZGlvTm9kZX1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSB0aHJlc2hvbGQgVGhlIHRoZXNob2xkIGFib3ZlIHdoaWNoIHRoZSBsaW1pdGluZyBpcyBhcHBsaWVkLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqICB2YXIgbGltaXRlciA9IG5ldyBUb25lLkxpbWl0ZXIoLTYpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5MaW1pdGVyID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFsndGhyZXNob2xkJ10sIFRvbmUuTGltaXRlcik7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgY29tcHJlc3NvclxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQ29tcHJlc3Nvcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2NvbXByZXNzb3IgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZS5Db21wcmVzc29yKHtcblx0ICAgICAgICAgICAgJ2F0dGFjayc6IDAuMDAxLFxuXHQgICAgICAgICAgICAnZGVjYXknOiAwLjAwMSxcblx0ICAgICAgICAgICAgJ3RocmVzaG9sZCc6IG9wdGlvbnMudGhyZXNob2xkXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBUaGUgdGhyZXNob2xkIG9mIG9mIHRoZSBsaW1pdGVyXG5cdFx0XHQgKiBAdHlwZSB7RGVjaWJlbH1cblx0XHRcdCAqIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMudGhyZXNob2xkID0gdGhpcy5fY29tcHJlc3Nvci50aHJlc2hvbGQ7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoJ3RocmVzaG9sZCcpO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuTGltaXRlciwgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0IHZhbHVlXG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICogIEBjb25zdFxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICovXG5cdCAgICBUb25lLkxpbWl0ZXIuZGVmYXVsdHMgPSB7ICd0aHJlc2hvbGQnOiAtMTIgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuTGltaXRlcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5MaW1pdGVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fY29tcHJlc3Nvci5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fY29tcHJlc3NvciA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoJ3RocmVzaG9sZCcpO1xuXHQgICAgICAgIHRoaXMudGhyZXNob2xkID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5MaW1pdGVyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5Mb3dwYXNzIGlzIGEgbG93cGFzcyBmZWVkYmFjayBjb21iIGZpbHRlci4gSXQgaXMgc2ltaWxhciB0b1xuXHRcdCAqICAgICAgICAgVG9uZS5GZWVkYmFja0NvbWJGaWx0ZXIsIGJ1dCBpbmNsdWRlcyBhIGxvd3Bhc3MgZmlsdGVyLlxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkF1ZGlvTm9kZX1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBwYXJhbSB7VGltZXxPYmplY3R9IFtkZWxheVRpbWVdIFRoZSBkZWxheSB0aW1lIG9mIHRoZSBjb21iIGZpbHRlclxuXHRcdCAqICBAcGFyYW0ge05vcm1hbFJhbmdlPX0gcmVzb25hbmNlIFRoZSByZXNvbmFuY2UgKGZlZWRiYWNrKSBvZiB0aGUgY29tYiBmaWx0ZXJcblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3k9fSBkYW1wZW5pbmcgVGhlIGN1dG9mZiBvZiB0aGUgbG93cGFzcyBmaWx0ZXIgZGFtcGVucyB0aGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lnbmFsIGFzIGl0IGlzIGZlZGJhY2suXG5cdFx0ICovXG5cdCAgICBUb25lLkxvd3Bhc3NDb21iRmlsdGVyID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ2RlbGF5VGltZScsXG5cdCAgICAgICAgICAgICdyZXNvbmFuY2UnLFxuXHQgICAgICAgICAgICAnZGFtcGVuaW5nJ1xuXHQgICAgICAgIF0sIFRvbmUuTG93cGFzc0NvbWJGaWx0ZXIpO1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5jcmVhdGVJbnNPdXRzKDEsIDEpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBkZWxheSBub2RlXG5cdFx0XHQgKiAgQHR5cGUge0RlbGF5Tm9kZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZGVsYXkgPSB0aGlzLmlucHV0ID0gbmV3IFRvbmUuRGVsYXkob3B0aW9ucy5kZWxheVRpbWUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBkZWxheVRpbWUgb2YgdGhlIGNvbWIgZmlsdGVyLlxuXHRcdFx0ICogIEB0eXBlIHtUaW1lfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZGVsYXlUaW1lID0gdGhpcy5fZGVsYXkuZGVsYXlUaW1lO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBsb3dwYXNzIGZpbHRlclxuXHRcdFx0ICogIEB0eXBlICB7QmlxdWFkRmlsdGVyTm9kZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbG93cGFzcyA9IHRoaXMub3V0cHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuXHQgICAgICAgIHRoaXMuX2xvd3Bhc3MuUS52YWx1ZSA9IC0zLjAxMDI5OTk1NjYzOTgxMjU7XG5cdCAgICAgICAgdGhpcy5fbG93cGFzcy50eXBlID0gJ2xvd3Bhc3MnO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBkYW1wZW5pbmcgY29udHJvbCBvZiB0aGUgZmVlZGJhY2tcblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZGFtcGVuaW5nID0gbmV3IFRvbmUuUGFyYW0oe1xuXHQgICAgICAgICAgICAncGFyYW0nOiB0aGlzLl9sb3dwYXNzLmZyZXF1ZW5jeSxcblx0ICAgICAgICAgICAgJ3VuaXRzJzogVG9uZS5UeXBlLkZyZXF1ZW5jeSxcblx0ICAgICAgICAgICAgJ3ZhbHVlJzogb3B0aW9ucy5kYW1wZW5pbmdcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgZmVlZGJhY2sgZ2FpblxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkdhaW59XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ZlZWRiYWNrID0gbmV3IFRvbmUuR2FpbihvcHRpb25zLnJlc29uYW5jZSwgVG9uZS5UeXBlLk5vcm1hbFJhbmdlKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgYW1vdW50IG9mIGZlZWRiYWNrIG9mIHRoZSBkZWxheWVkIHNpZ25hbC5cblx0XHRcdCAqICBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5yZXNvbmFuY2UgPSB0aGlzLl9mZWVkYmFjay5nYWluO1xuXHQgICAgICAgIC8vY29ubmVjdGlvbnNcblx0ICAgICAgICB0aGlzLl9kZWxheS5jaGFpbih0aGlzLl9sb3dwYXNzLCB0aGlzLl9mZWVkYmFjaywgdGhpcy5fZGVsYXkpO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFtcblx0ICAgICAgICAgICAgJ2RhbXBlbmluZycsXG5cdCAgICAgICAgICAgICdyZXNvbmFuY2UnLFxuXHQgICAgICAgICAgICAnZGVsYXlUaW1lJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuTG93cGFzc0NvbWJGaWx0ZXIsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICB0aGUgZGVmYXVsdCBwYXJhbWV0ZXJzXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQGNvbnN0XG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkxvd3Bhc3NDb21iRmlsdGVyLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdkZWxheVRpbWUnOiAwLjEsXG5cdCAgICAgICAgJ3Jlc29uYW5jZSc6IDAuNSxcblx0ICAgICAgICAnZGFtcGVuaW5nJzogMzAwMFxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuTG93cGFzc0NvbWJGaWx0ZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTG93cGFzc0NvbWJGaWx0ZXIucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbXG5cdCAgICAgICAgICAgICdkYW1wZW5pbmcnLFxuXHQgICAgICAgICAgICAncmVzb25hbmNlJyxcblx0ICAgICAgICAgICAgJ2RlbGF5VGltZSdcblx0ICAgICAgICBdKTtcblx0ICAgICAgICB0aGlzLmRhbXBlbmluZy5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5kYW1wZW5pbmcgPSBudWxsO1xuXHQgICAgICAgIHRoaXMucmVzb25hbmNlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLnJlc29uYW5jZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fZGVsYXkuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2RlbGF5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmRlbGF5VGltZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fbG93cGFzcy5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgdGhpcy5fbG93cGFzcyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fZmVlZGJhY2suZGlzY29ubmVjdCgpO1xuXHQgICAgICAgIHRoaXMuX2ZlZWRiYWNrID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5Mb3dwYXNzQ29tYkZpbHRlcjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBUb25lLk1lcmdlIGJyaW5ncyB0d28gc2lnbmFscyBpbnRvIHRoZSBsZWZ0IGFuZCByaWdodFxuXHRcdCAqICAgICAgICAgIGNoYW5uZWxzIG9mIGEgc2luZ2xlIHN0ZXJlbyBjaGFubmVsLlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIG1lcmdlID0gbmV3IFRvbmUuTWVyZ2UoKS50b01hc3RlcigpO1xuXHRcdCAqIC8vcm91dGluZyBhIHNpbmUgdG9uZSBpbiB0aGUgbGVmdCBjaGFubmVsXG5cdFx0ICogLy9hbmQgbm9pc2UgaW4gdGhlIHJpZ2h0IGNoYW5uZWxcblx0XHQgKiB2YXIgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QobWVyZ2UubGVmdCk7XG5cdFx0ICogdmFyIG5vaXNlID0gbmV3IFRvbmUuTm9pc2UoKS5jb25uZWN0KG1lcmdlLnJpZ2h0KTtcblx0XHQgKiAvL3N0YXJ0aW5nIG91ciBvc2NpbGxhdG9yc1xuXHRcdCAqIG5vaXNlLnN0YXJ0KCk7XG5cdFx0ICogb3NjLnN0YXJ0KCk7XG5cdFx0ICovXG5cdCAgICBUb25lLk1lcmdlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5jcmVhdGVJbnNPdXRzKDIsIDApO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBsZWZ0IGlucHV0IGNoYW5uZWwuXG5cdFx0XHQgKiAgQWxpYXMgZm9yIDxjb2RlPmlucHV0WzBdPC9jb2RlPlxuXHRcdFx0ICogIEB0eXBlIHtHYWluTm9kZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubGVmdCA9IHRoaXMuaW5wdXRbMF0gPSBuZXcgVG9uZS5HYWluKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHJpZ2h0IGlucHV0IGNoYW5uZWwuXG5cdFx0XHQgKiAgQWxpYXMgZm9yIDxjb2RlPmlucHV0WzFdPC9jb2RlPi5cblx0XHRcdCAqICBAdHlwZSB7R2Fpbk5vZGV9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnJpZ2h0ID0gdGhpcy5pbnB1dFsxXSA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbWVyZ2VyIG5vZGUgZm9yIHRoZSB0d28gY2hhbm5lbHNcblx0XHRcdCAqICBAdHlwZSB7Q2hhbm5lbE1lcmdlck5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX21lcmdlciA9IHRoaXMub3V0cHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNoYW5uZWxNZXJnZXIoMik7XG5cdCAgICAgICAgLy9jb25uZWN0aW9uc1xuXHQgICAgICAgIHRoaXMubGVmdC5jb25uZWN0KHRoaXMuX21lcmdlciwgMCwgMCk7XG5cdCAgICAgICAgdGhpcy5yaWdodC5jb25uZWN0KHRoaXMuX21lcmdlciwgMCwgMSk7XG5cdCAgICAgICAgdGhpcy5sZWZ0LmNoYW5uZWxDb3VudCA9IDE7XG5cdCAgICAgICAgdGhpcy5yaWdodC5jaGFubmVsQ291bnQgPSAxO1xuXHQgICAgICAgIHRoaXMubGVmdC5jaGFubmVsQ291bnRNb2RlID0gJ2V4cGxpY2l0Jztcblx0ICAgICAgICB0aGlzLnJpZ2h0LmNoYW5uZWxDb3VudE1vZGUgPSAnZXhwbGljaXQnO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuTWVyZ2UsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuTWVyZ2V9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTWVyZ2UucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLmxlZnQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMubGVmdCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5yaWdodC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5yaWdodCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fbWVyZ2VyLmRpc2Nvbm5lY3QoKTtcblx0ICAgICAgICB0aGlzLl9tZXJnZXIgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLk1lcmdlO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIFRvbmUuTWV0ZXIgZ2V0cyB0aGUgW1JNU10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUm9vdF9tZWFuX3NxdWFyZSlcblx0XHQgKiAgICAgICAgICBvZiBhbiBpbnB1dCBzaWduYWwgd2l0aCBzb21lIGF2ZXJhZ2luZyBhcHBsaWVkLiBJdCBjYW4gYWxzbyBnZXQgdGhlIHJhd1xuXHRcdCAqICAgICAgICAgIHZhbHVlIG9mIHRoZSBpbnB1dCBzaWduYWwuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkF1ZGlvTm9kZX1cblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ9IHNtb290aGluZyBUaGUgYW1vdW50IG9mIHNtb290aGluZyBhcHBsaWVkIGJldHdlZW4gZnJhbWVzLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBtZXRlciA9IG5ldyBUb25lLk1ldGVyKCk7XG5cdFx0ICogdmFyIG1pYyA9IG5ldyBUb25lLlVzZXJNZWRpYSgpLm9wZW4oKTtcblx0XHQgKiAvL2Nvbm5lY3QgbWljIHRvIHRoZSBtZXRlclxuXHRcdCAqIG1pYy5jb25uZWN0KG1ldGVyKTtcblx0XHQgKiAvL3RoZSBjdXJyZW50IGxldmVsIG9mIHRoZSBtaWMgaW5wdXQgaW4gZGVjaWJlbHNcblx0XHQgKiB2YXIgbGV2ZWwgPSBtZXRlci5nZXRWYWx1ZSgpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5NZXRlciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbJ3Ntb290aGluZyddLCBUb25lLk1ldGVyKTtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhbmFseXNlciBub2RlIHdoaWNoIGNvbXB1dGVzIHRoZSBsZXZlbHMuXG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqICBAdHlwZSAge1RvbmUuQW5hbHlzZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9hbmFseXNlciA9IG5ldyBUb25lLkFuYWx5c2VyKCd3YXZlZm9ybScsIDEwMjQpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhbW91bnQgb2YgY2FycnlvdmVyIGJldHdlZW4gdGhlIGN1cnJlbnQgYW5kIGxhc3QgZnJhbWUuXG5cdFx0XHQgKiAgT25seSBhcHBsaWVkIG1ldGVyIGZvciBcImxldmVsXCIgdHlwZS5cblx0XHRcdCAqICBAdHlwZSAge051bWJlcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuc21vb3RoaW5nID0gb3B0aW9ucy5zbW9vdGhpbmc7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5NZXRlciwgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0c1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBjb25zdFxuXHRcdCAqL1xuXHQgICAgVG9uZS5NZXRlci5kZWZhdWx0cyA9IHsgJ3Ntb290aGluZyc6IDAuOCB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEdldCB0aGUgY3VycmVudCBkZWNpYmVsIHZhbHVlIG9mIHRoZSBpbmNvbWluZyBzaWduYWxcblx0XHQgKiAgQHJldHVybnMge0RlY2liZWxzfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5NZXRlci5wcm90b3R5cGUuZ2V0TGV2ZWwgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fYW5hbHlzZXIudHlwZSA9ICdmZnQnO1xuXHQgICAgICAgIHZhciB2YWx1ZXMgPSB0aGlzLl9hbmFseXNlci5nZXRWYWx1ZSgpO1xuXHQgICAgICAgIHZhciBvZmZzZXQgPSAyODtcblx0ICAgICAgICAvLyBub3JtYWxpemVzIG1vc3Qgc2lnbmFsIGxldmVsc1xuXHQgICAgICAgIC8vIFRPRE86IGNvbXB1dGUgbG91ZG5lc3MgZnJvbSBGRlRcblx0ICAgICAgICByZXR1cm4gTWF0aC5tYXguYXBwbHkodGhpcywgdmFsdWVzKSArIG9mZnNldDtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgR2V0IHRoZSBzaWduYWwgdmFsdWUgb2YgdGhlIGluY29taW5nIHNpZ25hbFxuXHRcdCAqICBAcmV0dXJucyB7TnVtYmVyfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5NZXRlci5wcm90b3R5cGUuZ2V0VmFsdWUgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fYW5hbHlzZXIudHlwZSA9ICd3YXZlZm9ybSc7XG5cdCAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5fYW5hbHlzZXIuZ2V0VmFsdWUoKTtcblx0ICAgICAgICByZXR1cm4gdmFsdWVbMF07XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogQSB2YWx1ZSBmcm9tIDAgLT4gMSB3aGVyZSAwIHJlcHJlc2VudHMgbm8gdGltZSBhdmVyYWdpbmcgd2l0aCB0aGUgbGFzdCBhbmFseXNpcyBmcmFtZS5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5NZXRlciNcblx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqIEBuYW1lIHNtb290aGluZ1xuXHRcdCAqIEByZWFkT25seVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuTWV0ZXIucHJvdG90eXBlLCAnc21vb3RoaW5nJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuc21vb3RoaW5nO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2FuYWx5c2VyLnNtb290aGluZyA9IHZhbDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuTWV0ZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTWV0ZXIucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9hbmFseXNlci5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fYW5hbHlzZXIgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLk1ldGVyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqXHRAY2xhc3MgIFRvbmUuU3BsaXQgc3BsaXRzIGFuIGluY29taW5nIHNpZ25hbCBpbnRvIGxlZnQgYW5kIHJpZ2h0IGNoYW5uZWxzLlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHNwbGl0ID0gbmV3IFRvbmUuU3BsaXQoKTtcblx0XHQgKiBzdGVyZW9TaWduYWwuY29ubmVjdChzcGxpdCk7XG5cdFx0ICovXG5cdCAgICBUb25lLlNwbGl0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5jcmVhdGVJbnNPdXRzKDAsIDIpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEB0eXBlIHtDaGFubmVsU3BsaXR0ZXJOb2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9zcGxpdHRlciA9IHRoaXMuaW5wdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKDIpO1xuXHQgICAgICAgIHRoaXMuX3NwbGl0dGVyLmNoYW5uZWxDb3VudCA9IDI7XG5cdCAgICAgICAgdGhpcy5fc3BsaXR0ZXIuY2hhbm5lbENvdW50TW9kZSA9ICdleHBsaWNpdCc7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgTGVmdCBjaGFubmVsIG91dHB1dC5cblx0XHRcdCAqICBBbGlhcyBmb3IgPGNvZGU+b3V0cHV0WzBdPC9jb2RlPlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkdhaW59XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmxlZnQgPSB0aGlzLm91dHB1dFswXSA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBSaWdodCBjaGFubmVsIG91dHB1dC5cblx0XHRcdCAqICBBbGlhcyBmb3IgPGNvZGU+b3V0cHV0WzFdPC9jb2RlPlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkdhaW59XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnJpZ2h0ID0gdGhpcy5vdXRwdXRbMV0gPSBuZXcgVG9uZS5HYWluKCk7XG5cdCAgICAgICAgLy9jb25uZWN0aW9uc1xuXHQgICAgICAgIHRoaXMuX3NwbGl0dGVyLmNvbm5lY3QodGhpcy5sZWZ0LCAwLCAwKTtcblx0ICAgICAgICB0aGlzLl9zcGxpdHRlci5jb25uZWN0KHRoaXMucmlnaHQsIDEsIDApO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuU3BsaXQsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuU3BsaXR9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuU3BsaXQucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9zcGxpdHRlci5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgdGhpcy5sZWZ0LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmxlZnQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMucmlnaHQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMucmlnaHQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3NwbGl0dGVyID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5TcGxpdDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIE1pZC9TaWRlIHByb2Nlc3Npbmcgc2VwYXJhdGVzIHRoZSB0aGUgJ21pZCcgc2lnbmFsXG5cdFx0ICogICAgICAgICAod2hpY2ggY29tZXMgb3V0IG9mIGJvdGggdGhlIGxlZnQgYW5kIHRoZSByaWdodCBjaGFubmVsKVxuXHRcdCAqICAgICAgICAgYW5kIHRoZSAnc2lkZScgKHdoaWNoIG9ubHkgY29tZXMgb3V0IG9mIHRoZSB0aGUgc2lkZSBjaGFubmVscykuIDxicj48YnI+XG5cdFx0ICogICAgICAgICA8Y29kZT5cblx0XHQgKiAgICAgICAgIE1pZCA9IChMZWZ0K1JpZ2h0KS9zcXJ0KDIpOyAgIC8vIG9idGFpbiBtaWQtc2lnbmFsIGZyb20gbGVmdCBhbmQgcmlnaHQ8YnI+XG5cdFx0ICogICAgICAgICBTaWRlID0gKExlZnQtUmlnaHQpL3NxcnQoMik7ICAgLy8gb2J0YWluIHNpZGUtc2lnbmFsIGZyb20gbGVmdCBhbmQgcmlnaDxicj5cblx0XHQgKiAgICAgICAgIDwvY29kZT5cblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqL1xuXHQgICAgVG9uZS5NaWRTaWRlU3BsaXQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLmNyZWF0ZUluc091dHMoMCwgMik7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgc3BsaXQgdGhlIGluY29taW5nIHNpZ25hbCBpbnRvIGxlZnQgYW5kIHJpZ2h0IGNoYW5uZWxzXG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLlNwbGl0fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9zcGxpdCA9IHRoaXMuaW5wdXQgPSBuZXcgVG9uZS5TcGxpdCgpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBtaWQgc2VuZC4gQ29ubmVjdCB0byBtaWQgcHJvY2Vzc2luZy4gQWxpYXMgZm9yXG5cdFx0XHQgKiAgPGNvZGU+b3V0cHV0WzBdPC9jb2RlPlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkFkZH1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX21pZEFkZCA9IG5ldyBUb25lLkFkZCgpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogTXVsdGlwbHkgdGhlIF9taWRBZGQgYnkgc3FydCgxLzIpXG5cdFx0XHQgKiBAdHlwZSB7VG9uZS5NdWx0aXBseX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubWlkID0gdGhpcy5vdXRwdXRbMF0gPSBuZXcgVG9uZS5NdWx0aXBseShNYXRoLlNRUlQxXzIpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBzaWRlIG91dHB1dC4gQ29ubmVjdCB0byBzaWRlIHByb2Nlc3NpbmcuIEFsc28gT3V0cHV0IDFcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5TdWJ0cmFjdH1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3NpZGVTdWJ0cmFjdCA9IG5ldyBUb25lLlN1YnRyYWN0KCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBNdWx0aXBseSB0aGUgX21pZEFkZCBieSBzcXJ0KDEvMilcblx0XHRcdCAqIEB0eXBlIHtUb25lLk11bHRpcGx5fVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5zaWRlID0gdGhpcy5vdXRwdXRbMV0gPSBuZXcgVG9uZS5NdWx0aXBseShNYXRoLlNRUlQxXzIpO1xuXHQgICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fbWlkQWRkLCAwLCAwKTtcblx0ICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KHRoaXMuX21pZEFkZCwgMSwgMSk7XG5cdCAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdCh0aGlzLl9zaWRlU3VidHJhY3QsIDAsIDApO1xuXHQgICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fc2lkZVN1YnRyYWN0LCAxLCAxKTtcblx0ICAgICAgICB0aGlzLl9taWRBZGQuY29ubmVjdCh0aGlzLm1pZCk7XG5cdCAgICAgICAgdGhpcy5fc2lkZVN1YnRyYWN0LmNvbm5lY3QodGhpcy5zaWRlKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLk1pZFNpZGVTcGxpdCwgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk1pZFNpZGVTcGxpdH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5NaWRTaWRlU3BsaXQucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5taWQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuc2lkZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5zaWRlID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9taWRBZGQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX21pZEFkZCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fc2lkZVN1YnRyYWN0LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9zaWRlU3VidHJhY3QgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3NwbGl0LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9zcGxpdCA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuTWlkU2lkZVNwbGl0O1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgTWlkL1NpZGUgcHJvY2Vzc2luZyBzZXBhcmF0ZXMgdGhlIHRoZSAnbWlkJyBzaWduYWxcblx0XHQgKiAgICAgICAgICh3aGljaCBjb21lcyBvdXQgb2YgYm90aCB0aGUgbGVmdCBhbmQgdGhlIHJpZ2h0IGNoYW5uZWwpXG5cdFx0ICogICAgICAgICBhbmQgdGhlICdzaWRlJyAod2hpY2ggb25seSBjb21lcyBvdXQgb2YgdGhlIHRoZSBzaWRlIGNoYW5uZWxzKS5cblx0XHQgKiAgICAgICAgIE1pZFNpZGVNZXJnZSBtZXJnZXMgdGhlIG1pZCBhbmQgc2lkZSBzaWduYWwgYWZ0ZXIgdGhleSd2ZSBiZWVuIHNlcGVyYXRlZFxuXHRcdCAqICAgICAgICAgYnkgVG9uZS5NaWRTaWRlU3BsaXQuPGJyPjxicj5cblx0XHQgKiAgICAgICAgIDxjb2RlPlxuXHRcdCAqICAgICAgICAgTGVmdCA9IChNaWQrU2lkZSkvc3FydCgyKTsgICAvLyBvYnRhaW4gbGVmdCBzaWduYWwgZnJvbSBtaWQgYW5kIHNpZGU8YnI+XG5cdFx0ICogICAgICAgICBSaWdodCA9IChNaWQtU2lkZSkvc3FydCgyKTsgICAvLyBvYnRhaW4gcmlnaHQgc2lnbmFsIGZyb20gbWlkIGFuZCBzaWRlPGJyPlxuXHRcdCAqICAgICAgICAgPC9jb2RlPlxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkF1ZGlvTm9kZX1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICovXG5cdCAgICBUb25lLk1pZFNpZGVNZXJnZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuY3JlYXRlSW5zT3V0cygyLCAwKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbWlkIHNpZ25hbCBpbnB1dC4gQWxpYXMgZm9yXG5cdFx0XHQgKiAgPGNvZGU+aW5wdXRbMF08L2NvZGU+XG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLkdhaW59XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLm1pZCA9IHRoaXMuaW5wdXRbMF0gPSBuZXcgVG9uZS5HYWluKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgcmVjb21iaW5lIHRoZSBtaWQvc2lkZSBpbnRvIExlZnRcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5BZGR9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2xlZnQgPSBuZXcgVG9uZS5BZGQoKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIE11bHRpcGx5IHRoZSBsZWZ0IGJ5IHNxcnQoMS8yKVxuXHRcdFx0ICogQHR5cGUge1RvbmUuTXVsdGlwbHl9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl90aW1lc1R3b0xlZnQgPSBuZXcgVG9uZS5NdWx0aXBseShNYXRoLlNRUlQxXzIpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBzaWRlIHNpZ25hbCBpbnB1dC4gQWxpYXMgZm9yXG5cdFx0XHQgKiAgPGNvZGU+aW5wdXRbMV08L2NvZGU+XG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLkdhaW59XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnNpZGUgPSB0aGlzLmlucHV0WzFdID0gbmV3IFRvbmUuR2FpbigpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHJlY29tYmluZSB0aGUgbWlkL3NpZGUgaW50byBSaWdodFxuXHRcdFx0ICogIEB0eXBlIHtUb25lLlN1YnRyYWN0fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9yaWdodCA9IG5ldyBUb25lLlN1YnRyYWN0KCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBNdWx0aXBseSB0aGUgcmlnaHQgYnkgc3FydCgxLzIpXG5cdFx0XHQgKiBAdHlwZSB7VG9uZS5NdWx0aXBseX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3RpbWVzVHdvUmlnaHQgPSBuZXcgVG9uZS5NdWx0aXBseShNYXRoLlNRUlQxXzIpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIE1lcmdlIHRoZSBsZWZ0L3JpZ2h0IHNpZ25hbCBiYWNrIGludG8gYSBzdGVyZW8gc2lnbmFsLlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLk1lcmdlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9tZXJnZSA9IHRoaXMub3V0cHV0ID0gbmV3IFRvbmUuTWVyZ2UoKTtcblx0ICAgICAgICB0aGlzLm1pZC5jb25uZWN0KHRoaXMuX2xlZnQsIDAsIDApO1xuXHQgICAgICAgIHRoaXMuc2lkZS5jb25uZWN0KHRoaXMuX2xlZnQsIDAsIDEpO1xuXHQgICAgICAgIHRoaXMubWlkLmNvbm5lY3QodGhpcy5fcmlnaHQsIDAsIDApO1xuXHQgICAgICAgIHRoaXMuc2lkZS5jb25uZWN0KHRoaXMuX3JpZ2h0LCAwLCAxKTtcblx0ICAgICAgICB0aGlzLl9sZWZ0LmNvbm5lY3QodGhpcy5fdGltZXNUd29MZWZ0KTtcblx0ICAgICAgICB0aGlzLl9yaWdodC5jb25uZWN0KHRoaXMuX3RpbWVzVHdvUmlnaHQpO1xuXHQgICAgICAgIHRoaXMuX3RpbWVzVHdvTGVmdC5jb25uZWN0KHRoaXMuX21lcmdlLCAwLCAwKTtcblx0ICAgICAgICB0aGlzLl90aW1lc1R3b1JpZ2h0LmNvbm5lY3QodGhpcy5fbWVyZ2UsIDAsIDEpO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuTWlkU2lkZU1lcmdlLCBUb25lLkF1ZGlvTm9kZSk7XG5cdCAgICAvKipcblx0XHQgKiAgY2xlYW4gdXBcblx0XHQgKiAgQHJldHVybnMge1RvbmUuTWlkU2lkZU1lcmdlfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk1pZFNpZGVNZXJnZS5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLm1pZCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5zaWRlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLnNpZGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2xlZnQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2xlZnQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3RpbWVzVHdvTGVmdC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fdGltZXNUd29MZWZ0ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9yaWdodC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fcmlnaHQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3RpbWVzVHdvUmlnaHQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3RpbWVzVHdvUmlnaHQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX21lcmdlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9tZXJnZSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuTWlkU2lkZU1lcmdlO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5NaWRTaWRlQ29tcHJlc3NvciBhcHBsaWVzIHR3byBkaWZmZXJlbnQgY29tcHJlc3NvcnMgdG8gdGhlIG1pZFxuXHRcdCAqICAgICAgICAgYW5kIHNpZGUgc2lnbmFsIGNvbXBvbmVudHMuIFNlZSBUb25lLk1pZFNpZGVTcGxpdC5cblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFRoZSBvcHRpb25zIHRoYXQgYXJlIHBhc3NlZCB0byB0aGUgbWlkIGFuZCBzaWRlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXByZXNzb3JzLlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKi9cblx0ICAgIFRvbmUuTWlkU2lkZUNvbXByZXNzb3IgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdEFyZyhvcHRpb25zLCBUb25lLk1pZFNpZGVDb21wcmVzc29yLmRlZmF1bHRzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbWlkL3NpZGUgc3BsaXRcblx0XHRcdCAqICBAdHlwZSAge1RvbmUuTWlkU2lkZVNwbGl0fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQgPSB0aGlzLmlucHV0ID0gbmV3IFRvbmUuTWlkU2lkZVNwbGl0KCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIG1pZC9zaWRlIHJlY29tYmluYXRpb25cblx0XHRcdCAqICBAdHlwZSAge1RvbmUuTWlkU2lkZU1lcmdlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9taWRTaWRlTWVyZ2UgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLk1pZFNpZGVNZXJnZSgpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBjb21wcmVzc29yIGFwcGxpZWQgdG8gdGhlIG1pZCBzaWduYWxcblx0XHRcdCAqICBAdHlwZSAge1RvbmUuQ29tcHJlc3Nvcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubWlkID0gbmV3IFRvbmUuQ29tcHJlc3NvcihvcHRpb25zLm1pZCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGNvbXByZXNzb3IgYXBwbGllZCB0byB0aGUgc2lkZSBzaWduYWxcblx0XHRcdCAqICBAdHlwZSAge1RvbmUuQ29tcHJlc3Nvcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuc2lkZSA9IG5ldyBUb25lLkNvbXByZXNzb3Iob3B0aW9ucy5zaWRlKTtcblx0ICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQubWlkLmNoYWluKHRoaXMubWlkLCB0aGlzLl9taWRTaWRlTWVyZ2UubWlkKTtcblx0ICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQuc2lkZS5jaGFpbih0aGlzLnNpZGUsIHRoaXMuX21pZFNpZGVNZXJnZS5zaWRlKTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdtaWQnLFxuXHQgICAgICAgICAgICAnc2lkZSdcblx0ICAgICAgICBdKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLk1pZFNpZGVDb21wcmVzc29yLCBUb25lLkF1ZGlvTm9kZSk7XG5cdCAgICAvKipcblx0XHQgKiAgQGNvbnN0XG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuTWlkU2lkZUNvbXByZXNzb3IuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ21pZCc6IHtcblx0ICAgICAgICAgICAgJ3JhdGlvJzogMyxcblx0ICAgICAgICAgICAgJ3RocmVzaG9sZCc6IC0yNCxcblx0ICAgICAgICAgICAgJ3JlbGVhc2UnOiAwLjAzLFxuXHQgICAgICAgICAgICAnYXR0YWNrJzogMC4wMixcblx0ICAgICAgICAgICAgJ2tuZWUnOiAxNlxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgJ3NpZGUnOiB7XG5cdCAgICAgICAgICAgICdyYXRpbyc6IDYsXG5cdCAgICAgICAgICAgICd0aHJlc2hvbGQnOiAtMzAsXG5cdCAgICAgICAgICAgICdyZWxlYXNlJzogMC4yNSxcblx0ICAgICAgICAgICAgJ2F0dGFjayc6IDAuMDMsXG5cdCAgICAgICAgICAgICdrbmVlJzogMTBcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5NaWRTaWRlQ29tcHJlc3Nvcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5NaWRTaWRlQ29tcHJlc3Nvci5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ21pZCcsXG5cdCAgICAgICAgICAgICdzaWRlJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLm1pZCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5zaWRlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLnNpZGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9taWRTaWRlTWVyZ2UuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX21pZFNpZGVNZXJnZSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuTWlkU2lkZUNvbXByZXNzb3I7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBUb25lLk1vbm8gY29lcmNlcyB0aGUgaW5jb21pbmcgbW9ubyBvciBzdGVyZW8gc2lnbmFsIGludG8gYSBtb25vIHNpZ25hbFxuXHRcdCAqICAgICAgICAgd2hlcmUgYm90aCBsZWZ0IGFuZCByaWdodCBjaGFubmVscyBoYXZlIHRoZSBzYW1lIHZhbHVlLiBUaGlzIGNhbiBiZSB1c2VmdWxcblx0XHQgKiAgICAgICAgIGZvciBbc3RlcmVvIGltYWdpbmddKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N0ZXJlb19pbWFnaW5nKS5cblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqL1xuXHQgICAgVG9uZS5Nb25vID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5jcmVhdGVJbnNPdXRzKDEsIDApO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIG1lcmdlIHRoZSBzaWduYWxcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5NZXJnZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbWVyZ2UgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLk1lcmdlKCk7XG5cdCAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX21lcmdlLCAwLCAwKTtcblx0ICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fbWVyZ2UsIDAsIDEpO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuTW9ubywgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk1vbm99IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTW9uby5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX21lcmdlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9tZXJnZSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuTW9ubztcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIEEgY29tcHJlc3NvciB3aXRoIHNlcGVyYXRlIGNvbnRyb2xzIG92ZXIgbG93L21pZC9oaWdoIGR5bmFtaWNzXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuQXVkaW9Ob2RlfVxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgVGhlIGxvdy9taWQvaGlnaCBjb21wcmVzc29yIHNldHRpbmdzLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqICB2YXIgbXVsdGliYW5kID0gbmV3IFRvbmUuTXVsdGliYW5kQ29tcHJlc3Nvcih7XG5cdFx0ICogIFx0XCJsb3dGcmVxdWVuY3lcIiA6IDIwMCxcblx0XHQgKiAgXHRcImhpZ2hGcmVxdWVuY3lcIiA6IDEzMDBcblx0XHQgKiAgXHRcImxvd1wiIDoge1xuXHRcdCAqICBcdFx0XCJ0aHJlc2hvbGRcIiA6IC0xMlxuXHRcdCAqICBcdH1cblx0XHQgKiAgfSlcblx0XHQgKi9cblx0ICAgIFRvbmUuTXVsdGliYW5kQ29tcHJlc3NvciA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgICAgICBvcHRpb25zID0gVG9uZS5kZWZhdWx0QXJnKGFyZ3VtZW50cywgVG9uZS5NdWx0aWJhbmRDb21wcmVzc29yLmRlZmF1bHRzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBzcGxpdCB0aGUgaW5jb21pbmcgc2lnbmFsIGludG8gaGlnaC9taWQvbG93XG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuTXVsdGliYW5kU3BsaXR9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3NwbGl0dGVyID0gdGhpcy5pbnB1dCA9IG5ldyBUb25lLk11bHRpYmFuZFNwbGl0KHtcblx0ICAgICAgICAgICAgJ2xvd0ZyZXF1ZW5jeSc6IG9wdGlvbnMubG93RnJlcXVlbmN5LFxuXHQgICAgICAgICAgICAnaGlnaEZyZXF1ZW5jeSc6IG9wdGlvbnMuaGlnaEZyZXF1ZW5jeVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGxvdy9taWQgY3Jvc3NvdmVyIGZyZXF1ZW5jeS5cblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubG93RnJlcXVlbmN5ID0gdGhpcy5fc3BsaXR0ZXIubG93RnJlcXVlbmN5O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIG1pZC9oaWdoIGNyb3Nzb3ZlciBmcmVxdWVuY3kuXG5cdFx0XHQgKiAgQHR5cGUge0ZyZXF1ZW5jeX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kgPSB0aGlzLl9zcGxpdHRlci5oaWdoRnJlcXVlbmN5O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBvdXRwdXRcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5HYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgY29tcHJlc3NvciBhcHBsaWVkIHRvIHRoZSBsb3cgZnJlcXVlbmNpZXMuXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQ29tcHJlc3Nvcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubG93ID0gbmV3IFRvbmUuQ29tcHJlc3NvcihvcHRpb25zLmxvdyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGNvbXByZXNzb3IgYXBwbGllZCB0byB0aGUgbWlkIGZyZXF1ZW5jaWVzLlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkNvbXByZXNzb3J9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLm1pZCA9IG5ldyBUb25lLkNvbXByZXNzb3Iob3B0aW9ucy5taWQpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBjb21wcmVzc29yIGFwcGxpZWQgdG8gdGhlIGhpZ2ggZnJlcXVlbmNpZXMuXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQ29tcHJlc3Nvcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuaGlnaCA9IG5ldyBUb25lLkNvbXByZXNzb3Iob3B0aW9ucy5oaWdoKTtcblx0ICAgICAgICAvL2Nvbm5lY3QgdGhlIGNvbXByZXNzb3Jcblx0ICAgICAgICB0aGlzLl9zcGxpdHRlci5sb3cuY2hhaW4odGhpcy5sb3csIHRoaXMub3V0cHV0KTtcblx0ICAgICAgICB0aGlzLl9zcGxpdHRlci5taWQuY2hhaW4odGhpcy5taWQsIHRoaXMub3V0cHV0KTtcblx0ICAgICAgICB0aGlzLl9zcGxpdHRlci5oaWdoLmNoYWluKHRoaXMuaGlnaCwgdGhpcy5vdXRwdXQpO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFtcblx0ICAgICAgICAgICAgJ2hpZ2gnLFxuXHQgICAgICAgICAgICAnbWlkJyxcblx0ICAgICAgICAgICAgJ2xvdycsXG5cdCAgICAgICAgICAgICdoaWdoRnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2xvd0ZyZXF1ZW5jeSdcblx0ICAgICAgICBdKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLk11bHRpYmFuZENvbXByZXNzb3IsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5NdWx0aWJhbmRDb21wcmVzc29yLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdsb3cnOiBUb25lLkNvbXByZXNzb3IuZGVmYXVsdHMsXG5cdCAgICAgICAgJ21pZCc6IFRvbmUuQ29tcHJlc3Nvci5kZWZhdWx0cyxcblx0ICAgICAgICAnaGlnaCc6IFRvbmUuQ29tcHJlc3Nvci5kZWZhdWx0cyxcblx0ICAgICAgICAnbG93RnJlcXVlbmN5JzogMjUwLFxuXHQgICAgICAgICdoaWdoRnJlcXVlbmN5JzogMjAwMFxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBjbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5NdWx0aWJhbmRDb21wcmVzc29yfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk11bHRpYmFuZENvbXByZXNzb3IucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9zcGxpdHRlci5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoW1xuXHQgICAgICAgICAgICAnaGlnaCcsXG5cdCAgICAgICAgICAgICdtaWQnLFxuXHQgICAgICAgICAgICAnbG93Jyxcblx0ICAgICAgICAgICAgJ2hpZ2hGcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnbG93RnJlcXVlbmN5J1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMubG93LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5oaWdoLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9zcGxpdHRlciA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5sb3cgPSBudWxsO1xuXHQgICAgICAgIHRoaXMubWlkID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmhpZ2ggPSBudWxsO1xuXHQgICAgICAgIHRoaXMubG93RnJlcXVlbmN5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLk11bHRpYmFuZENvbXByZXNzb3I7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIGlmIChUb25lLnN1cHBvcnRlZCAmJiAhd2luZG93LlN0ZXJlb1Bhbm5lck5vZGUpIHtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIEBjbGFzcyBTaGltbWVkIFN0ZXJlb1Bhbm5lck5vZGVcblx0XHRcdCAqIEBwYXJhbSAge0F1ZGlvQ29udGV4dH0gY29udGV4dFxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHZhciBTdGVyZW9QYW5uZXJOb2RlID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcblx0ICAgICAgICAgICAgLyoqXG5cdFx0XHRcdCAqIFRoZSBhdWRpbyBjb250ZXh0XG5cdFx0XHRcdCAqIEB0eXBlIHtBdWRpb0NvbnRleHR9XG5cdFx0XHRcdCAqL1xuXHQgICAgICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuXHQgICAgICAgICAgICAvKipcblx0XHRcdFx0ICogVGhlIGxlZnQvcmlnaHQgcGFubmluZy4gWy0xLCAxXVxuXHRcdFx0XHQgKiBAdHlwZSB7QXVkaW9SYW5nZX1cblx0XHRcdFx0ICogQHNpZ25hbFxuXHRcdFx0XHQgKi9cblx0ICAgICAgICAgICAgdGhpcy5wYW4gPSBuZXcgVG9uZS5TaWduYWwoMCwgVG9uZS5UeXBlLkF1ZGlvUmFuZ2UpO1xuXHQgICAgICAgICAgICAvKipcblx0XHRcdFx0ICogRXF1YWwgcG93ZXIgc2NhbGluZyBvZiB0aGUgcmlnaHQgZ2FpblxuXHRcdFx0XHQgKiBAdHlwZSB7VG9uZS5XYXZlU2hhcGVyfVxuXHRcdFx0XHQgKi9cblx0ICAgICAgICAgICAgdmFyIHJpZ2h0V2F2ZVNoYXBlciA9IG5ldyBUb25lLldhdmVTaGFwZXIoZnVuY3Rpb24gKHZhbCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIFRvbmUuZXF1YWxQb3dlclNjYWxlKCh2YWwgKyAxKSAvIDIpO1xuXHQgICAgICAgICAgICB9LCA0MDk2KTtcblx0ICAgICAgICAgICAgLyoqXG5cdFx0XHRcdCAqIEVxdWFsIHBvd2VyIHNjYWxpbmcgb2YgdGhlIGxlZnQgZ2FpblxuXHRcdFx0XHQgKiBAdHlwZSB7VG9uZS5XYXZlU2hhcGVyfVxuXHRcdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0XHQgKi9cblx0ICAgICAgICAgICAgdmFyIGxlZnRXYXZlU2hhcGVyID0gbmV3IFRvbmUuV2F2ZVNoYXBlcihmdW5jdGlvbiAodmFsKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gVG9uZS5lcXVhbFBvd2VyU2NhbGUoMSAtICh2YWwgKyAxKSAvIDIpO1xuXHQgICAgICAgICAgICB9LCA0MDk2KTtcblx0ICAgICAgICAgICAgLyoqXG5cdFx0XHRcdCAqIFRoZSBsZWZ0IGdhaW4gdmFsdWVcblx0XHRcdFx0ICogQHR5cGUge1RvbmUuR2Fpbn1cblx0XHRcdFx0ICogQHByaXZhdGVcblx0XHRcdFx0ICovXG5cdCAgICAgICAgICAgIHZhciBsZWZ0R2FpbiA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAgICAgLyoqXG5cdFx0XHRcdCAqIFRoZSByaWdodCBnYWluIHZhbHVlXG5cdFx0XHRcdCAqIEB0eXBlIHtUb25lLkdhaW59XG5cdFx0XHRcdCAqIEBwcml2YXRlXG5cdFx0XHRcdCAqL1xuXHQgICAgICAgICAgICB2YXIgcmlnaHRHYWluID0gbmV3IFRvbmUuR2FpbigpO1xuXHQgICAgICAgICAgICAvKipcblx0XHRcdFx0ICogU3BsaXQgdGhlIGluY29taW5nIHNpZ25hbFxuXHRcdFx0XHQgKiBAdHlwZSB7VG9uZS5TcGxpdH1cblx0XHRcdFx0ICogQHByaXZhdGVcblx0XHRcdFx0ICovXG5cdCAgICAgICAgICAgIHZhciBzcGxpdCA9IHRoaXMuaW5wdXQgPSBuZXcgVG9uZS5TcGxpdCgpO1xuXHQgICAgICAgICAgICAvKipcblx0XHRcdFx0ICogS2VlcHMgdGhlIHdhdmVzaGFwZXJzIGZyb20gb3B0aW1pemluZyAwc1xuXHRcdFx0XHQgKiBAdHlwZSB7VG9uZS5aZXJvfVxuXHRcdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0XHQgKi9cblx0ICAgICAgICAgICAgdmFyIHplcm8gPSBuZXcgVG9uZS5aZXJvKCk7XG5cdCAgICAgICAgICAgIHplcm8uZmFuKHJpZ2h0V2F2ZVNoYXBlciwgbGVmdFdhdmVTaGFwZXIpO1xuXHQgICAgICAgICAgICAvKipcblx0XHRcdFx0ICogTWVyZ2UgdGhlIG91dGdvaW5nIHNpZ25hbFxuXHRcdFx0XHQgKiBAdHlwZSB7VG9uZS5NZXJnZX1cblx0XHRcdFx0ICogQHByaXZhdGVcblx0XHRcdFx0ICovXG5cdCAgICAgICAgICAgIHZhciBtZXJnZSA9IHRoaXMub3V0cHV0ID0gbmV3IFRvbmUuTWVyZ2UoKTtcblx0ICAgICAgICAgICAgLy9jb25uZWN0aW9uc1xuXHQgICAgICAgICAgICBzcGxpdC5sZWZ0LmNoYWluKGxlZnRHYWluLCBtZXJnZS5sZWZ0KTtcblx0ICAgICAgICAgICAgc3BsaXQucmlnaHQuY2hhaW4ocmlnaHRHYWluLCBtZXJnZS5yaWdodCk7XG5cdCAgICAgICAgICAgIHRoaXMucGFuLmNoYWluKGxlZnRXYXZlU2hhcGVyLCBsZWZ0R2Fpbi5nYWluKTtcblx0ICAgICAgICAgICAgdGhpcy5wYW4uY2hhaW4ocmlnaHRXYXZlU2hhcGVyLCByaWdodEdhaW4uZ2Fpbik7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICBTdGVyZW9QYW5uZXJOb2RlLnByb3RvdHlwZS5kaXNjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB0aGlzLm91dHB1dC5kaXNjb25uZWN0LmFwcGx5KHRoaXMub3V0cHV0LCBhcmd1bWVudHMpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgU3RlcmVvUGFubmVyTm9kZS5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdGhpcy5vdXRwdXQuY29ubmVjdC5hcHBseSh0aGlzLm91dHB1dCwgYXJndW1lbnRzKTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8vYWRkIGl0IHRvIHRoZSBBdWRpb0NvbnRleHRcblx0ICAgICAgICBBdWRpb0NvbnRleHQucHJvdG90eXBlLmNyZWF0ZVN0ZXJlb1Bhbm5lciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIG5ldyBTdGVyZW9QYW5uZXJOb2RlKHRoaXMpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgVG9uZS5Db250ZXh0LnByb3RvdHlwZS5jcmVhdGVTdGVyZW9QYW5uZXIgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgU3RlcmVvUGFubmVyTm9kZSh0aGlzKTtcblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIFRvbmUuUGFubmVyIGlzIGFuIGVxdWFsIHBvd2VyIExlZnQvUmlnaHQgUGFubmVyIGFuZCBkb2VzIG5vdFxuXHRcdCAqICAgICAgICAgIHN1cHBvcnQgM0QuIFBhbm5lciB1c2VzIHRoZSBTdGVyZW9QYW5uZXJOb2RlIHdoZW4gYXZhaWxhYmxlLlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBwYXJhbSB7Tm9ybWFsUmFuZ2V9IFtpbml0aWFsUGFuPTBdIFRoZSBpbml0YWlsIHBhbm5lciB2YWx1ZSAoY2VudGVyKS5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAgLy9wYW4gdGhlIGlucHV0IHNpZ25hbCBoYXJkIHJpZ2h0LlxuXHRcdCAqICB2YXIgcGFubmVyID0gbmV3IFRvbmUuUGFubmVyKDEpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYW5uZXIgPSBmdW5jdGlvbiAoaW5pdGlhbFBhbikge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQqICB0aGUgcGFubmVyIG5vZGVcblx0XHRcdCogIEB0eXBlIHtTdGVyZW9QYW5uZXJOb2RlfVxuXHRcdFx0KiAgQHByaXZhdGVcblx0XHRcdCovXG5cdCAgICAgICAgdGhpcy5fcGFubmVyID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZVN0ZXJlb1Bhbm5lcigpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0KiAgVGhlIHBhbiBjb250cm9sLiAtMSA9IGhhcmQgbGVmdCwgMSA9IGhhcmQgcmlnaHQuXG5cdFx0XHQqICBAdHlwZSB7QXVkaW9SYW5nZX1cblx0XHRcdCogIEBzaWduYWxcblx0XHRcdCovXG5cdCAgICAgICAgdGhpcy5wYW4gPSB0aGlzLl9wYW5uZXIucGFuO1xuXHQgICAgICAgIC8vaW5pdGlhbCB2YWx1ZVxuXHQgICAgICAgIHRoaXMucGFuLnZhbHVlID0gVG9uZS5kZWZhdWx0QXJnKGluaXRpYWxQYW4sIDApO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KCdwYW4nKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlBhbm5lciwgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5QYW5uZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFubmVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoJ3BhbicpO1xuXHQgICAgICAgIHRoaXMuX3Bhbm5lci5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgdGhpcy5fcGFubmVyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLnBhbiA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuUGFubmVyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIEEgc3BhdGlhbGl6ZWQgcGFubmVyIG5vZGUgd2hpY2ggc3VwcG9ydHMgZXF1YWxwb3dlciBvciBIUlRGIHBhbm5pbmcuXG5cdFx0ICogICAgICAgICAgVHJpZXMgdG8gbm9ybWFsaXplIHRoZSBBUEkgYWNyb3NzIHZhcmlvdXMgYnJvd3NlcnMuIFNlZSBUb25lLkxpc3RlbmVyXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkF1ZGlvTm9kZX1cblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ9IHBvc2l0aW9uWCBUaGUgaW5pdGlhbCB4IHBvc2l0aW9uLlxuXHRcdCAqICBAcGFyYW0ge051bWJlcn0gcG9zaXRpb25ZIFRoZSBpbml0aWFsIHkgcG9zaXRpb24uXG5cdFx0ICogIEBwYXJhbSB7TnVtYmVyfSBwb3NpdGlvblogVGhlIGluaXRpYWwgeiBwb3NpdGlvbi5cblx0XHQgKi9cblx0ICAgIFRvbmUuUGFubmVyM0QgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAncG9zaXRpb25YJyxcblx0ICAgICAgICAgICAgJ3Bvc2l0aW9uWScsXG5cdCAgICAgICAgICAgICdwb3NpdGlvblonXG5cdCAgICAgICAgXSwgVG9uZS5QYW5uZXIzRCk7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgcGFubmVyIG5vZGVcblx0XHRcdCAqICBAdHlwZSB7UGFubmVyTm9kZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fcGFubmVyID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZVBhbm5lcigpO1xuXHQgICAgICAgIC8vc2V0IHNvbWUgdmFsdWVzXG5cdCAgICAgICAgdGhpcy5fcGFubmVyLnBhbm5pbmdNb2RlbCA9IG9wdGlvbnMucGFubmluZ01vZGVsO1xuXHQgICAgICAgIHRoaXMuX3Bhbm5lci5tYXhEaXN0YW5jZSA9IG9wdGlvbnMubWF4RGlzdGFuY2U7XG5cdCAgICAgICAgdGhpcy5fcGFubmVyLmRpc3RhbmNlTW9kZWwgPSBvcHRpb25zLmRpc3RhbmNlTW9kZWw7XG5cdCAgICAgICAgdGhpcy5fcGFubmVyLmNvbmVPdXRlckdhaW4gPSBvcHRpb25zLmNvbmVPdXRlckdhaW47XG5cdCAgICAgICAgdGhpcy5fcGFubmVyLmNvbmVPdXRlckFuZ2xlID0gb3B0aW9ucy5jb25lT3V0ZXJBbmdsZTtcblx0ICAgICAgICB0aGlzLl9wYW5uZXIuY29uZUlubmVyQW5nbGUgPSBvcHRpb25zLmNvbmVJbm5lckFuZ2xlO1xuXHQgICAgICAgIHRoaXMuX3Bhbm5lci5yZWZEaXN0YW5jZSA9IG9wdGlvbnMucmVmRGlzdGFuY2U7XG5cdCAgICAgICAgdGhpcy5fcGFubmVyLnJvbGxvZmZGYWN0b3IgPSBvcHRpb25zLnJvbGxvZmZGYWN0b3I7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgSG9sZHMgdGhlIGN1cnJlbnQgb3JpZW50YXRpb25cblx0XHRcdCAqICBAdHlwZSAge0FycmF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9vcmllbnRhdGlvbiA9IFtcblx0ICAgICAgICAgICAgb3B0aW9ucy5vcmllbnRhdGlvblgsXG5cdCAgICAgICAgICAgIG9wdGlvbnMub3JpZW50YXRpb25ZLFxuXHQgICAgICAgICAgICBvcHRpb25zLm9yaWVudGF0aW9uWlxuXHQgICAgICAgIF07XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgSG9sZHMgdGhlIGN1cnJlbnQgcG9zaXRpb25cblx0XHRcdCAqICBAdHlwZSAge0FycmF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9wb3NpdGlvbiA9IFtcblx0ICAgICAgICAgICAgb3B0aW9ucy5wb3NpdGlvblgsXG5cdCAgICAgICAgICAgIG9wdGlvbnMucG9zaXRpb25ZLFxuXHQgICAgICAgICAgICBvcHRpb25zLnBvc2l0aW9uWlxuXHQgICAgICAgIF07XG5cdCAgICAgICAgLy8gc2V0IHRoZSBkZWZhdWx0IHBvc2l0aW9uL29yaWVudGF0aW9uXG5cdCAgICAgICAgdGhpcy5vcmllbnRhdGlvblggPSBvcHRpb25zLm9yaWVudGF0aW9uWDtcblx0ICAgICAgICB0aGlzLm9yaWVudGF0aW9uWSA9IG9wdGlvbnMub3JpZW50YXRpb25ZO1xuXHQgICAgICAgIHRoaXMub3JpZW50YXRpb25aID0gb3B0aW9ucy5vcmllbnRhdGlvblo7XG5cdCAgICAgICAgdGhpcy5wb3NpdGlvblggPSBvcHRpb25zLnBvc2l0aW9uWDtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uWSA9IG9wdGlvbnMucG9zaXRpb25ZO1xuXHQgICAgICAgIHRoaXMucG9zaXRpb25aID0gb3B0aW9ucy5wb3NpdGlvblo7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5QYW5uZXIzRCwgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIERlZmF1bHRzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvblxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBjb25zdFxuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QYW5uZXIzRC5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAncG9zaXRpb25YJzogMCxcblx0ICAgICAgICAncG9zaXRpb25ZJzogMCxcblx0ICAgICAgICAncG9zaXRpb25aJzogMCxcblx0ICAgICAgICAnb3JpZW50YXRpb25YJzogMCxcblx0ICAgICAgICAnb3JpZW50YXRpb25ZJzogMCxcblx0ICAgICAgICAnb3JpZW50YXRpb25aJzogMCxcblx0ICAgICAgICAncGFubmluZ01vZGVsJzogJ2VxdWFscG93ZXInLFxuXHQgICAgICAgICdtYXhEaXN0YW5jZSc6IDEwMDAwLFxuXHQgICAgICAgICdkaXN0YW5jZU1vZGVsJzogJ2ludmVyc2UnLFxuXHQgICAgICAgICdjb25lT3V0ZXJHYWluJzogMCxcblx0ICAgICAgICAnY29uZU91dGVyQW5nbGUnOiAzNjAsXG5cdCAgICAgICAgJ2NvbmVJbm5lckFuZ2xlJzogMzYwLFxuXHQgICAgICAgICdyZWZEaXN0YW5jZSc6IDEsXG5cdCAgICAgICAgJ3JvbGxvZmZGYWN0b3InOiAxXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHJhbXAgdGltZSB3aGljaCBpcyBhcHBsaWVkIHRvIHRoZSBzZXRUYXJnZXRBdFRpbWVcblx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlBhbm5lcjNELnByb3RvdHlwZS5fcmFtcFRpbWVDb25zdGFudCA9IDAuMDE7XG5cdCAgICAvKipcblx0XHQgKiAgU2V0cyB0aGUgcG9zaXRpb24gb2YgdGhlIHNvdXJjZSBpbiAzZCBzcGFjZS5cblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgeFxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICB5XG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHpcblx0XHQgKiAgQHJldHVybiB7VG9uZS5QYW5uZXIzRH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYW5uZXIzRC5wcm90b3R5cGUuc2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoeCwgeSwgeikge1xuXHQgICAgICAgIGlmICh0aGlzLl9wYW5uZXIucG9zaXRpb25YKSB7XG5cdCAgICAgICAgICAgIHZhciBub3cgPSB0aGlzLm5vdygpO1xuXHQgICAgICAgICAgICB0aGlzLl9wYW5uZXIucG9zaXRpb25YLnNldFRhcmdldEF0VGltZSh4LCBub3csIHRoaXMuX3JhbXBUaW1lQ29uc3RhbnQpO1xuXHQgICAgICAgICAgICB0aGlzLl9wYW5uZXIucG9zaXRpb25ZLnNldFRhcmdldEF0VGltZSh5LCBub3csIHRoaXMuX3JhbXBUaW1lQ29uc3RhbnQpO1xuXHQgICAgICAgICAgICB0aGlzLl9wYW5uZXIucG9zaXRpb25aLnNldFRhcmdldEF0VGltZSh6LCBub3csIHRoaXMuX3JhbXBUaW1lQ29uc3RhbnQpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3Bhbm5lci5zZXRQb3NpdGlvbih4LCB5LCB6KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5fcG9zaXRpb24gPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTZXRzIHRoZSBvcmllbnRhdGlvbiBvZiB0aGUgc291cmNlIGluIDNkIHNwYWNlLlxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICB4XG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHlcblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgelxuXHRcdCAqICBAcmV0dXJuIHtUb25lLlBhbm5lcjNEfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlBhbm5lcjNELnByb3RvdHlwZS5zZXRPcmllbnRhdGlvbiA9IGZ1bmN0aW9uICh4LCB5LCB6KSB7XG5cdCAgICAgICAgaWYgKHRoaXMuX3Bhbm5lci5vcmllbnRhdGlvblgpIHtcblx0ICAgICAgICAgICAgdmFyIG5vdyA9IHRoaXMubm93KCk7XG5cdCAgICAgICAgICAgIHRoaXMuX3Bhbm5lci5vcmllbnRhdGlvblguc2V0VGFyZ2V0QXRUaW1lKHgsIG5vdywgdGhpcy5fcmFtcFRpbWVDb25zdGFudCk7XG5cdCAgICAgICAgICAgIHRoaXMuX3Bhbm5lci5vcmllbnRhdGlvblkuc2V0VGFyZ2V0QXRUaW1lKHksIG5vdywgdGhpcy5fcmFtcFRpbWVDb25zdGFudCk7XG5cdCAgICAgICAgICAgIHRoaXMuX3Bhbm5lci5vcmllbnRhdGlvblouc2V0VGFyZ2V0QXRUaW1lKHosIG5vdywgdGhpcy5fcmFtcFRpbWVDb25zdGFudCk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGhpcy5fcGFubmVyLnNldE9yaWVudGF0aW9uKHgsIHksIHopO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl9vcmllbnRhdGlvbiA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSB4IHBvc2l0aW9uIG9mIHRoZSBwYW5uZXIgb2JqZWN0LlxuXHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5QYW5uZXIzRCNcblx0XHQgKiAgQG5hbWUgcG9zaXRpb25YXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QYW5uZXIzRC5wcm90b3R5cGUsICdwb3NpdGlvblgnLCB7XG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocG9zKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3Bvc2l0aW9uWzBdID0gcG9zO1xuXHQgICAgICAgICAgICB0aGlzLnNldFBvc2l0aW9uLmFwcGx5KHRoaXMsIHRoaXMuX3Bvc2l0aW9uKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fcG9zaXRpb25bMF07XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHkgcG9zaXRpb24gb2YgdGhlIHBhbm5lciBvYmplY3QuXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlBhbm5lcjNEI1xuXHRcdCAqICBAbmFtZSBwb3NpdGlvbllcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBhbm5lcjNELnByb3RvdHlwZSwgJ3Bvc2l0aW9uWScsIHtcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwb3MpIHtcblx0ICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25bMV0gPSBwb3M7XG5cdCAgICAgICAgICAgIHRoaXMuc2V0UG9zaXRpb24uYXBwbHkodGhpcywgdGhpcy5fcG9zaXRpb24pO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9wb3NpdGlvblsxXTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgeiBwb3NpdGlvbiBvZiB0aGUgcGFubmVyIG9iamVjdC5cblx0XHQgKiAgQHR5cGUge051bWJlcn1cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuUGFubmVyM0QjXG5cdFx0ICogIEBuYW1lIHBvc2l0aW9uWlxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGFubmVyM0QucHJvdG90eXBlLCAncG9zaXRpb25aJywge1xuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHBvcykge1xuXHQgICAgICAgICAgICB0aGlzLl9wb3NpdGlvblsyXSA9IHBvcztcblx0ICAgICAgICAgICAgdGhpcy5zZXRQb3NpdGlvbi5hcHBseSh0aGlzLCB0aGlzLl9wb3NpdGlvbik7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Bvc2l0aW9uWzJdO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSB4IG9yaWVudGF0aW9uIG9mIHRoZSBwYW5uZXIgb2JqZWN0LlxuXHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5QYW5uZXIzRCNcblx0XHQgKiAgQG5hbWUgb3JpZW50YXRpb25YXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QYW5uZXIzRC5wcm90b3R5cGUsICdvcmllbnRhdGlvblgnLCB7XG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocG9zKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX29yaWVudGF0aW9uWzBdID0gcG9zO1xuXHQgICAgICAgICAgICB0aGlzLnNldE9yaWVudGF0aW9uLmFwcGx5KHRoaXMsIHRoaXMuX29yaWVudGF0aW9uKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fb3JpZW50YXRpb25bMF07XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHkgb3JpZW50YXRpb24gb2YgdGhlIHBhbm5lciBvYmplY3QuXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlBhbm5lcjNEI1xuXHRcdCAqICBAbmFtZSBvcmllbnRhdGlvbllcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBhbm5lcjNELnByb3RvdHlwZSwgJ29yaWVudGF0aW9uWScsIHtcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwb3MpIHtcblx0ICAgICAgICAgICAgdGhpcy5fb3JpZW50YXRpb25bMV0gPSBwb3M7XG5cdCAgICAgICAgICAgIHRoaXMuc2V0T3JpZW50YXRpb24uYXBwbHkodGhpcywgdGhpcy5fb3JpZW50YXRpb24pO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcmllbnRhdGlvblsxXTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgeiBvcmllbnRhdGlvbiBvZiB0aGUgcGFubmVyIG9iamVjdC5cblx0XHQgKiAgQHR5cGUge051bWJlcn1cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuUGFubmVyM0QjXG5cdFx0ICogIEBuYW1lIG9yaWVudGF0aW9uWlxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGFubmVyM0QucHJvdG90eXBlLCAnb3JpZW50YXRpb25aJywge1xuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHBvcykge1xuXHQgICAgICAgICAgICB0aGlzLl9vcmllbnRhdGlvblsyXSA9IHBvcztcblx0ICAgICAgICAgICAgdGhpcy5zZXRPcmllbnRhdGlvbi5hcHBseSh0aGlzLCB0aGlzLl9vcmllbnRhdGlvbik7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uWzJdO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFByb3h5IGEgcHJvcGVydHkgb24gdGhlIHBhbm5lciB0byBhbiBleHBvc2VkIHB1YmxpYyBwcm9wZXJ5XG5cdFx0ICogIEBwYXJhbSAge1N0cmluZ30gIHByb3Bcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFubmVyM0QuX2FsaWFzUHJvcGVydHkgPSBmdW5jdGlvbiAocHJvcCkge1xuXHQgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBhbm5lcjNELnByb3RvdHlwZSwgcHJvcCwge1xuXHQgICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWwpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3Bhbm5lcltwcm9wXSA9IHZhbDtcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyW3Byb3BdO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBwYW5uaW5nIG1vZGVsLiBFaXRoZXIgXCJlcXVhbHBvd2VyXCIgb3IgXCJIUlRGXCIuXG5cdFx0ICogIEB0eXBlIHtTdHJpbmd9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlBhbm5lcjNEI1xuXHRcdCAqICBAbmFtZSBwYW5uaW5nTW9kZWxcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFubmVyM0QuX2FsaWFzUHJvcGVydHkoJ3Bhbm5pbmdNb2RlbCcpO1xuXHQgICAgLyoqXG5cdFx0ICogIEEgcmVmZXJlbmNlIGRpc3RhbmNlIGZvciByZWR1Y2luZyB2b2x1bWUgYXMgc291cmNlIG1vdmUgZnVydGhlciBmcm9tIHRoZSBsaXN0ZW5lclxuXHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5QYW5uZXIzRCNcblx0XHQgKiAgQG5hbWUgcmVmRGlzdGFuY2Vcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFubmVyM0QuX2FsaWFzUHJvcGVydHkoJ3JlZkRpc3RhbmNlJyk7XG5cdCAgICAvKipcblx0XHQgKiAgRGVzY3JpYmVzIGhvdyBxdWlja2x5IHRoZSB2b2x1bWUgaXMgcmVkdWNlZCBhcyBzb3VyY2UgbW92ZXMgYXdheSBmcm9tIGxpc3RlbmVyLlxuXHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5QYW5uZXIzRCNcblx0XHQgKiAgQG5hbWUgcm9sbG9mZkZhY3RvclxuXHRcdCAqL1xuXHQgICAgVG9uZS5QYW5uZXIzRC5fYWxpYXNQcm9wZXJ0eSgncm9sbG9mZkZhY3RvcicpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkaXN0YW5jZSBtb2RlbCB1c2VkIGJ5LCAgXCJsaW5lYXJcIiwgXCJpbnZlcnNlXCIsIG9yIFwiZXhwb25lbnRpYWxcIi5cblx0XHQgKiAgQHR5cGUge1N0cmluZ31cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuUGFubmVyM0QjXG5cdFx0ICogIEBuYW1lIGRpc3RhbmNlTW9kZWxcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFubmVyM0QuX2FsaWFzUHJvcGVydHkoJ2Rpc3RhbmNlTW9kZWwnKTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgYW5nbGUsIGluIGRlZ3JlZXMsIGluc2lkZSBvZiB3aGljaCB0aGVyZSB3aWxsIGJlIG5vIHZvbHVtZSByZWR1Y3Rpb25cblx0XHQgKiAgQHR5cGUge0RlZ3JlZXN9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlBhbm5lcjNEI1xuXHRcdCAqICBAbmFtZSBjb25lSW5uZXJBbmdsZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QYW5uZXIzRC5fYWxpYXNQcm9wZXJ0eSgnY29uZUlubmVyQW5nbGUnKTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgYW5nbGUsIGluIGRlZ3JlZXMsIG91dHNpZGUgb2Ygd2hpY2ggdGhlIHZvbHVtZSB3aWxsIGJlIHJlZHVjZWRcblx0XHQgKiAgdG8gYSBjb25zdGFudCB2YWx1ZSBvZiBjb25lT3V0ZXJHYWluXG5cdFx0ICogIEB0eXBlIHtEZWdyZWVzfVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5QYW5uZXIzRCNcblx0XHQgKiAgQG5hbWUgY29uZU91dGVyQW5nbGVcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFubmVyM0QuX2FsaWFzUHJvcGVydHkoJ2NvbmVPdXRlckFuZ2xlJyk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGdhaW4gb3V0c2lkZSBvZiB0aGUgY29uZU91dGVyQW5nbGVcblx0XHQgKiAgQHR5cGUge0dhaW59XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlBhbm5lcjNEI1xuXHRcdCAqICBAbmFtZSBjb25lT3V0ZXJHYWluXG5cdFx0ICovXG5cdCAgICBUb25lLlBhbm5lcjNELl9hbGlhc1Byb3BlcnR5KCdjb25lT3V0ZXJHYWluJyk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIG1heGltdW0gZGlzdGFuY2UgYmV0d2VlbiBzb3VyY2UgYW5kIGxpc3RlbmVyLFxuXHRcdCAqICBhZnRlciB3aGljaCB0aGUgdm9sdW1lIHdpbGwgbm90IGJlIHJlZHVjZWQgYW55IGZ1cnRoZXIuXG5cdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuUGFubmVyM0QjXG5cdFx0ICogIEBuYW1lIG1heERpc3RhbmNlXG5cdFx0ICovXG5cdCAgICBUb25lLlBhbm5lcjNELl9hbGlhc1Byb3BlcnR5KCdtYXhEaXN0YW5jZScpO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5QYW5uZXIzRH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYW5uZXIzRC5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3Bhbm5lci5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgdGhpcy5fcGFubmVyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9vcmllbnRhdGlvbiA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fcG9zaXRpb24gPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlBhbm5lcjNEO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5QYW5Wb2wgaXMgYSBUb25lLlBhbm5lciBhbmQgVG9uZS5Wb2x1bWUgaW4gb25lLlxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkF1ZGlvTm9kZX1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBwYXJhbSB7QXVkaW9SYW5nZX0gcGFuIHRoZSBpbml0aWFsIHBhblxuXHRcdCAqICBAcGFyYW0ge251bWJlcn0gdm9sdW1lIFRoZSBvdXRwdXQgdm9sdW1lLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vcGFuIHRoZSBpbmNvbWluZyBzaWduYWwgbGVmdCBhbmQgZHJvcCB0aGUgdm9sdW1lXG5cdFx0ICogdmFyIHBhblZvbCA9IG5ldyBUb25lLlBhblZvbCgtMC4yNSwgLTEyKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFuVm9sID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ3BhbicsXG5cdCAgICAgICAgICAgICd2b2x1bWUnXG5cdCAgICAgICAgXSwgVG9uZS5QYW5Wb2wpO1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHBhbm5pbmcgbm9kZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLlBhbm5lcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fcGFubmVyID0gdGhpcy5pbnB1dCA9IG5ldyBUb25lLlBhbm5lcihvcHRpb25zLnBhbik7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIEwvUiBwYW5uaW5nIGNvbnRyb2wuXG5cdFx0XHQgKiAgQHR5cGUge0F1ZGlvUmFuZ2V9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5wYW4gPSB0aGlzLl9wYW5uZXIucGFuO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSB2b2x1bWUgbm9kZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLlZvbHVtZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fdm9sdW1lID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZS5Wb2x1bWUob3B0aW9ucy52b2x1bWUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSB2b2x1bWUgY29udHJvbCBpbiBkZWNpYmVscy5cblx0XHRcdCAqICBAdHlwZSB7RGVjaWJlbHN9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuXHQgICAgICAgIC8vY29ubmVjdGlvbnNcblx0ICAgICAgICB0aGlzLl9wYW5uZXIuY29ubmVjdCh0aGlzLl92b2x1bWUpO1xuXHQgICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdwYW4nLFxuXHQgICAgICAgICAgICAndm9sdW1lJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuUGFuVm9sLCBUb25lLkF1ZGlvTm9kZSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGRlZmF1bHRzXG5cdFx0ICogIEB0eXBlICB7T2JqZWN0fVxuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYW5Wb2wuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ3Bhbic6IDAsXG5cdCAgICAgICAgJ3ZvbHVtZSc6IDAsXG5cdCAgICAgICAgJ211dGUnOiBmYWxzZVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIE11dGUvdW5tdXRlIHRoZSB2b2x1bWVcblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5QYW5Wb2wjXG5cdFx0ICogQG5hbWUgbXV0ZVxuXHRcdCAqIEB0eXBlIHtCb29sZWFufVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGFuVm9sLnByb3RvdHlwZSwgJ211dGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl92b2x1bWUubXV0ZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKG11dGUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fdm9sdW1lLm11dGUgPSBtdXRlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBhblZvbH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYW5Wb2wucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbXG5cdCAgICAgICAgICAgICdwYW4nLFxuXHQgICAgICAgICAgICAndm9sdW1lJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMuX3Bhbm5lci5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fcGFubmVyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLnBhbiA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fdm9sdW1lLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl92b2x1bWUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMudm9sdW1lID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5QYW5Wb2w7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5Tb2xvIGxldHMgeW91IGlzb2xhdGUgYSBzcGVjaWZpYyBhdWRpbyBzdHJlYW0uIFdoZW5cblx0XHQgKiAgICAgICAgIGFuIGluc3RhbmNlIGlzIHNldCB0byBgc29sbz10cnVlYCwgaXQgd2lsbCBtdXRlIGFsbCBvdGhlciBpbnN0YW5jZXMuXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkF1ZGlvTm9kZX1cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgc29sb0EgPSBuZXcgVG9uZS5Tb2xvKClcblx0XHQgKiB2YXIgc29sb0IgPSBuZXcgVG9uZS5Tb2xvKClcblx0XHQgKiBzb2xvQS5zb2xvID0gdHJ1ZVxuXHRcdCAqIC8vbm8gYXVkaW8gd2lsbCBwYXNzIHRocm91Z2ggc29sb0Jcblx0XHQgKi9cblx0ICAgIFRvbmUuU29sbyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbJ3NvbG8nXSwgVG9uZS5Tb2xvKTtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBpbnB1dCBhbmQgb3V0cHV0IG5vZGVcblx0XHRcdCAqICBAdHlwZSAge1RvbmUuR2Fpbn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBBIGJvdW5kIF9zb2xvZWQgbWV0aG9kXG5cdFx0XHQgKiAgQHR5cGUgIHtGdW5jdGlvbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc29sb0JpbmQgPSB0aGlzLl9zb2xvZWQuYmluZCh0aGlzKTtcblx0ICAgICAgICAvL2xpc3RlbiBmb3Igc29sbyBldmVudHMgY2xhc3Mtd2lkZS5cblx0ICAgICAgICB0aGlzLmNvbnRleHQub24oJ3NvbG8nLCB0aGlzLl9zb2xvQmluZCk7XG5cdCAgICAgICAgLy9zZXQgaW5pdGlhbGx5XG5cdCAgICAgICAgdGhpcy5zb2xvID0gb3B0aW9ucy5zb2xvO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuU29sbywgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0c1xuXHRcdCAqICBAdHlwZSAge09iamVjdH1cblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Tb2xvLmRlZmF1bHRzID0geyBzb2xvOiBmYWxzZSB9O1xuXHQgICAgLyoqXG5cdFx0ICogIElzb2xhdGVzIHRoaXMgaW5zdGFuY2UgYW5kIG11dGVzIGFsbCBvdGhlciBpbnN0YW5jZXMgb2YgVG9uZS5Tb2xvLlxuXHRcdCAqICBPbmx5IG9uZSBpbnN0YW5jZSBjYW4gYmUgc29sb2VkIGF0IGEgdGltZS4gQSBzb2xvZWRcblx0XHQgKiAgaW5zdGFuY2Ugd2lsbCByZXBvcnQgYHNvbG89ZmFsc2VgIHdoZW4gYW5vdGhlciBpbnN0YW5jZSBpcyBzb2xvZWQuXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlNvbG8jXG5cdFx0ICogIEB0eXBlIHtCb29sZWFufVxuXHRcdCAqICBAbmFtZSBzb2xvXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5Tb2xvLnByb3RvdHlwZSwgJ3NvbG8nLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9pc1NvbG9lZCgpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoc29sbykge1xuXHQgICAgICAgICAgICBpZiAoc29sbykge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fYWRkU29sbygpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlU29sbygpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuY29udGV4dC5lbWl0KCdzb2xvJywgdGhpcyk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgSWYgdGhlIGN1cnJlbnQgaW5zdGFuY2UgaXMgbXV0ZWQsIGkuZS4gYW5vdGhlciBpbnN0YW5jZSBpcyBzb2xvZWRcblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuU29sbyNcblx0XHQgKiAgQHR5cGUge0Jvb2xlYW59XG5cdFx0ICogIEBuYW1lIG11dGVkXG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuU29sby5wcm90b3R5cGUsICdtdXRlZCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXQuZ2Fpbi52YWx1ZSA9PT0gMDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIEFkZCB0aGlzIHRvIHRoZSBzb2xvZWQgYXJyYXlcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Tb2xvLnByb3RvdHlwZS5fYWRkU29sbyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBpZiAoIVRvbmUuaXNBcnJheSh0aGlzLmNvbnRleHQuX2N1cnJlbnRTb2xvKSkge1xuXHQgICAgICAgICAgICB0aGlzLmNvbnRleHQuX2N1cnJlbnRTb2xvID0gW107XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICghdGhpcy5faXNTb2xvZWQoKSkge1xuXHQgICAgICAgICAgICB0aGlzLmNvbnRleHQuX2N1cnJlbnRTb2xvLnB1c2godGhpcyk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFJlbW92ZSB0aGlzIGZyb20gdGhlIHNvbG9lZCBhcnJheVxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlNvbG8ucHJvdG90eXBlLl9yZW1vdmVTb2xvID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGlmICh0aGlzLl9pc1NvbG9lZCgpKSB7XG5cdCAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMuY29udGV4dC5fY3VycmVudFNvbG8uaW5kZXhPZih0aGlzKTtcblx0ICAgICAgICAgICAgdGhpcy5jb250ZXh0Ll9jdXJyZW50U29sby5zcGxpY2UoaW5kZXgsIDEpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBAcmV0dXJuIHtCb29sZWFufSBJcyB0aGlzIG9uIHRoZSBzb2xvZWQgYXJyYXlcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Tb2xvLnByb3RvdHlwZS5faXNTb2xvZWQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgaWYgKFRvbmUuaXNBcnJheSh0aGlzLmNvbnRleHQuX2N1cnJlbnRTb2xvKSkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0Ll9jdXJyZW50U29sby5sZW5ndGggIT09IDAgJiYgdGhpcy5jb250ZXh0Ll9jdXJyZW50U29sby5pbmRleE9mKHRoaXMpICE9PSAtMTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIEByZXR1cm4ge0Jvb2xlYW59IFJldHVybnMgdHJ1ZSBpZiBubyBvbmUgaXMgc29sb2VkXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuU29sby5wcm90b3R5cGUuX25vU29sb3MgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuICFUb25lLmlzQXJyYXkodGhpcy5jb250ZXh0Ll9jdXJyZW50U29sbykgfHwgdGhpcy5jb250ZXh0Ll9jdXJyZW50U29sby5sZW5ndGggPT09IDA7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFNvbG8gdGhlIGN1cnJlbnQgaW5zdGFuY2UgYW5kIHVuc29sbyBhbGwgb3RoZXIgaW5zdGFuY2VzLlxuXHRcdCAqICBAcGFyYW0gIHtUb25lLlNvbG99ICBpbnN0YW5jZSAgVGhlIGluc3RhbmNlIHdoaWNoIGlzIGJlaW5nIHNvbG9lZC91bnNvbG9lZC5cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuU29sby5wcm90b3R5cGUuX3NvbG9lZCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBpZiAodGhpcy5faXNTb2xvZWQoKSkge1xuXHQgICAgICAgICAgICB0aGlzLmlucHV0LmdhaW4udmFsdWUgPSAxO1xuXHQgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fbm9Tb2xvcygpKSB7XG5cdCAgICAgICAgICAgIC8vbm8gb25lIGlzIHNvbG9lZFxuXHQgICAgICAgICAgICB0aGlzLmlucHV0LmdhaW4udmFsdWUgPSAxO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRoaXMuaW5wdXQuZ2Fpbi52YWx1ZSA9IDA7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5Tb2xvfSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Tb2xvLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuY29udGV4dC5vZmYoJ3NvbG8nLCB0aGlzLl9zb2xvQmluZCk7XG5cdCAgICAgICAgdGhpcy5fcmVtb3ZlU29sbygpO1xuXHQgICAgICAgIHRoaXMuX3NvbG9CaW5kID0gbnVsbDtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlNvbG87XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIEdldCB0aGUgY3VycmVudCB3YXZlZm9ybSBkYXRhIG9mIHRoZSBjb25uZWN0ZWQgYXVkaW8gc291cmNlLlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5BdWRpb05vZGV9XG5cdFx0ICogIEBwYXJhbSB7TnVtYmVyPX0gc2l6ZSBUaGUgc2l6ZSBvZiB0aGUgRkZULiBWYWx1ZSBtdXN0IGJlIGEgcG93ZXIgb2Zcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgdHdvIGluIHRoZSByYW5nZSAzMiB0byAzMjc2OC5cblx0XHQgKi9cblx0ICAgIFRvbmUuV2F2ZWZvcm0gPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgWydzaXplJ10sIFRvbmUuV2F2ZWZvcm0pO1xuXHQgICAgICAgIG9wdGlvbnMudHlwZSA9IFRvbmUuQW5hbHlzZXIuVHlwZS5XYXZlZm9ybTtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhbmFseXNlciBub2RlLlxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQW5hbHlzZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9hbmFseXNlciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLkFuYWx5c2VyKG9wdGlvbnMpO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuV2F2ZWZvcm0sIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgZGVmYXVsdCB2YWx1ZXMuXG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICogIEBjb25zdFxuXHRcdCAqL1xuXHQgICAgVG9uZS5XYXZlZm9ybS5kZWZhdWx0cyA9IHsgJ3NpemUnOiAxMDI0IH07XG5cdCAgICAvKipcblx0XHQgKiAgR2V0cyB0aGUgd2F2ZWZvcm0gb2YgdGhlIGF1ZGlvIHNvdXJjZS4gUmV0dXJucyB0aGUgd2F2ZWZvcm0gZGF0YVxuXHRcdCAqICBvZiBsZW5ndGggW3NpemVdKCNzaXplKSBhcyBhIEZsb2F0MzJBcnJheSB3aXRoIHZhbHVlcyBiZXR3ZWVuIC0xIGFuZCAxLlxuXHRcdCAqICBAcmV0dXJucyB7VHlwZWRBcnJheX1cblx0XHQgKi9cblx0ICAgIFRvbmUuV2F2ZWZvcm0ucHJvdG90eXBlLmdldFZhbHVlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlci5nZXRWYWx1ZSgpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgc2l6ZSBvZiBhbmFseXNpcy4gVGhpcyBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGluIHRoZSByYW5nZSAzMiB0byAzMjc2OC5cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuV2F2ZWZvcm0jXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBuYW1lIHNpemVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLldhdmVmb3JtLnByb3RvdHlwZSwgJ3NpemUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlci5zaXplO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoc2l6ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9hbmFseXNlci5zaXplID0gc2l6ZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybiAge1RvbmUuV2F2ZWZvcm19ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLldhdmVmb3JtLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuQXVkaW9Ob2RlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fYW5hbHlzZXIuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2FuYWx5c2VyID0gbnVsbDtcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5XYXZlZm9ybTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuQ3RybEludGVycG9sYXRlIHdpbGwgaW50ZXJwb2xhdGUgYmV0d2VlbiBnaXZlbiB2YWx1ZXMgYmFzZWRcblx0XHQgKiAgICAgICAgIG9uIHRoZSBcImluZGV4XCIgcHJvcGVydHkuIFBhc3NpbmcgaW4gYW4gYXJyYXkgb3Igb2JqZWN0IGxpdGVyYWxcblx0XHQgKiAgICAgICAgIHdpbGwgaW50ZXJwb2xhdGUgZWFjaCBvZiB0aGUgcGFyYW1ldGVycy4gTm90ZSAoaS5lLiBcIkMzXCIpXG5cdFx0ICogICAgICAgICBhbmQgVGltZSAoaS5lLiBcIjRuICsgMlwiKSBjYW4gYmUgaW50ZXJwb2xhdGVkLiBBbGwgb3RoZXIgdmFsdWVzIGFyZVxuXHRcdCAqICAgICAgICAgYXNzdW1lZCB0byBiZSBudW1iZXJzLiBcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgaW50ZXJwID0gbmV3IFRvbmUuQ3RybEludGVycG9sYXRlKFswLCAyLCA5LCA0XSk7XG5cdFx0ICogaW50ZXJwLmluZGV4ID0gMC43NTtcblx0XHQgKiBpbnRlcnAudmFsdWU7IC8vcmV0dXJucyAxLjVcblx0XHQgKlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBpbnRlcnAgPSBuZXcgVG9uZS5DdHJsSW50ZXJwb2xhdGUoW1xuXHRcdCAqIFx0WzIsIDQsIDVdLFxuXHRcdCAqIFx0WzksIDMsIDJdLFxuXHRcdCAqIF0pO1xuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgYXJyYXkgb2YgdmFsdWVzIHRvIGludGVycG9sYXRlIG92ZXJcblx0XHQgKiBAcGFyYW0ge1Bvc2l0aXZlfSBpbmRleCBUaGUgaW5pdGlhbCBpbnRlcnBvbGF0aW9uIGluZGV4LlxuXHRcdCAqIEBleHRlbmRzIHtUb25lfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5DdHJsSW50ZXJwb2xhdGUgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAndmFsdWVzJyxcblx0ICAgICAgICAgICAgJ2luZGV4J1xuXHQgICAgICAgIF0sIFRvbmUuQ3RybEludGVycG9sYXRlKTtcblx0ICAgICAgICBUb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHZhbHVlcyB0byBpbnRlcnBvbGF0ZSBiZXR3ZWVuXG5cdFx0XHQgKiAgQHR5cGUgIHtBcnJheX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMudmFsdWVzID0gb3B0aW9ucy52YWx1ZXM7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGludGVycG9sYXRlZCBpbmRleCBiZXR3ZWVuIHZhbHVlcy4gRm9yIGV4YW1wbGU6IGEgdmFsdWUgb2YgMS41XG5cdFx0XHQgKiAgd291bGQgaW50ZXJwb2xhdGUgZXF1YWxseSBiZXR3ZWVuIHRoZSB2YWx1ZSBhdCBpbmRleCAxXG5cdFx0XHQgKiAgYW5kIHRoZSB2YWx1ZSBhdCBpbmRleCAyLiBcblx0XHRcdCAqICBAZXhhbXBsZVxuXHRcdFx0ICogaW50ZXJwLmluZGV4ID0gMDsgXG5cdFx0XHQgKiBpbnRlcnAudmFsdWU7IC8vcmV0dXJucyB0aGUgdmFsdWUgYXQgMFxuXHRcdFx0ICogaW50ZXJwLmluZGV4ID0gMC41O1xuXHRcdFx0ICogaW50ZXJwLnZhbHVlOyAvL3JldHVybnMgdGhlIHZhbHVlIGJldHdlZW4gaW5kaWNlcyAwIGFuZCAxLiBcblx0XHRcdCAqICBAdHlwZSAge1Bvc2l0aXZlfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5pbmRleCA9IG9wdGlvbnMuaW5kZXg7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5DdHJsSW50ZXJwb2xhdGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0c1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkN0cmxJbnRlcnBvbGF0ZS5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnaW5kZXgnOiAwLFxuXHQgICAgICAgICd2YWx1ZXMnOiBbXVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgY3VycmVudCBpbnRlcnBvbGF0ZWQgdmFsdWUgYmFzZWQgb24gdGhlIGluZGV4XG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5DdHJsSW50ZXJwb2xhdGUjXG5cdFx0ICogIEB0eXBlIHsqfVxuXHRcdCAqICBAbmFtZSB2YWx1ZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQ3RybEludGVycG9sYXRlLnByb3RvdHlwZSwgJ3ZhbHVlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLmluZGV4O1xuXHQgICAgICAgICAgICBpbmRleCA9IE1hdGgubWluKGluZGV4LCB0aGlzLnZhbHVlcy5sZW5ndGggLSAxKTtcblx0ICAgICAgICAgICAgdmFyIGxvd2VyUG9zaXRpb24gPSBNYXRoLmZsb29yKGluZGV4KTtcblx0ICAgICAgICAgICAgdmFyIGxvd2VyID0gdGhpcy52YWx1ZXNbbG93ZXJQb3NpdGlvbl07XG5cdCAgICAgICAgICAgIHZhciB1cHBlciA9IHRoaXMudmFsdWVzW01hdGguY2VpbChpbmRleCldO1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5faW50ZXJwb2xhdGUoaW5kZXggLSBsb3dlclBvc2l0aW9uLCBsb3dlciwgdXBwZXIpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIEludGVybmFsIGludGVycG9sYXRpb24gcm91dGluZVxuXHRcdCAqICBAcGFyYW0gIHtOb3JtYWxSYW5nZX0gIGluZGV4ICBUaGUgaW5kZXggYmV0d2VlbiB0aGUgbG93ZXIgYW5kIHVwcGVyXG5cdFx0ICogIEBwYXJhbSAgeyp9ICBsb3dlciBcblx0XHQgKiAgQHBhcmFtICB7Kn0gIHVwcGVyIFxuXHRcdCAqICBAcmV0dXJuICB7Kn0gIFRoZSBpbnRlcnBvbGF0ZWQgdmFsdWVcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuQ3RybEludGVycG9sYXRlLnByb3RvdHlwZS5faW50ZXJwb2xhdGUgPSBmdW5jdGlvbiAoaW5kZXgsIGxvd2VyLCB1cHBlcikge1xuXHQgICAgICAgIGlmIChUb25lLmlzQXJyYXkobG93ZXIpKSB7XG5cdCAgICAgICAgICAgIHZhciByZXRBcnJheSA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxvd2VyLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICByZXRBcnJheVtpXSA9IHRoaXMuX2ludGVycG9sYXRlKGluZGV4LCBsb3dlcltpXSwgdXBwZXJbaV0pO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHJldHVybiByZXRBcnJheTtcblx0ICAgICAgICB9IGVsc2UgaWYgKFRvbmUuaXNPYmplY3QobG93ZXIpKSB7XG5cdCAgICAgICAgICAgIHZhciByZXRPYmogPSB7fTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgYXR0ciBpbiBsb3dlcikge1xuXHQgICAgICAgICAgICAgICAgcmV0T2JqW2F0dHJdID0gdGhpcy5faW50ZXJwb2xhdGUoaW5kZXgsIGxvd2VyW2F0dHJdLCB1cHBlclthdHRyXSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgcmV0dXJuIHJldE9iajtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBsb3dlciA9IHRoaXMuX3RvTnVtYmVyKGxvd2VyKTtcblx0ICAgICAgICAgICAgdXBwZXIgPSB0aGlzLl90b051bWJlcih1cHBlcik7XG5cdCAgICAgICAgICAgIHJldHVybiAoMSAtIGluZGV4KSAqIGxvd2VyICsgaW5kZXggKiB1cHBlcjtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENvbnZlcnQgZnJvbSB0aGUgZ2l2ZW4gdHlwZSBpbnRvIGEgbnVtYmVyXG5cdFx0ICogIEBwYXJhbSAge051bWJlcnxTdHJpbmd9ICB2YWx1ZVxuXHRcdCAqICBAcmV0dXJuICB7TnVtYmVyfVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5DdHJsSW50ZXJwb2xhdGUucHJvdG90eXBlLl90b051bWJlciA9IGZ1bmN0aW9uICh2YWwpIHtcblx0ICAgICAgICBpZiAoVG9uZS5pc051bWJlcih2YWwpKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB2YWw7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgLy9vdGhlcndpc2UgYXNzdW1lIHRoYXQgaXQncyBUaW1lLi4uXG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLnRvU2Vjb25kcyh2YWwpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXBcblx0XHQgKiAgQHJldHVybiAge1RvbmUuQ3RybEludGVycG9sYXRlfSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5DdHJsSW50ZXJwb2xhdGUucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy52YWx1ZXMgPSBudWxsO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkN0cmxJbnRlcnBvbGF0ZTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuQ3RybE1hcmtvdiByZXByZXNlbnRzIGEgTWFya292IENoYWluIHdoZXJlIGVhY2ggY2FsbFxuXHRcdCAqICAgICAgICAgdG8gVG9uZS5DdHJsTWFya292Lm5leHQgd2lsbCBtb3ZlIHRvIHRoZSBuZXh0IHN0YXRlLiBJZiB0aGUgbmV4dFxuXHRcdCAqICAgICAgICAgc3RhdGUgY2hvaWNlIGlzIGFuIGFycmF5LCB0aGUgbmV4dCBzdGF0ZSBpcyBjaG9zZW4gcmFuZG9tbHkgd2l0aFxuXHRcdCAqICAgICAgICAgZXZlbiBwcm9iYWJpbGl0eSBmb3IgYWxsIG9mIHRoZSBjaG9pY2VzLiBGb3IgYSB3ZWlnaHRlZCBwcm9iYWJpbGl0eVxuXHRcdCAqICAgICAgICAgb2YgdGhlIG5leHQgY2hvaWNlcywgcGFzcyBpbiBhbiBvYmplY3Qgd2l0aCBcInN0YXRlXCIgYW5kIFwicHJvYmFiaWxpdHlcIiBhdHRyaWJ1dGVzLiBcblx0XHQgKiAgICAgICAgIFRoZSBwcm9iYWJpbGl0aWVzIHdpbGwgYmUgbm9ybWFsaXplZCBhbmQgdGhlbiBjaG9zZW4uIElmIG5vIG5leHQgb3B0aW9uc1xuXHRcdCAqICAgICAgICAgYXJlIGdpdmVuIGZvciB0aGUgY3VycmVudCBzdGF0ZSwgdGhlIHN0YXRlIHdpbGwgc3RheSB0aGVyZS4gXG5cdFx0ICogIEBleHRlbmRzIHtUb25lfVxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBjaGFpbiA9IG5ldyBUb25lLkN0cmxNYXJrb3Yoe1xuXHRcdCAqIFx0XCJiZWdpbm5pbmdcIiA6IFtcImVuZFwiLCBcIm1pZGRsZVwiXSxcblx0XHQgKiBcdFwibWlkZGxlXCIgOiBcImVuZFwiXG5cdFx0ICogfSk7XG5cdFx0ICogY2hhaW4udmFsdWUgPSBcImJlZ2lubmluZ1wiO1xuXHRcdCAqIGNoYWluLm5leHQoKTsgLy9yZXR1cm5zIFwiZW5kXCIgb3IgXCJtaWRkbGVcIiB3aXRoIDUwJSBwcm9iYWJpbGl0eVxuXHRcdCAqXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIGNoYWluID0gbmV3IFRvbmUuQ3RybE1hcmtvdih7XG5cdFx0ICogXHRcImJlZ2lubmluZ1wiIDogW3tcInZhbHVlXCIgOiBcImVuZFwiLCBcInByb2JhYmlsaXR5XCIgOiAwLjh9LCBcblx0XHQgKiBcdFx0XHRcdFx0e1widmFsdWVcIiA6IFwibWlkZGxlXCIsIFwicHJvYmFiaWxpdHlcIiA6IDAuMn1dLFxuXHRcdCAqIFx0XCJtaWRkbGVcIiA6IFwiZW5kXCJcblx0XHQgKiB9KTtcblx0XHQgKiBjaGFpbi52YWx1ZSA9IFwiYmVnaW5uaW5nXCI7XG5cdFx0ICogY2hhaW4ubmV4dCgpOyAvL3JldHVybnMgXCJlbmRcIiB3aXRoIDgwJSBwcm9iYWJpbGl0eSBvciBcIm1pZGRsZVwiIHdpdGggMjAlLlxuXHRcdCAqICBAcGFyYW0ge09iamVjdH0gdmFsdWVzIEFuIG9iamVjdCB3aXRoIHRoZSBzdGF0ZSBuYW1lcyBhcyB0aGUga2V5c1xuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgIGFuZCB0aGUgbmV4dCBzdGF0ZShzKSBhcyB0aGUgdmFsdWVzLiBcblx0XHQgKi9cblx0ICAgIFRvbmUuQ3RybE1hcmtvdiA9IGZ1bmN0aW9uICh2YWx1ZXMsIGluaXRpYWwpIHtcblx0ICAgICAgICBUb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIE1hcmtvdiB2YWx1ZXMgd2l0aCBzdGF0ZXMgYXMgdGhlIGtleXNcblx0XHRcdCAqICBhbmQgbmV4dCBzdGF0ZShzKSBhcyB0aGUgdmFsdWVzLiBcblx0XHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy52YWx1ZXMgPSBUb25lLmRlZmF1bHRBcmcodmFsdWVzLCB7fSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIE1hcmtvdiB2YWx1ZXMuIFRoZSBuZXh0XG5cdFx0XHQgKiAgc3RhdGUgd2lsbCBiZSBldmFsdWF0ZWQgYW5kIHJldHVybmVkIHdoZW4gVG9uZS5DdHJsTWFya292Lm5leHRcblx0XHRcdCAqICBpcyBpbnZva2VkLlxuXHRcdFx0ICogIEB0eXBlIHtTdHJpbmd9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnZhbHVlID0gVG9uZS5kZWZhdWx0QXJnKGluaXRpYWwsIE9iamVjdC5rZXlzKHRoaXMudmFsdWVzKVswXSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5DdHJsTWFya292KTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm5zIHRoZSBuZXh0IHN0YXRlIG9mIHRoZSBNYXJrb3YgdmFsdWVzLiBcblx0XHQgKiAgQHJldHVybiAge1N0cmluZ31cblx0XHQgKi9cblx0ICAgIFRvbmUuQ3RybE1hcmtvdi5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBpZiAodGhpcy52YWx1ZXMuaGFzT3duUHJvcGVydHkodGhpcy52YWx1ZSkpIHtcblx0ICAgICAgICAgICAgdmFyIG5leHQgPSB0aGlzLnZhbHVlc1t0aGlzLnZhbHVlXTtcblx0ICAgICAgICAgICAgaWYgKFRvbmUuaXNBcnJheShuZXh0KSkge1xuXHQgICAgICAgICAgICAgICAgdmFyIGRpc3RyaWJ1dGlvbiA9IHRoaXMuX2dldFByb2JEaXN0cmlidXRpb24obmV4dCk7XG5cdCAgICAgICAgICAgICAgICB2YXIgcmFuZCA9IE1hdGgucmFuZG9tKCk7XG5cdCAgICAgICAgICAgICAgICB2YXIgdG90YWwgPSAwO1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkaXN0cmlidXRpb24ubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgZGlzdCA9IGRpc3RyaWJ1dGlvbltpXTtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAocmFuZCA+IHRvdGFsICYmIHJhbmQgPCB0b3RhbCArIGRpc3QpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNob3NlbiA9IG5leHRbaV07XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGlmIChUb25lLmlzT2JqZWN0KGNob3NlbikpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSBjaG9zZW4udmFsdWU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gY2hvc2VuO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IGRpc3Q7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gbmV4dDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2hvb3NlIHJhbmRvbWx5IGZyb20gYW4gYXJyYXkgd2VpZ2h0ZWQgb3B0aW9ucyBpbiB0aGUgZm9ybSBcblx0XHQgKiAge1wic3RhdGVcIiA6IHN0cmluZywgXCJwcm9iYWJpbGl0eVwiIDogbnVtYmVyfSBvciBhbiBhcnJheSBvZiB2YWx1ZXNcblx0XHQgKiAgQHBhcmFtICB7QXJyYXl9ICBvcHRpb25zIFxuXHRcdCAqICBAcmV0dXJuICB7QXJyYXl9ICBUaGUgcmFuZG9tbHkgc2VsZWN0ZWQgY2hvaWNlXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkN0cmxNYXJrb3YucHJvdG90eXBlLl9nZXRQcm9iRGlzdHJpYnV0aW9uID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcblx0ICAgICAgICB2YXIgZGlzdHJpYnV0aW9uID0gW107XG5cdCAgICAgICAgdmFyIHRvdGFsID0gMDtcblx0ICAgICAgICB2YXIgbmVlZHNOb3JtYWxpemluZyA9IGZhbHNlO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3B0aW9ucy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICB2YXIgb3B0aW9uID0gb3B0aW9uc1tpXTtcblx0ICAgICAgICAgICAgaWYgKFRvbmUuaXNPYmplY3Qob3B0aW9uKSkge1xuXHQgICAgICAgICAgICAgICAgbmVlZHNOb3JtYWxpemluZyA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICBkaXN0cmlidXRpb25baV0gPSBvcHRpb24ucHJvYmFiaWxpdHk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBkaXN0cmlidXRpb25baV0gPSAxIC8gb3B0aW9ucy5sZW5ndGg7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdG90YWwgKz0gZGlzdHJpYnV0aW9uW2ldO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAobmVlZHNOb3JtYWxpemluZykge1xuXHQgICAgICAgICAgICAvL25vcm1hbGl6ZSB0aGUgdmFsdWVzXG5cdCAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgZGlzdHJpYnV0aW9uLmxlbmd0aDsgaisrKSB7XG5cdCAgICAgICAgICAgICAgICBkaXN0cmlidXRpb25bal0gPSBkaXN0cmlidXRpb25bal0gLyB0b3RhbDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gZGlzdHJpYnV0aW9uO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5DdHJsTWFya292fSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5DdHJsTWFya292LnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMudmFsdWVzID0gbnVsbDtcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5DdHJsTWFya292O1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgR2VuZXJhdGUgcGF0dGVybnMgZnJvbSBhbiBhcnJheSBvZiB2YWx1ZXMuXG5cdFx0ICogICAgICAgICBIYXMgYSBudW1iZXIgb2YgYXJwZWdnaWF0aW9uIGFuZCByYW5kb21pemVkXG5cdFx0ICogICAgICAgICBzZWxlY3Rpb24gcGF0dGVybnMuIFxuXHRcdCAqICAgICAgICAgICA8dWw+XG5cdFx0ICogIFx0ICAgICAgICA8bGk+XCJ1cFwiIC0gY3ljbGVzIHVwd2FyZDwvbGk+XG5cdFx0ICogIFx0XHRcdDxsaT5cImRvd25cIiAtIGN5Y2xlcyBkb3dud2FyZDwvbGk+XG5cdFx0ICogIFx0XHRcdDxsaT5cInVwRG93blwiIC0gdXAgdGhlbiBhbmQgZG93bjwvbGk+XG5cdFx0ICogIFx0XHRcdDxsaT5cImRvd25VcFwiIC0gY3ljbGVzIGRvd24gdGhlbiBhbmQgdXA8L2xpPlxuXHRcdCAqICBcdFx0XHQ8bGk+XCJhbHRlcm5hdGVVcFwiIC0ganVtcCB1cCB0d28gYW5kIGRvd24gb25lPC9saT5cblx0XHQgKiAgXHRcdFx0PGxpPlwiYWx0ZXJuYXRlRG93blwiIC0ganVtcCBkb3duIHR3byBhbmQgdXAgb25lPC9saT5cblx0XHQgKiAgXHRcdFx0PGxpPlwicmFuZG9tXCIgLSByYW5kb21seSBzZWxlY3QgYW4gaW5kZXg8L2xpPlxuXHRcdCAqICBcdFx0XHQ8bGk+XCJyYW5kb21XYWxrXCIgLSByYW5kb21seSBtb3ZlcyBvbmUgaW5kZXggYXdheSBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uPC9saT5cblx0XHQgKiAgXHRcdFx0PGxpPlwicmFuZG9tT25jZVwiIC0gcmFuZG9tbHkgc2VsZWN0IGFuIGluZGV4IHdpdGhvdXQgcmVwZWF0aW5nIHVudGlsIGFsbCB2YWx1ZXMgaGF2ZSBiZWVuIGNob3Nlbi48L2xpPlxuXHRcdCAqICAgICBcdFx0PC91bD5cblx0XHQgKiAgQHBhcmFtICB7QXJyYXl9ICB2YWx1ZXMgICBBbiBhcnJheSBvZiBvcHRpb25zIHRvIGNob29zZSBmcm9tLlxuXHRcdCAqICBAcGFyYW0gIHtUb25lLkN0cmxQYXR0ZXJuLlR5cGU9fSAgdHlwZSAgVGhlIG5hbWUgb2YgdGhlIHBhdHRlcm4uXG5cdFx0ICogIEBleHRlbmRzIHtUb25lfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5DdHJsUGF0dGVybiA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICd2YWx1ZXMnLFxuXHQgICAgICAgICAgICAndHlwZSdcblx0ICAgICAgICBdLCBUb25lLkN0cmxQYXR0ZXJuKTtcblx0ICAgICAgICBUb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGFycmF5IG9mIHZhbHVlcyB0byBhcnBlZ2dpYXRlIG92ZXJcblx0XHRcdCAqICBAdHlwZSB7QXJyYXl9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnZhbHVlcyA9IG9wdGlvbnMudmFsdWVzO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSB2YWx1ZXMgYXJyYXlcblx0XHRcdCAqICBAdHlwZSAge051bWJlcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuaW5kZXggPSAwO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSB0eXBlIHBsYWNlaG9sZGVyXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQ3RybFBhdHRlcm4uVHlwZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fdHlwZSA9IG51bGw7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgU2h1ZmZsZWQgdmFsdWVzIGZvciB0aGUgUmFuZG9tT25jZSB0eXBlXG5cdFx0XHQgKiAgQHR5cGUge0FycmF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9zaHVmZmxlZCA9IG51bGw7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGRpcmVjdGlvbiBvZiB0aGUgbW92ZW1lbnRcblx0XHRcdCAqICBAdHlwZSB7U3RyaW5nfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9kaXJlY3Rpb24gPSBudWxsO1xuXHQgICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkN0cmxQYXR0ZXJuKTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgQ29udHJvbCBQYXR0ZXJuc1xuXHRcdCAqICBAdHlwZSAge09iamVjdH1cblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqL1xuXHQgICAgVG9uZS5DdHJsUGF0dGVybi5UeXBlID0ge1xuXHQgICAgICAgIFVwOiAndXAnLFxuXHQgICAgICAgIERvd246ICdkb3duJyxcblx0ICAgICAgICBVcERvd246ICd1cERvd24nLFxuXHQgICAgICAgIERvd25VcDogJ2Rvd25VcCcsXG5cdCAgICAgICAgQWx0ZXJuYXRlVXA6ICdhbHRlcm5hdGVVcCcsXG5cdCAgICAgICAgQWx0ZXJuYXRlRG93bjogJ2FsdGVybmF0ZURvd24nLFxuXHQgICAgICAgIFJhbmRvbTogJ3JhbmRvbScsXG5cdCAgICAgICAgUmFuZG9tV2FsazogJ3JhbmRvbVdhbGsnLFxuXHQgICAgICAgIFJhbmRvbU9uY2U6ICdyYW5kb21PbmNlJ1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgZGVmYXVsdCB2YWx1ZXMuIFxuXHRcdCAqICBAdHlwZSAge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuQ3RybFBhdHRlcm4uZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ3R5cGUnOiBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuVXAsXG5cdCAgICAgICAgJ3ZhbHVlcyc6IFtdXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSB2YWx1ZSBhdCB0aGUgY3VycmVudCBpbmRleCBvZiB0aGUgcGF0dGVybi5cblx0XHQgKiAgQHJlYWRPbmx5XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkN0cmxQYXR0ZXJuI1xuXHRcdCAqICBAdHlwZSB7Kn1cblx0XHQgKiAgQG5hbWUgdmFsdWVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkN0cmxQYXR0ZXJuLnByb3RvdHlwZSwgJ3ZhbHVlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvL3NvbWUgc2FmZWd1YXJkc1xuXHQgICAgICAgICAgICBpZiAodGhpcy52YWx1ZXMubGVuZ3RoID09PSAwKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm47XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy52YWx1ZXMubGVuZ3RoID09PSAxKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy52YWx1ZXNbMF07XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5pbmRleCA9IE1hdGgubWluKHRoaXMuaW5kZXgsIHRoaXMudmFsdWVzLmxlbmd0aCAtIDEpO1xuXHQgICAgICAgICAgICB2YXIgdmFsID0gdGhpcy52YWx1ZXNbdGhpcy5pbmRleF07XG5cdCAgICAgICAgICAgIGlmICh0aGlzLnR5cGUgPT09IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5SYW5kb21PbmNlKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAodGhpcy52YWx1ZXMubGVuZ3RoICE9PSB0aGlzLl9zaHVmZmxlZC5sZW5ndGgpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl9zaHVmZmxlVmFsdWVzKCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB2YWwgPSB0aGlzLnZhbHVlc1t0aGlzLl9zaHVmZmxlZFt0aGlzLmluZGV4XV07XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgcmV0dXJuIHZhbDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgcGF0dGVybiB1c2VkIHRvIHNlbGVjdCB0aGUgbmV4dFxuXHRcdCAqICBpdGVtIGZyb20gdGhlIHZhbHVlcyBhcnJheVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5DdHJsUGF0dGVybiNcblx0XHQgKiAgQHR5cGUge1RvbmUuQ3RybFBhdHRlcm4uVHlwZX1cblx0XHQgKiAgQG5hbWUgdHlwZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQ3RybFBhdHRlcm4ucHJvdG90eXBlLCAndHlwZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh0eXBlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuXHQgICAgICAgICAgICB0aGlzLl9zaHVmZmxlZCA9IG51bGw7XG5cdCAgICAgICAgICAgIC8vdGhlIGZpcnN0IGluZGV4XG5cdCAgICAgICAgICAgIGlmICh0aGlzLl90eXBlID09PSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuVXAgfHwgdGhpcy5fdHlwZSA9PT0gVG9uZS5DdHJsUGF0dGVybi5UeXBlLlVwRG93biB8fCB0aGlzLl90eXBlID09PSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuUmFuZG9tT25jZSB8fCB0aGlzLl90eXBlID09PSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuQWx0ZXJuYXRlVXApIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXggPSAwO1xuXHQgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3R5cGUgPT09IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5Eb3duIHx8IHRoaXMuX3R5cGUgPT09IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5Eb3duVXAgfHwgdGhpcy5fdHlwZSA9PT0gVG9uZS5DdHJsUGF0dGVybi5UeXBlLkFsdGVybmF0ZURvd24pIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXggPSB0aGlzLnZhbHVlcy5sZW5ndGggLSAxO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIC8vdGhlIGRpcmVjdGlvblxuXHQgICAgICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gVG9uZS5DdHJsUGF0dGVybi5UeXBlLlVwRG93biB8fCB0aGlzLl90eXBlID09PSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuQWx0ZXJuYXRlVXApIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2RpcmVjdGlvbiA9IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5VcDtcblx0ICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl90eXBlID09PSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuRG93blVwIHx8IHRoaXMuX3R5cGUgPT09IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5BbHRlcm5hdGVEb3duKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9kaXJlY3Rpb24gPSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuRG93bjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAvL3JhbmRvbXNcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3R5cGUgPT09IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5SYW5kb21PbmNlKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9zaHVmZmxlVmFsdWVzKCk7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fdHlwZSA9PT0gVG9uZS5DdHJsUGF0dGVybi5SYW5kb20pIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXggPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB0aGlzLnZhbHVlcy5sZW5ndGgpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJuIHRoZSBuZXh0IHZhbHVlIGdpdmVuIHRoZSBjdXJyZW50IHBvc2l0aW9uXG5cdFx0ICogIGFuZCBwYXR0ZXJuLlxuXHRcdCAqICBAcmV0dXJuIHsqfSBUaGUgbmV4dCB2YWx1ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5DdHJsUGF0dGVybi5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgdHlwZSA9IHRoaXMudHlwZTtcblx0ICAgICAgICAvL2Nob29zZSB0aGUgbmV4dCBpbmRleFxuXHQgICAgICAgIGlmICh0eXBlID09PSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuVXApIHtcblx0ICAgICAgICAgICAgdGhpcy5pbmRleCsrO1xuXHQgICAgICAgICAgICBpZiAodGhpcy5pbmRleCA+PSB0aGlzLnZhbHVlcy5sZW5ndGgpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXggPSAwO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuRG93bikge1xuXHQgICAgICAgICAgICB0aGlzLmluZGV4LS07XG5cdCAgICAgICAgICAgIGlmICh0aGlzLmluZGV4IDwgMCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5pbmRleCA9IHRoaXMudmFsdWVzLmxlbmd0aCAtIDE7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5VcERvd24gfHwgdHlwZSA9PT0gVG9uZS5DdHJsUGF0dGVybi5UeXBlLkRvd25VcCkge1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fZGlyZWN0aW9uID09PSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuVXApIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXgrKztcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXgtLTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBpZiAodGhpcy5pbmRleCA8IDApIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXggPSAxO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fZGlyZWN0aW9uID0gVG9uZS5DdHJsUGF0dGVybi5UeXBlLlVwO1xuXHQgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaW5kZXggPj0gdGhpcy52YWx1ZXMubGVuZ3RoKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLmluZGV4ID0gdGhpcy52YWx1ZXMubGVuZ3RoIC0gMjtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2RpcmVjdGlvbiA9IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5Eb3duO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuUmFuZG9tKSB7XG5cdCAgICAgICAgICAgIHRoaXMuaW5kZXggPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB0aGlzLnZhbHVlcy5sZW5ndGgpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gVG9uZS5DdHJsUGF0dGVybi5UeXBlLlJhbmRvbVdhbGspIHtcblx0ICAgICAgICAgICAgaWYgKE1hdGgucmFuZG9tKCkgPCAwLjUpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXgtLTtcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXggPSBNYXRoLm1heCh0aGlzLmluZGV4LCAwKTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXgrKztcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXggPSBNYXRoLm1pbih0aGlzLmluZGV4LCB0aGlzLnZhbHVlcy5sZW5ndGggLSAxKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gVG9uZS5DdHJsUGF0dGVybi5UeXBlLlJhbmRvbU9uY2UpIHtcblx0ICAgICAgICAgICAgdGhpcy5pbmRleCsrO1xuXHQgICAgICAgICAgICBpZiAodGhpcy5pbmRleCA+PSB0aGlzLnZhbHVlcy5sZW5ndGgpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXggPSAwO1xuXHQgICAgICAgICAgICAgICAgLy9yZXNodWZmbGUgdGhlIHZhbHVlcyBmb3IgbmV4dCB0aW1lXG5cdCAgICAgICAgICAgICAgICB0aGlzLl9zaHVmZmxlVmFsdWVzKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5BbHRlcm5hdGVVcCkge1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fZGlyZWN0aW9uID09PSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuVXApIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuaW5kZXggKz0gMjtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2RpcmVjdGlvbiA9IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5Eb3duO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5pbmRleCAtPSAxO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fZGlyZWN0aW9uID0gVG9uZS5DdHJsUGF0dGVybi5UeXBlLlVwO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmICh0aGlzLmluZGV4ID49IHRoaXMudmFsdWVzLmxlbmd0aCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5pbmRleCA9IDA7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9kaXJlY3Rpb24gPSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuVXA7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5BbHRlcm5hdGVEb3duKSB7XG5cdCAgICAgICAgICAgIGlmICh0aGlzLl9kaXJlY3Rpb24gPT09IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5VcCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5pbmRleCArPSAxO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fZGlyZWN0aW9uID0gVG9uZS5DdHJsUGF0dGVybi5UeXBlLkRvd247XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLmluZGV4IC09IDI7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9kaXJlY3Rpb24gPSBUb25lLkN0cmxQYXR0ZXJuLlR5cGUuVXA7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXggPCAwKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLmluZGV4ID0gdGhpcy52YWx1ZXMubGVuZ3RoIC0gMTtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2RpcmVjdGlvbiA9IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5Eb3duO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTaHVmZmxlcyB0aGUgdmFsdWVzIGFuZCBwbGFjZXMgdGhlIHJlc3VsdHMgaW50byB0aGUgX3NodWZmbGVkXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkN0cmxQYXR0ZXJuLnByb3RvdHlwZS5fc2h1ZmZsZVZhbHVlcyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgY29weSA9IFtdO1xuXHQgICAgICAgIHRoaXMuX3NodWZmbGVkID0gW107XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnZhbHVlcy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICBjb3B5W2ldID0gaTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgd2hpbGUgKGNvcHkubGVuZ3RoID4gMCkge1xuXHQgICAgICAgICAgICB2YXIgcmFuZFZhbCA9IGNvcHkuc3BsaWNlKE1hdGguZmxvb3IoY29weS5sZW5ndGggKiBNYXRoLnJhbmRvbSgpKSwgMSk7XG5cdCAgICAgICAgICAgIHRoaXMuX3NodWZmbGVkLnB1c2gocmFuZFZhbFswXSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5DdHJsUGF0dGVybn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5DdHJsUGF0dGVybi5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB0aGlzLl9zaHVmZmxlZCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy52YWx1ZXMgPSBudWxsO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkN0cmxQYXR0ZXJuO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIENob29zZSBhIHJhbmRvbSB2YWx1ZS5cblx0XHQgKiAgQGV4dGVuZHMge1RvbmV9XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHJhbmRvbVdhbGsgPSBuZXcgVG9uZS5DdHJsUmFuZG9tKHtcblx0XHQgKiBcdFwibWluXCIgOiAwLFxuXHRcdCAqIFx0XCJtYXhcIiA6IDEwLFxuXHRcdCAqIFx0XCJpbnRlZ2VyXCIgOiB0cnVlXG5cdFx0ICogfSk7XG5cdFx0ICogcmFuZG9tV2Fsay5ldmFsKCk7XG5cdFx0ICpcblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ8VGltZT19IG1pbiBUaGUgbWluaW11bSByZXR1cm4gdmFsdWUuXG5cdFx0ICogIEBwYXJhbSB7TnVtYmVyfFRpbWU9fSBtYXggVGhlIG1heGltdW0gcmV0dXJuIHZhbHVlLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5DdHJsUmFuZG9tID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ21pbicsXG5cdCAgICAgICAgICAgICdtYXgnXG5cdCAgICAgICAgXSwgVG9uZS5DdHJsUmFuZG9tKTtcblx0ICAgICAgICBUb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG1pbmltdW0gcmV0dXJuIHZhbHVlXG5cdFx0XHQgKiAgQHR5cGUgIHtOdW1iZXJ8VGltZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubWluID0gb3B0aW9ucy5taW47XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG1heGltdW0gcmV0dXJuIHZhbHVlXG5cdFx0XHQgKiAgQHR5cGUgIHtOdW1iZXJ8VGltZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubWF4ID0gb3B0aW9ucy5tYXg7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgSWYgdGhlIHJldHVybiB2YWx1ZSBzaG91bGQgYmUgYW4gaW50ZWdlclxuXHRcdFx0ICogIEB0eXBlICB7Qm9vbGVhbn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuaW50ZWdlciA9IG9wdGlvbnMuaW50ZWdlcjtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkN0cmxSYW5kb20pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0c1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkN0cmxSYW5kb20uZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ21pbic6IDAsXG5cdCAgICAgICAgJ21heCc6IDEsXG5cdCAgICAgICAgJ2ludGVnZXInOiBmYWxzZVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm4gYSByYW5kb20gdmFsdWUgYmV0d2VlbiBtaW4gYW5kIG1heC4gXG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5DdHJsUmFuZG9tI1xuXHRcdCAqICBAdHlwZSB7Kn1cblx0XHQgKiAgQG5hbWUgdmFsdWVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkN0cmxSYW5kb20ucHJvdG90eXBlLCAndmFsdWUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBtaW4gPSB0aGlzLnRvU2Vjb25kcyh0aGlzLm1pbik7XG5cdCAgICAgICAgICAgIHZhciBtYXggPSB0aGlzLnRvU2Vjb25kcyh0aGlzLm1heCk7XG5cdCAgICAgICAgICAgIHZhciByYW5kID0gTWF0aC5yYW5kb20oKTtcblx0ICAgICAgICAgICAgdmFyIHZhbCA9IHJhbmQgKiBtaW4gKyAoMSAtIHJhbmQpICogbWF4O1xuXHQgICAgICAgICAgICBpZiAodGhpcy5pbnRlZ2VyKSB7XG5cdCAgICAgICAgICAgICAgICB2YWwgPSBNYXRoLmZsb29yKHZhbCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgcmV0dXJuIHZhbDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIHJldHVybiBUb25lLkN0cmxSYW5kb207XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgQSBkYXRhIHN0cnVjdHVyZSBmb3IgaG9sZGluZyBtdWx0aXBsZSBidWZmZXJzLlxuXHRcdCAqICBcblx0XHQgKiAgQHBhcmFtICB7T2JqZWN0fEFycmF5fSAgICB1cmxzICAgICAgQW4gb2JqZWN0IGxpdGVyYWwgb3IgYXJyYXlcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2YgdXJscyB0byBsb2FkLlxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbj19ICBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgYnVmZmVycyBhcmUgbG9hZGVkLiBcblx0XHQgKiAgQGV4dGVuZHMge1RvbmV9XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9sb2FkIGEgd2hvbGUgYmFuayBvZiBwaWFubyBzYW1wbGVzXG5cdFx0ICogdmFyIHBpYW5vU2FtcGxlcyA9IG5ldyBUb25lLkJ1ZmZlcnMoe1xuXHRcdCAqIFx0XCJDNFwiIDogXCJwYXRoL3RvL0M0Lm1wM1wiXG5cdFx0ICogXHRcIkMjNFwiIDogXCJwYXRoL3RvL0MjNC5tcDNcIlxuXHRcdCAqIFx0XCJENFwiIDogXCJwYXRoL3RvL0Q0Lm1wM1wiXG5cdFx0ICogXHRcIkQjNFwiIDogXCJwYXRoL3RvL0QjNC5tcDNcIlxuXHRcdCAqIFx0Li4uXG5cdFx0ICogfSwgZnVuY3Rpb24oKXtcblx0XHQgKiBcdC8vcGxheSBvbmUgb2YgdGhlIHNhbXBsZXMgd2hlbiB0aGV5IGFsbCBsb2FkXG5cdFx0ICogXHRwbGF5ZXIuYnVmZmVyID0gcGlhbm9TYW1wbGVzLmdldChcIkM0XCIpO1xuXHRcdCAqIFx0cGxheWVyLnN0YXJ0KCk7XG5cdFx0ICogfSk7XG5cdFx0ICogXHRAZXhhbXBsZVxuXHRcdCAqIC8vVG8gcGFzcyBpbiBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgaW4gdGhlIHNlY29uZCBwYXJhbWV0ZXJcblx0XHQgKiB2YXIgYnVmZmVycyA9IG5ldyBUb25lLkJ1ZmZlcnModXJscywge1xuXHRcdCAqIFx0XCJvbmxvYWRcIiA6IGNhbGxiYWNrLFxuXHRcdCAqIFx0XCJiYXNlVXJsXCIgOiBcIi4uL3BhdGgvdG8vYXVkaW8vXCJcblx0XHQgKiB9KVxuXHRcdCAqL1xuXHQgICAgVG9uZS5CdWZmZXJzID0gZnVuY3Rpb24gKHVybHMpIHtcblx0ICAgICAgICAvL3JlbW92ZSB0aGUgdXJscyBmcm9tIHRoZSBvcHRpb25zXG5cdCAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXHQgICAgICAgIGFyZ3Muc2hpZnQoKTtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJncywgW1xuXHQgICAgICAgICAgICAnb25sb2FkJyxcblx0ICAgICAgICAgICAgJ2Jhc2VVcmwnXG5cdCAgICAgICAgXSwgVG9uZS5CdWZmZXJzKTtcblx0ICAgICAgICBUb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQWxsIG9mIHRoZSBidWZmZXJzXG5cdFx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2J1ZmZlcnMgPSB7fTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBBIHBhdGggd2hpY2ggaXMgcHJlZml4ZWQgYmVmb3JlIGV2ZXJ5IHVybC5cblx0XHRcdCAqICBAdHlwZSAge1N0cmluZ31cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuYmFzZVVybCA9IG9wdGlvbnMuYmFzZVVybDtcblx0ICAgICAgICB0aGlzLl9sb2FkaW5nQ291bnQgPSAwO1xuXHQgICAgICAgIC8vYWRkIGVhY2ggb25lXG5cdCAgICAgICAgZm9yICh2YXIga2V5IGluIHVybHMpIHtcblx0ICAgICAgICAgICAgdGhpcy5fbG9hZGluZ0NvdW50Kys7XG5cdCAgICAgICAgICAgIHRoaXMuYWRkKGtleSwgdXJsc1trZXldLCB0aGlzLl9idWZmZXJMb2FkZWQuYmluZCh0aGlzLCBvcHRpb25zLm9ubG9hZCkpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkJ1ZmZlcnMpO1xuXHQgICAgLyoqXG5cdFx0ICogIERlZmF1bHRzXG5cdFx0ICogIEB0eXBlICB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5CdWZmZXJzLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdvbmxvYWQnOiBUb25lLm5vT3AsXG5cdCAgICAgICAgJ2Jhc2VVcmwnOiAnJ1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUcnVlIGlmIHRoZSBidWZmZXJzIG9iamVjdCBoYXMgYSBidWZmZXIgYnkgdGhhdCBuYW1lLlxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd8TnVtYmVyfSAgbmFtZSAgVGhlIGtleSBvciBpbmRleCBvZiB0aGUgXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuXG5cdFx0ICogIEByZXR1cm4gIHtCb29sZWFufVxuXHRcdCAqL1xuXHQgICAgVG9uZS5CdWZmZXJzLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAobmFtZSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmhhc093blByb3BlcnR5KG5hbWUpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBHZXQgYSBidWZmZXIgYnkgbmFtZS4gSWYgYW4gYXJyYXkgd2FzIGxvYWRlZCwgXG5cdFx0ICogIHRoZW4gdXNlIHRoZSBhcnJheSBpbmRleC5cblx0XHQgKiAgQHBhcmFtICB7U3RyaW5nfE51bWJlcn0gIG5hbWUgIFRoZSBrZXkgb3IgaW5kZXggb2YgdGhlIFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5CdWZmZXJ9XG5cdFx0ICovXG5cdCAgICBUb25lLkJ1ZmZlcnMucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChuYW1lKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuaGFzKG5hbWUpKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzW25hbWVdO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVG9uZS5CdWZmZXJzOiBubyBidWZmZXIgbmFtZWQgJyArIG5hbWUpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQSBidWZmZXIgd2FzIGxvYWRlZC4gZGVjcmVtZW50IHRoZSBjb3VudGVyLlxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbn0gIGNhbGxiYWNrIFxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5CdWZmZXJzLnByb3RvdHlwZS5fYnVmZmVyTG9hZGVkID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG5cdCAgICAgICAgdGhpcy5fbG9hZGluZ0NvdW50LS07XG5cdCAgICAgICAgaWYgKHRoaXMuX2xvYWRpbmdDb3VudCA9PT0gMCAmJiBjYWxsYmFjaykge1xuXHQgICAgICAgICAgICBjYWxsYmFjayh0aGlzKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogSWYgdGhlIGJ1ZmZlcnMgYXJlIGxvYWRlZCBvciBub3Rcblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5CdWZmZXJzI1xuXHRcdCAqIEB0eXBlIHtCb29sZWFufVxuXHRcdCAqIEBuYW1lIGxvYWRlZFxuXHRcdCAqIEByZWFkT25seVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQnVmZmVycy5wcm90b3R5cGUsICdsb2FkZWQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBpc0xvYWRlZCA9IHRydWU7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGJ1ZmZOYW1lIGluIHRoaXMuX2J1ZmZlcnMpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBidWZmID0gdGhpcy5nZXQoYnVmZk5hbWUpO1xuXHQgICAgICAgICAgICAgICAgaXNMb2FkZWQgPSBpc0xvYWRlZCAmJiBidWZmLmxvYWRlZDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICByZXR1cm4gaXNMb2FkZWQ7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQWRkIGEgYnVmZmVyIGJ5IG5hbWUgYW5kIHVybCB0byB0aGUgQnVmZmVyc1xuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd9ICAgIG5hbWUgICAgICBBIHVuaXF1ZSBuYW1lIHRvIGdpdmVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGJ1ZmZlclxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd8VG9uZS5CdWZmZXJ8QXVkaW9idWZmZXJ9ICB1cmwgIEVpdGhlciB0aGUgdXJsIG9mIHRoZSBidWZlciwgXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgYSBidWZmZXIgd2hpY2ggd2lsbCBiZSBhZGRlZFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggdGhlIGdpdmVuIG5hbWUuXG5cdFx0ICogIEBwYXJhbSAge0Z1bmN0aW9uPX0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hlbiB0aGUgdXJsIGlzIGxvYWRlZC5cblx0XHQgKi9cblx0ICAgIFRvbmUuQnVmZmVycy5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKG5hbWUsIHVybCwgY2FsbGJhY2spIHtcblx0ICAgICAgICBjYWxsYmFjayA9IFRvbmUuZGVmYXVsdEFyZyhjYWxsYmFjaywgVG9uZS5ub09wKTtcblx0ICAgICAgICBpZiAodXJsIGluc3RhbmNlb2YgVG9uZS5CdWZmZXIpIHtcblx0ICAgICAgICAgICAgdGhpcy5fYnVmZmVyc1tuYW1lXSA9IHVybDtcblx0ICAgICAgICAgICAgY2FsbGJhY2sodGhpcyk7XG5cdCAgICAgICAgfSBlbHNlIGlmICh1cmwgaW5zdGFuY2VvZiBBdWRpb0J1ZmZlcikge1xuXHQgICAgICAgICAgICB0aGlzLl9idWZmZXJzW25hbWVdID0gbmV3IFRvbmUuQnVmZmVyKHVybCk7XG5cdCAgICAgICAgICAgIGNhbGxiYWNrKHRoaXMpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAoVG9uZS5pc1N0cmluZyh1cmwpKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnNbbmFtZV0gPSBuZXcgVG9uZS5CdWZmZXIodGhpcy5iYXNlVXJsICsgdXJsLCBjYWxsYmFjayk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybiAge1RvbmUuQnVmZmVyc30gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5CdWZmZXJzLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICBmb3IgKHZhciBuYW1lIGluIHRoaXMuX2J1ZmZlcnMpIHtcblx0ICAgICAgICAgICAgdGhpcy5fYnVmZmVyc1tuYW1lXS5kaXNwb3NlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuX2J1ZmZlcnMgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkJ1ZmZlcnM7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIGJ1c2VzIGFyZSBhbm90aGVyIHdheSBvZiByb3V0aW5nIGF1ZGlvXG5cdFx0ICpcblx0XHQgKiAgYXVnbWVudHMgVG9uZS5wcm90b3R5cGUgdG8gaW5jbHVkZSBzZW5kIGFuZCByZWNpZXZlXG5cdFx0ICovXG5cdCAgICAvKipcblx0XHQgKiAgQWxsIG9mIHRoZSByb3V0ZXNcblx0XHQgKlxuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICB2YXIgQnVzZXMgPSB7fTtcblx0ICAgIC8qKlxuXHRcdCAqICBTZW5kIHRoaXMgc2lnbmFsIHRvIHRoZSBjaGFubmVsIG5hbWUuXG5cdFx0ICogIEBwYXJhbSAge1N0cmluZ30gY2hhbm5lbE5hbWUgQSBuYW1lZCBjaGFubmVsIHRvIHNlbmQgdGhlIHNpZ25hbCB0by5cblx0XHQgKiAgQHBhcmFtICB7RGVjaWJlbHN9IGFtb3VudCBUaGUgYW1vdW50IG9mIHRoZSBzb3VyY2UgdG8gc2VuZCB0byB0aGUgYnVzLlxuXHRcdCAqICBAcmV0dXJuIHtHYWluTm9kZX0gVGhlIGdhaW4gbm9kZSB3aGljaCBjb25uZWN0cyB0aGlzIG5vZGUgdG8gdGhlIGRlc2lyZWQgY2hhbm5lbC5cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgIENhbiBiZSB1c2VkIHRvIGFkanVzdCB0aGUgbGV2ZWxzIG9mIHRoZSBzZW5kLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHNvdXJjZS5zZW5kKFwicmV2ZXJiXCIsIC0xMik7XG5cdFx0ICovXG5cdCAgICBUb25lLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKGNoYW5uZWxOYW1lLCBhbW91bnQpIHtcblx0ICAgICAgICBpZiAoIUJ1c2VzLmhhc093blByb3BlcnR5KGNoYW5uZWxOYW1lKSkge1xuXHQgICAgICAgICAgICBCdXNlc1tjaGFubmVsTmFtZV0gPSB0aGlzLmNvbnRleHQuY3JlYXRlR2FpbigpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBhbW91bnQgPSBUb25lLmRlZmF1bHRBcmcoYW1vdW50LCAwKTtcblx0ICAgICAgICB2YXIgc2VuZEtub2IgPSBuZXcgVG9uZS5HYWluKGFtb3VudCwgVG9uZS5UeXBlLkRlY2liZWxzKTtcblx0ICAgICAgICB0aGlzLmNvbm5lY3Qoc2VuZEtub2IpO1xuXHQgICAgICAgIHNlbmRLbm9iLmNvbm5lY3QoQnVzZXNbY2hhbm5lbE5hbWVdKTtcblx0ICAgICAgICByZXR1cm4gc2VuZEtub2I7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJlY2lldmUgdGhlIGlucHV0IGZyb20gdGhlIGRlc2lyZWQgY2hhbm5lbE5hbWUgdG8gdGhlIGlucHV0XG5cdFx0ICpcblx0XHQgKiAgQHBhcmFtICB7U3RyaW5nfSBjaGFubmVsTmFtZSBBIG5hbWVkIGNoYW5uZWwgdG8gc2VuZCB0aGUgc2lnbmFsIHRvLlxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXI9fSBjaGFubmVsTnVtYmVyIFRoZSBjaGFubmVsIHRvIGNvbm5lY3QgdG9cblx0XHQgKiAgQHJldHVybnMge1RvbmV9IHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiByZXZlcmJFZmZlY3QucmVjZWl2ZShcInJldmVyYlwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUucHJvdG90eXBlLnJlY2VpdmUgPSBmdW5jdGlvbiAoY2hhbm5lbE5hbWUsIGlucHV0TnVtKSB7XG5cdCAgICAgICAgaWYgKCFCdXNlcy5oYXNPd25Qcm9wZXJ0eShjaGFubmVsTmFtZSkpIHtcblx0ICAgICAgICAgICAgQnVzZXNbY2hhbm5lbE5hbWVdID0gdGhpcy5jb250ZXh0LmNyZWF0ZUdhaW4oKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgQnVzZXNbY2hhbm5lbE5hbWVdLmNvbm5lY3QodGhpcywgMCwgaW5wdXROdW0pO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8vcmVtb3ZlIGFsbCB0aGUgc2VuZC9yZWNlaXZlcyB3aGVuIGEgbmV3IGF1ZGlvIGNvbnRleHQgaXMgcGFzc2VkIGluXG5cdCAgICBUb25lLkNvbnRleHQub24oJ2luaXQnLCBmdW5jdGlvbiAoY29udGV4dCkge1xuXHQgICAgICAgIGlmIChjb250ZXh0LkJ1c2VzKSB7XG5cdCAgICAgICAgICAgIEJ1c2VzID0gY29udGV4dC5CdXNlcztcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBCdXNlcyA9IHt9O1xuXHQgICAgICAgICAgICBjb250ZXh0LkJ1c2VzID0gQnVzZXM7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICByZXR1cm4gVG9uZTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuRHJhdyBpcyB1c2VmdWwgZm9yIHN5bmNocm9uaXppbmcgdmlzdWFscyBhbmQgYXVkaW8gZXZlbnRzLlxuXHRcdCAqICAgICAgICAgQ2FsbGJhY2tzIGZyb20gVG9uZS5UcmFuc3BvcnQgb3IgYW55IG9mIHRoZSBUb25lLkV2ZW50IGNsYXNzZXNcblx0XHQgKiAgICAgICAgIGFsd2F5cyBoYXBwZW4gX2JlZm9yZV8gdGhlIHNjaGVkdWxlZCB0aW1lIGFuZCBhcmUgbm90IHN5bmNocm9uaXplZFxuXHRcdCAqICAgICAgICAgdG8gdGhlIGFuaW1hdGlvbiBmcmFtZSBzbyB0aGV5IGFyZSBub3QgZ29vZCBmb3IgdHJpZ2dlcmluZyB0aWdodGx5XG5cdFx0ICogICAgICAgICBzeW5jaHJvbml6ZWQgdmlzdWFscyBhbmQgc291bmQuIFRvbmUuRHJhdyBtYWtlcyBpdCBlYXN5IHRvIHNjaGVkdWxlXG5cdFx0ICogICAgICAgICBjYWxsYmFja3MgdXNpbmcgdGhlIEF1ZGlvQ29udGV4dCB0aW1lIGFuZCB1c2VzIHJlcXVlc3RBbmltYXRpb25GcmFtZS5cblx0XHQgKiAgICAgICAgIFxuXHRcdCAqICBAc2luZ2xldG9uXG5cdFx0ICogIEBleHRlbmRzIHtUb25lfVxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlKGZ1bmN0aW9uKHRpbWUpe1xuXHRcdCAqIFx0Ly91c2UgdGhlIHRpbWUgYXJndW1lbnQgdG8gc2NoZWR1bGUgYSBjYWxsYmFjayB3aXRoIFRvbmUuRHJhd1xuXHRcdCAqIFx0VG9uZS5EcmF3LnNjaGVkdWxlKGZ1bmN0aW9uKCl7XG5cdFx0ICogXHRcdC8vZG8gZHJhd2luZyBvciBET00gbWFuaXB1bGF0aW9uIGhlcmVcblx0XHQgKiBcdH0sIHRpbWUpXG5cdFx0ICogfSwgXCIrMC41XCIpXG5cdFx0ICovXG5cdCAgICBUb25lLkRyYXcgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEFsbCBvZiB0aGUgZXZlbnRzLlxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5UaW1lbGluZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZXZlbnRzID0gbmV3IFRvbmUuVGltZWxpbmUoKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZHVyYXRpb24gYWZ0ZXIgd2hpY2ggZXZlbnRzIGFyZSBub3QgaW52b2tlZC5cblx0XHRcdCAqICBAdHlwZSAge051bWJlcn1cblx0XHRcdCAqICBAZGVmYXVsdCAwLjI1XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmV4cGlyYXRpb24gPSAwLjI1O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhbW91bnQgb2YgdGltZSBiZWZvcmUgdGhlIHNjaGVkdWxlZCB0aW1lIFxuXHRcdFx0ICogIHRoYXQgdGhlIGNhbGxiYWNrIGNhbiBiZSBpbnZva2VkLiBEZWZhdWx0IGlzXG5cdFx0XHQgKiAgaGFsZiB0aGUgdGltZSBvZiBhbiBhbmltYXRpb24gZnJhbWUgKDAuMDA4IHNlY29uZHMpLlxuXHRcdFx0ICogIEB0eXBlICB7TnVtYmVyfVxuXHRcdFx0ICogIEBkZWZhdWx0IDAuMDA4XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmFudGljaXBhdGlvbiA9IDAuMDA4O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBkcmF3IGxvb3Bcblx0XHRcdCAqICBAdHlwZSAge0Z1bmN0aW9ufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9ib3VuZERyYXdMb29wID0gdGhpcy5fZHJhd0xvb3AuYmluZCh0aGlzKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkRyYXcpO1xuXHQgICAgLyoqXG5cdFx0ICogIFNjaGVkdWxlIGEgZnVuY3Rpb24gYXQgdGhlIGdpdmVuIHRpbWUgdG8gYmUgaW52b2tlZFxuXHRcdCAqICBvbiB0aGUgbmVhcmVzdCBhbmltYXRpb24gZnJhbWUuXG5cdFx0ICogIEBwYXJhbSAge0Z1bmN0aW9ufSAgY2FsbGJhY2sgIENhbGxiYWNrIGlzIGludm9rZWQgYXQgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9ICAgIHRpbWUgICAgICBUaGUgdGltZSByZWxhdGl2ZSB0byB0aGUgQXVkaW9Db250ZXh0IHRpbWVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGludm9rZSB0aGUgY2FsbGJhY2suXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLkRyYXd9ICAgIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuRHJhdy5wcm90b3R5cGUuc2NoZWR1bGUgPSBmdW5jdGlvbiAoY2FsbGJhY2ssIHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcblx0ICAgICAgICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrLFxuXHQgICAgICAgICAgICB0aW1lOiB0aGlzLnRvU2Vjb25kcyh0aW1lKVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIC8vc3RhcnQgdGhlIGRyYXcgbG9vcCBvbiB0aGUgZmlyc3QgZXZlbnRcblx0ICAgICAgICBpZiAodGhpcy5fZXZlbnRzLmxlbmd0aCA9PT0gMSkge1xuXHQgICAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5fYm91bmREcmF3TG9vcCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDYW5jZWwgZXZlbnRzIHNjaGVkdWxlZCBhZnRlciB0aGUgZ2l2ZW4gdGltZVxuXHRcdCAqICBAcGFyYW0gIHtUaW1lPX0gIGFmdGVyICBUaW1lIGFmdGVyIHdoaWNoIHNjaGVkdWxlZCBldmVudHMgd2lsbCBcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYmUgcmVtb3ZlZCBmcm9tIHRoZSBzY2hlZHVsaW5nIHRpbWVsaW5lLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5EcmF3fSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5EcmF3LnByb3RvdHlwZS5jYW5jZWwgPSBmdW5jdGlvbiAoYWZ0ZXIpIHtcblx0ICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKHRoaXMudG9TZWNvbmRzKGFmdGVyKSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkcmF3IGxvb3Bcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuRHJhdy5wcm90b3R5cGUuX2RyYXdMb29wID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBub3cgPSBUb25lLm5vdygpO1xuXHQgICAgICAgIHdoaWxlICh0aGlzLl9ldmVudHMubGVuZ3RoICYmIHRoaXMuX2V2ZW50cy5wZWVrKCkudGltZSAtIHRoaXMuYW50aWNpcGF0aW9uIDw9IG5vdykge1xuXHQgICAgICAgICAgICB2YXIgZXZlbnQgPSB0aGlzLl9ldmVudHMuc2hpZnQoKTtcblx0ICAgICAgICAgICAgaWYgKG5vdyAtIGV2ZW50LnRpbWUgPD0gdGhpcy5leHBpcmF0aW9uKSB7XG5cdCAgICAgICAgICAgICAgICBldmVudC5jYWxsYmFjaygpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICh0aGlzLl9ldmVudHMubGVuZ3RoID4gMCkge1xuXHQgICAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5fYm91bmREcmF3TG9vcCk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8vbWFrZSBhIHNpbmdsZXRvblxuXHQgICAgVG9uZS5EcmF3ID0gbmV3IFRvbmUuRHJhdygpO1xuXHQgICAgcmV0dXJuIFRvbmUuRHJhdztcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBCb3RoIFRvbmUuUGFubmVyM0QgYW5kIFRvbmUuTGlzdGVuZXIgaGF2ZSBhIHBvc2l0aW9uIGluIDNEIHNwYWNlXG5cdFx0ICogICAgICAgICAgdXNpbmcgYSByaWdodC1oYW5kZWQgY2FydGVzaWFuIGNvb3JkaW5hdGUgc3lzdGVtLlxuXHRcdCAqICAgICAgICAgIFRoZSB1bml0cyB1c2VkIGluIHRoZSBjb29yZGluYXRlIHN5c3RlbSBhcmUgbm90IGRlZmluZWQ7XG5cdFx0ICogICAgICAgICAgdGhlc2UgY29vcmRpbmF0ZXMgYXJlIGluZGVwZW5kZW50L2ludmFyaWFudCBvZiBhbnkgcGFydGljdWxhclxuXHRcdCAqICAgICAgICAgIHVuaXRzIHN1Y2ggYXMgbWV0ZXJzIG9yIGZlZXQuIFRvbmUuUGFubmVyM0Qgb2JqZWN0cyBoYXZlIGFuIGZvcndhcmRcblx0XHQgKiAgICAgICAgICB2ZWN0b3IgcmVwcmVzZW50aW5nIHRoZSBkaXJlY3Rpb24gdGhlIHNvdW5kIGlzIHByb2plY3RpbmcuIEFkZGl0aW9uYWxseSxcblx0XHQgKiAgICAgICAgICB0aGV5IGhhdmUgYSBzb3VuZCBjb25lIHJlcHJlc2VudGluZyBob3cgZGlyZWN0aW9uYWwgdGhlIHNvdW5kIGlzLlxuXHRcdCAqICAgICAgICAgIEZvciBleGFtcGxlLCB0aGUgc291bmQgY291bGQgYmUgb21uaWRpcmVjdGlvbmFsLCBpbiB3aGljaCBjYXNlIGl0IHdvdWxkXG5cdFx0ICogICAgICAgICAgYmUgaGVhcmQgYW55d2hlcmUgcmVnYXJkbGVzcyBvZiBpdHMgZm9yd2FyZCwgb3IgaXQgY2FuIGJlIG1vcmUgZGlyZWN0aW9uYWxcblx0XHQgKiAgICAgICAgICBhbmQgaGVhcmQgb25seSBpZiBpdCBpcyBmYWNpbmcgdGhlIGxpc3RlbmVyLiBUb25lLkxpc3RlbmVyIG9iamVjdHNcblx0XHQgKiAgICAgICAgICAocmVwcmVzZW50aW5nIGEgcGVyc29uJ3MgZWFycykgaGF2ZSBhbiBmb3J3YXJkIGFuZCB1cCB2ZWN0b3Jcblx0XHQgKiAgICAgICAgICByZXByZXNlbnRpbmcgaW4gd2hpY2ggZGlyZWN0aW9uIHRoZSBwZXJzb24gaXMgZmFjaW5nLiBCZWNhdXNlIGJvdGggdGhlXG5cdFx0ICogICAgICAgICAgc291cmNlIHN0cmVhbSBhbmQgdGhlIGxpc3RlbmVyIGNhbiBiZSBtb3ZpbmcsIHRoZXkgYm90aCBoYXZlIGEgdmVsb2NpdHlcblx0XHQgKiAgICAgICAgICB2ZWN0b3IgcmVwcmVzZW50aW5nIGJvdGggdGhlIHNwZWVkIGFuZCBkaXJlY3Rpb24gb2YgbW92ZW1lbnQuIFRha2VuIHRvZ2V0aGVyLFxuXHRcdCAqICAgICAgICAgIHRoZXNlIHR3byB2ZWxvY2l0aWVzIGNhbiBiZSB1c2VkIHRvIGdlbmVyYXRlIGEgZG9wcGxlciBzaGlmdCBlZmZlY3Qgd2hpY2ggY2hhbmdlcyB0aGUgcGl0Y2guXG5cdFx0ICogICAgICAgICAgPGJyPjxicj5cblx0XHQgKiAgICAgICAgICBOb3RlOiB0aGUgcG9zaXRpb24gb2YgdGhlIExpc3RlbmVyIHdpbGwgaGF2ZSBubyBlZmZlY3Qgb24gbm9kZXMgbm90IGNvbm5lY3RlZCB0byBhIFRvbmUuUGFubmVyM0Rcblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmV9XG5cdFx0ICogIEBzaW5nbGV0b25cblx0XHQgKi9cblx0ICAgIFRvbmUuTGlzdGVuZXIgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEhvbGRzIHRoZSBjdXJyZW50IGZvcndhcmQgb3JpZW50YXRpb25cblx0XHRcdCAqICBAdHlwZSAge0FycmF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9vcmllbnRhdGlvbiA9IFtcblx0ICAgICAgICAgICAgMCxcblx0ICAgICAgICAgICAgMCxcblx0ICAgICAgICAgICAgMCxcblx0ICAgICAgICAgICAgMCxcblx0ICAgICAgICAgICAgMCxcblx0ICAgICAgICAgICAgMFxuXHQgICAgICAgIF07XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgSG9sZHMgdGhlIGN1cnJlbnQgcG9zaXRpb25cblx0XHRcdCAqICBAdHlwZSAge0FycmF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9wb3NpdGlvbiA9IFtcblx0ICAgICAgICAgICAgMCxcblx0ICAgICAgICAgICAgMCxcblx0ICAgICAgICAgICAgMFxuXHQgICAgICAgIF07XG5cdCAgICAgICAgVG9uZS5nZXRDb250ZXh0KGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gc2V0IHRoZSBkZWZhdWx0IHBvc2l0aW9uL2ZvcndhcmRcblx0ICAgICAgICAgICAgdGhpcy5zZXQoTGlzdGVuZXJDb25zdHJ1Y3Rvci5kZWZhdWx0cyk7XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkxpc3RlbmVyKTtcblx0ICAgIC8qKlxuXHRcdCAqICBEZWZhdWx0cyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb25cblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuTGlzdGVuZXIuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ3Bvc2l0aW9uWCc6IDAsXG5cdCAgICAgICAgJ3Bvc2l0aW9uWSc6IDAsXG5cdCAgICAgICAgJ3Bvc2l0aW9uWic6IDAsXG5cdCAgICAgICAgJ2ZvcndhcmRYJzogMCxcblx0ICAgICAgICAnZm9yd2FyZFknOiAwLFxuXHQgICAgICAgICdmb3J3YXJkWic6IDEsXG5cdCAgICAgICAgJ3VwWCc6IDAsXG5cdCAgICAgICAgJ3VwWSc6IDEsXG5cdCAgICAgICAgJ3VwWic6IDBcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcmFtcCB0aW1lIHdoaWNoIGlzIGFwcGxpZWQgdG8gdGhlIHNldFRhcmdldEF0VGltZVxuXHRcdCAqIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuTGlzdGVuZXIucHJvdG90eXBlLl9yYW1wVGltZUNvbnN0YW50ID0gMC4wMTtcblx0ICAgIC8qKlxuXHRcdCAqICBTZXRzIHRoZSBwb3NpdGlvbiBvZiB0aGUgbGlzdGVuZXIgaW4gM2Qgc3BhY2UuXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHhcblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgeVxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICB6XG5cdFx0ICogIEByZXR1cm4ge1RvbmUuTGlzdGVuZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTGlzdGVuZXIucHJvdG90eXBlLnNldFBvc2l0aW9uID0gZnVuY3Rpb24gKHgsIHksIHopIHtcblx0ICAgICAgICBpZiAodGhpcy5jb250ZXh0Lmxpc3RlbmVyLnBvc2l0aW9uWCkge1xuXHQgICAgICAgICAgICB2YXIgbm93ID0gdGhpcy5ub3coKTtcblx0ICAgICAgICAgICAgdGhpcy5jb250ZXh0Lmxpc3RlbmVyLnBvc2l0aW9uWC5zZXRUYXJnZXRBdFRpbWUoeCwgbm93LCB0aGlzLl9yYW1wVGltZUNvbnN0YW50KTtcblx0ICAgICAgICAgICAgdGhpcy5jb250ZXh0Lmxpc3RlbmVyLnBvc2l0aW9uWS5zZXRUYXJnZXRBdFRpbWUoeSwgbm93LCB0aGlzLl9yYW1wVGltZUNvbnN0YW50KTtcblx0ICAgICAgICAgICAgdGhpcy5jb250ZXh0Lmxpc3RlbmVyLnBvc2l0aW9uWi5zZXRUYXJnZXRBdFRpbWUoeiwgbm93LCB0aGlzLl9yYW1wVGltZUNvbnN0YW50KTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0aGlzLmNvbnRleHQubGlzdGVuZXIuc2V0UG9zaXRpb24oeCwgeSwgeik7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuX3Bvc2l0aW9uID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU2V0cyB0aGUgb3JpZW50YXRpb24gb2YgdGhlIGxpc3RlbmVyIHVzaW5nIHR3byB2ZWN0b3JzLCB0aGUgZm9yd2FyZFxuXHRcdCAqICB2ZWN0b3IgKHdoaWNoIGRpcmVjdGlvbiB0aGUgbGlzdGVuZXIgaXMgZmFjaW5nKSBhbmQgdGhlIHVwIHZlY3RvclxuXHRcdCAqICAod2hpY2ggdGhlIHVwIGRpcmVjdGlvbiBvZiB0aGUgbGlzdGVuZXIpLiBBbiB1cCB2ZWN0b3Jcblx0XHQgKiAgb2YgMCwgMCwgMSBpcyBlcXVpdmFsZW50IHRvIHRoZSBsaXN0ZW5lciBzdGFuZGluZyB1cCBpbiB0aGUgWiBkaXJlY3Rpb24uXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHhcblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgeVxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICB6XG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHVwWFxuXHRcdCAqICBAcGFyYW0gIHtOdW1iZXJ9ICB1cFlcblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgdXBaXG5cdFx0ICogIEByZXR1cm4ge1RvbmUuTGlzdGVuZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTGlzdGVuZXIucHJvdG90eXBlLnNldE9yaWVudGF0aW9uID0gZnVuY3Rpb24gKHgsIHksIHosIHVwWCwgdXBZLCB1cFopIHtcblx0ICAgICAgICBpZiAodGhpcy5jb250ZXh0Lmxpc3RlbmVyLmZvcndhcmRYKSB7XG5cdCAgICAgICAgICAgIHZhciBub3cgPSB0aGlzLm5vdygpO1xuXHQgICAgICAgICAgICB0aGlzLmNvbnRleHQubGlzdGVuZXIuZm9yd2FyZFguc2V0VGFyZ2V0QXRUaW1lKHgsIG5vdywgdGhpcy5fcmFtcFRpbWVDb25zdGFudCk7XG5cdCAgICAgICAgICAgIHRoaXMuY29udGV4dC5saXN0ZW5lci5mb3J3YXJkWS5zZXRUYXJnZXRBdFRpbWUoeSwgbm93LCB0aGlzLl9yYW1wVGltZUNvbnN0YW50KTtcblx0ICAgICAgICAgICAgdGhpcy5jb250ZXh0Lmxpc3RlbmVyLmZvcndhcmRaLnNldFRhcmdldEF0VGltZSh6LCBub3csIHRoaXMuX3JhbXBUaW1lQ29uc3RhbnQpO1xuXHQgICAgICAgICAgICB0aGlzLmNvbnRleHQubGlzdGVuZXIudXBYLnNldFRhcmdldEF0VGltZSh1cFgsIG5vdywgdGhpcy5fcmFtcFRpbWVDb25zdGFudCk7XG5cdCAgICAgICAgICAgIHRoaXMuY29udGV4dC5saXN0ZW5lci51cFkuc2V0VGFyZ2V0QXRUaW1lKHVwWSwgbm93LCB0aGlzLl9yYW1wVGltZUNvbnN0YW50KTtcblx0ICAgICAgICAgICAgdGhpcy5jb250ZXh0Lmxpc3RlbmVyLnVwWi5zZXRUYXJnZXRBdFRpbWUodXBaLCBub3csIHRoaXMuX3JhbXBUaW1lQ29uc3RhbnQpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRoaXMuY29udGV4dC5saXN0ZW5lci5zZXRPcmllbnRhdGlvbih4LCB5LCB6LCB1cFgsIHVwWSwgdXBaKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5fb3JpZW50YXRpb24gPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgeCBwb3NpdGlvbiBvZiB0aGUgcGFubmVyIG9iamVjdC5cblx0XHQgKiAgQHR5cGUge051bWJlcn1cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuTGlzdGVuZXIjXG5cdFx0ICogIEBuYW1lIHBvc2l0aW9uWFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuTGlzdGVuZXIucHJvdG90eXBlLCAncG9zaXRpb25YJywge1xuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHBvcykge1xuXHQgICAgICAgICAgICB0aGlzLl9wb3NpdGlvblswXSA9IHBvcztcblx0ICAgICAgICAgICAgdGhpcy5zZXRQb3NpdGlvbi5hcHBseSh0aGlzLCB0aGlzLl9wb3NpdGlvbik7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Bvc2l0aW9uWzBdO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSB5IHBvc2l0aW9uIG9mIHRoZSBwYW5uZXIgb2JqZWN0LlxuXHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5MaXN0ZW5lciNcblx0XHQgKiAgQG5hbWUgcG9zaXRpb25ZXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5MaXN0ZW5lci5wcm90b3R5cGUsICdwb3NpdGlvblknLCB7XG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocG9zKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3Bvc2l0aW9uWzFdID0gcG9zO1xuXHQgICAgICAgICAgICB0aGlzLnNldFBvc2l0aW9uLmFwcGx5KHRoaXMsIHRoaXMuX3Bvc2l0aW9uKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fcG9zaXRpb25bMV07XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHogcG9zaXRpb24gb2YgdGhlIHBhbm5lciBvYmplY3QuXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkxpc3RlbmVyI1xuXHRcdCAqICBAbmFtZSBwb3NpdGlvblpcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkxpc3RlbmVyLnByb3RvdHlwZSwgJ3Bvc2l0aW9uWicsIHtcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwb3MpIHtcblx0ICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25bMl0gPSBwb3M7XG5cdCAgICAgICAgICAgIHRoaXMuc2V0UG9zaXRpb24uYXBwbHkodGhpcywgdGhpcy5fcG9zaXRpb24pO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9wb3NpdGlvblsyXTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSBsaXN0ZW5lcnMgZnJvbnQgZGlyZWN0aW9uLiBpLmUuXG5cdFx0ICogIHdoaWNoIHdheSB0aGV5IGFyZSBmYWNpbmcuXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkxpc3RlbmVyI1xuXHRcdCAqICBAbmFtZSBmb3J3YXJkWFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuTGlzdGVuZXIucHJvdG90eXBlLCAnZm9yd2FyZFgnLCB7XG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocG9zKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX29yaWVudGF0aW9uWzBdID0gcG9zO1xuXHQgICAgICAgICAgICB0aGlzLnNldE9yaWVudGF0aW9uLmFwcGx5KHRoaXMsIHRoaXMuX29yaWVudGF0aW9uKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fb3JpZW50YXRpb25bMF07XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgbGlzdGVuZXJzIGZyb250IGRpcmVjdGlvbi4gaS5lLlxuXHRcdCAqICB3aGljaCB3YXkgdGhleSBhcmUgZmFjaW5nLlxuXHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5MaXN0ZW5lciNcblx0XHQgKiAgQG5hbWUgZm9yd2FyZFlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkxpc3RlbmVyLnByb3RvdHlwZSwgJ2ZvcndhcmRZJywge1xuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHBvcykge1xuXHQgICAgICAgICAgICB0aGlzLl9vcmllbnRhdGlvblsxXSA9IHBvcztcblx0ICAgICAgICAgICAgdGhpcy5zZXRPcmllbnRhdGlvbi5hcHBseSh0aGlzLCB0aGlzLl9vcmllbnRhdGlvbik7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uWzFdO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSB6IGNvb3JkaW5hdGUgb2YgdGhlIGxpc3RlbmVycyBmcm9udCBkaXJlY3Rpb24uIGkuZS5cblx0XHQgKiAgd2hpY2ggd2F5IHRoZXkgYXJlIGZhY2luZy5cblx0XHQgKiAgQHR5cGUge051bWJlcn1cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuTGlzdGVuZXIjXG5cdFx0ICogIEBuYW1lIGZvcndhcmRaXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5MaXN0ZW5lci5wcm90b3R5cGUsICdmb3J3YXJkWicsIHtcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwb3MpIHtcblx0ICAgICAgICAgICAgdGhpcy5fb3JpZW50YXRpb25bMl0gPSBwb3M7XG5cdCAgICAgICAgICAgIHRoaXMuc2V0T3JpZW50YXRpb24uYXBwbHkodGhpcywgdGhpcy5fb3JpZW50YXRpb24pO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcmllbnRhdGlvblsyXTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSBsaXN0ZW5lcidzIHVwIGRpcmVjdGlvbi4gaS5lLlxuXHRcdCAqICB0aGUgZGlyZWN0aW9uIHRoZSBsaXN0ZW5lciBpcyBzdGFuZGluZyBpbi5cblx0XHQgKiAgQHR5cGUge051bWJlcn1cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuTGlzdGVuZXIjXG5cdFx0ICogIEBuYW1lIHVwWFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuTGlzdGVuZXIucHJvdG90eXBlLCAndXBYJywge1xuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHBvcykge1xuXHQgICAgICAgICAgICB0aGlzLl9vcmllbnRhdGlvblszXSA9IHBvcztcblx0ICAgICAgICAgICAgdGhpcy5zZXRPcmllbnRhdGlvbi5hcHBseSh0aGlzLCB0aGlzLl9vcmllbnRhdGlvbik7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uWzNdO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGxpc3RlbmVyJ3MgdXAgZGlyZWN0aW9uLiBpLmUuXG5cdFx0ICogIHRoZSBkaXJlY3Rpb24gdGhlIGxpc3RlbmVyIGlzIHN0YW5kaW5nIGluLlxuXHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5MaXN0ZW5lciNcblx0XHQgKiAgQG5hbWUgdXBZXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5MaXN0ZW5lci5wcm90b3R5cGUsICd1cFknLCB7XG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocG9zKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX29yaWVudGF0aW9uWzRdID0gcG9zO1xuXHQgICAgICAgICAgICB0aGlzLnNldE9yaWVudGF0aW9uLmFwcGx5KHRoaXMsIHRoaXMuX29yaWVudGF0aW9uKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fb3JpZW50YXRpb25bNF07XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHogY29vcmRpbmF0ZSBvZiB0aGUgbGlzdGVuZXIncyB1cCBkaXJlY3Rpb24uIGkuZS5cblx0XHQgKiAgdGhlIGRpcmVjdGlvbiB0aGUgbGlzdGVuZXIgaXMgc3RhbmRpbmcgaW4uXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkxpc3RlbmVyI1xuXHRcdCAqICBAbmFtZSB1cFpcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkxpc3RlbmVyLnByb3RvdHlwZSwgJ3VwWicsIHtcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwb3MpIHtcblx0ICAgICAgICAgICAgdGhpcy5fb3JpZW50YXRpb25bNV0gPSBwb3M7XG5cdCAgICAgICAgICAgIHRoaXMuc2V0T3JpZW50YXRpb24uYXBwbHkodGhpcywgdGhpcy5fb3JpZW50YXRpb24pO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcmllbnRhdGlvbls1XTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuTGlzdGVuZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTGlzdGVuZXIucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fb3JpZW50YXRpb24gPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3Bvc2l0aW9uID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvL1NJTkdMRVRPTiBTRVRVUFxuXHQgICAgdmFyIExpc3RlbmVyQ29uc3RydWN0b3IgPSBUb25lLkxpc3RlbmVyO1xuXHQgICAgVG9uZS5MaXN0ZW5lciA9IG5ldyBMaXN0ZW5lckNvbnN0cnVjdG9yKCk7XG5cdCAgICBUb25lLkNvbnRleHQub24oJ2luaXQnLCBmdW5jdGlvbiAoY29udGV4dCkge1xuXHQgICAgICAgIGlmIChjb250ZXh0Lkxpc3RlbmVyIGluc3RhbmNlb2YgTGlzdGVuZXJDb25zdHJ1Y3Rvcikge1xuXHQgICAgICAgICAgICAvL2Egc2luZ2xlIGxpc3RlbmVyIG9iamVjdFxuXHQgICAgICAgICAgICBUb25lLkxpc3RlbmVyID0gY29udGV4dC5MaXN0ZW5lcjtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAvL21ha2UgbmV3IExpc3RlbmVyIGluc2lkZXNcblx0ICAgICAgICAgICAgVG9uZS5MaXN0ZW5lciA9IG5ldyBMaXN0ZW5lckNvbnN0cnVjdG9yKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNvbnRleHQuTGlzdGVuZXIgPSBUb25lLkxpc3RlbmVyO1xuXHQgICAgfSk7XG5cdCAgICAvL0VORCBTSU5HTEVUT04gU0VUVVBcblx0ICAgIHJldHVybiBUb25lLkxpc3RlbmVyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICAvKipcblx0XHQgKiBCZWNhdXNlIG9mIGEgYnVnIGluIGlPUyBjYXVzaW5nIHRoZSBjdXJyZW50VGltZSB0byBpbmNyZW1lbnRcblx0XHQgKiBiZWZvcmUgdGhlIHJlbmRlcmluZyBpcyBzdGFydGVkLCBzb21ldGltZXMgaXQgdGFrZXMgbXVsdGlwbGVcblx0XHQgKiBhdHRlbXB0cyB0byByZW5kZXIgdGhlIGF1ZGlvIGNvcnJlY3RseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgZnVuY3Rpb24gYXR0ZW1wdFJlbmRlcihjYWxsYmFjaywgZHVyYXRpb24sIHNhbXBsZVJhdGUsIHRyaWVzKSB7XG5cdCAgICAgICAgdHJpZXMgPSBUb25lLmRlZmF1bHRBcmcodHJpZXMsIDApO1xuXHQgICAgICAgIHZhciBjb250ZXh0ID0gbmV3IFRvbmUuT2ZmbGluZUNvbnRleHQoMiwgZHVyYXRpb24sIHNhbXBsZVJhdGUpO1xuXHQgICAgICAgIFRvbmUuY29udGV4dCA9IGNvbnRleHQ7XG5cdCAgICAgICAgLy9pbnZva2UgdGhlIGNhbGxiYWNrL3NjaGVkdWxpbmdcblx0ICAgICAgICB2YXIgcmVzcG9uc2UgPSBjYWxsYmFjayhUb25lLlRyYW5zcG9ydCk7XG5cdCAgICAgICAgaWYgKGNvbnRleHQuY3VycmVudFRpbWUgPiAwICYmIHRyaWVzIDwgMTAwMCkge1xuXHQgICAgICAgICAgICByZXR1cm4gYXR0ZW1wdFJlbmRlcihjYWxsYmFjaywgZHVyYXRpb24sIHNhbXBsZVJhdGUsICsrdHJpZXMpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgICAgICAncmVzcG9uc2UnOiByZXNwb25zZSxcblx0ICAgICAgICAgICAgICAgICdjb250ZXh0JzogY29udGV4dFxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHRcdCAqICBHZW5lcmF0ZSBhIGJ1ZmZlciBieSByZW5kZXJpbmcgYWxsIG9mIHRoZSBUb25lLmpzIGNvZGUgd2l0aGluIHRoZSBjYWxsYmFjayB1c2luZyB0aGUgT2ZmbGluZUF1ZGlvQ29udGV4dC5cblx0XHQgKiAgVGhlIE9mZmxpbmVBdWRpb0NvbnRleHQgaXMgY2FwYWJsZSBvZiByZW5kZXJpbmcgbXVjaCBmYXN0ZXIgdGhhbiByZWFsIHRpbWUgaW4gbWFueSBjYXNlcy5cblx0XHQgKiAgVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIGFsc28gcGFzc2VzIGluIGFuIG9mZmxpbmUgaW5zdGFuY2Ugb2YgVG9uZS5UcmFuc3BvcnQgd2hpY2ggY2FuIGJlIHVzZWRcblx0XHQgKiAgdG8gc2NoZWR1bGUgZXZlbnRzIGFsb25nIHRoZSBUcmFuc3BvcnQuICoqTk9URSoqIE9mZmxpbmVBdWRpb0NvbnRleHQgaGFzIHRoZSBzYW1lIHJlc3RyaWN0aW9uc1xuXHRcdCAqICBhcyB0aGUgQXVkaW9Db250ZXh0IGluIHRoYXQgb24gY2VydGFpbiBwbGF0Zm9ybXMgKGxpa2UgaU9TKSBpdCBtdXN0IGJlIGludm9rZWQgYnkgYW4gZXhwbGljaXRcblx0XHQgKiAgdXNlciBhY3Rpb24gbGlrZSBhIGNsaWNrIG9yIHRhcC4gXG5cdFx0ICogIEBwYXJhbSAge0Z1bmN0aW9ufSAgY2FsbGJhY2sgIEFsbCBUb25lLmpzIG5vZGVzIHdoaWNoIGFyZSBjcmVhdGVkIGFuZCBzY2hlZHVsZWQgd2l0aGluIHRoaXMgY2FsbGJhY2sgYXJlIHJlY29yZGVkIGludG8gdGhlIG91dHB1dCBCdWZmZXIuXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9ICBkdXJhdGlvbiAgICAgdGhlIGFtb3VudCBvZiB0aW1lIHRvIHJlY29yZCBmb3IuXG5cdFx0ICogIEByZXR1cm4gIHtQcm9taXNlfSAgVGhlIHByb21pc2Ugd2hpY2ggaXMgaW52b2tlZCB3aXRoIHRoZSBUb25lLkJ1ZmZlciBvZiB0aGUgcmVjb3JkZWQgb3V0cHV0LlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vcmVuZGVyIDIgc2Vjb25kcyBvZiB0aGUgb3NjaWxsYXRvclxuXHRcdCAqIFRvbmUuT2ZmbGluZShmdW5jdGlvbigpe1xuXHRcdCAqIFx0Ly9vbmx5IG5vZGVzIGNyZWF0ZWQgaW4gdGhpcyBjYWxsYmFjayB3aWxsIGJlIHJlY29yZGVkXG5cdFx0ICogXHR2YXIgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b01hc3RlcigpLnN0YXJ0KDApXG5cdFx0ICogXHQvL3NjaGVkdWxlIHRoZWlyIGV2ZW50c1xuXHRcdCAqIH0sIDIpLnRoZW4oZnVuY3Rpb24oYnVmZmVyKXtcblx0XHQgKiBcdC8vZG8gc29tZXRoaW5nIHdpdGggdGhlIG91dHB1dCBidWZmZXJcblx0XHQgKiB9KVxuXHRcdCAqIEBleGFtcGxlXG5cdFx0ICogLy9jYW4gYWxzbyBzY2hlZHVsZSBldmVudHMgYWxvbmcgdGhlIFRyYW5zcG9ydFxuXHRcdCAqIC8vdXNpbmcgdGhlIHBhc3NlZCBpbiBPZmZsaW5lIFRyYW5zcG9ydFxuXHRcdCAqIFRvbmUuT2ZmbGluZShmdW5jdGlvbihUcmFuc3BvcnQpe1xuXHRcdCAqIFx0dmFyIG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b01hc3RlcigpXG5cdFx0ICogXHRUcmFuc3BvcnQuc2NoZWR1bGUoZnVuY3Rpb24odGltZSl7XG5cdFx0ICogXHRcdG9zYy5zdGFydCh0aW1lKS5zdG9wKHRpbWUgKyAwLjEpXG5cdFx0ICogXHR9LCAxKVxuXHRcdCAqIFx0VHJhbnNwb3J0LnN0YXJ0KDAuMilcblx0XHQgKiB9LCA0KS50aGVuKGZ1bmN0aW9uKGJ1ZmZlcil7XG5cdFx0ICogXHQvL2RvIHNvbWV0aGluZyB3aXRoIHRoZSBvdXRwdXQgYnVmZmVyXG5cdFx0ICogfSlcblx0XHQgKi9cblx0ICAgIFRvbmUuT2ZmbGluZSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgZHVyYXRpb24pIHtcblx0ICAgICAgICAvL3NldCB0aGUgT2ZmbGluZUF1ZGlvQ29udGV4dFxuXHQgICAgICAgIHZhciBzYW1wbGVSYXRlID0gVG9uZS5jb250ZXh0LnNhbXBsZVJhdGU7XG5cdCAgICAgICAgdmFyIG9yaWdpbmFsQ29udGV4dCA9IFRvbmUuY29udGV4dDtcblx0ICAgICAgICB2YXIgcmVuZGVyUmV0ID0gYXR0ZW1wdFJlbmRlcihjYWxsYmFjaywgZHVyYXRpb24sIHNhbXBsZVJhdGUpO1xuXHQgICAgICAgIHZhciByZXNwb25zZSA9IHJlbmRlclJldC5yZXNwb25zZTtcblx0ICAgICAgICB2YXIgY29udGV4dCA9IHJlbmRlclJldC5jb250ZXh0O1xuXHQgICAgICAgIHZhciByZXQ7XG5cdCAgICAgICAgaWYgKHJlc3BvbnNlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuXHQgICAgICAgICAgICAvL3dhaXQgZm9yIHRoZSBwcm9taXNlIHRvIHJlc29sdmVcblx0ICAgICAgICAgICAgcmV0ID0gcmVzcG9uc2UudGhlbihmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAvL3RoZW4gcmVuZGVyIHRoZSBhdWRpb1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQucmVuZGVyKCk7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIC8vcHJvY2VzcyB0aGUgYXVkaW9cblx0ICAgICAgICAgICAgcmV0ID0gY29udGV4dC5yZW5kZXIoKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgLy9yZXR1cm4gdGhlIG9yaWdpbmFsIEF1ZGlvQ29udGV4dFxuXHQgICAgICAgIFRvbmUuY29udGV4dCA9IG9yaWdpbmFsQ29udGV4dDtcblx0ICAgICAgICAvL3JldHVybiB0aGUgYXVkaW9cblx0ICAgICAgICByZXR1cm4gcmV0LnRoZW4oZnVuY3Rpb24gKGJ1ZmZlcikge1xuXHQgICAgICAgICAgICAvL3dyYXAgaXQgaW4gYSBUb25lLkJ1ZmZlclxuXHQgICAgICAgICAgICByZXR1cm4gbmV3IFRvbmUuQnVmZmVyKGJ1ZmZlcik7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuT2ZmbGluZTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiBcdEBjbGFzcyAgVG9uZS5FZmZlY3QgaXMgdGhlIGJhc2UgY2xhc3MgZm9yIGVmZmVjdHMuIENvbm5lY3QgdGhlIGVmZmVjdCBiZXR3ZWVuXG5cdFx0ICogXHQgICAgICAgIHRoZSBlZmZlY3RTZW5kIGFuZCBlZmZlY3RSZXR1cm4gR2Fpbk5vZGVzLCB0aGVuIGNvbnRyb2wgdGhlIGFtb3VudCBvZlxuXHRcdCAqIFx0ICAgICAgICBlZmZlY3Qgd2hpY2ggZ29lcyB0byB0aGUgb3V0cHV0IHVzaW5nIHRoZSB3ZXQgY29udHJvbC5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuQXVkaW9Ob2RlfVxuXHRcdCAqICBAcGFyYW0ge05vcm1hbFJhbmdlfE9iamVjdH0gW3dldF0gVGhlIHN0YXJ0aW5nIHdldCB2YWx1ZS5cblx0XHQgKi9cblx0ICAgIFRvbmUuRWZmZWN0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFsnd2V0J10sIFRvbmUuRWZmZWN0KTtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuY3JlYXRlSW5zT3V0cygxLCAxKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgZHJ5d2V0IGtub2IgdG8gY29udHJvbCB0aGUgYW1vdW50IG9mIGVmZmVjdFxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkNyb3NzRmFkZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZHJ5V2V0ID0gbmV3IFRvbmUuQ3Jvc3NGYWRlKG9wdGlvbnMud2V0KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgd2V0IGNvbnRyb2wgaXMgaG93IG11Y2ggb2YgdGhlIGVmZmVjdGVkXG5cdFx0XHQgKiAgd2lsbCBwYXNzIHRocm91Z2ggdG8gdGhlIG91dHB1dC4gMSA9IDEwMCUgZWZmZWN0ZWRcblx0XHRcdCAqICBzaWduYWwsIDAgPSAxMDAlIGRyeSBzaWduYWwuXG5cdFx0XHQgKiAgQHR5cGUge05vcm1hbFJhbmdlfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMud2V0ID0gdGhpcy5fZHJ5V2V0LmZhZGU7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgY29ubmVjdCB0aGUgZWZmZWN0U2VuZCB0byB0aGUgaW5wdXQgb2YgaHRlIGVmZmVjdFxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkdhaW59XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZWZmZWN0U2VuZCA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBjb25uZWN0IHRoZSBvdXRwdXQgb2YgdGhlIGVmZmVjdCB0byB0aGUgZWZmZWN0UmV0dXJuXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuR2Fpbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4gPSBuZXcgVG9uZS5HYWluKCk7XG5cdCAgICAgICAgLy9jb25uZWN0aW9uc1xuXHQgICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9kcnlXZXQuYSk7XG5cdCAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuZWZmZWN0U2VuZCk7XG5cdCAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4uY29ubmVjdCh0aGlzLl9kcnlXZXQuYik7XG5cdCAgICAgICAgdGhpcy5fZHJ5V2V0LmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFsnd2V0J10pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuRWZmZWN0LCBUb25lLkF1ZGlvTm9kZSk7XG5cdCAgICAvKipcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5FZmZlY3QuZGVmYXVsdHMgPSB7ICd3ZXQnOiAxIH07XG5cdCAgICAvKipcblx0XHQgKiAgY2hhaW5zIHRoZSBlZmZlY3QgaW4gYmV0d2VlbiB0aGUgZWZmZWN0U2VuZCBhbmQgZWZmZWN0UmV0dXJuXG5cdFx0ICogIEBwYXJhbSAge1RvbmV9IGVmZmVjdFxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5FZmZlY3R9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuRWZmZWN0LnByb3RvdHlwZS5jb25uZWN0RWZmZWN0ID0gZnVuY3Rpb24gKGVmZmVjdCkge1xuXHQgICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jaGFpbihlZmZlY3QsIHRoaXMuZWZmZWN0UmV0dXJuKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkVmZmVjdH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5FZmZlY3QucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9kcnlXZXQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2RyeVdldCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmVmZmVjdFNlbmQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmVmZmVjdFJldHVybiA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoWyd3ZXQnXSk7XG5cdCAgICAgICAgdGhpcy53ZXQgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkVmZmVjdDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuQXV0b0ZpbHRlciBpcyBhIFRvbmUuRmlsdGVyIHdpdGggYSBUb25lLkxGTyBjb25uZWN0ZWQgdG8gdGhlIGZpbHRlciBjdXRvZmYgZnJlcXVlbmN5LlxuXHRcdCAqICAgICAgICAgU2V0dGluZyB0aGUgTEZPIHJhdGUgYW5kIGRlcHRoIGFsbG93cyBmb3IgY29udHJvbCBvdmVyIHRoZSBmaWx0ZXIgbW9kdWxhdGlvbiByYXRlIFxuXHRcdCAqICAgICAgICAgYW5kIGRlcHRoLlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5FZmZlY3R9XG5cdFx0ICogIEBwYXJhbSB7VGltZXxPYmplY3R9IFtmcmVxdWVuY3ldIFRoZSByYXRlIG9mIHRoZSBMRk8uXG5cdFx0ICogIEBwYXJhbSB7RnJlcXVlbmN5PX0gYmFzZUZyZXF1ZW5jeSBUaGUgbG93ZXIgdmFsdWUgb2YgdGhlIExGT3Mgb3NjaWxsYXRpb25cblx0IFx0ICogIEBwYXJhbSB7RnJlcXVlbmN5PX0gb2N0YXZlcyBUaGUgbnVtYmVyIG9mIG9jdGF2ZXMgYWJvdmUgdGhlIGJhc2VGcmVxdWVuY3lcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL2NyZWF0ZSBhbiBhdXRvZmlsdGVyIGFuZCBzdGFydCBpdCdzIExGT1xuXHRcdCAqIHZhciBhdXRvRmlsdGVyID0gbmV3IFRvbmUuQXV0b0ZpbHRlcihcIjRuXCIpLnRvTWFzdGVyKCkuc3RhcnQoKTtcblx0XHQgKiAvL3JvdXRlIGFuIG9zY2lsbGF0b3IgdGhyb3VnaCB0aGUgZmlsdGVyIGFuZCBzdGFydCBpdFxuXHRcdCAqIHZhciBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QoYXV0b0ZpbHRlcikuc3RhcnQoKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuQXV0b0ZpbHRlciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnYmFzZUZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdvY3RhdmVzJ1xuXHQgICAgICAgIF0sIFRvbmUuQXV0b0ZpbHRlcik7XG5cdCAgICAgICAgVG9uZS5FZmZlY3QuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbGZvIHdoaWNoIGRyaXZlcyB0aGUgZmlsdGVyIGN1dG9mZlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkxGT31cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbGZvID0gbmV3IFRvbmUuTEZPKHtcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeSc6IG9wdGlvbnMuZnJlcXVlbmN5LFxuXHQgICAgICAgICAgICAnYW1wbGl0dWRlJzogb3B0aW9ucy5kZXB0aFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIHJhbmdlIG9mIHRoZSBmaWx0ZXIgbW9kdWxhdGluZyBiZXR3ZWVuIHRoZSBtaW4gYW5kIG1heCBmcmVxdWVuY3kuIFxuXHRcdFx0ICogMCA9IG5vIG1vZHVsYXRpb24uIDEgPSBmdWxsIG1vZHVsYXRpb24uXG5cdFx0XHQgKiBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0XHQgKiBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmRlcHRoID0gdGhpcy5fbGZvLmFtcGxpdHVkZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIEhvdyBmYXN0IHRoZSBmaWx0ZXIgbW9kdWxhdGVzIGJldHdlZW4gbWluIGFuZCBtYXguIFxuXHRcdFx0ICogQHR5cGUge0ZyZXF1ZW5jeX1cblx0XHRcdCAqIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fbGZvLmZyZXF1ZW5jeTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZmlsdGVyIG5vZGVcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5GaWx0ZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmZpbHRlciA9IG5ldyBUb25lLkZpbHRlcihvcHRpb25zLmZpbHRlcik7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG9jdGF2ZXMgcGxhY2Vob2xkZXJcblx0XHRcdCAqICBAdHlwZSB7UG9zaXRpdmV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX29jdGF2ZXMgPSAwO1xuXHQgICAgICAgIC8vY29ubmVjdGlvbnNcblx0ICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5maWx0ZXIpO1xuXHQgICAgICAgIHRoaXMuX2xmby5jb25uZWN0KHRoaXMuZmlsdGVyLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFtcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdkZXB0aCdcblx0ICAgICAgICBdKTtcblx0ICAgICAgICB0aGlzLm9jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG5cdCAgICAgICAgdGhpcy5iYXNlRnJlcXVlbmN5ID0gb3B0aW9ucy5iYXNlRnJlcXVlbmN5O1xuXHQgICAgfTtcblx0ICAgIC8vZXh0ZW5kIEVmZmVjdFxuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5BdXRvRmlsdGVyLCBUb25lLkVmZmVjdCk7XG5cdCAgICAvKipcblx0XHQgKiAgZGVmYXVsdHNcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5BdXRvRmlsdGVyLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdmcmVxdWVuY3knOiAxLFxuXHQgICAgICAgICd0eXBlJzogJ3NpbmUnLFxuXHQgICAgICAgICdkZXB0aCc6IDEsXG5cdCAgICAgICAgJ2Jhc2VGcmVxdWVuY3knOiAyMDAsXG5cdCAgICAgICAgJ29jdGF2ZXMnOiAyLjYsXG5cdCAgICAgICAgJ2ZpbHRlcic6IHtcblx0ICAgICAgICAgICAgJ3R5cGUnOiAnbG93cGFzcycsXG5cdCAgICAgICAgICAgICdyb2xsb2ZmJzogLTEyLFxuXHQgICAgICAgICAgICAnUSc6IDFcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogU3RhcnQgdGhlIGVmZmVjdC5cblx0XHQgKiBAcGFyYW0ge1RpbWV9IFt0aW1lPW5vd10gV2hlbiB0aGUgTEZPIHdpbGwgc3RhcnQuIFxuXHRcdCAqIEByZXR1cm5zIHtUb25lLkF1dG9GaWx0ZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuQXV0b0ZpbHRlci5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRoaXMuX2xmby5zdGFydCh0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBTdG9wIHRoZSBlZmZlY3QuXG5cdFx0ICogQHBhcmFtIHtUaW1lfSBbdGltZT1ub3ddIFdoZW4gdGhlIExGTyB3aWxsIHN0b3AuIFxuXHRcdCAqIEByZXR1cm5zIHtUb25lLkF1dG9GaWx0ZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuQXV0b0ZpbHRlci5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGhpcy5fbGZvLnN0b3AodGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogU3luYyB0aGUgZmlsdGVyIHRvIHRoZSB0cmFuc3BvcnQuXG5cdFx0ICogQHBhcmFtIHtUaW1lfSBbZGVsYXk9MF0gRGVsYXkgdGltZSBiZWZvcmUgc3RhcnRpbmcgdGhlIGVmZmVjdCBhZnRlciB0aGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc3BvcnQgaGFzIHN0YXJ0ZWQuIFxuXHRcdCAqIEByZXR1cm5zIHtUb25lLkF1dG9GaWx0ZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuQXV0b0ZpbHRlci5wcm90b3R5cGUuc3luYyA9IGZ1bmN0aW9uIChkZWxheSkge1xuXHQgICAgICAgIHRoaXMuX2xmby5zeW5jKGRlbGF5KTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBVbnN5bmMgdGhlIGZpbHRlciBmcm9tIHRoZSB0cmFuc3BvcnQuXG5cdFx0ICogQHJldHVybnMge1RvbmUuQXV0b0ZpbHRlcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5BdXRvRmlsdGVyLnByb3RvdHlwZS51bnN5bmMgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fbGZvLnVuc3luYygpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFR5cGUgb2Ygb3NjaWxsYXRvciBhdHRhY2hlZCB0byB0aGUgQXV0b0ZpbHRlci4gXG5cdFx0ICogUG9zc2libGUgdmFsdWVzOiBcInNpbmVcIiwgXCJzcXVhcmVcIiwgXCJ0cmlhbmdsZVwiLCBcInNhd3Rvb3RoXCIuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuQXV0b0ZpbHRlciNcblx0XHQgKiBAdHlwZSB7c3RyaW5nfVxuXHRcdCAqIEBuYW1lIHR5cGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkF1dG9GaWx0ZXIucHJvdG90eXBlLCAndHlwZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xmby50eXBlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodHlwZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9sZm8udHlwZSA9IHR5cGU7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgbWluaW11bSB2YWx1ZSBvZiB0aGUgZmlsdGVyJ3MgY3V0b2ZmIGZyZXF1ZW5jeS5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5BdXRvRmlsdGVyI1xuXHRcdCAqIEB0eXBlIHtGcmVxdWVuY3l9XG5cdFx0ICogQG5hbWUgbWluXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5BdXRvRmlsdGVyLnByb3RvdHlwZSwgJ2Jhc2VGcmVxdWVuY3knLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9sZm8ubWluO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoZnJlcSkge1xuXHQgICAgICAgICAgICB0aGlzLl9sZm8ubWluID0gdGhpcy50b0ZyZXF1ZW5jeShmcmVxKTtcblx0ICAgICAgICAgICAgLy9hbmQgc2V0IHRoZSBtYXhcblx0ICAgICAgICAgICAgdGhpcy5vY3RhdmVzID0gdGhpcy5fb2N0YXZlcztcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBtYXhpbXVtIHZhbHVlIG9mIHRoZSBmaWx0ZXIncyBjdXRvZmYgZnJlcXVlbmN5LiBcblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5BdXRvRmlsdGVyI1xuXHRcdCAqIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHQgKiBAbmFtZSBvY3RhdmVzXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5BdXRvRmlsdGVyLnByb3RvdHlwZSwgJ29jdGF2ZXMnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9vY3RhdmVzO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAob2N0KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvY3Q7XG5cdCAgICAgICAgICAgIHRoaXMuX2xmby5tYXggPSB0aGlzLmJhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCBvY3QpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLiBcblx0XHQgKiAgQHJldHVybnMge1RvbmUuQXV0b0ZpbHRlcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5BdXRvRmlsdGVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuRWZmZWN0LnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fbGZvLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9sZm8gPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZmlsdGVyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmZpbHRlciA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoW1xuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2RlcHRoJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmRlcHRoID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5BdXRvRmlsdGVyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5BdXRvUGFubmVyIGlzIGEgVG9uZS5QYW5uZXIgd2l0aCBhbiBMRk8gY29ubmVjdGVkIHRvIHRoZSBwYW4gYW1vdW50LiBcblx0XHQgKiAgICAgICAgIE1vcmUgb24gdXNpbmcgYXV0b3Bhbm5lcnMgW2hlcmVdKGh0dHBzOi8vd3d3LmFibGV0b24uY29tL2VuL2Jsb2cvYXV0b3Bhbi1jaG9wcGVyLWVmZmVjdC1hbmQtbW9yZS1saXZlc2Nob29sLykuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkVmZmVjdH1cblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l8T2JqZWN0fSBbZnJlcXVlbmN5XSBSYXRlIG9mIGxlZnQtcmlnaHQgb3NjaWxsYXRpb24uIFxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vY3JlYXRlIGFuIGF1dG9wYW5uZXIgYW5kIHN0YXJ0IGl0J3MgTEZPXG5cdFx0ICogdmFyIGF1dG9QYW5uZXIgPSBuZXcgVG9uZS5BdXRvUGFubmVyKFwiNG5cIikudG9NYXN0ZXIoKS5zdGFydCgpO1xuXHRcdCAqIC8vcm91dGUgYW4gb3NjaWxsYXRvciB0aHJvdWdoIHRoZSBwYW5uZXIgYW5kIHN0YXJ0IGl0XG5cdFx0ICogdmFyIG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChhdXRvUGFubmVyKS5zdGFydCgpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5BdXRvUGFubmVyID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFsnZnJlcXVlbmN5J10sIFRvbmUuQXV0b1Bhbm5lcik7XG5cdCAgICAgICAgVG9uZS5FZmZlY3QuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbGZvIHdoaWNoIGRyaXZlcyB0aGUgcGFubmluZ1xuXHRcdFx0ICogIEB0eXBlIHtUb25lLkxGT31cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbGZvID0gbmV3IFRvbmUuTEZPKHtcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeSc6IG9wdGlvbnMuZnJlcXVlbmN5LFxuXHQgICAgICAgICAgICAnYW1wbGl0dWRlJzogb3B0aW9ucy5kZXB0aCxcblx0ICAgICAgICAgICAgJ21pbic6IC0xLFxuXHQgICAgICAgICAgICAnbWF4JzogMVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIGFtb3VudCBvZiBwYW5uaW5nIGJldHdlZW4gbGVmdCBhbmQgcmlnaHQuIFxuXHRcdFx0ICogMCA9IGFsd2F5cyBjZW50ZXIuIDEgPSBmdWxsIHJhbmdlIGJldHdlZW4gbGVmdCBhbmQgcmlnaHQuIFxuXHRcdFx0ICogQHR5cGUge05vcm1hbFJhbmdlfVxuXHRcdFx0ICogQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZXB0aCA9IHRoaXMuX2xmby5hbXBsaXR1ZGU7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIHBhbm5lciBub2RlIHdoaWNoIGRvZXMgdGhlIHBhbm5pbmdcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5QYW5uZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3Bhbm5lciA9IG5ldyBUb25lLlBhbm5lcigpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogSG93IGZhc3QgdGhlIHBhbm5lciBtb2R1bGF0ZXMgYmV0d2VlbiBsZWZ0IGFuZCByaWdodC4gXG5cdFx0XHQgKiBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9sZm8uZnJlcXVlbmN5O1xuXHQgICAgICAgIC8vY29ubmVjdGlvbnNcblx0ICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fcGFubmVyKTtcblx0ICAgICAgICB0aGlzLl9sZm8uY29ubmVjdCh0aGlzLl9wYW5uZXIucGFuKTtcblx0ICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoW1xuXHQgICAgICAgICAgICAnZGVwdGgnLFxuXHQgICAgICAgICAgICAnZnJlcXVlbmN5J1xuXHQgICAgICAgIF0pO1xuXHQgICAgfTtcblx0ICAgIC8vZXh0ZW5kIEVmZmVjdFxuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5BdXRvUGFubmVyLCBUb25lLkVmZmVjdCk7XG5cdCAgICAvKipcblx0XHQgKiAgZGVmYXVsdHNcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5BdXRvUGFubmVyLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdmcmVxdWVuY3knOiAxLFxuXHQgICAgICAgICd0eXBlJzogJ3NpbmUnLFxuXHQgICAgICAgICdkZXB0aCc6IDFcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBTdGFydCB0aGUgZWZmZWN0LlxuXHRcdCAqIEBwYXJhbSB7VGltZX0gW3RpbWU9bm93XSBXaGVuIHRoZSBMRk8gd2lsbCBzdGFydC4gXG5cdFx0ICogQHJldHVybnMge1RvbmUuQXV0b1Bhbm5lcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5BdXRvUGFubmVyLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGhpcy5fbGZvLnN0YXJ0KHRpbWUpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFN0b3AgdGhlIGVmZmVjdC5cblx0XHQgKiBAcGFyYW0ge1RpbWV9IFt0aW1lPW5vd10gV2hlbiB0aGUgTEZPIHdpbGwgc3RvcC4gXG5cdFx0ICogQHJldHVybnMge1RvbmUuQXV0b1Bhbm5lcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5BdXRvUGFubmVyLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9sZm8uc3RvcCh0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBTeW5jIHRoZSBwYW5uZXIgdG8gdGhlIHRyYW5zcG9ydC5cblx0XHQgKiBAcGFyYW0ge1RpbWV9IFtkZWxheT0wXSBEZWxheSB0aW1lIGJlZm9yZSBzdGFydGluZyB0aGUgZWZmZWN0IGFmdGVyIHRoZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zcG9ydCBoYXMgc3RhcnRlZC4gXG5cdFx0ICogQHJldHVybnMge1RvbmUuQXV0b1Bhbm5lcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5BdXRvUGFubmVyLnByb3RvdHlwZS5zeW5jID0gZnVuY3Rpb24gKGRlbGF5KSB7XG5cdCAgICAgICAgdGhpcy5fbGZvLnN5bmMoZGVsYXkpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFVuc3luYyB0aGUgcGFubmVyIGZyb20gdGhlIHRyYW5zcG9ydFxuXHRcdCAqIEByZXR1cm5zIHtUb25lLkF1dG9QYW5uZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuQXV0b1Bhbm5lci5wcm90b3R5cGUudW5zeW5jID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuX2xmby51bnN5bmMoKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUeXBlIG9mIG9zY2lsbGF0b3IgYXR0YWNoZWQgdG8gdGhlIEF1dG9GaWx0ZXIuIFxuXHRcdCAqIFBvc3NpYmxlIHZhbHVlczogXCJzaW5lXCIsIFwic3F1YXJlXCIsIFwidHJpYW5nbGVcIiwgXCJzYXd0b290aFwiLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkF1dG9GaWx0ZXIjXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAbmFtZSB0eXBlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5BdXRvUGFubmVyLnByb3RvdHlwZSwgJ3R5cGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9sZm8udHlwZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHR5cGUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fbGZvLnR5cGUgPSB0eXBlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkF1dG9QYW5uZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuQXV0b1Bhbm5lci5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkVmZmVjdC5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX2xmby5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbGZvID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9wYW5uZXIuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3Bhbm5lciA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoW1xuXHQgICAgICAgICAgICAnZGVwdGgnLFxuXHQgICAgICAgICAgICAnZnJlcXVlbmN5J1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmRlcHRoID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5BdXRvUGFubmVyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIFRvbmUuQXV0b1dhaCBjb25uZWN0cyBhIFRvbmUuRm9sbG93ZXIgdG8gYSBiYW5kcGFzcyBmaWx0ZXIgKFRvbmUuRmlsdGVyKS5cblx0XHQgKiAgICAgICAgICBUaGUgZnJlcXVlbmN5IG9mIHRoZSBmaWx0ZXIgaXMgYWRqdXN0ZWQgcHJvcG9ydGlvbmFsbHkgdG8gdGhlXG5cdFx0ICogICAgICAgICAgaW5jb21pbmcgc2lnbmFsJ3MgYW1wbGl0dWRlLiBJbnNwaXJhdGlvbiBmcm9tIFtUdW5hLmpzXShodHRwczovL2dpdGh1Yi5jb20vRGluYWhtb2UvdHVuYSkuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkVmZmVjdH1cblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l8T2JqZWN0fSBbYmFzZUZyZXF1ZW5jeV0gVGhlIGZyZXF1ZW5jeSB0aGUgZmlsdGVyIGlzIHNldFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0byBhdCB0aGUgbG93IHBvaW50IG9mIHRoZSB3YWhcblx0XHQgKiAgQHBhcmFtIHtQb3NpdGl2ZX0gW29jdGF2ZXNdIFRoZSBudW1iZXIgb2Ygb2N0YXZlcyBhYm92ZSB0aGUgYmFzZUZyZXF1ZW5jeVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgZmlsdGVyIHdpbGwgc3dlZXAgdG8gd2hlbiBmdWxseSBvcGVuXG5cdFx0ICogIEBwYXJhbSB7RGVjaWJlbHN9IFtzZW5zaXRpdml0eV0gVGhlIGRlY2liZWwgdGhyZXNob2xkIHNlbnNpdGl2aXR5IGZvclxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgaW5jb21pbmcgc2lnbmFsLiBOb3JtYWwgcmFuZ2Ugb2YgLTQwIHRvIDAuXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIGF1dG9XYWggPSBuZXcgVG9uZS5BdXRvV2FoKDUwLCA2LCAtMzApLnRvTWFzdGVyKCk7XG5cdFx0ICogLy9pbml0aWFsaXplIHRoZSBzeW50aCBhbmQgY29ubmVjdCB0byBhdXRvd2FoXG5cdFx0ICogdmFyIHN5bnRoID0gbmV3IFN5bnRoLmNvbm5lY3QoYXV0b1dhaCk7XG5cdFx0ICogLy9RIHZhbHVlIGluZmx1ZW5jZXMgdGhlIGVmZmVjdCBvZiB0aGUgd2FoIC0gZGVmYXVsdCBpcyAyXG5cdFx0ICogYXV0b1dhaC5RLnZhbHVlID0gNjtcblx0XHQgKiAvL21vcmUgYXVkaWJsZSBvbiBoaWdoZXIgbm90ZXNcblx0XHQgKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiOG5cIilcblx0XHQgKi9cblx0ICAgIFRvbmUuQXV0b1dhaCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdiYXNlRnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ29jdGF2ZXMnLFxuXHQgICAgICAgICAgICAnc2Vuc2l0aXZpdHknXG5cdCAgICAgICAgXSwgVG9uZS5BdXRvV2FoKTtcblx0ICAgICAgICBUb25lLkVmZmVjdC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBlbnZlbG9wZSBmb2xsb3dlci4gU2V0IHRoZSBhdHRhY2svcmVsZWFzZVxuXHRcdFx0ICogIHRpbWluZyB0byBhZGp1c3QgaG93IHRoZSBlbnZlbG9wZSBpcyBmb2xsb3dlZC5cblx0XHRcdCAqICBAdHlwZSB7VG9uZS5Gb2xsb3dlcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5mb2xsb3dlciA9IG5ldyBUb25lLkZvbGxvd2VyKG9wdGlvbnMuZm9sbG93ZXIpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHNjYWxlcyB0aGUgZm9sbG93ZXIgdmFsdWUgdG8gdGhlIGZyZXF1ZW5jeSBkb21haW5cblx0XHRcdCAqICBAdHlwZSB7VG9uZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3dlZXBSYW5nZSA9IG5ldyBUb25lLlNjYWxlRXhwKDAsIDEsIDAuNSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQHR5cGUge251bWJlcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IG9wdGlvbnMuYmFzZUZyZXF1ZW5jeTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAdHlwZSB7bnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBpbnB1dCBnYWluIHRvIGFkanVzdCB0aGUgc2Vuc2l0aXZpdHlcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5HYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9pbnB1dEJvb3N0ID0gbmV3IFRvbmUuR2FpbigpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEB0eXBlIHtCaXF1YWRGaWx0ZXJOb2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9iYW5kcGFzcyA9IG5ldyBUb25lLkZpbHRlcih7XG5cdCAgICAgICAgICAgICdyb2xsb2ZmJzogLTQ4LFxuXHQgICAgICAgICAgICAnZnJlcXVlbmN5JzogMCxcblx0ICAgICAgICAgICAgJ1EnOiBvcHRpb25zLlFcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5GaWx0ZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3BlYWtpbmcgPSBuZXcgVG9uZS5GaWx0ZXIoMCwgJ3BlYWtpbmcnKTtcblx0ICAgICAgICB0aGlzLl9wZWFraW5nLmdhaW4udmFsdWUgPSBvcHRpb25zLmdhaW47XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBUaGUgZ2FpbiBvZiB0aGUgZmlsdGVyLlxuXHRcdFx0ICogQHR5cGUge051bWJlcn1cblx0XHRcdCAqIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZ2FpbiA9IHRoaXMuX3BlYWtpbmcuZ2Fpbjtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBxdWFsaXR5IG9mIHRoZSBmaWx0ZXIuXG5cdFx0XHQgKiBAdHlwZSB7UG9zaXRpdmV9XG5cdFx0XHQgKiBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLlEgPSB0aGlzLl9iYW5kcGFzcy5RO1xuXHQgICAgICAgIC8vdGhlIGNvbnRyb2wgc2lnbmFsIHBhdGhcblx0ICAgICAgICB0aGlzLmVmZmVjdFNlbmQuY2hhaW4odGhpcy5faW5wdXRCb29zdCwgdGhpcy5mb2xsb3dlciwgdGhpcy5fc3dlZXBSYW5nZSk7XG5cdCAgICAgICAgdGhpcy5fc3dlZXBSYW5nZS5jb25uZWN0KHRoaXMuX2JhbmRwYXNzLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgdGhpcy5fc3dlZXBSYW5nZS5jb25uZWN0KHRoaXMuX3BlYWtpbmcuZnJlcXVlbmN5KTtcblx0ICAgICAgICAvL3RoZSBmaWx0ZXJlZCBwYXRoXG5cdCAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNoYWluKHRoaXMuX2JhbmRwYXNzLCB0aGlzLl9wZWFraW5nLCB0aGlzLmVmZmVjdFJldHVybik7XG5cdCAgICAgICAgLy9zZXQgdGhlIGluaXRpYWwgdmFsdWVcblx0ICAgICAgICB0aGlzLl9zZXRTd2VlcFJhbmdlKCk7XG5cdCAgICAgICAgdGhpcy5zZW5zaXRpdml0eSA9IG9wdGlvbnMuc2Vuc2l0aXZpdHk7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoW1xuXHQgICAgICAgICAgICAnZ2FpbicsXG5cdCAgICAgICAgICAgICdRJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuQXV0b1dhaCwgVG9uZS5FZmZlY3QpO1xuXHQgICAgLyoqXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuQXV0b1dhaC5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnYmFzZUZyZXF1ZW5jeSc6IDEwMCxcblx0ICAgICAgICAnb2N0YXZlcyc6IDYsXG5cdCAgICAgICAgJ3NlbnNpdGl2aXR5JzogMCxcblx0ICAgICAgICAnUSc6IDIsXG5cdCAgICAgICAgJ2dhaW4nOiAyLFxuXHQgICAgICAgICdmb2xsb3dlcic6IHtcblx0ICAgICAgICAgICAgJ2F0dGFjayc6IDAuMyxcblx0ICAgICAgICAgICAgJ3JlbGVhc2UnOiAwLjVcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIG51bWJlciBvZiBvY3RhdmVzIHRoYXQgdGhlIGZpbHRlciB3aWxsIHN3ZWVwIGFib3ZlIHRoZVxuXHRcdCAqIGJhc2VGcmVxdWVuY3kuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuQXV0b1dhaCNcblx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqIEBuYW1lIG9jdGF2ZXNcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkF1dG9XYWgucHJvdG90eXBlLCAnb2N0YXZlcycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChvY3RhdmVzKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvY3RhdmVzO1xuXHQgICAgICAgICAgICB0aGlzLl9zZXRTd2VlcFJhbmdlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgYmFzZSBmcmVxdWVuY3kgZnJvbSB3aGljaCB0aGUgc3dlZXAgd2lsbCBzdGFydCBmcm9tLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkF1dG9XYWgjXG5cdFx0ICogQHR5cGUge0ZyZXF1ZW5jeX1cblx0XHQgKiBAbmFtZSBiYXNlRnJlcXVlbmN5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5BdXRvV2FoLnByb3RvdHlwZSwgJ2Jhc2VGcmVxdWVuY3knLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoYmFzZUZyZXEpIHtcblx0ICAgICAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IGJhc2VGcmVxO1xuXHQgICAgICAgICAgICB0aGlzLl9zZXRTd2VlcFJhbmdlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgc2Vuc2l0aXZpdHkgdG8gY29udHJvbCBob3cgcmVzcG9uc2l2ZSB0byB0aGUgaW5wdXQgc2lnbmFsIHRoZSBmaWx0ZXIgaXMuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuQXV0b1dhaCNcblx0XHQgKiBAdHlwZSB7RGVjaWJlbHN9XG5cdFx0ICogQG5hbWUgc2Vuc2l0aXZpdHlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkF1dG9XYWgucHJvdG90eXBlLCAnc2Vuc2l0aXZpdHknLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBUb25lLmdhaW5Ub0RiKDEgLyB0aGlzLl9pbnB1dEJvb3N0LmdhaW4udmFsdWUpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoc2Vuc2l0aXZ5KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2lucHV0Qm9vc3QuZ2Fpbi52YWx1ZSA9IDEgLyBUb25lLmRiVG9HYWluKHNlbnNpdGl2eSk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgc2V0cyB0aGUgc3dlZXAgcmFuZ2Ugb2YgdGhlIHNjYWxlclxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5BdXRvV2FoLnByb3RvdHlwZS5fc2V0U3dlZXBSYW5nZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLm1pbiA9IHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG5cdCAgICAgICAgdGhpcy5fc3dlZXBSYW5nZS5tYXggPSBNYXRoLm1pbih0aGlzLl9iYXNlRnJlcXVlbmN5ICogTWF0aC5wb3coMiwgdGhpcy5fb2N0YXZlcyksIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlIC8gMik7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5BdXRvV2FofSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkF1dG9XYWgucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5FZmZlY3QucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLmZvbGxvd2VyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmZvbGxvd2VyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9zd2VlcFJhbmdlID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9iYW5kcGFzcy5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fYmFuZHBhc3MgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3BlYWtpbmcuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3BlYWtpbmcgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2lucHV0Qm9vc3QuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2lucHV0Qm9vc3QgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ2dhaW4nLFxuXHQgICAgICAgICAgICAnUSdcblx0ICAgICAgICBdKTtcblx0ICAgICAgICB0aGlzLmdhaW4gPSBudWxsO1xuXHQgICAgICAgIHRoaXMuUSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuQXV0b1dhaDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFNpZ25hbC1yYXRlIG1vZHVsbyBvcGVyYXRvci4gT25seSB3b3JrcyBpbiBBdWRpb1JhbmdlIFstMSwgMV0gYW5kIGZvciBtb2R1bHVzXG5cdFx0ICogICAgICAgICB2YWx1ZXMgaW4gdGhlIE5vcm1hbFJhbmdlLlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5TaWduYWxCYXNlfVxuXHRcdCAqICBAcGFyYW0ge05vcm1hbFJhbmdlfSBtb2R1bHVzIFRoZSBtb2R1bHVzIHRvIGFwcGx5LlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBtb2QgPSBuZXcgVG9uZS5Nb2R1bG8oMC4yKVxuXHRcdCAqIHZhciBzaWcgPSBuZXcgVG9uZS5TaWduYWwoMC41KS5jb25uZWN0KG1vZCk7XG5cdFx0ICogLy9tb2Qgb3V0cHV0cyAwLjFcblx0XHQgKi9cblx0ICAgIFRvbmUuTW9kdWxvID0gZnVuY3Rpb24gKG1vZHVsdXMpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLmNyZWF0ZUluc091dHMoMSwgMCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQSB3YXZlc2hhcGVyIGdldHMgdGhlIGludGVnZXIgbXVsdGlwbGUgb2Zcblx0XHRcdCAqICB0aGUgaW5wdXQgc2lnbmFsIGFuZCB0aGUgbW9kdWx1cy5cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLldhdmVTaGFwZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9zaGFwZXIgPSBuZXcgVG9uZS5XYXZlU2hhcGVyKE1hdGgucG93KDIsIDE2KSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGludGVnZXIgbXVsdGlwbGUgaXMgbXVsdGlwbGllZCBieSB0aGUgbW9kdWx1c1xuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5NdWx0aXBseX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbXVsdGlwbHkgPSBuZXcgVG9uZS5NdWx0aXBseSgpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGFuZCBzdWJ0cmFjdGVkIGZyb20gdGhlIGlucHV0IHNpZ25hbFxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5TdWJ0cmFjdH1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3VidHJhY3QgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLlN1YnRyYWN0KCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIG1vZHVsdXMgc2lnbmFsXG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLlNpZ25hbH1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbW9kU2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKG1vZHVsdXMpO1xuXHQgICAgICAgIC8vY29ubmVjdGlvbnNcblx0ICAgICAgICB0aGlzLmlucHV0LmZhbih0aGlzLl9zaGFwZXIsIHRoaXMuX3N1YnRyYWN0KTtcblx0ICAgICAgICB0aGlzLl9tb2RTaWduYWwuY29ubmVjdCh0aGlzLl9tdWx0aXBseSwgMCwgMCk7XG5cdCAgICAgICAgdGhpcy5fc2hhcGVyLmNvbm5lY3QodGhpcy5fbXVsdGlwbHksIDAsIDEpO1xuXHQgICAgICAgIHRoaXMuX211bHRpcGx5LmNvbm5lY3QodGhpcy5fc3VidHJhY3QsIDAsIDEpO1xuXHQgICAgICAgIHRoaXMuX3NldFdhdmVTaGFwZXIobW9kdWx1cyk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5Nb2R1bG8sIFRvbmUuU2lnbmFsQmFzZSk7XG5cdCAgICAvKipcblx0XHQgKiAgQHBhcmFtICB7bnVtYmVyfSAgbW9kICB0aGUgbW9kdWx1cyB0byBhcHBseVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Nb2R1bG8ucHJvdG90eXBlLl9zZXRXYXZlU2hhcGVyID0gZnVuY3Rpb24gKG1vZCkge1xuXHQgICAgICAgIHRoaXMuX3NoYXBlci5zZXRNYXAoZnVuY3Rpb24gKHZhbCkge1xuXHQgICAgICAgICAgICB2YXIgbXVsdGlwbGUgPSBNYXRoLmZsb29yKCh2YWwgKyAwLjAwMDEpIC8gbW9kKTtcblx0ICAgICAgICAgICAgcmV0dXJuIG11bHRpcGxlO1xuXHQgICAgICAgIH0pO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBtb2R1bHVzIHZhbHVlLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLk1vZHVsbyNcblx0XHQgKiBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0ICogQG5hbWUgdmFsdWVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLk1vZHVsby5wcm90b3R5cGUsICd2YWx1ZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21vZFNpZ25hbC52YWx1ZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKG1vZCkge1xuXHQgICAgICAgICAgICB0aGlzLl9tb2RTaWduYWwudmFsdWUgPSBtb2Q7XG5cdCAgICAgICAgICAgIHRoaXMuX3NldFdhdmVTaGFwZXIobW9kKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk1vZHVsb30gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Nb2R1bG8ucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWxCYXNlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fc2hhcGVyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9zaGFwZXIgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX211bHRpcGx5LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9tdWx0aXBseSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fc3VidHJhY3QuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3N1YnRyYWN0ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9tb2RTaWduYWwuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX21vZFNpZ25hbCA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuTW9kdWxvO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5CaXRjcnVzaGVyIGRvd25zYW1wbGVzIHRoZSBpbmNvbWluZyBzaWduYWwgdG8gYSBkaWZmZXJlbnQgYml0ZGVwdGguXG5cdFx0ICogICAgICAgICBMb3dlcmluZyB0aGUgYml0ZGVwdGggb2YgdGhlIHNpZ25hbCBjcmVhdGVzIGRpc3RvcnRpb24uIFJlYWQgbW9yZSBhYm91dCBCaXRjcnVzaGluZ1xuXHRcdCAqICAgICAgICAgb24gW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQml0Y3J1c2hlcikuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkVmZmVjdH1cblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ9IGJpdHMgVGhlIG51bWJlciBvZiBiaXRzIHRvIGRvd25zYW1wbGUgdGhlIHNpZ25hbC4gTm9taW5hbCByYW5nZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICBvZiAxIHRvIDguXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9pbml0aWFsaXplIGNydXNoZXIgYW5kIHJvdXRlIGEgc3ludGggdGhyb3VnaCBpdFxuXHRcdCAqIHZhciBjcnVzaGVyID0gbmV3IFRvbmUuQml0Q3J1c2hlcig0KS50b01hc3RlcigpO1xuXHRcdCAqIHZhciBzeW50aCA9IG5ldyBUb25lLk1vbm9TeW50aCgpLmNvbm5lY3QoY3J1c2hlcik7XG5cdFx0ICovXG5cdCAgICBUb25lLkJpdENydXNoZXIgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgWydiaXRzJ10sIFRvbmUuQml0Q3J1c2hlcik7XG5cdCAgICAgICAgVG9uZS5FZmZlY3QuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICB2YXIgaW52U3RlcFNpemUgPSAxIC8gTWF0aC5wb3coMiwgb3B0aW9ucy5iaXRzIC0gMSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgU3VidHJhY3QgdGhlIGlucHV0IHNpZ25hbCBhbmQgdGhlIG1vZHVsdXMgb2YgdGhlIGlucHV0IHNpZ25hbFxuXHRcdFx0ICogIEB0eXBlIHtUb25lLlN1YnRyYWN0fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9zdWJ0cmFjdCA9IG5ldyBUb25lLlN1YnRyYWN0KCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG1vZCBmdW5jdGlvblxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5Nb2R1bG99XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX21vZHVsbyA9IG5ldyBUb25lLk1vZHVsbyhpbnZTdGVwU2l6ZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAga2VlcHMgdHJhY2sgb2YgdGhlIGJpdHNcblx0XHRcdCAqICBAdHlwZSB7bnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9iaXRzID0gb3B0aW9ucy5iaXRzO1xuXHQgICAgICAgIC8vY29ubmVjdCBpdCB1cFxuXHQgICAgICAgIHRoaXMuZWZmZWN0U2VuZC5mYW4odGhpcy5fc3VidHJhY3QsIHRoaXMuX21vZHVsbyk7XG5cdCAgICAgICAgdGhpcy5fbW9kdWxvLmNvbm5lY3QodGhpcy5fc3VidHJhY3QsIDAsIDEpO1xuXHQgICAgICAgIHRoaXMuX3N1YnRyYWN0LmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm4pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuQml0Q3J1c2hlciwgVG9uZS5FZmZlY3QpO1xuXHQgICAgLyoqXG5cdFx0ICogIHRoZSBkZWZhdWx0IHZhbHVlc1xuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkJpdENydXNoZXIuZGVmYXVsdHMgPSB7ICdiaXRzJzogNCB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIGJpdCBkZXB0aCBvZiB0aGUgZWZmZWN0LiBOb21pbmFsIHJhbmdlIG9mIDEtOC5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5CaXRDcnVzaGVyI1xuXHRcdCAqIEB0eXBlIHtudW1iZXJ9XG5cdFx0ICogQG5hbWUgYml0c1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQml0Q3J1c2hlci5wcm90b3R5cGUsICdiaXRzJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fYml0cztcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGJpdHMpIHtcblx0ICAgICAgICAgICAgdGhpcy5fYml0cyA9IGJpdHM7XG5cdCAgICAgICAgICAgIHZhciBpbnZTdGVwU2l6ZSA9IDEgLyBNYXRoLnBvdygyLCBiaXRzIC0gMSk7XG5cdCAgICAgICAgICAgIHRoaXMuX21vZHVsby52YWx1ZSA9IGludlN0ZXBTaXplO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5CaXRDcnVzaGVyfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkJpdENydXNoZXIucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5FZmZlY3QucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9zdWJ0cmFjdC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fc3VidHJhY3QgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX21vZHVsby5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbW9kdWxvID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5CaXRDcnVzaGVyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5DaGVieVNoZXYgaXMgYSBDaGVieXNoZXYgd2F2ZXNoYXBlciwgYW4gZWZmZWN0IHdoaWNoIGlzIGdvb2QgXG5cdFx0ICogICAgICAgICBmb3IgbWFraW5nIGRpZmZlcmVudCB0eXBlcyBvZiBkaXN0b3J0aW9uIHNvdW5kcy5cblx0XHQgKiAgICAgICAgIE5vdGUgdGhhdCBvZGQgb3JkZXJzIHNvdW5kIHZlcnkgZGlmZmVyZW50IGZyb20gZXZlbiBvbmVzLCBcblx0XHQgKiAgICAgICAgIGFuZCBvcmRlciA9IDEgaXMgbm8gY2hhbmdlLiBcblx0XHQgKiAgICAgICAgIFJlYWQgbW9yZSBhdCBbbXVzaWMuY29sdW1iaWEuZWR1XShodHRwOi8vbXVzaWMuY29sdW1iaWEuZWR1L2NtYy9tdXNpY2FuZGNvbXB1dGVycy9jaGFwdGVyNC8wNF8wNi5waHApLlxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkVmZmVjdH1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBwYXJhbSB7UG9zaXRpdmV8T2JqZWN0fSBbb3JkZXJdIFRoZSBvcmRlciBvZiB0aGUgY2hlYnlzaGV2IHBvbHlub21pYWwuIE5vcm1hbCByYW5nZSBiZXR3ZWVuIDEtMTAwLiBcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL2NyZWF0ZSBhIG5ldyBjaGVieVxuXHRcdCAqIHZhciBjaGVieSA9IG5ldyBUb25lLkNoZWJ5c2hldig1MCk7XG5cdFx0ICogLy9jcmVhdGUgYSBtb25vc3ludGggY29ubmVjdGVkIHRvIG91ciBjaGVieVxuXHRcdCAqIHN5bnRoID0gbmV3IFRvbmUuTW9ub1N5bnRoKCkuY29ubmVjdChjaGVieSk7XG5cdFx0ICovXG5cdCAgICBUb25lLkNoZWJ5c2hldiA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbJ29yZGVyJ10sIFRvbmUuQ2hlYnlzaGV2KTtcblx0ICAgICAgICBUb25lLkVmZmVjdC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEB0eXBlIHtXYXZlU2hhcGVyTm9kZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc2hhcGVyID0gbmV3IFRvbmUuV2F2ZVNoYXBlcig0MDk2KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIGhvbGRzIG9udG8gdGhlIG9yZGVyIG9mIHRoZSBmaWx0ZXJcblx0XHRcdCAqIEB0eXBlIHtudW1iZXJ9XG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fb3JkZXIgPSBvcHRpb25zLm9yZGVyO1xuXHQgICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9zaGFwZXIpO1xuXHQgICAgICAgIHRoaXMub3JkZXIgPSBvcHRpb25zLm9yZGVyO1xuXHQgICAgICAgIHRoaXMub3ZlcnNhbXBsZSA9IG9wdGlvbnMub3ZlcnNhbXBsZTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkNoZWJ5c2hldiwgVG9uZS5FZmZlY3QpO1xuXHQgICAgLyoqXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQGNvbnN0XG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkNoZWJ5c2hldi5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnb3JkZXInOiAxLFxuXHQgICAgICAgICdvdmVyc2FtcGxlJzogJ25vbmUnXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIGdldCB0aGUgY29lZmZpY2llbnQgZm9yIHRoYXQgZGVncmVlXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSB4IHRoZSB4IHZhbHVlXG5cdFx0ICogIEBwYXJhbSAgIHtudW1iZXJ9IGRlZ3JlZSBcblx0XHQgKiAgQHBhcmFtIHtPYmplY3R9IG1lbW8gbWVtb2l6ZSB0aGUgY29tcHV0ZWQgdmFsdWUuIFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICB0aGlzIHNwZWVkcyB1cCBjb21wdXRhdGlvbiBncmVhdGx5LiBcblx0XHQgKiAgQHJldHVybiAge251bWJlcn0gICAgICAgdGhlIGNvZWZmaWNpZW50IFxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5DaGVieXNoZXYucHJvdG90eXBlLl9nZXRDb2VmZmljaWVudCA9IGZ1bmN0aW9uICh4LCBkZWdyZWUsIG1lbW8pIHtcblx0ICAgICAgICBpZiAobWVtby5oYXNPd25Qcm9wZXJ0eShkZWdyZWUpKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBtZW1vW2RlZ3JlZV07XG5cdCAgICAgICAgfSBlbHNlIGlmIChkZWdyZWUgPT09IDApIHtcblx0ICAgICAgICAgICAgbWVtb1tkZWdyZWVdID0gMDtcblx0ICAgICAgICB9IGVsc2UgaWYgKGRlZ3JlZSA9PT0gMSkge1xuXHQgICAgICAgICAgICBtZW1vW2RlZ3JlZV0gPSB4O1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIG1lbW9bZGVncmVlXSA9IDIgKiB4ICogdGhpcy5fZ2V0Q29lZmZpY2llbnQoeCwgZGVncmVlIC0gMSwgbWVtbykgLSB0aGlzLl9nZXRDb2VmZmljaWVudCh4LCBkZWdyZWUgLSAyLCBtZW1vKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIG1lbW9bZGVncmVlXTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgb3JkZXIgb2YgdGhlIENoZWJ5c2hldiBwb2x5bm9taWFsIHdoaWNoIGNyZWF0ZXNcblx0XHQgKiB0aGUgZXF1YXRpb24gd2hpY2ggaXMgYXBwbGllZCB0byB0aGUgaW5jb21pbmcgXG5cdFx0ICogc2lnbmFsIHRocm91Z2ggYSBUb25lLldhdmVTaGFwZXIuIFRoZSBlcXVhdGlvbnNcblx0XHQgKiBhcmUgaW4gdGhlIGZvcm06PGJyPlxuXHRcdCAqIG9yZGVyIDI6IDJ4XjIgKyAxPGJyPlxuXHRcdCAqIG9yZGVyIDM6IDR4XjMgKyAzeCA8YnI+XG5cdFx0ICogQG1lbWJlck9mIFRvbmUuQ2hlYnlzaGV2I1xuXHRcdCAqIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHQgKiBAbmFtZSBvcmRlclxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQ2hlYnlzaGV2LnByb3RvdHlwZSwgJ29yZGVyJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fb3JkZXI7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChvcmRlcikge1xuXHQgICAgICAgICAgICB0aGlzLl9vcmRlciA9IG9yZGVyO1xuXHQgICAgICAgICAgICB2YXIgY3VydmUgPSBuZXcgQXJyYXkoNDA5Nik7XG5cdCAgICAgICAgICAgIHZhciBsZW4gPSBjdXJ2ZS5sZW5ndGg7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcblx0ICAgICAgICAgICAgICAgIHZhciB4ID0gaSAqIDIgLyBsZW4gLSAxO1xuXHQgICAgICAgICAgICAgICAgaWYgKHggPT09IDApIHtcblx0ICAgICAgICAgICAgICAgICAgICAvL3Nob3VsZCBvdXRwdXQgMCB3aGVuIGlucHV0IGlzIDBcblx0ICAgICAgICAgICAgICAgICAgICBjdXJ2ZVtpXSA9IDA7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIGN1cnZlW2ldID0gdGhpcy5fZ2V0Q29lZmZpY2llbnQoeCwgb3JkZXIsIHt9KTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aGlzLl9zaGFwZXIuY3VydmUgPSBjdXJ2ZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBvdmVyc2FtcGxpbmcgb2YgdGhlIGVmZmVjdC4gQ2FuIGVpdGhlciBiZSBcIm5vbmVcIiwgXCIyeFwiIG9yIFwiNHhcIi5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5DaGVieXNoZXYjXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAbmFtZSBvdmVyc2FtcGxlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5DaGVieXNoZXYucHJvdG90eXBlLCAnb3ZlcnNhbXBsZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NoYXBlci5vdmVyc2FtcGxlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAob3ZlcnNhbXBsaW5nKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3NoYXBlci5vdmVyc2FtcGxlID0gb3ZlcnNhbXBsaW5nO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLiBcblx0XHQgKiAgQHJldHVybnMge1RvbmUuQ2hlYnlzaGV2fSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkNoZWJ5c2hldi5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkVmZmVjdC5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3NoYXBlci5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fc2hhcGVyID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5DaGVieXNoZXY7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBCYXNlIGNsYXNzIGZvciBTdGVyZW8gZWZmZWN0cy4gUHJvdmlkZXMgZWZmZWN0U2VuZEwvUiBhbmQgZWZmZWN0UmV0dXJuTC9SLlxuXHRcdCAqXG5cdFx0ICpcdEBjb25zdHJ1Y3RvclxuXHRcdCAqXHRAZXh0ZW5kcyB7VG9uZS5FZmZlY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLlN0ZXJlb0VmZmVjdCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAvL2dldCB0aGUgZGVmYXVsdHNcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFsnd2V0J10sIFRvbmUuRWZmZWN0KTtcblx0ICAgICAgICB0aGlzLmNyZWF0ZUluc091dHMoMSwgMSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGRyeXdldCBrbm9iIHRvIGNvbnRyb2wgdGhlIGFtb3VudCBvZiBlZmZlY3Rcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5Dcm9zc0ZhZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2RyeVdldCA9IG5ldyBUb25lLkNyb3NzRmFkZShvcHRpb25zLndldCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHdldCBjb250cm9sLCBpLmUuIGhvdyBtdWNoIG9mIHRoZSBlZmZlY3RlZFxuXHRcdFx0ICogIHdpbGwgcGFzcyB0aHJvdWdoIHRvIHRoZSBvdXRwdXQuXG5cdFx0XHQgKiAgQHR5cGUge05vcm1hbFJhbmdlfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMud2V0ID0gdGhpcy5fZHJ5V2V0LmZhZGU7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlbiBzcGxpdCBpdFxuXHRcdFx0ICogIEB0eXBlIHtUb25lLlNwbGl0fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9zcGxpdCA9IG5ldyBUb25lLlNwbGl0KCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGVmZmVjdHMgc2VuZCBMRUZUXG5cdFx0XHQgKiAgQHR5cGUge0dhaW5Ob2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmVmZmVjdFNlbmRMID0gdGhpcy5fc3BsaXQubGVmdDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgZWZmZWN0cyBzZW5kIFJJR0hUXG5cdFx0XHQgKiAgQHR5cGUge0dhaW5Ob2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmVmZmVjdFNlbmRSID0gdGhpcy5fc3BsaXQucmlnaHQ7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIHN0ZXJlbyBlZmZlY3QgbWVyZ2VyXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuTWVyZ2V9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX21lcmdlID0gbmV3IFRvbmUuTWVyZ2UoKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgZWZmZWN0IHJldHVybiBMRUZUXG5cdFx0XHQgKiAgQHR5cGUge0dhaW5Ob2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmVmZmVjdFJldHVybkwgPSB0aGlzLl9tZXJnZS5sZWZ0O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBlZmZlY3QgcmV0dXJuIFJJR0hUXG5cdFx0XHQgKiAgQHR5cGUge0dhaW5Ob2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmVmZmVjdFJldHVyblIgPSB0aGlzLl9tZXJnZS5yaWdodDtcblx0ICAgICAgICAvL2Nvbm5lY3Rpb25zXG5cdCAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX3NwbGl0KTtcblx0ICAgICAgICAvL2RyeSB3ZXQgY29ubmVjdGlvbnNcblx0ICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fZHJ5V2V0LCAwLCAwKTtcblx0ICAgICAgICB0aGlzLl9tZXJnZS5jb25uZWN0KHRoaXMuX2RyeVdldCwgMCwgMSk7XG5cdCAgICAgICAgdGhpcy5fZHJ5V2V0LmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFsnd2V0J10pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuU3RlcmVvRWZmZWN0LCBUb25lLkVmZmVjdCk7XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlN0ZXJlb0VmZmVjdH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5TdGVyZW9FZmZlY3QucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9kcnlXZXQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2RyeVdldCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fc3BsaXQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3NwbGl0ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9tZXJnZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbWVyZ2UgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZWZmZWN0U2VuZEwgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZWZmZWN0U2VuZFIgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuTCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm5SID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbJ3dldCddKTtcblx0ICAgICAgICB0aGlzLndldCA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuU3RlcmVvRWZmZWN0O1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5DaG9ydXMgaXMgYSBzdGVyZW8gY2hvcnVzIGVmZmVjdCBjb21wb3NlZCBvZlxuXHRcdCAqICAgICAgICAgYSBsZWZ0IGFuZCByaWdodCBkZWxheSB3aXRoIGEgVG9uZS5MRk8gYXBwbGllZCB0byB0aGUgZGVsYXlUaW1lIG9mIGVhY2ggY2hhbm5lbC5cblx0XHQgKiAgICAgICAgIEluc3BpcmF0aW9uIGZyb20gW1R1bmEuanNdKGh0dHBzOi8vZ2l0aHViLmNvbS9EaW5haG1vZS90dW5hL2Jsb2IvbWFzdGVyL3R1bmEuanMpLlxuXHRcdCAqICAgICAgICAgUmVhZCBtb3JlIG9uIHRoZSBjaG9ydXMgZWZmZWN0IG9uIFtTb3VuZE9uU291bmRdKGh0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbS9zb3MvanVuMDQvYXJ0aWNsZXMvc3ludGhzZWNyZXRzLmh0bSkuXG5cdFx0ICpcblx0XHQgKlx0QGNvbnN0cnVjdG9yXG5cdFx0ICpcdEBleHRlbmRzIHtUb25lLlN0ZXJlb0VmZmVjdH1cblx0XHQgKlx0QHBhcmFtIHtGcmVxdWVuY3l8T2JqZWN0fSBbZnJlcXVlbmN5XSBUaGUgZnJlcXVlbmN5IG9mIHRoZSBMRk8uXG5cdFx0ICpcdEBwYXJhbSB7TWlsbGlzZWNvbmRzfSBbZGVsYXlUaW1lXSBUaGUgZGVsYXkgb2YgdGhlIGNob3J1cyBlZmZlY3QgaW4gbXMuXG5cdFx0ICpcdEBwYXJhbSB7Tm9ybWFsUmFuZ2V9IFtkZXB0aF0gVGhlIGRlcHRoIG9mIHRoZSBjaG9ydXMuXG5cdFx0ICpcdEBleGFtcGxlXG5cdFx0ICogdmFyIGNob3J1cyA9IG5ldyBUb25lLkNob3J1cyg0LCAyLjUsIDAuNSk7XG5cdFx0ICogdmFyIHN5bnRoID0gbmV3IFRvbmUuUG9seVN5bnRoKDQsIFRvbmUuTW9ub1N5bnRoKS5jb25uZWN0KGNob3J1cyk7XG5cdFx0ICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoW1wiQzNcIixcIkUzXCIsXCJHM1wiXSwgXCI4blwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuQ2hvcnVzID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdkZWxheVRpbWUnLFxuXHQgICAgICAgICAgICAnZGVwdGgnXG5cdCAgICAgICAgXSwgVG9uZS5DaG9ydXMpO1xuXHQgICAgICAgIFRvbmUuU3RlcmVvRWZmZWN0LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGRlcHRoIG9mIHRoZSBjaG9ydXNcblx0XHRcdCAqICBAdHlwZSB7bnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9kZXB0aCA9IG9wdGlvbnMuZGVwdGg7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGRlbGF5VGltZVxuXHRcdFx0ICogIEB0eXBlIHtudW1iZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2RlbGF5VGltZSA9IG9wdGlvbnMuZGVsYXlUaW1lIC8gMTAwMDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbGZvIHdoaWNoIGNvbnRyb2xzIHRoZSBkZWxheVRpbWVcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5MRk99XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2xmb0wgPSBuZXcgVG9uZS5MRk8oe1xuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jzogb3B0aW9ucy5mcmVxdWVuY3ksXG5cdCAgICAgICAgICAgICdtaW4nOiAwLFxuXHQgICAgICAgICAgICAnbWF4JzogMVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGFub3RoZXIgTEZPIGZvciB0aGUgcmlnaHQgc2lkZSB3aXRoIGEgMTgwIGRlZ3JlZSBwaGFzZSBkaWZmXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuTEZPfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9sZm9SID0gbmV3IFRvbmUuTEZPKHtcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeSc6IG9wdGlvbnMuZnJlcXVlbmN5LFxuXHQgICAgICAgICAgICAnbWluJzogMCxcblx0ICAgICAgICAgICAgJ21heCc6IDEsXG5cdCAgICAgICAgICAgICdwaGFzZSc6IDE4MFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGRlbGF5IGZvciBsZWZ0XG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuRGVsYXl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2RlbGF5Tm9kZUwgPSBuZXcgVG9uZS5EZWxheSgpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGRlbGF5IGZvciByaWdodFxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkRlbGF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9kZWxheU5vZGVSID0gbmV3IFRvbmUuRGVsYXkoKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBmcmVxdWVuY3kgb2YgdGhlIExGTyB3aGljaCBtb2R1bGF0ZXMgdGhlIGRlbGF5VGltZS5cblx0XHRcdCAqIEB0eXBlIHtGcmVxdWVuY3l9XG5cdFx0XHQgKiBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX2xmb0wuZnJlcXVlbmN5O1xuXHQgICAgICAgIC8vY29ubmVjdGlvbnNcblx0ICAgICAgICB0aGlzLmVmZmVjdFNlbmRMLmNoYWluKHRoaXMuX2RlbGF5Tm9kZUwsIHRoaXMuZWZmZWN0UmV0dXJuTCk7XG5cdCAgICAgICAgdGhpcy5lZmZlY3RTZW5kUi5jaGFpbih0aGlzLl9kZWxheU5vZGVSLCB0aGlzLmVmZmVjdFJldHVyblIpO1xuXHQgICAgICAgIC8vYW5kIHBhc3MgdGhyb3VnaCB0byBtYWtlIHRoZSBkZXR1bmUgYXBwYXJlbnRcblx0ICAgICAgICB0aGlzLmVmZmVjdFNlbmRMLmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm5MKTtcblx0ICAgICAgICB0aGlzLmVmZmVjdFNlbmRSLmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm5SKTtcblx0ICAgICAgICAvL2xmbyBzZXR1cFxuXHQgICAgICAgIHRoaXMuX2xmb0wuY29ubmVjdCh0aGlzLl9kZWxheU5vZGVMLmRlbGF5VGltZSk7XG5cdCAgICAgICAgdGhpcy5fbGZvUi5jb25uZWN0KHRoaXMuX2RlbGF5Tm9kZVIuZGVsYXlUaW1lKTtcblx0ICAgICAgICAvL3N0YXJ0IHRoZSBsZm9cblx0ICAgICAgICB0aGlzLl9sZm9MLnN0YXJ0KCk7XG5cdCAgICAgICAgdGhpcy5fbGZvUi5zdGFydCgpO1xuXHQgICAgICAgIC8vaGF2ZSBvbmUgTEZPIGZyZXF1ZW5jeSBjb250cm9sIHRoZSBvdGhlclxuXHQgICAgICAgIHRoaXMuX2xmb0wuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fbGZvUi5mcmVxdWVuY3kpO1xuXHQgICAgICAgIC8vc2V0IHRoZSBpbml0aWFsIHZhbHVlc1xuXHQgICAgICAgIHRoaXMuZGVwdGggPSB0aGlzLl9kZXB0aDtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeS52YWx1ZSA9IG9wdGlvbnMuZnJlcXVlbmN5O1xuXHQgICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbJ2ZyZXF1ZW5jeSddKTtcblx0ICAgICAgICB0aGlzLnNwcmVhZCA9IG9wdGlvbnMuc3ByZWFkO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuQ2hvcnVzLCBUb25lLlN0ZXJlb0VmZmVjdCk7XG5cdCAgICAvKipcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5DaG9ydXMuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2ZyZXF1ZW5jeSc6IDEuNSxcblx0ICAgICAgICAnZGVsYXlUaW1lJzogMy41LFxuXHQgICAgICAgICdkZXB0aCc6IDAuNyxcblx0ICAgICAgICAndHlwZSc6ICdzaW5lJyxcblx0ICAgICAgICAnc3ByZWFkJzogMTgwXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIGRlcHRoIG9mIHRoZSBlZmZlY3QuIEEgZGVwdGggb2YgMSBtYWtlcyB0aGUgZGVsYXlUaW1lXG5cdFx0ICogbW9kdWxhdGUgYmV0d2VlbiAwIGFuZCAyKmRlbGF5VGltZSAoY2VudGVyZWQgYXJvdW5kIHRoZSBkZWxheVRpbWUpLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkNob3J1cyNcblx0XHQgKiBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0ICogQG5hbWUgZGVwdGhcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkNob3J1cy5wcm90b3R5cGUsICdkZXB0aCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlcHRoO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoZGVwdGgpIHtcblx0ICAgICAgICAgICAgdGhpcy5fZGVwdGggPSBkZXB0aDtcblx0ICAgICAgICAgICAgdmFyIGRldmlhdGlvbiA9IHRoaXMuX2RlbGF5VGltZSAqIGRlcHRoO1xuXHQgICAgICAgICAgICB0aGlzLl9sZm9MLm1pbiA9IE1hdGgubWF4KHRoaXMuX2RlbGF5VGltZSAtIGRldmlhdGlvbiwgMCk7XG5cdCAgICAgICAgICAgIHRoaXMuX2xmb0wubWF4ID0gdGhpcy5fZGVsYXlUaW1lICsgZGV2aWF0aW9uO1xuXHQgICAgICAgICAgICB0aGlzLl9sZm9SLm1pbiA9IE1hdGgubWF4KHRoaXMuX2RlbGF5VGltZSAtIGRldmlhdGlvbiwgMCk7XG5cdCAgICAgICAgICAgIHRoaXMuX2xmb1IubWF4ID0gdGhpcy5fZGVsYXlUaW1lICsgZGV2aWF0aW9uO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIGRlbGF5VGltZSBpbiBtaWxsaXNlY29uZHMgb2YgdGhlIGNob3J1cy4gQSBsYXJnZXIgZGVsYXlUaW1lXG5cdFx0ICogd2lsbCBnaXZlIGEgbW9yZSBwcm9ub3VuY2VkIGVmZmVjdC4gTm9taW5hbCByYW5nZSBhIGRlbGF5VGltZVxuXHRcdCAqIGlzIGJldHdlZW4gMiBhbmQgMjBtcy5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5DaG9ydXMjXG5cdFx0ICogQHR5cGUge01pbGxpc2Vjb25kc31cblx0XHQgKiBAbmFtZSBkZWxheVRpbWVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkNob3J1cy5wcm90b3R5cGUsICdkZWxheVRpbWUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZWxheVRpbWUgKiAxMDAwO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoZGVsYXlUaW1lKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2RlbGF5VGltZSA9IGRlbGF5VGltZSAvIDEwMDA7XG5cdCAgICAgICAgICAgIHRoaXMuZGVwdGggPSB0aGlzLl9kZXB0aDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBvc2NpbGxhdG9yIHR5cGUgb2YgdGhlIExGTy5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5DaG9ydXMjXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAbmFtZSB0eXBlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5DaG9ydXMucHJvdG90eXBlLCAndHlwZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xmb0wudHlwZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHR5cGUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fbGZvTC50eXBlID0gdHlwZTtcblx0ICAgICAgICAgICAgdGhpcy5fbGZvUi50eXBlID0gdHlwZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIEFtb3VudCBvZiBzdGVyZW8gc3ByZWFkLiBXaGVuIHNldCB0byAwLCBib3RoIExGTydzIHdpbGwgYmUgcGFubmVkIGNlbnRyYWxseS5cblx0XHQgKiBXaGVuIHNldCB0byAxODAsIExGTydzIHdpbGwgYmUgcGFubmVkIGhhcmQgbGVmdCBhbmQgcmlnaHQgcmVzcGVjdGl2ZWx5LlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkNob3J1cyNcblx0XHQgKiBAdHlwZSB7RGVncmVlc31cblx0XHQgKiBAbmFtZSBzcHJlYWRcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkNob3J1cy5wcm90b3R5cGUsICdzcHJlYWQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9sZm9SLnBoYXNlIC0gdGhpcy5fbGZvTC5waGFzZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHNwcmVhZCkge1xuXHQgICAgICAgICAgICB0aGlzLl9sZm9MLnBoYXNlID0gOTAgLSBzcHJlYWQgLyAyO1xuXHQgICAgICAgICAgICB0aGlzLl9sZm9SLnBoYXNlID0gc3ByZWFkIC8gMiArIDkwO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5DaG9ydXN9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuQ2hvcnVzLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuU3RlcmVvRWZmZWN0LnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fbGZvTC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbGZvTCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fbGZvUi5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbGZvUiA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fZGVsYXlOb2RlTC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fZGVsYXlOb2RlTCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fZGVsYXlOb2RlUi5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fZGVsYXlOb2RlUiA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoJ2ZyZXF1ZW5jeScpO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5DaG9ydXM7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgVG9uZS5Db252b2x2ZXIgaXMgYSB3cmFwcGVyIGFyb3VuZCB0aGUgTmF0aXZlIFdlYiBBdWRpb1xuXHRcdCAqICAgICAgICAgIFtDb252b2x2ZXJOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1jb252b2x2ZXJub2RlLWludGVyZmFjZSkuXG5cdFx0ICogICAgICAgICAgQ29udm9sdXRpb24gaXMgdXNlZnVsIGZvciByZXZlcmIgYW5kIGZpbHRlciBlbXVsYXRpb24uIFJlYWQgbW9yZSBhYm91dCBjb252b2x1dGlvbiByZXZlcmIgb25cblx0XHQgKiAgICAgICAgICBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db252b2x1dGlvbl9yZXZlcmIpLlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5FZmZlY3R9XG5cdFx0ICogIEBwYXJhbSB7c3RyaW5nfFRvbmUuQnVmZmVyfE9iamVjdH0gW3VybF0gVGhlIFVSTCBvZiB0aGUgaW1wdWxzZSByZXNwb25zZSBvciB0aGUgVG9uZS5CdWZmZXJcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aWFuaW5nIHRoZSBpbXB1bHNlIHJlc3BvbnNlLlxuXHRcdCAqICBAcGFyYW0ge0Z1bmN0aW9uPX0gb25sb2FkIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgdXJsIGlzIGxvYWRlZC5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL2luaXRpYWxpemluZyB0aGUgY29udm9sdmVyIHdpdGggYW4gaW1wdWxzZSByZXNwb25zZVxuXHRcdCAqIHZhciBjb252b2x2ZXIgPSBuZXcgVG9uZS5Db252b2x2ZXIoXCIuL3BhdGgvdG8vaXIud2F2XCIpLnRvTWFzdGVyKCk7XG5cdFx0ICovXG5cdCAgICBUb25lLkNvbnZvbHZlciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICd1cmwnLFxuXHQgICAgICAgICAgICAnb25sb2FkJ1xuXHQgICAgICAgIF0sIFRvbmUuQ29udm9sdmVyKTtcblx0ICAgICAgICBUb25lLkVmZmVjdC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGNvbnZvbHZlciBub2RlXG5cdFx0XHQgKiAgQHR5cGUge0NvbnZvbHZlck5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2NvbnZvbHZlciA9IHRoaXMuY29udGV4dC5jcmVhdGVDb252b2x2ZXIoKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgY29udm9sdXRpb24gYnVmZmVyXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQnVmZmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9idWZmZXIgPSBuZXcgVG9uZS5CdWZmZXIob3B0aW9ucy51cmwsIGZ1bmN0aW9uIChidWZmZXIpIHtcblx0ICAgICAgICAgICAgdGhpcy5fY29udm9sdmVyLmJ1ZmZlciA9IGJ1ZmZlci5nZXQoKTtcblx0ICAgICAgICAgICAgb3B0aW9ucy5vbmxvYWQoKTtcblx0ICAgICAgICB9LmJpbmQodGhpcykpO1xuXHQgICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9jb252b2x2ZXIpO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuQ29udm9sdmVyLCBUb25lLkVmZmVjdCk7XG5cdCAgICAvKipcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkNvbnZvbHZlci5kZWZhdWx0cyA9IHsgJ29ubG9hZCc6IFRvbmUubm9PcCB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBjb252b2x2ZXIncyBidWZmZXJcblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuQ29udm9sdmVyI1xuXHRcdCAqICBAdHlwZSB7QXVkaW9CdWZmZXJ9XG5cdFx0ICogIEBuYW1lIGJ1ZmZlclxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQ29udm9sdmVyLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5nZXQoKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGJ1ZmZlcikge1xuXHQgICAgICAgICAgICB0aGlzLl9idWZmZXIuc2V0KGJ1ZmZlcik7XG5cdCAgICAgICAgICAgIHRoaXMuX2NvbnZvbHZlci5idWZmZXIgPSB0aGlzLl9idWZmZXIuZ2V0KCk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgTG9hZCBhbiBpbXB1bHNlIHJlc3BvbnNlIHVybCBhcyBhbiBhdWRpbyBidWZmZXIuXG5cdFx0ICogIERlY29kZXMgdGhlIGF1ZGlvIGFzeW5jaHJvbm91c2x5IGFuZCBpbnZva2VzXG5cdFx0ICogIHRoZSBjYWxsYmFjayBvbmNlIHRoZSBhdWRpbyBidWZmZXIgbG9hZHMuXG5cdFx0ICogIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIHVybCBvZiB0aGUgYnVmZmVyIHRvIGxvYWQuXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgZmlsZXR5cGUgc3VwcG9ydCBkZXBlbmRzIG9uIHRoZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgIGJyb3dzZXIuXG5cdFx0ICogIEBwYXJhbSAge2Z1bmN0aW9uPX0gY2FsbGJhY2tcblx0XHQgKiAgQHJldHVybnMge1Byb21pc2V9XG5cdFx0ICovXG5cdCAgICBUb25lLkNvbnZvbHZlci5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uICh1cmwsIGNhbGxiYWNrKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5sb2FkKHVybCwgZnVuY3Rpb24gKGJ1ZmYpIHtcblx0ICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBidWZmO1xuXHQgICAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcblx0ICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LmJpbmQodGhpcykpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuQ29udm9sdmVyfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkNvbnZvbHZlci5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkVmZmVjdC5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX2NvbnZvbHZlci5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgdGhpcy5fY29udm9sdmVyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9idWZmZXIuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2J1ZmZlciA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuQ29udm9sdmVyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5EaXN0b3J0aW9uIGlzIGEgc2ltcGxlIGRpc3RvcnRpb24gZWZmZWN0IHVzaW5nIFRvbmUuV2F2ZVNoYXBlci5cblx0XHQgKiAgICAgICAgIEFsZ29yaXRobSBmcm9tIFthIHN0YWNrb3ZlcmZsb3cgYW5zd2VyXShodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjMxMzQwOCkuXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuRWZmZWN0fVxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ8T2JqZWN0fSBbZGlzdG9ydGlvbl0gVGhlIGFtb3VudCBvZiBkaXN0b3J0aW9uIChub21pbmFsIHJhbmdlIG9mIDAtMSlcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgZGlzdCA9IG5ldyBUb25lLkRpc3RvcnRpb24oMC44KS50b01hc3RlcigpO1xuXHRcdCAqIHZhciBmbSA9IG5ldyBUb25lLlNpbXBsZUZNKCkuY29ubmVjdChkaXN0KTtcblx0XHQgKiAvL3RoaXMgc291bmRzIGdvb2Qgb24gYmFzcyBub3Rlc1xuXHRcdCAqIGZtLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQTFcIiwgXCI4blwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuRGlzdG9ydGlvbiA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbJ2Rpc3RvcnRpb24nXSwgVG9uZS5EaXN0b3J0aW9uKTtcblx0ICAgICAgICBUb25lLkVmZmVjdC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLldhdmVTaGFwZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3NoYXBlciA9IG5ldyBUb25lLldhdmVTaGFwZXIoNDA5Nik7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBob2xkcyB0aGUgZGlzdG9ydGlvbiBhbW91bnRcblx0XHRcdCAqIEB0eXBlIHtudW1iZXJ9XG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZGlzdG9ydGlvbiA9IG9wdGlvbnMuZGlzdG9ydGlvbjtcblx0ICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fc2hhcGVyKTtcblx0ICAgICAgICB0aGlzLmRpc3RvcnRpb24gPSBvcHRpb25zLmRpc3RvcnRpb247XG5cdCAgICAgICAgdGhpcy5vdmVyc2FtcGxlID0gb3B0aW9ucy5vdmVyc2FtcGxlO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuRGlzdG9ydGlvbiwgVG9uZS5FZmZlY3QpO1xuXHQgICAgLyoqXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQGNvbnN0XG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkRpc3RvcnRpb24uZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2Rpc3RvcnRpb24nOiAwLjQsXG5cdCAgICAgICAgJ292ZXJzYW1wbGUnOiAnbm9uZSdcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgYW1vdW50IG9mIGRpc3RvcnRpb24uXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuRGlzdG9ydGlvbiNcblx0XHQgKiBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0ICogQG5hbWUgZGlzdG9ydGlvblxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuRGlzdG9ydGlvbi5wcm90b3R5cGUsICdkaXN0b3J0aW9uJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fZGlzdG9ydGlvbjtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGFtb3VudCkge1xuXHQgICAgICAgICAgICB0aGlzLl9kaXN0b3J0aW9uID0gYW1vdW50O1xuXHQgICAgICAgICAgICB2YXIgayA9IGFtb3VudCAqIDEwMDtcblx0ICAgICAgICAgICAgdmFyIGRlZyA9IE1hdGguUEkgLyAxODA7XG5cdCAgICAgICAgICAgIHRoaXMuX3NoYXBlci5zZXRNYXAoZnVuY3Rpb24gKHgpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChNYXRoLmFicyh4KSA8IDAuMDAxKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgLy9zaG91bGQgb3V0cHV0IDAgd2hlbiBpbnB1dCBpcyAwXG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiAoMyArIGspICogeCAqIDIwICogZGVnIC8gKE1hdGguUEkgKyBrICogTWF0aC5hYnMoeCkpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBvdmVyc2FtcGxpbmcgb2YgdGhlIGVmZmVjdC4gQ2FuIGVpdGhlciBiZSBcIm5vbmVcIiwgXCIyeFwiIG9yIFwiNHhcIi5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5EaXN0b3J0aW9uI1xuXHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0ICogQG5hbWUgb3ZlcnNhbXBsZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuRGlzdG9ydGlvbi5wcm90b3R5cGUsICdvdmVyc2FtcGxlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChvdmVyc2FtcGxpbmcpIHtcblx0ICAgICAgICAgICAgdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGUgPSBvdmVyc2FtcGxpbmc7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuIFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5EaXN0b3J0aW9ufSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkRpc3RvcnRpb24ucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5FZmZlY3QucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9zaGFwZXIuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3NoYXBlciA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuRGlzdG9ydGlvbjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiBcdEBjbGFzcyAgVG9uZS5GZWVkYmFja0VmZmVjdCBwcm92aWRlcyBhIGxvb3AgYmV0d2VlbiBhbiBcblx0XHQgKiBcdCAgICAgICAgYXVkaW8gc291cmNlIGFuZCBpdHMgb3duIG91dHB1dC4gVGhpcyBpcyBhIGJhc2UtY2xhc3Ncblx0XHQgKiBcdCAgICAgICAgZm9yIGZlZWRiYWNrIGVmZmVjdHMuIFxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5FZmZlY3R9XG5cdFx0ICogIEBwYXJhbSB7Tm9ybWFsUmFuZ2V8T2JqZWN0fSBbZmVlZGJhY2tdIFRoZSBpbml0aWFsIGZlZWRiYWNrIHZhbHVlLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5GZWVkYmFja0VmZmVjdCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbJ2ZlZWRiYWNrJ10sIFRvbmUuRmVlZGJhY2tFZmZlY3QpO1xuXHQgICAgICAgIFRvbmUuRWZmZWN0LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGdhaW4gd2hpY2ggY29udHJvbHMgdGhlIGZlZWRiYWNrXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuR2Fpbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZmVlZGJhY2tHYWluID0gbmV3IFRvbmUuR2FpbihvcHRpb25zLmZlZWRiYWNrLCBUb25lLlR5cGUuTm9ybWFsUmFuZ2UpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhbW91bnQgb2Ygc2lnbmFsIHdoaWNoIGlzIGZlZCBiYWNrIGludG8gdGhlIGVmZmVjdCBpbnB1dC4gXG5cdFx0XHQgKiAgQHR5cGUge05vcm1hbFJhbmdlfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZmVlZGJhY2sgPSB0aGlzLl9mZWVkYmFja0dhaW4uZ2Fpbjtcblx0ICAgICAgICAvL3RoZSBmZWVkYmFjayBsb29wXG5cdCAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4uY2hhaW4odGhpcy5fZmVlZGJhY2tHYWluLCB0aGlzLmVmZmVjdFNlbmQpO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFsnZmVlZGJhY2snXSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5GZWVkYmFja0VmZmVjdCwgVG9uZS5FZmZlY3QpO1xuXHQgICAgLyoqXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuRmVlZGJhY2tFZmZlY3QuZGVmYXVsdHMgPSB7ICdmZWVkYmFjayc6IDAuMTI1IH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuIFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5GZWVkYmFja0VmZmVjdH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5GZWVkYmFja0VmZmVjdC5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkVmZmVjdC5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFsnZmVlZGJhY2snXSk7XG5cdCAgICAgICAgdGhpcy5fZmVlZGJhY2tHYWluLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9mZWVkYmFja0dhaW4gPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZmVlZGJhY2sgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkZlZWRiYWNrRWZmZWN0O1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIFRvbmUuRmVlZGJhY2tEZWxheSBpcyBhIERlbGF5Tm9kZSBpbiB3aGljaCBwYXJ0IG9mIG91dHB1dFxuXHRcdCAqICAgICAgICAgIHNpZ25hbCBpcyBmZWQgYmFjayBpbnRvIHRoZSBkZWxheS5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuRmVlZGJhY2tFZmZlY3R9XG5cdFx0ICogIEBwYXJhbSB7VGltZXxPYmplY3R9IFtkZWxheVRpbWVdIFRoZSBkZWxheSBhcHBsaWVkIHRvIHRoZSBpbmNvbWluZyBzaWduYWwuXG5cdFx0ICogIEBwYXJhbSB7Tm9ybWFsUmFuZ2U9fSBmZWVkYmFjayBUaGUgYW1vdW50IG9mIHRoZSBlZmZlY3RlZCBzaWduYWwgd2hpY2hcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBmZWQgYmFjayB0aHJvdWdoIHRoZSBkZWxheS5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgZmVlZGJhY2tEZWxheSA9IG5ldyBUb25lLkZlZWRiYWNrRGVsYXkoXCI4blwiLCAwLjUpLnRvTWFzdGVyKCk7XG5cdFx0ICogdmFyIHRvbSA9IG5ldyBUb25lLkRydW1TeW50aCh7XG5cdFx0ICogXHRcIm9jdGF2ZXNcIiA6IDQsXG5cdFx0ICogXHRcInBpdGNoRGVjYXlcIiA6IDAuMVxuXHRcdCAqIH0pLmNvbm5lY3QoZmVlZGJhY2tEZWxheSk7XG5cdFx0ICogdG9tLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQTJcIixcIjMyblwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuRmVlZGJhY2tEZWxheSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdkZWxheVRpbWUnLFxuXHQgICAgICAgICAgICAnZmVlZGJhY2snXG5cdCAgICAgICAgXSwgVG9uZS5GZWVkYmFja0RlbGF5KTtcblx0ICAgICAgICBUb25lLkZlZWRiYWNrRWZmZWN0LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGRlbGF5IG5vZGVcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5EZWxheX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZGVsYXlOb2RlID0gbmV3IFRvbmUuRGVsYXkob3B0aW9ucy5kZWxheVRpbWUsIG9wdGlvbnMubWF4RGVsYXkpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBkZWxheVRpbWUgb2YgdGhlIERlbGF5Tm9kZS5cblx0XHRcdCAqICBAdHlwZSB7VGltZX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmRlbGF5VGltZSA9IHRoaXMuX2RlbGF5Tm9kZS5kZWxheVRpbWU7XG5cdCAgICAgICAgLy8gY29ubmVjdCBpdCB1cFxuXHQgICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9kZWxheU5vZGUpO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFsnZGVsYXlUaW1lJ10pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuRmVlZGJhY2tEZWxheSwgVG9uZS5GZWVkYmFja0VmZmVjdCk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGRlZmF1bHQgdmFsdWVzLlxuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5GZWVkYmFja0RlbGF5LmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdkZWxheVRpbWUnOiAwLjI1LFxuXHQgICAgICAgICdtYXhEZWxheSc6IDFcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgY2xlYW4gdXBcblx0XHQgKiAgQHJldHVybnMge1RvbmUuRmVlZGJhY2tEZWxheX0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5GZWVkYmFja0RlbGF5LnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuRmVlZGJhY2tFZmZlY3QucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9kZWxheU5vZGUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2RlbGF5Tm9kZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoWydkZWxheVRpbWUnXSk7XG5cdCAgICAgICAgdGhpcy5kZWxheVRpbWUgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkZlZWRiYWNrRGVsYXk7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIGFuIGFycmF5IG9mIGNvbWIgZmlsdGVyIGRlbGF5IHZhbHVlcyBmcm9tIEZyZWV2ZXJiIGltcGxlbWVudGF0aW9uXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKiAgQHR5cGUge0FycmF5fVxuXHRcdCAqL1xuXHQgICAgdmFyIGNvbWJGaWx0ZXJUdW5pbmdzID0gW1xuXHQgICAgICAgIDE1NTcgLyA0NDEwMCxcblx0ICAgICAgICAxNjE3IC8gNDQxMDAsXG5cdCAgICAgICAgMTQ5MSAvIDQ0MTAwLFxuXHQgICAgICAgIDE0MjIgLyA0NDEwMCxcblx0ICAgICAgICAxMjc3IC8gNDQxMDAsXG5cdCAgICAgICAgMTM1NiAvIDQ0MTAwLFxuXHQgICAgICAgIDExODggLyA0NDEwMCxcblx0ICAgICAgICAxMTE2IC8gNDQxMDBcblx0ICAgIF07XG5cdCAgICAvKipcblx0XHQgKiAgYW4gYXJyYXkgb2YgYWxscGFzcyBmaWx0ZXIgZnJlcXVlbmN5IHZhbHVlcyBmcm9tIEZyZWV2ZXJiIGltcGxlbWVudGF0aW9uXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHR5cGUge0FycmF5fVxuXHRcdCAqL1xuXHQgICAgdmFyIGFsbHBhc3NGaWx0ZXJGcmVxdWVuY2llcyA9IFtcblx0ICAgICAgICAyMjUsXG5cdCAgICAgICAgNTU2LFxuXHQgICAgICAgIDQ0MSxcblx0ICAgICAgICAzNDFcblx0ICAgIF07XG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuRnJlZXZlcmIgaXMgYSByZXZlcmIgYmFzZWQgb24gW0ZyZWV2ZXJiXShodHRwczovL2Njcm1hLnN0YW5mb3JkLmVkdS9+am9zL3Bhc3AvRnJlZXZlcmIuaHRtbCkuXG5cdFx0ICogICAgICAgICBSZWFkIG1vcmUgb24gcmV2ZXJiIG9uIFtTb3VuZCBPbiBTb3VuZF0oaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTYwNDA0MDgzOTAyL2h0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbTo4MC9zb3MvZmViMDEvYXJ0aWNsZXMvc3ludGhzZWNyZXRzLmFzcCkuXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuRWZmZWN0fVxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQHBhcmFtIHtOb3JtYWxSYW5nZXxPYmplY3R9IFtyb29tU2l6ZV0gQ29ycmVsYXRlZCB0byB0aGUgZGVjYXkgdGltZS5cblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l9IFtkYW1wZW5pbmddIFRoZSBjdXRvZmYgZnJlcXVlbmN5IG9mIGEgbG93cGFzcyBmaWx0ZXIgYXMgcGFydFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2YgdGhlIHJldmVyYi5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgZnJlZXZlcmIgPSBuZXcgVG9uZS5GcmVldmVyYigpLnRvTWFzdGVyKCk7XG5cdFx0ICogZnJlZXZlcmIuZGFtcGVuaW5nLnZhbHVlID0gMTAwMDtcblx0XHQgKiAvL3JvdXRpbmcgc3ludGggdGhyb3VnaCB0aGUgcmV2ZXJiXG5cdFx0ICogdmFyIHN5bnRoID0gbmV3IFRvbmUuQU1TeW50aCgpLmNvbm5lY3QoZnJlZXZlcmIpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5GcmVldmVyYiA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdyb29tU2l6ZScsXG5cdCAgICAgICAgICAgICdkYW1wZW5pbmcnXG5cdCAgICAgICAgXSwgVG9uZS5GcmVldmVyYik7XG5cdCAgICAgICAgVG9uZS5TdGVyZW9FZmZlY3QuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgcm9vbVNpemUgdmFsdWUgYmV0d2Vlbi4gQSBsYXJnZXIgcm9vbVNpemVcblx0XHRcdCAqICB3aWxsIHJlc3VsdCBpbiBhIGxvbmdlciBkZWNheS5cblx0XHRcdCAqICBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5yb29tU2l6ZSA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLnJvb21TaXplLCBUb25lLlR5cGUuTm9ybWFsUmFuZ2UpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhbW91bnQgb2YgZGFtcGVuaW5nIG9mIHRoZSByZXZlcmJlcmFudCBzaWduYWwuXG5cdFx0XHQgKiAgQHR5cGUge0ZyZXF1ZW5jeX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmRhbXBlbmluZyA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLmRhbXBlbmluZywgVG9uZS5UeXBlLkZyZXF1ZW5jeSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGNvbWIgZmlsdGVyc1xuXHRcdFx0ICogIEB0eXBlIHtBcnJheX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fY29tYkZpbHRlcnMgPSBbXTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgYWxscGFzcyBmaWx0ZXJzIG9uIHRoZSBsZWZ0XG5cdFx0XHQgKiAgQHR5cGUge0FycmF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc0wgPSBbXTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgYWxscGFzcyBmaWx0ZXJzIG9uIHRoZSByaWdodFxuXHRcdFx0ICogIEB0eXBlIHtBcnJheX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNSID0gW107XG5cdCAgICAgICAgLy9tYWtlIHRoZSBhbGxwYXNzIGZpbHRlcnMgb24gdGhlIHJpZ2h0XG5cdCAgICAgICAgZm9yICh2YXIgbCA9IDA7IGwgPCBhbGxwYXNzRmlsdGVyRnJlcXVlbmNpZXMubGVuZ3RoOyBsKyspIHtcblx0ICAgICAgICAgICAgdmFyIGFsbHBhc3NMID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuXHQgICAgICAgICAgICBhbGxwYXNzTC50eXBlID0gJ2FsbHBhc3MnO1xuXHQgICAgICAgICAgICBhbGxwYXNzTC5mcmVxdWVuY3kudmFsdWUgPSBhbGxwYXNzRmlsdGVyRnJlcXVlbmNpZXNbbF07XG5cdCAgICAgICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzTC5wdXNoKGFsbHBhc3NMKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgLy9tYWtlIHRoZSBhbGxwYXNzIGZpbHRlcnMgb24gdGhlIGxlZnRcblx0ICAgICAgICBmb3IgKHZhciByID0gMDsgciA8IGFsbHBhc3NGaWx0ZXJGcmVxdWVuY2llcy5sZW5ndGg7IHIrKykge1xuXHQgICAgICAgICAgICB2YXIgYWxscGFzc1IgPSB0aGlzLmNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG5cdCAgICAgICAgICAgIGFsbHBhc3NSLnR5cGUgPSAnYWxscGFzcyc7XG5cdCAgICAgICAgICAgIGFsbHBhc3NSLmZyZXF1ZW5jeS52YWx1ZSA9IGFsbHBhc3NGaWx0ZXJGcmVxdWVuY2llc1tyXTtcblx0ICAgICAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNSLnB1c2goYWxscGFzc1IpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL21ha2UgdGhlIGNvbWIgZmlsdGVyc1xuXHQgICAgICAgIGZvciAodmFyIGMgPSAwOyBjIDwgY29tYkZpbHRlclR1bmluZ3MubGVuZ3RoOyBjKyspIHtcblx0ICAgICAgICAgICAgdmFyIGxmcGYgPSBuZXcgVG9uZS5Mb3dwYXNzQ29tYkZpbHRlcihjb21iRmlsdGVyVHVuaW5nc1tjXSk7XG5cdCAgICAgICAgICAgIGlmIChjIDwgY29tYkZpbHRlclR1bmluZ3MubGVuZ3RoIC8gMikge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5lZmZlY3RTZW5kTC5jaGFpbihsZnBmLCB0aGlzLl9hbGxwYXNzRmlsdGVyc0xbMF0pO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5lZmZlY3RTZW5kUi5jaGFpbihsZnBmLCB0aGlzLl9hbGxwYXNzRmlsdGVyc1JbMF0pO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMucm9vbVNpemUuY29ubmVjdChsZnBmLnJlc29uYW5jZSk7XG5cdCAgICAgICAgICAgIHRoaXMuZGFtcGVuaW5nLmNvbm5lY3QobGZwZi5kYW1wZW5pbmcpO1xuXHQgICAgICAgICAgICB0aGlzLl9jb21iRmlsdGVycy5wdXNoKGxmcGYpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL2NoYWluIHRoZSBhbGxwYXNzIGZpbHRlcnMgdG9nZXRlaHJcblx0ICAgICAgICBUb25lLmNvbm5lY3RTZXJpZXMuYXBwbHkoVG9uZSwgdGhpcy5fYWxscGFzc0ZpbHRlcnNMKTtcblx0ICAgICAgICBUb25lLmNvbm5lY3RTZXJpZXMuYXBwbHkoVG9uZSwgdGhpcy5fYWxscGFzc0ZpbHRlcnNSKTtcblx0ICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc0xbdGhpcy5fYWxscGFzc0ZpbHRlcnNMLmxlbmd0aCAtIDFdLmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm5MKTtcblx0ICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc1JbdGhpcy5fYWxscGFzc0ZpbHRlcnNSLmxlbmd0aCAtIDFdLmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm5SKTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdyb29tU2l6ZScsXG5cdCAgICAgICAgICAgICdkYW1wZW5pbmcnXG5cdCAgICAgICAgXSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5GcmVldmVyYiwgVG9uZS5TdGVyZW9FZmZlY3QpO1xuXHQgICAgLyoqXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuRnJlZXZlcmIuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ3Jvb21TaXplJzogMC43LFxuXHQgICAgICAgICdkYW1wZW5pbmcnOiAzMDAwXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5GcmVldmVyYn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5GcmVldmVyYi5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlN0ZXJlb0VmZmVjdC5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIGZvciAodmFyIGFsID0gMDsgYWwgPCB0aGlzLl9hbGxwYXNzRmlsdGVyc0wubGVuZ3RoOyBhbCsrKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzTFthbF0uZGlzY29ubmVjdCgpO1xuXHQgICAgICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc0xbYWxdID0gbnVsbDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNMID0gbnVsbDtcblx0ICAgICAgICBmb3IgKHZhciBhciA9IDA7IGFyIDwgdGhpcy5fYWxscGFzc0ZpbHRlcnNSLmxlbmd0aDsgYXIrKykge1xuXHQgICAgICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc1JbYXJdLmRpc2Nvbm5lY3QoKTtcblx0ICAgICAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNSW2FyXSA9IG51bGw7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzUiA9IG51bGw7XG5cdCAgICAgICAgZm9yICh2YXIgY2YgPSAwOyBjZiA8IHRoaXMuX2NvbWJGaWx0ZXJzLmxlbmd0aDsgY2YrKykge1xuXHQgICAgICAgICAgICB0aGlzLl9jb21iRmlsdGVyc1tjZl0uZGlzcG9zZSgpO1xuXHQgICAgICAgICAgICB0aGlzLl9jb21iRmlsdGVyc1tjZl0gPSBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl9jb21iRmlsdGVycyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoW1xuXHQgICAgICAgICAgICAncm9vbVNpemUnLFxuXHQgICAgICAgICAgICAnZGFtcGVuaW5nJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMucm9vbVNpemUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMucm9vbVNpemUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZGFtcGVuaW5nLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmRhbXBlbmluZyA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuRnJlZXZlcmI7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIGFuIGFycmF5IG9mIHRoZSBjb21iIGZpbHRlciBkZWxheSB0aW1lIHZhbHVlc1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEB0eXBlIHtBcnJheX1cblx0XHQgKi9cblx0ICAgIHZhciBjb21iRmlsdGVyRGVsYXlUaW1lcyA9IFtcblx0ICAgICAgICAxNjg3IC8gMjUwMDAsXG5cdCAgICAgICAgMTYwMSAvIDI1MDAwLFxuXHQgICAgICAgIDIwNTMgLyAyNTAwMCxcblx0ICAgICAgICAyMjUxIC8gMjUwMDBcblx0ICAgIF07XG5cdCAgICAvKipcblx0XHQgKiAgdGhlIHJlc29uYW5jZXMgb2YgZWFjaCBvZiB0aGUgY29tYiBmaWx0ZXJzXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHR5cGUge0FycmF5fVxuXHRcdCAqL1xuXHQgICAgdmFyIGNvbWJGaWx0ZXJSZXNvbmFuY2VzID0gW1xuXHQgICAgICAgIDAuNzczLFxuXHQgICAgICAgIDAuODAyLFxuXHQgICAgICAgIDAuNzUzLFxuXHQgICAgICAgIDAuNzMzXG5cdCAgICBdO1xuXHQgICAgLyoqXG5cdFx0ICogIHRoZSBhbGxwYXNzIGZpbHRlciBmcmVxdWVuY2llc1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEB0eXBlIHtBcnJheX1cblx0XHQgKi9cblx0ICAgIHZhciBhbGxwYXNzRmlsdGVyRnJlcXMgPSBbXG5cdCAgICAgICAgMzQ3LFxuXHQgICAgICAgIDExMyxcblx0ICAgICAgICAzN1xuXHQgICAgXTtcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5KQ1JldmVyYiBpcyBhIHNpbXBsZSBbU2Nocm9lZGVyIFJldmVyYmVyYXRvcl0oaHR0cHM6Ly9jY3JtYS5zdGFuZm9yZC5lZHUvfmpvcy9wYXNwL1NjaHJvZWRlcl9SZXZlcmJlcmF0b3JzLmh0bWwpXG5cdFx0ICogICAgICAgICB0dW5lZCBieSBKb2huIENob3duaW5nIGluIDE5NzAuXG5cdFx0ICogICAgICAgICBJdCBpcyBtYWRlIHVwIG9mIHRocmVlIGFsbHBhc3MgZmlsdGVycyBhbmQgZm91ciBUb25lLkZlZWRiYWNrQ29tYkZpbHRlci5cblx0XHQgKlxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkVmZmVjdH1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBwYXJhbSB7Tm9ybWFsUmFuZ2V8T2JqZWN0fSBbcm9vbVNpemVdIENvb3JlbGF0ZXMgdG8gdGhlIGRlY2F5IHRpbWUuXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHJldmVyYiA9IG5ldyBUb25lLkpDUmV2ZXJiKDAuNCkuY29ubmVjdChUb25lLk1hc3Rlcik7XG5cdFx0ICogdmFyIGRlbGF5ID0gbmV3IFRvbmUuRmVlZGJhY2tEZWxheSgwLjUpO1xuXHRcdCAqIC8vY29ubmVjdGluZyB0aGUgc3ludGggdG8gcmV2ZXJiIHRocm91Z2ggZGVsYXlcblx0XHQgKiB2YXIgc3ludGggPSBuZXcgVG9uZS5EdW9TeW50aCgpLmNoYWluKGRlbGF5LCByZXZlcmIpO1xuXHRcdCAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQTRcIixcIjhuXCIpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5KQ1JldmVyYiA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbJ3Jvb21TaXplJ10sIFRvbmUuSkNSZXZlcmIpO1xuXHQgICAgICAgIFRvbmUuU3RlcmVvRWZmZWN0LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgcm9vbSBzaXplIGNvbnRyb2wgdmFsdWVzIGJldHdlZW4gWzAsMV1cblx0XHRcdCAqICBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5yb29tU2l6ZSA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLnJvb21TaXplLCBUb25lLlR5cGUuTm9ybWFsUmFuZ2UpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHNjYWxlIHRoZSByb29tIHNpemVcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5TY2FsZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc2NhbGVSb29tU2l6ZSA9IG5ldyBUb25lLlNjYWxlKC0wLjczMywgMC4xOTcpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGEgc2VyaWVzIG9mIGFsbHBhc3MgZmlsdGVyc1xuXHRcdFx0ICogIEB0eXBlIHtBcnJheX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnMgPSBbXTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBwYXJhbGxlbCBmZWVkYmFjayBjb21iIGZpbHRlcnNcblx0XHRcdCAqICBAdHlwZSB7QXJyYXl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ZlZWRiYWNrQ29tYkZpbHRlcnMgPSBbXTtcblx0ICAgICAgICAvL21ha2UgdGhlIGFsbHBhc3MgZmlsdGVyc1xuXHQgICAgICAgIGZvciAodmFyIGFmID0gMDsgYWYgPCBhbGxwYXNzRmlsdGVyRnJlcXMubGVuZ3RoOyBhZisrKSB7XG5cdCAgICAgICAgICAgIHZhciBhbGxwYXNzID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuXHQgICAgICAgICAgICBhbGxwYXNzLnR5cGUgPSAnYWxscGFzcyc7XG5cdCAgICAgICAgICAgIGFsbHBhc3MuZnJlcXVlbmN5LnZhbHVlID0gYWxscGFzc0ZpbHRlckZyZXFzW2FmXTtcblx0ICAgICAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnMucHVzaChhbGxwYXNzKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgLy9hbmQgdGhlIGNvbWIgZmlsdGVyc1xuXHQgICAgICAgIGZvciAodmFyIGNmID0gMDsgY2YgPCBjb21iRmlsdGVyRGVsYXlUaW1lcy5sZW5ndGg7IGNmKyspIHtcblx0ICAgICAgICAgICAgdmFyIGZiY2YgPSBuZXcgVG9uZS5GZWVkYmFja0NvbWJGaWx0ZXIoY29tYkZpbHRlckRlbGF5VGltZXNbY2ZdLCAwLjEpO1xuXHQgICAgICAgICAgICB0aGlzLl9zY2FsZVJvb21TaXplLmNvbm5lY3QoZmJjZi5yZXNvbmFuY2UpO1xuXHQgICAgICAgICAgICBmYmNmLnJlc29uYW5jZS52YWx1ZSA9IGNvbWJGaWx0ZXJSZXNvbmFuY2VzW2NmXTtcblx0ICAgICAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNbdGhpcy5fYWxscGFzc0ZpbHRlcnMubGVuZ3RoIC0gMV0uY29ubmVjdChmYmNmKTtcblx0ICAgICAgICAgICAgaWYgKGNmIDwgY29tYkZpbHRlckRlbGF5VGltZXMubGVuZ3RoIC8gMikge1xuXHQgICAgICAgICAgICAgICAgZmJjZi5jb25uZWN0KHRoaXMuZWZmZWN0UmV0dXJuTCk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBmYmNmLmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm5SKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aGlzLl9mZWVkYmFja0NvbWJGaWx0ZXJzLnB1c2goZmJjZik7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vY2hhaW4gdGhlIGFsbHBhc3MgZmlsdGVycyB0b2dldGhlclxuXHQgICAgICAgIHRoaXMucm9vbVNpemUuY29ubmVjdCh0aGlzLl9zY2FsZVJvb21TaXplKTtcblx0ICAgICAgICBUb25lLmNvbm5lY3RTZXJpZXMuYXBwbHkoVG9uZSwgdGhpcy5fYWxscGFzc0ZpbHRlcnMpO1xuXHQgICAgICAgIHRoaXMuZWZmZWN0U2VuZEwuY29ubmVjdCh0aGlzLl9hbGxwYXNzRmlsdGVyc1swXSk7XG5cdCAgICAgICAgdGhpcy5lZmZlY3RTZW5kUi5jb25uZWN0KHRoaXMuX2FsbHBhc3NGaWx0ZXJzWzBdKTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbJ3Jvb21TaXplJ10pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuSkNSZXZlcmIsIFRvbmUuU3RlcmVvRWZmZWN0KTtcblx0ICAgIC8qKlxuXHRcdCAqICB0aGUgZGVmYXVsdCB2YWx1ZXNcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuSkNSZXZlcmIuZGVmYXVsdHMgPSB7ICdyb29tU2l6ZSc6IDAuNSB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5KQ1JldmVyYn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5KQ1JldmVyYi5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlN0ZXJlb0VmZmVjdC5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIGZvciAodmFyIGFwZiA9IDA7IGFwZiA8IHRoaXMuX2FsbHBhc3NGaWx0ZXJzLmxlbmd0aDsgYXBmKyspIHtcblx0ICAgICAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNbYXBmXS5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzW2FwZl0gPSBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVycyA9IG51bGw7XG5cdCAgICAgICAgZm9yICh2YXIgZmJjZiA9IDA7IGZiY2YgPCB0aGlzLl9mZWVkYmFja0NvbWJGaWx0ZXJzLmxlbmd0aDsgZmJjZisrKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2ZlZWRiYWNrQ29tYkZpbHRlcnNbZmJjZl0uZGlzcG9zZSgpO1xuXHQgICAgICAgICAgICB0aGlzLl9mZWVkYmFja0NvbWJGaWx0ZXJzW2ZiY2ZdID0gbnVsbDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5fZmVlZGJhY2tDb21iRmlsdGVycyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoWydyb29tU2l6ZSddKTtcblx0ICAgICAgICB0aGlzLnJvb21TaXplLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLnJvb21TaXplID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9zY2FsZVJvb21TaXplLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9zY2FsZVJvb21TaXplID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5KQ1JldmVyYjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIE1pZC9TaWRlIHByb2Nlc3Npbmcgc2VwYXJhdGVzIHRoZSB0aGUgJ21pZCcgc2lnbmFsXG5cdFx0ICogICAgICAgICAod2hpY2ggY29tZXMgb3V0IG9mIGJvdGggdGhlIGxlZnQgYW5kIHRoZSByaWdodCBjaGFubmVsKVxuXHRcdCAqICAgICAgICAgYW5kIHRoZSAnc2lkZScgKHdoaWNoIG9ubHkgY29tZXMgb3V0IG9mIHRoZSB0aGUgc2lkZSBjaGFubmVscylcblx0XHQgKiAgICAgICAgIGFuZCBlZmZlY3RzIHRoZW0gc2VwYXJhdGVseSBiZWZvcmUgYmVpbmcgcmVjb21iaW5lZC5cblx0XHQgKiAgICAgICAgIEFwcGxpZXMgYSBNaWQvU2lkZSBzZXBlcmF0aW9uIGFuZCByZWNvbWJpbmF0aW9uLlxuXHRcdCAqICAgICAgICAgQWxnb3JpdGhtIGZvdW5kIGluIFtrdnJhdWRpbyBmb3J1bXNdKGh0dHA6Ly93d3cua3ZyYXVkaW8uY29tL2ZvcnVtL3ZpZXd0b3BpYy5waHA/dD0yMTI1ODcpLlxuXHRcdCAqICAgICAgICAgPGJyPjxicj5cblx0XHQgKiAgICAgICAgIFRoaXMgaXMgYSBiYXNlLWNsYXNzIGZvciBNaWQvU2lkZSBFZmZlY3RzLlxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkVmZmVjdH1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICovXG5cdCAgICBUb25lLk1pZFNpZGVFZmZlY3QgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5FZmZlY3QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbWlkL3NpZGUgc3BsaXRcblx0XHRcdCAqICBAdHlwZSAge1RvbmUuTWlkU2lkZVNwbGl0fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQgPSBuZXcgVG9uZS5NaWRTaWRlU3BsaXQoKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbWlkL3NpZGUgbWVyZ2Vcblx0XHRcdCAqICBAdHlwZSAge1RvbmUuTWlkU2lkZU1lcmdlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9taWRTaWRlTWVyZ2UgPSBuZXcgVG9uZS5NaWRTaWRlTWVyZ2UoKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbWlkIHNlbmQuIENvbm5lY3QgdG8gbWlkIHByb2Nlc3Npbmdcblx0XHRcdCAqICBAdHlwZSB7VG9uZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5taWRTZW5kID0gdGhpcy5fbWlkU2lkZVNwbGl0Lm1pZDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgc2lkZSBzZW5kLiBDb25uZWN0IHRvIHNpZGUgcHJvY2Vzc2luZ1xuXHRcdFx0ICogIEB0eXBlIHtUb25lfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnNpZGVTZW5kID0gdGhpcy5fbWlkU2lkZVNwbGl0LnNpZGU7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG1pZCByZXR1cm4gY29ubmVjdGlvblxuXHRcdFx0ICogIEB0eXBlIHtHYWluTm9kZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5taWRSZXR1cm4gPSB0aGlzLl9taWRTaWRlTWVyZ2UubWlkO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBzaWRlIHJldHVybiBjb25uZWN0aW9uXG5cdFx0XHQgKiAgQHR5cGUge0dhaW5Ob2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnNpZGVSZXR1cm4gPSB0aGlzLl9taWRTaWRlTWVyZ2Uuc2lkZTtcblx0ICAgICAgICAvL3RoZSBjb25uZWN0aW9uc1xuXHQgICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jb25uZWN0KHRoaXMuX21pZFNpZGVTcGxpdCk7XG5cdCAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlLmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm4pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuTWlkU2lkZUVmZmVjdCwgVG9uZS5FZmZlY3QpO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5NaWRTaWRlRWZmZWN0fSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk1pZFNpZGVFZmZlY3QucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5FZmZlY3QucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9taWRTaWRlTWVyZ2UgPSBudWxsO1xuXHQgICAgICAgIHRoaXMubWlkU2VuZCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5zaWRlU2VuZCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5taWRSZXR1cm4gPSBudWxsO1xuXHQgICAgICAgIHRoaXMuc2lkZVJldHVybiA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuTWlkU2lkZUVmZmVjdDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuUGhhc2VyIGlzIGEgcGhhc2VyIGVmZmVjdC4gUGhhc2VycyB3b3JrIGJ5IGNoYW5naW5nIHRoZSBwaGFzZVxuXHRcdCAqICAgICAgICAgb2YgZGlmZmVyZW50IGZyZXF1ZW5jeSBjb21wb25lbnRzIG9mIGFuIGluY29taW5nIHNpZ25hbC4gUmVhZCBtb3JlIG9uXG5cdFx0ICogICAgICAgICBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QaGFzZXJfKGVmZmVjdCkpLlxuXHRcdCAqICAgICAgICAgSW5zcGlyYXRpb24gZm9yIHRoaXMgcGhhc2VyIGNvbWVzIGZyb20gW1R1bmEuanNdKGh0dHBzOi8vZ2l0aHViLmNvbS9EaW5haG1vZS90dW5hLykuXG5cdFx0ICpcblx0XHQgKlx0QGV4dGVuZHMge1RvbmUuU3RlcmVvRWZmZWN0fVxuXHRcdCAqXHRAY29uc3RydWN0b3Jcblx0XHQgKlx0QHBhcmFtIHtGcmVxdWVuY3l8T2JqZWN0fSBbZnJlcXVlbmN5XSBUaGUgc3BlZWQgb2YgdGhlIHBoYXNpbmcuXG5cdFx0ICpcdEBwYXJhbSB7bnVtYmVyfSBbb2N0YXZlc10gVGhlIG9jdGF2ZXMgb2YgdGhlIGVmZmVjdC5cblx0XHQgKlx0QHBhcmFtIHtGcmVxdWVuY3l9IFtiYXNlRnJlcXVlbmN5XSBUaGUgYmFzZSBmcmVxdWVuY3kgb2YgdGhlIGZpbHRlcnMuXG5cdFx0ICpcdEBleGFtcGxlXG5cdFx0ICogdmFyIHBoYXNlciA9IG5ldyBUb25lLlBoYXNlcih7XG5cdFx0ICogXHRcImZyZXF1ZW5jeVwiIDogMTUsXG5cdFx0ICogXHRcIm9jdGF2ZXNcIiA6IDUsXG5cdFx0ICogXHRcImJhc2VGcmVxdWVuY3lcIiA6IDEwMDBcblx0XHQgKiB9KS50b01hc3RlcigpO1xuXHRcdCAqIHZhciBzeW50aCA9IG5ldyBUb25lLkZNU3ludGgoKS5jb25uZWN0KHBoYXNlcik7XG5cdFx0ICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJFM1wiLCBcIjJuXCIpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QaGFzZXIgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgLy9zZXQgdGhlIGRlZmF1bHRzXG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ29jdGF2ZXMnLFxuXHQgICAgICAgICAgICAnYmFzZUZyZXF1ZW5jeSdcblx0ICAgICAgICBdLCBUb25lLlBoYXNlcik7XG5cdCAgICAgICAgVG9uZS5TdGVyZW9FZmZlY3QuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbGZvIHdoaWNoIGNvbnRyb2xzIHRoZSBmcmVxdWVuY3kgb24gdGhlIGxlZnQgc2lkZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkxGT31cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbGZvTCA9IG5ldyBUb25lLkxGTyhvcHRpb25zLmZyZXF1ZW5jeSwgMCwgMSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGxmbyB3aGljaCBjb250cm9scyB0aGUgZnJlcXVlbmN5IG9uIHRoZSByaWdodCBzaWRlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuTEZPfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9sZm9SID0gbmV3IFRvbmUuTEZPKG9wdGlvbnMuZnJlcXVlbmN5LCAwLCAxKTtcblx0ICAgICAgICB0aGlzLl9sZm9SLnBoYXNlID0gMTgwO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBiYXNlIG1vZHVsYXRpb24gZnJlcXVlbmN5XG5cdFx0XHQgKiAgQHR5cGUge251bWJlcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IG9wdGlvbnMuYmFzZUZyZXF1ZW5jeTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgb2N0YXZlcyBvZiB0aGUgcGhhc2luZ1xuXHRcdFx0ICogIEB0eXBlIHtudW1iZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHF1YWxpdHkgZmFjdG9yIG9mIHRoZSBmaWx0ZXJzXG5cdFx0XHQgKiAgQHR5cGUge1Bvc2l0aXZlfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuUSA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLlEsIFRvbmUuVHlwZS5Qb3NpdGl2ZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGFycmF5IG9mIGZpbHRlcnMgZm9yIHRoZSBsZWZ0IHNpZGVcblx0XHRcdCAqICBAdHlwZSB7QXJyYXl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ZpbHRlcnNMID0gdGhpcy5fbWFrZUZpbHRlcnMob3B0aW9ucy5zdGFnZXMsIHRoaXMuX2xmb0wsIHRoaXMuUSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGFycmF5IG9mIGZpbHRlcnMgZm9yIHRoZSBsZWZ0IHNpZGVcblx0XHRcdCAqICBAdHlwZSB7QXJyYXl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ZpbHRlcnNSID0gdGhpcy5fbWFrZUZpbHRlcnMob3B0aW9ucy5zdGFnZXMsIHRoaXMuX2xmb1IsIHRoaXMuUSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiB0aGUgZnJlcXVlbmN5IG9mIHRoZSBlZmZlY3Rcblx0XHRcdCAqIEB0eXBlIHtUb25lLlNpZ25hbH1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fbGZvTC5mcmVxdWVuY3k7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kudmFsdWUgPSBvcHRpb25zLmZyZXF1ZW5jeTtcblx0ICAgICAgICAvL2Nvbm5lY3QgdGhlbSB1cFxuXHQgICAgICAgIHRoaXMuZWZmZWN0U2VuZEwuY29ubmVjdCh0aGlzLl9maWx0ZXJzTFswXSk7XG5cdCAgICAgICAgdGhpcy5lZmZlY3RTZW5kUi5jb25uZWN0KHRoaXMuX2ZpbHRlcnNSWzBdKTtcblx0ICAgICAgICB0aGlzLl9maWx0ZXJzTFtvcHRpb25zLnN0YWdlcyAtIDFdLmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm5MKTtcblx0ICAgICAgICB0aGlzLl9maWx0ZXJzUltvcHRpb25zLnN0YWdlcyAtIDFdLmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm5SKTtcblx0ICAgICAgICAvL2NvbnRyb2wgdGhlIGZyZXF1ZW5jeSB3aXRoIG9uZSBMRk9cblx0ICAgICAgICB0aGlzLl9sZm9MLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX2xmb1IuZnJlcXVlbmN5KTtcblx0ICAgICAgICAvL3NldCB0aGUgb3B0aW9uc1xuXHQgICAgICAgIHRoaXMuYmFzZUZyZXF1ZW5jeSA9IG9wdGlvbnMuYmFzZUZyZXF1ZW5jeTtcblx0ICAgICAgICB0aGlzLm9jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG5cdCAgICAgICAgLy9zdGFydCB0aGUgbGZvXG5cdCAgICAgICAgdGhpcy5fbGZvTC5zdGFydCgpO1xuXHQgICAgICAgIHRoaXMuX2xmb1Iuc3RhcnQoKTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnUSdcblx0ICAgICAgICBdKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlBoYXNlciwgVG9uZS5TdGVyZW9FZmZlY3QpO1xuXHQgICAgLyoqXG5cdFx0ICogIGRlZmF1bHRzXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHR5cGUge29iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuUGhhc2VyLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdmcmVxdWVuY3knOiAwLjUsXG5cdCAgICAgICAgJ29jdGF2ZXMnOiAzLFxuXHQgICAgICAgICdzdGFnZXMnOiAxMCxcblx0ICAgICAgICAnUSc6IDEwLFxuXHQgICAgICAgICdiYXNlRnJlcXVlbmN5JzogMzUwXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSBzdGFnZXNcblx0XHQgKiAgQHJldHVybnMge0FycmF5fSB0aGUgbnVtYmVyIG9mIGZpbHRlcnMgYWxsIGNvbm5lY3RlZCB0b2dldGhlclxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QaGFzZXIucHJvdG90eXBlLl9tYWtlRmlsdGVycyA9IGZ1bmN0aW9uIChzdGFnZXMsIGNvbm5lY3RUb0ZyZXEsIFEpIHtcblx0ICAgICAgICB2YXIgZmlsdGVycyA9IG5ldyBBcnJheShzdGFnZXMpO1xuXHQgICAgICAgIC8vbWFrZSBhbGwgdGhlIGZpbHRlcnNcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YWdlczsgaSsrKSB7XG5cdCAgICAgICAgICAgIHZhciBmaWx0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG5cdCAgICAgICAgICAgIGZpbHRlci50eXBlID0gJ2FsbHBhc3MnO1xuXHQgICAgICAgICAgICBRLmNvbm5lY3QoZmlsdGVyLlEpO1xuXHQgICAgICAgICAgICBjb25uZWN0VG9GcmVxLmNvbm5lY3QoZmlsdGVyLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgICAgIGZpbHRlcnNbaV0gPSBmaWx0ZXI7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIFRvbmUuY29ubmVjdFNlcmllcy5hcHBseShUb25lLCBmaWx0ZXJzKTtcblx0ICAgICAgICByZXR1cm4gZmlsdGVycztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgbnVtYmVyIG9mIG9jdGF2ZXMgdGhlIHBoYXNlIGdvZXMgYWJvdmVcblx0XHQgKiB0aGUgYmFzZUZyZXF1ZW5jeVxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlBoYXNlciNcblx0XHQgKiBAdHlwZSB7UG9zaXRpdmV9XG5cdFx0ICogQG5hbWUgb2N0YXZlc1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGhhc2VyLnByb3RvdHlwZSwgJ29jdGF2ZXMnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9vY3RhdmVzO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAob2N0YXZlcykge1xuXHQgICAgICAgICAgICB0aGlzLl9vY3RhdmVzID0gb2N0YXZlcztcblx0ICAgICAgICAgICAgdmFyIG1heCA9IHRoaXMuX2Jhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCBvY3RhdmVzKTtcblx0ICAgICAgICAgICAgdGhpcy5fbGZvTC5tYXggPSBtYXg7XG5cdCAgICAgICAgICAgIHRoaXMuX2xmb1IubWF4ID0gbWF4O1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHRoZSBiYXNlIGZyZXF1ZW5jeSBvZiB0aGUgZmlsdGVycy5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5QaGFzZXIjXG5cdFx0ICogQHR5cGUge251bWJlcn1cblx0XHQgKiBAbmFtZSBiYXNlRnJlcXVlbmN5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QaGFzZXIucHJvdG90eXBlLCAnYmFzZUZyZXF1ZW5jeScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChmcmVxKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2Jhc2VGcmVxdWVuY3kgPSBmcmVxO1xuXHQgICAgICAgICAgICB0aGlzLl9sZm9MLm1pbiA9IGZyZXE7XG5cdCAgICAgICAgICAgIHRoaXMuX2xmb1IubWluID0gZnJlcTtcblx0ICAgICAgICAgICAgdGhpcy5vY3RhdmVzID0gdGhpcy5fb2N0YXZlcztcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBjbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5QaGFzZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGhhc2VyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuU3RlcmVvRWZmZWN0LnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoW1xuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ1EnXG5cdCAgICAgICAgXSk7XG5cdCAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLlEgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2xmb0wuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2xmb0wgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2xmb1IuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2xmb1IgPSBudWxsO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fZmlsdGVyc0wubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgdGhpcy5fZmlsdGVyc0xbaV0uZGlzY29ubmVjdCgpO1xuXHQgICAgICAgICAgICB0aGlzLl9maWx0ZXJzTFtpXSA9IG51bGw7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuX2ZpbHRlcnNMID0gbnVsbDtcblx0ICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMuX2ZpbHRlcnNSLmxlbmd0aDsgaisrKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2ZpbHRlcnNSW2pdLmRpc2Nvbm5lY3QoKTtcblx0ICAgICAgICAgICAgdGhpcy5fZmlsdGVyc1Jbal0gPSBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl9maWx0ZXJzUiA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlBoYXNlcjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIEp1c3QgbGlrZSBhIHN0ZXJlbyBmZWVkYmFjayBlZmZlY3QsIGJ1dCB0aGUgZmVlZGJhY2sgaXMgcm91dGVkIGZyb20gbGVmdCB0byByaWdodFxuXHRcdCAqICAgICAgICAgYW5kIHJpZ2h0IHRvIGxlZnQgaW5zdGVhZCBvZiBvbiB0aGUgc2FtZSBjaGFubmVsLlxuXHRcdCAqXG5cdFx0ICpcdEBjb25zdHJ1Y3RvclxuXHRcdCAqXHRAZXh0ZW5kcyB7VG9uZS5TdGVyZW9FZmZlY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLlN0ZXJlb1hGZWVkYmFja0VmZmVjdCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbJ2ZlZWRiYWNrJ10sIFRvbmUuRmVlZGJhY2tFZmZlY3QpO1xuXHQgICAgICAgIFRvbmUuU3RlcmVvRWZmZWN0LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGFtb3VudCBvZiBmZWVkYmFjayBmcm9tIHRoZSBvdXRwdXRcblx0XHRcdCAqICBiYWNrIGludG8gdGhlIGlucHV0IG9mIHRoZSBlZmZlY3QgKHJvdXRlZFxuXHRcdFx0ICogIGFjcm9zcyBsZWZ0IGFuZCByaWdodCBjaGFubmVscykuXG5cdFx0XHQgKiAgQHR5cGUge05vcm1hbFJhbmdlfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZmVlZGJhY2sgPSBuZXcgVG9uZS5TaWduYWwob3B0aW9ucy5mZWVkYmFjaywgVG9uZS5UeXBlLk5vcm1hbFJhbmdlKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbGVmdCBzaWRlIGZlZWJhY2tcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5HYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9mZWVkYmFja0xSID0gbmV3IFRvbmUuR2FpbigpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSByaWdodCBzaWRlIGZlZWJhY2tcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5HYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9mZWVkYmFja1JMID0gbmV3IFRvbmUuR2FpbigpO1xuXHQgICAgICAgIC8vY29ubmVjdCBpdCB1cFxuXHQgICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuTC5jaGFpbih0aGlzLl9mZWVkYmFja0xSLCB0aGlzLmVmZmVjdFNlbmRSKTtcblx0ICAgICAgICB0aGlzLmVmZmVjdFJldHVyblIuY2hhaW4odGhpcy5fZmVlZGJhY2tSTCwgdGhpcy5lZmZlY3RTZW5kTCk7XG5cdCAgICAgICAgdGhpcy5mZWVkYmFjay5mYW4odGhpcy5fZmVlZGJhY2tMUi5nYWluLCB0aGlzLl9mZWVkYmFja1JMLmdhaW4pO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFsnZmVlZGJhY2snXSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5TdGVyZW9YRmVlZGJhY2tFZmZlY3QsIFRvbmUuU3RlcmVvRWZmZWN0KTtcblx0ICAgIC8qKlxuXHRcdCAqICBjbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5TdGVyZW9YRmVlZGJhY2tFZmZlY3R9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuU3RlcmVvWEZlZWRiYWNrRWZmZWN0LnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuU3RlcmVvRWZmZWN0LnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoWydmZWVkYmFjayddKTtcblx0ICAgICAgICB0aGlzLmZlZWRiYWNrLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmZlZWRiYWNrID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9mZWVkYmFja0xSLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9mZWVkYmFja0xSID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9mZWVkYmFja1JMLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9mZWVkYmFja1JMID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5TdGVyZW9YRmVlZGJhY2tFZmZlY3Q7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgVG9uZS5QaW5nUG9uZ0RlbGF5IGlzIGEgZmVlZGJhY2sgZGVsYXkgZWZmZWN0IHdoZXJlIHRoZSBlY2hvIGlzIGhlYXJkXG5cdFx0ICogICAgICAgICAgZmlyc3QgaW4gb25lIGNoYW5uZWwgYW5kIG5leHQgaW4gdGhlIG9wcG9zaXRlIGNoYW5uZWwuIEluIGEgc3RlcmVvXG5cdFx0ICogICAgICAgICAgc3lzdGVtIHRoZXNlIGFyZSB0aGUgcmlnaHQgYW5kIGxlZnQgY2hhbm5lbHMuXG5cdFx0ICogICAgICAgICAgUGluZ1BvbmdEZWxheSBpbiBtb3JlIHNpbXBsaWZpZWQgdGVybXMgaXMgdHdvIFRvbmUuRmVlZGJhY2tEZWxheXNcblx0XHQgKiAgICAgICAgICB3aXRoIGluZGVwZW5kZW50IGRlbGF5IHZhbHVlcy4gRWFjaCBkZWxheSBpcyByb3V0ZWQgdG8gb25lIGNoYW5uZWxcblx0XHQgKiAgICAgICAgICAobGVmdCBvciByaWdodCksIGFuZCB0aGUgY2hhbm5lbCB0cmlnZ2VyZWQgc2Vjb25kIHdpbGwgYWx3YXlzXG5cdFx0ICogICAgICAgICAgdHJpZ2dlciBhdCB0aGUgc2FtZSBpbnRlcnZhbCBhZnRlciB0aGUgZmlyc3QuXG5cdFx0ICpcblx0XHQgKiBcdEBjb25zdHJ1Y3RvclxuXHRcdCAqIFx0QGV4dGVuZHMge1RvbmUuU3RlcmVvWEZlZWRiYWNrRWZmZWN0fVxuXHRcdCAqICBAcGFyYW0ge1RpbWV8T2JqZWN0fSBbZGVsYXlUaW1lXSBUaGUgZGVsYXlUaW1lIGJldHdlZW4gY29uc2VjdXRpdmUgZWNob3MuXG5cdFx0ICogIEBwYXJhbSB7Tm9ybWFsUmFuZ2U9fSBmZWVkYmFjayBUaGUgYW1vdW50IG9mIHRoZSBlZmZlY3RlZCBzaWduYWwgd2hpY2hcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzIGZlZCBiYWNrIHRocm91Z2ggdGhlIGRlbGF5LlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBwaW5nUG9uZyA9IG5ldyBUb25lLlBpbmdQb25nRGVsYXkoXCI0blwiLCAwLjIpLnRvTWFzdGVyKCk7XG5cdFx0ICogdmFyIGRydW0gPSBuZXcgVG9uZS5EcnVtU3ludGgoKS5jb25uZWN0KHBpbmdQb25nKTtcblx0XHQgKiBkcnVtLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCIzMm5cIik7XG5cdFx0ICovXG5cdCAgICBUb25lLlBpbmdQb25nRGVsYXkgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAnZGVsYXlUaW1lJyxcblx0ICAgICAgICAgICAgJ2ZlZWRiYWNrJ1xuXHQgICAgICAgIF0sIFRvbmUuUGluZ1BvbmdEZWxheSk7XG5cdCAgICAgICAgVG9uZS5TdGVyZW9YRmVlZGJhY2tFZmZlY3QuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgZGVsYXkgbm9kZSBvbiB0aGUgbGVmdCBzaWRlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuRGVsYXl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2xlZnREZWxheSA9IG5ldyBUb25lLkRlbGF5KDAsIG9wdGlvbnMubWF4RGVsYXlUaW1lKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgZGVsYXkgbm9kZSBvbiB0aGUgcmlnaHQgc2lkZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkRlbGF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9yaWdodERlbGF5ID0gbmV3IFRvbmUuRGVsYXkoMCwgb3B0aW9ucy5tYXhEZWxheVRpbWUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBwcmVkZWxheSBvbiB0aGUgcmlnaHQgc2lkZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkRlbGF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9yaWdodFByZURlbGF5ID0gbmV3IFRvbmUuRGVsYXkoMCwgb3B0aW9ucy5tYXhEZWxheVRpbWUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBkZWxheSB0aW1lIHNpZ25hbFxuXHRcdFx0ICogIEB0eXBlIHtUaW1lfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZGVsYXlUaW1lID0gbmV3IFRvbmUuU2lnbmFsKG9wdGlvbnMuZGVsYXlUaW1lLCBUb25lLlR5cGUuVGltZSk7XG5cdCAgICAgICAgLy9jb25uZWN0IGl0IHVwXG5cdCAgICAgICAgdGhpcy5lZmZlY3RTZW5kTC5jaGFpbih0aGlzLl9sZWZ0RGVsYXksIHRoaXMuZWZmZWN0UmV0dXJuTCk7XG5cdCAgICAgICAgdGhpcy5lZmZlY3RTZW5kUi5jaGFpbih0aGlzLl9yaWdodFByZURlbGF5LCB0aGlzLl9yaWdodERlbGF5LCB0aGlzLmVmZmVjdFJldHVyblIpO1xuXHQgICAgICAgIHRoaXMuZGVsYXlUaW1lLmZhbih0aGlzLl9sZWZ0RGVsYXkuZGVsYXlUaW1lLCB0aGlzLl9yaWdodERlbGF5LmRlbGF5VGltZSwgdGhpcy5fcmlnaHRQcmVEZWxheS5kZWxheVRpbWUpO1xuXHQgICAgICAgIC8vcmVhcnJhbmdlZCB0aGUgZmVlZGJhY2sgdG8gYmUgYWZ0ZXIgdGhlIHJpZ2h0UHJlRGVsYXlcblx0ICAgICAgICB0aGlzLl9mZWVkYmFja0xSLmRpc2Nvbm5lY3QoKTtcblx0ICAgICAgICB0aGlzLl9mZWVkYmFja0xSLmNvbm5lY3QodGhpcy5fcmlnaHREZWxheSk7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoWydkZWxheVRpbWUnXSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5QaW5nUG9uZ0RlbGF5LCBUb25lLlN0ZXJlb1hGZWVkYmFja0VmZmVjdCk7XG5cdCAgICAvKipcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QaW5nUG9uZ0RlbGF5LmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdkZWxheVRpbWUnOiAwLjI1LFxuXHQgICAgICAgICdtYXhEZWxheVRpbWUnOiAxXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5QaW5nUG9uZ0RlbGF5fSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlBpbmdQb25nRGVsYXkucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TdGVyZW9YRmVlZGJhY2tFZmZlY3QucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9sZWZ0RGVsYXkuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2xlZnREZWxheSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fcmlnaHREZWxheS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fcmlnaHREZWxheSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fcmlnaHRQcmVEZWxheS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fcmlnaHRQcmVEZWxheSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoWydkZWxheVRpbWUnXSk7XG5cdCAgICAgICAgdGhpcy5kZWxheVRpbWUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZGVsYXlUaW1lID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5QaW5nUG9uZ0RlbGF5O1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5QaXRjaFNoaWZ0IGRvZXMgbmVhci1yZWFsdGltZSBwaXRjaCBzaGlmdGluZyB0byB0aGUgaW5jb21pbmcgc2lnbmFsLlxuXHRcdCAqICAgICAgICAgVGhlIGVmZmVjdCBpcyBhY2hpZXZlZCBieSBzcGVlZGluZyB1cCBvciBzbG93aW5nIGRvd24gdGhlIGRlbGF5VGltZVxuXHRcdCAqICAgICAgICAgb2YgYSBEZWxheU5vZGUgdXNpbmcgYSBzYXd0b290aCB3YXZlLlxuXHRcdCAqICAgICAgICAgQWxnb3JpdGhtIGZvdW5kIGluIFt0aGlzIHBkZl0oaHR0cDovL2RzcC1ib29rLm5hcm9kLnJ1L3NvdW5kcHJvYy5wZGYpLlxuXHRcdCAqICAgICAgICAgQWRkaXRpb25hbCByZWZlcmVuY2UgYnkgW01pbGxlciBQdWNrZXRdKGh0dHA6Ly9tc3AudWNzZC5lZHUvdGVjaG5pcXVlcy92MC4xMS9ib29rLWh0bWwvbm9kZTExNS5odG1sKS5cblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5GZWVkYmFja0VmZmVjdH1cblx0XHQgKiAgQHBhcmFtIHtJbnRlcnZhbD19IHBpdGNoIFRoZSBpbnRlcnZhbCB0byB0cmFuc3Bvc2UgdGhlIGluY29taW5nIHNpZ25hbCBieS5cblx0XHQgKi9cblx0ICAgIFRvbmUuUGl0Y2hTaGlmdCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbJ3BpdGNoJ10sIFRvbmUuUGl0Y2hTaGlmdCk7XG5cdCAgICAgICAgVG9uZS5GZWVkYmFja0VmZmVjdC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBwaXRjaCBzaWduYWxcblx0XHRcdCAqICBAdHlwZSAge1RvbmUuU2lnbmFsfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBuZXcgVG9uZS5TaWduYWwoMCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVXNlcyB0d28gRGVsYXlOb2RlcyB0byBjb3ZlciB1cCB0aGUganVtcCBpblxuXHRcdFx0ICogIHRoZSBzYXd0b290aCB3YXZlLlxuXHRcdFx0ICogIEB0eXBlICB7RGVsYXlOb2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9kZWxheUEgPSBuZXcgVG9uZS5EZWxheSgwLCAxKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZmlyc3QgTEZPLlxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5MRk99XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2xmb0EgPSBuZXcgVG9uZS5MRk8oe1xuXHQgICAgICAgICAgICAnbWluJzogMCxcblx0ICAgICAgICAgICAgJ21heCc6IDAuMSxcblx0ICAgICAgICAgICAgJ3R5cGUnOiAnc2F3dG9vdGgnXG5cdCAgICAgICAgfSkuY29ubmVjdCh0aGlzLl9kZWxheUEuZGVsYXlUaW1lKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgc2Vjb25kIERlbGF5Tm9kZVxuXHRcdFx0ICogIEB0eXBlICB7RGVsYXlOb2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9kZWxheUIgPSBuZXcgVG9uZS5EZWxheSgwLCAxKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZmlyc3QgTEZPLlxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5MRk99XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2xmb0IgPSBuZXcgVG9uZS5MRk8oe1xuXHQgICAgICAgICAgICAnbWluJzogMCxcblx0ICAgICAgICAgICAgJ21heCc6IDAuMSxcblx0ICAgICAgICAgICAgJ3R5cGUnOiAnc2F3dG9vdGgnLFxuXHQgICAgICAgICAgICAncGhhc2UnOiAxODBcblx0ICAgICAgICB9KS5jb25uZWN0KHRoaXMuX2RlbGF5Qi5kZWxheVRpbWUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIENyb3NzZmFkZSBxdWlja2x5IGJldHdlZW4gdGhlIHR3byBkZWxheSBsaW5lc1xuXHRcdFx0ICogIHRvIGNvdmVyIHVwIHRoZSBqdW1wIGluIHRoZSBzYXd0b290aCB3YXZlXG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLkNyb3NzRmFkZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fY3Jvc3NGYWRlID0gbmV3IFRvbmUuQ3Jvc3NGYWRlKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgTEZPIHdoaWNoIGFsdGVybmF0ZXMgYmV0d2VlbiB0aGUgdHdvXG5cdFx0XHQgKiAgZGVsYXkgbGluZXMgdG8gY292ZXIgdXAgdGhlIGRpc3Bhcml0eSBpbiB0aGVcblx0XHRcdCAqICBzYXd0b290aCB3YXZlLlxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5MRk99XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2Nyb3NzRmFkZUxGTyA9IG5ldyBUb25lLkxGTyh7XG5cdCAgICAgICAgICAgICdtaW4nOiAwLFxuXHQgICAgICAgICAgICAnbWF4JzogMSxcblx0ICAgICAgICAgICAgJ3R5cGUnOiAndHJpYW5nbGUnLFxuXHQgICAgICAgICAgICAncGhhc2UnOiA5MFxuXHQgICAgICAgIH0pLmNvbm5lY3QodGhpcy5fY3Jvc3NGYWRlLmZhZGUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBkZWxheSBub2RlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuRGVsYXl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ZlZWRiYWNrRGVsYXkgPSBuZXcgVG9uZS5EZWxheShvcHRpb25zLmRlbGF5VGltZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGFtb3VudCBvZiBkZWxheSBvbiB0aGUgaW5wdXQgc2lnbmFsXG5cdFx0XHQgKiAgQHR5cGUge1RpbWV9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZWxheVRpbWUgPSB0aGlzLl9mZWVkYmFja0RlbGF5LmRlbGF5VGltZTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seSgnZGVsYXlUaW1lJyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgSG9sZCB0aGUgY3VycmVudCBwaXRjaFxuXHRcdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3BpdGNoID0gb3B0aW9ucy5waXRjaDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBIb2xkIHRoZSBjdXJyZW50IHdpbmRvd1NpemVcblx0XHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl93aW5kb3dTaXplID0gb3B0aW9ucy53aW5kb3dTaXplO1xuXHQgICAgICAgIC8vY29ubmVjdCB0aGUgdHdvIGRlbGF5IGxpbmVzIHVwXG5cdCAgICAgICAgdGhpcy5fZGVsYXlBLmNvbm5lY3QodGhpcy5fY3Jvc3NGYWRlLmEpO1xuXHQgICAgICAgIHRoaXMuX2RlbGF5Qi5jb25uZWN0KHRoaXMuX2Nyb3NzRmFkZS5iKTtcblx0ICAgICAgICAvL2Nvbm5lY3QgdGhlIGZyZXF1ZW5jeVxuXHQgICAgICAgIHRoaXMuX2ZyZXF1ZW5jeS5mYW4odGhpcy5fbGZvQS5mcmVxdWVuY3ksIHRoaXMuX2xmb0IuZnJlcXVlbmN5LCB0aGlzLl9jcm9zc0ZhZGVMRk8uZnJlcXVlbmN5KTtcblx0ICAgICAgICAvL3JvdXRlIHRoZSBpbnB1dFxuXHQgICAgICAgIHRoaXMuZWZmZWN0U2VuZC5mYW4odGhpcy5fZGVsYXlBLCB0aGlzLl9kZWxheUIpO1xuXHQgICAgICAgIHRoaXMuX2Nyb3NzRmFkZS5jaGFpbih0aGlzLl9mZWVkYmFja0RlbGF5LCB0aGlzLmVmZmVjdFJldHVybik7XG5cdCAgICAgICAgLy9zdGFydCB0aGUgTEZPcyBhdCB0aGUgc2FtZSB0aW1lXG5cdCAgICAgICAgdmFyIG5vdyA9IHRoaXMubm93KCk7XG5cdCAgICAgICAgdGhpcy5fbGZvQS5zdGFydChub3cpO1xuXHQgICAgICAgIHRoaXMuX2xmb0Iuc3RhcnQobm93KTtcblx0ICAgICAgICB0aGlzLl9jcm9zc0ZhZGVMRk8uc3RhcnQobm93KTtcblx0ICAgICAgICAvL3NldCB0aGUgaW5pdGlhbCB2YWx1ZVxuXHQgICAgICAgIHRoaXMud2luZG93U2l6ZSA9IHRoaXMuX3dpbmRvd1NpemU7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5QaXRjaFNoaWZ0LCBUb25lLkZlZWRiYWNrRWZmZWN0KTtcblx0ICAgIC8qKlxuXHRcdCAqICBkZWZhdWx0IHZhbHVlc1xuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICogIEBjb25zdFxuXHRcdCAqL1xuXHQgICAgVG9uZS5QaXRjaFNoaWZ0LmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdwaXRjaCc6IDAsXG5cdCAgICAgICAgJ3dpbmRvd1NpemUnOiAwLjEsXG5cdCAgICAgICAgJ2RlbGF5VGltZSc6IDAsXG5cdCAgICAgICAgJ2ZlZWRiYWNrJzogMFxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFJlcGl0Y2ggdGhlIGluY29taW5nIHNpZ25hbCBieSBzb21lIGludGVydmFsIChtZWFzdXJlZFxuXHRcdCAqIGluIHNlbWktdG9uZXMpLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlBpdGNoU2hpZnQjXG5cdFx0ICogQHR5cGUge0ludGVydmFsfVxuXHRcdCAqIEBuYW1lIHBpdGNoXG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiBwaXRjaFNoaWZ0LnBpdGNoID0gLTEyOyAvL2Rvd24gb25lIG9jdGF2ZVxuXHRcdCAqIHBpdGNoU2hpZnQucGl0Y2ggPSA3OyAvL3VwIGEgZmlmdGhcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBpdGNoU2hpZnQucHJvdG90eXBlLCAncGl0Y2gnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9waXRjaDtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGludGVydmFsKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3BpdGNoID0gaW50ZXJ2YWw7XG5cdCAgICAgICAgICAgIHZhciBmYWN0b3IgPSAwO1xuXHQgICAgICAgICAgICBpZiAoaW50ZXJ2YWwgPCAwKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9sZm9BLm1pbiA9IDA7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9sZm9BLm1heCA9IHRoaXMuX3dpbmRvd1NpemU7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9sZm9CLm1pbiA9IDA7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9sZm9CLm1heCA9IHRoaXMuX3dpbmRvd1NpemU7XG5cdCAgICAgICAgICAgICAgICBmYWN0b3IgPSBUb25lLmludGVydmFsVG9GcmVxdWVuY3lSYXRpbyhpbnRlcnZhbCAtIDEpICsgMTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2xmb0EubWluID0gdGhpcy5fd2luZG93U2l6ZTtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2xmb0EubWF4ID0gMDtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2xmb0IubWluID0gdGhpcy5fd2luZG93U2l6ZTtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2xmb0IubWF4ID0gMDtcblx0ICAgICAgICAgICAgICAgIGZhY3RvciA9IFRvbmUuaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGludGVydmFsKSAtIDE7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5fZnJlcXVlbmN5LnZhbHVlID0gZmFjdG9yICogKDEuMiAvIHRoaXMuX3dpbmRvd1NpemUpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHdpbmRvdyBzaXplIGNvcnJlc3BvbmRzIHJvdWdobHkgdG8gdGhlIHNhbXBsZSBsZW5ndGggaW4gYSBsb29waW5nIHNhbXBsZXIuXG5cdFx0ICogU21hbGxlciB2YWx1ZXMgYXJlIGRlc2lyYWJsZSBmb3IgYSBsZXNzIG5vdGljZWFibGUgZGVsYXkgdGltZSBvZiB0aGUgcGl0Y2ggc2hpZnRlZFxuXHRcdCAqIHNpZ25hbCwgYnV0IGxhcmdlciB2YWx1ZXMgd2lsbCByZXN1bHQgaW4gc21vb3RoZXIgcGl0Y2ggc2hpZnRpbmcgZm9yIGxhcmdlciBpbnRlcnZhbHMuXG5cdFx0ICogQSBub21pbmFsIHJhbmdlIG9mIDAuMDMgdG8gMC4xIGlzIHJlY29tbWVuZGVkLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlBpdGNoU2hpZnQjXG5cdFx0ICogQHR5cGUge1RpbWV9XG5cdFx0ICogQG5hbWUgd2luZG93U2l6ZVxuXHRcdCAqIEBleGFtcGxlXG5cdFx0ICogcGl0Y2hTaGlmdC53aW5kb3dTaXplID0gMC4xO1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGl0Y2hTaGlmdC5wcm90b3R5cGUsICd3aW5kb3dTaXplJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fd2luZG93U2l6ZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHNpemUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fd2luZG93U2l6ZSA9IHRoaXMudG9TZWNvbmRzKHNpemUpO1xuXHQgICAgICAgICAgICB0aGlzLnBpdGNoID0gdGhpcy5fcGl0Y2g7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLlBpdGNoU2hpZnR9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlBpdGNoU2hpZnQucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5GZWVkYmFja0VmZmVjdC5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX2ZyZXF1ZW5jeS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fZnJlcXVlbmN5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9kZWxheUEuZGlzY29ubmVjdCgpO1xuXHQgICAgICAgIHRoaXMuX2RlbGF5QSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fZGVsYXlCLmRpc2Nvbm5lY3QoKTtcblx0ICAgICAgICB0aGlzLl9kZWxheUIgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2xmb0EuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2xmb0EgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2xmb0IuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2xmb0IgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2Nyb3NzRmFkZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fY3Jvc3NGYWRlID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9jcm9zc0ZhZGVMRk8uZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2Nyb3NzRmFkZUxGTyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoJ2RlbGF5VGltZScpO1xuXHQgICAgICAgIHRoaXMuX2ZlZWRiYWNrRGVsYXkuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2ZlZWRiYWNrRGVsYXkgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZGVsYXlUaW1lID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5QaXRjaFNoaWZ0O1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgQnVmZmVyU291cmNlTm9kZS5cblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuQXVkaW9Ob2RlfVxuXHRcdCAqICBAcGFyYW0gIHtBdWRpb0J1ZmZlcnxUb25lLkJ1ZmZlcn0gIGJ1ZmZlciAgIFRoZSBidWZmZXIgdG8gcGxheVxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbn0gIG9ubG9hZCAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciBpcyBkb25lIHBsYXlpbmcuXG5cdFx0ICovXG5cdCAgICBUb25lLkJ1ZmZlclNvdXJjZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdidWZmZXInLFxuXHQgICAgICAgICAgICAnb25sb2FkJ1xuXHQgICAgICAgIF0sIFRvbmUuQnVmZmVyU291cmNlKTtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBjYWxsYmFjayB0byBpbnZva2UgYWZ0ZXIgdGhlXG5cdFx0XHQgKiAgYnVmZmVyIHNvdXJjZSBpcyBkb25lIHBsYXlpbmcuXG5cdFx0XHQgKiAgQHR5cGUgIHtGdW5jdGlvbn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMub25lbmRlZCA9IG9wdGlvbnMub25lbmRlZDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgdGltZSB0aGF0IHRoZSBidWZmZXIgd2FzIHN0YXJ0ZWQuXG5cdFx0XHQgKiAgQHR5cGUgIHtOdW1iZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3N0YXJ0VGltZSA9IC0xO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEFuIGFkZGl0aW9uYWwgZmxhZyBpZiB0aGUgYWN0dWFsIEJ1ZmZlclNvdXJjZU5vZGVcblx0XHRcdCAqICBoYXMgYmVlbiBzdGFydGVkLiBiL2Mgc3RvcHBpbmcgYW4gdW5zdGFydGVkIGJ1ZmZlclxuXHRcdFx0ICogIHdpbGwgdGhyb3cgaXQgaW50byBhbiBpbnZhbGlkIHN0YXRlXG5cdFx0XHQgKiAgQHR5cGUgIHtCb29sZWFufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9zb3VyY2VTdGFydGVkID0gZmFsc2U7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgRmxhZyBpZiB0aGUgc291cmNlIGhhcyBhbHJlYWR5IGJlZW4gc3RvcHBlZFxuXHRcdFx0ICogIEB0eXBlICB7Qm9vbGVhbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc291cmNlU3RvcHBlZCA9IGZhbHNlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSB0aW1lIHRoYXQgdGhlIGJ1ZmZlciBpcyBzY2hlZHVsZWQgdG8gc3RvcC5cblx0XHRcdCAqICBAdHlwZSAge051bWJlcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3RvcFRpbWUgPSAtMTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZ2FpbiBub2RlIHdoaWNoIGVudmVsb3BlcyB0aGUgQnVmZmVyU291cmNlXG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLkdhaW59XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2dhaW5Ob2RlID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZS5HYWluKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGJ1ZmZlciBzb3VyY2Vcblx0XHRcdCAqICBAdHlwZSAge0F1ZGlvQnVmZmVyU291cmNlTm9kZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc291cmNlID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuXHQgICAgICAgIHRoaXMuX3NvdXJjZS5jb25uZWN0KHRoaXMuX2dhaW5Ob2RlKTtcblx0ICAgICAgICB0aGlzLl9zb3VyY2Uub25lbmRlZCA9IHRoaXMuX29uZW5kZWQuYmluZCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBwcml2YXRlIGJ1ZmZlciBpbnN0YW5jZVxuXHRcdFx0ICogQHR5cGUge1RvbmUuQnVmZmVyfVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2J1ZmZlciA9IG5ldyBUb25lLkJ1ZmZlcihvcHRpb25zLmJ1ZmZlciwgb3B0aW9ucy5vbmxvYWQpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBwbGF5YmFja1JhdGUgb2YgdGhlIGJ1ZmZlclxuXHRcdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZSA9IG5ldyBUb25lLlBhcmFtKHRoaXMuX3NvdXJjZS5wbGF5YmFja1JhdGUsIFRvbmUuVHlwZS5Qb3NpdGl2ZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGZhZGVJbiB0aW1lIG9mIHRoZSBhbXBsaXR1ZGUgZW52ZWxvcGUuXG5cdFx0XHQgKiAgQHR5cGUge1RpbWV9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmZhZGVJbiA9IG9wdGlvbnMuZmFkZUluO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBmYWRlT3V0IHRpbWUgb2YgdGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cblx0XHRcdCAqICBAdHlwZSB7VGltZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZmFkZU91dCA9IG9wdGlvbnMuZmFkZU91dDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBjdXJ2ZSBhcHBsaWVkIHRvIHRoZSBmYWRlcywgZWl0aGVyIFwibGluZWFyXCIgb3IgXCJleHBvbmVudGlhbFwiXG5cdFx0XHQgKiBAdHlwZSB7U3RyaW5nfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5jdXJ2ZSA9IG9wdGlvbnMuY3VydmU7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHZhbHVlIHRoYXQgdGhlIGJ1ZmZlciByYW1wcyB0b1xuXHRcdFx0ICogIEB0eXBlIHtHYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9nYWluID0gMTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBvbmVuZGVkIHRpbWVvdXRcblx0XHRcdCAqIEB0eXBlIHtOdW1iZXJ9XG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fb25lbmRlZFRpbWVvdXQgPSAtMTtcblx0ICAgICAgICAvL3NldCBzb21lIHZhbHVlcyBpbml0aWFsbHlcblx0ICAgICAgICB0aGlzLmxvb3AgPSBvcHRpb25zLmxvb3A7XG5cdCAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBvcHRpb25zLmxvb3BTdGFydDtcblx0ICAgICAgICB0aGlzLmxvb3BFbmQgPSBvcHRpb25zLmxvb3BFbmQ7XG5cdCAgICAgICAgdGhpcy5wbGF5YmFja1JhdGUudmFsdWUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkJ1ZmZlclNvdXJjZSwgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0c1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkJ1ZmZlclNvdXJjZS5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnb25lbmRlZCc6IFRvbmUubm9PcCxcblx0ICAgICAgICAnb25sb2FkJzogVG9uZS5ub09wLFxuXHQgICAgICAgICdsb29wJzogZmFsc2UsXG5cdCAgICAgICAgJ2xvb3BTdGFydCc6IDAsXG5cdCAgICAgICAgJ2xvb3BFbmQnOiAwLFxuXHQgICAgICAgICdmYWRlSW4nOiAwLFxuXHQgICAgICAgICdmYWRlT3V0JzogMCxcblx0ICAgICAgICAnY3VydmUnOiAnbGluZWFyJyxcblx0ICAgICAgICAncGxheWJhY2tSYXRlJzogMVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIgb3IgXCJzdG9wcGVkXCIuXG5cdFx0ICogIEB0eXBlIHtUb25lLlN0YXRlfVxuXHRcdCAqICBAcmVhZE9ubHlcblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuQnVmZmVyU291cmNlI1xuXHRcdCAqICBAbmFtZSBzdGF0ZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQnVmZmVyU291cmNlLnByb3RvdHlwZSwgJ3N0YXRlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRTdGF0ZUF0VGltZSh0aGlzLm5vdygpKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBHZXQgdGhlIHBsYXliYWNrIHN0YXRlIGF0IHRoZSBnaXZlbiB0aW1lXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9ICB0aW1lICBUaGUgdGltZSB0byB0ZXN0IHRoZSBzdGF0ZSBhdFxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5TdGF0ZX0gIFRoZSBwbGF5YmFjayBzdGF0ZS4gXG5cdFx0ICovXG5cdCAgICBUb25lLkJ1ZmZlclNvdXJjZS5wcm90b3R5cGUuZ2V0U3RhdGVBdFRpbWUgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICBpZiAodGhpcy5fc3RhcnRUaW1lICE9PSAtMSAmJiB0aW1lID49IHRoaXMuX3N0YXJ0VGltZSAmJiAhdGhpcy5fc291cmNlU3RvcHBlZCkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5TdGF0ZS5TdGFydGVkO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHJldHVybiBUb25lLlN0YXRlLlN0b3BwZWQ7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTdGFydCB0aGUgYnVmZmVyXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IFtzdGFydFRpbWU9bm93XSBXaGVuIHRoZSBwbGF5ZXIgc2hvdWxkIHN0YXJ0LlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbb2Zmc2V0PTBdIFRoZSBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzYW1wbGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIHN0YXJ0IGF0LlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lPX0gZHVyYXRpb24gSG93IGxvbmcgdGhlIHNhbXBsZSBzaG91bGQgcGxheS4gSWYgbm8gZHVyYXRpb25cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgZ2l2ZW4sIGl0IHdpbGwgZGVmYXVsdCB0byB0aGUgZnVsbCBsZW5ndGhcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2YgdGhlIHNhbXBsZSAobWludXMgYW55IG9mZnNldClcblx0XHQgKiAgQHBhcmFtICB7R2Fpbn0gIFtnYWluPTFdICBUaGUgZ2FpbiB0byBwbGF5IHRoZSBidWZmZXIgYmFjayBhdC5cblx0XHQgKiAgQHBhcmFtICB7VGltZT19ICBmYWRlSW5UaW1lICBUaGUgb3B0aW9uYWwgZmFkZUluIHJhbXAgdGltZS5cblx0XHQgKiAgQHJldHVybiAge1RvbmUuQnVmZmVyU291cmNlfSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5CdWZmZXJTb3VyY2UucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24gKHRpbWUsIG9mZnNldCwgZHVyYXRpb24sIGdhaW4sIGZhZGVJblRpbWUpIHtcblx0ICAgICAgICBpZiAodGhpcy5fc3RhcnRUaW1lICE9PSAtMSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RvbmUuQnVmZmVyU291cmNlIGNhbiBvbmx5IGJlIHN0YXJ0ZWQgb25jZS4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKCF0aGlzLmJ1ZmZlci5sb2FkZWQpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUb25lLkJ1ZmZlclNvdXJjZTogYnVmZmVyIGlzIGVpdGhlciBub3Qgc2V0IG9yIG5vdCBsb2FkZWQuJyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICAvL2lmIGl0J3MgYSBsb29wIHRoZSBkZWZhdWx0IG9mZnNldCBpcyB0aGUgbG9vcHN0YXJ0IHBvaW50XG5cdCAgICAgICAgaWYgKHRoaXMubG9vcCkge1xuXHQgICAgICAgICAgICBvZmZzZXQgPSBUb25lLmRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLmxvb3BTdGFydCk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgLy9vdGhlcndpc2UgdGhlIGRlZmF1bHQgb2Zmc2V0IGlzIDBcblx0ICAgICAgICAgICAgb2Zmc2V0ID0gVG9uZS5kZWZhdWx0QXJnKG9mZnNldCwgMCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIG9mZnNldCA9IHRoaXMudG9TZWNvbmRzKG9mZnNldCk7XG5cdCAgICAgICAgZ2FpbiA9IFRvbmUuZGVmYXVsdEFyZyhnYWluLCAxKTtcblx0ICAgICAgICB0aGlzLl9nYWluID0gZ2Fpbjtcblx0ICAgICAgICBmYWRlSW5UaW1lID0gdGhpcy50b1NlY29uZHMoVG9uZS5kZWZhdWx0QXJnKGZhZGVJblRpbWUsIHRoaXMuZmFkZUluKSk7XG5cdCAgICAgICAgdGhpcy5mYWRlSW4gPSBmYWRlSW5UaW1lO1xuXHQgICAgICAgIGlmIChmYWRlSW5UaW1lID4gMCkge1xuXHQgICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuXHQgICAgICAgICAgICBpZiAodGhpcy5jdXJ2ZSA9PT0gJ2xpbmVhcicpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5fZ2FpbiwgdGltZSArIGZhZGVJblRpbWUpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5leHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUodGhpcy5fZ2FpbiwgdGltZSwgZmFkZUluVGltZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKGdhaW4sIHRpbWUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl9zdGFydFRpbWUgPSB0aW1lO1xuXHQgICAgICAgIHZhciBjb21wdXRlZER1ciA9IHRoaXMudG9TZWNvbmRzKFRvbmUuZGVmYXVsdEFyZyhkdXJhdGlvbiwgdGhpcy5idWZmZXIuZHVyYXRpb24gLSBvZmZzZXQgJSB0aGlzLmJ1ZmZlci5kdXJhdGlvbikpO1xuXHQgICAgICAgIGNvbXB1dGVkRHVyID0gTWF0aC5tYXgoY29tcHV0ZWREdXIsIDApO1xuXHQgICAgICAgIGlmIChUb25lLmlzRGVmaW5lZChkdXJhdGlvbikpIHtcblx0ICAgICAgICAgICAgLy9jbGlwIHRoZSBkdXJhdGlvbiB3aGVuIG5vdCBsb29waW5nXG5cdCAgICAgICAgICAgIGlmICghdGhpcy5sb29wKSB7XG5cdCAgICAgICAgICAgICAgICBjb21wdXRlZER1ciA9IE1hdGgubWluKGNvbXB1dGVkRHVyLCB0aGlzLmJ1ZmZlci5kdXJhdGlvbiAtIG9mZnNldCAlIHRoaXMuYnVmZmVyLmR1cmF0aW9uKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aGlzLnN0b3AodGltZSArIGNvbXB1dGVkRHVyLCB0aGlzLmZhZGVPdXQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL3N0YXJ0IHRoZSBidWZmZXIgc291cmNlXG5cdCAgICAgICAgaWYgKHRoaXMubG9vcCkge1xuXHQgICAgICAgICAgICAvL21vZGlmeSB0aGUgb2Zmc2V0IGlmIGl0J3MgZ3JlYXRlciB0aGFuIHRoZSBsb29wIHRpbWVcblx0ICAgICAgICAgICAgdmFyIGxvb3BFbmQgPSB0aGlzLmxvb3BFbmQgfHwgdGhpcy5idWZmZXIuZHVyYXRpb247XG5cdCAgICAgICAgICAgIHZhciBsb29wU3RhcnQgPSB0aGlzLmxvb3BTdGFydDtcblx0ICAgICAgICAgICAgdmFyIGxvb3BEdXJhdGlvbiA9IGxvb3BFbmQgLSBsb29wU3RhcnQ7XG5cdCAgICAgICAgICAgIC8vbW92ZSB0aGUgb2Zmc2V0IGJhY2tcblx0ICAgICAgICAgICAgaWYgKG9mZnNldCA+PSBsb29wRW5kKSB7XG5cdCAgICAgICAgICAgICAgICBvZmZzZXQgPSAob2Zmc2V0IC0gbG9vcFN0YXJ0KSAlIGxvb3BEdXJhdGlvbiArIGxvb3BTdGFydDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl9zb3VyY2UuYnVmZmVyID0gdGhpcy5idWZmZXIuZ2V0KCk7XG5cdCAgICAgICAgdGhpcy5fc291cmNlLmxvb3BFbmQgPSB0aGlzLmxvb3BFbmQgfHwgdGhpcy5idWZmZXIuZHVyYXRpb247XG5cdCAgICAgICAgaWYgKG9mZnNldCA8IHRoaXMuYnVmZmVyLmR1cmF0aW9uKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3NvdXJjZVN0YXJ0ZWQgPSB0cnVlO1xuXHQgICAgICAgICAgICB0aGlzLl9zb3VyY2Uuc3RhcnQodGltZSwgb2Zmc2V0KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFN0b3AgdGhlIGJ1ZmZlci4gT3B0aW9uYWxseSBhZGQgYSByYW1wIHRpbWUgdG8gZmFkZSB0aGVcblx0XHQgKiAgYnVmZmVyIG91dC5cblx0XHQgKiAgQHBhcmFtICB7VGltZT19ICB0aW1lICAgICAgICAgVGhlIHRpbWUgdGhlIGJ1ZmZlciBzaG91bGQgc3RvcC5cblx0XHQgKiAgQHBhcmFtICB7VGltZT19ICBmYWRlT3V0VGltZSAgSG93IGxvbmcgdGhlIGdhaW4gc2hvdWxkIGZhZGUgb3V0IGZvclxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5CdWZmZXJTb3VyY2V9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkJ1ZmZlclNvdXJjZS5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uICh0aW1lLCBmYWRlT3V0VGltZSkge1xuXHQgICAgICAgIGlmICghdGhpcy5idWZmZXIubG9hZGVkKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVG9uZS5CdWZmZXJTb3VyY2U6IGJ1ZmZlciBpcyBlaXRoZXIgbm90IHNldCBvciBub3QgbG9hZGVkLicpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAodGhpcy5fc291cmNlU3RvcHBlZCkge1xuXHQgICAgICAgICAgICByZXR1cm47XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICAvL2lmIHRoZSBldmVudCBoYXMgYWxyZWFkeSBiZWVuIHNjaGVkdWxlZCwgY2xlYXIgaXRcblx0ICAgICAgICBpZiAodGhpcy5fc3RvcFRpbWUgIT09IC0xKSB7XG5cdCAgICAgICAgICAgIHRoaXMuY2FuY2VsU3RvcCgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL3N0b3AgaWYgaXQncyBzY2hlZHVsZSBiZWZvcmUgdGhlIHN0YXJ0IHRpbWVcblx0ICAgICAgICBpZiAodGltZSA8PSB0aGlzLl9zdGFydFRpbWUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSk7XG5cdCAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4udmFsdWUgPSAwO1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGltZSA9IE1hdGgubWF4KHRoaXMuX3N0YXJ0VGltZSArIHRoaXMuZmFkZUluICsgdGhpcy5zYW1wbGVUaW1lLCB0aW1lKTtcblx0ICAgICAgICAvL2NhbmNlbCB0aGUgcHJldmlvdXMgY3VydmVcblx0ICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9zdG9wVGltZSA9IHRpbWU7XG5cdCAgICAgICAgLy90aGUgZmFkZU91dCB0aW1lXG5cdCAgICAgICAgZmFkZU91dFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhUb25lLmRlZmF1bHRBcmcoZmFkZU91dFRpbWUsIHRoaXMuZmFkZU91dCkpO1xuXHQgICAgICAgIHZhciBoZWxkRHVyYXRpb24gPSB0aW1lIC0gdGhpcy5fc3RhcnRUaW1lIC0gdGhpcy5mYWRlSW4gLSB0aGlzLnNhbXBsZVRpbWU7XG5cdCAgICAgICAgaWYgKCF0aGlzLmxvb3ApIHtcblx0ICAgICAgICAgICAgLy9tYWtlIHN1cmUgdGhlIGZhZGUgZG9lcyBub3QgZ28gYmV5b25kIHRoZSBsZW5ndGggb2YgdGhlIGJ1ZmZlclxuXHQgICAgICAgICAgICBoZWxkRHVyYXRpb24gPSBNYXRoLm1pbihoZWxkRHVyYXRpb24sIHRoaXMuYnVmZmVyLmR1cmF0aW9uKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZmFkZU91dFRpbWUgPSBNYXRoLm1pbihoZWxkRHVyYXRpb24sIGZhZGVPdXRUaW1lKTtcblx0ICAgICAgICB2YXIgc3RhcnRGYWRlID0gdGltZSAtIGZhZGVPdXRUaW1lO1xuXHQgICAgICAgIGlmIChmYWRlT3V0VGltZSA+IHRoaXMuc2FtcGxlVGltZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKHRoaXMuX2dhaW4sIHN0YXJ0RmFkZSk7XG5cdCAgICAgICAgICAgIGlmICh0aGlzLmN1cnZlID09PSAnbGluZWFyJykge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSgwLCB0aW1lKTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKDAsIHN0YXJ0RmFkZSwgZmFkZU91dFRpbWUpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgwLCB0aW1lKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgVG9uZS5jb250ZXh0LmNsZWFyVGltZW91dCh0aGlzLl9vbmVuZGVkVGltZW91dCk7XG5cdCAgICAgICAgdGhpcy5fb25lbmRlZFRpbWVvdXQgPSBUb25lLmNvbnRleHQuc2V0VGltZW91dCh0aGlzLl9vbmVuZGVkLmJpbmQodGhpcyksIHRoaXMuX3N0b3BUaW1lIC0gdGhpcy5ub3coKSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENhbmNlbCBhIHNjaGVkdWxlZCBzdG9wIGV2ZW50XG5cdFx0ICogIEByZXR1cm4gIHtUb25lLkJ1ZmZlclNvdXJjZX0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuQnVmZmVyU291cmNlLnByb3RvdHlwZS5jYW5jZWxTdG9wID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGlmICh0aGlzLl9zdGFydFRpbWUgIT09IC0xICYmICF0aGlzLl9zb3VyY2VTdG9wcGVkKSB7XG5cdCAgICAgICAgICAgIC8vY2FuY2VsIHRoZSBzdG9wIGVudmVsb3BlXG5cdCAgICAgICAgICAgIHZhciBmYWRlSW5UaW1lID0gdGhpcy50b1NlY29uZHModGhpcy5mYWRlSW4pO1xuXHQgICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aGlzLl9zdGFydFRpbWUgKyBmYWRlSW5UaW1lICsgdGhpcy5zYW1wbGVUaW1lKTtcblx0ICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCBNYXRoLm1heCh0aGlzLm5vdygpLCB0aGlzLl9zdGFydFRpbWUgKyBmYWRlSW5UaW1lICsgdGhpcy5zYW1wbGVUaW1lKSk7XG5cdCAgICAgICAgICAgIHRoaXMuY29udGV4dC5jbGVhclRpbWVvdXQodGhpcy5fb25lbmRlZFRpbWVvdXQpO1xuXHQgICAgICAgICAgICB0aGlzLl9zdG9wVGltZSA9IC0xO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgSW50ZXJuYWwgY2FsbGJhY2sgd2hlbiB0aGUgYnVmZmVyIGlzIGVuZGVkLlxuXHRcdCAqICBJbnZva2VzIGBvbmVuZGVkYCBhbmQgZGlzcG9zZXMgdGhlIG5vZGUuXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkJ1ZmZlclNvdXJjZS5wcm90b3R5cGUuX29uZW5kZWQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgaWYgKCF0aGlzLl9zb3VyY2VTdG9wcGVkKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3NvdXJjZVN0b3BwZWQgPSB0cnVlO1xuXHQgICAgICAgICAgICAvL2FsbG93IGFkZGl0aW9uYWwgdGltZSBmb3IgdGhlIGV4cG9uZW50aWFsIGN1cnZlIHRvIGZ1bGx5IGRlY2F5XG5cdCAgICAgICAgICAgIHZhciBhZGRpdGlvbmFsVGFpbCA9IHRoaXMuY3VydmUgPT09ICdleHBvbmVudGlhbCcgPyB0aGlzLmZhZGVPdXQgKiAyIDogMDtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3NvdXJjZVN0YXJ0ZWQgJiYgdGhpcy5fc3RvcFRpbWUgIT09IC0xKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9zb3VyY2Uuc3RvcCh0aGlzLl9zdG9wVGltZSArIGFkZGl0aW9uYWxUYWlsKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aGlzLm9uZW5kZWQodGhpcyk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIElmIGxvb3AgaXMgdHJ1ZSwgdGhlIGxvb3Agd2lsbCBzdGFydCBhdCB0aGlzIHBvc2l0aW9uLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkJ1ZmZlclNvdXJjZSNcblx0XHQgKiBAdHlwZSB7VGltZX1cblx0XHQgKiBAbmFtZSBsb29wU3RhcnRcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkJ1ZmZlclNvdXJjZS5wcm90b3R5cGUsICdsb29wU3RhcnQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9zb3VyY2UubG9vcFN0YXJ0O1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobG9vcFN0YXJ0KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5sb29wU3RhcnQgPSB0aGlzLnRvU2Vjb25kcyhsb29wU3RhcnQpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogSWYgbG9vcCBpcyB0cnVlLCB0aGUgbG9vcCB3aWxsIGVuZCBhdCB0aGlzIHBvc2l0aW9uLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkJ1ZmZlclNvdXJjZSNcblx0XHQgKiBAdHlwZSB7VGltZX1cblx0XHQgKiBAbmFtZSBsb29wRW5kXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5CdWZmZXJTb3VyY2UucHJvdG90eXBlLCAnbG9vcEVuZCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZS5sb29wRW5kO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobG9vcEVuZCkge1xuXHQgICAgICAgICAgICB0aGlzLl9zb3VyY2UubG9vcEVuZCA9IHRoaXMudG9TZWNvbmRzKGxvb3BFbmQpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIGF1ZGlvIGJ1ZmZlciBiZWxvbmdpbmcgdG8gdGhlIHBsYXllci5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5CdWZmZXJTb3VyY2UjXG5cdFx0ICogQHR5cGUge1RvbmUuQnVmZmVyfVxuXHRcdCAqIEBuYW1lIGJ1ZmZlclxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQnVmZmVyU291cmNlLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGJ1ZmZlcikge1xuXHQgICAgICAgICAgICB0aGlzLl9idWZmZXIuc2V0KGJ1ZmZlcik7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBJZiB0aGUgYnVmZmVyIHNob3VsZCBsb29wIG9uY2UgaXQncyBvdmVyLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkJ1ZmZlclNvdXJjZSNcblx0XHQgKiBAdHlwZSB7Qm9vbGVhbn1cblx0XHQgKiBAbmFtZSBsb29wXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5CdWZmZXJTb3VyY2UucHJvdG90eXBlLCAnbG9vcCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZS5sb29wO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobG9vcCkge1xuXHQgICAgICAgICAgICB0aGlzLl9zb3VyY2UubG9vcCA9IGxvb3A7XG5cdCAgICAgICAgICAgIHRoaXMuY2FuY2VsU3RvcCgpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5CdWZmZXJTb3VyY2V9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkJ1ZmZlclNvdXJjZS5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMub25lbmRlZCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fc291cmNlLm9uZW5kZWQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3NvdXJjZS5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgdGhpcy5fc291cmNlID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9nYWluTm9kZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fZ2Fpbk5vZGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2J1ZmZlci5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fYnVmZmVyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9zdGFydFRpbWUgPSAtMTtcblx0ICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZSA9IG51bGw7XG5cdCAgICAgICAgVG9uZS5jb250ZXh0LmNsZWFyVGltZW91dCh0aGlzLl9vbmVuZGVkVGltZW91dCk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuQnVmZmVyU291cmNlO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIFRvbmUuTm9pc2UgaXMgYSBub2lzZSBnZW5lcmF0b3IuIEl0IHVzZXMgbG9vcGVkIG5vaXNlIGJ1ZmZlcnMgdG8gc2F2ZSBvbiBwZXJmb3JtYW5jZS5cblx0XHQgKiAgICAgICAgICBUb25lLk5vaXNlIHN1cHBvcnRzIHRoZSBub2lzZSB0eXBlczogXCJwaW5rXCIsIFwid2hpdGVcIiwgYW5kIFwiYnJvd25cIi4gUmVhZCBtb3JlIGFib3V0XG5cdFx0ICogICAgICAgICAgY29sb3JzIG9mIG5vaXNlIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbG9yc19vZl9ub2lzZSkuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlNvdXJjZX1cblx0XHQgKiAgQHBhcmFtIHtzdHJpbmd9IHR5cGUgdGhlIG5vaXNlIHR5cGUgKHdoaXRlfHBpbmt8YnJvd24pXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9pbml0aWFsaXplIHRoZSBub2lzZSBhbmQgc3RhcnRcblx0XHQgKiB2YXIgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZShcInBpbmtcIikuc3RhcnQoKTtcblx0XHQgKlxuXHRcdCAqIC8vbWFrZSBhbiBhdXRvZmlsdGVyIHRvIHNoYXBlIHRoZSBub2lzZVxuXHRcdCAqIHZhciBhdXRvRmlsdGVyID0gbmV3IFRvbmUuQXV0b0ZpbHRlcih7XG5cdFx0ICogXHRcImZyZXF1ZW5jeVwiIDogXCI4bVwiLFxuXHRcdCAqIFx0XCJtaW5cIiA6IDgwMCxcblx0XHQgKiBcdFwibWF4XCIgOiAxNTAwMFxuXHRcdCAqIH0pLmNvbm5lY3QoVG9uZS5NYXN0ZXIpO1xuXHRcdCAqXG5cdFx0ICogLy9jb25uZWN0IHRoZSBub2lzZVxuXHRcdCAqIG5vaXNlLmNvbm5lY3QoYXV0b0ZpbHRlcik7XG5cdFx0ICogLy9zdGFydCB0aGUgYXV0b2ZpbHRlciBMRk9cblx0XHQgKiBhdXRvRmlsdGVyLnN0YXJ0KClcblx0XHQgKi9cblx0ICAgIFRvbmUuTm9pc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgWyd0eXBlJ10sIFRvbmUuTm9pc2UpO1xuXHQgICAgICAgIFRvbmUuU291cmNlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqICBAdHlwZSB7QXVkaW9CdWZmZXJTb3VyY2VOb2RlfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc291cmNlID0gbnVsbDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgYnVmZmVyXG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqICBAdHlwZSB7QXVkaW9CdWZmZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl90eXBlID0gb3B0aW9ucy50eXBlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBub2lzZS4gQWZmZWN0c1xuXHRcdFx0ICogIHRoZSBcImZyZXF1ZW5jeVwiIG9mIHRoZSBub2lzZS5cblx0XHRcdCAqICBAdHlwZSB7UG9zaXRpdmV9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5Ob2lzZSwgVG9uZS5Tb3VyY2UpO1xuXHQgICAgLyoqXG5cdFx0ICogIHRoZSBkZWZhdWx0IHBhcmFtZXRlcnNcblx0XHQgKlxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBjb25zdFxuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Ob2lzZS5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAndHlwZSc6ICd3aGl0ZScsXG5cdCAgICAgICAgJ3BsYXliYWNrUmF0ZSc6IDFcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgdHlwZSBvZiB0aGUgbm9pc2UuIENhbiBiZSBcIndoaXRlXCIsIFwiYnJvd25cIiwgb3IgXCJwaW5rXCIuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuTm9pc2UjXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAbmFtZSB0eXBlXG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiBub2lzZS50eXBlID0gXCJ3aGl0ZVwiO1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuTm9pc2UucHJvdG90eXBlLCAndHlwZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh0eXBlKSB7XG5cdCAgICAgICAgICAgIGlmICh0aGlzLl90eXBlICE9PSB0eXBlKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAodHlwZSBpbiBfbm9pc2VCdWZmZXJzKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG5cdCAgICAgICAgICAgICAgICAgICAgLy9pZiBpdCdzIHBsYXlpbmcsIHN0b3AgYW5kIHJlc3RhcnQgaXRcblx0ICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gVG9uZS5TdGF0ZS5TdGFydGVkKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub3cgPSB0aGlzLm5vdygpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdG9wKG5vdyk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KG5vdyk7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUb25lLk5vaXNlOiBpbnZhbGlkIHR5cGU6ICcgKyB0eXBlKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBub2lzZS4gQWZmZWN0c1xuXHRcdCAqICB0aGUgXCJmcmVxdWVuY3lcIiBvZiB0aGUgbm9pc2UuXG5cdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHQgKiAgQHNpZ25hbFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuTm9pc2UucHJvdG90eXBlLCAncGxheWJhY2tSYXRlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocmF0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSByYXRlO1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fc291cmNlKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9zb3VyY2UucGxheWJhY2tSYXRlLnZhbHVlID0gcmF0ZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIGludGVybmFsIHN0YXJ0IG1ldGhvZFxuXHRcdCAqXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gdGltZVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Ob2lzZS5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB2YXIgYnVmZmVyID0gX25vaXNlQnVmZmVyc1t0aGlzLl90eXBlXTtcblx0ICAgICAgICB0aGlzLl9zb3VyY2UgPSBuZXcgVG9uZS5CdWZmZXJTb3VyY2UoYnVmZmVyKS5jb25uZWN0KHRoaXMub3V0cHV0KTtcblx0ICAgICAgICB0aGlzLl9zb3VyY2UubG9vcCA9IHRydWU7XG5cdCAgICAgICAgdGhpcy5fc291cmNlLnBsYXliYWNrUmF0ZS52YWx1ZSA9IHRoaXMuX3BsYXliYWNrUmF0ZTtcblx0ICAgICAgICB0aGlzLl9zb3VyY2Uuc3RhcnQodGhpcy50b1NlY29uZHModGltZSksIE1hdGgucmFuZG9tKCkgKiAoYnVmZmVyLmR1cmF0aW9uIC0gMC4wMDEpKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgaW50ZXJuYWwgc3RvcCBtZXRob2Rcblx0XHQgKlxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IHRpbWVcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuTm9pc2UucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICBpZiAodGhpcy5fc291cmNlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5zdG9wKHRoaXMudG9TZWNvbmRzKHRpbWUpKTtcblx0ICAgICAgICAgICAgdGhpcy5fc291cmNlID0gbnVsbDtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogUmVzdGFydHMgdGhlIG5vaXNlLlxuXHRcdCAqIEBwYXJhbSAge1t0eXBlXX0gdGltZSBbZGVzY3JpcHRpb25dXG5cdFx0ICogQHJldHVybiB7W3R5cGVdfSAgICAgIFtkZXNjcmlwdGlvbl1cblx0XHQgKi9cblx0ICAgIFRvbmUuTm9pc2UucHJvdG90eXBlLnJlc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIC8vVE9ETyBjb3VsZCBiZSBvcHRpbWl6ZWQgYnkgY2FuY2VsbGluZyB0aGUgYnVmZmVyIHNvdXJjZSAnc3RvcCdcblx0ICAgICAgICAvL3N0b3AgYW5kIHJlc3RhcnRcblx0ICAgICAgICB0aGlzLl9zdG9wKHRpbWUpO1xuXHQgICAgICAgIHRoaXMuX3N0YXJ0KHRpbWUpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuTm9pc2V9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTm9pc2UucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5Tb3VyY2UucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICBpZiAodGhpcy5fc291cmNlICE9PSBudWxsKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgICAgIHRoaXMuX3NvdXJjZSA9IG51bGw7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuX2J1ZmZlciA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvLyBUSEUgQlVGRkVSU1xuXHQgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdCAgICAvL05vaXNlIGJ1ZmZlciBzdGF0c1xuXHQgICAgdmFyIGJ1ZmZlckxlbmd0aCA9IDQ0MTAwICogNTtcblx0ICAgIHZhciBjaGFubmVscyA9IDI7XG5cdCAgICAvKipcblx0XHQgKlx0VGhlIG5vaXNlIGFycmF5cy4gR2VuZXJhdGVkIG9uIGluaXRpYWxpemF0aW9uLlxuXHRcdCAqICBib3Jyb3dlZCBoZWF2aWx5IGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3phY2hhcnlkZW50b24vbm9pc2UuanNcblx0XHQgKiAgKGMpIDIwMTMgWmFjaCBEZW50b24gKE1JVClcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqICBAdHlwZSB7QXJyYXl9XG5cdFx0ICovXG5cdCAgICB2YXIgX25vaXNlQXJyYXlzID0ge1xuXHQgICAgICAgICdwaW5rJzogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgYnVmZmVyID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGNoYW5uZWxOdW0gPSAwOyBjaGFubmVsTnVtIDwgY2hhbm5lbHM7IGNoYW5uZWxOdW0rKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlckxlbmd0aCk7XG5cdCAgICAgICAgICAgICAgICBidWZmZXJbY2hhbm5lbE51bV0gPSBjaGFubmVsO1xuXHQgICAgICAgICAgICAgICAgdmFyIGIwLCBiMSwgYjIsIGIzLCBiNCwgYjUsIGI2O1xuXHQgICAgICAgICAgICAgICAgYjAgPSBiMSA9IGIyID0gYjMgPSBiNCA9IGI1ID0gYjYgPSAwO1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBidWZmZXJMZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciB3aGl0ZSA9IE1hdGgucmFuZG9tKCkgKiAyIC0gMTtcblx0ICAgICAgICAgICAgICAgICAgICBiMCA9IDAuOTk4ODYgKiBiMCArIHdoaXRlICogMC4wNTU1MTc5O1xuXHQgICAgICAgICAgICAgICAgICAgIGIxID0gMC45OTMzMiAqIGIxICsgd2hpdGUgKiAwLjA3NTA3NTk7XG5cdCAgICAgICAgICAgICAgICAgICAgYjIgPSAwLjk2OSAqIGIyICsgd2hpdGUgKiAwLjE1Mzg1Mjtcblx0ICAgICAgICAgICAgICAgICAgICBiMyA9IDAuODY2NSAqIGIzICsgd2hpdGUgKiAwLjMxMDQ4NTY7XG5cdCAgICAgICAgICAgICAgICAgICAgYjQgPSAwLjU1ICogYjQgKyB3aGl0ZSAqIDAuNTMyOTUyMjtcblx0ICAgICAgICAgICAgICAgICAgICBiNSA9IC0wLjc2MTYgKiBiNSAtIHdoaXRlICogMC4wMTY4OTg7XG5cdCAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSA9IGIwICsgYjEgKyBiMiArIGIzICsgYjQgKyBiNSArIGI2ICsgd2hpdGUgKiAwLjUzNjI7XG5cdCAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSAqPSAwLjExO1xuXHQgICAgICAgICAgICAgICAgICAgIC8vIChyb3VnaGx5KSBjb21wZW5zYXRlIGZvciBnYWluXG5cdCAgICAgICAgICAgICAgICAgICAgYjYgPSB3aGl0ZSAqIDAuMTE1OTI2O1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHJldHVybiBidWZmZXI7XG5cdCAgICAgICAgfSgpLFxuXHQgICAgICAgICdicm93bic6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGJ1ZmZlciA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBjaGFubmVsTnVtID0gMDsgY2hhbm5lbE51bSA8IGNoYW5uZWxzOyBjaGFubmVsTnVtKyspIHtcblx0ICAgICAgICAgICAgICAgIHZhciBjaGFubmVsID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXJMZW5ndGgpO1xuXHQgICAgICAgICAgICAgICAgYnVmZmVyW2NoYW5uZWxOdW1dID0gY2hhbm5lbDtcblx0ICAgICAgICAgICAgICAgIHZhciBsYXN0T3V0ID0gMDtcblx0ICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYnVmZmVyTGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgd2hpdGUgPSBNYXRoLnJhbmRvbSgpICogMiAtIDE7XG5cdCAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSA9IChsYXN0T3V0ICsgMC4wMiAqIHdoaXRlKSAvIDEuMDI7XG5cdCAgICAgICAgICAgICAgICAgICAgbGFzdE91dCA9IGNoYW5uZWxbaV07XG5cdCAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSAqPSAzLjU7ICAgIC8vIChyb3VnaGx5KSBjb21wZW5zYXRlIGZvciBnYWluXG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcblx0ICAgICAgICB9KCksXG5cdCAgICAgICAgJ3doaXRlJzogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgYnVmZmVyID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGNoYW5uZWxOdW0gPSAwOyBjaGFubmVsTnVtIDwgY2hhbm5lbHM7IGNoYW5uZWxOdW0rKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlckxlbmd0aCk7XG5cdCAgICAgICAgICAgICAgICBidWZmZXJbY2hhbm5lbE51bV0gPSBjaGFubmVsO1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBidWZmZXJMZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxbaV0gPSBNYXRoLnJhbmRvbSgpICogMiAtIDE7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcblx0ICAgICAgICB9KClcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKlx0c3RhdGljIG5vaXNlIGJ1ZmZlcnNcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqICBAdHlwZSB7VG9uZS5CdWZmZXJ9XG5cdFx0ICovXG5cdCAgICB2YXIgX25vaXNlQnVmZmVycyA9IHt9O1xuXHQgICAgLy9jcmVhdGUgdGhlIFRvbmUuQnVmZmVyc1xuXHQgICAgZnVuY3Rpb24gY3JlYXRlQnVmZmVycygpIHtcblx0ICAgICAgICBmb3IgKHZhciB0eXBlIGluIF9ub2lzZUFycmF5cykge1xuXHQgICAgICAgICAgICBfbm9pc2VCdWZmZXJzW3R5cGVdID0gbmV3IFRvbmUuQnVmZmVyKCkuZnJvbUFycmF5KF9ub2lzZUFycmF5c1t0eXBlXSk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLy9jcmVhdGUgdGhlIG5vaXNlIGJ1ZmZlcnNcblx0ICAgIFRvbmUuZ2V0Q29udGV4dChjcmVhdGVCdWZmZXJzKTtcblx0ICAgIFRvbmUuQ29udGV4dC5vbignaW5pdCcsIGNyZWF0ZUJ1ZmZlcnMpO1xuXHQgICAgcmV0dXJuIFRvbmUuTm9pc2U7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBTaW1wbGUgY29udm9sdXRpb24gY3JlYXRlZCB3aXRoIGRlY2F5aW5nIG5vaXNlLlxuXHRcdCAqICBcdFx0R2VuZXJhdGVzIGFuIEltcHVsc2UgUmVzcG9uc2UgQnVmZmVyXG5cdFx0ICogXHRcdFx0d2l0aCBUb25lLk9mZmxpbmUgdGhlbiBmZWVkcyB0aGUgSVIgaW50byBDb252b2x2ZXJOb2RlLlxuXHRcdCAqIFx0XHRcdE5vdGU6IHRoZSBSZXZlcmIgd2lsbCBub3QgbWFrZSBhbnkgc291bmQgdW50aWwgW2dlbmVyYXRlXSgjZ2VuZXJhdGUpXG5cdFx0ICogXHRcdFx0aGFzIGJlZW4gaW52b2tlZCBhbmQgcmVzb2x2ZWQuXG5cdFx0ICpcblx0XHQgKiBcdFx0XHRJbnNwaXJhdGlvbiBmcm9tIFtSZXZlcmJHZW5dKGh0dHBzOi8vZ2l0aHViLmNvbS9hZGVsZXNwaW5hc3NlL3JldmVyYkdlbikuXG5cdFx0ICogXHRcdFx0Q29weXJpZ2h0IChjKSAyMDE0IEFsYW4gZGVMZXNwaW5hc3NlIEFwYWNoZSAyLjAgTGljZW5zZS5cblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5Db252b2x2ZXJ9XG5cdFx0ICogIEBwYXJhbSB7VGltZT19IGRlY2F5IFRoZSBhbW91bnQgb2YgdGltZSBpdCB3aWxsIHJldmVyYmVyYXRlIGZvci5cblx0XHQgKi9cblx0ICAgIFRvbmUuUmV2ZXJiID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFsnZGVjYXknXSwgVG9uZS5SZXZlcmIpO1xuXHQgICAgICAgIFRvbmUuRWZmZWN0LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQ29udm9sdmVyIG5vZGVcblx0XHRcdCAqICBAdHlwZSB7Q29udm9sdmVyTm9kZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fY29udm9sdmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIGR1cmF0aW9uIG9mIHRoZSByZXZlcmJcblx0XHRcdCAqIEB0eXBlIHtUaW1lfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZWNheSA9IG9wdGlvbnMuZGVjYXk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBUaGUgYW1vdW50IG9mIHRpbWUgYmVmb3JlIHRoZSByZXZlcmIgaXMgZnVsbHlcblx0XHRcdCAqIHJhbXBlZCBpbi5cblx0XHRcdCAqIEB0eXBlIHtUaW1lfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5wcmVEZWxheSA9IG9wdGlvbnMucHJlRGVsYXk7XG5cdCAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0KHRoaXMuX2NvbnZvbHZlcik7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5SZXZlcmIsIFRvbmUuRWZmZWN0KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBkZWZhdWx0c1xuXHRcdCAqIEB0eXBlIHtPYmplY3R9XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHQgICAgVG9uZS5SZXZlcmIuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2RlY2F5JzogMS41LFxuXHQgICAgICAgICdwcmVEZWxheSc6IDAuMDFcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBHZW5lcmF0ZSB0aGUgSW1wdWxzZSBSZXNwb25zZS4gUmV0dXJucyBhIHByb21pc2Ugd2hpbGUgdGhlIElSIGlzIGJlaW5nXG5cdFx0ICogZ2VuZXJhdGVkLlxuXHRcdCAqIEByZXR1cm4ge1Byb21pc2U8VG9uZS5SZXZlcmI+fSBQcm9taXNlIHdoaWNoIHJldHVybnMgdGhpcyBvYmplY3QuXG5cdFx0ICovXG5cdCAgICBUb25lLlJldmVyYi5wcm90b3R5cGUuZ2VuZXJhdGUgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIFRvbmUuT2ZmbGluZShmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vY3JlYXRlIGEgbm9pc2UgYnVyc3Qgd2hpY2ggZGVjYXlzIG92ZXIgdGhlIGR1cmF0aW9uXG5cdCAgICAgICAgICAgIHZhciBub2lzZUwgPSBuZXcgVG9uZS5Ob2lzZSgpO1xuXHQgICAgICAgICAgICB2YXIgbm9pc2VSID0gbmV3IFRvbmUuTm9pc2UoKTtcblx0ICAgICAgICAgICAgdmFyIG1lcmdlID0gbmV3IFRvbmUuTWVyZ2UoKTtcblx0ICAgICAgICAgICAgbm9pc2VMLmNvbm5lY3QobWVyZ2UubGVmdCk7XG5cdCAgICAgICAgICAgIG5vaXNlUi5jb25uZWN0KG1lcmdlLnJpZ2h0KTtcblx0ICAgICAgICAgICAgdmFyIGdhaW5Ob2RlID0gbmV3IFRvbmUuR2FpbigpLnRvTWFzdGVyKCk7XG5cdCAgICAgICAgICAgIG1lcmdlLmNvbm5lY3QoZ2Fpbk5vZGUpO1xuXHQgICAgICAgICAgICBub2lzZUwuc3RhcnQoMCk7XG5cdCAgICAgICAgICAgIG5vaXNlUi5zdGFydCgwKTtcblx0ICAgICAgICAgICAgLy9zaG9ydCBmYWRlIGluXG5cdCAgICAgICAgICAgIGdhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgMCk7XG5cdCAgICAgICAgICAgIGdhaW5Ob2RlLmdhaW4ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUoMSwgdGhpcy5wcmVEZWxheSk7XG5cdCAgICAgICAgICAgIC8vZGVjYXlcblx0ICAgICAgICAgICAgZ2Fpbk5vZGUuZ2Fpbi5leHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUoMCwgdGhpcy5wcmVEZWxheSwgdGhpcy5kZWNheSAtIHRoaXMucHJlRGVsYXkpO1xuXHQgICAgICAgIH0uYmluZCh0aGlzKSwgdGhpcy5kZWNheSkudGhlbihmdW5jdGlvbiAoYnVmZmVyKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2NvbnZvbHZlci5idWZmZXIgPSBidWZmZXIuZ2V0KCk7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH0uYmluZCh0aGlzKSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5SZXZlcmJ9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlJldmVyYi5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkVmZmVjdC5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX2NvbnZvbHZlci5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgdGhpcy5fY29udm9sdmVyID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5SZXZlcmI7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBCYXNlIGNsYXNzIGZvciBzdGVyZW8gZmVlZGJhY2sgZWZmZWN0cyB3aGVyZSB0aGUgZWZmZWN0UmV0dXJuXG5cdFx0ICogICAgICAgICBpcyBmZWQgYmFjayBpbnRvIHRoZSBzYW1lIGNoYW5uZWwuXG5cdFx0ICpcblx0XHQgKlx0QGNvbnN0cnVjdG9yXG5cdFx0ICpcdEBleHRlbmRzIHtUb25lLlN0ZXJlb0VmZmVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuU3RlcmVvRmVlZGJhY2tFZmZlY3QgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgWydmZWVkYmFjayddLCBUb25lLkZlZWRiYWNrRWZmZWN0KTtcblx0ICAgICAgICBUb25lLlN0ZXJlb0VmZmVjdC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGNvbnRyb2xzIHRoZSBhbW91bnQgb2YgZmVlZGJhY2tcblx0XHRcdCAqICBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5mZWVkYmFjayA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLmZlZWRiYWNrLCBUb25lLlR5cGUuTm9ybWFsUmFuZ2UpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBsZWZ0IHNpZGUgZmVlYmFja1xuXHRcdFx0ICogIEB0eXBlIHtUb25lLkdhaW59XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ZlZWRiYWNrTCA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgcmlnaHQgc2lkZSBmZWViYWNrXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuR2Fpbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZmVlZGJhY2tSID0gbmV3IFRvbmUuR2FpbigpO1xuXHQgICAgICAgIC8vY29ubmVjdCBpdCB1cFxuXHQgICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuTC5jaGFpbih0aGlzLl9mZWVkYmFja0wsIHRoaXMuZWZmZWN0U2VuZEwpO1xuXHQgICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuUi5jaGFpbih0aGlzLl9mZWVkYmFja1IsIHRoaXMuZWZmZWN0U2VuZFIpO1xuXHQgICAgICAgIHRoaXMuZmVlZGJhY2suZmFuKHRoaXMuX2ZlZWRiYWNrTC5nYWluLCB0aGlzLl9mZWVkYmFja1IuZ2Fpbik7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoWydmZWVkYmFjayddKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlN0ZXJlb0ZlZWRiYWNrRWZmZWN0LCBUb25lLlN0ZXJlb0VmZmVjdCk7XG5cdCAgICAvKipcblx0XHQgKiAgY2xlYW4gdXBcblx0XHQgKiAgQHJldHVybnMge1RvbmUuU3RlcmVvRmVlZGJhY2tFZmZlY3R9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuU3RlcmVvRmVlZGJhY2tFZmZlY3QucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TdGVyZW9FZmZlY3QucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbJ2ZlZWRiYWNrJ10pO1xuXHQgICAgICAgIHRoaXMuZmVlZGJhY2suZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZmVlZGJhY2sgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fZmVlZGJhY2tMID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9mZWVkYmFja1IuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2ZlZWRiYWNrUiA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuU3RlcmVvRmVlZGJhY2tFZmZlY3Q7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBBcHBsaWVzIGEgd2lkdGggZmFjdG9yIHRvIHRoZSBtaWQvc2lkZSBzZXBlcmF0aW9uLlxuXHRcdCAqICAgICAgICAgMCBpcyBhbGwgbWlkIGFuZCAxIGlzIGFsbCBzaWRlLlxuXHRcdCAqICAgICAgICAgQWxnb3JpdGhtIGZvdW5kIGluIFtrdnJhdWRpbyBmb3J1bXNdKGh0dHA6Ly93d3cua3ZyYXVkaW8uY29tL2ZvcnVtL3ZpZXd0b3BpYy5waHA/dD0yMTI1ODcpLlxuXHRcdCAqICAgICAgICAgPGJyPjxicj5cblx0XHQgKiAgICAgICAgIDxjb2RlPlxuXHRcdCAqICAgICAgICAgTWlkICo9IDIqKDEtd2lkdGgpPGJyPlxuXHRcdCAqICAgICAgICAgU2lkZSAqPSAyKndpZHRoXG5cdFx0ICogICAgICAgICA8L2NvZGU+XG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuTWlkU2lkZUVmZmVjdH1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBwYXJhbSB7Tm9ybWFsUmFuZ2V8T2JqZWN0fSBbd2lkdGhdIFRoZSBzdGVyZW8gd2lkdGguIEEgd2lkdGggb2YgMCBpcyBtb25vIGFuZCAxIGlzIHN0ZXJlby4gMC41IGlzIG5vIGNoYW5nZS5cblx0XHQgKi9cblx0ICAgIFRvbmUuU3RlcmVvV2lkZW5lciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbJ3dpZHRoJ10sIFRvbmUuU3RlcmVvV2lkZW5lcik7XG5cdCAgICAgICAgVG9uZS5NaWRTaWRlRWZmZWN0LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHdpZHRoIGNvbnRyb2wuIDAgPSAxMDAlIG1pZC4gMSA9IDEwMCUgc2lkZS4gMC41ID0gbm8gY2hhbmdlLlxuXHRcdFx0ICogIEB0eXBlIHtOb3JtYWxSYW5nZX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLndpZHRoID0gbmV3IFRvbmUuU2lnbmFsKG9wdGlvbnMud2lkdGgsIFRvbmUuVHlwZS5Ob3JtYWxSYW5nZSk7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoWyd3aWR0aCddKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFR3byB0aW1lcyB0aGUgKDEtd2lkdGgpIGZvciB0aGUgbWlkIGNoYW5uZWxcblx0XHRcdCAqIEB0eXBlIHtUb25lLk11bHRpcGx5fVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhNaWQgPSBuZXcgVG9uZS5NdWx0aXBseSgyKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFR3byB0aW1lcyB0aGUgd2lkdGggZm9yIHRoZSBzaWRlIGNoYW5uZWxcblx0XHRcdCAqIEB0eXBlIHtUb25lLk11bHRpcGx5fVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhTaWRlID0gbmV3IFRvbmUuTXVsdGlwbHkoMik7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgTWlkIG11bHRpcGxpZXJcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5NdWx0aXBseX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbWlkTXVsdCA9IG5ldyBUb25lLk11bHRpcGx5KCk7XG5cdCAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aE1pZC5jb25uZWN0KHRoaXMuX21pZE11bHQsIDAsIDEpO1xuXHQgICAgICAgIHRoaXMubWlkU2VuZC5jaGFpbih0aGlzLl9taWRNdWx0LCB0aGlzLm1pZFJldHVybik7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAxIC0gd2lkdGhcblx0XHRcdCAqIEB0eXBlIHtUb25lfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fb25lTWludXNXaWR0aCA9IG5ldyBUb25lLlN1YnRyYWN0KCk7XG5cdCAgICAgICAgdGhpcy5fb25lTWludXNXaWR0aC5jb25uZWN0KHRoaXMuX3R3b1RpbWVzV2lkdGhNaWQpO1xuXHQgICAgICAgIHRoaXMuY29udGV4dC5nZXRDb25zdGFudCgxKS5jb25uZWN0KHRoaXMuX29uZU1pbnVzV2lkdGgsIDAsIDApO1xuXHQgICAgICAgIHRoaXMud2lkdGguY29ubmVjdCh0aGlzLl9vbmVNaW51c1dpZHRoLCAwLCAxKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBTaWRlIG11bHRpcGxpZXJcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5NdWx0aXBseX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc2lkZU11bHQgPSBuZXcgVG9uZS5NdWx0aXBseSgpO1xuXHQgICAgICAgIHRoaXMud2lkdGguY29ubmVjdCh0aGlzLl90d29UaW1lc1dpZHRoU2lkZSk7XG5cdCAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aFNpZGUuY29ubmVjdCh0aGlzLl9zaWRlTXVsdCwgMCwgMSk7XG5cdCAgICAgICAgdGhpcy5zaWRlU2VuZC5jaGFpbih0aGlzLl9zaWRlTXVsdCwgdGhpcy5zaWRlUmV0dXJuKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlN0ZXJlb1dpZGVuZXIsIFRvbmUuTWlkU2lkZUVmZmVjdCk7XG5cdCAgICAvKipcblx0XHQgKiAgdGhlIGRlZmF1bHQgdmFsdWVzXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuU3RlcmVvV2lkZW5lci5kZWZhdWx0cyA9IHsgJ3dpZHRoJzogMC41IH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlN0ZXJlb1dpZGVuZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuU3RlcmVvV2lkZW5lci5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLk1pZFNpZGVFZmZlY3QucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbJ3dpZHRoJ10pO1xuXHQgICAgICAgIHRoaXMud2lkdGguZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMud2lkdGggPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX21pZE11bHQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX21pZE11bHQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3NpZGVNdWx0LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9zaWRlTXVsdCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aE1pZC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aE1pZCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aFNpZGUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhTaWRlID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9vbmVNaW51c1dpZHRoLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9vbmVNaW51c1dpZHRoID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5TdGVyZW9XaWRlbmVyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5UcmVtb2xvIG1vZHVsYXRlcyB0aGUgYW1wbGl0dWRlIG9mIGFuIGluY29taW5nIHNpZ25hbCB1c2luZyBhIFRvbmUuTEZPLlxuXHRcdCAqICAgICAgICAgVGhlIHR5cGUsIGZyZXF1ZW5jeSwgYW5kIGRlcHRoIG9mIHRoZSBMRk8gaXMgY29udHJvbGxhYmxlLlxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlN0ZXJlb0VmZmVjdH1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBwYXJhbSB7RnJlcXVlbmN5fSBbZnJlcXVlbmN5XSBUaGUgcmF0ZSBvZiB0aGUgZWZmZWN0LlxuXHRcdCAqICBAcGFyYW0ge05vcm1hbFJhbmdlfSBbZGVwdGhdIFRoZSBkZXB0aCBvZiB0aGUgZWZmZWN0LlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vY3JlYXRlIGEgdHJlbW9sbyBhbmQgc3RhcnQgaXQncyBMRk9cblx0XHQgKiB2YXIgdHJlbW9sbyA9IG5ldyBUb25lLlRyZW1vbG8oOSwgMC43NSkudG9NYXN0ZXIoKS5zdGFydCgpO1xuXHRcdCAqIC8vcm91dGUgYW4gb3NjaWxsYXRvciB0aHJvdWdoIHRoZSB0cmVtb2xvIGFuZCBzdGFydCBpdFxuXHRcdCAqIHZhciBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QodHJlbW9sbykuc3RhcnQoKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJlbW9sbyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnZGVwdGgnXG5cdCAgICAgICAgXSwgVG9uZS5UcmVtb2xvKTtcblx0ICAgICAgICBUb25lLlN0ZXJlb0VmZmVjdC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSB0cmVtZWxvIExGTyBpbiB0aGUgbGVmdCBjaGFubmVsXG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLkxGT31cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbGZvTCA9IG5ldyBUb25lLkxGTyh7XG5cdCAgICAgICAgICAgICdwaGFzZSc6IG9wdGlvbnMuc3ByZWFkLFxuXHQgICAgICAgICAgICAnbWluJzogMSxcblx0ICAgICAgICAgICAgJ21heCc6IDBcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgdHJlbWVsbyBMRk8gaW4gdGhlIGxlZnQgY2hhbm5lbFxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5MRk99XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2xmb1IgPSBuZXcgVG9uZS5MRk8oe1xuXHQgICAgICAgICAgICAncGhhc2UnOiBvcHRpb25zLnNwcmVhZCxcblx0ICAgICAgICAgICAgJ21pbic6IDEsXG5cdCAgICAgICAgICAgICdtYXgnOiAwXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgV2hlcmUgdGhlIGdhaW4gaXMgbXVsdGlwbGllZFxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5HYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9hbXBsaXR1ZGVMID0gbmV3IFRvbmUuR2FpbigpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFdoZXJlIHRoZSBnYWluIGlzIG11bHRpcGxpZWRcblx0XHRcdCAqICBAdHlwZSAge1RvbmUuR2Fpbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYW1wbGl0dWRlUiA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZnJlcXVlbmN5IG9mIHRoZSB0cmVtb2xvLlxuXHRcdFx0ICogIEB0eXBlICB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFRvbmUuU2lnbmFsKG9wdGlvbnMuZnJlcXVlbmN5LCBUb25lLlR5cGUuRnJlcXVlbmN5KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZGVwdGggb2YgdGhlIGVmZmVjdC4gQSBkZXB0aCBvZiAwLCBoYXMgbm8gZWZmZWN0XG5cdFx0XHQgKiAgb24gdGhlIGFtcGxpdHVkZSwgYW5kIGEgZGVwdGggb2YgMSBtYWtlcyB0aGUgYW1wbGl0dWRlXG5cdFx0XHQgKiAgbW9kdWxhdGUgZnVsbHkgYmV0d2VlbiAwIGFuZCAxLlxuXHRcdFx0ICogIEB0eXBlICB7Tm9ybWFsUmFuZ2V9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZXB0aCA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLmRlcHRoLCBUb25lLlR5cGUuTm9ybWFsUmFuZ2UpO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFtcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdkZXB0aCdcblx0ICAgICAgICBdKTtcblx0ICAgICAgICB0aGlzLmVmZmVjdFNlbmRMLmNoYWluKHRoaXMuX2FtcGxpdHVkZUwsIHRoaXMuZWZmZWN0UmV0dXJuTCk7XG5cdCAgICAgICAgdGhpcy5lZmZlY3RTZW5kUi5jaGFpbih0aGlzLl9hbXBsaXR1ZGVSLCB0aGlzLmVmZmVjdFJldHVyblIpO1xuXHQgICAgICAgIHRoaXMuX2xmb0wuY29ubmVjdCh0aGlzLl9hbXBsaXR1ZGVMLmdhaW4pO1xuXHQgICAgICAgIHRoaXMuX2xmb1IuY29ubmVjdCh0aGlzLl9hbXBsaXR1ZGVSLmdhaW4pO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5LmZhbih0aGlzLl9sZm9MLmZyZXF1ZW5jeSwgdGhpcy5fbGZvUi5mcmVxdWVuY3kpO1xuXHQgICAgICAgIHRoaXMuZGVwdGguZmFuKHRoaXMuX2xmb1IuYW1wbGl0dWRlLCB0aGlzLl9sZm9MLmFtcGxpdHVkZSk7XG5cdCAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuXHQgICAgICAgIHRoaXMuc3ByZWFkID0gb3B0aW9ucy5zcHJlYWQ7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5UcmVtb2xvLCBUb25lLlN0ZXJlb0VmZmVjdCk7XG5cdCAgICAvKipcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuVHJlbW9sby5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnZnJlcXVlbmN5JzogMTAsXG5cdCAgICAgICAgJ3R5cGUnOiAnc2luZScsXG5cdCAgICAgICAgJ2RlcHRoJzogMC41LFxuXHQgICAgICAgICdzcHJlYWQnOiAxODBcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBTdGFydCB0aGUgdHJlbW9sby5cblx0XHQgKiBAcGFyYW0ge1RpbWV9IFt0aW1lPW5vd10gV2hlbiB0aGUgdHJlbW9sbyBiZWdpbnMuXG5cdFx0ICogQHJldHVybnMge1RvbmUuVHJlbW9sb30gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmVtb2xvLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGhpcy5fbGZvTC5zdGFydCh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9sZm9SLnN0YXJ0KHRpbWUpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFN0b3AgdGhlIHRyZW1vbG8uXG5cdFx0ICogQHBhcmFtIHtUaW1lfSBbdGltZT1ub3ddIFdoZW4gdGhlIHRyZW1vbG8gc3RvcHMuXG5cdFx0ICogQHJldHVybnMge1RvbmUuVHJlbW9sb30gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmVtb2xvLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9sZm9MLnN0b3AodGltZSk7XG5cdCAgICAgICAgdGhpcy5fbGZvUi5zdG9wKHRpbWUpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFN5bmMgdGhlIGVmZmVjdCB0byB0aGUgdHJhbnNwb3J0LlxuXHRcdCAqIEBwYXJhbSB7VGltZX0gW2RlbGF5PTBdIERlbGF5IHRpbWUgYmVmb3JlIHN0YXJ0aW5nIHRoZSBlZmZlY3QgYWZ0ZXIgdGhlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc3BvcnQgaGFzIHN0YXJ0ZWQuXG5cdFx0ICogQHJldHVybnMge1RvbmUuQXV0b0ZpbHRlcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmVtb2xvLnByb3RvdHlwZS5zeW5jID0gZnVuY3Rpb24gKGRlbGF5KSB7XG5cdCAgICAgICAgdGhpcy5fbGZvTC5zeW5jKGRlbGF5KTtcblx0ICAgICAgICB0aGlzLl9sZm9SLnN5bmMoZGVsYXkpO1xuXHQgICAgICAgIFRvbmUuVHJhbnNwb3J0LnN5bmNTaWduYWwodGhpcy5mcmVxdWVuY3kpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFVuc3luYyB0aGUgZmlsdGVyIGZyb20gdGhlIHRyYW5zcG9ydFxuXHRcdCAqIEByZXR1cm5zIHtUb25lLlRyZW1vbG99IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJlbW9sby5wcm90b3R5cGUudW5zeW5jID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuX2xmb0wudW5zeW5jKCk7XG5cdCAgICAgICAgdGhpcy5fbGZvUi51bnN5bmMoKTtcblx0ICAgICAgICBUb25lLlRyYW5zcG9ydC51bnN5bmNTaWduYWwodGhpcy5mcmVxdWVuY3kpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBUcmVtb2xvJ3Mgb3NjaWxsYXRvciB0eXBlLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlRyZW1vbG8jXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAbmFtZSB0eXBlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5UcmVtb2xvLnByb3RvdHlwZSwgJ3R5cGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9sZm9MLnR5cGU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh0eXBlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2xmb0wudHlwZSA9IHR5cGU7XG5cdCAgICAgICAgICAgIHRoaXMuX2xmb1IudHlwZSA9IHR5cGU7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBBbW91bnQgb2Ygc3RlcmVvIHNwcmVhZC4gV2hlbiBzZXQgdG8gMCwgYm90aCBMRk8ncyB3aWxsIGJlIHBhbm5lZCBjZW50cmFsbHkuXG5cdFx0ICogV2hlbiBzZXQgdG8gMTgwLCBMRk8ncyB3aWxsIGJlIHBhbm5lZCBoYXJkIGxlZnQgYW5kIHJpZ2h0IHJlc3BlY3RpdmVseS5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5UcmVtb2xvI1xuXHRcdCAqIEB0eXBlIHtEZWdyZWVzfVxuXHRcdCAqIEBuYW1lIHNwcmVhZFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuVHJlbW9sby5wcm90b3R5cGUsICdzcHJlYWQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9sZm9SLnBoYXNlIC0gdGhpcy5fbGZvTC5waGFzZTsgICAgLy8xODBcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHNwcmVhZCkge1xuXHQgICAgICAgICAgICB0aGlzLl9sZm9MLnBoYXNlID0gOTAgLSBzcHJlYWQgLyAyO1xuXHQgICAgICAgICAgICB0aGlzLl9sZm9SLnBoYXNlID0gc3ByZWFkIC8gMiArIDkwO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRyZW1vbG99IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJlbW9sby5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlN0ZXJlb0VmZmVjdC5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdkZXB0aCdcblx0ICAgICAgICBdKTtcblx0ICAgICAgICB0aGlzLl9sZm9MLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9sZm9MID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9sZm9SLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9sZm9SID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9hbXBsaXR1ZGVMLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9hbXBsaXR1ZGVMID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9hbXBsaXR1ZGVSLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9hbXBsaXR1ZGVSID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5kZXB0aCA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuVHJlbW9sbztcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIEEgVmlicmF0byBlZmZlY3QgY29tcG9zZWQgb2YgYSBUb25lLkRlbGF5IGFuZCBhIFRvbmUuTEZPLiBUaGUgTEZPXG5cdFx0ICogICAgICAgICBtb2R1bGF0ZXMgdGhlIGRlbGF5VGltZSBvZiB0aGUgZGVsYXksIGNhdXNpbmcgdGhlIHBpdGNoIHRvIHJpc2Vcblx0XHQgKiAgICAgICAgIGFuZCBmYWxsLiBcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuRWZmZWN0fVxuXHRcdCAqICBAcGFyYW0ge0ZyZXF1ZW5jeX0gZnJlcXVlbmN5IFRoZSBmcmVxdWVuY3kgb2YgdGhlIHZpYnJhdG8uXG5cdFx0ICogIEBwYXJhbSB7Tm9ybWFsUmFuZ2V9IGRlcHRoIFRoZSBhbW91bnQgdGhlIHBpdGNoIGlzIG1vZHVsYXRlZC5cblx0XHQgKi9cblx0ICAgIFRvbmUuVmlicmF0byA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnZGVwdGgnXG5cdCAgICAgICAgXSwgVG9uZS5WaWJyYXRvKTtcblx0ICAgICAgICBUb25lLkVmZmVjdC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBkZWxheSBub2RlIHVzZWQgZm9yIHRoZSB2aWJyYXRvIGVmZmVjdFxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkRlbGF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9kZWxheU5vZGUgPSBuZXcgVG9uZS5EZWxheSgwLCBvcHRpb25zLm1heERlbGF5KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgTEZPIHVzZWQgdG8gY29udHJvbCB0aGUgdmlicmF0b1xuXHRcdFx0ICogIEB0eXBlIHtUb25lLkxGT31cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbGZvID0gbmV3IFRvbmUuTEZPKHtcblx0ICAgICAgICAgICAgJ3R5cGUnOiBvcHRpb25zLnR5cGUsXG5cdCAgICAgICAgICAgICdtaW4nOiAwLFxuXHQgICAgICAgICAgICAnbWF4Jzogb3B0aW9ucy5tYXhEZWxheSxcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeSc6IG9wdGlvbnMuZnJlcXVlbmN5LFxuXHQgICAgICAgICAgICAncGhhc2UnOiAtOTAgICAgLy9vZmZzZSB0aGUgcGhhc2Ugc28gdGhlIHJlc3RpbmcgcG9zaXRpb24gaXMgaW4gdGhlIGNlbnRlclxuXHQgICAgICAgIH0pLnN0YXJ0KCkuY29ubmVjdCh0aGlzLl9kZWxheU5vZGUuZGVsYXlUaW1lKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZnJlcXVlbmN5IG9mIHRoZSB2aWJyYXRvXG5cdFx0XHQgKiAgQHR5cGUge0ZyZXF1ZW5jeX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX2xmby5mcmVxdWVuY3k7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGRlcHRoIG9mIHRoZSB2aWJyYXRvLiBcblx0XHRcdCAqICBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZXB0aCA9IHRoaXMuX2xmby5hbXBsaXR1ZGU7XG5cdCAgICAgICAgdGhpcy5kZXB0aC52YWx1ZSA9IG9wdGlvbnMuZGVwdGg7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoW1xuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2RlcHRoJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jaGFpbih0aGlzLl9kZWxheU5vZGUsIHRoaXMuZWZmZWN0UmV0dXJuKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlZpYnJhdG8sIFRvbmUuRWZmZWN0KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgZGVmYXVsdHNcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICogIEBjb25zdFxuXHRcdCAqL1xuXHQgICAgVG9uZS5WaWJyYXRvLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdtYXhEZWxheSc6IDAuMDA1LFxuXHQgICAgICAgICdmcmVxdWVuY3knOiA1LFxuXHQgICAgICAgICdkZXB0aCc6IDAuMSxcblx0ICAgICAgICAndHlwZSc6ICdzaW5lJ1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFR5cGUgb2Ygb3NjaWxsYXRvciBhdHRhY2hlZCB0byB0aGUgVmlicmF0by5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5WaWJyYXRvI1xuXHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0ICogQG5hbWUgdHlwZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuVmlicmF0by5wcm90b3R5cGUsICd0eXBlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fbGZvLnR5cGU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh0eXBlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2xmby50eXBlID0gdHlwZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuVmlicmF0b30gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5WaWJyYXRvLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuRWZmZWN0LnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fZGVsYXlOb2RlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9kZWxheU5vZGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2xmby5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbGZvID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnZGVwdGgnXG5cdCAgICAgICAgXSk7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZGVwdGggPSBudWxsO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlZpYnJhdG87XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgVG9uZS5FdmVudCBhYnN0cmFjdHMgYXdheSBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZSBhbmQgcHJvdmlkZXMgYSBzY2hlZHVsYWJsZVxuXHRcdCAqICAgICAgICAgIGNhbGxiYWNrIGZvciBhIHNpbmdsZSBvciByZXBlYXRhYmxlIGV2ZW50cyBhbG9uZyB0aGUgdGltZWxpbmUuXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmV9XG5cdFx0ICogIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2UgYXQgdGhlIHRpbWUuXG5cdFx0ICogIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIG9yIHZhbHVlcyB3aGljaCBzaG91bGQgYmUgcGFzc2VkIHRvXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIG9uIGludm9jYXRpb24uXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIGNob3JkID0gbmV3IFRvbmUuRXZlbnQoZnVuY3Rpb24odGltZSwgY2hvcmQpe1xuXHRcdCAqIFx0Ly90aGUgY2hvcmQgYXMgd2VsbCBhcyB0aGUgZXhhY3QgdGltZSBvZiB0aGUgZXZlbnRcblx0XHQgKiBcdC8vYXJlIHBhc3NlZCBpbiBhcyBhcmd1bWVudHMgdG8gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uXG5cdFx0ICogfSwgW1wiRDRcIiwgXCJFNFwiLCBcIkY0XCJdKTtcblx0XHQgKiAvL3N0YXJ0IHRoZSBjaG9yZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0cmFuc3BvcnQgdGltZWxpbmVcblx0XHQgKiBjaG9yZC5zdGFydCgpO1xuXHRcdCAqIC8vbG9vcCBpdCBldmVyeSBtZWFzdXJlIGZvciA4IG1lYXN1cmVzXG5cdFx0ICogY2hvcmQubG9vcCA9IDg7XG5cdFx0ICogY2hvcmQubG9vcEVuZCA9IFwiMW1cIjtcblx0XHQgKi9cblx0ICAgIFRvbmUuRXZlbnQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAnY2FsbGJhY2snLFxuXHQgICAgICAgICAgICAndmFsdWUnXG5cdCAgICAgICAgXSwgVG9uZS5FdmVudCk7XG5cdCAgICAgICAgVG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIExvb3AgdmFsdWVcblx0XHRcdCAqICBAdHlwZSAge0Jvb2xlYW58UG9zaXRpdmV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2xvb3AgPSBvcHRpb25zLmxvb3A7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGNhbGxiYWNrIHRvIGludm9rZS5cblx0XHRcdCAqICBAdHlwZSAge0Z1bmN0aW9ufVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5jYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHZhbHVlIHdoaWNoIGlzIHBhc3NlZCB0byB0aGVcblx0XHRcdCAqICBjYWxsYmFjayBmdW5jdGlvbi5cblx0XHRcdCAqICBAdHlwZSAgeyp9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMudmFsdWUgPSBvcHRpb25zLnZhbHVlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFdoZW4gdGhlIG5vdGUgaXMgc2NoZWR1bGVkIHRvIHN0YXJ0LlxuXHRcdFx0ICogIEB0eXBlICB7TnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSB0aGlzLnRvVGlja3Mob3B0aW9ucy5sb29wU3RhcnQpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFdoZW4gdGhlIG5vdGUgaXMgc2NoZWR1bGVkIHRvIHN0YXJ0LlxuXHRcdFx0ICogIEB0eXBlICB7TnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9sb29wRW5kID0gdGhpcy50b1RpY2tzKG9wdGlvbnMubG9vcEVuZCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVHJhY2tzIHRoZSBzY2hlZHVsZWQgZXZlbnRzXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuVGltZWxpbmVTdGF0ZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3RhdGUgPSBuZXcgVG9uZS5UaW1lbGluZVN0YXRlKFRvbmUuU3RhdGUuU3RvcHBlZCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHBsYXliYWNrIHNwZWVkIG9mIHRoZSBub3RlLiBBIHNwZWVkIG9mIDFcblx0XHRcdCAqICBpcyBubyBjaGFuZ2UuXG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqICBAdHlwZSB7UG9zaXRpdmV9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSAxO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEEgZGVsYXkgdGltZSBmcm9tIHdoZW4gdGhlIGV2ZW50IGlzIHNjaGVkdWxlZCB0byBzdGFydFxuXHRcdFx0ICogIEB0eXBlIHtUaWNrc31cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3RhcnRPZmZzZXQgPSAwO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHByaXZhdGUgaG9sZGVyIG9mIHByb2JhYmlsaXR5IHZhbHVlXG5cdFx0XHQgKiAgQHR5cGUge05vcm1hbFJhbmdlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9wcm9iYWJpbGl0eSA9IG9wdGlvbnMucHJvYmFiaWxpdHk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGFtb3VudCBvZiB2YXJpYXRpb24gZnJvbSB0aGVcblx0XHRcdCAqICBnaXZlbiB0aW1lLlxuXHRcdFx0ICogIEB0eXBlIHtCb29sZWFufFRpbWV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2h1bWFuaXplID0gb3B0aW9ucy5odW1hbml6ZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBJZiBtdXRlIGlzIHRydWUsIHRoZSBjYWxsYmFjayB3b24ndCBiZVxuXHRcdFx0ICogIGludm9rZWQuXG5cdFx0XHQgKiAgQHR5cGUge0Jvb2xlYW59XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG5cdCAgICAgICAgLy9zZXQgdGhlIGluaXRpYWwgdmFsdWVzXG5cdCAgICAgICAgdGhpcy5wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkV2ZW50KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgZGVmYXVsdCB2YWx1ZXNcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICogIEBjb25zdFxuXHRcdCAqL1xuXHQgICAgVG9uZS5FdmVudC5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnY2FsbGJhY2snOiBUb25lLm5vT3AsXG5cdCAgICAgICAgJ2xvb3AnOiBmYWxzZSxcblx0ICAgICAgICAnbG9vcEVuZCc6ICcxbScsXG5cdCAgICAgICAgJ2xvb3BTdGFydCc6IDAsXG5cdCAgICAgICAgJ3BsYXliYWNrUmF0ZSc6IDEsXG5cdCAgICAgICAgJ3ZhbHVlJzogbnVsbCxcblx0ICAgICAgICAncHJvYmFiaWxpdHknOiAxLFxuXHQgICAgICAgICdtdXRlJzogZmFsc2UsXG5cdCAgICAgICAgJ2h1bWFuaXplJzogZmFsc2Vcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmVzY2hlZHVsZSBhbGwgb2YgdGhlIGV2ZW50cyBhbG9uZyB0aGUgdGltZWxpbmVcblx0XHQgKiAgd2l0aCB0aGUgdXBkYXRlZCB2YWx1ZXMuXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gYWZ0ZXIgT25seSByZXNjaGVkdWxlcyBldmVudHMgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLkV2ZW50fSAgdGhpc1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5FdmVudC5wcm90b3R5cGUuX3Jlc2NoZWR1bGVFdmVudHMgPSBmdW5jdGlvbiAoYWZ0ZXIpIHtcblx0ICAgICAgICAvL2lmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCBzY2hlZHVsZXMgYWxsIG9mIHRoZSBldmVudHNcblx0ICAgICAgICBhZnRlciA9IFRvbmUuZGVmYXVsdEFyZyhhZnRlciwgLTEpO1xuXHQgICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hGcm9tKGFmdGVyLCBmdW5jdGlvbiAoZXZlbnQpIHtcblx0ICAgICAgICAgICAgdmFyIGR1cmF0aW9uO1xuXHQgICAgICAgICAgICBpZiAoZXZlbnQuc3RhdGUgPT09IFRvbmUuU3RhdGUuU3RhcnRlZCkge1xuXHQgICAgICAgICAgICAgICAgaWYgKFRvbmUuaXNEZWZpbmVkKGV2ZW50LmlkKSkge1xuXHQgICAgICAgICAgICAgICAgICAgIFRvbmUuVHJhbnNwb3J0LmNsZWFyKGV2ZW50LmlkKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHZhciBzdGFydFRpY2sgPSBldmVudC50aW1lICsgTWF0aC5yb3VuZCh0aGlzLnN0YXJ0T2Zmc2V0IC8gdGhpcy5fcGxheWJhY2tSYXRlKTtcblx0ICAgICAgICAgICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSBJbmZpbml0eTtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAoVG9uZS5pc051bWJlcih0aGlzLl9sb29wKSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IHRoaXMuX2xvb3AgKiB0aGlzLl9nZXRMb29wRHVyYXRpb24oKTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIG5leHRFdmVudCA9IHRoaXMuX3N0YXRlLmdldEFmdGVyKHN0YXJ0VGljayk7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRFdmVudCAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IE1hdGgubWluKGR1cmF0aW9uLCBuZXh0RXZlbnQudGltZSAtIHN0YXJ0VGljayk7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgIGlmIChkdXJhdGlvbiAhPT0gSW5maW5pdHkpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgLy9zY2hlZHVsZSBhIHN0b3Agc2luY2UgaXQncyBmaW5pdGUgZHVyYXRpb25cblx0ICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoVG9uZS5TdGF0ZS5TdG9wcGVkLCBzdGFydFRpY2sgKyBkdXJhdGlvbiArIDEpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IFRvbmUuVGlja3MoZHVyYXRpb24pO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICB2YXIgaW50ZXJ2YWwgPSBUb25lLlRpY2tzKHRoaXMuX2dldExvb3BEdXJhdGlvbigpKTtcblx0ICAgICAgICAgICAgICAgICAgICBldmVudC5pZCA9IFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlUmVwZWF0KHRoaXMuX3RpY2suYmluZCh0aGlzKSwgaW50ZXJ2YWwsIFRvbmUuVGlja3Moc3RhcnRUaWNrKSwgZHVyYXRpb24pO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICBldmVudC5pZCA9IFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlKHRoaXMuX3RpY2suYmluZCh0aGlzKSwgVG9uZS5UaWNrcyhzdGFydFRpY2spKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0uYmluZCh0aGlzKSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBub3RlLCBlaXRoZXIgXCJzdGFydGVkXCIgb3IgXCJzdG9wcGVkXCIuXG5cdFx0ICogIEB0eXBlIHtTdHJpbmd9XG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5FdmVudCNcblx0XHQgKiAgQG5hbWUgc3RhdGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkV2ZW50LnByb3RvdHlwZSwgJ3N0YXRlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoVG9uZS5UcmFuc3BvcnQudGlja3MpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBzdGFydCBmcm9tIHRoZSBzY2hlZHVsZWQgc3RhcnQgdGltZVxuXHRcdCAqICBAdHlwZSB7VGlja3N9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkV2ZW50I1xuXHRcdCAqICBAbmFtZSBzdGFydE9mZnNldFxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuRXZlbnQucHJvdG90eXBlLCAnc3RhcnRPZmZzZXQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdGFydE9mZnNldDtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKG9mZnNldCkge1xuXHQgICAgICAgICAgICB0aGlzLl9zdGFydE9mZnNldCA9IG9mZnNldDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgcHJvYmFiaWxpdHkgb2YgdGhlIG5vdGVzIGJlaW5nIHRyaWdnZXJlZC5cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuRXZlbnQjXG5cdFx0ICogIEB0eXBlIHtOb3JtYWxSYW5nZX1cblx0XHQgKiAgQG5hbWUgcHJvYmFiaWxpdHlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkV2ZW50LnByb3RvdHlwZSwgJ3Byb2JhYmlsaXR5Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fcHJvYmFiaWxpdHk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwcm9iKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3Byb2JhYmlsaXR5ID0gcHJvYjtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBJZiBzZXQgdG8gdHJ1ZSwgd2lsbCBhcHBseSBzbWFsbCByYW5kb20gdmFyaWF0aW9uXG5cdFx0ICogIHRvIHRoZSBjYWxsYmFjayB0aW1lLiBJZiB0aGUgdmFsdWUgaXMgZ2l2ZW4gYXMgYSB0aW1lLCBpdCB3aWxsIHJhbmRvbWl6ZVxuXHRcdCAqICBieSB0aGF0IGFtb3VudC5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBldmVudC5odW1hbml6ZSA9IHRydWU7XG5cdFx0ICogIEB0eXBlIHtCb29sZWFufFRpbWV9XG5cdFx0ICogIEBuYW1lIGh1bWFuaXplXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5FdmVudC5wcm90b3R5cGUsICdodW1hbml6ZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2h1bWFuaXplO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFyaWF0aW9uKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2h1bWFuaXplID0gdmFyaWF0aW9uO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFN0YXJ0IHRoZSBub3RlIGF0IHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lbGluZVBvc2l0aW9ufSAgdGltZSAgV2hlbiB0aGUgbm90ZSBzaG91bGQgc3RhcnQuXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLkV2ZW50fSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5FdmVudC5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvVGlja3ModGltZSk7XG5cdCAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpbWUpID09PSBUb25lLlN0YXRlLlN0b3BwZWQpIHtcblx0ICAgICAgICAgICAgdGhpcy5fc3RhdGUuYWRkKHtcblx0ICAgICAgICAgICAgICAgICdzdGF0ZSc6IFRvbmUuU3RhdGUuU3RhcnRlZCxcblx0ICAgICAgICAgICAgICAgICd0aW1lJzogdGltZSxcblx0ICAgICAgICAgICAgICAgICdpZCc6IHVuZGVmaW5lZFxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cyh0aW1lKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFN0b3AgdGhlIEV2ZW50IGF0IHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lbGluZVBvc2l0aW9ufSAgdGltZSAgV2hlbiB0aGUgbm90ZSBzaG91bGQgc3RvcC5cblx0XHQgKiAgQHJldHVybiAge1RvbmUuRXZlbnR9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkV2ZW50LnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLmNhbmNlbCh0aW1lKTtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuXHQgICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aW1lKSA9PT0gVG9uZS5TdGF0ZS5TdGFydGVkKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFRvbmUuU3RhdGUuU3RvcHBlZCwgdGltZSk7XG5cdCAgICAgICAgICAgIHZhciBwcmV2aW91c0V2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0QmVmb3JlKHRpbWUpO1xuXHQgICAgICAgICAgICB2YXIgcmVzY2hlZHVsVGltZSA9IHRpbWU7XG5cdCAgICAgICAgICAgIGlmIChwcmV2aW91c0V2ZW50ICE9PSBudWxsKSB7XG5cdCAgICAgICAgICAgICAgICByZXNjaGVkdWxUaW1lID0gcHJldmlvdXNFdmVudC50aW1lO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVFdmVudHMocmVzY2hlZHVsVGltZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDYW5jZWwgYWxsIHNjaGVkdWxlZCBldmVudHMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lXG5cdFx0ICogIEBwYXJhbSAge1RpbWVsaW5lUG9zaXRpb259ICBbdGltZT0wXSAgVGhlIHRpbWUgYWZ0ZXIgd2hpY2ggZXZlbnRzIHdpbGwgYmUgY2FuY2VsLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5FdmVudH0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuRXZlbnQucHJvdG90eXBlLmNhbmNlbCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IFRvbmUuZGVmYXVsdEFyZyh0aW1lLCAtSW5maW5pdHkpO1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvVGlja3ModGltZSk7XG5cdCAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaEZyb20odGltZSwgZnVuY3Rpb24gKGV2ZW50KSB7XG5cdCAgICAgICAgICAgIFRvbmUuVHJhbnNwb3J0LmNsZWFyKGV2ZW50LmlkKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBjYWxsYmFjayBmdW5jdGlvbiBpbnZva2VyLiBBbHNvXG5cdFx0ICogIGNoZWNrcyBpZiB0aGUgRXZlbnQgaXMgZG9uZSBwbGF5aW5nXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWUgIFRoZSB0aW1lIG9mIHRoZSBldmVudCBpbiBzZWNvbmRzXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkV2ZW50LnByb3RvdHlwZS5fdGljayA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdmFyIHRpY2tzID0gVG9uZS5UcmFuc3BvcnQuZ2V0VGlja3NBdFRpbWUodGltZSk7XG5cdCAgICAgICAgaWYgKCF0aGlzLm11dGUgJiYgdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGlja3MpID09PSBUb25lLlN0YXRlLlN0YXJ0ZWQpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMucHJvYmFiaWxpdHkgPCAxICYmIE1hdGgucmFuZG9tKCkgPiB0aGlzLnByb2JhYmlsaXR5KSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm47XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKHRoaXMuaHVtYW5pemUpIHtcblx0ICAgICAgICAgICAgICAgIHZhciB2YXJpYXRpb24gPSAwLjAyO1xuXHQgICAgICAgICAgICAgICAgaWYgKCFUb25lLmlzQm9vbGVhbih0aGlzLmh1bWFuaXplKSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhcmlhdGlvbiA9IHRoaXMudG9TZWNvbmRzKHRoaXMuaHVtYW5pemUpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgdGltZSArPSAoTWF0aC5yYW5kb20oKSAqIDIgLSAxKSAqIHZhcmlhdGlvbjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUsIHRoaXMudmFsdWUpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgR2V0IHRoZSBkdXJhdGlvbiBvZiB0aGUgbG9vcC5cblx0XHQgKiAgQHJldHVybiAge1RpY2tzfVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5FdmVudC5wcm90b3R5cGUuX2dldExvb3BEdXJhdGlvbiA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCgodGhpcy5fbG9vcEVuZCAtIHRoaXMuX2xvb3BTdGFydCkgLyB0aGlzLl9wbGF5YmFja1JhdGUpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBJZiB0aGUgbm90ZSBzaG91bGQgbG9vcCBvciBub3Rcblx0XHQgKiAgYmV0d2VlbiBUb25lLkV2ZW50Lmxvb3BTdGFydCBhbmRcblx0XHQgKiAgVG9uZS5FdmVudC5sb29wRW5kLiBBbiBpbnRlZ2VyXG5cdFx0ICogIHZhbHVlIGNvcnJlc3BvbmRzIHRvIHRoZSBudW1iZXIgb2Zcblx0XHQgKiAgbG9vcHMgdGhlIEV2ZW50IGRvZXMgYWZ0ZXIgaXQgc3RhcnRzLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5FdmVudCNcblx0XHQgKiAgQHR5cGUge0Jvb2xlYW58UG9zaXRpdmV9XG5cdFx0ICogIEBuYW1lIGxvb3Bcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkV2ZW50LnByb3RvdHlwZSwgJ2xvb3AnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb29wO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobG9vcCkge1xuXHQgICAgICAgICAgICB0aGlzLl9sb29wID0gbG9vcDtcblx0ICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cygpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogXHRUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgbm90ZS4gRGVmYXVsdHMgdG8gMS5cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuRXZlbnQjXG5cdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHQgKiAgQG5hbWUgcGxheWJhY2tSYXRlXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogbm90ZS5sb29wID0gdHJ1ZTtcblx0XHQgKiAvL3JlcGVhdCB0aGUgbm90ZSB0d2ljZSBhcyBmYXN0XG5cdFx0ICogbm90ZS5wbGF5YmFja1JhdGUgPSAyO1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuRXZlbnQucHJvdG90eXBlLCAncGxheWJhY2tSYXRlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocmF0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSByYXRlO1xuXHQgICAgICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGxvb3BFbmQgcG9pbnQgaXMgdGhlIHRpbWUgdGhlIGV2ZW50IHdpbGwgbG9vcFxuXHRcdCAqICBpZiBUb25lLkV2ZW50Lmxvb3AgaXMgdHJ1ZS5cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuRXZlbnQjXG5cdFx0ICogIEB0eXBlIHtUaW1lfVxuXHRcdCAqICBAbmFtZSBsb29wRW5kXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5FdmVudC5wcm90b3R5cGUsICdsb29wRW5kJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5UaWNrcyh0aGlzLl9sb29wRW5kKS50b1NlY29uZHMoKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGxvb3BFbmQpIHtcblx0ICAgICAgICAgICAgdGhpcy5fbG9vcEVuZCA9IHRoaXMudG9UaWNrcyhsb29wRW5kKTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVFdmVudHMoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSB0aW1lIHdoZW4gdGhlIGxvb3Agc2hvdWxkIHN0YXJ0LlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5FdmVudCNcblx0XHQgKiAgQHR5cGUge1RpbWV9XG5cdFx0ICogIEBuYW1lIGxvb3BTdGFydFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuRXZlbnQucHJvdG90eXBlLCAnbG9vcFN0YXJ0Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5UaWNrcyh0aGlzLl9sb29wU3RhcnQpLnRvU2Vjb25kcygpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobG9vcFN0YXJ0KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IHRoaXMudG9UaWNrcyhsb29wU3RhcnQpO1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cygpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGN1cnJlbnQgcHJvZ3Jlc3Mgb2YgdGhlIGxvb3AgaW50ZXJ2YWwuXG5cdFx0ICogIFJldHVybnMgMCBpZiB0aGUgZXZlbnQgaXMgbm90IHN0YXJ0ZWQgeWV0IG9yXG5cdFx0ICogIGl0IGlzIG5vdCBzZXQgdG8gbG9vcC5cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuRXZlbnQjXG5cdFx0ICogIEB0eXBlIHtOb3JtYWxSYW5nZX1cblx0XHQgKiAgQG5hbWUgcHJvZ3Jlc3Ncblx0XHQgKiAgQHJlYWRPbmx5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5FdmVudC5wcm90b3R5cGUsICdwcm9ncmVzcycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcblx0ICAgICAgICAgICAgICAgIHZhciB0aWNrcyA9IFRvbmUuVHJhbnNwb3J0LnRpY2tzO1xuXHQgICAgICAgICAgICAgICAgdmFyIGxhc3RFdmVudCA9IHRoaXMuX3N0YXRlLmdldCh0aWNrcyk7XG5cdCAgICAgICAgICAgICAgICBpZiAobGFzdEV2ZW50ICE9PSBudWxsICYmIGxhc3RFdmVudC5zdGF0ZSA9PT0gVG9uZS5TdGF0ZS5TdGFydGVkKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIGxvb3BEdXJhdGlvbiA9IHRoaXMuX2dldExvb3BEdXJhdGlvbigpO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBwcm9ncmVzcyA9ICh0aWNrcyAtIGxhc3RFdmVudC50aW1lKSAlIGxvb3BEdXJhdGlvbjtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJvZ3Jlc3MgLyBsb29wRHVyYXRpb247XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5FdmVudH0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuRXZlbnQucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5jYW5jZWwoKTtcblx0ICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuY2FsbGJhY2sgPSBudWxsO1xuXHQgICAgICAgIHRoaXMudmFsdWUgPSBudWxsO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkV2ZW50O1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuTG9vcCBjcmVhdGVzIGEgbG9vcGVkIGNhbGxiYWNrIGF0IHRoZSBcblx0XHQgKiAgICAgICAgIHNwZWNpZmllZCBpbnRlcnZhbC4gVGhlIGNhbGxiYWNrIGNhbiBiZSBcblx0XHQgKiAgICAgICAgIHN0YXJ0ZWQsIHN0b3BwZWQgYW5kIHNjaGVkdWxlZCBhbG9uZ1xuXHRcdCAqICAgICAgICAgdGhlIFRyYW5zcG9ydCdzIHRpbWVsaW5lLiBcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgbG9vcCA9IG5ldyBUb25lLkxvb3AoZnVuY3Rpb24odGltZSl7XG5cdFx0ICogXHQvL3RyaWdnZXJlZCBldmVyeSBlaWdodGggbm90ZS4gXG5cdFx0ICogXHRjb25zb2xlLmxvZyh0aW1lKTtcblx0XHQgKiB9LCBcIjhuXCIpLnN0YXJ0KDApO1xuXHRcdCAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG5cdFx0ICogIEBleHRlbmRzIHtUb25lfVxuXHRcdCAqICBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggdGhlIGV2ZW50LlxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IGludGVydmFsIFRoZSB0aW1lIGJldHdlZW4gc3VjY2Vzc2l2ZSBjYWxsYmFjayBjYWxscy4gXG5cdFx0ICovXG5cdCAgICBUb25lLkxvb3AgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAnY2FsbGJhY2snLFxuXHQgICAgICAgICAgICAnaW50ZXJ2YWwnXG5cdCAgICAgICAgXSwgVG9uZS5Mb29wKTtcblx0ICAgICAgICBUb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGV2ZW50IHdoaWNoIHByb2R1Y2VzIHRoZSBjYWxsYmFja3Ncblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2V2ZW50ID0gbmV3IFRvbmUuRXZlbnQoe1xuXHQgICAgICAgICAgICAnY2FsbGJhY2snOiB0aGlzLl90aWNrLmJpbmQodGhpcyksXG5cdCAgICAgICAgICAgICdsb29wJzogdHJ1ZSxcblx0ICAgICAgICAgICAgJ2xvb3BFbmQnOiBvcHRpb25zLmludGVydmFsLFxuXHQgICAgICAgICAgICAncGxheWJhY2tSYXRlJzogb3B0aW9ucy5wbGF5YmFja1JhdGUsXG5cdCAgICAgICAgICAgICdwcm9iYWJpbGl0eSc6IG9wdGlvbnMucHJvYmFiaWxpdHlcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggdGhlIG5leHQgZXZlbnQgaW4gdGhlIHBhdHRlcm5cblx0XHRcdCAqICBAdHlwZSB7RnVuY3Rpb259XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcblx0ICAgICAgICAvL3NldCB0aGUgaXRlcmF0aW9uc1xuXHQgICAgICAgIHRoaXMuaXRlcmF0aW9ucyA9IG9wdGlvbnMuaXRlcmF0aW9ucztcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkxvb3ApO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0c1xuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkxvb3AuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2ludGVydmFsJzogJzRuJyxcblx0ICAgICAgICAnY2FsbGJhY2snOiBUb25lLm5vT3AsXG5cdCAgICAgICAgJ3BsYXliYWNrUmF0ZSc6IDEsXG5cdCAgICAgICAgJ2l0ZXJhdGlvbnMnOiBJbmZpbml0eSxcblx0ICAgICAgICAncHJvYmFiaWxpdHknOiB0cnVlLFxuXHQgICAgICAgICdtdXRlJzogZmFsc2Vcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU3RhcnQgdGhlIGxvb3AgYXQgdGhlIHNwZWNpZmllZCB0aW1lIGFsb25nIHRoZSBUcmFuc3BvcnQnc1xuXHRcdCAqICB0aW1lbGluZS5cblx0XHQgKiAgQHBhcmFtICB7VGltZWxpbmVQb3NpdGlvbj19ICB0aW1lICBXaGVuIHRvIHN0YXJ0IHRoZSBMb29wLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5Mb29wfSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Mb29wLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGhpcy5fZXZlbnQuc3RhcnQodGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFN0b3AgdGhlIGxvb3AgYXQgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogIEBwYXJhbSAge1RpbWVsaW5lUG9zaXRpb249fSAgdGltZSAgV2hlbiB0byBzdG9wIHRoZSBBcnBlZ2dpb1xuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5Mb29wfSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Mb29wLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9ldmVudC5zdG9wKHRpbWUpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDYW5jZWwgYWxsIHNjaGVkdWxlZCBldmVudHMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lXG5cdFx0ICogIEBwYXJhbSAge1RpbWVsaW5lUG9zaXRpb259ICBbdGltZT0wXSAgVGhlIHRpbWUgYWZ0ZXIgd2hpY2ggZXZlbnRzIHdpbGwgYmUgY2FuY2VsLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5Mb29wfSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Mb29wLnByb3RvdHlwZS5jYW5jZWwgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRoaXMuX2V2ZW50LmNhbmNlbCh0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgSW50ZXJuYWwgZnVuY3Rpb24gY2FsbGVkIHdoZW4gdGhlIG5vdGVzIHNob3VsZCBiZSBjYWxsZWRcblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgdGltZSAgVGhlIHRpbWUgdGhlIGV2ZW50IG9jY3Vyc1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Mb29wLnByb3RvdHlwZS5fdGljayA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHN0YXRlIG9mIHRoZSBMb29wLCBlaXRoZXIgc3RhcnRlZCBvciBzdG9wcGVkLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5Mb29wI1xuXHRcdCAqICBAdHlwZSB7U3RyaW5nfVxuXHRcdCAqICBAbmFtZSBzdGF0ZVxuXHRcdCAqICBAcmVhZE9ubHlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkxvb3AucHJvdG90eXBlLCAnc3RhdGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5zdGF0ZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgcHJvZ3Jlc3Mgb2YgdGhlIGxvb3AgYXMgYSB2YWx1ZSBiZXR3ZWVuIDAtMS4gMCwgd2hlblxuXHRcdCAqICB0aGUgbG9vcCBpcyBzdG9wcGVkIG9yIGRvbmUgaXRlcmF0aW5nLiBcblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuTG9vcCNcblx0XHQgKiAgQHR5cGUge05vcm1hbFJhbmdlfVxuXHRcdCAqICBAbmFtZSBwcm9ncmVzc1xuXHRcdCAqICBAcmVhZE9ubHlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkxvb3AucHJvdG90eXBlLCAncHJvZ3Jlc3MnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5wcm9ncmVzcztcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgdGltZSBiZXR3ZWVuIHN1Y2Nlc3NpdmUgY2FsbGJhY2tzLiBcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBsb29wLmludGVydmFsID0gXCI4blwiOyAvL2xvb3AgZXZlcnkgOG5cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuTG9vcCNcblx0XHQgKiAgQHR5cGUge1RpbWV9XG5cdFx0ICogIEBuYW1lIGludGVydmFsXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5Mb29wLnByb3RvdHlwZSwgJ2ludGVydmFsJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQubG9vcEVuZDtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGludGVydmFsKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2V2ZW50Lmxvb3BFbmQgPSBpbnRlcnZhbDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgbG9vcC4gVGhlIG5vcm1hbCBwbGF5YmFjayByYXRlIGlzIDEgKG5vIGNoYW5nZSkuIFxuXHRcdCAqICBBIGBwbGF5YmFja1JhdGVgIG9mIDIgd291bGQgYmUgdHdpY2UgYXMgZmFzdC4gXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkxvb3AjXG5cdFx0ICogIEB0eXBlIHtUaW1lfVxuXHRcdCAqICBAbmFtZSBwbGF5YmFja1JhdGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkxvb3AucHJvdG90eXBlLCAncGxheWJhY2tSYXRlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQucGxheWJhY2tSYXRlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocmF0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9ldmVudC5wbGF5YmFja1JhdGUgPSByYXRlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFJhbmRvbSB2YXJpYXRpb24gKy8tMC4wMXMgdG8gdGhlIHNjaGVkdWxlZCB0aW1lLiBcblx0XHQgKiAgT3IgZ2l2ZSBpdCBhIHRpbWUgdmFsdWUgd2hpY2ggaXQgd2lsbCByYW5kb21pemUgYnkuXG5cdFx0ICogIEB0eXBlIHtCb29sZWFufFRpbWV9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkxvb3AjXG5cdFx0ICogIEBuYW1lIGh1bWFuaXplXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5Mb29wLnByb3RvdHlwZSwgJ2h1bWFuaXplJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQuaHVtYW5pemU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YXJpYXRpb24pIHtcblx0ICAgICAgICAgICAgdGhpcy5fZXZlbnQuaHVtYW5pemUgPSB2YXJpYXRpb247XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHByb2JhYmx5IG9mIHRoZSBjYWxsYmFjayBiZWluZyBpbnZva2VkLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5Mb29wI1xuXHRcdCAqICBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0ICogIEBuYW1lIHByb2JhYmlsaXR5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5Mb29wLnByb3RvdHlwZSwgJ3Byb2JhYmlsaXR5Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQucHJvYmFiaWxpdHk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwcm9iKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2V2ZW50LnByb2JhYmlsaXR5ID0gcHJvYjtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBNdXRpbmcgdGhlIExvb3AgbWVhbnMgdGhhdCBubyBjYWxsYmFja3MgYXJlIGludm9rZWQuXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLkxvb3AjXG5cdFx0ICogIEB0eXBlIHtCb29sZWFufVxuXHRcdCAqICBAbmFtZSBtdXRlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5Mb29wLnByb3RvdHlwZSwgJ211dGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5tdXRlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobXV0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9ldmVudC5tdXRlID0gbXV0ZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgb2YgdGhlIGxvb3AuIFRoZSBkZWZhdWx0XG5cdFx0ICogIHZhbHVlIGlzIEluZmluaXR5IChsb29wIGZvcmV2ZXIpLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5Mb29wI1xuXHRcdCAqICBAdHlwZSB7UG9zaXRpdmV9XG5cdFx0ICogIEBuYW1lIGl0ZXJhdGlvbnNcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkxvb3AucHJvdG90eXBlLCAnaXRlcmF0aW9ucycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX2V2ZW50Lmxvb3AgPT09IHRydWUpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBJbmZpbml0eTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5sb29wO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChpdGVycykge1xuXHQgICAgICAgICAgICBpZiAoaXRlcnMgPT09IEluZmluaXR5KSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9ldmVudC5sb29wID0gdHJ1ZTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50Lmxvb3AgPSBpdGVycztcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLkxvb3B9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkxvb3AucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fZXZlbnQuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2V2ZW50ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmNhbGxiYWNrID0gbnVsbDtcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5Mb29wO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5QYXJ0IGlzIGEgY29sbGVjdGlvbiBUb25lLkV2ZW50cyB3aGljaCBjYW4gYmVcblx0XHQgKiAgICAgICAgIHN0YXJ0ZWQvc3RvcHBlZCBhbmQgbG9vcGVkIGFzIGEgc2luZ2xlIHVuaXQuXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuRXZlbnR9XG5cdFx0ICogIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugb24gZWFjaCBldmVudFxuXHRcdCAqICBAcGFyYW0ge0FycmF5fSBldmVudHMgdGhlIGFycmF5IG9mIGV2ZW50c1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBwYXJ0ID0gbmV3IFRvbmUuUGFydChmdW5jdGlvbih0aW1lLCBub3RlKXtcblx0XHQgKiBcdC8vdGhlIG5vdGVzIGdpdmVuIGFzIHRoZSBzZWNvbmQgZWxlbWVudCBpbiB0aGUgYXJyYXlcblx0XHQgKiBcdC8vd2lsbCBiZSBwYXNzZWQgaW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudFxuXHRcdCAqIFx0c3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZSwgXCI4blwiLCB0aW1lKTtcblx0XHQgKiB9LCBbWzAsIFwiQzJcIl0sIFtcIjA6MlwiLCBcIkMzXCJdLCBbXCIwOjM6MlwiLCBcIkcyXCJdXSk7XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy91c2UgYW4gYXJyYXkgb2Ygb2JqZWN0cyBhcyBsb25nIGFzIHRoZSBvYmplY3QgaGFzIGEgXCJ0aW1lXCIgYXR0cmlidXRlXG5cdFx0ICogdmFyIHBhcnQgPSBuZXcgVG9uZS5QYXJ0KGZ1bmN0aW9uKHRpbWUsIHZhbHVlKXtcblx0XHQgKiBcdC8vdGhlIHZhbHVlIGlzIGFuIG9iamVjdCB3aGljaCBjb250YWlucyBib3RoIHRoZSBub3RlIGFuZCB0aGUgdmVsb2NpdHlcblx0XHQgKiBcdHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKHZhbHVlLm5vdGUsIFwiOG5cIiwgdGltZSwgdmFsdWUudmVsb2NpdHkpO1xuXHRcdCAqIH0sIFt7XCJ0aW1lXCIgOiAwLCBcIm5vdGVcIiA6IFwiQzNcIiwgXCJ2ZWxvY2l0eVwiOiAwLjl9LFxuXHRcdCAqIFx0ICAge1widGltZVwiIDogXCIwOjJcIiwgXCJub3RlXCIgOiBcIkM0XCIsIFwidmVsb2NpdHlcIjogMC41fVxuXHRcdCAqIF0pLnN0YXJ0KDApO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYXJ0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ2NhbGxiYWNrJyxcblx0ICAgICAgICAgICAgJ2V2ZW50cydcblx0ICAgICAgICBdLCBUb25lLlBhcnQpO1xuXHQgICAgICAgIFRvbmUuRXZlbnQuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBBbiBhcnJheSBvZiBPYmplY3RzLlxuXHRcdFx0ICogIEB0eXBlICB7QXJyYXl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2V2ZW50cyA9IFtdO1xuXHQgICAgICAgIC8vYWRkIHRoZSBldmVudHNcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9wdGlvbnMuZXZlbnRzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMuZXZlbnRzW2ldKSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5hZGQob3B0aW9ucy5ldmVudHNbaV1bMF0sIG9wdGlvbnMuZXZlbnRzW2ldWzFdKTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuYWRkKG9wdGlvbnMuZXZlbnRzW2ldKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlBhcnQsIFRvbmUuRXZlbnQpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0IHZhbHVlc1xuXHRcdCAqICBAdHlwZSAge09iamVjdH1cblx0XHQgKiAgQGNvbnN0XG5cdFx0ICovXG5cdCAgICBUb25lLlBhcnQuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2NhbGxiYWNrJzogVG9uZS5ub09wLFxuXHQgICAgICAgICdsb29wJzogZmFsc2UsXG5cdCAgICAgICAgJ2xvb3BFbmQnOiAnMW0nLFxuXHQgICAgICAgICdsb29wU3RhcnQnOiAwLFxuXHQgICAgICAgICdwbGF5YmFja1JhdGUnOiAxLFxuXHQgICAgICAgICdwcm9iYWJpbGl0eSc6IDEsXG5cdCAgICAgICAgJ2h1bWFuaXplJzogZmFsc2UsXG5cdCAgICAgICAgJ211dGUnOiBmYWxzZSxcblx0ICAgICAgICAnZXZlbnRzJzogW11cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU3RhcnQgdGhlIHBhcnQgYXQgdGhlIGdpdmVuIHRpbWUuXG5cdFx0ICogIEBwYXJhbSAge1RyYW5zcG9ydFRpbWV9ICB0aW1lICAgIFdoZW4gdG8gc3RhcnQgdGhlIHBhcnQuXG5cdFx0ICogIEBwYXJhbSAge1RpbWU9fSAgb2Zmc2V0ICBUaGUgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBwYXJ0XG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICB0byBiZWdpbiBwbGF5aW5nIGF0LlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5QYXJ0fSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYXJ0LnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICh0aW1lLCBvZmZzZXQpIHtcblx0ICAgICAgICB2YXIgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG5cdCAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpY2tzKSAhPT0gVG9uZS5TdGF0ZS5TdGFydGVkKSB7XG5cdCAgICAgICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG5cdCAgICAgICAgICAgICAgICBvZmZzZXQgPSBUb25lLmRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLl9sb29wU3RhcnQpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgb2Zmc2V0ID0gVG9uZS5kZWZhdWx0QXJnKG9mZnNldCwgMCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgb2Zmc2V0ID0gdGhpcy50b1RpY2tzKG9mZnNldCk7XG5cdCAgICAgICAgICAgIHRoaXMuX3N0YXRlLmFkZCh7XG5cdCAgICAgICAgICAgICAgICAnc3RhdGUnOiBUb25lLlN0YXRlLlN0YXJ0ZWQsXG5cdCAgICAgICAgICAgICAgICAndGltZSc6IHRpY2tzLFxuXHQgICAgICAgICAgICAgICAgJ29mZnNldCc6IG9mZnNldFxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0Tm90ZShldmVudCwgdGlja3MsIG9mZnNldCk7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU3RhcnQgdGhlIGV2ZW50IGluIHRoZSBnaXZlbiBldmVudCBhdCB0aGUgY29ycmVjdCB0aW1lIGdpdmVuXG5cdFx0ICogIHRoZSB0aWNrcyBhbmQgb2Zmc2V0IGFuZCBsb29waW5nLlxuXHRcdCAqICBAcGFyYW0gIHtUb25lLkV2ZW50fSAgZXZlbnRcblx0XHQgKiAgQHBhcmFtICB7VGlja3N9ICB0aWNrc1xuXHRcdCAqICBAcGFyYW0gIHtUaWNrc30gIG9mZnNldFxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QYXJ0LnByb3RvdHlwZS5fc3RhcnROb3RlID0gZnVuY3Rpb24gKGV2ZW50LCB0aWNrcywgb2Zmc2V0KSB7XG5cdCAgICAgICAgdGlja3MgLT0gb2Zmc2V0O1xuXHQgICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG5cdCAgICAgICAgICAgIGlmIChldmVudC5zdGFydE9mZnNldCA+PSB0aGlzLl9sb29wU3RhcnQgJiYgZXZlbnQuc3RhcnRPZmZzZXQgPCB0aGlzLl9sb29wRW5kKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAvL3N0YXJ0IGl0IG9uIHRoZSBuZXh0IGxvb3Bcblx0ICAgICAgICAgICAgICAgICAgICB0aWNrcyArPSB0aGlzLl9nZXRMb29wRHVyYXRpb24oKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGV2ZW50LnN0YXJ0KFRvbmUuVGlja3ModGlja3MpKTtcblx0ICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudC5zdGFydE9mZnNldCA8IHRoaXMuX2xvb3BTdGFydCAmJiBldmVudC5zdGFydE9mZnNldCA+PSBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgICAgIGV2ZW50Lmxvb3AgPSBmYWxzZTtcblx0ICAgICAgICAgICAgICAgIGV2ZW50LnN0YXJ0KFRvbmUuVGlja3ModGlja3MpKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPj0gb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIGV2ZW50LnN0YXJ0KFRvbmUuVGlja3ModGlja3MpKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBzdGFydCBmcm9tIHRoZSBzY2hlZHVsZWQgc3RhcnQgdGltZVxuXHRcdCAqICBAdHlwZSB7VGlja3N9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlBhcnQjXG5cdFx0ICogIEBuYW1lIHN0YXJ0T2Zmc2V0XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QYXJ0LnByb3RvdHlwZSwgJ3N0YXJ0T2Zmc2V0Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhcnRPZmZzZXQ7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChvZmZzZXQpIHtcblx0ICAgICAgICAgICAgdGhpcy5fc3RhcnRPZmZzZXQgPSBvZmZzZXQ7XG5cdCAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG5cdCAgICAgICAgICAgICAgICBldmVudC5zdGFydE9mZnNldCArPSB0aGlzLl9zdGFydE9mZnNldDtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgU3RvcCB0aGUgcGFydCBhdCB0aGUgZ2l2ZW4gdGltZS5cblx0XHQgKiAgQHBhcmFtICB7VGltZWxpbmVQb3NpdGlvbn0gIHRpbWUgIFdoZW4gdG8gc3RvcCB0aGUgcGFydC5cblx0XHQgKiAgQHJldHVybiAge1RvbmUuUGFydH0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFydC5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdmFyIHRpY2tzID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuXHQgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aWNrcyk7XG5cdCAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoVG9uZS5TdGF0ZS5TdG9wcGVkLCB0aWNrcyk7XG5cdCAgICAgICAgdGhpcy5fZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcblx0ICAgICAgICAgICAgZXZlbnQuc3RvcCh0aW1lKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgR2V0L1NldCBhbiBFdmVudCdzIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqICBJZiBhIHZhbHVlIGlzIHBhc3NlZCBpbiBhbmQgbm8gZXZlbnQgZXhpc3RzIGF0XG5cdFx0ICogIHRoZSBnaXZlbiB0aW1lLCBvbmUgd2lsbCBiZSBjcmVhdGVkIHdpdGggdGhhdCB2YWx1ZS5cblx0XHQgKiAgSWYgdHdvIGV2ZW50cyBhcmUgYXQgdGhlIHNhbWUgdGltZSwgdGhlIGZpcnN0IG9uZSB3aWxsXG5cdFx0ICogIGJlIHJldHVybmVkLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHBhcnQuYXQoXCIxbVwiKTsgLy9yZXR1cm5zIHRoZSBwYXJ0IGF0IHRoZSBmaXJzdCBtZWFzdXJlXG5cdFx0ICpcblx0XHQgKiBwYXJ0LmF0KFwiMm1cIiwgXCJDMlwiKTsgLy9zZXQgdGhlIHZhbHVlIGF0IFwiMm1cIiB0byBDMi5cblx0XHQgKiAvL2lmIGFuIGV2ZW50IGRpZG4ndCBleGlzdCBhdCB0aGF0IHRpbWUsIGl0IHdpbGwgYmUgY3JlYXRlZC5cblx0XHQgKiAgQHBhcmFtIHtUcmFuc3BvcnRUaW1lfSB0aW1lIFRoZSB0aW1lIG9mIHRoZSBldmVudCB0byBnZXQgb3Igc2V0LlxuXHRcdCAqICBAcGFyYW0geyo9fSB2YWx1ZSBJZiBhIHZhbHVlIGlzIHBhc3NlZCBpbiwgdGhlIHZhbHVlIG9mIHRoZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICBldmVudCBhdCB0aGUgZ2l2ZW4gdGltZSB3aWxsIGJlIHNldCB0byBpdC5cblx0XHQgKiAgQHJldHVybiB7VG9uZS5FdmVudH0gdGhlIGV2ZW50IGF0IHRoZSB0aW1lXG5cdFx0ICovXG5cdCAgICBUb25lLlBhcnQucHJvdG90eXBlLmF0ID0gZnVuY3Rpb24gKHRpbWUsIHZhbHVlKSB7XG5cdCAgICAgICAgdGltZSA9IFRvbmUuVHJhbnNwb3J0VGltZSh0aW1lKTtcblx0ICAgICAgICB2YXIgdGlja1RpbWUgPSBUb25lLlRpY2tzKDEpLnRvU2Vjb25kcygpO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fZXZlbnRzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgIHZhciBldmVudCA9IHRoaXMuX2V2ZW50c1tpXTtcblx0ICAgICAgICAgICAgaWYgKE1hdGguYWJzKHRpbWUudG9UaWNrcygpIC0gZXZlbnQuc3RhcnRPZmZzZXQpIDwgdGlja1RpbWUpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChUb25lLmlzRGVmaW5lZCh2YWx1ZSkpIHtcblx0ICAgICAgICAgICAgICAgICAgICBldmVudC52YWx1ZSA9IHZhbHVlO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vaWYgdGhlcmUgd2FzIG5vIGV2ZW50IGF0IHRoYXQgdGltZSwgY3JlYXRlIG9uZVxuXHQgICAgICAgIGlmIChUb25lLmlzRGVmaW5lZCh2YWx1ZSkpIHtcblx0ICAgICAgICAgICAgdGhpcy5hZGQodGltZSwgdmFsdWUpO1xuXHQgICAgICAgICAgICAvL3JldHVybiB0aGUgbmV3IGV2ZW50XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9ldmVudHNbdGhpcy5fZXZlbnRzLmxlbmd0aCAtIDFdO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHJldHVybiBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQWRkIGEgYW4gZXZlbnQgdG8gdGhlIHBhcnQuXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gdGltZSBUaGUgdGltZSB0aGUgbm90ZSBzaG91bGQgc3RhcnQuXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYgYW4gb2JqZWN0IGlzIHBhc3NlZCBpbiwgaXQgc2hvdWxkXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGF2ZSBhICd0aW1lJyBhdHRyaWJ1dGUgYW5kIHRoZSByZXN0XG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2YgdGhlIG9iamVjdCB3aWxsIGJlIHVzZWQgYXMgdGhlICd2YWx1ZScuXG5cdFx0ICogIEBwYXJhbSAge1RvbmUuRXZlbnR8Kn0gIHZhbHVlXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBhcnR9IHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBwYXJ0LmFkZChcIjFtXCIsIFwiQyMrMTFcIik7XG5cdFx0ICovXG5cdCAgICBUb25lLlBhcnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uICh0aW1lLCB2YWx1ZSkge1xuXHQgICAgICAgIC8vZXh0cmFjdCB0aGUgcGFyYW1ldGVyc1xuXHQgICAgICAgIGlmICh0aW1lLmhhc093blByb3BlcnR5KCd0aW1lJykpIHtcblx0ICAgICAgICAgICAgdmFsdWUgPSB0aW1lO1xuXHQgICAgICAgICAgICB0aW1lID0gdmFsdWUudGltZTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9UaWNrcyh0aW1lKTtcblx0ICAgICAgICB2YXIgZXZlbnQ7XG5cdCAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgVG9uZS5FdmVudCkge1xuXHQgICAgICAgICAgICBldmVudCA9IHZhbHVlO1xuXHQgICAgICAgICAgICBldmVudC5jYWxsYmFjayA9IHRoaXMuX3RpY2suYmluZCh0aGlzKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBldmVudCA9IG5ldyBUb25lLkV2ZW50KHtcblx0ICAgICAgICAgICAgICAgICdjYWxsYmFjayc6IHRoaXMuX3RpY2suYmluZCh0aGlzKSxcblx0ICAgICAgICAgICAgICAgICd2YWx1ZSc6IHZhbHVlXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL3RoZSBzdGFydCBvZmZzZXRcblx0ICAgICAgICBldmVudC5zdGFydE9mZnNldCA9IHRpbWU7XG5cdCAgICAgICAgLy9pbml0aWFsaXplIHRoZSB2YWx1ZXNcblx0ICAgICAgICBldmVudC5zZXQoe1xuXHQgICAgICAgICAgICAnbG9vcEVuZCc6IHRoaXMubG9vcEVuZCxcblx0ICAgICAgICAgICAgJ2xvb3BTdGFydCc6IHRoaXMubG9vcFN0YXJ0LFxuXHQgICAgICAgICAgICAnbG9vcCc6IHRoaXMubG9vcCxcblx0ICAgICAgICAgICAgJ2h1bWFuaXplJzogdGhpcy5odW1hbml6ZSxcblx0ICAgICAgICAgICAgJ3BsYXliYWNrUmF0ZSc6IHRoaXMucGxheWJhY2tSYXRlLFxuXHQgICAgICAgICAgICAncHJvYmFiaWxpdHknOiB0aGlzLnByb2JhYmlsaXR5XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdGhpcy5fZXZlbnRzLnB1c2goZXZlbnQpO1xuXHQgICAgICAgIC8vc3RhcnQgdGhlIG5vdGUgaWYgaXQgc2hvdWxkIGJlIHBsYXllZCByaWdodCBub3dcblx0ICAgICAgICB0aGlzLl9yZXN0YXJ0RXZlbnQoZXZlbnQpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZXN0YXJ0IHRoZSBnaXZlbiBldmVudFxuXHRcdCAqICBAcGFyYW0gIHtUb25lLkV2ZW50fSAgZXZlbnRcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFydC5wcm90b3R5cGUuX3Jlc3RhcnRFdmVudCA9IGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2goZnVuY3Rpb24gKHN0YXRlRXZlbnQpIHtcblx0ICAgICAgICAgICAgaWYgKHN0YXRlRXZlbnQuc3RhdGUgPT09IFRvbmUuU3RhdGUuU3RhcnRlZCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnROb3RlKGV2ZW50LCBzdGF0ZUV2ZW50LnRpbWUsIHN0YXRlRXZlbnQub2Zmc2V0KTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIC8vc3RvcCB0aGUgbm90ZVxuXHQgICAgICAgICAgICAgICAgZXZlbnQuc3RvcChUb25lLlRpY2tzKHN0YXRlRXZlbnQudGltZSkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmVtb3ZlIGFuIGV2ZW50IGZyb20gdGhlIHBhcnQuIFdpbGwgcmVjdXJzaXZlbHkgaXRlcmF0ZVxuXHRcdCAqICBpbnRvIG5lc3RlZCBwYXJ0cyB0byBmaW5kIHRoZSBldmVudC5cblx0XHQgKiAgQHBhcmFtIHtUaW1lfSB0aW1lIFRoZSB0aW1lIG9mIHRoZSBldmVudFxuXHRcdCAqICBAcGFyYW0geyp9IHZhbHVlIE9wdGlvbmFsbHkgc2VsZWN0IG9ubHkgYSBzcGVjaWZpYyBldmVudCB2YWx1ZVxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5QYXJ0fSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYXJ0LnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAodGltZSwgdmFsdWUpIHtcblx0ICAgICAgICAvL2V4dHJhY3QgdGhlIHBhcmFtZXRlcnNcblx0ICAgICAgICBpZiAodGltZS5oYXNPd25Qcm9wZXJ0eSgndGltZScpKSB7XG5cdCAgICAgICAgICAgIHZhbHVlID0gdGltZTtcblx0ICAgICAgICAgICAgdGltZSA9IHZhbHVlLnRpbWU7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvVGlja3ModGltZSk7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IHRoaXMuX2V2ZW50cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuXHQgICAgICAgICAgICB2YXIgZXZlbnQgPSB0aGlzLl9ldmVudHNbaV07XG5cdCAgICAgICAgICAgIGlmIChldmVudCBpbnN0YW5jZW9mIFRvbmUuUGFydCkge1xuXHQgICAgICAgICAgICAgICAgZXZlbnQucmVtb3ZlKHRpbWUsIHZhbHVlKTtcblx0ICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudC5zdGFydE9mZnNldCA9PT0gdGltZSkge1xuXHQgICAgICAgICAgICAgICAgaWYgKFRvbmUuaXNVbmRlZih2YWx1ZSkgfHwgVG9uZS5pc0RlZmluZWQodmFsdWUpICYmIGV2ZW50LnZhbHVlID09PSB2YWx1ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5zcGxpY2UoaSwgMSk7XG5cdCAgICAgICAgICAgICAgICAgICAgZXZlbnQuZGlzcG9zZSgpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBSZW1vdmUgYWxsIG9mIHRoZSBub3RlcyBmcm9tIHRoZSBncm91cC5cblx0XHQgKiAgQHJldHVybiAge1RvbmUuUGFydH0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFydC5wcm90b3R5cGUucmVtb3ZlQWxsID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuX2ZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG5cdCAgICAgICAgICAgIGV2ZW50LmRpc3Bvc2UoKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0aGlzLl9ldmVudHMgPSBbXTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2FuY2VsIHNjaGVkdWxlZCBzdGF0ZSBjaGFuZ2UgZXZlbnRzOiBpLmUuIFwic3RhcnRcIiBhbmQgXCJzdG9wXCIuXG5cdFx0ICogIEBwYXJhbSB7VGltZWxpbmVQb3NpdGlvbn0gYWZ0ZXIgVGhlIHRpbWUgYWZ0ZXIgd2hpY2ggdG8gY2FuY2VsIHRoZSBzY2hlZHVsZWQgZXZlbnRzLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5QYXJ0fSAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QYXJ0LnByb3RvdHlwZS5jYW5jZWwgPSBmdW5jdGlvbiAoYWZ0ZXIpIHtcblx0ICAgICAgICB0aGlzLl9mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgICAgICBldmVudC5jYW5jZWwoYWZ0ZXIpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aGlzLnRvVGlja3MoYWZ0ZXIpKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgSXRlcmF0ZSBvdmVyIGFsbCBvZiB0aGUgZXZlbnRzXG5cdFx0ICogIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG5cdFx0ICogIEBwYXJhbSB7T2JqZWN0fSBjdHggVGhlIGNvbnRleHRcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFydC5wcm90b3R5cGUuX2ZvckVhY2ggPSBmdW5jdGlvbiAoY2FsbGJhY2ssIGN0eCkge1xuXHQgICAgICAgIGlmICh0aGlzLl9ldmVudHMpIHtcblx0ICAgICAgICAgICAgY3R4ID0gVG9uZS5kZWZhdWx0QXJnKGN0eCwgdGhpcyk7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSB0aGlzLl9ldmVudHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcblx0ICAgICAgICAgICAgICAgIHZhciBlID0gdGhpcy5fZXZlbnRzW2ldO1xuXHQgICAgICAgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBUb25lLlBhcnQpIHtcblx0ICAgICAgICAgICAgICAgICAgICBlLl9mb3JFYWNoKGNhbGxiYWNrLCBjdHgpO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKGN0eCwgZSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFNldCB0aGUgYXR0cmlidXRlIG9mIGFsbCBvZiB0aGUgZXZlbnRzXG5cdFx0ICogIEBwYXJhbSAge1N0cmluZ30gIGF0dHIgIHRoZSBhdHRyaWJ1dGUgdG8gc2V0XG5cdFx0ICogIEBwYXJhbSAgeyp9ICB2YWx1ZSAgICAgIFRoZSB2YWx1ZSB0byBzZXQgaXQgdG9cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFydC5wcm90b3R5cGUuX3NldEFsbCA9IGZ1bmN0aW9uIChhdHRyLCB2YWx1ZSkge1xuXHQgICAgICAgIHRoaXMuX2ZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG5cdCAgICAgICAgICAgIGV2ZW50W2F0dHJdID0gdmFsdWU7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEludGVybmFsIHRpY2sgbWV0aG9kXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWUgIFRoZSB0aW1lIG9mIHRoZSBldmVudCBpbiBzZWNvbmRzXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlBhcnQucHJvdG90eXBlLl90aWNrID0gZnVuY3Rpb24gKHRpbWUsIHZhbHVlKSB7XG5cdCAgICAgICAgaWYgKCF0aGlzLm11dGUpIHtcblx0ICAgICAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lLCB2YWx1ZSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBEZXRlcm1pbmUgaWYgdGhlIGV2ZW50IHNob3VsZCBiZSBjdXJyZW50bHkgbG9vcGluZ1xuXHRcdCAqICBnaXZlbiB0aGUgbG9vcCBib3VuZHJpZXMgb2YgdGhpcyBQYXJ0LlxuXHRcdCAqICBAcGFyYW0gIHtUb25lLkV2ZW50fSAgZXZlbnQgIFRoZSBldmVudCB0byB0ZXN0XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlBhcnQucHJvdG90eXBlLl90ZXN0TG9vcEJvdW5kcmllcyA9IGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgIGlmIChldmVudC5zdGFydE9mZnNldCA8IHRoaXMuX2xvb3BTdGFydCB8fCBldmVudC5zdGFydE9mZnNldCA+PSB0aGlzLl9sb29wRW5kKSB7XG5cdCAgICAgICAgICAgIGV2ZW50LmNhbmNlbCgwKTtcblx0ICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnN0YXRlID09PSBUb25lLlN0YXRlLlN0b3BwZWQpIHtcblx0ICAgICAgICAgICAgLy9yZXNjaGVkdWxlIGl0IGlmIGl0J3Mgc3RvcHBlZFxuXHQgICAgICAgICAgICB0aGlzLl9yZXN0YXJ0RXZlbnQoZXZlbnQpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHByb2JhYmlsaXR5IG9mIHRoZSBub3RlcyBiZWluZyB0cmlnZ2VyZWQuXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlBhcnQjXG5cdFx0ICogIEB0eXBlIHtOb3JtYWxSYW5nZX1cblx0XHQgKiAgQG5hbWUgcHJvYmFiaWxpdHlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBhcnQucHJvdG90eXBlLCAncHJvYmFiaWxpdHknLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9wcm9iYWJpbGl0eTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHByb2IpIHtcblx0ICAgICAgICAgICAgdGhpcy5fcHJvYmFiaWxpdHkgPSBwcm9iO1xuXHQgICAgICAgICAgICB0aGlzLl9zZXRBbGwoJ3Byb2JhYmlsaXR5JywgcHJvYik7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgSWYgc2V0IHRvIHRydWUsIHdpbGwgYXBwbHkgc21hbGwgcmFuZG9tIHZhcmlhdGlvblxuXHRcdCAqICB0byB0aGUgY2FsbGJhY2sgdGltZS4gSWYgdGhlIHZhbHVlIGlzIGdpdmVuIGFzIGEgdGltZSwgaXQgd2lsbCByYW5kb21pemVcblx0XHQgKiAgYnkgdGhhdCBhbW91bnQuXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogZXZlbnQuaHVtYW5pemUgPSB0cnVlO1xuXHRcdCAqICBAdHlwZSB7Qm9vbGVhbnxUaW1lfVxuXHRcdCAqICBAbmFtZSBodW1hbml6ZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGFydC5wcm90b3R5cGUsICdodW1hbml6ZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2h1bWFuaXplO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFyaWF0aW9uKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2h1bWFuaXplID0gdmFyaWF0aW9uO1xuXHQgICAgICAgICAgICB0aGlzLl9zZXRBbGwoJ2h1bWFuaXplJywgdmFyaWF0aW9uKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBJZiB0aGUgcGFydCBzaG91bGQgbG9vcCBvciBub3Rcblx0XHQgKiAgYmV0d2VlbiBUb25lLlBhcnQubG9vcFN0YXJ0IGFuZFxuXHRcdCAqICBUb25lLlBhcnQubG9vcEVuZC4gQW4gaW50ZWdlclxuXHRcdCAqICB2YWx1ZSBjb3JyZXNwb25kcyB0byB0aGUgbnVtYmVyIG9mXG5cdFx0ICogIGxvb3BzIHRoZSBQYXJ0IGRvZXMgYWZ0ZXIgaXQgc3RhcnRzLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5QYXJ0I1xuXHRcdCAqICBAdHlwZSB7Qm9vbGVhbnxQb3NpdGl2ZX1cblx0XHQgKiAgQG5hbWUgbG9vcFxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vbG9vcCB0aGUgcGFydCA4IHRpbWVzXG5cdFx0ICogcGFydC5sb29wID0gODtcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBhcnQucHJvdG90eXBlLCAnbG9vcCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3A7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChsb29wKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2xvb3AgPSBsb29wO1xuXHQgICAgICAgICAgICB0aGlzLl9mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAgICAgICAgICAgZXZlbnQuX2xvb3BTdGFydCA9IHRoaXMuX2xvb3BTdGFydDtcblx0ICAgICAgICAgICAgICAgIGV2ZW50Ll9sb29wRW5kID0gdGhpcy5fbG9vcEVuZDtcblx0ICAgICAgICAgICAgICAgIGV2ZW50Lmxvb3AgPSBsb29wO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fdGVzdExvb3BCb3VuZHJpZXMoZXZlbnQpO1xuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgbG9vcEVuZCBwb2ludCBkZXRlcm1pbmVzIHdoZW4gaXQgd2lsbFxuXHRcdCAqICBsb29wIGlmIFRvbmUuUGFydC5sb29wIGlzIHRydWUuXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlBhcnQjXG5cdFx0ICogIEB0eXBlIHtUaW1lfVxuXHRcdCAqICBAbmFtZSBsb29wRW5kXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QYXJ0LnByb3RvdHlwZSwgJ2xvb3BFbmQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBUb25lLlRpY2tzKHRoaXMuX2xvb3BFbmQpLnRvU2Vjb25kcygpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobG9vcEVuZCkge1xuXHQgICAgICAgICAgICB0aGlzLl9sb29wRW5kID0gdGhpcy50b1RpY2tzKGxvb3BFbmQpO1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcblx0ICAgICAgICAgICAgICAgICAgICBldmVudC5sb29wRW5kID0gbG9vcEVuZDtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl90ZXN0TG9vcEJvdW5kcmllcyhldmVudCk7XG5cdCAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBsb29wU3RhcnQgcG9pbnQgZGV0ZXJtaW5lcyB3aGVuIGl0IHdpbGxcblx0XHQgKiAgbG9vcCBpZiBUb25lLlBhcnQubG9vcCBpcyB0cnVlLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5QYXJ0I1xuXHRcdCAqICBAdHlwZSB7VGltZX1cblx0XHQgKiAgQG5hbWUgbG9vcFN0YXJ0XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QYXJ0LnByb3RvdHlwZSwgJ2xvb3BTdGFydCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIFRvbmUuVGlja3ModGhpcy5fbG9vcFN0YXJ0KS50b1NlY29uZHMoKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGxvb3BTdGFydCkge1xuXHQgICAgICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSB0aGlzLnRvVGlja3MobG9vcFN0YXJ0KTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgZXZlbnQubG9vcFN0YXJ0ID0gdGhpcy5sb29wU3RhcnQ7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGVzdExvb3BCb3VuZHJpZXMoZXZlbnQpO1xuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFx0VGhlIHBsYXliYWNrIHJhdGUgb2YgdGhlIHBhcnRcblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuUGFydCNcblx0XHQgKiAgQHR5cGUge1Bvc2l0aXZlfVxuXHRcdCAqICBAbmFtZSBwbGF5YmFja1JhdGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBhcnQucHJvdG90eXBlLCAncGxheWJhY2tSYXRlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocmF0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSByYXRlO1xuXHQgICAgICAgICAgICB0aGlzLl9zZXRBbGwoJ3BsYXliYWNrUmF0ZScsIHJhdGUpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogXHRUaGUgbnVtYmVyIG9mIHNjaGVkdWxlZCBub3RlcyBpbiB0aGUgcGFydC5cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuUGFydCNcblx0XHQgKiAgQHR5cGUge1Bvc2l0aXZlfVxuXHRcdCAqICBAbmFtZSBsZW5ndGhcblx0XHQgKiAgQHJlYWRPbmx5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QYXJ0LnByb3RvdHlwZSwgJ2xlbmd0aCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50cy5sZW5ndGg7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXBcblx0XHQgKiAgQHJldHVybiAge1RvbmUuUGFydH0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGFydC5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB0aGlzLnJlbW92ZUFsbCgpO1xuXHQgICAgICAgIHRoaXMuX3N0YXRlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5jYWxsYmFjayA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fZXZlbnRzID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5QYXJ0O1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuUGF0dGVybiBhcnBlZ2dpYXRlcyBiZXR3ZWVuIHRoZSBnaXZlbiBub3Rlc1xuXHRcdCAqICAgICAgICAgaW4gYSBudW1iZXIgb2YgcGF0dGVybnMuIFNlZSBUb25lLkN0cmxQYXR0ZXJuIGZvclxuXHRcdCAqICAgICAgICAgYSBmdWxsIGxpc3Qgb2YgcGF0dGVybnMuXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHBhdHRlcm4gPSBuZXcgVG9uZS5QYXR0ZXJuKGZ1bmN0aW9uKHRpbWUsIG5vdGUpe1xuXHRcdCAqICAgLy90aGUgb3JkZXIgb2YgdGhlIG5vdGVzIHBhc3NlZCBpbiBkZXBlbmRzIG9uIHRoZSBwYXR0ZXJuXG5cdFx0ICogfSwgW1wiQzJcIiwgXCJENFwiLCBcIkU1XCIsIFwiQTZcIl0sIFwidXBEb3duXCIpO1xuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5Mb29wfVxuXHRcdCAqICBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggdGhlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LlxuXHRcdCAqICBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byBhcnBlZ2dpYXRlIG92ZXIuXG5cdFx0ICovXG5cdCAgICBUb25lLlBhdHRlcm4gPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAnY2FsbGJhY2snLFxuXHQgICAgICAgICAgICAndmFsdWVzJyxcblx0ICAgICAgICAgICAgJ3BhdHRlcm4nXG5cdCAgICAgICAgXSwgVG9uZS5QYXR0ZXJuKTtcblx0ICAgICAgICBUb25lLkxvb3AuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgcGF0dGVybiBtYW5hZ2VyXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQ3RybFBhdHRlcm59XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3BhdHRlcm4gPSBuZXcgVG9uZS5DdHJsUGF0dGVybih7XG5cdCAgICAgICAgICAgICd2YWx1ZXMnOiBvcHRpb25zLnZhbHVlcyxcblx0ICAgICAgICAgICAgJ3R5cGUnOiBvcHRpb25zLnBhdHRlcm4sXG5cdCAgICAgICAgICAgICdpbmRleCc6IG9wdGlvbnMuaW5kZXhcblx0ICAgICAgICB9KTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlBhdHRlcm4sIFRvbmUuTG9vcCk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGRlZmF1bHRzXG5cdFx0ICogIEBjb25zdFxuXHRcdCAqICBAdHlwZSAge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuUGF0dGVybi5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAncGF0dGVybic6IFRvbmUuQ3RybFBhdHRlcm4uVHlwZS5VcCxcblx0ICAgICAgICAnY2FsbGJhY2snOiBUb25lLm5vT3AsXG5cdCAgICAgICAgJ3ZhbHVlcyc6IFtdXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEludGVybmFsIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIHRoZSBub3RlcyBzaG91bGQgYmUgY2FsbGVkXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIHRpbWUgIFRoZSB0aW1lIHRoZSBldmVudCBvY2N1cnNcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuUGF0dGVybi5wcm90b3R5cGUuX3RpY2sgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSwgdGhpcy5fcGF0dGVybi52YWx1ZSk7XG5cdCAgICAgICAgdGhpcy5fcGF0dGVybi5uZXh0KCk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBjdXJyZW50IGluZGV4IGluIHRoZSB2YWx1ZXMgYXJyYXkuXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlBhdHRlcm4jXG5cdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHQgKiAgQG5hbWUgaW5kZXhcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBhdHRlcm4ucHJvdG90eXBlLCAnaW5kZXgnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYXR0ZXJuLmluZGV4O1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoaSkge1xuXHQgICAgICAgICAgICB0aGlzLl9wYXR0ZXJuLmluZGV4ID0gaTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgYXJyYXkgb2YgZXZlbnRzLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5QYXR0ZXJuI1xuXHRcdCAqICBAdHlwZSB7QXJyYXl9XG5cdFx0ICogIEBuYW1lIHZhbHVlc1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGF0dGVybi5wcm90b3R5cGUsICd2YWx1ZXMnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYXR0ZXJuLnZhbHVlcztcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHMpIHtcblx0ICAgICAgICAgICAgdGhpcy5fcGF0dGVybi52YWx1ZXMgPSB2YWxzO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBwYXR0ZXJuLlxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5QYXR0ZXJuI1xuXHRcdCAqICBAdHlwZSB7Kn1cblx0XHQgKiAgQG5hbWUgdmFsdWVcblx0XHQgKiAgQHJlYWRPbmx5XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QYXR0ZXJuLnByb3RvdHlwZSwgJ3ZhbHVlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fcGF0dGVybi52YWx1ZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgcGF0dGVybiB0eXBlLiBTZWUgVG9uZS5DdHJsUGF0dGVybiBmb3IgdGhlIGZ1bGwgbGlzdCBvZiBwYXR0ZXJucy5cblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuUGF0dGVybiNcblx0XHQgKiAgQHR5cGUge1N0cmluZ31cblx0XHQgKiAgQG5hbWUgcGF0dGVyblxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGF0dGVybi5wcm90b3R5cGUsICdwYXR0ZXJuJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fcGF0dGVybi50eXBlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocGF0dGVybikge1xuXHQgICAgICAgICAgICB0aGlzLl9wYXR0ZXJuLnR5cGUgPSBwYXR0ZXJuO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLlBhdHRlcm59ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlBhdHRlcm4ucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5Mb29wLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fcGF0dGVybi5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fcGF0dGVybiA9IG51bGw7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuUGF0dGVybjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIEEgc2VxdWVuY2UgaXMgYW4gYWx0ZXJuYXRlIG5vdGF0aW9uIG9mIGEgcGFydC4gSW5zdGVhZFxuXHRcdCAqICAgICAgICAgb2YgcGFzc2luZyBpbiBhbiBhcnJheSBvZiBbdGltZSwgZXZlbnRdIHBhaXJzLCBwYXNzXG5cdFx0ICogICAgICAgICBpbiBhbiBhcnJheSBvZiBldmVudHMgd2hpY2ggd2lsbCBiZSBzcGFjZWQgYXQgdGhlXG5cdFx0ICogICAgICAgICBnaXZlbiBzdWJkaXZpc2lvbi4gU3ViLWFycmF5cyB3aWxsIHN1YmRpdmlkZSB0aGF0IGJlYXRcblx0XHQgKiAgICAgICAgIGJ5IHRoZSBudW1iZXIgb2YgaXRlbXMgYXJlIGluIHRoZSBhcnJheS5cblx0XHQgKiAgICAgICAgIFNlcXVlbmNlIG5vdGF0aW9uIGluc3BpcmF0aW9uIGZyb20gW1RpZGFsXShodHRwOi8veWF4dS5vcmcvdGlkYWwvKVxuXHRcdCAqICBAcGFyYW0gIHtGdW5jdGlvbn0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgbm90ZVxuXHRcdCAqICBAcGFyYW0gIHtBcnJheX0gICAgZXZlbnRzICBUaGUgc2VxdWVuY2Vcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gc3ViZGl2aXNpb24gIFRoZSBzdWJkaXZpc2lvbiBiZXR3ZWVuIHdoaWNoIGV2ZW50cyBhcmUgcGxhY2VkLlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5QYXJ0fVxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBzZXEgPSBuZXcgVG9uZS5TZXF1ZW5jZShmdW5jdGlvbih0aW1lLCBub3RlKXtcblx0XHQgKiBcdGNvbnNvbGUubG9nKG5vdGUpO1xuXHRcdCAqIC8vc3RyYWlnaHQgcXVhdGVyIG5vdGVzXG5cdFx0ICogfSwgW1wiQzRcIiwgXCJFNFwiLCBcIkc0XCIsIFwiQTRcIl0sIFwiNG5cIik7XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHNlcSA9IG5ldyBUb25lLlNlcXVlbmNlKGZ1bmN0aW9uKHRpbWUsIG5vdGUpe1xuXHRcdCAqIFx0Y29uc29sZS5sb2cobm90ZSk7XG5cdFx0ICogLy9zdWJkaXZpc2lvbnMgYXJlIGdpdmVuIGFzIHN1YmFycmF5c1xuXHRcdCAqIH0sIFtcIkM0XCIsIFtcIkU0XCIsIFwiRDRcIiwgXCJFNFwiXSwgXCJHNFwiLCBbXCJBNFwiLCBcIkc0XCJdXSk7XG5cdFx0ICovXG5cdCAgICBUb25lLlNlcXVlbmNlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ2NhbGxiYWNrJyxcblx0ICAgICAgICAgICAgJ2V2ZW50cycsXG5cdCAgICAgICAgICAgICdzdWJkaXZpc2lvbidcblx0ICAgICAgICBdLCBUb25lLlNlcXVlbmNlKTtcblx0ICAgICAgICAvL3JlbW92ZSB0aGUgZXZlbnRzXG5cdCAgICAgICAgdmFyIGV2ZW50cyA9IG9wdGlvbnMuZXZlbnRzO1xuXHQgICAgICAgIGRlbGV0ZSBvcHRpb25zLmV2ZW50cztcblx0ICAgICAgICBUb25lLlBhcnQuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgc3ViZGl2aXNvbiBvZiBlYWNoIG5vdGVcblx0XHRcdCAqICBAdHlwZSAge1RpY2tzfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9zdWJkaXZpc2lvbiA9IHRoaXMudG9UaWNrcyhvcHRpb25zLnN1YmRpdmlzaW9uKTtcblx0ICAgICAgICAvL2lmIG5vIHRpbWUgd2FzIHBhc3NlZCBpbiwgdGhlIGxvb3AgZW5kIGlzIHRoZSBlbmQgb2YgdGhlIGN5Y2xlXG5cdCAgICAgICAgaWYgKFRvbmUuaXNVbmRlZihvcHRpb25zLmxvb3BFbmQpICYmIFRvbmUuaXNEZWZpbmVkKGV2ZW50cykpIHtcblx0ICAgICAgICAgICAgdGhpcy5fbG9vcEVuZCA9IGV2ZW50cy5sZW5ndGggKiB0aGlzLl9zdWJkaXZpc2lvbjtcblx0ICAgICAgICB9XG5cdCAgICAgICAgLy9kZWZhdWx0cyB0byBsb29waW5nXG5cdCAgICAgICAgdGhpcy5fbG9vcCA9IHRydWU7XG5cdCAgICAgICAgLy9hZGQgYWxsIG9mIHRoZSBldmVudHNcblx0ICAgICAgICBpZiAoVG9uZS5pc0RlZmluZWQoZXZlbnRzKSkge1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5hZGQoaSwgZXZlbnRzW2ldKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlNlcXVlbmNlLCBUb25lLlBhcnQpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0IHZhbHVlcy5cblx0XHQgKiAgQHR5cGUgIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLlNlcXVlbmNlLmRlZmF1bHRzID0geyAnc3ViZGl2aXNpb24nOiAnNG4nIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIHN1YmRpdmlzaW9uIG9mIHRoZSBzZXF1ZW5jZS4gVGhpcyBjYW4gb25seSBiZVxuXHRcdCAqICBzZXQgaW4gdGhlIGNvbnN0cnVjdG9yLiBUaGUgc3ViZGl2aXNpb24gaXMgdGhlXG5cdFx0ICogIGludGVydmFsIGJldHdlZW4gc3VjY2Vzc2l2ZSBzdGVwcy5cblx0XHQgKiAgQHR5cGUge1RpbWV9XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlNlcXVlbmNlI1xuXHRcdCAqICBAbmFtZSBzdWJkaXZpc2lvblxuXHRcdCAqICBAcmVhZE9ubHlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlNlcXVlbmNlLnByb3RvdHlwZSwgJ3N1YmRpdmlzaW9uJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5UaWNrcyh0aGlzLl9zdWJkaXZpc2lvbikudG9TZWNvbmRzKCk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgR2V0L1NldCBhbiBpbmRleCBvZiB0aGUgc2VxdWVuY2UuIElmIHRoZSBpbmRleCBjb250YWlucyBhIHN1YmFycmF5LFxuXHRcdCAqICBhIFRvbmUuU2VxdWVuY2UgcmVwcmVzZW50aW5nIHRoYXQgc3ViLWFycmF5IHdpbGwgYmUgcmV0dXJuZWQuXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHNlcXVlbmNlID0gbmV3IFRvbmUuU2VxdWVuY2UocGxheU5vdGUsIFtcIkU0XCIsIFwiQzRcIiwgXCJGIzRcIiwgW1wiQTRcIiwgXCJCYjNcIl1dKVxuXHRcdCAqIHNlcXVlbmNlLmF0KDApLy8gPT4gcmV0dXJucyBcIkU0XCJcblx0XHQgKiAvL3NldCBhIHZhbHVlXG5cdFx0ICogc2VxdWVuY2UuYXQoMCwgXCJHM1wiKTtcblx0XHQgKiAvL2dldCBhIG5lc3RlZCBzZXF1ZW5jZVxuXHRcdCAqIHNlcXVlbmNlLmF0KDMpLmF0KDEpLy8gPT4gcmV0dXJucyBcIkJiM1wiXG5cdFx0ICogQHBhcmFtIHtQb3NpdGl2ZX0gaW5kZXggVGhlIGluZGV4IHRvIGdldCBvciBzZXRcblx0XHQgKiBAcGFyYW0geyp9IHZhbHVlIE9wdGlvbmFsbHkgcGFzcyBpbiB0aGUgdmFsdWUgdG8gc2V0IGF0IHRoZSBnaXZlbiBpbmRleC5cblx0XHQgKi9cblx0ICAgIFRvbmUuU2VxdWVuY2UucHJvdG90eXBlLmF0ID0gZnVuY3Rpb24gKGluZGV4LCB2YWx1ZSkge1xuXHQgICAgICAgIC8vaWYgdGhlIHZhbHVlIGlzIGFuIGFycmF5LFxuXHQgICAgICAgIGlmIChUb25lLmlzQXJyYXkodmFsdWUpKSB7XG5cdCAgICAgICAgICAgIC8vcmVtb3ZlIHRoZSBjdXJyZW50IGV2ZW50IGF0IHRoYXQgaW5kZXhcblx0ICAgICAgICAgICAgdGhpcy5yZW1vdmUoaW5kZXgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL2NhbGwgdGhlIHBhcmVudCdzIG1ldGhvZFxuXHQgICAgICAgIHJldHVybiBUb25lLlBhcnQucHJvdG90eXBlLmF0LmNhbGwodGhpcywgdGhpcy5faW5kZXhUaW1lKGluZGV4KSwgdmFsdWUpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBBZGQgYW4gZXZlbnQgYXQgYW4gaW5kZXgsIGlmIHRoZXJlJ3MgYWxyZWFkeSBzb21ldGhpbmdcblx0XHQgKiAgYXQgdGhhdCBpbmRleCwgb3ZlcndyaXRlIGl0LiBJZiBgdmFsdWVgIGlzIGFuIGFycmF5LFxuXHRcdCAqICBpdCB3aWxsIGJlIHBhcnNlZCBhcyBhIHN1YnNlcXVlbmNlLlxuXHRcdCAqICBAcGFyYW0ge051bWJlcn0gaW5kZXggVGhlIGluZGV4IHRvIGFkZCB0aGUgZXZlbnQgdG9cblx0XHQgKiAgQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYWRkIGF0IHRoYXQgaW5kZXhcblx0XHQgKiAgQHJldHVybnMge1RvbmUuU2VxdWVuY2V9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuU2VxdWVuY2UucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChpbmRleCwgdmFsdWUpIHtcblx0ICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChUb25lLmlzQXJyYXkodmFsdWUpKSB7XG5cdCAgICAgICAgICAgIC8vbWFrZSBhIHN1YnNlcXVlbmNlIGFuZCBhZGQgdGhhdCB0byB0aGUgc2VxdWVuY2Vcblx0ICAgICAgICAgICAgdmFyIHN1YlN1YmRpdmlzaW9uID0gTWF0aC5yb3VuZCh0aGlzLl9zdWJkaXZpc2lvbiAvIHZhbHVlLmxlbmd0aCk7XG5cdCAgICAgICAgICAgIHZhbHVlID0gbmV3IFRvbmUuU2VxdWVuY2UodGhpcy5fdGljay5iaW5kKHRoaXMpLCB2YWx1ZSwgVG9uZS5UaWNrcyhzdWJTdWJkaXZpc2lvbikpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBUb25lLlBhcnQucHJvdG90eXBlLmFkZC5jYWxsKHRoaXMsIHRoaXMuX2luZGV4VGltZShpbmRleCksIHZhbHVlKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmVtb3ZlIGEgdmFsdWUgZnJvbSB0aGUgc2VxdWVuY2UgYnkgaW5kZXhcblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ9IGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlNlcXVlbmNlfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlNlcXVlbmNlLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAoaW5kZXgsIHZhbHVlKSB7XG5cdCAgICAgICAgVG9uZS5QYXJ0LnByb3RvdHlwZS5yZW1vdmUuY2FsbCh0aGlzLCB0aGlzLl9pbmRleFRpbWUoaW5kZXgpLCB2YWx1ZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEdldCB0aGUgdGltZSBvZiB0aGUgaW5kZXggZ2l2ZW4gdGhlIFNlcXVlbmNlJ3Mgc3ViZGl2aXNpb25cblx0XHQgKiAgQHBhcmFtICB7TnVtYmVyfSAgaW5kZXhcblx0XHQgKiAgQHJldHVybiAge1RpbWV9ICBUaGUgdGltZSBvZiB0aGF0IGluZGV4XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlNlcXVlbmNlLnByb3RvdHlwZS5faW5kZXhUaW1lID0gZnVuY3Rpb24gKGluZGV4KSB7XG5cdCAgICAgICAgaWYgKGluZGV4IGluc3RhbmNlb2YgVG9uZS5UcmFuc3BvcnRUaW1lKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBpbmRleDtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5UaWNrcyhpbmRleCAqIHRoaXMuX3N1YmRpdmlzaW9uICsgdGhpcy5zdGFydE9mZnNldCkudG9TZWNvbmRzKCk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybiB7VG9uZS5TZXF1ZW5jZX0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5TZXF1ZW5jZS5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlBhcnQucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5TZXF1ZW5jZTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuUHVsc2VPc2NpbGxhdG9yIGlzIGEgcHVsc2Ugb3NjaWxsYXRvciB3aXRoIGNvbnRyb2wgb3ZlciBwdWxzZSB3aWR0aCxcblx0XHQgKiAgICAgICAgIGFsc28ga25vd24gYXMgdGhlIGR1dHkgY3ljbGUuIEF0IDUwJSBkdXR5IGN5Y2xlICh3aWR0aCA9IDAuNSkgdGhlIHdhdmUgaXNcblx0XHQgKiAgICAgICAgIGEgc3F1YXJlIGFuZCBvbmx5IG9kZC1udW1iZXJlZCBoYXJtb25pY3MgYXJlIHByZXNlbnQuIEF0IGFsbCBvdGhlciB3aWR0aHNcblx0XHQgKiAgICAgICAgIGV2ZW4tbnVtYmVyZWQgaGFybW9uaWNzIGFyZSBwcmVzZW50LiBSZWFkIG1vcmVcblx0XHQgKiAgICAgICAgIFtoZXJlXShodHRwczovL3dpZ2dsZXdhdmUud29yZHByZXNzLmNvbS8yMDE0LzA4LzE2L3B1bHNlLXdhdmVmb3Jtcy1hbmQtaGFybW9uaWNzLykuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlNvdXJjZX1cblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l9IFtmcmVxdWVuY3ldIFRoZSBmcmVxdWVuY3kgb2YgdGhlIG9zY2lsbGF0b3Jcblx0XHQgKiAgQHBhcmFtIHtOb3JtYWxSYW5nZX0gW3dpZHRoXSBUaGUgd2lkdGggb2YgdGhlIHB1bHNlXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHB1bHNlID0gbmV3IFRvbmUuUHVsc2VPc2NpbGxhdG9yKFwiRTVcIiwgMC40KS50b01hc3RlcigpLnN0YXJ0KCk7XG5cdFx0ICovXG5cdCAgICBUb25lLlB1bHNlT3NjaWxsYXRvciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnd2lkdGgnXG5cdCAgICAgICAgXSwgVG9uZS5Pc2NpbGxhdG9yKTtcblx0ICAgICAgICBUb25lLlNvdXJjZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSB3aWR0aCBvZiB0aGUgcHVsc2UuXG5cdFx0XHQgKiAgQHR5cGUge05vcm1hbFJhbmdlfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMud2lkdGggPSBuZXcgVG9uZS5TaWduYWwob3B0aW9ucy53aWR0aCwgVG9uZS5UeXBlLk5vcm1hbFJhbmdlKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBnYXRlIHRoZSB3aWR0aCBhbW91bnRcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5HYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl93aWR0aEdhdGUgPSBuZXcgVG9uZS5HYWluKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIHNhd3Rvb3RoIG9zY2lsbGF0b3Jcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5Pc2NpbGxhdG9yfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9zYXd0b290aCA9IG5ldyBUb25lLk9zY2lsbGF0b3Ioe1xuXHQgICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuXHQgICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuXHQgICAgICAgICAgICB0eXBlOiAnc2F3dG9vdGgnLFxuXHQgICAgICAgICAgICBwaGFzZTogb3B0aW9ucy5waGFzZVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBmcmVxdWVuY3kgY29udHJvbC5cblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fc2F3dG9vdGguZnJlcXVlbmN5O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBkZXR1bmUgaW4gY2VudHMuXG5cdFx0XHQgKiAgQHR5cGUge0NlbnRzfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZGV0dW5lID0gdGhpcy5fc2F3dG9vdGguZGV0dW5lO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRocmVzaG9sZCB0aGUgc2lnbmFsIHRvIHR1cm4gaXQgaW50byBhIHNxdWFyZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLldhdmVTaGFwZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3RocmVzaCA9IG5ldyBUb25lLldhdmVTaGFwZXIoZnVuY3Rpb24gKHZhbCkge1xuXHQgICAgICAgICAgICBpZiAodmFsIDwgMCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIDE7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvL2Nvbm5lY3Rpb25zXG5cdCAgICAgICAgdGhpcy5fc2F3dG9vdGguY2hhaW4odGhpcy5fdGhyZXNoLCB0aGlzLm91dHB1dCk7XG5cdCAgICAgICAgdGhpcy53aWR0aC5jaGFpbih0aGlzLl93aWR0aEdhdGUsIHRoaXMuX3RocmVzaCk7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoW1xuXHQgICAgICAgICAgICAnd2lkdGgnLFxuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2RldHVuZSdcblx0ICAgICAgICBdKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlB1bHNlT3NjaWxsYXRvciwgVG9uZS5Tb3VyY2UpO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBkZWZhdWx0IHBhcmFtZXRlcnMuXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQGNvbnN0XG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLlB1bHNlT3NjaWxsYXRvci5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnZnJlcXVlbmN5JzogNDQwLFxuXHQgICAgICAgICdkZXR1bmUnOiAwLFxuXHQgICAgICAgICdwaGFzZSc6IDAsXG5cdCAgICAgICAgJ3dpZHRoJzogMC4yXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IHRpbWVcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuUHVsc2VPc2NpbGxhdG9yLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9zYXd0b290aC5zdGFydCh0aW1lKTtcblx0ICAgICAgICB0aGlzLl93aWR0aEdhdGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCB0aW1lKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgc3RvcCB0aGUgb3NjaWxsYXRvclxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSB0aW1lXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlB1bHNlT3NjaWxsYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9zYXd0b290aC5zdG9wKHRpbWUpO1xuXHQgICAgICAgIC8vdGhlIHdpZHRoIGlzIHN0aWxsIGNvbm5lY3RlZCB0byB0aGUgb3V0cHV0LlxuXHQgICAgICAgIC8vdGhhdCBuZWVkcyB0byBiZSBzdG9wcGVkIGFsc29cblx0ICAgICAgICB0aGlzLl93aWR0aEdhdGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgwLCB0aW1lKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgcmVzdGFydCB0aGUgb3NjaWxsYXRvclxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSB0aW1lIChvcHRpb25hbCkgdGltaW5nIHBhcmFtZXRlclxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QdWxzZU9zY2lsbGF0b3IucHJvdG90eXBlLnJlc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRoaXMuX3Nhd3Rvb3RoLnJlc3RhcnQodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHBoYXNlIG9mIHRoZSBvc2NpbGxhdG9yIGluIGRlZ3JlZXMuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuUHVsc2VPc2NpbGxhdG9yI1xuXHRcdCAqIEB0eXBlIHtEZWdyZWVzfVxuXHRcdCAqIEBuYW1lIHBoYXNlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QdWxzZU9zY2lsbGF0b3IucHJvdG90eXBlLCAncGhhc2UnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9zYXd0b290aC5waGFzZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHBoYXNlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3Nhd3Rvb3RoLnBoYXNlID0gcGhhc2U7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQWx3YXlzIHJldHVybnMgXCJwdWxzZVwiLlxuXHRcdCAqIEByZWFkT25seVxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlB1bHNlT3NjaWxsYXRvciNcblx0XHQgKiBAdHlwZSB7c3RyaW5nfVxuXHRcdCAqIEBuYW1lIHR5cGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlB1bHNlT3NjaWxsYXRvci5wcm90b3R5cGUsICd0eXBlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gJ3B1bHNlJztcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBwYXJ0aWFscyBvZiB0aGUgd2F2ZWZvcm0uIENhbm5vdCBzZXQgcGFydGlhbHMgZm9yIHRoaXMgd2F2ZWZvcm0gdHlwZVxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlB1bHNlT3NjaWxsYXRvciNcblx0XHQgKiBAdHlwZSB7QXJyYXl9XG5cdFx0ICogQG5hbWUgcGFydGlhbHNcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUHVsc2VPc2NpbGxhdG9yLnByb3RvdHlwZSwgJ3BhcnRpYWxzJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gW107XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAgbWV0aG9kLlxuXHRcdCAqICBAcmV0dXJuIHtUb25lLlB1bHNlT3NjaWxsYXRvcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QdWxzZU9zY2lsbGF0b3IucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5Tb3VyY2UucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9zYXd0b290aC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fc2F3dG9vdGggPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ3dpZHRoJyxcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdkZXR1bmUnXG5cdCAgICAgICAgXSk7XG5cdCAgICAgICAgdGhpcy53aWR0aC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy53aWR0aCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl93aWR0aEdhdGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3RocmVzaC5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fdGhyZXNoID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlB1bHNlT3NjaWxsYXRvcjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIFRvbmUuUFdNT3NjaWxsYXRvciBtb2R1bGF0ZXMgdGhlIHdpZHRoIG9mIGEgVG9uZS5QdWxzZU9zY2lsbGF0b3Jcblx0XHQgKiAgICAgICAgIGF0IHRoZSBtb2R1bGF0aW9uRnJlcXVlbmN5LiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGNvbnRpbnVvdXNseVxuXHRcdCAqICAgICAgICAgY2hhbmdpbmcgdGhlIHRpbWJyZSBvZiB0aGUgb3NjaWxsYXRvciBieSBhbHRlcmluZyB0aGUgaGFybW9uaWNzXG5cdFx0ICogICAgICAgICBnZW5lcmF0ZWQuXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuU291cmNlfVxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l9IGZyZXF1ZW5jeSBUaGUgc3RhcnRpbmcgZnJlcXVlbmN5IG9mIHRoZSBvc2NpbGxhdG9yLlxuXHRcdCAqICBAcGFyYW0ge0ZyZXF1ZW5jeX0gbW9kdWxhdGlvbkZyZXF1ZW5jeSBUaGUgbW9kdWxhdGlvbiBmcmVxdWVuY3kgb2YgdGhlIHdpZHRoIG9mIHRoZSBwdWxzZS5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAgdmFyIHB3bSA9IG5ldyBUb25lLlBXTU9zY2lsbGF0b3IoXCJBYjNcIiwgMC4zKS50b01hc3RlcigpLnN0YXJ0KCk7XG5cdFx0ICovXG5cdCAgICBUb25lLlBXTU9zY2lsbGF0b3IgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ21vZHVsYXRpb25GcmVxdWVuY3knXG5cdCAgICAgICAgXSwgVG9uZS5QV01Pc2NpbGxhdG9yKTtcblx0ICAgICAgICBUb25lLlNvdXJjZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBwdWxzZSBvc2NpbGxhdG9yXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuUHVsc2VPc2NpbGxhdG9yfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9wdWxzZSA9IG5ldyBUb25lLlB1bHNlT3NjaWxsYXRvcihvcHRpb25zLm1vZHVsYXRpb25GcmVxdWVuY3kpO1xuXHQgICAgICAgIC8vY2hhbmdlIHRoZSBwdWxzZSBvc2NpbGxhdG9yIHR5cGVcblx0ICAgICAgICB0aGlzLl9wdWxzZS5fc2F3dG9vdGgudHlwZSA9ICdzaW5lJztcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbW9kdWxhdG9yXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuT3NjaWxsYXRvcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcih7XG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knOiBvcHRpb25zLmZyZXF1ZW5jeSxcblx0ICAgICAgICAgICAgJ2RldHVuZSc6IG9wdGlvbnMuZGV0dW5lLFxuXHQgICAgICAgICAgICAncGhhc2UnOiBvcHRpb25zLnBoYXNlXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgU2NhbGUgdGhlIG9zY2lsbGF0b3Igc28gaXQgZG9lc24ndCBnbyBzaWxlbnRcblx0XHRcdCAqICBhdCB0aGUgZXh0cmVtZSB2YWx1ZXMuXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuTXVsdGlwbHl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3NjYWxlID0gbmV3IFRvbmUuTXVsdGlwbHkoMik7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGZyZXF1ZW5jeSBjb250cm9sLlxuXHRcdFx0ICogIEB0eXBlIHtGcmVxdWVuY3l9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBkZXR1bmUgb2YgdGhlIG9zY2lsbGF0b3IuXG5cdFx0XHQgKiAgQHR5cGUge0NlbnRzfVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZGV0dW5lID0gdGhpcy5fbW9kdWxhdG9yLmRldHVuZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbW9kdWxhdGlvbiByYXRlIG9mIHRoZSBvc2NpbGxhdG9yLlxuXHRcdFx0ICogIEB0eXBlIHtGcmVxdWVuY3l9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5tb2R1bGF0aW9uRnJlcXVlbmN5ID0gdGhpcy5fcHVsc2UuZnJlcXVlbmN5O1xuXHQgICAgICAgIC8vY29ubmVjdGlvbnNcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3IuY2hhaW4odGhpcy5fc2NhbGUsIHRoaXMuX3B1bHNlLndpZHRoKTtcblx0ICAgICAgICB0aGlzLl9wdWxzZS5jb25uZWN0KHRoaXMub3V0cHV0KTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdtb2R1bGF0aW9uRnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdkZXR1bmUnXG5cdCAgICAgICAgXSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5QV01Pc2NpbGxhdG9yLCBUb25lLlNvdXJjZSk7XG5cdCAgICAvKipcblx0XHQgKiAgZGVmYXVsdCB2YWx1ZXNcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqICBAY29uc3Rcblx0XHQgKi9cblx0ICAgIFRvbmUuUFdNT3NjaWxsYXRvci5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnZnJlcXVlbmN5JzogNDQwLFxuXHQgICAgICAgICdkZXR1bmUnOiAwLFxuXHQgICAgICAgICdwaGFzZSc6IDAsXG5cdCAgICAgICAgJ21vZHVsYXRpb25GcmVxdWVuY3knOiAwLjRcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgc3RhcnQgdGhlIG9zY2lsbGF0b3Jcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gW3RpbWU9bm93XVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QV01Pc2NpbGxhdG9yLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RhcnQodGltZSk7XG5cdCAgICAgICAgdGhpcy5fcHVsc2Uuc3RhcnQodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIHN0b3AgdGhlIG9zY2lsbGF0b3Jcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gdGltZSAob3B0aW9uYWwpIHRpbWluZyBwYXJhbWV0ZXJcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuUFdNT3NjaWxsYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RvcCh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9wdWxzZS5zdG9wKHRpbWUpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICByZXN0YXJ0IHRoZSBvc2NpbGxhdG9yXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IHRpbWUgKG9wdGlvbmFsKSB0aW1pbmcgcGFyYW1ldGVyXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlBXTU9zY2lsbGF0b3IucHJvdG90eXBlLnJlc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvci5yZXN0YXJ0KHRpbWUpO1xuXHQgICAgICAgIHRoaXMuX3B1bHNlLnJlc3RhcnQodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIEFsd2F5cyByZXR1cm5zIFwicHdtXCIuXG5cdFx0ICogQHJlYWRPbmx5XG5cdFx0ICogQG1lbWJlck9mIFRvbmUuUFdNT3NjaWxsYXRvciNcblx0XHQgKiBAdHlwZSB7c3RyaW5nfVxuXHRcdCAqIEBuYW1lIHR5cGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBXTU9zY2lsbGF0b3IucHJvdG90eXBlLCAndHlwZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuICdwd20nO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHBhcnRpYWxzIG9mIHRoZSB3YXZlZm9ybS4gQ2Fubm90IHNldCBwYXJ0aWFscyBmb3IgdGhpcyB3YXZlZm9ybSB0eXBlXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuUFdNT3NjaWxsYXRvciNcblx0XHQgKiBAdHlwZSB7QXJyYXl9XG5cdFx0ICogQG5hbWUgcGFydGlhbHNcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUFdNT3NjaWxsYXRvci5wcm90b3R5cGUsICdwYXJ0aWFscycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIFtdO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHBoYXNlIG9mIHRoZSBvc2NpbGxhdG9yIGluIGRlZ3JlZXMuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuUFdNT3NjaWxsYXRvciNcblx0XHQgKiBAdHlwZSB7bnVtYmVyfVxuXHRcdCAqIEBuYW1lIHBoYXNlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QV01Pc2NpbGxhdG9yLnByb3RvdHlwZSwgJ3BoYXNlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9kdWxhdG9yLnBoYXNlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocGhhc2UpIHtcblx0ICAgICAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnBoYXNlID0gcGhhc2U7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm4ge1RvbmUuUFdNT3NjaWxsYXRvcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QV01Pc2NpbGxhdG9yLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuU291cmNlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fcHVsc2UuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3B1bHNlID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9zY2FsZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fc2NhbGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvci5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbXG5cdCAgICAgICAgICAgICdtb2R1bGF0aW9uRnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdkZXR1bmUnXG5cdCAgICAgICAgXSk7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZGV0dW5lID0gbnVsbDtcblx0ICAgICAgICB0aGlzLm1vZHVsYXRpb25GcmVxdWVuY3kgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLlBXTU9zY2lsbGF0b3I7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBUb25lLkZNT3NjaWxsYXRvclxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlNvdXJjZX1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBwYXJhbSB7RnJlcXVlbmN5fSBmcmVxdWVuY3kgVGhlIHN0YXJ0aW5nIGZyZXF1ZW5jeSBvZiB0aGUgb3NjaWxsYXRvci5cblx0XHQgKiAgQHBhcmFtIHtTdHJpbmd9IHR5cGUgVGhlIHR5cGUgb2YgdGhlIGNhcnJpZXIgb3NjaWxsYXRvci5cblx0XHQgKiAgQHBhcmFtIHtTdHJpbmd9IG1vZHVsYXRpb25UeXBlIFRoZSB0eXBlIG9mIHRoZSBtb2R1bGF0b3Igb3NjaWxsYXRvci5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiAvL2Egc2luZSBvc2NpbGxhdG9yIGZyZXF1ZW5jeS1tb2R1bGF0ZWQgYnkgYSBzcXVhcmUgd2F2ZVxuXHRcdCAqIHZhciBmbU9zYyA9IG5ldyBUb25lLkZNT3NjaWxsYXRvcihcIkFiM1wiLCBcInNpbmVcIiwgXCJzcXVhcmVcIikudG9NYXN0ZXIoKS5zdGFydCgpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5GTU9zY2lsbGF0b3IgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3VtZW50cywgW1xuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ3R5cGUnLFxuXHQgICAgICAgICAgICAnbW9kdWxhdGlvblR5cGUnXG5cdCAgICAgICAgXSwgVG9uZS5GTU9zY2lsbGF0b3IpO1xuXHQgICAgICAgIFRvbmUuU291cmNlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGNhcnJpZXIgb3NjaWxsYXRvclxuXHRcdFx0ICogIEB0eXBlIHtUb25lLk9zY2lsbGF0b3J9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2NhcnJpZXIgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKG9wdGlvbnMuZnJlcXVlbmN5LCBvcHRpb25zLnR5cGUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBvc2NpbGxhdG9yJ3MgZnJlcXVlbmN5XG5cdFx0XHQgKiAgQHR5cGUge0ZyZXF1ZW5jeX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLmZyZXF1ZW5jeSwgVG9uZS5UeXBlLkZyZXF1ZW5jeSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGRldHVuZSBjb250cm9sIHNpZ25hbC5cblx0XHRcdCAqICBAdHlwZSB7Q2VudHN9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLl9jYXJyaWVyLmRldHVuZTtcblx0ICAgICAgICB0aGlzLmRldHVuZS52YWx1ZSA9IG9wdGlvbnMuZGV0dW5lO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBtb2R1bGF0aW9uIGluZGV4IHdoaWNoIGlzIGluIGVzc2VuY2UgdGhlIGRlcHRoIG9yIGFtb3VudCBvZiB0aGUgbW9kdWxhdGlvbi4gSW4gb3RoZXIgdGVybXMgaXQgaXMgdGhlXG5cdFx0XHQgKiAgcmF0aW8gb2YgdGhlIGZyZXF1ZW5jeSBvZiB0aGUgbW9kdWxhdGluZyBzaWduYWwgKG1mKSB0byB0aGUgYW1wbGl0dWRlIG9mIHRoZVxuXHRcdFx0ICogIG1vZHVsYXRpbmcgc2lnbmFsIChtYSkgLS0gYXMgaW4gbWEvbWYuXG5cdFx0XHQgKlx0QHR5cGUge1Bvc2l0aXZlfVxuXHRcdFx0ICpcdEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4ID0gbmV3IFRvbmUuTXVsdGlwbHkob3B0aW9ucy5tb2R1bGF0aW9uSW5kZXgpO1xuXHQgICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4LnVuaXRzID0gVG9uZS5UeXBlLlBvc2l0aXZlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBtb2R1bGF0aW5nIG9zY2lsbGF0b3Jcblx0XHRcdCAqICBAdHlwZSAge1RvbmUuT3NjaWxsYXRvcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcihvcHRpb25zLmZyZXF1ZW5jeSwgb3B0aW9ucy5tb2R1bGF0aW9uVHlwZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgSGFybW9uaWNpdHkgaXMgdGhlIGZyZXF1ZW5jeSByYXRpbyBiZXR3ZWVuIHRoZSBjYXJyaWVyIGFuZCB0aGUgbW9kdWxhdG9yIG9zY2lsbGF0b3JzLlxuXHRcdFx0ICogIEEgaGFybW9uaWNpdHkgb2YgMSBnaXZlcyBib3RoIG9zY2lsbGF0b3JzIHRoZSBzYW1lIGZyZXF1ZW5jeS5cblx0XHRcdCAqICBIYXJtb25pY2l0eSA9IDIgbWVhbnMgYSBjaGFuZ2Ugb2YgYW4gb2N0YXZlLlxuXHRcdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKiAgQGV4YW1wbGVcblx0XHRcdCAqIC8vcGl0Y2ggdGhlIG1vZHVsYXRvciBhbiBvY3RhdmUgYmVsb3cgY2FycmllclxuXHRcdFx0ICogc3ludGguaGFybW9uaWNpdHkudmFsdWUgPSAwLjU7XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmhhcm1vbmljaXR5ID0gbmV3IFRvbmUuTXVsdGlwbHkob3B0aW9ucy5oYXJtb25pY2l0eSk7XG5cdCAgICAgICAgdGhpcy5oYXJtb25pY2l0eS51bml0cyA9IFRvbmUuVHlwZS5Qb3NpdGl2ZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbm9kZSB3aGVyZSB0aGUgbW9kdWxhdGlvbiBoYXBwZW5zXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuR2Fpbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUgPSBuZXcgVG9uZS5HYWluKDApO1xuXHQgICAgICAgIC8vY29ubmVjdGlvbnNcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5KTtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLm1vZHVsYXRpb25JbmRleCwgdGhpcy5fbW9kdWxhdGlvbk5vZGUpO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvci5jb25uZWN0KHRoaXMuX21vZHVsYXRpb25Ob2RlLmdhaW4pO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlLmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuXHQgICAgICAgIHRoaXMuX2NhcnJpZXIuY29ubmVjdCh0aGlzLm91dHB1dCk7XG5cdCAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdCh0aGlzLl9tb2R1bGF0b3IuZGV0dW5lKTtcblx0ICAgICAgICB0aGlzLnBoYXNlID0gb3B0aW9ucy5waGFzZTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdtb2R1bGF0aW9uSW5kZXgnLFxuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2RldHVuZScsXG5cdCAgICAgICAgICAgICdoYXJtb25pY2l0eSdcblx0ICAgICAgICBdKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkZNT3NjaWxsYXRvciwgVG9uZS5Tb3VyY2UpO1xuXHQgICAgLyoqXG5cdFx0ICogIGRlZmF1bHQgdmFsdWVzXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKiAgQGNvbnN0XG5cdFx0ICovXG5cdCAgICBUb25lLkZNT3NjaWxsYXRvci5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnZnJlcXVlbmN5JzogNDQwLFxuXHQgICAgICAgICdkZXR1bmUnOiAwLFxuXHQgICAgICAgICdwaGFzZSc6IDAsXG5cdCAgICAgICAgJ21vZHVsYXRpb25JbmRleCc6IDIsXG5cdCAgICAgICAgJ21vZHVsYXRpb25UeXBlJzogJ3NxdWFyZScsXG5cdCAgICAgICAgJ2hhcm1vbmljaXR5JzogMVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBzdGFydCB0aGUgb3NjaWxsYXRvclxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkZNT3NjaWxsYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RhcnQodGltZSk7XG5cdCAgICAgICAgdGhpcy5fY2Fycmllci5zdGFydCh0aW1lKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgc3RvcCB0aGUgb3NjaWxsYXRvclxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSB0aW1lIChvcHRpb25hbCkgdGltaW5nIHBhcmFtZXRlclxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5GTU9zY2lsbGF0b3IucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RvcCh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyLnN0b3AodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIHN0b3AgdGhlIG9zY2lsbGF0b3Jcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gdGltZSAob3B0aW9uYWwpIHRpbWluZyBwYXJhbWV0ZXJcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuRk1Pc2NpbGxhdG9yLnByb3RvdHlwZS5yZXN0YXJ0ID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3IucmVzdGFydCh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyLnJlc3RhcnQodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHR5cGUgb2YgdGhlIGNhcnJpZXIgb3NjaWxsYXRvclxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkZNT3NjaWxsYXRvciNcblx0XHQgKiBAdHlwZSB7c3RyaW5nfVxuXHRcdCAqIEBuYW1lIHR5cGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkZNT3NjaWxsYXRvci5wcm90b3R5cGUsICd0eXBlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci50eXBlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodHlwZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9jYXJyaWVyLnR5cGUgPSB0eXBlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHR5cGUgb2YgdGhlIG1vZHVsYXRvciBvc2NpbGxhdG9yXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuRk1Pc2NpbGxhdG9yI1xuXHRcdCAqIEB0eXBlIHtTdHJpbmd9XG5cdFx0ICogQG5hbWUgbW9kdWxhdGlvblR5cGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkZNT3NjaWxsYXRvci5wcm90b3R5cGUsICdtb2R1bGF0aW9uVHlwZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21vZHVsYXRvci50eXBlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodHlwZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9tb2R1bGF0b3IudHlwZSA9IHR5cGU7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcGhhc2Ugb2YgdGhlIG9zY2lsbGF0b3IgaW4gZGVncmVlcy5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5GTU9zY2lsbGF0b3IjXG5cdFx0ICogQHR5cGUge251bWJlcn1cblx0XHQgKiBAbmFtZSBwaGFzZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuRk1Pc2NpbGxhdG9yLnByb3RvdHlwZSwgJ3BoYXNlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5waGFzZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHBoYXNlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2NhcnJpZXIucGhhc2UgPSBwaGFzZTtcblx0ICAgICAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnBoYXNlID0gcGhhc2U7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcGFydGlhbHMgb2YgdGhlIGNhcnJpZXIgd2F2ZWZvcm0uIEEgcGFydGlhbCByZXByZXNlbnRzXG5cdFx0ICogdGhlIGFtcGxpdHVkZSBhdCBhIGhhcm1vbmljLiBUaGUgZmlyc3QgaGFybW9uaWMgaXMgdGhlXG5cdFx0ICogZnVuZGFtZW50YWwgZnJlcXVlbmN5LCB0aGUgc2Vjb25kIGlzIHRoZSBvY3RhdmUgYW5kIHNvIG9uXG5cdFx0ICogZm9sbG93aW5nIHRoZSBoYXJtb25pYyBzZXJpZXMuXG5cdFx0ICogU2V0dGluZyB0aGlzIHZhbHVlIHdpbGwgYXV0b21hdGljYWxseSBzZXQgdGhlIHR5cGUgdG8gXCJjdXN0b21cIi5cblx0XHQgKiBUaGUgdmFsdWUgaXMgYW4gZW1wdHkgYXJyYXkgd2hlbiB0aGUgdHlwZSBpcyBub3QgXCJjdXN0b21cIi5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5GTU9zY2lsbGF0b3IjXG5cdFx0ICogQHR5cGUge0FycmF5fVxuXHRcdCAqIEBuYW1lIHBhcnRpYWxzXG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiBvc2MucGFydGlhbHMgPSBbMSwgMC4yLCAwLjAxXTtcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkZNT3NjaWxsYXRvci5wcm90b3R5cGUsICdwYXJ0aWFscycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIucGFydGlhbHM7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwYXJ0aWFscykge1xuXHQgICAgICAgICAgICB0aGlzLl9jYXJyaWVyLnBhcnRpYWxzID0gcGFydGlhbHM7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm4ge1RvbmUuRk1Pc2NpbGxhdG9yfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkZNT3NjaWxsYXRvci5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNvdXJjZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ21vZHVsYXRpb25JbmRleCcsXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnZGV0dW5lJyxcblx0ICAgICAgICAgICAgJ2hhcm1vbmljaXR5J1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuaGFybW9uaWNpdHkuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuaGFybW9uaWNpdHkgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2NhcnJpZXIuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2NhcnJpZXIgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvci5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLm1vZHVsYXRpb25JbmRleCA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuRk1Pc2NpbGxhdG9yO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5BTU9zY2lsbGF0b3Jcblx0XHQgKlxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5Pc2NpbGxhdG9yfVxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l9IGZyZXF1ZW5jeSBUaGUgc3RhcnRpbmcgZnJlcXVlbmN5IG9mIHRoZSBvc2NpbGxhdG9yLlxuXHRcdCAqICBAcGFyYW0ge1N0cmluZ30gdHlwZSBUaGUgdHlwZSBvZiB0aGUgY2FycmllciBvc2NpbGxhdG9yLlxuXHRcdCAqICBAcGFyYW0ge1N0cmluZ30gbW9kdWxhdGlvblR5cGUgVGhlIHR5cGUgb2YgdGhlIG1vZHVsYXRvciBvc2NpbGxhdG9yLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vYSBzaW5lIG9zY2lsbGF0b3IgZnJlcXVlbmN5LW1vZHVsYXRlZCBieSBhIHNxdWFyZSB3YXZlXG5cdFx0ICogdmFyIGZtT3NjID0gbmV3IFRvbmUuQU1Pc2NpbGxhdG9yKFwiQWIzXCIsIFwic2luZVwiLCBcInNxdWFyZVwiKS50b01hc3RlcigpLnN0YXJ0KCk7XG5cdFx0ICovXG5cdCAgICBUb25lLkFNT3NjaWxsYXRvciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAndHlwZScsXG5cdCAgICAgICAgICAgICdtb2R1bGF0aW9uVHlwZSdcblx0ICAgICAgICBdLCBUb25lLkFNT3NjaWxsYXRvcik7XG5cdCAgICAgICAgVG9uZS5Tb3VyY2UuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgY2FycmllciBvc2NpbGxhdG9yXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuT3NjaWxsYXRvcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fY2FycmllciA9IG5ldyBUb25lLk9zY2lsbGF0b3Iob3B0aW9ucy5mcmVxdWVuY3ksIG9wdGlvbnMudHlwZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG9zY2lsbGF0b3IncyBmcmVxdWVuY3lcblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fY2Fycmllci5mcmVxdWVuY3k7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGRldHVuZSBjb250cm9sIHNpZ25hbC5cblx0XHRcdCAqICBAdHlwZSB7Q2VudHN9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLl9jYXJyaWVyLmRldHVuZTtcblx0ICAgICAgICB0aGlzLmRldHVuZS52YWx1ZSA9IG9wdGlvbnMuZGV0dW5lO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBtb2R1bGF0aW5nIG9zY2lsbGF0b3Jcblx0XHRcdCAqICBAdHlwZSAge1RvbmUuT3NjaWxsYXRvcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcihvcHRpb25zLmZyZXF1ZW5jeSwgb3B0aW9ucy5tb2R1bGF0aW9uVHlwZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgY29udmVydCB0aGUgLTEsMSBvdXRwdXQgdG8gMCwxXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQXVkaW9Ub0dhaW59XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRpb25TY2FsZSA9IG5ldyBUb25lLkF1ZGlvVG9HYWluKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgSGFybW9uaWNpdHkgaXMgdGhlIGZyZXF1ZW5jeSByYXRpbyBiZXR3ZWVuIHRoZSBjYXJyaWVyIGFuZCB0aGUgbW9kdWxhdG9yIG9zY2lsbGF0b3JzLlxuXHRcdFx0ICogIEEgaGFybW9uaWNpdHkgb2YgMSBnaXZlcyBib3RoIG9zY2lsbGF0b3JzIHRoZSBzYW1lIGZyZXF1ZW5jeS5cblx0XHRcdCAqICBIYXJtb25pY2l0eSA9IDIgbWVhbnMgYSBjaGFuZ2Ugb2YgYW4gb2N0YXZlLlxuXHRcdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKiAgQGV4YW1wbGVcblx0XHRcdCAqIC8vcGl0Y2ggdGhlIG1vZHVsYXRvciBhbiBvY3RhdmUgYmVsb3cgY2FycmllclxuXHRcdFx0ICogc3ludGguaGFybW9uaWNpdHkudmFsdWUgPSAwLjU7XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmhhcm1vbmljaXR5ID0gbmV3IFRvbmUuTXVsdGlwbHkob3B0aW9ucy5oYXJtb25pY2l0eSk7XG5cdCAgICAgICAgdGhpcy5oYXJtb25pY2l0eS51bml0cyA9IFRvbmUuVHlwZS5Qb3NpdGl2ZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbm9kZSB3aGVyZSB0aGUgbW9kdWxhdGlvbiBoYXBwZW5zXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuR2Fpbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUgPSBuZXcgVG9uZS5HYWluKDApO1xuXHQgICAgICAgIC8vY29ubmVjdGlvbnNcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5KTtcblx0ICAgICAgICB0aGlzLmRldHVuZS5jb25uZWN0KHRoaXMuX21vZHVsYXRvci5kZXR1bmUpO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvci5jaGFpbih0aGlzLl9tb2R1bGF0aW9uU2NhbGUsIHRoaXMuX21vZHVsYXRpb25Ob2RlLmdhaW4pO1xuXHQgICAgICAgIHRoaXMuX2NhcnJpZXIuY2hhaW4odGhpcy5fbW9kdWxhdGlvbk5vZGUsIHRoaXMub3V0cHV0KTtcblx0ICAgICAgICB0aGlzLnBoYXNlID0gb3B0aW9ucy5waGFzZTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnZGV0dW5lJyxcblx0ICAgICAgICAgICAgJ2hhcm1vbmljaXR5J1xuXHQgICAgICAgIF0pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuQU1Pc2NpbGxhdG9yLCBUb25lLk9zY2lsbGF0b3IpO1xuXHQgICAgLyoqXG5cdFx0ICogIGRlZmF1bHQgdmFsdWVzXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKiAgQGNvbnN0XG5cdFx0ICovXG5cdCAgICBUb25lLkFNT3NjaWxsYXRvci5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnZnJlcXVlbmN5JzogNDQwLFxuXHQgICAgICAgICdkZXR1bmUnOiAwLFxuXHQgICAgICAgICdwaGFzZSc6IDAsXG5cdCAgICAgICAgJ21vZHVsYXRpb25UeXBlJzogJ3NxdWFyZScsXG5cdCAgICAgICAgJ2hhcm1vbmljaXR5JzogMVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBzdGFydCB0aGUgb3NjaWxsYXRvclxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkFNT3NjaWxsYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RhcnQodGltZSk7XG5cdCAgICAgICAgdGhpcy5fY2Fycmllci5zdGFydCh0aW1lKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgc3RvcCB0aGUgb3NjaWxsYXRvclxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSB0aW1lIChvcHRpb25hbCkgdGltaW5nIHBhcmFtZXRlclxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5BTU9zY2lsbGF0b3IucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RvcCh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyLnN0b3AodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIHJlc3RhcnQgdGhlIG9zY2lsbGF0b3Jcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gdGltZSAob3B0aW9uYWwpIHRpbWluZyBwYXJhbWV0ZXJcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuQU1Pc2NpbGxhdG9yLnByb3RvdHlwZS5yZXN0YXJ0ID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3IucmVzdGFydCh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyLnJlc3RhcnQodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHR5cGUgb2YgdGhlIGNhcnJpZXIgb3NjaWxsYXRvclxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkFNT3NjaWxsYXRvciNcblx0XHQgKiBAdHlwZSB7c3RyaW5nfVxuXHRcdCAqIEBuYW1lIHR5cGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkFNT3NjaWxsYXRvci5wcm90b3R5cGUsICd0eXBlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci50eXBlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodHlwZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9jYXJyaWVyLnR5cGUgPSB0eXBlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHR5cGUgb2YgdGhlIG1vZHVsYXRvciBvc2NpbGxhdG9yXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuQU1Pc2NpbGxhdG9yI1xuXHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0ICogQG5hbWUgbW9kdWxhdGlvblR5cGVcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkFNT3NjaWxsYXRvci5wcm90b3R5cGUsICdtb2R1bGF0aW9uVHlwZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21vZHVsYXRvci50eXBlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodHlwZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9tb2R1bGF0b3IudHlwZSA9IHR5cGU7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcGhhc2Ugb2YgdGhlIG9zY2lsbGF0b3IgaW4gZGVncmVlcy5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5BTU9zY2lsbGF0b3IjXG5cdFx0ICogQHR5cGUge251bWJlcn1cblx0XHQgKiBAbmFtZSBwaGFzZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuQU1Pc2NpbGxhdG9yLnByb3RvdHlwZSwgJ3BoYXNlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5waGFzZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHBoYXNlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2NhcnJpZXIucGhhc2UgPSBwaGFzZTtcblx0ICAgICAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnBoYXNlID0gcGhhc2U7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcGFydGlhbHMgb2YgdGhlIGNhcnJpZXIgd2F2ZWZvcm0uIEEgcGFydGlhbCByZXByZXNlbnRzXG5cdFx0ICogdGhlIGFtcGxpdHVkZSBhdCBhIGhhcm1vbmljLiBUaGUgZmlyc3QgaGFybW9uaWMgaXMgdGhlXG5cdFx0ICogZnVuZGFtZW50YWwgZnJlcXVlbmN5LCB0aGUgc2Vjb25kIGlzIHRoZSBvY3RhdmUgYW5kIHNvIG9uXG5cdFx0ICogZm9sbG93aW5nIHRoZSBoYXJtb25pYyBzZXJpZXMuXG5cdFx0ICogU2V0dGluZyB0aGlzIHZhbHVlIHdpbGwgYXV0b21hdGljYWxseSBzZXQgdGhlIHR5cGUgdG8gXCJjdXN0b21cIi5cblx0XHQgKiBUaGUgdmFsdWUgaXMgYW4gZW1wdHkgYXJyYXkgd2hlbiB0aGUgdHlwZSBpcyBub3QgXCJjdXN0b21cIi5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5BTU9zY2lsbGF0b3IjXG5cdFx0ICogQHR5cGUge0FycmF5fVxuXHRcdCAqIEBuYW1lIHBhcnRpYWxzXG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiBvc2MucGFydGlhbHMgPSBbMSwgMC4yLCAwLjAxXTtcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkFNT3NjaWxsYXRvci5wcm90b3R5cGUsICdwYXJ0aWFscycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIucGFydGlhbHM7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwYXJ0aWFscykge1xuXHQgICAgICAgICAgICB0aGlzLl9jYXJyaWVyLnBhcnRpYWxzID0gcGFydGlhbHM7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm4ge1RvbmUuQU1Pc2NpbGxhdG9yfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkFNT3NjaWxsYXRvci5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNvdXJjZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdkZXR1bmUnLFxuXHQgICAgICAgICAgICAnaGFybW9uaWNpdHknXG5cdCAgICAgICAgXSk7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZGV0dW5lID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmhhcm1vbmljaXR5LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmhhcm1vbmljaXR5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3IuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvciA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0aW9uU2NhbGUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRpb25TY2FsZSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuQU1Pc2NpbGxhdG9yO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgVG9uZS5GYXRPc2NpbGxhdG9yXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuU291cmNlfVxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l9IGZyZXF1ZW5jeSBUaGUgc3RhcnRpbmcgZnJlcXVlbmN5IG9mIHRoZSBvc2NpbGxhdG9yLlxuXHRcdCAqICBAcGFyYW0ge1N0cmluZ30gdHlwZSBUaGUgdHlwZSBvZiB0aGUgY2FycmllciBvc2NpbGxhdG9yLlxuXHRcdCAqICBAcGFyYW0ge1N0cmluZ30gbW9kdWxhdGlvblR5cGUgVGhlIHR5cGUgb2YgdGhlIG1vZHVsYXRvciBvc2NpbGxhdG9yLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vYSBzaW5lIG9zY2lsbGF0b3IgZnJlcXVlbmN5LW1vZHVsYXRlZCBieSBhIHNxdWFyZSB3YXZlXG5cdFx0ICogdmFyIGZtT3NjID0gbmV3IFRvbmUuRmF0T3NjaWxsYXRvcihcIkFiM1wiLCBcInNpbmVcIiwgXCJzcXVhcmVcIikudG9NYXN0ZXIoKS5zdGFydCgpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5GYXRPc2NpbGxhdG9yID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICd0eXBlJyxcblx0ICAgICAgICAgICAgJ3NwcmVhZCdcblx0ICAgICAgICBdLCBUb25lLkZhdE9zY2lsbGF0b3IpO1xuXHQgICAgICAgIFRvbmUuU291cmNlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG9zY2lsbGF0b3IncyBmcmVxdWVuY3lcblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFRvbmUuU2lnbmFsKG9wdGlvbnMuZnJlcXVlbmN5LCBUb25lLlR5cGUuRnJlcXVlbmN5KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZGV0dW5lIGNvbnRyb2wgc2lnbmFsLlxuXHRcdFx0ICogIEB0eXBlIHtDZW50c31cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLmRldHVuZSwgVG9uZS5UeXBlLkNlbnRzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgYXJyYXkgb2Ygb3NjaWxsYXRvcnNcblx0XHRcdCAqICBAdHlwZSB7QXJyYXl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzID0gW107XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHRvdGFsIHNwcmVhZCBvZiB0aGUgb3NjaWxsYXRvcnNcblx0XHRcdCAqICBAdHlwZSAge0NlbnRzfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9zcHJlYWQgPSBvcHRpb25zLnNwcmVhZDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvclxuXHRcdFx0ICogIEB0eXBlIHtTdHJpbmd9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnR5cGU7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHBoYXNlIG9mIHRoZSBvc2NpbGxhdG9yc1xuXHRcdFx0ICogIEB0eXBlIHtEZWdyZWVzfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9waGFzZSA9IG9wdGlvbnMucGhhc2U7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHBhcnRpYWxzIGFycmF5XG5cdFx0XHQgKiAgQHR5cGUge0FycmF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IFRvbmUuZGVmYXVsdEFyZyhvcHRpb25zLnBhcnRpYWxzLCBbXSk7XG5cdCAgICAgICAgLy9zZXQgdGhlIGNvdW50IGluaXRpYWxseVxuXHQgICAgICAgIHRoaXMuY291bnQgPSBvcHRpb25zLmNvdW50O1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFtcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdkZXR1bmUnXG5cdCAgICAgICAgXSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5GYXRPc2NpbGxhdG9yLCBUb25lLlNvdXJjZSk7XG5cdCAgICAvKipcblx0XHQgKiAgZGVmYXVsdCB2YWx1ZXNcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqICBAY29uc3Rcblx0XHQgKi9cblx0ICAgIFRvbmUuRmF0T3NjaWxsYXRvci5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnZnJlcXVlbmN5JzogNDQwLFxuXHQgICAgICAgICdkZXR1bmUnOiAwLFxuXHQgICAgICAgICdwaGFzZSc6IDAsXG5cdCAgICAgICAgJ3NwcmVhZCc6IDIwLFxuXHQgICAgICAgICdjb3VudCc6IDMsXG5cdCAgICAgICAgJ3R5cGUnOiAnc2F3dG9vdGgnXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IFt0aW1lPW5vd11cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuRmF0T3NjaWxsYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdGhpcy5fZm9yRWFjaChmdW5jdGlvbiAob3NjKSB7XG5cdCAgICAgICAgICAgIG9zYy5zdGFydCh0aW1lKTtcblx0ICAgICAgICB9KTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgc3RvcCB0aGUgb3NjaWxsYXRvclxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkZhdE9zY2lsbGF0b3IucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdGhpcy5fZm9yRWFjaChmdW5jdGlvbiAob3NjKSB7XG5cdCAgICAgICAgICAgIG9zYy5zdG9wKHRpbWUpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICByZXN0YXJ0IHRoZSBvc2NpbGxhdG9yXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IHRpbWUgKG9wdGlvbmFsKSB0aW1pbmcgcGFyYW1ldGVyXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkZhdE9zY2lsbGF0b3IucHJvdG90eXBlLnJlc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9mb3JFYWNoKGZ1bmN0aW9uIChvc2MpIHtcblx0ICAgICAgICAgICAgb3NjLnJlc3RhcnQodGltZSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEl0ZXJhdGUgb3ZlciBhbGwgb2YgdGhlIG9zY2lsbGF0b3JzXG5cdFx0ICogIEBwYXJhbSAge0Z1bmN0aW9ufSAgaXRlcmF0b3IgIFRoZSBpdGVyYXRvciBmdW5jdGlvblxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5GYXRPc2NpbGxhdG9yLnByb3RvdHlwZS5fZm9yRWFjaCA9IGZ1bmN0aW9uIChpdGVyYXRvcikge1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fb3NjaWxsYXRvcnMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgaXRlcmF0b3IuY2FsbCh0aGlzLCB0aGlzLl9vc2NpbGxhdG9yc1tpXSwgaSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSB0eXBlIG9mIHRoZSBjYXJyaWVyIG9zY2lsbGF0b3Jcblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5GYXRPc2NpbGxhdG9yI1xuXHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0ICogQG5hbWUgdHlwZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuRmF0T3NjaWxsYXRvci5wcm90b3R5cGUsICd0eXBlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHR5cGUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG5cdCAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZnVuY3Rpb24gKG9zYykge1xuXHQgICAgICAgICAgICAgICAgb3NjLnR5cGUgPSB0eXBlO1xuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBkZXR1bmUgc3ByZWFkIGJldHdlZW4gdGhlIG9zY2lsbGF0b3JzLiBJZiBcImNvdW50XCIgaXNcblx0XHQgKiBzZXQgdG8gMyBvc2NpbGxhdG9ycyBhbmQgdGhlIFwic3ByZWFkXCIgaXMgc2V0IHRvIDQwLFxuXHRcdCAqIHRoZSB0aHJlZSBvc2NpbGxhdG9ycyB3b3VsZCBiZSBkZXR1bmVkIGxpa2UgdGhpczogWy0yMCwgMCwgMjBdXG5cdFx0ICogZm9yIGEgdG90YWwgZGV0dW5lIHNwcmVhZCBvZiA0MCBjZW50cy5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5GYXRPc2NpbGxhdG9yI1xuXHRcdCAqIEB0eXBlIHtDZW50c31cblx0XHQgKiBAbmFtZSBzcHJlYWRcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkZhdE9zY2lsbGF0b3IucHJvdG90eXBlLCAnc3ByZWFkJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fc3ByZWFkO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoc3ByZWFkKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3NwcmVhZCA9IHNwcmVhZDtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aCA+IDEpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBzdGFydCA9IC1zcHJlYWQgLyAyO1xuXHQgICAgICAgICAgICAgICAgdmFyIHN0ZXAgPSBzcHJlYWQgLyAodGhpcy5fb3NjaWxsYXRvcnMubGVuZ3RoIC0gMSk7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9mb3JFYWNoKGZ1bmN0aW9uIChvc2MsIGkpIHtcblx0ICAgICAgICAgICAgICAgICAgICBvc2MuZGV0dW5lLnZhbHVlID0gc3RhcnQgKyBzdGVwICogaTtcblx0ICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgbnVtYmVyIG9mIGRldHVuZWQgb3NjaWxsYXRvcnNcblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5GYXRPc2NpbGxhdG9yI1xuXHRcdCAqIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogQG5hbWUgY291bnRcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkZhdE9zY2lsbGF0b3IucHJvdG90eXBlLCAnY291bnQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGg7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChjb3VudCkge1xuXHQgICAgICAgICAgICBjb3VudCA9IE1hdGgubWF4KGNvdW50LCAxKTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aCAhPT0gY291bnQpIHtcblx0ICAgICAgICAgICAgICAgIC8vIHZhciBwYXJ0aWFscyA9IHRoaXMucGFydGlhbHM7XG5cdCAgICAgICAgICAgICAgICAvLyB2YXIgdHlwZSA9IHRoaXMudHlwZTtcblx0ICAgICAgICAgICAgICAgIC8vZGlzcG9zZSB0aGUgcHJldmlvdXMgb3NjaWxsYXRvcnNcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZnVuY3Rpb24gKG9zYykge1xuXHQgICAgICAgICAgICAgICAgICAgIG9zYy5kaXNwb3NlKCk7XG5cdCAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzID0gW107XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpO1xuXHQgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnR5cGUgPT09IFRvbmUuT3NjaWxsYXRvci5UeXBlLkN1c3RvbSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBvc2MucGFydGlhbHMgPSB0aGlzLl9wYXJ0aWFscztcblx0ICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBvc2MudHlwZSA9IHRoaXMuX3R5cGU7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgIG9zYy5waGFzZSA9IHRoaXMuX3BoYXNlO1xuXHQgICAgICAgICAgICAgICAgICAgIG9zYy52b2x1bWUudmFsdWUgPSAtNiAtIGNvdW50ICogMS4xO1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3Qob3NjLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdChvc2MuZGV0dW5lKTtcblx0ICAgICAgICAgICAgICAgICAgICBvc2MuY29ubmVjdCh0aGlzLm91dHB1dCk7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnNbaV0gPSBvc2M7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAvL3NldCB0aGUgc3ByZWFkXG5cdCAgICAgICAgICAgICAgICB0aGlzLnNwcmVhZCA9IHRoaXMuX3NwcmVhZDtcblx0ICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBUb25lLlN0YXRlLlN0YXJ0ZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl9mb3JFYWNoKGZ1bmN0aW9uIChvc2MpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgb3NjLnN0YXJ0KCk7XG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBwaGFzZSBvZiB0aGUgb3NjaWxsYXRvciBpbiBkZWdyZWVzLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkZhdE9zY2lsbGF0b3IjXG5cdFx0ICogQHR5cGUge051bWJlcn1cblx0XHQgKiBAbmFtZSBwaGFzZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuRmF0T3NjaWxsYXRvci5wcm90b3R5cGUsICdwaGFzZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BoYXNlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocGhhc2UpIHtcblx0ICAgICAgICAgICAgdGhpcy5fcGhhc2UgPSBwaGFzZTtcblx0ICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChmdW5jdGlvbiAob3NjKSB7XG5cdCAgICAgICAgICAgICAgICBvc2MucGhhc2UgPSBwaGFzZTtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcGFydGlhbHMgb2YgdGhlIGNhcnJpZXIgd2F2ZWZvcm0uIEEgcGFydGlhbCByZXByZXNlbnRzXG5cdFx0ICogdGhlIGFtcGxpdHVkZSBhdCBhIGhhcm1vbmljLiBUaGUgZmlyc3QgaGFybW9uaWMgaXMgdGhlXG5cdFx0ICogZnVuZGFtZW50YWwgZnJlcXVlbmN5LCB0aGUgc2Vjb25kIGlzIHRoZSBvY3RhdmUgYW5kIHNvIG9uXG5cdFx0ICogZm9sbG93aW5nIHRoZSBoYXJtb25pYyBzZXJpZXMuXG5cdFx0ICogU2V0dGluZyB0aGlzIHZhbHVlIHdpbGwgYXV0b21hdGljYWxseSBzZXQgdGhlIHR5cGUgdG8gXCJjdXN0b21cIi5cblx0XHQgKiBUaGUgdmFsdWUgaXMgYW4gZW1wdHkgYXJyYXkgd2hlbiB0aGUgdHlwZSBpcyBub3QgXCJjdXN0b21cIi5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5GYXRPc2NpbGxhdG9yI1xuXHRcdCAqIEB0eXBlIHtBcnJheX1cblx0XHQgKiBAbmFtZSBwYXJ0aWFsc1xuXHRcdCAqIEBleGFtcGxlXG5cdFx0ICogb3NjLnBhcnRpYWxzID0gWzEsIDAuMiwgMC4wMV07XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5GYXRPc2NpbGxhdG9yLnByb3RvdHlwZSwgJ3BhcnRpYWxzJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fcGFydGlhbHM7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwYXJ0aWFscykge1xuXHQgICAgICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IHBhcnRpYWxzO1xuXHQgICAgICAgICAgICB0aGlzLl90eXBlID0gVG9uZS5Pc2NpbGxhdG9yLlR5cGUuQ3VzdG9tO1xuXHQgICAgICAgICAgICB0aGlzLl9mb3JFYWNoKGZ1bmN0aW9uIChvc2MpIHtcblx0ICAgICAgICAgICAgICAgIG9zYy5wYXJ0aWFscyA9IHBhcnRpYWxzO1xuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybiB7VG9uZS5GYXRPc2NpbGxhdG9yfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkZhdE9zY2lsbGF0b3IucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5Tb3VyY2UucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnZGV0dW5lJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZGV0dW5lID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9mb3JFYWNoKGZ1bmN0aW9uIChvc2MpIHtcblx0ICAgICAgICAgICAgb3NjLmRpc3Bvc2UoKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkZhdE9zY2lsbGF0b3I7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBUb25lLk9tbmlPc2NpbGxhdG9yIGFnZ3JlZ2F0ZXMgVG9uZS5Pc2NpbGxhdG9yLCBUb25lLlB1bHNlT3NjaWxsYXRvcixcblx0XHQgKiAgICAgICAgIFRvbmUuUFdNT3NjaWxsYXRvciwgVG9uZS5GTU9zY2lsbGF0b3IsIFRvbmUuQU1Pc2NpbGxhdG9yLCBhbmQgVG9uZS5GYXRPc2NpbGxhdG9yXG5cdFx0ICogICAgICAgICBpbnRvIG9uZSBjbGFzcy4gVGhlIG9zY2lsbGF0b3IgY2xhc3MgY2FuIGJlIGNoYW5nZWQgYnkgc2V0dGluZyB0aGUgYHR5cGVgLlxuXHRcdCAqICAgICAgICAgYG9tbmlPc2MudHlwZSA9IFwicHdtXCJgIHdpbGwgc2V0IGl0IHRvIHRoZSBUb25lLlBXTU9zY2lsbGF0b3IuIFByZWZpeGluZ1xuXHRcdCAqICAgICAgICAgYW55IG9mIHRoZSBiYXNpYyB0eXBlcyAoXCJzaW5lXCIsIFwic3F1YXJlNFwiLCBldGMuKSB3aXRoIFwiZm1cIiwgXCJhbVwiLCBvciBcImZhdFwiXG5cdFx0ICogICAgICAgICB3aWxsIHVzZSB0aGUgRk1Pc2NpbGxhdG9yLCBBTU9zY2lsbGF0b3Igb3IgRmF0T3NjaWxsYXRvciByZXNwZWN0aXZlbHkuXG5cdFx0ICogICAgICAgICBGb3IgZXhhbXBsZTogYG9tbmlPc2MudHlwZSA9IFwiZmF0c2F3dG9vdGhcImAgd2lsbCBjcmVhdGUgc2V0IHRoZSBvc2NpbGxhdG9yXG5cdFx0ICogICAgICAgICB0byBhIEZhdE9zY2lsbGF0b3Igb2YgdHlwZSBcInNhd3Rvb3RoXCIuXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuU291cmNlfVxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l9IGZyZXF1ZW5jeSBUaGUgaW5pdGlhbCBmcmVxdWVuY3kgb2YgdGhlIG9zY2lsbGF0b3IuXG5cdFx0ICogIEBwYXJhbSB7U3RyaW5nfSB0eXBlIFRoZSB0eXBlIG9mIHRoZSBvc2NpbGxhdG9yLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqICB2YXIgb21uaU9zYyA9IG5ldyBUb25lLk9tbmlPc2NpbGxhdG9yKFwiQyM0XCIsIFwicHdtXCIpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5PbW5pT3NjaWxsYXRvciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAndHlwZSdcblx0ICAgICAgICBdLCBUb25lLk9tbmlPc2NpbGxhdG9yKTtcblx0ICAgICAgICBUb25lLlNvdXJjZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBmcmVxdWVuY3kgY29udHJvbC5cblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFRvbmUuU2lnbmFsKG9wdGlvbnMuZnJlcXVlbmN5LCBUb25lLlR5cGUuRnJlcXVlbmN5KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZGV0dW5lIGNvbnRyb2xcblx0XHRcdCAqICBAdHlwZSB7Q2VudHN9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgVG9uZS5TaWduYWwob3B0aW9ucy5kZXR1bmUsIFRvbmUuVHlwZS5DZW50cyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3Igc291cmNlXG5cdFx0XHQgKiAgQHR5cGUge1N0cmluZ31cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc291cmNlVHlwZSA9IHVuZGVmaW5lZDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgb3NjaWxsYXRvclxuXHRcdFx0ICogIEB0eXBlIHtUb25lLk9zY2lsbGF0b3J9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSBudWxsO1xuXHQgICAgICAgIC8vc2V0IHRoZSBvc2NpbGxhdG9yXG5cdCAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFtcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdkZXR1bmUnXG5cdCAgICAgICAgXSk7XG5cdCAgICAgICAgLy9zZXQgdGhlIG9wdGlvbnNcblx0ICAgICAgICB0aGlzLnNldChvcHRpb25zKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLk9tbmlPc2NpbGxhdG9yLCBUb25lLlNvdXJjZSk7XG5cdCAgICAvKipcblx0XHQgKiAgZGVmYXVsdCB2YWx1ZXNcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqICBAY29uc3Rcblx0XHQgKi9cblx0ICAgIFRvbmUuT21uaU9zY2lsbGF0b3IuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2ZyZXF1ZW5jeSc6IDQ0MCxcblx0ICAgICAgICAnZGV0dW5lJzogMCxcblx0ICAgICAgICAndHlwZSc6ICdzaW5lJyxcblx0ICAgICAgICAncGhhc2UnOiAwXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEBlbnVtIHtTdHJpbmd9XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICB2YXIgT21uaU9zY1R5cGUgPSB7XG5cdCAgICAgICAgUHVsc2U6ICdQdWxzZU9zY2lsbGF0b3InLFxuXHQgICAgICAgIFBXTTogJ1BXTU9zY2lsbGF0b3InLFxuXHQgICAgICAgIE9zYzogJ09zY2lsbGF0b3InLFxuXHQgICAgICAgIEZNOiAnRk1Pc2NpbGxhdG9yJyxcblx0ICAgICAgICBBTTogJ0FNT3NjaWxsYXRvcicsXG5cdCAgICAgICAgRmF0OiAnRmF0T3NjaWxsYXRvcidcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgc3RhcnQgdGhlIG9zY2lsbGF0b3Jcblx0XHQgKiAgQHBhcmFtIHtUaW1lfSBbdGltZT1ub3ddIHRoZSB0aW1lIHRvIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLk9tbmlPc2NpbGxhdG9yLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW3RpbWU9bm93XSB0aGUgdGltZSB0byBzdGFydCB0aGUgb3NjaWxsYXRvclxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5PbW5pT3NjaWxsYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RvcCh0aW1lKTtcblx0ICAgIH07XG5cdCAgICBUb25lLk9tbmlPc2NpbGxhdG9yLnByb3RvdHlwZS5yZXN0YXJ0ID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnJlc3RhcnQodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIENhbiBiZSBhbnkgb2YgdGhlIGJhc2ljIHR5cGVzOiBzaW5lLCBzcXVhcmUsIHRyaWFuZ2xlLCBzYXd0b290aC4gT3Jcblx0XHQgKiBwcmVmaXggdGhlIGJhc2ljIHR5cGVzIHdpdGggXCJmbVwiLCBcImFtXCIsIG9yIFwiZmF0XCIgdG8gdXNlIHRoZSBGTU9zY2lsbGF0b3IsIEFNT3NjaWxsYXRvciBvciBGYXRPc2NpbGxhdG9yXG5cdFx0ICogdHlwZXMuIFRoZSBvc2NpbGxhdG9yIGNvdWxkIGFsc28gYmUgc2V0IHRvIFwicHdtXCIgb3IgXCJwdWxzZVwiLiBBbGwgb2YgdGhlIHBhcmFtZXRlcnMgb2YgdGhlXG5cdFx0ICogb3NjaWxsYXRvcidzIGNsYXNzIGFyZSBhY2Nlc3NpYmxlIHdoZW4gdGhlIG9zY2lsbGF0b3IgaXMgc2V0IHRvIHRoYXQgdHlwZSwgYnV0IHRocm93cyBhbiBlcnJvclxuXHRcdCAqIHdoZW4gaXQncyBub3QuXG5cdFx0ICpcblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5PbW5pT3NjaWxsYXRvciNcblx0XHQgKiBAdHlwZSB7U3RyaW5nfVxuXHRcdCAqIEBuYW1lIHR5cGVcblx0XHQgKiBAZXhhbXBsZVxuXHRcdCAqIG9tbmlPc2MudHlwZSA9IFwicHdtXCI7XG5cdFx0ICogLy9tb2R1bGF0aW9uRnJlcXVlbmN5IGlzIHBhcmFtZXRlciB3aGljaCBpcyBhdmFpbGFibGVcblx0XHQgKiAvL29ubHkgd2hlbiB0aGUgdHlwZSBpcyBcInB3bVwiLlxuXHRcdCAqIG9tbmlPc2MubW9kdWxhdGlvbkZyZXF1ZW5jeS52YWx1ZSA9IDAuNTtcblx0XHQgKiBAZXhhbXBsZVxuXHRcdCAqIC8vYW4gc3F1YXJlIHdhdmUgZnJlcXVlbmN5IG1vZHVsYXRlZCBieSBhIHNhd3Rvb3RoXG5cdFx0ICogb21uaU9zYy50eXBlID0gXCJmbXNxdWFyZVwiO1xuXHRcdCAqIG9tbmlPc2MubW9kdWxhdGlvblR5cGUgPSBcInNhd3Rvb3RoXCI7XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5PbW5pT3NjaWxsYXRvci5wcm90b3R5cGUsICd0eXBlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgcHJlZml4ID0gJyc7XG5cdCAgICAgICAgICAgIGlmICh0aGlzLl9zb3VyY2VUeXBlID09PSBPbW5pT3NjVHlwZS5GTSkge1xuXHQgICAgICAgICAgICAgICAgcHJlZml4ID0gJ2ZtJztcblx0ICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9zb3VyY2VUeXBlID09PSBPbW5pT3NjVHlwZS5BTSkge1xuXHQgICAgICAgICAgICAgICAgcHJlZml4ID0gJ2FtJztcblx0ICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9zb3VyY2VUeXBlID09PSBPbW5pT3NjVHlwZS5GYXQpIHtcblx0ICAgICAgICAgICAgICAgIHByZWZpeCA9ICdmYXQnO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHJldHVybiBwcmVmaXggKyB0aGlzLl9vc2NpbGxhdG9yLnR5cGU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh0eXBlKSB7XG5cdCAgICAgICAgICAgIGlmICh0eXBlLnN1YnN0cigwLCAyKSA9PT0gJ2ZtJykge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihPbW5pT3NjVHlwZS5GTSk7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlLnN1YnN0cigyKTtcblx0ICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlLnN1YnN0cigwLCAyKSA9PT0gJ2FtJykge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihPbW5pT3NjVHlwZS5BTSk7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlLnN1YnN0cigyKTtcblx0ICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlLnN1YnN0cigwLCAzKSA9PT0gJ2ZhdCcpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoT21uaU9zY1R5cGUuRmF0KTtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGUuc3Vic3RyKDMpO1xuXHQgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdwd20nKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVOZXdPc2NpbGxhdG9yKE9tbmlPc2NUeXBlLlBXTSk7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3B1bHNlJykge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihPbW5pT3NjVHlwZS5QdWxzZSk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVOZXdPc2NpbGxhdG9yKE9tbmlPc2NUeXBlLk9zYyk7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcGFydGlhbHMgb2YgdGhlIHdhdmVmb3JtLiBBIHBhcnRpYWwgcmVwcmVzZW50c1xuXHRcdCAqIHRoZSBhbXBsaXR1ZGUgYXQgYSBoYXJtb25pYy4gVGhlIGZpcnN0IGhhcm1vbmljIGlzIHRoZVxuXHRcdCAqIGZ1bmRhbWVudGFsIGZyZXF1ZW5jeSwgdGhlIHNlY29uZCBpcyB0aGUgb2N0YXZlIGFuZCBzbyBvblxuXHRcdCAqIGZvbGxvd2luZyB0aGUgaGFybW9uaWMgc2VyaWVzLlxuXHRcdCAqIFNldHRpbmcgdGhpcyB2YWx1ZSB3aWxsIGF1dG9tYXRpY2FsbHkgc2V0IHRoZSB0eXBlIHRvIFwiY3VzdG9tXCIuXG5cdFx0ICogVGhlIHZhbHVlIGlzIGFuIGVtcHR5IGFycmF5IHdoZW4gdGhlIHR5cGUgaXMgbm90IFwiY3VzdG9tXCIuXG5cdFx0ICogVGhpcyBpcyBub3QgYXZhaWxhYmxlIG9uIFwicHdtXCIgYW5kIFwicHVsc2VcIiBvc2NpbGxhdG9yIHR5cGVzLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLk9tbmlPc2NpbGxhdG9yI1xuXHRcdCAqIEB0eXBlIHtBcnJheX1cblx0XHQgKiBAbmFtZSBwYXJ0aWFsc1xuXHRcdCAqIEBleGFtcGxlXG5cdFx0ICogb3NjLnBhcnRpYWxzID0gWzEsIDAuMiwgMC4wMV07XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5PbW5pT3NjaWxsYXRvci5wcm90b3R5cGUsICdwYXJ0aWFscycsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbHM7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChwYXJ0aWFscykge1xuXHQgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxzID0gcGFydGlhbHM7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgU2V0IGEgbWVtYmVyL2F0dHJpYnV0ZSBvZiB0aGUgb3NjaWxsYXRvci5cblx0XHQgKiAgQHBhcmFtIHtPYmplY3R8U3RyaW5nfSBwYXJhbXNcblx0XHQgKiAgQHBhcmFtIHtudW1iZXI9fSB2YWx1ZVxuXHRcdCAqICBAcGFyYW0ge1RpbWU9fSByYW1wVGltZVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5PbW5pT3NjaWxsYXRvcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5PbW5pT3NjaWxsYXRvci5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKHBhcmFtcywgdmFsdWUpIHtcblx0ICAgICAgICAvL21ha2Ugc3VyZSB0aGUgdHlwZSBpcyBzZXQgZmlyc3Rcblx0ICAgICAgICBpZiAocGFyYW1zID09PSAndHlwZScpIHtcblx0ICAgICAgICAgICAgdGhpcy50eXBlID0gdmFsdWU7XG5cdCAgICAgICAgfSBlbHNlIGlmIChUb25lLmlzT2JqZWN0KHBhcmFtcykgJiYgcGFyYW1zLmhhc093blByb3BlcnR5KCd0eXBlJykpIHtcblx0ICAgICAgICAgICAgdGhpcy50eXBlID0gcGFyYW1zLnR5cGU7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vdGhlbiBzZXQgdGhlIHJlc3Rcblx0ICAgICAgICBUb25lLnByb3RvdHlwZS5zZXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgY29ubmVjdCB0aGUgb3NjaWxsYXRvciB0byB0aGUgZnJlcXVlbmN5IGFuZCBkZXR1bmUgc2lnbmFsc1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5PbW5pT3NjaWxsYXRvci5wcm90b3R5cGUuX2NyZWF0ZU5ld09zY2lsbGF0b3IgPSBmdW5jdGlvbiAob3NjVHlwZSkge1xuXHQgICAgICAgIGlmIChvc2NUeXBlICE9PSB0aGlzLl9zb3VyY2VUeXBlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3NvdXJjZVR5cGUgPSBvc2NUeXBlO1xuXHQgICAgICAgICAgICB2YXIgT3NjaWxsYXRvckNvbnN0cnVjdG9yID0gVG9uZVtvc2NUeXBlXTtcblx0ICAgICAgICAgICAgLy9zaG9ydCBkZWxheSB0byBhdm9pZCBjbGlja3Mgb24gdGhlIGNoYW5nZVxuXHQgICAgICAgICAgICB2YXIgbm93ID0gdGhpcy5ub3coKTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBvbGRPc2MgPSB0aGlzLl9vc2NpbGxhdG9yO1xuXHQgICAgICAgICAgICAgICAgb2xkT3NjLnN0b3Aobm93KTtcblx0ICAgICAgICAgICAgICAgIC8vZGlzcG9zZSB0aGUgb2xkIG9uZVxuXHQgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgIG9sZE9zYy5kaXNwb3NlKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgb2xkT3NjID0gbnVsbDtcblx0ICAgICAgICAgICAgICAgIH0sIHRoaXMuYmxvY2tUaW1lKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gbmV3IE9zY2lsbGF0b3JDb25zdHJ1Y3RvcigpO1xuXHQgICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX29zY2lsbGF0b3IuZnJlcXVlbmN5KTtcblx0ICAgICAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLmRldHVuZSk7XG5cdCAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IuY29ubmVjdCh0aGlzLm91dHB1dCk7XG5cdCAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBUb25lLlN0YXRlLlN0YXJ0ZWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQobm93KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcGhhc2Ugb2YgdGhlIG9zY2lsbGF0b3IgaW4gZGVncmVlcy5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5PbW5pT3NjaWxsYXRvciNcblx0XHQgKiBAdHlwZSB7RGVncmVlc31cblx0XHQgKiBAbmFtZSBwaGFzZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuT21uaU9zY2lsbGF0b3IucHJvdG90eXBlLCAncGhhc2UnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBoYXNlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocGhhc2UpIHtcblx0ICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5waGFzZSA9IHBoYXNlO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIHdpZHRoIG9mIHRoZSBvc2NpbGxhdG9yIChvbmx5IGlmIHRoZSBvc2NpbGxhdG9yIGlzIHNldCB0byBcInB1bHNlXCIpXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuT21uaU9zY2lsbGF0b3IjXG5cdFx0ICogQHR5cGUge05vcm1hbFJhbmdlfVxuXHRcdCAqIEBzaWduYWxcblx0XHQgKiBAbmFtZSB3aWR0aFxuXHRcdCAqIEBleGFtcGxlXG5cdFx0ICogdmFyIG9tbmlPc2MgPSBuZXcgVG9uZS5PbW5pT3NjaWxsYXRvcig0NDAsIFwicHVsc2VcIik7XG5cdFx0ICogLy9jYW4gYWNjZXNzIHRoZSB3aWR0aCBhdHRyaWJ1dGUgb25seSBpZiB0eXBlID09PSBcInB1bHNlXCJcblx0XHQgKiBvbW5pT3NjLndpZHRoLnZhbHVlID0gMC4yO1xuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuT21uaU9zY2lsbGF0b3IucHJvdG90eXBlLCAnd2lkdGgnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIGlmICh0aGlzLl9zb3VyY2VUeXBlID09PSBPbW5pT3NjVHlwZS5QdWxzZSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3Iud2lkdGg7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBudW1iZXIgb2YgZGV0dW5lZCBvc2NpbGxhdG9yc1xuXHRcdCAqIEBtZW1iZXJPZiBUb25lLk9tbmlPc2NpbGxhdG9yI1xuXHRcdCAqIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogQG5hbWUgY291bnRcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLk9tbmlPc2NpbGxhdG9yLnByb3RvdHlwZSwgJ2NvdW50Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fc291cmNlVHlwZSA9PT0gT21uaU9zY1R5cGUuRmF0KSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5jb3VudDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAoY291bnQpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3NvdXJjZVR5cGUgPT09IE9tbmlPc2NUeXBlLkZhdCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5jb3VudCA9IGNvdW50O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgZGV0dW5lIHNwcmVhZCBiZXR3ZWVuIHRoZSBvc2NpbGxhdG9ycy4gSWYgXCJjb3VudFwiIGlzXG5cdFx0ICogc2V0IHRvIDMgb3NjaWxsYXRvcnMgYW5kIHRoZSBcInNwcmVhZFwiIGlzIHNldCB0byA0MCxcblx0XHQgKiB0aGUgdGhyZWUgb3NjaWxsYXRvcnMgd291bGQgYmUgZGV0dW5lZCBsaWtlIHRoaXM6IFstMjAsIDAsIDIwXVxuXHRcdCAqIGZvciBhIHRvdGFsIGRldHVuZSBzcHJlYWQgb2YgNDAgY2VudHMuIFNlZSBUb25lLkZhdE9zY2lsbGF0b3Jcblx0XHQgKiBmb3IgbW9yZSBpbmZvLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLk9tbmlPc2NpbGxhdG9yI1xuXHRcdCAqIEB0eXBlIHtDZW50c31cblx0XHQgKiBAbmFtZSBzcHJlYWRcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLk9tbmlPc2NpbGxhdG9yLnByb3RvdHlwZSwgJ3NwcmVhZCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3NvdXJjZVR5cGUgPT09IE9tbmlPc2NUeXBlLkZhdCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3Iuc3ByZWFkO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChzcHJlYWQpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3NvdXJjZVR5cGUgPT09IE9tbmlPc2NUeXBlLkZhdCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zcHJlYWQgPSBzcHJlYWQ7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSB0eXBlIG9mIHRoZSBtb2R1bGF0b3Igb3NjaWxsYXRvci4gT25seSBpZiB0aGUgb3NjaWxsYXRvclxuXHRcdCAqIGlzIHNldCB0byBcImFtXCIgb3IgXCJmbVwiIHR5cGVzLiBzZWUuIFRvbmUuQU1Pc2NpbGxhdG9yIG9yIFRvbmUuRk1Pc2NpbGxhdG9yXG5cdFx0ICogZm9yIG1vcmUgaW5mby5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5PbW5pT3NjaWxsYXRvciNcblx0XHQgKiBAdHlwZSB7U3RyaW5nfVxuXHRcdCAqIEBuYW1lIG1vZHVsYXRpb25UeXBlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5PbW5pT3NjaWxsYXRvci5wcm90b3R5cGUsICdtb2R1bGF0aW9uVHlwZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3NvdXJjZVR5cGUgPT09IE9tbmlPc2NUeXBlLkZNIHx8IHRoaXMuX3NvdXJjZVR5cGUgPT09IE9tbmlPc2NUeXBlLkFNKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5tb2R1bGF0aW9uVHlwZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobVR5cGUpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3NvdXJjZVR5cGUgPT09IE9tbmlPc2NUeXBlLkZNIHx8IHRoaXMuX3NvdXJjZVR5cGUgPT09IE9tbmlPc2NUeXBlLkFNKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLm1vZHVsYXRpb25UeXBlID0gbVR5cGU7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBtb2R1bGF0aW9uIGluZGV4IHdoaWNoIGlzIGluIGVzc2VuY2UgdGhlIGRlcHRoIG9yIGFtb3VudCBvZiB0aGUgbW9kdWxhdGlvbi4gSW4gb3RoZXIgdGVybXMgaXQgaXMgdGhlXG5cdFx0ICogcmF0aW8gb2YgdGhlIGZyZXF1ZW5jeSBvZiB0aGUgbW9kdWxhdGluZyBzaWduYWwgKG1mKSB0byB0aGUgYW1wbGl0dWRlIG9mIHRoZVxuXHRcdCAqIG1vZHVsYXRpbmcgc2lnbmFsIChtYSkgLS0gYXMgaW4gbWEvbWYuXG5cdFx0ICogU2VlIFRvbmUuRk1Pc2NpbGxhdG9yIGZvciBtb3JlIGluZm8uXG5cdFx0ICogQHR5cGUge1Bvc2l0aXZlfVxuXHRcdCAqIEBzaWduYWxcblx0XHQgKiBAbmFtZSBtb2R1bGF0aW9uSW5kZXhcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLk9tbmlPc2NpbGxhdG9yLnByb3RvdHlwZSwgJ21vZHVsYXRpb25JbmRleCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3NvdXJjZVR5cGUgPT09IE9tbmlPc2NUeXBlLkZNKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5tb2R1bGF0aW9uSW5kZXg7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBIYXJtb25pY2l0eSBpcyB0aGUgZnJlcXVlbmN5IHJhdGlvIGJldHdlZW4gdGhlIGNhcnJpZXIgYW5kIHRoZSBtb2R1bGF0b3Igb3NjaWxsYXRvcnMuXG5cdFx0ICogIEEgaGFybW9uaWNpdHkgb2YgMSBnaXZlcyBib3RoIG9zY2lsbGF0b3JzIHRoZSBzYW1lIGZyZXF1ZW5jeS5cblx0XHQgKiAgSGFybW9uaWNpdHkgPSAyIG1lYW5zIGEgY2hhbmdlIG9mIGFuIG9jdGF2ZS4gU2VlIFRvbmUuQU1Pc2NpbGxhdG9yIG9yIFRvbmUuRk1Pc2NpbGxhdG9yXG5cdFx0ICogIGZvciBtb3JlIGluZm8uXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLk9tbmlPc2NpbGxhdG9yI1xuXHRcdCAqICBAc2lnbmFsXG5cdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHQgKiAgQG5hbWUgaGFybW9uaWNpdHlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLk9tbmlPc2NpbGxhdG9yLnByb3RvdHlwZSwgJ2hhcm1vbmljaXR5Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fc291cmNlVHlwZSA9PT0gT21uaU9zY1R5cGUuRk0gfHwgdGhpcy5fc291cmNlVHlwZSA9PT0gT21uaU9zY1R5cGUuQU0pIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLmhhcm1vbmljaXR5O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgbW9kdWxhdGlvbkZyZXF1ZW5jeSBTaWduYWwgb2YgdGhlIG9zY2lsbGF0b3Jcblx0XHQgKiAob25seSBpZiB0aGUgb3NjaWxsYXRvciB0eXBlIGlzIHNldCB0byBwd20pLiBTZWVcblx0XHQgKiBUb25lLlBXTU9zY2lsbGF0b3IgZm9yIG1vcmUgaW5mby5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5PbW5pT3NjaWxsYXRvciNcblx0XHQgKiBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdCAqIEBzaWduYWxcblx0XHQgKiBAbmFtZSBtb2R1bGF0aW9uRnJlcXVlbmN5XG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiB2YXIgb21uaU9zYyA9IG5ldyBUb25lLk9tbmlPc2NpbGxhdG9yKDQ0MCwgXCJwd21cIik7XG5cdFx0ICogLy9jYW4gYWNjZXNzIHRoZSBtb2R1bGF0aW9uRnJlcXVlbmN5IGF0dHJpYnV0ZSBvbmx5IGlmIHR5cGUgPT09IFwicHdtXCJcblx0XHQgKiBvbW5pT3NjLm1vZHVsYXRpb25GcmVxdWVuY3kudmFsdWUgPSAwLjI7XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5PbW5pT3NjaWxsYXRvci5wcm90b3R5cGUsICdtb2R1bGF0aW9uRnJlcXVlbmN5Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fc291cmNlVHlwZSA9PT0gT21uaU9zY1R5cGUuUFdNKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5tb2R1bGF0aW9uRnJlcXVlbmN5O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm4ge1RvbmUuT21uaU9zY2lsbGF0b3J9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuT21uaU9zY2lsbGF0b3IucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5Tb3VyY2UucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnZGV0dW5lJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmRldHVuZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9zb3VyY2VUeXBlID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5PbW5pT3NjaWxsYXRvcjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBCYXNlLWNsYXNzIGZvciBhbGwgaW5zdHJ1bWVudHNcblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuQXVkaW9Ob2RlfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5JbnN0cnVtZW50ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcblx0ICAgICAgICAvL2dldCB0aGUgZGVmYXVsdHNcblx0ICAgICAgICBvcHRpb25zID0gVG9uZS5kZWZhdWx0QXJnKG9wdGlvbnMsIFRvbmUuSW5zdHJ1bWVudC5kZWZhdWx0cyk7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgb3V0cHV0IGFuZCB2b2x1bWUgdHJpbWluZyBub2RlXG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLlZvbHVtZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fdm9sdW1lID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZS5Wb2x1bWUob3B0aW9ucy52b2x1bWUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIHZvbHVtZSBvZiB0aGUgb3V0cHV0IGluIGRlY2liZWxzLlxuXHRcdFx0ICogQHR5cGUge0RlY2liZWxzfVxuXHRcdFx0ICogQHNpZ25hbFxuXHRcdFx0ICogQGV4YW1wbGVcblx0XHRcdCAqIHNvdXJjZS52b2x1bWUudmFsdWUgPSAtNjtcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5fdm9sdW1lLnZvbHVtZTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seSgndm9sdW1lJyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBLZWVwIHRyYWNrIG9mIGFsbCBldmVudHMgc2NoZWR1bGVkIHRvIHRoZSB0cmFuc3BvcnRcblx0XHRcdCAqIHdoZW4gdGhlIGluc3RydW1lbnQgaXMgJ3N5bmNlZCdcblx0XHRcdCAqIEB0eXBlIHtBcnJheTxOdW1iZXI+fVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50cyA9IFtdO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuSW5zdHJ1bWVudCwgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogIHRoZSBkZWZhdWx0IGF0dHJpYnV0ZXNcblx0XHQgKiAgQHR5cGUge29iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuSW5zdHJ1bWVudC5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAvKiogdGhlIHZvbHVtZSBvZiB0aGUgb3V0cHV0IGluIGRlY2liZWxzICovXG5cdCAgICAgICAgJ3ZvbHVtZSc6IDBcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQGFic3RyYWN0XG5cdFx0ICogIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gbm90ZSB0aGUgbm90ZSB0byB0cmlnZ2VyXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW3RpbWU9bm93XSB0aGUgdGltZSB0byB0cmlnZ2VyIHRoZSBudG9lXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSBbdmVsb2NpdHk9MV0gdGhlIHZlbG9jaXR5IHRvIHRyaWdnZXIgdGhlIG5vdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuSW5zdHJ1bWVudC5wcm90b3R5cGUudHJpZ2dlckF0dGFjayA9IFRvbmUubm9PcDtcblx0ICAgIC8qKlxuXHRcdCAqICBAYWJzdHJhY3Rcblx0XHQgKiAgQHBhcmFtIHtUaW1lfSBbdGltZT1ub3ddIHdoZW4gdG8gdHJpZ2dlciB0aGUgcmVsZWFzZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5JbnN0cnVtZW50LnByb3RvdHlwZS50cmlnZ2VyUmVsZWFzZSA9IFRvbmUubm9PcDtcblx0ICAgIC8qKlxuXHRcdCAqIFN5bmMgdGhlIGluc3RydW1lbnQgdG8gdGhlIFRyYW5zcG9ydC4gQWxsIHN1YnNlcXVlbnQgY2FsbHMgb2Zcblx0XHQgKiBbdHJpZ2dlckF0dGFja10oI3RyaWdnZXJhdHRhY2spIGFuZCBbdHJpZ2dlclJlbGVhc2VdKCN0cmlnZ2VycmVsZWFzZSlcblx0XHQgKiB3aWxsIGJlIHNjaGVkdWxlZCBhbG9uZyB0aGUgdHJhbnNwb3J0LlxuXHRcdCAqIEBleGFtcGxlXG5cdFx0ICogaW5zdHJ1bWVudC5zeW5jKClcblx0XHQgKiAvL3NjaGVkdWxlIDMgbm90ZXMgd2hlbiB0aGUgdHJhbnNwb3J0IGZpcnN0IHN0YXJ0c1xuXHRcdCAqIGluc3RydW1lbnQudHJpZ2dlckF0dGFja1JlbGVhc2UoJ0M0JywgJzhuJywgMClcblx0XHQgKiBpbnN0cnVtZW50LnRyaWdnZXJBdHRhY2tSZWxlYXNlKCdFNCcsICc4bicsICc4bicpXG5cdFx0ICogaW5zdHJ1bWVudC50cmlnZ2VyQXR0YWNrUmVsZWFzZSgnRzQnLCAnOG4nLCAnNG4nKVxuXHRcdCAqIC8vc3RhcnQgdGhlIHRyYW5zcG9ydCB0byBoZWFyIHRoZSBub3Rlc1xuXHRcdCAqIFRyYW5zcG9ydC5zdGFydCgpXG5cdFx0ICogQHJldHVybnMge1RvbmUuSW5zdHJ1bWVudH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5JbnN0cnVtZW50LnByb3RvdHlwZS5zeW5jID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoJ3RyaWdnZXJBdHRhY2snLCAxKTtcblx0ICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKCd0cmlnZ2VyUmVsZWFzZScsIDApO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFdyYXAgdGhlIGdpdmVuIG1ldGhvZCBzbyB0aGF0IGl0IGNhbiBiZSBzeW5jaHJvbml6ZWRcblx0XHQgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIFdoaWNoIG1ldGhvZCB0byB3cmFwIGFuZCBzeW5jXG5cdFx0ICogQHBhcmFtICB7TnVtYmVyfSB0aW1lUG9zaXRpb24gV2hhdCBwb3NpdGlvbiB0aGUgdGltZSBhcmd1bWVudCBhcHBlYXJzIGluXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuSW5zdHJ1bWVudC5wcm90b3R5cGUuX3N5bmNNZXRob2QgPSBmdW5jdGlvbiAobWV0aG9kLCB0aW1lUG9zaXRpb24pIHtcblx0ICAgICAgICB2YXIgb3JpZ2luYWxNZXRob2QgPSB0aGlzWydfb3JpZ2luYWxfJyArIG1ldGhvZF0gPSB0aGlzW21ldGhvZF07XG5cdCAgICAgICAgdGhpc1ttZXRob2RdID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cdCAgICAgICAgICAgIHZhciB0aW1lID0gYXJnc1t0aW1lUG9zaXRpb25dO1xuXHQgICAgICAgICAgICB2YXIgaWQgPSBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZShmdW5jdGlvbiAodCkge1xuXHQgICAgICAgICAgICAgICAgYXJnc1t0aW1lUG9zaXRpb25dID0gdDtcblx0ICAgICAgICAgICAgICAgIG9yaWdpbmFsTWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHQgICAgICAgICAgICB9LmJpbmQodGhpcyksIHRpbWUpO1xuXHQgICAgICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMucHVzaChpZCk7XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFVuc3luYyB0aGUgaW5zdHJ1bWVudCBmcm9tIHRoZSBUcmFuc3BvcnRcblx0XHQgKiBAcmV0dXJucyB7VG9uZS5JbnN0cnVtZW50fSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkluc3RydW1lbnQucHJvdG90eXBlLnVuc3luYyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMuZm9yRWFjaChmdW5jdGlvbiAoaWQpIHtcblx0ICAgICAgICAgICAgVG9uZS5UcmFuc3BvcnQuY2xlYXIoaWQpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50cyA9IFtdO1xuXHQgICAgICAgIGlmICh0aGlzLl9vcmlnaW5hbF90cmlnZ2VyQXR0YWNrKSB7XG5cdCAgICAgICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayA9IHRoaXMuX29yaWdpbmFsX3RyaWdnZXJBdHRhY2s7XG5cdCAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2UgPSB0aGlzLl9vcmlnaW5hbF90cmlnZ2VyUmVsZWFzZTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRyaWdnZXIgdGhlIGF0dGFjayBhbmQgdGhlbiB0aGUgcmVsZWFzZSBhZnRlciB0aGUgZHVyYXRpb24uXG5cdFx0ICogIEBwYXJhbSAge0ZyZXF1ZW5jeX0gbm90ZSAgICAgVGhlIG5vdGUgdG8gdHJpZ2dlci5cblx0XHQgKiAgQHBhcmFtICB7VGltZX0gZHVyYXRpb24gSG93IGxvbmcgdGhlIG5vdGUgc2hvdWxkIGJlIGhlbGQgZm9yIGJlZm9yZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyaW5nIHRoZSByZWxlYXNlLiBUaGlzIHZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAuXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW3RpbWU9bm93XSAgV2hlbiB0aGUgbm90ZSBzaG91bGQgYmUgdHJpZ2dlcmVkLlxuXHRcdCAqICBAcGFyYW0gIHtOb3JtYWxSYW5nZX0gW3ZlbG9jaXR5PTFdIFRoZSB2ZWxvY2l0eSB0aGUgbm90ZSBzaG91bGQgYmUgdHJpZ2dlcmVkIGF0LlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5JbnN0cnVtZW50fSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy90cmlnZ2VyIFwiQzRcIiBmb3IgdGhlIGR1cmF0aW9uIG9mIGFuIDh0aCBub3RlXG5cdFx0ICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5JbnN0cnVtZW50LnByb3RvdHlwZS50cmlnZ2VyQXR0YWNrUmVsZWFzZSA9IGZ1bmN0aW9uIChub3RlLCBkdXJhdGlvbiwgdGltZSwgdmVsb2NpdHkpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgZHVyYXRpb24gPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG5cdCAgICAgICAgdGhpcy50cmlnZ2VyQXR0YWNrKG5vdGUsIHRpbWUsIHZlbG9jaXR5KTtcblx0ICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKHRpbWUgKyBkdXJhdGlvbik7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkluc3RydW1lbnR9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuSW5zdHJ1bWVudC5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fdm9sdW1lID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbJ3ZvbHVtZSddKTtcblx0ICAgICAgICB0aGlzLnZvbHVtZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy51bnN5bmMoKTtcblx0ICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkluc3RydW1lbnQ7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgVGhpcyBpcyBhbiBhYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBvdGhlciBtb25vcGhvbmljIGluc3RydW1lbnRzIHRvIFxuXHRcdCAqICAgICAgICAgIGV4dGVuZC4gSU1QT1JUQU5UOiBJdCBkb2VzIG5vdCBtYWtlIGFueSBzb3VuZCBvbiBpdHMgb3duIGFuZFxuXHRcdCAqICAgICAgICAgIHNob3VsZG4ndCBiZSBkaXJlY3RseSBpbnN0YW50aWF0ZWQuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBhYnN0cmFjdFxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5JbnN0cnVtZW50fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Nb25vcGhvbmljID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcblx0ICAgICAgICAvL2dldCB0aGUgZGVmYXVsdHNcblx0ICAgICAgICBvcHRpb25zID0gVG9uZS5kZWZhdWx0QXJnKG9wdGlvbnMsIFRvbmUuTW9ub3Bob25pYy5kZWZhdWx0cyk7XG5cdCAgICAgICAgVG9uZS5JbnN0cnVtZW50LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGdsaWRlIHRpbWUgYmV0d2VlbiBub3Rlcy4gXG5cdFx0XHQgKiAgQHR5cGUge1RpbWV9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnBvcnRhbWVudG8gPSBvcHRpb25zLnBvcnRhbWVudG87XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5Nb25vcGhvbmljLCBUb25lLkluc3RydW1lbnQpO1xuXHQgICAgLyoqXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQGNvbnN0XG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLk1vbm9waG9uaWMuZGVmYXVsdHMgPSB7ICdwb3J0YW1lbnRvJzogMCB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRyaWdnZXIgdGhlIGF0dGFjayBvZiB0aGUgbm90ZSBvcHRpb25hbGx5IHdpdGggYSBnaXZlbiB2ZWxvY2l0eS4gXG5cdFx0ICogIFxuXHRcdCAqICBcblx0XHQgKiAgQHBhcmFtICB7RnJlcXVlbmN5fSBub3RlICAgICBUaGUgbm90ZSB0byB0cmlnZ2VyLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddICAgICBXaGVuIHRoZSBub3RlIHNob3VsZCBzdGFydC5cblx0XHQgKiAgQHBhcmFtICB7bnVtYmVyfSBbdmVsb2NpdHk9MV0gdmVsb2NpdHkgVGhlIHZlbG9jaXR5IHNjYWxlciBcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV0ZXJtaW5lcyBob3cgXCJsb3VkXCIgdGhlIG5vdGUgXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgYmUgdHJpZ2dlcmVkLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5Nb25vcGhvbmljfSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogc3ludGgudHJpZ2dlckF0dGFjayhcIkM0XCIpO1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vdHJpZ2dlciB0aGUgbm90ZSBhIGhhbGYgc2Vjb25kIGZyb20gbm93IGF0IGhhbGYgdmVsb2NpdHlcblx0XHQgKiBzeW50aC50cmlnZ2VyQXR0YWNrKFwiQzRcIiwgXCIrMC41XCIsIDAuNSk7XG5cdFx0ICovXG5cdCAgICBUb25lLk1vbm9waG9uaWMucHJvdG90eXBlLnRyaWdnZXJBdHRhY2sgPSBmdW5jdGlvbiAobm90ZSwgdGltZSwgdmVsb2NpdHkpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdGhpcy5fdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcblx0ICAgICAgICB0aGlzLnNldE5vdGUobm90ZSwgdGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRyaWdnZXIgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gW3RpbWU9bm93XSBJZiBubyB0aW1lIGlzIGdpdmVuLCB0aGUgcmVsZWFzZSBoYXBwZW5zIGltbWVkaWF0bHlcblx0XHQgKiAgQHJldHVybnMge1RvbmUuTW9ub3Bob25pY30gdGhpc1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHN5bnRoLnRyaWdnZXJSZWxlYXNlKCk7XG5cdFx0ICovXG5cdCAgICBUb25lLk1vbm9waG9uaWMucHJvdG90eXBlLnRyaWdnZXJSZWxlYXNlID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdGhpcy5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgb3ZlcnJpZGUgdGhpcyBtZXRob2Qgd2l0aCB0aGUgYWN0dWFsIG1ldGhvZFxuXHRcdCAqICBAYWJzdHJhY3Rcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuTW9ub3Bob25pYy5wcm90b3R5cGUuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayA9IGZ1bmN0aW9uICgpIHtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgb3ZlcnJpZGUgdGhpcyBtZXRob2Qgd2l0aCB0aGUgYWN0dWFsIG1ldGhvZFxuXHRcdCAqICBAYWJzdHJhY3Rcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuTW9ub3Bob25pYy5wcm90b3R5cGUuX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEdldCB0aGUgbGV2ZWwgb2YgdGhlIG91dHB1dCBhdCB0aGUgZ2l2ZW4gdGltZS4gTWVhc3VyZXNcblx0XHQgKiAgdGhlIGVudmVsb3BlKHMpIHZhbHVlIGF0IHRoZSB0aW1lLiBcblx0XHQgKiAgQHBhcmFtIHtUaW1lfSB0aW1lIFRoZSB0aW1lIHRvIHF1ZXJ5IHRoZSBlbnZlbG9wZSB2YWx1ZVxuXHRcdCAqICBAcmV0dXJuIHtOb3JtYWxSYW5nZX0gVGhlIG91dHB1dCBsZXZlbCBiZXR3ZWVuIDAtMVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Nb25vcGhvbmljLnByb3RvdHlwZS5nZXRMZXZlbEF0VGltZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHJldHVybiB0aGlzLmVudmVsb3BlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTZXQgdGhlIG5vdGUgYXQgdGhlIGdpdmVuIHRpbWUuIElmIG5vIHRpbWUgaXMgZ2l2ZW4sIHRoZSBub3RlXG5cdFx0ICogIHdpbGwgc2V0IGltbWVkaWF0ZWx5LiBcblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l9IG5vdGUgVGhlIG5vdGUgdG8gY2hhbmdlIHRvLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddIFRoZSB0aW1lIHdoZW4gdGhlIG5vdGUgc2hvdWxkIGJlIHNldC4gXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk1vbm9waG9uaWN9IHRoaXNcblx0XHQgKiBAZXhhbXBsZVxuXHRcdCAqIC8vY2hhbmdlIHRvIEYjNiBpbiBvbmUgcXVhcnRlciBub3RlIGZyb20gbm93LlxuXHRcdCAqIHN5bnRoLnNldE5vdGUoXCJGIzZcIiwgXCIrNG5cIik7XG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiAvL2NoYW5nZSB0byBCYjQgcmlnaHQgbm93XG5cdFx0ICogc3ludGguc2V0Tm90ZShcIkJiNFwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuTW9ub3Bob25pYy5wcm90b3R5cGUuc2V0Tm90ZSA9IGZ1bmN0aW9uIChub3RlLCB0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIGlmICh0aGlzLnBvcnRhbWVudG8gPiAwICYmIHRoaXMuZ2V0TGV2ZWxBdFRpbWUodGltZSkgPiAwLjA1KSB7XG5cdCAgICAgICAgICAgIHZhciBwb3J0VGltZSA9IHRoaXMudG9TZWNvbmRzKHRoaXMucG9ydGFtZW50byk7XG5cdCAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmV4cG9uZW50aWFsUmFtcFRvKG5vdGUsIHBvcnRUaW1lLCB0aW1lKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5zZXRWYWx1ZUF0VGltZShub3RlLCB0aW1lKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuTW9ub3Bob25pYztcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBUb25lLlN5bnRoIGlzIGNvbXBvc2VkIHNpbXBseSBvZiBhIFRvbmUuT21uaU9zY2lsbGF0b3Jcblx0XHQgKiAgICAgICAgICByb3V0ZWQgdGhyb3VnaCBhIFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUuXG5cdFx0ICogICAgICAgICAgPGltZyBzcmM9XCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9kcmF3aW5ncy9kLzEtMV8wWVcyWjFKMkVQSTM2UDhmTkNNY1pHN04xdzFHWmx1UHM0b2c0ZXZvL3B1Yj93PTExNjMmaD0yMzFcIj5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuTW9ub3Bob25pY31cblx0XHQgKiAgQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSB0aGUgb3B0aW9ucyBhdmFpbGFibGUgZm9yIHRoZSBzeW50aFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICBzZWUgZGVmYXVsdHMgYmVsb3dcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvTWFzdGVyKCk7XG5cdFx0ICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5TeW50aCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cdCAgICAgICAgLy9nZXQgdGhlIGRlZmF1bHRzXG5cdCAgICAgICAgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdEFyZyhvcHRpb25zLCBUb25lLlN5bnRoLmRlZmF1bHRzKTtcblx0ICAgICAgICBUb25lLk1vbm9waG9uaWMuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgb3NjaWxsYXRvci5cblx0XHRcdCAqICBAdHlwZSB7VG9uZS5PbW5pT3NjaWxsYXRvcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMub3NjaWxsYXRvciA9IG5ldyBUb25lLk9tbmlPc2NpbGxhdG9yKG9wdGlvbnMub3NjaWxsYXRvcik7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGZyZXF1ZW5jeSBjb250cm9sLlxuXHRcdFx0ICogIEB0eXBlIHtGcmVxdWVuY3l9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLm9zY2lsbGF0b3IuZnJlcXVlbmN5O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBkZXR1bmUgY29udHJvbC5cblx0XHRcdCAqICBAdHlwZSB7Q2VudHN9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLm9zY2lsbGF0b3IuZGV0dW5lO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhbXBsaXR1ZGUgZW52ZWxvcGUuXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQW1wbGl0dWRlRW52ZWxvcGV9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUob3B0aW9ucy5lbnZlbG9wZSk7XG5cdCAgICAgICAgLy9jb25uZWN0IHRoZSBvc2NpbGxhdG9ycyB0byB0aGUgb3V0cHV0XG5cdCAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmNoYWluKHRoaXMuZW52ZWxvcGUsIHRoaXMub3V0cHV0KTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdvc2NpbGxhdG9yJyxcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdkZXR1bmUnLFxuXHQgICAgICAgICAgICAnZW52ZWxvcGUnXG5cdCAgICAgICAgXSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5TeW50aCwgVG9uZS5Nb25vcGhvbmljKTtcblx0ICAgIC8qKlxuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5TeW50aC5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnb3NjaWxsYXRvcic6IHsgJ3R5cGUnOiAndHJpYW5nbGUnIH0sXG5cdCAgICAgICAgJ2VudmVsb3BlJzoge1xuXHQgICAgICAgICAgICAnYXR0YWNrJzogMC4wMDUsXG5cdCAgICAgICAgICAgICdkZWNheSc6IDAuMSxcblx0ICAgICAgICAgICAgJ3N1c3RhaW4nOiAwLjMsXG5cdCAgICAgICAgICAgICdyZWxlYXNlJzogMVxuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgc3RhcnQgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IFt0aW1lPW5vd10gdGhlIHRpbWUgdGhlIGF0dGFjayBzaG91bGQgc3RhcnRcblx0XHQgKiAgQHBhcmFtIHtudW1iZXJ9IFt2ZWxvY2l0eT0xXSB0aGUgdmVsb2NpdHkgb2YgdGhlIG5vdGUgKDAtMSlcblx0XHQgKiAgQHJldHVybnMge1RvbmUuU3ludGh9IHRoaXNcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuU3ludGgucHJvdG90eXBlLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sgPSBmdW5jdGlvbiAodGltZSwgdmVsb2NpdHkpIHtcblx0ICAgICAgICAvL3RoZSBlbnZlbG9wZXNcblx0ICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuXHQgICAgICAgIHRoaXMub3NjaWxsYXRvci5zdGFydCh0aW1lKTtcblx0ICAgICAgICAvL2lmIHRoZXJlIGlzIG5vIHJlbGVhc2UgcG9ydGlvbiwgc3RvcCB0aGUgb3NjaWxsYXRvclxuXHQgICAgICAgIGlmICh0aGlzLmVudmVsb3BlLnN1c3RhaW4gPT09IDApIHtcblx0ICAgICAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0b3AodGltZSArIHRoaXMuZW52ZWxvcGUuYXR0YWNrICsgdGhpcy5lbnZlbG9wZS5kZWNheSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBzdGFydCB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IFt0aW1lPW5vd10gdGhlIHRpbWUgdGhlIHJlbGVhc2Ugc2hvdWxkIHN0YXJ0XG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlN5bnRofSB0aGlzXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlN5bnRoLnByb3RvdHlwZS5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlclJlbGVhc2UodGltZSk7XG5cdCAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0b3AodGltZSArIHRoaXMuZW52ZWxvcGUucmVsZWFzZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlN5bnRofSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlN5bnRoLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuTW9ub3Bob25pYy5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ29zY2lsbGF0b3InLFxuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2RldHVuZScsXG5cdCAgICAgICAgICAgICdlbnZlbG9wZSdcblx0ICAgICAgICBdKTtcblx0ICAgICAgICB0aGlzLm9zY2lsbGF0b3IuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMub3NjaWxsYXRvciA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5lbnZlbG9wZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZGV0dW5lID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5TeW50aDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBBTVN5bnRoIHVzZXMgdGhlIG91dHB1dCBvZiBvbmUgVG9uZS5TeW50aCB0byBtb2R1bGF0ZSB0aGVcblx0XHQgKiAgICAgICAgICBhbXBsaXR1ZGUgb2YgYW5vdGhlciBUb25lLlN5bnRoLiBUaGUgaGFybW9uaWNpdHkgKHRoZSByYXRpbyBiZXR3ZWVuXG5cdFx0ICogICAgICAgICAgdGhlIHR3byBzaWduYWxzKSBhZmZlY3RzIHRoZSB0aW1icmUgb2YgdGhlIG91dHB1dCBzaWduYWwgZ3JlYXRseS5cblx0XHQgKiAgICAgICAgICBSZWFkIG1vcmUgYWJvdXQgQW1wbGl0dWRlIE1vZHVsYXRpb24gU3ludGhlc2lzIG9uXG5cdFx0ICogICAgICAgICAgW1NvdW5kT25Tb3VuZF0oaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTYwNDA0MTAzNjUzL2h0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbTo4MC9zb3MvbWFyMDAvYXJ0aWNsZXMvc3ludGhzZWNyZXRzLmh0bSkuXG5cdFx0ICogICAgICAgICAgPGltZyBzcmM9XCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9kcmF3aW5ncy9kLzFUUXU4RWQ0aUZyMVlUTEtwQjNVMV9odXItVXdCcmg1Z2RCWGM4QnhmR0t3L3B1Yj93PTEwMDkmaD00NTdcIj5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuTW9ub3Bob25pY31cblx0XHQgKiAgQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSB0aGUgb3B0aW9ucyBhdmFpbGFibGUgZm9yIHRoZSBzeW50aFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZSBkZWZhdWx0cyBiZWxvd1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBzeW50aCA9IG5ldyBUb25lLkFNU3ludGgoKS50b01hc3RlcigpO1xuXHRcdCAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCI0blwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuQU1TeW50aCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cdCAgICAgICAgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdEFyZyhvcHRpb25zLCBUb25lLkFNU3ludGguZGVmYXVsdHMpO1xuXHQgICAgICAgIFRvbmUuTW9ub3Bob25pYy5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBjYXJyaWVyIHZvaWNlLlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLlN5bnRofVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9jYXJyaWVyID0gbmV3IFRvbmUuU3ludGgoKTtcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyLnZvbHVtZS52YWx1ZSA9IC0xMDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgY2FycmllcidzIG9zY2lsbGF0b3Jcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5Pc2NpbGxhdG9yfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5vc2NpbGxhdG9yID0gdGhpcy5fY2Fycmllci5vc2NpbGxhdG9yO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBjYXJyaWVyJ3MgZW52ZWxvcGVcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5BbXBsaXR1ZGVFbnZlbG9wZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUgPSB0aGlzLl9jYXJyaWVyLmVudmVsb3BlLnNldChvcHRpb25zLmVudmVsb3BlKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbW9kdWxhdG9yIHZvaWNlLlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLlN5bnRofVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3IgPSBuZXcgVG9uZS5TeW50aCgpO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvci52b2x1bWUudmFsdWUgPSAtMTA7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG1vZHVsYXRvcidzIG9zY2lsbGF0b3Igd2hpY2ggaXMgYXBwbGllZFxuXHRcdFx0ICogIHRvIHRoZSBhbXBsaXR1ZGUgb2YgdGhlIG9zY2lsbGF0b3Jcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5Pc2NpbGxhdG9yfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5tb2R1bGF0aW9uID0gdGhpcy5fbW9kdWxhdG9yLm9zY2lsbGF0b3Iuc2V0KG9wdGlvbnMubW9kdWxhdGlvbik7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG1vZHVsYXRvcidzIGVudmVsb3BlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQW1wbGl0dWRlRW52ZWxvcGV9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLm1vZHVsYXRpb25FbnZlbG9wZSA9IHRoaXMuX21vZHVsYXRvci5lbnZlbG9wZS5zZXQob3B0aW9ucy5tb2R1bGF0aW9uRW52ZWxvcGUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBmcmVxdWVuY3kuXG5cdFx0XHQgKiAgQHR5cGUge0ZyZXF1ZW5jeX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBUb25lLlNpZ25hbCg0NDAsIFRvbmUuVHlwZS5GcmVxdWVuY3kpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBkZXR1bmUgaW4gY2VudHNcblx0XHRcdCAqICBAdHlwZSB7Q2VudHN9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgVG9uZS5TaWduYWwob3B0aW9ucy5kZXR1bmUsIFRvbmUuVHlwZS5DZW50cyk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgSGFybW9uaWNpdHkgaXMgdGhlIHJhdGlvIGJldHdlZW4gdGhlIHR3byB2b2ljZXMuIEEgaGFybW9uaWNpdHkgb2Zcblx0XHRcdCAqICAxIGlzIG5vIGNoYW5nZS4gSGFybW9uaWNpdHkgPSAyIG1lYW5zIGEgY2hhbmdlIG9mIGFuIG9jdGF2ZS5cblx0XHRcdCAqICBAdHlwZSB7UG9zaXRpdmV9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICogIEBleGFtcGxlXG5cdFx0XHQgKiAvL3BpdGNoIHZvaWNlMSBhbiBvY3RhdmUgYmVsb3cgdm9pY2UwXG5cdFx0XHQgKiBzeW50aC5oYXJtb25pY2l0eS52YWx1ZSA9IDAuNTtcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuaGFybW9uaWNpdHkgPSBuZXcgVG9uZS5NdWx0aXBseShvcHRpb25zLmhhcm1vbmljaXR5KTtcblx0ICAgICAgICB0aGlzLmhhcm1vbmljaXR5LnVuaXRzID0gVG9uZS5UeXBlLlBvc2l0aXZlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGNvbnZlcnQgdGhlIC0xLDEgb3V0cHV0IHRvIDAsMVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkF1ZGlvVG9HYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9tb2R1bGF0aW9uU2NhbGUgPSBuZXcgVG9uZS5BdWRpb1RvR2FpbigpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBub2RlIHdoZXJlIHRoZSBtb2R1bGF0aW9uIGhhcHBlbnNcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5HYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZSA9IG5ldyBUb25lLkdhaW4oKTtcblx0ICAgICAgICAvL2NvbnRyb2wgdGhlIHR3byB2b2ljZXMgZnJlcXVlbmN5XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9jYXJyaWVyLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5oYXJtb25pY2l0eSwgdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgdGhpcy5kZXR1bmUuZmFuKHRoaXMuX2NhcnJpZXIuZGV0dW5lLCB0aGlzLl9tb2R1bGF0b3IuZGV0dW5lKTtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3IuY2hhaW4odGhpcy5fbW9kdWxhdGlvblNjYWxlLCB0aGlzLl9tb2R1bGF0aW9uTm9kZS5nYWluKTtcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyLmNoYWluKHRoaXMuX21vZHVsYXRpb25Ob2RlLCB0aGlzLm91dHB1dCk7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoW1xuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2hhcm1vbmljaXR5Jyxcblx0ICAgICAgICAgICAgJ29zY2lsbGF0b3InLFxuXHQgICAgICAgICAgICAnZW52ZWxvcGUnLFxuXHQgICAgICAgICAgICAnbW9kdWxhdGlvbicsXG5cdCAgICAgICAgICAgICdtb2R1bGF0aW9uRW52ZWxvcGUnLFxuXHQgICAgICAgICAgICAnZGV0dW5lJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuQU1TeW50aCwgVG9uZS5Nb25vcGhvbmljKTtcblx0ICAgIC8qKlxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkFNU3ludGguZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2hhcm1vbmljaXR5JzogMyxcblx0ICAgICAgICAnZGV0dW5lJzogMCxcblx0ICAgICAgICAnb3NjaWxsYXRvcic6IHsgJ3R5cGUnOiAnc2luZScgfSxcblx0ICAgICAgICAnZW52ZWxvcGUnOiB7XG5cdCAgICAgICAgICAgICdhdHRhY2snOiAwLjAxLFxuXHQgICAgICAgICAgICAnZGVjYXknOiAwLjAxLFxuXHQgICAgICAgICAgICAnc3VzdGFpbic6IDEsXG5cdCAgICAgICAgICAgICdyZWxlYXNlJzogMC41XG5cdCAgICAgICAgfSxcblx0ICAgICAgICAnbW9kdWxhdGlvbic6IHsgJ3R5cGUnOiAnc3F1YXJlJyB9LFxuXHQgICAgICAgICdtb2R1bGF0aW9uRW52ZWxvcGUnOiB7XG5cdCAgICAgICAgICAgICdhdHRhY2snOiAwLjUsXG5cdCAgICAgICAgICAgICdkZWNheSc6IDAsXG5cdCAgICAgICAgICAgICdzdXN0YWluJzogMSxcblx0ICAgICAgICAgICAgJ3JlbGVhc2UnOiAwLjVcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIHRyaWdnZXIgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBub3RlXG5cdFx0ICpcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gW3RpbWU9bm93XSB0aGUgdGltZSB0aGUgbm90ZSB3aWxsIG9jY3VyXG5cdFx0ICogIEBwYXJhbSB7Tm9ybWFsUmFuZ2V9IFt2ZWxvY2l0eT0xXSB0aGUgdmVsb2NpdHkgb2YgdGhlIG5vdGVcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKiAgQHJldHVybnMge1RvbmUuQU1TeW50aH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5BTVN5bnRoLnByb3RvdHlwZS5fdHJpZ2dlckVudmVsb3BlQXR0YWNrID0gZnVuY3Rpb24gKHRpbWUsIHZlbG9jaXR5KSB7XG5cdCAgICAgICAgLy90aGUgcG9ydCBnbGlkZVxuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICAvL3RoZSBlbnZlbG9wZXNcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvci5fdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICB0cmlnZ2VyIHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIG5vdGVcblx0XHQgKlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddIHRoZSB0aW1lIHRoZSBub3RlIHdpbGwgcmVsZWFzZVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5BTVN5bnRofSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkFNU3ludGgucHJvdG90eXBlLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvci5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgY2xlYW4gdXBcblx0XHQgKiAgQHJldHVybnMge1RvbmUuQU1TeW50aH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5BTVN5bnRoLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuTW9ub3Bob25pYy5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICdoYXJtb25pY2l0eScsXG5cdCAgICAgICAgICAgICdvc2NpbGxhdG9yJyxcblx0ICAgICAgICAgICAgJ2VudmVsb3BlJyxcblx0ICAgICAgICAgICAgJ21vZHVsYXRpb24nLFxuXHQgICAgICAgICAgICAnbW9kdWxhdGlvbkVudmVsb3BlJyxcblx0ICAgICAgICAgICAgJ2RldHVuZSdcblx0ICAgICAgICBdKTtcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3IuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvciA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuaGFybW9uaWNpdHkuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuaGFybW9uaWNpdHkgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRpb25TY2FsZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdGlvblNjYWxlID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMub3NjaWxsYXRvciA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5tb2R1bGF0aW9uRW52ZWxvcGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMubW9kdWxhdGlvbiA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuQU1TeW50aDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBUb25lLk1vbm9TeW50aCBpcyBjb21wb3NlZCBvZiBvbmUgb3NjaWxsYXRvciwgb25lIGZpbHRlciwgYW5kIHR3byBlbnZlbG9wZXMuXG5cdFx0ICogICAgICAgICAgVGhlIGFtcGxpdHVkZSBvZiB0aGUgVG9uZS5Pc2NpbGxhdG9yIGFuZCB0aGUgY3V0b2ZmIGZyZXF1ZW5jeSBvZiB0aGVcblx0XHQgKiAgICAgICAgICBUb25lLkZpbHRlciBhcmUgY29udHJvbGxlZCBieSBUb25lLkVudmVsb3Blcy5cblx0XHQgKiAgICAgICAgICA8aW1nIHNyYz1cImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL2RyYXdpbmdzL2QvMWdhWTFERjlfSHprb2RxZjhKSTFDZzJWWmZ3U0VscEZRZkk5NElRd2FkMzgvcHViP3c9OTI0Jmg9MjQwXCI+XG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLk1vbm9waG9uaWN9XG5cdFx0ICogIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gdGhlIG9wdGlvbnMgYXZhaWxhYmxlIGZvciB0aGUgc3ludGhcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlIGRlZmF1bHRzIGJlbG93XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHN5bnRoID0gbmV3IFRvbmUuTW9ub1N5bnRoKHtcblx0XHQgKiBcdFwib3NjaWxsYXRvclwiIDoge1xuXHRcdCAqIFx0XHRcInR5cGVcIiA6IFwic3F1YXJlXCJcblx0XHQgKiAgfSxcblx0XHQgKiAgXCJlbnZlbG9wZVwiIDoge1xuXHRcdCAqICBcdFwiYXR0YWNrXCIgOiAwLjFcblx0XHQgKiAgfVxuXHRcdCAqIH0pLnRvTWFzdGVyKCk7XG5cdFx0ICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Nb25vU3ludGggPSBmdW5jdGlvbiAob3B0aW9ucykge1xuXHQgICAgICAgIC8vZ2V0IHRoZSBkZWZhdWx0c1xuXHQgICAgICAgIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRBcmcob3B0aW9ucywgVG9uZS5Nb25vU3ludGguZGVmYXVsdHMpO1xuXHQgICAgICAgIFRvbmUuTW9ub3Bob25pYy5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBvc2NpbGxhdG9yLlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLk9tbmlPc2NpbGxhdG9yfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5vc2NpbGxhdG9yID0gbmV3IFRvbmUuT21uaU9zY2lsbGF0b3Iob3B0aW9ucy5vc2NpbGxhdG9yKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZnJlcXVlbmN5IGNvbnRyb2wuXG5cdFx0XHQgKiAgQHR5cGUge0ZyZXF1ZW5jeX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMub3NjaWxsYXRvci5mcmVxdWVuY3k7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGRldHVuZSBjb250cm9sLlxuXHRcdFx0ICogIEB0eXBlIHtDZW50c31cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMub3NjaWxsYXRvci5kZXR1bmU7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGZpbHRlci5cblx0XHRcdCAqICBAdHlwZSB7VG9uZS5GaWx0ZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmZpbHRlciA9IG5ldyBUb25lLkZpbHRlcihvcHRpb25zLmZpbHRlcik7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGZpbHRlciBlbnZlbG9wZS5cblx0XHRcdCAqICBAdHlwZSB7VG9uZS5GcmVxdWVuY3lFbnZlbG9wZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZmlsdGVyRW52ZWxvcGUgPSBuZXcgVG9uZS5GcmVxdWVuY3lFbnZlbG9wZShvcHRpb25zLmZpbHRlckVudmVsb3BlKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgYW1wbGl0dWRlIGVudmVsb3BlLlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkFtcGxpdHVkZUVudmVsb3BlfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG5ldyBUb25lLkFtcGxpdHVkZUVudmVsb3BlKG9wdGlvbnMuZW52ZWxvcGUpO1xuXHQgICAgICAgIC8vY29ubmVjdCB0aGUgb3NjaWxsYXRvcnMgdG8gdGhlIG91dHB1dFxuXHQgICAgICAgIHRoaXMub3NjaWxsYXRvci5jaGFpbih0aGlzLmZpbHRlciwgdGhpcy5lbnZlbG9wZSwgdGhpcy5vdXRwdXQpO1xuXHQgICAgICAgIC8vY29ubmVjdCB0aGUgZmlsdGVyIGVudmVsb3BlXG5cdCAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZS5jb25uZWN0KHRoaXMuZmlsdGVyLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoW1xuXHQgICAgICAgICAgICAnb3NjaWxsYXRvcicsXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnZGV0dW5lJyxcblx0ICAgICAgICAgICAgJ2ZpbHRlcicsXG5cdCAgICAgICAgICAgICdmaWx0ZXJFbnZlbG9wZScsXG5cdCAgICAgICAgICAgICdlbnZlbG9wZSdcblx0ICAgICAgICBdKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLk1vbm9TeW50aCwgVG9uZS5Nb25vcGhvbmljKTtcblx0ICAgIC8qKlxuXHRcdCAqICBAY29uc3Rcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Nb25vU3ludGguZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ2ZyZXF1ZW5jeSc6ICdDNCcsXG5cdCAgICAgICAgJ2RldHVuZSc6IDAsXG5cdCAgICAgICAgJ29zY2lsbGF0b3InOiB7ICd0eXBlJzogJ3NxdWFyZScgfSxcblx0ICAgICAgICAnZmlsdGVyJzoge1xuXHQgICAgICAgICAgICAnUSc6IDYsXG5cdCAgICAgICAgICAgICd0eXBlJzogJ2xvd3Bhc3MnLFxuXHQgICAgICAgICAgICAncm9sbG9mZic6IC0yNFxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgJ2VudmVsb3BlJzoge1xuXHQgICAgICAgICAgICAnYXR0YWNrJzogMC4wMDUsXG5cdCAgICAgICAgICAgICdkZWNheSc6IDAuMSxcblx0ICAgICAgICAgICAgJ3N1c3RhaW4nOiAwLjksXG5cdCAgICAgICAgICAgICdyZWxlYXNlJzogMVxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgJ2ZpbHRlckVudmVsb3BlJzoge1xuXHQgICAgICAgICAgICAnYXR0YWNrJzogMC4wNixcblx0ICAgICAgICAgICAgJ2RlY2F5JzogMC4yLFxuXHQgICAgICAgICAgICAnc3VzdGFpbic6IDAuNSxcblx0ICAgICAgICAgICAgJ3JlbGVhc2UnOiAyLFxuXHQgICAgICAgICAgICAnYmFzZUZyZXF1ZW5jeSc6IDIwMCxcblx0ICAgICAgICAgICAgJ29jdGF2ZXMnOiA3LFxuXHQgICAgICAgICAgICAnZXhwb25lbnQnOiAyXG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBzdGFydCB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW3RpbWU9bm93XSB0aGUgdGltZSB0aGUgYXR0YWNrIHNob3VsZCBzdGFydFxuXHRcdCAqICBAcGFyYW0ge05vcm1hbFJhbmdlfSBbdmVsb2NpdHk9MV0gdGhlIHZlbG9jaXR5IG9mIHRoZSBub3RlICgwLTEpXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk1vbm9TeW50aH0gdGhpc1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Nb25vU3ludGgucHJvdG90eXBlLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sgPSBmdW5jdGlvbiAodGltZSwgdmVsb2NpdHkpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgLy90aGUgZW52ZWxvcGVzXG5cdCAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcblx0ICAgICAgICB0aGlzLmZpbHRlckVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSk7XG5cdCAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0YXJ0KHRpbWUpO1xuXHQgICAgICAgIGlmICh0aGlzLmVudmVsb3BlLnN1c3RhaW4gPT09IDApIHtcblx0ICAgICAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0b3AodGltZSArIHRoaXMuZW52ZWxvcGUuYXR0YWNrICsgdGhpcy5lbnZlbG9wZS5kZWNheSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBzdGFydCB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IFt0aW1lPW5vd10gdGhlIHRpbWUgdGhlIHJlbGVhc2Ugc2hvdWxkIHN0YXJ0XG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk1vbm9TeW50aH0gdGhpc1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Nb25vU3ludGgucHJvdG90eXBlLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuXHQgICAgICAgIHRoaXMuZmlsdGVyRW52ZWxvcGUudHJpZ2dlclJlbGVhc2UodGltZSk7XG5cdCAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0b3AodGltZSArIHRoaXMuZW52ZWxvcGUucmVsZWFzZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk1vbm9TeW50aH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Nb25vU3ludGgucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5Nb25vcGhvbmljLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fd3JpdGFibGUoW1xuXHQgICAgICAgICAgICAnb3NjaWxsYXRvcicsXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnZGV0dW5lJyxcblx0ICAgICAgICAgICAgJ2ZpbHRlcicsXG5cdCAgICAgICAgICAgICdmaWx0ZXJFbnZlbG9wZScsXG5cdCAgICAgICAgICAgICdlbnZlbG9wZSdcblx0ICAgICAgICBdKTtcblx0ICAgICAgICB0aGlzLm9zY2lsbGF0b3IuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMub3NjaWxsYXRvciA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5lbnZlbG9wZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5maWx0ZXIuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZmlsdGVyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLk1vbm9TeW50aDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBUb25lLkR1b1N5bnRoIGlzIGEgbW9ub3Bob25pYyBzeW50aCBjb21wb3NlZCBvZiB0d29cblx0XHQgKiAgICAgICAgICBNb25vU3ludGhzIHJ1biBpbiBwYXJhbGxlbCB3aXRoIGNvbnRyb2wgb3ZlciB0aGVcblx0XHQgKiAgICAgICAgICBmcmVxdWVuY3kgcmF0aW8gYmV0d2VlbiB0aGUgdHdvIHZvaWNlcyBhbmQgdmlicmF0byBlZmZlY3QuXG5cdFx0ICogICAgICAgICAgPGltZyBzcmM9XCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9kcmF3aW5ncy9kLzFiTDRHWHZmUk1NbHFTN1h5Qm05Q2pMOUtKUFNVS2JjZEJOcHFPbGtGTHhrL3B1Yj93PTEwMTImaD00NDhcIj5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuTW9ub3Bob25pY31cblx0XHQgKiAgQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSB0aGUgb3B0aW9ucyBhdmFpbGFibGUgZm9yIHRoZSBzeW50aFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICBzZWUgZGVmYXVsdHMgYmVsb3dcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgZHVvU3ludGggPSBuZXcgVG9uZS5EdW9TeW50aCgpLnRvTWFzdGVyKCk7XG5cdFx0ICogZHVvU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjJuXCIpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5EdW9TeW50aCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cdCAgICAgICAgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdEFyZyhvcHRpb25zLCBUb25lLkR1b1N5bnRoLmRlZmF1bHRzKTtcblx0ICAgICAgICBUb25lLk1vbm9waG9uaWMuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgZmlyc3Qgdm9pY2Vcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5Nb25vU3ludGh9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnZvaWNlMCA9IG5ldyBUb25lLk1vbm9TeW50aChvcHRpb25zLnZvaWNlMCk7XG5cdCAgICAgICAgdGhpcy52b2ljZTAudm9sdW1lLnZhbHVlID0gLTEwO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBzZWNvbmQgdm9pY2Vcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5Nb25vU3ludGh9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnZvaWNlMSA9IG5ldyBUb25lLk1vbm9TeW50aChvcHRpb25zLnZvaWNlMSk7XG5cdCAgICAgICAgdGhpcy52b2ljZTEudm9sdW1lLnZhbHVlID0gLTEwO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSB2aWJyYXRvIExGTy5cblx0XHRcdCAqICBAdHlwZSB7VG9uZS5MRk99XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3ZpYnJhdG8gPSBuZXcgVG9uZS5MRk8ob3B0aW9ucy52aWJyYXRvUmF0ZSwgLTUwLCA1MCk7XG5cdCAgICAgICAgdGhpcy5fdmlicmF0by5zdGFydCgpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogdGhlIHZpYnJhdG8gZnJlcXVlbmN5XG5cdFx0XHQgKiBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy52aWJyYXRvUmF0ZSA9IHRoaXMuX3ZpYnJhdG8uZnJlcXVlbmN5O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSB2aWJyYXRvIGdhaW5cblx0XHRcdCAqICBAdHlwZSB7VG9uZS5HYWlufVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl92aWJyYXRvR2FpbiA9IG5ldyBUb25lLkdhaW4ob3B0aW9ucy52aWJyYXRvQW1vdW50LCBUb25lLlR5cGUuUG9zaXRpdmUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIGFtb3VudCBvZiB2aWJyYXRvXG5cdFx0XHQgKiBAdHlwZSB7UG9zaXRpdmV9XG5cdFx0XHQgKiBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnZpYnJhdG9BbW91bnQgPSB0aGlzLl92aWJyYXRvR2Fpbi5nYWluO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBmcmVxdWVuY3kgY29udHJvbFxuXHRcdFx0ICogIEB0eXBlIHtGcmVxdWVuY3l9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgVG9uZS5TaWduYWwoNDQwLCBUb25lLlR5cGUuRnJlcXVlbmN5KTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBIYXJtb25pY2l0eSBpcyB0aGUgcmF0aW8gYmV0d2VlbiB0aGUgdHdvIHZvaWNlcy4gQSBoYXJtb25pY2l0eSBvZlxuXHRcdFx0ICogIDEgaXMgbm8gY2hhbmdlLiBIYXJtb25pY2l0eSA9IDIgbWVhbnMgYSBjaGFuZ2Ugb2YgYW4gb2N0YXZlLlxuXHRcdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKiAgQGV4YW1wbGVcblx0XHRcdCAqIC8vcGl0Y2ggdm9pY2UxIGFuIG9jdGF2ZSBiZWxvdyB2b2ljZTBcblx0XHRcdCAqIGR1b1N5bnRoLmhhcm1vbmljaXR5LnZhbHVlID0gMC41O1xuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG5ldyBUb25lLk11bHRpcGx5KG9wdGlvbnMuaGFybW9uaWNpdHkpO1xuXHQgICAgICAgIHRoaXMuaGFybW9uaWNpdHkudW5pdHMgPSBUb25lLlR5cGUuUG9zaXRpdmU7XG5cdCAgICAgICAgLy9jb250cm9sIHRoZSB0d28gdm9pY2VzIGZyZXF1ZW5jeVxuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy52b2ljZTAuZnJlcXVlbmN5KTtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLnZvaWNlMS5mcmVxdWVuY3kpO1xuXHQgICAgICAgIHRoaXMuX3ZpYnJhdG8uY29ubmVjdCh0aGlzLl92aWJyYXRvR2Fpbik7XG5cdCAgICAgICAgdGhpcy5fdmlicmF0b0dhaW4uZmFuKHRoaXMudm9pY2UwLmRldHVuZSwgdGhpcy52b2ljZTEuZGV0dW5lKTtcblx0ICAgICAgICB0aGlzLnZvaWNlMC5jb25uZWN0KHRoaXMub3V0cHV0KTtcblx0ICAgICAgICB0aGlzLnZvaWNlMS5jb25uZWN0KHRoaXMub3V0cHV0KTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICd2b2ljZTAnLFxuXHQgICAgICAgICAgICAndm9pY2UxJyxcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICd2aWJyYXRvQW1vdW50Jyxcblx0ICAgICAgICAgICAgJ3ZpYnJhdG9SYXRlJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuRHVvU3ludGgsIFRvbmUuTW9ub3Bob25pYyk7XG5cdCAgICAvKipcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5EdW9TeW50aC5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAndmlicmF0b0Ftb3VudCc6IDAuNSxcblx0ICAgICAgICAndmlicmF0b1JhdGUnOiA1LFxuXHQgICAgICAgICdoYXJtb25pY2l0eSc6IDEuNSxcblx0ICAgICAgICAndm9pY2UwJzoge1xuXHQgICAgICAgICAgICAndm9sdW1lJzogLTEwLFxuXHQgICAgICAgICAgICAncG9ydGFtZW50byc6IDAsXG5cdCAgICAgICAgICAgICdvc2NpbGxhdG9yJzogeyAndHlwZSc6ICdzaW5lJyB9LFxuXHQgICAgICAgICAgICAnZmlsdGVyRW52ZWxvcGUnOiB7XG5cdCAgICAgICAgICAgICAgICAnYXR0YWNrJzogMC4wMSxcblx0ICAgICAgICAgICAgICAgICdkZWNheSc6IDAsXG5cdCAgICAgICAgICAgICAgICAnc3VzdGFpbic6IDEsXG5cdCAgICAgICAgICAgICAgICAncmVsZWFzZSc6IDAuNVxuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICAnZW52ZWxvcGUnOiB7XG5cdCAgICAgICAgICAgICAgICAnYXR0YWNrJzogMC4wMSxcblx0ICAgICAgICAgICAgICAgICdkZWNheSc6IDAsXG5cdCAgICAgICAgICAgICAgICAnc3VzdGFpbic6IDEsXG5cdCAgICAgICAgICAgICAgICAncmVsZWFzZSc6IDAuNVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICAndm9pY2UxJzoge1xuXHQgICAgICAgICAgICAndm9sdW1lJzogLTEwLFxuXHQgICAgICAgICAgICAncG9ydGFtZW50byc6IDAsXG5cdCAgICAgICAgICAgICdvc2NpbGxhdG9yJzogeyAndHlwZSc6ICdzaW5lJyB9LFxuXHQgICAgICAgICAgICAnZmlsdGVyRW52ZWxvcGUnOiB7XG5cdCAgICAgICAgICAgICAgICAnYXR0YWNrJzogMC4wMSxcblx0ICAgICAgICAgICAgICAgICdkZWNheSc6IDAsXG5cdCAgICAgICAgICAgICAgICAnc3VzdGFpbic6IDEsXG5cdCAgICAgICAgICAgICAgICAncmVsZWFzZSc6IDAuNVxuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICAnZW52ZWxvcGUnOiB7XG5cdCAgICAgICAgICAgICAgICAnYXR0YWNrJzogMC4wMSxcblx0ICAgICAgICAgICAgICAgICdkZWNheSc6IDAsXG5cdCAgICAgICAgICAgICAgICAnc3VzdGFpbic6IDEsXG5cdCAgICAgICAgICAgICAgICAncmVsZWFzZSc6IDAuNVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBzdGFydCB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIGVudmVsb3Blc1xuXHRcdCAqXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW3RpbWU9bm93XSB0aGUgdGltZSB0aGUgYXR0YWNrIHNob3VsZCBzdGFydFxuXHRcdCAqICBAcGFyYW0ge05vcm1hbFJhbmdlfSBbdmVsb2NpdHk9MV0gdGhlIHZlbG9jaXR5IG9mIHRoZSBub3RlICgwLTEpXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkR1b1N5bnRofSB0aGlzXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkR1b1N5bnRoLnByb3RvdHlwZS5fdHJpZ2dlckVudmVsb3BlQXR0YWNrID0gZnVuY3Rpb24gKHRpbWUsIHZlbG9jaXR5KSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHRoaXMudm9pY2UwLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuXHQgICAgICAgIHRoaXMudm9pY2UxLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBzdGFydCB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZXNcblx0XHQgKlxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IFt0aW1lPW5vd10gdGhlIHRpbWUgdGhlIHJlbGVhc2Ugc2hvdWxkIHN0YXJ0XG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkR1b1N5bnRofSB0aGlzXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkR1b1N5bnRoLnByb3RvdHlwZS5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGhpcy52b2ljZTAuX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSk7XG5cdCAgICAgICAgdGhpcy52b2ljZTEuX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEdldCB0aGUgbGV2ZWwgb2YgdGhlIG91dHB1dCBhdCB0aGUgZ2l2ZW4gdGltZS4gTWVhc3VyZXNcblx0XHQgKiAgdGhlIGVudmVsb3BlKHMpIHZhbHVlIGF0IHRoZSB0aW1lLiBcblx0XHQgKiAgQHBhcmFtIHtUaW1lfSB0aW1lIFRoZSB0aW1lIHRvIHF1ZXJ5IHRoZSBlbnZlbG9wZSB2YWx1ZVxuXHRcdCAqICBAcmV0dXJuIHtOb3JtYWxSYW5nZX0gVGhlIG91dHB1dCBsZXZlbCBiZXR3ZWVuIDAtMVxuXHRcdCAqL1xuXHQgICAgVG9uZS5EdW9TeW50aC5wcm90b3R5cGUuZ2V0TGV2ZWxBdFRpbWUgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHJldHVybiAodGhpcy52b2ljZTAuZ2V0TGV2ZWxBdFRpbWUodGltZSkgKyB0aGlzLnZvaWNlMS5nZXRMZXZlbEF0VGltZSh0aW1lKSkgLyAyO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBjbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5EdW9TeW50aH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5EdW9TeW50aC5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLk1vbm9waG9uaWMucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbXG5cdCAgICAgICAgICAgICd2b2ljZTAnLFxuXHQgICAgICAgICAgICAndm9pY2UxJyxcblx0ICAgICAgICAgICAgJ2ZyZXF1ZW5jeScsXG5cdCAgICAgICAgICAgICd2aWJyYXRvQW1vdW50Jyxcblx0ICAgICAgICAgICAgJ3ZpYnJhdG9SYXRlJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMudm9pY2UwLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLnZvaWNlMCA9IG51bGw7XG5cdCAgICAgICAgdGhpcy52b2ljZTEuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMudm9pY2UxID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3ZpYnJhdG9HYWluLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl92aWJyYXRvR2FpbiA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fdmlicmF0byA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5oYXJtb25pY2l0eS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy52aWJyYXRvQW1vdW50LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLnZpYnJhdG9BbW91bnQgPSBudWxsO1xuXHQgICAgICAgIHRoaXMudmlicmF0b1JhdGUgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLkR1b1N5bnRoO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIEZNU3ludGggaXMgY29tcG9zZWQgb2YgdHdvIFRvbmUuU3ludGhzIHdoZXJlIG9uZSBUb25lLlN5bnRoIG1vZHVsYXRlc1xuXHRcdCAqICAgICAgICAgIHRoZSBmcmVxdWVuY3kgb2YgYSBzZWNvbmQgVG9uZS5TeW50aC4gQSBsb3Qgb2Ygc3BlY3RyYWwgY29udGVudFxuXHRcdCAqICAgICAgICAgIGNhbiBiZSBleHBsb3JlZCB1c2luZyB0aGUgbW9kdWxhdGlvbkluZGV4IHBhcmFtZXRlci4gUmVhZCBtb3JlIGFib3V0XG5cdFx0ICogICAgICAgICAgZnJlcXVlbmN5IG1vZHVsYXRpb24gc3ludGhlc2lzIG9uIFNvdW5kIE9uIFNvdW5kOiBbUGFydCAxXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNjA0MDMxMjM3MDQvaHR0cDovL3d3dy5zb3VuZG9uc291bmQuY29tL3Nvcy9hcHIwMC9hcnRpY2xlcy9zeW50aHNlY3JldHMuaHRtKSwgW1BhcnQgMl0oaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTYwNDAzMTE1ODM1L2h0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbS9zb3MvbWF5MDAvYXJ0aWNsZXMvc3ludGguaHRtKS5cblx0XHQgKiAgICAgICAgICA8aW1nIHNyYz1cImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL2RyYXdpbmdzL2QvMWgwUFVEWlhQZ2k0SWt4NmJWVDZvbmNyWVBMbHVGS3k3bGo1M3B1eGotRE0vcHViP3c9OTAyJmg9NDYyXCI+XG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLk1vbm9waG9uaWN9XG5cdFx0ICogIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gdGhlIG9wdGlvbnMgYXZhaWxhYmxlIGZvciB0aGUgc3ludGhcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlIGRlZmF1bHRzIGJlbG93XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIGZtU3ludGggPSBuZXcgVG9uZS5GTVN5bnRoKCkudG9NYXN0ZXIoKTtcblx0XHQgKiBmbVN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzVcIiwgXCI0blwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuRk1TeW50aCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cdCAgICAgICAgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdEFyZyhvcHRpb25zLCBUb25lLkZNU3ludGguZGVmYXVsdHMpO1xuXHQgICAgICAgIFRvbmUuTW9ub3Bob25pYy5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBjYXJyaWVyIHZvaWNlLlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLlN5bnRofVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9jYXJyaWVyID0gbmV3IFRvbmUuU3ludGgob3B0aW9ucy5jYXJyaWVyKTtcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyLnZvbHVtZS52YWx1ZSA9IC0xMDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgY2FycmllcidzIG9zY2lsbGF0b3Jcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5Pc2NpbGxhdG9yfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5vc2NpbGxhdG9yID0gdGhpcy5fY2Fycmllci5vc2NpbGxhdG9yO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBjYXJyaWVyJ3MgZW52ZWxvcGVcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5Pc2NpbGxhdG9yfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5lbnZlbG9wZSA9IHRoaXMuX2NhcnJpZXIuZW52ZWxvcGUuc2V0KG9wdGlvbnMuZW52ZWxvcGUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBtb2R1bGF0b3Igdm9pY2UuXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuU3ludGh9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvciA9IG5ldyBUb25lLlN5bnRoKG9wdGlvbnMubW9kdWxhdG9yKTtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3Iudm9sdW1lLnZhbHVlID0gLTEwO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBtb2R1bGF0b3IncyBvc2NpbGxhdG9yIHdoaWNoIGlzIGFwcGxpZWRcblx0XHRcdCAqICB0byB0aGUgYW1wbGl0dWRlIG9mIHRoZSBvc2NpbGxhdG9yXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuT3NjaWxsYXRvcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubW9kdWxhdGlvbiA9IHRoaXMuX21vZHVsYXRvci5vc2NpbGxhdG9yLnNldChvcHRpb25zLm1vZHVsYXRpb24pO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBtb2R1bGF0b3IncyBlbnZlbG9wZVxuXHRcdFx0ICogIEB0eXBlIHtUb25lLk9zY2lsbGF0b3J9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLm1vZHVsYXRpb25FbnZlbG9wZSA9IHRoaXMuX21vZHVsYXRvci5lbnZlbG9wZS5zZXQob3B0aW9ucy5tb2R1bGF0aW9uRW52ZWxvcGUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBmcmVxdWVuY3kgY29udHJvbC5cblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFRvbmUuU2lnbmFsKDQ0MCwgVG9uZS5UeXBlLkZyZXF1ZW5jeSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGRldHVuZSBpbiBjZW50c1xuXHRcdFx0ICogIEB0eXBlIHtDZW50c31cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLmRldHVuZSwgVG9uZS5UeXBlLkNlbnRzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBIYXJtb25pY2l0eSBpcyB0aGUgcmF0aW8gYmV0d2VlbiB0aGUgdHdvIHZvaWNlcy4gQSBoYXJtb25pY2l0eSBvZlxuXHRcdFx0ICogIDEgaXMgbm8gY2hhbmdlLiBIYXJtb25pY2l0eSA9IDIgbWVhbnMgYSBjaGFuZ2Ugb2YgYW4gb2N0YXZlLlxuXHRcdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKiAgQGV4YW1wbGVcblx0XHRcdCAqIC8vcGl0Y2ggdm9pY2UxIGFuIG9jdGF2ZSBiZWxvdyB2b2ljZTBcblx0XHRcdCAqIHN5bnRoLmhhcm1vbmljaXR5LnZhbHVlID0gMC41O1xuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG5ldyBUb25lLk11bHRpcGx5KG9wdGlvbnMuaGFybW9uaWNpdHkpO1xuXHQgICAgICAgIHRoaXMuaGFybW9uaWNpdHkudW5pdHMgPSBUb25lLlR5cGUuUG9zaXRpdmU7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG1vZHVsYXRpb24gaW5kZXggd2hpY2ggZXNzZW50aWFsbHkgdGhlIGRlcHRoIG9yIGFtb3VudCBvZiB0aGUgbW9kdWxhdGlvbi4gSXQgaXMgdGhlXG5cdFx0XHQgKiAgcmF0aW8gb2YgdGhlIGZyZXF1ZW5jeSBvZiB0aGUgbW9kdWxhdGluZyBzaWduYWwgKG1mKSB0byB0aGUgYW1wbGl0dWRlIG9mIHRoZVxuXHRcdFx0ICogIG1vZHVsYXRpbmcgc2lnbmFsIChtYSkgLS0gYXMgaW4gbWEvbWYuXG5cdFx0XHQgKlx0QHR5cGUge1Bvc2l0aXZlfVxuXHRcdFx0ICpcdEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4ID0gbmV3IFRvbmUuTXVsdGlwbHkob3B0aW9ucy5tb2R1bGF0aW9uSW5kZXgpO1xuXHQgICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4LnVuaXRzID0gVG9uZS5UeXBlLlBvc2l0aXZlO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBub2RlIHdoZXJlIHRoZSBtb2R1bGF0aW9uIGhhcHBlbnNcblx0XHRcdCAqICBAdHlwZSB7R2Fpbk5vZGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlID0gbmV3IFRvbmUuR2FpbigwKTtcblx0ICAgICAgICAvL2NvbnRyb2wgdGhlIHR3byB2b2ljZXMgZnJlcXVlbmN5XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9jYXJyaWVyLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5oYXJtb25pY2l0eSwgdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5tb2R1bGF0aW9uSW5kZXgsIHRoaXMuX21vZHVsYXRpb25Ob2RlKTtcblx0ICAgICAgICB0aGlzLmRldHVuZS5mYW4odGhpcy5fY2Fycmllci5kZXR1bmUsIHRoaXMuX21vZHVsYXRvci5kZXR1bmUpO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvci5jb25uZWN0KHRoaXMuX21vZHVsYXRpb25Ob2RlLmdhaW4pO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlLmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuXHQgICAgICAgIHRoaXMuX2NhcnJpZXIuY29ubmVjdCh0aGlzLm91dHB1dCk7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoW1xuXHQgICAgICAgICAgICAnZnJlcXVlbmN5Jyxcblx0ICAgICAgICAgICAgJ2hhcm1vbmljaXR5Jyxcblx0ICAgICAgICAgICAgJ21vZHVsYXRpb25JbmRleCcsXG5cdCAgICAgICAgICAgICdvc2NpbGxhdG9yJyxcblx0ICAgICAgICAgICAgJ2VudmVsb3BlJyxcblx0ICAgICAgICAgICAgJ21vZHVsYXRpb24nLFxuXHQgICAgICAgICAgICAnbW9kdWxhdGlvbkVudmVsb3BlJyxcblx0ICAgICAgICAgICAgJ2RldHVuZSdcblx0ICAgICAgICBdKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLkZNU3ludGgsIFRvbmUuTW9ub3Bob25pYyk7XG5cdCAgICAvKipcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5GTVN5bnRoLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdoYXJtb25pY2l0eSc6IDMsXG5cdCAgICAgICAgJ21vZHVsYXRpb25JbmRleCc6IDEwLFxuXHQgICAgICAgICdkZXR1bmUnOiAwLFxuXHQgICAgICAgICdvc2NpbGxhdG9yJzogeyAndHlwZSc6ICdzaW5lJyB9LFxuXHQgICAgICAgICdlbnZlbG9wZSc6IHtcblx0ICAgICAgICAgICAgJ2F0dGFjayc6IDAuMDEsXG5cdCAgICAgICAgICAgICdkZWNheSc6IDAuMDEsXG5cdCAgICAgICAgICAgICdzdXN0YWluJzogMSxcblx0ICAgICAgICAgICAgJ3JlbGVhc2UnOiAwLjVcblx0ICAgICAgICB9LFxuXHQgICAgICAgICdtb2R1bGF0aW9uJzogeyAndHlwZSc6ICdzcXVhcmUnIH0sXG5cdCAgICAgICAgJ21vZHVsYXRpb25FbnZlbG9wZSc6IHtcblx0ICAgICAgICAgICAgJ2F0dGFjayc6IDAuNSxcblx0ICAgICAgICAgICAgJ2RlY2F5JzogMCxcblx0ICAgICAgICAgICAgJ3N1c3RhaW4nOiAxLFxuXHQgICAgICAgICAgICAncmVsZWFzZSc6IDAuNVxuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBcdHRyaWdnZXIgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBub3RlXG5cdFx0ICpcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gW3RpbWU9bm93XSB0aGUgdGltZSB0aGUgbm90ZSB3aWxsIG9jY3VyXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSBbdmVsb2NpdHk9MV0gdGhlIHZlbG9jaXR5IG9mIHRoZSBub3RlXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkZNU3ludGh9IHRoaXNcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuRk1TeW50aC5wcm90b3R5cGUuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayA9IGZ1bmN0aW9uICh0aW1lLCB2ZWxvY2l0eSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICAvL3RoZSBlbnZlbG9wZXNcblx0ICAgICAgICB0aGlzLl9jYXJyaWVyLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvci5fdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICB0cmlnZ2VyIHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIG5vdGVcblx0XHQgKlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddIHRoZSB0aW1lIHRoZSBub3RlIHdpbGwgcmVsZWFzZVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5GTVN5bnRofSB0aGlzXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkZNU3ludGgucHJvdG90eXBlLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdGhpcy5fY2Fycmllci5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0b3IuX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIGNsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLkZNU3ludGh9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuRk1TeW50aC5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLk1vbm9waG9uaWMucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZShbXG5cdCAgICAgICAgICAgICdmcmVxdWVuY3knLFxuXHQgICAgICAgICAgICAnaGFybW9uaWNpdHknLFxuXHQgICAgICAgICAgICAnbW9kdWxhdGlvbkluZGV4Jyxcblx0ICAgICAgICAgICAgJ29zY2lsbGF0b3InLFxuXHQgICAgICAgICAgICAnZW52ZWxvcGUnLFxuXHQgICAgICAgICAgICAnbW9kdWxhdGlvbicsXG5cdCAgICAgICAgICAgICdtb2R1bGF0aW9uRW52ZWxvcGUnLFxuXHQgICAgICAgICAgICAnZGV0dW5lJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMuX2NhcnJpZXIuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2NhcnJpZXIgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX21vZHVsYXRvci5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmRldHVuZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5tb2R1bGF0aW9uSW5kZXguZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLmhhcm1vbmljaXR5LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLmhhcm1vbmljaXR5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMub3NjaWxsYXRvciA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5tb2R1bGF0aW9uRW52ZWxvcGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMubW9kdWxhdGlvbiA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuRk1TeW50aDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBUb25lLk1lbWJyYW5lU3ludGggbWFrZXMga2ljayBhbmQgdG9tIHNvdW5kcyB1c2luZyBhIHNpbmdsZSBvc2NpbGxhdG9yXG5cdFx0ICogICAgICAgICAgd2l0aCBhbiBhbXBsaXR1ZGUgZW52ZWxvcGUgYW5kIGZyZXF1ZW5jeSByYW1wLiBBIFRvbmUuT21uaU9zY2lsbGF0b3Jcblx0XHQgKiAgICAgICAgICBpcyByb3V0ZWQgdGhyb3VnaCBhIFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUgdG8gdGhlIG91dHB1dC4gVGhlIGRydW1cblx0XHQgKiAgICAgICAgICBxdWFsaXR5IG9mIHRoZSBzb3VuZCBjb21lcyBmcm9tIHRoZSBmcmVxdWVuY3kgZW52ZWxvcGUgYXBwbGllZFxuXHRcdCAqICAgICAgICAgIGR1cmluZyBUb25lLk1lbWJyYW5lU3ludGgudHJpZ2dlckF0dGFjayhub3RlKS4gVGhlIGZyZXF1ZW5jeSBlbnZlbG9wZVxuXHRcdCAqICAgICAgICAgIHN0YXJ0cyBhdCA8Y29kZT5ub3RlICogLm9jdGF2ZXM8L2NvZGU+IGFuZCByYW1wcyB0byA8Y29kZT5ub3RlPC9jb2RlPlxuXHRcdCAqICAgICAgICAgIG92ZXIgdGhlIGR1cmF0aW9uIG9mIDxjb2RlPi5waXRjaERlY2F5PC9jb2RlPi5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuSW5zdHJ1bWVudH1cblx0XHQgKiAgQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSB0aGUgb3B0aW9ucyBhdmFpbGFibGUgZm9yIHRoZSBzeW50aFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICBzZWUgZGVmYXVsdHMgYmVsb3dcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgc3ludGggPSBuZXcgVG9uZS5NZW1icmFuZVN5bnRoKCkudG9NYXN0ZXIoKTtcblx0XHQgKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkMyXCIsIFwiOG5cIik7XG5cdFx0ICovXG5cdCAgICBUb25lLk1lbWJyYW5lU3ludGggPSBmdW5jdGlvbiAob3B0aW9ucykge1xuXHQgICAgICAgIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRBcmcob3B0aW9ucywgVG9uZS5NZW1icmFuZVN5bnRoLmRlZmF1bHRzKTtcblx0ICAgICAgICBUb25lLkluc3RydW1lbnQuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgb3NjaWxsYXRvci5cblx0XHRcdCAqICBAdHlwZSB7VG9uZS5PbW5pT3NjaWxsYXRvcn1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMub3NjaWxsYXRvciA9IG5ldyBUb25lLk9tbmlPc2NpbGxhdG9yKG9wdGlvbnMub3NjaWxsYXRvcik7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cblx0XHRcdCAqICBAdHlwZSB7VG9uZS5BbXBsaXR1ZGVFbnZlbG9wZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUgPSBuZXcgVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZShvcHRpb25zLmVudmVsb3BlKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbnVtYmVyIG9mIG9jdGF2ZXMgdGhlIHBpdGNoIGVudmVsb3BlIHJhbXBzLlxuXHRcdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMub2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgYW1vdW50IG9mIHRpbWUgdGhlIGZyZXF1ZW5jeSBlbnZlbG9wZSB0YWtlcy5cblx0XHRcdCAqICBAdHlwZSB7VGltZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMucGl0Y2hEZWNheSA9IG9wdGlvbnMucGl0Y2hEZWNheTtcblx0ICAgICAgICB0aGlzLm9zY2lsbGF0b3IuY2hhaW4odGhpcy5lbnZlbG9wZSwgdGhpcy5vdXRwdXQpO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KFtcblx0ICAgICAgICAgICAgJ29zY2lsbGF0b3InLFxuXHQgICAgICAgICAgICAnZW52ZWxvcGUnXG5cdCAgICAgICAgXSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5NZW1icmFuZVN5bnRoLCBUb25lLkluc3RydW1lbnQpO1xuXHQgICAgLyoqXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuTWVtYnJhbmVTeW50aC5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAncGl0Y2hEZWNheSc6IDAuMDUsXG5cdCAgICAgICAgJ29jdGF2ZXMnOiAxMCxcblx0ICAgICAgICAnb3NjaWxsYXRvcic6IHsgJ3R5cGUnOiAnc2luZScgfSxcblx0ICAgICAgICAnZW52ZWxvcGUnOiB7XG5cdCAgICAgICAgICAgICdhdHRhY2snOiAwLjAwMSxcblx0ICAgICAgICAgICAgJ2RlY2F5JzogMC40LFxuXHQgICAgICAgICAgICAnc3VzdGFpbic6IDAuMDEsXG5cdCAgICAgICAgICAgICdyZWxlYXNlJzogMS40LFxuXHQgICAgICAgICAgICAnYXR0YWNrQ3VydmUnOiAnZXhwb25lbnRpYWwnXG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUcmlnZ2VyIHRoZSBub3RlIGF0IHRoZSBnaXZlbiB0aW1lIHdpdGggdGhlIGdpdmVuIHZlbG9jaXR5LlxuXHRcdCAqXG5cdFx0ICogIEBwYXJhbSAge0ZyZXF1ZW5jeX0gbm90ZSAgICAgdGhlIG5vdGVcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gW3RpbWU9bm93XSAgICAgdGhlIHRpbWUsIGlmIG5vdCBnaXZlbiBpcyBub3dcblx0XHQgKiAgQHBhcmFtICB7bnVtYmVyfSBbdmVsb2NpdHk9MV0gdmVsb2NpdHkgZGVmYXVsdHMgdG8gMVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5NZW1icmFuZVN5bnRofSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogIGtpY2sudHJpZ2dlckF0dGFjayg2MCk7XG5cdFx0ICovXG5cdCAgICBUb25lLk1lbWJyYW5lU3ludGgucHJvdG90eXBlLnRyaWdnZXJBdHRhY2sgPSBmdW5jdGlvbiAobm90ZSwgdGltZSwgdmVsb2NpdHkpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgbm90ZSA9IHRoaXMudG9GcmVxdWVuY3kobm90ZSk7XG5cdCAgICAgICAgdmFyIG1heE5vdGUgPSBub3RlICogdGhpcy5vY3RhdmVzO1xuXHQgICAgICAgIHRoaXMub3NjaWxsYXRvci5mcmVxdWVuY3kuc2V0VmFsdWVBdFRpbWUobWF4Tm90ZSwgdGltZSk7XG5cdCAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKG5vdGUsIHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLnBpdGNoRGVjYXkpKTtcblx0ICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuXHQgICAgICAgIHRoaXMub3NjaWxsYXRvci5zdGFydCh0aW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVHJpZ2dlciB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBub3RlLlxuXHRcdCAqXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IFt0aW1lPW5vd10gdGhlIHRpbWUgdGhlIG5vdGUgd2lsbCByZWxlYXNlXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk1lbWJyYW5lU3ludGh9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTWVtYnJhbmVTeW50aC5wcm90b3R5cGUudHJpZ2dlclJlbGVhc2UgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuXHQgICAgICAgIHRoaXMub3NjaWxsYXRvci5zdG9wKHRpbWUgKyB0aGlzLmVudmVsb3BlLnJlbGVhc2UpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuTWVtYnJhbmVTeW50aH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5NZW1icmFuZVN5bnRoLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuSW5zdHJ1bWVudC5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ29zY2lsbGF0b3InLFxuXHQgICAgICAgICAgICAnZW52ZWxvcGUnXG5cdCAgICAgICAgXSk7XG5cdCAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLm9zY2lsbGF0b3IgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLk1lbWJyYW5lU3ludGg7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIC8qKlxuXHRcdCAqICBJbmhhcm1vbmljIHJhdGlvIG9mIGZyZXF1ZW5jaWVzIGJhc2VkIG9uIHRoZSBSb2xhbmQgVFItODA4XG5cdFx0ICogIFRha2VuIGZyb20gaHR0cHM6Ly9jY3JtYS5zdGFuZm9yZC5lZHUvcGFwZXJzL3RyLTgwOC1jeW1iYWwtcGh5c2ljYWxseS1pbmZvcm1lZC1jaXJjdWl0LWJlbmRhYmxlLWRpZ2l0YWwtbW9kZWxcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqICBAdHlwZSB7QXJyYXl9XG5cdFx0ICovXG5cdCAgICB2YXIgaW5oYXJtUmF0aW9zID0gW1xuXHQgICAgICAgIDEsXG5cdCAgICAgICAgMS40ODMsXG5cdCAgICAgICAgMS45MzIsXG5cdCAgICAgICAgMi41NDYsXG5cdCAgICAgICAgMi42Myxcblx0ICAgICAgICAzLjg5N1xuXHQgICAgXTtcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIEEgaGlnaGx5IGluaGFybW9uaWMgYW5kIHNwZWN0cmFsbHkgY29tcGxleCBzb3VyY2Ugd2l0aCBhIGhpZ2hwYXNzIGZpbHRlclxuXHRcdCAqICAgICAgICAgIGFuZCBhbXBsaXR1ZGUgZW52ZWxvcGUgd2hpY2ggaXMgZ29vZCBmb3IgbWFraW5nIG1ldGFsb3Bob25lIHNvdW5kcy4gQmFzZWRcblx0XHQgKiAgICAgICAgICBvbiBDeW1iYWxTeW50aCBieSBbQHBvbHlyaHl0aG1hdGljXShodHRwczovL2dpdGh1Yi5jb20vcG9seXJoeXRobWF0aWMpLlxuXHRcdCAqICAgICAgICAgIEluc3BpcmF0aW9uIGZyb20gW1NvdW5kIG9uIFNvdW5kXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNjA2MTAxNDM5MjQvaHR0cHM6Ly93d3cuc291bmRvbnNvdW5kLmNvbS9zb3MvanVsMDIvYXJ0aWNsZXMvc3ludGhzZWNyZXRzMDcwMi5hc3ApLlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5JbnN0cnVtZW50fVxuXHRcdCAqICBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIFRoZSBvcHRpb25zIGF2YWlsYmxlIGZvciB0aGUgc3ludGhcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlIGRlZmF1bHRzIGJlbG93XG5cdFx0ICovXG5cdCAgICBUb25lLk1ldGFsU3ludGggPSBmdW5jdGlvbiAob3B0aW9ucykge1xuXHQgICAgICAgIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRBcmcob3B0aW9ucywgVG9uZS5NZXRhbFN5bnRoLmRlZmF1bHRzKTtcblx0ICAgICAgICBUb25lLkluc3RydW1lbnQuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZnJlcXVlbmN5IG9mIHRoZSBjeW1iYWxcblx0XHRcdCAqICBAdHlwZSAge0ZyZXF1ZW5jeX1cblx0XHRcdCAqICBAc2lnbmFsXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBUb25lLlNpZ25hbChvcHRpb25zLmZyZXF1ZW5jeSwgVG9uZS5UeXBlLkZyZXF1ZW5jeSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGFycmF5IG9mIEZNT3NjaWxsYXRvcnNcblx0XHRcdCAqICBAdHlwZSAge0FycmF5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycyA9IFtdO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBmcmVxdWVuY3kgbXVsdGlwbGllcnNcblx0XHRcdCAqICBAdHlwZSB7QXJyYXl9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ZyZXFNdWx0aXBsaWVycyA9IFtdO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhbXBsaXR1ZGUgZm9yIHRoZSBib2R5XG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuR2Fpbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYW1wbGl0dWUgPSBuZXcgVG9uZS5HYWluKDApLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGhpZ2hwYXNzIHRoZSBvdXRwdXRcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5GaWx0ZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2hpZ2hwYXNzID0gbmV3IFRvbmUuRmlsdGVyKHtcblx0ICAgICAgICAgICAgJ3R5cGUnOiAnaGlnaHBhc3MnLFxuXHQgICAgICAgICAgICAnUSc6IC0zLjAxMDI5OTk1NjYzOTgxMjVcblx0ICAgICAgICB9KS5jb25uZWN0KHRoaXMuX2FtcGxpdHVlKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgbnVtYmVyIG9mIG9jdGF2ZXMgdGhlIGhpZ2hwYXNzXG5cdFx0XHQgKiAgZmlsdGVyIGZyZXF1ZW5jeSByYW1wc1xuXHRcdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgU2NhbGUgdGhlIGJvZHkgZW52ZWxvcGVcblx0XHRcdCAqICBmb3IgdGhlIGJhbmRwYXNzXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuU2NhbGV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIgPSBuZXcgVG9uZS5TY2FsZShvcHRpb25zLnJlc29uYW5jZSwgNzAwMCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGVudmVsb3BlIHdoaWNoIGlzIGNvbm5lY3RlZCBib3RoIHRvIHRoZVxuXHRcdFx0ICogIGFtcGxpdHVkZSBhbmQgaGlnaHBhc3MgZmlsdGVyJ3MgY3V0b2ZmIGZyZXF1ZW5jeVxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5FbnZlbG9wZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUgPSBuZXcgVG9uZS5FbnZlbG9wZSh7XG5cdCAgICAgICAgICAgICdhdHRhY2snOiBvcHRpb25zLmVudmVsb3BlLmF0dGFjayxcblx0ICAgICAgICAgICAgJ2F0dGFja0N1cnZlJzogJ2xpbmVhcicsXG5cdCAgICAgICAgICAgICdkZWNheSc6IG9wdGlvbnMuZW52ZWxvcGUuZGVjYXksXG5cdCAgICAgICAgICAgICdzdXN0YWluJzogMCxcblx0ICAgICAgICAgICAgJ3JlbGVhc2UnOiBvcHRpb25zLmVudmVsb3BlLnJlbGVhc2Vcblx0ICAgICAgICB9KS5jaGFpbih0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLCB0aGlzLl9oaWdocGFzcy5mcmVxdWVuY3kpO1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUuY29ubmVjdCh0aGlzLl9hbXBsaXR1ZS5nYWluKTtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluaGFybVJhdGlvcy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICB2YXIgb3NjID0gbmV3IFRvbmUuRk1Pc2NpbGxhdG9yKHtcblx0ICAgICAgICAgICAgICAgICd0eXBlJzogJ3NxdWFyZScsXG5cdCAgICAgICAgICAgICAgICAnbW9kdWxhdGlvblR5cGUnOiAnc3F1YXJlJyxcblx0ICAgICAgICAgICAgICAgICdoYXJtb25pY2l0eSc6IG9wdGlvbnMuaGFybW9uaWNpdHksXG5cdCAgICAgICAgICAgICAgICAnbW9kdWxhdGlvbkluZGV4Jzogb3B0aW9ucy5tb2R1bGF0aW9uSW5kZXhcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIG9zYy5jb25uZWN0KHRoaXMuX2hpZ2hwYXNzKTtcblx0ICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnNbaV0gPSBvc2M7XG5cdCAgICAgICAgICAgIHZhciBtdWx0ID0gbmV3IFRvbmUuTXVsdGlwbHkoaW5oYXJtUmF0aW9zW2ldKTtcblx0ICAgICAgICAgICAgdGhpcy5fZnJlcU11bHRpcGxpZXJzW2ldID0gbXVsdDtcblx0ICAgICAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4obXVsdCwgb3NjLmZyZXF1ZW5jeSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vc2V0IHRoZSBvY3RhdmVzXG5cdCAgICAgICAgdGhpcy5vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuTWV0YWxTeW50aCwgVG9uZS5JbnN0cnVtZW50KTtcblx0ICAgIC8qKlxuXHRcdCAqICBkZWZhdWx0IHZhbHVlc1xuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBjb25zdFxuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5NZXRhbFN5bnRoLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdmcmVxdWVuY3knOiAyMDAsXG5cdCAgICAgICAgJ2VudmVsb3BlJzoge1xuXHQgICAgICAgICAgICAnYXR0YWNrJzogMC4wMDEsXG5cdCAgICAgICAgICAgICdkZWNheSc6IDEuNCxcblx0ICAgICAgICAgICAgJ3JlbGVhc2UnOiAwLjJcblx0ICAgICAgICB9LFxuXHQgICAgICAgICdoYXJtb25pY2l0eSc6IDUuMSxcblx0ICAgICAgICAnbW9kdWxhdGlvbkluZGV4JzogMzIsXG5cdCAgICAgICAgJ3Jlc29uYW5jZSc6IDQwMDAsXG5cdCAgICAgICAgJ29jdGF2ZXMnOiAxLjVcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVHJpZ2dlciB0aGUgYXR0YWNrLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSAgdGltZSAgICAgIFdoZW4gdGhlIGF0dGFjayBzaG91bGQgYmUgdHJpZ2dlcmVkLlxuXHRcdCAqICBAcGFyYW0gIHtOb3JtYWxSYW5nZX0gIFt2ZWxvY2l0eT0xXSAgVGhlIHZlbG9jaXR5IHRoYXQgdGhlIGVudmVsb3BlIHNob3VsZCBiZSB0cmlnZ2VyZWQgYXQuXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLk1ldGFsU3ludGh9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk1ldGFsU3ludGgucHJvdG90eXBlLnRyaWdnZXJBdHRhY2sgPSBmdW5jdGlvbiAodGltZSwgdmVsKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHZlbCA9IFRvbmUuZGVmYXVsdEFyZyh2ZWwsIDEpO1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWwpO1xuXHQgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2goZnVuY3Rpb24gKG9zYykge1xuXHQgICAgICAgICAgICBvc2Muc3RhcnQodGltZSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLy9pZiB0aGUgc3VzdGFpbiBpcyAwLCBzdG9wIHRoZSBvc2NpbGxhdG9yIGFzIHdlbGxcblx0ICAgICAgICBpZiAodGhpcy5lbnZlbG9wZS5zdXN0YWluID09PSAwKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2goZnVuY3Rpb24gKG9zYykge1xuXHQgICAgICAgICAgICAgICAgb3NjLnN0b3AodGltZSArIHRoaXMuZW52ZWxvcGUuYXR0YWNrICsgdGhpcy5lbnZlbG9wZS5kZWNheSk7XG5cdCAgICAgICAgICAgIH0uYmluZCh0aGlzKSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUcmlnZ2VyIHRoZSByZWxlYXNlIG9mIHRoZSBlbnZlbG9wZS5cblx0XHQgKiAgQHBhcmFtICB7VGltZX0gIHRpbWUgICAgICBXaGVuIHRoZSByZWxlYXNlIHNob3VsZCBiZSB0cmlnZ2VyZWQuXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLk1ldGFsU3ludGh9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk1ldGFsU3ludGgucHJvdG90eXBlLnRyaWdnZXJSZWxlYXNlID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyUmVsZWFzZSh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycy5mb3JFYWNoKGZ1bmN0aW9uIChvc2MpIHtcblx0ICAgICAgICAgICAgb3NjLnN0b3AodGltZSArIHRoaXMuZW52ZWxvcGUucmVsZWFzZSk7XG5cdCAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBTeW5jIHRoZSBpbnN0cnVtZW50IHRvIHRoZSBUcmFuc3BvcnQuIEFsbCBzdWJzZXF1ZW50IGNhbGxzIG9mXG5cdFx0ICogW3RyaWdnZXJBdHRhY2tdKCN0cmlnZ2VyYXR0YWNrKSBhbmQgW3RyaWdnZXJSZWxlYXNlXSgjdHJpZ2dlcnJlbGVhc2UpXG5cdFx0ICogd2lsbCBiZSBzY2hlZHVsZWQgYWxvbmcgdGhlIHRyYW5zcG9ydC5cblx0XHQgKiBAZXhhbXBsZVxuXHRcdCAqIHN5bnRoLnN5bmMoKVxuXHRcdCAqIC8vc2NoZWR1bGUgMyBub3RlcyB3aGVuIHRoZSB0cmFuc3BvcnQgZmlyc3Qgc3RhcnRzXG5cdFx0ICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoJzhuJywgMClcblx0XHQgKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZSgnOG4nLCAnOG4nKVxuXHRcdCAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKCc4bicsICc0bicpXG5cdFx0ICogLy9zdGFydCB0aGUgdHJhbnNwb3J0IHRvIGhlYXIgdGhlIG5vdGVzXG5cdFx0ICogVHJhbnNwb3J0LnN0YXJ0KClcblx0XHQgKiBAcmV0dXJucyB7VG9uZS5JbnN0cnVtZW50fSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk1ldGFsU3ludGgucHJvdG90eXBlLnN5bmMgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fc3luY01ldGhvZCgndHJpZ2dlckF0dGFjaycsIDApO1xuXHQgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoJ3RyaWdnZXJSZWxlYXNlJywgMCk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRyaWdnZXIgdGhlIGF0dGFjayBhbmQgcmVsZWFzZSBvZiB0aGUgZW52ZWxvcGUgYWZ0ZXIgdGhlIGdpdmVuXG5cdFx0ICogIGR1cmF0aW9uLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSAgZHVyYXRpb24gIFRoZSBkdXJhdGlvbiBiZWZvcmUgdHJpZ2dlcmluZyB0aGUgcmVsZWFzZVxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSAgdGltZSAgICAgIFdoZW4gdGhlIGF0dGFjayBzaG91bGQgYmUgdHJpZ2dlcmVkLlxuXHRcdCAqICBAcGFyYW0gIHtOb3JtYWxSYW5nZX0gIFt2ZWxvY2l0eT0xXSAgVGhlIHZlbG9jaXR5IHRoYXQgdGhlIGVudmVsb3BlIHNob3VsZCBiZSB0cmlnZ2VyZWQgYXQuXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLk1ldGFsU3ludGh9ICB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk1ldGFsU3ludGgucHJvdG90eXBlLnRyaWdnZXJBdHRhY2tSZWxlYXNlID0gZnVuY3Rpb24gKGR1cmF0aW9uLCB0aW1lLCB2ZWxvY2l0eSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcblx0ICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuXHQgICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2UodGltZSArIGR1cmF0aW9uKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIG1vZHVsYXRpb25JbmRleCBvZiB0aGUgb3NjaWxsYXRvcnMgd2hpY2ggbWFrZSB1cCB0aGUgc291cmNlLlxuXHRcdCAqICBzZWUgVG9uZS5GTU9zY2lsbGF0b3IubW9kdWxhdGlvbkluZGV4XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLk1ldGFsU3ludGgjXG5cdFx0ICogIEB0eXBlIHtQb3NpdGl2ZX1cblx0XHQgKiAgQG5hbWUgIG1vZHVsYXRpb25JbmRleFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuTWV0YWxTeW50aC5wcm90b3R5cGUsICdtb2R1bGF0aW9uSW5kZXgnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yc1swXS5tb2R1bGF0aW9uSW5kZXgudmFsdWU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWwpIHtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnNbaV0ubW9kdWxhdGlvbkluZGV4LnZhbHVlID0gdmFsO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGhhcm1vbmljaXR5IG9mIHRoZSBvc2NpbGxhdG9ycyB3aGljaCBtYWtlIHVwIHRoZSBzb3VyY2UuXG5cdFx0ICogIHNlZSBUb25lLkZNT3NjaWxsYXRvci5oYXJtb25pY2l0eVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5NZXRhbFN5bnRoI1xuXHRcdCAqICBAdHlwZSB7UG9zaXRpdmV9XG5cdFx0ICogIEBuYW1lICBoYXJtb25pY2l0eVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuTWV0YWxTeW50aC5wcm90b3R5cGUsICdoYXJtb25pY2l0eScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzWzBdLmhhcm1vbmljaXR5LnZhbHVlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsKSB7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fb3NjaWxsYXRvcnMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzW2ldLmhhcm1vbmljaXR5LnZhbHVlID0gdmFsO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGZyZXF1ZW5jeSBvZiB0aGUgaGlnaHBhc3MgZmlsdGVyIGF0dGFjaGVkIHRvIHRoZSBlbnZlbG9wZVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5NZXRhbFN5bnRoI1xuXHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdCAqICBAbmFtZSAgcmVzb25hbmNlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5NZXRhbFN5bnRoLnByb3RvdHlwZSwgJ3Jlc29uYW5jZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIubWluO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIubWluID0gdmFsO1xuXHQgICAgICAgICAgICB0aGlzLm9jdGF2ZXMgPSB0aGlzLl9vY3RhdmVzO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFRoZSBudW1iZXIgb2Ygb2N0YXZlcyBhYm92ZSB0aGUgXCJyZXNvbmFuY2VcIiBmcmVxdWVuY3lcblx0XHQgKiAgdGhhdCB0aGUgZmlsdGVyIHJhbXBzIGR1cmluZyB0aGUgYXR0YWNrL2RlY2F5IGVudmVsb3BlXG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLk1ldGFsU3ludGgjXG5cdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogIEBuYW1lICBvY3RhdmVzXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5NZXRhbFN5bnRoLnByb3RvdHlwZSwgJ29jdGF2ZXMnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9vY3RhdmVzO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAob2N0cykge1xuXHQgICAgICAgICAgICB0aGlzLl9vY3RhdmVzID0gb2N0cztcblx0ICAgICAgICAgICAgdGhpcy5fZmlsdGVyRnJlcVNjYWxlci5tYXggPSB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLm1pbiAqIE1hdGgucG93KDIsIG9jdHMpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIENsZWFuIHVwXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk1ldGFsU3ludGh9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTWV0YWxTeW50aC5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkluc3RydW1lbnQucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzW2ldLmRpc3Bvc2UoKTtcblx0ICAgICAgICAgICAgdGhpcy5fZnJlcU11bHRpcGxpZXJzW2ldLmRpc3Bvc2UoKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2ZyZXFNdWx0aXBsaWVycyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9hbXBsaXR1ZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fYW1wbGl0dWUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2hpZ2hwYXNzLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9oaWdocGFzcyA9IG51bGw7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuTWV0YWxTeW50aDtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzICBUb25lLk5vaXNlU3ludGggaXMgY29tcG9zZWQgb2YgYSBub2lzZSBnZW5lcmF0b3IgKFRvbmUuTm9pc2UpLCBvbmUgZmlsdGVyIChUb25lLkZpbHRlciksXG5cdFx0ICogICAgICAgICAgYW5kIHR3byBlbnZlbG9wZXMgKFRvbmUuRW52ZWxvcCkuIE9uZSBlbnZlbG9wZSBjb250cm9scyB0aGUgYW1wbGl0dWRlXG5cdFx0ICogICAgICAgICAgb2YgdGhlIG5vaXNlIGFuZCB0aGUgb3RoZXIgaXMgY29udHJvbHMgdGhlIGN1dG9mZiBmcmVxdWVuY3kgb2YgdGhlIGZpbHRlci5cblx0XHQgKiAgICAgICAgICA8aW1nIHNyYz1cImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL2RyYXdpbmdzL2QvMXJxenVYOXJCbGhUNTBNUnZEMlRLbWw5Ym5aaGNabXpYRjFyZl9vN3ZkbkUvcHViP3c9OTE4Jmg9MjQyXCI+XG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkluc3RydW1lbnR9XG5cdFx0ICogIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gdGhlIG9wdGlvbnMgYXZhaWxhYmxlIGZvciB0aGUgc3ludGhcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlIGRlZmF1bHRzIGJlbG93XG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiB2YXIgbm9pc2VTeW50aCA9IG5ldyBUb25lLk5vaXNlU3ludGgoKS50b01hc3RlcigpO1xuXHRcdCAqIG5vaXNlU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCI4blwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuTm9pc2VTeW50aCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cdCAgICAgICAgLy9nZXQgdGhlIGRlZmF1bHRzXG5cdCAgICAgICAgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdEFyZyhvcHRpb25zLCBUb25lLk5vaXNlU3ludGguZGVmYXVsdHMpO1xuXHQgICAgICAgIFRvbmUuSW5zdHJ1bWVudC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBub2lzZSBzb3VyY2UuXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuTm9pc2V9XG5cdFx0XHQgKiAgQGV4YW1wbGVcblx0XHRcdCAqIG5vaXNlU3ludGguc2V0KFwibm9pc2UudHlwZVwiLCBcImJyb3duXCIpO1xuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5ub2lzZSA9IG5ldyBUb25lLk5vaXNlKCk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cblx0XHRcdCAqICBAdHlwZSB7VG9uZS5BbXBsaXR1ZGVFbnZlbG9wZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUgPSBuZXcgVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZShvcHRpb25zLmVudmVsb3BlKTtcblx0ICAgICAgICAvL2Nvbm5lY3QgdGhlIG5vaXNlIHRvIHRoZSBvdXRwdXRcblx0ICAgICAgICB0aGlzLm5vaXNlLmNoYWluKHRoaXMuZW52ZWxvcGUsIHRoaXMub3V0cHV0KTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdub2lzZScsXG5cdCAgICAgICAgICAgICdlbnZlbG9wZSdcblx0ICAgICAgICBdKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLk5vaXNlU3ludGgsIFRvbmUuSW5zdHJ1bWVudCk7XG5cdCAgICAvKipcblx0XHQgKiAgQGNvbnN0XG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuTm9pc2VTeW50aC5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnbm9pc2UnOiB7ICd0eXBlJzogJ3doaXRlJyB9LFxuXHQgICAgICAgICdlbnZlbG9wZSc6IHtcblx0ICAgICAgICAgICAgJ2F0dGFjayc6IDAuMDA1LFxuXHQgICAgICAgICAgICAnZGVjYXknOiAwLjEsXG5cdCAgICAgICAgICAgICdzdXN0YWluJzogMFxuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU3RhcnQgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZXMuIFVubGlrZSBvdGhlclxuXHRcdCAqICBpbnN0cnVtZW50cywgVG9uZS5Ob2lzZVN5bnRoIGRvZXNuJ3QgaGF2ZSBhIG5vdGUuXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW3RpbWU9bm93XSB0aGUgdGltZSB0aGUgYXR0YWNrIHNob3VsZCBzdGFydFxuXHRcdCAqICBAcGFyYW0ge251bWJlcn0gW3ZlbG9jaXR5PTFdIHRoZSB2ZWxvY2l0eSBvZiB0aGUgbm90ZSAoMC0xKVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5Ob2lzZVN5bnRofSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogbm9pc2VTeW50aC50cmlnZ2VyQXR0YWNrKCk7XG5cdFx0ICovXG5cdCAgICBUb25lLk5vaXNlU3ludGgucHJvdG90eXBlLnRyaWdnZXJBdHRhY2sgPSBmdW5jdGlvbiAodGltZSwgdmVsb2NpdHkpIHtcblx0ICAgICAgICAvL3RoZSBlbnZlbG9wZXNcblx0ICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuXHQgICAgICAgIC8vc3RhcnQgdGhlIG5vaXNlXG5cdCAgICAgICAgdGhpcy5ub2lzZS5zdGFydCh0aW1lKTtcblx0ICAgICAgICBpZiAodGhpcy5lbnZlbG9wZS5zdXN0YWluID09PSAwKSB7XG5cdCAgICAgICAgICAgIHRoaXMubm9pc2Uuc3RvcCh0aW1lID0gdGhpcy5lbnZlbG9wZS5hdHRhY2sgKyB0aGlzLmVudmVsb3BlLmRlY2F5KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFN0YXJ0IHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIGVudmVsb3Blcy5cblx0XHQgKiAgQHBhcmFtIHtUaW1lfSBbdGltZT1ub3ddIHRoZSB0aW1lIHRoZSByZWxlYXNlIHNob3VsZCBzdGFydFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5Ob2lzZVN5bnRofSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk5vaXNlU3ludGgucHJvdG90eXBlLnRyaWdnZXJSZWxlYXNlID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuXHQgICAgICAgIHRoaXMubm9pc2Uuc3RvcCh0aW1lICsgdGhpcy5lbnZlbG9wZS5yZWxlYXNlKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBTeW5jIHRoZSBpbnN0cnVtZW50IHRvIHRoZSBUcmFuc3BvcnQuIEFsbCBzdWJzZXF1ZW50IGNhbGxzIG9mXG5cdFx0ICogW3RyaWdnZXJBdHRhY2tdKCN0cmlnZ2VyYXR0YWNrKSBhbmQgW3RyaWdnZXJSZWxlYXNlXSgjdHJpZ2dlcnJlbGVhc2UpXG5cdFx0ICogd2lsbCBiZSBzY2hlZHVsZWQgYWxvbmcgdGhlIHRyYW5zcG9ydC5cblx0XHQgKiBAZXhhbXBsZVxuXHRcdCAqIHN5bnRoLnN5bmMoKVxuXHRcdCAqIC8vc2NoZWR1bGUgMyBub3RlcyB3aGVuIHRoZSB0cmFuc3BvcnQgZmlyc3Qgc3RhcnRzXG5cdFx0ICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoJzhuJywgMClcblx0XHQgKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZSgnOG4nLCAnOG4nKVxuXHRcdCAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKCc4bicsICc0bicpXG5cdFx0ICogLy9zdGFydCB0aGUgdHJhbnNwb3J0IHRvIGhlYXIgdGhlIG5vdGVzXG5cdFx0ICogVHJhbnNwb3J0LnN0YXJ0KClcblx0XHQgKiBAcmV0dXJucyB7VG9uZS5JbnN0cnVtZW50fSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk5vaXNlU3ludGgucHJvdG90eXBlLnN5bmMgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fc3luY01ldGhvZCgndHJpZ2dlckF0dGFjaycsIDApO1xuXHQgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoJ3RyaWdnZXJSZWxlYXNlJywgMCk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRyaWdnZXIgdGhlIGF0dGFjayBhbmQgdGhlbiB0aGUgcmVsZWFzZS5cblx0XHQgKiAgQHBhcmFtICB7VGltZX0gZHVyYXRpb24gdGhlIGR1cmF0aW9uIG9mIHRoZSBub3RlXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IFt0aW1lPW5vd10gICAgIHRoZSB0aW1lIG9mIHRoZSBhdHRhY2tcblx0XHQgKiAgQHBhcmFtICB7bnVtYmVyfSBbdmVsb2NpdHk9MV0gdGhlIHZlbG9jaXR5XG5cdFx0ICogIEByZXR1cm5zIHtUb25lLk5vaXNlU3ludGh9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuTm9pc2VTeW50aC5wcm90b3R5cGUudHJpZ2dlckF0dGFja1JlbGVhc2UgPSBmdW5jdGlvbiAoZHVyYXRpb24sIHRpbWUsIHZlbG9jaXR5KSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIGR1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuXHQgICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG5cdCAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZSh0aW1lICsgZHVyYXRpb24pO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuTm9pc2VTeW50aH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Ob2lzZVN5bnRoLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuSW5zdHJ1bWVudC5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ25vaXNlJyxcblx0ICAgICAgICAgICAgJ2VudmVsb3BlJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgICAgIHRoaXMubm9pc2UuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMubm9pc2UgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZW52ZWxvcGUgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLk5vaXNlU3ludGg7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBLYXJwbHVzLVN0cmluZyBzdHJpbmcgc3ludGhlc2lzLiBPZnRlbiBvdXQgb2YgdHVuZS5cblx0XHQgKiAgICAgICAgIFdpbGwgY2hhbmdlIHdoZW4gdGhlIEF1ZGlvV29ya2VyTm9kZSBpcyBhdmFpbGFibGUgYWNyb3NzXG5cdFx0ICogICAgICAgICBicm93c2Vycy5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuSW5zdHJ1bWVudH1cblx0XHQgKiAgQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBzZWUgdGhlIGRlZmF1bHRzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIHBsdWNreSA9IG5ldyBUb25lLlBsdWNrU3ludGgoKS50b01hc3RlcigpO1xuXHRcdCAqIHBsdWNreS50cmlnZ2VyQXR0YWNrKFwiQzRcIik7XG5cdFx0ICovXG5cdCAgICBUb25lLlBsdWNrU3ludGggPSBmdW5jdGlvbiAob3B0aW9ucykge1xuXHQgICAgICAgIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRBcmcob3B0aW9ucywgVG9uZS5QbHVja1N5bnRoLmRlZmF1bHRzKTtcblx0ICAgICAgICBUb25lLkluc3RydW1lbnQuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAdHlwZSB7VG9uZS5Ob2lzZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZSgncGluaycpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBhbW91bnQgb2Ygbm9pc2UgYXQgdGhlIGF0dGFjay5cblx0XHRcdCAqICBOb21pbmFsIHJhbmdlIG9mIFswLjEsIDIwXVxuXHRcdFx0ICogIEB0eXBlIHtudW1iZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmF0dGFja05vaXNlID0gb3B0aW9ucy5hdHRhY2tOb2lzZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgTEZDRlxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkxvd3Bhc3NDb21iRmlsdGVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9sZmNmID0gbmV3IFRvbmUuTG93cGFzc0NvbWJGaWx0ZXIoe1xuXHQgICAgICAgICAgICAncmVzb25hbmNlJzogb3B0aW9ucy5yZXNvbmFuY2UsXG5cdCAgICAgICAgICAgICdkYW1wZW5pbmcnOiBvcHRpb25zLmRhbXBlbmluZ1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSByZXNvbmFuY2UgY29udHJvbC5cblx0XHRcdCAqICBAdHlwZSB7Tm9ybWFsUmFuZ2V9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5yZXNvbmFuY2UgPSB0aGlzLl9sZmNmLnJlc29uYW5jZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZGFtcGVuaW5nIGNvbnRyb2wuIGkuZS4gdGhlIGxvd3Bhc3MgZmlsdGVyIGZyZXF1ZW5jeSBvZiB0aGUgY29tYiBmaWx0ZXJcblx0XHRcdCAqICBAdHlwZSB7RnJlcXVlbmN5fVxuXHRcdFx0ICogIEBzaWduYWxcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuZGFtcGVuaW5nID0gdGhpcy5fbGZjZi5kYW1wZW5pbmc7XG5cdCAgICAgICAgLy9jb25uZWN0aW9uc1xuXHQgICAgICAgIHRoaXMuX25vaXNlLmNvbm5lY3QodGhpcy5fbGZjZik7XG5cdCAgICAgICAgdGhpcy5fbGZjZi5jb25uZWN0KHRoaXMub3V0cHV0KTtcblx0ICAgICAgICB0aGlzLl9yZWFkT25seShbXG5cdCAgICAgICAgICAgICdyZXNvbmFuY2UnLFxuXHQgICAgICAgICAgICAnZGFtcGVuaW5nJ1xuXHQgICAgICAgIF0pO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuUGx1Y2tTeW50aCwgVG9uZS5JbnN0cnVtZW50KTtcblx0ICAgIC8qKlxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBjb25zdFxuXHRcdCAqICBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QbHVja1N5bnRoLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdhdHRhY2tOb2lzZSc6IDEsXG5cdCAgICAgICAgJ2RhbXBlbmluZyc6IDQwMDAsXG5cdCAgICAgICAgJ3Jlc29uYW5jZSc6IDAuN1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUcmlnZ2VyIHRoZSBub3RlLlxuXHRcdCAqICBAcGFyYW0ge0ZyZXF1ZW5jeX0gbm90ZSBUaGUgbm90ZSB0byB0cmlnZ2VyLlxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IFt0aW1lPW5vd10gV2hlbiB0aGUgbm90ZSBzaG91bGQgYmUgdHJpZ2dlcmVkLlxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5QbHVja1N5bnRofSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlBsdWNrU3ludGgucHJvdG90eXBlLnRyaWdnZXJBdHRhY2sgPSBmdW5jdGlvbiAobm90ZSwgdGltZSkge1xuXHQgICAgICAgIG5vdGUgPSB0aGlzLnRvRnJlcXVlbmN5KG5vdGUpO1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB2YXIgZGVsYXlBbW91bnQgPSAxIC8gbm90ZTtcblx0ICAgICAgICB0aGlzLl9sZmNmLmRlbGF5VGltZS5zZXRWYWx1ZUF0VGltZShkZWxheUFtb3VudCwgdGltZSk7XG5cdCAgICAgICAgdGhpcy5fbm9pc2Uuc3RhcnQodGltZSk7XG5cdCAgICAgICAgdGhpcy5fbm9pc2Uuc3RvcCh0aW1lICsgZGVsYXlBbW91bnQgKiB0aGlzLmF0dGFja05vaXNlKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgQ2xlYW4gdXAuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBsdWNrU3ludGh9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGx1Y2tTeW50aC5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkluc3RydW1lbnQucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9ub2lzZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbGZjZi5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fbm9pc2UgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2xmY2YgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX3dyaXRhYmxlKFtcblx0ICAgICAgICAgICAgJ3Jlc29uYW5jZScsXG5cdCAgICAgICAgICAgICdkYW1wZW5pbmcnXG5cdCAgICAgICAgXSk7XG5cdCAgICAgICAgdGhpcy5kYW1wZW5pbmcgPSBudWxsO1xuXHQgICAgICAgIHRoaXMucmVzb25hbmNlID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5QbHVja1N5bnRoO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIFRvbmUuUG9seVN5bnRoIGhhbmRsZXMgdm9pY2UgY3JlYXRpb24gYW5kIGFsbG9jYXRpb24gZm9yIGFueVxuXHRcdCAqICAgICAgICAgIGluc3RydW1lbnRzIHBhc3NlZCBpbiBhcyB0aGUgc2Vjb25kIHBhcmFtdGVyLiBQb2x5U3ludGggaXNcblx0XHQgKiAgICAgICAgICBub3QgYSBzeW50aGVzaXplciBieSBpdHNlbGYsIGl0IG1lcmVseSBtYW5hZ2VzIHZvaWNlcyBvZlxuXHRcdCAqICAgICAgICAgIG9uZSBvZiB0aGUgb3RoZXIgdHlwZXMgb2Ygc3ludGhzLCBhbGxvd2luZyBhbnkgb2YgdGhlXG5cdFx0ICogICAgICAgICAgbW9ub3Bob25pYyBzeW50aGVzaXplcnMgdG8gYmUgcG9seXBob25pYy5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuSW5zdHJ1bWVudH1cblx0XHQgKiAgQHBhcmFtIHtudW1iZXJ8T2JqZWN0fSBbcG9seXBob255PTRdIFRoZSBudW1iZXIgb2Ygdm9pY2VzIHRvIGNyZWF0ZVxuXHRcdCAqICBAcGFyYW0ge2Z1bmN0aW9ufSBbdm9pY2U9VG9uZS5TeW50aF0gVGhlIGNvbnN0cnVjdG9yIG9mIHRoZSB2b2ljZXNcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlcyBUb25lLlN5bnRoIGJ5IGRlZmF1bHQuXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9hIHBvbHlzeW50aCBjb21wb3NlZCBvZiA2IFZvaWNlcyBvZiBTeW50aFxuXHRcdCAqIHZhciBzeW50aCA9IG5ldyBUb25lLlBvbHlTeW50aCg2LCBUb25lLlN5bnRoKS50b01hc3RlcigpO1xuXHRcdCAqIC8vc2V0IHRoZSBhdHRyaWJ1dGVzIHVzaW5nIHRoZSBzZXQgaW50ZXJmYWNlXG5cdFx0ICogc3ludGguc2V0KFwiZGV0dW5lXCIsIC0xMjAwKTtcblx0XHQgKiAvL3BsYXkgYSBjaG9yZFxuXHRcdCAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFtcIkM0XCIsIFwiRTRcIiwgXCJBNFwiXSwgXCI0blwiKTtcblx0XHQgKi9cblx0ICAgIFRvbmUuUG9seVN5bnRoID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ3BvbHlwaG9ueScsXG5cdCAgICAgICAgICAgICd2b2ljZSdcblx0ICAgICAgICBdLCBUb25lLlBvbHlTeW50aCk7XG5cdCAgICAgICAgVG9uZS5JbnN0cnVtZW50LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdEFyZyhvcHRpb25zLCBUb25lLkluc3RydW1lbnQuZGVmYXVsdHMpO1xuXHQgICAgICAgIC8vbWF4IHBvbHlwaG9ueVxuXHQgICAgICAgIG9wdGlvbnMucG9seXBob255ID0gTWF0aC5taW4oVG9uZS5Qb2x5U3ludGguTUFYX1BPTFlQSE9OWSwgb3B0aW9ucy5wb2x5cGhvbnkpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBhcnJheSBvZiB2b2ljZXNcblx0XHRcdCAqICBAdHlwZSB7QXJyYXl9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLnZvaWNlcyA9IG5ldyBBcnJheShvcHRpb25zLnBvbHlwaG9ueSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIHF1ZXVlIG9mIHZvaWNlcyB3aXRoIGRhdGEgYWJvdXQgbGFzdCB0cmlnZ2VyXG5cdFx0XHQgKiAgYW5kIHRoZSB0cmlnZ2VyZWQgbm90ZVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge0FycmF5fVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fdHJpZ2dlcnMgPSBuZXcgQXJyYXkob3B0aW9ucy5wb2x5cGhvbnkpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBkZXR1bmUgaW4gY2VudHNcblx0XHRcdCAqICBAdHlwZSB7Q2VudHN9XG5cdFx0XHQgKiAgQHNpZ25hbFxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgVG9uZS5TaWduYWwob3B0aW9ucy5kZXR1bmUsIFRvbmUuVHlwZS5DZW50cyk7XG5cdCAgICAgICAgdGhpcy5fcmVhZE9ubHkoJ2RldHVuZScpO1xuXHQgICAgICAgIC8vY3JlYXRlIHRoZSB2b2ljZXNcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9wdGlvbnMucG9seXBob255OyBpKyspIHtcblx0ICAgICAgICAgICAgdmFyIHYgPSBuZXcgb3B0aW9ucy52b2ljZShhcmd1bWVudHNbMl0sIGFyZ3VtZW50c1szXSk7XG5cdCAgICAgICAgICAgIGlmICghKHYgaW5zdGFuY2VvZiBUb25lLk1vbm9waG9uaWMpKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N5bnRoIGNvbnN0cnVjdG9yIG11c3QgYmUgaW5zdGFuY2Ugb2YgVG9uZS5Nb25vcGhvbmljJyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy52b2ljZXNbaV0gPSB2O1xuXHQgICAgICAgICAgICB2LmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuXHQgICAgICAgICAgICBpZiAodi5oYXNPd25Qcm9wZXJ0eSgnZGV0dW5lJykpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3Qodi5kZXR1bmUpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuX3RyaWdnZXJzW2ldID0ge1xuXHQgICAgICAgICAgICAgICAgcmVsZWFzZTogLTEsXG5cdCAgICAgICAgICAgICAgICBub3RlOiBudWxsLFxuXHQgICAgICAgICAgICAgICAgdm9pY2U6IHZcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5Qb2x5U3ludGgsIFRvbmUuSW5zdHJ1bWVudCk7XG5cdCAgICAvKipcblx0XHQgKiAgdGhlIGRlZmF1bHRzXG5cdFx0ICogIEBjb25zdFxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLlBvbHlTeW50aC5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAncG9seXBob255JzogNCxcblx0ICAgICAgICAndm9sdW1lJzogMCxcblx0ICAgICAgICAnZGV0dW5lJzogMCxcblx0ICAgICAgICAndm9pY2UnOiBUb25lLlN5bnRoXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFRyaWdnZXIgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBub3RlXG5cdFx0ICogIEBwYXJhbSAge0ZyZXF1ZW5jeXxBcnJheX0gbm90ZXMgVGhlIG5vdGVzIHRvIHBsYXkuIEFjY2VwdHMgYSBzaW5nbGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGcmVxdWVuY3kgb3IgYW4gYXJyYXkgb2YgZnJlcXVlbmNpZXMuXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IFt0aW1lPW5vd10gIFRoZSBzdGFydCB0aW1lIG9mIHRoZSBub3RlLlxuXHRcdCAqICBAcGFyYW0ge251bWJlcn0gW3ZlbG9jaXR5PTFdIFRoZSB2ZWxvY2l0eSBvZiB0aGUgbm90ZS5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuUG9seVN5bnRofSB0aGlzXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy90cmlnZ2VyIGEgY2hvcmQgaW1tZWRpYXRlbHkgd2l0aCBhIHZlbG9jaXR5IG9mIDAuMlxuXHRcdCAqIHBvbHkudHJpZ2dlckF0dGFjayhbXCJBYjNcIiwgXCJDNFwiLCBcIkY1XCJdLCB1bmRlZmluZWQsIDAuMik7XG5cdFx0ICovXG5cdCAgICBUb25lLlBvbHlTeW50aC5wcm90b3R5cGUudHJpZ2dlckF0dGFjayA9IGZ1bmN0aW9uIChub3RlcywgdGltZSwgdmVsb2NpdHkpIHtcblx0ICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobm90ZXMpKSB7XG5cdCAgICAgICAgICAgIG5vdGVzID0gW25vdGVzXTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm90ZXMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgdmFyIHZhbCA9IG5vdGVzW2ldO1xuXHQgICAgICAgICAgICAvL3RyaWdnZXIgdGhlIG9sZGVzdCB2b2ljZVxuXHQgICAgICAgICAgICB2YXIgb2xkZXN0ID0gdGhpcy5fdHJpZ2dlcnNbMF07XG5cdCAgICAgICAgICAgIGZvciAodmFyIGogPSAxOyBqIDwgdGhpcy5fdHJpZ2dlcnMubGVuZ3RoOyBqKyspIHtcblx0ICAgICAgICAgICAgICAgIGlmICh0aGlzLl90cmlnZ2Vyc1tqXS5yZWxlYXNlIDwgb2xkZXN0LnJlbGVhc2UpIHtcblx0ICAgICAgICAgICAgICAgICAgICBvbGRlc3QgPSB0aGlzLl90cmlnZ2Vyc1tqXTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBvbGRlc3QucmVsZWFzZSA9IEluZmluaXR5O1xuXHQgICAgICAgICAgICBvbGRlc3Qubm90ZSA9IEpTT04uc3RyaW5naWZ5KHZhbCk7XG5cdCAgICAgICAgICAgIG9sZGVzdC52b2ljZS50cmlnZ2VyQXR0YWNrKHZhbCwgdGltZSwgdmVsb2NpdHkpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVHJpZ2dlciB0aGUgYXR0YWNrIGFuZCByZWxlYXNlIGFmdGVyIHRoZSBzcGVjaWZpZWQgZHVyYXRpb25cblx0XHQgKlxuXHRcdCAqICBAcGFyYW0gIHtGcmVxdWVuY3l8QXJyYXl9IG5vdGVzIFRoZSBub3RlcyB0byBwbGF5LiBBY2NlcHRzIGEgc2luZ2xlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRnJlcXVlbmN5IG9yIGFuIGFycmF5IG9mIGZyZXF1ZW5jaWVzLlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBkdXJhdGlvbiB0aGUgZHVyYXRpb24gb2YgdGhlIG5vdGVcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gW3RpbWU9bm93XSAgICAgaWYgbm8gdGltZSBpcyBnaXZlbiwgZGVmYXVsdHMgdG8gbm93XG5cdFx0ICogIEBwYXJhbSAge251bWJlcn0gW3ZlbG9jaXR5PTFdIHRoZSB2ZWxvY2l0eSBvZiB0aGUgYXR0YWNrICgwLTEpXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBvbHlTeW50aH0gdGhpc1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vdHJpZ2dlciBhIGNob3JkIGZvciBhIGR1cmF0aW9uIG9mIGEgaGFsZiBub3RlXG5cdFx0ICogcG9seS50cmlnZ2VyQXR0YWNrUmVsZWFzZShbXCJFYjNcIiwgXCJHNFwiLCBcIkM1XCJdLCBcIjJuXCIpO1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vY2FuIHBhc3MgaW4gYW4gYXJyYXkgb2YgZHVyYXRpb25zIGFzIHdlbGxcblx0XHQgKiBwb2x5LnRyaWdnZXJBdHRhY2tSZWxlYXNlKFtcIkViM1wiLCBcIkc0XCIsIFwiQzVcIl0sIFtcIjJuXCIsIFwiNG5cIiwgXCI0blwiXSk7XG5cdFx0ICovXG5cdCAgICBUb25lLlBvbHlTeW50aC5wcm90b3R5cGUudHJpZ2dlckF0dGFja1JlbGVhc2UgPSBmdW5jdGlvbiAobm90ZXMsIGR1cmF0aW9uLCB0aW1lLCB2ZWxvY2l0eSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sobm90ZXMsIHRpbWUsIHZlbG9jaXR5KTtcblx0ICAgICAgICBpZiAoVG9uZS5pc0FycmF5KGR1cmF0aW9uKSAmJiBUb25lLmlzQXJyYXkobm90ZXMpKSB7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm90ZXMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHZhciBkID0gZHVyYXRpb25bTWF0aC5taW4oaSwgZHVyYXRpb24ubGVuZ3RoIC0gMSldO1xuXHQgICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZShub3Rlc1tpXSwgdGltZSArIHRoaXMudG9TZWNvbmRzKGQpKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2Uobm90ZXMsIHRpbWUgKyB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbikpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVHJpZ2dlciB0aGUgcmVsZWFzZSBvZiB0aGUgbm90ZS4gVW5saWtlIG1vbm9waG9uaWMgaW5zdHJ1bWVudHMsXG5cdFx0ICogIGEgbm90ZSAob3IgYXJyYXkgb2Ygbm90ZXMpIG5lZWRzIHRvIGJlIHBhc3NlZCBpbiBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG5cdFx0ICogIEBwYXJhbSAge0ZyZXF1ZW5jeXxBcnJheX0gbm90ZXMgVGhlIG5vdGVzIHRvIHBsYXkuIEFjY2VwdHMgYSBzaW5nbGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGcmVxdWVuY3kgb3IgYW4gYXJyYXkgb2YgZnJlcXVlbmNpZXMuXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IFt0aW1lPW5vd10gIFdoZW4gdGhlIHJlbGVhc2Ugd2lsbCBiZSB0cmlnZ2VyZWQuXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBvbHlTeW50aH0gdGhpc1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHBvbHkudHJpZ2dlclJlbGVhc2UoW1wiQWIzXCIsIFwiQzRcIiwgXCJGNVwiXSwgXCIrMm5cIik7XG5cdFx0ICovXG5cdCAgICBUb25lLlBvbHlTeW50aC5wcm90b3R5cGUudHJpZ2dlclJlbGVhc2UgPSBmdW5jdGlvbiAobm90ZXMsIHRpbWUpIHtcblx0ICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobm90ZXMpKSB7XG5cdCAgICAgICAgICAgIG5vdGVzID0gW25vdGVzXTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm90ZXMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgLy9nZXQgdGhlIHZvaWNlXG5cdCAgICAgICAgICAgIHZhciBzdHJpbmdpZmllZCA9IEpTT04uc3RyaW5naWZ5KG5vdGVzW2ldKTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgdiA9IDA7IHYgPCB0aGlzLl90cmlnZ2Vycy5sZW5ndGg7IHYrKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGRlc2MgPSB0aGlzLl90cmlnZ2Vyc1t2XTtcblx0ICAgICAgICAgICAgICAgIGlmIChkZXNjLm5vdGUgPT09IHN0cmluZ2lmaWVkICYmIGRlc2MucmVsZWFzZSA+IHRpbWUpIHtcblx0ICAgICAgICAgICAgICAgICAgICBkZXNjLnZvaWNlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuXHQgICAgICAgICAgICAgICAgICAgIGRlc2MucmVsZWFzZSA9IHRpbWU7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogU3luYyB0aGUgaW5zdHJ1bWVudCB0byB0aGUgVHJhbnNwb3J0LiBBbGwgc3Vic2VxdWVudCBjYWxscyBvZlxuXHRcdCAqIFt0cmlnZ2VyQXR0YWNrXSgjdHJpZ2dlcmF0dGFjaykgYW5kIFt0cmlnZ2VyUmVsZWFzZV0oI3RyaWdnZXJyZWxlYXNlKVxuXHRcdCAqIHdpbGwgYmUgc2NoZWR1bGVkIGFsb25nIHRoZSB0cmFuc3BvcnQuXG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiBzeW50aC5zeW5jKClcblx0XHQgKiAvL3NjaGVkdWxlIDMgbm90ZXMgd2hlbiB0aGUgdHJhbnNwb3J0IGZpcnN0IHN0YXJ0c1xuXHRcdCAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKCc4bicsIDApXG5cdFx0ICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoJzhuJywgJzhuJylcblx0XHQgKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZSgnOG4nLCAnNG4nKVxuXHRcdCAqIC8vc3RhcnQgdGhlIHRyYW5zcG9ydCB0byBoZWFyIHRoZSBub3Rlc1xuXHRcdCAqIFRyYW5zcG9ydC5zdGFydCgpXG5cdFx0ICogQHJldHVybnMge1RvbmUuSW5zdHJ1bWVudH0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Qb2x5U3ludGgucHJvdG90eXBlLnN5bmMgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fc3luY01ldGhvZCgndHJpZ2dlckF0dGFjaycsIDEpO1xuXHQgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoJ3RyaWdnZXJSZWxlYXNlJywgMSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFNldCBhIG1lbWJlci9hdHRyaWJ1dGUgb2YgdGhlIHZvaWNlcy5cblx0XHQgKiAgQHBhcmFtIHtPYmplY3R8c3RyaW5nfSBwYXJhbXNcblx0XHQgKiAgQHBhcmFtIHtudW1iZXI9fSB2YWx1ZVxuXHRcdCAqICBAcGFyYW0ge1RpbWU9fSByYW1wVGltZVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5Qb2x5U3ludGh9IHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBwb2x5LnNldCh7XG5cdFx0ICogXHRcImZpbHRlclwiIDoge1xuXHRcdCAqIFx0XHRcInR5cGVcIiA6IFwiaGlnaHBhc3NcIlxuXHRcdCAqIFx0fSxcblx0XHQgKiBcdFwiZW52ZWxvcGVcIiA6IHtcblx0XHQgKiBcdFx0XCJhdHRhY2tcIiA6IDAuMjVcblx0XHQgKiBcdH1cblx0XHQgKiB9KTtcblx0XHQgKi9cblx0ICAgIFRvbmUuUG9seVN5bnRoLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAocGFyYW1zLCB2YWx1ZSwgcmFtcFRpbWUpIHtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudm9pY2VzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgIHRoaXMudm9pY2VzW2ldLnNldChwYXJhbXMsIHZhbHVlLCByYW1wVGltZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBHZXQgdGhlIHN5bnRoJ3MgYXR0cmlidXRlcy4gR2l2ZW4gbm8gYXJndW1lbnRzIGdldFxuXHRcdCAqICB3aWxsIHJldHVybiBhbGwgYXZhaWxhYmxlIG9iamVjdCBwcm9wZXJ0aWVzIGFuZCB0aGVpciBjb3JyZXNwb25kaW5nXG5cdFx0ICogIHZhbHVlcy4gUGFzcyBpbiBhIHNpbmdsZSBhdHRyaWJ1dGUgdG8gcmV0cmlldmUgb3IgYW4gYXJyYXlcblx0XHQgKiAgb2YgYXR0cmlidXRlcy4gVGhlIGF0dHJpYnV0ZSBzdHJpbmdzIGNhbiBhbHNvIGluY2x1ZGUgYSBcIi5cIlxuXHRcdCAqICB0byBhY2Nlc3MgZGVlcGVyIHByb3BlcnRpZXMuXG5cdFx0ICogIEBwYXJhbSB7QXJyYXk9fSBwYXJhbXMgdGhlIHBhcmFtZXRlcnMgdG8gZ2V0LCBvdGhlcndpc2Ugd2lsbCByZXR1cm5cblx0XHQgKiAgXHRcdFx0XHRcdCAgIGFsbCBhdmFpbGFibGUuXG5cdFx0ICovXG5cdCAgICBUb25lLlBvbHlTeW50aC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKHBhcmFtcykge1xuXHQgICAgICAgIHJldHVybiB0aGlzLnZvaWNlc1swXS5nZXQocGFyYW1zKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVHJpZ2dlciB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIGFsbCB0aGUgY3VycmVudGx5IGFjdGl2ZSB2b2ljZXMuXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gW3RpbWU9bm93XSBXaGVuIHRoZSBub3RlcyBzaG91bGQgYmUgcmVsZWFzZWQuXG5cdFx0ICogIEByZXR1cm4ge1RvbmUuUG9seVN5bnRofSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlBvbHlTeW50aC5wcm90b3R5cGUucmVsZWFzZUFsbCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fdHJpZ2dlcnMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgdmFyIGRlc2MgPSB0aGlzLl90cmlnZ2Vyc1tpXTtcblx0ICAgICAgICAgICAgaWYgKGRlc2MucmVsZWFzZSA+IHRpbWUpIHtcblx0ICAgICAgICAgICAgICAgIGRlc2MucmVsZWFzZSA9IHRpbWU7XG5cdCAgICAgICAgICAgICAgICBkZXNjLnZvaWNlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbGVhbiB1cC5cblx0XHQgKiAgQHJldHVybnMge1RvbmUuUG9seVN5bnRofSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlBvbHlTeW50aC5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkluc3RydW1lbnQucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudm9pY2VzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgIHRoaXMudm9pY2VzW2ldLmRpc3Bvc2UoKTtcblx0ICAgICAgICAgICAgdGhpcy52b2ljZXNbaV0gPSBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLl93cml0YWJsZSgnZGV0dW5lJyk7XG5cdCAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuZGV0dW5lID0gbnVsbDtcblx0ICAgICAgICB0aGlzLnZvaWNlcyA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fdHJpZ2dlcnMgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUaGUgbWF4aW11bSBudW1iZXIgb2Ygbm90ZXMgdGhhdCBjYW4gYmUgYWxsb2NhdGVkXG5cdFx0ICogIHRvIGEgcG9seXN5bnRoLlxuXHRcdCAqICBAdHlwZSAge051bWJlcn1cblx0XHQgKiAgQHN0YXRpY1xuXHRcdCAqL1xuXHQgICAgVG9uZS5Qb2x5U3ludGguTUFYX1BPTFlQSE9OWSA9IDIwO1xuXHQgICAgcmV0dXJuIFRvbmUuUG9seVN5bnRoO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICAvKipcblx0XHQgKiBAY2xhc3MgQXV0b21hdGljYWxseSBpbnRlcnBvbGF0ZXMgYmV0d2VlbiBhIHNldCBvZiBwaXRjaGVkIHNhbXBsZXMuIFBhc3MgaW4gYW4gb2JqZWN0IHdoaWNoIG1hcHMgdGhlIG5vdGUncyBwaXRjaCBvciBtaWRpIHZhbHVlIHRvIHRoZSB1cmwsIHRoZW4geW91IGNhbiB0cmlnZ2VyIHRoZSBhdHRhY2sgYW5kIHJlbGVhc2Ugb2YgdGhhdCBub3RlIGxpa2Ugb3RoZXIgaW5zdHJ1bWVudHMuIEJ5IGF1dG9tYXRpY2FsbHkgcmVwaXRjaGluZyB0aGUgc2FtcGxlcywgaXQgaXMgcG9zc2libGUgdG8gcGxheSBwaXRjaGVzIHdoaWNoIHdlcmUgbm90IGV4cGxpY2l0bHkgaW5jbHVkZWQgd2hpY2ggY2FuIHNhdmUgbG9hZGluZyB0aW1lLlxuXHRcdCAqICAgICAgICBGb3Igc2FtcGxlIG9yIGJ1ZmZlciBwbGF5YmFjayB3aGVyZSByZXBpdGNoaW5nIGlzIG5vdCBuZWNlc3NhcnksIHVzZSBbVG9uZS5QbGF5ZXJdKGh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9kb2NzL1BsYXllcikuXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IHNhbXBsZXMgQW4gb2JqZWN0IG9mIHNhbXBsZXMgbWFwcGluZyBlaXRoZXIgTWlkaVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgIE5vdGUgTnVtYmVycyBvciBTY2llbnRpZmljIFBpdGNoIE5vdGF0aW9uXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgdG8gdGhlIHVybCBvZiB0aGF0IHNhbXBsZS5cblx0XHQgKiBAcGFyYW0ge0Z1bmN0aW9uPX0gb25sb2FkIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiBhbGwgb2YgdGhlIHNhbXBsZXMgYXJlIGxvYWRlZC5cblx0XHQgKiBAcGFyYW0ge1N0cmluZz19IGJhc2VVcmwgVGhlIHJvb3QgVVJMIG9mIGFsbCBvZiB0aGUgc2FtcGxlcywgd2hpY2ggaXMgcHJlcGVuZGVkIHRvIGFsbCB0aGUgVVJMcy5cblx0XHQgKiBAZXhhbXBsZVxuXHRcdCAqIHZhciBzYW1wbGVyID0gbmV3IFRvbmUuU2FtcGxlcih7XG5cdFx0ICogXHRcIkMzXCIgOiBcInBhdGgvdG8vQzMubXAzXCIsXG5cdFx0ICogXHRcIkQjM1wiIDogXCJwYXRoL3RvL0RzaGFycDMubXAzXCIsXG5cdFx0ICogXHRcIkYjM1wiIDogXCJwYXRoL3RvL0ZzaGFycDMubXAzXCIsXG5cdFx0ICogXHRcIkEzXCIgOiBcInBhdGgvdG8vQTMubXAzXCIsXG5cdFx0ICogfSwgZnVuY3Rpb24oKXtcblx0XHQgKiBcdC8vc2FtcGxlciB3aWxsIHJlcGl0Y2ggdGhlIGNsb3Nlc3Qgc2FtcGxlXG5cdFx0ICogXHRzYW1wbGVyLnRyaWdnZXJBdHRhY2soXCJEM1wiKVxuXHRcdCAqIH0pXG5cdFx0ICogQGV4dGVuZHMge1RvbmUuSW5zdHJ1bWVudH1cblx0XHQgKi9cblx0ICAgIFRvbmUuU2FtcGxlciA9IGZ1bmN0aW9uICh1cmxzKSB7XG5cdCAgICAgICAgLy8gc2hpZnQgYXJndW1lbnRzIG92ZXIgb25lLiBUaG9zZSBhcmUgdGhlIHJlbWFpbmRlciBvZiB0aGUgb3B0aW9uc1xuXHQgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblx0ICAgICAgICBhcmdzLnNoaWZ0KCk7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3MsIFtcblx0ICAgICAgICAgICAgJ29ubG9hZCcsXG5cdCAgICAgICAgICAgICdiYXNlVXJsJ1xuXHQgICAgICAgIF0sIFRvbmUuU2FtcGxlcik7XG5cdCAgICAgICAgVG9uZS5JbnN0cnVtZW50LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cdCAgICAgICAgdmFyIHVybE1hcCA9IHt9O1xuXHQgICAgICAgIGZvciAodmFyIG5vdGUgaW4gdXJscykge1xuXHQgICAgICAgICAgICBpZiAoVG9uZS5pc05vdGUobm90ZSkpIHtcblx0ICAgICAgICAgICAgICAgIC8vY29udmVydCB0aGUgbm90ZSBuYW1lIHRvIE1JRElcblx0ICAgICAgICAgICAgICAgIHZhciBtaWQgPSBUb25lLkZyZXF1ZW5jeShub3RlKS50b01pZGkoKTtcblx0ICAgICAgICAgICAgICAgIHVybE1hcFttaWRdID0gdXJsc1tub3RlXTtcblx0ICAgICAgICAgICAgfSBlbHNlIGlmICghaXNOYU4ocGFyc2VGbG9hdChub3RlKSkpIHtcblx0ICAgICAgICAgICAgICAgIC8vb3RoZXJ3aXNlIGlmIGl0J3MgbnVtYmVycyBhc3N1bWUgaXQncyBtaWRpXG5cdCAgICAgICAgICAgICAgICB1cmxNYXBbbm90ZV0gPSB1cmxzW25vdGVdO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUb25lLlNhbXBsZXI6IHVybCBrZXlzIG11c3QgYmUgdGhlIG5vdGVcXCdzIHBpdGNoJyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBUaGUgc3RvcmVkIGFuZCBsb2FkZWQgYnVmZmVyc1xuXHRcdFx0ICogQHR5cGUge1RvbmUuQnVmZmVyc31cblx0XHRcdCAqIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9idWZmZXJzID0gbmV3IFRvbmUuQnVmZmVycyh1cmxNYXAsIG9wdGlvbnMub25sb2FkLCBvcHRpb25zLmJhc2VVcmwpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIG9iamVjdCBvZiBhbGwgY3VycmVudGx5IHBsYXlpbmcgQnVmZmVyU291cmNlc1xuXHRcdFx0ICogQHR5cGUge09iamVjdH1cblx0XHRcdCAqIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzID0ge307XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBUaGUgZW52ZWxvcGUgYXBwbGllZCB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzYW1wbGUuXG5cdFx0XHQgKiBAdHlwZSB7VGltZX1cblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuYXR0YWNrID0gb3B0aW9ucy5hdHRhY2s7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBUaGUgZW52ZWxvcGUgYXBwbGllZCB0byB0aGUgZW5kIG9mIHRoZSBlbnZlbG9wZS5cblx0XHRcdCAqIEB0eXBlIHtUaW1lfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5yZWxlYXNlID0gb3B0aW9ucy5yZWxlYXNlO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuU2FtcGxlciwgVG9uZS5JbnN0cnVtZW50KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBkZWZhdWx0c1xuXHRcdCAqIEBjb25zdFxuXHRcdCAqIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLlNhbXBsZXIuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgYXR0YWNrOiAwLFxuXHQgICAgICAgIHJlbGVhc2U6IDAuMSxcblx0ICAgICAgICBvbmxvYWQ6IFRvbmUubm9PcCxcblx0ICAgICAgICBiYXNlVXJsOiAnJ1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFJldHVybnMgdGhlIGRpZmZlcmVuY2UgaW4gc3RlcHMgYmV0d2VlbiB0aGUgZ2l2ZW4gbWlkaSBub3RlIGF0IHRoZSBjbG9zZXRzIHNhbXBsZS5cblx0XHQgKiBAcGFyYW0gIHtNaWRpfSBtaWRpXG5cdFx0ICogQHJldHVybiB7SW50ZXJ2YWx9XG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuU2FtcGxlci5wcm90b3R5cGUuX2ZpbmRDbG9zZXN0ID0gZnVuY3Rpb24gKG1pZGkpIHtcblx0ICAgICAgICAvL3NlYXJjaGVzIHdpdGhpbiA4IG9jdGF2ZXMgb2YgdGhlIGdpdmVuIG1pZGkgbm90ZVxuXHQgICAgICAgIHZhciBNQVhfSU5URVJWQUwgPSA5Njtcblx0ICAgICAgICB2YXIgaW50ZXJ2YWwgPSAwO1xuXHQgICAgICAgIHdoaWxlIChpbnRlcnZhbCA8IE1BWF9JTlRFUlZBTCkge1xuXHQgICAgICAgICAgICAvLyBjaGVjayBhYm92ZSBhbmQgYmVsb3dcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcnMuaGFzKG1pZGkgKyBpbnRlcnZhbCkpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiAtaW50ZXJ2YWw7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYnVmZmVycy5oYXMobWlkaSAtIGludGVydmFsKSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGludGVydmFsO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGludGVydmFsKys7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBudWxsO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIEBwYXJhbSAge0ZyZXF1ZW5jeX0gbm90ZSAgICAgVGhlIG5vdGUgdG8gcGxheVxuXHRcdCAqIEBwYXJhbSAge1RpbWU9fSB0aW1lICAgICBXaGVuIHRvIHBsYXkgdGhlIG5vdGVcblx0XHQgKiBAcGFyYW0gIHtOb3JtYWxSYW5nZT19IHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSB0byBwbGF5IHRoZSBzYW1wbGUgYmFjay5cblx0XHQgKiBAcmV0dXJuIHtUb25lLlNhbXBsZXJ9ICAgICAgICAgIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuU2FtcGxlci5wcm90b3R5cGUudHJpZ2dlckF0dGFjayA9IGZ1bmN0aW9uIChub3RlLCB0aW1lLCB2ZWxvY2l0eSkge1xuXHQgICAgICAgIHZhciBtaWRpID0gVG9uZS5GcmVxdWVuY3kobm90ZSkudG9NaWRpKCk7XG5cdCAgICAgICAgLy8gZmluZCB0aGUgY2xvc2VzdCBub3RlIHBpdGNoXG5cdCAgICAgICAgdmFyIGRpZmZlcmVuY2UgPSB0aGlzLl9maW5kQ2xvc2VzdChtaWRpKTtcblx0ICAgICAgICBpZiAoZGlmZmVyZW5jZSAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICB2YXIgY2xvc2VzdE5vdGUgPSBtaWRpIC0gZGlmZmVyZW5jZTtcblx0ICAgICAgICAgICAgdmFyIGJ1ZmZlciA9IHRoaXMuX2J1ZmZlcnMuZ2V0KGNsb3Nlc3ROb3RlKTtcblx0ICAgICAgICAgICAgLy8gcGxheSB0aGF0IG5vdGVcblx0ICAgICAgICAgICAgdmFyIHNvdXJjZSA9IG5ldyBUb25lLkJ1ZmZlclNvdXJjZSh7XG5cdCAgICAgICAgICAgICAgICAnYnVmZmVyJzogYnVmZmVyLFxuXHQgICAgICAgICAgICAgICAgJ3BsYXliYWNrUmF0ZSc6IFRvbmUuaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGRpZmZlcmVuY2UpLFxuXHQgICAgICAgICAgICAgICAgJ2ZhZGVJbic6IHRoaXMuYXR0YWNrLFxuXHQgICAgICAgICAgICAgICAgJ2ZhZGVPdXQnOiB0aGlzLnJlbGVhc2UsXG5cdCAgICAgICAgICAgICAgICAnY3VydmUnOiAnZXhwb25lbnRpYWwnXG5cdCAgICAgICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuXHQgICAgICAgICAgICBzb3VyY2Uuc3RhcnQodGltZSwgMCwgYnVmZmVyLmR1cmF0aW9uLCB2ZWxvY2l0eSk7XG5cdCAgICAgICAgICAgIC8vIGFkZCBpdCB0byB0aGUgYWN0aXZlIHNvdXJjZXNcblx0ICAgICAgICAgICAgaWYgKCFUb25lLmlzQXJyYXkodGhpcy5fYWN0aXZlU291cmNlc1ttaWRpXSkpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXNbbWlkaV0gPSBbXTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzW21pZGldLnB1c2goe1xuXHQgICAgICAgICAgICAgICAgbm90ZTogbWlkaSxcblx0ICAgICAgICAgICAgICAgIHNvdXJjZTogc291cmNlXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBAcGFyYW0gIHtGcmVxdWVuY3l9IG5vdGUgICAgIFRoZSBub3RlIHRvIHJlbGVhc2UuXG5cdFx0ICogQHBhcmFtICB7VGltZT19IHRpbWUgICAgIFx0V2hlbiB0byByZWxlYXNlIHRoZSBub3RlLlxuXHRcdCAqIEByZXR1cm4ge1RvbmUuU2FtcGxlcn1cdHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuU2FtcGxlci5wcm90b3R5cGUudHJpZ2dlclJlbGVhc2UgPSBmdW5jdGlvbiAobm90ZSwgdGltZSkge1xuXHQgICAgICAgIHZhciBtaWRpID0gVG9uZS5GcmVxdWVuY3kobm90ZSkudG9NaWRpKCk7XG5cdCAgICAgICAgLy8gZmluZCB0aGUgbm90ZVxuXHQgICAgICAgIGlmICh0aGlzLl9hY3RpdmVTb3VyY2VzW21pZGldICYmIHRoaXMuX2FjdGl2ZVNvdXJjZXNbbWlkaV0ubGVuZ3RoKSB7XG5cdCAgICAgICAgICAgIHZhciBzb3VyY2UgPSB0aGlzLl9hY3RpdmVTb3VyY2VzW21pZGldLnNoaWZ0KCkuc291cmNlO1xuXHQgICAgICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgICAgIHNvdXJjZS5zdG9wKHRpbWUgKyB0aGlzLnJlbGVhc2UsIHRoaXMucmVsZWFzZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFJlbGVhc2UgYWxsIGN1cnJlbnRseSBhY3RpdmUgbm90ZXMuXG5cdFx0ICogQHBhcmFtICB7VGltZT19IHRpbWUgICAgIFx0V2hlbiB0byByZWxlYXNlIHRoZSBub3Rlcy5cblx0XHQgKiBAcmV0dXJuIHtUb25lLlNhbXBsZXJ9XHR0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlNhbXBsZXIucHJvdG90eXBlLnJlbGVhc2VBbGwgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICBmb3IgKHZhciBub3RlIGluIHRoaXMuX2FjdGl2ZVNvdXJjZXMpIHtcblx0ICAgICAgICAgICAgdmFyIHNvdXJjZXMgPSB0aGlzLl9hY3RpdmVTb3VyY2VzW25vdGVdO1xuXHQgICAgICAgICAgICB3aGlsZSAoc291cmNlcy5sZW5ndGgpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBzb3VyY2UgPSBzb3VyY2VzLnNoaWZ0KCkuc291cmNlO1xuXHQgICAgICAgICAgICAgICAgc291cmNlLnN0b3AodGltZSArIHRoaXMucmVsZWFzZSwgdGhpcy5yZWxlYXNlKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBTeW5jIHRoZSBpbnN0cnVtZW50IHRvIHRoZSBUcmFuc3BvcnQuIEFsbCBzdWJzZXF1ZW50IGNhbGxzIG9mXG5cdFx0ICogW3RyaWdnZXJBdHRhY2tdKCN0cmlnZ2VyYXR0YWNrKSBhbmQgW3RyaWdnZXJSZWxlYXNlXSgjdHJpZ2dlcnJlbGVhc2UpXG5cdFx0ICogd2lsbCBiZSBzY2hlZHVsZWQgYWxvbmcgdGhlIHRyYW5zcG9ydC5cblx0XHQgKiBAZXhhbXBsZVxuXHRcdCAqIHN5bnRoLnN5bmMoKVxuXHRcdCAqIC8vc2NoZWR1bGUgMyBub3RlcyB3aGVuIHRoZSB0cmFuc3BvcnQgZmlyc3Qgc3RhcnRzXG5cdFx0ICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoJzhuJywgMClcblx0XHQgKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZSgnOG4nLCAnOG4nKVxuXHRcdCAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKCc4bicsICc0bicpXG5cdFx0ICogLy9zdGFydCB0aGUgdHJhbnNwb3J0IHRvIGhlYXIgdGhlIG5vdGVzXG5cdFx0ICogVHJhbnNwb3J0LnN0YXJ0KClcblx0XHQgKiBAcmV0dXJucyB7VG9uZS5JbnN0cnVtZW50fSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlNhbXBsZXIucHJvdG90eXBlLnN5bmMgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdGhpcy5fc3luY01ldGhvZCgndHJpZ2dlckF0dGFjaycsIDEpO1xuXHQgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoJ3RyaWdnZXJSZWxlYXNlJywgMSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogSW52b2tlIHRoZSBhdHRhY2sgcGhhc2UsIHRoZW4gYWZ0ZXIgdGhlIGR1cmF0aW9uLCBpbnZva2UgdGhlIHJlbGVhc2UuXG5cdFx0ICogQHBhcmFtICB7RnJlcXVlbmN5fSBub3RlICAgICBUaGUgbm90ZSB0byBwbGF5XG5cdFx0ICogQHBhcmFtICB7VGltZX0gZHVyYXRpb24gVGhlIHRpbWUgdGhlIG5vdGUgc2hvdWxkIGJlIGhlbGRcblx0XHQgKiBAcGFyYW0gIHtUaW1lPX0gdGltZSAgICAgV2hlbiB0byBzdGFydCB0aGUgYXR0YWNrXG5cdFx0ICogQHBhcmFtICB7Tm9ybWFsUmFuZ2V9IFt2ZWxvY2l0eT0xXSBUaGUgdmVsb2NpdHkgb2YgdGhlIGF0dGFja1xuXHRcdCAqIEByZXR1cm4ge1RvbmUuU2FtcGxlcn0gICAgICAgICAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5TYW1wbGVyLnByb3RvdHlwZS50cmlnZ2VyQXR0YWNrUmVsZWFzZSA9IGZ1bmN0aW9uIChub3RlLCBkdXJhdGlvbiwgdGltZSwgdmVsb2NpdHkpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgZHVyYXRpb24gPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG5cdCAgICAgICAgdGhpcy50cmlnZ2VyQXR0YWNrKG5vdGUsIHRpbWUsIHZlbG9jaXR5KTtcblx0ICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKG5vdGUsIHRpbWUgKyBkdXJhdGlvbik7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEFkZCBhIG5vdGUgdG8gdGhlIHNhbXBsZXIuXG5cdFx0ICogIEBwYXJhbSAge05vdGV8TWlkaX0gICBub3RlICAgICAgVGhlIGJ1ZmZlcidzIHBpdGNoLlxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd8VG9uZS5CdWZmZXJ8QXVkaW9idWZmZXJ9ICB1cmwgIEVpdGhlciB0aGUgdXJsIG9mIHRoZSBidWZlcixcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvciBhIGJ1ZmZlciB3aGljaCB3aWxsIGJlIGFkZGVkXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCB0aGUgZ2l2ZW4gbmFtZS5cblx0XHQgKiAgQHBhcmFtICB7RnVuY3Rpb249fSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB0byBpbnZva2Vcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoZW4gdGhlIHVybCBpcyBsb2FkZWQuXG5cdFx0ICovXG5cdCAgICBUb25lLlNhbXBsZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChub3RlLCB1cmwsIGNhbGxiYWNrKSB7XG5cdCAgICAgICAgaWYgKFRvbmUuaXNOb3RlKG5vdGUpKSB7XG5cdCAgICAgICAgICAgIC8vY29udmVydCB0aGUgbm90ZSBuYW1lIHRvIE1JRElcblx0ICAgICAgICAgICAgdmFyIG1pZCA9IFRvbmUuRnJlcXVlbmN5KG5vdGUpLnRvTWlkaSgpO1xuXHQgICAgICAgICAgICB0aGlzLl9idWZmZXJzLmFkZChtaWQsIHVybCwgY2FsbGJhY2spO1xuXHQgICAgICAgIH0gZWxzZSBpZiAoIWlzTmFOKHBhcnNlRmxvYXQobm90ZSkpKSB7XG5cdCAgICAgICAgICAgIC8vb3RoZXJ3aXNlIGlmIGl0J3MgbnVtYmVycyBhc3N1bWUgaXQncyBtaWRpXG5cdCAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnMuYWRkKG5vdGUsIHVybCwgY2FsbGJhY2spO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVG9uZS5TYW1wbGVyOiBub3RlIG11c3QgYmUgdGhlIG5vdGVcXCdzIHBpdGNoLiBJbnN0ZWFkIGdvdCAnICsgbm90ZSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIElmIHRoZSBidWZmZXJzIGFyZSBsb2FkZWQgb3Igbm90XG5cdFx0ICogQG1lbWJlck9mIFRvbmUuU2FtcGxlciNcblx0XHQgKiBAdHlwZSB7Qm9vbGVhbn1cblx0XHQgKiBAbmFtZSBsb2FkZWRcblx0XHQgKiBAcmVhZE9ubHlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlNhbXBsZXIucHJvdG90eXBlLCAnbG9hZGVkJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVycy5sb2FkZWQ7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBDbGVhbiB1cFxuXHRcdCAqIEByZXR1cm4ge1RvbmUuU2FtcGxlcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5TYW1wbGVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuSW5zdHJ1bWVudC5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX2J1ZmZlcnMuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX2J1ZmZlcnMgPSBudWxsO1xuXHQgICAgICAgIGZvciAodmFyIG1pZGkgaW4gdGhpcy5fYWN0aXZlU291cmNlcykge1xuXHQgICAgICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzW21pZGldLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG5cdCAgICAgICAgICAgICAgICBldmVudC5zb3VyY2UuZGlzcG9zZSgpO1xuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcyA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuU2FtcGxlcjtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgaWYgKFRvbmUuc3VwcG9ydGVkKSB7XG5cdCAgICAgICAgaWYgKCFPc2NpbGxhdG9yTm9kZS5wcm90b3R5cGUuc2V0UGVyaW9kaWNXYXZlKSB7XG5cdCAgICAgICAgICAgIE9zY2lsbGF0b3JOb2RlLnByb3RvdHlwZS5zZXRQZXJpb2RpY1dhdmUgPSBPc2NpbGxhdG9yTm9kZS5wcm90b3R5cGUuc2V0V2F2ZVRhYmxlO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAoIUF1ZGlvQ29udGV4dC5wcm90b3R5cGUuY3JlYXRlUGVyaW9kaWNXYXZlKSB7XG5cdCAgICAgICAgICAgIEF1ZGlvQ29udGV4dC5wcm90b3R5cGUuY3JlYXRlUGVyaW9kaWNXYXZlID0gQXVkaW9Db250ZXh0LnByb3RvdHlwZS5jcmVhdGVXYXZlVGFibGU7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgTWFwcyBhIE5vcm1hbFJhbmdlIFswLCAxXSB0byBhbiBBdWRpb1JhbmdlIFstMSwgMV0uIFxuXHRcdCAqICAgICAgICAgU2VlIGFsc28gVG9uZS5BdWRpb1RvR2Fpbi4gXG5cdFx0ICpcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuU2lnbmFsQmFzZX1cblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogdmFyIGcyYSA9IG5ldyBUb25lLkdhaW5Ub0F1ZGlvKCk7XG5cdFx0ICovXG5cdCAgICBUb25lLkdhaW5Ub0F1ZGlvID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuU2lnbmFsQmFzZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEB0eXBlIHtXYXZlU2hhcGVyTm9kZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbm9ybSA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLldhdmVTaGFwZXIoZnVuY3Rpb24gKHgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIE1hdGguYWJzKHgpICogMiAtIDE7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5HYWluVG9BdWRpbywgVG9uZS5TaWduYWxCYXNlKTtcblx0ICAgIC8qKlxuXHRcdCAqICBjbGVhbiB1cFxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5HYWluVG9BdWRpb30gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5HYWluVG9BdWRpby5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9ub3JtLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9ub3JtID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5HYWluVG9BdWRpbztcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgXG5cdCAgICAvKipcblx0XHQgKiAgQGNsYXNzIE5vcm1hbGl6ZSB0YWtlcyBhbiBpbnB1dCBtaW4gYW5kIG1heCBhbmQgbWFwcyBpdCBsaW5lYXJseSB0byBOb3JtYWxSYW5nZSBbMCwxXVxuXHRcdCAqXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLlNpZ25hbEJhc2V9XG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAcGFyYW0ge251bWJlcn0gaW5wdXRNaW4gdGhlIG1pbiBpbnB1dCB2YWx1ZVxuXHRcdCAqICBAcGFyYW0ge251bWJlcn0gaW5wdXRNYXggdGhlIG1heCBpbnB1dCB2YWx1ZVxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBub3JtID0gbmV3IFRvbmUuTm9ybWFsaXplKDIsIDQpO1xuXHRcdCAqIHZhciBzaWcgPSBuZXcgVG9uZS5TaWduYWwoMykuY29ubmVjdChub3JtKTtcblx0XHQgKiAvL291dHB1dCBvZiBub3JtIGlzIDAuNS4gXG5cdFx0ICovXG5cdCAgICBUb25lLk5vcm1hbGl6ZSA9IGZ1bmN0aW9uIChpbnB1dE1pbiwgaW5wdXRNYXgpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICB0aGUgbWluIGlucHV0IHZhbHVlXG5cdFx0XHQgKiAgQHR5cGUge251bWJlcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5faW5wdXRNaW4gPSBUb25lLmRlZmF1bHRBcmcoaW5wdXRNaW4sIDApO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIHRoZSBtYXggaW5wdXQgdmFsdWVcblx0XHRcdCAqICBAdHlwZSB7bnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9pbnB1dE1heCA9IFRvbmUuZGVmYXVsdEFyZyhpbnB1dE1heCwgMSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgc3VidHJhY3QgdGhlIG1pbiBmcm9tIHRoZSBpbnB1dFxuXHRcdFx0ICogIEB0eXBlIHtUb25lLkFkZH1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3ViID0gdGhpcy5pbnB1dCA9IG5ldyBUb25lLkFkZCgwKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBkaXZpZGUgYnkgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgaW5wdXQgYW5kIG91dHB1dFxuXHRcdFx0ICogIEB0eXBlIHtUb25lLk11bHRpcGx5fVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9kaXYgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLk11bHRpcGx5KDEpO1xuXHQgICAgICAgIHRoaXMuX3N1Yi5jb25uZWN0KHRoaXMuX2Rpdik7XG5cdCAgICAgICAgdGhpcy5fc2V0UmFuZ2UoKTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLk5vcm1hbGl6ZSwgVG9uZS5TaWduYWxCYXNlKTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBtaW5pbXVtIHZhbHVlIHRoZSBpbnB1dCBzaWduYWwgd2lsbCByZWFjaC5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5Ob3JtYWxpemUjXG5cdFx0ICogQHR5cGUge251bWJlcn1cblx0XHQgKiBAbmFtZSBtaW5cblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLk5vcm1hbGl6ZS5wcm90b3R5cGUsICdtaW4nLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9pbnB1dE1pbjtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKG1pbikge1xuXHQgICAgICAgICAgICB0aGlzLl9pbnB1dE1pbiA9IG1pbjtcblx0ICAgICAgICAgICAgdGhpcy5fc2V0UmFuZ2UoKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBtYXhpbXVtIHZhbHVlIHRoZSBpbnB1dCBzaWduYWwgd2lsbCByZWFjaC5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5Ob3JtYWxpemUjXG5cdFx0ICogQHR5cGUge251bWJlcn1cblx0XHQgKiBAbmFtZSBtYXhcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLk5vcm1hbGl6ZS5wcm90b3R5cGUsICdtYXgnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9pbnB1dE1heDtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKG1heCkge1xuXHQgICAgICAgICAgICB0aGlzLl9pbnB1dE1heCA9IG1heDtcblx0ICAgICAgICAgICAgdGhpcy5fc2V0UmFuZ2UoKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBzZXQgdGhlIHZhbHVlc1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Ob3JtYWxpemUucHJvdG90eXBlLl9zZXRSYW5nZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB0aGlzLl9zdWIudmFsdWUgPSAtdGhpcy5faW5wdXRNaW47XG5cdCAgICAgICAgdGhpcy5fZGl2LnZhbHVlID0gMSAvICh0aGlzLl9pbnB1dE1heCAtIHRoaXMuX2lucHV0TWluKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgY2xlYW4gdXBcblx0XHQgKiAgQHJldHVybnMge1RvbmUuTm9ybWFsaXplfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLk5vcm1hbGl6ZS5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLlNpZ25hbEJhc2UucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9zdWIuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX3N1YiA9IG51bGw7XG5cdCAgICAgICAgdGhpcy5fZGl2LmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9kaXYgPSBudWxsO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIHJldHVybiBUb25lLk5vcm1hbGl6ZTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgLyoqXG5cdFx0ICogQGNsYXNzIFRvbmUuVHJhbnNwb3J0VGltZWxpbmVTaWduYWwgZXh0ZW5kcyBUb25lLlNpZ25hbCwgYnV0IGFkZHMgdGhlIGFiaWxpdHkgdG8gc3luY2hyb25pemUgdGhlIHNpZ25hbCB0byB0aGUgc2lnbmFsIHRvIHRoZSBUb25lLlRyYW5zcG9ydFxuXHRcdCAqIEBleHRlbmRzIHtUb25lLlNpZ25hbH1cblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0VGltZWxpbmVTaWduYWwgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgVG9uZS5TaWduYWwuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSByZWFsIHNpZ25hbCBvdXRwdXRcblx0XHRcdCAqIEB0eXBlIHtUb25lLlNpZ25hbH1cblx0XHRcdCAqIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX291dHB1dFNpZyA9IG5ldyBUb25lLlNpZ25hbCh0aGlzLl9pbml0aWFsVmFsdWUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogS2VlcCB0cmFjayBvZiB0aGUgbGFzdCB2YWx1ZS4gKHNtYWxsIG9wdGltaXphdGlvbilcblx0XHRcdCAqIEBwcml2YXRlXG5cdFx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbGFzdFZhbCA9IHRoaXMudmFsdWU7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBUaGUgZXZlbnQgaWQgb2YgdGhlIHRpY2sgdXBkYXRlIGxvb3Bcblx0XHRcdCAqIEBwcml2YXRlXG5cdFx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3luY2VkID0gVG9uZS5UcmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQodGhpcy5fb25UaWNrLmJpbmQodGhpcyksICcxaScpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogQSBib3VuZCB2ZXJzaW9uIG9mIHRoZSBhbmNob3IgdmFsdWUgbWV0aG9kc1xuXHRcdFx0ICogQHR5cGUge0Z1bmN0aW9ufVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2JpbmRBbmNob3JWYWx1ZSA9IHRoaXMuX2FuY2hvclZhbHVlLmJpbmQodGhpcyk7XG5cdCAgICAgICAgVG9uZS5UcmFuc3BvcnQub24oJ3N0YXJ0IHN0b3AgcGF1c2UnLCB0aGlzLl9iaW5kQW5jaG9yVmFsdWUpO1xuXHQgICAgICAgIHRoaXMuX2V2ZW50cy5tZW1vcnkgPSBJbmZpbml0eTtcblx0ICAgIH07XG5cdCAgICBUb25lLmV4dGVuZChUb25lLlRyYW5zcG9ydFRpbWVsaW5lU2lnbmFsLCBUb25lLlNpZ25hbCk7XG5cdCAgICAvKipcblx0XHQgKiBDYWxsYmFjayB3aGljaCBpcyBpbnZva2VkIGV2ZXJ5IHRpY2suXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKiBAcGFyYW0gIHtOdW1iZXJ9IHRpbWVcblx0XHQgKiBAcmV0dXJuIHtUb25lLlRyYW5zcG9ydFRpbWVsaW5lU2lnbmFsfSAgICAgIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0VGltZWxpbmVTaWduYWwucHJvdG90eXBlLl9vblRpY2sgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHZhciB2YWwgPSB0aGlzLmdldFZhbHVlQXRUaW1lKFRvbmUuVHJhbnNwb3J0LnNlY29uZHMpO1xuXHQgICAgICAgIGlmICh0aGlzLl9sYXN0VmFsICE9PSB2YWwpIHtcblx0ICAgICAgICAgICAgdGhpcy5fbGFzdFZhbCA9IHZhbDtcblx0ICAgICAgICAgICAgLy9hcHByb3hpbWF0ZSByYW1wIGN1cnZlcyB3aXRoIGxpbmVhciByYW1wc1xuXHQgICAgICAgICAgICB0aGlzLl9vdXRwdXRTaWcubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsLCB0aW1lKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogQW5jaG9yIHRoZSB2YWx1ZSBhdCB0aGUgc3RhcnQgYW5kIHN0b3Agb2YgdGhlIFRyYW5zcG9ydFxuXHRcdCAqIEBwYXJhbSAge051bWJlcn0gdGltZSBUaGUgdGltZSBvZiB0aGUgZXZlbnRcblx0XHQgKiBAcmV0dXJuIHtUb25lLlRyYW5zcG9ydFRpbWVsaW5lU2lnbmFsfSAgICAgIHRoaXNcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnRUaW1lbGluZVNpZ25hbC5wcm90b3R5cGUuX2FuY2hvclZhbHVlID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB2YXIgdmFsID0gdGhpcy5nZXRWYWx1ZUF0VGltZShUb25lLlRyYW5zcG9ydC5zZWNvbmRzKTtcblx0ICAgICAgICB0aGlzLl9sYXN0VmFsID0gdmFsO1xuXHQgICAgICAgIHRoaXMuX291dHB1dFNpZy5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSk7XG5cdCAgICAgICAgdGhpcy5fb3V0cHV0U2lnLnNldFZhbHVlQXRUaW1lKHZhbCwgdGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEdldCB0aGUgc2NoZWR1bGVkIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lLiBUaGlzIHdpbGxcblx0XHQgKiAgcmV0dXJuIHRoZSB1bmNvbnZlcnRlZCAocmF3KSB2YWx1ZS5cblx0XHQgKiAgQHBhcmFtICB7VHJhbnNwb3J0VGltZX0gIHRpbWUgIFRoZSB0aW1lIGluIHNlY29uZHMuXG5cdFx0ICogIEByZXR1cm4gIHtOdW1iZXJ9ICBUaGUgc2NoZWR1bGVkIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnRUaW1lbGluZVNpZ25hbC5wcm90b3R5cGUuZ2V0VmFsdWVBdFRpbWUgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRpbWUgPSBUb25lLlRyYW5zcG9ydFRpbWUodGltZSk7XG5cdCAgICAgICAgcmV0dXJuIFRvbmUuU2lnbmFsLnByb3RvdHlwZS5nZXRWYWx1ZUF0VGltZS5jYWxsKHRoaXMsIHRpbWUpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIFNldCB0aGUgb3V0cHV0IG9mIHRoZSBzaWduYWwgYXQgdGhlIGdpdmVuIHRpbWVcblx0XHQgKiBAcGFyYW0gIHtOdW1iZXJ9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGFuZ2UgdG8gYXQgdGhlIGdpdmVuIHRpbWVcblx0XHQgKiBAcGFyYW0gIHtUcmFuc3BvcnRUaW1lfSB0aW1lICBUaGUgdGltZSB0byBjaGFuZ2UgdGhlIHNpZ25hbFxuXHRcdCAqIEByZXR1cm4ge1RvbmUuVHJhbnNwb3J0VGltZWxpbmVTaWduYWx9ICAgICAgIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0VGltZWxpbmVTaWduYWwucHJvdG90eXBlLnNldFZhbHVlQXRUaW1lID0gZnVuY3Rpb24gKHZhbHVlLCB0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IFRvbmUuVHJhbnNwb3J0VGltZSh0aW1lKTtcblx0ICAgICAgICBUb25lLlNpZ25hbC5wcm90b3R5cGUuc2V0VmFsdWVBdFRpbWUuY2FsbCh0aGlzLCB2YWx1ZSwgdGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogTGluZWFyIHJhbXAgdG8gdGhlIGdpdmVuIHZhbHVlIGZyb20gdGhlIHByZXZpb3VzIHNjaGVkdWxlZCBwb2ludCB0byB0aGUgZ2l2ZW4gdmFsdWVcblx0XHQgKiBAcGFyYW0gIHtOdW1iZXJ9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGFuZ2UgdG8gYXQgdGhlIGdpdmVuIHRpbWVcblx0XHQgKiBAcGFyYW0gIHtUcmFuc3BvcnRUaW1lfSB0aW1lICBUaGUgdGltZSB0byBjaGFuZ2UgdGhlIHNpZ25hbFxuXHRcdCAqIEByZXR1cm4ge1RvbmUuVHJhbnNwb3J0VGltZWxpbmVTaWduYWx9ICAgICAgIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0VGltZWxpbmVTaWduYWwucHJvdG90eXBlLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lID0gZnVuY3Rpb24gKHZhbHVlLCB0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IFRvbmUuVHJhbnNwb3J0VGltZSh0aW1lKTtcblx0ICAgICAgICBUb25lLlNpZ25hbC5wcm90b3R5cGUubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUuY2FsbCh0aGlzLCB2YWx1ZSwgdGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogRXhwb25lbnRpYWwgcmFtcCB0byB0aGUgZ2l2ZW4gdmFsdWUgZnJvbSB0aGUgcHJldmlvdXMgc2NoZWR1bGVkIHBvaW50IHRvIHRoZSBnaXZlbiB2YWx1ZVxuXHRcdCAqIEBwYXJhbSAge051bWJlcn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoYW5nZSB0byBhdCB0aGUgZ2l2ZW4gdGltZVxuXHRcdCAqIEBwYXJhbSAge1RyYW5zcG9ydFRpbWV9IHRpbWUgIFRoZSB0aW1lIHRvIGNoYW5nZSB0aGUgc2lnbmFsXG5cdFx0ICogQHJldHVybiB7VG9uZS5UcmFuc3BvcnRUaW1lbGluZVNpZ25hbH0gICAgICAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnRUaW1lbGluZVNpZ25hbC5wcm90b3R5cGUuZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSA9IGZ1bmN0aW9uICh2YWx1ZSwgdGltZSkge1xuXHQgICAgICAgIHRpbWUgPSBUb25lLlRyYW5zcG9ydFRpbWUodGltZSk7XG5cdCAgICAgICAgVG9uZS5TaWduYWwucHJvdG90eXBlLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUuY2FsbCh0aGlzLCB2YWx1ZSwgdGltZSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFN0YXJ0IGV4cG9uZW50aWFsbHkgYXBwcm9hY2hpbmcgdGhlIHRhcmdldCB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZSB3aXRoXG5cdFx0ICogIGEgcmF0ZSBoYXZpbmcgdGhlIGdpdmVuIHRpbWUgY29uc3RhbnQuXG5cdFx0ICogIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuXHRcdCAqICBAcGFyYW0ge1RyYW5zcG9ydFRpbWV9IHN0YXJ0VGltZVxuXHRcdCAqICBAcGFyYW0ge251bWJlcn0gdGltZUNvbnN0YW50XG5cdFx0ICogQHJldHVybiB7VG9uZS5UcmFuc3BvcnRUaW1lbGluZVNpZ25hbH0gICAgICAgdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5UcmFuc3BvcnRUaW1lbGluZVNpZ25hbC5wcm90b3R5cGUuc2V0VGFyZ2V0QXRUaW1lID0gZnVuY3Rpb24gKHZhbHVlLCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkge1xuXHQgICAgICAgIHN0YXJ0VGltZSA9IFRvbmUuVHJhbnNwb3J0VGltZShzdGFydFRpbWUpO1xuXHQgICAgICAgIFRvbmUuU2lnbmFsLnByb3RvdHlwZS5zZXRUYXJnZXRBdFRpbWUuY2FsbCh0aGlzLCB2YWx1ZSwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDYW5jZWxzIGFsbCBzY2hlZHVsZWQgcGFyYW1ldGVyIGNoYW5nZXMgd2l0aCB0aW1lcyBncmVhdGVyIHRoYW4gb3Jcblx0XHQgKiAgZXF1YWwgdG8gc3RhcnRUaW1lLlxuXHRcdCAqICBAcGFyYW0gIHtUcmFuc3BvcnRUaW1lfSBzdGFydFRpbWVcblx0XHQgKiAgQHJldHVybnMge1RvbmUuUGFyYW19IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0VGltZWxpbmVTaWduYWwucHJvdG90eXBlLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyA9IGZ1bmN0aW9uIChzdGFydFRpbWUpIHtcblx0ICAgICAgICBzdGFydFRpbWUgPSBUb25lLlRyYW5zcG9ydFRpbWUoc3RhcnRUaW1lKTtcblx0ICAgICAgICBUb25lLlNpZ25hbC5wcm90b3R5cGUuY2FuY2VsU2NoZWR1bGVkVmFsdWVzLmNhbGwodGhpcywgc3RhcnRUaW1lKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgU2V0IGFuIGFycmF5IG9mIGFyYml0cmFyeSB2YWx1ZXMgc3RhcnRpbmcgYXQgdGhlIGdpdmVuIHRpbWUgZm9yIHRoZSBnaXZlbiBkdXJhdGlvbi5cblx0XHQgKiAgQHBhcmFtIHtGbG9hdDMyQXJyYXl9IHZhbHVlc1xuXHRcdCAqICBAcGFyYW0ge1RpbWV9IHN0YXJ0VGltZVxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IGR1cmF0aW9uXG5cdFx0ICogIEBwYXJhbSB7Tm9ybWFsUmFuZ2V9IFtzY2FsaW5nPTFdIElmIHRoZSB2YWx1ZXMgaW4gdGhlIGN1cnZlIHNob3VsZCBiZSBzY2FsZWQgYnkgc29tZSB2YWx1ZVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5TaWduYWx9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuVHJhbnNwb3J0VGltZWxpbmVTaWduYWwucHJvdG90eXBlLnNldFZhbHVlQ3VydmVBdFRpbWUgPSBmdW5jdGlvbiAodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nKSB7XG5cdCAgICAgICAgc3RhcnRUaW1lID0gVG9uZS5UcmFuc3BvcnRUaW1lKHN0YXJ0VGltZSk7XG5cdCAgICAgICAgZHVyYXRpb24gPSBUb25lLlRyYW5zcG9ydFRpbWUoZHVyYXRpb24pO1xuXHQgICAgICAgIFRvbmUuU2lnbmFsLnByb3RvdHlwZS5zZXRWYWx1ZUN1cnZlQXRUaW1lLmNhbGwodGhpcywgdmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgVGhpcyBpcyBzaW1pbGFyIHRvIFtjYW5jZWxTY2hlZHVsZWRWYWx1ZXNdKCNjYW5jZWxTY2hlZHVsZWRWYWx1ZXMpIGV4Y2VwdFxuXHRcdCAqICBpdCBob2xkcyB0aGUgYXV0b21hdGVkIHZhbHVlIGF0IHRpbWUgdW50aWwgdGhlIG5leHQgYXV0b21hdGVkIGV2ZW50LlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSB0aW1lXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlRyYW5zcG9ydFRpbWVsaW5lU2lnbmFsfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRyYW5zcG9ydFRpbWVsaW5lU2lnbmFsLnByb3RvdHlwZS5jYW5jZWxBbmRIb2xkQXRUaW1lID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICByZXR1cm4gVG9uZS5TaWduYWwucHJvdG90eXBlLmNhbmNlbEFuZEhvbGRBdFRpbWUuY2FsbCh0aGlzLCBUb25lLlRyYW5zcG9ydFRpbWUodGltZSkpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIERpc3Bvc2UgYW5kIGRpc2Nvbm5lY3Rcblx0XHQgKiBAcmV0dXJuIHtUb25lLlRyYW5zcG9ydFRpbWVsaW5lU2lnbmFsfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlRyYW5zcG9ydFRpbWVsaW5lU2lnbmFsLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuVHJhbnNwb3J0LmNsZWFyKHRoaXMuX3N5bmNlZCk7XG5cdCAgICAgICAgVG9uZS5UcmFuc3BvcnQub2ZmKCdzdGFydCBzdG9wIHBhdXNlJywgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuXHQgICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoMCk7XG5cdCAgICAgICAgVG9uZS5TaWduYWwucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl9vdXRwdXRTaWcuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuX291dHB1dFNpZyA9IG51bGw7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuVHJhbnNwb3J0VGltZWxpbmVTaWduYWw7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIC8qKlxuXHRcdCAqIEBjbGFzcyBUb25lLkdyYWluUGxheWVyIGltcGxlbWVudHMgW2dyYW51bGFyIHN5bnRoZXNpc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvR3JhbnVsYXJfc3ludGhlc2lzKS5cblx0XHQgKiAgICAgICAgR3JhbnVsYXIgU3ludGhlc2lzIGVuYWJsZXMgeW91IHRvIGFkanVzdCBwaXRjaCBhbmQgcGxheWJhY2sgcmF0ZSBpbmRlcGVuZGVudGx5LiBUaGUgZ3JhaW5TaXplIGlzIHRoZVxuXHRcdCAqICAgICAgICBhbW91bnQgb2YgdGltZSBlYWNoIHNtYWxsIGNodW5rIG9mIGF1ZGlvIGlzIHBsYXllZCBmb3IgYW5kIHRoZSBvdmVybGFwIGlzIHRoZVxuXHRcdCAqICAgICAgICBhbW91bnQgb2YgY3Jvc3NmYWRpbmcgdHJhbnNpdGlvbiB0aW1lIGJldHdlZW4gc3VjY2Vzc2l2ZSBncmFpbnMuXG5cdFx0ICogQGV4dGVuZHMge1RvbmUuU291cmNlfVxuXHRcdCAqIEBwYXJhbSB7U3RyaW5nfFRvbmUuQnVmZmVyfSB1cmxcdFRoZSB1cmwgdG8gbG9hZCwgb3IgdGhlIFRvbmUuQnVmZmVyIHRvIHBsYXkuXG5cdFx0ICogQHBhcmFtIHtGdW5jdGlvbj19IGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2UgYWZ0ZXIgdGhlIHVybCBpcyBsb2FkZWQuXG5cdFx0ICovXG5cdCAgICBUb25lLkdyYWluUGxheWVyID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgJ3VybCcsXG5cdCAgICAgICAgICAgICdvbmxvYWQnXG5cdCAgICAgICAgXSwgVG9uZS5HcmFpblBsYXllcik7XG5cdCAgICAgICAgVG9uZS5Tb3VyY2UuY2FsbCh0aGlzLCBvcHRpb25zKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgYXVkaW8gYnVmZmVyIGJlbG9uZ2luZyB0byB0aGUgcGxheWVyLlxuXHRcdFx0ICogIEB0eXBlICB7VG9uZS5CdWZmZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmJ1ZmZlciA9IG5ldyBUb25lLkJ1ZmZlcihvcHRpb25zLnVybCwgb3B0aW9ucy5vbmxvYWQpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIENyZWF0ZSBhIHJlcGVhdGluZyB0aWNrIHRvIHNjaGVkdWxlXG5cdFx0XHQgKiAgdGhlIGdyYWlucy5cblx0XHRcdCAqICBAdHlwZSAge1RvbmUuQ2xvY2t9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2Nsb2NrID0gbmV3IFRvbmUuQ2xvY2sodGhpcy5fdGljay5iaW5kKHRoaXMpLCBvcHRpb25zLmdyYWluU2l6ZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQHR5cGUgIHtOdW1iZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IDA7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQHR5cGUgIHtOdW1iZXJ9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2xvb3BFbmQgPSAwO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogQWxsIG9mIHRoZSBjdXJyZW50bHkgcGxheWluZyBCdWZmZXJTb3VyY2VzXG5cdFx0XHQgKiBAdHlwZSB7QXJyYXl9XG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcyA9IFtdO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIEB0eXBlICB7TnVtYmVyfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBAdHlwZSAge051bWJlcn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZ3JhaW5TaXplID0gb3B0aW9ucy5ncmFpblNpemU7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqICBAdHlwZSB7TnVtYmVyfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fb3ZlcmxhcCA9IG9wdGlvbnMub3ZlcmxhcDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBBZGp1c3QgdGhlIHBpdGNoIGluZGVwZW5kZW50bHkgb2YgdGhlIHBsYXliYWNrUmF0ZS5cblx0XHRcdCAqICBAdHlwZSAge0NlbnRzfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5kZXR1bmUgPSBvcHRpb25zLmRldHVuZTtcblx0ICAgICAgICAvL3NldHVwXG5cdCAgICAgICAgdGhpcy5vdmVybGFwID0gb3B0aW9ucy5vdmVybGFwO1xuXHQgICAgICAgIHRoaXMubG9vcCA9IG9wdGlvbnMubG9vcDtcblx0ICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuXHQgICAgICAgIHRoaXMuZ3JhaW5TaXplID0gb3B0aW9ucy5ncmFpblNpemU7XG5cdCAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBvcHRpb25zLmxvb3BTdGFydDtcblx0ICAgICAgICB0aGlzLmxvb3BFbmQgPSBvcHRpb25zLmxvb3BFbmQ7XG5cdCAgICAgICAgdGhpcy5yZXZlcnNlID0gb3B0aW9ucy5yZXZlcnNlO1xuXHQgICAgICAgIHRoaXMuX2Nsb2NrLm9uKCdzdG9wJywgdGhpcy5fb25zdG9wLmJpbmQodGhpcykpO1xuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuR3JhaW5QbGF5ZXIsIFRvbmUuU291cmNlKTtcblx0ICAgIC8qKlxuXHRcdCAqICB0aGUgZGVmYXVsdCBwYXJhbWV0ZXJzXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQGNvbnN0XG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLkdyYWluUGxheWVyLmRlZmF1bHRzID0ge1xuXHQgICAgICAgICdvbmxvYWQnOiBUb25lLm5vT3AsXG5cdCAgICAgICAgJ292ZXJsYXAnOiAwLjEsXG5cdCAgICAgICAgJ2dyYWluU2l6ZSc6IDAuMixcblx0ICAgICAgICAncGxheWJhY2tSYXRlJzogMSxcblx0ICAgICAgICAnZGV0dW5lJzogMCxcblx0ICAgICAgICAnbG9vcCc6IGZhbHNlLFxuXHQgICAgICAgICdsb29wU3RhcnQnOiAwLFxuXHQgICAgICAgICdsb29wRW5kJzogMCxcblx0ICAgICAgICAncmV2ZXJzZSc6IGZhbHNlXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFBsYXkgdGhlIGJ1ZmZlciBhdCB0aGUgZ2l2ZW4gc3RhcnRUaW1lLiBPcHRpb25hbGx5IGFkZCBhbiBvZmZzZXRcblx0XHQgKiAgYW5kL29yIGR1cmF0aW9uIHdoaWNoIHdpbGwgcGxheSB0aGUgYnVmZmVyIGZyb20gYSBwb3NpdGlvblxuXHRcdCAqICB3aXRoaW4gdGhlIGJ1ZmZlciBmb3IgdGhlIGdpdmVuIGR1cmF0aW9uLlxuXHRcdCAqXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IFtzdGFydFRpbWU9bm93XSBXaGVuIHRoZSBwbGF5ZXIgc2hvdWxkIHN0YXJ0LlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbb2Zmc2V0PTBdIFRoZSBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzYW1wbGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIHN0YXJ0IGF0LlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lPX0gZHVyYXRpb24gSG93IGxvbmcgdGhlIHNhbXBsZSBzaG91bGQgcGxheS4gSWYgbm8gZHVyYXRpb25cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgZ2l2ZW4sIGl0IHdpbGwgZGVmYXVsdCB0byB0aGUgZnVsbCBsZW5ndGhcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2YgdGhlIHNhbXBsZSAobWludXMgYW55IG9mZnNldClcblx0XHQgKiAgQHJldHVybnMge1RvbmUuR3JhaW5QbGF5ZXJ9IHRoaXNcblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuR3JhaW5QbGF5ZXIjXG5cdFx0ICogIEBtZXRob2Qgc3RhcnRcblx0XHQgKiAgQG5hbWUgc3RhcnRcblx0XHQgKi9cblx0ICAgIC8qKlxuXHRcdCAqICBJbnRlcm5hbCBzdGFydCBtZXRob2Rcblx0XHQgKiAgQHBhcmFtIHtUaW1lfSB0aW1lXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gb2Zmc2V0XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLkdyYWluUGxheWVyLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuXHQgICAgICAgIG9mZnNldCA9IFRvbmUuZGVmYXVsdEFyZyhvZmZzZXQsIDApO1xuXHQgICAgICAgIG9mZnNldCA9IHRoaXMudG9TZWNvbmRzKG9mZnNldCk7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIHRoaXMuX29mZnNldCA9IG9mZnNldDtcblx0ICAgICAgICB0aGlzLl9jbG9jay5zdGFydCh0aW1lKTtcblx0ICAgICAgICBpZiAoZHVyYXRpb24pIHtcblx0ICAgICAgICAgICAgdGhpcy5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbikpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgSW50ZXJuYWwgc3RhcnQgbWV0aG9kXG5cdFx0ICogIEBwYXJhbSB7VGltZX0gdGltZVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5HcmFpblBsYXllci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIHRoaXMuX2Nsb2NrLnN0b3AodGltZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogSW52b2tlZCB3aGVuIHRoZSBjbG9jayBpcyBzdG9wcGVkXG5cdFx0ICogQHBhcmFtICB7TnVtYmVyfSB0aW1lXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuR3JhaW5QbGF5ZXIucHJvdG90eXBlLl9vbnN0b3AgPSBmdW5jdGlvbiAodGltZSkge1xuXHQgICAgICAgIC8vc3RvcCB0aGUgcGxheWVyc1xuXHQgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChmdW5jdGlvbiAoc291cmNlKSB7XG5cdCAgICAgICAgICAgIHNvdXJjZS5zdG9wKHRpbWUsIDApO1xuXHQgICAgICAgIH0pO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBJbnZva2VkIG9uIGVhY2ggY2xvY2sgdGljay4gc2NoZWR1bGVkIGEgbmV3XG5cdFx0ICogIGdyYWluIGF0IHRoaXMgdGltZS5cblx0XHQgKiAgQHBhcmFtICB7VGltZX0gIHRpbWVcblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuR3JhaW5QbGF5ZXIucHJvdG90eXBlLl90aWNrID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB2YXIgZmFkZUluID0gdGhpcy5fb2Zmc2V0IDwgdGhpcy5fb3ZlcmxhcCA/IDAgOiB0aGlzLl9vdmVybGFwO1xuXHQgICAgICAgIHZhciBzb3VyY2UgPSBuZXcgVG9uZS5CdWZmZXJTb3VyY2Uoe1xuXHQgICAgICAgICAgICAnYnVmZmVyJzogdGhpcy5idWZmZXIsXG5cdCAgICAgICAgICAgICdmYWRlSW4nOiBmYWRlSW4sXG5cdCAgICAgICAgICAgICdmYWRlT3V0JzogdGhpcy5fb3ZlcmxhcCxcblx0ICAgICAgICAgICAgJ2xvb3AnOiB0aGlzLmxvb3AsXG5cdCAgICAgICAgICAgICdsb29wU3RhcnQnOiB0aGlzLl9sb29wU3RhcnQsXG5cdCAgICAgICAgICAgICdsb29wRW5kJzogdGhpcy5fbG9vcEVuZCxcblx0ICAgICAgICAgICAgJ3BsYXliYWNrUmF0ZSc6IFRvbmUuaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKHRoaXMuZGV0dW5lIC8gMTAwKVxuXHQgICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuXHQgICAgICAgIHNvdXJjZS5zdGFydCh0aW1lLCB0aGlzLl9vZmZzZXQpO1xuXHQgICAgICAgIHRoaXMuX29mZnNldCArPSB0aGlzLmdyYWluU2l6ZTtcblx0ICAgICAgICBzb3VyY2Uuc3RvcCh0aW1lICsgdGhpcy5ncmFpblNpemUpO1xuXHQgICAgICAgIC8vYWRkIGl0IHRvIHRoZSBhY3RpdmUgc291cmNlc1xuXHQgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMucHVzaChzb3VyY2UpO1xuXHQgICAgICAgIC8vcmVtb3ZlIGl0IHdoZW4gaXQncyBkb25lXG5cdCAgICAgICAgc291cmNlLm9uZW5kZWQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX2FjdGl2ZVNvdXJjZXMuaW5kZXhPZihzb3VyY2UpO1xuXHQgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLnNwbGljZShpbmRleCwgMSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LmJpbmQodGhpcyk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEp1bXAgdG8gYSBzcGVjaWZpYyB0aW1lIGFuZCBwbGF5IGl0LlxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSAgb2Zmc2V0ICBUaGUgb2Zmc2V0IHRvIGp1bXAgdG8uXG5cdFx0ICogIEBwYXJhbSB7VGltZT19IHRpbWUgV2hlbiB0byBtYWtlIHRoZSBqdW1wLlxuXHRcdCAqICBAcmV0dXJuICB7VG9uZS5HcmFpblBsYXllcn0gIHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuR3JhaW5QbGF5ZXIucHJvdG90eXBlLnNlZWsgPSBmdW5jdGlvbiAob2Zmc2V0LCB0aW1lKSB7XG5cdCAgICAgICAgdGhpcy5fb2Zmc2V0ID0gdGhpcy50b1NlY29uZHMob2Zmc2V0KTtcblx0ICAgICAgICB0aGlzLl90aWNrKHRoaXMudG9TZWNvbmRzKHRpbWUpKTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgc2FtcGxlXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuR3JhaW5QbGF5ZXIjXG5cdFx0ICogQHR5cGUge1Bvc2l0aXZlfVxuXHRcdCAqIEBuYW1lIHBsYXliYWNrUmF0ZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuR3JhaW5QbGF5ZXIucHJvdG90eXBlLCAncGxheWJhY2tSYXRlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocmF0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSByYXRlO1xuXHQgICAgICAgICAgICB0aGlzLmdyYWluU2l6ZSA9IHRoaXMuX2dyYWluU2l6ZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBsb29wIHN0YXJ0IHRpbWUuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuR3JhaW5QbGF5ZXIjXG5cdFx0ICogQHR5cGUge1RpbWV9XG5cdFx0ICogQG5hbWUgbG9vcFN0YXJ0XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5HcmFpblBsYXllci5wcm90b3R5cGUsICdsb29wU3RhcnQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb29wU3RhcnQ7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIGxvb3AgZW5kIHRpbWUuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuR3JhaW5QbGF5ZXIjXG5cdFx0ICogQHR5cGUge1RpbWV9XG5cdFx0ICogQG5hbWUgbG9vcEVuZFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuR3JhaW5QbGF5ZXIucHJvdG90eXBlLCAnbG9vcEVuZCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BFbmQ7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBkaXJlY3Rpb24gdGhlIGJ1ZmZlciBzaG91bGQgcGxheSBpblxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLkdyYWluUGxheWVyI1xuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBuYW1lIHJldmVyc2Vcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLkdyYWluUGxheWVyLnByb3RvdHlwZSwgJ3JldmVyc2UnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLmJ1ZmZlci5yZXZlcnNlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocmV2KSB7XG5cdCAgICAgICAgICAgIHRoaXMuYnVmZmVyLnJldmVyc2UgPSByZXY7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgc2l6ZSBvZiBlYWNoIGNodW5rIG9mIGF1ZGlvIHRoYXQgdGhlXG5cdFx0ICogYnVmZmVyIGlzIGNob3BwZWQgaW50byBhbmQgcGxheWVkIGJhY2sgYXQuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuR3JhaW5QbGF5ZXIjXG5cdFx0ICogQHR5cGUge1RpbWV9XG5cdFx0ICogQG5hbWUgZ3JhaW5TaXplXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5HcmFpblBsYXllci5wcm90b3R5cGUsICdncmFpblNpemUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9ncmFpblNpemU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChzaXplKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2dyYWluU2l6ZSA9IHRoaXMudG9TZWNvbmRzKHNpemUpO1xuXHQgICAgICAgICAgICB0aGlzLl9jbG9jay5mcmVxdWVuY3kudmFsdWUgPSB0aGlzLl9wbGF5YmFja1JhdGUgLyB0aGlzLl9ncmFpblNpemU7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGlzIGlzIHRoZSBkdXJhdGlvbiBvZiB0aGUgY3Jvc3MtZmFkZSBiZXR3ZWVuXG5cdFx0ICogc3VjZXNzaXZlIGdyYWlucy5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5HcmFpblBsYXllciNcblx0XHQgKiBAdHlwZSB7VGltZX1cblx0XHQgKiBAbmFtZSBvdmVybGFwXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5HcmFpblBsYXllci5wcm90b3R5cGUsICdvdmVybGFwJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fb3ZlcmxhcDtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fb3ZlcmxhcCA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogQ2xlYW4gdXBcblx0XHQgKiBAcmV0dXJuIHtUb25lLkdyYWluUGxheWVyfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLkdyYWluUGxheWVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIFRvbmUuU291cmNlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5idWZmZXIuZGlzcG9zZSgpO1xuXHQgICAgICAgIHRoaXMuYnVmZmVyID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9jbG9jay5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fY2xvY2sgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChmdW5jdGlvbiAoc291cmNlKSB7XG5cdCAgICAgICAgICAgIHNvdXJjZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcyA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuR3JhaW5QbGF5ZXI7XG5cdH0pO1xuXHRNb2R1bGUoZnVuY3Rpb24gKFRvbmUpIHtcblx0ICAgIFxuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyAgVG9uZS5QbGF5ZXIgaXMgYW4gYXVkaW8gZmlsZSBwbGF5ZXIgd2l0aCBzdGFydCwgbG9vcCwgYW5kIHN0b3AgZnVuY3Rpb25zLlxuXHRcdCAqXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5Tb3VyY2V9XG5cdFx0ICogIEBwYXJhbSB7c3RyaW5nfEF1ZGlvQnVmZmVyfSB1cmwgRWl0aGVyIHRoZSBBdWRpb0J1ZmZlciBvciB0aGUgdXJsIGZyb21cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaCB0byBsb2FkIHRoZSBBdWRpb0J1ZmZlclxuXHRcdCAqICBAcGFyYW0ge0Z1bmN0aW9uPX0gb25sb2FkIFRoZSBmdW5jdGlvbiB0byBpbnZva2Ugd2hlbiB0aGUgYnVmZmVyIGlzIGxvYWRlZC5cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWNvbW1lbmRlZCB0byB1c2UgVG9uZS5CdWZmZXIub24oJ2xvYWQnKSBpbnN0ZWFkLlxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIHZhciBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCIuL3BhdGgvdG8vc2FtcGxlLm1wM1wiKS50b01hc3RlcigpO1xuXHRcdCAqIC8vcGxheSBhcyBzb29uIGFzIHRoZSBidWZmZXIgaXMgbG9hZGVkXG5cdFx0ICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG5cdFx0ICovXG5cdCAgICBUb25lLlBsYXllciA9IGZ1bmN0aW9uICh1cmwpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucztcblx0ICAgICAgICBpZiAodXJsIGluc3RhbmNlb2YgVG9uZS5CdWZmZXIgJiYgdXJsLmxvYWRlZCkge1xuXHQgICAgICAgICAgICB1cmwgPSB1cmwuZ2V0KCk7XG5cdCAgICAgICAgICAgIG9wdGlvbnMgPSBUb25lLlBsYXllci5kZWZhdWx0cztcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBvcHRpb25zID0gVG9uZS5kZWZhdWx0cyhhcmd1bWVudHMsIFtcblx0ICAgICAgICAgICAgICAgICd1cmwnLFxuXHQgICAgICAgICAgICAgICAgJ29ubG9hZCdcblx0ICAgICAgICAgICAgXSwgVG9uZS5QbGF5ZXIpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBUb25lLlNvdXJjZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIElmIHRoZSBmaWxlIHNob3VsZCBwbGF5IGFzIHNvb25cblx0XHRcdCAqICBhcyB0aGUgYnVmZmVyIGlzIGxvYWRlZC5cblx0XHRcdCAqICBAdHlwZSB7Qm9vbGVhbn1cblx0XHRcdCAqICBAZXhhbXBsZVxuXHRcdFx0ICogLy93aWxsIHBsYXkgYXMgc29vbiBhcyBpdCdzIGxvYWRlZFxuXHRcdFx0ICogdmFyIHBsYXllciA9IG5ldyBUb25lLlBsYXllcih7XG5cdFx0XHQgKiBcdFwidXJsXCIgOiBcIi4vcGF0aC90by9zYW1wbGUubXAzXCIsXG5cdFx0XHQgKiBcdFwiYXV0b3N0YXJ0XCIgOiB0cnVlLFxuXHRcdFx0ICogfSkudG9NYXN0ZXIoKTtcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuYXV0b3N0YXJ0ID0gb3B0aW9ucy5hdXRvc3RhcnQ7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIGJ1ZmZlclxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKiAgQHR5cGUge1RvbmUuQnVmZmVyfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYnVmZmVyID0gbmV3IFRvbmUuQnVmZmVyKHtcblx0ICAgICAgICAgICAgJ3VybCc6IG9wdGlvbnMudXJsLFxuXHQgICAgICAgICAgICAnb25sb2FkJzogdGhpcy5fb25sb2FkLmJpbmQodGhpcywgb3B0aW9ucy5vbmxvYWQpLFxuXHQgICAgICAgICAgICAncmV2ZXJzZSc6IG9wdGlvbnMucmV2ZXJzZVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGlmICh1cmwgaW5zdGFuY2VvZiBBdWRpb0J1ZmZlcikge1xuXHQgICAgICAgICAgICB0aGlzLl9idWZmZXIuc2V0KHVybCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGlmIHRoZSBidWZmZXIgc2hvdWxkIGxvb3Agb25jZSBpdCdzIG92ZXJcblx0XHRcdCAqICBAdHlwZSB7Qm9vbGVhbn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fbG9vcCA9IG9wdGlvbnMubG9vcDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBpZiAnbG9vcCcgaXMgdHJ1ZSwgdGhlIGxvb3Agd2lsbCBzdGFydCBhdCB0aGlzIHBvc2l0aW9uXG5cdFx0XHQgKiAgQHR5cGUge1RpbWV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IG9wdGlvbnMubG9vcFN0YXJ0O1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIGlmICdsb29wJyBpcyB0cnVlLCB0aGUgbG9vcCB3aWxsIGVuZCBhdCB0aGlzIHBvc2l0aW9uXG5cdFx0XHQgKiAgQHR5cGUge1RpbWV9XG5cdFx0XHQgKiAgQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2xvb3BFbmQgPSBvcHRpb25zLmxvb3BFbmQ7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgdGhlIHBsYXliYWNrIHJhdGVcblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICogIEB0eXBlIHtOdW1iZXJ9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBBbGwgb2YgdGhlIGFjdGl2ZSBidWZmZXIgc291cmNlIG5vZGVzXG5cdFx0XHQgKiAgQHR5cGUge0FycmF5PFRvbmUuQnVmZmVyU291cmNlPn1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcyA9IFtdO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBlbGFwc2VkIHRpbWUgY291bnRlci5cblx0XHRcdCAqICBAdHlwZSB7VG9uZS5UaWNrU291cmNlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9lbGFwc2VkVGltZSA9IG5ldyBUb25lLlRpY2tTb3VyY2Uob3B0aW9ucy5wbGF5YmFja1JhdGUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBmYWRlSW4gdGltZSBvZiB0aGUgYW1wbGl0dWRlIGVudmVsb3BlLlxuXHRcdFx0ICogIEB0eXBlIHtUaW1lfVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5mYWRlSW4gPSBvcHRpb25zLmZhZGVJbjtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgZmFkZU91dCB0aW1lIG9mIHRoZSBhbXBsaXR1ZGUgZW52ZWxvcGUuXG5cdFx0XHQgKiAgQHR5cGUge1RpbWV9XG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLmZhZGVPdXQgPSBvcHRpb25zLmZhZGVPdXQ7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5QbGF5ZXIsIFRvbmUuU291cmNlKTtcblx0ICAgIC8qKlxuXHRcdCAqICB0aGUgZGVmYXVsdCBwYXJhbWV0ZXJzXG5cdFx0ICogIEBzdGF0aWNcblx0XHQgKiAgQGNvbnN0XG5cdFx0ICogIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdCAgICBUb25lLlBsYXllci5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAnb25sb2FkJzogVG9uZS5ub09wLFxuXHQgICAgICAgICdwbGF5YmFja1JhdGUnOiAxLFxuXHQgICAgICAgICdsb29wJzogZmFsc2UsXG5cdCAgICAgICAgJ2F1dG9zdGFydCc6IGZhbHNlLFxuXHQgICAgICAgICdsb29wU3RhcnQnOiAwLFxuXHQgICAgICAgICdsb29wRW5kJzogMCxcblx0ICAgICAgICAncmV0cmlnZ2VyJzogZmFsc2UsXG5cdCAgICAgICAgJ3JldmVyc2UnOiBmYWxzZSxcblx0ICAgICAgICAnZmFkZUluJzogMCxcblx0ICAgICAgICAnZmFkZU91dCc6IDBcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgTG9hZCB0aGUgYXVkaW8gZmlsZSBhcyBhbiBhdWRpbyBidWZmZXIuXG5cdFx0ICogIERlY29kZXMgdGhlIGF1ZGlvIGFzeW5jaHJvbm91c2x5IGFuZCBpbnZva2VzXG5cdFx0ICogIHRoZSBjYWxsYmFjayBvbmNlIHRoZSBhdWRpbyBidWZmZXIgbG9hZHMuXG5cdFx0ICogIE5vdGU6IHRoaXMgZG9lcyBub3QgbmVlZCB0byBiZSBjYWxsZWQgaWYgYSB1cmxcblx0XHQgKiAgd2FzIHBhc3NlZCBpbiB0byB0aGUgY29uc3RydWN0b3IuIE9ubHkgdXNlIHRoaXNcblx0XHQgKiAgaWYgeW91IHdhbnQgdG8gbWFudWFsbHkgbG9hZCBhIG5ldyB1cmwuXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IHVybCBUaGUgdXJsIG9mIHRoZSBidWZmZXIgdG8gbG9hZC5cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgIEZpbGV0eXBlIHN1cHBvcnQgZGVwZW5kcyBvbiB0aGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgIGJyb3dzZXIuXG5cdFx0ICogIEBwYXJhbSAge0Z1bmN0aW9uPX0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIGludm9rZSBvbmNlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHNhbXBsZSBpcyBsb2FkZWQuXG5cdFx0ICogIEByZXR1cm5zIHtQcm9taXNlfVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QbGF5ZXIucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAodXJsLCBjYWxsYmFjaykge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIubG9hZCh1cmwsIHRoaXMuX29ubG9hZC5iaW5kKHRoaXMsIGNhbGxiYWNrKSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogSW50ZXJuYWwgY2FsbGJhY2sgd2hlbiB0aGUgYnVmZmVyIGlzIGxvYWRlZC5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QbGF5ZXIucHJvdG90eXBlLl9vbmxvYWQgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcblx0ICAgICAgICBjYWxsYmFjayA9IFRvbmUuZGVmYXVsdEFyZyhjYWxsYmFjaywgVG9uZS5ub09wKTtcblx0ICAgICAgICBjYWxsYmFjayh0aGlzKTtcblx0ICAgICAgICBpZiAodGhpcy5hdXRvc3RhcnQpIHtcblx0ICAgICAgICAgICAgdGhpcy5zdGFydCgpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBJbnRlcm5hbCBjYWxsYmFjayB3aGVuIHRoZSBidWZmZXIgaXMgZG9uZSBwbGF5aW5nLlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlBsYXllci5wcm90b3R5cGUuX29uU291cmNlRW5kID0gZnVuY3Rpb24gKHNvdXJjZSkge1xuXHQgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX2FjdGl2ZVNvdXJjZXMuaW5kZXhPZihzb3VyY2UpO1xuXHQgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuc3BsaWNlKGluZGV4LCAxKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUGxheSB0aGUgYnVmZmVyIGF0IHRoZSBnaXZlbiBzdGFydFRpbWUuIE9wdGlvbmFsbHkgYWRkIGFuIG9mZnNldFxuXHRcdCAqICBhbmQvb3IgZHVyYXRpb24gd2hpY2ggd2lsbCBwbGF5IHRoZSBidWZmZXIgZnJvbSBhIHBvc2l0aW9uXG5cdFx0ICogIHdpdGhpbiB0aGUgYnVmZmVyIGZvciB0aGUgZ2l2ZW4gZHVyYXRpb24uXG5cdFx0ICpcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gW3N0YXJ0VGltZT1ub3ddIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IFtvZmZzZXQ9MF0gVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gc3RhcnQgYXQuXG5cdFx0ICogIEBwYXJhbSAge1RpbWU9fSBkdXJhdGlvbiBIb3cgbG9uZyB0aGUgc2FtcGxlIHNob3VsZCBwbGF5LiBJZiBubyBkdXJhdGlvblxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBnaXZlbiwgaXQgd2lsbCBkZWZhdWx0IHRvIHRoZSBmdWxsIGxlbmd0aFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZiB0aGUgc2FtcGxlIChtaW51cyBhbnkgb2Zmc2V0KVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5QbGF5ZXJ9IHRoaXNcblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuUGxheWVyI1xuXHRcdCAqICBAbWV0aG9kIHN0YXJ0XG5cdFx0ICogIEBuYW1lIHN0YXJ0XG5cdFx0ICovXG5cdCAgICAvKipcblx0XHQgKiAgSW50ZXJuYWwgc3RhcnQgbWV0aG9kXG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlBsYXllci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKHN0YXJ0VGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuXHQgICAgICAgIC8vaWYgaXQncyBhIGxvb3AgdGhlIGRlZmF1bHQgb2Zmc2V0IGlzIHRoZSBsb29wc3RhcnQgcG9pbnRcblx0ICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuXHQgICAgICAgICAgICBvZmZzZXQgPSBUb25lLmRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLl9sb29wU3RhcnQpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIC8vb3RoZXJ3aXNlIHRoZSBkZWZhdWx0IG9mZnNldCBpcyAwXG5cdCAgICAgICAgICAgIG9mZnNldCA9IFRvbmUuZGVmYXVsdEFyZyhvZmZzZXQsIDApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL2NvbXB1dGUgdGhlIHZhbHVlcyBpbiBzZWNvbmRzXG5cdCAgICAgICAgb2Zmc2V0ID0gdGhpcy50b1NlY29uZHMob2Zmc2V0KTtcblx0ICAgICAgICB2YXIgY29tcHV0ZWREdXJhdGlvbiA9IFRvbmUuZGVmYXVsdEFyZyhkdXJhdGlvbiwgTWF0aC5tYXgodGhpcy5fYnVmZmVyLmR1cmF0aW9uIC0gb2Zmc2V0LCAwKSk7XG5cdCAgICAgICAgY29tcHV0ZWREdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGNvbXB1dGVkRHVyYXRpb24pO1xuXHQgICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG5cdCAgICAgICAgLy9zdGFydCB0aGUgZWxhcHNlZCB0aW1lIGNvdW50ZXJcblx0ICAgICAgICB0aGlzLl9lbGFwc2VkVGltZS5zdGFydChzdGFydFRpbWUsIG9mZnNldCk7XG5cdCAgICAgICAgLy9tYWtlIHRoZSBzb3VyY2Vcblx0ICAgICAgICB2YXIgc291cmNlID0gbmV3IFRvbmUuQnVmZmVyU291cmNlKHtcblx0ICAgICAgICAgICAgJ2J1ZmZlcic6IHRoaXMuX2J1ZmZlcixcblx0ICAgICAgICAgICAgJ2xvb3AnOiB0aGlzLl9sb29wLFxuXHQgICAgICAgICAgICAnbG9vcFN0YXJ0JzogdGhpcy5fbG9vcFN0YXJ0LFxuXHQgICAgICAgICAgICAnbG9vcEVuZCc6IHRoaXMuX2xvb3BFbmQsXG5cdCAgICAgICAgICAgICdvbmVuZGVkJzogdGhpcy5fb25Tb3VyY2VFbmQuYmluZCh0aGlzKSxcblx0ICAgICAgICAgICAgJ3BsYXliYWNrUmF0ZSc6IHRoaXMuX3BsYXliYWNrUmF0ZSxcblx0ICAgICAgICAgICAgJ2ZhZGVJbic6IHRoaXMuZmFkZUluLFxuXHQgICAgICAgICAgICAnZmFkZU91dCc6IHRoaXMuZmFkZU91dFxuXHQgICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuXHQgICAgICAgIC8vc2V0IHRoZSBsb29waW5nIHByb3BlcnRpZXNcblx0ICAgICAgICBpZiAoIXRoaXMuX2xvb3AgJiYgIXRoaXMuX3N5bmNlZCkge1xuXHQgICAgICAgICAgICAvL2lmIGl0J3Mgbm90IGxvb3BpbmcsIHNldCB0aGUgc3RhdGUgY2hhbmdlIGF0IHRoZSBlbmQgb2YgdGhlIHNhbXBsZVxuXHQgICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShUb25lLlN0YXRlLlN0b3BwZWQsIHN0YXJ0VGltZSArIGNvbXB1dGVkRHVyYXRpb24gLyB0aGlzLl9wbGF5YmFja1JhdGUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvL2FkZCBpdCB0byB0aGUgYXJyYXkgb2YgYWN0aXZlIHNvdXJjZXNcblx0ICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLnB1c2goc291cmNlKTtcblx0ICAgICAgICAvL3N0YXJ0IGl0XG5cdCAgICAgICAgaWYgKHRoaXMuX2xvb3AgJiYgVG9uZS5pc1VuZGVmKGR1cmF0aW9uKSkge1xuXHQgICAgICAgICAgICBzb3VyY2Uuc3RhcnQoc3RhcnRUaW1lLCBvZmZzZXQpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHNvdXJjZS5zdGFydChzdGFydFRpbWUsIG9mZnNldCwgY29tcHV0ZWREdXJhdGlvbik7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTdG9wIHBsYXliYWNrLlxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqICBAcGFyYW0gIHtUaW1lfSBbdGltZT1ub3ddXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBsYXllcn0gdGhpc1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QbGF5ZXIucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKHRpbWUpIHtcblx0ICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG5cdCAgICAgICAgdGhpcy5fZWxhcHNlZFRpbWUuc3RvcCh0aW1lKTtcblx0ICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goZnVuY3Rpb24gKHNvdXJjZSkge1xuXHQgICAgICAgICAgICBzb3VyY2Uuc3RvcCh0aW1lKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBTdG9wIGFuZCB0aGVuIHJlc3RhcnQgdGhlIHBsYXllciBmcm9tIHRoZSBiZWdpbm5pbmcgKG9yIG9mZnNldClcblx0XHQgKiAgQHBhcmFtICB7VGltZX0gW3N0YXJ0VGltZT1ub3ddIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG5cdFx0ICogIEBwYXJhbSAge1RpbWV9IFtvZmZzZXQ9MF0gVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZVxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gc3RhcnQgYXQuXG5cdFx0ICogIEBwYXJhbSAge1RpbWU9fSBkdXJhdGlvbiBIb3cgbG9uZyB0aGUgc2FtcGxlIHNob3VsZCBwbGF5LiBJZiBubyBkdXJhdGlvblxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBnaXZlbiwgaXQgd2lsbCBkZWZhdWx0IHRvIHRoZSBmdWxsIGxlbmd0aFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZiB0aGUgc2FtcGxlIChtaW51cyBhbnkgb2Zmc2V0KVxuXHRcdCAqICBAcmV0dXJucyB7VG9uZS5QbGF5ZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGxheWVyLnByb3RvdHlwZS5yZXN0YXJ0ID0gZnVuY3Rpb24gKHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcblx0ICAgICAgICB0aGlzLl9zdG9wKHRpbWUpO1xuXHQgICAgICAgIHRoaXMuX3N0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTZWVrIHRvIGEgc3BlY2lmaWMgdGltZSBpbiB0aGUgcGxheWVyJ3MgYnVmZmVyLiBJZiB0aGVcblx0XHQgKiAgc291cmNlIGlzIG5vIGxvbmdlciBwbGF5aW5nIGF0IHRoYXQgdGltZSwgaXQgd2lsbCBzdG9wLlxuXHRcdCAqICBJZiB5b3Ugc2VlayB0byBhIHRpbWUgdGhhdFxuXHRcdCAqICBAcGFyYW0ge1RpbWV9IG9mZnNldCBUaGUgdGltZSB0byBzZWVrIHRvLlxuXHRcdCAqICBAcGFyYW0ge1RpbWU9fSB0aW1lIFRoZSB0aW1lIGZvciB0aGUgc2VlayBldmVudCB0byBvY2N1ci5cblx0XHQgKiAgQHJldHVybiB7VG9uZS5QbGF5ZXJ9IHRoaXNcblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBzb3VyY2Uuc3RhcnQoMC4yKTtcblx0XHQgKiBzb3VyY2Uuc3RvcCgwLjQpO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QbGF5ZXIucHJvdG90eXBlLnNlZWsgPSBmdW5jdGlvbiAob2Zmc2V0LCB0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuXHQgICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aW1lKSA9PT0gVG9uZS5TdGF0ZS5TdGFydGVkKSB7XG5cdCAgICAgICAgICAgIG9mZnNldCA9IHRoaXMudG9TZWNvbmRzKG9mZnNldCk7XG5cdCAgICAgICAgICAgIC8vIGlmIGl0J3MgY3VycmVudGx5IHBsYXlpbmcsIHN0b3AgaXRcblx0ICAgICAgICAgICAgdGhpcy5fc3RvcCh0aW1lKTtcblx0ICAgICAgICAgICAgLy9yZXN0YXJ0IGl0IGF0IHRoZSBnaXZlbiB0aW1lXG5cdCAgICAgICAgICAgIHRoaXMuX3N0YXJ0KHRpbWUsIG9mZnNldCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBTZXQgdGhlIGxvb3Agc3RhcnQgYW5kIGVuZC4gV2lsbCBvbmx5IGxvb3AgaWYgbG9vcCBpc1xuXHRcdCAqICBzZXQgdG8gdHJ1ZS5cblx0XHQgKiAgQHBhcmFtIHtUaW1lfSBsb29wU3RhcnQgVGhlIGxvb3AgZW5kIHRpbWVcblx0XHQgKiAgQHBhcmFtIHtUaW1lfSBsb29wRW5kIFRoZSBsb29wIGVuZCB0aW1lXG5cdFx0ICogIEByZXR1cm5zIHtUb25lLlBsYXllcn0gdGhpc1xuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIC8vbG9vcCAwLjEgc2Vjb25kcyBvZiB0aGUgZmlsZS5cblx0XHQgKiBwbGF5ZXIuc2V0TG9vcFBvaW50cygwLjIsIDAuMyk7XG5cdFx0ICogcGxheWVyLmxvb3AgPSB0cnVlO1xuXHRcdCAqL1xuXHQgICAgVG9uZS5QbGF5ZXIucHJvdG90eXBlLnNldExvb3BQb2ludHMgPSBmdW5jdGlvbiAobG9vcFN0YXJ0LCBsb29wRW5kKSB7XG5cdCAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBsb29wU3RhcnQ7XG5cdCAgICAgICAgdGhpcy5sb29wRW5kID0gbG9vcEVuZDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBJZiBsb29wIGlzIHRydWUsIHRoZSBsb29wIHdpbGwgc3RhcnQgYXQgdGhpcyBwb3NpdGlvbi5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5QbGF5ZXIjXG5cdFx0ICogQHR5cGUge1RpbWV9XG5cdFx0ICogQG5hbWUgbG9vcFN0YXJ0XG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QbGF5ZXIucHJvdG90eXBlLCAnbG9vcFN0YXJ0Jywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9vcFN0YXJ0O1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobG9vcFN0YXJ0KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IGxvb3BTdGFydDtcblx0ICAgICAgICAgICAgLy9nZXQgdGhlIGN1cnJlbnQgc291cmNlXG5cdCAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChmdW5jdGlvbiAoc291cmNlKSB7XG5cdCAgICAgICAgICAgICAgICBzb3VyY2UubG9vcFN0YXJ0ID0gbG9vcFN0YXJ0O1xuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIElmIGxvb3AgaXMgdHJ1ZSwgdGhlIGxvb3Agd2lsbCBlbmQgYXQgdGhpcyBwb3NpdGlvbi5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5QbGF5ZXIjXG5cdFx0ICogQHR5cGUge1RpbWV9XG5cdFx0ICogQG5hbWUgbG9vcEVuZFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGxheWVyLnByb3RvdHlwZSwgJ2xvb3BFbmQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb29wRW5kO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobG9vcEVuZCkge1xuXHQgICAgICAgICAgICB0aGlzLl9sb29wRW5kID0gbG9vcEVuZDtcblx0ICAgICAgICAgICAgLy9nZXQgdGhlIGN1cnJlbnQgc291cmNlXG5cdCAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChmdW5jdGlvbiAoc291cmNlKSB7XG5cdCAgICAgICAgICAgICAgICBzb3VyY2UubG9vcEVuZCA9IGxvb3BFbmQ7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIGF1ZGlvIGJ1ZmZlciBiZWxvbmdpbmcgdG8gdGhlIHBsYXllci5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5QbGF5ZXIjXG5cdFx0ICogQHR5cGUge1RvbmUuQnVmZmVyfVxuXHRcdCAqIEBuYW1lIGJ1ZmZlclxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGxheWVyLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGJ1ZmZlcikge1xuXHQgICAgICAgICAgICB0aGlzLl9idWZmZXIuc2V0KGJ1ZmZlcik7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBJZiB0aGUgYnVmZmVyIHNob3VsZCBsb29wIG9uY2UgaXQncyBvdmVyLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlBsYXllciNcblx0XHQgKiBAdHlwZSB7Qm9vbGVhbn1cblx0XHQgKiBAbmFtZSBsb29wXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QbGF5ZXIucHJvdG90eXBlLCAnbG9vcCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3A7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChsb29wKSB7XG5cdCAgICAgICAgICAgIC8vaWYgbm8gY2hhbmdlLCBkbyBub3RoaW5nXG5cdCAgICAgICAgICAgIGlmICh0aGlzLl9sb29wID09PSBsb29wKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm47XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5fbG9vcCA9IGxvb3A7XG5cdCAgICAgICAgICAgIHZhciBub3cgPSB0aGlzLm5vdygpO1xuXHQgICAgICAgICAgICBpZiAoIWxvb3ApIHtcblx0ICAgICAgICAgICAgICAgIC8vc3RvcCB0aGUgcGxheWJhY2sgb24gdGhlIG5leHQgY3ljbGVcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3N0b3BBdE5leHRJdGVyYXRpb24obm93KTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIC8vcmVtb3ZlIHRoZSBuZXh0IHN0b3BFdmVudFxuXHQgICAgICAgICAgICAgICAgdmFyIHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldE5leHRTdGF0ZShUb25lLlN0YXRlLlN0b3BwZWQsIG5vdyk7XG5cdCAgICAgICAgICAgICAgICBpZiAoc3RvcEV2ZW50KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKGZ1bmN0aW9uIChzb3VyY2UpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLmxvb3AgPSBsb29wO1xuXHQgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChzdG9wRXZlbnQudGltZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fZWxhcHNlZFRpbWUuY2FuY2VsKHN0b3BFdmVudC50aW1lKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIFNjaGVkdWxlcyBhIHN0b3AgZXZlbnQgYXQgdGhlIG5leHQgZnVsbCBpdGVyYXRpb24uIFVzZWRcblx0XHQgKiAgZm9yIHNjaGVkdWxpbmcgc3RvcCB3aGVuIHRoZSBsb29wIHN0YXRlIG9yIHBsYXliYWNrUmF0ZSBjaGFuZ2VzXG5cdFx0ICogIEBwYXJhbSAge051bWJlcn0gIG5vdyAgVGhlIGN1cnJlbnQgdGltZVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QbGF5ZXIucHJvdG90eXBlLl9zdG9wQXROZXh0SXRlcmF0aW9uID0gZnVuY3Rpb24gKG5vdykge1xuXHQgICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShub3cpID09PSBUb25lLlN0YXRlLlN0YXJ0ZWQpIHtcblx0ICAgICAgICAgICAgdmFyIG5leHRTdG9wID0gdGhpcy5fc3RhdGUuZ2V0TmV4dFN0YXRlKFRvbmUuU3RhdGUuU3RvcHBlZCwgbm93KTtcblx0ICAgICAgICAgICAgdmFyIHBvc2l0aW9uID0gdGhpcy5fZWxhcHNlZFRpbWUuZ2V0VGlja3NBdFRpbWUobm93KTtcblx0ICAgICAgICAgICAgdmFyIGl0ZXJhdGlvbnMgPSBNYXRoLm1heChNYXRoLmNlaWwocG9zaXRpb24gLyB0aGlzLmJ1ZmZlci5kdXJhdGlvbiksIDEpO1xuXHQgICAgICAgICAgICB2YXIgc3RvcFRpbWUgPSB0aGlzLl9lbGFwc2VkVGltZS5nZXRUaW1lT2ZUaWNrKGl0ZXJhdGlvbnMgKiB0aGlzLmJ1ZmZlci5kdXJhdGlvbiwgbmV4dFN0b3AgPyBuZXh0U3RvcC50aW1lIC0gdGhpcy5zYW1wbGVUaW1lIDogSW5maW5pdHkpO1xuXHQgICAgICAgICAgICB0aGlzLnN0b3Aoc3RvcFRpbWUpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBUaGUgcGxheWJhY2sgc3BlZWQuIDEgaXMgbm9ybWFsIHNwZWVkLiBUaGlzIGlzIG5vdCBhIHNpZ25hbCBiZWNhdXNlXG5cdFx0ICogU2FmYXJpIGFuZCBpT1MgY3VycmVudGx5IGRvbid0IHN1cHBvcnQgcGxheWJhY2tSYXRlIGFzIGEgc2lnbmFsLlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlBsYXllciNcblx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdCAqIEBuYW1lIHBsYXliYWNrUmF0ZVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGxheWVyLnByb3RvdHlwZSwgJ3BsYXliYWNrUmF0ZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKHJhdGUpIHtcblx0ICAgICAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcblx0ICAgICAgICAgICAgdmFyIG5vdyA9IHRoaXMubm93KCk7XG5cdCAgICAgICAgICAgIHRoaXMuX2VsYXBzZWRUaW1lLmZyZXF1ZW5jeS5zZXRWYWx1ZUF0VGltZShyYXRlLCBub3cpO1xuXHQgICAgICAgICAgICAvL2lmIGl0J3Mgbm90IGxvb3Bpbmdcblx0ICAgICAgICAgICAgaWYgKCF0aGlzLl9sb29wKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9zdG9wQXROZXh0SXRlcmF0aW9uKG5vdyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgLy9zZXQgYWxsIHRoZSBzb3VyY2VzXG5cdCAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChmdW5jdGlvbiAoc291cmNlKSB7XG5cdCAgICAgICAgICAgICAgICBzb3VyY2UucGxheWJhY2tSYXRlLnNldFZhbHVlQXRUaW1lKHJhdGUsIG5vdyk7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIGN1cnJlbnQgcGxheWJhY2sgcG9zaXRpb24gb2YgdGhlIGJ1ZmZlci4gXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuUGxheWVyI1xuXHRcdCAqIEB0eXBlIHtOdW1iZXJ9XG5cdFx0ICogQG5hbWUgcG9zaXRpb25cblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBsYXllci5wcm90b3R5cGUsICdwb3NpdGlvbicsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIG5vdyA9IHRoaXMubm93KCk7XG5cdCAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShub3cpID09PSBUb25lLlN0YXRlLlN0YXJ0ZWQgJiYgdGhpcy5sb2FkZWQpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBkdXJhdGlvbiA9IHRoaXMuYnVmZmVyLmR1cmF0aW9uO1xuXHQgICAgICAgICAgICAgICAgdmFyIHBvc2l0aW9uID0gdGhpcy5fZWxhcHNlZFRpbWUuZ2V0VGlja3NBdFRpbWUobm93KTtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvbiAlIGR1cmF0aW9uO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFRoZSBkaXJlY3Rpb24gdGhlIGJ1ZmZlciBzaG91bGQgcGxheSBpblxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlBsYXllciNcblx0XHQgKiBAdHlwZSB7Qm9vbGVhbn1cblx0XHQgKiBAbmFtZSByZXZlcnNlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QbGF5ZXIucHJvdG90eXBlLCAncmV2ZXJzZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5yZXZlcnNlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAocmV2KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5yZXZlcnNlID0gcmV2O1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogSWYgYWxsIHRoZSBidWZmZXIgaXMgbG9hZGVkXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuUGxheWVyI1xuXHRcdCAqIEB0eXBlIHtCb29sZWFufVxuXHRcdCAqIEBuYW1lIGxvYWRlZFxuXHRcdCAqIEByZWFkT25seVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGxheWVyLnByb3RvdHlwZSwgJ2xvYWRlZCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5sb2FkZWQ7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiAgRGlzcG9zZSBhbmQgZGlzY29ubmVjdC5cblx0XHQgKiAgQHJldHVybiB7VG9uZS5QbGF5ZXJ9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGxheWVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIC8vZGlzY29ubmVjdCBhbGwgb2YgdGhlIHBsYXllcnNcblx0ICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goZnVuY3Rpb24gKHNvdXJjZSkge1xuXHQgICAgICAgICAgICBzb3VyY2UuZGlzcG9zZSgpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMgPSBudWxsO1xuXHQgICAgICAgIFRvbmUuU291cmNlLnByb3RvdHlwZS5kaXNwb3NlLmNhbGwodGhpcyk7XG5cdCAgICAgICAgdGhpcy5fYnVmZmVyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9idWZmZXIgPSBudWxsO1xuXHQgICAgICAgIHRoaXMuX2VsYXBzZWRUaW1lLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl9lbGFwc2VkVGltZSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgcmV0dXJuIFRvbmUuUGxheWVyO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIFRvbmUuUGxheWVycyBjb21iaW5lcyBtdWx0aXBsZSBbVG9uZS5QbGF5ZXJdKFBsYXllcikgb2JqZWN0cy5cblx0XHQgKlxuXHRcdCAqICBAY29uc3RydWN0b3Jcblx0XHQgKiAgQGV4dGVuZHMge1RvbmUuQXVkaW9Ob2RlfVxuXHRcdCAqICBAcGFyYW0ge09iamVjdH0gdXJscyBBbiBvYmplY3QgbWFwcGluZyBhIG5hbWUgdG8gYSB1cmwuXG5cdFx0ICogIEBwYXJhbSB7ZnVuY3Rpb249fSBvbmxvYWQgVGhlIGZ1bmN0aW9uIHRvIGludm9rZSB3aGVuIGFsbCBidWZmZXJzIGFyZSBsb2FkZWQuXG5cdFx0ICovXG5cdCAgICBUb25lLlBsYXllcnMgPSBmdW5jdGlvbiAodXJscykge1xuXHQgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblx0ICAgICAgICBhcmdzLnNoaWZ0KCk7XG5cdCAgICAgICAgdmFyIG9wdGlvbnMgPSBUb25lLmRlZmF1bHRzKGFyZ3MsIFsnb25sb2FkJ10sIFRvbmUuUGxheWVycyk7XG5cdCAgICAgICAgVG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogIFRoZSBvdXRwdXQgdm9sdW1lIG5vZGVcblx0XHRcdCAqICBAdHlwZSAge1RvbmUuVm9sdW1lfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl92b2x1bWUgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lLlZvbHVtZShvcHRpb25zLnZvbHVtZSk7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBUaGUgdm9sdW1lIG9mIHRoZSBvdXRwdXQgaW4gZGVjaWJlbHMuXG5cdFx0XHQgKiBAdHlwZSB7RGVjaWJlbHN9XG5cdFx0XHQgKiBAc2lnbmFsXG5cdFx0XHQgKiBAZXhhbXBsZVxuXHRcdFx0ICogc291cmNlLnZvbHVtZS52YWx1ZSA9IC02O1xuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KCd2b2x1bWUnKTtcblx0ICAgICAgICAvL21ha2UgdGhlIG91dHB1dCBleHBsaWNpdGx5IHN0ZXJlb1xuXHQgICAgICAgIHRoaXMuX3ZvbHVtZS5vdXRwdXQub3V0cHV0LmNoYW5uZWxDb3VudCA9IDI7XG5cdCAgICAgICAgdGhpcy5fdm9sdW1lLm91dHB1dC5vdXRwdXQuY2hhbm5lbENvdW50TW9kZSA9ICdleHBsaWNpdCc7XG5cdCAgICAgICAgLy9tdXRlIGluaXRpYWxseVxuXHQgICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBjb250YWluZXIgb2YgYWxsIG9mIHRoZSBwbGF5ZXJzXG5cdFx0XHQgKiBAdHlwZSB7T2JqZWN0fVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX3BsYXllcnMgPSB7fTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqIFRoZSBsb2FkaW5nIGNvdW50XG5cdFx0XHQgKiBAdHlwZSB7TnVtYmVyfVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2xvYWRpbmdDb3VudCA9IDA7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiBwcml2YXRlIGhvbGRlciBvZiB0aGUgZmFkZUluIHRpbWVcblx0XHRcdCAqIEB0eXBlIHtUaW1lfVxuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHQgICAgICAgIHRoaXMuX2ZhZGVJbiA9IG9wdGlvbnMuZmFkZUluO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogcHJpdmF0ZSBob2xkZXIgb2YgdGhlIGZhZGVPdXQgdGltZVxuXHRcdFx0ICogQHR5cGUge1RpbWV9XG5cdFx0XHQgKiBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZmFkZU91dCA9IG9wdGlvbnMuZmFkZU91dDtcblx0ICAgICAgICAvL2FkZCBhbGwgb2YgdGhlIHBsYXllcnNcblx0ICAgICAgICBmb3IgKHZhciBuYW1lIGluIHVybHMpIHtcblx0ICAgICAgICAgICAgdGhpcy5fbG9hZGluZ0NvdW50Kys7XG5cdCAgICAgICAgICAgIHRoaXMuYWRkKG5hbWUsIHVybHNbbmFtZV0sIHRoaXMuX2J1ZmZlckxvYWRlZC5iaW5kKHRoaXMsIG9wdGlvbnMub25sb2FkKSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIFRvbmUuZXh0ZW5kKFRvbmUuUGxheWVycywgVG9uZS5BdWRpb05vZGUpO1xuXHQgICAgLyoqXG5cdFx0ICogVGhlIGRlZmF1bHQgdmFsdWVzXG5cdFx0ICogQHR5cGUge09iamVjdH1cblx0XHQgKi9cblx0ICAgIFRvbmUuUGxheWVycy5kZWZhdWx0cyA9IHtcblx0ICAgICAgICAndm9sdW1lJzogMCxcblx0ICAgICAgICAnbXV0ZSc6IGZhbHNlLFxuXHQgICAgICAgICdvbmxvYWQnOiBUb25lLm5vT3AsXG5cdCAgICAgICAgJ2ZhZGVJbic6IDAsXG5cdCAgICAgICAgJ2ZhZGVPdXQnOiAwXG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEEgYnVmZmVyIHdhcyBsb2FkZWQuIGRlY3JlbWVudCB0aGUgY291bnRlci5cblx0XHQgKiAgQHBhcmFtICB7RnVuY3Rpb259ICBjYWxsYmFja1xuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5QbGF5ZXJzLnByb3RvdHlwZS5fYnVmZmVyTG9hZGVkID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG5cdCAgICAgICAgdGhpcy5fbG9hZGluZ0NvdW50LS07XG5cdCAgICAgICAgaWYgKHRoaXMuX2xvYWRpbmdDb3VudCA9PT0gMCAmJiBjYWxsYmFjaykge1xuXHQgICAgICAgICAgICBjYWxsYmFjayh0aGlzKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogTXV0ZSB0aGUgb3V0cHV0LlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlNvdXJjZSNcblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAbmFtZSBtdXRlXG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiAvL211dGUgdGhlIG91dHB1dFxuXHRcdCAqIHNvdXJjZS5tdXRlID0gdHJ1ZTtcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBsYXllcnMucHJvdG90eXBlLCAnbXV0ZScsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZvbHVtZS5tdXRlO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2V0OiBmdW5jdGlvbiAobXV0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl92b2x1bWUubXV0ZSA9IG11dGU7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgZmFkZUluIHRpbWUgb2YgdGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5Tb3VyY2UjXG5cdFx0ICogQHR5cGUge1RpbWV9XG5cdFx0ICogQG5hbWUgZmFkZUluXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5QbGF5ZXJzLnByb3RvdHlwZSwgJ2ZhZGVJbicsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVJbjtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNldDogZnVuY3Rpb24gKGZhZGVJbikge1xuXHQgICAgICAgICAgICB0aGlzLl9mYWRlSW4gPSBmYWRlSW47XG5cdCAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZnVuY3Rpb24gKHBsYXllcikge1xuXHQgICAgICAgICAgICAgICAgcGxheWVyLmZhZGVJbiA9IGZhZGVJbjtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgZmFkZU91dCB0aW1lIG9mIHRoZSBhbXBsaXR1ZGUgZW52ZWxvcGUuXG5cdFx0ICogQG1lbWJlck9mIFRvbmUuU291cmNlI1xuXHRcdCAqIEB0eXBlIHtUaW1lfVxuXHRcdCAqIEBuYW1lIGZhZGVPdXRcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBsYXllcnMucHJvdG90eXBlLCAnZmFkZU91dCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVPdXQ7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChmYWRlT3V0KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2ZhZGVPdXQgPSBmYWRlT3V0O1xuXHQgICAgICAgICAgICB0aGlzLl9mb3JFYWNoKGZ1bmN0aW9uIChwbGF5ZXIpIHtcblx0ICAgICAgICAgICAgICAgIHBsYXllci5mYWRlT3V0ID0gZmFkZU91dDtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBUaGUgc3RhdGUgb2YgdGhlIHBsYXllcnMgb2JqZWN0LiBSZXR1cm5zIFwic3RhcnRlZFwiIGlmIGFueSBvZiB0aGUgcGxheWVycyBhcmUgcGxheWluZy5cblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5QbGF5ZXJzI1xuXHRcdCAqIEB0eXBlIHtTdHJpbmd9XG5cdFx0ICogQG5hbWUgc3RhdGVcblx0XHQgKiBAcmVhZE9ubHlcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlBsYXllcnMucHJvdG90eXBlLCAnc3RhdGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBwbGF5aW5nID0gZmFsc2U7XG5cdCAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZnVuY3Rpb24gKHBsYXllcikge1xuXHQgICAgICAgICAgICAgICAgcGxheWluZyA9IHBsYXlpbmcgfHwgcGxheWVyLnN0YXRlID09PSBUb25lLlN0YXRlLlN0YXJ0ZWQ7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICByZXR1cm4gcGxheWluZyA/IFRvbmUuU3RhdGUuU3RhcnRlZCA6IFRvbmUuU3RhdGUuU3RvcHBlZDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqICBUcnVlIGlmIHRoZSBidWZmZXJzIG9iamVjdCBoYXMgYSBidWZmZXIgYnkgdGhhdCBuYW1lLlxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd8TnVtYmVyfSAgbmFtZSAgVGhlIGtleSBvciBpbmRleCBvZiB0aGVcblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5cblx0XHQgKiAgQHJldHVybiAge0Jvb2xlYW59XG5cdFx0ICovXG5cdCAgICBUb25lLlBsYXllcnMucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uIChuYW1lKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXllcnMuaGFzT3duUHJvcGVydHkobmFtZSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIEdldCBhIHBsYXllciBieSBuYW1lLlxuXHRcdCAqICBAcGFyYW0gIHtTdHJpbmd9ICBuYW1lICBUaGUgcGxheWVycyBuYW1lIGFzIGRlZmluZWQgaW5cblx0XHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGNvbnN0cnVjdG9yIG9iamVjdCBvciBgYWRkYCBtZXRob2QuXG5cdFx0ICogIEByZXR1cm4gIHtUb25lLlBsYXllcn1cblx0XHQgKi9cblx0ICAgIFRvbmUuUGxheWVycy5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKG5hbWUpIHtcblx0ICAgICAgICBpZiAodGhpcy5oYXMobmFtZSkpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXllcnNbbmFtZV07XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUb25lLlBsYXllcnM6IG5vIHBsYXllciBuYW1lZCAnICsgbmFtZSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqIEl0ZXJhdGUgb3ZlciBhbGwgb2YgdGhlIHBsYXllcnNcblx0XHQgKiBAcGFyYW0gIHtGdW5jdGlvbn0gY2FsbGJhY2tcblx0XHQgKiBAcmV0dXJuIHtUb25lLlBsYXllcnN9ICAgICAgICAgICAgdGhpc1xuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLlBsYXllcnMucHJvdG90eXBlLl9mb3JFYWNoID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG5cdCAgICAgICAgZm9yICh2YXIgcGxheWVyTmFtZSBpbiB0aGlzLl9wbGF5ZXJzKSB7XG5cdCAgICAgICAgICAgIGNhbGxiYWNrKHRoaXMuX3BsYXllcnNbcGxheWVyTmFtZV0sIHBsYXllck5hbWUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBJZiBhbGwgdGhlIGJ1ZmZlcnMgYXJlIGxvYWRlZCBvciBub3Rcblx0XHQgKiBAbWVtYmVyT2YgVG9uZS5QbGF5ZXJzI1xuXHRcdCAqIEB0eXBlIHtCb29sZWFufVxuXHRcdCAqIEBuYW1lIGxvYWRlZFxuXHRcdCAqIEByZWFkT25seVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuUGxheWVycy5wcm90b3R5cGUsICdsb2FkZWQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBpc0xvYWRlZCA9IHRydWU7XG5cdCAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZnVuY3Rpb24gKHBsYXllcikge1xuXHQgICAgICAgICAgICAgICAgaXNMb2FkZWQgPSBpc0xvYWRlZCAmJiBwbGF5ZXIubG9hZGVkO1xuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIGlzTG9hZGVkO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogIEFkZCBhIHBsYXllciBieSBuYW1lIGFuZCB1cmwgdG8gdGhlIFBsYXllcnNcblx0XHQgKiAgQHBhcmFtICB7U3RyaW5nfSAgICBuYW1lICAgICAgQSB1bmlxdWUgbmFtZSB0byBnaXZlIHRoZSBwbGF5ZXJcblx0XHQgKiAgQHBhcmFtICB7U3RyaW5nfFRvbmUuQnVmZmVyfEF1ZGlvYnVmZmVyfSAgdXJsICBFaXRoZXIgdGhlIHVybCBvZiB0aGUgYnVmZXIsXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgYSBidWZmZXIgd2hpY2ggd2lsbCBiZSBhZGRlZFxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggdGhlIGdpdmVuIG5hbWUuXG5cdFx0ICogIEBwYXJhbSAge0Z1bmN0aW9uPX0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlXG5cdFx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGVuIHRoZSB1cmwgaXMgbG9hZGVkLlxuXHRcdCAqL1xuXHQgICAgVG9uZS5QbGF5ZXJzLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAobmFtZSwgdXJsLCBjYWxsYmFjaykge1xuXHQgICAgICAgIHRoaXMuX3BsYXllcnNbbmFtZV0gPSBuZXcgVG9uZS5QbGF5ZXIodXJsLCBjYWxsYmFjaykuY29ubmVjdCh0aGlzLm91dHB1dCk7XG5cdCAgICAgICAgdGhpcy5fcGxheWVyc1tuYW1lXS5mYWRlSW4gPSB0aGlzLl9mYWRlSW47XG5cdCAgICAgICAgdGhpcy5fcGxheWVyc1tuYW1lXS5mYWRlT3V0ID0gdGhpcy5fZmFkZU91dDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiBTdG9wIGFsbCBvZiB0aGUgcGxheWVycyBhdCB0aGUgZ2l2ZW4gdGltZVxuXHRcdCAqIEBwYXJhbSB7VGltZX0gdGltZSBUaGUgdGltZSB0byBzdG9wIGFsbCBvZiB0aGUgcGxheWVycy5cblx0XHQgKiBAcmV0dXJuIHtUb25lLlBsYXllcnN9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGxheWVycy5wcm90b3R5cGUuc3RvcEFsbCA9IGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgICAgICAgdGhpcy5fZm9yRWFjaChmdW5jdGlvbiAocGxheWVyKSB7XG5cdCAgICAgICAgICAgIHBsYXllci5zdG9wKHRpbWUpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBEaXNwb3NlIGFuZCBkaXNjb25uZWN0LlxuXHRcdCAqICBAcmV0dXJuIHtUb25lLlBsYXllcnN9IHRoaXNcblx0XHQgKi9cblx0ICAgIFRvbmUuUGxheWVycy5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG5cdCAgICAgICAgdGhpcy5fdm9sdW1lID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZSgndm9sdW1lJyk7XG5cdCAgICAgICAgdGhpcy52b2x1bWUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMub3V0cHV0ID0gbnVsbDtcblx0ICAgICAgICB0aGlzLl9mb3JFYWNoKGZ1bmN0aW9uIChwbGF5ZXIpIHtcblx0ICAgICAgICAgICAgcGxheWVyLmRpc3Bvc2UoKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0aGlzLl9wbGF5ZXJzID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5QbGF5ZXJzO1xuXHR9KTtcblx0TW9kdWxlKGZ1bmN0aW9uIChUb25lKSB7XG5cdCAgICBcblx0ICAgIC8qKlxuXHRcdCAqICBAY2xhc3MgIFRvbmUuVXNlck1lZGlhIHVzZXMgTWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSB0byBvcGVuIHVwXG5cdFx0ICogICAgICAgICAgYW5kIGV4dGVybmFsIG1pY3JvcGhvbmUgb3IgYXVkaW8gaW5wdXQuIENoZWNrXG5cdFx0ICogICAgICAgICAgW01lZGlhRGV2aWNlcyBBUEkgU3VwcG9ydF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL01lZGlhRGV2aWNlcy9nZXRVc2VyTWVkaWEpXG5cdFx0ICogICAgICAgICAgdG8gc2VlIHdoaWNoIGJyb3dzZXJzIGFyZSBzdXBwb3J0ZWQuIEFjY2VzcyB0byBhbiBleHRlcm5hbCBpbnB1dFxuXHRcdCAqICAgICAgICAgIGlzIGxpbWl0ZWQgdG8gc2VjdXJlIChIVFRQUykgY29ubmVjdGlvbnMuXG5cdFx0ICpcblx0XHQgKiAgQGNvbnN0cnVjdG9yXG5cdFx0ICogIEBleHRlbmRzIHtUb25lLkF1ZGlvTm9kZX1cblx0XHQgKiAgQHBhcmFtIHtEZWNpYmVscz19IHZvbHVtZSBUaGUgbGV2ZWwgb2YgdGhlIGlucHV0XG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogLy9saXN0IHRoZSBpbnB1dHMgYW5kIG9wZW4gdGhlIHRoaXJkIG9uZVxuXHRcdCAqIHZhciBtb3R1ID0gbmV3IFRvbmUuVXNlck1lZGlhKCk7XG5cdFx0ICpcblx0XHQgKiAvL29wZW5pbmcgdGhlIGlucHV0IGFza3MgdGhlIHVzZXIgdG8gYWN0aXZhdGUgdGhlaXIgbWljXG5cdFx0ICogbW90dS5vcGVuKCkudGhlbihmdW5jdGlvbigpe1xuXHRcdCAqIFx0Ly9wcm9taXNlIHJlc29sdmVzIHdoZW4gaW5wdXQgaXMgYXZhaWxhYmxlXG5cdFx0ICogfSk7XG5cdFx0ICovXG5cdCAgICBUb25lLlVzZXJNZWRpYSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgb3B0aW9ucyA9IFRvbmUuZGVmYXVsdHMoYXJndW1lbnRzLCBbJ3ZvbHVtZSddLCBUb25lLlVzZXJNZWRpYSk7XG5cdCAgICAgICAgVG9uZS5BdWRpb05vZGUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgTWVkaWFTdHJlYW1Ob2RlXG5cdFx0XHQgKiAgQHR5cGUge01lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlfVxuXHRcdFx0ICogIEBwcml2YXRlXG5cdFx0XHQgKi9cblx0ICAgICAgICB0aGlzLl9tZWRpYVN0cmVhbSA9IG51bGw7XG5cdCAgICAgICAgLyoqXG5cdFx0XHQgKiAgVGhlIG1lZGlhIHN0cmVhbSBjcmVhdGVkIGJ5IGdldFVzZXJNZWRpYS5cblx0XHRcdCAqICBAdHlwZSB7TG9jYWxNZWRpYVN0cmVhbX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fc3RyZWFtID0gbnVsbDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgb3BlbiBkZXZpY2Vcblx0XHRcdCAqICBAdHlwZSAge01lZGlhRGV2aWNlSW5mb31cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fZGV2aWNlID0gbnVsbDtcblx0ICAgICAgICAvKipcblx0XHRcdCAqICBUaGUgb3V0cHV0IHZvbHVtZSBub2RlXG5cdFx0XHQgKiAgQHR5cGUgIHtUb25lLlZvbHVtZX1cblx0XHRcdCAqICBAcHJpdmF0ZVxuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy5fdm9sdW1lID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZS5Wb2x1bWUob3B0aW9ucy52b2x1bWUpO1xuXHQgICAgICAgIC8qKlxuXHRcdFx0ICogVGhlIHZvbHVtZSBvZiB0aGUgb3V0cHV0IGluIGRlY2liZWxzLlxuXHRcdFx0ICogQHR5cGUge0RlY2liZWxzfVxuXHRcdFx0ICogQHNpZ25hbFxuXHRcdFx0ICogQGV4YW1wbGVcblx0XHRcdCAqIGlucHV0LnZvbHVtZS52YWx1ZSA9IC02O1xuXHRcdFx0ICovXG5cdCAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuXHQgICAgICAgIHRoaXMuX3JlYWRPbmx5KCd2b2x1bWUnKTtcblx0ICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5Vc2VyTWVkaWEsIFRvbmUuQXVkaW9Ob2RlKTtcblx0ICAgIC8qKlxuXHRcdCAqIHRoZSBkZWZhdWx0IHBhcmFtZXRlcnNcblx0XHQgKiBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqL1xuXHQgICAgVG9uZS5Vc2VyTWVkaWEuZGVmYXVsdHMgPSB7XG5cdCAgICAgICAgJ3ZvbHVtZSc6IDAsXG5cdCAgICAgICAgJ211dGUnOiBmYWxzZVxuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBPcGVuIHRoZSBtZWRpYSBzdHJlYW0uIElmIGEgc3RyaW5nIGlzIHBhc3NlZCBpbiwgaXQgaXMgYXNzdW1lZFxuXHRcdCAqICB0byBiZSB0aGUgbGFiZWwgb3IgaWQgb2YgdGhlIHN0cmVhbSwgaWYgYSBudW1iZXIgaXMgcGFzc2VkIGluLFxuXHRcdCAqICBpdCBpcyB0aGUgaW5wdXQgbnVtYmVyIG9mIHRoZSBzdHJlYW0uXG5cdFx0ICogIEBwYXJhbSAge1N0cmluZ3xOdW1iZXJ9IFtsYWJlbE9ySWQ9XCJkZWZhdWx0XCJdIFRoZSBsYWJlbCBvciBpZCBvZiB0aGUgYXVkaW8gaW5wdXQgbWVkaWEgZGV2aWNlLlxuXHRcdCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2l0aCBubyBhcmd1bWVudCwgdGhlIGRlZmF1bHQgc3RyZWFtIGlzIG9wZW5lZC5cblx0XHQgKiAgQHJldHVybiB7UHJvbWlzZX0gVGhlIHByb21pc2UgaXMgcmVzb2x2ZWQgd2hlbiB0aGUgc3RyZWFtIGlzIG9wZW4uXG5cdFx0ICovXG5cdCAgICBUb25lLlVzZXJNZWRpYS5wcm90b3R5cGUub3BlbiA9IGZ1bmN0aW9uIChsYWJlbE9ySWQpIHtcblx0ICAgICAgICByZXR1cm4gVG9uZS5Vc2VyTWVkaWEuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oZnVuY3Rpb24gKGRldmljZXMpIHtcblx0ICAgICAgICAgICAgdmFyIGRldmljZTtcblx0ICAgICAgICAgICAgaWYgKFRvbmUuaXNOdW1iZXIobGFiZWxPcklkKSkge1xuXHQgICAgICAgICAgICAgICAgZGV2aWNlID0gZGV2aWNlc1tsYWJlbE9ySWRdO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgZGV2aWNlID0gZGV2aWNlcy5maW5kKGZ1bmN0aW9uIChkZXZpY2UpIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGV2aWNlLmxhYmVsID09PSBsYWJlbE9ySWQgfHwgZGV2aWNlLmRldmljZUlkID09PSBsYWJlbE9ySWQ7XG5cdCAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgIC8vZGlkbid0IGZpbmQgYSBtYXRjaGluZyBkZXZpY2Vcblx0ICAgICAgICAgICAgICAgIGlmICghZGV2aWNlICYmIGRldmljZXMubGVuZ3RoID4gMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIGRldmljZSA9IGRldmljZXNbMF07XG5cdCAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFkZXZpY2UgJiYgVG9uZS5pc0RlZmluZWQobGFiZWxPcklkKSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVG9uZS5Vc2VyTWVkaWE6IG5vIG1hdGNoaW5nIGRldmljZTogJyArIGxhYmVsT3JJZCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5fZGV2aWNlID0gZGV2aWNlO1xuXHQgICAgICAgICAgICAvL2RvIGdldFVzZXJNZWRpYVxuXHQgICAgICAgICAgICB2YXIgY29uc3RyYWludHMgPSB7XG5cdCAgICAgICAgICAgICAgICBhdWRpbzoge1xuXHQgICAgICAgICAgICAgICAgICAgICdlY2hvQ2FuY2VsbGF0aW9uJzogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICAgICAgJ3NhbXBsZVJhdGUnOiB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZVxuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICBpZiAoZGV2aWNlKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdHJhaW50cy5hdWRpby5kZXZpY2VJZCA9IGRldmljZS5kZXZpY2VJZDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICByZXR1cm4gbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHMpLnRoZW4oZnVuY3Rpb24gKHN0cmVhbSkge1xuXHQgICAgICAgICAgICAgICAgLy9zdGFydCBhIG5ldyBzb3VyY2Ugb25seSBpZiB0aGUgcHJldmlvdXMgb25lIGlzIGNsb3NlZFxuXHQgICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9zdHJlYW0pIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdHJlYW0gPSBzdHJlYW07XG5cdCAgICAgICAgICAgICAgICAgICAgLy9XcmFwIGEgTWVkaWFTdHJlYW1Tb3VyY2VOb2RlIGFyb3VuZCB0aGUgbGl2ZSBpbnB1dCBzdHJlYW0uXG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWVkaWFTdHJlYW0gPSB0aGlzLmNvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2Uoc3RyZWFtKTtcblx0ICAgICAgICAgICAgICAgICAgICAvL0Nvbm5lY3QgdGhlIE1lZGlhU3RyZWFtU291cmNlTm9kZSB0byBhIGdhdGUgZ2FpbiBub2RlXG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWVkaWFTdHJlYW0uY29ubmVjdCh0aGlzLm91dHB1dCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgICAgICAgfS5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB9LmJpbmQodGhpcykpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBDbG9zZSB0aGUgbWVkaWEgc3RyZWFtXG5cdFx0ICogIEByZXR1cm4ge1RvbmUuVXNlck1lZGlhfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlVzZXJNZWRpYS5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuX3N0cmVhbSkge1xuXHQgICAgICAgICAgICB0aGlzLl9zdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uICh0cmFjaykge1xuXHQgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgdGhpcy5fc3RyZWFtID0gbnVsbDtcblx0ICAgICAgICAgICAgLy9yZW1vdmUgdGhlIG9sZCBtZWRpYSBzdHJlYW1cblx0ICAgICAgICAgICAgdGhpcy5fbWVkaWFTdHJlYW0uZGlzY29ubmVjdCgpO1xuXHQgICAgICAgICAgICB0aGlzLl9tZWRpYVN0cmVhbSA9IG51bGw7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuX2RldmljZSA9IG51bGw7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybnMgYSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdpdGggdGhlIGxpc3Qgb2YgYXVkaW8gaW5wdXQgZGV2aWNlcyBhdmFpbGFibGUuXG5cdFx0ICogIEByZXR1cm4ge1Byb21pc2V9IFRoZSBwcm9taXNlIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgZGV2aWNlc1xuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEBleGFtcGxlXG5cdFx0ICogVG9uZS5Vc2VyTWVkaWEuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oZnVuY3Rpb24oZGV2aWNlcyl7XG5cdFx0ICogXHRjb25zb2xlLmxvZyhkZXZpY2VzKVxuXHRcdCAqIH0pXG5cdFx0ICovXG5cdCAgICBUb25lLlVzZXJNZWRpYS5lbnVtZXJhdGVEZXZpY2VzID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKGZ1bmN0aW9uIChkZXZpY2VzKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBkZXZpY2VzLmZpbHRlcihmdW5jdGlvbiAoZGV2aWNlKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gZGV2aWNlLmtpbmQgPT09ICdhdWRpb2lucHV0Jztcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIFwic3RhcnRlZFwiIHdoZW4gdGhlIG1pY3JvcGhvbmUgaXMgb3BlblxuXHRcdCAqICBhbmQgXCJzdG9wcGVkXCIgd2hlbiB0aGUgbWljIGlzIGNsb3NlZC5cblx0XHQgKiAgQHR5cGUge1RvbmUuU3RhdGV9XG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5Vc2VyTWVkaWEjXG5cdFx0ICogIEBuYW1lIHN0YXRlXG5cdFx0ICovXG5cdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9uZS5Vc2VyTWVkaWEucHJvdG90eXBlLCAnc3RhdGUnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdHJlYW0gJiYgdGhpcy5fc3RyZWFtLmFjdGl2ZSA/IFRvbmUuU3RhdGUuU3RhcnRlZCA6IFRvbmUuU3RhdGUuU3RvcHBlZDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIFx0UmV0dXJucyBhbiBpZGVudGlmaWVyIGZvciB0aGUgcmVwcmVzZW50ZWQgZGV2aWNlIHRoYXQgaXNcblx0XHQgKiBcdHBlcnNpc3RlZCBhY3Jvc3Mgc2Vzc2lvbnMuIEl0IGlzIHVuLWd1ZXNzYWJsZSBieSBvdGhlciBhcHBsaWNhdGlvbnMgYW5kXG5cdFx0ICogXHR1bmlxdWUgdG8gdGhlIG9yaWdpbiBvZiB0aGUgY2FsbGluZyBhcHBsaWNhdGlvbi4gSXQgaXMgcmVzZXQgd2hlbiB0aGVcblx0XHQgKiBcdHVzZXIgY2xlYXJzIGNvb2tpZXMgKGZvciBQcml2YXRlIEJyb3dzaW5nLCBhIGRpZmZlcmVudCBpZGVudGlmaWVyIGlzXG5cdFx0ICogXHR1c2VkIHRoYXQgaXMgbm90IHBlcnNpc3RlZCBhY3Jvc3Mgc2Vzc2lvbnMpLiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIHRoZVxuXHRcdCAqIFx0ZGV2aWNlIGlzIG5vdCBvcGVuLlxuXHRcdCAqICBAdHlwZSB7U3RyaW5nfVxuXHRcdCAqICBAcmVhZE9ubHlcblx0XHQgKiAgQG1lbWJlck9mIFRvbmUuVXNlck1lZGlhI1xuXHRcdCAqICBAbmFtZSBkZXZpY2VJZFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuVXNlck1lZGlhLnByb3RvdHlwZSwgJ2RldmljZUlkJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBpZiAodGhpcy5fZGV2aWNlKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV2aWNlLmRldmljZUlkO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICAvKipcblx0XHQgKiBcdFJldHVybnMgYSBncm91cCBpZGVudGlmaWVyLiBUd28gZGV2aWNlcyBoYXZlIHRoZVxuXHRcdCAqIFx0c2FtZSBncm91cCBpZGVudGlmaWVyIGlmIHRoZXkgYmVsb25nIHRvIHRoZSBzYW1lIHBoeXNpY2FsIGRldmljZS5cblx0XHQgKiBcdFJldHVybnMgdW5kZWZpbmVkIHdoZW4gdGhlIGRldmljZSBpcyBub3Qgb3Blbi5cblx0XHQgKiAgQHR5cGUge1N0cmluZ31cblx0XHQgKiAgQHJlYWRPbmx5XG5cdFx0ICogIEBtZW1iZXJPZiBUb25lLlVzZXJNZWRpYSNcblx0XHQgKiAgQG5hbWUgZ3JvdXBJZFxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuVXNlck1lZGlhLnByb3RvdHlwZSwgJ2dyb3VwSWQnLCB7XG5cdCAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIGlmICh0aGlzLl9kZXZpY2UpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZXZpY2UuZ3JvdXBJZDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogXHRSZXR1cm5zIGEgbGFiZWwgZGVzY3JpYmluZyB0aGlzIGRldmljZSAoZm9yIGV4YW1wbGUgXCJCdWlsdC1pbiBNaWNyb3Bob25lXCIpLlxuXHRcdCAqIFx0UmV0dXJucyB1bmRlZmluZWQgd2hlbiB0aGUgZGV2aWNlIGlzIG5vdCBvcGVuIG9yIGxhYmVsIGlzIG5vdCBhdmFpbGFibGVcblx0XHQgKiBcdGJlY2F1c2Ugb2YgcGVybWlzc2lvbnMuXG5cdFx0ICogIEB0eXBlIHtTdHJpbmd9XG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5Vc2VyTWVkaWEjXG5cdFx0ICogIEBuYW1lIGdyb3VwSWRcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlVzZXJNZWRpYS5wcm90b3R5cGUsICdsYWJlbCcsIHtcblx0ICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX2RldmljZSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RldmljZS5sYWJlbDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgLyoqXG5cdFx0ICogTXV0ZSB0aGUgb3V0cHV0LlxuXHRcdCAqIEBtZW1iZXJPZiBUb25lLlVzZXJNZWRpYSNcblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAbmFtZSBtdXRlXG5cdFx0ICogQGV4YW1wbGVcblx0XHQgKiAvL211dGUgdGhlIG91dHB1dFxuXHRcdCAqIHVzZXJNZWRpYS5tdXRlID0gdHJ1ZTtcblx0XHQgKi9cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb25lLlVzZXJNZWRpYS5wcm90b3R5cGUsICdtdXRlJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fdm9sdW1lLm11dGU7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXQ6IGZ1bmN0aW9uIChtdXRlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX3ZvbHVtZS5tdXRlID0gbXV0ZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIC8qKlxuXHRcdCAqIENsZWFuIHVwLlxuXHRcdCAqIEByZXR1cm4ge1RvbmUuVXNlck1lZGlhfSB0aGlzXG5cdFx0ICovXG5cdCAgICBUb25lLlVzZXJNZWRpYS5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBUb25lLkF1ZGlvTm9kZS5wcm90b3R5cGUuZGlzcG9zZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuY2xvc2UoKTtcblx0ICAgICAgICB0aGlzLl93cml0YWJsZSgndm9sdW1lJyk7XG5cdCAgICAgICAgdGhpcy5fdm9sdW1lLmRpc3Bvc2UoKTtcblx0ICAgICAgICB0aGlzLl92b2x1bWUgPSBudWxsO1xuXHQgICAgICAgIHRoaXMudm9sdW1lID0gbnVsbDtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgSWYgZ2V0VXNlck1lZGlhIGlzIHN1cHBvcnRlZCBieSB0aGUgYnJvd3Nlci5cblx0XHQgKiAgQHR5cGUgIHtCb29sZWFufVxuXHRcdCAqICBAbWVtYmVyT2YgVG9uZS5Vc2VyTWVkaWEjXG5cdFx0ICogIEBuYW1lIHN1cHBvcnRlZFxuXHRcdCAqICBAc3RhdGljXG5cdFx0ICogIEByZWFkT25seVxuXHRcdCAqL1xuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvbmUuVXNlck1lZGlhLCAnc3VwcG9ydGVkJywge1xuXHQgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gVG9uZS5pc0RlZmluZWQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcykgJiYgVG9uZS5pc0Z1bmN0aW9uKG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIHJldHVybiBUb25lLlVzZXJNZWRpYTtcblx0fSk7XG5cdE1vZHVsZShmdW5jdGlvbiAoVG9uZSkge1xuXHQgICAgLyoqXG5cdFx0ICogIEBjbGFzcyBUb25lLk1pZGkgaXMgYSBwcmltaXRpdmUgdHlwZSBmb3IgZW5jb2RpbmcgVGltZSB2YWx1ZXMuXG5cdFx0ICogICAgICAgICBUb25lLk1pZGkgY2FuIGJlIGNvbnN0cnVjdGVkIHdpdGggb3Igd2l0aG91dCB0aGUgYG5ld2Aga2V5d29yZC4gVG9uZS5NaWRpIGNhbiBiZSBwYXNzZWRcblx0XHQgKiAgICAgICAgIGludG8gdGhlIHBhcmFtZXRlciBvZiBhbnkgbWV0aG9kIHdoaWNoIHRha2VzIHRpbWUgYXMgYW4gYXJndW1lbnQuXG5cdFx0ICogIEBjb25zdHJ1Y3RvclxuXHRcdCAqICBAZXh0ZW5kcyB7VG9uZS5GcmVxdWVuY3l9XG5cdFx0ICogIEBwYXJhbSAge1N0cmluZ3xOdW1iZXJ9ICB2YWwgICAgVGhlIHRpbWUgdmFsdWUuXG5cdFx0ICogIEBwYXJhbSAge1N0cmluZz19ICB1bml0cyAgVGhlIHVuaXRzIG9mIHRoZSB2YWx1ZS5cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiB2YXIgdCA9IFRvbmUuTWlkaShcIjRuXCIpOy8vYSBxdWFydGVyIG5vdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuTWlkaSA9IGZ1bmN0aW9uICh2YWwsIHVuaXRzKSB7XG5cdCAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBUb25lLk1pZGkpIHtcblx0ICAgICAgICAgICAgVG9uZS5GcmVxdWVuY3kuY2FsbCh0aGlzLCB2YWwsIHVuaXRzKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICByZXR1cm4gbmV3IFRvbmUuTWlkaSh2YWwsIHVuaXRzKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgVG9uZS5leHRlbmQoVG9uZS5NaWRpLCBUb25lLkZyZXF1ZW5jeSk7XG5cdCAgICAvKipcblx0XHQgKiAgVGhlIGRlZmF1bHQgdW5pdHMgaWYgbm9uZSBhcmUgZ2l2ZW4uXG5cdFx0ICogIEB0eXBlIHtTdHJpbmd9XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLk1pZGkucHJvdG90eXBlLl9kZWZhdWx0VW5pdHMgPSAnbWlkaSc7XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBmcmVxdWVuY3kgaW4gdGhlIGN1cnJlbnQgdW5pdHNcblx0XHQgKiAgQHBhcmFtIHtGcmVxdWVuY3l9IGZyZXFcblx0XHQgKiAgQHJldHVybiAge051bWJlcn1cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuTWlkaS5wcm90b3R5cGUuX2ZyZXF1ZW5jeVRvVW5pdHMgPSBmdW5jdGlvbiAoZnJlcSkge1xuXHQgICAgICAgIHJldHVybiBUb25lLkZyZXF1ZW5jeS5mdG9tKFRvbmUuRnJlcXVlbmN5LnByb3RvdHlwZS5fZnJlcXVlbmN5VG9Vbml0cy5jYWxsKHRoaXMsIGZyZXEpKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJucyB0aGUgdmFsdWUgb2YgYSB0aWNrIGluIHRoZSBjdXJyZW50IHRpbWUgdW5pdHNcblx0XHQgKiAgQHBhcmFtIHtUaWNrc30gdGlja3Ncblx0XHQgKiAgQHJldHVybiAge051bWJlcn1cblx0XHQgKiAgQHByaXZhdGVcblx0XHQgKi9cblx0ICAgIFRvbmUuTWlkaS5wcm90b3R5cGUuX3RpY2tzVG9Vbml0cyA9IGZ1bmN0aW9uICh0aWNrcykge1xuXHQgICAgICAgIHJldHVybiBUb25lLkZyZXF1ZW5jeS5mdG9tKFRvbmUuRnJlcXVlbmN5LnByb3RvdHlwZS5fdGlja3NUb1VuaXRzLmNhbGwodGhpcywgdGlja3MpKTtcblx0ICAgIH07XG5cdCAgICAvKipcblx0XHQgKiAgUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYmVhdHMgaW4gdGhlIGN1cnJlbnQgdW5pdHNcblx0XHQgKiAgQHBhcmFtIHtOdW1iZXJ9IGJlYXRzXG5cdFx0ICogIEByZXR1cm4gIHtOdW1iZXJ9XG5cdFx0ICogIEBwcml2YXRlXG5cdFx0ICovXG5cdCAgICBUb25lLk1pZGkucHJvdG90eXBlLl9iZWF0c1RvVW5pdHMgPSBmdW5jdGlvbiAoYmVhdHMpIHtcblx0ICAgICAgICByZXR1cm4gVG9uZS5GcmVxdWVuY3kuZnRvbShUb25lLkZyZXF1ZW5jeS5wcm90b3R5cGUuX2JlYXRzVG9Vbml0cy5jYWxsKHRoaXMsIGJlYXRzKSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgc2Vjb25kIGluIHRoZSBjdXJyZW50IHVuaXRzXG5cdFx0ICogIEBwYXJhbSB7U2Vjb25kc30gc2Vjb25kc1xuXHRcdCAqICBAcmV0dXJuICB7TnVtYmVyfVxuXHRcdCAqICBAcHJpdmF0ZVxuXHRcdCAqL1xuXHQgICAgVG9uZS5NaWRpLnByb3RvdHlwZS5fc2Vjb25kc1RvVW5pdHMgPSBmdW5jdGlvbiAoc2Vjb25kcykge1xuXHQgICAgICAgIHJldHVybiBUb25lLkZyZXF1ZW5jeS5mdG9tKFRvbmUuRnJlcXVlbmN5LnByb3RvdHlwZS5fc2Vjb25kc1RvVW5pdHMuY2FsbCh0aGlzLCBzZWNvbmRzKSk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZyZXF1ZW5jeSBhcyBhIE1JREkgbm90ZVxuXHRcdCAqICBAcmV0dXJuICB7TUlESX1cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBUb25lLk1pZGkoNjApLnRvTWlkaSgpOyAvLzYwXG5cdFx0ICovXG5cdCAgICBUb25lLk1pZGkucHJvdG90eXBlLnRvTWlkaSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy52YWx1ZU9mKCk7XG5cdCAgICB9O1xuXHQgICAgLyoqXG5cdFx0ICogIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZyZXF1ZW5jeSBhcyBhIE1JREkgbm90ZVxuXHRcdCAqICBAcmV0dXJuICB7TUlESX1cblx0XHQgKiAgQGV4YW1wbGVcblx0XHQgKiBUb25lLk1pZGkoNjApLnRvTWlkaSgpOyAvLzYwXG5cdFx0ICovXG5cdCAgICBUb25lLk1pZGkucHJvdG90eXBlLnRvRnJlcXVlbmN5ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiBUb25lLkZyZXF1ZW5jeS5tdG9mKHRoaXMudG9NaWRpKCkpO1xuXHQgICAgfTtcblx0ICAgIC8qKlxuXHRcdCAqICBUcmFuc3Bvc2VzIHRoZSBmcmVxdWVuY3kgYnkgdGhlIGdpdmVuIG51bWJlciBvZiBzZW1pdG9uZXMuXG5cdFx0ICogIEBwYXJhbSAge0ludGVydmFsfSAgaW50ZXJ2YWxcblx0XHQgKiAgQHJldHVybiAge1RvbmUuRnJlcXVlbmN5fSBBIG5ldyB0cmFuc3Bvc2VkIGZyZXF1ZW5jeVxuXHRcdCAqICBAZXhhbXBsZVxuXHRcdCAqIFRvbmUuRnJlcXVlbmN5KFwiQTRcIikudHJhbnNwb3NlKDMpOyAvL1wiQzVcIlxuXHRcdCAqL1xuXHQgICAgVG9uZS5NaWRpLnByb3RvdHlwZS50cmFuc3Bvc2UgPSBmdW5jdGlvbiAoaW50ZXJ2YWwpIHtcblx0ICAgICAgICByZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy50b01pZGkoKSArIGludGVydmFsKTtcblx0ICAgIH07XG5cdCAgICByZXR1cm4gVG9uZS5NaWRpO1xuXHR9KTtcblx0XG5cdHJldHVybiBUb25lO1xufSkpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi90b25lL2J1aWxkL1RvbmUuanNcbi8vIG1vZHVsZSBpZCA9IDI0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gdHJ1ZTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2xpYnJhcnkuanNcbi8vIG1vZHVsZSBpZCA9IDI1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImV4cG9ydHMuZiA9IHt9LnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fb2JqZWN0LXBpZS5qc1xuLy8gbW9kdWxlIGlkID0gMjZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGRlZiA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmZcbiAgLCBoYXMgPSByZXF1aXJlKCcuL19oYXMnKVxuICAsIFRBRyA9IHJlcXVpcmUoJy4vX3drcycpKCd0b1N0cmluZ1RhZycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCB0YWcsIHN0YXQpe1xuICBpZihpdCAmJiAhaGFzKGl0ID0gc3RhdCA/IGl0IDogaXQucHJvdG90eXBlLCBUQUcpKWRlZihpdCwgVEFHLCB7Y29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogdGFnfSk7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanNcbi8vIG1vZHVsZSBpZCA9IDI3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIDcuMS4xMyBUb09iamVjdChhcmd1bWVudClcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiBPYmplY3QoZGVmaW5lZChpdCkpO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3RvLW9iamVjdC5qc1xuLy8gbW9kdWxlIGlkID0gMjhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGlkID0gMFxuICAsIHB4ID0gTWF0aC5yYW5kb20oKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oa2V5KXtcbiAgcmV0dXJuICdTeW1ib2woJy5jb25jYXQoa2V5ID09PSB1bmRlZmluZWQgPyAnJyA6IGtleSwgJylfJywgKCsraWQgKyBweCkudG9TdHJpbmcoMzYpKTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL191aWQuanNcbi8vIG1vZHVsZSBpZCA9IDI5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInJlcXVpcmUoJy4vZXM2LmFycmF5Lml0ZXJhdG9yJyk7XG52YXIgZ2xvYmFsICAgICAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgaGlkZSAgICAgICAgICA9IHJlcXVpcmUoJy4vX2hpZGUnKVxuICAsIEl0ZXJhdG9ycyAgICAgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKVxuICAsIFRPX1NUUklOR19UQUcgPSByZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKTtcblxuZm9yKHZhciBjb2xsZWN0aW9ucyA9IFsnTm9kZUxpc3QnLCAnRE9NVG9rZW5MaXN0JywgJ01lZGlhTGlzdCcsICdTdHlsZVNoZWV0TGlzdCcsICdDU1NSdWxlTGlzdCddLCBpID0gMDsgaSA8IDU7IGkrKyl7XG4gIHZhciBOQU1FICAgICAgID0gY29sbGVjdGlvbnNbaV1cbiAgICAsIENvbGxlY3Rpb24gPSBnbG9iYWxbTkFNRV1cbiAgICAsIHByb3RvICAgICAgPSBDb2xsZWN0aW9uICYmIENvbGxlY3Rpb24ucHJvdG90eXBlO1xuICBpZihwcm90byAmJiAhcHJvdG9bVE9fU1RSSU5HX1RBR10paGlkZShwcm90bywgVE9fU1RSSU5HX1RBRywgTkFNRSk7XG4gIEl0ZXJhdG9yc1tOQU1FXSA9IEl0ZXJhdG9ycy5BcnJheTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvd2ViLmRvbS5pdGVyYWJsZS5qc1xuLy8gbW9kdWxlIGlkID0gMzBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0IFRvbmUgZnJvbSAndG9uZSdcbmltcG9ydCBTdGFydEF1ZGlvQ29udGV4dCBmcm9tICcuL3N0YXJ0QXVkaW9Db250ZXh0J1xuXG5leHBvcnQgY29uc3QgaXNJcGhvbmUgPSAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lL2kpKSB8fCAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBvZC9pKSlcbmV4cG9ydCBjb25zdCBpc0lwYWQgPSAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBhZC9pKSlcbmV4cG9ydCBjb25zdCBpc0FuZHJvaWQgPSAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSlcbmV4cG9ydCBjb25zdCBpc01vYmlsZSA9IGlzSXBob25lIHx8IGlzSXBhZCB8fCBpc0FuZHJvaWRcbmV4cG9ydCBjb25zdCBpc0Rlc2t0b3AgPSAhIGlzTW9iaWxlXG5cbmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZChpc01vYmlsZSA/ICdtb2JpbGUnIDogJ2Rlc2t0b3AnKVxuXG5leHBvcnQgY29uc3QgYnJvd3NlciA9IHsgaXNJcGhvbmUsIGlzSXBhZCwgaXNNb2JpbGUsIGlzRGVza3RvcCB9XG5cbmV4cG9ydCBmdW5jdGlvbiBjaG9pY2UgKGEpeyByZXR1cm4gYVsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogYS5sZW5ndGgpIF0gfVxuZXhwb3J0IGZ1bmN0aW9uIG1vZChuLG0peyByZXR1cm4gbi0obSAqIE1hdGguZmxvb3Iobi9tKSkgfVxuZXhwb3J0IGZ1bmN0aW9uIG5vcm0obiwgbWluLCBtYXgpeyByZXR1cm4gKG4gLSBtaW4pIC8gKG1heCAtIG1pbikgfVxuXG5leHBvcnQgZnVuY3Rpb24gcmVxdWVzdEF1ZGlvQ29udGV4dCAoZm4pIHtcblx0aWYgKGlzTW9iaWxlKSB7XG4gICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICBjb25zdCBidXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICAgIGJ1dHRvbi5pbm5lckhUTUwgPSAnVGFwIHRvIHN0YXJ0IC0gcGxlYXNlIHVubXV0ZSB5b3VyIHBob25lJ1xuICAgIE9iamVjdC5hc3NpZ24oY29udGFpbmVyLnN0eWxlLCB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICBoZWlnaHQ6ICcxMDAlJyxcbiAgICAgIHpJbmRleDogJzEwMDAwJyxcbiAgICAgIHRvcDogJzBweCcsXG4gICAgICBsZWZ0OiAnMHB4JyxcbiAgICAgIGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwgMCwgMCwgMC44KScsXG4gICAgfSlcblx0XHRPYmplY3QuYXNzaWduKGJ1dHRvbi5zdHlsZSwge1xuXHRcdCAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG5cdFx0ICBsZWZ0OiAnNTAlJyxcblx0XHQgIHRvcDogJzUwJScsXG5cdFx0XHRwYWRkaW5nOiAnMjBweCcsXG5cdFx0ICBiYWNrZ3JvdW5kQ29sb3I6ICcjN0YzM0VEJyxcblx0XHQgIGNvbG9yOiAnd2hpdGUnLFxuXHRcdCAgZm9udEZhbWlseTogJ21vbm9zcGFjZScsXG5cdFx0ICBib3JkZXJSYWRpdXM6ICczcHgnLFxuXHRcdCAgdHJhbnNmb3JtOiAndHJhbnNsYXRlM0QoLTUwJSwtNTAlLDApJyxcblx0XHQgIHRleHRBbGlnbjogJ2NlbnRlcicsXG5cdFx0XHRsaW5lSGVpZ2h0OiAnMS41JyxcbiAgICB9KVxuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChidXR0b24pXG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChjb250YWluZXIpXG4gICAgU3RhcnRBdWRpb0NvbnRleHQuc2V0Q29udGV4dChUb25lLmNvbnRleHQpXG4gICAgU3RhcnRBdWRpb0NvbnRleHQub24oYnV0dG9uKVxuICAgIFN0YXJ0QXVkaW9Db250ZXh0Lm9uU3RhcnRlZChfID0+IHtcbiAgICAgIGNvbnRhaW5lci5yZW1vdmUoKVxuXHRcdFx0Zm4oKVxuICBcdH0pXG5cdH0gZWxzZSB7XG5cdFx0Zm4oKVxuXHR9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkYXRhVVJJdG9CbG9iKGRhdGFVUkkpIHtcbiAgLy8gY29udmVydCBiYXNlNjQgdG8gcmF3IGJpbmFyeSBkYXRhIGhlbGQgaW4gYSBzdHJpbmdcbiAgLy8gZG9lc24ndCBoYW5kbGUgVVJMRW5jb2RlZCBEYXRhVVJJcyAtIHNlZSBTTyBhbnN3ZXIgIzY4NTAyNzYgZm9yIGNvZGUgdGhhdCBkb2VzIHRoaXNcbiAgdmFyIGJ5dGVTdHJpbmcgPSBhdG9iKGRhdGFVUkkuc3BsaXQoJywnKVsxXSk7XG5cbiAgLy8gc2VwYXJhdGUgb3V0IHRoZSBtaW1lIGNvbXBvbmVudFxuICB2YXIgbWltZVN0cmluZyA9IGRhdGFVUkkuc3BsaXQoJywnKVswXS5zcGxpdCgnOicpWzFdLnNwbGl0KCc7JylbMF1cblxuICAvLyB3cml0ZSB0aGUgYnl0ZXMgb2YgdGhlIHN0cmluZyB0byBhbiBBcnJheUJ1ZmZlclxuICB2YXIgYWIgPSBuZXcgQXJyYXlCdWZmZXIoYnl0ZVN0cmluZy5sZW5ndGgpO1xuXG4gIC8vIGNyZWF0ZSBhIHZpZXcgaW50byB0aGUgYnVmZmVyXG4gIHZhciBpYSA9IG5ldyBVaW50OEFycmF5KGFiKTtcblxuICAvLyBzZXQgdGhlIGJ5dGVzIG9mIHRoZSBidWZmZXIgdG8gdGhlIGNvcnJlY3QgdmFsdWVzXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZVN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgaWFbaV0gPSBieXRlU3RyaW5nLmNoYXJDb2RlQXQoaSk7XG4gIH1cblxuICAvLyB3cml0ZSB0aGUgQXJyYXlCdWZmZXIgdG8gYSBibG9iLCBhbmQgeW91J3JlIGRvbmVcbiAgdmFyIGJsb2IgPSBuZXcgQmxvYihbYWJdLCB7dHlwZTogbWltZVN0cmluZ30pO1xuICByZXR1cm4gYmxvYjtcblxufVxuZXhwb3J0IGZ1bmN0aW9uIGZ0b20oZikge1xuICAvLyByZXR1cm4gKE1hdGgubG9nKGYpIC0gTWF0aC5sb2coMjYxLjYyNikpIC8gTWF0aC5sb2coMikgKyA0LjBcbiAgcmV0dXJuIDY5ICsgMTIgKiBNYXRoLmxvZzIoZiAvIDQ0MClcbn1cbmV4cG9ydCBmdW5jdGlvbiBtdG9mKG0pIHtcbiAgcmV0dXJuIDQ0MCAqIE1hdGgucG93KDIsIChtIC0gNjkpIC8gMTIpXG59XG5leHBvcnQgZnVuY3Rpb24gdGFwIChmbikge1xuICByZXR1cm4gKGUpID0+IHtcbiAgICBpZiAoYnJvd3Nlci5pc01vYmlsZSkgZm4oKVxuICAgIGVsc2UgaWYgKGUucHJlc3MpIGZuKClcbiAgfVxufVxuXG4vKiBnZXQgbWluaW11bSBhbmQgbWF4aW11bSB2YXJpYW5jZSBmcm9tIHJvdy10by1yb3cgKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldF9kaWZmX2JvdW5kcyhyb3dzKXtcbiAgY29uc3QgZGlmZnMgPSByb3dzLm1hcChyb3cgPT4ge1xuICAgIGNvbnN0IHJvd19taW4gPSBNYXRoLm1pbi5hcHBseShNYXRoLCByb3cpXG4gICAgY29uc3Qgcm93X21heCA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIHJvdylcbiAgICByZXR1cm4gcm93X21heCAtIHJvd19taW5cbiAgfSlcbiAgY29uc3QgbWluID0gTWF0aC5taW4uYXBwbHkoTWF0aCwgZGlmZnMpXG4gIGNvbnN0IG1heCA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIGRpZmZzKVxuICByZXR1cm4geyBtaW4sIG1heCB9XG59XG5cbi8qIGdldCBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlcyBmcm9tIGEgZGF0YXNldCAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0X2JvdW5kcyhkYXRhc2V0KXtcbiAgbGV0IHJvd3MgPSBkYXRhc2V0LmxpbmVzXG4gIC8vIHJvd3MuZm9yRWFjaChyb3cgPT4gcm93LnNoaWZ0KCkpXG4gIHJvd3MgPSByb3dzLm1hcChhID0+IGEubWFwKG4gPT4gcGFyc2VGbG9hdChuKSkpXG4gIGNvbnN0IG1heCA9IHJvd3MucmVkdWNlKChhLGIpID0+IHtcbiAgICByZXR1cm4gYi5yZWR1Y2UoKHosYmIpID0+IHtcbiAgICAgIHJldHVybiBNYXRoLm1heCh6LCBiYilcbiAgICB9LCBhKVxuICB9LCAtSW5maW5pdHkpXG4gIGNvbnN0IG1pbiA9IHJvd3MucmVkdWNlKChhLGIpID0+IHtcbiAgICByZXR1cm4gYi5yZWR1Y2UoKHosYmIpID0+IHtcbiAgICAgIHJldHVybiBNYXRoLm1pbih6LCBiYilcbiAgICB9LCBhKVxuICB9LCBJbmZpbml0eSlcbiAgcmV0dXJuIHsgcm93cywgbWF4LCBtaW4gfVxufVxuXG4vKiB0cmFuc3Bvc2UgYSAyRCBhcnJheSAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNwb3NlKGEpIHtcbiAgbGV0IGlfbGVuID0gYVswXS5sZW5ndGhcbiAgbGV0IGpfbGVuID0gYS5sZW5ndGhcbiAgbGV0IFQgPSBuZXcgQXJyYXkoaV9sZW4pXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaV9sZW47IGkrKykge1xuICAgIFRbaV0gPSBuZXcgQXJyYXkoal9sZW4pXG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBqX2xlbjsgaisrKSB7XG4gICAgICBUW2ldW2pdID0gYVtqXVtpXVxuICAgIH1cbiAgfVxuICByZXR1cm4gVFxufVxuXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvbGliL3V0aWwuanMiLCIndXNlIHN0cmljdCc7XG5cbnZhciBidWZmZXIgPSByZXF1aXJlKCdidWZmZXInKTtcbnZhciBCdWZmZXIgPSBidWZmZXIuQnVmZmVyO1xudmFyIFNsb3dCdWZmZXIgPSBidWZmZXIuU2xvd0J1ZmZlcjtcbnZhciBNQVhfTEVOID0gYnVmZmVyLmtNYXhMZW5ndGggfHwgMjE0NzQ4MzY0NztcbmV4cG9ydHMuYWxsb2MgPSBmdW5jdGlvbiBhbGxvYyhzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIEJ1ZmZlci5hbGxvYyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBCdWZmZXIuYWxsb2Moc2l6ZSwgZmlsbCwgZW5jb2RpbmcpO1xuICB9XG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZW5jb2RpbmcgbXVzdCBub3QgYmUgbnVtYmVyJyk7XG4gIH1cbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3NpemUgbXVzdCBiZSBhIG51bWJlcicpO1xuICB9XG4gIGlmIChzaXplID4gTUFYX0xFTikge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdzaXplIGlzIHRvbyBsYXJnZScpO1xuICB9XG4gIHZhciBlbmMgPSBlbmNvZGluZztcbiAgdmFyIF9maWxsID0gZmlsbDtcbiAgaWYgKF9maWxsID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmMgPSB1bmRlZmluZWQ7XG4gICAgX2ZpbGwgPSAwO1xuICB9XG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKHNpemUpO1xuICBpZiAodHlwZW9mIF9maWxsID09PSAnc3RyaW5nJykge1xuICAgIHZhciBmaWxsQnVmID0gbmV3IEJ1ZmZlcihfZmlsbCwgZW5jKTtcbiAgICB2YXIgZmxlbiA9IGZpbGxCdWYubGVuZ3RoO1xuICAgIHZhciBpID0gLTE7XG4gICAgd2hpbGUgKCsraSA8IHNpemUpIHtcbiAgICAgIGJ1ZltpXSA9IGZpbGxCdWZbaSAlIGZsZW5dO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBidWYuZmlsbChfZmlsbCk7XG4gIH1cbiAgcmV0dXJuIGJ1Zjtcbn1cbmV4cG9ydHMuYWxsb2NVbnNhZmUgPSBmdW5jdGlvbiBhbGxvY1Vuc2FmZShzaXplKSB7XG4gIGlmICh0eXBlb2YgQnVmZmVyLmFsbG9jVW5zYWZlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvY1Vuc2FmZShzaXplKTtcbiAgfVxuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc2l6ZSBtdXN0IGJlIGEgbnVtYmVyJyk7XG4gIH1cbiAgaWYgKHNpemUgPiBNQVhfTEVOKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NpemUgaXMgdG9vIGxhcmdlJyk7XG4gIH1cbiAgcmV0dXJuIG5ldyBCdWZmZXIoc2l6ZSk7XG59XG5leHBvcnRzLmZyb20gPSBmdW5jdGlvbiBmcm9tKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKHR5cGVvZiBCdWZmZXIuZnJvbSA9PT0gJ2Z1bmN0aW9uJyAmJiAoIWdsb2JhbC5VaW50OEFycmF5IHx8IFVpbnQ4QXJyYXkuZnJvbSAhPT0gQnVmZmVyLmZyb20pKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJyk7XG4gIH1cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCk7XG4gIH1cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgIHZhciBvZmZzZXQgPSBlbmNvZGluZ09yT2Zmc2V0O1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZSk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgb2Zmc2V0ID0gMDtcbiAgICB9XG4gICAgdmFyIGxlbiA9IGxlbmd0aDtcbiAgICBpZiAodHlwZW9mIGxlbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGxlbiA9IHZhbHVlLmJ5dGVMZW5ndGggLSBvZmZzZXQ7XG4gICAgfVxuICAgIGlmIChvZmZzZXQgPj0gdmFsdWUuYnl0ZUxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ29mZnNldFxcJyBpcyBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmIChsZW4gPiB2YWx1ZS5ieXRlTGVuZ3RoIC0gb2Zmc2V0KSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnbGVuZ3RoXFwnIGlzIG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIodmFsdWUuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBsZW4pKTtcbiAgfVxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbHVlKSkge1xuICAgIHZhciBvdXQgPSBuZXcgQnVmZmVyKHZhbHVlLmxlbmd0aCk7XG4gICAgdmFsdWUuY29weShvdXQsIDAsIDAsIHZhbHVlLmxlbmd0aCk7XG4gICAgcmV0dXJuIG91dDtcbiAgfVxuICBpZiAodmFsdWUpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgfHwgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHx8ICdsZW5ndGgnIGluIHZhbHVlKSB7XG4gICAgICByZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZSk7XG4gICAgfVxuICAgIGlmICh2YWx1ZS50eXBlID09PSAnQnVmZmVyJyAmJiBBcnJheS5pc0FycmF5KHZhbHVlLmRhdGEpKSB7XG4gICAgICByZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZS5kYXRhKTtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nLCBCdWZmZXIsICcgKyAnQXJyYXlCdWZmZXIsIEFycmF5LCBvciBhcnJheS1saWtlIG9iamVjdC4nKTtcbn1cbmV4cG9ydHMuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gYWxsb2NVbnNhZmVTbG93KHNpemUpIHtcbiAgaWYgKHR5cGVvZiBCdWZmZXIuYWxsb2NVbnNhZmVTbG93ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3coc2l6ZSk7XG4gIH1cbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3NpemUgbXVzdCBiZSBhIG51bWJlcicpO1xuICB9XG4gIGlmIChzaXplID49IE1BWF9MRU4pIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc2l6ZSBpcyB0b28gbGFyZ2UnKTtcbiAgfVxuICByZXR1cm4gbmV3IFNsb3dCdWZmZXIoc2l6ZSk7XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vYnVmZmVyLXNoaW1zL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAzMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgaWYodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYSBmdW5jdGlvbiEnKTtcbiAgcmV0dXJuIGl0O1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2EtZnVuY3Rpb24uanNcbi8vIG1vZHVsZSBpZCA9IDMzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIGdldHRpbmcgdGFnIGZyb20gMTkuMS4zLjYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZygpXG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJylcbiAgLCBUQUcgPSByZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKVxuICAvLyBFUzMgd3JvbmcgaGVyZVxuICAsIEFSRyA9IGNvZihmdW5jdGlvbigpeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpID09ICdBcmd1bWVudHMnO1xuXG4vLyBmYWxsYmFjayBmb3IgSUUxMSBTY3JpcHQgQWNjZXNzIERlbmllZCBlcnJvclxudmFyIHRyeUdldCA9IGZ1bmN0aW9uKGl0LCBrZXkpe1xuICB0cnkge1xuICAgIHJldHVybiBpdFtrZXldO1xuICB9IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgdmFyIE8sIFQsIEI7XG4gIHJldHVybiBpdCA9PT0gdW5kZWZpbmVkID8gJ1VuZGVmaW5lZCcgOiBpdCA9PT0gbnVsbCA/ICdOdWxsJ1xuICAgIC8vIEBAdG9TdHJpbmdUYWcgY2FzZVxuICAgIDogdHlwZW9mIChUID0gdHJ5R2V0KE8gPSBPYmplY3QoaXQpLCBUQUcpKSA9PSAnc3RyaW5nJyA/IFRcbiAgICAvLyBidWlsdGluVGFnIGNhc2VcbiAgICA6IEFSRyA/IGNvZihPKVxuICAgIC8vIEVTMyBhcmd1bWVudHMgZmFsbGJhY2tcbiAgICA6IChCID0gY29mKE8pKSA9PSAnT2JqZWN0JyAmJiB0eXBlb2YgTy5jYWxsZWUgPT0gJ2Z1bmN0aW9uJyA/ICdBcmd1bWVudHMnIDogQjtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19jbGFzc29mLmpzXG4vLyBtb2R1bGUgaWQgPSAzNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyA3LjIuMSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGFyZ3VtZW50KVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIGlmKGl0ID09IHVuZGVmaW5lZCl0aHJvdyBUeXBlRXJyb3IoXCJDYW4ndCBjYWxsIG1ldGhvZCBvbiAgXCIgKyBpdCk7XG4gIHJldHVybiBpdDtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19kZWZpbmVkLmpzXG4vLyBtb2R1bGUgaWQgPSAzNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIGRvY3VtZW50ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuZG9jdW1lbnRcbiAgLy8gaW4gb2xkIElFIHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50IGlzICdvYmplY3QnXG4gICwgaXMgPSBpc09iamVjdChkb2N1bWVudCkgJiYgaXNPYmplY3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIGlzID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChpdCkgOiB7fTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19kb20tY3JlYXRlLmpzXG4vLyBtb2R1bGUgaWQgPSAzNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBJRSA4LSBkb24ndCBlbnVtIGJ1ZyBrZXlzXG5tb2R1bGUuZXhwb3J0cyA9IChcbiAgJ2NvbnN0cnVjdG9yLGhhc093blByb3BlcnR5LGlzUHJvdG90eXBlT2YscHJvcGVydHlJc0VudW1lcmFibGUsdG9Mb2NhbGVTdHJpbmcsdG9TdHJpbmcsdmFsdWVPZidcbikuc3BsaXQoJywnKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2VudW0tYnVnLWtleXMuanNcbi8vIG1vZHVsZSBpZCA9IDM3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImV4cG9ydHMuZiA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19vYmplY3QtZ29wcy5qc1xuLy8gbW9kdWxlIGlkID0gMzhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIHNoYXJlZCA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpKCdrZXlzJylcbiAgLCB1aWQgICAgPSByZXF1aXJlKCcuL191aWQnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oa2V5KXtcbiAgcmV0dXJuIHNoYXJlZFtrZXldIHx8IChzaGFyZWRba2V5XSA9IHVpZChrZXkpKTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19zaGFyZWQta2V5LmpzXG4vLyBtb2R1bGUgaWQgPSAzOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCBTSEFSRUQgPSAnX19jb3JlLWpzX3NoYXJlZF9fJ1xuICAsIHN0b3JlICA9IGdsb2JhbFtTSEFSRURdIHx8IChnbG9iYWxbU0hBUkVEXSA9IHt9KTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oa2V5KXtcbiAgcmV0dXJuIHN0b3JlW2tleV0gfHwgKHN0b3JlW2tleV0gPSB7fSk7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fc2hhcmVkLmpzXG4vLyBtb2R1bGUgaWQgPSA0MFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyA3LjEuNCBUb0ludGVnZXJcbnZhciBjZWlsICA9IE1hdGguY2VpbFxuICAsIGZsb29yID0gTWF0aC5mbG9vcjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gaXNOYU4oaXQgPSAraXQpID8gMCA6IChpdCA+IDAgPyBmbG9vciA6IGNlaWwpKGl0KTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL190by1pbnRlZ2VyLmpzXG4vLyBtb2R1bGUgaWQgPSA0MVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyA3LjEuMTUgVG9MZW5ndGhcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJylcbiAgLCBtaW4gICAgICAgPSBNYXRoLm1pbjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gaXQgPiAwID8gbWluKHRvSW50ZWdlcihpdCksIDB4MWZmZmZmZmZmZmZmZmYpIDogMDsgLy8gcG93KDIsIDUzKSAtIDEgPT0gOTAwNzE5OTI1NDc0MDk5MVxufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3RvLWxlbmd0aC5qc1xuLy8gbW9kdWxlIGlkID0gNDJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gNy4xLjEgVG9QcmltaXRpdmUoaW5wdXQgWywgUHJlZmVycmVkVHlwZV0pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbi8vIGluc3RlYWQgb2YgdGhlIEVTNiBzcGVjIHZlcnNpb24sIHdlIGRpZG4ndCBpbXBsZW1lbnQgQEB0b1ByaW1pdGl2ZSBjYXNlXG4vLyBhbmQgdGhlIHNlY29uZCBhcmd1bWVudCAtIGZsYWcgLSBwcmVmZXJyZWQgdHlwZSBpcyBhIHN0cmluZ1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCwgUyl7XG4gIGlmKCFpc09iamVjdChpdCkpcmV0dXJuIGl0O1xuICB2YXIgZm4sIHZhbDtcbiAgaWYoUyAmJiB0eXBlb2YgKGZuID0gaXQudG9TdHJpbmcpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSlyZXR1cm4gdmFsO1xuICBpZih0eXBlb2YgKGZuID0gaXQudmFsdWVPZikgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKXJldHVybiB2YWw7XG4gIGlmKCFTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKXJldHVybiB2YWw7XG4gIHRocm93IFR5cGVFcnJvcihcIkNhbid0IGNvbnZlcnQgb2JqZWN0IHRvIHByaW1pdGl2ZSB2YWx1ZVwiKTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL190by1wcmltaXRpdmUuanNcbi8vIG1vZHVsZSBpZCA9IDQzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBnbG9iYWwgICAgICAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgY29yZSAgICAgICAgICAgPSByZXF1aXJlKCcuL19jb3JlJylcbiAgLCBMSUJSQVJZICAgICAgICA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKVxuICAsIHdrc0V4dCAgICAgICAgID0gcmVxdWlyZSgnLi9fd2tzLWV4dCcpXG4gICwgZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihuYW1lKXtcbiAgdmFyICRTeW1ib2wgPSBjb3JlLlN5bWJvbCB8fCAoY29yZS5TeW1ib2wgPSBMSUJSQVJZID8ge30gOiBnbG9iYWwuU3ltYm9sIHx8IHt9KTtcbiAgaWYobmFtZS5jaGFyQXQoMCkgIT0gJ18nICYmICEobmFtZSBpbiAkU3ltYm9sKSlkZWZpbmVQcm9wZXJ0eSgkU3ltYm9sLCBuYW1lLCB7dmFsdWU6IHdrc0V4dC5mKG5hbWUpfSk7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fd2tzLWRlZmluZS5qc1xuLy8gbW9kdWxlIGlkID0gNDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fd2tzJyk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL193a3MtZXh0LmpzXG4vLyBtb2R1bGUgaWQgPSA0NVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgY2xhc3NvZiAgID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpXG4gICwgSVRFUkFUT1IgID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJylcbiAgLCBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29yZScpLmdldEl0ZXJhdG9yTWV0aG9kID0gZnVuY3Rpb24oaXQpe1xuICBpZihpdCAhPSB1bmRlZmluZWQpcmV0dXJuIGl0W0lURVJBVE9SXVxuICAgIHx8IGl0WydAQGl0ZXJhdG9yJ11cbiAgICB8fCBJdGVyYXRvcnNbY2xhc3NvZihpdCldO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kLmpzXG4vLyBtb2R1bGUgaWQgPSA0NlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICB0aGlzLl9ldmVudHMgPSB0aGlzLl9ldmVudHMgfHwge307XG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbkV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbi8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuLy8gdGhhdCB0byBiZSBpbmNyZWFzZWQuIFNldCB0byB6ZXJvIGZvciB1bmxpbWl0ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uKG4pIHtcbiAgaWYgKCFpc051bWJlcihuKSB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ24gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSBuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGVyLCBoYW5kbGVyLCBsZW4sIGFyZ3MsIGksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmICh0eXBlID09PSAnZXJyb3InKSB7XG4gICAgaWYgKCF0aGlzLl9ldmVudHMuZXJyb3IgfHxcbiAgICAgICAgKGlzT2JqZWN0KHRoaXMuX2V2ZW50cy5lcnJvcikgJiYgIXRoaXMuX2V2ZW50cy5lcnJvci5sZW5ndGgpKSB7XG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdVbmNhdWdodCwgdW5zcGVjaWZpZWQgXCJlcnJvclwiIGV2ZW50LiAoJyArIGVyICsgJyknKTtcbiAgICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGhhbmRsZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzVW5kZWZpbmVkKGhhbmRsZXIpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgLy8gZmFzdCBjYXNlc1xuICAgICAgY2FzZSAxOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoaGFuZGxlcikpIHtcbiAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICBsaXN0ZW5lcnMgPSBoYW5kbGVyLnNsaWNlKCk7XG4gICAgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lclwiLlxuICBpZiAodGhpcy5fZXZlbnRzLm5ld0xpc3RlbmVyKVxuICAgIHRoaXMuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICBpc0Z1bmN0aW9uKGxpc3RlbmVyLmxpc3RlbmVyKSA/XG4gICAgICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICBlbHNlIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gIGVsc2VcbiAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBbdGhpcy5fZXZlbnRzW3R5cGVdLCBsaXN0ZW5lcl07XG5cbiAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkgJiYgIXRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQpIHtcbiAgICBpZiAoIWlzVW5kZWZpbmVkKHRoaXMuX21heExpc3RlbmVycykpIHtcbiAgICAgIG0gPSB0aGlzLl9tYXhMaXN0ZW5lcnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgICB9XG5cbiAgICBpZiAobSAmJiBtID4gMCAmJiB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoID4gbSkge1xuICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCA9IHRydWU7XG4gICAgICBjb25zb2xlLmVycm9yKCcobm9kZSkgd2FybmluZzogcG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSAnICtcbiAgICAgICAgICAgICAgICAgICAgJ2xlYWsgZGV0ZWN0ZWQuICVkIGxpc3RlbmVycyBhZGRlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICdVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byBpbmNyZWFzZSBsaW1pdC4nLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoKTtcbiAgICAgIGlmICh0eXBlb2YgY29uc29sZS50cmFjZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBub3Qgc3VwcG9ydGVkIGluIElFIDEwXG4gICAgICAgIGNvbnNvbGUudHJhY2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgdmFyIGZpcmVkID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gZygpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGcpO1xuXG4gICAgaWYgKCFmaXJlZCkge1xuICAgICAgZmlyZWQgPSB0cnVlO1xuICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cblxuICBnLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHRoaXMub24odHlwZSwgZyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBlbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWZmIHRoZSBsaXN0ZW5lciB3YXMgcmVtb3ZlZFxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBsaXN0LCBwb3NpdGlvbiwgbGVuZ3RoLCBpO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIGxpc3QgPSB0aGlzLl9ldmVudHNbdHlwZV07XG4gIGxlbmd0aCA9IGxpc3QubGVuZ3RoO1xuICBwb3NpdGlvbiA9IC0xO1xuXG4gIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fFxuICAgICAgKGlzRnVuY3Rpb24obGlzdC5saXN0ZW5lcikgJiYgbGlzdC5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcblxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGxpc3QpKSB7XG4gICAgZm9yIChpID0gbGVuZ3RoOyBpLS0gPiAwOykge1xuICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8XG4gICAgICAgICAgKGxpc3RbaV0ubGlzdGVuZXIgJiYgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgICBsaXN0Lmxlbmd0aCA9IDA7XG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaXN0LnNwbGljZShwb3NpdGlvbiwgMSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIga2V5LCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICBpZiAoIXRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxuICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgZWxzZSBpZiAodGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIGZvciAoa2V5IGluIHRoaXMuX2V2ZW50cykge1xuICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgIH1cbiAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNGdW5jdGlvbihsaXN0ZW5lcnMpKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgIC8vIExJRk8gb3JkZXJcbiAgICB3aGlsZSAobGlzdGVuZXJzLmxlbmd0aClcbiAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXSk7XG4gIH1cbiAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgcmV0O1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldCA9IFtdO1xuICBlbHNlIGlmIChpc0Z1bmN0aW9uKHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgcmV0ID0gW3RoaXMuX2V2ZW50c1t0eXBlXV07XG4gIGVsc2VcbiAgICByZXQgPSB0aGlzLl9ldmVudHNbdHlwZV0uc2xpY2UoKTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgaWYgKHRoaXMuX2V2ZW50cykge1xuICAgIHZhciBldmxpc3RlbmVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKGlzRnVuY3Rpb24oZXZsaXN0ZW5lcikpXG4gICAgICByZXR1cm4gMTtcbiAgICBlbHNlIGlmIChldmxpc3RlbmVyKVxuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICB9XG4gIHJldHVybiAwO1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG59O1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vZXZlbnRzL2V2ZW50cy5qc1xuLy8gbW9kdWxlIGlkID0gNDdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbnZhciBpc0J1ZmZlckVuY29kaW5nID0gQnVmZmVyLmlzRW5jb2RpbmdcbiAgfHwgZnVuY3Rpb24oZW5jb2RpbmcpIHtcbiAgICAgICBzd2l0Y2ggKGVuY29kaW5nICYmIGVuY29kaW5nLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgIGNhc2UgJ2hleCc6IGNhc2UgJ3V0ZjgnOiBjYXNlICd1dGYtOCc6IGNhc2UgJ2FzY2lpJzogY2FzZSAnYmluYXJ5JzogY2FzZSAnYmFzZTY0JzogY2FzZSAndWNzMic6IGNhc2UgJ3Vjcy0yJzogY2FzZSAndXRmMTZsZSc6IGNhc2UgJ3V0Zi0xNmxlJzogY2FzZSAncmF3JzogcmV0dXJuIHRydWU7XG4gICAgICAgICBkZWZhdWx0OiByZXR1cm4gZmFsc2U7XG4gICAgICAgfVxuICAgICB9XG5cblxuZnVuY3Rpb24gYXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgaWYgKGVuY29kaW5nICYmICFpc0J1ZmZlckVuY29kaW5nKGVuY29kaW5nKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKTtcbiAgfVxufVxuXG4vLyBTdHJpbmdEZWNvZGVyIHByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgZWZmaWNpZW50bHkgc3BsaXR0aW5nIGEgc2VyaWVzIG9mXG4vLyBidWZmZXJzIGludG8gYSBzZXJpZXMgb2YgSlMgc3RyaW5ncyB3aXRob3V0IGJyZWFraW5nIGFwYXJ0IG11bHRpLWJ5dGVcbi8vIGNoYXJhY3RlcnMuIENFU1UtOCBpcyBoYW5kbGVkIGFzIHBhcnQgb2YgdGhlIFVURi04IGVuY29kaW5nLlxuLy9cbi8vIEBUT0RPIEhhbmRsaW5nIGFsbCBlbmNvZGluZ3MgaW5zaWRlIGEgc2luZ2xlIG9iamVjdCBtYWtlcyBpdCB2ZXJ5IGRpZmZpY3VsdFxuLy8gdG8gcmVhc29uIGFib3V0IHRoaXMgY29kZSwgc28gaXQgc2hvdWxkIGJlIHNwbGl0IHVwIGluIHRoZSBmdXR1cmUuXG4vLyBAVE9ETyBUaGVyZSBzaG91bGQgYmUgYSB1dGY4LXN0cmljdCBlbmNvZGluZyB0aGF0IHJlamVjdHMgaW52YWxpZCBVVEYtOCBjb2RlXG4vLyBwb2ludHMgYXMgdXNlZCBieSBDRVNVLTguXG52YXIgU3RyaW5nRGVjb2RlciA9IGV4cG9ydHMuU3RyaW5nRGVjb2RlciA9IGZ1bmN0aW9uKGVuY29kaW5nKSB7XG4gIHRoaXMuZW5jb2RpbmcgPSAoZW5jb2RpbmcgfHwgJ3V0ZjgnKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1stX10vLCAnJyk7XG4gIGFzc2VydEVuY29kaW5nKGVuY29kaW5nKTtcbiAgc3dpdGNoICh0aGlzLmVuY29kaW5nKSB7XG4gICAgY2FzZSAndXRmOCc6XG4gICAgICAvLyBDRVNVLTggcmVwcmVzZW50cyBlYWNoIG9mIFN1cnJvZ2F0ZSBQYWlyIGJ5IDMtYnl0ZXNcbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDM7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIC8vIFVURi0xNiByZXByZXNlbnRzIGVhY2ggb2YgU3Vycm9nYXRlIFBhaXIgYnkgMi1ieXRlc1xuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMjtcbiAgICAgIHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIC8vIEJhc2UtNjQgc3RvcmVzIDMgYnl0ZXMgaW4gNCBjaGFycywgYW5kIHBhZHMgdGhlIHJlbWFpbmRlci5cbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDM7XG4gICAgICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyID0gYmFzZTY0RGV0ZWN0SW5jb21wbGV0ZUNoYXI7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhpcy53cml0ZSA9IHBhc3NUaHJvdWdoV3JpdGU7XG4gICAgICByZXR1cm47XG4gIH1cblxuICAvLyBFbm91Z2ggc3BhY2UgdG8gc3RvcmUgYWxsIGJ5dGVzIG9mIGEgc2luZ2xlIGNoYXJhY3Rlci4gVVRGLTggbmVlZHMgNFxuICAvLyBieXRlcywgYnV0IENFU1UtOCBtYXkgcmVxdWlyZSB1cCB0byA2ICgzIGJ5dGVzIHBlciBzdXJyb2dhdGUpLlxuICB0aGlzLmNoYXJCdWZmZXIgPSBuZXcgQnVmZmVyKDYpO1xuICAvLyBOdW1iZXIgb2YgYnl0ZXMgcmVjZWl2ZWQgZm9yIHRoZSBjdXJyZW50IGluY29tcGxldGUgbXVsdGktYnl0ZSBjaGFyYWN0ZXIuXG4gIHRoaXMuY2hhclJlY2VpdmVkID0gMDtcbiAgLy8gTnVtYmVyIG9mIGJ5dGVzIGV4cGVjdGVkIGZvciB0aGUgY3VycmVudCBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgY2hhcmFjdGVyLlxuICB0aGlzLmNoYXJMZW5ndGggPSAwO1xufTtcblxuXG4vLyB3cml0ZSBkZWNvZGVzIHRoZSBnaXZlbiBidWZmZXIgYW5kIHJldHVybnMgaXQgYXMgSlMgc3RyaW5nIHRoYXQgaXNcbi8vIGd1YXJhbnRlZWQgdG8gbm90IGNvbnRhaW4gYW55IHBhcnRpYWwgbXVsdGktYnl0ZSBjaGFyYWN0ZXJzLiBBbnkgcGFydGlhbFxuLy8gY2hhcmFjdGVyIGZvdW5kIGF0IHRoZSBlbmQgb2YgdGhlIGJ1ZmZlciBpcyBidWZmZXJlZCB1cCwgYW5kIHdpbGwgYmVcbi8vIHJldHVybmVkIHdoZW4gY2FsbGluZyB3cml0ZSBhZ2FpbiB3aXRoIHRoZSByZW1haW5pbmcgYnl0ZXMuXG4vL1xuLy8gTm90ZTogQ29udmVydGluZyBhIEJ1ZmZlciBjb250YWluaW5nIGFuIG9ycGhhbiBzdXJyb2dhdGUgdG8gYSBTdHJpbmdcbi8vIGN1cnJlbnRseSB3b3JrcywgYnV0IGNvbnZlcnRpbmcgYSBTdHJpbmcgdG8gYSBCdWZmZXIgKHZpYSBgbmV3IEJ1ZmZlcmAsIG9yXG4vLyBCdWZmZXIjd3JpdGUpIHdpbGwgcmVwbGFjZSBpbmNvbXBsZXRlIHN1cnJvZ2F0ZXMgd2l0aCB0aGUgdW5pY29kZVxuLy8gcmVwbGFjZW1lbnQgY2hhcmFjdGVyLiBTZWUgaHR0cHM6Ly9jb2RlcmV2aWV3LmNocm9taXVtLm9yZy8xMjExNzMwMDkvIC5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gIHZhciBjaGFyU3RyID0gJyc7XG4gIC8vIGlmIG91ciBsYXN0IHdyaXRlIGVuZGVkIHdpdGggYW4gaW5jb21wbGV0ZSBtdWx0aWJ5dGUgY2hhcmFjdGVyXG4gIHdoaWxlICh0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAvLyBkZXRlcm1pbmUgaG93IG1hbnkgcmVtYWluaW5nIGJ5dGVzIHRoaXMgYnVmZmVyIGhhcyB0byBvZmZlciBmb3IgdGhpcyBjaGFyXG4gICAgdmFyIGF2YWlsYWJsZSA9IChidWZmZXIubGVuZ3RoID49IHRoaXMuY2hhckxlbmd0aCAtIHRoaXMuY2hhclJlY2VpdmVkKSA/XG4gICAgICAgIHRoaXMuY2hhckxlbmd0aCAtIHRoaXMuY2hhclJlY2VpdmVkIDpcbiAgICAgICAgYnVmZmVyLmxlbmd0aDtcblxuICAgIC8vIGFkZCB0aGUgbmV3IGJ5dGVzIHRvIHRoZSBjaGFyIGJ1ZmZlclxuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgdGhpcy5jaGFyUmVjZWl2ZWQsIDAsIGF2YWlsYWJsZSk7XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgKz0gYXZhaWxhYmxlO1xuXG4gICAgaWYgKHRoaXMuY2hhclJlY2VpdmVkIDwgdGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgICAvLyBzdGlsbCBub3QgZW5vdWdoIGNoYXJzIGluIHRoaXMgYnVmZmVyPyB3YWl0IGZvciBtb3JlIC4uLlxuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIC8vIHJlbW92ZSBieXRlcyBiZWxvbmdpbmcgdG8gdGhlIGN1cnJlbnQgY2hhcmFjdGVyIGZyb20gdGhlIGJ1ZmZlclxuICAgIGJ1ZmZlciA9IGJ1ZmZlci5zbGljZShhdmFpbGFibGUsIGJ1ZmZlci5sZW5ndGgpO1xuXG4gICAgLy8gZ2V0IHRoZSBjaGFyYWN0ZXIgdGhhdCB3YXMgc3BsaXRcbiAgICBjaGFyU3RyID0gdGhpcy5jaGFyQnVmZmVyLnNsaWNlKDAsIHRoaXMuY2hhckxlbmd0aCkudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG5cbiAgICAvLyBDRVNVLTg6IGxlYWQgc3Vycm9nYXRlIChEODAwLURCRkYpIGlzIGFsc28gdGhlIGluY29tcGxldGUgY2hhcmFjdGVyXG4gICAgdmFyIGNoYXJDb2RlID0gY2hhclN0ci5jaGFyQ29kZUF0KGNoYXJTdHIubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGNoYXJDb2RlID49IDB4RDgwMCAmJiBjaGFyQ29kZSA8PSAweERCRkYpIHtcbiAgICAgIHRoaXMuY2hhckxlbmd0aCArPSB0aGlzLnN1cnJvZ2F0ZVNpemU7XG4gICAgICBjaGFyU3RyID0gJyc7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgPSB0aGlzLmNoYXJMZW5ndGggPSAwO1xuXG4gICAgLy8gaWYgdGhlcmUgYXJlIG5vIG1vcmUgYnl0ZXMgaW4gdGhpcyBidWZmZXIsIGp1c3QgZW1pdCBvdXIgY2hhclxuICAgIGlmIChidWZmZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gY2hhclN0cjtcbiAgICB9XG4gICAgYnJlYWs7XG4gIH1cblxuICAvLyBkZXRlcm1pbmUgYW5kIHNldCBjaGFyTGVuZ3RoIC8gY2hhclJlY2VpdmVkXG4gIHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKTtcblxuICB2YXIgZW5kID0gYnVmZmVyLmxlbmd0aDtcbiAgaWYgKHRoaXMuY2hhckxlbmd0aCkge1xuICAgIC8vIGJ1ZmZlciB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXIgYnl0ZXMgd2UgZ290XG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCAwLCBidWZmZXIubGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQsIGVuZCk7XG4gICAgZW5kIC09IHRoaXMuY2hhclJlY2VpdmVkO1xuICB9XG5cbiAgY2hhclN0ciArPSBidWZmZXIudG9TdHJpbmcodGhpcy5lbmNvZGluZywgMCwgZW5kKTtcblxuICB2YXIgZW5kID0gY2hhclN0ci5sZW5ndGggLSAxO1xuICB2YXIgY2hhckNvZGUgPSBjaGFyU3RyLmNoYXJDb2RlQXQoZW5kKTtcbiAgLy8gQ0VTVS04OiBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICBpZiAoY2hhckNvZGUgPj0gMHhEODAwICYmIGNoYXJDb2RlIDw9IDB4REJGRikge1xuICAgIHZhciBzaXplID0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgIHRoaXMuY2hhckxlbmd0aCArPSBzaXplO1xuICAgIHRoaXMuY2hhclJlY2VpdmVkICs9IHNpemU7XG4gICAgdGhpcy5jaGFyQnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCBzaXplLCAwLCBzaXplKTtcbiAgICBidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIDAsIDAsIHNpemUpO1xuICAgIHJldHVybiBjaGFyU3RyLnN1YnN0cmluZygwLCBlbmQpO1xuICB9XG5cbiAgLy8gb3IganVzdCBlbWl0IHRoZSBjaGFyU3RyXG4gIHJldHVybiBjaGFyU3RyO1xufTtcblxuLy8gZGV0ZWN0SW5jb21wbGV0ZUNoYXIgZGV0ZXJtaW5lcyBpZiB0aGVyZSBpcyBhbiBpbmNvbXBsZXRlIFVURi04IGNoYXJhY3RlciBhdFxuLy8gdGhlIGVuZCBvZiB0aGUgZ2l2ZW4gYnVmZmVyLiBJZiBzbywgaXQgc2V0cyB0aGlzLmNoYXJMZW5ndGggdG8gdGhlIGJ5dGVcbi8vIGxlbmd0aCB0aGF0IGNoYXJhY3RlciwgYW5kIHNldHMgdGhpcy5jaGFyUmVjZWl2ZWQgdG8gdGhlIG51bWJlciBvZiBieXRlc1xuLy8gdGhhdCBhcmUgYXZhaWxhYmxlIGZvciB0aGlzIGNoYXJhY3Rlci5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmRldGVjdEluY29tcGxldGVDaGFyID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gIC8vIGRldGVybWluZSBob3cgbWFueSBieXRlcyB3ZSBoYXZlIHRvIGNoZWNrIGF0IHRoZSBlbmQgb2YgdGhpcyBidWZmZXJcbiAgdmFyIGkgPSAoYnVmZmVyLmxlbmd0aCA+PSAzKSA/IDMgOiBidWZmZXIubGVuZ3RoO1xuXG4gIC8vIEZpZ3VyZSBvdXQgaWYgb25lIG9mIHRoZSBsYXN0IGkgYnl0ZXMgb2Ygb3VyIGJ1ZmZlciBhbm5vdW5jZXMgYW5cbiAgLy8gaW5jb21wbGV0ZSBjaGFyLlxuICBmb3IgKDsgaSA+IDA7IGktLSkge1xuICAgIHZhciBjID0gYnVmZmVyW2J1ZmZlci5sZW5ndGggLSBpXTtcblxuICAgIC8vIFNlZSBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1VURi04I0Rlc2NyaXB0aW9uXG5cbiAgICAvLyAxMTBYWFhYWFxuICAgIGlmIChpID09IDEgJiYgYyA+PiA1ID09IDB4MDYpIHtcbiAgICAgIHRoaXMuY2hhckxlbmd0aCA9IDI7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyAxMTEwWFhYWFxuICAgIGlmIChpIDw9IDIgJiYgYyA+PiA0ID09IDB4MEUpIHtcbiAgICAgIHRoaXMuY2hhckxlbmd0aCA9IDM7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyAxMTExMFhYWFxuICAgIGlmIChpIDw9IDMgJiYgYyA+PiAzID09IDB4MUUpIHtcbiAgICAgIHRoaXMuY2hhckxlbmd0aCA9IDQ7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSBpO1xufTtcblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gIHZhciByZXMgPSAnJztcbiAgaWYgKGJ1ZmZlciAmJiBidWZmZXIubGVuZ3RoKVxuICAgIHJlcyA9IHRoaXMud3JpdGUoYnVmZmVyKTtcblxuICBpZiAodGhpcy5jaGFyUmVjZWl2ZWQpIHtcbiAgICB2YXIgY3IgPSB0aGlzLmNoYXJSZWNlaXZlZDtcbiAgICB2YXIgYnVmID0gdGhpcy5jaGFyQnVmZmVyO1xuICAgIHZhciBlbmMgPSB0aGlzLmVuY29kaW5nO1xuICAgIHJlcyArPSBidWYuc2xpY2UoMCwgY3IpLnRvU3RyaW5nKGVuYyk7XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcblxuZnVuY3Rpb24gcGFzc1Rocm91Z2hXcml0ZShidWZmZXIpIHtcbiAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nKTtcbn1cblxuZnVuY3Rpb24gdXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpIHtcbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSBidWZmZXIubGVuZ3RoICUgMjtcbiAgdGhpcy5jaGFyTGVuZ3RoID0gdGhpcy5jaGFyUmVjZWl2ZWQgPyAyIDogMDtcbn1cblxuZnVuY3Rpb24gYmFzZTY0RGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKSB7XG4gIHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDM7XG4gIHRoaXMuY2hhckxlbmd0aCA9IHRoaXMuY2hhclJlY2VpdmVkID8gMyA6IDA7XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vbm9kZS1saWJzLWJyb3dzZXIvfi9zdHJpbmdfZGVjb2Rlci9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gNDhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiJ3VzZSBzdHJpY3QnO1xuXG5pZiAoIXByb2Nlc3MudmVyc2lvbiB8fFxuICAgIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MC4nKSA9PT0gMCB8fFxuICAgIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MS4nKSA9PT0gMCAmJiBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjEuOC4nKSAhPT0gMCkge1xuICBtb2R1bGUuZXhwb3J0cyA9IG5leHRUaWNrO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBwcm9jZXNzLm5leHRUaWNrO1xufVxuXG5mdW5jdGlvbiBuZXh0VGljayhmbiwgYXJnMSwgYXJnMiwgYXJnMykge1xuICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJjYWxsYmFja1wiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB9XG4gIHZhciBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICB2YXIgYXJncywgaTtcbiAgc3dpdGNoIChsZW4pIHtcbiAgY2FzZSAwOlxuICBjYXNlIDE6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZm4pO1xuICBjYXNlIDI6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrT25lKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxKTtcbiAgICB9KTtcbiAgY2FzZSAzOlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1R3bygpIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgYXJnMSwgYXJnMik7XG4gICAgfSk7XG4gIGNhc2UgNDpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tUaHJlZSgpIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gICAgfSk7XG4gIGRlZmF1bHQ6XG4gICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICBpID0gMDtcbiAgICB3aGlsZSAoaSA8IGFyZ3MubGVuZ3RoKSB7XG4gICAgICBhcmdzW2krK10gPSBhcmd1bWVudHNbaV07XG4gICAgfVxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGljaygpIHtcbiAgICAgIGZuLmFwcGx5KG51bGwsIGFyZ3MpO1xuICAgIH0pO1xuICB9XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vcHJvY2Vzcy1uZXh0aWNrLWFyZ3MvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDQ5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIEEgYml0IHNpbXBsZXIgdGhhbiByZWFkYWJsZSBzdHJlYW1zLlxuLy8gSW1wbGVtZW50IGFuIGFzeW5jIC5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBjYiksIGFuZCBpdCdsbCBoYW5kbGUgYWxsXG4vLyB0aGUgZHJhaW4gZXZlbnQgZW1pc3Npb24gYW5kIGJ1ZmZlcmluZy5cblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdyaXRhYmxlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHByb2Nlc3NOZXh0VGljayA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBhc3luY1dyaXRlID0gIXByb2Nlc3MuYnJvd3NlciAmJiBbJ3YwLjEwJywgJ3YwLjkuJ10uaW5kZXhPZihwcm9jZXNzLnZlcnNpb24uc2xpY2UoMCwgNSkpID4gLTEgPyBzZXRJbW1lZGlhdGUgOiBwcm9jZXNzTmV4dFRpY2s7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBEdXBsZXg7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuV3JpdGFibGUuV3JpdGFibGVTdGF0ZSA9IFdyaXRhYmxlU3RhdGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpbnRlcm5hbFV0aWwgPSB7XG4gIGRlcHJlY2F0ZTogcmVxdWlyZSgndXRpbC1kZXByZWNhdGUnKVxufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0nKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBidWZmZXJTaGltID0gcmVxdWlyZSgnYnVmZmVyLXNoaW1zJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhXcml0YWJsZSwgU3RyZWFtKTtcblxuZnVuY3Rpb24gbm9wKCkge31cblxuZnVuY3Rpb24gV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aGlzLmNodW5rID0gY2h1bms7XG4gIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgdGhpcy5jYWxsYmFjayA9IGNiO1xuICB0aGlzLm5leHQgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCB0aGlzIHN0cmVhbVxuICAvLyBjb250YWlucyBidWZmZXJzIG9yIG9iamVjdHMuXG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXgpIHRoaXMub2JqZWN0TW9kZSA9IHRoaXMub2JqZWN0TW9kZSB8fCAhIW9wdGlvbnMud3JpdGFibGVPYmplY3RNb2RlO1xuXG4gIC8vIHRoZSBwb2ludCBhdCB3aGljaCB3cml0ZSgpIHN0YXJ0cyByZXR1cm5pbmcgZmFsc2VcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyB0aGF0IHdlIGFsd2F5cyByZXR1cm4gZmFsc2UgaWZcbiAgLy8gdGhlIGVudGlyZSBidWZmZXIgaXMgbm90IGZsdXNoZWQgaW1tZWRpYXRlbHkgb24gd3JpdGUoKVxuICB2YXIgaHdtID0gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrO1xuICB2YXIgZGVmYXVsdEh3bSA9IHRoaXMub2JqZWN0TW9kZSA/IDE2IDogMTYgKiAxMDI0O1xuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSBod20gfHwgaHdtID09PSAwID8gaHdtIDogZGVmYXVsdEh3bTtcblxuICAvLyBjYXN0IHRvIGludHMuXG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IH5+dGhpcy5oaWdoV2F0ZXJNYXJrO1xuXG4gIC8vIGRyYWluIGV2ZW50IGZsYWcuXG4gIHRoaXMubmVlZERyYWluID0gZmFsc2U7XG4gIC8vIGF0IHRoZSBzdGFydCBvZiBjYWxsaW5nIGVuZCgpXG4gIHRoaXMuZW5kaW5nID0gZmFsc2U7XG4gIC8vIHdoZW4gZW5kKCkgaGFzIGJlZW4gY2FsbGVkLCBhbmQgcmV0dXJuZWRcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAvLyB3aGVuICdmaW5pc2gnIGlzIGVtaXR0ZWRcbiAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIHNob3VsZCB3ZSBkZWNvZGUgc3RyaW5ncyBpbnRvIGJ1ZmZlcnMgYmVmb3JlIHBhc3NpbmcgdG8gX3dyaXRlP1xuICAvLyB0aGlzIGlzIGhlcmUgc28gdGhhdCBzb21lIG5vZGUtY29yZSBzdHJlYW1zIGNhbiBvcHRpbWl6ZSBzdHJpbmdcbiAgLy8gaGFuZGxpbmcgYXQgYSBsb3dlciBsZXZlbC5cbiAgdmFyIG5vRGVjb2RlID0gb3B0aW9ucy5kZWNvZGVTdHJpbmdzID09PSBmYWxzZTtcbiAgdGhpcy5kZWNvZGVTdHJpbmdzID0gIW5vRGVjb2RlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIG5vdCBhbiBhY3R1YWwgYnVmZmVyIHdlIGtlZXAgdHJhY2sgb2YsIGJ1dCBhIG1lYXN1cmVtZW50XG4gIC8vIG9mIGhvdyBtdWNoIHdlJ3JlIHdhaXRpbmcgdG8gZ2V0IHB1c2hlZCB0byBzb21lIHVuZGVybHlpbmdcbiAgLy8gc29ja2V0IG9yIGZpbGUuXG4gIHRoaXMubGVuZ3RoID0gMDtcblxuICAvLyBhIGZsYWcgdG8gc2VlIHdoZW4gd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIHdyaXRlLlxuICB0aGlzLndyaXRpbmcgPSBmYWxzZTtcblxuICAvLyB3aGVuIHRydWUgYWxsIHdyaXRlcyB3aWxsIGJlIGJ1ZmZlcmVkIHVudGlsIC51bmNvcmsoKSBjYWxsXG4gIHRoaXMuY29ya2VkID0gMDtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyBhIGZsYWcgdG8ga25vdyBpZiB3ZSdyZSBwcm9jZXNzaW5nIHByZXZpb3VzbHkgYnVmZmVyZWQgaXRlbXMsIHdoaWNoXG4gIC8vIG1heSBjYWxsIHRoZSBfd3JpdGUoKSBjYWxsYmFjayBpbiB0aGUgc2FtZSB0aWNrLCBzbyB0aGF0IHdlIGRvbid0XG4gIC8vIGVuZCB1cCBpbiBhbiBvdmVybGFwcGVkIG9ud3JpdGUgc2l0dWF0aW9uLlxuICB0aGlzLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCdzIHBhc3NlZCB0byBfd3JpdGUoY2h1bmssY2IpXG4gIHRoaXMub253cml0ZSA9IGZ1bmN0aW9uIChlcikge1xuICAgIG9ud3JpdGUoc3RyZWFtLCBlcik7XG4gIH07XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQgdGhlIHVzZXIgc3VwcGxpZXMgdG8gd3JpdGUoY2h1bmssZW5jb2RpbmcsY2IpXG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG5cbiAgLy8gdGhlIGFtb3VudCB0aGF0IGlzIGJlaW5nIHdyaXR0ZW4gd2hlbiBfd3JpdGUgaXMgY2FsbGVkLlxuICB0aGlzLndyaXRlbGVuID0gMDtcblxuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIHRoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG5cbiAgLy8gbnVtYmVyIG9mIHBlbmRpbmcgdXNlci1zdXBwbGllZCB3cml0ZSBjYWxsYmFja3NcbiAgLy8gdGhpcyBtdXN0IGJlIDAgYmVmb3JlICdmaW5pc2gnIGNhbiBiZSBlbWl0dGVkXG4gIHRoaXMucGVuZGluZ2NiID0gMDtcblxuICAvLyBlbWl0IHByZWZpbmlzaCBpZiB0aGUgb25seSB0aGluZyB3ZSdyZSB3YWl0aW5nIGZvciBpcyBfd3JpdGUgY2JzXG4gIC8vIFRoaXMgaXMgcmVsZXZhbnQgZm9yIHN5bmNocm9ub3VzIFRyYW5zZm9ybSBzdHJlYW1zXG4gIHRoaXMucHJlZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBUcnVlIGlmIHRoZSBlcnJvciB3YXMgYWxyZWFkeSBlbWl0dGVkIGFuZCBzaG91bGQgbm90IGJlIHRocm93biBhZ2FpblxuICB0aGlzLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuXG4gIC8vIGNvdW50IGJ1ZmZlcmVkIHJlcXVlc3RzXG4gIHRoaXMuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuXG4gIC8vIGFsbG9jYXRlIHRoZSBmaXJzdCBDb3JrZWRSZXF1ZXN0LCB0aGVyZSBpcyBhbHdheXNcbiAgLy8gb25lIGFsbG9jYXRlZCBhbmQgZnJlZSB0byB1c2UsIGFuZCB3ZSBtYWludGFpbiBhdCBtb3N0IHR3b1xuICB0aGlzLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHRoaXMpO1xufVxuXG5Xcml0YWJsZVN0YXRlLnByb3RvdHlwZS5nZXRCdWZmZXIgPSBmdW5jdGlvbiBnZXRCdWZmZXIoKSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5idWZmZXJlZFJlcXVlc3Q7XG4gIHZhciBvdXQgPSBbXTtcbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICBvdXQucHVzaChjdXJyZW50KTtcbiAgICBjdXJyZW50ID0gY3VycmVudC5uZXh0O1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG4oZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0YXRlLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcbiAgICAgIGdldDogaW50ZXJuYWxVdGlsLmRlcHJlY2F0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJ1ZmZlcigpO1xuICAgICAgfSwgJ193cml0YWJsZVN0YXRlLmJ1ZmZlciBpcyBkZXByZWNhdGVkLiBVc2UgX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyICcgKyAnaW5zdGVhZC4nKVxuICAgIH0pO1xuICB9IGNhdGNoIChfKSB7fVxufSkoKTtcblxuLy8gVGVzdCBfd3JpdGFibGVTdGF0ZSBmb3IgaW5oZXJpdGFuY2UgdG8gYWNjb3VudCBmb3IgRHVwbGV4IHN0cmVhbXMsXG4vLyB3aG9zZSBwcm90b3R5cGUgY2hhaW4gb25seSBwb2ludHMgdG8gUmVhZGFibGUuXG52YXIgcmVhbEhhc0luc3RhbmNlO1xuaWYgKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgU3ltYm9sLmhhc0luc3RhbmNlICYmIHR5cGVvZiBGdW5jdGlvbi5wcm90b3R5cGVbU3ltYm9sLmhhc0luc3RhbmNlXSA9PT0gJ2Z1bmN0aW9uJykge1xuICByZWFsSGFzSW5zdGFuY2UgPSBGdW5jdGlvbi5wcm90b3R5cGVbU3ltYm9sLmhhc0luc3RhbmNlXTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlLCBTeW1ib2wuaGFzSW5zdGFuY2UsIHtcbiAgICB2YWx1ZTogZnVuY3Rpb24gKG9iamVjdCkge1xuICAgICAgaWYgKHJlYWxIYXNJbnN0YW5jZS5jYWxsKHRoaXMsIG9iamVjdCkpIHJldHVybiB0cnVlO1xuXG4gICAgICByZXR1cm4gb2JqZWN0ICYmIG9iamVjdC5fd3JpdGFibGVTdGF0ZSBpbnN0YW5jZW9mIFdyaXRhYmxlU3RhdGU7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIHJlYWxIYXNJbnN0YW5jZSA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgdGhpcztcbiAgfTtcbn1cblxuZnVuY3Rpb24gV3JpdGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIC8vIFdyaXRhYmxlIGN0b3IgaXMgYXBwbGllZCB0byBEdXBsZXhlcywgdG9vLlxuICAvLyBgcmVhbEhhc0luc3RhbmNlYCBpcyBuZWNlc3NhcnkgYmVjYXVzZSB1c2luZyBwbGFpbiBgaW5zdGFuY2VvZmBcbiAgLy8gd291bGQgcmV0dXJuIGZhbHNlLCBhcyBubyBgX3dyaXRhYmxlU3RhdGVgIHByb3BlcnR5IGlzIGF0dGFjaGVkLlxuXG4gIC8vIFRyeWluZyB0byB1c2UgdGhlIGN1c3RvbSBgaW5zdGFuY2VvZmAgZm9yIFdyaXRhYmxlIGhlcmUgd2lsbCBhbHNvIGJyZWFrIHRoZVxuICAvLyBOb2RlLmpzIExhenlUcmFuc2Zvcm0gaW1wbGVtZW50YXRpb24sIHdoaWNoIGhhcyBhIG5vbi10cml2aWFsIGdldHRlciBmb3JcbiAgLy8gYF93cml0YWJsZVN0YXRlYCB0aGF0IHdvdWxkIGxlYWQgdG8gaW5maW5pdGUgcmVjdXJzaW9uLlxuICBpZiAoIXJlYWxIYXNJbnN0YW5jZS5jYWxsKFdyaXRhYmxlLCB0aGlzKSAmJiAhKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKSB7XG4gICAgcmV0dXJuIG5ldyBXcml0YWJsZShvcHRpb25zKTtcbiAgfVxuXG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUgPSBuZXcgV3JpdGFibGVTdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyBsZWdhY3kuXG4gIHRoaXMud3JpdGFibGUgPSB0cnVlO1xuXG4gIGlmIChvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRlID09PSAnZnVuY3Rpb24nKSB0aGlzLl93cml0ZSA9IG9wdGlvbnMud3JpdGU7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMud3JpdGV2ID09PSAnZnVuY3Rpb24nKSB0aGlzLl93cml0ZXYgPSBvcHRpb25zLndyaXRldjtcbiAgfVxuXG4gIFN0cmVhbS5jYWxsKHRoaXMpO1xufVxuXG4vLyBPdGhlcndpc2UgcGVvcGxlIGNhbiBwaXBlIFdyaXRhYmxlIHN0cmVhbXMsIHdoaWNoIGlzIGp1c3Qgd3JvbmcuXG5Xcml0YWJsZS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignQ2Fubm90IHBpcGUsIG5vdCByZWFkYWJsZScpKTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLCBjYikge1xuICB2YXIgZXIgPSBuZXcgRXJyb3IoJ3dyaXRlIGFmdGVyIGVuZCcpO1xuICAvLyBUT0RPOiBkZWZlciBlcnJvciBldmVudHMgY29uc2lzdGVudGx5IGV2ZXJ5d2hlcmUsIG5vdCBqdXN0IHRoZSBjYlxuICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIHByb2Nlc3NOZXh0VGljayhjYiwgZXIpO1xufVxuXG4vLyBDaGVja3MgdGhhdCBhIHVzZXItc3VwcGxpZWQgY2h1bmsgaXMgdmFsaWQsIGVzcGVjaWFsbHkgZm9yIHRoZSBwYXJ0aWN1bGFyXG4vLyBtb2RlIHRoZSBzdHJlYW0gaXMgaW4uIEN1cnJlbnRseSB0aGlzIG1lYW5zIHRoYXQgYG51bGxgIGlzIG5ldmVyIGFjY2VwdGVkXG4vLyBhbmQgdW5kZWZpbmVkL25vbi1zdHJpbmcgdmFsdWVzIGFyZSBvbmx5IGFsbG93ZWQgaW4gb2JqZWN0IG1vZGUuXG5mdW5jdGlvbiB2YWxpZENodW5rKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBjYikge1xuICB2YXIgdmFsaWQgPSB0cnVlO1xuICB2YXIgZXIgPSBmYWxzZTtcblxuICBpZiAoY2h1bmsgPT09IG51bGwpIHtcbiAgICBlciA9IG5ldyBUeXBlRXJyb3IoJ01heSBub3Qgd3JpdGUgbnVsbCB2YWx1ZXMgdG8gc3RyZWFtJyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgaWYgKGVyKSB7XG4gICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICAgIHByb2Nlc3NOZXh0VGljayhjYiwgZXIpO1xuICAgIHZhbGlkID0gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHZhbGlkO1xufVxuXG5Xcml0YWJsZS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuICB2YXIgcmV0ID0gZmFsc2U7XG4gIHZhciBpc0J1ZiA9IEJ1ZmZlci5pc0J1ZmZlcihjaHVuayk7XG5cbiAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgaWYgKGlzQnVmKSBlbmNvZGluZyA9ICdidWZmZXInO2Vsc2UgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBjYiAhPT0gJ2Z1bmN0aW9uJykgY2IgPSBub3A7XG5cbiAgaWYgKHN0YXRlLmVuZGVkKSB3cml0ZUFmdGVyRW5kKHRoaXMsIGNiKTtlbHNlIGlmIChpc0J1ZiB8fCB2YWxpZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgY2IpKSB7XG4gICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgcmV0ID0gd3JpdGVPckJ1ZmZlcih0aGlzLCBzdGF0ZSwgaXNCdWYsIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5jb3JrID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIHN0YXRlLmNvcmtlZCsrO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLnVuY29yayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAoc3RhdGUuY29ya2VkKSB7XG4gICAgc3RhdGUuY29ya2VkLS07XG5cbiAgICBpZiAoIXN0YXRlLndyaXRpbmcgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuZmluaXNoZWQgJiYgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KSBjbGVhckJ1ZmZlcih0aGlzLCBzdGF0ZSk7XG4gIH1cbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5zZXREZWZhdWx0RW5jb2RpbmcgPSBmdW5jdGlvbiBzZXREZWZhdWx0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgLy8gbm9kZTo6UGFyc2VFbmNvZGluZygpIHJlcXVpcmVzIGxvd2VyIGNhc2UuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnKSBlbmNvZGluZyA9IGVuY29kaW5nLnRvTG93ZXJDYXNlKCk7XG4gIGlmICghKFsnaGV4JywgJ3V0ZjgnLCAndXRmLTgnLCAnYXNjaWknLCAnYmluYXJ5JywgJ2Jhc2U2NCcsICd1Y3MyJywgJ3Vjcy0yJywgJ3V0ZjE2bGUnLCAndXRmLTE2bGUnLCAncmF3J10uaW5kZXhPZigoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKSkgPiAtMSkpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZyk7XG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVmYXVsdEVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gZGVjb2RlQ2h1bmsoc3RhdGUsIGNodW5rLCBlbmNvZGluZykge1xuICBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgc3RhdGUuZGVjb2RlU3RyaW5ncyAhPT0gZmFsc2UgJiYgdHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgIGNodW5rID0gYnVmZmVyU2hpbS5mcm9tKGNodW5rLCBlbmNvZGluZyk7XG4gIH1cbiAgcmV0dXJuIGNodW5rO1xufVxuXG4vLyBpZiB3ZSdyZSBhbHJlYWR5IHdyaXRpbmcgc29tZXRoaW5nLCB0aGVuIGp1c3QgcHV0IHRoaXNcbi8vIGluIHRoZSBxdWV1ZSwgYW5kIHdhaXQgb3VyIHR1cm4uICBPdGhlcndpc2UsIGNhbGwgX3dyaXRlXG4vLyBJZiB3ZSByZXR1cm4gZmFsc2UsIHRoZW4gd2UgbmVlZCBhIGRyYWluIGV2ZW50LCBzbyBzZXQgdGhhdCBmbGFnLlxuZnVuY3Rpb24gd3JpdGVPckJ1ZmZlcihzdHJlYW0sIHN0YXRlLCBpc0J1ZiwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBpZiAoIWlzQnVmKSB7XG4gICAgY2h1bmsgPSBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKTtcbiAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKGNodW5rKSkgZW5jb2RpbmcgPSAnYnVmZmVyJztcbiAgfVxuICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgc3RhdGUubGVuZ3RoICs9IGxlbjtcblxuICB2YXIgcmV0ID0gc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgLy8gd2UgbXVzdCBlbnN1cmUgdGhhdCBwcmV2aW91cyBuZWVkRHJhaW4gd2lsbCBub3QgYmUgcmVzZXQgdG8gZmFsc2UuXG4gIGlmICghcmV0KSBzdGF0ZS5uZWVkRHJhaW4gPSB0cnVlO1xuXG4gIGlmIChzdGF0ZS53cml0aW5nIHx8IHN0YXRlLmNvcmtlZCkge1xuICAgIHZhciBsYXN0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbmV3IFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpO1xuICAgIGlmIChsYXN0KSB7XG4gICAgICBsYXN0Lm5leHQgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIH1cbiAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudCArPSAxO1xuICB9IGVsc2Uge1xuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmFsc2UsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIHdyaXRldiwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHN0YXRlLndyaXRlbGVuID0gbGVuO1xuICBzdGF0ZS53cml0ZWNiID0gY2I7XG4gIHN0YXRlLndyaXRpbmcgPSB0cnVlO1xuICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgaWYgKHdyaXRldikgc3RyZWFtLl93cml0ZXYoY2h1bmssIHN0YXRlLm9ud3JpdGUpO2Vsc2Ugc3RyZWFtLl93cml0ZShjaHVuaywgZW5jb2RpbmcsIHN0YXRlLm9ud3JpdGUpO1xuICBzdGF0ZS5zeW5jID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpIHtcbiAgLS1zdGF0ZS5wZW5kaW5nY2I7XG4gIGlmIChzeW5jKSBwcm9jZXNzTmV4dFRpY2soY2IsIGVyKTtlbHNlIGNiKGVyKTtcblxuICBzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkID0gdHJ1ZTtcbiAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpIHtcbiAgc3RhdGUud3JpdGluZyA9IGZhbHNlO1xuICBzdGF0ZS53cml0ZWNiID0gbnVsbDtcbiAgc3RhdGUubGVuZ3RoIC09IHN0YXRlLndyaXRlbGVuO1xuICBzdGF0ZS53cml0ZWxlbiA9IDA7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGUoc3RyZWFtLCBlcikge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciBzeW5jID0gc3RhdGUuc3luYztcbiAgdmFyIGNiID0gc3RhdGUud3JpdGVjYjtcblxuICBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO1xuXG4gIGlmIChlcikgb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYik7ZWxzZSB7XG4gICAgLy8gQ2hlY2sgaWYgd2UncmUgYWN0dWFsbHkgcmVhZHkgdG8gZmluaXNoLCBidXQgZG9uJ3QgZW1pdCB5ZXRcbiAgICB2YXIgZmluaXNoZWQgPSBuZWVkRmluaXNoKHN0YXRlKTtcblxuICAgIGlmICghZmluaXNoZWQgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIHtcbiAgICAgIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cblxuICAgIGlmIChzeW5jKSB7XG4gICAgICAvKjxyZXBsYWNlbWVudD4qL1xuICAgICAgYXN5bmNXcml0ZShhZnRlcldyaXRlLCBzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgICAgLyo8L3JlcGxhY2VtZW50PiovXG4gICAgfSBlbHNlIHtcbiAgICAgIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpIHtcbiAgaWYgKCFmaW5pc2hlZCkgb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpO1xuICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgY2IoKTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG59XG5cbi8vIE11c3QgZm9yY2UgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIG9uIG5leHRUaWNrLCBzbyB0aGF0IHdlIGRvbid0XG4vLyBlbWl0ICdkcmFpbicgYmVmb3JlIHRoZSB3cml0ZSgpIGNvbnN1bWVyIGdldHMgdGhlICdmYWxzZScgcmV0dXJuXG4vLyB2YWx1ZSwgYW5kIGhhcyBhIGNoYW5jZSB0byBhdHRhY2ggYSAnZHJhaW4nIGxpc3RlbmVyLlxuZnVuY3Rpb24gb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5uZWVkRHJhaW4pIHtcbiAgICBzdGF0ZS5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZHJhaW4nKTtcbiAgfVxufVxuXG4vLyBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiB0aGUgYnVmZmVyIHdhaXRpbmcsIHRoZW4gcHJvY2VzcyBpdFxuZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSkge1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgdmFyIGVudHJ5ID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0O1xuXG4gIGlmIChzdHJlYW0uX3dyaXRldiAmJiBlbnRyeSAmJiBlbnRyeS5uZXh0KSB7XG4gICAgLy8gRmFzdCBjYXNlLCB3cml0ZSBldmVyeXRoaW5nIHVzaW5nIF93cml0ZXYoKVxuICAgIHZhciBsID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQ7XG4gICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheShsKTtcbiAgICB2YXIgaG9sZGVyID0gc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlO1xuICAgIGhvbGRlci5lbnRyeSA9IGVudHJ5O1xuXG4gICAgdmFyIGNvdW50ID0gMDtcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIGJ1ZmZlcltjb3VudF0gPSBlbnRyeTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIGNvdW50ICs9IDE7XG4gICAgfVxuXG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCB0cnVlLCBzdGF0ZS5sZW5ndGgsIGJ1ZmZlciwgJycsIGhvbGRlci5maW5pc2gpO1xuXG4gICAgLy8gZG9Xcml0ZSBpcyBhbG1vc3QgYWx3YXlzIGFzeW5jLCBkZWZlciB0aGVzZSB0byBzYXZlIGEgYml0IG9mIHRpbWVcbiAgICAvLyBhcyB0aGUgaG90IHBhdGggZW5kcyB3aXRoIGRvV3JpdGVcbiAgICBzdGF0ZS5wZW5kaW5nY2IrKztcbiAgICBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgICBpZiAoaG9sZGVyLm5leHQpIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IGhvbGRlci5uZXh0O1xuICAgICAgaG9sZGVyLm5leHQgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBuZXcgQ29ya2VkUmVxdWVzdChzdGF0ZSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFNsb3cgY2FzZSwgd3JpdGUgY2h1bmtzIG9uZS1ieS1vbmVcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIHZhciBjaHVuayA9IGVudHJ5LmNodW5rO1xuICAgICAgdmFyIGVuY29kaW5nID0gZW50cnkuZW5jb2Rpbmc7XG4gICAgICB2YXIgY2IgPSBlbnRyeS5jYWxsYmFjaztcbiAgICAgIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcblxuICAgICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIC8vIGlmIHdlIGRpZG4ndCBjYWxsIHRoZSBvbndyaXRlIGltbWVkaWF0ZWx5LCB0aGVuXG4gICAgICAvLyBpdCBtZWFucyB0aGF0IHdlIG5lZWQgdG8gd2FpdCB1bnRpbCBpdCBkb2VzLlxuICAgICAgLy8gYWxzbywgdGhhdCBtZWFucyB0aGF0IHRoZSBjaHVuayBhbmQgY2IgYXJlIGN1cnJlbnRseVxuICAgICAgLy8gYmVpbmcgcHJvY2Vzc2VkLCBzbyBtb3ZlIHRoZSBidWZmZXIgY291bnRlciBwYXN0IHRoZW0uXG4gICAgICBpZiAoc3RhdGUud3JpdGluZykge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW50cnkgPT09IG51bGwpIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICB9XG5cbiAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPSBlbnRyeTtcbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IGZhbHNlO1xufVxuXG5Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobmV3IEVycm9yKCdfd3JpdGUoKSBpcyBub3QgaW1wbGVtZW50ZWQnKSk7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRldiA9IG51bGw7XG5cbldyaXRhYmxlLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIGlmICh0eXBlb2YgY2h1bmsgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGNodW5rO1xuICAgIGNodW5rID0gbnVsbDtcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAoY2h1bmsgIT09IG51bGwgJiYgY2h1bmsgIT09IHVuZGVmaW5lZCkgdGhpcy53cml0ZShjaHVuaywgZW5jb2RpbmcpO1xuXG4gIC8vIC5lbmQoKSBmdWxseSB1bmNvcmtzXG4gIGlmIChzdGF0ZS5jb3JrZWQpIHtcbiAgICBzdGF0ZS5jb3JrZWQgPSAxO1xuICAgIHRoaXMudW5jb3JrKCk7XG4gIH1cblxuICAvLyBpZ25vcmUgdW5uZWNlc3NhcnkgZW5kKCkgY2FsbHMuXG4gIGlmICghc3RhdGUuZW5kaW5nICYmICFzdGF0ZS5maW5pc2hlZCkgZW5kV3JpdGFibGUodGhpcywgc3RhdGUsIGNiKTtcbn07XG5cbmZ1bmN0aW9uIG5lZWRGaW5pc2goc3RhdGUpIHtcbiAgcmV0dXJuIHN0YXRlLmVuZGluZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID09PSBudWxsICYmICFzdGF0ZS5maW5pc2hlZCAmJiAhc3RhdGUud3JpdGluZztcbn1cblxuZnVuY3Rpb24gcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5wcmVmaW5pc2hlZCkge1xuICAgIHN0YXRlLnByZWZpbmlzaGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0uZW1pdCgncHJlZmluaXNoJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbmVlZCA9IG5lZWRGaW5pc2goc3RhdGUpO1xuICBpZiAobmVlZCkge1xuICAgIGlmIChzdGF0ZS5wZW5kaW5nY2IgPT09IDApIHtcbiAgICAgIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKTtcbiAgICAgIHN0YXRlLmZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5lbWl0KCdmaW5pc2gnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmVlZDtcbn1cblxuZnVuY3Rpb24gZW5kV3JpdGFibGUoc3RyZWFtLCBzdGF0ZSwgY2IpIHtcbiAgc3RhdGUuZW5kaW5nID0gdHJ1ZTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG4gIGlmIChjYikge1xuICAgIGlmIChzdGF0ZS5maW5pc2hlZCkgcHJvY2Vzc05leHRUaWNrKGNiKTtlbHNlIHN0cmVhbS5vbmNlKCdmaW5pc2gnLCBjYik7XG4gIH1cbiAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuICBzdHJlYW0ud3JpdGFibGUgPSBmYWxzZTtcbn1cblxuLy8gSXQgc2VlbXMgYSBsaW5rZWQgbGlzdCBidXQgaXQgaXMgbm90XG4vLyB0aGVyZSB3aWxsIGJlIG9ubHkgMiBvZiB0aGVzZSBmb3IgZWFjaCBzdHJlYW1cbmZ1bmN0aW9uIENvcmtlZFJlcXVlc3Qoc3RhdGUpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICB0aGlzLm5leHQgPSBudWxsO1xuICB0aGlzLmVudHJ5ID0gbnVsbDtcbiAgdGhpcy5maW5pc2ggPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgdmFyIGVudHJ5ID0gX3RoaXMuZW50cnk7XG4gICAgX3RoaXMuZW50cnkgPSBudWxsO1xuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgdmFyIGNiID0gZW50cnkuY2FsbGJhY2s7XG4gICAgICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgICAgIGNiKGVycik7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgfVxuICAgIGlmIChzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUpIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZS5uZXh0ID0gX3RoaXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IF90aGlzO1xuICAgIH1cbiAgfTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXG4vLyBtb2R1bGUgaWQgPSA1MFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzJyk7XG5leHBvcnRzLlN0cmVhbSA9IGV4cG9ydHM7XG5leHBvcnRzLlJlYWRhYmxlID0gZXhwb3J0cztcbmV4cG9ydHMuV3JpdGFibGUgPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzJyk7XG5leHBvcnRzLkR1cGxleCA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fZHVwbGV4LmpzJyk7XG5leHBvcnRzLlRyYW5zZm9ybSA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzJyk7XG5leHBvcnRzLlBhc3NUaHJvdWdoID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qcycpO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWRhYmxlLXN0cmVhbS9yZWFkYWJsZS1icm93c2VyLmpzXG4vLyBtb2R1bGUgaWQgPSA1MVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJpbXBvcnQgVG9uZSBmcm9tICd0b25lJ1xuaW1wb3J0IHsgY2hvaWNlIH0gZnJvbSAnLi91dGlsJ1xuXG5jb25zdCBwbGF5ZXJfY291bnQgPSAyXG5sZXQgc2FtcGxlX2luZGV4ID0gMFxuXG5jb25zdCBjb21wcmVzc29yID0gbmV3IFRvbmUuQ29tcHJlc3NvcigtMzAsIDMpLnRvTWFzdGVyKClcblxuY29uc3Qgc2FtcGxlcyA9IFtcbiAgeyByb290OiAyMjYsIGZuOiAnc2FtcGxlcy8zODA3MzdfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTAxLWEtcmF3Lm1wMycsIH0sXG4gIHsgcm9vdDogMjY3LCBmbjogJ3NhbXBsZXMvMzgwNzM2X19jYWJsZWQtbWVzc19fc2Fuc3VsYS0wMi1jLXJhdy5tcDMnLCB9LFxuICB7IHJvb3Q6IDM0MCwgZm46ICdzYW1wbGVzLzM4MDczNV9fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDMtZS1yYXcubXAzJywgfSxcbiAgeyByb290OiA0NTIsIGZuOiAnc2FtcGxlcy8zODA3MzNfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTA2LWEtMDItcmF3Lm1wMycsIH0sXG4vLyAgeyByb290OiA1MDcsIGZuOiAnc2FtcGxlcy8zODA3MzRfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTA3LWItaC1yYXcubXAzJywgfSxcbi8vICB7IHJvb3Q6IDUzNSwgZm46ICdzYW1wbGVzLzM4MDczMV9fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDgtYy1yYXcubXAzJywgfSxcbi8vICB7IHJvb3Q6IDY3MSwgZm46ICdzYW1wbGVzLzM4MDczMl9fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDktZS1yYXcubXAzJywgfSxcbl1cblxuc2FtcGxlcy5mb3JFYWNoKChzYW1wbGUpID0+IHtcbiAgc2FtcGxlLnBsYXllcnMgPSBbXVxuICBzYW1wbGUuaW5kZXggPSAtMVxuICBmb3IgKGxldCBpID0gMDsgaSA8IHBsYXllcl9jb3VudDsgaSsrKSB7XG4gICAgbGV0IGZuID0gc2FtcGxlLmZuXG4gICAgaWYgKHdpbmRvdy5sb2NhdGlvbi5ocmVmLm1hdGNoKC9hc2RmLnVzLykpIHtcbiAgICAgIGZuID0gJy8vYXNkZi51cy9rYWxpbWJhLycgKyBmblxuICAgIH1cbiAgICBsZXQgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKHtcbiAgICAgIHVybDogZm4sXG4gICAgICByZXRyaWdnZXI6IHRydWUsXG4gICAgICBwbGF5YmFja1JhdGU6IDEsXG4gICAgfSlcbiAgICBwbGF5ZXIuY29ubmVjdChjb21wcmVzc29yKVxuICAgIHNhbXBsZS5wbGF5ZXJzLnB1c2gocGxheWVyKVxuICB9XG59KVxuXG5mdW5jdGlvbiBwbGF5IChmcmVxLCB2b2x1bWUgPSAwLjApIHtcbiAgY29uc3QgYmVzdCA9IHsgc2FtcGxlOiBzYW1wbGVzW3NhbXBsZV9pbmRleF0gfVxuICBzYW1wbGVfaW5kZXggPSAoc2FtcGxlX2luZGV4ICsgMSkgJSBzYW1wbGVzLmxlbmd0aFxuICBiZXN0LnNhbXBsZS5pbmRleCA9IChiZXN0LnNhbXBsZS5pbmRleCArIDEpICUgcGxheWVyX2NvdW50XG5cbiAgY29uc3QgcGxheWVyID0gYmVzdC5zYW1wbGUucGxheWVyc1sgYmVzdC5zYW1wbGUuaW5kZXggXVxuICBwbGF5ZXIucGxheWJhY2tSYXRlID0gZnJlcSAvIGJlc3Quc2FtcGxlLnJvb3RcbiAgLy8gY29uc29sZS5sb2cocGxheWVyKVxuICBwbGF5ZXIudm9sdW1lLnZhbHVlID0gdm9sdW1lXG4gIHNldFRpbWVvdXQoKCkgPT4geyBwbGF5ZXIuc3RhcnQoKSB9LCAwKVxufVxuXG5leHBvcnQgZGVmYXVsdCB7IHBsYXkgfVxuXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvbGliL2thbGltYmEuanMiLCJpbXBvcnQgSW50b25hdGlvbiBmcm9tICcuL2ludG9uYXRpb24nXG5cbmNvbnN0IG1lYW50b25lID0gYCEgbWVhbnF1YXIuc2NsXG4hXG4xLzQtY29tbWEgbWVhbnRvbmUgc2NhbGUuIFBpZXRybyBBYXJvbidzIHRlbXBlcmFtZW50ICgxNTIzKVxuIDEyXG4hXG4gNzYuMDQ5MDBcbiAxOTMuMTU2ODZcbiAzMTAuMjY0NzFcbiA1LzRcbiA1MDMuNDIxNTdcbiA1NzkuNDcwNTdcbiA2OTYuNTc4NDNcbiAyNS8xNlxuIDg4OS43MzUyOVxuIDEwMDYuODQzMTRcbiAxMDgyLjg5MjE0XG4gMi8xXG5gXG5cbmNvbnN0IHNoYXJlcyA9IGAhIHNoYXJlcy5zY2xcbiFcbkEgc2NhbGUgYmFzZWQgb24gc2hhcmVzIG9mIHdlYWx0aFxuIVxuMS5cbjUuXG4xNS5cbjMyLlxuNTIuXG43OC5cbjExNi5cbjE4Mi5cbjUyMS5cbjEwMDAuXG5gXG5cbmNvbnN0IHNoYXJlc19zdW0gPSBgISBzaGFyZXNfc3VtLnNjbFxuIVxuQSBzY2FsZSBiYXNlZCBvbiBzdW1taW5nIHNoYXJlcyBvZiB3ZWFsdGhcbiFcbjFcbjYuMFxuMjEuMFxuNTMuMFxuMTA1LjBcbjE4My4wXG4yOTkuMFxuNDgxLjBcbjEwMDIuMFxuMi8xXG5gXG5cbmNvbnN0IG1hdmlsYSA9IGAhIG1hdmlsYTEyLnNjbFxuIVxuQSAxMi1ub3RlIG1hdmlsYSBzY2FsZSAoZm9yIHdhcnBpbmcgbWVhbnRvbmUtYmFzZWQgbXVzaWMpLCA1LWxpbWl0IFRPUFxuIDEyXG4hXG4tMzAuOTk3MTlcbiAxNjMuNTA3NzBcbiAzNTguMDEyNThcbiAzMjcuMDE1NDBcbiA1MjEuNTIwMjhcbiA0OTAuNTIzMTBcbiA2ODUuMDI3OThcbiA2NTQuMDMwODBcbiA4NDguNTM1NjhcbiAxMDQzLjA0MDU3XG4gMTAxMi4wNDMzOFxuIDEyMDYuNTQ4MjZcbmBcblxuY29uc3QgY2FybG9zX2FscGhhID0gYCEgY2FybG9zX2FscGhhLnNjbFxuIVxuV2VuZHkgQ2FybG9zJyBBbHBoYSBzY2FsZSB3aXRoIHBlcmZlY3QgZmlmdGggZGl2aWRlZCBpbiBuaW5lXG4gMThcbiFcbiA3OC4wMDAwMFxuIDE1Ni4wMDAwMFxuIDIzNC4wMDAwMFxuIDMxMi4wMDAwMFxuIDM5MC4wMDAwMFxuIDQ2OC4wMDAwMFxuIDU0Ni4wMDAwMFxuIDYyNC4wMDAwMFxuIDcwMi4wMDAwMFxuIDc4MC4wMDAwMFxuIDg1OC4wMDAwMFxuIDkzNi4wMDAwMFxuIDEwMTQuMDAwMDBcbiAxMDkyLjAwMDAwXG4gMTE3MC4wMDAwMFxuIDEyNDguMDAwMDBcbiAxMzI2LjAwMDAwXG4gMTQwNC4wMDAwMFxuYFxuXG5jb25zdCBsYW1vbnRlID0gYCEgeW91bmctbG1fcGlhbm8uc2NsXG4hXG5MYU1vbnRlIFlvdW5nJ3MgV2VsbC1UZW1wZXJlZCBQaWFub1xuMTJcbiFcbjU2Ny81MTJcbjkvOFxuMTQ3LzEyOFxuMjEvMTZcbjEzMjMvMTAyNFxuMTg5LzEyOFxuMy8yXG40OS8zMlxuNy80XG40NDEvMjU2XG42My8zMlxuMi8xXG5gXG5cbmNvbnN0IGNvbHVuZGkgPSBgISBjb2x1bmRpLnNjbFxuIVxuQ29sdW5kaSBzY2FsZVxuMTBcbiFcbjkvOFxuMTcxLzE0MFxuMTM3LzExMlxuNDMvMzVcbjMvMlxuNDIxLzI4MFxuMjEzLzE0MFxuMjYzLzE1MFxuNjYvMzVcbjIvMVxuYFxuXG5jb25zdCBsaXVfbWFqb3IgPSBgISBsaXVfbWFqb3Iuc2NsXG4hXG5MaW51cyBMaXUncyBNYWpvciBTY2FsZSwgc2VlIGhpcyAxOTc4IGJvb2ssIFwiSW50b25hdGlvbiBUaGVvcnlcIiAgICAgICAgICAgICAgICAgXG4gN1xuIVxuIDEwLzlcbiAxMDAvODFcbiA0LzNcbiAzLzJcbiA1LzNcbiA1MC8yN1xuIDIvMVxuYFxuY29uc3QgbGl1X3BlbnRhdG9uaWMgPSBgISBsaXVfcGVudC5zY2xcbiFcbkxpbnVzIExpdSdzIFwicGVudGF0b25pYyBzY2FsZVwiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiA3XG4hXG4gOS84XG4gODEvNjRcbiAyNy8yMFxuIDMvMlxuIDI3LzE2XG4gMjQzLzEyOFxuIDgxLzQwXG5gXG5cbmNvbnN0IGxpdV9taW5vciA9IGAhIExJVV9NSU5vci5zY2xcbiFcbkxpbnVzIExpdSdzIEhhcm1vbmljIE1pbm9yICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gN1xuIVxuIDEwLzlcbiA2LzVcbiA0LzNcbiA0MC8yN1xuIDgvNVxuIDUwLzI3XG4gMi8xXG5gXG5cbmNvbnN0IGxpdV9tZWxvZGljX21pbm9yID0gYCEgbGl1X21lbC5zY2xcbiFcbkxpbnVzIExpdSdzIE1lbG9kaWMgTWlub3IsIHVzZSA1IGFuZCA3IGRlc2NlbmRpbmcgYW5kIDYgYW5kIDggYXNjZW5kaW5nICAgICAgICAgXG4gOVxuIVxuIDEwLzlcbiA2LzVcbiA0LzNcbiAzLzJcbiA4MS81MFxuIDUvM1xuIDkvNVxuIDUwLzI3XG4gMi8xXG5gXG5cbmNvbnN0IHNjYWxlcyA9IFtcbiAge1xuICAgIGludGVydmFsczogJzEvMSA5LzggNS80IDQvMyAzLzIgNS8zIDE1LzggMi8xJyxcbiAgICBuYW1lOiBcImhhcm1vbmljIHNjYWxlXCIsXG4gIH0sXG4gIHtcbiAgICByb290OiA0NTAsXG4gICAgaW50ZXJ2YWxzOiAnMS8xIDkvOCA1LzQgNC8zIDMvMiA1LzMgMTUvOCAyLzEnLFxuICAgIG5hbWU6IFwiaGFybW9uaWMgc2NhbGUgQCA0NTBcIixcbiAgfSxcbiAge1xuICAgIHRldDogNSxcbiAgfSxcbiAge1xuICAgIHRldDogMTIsXG4gIH0sXG4gIHtcbiAgICB0ZXQ6IDE3LFxuICB9LFxuICB7XG4gICAgaW50ZXJ2YWxzOiAnMS8xIDgxLzgwIDMzLzMyIDIxLzIwIDE2LzE1IDEyLzExIDExLzEwIDEwLzkgOS84IDgvNyA3LzYgMzIvMjcgNi81IDExLzkgNS80IDE0LzExIDkvNyAyMS8xNiA0LzMgMjcvMjAgMTEvOCA3LzUgMTAvNyAxNi8xMSA0MC8yNyAzLzIgMzIvMjEgMTQvOSAxMS83IDgvNSAxOC8xMSA1LzMgMjcvMTYgMTIvNyA3LzQgMTYvOSA5LzUgMjAvMTEgMTEvNiAxNS84IDQwLzIxIDY0LzMzIDE2MC84MSAyLzEnLFxuICAgIG5hbWU6IFwiaGFycnkgcGFydGNoIHNjYWxlXCIsXG4gIH0sXG4gIHtcbiAgICBzY2w6IGxhbW9udGUsXG4gIH0sXG4gIHtcbiAgICBzY2w6IG1lYW50b25lLFxuICB9LFxuICB7XG4gICAgc2NsOiBtYXZpbGEsXG4gIH0sXG4gIHtcbiAgICBzY2w6IGNhcmxvc19hbHBoYSxcbiAgfSxcbiAge1xuICAgIHNjbDogY29sdW5kaSxcbiAgfSxcbiAge1xuICAgIHNjbDogc2hhcmVzLFxuICB9LFxuICB7XG4gICAgc2NsOiBzaGFyZXNfc3VtLFxuICB9LFxuICB7XG4gICAgc2NsOiBsaXVfbWFqb3IsXG4gIH0sXG4gIHtcbiAgICBzY2w6IGxpdV9taW5vcixcbiAgfSxcbiAge1xuICAgIHNjbDogbGl1X21lbG9kaWNfbWlub3IsXG4gIH0sXG4gIHtcbiAgICBzY2w6IGxpdV9wZW50YXRvbmljLFxuICB9XG5dLm1hcCggKG9wdCkgPT4gbmV3IEludG9uYXRpb24ob3B0KSApXG5cbmxldCBzY2FsZSA9IHNjYWxlc1swXVxubGV0IGhhbmRsZUNoYW5nZSA9IGZ1bmN0aW9uKCl7fVxuXG5mdW5jdGlvbiBidWlsZCAoKSB7XG4gIHNjYWxlcy5mb3JFYWNoKCAoc2NhbGUsIGkpID0+IHtcbiAgICBzY2FsZS5oZWFkaW5nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICBzY2FsZS5oZWFkaW5nLmlubmVySFRNTCA9IHNjYWxlLm5hbWVcbiAgICBzY2FsZS5oZWFkaW5nLmNsYXNzTGlzdC5hZGQoJ2hlYWRpbmcnKVxuICAgIHNjYWxlLmhlYWRpbmcuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpe1xuICAgICAgcGljayhpKVxuICAgIH0pXG4gICAgc2NhbGVfbGlzdC5hcHBlbmRDaGlsZChzY2FsZS5oZWFkaW5nKVxuICB9KVxuICBwaWNrKDApXG59XG5mdW5jdGlvbiBidWlsZF9vcHRpb25zKGVsKSB7XG4gIHNjYWxlcy5mb3JFYWNoKCAoc2NhbGUsIGkpID0+IHtcbiAgICBjb25zdCBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRpb24nKVxuICAgIG9wdGlvbi5pbm5lckhUTUwgPSBzY2FsZS5uYW1lXG4gICAgb3B0aW9uLnZhbHVlID0gaVxuICAgIGVsLmFwcGVuZENoaWxkKG9wdGlvbilcbiAgfSlcbiAgZWwuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBmdW5jdGlvbihlKXtcbiAgICBwaWNrKGUudGFyZ2V0LnZhbHVlKVxuICB9KVxuICBwaWNrKDApXG59XG5cbmZ1bmN0aW9uIHBpY2sgKGkpIHtcbiAgaWYgKHNjYWxlKSB7XG4gICAgc2NhbGUuaGVhZGluZyAmJiBzY2FsZS5oZWFkaW5nLmNsYXNzTGlzdC5yZW1vdmUoJ3NlbGVjdGVkJylcbiAgfVxuICBzY2FsZSA9IHNjYWxlc1tpXVxuICBzY2FsZS5oZWFkaW5nICYmIHNjYWxlLmhlYWRpbmcuY2xhc3NMaXN0LmFkZCgnc2VsZWN0ZWQnKVxuXHRoYW5kbGVDaGFuZ2Uoc2NhbGUpXG59XG5cbmZ1bmN0aW9uIGN1cnJlbnQgKCkge1xuICByZXR1cm4gc2NhbGVcbn1cblxuZnVuY3Rpb24gb25DaGFuZ2UgKGZuKSB7XG5cdGhhbmRsZUNoYW5nZSA9IGZuXG59XG5cbmZ1bmN0aW9uIG5hbWVzICgpIHtcblx0cmV0dXJuIHNjYWxlcy5tYXAoIHNjYWxlID0+IHNjYWxlLm5hbWUgKVxufVxuXG5cbmV4cG9ydCBkZWZhdWx0IHsgc2NhbGVzLCBjdXJyZW50LCBidWlsZCwgYnVpbGRfb3B0aW9ucywgcGljaywgbmFtZXMsIG9uQ2hhbmdlIH1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9saWIvc2NhbGVzLmpzIiwiaW1wb3J0IE5leHVzIGZyb20gJ25leHVzdWknXG5cbmV4cG9ydCBjb25zdCBueCA9IHdpbmRvdy5ueCA9IHt9XG5cbi8qIHVpIC0gdXBkYXRlIGFuIGludC9mbG9hdCB2YWx1ZSAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlX3ZhbHVlX29uX2NoYW5nZShlbCwgaWQsIGlzX2ludCwgZm4pIHtcbiAgY29uc3QgbGFiZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGlkICsgJyArIC52YWwnKVxuICBjb25zdCB1cGRhdGUgPSB2ID0+IHtcbiAgICBsYWJlbC5pbm5lckhUTUwgPSBpc19pbnQgPyBwYXJzZUludCh2KSA6IHYudG9GaXhlZCgyKVxuICAgIGZuICYmIGZuKHYpXG4gIH1cbiAgZWwub24oJ2NoYW5nZScsIHVwZGF0ZSlcbiAgdXBkYXRlKGVsLnZhbHVlKVxuICBlbC51cGRhdGUgPSB1cGRhdGVcbn1cblxuLyogdWkgLSB1cGRhdGUgYSByYWRpbyBidXR0b24gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZV9yYWRpb192YWx1ZV9vbl9jaGFuZ2UoZWwsIGlkLCB2YWx1ZXMsIGZuKSB7XG4gIGxldCBvbGRfdiA9IGVsLmFjdGl2ZVxuICBjb25zdCBsYWJlbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoaWQgKyAnICsgLnZhbCcpXG4gIGNvbnN0IHVwZGF0ZSA9IHYgPT4ge1xuICAgIGlmICh2ID09PSAtMSkge1xuICAgICAgdiA9IGVsLmFjdGl2ZSA9IG9sZF92XG4gICAgfSBlbHNlIHtcbiAgICAgIG9sZF92ID0gdlxuICAgIH1cbiAgICBsYWJlbC5pbm5lckhUTUwgPSB2YWx1ZXNbdl1bMV1cbiAgICBmbiAmJiBmbih2KVxuICB9XG4gIGVsLm9uKCdjaGFuZ2UnLCB1cGRhdGUpXG4gIHVwZGF0ZShlbC5hY3RpdmUpXG4gIGVsLnVwZGF0ZSA9IHVwZGF0ZVxufVxuXG4vKiB1aSAtIGJpbmQvYnVpbGQgYSBzZWxlY3QgZHJvcGRvd24gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkX29wdGlvbnMoZWwsIGxpc3RzLCBmbikge1xuICBPYmplY3Qua2V5cyhsaXN0cykuZm9yRWFjaChrZXkgPT4ge1xuICAgIGNvbnN0IGxpc3QgPSBsaXN0c1trZXldXG4gICAgY29uc3Qgb3B0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb3B0aW9uJylcbiAgICBvcHRpb24uaW5uZXJIVE1MID0gbGlzdC5uYW1lXG4gICAgb3B0aW9uLnZhbHVlID0ga2V5XG4gICAgZWwuYXBwZW5kQ2hpbGQob3B0aW9uKVxuICB9KVxuICBlbC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIGZ1bmN0aW9uKGUpe1xuICAgIGZuKGUudGFyZ2V0LnZhbHVlKVxuICB9KVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2xpYi91aS5qcyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2lzSXRlcmFibGUyID0gcmVxdWlyZShcIi4uL2NvcmUtanMvaXMtaXRlcmFibGVcIik7XG5cbnZhciBfaXNJdGVyYWJsZTMgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0l0ZXJhYmxlMik7XG5cbnZhciBfZ2V0SXRlcmF0b3IyID0gcmVxdWlyZShcIi4uL2NvcmUtanMvZ2V0LWl0ZXJhdG9yXCIpO1xuXG52YXIgX2dldEl0ZXJhdG9yMyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2dldEl0ZXJhdG9yMik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmV4cG9ydHMuZGVmYXVsdCA9IGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gc2xpY2VJdGVyYXRvcihhcnIsIGkpIHtcbiAgICB2YXIgX2FyciA9IFtdO1xuICAgIHZhciBfbiA9IHRydWU7XG4gICAgdmFyIF9kID0gZmFsc2U7XG4gICAgdmFyIF9lID0gdW5kZWZpbmVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIGZvciAodmFyIF9pID0gKDAsIF9nZXRJdGVyYXRvcjMuZGVmYXVsdCkoYXJyKSwgX3M7ICEoX24gPSAoX3MgPSBfaS5uZXh0KCkpLmRvbmUpOyBfbiA9IHRydWUpIHtcbiAgICAgICAgX2Fyci5wdXNoKF9zLnZhbHVlKTtcblxuICAgICAgICBpZiAoaSAmJiBfYXJyLmxlbmd0aCA9PT0gaSkgYnJlYWs7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBfZCA9IHRydWU7XG4gICAgICBfZSA9IGVycjtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFfbiAmJiBfaVtcInJldHVyblwiXSkgX2lbXCJyZXR1cm5cIl0oKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlmIChfZCkgdGhyb3cgX2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIF9hcnI7XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gKGFyciwgaSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGFycikpIHtcbiAgICAgIHJldHVybiBhcnI7XG4gICAgfSBlbHNlIGlmICgoMCwgX2lzSXRlcmFibGUzLmRlZmF1bHQpKE9iamVjdChhcnIpKSkge1xuICAgICAgcmV0dXJuIHNsaWNlSXRlcmF0b3IoYXJyLCBpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBkZXN0cnVjdHVyZSBub24taXRlcmFibGUgaW5zdGFuY2VcIik7XG4gICAgfVxuICB9O1xufSgpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9iYWJlbC1ydW50aW1lL2hlbHBlcnMvc2xpY2VkVG9BcnJheS5qc1xuLy8gbW9kdWxlIGlkID0gNTVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wiTmV4dXNcIl0gPSBmYWN0b3J5KCk7XG5cdGVsc2Vcblx0XHRyb290W1wiTmV4dXNcIl0gPSBmYWN0b3J5KCk7XG59KSh0aGlzLCBmdW5jdGlvbigpIHtcbnJldHVybiAvKioqKioqLyAoZnVuY3Rpb24obW9kdWxlcykgeyAvLyB3ZWJwYWNrQm9vdHN0cmFwXG4vKioqKioqLyBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4vKioqKioqLyBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4vKioqKioqLyBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pXG4vKioqKioqLyBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbi8qKioqKiovIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4vKioqKioqLyBcdFx0XHRleHBvcnRzOiB7fSxcbi8qKioqKiovIFx0XHRcdGlkOiBtb2R1bGVJZCxcbi8qKioqKiovIFx0XHRcdGxvYWRlZDogZmFsc2Vcbi8qKioqKiovIFx0XHR9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbi8qKioqKiovIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuLyoqKioqKi8gXHRcdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuLyoqKioqKi8gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbi8qKioqKiovIFx0fVxuLyoqKioqKi9cbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuLyoqKioqKi8gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcbi8qKioqKiovIH0pXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyoqKioqKi8gKFtcbi8qIDAgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBfaW50ZXJvcFJlcXVpcmUgPSBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmpbXCJkZWZhdWx0XCJdIDogb2JqOyB9O1xuXHRcblx0dmFyIE5leHVzVUkgPSBfaW50ZXJvcFJlcXVpcmUoX193ZWJwYWNrX3JlcXVpcmVfXygxKSk7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IE5leHVzVUk7XG5cbi8qKiovIH0pLFxuLyogMSAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkID0gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBcImRlZmF1bHRcIjogb2JqIH07IH07XG5cdFxuXHR2YXIgX2ludGVyb3BSZXF1aXJlID0gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqW1wiZGVmYXVsdFwiXSA6IG9iajsgfTtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdGV4cG9ydHMuY29sb3JzID0gY29sb3JzO1xuXHRleHBvcnRzLmNvbnRleHQgPSBjb250ZXh0O1xuXHRleHBvcnRzLmNsb2NrID0gY2xvY2s7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBJbnRlcmZhY2VzID0gX2ludGVyb3BSZXF1aXJlKF9fd2VicGFja19yZXF1aXJlX18oMikpO1xuXHRcblx0dmFyIG1hdGggPSBfaW50ZXJvcFJlcXVpcmUoX193ZWJwYWNrX3JlcXVpcmVfXyg1KSk7XG5cdFxuXHR2YXIgUmFjayA9IF9pbnRlcm9wUmVxdWlyZShfX3dlYnBhY2tfcmVxdWlyZV9fKDM4KSk7XG5cdFxuXHR2YXIgVHVuZSA9IF9pbnRlcm9wUmVxdWlyZShfX3dlYnBhY2tfcmVxdWlyZV9fKDQwKSk7XG5cdFxuXHR2YXIgVHJhbnNmb3JtID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX193ZWJwYWNrX3JlcXVpcmVfXygzOSkpO1xuXHRcblx0dmFyIENvdW50ZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDI4KTtcblx0dmFyIFJhZGlvID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0MSk7XG5cdHZhciBEcnVuayA9IF9fd2VicGFja19yZXF1aXJlX18oMjcpO1xuXHR2YXIgU2VxdWVuY2UgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDI2KTtcblx0dmFyIE1hdHJpeCA9IF9fd2VicGFja19yZXF1aXJlX18oMjUpO1xuXHRcblx0dmFyIFdBQUNsb2NrID0gX2ludGVyb3BSZXF1aXJlKF9fd2VicGFja19yZXF1aXJlX18oNDIpKTtcblx0XG5cdHZhciBJbnRlcnZhbCA9IF9pbnRlcm9wUmVxdWlyZShfX3dlYnBhY2tfcmVxdWlyZV9fKDQ1KSk7XG5cdFxuXHQvKipcblx0TmV4dXNVSSA9PiBjcmVhdGVkIGFzIE5leHVzXG5cdCovXG5cdFxuXHR2YXIgTmV4dXNVSSA9IChmdW5jdGlvbiAoKSB7XG5cdCAgZnVuY3Rpb24gTmV4dXNVSShjb250ZXh0KSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTmV4dXNVSSk7XG5cdFxuXHQgICAgZm9yICh2YXIga2V5IGluIEludGVyZmFjZXMpIHtcblx0ICAgICAgdGhpc1trZXldID0gSW50ZXJmYWNlc1trZXldO1xuXHQgICAgfVxuXHRcblx0ICAgIGZvciAodmFyIGtleSBpbiBtYXRoKSB7XG5cdCAgICAgIHRoaXNba2V5XSA9IG1hdGhba2V5XTtcblx0ICAgIH1cblx0XG5cdCAgICB2YXIgQ29yZSA9IHtcblx0ICAgICAgUmFjazogUmFja1xuXHQgICAgfTtcblx0XG5cdCAgICB2YXIgTW9kZWxzID0ge1xuXHQgICAgICBDb3VudGVyOiBDb3VudGVyLFxuXHQgICAgICBSYWRpbzogUmFkaW8sXG5cdCAgICAgIERydW5rOiBEcnVuayxcblx0ICAgICAgU2VxdWVuY2U6IFNlcXVlbmNlLFxuXHQgICAgICBNYXRyaXg6IE1hdHJpeFxuXHQgICAgfTtcblx0XG5cdCAgICBmb3IgKHZhciBrZXkgaW4gTW9kZWxzKSB7XG5cdCAgICAgIHRoaXNba2V5XSA9IE1vZGVsc1trZXldO1xuXHQgICAgfVxuXHRcblx0ICAgIGZvciAodmFyIGtleSBpbiBDb3JlKSB7XG5cdCAgICAgIHRoaXNba2V5XSA9IENvcmVba2V5XTtcblx0ICAgIH1cblx0XG5cdCAgICB2YXIgRGVmYXVsdENvbnRleHQgPSB3aW5kb3cuQXVkaW9Db250ZXh0IHx8IHdpbmRvdy53ZWJraXRBdWRpb0NvbnRleHQ7XG5cdCAgICB0aGlzLl9jb250ZXh0ID0gY29udGV4dCB8fCBuZXcgRGVmYXVsdENvbnRleHQoKTtcblx0XG5cdCAgICB0aGlzLnR1bmUgPSBuZXcgVHVuZSgpO1xuXHQgICAgdGhpcy5ub3RlID0gdGhpcy50dW5lLm5vdGUuYmluZCh0aGlzLnR1bmUpO1xuXHRcblx0ICAgIHRoaXMuY2xvY2sgPSBuZXcgV0FBQ2xvY2sodGhpcy5fY29udGV4dCk7XG5cdCAgICB0aGlzLmNsb2NrLnN0YXJ0KCk7XG5cdCAgICB0aGlzLkludGVydmFsID0gSW50ZXJ2YWw7XG5cdFxuXHQgICAgdGhpcy5jb2xvcnMgPSB7XG5cdCAgICAgIGFjY2VudDogXCIjMmJiXCIsXG5cdCAgICAgIGZpbGw6IFwiI2VlZVwiLFxuXHQgICAgICBsaWdodDogXCIjZmZmXCIsXG5cdCAgICAgIGRhcms6IFwiIzMzM1wiLFxuXHQgICAgICBtZWRpdW1MaWdodDogXCIjY2NjXCIsXG5cdCAgICAgIG1lZGl1bURhcms6IFwiIzY2NlwiXG5cdCAgICB9O1xuXHRcblx0ICAgIHRoaXMudHJhbnNmb3JtID0gVHJhbnNmb3JtO1xuXHQgICAgdGhpcy5hZGQgPSBUcmFuc2Zvcm0uYWRkO1xuXHRcblx0ICAgIHRoaXMuQWRkID0ge307XG5cdCAgICBmb3IgKHZhciBrZXkgaW4gSW50ZXJmYWNlcykge1xuXHQgICAgICB0aGlzLkFkZFtrZXldID0gVHJhbnNmb3JtLmFkZC5iaW5kKHRoaXMsIGtleSk7XG5cdCAgICB9XG5cdFxuXHQgICAgLyogY3JlYXRlIGRlZmF1bHQgY29tcG9uZW50IHNpemUgKi9cblx0ICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cblx0ICAgIHZhciBleGlzdGluZ1N0eWxlc2hlZXRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJzdHlsZVwiKTtcblx0ICAgIHZhciBkZWZhdWx0U2l6ZURlY2xhcmF0aW9uID0gXCJbbmV4dXMtdWlde2hlaWdodDo1MDAwcHg7d2lkdGg6NTAwMHB4fVwiO1xuXHQgICAgdmFyIGRlZmF1bHRTdHlsZU5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIik7XG5cdCAgICBkZWZhdWx0U3R5bGVOb2RlLnR5cGUgPSBcInRleHQvY3NzXCI7XG5cdCAgICBkZWZhdWx0U3R5bGVOb2RlLmlubmVySFRNTCA9IGRlZmF1bHRTaXplRGVjbGFyYXRpb247XG5cdCAgICBpZiAoZXhpc3RpbmdTdHlsZXNoZWV0cy5sZW5ndGggPiAwKSB7XG5cdCAgICAgIHZhciBwYXJlbnQgPSBleGlzdGluZ1N0eWxlc2hlZXRzWzBdLnBhcmVudE5vZGU7XG5cdCAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoZGVmYXVsdFN0eWxlTm9kZSwgZXhpc3RpbmdTdHlsZXNoZWV0c1swXSk7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICBkb2N1bWVudC53cml0ZShcIjxzdHlsZT5cIiArIGRlZmF1bHRTaXplRGVjbGFyYXRpb24gKyBcIjwvc3R5bGU+XCIpO1xuXHQgICAgfVxuXHQgICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cblx0ICB9XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhOZXh1c1VJLCB7XG5cdCAgICBjb250ZXh0OiB7XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0O1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uIChjdHgpIHtcblx0ICAgICAgICB0aGlzLmNsb2NrLnN0b3AoKTtcblx0ICAgICAgICB0aGlzLl9jb250ZXh0ID0gY3R4O1xuXHQgICAgICAgIHRoaXMuY2xvY2sgPSBuZXcgV0FBQ2xvY2sodGhpcy5jb250ZXh0KTtcblx0ICAgICAgICB0aGlzLmNsb2NrLnN0YXJ0KCk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIE5leHVzVUk7XG5cdH0pKCk7XG5cdFxuXHR2YXIgTmV4dXMgPSBuZXcgTmV4dXNVSSgpO1xuXHRcblx0ZnVuY3Rpb24gY29sb3JzKCkge1xuXHQgIHJldHVybiBOZXh1cy5jb2xvcnM7XG5cdH1cblx0XG5cdGZ1bmN0aW9uIGNvbnRleHQoKSB7XG5cdCAgcmV0dXJuIE5leHVzLmNvbnRleHQ7XG5cdH1cblx0XG5cdGZ1bmN0aW9uIGNsb2NrKCkge1xuXHQgIHJldHVybiBOZXh1cy5jbG9jaztcblx0fVxuXHRcblx0ZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBOZXh1cztcblxuLyoqKi8gfSksXG4vKiAyICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IHtcblx0ICBQb3NpdGlvbjogX193ZWJwYWNrX3JlcXVpcmVfXygzKSxcblx0ICBTbGlkZXI6IF9fd2VicGFja19yZXF1aXJlX18oMTQpLFxuXHQgIFRvZ2dsZTogX193ZWJwYWNrX3JlcXVpcmVfXygxNSksXG5cdCAgLyogIFJhbmdlOiByZXF1aXJlKCcuL3Jhbmdlc2xpZGVyJyksXG5cdCAgICBXYXZlZm9ybTogcmVxdWlyZSgnLi93YXZlZm9ybScpLCAqL1xuXHQgIEJ1dHRvbjogX193ZWJwYWNrX3JlcXVpcmVfXygxNiksXG5cdCAgVGV4dEJ1dHRvbjogX193ZWJwYWNrX3JlcXVpcmVfXygxOCksXG5cdCAgUmFkaW9CdXR0b246IF9fd2VicGFja19yZXF1aXJlX18oMTkpLFxuXHQgIE51bWJlcjogX193ZWJwYWNrX3JlcXVpcmVfXygyMCksXG5cdCAgU2VsZWN0OiBfX3dlYnBhY2tfcmVxdWlyZV9fKDIxKSxcblx0ICBEaWFsOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDIyKSxcblx0ICBQaWFubzogX193ZWJwYWNrX3JlcXVpcmVfXygyMyksXG5cdCAgU2VxdWVuY2VyOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDI0KSxcblx0ICBQYW4yRDogX193ZWJwYWNrX3JlcXVpcmVfXygyOSksXG5cdCAgVGlsdDogX193ZWJwYWNrX3JlcXVpcmVfXygzMCksXG5cdCAgTXVsdGlzbGlkZXI6IF9fd2VicGFja19yZXF1aXJlX18oMzEpLFxuXHQgIFBhbjogX193ZWJwYWNrX3JlcXVpcmVfXygzMyksXG5cdCAgRW52ZWxvcGU6IF9fd2VicGFja19yZXF1aXJlX18oMzQpLFxuXHQgIFNwZWN0cm9ncmFtOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM1KSxcblx0ICBNZXRlcjogX193ZWJwYWNrX3JlcXVpcmVfXygzNiksXG5cdCAgT3NjaWxsb3Njb3BlOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM3KVxuXHR9O1xuXG4vKioqLyB9KSxcbi8qIDMgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRcblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQgPSBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IFwiZGVmYXVsdFwiOiBvYmogfTsgfTtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KG9iamVjdCwgcHJvcGVydHksIHJlY2VpdmVyKSB7IHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHByb3BlcnR5KTsgaWYgKGRlc2MgPT09IHVuZGVmaW5lZCkgeyB2YXIgcGFyZW50ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCk7IGlmIChwYXJlbnQgPT09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBlbHNlIHsgcmV0dXJuIGdldChwYXJlbnQsIHByb3BlcnR5LCByZWNlaXZlcik7IH0gfSBlbHNlIGlmIChcInZhbHVlXCIgaW4gZGVzYyAmJiBkZXNjLndyaXRhYmxlKSB7IHJldHVybiBkZXNjLnZhbHVlOyB9IGVsc2UgeyB2YXIgZ2V0dGVyID0gZGVzYy5nZXQ7IGlmIChnZXR0ZXIgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IHJldHVybiBnZXR0ZXIuY2FsbChyZWNlaXZlcik7IH0gfTtcblx0XG5cdHZhciBfaW5oZXJpdHMgPSBmdW5jdGlvbiAoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSBcImZ1bmN0aW9uXCIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCBcIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdHZhciBzdmcgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpO1xuXHR2YXIgSW50ZXJmYWNlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2KTtcblx0dmFyIFN0ZXAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDExKTtcblx0XG5cdHZhciBJbnRlcmFjdGlvbiA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9fd2VicGFja19yZXF1aXJlX18oMTIpKTtcblx0XG5cdC8qKlxuXHQqIFBvc2l0aW9uXG5cdCpcblx0KiBAZGVzY3JpcHRpb24gVHdvLWRpbWVuc2lvbmFsIHRvdWNoIHNsaWRlci5cblx0KlxuXHQqIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwicG9zaXRpb25cIj48L3NwYW4+XG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciBwb3NpdGlvbiA9IG5ldyBOZXh1cy5Qb3NpdGlvbignI3RhcmdldCcpXG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciBwb3NpdGlvbiA9IG5ldyBOZXh1cy5Qb3NpdGlvbignI3RhcmdldCcse1xuXHQqICAgJ3NpemUnOiBbMjAwLDIwMF0sXG5cdCogICAnbW9kZSc6ICdhYnNvbHV0ZScsICAvLyBcImFic29sdXRlXCIgb3IgXCJyZWxhdGl2ZVwiXG5cdCogICAneCc6IDAuNSwgIC8vIGluaXRpYWwgeCB2YWx1ZVxuXHQqICAgJ21pblgnOiAwLFxuXHQqICAgJ21heFgnOiAxLFxuXHQqICAgJ3N0ZXBYJzogMCxcblx0KiAgICd5JzogMC41LCAgLy8gaW5pdGlhbCB5IHZhbHVlXG5cdCogICAnbWluWSc6IDAsXG5cdCogICAnbWF4WSc6IDEsXG5cdCogICAnc3RlcFknOiAwXG5cdCogfSlcblx0KlxuXHQqIEBvdXRwdXRcblx0KiBjaGFuZ2Vcblx0KiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuXHQqIFRoZSBldmVudCBkYXRhIGlzIGFuIG9iamVjdCB3aXRoIHggYW5kIHkgcHJvcGVydGllcyBjb250YWluaW5nIHRoZSB4IGFuZCB5IHZhbHVlcyBvZiB0aGUgaW50ZXJmYWNlLlxuXHQqXG5cdCogQG91dHB1dGV4YW1wbGVcblx0KiBwb3NpdGlvbi5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG5cdCogICBjb25zb2xlLmxvZyh2KTtcblx0KiB9KVxuXHQqXG5cdCpcblx0Ki9cblx0XG5cdHZhciBQb3NpdGlvbiA9IChmdW5jdGlvbiAoX0ludGVyZmFjZSkge1xuXHQgIGZ1bmN0aW9uIFBvc2l0aW9uKCkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFBvc2l0aW9uKTtcblx0XG5cdCAgICB2YXIgb3B0aW9ucyA9IFtcInZhbHVlXCJdO1xuXHRcblx0ICAgIHZhciBkZWZhdWx0cyA9IHtcblx0ICAgICAgc2l6ZTogWzIwMCwgMjAwXSxcblx0ICAgICAgbW9kZTogXCJhYnNvbHV0ZVwiLFxuXHQgICAgICBtaW5YOiAwLFxuXHQgICAgICBtYXhYOiAxLFxuXHQgICAgICBzdGVwWDogMCxcblx0ICAgICAgeDogMC41LFxuXHQgICAgICBtaW5ZOiAwLFxuXHQgICAgICBtYXhZOiAxLFxuXHQgICAgICBzdGVwWTogMCxcblx0ICAgICAgeTogMC41XG5cdCAgICB9O1xuXHRcblx0ICAgIF9nZXQoT2JqZWN0LmdldFByb3RvdHlwZU9mKFBvc2l0aW9uLnByb3RvdHlwZSksIFwiY29uc3RydWN0b3JcIiwgdGhpcykuY2FsbCh0aGlzLCBhcmd1bWVudHMsIG9wdGlvbnMsIGRlZmF1bHRzKTtcblx0XG5cdCAgICB0aGlzLl94ID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5taW5YLCB0aGlzLnNldHRpbmdzLm1heFgsIHRoaXMuc2V0dGluZ3Muc3RlcFgsIHRoaXMuc2V0dGluZ3MueCk7XG5cdCAgICB0aGlzLl95ID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5taW5ZLCB0aGlzLnNldHRpbmdzLm1heFksIHRoaXMuc2V0dGluZ3Muc3RlcFksIHRoaXMuc2V0dGluZ3MueSk7XG5cdFxuXHQgICAgdGhpcy5wb3NpdGlvbiA9IHtcblx0ICAgICAgeDogbmV3IEludGVyYWN0aW9uLkhhbmRsZSh0aGlzLnNldHRpbmdzLm1vZGUsIFwiaG9yaXpvbnRhbFwiLCBbMCwgdGhpcy53aWR0aF0sIFt0aGlzLmhlaWdodCwgMF0pLFxuXHQgICAgICB5OiBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMuc2V0dGluZ3MubW9kZSwgXCJ2ZXJ0aWNhbFwiLCBbMCwgdGhpcy53aWR0aF0sIFt0aGlzLmhlaWdodCwgMF0pXG5cdCAgICB9O1xuXHQgICAgdGhpcy5wb3NpdGlvbi54LnZhbHVlID0gdGhpcy5feC5ub3JtYWxpemVkO1xuXHQgICAgdGhpcy5wb3NpdGlvbi55LnZhbHVlID0gdGhpcy5feS5ub3JtYWxpemVkO1xuXHRcblx0ICAgIHRoaXMuaW5pdCgpO1xuXHQgICAgdGhpcy5yZW5kZXIoKTtcblx0ICB9XG5cdFxuXHQgIF9pbmhlcml0cyhQb3NpdGlvbiwgX0ludGVyZmFjZSk7XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhQb3NpdGlvbiwge1xuXHQgICAgYnVpbGRJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkSW50ZXJmYWNlKCkge1xuXHRcblx0ICAgICAgICB0aGlzLmtub2IgPSBzdmcuY3JlYXRlKFwiY2lyY2xlXCIpO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmtub2IpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2l6ZUludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc2l6ZUludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgdGhpcy5wb3NpdGlvbi54LnJlc2l6ZShbMCwgdGhpcy53aWR0aF0sIFt0aGlzLmhlaWdodCwgMF0pO1xuXHQgICAgICAgIHRoaXMucG9zaXRpb24ueS5yZXNpemUoWzAsIHRoaXMud2lkdGhdLCBbdGhpcy5oZWlnaHQsIDBdKTtcblx0XG5cdCAgICAgICAgdGhpcy5fbWluRGltZW5zaW9uID0gTWF0aC5taW4odGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xuXHRcblx0ICAgICAgICB0aGlzLmtub2JSYWRpdXMgPSB7XG5cdCAgICAgICAgICBvZmY6IH4gfih0aGlzLl9taW5EaW1lbnNpb24gLyAxMDApICogNSArIDUgfTtcblx0ICAgICAgICB0aGlzLmtub2JSYWRpdXMub24gPSB0aGlzLmtub2JSYWRpdXMub2ZmICogMjtcblx0XG5cdCAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImN4XCIsIHRoaXMud2lkdGggLyAyKTtcblx0ICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiY3lcIiwgdGhpcy5oZWlnaHQgLyAyKTtcblx0ICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiclwiLCB0aGlzLmtub2JSYWRpdXMub2ZmKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNvbG9ySW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb2xvckludGVyZmFjZSgpIHtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcblx0ICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcmVuZGVyOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuXHQgICAgICAgICAgLy8gIHRoaXMua25vYlJhZGl1cyA9IDMwO1xuXHQgICAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcInJcIiwgdGhpcy5rbm9iUmFkaXVzLm9uKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgLy8gIHRoaXMua25vYlJhZGl1cyA9IDE1O1xuXHQgICAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcInJcIiwgdGhpcy5rbm9iUmFkaXVzLm9mZik7XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICB0aGlzLmtub2JDb29yZGluYXRlcyA9IHtcblx0ICAgICAgICAgIHg6IHRoaXMuX3gubm9ybWFsaXplZCAqIHRoaXMud2lkdGgsXG5cdCAgICAgICAgICB5OiB0aGlzLmhlaWdodCAtIHRoaXMuX3kubm9ybWFsaXplZCAqIHRoaXMuaGVpZ2h0XG5cdCAgICAgICAgfTtcblx0XG5cdCAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImN4XCIsIHRoaXMua25vYkNvb3JkaW5hdGVzLngpO1xuXHQgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJjeVwiLCB0aGlzLmtub2JDb29yZGluYXRlcy55KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNsaWNrOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjbGljaygpIHtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uLnguYW5jaG9yID0gdGhpcy5tb3VzZTtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uLnkuYW5jaG9yID0gdGhpcy5tb3VzZTtcblx0ICAgICAgICB0aGlzLm1vdmUoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIG1vdmU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIG1vdmUoKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuXHQgICAgICAgICAgdGhpcy5wb3NpdGlvbi54LnVwZGF0ZSh0aGlzLm1vdXNlKTtcblx0ICAgICAgICAgIHRoaXMucG9zaXRpb24ueS51cGRhdGUodGhpcy5tb3VzZSk7XG5cdCAgICAgICAgICB0aGlzLl94LnVwZGF0ZU5vcm1hbCh0aGlzLnBvc2l0aW9uLngudmFsdWUpO1xuXHQgICAgICAgICAgdGhpcy5feS51cGRhdGVOb3JtYWwodGhpcy5wb3NpdGlvbi55LnZhbHVlKTtcblx0ICAgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB7XG5cdCAgICAgICAgICAgIHg6IHRoaXMuX3gudmFsdWUsXG5cdCAgICAgICAgICAgIHk6IHRoaXMuX3kudmFsdWVcblx0ICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByZWxlYXNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZWxlYXNlKCkge1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICB4OiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgKiBUaGUgaW50ZXJmYWNlJ3MgeCB2YWx1ZS4gV2hlbiBzZXQsIGl0IHdpbGwgYXV0b21hdGljYWxseSBhZGp1c3QgdG8gZml0IG1pbi9tYXgvc3RlcCBzZXR0aW5ncyBvZiB0aGUgaW50ZXJmYWNlLlxuXHQgICAgICAqIEB0eXBlIHtvYmplY3R9XG5cdCAgICAgICogQGV4YW1wbGUgcG9zaXRpb24ueCA9IDAuNTtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl94LnZhbHVlO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHQgICAgICAgIHRoaXMuX3gudXBkYXRlKHZhbHVlKTtcblx0ICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwge1xuXHQgICAgICAgICAgeDogdGhpcy5feC52YWx1ZSxcblx0ICAgICAgICAgIHk6IHRoaXMuX3kudmFsdWVcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgeToge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgICogVGhlIGludGVyZmFjZSdzIHkgdmFsdWVzLiBXaGVuIHNldCwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IGFkanVzdCB0byBmaXQgbWluL21heC9zdGVwIHNldHRpbmdzIG9mIHRoZSBpbnRlcmZhY2UuXG5cdCAgICAgICogQHR5cGUge29iamVjdH1cblx0ICAgICAgKiBAZXhhbXBsZSBwb3NpdGlvbi54ID0gMC41O1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3kudmFsdWU7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG5cdCAgICAgICAgdGhpcy5feS51cGRhdGUodmFsdWUpO1xuXHQgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB7XG5cdCAgICAgICAgICB4OiB0aGlzLl94LnZhbHVlLFxuXHQgICAgICAgICAgeTogdGhpcy5feS52YWx1ZVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBub3JtYWxpemVkOiB7XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICB4OiB0aGlzLl94Lm5vcm1hbGl6ZWQsXG5cdCAgICAgICAgICB5OiB0aGlzLl95Lm5vcm1hbGl6ZWRcblx0ICAgICAgICB9O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbWluWDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgICogVGhlIGxvd2VyIGxpbWl0IG9mIHZhbHVlIG9uIHRoZSB4IGF4aXNcblx0ICAgICAgKiBAdHlwZSB7b2JqZWN0fVxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3gubWluO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdGhpcy5feC5taW4gPSB2O1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBtaW5ZOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgKiBUaGUgbG93ZXIgbGltaXQgb2YgdmFsdWUgb24gdGhlIHkgYXhpc1xuXHQgICAgICAqIEB0eXBlIHtvYmplY3R9XG5cdCAgICAgICovXG5cdFxuXHQgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5feS5taW47XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLl95Lm1pbiA9IHY7XG5cdCAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIG1heFg6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICAqIFRoZSB1cHBlciBsaW1pdCBvZiB2YWx1ZSBvbiB0aGUgeCBheGlzXG5cdCAgICAgICogQHR5cGUge29iamVjdH1cblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl94Lm1heDtcblx0ICAgICAgfSxcblx0ICAgICAgc2V0OiBmdW5jdGlvbiAodikge1xuXHQgICAgICAgIHRoaXMuX3gubWF4ID0gdjtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbWF4WToge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgICogVGhlIHVwcGVyIGxpbWl0IG9mIHZhbHVlIG9uIHRoZSB5IGF4aXNcblx0ICAgICAgKiBAdHlwZSB7b2JqZWN0fVxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3kubWF4O1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdGhpcy5feS5tYXggPSB2O1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzdGVwWDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgICogVGhlIGluY3JlbWVudGFsIHN0ZXAgb2YgdmFsdWVzIG9uIHRoZSB4IGF4aXNcblx0ICAgICAgKiBAdHlwZSB7b2JqZWN0fVxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3guc3RlcDtcblx0ICAgICAgfSxcblx0ICAgICAgc2V0OiBmdW5jdGlvbiAodikge1xuXHQgICAgICAgIHRoaXMuX3guc3RlcCA9IHY7XG5cdCAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHN0ZXBZOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgKiBUaGUgaW5jcmVtZW50YWwgc3RlcCBvZiB2YWx1ZXMgb24gdGhlIHkgYXhpc1xuXHQgICAgICAqIEB0eXBlIHtvYmplY3R9XG5cdCAgICAgICovXG5cdFxuXHQgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5feS5zdGVwO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdGhpcy5feS5zdGVwID0gdjtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbW9kZToge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIEFic29sdXRlIG1vZGUgKHBvc2l0aW9uJ3MgdmFsdWUganVtcHMgdG8gbW91c2UgY2xpY2sgcG9zaXRpb24pIG9yIHJlbGF0aXZlIG1vZGUgKG1vdXNlIGRyYWcgY2hhbmdlcyB2YWx1ZSByZWxhdGl2ZSB0byBpdHMgY3VycmVudCBwb3NpdGlvbikuIERlZmF1bHQ6IFwiYWJzb2x1dGVcIi5cblx0ICAgICAgQHR5cGUge3N0cmluZ31cblx0ICAgICAgQGV4YW1wbGUgcG9zaXRpb24ubW9kZSA9IFwicmVsYXRpdmVcIjtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uLngubW9kZTtcblx0ICAgICAgfSxcblx0ICAgICAgc2V0OiBmdW5jdGlvbiAodikge1xuXHQgICAgICAgIHRoaXMucG9zaXRpb24ueC5tb2RlID0gdjtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uLnkubW9kZSA9IHY7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIFBvc2l0aW9uO1xuXHR9KShJbnRlcmZhY2UpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBQb3NpdGlvbjtcblxuLyoqKi8gfSksXG4vKiA0ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgbWF0aCA9IF9fd2VicGFja19yZXF1aXJlX18oNSk7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IHtcblx0XG5cdCAgY3JlYXRlOiBmdW5jdGlvbiAodHlwZSkge1xuXHQgICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIHR5cGUpO1xuXHQgIH0sXG5cdFxuXHQgIGFyYzogZnVuY3Rpb24gKHgsIHksIHJhZGl1cywgc3RhcnRBbmdsZSwgZW5kQW5nbGUpIHtcblx0XG5cdCAgICB2YXIgc3RhcnQgPSBtYXRoLnRvQ2FydGVzaWFuKHJhZGl1cywgZW5kQW5nbGUpO1xuXHQgICAgdmFyIGVuZCA9IG1hdGgudG9DYXJ0ZXNpYW4ocmFkaXVzLCBzdGFydEFuZ2xlKTtcblx0XG5cdCAgICB2YXIgbGFyZ2VBcmNGbGFnID0gZW5kQW5nbGUgLSBzdGFydEFuZ2xlIDw9IDE4MCA/IFwiMFwiIDogXCIxXCI7XG5cdFxuXHQgICAgdmFyIGQgPSBbXCJNXCIsIHN0YXJ0LnggKyB4LCBzdGFydC55ICsgeSwgXCJBXCIsIHJhZGl1cywgcmFkaXVzLCAwLCBsYXJnZUFyY0ZsYWcsIDAsIGVuZC54ICsgeCwgZW5kLnkgKyB5XS5qb2luKFwiIFwiKTtcblx0XG5cdCAgICByZXR1cm4gZDtcblx0ICB9LFxuXHRcblx0ICByYWRpYWxHcmFkaWVudDogZnVuY3Rpb24gKGRlZnMsIG51bWJlck9mU3RvcHMpIHtcblx0XG5cdCAgICB2YXIgaWQgPSBcImdyYWRpZW50XCIgKyBtYXRoLnJpKDEwMDAwMDAwMDAwMCk7XG5cdCAgICB2YXIgc3RvcHMgPSBbXTtcblx0XG5cdCAgICB2YXIgZ3JhZGllbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCBcInJhZGlhbEdyYWRpZW50XCIpO1xuXHQgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgaWQpO1xuXHQgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlKFwiY3hcIiwgXCI1MCVcIik7XG5cdCAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGUoXCJjeVwiLCBcIjUwJVwiKTtcblx0ICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZShcInJcIiwgXCI1MCVcIik7XG5cdFxuXHQgICAgZGVmcy5hcHBlbmRDaGlsZChncmFkaWVudCk7XG5cdFxuXHQgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1iZXJPZlN0b3BzOyBpKyspIHtcblx0ICAgICAgdmFyIF9zdG9wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiwgXCJzdG9wXCIpO1xuXHQgICAgICBfc3RvcC5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBcInN0b3BcIiArIGkpO1xuXHQgICAgICAvL3N0b3Auc2V0QXR0cmlidXRlKCdvZmZzZXQnLCAnNzAlJyk7XG5cdCAgICAgIC8vc3RvcC5zZXRBdHRyaWJ1dGUoJ3N0b3AtY29sb3InLCAnV2hpdGUnKTtcblx0ICAgICAgZ3JhZGllbnQuYXBwZW5kQ2hpbGQoX3N0b3ApO1xuXHQgICAgICBzdG9wcy5wdXNoKF9zdG9wKTtcblx0ICAgIH1cblx0XG5cdCAgICByZXR1cm4ge1xuXHQgICAgICBpZDogaWQsXG5cdCAgICAgIHN0b3BzOiBzdG9wcyxcblx0ICAgICAgZWxlbWVudDogZ3JhZGllbnRcblx0ICAgIH07XG5cdCAgfVxuXHRcblx0fTtcblxuLyoqKi8gfSksXG4vKiA1ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHQvKipcblx0ICogTGltaXQgYSBudW1iZXIgdG8gd2l0aGluIGEgbWluaW11bSBhbmQgbWF4aW11bVxuXHQgKiBAcGFyYW0gIHtudW1iZXJ9IHZhbHVlIElucHV0IHZhbHVlXG5cdCAqIEBwYXJhbSAge251bWJlcn0gbWluICAgTG93ZXIgbGltaXRcblx0ICogQHBhcmFtICB7bnVtYmVyfSBtYXggICBVcHBlciBsaW1pdFxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgIFRoZSBpbnB1dCB2YWx1ZSBjb25zdHJhaW5lZCB3aXRoaW4gdGhlIGxvd2VyIGFuZCB1cHBlciBsaW1pdHNcblx0ICogQGV4YW1wbGVcblx0ICogTmV4dXMuY2xpcCgxMSwwLDEwKSAgIC8vIHJldHVybnMgMTBcblx0ICogTmV4dXMuY2xpcCgtMSwwLDEwKSAgIC8vIHJldHVybnMgMFxuXHQgKiBOZXh1cy5jbGlwKDUsMCwxMCkgICAgLy8gcmV0dXJucyA1XG5cdCAqL1xuXHRcblx0ZXhwb3J0cy5jbGlwID0gZnVuY3Rpb24gKHZhbHVlLCBtaW4sIG1heCkge1xuXHQgIHJldHVybiBNYXRoLm1pbihNYXRoLm1heCh2YWx1ZSwgbWluKSwgbWF4KTtcblx0fTtcblx0XG5cdGV4cG9ydHMubm9ybWFsaXplID0gZnVuY3Rpb24gKHZhbHVlLCBtaW4sIG1heCkge1xuXHQgIHJldHVybiAodmFsdWUgLSBtaW4pIC8gKG1heCAtIG1pbik7XG5cdH07XG5cdFxuXHQvKipcblx0ICogU2NhbGUgYSB2YWx1ZSBmcm9tIG9uZSByYW5nZSB0byBhbm90aGVyIHJhbmdlLlxuXHQgKiBAcGFyYW0gIHtudW1iZXJ9IGluTnVtICBJbnB1dCB2YWx1ZVxuXHQgKiBAcGFyYW0gIHtudW1iZXJ9IGluTWluICBJbnB1dCByYW5nZSBtaW5pbXVtXG5cdCAqIEBwYXJhbSAge251bWJlcn0gaW5NYXggIElucHV0IHJhbmdlIG1heGltdW1cblx0ICogQHBhcmFtICB7bnVtYmVyfSBvdXRNaW4gT3V0cHV0IHJhbmdlIG1pbmltdW1cblx0ICogQHBhcmFtICB7bnVtYmVyfSBvdXRNYXggT3V0cHV0IHJhbmdlIG1heGltdW1cblx0ICogQHJldHVybiB7bnVtYmVyfSAgICAgICAgVGhlIGlucHV0IHZhbHVlIHNjYWxlZCB0byBpdHMgbmV3IHJhbmdlXG5cdCAqIEBleGFtcGxlXG5cdCAqIE5leHVzLnNjYWxlKDAuNSwwLDEsMCwxMCkgICAvLyByZXR1cm5zIDVcblx0ICogTmV4dXMuc2NhbGUoMC45LDAsMSwxLDApICAgIC8vIHJldHVybnMgMC4xXG5cdCAqL1xuXHRleHBvcnRzLnNjYWxlID0gZnVuY3Rpb24gKGluTnVtLCBpbk1pbiwgaW5NYXgsIG91dE1pbiwgb3V0TWF4KSB7XG5cdCAgaWYgKGluTWluID09PSBpbk1heCkge1xuXHQgICAgcmV0dXJuIG91dE1pbjtcblx0ICB9XG5cdCAgcmV0dXJuIChpbk51bSAtIGluTWluKSAqIChvdXRNYXggLSBvdXRNaW4pIC8gKGluTWF4IC0gaW5NaW4pICsgb3V0TWluO1xuXHR9O1xuXHRcblx0ZXhwb3J0cy50b1BvbGFyID0gZnVuY3Rpb24gKHgsIHkpIHtcblx0ICB2YXIgciA9IE1hdGguc3FydCh4ICogeCArIHkgKiB5KTtcblx0XG5cdCAgdmFyIHRoZXRhID0gTWF0aC5hdGFuMih5LCB4KTtcblx0ICBpZiAodGhldGEgPCAwKSB7XG5cdCAgICB0aGV0YSA9IHRoZXRhICsgMiAqIE1hdGguUEk7XG5cdCAgfVxuXHQgIHJldHVybiB7IHJhZGl1czogciwgYW5nbGU6IHRoZXRhIH07XG5cdH07XG5cdFxuXHRleHBvcnRzLnRvQ2FydGVzaWFuID0gZnVuY3Rpb24gKHJhZGl1cywgYW5nbGUpIHtcblx0ICB2YXIgY29zID0gTWF0aC5jb3MoYW5nbGUpO1xuXHQgIHZhciBzaW4gPSBNYXRoLnNpbihhbmdsZSk7XG5cdCAgcmV0dXJuIHsgeDogcmFkaXVzICogY29zLCB5OiByYWRpdXMgKiBzaW4gKiAtMSB9O1xuXHR9O1xuXHQvKlxuXHRleHBvcnRzLnBvbGFyVG9DYXJ0ZXNpYW4oY2VudGVyWCwgY2VudGVyWSwgcmFkaXVzLCBhbmdsZUluRGVncmVlcykge1xuXHQgIHZhciBhbmdsZUluUmFkaWFucyA9IChhbmdsZUluRGVncmVlcy05MCkgKiBNYXRoLlBJIC8gMTgwLjA7XG5cdFxuXHQgIHJldHVybiB7XG5cdCAgICB4OiBjZW50ZXJYICsgKHJhZGl1cyAqIE1hdGguY29zKGFuZ2xlSW5SYWRpYW5zKSksXG5cdCAgICB5OiBjZW50ZXJZICsgKHJhZGl1cyAqIE1hdGguc2luKGFuZ2xlSW5SYWRpYW5zKSlcblx0ICB9O1xuXHR9ICAqL1xuXHRcblx0ZXhwb3J0cy5wcnVuZSA9IGZ1bmN0aW9uIChkYXRhLCBzY2FsZSkge1xuXHQgIHJldHVybiBwYXJzZUZsb2F0KGRhdGEudG9GaXhlZChzY2FsZSkpO1xuXHR9O1xuXHRcblx0ZXhwb3J0cy5pbnZlcnQgPSBmdW5jdGlvbiAoaW5OdW0pIHtcblx0ICByZXR1cm4gZXhwb3J0cy5zY2FsZShpbk51bSwgMSwgMCwgMCwgMSk7XG5cdH07XG5cdFxuXHQvKipcblx0ICogQ29udmVydCBhIE1JRGkgbm90ZSBudW1iZXIgdG8gYSBmcmVxdWVuY3kgdmFsdWUgaW4gZXF1YWwgdGVtcGVyYW1lbnQuXG5cdCAqIEBwYXJhbSAge251bWJlcn0gbWlkaSBNSURJIG5vdGUgdmFsdWVcblx0ICogQHJldHVybiB7bnVtYmVyfSAgICAgIEZyZXF1ZW5jZSB2YWx1ZVxuXHQgKiBAZXhhbXBsZVxuXHQgKiBOZXh1cy5tdG9mKDYwKSAgLy8gcmV0dXJucyB0aGUgZnJlcXVlbmN5IG51bWJlciBvZiBNaWRkbGUgQ1xuXHQgKi9cblx0ZXhwb3J0cy5tdG9mID0gZnVuY3Rpb24gKG1pZGkpIHtcblx0ICByZXR1cm4gTWF0aC5wb3coMiwgKG1pZGkgLSA2OSkgLyAxMikgKiA0NDA7XG5cdH07XG5cdFxuXHQvKipcblx0ICogSW50ZXJwb2xhdGUgYmV0d2VlbiB0d28gbnVtYmVyc1xuXHQgKiBAcGFyYW0gIHtudW1iZXJ9IGxvYyBJbnRlcnBvbGF0aW9uIGluZGV4ICgwLTEpXG5cdCAqIEBwYXJhbSAge251bWJlcn0gbWluIExvd2VyIHZhbHVlXG5cdCAqIEBwYXJhbSAge251bWJlcn0gbWF4IFVwcGVyIHZhbHVlXG5cdCAqIEByZXR1cm4ge251bWJlcn0gICAgIEludGVycG9sYXRlZCB2YWx1ZVxuXHQgKiBAZXhhbXBsZVxuXHQgKiBOZXh1cy5pbnRlcnAoMC41LDIsNCkgICAvLyByZXR1cm5zIDNcblx0ICogTmV4dXMuaW50ZXJwKDAuMSwwLDEwKSAgICAgLy8gcmV0dXJucyAxXG5cdCAqL1xuXHRleHBvcnRzLmludGVycCA9IGZ1bmN0aW9uIChsb2MsIG1pbiwgbWF4KSB7XG5cdCAgcmV0dXJuIGxvYyAqIChtYXggLSBtaW4pICsgbWluO1xuXHR9O1xuXHRcblx0LyoqXG5cdCAqIFJldHVybiBhIHJhbmRvbSBjaG9pY2UgZnJvbSBhIGxpc3Qgb2YgYXJndW1lbnRzXG5cdCAqIEByZXR1cm4ge3ZhcmlvdXN9IE9uZSByYW5kb20gYXJndW1lbnRcblx0ICogQGV4YW1wbGVcblx0ICogTmV4dXMucGljaygxLDIsMyw0KSAgIC8vIHJldHVybnMgMSwgMiwgMywgb3IgNFxuXHQgKiBOZXh1cy5waWNrKGZ1bmN0aW9uMSxmdW5jdGlvbjIpICAgLy8gcmV0dXJucyBlaXRoZXIgZnVuY3Rpb24xIG9yIGZ1bmN0aW9uMlxuXHQgKi9cblx0ZXhwb3J0cy5waWNrID0gZnVuY3Rpb24gKCkge1xuXHQgIHJldHVybiBhcmd1bWVudHNbfiB+KE1hdGgucmFuZG9tKCkgKiBhcmd1bWVudHMubGVuZ3RoKV07XG5cdH07XG5cdFxuXHQvKipcblx0ICogUmV0dXJucyBhbiBvY3RhdmUgbXVsdGlwbGllciBmb3IgZnJlcXVlbmN5IHZhbHVlc1xuXHQgKiBAcGFyYW0gIHtudW1iZXJ9IG51bSBSZWxhdGl2ZSBvY3RhdmUgbnVtYmVyIChlLmcuIC0xIGZvciBvbmUgb2N0YXZlIGRvd24sIDEgZm9yIG9uZSBvY3RhdmUgdXApXG5cdCAqIEByZXR1cm4ge251bWJlcn0gICAgIE9jdGF2ZSBtdWx0aXBsaWVyXG5cdCAqIEBleGFtcGxlXG5cdCAqIE5leHVzLm9jdGF2ZSgtMSkgIC8vIHJldHVybnMgMC41XG5cdCAqIE5leHVzLm9jdGF2ZSgwKSAgIC8vIHJldHVybnMgMVxuXHQgKiBOZXh1cy5vY3RhdmUoMSkgICAvLyByZXR1cm5zIDJcblx0ICogTmV4dXMub2N0YXZlKDIpICAgLy8gcmV0dXJucyA0XG5cdCAqL1xuXHRleHBvcnRzLm9jdGF2ZSA9IGZ1bmN0aW9uIChudW0pIHtcblx0ICByZXR1cm4gTWF0aC5wb3coMiwgbnVtKTtcblx0fTtcblx0XG5cdC8qKlxuXHQgKiBSYW5kb20gaW50ZWdlciBnZW5lcmF0b3IuIElmIG5vIHNlY29uZCBhcmd1bWVudCBpcyBnaXZlbiwgd2lsbCByZXR1cm4gcmFuZG9tIGludGVnZXIgZnJvbSAwIHRvIGJvdW5kMS5cblx0ICogQHBhcmFtICB7bnVtYmVyfSBib3VuZDEgTWluaW11bSByYW5kb20gdmFsdWVcblx0ICogQHBhcmFtICB7bnVtYmVyfSBib3VuZDIgTWF4aW11bSByYW5kb20gdmFsdWVcblx0ICogQHJldHVybiB7bnVtYmVyfSAgICAgICAgUmFuZG9tIGludGVnZXIgYmV0d2VlbiBsb3dlciBhbmQgdXBwZXIgYm91bmRhcnlcblx0ICogQGV4YW1wbGVcblx0ICogTmV4dXMucmkoMTApICAgIC8vIHJldHVybnMgcmFuZG9tIGludCBmcm9tIDAgdG8gMTBcblx0ICogTmV4dXMucmkoMjAsMjAwMCkgLy8gcmV0dXJucyByYW5kb20gaW50IGZyb20gMjAgdG8gMjAwMFxuXHQgKi9cblx0ZXhwb3J0cy5yaSA9IGZ1bmN0aW9uIChib3VuZDEsIGJvdW5kMikge1xuXHQgIGlmICghYm91bmQyKSB7XG5cdCAgICBib3VuZDIgPSBib3VuZDE7XG5cdCAgICBib3VuZDEgPSAwO1xuXHQgIH1cblx0ICB2YXIgbG93ID0gTWF0aC5taW4oYm91bmQxLCBib3VuZDIpO1xuXHQgIHZhciBoaWdoID0gTWF0aC5tYXgoYm91bmQxLCBib3VuZDIpO1xuXHQgIHJldHVybiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAoaGlnaCAtIGxvdykgKyBsb3cpO1xuXHR9O1xuXHRcblx0LyoqXG5cdCAqIFJhbmRvbSBmbG9hdCBudW1iZXIgZ2VuZXJhdG9yLiBJZiBubyBzZWNvbmQgYXJndW1lbnQgaXMgZ2l2ZW4sIHdpbGwgcmV0dXJuIHJhbmRvbSBmbG9hdCBmcm9tIDAgdG8gYm91bmQxLlxuXHQgKiBAcGFyYW0gIHtudW1iZXJ9IGJvdW5kMSBNaW5pbXVtIHJhbmRvbSB2YWx1ZVxuXHQgKiBAcGFyYW0gIHtudW1iZXJ9IGJvdW5kMiBNYXhpbXVtIHJhbmRvbSB2YWx1ZVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgICBSYW5kb20gZmxvYXQgYmV0d2VlbiBsb3dlciBhbmQgdXBwZXIgYm91bmRhcnlcblx0ICogQGV4YW1wbGVcblx0ICogTmV4dXMucmYoMSkgICAgLy8gcmV0dXJucyByYW5kb20gZmxvYXQgZnJvbSAwIHRvIDFcblx0ICogTmV4dXMucmYoMSwyKSAvLyByZXR1cm5zIHJhbmRvbSBmbG9hdCBmcm9tIDEgdG8gMlxuXHQgKi9cblx0ZXhwb3J0cy5yZiA9IGZ1bmN0aW9uIChib3VuZDEsIGJvdW5kMikge1xuXHQgIGlmICghYm91bmQyKSB7XG5cdCAgICBib3VuZDIgPSBib3VuZDE7XG5cdCAgICBib3VuZDEgPSAwO1xuXHQgIH1cblx0ICB2YXIgbG93ID0gTWF0aC5taW4oYm91bmQxLCBib3VuZDIpO1xuXHQgIHZhciBoaWdoID0gTWF0aC5tYXgoYm91bmQxLCBib3VuZDIpO1xuXHQgIHJldHVybiBNYXRoLnJhbmRvbSgpICogKGhpZ2ggLSBsb3cpICsgbG93O1xuXHR9O1xuXHRcblx0ZXhwb3J0cy5jeWNsZSA9IGZ1bmN0aW9uIChpbnB1dCwgbWluLCBtYXgpIHtcblx0ICBpbnB1dCsrO1xuXHQgIGlmIChpbnB1dCA+PSBtYXgpIHtcblx0ICAgIGlucHV0ID0gbWluO1xuXHQgIH1cblx0ICByZXR1cm4gaW5wdXQ7XG5cdH07XG5cdFxuXHQvKipcblx0ICogQXZlcmFnZSBhbiBhcnJheSBvZiBudW1iZXJzXG5cdCAqIEBwYXJhbSAge0FycmF5fSBkYXRhIEFycmF5IG9mIG51bWJlcnMgdG8gYXZlcmFnZVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgQXZlcmFnZSBvZiB0aGUgaW5wdXQgZGF0YVxuXHQgKiBAZXhhbXBsZVxuXHQgKiBOZXh1cy5hdmVyYWdlKFswLDIsNCw2LDgsMTBdKSAgIC8vIHJldHVybnMgNVxuXHQgKi9cblx0ZXhwb3J0cy5hdmVyYWdlID0gZnVuY3Rpb24gKGRhdGEpIHtcblx0ICB2YXIgdG90YWwgPSAwO1xuXHQgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuXHQgICAgdG90YWwgKz0gZGF0YVtpXTtcblx0ICB9XG5cdCAgcmV0dXJuIHRvdGFsIC8gZGF0YS5sZW5ndGg7XG5cdH07XG5cdFxuXHQvKipcblx0ICogR2V0IHRoZSBkaXN0YW5jZSBmcm9tIG9uZSAoeCx5KSBwb2ludCB0byBhbm90aGVyICh4LHkpIHBvaW50XG5cdCAqIEBwYXJhbSAge251bWJlcn0geDEgeCBvZiBmaXJzdCBwb2ludFxuXHQgKiBAcGFyYW0gIHtudW1iZXJ9IHkxIHkgb2YgZmlyc3QgcG9pbnRcblx0ICogQHBhcmFtICB7bnVtYmVyfSB4MiB4IG9mIHNlY29uZCBwb2ludFxuXHQgKiBAcGFyYW0gIHtudW1iZXJ9IHkyIHkgb2Ygc2Vjb25kIHBvaW55XG5cdCAqIEByZXR1cm4ge251bWJlcn0gICAgRGlzdGFuY2Vcblx0ICogQGV4YW1wbGVcblx0ICogTmV4dXMuZGlzdGFuY2UoMCwwLDMsNCkgICAvLyByZXR1cm5zIDVcblx0ICovXG5cdGV4cG9ydHMuZGlzdGFuY2UgPSBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIpIHtcblx0ICB2YXIgYSA9IHgxIC0geDI7XG5cdCAgdmFyIGIgPSB5MSAtIHkyO1xuXHQgIHJldHVybiBNYXRoLnNxcnQoYSAqIGEgKyBiICogYik7XG5cdH07XG5cdFxuXHRleHBvcnRzLmdhaW5Ub0RCID0gZnVuY3Rpb24gKGdhaW4pIHtcblx0ICByZXR1cm4gMjAgKiBNYXRoLmxvZzEwKGdhaW4pO1xuXHR9O1xuXHRcblx0LyoqXG5cdCAqIEZsaXAgYSBjb2luLCByZXR1cm5pbmcgZWl0aGVyIDAgb3IgMSBhY2NvcmRpbmcgdG8gYSBwcm9iYWJpbGl0eVxuXHQgKiBAcGFyYW0gIHtudW1iZXJ9IFtvZGRzPTAuNV0gTGlrZWxpaG9vZCBvZiByZXR1cm5pbmcgMVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgICAgICAgMSBvciAwXG5cdCAqIEBleGFtcGxlXG5cdCAqIE5leHVzLmNvaW4oMC4xKSAgIC8vIHJldHVybnMgMSAoMTAlIG9mIHRoZSB0aW1lKSBvciAwICg5MCUgb2YgdGhlIHRpbWUpXG5cdCAqL1xuXHRleHBvcnRzLmNvaW4gPSBmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIG9kZHMgPSBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IDAuNSA6IGFyZ3VtZW50c1swXTtcblx0XG5cdCAgaWYgKGV4cG9ydHMucmYoMCwgMSkgPCBvZGRzKSB7XG5cdCAgICByZXR1cm4gMTtcblx0ICB9IGVsc2Uge1xuXHQgICAgcmV0dXJuIDA7XG5cdCAgfVxuXHR9O1xuXG4vKioqLyB9KSxcbi8qIDYgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KG9iamVjdCwgcHJvcGVydHksIHJlY2VpdmVyKSB7IHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHByb3BlcnR5KTsgaWYgKGRlc2MgPT09IHVuZGVmaW5lZCkgeyB2YXIgcGFyZW50ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCk7IGlmIChwYXJlbnQgPT09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBlbHNlIHsgcmV0dXJuIGdldChwYXJlbnQsIHByb3BlcnR5LCByZWNlaXZlcik7IH0gfSBlbHNlIGlmIChcInZhbHVlXCIgaW4gZGVzYyAmJiBkZXNjLndyaXRhYmxlKSB7IHJldHVybiBkZXNjLnZhbHVlOyB9IGVsc2UgeyB2YXIgZ2V0dGVyID0gZGVzYy5nZXQ7IGlmIChnZXR0ZXIgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IHJldHVybiBnZXR0ZXIuY2FsbChyZWNlaXZlcik7IH0gfTtcblx0XG5cdHZhciBfaW5oZXJpdHMgPSBmdW5jdGlvbiAoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSBcImZ1bmN0aW9uXCIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCBcIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdHZhciBzdmcgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpO1xuXHR2YXIgZG9tID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3KTtcblx0dmFyIHV0aWwgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDgpO1xuXHR2YXIgdG91Y2ggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDkpO1xuXHR2YXIgRXZlbnRFbWl0dGVyID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMCk7XG5cdFxuXHR2YXIgY29sb3JzID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKS5jb2xvcnM7XG5cdFxuXHQvKipcblx0SW50ZXJmYWNlXG5cdCovXG5cdFxuXHR2YXIgSW50ZXJmYWNlID0gKGZ1bmN0aW9uIChfRXZlbnRFbWl0dGVyKSB7XG5cdCAgZnVuY3Rpb24gSW50ZXJmYWNlKGFyZ3MsIG9wdGlvbnMsIGRlZmF1bHRzKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgSW50ZXJmYWNlKTtcblx0XG5cdCAgICBfZ2V0KE9iamVjdC5nZXRQcm90b3R5cGVPZihJbnRlcmZhY2UucHJvdG90eXBlKSwgXCJjb25zdHJ1Y3RvclwiLCB0aGlzKS5jYWxsKHRoaXMpO1xuXHQgICAgdGhpcy50eXBlID0gdGhpcy5jb25zdHJ1Y3Rvci5uYW1lO1xuXHQgICAgdGhpcy5zZXR0aW5ncyA9IHRoaXMucGFyc2VTZXR0aW5ncyhhcmdzLCBvcHRpb25zLCBkZWZhdWx0cyk7XG5cdCAgICB0aGlzLm1vdXNlID0ge307XG5cdCAgICB0aGlzLndhaXQgPSBmYWxzZTtcblx0ICAgIHRoaXMuY29sb3JzID0ge307XG5cdCAgICB2YXIgZGVmYXVsdENvbG9ycyA9IGNvbG9ycygpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblx0ICAgIHRoaXMuY29sb3JzLmFjY2VudCA9IGRlZmF1bHRDb2xvcnMuYWNjZW50O1xuXHQgICAgdGhpcy5jb2xvcnMuZmlsbCA9IGRlZmF1bHRDb2xvcnMuZmlsbDtcblx0ICAgIHRoaXMuY29sb3JzLmxpZ2h0ID0gZGVmYXVsdENvbG9ycy5saWdodDtcblx0ICAgIHRoaXMuY29sb3JzLmRhcmsgPSBkZWZhdWx0Q29sb3JzLmRhcms7XG5cdCAgICB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCA9IGRlZmF1bHRDb2xvcnMubWVkaXVtTGlnaHQ7XG5cdCAgICB0aGlzLmNvbG9ycy5tZWRpdW1EYXJrID0gZGVmYXVsdENvbG9ycy5tZWRpdW1EYXJrO1xuXHQgIH1cblx0XG5cdCAgX2luaGVyaXRzKEludGVyZmFjZSwgX0V2ZW50RW1pdHRlcik7XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhJbnRlcmZhY2UsIHtcblx0ICAgIHBhcnNlU2V0dGluZ3M6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHBhcnNlU2V0dGluZ3MoYXJncywgb3B0aW9ucywgZGVmYXVsdHMpIHtcblx0XG5cdCAgICAgICAgb3B0aW9ucy51bnNoaWZ0KFwidGFyZ2V0XCIpO1xuXHQgICAgICAgIGRlZmF1bHRzLmRlZmF1bHRTaXplID0gZGVmYXVsdHMuc2l6ZS5zcGxpY2UoMCwgMik7XG5cdCAgICAgICAgZGVmYXVsdHMuc2l6ZSA9IGZhbHNlO1xuXHRcblx0ICAgICAgICB2YXIgc2V0dGluZ3MgPSB7XG5cdCAgICAgICAgICB0YXJnZXQ6IGRvY3VtZW50LmJvZHksXG5cdCAgICAgICAgICBjb2xvcnM6IHt9LCAvLyBzaG91bGQgaW5oZXJpdCBmcm9tIGEgY29sb3JzIG1vZHVsZSxcblx0ICAgICAgICAgIHNuYXBXaXRoUGFyZW50OiB0cnVlLFxuXHQgICAgICAgICAgZXZlbnQ6IGZ1bmN0aW9uIGV2ZW50KCkge30sXG5cdCAgICAgICAgICBjb21wb25lbnQ6IGZhbHNlXG5cdCAgICAgICAgfTtcblx0XG5cdCAgICAgICAgZm9yICh2YXIga2V5IGluIGRlZmF1bHRzKSB7XG5cdCAgICAgICAgICBzZXR0aW5nc1trZXldID0gZGVmYXVsdHNba2V5XTtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgLy8gZ3JhYnMgdGhlIG5leHQgYXJndW1lbnRcblx0ICAgICAgICAgIHZhciBzZXR0aW5nID0gYXJnc1tpXTtcblx0ICAgICAgICAgIC8vIGlmIGl0J3MgYW4gb2JqZWN0LCBpdCBtdXN0IGJlIHRoZSBzZXR0aW5ncyBvYmplY3Rcblx0ICAgICAgICAgIGlmICh1dGlsLmlzT2JqZWN0KHNldHRpbmcpKSB7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBzZXR0aW5nKSB7XG5cdCAgICAgICAgICAgICAgc2V0dGluZ3Nba2V5XSA9IHNldHRpbmdba2V5XTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAvLyBpZiBpdCdzIGEgZnVuY3Rpb24sIGl0IG11c3QgYmUgdGhlIGV2ZW50IHNldHRpbmdcblx0ICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHNldHRpbmcgPT09IFwiZnVuY3Rpb25cIikge1xuXHQgICAgICAgICAgICBzZXR0aW5ncy5ldmVudCA9IHNldHRpbmc7XG5cdCAgICAgICAgICAgIC8vIG90aGVyd2lzZSwgY29uc2lkZXIgaXQgb25lIG9mIHRoZSB3aWRnZXQncyBjdXN0b20gb3B0aW9uc1xuXHQgICAgICAgICAgfSBlbHNlIGlmIChvcHRpb25zLmxlbmd0aCA+PSAxKSB7XG5cdCAgICAgICAgICAgIC8vIGdyYWIgdGhlIGZpcnN0IG9wdGlvbiAtLSBpLmUuICd0YXJnZXQnXG5cdCAgICAgICAgICAgIHZhciBrZXkgPSBvcHRpb25zLnNwbGljZSgwLCAxKVswXTtcblx0ICAgICAgICAgICAgc2V0dGluZ3Nba2V5XSA9IHNldHRpbmc7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICAvKiAgaGFuZGxlIGNvbW1vbiBzZXR0aW5ncyAgKi9cblx0XG5cdCAgICAgICAgLy8gdGFyZ2V0XG5cdCAgICAgICAgdGhpcy5wYXJlbnQgPSBkb20ucGFyc2VFbGVtZW50KHNldHRpbmdzLnRhcmdldCk7XG5cdFxuXHQgICAgICAgIC8vIG5leHVzLXVpIGF0dHJpYnV0ZVxuXHQgICAgICAgIGlmICh0aGlzLnBhcmVudCAmJiB0aGlzLnBhcmVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmICFzZXR0aW5ncy5jb21wb25lbnQpIHtcblx0ICAgICAgICAgIGlmICghdGhpcy5wYXJlbnQuaGFzQXR0cmlidXRlKFwibmV4dXMtdWlcIikpIHtcblx0ICAgICAgICAgICAgdGhpcy5wYXJlbnQuc2V0QXR0cmlidXRlKFwibmV4dXMtdWlcIiwgXCJcIik7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICAvLyBzaXplXG5cdFxuXHQgICAgICAgIGlmIChzZXR0aW5ncy5zaXplICYmIEFycmF5LmlzQXJyYXkoc2V0dGluZ3Muc2l6ZSkgJiYgc2V0dGluZ3Muc25hcFdpdGhQYXJlbnQpIHtcblx0ICAgICAgICAgIHRoaXMud2lkdGggPSBzZXR0aW5ncy5zaXplWzBdO1xuXHQgICAgICAgICAgdGhpcy5oZWlnaHQgPSBzZXR0aW5ncy5zaXplWzFdO1xuXHQgICAgICAgICAgdGhpcy5wYXJlbnQuc3R5bGUud2lkdGggPSB0aGlzLndpZHRoICsgXCJweFwiO1xuXHQgICAgICAgICAgdGhpcy5wYXJlbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyBcInB4XCI7XG5cdCAgICAgICAgfSBlbHNlIGlmIChzZXR0aW5ncy5zbmFwV2l0aFBhcmVudCAmJiAhc2V0dGluZ3MuY29tcG9uZW50KSB7XG5cdFxuXHQgICAgICAgICAgdGhpcy53aWR0aCA9IHBhcnNlRmxvYXQod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5wYXJlbnQsIG51bGwpLmdldFByb3BlcnR5VmFsdWUoXCJ3aWR0aFwiKS5yZXBsYWNlKFwicHhcIiwgXCJcIikpO1xuXHQgICAgICAgICAgdGhpcy5oZWlnaHQgPSBwYXJzZUZsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMucGFyZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKFwiaGVpZ2h0XCIpLnJlcGxhY2UoXCJweFwiLCBcIlwiKSk7XG5cdFxuXHQgICAgICAgICAgaWYgKHRoaXMud2lkdGggPT0gNTAwMCkge1xuXHQgICAgICAgICAgICB0aGlzLndpZHRoID0gc2V0dGluZ3MuZGVmYXVsdFNpemVbMF07XG5cdCAgICAgICAgICAgIHRoaXMucGFyZW50LnN0eWxlLndpZHRoID0gdGhpcy5wYXJlbnQud2lkdGggPSB0aGlzLndpZHRoICsgXCJweFwiO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgICAgaWYgKHRoaXMuaGVpZ2h0ID09IDUwMDApIHtcblx0ICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSBzZXR0aW5ncy5kZWZhdWx0U2l6ZVsxXTtcblx0ICAgICAgICAgICAgdGhpcy5wYXJlbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5wYXJlbnQuaGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyBcInB4XCI7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHNldHRpbmdzLnNpemUgPSBzZXR0aW5ncy5kZWZhdWx0U2l6ZTtcblx0ICAgICAgICAgIHRoaXMud2lkdGggPSBzZXR0aW5ncy5zaXplWzBdO1xuXHQgICAgICAgICAgdGhpcy5oZWlnaHQgPSBzZXR0aW5ncy5zaXplWzFdO1xuXHQgICAgICAgIH1cblx0XG5cdCAgICAgICAgLy8gZXZlbnRcblx0ICAgICAgICBpZiAoc2V0dGluZ3MuZXZlbnQpIHtcblx0ICAgICAgICAgIHRoaXMuZXZlbnQgPSB0aGlzLm9uKFwiY2hhbmdlXCIsIHNldHRpbmdzLmV2ZW50KTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdGhpcy5ldmVudCA9IGZhbHNlO1xuXHQgICAgICAgIH1cblx0XG5cdCAgICAgICAgcmV0dXJuIHNldHRpbmdzO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgaW5pdDoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gaW5pdCgpIHtcblx0ICAgICAgICB0aGlzLmJ1aWxkRnJhbWUoKTtcblx0ICAgICAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG5cdCAgICAgICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG5cdCAgICAgICAgdGhpcy5hdHRhY2hMaXN0ZW5lcnMoKTtcblx0ICAgICAgICB0aGlzLmNvbG9ySW50ZXJmYWNlKCk7XG5cdCAgICAgICAgdGhpcy5maW5hbFRvdWNoZXMoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGJ1aWxkRnJhbWU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkRnJhbWUoKSB7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50ID0gc3ZnLmNyZWF0ZShcInN2Z1wiKTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgdGhpcy53aWR0aCk7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCB0aGlzLmhlaWdodCk7XG5cdCAgICAgICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGJ1aWxkSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBidWlsZEludGVyZmFjZSgpIHt9XG5cdCAgICB9LFxuXHQgICAgc2l6ZUludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc2l6ZUludGVyZmFjZSgpIHt9XG5cdCAgICB9LFxuXHQgICAgY29sb3JJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbG9ySW50ZXJmYWNlKCkge31cblx0ICAgIH0sXG5cdCAgICBhdHRhY2hMaXN0ZW5lcnM6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGF0dGFjaExpc3RlbmVycygpIHtcblx0ICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0ID0gdGhpcy5pbnRlcmFjdGlvblRhcmdldCB8fCB0aGlzLmVsZW1lbnQ7XG5cdFxuXHQgICAgICAgIC8vIFNldHVwIGludGVyYWN0aW9uXG5cdCAgICAgICAgaWYgKHRvdWNoLmV4aXN0cykge1xuXHQgICAgICAgICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCBmdW5jdGlvbiAoZXZ0KSB7XG5cdCAgICAgICAgICAgIHJldHVybiBfdGhpcy5wcmVUb3VjaChldnQpO1xuXHQgICAgICAgICAgfSk7XG5cdCAgICAgICAgICB0aGlzLmludGVyYWN0aW9uVGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgZnVuY3Rpb24gKGV2dCkge1xuXHQgICAgICAgICAgICByZXR1cm4gX3RoaXMucHJlVG91Y2hNb3ZlKGV2dCk7XG5cdCAgICAgICAgICB9KTtcblx0ICAgICAgICAgIHRoaXMuaW50ZXJhY3Rpb25UYXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsIGZ1bmN0aW9uIChldnQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIF90aGlzLnByZVRvdWNoUmVsZWFzZShldnQpO1xuXHQgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuYm91bmRQcmVNb3ZlID0gZnVuY3Rpb24gKGV2dCkge1xuXHQgICAgICAgICAgcmV0dXJuIF90aGlzLnByZU1vdmUoZXZ0KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIHRoaXMuYm91bmRQcmVSZWxlYXNlID0gZnVuY3Rpb24gKGV2dCkge1xuXHQgICAgICAgICAgcmV0dXJuIF90aGlzLnByZVJlbGVhc2UoZXZ0KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIHRoaXMuaW50ZXJhY3Rpb25UYXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlZG93blwiLCBmdW5jdGlvbiAoZXZ0KSB7XG5cdCAgICAgICAgICByZXR1cm4gX3RoaXMucHJlQ2xpY2soZXZ0KTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGZpbmFsVG91Y2hlczoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gZmluYWxUb3VjaGVzKCkge1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5jdXJzb3IgPSBcInBvaW50ZXJcIjtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHByZUNsaWNrOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBwcmVDbGljayhlKSB7XG5cdCAgICAgICAgLy8gMTAwMDAgZ2V0Q29tcHV0ZWRTdHlsZSBjYWxscyB0YWtlcyAxMDAgbXMuXG5cdCAgICAgICAgLy8gLjouIG9uZSB0YWtlcyBhYm91dCAuMDFtc1xuXHQgICAgICAgIGlmICh0aGlzLmVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuXHQgICAgICAgICAgdGhpcy53aWR0aCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuZWxlbWVudCwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShcIndpZHRoXCIpLnJlcGxhY2UoXCJweFwiLCBcIlwiKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgLy8gMTAwMDAgZ2V0Q29tcHV0ZWRTdHlsZSBjYWxscyB0YWtlcyA0MCBtcy5cblx0ICAgICAgICAvLyAuOi4gb25lIHRha2VzIGFib3V0IC4wMDRtc1xuXHQgICAgICAgIHRoaXMub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbih0aGlzLmVsZW1lbnQpO1xuXHQgICAgICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSwgdGhpcy5vZmZzZXQpO1xuXHQgICAgICAgIHRoaXMuY2xpY2tlZCA9IHRydWU7XG5cdCAgICAgICAgdGhpcy5jbGljaygpO1xuXHQgICAgICAgIHRoaXMubW92ZUV2ZW50ID0gZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCB0aGlzLmJvdW5kUHJlTW92ZSk7XG5cdCAgICAgICAgdGhpcy5yZWxlYXNlRXZlbnQgPSBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCB0aGlzLmJvdW5kUHJlUmVsZWFzZSk7XG5cdCAgICAgICAgdGhpcy5lbWl0KFwiY2xpY2tcIik7XG5cdCAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBwcmVNb3ZlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBwcmVNb3ZlKGUpIHtcblx0ICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICAgICBpZiAoIXRoaXMud2FpdCkge1xuXHQgICAgICAgICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVNb3VzZShlLCB0aGlzLm9mZnNldCk7XG5cdCAgICAgICAgICB0aGlzLm1vdmUoKTtcblx0ICAgICAgICAgIHRoaXMud2FpdCA9IHRydWU7XG5cdCAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgX3RoaXMud2FpdCA9IGZhbHNlO1xuXHQgICAgICAgICAgfSwgMjUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cdCAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHByZVJlbGVhc2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHByZVJlbGVhc2UoZSkge1xuXHQgICAgICAgIHRoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSwgdGhpcy5vZmZzZXQpO1xuXHQgICAgICAgIHRoaXMuY2xpY2tlZCA9IGZhbHNlO1xuXHQgICAgICAgIHRoaXMucmVsZWFzZSgpO1xuXHQgICAgICAgIHRoaXMuZW1pdChcInJlbGVhc2VcIik7XG5cdCAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCB0aGlzLmJvdW5kUHJlTW92ZSk7XG5cdCAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgdGhpcy5ib3VuZFByZVJlbGVhc2UpO1xuXHQgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblx0ICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY2xpY2s6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNsaWNrKCkge31cblx0ICAgIH0sXG5cdCAgICBtb3ZlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBtb3ZlKCkge31cblx0ICAgIH0sXG5cdCAgICByZWxlYXNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZWxlYXNlKCkge31cblx0ICAgIH0sXG5cdCAgICBwcmVUb3VjaDoge1xuXHRcblx0ICAgICAgLyogdG91Y2ggKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBwcmVUb3VjaChlKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG5cdCAgICAgICAgICB0aGlzLndpZHRoID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbGVtZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKFwid2lkdGhcIikucmVwbGFjZShcInB4XCIsIFwiXCIpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLm9mZnNldCA9IGRvbS5maW5kUG9zaXRpb24odGhpcy5lbGVtZW50KTtcblx0ICAgICAgICB0aGlzLm1vdXNlID0gZG9tLmxvY2F0ZVRvdWNoKGUsIHRoaXMub2Zmc2V0KTtcblx0ICAgICAgICB0aGlzLmNsaWNrZWQgPSB0cnVlO1xuXHQgICAgICAgIHRoaXMudG91Y2goZSk7XG5cdCAgICAgICAgdGhpcy5lbWl0KFwiY2xpY2tcIik7XG5cdCAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBwcmVUb3VjaE1vdmU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHByZVRvdWNoTW92ZShlKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuXHQgICAgICAgICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVUb3VjaChlLCB0aGlzLm9mZnNldCk7XG5cdCAgICAgICAgICB0aGlzLnRvdWNoTW92ZSgpO1xuXHQgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBwcmVUb3VjaFJlbGVhc2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHByZVRvdWNoUmVsZWFzZShlKSB7XG5cdCAgICAgICAgdGhpcy5tb3VzZSA9IGRvbS5sb2NhdGVUb3VjaChlLCB0aGlzLm9mZnNldCk7XG5cdCAgICAgICAgdGhpcy5jbGlja2VkID0gZmFsc2U7XG5cdCAgICAgICAgdGhpcy50b3VjaFJlbGVhc2UoKTtcblx0ICAgICAgICB0aGlzLmVtaXQoXCJyZWxlYXNlXCIpO1xuXHQgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblx0ICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdG91Y2g6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvdWNoKCkge1xuXHQgICAgICAgIHRoaXMuY2xpY2soKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHRvdWNoTW92ZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gdG91Y2hNb3ZlKCkge1xuXHQgICAgICAgIHRoaXMubW92ZSgpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdG91Y2hSZWxlYXNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiB0b3VjaFJlbGVhc2UoKSB7XG5cdCAgICAgICAgdGhpcy5yZWxlYXNlKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByZXNpemU6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICAqIFJlc2l6ZSB0aGUgaW50ZXJmYWNlXG5cdCAgICAgICogQHBhcmFtIHdpZHRoIHtudW1iZXJ9IE5ldyB3aWR0aCBpbiBwaXhlbHNcblx0ICAgICAgKiBAcGFyYW0gaGVpZ2h0IHtudW1iZXJ9IE5ldyBoZWlnaHQgaW4gcGl4ZWxzXG5cdCAgICAgICpcblx0ICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAqIGJ1dHRvbi5yZXNpemUoMTAwLDEwMCk7XG5cdCAgICAgICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVzaXplKHdpZHRoLCBoZWlnaHQpIHtcblx0ICAgICAgICB0aGlzLndpZHRoID0gd2lkdGg7XG5cdCAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG5cdCAgICAgICAgdGhpcy5wYXJlbnQuc3R5bGUud2lkdGggPSB0aGlzLndpZHRoICsgXCJweFwiO1xuXHQgICAgICAgIHRoaXMucGFyZW50LnN0eWxlLmhlaWdodCA9IHRoaXMuaGVpZ2h0ICsgXCJweFwiO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiLCB0aGlzLndpZHRoKTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIHRoaXMuaGVpZ2h0KTtcblx0ICAgICAgICB0aGlzLnNpemVJbnRlcmZhY2UoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGVtcHR5OiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBlbXB0eSgpIHtcblx0ICAgICAgICB3aGlsZSAodGhpcy5lbGVtZW50Lmxhc3RDaGlsZCkge1xuXHQgICAgICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudC5sYXN0Q2hpbGQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGRlc3Ryb3k6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICAqIFJlbW92ZSB0aGUgaW50ZXJmYWNlIGZyb20gdGhlIHBhZ2UgYW5kIGNhbmNlbCBpdHMgZXZlbnQgbGlzdGVuZXIocykuXG5cdCAgICAgICpcblx0ICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAqIGJ1dHRvbi5kZXN0cm95KCk7XG5cdCAgICAgICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gZGVzdHJveSgpIHtcblx0ICAgICAgICB0aGlzLmVtcHR5KCk7XG5cdCAgICAgICAgdGhpcy5wYXJlbnQucmVtb3ZlQ2hpbGQodGhpcy5lbGVtZW50KTtcblx0ICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygpO1xuXHQgICAgICAgIGlmICh0aGlzLmluc3RydW1lbnQpIHtcblx0ICAgICAgICAgIGRlbGV0ZSB0aGlzLmluc3RydW1lbnRbdGhpcy5pZF07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuY3VzdG9tRGVzdHJveSgpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY3VzdG9tRGVzdHJveToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY3VzdG9tRGVzdHJveSgpIHt9XG5cdCAgICB9LFxuXHQgICAgY29sb3JpemU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbG9yaXplKHR5cGUsIGNvbG9yKSB7XG5cdCAgICAgICAgdGhpcy5jb2xvcnNbdHlwZV0gPSBjb2xvcjtcblx0ICAgICAgICB0aGlzLmNvbG9ySW50ZXJmYWNlKCk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIEludGVyZmFjZTtcblx0fSkoRXZlbnRFbWl0dGVyKTtcblx0XG5cdG1vZHVsZS5leHBvcnRzID0gSW50ZXJmYWNlO1xuXG4vKioqLyB9KSxcbi8qIDcgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdGV4cG9ydHMuZmluZFBvc2l0aW9uID0gZnVuY3Rpb24gKGVsKSB7XG5cdCAgdmFyIHZpZXdwb3J0T2Zmc2V0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdCAgdmFyIHRvcCA9IHZpZXdwb3J0T2Zmc2V0LnRvcCArIHdpbmRvdy5zY3JvbGxZO1xuXHQgIHZhciBsZWZ0ID0gdmlld3BvcnRPZmZzZXQubGVmdCArIHdpbmRvdy5zY3JvbGxYO1xuXHQgIHJldHVybiB7IHRvcDogdG9wLCBsZWZ0OiBsZWZ0IH07XG5cdH07XG5cdFxuXHRleHBvcnRzLnBhcnNlRWxlbWVudCA9IGZ1bmN0aW9uIChwYXJlbnQpIHtcblx0ICBpZiAodHlwZW9mIHBhcmVudCA9PT0gXCJzdHJpbmdcIikge1xuXHQgICAgcGFyZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50LnJlcGxhY2UoXCIjXCIsIFwiXCIpKTtcblx0ICB9XG5cdFxuXHQgIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCB8fCBwYXJlbnQgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSB7XG5cdCAgICByZXR1cm4gcGFyZW50O1xuXHQgIH0gZWxzZSB7XG5cdCAgICByZXR1cm4gXCJObyB2YWxpZCBwYXJlbnQgYXJndW1lbnRcIjtcblx0ICB9XG5cdH07XG5cdFxuXHRleHBvcnRzLmxvY2F0ZU1vdXNlID0gZnVuY3Rpb24gKGUsIG9mZnNldCkge1xuXHQgIHJldHVybiB7XG5cdCAgICB4OiBlLnBhZ2VYIC0gb2Zmc2V0LmxlZnQsXG5cdCAgICB5OiBlLnBhZ2VZIC0gb2Zmc2V0LnRvcFxuXHQgIH07XG5cdH07XG5cdFxuXHRleHBvcnRzLmxvY2F0ZVRvdWNoID0gZnVuY3Rpb24gKGUsIG9mZnNldCkge1xuXHQgIHJldHVybiB7XG5cdCAgICB4OiBlLnRhcmdldFRvdWNoZXMubGVuZ3RoID8gZS50YXJnZXRUb3VjaGVzWzBdLnBhZ2VYIC0gb2Zmc2V0LmxlZnQgOiBmYWxzZSxcblx0ICAgIHk6IGUudGFyZ2V0VG91Y2hlcy5sZW5ndGggPyBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVkgLSBvZmZzZXQudG9wIDogZmFsc2Vcblx0ICB9O1xuXHR9O1xuXHRcblx0ZXhwb3J0cy5TbWFydENhbnZhcyA9IGZ1bmN0aW9uIChwYXJlbnQpIHtcblx0ICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuXHQgIHRoaXMuY29udGV4dCA9IHRoaXMuZWxlbWVudC5nZXRDb250ZXh0KFwiMmRcIik7XG5cdCAgcGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG5cdFxuXHQgIHRoaXMucmVzaXplID0gZnVuY3Rpb24gKHcsIGgpIHtcblx0ICAgIF90aGlzLmVsZW1lbnQud2lkdGggPSB3ICogMjtcblx0ICAgIF90aGlzLmVsZW1lbnQuaGVpZ2h0ID0gaCAqIDI7XG5cdCAgICBfdGhpcy5lbGVtZW50LnN0eWxlLndpZHRoID0gdyArIFwicHhcIjtcblx0ICAgIF90aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gaCArIFwicHhcIjtcblx0ICB9O1xuXHR9O1xuXG4vKioqLyB9KSxcbi8qIDggKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdGV4cG9ydHMuaXNPYmplY3QgPSBmdW5jdGlvbiAob2JqKSB7XG5cdCAgaWYgKHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkob2JqKSAmJiBvYmogIT09IG51bGwgJiYgb2JqIGluc3RhbmNlb2YgU1ZHRWxlbWVudCA9PT0gZmFsc2UgJiYgb2JqIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgPT09IGZhbHNlKSB7XG5cdCAgICByZXR1cm4gdHJ1ZTtcblx0ICB9IGVsc2Uge1xuXHQgICAgcmV0dXJuIGZhbHNlO1xuXHQgIH1cblx0fTtcblxuLyoqKi8gfSksXG4vKiA5ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHRleHBvcnRzLmV4aXN0cyA9IFwib250b3VjaHN0YXJ0XCIgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXG4vKioqLyB9KSxcbi8qIDEwICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0Ly8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG5cdC8vXG5cdC8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG5cdC8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcblx0Ly8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG5cdC8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcblx0Ly8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuXHQvLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcblx0Ly8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cdC8vXG5cdC8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG5cdC8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuXHQvL1xuXHQvLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG5cdC8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcblx0Ly8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuXHQvLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcblx0Ly8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG5cdC8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcblx0Ly8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblx0XG5cdGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcblx0ICB0aGlzLl9ldmVudHMgPSB0aGlzLl9ldmVudHMgfHwge307XG5cdCAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcblx0fVxuXHRtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblx0XG5cdC8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuXHRFdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXHRcblx0RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuXHRFdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cdFxuXHQvLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcblx0Ly8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cblx0RXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblx0XG5cdC8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuXHQvLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cblx0RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbihuKSB7XG5cdCAgaWYgKCFpc051bWJlcihuKSB8fCBuIDwgMCB8fCBpc05hTihuKSlcblx0ICAgIHRocm93IFR5cGVFcnJvcignbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG5cdCAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcblx0ICByZXR1cm4gdGhpcztcblx0fTtcblx0XG5cdEV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKHR5cGUpIHtcblx0ICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgbGlzdGVuZXJzO1xuXHRcblx0ICBpZiAoIXRoaXMuX2V2ZW50cylcblx0ICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXHRcblx0ICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG5cdCAgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcblx0ICAgIGlmICghdGhpcy5fZXZlbnRzLmVycm9yIHx8XG5cdCAgICAgICAgKGlzT2JqZWN0KHRoaXMuX2V2ZW50cy5lcnJvcikgJiYgIXRoaXMuX2V2ZW50cy5lcnJvci5sZW5ndGgpKSB7XG5cdCAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuXHQgICAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuXHQgICAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcblx0ICAgICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdVbmNhdWdodCwgdW5zcGVjaWZpZWQgXCJlcnJvclwiIGV2ZW50LiAoJyArIGVyICsgJyknKTtcblx0ICAgICAgICBlcnIuY29udGV4dCA9IGVyO1xuXHQgICAgICAgIHRocm93IGVycjtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH1cblx0XG5cdCAgaGFuZGxlciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblx0XG5cdCAgaWYgKGlzVW5kZWZpbmVkKGhhbmRsZXIpKVxuXHQgICAgcmV0dXJuIGZhbHNlO1xuXHRcblx0ICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuXHQgICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG5cdCAgICAgIC8vIGZhc3QgY2FzZXNcblx0ICAgICAgY2FzZSAxOlxuXHQgICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzKTtcblx0ICAgICAgICBicmVhaztcblx0ICAgICAgY2FzZSAyOlxuXHQgICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0pO1xuXHQgICAgICAgIGJyZWFrO1xuXHQgICAgICBjYXNlIDM6XG5cdCAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcblx0ICAgICAgICBicmVhaztcblx0ICAgICAgLy8gc2xvd2VyXG5cdCAgICAgIGRlZmF1bHQ6XG5cdCAgICAgICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cdCAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLCBhcmdzKTtcblx0ICAgIH1cblx0ICB9IGVsc2UgaWYgKGlzT2JqZWN0KGhhbmRsZXIpKSB7XG5cdCAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblx0ICAgIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcblx0ICAgIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7XG5cdCAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG5cdCAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcblx0ICB9XG5cdFxuXHQgIHJldHVybiB0cnVlO1xuXHR9O1xuXHRcblx0RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG5cdCAgdmFyIG07XG5cdFxuXHQgIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG5cdCAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXHRcblx0ICBpZiAoIXRoaXMuX2V2ZW50cylcblx0ICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXHRcblx0ICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuXHQgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cblx0ICBpZiAodGhpcy5fZXZlbnRzLm5ld0xpc3RlbmVyKVxuXHQgICAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG5cdCAgICAgICAgICAgICAgaXNGdW5jdGlvbihsaXN0ZW5lci5saXN0ZW5lcikgP1xuXHQgICAgICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXHRcblx0ICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSlcblx0ICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuXHQgICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG5cdCAgZWxzZSBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSlcblx0ICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cblx0ICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcblx0ICBlbHNlXG5cdCAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cblx0ICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFt0aGlzLl9ldmVudHNbdHlwZV0sIGxpc3RlbmVyXTtcblx0XG5cdCAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcblx0ICBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSAmJiAhdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCkge1xuXHQgICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLl9tYXhMaXN0ZW5lcnMpKSB7XG5cdCAgICAgIG0gPSB0aGlzLl9tYXhMaXN0ZW5lcnM7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICBtID0gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG5cdCAgICB9XG5cdFxuXHQgICAgaWYgKG0gJiYgbSA+IDAgJiYgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCA+IG0pIHtcblx0ICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCA9IHRydWU7XG5cdCAgICAgIGNvbnNvbGUuZXJyb3IoJyhub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5ICcgK1xuXHQgICAgICAgICAgICAgICAgICAgICdsZWFrIGRldGVjdGVkLiAlZCBsaXN0ZW5lcnMgYWRkZWQuICcgK1xuXHQgICAgICAgICAgICAgICAgICAgICdVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byBpbmNyZWFzZSBsaW1pdC4nLFxuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO1xuXHQgICAgICBpZiAodHlwZW9mIGNvbnNvbGUudHJhY2UgPT09ICdmdW5jdGlvbicpIHtcblx0ICAgICAgICAvLyBub3Qgc3VwcG9ydGVkIGluIElFIDEwXG5cdCAgICAgICAgY29uc29sZS50cmFjZSgpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfVxuXHRcblx0ICByZXR1cm4gdGhpcztcblx0fTtcblx0XG5cdEV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXHRcblx0RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcblx0ICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuXHQgICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblx0XG5cdCAgdmFyIGZpcmVkID0gZmFsc2U7XG5cdFxuXHQgIGZ1bmN0aW9uIGcoKSB7XG5cdCAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGcpO1xuXHRcblx0ICAgIGlmICghZmlyZWQpIHtcblx0ICAgICAgZmlyZWQgPSB0cnVlO1xuXHQgICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXHQgICAgfVxuXHQgIH1cblx0XG5cdCAgZy5saXN0ZW5lciA9IGxpc3RlbmVyO1xuXHQgIHRoaXMub24odHlwZSwgZyk7XG5cdFxuXHQgIHJldHVybiB0aGlzO1xuXHR9O1xuXHRcblx0Ly8gZW1pdHMgYSAncmVtb3ZlTGlzdGVuZXInIGV2ZW50IGlmZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWRcblx0RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG5cdCAgdmFyIGxpc3QsIHBvc2l0aW9uLCBsZW5ndGgsIGk7XG5cdFxuXHQgIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG5cdCAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXHRcblx0ICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuXHQgICAgcmV0dXJuIHRoaXM7XG5cdFxuXHQgIGxpc3QgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cdCAgbGVuZ3RoID0gbGlzdC5sZW5ndGg7XG5cdCAgcG9zaXRpb24gPSAtMTtcblx0XG5cdCAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8XG5cdCAgICAgIChpc0Z1bmN0aW9uKGxpc3QubGlzdGVuZXIpICYmIGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuXHQgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcblx0ICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG5cdCAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG5cdFxuXHQgIH0gZWxzZSBpZiAoaXNPYmplY3QobGlzdCkpIHtcblx0ICAgIGZvciAoaSA9IGxlbmd0aDsgaS0tID4gMDspIHtcblx0ICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8XG5cdCAgICAgICAgICAobGlzdFtpXS5saXN0ZW5lciAmJiBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcblx0ICAgICAgICBwb3NpdGlvbiA9IGk7XG5cdCAgICAgICAgYnJlYWs7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0XG5cdCAgICBpZiAocG9zaXRpb24gPCAwKVxuXHQgICAgICByZXR1cm4gdGhpcztcblx0XG5cdCAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcblx0ICAgICAgbGlzdC5sZW5ndGggPSAwO1xuXHQgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgbGlzdC5zcGxpY2UocG9zaXRpb24sIDEpO1xuXHQgICAgfVxuXHRcblx0ICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG5cdCAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG5cdCAgfVxuXHRcblx0ICByZXR1cm4gdGhpcztcblx0fTtcblx0XG5cdEV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuXHQgIHZhciBrZXksIGxpc3RlbmVycztcblx0XG5cdCAgaWYgKCF0aGlzLl9ldmVudHMpXG5cdCAgICByZXR1cm4gdGhpcztcblx0XG5cdCAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuXHQgIGlmICghdGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKSB7XG5cdCAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcblx0ICAgICAgdGhpcy5fZXZlbnRzID0ge307XG5cdCAgICBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0pXG5cdCAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG5cdCAgICByZXR1cm4gdGhpcztcblx0ICB9XG5cdFxuXHQgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuXHQgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG5cdCAgICBmb3IgKGtleSBpbiB0aGlzLl9ldmVudHMpIHtcblx0ICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG5cdCAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG5cdCAgICB9XG5cdCAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcblx0ICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXHQgICAgcmV0dXJuIHRoaXM7XG5cdCAgfVxuXHRcblx0ICBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cdFxuXHQgIGlmIChpc0Z1bmN0aW9uKGxpc3RlbmVycykpIHtcblx0ICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzKTtcblx0ICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuXHQgICAgLy8gTElGTyBvcmRlclxuXHQgICAgd2hpbGUgKGxpc3RlbmVycy5sZW5ndGgpXG5cdCAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXSk7XG5cdCAgfVxuXHQgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG5cdFxuXHQgIHJldHVybiB0aGlzO1xuXHR9O1xuXHRcblx0RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG5cdCAgdmFyIHJldDtcblx0ICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuXHQgICAgcmV0ID0gW107XG5cdCAgZWxzZSBpZiAoaXNGdW5jdGlvbih0aGlzLl9ldmVudHNbdHlwZV0pKVxuXHQgICAgcmV0ID0gW3RoaXMuX2V2ZW50c1t0eXBlXV07XG5cdCAgZWxzZVxuXHQgICAgcmV0ID0gdGhpcy5fZXZlbnRzW3R5cGVdLnNsaWNlKCk7XG5cdCAgcmV0dXJuIHJldDtcblx0fTtcblx0XG5cdEV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKHR5cGUpIHtcblx0ICBpZiAodGhpcy5fZXZlbnRzKSB7XG5cdCAgICB2YXIgZXZsaXN0ZW5lciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblx0XG5cdCAgICBpZiAoaXNGdW5jdGlvbihldmxpc3RlbmVyKSlcblx0ICAgICAgcmV0dXJuIDE7XG5cdCAgICBlbHNlIGlmIChldmxpc3RlbmVyKVxuXHQgICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG5cdCAgfVxuXHQgIHJldHVybiAwO1xuXHR9O1xuXHRcblx0RXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG5cdCAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJDb3VudCh0eXBlKTtcblx0fTtcblx0XG5cdGZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG5cdCAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG5cdH1cblx0XG5cdGZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuXHQgIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcblx0fVxuXHRcblx0ZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG5cdCAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcblx0fVxuXHRcblx0ZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG5cdCAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xuXHR9XG5cblxuLyoqKi8gfSksXG4vKiAxMSAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIG1hdGggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpO1xuXHRcblx0LyoqXG5cdCAgQ3JlYXRlcyBhIHN0ZXBwYWJsZSB2YWx1ZSB3aXRoIG1pbmltdW0sIG1heGltdW0sIGFuZCBzdGVwIHNpemUuIFRoaXMgaXMgdXNlZCBpbiBtYW55IGludGVyZmFjZXMgdG8gY29uc3RyaWN0IHRoZWlyIHZhbHVlcyB0byBjZXJ0YWluIHJhbmdlcy5cblx0ICBAcGFyYW0ge251bWJlcn0gW21pbj0wXSBtaW5pbXVtXG5cdCAgQHBhcmFtIHtudW1iZXJ9IFttYXg9MV0gbWF4aW11bVxuXHQgIEBwYXJhbSB7bnVtYmVyfSBbc3RlcD0wXVxuXHQgIEBwYXJhbSB7bnVtYmVyfSBbdmFsdWU9MF0gaW5pdGlhbCB2YWx1ZVxuXHQgIEByZXR1cm5zIHtPYmplY3R9IFN0ZXBcblx0Ki9cblx0XG5cdHZhciBTdGVwID0gKGZ1bmN0aW9uICgpIHtcblx0ICBmdW5jdGlvbiBTdGVwKCkge1xuXHQgICAgdmFyIG1pbiA9IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gMCA6IGFyZ3VtZW50c1swXTtcblx0ICAgIHZhciBtYXggPSBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCA/IDEgOiBhcmd1bWVudHNbMV07XG5cdCAgICB2YXIgc3RlcCA9IGFyZ3VtZW50c1syXSA9PT0gdW5kZWZpbmVkID8gMCA6IGFyZ3VtZW50c1syXTtcblx0ICAgIHZhciB2YWx1ZSA9IGFyZ3VtZW50c1szXSA9PT0gdW5kZWZpbmVkID8gMCA6IGFyZ3VtZW50c1szXTtcblx0XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgU3RlcCk7XG5cdFxuXHQgICAgLy9PYmplY3QuYXNzaWduKHRoaXMse21pbixtYXgsc3RlcH0pO1xuXHQgICAgLy9DYW5ub3QgdXNlIE9iamVjdC5hc3NpZ24gYmVjYXVzZSBub3Qgc3VwcG9ydGVkIGluIFNhZmFyaS5cblx0ICAgIC8vSSB3b3VsZCBleHBlY3QgZm9yIEJhYmVsIHRvIHRha2UgY2FyZSBvZiB0aGlzIGJ1dCBpdCBpcyBub3QuXG5cdCAgICB0aGlzLm1pbiA9IG1pbjtcblx0ICAgIHRoaXMubWF4ID0gbWF4O1xuXHQgICAgdGhpcy5zdGVwID0gc3RlcDtcblx0ICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcblx0ICAgIHRoaXMuY2hhbmdlZCA9IGZhbHNlO1xuXHQgICAgdGhpcy5vbGRWYWx1ZSA9IGZhbHNlO1xuXHQgICAgdGhpcy51cGRhdGUodGhpcy52YWx1ZSk7XG5cdCAgfVxuXHRcblx0ICBfY3JlYXRlQ2xhc3MoU3RlcCwge1xuXHQgICAgdXBkYXRlOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgICBVcGRhdGUgd2l0aCBhIG5ldyB2YWx1ZS4gVGhlIHZhbHVlIHdpbGwgYmUgYXV0by1hZGp1c3RlZCB0byBmaXQgdGhlIG1pbi9tYXgvc3RlcC5cblx0ICAgICAgICBAcGFyYW0ge251bWJlcn0gdmFsdWVcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiB1cGRhdGUodmFsdWUpIHtcblx0ICAgICAgICBpZiAodGhpcy5zdGVwKSB7XG5cdCAgICAgICAgICAvLyB0aGlzLnZhbHVlID0gbWF0aC5jbGlwKE1hdGgucm91bmQodmFsdWUgLyAodGhpcy5zdGVwKSkgKiB0aGlzLnN0ZXAsIHRoaXMubWluLHRoaXMubWF4KTtcblx0ICAgICAgICAgIHRoaXMudmFsdWUgPSBtYXRoLmNsaXAoTWF0aC5yb3VuZCgodmFsdWUgLSB0aGlzLm1pbikgLyB0aGlzLnN0ZXApICogdGhpcy5zdGVwICsgdGhpcy5taW4sIHRoaXMubWluLCB0aGlzLm1heCk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMudmFsdWUgPSBtYXRoLmNsaXAodmFsdWUsIHRoaXMubWluLCB0aGlzLm1heCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICh0aGlzLm9sZFZhbHVlICE9PSB0aGlzLnZhbHVlKSB7XG5cdCAgICAgICAgICB0aGlzLm9sZFZhbHVlID0gdGhpcy52YWx1ZTtcblx0ICAgICAgICAgIHRoaXMuY2hhbmdlZCA9IHRydWU7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMuY2hhbmdlZCA9IGZhbHNlO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHVwZGF0ZU5vcm1hbDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgICAgVXBkYXRlIHdpdGggYSBub3JtYWxpemVkIHZhbHVlIDAtMS5cblx0ICAgICAgICBAcGFyYW0ge251bWJlcn0gdmFsdWVcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiB1cGRhdGVOb3JtYWwodmFsdWUpIHtcblx0ICAgICAgICB0aGlzLnZhbHVlID0gbWF0aC5zY2FsZSh2YWx1ZSwgMCwgMSwgdGhpcy5taW4sIHRoaXMubWF4KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy51cGRhdGUodGhpcy52YWx1ZSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBub3JtYWxpemVkOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgICBHZXQgYSBub3JtYWxpemVkIHZlcnNpb24gb2YgdGhpcy52YWx1ZSAuIE5vdCBzZXR0YWJsZS5cblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiBtYXRoLm5vcm1hbGl6ZSh0aGlzLnZhbHVlLCB0aGlzLm1pbiwgdGhpcy5tYXgpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSk7XG5cdFxuXHQgIHJldHVybiBTdGVwO1xuXHR9KSgpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBTdGVwO1xuXG4vKioqLyB9KSxcbi8qIDEyICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgX2ludGVyb3BSZXF1aXJlID0gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqW1wiZGVmYXVsdFwiXSA6IG9iajsgfTtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBtYXRoID0gX2ludGVyb3BSZXF1aXJlKF9fd2VicGFja19yZXF1aXJlX18oNSkpO1xuXHRcblx0dmFyIFRvZ2dsZU1vZGVsID0gX2ludGVyb3BSZXF1aXJlKF9fd2VicGFja19yZXF1aXJlX18oMTMpKTtcblx0XG5cdC8qXG5cdGhvdyB0byB1c2UgOlxuXHRcblx0ZGlhbC5pbnRlcmFjdGlvbiA9IG5ldyBIYW5kbGUoJ3JhZGlhbCcsJ3JlbGF0aXZlJyx0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtcblx0Ly8gZGlhbC5pbnRlcmFjdGlvbi5tb2RlID0gJ3JlbGF0aXZlJ1xuXHQvLyBkaWFsLmludGVyYWN0aW9uLmRpcmVjdGlvbiA9ICdyYWRpYWwnXG5cdFxuXHRvbiBjbGljazpcblx0ZGlhbC5pbnRlcmFjdGlvbi5hbmNob3IgPSB0aGlzLm1vdXNlO1xuXHRcblx0b24gbW92ZTpcblx0ZGlhbC5pbnRlcmFjdGlvbi51cGRhdGUodGhpcy5tb3VzZSk7XG5cdFxuXHRjb25zb2xlLmxvZyggZGlhbC5pbnRlcmFjdGlvbi52YWx1ZSApOyBzaG91bGQgYmUgYSBub3JtYWxpemVkIHZhbHVlLlxuXHRcblx0Ki9cblx0XG5cdC8qXG5cdCAgYWJzb2x1dGUvcmVsYXRpdmUgYXJlIHByb3BlcnR5OiBtb2RlXG5cdCAgcmFkaWFsL3ZlcnRpY2FsL2hvcml6b250YWwvMmQgYXJlIHByb3BlcnR5OiBkaXJlY3Rpb25cblx0XG5cdCAgcGxhbiA6XG5cdFxuXHQgIGlmIHJlbGF0aXZlIC0tXG5cdCAgTk8gb24gY2xpY2ssIGdldCB2YWx1ZSBvZmZzZXQgYmV0d2VlbiBjdXJyZW50IHZhbHVlIGFuZCBjbGljayB2YWx1ZS5cblx0ICBOTyBvbiBtb3ZlLCB1c2UgY2xpY2sgdmFsdWUgLSBvZmZzZXRcblx0ICBJTlNURUFEXG5cdCAgdXNlIGRlbHRhIC0tIGJjIHZlcnRpY2FsIG1vdGlvbiBvbiBkaWFsIGlzIGltcG9zc2libGUgb3RoZXJ3aXNlXG5cdCAgYWxzbyBhbGxvdyB0byBzZXQgc2Vuc2l0aXZpdHlcblx0XG5cdCovXG5cdFxuXHR2YXIgSGFuZGxlID0gZXhwb3J0cy5IYW5kbGUgPSAoZnVuY3Rpb24gKCkge1xuXHQgIGZ1bmN0aW9uIEhhbmRsZSgpIHtcblx0ICAgIHZhciBtb2RlID0gYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyBcImFic29sdXRlXCIgOiBhcmd1bWVudHNbMF07XG5cdCAgICB2YXIgZGlyZWN0aW9uID0gYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyBcInZlcnRpY2FsXCIgOiBhcmd1bWVudHNbMV07XG5cdCAgICB2YXIgeGJvdW5kID0gYXJndW1lbnRzWzJdID09PSB1bmRlZmluZWQgPyBbMCwgMTAwXSA6IGFyZ3VtZW50c1syXTtcblx0ICAgIHZhciB5Ym91bmQgPSBhcmd1bWVudHNbM10gPT09IHVuZGVmaW5lZCA/IFswLCAxMDBdIDogYXJndW1lbnRzWzNdO1xuXHRcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBIYW5kbGUpO1xuXHRcblx0ICAgIHRoaXMubW9kZSA9IG1vZGU7XG5cdCAgICB0aGlzLmRpcmVjdGlvbiA9IGRpcmVjdGlvbjtcblx0ICAgIHRoaXMucHJldmlvdXMgPSAwO1xuXHQgICAgdGhpcy52YWx1ZSA9IDA7XG5cdCAgICB0aGlzLnNlbnNpdGl2aXR5ID0gMTtcblx0ICAgIHRoaXMucmVzaXplKHhib3VuZCwgeWJvdW5kKTtcblx0ICB9XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhIYW5kbGUsIHtcblx0ICAgIHJlc2l6ZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVzaXplKHhib3VuZCwgeWJvdW5kKSB7XG5cdCAgICAgICAgdGhpcy5ib3VuZGFyeSA9IHtcblx0ICAgICAgICAgIG1pbjoge1xuXHQgICAgICAgICAgICB4OiB4Ym91bmRbMF0sXG5cdCAgICAgICAgICAgIHk6IHlib3VuZFswXVxuXHQgICAgICAgICAgfSxcblx0ICAgICAgICAgIG1heDoge1xuXHQgICAgICAgICAgICB4OiB4Ym91bmRbMV0sXG5cdCAgICAgICAgICAgIHk6IHlib3VuZFsxXVxuXHQgICAgICAgICAgfSxcblx0ICAgICAgICAgIGNlbnRlcjoge1xuXHQgICAgICAgICAgICB4OiAoeGJvdW5kWzFdIC0geGJvdW5kWzBdKSAvIDIgKyB4Ym91bmRbMF0sXG5cdCAgICAgICAgICAgIHk6ICh5Ym91bmRbMV0gLSB5Ym91bmRbMF0pIC8gMiArIHlib3VuZFswXVxuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH07XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBhbmNob3I6IHtcblx0ICAgICAgc2V0OiBmdW5jdGlvbiAobW91c2UpIHtcblx0ICAgICAgICB0aGlzLl9hbmNob3IgPSB0aGlzLmNvbnZlcnRQb3NpdGlvblRvVmFsdWUobW91c2UpO1xuXHQgICAgICB9LFxuXHQgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fYW5jaG9yO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdXBkYXRlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiB1cGRhdGUobW91c2UpIHtcblx0ICAgICAgICBpZiAodGhpcy5tb2RlID09PSBcInJlbGF0aXZlXCIpIHtcblx0ICAgICAgICAgIHZhciBpbmNyZW1lbnQgPSB0aGlzLmNvbnZlcnRQb3NpdGlvblRvVmFsdWUobW91c2UpIC0gdGhpcy5hbmNob3I7XG5cdCAgICAgICAgICBpZiAoTWF0aC5hYnMoaW5jcmVtZW50KSA+IDAuNSkge1xuXHQgICAgICAgICAgICBpbmNyZW1lbnQgPSAwO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgICAgdGhpcy5hbmNob3IgPSBtb3VzZTtcblx0ICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLnZhbHVlICsgaW5jcmVtZW50ICogdGhpcy5zZW5zaXRpdml0eTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuY29udmVydFBvc2l0aW9uVG9WYWx1ZShtb3VzZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMudmFsdWUgPSBtYXRoLmNsaXAodGhpcy52YWx1ZSwgMCwgMSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjb252ZXJ0UG9zaXRpb25Ub1ZhbHVlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb252ZXJ0UG9zaXRpb25Ub1ZhbHVlKGN1cnJlbnQpIHtcblx0ICAgICAgICBzd2l0Y2ggKHRoaXMuZGlyZWN0aW9uKSB7XG5cdCAgICAgICAgICBjYXNlIFwicmFkaWFsXCI6XG5cdCAgICAgICAgICAgIHZhciBwb3NpdGlvbiA9IG1hdGgudG9Qb2xhcihjdXJyZW50LnggLSB0aGlzLmJvdW5kYXJ5LmNlbnRlci54LCBjdXJyZW50LnkgLSB0aGlzLmJvdW5kYXJ5LmNlbnRlci55KTtcblx0ICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbi5hbmdsZSAvIChNYXRoLlBJICogMik7XG5cdCAgICAgICAgICAgIHBvc2l0aW9uID0gKHBvc2l0aW9uIC0gMC4yNSArIDEpICUgMTtcblx0ICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uO1xuXHQgICAgICAgICAgY2FzZSBcInZlcnRpY2FsXCI6XG5cdCAgICAgICAgICAgIHJldHVybiBtYXRoLnNjYWxlKGN1cnJlbnQueSwgdGhpcy5ib3VuZGFyeS5taW4ueSwgdGhpcy5ib3VuZGFyeS5tYXgueSwgMCwgMSk7XG5cdCAgICAgICAgICBjYXNlIFwiaG9yaXpvbnRhbFwiOlxuXHQgICAgICAgICAgICByZXR1cm4gbWF0aC5zY2FsZShjdXJyZW50LngsIHRoaXMuYm91bmRhcnkubWluLngsIHRoaXMuYm91bmRhcnkubWF4LngsIDAsIDEpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pO1xuXHRcblx0ICByZXR1cm4gSGFuZGxlO1xuXHR9KSgpO1xuXHRcblx0dmFyIEJ1dHRvbiA9IGV4cG9ydHMuQnV0dG9uID0gKGZ1bmN0aW9uICgpIHtcblx0ICBmdW5jdGlvbiBCdXR0b24oKSB7XG5cdCAgICB2YXIgbW9kZSA9IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gXCJidXR0b25cIiA6IGFyZ3VtZW50c1swXTtcblx0XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQnV0dG9uKTtcblx0XG5cdCAgICB0aGlzLm1vZGUgPSBtb2RlO1xuXHQgICAgdGhpcy5zdGF0ZSA9IG5ldyBUb2dnbGVNb2RlbCgpO1xuXHQgICAgdGhpcy5wYWludGJydXNoID0gZmFsc2U7XG5cdCAgfVxuXHRcblx0ICBfY3JlYXRlQ2xhc3MoQnV0dG9uLCB7XG5cdCAgICBjbGljazoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY2xpY2soKSB7XG5cdCAgICAgICAgc3dpdGNoICh0aGlzLm1vZGUpIHtcblx0ICAgICAgICAgIGNhc2UgXCJpbXB1bHNlXCI6XG5cdCAgICAgICAgICAgIHRoaXMuc3RhdGUub24oKTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMudGltZW91dCkge1xuXHQgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMudGltZW91dCA9IHNldFRpbWVvdXQodGhpcy5zdGF0ZS5vZmYuYmluZCh0aGlzKSwgMzApO1xuXHQgICAgICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy5zdGF0ZSk7XG5cdCAgICAgICAgICAgIGJyZWFrO1xuXHQgICAgICAgICAgY2FzZSBcImJ1dHRvblwiOlxuXHQgICAgICAgICAgICB0aGlzLnR1cm5PbigpO1xuXHQgICAgICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy5zdGF0ZSk7XG5cdCAgICAgICAgICAgIGJyZWFrO1xuXHQgICAgICAgICAgY2FzZSBcImFmdGVydG91Y2hcIjpcblx0ICAgICAgICAgICAgdGhpcy5wb3NpdGlvbiA9IHtcblx0ICAgICAgICAgICAgICB4OiBtYXRoLmNsaXAodGhpcy5tb3VzZS54IC8gdGhpcy53aWR0aCwgMCwgMSksXG5cdCAgICAgICAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwgMCwgMSlcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgdGhpcy50dXJuT24oKTtcblx0ICAgICAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHtcblx0ICAgICAgICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcblx0ICAgICAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG5cdCAgICAgICAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55IH0pO1xuXHQgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgIGNhc2UgXCJ0b2dnbGVcIjpcblx0ICAgICAgICAgICAgdGhpcy5mbGlwKCk7XG5cdCAgICAgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB0aGlzLnN0YXRlKTtcblx0ICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbW92ZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gbW92ZSgpIHtcblx0ICAgICAgICBpZiAodGhpcy5tb2RlID09PSBcImFmdGVydG91Y2hcIikge1xuXHQgICAgICAgICAgdGhpcy5wb3NpdGlvbiA9IHtcblx0ICAgICAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsIDAsIDEpLFxuXHQgICAgICAgICAgICB5OiBtYXRoLmNsaXAoMSAtIHRoaXMubW91c2UueSAvIHRoaXMuaGVpZ2h0LCAwLCAxKVxuXHQgICAgICAgICAgfTtcblx0ICAgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB7XG5cdCAgICAgICAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuXHQgICAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG5cdCAgICAgICAgICAgIHk6IHRoaXMucG9zaXRpb24ueSB9KTtcblx0ICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcmVsZWFzZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVsZWFzZSgpIHtcblx0ICAgICAgICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuXHQgICAgICAgICAgY2FzZSBcImJ1dHRvblwiOlxuXHQgICAgICAgICAgICB0aGlzLnR1cm5PZmYoKTtcblx0ICAgICAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMuc3RhdGUpO1xuXHQgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgIGNhc2UgXCJhZnRlcnRvdWNoXCI6XG5cdCAgICAgICAgICAgIHRoaXMudHVybk9mZigpO1xuXHQgICAgICAgICAgICB0aGlzLnBvc2l0aW9uID0ge1xuXHQgICAgICAgICAgICAgIHg6IHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsXG5cdCAgICAgICAgICAgICAgeTogMSAtIHRoaXMubW91c2UueSAvIHRoaXMuaGVpZ2h0XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB7XG5cdCAgICAgICAgICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG5cdCAgICAgICAgICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuXHQgICAgICAgICAgICAgIHk6IHRoaXMucG9zaXRpb24ueSB9KTtcblx0ICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSk7XG5cdFxuXHQgIHJldHVybiBCdXR0b247XG5cdH0pKCk7XG5cbi8qKiovIH0pLFxuLyogMTMgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdHZhciBUb2dnbGUgPSAoZnVuY3Rpb24gKCkge1xuXHQgIGZ1bmN0aW9uIFRvZ2dsZShzdGF0ZSkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFRvZ2dsZSk7XG5cdFxuXHQgICAgdGhpcy5zdGF0ZSA9IHN0YXRlIHx8IGZhbHNlO1xuXHQgIH1cblx0XG5cdCAgX2NyZWF0ZUNsYXNzKFRvZ2dsZSwge1xuXHQgICAgZmxpcDoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gZmxpcChzdGF0ZSkge1xuXHQgICAgICAgIGlmIChzdGF0ZSB8fCBzdGF0ZSA9PT0gZmFsc2UpIHtcblx0ICAgICAgICAgIHRoaXMuc3RhdGUgPSBzdGF0ZTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdGhpcy5zdGF0ZSA9ICF0aGlzLnN0YXRlO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBvbigpIHtcblx0ICAgICAgICB0aGlzLnN0YXRlID0gdHJ1ZTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIG9mZjoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gb2ZmKCkge1xuXHQgICAgICAgIHRoaXMuc3RhdGUgPSBmYWxzZTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pO1xuXHRcblx0ICByZXR1cm4gVG9nZ2xlO1xuXHR9KSgpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBUb2dnbGU7XG5cbi8qKiovIH0pLFxuLyogMTQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCA9IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgXCJkZWZhdWx0XCI6IG9iaiB9OyB9O1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9nZXQgPSBmdW5jdGlvbiBnZXQob2JqZWN0LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpIHsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyByZXR1cm4gZ2V0KHBhcmVudCwgcHJvcGVydHksIHJlY2VpdmVyKTsgfSB9IGVsc2UgaWYgKFwidmFsdWVcIiBpbiBkZXNjICYmIGRlc2Mud3JpdGFibGUpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9O1xuXHRcblx0dmFyIF9pbmhlcml0cyA9IGZ1bmN0aW9uIChzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9O1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIHN2ZyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7XG5cdHZhciBJbnRlcmZhY2UgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpO1xuXHR2YXIgU3RlcCA9IF9fd2VicGFja19yZXF1aXJlX18oMTEpO1xuXHRcblx0dmFyIEludGVyYWN0aW9uID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX193ZWJwYWNrX3JlcXVpcmVfXygxMikpO1xuXHRcblx0LyoqXG5cdCogU2xpZGVyXG5cdCpcblx0KiBAZGVzY3JpcHRpb24gSG9yaXpvbnRhbCBvciB2ZXJ0aWNhbCBzbGlkZXIgd2l0aCBzZXR0YWJsZSBpbnRlcmFjdGlvbiBtb2Rlcy5cblx0KlxuXHQqIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwic2xpZGVyXCIgc3RlcD0wLjI+PC9zcGFuPlxuXHQqXG5cdCogQGV4YW1wbGVcblx0KiB2YXIgc2xpZGVyID0gbmV3IE5leHVzLlNsaWRlcignI3RhcmdldCcpXG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciBzbGlkZXIgPSBuZXcgTmV4dXMuU2xpZGVyKCcjdGFyZ2V0Jyx7XG5cdCogICAgICdzaXplJzogWzEyMCwyMF0sXG5cdCogICAgICdtb2RlJzogJ3JlbGF0aXZlJywgIC8vICdyZWxhdGl2ZScgb3IgJ2Fic29sdXRlJ1xuXHQqICAgICAnbWluJzogMCxcblx0KiAgICAgJ21heCc6IDEsXG5cdCogICAgICdzdGVwJzogMCxcblx0KiAgICAgJ3ZhbHVlJzogMFxuXHQqIH0pXG5cdCpcblx0KiBAb3V0cHV0XG5cdCogY2hhbmdlXG5cdCogRmlyZXMgd2hlbiB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuXHQqIEV2ZW50IGRhdGE6IDxpPm51bWJlcjwvaT4gVGhlIG51bWJlciB2YWx1ZSBvZiB0aGUgaW50ZXJmYWNlLlxuXHQqXG5cdCogQG91dHB1dGV4YW1wbGVcblx0KiBzbGlkZXIub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuXHQqICAgY29uc29sZS5sb2codik7XG5cdCogfSlcblx0KlxuXHQqXG5cdCovXG5cdFxuXHR2YXIgU2xpZGVyID0gKGZ1bmN0aW9uIChfSW50ZXJmYWNlKSB7XG5cdCAgZnVuY3Rpb24gU2xpZGVyKCkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFNsaWRlcik7XG5cdFxuXHQgICAgdmFyIG9wdGlvbnMgPSBbXCJtaW5cIiwgXCJtYXhcIiwgXCJ2YWx1ZVwiXTtcblx0XG5cdCAgICB2YXIgZGVmYXVsdHMgPSB7XG5cdCAgICAgIHNpemU6IFsxMjAsIDIwXSxcblx0ICAgICAgbW9kZTogXCJyZWxhdGl2ZVwiLCAvLyAncmVsYXRpdmUnIG9yICdhYnNvbHV0ZSdcblx0ICAgICAgbWluOiAwLFxuXHQgICAgICBtYXg6IDEsXG5cdCAgICAgIHN0ZXA6IDAsXG5cdCAgICAgIHZhbHVlOiAwXG5cdCAgICB9O1xuXHRcblx0ICAgIF9nZXQoT2JqZWN0LmdldFByb3RvdHlwZU9mKFNsaWRlci5wcm90b3R5cGUpLCBcImNvbnN0cnVjdG9yXCIsIHRoaXMpLmNhbGwodGhpcywgYXJndW1lbnRzLCBvcHRpb25zLCBkZWZhdWx0cyk7XG5cdFxuXHQgICAgdGhpcy5vcmllbnRhdGlvbiA9IFwidmVydGljYWxcIjsgLy8gVGhpcyB3aWxsIGNoYW5nZSBhdXRvbWF0aWNhbGx5IHRvICdob3Jpem9udGFsJ2lmIHRoZSBpbnRlcmZhY2UgaXMgd2lkZXIgdGhhbiBpdCBpcyB0YWxsLlxuXHRcblx0ICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5taW4sIHRoaXMuc2V0dGluZ3MubWF4LCB0aGlzLnNldHRpbmdzLnN0ZXAsIHRoaXMuc2V0dGluZ3MudmFsdWUpO1xuXHRcblx0ICAgIHRoaXMucG9zaXRpb24gPSBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMuc2V0dGluZ3MubW9kZSwgdGhpcy5vcmllbnRhdGlvbiwgWzAsIHRoaXMud2lkdGhdLCBbdGhpcy5oZWlnaHQsIDBdKTtcblx0ICAgIHRoaXMucG9zaXRpb24udmFsdWUgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXHRcblx0ICAgIHRoaXMuaW5pdCgpO1xuXHRcblx0ICAgIHRoaXMucG9zaXRpb24uZGlyZWN0aW9uID0gdGhpcy5vcmllbnRhdGlvbjtcblx0XG5cdCAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy52YWx1ZSk7XG5cdCAgfVxuXHRcblx0ICBfaW5oZXJpdHMoU2xpZGVyLCBfSW50ZXJmYWNlKTtcblx0XG5cdCAgX2NyZWF0ZUNsYXNzKFNsaWRlciwge1xuXHQgICAgYnVpbGRJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkSW50ZXJmYWNlKCkge1xuXHRcblx0ICAgICAgICB0aGlzLmJhciA9IHN2Zy5jcmVhdGUoXCJyZWN0XCIpO1xuXHQgICAgICAgIHRoaXMuZmlsbGJhciA9IHN2Zy5jcmVhdGUoXCJyZWN0XCIpO1xuXHQgICAgICAgIHRoaXMua25vYiA9IHN2Zy5jcmVhdGUoXCJjaXJjbGVcIik7XG5cdFxuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhcik7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuZmlsbGJhcik7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzaXplSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBzaXplSW50ZXJmYWNlKCkge1xuXHRcblx0ICAgICAgICBpZiAodGhpcy53aWR0aCA8IHRoaXMuaGVpZ2h0KSB7XG5cdCAgICAgICAgICB0aGlzLm9yaWVudGF0aW9uID0gXCJ2ZXJ0aWNhbFwiO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aGlzLm9yaWVudGF0aW9uID0gXCJob3Jpem9udGFsXCI7XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICBpZiAodGhpcy5wb3NpdGlvbikge1xuXHQgICAgICAgICAgdGhpcy5wb3NpdGlvbi5yZXNpemUoWzAsIHRoaXMud2lkdGhdLCBbdGhpcy5oZWlnaHQsIDBdKTtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHZhciB4ID0gdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICB5ID0gdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICB3ID0gdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICBoID0gdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICBiYXJPZmZzZXQgPSB1bmRlZmluZWQsXG5cdCAgICAgICAgICAgIGNvcm5lclJhZGl1cyA9IHVuZGVmaW5lZDtcblx0ICAgICAgICB0aGlzLmtub2JEYXRhID0ge1xuXHQgICAgICAgICAgbGV2ZWw6IDAsXG5cdCAgICAgICAgICByOiAwXG5cdCAgICAgICAgfTtcblx0XG5cdCAgICAgICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09IFwidmVydGljYWxcIikge1xuXHQgICAgICAgICAgdGhpcy50aGlja25lc3MgPSB0aGlzLndpZHRoIC8gMjtcblx0ICAgICAgICAgIHggPSB0aGlzLndpZHRoIC8gMjtcblx0ICAgICAgICAgIHkgPSAwO1xuXHQgICAgICAgICAgdyA9IHRoaXMudGhpY2tuZXNzO1xuXHQgICAgICAgICAgaCA9IHRoaXMuaGVpZ2h0O1xuXHQgICAgICAgICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MgKiAwLjg7XG5cdCAgICAgICAgICB0aGlzLmtub2JEYXRhLmxldmVsID0gaCAtIHRoaXMua25vYkRhdGEuciAtIHRoaXMubm9ybWFsaXplZCAqIChoIC0gdGhpcy5rbm9iRGF0YS5yICogMik7XG5cdCAgICAgICAgICBiYXJPZmZzZXQgPSBcInRyYW5zbGF0ZShcIiArIHRoaXMudGhpY2tuZXNzICogLTEgLyAyICsgXCIsMClcIjtcblx0ICAgICAgICAgIGNvcm5lclJhZGl1cyA9IHcgLyAyO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMuaGVpZ2h0IC8gMjtcblx0ICAgICAgICAgIHggPSAwO1xuXHQgICAgICAgICAgeSA9IHRoaXMuaGVpZ2h0IC8gMjtcblx0ICAgICAgICAgIHcgPSB0aGlzLndpZHRoO1xuXHQgICAgICAgICAgaCA9IHRoaXMudGhpY2tuZXNzO1xuXHQgICAgICAgICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MgKiAwLjg7XG5cdCAgICAgICAgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5ub3JtYWxpemVkICogKHcgLSB0aGlzLmtub2JEYXRhLnIgKiAyKSArIHRoaXMua25vYkRhdGEucjtcblx0ICAgICAgICAgIGJhck9mZnNldCA9IFwidHJhbnNsYXRlKDAsXCIgKyB0aGlzLnRoaWNrbmVzcyAqIC0xIC8gMiArIFwiKVwiO1xuXHQgICAgICAgICAgY29ybmVyUmFkaXVzID0gaCAvIDI7XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoXCJ4XCIsIHgpO1xuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcInlcIiwgeSk7XG5cdCAgICAgICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIGJhck9mZnNldCk7XG5cdCAgICAgICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKFwicnhcIiwgY29ybmVyUmFkaXVzKTsgLy8gY29ybmVyIHJhZGl1c1xuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcInJ5XCIsIGNvcm5lclJhZGl1cyk7XG5cdCAgICAgICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgdyk7XG5cdCAgICAgICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGgpO1xuXHRcblx0ICAgICAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gXCJ2ZXJ0aWNhbFwiKSB7XG5cdCAgICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwieFwiLCB4KTtcblx0ICAgICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoXCJ5XCIsIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuXHQgICAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIHcpO1xuXHQgICAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCBoIC0gdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoXCJ4XCIsIDApO1xuXHQgICAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcInlcIiwgeSk7XG5cdCAgICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG5cdCAgICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIGJhck9mZnNldCk7XG5cdCAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcInJ4XCIsIGNvcm5lclJhZGl1cyk7XG5cdCAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcInJ5XCIsIGNvcm5lclJhZGl1cyk7XG5cdFxuXHQgICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSBcInZlcnRpY2FsXCIpIHtcblx0ICAgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJjeFwiLCB4KTtcblx0ICAgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJjeVwiLCB0aGlzLmtub2JEYXRhLmxldmVsKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImN4XCIsIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuXHQgICAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImN5XCIsIHkpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiclwiLCB0aGlzLmtub2JEYXRhLnIpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY29sb3JJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbG9ySW50ZXJmYWNlKCkge1xuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdGhpcy5jb2xvcnMuZmlsbCk7XG5cdCAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdGhpcy5jb2xvcnMuYWNjZW50KTtcblx0ICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcmVuZGVyOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cdCAgICAgICAgaWYgKCF0aGlzLmNsaWNrZWQpIHtcblx0ICAgICAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC43NTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcInJcIiwgdGhpcy5rbm9iRGF0YS5yKTtcblx0XG5cdCAgICAgICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09IFwidmVydGljYWxcIikge1xuXHQgICAgICAgICAgdGhpcy5rbm9iRGF0YS5sZXZlbCA9IHRoaXMua25vYkRhdGEuciArIHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQgKiAodGhpcy5oZWlnaHQgLSB0aGlzLmtub2JEYXRhLnIgKiAyKTtcblx0ICAgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJjeVwiLCB0aGlzLmhlaWdodCAtIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuXHQgICAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcInlcIiwgdGhpcy5oZWlnaHQgLSB0aGlzLmtub2JEYXRhLmxldmVsKTtcblx0ICAgICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkICogKHRoaXMud2lkdGggLSB0aGlzLmtub2JEYXRhLnIgKiAyKSArIHRoaXMua25vYkRhdGEucjtcblx0ICAgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJjeFwiLCB0aGlzLmtub2JEYXRhLmxldmVsKTtcblx0ICAgICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoXCJ4XCIsIDApO1xuXHQgICAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNsaWNrOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjbGljaygpIHtcblx0ICAgICAgICB0aGlzLmtub2JEYXRhLnIgPSB0aGlzLnRoaWNrbmVzcyAqIDAuOTtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG5cdCAgICAgICAgdGhpcy5tb3ZlKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBtb3ZlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBtb3ZlKCkge1xuXHQgICAgICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcblx0ICAgICAgICAgIHRoaXMucG9zaXRpb24udXBkYXRlKHRoaXMubW91c2UpO1xuXHQgICAgICAgICAgdGhpcy5fdmFsdWUudXBkYXRlTm9ybWFsKHRoaXMucG9zaXRpb24udmFsdWUpO1xuXHQgICAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMuX3ZhbHVlLnZhbHVlKTtcblx0ICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcmVsZWFzZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVsZWFzZSgpIHtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbm9ybWFsaXplZDoge1xuXHQgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHZhbHVlOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgVGhlIHNsaWRlcidzIGN1cnJlbnQgdmFsdWUuIElmIHNldCBtYW51YWxseSwgd2lsbCB1cGRhdGUgdGhlIGludGVyZmFjZSBhbmQgdHJpZ2dlciB0aGUgb3V0cHV0IGV2ZW50LlxuXHQgICAgICBAdHlwZSB7bnVtYmVyfVxuXHQgICAgICBAZXhhbXBsZSBzbGlkZXIudmFsdWUgPSAxMDtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl92YWx1ZS52YWx1ZTtcblx0ICAgICAgfSxcblx0ICAgICAgc2V0OiBmdW5jdGlvbiAodikge1xuXHQgICAgICAgIHRoaXMuX3ZhbHVlLnVwZGF0ZSh2KTtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblx0ICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy5fdmFsdWUudmFsdWUpO1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBtaW46IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBMb3dlciBsaW1pdCBvZiB0aGUgc2xpZGVycydzIG91dHB1dCByYW5nZVxuXHQgICAgICBAdHlwZSB7bnVtYmVyfVxuXHQgICAgICBAZXhhbXBsZSBzbGlkZXIubWluID0gMTAwMDtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5taW47XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLl92YWx1ZS5taW4gPSB2O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbWF4OiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgVXBwZXIgbGltaXQgb2YgdGhlIHNsaWRlcidzIG91dHB1dCByYW5nZVxuXHQgICAgICBAdHlwZSB7bnVtYmVyfVxuXHQgICAgICBAZXhhbXBsZSBzbGlkZXIubWF4ID0gMTAwMDtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5tYXg7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLl92YWx1ZS5tYXggPSB2O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc3RlcDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFRoZSBpbmNyZW1lbnQgdGhhdCB0aGUgc2xpZGVyJ3MgdmFsdWUgY2hhbmdlcyBieS5cblx0ICAgICAgQHR5cGUge251bWJlcn1cblx0ICAgICAgQGV4YW1wbGUgc2xpZGVyLnN0ZXAgPSA1O1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnN0ZXA7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLl92YWx1ZS5zdGVwID0gdjtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIG1vZGU6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBBYnNvbHV0ZSBtb2RlIChzbGlkZXIncyB2YWx1ZSBqdW1wcyB0byBtb3VzZSBjbGljayBwb3NpdGlvbikgb3IgcmVsYXRpdmUgbW9kZSAobW91c2UgZHJhZyBjaGFuZ2VzIHZhbHVlIHJlbGF0aXZlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uKS4gRGVmYXVsdDogXCJyZWxhdGl2ZVwiLlxuXHQgICAgICBAdHlwZSB7c3RyaW5nfVxuXHQgICAgICBAZXhhbXBsZSBzbGlkZXIubW9kZSA9IFwicmVsYXRpdmVcIjtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uLm1vZGU7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uLm1vZGUgPSB2O1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSk7XG5cdFxuXHQgIHJldHVybiBTbGlkZXI7XG5cdH0pKEludGVyZmFjZSk7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IFNsaWRlcjtcblxuLyoqKi8gfSksXG4vKiAxNSAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9nZXQgPSBmdW5jdGlvbiBnZXQob2JqZWN0LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpIHsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyByZXR1cm4gZ2V0KHBhcmVudCwgcHJvcGVydHksIHJlY2VpdmVyKTsgfSB9IGVsc2UgaWYgKFwidmFsdWVcIiBpbiBkZXNjICYmIGRlc2Mud3JpdGFibGUpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9O1xuXHRcblx0dmFyIF9pbmhlcml0cyA9IGZ1bmN0aW9uIChzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9O1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIHN2ZyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7XG5cdHZhciBUb2dnbGVNb2RlbCA9IF9fd2VicGFja19yZXF1aXJlX18oMTMpO1xuXHR2YXIgSW50ZXJmYWNlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2KTtcblx0XG5cdC8qKlxuXHQqIFRvZ2dsZVxuXHQqXG5cdCogQGRlc2NyaXB0aW9uIEJpbmFyeSBzd2l0Y2hcblx0KlxuXHQqIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwidG9nZ2xlXCI+PC9zcGFuPlxuXHQqXG5cdCogQGV4YW1wbGVcblx0KiB2YXIgdG9nZ2xlID0gbmV3IE5leHVzLlRvZ2dsZSgnI3RhcmdldCcpXG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciB0b2dnbGUgPSBuZXcgTmV4dXMuVG9nZ2xlKCcjdGFyZ2V0Jyx7XG5cdCogICAgICdzaXplJzogWzQwLDIwXSxcblx0KiAgICAgJ3N0YXRlJzogZmFsc2Vcblx0KiB9KVxuXHQqXG5cdCogQG91dHB1dFxuXHQqIGNoYW5nZVxuXHQqIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG5cdCogUGFyYW1ldGVyOiBUaGUgYm9vbGVhbiBzdGF0ZSBvZiB0aGUgaW50ZXJmYWNlLlxuXHQqXG5cdCogQG91dHB1dGV4YW1wbGVcblx0KiB0b2dnbGUub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuXHQqICAgY29uc29sZS5sb2codik7XG5cdCogfSlcblx0KlxuXHQqXG5cdCovXG5cdFxuXHR2YXIgVG9nZ2xlID0gKGZ1bmN0aW9uIChfSW50ZXJmYWNlKSB7XG5cdCAgZnVuY3Rpb24gVG9nZ2xlKCkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFRvZ2dsZSk7XG5cdFxuXHQgICAgdmFyIG9wdGlvbnMgPSBbXCJ2YWx1ZVwiXTtcblx0XG5cdCAgICB2YXIgZGVmYXVsdHMgPSB7XG5cdCAgICAgIHNpemU6IFs0MCwgMjBdLFxuXHQgICAgICB0YXJnZXQ6IGZhbHNlLFxuXHQgICAgICBzdGF0ZTogZmFsc2Vcblx0ICAgIH07XG5cdFxuXHQgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoVG9nZ2xlLnByb3RvdHlwZSksIFwiY29uc3RydWN0b3JcIiwgdGhpcykuY2FsbCh0aGlzLCBhcmd1bWVudHMsIG9wdGlvbnMsIGRlZmF1bHRzKTtcblx0XG5cdCAgICB0aGlzLl9zdGF0ZSA9IG5ldyBUb2dnbGVNb2RlbCh0aGlzLnNldHRpbmdzLnN0YXRlKTtcblx0XG5cdCAgICB0aGlzLmluaXQoKTtcblx0ICB9XG5cdFxuXHQgIF9pbmhlcml0cyhUb2dnbGUsIF9JbnRlcmZhY2UpO1xuXHRcblx0ICBfY3JlYXRlQ2xhc3MoVG9nZ2xlLCB7XG5cdCAgICBidWlsZEludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gYnVpbGRJbnRlcmZhY2UoKSB7XG5cdFxuXHQgICAgICAgIHRoaXMuYmFyID0gc3ZnLmNyZWF0ZShcInJlY3RcIik7XG5cdCAgICAgICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZShcImNpcmNsZVwiKTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXIpO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmtub2IpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2l6ZUludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc2l6ZUludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgaWYgKHRoaXMuaGVpZ2h0IDwgdGhpcy53aWR0aCAvIDIpIHtcblx0ICAgICAgICAgIHRoaXMua25vYlNpemUgPSB0aGlzLmhlaWdodCAvIDI7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMua25vYlNpemUgPSB0aGlzLndpZHRoIC8gNDtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcInhcIiwgdGhpcy53aWR0aCAvIDIgLSB0aGlzLmtub2JTaXplICogMS41KTtcblx0ICAgICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoXCJ5XCIsIHRoaXMuaGVpZ2h0IC8gMiAtIHRoaXMua25vYlNpemUgLyAyKTtcblx0ICAgICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoXCJyeFwiLCB0aGlzLmtub2JTaXplIC8gMik7XG5cdCAgICAgICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKFwicnlcIiwgdGhpcy5rbm9iU2l6ZSAvIDIpO1xuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIHRoaXMua25vYlNpemUgKiAzKTtcblx0ICAgICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgdGhpcy5rbm9iU2l6ZSk7XG5cdFxuXHQgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJjeFwiLCB0aGlzLndpZHRoIC8gMiAtIHRoaXMua25vYlNpemUpO1xuXHQgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJjeVwiLCB0aGlzLmhlaWdodCAvIDIpO1xuXHQgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJyXCIsIHRoaXMua25vYlNpemUpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY29sb3JJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbG9ySW50ZXJmYWNlKCkge1xuXHQgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cdCAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHJlbmRlcjoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuXHQgICAgICAgIGlmICghdGhpcy5zdGF0ZSkge1xuXHQgICAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImN4XCIsIHRoaXMud2lkdGggLyAyIC0gdGhpcy5rbm9iU2l6ZSk7XG5cdCAgICAgICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3JzLmZpbGwpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiY3hcIiwgdGhpcy53aWR0aCAvIDIgKyB0aGlzLmtub2JTaXplKTtcblx0ICAgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdGhpcy5jb2xvcnMuYWNjZW50KTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjbGljazoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY2xpY2soKSB7XG5cdCAgICAgICAgdGhpcy5mbGlwKCk7XG5cdCAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy5zdGF0ZSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzdGF0ZToge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFdoZXRoZXIgdGhlIHRvZ2dsZSBpcyBjdXJyZW50bHkgb24gb3Igb2ZmLiBTZXR0aW5nIHRoaXMgcHJvcGVydHkgd2lsbCB1cGRhdGUgdGhlIHRvZ2dsZSBpbnRlcmZhY2UgYW5kIHRyaWdnZXIgdGhlIG91dHB1dCBldmVudC5cblx0ICAgICAgQHR5cGUge2Jvb2xlYW59XG5cdCAgICAgIEBleGFtcGxlIHRvZ2dsZS5zdGF0ZSA9IGZhbHNlO1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLnN0YXRlO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHQgICAgICAgIHRoaXMuX3N0YXRlLmZsaXAodmFsdWUpO1xuXHQgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB0aGlzLnN0YXRlKTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgZmxpcDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgICogU3dpdGNoIHRoZSB0b2dnbGUgc3RhdGUgdG8gaXRzIG9wcG9zaXRlIHN0YXRlXG5cdCAgICAgICogQGV4YW1wbGVcblx0ICAgICAgKiB0b2dnbGUuZmxpcCgpO1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZsaXAoKSB7XG5cdCAgICAgICAgdGhpcy5fc3RhdGUuZmxpcCgpO1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIFRvZ2dsZTtcblx0fSkoSW50ZXJmYWNlKTtcblx0XG5cdG1vZHVsZS5leHBvcnRzID0gVG9nZ2xlO1xuXG4vKioqLyB9KSxcbi8qIDE2ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgX2NyZWF0ZUNsYXNzID0gKGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGtleSBpbiBwcm9wcykgeyB2YXIgcHJvcCA9IHByb3BzW2tleV07IHByb3AuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKHByb3AudmFsdWUpIHByb3Aud3JpdGFibGUgPSB0cnVlOyB9IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpOyB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cdFxuXHR2YXIgX2dldCA9IGZ1bmN0aW9uIGdldChvYmplY3QsIHByb3BlcnR5LCByZWNlaXZlcikgeyB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBwcm9wZXJ0eSk7IGlmIChkZXNjID09PSB1bmRlZmluZWQpIHsgdmFyIHBhcmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpOyBpZiAocGFyZW50ID09PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gZWxzZSB7IHJldHVybiBnZXQocGFyZW50LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpOyB9IH0gZWxzZSBpZiAoXCJ2YWx1ZVwiIGluIGRlc2MgJiYgZGVzYy53cml0YWJsZSkgeyByZXR1cm4gZGVzYy52YWx1ZTsgfSBlbHNlIHsgdmFyIGdldHRlciA9IGRlc2MuZ2V0OyBpZiAoZ2V0dGVyID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpOyB9IH07XG5cdFxuXHR2YXIgX2luaGVyaXRzID0gZnVuY3Rpb24gKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgXCIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH07XG5cdFxuXHR2YXIgX2NsYXNzQ2FsbENoZWNrID0gZnVuY3Rpb24gKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH07XG5cdFxuXHR2YXIgc3ZnID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTtcblx0dmFyIEJ1dHRvblRlbXBsYXRlID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNyk7XG5cdFxuXHQvKipcblx0KiBCdXR0b25cblx0KlxuXHQqIEBkZXNjcmlwdGlvbiBDaXJjdWxhciBidXR0b24gd2l0aCBvcHRpb25hbCBhZnRlcnRvdWNoLlxuXHQqXG5cdCogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJidXR0b25cIj48L3NwYW4+XG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciBidXR0b24gPSBuZXcgTmV4dXMuQnV0dG9uKCcjdGFyZ2V0Jylcblx0KlxuXHQqIEBleGFtcGxlXG5cdCogdmFyIGJ1dHRvbiA9IG5ldyBOZXh1cy5CdXR0b24oJyN0YXJnZXQnLHtcblx0KiAgICdzaXplJzogWzgwLDgwXSxcblx0KiAgICdtb2RlJzogJ2FmdGVydG91Y2gnLFxuXHQqICAgJ3N0YXRlJzogZmFsc2Vcblx0KiB9KVxuXHQqXG5cdCogQG91dHB1dFxuXHQqIGNoYW5nZVxuXHQqIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG5cdCogSW4gPGI+YnV0dG9uIG1vZGU8L2I+LCA8Yj50b2dnbGUgbW9kZTwvYj4sIGFuZCA8Yj5pbXB1bHNlIG1vZGU8L2I+LCB0aGUgb3V0cHV0IGRhdGEgaXMgYSBib29sZWFuIGRlc2NyaWJpbmcgdGhlIHN0YXRlIG9mIHRoZSBidXR0b24uPGJyPlxuXHQqIEluIDxiPmFmdGVydG91Y2ggbW9kZTwvYj4sIHRoZSBvdXRwdXQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyB4ICgwLTEpIGFuZCB5ICgwLTEpIHBvc2l0aW9ucyBvZiBhZnRlcnRvdWNoLlxuXHQqXG5cdCogQG91dHB1dGV4YW1wbGVcblx0KiBidXR0b24ub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuXHQqICAgLy8gdiBpcyB0aGUgdmFsdWUgb2YgdGhlIGJ1dHRvblxuXHQqICAgY29uc29sZS5sb2codik7XG5cdCogfSlcblx0KlxuXHQqL1xuXHRcblx0dmFyIEJ1dHRvbiA9IChmdW5jdGlvbiAoX0J1dHRvblRlbXBsYXRlKSB7XG5cdCAgZnVuY3Rpb24gQnV0dG9uKCkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEJ1dHRvbik7XG5cdFxuXHQgICAgdmFyIG9wdGlvbnMgPSBbXCJtb2RlXCJdO1xuXHRcblx0ICAgIHZhciBkZWZhdWx0cyA9IHtcblx0ICAgICAgc2l6ZTogWzgwLCA4MF0sXG5cdCAgICAgIG1vZGU6IFwiYWZ0ZXJ0b3VjaFwiLCAvLyBidXR0b24sIGFmdGVydG91Y2gsIGltcHVsc2UsIHRvZ2dsZVxuXHQgICAgICBzdGF0ZTogZmFsc2Vcblx0ICAgIH07XG5cdFxuXHQgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoQnV0dG9uLnByb3RvdHlwZSksIFwiY29uc3RydWN0b3JcIiwgdGhpcykuY2FsbCh0aGlzLCBhcmd1bWVudHMsIG9wdGlvbnMsIGRlZmF1bHRzKTtcblx0XG5cdCAgICAvKipcblx0ICAgICogSW50ZXJhY3Rpb24gbW9kZTogc3VwcG9ydHMgXCJidXR0b25cIiwgXCJhZnRlcnRvdWNoXCIsIFwiaW1wdWxzZVwiLCBvciBcInRvZ2dsZVwiXG5cdCAgICAqIEB0eXBlIHtzdHJpbmd9XG5cdCAgICAqIEBleGFtcGxlIGJ1dHRvbi5tb2RlID0gJ3RvZ2dsZSc7XG5cdCAgICAqL1xuXHQgICAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlO1xuXHRcblx0ICAgIHRoaXMuaW5pdCgpO1xuXHQgICAgdGhpcy5yZW5kZXIoKTtcblx0ICB9XG5cdFxuXHQgIF9pbmhlcml0cyhCdXR0b24sIF9CdXR0b25UZW1wbGF0ZSk7XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhCdXR0b24sIHtcblx0ICAgIGJ1aWxkSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBidWlsZEludGVyZmFjZSgpIHtcblx0ICAgICAgICB0aGlzLnBhZCA9IHN2Zy5jcmVhdGUoXCJjaXJjbGVcIik7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMucGFkKTtcblx0XG5cdCAgICAgICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXHRcblx0ICAgICAgICAvLyBvbmx5IHVzZWQgaWYgaW4gJ2FmdGVydG91Y2gnIG1vZGVcblx0ICAgICAgICB0aGlzLmRlZnMgPSBzdmcuY3JlYXRlKFwiZGVmc1wiKTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5kZWZzKTtcblx0XG5cdCAgICAgICAgdGhpcy5ncmFkaWVudCA9IHN2Zy5yYWRpYWxHcmFkaWVudCh0aGlzLmRlZnMsIDIpO1xuXHRcblx0ICAgICAgICB0aGlzLmdyYWRpZW50LnN0b3BzWzBdLnNldEF0dHJpYnV0ZShcIm9mZnNldFwiLCBcIjMwJVwiKTtcblx0XG5cdCAgICAgICAgdGhpcy5ncmFkaWVudC5zdG9wc1sxXS5zZXRBdHRyaWJ1dGUoXCJvZmZzZXRcIiwgXCIxMDAlXCIpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2l6ZUludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc2l6ZUludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwiY3hcIiwgdGhpcy53aWR0aCAvIDIpO1xuXHQgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcImN5XCIsIHRoaXMuaGVpZ2h0IC8gMik7XG5cdCAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwiclwiLCBNYXRoLm1pbih0aGlzLndpZHRoLCB0aGlzLmhlaWdodCkgLyAyIC0gdGhpcy53aWR0aCAvIDQwKTtcblx0ICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgdGhpcy53aWR0aCAvIDIwKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNvbG9ySW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb2xvckludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgdGhpcy5ncmFkaWVudC5zdG9wc1swXS5zZXRBdHRyaWJ1dGUoXCJzdG9wLWNvbG9yXCIsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cdCAgICAgICAgdGhpcy5ncmFkaWVudC5zdG9wc1sxXS5zZXRBdHRyaWJ1dGUoXCJzdG9wLWNvbG9yXCIsIHRoaXMuY29sb3JzLmZpbGwpO1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByZW5kZXI6IHtcblx0XG5cdCAgICAgIC8qXG5cdCAgICAgICogVXBkYXRlIHRoZSB2aXN1YWwgaW50ZXJmYWNlIHVzaW5nIGl0cyBjdXJyZW50IHN0YXRlXG5cdCAgICAgICpcblx0ICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAqIGJ1dHRvbi5yZW5kZXIoKTtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cdCAgICAgICAgaWYgKCF0aGlzLnN0YXRlKSB7XG5cdCAgICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3JzLmZpbGwpO1xuXHQgICAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgaWYgKHRoaXMubW9kZSA9PT0gXCJhZnRlcnRvdWNoXCIpIHtcblx0ICAgICAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwidXJsKCNcIiArIHRoaXMuZ3JhZGllbnQuaWQgKyBcIilcIik7XG5cdCAgICAgICAgICAgIHRoaXMuZ3JhZGllbnQuZWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJjeFwiLCB0aGlzLnBvc2l0aW9uLnggKiAxMDAgKyBcIiVcIik7XG5cdCAgICAgICAgICAgIHRoaXMuZ3JhZGllbnQuZWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJjeVwiLCAoMSAtIHRoaXMucG9zaXRpb24ueSkgKiAxMDAgKyBcIiVcIik7XG5cdCAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgdGhpcy5jb2xvcnMuYWNjZW50KTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdGhpcy5jb2xvcnMuYWNjZW50KTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIEJ1dHRvbjtcblx0fSkoQnV0dG9uVGVtcGxhdGUpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBCdXR0b247XG5cbi8qKiovIH0pLFxuLyogMTcgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KG9iamVjdCwgcHJvcGVydHksIHJlY2VpdmVyKSB7IHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHByb3BlcnR5KTsgaWYgKGRlc2MgPT09IHVuZGVmaW5lZCkgeyB2YXIgcGFyZW50ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCk7IGlmIChwYXJlbnQgPT09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBlbHNlIHsgcmV0dXJuIGdldChwYXJlbnQsIHByb3BlcnR5LCByZWNlaXZlcik7IH0gfSBlbHNlIGlmIChcInZhbHVlXCIgaW4gZGVzYyAmJiBkZXNjLndyaXRhYmxlKSB7IHJldHVybiBkZXNjLnZhbHVlOyB9IGVsc2UgeyB2YXIgZ2V0dGVyID0gZGVzYy5nZXQ7IGlmIChnZXR0ZXIgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IHJldHVybiBnZXR0ZXIuY2FsbChyZWNlaXZlcik7IH0gfTtcblx0XG5cdHZhciBfaW5oZXJpdHMgPSBmdW5jdGlvbiAoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSBcImZ1bmN0aW9uXCIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCBcIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdHZhciBzdmcgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpO1xuXHR2YXIgbWF0aCA9IF9fd2VicGFja19yZXF1aXJlX18oNSk7XG5cdHZhciBUb2dnbGVNb2RlbCA9IF9fd2VicGFja19yZXF1aXJlX18oMTMpO1xuXHR2YXIgSW50ZXJmYWNlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2KTtcblx0XG5cdC8qKlxuXHRCdXR0b24gVGVtcGxhdGVcblx0Ki9cblx0XG5cdHZhciBCdXR0b25UZW1wbGF0ZSA9IChmdW5jdGlvbiAoX0ludGVyZmFjZSkge1xuXHQgIGZ1bmN0aW9uIEJ1dHRvblRlbXBsYXRlKGFyZ3MsIG9wdGlvbnMsIGRlZmF1bHRzKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQnV0dG9uVGVtcGxhdGUpO1xuXHRcblx0ICAgIF9nZXQoT2JqZWN0LmdldFByb3RvdHlwZU9mKEJ1dHRvblRlbXBsYXRlLnByb3RvdHlwZSksIFwiY29uc3RydWN0b3JcIiwgdGhpcykuY2FsbCh0aGlzLCBhcmdzLCBvcHRpb25zLCBkZWZhdWx0cyk7XG5cdFxuXHQgICAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5tb2RlIHx8IFwiYnV0dG9uXCI7XG5cdFxuXHQgICAgdGhpcy5wb3NpdGlvbiA9IHtcblx0ICAgICAgeDogMCxcblx0ICAgICAgeTogMFxuXHQgICAgfTtcblx0XG5cdCAgICB0aGlzLl9zdGF0ZSA9IG5ldyBUb2dnbGVNb2RlbCh0aGlzLnNldHRpbmdzLnN0YXRlKTtcblx0ICB9XG5cdFxuXHQgIF9pbmhlcml0cyhCdXR0b25UZW1wbGF0ZSwgX0ludGVyZmFjZSk7XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhCdXR0b25UZW1wbGF0ZSwge1xuXHQgICAgYnVpbGRJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkSW50ZXJmYWNlKCkge1xuXHQgICAgICAgIHRoaXMucGFkID0gc3ZnLmNyZWF0ZShcImNpcmNsZVwiKTtcblx0ICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwiI2QxOFwiKTtcblx0ICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgXCIjZDE4XCIpO1xuXHQgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCA0KTtcblx0XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMucGFkKTtcblx0XG5cdCAgICAgICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXHRcblx0ICAgICAgICB0aGlzLnNpemVJbnRlcmZhY2UoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHNpemVJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNpemVJbnRlcmZhY2UoKSB7XG5cdCAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwiY3hcIiwgdGhpcy53aWR0aCAvIDIpO1xuXHQgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcImN5XCIsIHRoaXMuaGVpZ2h0IC8gMik7XG5cdCAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwiclwiLCBNYXRoLm1pbih0aGlzLndpZHRoLCB0aGlzLmhlaWdodCkgLyAyIC0gMik7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByZW5kZXI6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcblx0ICAgICAgICBpZiAoIXRoaXMuc3RhdGUpIHtcblx0ICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdGhpcy5jb2xvcnMuZmlsbCk7XG5cdCAgICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cdCAgICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgdGhpcy5jb2xvcnMuYWNjZW50KTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBkb3duOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBkb3duKHBhaW50YnJ1c2gpIHtcblx0ICAgICAgICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuXHQgICAgICAgICAgY2FzZSBcImltcHVsc2VcIjpcblx0ICAgICAgICAgICAgdGhpcy50dXJuT24oKTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMudGltZW91dCkge1xuXHQgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMudGltZW91dCA9IHNldFRpbWVvdXQodGhpcy50dXJuT2ZmLmJpbmQodGhpcyksIDMwKTtcblx0ICAgICAgICAgICAgLy8gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuXHQgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgIGNhc2UgXCJidXR0b25cIjpcblx0ICAgICAgICAgICAgdGhpcy50dXJuT24oKTtcblx0ICAgICAgICAgICAgLy8gICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMuc3RhdGUpO1xuXHQgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgIGNhc2UgXCJhZnRlcnRvdWNoXCI6XG5cdCAgICAgICAgICAgIHRoaXMucG9zaXRpb24gPSB7XG5cdCAgICAgICAgICAgICAgeDogbWF0aC5jbGlwKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsIDAsIDEpLFxuXHQgICAgICAgICAgICAgIHk6IG1hdGguY2xpcCgxIC0gdGhpcy5tb3VzZS55IC8gdGhpcy5oZWlnaHQsIDAsIDEpXG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIHRoaXMudHVybk9uKCk7XG5cdCAgICAgICAgICAgIC8vICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG5cdCAgICAgICAgICAgIC8vICAgICAgc3RhdGU6IHRoaXMuc3RhdGUsXG5cdCAgICAgICAgICAgIC8vICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuXHQgICAgICAgICAgICAvLyAgICAgIHk6IHRoaXMucG9zaXRpb24ueSxcblx0ICAgICAgICAgICAgLy8gICAgfSk7XG5cdCAgICAgICAgICAgIGJyZWFrO1xuXHQgICAgICAgICAgY2FzZSBcInRvZ2dsZVwiOlxuXHQgICAgICAgICAgICB0aGlzLmZsaXAocGFpbnRicnVzaCk7XG5cdCAgICAgICAgICAgIC8vICAgIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcblx0ICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgYmVuZDoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gYmVuZChtb3VzZSkge1xuXHQgICAgICAgIGlmICh0aGlzLm1vZGUgPT09IFwiYWZ0ZXJ0b3VjaFwiKSB7XG5cdCAgICAgICAgICB0aGlzLm1vdXNlID0gbW91c2UgfHwgdGhpcy5tb3VzZTtcblx0ICAgICAgICAgIHRoaXMucG9zaXRpb24gPSB7XG5cdCAgICAgICAgICAgIHg6IG1hdGguY2xpcCh0aGlzLm1vdXNlLnggLyB0aGlzLndpZHRoLCAwLCAxKSxcblx0ICAgICAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwgMCwgMSlcblx0ICAgICAgICAgIH07XG5cdCAgICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwge1xuXHQgICAgICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcblx0ICAgICAgICAgICAgeDogdGhpcy5wb3NpdGlvbi54LFxuXHQgICAgICAgICAgICB5OiB0aGlzLnBvc2l0aW9uLnkgfSk7XG5cdCAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHVwOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiB1cCgpIHtcblx0ICAgICAgICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuXHQgICAgICAgICAgY2FzZSBcImJ1dHRvblwiOlxuXHQgICAgICAgICAgICB0aGlzLnR1cm5PZmYoKTtcblx0ICAgICAgICAgICAgLy8gIHRoaXMuZW1pdCgnY2hhbmdlJyx0aGlzLnN0YXRlKTtcblx0ICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgICBjYXNlIFwiYWZ0ZXJ0b3VjaFwiOlxuXHQgICAgICAgICAgICB0aGlzLnR1cm5PZmYoKTtcblx0ICAgICAgICAgICAgdGhpcy5wb3NpdGlvbiA9IHtcblx0ICAgICAgICAgICAgICB4OiBtYXRoLmNsaXAodGhpcy5tb3VzZS54IC8gdGhpcy53aWR0aCwgMCwgMSksXG5cdCAgICAgICAgICAgICAgeTogbWF0aC5jbGlwKDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCwgMCwgMSlcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgLy8gIHRoaXMuZW1pdCgnY2hhbmdlJyx7XG5cdCAgICAgICAgICAgIC8vICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuXHQgICAgICAgICAgICAvLyAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG5cdCAgICAgICAgICAgIC8vICAgIHk6IHRoaXMucG9zaXRpb24ueSxcblx0ICAgICAgICAgICAgLy8gIH0pO1xuXHQgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjbGljazoge1xuXHRcblx0ICAgICAgLyogb3ZlcndyaXRhYmxlIGludGVyYWN0aW9uIGhhbmRsZXJzICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY2xpY2soKSB7XG5cdCAgICAgICAgdGhpcy5kb3duKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBtb3ZlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBtb3ZlKCkge1xuXHQgICAgICAgIHRoaXMuYmVuZCgpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcmVsZWFzZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVsZWFzZSgpIHtcblx0ICAgICAgICB0aGlzLnVwKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzdGF0ZToge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFdoZXRoZXIgdGhlIGJ1dHRvbiBpcyBvbiAocHJlc3NlZCkgb3Igb2ZmIChub3QgcHJlc3NlZClcblx0ICAgICAgQHR5cGUge2Jvb2xlYW59XG5cdCAgICAgIEBleGFtcGxlIGJ1dHRvbi5zdGF0ZSA9IHRydWU7XG5cdCAgICAgICovXG5cdFxuXHQgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuc3RhdGU7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG5cdCAgICAgICAgdGhpcy5fc3RhdGUuZmxpcCh2YWx1ZSk7XG5cdCAgICAgICAgaWYgKHRoaXMubW9kZSA9PT0gXCJhZnRlcnRvdWNoXCIpIHtcblx0ICAgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB7XG5cdCAgICAgICAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuXHQgICAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG5cdCAgICAgICAgICAgIHk6IHRoaXMucG9zaXRpb24ueSB9KTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMuc3RhdGUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgZmxpcDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIENoYW5nZSB0aGUgYnV0dG9uIHRvIGl0cyBhbHRlcm5hdGUgc3RhdGUgKG9mZj0+b24sIG9uPT5vZmYpLCBvciBmbGlwIGl0IHRvIGEgc3BlY2lmaWVkIHN0YXRlLlxuXHQgICAgICBAcGFyYW0gdmFsdWUge2Jvb2xlYW59IChPcHRpb25hbCkgU3RhdGUgdG8gZmxpcCB0by5cblx0ICAgICAgQGV4YW1wbGUgYnV0dG9uLmZsaXAoKTtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBmbGlwKHZhbHVlKSB7XG5cdCAgICAgICAgdGhpcy5fc3RhdGUuZmxpcCh2YWx1ZSk7XG5cdCAgICAgICAgaWYgKHRoaXMubW9kZSA9PT0gXCJhZnRlcnRvdWNoXCIpIHtcblx0ICAgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB7XG5cdCAgICAgICAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuXHQgICAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG5cdCAgICAgICAgICAgIHk6IHRoaXMucG9zaXRpb24ueSB9KTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMuc3RhdGUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdHVybk9uOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgVHVybiB0aGUgYnV0dG9uJ3Mgc3RhdGUgdG8gdHJ1ZS5cblx0ICAgICAgQGV4YW1wbGUgYnV0dG9uLnR1cm5PbigpO1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHR1cm5PbihlbWl0dGluZykge1xuXHQgICAgICAgIHRoaXMuX3N0YXRlLm9uKCk7XG5cdCAgICAgICAgaWYgKGVtaXR0aW5nICE9PSBmYWxzZSkge1xuXHQgICAgICAgICAgaWYgKHRoaXMubW9kZSA9PT0gXCJhZnRlcnRvdWNoXCIpIHtcblx0ICAgICAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHtcblx0ICAgICAgICAgICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcblx0ICAgICAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLngsXG5cdCAgICAgICAgICAgICAgeTogdGhpcy5wb3NpdGlvbi55IH0pO1xuXHQgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMuc3RhdGUpO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdHVybk9mZjoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFR1cm4gdGhlIGJ1dHRvbidzIHN0YXRlIHRvIGZhbHNlLlxuXHQgICAgICBAZXhhbXBsZSBidXR0b24udHVybk9mZigpO1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHR1cm5PZmYoZW1pdHRpbmcpIHtcblx0ICAgICAgICB0aGlzLl9zdGF0ZS5vZmYoKTtcblx0ICAgICAgICBpZiAoZW1pdHRpbmcgIT09IGZhbHNlKSB7XG5cdCAgICAgICAgICBpZiAodGhpcy5tb2RlID09PSBcImFmdGVydG91Y2hcIikge1xuXHQgICAgICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwge1xuXHQgICAgICAgICAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuXHQgICAgICAgICAgICAgIHg6IHRoaXMucG9zaXRpb24ueCxcblx0ICAgICAgICAgICAgICB5OiB0aGlzLnBvc2l0aW9uLnkgfSk7XG5cdCAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy5zdGF0ZSk7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIEJ1dHRvblRlbXBsYXRlO1xuXHR9KShJbnRlcmZhY2UpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBCdXR0b25UZW1wbGF0ZTtcblxuLyoqKi8gfSksXG4vKiAxOCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9nZXQgPSBmdW5jdGlvbiBnZXQob2JqZWN0LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpIHsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyByZXR1cm4gZ2V0KHBhcmVudCwgcHJvcGVydHksIHJlY2VpdmVyKTsgfSB9IGVsc2UgaWYgKFwidmFsdWVcIiBpbiBkZXNjICYmIGRlc2Mud3JpdGFibGUpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9O1xuXHRcblx0dmFyIF9pbmhlcml0cyA9IGZ1bmN0aW9uIChzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9O1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIEJ1dHRvblRlbXBsYXRlID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNyk7XG5cdFxuXHQvKipcblx0KiBUZXh0QnV0dG9uXG5cdCpcblx0KiBAZGVzY3JpcHRpb24gVGV4dCBidXR0b25cblx0KlxuXHQqIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwidGV4dEJ1dHRvblwiPjwvc3Bhbj5cblx0KlxuXHQqIEBleGFtcGxlXG5cdCogdmFyIHRleHRidXR0b24gPSBuZXcgTmV4dXMuVGV4dEJ1dHRvbignI3RhcmdldCcpXG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciB0ZXh0YnV0dG9uID0gbmV3IE5leHVzLlRleHRCdXR0b24oJyN0YXJnZXQnLHtcblx0KiAgICAgJ3NpemUnOiBbMTUwLDUwXSxcblx0KiAgICAgJ3N0YXRlJzogZmFsc2UsXG5cdCogICAgICd0ZXh0JzogJ1BsYXknLFxuXHQqICAgICAnYWx0ZXJuYXRlVGV4dCc6ICdTdG9wJ1xuXHQqIH0pXG5cdCpcblx0KiBAb3V0cHV0XG5cdCogY2hhbmdlXG5cdCogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cblx0KiBUaGUgZXZlbnQgZGF0YSBpcyBhIDxpPnN0cmluZzwvaT4gb2YgdGhlIHRleHQgb24gdGhlIGJ1dHRvbiBhdCB0aGUgbW9tZW50IGl0IHdhcyBjbGlja2VkLlxuXHQqXG5cdCogQG91dHB1dGV4YW1wbGVcblx0KiB0ZXh0YnV0dG9uLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcblx0KiAgIGNvbnNvbGUubG9nKHYpO1xuXHQqIH0pXG5cdCpcblx0Ki9cblx0XG5cdHZhciBUZXh0QnV0dG9uID0gKGZ1bmN0aW9uIChfQnV0dG9uVGVtcGxhdGUpIHtcblx0ICBmdW5jdGlvbiBUZXh0QnV0dG9uKCkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFRleHRCdXR0b24pO1xuXHRcblx0ICAgIHZhciBvcHRpb25zID0gW1widmFsdWVcIl07XG5cdFxuXHQgICAgdmFyIGRlZmF1bHRzID0ge1xuXHQgICAgICBzaXplOiBbMTUwLCA1MF0sXG5cdCAgICAgIHN0YXRlOiBmYWxzZSxcblx0ICAgICAgdGV4dDogXCJQbGF5XCJcblx0ICAgIH07XG5cdFxuXHQgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoVGV4dEJ1dHRvbi5wcm90b3R5cGUpLCBcImNvbnN0cnVjdG9yXCIsIHRoaXMpLmNhbGwodGhpcywgYXJndW1lbnRzLCBvcHRpb25zLCBkZWZhdWx0cyk7XG5cdFxuXHQgICAgdGhpcy5fdGV4dCA9IHRoaXMuc2V0dGluZ3MudGV4dDtcblx0XG5cdCAgICBpZiAodGhpcy5zZXR0aW5ncy5hbHRlcm5hdGUpIHtcblx0ICAgICAgLy9UT0RPOiBSZW1vdmUgdGhpcyBjb25kaXRpb25hbCBpbiBhIGJyZWFraW5nLWNoYW5nZXMgcmVsZWFzZVxuXHQgICAgICB0aGlzLnNldHRpbmdzLmFsdGVybmF0ZVRleHQgPSB0aGlzLnNldHRpbmdzLmFsdGVybmF0ZTtcblx0ICAgICAgY29uc29sZS53YXJuKFwiJ2FsdGVybmF0ZScgaW5pdGlhdG9yIGlzIGRlcHJlY2F0ZWQuIFVzZSAnYWx0ZXJuYXRlVGV4dCcgaW5zdGVhZC5cIik7XG5cdCAgICB9XG5cdCAgICB0aGlzLl9hbHRlcm5hdGVUZXh0ID0gdGhpcy5zZXR0aW5ncy5hbHRlcm5hdGVUZXh0O1xuXHQgICAgdGhpcy5tb2RlID0gdGhpcy5zZXR0aW5ncy5hbHRlcm5hdGVUZXh0ID8gXCJ0b2dnbGVcIiA6IFwiYnV0dG9uXCI7XG5cdCAgICB0aGlzLmluaXQoKTtcblx0ICAgIHRoaXMucmVuZGVyKCk7XG5cdFxuXHQgICAgdGhpcy5zdGF0ZSA9IHRoaXMuc2V0dGluZ3Muc3RhdGU7XG5cdCAgfVxuXHRcblx0ICBfaW5oZXJpdHMoVGV4dEJ1dHRvbiwgX0J1dHRvblRlbXBsYXRlKTtcblx0XG5cdCAgX2NyZWF0ZUNsYXNzKFRleHRCdXR0b24sIHtcblx0ICAgIGJ1aWxkRnJhbWU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkRnJhbWUoKSB7XG5cdFxuXHQgICAgICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cdCAgICAgICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcblx0XG5cdCAgICAgICAgdGhpcy50ZXh0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cdCAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl90ZXh0O1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnRleHRFbGVtZW50KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGJ1aWxkSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBidWlsZEludGVyZmFjZSgpIHt9XG5cdCAgICB9LFxuXHQgICAgY29sb3JJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbG9ySW50ZXJmYWNlKCkge1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG5cdCAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHNpemVJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNpemVJbnRlcmZhY2UoKSB7XG5cdCAgICAgICAgdmFyIHRleHRzaXplID0gdGhpcy5oZWlnaHQgLyAzO1xuXHQgICAgICAgIHZhciB0ZXh0c2l6ZTIgPSB0aGlzLndpZHRoIC8gKHRoaXMuX3RleHQubGVuZ3RoICsgMik7XG5cdCAgICAgICAgdGV4dHNpemUgPSBNYXRoLm1pbih0ZXh0c2l6ZSwgdGV4dHNpemUyKTtcblx0ICAgICAgICBpZiAodGhpcy5hbHRlcm5hdGVUZXh0KSB7XG5cdCAgICAgICAgICB2YXIgdGV4dHNpemUzID0gdGhpcy53aWR0aCAvICh0aGlzLmFsdGVybmF0ZVRleHQubGVuZ3RoICsgMik7XG5cdCAgICAgICAgICB0ZXh0c2l6ZSA9IE1hdGgubWluKHRleHRzaXplLCB0ZXh0c2l6ZTMpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB2YXIgc3R5bGVzID0gXCJ3aWR0aDogXCIgKyB0aGlzLndpZHRoICsgXCJweDtcIjtcblx0ICAgICAgICBzdHlsZXMgKz0gXCJoZWlnaHQ6IFwiICsgdGhpcy5oZWlnaHQgKyBcInB4O1wiO1xuXHQgICAgICAgIHN0eWxlcyArPSBcInBhZGRpbmc6IFwiICsgKHRoaXMuaGVpZ2h0IC0gdGV4dHNpemUpIC8gMiArIFwicHggMHB4O1wiO1xuXHQgICAgICAgIHN0eWxlcyArPSBcImJveC1zaXppbmc6IGJvcmRlci1ib3g7XCI7XG5cdCAgICAgICAgc3R5bGVzICs9IFwidGV4dC1hbGlnbjogY2VudGVyO1wiO1xuXHQgICAgICAgIHN0eWxlcyArPSBcImZvbnQtZmFtaWx5OiBpbmhlcml0O1wiO1xuXHQgICAgICAgIHN0eWxlcyArPSBcImZvbnQtd2VpZ2h0OiA3MDA7XCI7XG5cdCAgICAgICAgc3R5bGVzICs9IFwib3BhY2l0eTogMTtcIjtcblx0ICAgICAgICBzdHlsZXMgKz0gXCJmb250LXNpemU6XCIgKyB0ZXh0c2l6ZSArIFwicHg7XCI7XG5cdCAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5zdHlsZS5jc3NUZXh0ID0gc3R5bGVzO1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByZW5kZXI6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcblx0ICAgICAgICBpZiAoIXRoaXMuc3RhdGUpIHtcblx0ICAgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5maWxsO1xuXHQgICAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG5cdCAgICAgICAgICB0aGlzLnRleHRFbGVtZW50LmlubmVySFRNTCA9IHRoaXMuX3RleHQ7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG5cdCAgICAgICAgICB0aGlzLnRleHRFbGVtZW50LnN0eWxlLmNvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcblx0ICAgICAgICAgIGlmICh0aGlzLmFsdGVybmF0ZVRleHQpIHtcblx0ICAgICAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl9hbHRlcm5hdGVUZXh0O1xuXHQgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl90ZXh0O1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGFsdGVybmF0ZVRleHQ6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBUaGUgdGV4dCB0byBkaXNwbGF5IHdoZW4gdGhlIGJ1dHRvbiBpcyBpbiBpdHMgXCJvblwiIHN0YXRlLiBJZiBzZXQsIHRoaXMgcHV0cyB0aGUgYnV0dG9uIGluIFwidG9nZ2xlXCIgbW9kZS5cblx0ICAgICAgQHR5cGUge1N0cmluZ31cblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9hbHRlcm5hdGVUZXh0O1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh0ZXh0KSB7XG5cdCAgICAgICAgaWYgKHRleHQpIHtcblx0ICAgICAgICAgIHRoaXMubW9kZSA9IFwidG9nZ2xlXCI7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMubW9kZSA9IFwiYnV0dG9uXCI7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuX2FsdGVybmF0ZVRleHQgPSB0ZXh0O1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICB0ZXh0OiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgVGhlIHRleHQgdG8gZGlzcGxheS4gKElmIC5hbHRlcm5hdGVUZXh0IGV4aXN0cywgdGhlbiB0aGlzIC50ZXh0IHdpbGwgb25seSBiZSBkaXNwbGF5ZWQgd2hlbiB0aGUgYnV0dG9uIGlzIGluIGl0cyBcIm9mZlwiIHN0YXRlLilcblx0ICAgICAgQHR5cGUge1N0cmluZ31cblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl90ZXh0O1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh0ZXh0KSB7XG5cdCAgICAgICAgdGhpcy5fdGV4dCA9IHRleHQ7XG5cdCAgICAgICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG5cdCAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pO1xuXHRcblx0ICByZXR1cm4gVGV4dEJ1dHRvbjtcblx0fSkoQnV0dG9uVGVtcGxhdGUpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBUZXh0QnV0dG9uO1xuXG4vKioqLyB9KSxcbi8qIDE5ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgX2NyZWF0ZUNsYXNzID0gKGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGtleSBpbiBwcm9wcykgeyB2YXIgcHJvcCA9IHByb3BzW2tleV07IHByb3AuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKHByb3AudmFsdWUpIHByb3Aud3JpdGFibGUgPSB0cnVlOyB9IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpOyB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cdFxuXHR2YXIgX2dldCA9IGZ1bmN0aW9uIGdldChvYmplY3QsIHByb3BlcnR5LCByZWNlaXZlcikgeyB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBwcm9wZXJ0eSk7IGlmIChkZXNjID09PSB1bmRlZmluZWQpIHsgdmFyIHBhcmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpOyBpZiAocGFyZW50ID09PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gZWxzZSB7IHJldHVybiBnZXQocGFyZW50LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpOyB9IH0gZWxzZSBpZiAoXCJ2YWx1ZVwiIGluIGRlc2MgJiYgZGVzYy53cml0YWJsZSkgeyByZXR1cm4gZGVzYy52YWx1ZTsgfSBlbHNlIHsgdmFyIGdldHRlciA9IGRlc2MuZ2V0OyBpZiAoZ2V0dGVyID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpOyB9IH07XG5cdFxuXHR2YXIgX2luaGVyaXRzID0gZnVuY3Rpb24gKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgXCIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH07XG5cdFxuXHR2YXIgX2NsYXNzQ2FsbENoZWNrID0gZnVuY3Rpb24gKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH07XG5cdFxuXHQvL2xldCBzdmcgPSByZXF1aXJlKCcuLi91dGlsL3N2ZycpO1xuXHR2YXIgSW50ZXJmYWNlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2KTtcblx0dmFyIEJ1dHRvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMTYpO1xuXHRcblx0LyoqXG5cdCogUmFkaW9CdXR0b25cblx0KlxuXHQqIEBkZXNjcmlwdGlvbiBBbiBhcnJheSBvZiBidXR0b25zLiBCeSBkZWZhdWx0LCBzZWxlY3Rpbmcgb25lIGJ1dHRvbiB3aWxsIGRlc2VsZWN0IGFsbCBvdGhlciBidXR0b25zLCBidXQgdGhpcyBjYW4gYmUgY3VzdG9taXplZCB1c2luZyB0aGUgQVBJIGJlbG93LlxuXHQqXG5cdCogQGRlbW8gPGRpdiBuZXh1cy11aT1cIlJhZGlvQnV0dG9uXCI+PC9kaXY+XG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciByYWRpb2J1dHRvbiA9IG5ldyBOZXh1cy5SYWRpb0J1dHRvbignI3RhcmdldCcpXG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciByYWRpb2J1dHRvbiA9IG5ldyBOZXh1cy5SYWRpb0J1dHRvbignI3RhcmdldCcse1xuXHQqICAgJ3NpemUnOiBbMTIwLDI1XSxcblx0KiAgICdudW1iZXJPZkJ1dHRvbnMnOiA0LFxuXHQqICAgJ2FjdGl2ZSc6IC0xXG5cdCogfSlcblx0KlxuXHQqIEBvdXRwdXRcblx0KiBjaGFuZ2Vcblx0KiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuXHQqIFRoZSBldmVudCBkYXRhIGFuIDxpPmludGVnZXI8L2k+LCB0aGUgaW5kZXggb2YgdGhlIGJ1dHRvbiB0aGF0IGlzIGN1cnJlbnRseSBvbi4gSWYgbm8gYnV0dG9uIGlzIHNlbGVjdGVkLCB0aGUgdmFsdWUgd2lsbCBiZSAtMS5cblx0KlxuXHQqIEBvdXRwdXRleGFtcGxlXG5cdCogcmFkaW9idXR0b24ub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuXHQqICAgY29uc29sZS5sb2codik7XG5cdCogfSlcblx0KlxuXHQqL1xuXHRcblx0dmFyIFJhZGlvQnV0dG9uID0gKGZ1bmN0aW9uIChfSW50ZXJmYWNlKSB7XG5cdCAgZnVuY3Rpb24gUmFkaW9CdXR0b24oKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUmFkaW9CdXR0b24pO1xuXHRcblx0ICAgIHZhciBvcHRpb25zID0gW1widmFsdWVcIl07XG5cdFxuXHQgICAgdmFyIGRlZmF1bHRzID0ge1xuXHQgICAgICBzaXplOiBbMTIwLCAyNV0sXG5cdCAgICAgIG51bWJlck9mQnV0dG9uczogNCxcblx0ICAgICAgYWN0aXZlOiAtMVxuXHQgICAgfTtcblx0XG5cdCAgICBfZ2V0KE9iamVjdC5nZXRQcm90b3R5cGVPZihSYWRpb0J1dHRvbi5wcm90b3R5cGUpLCBcImNvbnN0cnVjdG9yXCIsIHRoaXMpLmNhbGwodGhpcywgYXJndW1lbnRzLCBvcHRpb25zLCBkZWZhdWx0cyk7XG5cdFxuXHQgICAgdGhpcy5idXR0b25zID0gW107XG5cdCAgICB0aGlzLl9udW1iZXJPZkJ1dHRvbnMgPSB0aGlzLnNldHRpbmdzLm51bWJlck9mQnV0dG9ucztcblx0ICAgIHRoaXMuYWN0aXZlID0gdGhpcy5zZXR0aW5ncy5hY3RpdmU7XG5cdFxuXHQgICAgdGhpcy5pbml0KCk7XG5cdCAgICB0aGlzLnJlbmRlcigpO1xuXHQgIH1cblx0XG5cdCAgX2luaGVyaXRzKFJhZGlvQnV0dG9uLCBfSW50ZXJmYWNlKTtcblx0XG5cdCAgX2NyZWF0ZUNsYXNzKFJhZGlvQnV0dG9uLCB7XG5cdCAgICBidWlsZEZyYW1lOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBidWlsZEZyYW1lKCkge1xuXHQgICAgICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cdCAgICAgICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGJ1aWxkSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBidWlsZEludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLl9udW1iZXJPZkJ1dHRvbnM7IGkrKykge1xuXHQgICAgICAgICAgdmFyIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuXHRcblx0ICAgICAgICAgIHZhciBidXR0b24gPSBuZXcgQnV0dG9uKGNvbnRhaW5lciwge1xuXHQgICAgICAgICAgICBtb2RlOiBcInRvZ2dsZVwiLFxuXHQgICAgICAgICAgICBjb21wb25lbnQ6IHRydWUgfSwgdGhpcy51cGRhdGUuYmluZCh0aGlzLCBpKSk7XG5cdFxuXHQgICAgICAgICAgdGhpcy5idXR0b25zLnB1c2goYnV0dG9uKTtcblx0ICAgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHNpemVJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNpemVJbnRlcmZhY2UoKSB7XG5cdFxuXHQgICAgICAgIHZhciBidXR0b25XaWR0aCA9IHRoaXMud2lkdGggLyB0aGlzLl9udW1iZXJPZkJ1dHRvbnM7XG5cdCAgICAgICAgdmFyIGJ1dHRvbkhlaWdodCA9IHRoaXMuaGVpZ2h0O1xuXHRcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX251bWJlck9mQnV0dG9uczsgaSsrKSB7XG5cdCAgICAgICAgICB0aGlzLmJ1dHRvbnNbaV0ucmVzaXplKGJ1dHRvbldpZHRoLCBidXR0b25IZWlnaHQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNvbG9ySW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb2xvckludGVyZmFjZSgpIHtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX251bWJlck9mQnV0dG9uczsgaSsrKSB7XG5cdCAgICAgICAgICB0aGlzLmJ1dHRvbnNbaV0uY29sb3JzID0gdGhpcy5jb2xvcnM7XG5cdCAgICAgICAgICB0aGlzLmJ1dHRvbnNbaV0ucmVuZGVyKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdXBkYXRlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiB1cGRhdGUoaW5kZXgpIHtcblx0ICAgICAgICBpZiAodGhpcy5idXR0b25zW2luZGV4XS5zdGF0ZSkge1xuXHQgICAgICAgICAgdGhpcy5zZWxlY3QoaW5kZXgpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aGlzLmRlc2VsZWN0KCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcmVuZGVyOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJ1dHRvbnMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgIGlmIChpID09PSB0aGlzLmFjdGl2ZSkge1xuXHQgICAgICAgICAgICB0aGlzLmJ1dHRvbnNbaV0udHVybk9uKGZhbHNlKTtcblx0ICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRoaXMuYnV0dG9uc1tpXS50dXJuT2ZmKGZhbHNlKTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzZWxlY3Q6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBTZWxlY3Qgb25lIGJ1dHRvbiBhbmQgZGVzZWxlY3QgYWxsIG90aGVyIGJ1dHRvbnMuXG5cdCAgICAgIEBwYXJhbSBpbmRleCB7bnVtYmVyfSBUaGUgaW5kZXggb2YgdGhlIGJ1dHRvbiB0byBzZWxlY3Rcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZWxlY3QoaW5kZXgpIHtcblx0ICAgICAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IHRoaXMuYnV0dG9ucy5sZW5ndGgpIHtcblx0ICAgICAgICAgIHRoaXMuYWN0aXZlID0gaW5kZXg7XG5cdCAgICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy5hY3RpdmUpO1xuXHQgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBkZXNlbGVjdDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIERlc2VsZWN0IGFsbCBidXR0b25zLlxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRlc2VsZWN0KCkge1xuXHQgICAgICAgIHRoaXMuYWN0aXZlID0gLTE7XG5cdCAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMuYWN0aXZlKTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbnVtYmVyT2ZCdXR0b25zOiB7XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9udW1iZXJPZkJ1dHRvbnM7XG5cdCAgICAgIH0sXG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgICogVXBkYXRlIGhvdyBtYW55IGJ1dHRvbnMgYXJlIGluIHRoZSBpbnRlcmZhY2Vcblx0ICAgICAgICogQHBhcmFtICB7bnVtYmVyfSBidXR0b25zIEhvdyBtYW55IGJ1dHRvbnMgYXJlIGluIHRoZSBpbnRlcmZhY2Vcblx0ICAgICAgICovXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKGJ1dHRvbnMpIHtcblx0ICAgICAgICB0aGlzLl9udW1iZXJPZkJ1dHRvbnMgPSBidXR0b25zO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5idXR0b25zLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICB0aGlzLmJ1dHRvbnNbaV0uZGVzdHJveSgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLmJ1dHRvbnMgPSBbXTtcblx0ICAgICAgICAvLyAgZm9yIChsZXQgaT0wO2k8dGhpcy5idXR0b25zLmxlbmd0aDtpKyspIHtcblx0ICAgICAgICAvLyAgICB0aGlzLmJ1dHRvbnNbaV0uZGVzdHJveSgpO1xuXHQgICAgICAgIC8vICB9XG5cdCAgICAgICAgdGhpcy5lbXB0eSgpO1xuXHQgICAgICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pO1xuXHRcblx0ICByZXR1cm4gUmFkaW9CdXR0b247XG5cdH0pKEludGVyZmFjZSk7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IFJhZGlvQnV0dG9uO1xuXG4vKioqLyB9KSxcbi8qIDIwICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgX2NyZWF0ZUNsYXNzID0gKGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGtleSBpbiBwcm9wcykgeyB2YXIgcHJvcCA9IHByb3BzW2tleV07IHByb3AuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKHByb3AudmFsdWUpIHByb3Aud3JpdGFibGUgPSB0cnVlOyB9IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpOyB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cdFxuXHR2YXIgX2dldCA9IGZ1bmN0aW9uIGdldChvYmplY3QsIHByb3BlcnR5LCByZWNlaXZlcikgeyB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBwcm9wZXJ0eSk7IGlmIChkZXNjID09PSB1bmRlZmluZWQpIHsgdmFyIHBhcmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpOyBpZiAocGFyZW50ID09PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gZWxzZSB7IHJldHVybiBnZXQocGFyZW50LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpOyB9IH0gZWxzZSBpZiAoXCJ2YWx1ZVwiIGluIGRlc2MgJiYgZGVzYy53cml0YWJsZSkgeyByZXR1cm4gZGVzYy52YWx1ZTsgfSBlbHNlIHsgdmFyIGdldHRlciA9IGRlc2MuZ2V0OyBpZiAoZ2V0dGVyID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpOyB9IH07XG5cdFxuXHR2YXIgX2luaGVyaXRzID0gZnVuY3Rpb24gKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgXCIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH07XG5cdFxuXHR2YXIgX2NsYXNzQ2FsbENoZWNrID0gZnVuY3Rpb24gKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH07XG5cdFxuXHR2YXIgSW50ZXJmYWNlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2KTtcblx0dmFyIFN0ZXAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDExKTtcblx0dmFyIG1hdGggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpO1xuXHRcblx0LyoqXG5cdCogTnVtYmVyXG5cdCpcblx0KiBAZGVzY3JpcHRpb24gTnVtYmVyIGludGVyZmFjZSB3aGljaCBpcyBjb250cm9sbGFibGUgYnkgZHJhZ2dpbmcgb3IgdHlwaW5nLlxuXHQqXG5cdCogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJudW1iZXJcIj48L3NwYW4+XG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciBudW1iZXIgPSBuZXcgTmV4dXMuTnVtYmVyKCcjdGFyZ2V0Jylcblx0KlxuXHQqIEBleGFtcGxlXG5cdCogdmFyIG51bWJlciA9IG5ldyBOZXh1cy5OdW1iZXIoJyN0YXJnZXQnLHtcblx0KiAgICdzaXplJzogWzYwLDMwXSxcblx0KiAgICd2YWx1ZSc6IDAsXG5cdCogICAnbWluJzogMCxcblx0KiAgICdtYXgnOiAyMDAwMCxcblx0KiAgICdzdGVwJzogMVxuXHQqIH0pXG5cdCpcblx0KiBAb3V0cHV0XG5cdCogY2hhbmdlXG5cdCogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cblx0KiBUaGUgZXZlbnQgZGF0YSBpcyB0aGUgbnVtYmVyIHZhbHVlIG9mIHRoZSBpbnRlcmZhY2UuXG5cdCpcblx0KiBAb3V0cHV0ZXhhbXBsZVxuXHQqIG51bWJlci5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG5cdCogICBjb25zb2xlLmxvZyh2KTtcblx0KiB9KVxuXHQqXG5cdCpcblx0Ki9cblx0XG5cdHZhciBOdW1iZXIgPSAoZnVuY3Rpb24gKF9JbnRlcmZhY2UpIHtcblx0ICBmdW5jdGlvbiBOdW1iZXIoKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTnVtYmVyKTtcblx0XG5cdCAgICB2YXIgb3B0aW9ucyA9IFtcInZhbHVlXCJdO1xuXHRcblx0ICAgIHZhciBkZWZhdWx0cyA9IHtcblx0ICAgICAgc2l6ZTogWzYwLCAzMF0sXG5cdCAgICAgIHZhbHVlOiAwLFxuXHQgICAgICBtaW46IDAsXG5cdCAgICAgIG1heDogMjAwMDAsXG5cdCAgICAgIHN0ZXA6IDFcblx0ICAgIH07XG5cdFxuXHQgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoTnVtYmVyLnByb3RvdHlwZSksIFwiY29uc3RydWN0b3JcIiwgdGhpcykuY2FsbCh0aGlzLCBhcmd1bWVudHMsIG9wdGlvbnMsIGRlZmF1bHRzKTtcblx0XG5cdCAgICB0aGlzLl92YWx1ZSA9IG5ldyBTdGVwKHRoaXMuc2V0dGluZ3MubWluLCB0aGlzLnNldHRpbmdzLm1heCwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblx0XG5cdCAgICAvKlxuXHQgICAgRGVmYXVsdDogMi4gSG93IG1hbnkgZGVjaW1hbCBwbGFjZXMgdG8gY2xpcCB0aGUgbnVtYmVyJ3MgdmlzdWFsIHJlbmRlcmluZyB0by4gVGhpcyBkb2VzIG5vdCBhZmZlY3QgbnVtYmVyJ3MgYWN0dWFsIHZhbHVlIG91dHB1dCAtLSBmb3IgdGhhdCwgc2V0IHRoZSBzdGVwIHByb3BlcnR5IHRvIC4wMSwgLjEsIG9yIDEuXG5cdCAgICBAdHlwZSB7bnVtYmVyfVxuXHQgICAgQGV4YW1wbGUgbnVtYmVyLmRlY2ltYWxQbGFjZXMgPSAyO1xuXHQgICAgKi9cblx0ICAgIHRoaXMuZGVjaW1hbFBsYWNlcyA9IDI7XG5cdCAgICB0aGlzLmFjdHVhbCA9IDA7XG5cdFxuXHQgICAgdGhpcy5tYXggPSB0aGlzLl92YWx1ZS5tYXg7XG5cdFxuXHQgICAgdGhpcy5taW4gPSB0aGlzLl92YWx1ZS5taW47XG5cdFxuXHQgICAgdGhpcy5zdGVwID0gdGhpcy5fdmFsdWUuc3RlcDtcblx0XG5cdCAgICB0aGlzLmluaXQoKTtcblx0ICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgfVxuXHRcblx0ICBfaW5oZXJpdHMoTnVtYmVyLCBfSW50ZXJmYWNlKTtcblx0XG5cdCAgX2NyZWF0ZUNsYXNzKE51bWJlciwge1xuXHQgICAgYnVpbGRGcmFtZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gYnVpbGRGcmFtZSgpIHtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LnR5cGUgPSBcInRleHRcIjtcblx0XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsIChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcblx0ICAgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG5cdCAgICAgICAgICBpZiAodGhpcy5lbGVtZW50LnZhbHVlICE9PSB0aGlzLnZhbHVlKSB7XG5cdCAgICAgICAgICAgIHRoaXMudmFsdWUgPSBwYXJzZUZsb2F0KHRoaXMuZWxlbWVudC52YWx1ZSk7XG5cdCAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfSkuYmluZCh0aGlzKSk7XG5cdFxuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLCAoZnVuY3Rpb24gKGUpIHtcblx0ICAgICAgICAgIGlmIChlLndoaWNoIDwgNDggfHwgZS53aGljaCA+IDU3KSB7XG5cdCAgICAgICAgICAgIGlmIChlLndoaWNoICE9PSAxODkgJiYgZS53aGljaCAhPT0gMTkwICYmIGUud2hpY2ggIT09IDgpIHtcblx0ICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgIH1cblx0ICAgICAgICAgIGlmIChlLndoaWNoID09PSAxMykge1xuXHQgICAgICAgICAgICB0aGlzLmVsZW1lbnQuYmx1cigpO1xuXHQgICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5lbGVtZW50LnZhbHVlO1xuXHQgICAgICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy52YWx1ZSk7XG5cdCAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfSkuYmluZCh0aGlzKSk7XG5cdFxuXHQgICAgICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzaXplSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBzaXplSW50ZXJmYWNlKCkge1xuXHRcblx0ICAgICAgICB0aGlzLl9taW5EaW1lbnNpb24gPSBNYXRoLm1pbih0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XG5cdFxuXHQgICAgICAgIHZhciBzdHlsZXMgPSBcIndpZHRoOiBcIiArIHRoaXMud2lkdGggKyBcInB4O1wiO1xuXHQgICAgICAgIHN0eWxlcyArPSBcImhlaWdodDogXCIgKyB0aGlzLmhlaWdodCArIFwicHg7XCI7XG5cdCAgICAgICAgc3R5bGVzICs9IFwiYmFja2dyb3VuZC1jb2xvcjogI2U3ZTdlNztcIjtcblx0ICAgICAgICBzdHlsZXMgKz0gXCJjb2xvcjogIzMzMztcIjtcblx0ICAgICAgICBzdHlsZXMgKz0gXCJmb250LWZhbWlseTogYXJpYWw7XCI7XG5cdCAgICAgICAgc3R5bGVzICs9IFwiZm9udC13ZWlnaHQ6IDUwMDtcIjtcblx0ICAgICAgICBzdHlsZXMgKz0gXCJmb250LXNpemU6XCIgKyB0aGlzLl9taW5EaW1lbnNpb24gLyAyICsgXCJweDtcIjtcblx0ICAgICAgICAvLyAgc3R5bGVzICs9ICdoaWdobGlnaHQ6ICNkMTg7Jztcblx0ICAgICAgICBzdHlsZXMgKz0gXCJib3JkZXI6IG5vbmU7XCI7XG5cdCAgICAgICAgc3R5bGVzICs9IFwib3V0bGluZTogbm9uZTtcIjtcblx0ICAgICAgICBzdHlsZXMgKz0gXCJwYWRkaW5nOiBcIiArIHRoaXMuX21pbkRpbWVuc2lvbiAvIDQgKyBcInB4IFwiICsgdGhpcy5fbWluRGltZW5zaW9uIC8gNCArIFwicHg7XCI7XG5cdCAgICAgICAgc3R5bGVzICs9IFwiYm94LXNpemluZzogYm9yZGVyLWJveDtcIjtcblx0ICAgICAgICBzdHlsZXMgKz0gXCJ1c2VyU2VsZWN0OiB0ZXh0O1wiO1xuXHQgICAgICAgIHN0eWxlcyArPSBcIm1velVzZXJTZWxlY3Q6IHRleHQ7XCI7XG5cdCAgICAgICAgc3R5bGVzICs9IFwid2Via2l0VXNlclNlbGVjdDogdGV4dDtcIjtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY3NzVGV4dCArPSBzdHlsZXM7XG5cdFxuXHQgICAgICAgIC8vIHRvIGFkZCBldmVudHVhbGx5XG5cdCAgICAgICAgLy8gdmFyIGNzcyA9ICcjJyt0aGlzLmVsZW1lbnRJRCsnOjpzZWxlY3Rpb257IGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50IH0nO1xuXHRcblx0ICAgICAgICB0aGlzLmVsZW1lbnQudmFsdWUgPSB0aGlzLnZhbHVlO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY29sb3JJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbG9ySW50ZXJmYWNlKCkge1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5maWxsO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5jb2xvciA9IHRoaXMuY29sb3JzLmRhcms7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByZW5kZXI6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcblx0XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LnZhbHVlID0gbWF0aC5wcnVuZSh0aGlzLnZhbHVlLCB0aGlzLmRlY2ltYWxQbGFjZXMpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY2xpY2s6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNsaWNrKCkge1xuXHQgICAgICAgIHRoaXMuaGFzTW92ZWQgPSBmYWxzZTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQucmVhZE9ubHkgPSB0cnVlO1xuXHQgICAgICAgIHRoaXMuYWN0dWFsID0gdGhpcy52YWx1ZTtcblx0ICAgICAgICB0aGlzLmluaXRpYWwgPSB7IHk6IHRoaXMubW91c2UueSB9O1xuXHQgICAgICAgIHRoaXMuY2hhbmdlRmFjdG9yID0gbWF0aC5pbnZlcnQodGhpcy5tb3VzZS54IC8gdGhpcy53aWR0aCk7XG5cdCAgICAgICAgY29uc29sZS5sb2codGhpcy5jaGFuZ2VGYWN0b3IpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbW92ZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gbW92ZSgpIHtcblx0ICAgICAgICB0aGlzLmhhc01vdmVkID0gdHJ1ZTtcblx0ICAgICAgICBpZiAodGhpcy5jbGlja2VkKSB7XG5cdFxuXHQgICAgICAgICAgdmFyIG5ld3ZhbHVlID0gdGhpcy5hY3R1YWwgLSAodGhpcy5tb3VzZS55IC0gdGhpcy5pbml0aWFsLnkpICogKG1hdGguY2xpcCh0aGlzLm1heCAtIHRoaXMubWluLCAwLCAxMDAwKSAvIDIwMCkgKiBNYXRoLnBvdyh0aGlzLmNoYW5nZUZhY3RvciwgMik7XG5cdCAgICAgICAgICB0aGlzLnZhbHVlID0gbmV3dmFsdWU7XG5cdFxuXHQgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgICAgIGlmICh0aGlzLl92YWx1ZS5jaGFuZ2VkKSB7XG5cdCAgICAgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB0aGlzLnZhbHVlKTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByZWxlYXNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZWxlYXNlKCkge1xuXHQgICAgICAgIGlmICghdGhpcy5oYXNNb3ZlZCkge1xuXHQgICAgICAgICAgdGhpcy5lbGVtZW50LnJlYWRPbmx5ID0gZmFsc2U7XG5cdCAgICAgICAgICB0aGlzLmVsZW1lbnQuZm9jdXMoKTtcblx0ICAgICAgICAgIHRoaXMuZWxlbWVudC5zZXRTZWxlY3Rpb25SYW5nZSgwLCB0aGlzLmVsZW1lbnQudmFsdWUubGVuZ3RoKTtcblx0ICAgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG5cdCAgICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY29sb3IgPSB0aGlzLmNvbG9ycy5saWdodDtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgZG9jdW1lbnQuYm9keS5mb2N1cygpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGxpbms6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBDb25uZWN0IHRoaXMgbnVtYmVyIGludGVyZmFjZSB0byBhIGRpYWwgb3Igc2xpZGVyXG5cdCAgICAgIEBwYXJhbSB7SW50ZXJmYWNlfSBlbGVtZW50IEVsZW1lbnQgdG8gY29ubmVjdCB0by5cblx0ICAgICAgQGV4YW1wbGUgbnVtYmVyLmxpbmsoc2xpZGVyKVxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGxpbmsoZGVzdGluYXRpb24pIHtcblx0ICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICAgICB0aGlzLm1pbiA9IGRlc3RpbmF0aW9uLm1pbjtcblx0ICAgICAgICB0aGlzLm1heCA9IGRlc3RpbmF0aW9uLm1heDtcblx0ICAgICAgICB0aGlzLnN0ZXAgPSBkZXN0aW5hdGlvbi5zdGVwO1xuXHQgICAgICAgIGRlc3RpbmF0aW9uLm9uKFwiY2hhbmdlXCIsIGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgICBfdGhpcy5wYXNzaXZlVXBkYXRlKHYpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRoaXMub24oXCJjaGFuZ2VcIiwgZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICAgIGRlc3RpbmF0aW9uLnZhbHVlID0gdjtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0aGlzLnZhbHVlID0gZGVzdGluYXRpb24udmFsdWU7XG5cdCAgICAgICAgLyogIHJldHVybiB7XG5cdCAgICAgICAgICAgIGxpc3RlbmVyMTogbGlzdGVuZXIxLFxuXHQgICAgICAgICAgICBsaXN0ZW5lcjI6IGxpc3RlbmVyMixcblx0ICAgICAgICAgICAgZGVzdHJveTogKCkgPT4ge1xuXHQgICAgICAgICAgICAgIGxpc3RlbmVyMS5yZW1vdmUoKSAob3Igc2ltaWxhcilcblx0ICAgICAgICAgICAgICBsaXN0ZW5lcjIucmVtb3ZlKCkgKG9yIHNpbWlsYXIpXG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgIH0gKi9cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHBhc3NpdmVVcGRhdGU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHBhc3NpdmVVcGRhdGUodikge1xuXHQgICAgICAgIHRoaXMuX3ZhbHVlLnVwZGF0ZSh2KTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdmFsdWU6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBUaGUgaW50ZXJmYWNlJ3MgY3VycmVudCB2YWx1ZS4gSWYgc2V0IG1hbnVhbGx5LCB3aWxsIHVwZGF0ZSB0aGUgaW50ZXJmYWNlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG5cdCAgICAgIEB0eXBlIHtudW1iZXJ9XG5cdCAgICAgIEBleGFtcGxlIG51bWJlci52YWx1ZSA9IDEwO1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdGhpcy5fdmFsdWUudXBkYXRlKHYpO1xuXHQgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB0aGlzLnZhbHVlKTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbWluOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgTG93ZXIgbGltaXQgb2YgdGhlIG51bWJlcidzIG91dHB1dCByYW5nZVxuXHQgICAgICBAdHlwZSB7bnVtYmVyfVxuXHQgICAgICBAZXhhbXBsZSBudW1iZXIubWluID0gMTAwMDtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5taW47XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLl92YWx1ZS5taW4gPSB2O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbWF4OiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgVXBwZXIgbGltaXQgb2YgdGhlIG51bWJlcidzIG91dHB1dCByYW5nZVxuXHQgICAgICBAdHlwZSB7bnVtYmVyfVxuXHQgICAgICBAZXhhbXBsZSBudW1iZXIubWF4ID0gMTAwMDtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5tYXg7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLl92YWx1ZS5tYXggPSB2O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc3RlcDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFRoZSBpbmNyZW1lbnQgdGhhdCB0aGUgbnVtYmVyJ3MgdmFsdWUgY2hhbmdlcyBieS5cblx0ICAgICAgQHR5cGUge251bWJlcn1cblx0ICAgICAgQGV4YW1wbGUgbnVtYmVyLnN0ZXAgPSA1O1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnN0ZXA7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLl92YWx1ZS5zdGVwID0gdjtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pO1xuXHRcblx0ICByZXR1cm4gTnVtYmVyO1xuXHR9KShJbnRlcmZhY2UpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBOdW1iZXI7XG5cbi8qKiovIH0pLFxuLyogMjEgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KG9iamVjdCwgcHJvcGVydHksIHJlY2VpdmVyKSB7IHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHByb3BlcnR5KTsgaWYgKGRlc2MgPT09IHVuZGVmaW5lZCkgeyB2YXIgcGFyZW50ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCk7IGlmIChwYXJlbnQgPT09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBlbHNlIHsgcmV0dXJuIGdldChwYXJlbnQsIHByb3BlcnR5LCByZWNlaXZlcik7IH0gfSBlbHNlIGlmIChcInZhbHVlXCIgaW4gZGVzYyAmJiBkZXNjLndyaXRhYmxlKSB7IHJldHVybiBkZXNjLnZhbHVlOyB9IGVsc2UgeyB2YXIgZ2V0dGVyID0gZGVzYy5nZXQ7IGlmIChnZXR0ZXIgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IHJldHVybiBnZXR0ZXIuY2FsbChyZWNlaXZlcik7IH0gfTtcblx0XG5cdHZhciBfaW5oZXJpdHMgPSBmdW5jdGlvbiAoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSBcImZ1bmN0aW9uXCIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCBcIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdHZhciBJbnRlcmZhY2UgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpO1xuXHRcblx0LyoqXG5cdCogU2VsZWN0XG5cdCpcblx0KiBAZGVzY3JpcHRpb24gRHJvcGRvd24gbWVudVxuXHQqXG5cdCogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJzZWxlY3RcIj48L3NwYW4+XG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciBzZWxlY3QgPSBuZXcgTmV4dXMuU2VsZWN0KCcjdGFyZ2V0Jylcblx0KlxuXHQqIEBleGFtcGxlXG5cdCogdmFyIHNlbGVjdCA9IG5ldyBOZXh1cy5TZWxlY3QoJyN0YXJnZXQnLHtcblx0KiAgICdzaXplJzogWzEwMCwzMF0sXG5cdCogICAnb3B0aW9ucyc6IFsnZGVmYXVsdCcsJ29wdGlvbnMnXVxuXHQqIH0pXG5cdCpcblx0KiBAb3V0cHV0XG5cdCogY2hhbmdlXG5cdCogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIHZhbHVlIGNoYW5nZXMuIDxicj5cblx0KiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgdGV4dCB2YWx1ZSBvZiB0aGUgc2VsZWN0ZWQgb3B0aW9uLCBhcyB3ZWxsIGFzIHRoZSBudW1lcmljIGluZGV4IG9mIHRoZSBzZWxlY3Rpb24uXG5cdCpcblx0KiBAb3V0cHV0ZXhhbXBsZVxuXHQqIHNlbGVjdC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG5cdCogICBjb25zb2xlLmxvZyh2KTtcblx0KiB9KVxuXHQqXG5cdCpcblx0Ki9cblx0XG5cdHZhciBTZWxlY3QgPSAoZnVuY3Rpb24gKF9JbnRlcmZhY2UpIHtcblx0ICBmdW5jdGlvbiBTZWxlY3QoKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgU2VsZWN0KTtcblx0XG5cdCAgICB2YXIgb3B0aW9ucyA9IFtcInZhbHVlXCJdO1xuXHRcblx0ICAgIHZhciBkZWZhdWx0cyA9IHtcblx0ICAgICAgc2l6ZTogWzEwMCwgMzBdLFxuXHQgICAgICBvcHRpb25zOiBbXCJkZWZhdWx0XCIsIFwib3B0aW9uc1wiXVxuXHQgICAgfTtcblx0XG5cdCAgICBfZ2V0KE9iamVjdC5nZXRQcm90b3R5cGVPZihTZWxlY3QucHJvdG90eXBlKSwgXCJjb25zdHJ1Y3RvclwiLCB0aGlzKS5jYWxsKHRoaXMsIGFyZ3VtZW50cywgb3B0aW9ucywgZGVmYXVsdHMpO1xuXHRcblx0ICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSAtMTtcblx0ICAgIHRoaXMuX3ZhbHVlID0gZmFsc2U7XG5cdFxuXHQgICAgdGhpcy5fb3B0aW9ucyA9IHRoaXMuc2V0dGluZ3Mub3B0aW9ucztcblx0XG5cdCAgICB0aGlzLmluaXQoKTtcblx0ICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgfVxuXHRcblx0ICBfaW5oZXJpdHMoU2VsZWN0LCBfSW50ZXJmYWNlKTtcblx0XG5cdCAgX2NyZWF0ZUNsYXNzKFNlbGVjdCwge1xuXHQgICAgYnVpbGRGcmFtZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gYnVpbGRGcmFtZSgpIHtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2VsZWN0XCIpO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5mb250U2l6ZSA9IHRoaXMuaGVpZ2h0IC8gMiArIFwicHhcIjtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUub3V0bGluZSA9IFwibm9uZVwiO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5oaWdobGlnaHQgPSBcIm5vbmVcIjtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUud2lkdGggPSB0aGlzLndpZHRoICsgXCJweFwiO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmhlaWdodCArIFwicHhcIjtcblx0XG5cdCAgICAgICAgdGhpcy5ib3VuZFJlbmRlciA9IHRoaXMucmVuZGVyLmJpbmQodGhpcyk7XG5cdFxuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2hhbmdlXCIsIHRoaXMuYm91bmRSZW5kZXIpO1xuXHRcblx0ICAgICAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgYXR0YWNoTGlzdGVuZXJzOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBhdHRhY2hMaXN0ZW5lcnMoKSB7fVxuXHQgICAgfSxcblx0ICAgIGJ1aWxkSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBidWlsZEludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgdGhpcy5kZWZpbmVPcHRpb25zKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjb2xvckludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY29sb3JJbnRlcmZhY2UoKSB7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuY29sb3JzLmZpbGw7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmNvbG9yID0gdGhpcy5jb2xvcnMuZGFyaztcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYm9yZGVyID0gXCJzb2xpZCAwcHggXCIgKyB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodDtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHJlbmRlcjoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuXHRcblx0ICAgICAgICB0aGlzLl92YWx1ZSA9IHRoaXMuZWxlbWVudC5vcHRpb25zW3RoaXMuZWxlbWVudC5zZWxlY3RlZEluZGV4XS50ZXh0O1xuXHQgICAgICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSB0aGlzLmVsZW1lbnQuc2VsZWN0ZWRJbmRleDtcblx0ICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwge1xuXHQgICAgICAgICAgdmFsdWU6IHRoaXMuX3ZhbHVlLFxuXHQgICAgICAgICAgaW5kZXg6IHRoaXMuX3NlbGVjdGVkSW5kZXhcblx0ICAgICAgICB9KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNsaWNrOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjbGljaygpIHt9XG5cdCAgICB9LFxuXHQgICAgbW92ZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gbW92ZSgpIHt9XG5cdCAgICB9LFxuXHQgICAgcmVsZWFzZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVsZWFzZSgpIHt9XG5cdCAgICB9LFxuXHQgICAgZGVmaW5lT3B0aW9uczoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgICAqIFVwZGF0ZSB0aGUgbGlzdCBvZiBvcHRpb25zLiBUaGlzIHJlbW92ZXMgYWxsIGV4aXN0aW5nIG9wdGlvbnMgYW5kIGNyZWF0ZXMgYSBuZXcgbGlzdCBvZiBvcHRpb25zLlxuXHQgICAgICAgKiBAcGFyYW0gIHthcnJheX0gb3B0aW9ucyBOZXcgYXJyYXkgb2Ygb3B0aW9uc1xuXHQgICAgICAgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBkZWZpbmVPcHRpb25zKG9wdGlvbnMpIHtcblx0XG5cdCAgICAgICAgLyogIGZ1bmN0aW9uIHJlbW92ZU9wdGlvbnMoc2VsZWN0Ym94KVxuXHQgICAgICAgICAge1xuXHQgICAgICAgICAgICAgIHZhciBpO1xuXHQgICAgICAgICAgICAgIGZvcihpID0gc2VsZWN0Ym94Lm9wdGlvbnMubGVuZ3RoIC0gMSA7IGkgPj0gMCA7IGktLSlcblx0ICAgICAgICAgICAgICB7XG5cdCAgICAgICAgICAgICAgICAgIHNlbGVjdGJveC5yZW1vdmUoaSk7XG5cdCAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgfVxuXHQgICAgICAgICAgLy91c2luZyB0aGUgZnVuY3Rpb246XG5cdCAgICAgICAgICByZW1vdmVPcHRpb25zKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibXlTZWxlY3RPYmplY3RcIikpOyAqL1xuXHRcblx0ICAgICAgICBpZiAob3B0aW9ucykge1xuXHQgICAgICAgICAgdGhpcy5fb3B0aW9ucyA9IG9wdGlvbnM7XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICBmb3IgKHZhciBpID0gdGhpcy5lbGVtZW50Lm9wdGlvbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcblx0ICAgICAgICAgIHRoaXMuZWxlbWVudC5yZW1vdmUoaSk7XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX29wdGlvbnMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgIHRoaXMuZWxlbWVudC5vcHRpb25zLmFkZChuZXcgT3B0aW9uKHRoaXMuX29wdGlvbnNbaV0sIGkpKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICB2YWx1ZToge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFRoZSB0ZXh0IG9mIHRoZSBvcHRpb24gdGhhdCBpcyBjdXJyZW50bHkgc2VsZWN0ZWQuIElmIHNldCwgd2lsbCB1cGRhdGUgdGhlIGludGVyZmFjZSBhbmQgdHJpZ2dlciB0aGUgb3V0cHV0IGV2ZW50LlxuXHQgICAgICBAdHlwZSB7U3RyaW5nfVxuXHQgICAgICBAZXhhbXBsZSBzZWxlY3QudmFsdWUgPSBcInNhd3Rvb3RoXCI7XG5cdCAgICAgICovXG5cdFxuXHQgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWU7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLl92YWx1ZSA9IHY7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmVsZW1lbnQub3B0aW9ucy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgaWYgKHYgPT09IHRoaXMuZWxlbWVudC5vcHRpb25zW2ldLnRleHQpIHtcblx0ICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ID0gaTtcblx0ICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2VsZWN0ZWRJbmRleDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFRoZSBudW1lcmljIGluZGV4IG9mIHRoZSBvcHRpb24gdGhhdCBpcyBjdXJyZW50bHkgc2VsZWN0ZWQuIElmIHNldCwgd2lsbCB1cGRhdGUgdGhlIGludGVyZmFjZSBhbmQgdHJpZ2dlciB0aGUgb3V0cHV0IGV2ZW50LlxuXHQgICAgICBAdHlwZSB7bnVtYmVyfVxuXHQgICAgICBAZXhhbXBsZSBzZWxlY3Quc2VsZWN0ZWRJbmRleCA9IDI7XG5cdCAgICAgICovXG5cdFxuXHQgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRJbmRleDtcblx0ICAgICAgfSxcblx0ICAgICAgc2V0OiBmdW5jdGlvbiAodikge1xuXHQgICAgICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSB2O1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zZWxlY3RlZEluZGV4ID0gdjtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY3VzdG9tRGVzdHJveToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY3VzdG9tRGVzdHJveSgpIHtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLCB0aGlzLmJvdW5kUmVuZGVyKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pO1xuXHRcblx0ICByZXR1cm4gU2VsZWN0O1xuXHR9KShJbnRlcmZhY2UpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBTZWxlY3Q7XG5cbi8qKiovIH0pLFxuLyogMjIgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCA9IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgXCJkZWZhdWx0XCI6IG9iaiB9OyB9O1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9nZXQgPSBmdW5jdGlvbiBnZXQob2JqZWN0LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpIHsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyByZXR1cm4gZ2V0KHBhcmVudCwgcHJvcGVydHksIHJlY2VpdmVyKTsgfSB9IGVsc2UgaWYgKFwidmFsdWVcIiBpbiBkZXNjICYmIGRlc2Mud3JpdGFibGUpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9O1xuXHRcblx0dmFyIF9pbmhlcml0cyA9IGZ1bmN0aW9uIChzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9O1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIHN2ZyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7XG5cdHZhciBtYXRoID0gX193ZWJwYWNrX3JlcXVpcmVfXyg1KTtcblx0dmFyIEludGVyZmFjZSA9IF9fd2VicGFja19yZXF1aXJlX18oNik7XG5cdHZhciBTdGVwID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMSk7XG5cdFxuXHR2YXIgSW50ZXJhY3Rpb24gPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfX3dlYnBhY2tfcmVxdWlyZV9fKDEyKSk7XG5cdFxuXHQvKipcblx0KiBEaWFsXG5cdCpcblx0KlxuXHQqIEBkZXNjcmlwdGlvbiBEaWFsIHdpdGggcmFkaWFsIG9yIGxpbmVhciBpbnRlcmFjdGlvbi5cblx0KlxuXHQqIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwiZGlhbFwiPjwvc3Bhbj5cblx0KlxuXHQqIEBleGFtcGxlXG5cdCogdmFyIGRpYWwgPSBuZXcgTmV4dXMuRGlhbCgnI3RhcmdldCcpXG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciBkaWFsID0gbmV3IE5leHVzLkRpYWwoJyN0YXJnZXQnLHtcblx0KiAgICdzaXplJzogWzc1LDc1XSxcblx0KiAgICdpbnRlcmFjdGlvbic6ICdyYWRpYWwnLCAvLyBcInJhZGlhbFwiLCBcInZlcnRpY2FsXCIsIG9yIFwiaG9yaXpvbnRhbFwiXG5cdCogICAnbW9kZSc6ICdyZWxhdGl2ZScsIC8vIFwiYWJzb2x1dGVcIiBvciBcInJlbGF0aXZlXCJcblx0KiAgICdtaW4nOiAwLFxuXHQqICAgJ21heCc6IDEsXG5cdCogICAnc3RlcCc6IDAsXG5cdCogICAndmFsdWUnOiAwXG5cdCogfSlcblx0KlxuXHQqIEBvdXRwdXRcblx0KiBjaGFuZ2Vcblx0KiBGaXJlcyBhbnkgdGltZSB0aGUgaW50ZXJmYWNlJ3MgdmFsdWUgY2hhbmdlcy4gPGJyPlxuXHQqIFRoZSBldmVudCBkYXRhIGlzIHRoZSBudW1iZXIgdmFsdWUgb2YgdGhlIGludGVyZmFjZS5cblx0KlxuXHQqIEBvdXRwdXRleGFtcGxlXG5cdCogZGlhbC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG5cdCogICBjb25zb2xlLmxvZyh2KTtcblx0KiB9KVxuXHQqXG5cdCogQHR1dG9yaWFsXG5cdCogRGlhbFxuXHQqIHlnR014cVxuXHQqXG5cdCovXG5cdFxuXHR2YXIgRGlhbCA9IChmdW5jdGlvbiAoX0ludGVyZmFjZSkge1xuXHQgIGZ1bmN0aW9uIERpYWwoKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRGlhbCk7XG5cdFxuXHQgICAgdmFyIG9wdGlvbnMgPSBbXCJtaW5cIiwgXCJtYXhcIiwgXCJ2YWx1ZVwiXTtcblx0XG5cdCAgICB2YXIgZGVmYXVsdHMgPSB7XG5cdCAgICAgIHNpemU6IFs3NSwgNzVdLFxuXHQgICAgICBpbnRlcmFjdGlvbjogXCJyYWRpYWxcIiwgLy8gcmFkaWFsLCB2ZXJ0aWNhbCwgaG9yaXpvbnRhbFxuXHQgICAgICBtb2RlOiBcInJlbGF0aXZlXCIsIC8vIGFic29sdXRlLCByZWxhdGl2ZVxuXHQgICAgICBtaW46IDAsXG5cdCAgICAgIG1heDogMSxcblx0ICAgICAgc3RlcDogMCxcblx0ICAgICAgdmFsdWU6IDBcblx0ICAgIH07XG5cdFxuXHQgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoRGlhbC5wcm90b3R5cGUpLCBcImNvbnN0cnVjdG9yXCIsIHRoaXMpLmNhbGwodGhpcywgYXJndW1lbnRzLCBvcHRpb25zLCBkZWZhdWx0cyk7XG5cdFxuXHQgICAgdGhpcy5pbnRlcmFjdGlvbiA9IHRoaXMuc2V0dGluZ3MuaW50ZXJhY3Rpb247XG5cdFxuXHQgICAgdGhpcy5fdmFsdWUgPSBuZXcgU3RlcCh0aGlzLnNldHRpbmdzLm1pbiwgdGhpcy5zZXR0aW5ncy5tYXgsIHRoaXMuc2V0dGluZ3Muc3RlcCwgdGhpcy5zZXR0aW5ncy52YWx1ZSk7XG5cdFxuXHQgICAgdGhpcy5wb3NpdGlvbiA9IG5ldyBJbnRlcmFjdGlvbi5IYW5kbGUodGhpcy5zZXR0aW5ncy5tb2RlLCB0aGlzLmludGVyYWN0aW9uLCBbMCwgdGhpcy53aWR0aF0sIFt0aGlzLmhlaWdodCwgMF0pO1xuXHRcblx0ICAgIHRoaXMuaW5pdCgpO1xuXHRcblx0ICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblx0XG5cdCAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblx0XG5cdCAgICB0aGlzLnByZXZpb3VzQW5nbGUgPSBmYWxzZTtcblx0XG5cdCAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy52YWx1ZSk7XG5cdCAgfVxuXHRcblx0ICBfaW5oZXJpdHMoRGlhbCwgX0ludGVyZmFjZSk7XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhEaWFsLCB7XG5cdCAgICBidWlsZEludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gYnVpbGRJbnRlcmZhY2UoKSB7XG5cdFxuXHQgICAgICAgIHRoaXMuYmFja2dyb3VuZCA9IHN2Zy5jcmVhdGUoXCJjaXJjbGVcIik7XG5cdCAgICAgICAgdGhpcy5zY3JldyA9IHN2Zy5jcmVhdGUoXCJjaXJjbGVcIik7XG5cdCAgICAgICAgdGhpcy5oYW5kbGUgPSBzdmcuY3JlYXRlKFwicGF0aFwiKTtcblx0ICAgICAgICB0aGlzLmhhbmRsZTIgPSBzdmcuY3JlYXRlKFwicGF0aFwiKTtcblx0ICAgICAgICB0aGlzLmhhbmRsZUZpbGwgPSBzdmcuY3JlYXRlKFwicGF0aFwiKTtcblx0ICAgICAgICB0aGlzLmhhbmRsZTJGaWxsID0gc3ZnLmNyZWF0ZShcInBhdGhcIik7XG5cdCAgICAgICAgdGhpcy5oYW5kbGVMaW5lID0gc3ZnLmNyZWF0ZShcInBhdGhcIik7XG5cdFxuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhY2tncm91bmQpO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZSk7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuaGFuZGxlMik7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuaGFuZGxlRmlsbCk7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuaGFuZGxlMkZpbGwpO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmhhbmRsZUxpbmUpO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnNjcmV3KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHNpemVJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNpemVJbnRlcmZhY2UoKSB7XG5cdFxuXHQgICAgICAgIHRoaXMucG9zaXRpb24ucmVzaXplKFswLCB0aGlzLndpZHRoXSwgW3RoaXMuaGVpZ2h0LCAwXSk7XG5cdFxuXHQgICAgICAgIHZhciBjZW50ZXIgPSB7XG5cdCAgICAgICAgICB4OiB0aGlzLndpZHRoIC8gMixcblx0ICAgICAgICAgIHk6IHRoaXMuaGVpZ2h0IC8gMlxuXHQgICAgICAgIH07XG5cdFxuXHQgICAgICAgIHZhciBkaWFtZXRlciA9IE1hdGgubWluKHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KTtcblx0XG5cdCAgICAgICAgdGhpcy5iYWNrZ3JvdW5kLnNldEF0dHJpYnV0ZShcImN4XCIsIGNlbnRlci54KTtcblx0ICAgICAgICB0aGlzLmJhY2tncm91bmQuc2V0QXR0cmlidXRlKFwiY3lcIiwgY2VudGVyLnkpO1xuXHQgICAgICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoXCJyXCIsIGRpYW1ldGVyIC8gMiAtIGRpYW1ldGVyIC8gNDApO1xuXHRcblx0ICAgICAgICB0aGlzLnNjcmV3LnNldEF0dHJpYnV0ZShcImN4XCIsIGNlbnRlci54KTtcblx0ICAgICAgICB0aGlzLnNjcmV3LnNldEF0dHJpYnV0ZShcImN5XCIsIGNlbnRlci55KTtcblx0ICAgICAgICB0aGlzLnNjcmV3LnNldEF0dHJpYnV0ZShcInJcIiwgZGlhbWV0ZXIgLyAxMik7XG5cdFxuXHQgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMudmFsdWU7XG5cdFxuXHQgICAgICAgIHZhciBoYW5kbGVQb2ludHMgPSB7XG5cdCAgICAgICAgICBzdGFydDogTWF0aC5QSSAqIDEuNSxcblx0ICAgICAgICAgIGVuZDogbWF0aC5jbGlwKG1hdGguc2NhbGUodmFsdWUsIDAsIDAuNSwgTWF0aC5QSSAqIDEuNSwgTWF0aC5QSSAqIDAuNSksIE1hdGguUEkgKiAwLjUsIE1hdGguUEkgKiAxLjUpXG5cdCAgICAgICAgfTtcblx0ICAgICAgICB2YXIgaGFuZGxlMlBvaW50cyA9IHtcblx0ICAgICAgICAgIHN0YXJ0OiBNYXRoLlBJICogMi41LFxuXHQgICAgICAgICAgZW5kOiBtYXRoLmNsaXAobWF0aC5zY2FsZSh2YWx1ZSwgMC41LCAxLCBNYXRoLlBJICogMi41LCBNYXRoLlBJICogMS41KSwgTWF0aC5QSSAqIDEuNSwgTWF0aC5QSSAqIDIuNSlcblx0ICAgICAgICB9O1xuXHRcblx0ICAgICAgICB2YXIgaGFuZGxlUGF0aCA9IHN2Zy5hcmMoY2VudGVyLngsIGNlbnRlci55LCBkaWFtZXRlciAvIDIgLSBkaWFtZXRlciAvIDQwLCBoYW5kbGVQb2ludHMuc3RhcnQsIGhhbmRsZVBvaW50cy5lbmQpO1xuXHQgICAgICAgIHZhciBoYW5kbGUyUGF0aCA9IHN2Zy5hcmMoY2VudGVyLngsIGNlbnRlci55LCBkaWFtZXRlciAvIDIgLSBkaWFtZXRlciAvIDQwLCBoYW5kbGUyUG9pbnRzLnN0YXJ0LCBoYW5kbGUyUG9pbnRzLmVuZCk7XG5cdFxuXHQgICAgICAgIHRoaXMuaGFuZGxlLnNldEF0dHJpYnV0ZShcImRcIiwgaGFuZGxlUGF0aCk7XG5cdCAgICAgICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIGRpYW1ldGVyIC8gMjApO1xuXHQgICAgICAgIHRoaXMuaGFuZGxlLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgXCJub25lXCIpO1xuXHRcblx0ICAgICAgICB0aGlzLmhhbmRsZTIuc2V0QXR0cmlidXRlKFwiZFwiLCBoYW5kbGUyUGF0aCk7XG5cdCAgICAgICAgdGhpcy5oYW5kbGUyLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBkaWFtZXRlciAvIDIwKTtcblx0ICAgICAgICB0aGlzLmhhbmRsZTIuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcIm5vbmVcIik7XG5cdFxuXHQgICAgICAgIGhhbmRsZVBhdGggKz0gXCIgTCBcIiArIGNlbnRlci54ICsgXCIgXCIgKyBjZW50ZXIueTtcblx0XG5cdCAgICAgICAgdGhpcy5oYW5kbGVGaWxsLnNldEF0dHJpYnV0ZShcImRcIiwgaGFuZGxlUGF0aCk7XG5cdCAgICAgICAgdGhpcy5oYW5kbGVGaWxsLnNldEF0dHJpYnV0ZShcImZpbGwtb3BhY2l0eVwiLCBcIjAuM1wiKTtcblx0XG5cdCAgICAgICAgaGFuZGxlMlBhdGggKz0gXCIgTCBcIiArIGNlbnRlci54ICsgXCIgXCIgKyBjZW50ZXIueTtcblx0XG5cdCAgICAgICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoXCJkXCIsIGhhbmRsZTJQYXRoKTtcblx0ICAgICAgICB0aGlzLmhhbmRsZTJGaWxsLnNldEF0dHJpYnV0ZShcImZpbGwtb3BhY2l0eVwiLCBcIjAuM1wiKTtcblx0XG5cdCAgICAgICAgdmFyIGFyY0VuZGluZ0EgPSB1bmRlZmluZWQ7XG5cdCAgICAgICAgaWYgKHZhbHVlIDwgMC41KSB7XG5cdCAgICAgICAgICBhcmNFbmRpbmdBID0gaGFuZGxlUG9pbnRzLmVuZDtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgYXJjRW5kaW5nQSA9IGhhbmRsZTJQb2ludHMuZW5kO1xuXHQgICAgICAgIH1cblx0XG5cdCAgICAgICAgdmFyIGFyY0VuZGluZ1ggPSBjZW50ZXIueCArIE1hdGguY29zKGFyY0VuZGluZ0EpICogKGRpYW1ldGVyIC8gMik7XG5cdCAgICAgICAgdmFyIGFyY0VuZGluZ1kgPSBjZW50ZXIueSArIE1hdGguc2luKGFyY0VuZGluZ0EpICogKGRpYW1ldGVyIC8gMikgKiAtMTtcblx0XG5cdCAgICAgICAgdGhpcy5oYW5kbGVMaW5lLnNldEF0dHJpYnV0ZShcImRcIiwgXCJNIFwiICsgY2VudGVyLnggKyBcIiBcIiArIGNlbnRlci55ICsgXCIgTCBcIiArIGFyY0VuZGluZ1ggKyBcIiBcIiArIGFyY0VuZGluZ1kpO1xuXHQgICAgICAgIHRoaXMuaGFuZGxlTGluZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgZGlhbWV0ZXIgLyAyMCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjb2xvckludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY29sb3JJbnRlcmZhY2UoKSB7XG5cdCAgICAgICAgdGhpcy5iYWNrZ3JvdW5kLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdGhpcy5jb2xvcnMuZmlsbCk7XG5cdCAgICAgICAgdGhpcy5zY3Jldy5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cdCAgICAgICAgdGhpcy5oYW5kbGUuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cdCAgICAgICAgdGhpcy5oYW5kbGUyLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuXHQgICAgICAgIHRoaXMuaGFuZGxlRmlsbC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cdCAgICAgICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cdCAgICAgICAgdGhpcy5oYW5kbGVMaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcmVuZGVyOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cdCAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblx0XG5cdCAgICAgICAgdmFyIGNlbnRlciA9IHtcblx0ICAgICAgICAgIHg6IHRoaXMud2lkdGggLyAyLFxuXHQgICAgICAgICAgeTogdGhpcy5oZWlnaHQgLyAyXG5cdCAgICAgICAgfTtcblx0XG5cdCAgICAgICAgdmFyIGRpYW1ldGVyID0gTWF0aC5taW4odGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xuXHRcblx0ICAgICAgICB2YXIgaGFuZGxlUG9pbnRzID0ge1xuXHQgICAgICAgICAgc3RhcnQ6IE1hdGguUEkgKiAxLjUsXG5cdCAgICAgICAgICBlbmQ6IG1hdGguY2xpcChtYXRoLnNjYWxlKHZhbHVlLCAwLCAwLjUsIE1hdGguUEkgKiAxLjUsIE1hdGguUEkgKiAwLjUpLCBNYXRoLlBJICogMC41LCBNYXRoLlBJICogMS41KVxuXHQgICAgICAgIH07XG5cdCAgICAgICAgdmFyIGhhbmRsZTJQb2ludHMgPSB7XG5cdCAgICAgICAgICBzdGFydDogTWF0aC5QSSAqIDIuNSxcblx0ICAgICAgICAgIGVuZDogbWF0aC5jbGlwKG1hdGguc2NhbGUodmFsdWUsIDAuNSwgMSwgTWF0aC5QSSAqIDIuNSwgTWF0aC5QSSAqIDEuNSksIE1hdGguUEkgKiAxLjUsIE1hdGguUEkgKiAyLjUpXG5cdCAgICAgICAgfTtcblx0XG5cdCAgICAgICAgdmFyIGhhbmRsZVBhdGggPSBzdmcuYXJjKGNlbnRlci54LCBjZW50ZXIueSwgZGlhbWV0ZXIgLyAyIC0gZGlhbWV0ZXIgLyA0MCwgaGFuZGxlUG9pbnRzLnN0YXJ0LCBoYW5kbGVQb2ludHMuZW5kKTtcblx0ICAgICAgICB2YXIgaGFuZGxlMlBhdGggPSBzdmcuYXJjKGNlbnRlci54LCBjZW50ZXIueSwgZGlhbWV0ZXIgLyAyIC0gZGlhbWV0ZXIgLyA0MCwgaGFuZGxlMlBvaW50cy5zdGFydCwgaGFuZGxlMlBvaW50cy5lbmQpO1xuXHRcblx0ICAgICAgICB0aGlzLmhhbmRsZS5zZXRBdHRyaWJ1dGUoXCJkXCIsIGhhbmRsZVBhdGgpO1xuXHQgICAgICAgIHRoaXMuaGFuZGxlMi5zZXRBdHRyaWJ1dGUoXCJkXCIsIGhhbmRsZTJQYXRoKTtcblx0XG5cdCAgICAgICAgaGFuZGxlUGF0aCArPSBcIiBMIFwiICsgY2VudGVyLnggKyBcIiBcIiArIGNlbnRlci55O1xuXHRcblx0ICAgICAgICB0aGlzLmhhbmRsZUZpbGwuc2V0QXR0cmlidXRlKFwiZFwiLCBoYW5kbGVQYXRoKTtcblx0XG5cdCAgICAgICAgaGFuZGxlMlBhdGggKz0gXCIgTCBcIiArIGNlbnRlci54ICsgXCIgXCIgKyBjZW50ZXIueTtcblx0XG5cdCAgICAgICAgdGhpcy5oYW5kbGUyRmlsbC5zZXRBdHRyaWJ1dGUoXCJkXCIsIGhhbmRsZTJQYXRoKTtcblx0XG5cdCAgICAgICAgdmFyIGFyY0VuZGluZ0EgPSB1bmRlZmluZWQ7XG5cdCAgICAgICAgaWYgKHZhbHVlIDw9IDAuNSkge1xuXHQgICAgICAgICAgYXJjRW5kaW5nQSA9IGhhbmRsZVBvaW50cy5lbmQ7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIGFyY0VuZGluZ0EgPSBoYW5kbGUyUG9pbnRzLmVuZDtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHZhciBhcmNFbmRpbmdYID0gY2VudGVyLnggKyBNYXRoLmNvcyhhcmNFbmRpbmdBKSAqIChkaWFtZXRlciAvIDIpO1xuXHQgICAgICAgIHZhciBhcmNFbmRpbmdZID0gY2VudGVyLnkgKyBNYXRoLnNpbihhcmNFbmRpbmdBKSAqIChkaWFtZXRlciAvIDIpICogLTE7XG5cdFxuXHQgICAgICAgIHRoaXMuaGFuZGxlTGluZS5zZXRBdHRyaWJ1dGUoXCJkXCIsIFwiTSBcIiArIGNlbnRlci54ICsgXCIgXCIgKyBjZW50ZXIueSArIFwiIEwgXCIgKyBhcmNFbmRpbmdYICsgXCIgXCIgKyBhcmNFbmRpbmdZKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNsaWNrOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjbGljaygpIHtcblx0ICAgICAgICBpZiAodGhpcy5tb2RlID09PSBcInJlbGF0aXZlXCIpIHtcblx0ICAgICAgICAgIHRoaXMucHJldmlvdXNBbmdsZSA9IGZhbHNlO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLnBvc2l0aW9uLmFuY2hvciA9IHRoaXMubW91c2U7XG5cdCAgICAgICAgdGhpcy5wb3NpdGlvbi52YWx1ZSA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQ7XG5cdCAgICAgICAgdGhpcy5tb3ZlKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBtb3ZlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBtb3ZlKCkge1xuXHQgICAgICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcblx0XG5cdCAgICAgICAgICB0aGlzLnBvc2l0aW9uLnVwZGF0ZSh0aGlzLm1vdXNlKTtcblx0XG5cdCAgICAgICAgICB2YXIgYW5nbGUgPSB0aGlzLnBvc2l0aW9uLnZhbHVlICogTWF0aC5QSSAqIDI7XG5cdFxuXHQgICAgICAgICAgaWYgKGFuZ2xlIDwgMCkge1xuXHQgICAgICAgICAgICBhbmdsZSArPSBNYXRoLlBJICogMjtcblx0ICAgICAgICAgIH1cblx0XG5cdCAgICAgICAgICBpZiAodGhpcy5tb2RlID09PSBcInJlbGF0aXZlXCIpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMucHJldmlvdXNBbmdsZSAhPT0gZmFsc2UgJiYgTWF0aC5hYnModGhpcy5wcmV2aW91c0FuZ2xlIC0gYW5nbGUpID4gMikge1xuXHQgICAgICAgICAgICAgIGlmICh0aGlzLnByZXZpb3VzQW5nbGUgPiAzKSB7XG5cdCAgICAgICAgICAgICAgICBhbmdsZSA9IE1hdGguUEkgKiAyO1xuXHQgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBhbmdsZSA9IDA7XG5cdCAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICB9IC8qIGVsc2Uge1xuXHQgICAgICAgICAgICBpZiAodGhpcy5wcmV2aW91c0FuZ2xlICE9PSBmYWxzZSAmJiBNYXRoLmFicyh0aGlzLnByZXZpb3VzQW5nbGUgLSBhbmdsZSkgPiAyKSB7XG5cdCAgICAgICAgICAgICAgaWYgKHRoaXMucHJldmlvdXNBbmdsZSA+IDMpIHtcblx0ICAgICAgICAgICAgICAgIGFuZ2xlID0gTWF0aC5QSSoyO1xuXHQgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBhbmdsZSA9IDA7XG5cdCAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gKi9cblx0ICAgICAgICAgIHRoaXMucHJldmlvdXNBbmdsZSA9IGFuZ2xlO1xuXHRcblx0ICAgICAgICAgIHZhciByZWFsVmFsdWUgPSBhbmdsZSAvIChNYXRoLlBJICogMik7XG5cdFxuXHQgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuX3ZhbHVlLnVwZGF0ZU5vcm1hbChyZWFsVmFsdWUpO1xuXHRcblx0ICAgICAgICAgIGlmICh0aGlzLm1vZGUgPT09IFwicmVsYXRpdmVcIikge1xuXHQgICAgICAgICAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gcmVhbFZhbHVlO1xuXHQgICAgICAgICAgfVxuXHRcblx0ICAgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB0aGlzLl92YWx1ZS52YWx1ZSk7XG5cdFxuXHQgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByZWxlYXNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZWxlYXNlKCkge31cblx0ICAgIH0sXG5cdCAgICB2YWx1ZToge1xuXHRcblx0ICAgICAgLypcblx0ICAgICAgRGlhbCdzIHZhbHVlLiBXaGVuIHNldCwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGFkanVzdCB0byBmaXQgbWluL21heC9zdGVwIHNldHRpbmdzIG9mIHRoZSBpbnRlcmZhY2UuXG5cdCAgICAgIEB0eXBlIHtudW1iZXJ9XG5cdCAgICAgIEBleGFtcGxlIGRpYWwudmFsdWUgPSAxMDtcblx0ICAgICAgIGdldCB2YWx1ZSgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWUudmFsdWU7XG5cdCAgICAgIH1cblx0ICAgICAgIHNldCB2YWx1ZSh2YWx1ZSkge1xuXHQgICAgICAgIHRoaXMuX3ZhbHVlLnVwZGF0ZSh2YWx1ZSk7XG5cdCAgICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLHRoaXMudmFsdWUpO1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgICAgKi9cblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBEaWFsJ3MgdmFsdWUuIFdoZW4gc2V0LCBpdCB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgYWRqdXN0IHRvIGZpdCBtaW4vbWF4L3N0ZXAgc2V0dGluZ3Mgb2YgdGhlIGludGVyZmFjZS5cblx0ICAgICAgQHR5cGUge251bWJlcn1cblx0ICAgICAgQGV4YW1wbGUgZGlhbC52YWx1ZSA9IDEwO1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLnZhbHVlO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdGhpcy5fdmFsdWUudXBkYXRlKHYpO1xuXHQgICAgICAgIHRoaXMucG9zaXRpb24udmFsdWUgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXHQgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB0aGlzLl92YWx1ZS52YWx1ZSk7XG5cdCAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIG1pbjoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIExvd2VyIGxpbWl0IG9mIHRoZSBkaWFsJ3Mgb3V0cHV0IHJhbmdlXG5cdCAgICAgIEB0eXBlIHtudW1iZXJ9XG5cdCAgICAgIEBleGFtcGxlIGRpYWwubWluID0gMTAwMDtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5taW47XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLl92YWx1ZS5taW4gPSB2O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbWF4OiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgVXBwZXIgbGltaXQgb2YgdGhlIGRpYWwncyBvdXRwdXQgcmFuZ2Vcblx0ICAgICAgQHR5cGUge251bWJlcn1cblx0ICAgICAgQGV4YW1wbGUgZGlhbC5tYXggPSAxMDAwO1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLm1heDtcblx0ICAgICAgfSxcblx0ICAgICAgc2V0OiBmdW5jdGlvbiAodikge1xuXHQgICAgICAgIHRoaXMuX3ZhbHVlLm1heCA9IHY7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzdGVwOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgVGhlIGluY3JlbWVudCB0aGF0IHRoZSBkaWFsJ3MgdmFsdWUgY2hhbmdlcyBieS5cblx0ICAgICAgQHR5cGUge251bWJlcn1cblx0ICAgICAgQGV4YW1wbGUgZGlhbC5zdGVwID0gNTtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5zdGVwO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdGhpcy5fdmFsdWUuc3RlcCA9IHY7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBtb2RlOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgQWJzb2x1dGUgbW9kZSAoZGlhbCdzIHZhbHVlIGp1bXBzIHRvIG1vdXNlIGNsaWNrIHBvc2l0aW9uKSBvciByZWxhdGl2ZSBtb2RlIChtb3VzZSBkcmFnIGNoYW5nZXMgdmFsdWUgcmVsYXRpdmUgdG8gaXRzIGN1cnJlbnQgcG9zaXRpb24pLiBEZWZhdWx0OiBcInJlbGF0aXZlXCIuXG5cdCAgICAgIEB0eXBlIHtzdHJpbmd9XG5cdCAgICAgIEBleGFtcGxlIGRpYWwubW9kZSA9IFwicmVsYXRpdmVcIjtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uLm1vZGU7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uLm1vZGUgPSB2O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbm9ybWFsaXplZDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIE5vcm1hbGl6ZWQgdmFsdWUgb2YgdGhlIGRpYWwuXG5cdCAgICAgIEB0eXBlIHtudW1iZXJ9XG5cdCAgICAgIEBleGFtcGxlIGRpYWwubm9ybWFsaXplZCA9IDAuNTtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdGhpcy5fdmFsdWUudXBkYXRlTm9ybWFsKHYpO1xuXHQgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB0aGlzLnZhbHVlKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pO1xuXHRcblx0ICByZXR1cm4gRGlhbDtcblx0fSkoSW50ZXJmYWNlKTtcblx0XG5cdG1vZHVsZS5leHBvcnRzID0gRGlhbDtcblxuLyoqKi8gfSksXG4vKiAyMyAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9nZXQgPSBmdW5jdGlvbiBnZXQob2JqZWN0LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpIHsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyByZXR1cm4gZ2V0KHBhcmVudCwgcHJvcGVydHksIHJlY2VpdmVyKTsgfSB9IGVsc2UgaWYgKFwidmFsdWVcIiBpbiBkZXNjICYmIGRlc2Mud3JpdGFibGUpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9O1xuXHRcblx0dmFyIF9pbmhlcml0cyA9IGZ1bmN0aW9uIChzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9O1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIHN2ZyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7XG5cdHZhciBJbnRlcmZhY2UgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpO1xuXHR2YXIgQnV0dG9uVGVtcGxhdGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE3KTtcblx0dmFyIHRvdWNoID0gX193ZWJwYWNrX3JlcXVpcmVfXyg5KTtcblx0XG5cdHZhciBQaWFub0tleSA9IChmdW5jdGlvbiAoX0J1dHRvblRlbXBsYXRlKSB7XG5cdCAgZnVuY3Rpb24gUGlhbm9LZXkoKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUGlhbm9LZXkpO1xuXHRcblx0ICAgIHZhciBvcHRpb25zID0gW1widmFsdWVcIiwgXCJub3RlXCIsIFwiY29sb3JcIl07XG5cdFxuXHQgICAgdmFyIGRlZmF1bHRzID0ge1xuXHQgICAgICBzaXplOiBbODAsIDgwXSxcblx0ICAgICAgdGFyZ2V0OiBmYWxzZSxcblx0ICAgICAgbW9kZTogXCJidXR0b25cIixcblx0ICAgICAgdmFsdWU6IDBcblx0ICAgIH07XG5cdFxuXHQgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoUGlhbm9LZXkucHJvdG90eXBlKSwgXCJjb25zdHJ1Y3RvclwiLCB0aGlzKS5jYWxsKHRoaXMsIGFyZ3VtZW50cywgb3B0aW9ucywgZGVmYXVsdHMpO1xuXHRcblx0ICAgIHRoaXMubm90ZSA9IHRoaXMuc2V0dGluZ3Mubm90ZTtcblx0ICAgIHRoaXMuY29sb3IgPSB0aGlzLnNldHRpbmdzLmNvbG9yO1xuXHRcblx0ICAgIHRoaXMuY29sb3JzID0ge1xuXHQgICAgICB3OiBcIiNmZmZcIixcblx0ICAgICAgYjogXCIjNjY2XCIgfTtcblx0XG5cdCAgICB0aGlzLmluaXQoKTtcblx0ICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgfVxuXHRcblx0ICBfaW5oZXJpdHMoUGlhbm9LZXksIF9CdXR0b25UZW1wbGF0ZSk7XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhQaWFub0tleSwge1xuXHQgICAgYnVpbGRGcmFtZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gYnVpbGRGcmFtZSgpIHtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQgPSBzdmcuY3JlYXRlKFwic3ZnXCIpO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiLCB0aGlzLndpZHRoKTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIHRoaXMuaGVpZ2h0KTtcblx0ICAgICAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgYnVpbGRJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkSW50ZXJmYWNlKCkge1xuXHQgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgICAgIHRoaXMucGFkID0gc3ZnLmNyZWF0ZShcInJlY3RcIik7XG5cdFxuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnBhZCk7XG5cdFxuXHQgICAgICAgIHRoaXMuaW50ZXJhY3Rpb25UYXJnZXQgPSB0aGlzLnBhZDtcblx0XG5cdCAgICAgICAgLyogZXZlbnRzICovXG5cdFxuXHQgICAgICAgIGlmICghdG91Y2guZXhpc3RzKSB7XG5cdFxuXHQgICAgICAgICAgdGhpcy5jbGljayA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gIGNvbnNvbGUubG9nKCdjbGljaycpO1xuXHQgICAgICAgICAgICBfdGhpcy5waWFuby5pbnRlcmFjdGluZyA9IHRydWU7XG5cdCAgICAgICAgICAgIF90aGlzLnBpYW5vLnBhaW50YnJ1c2ggPSAhX3RoaXMuc3RhdGU7XG5cdCAgICAgICAgICAgIF90aGlzLmRvd24oX3RoaXMucGlhbm8ucGFpbnRicnVzaCk7XG5cdCAgICAgICAgICB9O1xuXHRcblx0ICAgICAgICAgIHRoaXMucGFkLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW92ZXJcIiwgZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBpZiAoX3RoaXMucGlhbm8uaW50ZXJhY3RpbmcpIHtcblx0ICAgICAgICAgICAgICAvLyAgICBjb25zb2xlLmxvZygnbW91c2VvdmVyJyk7XG5cdCAgICAgICAgICAgICAgX3RoaXMuZG93bihfdGhpcy5waWFuby5wYWludGJydXNoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgfSk7XG5cdFxuXHQgICAgICAgICAgdGhpcy5tb3ZlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBpZiAoX3RoaXMucGlhbm8uaW50ZXJhY3RpbmcpIHtcblx0ICAgICAgICAgICAgICAvLyAgY29uc29sZS5sb2coJ21vdmUnKTtcblx0ICAgICAgICAgICAgICBfdGhpcy5iZW5kKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgIH07XG5cdFxuXHQgICAgICAgICAgdGhpcy5yZWxlYXNlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBfdGhpcy5waWFuby5pbnRlcmFjdGluZyA9IGZhbHNlO1xuXHQgICAgICAgICAgICAvLyAgY29uc29sZS5sb2coJ3JlbGVhc2UnKTtcblx0ICAgICAgICAgICAgLy8gIHRoaXMudXAoKTtcblx0ICAgICAgICAgIH07XG5cdCAgICAgICAgICB0aGlzLnBhZC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIGlmIChfdGhpcy5waWFuby5pbnRlcmFjdGluZykge1xuXHQgICAgICAgICAgICAgIC8vICBjb25zb2xlLmxvZygnbW91c2V1cCcpO1xuXHQgICAgICAgICAgICAgIF90aGlzLnVwKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlb3V0XCIsIGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKF90aGlzLnBpYW5vLmludGVyYWN0aW5nKSB7XG5cdCAgICAgICAgICAgICAgLy8gIGNvbnNvbGUubG9nKCdtb3VzZW91dCcpO1xuXHQgICAgICAgICAgICAgIF90aGlzLnVwKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHNpemVJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNpemVJbnRlcmZhY2UoKSB7XG5cdFxuXHQgICAgICAgIC8vbGV0IHJhZGl1cyA9IE1hdGgubWluKHRoaXMud2lkdGgsdGhpcy5oZWlnaHQpIC8gNTtcblx0ICAgICAgICB2YXIgcmFkaXVzID0gMDtcblx0XG5cdCAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwieFwiLCAwLjUpO1xuXHQgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcInlcIiwgMC41KTtcblx0ICAgICAgICBpZiAodGhpcy53aWR0aCA+IDIpIHtcblx0ICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIHRoaXMud2lkdGggLSAxKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgdGhpcy53aWR0aCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICh0aGlzLmhlaWdodCA+IDIpIHtcblx0ICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCB0aGlzLmhlaWdodCk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCB0aGlzLmhlaWdodCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcInJ4XCIsIHJhZGl1cyk7XG5cdCAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwicnlcIiwgcmFkaXVzKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHJlbmRlcjoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuXHQgICAgICAgIGlmICghdGhpcy5zdGF0ZSkge1xuXHQgICAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCB0aGlzLmNvbG9yc1t0aGlzLmNvbG9yXSk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdGhpcy5jb2xvcnMuYWNjZW50KTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIFBpYW5vS2V5O1xuXHR9KShCdXR0b25UZW1wbGF0ZSk7XG5cdFxuXHQvKipcblx0KiBQaWFub1xuXHQqXG5cdCogQGRlc2NyaXB0aW9uIFBpYW5vIGtleWJvYXJkIGludGVyZmFjZVxuXHQqXG5cdCogQGRlbW8gPGRpdiBuZXh1cy11aT1cInBpYW5vXCI+PC9kaXY+XG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciBwaWFubyA9IG5ldyBOZXh1cy5QaWFubygnI3RhcmdldCcpXG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciBwaWFubyA9IG5ldyBOZXh1cy5QaWFubygnI3RhcmdldCcse1xuXHQqICAgICAnc2l6ZSc6IFs1MDAsMTI1XSxcblx0KiAgICAgJ21vZGUnOiAnYnV0dG9uJywgIC8vICdidXR0b24nLCAndG9nZ2xlJywgb3IgJ2ltcHVsc2UnXG5cdCogICAgICdsb3dOb3RlJzogMjQsXG5cdCogICAgICdoaWdoTm90ZSc6IDYwXG5cdCogfSlcblx0KlxuXHQqIEBvdXRwdXRcblx0KiBjaGFuZ2Vcblx0KiBGaXJlcyBhbnkgdGltZSBhIG5ldyBrZXkgaXMgcHJlc3NlZCBvciByZWxlYXNlZCA8YnI+XG5cdCogVGhlIGV2ZW50IGRhdGEgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgPGk+bm90ZTwvaT4gYW5kIDxpPnN0YXRlPC9pPiBwcm9wZXJ0aWVzLlxuXHQqXG5cdCogQG91dHB1dGV4YW1wbGVcblx0KiBwaWFuby5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG5cdCogICBjb25zb2xlLmxvZyh2KTtcblx0KiB9KVxuXHQqXG5cdCovXG5cdFxuXHR2YXIgUGlhbm8gPSAoZnVuY3Rpb24gKF9JbnRlcmZhY2UpIHtcblx0ICBmdW5jdGlvbiBQaWFubygpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQaWFubyk7XG5cdFxuXHQgICAgdmFyIG9wdGlvbnMgPSBbXCJ2YWx1ZVwiXTtcblx0XG5cdCAgICB2YXIgZGVmYXVsdHMgPSB7XG5cdCAgICAgIHNpemU6IFs1MDAsIDEyNV0sXG5cdCAgICAgIGxvd05vdGU6IDI0LFxuXHQgICAgICBoaWdoTm90ZTogNjAsXG5cdCAgICAgIG1vZGU6IFwiYnV0dG9uXCJcblx0ICAgIH07XG5cdFxuXHQgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoUGlhbm8ucHJvdG90eXBlKSwgXCJjb25zdHJ1Y3RvclwiLCB0aGlzKS5jYWxsKHRoaXMsIGFyZ3VtZW50cywgb3B0aW9ucywgZGVmYXVsdHMpO1xuXHRcblx0ICAgIHRoaXMua2V5UGF0dGVybiA9IFtcIndcIiwgXCJiXCIsIFwid1wiLCBcImJcIiwgXCJ3XCIsIFwid1wiLCBcImJcIiwgXCJ3XCIsIFwiYlwiLCBcIndcIiwgXCJiXCIsIFwid1wiXTtcblx0XG5cdCAgICB0aGlzLnBhaW50YnJ1c2ggPSBmYWxzZTtcblx0XG5cdCAgICB0aGlzLm1vZGUgPSB0aGlzLnNldHRpbmdzLm1vZGU7XG5cdFxuXHQgICAgdGhpcy5yYW5nZSA9IHtcblx0ICAgICAgbG93OiB0aGlzLnNldHRpbmdzLmxvd05vdGUsXG5cdCAgICAgIGhpZ2g6IHRoaXMuc2V0dGluZ3MuaGlnaE5vdGVcblx0ICAgIH07XG5cdFxuXHQgICAgdGhpcy5yYW5nZS5zaXplID0gdGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7XG5cdFxuXHQgICAgdGhpcy5rZXlzID0gW107XG5cdFxuXHQgICAgdGhpcy50b2dnbGVUbyA9IGZhbHNlO1xuXHRcblx0ICAgIHRoaXMuaW5pdCgpO1xuXHQgICAgdGhpcy5yZW5kZXIoKTtcblx0ICB9XG5cdFxuXHQgIF9pbmhlcml0cyhQaWFubywgX0ludGVyZmFjZSk7XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhQaWFubywge1xuXHQgICAgYnVpbGRGcmFtZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gYnVpbGRGcmFtZSgpIHtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9IFwicmVsYXRpdmVcIjtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYm9yZGVyUmFkaXVzID0gXCIwcHhcIjtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIjtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUud2lkdGggPSBcIjEwMCVcIjtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gXCIxMDAlXCI7XG5cdCAgICAgICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGJ1aWxkSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBidWlsZEludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgdGhpcy5rZXlzID0gW107XG5cdFxuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5yYW5nZS5oaWdoIC0gdGhpcy5yYW5nZS5sb3c7IGkrKykge1xuXHRcblx0ICAgICAgICAgIHZhciBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcblx0ICAgICAgICAgIHZhciBzY2FsZUluZGV4ID0gKGkgKyB0aGlzLnJhbmdlLmxvdykgJSB0aGlzLmtleVBhdHRlcm4ubGVuZ3RoO1xuXHRcblx0ICAgICAgICAgIHZhciBrZXkgPSBuZXcgUGlhbm9LZXkoY29udGFpbmVyLCB7XG5cdCAgICAgICAgICAgIGNvbXBvbmVudDogdHJ1ZSxcblx0ICAgICAgICAgICAgbm90ZTogaSArIHRoaXMucmFuZ2UubG93LFxuXHQgICAgICAgICAgICBjb2xvcjogdGhpcy5rZXlQYXR0ZXJuW3NjYWxlSW5kZXhdLFxuXHQgICAgICAgICAgICBtb2RlOiB0aGlzLm1vZGVcblx0ICAgICAgICAgIH0sIHRoaXMua2V5Q2hhbmdlLmJpbmQodGhpcywgaSArIHRoaXMucmFuZ2UubG93KSk7XG5cdFxuXHQgICAgICAgICAga2V5LnBpYW5vID0gdGhpcztcblx0XG5cdCAgICAgICAgICBpZiAodG91Y2guZXhpc3RzKSB7XG5cdCAgICAgICAgICAgIGtleS5wYWQuaW5kZXggPSBpO1xuXHQgICAgICAgICAgICBrZXkucHJlQ2xpY2sgPSBrZXkucHJlTW92ZSA9IGtleS5wcmVSZWxlYXNlID0gZnVuY3Rpb24gKCkge307XG5cdCAgICAgICAgICAgIGtleS5jbGljayA9IGtleS5tb3ZlID0ga2V5LnJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7fTtcblx0ICAgICAgICAgICAga2V5LnByZVRvdWNoID0ga2V5LnByZVRvdWNoTW92ZSA9IGtleS5wcmVUb3VjaFJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7fTtcblx0ICAgICAgICAgICAga2V5LnRvdWNoID0ga2V5LnRvdWNoTW92ZSA9IGtleS50b3VjaFJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7fTtcblx0ICAgICAgICAgIH1cblx0XG5cdCAgICAgICAgICB0aGlzLmtleXMucHVzaChrZXkpO1xuXHQgICAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICh0b3VjaC5leGlzdHMpIHtcblx0ICAgICAgICAgIHRoaXMuYWRkVG91Y2hMaXN0ZW5lcnMoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzaXplSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBzaXplSW50ZXJmYWNlKCkge1xuXHRcblx0ICAgICAgICB2YXIga2V5WCA9IDA7XG5cdFxuXHQgICAgICAgIHZhciBrZXlQb3NpdGlvbnMgPSBbXTtcblx0XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnJhbmdlLmhpZ2ggLSB0aGlzLnJhbmdlLmxvdzsgaSsrKSB7XG5cdFxuXHQgICAgICAgICAga2V5UG9zaXRpb25zLnB1c2goa2V5WCk7XG5cdFxuXHQgICAgICAgICAgdmFyIHNjYWxlSW5kZXggPSAoaSArIHRoaXMucmFuZ2UubG93KSAlIHRoaXMua2V5UGF0dGVybi5sZW5ndGg7XG5cdCAgICAgICAgICB2YXIgbmV4dFNjYWxlSW5kZXggPSAoaSArIDEgKyB0aGlzLnJhbmdlLmxvdykgJSB0aGlzLmtleVBhdHRlcm4ubGVuZ3RoO1xuXHQgICAgICAgICAgaWYgKGkgKyAxICsgdGhpcy5yYW5nZS5sb3cgPj0gdGhpcy5yYW5nZS5oaWdoKSB7XG5cdCAgICAgICAgICAgIGtleVggKz0gMTtcblx0ICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5rZXlQYXR0ZXJuW3NjYWxlSW5kZXhdID09PSBcIndcIiAmJiB0aGlzLmtleVBhdHRlcm5bbmV4dFNjYWxlSW5kZXhdID09PSBcIndcIikge1xuXHQgICAgICAgICAgICBrZXlYICs9IDE7XG5cdCAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBrZXlYICs9IDAuNTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgdmFyIGtleXNXaWRlID0ga2V5WDtcblx0XG5cdCAgICAgICAgLy8gIGxldCBwYWRkaW5nID0gdGhpcy53aWR0aCAvIDEyMDtcblx0ICAgICAgICB2YXIgcGFkZGluZyA9IDE7XG5cdCAgICAgICAgdmFyIGJ1dHRvbldpZHRoID0gKHRoaXMud2lkdGggLSBwYWRkaW5nICogMikgLyBrZXlzV2lkZTtcblx0ICAgICAgICB2YXIgYnV0dG9uSGVpZ2h0ID0gKHRoaXMuaGVpZ2h0IC0gcGFkZGluZyAqIDIpIC8gMjtcblx0XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmtleXMubGVuZ3RoOyBpKyspIHtcblx0XG5cdCAgICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5rZXlzW2ldLnBhcmVudDtcblx0ICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcblx0ICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS5sZWZ0ID0ga2V5UG9zaXRpb25zW2ldICogYnV0dG9uV2lkdGggKyBwYWRkaW5nICsgXCJweFwiO1xuXHQgICAgICAgICAgaWYgKHRoaXMua2V5c1tpXS5jb2xvciA9PT0gXCJ3XCIpIHtcblx0ICAgICAgICAgICAgY29udGFpbmVyLnN0eWxlLnRvcCA9IHBhZGRpbmcgKyBcInB4XCI7XG5cdCAgICAgICAgICAgIHRoaXMua2V5c1tpXS5yZXNpemUoYnV0dG9uV2lkdGgsIGJ1dHRvbkhlaWdodCAqIDIpO1xuXHQgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgY29udGFpbmVyLnN0eWxlLnpJbmRleCA9IDE7XG5cdCAgICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSBwYWRkaW5nICsgXCJweFwiO1xuXHQgICAgICAgICAgICB0aGlzLmtleXNbaV0ucmVzaXplKGJ1dHRvbldpZHRoLCBidXR0b25IZWlnaHQgKiAxLjEpO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNvbG9ySW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb2xvckludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgLy8gUGlhbm8ga2V5cyBkb24ndCBhY3R1YWxseSBoYXZlIGEgc3Ryb2tlIGJvcmRlclxuXHQgICAgICAgIC8vIFRoZXkgaGF2ZSBzcGFjZSBiZXR3ZWVuIHRoZW0sIHdoaWNoIHNob3dzIHRoZSBQaWFubyBiZyBjb2xvclxuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodDtcblx0XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmtleXMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgIHRoaXMua2V5c1tpXS5jb2xvcnMgPSB7XG5cdCAgICAgICAgICAgIHc6IHRoaXMuY29sb3JzLmxpZ2h0LFxuXHQgICAgICAgICAgICBiOiB0aGlzLmNvbG9ycy5kYXJrLFxuXHQgICAgICAgICAgICBhY2NlbnQ6IHRoaXMuY29sb3JzLmFjY2VudCxcblx0ICAgICAgICAgICAgYm9yZGVyOiB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodFxuXHQgICAgICAgICAgfTtcblx0ICAgICAgICAgIHRoaXMua2V5c1tpXS5jb2xvckludGVyZmFjZSgpO1xuXHQgICAgICAgICAgdGhpcy5rZXlzW2ldLnJlbmRlcigpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGtleUNoYW5nZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24ga2V5Q2hhbmdlKG5vdGUsIG9uKSB7XG5cdCAgICAgICAgLy8gZW1pdCBkYXRhIGZvciBhbnkga2V5IHR1cm5pbmcgb24vb2ZmXG5cdCAgICAgICAgLy8gXCJub3RlXCIgaXMgdGhlIG5vdGUgdmFsdWVcblx0ICAgICAgICAvLyBcIm9uXCIgaXMgYSBib29sZWFuIHdoZXRoZXIgaXQgaXMgb24gb3Igb2ZmXG5cdCAgICAgICAgLy8gaW4gYWZ0ZXJ0b3VjaCBtb2RlLCBcIm9uOiBpcyBhbiBvYmplY3Qgd2l0aCBzdGF0ZS94L3kgcHJvcGVydGllc1xuXHQgICAgICAgIHZhciBkYXRhID0ge1xuXHQgICAgICAgICAgbm90ZTogbm90ZVxuXHQgICAgICAgIH07XG5cdCAgICAgICAgaWYgKHR5cGVvZiBvbiA9PT0gXCJvYmplY3RcIikge1xuXHQgICAgICAgICAgZGF0YS5zdGF0ZSA9IG9uLnN0YXRlO1xuXHQgICAgICAgICAgLy8gIGRhdGEueCA9IG9uLnhcblx0ICAgICAgICAgIC8vICBkYXRhLnkgPSBvbi55XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIGRhdGEuc3RhdGUgPSBvbjtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIGRhdGEpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcmVuZGVyOiB7XG5cdFxuXHQgICAgICAvKiBkcmFnKG5vdGUsb24pIHtcblx0ICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScse1xuXHQgICAgICAgICAgbm90ZTogbm90ZSxcblx0ICAgICAgICAgIHN0YXRlOiBvblxuXHQgICAgICAgIH0pO1xuXHQgICAgICB9ICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge31cblx0ICAgIH0sXG5cdCAgICBhZGRUb3VjaExpc3RlbmVyczoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gYWRkVG91Y2hMaXN0ZW5lcnMoKSB7XG5cdCAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblx0XG5cdCAgICAgICAgdGhpcy5wcmVDbGljayA9IHRoaXMucHJlTW92ZSA9IHRoaXMucHJlUmVsZWFzZSA9IGZ1bmN0aW9uICgpIHt9O1xuXHQgICAgICAgIHRoaXMuY2xpY2sgPSB0aGlzLm1vdmUgPSB0aGlzLnJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7fTtcblx0ICAgICAgICB0aGlzLnByZVRvdWNoID0gdGhpcy5wcmVUb3VjaE1vdmUgPSB0aGlzLnByZVRvdWNoUmVsZWFzZSA9IGZ1bmN0aW9uICgpIHt9O1xuXHQgICAgICAgIHRoaXMudG91Y2ggPSB0aGlzLnRvdWNoTW92ZSA9IHRoaXMudG91Y2hSZWxlYXNlID0gZnVuY3Rpb24gKCkge307XG5cdFxuXHQgICAgICAgIHRoaXMuY3VycmVudEVsZW1lbnQgPSBmYWxzZTtcblx0XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIGZ1bmN0aW9uIChlKSB7XG5cdCAgICAgICAgICBjb25zb2xlLmxvZyhcInRvdWNoc3RhcnRcIik7XG5cdCAgICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFgsIGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRZKTtcblx0ICAgICAgICAgIHZhciBrZXkgPSBfdGhpcy5rZXlzW2VsZW1lbnQuaW5kZXhdO1xuXHQgICAgICAgICAgX3RoaXMucGFpbnRicnVzaCA9ICFrZXkuc3RhdGU7XG5cdCAgICAgICAgICBrZXkuZG93bihfdGhpcy5wYWludGJydXNoKTtcblx0ICAgICAgICAgIF90aGlzLmN1cnJlbnRFbGVtZW50ID0gZWxlbWVudC5pbmRleDtcblx0ICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblx0ICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdCAgICAgICAgfSk7XG5cdFxuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIGZ1bmN0aW9uIChlKSB7XG5cdCAgICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFgsIGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRZKTtcblx0ICAgICAgICAgIHZhciBrZXkgPSBfdGhpcy5rZXlzW2VsZW1lbnQuaW5kZXhdO1xuXHQgICAgICAgICAgaWYgKGVsZW1lbnQuaW5kZXggIT09IF90aGlzLmN1cnJlbnRFbGVtZW50KSB7XG5cdCAgICAgICAgICAgIGlmIChfdGhpcy5jdXJyZW50RWxlbWVudCkge1xuXHQgICAgICAgICAgICAgIHZhciBwYXN0S2V5ID0gX3RoaXMua2V5c1tfdGhpcy5jdXJyZW50RWxlbWVudF07XG5cdCAgICAgICAgICAgICAgcGFzdEtleS51cCgpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGtleS5kb3duKF90aGlzLnBhaW50YnJ1c2gpO1xuXHQgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAga2V5LmJlbmQoKTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICAgIF90aGlzLmN1cnJlbnRFbGVtZW50ID0gZWxlbWVudC5pbmRleDtcblx0ICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblx0ICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdCAgICAgICAgfSk7XG5cdFxuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgZnVuY3Rpb24gKGUpIHtcblx0ICAgICAgICAgIC8vIG5vIHRvdWNoZXMgdG8gY2FsY3VsYXRlIGJlY2F1c2Ugbm9uZSByZW1haW5pbmdcblx0ICAgICAgICAgIHZhciBrZXkgPSBfdGhpcy5rZXlzW190aGlzLmN1cnJlbnRFbGVtZW50XTtcblx0ICAgICAgICAgIGtleS51cCgpO1xuXHQgICAgICAgICAgX3RoaXMuaW50ZXJhY3RpbmcgPSBmYWxzZTtcblx0ICAgICAgICAgIF90aGlzLmN1cnJlbnRFbGVtZW50ID0gZmFsc2U7XG5cdCAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cdCAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2V0UmFuZ2U6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBEZWZpbmUgdGhlIHBpdGNoIHJhbmdlIChsb3dlc3QgYW5kIGhpZ2hlc3Qgbm90ZSkgb2YgdGhlIHBpYW5vIGtleWJvYXJkLlxuXHQgICAgICBAcGFyYW0gbG93IHtudW1iZXJ9IE1JREkgbm90ZSB2YWx1ZSBvZiB0aGUgbG93ZXN0IG5vdGUgb24gdGhlIGtleWJvYXJkXG5cdCAgICAgIEBwYXJhbSBoaWdoIHtudW1iZXJ9IE1JREkgbm90ZSB2YWx1ZSBvZiB0aGUgaGlnaGVzdCBub3RlIG9uIHRoZSBrZXlib2FyZFxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNldFJhbmdlKGxvdywgaGlnaCkge1xuXHQgICAgICAgIHRoaXMucmFuZ2UubG93ID0gbG93O1xuXHQgICAgICAgIHRoaXMucmFuZ2UuaGlnaCA9IGhpZ2g7XG5cdCAgICAgICAgdGhpcy5lbXB0eSgpO1xuXHQgICAgICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHRvZ2dsZUtleToge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFR1cm4gYSBrZXkgb24gb3Igb2ZmIHVzaW5nIGl0cyBNSURJIG5vdGUgdmFsdWU7XG5cdCAgICAgIEBwYXJhbSBub3RlIHtudW1iZXJ9IE1JREkgbm90ZSB2YWx1ZSBvZiB0aGUga2V5IHRvIGNoYW5nZVxuXHQgICAgICBAcGFyYW0gb24ge2Jvb2xlYW59IFdoZXRoZXIgdGhlIG5vdGUgc2hvdWxkIHR1cm4gb24gb3Igb2ZmXG5cdCAgICAgICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gdG9nZ2xlS2V5KG5vdGUsIG9uKSB7XG5cdCAgICAgICAgdGhpcy5rZXlzW25vdGUgLSB0aGlzLnJhbmdlLmxvd10uZmxpcChvbik7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICB0b2dnbGVJbmRleDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFR1cm4gYSBrZXkgb24gb3Igb2ZmIHVzaW5nIGl0cyBrZXkgaW5kZXggb24gdGhlIHBpYW5vIGludGVyZmFjZS5cblx0ICAgICAgQHBhcmFtIGluZGV4IHtudW1iZXJ9IEluZGV4IG9mIHRoZSBrZXkgdG8gY2hhbmdlXG5cdCAgICAgIEBwYXJhbSBvbiB7Ym9vbGVhbn0gV2hldGhlciB0aGUgbm90ZSBzaG91bGQgdHVybiBvbiBvciBvZmZcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiB0b2dnbGVJbmRleChpbmRleCwgb24pIHtcblx0ICAgICAgICB0aGlzLmtleXNbaW5kZXhdLmZsaXAob24pO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSk7XG5cdFxuXHQgIHJldHVybiBQaWFubztcblx0fSkoSW50ZXJmYWNlKTtcblx0XG5cdG1vZHVsZS5leHBvcnRzID0gUGlhbm87XG5cdFxuXHQvLyBsb29wIHRocm91Z2ggYW5kIHJlbmRlciB0aGUga2V5cz9cblxuLyoqKi8gfSksXG4vKiAyNCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9nZXQgPSBmdW5jdGlvbiBnZXQob2JqZWN0LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpIHsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyByZXR1cm4gZ2V0KHBhcmVudCwgcHJvcGVydHksIHJlY2VpdmVyKTsgfSB9IGVsc2UgaWYgKFwidmFsdWVcIiBpbiBkZXNjICYmIGRlc2Mud3JpdGFibGUpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9O1xuXHRcblx0dmFyIF9pbmhlcml0cyA9IGZ1bmN0aW9uIChzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9O1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIHN2ZyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7XG5cdHZhciBkb20gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDcpO1xuXHR2YXIgSW50ZXJmYWNlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2KTtcblx0dmFyIEJ1dHRvblRlbXBsYXRlID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNyk7XG5cdHZhciBNYXRyaXhNb2RlbCA9IF9fd2VicGFja19yZXF1aXJlX18oMjUpO1xuXHR2YXIgQ291bnRlck1vZGVsID0gX193ZWJwYWNrX3JlcXVpcmVfXygyOCk7XG5cdHZhciB0b3VjaCA9IF9fd2VicGFja19yZXF1aXJlX18oOSk7XG5cdFxuXHR2YXIgTWF0cml4Q2VsbCA9IChmdW5jdGlvbiAoX0J1dHRvblRlbXBsYXRlKSB7XG5cdCAgZnVuY3Rpb24gTWF0cml4Q2VsbCgpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBNYXRyaXhDZWxsKTtcblx0XG5cdCAgICB2YXIgb3B0aW9ucyA9IFtcInZhbHVlXCJdO1xuXHRcblx0ICAgIHZhciBkZWZhdWx0cyA9IHtcblx0ICAgICAgc2l6ZTogWzgwLCA4MF0sXG5cdCAgICAgIHRhcmdldDogZmFsc2UsXG5cdCAgICAgIG1vZGU6IFwidG9nZ2xlXCIsXG5cdCAgICAgIHZhbHVlOiAwXG5cdCAgICB9O1xuXHRcblx0ICAgIF9nZXQoT2JqZWN0LmdldFByb3RvdHlwZU9mKE1hdHJpeENlbGwucHJvdG90eXBlKSwgXCJjb25zdHJ1Y3RvclwiLCB0aGlzKS5jYWxsKHRoaXMsIGFyZ3VtZW50cywgb3B0aW9ucywgZGVmYXVsdHMpO1xuXHRcblx0ICAgIHRoaXMuaW5kZXggPSB0aGlzLnNldHRpbmdzLmluZGV4O1xuXHQgICAgdGhpcy5yb3cgPSB0aGlzLnNldHRpbmdzLnJvdztcblx0ICAgIHRoaXMuY29sdW1uID0gdGhpcy5zZXR0aW5ncy5jb2x1bW47XG5cdFxuXHQgICAgdGhpcy5tYXRyaXggPSB0aGlzLnNldHRpbmdzLm1hdHJpeDtcblx0XG5cdCAgICB0aGlzLmludGVyYWN0aW5nID0gZmFsc2U7XG5cdCAgICB0aGlzLnBhaW50YnJ1c2ggPSBmYWxzZTtcblx0XG5cdCAgICB0aGlzLmluaXQoKTtcblx0ICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgfVxuXHRcblx0ICBfaW5oZXJpdHMoTWF0cml4Q2VsbCwgX0J1dHRvblRlbXBsYXRlKTtcblx0XG5cdCAgX2NyZWF0ZUNsYXNzKE1hdHJpeENlbGwsIHtcblx0ICAgIGJ1aWxkRnJhbWU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkRnJhbWUoKSB7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50ID0gc3ZnLmNyZWF0ZShcInN2Z1wiKTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgdGhpcy53aWR0aCk7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCB0aGlzLmhlaWdodCk7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLnRvcCA9IFwiMHB4XCI7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmxlZnQgPSBcIjBweFwiO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcblx0ICAgICAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgYnVpbGRJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkSW50ZXJmYWNlKCkge1xuXHQgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgICAgIHRoaXMucGFkID0gc3ZnLmNyZWF0ZShcInJlY3RcIik7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMucGFkKTtcblx0XG5cdCAgICAgICAgdGhpcy5pbnRlcmFjdGlvblRhcmdldCA9IHRoaXMucGFkO1xuXHRcblx0ICAgICAgICAvKiBldmVudHMgKi9cblx0XG5cdCAgICAgICAgaWYgKCF0b3VjaC5leGlzdHMpIHtcblx0XG5cdCAgICAgICAgICB0aGlzLmNsaWNrID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBfdGhpcy5tYXRyaXguaW50ZXJhY3RpbmcgPSB0cnVlO1xuXHQgICAgICAgICAgICBfdGhpcy5tYXRyaXgucGFpbnRicnVzaCA9ICFfdGhpcy5zdGF0ZTtcblx0ICAgICAgICAgICAgX3RoaXMuZG93bihfdGhpcy5tYXRyaXgucGFpbnRicnVzaCk7XG5cdCAgICAgICAgICB9O1xuXHQgICAgICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlb3ZlclwiLCBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIGlmIChfdGhpcy5tYXRyaXguaW50ZXJhY3RpbmcpIHtcblx0ICAgICAgICAgICAgICBfdGhpcy5kb3duKF90aGlzLm1hdHJpeC5wYWludGJydXNoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgfSk7XG5cdFxuXHQgICAgICAgICAgdGhpcy5tb3ZlID0gZnVuY3Rpb24gKCkge307XG5cdCAgICAgICAgICB0aGlzLnBhZC5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIGZ1bmN0aW9uIChlKSB7XG5cdCAgICAgICAgICAgIGlmIChfdGhpcy5tYXRyaXguaW50ZXJhY3RpbmcpIHtcblx0ICAgICAgICAgICAgICBpZiAoIV90aGlzLm9mZnNldCkge1xuXHQgICAgICAgICAgICAgICAgX3RoaXMub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbihfdGhpcy5lbGVtZW50KTtcblx0ICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgX3RoaXMubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSwgX3RoaXMub2Zmc2V0KTtcblx0ICAgICAgICAgICAgICBfdGhpcy5iZW5kKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgIH0pO1xuXHRcblx0ICAgICAgICAgIHRoaXMucmVsZWFzZSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgX3RoaXMubWF0cml4LmludGVyYWN0aW5nID0gZmFsc2U7XG5cdCAgICAgICAgICB9O1xuXHQgICAgICAgICAgdGhpcy5wYWQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBpZiAoX3RoaXMubWF0cml4LmludGVyYWN0aW5nKSB7XG5cdCAgICAgICAgICAgICAgX3RoaXMudXAoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgfSk7XG5cdCAgICAgICAgICB0aGlzLnBhZC5hZGRFdmVudExpc3RlbmVyKFwibW91c2VvdXRcIiwgZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBpZiAoX3RoaXMubWF0cml4LmludGVyYWN0aW5nKSB7XG5cdCAgICAgICAgICAgICAgX3RoaXMudXAoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2l6ZUludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc2l6ZUludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwieFwiLCAxKTtcblx0ICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoXCJ5XCIsIDEpO1xuXHQgICAgICAgIGlmICh0aGlzLndpZHRoID4gMikge1xuXHQgICAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgdGhpcy53aWR0aCAtIDIpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiLCB0aGlzLndpZHRoKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKHRoaXMuaGVpZ2h0ID4gMikge1xuXHQgICAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIHRoaXMuaGVpZ2h0IC0gMik7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCB0aGlzLmhlaWdodCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vdGhpcy5wYWQuc2V0QXR0cmlidXRlKCdoZWlnaHQnLCB0aGlzLmhlaWdodCAtIDIpO1xuXHQgICAgICAgIHRoaXMucGFkLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdGhpcy5tYXRyaXguY29sb3JzLmZpbGwpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcmVuZGVyOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cdCAgICAgICAgaWYgKCF0aGlzLnN0YXRlKSB7XG5cdCAgICAgICAgICB0aGlzLnBhZC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMubWF0cml4LmNvbG9ycy5maWxsKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdGhpcy5wYWQuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCB0aGlzLm1hdHJpeC5jb2xvcnMuYWNjZW50KTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIE1hdHJpeENlbGw7XG5cdH0pKEJ1dHRvblRlbXBsYXRlKTtcblx0XG5cdC8qKlxuXHQqIFNlcXVlbmNlclxuXHQqXG5cdCogQGRlc2NyaXB0aW9uIEdyaWQgb2YgYnV0dG9ucyB3aXRoIGJ1aWx0LWluIHN0ZXAgc2VxdWVuY2VyLlxuXHQqXG5cdCogQGRlbW8gPGRpdiBuZXh1cy11aT1cInNlcXVlbmNlclwiIHN0eWxlPVwid2lkdGg6NDAwcHg7aGVpZ2h0OjIwMHB4O1wiPjwvZGl2PlxuXHQqXG5cdCogQGV4YW1wbGVcblx0KiB2YXIgc2VxdWVuY2VyID0gbmV3IE5leHVzLlNlcXVlbmNlcignI3RhcmdldCcpXG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciBzZXF1ZW5jZXIgPSBuZXcgTmV4dXMuU2VxdWVuY2VyKCcjdGFyZ2V0Jyx7XG5cdCogICdzaXplJzogWzQwMCwyMDBdLFxuXHQqICAnbW9kZSc6ICd0b2dnbGUnLFxuXHQqICAncm93cyc6IDUsXG5cdCogICdjb2x1bW5zJzogMTBcblx0Kn0pXG5cdCpcblx0KiBAb3V0cHV0XG5cdCogY2hhbmdlXG5cdCogRmlyZXMgYW55IHRpbWUgdGhlIGludGVyZmFjZSdzIG1hdHJpeCBjaGFuZ2VzLiA8YnI+XG5cdCogVGhlIGV2ZW50IGRhdGEgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgPGk+cm93PC9pPiAobnVtYmVyKSwgPGk+Y29sdW1uPC9pPiAobnVtYmVyKSwgYW5kIDxpPnN0YXRlPC9pPiAoYm9vbGVhbikgcHJvcGVydGllcy5cblx0KlxuXHQqIEBvdXRwdXRleGFtcGxlXG5cdCogc2VxdWVuY2VyLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcblx0KiAgIGNvbnNvbGUubG9nKHYpO1xuXHQqIH0pXG5cdCpcblx0KiBAb3V0cHV0XG5cdCogc3RlcFxuXHQqIEZpcmVzIGFueSB0aW1lIHRoZSBzZXF1ZW5jZXIgc3RlcHMgdG8gdGhlIG5leHQgY29sdW1uLCBpbiBzZXF1ZWNlIG1vZGUuIDxicj5cblx0KiBUaGUgZXZlbnQgZGF0YSBpcyBhbiA8aT5hcnJheTwvaT4gY29udGFpbmluZyBhbGwgdmFsdWVzIGluIHRoZSBjb2x1bW4sIDxpPmJvdHRvbSByb3cgZmlyc3Q8L2k+LlxuXHQqXG5cdCogQG91dHB1dGV4YW1wbGVcblx0KiBzZXF1ZW5jZXIub24oJ3N0ZXAnLGZ1bmN0aW9uKHYpIHtcblx0KiAgIGNvbnNvbGUubG9nKHYpO1xuXHQqIH0pXG5cdCovXG5cdFxuXHR2YXIgU2VxdWVuY2VyID0gKGZ1bmN0aW9uIChfSW50ZXJmYWNlKSB7XG5cdCAgZnVuY3Rpb24gU2VxdWVuY2VyKCkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFNlcXVlbmNlcik7XG5cdFxuXHQgICAgdmFyIG9wdGlvbnMgPSBbXCJ2YWx1ZVwiXTtcblx0XG5cdCAgICB2YXIgZGVmYXVsdHMgPSB7XG5cdCAgICAgIHNpemU6IFs0MDAsIDIwMF0sXG5cdCAgICAgIG1vZGU6IFwidG9nZ2xlXCIsXG5cdCAgICAgIHJvd3M6IDUsXG5cdCAgICAgIGNvbHVtbnM6IDEwXG5cdCAgICB9O1xuXHRcblx0ICAgIF9nZXQoT2JqZWN0LmdldFByb3RvdHlwZU9mKFNlcXVlbmNlci5wcm90b3R5cGUpLCBcImNvbnN0cnVjdG9yXCIsIHRoaXMpLmNhbGwodGhpcywgYXJndW1lbnRzLCBvcHRpb25zLCBkZWZhdWx0cyk7XG5cdFxuXHQgICAgdGhpcy5hY3RpdmUgPSAtMTtcblx0XG5cdCAgICAvKipcblx0ICAgICogQnV0dG9uIGludGVyYWN0aW9uIG1vZGU6IHNlZSBCdXR0b25cblx0ICAgICogQHR5cGUge3N0cmluZ31cblx0ICAgICogQGV4YW1wbGUgYnV0dG9uLm1vZGUgPSAndG9nZ2xlJztcblx0ICAgICovXG5cdCAgICB0aGlzLm1vZGUgPSB0aGlzLnNldHRpbmdzLm1vZGU7XG5cdFxuXHQgICAgLyoqXG5cdCAgICAqIFRoZSBpbnRlcnZhbCBvYmplY3Qgd2hpY2ggY29udHJvbHMgdGltaW5nIGFuZCBzZXF1ZW5jZSBzY2hlZHVsaW5nLlxuXHQgICAgKiBAdHlwZSB7aW50ZXJ2YWx9XG5cdCAgICAqL1xuXHQgICAgdGhpcy5pbnRlcnZhbCA9IG5ldyBOZXh1cy5JbnRlcnZhbCgyMDAsIGZ1bmN0aW9uICgpIHt9LCBmYWxzZSk7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuXHRcblx0ICAgIC8qKlxuXHQgICAgKiBBIE1hdHJpeCBtb2RlbCBjb250YWluaW5nIG1ldGhvZHMgZm9yIG1hbmlwdWxhdGluZyB0aGUgc2VxdWVuY2VyJ3MgYXJyYXkgb2YgdmFsdWVzLiBUbyBsZWFybiBob3cgdG8gbWFuaXB1bGF0ZSB0aGUgbWF0cml4LCByZWFkIGFib3V0IHRoZSBtYXRyaXggbW9kZWwuXG5cdCAgICAqIEB0eXBlIHttYXRyaXh9XG5cdCAgICAqL1xuXHQgICAgdGhpcy5tYXRyaXggPSBuZXcgTWF0cml4TW9kZWwodGhpcy5zZXR0aW5ncy5yb3dzLCB0aGlzLnNldHRpbmdzLmNvbHVtbnMpO1xuXHQgICAgdGhpcy5tYXRyaXgudWkgPSB0aGlzO1xuXHRcblx0ICAgIC8qKlxuXHQgICAgKiBBIENvdW50ZXIgbW9kZWwgd2hpY2ggdGhlIHNlcXVlbmNlciBzdGVwcyB0aHJvdWdoLiBGb3IgZXhhbXBsZSwgeW91IGNvdWxkIHVzZSB0aGlzIG1vZGVsIHRvIHN0ZXAgdGhyb3VnaCB0aGUgc2VxdWVuY2VyIGluIHJldmVyc2UsIHJhbmRvbWx5LCBvciBpbiBhIGRydW5rIHdhbGsuXG5cdCAgICAqIEB0eXBlIHtjb3VudGVyfVxuXHQgICAgKi9cblx0ICAgIHRoaXMuc3RlcHBlciA9IG5ldyBDb3VudGVyTW9kZWwoMCwgdGhpcy5jb2x1bW5zKTtcblx0XG5cdCAgICB0aGlzLmluaXQoKTtcblx0ICB9XG5cdFxuXHQgIF9pbmhlcml0cyhTZXF1ZW5jZXIsIF9JbnRlcmZhY2UpO1xuXHRcblx0ICBfY3JlYXRlQ2xhc3MoU2VxdWVuY2VyLCB7XG5cdCAgICBidWlsZEZyYW1lOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBidWlsZEZyYW1lKCkge1xuXHQgICAgICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBcIjEwMCVcIjtcblx0ICAgICAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXHQgICAgICAgIGlmICh0b3VjaC5leGlzdHMpIHtcblx0ICAgICAgICAgIHRoaXMuYWRkVG91Y2hMaXN0ZW5lcnMoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBidWlsZEludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gYnVpbGRJbnRlcmZhY2UoKSB7XG5cdFxuXHQgICAgICAgIHRoaXMuY2VsbHMgPSBbXTtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubWF0cml4Lmxlbmd0aDsgaSsrKSB7XG5cdFxuXHQgICAgICAgICAgdmFyIF9sb2NhdGlvbiA9IHRoaXMubWF0cml4LmxvY2F0ZShpKTtcblx0ICAgICAgICAgIC8vIHJldHVybnMge3Jvdyxjb2x9XG5cdFxuXHQgICAgICAgICAgdmFyIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuXHQgICAgICAgICAgY29udGFpbmVyLnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xuXHRcblx0ICAgICAgICAgIHZhciBjZWxsID0gbmV3IE1hdHJpeENlbGwoY29udGFpbmVyLCB7XG5cdCAgICAgICAgICAgIGNvbXBvbmVudDogdHJ1ZSxcblx0ICAgICAgICAgICAgaW5kZXg6IGksXG5cdCAgICAgICAgICAgIHJvdzogX2xvY2F0aW9uLnJvdyxcblx0ICAgICAgICAgICAgY29sdW1uOiBfbG9jYXRpb24uY29sdW1uLFxuXHQgICAgICAgICAgICBtb2RlOiB0aGlzLm1vZGUsXG5cdCAgICAgICAgICAgIG1hdHJpeDogdGhpc1xuXHQgICAgICAgICAgfSwgdGhpcy5rZXlDaGFuZ2UuYmluZCh0aGlzLCBpKSk7XG5cdFxuXHQgICAgICAgICAgLy8gIGNlbGwubWF0cml4ID0gdGhpcztcblx0ICAgICAgICAgIGlmICh0b3VjaC5leGlzdHMpIHtcblx0ICAgICAgICAgICAgY2VsbC5wYWQuaW5kZXggPSBpO1xuXHQgICAgICAgICAgICBjZWxsLnByZUNsaWNrID0gY2VsbC5wcmVNb3ZlID0gY2VsbC5wcmVSZWxlYXNlID0gZnVuY3Rpb24gKCkge307XG5cdCAgICAgICAgICAgIGNlbGwuY2xpY2sgPSBjZWxsLm1vdmUgPSBjZWxsLnJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7fTtcblx0ICAgICAgICAgICAgY2VsbC5wcmVUb3VjaCA9IGNlbGwucHJlVG91Y2hNb3ZlID0gY2VsbC5wcmVUb3VjaFJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7fTtcblx0ICAgICAgICAgICAgY2VsbC50b3VjaCA9IGNlbGwudG91Y2hNb3ZlID0gY2VsbC50b3VjaFJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7fTtcblx0ICAgICAgICAgIH1cblx0XG5cdCAgICAgICAgICB0aGlzLmNlbGxzLnB1c2goY2VsbCk7XG5cdCAgICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5zaXplSW50ZXJmYWNlKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzaXplSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBzaXplSW50ZXJmYWNlKCkge1xuXHRcblx0ICAgICAgICB2YXIgY2VsbFdpZHRoID0gdGhpcy53aWR0aCAvIHRoaXMuY29sdW1ucztcblx0ICAgICAgICB2YXIgY2VsbEhlaWdodCA9IHRoaXMuaGVpZ2h0IC8gdGhpcy5yb3dzO1xuXHRcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuY2VsbHMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmNlbGxzW2ldLnBhcmVudDtcblx0ICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gdGhpcy5jZWxsc1tpXS5jb2x1bW4gKiBjZWxsV2lkdGggKyBcInB4XCI7XG5cdCAgICAgICAgICBjb250YWluZXIuc3R5bGUudG9wID0gdGhpcy5jZWxsc1tpXS5yb3cgKiBjZWxsSGVpZ2h0ICsgXCJweFwiO1xuXHQgICAgICAgICAgdGhpcy5jZWxsc1tpXS5yZXNpemUoY2VsbFdpZHRoLCBjZWxsSGVpZ2h0KTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjb2xvckludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY29sb3JJbnRlcmZhY2UoKSB7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmNlbGxzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICB0aGlzLmNlbGxzW2ldLnJlbmRlcigpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHVwZGF0ZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gdXBkYXRlKCkge1xuXHQgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgICAgIC8vICBjb25zb2xlLmxvZyhcInVwZGF0aW5nLi4uXCIpXG5cdCAgICAgICAgLy9vbiA9IG9uIHx8IGZhbHNlO1xuXHQgICAgICAgIHRoaXMubWF0cml4Lml0ZXJhdGUoZnVuY3Rpb24gKHIsIGMsIGkpIHtcblx0ICAgICAgICAgIC8vICBjb25zb2xlLmxvZyh0aGlzLm1hdHJpeC5wYXR0ZXJuW3JdW2NdLCB0aGlzLmNlbGxzW2ldLnN0YXRlKTtcblx0ICAgICAgICAgIGlmIChfdGhpcy5tYXRyaXgucGF0dGVybltyXVtjXSAhPT0gX3RoaXMuY2VsbHNbaV0uc3RhdGUpIHtcblx0ICAgICAgICAgICAgaWYgKF90aGlzLm1hdHJpeC5wYXR0ZXJuW3JdW2NdID4gMCkge1xuXHQgICAgICAgICAgICAgIF90aGlzLmNlbGxzW2ldLnR1cm5PbigpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgIF90aGlzLmNlbGxzW2ldLnR1cm5PZmYoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAga2V5Q2hhbmdlOiB7XG5cdFxuXHQgICAgICAvLyB1cGRhdGUgPT4gY2VsbC50dXJuT24gPT4gY2VsbC5lbWl0ID0+IGtleUNoYW5nZSAoc2VxLmVtaXQpID0+IG1hdHJpeC5zZXQuY2VsbCA9PiB1cGRhdGVcblx0ICAgICAgLy9cblx0ICAgICAgLy8gaW50ZXJhY3Rpb24gPT4ga2V5Q2hhbmdlID0+IG1hdHJpeC5zZXQuY2VsbCA9PiB1cGRhdGUgPT4gY2VsbC50dXJuT25cblx0ICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiBlbWl0XG5cdCAgICAgIC8vXG5cdCAgICAgIC8vIHNldC5jZWxsID0+IHVwZGF0ZSA9PiBuZWVkcyB0byBlbWl0LlxuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGtleUNoYW5nZShub3RlLCBvbikge1xuXHQgICAgICAgIC8vIGVtaXQgZGF0YSBmb3IgYW55IGtleSB0dXJuaW5nIG9uL29mZlxuXHQgICAgICAgIC8vIGkgaXMgdGhlIG5vdGUgaW5kZXhcblx0ICAgICAgICAvLyB2IGlzIHdoZXRoZXIgaXQgaXMgb24gb3Igb2ZmXG5cdCAgICAgICAgdmFyIGNlbGwgPSB0aGlzLm1hdHJpeC5sb2NhdGUobm90ZSk7XG5cdCAgICAgICAgLy8gIHRoaXMubWF0cml4LnNldC5jZWxsKGNlbGwuY29sdW1uLGNlbGwucm93LG9uKTtcblx0ICAgICAgICB0aGlzLm1hdHJpeC5wYXR0ZXJuW2NlbGwucm93XVtjZWxsLmNvbHVtbl0gPSBvbjtcblx0ICAgICAgICB2YXIgZGF0YSA9IHtcblx0ICAgICAgICAgIHJvdzogY2VsbC5yb3csXG5cdCAgICAgICAgICBjb2x1bW46IGNlbGwuY29sdW1uLFxuXHQgICAgICAgICAgc3RhdGU6IG9uXG5cdCAgICAgICAgfTtcblx0ICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgZGF0YSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByZW5kZXI6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcblx0ICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICAgICBpZiAodGhpcy5zdGVwcGVyLnZhbHVlID49IDApIHtcblx0ICAgICAgICAgIHRoaXMubWF0cml4Lml0ZXJhdGUoZnVuY3Rpb24gKHIsIGMsIGkpIHtcblx0ICAgICAgICAgICAgaWYgKGMgPT09IF90aGlzLnN0ZXBwZXIudmFsdWUpIHtcblx0ICAgICAgICAgICAgICBfdGhpcy5jZWxsc1tpXS5wYWQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIF90aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG5cdCAgICAgICAgICAgICAgX3RoaXMuY2VsbHNbaV0ucGFkLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBcIjFcIik7XG5cdCAgICAgICAgICAgICAgX3RoaXMuY2VsbHNbaV0ucGFkLnNldEF0dHJpYnV0ZShcInN0cm9rZS1vcGFjaXR5XCIsIFwiMVwiKTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICBfdGhpcy5jZWxsc1tpXS5wYWQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwibm9uZVwiKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc3RhcnQ6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICAgKiBTdGFydCBzZXF1ZW5jaW5nXG5cdCAgICAgICAqIEBwYXJhbSAge251bWJlcn0gbXMgQmVhdCB0ZW1wbyBpbiBtaWxsaXNlY29uZHNcblx0ICAgICAgICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc3RhcnQobXMpIHtcblx0ICAgICAgICB0aGlzLmludGVydmFsLmV2ZW50ID0gdGhpcy5uZXh0LmJpbmQodGhpcyk7XG5cdCAgICAgICAgaWYgKG1zKSB7XG5cdCAgICAgICAgICB0aGlzLmludGVydmFsLm1zKG1zKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5pbnRlcnZhbC5zdGFydCgpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc3RvcDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFN0b3Agc2VxdWVuY2luZ1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHN0b3AoKSB7XG5cdCAgICAgICAgdGhpcy5pbnRlcnZhbC5zdG9wKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBuZXh0OiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgTWFudWFsbHkganVtcCB0byB0aGUgbmV4dCBjb2x1bW4gYW5kIHRyaWdnZXIgdGhlICdjaGFuZ2UnIGV2ZW50LiBUaGUgXCJuZXh0XCIgY29sdW1uIGlzIGRldGVybWluZWQgYnkgeW91ciBtb2RlIG9mIHNlcXVlbmNpbmcuXG5cdCAgICAgICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gbmV4dCgpIHtcblx0ICAgICAgICB0aGlzLnN0ZXBwZXIubmV4dCgpO1xuXHQgICAgICAgIHRoaXMuZW1pdChcInN0ZXBcIiwgdGhpcy5tYXRyaXguY29sdW1uKHRoaXMuc3RlcHBlci52YWx1ZSkucmV2ZXJzZSgpKTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgYWRkVG91Y2hMaXN0ZW5lcnM6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGFkZFRvdWNoTGlzdGVuZXJzKCkge1xuXHQgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7fTtcblx0ICAgICAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gZnVuY3Rpb24gKCkge307XG5cdCAgICAgICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7fTtcblx0ICAgICAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9IGZ1bmN0aW9uICgpIHt9O1xuXHRcblx0ICAgICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZmFsc2U7XG5cdFxuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCBmdW5jdGlvbiAoZSkge1xuXHQgICAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRYLCBlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG5cdCAgICAgICAgICB2YXIgY2VsbCA9IF90aGlzLmNlbGxzW2VsZW1lbnQuaW5kZXhdO1xuXHQgICAgICAgICAgX3RoaXMucGFpbnRicnVzaCA9ICFjZWxsLnN0YXRlO1xuXHQgICAgICAgICAgY2VsbC5kb3duKF90aGlzLnBhaW50YnJ1c2gpO1xuXHQgICAgICAgICAgX3RoaXMuY3VycmVudEVsZW1lbnQgPSBlbGVtZW50LmluZGV4O1xuXHQgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblx0ICAgICAgICB9KTtcblx0XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgZnVuY3Rpb24gKGUpIHtcblx0ICAgICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCwgZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFkpO1xuXHQgICAgICAgICAgdmFyIGNlbGwgPSBfdGhpcy5jZWxsc1tlbGVtZW50LmluZGV4XTtcblx0ICAgICAgICAgIGlmIChlbGVtZW50LmluZGV4ICE9PSBfdGhpcy5jdXJyZW50RWxlbWVudCkge1xuXHQgICAgICAgICAgICBpZiAoX3RoaXMuY3VycmVudEVsZW1lbnQgPj0gMCkge1xuXHQgICAgICAgICAgICAgIHZhciBwYXN0Q2VsbCA9IF90aGlzLmNlbGxzW190aGlzLmN1cnJlbnRFbGVtZW50XTtcblx0ICAgICAgICAgICAgICBwYXN0Q2VsbC51cCgpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNlbGwuZG93bihfdGhpcy5wYWludGJydXNoKTtcblx0ICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIGNlbGwuYmVuZCgpO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgICAgX3RoaXMuY3VycmVudEVsZW1lbnQgPSBlbGVtZW50LmluZGV4O1xuXHQgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblx0ICAgICAgICB9KTtcblx0XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCBmdW5jdGlvbiAoZSkge1xuXHQgICAgICAgICAgLy8gbm8gdG91Y2hlcyB0byBjYWxjdWxhdGUgYmVjYXVzZSBub25lIHJlbWFpbmluZ1xuXHQgICAgICAgICAgdmFyIGNlbGwgPSBfdGhpcy5jZWxsc1tfdGhpcy5jdXJyZW50RWxlbWVudF07XG5cdCAgICAgICAgICBjZWxsLnVwKCk7XG5cdCAgICAgICAgICBfdGhpcy5pbnRlcmFjdGluZyA9IGZhbHNlO1xuXHQgICAgICAgICAgX3RoaXMuY3VycmVudEVsZW1lbnQgPSBmYWxzZTtcblx0ICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblx0ICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByb3dzOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgTnVtYmVyIG9mIHJvd3MgaW4gdGhlIHNlcXVlbmNlclxuXHQgICAgICBAdHlwZSB7bnVtYmVyfVxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMubWF0cml4LnJvd3M7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLm1hdHJpeC5yb3dzID0gdjtcblx0ICAgICAgICB0aGlzLmVtcHR5KCk7XG5cdCAgICAgICAgdGhpcy5idWlsZEludGVyZmFjZSgpO1xuXHQgICAgICAgIHRoaXMudXBkYXRlKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjb2x1bW5zOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgTnVtYmVyIG9mIGNvbHVtbnMgaW4gdGhlIHNlcXVlbmNlclxuXHQgICAgICBAdHlwZSB7bnVtYmVyfVxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMubWF0cml4LmNvbHVtbnM7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLm1hdHJpeC5jb2x1bW5zID0gdjtcblx0ICAgICAgICB0aGlzLnN0ZXBwZXIubWF4ID0gdjtcblx0ICAgICAgICB0aGlzLmVtcHR5KCk7XG5cdCAgICAgICAgdGhpcy5idWlsZEludGVyZmFjZSgpO1xuXHQgICAgICAgIHRoaXMudXBkYXRlKCk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIFNlcXVlbmNlcjtcblx0fSkoSW50ZXJmYWNlKTtcblx0XG5cdG1vZHVsZS5leHBvcnRzID0gU2VxdWVuY2VyO1xuXG4vKioqLyB9KSxcbi8qIDI1ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgX2ludGVyb3BSZXF1aXJlID0gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqW1wiZGVmYXVsdFwiXSA6IG9iajsgfTtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdHZhciBtYXRoID0gX2ludGVyb3BSZXF1aXJlKF9fd2VicGFja19yZXF1aXJlX18oNSkpO1xuXHRcblx0dmFyIFNlcXVlbmNlID0gX2ludGVyb3BSZXF1aXJlKF9fd2VicGFja19yZXF1aXJlX18oMjYpKTtcblx0XG5cdC8vIEZvciB0aGUgdHV0b3JpYWwsIGxvb2tpbmcgYXRcblx0XG5cdC8vUGF0dGVybiBzZWN0aW9uOlxuXHQvLyAuY3JlYXRlKCksIC5yb3dzLCAuY29sdW1ucyxcblx0Ly8gLnBhdHRlcm4sIC5sZW5ndGgsIC5mb3JtYXRBc1RleHQoKSwgLmxvZygpLFxuXHQvLyAubG9jYXRlKGkpLCAuaW5kZXhPZihjLHIpXG5cdC8vIHJvdygpLCBjb2x1bW4oKSAocmV0dXJucyBjb250ZW50cyBvZiByb3cgb3IgY29sdW0pXG5cdFxuXHQvL0NvbnRyb2wgc2VjdGlvbjpcblx0Ly8gdG9nZ2xlIHgzXG5cdC8vIHNldCB4NFxuXHQvLyByb3RhdGUgeDNcblx0Ly8gcG9wdWxhdGUgeDNcblx0Ly8gZXJhc2UgeDNcblx0XG5cdC8vIHNob3VsZCBzb21lIHZlcnNpb24gb2YgdGhpcyBoYXZlIGEgZmxvYXQgdmFsdWUgZm9yIGVhY2ggY2VsbD9cblx0Ly8gY291bGQgYmUgbGlrZSBhIG1pcnJvciAucGF0dGVybiB0aGF0IGhhcyB2YWx1ZXMuIGJ5IGRlZmF1bHQsIGV2ZXJ5dGhpbmcgaXMgMSwgYnV0IGNvdWxkIGJlIHNldC4uLlxuXHQvLyBub3QgYSBnb29kIHdheSB0byBkbyB0aGF0IG9uIGludGVyZmFjZSwgYnV0IGFzIGEgbW9kZWwgaXQgd291bGQgYmUgbmljZS4uLlxuXHQvLyBmb3IgLmZvcm1hdEFzVGV4dCgpLCBjb3VsZCBtdWx0aXBseSBieSAxMDAgYW5kIGZsb29yLCBzbyBlYWNoIGNlbGwgaXMgYW4gaW50IGZyb20gMCB0byA5XG5cdFxuXHR2YXIgTWF0cml4ID0gKGZ1bmN0aW9uICgpIHtcblx0ICBmdW5jdGlvbiBNYXRyaXgocm93cywgY29sdW1ucykge1xuXHQgICAgdmFyIF90aGlzID0gdGhpcztcblx0XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTWF0cml4KTtcblx0XG5cdCAgICAvLyBzaG91bGQgYWxzbyBoYXZlIGFiaWxpdHkgdG8gY3JlYXRlIHVzaW5nIGFuIGV4aXN0aW5nIG1hdHJpeCAoMmQgYXJyYXkpXG5cdCAgICB0aGlzLnBhdHRlcm4gPSBbXTtcblx0ICAgIHRoaXMuY3JlYXRlKHJvd3MsIGNvbHVtbnMpO1xuXHRcblx0ICAgIHRoaXMudG9nZ2xlID0ge1xuXHQgICAgICBjZWxsOiBmdW5jdGlvbiAoY29sdW1uLCByb3cpIHtcblx0ICAgICAgICBfdGhpcy5wYXR0ZXJuW3Jvd11bY29sdW1uXSA9ICFfdGhpcy5wYXR0ZXJuW3Jvd11bY29sdW1uXTsgLy8gbWF0aC5pbnZlcnQodGhpcy5wYXR0ZXJuW3Jvd11bY29sdW1uXSk7XG5cdCAgICAgICAgaWYgKF90aGlzLnVpKSB7XG5cdCAgICAgICAgICBfdGhpcy51aS51cGRhdGUoKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIF90aGlzLnBhdHRlcm5bcm93XVtjb2x1bW5dO1xuXHQgICAgICB9LFxuXHQgICAgICBhbGw6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBfdGhpcy5pdGVyYXRlKGZ1bmN0aW9uIChyLCBjKSB7XG5cdCAgICAgICAgICBfdGhpcy50b2dnbGUuY2VsbChjLCByKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBpZiAoX3RoaXMudWkpIHtcblx0ICAgICAgICAgIF90aGlzLnVpLnVwZGF0ZSgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSxcblx0ICAgICAgcm93OiBmdW5jdGlvbiAocm93KSB7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBfdGhpcy5jb2x1bW5zOyBpKyspIHtcblx0ICAgICAgICAgIF90aGlzLnRvZ2dsZS5jZWxsKGksIHJvdyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChfdGhpcy51aSkge1xuXHQgICAgICAgICAgX3RoaXMudWkudXBkYXRlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9LFxuXHQgICAgICBjb2x1bW46IGZ1bmN0aW9uIChjb2x1bW4pIHtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IF90aGlzLnJvd3M7IGkrKykge1xuXHQgICAgICAgICAgX3RoaXMudG9nZ2xlLmNlbGwoY29sdW1uLCBpKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKF90aGlzLnVpKSB7XG5cdCAgICAgICAgICBfdGhpcy51aS51cGRhdGUoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH07XG5cdFxuXHQgICAgdGhpcy5zZXQgPSB7XG5cdCAgICAgIGNlbGw6IGZ1bmN0aW9uIChjb2x1bW4sIHJvdywgdmFsdWUpIHtcblx0ICAgICAgICBfdGhpcy5wYXR0ZXJuW3Jvd11bY29sdW1uXSA9IHZhbHVlO1xuXHQgICAgICAgIGlmIChfdGhpcy51aSkge1xuXHQgICAgICAgICAgX3RoaXMudWkudXBkYXRlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9LFxuXHQgICAgICBhbGw6IGZ1bmN0aW9uICh2YWx1ZXMpIHtcblx0ICAgICAgICAvLyBzZXQgdGhlIHdob2xlIG1hdHJpeCB1c2luZyBhIDJkIGFycmF5IGFzIGlucHV0XG5cdCAgICAgICAgLy8gdGhpcyBzaG91bGQgYWxzbyByZXNpemUgdGhlIGFycmF5P1xuXHQgICAgICAgIF90aGlzLnBhdHRlcm4gPSB2YWx1ZXM7XG5cdCAgICAgICAgaWYgKF90aGlzLnVpKSB7XG5cdCAgICAgICAgICBfdGhpcy51aS51cGRhdGUoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH0sXG5cdCAgICAgIHJvdzogZnVuY3Rpb24gKHJvdywgdmFsdWVzKSB7XG5cdCAgICAgICAgLy8gc2V0IGEgcm93IHVzaW5nIGFuIGFycmF5IGFzIGlucHV0XG5cdCAgICAgICAgX3RoaXMucGF0dGVybltyb3ddID0gdmFsdWVzO1xuXHQgICAgICAgIGlmIChfdGhpcy51aSkge1xuXHQgICAgICAgICAgX3RoaXMudWkudXBkYXRlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9LFxuXHQgICAgICBjb2x1bW46IGZ1bmN0aW9uIChjb2x1bW4sIHZhbHVlcykge1xuXHQgICAgICAgIC8vIHNldCBhIGNvbHVtbiB1c2luZyBhbiBhcnJheSBhcyBpbnB1dFxuXHQgICAgICAgIF90aGlzLnBhdHRlcm4uZm9yRWFjaChmdW5jdGlvbiAocm93LCBpKSB7XG5cdCAgICAgICAgICBfdGhpcy5wYXR0ZXJuW2ldW2NvbHVtbl0gPSB2YWx1ZXNbaV07XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgaWYgKF90aGlzLnVpKSB7XG5cdCAgICAgICAgICBfdGhpcy51aS51cGRhdGUoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH07XG5cdFxuXHQgICAgdGhpcy5yb3RhdGUgPSB7XG5cdCAgICAgIC8vc2hvdWxkIGV2ZW50dWFsbHkgZG8gKGFtb3VudFgsIGFtb3VudFkpIGhlcmVcblx0ICAgICAgLy8gY291bGQganVzdCB1c2UgYSBsb29wIGFuZCB0aGlzLnJvdGF0ZS5yb3coaSxhbW91bnRYKTtcblx0ICAgICAgYWxsOiBmdW5jdGlvbiAoYW1vdW50KSB7XG5cdCAgICAgICAgaWYgKCFhbW91bnQgJiYgYW1vdW50ICE9PSAwKSB7XG5cdCAgICAgICAgICBhbW91bnQgPSAxO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBhbW91bnQgJT0gX3RoaXMucGF0dGVyblswXS5sZW5ndGg7XG5cdCAgICAgICAgaWYgKGFtb3VudCA8IDApIHtcblx0ICAgICAgICAgIGFtb3VudCA9IF90aGlzLnBhdHRlcm5bMF0ubGVuZ3RoICsgYW1vdW50O1xuXHQgICAgICAgIH1cblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IF90aGlzLnJvd3M7IGkrKykge1xuXHQgICAgICAgICAgdmFyIGN1dCA9IF90aGlzLnBhdHRlcm5baV0uc3BsaWNlKF90aGlzLnBhdHRlcm5baV0ubGVuZ3RoIC0gYW1vdW50LCBhbW91bnQpO1xuXHQgICAgICAgICAgX3RoaXMucGF0dGVybltpXSA9IGN1dC5jb25jYXQoX3RoaXMucGF0dGVybltpXSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChfdGhpcy51aSkge1xuXHQgICAgICAgICAgX3RoaXMudWkudXBkYXRlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9LFxuXHQgICAgICByb3c6IGZ1bmN0aW9uIChyb3csIGFtb3VudCkge1xuXHQgICAgICAgIGlmICghYW1vdW50ICYmIGFtb3VudCAhPT0gMCkge1xuXHQgICAgICAgICAgYW1vdW50ID0gMTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgYW1vdW50ICU9IF90aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuXHQgICAgICAgIGlmIChhbW91bnQgPCAwKSB7XG5cdCAgICAgICAgICBhbW91bnQgPSBfdGhpcy5wYXR0ZXJuWzBdLmxlbmd0aCArIGFtb3VudDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdmFyIGN1dCA9IF90aGlzLnBhdHRlcm5bcm93XS5zcGxpY2UoX3RoaXMucGF0dGVybltyb3ddLmxlbmd0aCAtIGFtb3VudCwgYW1vdW50KTtcblx0ICAgICAgICBfdGhpcy5wYXR0ZXJuW3Jvd10gPSBjdXQuY29uY2F0KF90aGlzLnBhdHRlcm5bcm93XSk7XG5cdCAgICAgICAgaWYgKF90aGlzLnVpKSB7XG5cdCAgICAgICAgICBfdGhpcy51aS51cGRhdGUoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH0sXG5cdCAgICAgIGNvbHVtbjogZnVuY3Rpb24gKGNvbHVtbiwgYW1vdW50KSB7XG5cdCAgICAgICAgaWYgKCFhbW91bnQgJiYgYW1vdW50ICE9PSAwKSB7XG5cdCAgICAgICAgICBhbW91bnQgPSAxO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBhbW91bnQgJT0gX3RoaXMucGF0dGVybi5sZW5ndGg7XG5cdCAgICAgICAgaWYgKGFtb3VudCA8IDApIHtcblx0ICAgICAgICAgIGFtb3VudCA9IF90aGlzLnBhdHRlcm4ubGVuZ3RoICsgYW1vdW50O1xuXHQgICAgICAgIH1cblx0ICAgICAgICB2YXIgcHJveHkgPSBbXTtcblx0ICAgICAgICBfdGhpcy5wYXR0ZXJuLmZvckVhY2goZnVuY3Rpb24gKHJvdykge1xuXHQgICAgICAgICAgcHJveHkucHVzaChyb3dbY29sdW1uXSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdmFyIGN1dCA9IHByb3h5LnNwbGljZShwcm94eS5sZW5ndGggLSBhbW91bnQsIGFtb3VudCk7XG5cdCAgICAgICAgcHJveHkgPSBjdXQuY29uY2F0KHByb3h5KTtcblx0ICAgICAgICBfdGhpcy5wYXR0ZXJuLmZvckVhY2goZnVuY3Rpb24gKHJvdywgaSkge1xuXHQgICAgICAgICAgcm93W2NvbHVtbl0gPSBwcm94eVtpXTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBpZiAoX3RoaXMudWkpIHtcblx0ICAgICAgICAgIF90aGlzLnVpLnVwZGF0ZSgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfTtcblx0XG5cdCAgICAvLyB0aGUgaWRlYSBiZWhpbmQgcG9wdWxhdGUgaXMgdG8gYmUgYWJsZSB0byBzZXQgYSB3aG9sZSByb3cgb3IgY29sdW1uIHRvIDAgb3IgMVxuXHQgICAgLy8gSUYgdGhlIHZhbHVlIGlzIGEgZmxvYXQsIHN1Y2ggYXMgMC43LCB0aGVuIGl0IHdvdWxkIGJlY29tZSBhIHByb2JhYmlsaXR5XG5cdCAgICAvLyBzbyBwb3B1bGF0ZSgwLjcpIHdvdWxkIGdpdmUgZWFjaCBjZWxsIGEgNzAlIGNoYW5jZSBvZiBiZWluZyAxXG5cdCAgICB0aGlzLnBvcHVsYXRlID0ge1xuXHQgICAgICBhbGw6IGZ1bmN0aW9uIChvZGRzKSB7XG5cdCAgICAgICAgdmFyIG9kZHNTZXF1ZW5jZSA9IG5ldyBTZXF1ZW5jZShvZGRzKTtcblx0ICAgICAgICBfdGhpcy5pdGVyYXRlKGZ1bmN0aW9uIChyLCBjKSB7XG5cdCAgICAgICAgICBfdGhpcy5wYXR0ZXJuW3JdW2NdID0gbWF0aC5jb2luKG9kZHNTZXF1ZW5jZS5uZXh0KCkpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIC8vIFRoaXMgY291bGQgYmUgdXNlZCBzbyB0aGF0IGVhY2ggcm93IGhhcyBzYW1lIG9kZHMgcGF0dGVybiwgZXZlbiBpZiByb3cgbGVuZ3RoIGlzIG5vdCBkaXZpc2libHkgYnkgc2VxdWVuY2UgbGVuZ3RoLlxuXHQgICAgICAgIC8vLCgpID0+IHtcblx0ICAgICAgICAvLyAgb2Rkcy5wb3MgPSAtMTtcblx0ICAgICAgICAvLyB9XG5cdCAgICAgICAgaWYgKF90aGlzLnVpKSB7XG5cdCAgICAgICAgICBfdGhpcy51aS51cGRhdGUoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH0sXG5cdCAgICAgIHJvdzogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciByb3cgPSBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IDAgOiBhcmd1bWVudHNbMF07XG5cdCAgICAgICAgdmFyIG9kZHMgPSBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCA/IDEgOiBhcmd1bWVudHNbMV07XG5cdFxuXHQgICAgICAgIHZhciBvZGRzU2VxdWVuY2UgPSBuZXcgU2VxdWVuY2Uob2Rkcyk7XG5cdCAgICAgICAgX3RoaXMucGF0dGVybltyb3ddLmZvckVhY2goZnVuY3Rpb24gKGNlbGwsIGkpIHtcblx0ICAgICAgICAgIF90aGlzLnBhdHRlcm5bcm93XVtpXSA9IG1hdGguY29pbihvZGRzU2VxdWVuY2UubmV4dCgpKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBpZiAoX3RoaXMudWkpIHtcblx0ICAgICAgICAgIF90aGlzLnVpLnVwZGF0ZSgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSxcblx0ICAgICAgY29sdW1uOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIGNvbHVtbiA9IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gMCA6IGFyZ3VtZW50c1swXTtcblx0ICAgICAgICB2YXIgb2RkcyA9IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gMSA6IGFyZ3VtZW50c1sxXTtcblx0XG5cdCAgICAgICAgdmFyIG9kZHNTZXF1ZW5jZSA9IG5ldyBTZXF1ZW5jZShvZGRzKTtcblx0ICAgICAgICBfdGhpcy5wYXR0ZXJuLmZvckVhY2goZnVuY3Rpb24gKHJvdywgaSkge1xuXHQgICAgICAgICAgX3RoaXMucGF0dGVybltpXVtjb2x1bW5dID0gbWF0aC5jb2luKG9kZHNTZXF1ZW5jZS5uZXh0KCkpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGlmIChfdGhpcy51aSkge1xuXHQgICAgICAgICAgX3RoaXMudWkudXBkYXRlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9O1xuXHRcblx0ICAgIC8vIGVzc2VudGlhbGwgcG9wdWxhdGUoMCkgc28gaSdtIG5vdCBzdXJlIGlmIHRoaXMgaXMgbmVjZXNzYXJ5IGJ1dCBpcyBuaWNlXG5cdCAgICB0aGlzLmVyYXNlID0ge1xuXHQgICAgICBhbGw6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBfdGhpcy5zZXQuYWxsKDApO1xuXHQgICAgICB9LFxuXHQgICAgICByb3c6IGZ1bmN0aW9uIChyb3cpIHtcblx0ICAgICAgICBfdGhpcy5zZXQucm93KHJvdywgMCk7XG5cdCAgICAgIH0sXG5cdCAgICAgIGNvbHVtbjogZnVuY3Rpb24gKGNvbHVtbikge1xuXHQgICAgICAgIF90aGlzLnNldC5jb2x1bW4oY29sdW1uLCAwKTtcblx0ICAgICAgfVxuXHQgICAgfTtcblx0XG5cdCAgICAvLyBlbmQgY29uc3RydWN0b3Jcblx0ICB9XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhNYXRyaXgsIHtcblx0ICAgIGNyZWF0ZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlKHJvd3MsIGNvbHVtbnMpIHtcblx0ICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICAgICB0aGlzLnBhdHRlcm4gPSBbXTtcblx0ICAgICAgICBmb3IgKHZhciByb3cgPSAwOyByb3cgPCByb3dzOyByb3crKykge1xuXHQgICAgICAgICAgdmFyIGFyciA9IG5ldyBBcnJheShjb2x1bW5zKTtcblx0ICAgICAgICAgIHRoaXMucGF0dGVybi5wdXNoKGFycik7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuaXRlcmF0ZShmdW5jdGlvbiAociwgYykge1xuXHQgICAgICAgICAgX3RoaXMucGF0dGVybltyXVtjXSA9IGZhbHNlO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgaXRlcmF0ZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gaXRlcmF0ZShmLCBmMikge1xuXHQgICAgICAgIHZhciBpID0gMDtcblx0ICAgICAgICBmb3IgKHZhciByb3cgPSAwOyByb3cgPCB0aGlzLnJvd3M7IHJvdysrKSB7XG5cdCAgICAgICAgICBpZiAoZjIpIHtcblx0ICAgICAgICAgICAgZjIocm93KTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICAgIGZvciAodmFyIGNvbHVtbiA9IDA7IGNvbHVtbiA8IHRoaXMuY29sdW1uczsgY29sdW1uKyspIHtcblx0ICAgICAgICAgICAgZihyb3csIGNvbHVtbiwgaSk7XG5cdCAgICAgICAgICAgIGkrKztcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBmb3JtYXRBc1RleHQ6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZvcm1hdEFzVGV4dCgpIHtcblx0ICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICAgICB2YXIgcGF0dGVyblN0cmluZyA9IFwiXCI7XG5cdCAgICAgICAgdGhpcy5pdGVyYXRlKGZ1bmN0aW9uIChyLCBjKSB7XG5cdCAgICAgICAgICBwYXR0ZXJuU3RyaW5nICs9IChfdGhpcy5wYXR0ZXJuW3JdW2NdID8gMSA6IDApICsgXCIgXCI7XG5cdCAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgcGF0dGVyblN0cmluZyArPSBcIlxcblwiO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBwYXR0ZXJuU3RyaW5nO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbG9nOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBsb2coKSB7XG5cdCAgICAgICAgY29uc29sZS5sb2codGhpcy5mb3JtYXRBc1RleHQoKSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICB1cGRhdGU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHVwZGF0ZShwYXR0ZXJuKSB7XG5cdCAgICAgICAgdGhpcy5wYXR0ZXJuID0gcGF0dGVybiB8fCB0aGlzLnBhdHRlcm47XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBsZW5ndGg6IHtcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMucm93cyAqIHRoaXMuY29sdW1ucztcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGxvY2F0ZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gbG9jYXRlKGluZGV4KSB7XG5cdCAgICAgICAgLy8gcmV0dXJucyByb3cgYW5kIGNvbHVtbiBvZiBjZWxsIGJ5IGluZGV4XG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgIHJvdzogfiB+KGluZGV4IC8gdGhpcy5jb2x1bW5zKSxcblx0ICAgICAgICAgIGNvbHVtbjogaW5kZXggJSB0aGlzLmNvbHVtbnNcblx0ICAgICAgICB9O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgaW5kZXhPZjoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gaW5kZXhPZihyb3csIGNvbHVtbikge1xuXHQgICAgICAgIHJldHVybiBjb2x1bW4gKyByb3cgKiB0aGlzLmNvbHVtbnM7XG5cdCAgICAgICAgLy8gcmV0dXJucyBpbmRleCBvZiBjZWxsIGJ5IHJvdyBhbmQgY29sdW1uXG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByb3c6IHtcblx0ICAgICAgdmFsdWU6IChmdW5jdGlvbiAoX3Jvdykge1xuXHQgICAgICAgIHZhciBfcm93V3JhcHBlciA9IGZ1bmN0aW9uIHJvdyhfeCkge1xuXHQgICAgICAgICAgcmV0dXJuIF9yb3cuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0ICAgICAgICB9O1xuXHRcblx0ICAgICAgICBfcm93V3JhcHBlci50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgIHJldHVybiBfcm93LnRvU3RyaW5nKCk7XG5cdCAgICAgICAgfTtcblx0XG5cdCAgICAgICAgcmV0dXJuIF9yb3dXcmFwcGVyO1xuXHQgICAgICB9KShmdW5jdGlvbiAocm93KSB7XG5cdCAgICAgICAgdmFyIGRhdGEgPSBbXTtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuY29sdW1uczsgaSsrKSB7XG5cdCAgICAgICAgICBkYXRhLnB1c2godGhpcy5wYXR0ZXJuW3Jvd10gPyAxIDogMCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBkYXRhO1xuXHQgICAgICB9KVxuXHQgICAgfSxcblx0ICAgIGNvbHVtbjoge1xuXHQgICAgICB2YWx1ZTogKGZ1bmN0aW9uIChfY29sdW1uKSB7XG5cdCAgICAgICAgdmFyIF9jb2x1bW5XcmFwcGVyID0gZnVuY3Rpb24gY29sdW1uKF94Mikge1xuXHQgICAgICAgICAgcmV0dXJuIF9jb2x1bW4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0ICAgICAgICB9O1xuXHRcblx0ICAgICAgICBfY29sdW1uV3JhcHBlci50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgIHJldHVybiBfY29sdW1uLnRvU3RyaW5nKCk7XG5cdCAgICAgICAgfTtcblx0XG5cdCAgICAgICAgcmV0dXJuIF9jb2x1bW5XcmFwcGVyO1xuXHQgICAgICB9KShmdW5jdGlvbiAoY29sdW1uKSB7XG5cdCAgICAgICAgdmFyIGRhdGEgPSBbXTtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucm93czsgaSsrKSB7XG5cdCAgICAgICAgICBkYXRhLnB1c2godGhpcy5wYXR0ZXJuW2ldW2NvbHVtbl0gPyAxIDogMCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBkYXRhO1xuXHQgICAgICB9KVxuXHQgICAgfSxcblx0ICAgIHJvd3M6IHtcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMucGF0dGVybi5sZW5ndGg7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICAgICB2YXIgcHJldmlvdXMgPSB0aGlzLnBhdHRlcm4uc2xpY2UoMCk7XG5cdCAgICAgICAgdGhpcy5jcmVhdGUodiwgdGhpcy5jb2x1bW5zKTtcblx0ICAgICAgICB0aGlzLml0ZXJhdGUoZnVuY3Rpb24gKHIsIGMpIHtcblx0ICAgICAgICAgIGlmIChwcmV2aW91c1tyXSAmJiBwcmV2aW91c1tyXVtjXSkge1xuXHQgICAgICAgICAgICBfdGhpcy5wYXR0ZXJuW3JdW2NdID0gcHJldmlvdXNbcl1bY107XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjb2x1bW5zOiB7XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLnBhdHRlcm5bMF0ubGVuZ3RoO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblx0XG5cdCAgICAgICAgdmFyIHByZXZpb3VzID0gdGhpcy5wYXR0ZXJuLnNsaWNlKDApO1xuXHQgICAgICAgIHRoaXMuY3JlYXRlKHRoaXMucm93cywgdik7XG5cdCAgICAgICAgdGhpcy5pdGVyYXRlKGZ1bmN0aW9uIChyLCBjKSB7XG5cdCAgICAgICAgICBpZiAocHJldmlvdXNbcl0gJiYgcHJldmlvdXNbcl1bY10pIHtcblx0ICAgICAgICAgICAgX3RoaXMucGF0dGVybltyXVtjXSA9IHByZXZpb3VzW3JdW2NdO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSk7XG5cdFxuXHQgIHJldHVybiBNYXRyaXg7XG5cdH0pKCk7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IE1hdHJpeDtcblxuLyoqKi8gfSksXG4vKiAyNiAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9pbnRlcm9wUmVxdWlyZSA9IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9ialtcImRlZmF1bHRcIl0gOiBvYmo7IH07XG5cdFxuXHR2YXIgX2NyZWF0ZUNsYXNzID0gKGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGtleSBpbiBwcm9wcykgeyB2YXIgcHJvcCA9IHByb3BzW2tleV07IHByb3AuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKHByb3AudmFsdWUpIHByb3Aud3JpdGFibGUgPSB0cnVlOyB9IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpOyB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cdFxuXHR2YXIgX2NsYXNzQ2FsbENoZWNrID0gZnVuY3Rpb24gKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH07XG5cdFxuXHR2YXIgbWF0aCA9IF9pbnRlcm9wUmVxdWlyZShfX3dlYnBhY2tfcmVxdWlyZV9fKDUpKTtcblx0XG5cdHZhciBEcnVuayA9IF9pbnRlcm9wUmVxdWlyZShfX3dlYnBhY2tfcmVxdWlyZV9fKDI3KSk7XG5cdFxuXHR2YXIgU2VxdWVuY2UgPSAoZnVuY3Rpb24gKCkge1xuXHQgIGZ1bmN0aW9uIFNlcXVlbmNlKCkge1xuXHQgICAgdmFyIHNlcXVlbmNlID0gYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyBbMCwgMTAsIDIwLCAzMF0gOiBhcmd1bWVudHNbMF07XG5cdCAgICB2YXIgbW9kZSA9IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gXCJ1cFwiIDogYXJndW1lbnRzWzFdO1xuXHQgICAgdmFyIHBvc2l0aW9uID0gYXJndW1lbnRzWzJdID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IGFyZ3VtZW50c1syXTtcblx0XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgU2VxdWVuY2UpO1xuXHRcblx0ICAgIHRoaXMudmFsdWVzID0gc2VxdWVuY2U7XG5cdCAgICBpZiAoIUFycmF5LmlzQXJyYXkodGhpcy52YWx1ZXMpKSB7XG5cdCAgICAgIHRoaXMudmFsdWVzID0gW3RoaXMudmFsdWVzXTtcblx0ICAgIH1cblx0ICAgIHRoaXMuX21vZGUgPSBtb2RlO1xuXHQgICAgdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xuXHRcblx0ICAgIHRoaXMuZHJ1bmtXYWxrID0gbmV3IERydW5rKDAsIHRoaXMudmFsdWVzLmxlbmd0aCAtIDEpO1xuXHRcblx0ICAgIHRoaXMuc3RhcnRWYWx1ZXMgPSB7XG5cdCAgICAgIHVwOiAwLFxuXHQgICAgICBkb3duOiB0aGlzLnZhbHVlcy5sZW5ndGggLSAxLFxuXHQgICAgICBkcnVuazogfiB+KHRoaXMudmFsdWVzLmxlbmd0aCAvIDIpLFxuXHQgICAgICByYW5kb206IG1hdGgucmkodGhpcy52YWx1ZXMubGVuZ3RoKVxuXHQgICAgfTtcblx0XG5cdCAgICBpZiAodGhpcy5wb3NpdGlvbiAhPT0gZmFsc2UpIHtcblx0ICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIHRoaXMubmV4dCA9IHRoaXMuZmlyc3Q7XG5cdCAgICB9XG5cdCAgfVxuXHRcblx0ICBfY3JlYXRlQ2xhc3MoU2VxdWVuY2UsIHtcblx0ICAgIG1vZGU6IHtcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX21vZGU7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKG1vZGUpIHtcblx0ICAgICAgICBpZiAoIShtb2RlID09PSBcInVwXCIgfHwgbW9kZSA9PT0gXCJkb3duXCIgfHwgbW9kZSA9PT0gXCJyYW5kb21cIiB8fCBtb2RlID09PSBcImRydW5rXCIpKSB7XG5cdCAgICAgICAgICBjb25zb2xlLmVycm9yKFwiVGhlIG9ubHkgbW9kZXMgY3VycmVudGx5IGFsbG93ZWQgYXJlOiB1cCwgZG93biwgcmFuZG9tLCBkcnVua1wiKTtcblx0ICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5fbW9kZSA9IG1vZGU7XG5cdCAgICAgICAgaWYgKHRoaXMucG9zaXRpb24pIHtcblx0ICAgICAgICAgIHRoaXMubmV4dCA9IHRoaXNbdGhpcy5fbW9kZV07XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdmFsdWU6IHtcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVzW3RoaXMucG9zaXRpb25dO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdGhpcy5wb3NpdGlvbiA9IHRoaXMudmFsdWVzLmluZGV4T2Yodik7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBmaXJzdDoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gZmlyc3QoKSB7XG5cdCAgICAgICAgaWYgKHRoaXMucG9zaXRpb24gIT09IGZhbHNlKSB7XG5cdCAgICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xuXHQgICAgICAgICAgcmV0dXJuIHRoaXMubmV4dCgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLnBvc2l0aW9uID0gdGhpcy5zdGFydFZhbHVlc1t0aGlzLl9tb2RlXTtcblx0ICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xuXHQgICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdXA6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHVwKCkge1xuXHQgICAgICAgIHRoaXMucG9zaXRpb24rKztcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uICU9IHRoaXMudmFsdWVzLmxlbmd0aDtcblx0ICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGRvd246IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRvd24oKSB7XG5cdCAgICAgICAgdGhpcy5wb3NpdGlvbi0tO1xuXHQgICAgICAgIGlmICh0aGlzLnBvc2l0aW9uIDwgMCkge1xuXHQgICAgICAgICAgdGhpcy5wb3NpdGlvbiA9ICh0aGlzLnBvc2l0aW9uICsgdGhpcy52YWx1ZXMubGVuZ3RoKSAlIHRoaXMudmFsdWVzLmxlbmd0aDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByYW5kb206IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJhbmRvbSgpIHtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uID0gbWF0aC5yaSgwLCB0aGlzLnZhbHVlcy5sZW5ndGgpO1xuXHQgICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgZHJ1bms6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRydW5rKCkge1xuXHQgICAgICAgIHRoaXMuZHJ1bmtXYWxrLm1heCA9IHRoaXMudmFsdWVzLmxlbmd0aDtcblx0ICAgICAgICB0aGlzLmRydW5rV2Fsay52YWx1ZSA9IHRoaXMucG9zaXRpb247XG5cdCAgICAgICAgdGhpcy5wb3NpdGlvbiA9IHRoaXMuZHJ1bmtXYWxrLm5leHQoKTtcblx0ICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgICAgfVxuXHRcblx0ICAgICAgLyogZnV0dXJlIG1ldGhvZHNcclxuXHQgICAgICAuZ3JvdXAoc3RhcnQsc3RvcCkgLS0gb3V0cHV0cyBhIGdyb3VwIG9mIG4gaXRlbXMgZnJvbSB0aGUgbGlzdCwgd2l0aCB3cmFwcGluZ1xyXG5cdCAgICAgIC5sb29wKHN0YXJ0LHN0b3ApIC0tIGNvbmZpbmVzIHNlcXVlbmNpbmcgdG8gYSBzdWJzZXQgb2YgdGhlIHZhbHVlc1xyXG5cdCAgICAgICAgICAoY291bGQgZXZlbiBoYXZlIGEgZGlzdGluY3Rpb24gYmV0d2VlbiAub3JpZ2luYWxWYWx1ZXMgYW5kIHRoZSBhcnJheSBvZiB2YWx1ZXMgYmVpbmcgdXNlZClcclxuXHQgICAgICAqL1xuXHRcblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIFNlcXVlbmNlO1xuXHR9KSgpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBTZXF1ZW5jZTtcblxuLyoqKi8gfSksXG4vKiAyNyAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9pbnRlcm9wUmVxdWlyZSA9IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9ialtcImRlZmF1bHRcIl0gOiBvYmo7IH07XG5cdFxuXHR2YXIgX2NyZWF0ZUNsYXNzID0gKGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGtleSBpbiBwcm9wcykgeyB2YXIgcHJvcCA9IHByb3BzW2tleV07IHByb3AuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKHByb3AudmFsdWUpIHByb3Aud3JpdGFibGUgPSB0cnVlOyB9IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpOyB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cdFxuXHR2YXIgX2NsYXNzQ2FsbENoZWNrID0gZnVuY3Rpb24gKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH07XG5cdFxuXHR2YXIgbWF0aCA9IF9pbnRlcm9wUmVxdWlyZShfX3dlYnBhY2tfcmVxdWlyZV9fKDUpKTtcblx0XG5cdHZhciBEcnVuayA9IChmdW5jdGlvbiAoKSB7XG5cdCAgICBmdW5jdGlvbiBEcnVuaygpIHtcblx0ICAgICAgICB2YXIgbWluID0gYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyAwIDogYXJndW1lbnRzWzBdO1xuXHQgICAgICAgIHZhciBtYXggPSBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCA/IDkgOiBhcmd1bWVudHNbMV07XG5cdCAgICAgICAgdmFyIHZhbHVlID0gYXJndW1lbnRzWzJdID09PSB1bmRlZmluZWQgPyAwIDogYXJndW1lbnRzWzJdO1xuXHQgICAgICAgIHZhciBpbmNyZW1lbnQgPSBhcmd1bWVudHNbM10gPT09IHVuZGVmaW5lZCA/IDEgOiBhcmd1bWVudHNbM107XG5cdCAgICAgICAgdmFyIGxvb3AgPSBhcmd1bWVudHNbNF0gPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogYXJndW1lbnRzWzRdO1xuXHRcblx0ICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRHJ1bmspO1xuXHRcblx0ICAgICAgICB0aGlzLm1pbiA9IG1pbjtcblx0ICAgICAgICB0aGlzLm1heCA9IG1heDtcblx0ICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG5cdCAgICAgICAgdGhpcy5pbmNyZW1lbnQgPSBpbmNyZW1lbnQ7XG5cdCAgICAgICAgdGhpcy5sb29wID0gbG9vcDtcblx0ICAgIH1cblx0XG5cdCAgICBfY3JlYXRlQ2xhc3MoRHJ1bmssIHtcblx0ICAgICAgICBuZXh0OiB7XG5cdCAgICAgICAgICAgIHZhbHVlOiBmdW5jdGlvbiBuZXh0KCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy52YWx1ZSArPSBtYXRoLnBpY2soLTEgKiB0aGlzLmluY3JlbWVudCwgdGhpcy5pbmNyZW1lbnQpO1xuXHQgICAgICAgICAgICAgICAgaWYgKHRoaXMudmFsdWUgPiB0aGlzLm1heCkge1xuXHQgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmxvb3ApIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluO1xuXHQgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLm1heCAtIHRoaXMuaW5jcmVtZW50O1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0XG5cdCAgICAgICAgICAgICAgICBpZiAodGhpcy52YWx1ZSA8IHRoaXMubWluKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubG9vcCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5tYXg7XG5cdCAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluICsgdGhpcy5pbmNyZW1lbnQ7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0XG5cdCAgICByZXR1cm4gRHJ1bms7XG5cdH0pKCk7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IERydW5rO1xuXG4vKioqLyB9KSxcbi8qIDI4ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgX2ludGVyb3BSZXF1aXJlID0gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqW1wiZGVmYXVsdFwiXSA6IG9iajsgfTtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdHZhciBtYXRoID0gX2ludGVyb3BSZXF1aXJlKF9fd2VicGFja19yZXF1aXJlX18oNSkpO1xuXHRcblx0dmFyIERydW5rID0gX2ludGVyb3BSZXF1aXJlKF9fd2VicGFja19yZXF1aXJlX18oMjcpKTtcblx0XG5cdHZhciBDb3VudGVyID0gKGZ1bmN0aW9uICgpIHtcblx0ICAgIGZ1bmN0aW9uIENvdW50ZXIoKSB7XG5cdCAgICAgICAgdmFyIG1pbiA9IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gMCA6IGFyZ3VtZW50c1swXTtcblx0ICAgICAgICB2YXIgbWF4ID0gYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyAxMCA6IGFyZ3VtZW50c1sxXTtcblx0ICAgICAgICB2YXIgbW9kZSA9IGFyZ3VtZW50c1syXSA9PT0gdW5kZWZpbmVkID8gXCJ1cFwiIDogYXJndW1lbnRzWzJdO1xuXHQgICAgICAgIHZhciB2YWx1ZSA9IGFyZ3VtZW50c1szXSA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBhcmd1bWVudHNbM107XG5cdFxuXHQgICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDb3VudGVyKTtcblx0XG5cdCAgICAgICAgdGhpcy5taW4gPSBtaW47XG5cdCAgICAgICAgdGhpcy5tYXggPSBtYXg7XG5cdCAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuXHQgICAgICAgIHRoaXMubW9kZSA9IG1vZGU7XG5cdCAgICAgICAgdGhpcy5kcnVua1dhbGsgPSBuZXcgRHJ1bmsodGhpcy5taW4sIHRoaXMubWF4KTtcblx0ICAgICAgICBpZiAodGhpcy52YWx1ZSAhPT0gZmFsc2UpIHtcblx0ICAgICAgICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0aGlzLm5leHQgPSB0aGlzLmZpcnN0O1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0XG5cdCAgICBfY3JlYXRlQ2xhc3MoQ291bnRlciwge1xuXHQgICAgICAgIG1vZGU6IHtcblx0ICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAobW9kZSkge1xuXHQgICAgICAgICAgICAgICAgaWYgKCEobW9kZSA9PT0gXCJ1cFwiIHx8IG1vZGUgPT09IFwiZG93blwiIHx8IG1vZGUgPT09IFwicmFuZG9tXCIgfHwgbW9kZSA9PT0gXCJkcnVua1wiKSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJUaGUgb25seSBtb2RlcyBjdXJyZW50bHkgYWxsb3dlZCBhcmU6IHVwLCBkb3duLCByYW5kb20sIGRydW5rXCIpO1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHRoaXMuX21vZGUgPSBtb2RlO1xuXHQgICAgICAgICAgICAgICAgaWYgKHRoaXMudmFsdWUpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb2RlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBmaXJzdDoge1xuXHQgICAgICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZmlyc3QoKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAodGhpcy52YWx1ZSAhPT0gZmFsc2UpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLm5leHQgPSB0aGlzW3RoaXMuX21vZGVdO1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5leHQoKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHRoaXMuc3RhcnRWYWx1ZXMgPSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdXA6IHRoaXMubWluLFxuXHQgICAgICAgICAgICAgICAgICAgIGRvd246IHRoaXMubWF4LFxuXHQgICAgICAgICAgICAgICAgICAgIGRydW5rOiB+IH5tYXRoLmF2ZXJhZ2UodGhpcy5taW4sIHRoaXMubWF4KSxcblx0ICAgICAgICAgICAgICAgICAgICByYW5kb206IG1hdGgucmkodGhpcy5taW4sIHRoaXMubWF4KVxuXHQgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLnN0YXJ0VmFsdWVzW3RoaXMuX21vZGVdO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5uZXh0ID0gdGhpc1t0aGlzLl9tb2RlXTtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICB1cDoge1xuXHQgICAgICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdXAoKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnZhbHVlKys7XG5cdCAgICAgICAgICAgICAgICBpZiAodGhpcy52YWx1ZSA+PSB0aGlzLm1heCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLm1pbjtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBkb3duOiB7XG5cdCAgICAgICAgICAgIHZhbHVlOiBmdW5jdGlvbiBkb3duKCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy52YWx1ZS0tO1xuXHQgICAgICAgICAgICAgICAgaWYgKHRoaXMudmFsdWUgPCB0aGlzLm1pbikge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLm1heDtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICByYW5kb206IHtcblx0ICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJhbmRvbSgpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSBtYXRoLnJpKHRoaXMubWluLCB0aGlzLm1heCk7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZHJ1bms6IHtcblx0ICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRydW5rKCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5kcnVua1dhbGsubWluID0gdGhpcy5taW47XG5cdCAgICAgICAgICAgICAgICB0aGlzLmRydW5rV2Fsay5tYXggPSB0aGlzLm1heDtcblx0ICAgICAgICAgICAgICAgIHRoaXMuZHJ1bmtXYWxrLnZhbHVlID0gdGhpcy52YWx1ZTtcblx0ICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLmRydW5rV2Fsay5uZXh0KCk7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHRcblx0ICAgIHJldHVybiBDb3VudGVyO1xuXHR9KSgpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBDb3VudGVyO1xuXG4vKioqLyB9KSxcbi8qIDI5ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQgPSBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IFwiZGVmYXVsdFwiOiBvYmogfTsgfTtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KG9iamVjdCwgcHJvcGVydHksIHJlY2VpdmVyKSB7IHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHByb3BlcnR5KTsgaWYgKGRlc2MgPT09IHVuZGVmaW5lZCkgeyB2YXIgcGFyZW50ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCk7IGlmIChwYXJlbnQgPT09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBlbHNlIHsgcmV0dXJuIGdldChwYXJlbnQsIHByb3BlcnR5LCByZWNlaXZlcik7IH0gfSBlbHNlIGlmIChcInZhbHVlXCIgaW4gZGVzYyAmJiBkZXNjLndyaXRhYmxlKSB7IHJldHVybiBkZXNjLnZhbHVlOyB9IGVsc2UgeyB2YXIgZ2V0dGVyID0gZGVzYy5nZXQ7IGlmIChnZXR0ZXIgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IHJldHVybiBnZXR0ZXIuY2FsbChyZWNlaXZlcik7IH0gfTtcblx0XG5cdHZhciBfaW5oZXJpdHMgPSBmdW5jdGlvbiAoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSBcImZ1bmN0aW9uXCIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCBcIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdHZhciBzdmcgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpO1xuXHR2YXIgbWF0aCA9IF9fd2VicGFja19yZXF1aXJlX18oNSk7XG5cdHZhciBJbnRlcmZhY2UgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpO1xuXHR2YXIgU3RlcCA9IF9fd2VicGFja19yZXF1aXJlX18oMTEpO1xuXHRcblx0dmFyIEludGVyYWN0aW9uID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX193ZWJwYWNrX3JlcXVpcmVfXygxMikpO1xuXHRcblx0LyoqXG5cdCogUGFuMkRcblx0KlxuXHQqIEBkZXNjcmlwdGlvbiBJbnRlcmZhY2UgZm9yIG1vdmluZyBhIHNvdW5kIGFyb3VuZCBhbiBhcnJheSBvZiBzcGVha2Vycy4gU3BlYWtlciBsb2NhdGlvbnMgY2FuIGJlIGN1c3RvbWl6ZWQuIFRoZSBpbnRlcmZhY2UgY2FsY3VsYXRlcyB0aGUgY2xvc2VuZXNzIG9mIHRoZSBzb3VuZCBzb3VyY2UgdG8gZWFjaCBzcGVha2VyIGFuZCByZXR1cm5zIHRoYXQgZGlzdGFuY2UgYXMgYSBudW1lcmljIHZhbHVlLlxuXHQqXG5cdCogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJwYW4yRFwiPjwvc3Bhbj5cblx0KlxuXHQqIEBleGFtcGxlXG5cdCogdmFyIHBhbjJkID0gbmV3IE5leHVzLlBhbjJkKCcjdGFyZ2V0Jylcblx0KlxuXHQqIEBleGFtcGxlXG5cdCogdmFyIHBhbjJkID0gbmV3IE5leHVzLlBhbjJEKCcjdGFyZ2V0Jyx7XG5cdCogICAnc2l6ZSc6IFsyMDAsMjAwXSxcblx0KiAgICdyYW5nZSc6IDAuNSwgIC8vIGRldGVjdGlvbiByYWRpdXMgb2YgZWFjaCBzcGVha2VyXG5cdCogICAnbW9kZSc6ICdhYnNvbHV0ZScsICAgLy8gJ2Fic29sdXRlJyBvciAncmVsYXRpdmUnIHNvdW5kIG1vdmVtZW50XG5cdCogICAnc3BlYWtlcnMnOiBbICAvLyB0aGUgc3BlYWtlciBbeCx5XSBwb3NpdGlvbnNcblx0KiAgICAgICBbMC41LDAuMl0sXG5cdCogICAgICAgWzAuNzUsMC4yNV0sXG5cdCogICAgICAgWzAuOCwwLjVdLFxuXHQqICAgICAgIFswLjc1LDAuNzVdLFxuXHQqICAgICAgIFswLjUsMC44XSxcblx0KiAgICAgICBbMC4yNSwwLjc1XVxuXHQqICAgICAgIFswLjIsMC41XSxcblx0KiAgICAgICBbMC4yNSwwLjI1XVxuXHQqICAgXVxuXHQqIH0pXG5cdCpcblx0KiBAb3V0cHV0XG5cdCogY2hhbmdlXG5cdCogRmlyZXMgYW55IHRpbWUgdGhlIFwic291cmNlXCIgbm9kZSdzIHBvc2l0aW9uIGNoYW5nZXMuIDxicj5cblx0KiBUaGUgZXZlbnQgZGF0YSBpcyBhbiBhcnJheSBvZiB0aGUgYW1wbGl0dWRlcyAoMC0xKSwgcmVwcmVzZW50aW5nIHRoZSBsZXZlbCBvZiBlYWNoIHNwZWFrZXIgKGFzIGNhbGN1bGF0ZWQgYnkgaXRzIGRpc3RhbmNlIHRvIHRoZSBhdWRpbyBzb3VyY2UpLlxuXHQqXG5cdCogQG91dHB1dGV4YW1wbGVcblx0KiBwYW4yZC5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG5cdCogICBjb25zb2xlLmxvZyh2KTtcblx0KiB9KVxuXHQqXG5cdCovXG5cdFxuXHR2YXIgUGFuMkQgPSAoZnVuY3Rpb24gKF9JbnRlcmZhY2UpIHtcblx0ICBmdW5jdGlvbiBQYW4yRCgpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQYW4yRCk7XG5cdFxuXHQgICAgdmFyIG9wdGlvbnMgPSBbXCJyYW5nZVwiXTtcblx0XG5cdCAgICB2YXIgZGVmYXVsdHMgPSB7XG5cdCAgICAgIHNpemU6IFsyMDAsIDIwMF0sXG5cdCAgICAgIHJhbmdlOiAwLjUsXG5cdCAgICAgIG1vZGU6IFwiYWJzb2x1dGVcIixcblx0ICAgICAgc3BlYWtlcnM6IFtbMC41LCAwLjJdLCBbMC43NSwgMC4yNV0sIFswLjgsIDAuNV0sIFswLjc1LCAwLjc1XSwgWzAuNSwgMC44XSwgWzAuMjUsIDAuNzVdLCBbMC4yLCAwLjVdLCBbMC4yNSwgMC4yNV1dXG5cdCAgICB9O1xuXHRcblx0ICAgIF9nZXQoT2JqZWN0LmdldFByb3RvdHlwZU9mKFBhbjJELnByb3RvdHlwZSksIFwiY29uc3RydWN0b3JcIiwgdGhpcykuY2FsbCh0aGlzLCBhcmd1bWVudHMsIG9wdGlvbnMsIGRlZmF1bHRzKTtcblx0XG5cdCAgICB0aGlzLnZhbHVlID0ge1xuXHQgICAgICB4OiBuZXcgU3RlcCgwLCAxLCAwLCAwLjUpLFxuXHQgICAgICB5OiBuZXcgU3RlcCgwLCAxLCAwLCAwLjUpXG5cdCAgICB9O1xuXHRcblx0ICAgIC8qKlxuXHQgICAgQWJzb2x1dGUgb3IgcmVsYXRpdmUgbW91c2UgaW50ZXJhY3Rpb24uIEluIFwiYWJzb2x1dGVcIiBtb2RlLCB0aGUgc291cmNlIG5vZGUgd2lsbCBqdW1wIHRvIHlvdXIgbW91c2UgcG9zaXRpb24gb24gbW91c2UgY2xpY2suIEluIFwicmVsYXRpdmVcIiBtb2RlLCBpdCBkb2VzIG5vdC5cblx0ICAgICovXG5cdCAgICB0aGlzLm1vZGUgPSB0aGlzLnNldHRpbmdzLm1vZGU7XG5cdFxuXHQgICAgdGhpcy5wb3NpdGlvbiA9IHtcblx0ICAgICAgeDogbmV3IEludGVyYWN0aW9uLkhhbmRsZSh0aGlzLm1vZGUsIFwiaG9yaXpvbnRhbFwiLCBbMCwgdGhpcy53aWR0aF0sIFt0aGlzLmhlaWdodCwgMF0pLFxuXHQgICAgICB5OiBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMubW9kZSwgXCJ2ZXJ0aWNhbFwiLCBbMCwgdGhpcy53aWR0aF0sIFt0aGlzLmhlaWdodCwgMF0pXG5cdCAgICB9O1xuXHQgICAgdGhpcy5wb3NpdGlvbi54LnZhbHVlID0gdGhpcy52YWx1ZS54Lm5vcm1hbGl6ZWQ7XG5cdCAgICB0aGlzLnBvc2l0aW9uLnkudmFsdWUgPSB0aGlzLnZhbHVlLnkubm9ybWFsaXplZDtcblx0XG5cdCAgICAvKipcblx0ICAgIEFuIGFycmF5IG9mIHNwZWFrZXIgbG9jYXRpb25zLiBVcGRhdGUgdGhpcyB3aXRoIC5tb3ZlU3BlYWtlcigpIG9yIC5tb3ZlQWxsU3BlYWtlcnMoKVxuXHQgICAgKi9cblx0ICAgIHRoaXMuc3BlYWtlcnMgPSB0aGlzLnNldHRpbmdzLnNwZWFrZXJzO1xuXHRcblx0ICAgIC8qKlxuXHQgICAgUmV3cml0ZTogVGhlIG1heGltdW0gZGlzdGFuY2UgZnJvbSBhIHNwZWFrZXIgdGhhdCB0aGUgc291cmNlIG5vZGUgY2FuIGJlIGZvciBpdCB0byBiZSBoZWFyZCBmcm9tIHRoYXQgc3BlYWtlci4gQSBsb3cgcmFuZ2UgKDAuMSkgd2lsbCByZXN1bHQgaW4gc3BlYWtlcnMgb25seSBwbGF5aW5nIHdoZW4gdGhlIHNvdW5kIGlzIHZlcnkgY2xvc2UgaXQuIERlZmF1bHQgaXMgMC41IChoYWxmIG9mIHRoZSBpbnRlcmZhY2UpLlxuXHQgICAgKi9cblx0ICAgIHRoaXMucmFuZ2UgPSB0aGlzLnNldHRpbmdzLnJhbmdlO1xuXHRcblx0ICAgIC8qKlxuXHQgICAgVGhlIGN1cnJlbnQgbGV2ZWxzIGZvciBlYWNoIHNwZWFrZXIuIFRoaXMgaXMgY2FsY3VsYXRlZCB3aGVuIGEgc291cmNlIG5vZGUgb3Igc3BlYWtlciBub2RlIGlzIG1vdmVkIHRocm91Z2ggaW50ZXJhY3Rpb24gb3IgcHJvZ3JhbWF0aWNhbGx5LlxuXHQgICAgKi9cblx0ICAgIHRoaXMubGV2ZWxzID0gW107XG5cdFxuXHQgICAgdGhpcy5pbml0KCk7XG5cdFxuXHQgICAgdGhpcy5jYWxjdWxhdGVMZXZlbHMoKTtcblx0ICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgfVxuXHRcblx0ICBfaW5oZXJpdHMoUGFuMkQsIF9JbnRlcmZhY2UpO1xuXHRcblx0ICBfY3JlYXRlQ2xhc3MoUGFuMkQsIHtcblx0ICAgIGJ1aWxkSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBidWlsZEludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgdGhpcy5rbm9iID0gc3ZnLmNyZWF0ZShcImNpcmNsZVwiKTtcblx0XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMua25vYik7XG5cdFxuXHQgICAgICAgIC8vIGFkZCBzcGVha2Vyc1xuXHQgICAgICAgIHRoaXMuc3BlYWtlckVsZW1lbnRzID0gW107XG5cdFxuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zcGVha2Vycy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgdmFyIHNwZWFrZXJFbGVtZW50ID0gc3ZnLmNyZWF0ZShcImNpcmNsZVwiKTtcblx0XG5cdCAgICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoc3BlYWtlckVsZW1lbnQpO1xuXHRcblx0ICAgICAgICAgIHRoaXMuc3BlYWtlckVsZW1lbnRzLnB1c2goc3BlYWtlckVsZW1lbnQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHNpemVJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNpemVJbnRlcmZhY2UoKSB7XG5cdFxuXHQgICAgICAgIHRoaXMuX21pbkRpbWVuc2lvbiA9IE1hdGgubWluKHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KTtcblx0XG5cdCAgICAgICAgdGhpcy5rbm9iUmFkaXVzID0ge1xuXHQgICAgICAgICAgb2ZmOiB+IH4odGhpcy5fbWluRGltZW5zaW9uIC8gMTAwKSAqIDMgKyA1IH07XG5cdCAgICAgICAgdGhpcy5rbm9iUmFkaXVzLm9uID0gdGhpcy5rbm9iUmFkaXVzLm9mZiAqIDI7XG5cdFxuXHQgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJjeFwiLCB0aGlzLndpZHRoIC8gMik7XG5cdCAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImN5XCIsIHRoaXMuaGVpZ2h0IC8gMik7XG5cdCAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcInJcIiwgdGhpcy5rbm9iUmFkaXVzLm9mZik7XG5cdFxuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zcGVha2Vycy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgdmFyIHNwZWFrZXJFbGVtZW50ID0gdGhpcy5zcGVha2VyRWxlbWVudHNbaV07XG5cdCAgICAgICAgICB2YXIgc3BlYWtlciA9IHRoaXMuc3BlYWtlcnNbaV07XG5cdCAgICAgICAgICBzcGVha2VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJjeFwiLCBzcGVha2VyWzBdICogdGhpcy53aWR0aCk7XG5cdCAgICAgICAgICBzcGVha2VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJjeVwiLCBzcGVha2VyWzFdICogdGhpcy5oZWlnaHQpO1xuXHQgICAgICAgICAgc3BlYWtlckVsZW1lbnQuc2V0QXR0cmlidXRlKFwiclwiLCB0aGlzLl9taW5EaW1lbnNpb24gLyAyMCArIDUpO1xuXHQgICAgICAgICAgc3BlYWtlckVsZW1lbnQuc2V0QXR0cmlidXRlKFwiZmlsbC1vcGFjaXR5XCIsIFwiMFwiKTtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHRoaXMucG9zaXRpb24ueC5yZXNpemUoWzAsIHRoaXMud2lkdGhdLCBbdGhpcy5oZWlnaHQsIDBdKTtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uLnkucmVzaXplKFswLCB0aGlzLndpZHRoXSwgW3RoaXMuaGVpZ2h0LCAwXSk7XG5cdFxuXHQgICAgICAgIC8vIG5leHQsIG5lZWQgdG9cblx0ICAgICAgICAvLyByZXNpemUgcG9zaXRpb25zXG5cdCAgICAgICAgLy8gY2FsY3VsYXRlIHNwZWFrZXIgZGlzdGFuY2VzXG5cdCAgICAgICAgdGhpcy5jYWxjdWxhdGVMZXZlbHMoKTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY29sb3JJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbG9ySW50ZXJmYWNlKCkge1xuXHRcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcblx0ICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG5cdFxuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zcGVha2Vycy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgdmFyIHNwZWFrZXJFbGVtZW50ID0gdGhpcy5zcGVha2VyRWxlbWVudHNbaV07XG5cdCAgICAgICAgICBzcGVha2VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cdCAgICAgICAgICBzcGVha2VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgdGhpcy5jb2xvcnMuYWNjZW50KTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByZW5kZXI6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcblx0ICAgICAgICB0aGlzLmtub2JDb29yZGluYXRlcyA9IHtcblx0ICAgICAgICAgIHg6IHRoaXMudmFsdWUueC5ub3JtYWxpemVkICogdGhpcy53aWR0aCxcblx0ICAgICAgICAgIHk6IHRoaXMuaGVpZ2h0IC0gdGhpcy52YWx1ZS55Lm5vcm1hbGl6ZWQgKiB0aGlzLmhlaWdodFxuXHQgICAgICAgIH07XG5cdFxuXHQgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJjeFwiLCB0aGlzLmtub2JDb29yZGluYXRlcy54KTtcblx0ICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiY3lcIiwgdGhpcy5rbm9iQ29vcmRpbmF0ZXMueSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjbGljazoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY2xpY2soKSB7XG5cdCAgICAgICAgdGhpcy5wb3NpdGlvbi54LmFuY2hvciA9IHRoaXMubW91c2U7XG5cdCAgICAgICAgdGhpcy5wb3NpdGlvbi55LmFuY2hvciA9IHRoaXMubW91c2U7XG5cdCAgICAgICAgdGhpcy5tb3ZlKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBtb3ZlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBtb3ZlKCkge1xuXHQgICAgICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcblx0ICAgICAgICAgIHRoaXMucG9zaXRpb24ueC51cGRhdGUodGhpcy5tb3VzZSk7XG5cdCAgICAgICAgICB0aGlzLnBvc2l0aW9uLnkudXBkYXRlKHRoaXMubW91c2UpO1xuXHQgICAgICAgICAgLy8gcG9zaXRpb24ueCBhbmQgcG9zaXRpb24ueSBhcmUgbm9ybWFsaXplZFxuXHQgICAgICAgICAgLy8gc28gYXJlIHRoZSBsZXZlbHNcblx0ICAgICAgICAgIC8vIGxpa2VseSBkb24ndCBuZWVkIHRoaXMudmFsdWUgYXQgYWxsIC0tIG9ubHkgdXNlZCBmb3IgZHJhd2luZ1xuXHQgICAgICAgICAgLy8gbm90IGdvaW5nIHRvIGJlIGEgJ3N0ZXAnIG9yICdtaW4nIGFuZCAnbWF4JyBpbiB0aGlzIG9uZS5cblx0ICAgICAgICAgIHRoaXMuY2FsY3VsYXRlTGV2ZWxzKCk7XG5cdCAgICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy5sZXZlbHMpO1xuXHQgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByZWxlYXNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZWxlYXNlKCkge1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBub3JtYWxpemVkOiB7XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICB4OiB0aGlzLnZhbHVlLngubm9ybWFsaXplZCxcblx0ICAgICAgICAgIHk6IHRoaXMudmFsdWUueS5ub3JtYWxpemVkXG5cdCAgICAgICAgfTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNhbGN1bGF0ZUxldmVsczoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY2FsY3VsYXRlTGV2ZWxzKCkge1xuXHQgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgICAgIHRoaXMudmFsdWUueC51cGRhdGVOb3JtYWwodGhpcy5wb3NpdGlvbi54LnZhbHVlKTtcblx0ICAgICAgICB0aGlzLnZhbHVlLnkudXBkYXRlTm9ybWFsKHRoaXMucG9zaXRpb24ueS52YWx1ZSk7XG5cdCAgICAgICAgdGhpcy5sZXZlbHMgPSBbXTtcblx0ICAgICAgICB0aGlzLnNwZWFrZXJzLmZvckVhY2goZnVuY3Rpb24gKHMsIGkpIHtcblx0ICAgICAgICAgIHZhciBkaXN0YW5jZSA9IG1hdGguZGlzdGFuY2Uoc1swXSAqIF90aGlzLndpZHRoLCBzWzFdICogX3RoaXMuaGVpZ2h0LCBfdGhpcy5wb3NpdGlvbi54LnZhbHVlICogX3RoaXMud2lkdGgsICgxIC0gX3RoaXMucG9zaXRpb24ueS52YWx1ZSkgKiBfdGhpcy5oZWlnaHQpO1xuXHQgICAgICAgICAgdmFyIGxldmVsID0gbWF0aC5jbGlwKDEgLSBkaXN0YW5jZSAvIChfdGhpcy5yYW5nZSAqIF90aGlzLndpZHRoKSwgMCwgMSk7XG5cdCAgICAgICAgICBfdGhpcy5sZXZlbHMucHVzaChsZXZlbCk7XG5cdCAgICAgICAgICBfdGhpcy5zcGVha2VyRWxlbWVudHNbaV0uc2V0QXR0cmlidXRlKFwiZmlsbC1vcGFjaXR5XCIsIGxldmVsKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIG1vdmVTb3VyY2U6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBNb3ZlIHRoZSBhdWRpbyBzb3VyY2Ugbm9kZSBhbmQgdHJpZ2dlciB0aGUgb3V0cHV0IGV2ZW50LlxuXHQgICAgICBAcGFyYW0geCB7bnVtYmVyfSBOZXcgeCBsb2NhdGlvbiwgbm9ybWFsaXplZCAwLTFcblx0ICAgICAgQHBhcmFtIHkge251bWJlcn0gTmV3IHkgbG9jYXRpb24sIG5vcm1hbGl6ZWQgMC0xXG5cdCAgICAgICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gbW92ZVNvdXJjZSh4LCB5KSB7XG5cdCAgICAgICAgdmFyIGxvY2F0aW9uID0ge1xuXHQgICAgICAgICAgeDogeCAqIHRoaXMud2lkdGgsXG5cdCAgICAgICAgICB5OiB5ICogdGhpcy5oZWlnaHRcblx0ICAgICAgICB9O1xuXHQgICAgICAgIHRoaXMucG9zaXRpb24ueC51cGRhdGUobG9jYXRpb24pO1xuXHQgICAgICAgIHRoaXMucG9zaXRpb24ueS51cGRhdGUobG9jYXRpb24pO1xuXHQgICAgICAgIHRoaXMuY2FsY3VsYXRlTGV2ZWxzKCk7XG5cdCAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMubGV2ZWxzKTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbW92ZVNwZWFrZXI6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBNb3ZlIGEgc3BlYWtlciBub2RlIGFuZCB0cmlnZ2VyIHRoZSBvdXRwdXQgZXZlbnQuXG5cdCAgICAgIEBwYXJhbSBpbmRleCB7bnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlYWtlciB0byBtb3ZlXG5cdCAgICAgIEBwYXJhbSB4IHtudW1iZXJ9IE5ldyB4IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuXHQgICAgICBAcGFyYW0geSB7bnVtYmVyfSBOZXcgeSBsb2NhdGlvbiwgbm9ybWFsaXplZCAwLTFcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBtb3ZlU3BlYWtlcihpbmRleCwgeCwgeSkge1xuXHRcblx0ICAgICAgICB0aGlzLnNwZWFrZXJzW2luZGV4XSA9IFt4LCB5XTtcblx0ICAgICAgICB0aGlzLnNwZWFrZXJFbGVtZW50c1tpbmRleF0uc2V0QXR0cmlidXRlKFwiY3hcIiwgeCAqIHRoaXMud2lkdGgpO1xuXHQgICAgICAgIHRoaXMuc3BlYWtlckVsZW1lbnRzW2luZGV4XS5zZXRBdHRyaWJ1dGUoXCJjeVwiLCB5ICogdGhpcy5oZWlnaHQpO1xuXHQgICAgICAgIHRoaXMuY2FsY3VsYXRlTGV2ZWxzKCk7XG5cdCAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMubGV2ZWxzKTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgU2V0IGFsbCBzcGVha2VyIGxvY2F0aW9uc1xuXHQgICAgICBAcGFyYW0gbG9jYXRpb25zIHtBcnJheX0gQXJyYXkgb2Ygc3BlYWtlciBsb2NhdGlvbnMuIEVhY2ggaXRlbSBpbiB0aGUgYXJyYXkgc2hvdWxkIGJlIGFuIGFycmF5IG9mIG5vcm1hbGl6ZWQgeCBhbmQgeSBjb29yZGluYXRlcy5cblx0ICAgICAgIHNldFNwZWFrZXJzKGxvY2F0aW9ucykge1xuXHQgICAgICAgfVxuXHQgICAgICAqL1xuXHRcblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIFBhbjJEO1xuXHR9KShJbnRlcmZhY2UpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBQYW4yRDtcblxuLyoqKi8gfSksXG4vKiAzMCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9nZXQgPSBmdW5jdGlvbiBnZXQob2JqZWN0LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpIHsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyByZXR1cm4gZ2V0KHBhcmVudCwgcHJvcGVydHksIHJlY2VpdmVyKTsgfSB9IGVsc2UgaWYgKFwidmFsdWVcIiBpbiBkZXNjICYmIGRlc2Mud3JpdGFibGUpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9O1xuXHRcblx0dmFyIF9pbmhlcml0cyA9IGZ1bmN0aW9uIChzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9O1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIG1hdGggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpO1xuXHR2YXIgc3ZnID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTtcblx0dmFyIEludGVyZmFjZSA9IF9fd2VicGFja19yZXF1aXJlX18oNik7XG5cdFxuXHQvKipcblx0KiBUaWx0XG5cdCpcblx0KiBAZGVzY3JpcHRpb24gRGV2aWNlIHRpbHQgc2Vuc29yIHdpdGggMiBvciAzIGF4ZXMgKGRlcGVuZGluZyBvbiB5b3VyIGRldmljZSBhbmQgYnJvd3NlcikuXG5cdCpcblx0KiBAZGVtbyA8c3BhbiBuZXh1cy11aT0ndGlsdCc+PC9zcGFuPlxuXHQqXG5cdCogQGV4YW1wbGVcblx0KiB2YXIgdGlsdCA9IG5ldyBOZXh1cy5UaWx0KCcjdGFyZ2V0Jylcblx0KlxuXHQqIEBvdXRwdXRcblx0KiBjaGFuZ2Vcblx0KiBGaXJlcyBhdCBhIHJlZ3VsYXIgaW50ZXJ2YWwsIGFzIGxvbmcgYXMgdGhpcyBpbnRlcmZhY2UgaXMgYWN0aXZlIChzZWUgdGhlIGludGVyZmFjZSdzIDxpPi5hY3RpdmU8L2k+IHByb3BlcnR5KTxicj5cblx0KiBUaGUgZXZlbnQgZGF0YSBpcyBhbiA8aT5vYmplY3Q8L2k+IGNvbnRhaW5pbmcgeCAobnVtYmVyKSBhbmQgeSAobnVtYmVyKSBwcm9wZXJ0aWVzIHdoaWNoIHJlcHJlc2VudCB0aGUgY3VycmVudCB0aWx0IHN0YXRlIG9mIHRoZSBkZXZpY2UuXG5cdCpcblx0KiBAb3V0cHV0ZXhhbXBsZVxuXHQqIHRpbHQub24oJ2NoYW5nZScsZnVuY3Rpb24odikge1xuXHQqICAgY29uc29sZS5sb2codik7XG5cdCogfSlcblx0KlxuXHQqXG5cdCovXG5cdFxuXHR2YXIgVGlsdCA9IChmdW5jdGlvbiAoX0ludGVyZmFjZSkge1xuXHQgIGZ1bmN0aW9uIFRpbHQoKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVGlsdCk7XG5cdFxuXHQgICAgdmFyIG9wdGlvbnMgPSBbXCJ2YWx1ZVwiXTtcblx0XG5cdCAgICB2YXIgZGVmYXVsdHMgPSB7XG5cdCAgICAgIHNpemU6IFs4MCwgODBdXG5cdCAgICB9O1xuXHRcblx0ICAgIF9nZXQoT2JqZWN0LmdldFByb3RvdHlwZU9mKFRpbHQucHJvdG90eXBlKSwgXCJjb25zdHJ1Y3RvclwiLCB0aGlzKS5jYWxsKHRoaXMsIGFyZ3VtZW50cywgb3B0aW9ucywgZGVmYXVsdHMpO1xuXHRcblx0ICAgIHRoaXMuX2FjdGl2ZSA9IHRydWU7XG5cdFxuXHQgICAgdGhpcy5pbml0KCk7XG5cdFxuXHQgICAgLy8gYWRkIGV2ZW50IGxpc3RlbmVyIGZvciBkZXZpY2Ugb3JpZW50YXRpb25cblx0XG5cdCAgICB0aGlzLmJvdW5kVXBkYXRlID0gdGhpcy51cGRhdGUuYmluZCh0aGlzKTtcblx0ICAgIC8vXHR0aGlzLmJvdW5kTW96VGlsdCA9IHRoaXMubW96VGlsdC5iaW5kKHRoaXMpXG5cdFxuXHQgICAgaWYgKHdpbmRvdy5EZXZpY2VPcmllbnRhdGlvbkV2ZW50KSB7XG5cdCAgICAgIHRoaXMub3JpZW50YXRpb25MaXN0ZW5lciA9IHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiZGV2aWNlb3JpZW50YXRpb25cIiwgdGhpcy5ib3VuZFVwZGF0ZSwgZmFsc2UpO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgdGhpcy5fYWN0aXZlID0gZmFsc2U7XG5cdCAgICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcblx0ICAgIH1cblx0XG5cdCAgICAvKmVsc2UgaWYgKHdpbmRvdy5PcmllbnRhdGlvbkV2ZW50KSB7XG5cdCAgICAvL1x0ICBcdHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdNb3pPcmllbnRhdGlvbicsIHRoaXMuYm91bmRNb3pUaWx0LCBmYWxzZSk7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgY29uc29sZS5sb2coJ05vdCBzdXBwb3J0ZWQgb24geW91ciBkZXZpY2Ugb3IgYnJvd3Nlci4nKTtcblx0ICAgIH0gKi9cblx0ICB9XG5cdFxuXHQgIF9pbmhlcml0cyhUaWx0LCBfSW50ZXJmYWNlKTtcblx0XG5cdCAgX2NyZWF0ZUNsYXNzKFRpbHQsIHtcblx0ICAgIGJ1aWxkSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBidWlsZEludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgdGhpcy50aXRsZSA9IHN2Zy5jcmVhdGUoXCJ0ZXh0XCIpO1xuXHQgICAgICAgIHRoaXMuY2lyY2xlWCA9IHN2Zy5jcmVhdGUoXCJjaXJjbGVcIik7XG5cdCAgICAgICAgdGhpcy5jaXJjbGVZID0gc3ZnLmNyZWF0ZShcImNpcmNsZVwiKTtcblx0ICAgICAgICB0aGlzLmNpcmNsZVogPSBzdmcuY3JlYXRlKFwiY2lyY2xlXCIpO1xuXHRcblx0ICAgICAgICB0aGlzLmJhclggPSBzdmcuY3JlYXRlKFwicGF0aFwiKTtcblx0ICAgICAgICB0aGlzLmJhclkgPSBzdmcuY3JlYXRlKFwicGF0aFwiKTtcblx0ICAgICAgICB0aGlzLmJhclogPSBzdmcuY3JlYXRlKFwicGF0aFwiKTtcblx0XG5cdCAgICAgICAgdGhpcy5iYXJYMiA9IHN2Zy5jcmVhdGUoXCJwYXRoXCIpO1xuXHQgICAgICAgIHRoaXMuYmFyWTIgPSBzdmcuY3JlYXRlKFwicGF0aFwiKTtcblx0ICAgICAgICB0aGlzLmJhcloyID0gc3ZnLmNyZWF0ZShcInBhdGhcIik7XG5cdFxuXHQgICAgICAgIHRoaXMuYmFyWC5zZXRBdHRyaWJ1dGUoXCJvcGFjaXR5XCIsIFwiMC44XCIpO1xuXHQgICAgICAgIHRoaXMuYmFyWS5zZXRBdHRyaWJ1dGUoXCJvcGFjaXR5XCIsIFwiMC44XCIpO1xuXHQgICAgICAgIHRoaXMuYmFyWi5zZXRBdHRyaWJ1dGUoXCJvcGFjaXR5XCIsIFwiMC44XCIpO1xuXHQgICAgICAgIHRoaXMuYmFyWDIuc2V0QXR0cmlidXRlKFwib3BhY2l0eVwiLCBcIjAuOFwiKTtcblx0ICAgICAgICB0aGlzLmJhclkyLnNldEF0dHJpYnV0ZShcIm9wYWNpdHlcIiwgXCIwLjhcIik7XG5cdCAgICAgICAgdGhpcy5iYXJaMi5zZXRBdHRyaWJ1dGUoXCJvcGFjaXR5XCIsIFwiMC44XCIpO1xuXHRcblx0ICAgICAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKFwiY3hcIiwgdGhpcy53aWR0aCAqIDMgLyAxMik7XG5cdCAgICAgICAgdGhpcy5jaXJjbGVYLnNldEF0dHJpYnV0ZShcImN5XCIsIHRoaXMuaGVpZ2h0ICogMyAvIDQpO1xuXHQgICAgICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoXCJyXCIsIHRoaXMuaGVpZ2h0IC8gMTApO1xuXHQgICAgICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoXCJvcGFjaXR5XCIsIFwiMC40XCIpO1xuXHRcblx0ICAgICAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKFwiY3hcIiwgdGhpcy53aWR0aCAqIDYgLyAxMik7XG5cdCAgICAgICAgdGhpcy5jaXJjbGVZLnNldEF0dHJpYnV0ZShcImN5XCIsIHRoaXMuaGVpZ2h0ICogMyAvIDQpO1xuXHQgICAgICAgIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoXCJyXCIsIHRoaXMuaGVpZ2h0IC8gMTApO1xuXHQgICAgICAgIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoXCJvcGFjaXR5XCIsIFwiMC40XCIpO1xuXHRcblx0ICAgICAgICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKFwiY3hcIiwgdGhpcy53aWR0aCAqIDkgLyAxMik7XG5cdCAgICAgICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZShcImN5XCIsIHRoaXMuaGVpZ2h0ICogMyAvIDQpO1xuXHQgICAgICAgIHRoaXMuY2lyY2xlWi5zZXRBdHRyaWJ1dGUoXCJyXCIsIHRoaXMuaGVpZ2h0IC8gMTApO1xuXHQgICAgICAgIHRoaXMuY2lyY2xlWi5zZXRBdHRyaWJ1dGUoXCJvcGFjaXR5XCIsIFwiMC40XCIpO1xuXHRcblx0ICAgICAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIE1hdGgucm91bmQodGhpcy5oZWlnaHQgLyAzMCkpO1xuXHQgICAgICAgIHRoaXMuYmFyWS5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgTWF0aC5yb3VuZCh0aGlzLmhlaWdodCAvIDMwKSk7XG5cdCAgICAgICAgdGhpcy5iYXJaLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0IC8gMzApKTtcblx0XG5cdCAgICAgICAgdGhpcy5iYXJYLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgXCJub25lXCIpO1xuXHQgICAgICAgIHRoaXMuYmFyWS5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwibm9uZVwiKTtcblx0ICAgICAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcIm5vbmVcIik7XG5cdFxuXHQgICAgICAgIHRoaXMuYmFyWDIuc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIE1hdGgucm91bmQodGhpcy5oZWlnaHQgLyAzMCkpO1xuXHQgICAgICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIE1hdGgucm91bmQodGhpcy5oZWlnaHQgLyAzMCkpO1xuXHQgICAgICAgIHRoaXMuYmFyWjIuc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIE1hdGgucm91bmQodGhpcy5oZWlnaHQgLyAzMCkpO1xuXHRcblx0ICAgICAgICB0aGlzLmJhclgyLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgXCJub25lXCIpO1xuXHQgICAgICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcIm5vbmVcIik7XG5cdCAgICAgICAgdGhpcy5iYXJaMi5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwibm9uZVwiKTtcblx0XG5cdCAgICAgICAgdGhpcy50aXRsZS5zZXRBdHRyaWJ1dGUoXCJ4XCIsIHRoaXMud2lkdGggLyAyKTtcblx0ICAgICAgICB0aGlzLnRpdGxlLnNldEF0dHJpYnV0ZShcInlcIiwgdGhpcy5oZWlnaHQgLyAzICsgNyk7XG5cdCAgICAgICAgdGhpcy50aXRsZS5zZXRBdHRyaWJ1dGUoXCJmb250LXNpemVcIiwgXCIxNXB4XCIpO1xuXHQgICAgICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKFwiZm9udC13ZWlnaHRcIiwgXCJib2xkXCIpO1xuXHQgICAgICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKFwibGV0dGVyLXNwYWNpbmdcIiwgXCIycHhcIik7XG5cdCAgICAgICAgdGhpcy50aXRsZS5zZXRBdHRyaWJ1dGUoXCJvcGFjaXR5XCIsIFwiMC43XCIpO1xuXHQgICAgICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKFwidGV4dC1hbmNob3JcIiwgXCJtaWRkbGVcIik7XG5cdCAgICAgICAgdGhpcy50aXRsZS50ZXh0Q29udGVudCA9IFwiVElMVFwiO1xuXHRcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5jaXJjbGVYKTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5jaXJjbGVZKTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5jaXJjbGVaKTtcblx0XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuYmFyWCk7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuYmFyWSk7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuYmFyWik7XG5cdFxuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmJhclgyKTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXJZMik7XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuYmFyWjIpO1xuXHRcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy50aXRsZSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjb2xvckludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY29sb3JJbnRlcmZhY2UoKSB7XG5cdFxuXHQgICAgICAgIGlmICh0aGlzLl9hY3RpdmUpIHtcblx0ICAgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG5cdCAgICAgICAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKFwiZmlsbFwiLCB0aGlzLmNvbG9ycy5saWdodCk7XG5cdCAgICAgICAgICB0aGlzLmNpcmNsZVkuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCB0aGlzLmNvbG9ycy5saWdodCk7XG5cdCAgICAgICAgICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKFwiZmlsbFwiLCB0aGlzLmNvbG9ycy5saWdodCk7XG5cdCAgICAgICAgICB0aGlzLmNpcmNsZVguc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIHRoaXMuY29sb3JzLmxpZ2h0KTtcblx0ICAgICAgICAgIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgdGhpcy5jb2xvcnMubGlnaHQpO1xuXHQgICAgICAgICAgdGhpcy5jaXJjbGVaLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCB0aGlzLmNvbG9ycy5saWdodCk7XG5cdCAgICAgICAgICB0aGlzLmJhclguc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIHRoaXMuY29sb3JzLmxpZ2h0KTtcblx0ICAgICAgICAgIHRoaXMuYmFyWS5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgdGhpcy5jb2xvcnMubGlnaHQpO1xuXHQgICAgICAgICAgdGhpcy5iYXJaLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCB0aGlzLmNvbG9ycy5saWdodCk7XG5cdCAgICAgICAgICB0aGlzLmJhclgyLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCB0aGlzLmNvbG9ycy5saWdodCk7XG5cdCAgICAgICAgICB0aGlzLmJhclkyLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCB0aGlzLmNvbG9ycy5saWdodCk7XG5cdCAgICAgICAgICB0aGlzLmJhcloyLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCB0aGlzLmNvbG9ycy5saWdodCk7XG5cdCAgICAgICAgICB0aGlzLnRpdGxlLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdGhpcy5jb2xvcnMubGlnaHQpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcblx0ICAgICAgICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcblx0ICAgICAgICAgIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcblx0ICAgICAgICAgIHRoaXMuY2lyY2xlWi5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcblx0ICAgICAgICAgIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuXHQgICAgICAgICAgdGhpcy5jaXJjbGVZLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG5cdCAgICAgICAgICB0aGlzLmNpcmNsZVouc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcblx0ICAgICAgICAgIHRoaXMuYmFyWC5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgdGhpcy5jb2xvcnMubWVkaXVtTGlnaHQpO1xuXHQgICAgICAgICAgdGhpcy5iYXJZLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG5cdCAgICAgICAgICB0aGlzLmJhclouc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcblx0ICAgICAgICAgIHRoaXMuYmFyWDIuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcblx0ICAgICAgICAgIHRoaXMuYmFyWTIuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcblx0ICAgICAgICAgIHRoaXMuYmFyWjIuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIHRoaXMuY29sb3JzLm1lZGl1bUxpZ2h0KTtcblx0ICAgICAgICAgIHRoaXMudGl0bGUuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCB0aGlzLmNvbG9ycy5tZWRpdW1MaWdodCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdXBkYXRlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiB1cGRhdGUodikge1xuXHQgICAgICAgIGlmICh0aGlzLl9hY3RpdmUpIHtcblx0XG5cdCAgICAgICAgICB2YXIgeSA9IHYuYmV0YTtcblx0ICAgICAgICAgIHZhciB4ID0gdi5nYW1tYTtcblx0ICAgICAgICAgIHZhciB6ID0gdi5hbHBoYTtcblx0XG5cdCAgICAgICAgICAvLyB0YWtlIHRoZSBvcmlnaW5hbCAtOTAgdG8gOTAgc2NhbGUgYW5kIG5vcm1hbGl6ZSBpdCAwLTFcblx0ICAgICAgICAgIHggPSBtYXRoLnNjYWxlKHgsIC05MCwgOTAsIDAsIDEpO1xuXHQgICAgICAgICAgeSA9IG1hdGguc2NhbGUoeSwgLTkwLCA5MCwgMCwgMSk7XG5cdCAgICAgICAgICB6ID0gbWF0aC5zY2FsZSh6LCAwLCAzNjAsIDAsIDEpO1xuXHRcblx0ICAgICAgICAgIHZhciBoYW5kbGVQb2ludHMgPSB7XG5cdCAgICAgICAgICAgIHN0YXJ0OiBNYXRoLlBJICogMS41LFxuXHQgICAgICAgICAgICBlbmQ6IG1hdGguY2xpcChtYXRoLnNjYWxlKHgsIDAsIDAuNSwgTWF0aC5QSSAqIDEuNSwgTWF0aC5QSSAqIDAuNSksIE1hdGguUEkgKiAwLjUsIE1hdGguUEkgKiAxLjUpXG5cdCAgICAgICAgICB9O1xuXHQgICAgICAgICAgdmFyIGhhbmRsZTJQb2ludHMgPSB7XG5cdCAgICAgICAgICAgIHN0YXJ0OiBNYXRoLlBJICogMi41LFxuXHQgICAgICAgICAgICBlbmQ6IG1hdGguY2xpcChtYXRoLnNjYWxlKHgsIDAuNSwgMSwgTWF0aC5QSSAqIDIuNSwgTWF0aC5QSSAqIDEuNSksIE1hdGguUEkgKiAxLjUsIE1hdGguUEkgKiAyLjUpXG5cdCAgICAgICAgICB9O1xuXHRcblx0ICAgICAgICAgIHZhciBoYW5kbGVQYXRoID0gc3ZnLmFyYyh0aGlzLmNpcmNsZVguY3guYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVYLmN5LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWC5yLmJhc2VWYWwudmFsdWUsIGhhbmRsZVBvaW50cy5zdGFydCwgaGFuZGxlUG9pbnRzLmVuZCk7XG5cdCAgICAgICAgICB2YXIgaGFuZGxlMlBhdGggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWC5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVguY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVYLnIuYmFzZVZhbC52YWx1ZSwgaGFuZGxlMlBvaW50cy5zdGFydCwgaGFuZGxlMlBvaW50cy5lbmQpO1xuXHRcblx0ICAgICAgICAgIHRoaXMuYmFyWC5zZXRBdHRyaWJ1dGUoXCJkXCIsIGhhbmRsZVBhdGgpO1xuXHQgICAgICAgICAgdGhpcy5iYXJYMi5zZXRBdHRyaWJ1dGUoXCJkXCIsIGhhbmRsZTJQYXRoKTtcblx0XG5cdCAgICAgICAgICBoYW5kbGVQb2ludHMgPSB7XG5cdCAgICAgICAgICAgIHN0YXJ0OiBNYXRoLlBJICogMS41LFxuXHQgICAgICAgICAgICBlbmQ6IG1hdGguY2xpcChtYXRoLnNjYWxlKHksIDAsIDAuNSwgTWF0aC5QSSAqIDEuNSwgTWF0aC5QSSAqIDAuNSksIE1hdGguUEkgKiAwLjUsIE1hdGguUEkgKiAxLjUpXG5cdCAgICAgICAgICB9O1xuXHQgICAgICAgICAgaGFuZGxlMlBvaW50cyA9IHtcblx0ICAgICAgICAgICAgc3RhcnQ6IE1hdGguUEkgKiAyLjUsXG5cdCAgICAgICAgICAgIGVuZDogbWF0aC5jbGlwKG1hdGguc2NhbGUoeSwgMC41LCAxLCBNYXRoLlBJICogMi41LCBNYXRoLlBJICogMS41KSwgTWF0aC5QSSAqIDEuNSwgTWF0aC5QSSAqIDIuNSlcblx0ICAgICAgICAgIH07XG5cdFxuXHQgICAgICAgICAgaGFuZGxlUGF0aCA9IHN2Zy5hcmModGhpcy5jaXJjbGVZLmN4LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWS5jeS5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVkuci5iYXNlVmFsLnZhbHVlLCBoYW5kbGVQb2ludHMuc3RhcnQsIGhhbmRsZVBvaW50cy5lbmQpO1xuXHQgICAgICAgICAgaGFuZGxlMlBhdGggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWS5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVkuY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVZLnIuYmFzZVZhbC52YWx1ZSwgaGFuZGxlMlBvaW50cy5zdGFydCwgaGFuZGxlMlBvaW50cy5lbmQpO1xuXHRcblx0ICAgICAgICAgIHRoaXMuYmFyWS5zZXRBdHRyaWJ1dGUoXCJkXCIsIGhhbmRsZVBhdGgpO1xuXHQgICAgICAgICAgdGhpcy5iYXJZMi5zZXRBdHRyaWJ1dGUoXCJkXCIsIGhhbmRsZTJQYXRoKTtcblx0XG5cdCAgICAgICAgICBoYW5kbGVQb2ludHMgPSB7XG5cdCAgICAgICAgICAgIHN0YXJ0OiBNYXRoLlBJICogMS41LFxuXHQgICAgICAgICAgICBlbmQ6IG1hdGguY2xpcChtYXRoLnNjYWxlKHosIDAsIDAuNSwgTWF0aC5QSSAqIDEuNSwgTWF0aC5QSSAqIDAuNSksIE1hdGguUEkgKiAwLjUsIE1hdGguUEkgKiAxLjUpXG5cdCAgICAgICAgICB9O1xuXHQgICAgICAgICAgaGFuZGxlMlBvaW50cyA9IHtcblx0ICAgICAgICAgICAgc3RhcnQ6IE1hdGguUEkgKiAyLjUsXG5cdCAgICAgICAgICAgIGVuZDogbWF0aC5jbGlwKG1hdGguc2NhbGUoeiwgMC41LCAxLCBNYXRoLlBJICogMi41LCBNYXRoLlBJICogMS41KSwgTWF0aC5QSSAqIDEuNSwgTWF0aC5QSSAqIDIuNSlcblx0ICAgICAgICAgIH07XG5cdFxuXHQgICAgICAgICAgaGFuZGxlUGF0aCA9IHN2Zy5hcmModGhpcy5jaXJjbGVaLmN4LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWi5jeS5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVouci5iYXNlVmFsLnZhbHVlLCBoYW5kbGVQb2ludHMuc3RhcnQsIGhhbmRsZVBvaW50cy5lbmQpO1xuXHQgICAgICAgICAgaGFuZGxlMlBhdGggPSBzdmcuYXJjKHRoaXMuY2lyY2xlWi5jeC5iYXNlVmFsLnZhbHVlLCB0aGlzLmNpcmNsZVouY3kuYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVaLnIuYmFzZVZhbC52YWx1ZSwgaGFuZGxlMlBvaW50cy5zdGFydCwgaGFuZGxlMlBvaW50cy5lbmQpO1xuXHRcblx0ICAgICAgICAgIHRoaXMuYmFyWi5zZXRBdHRyaWJ1dGUoXCJkXCIsIGhhbmRsZVBhdGgpO1xuXHQgICAgICAgICAgdGhpcy5iYXJaMi5zZXRBdHRyaWJ1dGUoXCJkXCIsIGhhbmRsZTJQYXRoKTtcblx0XG5cdCAgICAgICAgICAvKlxuXHQgICAgICAgICAgIGxldCBwb2ludHNYID0ge1xuXHQgICAgICAgICAgICBzdGFydDogMCxcblx0ICAgICAgICAgICAgZW5kOiBtYXRoLnNjYWxlKCB4LCAwLCAxLCAwLCBNYXRoLlBJKjIgKVxuXHQgICAgICAgICAgfTtcblx0ICAgICAgICAgIC8vICBjb25zb2xlLmxvZyh0aGlzLmNpcmNsZVguY3guYmFzZVZhbC52YWx1ZSk7XG5cdCAgICAgICAgICAgbGV0IHBhdGhYID0gc3ZnLmFyYyh0aGlzLmNpcmNsZVguY3guYmFzZVZhbC52YWx1ZSwgdGhpcy5jaXJjbGVYLmN5LmJhc2VWYWwudmFsdWUsIHRoaXMuY2lyY2xlWC5yLmJhc2VWYWwudmFsdWUqMiwgcG9pbnRzWC5zdGFydCwgcG9pbnRzWC5lbmQpO1xuXHQgICAgICAgICAgIHRoaXMuYmFyWC5zZXRBdHRyaWJ1dGUoJ2QnLHBhdGhYKTsgKi9cblx0XG5cdCAgICAgICAgICAvL3RoaXMudGV4dEgudGV4dENvbnRlbnQgPSBtYXRoLnBydW5lKHgsMik7XG5cdCAgICAgICAgICAvL3RoaXMudGV4dFYudGV4dENvbnRlbnQgPSBtYXRoLnBydW5lKHksMik7XG5cdCAgICAgICAgICAvL1xuXHQgICAgICAgICAgLy8gIHRoaXMuY2lyY2xlWC5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLHgpO1xuXHQgICAgICAgICAgLy8gIHRoaXMuY2lyY2xlWS5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLHkpO1xuXHQgICAgICAgICAgLy8gIHRoaXMuY2lyY2xlWi5zZXRBdHRyaWJ1dGUoJ29wYWNpdHknLHopO1xuXHRcblx0ICAgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB7XG5cdCAgICAgICAgICAgIHg6IHgsXG5cdCAgICAgICAgICAgIHk6IHksXG5cdCAgICAgICAgICAgIHo6IHpcblx0ICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNsaWNrOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjbGljaygpIHtcblx0ICAgICAgICBpZiAod2luZG93LkRldmljZU9yaWVudGF0aW9uRXZlbnQpIHtcblx0ICAgICAgICAgIHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGFjdGl2ZToge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFdoZXRoZXIgdGhlIGludGVyZmFjZSBpcyBvbiAoZW1pdHRpbmcgdmFsdWVzKSBvciBvZmYgKHBhdXNlZCAmIG5vdCBlbWl0dGluZyB2YWx1ZXMpLiBTZXR0aW5nIHRoaXMgcHJvcGVydHkgd2lsbCB1cGRhdGUgaXQuXG5cdCAgICAgIEB0eXBlIHtib29sZWFufVxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2FjdGl2ZTtcblx0ICAgICAgfSxcblx0ICAgICAgc2V0OiBmdW5jdGlvbiAob24pIHtcblx0ICAgICAgICB0aGlzLl9hY3RpdmUgPSBvbjtcblx0ICAgICAgICB0aGlzLmNvbG9ySW50ZXJmYWNlKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjdXN0b21EZXN0cm95OiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjdXN0b21EZXN0cm95KCkge1xuXHQgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwiZGV2aWNlb3JpZW50YXRpb25cIiwgdGhpcy5ib3VuZFVwZGF0ZSwgZmFsc2UpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSk7XG5cdFxuXHQgIHJldHVybiBUaWx0O1xuXHR9KShJbnRlcmZhY2UpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBUaWx0O1xuXG4vKioqLyB9KSxcbi8qIDMxICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgX2NyZWF0ZUNsYXNzID0gKGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGtleSBpbiBwcm9wcykgeyB2YXIgcHJvcCA9IHByb3BzW2tleV07IHByb3AuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKHByb3AudmFsdWUpIHByb3Aud3JpdGFibGUgPSB0cnVlOyB9IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpOyB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cdFxuXHR2YXIgX2dldCA9IGZ1bmN0aW9uIGdldChvYmplY3QsIHByb3BlcnR5LCByZWNlaXZlcikgeyB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBwcm9wZXJ0eSk7IGlmIChkZXNjID09PSB1bmRlZmluZWQpIHsgdmFyIHBhcmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpOyBpZiAocGFyZW50ID09PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gZWxzZSB7IHJldHVybiBnZXQocGFyZW50LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpOyB9IH0gZWxzZSBpZiAoXCJ2YWx1ZVwiIGluIGRlc2MgJiYgZGVzYy53cml0YWJsZSkgeyByZXR1cm4gZGVzYy52YWx1ZTsgfSBlbHNlIHsgdmFyIGdldHRlciA9IGRlc2MuZ2V0OyBpZiAoZ2V0dGVyID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpOyB9IH07XG5cdFxuXHR2YXIgX2luaGVyaXRzID0gZnVuY3Rpb24gKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgXCIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH07XG5cdFxuXHR2YXIgX2NsYXNzQ2FsbENoZWNrID0gZnVuY3Rpb24gKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH07XG5cdFxuXHR2YXIgZG9tID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3KTtcblx0dmFyIG1hdGggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpO1xuXHR2YXIgSW50ZXJmYWNlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2KTtcblx0dmFyIFNsaWRlclRlbXBsYXRlID0gX193ZWJwYWNrX3JlcXVpcmVfXygzMik7XG5cdHZhciB0b3VjaCA9IF9fd2VicGFja19yZXF1aXJlX18oOSk7XG5cdFxuXHR2YXIgU2luZ2xlU2xpZGVyID0gKGZ1bmN0aW9uIChfU2xpZGVyVGVtcGxhdGUpIHtcblx0ICBmdW5jdGlvbiBTaW5nbGVTbGlkZXIoKSB7XG5cdCAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTaW5nbGVTbGlkZXIpO1xuXHRcblx0ICAgIHZhciBvcHRpb25zID0gW1wic2NhbGVcIiwgXCJ2YWx1ZVwiXTtcblx0XG5cdCAgICB2YXIgZGVmYXVsdHMgPSB7XG5cdCAgICAgIHNpemU6IFsxMjAsIDIwXSxcblx0ICAgICAgb3JpZW50YXRpb246IFwidmVydGljYWxcIixcblx0ICAgICAgbW9kZTogXCJhYnNvbHV0ZVwiLFxuXHQgICAgICBzY2FsZTogWzAsIDFdLFxuXHQgICAgICBzdGVwOiAwLFxuXHQgICAgICB2YWx1ZTogMCxcblx0ICAgICAgaGFzS25vYjogdHJ1ZVxuXHQgICAgfTtcblx0XG5cdCAgICBfZ2V0KE9iamVjdC5nZXRQcm90b3R5cGVPZihTaW5nbGVTbGlkZXIucHJvdG90eXBlKSwgXCJjb25zdHJ1Y3RvclwiLCB0aGlzKS5jYWxsKHRoaXMsIGFyZ3VtZW50cywgb3B0aW9ucywgZGVmYXVsdHMpO1xuXHRcblx0ICAgIC8qIGV2ZW50cyAqL1xuXHRcblx0ICAgIGlmICghdG91Y2guZXhpc3RzKSB7XG5cdFxuXHQgICAgICB0aGlzLmNsaWNrID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIF90aGlzLm11bHRpc2xpZGVyLmludGVyYWN0aW5nID0gdHJ1ZTtcblx0ICAgICAgICBfdGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uID0ge1xuXHQgICAgICAgICAgaW5kZXg6IF90aGlzLmluZGV4LFxuXHQgICAgICAgICAgdmFsdWU6IF90aGlzLnZhbHVlXG5cdCAgICAgICAgfTtcblx0ICAgICAgICBfdGhpcy5kb3duKCk7XG5cdCAgICAgICAgX3RoaXMubXVsdGlzbGlkZXIudmFsdWVzW190aGlzLmluZGV4XSA9IF90aGlzLnZhbHVlO1xuXHQgICAgICB9O1xuXHQgICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlb3ZlclwiLCBmdW5jdGlvbiAoZSkge1xuXHQgICAgICAgIGlmIChfdGhpcy5tdWx0aXNsaWRlci5pbnRlcmFjdGluZykge1xuXHQgICAgICAgICAgaWYgKCFfdGhpcy5vZmZzZXQpIHtcblx0ICAgICAgICAgICAgX3RoaXMub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbihfdGhpcy5lbGVtZW50KTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICAgIF90aGlzLm1vdXNlID0gZG9tLmxvY2F0ZU1vdXNlKGUsIF90aGlzLm9mZnNldCk7XG5cdCAgICAgICAgICBfdGhpcy5kb3duKCk7XG5cdCAgICAgICAgICBfdGhpcy5tdWx0aXNsaWRlci52YWx1ZXNbX3RoaXMuaW5kZXhdID0gX3RoaXMudmFsdWU7XG5cdCAgICAgICAgICBpZiAoX3RoaXMubXVsdGlzbGlkZXIuaW50ZXJwb2xhdGlvbikge1xuXHQgICAgICAgICAgICB2YXIgZGlzdGFuY2UgPSBNYXRoLmFicyhfdGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uLmluZGV4IC0gX3RoaXMuaW5kZXgpO1xuXHQgICAgICAgICAgICBpZiAoZGlzdGFuY2UgPiAxKSB7XG5cdCAgICAgICAgICAgICAgdmFyIGxvdyA9IE1hdGgubWluKF90aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24uaW5kZXgsIF90aGlzLmluZGV4KTtcblx0ICAgICAgICAgICAgICB2YXIgaGlnaCA9IE1hdGgubWF4KF90aGlzLm11bHRpc2xpZGVyLmludGVycG9sYXRpb24uaW5kZXgsIF90aGlzLmluZGV4KTtcblx0ICAgICAgICAgICAgICB2YXIgbG93VmFsdWUgPSBfdGhpcy5tdWx0aXNsaWRlci5zbGlkZXJzW2xvd10udmFsdWU7XG5cdCAgICAgICAgICAgICAgdmFyIGhpZ2hWYWx1ZSA9IF90aGlzLm11bHRpc2xpZGVyLnNsaWRlcnNbaGlnaF0udmFsdWU7XG5cdCAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IGxvdzsgaSA8IGhpZ2g7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgX3RoaXMubXVsdGlzbGlkZXIuc2xpZGVyc1tpXS52YWx1ZSA9IG1hdGguaW50ZXJwKChpIC0gbG93KSAvIGRpc3RhbmNlLCBsb3dWYWx1ZSwgaGlnaFZhbHVlKTtcblx0ICAgICAgICAgICAgICAgIHZhciBzbW9vdGhlZFZhbHVlID0gX3RoaXMubXVsdGlzbGlkZXIuc2xpZGVyc1tpXS52YWx1ZTtcblx0ICAgICAgICAgICAgICAgIF90aGlzLm11bHRpc2xpZGVyLnZhbHVlc1tpXSA9IHNtb290aGVkVmFsdWU7XG5cdCAgICAgICAgICAgICAgICBfdGhpcy5tdWx0aXNsaWRlci51cGRhdGUoaSwgc21vb3RoZWRWYWx1ZSk7XG5cdCAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICB9XG5cdFxuXHQgICAgICAgICAgX3RoaXMubXVsdGlzbGlkZXIuaW50ZXJwb2xhdGlvbiA9IHtcblx0ICAgICAgICAgICAgaW5kZXg6IF90aGlzLmluZGV4LFxuXHQgICAgICAgICAgICB2YWx1ZTogX3RoaXMudmFsdWVcblx0ICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXHQgICAgICB9KTtcblx0XG5cdCAgICAgIHRoaXMubW92ZSA9IGZ1bmN0aW9uICgpIHt9O1xuXHQgICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCBmdW5jdGlvbiAoZSkge1xuXHQgICAgICAgIGlmIChfdGhpcy5tdWx0aXNsaWRlci5pbnRlcmFjdGluZykge1xuXHQgICAgICAgICAgaWYgKCFfdGhpcy5vZmZzZXQpIHtcblx0ICAgICAgICAgICAgX3RoaXMub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbihfdGhpcy5lbGVtZW50KTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICAgIF90aGlzLm1vdXNlID0gZG9tLmxvY2F0ZU1vdXNlKGUsIF90aGlzLm9mZnNldCk7XG5cdCAgICAgICAgICBfdGhpcy5zbGlkZSgpO1xuXHQgICAgICAgICAgX3RoaXMubXVsdGlzbGlkZXIudmFsdWVzW190aGlzLmluZGV4XSA9IF90aGlzLnZhbHVlO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSk7XG5cdFxuXHQgICAgICB0aGlzLnJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgX3RoaXMubXVsdGlzbGlkZXIuaW50ZXJhY3RpbmcgPSBmYWxzZTtcblx0ICAgICAgICBfdGhpcy5tdWx0aXNsaWRlci5pbnRlcnBvbGF0aW9uID0gZmFsc2U7XG5cdCAgICAgIH07XG5cdCAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgaWYgKF90aGlzLm11bHRpc2xpZGVyLmludGVyYWN0aW5nKSB7XG5cdCAgICAgICAgICBfdGhpcy51cCgpO1xuXHQgICAgICAgICAgX3RoaXMubXVsdGlzbGlkZXIuaW50ZXJwb2xhdGlvbiA9IGZhbHNlO1xuXHQgICAgICAgICAgX3RoaXMubXVsdGlzbGlkZXIudmFsdWVzW190aGlzLmluZGV4XSA9IF90aGlzLnZhbHVlO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSk7XG5cdCAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2VvdXRcIiwgZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGlmIChfdGhpcy5tdWx0aXNsaWRlci5pbnRlcmFjdGluZykge1xuXHQgICAgICAgICAgX3RoaXMudXAoKTtcblx0ICAgICAgICAgIF90aGlzLm11bHRpc2xpZGVyLnZhbHVlc1tfdGhpcy5pbmRleF0gPSBfdGhpcy52YWx1ZTtcblx0ICAgICAgICB9XG5cdCAgICAgIH0pO1xuXHQgICAgfVxuXHRcblx0ICAgIHRoaXMuY3VzdG9tU3R5bGUoKTtcblx0ICB9XG5cdFxuXHQgIF9pbmhlcml0cyhTaW5nbGVTbGlkZXIsIF9TbGlkZXJUZW1wbGF0ZSk7XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhTaW5nbGVTbGlkZXIsIHtcblx0ICAgIGN1c3RvbVN0eWxlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjdXN0b21TdHlsZSgpIHtcblx0XG5cdCAgICAgICAgLyogc3R5bGUgY2hhbmdlcyAqL1xuXHRcblx0ICAgICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoXCJ4XCIsIDApO1xuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZSgwLDApXCIpO1xuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcInJ4XCIsIDApOyAvLyBjb3JuZXIgcmFkaXVzXG5cdCAgICAgICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKFwicnlcIiwgMCk7XG5cdCAgICAgICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgdGhpcy53aWR0aCk7XG5cdCAgICAgICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIHRoaXMuaGVpZ2h0KTtcblx0XG5cdCAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcInhcIiwgMCk7XG5cdCAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZSgwLDApXCIpO1xuXHQgICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoXCJyeFwiLCAwKTsgLy8gY29ybmVyIHJhZGl1c1xuXHQgICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoXCJyeVwiLCAwKTtcblx0ICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgdGhpcy53aWR0aCk7XG5cdCAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCB0aGlzLmhlaWdodCk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIFNpbmdsZVNsaWRlcjtcblx0fSkoU2xpZGVyVGVtcGxhdGUpO1xuXHRcblx0LyoqXG5cdCogTXVsdGlzbGlkZXJcblx0KlxuXHQqIEBkZXNjcmlwdGlvbiBNdWx0aXNsaWRlclxuXHQqXG5cdCogQGRlbW8gPHNwYW4gbmV4dXMtdWk9XCJtdWx0aXNsaWRlclwiPjwvc3Bhbj5cblx0KlxuXHQqIEBleGFtcGxlXG5cdCogdmFyIG11bHRpc2xpZGVyID0gbmV3IE5leHVzLk11bHRpc2xpZGVyKCcjdGFyZ2V0Jylcblx0KlxuXHQqIEBleGFtcGxlXG5cdCogdmFyIG11bHRpc2xpZGVyID0gbmV3IE5leHVzLk11bHRpc2xpZGVyKCcjdGFyZ2V0Jyx7XG5cdCogICdzaXplJzogWzIwMCwxMDBdLFxuXHQqICAnbnVtYmVyT2ZTbGlkZXJzJzogNSxcblx0KiAgJ21pbic6IDAsXG5cdCogICdtYXgnOiAxLFxuXHQqICAnc3RlcCc6IDAsXG5cdCogICd2YWx1ZXMnOiBbMC43LDAuNywwLjcsMC43LDAuN11cblx0KiB9KVxuXHQqXG5cdCogQG91dHB1dFxuXHQqIGNoYW5nZVxuXHQqIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG5cdCogVGhlIGV2ZW50IGRhdGEgYW4gb2JqZWN0IGNvbnRhaW5pbmcgPGk+aW5kZXg8L2k+IGFuZCA8aT52YWx1ZTwvaT4gcHJvcGVydGllc1xuXHQqXG5cdCogQG91dHB1dGV4YW1wbGVcblx0KiBtdWx0aXNsaWRlci5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG5cdCogICBjb25zb2xlLmxvZyh2KTtcblx0KiB9KVxuXHQqXG5cdCovXG5cdFxuXHQvKlxuXHRQcm9wZXJ0aWVzXG5cdC52YWx1ZXNcblx0XG5cdCovXG5cdFxuXHR2YXIgTXVsdGlzbGlkZXIgPSAoZnVuY3Rpb24gKF9JbnRlcmZhY2UpIHtcblx0ICBmdW5jdGlvbiBNdWx0aXNsaWRlcigpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBNdWx0aXNsaWRlcik7XG5cdFxuXHQgICAgdmFyIG9wdGlvbnMgPSBbXCJ2YWx1ZVwiXTtcblx0XG5cdCAgICB2YXIgZGVmYXVsdHMgPSB7XG5cdCAgICAgIHNpemU6IFsyMDAsIDEwMF0sXG5cdCAgICAgIG51bWJlck9mU2xpZGVyczogNSxcblx0ICAgICAgbWluOiAwLFxuXHQgICAgICBtYXg6IDEsXG5cdCAgICAgIHN0ZXA6IDAsXG5cdCAgICAgIHZhbHVlczogWzAuNywgMC43LCAwLjcsIDAuNywgMC43XVxuXHQgICAgfTtcblx0XG5cdCAgICBfZ2V0KE9iamVjdC5nZXRQcm90b3R5cGVPZihNdWx0aXNsaWRlci5wcm90b3R5cGUpLCBcImNvbnN0cnVjdG9yXCIsIHRoaXMpLmNhbGwodGhpcywgYXJndW1lbnRzLCBvcHRpb25zLCBkZWZhdWx0cyk7XG5cdFxuXHQgICAgdGhpcy5fbnVtYmVyT2ZTbGlkZXJzID0gdGhpcy5zZXR0aW5ncy5udW1iZXJPZlNsaWRlcnM7XG5cdCAgICB0aGlzLnZhbHVlcyA9IHRoaXMuc2V0dGluZ3MudmFsdWVzO1xuXHRcblx0ICAgIHRoaXMuc2xpZGVycyA9IFtdO1xuXHRcblx0ICAgIHRoaXMuaW50ZXJhY3RpbmcgPSBmYWxzZTtcblx0XG5cdCAgICB0aGlzLmluaXQoKTtcblx0ICB9XG5cdFxuXHQgIF9pbmhlcml0cyhNdWx0aXNsaWRlciwgX0ludGVyZmFjZSk7XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhNdWx0aXNsaWRlciwge1xuXHQgICAgYnVpbGRGcmFtZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gYnVpbGRGcmFtZSgpIHtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXHQgICAgICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBidWlsZEludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gYnVpbGRJbnRlcmZhY2UoKSB7XG5cdFxuXHQgICAgICAgIHZhciBtaW4gPSB0aGlzLnNldHRpbmdzLm1pbjtcblx0ICAgICAgICB2YXIgbWF4ID0gdGhpcy5zZXR0aW5ncy5tYXg7XG5cdCAgICAgICAgdmFyIHN0ZXAgPSB0aGlzLnNldHRpbmdzLnN0ZXA7XG5cdFxuXHQgICAgICAgIGlmICh0aGlzLnNsaWRlcnMubGVuZ3RoKSB7XG5cdCAgICAgICAgICBtaW4gPSB0aGlzLnNsaWRlcnNbMF0ubWluO1xuXHQgICAgICAgICAgbWF4ID0gdGhpcy5zbGlkZXJzWzBdLm1heDtcblx0ICAgICAgICAgIHN0ZXAgPSB0aGlzLnNsaWRlcnNbMF0uc3RlcDtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHRoaXMuc2xpZGVycyA9IFtdO1xuXHRcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX251bWJlck9mU2xpZGVyczsgaSsrKSB7XG5cdCAgICAgICAgICB2YXIgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNwYW5cIik7XG5cdFxuXHQgICAgICAgICAgdmFyIHNsaWRlciA9IG5ldyBTaW5nbGVTbGlkZXIoY29udGFpbmVyLCB7XG5cdCAgICAgICAgICAgIHNjYWxlOiBbbWluLCBtYXhdLFxuXHQgICAgICAgICAgICBzdGVwOiBzdGVwLFxuXHQgICAgICAgICAgICBtb2RlOiBcImFic29sdXRlXCIsXG5cdCAgICAgICAgICAgIG9yaWVudGF0aW9uOiBcInZlcnRpY2FsXCIsXG5cdCAgICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlc1tpXSxcblx0ICAgICAgICAgICAgaGFzS25vYjogZmFsc2UsXG5cdCAgICAgICAgICAgIGNvbXBvbmVudDogdHJ1ZSB9LCB0aGlzLnVwZGF0ZS5iaW5kKHRoaXMsIGkpKTtcblx0ICAgICAgICAgIHNsaWRlci5tdWx0aXNsaWRlciA9IHRoaXM7XG5cdFxuXHQgICAgICAgICAgc2xpZGVyLmluZGV4ID0gaTtcblx0ICAgICAgICAgIGlmICh0b3VjaC5leGlzdHMpIHtcblx0ICAgICAgICAgICAgc2xpZGVyLmJhci5pbmRleCA9IGk7XG5cdCAgICAgICAgICAgIHNsaWRlci5maWxsYmFyLmluZGV4ID0gaTtcblx0ICAgICAgICAgICAgc2xpZGVyLnByZUNsaWNrID0gc2xpZGVyLnByZU1vdmUgPSBzbGlkZXIucHJlUmVsZWFzZSA9IGZ1bmN0aW9uICgpIHt9O1xuXHQgICAgICAgICAgICBzbGlkZXIuY2xpY2sgPSBzbGlkZXIubW92ZSA9IHNsaWRlci5yZWxlYXNlID0gZnVuY3Rpb24gKCkge307XG5cdCAgICAgICAgICAgIHNsaWRlci5wcmVUb3VjaCA9IHNsaWRlci5wcmVUb3VjaE1vdmUgPSBzbGlkZXIucHJlVG91Y2hSZWxlYXNlID0gZnVuY3Rpb24gKCkge307XG5cdCAgICAgICAgICAgIHNsaWRlci50b3VjaCA9IHNsaWRlci50b3VjaE1vdmUgPSBzbGlkZXIudG91Y2hSZWxlYXNlID0gZnVuY3Rpb24gKCkge307XG5cdCAgICAgICAgICB9XG5cdFxuXHQgICAgICAgICAgdGhpcy5zbGlkZXJzLnB1c2goc2xpZGVyKTtcblx0ICAgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAodG91Y2guZXhpc3RzKSB7XG5cdCAgICAgICAgICB0aGlzLmFkZFRvdWNoTGlzdGVuZXJzKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY29sb3JJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbG9ySW50ZXJmYWNlKCkge1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zbGlkZXJzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICB0aGlzLnNsaWRlcnNbaV0uY29sb3JzID0gdGhpcy5jb2xvcnM7XG5cdCAgICAgICAgICB0aGlzLnNsaWRlcnNbaV0uY29sb3JJbnRlcmZhY2UoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzaXplSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBzaXplSW50ZXJmYWNlKCkge1xuXHRcblx0ICAgICAgICB2YXIgc2xpZGVyV2lkdGggPSB0aGlzLndpZHRoIC8gdGhpcy5zbGlkZXJzLmxlbmd0aDtcblx0ICAgICAgICB2YXIgc2xpZGVySGVpZ2h0ID0gdGhpcy5oZWlnaHQ7XG5cdFxuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zbGlkZXJzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICB0aGlzLnNsaWRlcnNbaV0ucmVzaXplKHNsaWRlcldpZHRoLCBzbGlkZXJIZWlnaHQpO1xuXHQgICAgICAgICAgdGhpcy5zbGlkZXJzW2ldLmN1c3RvbVN0eWxlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdXBkYXRlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiB1cGRhdGUoaW5kZXgsIHZhbHVlKSB7XG5cdCAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHtcblx0ICAgICAgICAgIGluZGV4OiBpbmRleCxcblx0ICAgICAgICAgIHZhbHVlOiB2YWx1ZVxuXHQgICAgICAgIH0pO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgYWRkVG91Y2hMaXN0ZW5lcnM6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGFkZFRvdWNoTGlzdGVuZXJzKCkge1xuXHQgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgICAgIHRoaXMucHJlQ2xpY2sgPSB0aGlzLnByZU1vdmUgPSB0aGlzLnByZVJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7fTtcblx0ICAgICAgICB0aGlzLmNsaWNrID0gdGhpcy5tb3ZlID0gdGhpcy5yZWxlYXNlID0gZnVuY3Rpb24gKCkge307XG5cdCAgICAgICAgdGhpcy5wcmVUb3VjaCA9IHRoaXMucHJlVG91Y2hNb3ZlID0gdGhpcy5wcmVUb3VjaFJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7fTtcblx0ICAgICAgICB0aGlzLnRvdWNoID0gdGhpcy50b3VjaE1vdmUgPSB0aGlzLnRvdWNoUmVsZWFzZSA9IGZ1bmN0aW9uICgpIHt9O1xuXHRcblx0ICAgICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gZmFsc2U7XG5cdFxuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCBmdW5jdGlvbiAoZSkge1xuXHQgICAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGUudGFyZ2V0VG91Y2hlc1swXS5jbGllbnRYLCBlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSk7XG5cdCAgICAgICAgICB2YXIgc2xpZGVyID0gX3RoaXMuc2xpZGVyc1tlbGVtZW50LmluZGV4XTtcblx0ICAgICAgICAgIGlmICghc2xpZGVyLm9mZnNldCkge1xuXHQgICAgICAgICAgICBzbGlkZXIub2Zmc2V0ID0gZG9tLmZpbmRQb3NpdGlvbihzbGlkZXIuZWxlbWVudCk7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgICBzbGlkZXIubW91c2UgPSBkb20ubG9jYXRlTW91c2UoZSwgc2xpZGVyLm9mZnNldCk7XG5cdCAgICAgICAgICBzbGlkZXIuZG93bigpO1xuXHQgICAgICAgICAgX3RoaXMuY3VycmVudEVsZW1lbnQgPSBlbGVtZW50LmluZGV4O1xuXHQgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblx0ICAgICAgICB9KTtcblx0XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgZnVuY3Rpb24gKGUpIHtcblx0ICAgICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCwgZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFkpO1xuXHQgICAgICAgICAgdmFyIHNsaWRlciA9IF90aGlzLnNsaWRlcnNbZWxlbWVudC5pbmRleF07XG5cdCAgICAgICAgICBpZiAoIXNsaWRlci5vZmZzZXQpIHtcblx0ICAgICAgICAgICAgc2xpZGVyLm9mZnNldCA9IGRvbS5maW5kUG9zaXRpb24oc2xpZGVyLmVsZW1lbnQpO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgICAgc2xpZGVyLm1vdXNlID0gZG9tLmxvY2F0ZU1vdXNlKGUsIHNsaWRlci5vZmZzZXQpO1xuXHQgICAgICAgICAgaWYgKGVsZW1lbnQuaW5kZXggIT09IF90aGlzLmN1cnJlbnRFbGVtZW50KSB7XG5cdCAgICAgICAgICAgIGlmIChfdGhpcy5jdXJyZW50RWxlbWVudCA+PSAwKSB7XG5cdCAgICAgICAgICAgICAgdmFyIHBhc3RzbGlkZXIgPSBfdGhpcy5zbGlkZXJzW190aGlzLmN1cnJlbnRFbGVtZW50XTtcblx0ICAgICAgICAgICAgICBwYXN0c2xpZGVyLnVwKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgc2xpZGVyLmRvd24oKTtcblx0ICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHNsaWRlci5zbGlkZSgpO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgICAgX3RoaXMuY3VycmVudEVsZW1lbnQgPSBlbGVtZW50LmluZGV4O1xuXHQgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblx0ICAgICAgICB9KTtcblx0XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCBmdW5jdGlvbiAoZSkge1xuXHQgICAgICAgICAgLy8gbm8gdG91Y2hlcyB0byBjYWxjdWxhdGUgYmVjYXVzZSBub25lIHJlbWFpbmluZ1xuXHQgICAgICAgICAgdmFyIHNsaWRlciA9IF90aGlzLnNsaWRlcnNbX3RoaXMuY3VycmVudEVsZW1lbnRdO1xuXHQgICAgICAgICAgc2xpZGVyLnVwKCk7XG5cdCAgICAgICAgICBfdGhpcy5pbnRlcmFjdGluZyA9IGZhbHNlO1xuXHQgICAgICAgICAgX3RoaXMuY3VycmVudEVsZW1lbnQgPSBmYWxzZTtcblx0ICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblx0ICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBudW1iZXJPZlNsaWRlcnM6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBHZXQgb3Igc2V0IHRoZSBudW1iZXIgb2Ygc2xpZGVyc1xuXHQgICAgICBAdHlwZSB7TnVtYmVyfVxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuc2xpZGVycy5sZW5ndGg7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICBpZiAodiA9PT0gdGhpcy5zbGlkZXJzLmxlbmd0aCkge1xuXHQgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLnNsaWRlcnMuZm9yRWFjaChmdW5jdGlvbiAoc2xpZGVyKSB7XG5cdCAgICAgICAgICBzbGlkZXIuZGVzdHJveSgpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRoaXMuZW1wdHkoKTtcblx0ICAgICAgICB0aGlzLl9udW1iZXJPZlNsaWRlcnMgPSB2O1xuXHQgICAgICAgIHRoaXMuYnVpbGRJbnRlcmZhY2UoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIG1pbjoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIExvd2VyIGxpbWl0IG9mIHRoZSBtdWx0aXNsaWRlcidzIG91dHB1dCByYW5nZVxuXHQgICAgICBAdHlwZSB7bnVtYmVyfVxuXHQgICAgICBAZXhhbXBsZSBtdWx0aXNsaWRlci5taW4gPSAxMDAwO1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuc2xpZGVyc1swXS5taW47XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLnNsaWRlcnMuZm9yRWFjaChmdW5jdGlvbiAoc2xpZGVyKSB7XG5cdCAgICAgICAgICBzbGlkZXIubWluID0gdjtcblx0ICAgICAgICB9KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIG1heDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFVwcGVyIGxpbWl0IG9mIHRoZSBtdWx0aXNsaWRlcidzIG91dHB1dCByYW5nZVxuXHQgICAgICBAdHlwZSB7bnVtYmVyfVxuXHQgICAgICBAZXhhbXBsZSBtdWx0aXNsaWRlci5tYXggPSAxMDAwO1xuXHQgICAgICAqL1xuXHRcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuc2xpZGVyc1swXS5tYXg7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLnNsaWRlcnMuZm9yRWFjaChmdW5jdGlvbiAoc2xpZGVyKSB7XG5cdCAgICAgICAgICBzbGlkZXIubWF4ID0gdjtcblx0ICAgICAgICB9KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHN0ZXA6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBUaGUgaW5jcmVtZW50IHRoYXQgdGhlIG11bHRpc2xpZGVyJ3MgdmFsdWUgY2hhbmdlcyBieS5cblx0ICAgICAgQHR5cGUge251bWJlcn1cblx0ICAgICAgQGV4YW1wbGUgbXVsdGlzbGlkZXIuc3RlcCA9IDU7XG5cdCAgICAgICovXG5cdFxuXHQgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5zbGlkZXJzWzBdLnN0ZXA7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICB0aGlzLnNsaWRlcnMuZm9yRWFjaChmdW5jdGlvbiAoc2xpZGVyKSB7XG5cdCAgICAgICAgICBzbGlkZXIuc3RlcCA9IHY7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzZXRTbGlkZXI6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBTZXQgdGhlIHZhbHVlIG9mIGFuIGluZGl2aWR1YWwgc2xpZGVyXG5cdCAgICAgIEBwYXJhbSBpbmRleCB7bnVtYmVyfSBTbGlkZXIgaW5kZXhcblx0ICAgICAgQHBhcmFtIHZhbHVlIHtudW1iZXJ9IE5ldyBzbGlkZXIgdmFsdWVcblx0ICAgICAgQGV4YW1wbGVcblx0ICAgICAgLy8gU2V0IHRoZSBmaXJzdCBzbGlkZXIgdG8gdmFsdWUgMC41XG5cdCAgICAgIG11bHRpc2xpZGVyLnNldFNsaWRlcigwLDAuNSlcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRTbGlkZXIoaW5kZXgsIHZhbHVlKSB7XG5cdCAgICAgICAgdGhpcy5zbGlkZXJzW2luZGV4XS52YWx1ZSA9IHZhbHVlO1xuXHQgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB7XG5cdCAgICAgICAgICBpbmRleDogaW5kZXgsXG5cdCAgICAgICAgICB2YWx1ZTogdmFsdWVcblx0ICAgICAgICB9KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHNldEFsbFNsaWRlcnM6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBTZXQgdGhlIHZhbHVlIG9mIGFsbCBzbGlkZXJzIGF0IG9uY2UuIElmIHRoZSBzaXplIG9mIHRoZSBpbnB1dCBhcnJheSBkb2VzIG5vdCBtYXRjaCB0aGUgY3VycmVudCBudW1iZXIgb2Ygc2xpZGVycywgdGhlIHZhbHVlIGFycmF5IHdpbGwgcmVwZWF0IHVudGlsIGFsbCBzbGlkZXJzIGhhdmUgYmVlbiBzZXQuIEkuZS4gYW4gaW5wdXQgYXJyYXkgb2YgbGVuZ3RoIDEgd2lsbCBzZXQgYWxsIHNsaWRlcnMgdG8gdGhhdCB2YWx1ZS5cblx0ICAgICAgQHBhcmFtIHZhbHVlcyB7QXJyYXl9IEFsbCBzbGlkZXIgdmFsdWVzXG5cdCAgICAgIEBleGFtcGxlXG5cdCAgICAgIG11bHRpc2xpZGVyLnNldEFsbFNsaWRlcnMoWzAuMiwwLjMsMC40LDAuNSwwLjZdKVxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNldEFsbFNsaWRlcnModmFsdWVzKSB7XG5cdCAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblx0XG5cdCAgICAgICAgdGhpcy52YWx1ZXMgPSB2YWx1ZXM7XG5cdCAgICAgICAgdGhpcy5zbGlkZXJzLmZvckVhY2goZnVuY3Rpb24gKHNsaWRlciwgaSkge1xuXHQgICAgICAgICAgc2xpZGVyLnZhbHVlID0gdmFsdWVzW2kgJSB2YWx1ZXMubGVuZ3RoXTtcblx0ICAgICAgICAgIF90aGlzLmVtaXQoXCJjaGFuZ2VcIiwge1xuXHQgICAgICAgICAgICBpbmRleDogaSxcblx0ICAgICAgICAgICAgdmFsdWU6IHNsaWRlci52YWx1ZVxuXHQgICAgICAgICAgfSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIE11bHRpc2xpZGVyO1xuXHR9KShJbnRlcmZhY2UpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBNdWx0aXNsaWRlcjtcblxuLyoqKi8gfSksXG4vKiAzMiAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkID0gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBcImRlZmF1bHRcIjogb2JqIH07IH07XG5cdFxuXHR2YXIgX2NyZWF0ZUNsYXNzID0gKGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGtleSBpbiBwcm9wcykgeyB2YXIgcHJvcCA9IHByb3BzW2tleV07IHByb3AuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKHByb3AudmFsdWUpIHByb3Aud3JpdGFibGUgPSB0cnVlOyB9IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpOyB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cdFxuXHR2YXIgX2dldCA9IGZ1bmN0aW9uIGdldChvYmplY3QsIHByb3BlcnR5LCByZWNlaXZlcikgeyB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBwcm9wZXJ0eSk7IGlmIChkZXNjID09PSB1bmRlZmluZWQpIHsgdmFyIHBhcmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpOyBpZiAocGFyZW50ID09PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gZWxzZSB7IHJldHVybiBnZXQocGFyZW50LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpOyB9IH0gZWxzZSBpZiAoXCJ2YWx1ZVwiIGluIGRlc2MgJiYgZGVzYy53cml0YWJsZSkgeyByZXR1cm4gZGVzYy52YWx1ZTsgfSBlbHNlIHsgdmFyIGdldHRlciA9IGRlc2MuZ2V0OyBpZiAoZ2V0dGVyID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpOyB9IH07XG5cdFxuXHR2YXIgX2luaGVyaXRzID0gZnVuY3Rpb24gKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgXCIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH07XG5cdFxuXHR2YXIgX2NsYXNzQ2FsbENoZWNrID0gZnVuY3Rpb24gKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH07XG5cdFxuXHR2YXIgc3ZnID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTtcblx0dmFyIEludGVyZmFjZSA9IF9fd2VicGFja19yZXF1aXJlX18oNik7XG5cdHZhciBTdGVwID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMSk7XG5cdFxuXHR2YXIgSW50ZXJhY3Rpb24gPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfX3dlYnBhY2tfcmVxdWlyZV9fKDEyKSk7XG5cdFxuXHR2YXIgU2xpZGVyVGVtcGxhdGUgPSAoZnVuY3Rpb24gKF9JbnRlcmZhY2UpIHtcblx0ICBmdW5jdGlvbiBTbGlkZXJUZW1wbGF0ZShhcmdzLCBvcHRpb25zLCBkZWZhdWx0cykge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFNsaWRlclRlbXBsYXRlKTtcblx0XG5cdCAgICBfZ2V0KE9iamVjdC5nZXRQcm90b3R5cGVPZihTbGlkZXJUZW1wbGF0ZS5wcm90b3R5cGUpLCBcImNvbnN0cnVjdG9yXCIsIHRoaXMpLmNhbGwodGhpcywgYXJncywgb3B0aW9ucywgZGVmYXVsdHMpO1xuXHRcblx0ICAgIHRoaXMub3JpZW50YXRpb24gPSB0aGlzLnNldHRpbmdzLm9yaWVudGF0aW9uO1xuXHRcblx0ICAgIC8vICB0aGlzLm1vZGUgPSB0aGlzLnNldHRpbmdzLm1vZGU7XG5cdFxuXHQgICAgdGhpcy5oYXNLbm9iID0gdGhpcy5zZXR0aW5ncy5oYXNLbm9iO1xuXHRcblx0ICAgIC8vIHRoaXMuc3RlcCBzaG91bGQgZXZlbnR1YWxseSBiZSBnZXQvc2V0XG5cdCAgICAvLyB1cGRhdGluZyBpdCB3aWxsIHVwZGF0ZSB0aGUgX3ZhbHVlIHN0ZXAgbW9kZWxcblx0ICAgIC8vICB0aGlzLnN0ZXAgPSB0aGlzLnNldHRpbmdzLnN0ZXA7IC8vIGZsb2F0XG5cdFxuXHQgICAgdGhpcy5fdmFsdWUgPSBuZXcgU3RlcCh0aGlzLnNldHRpbmdzLnNjYWxlWzBdLCB0aGlzLnNldHRpbmdzLnNjYWxlWzFdLCB0aGlzLnNldHRpbmdzLnN0ZXAsIHRoaXMuc2V0dGluZ3MudmFsdWUpO1xuXHRcblx0ICAgIHRoaXMuaW5pdCgpO1xuXHRcblx0ICAgIHRoaXMucG9zaXRpb24gPSBuZXcgSW50ZXJhY3Rpb24uSGFuZGxlKHRoaXMuc2V0dGluZ3MubW9kZSwgdGhpcy5vcmllbnRhdGlvbiwgWzAsIHRoaXMud2lkdGhdLCBbdGhpcy5oZWlnaHQsIDBdKTtcblx0ICAgIHRoaXMucG9zaXRpb24udmFsdWUgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXHRcblx0ICAgIHRoaXMudmFsdWUgPSB0aGlzLl92YWx1ZS52YWx1ZTtcblx0XG5cdCAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy52YWx1ZSk7XG5cdCAgfVxuXHRcblx0ICBfaW5oZXJpdHMoU2xpZGVyVGVtcGxhdGUsIF9JbnRlcmZhY2UpO1xuXHRcblx0ICBfY3JlYXRlQ2xhc3MoU2xpZGVyVGVtcGxhdGUsIHtcblx0ICAgIGJ1aWxkSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBidWlsZEludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgdGhpcy5iYXIgPSBzdmcuY3JlYXRlKFwicmVjdFwiKTtcblx0ICAgICAgICB0aGlzLmZpbGxiYXIgPSBzdmcuY3JlYXRlKFwicmVjdFwiKTtcblx0ICAgICAgICB0aGlzLmtub2IgPSBzdmcuY3JlYXRlKFwiY2lyY2xlXCIpO1xuXHRcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXIpO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmZpbGxiYXIpO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmtub2IpO1xuXHRcblx0ICAgICAgICB0aGlzLnNpemVJbnRlcmZhY2UoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHNpemVJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNpemVJbnRlcmZhY2UoKSB7XG5cdFxuXHQgICAgICAgIGlmICghdGhpcy5zZXR0aW5ncy5vcmllbnRhdGlvbikge1xuXHQgICAgICAgICAgaWYgKHRoaXMud2lkdGggPCB0aGlzLmhlaWdodCkge1xuXHQgICAgICAgICAgICB0aGlzLm9yaWVudGF0aW9uID0gXCJ2ZXJ0aWNhbFwiO1xuXHQgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgdGhpcy5vcmllbnRhdGlvbiA9IFwiaG9yaXpvbnRhbFwiO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0XG5cdCAgICAgICAgdmFyIHggPSB1bmRlZmluZWQsXG5cdCAgICAgICAgICAgIHkgPSB1bmRlZmluZWQsXG5cdCAgICAgICAgICAgIHcgPSB1bmRlZmluZWQsXG5cdCAgICAgICAgICAgIGggPSB1bmRlZmluZWQsXG5cdCAgICAgICAgICAgIGJhck9mZnNldCA9IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgY29ybmVyUmFkaXVzID0gdW5kZWZpbmVkO1xuXHQgICAgICAgIHRoaXMua25vYkRhdGEgPSB7XG5cdCAgICAgICAgICBsZXZlbDogMCxcblx0ICAgICAgICAgIHI6IDBcblx0ICAgICAgICB9O1xuXHRcblx0ICAgICAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gXCJ2ZXJ0aWNhbFwiKSB7XG5cdCAgICAgICAgICB0aGlzLnRoaWNrbmVzcyA9IHRoaXMud2lkdGggLyAyO1xuXHQgICAgICAgICAgeCA9IHRoaXMud2lkdGggLyAyO1xuXHQgICAgICAgICAgeSA9IDA7XG5cdCAgICAgICAgICB3ID0gdGhpcy50aGlja25lc3M7XG5cdCAgICAgICAgICBoID0gdGhpcy5oZWlnaHQ7XG5cdCAgICAgICAgICB0aGlzLmtub2JEYXRhLnIgPSB0aGlzLnRoaWNrbmVzcyAqIDAuODtcblx0ICAgICAgICAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSBoIC0gdGhpcy5ub3JtYWxpemVkICogaDtcblx0ICAgICAgICAgIGJhck9mZnNldCA9IFwidHJhbnNsYXRlKFwiICsgdGhpcy50aGlja25lc3MgKiAtMSAvIDIgKyBcIiwwKVwiO1xuXHQgICAgICAgICAgY29ybmVyUmFkaXVzID0gdyAvIDI7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMudGhpY2tuZXNzID0gdGhpcy5oZWlnaHQgLyAyO1xuXHQgICAgICAgICAgeCA9IDA7XG5cdCAgICAgICAgICB5ID0gdGhpcy5oZWlnaHQgLyAyO1xuXHQgICAgICAgICAgdyA9IHRoaXMud2lkdGg7XG5cdCAgICAgICAgICBoID0gdGhpcy50aGlja25lc3M7XG5cdCAgICAgICAgICB0aGlzLmtub2JEYXRhLnIgPSB0aGlzLnRoaWNrbmVzcyAqIDAuODtcblx0ICAgICAgICAgIHRoaXMua25vYkRhdGEubGV2ZWwgPSB0aGlzLm5vcm1hbGl6ZWQgKiB3O1xuXHQgICAgICAgICAgYmFyT2Zmc2V0ID0gXCJ0cmFuc2xhdGUoMCxcIiArIHRoaXMudGhpY2tuZXNzICogLTEgLyAyICsgXCIpXCI7XG5cdCAgICAgICAgICBjb3JuZXJSYWRpdXMgPSBoIC8gMjtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcInhcIiwgeCk7XG5cdCAgICAgICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKFwieVwiLCB5KTtcblx0ICAgICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgYmFyT2Zmc2V0KTtcblx0ICAgICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoXCJyeFwiLCBjb3JuZXJSYWRpdXMpOyAvLyBjb3JuZXIgcmFkaXVzXG5cdCAgICAgICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKFwicnlcIiwgY29ybmVyUmFkaXVzKTtcblx0ICAgICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiLCB3KTtcblx0ICAgICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgaCk7XG5cdFxuXHQgICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSBcInZlcnRpY2FsXCIpIHtcblx0ICAgICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoXCJ4XCIsIHgpO1xuXHQgICAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcInlcIiwgdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG5cdCAgICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgdyk7XG5cdCAgICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGggLSB0aGlzLmtub2JEYXRhLmxldmVsKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcInhcIiwgMCk7XG5cdCAgICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwieVwiLCB5KTtcblx0ICAgICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiLCB0aGlzLmtub2JEYXRhLmxldmVsKTtcblx0ICAgICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgaCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuZmlsbGJhci5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgYmFyT2Zmc2V0KTtcblx0ICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwicnhcIiwgY29ybmVyUmFkaXVzKTtcblx0ICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwicnlcIiwgY29ybmVyUmFkaXVzKTtcblx0XG5cdCAgICAgICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09IFwidmVydGljYWxcIikge1xuXHQgICAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImN4XCIsIHgpO1xuXHQgICAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImN5XCIsIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiY3hcIiwgdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG5cdCAgICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiY3lcIiwgeSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJyXCIsIHRoaXMua25vYkRhdGEucik7XG5cdFxuXHQgICAgICAgIGlmICh0aGlzLnBvc2l0aW9uKSB7XG5cdCAgICAgICAgICB0aGlzLnBvc2l0aW9uLnJlc2l6ZShbMCwgdGhpcy53aWR0aF0sIFt0aGlzLmhlaWdodCwgMF0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNvbG9ySW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb2xvckludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCB0aGlzLmNvbG9ycy5maWxsKTtcblx0ICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCB0aGlzLmNvbG9ycy5hY2NlbnQpO1xuXHQgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cdCAgICAgICAgaWYgKCF0aGlzLmhhc0tub2IpIHtcblx0ICAgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwibm9uZVwiKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByZW5kZXI6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcblx0ICAgICAgICBpZiAoIXRoaXMuY2xpY2tlZCkge1xuXHQgICAgICAgICAgdGhpcy5rbm9iRGF0YS5yID0gdGhpcy50aGlja25lc3MgKiAwLjc1O1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiclwiLCB0aGlzLmtub2JEYXRhLnIpO1xuXHRcblx0ICAgICAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gXCJ2ZXJ0aWNhbFwiKSB7XG5cdCAgICAgICAgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZCAqIHRoaXMuaGVpZ2h0O1xuXHQgICAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImN5XCIsIHRoaXMuaGVpZ2h0IC0gdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG5cdCAgICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwieVwiLCB0aGlzLmhlaWdodCAtIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuXHQgICAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCB0aGlzLmtub2JEYXRhLmxldmVsKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdGhpcy5rbm9iRGF0YS5sZXZlbCA9IHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQgKiB0aGlzLndpZHRoO1xuXHQgICAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImN4XCIsIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuXHQgICAgICAgICAgdGhpcy5maWxsYmFyLnNldEF0dHJpYnV0ZShcInhcIiwgMCk7XG5cdCAgICAgICAgICB0aGlzLmZpbGxiYXIuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgZG93bjoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gZG93bigpIHtcblx0ICAgICAgICB0aGlzLmNsaWNrZWQgPSB0cnVlO1xuXHQgICAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC45O1xuXHQgICAgICAgIHRoaXMucG9zaXRpb24uYW5jaG9yID0gdGhpcy5tb3VzZTtcblx0ICAgICAgICB0aGlzLnNsaWRlKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzbGlkZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc2xpZGUoKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuXHQgICAgICAgICAgdGhpcy5wb3NpdGlvbi51cGRhdGUodGhpcy5tb3VzZSk7XG5cdCAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5fdmFsdWUudXBkYXRlTm9ybWFsKHRoaXMucG9zaXRpb24udmFsdWUpO1xuXHQgICAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMudmFsdWUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHVwOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiB1cCgpIHtcblx0ICAgICAgICB0aGlzLmNsaWNrZWQgPSBmYWxzZTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbm9ybWFsaXplZDoge1xuXHQgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHZhbHVlOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgVGhlIHNsaWRlcidzIGN1cnJlbnQgdmFsdWUuIElmIHNldCBtYW51YWxseSwgd2lsbCB1cGRhdGUgdGhlIGludGVyZmFjZSBhbmQgdHJpZ2dlciB0aGUgb3V0cHV0IGV2ZW50LlxuXHQgICAgICBAdHlwZSB7bnVtYmVyfVxuXHQgICAgICBAZXhhbXBsZSBzbGlkZXIudmFsdWUgPSAxMDtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl92YWx1ZS52YWx1ZTtcblx0ICAgICAgfSxcblx0ICAgICAgc2V0OiBmdW5jdGlvbiAodikge1xuXHQgICAgICAgIHRoaXMuX3ZhbHVlLnVwZGF0ZSh2KTtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbWluOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgTG93ZXIgbGltaXQgb2YgdGhlIHNsaWRlcnMncyBvdXRwdXQgcmFuZ2Vcblx0ICAgICAgQHR5cGUge251bWJlcn1cblx0ICAgICAgQGV4YW1wbGUgc2xpZGVyLm1pbiA9IDEwMDA7XG5cdCAgICAgICovXG5cdFxuXHQgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWUubWluO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdGhpcy5fdmFsdWUubWluID0gdjtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIG1heDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFVwcGVyIGxpbWl0IG9mIHRoZSBzbGlkZXIncyBvdXRwdXQgcmFuZ2Vcblx0ICAgICAgQHR5cGUge251bWJlcn1cblx0ICAgICAgQGV4YW1wbGUgc2xpZGVyLm1heCA9IDEwMDA7XG5cdCAgICAgICovXG5cdFxuXHQgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWUubWF4O1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdGhpcy5fdmFsdWUubWF4ID0gdjtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHN0ZXA6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBUaGUgaW5jcmVtZW50IHRoYXQgdGhlIHNsaWRlcidzIHZhbHVlIGNoYW5nZXMgYnkuXG5cdCAgICAgIEB0eXBlIHtudW1iZXJ9XG5cdCAgICAgIEBleGFtcGxlIHNsaWRlci5zdGVwID0gNTtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5zdGVwO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdGhpcy5fdmFsdWUuc3RlcCA9IHY7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBtb2RlOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgQWJzb2x1dGUgbW9kZSAoc2xpZGVyJ3MgdmFsdWUganVtcHMgdG8gbW91c2UgY2xpY2sgcG9zaXRpb24pIG9yIHJlbGF0aXZlIG1vZGUgKG1vdXNlIGRyYWcgY2hhbmdlcyB2YWx1ZSByZWxhdGl2ZSB0byBpdHMgY3VycmVudCBwb3NpdGlvbikuIERlZmF1bHQ6IFwicmVsYXRpdmVcIi5cblx0ICAgICAgQHR5cGUge3N0cmluZ31cblx0ICAgICAgQGV4YW1wbGUgc2xpZGVyLm1vZGUgPSBcInJlbGF0aXZlXCI7XG5cdCAgICAgICovXG5cdFxuXHQgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi5tb2RlO1xuXHQgICAgICB9LFxuXHQgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgdGhpcy5wb3NpdGlvbi5tb2RlID0gdjtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pO1xuXHRcblx0ICByZXR1cm4gU2xpZGVyVGVtcGxhdGU7XG5cdH0pKEludGVyZmFjZSk7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IFNsaWRlclRlbXBsYXRlO1xuXG4vKioqLyB9KSxcbi8qIDMzICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQgPSBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IFwiZGVmYXVsdFwiOiBvYmogfTsgfTtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KG9iamVjdCwgcHJvcGVydHksIHJlY2VpdmVyKSB7IHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHByb3BlcnR5KTsgaWYgKGRlc2MgPT09IHVuZGVmaW5lZCkgeyB2YXIgcGFyZW50ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCk7IGlmIChwYXJlbnQgPT09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBlbHNlIHsgcmV0dXJuIGdldChwYXJlbnQsIHByb3BlcnR5LCByZWNlaXZlcik7IH0gfSBlbHNlIGlmIChcInZhbHVlXCIgaW4gZGVzYyAmJiBkZXNjLndyaXRhYmxlKSB7IHJldHVybiBkZXNjLnZhbHVlOyB9IGVsc2UgeyB2YXIgZ2V0dGVyID0gZGVzYy5nZXQ7IGlmIChnZXR0ZXIgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IHJldHVybiBnZXR0ZXIuY2FsbChyZWNlaXZlcik7IH0gfTtcblx0XG5cdHZhciBfaW5oZXJpdHMgPSBmdW5jdGlvbiAoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSBcImZ1bmN0aW9uXCIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCBcIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdHZhciBzdmcgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpO1xuXHR2YXIgbWF0aCA9IF9fd2VicGFja19yZXF1aXJlX18oNSk7XG5cdHZhciBJbnRlcmZhY2UgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpO1xuXHR2YXIgU3RlcCA9IF9fd2VicGFja19yZXF1aXJlX18oMTEpO1xuXHRcblx0dmFyIEludGVyYWN0aW9uID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX193ZWJwYWNrX3JlcXVpcmVfXygxMikpO1xuXHRcblx0LyoqXG5cdCogUGFuXG5cdCpcblx0KiBAZGVzY3JpcHRpb24gU3RlcmVvIGNyb3NzZmFkZXIuXG5cdCpcblx0KiBAZGVtbyA8c3BhbiBuZXh1cy11aT1cInBhblwiPjwvc3Bhbj5cblx0KlxuXHQqIEBleGFtcGxlXG5cdCogdmFyIHBhbiA9IG5ldyBOZXh1cy5QYW4oJyN0YXJnZXQnKVxuXHQqXG5cdCogQG91dHB1dFxuXHQqIGNoYW5nZVxuXHQqIEZpcmVzIGFueSB0aW1lIHRoZSBpbnRlcmZhY2UncyB2YWx1ZSBjaGFuZ2VzLiA8YnI+XG5cdCogVGhlIGV2ZW50IGRhdGEgaXMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGludGVyZmFjZSdzIDxpPnZhbHVlPC9pPiAoLTEgdG8gMSksIGFzIHdlbGwgYXMgPGk+TDwvaT4gYW5kIDxpPlI8L2k+IGFtcGxpdHVkZSB2YWx1ZXMgKDAtMSkgZm9yIGxlZnQgYW5kIHJpZ2h0IHNwZWFrZXJzLCBjYWxjdWxhdGVkIGJ5IGEgc3F1YXJlLXJvb3QgY3Jvc3NmYWRlIGFsZ29yaXRobS5cblx0KlxuXHQqIEBvdXRwdXRleGFtcGxlXG5cdCogcGFuLm9uKCdjaGFuZ2UnLGZ1bmN0aW9uKHYpIHtcblx0KiAgIGNvbnNvbGUubG9nKHYpO1xuXHQqIH0pXG5cdCpcblx0KlxuXHQqL1xuXHRcblx0dmFyIFBhbiA9IChmdW5jdGlvbiAoX0ludGVyZmFjZSkge1xuXHQgIGZ1bmN0aW9uIFBhbigpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQYW4pO1xuXHRcblx0ICAgIHZhciBvcHRpb25zID0gW1wic2NhbGVcIiwgXCJ2YWx1ZVwiXTtcblx0XG5cdCAgICB2YXIgZGVmYXVsdHMgPSB7XG5cdCAgICAgIHNpemU6IFsxMjAsIDIwXSxcblx0ICAgICAgb3JpZW50YXRpb246IFwiaG9yaXpvbnRhbFwiLFxuXHQgICAgICBtb2RlOiBcInJlbGF0aXZlXCIsXG5cdCAgICAgIHNjYWxlOiBbLTEsIDFdLFxuXHQgICAgICBzdGVwOiAwLFxuXHQgICAgICB2YWx1ZTogMCxcblx0ICAgICAgaGFzS25vYjogdHJ1ZVxuXHQgICAgfTtcblx0XG5cdCAgICBfZ2V0KE9iamVjdC5nZXRQcm90b3R5cGVPZihQYW4ucHJvdG90eXBlKSwgXCJjb25zdHJ1Y3RvclwiLCB0aGlzKS5jYWxsKHRoaXMsIGFyZ3VtZW50cywgb3B0aW9ucywgZGVmYXVsdHMpO1xuXHRcblx0ICAgIHRoaXMub3JpZW50YXRpb24gPSB0aGlzLnNldHRpbmdzLm9yaWVudGF0aW9uO1xuXHRcblx0ICAgIHRoaXMubW9kZSA9IHRoaXMuc2V0dGluZ3MubW9kZTtcblx0XG5cdCAgICB0aGlzLmhhc0tub2IgPSB0aGlzLnNldHRpbmdzLmhhc0tub2I7XG5cdFxuXHQgICAgLy8gdGhpcy5zdGVwIHNob3VsZCBldmVudHVhbGx5IGJlIGdldC9zZXRcblx0ICAgIC8vIHVwZGF0aW5nIGl0IHdpbGwgdXBkYXRlIHRoZSBfdmFsdWUgc3RlcCBtb2RlbFxuXHQgICAgdGhpcy5zdGVwID0gdGhpcy5zZXR0aW5ncy5zdGVwOyAvLyBmbG9hdFxuXHRcblx0ICAgIHRoaXMuX3ZhbHVlID0gbmV3IFN0ZXAodGhpcy5zZXR0aW5ncy5zY2FsZVswXSwgdGhpcy5zZXR0aW5ncy5zY2FsZVsxXSwgdGhpcy5zZXR0aW5ncy5zdGVwLCB0aGlzLnNldHRpbmdzLnZhbHVlKTtcblx0XG5cdCAgICB0aGlzLmluaXQoKTtcblx0XG5cdCAgICB0aGlzLnBvc2l0aW9uID0gbmV3IEludGVyYWN0aW9uLkhhbmRsZSh0aGlzLm1vZGUsIHRoaXMub3JpZW50YXRpb24sIFswLCB0aGlzLndpZHRoXSwgW3RoaXMuaGVpZ2h0LCAwXSk7XG5cdCAgICB0aGlzLnBvc2l0aW9uLnZhbHVlID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZDtcblx0XG5cdCAgICB0aGlzLnZhbHVlID0gdGhpcy5fdmFsdWUudmFsdWU7XG5cdFxuXHQgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMudmFsdWUpO1xuXHQgIH1cblx0XG5cdCAgX2luaGVyaXRzKFBhbiwgX0ludGVyZmFjZSk7XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhQYW4sIHtcblx0ICAgIGJ1aWxkSW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBidWlsZEludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgdGhpcy5iYXIgPSBzdmcuY3JlYXRlKFwicmVjdFwiKTtcblx0ICAgICAgICB0aGlzLmtub2IgPSBzdmcuY3JlYXRlKFwiY2lyY2xlXCIpO1xuXHRcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5iYXIpO1xuXHQgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmtub2IpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2l6ZUludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc2l6ZUludGVyZmFjZSgpIHtcblx0XG5cdCAgICAgICAgaWYgKHRoaXMucG9zaXRpb24pIHtcblx0ICAgICAgICAgIHRoaXMucG9zaXRpb24ucmVzaXplKFswLCB0aGlzLndpZHRoXSwgW3RoaXMuaGVpZ2h0LCAwXSk7XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICBpZiAodGhpcy53aWR0aCA8IHRoaXMuaGVpZ2h0KSB7XG5cdCAgICAgICAgICB0aGlzLm9yaWVudGF0aW9uID0gXCJ2ZXJ0aWNhbFwiO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aGlzLm9yaWVudGF0aW9uID0gXCJob3Jpem9udGFsXCI7XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICB2YXIgeCA9IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgeSA9IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgdyA9IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgaCA9IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgYmFyT2Zmc2V0ID0gdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICBjb3JuZXJSYWRpdXMgPSB1bmRlZmluZWQ7XG5cdCAgICAgICAgdGhpcy5rbm9iRGF0YSA9IHtcblx0ICAgICAgICAgIGxldmVsOiAwLFxuXHQgICAgICAgICAgcjogMFxuXHQgICAgICAgIH07XG5cdFxuXHQgICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSBcInZlcnRpY2FsXCIpIHtcblx0ICAgICAgICAgIHRoaXMudGhpY2tuZXNzID0gdGhpcy53aWR0aCAvIDI7XG5cdCAgICAgICAgICB4ID0gdGhpcy53aWR0aCAvIDI7XG5cdCAgICAgICAgICB5ID0gMDtcblx0ICAgICAgICAgIHcgPSB0aGlzLnRoaWNrbmVzcztcblx0ICAgICAgICAgIGggPSB0aGlzLmhlaWdodDtcblx0ICAgICAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuXHQgICAgICAgICAgdGhpcy5rbm9iRGF0YS5sZXZlbCA9IGggLSB0aGlzLmtub2JEYXRhLnIgLSB0aGlzLm5vcm1hbGl6ZWQgKiAoaCAtIHRoaXMua25vYkRhdGEuciAqIDIpO1xuXHQgICAgICAgICAgYmFyT2Zmc2V0ID0gXCJ0cmFuc2xhdGUoXCIgKyB0aGlzLnRoaWNrbmVzcyAqIC0xIC8gMiArIFwiLDApXCI7XG5cdCAgICAgICAgICBjb3JuZXJSYWRpdXMgPSB3IC8gMjtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdGhpcy50aGlja25lc3MgPSB0aGlzLmhlaWdodCAvIDI7XG5cdCAgICAgICAgICB4ID0gMDtcblx0ICAgICAgICAgIHkgPSB0aGlzLmhlaWdodCAvIDI7XG5cdCAgICAgICAgICB3ID0gdGhpcy53aWR0aDtcblx0ICAgICAgICAgIGggPSB0aGlzLnRoaWNrbmVzcztcblx0ICAgICAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC44O1xuXHQgICAgICAgICAgdGhpcy5rbm9iRGF0YS5sZXZlbCA9IHRoaXMubm9ybWFsaXplZCAqICh3IC0gdGhpcy5rbm9iRGF0YS5yICogMikgKyB0aGlzLmtub2JEYXRhLnI7XG5cdCAgICAgICAgICBiYXJPZmZzZXQgPSBcInRyYW5zbGF0ZSgwLFwiICsgdGhpcy50aGlja25lc3MgKiAtMSAvIDIgKyBcIilcIjtcblx0ICAgICAgICAgIGNvcm5lclJhZGl1cyA9IGggLyAyO1xuXHQgICAgICAgIH1cblx0XG5cdCAgICAgICAgdGhpcy5iYXIuc2V0QXR0cmlidXRlKFwieFwiLCB4KTtcblx0ICAgICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoXCJ5XCIsIHkpO1xuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCBiYXJPZmZzZXQpO1xuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcInJ4XCIsIGNvcm5lclJhZGl1cyk7IC8vIGNvcm5lciByYWRpdXNcblx0ICAgICAgICB0aGlzLmJhci5zZXRBdHRyaWJ1dGUoXCJyeVwiLCBjb3JuZXJSYWRpdXMpO1xuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIHcpO1xuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCBoKTtcblx0XG5cdCAgICAgICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09IFwidmVydGljYWxcIikge1xuXHQgICAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImN4XCIsIHgpO1xuXHQgICAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImN5XCIsIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiY3hcIiwgdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG5cdCAgICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiY3lcIiwgeSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJyXCIsIHRoaXMua25vYkRhdGEucik7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjb2xvckludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY29sb3JJbnRlcmZhY2UoKSB7XG5cdFxuXHQgICAgICAgIHRoaXMuYmFyLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdGhpcy5jb2xvcnMuZmlsbCk7XG5cdCAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdGhpcy5jb2xvcnMuYWNjZW50KTtcblx0XG5cdCAgICAgICAgaWYgKCF0aGlzLmhhc0tub2IpIHtcblx0ICAgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwidHJhbnNwYXJlbnRcIik7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcmVuZGVyOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cdCAgICAgICAgaWYgKCF0aGlzLmNsaWNrZWQpIHtcblx0ICAgICAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC43NTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5rbm9iLnNldEF0dHJpYnV0ZShcInJcIiwgdGhpcy5rbm9iRGF0YS5yKTtcblx0XG5cdCAgICAgICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09IFwidmVydGljYWxcIikge1xuXHQgICAgICAgICAgdGhpcy5rbm9iRGF0YS5sZXZlbCA9IHRoaXMua25vYkRhdGEuciArIHRoaXMuX3ZhbHVlLm5vcm1hbGl6ZWQgKiAodGhpcy5oZWlnaHQgLSB0aGlzLmtub2JEYXRhLnIgKiAyKTtcblx0ICAgICAgICAgIHRoaXMua25vYi5zZXRBdHRyaWJ1dGUoXCJjeVwiLCB0aGlzLmhlaWdodCAtIHRoaXMua25vYkRhdGEubGV2ZWwpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aGlzLmtub2JEYXRhLmxldmVsID0gdGhpcy5fdmFsdWUubm9ybWFsaXplZCAqICh0aGlzLndpZHRoIC0gdGhpcy5rbm9iRGF0YS5yICogMikgKyB0aGlzLmtub2JEYXRhLnI7XG5cdCAgICAgICAgICB0aGlzLmtub2Iuc2V0QXR0cmlidXRlKFwiY3hcIiwgdGhpcy5rbm9iRGF0YS5sZXZlbCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY2xpY2s6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNsaWNrKCkge1xuXHQgICAgICAgIHRoaXMua25vYkRhdGEuciA9IHRoaXMudGhpY2tuZXNzICogMC45O1xuXHQgICAgICAgIHRoaXMucG9zaXRpb24uYW5jaG9yID0gdGhpcy5tb3VzZTtcblx0ICAgICAgICB0aGlzLm1vdmUoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIG1vdmU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIG1vdmUoKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuY2xpY2tlZCkge1xuXHQgICAgICAgICAgdGhpcy5wb3NpdGlvbi51cGRhdGUodGhpcy5tb3VzZSk7XG5cdFxuXHQgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuX3ZhbHVlLnVwZGF0ZU5vcm1hbCh0aGlzLnBvc2l0aW9uLnZhbHVlKTtcblx0XG5cdCAgICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwge1xuXHQgICAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZSxcblx0ICAgICAgICAgICAgTDogTWF0aC5wb3cobWF0aC5zY2FsZSh0aGlzLnZhbHVlLCAtMSwgMSwgMSwgMCksIDIpLFxuXHQgICAgICAgICAgICBSOiBNYXRoLnBvdyhtYXRoLnNjYWxlKHRoaXMudmFsdWUsIC0xLCAxLCAwLCAxKSwgMilcblx0ICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHJlbGVhc2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbGVhc2UoKSB7XG5cdCAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHZhbHVlOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgVGhlIHBvc2l0aW9uIG9mIGNyb3NzZmFkZXIsIGZyb20gLTEgKGxlZnQpIHRvIDEgKHJpZ2h0KS4gU2V0dGluZyB0aGlzIHZhbHVlIHVwZGF0ZXMgdGhlIGludGVyZmFjZSBhbmQgdHJpZ2dlcnMgdGhlIG91dHB1dCBldmVudC5cblx0ICAgICAgQHR5cGUge251bWJlcn1cblx0ICAgICAgKi9cblx0XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl92YWx1ZS52YWx1ZTtcblx0ICAgICAgfSxcblx0ICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcblx0ICAgICAgICB0aGlzLl92YWx1ZS51cGRhdGUodmFsdWUpO1xuXHQgICAgICAgIHRoaXMucG9zaXRpb24udmFsdWUgPSB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXHQgICAgICAgIHRoaXMuZW1pdChcImNoYW5nZVwiLCB7XG5cdCAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZSxcblx0ICAgICAgICAgIEw6IE1hdGgucG93KG1hdGguc2NhbGUodGhpcy52YWx1ZSwgLTEsIDEsIDEsIDApLCAyKSxcblx0ICAgICAgICAgIFI6IE1hdGgucG93KG1hdGguc2NhbGUodGhpcy52YWx1ZSwgLTEsIDEsIDAsIDEpLCAyKVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBub3JtYWxpemVkOiB7XG5cdCAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLl92YWx1ZS5ub3JtYWxpemVkO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSk7XG5cdFxuXHQgIHJldHVybiBQYW47XG5cdH0pKEludGVyZmFjZSk7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IFBhbjtcblxuLyoqKi8gfSksXG4vKiAzNCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9nZXQgPSBmdW5jdGlvbiBnZXQob2JqZWN0LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpIHsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyByZXR1cm4gZ2V0KHBhcmVudCwgcHJvcGVydHksIHJlY2VpdmVyKTsgfSB9IGVsc2UgaWYgKFwidmFsdWVcIiBpbiBkZXNjICYmIGRlc2Mud3JpdGFibGUpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9O1xuXHRcblx0dmFyIF9pbmhlcml0cyA9IGZ1bmN0aW9uIChzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9O1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIG1hdGggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpO1xuXHR2YXIgc3ZnID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTtcblx0dmFyIEludGVyZmFjZSA9IF9fd2VicGFja19yZXF1aXJlX18oNik7XG5cdFxuXHR2YXIgUG9pbnQgPSBmdW5jdGlvbiBQb2ludChwb2ludCwgZW52ZWxvcGUpIHtcblx0XG5cdCAgdGhpcy54ID0gcG9pbnQueDtcblx0ICB0aGlzLnkgPSBwb2ludC55O1xuXHQgIHRoaXMuZW52ZWxvcGUgPSBlbnZlbG9wZTtcblx0XG5cdCAgdGhpcy5lbGVtZW50ID0gc3ZnLmNyZWF0ZShcImNpcmNsZVwiKTtcblx0ICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCB0aGlzLmVudmVsb3BlLmNvbG9ycy5hY2NlbnQpO1xuXHRcblx0ICB0aGlzLmVudmVsb3BlLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcblx0XG5cdCAgdGhpcy5yZXNpemUgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICB2YXIgciA9IH4gfihNYXRoLm1pbih0aGlzLmVudmVsb3BlLndpZHRoLCB0aGlzLmVudmVsb3BlLmhlaWdodCkgLyA1MCkgKyAyO1xuXHQgICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZShcInJcIiwgcik7XG5cdCAgfTtcblx0XG5cdCAgdGhpcy5tb3ZlID0gZnVuY3Rpb24gKHgsIHkpIHtcblx0XG5cdCAgICB0aGlzLnggPSB4IHx8IHggPT09IDAgPyB4IDogdGhpcy54O1xuXHQgICAgdGhpcy55ID0geSB8fCB5ID09PSAwID8geSA6IHRoaXMueTtcblx0XG5cdCAgICBpZiAodGhpcy5lbnZlbG9wZS5ub2Rlcy5pbmRleE9mKHRoaXMpID49IDApIHtcblx0XG5cdCAgICAgIHZhciBwcmV2SW5kZXggPSB0aGlzLmVudmVsb3BlLm5vZGVzLmluZGV4T2YodGhpcykgLSAxO1xuXHQgICAgICB2YXIgbmV4dEluZGV4ID0gdGhpcy5lbnZlbG9wZS5ub2Rlcy5pbmRleE9mKHRoaXMpICsgMTtcblx0XG5cdCAgICAgIHZhciBwcmV2Tm9kZSA9IHRoaXMuZW52ZWxvcGUubm9kZXNbcHJldkluZGV4XTtcblx0ICAgICAgdmFyIG5leHROb2RlID0gdGhpcy5lbnZlbG9wZS5ub2Rlc1tuZXh0SW5kZXhdO1xuXHRcblx0ICAgICAgdmFyIGxvd1ggPSBwcmV2SW5kZXggPj0gMCA/IHByZXZOb2RlLnggOiAwO1xuXHQgICAgICB2YXIgaGlnaFggPSBuZXh0SW5kZXggPCB0aGlzLmVudmVsb3BlLm5vZGVzLmxlbmd0aCA/IG5leHROb2RlLnggOiAxO1xuXHRcblx0ICAgICAgaWYgKHRoaXMueCA8IGxvd1gpIHtcblx0ICAgICAgICB0aGlzLnggPSBsb3dYO1xuXHQgICAgICB9XG5cdCAgICAgIGlmICh0aGlzLnggPiBoaWdoWCkge1xuXHQgICAgICAgIHRoaXMueCA9IGhpZ2hYO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdFxuXHQgICAgdGhpcy5sb2NhdGlvbiA9IHRoaXMuZ2V0Q29vcmRpbmF0ZXMoKTtcblx0ICAgIHRoaXMuZWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJjeFwiLCB0aGlzLmxvY2F0aW9uLngpO1xuXHQgICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZShcImN5XCIsIHRoaXMubG9jYXRpb24ueSk7XG5cdCAgfTtcblx0XG5cdCAgdGhpcy5nZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgIHg6IHRoaXMueCAqIHRoaXMuZW52ZWxvcGUud2lkdGgsXG5cdCAgICAgIHk6ICgxIC0gdGhpcy55KSAqIHRoaXMuZW52ZWxvcGUuaGVpZ2h0XG5cdCAgICB9O1xuXHQgIH07XG5cdFxuXHQgIHRoaXMubW92ZSh0aGlzLngsIHRoaXMueSwgdHJ1ZSk7XG5cdCAgdGhpcy5yZXNpemUoKTtcblx0XG5cdCAgdGhpcy5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgdGhpcy5lbnZlbG9wZS5lbGVtZW50LnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudCk7XG5cdCAgICB0aGlzLmVudmVsb3BlLm5vZGVzLnNwbGljZSh0aGlzLmVudmVsb3BlLm5vZGVzLmluZGV4T2YodGhpcyksIDEpO1xuXHQgIH07XG5cdH07XG5cdFxuXHQvKipcblx0KiBFbnZlbG9wZVxuXHQqXG5cdCogQGRlc2NyaXB0aW9uIEludGVyYWN0aXZlIGxpbmVhciByYW1wIHZpc3VhbGl6YXRpb24uXG5cdCpcblx0KiBAZGVtbyA8c3BhbiBuZXh1cy11aT1cImVudmVsb3BlXCI+PC9zcGFuPlxuXHQqXG5cdCogQGV4YW1wbGVcblx0KiB2YXIgZW52ZWxvcGUgPSBuZXcgTmV4dXMuRW52ZWxvcGUoJyN0YXJnZXQnKVxuXHQqXG5cdCogQGV4YW1wbGVcblx0KiB2YXIgZW52ZWxvcGUgPSBuZXcgTmV4dXMuRW52ZWxvcGUoJyN0YXJnZXQnLHtcblx0KiAgICdzaXplJzogWzMwMCwxNTBdLFxuXHQqICAgJ3BvaW50cyc6IFtcblx0KiAgICAge1xuXHQqICAgICAgIHg6IDAuMSxcblx0KiAgICAgICB5OiAwLjRcblx0KiAgICAgfSxcblx0KiAgICAge1xuXHQqICAgICAgIHg6IDAuMzUsXG5cdCogICAgICAgeTogMC42XG5cdCogICAgIH0sXG5cdCogICAgIHtcblx0KiAgICAgICB4OiAwLjY1LFxuXHQqICAgICAgIHk6IDAuMlxuXHQqICAgICB9LFxuXHQqICAgICB7XG5cdCogICAgICAgeDogMC45LFxuXHQqICAgICAgIHk6IDAuNFxuXHQqICAgICB9LFxuXHQqICAgXVxuXHQqIH0pXG5cdCpcblx0KiBAb3V0cHV0XG5cdCogY2hhbmdlXG5cdCogRmlyZXMgYW55IHRpbWUgYSBub2RlIGlzIG1vdmVkLiA8YnI+XG5cdCogVGhlIGV2ZW50IGRhdGEgaXMgYW4gYXJyYXkgb2YgcG9pbnQgbG9jYXRpb25zLiBFYWNoIGl0ZW0gaW4gdGhlIGFycmF5IGlzIGFuIG9iamVjdCBjb250YWluaW5nIDxpPng8L2k+IGFuZCA8aT55PC9pPiBwcm9wZXJ0aWVzIGRlc2NyaWJpbmcgdGhlIGxvY2F0aW9uIG9mIGEgcG9pbnQgb24gdGhlIGVudmVsb3BlLlxuXHQqXG5cdCogQG91dHB1dGV4YW1wbGVcblx0KiBlbnZlbG9wZS5vbignY2hhbmdlJyxmdW5jdGlvbih2KSB7XG5cdCogICBjb25zb2xlLmxvZyh2KTtcblx0KiB9KVxuXHQqXG5cdCovXG5cdFxuXHR2YXIgRW52ZWxvcGUgPSAoZnVuY3Rpb24gKF9JbnRlcmZhY2UpIHtcblx0ICBmdW5jdGlvbiBFbnZlbG9wZSgpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFbnZlbG9wZSk7XG5cdFxuXHQgICAgdmFyIG9wdGlvbnMgPSBbXCJ2YWx1ZVwiXTtcblx0XG5cdCAgICB2YXIgZGVmYXVsdHMgPSB7XG5cdCAgICAgIHNpemU6IFszMDAsIDE1MF0sXG5cdCAgICAgIHBvaW50czogW3tcblx0ICAgICAgICB4OiAwLjEsXG5cdCAgICAgICAgeTogMC40XG5cdCAgICAgIH0sIHtcblx0ICAgICAgICB4OiAwLjM1LFxuXHQgICAgICAgIHk6IDAuNlxuXHQgICAgICB9LCB7XG5cdCAgICAgICAgeDogMC42NSxcblx0ICAgICAgICB5OiAwLjJcblx0ICAgICAgfSwge1xuXHQgICAgICAgIHg6IDAuOSxcblx0ICAgICAgICB5OiAwLjRcblx0ICAgICAgfV1cblx0ICAgIH07XG5cdFxuXHQgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoRW52ZWxvcGUucHJvdG90eXBlKSwgXCJjb25zdHJ1Y3RvclwiLCB0aGlzKS5jYWxsKHRoaXMsIGFyZ3VtZW50cywgb3B0aW9ucywgZGVmYXVsdHMpO1xuXHRcblx0ICAgIHRoaXMucG9pbnRzID0gdGhpcy5zZXR0aW5ncy5wb2ludHM7XG5cdFxuXHQgICAgdGhpcy5ub2RlcyA9IFtdO1xuXHRcblx0ICAgIHRoaXMuc2VsZWN0ZWQgPSBmYWxzZTtcblx0XG5cdCAgICB0aGlzLmluaXQoKTtcblx0ICB9XG5cdFxuXHQgIF9pbmhlcml0cyhFbnZlbG9wZSwgX0ludGVyZmFjZSk7XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhFbnZlbG9wZSwge1xuXHQgICAgYnVpbGRJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkSW50ZXJmYWNlKCkge1xuXHQgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgICAgIHRoaXMucG9pbnRzLmZvckVhY2goZnVuY3Rpb24gKHBvaW50KSB7XG5cdCAgICAgICAgICB2YXIgbm9kZSA9IG5ldyBQb2ludChwb2ludCwgX3RoaXMpO1xuXHQgICAgICAgICAgX3RoaXMubm9kZXMucHVzaChub2RlKTtcblx0ICAgICAgICB9KTtcblx0XG5cdCAgICAgICAgdGhpcy5zb3J0UG9pbnRzKCk7XG5cdFxuXHQgICAgICAgIHRoaXMubGluZSA9IHN2Zy5jcmVhdGUoXCJwb2x5bGluZVwiKTtcblx0ICAgICAgICB0aGlzLmxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIDIpO1xuXHQgICAgICAgIHRoaXMubGluZS5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwibm9uZVwiKTtcblx0XG5cdCAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMubGluZSk7XG5cdFxuXHQgICAgICAgIHRoaXMuZmlsbCA9IHN2Zy5jcmVhdGUoXCJwb2x5bGluZVwiKTtcblx0ICAgICAgICB0aGlzLmZpbGwuc2V0QXR0cmlidXRlKFwiZmlsbC1vcGFjaXR5XCIsIFwiMC4yXCIpO1xuXHRcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5maWxsKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHNpemVJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNpemVJbnRlcmZhY2UoKSB7XG5cdFxuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5ub2Rlcy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgdGhpcy5ub2Rlc1tpXS5yZXNpemUoKTtcblx0ICAgICAgICAgIHRoaXMubm9kZXNbaV0ubW92ZSgpO1xuXHQgICAgICAgIH1cblx0XG5cdCAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNvbG9ySW50ZXJmYWNlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb2xvckludGVyZmFjZSgpIHtcblx0ICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcblx0ICAgICAgICB0aGlzLmxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIHRoaXMuY29sb3JzLmFjY2VudCk7XG5cdCAgICAgICAgdGhpcy5maWxsLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdGhpcy5jb2xvcnMuYWNjZW50KTtcblx0ICAgICAgICB0aGlzLm5vZGVzLmZvckVhY2goZnVuY3Rpb24gKG5vZGUpIHtcblx0ICAgICAgICAgIG5vZGUuZWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIF90aGlzLmNvbG9ycy5hY2NlbnQpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcmVuZGVyOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cdCAgICAgICAgLy8gIHRoaXMubm9kZXNbdGhpcy5zZWxlY3RlZF0ubW92ZSggdGhpcy5wb2ludHMgKVxuXHQgICAgICAgIHRoaXMuY2FsY3VsYXRlUGF0aCgpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY2FsY3VsYXRlUG9pbnRzOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjYWxjdWxhdGVQb2ludHMoKSB7XG5cdCAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblx0XG5cdCAgICAgICAgdGhpcy5wb2ludHMgPSBbXTtcblx0ICAgICAgICB0aGlzLm5vZGVzLmZvckVhY2goZnVuY3Rpb24gKG5vZGUpIHtcblx0ICAgICAgICAgIF90aGlzLnBvaW50cy5wdXNoKHsgeDogbm9kZS54LCB5OiBub2RlLnkgfSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjYWxjdWxhdGVQYXRoOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjYWxjdWxhdGVQYXRoKCkge1xuXHRcblx0ICAgICAgICAvL3N0cm9rZSBkYXRhXG5cdCAgICAgICAgdmFyIGRhdGEgPSBcIjAgXCIgKyB0aGlzLm5vZGVzWzBdLmxvY2F0aW9uLnkgKyBcIiwgXCI7XG5cdFxuXHQgICAgICAgIC8vIGRhdGEgc2hvdWxkIGJlIHJlLW9yZGVyZWQgYmFzZWQgb24geCBsb2NhdGlvbi5cblx0ICAgICAgICAvLyB3aGF0ZXZlciBmdW5jdGlvbiBhZGRzIGEgbm9kZSBzaG91bGQgYWRkIGl0IGF0IHRoZSByaWdodCBpbmRleFxuXHRcblx0ICAgICAgICB0aGlzLm5vZGVzLmZvckVhY2goZnVuY3Rpb24gKG5vZGUpIHtcblx0ICAgICAgICAgIC8vICBsZXQgbG9jYXRpb24gPSBub2RlLmdldENvb3JkaW5hdGVzKCk7XG5cdCAgICAgICAgICBkYXRhICs9IG5vZGUubG9jYXRpb24ueCArIFwiIFwiICsgbm9kZS5sb2NhdGlvbi55ICsgXCIsIFwiO1xuXHQgICAgICAgIH0pO1xuXHRcblx0ICAgICAgICAvLyAgZGF0YSArPSBwb2ludC54KnRoaXMud2lkdGgrJyAnKyBwb2ludC55KnRoaXMuaGVpZ2h0KycsICc7XG5cdCAgICAgICAgZGF0YSArPSB0aGlzLndpZHRoICsgXCIgXCIgKyB0aGlzLm5vZGVzW3RoaXMubm9kZXMubGVuZ3RoIC0gMV0ubG9jYXRpb24ueTtcblx0XG5cdCAgICAgICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZShcInBvaW50c1wiLCBkYXRhKTtcblx0XG5cdCAgICAgICAgLy8gZmlsbCBkYXRhXG5cdCAgICAgICAgLy8gYWRkIGJvdHRvbSBjb3JuZXJzXG5cdFxuXHQgICAgICAgIGRhdGEgKz0gXCIsIFwiICsgdGhpcy53aWR0aCArIFwiIFwiICsgdGhpcy5oZWlnaHQgKyBcIiwgXCI7XG5cdCAgICAgICAgZGF0YSArPSBcIjAgXCIgKyB0aGlzLmhlaWdodDtcblx0XG5cdCAgICAgICAgdGhpcy5maWxsLnNldEF0dHJpYnV0ZShcInBvaW50c1wiLCBkYXRhKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNsaWNrOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjbGljaygpIHtcblx0ICAgICAgICAvLyBmaW5kIG5lYXJlc3Qgbm9kZSBhbmQgc2V0IHRoaXMuc2VsZWN0ZWQgKGluZGV4KVxuXHQgICAgICAgIHRoaXMuaGFzTW92ZWQgPSBmYWxzZTtcblx0ICAgICAgICB0aGlzLnNlbGVjdGVkID0gdGhpcy5maW5kTmVhcmVzdE5vZGUoKTtcblx0XG5cdCAgICAgICAgdGhpcy5ub2Rlc1t0aGlzLnNlbGVjdGVkXS5tb3ZlKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsIDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCk7XG5cdCAgICAgICAgdGhpcy5zY2FsZU5vZGUodGhpcy5zZWxlY3RlZCk7XG5cdFxuXHQgICAgICAgIC8vIG11c3QgZG8gdGhpcyBiL2MgbmV3IG5vZGUgbWF5IGhhdmUgYmVlbiBjcmVhdGVkXG5cdCAgICAgICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcblx0ICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy5wb2ludHMpO1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBtb3ZlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBtb3ZlKCkge1xuXHQgICAgICAgIGlmICh0aGlzLmNsaWNrZWQpIHtcblx0ICAgICAgICAgIHRoaXMubW91c2UueCA9IG1hdGguY2xpcCh0aGlzLm1vdXNlLngsIDAsIHRoaXMud2lkdGgpO1xuXHQgICAgICAgICAgdGhpcy5oYXNNb3ZlZCA9IHRydWU7XG5cdFxuXHQgICAgICAgICAgdGhpcy5ub2Rlc1t0aGlzLnNlbGVjdGVkXS5tb3ZlKHRoaXMubW91c2UueCAvIHRoaXMud2lkdGgsIDEgLSB0aGlzLm1vdXNlLnkgLyB0aGlzLmhlaWdodCk7XG5cdCAgICAgICAgICB0aGlzLnNjYWxlTm9kZSh0aGlzLnNlbGVjdGVkKTtcblx0XG5cdCAgICAgICAgICB0aGlzLmNhbGN1bGF0ZVBvaW50cygpO1xuXHQgICAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMucG9pbnRzKTtcblx0ICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcmVsZWFzZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVsZWFzZSgpIHtcblx0XG5cdCAgICAgICAgaWYgKCF0aGlzLmhhc01vdmVkKSB7XG5cdCAgICAgICAgICB0aGlzLm5vZGVzW3RoaXMuc2VsZWN0ZWRdLmRlc3Ryb3koKTtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHRoaXMuY2FsY3VsYXRlUG9pbnRzKCk7XG5cdCAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMucG9pbnRzKTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHRcblx0ICAgICAgICAvLyByZXNldCB0aGlzLnNlbGVjdGVkXG5cdCAgICAgICAgdGhpcy5zZWxlY3RlZCA9IG51bGw7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBmaW5kTmVhcmVzdE5vZGU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZpbmROZWFyZXN0Tm9kZSgpIHtcblx0ICAgICAgICB2YXIgbmVhcmVzdEluZGV4ID0gbnVsbDtcblx0ICAgICAgICAvLyBzZXQgdGhpcyB1bnJlYXNvbmFibHkgaGlnaCBzbyB0aGF0IGV2ZXJ5IGRpc3RhbmNlIHdpbGwgYmUgbG93ZXIgdGhhbiBpdC5cblx0ICAgICAgICB2YXIgbmVhcmVzdERpc3QgPSAxMDAwMDtcblx0ICAgICAgICB2YXIgYmVmb3JlID0gZmFsc2U7XG5cdCAgICAgICAgdmFyIHggPSB0aGlzLm1vdXNlLnggLyB0aGlzLndpZHRoO1xuXHQgICAgICAgIHZhciB5ID0gMSAtIHRoaXMubW91c2UueSAvIHRoaXMuaGVpZ2h0O1xuXHQgICAgICAgIHZhciBub2RlcyA9IHRoaXMubm9kZXM7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuXHRcblx0ICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgZGlzdGFuY2UgZnJvbSBtb3VzZSB0byB0aGlzIG5vZGUgdXNpbmcgcHl0aGFnb3JlYW4gdGhlb3JlbVxuXHQgICAgICAgICAgdmFyIGRpc3RhbmNlID0gTWF0aC5zcXJ0KE1hdGgucG93KG5vZGVzW2ldLnggLSB4LCAyKSArIE1hdGgucG93KG5vZGVzW2ldLnkgLSB5LCAyKSk7XG5cdFxuXHQgICAgICAgICAgLy8gaWYgdGhpcyBkaXN0YW5jZSBpcyBsZXNzIHRoYW4gdGhlIHByZXZpb3VzIHNob3J0ZXN0IGRpc3RhbmNlLCB1c2UgdGhpcyBpbmRleFxuXHQgICAgICAgICAgaWYgKGRpc3RhbmNlIDwgbmVhcmVzdERpc3QpIHtcblx0ICAgICAgICAgICAgbmVhcmVzdERpc3QgPSBkaXN0YW5jZTtcblx0ICAgICAgICAgICAgbmVhcmVzdEluZGV4ID0gaTtcblx0ICAgICAgICAgICAgYmVmb3JlID0geCA+IG5vZGVzW2ldLng7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICAvLyBpZiBub3QgdmVyeSBjbG9zZSB0byBhbnkgbm9kZSwgY3JlYXRlIGEgbm9kZVxuXHQgICAgICAgIGlmIChuZWFyZXN0RGlzdCA+IDAuMDcpIHtcblx0XG5cdCAgICAgICAgICBuZWFyZXN0SW5kZXggPSB0aGlzLmdldEluZGV4RnJvbVgodGhpcy5tb3VzZS54IC8gdGhpcy53aWR0aCk7XG5cdFxuXHQgICAgICAgICAgdGhpcy5ub2Rlcy5zcGxpY2UobmVhcmVzdEluZGV4LCAwLCBuZXcgUG9pbnQoe1xuXHQgICAgICAgICAgICB4OiB0aGlzLm1vdXNlLnggLyB0aGlzLndpZHRoLFxuXHQgICAgICAgICAgICB5OiAxIC0gdGhpcy5tb3VzZS55IC8gdGhpcy5oZWlnaHRcblx0ICAgICAgICAgIH0sIHRoaXMpKTtcblx0ICAgICAgICAgIHRoaXMuaGFzTW92ZWQgPSB0cnVlO1xuXHQgICAgICAgIH1cblx0XG5cdCAgICAgICAgcmV0dXJuIG5lYXJlc3RJbmRleDtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGdldEluZGV4RnJvbVg6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldEluZGV4RnJvbVgoeCkge1xuXHQgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgICAgIHZhciBpbmRleCA9IDA7XG5cdCAgICAgICAgdGhpcy5ub2Rlcy5mb3JFYWNoKGZ1bmN0aW9uIChub2RlLCBpKSB7XG5cdCAgICAgICAgICBpZiAoX3RoaXMubm9kZXNbaV0ueCA8PSB4KSB7XG5cdCAgICAgICAgICAgIGluZGV4ID0gaSArIDE7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIGluZGV4O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2NhbGVOb2RlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBzY2FsZU5vZGUoaSkge1xuXHRcblx0ICAgICAgICB2YXIgY2xpcHBlZFggPSBtYXRoLmNsaXAodGhpcy5ub2Rlc1tpXS54LCAwLCAxKTtcblx0ICAgICAgICB2YXIgY2xpcHBlZFkgPSBtYXRoLmNsaXAodGhpcy5ub2Rlc1tpXS55LCAwLCAxKTtcblx0XG5cdCAgICAgICAgdGhpcy5ub2Rlc1tpXS5tb3ZlKGNsaXBwZWRYLCBjbGlwcGVkWSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzb3J0UG9pbnRzOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgU29ydCB0aGUgdGhpcy5wb2ludHMgYXJyYXkgZnJvbSBsZWZ0LW1vc3QgcG9pbnQgdG8gcmlnaHQtbW9zdCBwb2ludC4gWW91IHNob3VsZCBub3QgcmVndWxhcmx5IG5lZWQgdG8gdXNlIHRoaXMsIGhvd2V2ZXIgaXQgbWF5IGJlIHVzZWZ1bCBpZiB0aGUgcG9pbnRzIGdldCB1bm9yZGVyZWQuXG5cdCAgICAgICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc29ydFBvaW50cygpIHtcblx0ICAgICAgICB0aGlzLm5vZGVzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcblx0ICAgICAgICAgIHJldHVybiBhLnggPiBiLng7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBhZGRQb2ludDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIEFkZCBhIGJyZWFrcG9pbnQgb24gdGhlIGVudmVsb3BlLlxuXHQgICAgICBAcGFyYW0geCB7bnVtYmVyfSB4IGxvY2F0aW9uIG9mIHRoZSBwb2ludCwgbm9ybWFsaXplZCAoMC0xKVxuXHQgICAgICBAcGFyYW0geSB7bnVtYmVyfSB5IGxvY2F0aW9uIG9mIHRoZSBwb2ludCwgbm9ybWFsaXplZCAoMC0xKVxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGFkZFBvaW50KHgsIHkpIHtcblx0ICAgICAgICB2YXIgaW5kZXggPSB0aGlzLm5vZGVzLmxlbmd0aDtcblx0XG5cdCAgICAgICAgdGhpcy5zb3J0UG9pbnRzKCk7XG5cdFxuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5ub2Rlcy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgaWYgKHggPCB0aGlzLm5vZGVzW2ldLngpIHtcblx0ICAgICAgICAgICAgaW5kZXggPSBpO1xuXHQgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHRoaXMubm9kZXMuc3BsaWNlKGluZGV4LCAwLCBuZXcgUG9pbnQoe1xuXHQgICAgICAgICAgeDogeCxcblx0ICAgICAgICAgIHk6IHlcblx0ICAgICAgICB9LCB0aGlzKSk7XG5cdFxuXHQgICAgICAgIHRoaXMuc2NhbGVOb2RlKGluZGV4KTtcblx0XG5cdCAgICAgICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcblx0ICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy5wb2ludHMpO1xuXHRcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2Nhbjoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIEZpbmQgdGhlIGxldmVsIGF0IGEgY2VydGFpbiB4IGxvY2F0aW9uIG9uIHRoZSBlbnZlbG9wZS5cblx0ICAgICAgQHBhcmFtIHgge251bWJlcn0gVGhlIHggbG9jYXRpb24gdG8gZmluZCB0aGUgbGV2ZWwgb2YsIG5vcm1hbGl6ZWQgMC0xXG5cdCAgICAgICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc2Nhbih4KSB7XG5cdCAgICAgICAgLy8gZmluZCBzdXJyb3VuZGluZyBwb2ludHNcblx0ICAgICAgICB2YXIgbmV4dEluZGV4ID0gdGhpcy5nZXRJbmRleEZyb21YKHgpO1xuXHQgICAgICAgIHZhciBwcmlvckluZGV4ID0gbmV4dEluZGV4IC0gMTtcblx0ICAgICAgICBpZiAocHJpb3JJbmRleCA8IDApIHtcblx0ICAgICAgICAgIHByaW9ySW5kZXggPSAwO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAobmV4dEluZGV4ID49IHRoaXMubm9kZXMubGVuZ3RoKSB7XG5cdCAgICAgICAgICBuZXh0SW5kZXggPSB0aGlzLm5vZGVzLmxlbmd0aCAtIDE7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHZhciBwcmlvclBvaW50ID0gdGhpcy5ub2Rlc1twcmlvckluZGV4XTtcblx0ICAgICAgICB2YXIgbmV4dFBvaW50ID0gdGhpcy5ub2Rlc1tuZXh0SW5kZXhdO1xuXHQgICAgICAgIHZhciBsb2MgPSBtYXRoLnNjYWxlKHgsIHByaW9yUG9pbnQueCwgbmV4dFBvaW50LngsIDAsIDEpO1xuXHQgICAgICAgIHZhciB2YWx1ZSA9IG1hdGguaW50ZXJwKGxvYywgcHJpb3JQb2ludC55LCBuZXh0UG9pbnQueSk7XG5cdCAgICAgICAgdGhpcy5lbWl0KFwic2NhblwiLCB2YWx1ZSk7XG5cdCAgICAgICAgcmV0dXJuIHZhbHVlO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbW92ZVBvaW50OiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgTW92ZSBhIGJyZWFrcG9pbnQgb24gdGhlIGVudmVsb3BlLlxuXHQgICAgICBAcGFyYW0gaW5kZXgge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBicmVha3BvaW50IHRvIG1vdmVcblx0ICAgICAgQHBhcmFtIHgge251bWJlcn0gTmV3IHggbG9jYXRpb24sIG5vcm1hbGl6ZWQgMC0xXG5cdCAgICAgIEBwYXJhbSB5IHtudW1iZXJ9IE5ldyB5IGxvY2F0aW9uLCBub3JtYWxpemVkIDAtMVxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIG1vdmVQb2ludChpbmRleCwgeCwgeSkge1xuXHQgICAgICAgIHRoaXMubm9kZXNbaW5kZXhdLm1vdmUoeCwgeSk7XG5cdCAgICAgICAgdGhpcy5zY2FsZU5vZGUoaW5kZXgpO1xuXHQgICAgICAgIHRoaXMuY2FsY3VsYXRlUG9pbnRzKCk7XG5cdCAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMucG9pbnRzKTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgYWRqdXN0UG9pbnQ6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBNb3ZlIGEgYnJlYWtwb2ludCBvbiB0aGUgZW52ZWxvcGUgYnkgYSBjZXJ0YWluIGFtb3VudC5cblx0ICAgICAgQHBhcmFtIGluZGV4IHtudW1iZXJ9IFRoZSBpbmRleCBvZiB0aGUgYnJlYWtwb2ludCB0byBtb3ZlXG5cdCAgICAgIEBwYXJhbSB4T2Zmc2V0IHtudW1iZXJ9IFggZGlzcGxhY2VtZW50LCBub3JtYWxpemVkIDAtMVxuXHQgICAgICBAcGFyYW0geU9mZnNldCB7bnVtYmVyfSBZIGRpc3BsYWNlbWVudCwgbm9ybWFsaXplZCAwLTFcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBhZGp1c3RQb2ludChpbmRleCwgeE9mZnNldCwgeU9mZnNldCkge1xuXHQgICAgICAgIHRoaXMubm9kZXNbaW5kZXhdLm1vdmUodGhpcy5ub2Rlc1tpbmRleF0ueCArIHhPZmZzZXQsIHRoaXMubm9kZXNbaW5kZXhdLnkgKyB5T2Zmc2V0KTtcblx0ICAgICAgICB0aGlzLnNjYWxlTm9kZShpbmRleCk7XG5cdCAgICAgICAgdGhpcy5jYWxjdWxhdGVQb2ludHMoKTtcblx0ICAgICAgICB0aGlzLmVtaXQoXCJjaGFuZ2VcIiwgdGhpcy5wb2ludHMpO1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBkZXN0cm95UG9pbnQ6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBSZW1vdmUgYSBicmVha3BvaW50IGZyb20gdGhlIGVudmVsb3BlLlxuXHQgICAgICBAcGFyYW0gaW5kZXgge251bWJlcn0gSW5kZXggb2YgdGhlIGJyZWFrcG9pbnQgdG8gcmVtb3ZlXG5cdCAgICAgICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gZGVzdHJveVBvaW50KGluZGV4KSB7XG5cdCAgICAgICAgdGhpcy5ub2Rlc1tpbmRleF0uZGVzdHJveSgpO1xuXHQgICAgICAgIHRoaXMuY2FsY3VsYXRlUG9pbnRzKCk7XG5cdCAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMucG9pbnRzKTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2V0UG9pbnRzOiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgUmVtb3ZlIGFsbCBleGlzdGluZyBicmVha3BvaW50cyBhbmQgYWRkIGFuIGVudGlyZWx5IG5ldyBzZXQgb2YgYnJlYWtwb2ludHMuXG5cdCAgICAgIEBwYXJhbSBhbGxQb2ludHMge2FycmF5fSBBbiBhcnJheSBvZiBvYmplY3RzIHdpdGggeC95IHByb3BlcnRpZXMgKG5vcm1hbGl6ZWQgMC0xKS4gRWFjaCBvYmplY3QgaW4gdGhlIGFycmF5IHNwZWNpZmljZXMgdGhlIHgveSBsb2NhdGlvbiBvZiBhIG5ldyBicmVha3BvaW50IHRvIGJlIGFkZGVkLlxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNldFBvaW50cyhhbGxQb2ludHMpIHtcblx0ICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICAgICB3aGlsZSAodGhpcy5ub2Rlcy5sZW5ndGgpIHtcblx0ICAgICAgICAgIHRoaXMubm9kZXNbMF0uZGVzdHJveSgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBhbGxQb2ludHMuZm9yRWFjaChmdW5jdGlvbiAocG9pbnQpIHtcblx0ICAgICAgICAgIF90aGlzLmFkZFBvaW50KHBvaW50LngsIHBvaW50LnkpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRoaXMuY2FsY3VsYXRlUG9pbnRzKCk7XG5cdCAgICAgICAgdGhpcy5lbWl0KFwiY2hhbmdlXCIsIHRoaXMucG9pbnRzKTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSk7XG5cdFxuXHQgIHJldHVybiBFbnZlbG9wZTtcblx0fSkoSW50ZXJmYWNlKTtcblx0XG5cdG1vZHVsZS5leHBvcnRzID0gRW52ZWxvcGU7XG5cbi8qKiovIH0pLFxuLyogMzUgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KG9iamVjdCwgcHJvcGVydHksIHJlY2VpdmVyKSB7IHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHByb3BlcnR5KTsgaWYgKGRlc2MgPT09IHVuZGVmaW5lZCkgeyB2YXIgcGFyZW50ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCk7IGlmIChwYXJlbnQgPT09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBlbHNlIHsgcmV0dXJuIGdldChwYXJlbnQsIHByb3BlcnR5LCByZWNlaXZlcik7IH0gfSBlbHNlIGlmIChcInZhbHVlXCIgaW4gZGVzYyAmJiBkZXNjLndyaXRhYmxlKSB7IHJldHVybiBkZXNjLnZhbHVlOyB9IGVsc2UgeyB2YXIgZ2V0dGVyID0gZGVzYy5nZXQ7IGlmIChnZXR0ZXIgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IHJldHVybiBnZXR0ZXIuY2FsbChyZWNlaXZlcik7IH0gfTtcblx0XG5cdHZhciBfaW5oZXJpdHMgPSBmdW5jdGlvbiAoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSBcImZ1bmN0aW9uXCIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCBcIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdHZhciBkb20gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDcpO1xuXHQvL2xldCBtYXRoID0gcmVxdWlyZSgnLi4vdXRpbC9tYXRoJyk7XG5cdHZhciBJbnRlcmZhY2UgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpO1xuXHRcblx0LyoqXG5cdCogU3BlY3Ryb2dyYW1cblx0KlxuXHQqIEBkZXNjcmlwdGlvbiBBdWRpbyBzcGVjdHJ1bSB2aXN1YWxpemF0aW9uXG5cdCpcblx0KiBAZGVtbyA8c3BhbiBuZXh1cy11aT1cInNwZWN0cm9ncmFtXCI+PC9zcGFuPlxuXHQqXG5cdCogQGV4YW1wbGVcblx0KiB2YXIgc3BlY3Ryb2dyYW0gPSBuZXcgTmV4dXMuU3BlY3Ryb2dyYW0oJyN0YXJnZXQnKVxuXHQqXG5cdCogQGV4YW1wbGVcblx0KiB2YXIgc3BlY3Ryb2dyYW0gPSBuZXcgTmV4dXMuU3BlY3Ryb2dyYW0oJyN0YXJnZXQnLHtcblx0KiAgICdzaXplJzogWzMwMCwxNTBdXG5cdCogfSlcblx0KlxuXHQqIEBvdXRwdXRcblx0KiAmbmJzcDtcblx0KiBObyBldmVudHNcblx0KlxuXHQqL1xuXHRcblx0dmFyIGNvbnRleHQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpLmNvbnRleHQ7XG5cdFxuXHR2YXIgU3BlY3Ryb2dyYW0gPSAoZnVuY3Rpb24gKF9JbnRlcmZhY2UpIHtcblx0ICBmdW5jdGlvbiBTcGVjdHJvZ3JhbSgpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTcGVjdHJvZ3JhbSk7XG5cdFxuXHQgICAgdmFyIG9wdGlvbnMgPSBbXCJzY2FsZVwiLCBcInZhbHVlXCJdO1xuXHRcblx0ICAgIHZhciBkZWZhdWx0cyA9IHtcblx0ICAgICAgc2l6ZTogWzMwMCwgMTUwXVxuXHQgICAgfTtcblx0XG5cdCAgICBfZ2V0KE9iamVjdC5nZXRQcm90b3R5cGVPZihTcGVjdHJvZ3JhbS5wcm90b3R5cGUpLCBcImNvbnN0cnVjdG9yXCIsIHRoaXMpLmNhbGwodGhpcywgYXJndW1lbnRzLCBvcHRpb25zLCBkZWZhdWx0cyk7XG5cdFxuXHQgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dCgpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblx0XG5cdCAgICB0aGlzLmFuYWx5c2VyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG5cdCAgICB0aGlzLmFuYWx5c2VyLmZmdFNpemUgPSAyMDQ4O1xuXHQgICAgdGhpcy5idWZmZXJMZW5ndGggPSB0aGlzLmFuYWx5c2VyLmZyZXF1ZW5jeUJpbkNvdW50O1xuXHQgICAgdGhpcy5kYXRhQXJyYXkgPSBuZXcgVWludDhBcnJheSh0aGlzLmJ1ZmZlckxlbmd0aCk7XG5cdFxuXHQgICAgdGhpcy5hY3RpdmUgPSB0cnVlO1xuXHRcblx0ICAgIHRoaXMuc291cmNlID0gZmFsc2U7XG5cdFxuXHQgICAgdGhpcy5pbml0KCk7XG5cdCAgfVxuXHRcblx0ICBfaW5oZXJpdHMoU3BlY3Ryb2dyYW0sIF9JbnRlcmZhY2UpO1xuXHRcblx0ICBfY3JlYXRlQ2xhc3MoU3BlY3Ryb2dyYW0sIHtcblx0ICAgIGJ1aWxkRnJhbWU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkRnJhbWUoKSB7XG5cdCAgICAgICAgdGhpcy5jYW52YXMgPSBuZXcgZG9tLlNtYXJ0Q2FudmFzKHRoaXMucGFyZW50KTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNhbnZhcy5lbGVtZW50O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2l6ZUludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc2l6ZUludGVyZmFjZSgpIHtcblx0ICAgICAgICB0aGlzLmNhbnZhcy5yZXNpemUodGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY29sb3JJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbG9ySW50ZXJmYWNlKCkge1xuXHQgICAgICAgIHRoaXMuY2FudmFzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHJlbmRlcjoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuXHRcblx0ICAgICAgICBpZiAodGhpcy5hY3RpdmUpIHtcblx0ICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlci5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHRoaXMuYW5hbHlzZXIuZ2V0Qnl0ZUZyZXF1ZW5jeURhdGEodGhpcy5kYXRhQXJyYXkpO1xuXHRcblx0ICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxTdHlsZSA9IHRoaXMuY29sb3JzLmZpbGw7XG5cdCAgICAgICAgdGhpcy5jYW52YXMuY29udGV4dC5maWxsUmVjdCgwLCAwLCB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoLCB0aGlzLmNhbnZhcy5lbGVtZW50LmhlaWdodCk7XG5cdFxuXHQgICAgICAgIGlmICh0aGlzLnNvdXJjZSAmJiB0aGlzLmRhdGFBcnJheSkge1xuXHRcblx0ICAgICAgICAgIC8vY29uc29sZS5sb2codGhpcy5kYXRhQXJyYXkpO1xuXHRcblx0ICAgICAgICAgIHZhciBiYXJXaWR0aCA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGggLyB0aGlzLmJ1ZmZlckxlbmd0aDtcblx0ICAgICAgICAgIHZhciBiYXJIZWlnaHQgPSB1bmRlZmluZWQ7XG5cdCAgICAgICAgICB2YXIgeCA9IDA7XG5cdFxuXHQgICAgICAgICAgdmFyIGRlZmluaXRpb24gPSB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoIC8gNTA7XG5cdFxuXHQgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJ1ZmZlckxlbmd0aDsgaSA9IGkgKyBkZWZpbml0aW9uKSB7XG5cdCAgICAgICAgICAgIGJhckhlaWdodCA9IE1hdGgubWF4LmFwcGx5KG51bGwsIHRoaXMuZGF0YUFycmF5LnN1YmFycmF5KGksIGkgKyBkZWZpbml0aW9uKSk7XG5cdCAgICAgICAgICAgIGJhckhlaWdodCAvPSAyNTU7XG5cdCAgICAgICAgICAgIGJhckhlaWdodCAqPSB0aGlzLmNhbnZhcy5lbGVtZW50LmhlaWdodDtcblx0XG5cdCAgICAgICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuYWNjZW50O1xuXHQgICAgICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KHgsIHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0IC0gYmFySGVpZ2h0LCBiYXJXaWR0aCAqIGRlZmluaXRpb24sIGJhckhlaWdodCk7XG5cdFxuXHQgICAgICAgICAgICB4ICs9IGJhcldpZHRoICogZGVmaW5pdGlvbjtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjb25uZWN0OiB7XG5cdFxuXHQgICAgICAvKipcblx0ICAgICAgRXF1aXZhbGVudCB0byBcInBhdGNoaW5nIGluXCIgYW4gYXVkaW8gbm9kZSB0byB2aXN1YWxpemUuIE5PVEU6IFlvdSBjYW5ub3QgY29ubmVjdCBhdWRpbyBub2RlcyBhY3Jvc3MgdHdvIGRpZmZlcmVudCBhdWRpbyBjb250ZXh0cy4gTmV4dXNVSSBydW5zIGl0cyBhdWRpbyBhbmFseXNpcyBvbiBpdHMgb3duIGF1ZGlvIGNvbnRleHQsIE5leHVzLmNvbnRleHQuIElmIHRoZSBhdWRpbyBub2RlIHlvdSBhcmUgdmlzdWFsaXppbmcgaXMgY3JlYXRlZCBvbiBhIGRpZmZlcmVudCBhdWRpbyBjb250ZXh0LCB5b3Ugd2lsbCBuZWVkIHRvIHRlbGwgTmV4dXNVSSB0byB1c2UgdGhhdCBjb250ZXh0IGluc3RlYWQ6IGkuZS4gTmV4dXMuY29udGV4dCA9IFlvdXJBdWRpb0NvbnRleHROYW1lLiBGb3IgZXhhbXBsZSwgaW4gVG9uZUpTIHByb2plY3RzLCB0aGUgbGluZSB3b3VsZCBiZTogTmV4dXMuY29udGV4dCA9IFRvbmUuY29udGV4dCAuIFdlIHJlY29tbWVuZCB0aGF0IHlvdSB3cml0ZSB0aGF0IGxpbmUgb2YgY29kZSBvbmx5IG9uY2UgYXQgdGhlIGJlZ2lubmluZyBvZiB5b3VyIHByb2plY3QuXG5cdCAgICAgIEBwYXJhbSBub2RlIHtBdWRpb05vZGV9IFRoZSBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZVxuXHQgICAgICBAZXhhbXBsZSBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC8vIG9yIGFub3RoZXIgYXVkaW8gY29udGV4dCB5b3UgaGF2ZSBjcmVhdGVkXG5cdCAgICAgIHNwZWN0cm9ncmFtLmNvbm5lY3QoIFRvbmUuTWFzdGVyICk7XG5cdCAgICAgICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY29ubmVjdChub2RlKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuc291cmNlKSB7XG5cdCAgICAgICAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5zb3VyY2UgPSBub2RlO1xuXHQgICAgICAgIHRoaXMuc291cmNlLmNvbm5lY3QodGhpcy5hbmFseXNlcik7XG5cdCAgICAgICAgdGhpcy5yZW5kZXIoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGRpc2Nvbm5lY3Q6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBTdG9wIHZpc3VhbGl6aW5nIHRoZSBzb3VyY2Ugbm9kZSBhbmQgZGlzY29ubmVjdCBpdC5cblx0ICAgICAgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBkaXNjb25uZWN0KCkge1xuXHQgICAgICAgIHRoaXMuc291cmNlLmRpc2Nvbm5lY3QodGhpcy5hbmFseXNlcik7XG5cdCAgICAgICAgdGhpcy5zb3VyY2UgPSBudWxsO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY2xpY2s6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNsaWNrKCkge1xuXHQgICAgICAgIHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjdXN0b21EZXN0cm95OiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjdXN0b21EZXN0cm95KCkge1xuXHQgICAgICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIFNwZWN0cm9ncmFtO1xuXHR9KShJbnRlcmZhY2UpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBTcGVjdHJvZ3JhbTtcblxuLyoqKi8gfSksXG4vKiAzNiAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9nZXQgPSBmdW5jdGlvbiBnZXQob2JqZWN0LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpIHsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyByZXR1cm4gZ2V0KHBhcmVudCwgcHJvcGVydHksIHJlY2VpdmVyKTsgfSB9IGVsc2UgaWYgKFwidmFsdWVcIiBpbiBkZXNjICYmIGRlc2Mud3JpdGFibGUpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9O1xuXHRcblx0dmFyIF9pbmhlcml0cyA9IGZ1bmN0aW9uIChzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9O1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIGRvbSA9IF9fd2VicGFja19yZXF1aXJlX18oNyk7XG5cdHZhciBtYXRoID0gX193ZWJwYWNrX3JlcXVpcmVfXyg1KTtcblx0dmFyIEludGVyZmFjZSA9IF9fd2VicGFja19yZXF1aXJlX18oNik7XG5cdFxuXHQvKipcblx0KiBNZXRlclxuXHQqXG5cdCogQGRlc2NyaXB0aW9uIFN0ZXJlbyBkZWNpYmVsIG1ldGVyXG5cdCpcblx0KiBAZGVtbyA8c3BhbiBuZXh1cy11aT1cIm1ldGVyXCI+PC9zcGFuPlxuXHQqXG5cdCogQGV4YW1wbGVcblx0KiB2YXIgbWV0ZXIgPSBuZXcgTmV4dXMuTWV0ZXIoJyN0YXJnZXQnKVxuXHQqXG5cdCogQGV4YW1wbGVcblx0KiB2YXIgbWV0ZXIgPSBuZXcgTmV4dXMuTWV0ZXIoJyN0YXJnZXQnLHtcblx0KiAgIHNpemU6IFs3NSw3NV1cblx0KiB9KVxuXHQqXG5cdCogQG91dHB1dFxuXHQqICZuYnNwO1xuXHQqIE5vIGV2ZW50c1xuXHQqXG5cdCovXG5cdFxuXHR2YXIgY29udGV4dCA9IF9fd2VicGFja19yZXF1aXJlX18oMSkuY29udGV4dDtcblx0XG5cdHZhciBNZXRlciA9IChmdW5jdGlvbiAoX0ludGVyZmFjZSkge1xuXHQgIGZ1bmN0aW9uIE1ldGVyKCkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIE1ldGVyKTtcblx0XG5cdCAgICB2YXIgb3B0aW9ucyA9IFtcInNjYWxlXCIsIFwidmFsdWVcIl07XG5cdFxuXHQgICAgdmFyIGRlZmF1bHRzID0ge1xuXHQgICAgICBzaXplOiBbMzAsIDEwMF1cblx0ICAgIH07XG5cdFxuXHQgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoTWV0ZXIucHJvdG90eXBlKSwgXCJjb25zdHJ1Y3RvclwiLCB0aGlzKS5jYWxsKHRoaXMsIGFyZ3VtZW50cywgb3B0aW9ucywgZGVmYXVsdHMpO1xuXHRcblx0ICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQoKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cdFxuXHQgICAgdGhpcy5jaGFubmVscyA9IDI7XG5cdFxuXHQgICAgdGhpcy5zcGxpdHRlciA9IHRoaXMuY29udGV4dC5jcmVhdGVDaGFubmVsU3BsaXR0ZXIodGhpcy5jaGFubmVscyk7XG5cdFxuXHQgICAgdGhpcy5hbmFseXNlcnMgPSBbXTtcblx0XG5cdCAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuY2hhbm5lbHM7IGkrKykge1xuXHQgICAgICB2YXIgYW5hbHlzZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcblx0ICAgICAgdGhpcy5zcGxpdHRlci5jb25uZWN0KGFuYWx5c2VyLCBpKTtcblx0ICAgICAgYW5hbHlzZXIuZmZ0U2l6ZSA9IDEwMjQ7XG5cdCAgICAgIGFuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IDE7XG5cdCAgICAgIHRoaXMuYW5hbHlzZXJzLnB1c2goYW5hbHlzZXIpO1xuXHQgICAgfVxuXHQgICAgdGhpcy5idWZmZXJMZW5ndGggPSB0aGlzLmFuYWx5c2Vyc1swXS5mcmVxdWVuY3lCaW5Db3VudDtcblx0ICAgIHRoaXMuZGF0YUFycmF5ID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJ1ZmZlckxlbmd0aCk7XG5cdFxuXHQgICAgLypcblx0ICAgICAgICAvLyBhZGQgbGluZWFyIGdyYWRpZW50XG5cdCAgICAgICAgdmFyIGdyZCA9IGNhbnZhc0N0eC5jcmVhdGVMaW5lYXJHcmFkaWVudCgwLCAwLCAwLCBjYW52YXMuaGVpZ2h0KTtcblx0ICAgICAgICAvLyBsaWdodCBibHVlXG5cdCAgICAgICAgZ3JkLmFkZENvbG9yU3RvcCgwLCAnIzAwMCcpO1xuXHQgICAgICAgIGdyZC5hZGRDb2xvclN0b3AoMC4yLCAnI2JiYicpO1xuXHQgICAgICAgIGdyZC5hZGRDb2xvclN0b3AoMC40LCAnI2QxOCcpO1xuXHQgICAgICAgIC8vIGRhcmsgYmx1ZVxuXHQgICAgICAgIGdyZC5hZGRDb2xvclN0b3AoMSwgJyNkMTgnKTtcblx0ICAgICAgICBjYW52YXNDdHguZmlsbFN0eWxlID0gZ3JkOyAqL1xuXHRcblx0ICAgIHRoaXMuYWN0aXZlID0gdHJ1ZTtcblx0XG5cdCAgICB0aGlzLmRiID0gLUluZmluaXR5O1xuXHRcblx0ICAgIHRoaXMuaW5pdCgpO1xuXHRcblx0ICAgIHRoaXMubWV0ZXJXaWR0aCA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGggLyB0aGlzLmNoYW5uZWxzO1xuXHRcblx0ICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgfVxuXHRcblx0ICBfaW5oZXJpdHMoTWV0ZXIsIF9JbnRlcmZhY2UpO1xuXHRcblx0ICBfY3JlYXRlQ2xhc3MoTWV0ZXIsIHtcblx0ICAgIGJ1aWxkRnJhbWU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkRnJhbWUoKSB7XG5cdCAgICAgICAgdGhpcy5jYW52YXMgPSBuZXcgZG9tLlNtYXJ0Q2FudmFzKHRoaXMucGFyZW50KTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNhbnZhcy5lbGVtZW50O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2l6ZUludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc2l6ZUludGVyZmFjZSgpIHtcblx0ICAgICAgICB0aGlzLmNhbnZhcy5yZXNpemUodGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY29sb3JJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbG9ySW50ZXJmYWNlKCkge1xuXHQgICAgICAgIHRoaXMuY2FudmFzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHJlbmRlcjoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuXHRcblx0ICAgICAgICBpZiAodGhpcy5hY3RpdmUpIHtcblx0ICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlci5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFN0eWxlID0gdGhpcy5jb2xvcnMuZmlsbDtcblx0ICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmZpbGxSZWN0KDAsIDAsIHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgsIHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0KTtcblx0XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmFuYWx5c2Vycy5sZW5ndGg7IGkrKykge1xuXHRcblx0ICAgICAgICAgIGlmICh0aGlzLnNvdXJjZSkge1xuXHRcblx0ICAgICAgICAgICAgdGhpcy5hbmFseXNlcnNbaV0uZ2V0RmxvYXRUaW1lRG9tYWluRGF0YSh0aGlzLmRhdGFBcnJheSk7XG5cdFxuXHQgICAgICAgICAgICB2YXIgcm1zID0gMDtcblx0XG5cdCAgICAgICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCB0aGlzLmRhdGFBcnJheS5sZW5ndGg7IF9pKyspIHtcblx0ICAgICAgICAgICAgICBybXMgKz0gdGhpcy5kYXRhQXJyYXlbX2ldICogdGhpcy5kYXRhQXJyYXlbX2ldO1xuXHQgICAgICAgICAgICB9XG5cdFxuXHQgICAgICAgICAgICBybXMgPSBNYXRoLnNxcnQocm1zIC8gdGhpcy5kYXRhQXJyYXkubGVuZ3RoKTtcblx0XG5cdCAgICAgICAgICAgIHRoaXMuZGIgPSAyMCAqIE1hdGgubG9nMTAocm1zKTtcblx0ICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5kYiA+IC0yMDAgJiYgdGhpcy5kYiAhPT0gLUluZmluaXR5KSB7XG5cdCAgICAgICAgICAgIHRoaXMuZGIgLT0gMTtcblx0ICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIHRoaXMuZGIgPSAtSW5maW5pdHk7XG5cdCAgICAgICAgICB9XG5cdFxuXHQgICAgICAgICAgLy9jb25zb2xlLmxvZyhkYilcblx0XG5cdCAgICAgICAgICBpZiAodGhpcy5kYiA+IC03MCkge1xuXHRcblx0ICAgICAgICAgICAgdmFyIGxpbmVhciA9IG1hdGgubm9ybWFsaXplKHRoaXMuZGIsIC03MCwgNSk7XG5cdCAgICAgICAgICAgIHZhciBleHAgPSBsaW5lYXIgKiBsaW5lYXI7XG5cdCAgICAgICAgICAgIHZhciB5ID0gbWF0aC5zY2FsZShleHAsIDAsIDEsIHRoaXMuZWxlbWVudC5oZWlnaHQsIDApO1xuXHRcblx0ICAgICAgICAgICAgdGhpcy5jYW52YXMuY29udGV4dC5maWxsU3R5bGUgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG5cdCAgICAgICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFJlY3QodGhpcy5tZXRlcldpZHRoICogaSwgeSwgdGhpcy5tZXRlcldpZHRoLCB0aGlzLmNhbnZhcy5lbGVtZW50LmhlaWdodCAtIHkpO1xuXHRcblx0ICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcInJlbmRlcmluZy4uLlwiKVxuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNvbm5lY3Q6IHtcblx0XG5cdCAgICAgIC8qKlxuXHQgICAgICBFcXVpdmFsZW50IHRvIFwicGF0Y2hpbmcgaW5cIiBhbiBhdWRpbyBub2RlIHRvIHZpc3VhbGl6ZS4gTk9URTogWW91IGNhbm5vdCBjb25uZWN0IGF1ZGlvIG5vZGVzIGFjcm9zcyB0d28gZGlmZmVyZW50IGF1ZGlvIGNvbnRleHRzLiBOZXh1c1VJIHJ1bnMgaXRzIGF1ZGlvIGFuYWx5c2lzIG9uIGl0cyBvd24gYXVkaW8gY29udGV4dCwgTmV4dXMuY29udGV4dC4gSWYgdGhlIGF1ZGlvIG5vZGUgeW91IGFyZSB2aXN1YWxpemluZyBpcyBjcmVhdGVkIG9uIGEgZGlmZmVyZW50IGF1ZGlvIGNvbnRleHQsIHlvdSB3aWxsIG5lZWQgdG8gdGVsbCBOZXh1c1VJIHRvIHVzZSB0aGF0IGNvbnRleHQgaW5zdGVhZDogaS5lLiBOZXh1cy5jb250ZXh0ID0gWW91ckF1ZGlvQ29udGV4dE5hbWUuIEZvciBleGFtcGxlLCBpbiBUb25lSlMgcHJvamVjdHMsIHRoZSBsaW5lIHdvdWxkIGJlOiBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC4gV2UgcmVjb21tZW5kIHRoYXQgeW91IHdyaXRlIHRoYXQgbGluZSBvZiBjb2RlIG9ubHkgb25jZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgcHJvamVjdC5cblx0ICAgICAgQHBhcmFtIG5vZGUge0F1ZGlvTm9kZX0gVGhlIGF1ZGlvIG5vZGUgdG8gdmlzdWFsaXplXG5cdCAgICAgIEBwYXJhbSBjaGFubmVscyB7bnVtYmVyfSAob3B0aW9uYWwpIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIHNvdXJjZSBub2RlIHRvIHdhdGNoLiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgaW50ZXJmYWNlIHdpbGwgbG9vayBmb3IgYSAuY2hhbm5lbENvdW50IHByb3BlcnR5IG9uIHRoZSBpbnB1dCBub2RlLiBJZiBpdCBkb2VzIG5vdCBleGlzdCwgdGhlIGludGVyZmFjZSB3aWxsIGRlZmF1bHQgdG8gMSBjaGFubmVsLlxuXHQgICAgICBAZXhhbXBsZSBOZXh1cy5jb250ZXh0ID0gVG9uZS5jb250ZXh0IC8vIG9yIGFub3RoZXIgYXVkaW8gY29udGV4dCB5b3UgaGF2ZSBjcmVhdGVkXG5cdCAgICAgIG1ldGVyLmNvbm5lY3QoIFRvbmUuTWFzdGVyLCAyICk7XG5cdCAgICAgICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY29ubmVjdChub2RlLCBjaGFubmVscykge1xuXHQgICAgICAgIGlmICh0aGlzLnNvdXJjZSkge1xuXHQgICAgICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vdGhpcy5kdW1teS5kaXNjb25uZWN0KHRoaXMuc3BsaXR0ZXIpO1xuXHRcblx0ICAgICAgICBpZiAoY2hhbm5lbHMpIHtcblx0ICAgICAgICAgIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVscztcblx0ICAgICAgICB9IGVsc2UgaWYgKG5vZGUuY2hhbm5lbENvdW50KSB7XG5cdCAgICAgICAgICB0aGlzLmNoYW5uZWxzID0gbm9kZS5jaGFubmVsQ291bnQ7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMuY2hhbm5lbHMgPSAyO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLm1ldGVyV2lkdGggPSB0aGlzLmNhbnZhcy5lbGVtZW50LndpZHRoIC8gdGhpcy5jaGFubmVscztcblx0XG5cdCAgICAgICAgdGhpcy5zb3VyY2UgPSBub2RlO1xuXHQgICAgICAgIHRoaXMuc291cmNlLmNvbm5lY3QodGhpcy5zcGxpdHRlcik7XG5cdFxuXHQgICAgICAgIC8vICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgZGlzY29ubmVjdDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFN0b3AgdmlzdWFsaXppbmcgdGhlIHNvdXJjZSBub2RlIGFuZCBkaXNjb25uZWN0IGl0LlxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRpc2Nvbm5lY3QoKSB7XG5cdFxuXHQgICAgICAgIHRoaXMuc291cmNlLmRpc2Nvbm5lY3QodGhpcy5zcGxpdHRlcik7XG5cdCAgICAgICAgdGhpcy5zb3VyY2UgPSBmYWxzZTtcblx0ICAgICAgICAvLyAgdGhpcy5kdW1teS5jb25uZWN0KHRoaXMuc3BsaXR0ZXIpO1xuXHQgICAgICAgIHRoaXMubWV0ZXJXaWR0aCA9IHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGggLyB0aGlzLmNoYW5uZWxzO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY2xpY2s6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNsaWNrKCkge1xuXHQgICAgICAgIHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xuXHQgICAgICAgIHRoaXMucmVuZGVyKCk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjdXN0b21EZXN0cm95OiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjdXN0b21EZXN0cm95KCkge1xuXHQgICAgICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KTtcblx0XG5cdCAgcmV0dXJuIE1ldGVyO1xuXHR9KShJbnRlcmZhY2UpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBNZXRlcjtcblxuLyoqKi8gfSksXG4vKiAzNyAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9nZXQgPSBmdW5jdGlvbiBnZXQob2JqZWN0LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpIHsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyByZXR1cm4gZ2V0KHBhcmVudCwgcHJvcGVydHksIHJlY2VpdmVyKTsgfSB9IGVsc2UgaWYgKFwidmFsdWVcIiBpbiBkZXNjICYmIGRlc2Mud3JpdGFibGUpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9O1xuXHRcblx0dmFyIF9pbmhlcml0cyA9IGZ1bmN0aW9uIChzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9O1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIGRvbSA9IF9fd2VicGFja19yZXF1aXJlX18oNyk7XG5cdHZhciBJbnRlcmZhY2UgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpO1xuXHRcblx0LyoqXG5cdCogT3NjaWxsb3Njb3BlXG5cdCpcblx0KiBAZGVzY3JpcHRpb24gVmlzdWFsaXplcyBhIHdhdmVmb3JtJ3Mgc3RyZWFtIG9mIHZhbHVlcy5cblx0KlxuXHQqIEBkZW1vIDxzcGFuIG5leHVzLXVpPVwib3NjaWxsb3Njb3BlXCI+PC9zcGFuPlxuXHQqXG5cdCogQGV4YW1wbGVcblx0KiB2YXIgb3NjaWxsb3Njb3BlID0gbmV3IE5leHVzLk9zY2lsbG9zY29wZSgnI3RhcmdldCcpXG5cdCpcblx0KiBAZXhhbXBsZVxuXHQqIHZhciBvc2NpbGxvc2NvcGUgPSBuZXcgTmV4dXMuT3NjaWxsb3Njb3BlKCcjdGFyZ2V0Jyx7XG5cdCogICAnc2l6ZSc6IFszMDAsMTUwXVxuXHQqIH0pXG5cdCpcblx0KiBAb3V0cHV0XG5cdCogJm5ic3A7XG5cdCogTm8gZXZlbnRzXG5cdCpcblx0Ki9cblx0XG5cdHZhciBjb250ZXh0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKS5jb250ZXh0O1xuXHRcblx0dmFyIE9zY2lsbG9zY29wZSA9IChmdW5jdGlvbiAoX0ludGVyZmFjZSkge1xuXHQgIGZ1bmN0aW9uIE9zY2lsbG9zY29wZSgpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBPc2NpbGxvc2NvcGUpO1xuXHRcblx0ICAgIHZhciBvcHRpb25zID0gW1wic2NhbGVcIiwgXCJ2YWx1ZVwiXTtcblx0XG5cdCAgICB2YXIgZGVmYXVsdHMgPSB7XG5cdCAgICAgIHNpemU6IFszMDAsIDE1MF1cblx0ICAgIH07XG5cdFxuXHQgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoT3NjaWxsb3Njb3BlLnByb3RvdHlwZSksIFwiY29uc3RydWN0b3JcIiwgdGhpcykuY2FsbCh0aGlzLCBhcmd1bWVudHMsIG9wdGlvbnMsIGRlZmF1bHRzKTtcblx0XG5cdCAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0KCk7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuXHRcblx0ICAgIHRoaXMuYW5hbHlzZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcblx0ICAgIHRoaXMuYW5hbHlzZXIuZmZ0U2l6ZSA9IDIwNDg7XG5cdCAgICB0aGlzLmJ1ZmZlckxlbmd0aCA9IHRoaXMuYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQ7XG5cdCAgICB0aGlzLmRhdGFBcnJheSA9IG5ldyBVaW50OEFycmF5KHRoaXMuYnVmZmVyTGVuZ3RoKTtcblx0ICAgIHRoaXMuYW5hbHlzZXIuZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKHRoaXMuZGF0YUFycmF5KTtcblx0XG5cdCAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG5cdFxuXHQgICAgdGhpcy5zb3VyY2UgPSBmYWxzZTtcblx0XG5cdCAgICB0aGlzLmluaXQoKTtcblx0XG5cdCAgICB0aGlzLnJlbmRlcigpO1xuXHQgIH1cblx0XG5cdCAgX2luaGVyaXRzKE9zY2lsbG9zY29wZSwgX0ludGVyZmFjZSk7XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhPc2NpbGxvc2NvcGUsIHtcblx0ICAgIGJ1aWxkRnJhbWU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkRnJhbWUoKSB7XG5cdCAgICAgICAgdGhpcy5jYW52YXMgPSBuZXcgZG9tLlNtYXJ0Q2FudmFzKHRoaXMucGFyZW50KTtcblx0ICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNhbnZhcy5lbGVtZW50O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2l6ZUludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gc2l6ZUludGVyZmFjZSgpIHtcblx0ICAgICAgICB0aGlzLmNhbnZhcy5yZXNpemUodGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY29sb3JJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbG9ySW50ZXJmYWNlKCkge1xuXHQgICAgICAgIHRoaXMuY2FudmFzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcnMuZmlsbDtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHJlbmRlcjoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuXHRcblx0ICAgICAgICBpZiAodGhpcy5hY3RpdmUpIHtcblx0ICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlci5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHRoaXMuYW5hbHlzZXIuZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKHRoaXMuZGF0YUFycmF5KTtcblx0XG5cdCAgICAgICAgdGhpcy5jYW52YXMuY29udGV4dC5maWxsU3R5bGUgPSB0aGlzLmNvbG9ycy5maWxsO1xuXHQgICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuZmlsbFJlY3QoMCwgMCwgdGhpcy5jYW52YXMuZWxlbWVudC53aWR0aCwgdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQpO1xuXHRcblx0ICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LmxpbmVXaWR0aCA9IH4gfih0aGlzLmhlaWdodCAvIDEwMCArIDIpO1xuXHQgICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuc3Ryb2tlU3R5bGUgPSB0aGlzLmNvbG9ycy5hY2NlbnQ7XG5cdFxuXHQgICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQuYmVnaW5QYXRoKCk7XG5cdFxuXHQgICAgICAgIGlmICh0aGlzLnNvdXJjZSkge1xuXHRcblx0ICAgICAgICAgIHZhciBzbGljZVdpZHRoID0gdGhpcy5jYW52YXMuZWxlbWVudC53aWR0aCAqIDEgLyB0aGlzLmJ1ZmZlckxlbmd0aDtcblx0ICAgICAgICAgIHZhciB4ID0gMDtcblx0XG5cdCAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYnVmZmVyTGVuZ3RoOyBpKyspIHtcblx0XG5cdCAgICAgICAgICAgIHZhciB2ID0gdGhpcy5kYXRhQXJyYXlbaV0gLyAxMjg7XG5cdCAgICAgICAgICAgIHZhciB5ID0gdiAqIHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0IC8gMjtcblx0XG5cdCAgICAgICAgICAgIGlmIChpID09PSAwKSB7XG5cdCAgICAgICAgICAgICAgdGhpcy5jYW52YXMuY29udGV4dC5tb3ZlVG8oeCwgeSk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgdGhpcy5jYW52YXMuY29udGV4dC5saW5lVG8oeCwgeSk7XG5cdCAgICAgICAgICAgIH1cblx0XG5cdCAgICAgICAgICAgIHggKz0gc2xpY2VXaWR0aDtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdGhpcy5jYW52YXMuY29udGV4dC5tb3ZlVG8oMCwgdGhpcy5jYW52YXMuZWxlbWVudC5oZWlnaHQgLyAyKTtcblx0ICAgICAgICAgIHRoaXMuY2FudmFzLmNvbnRleHQubGluZVRvKHRoaXMuY2FudmFzLmVsZW1lbnQud2lkdGgsIHRoaXMuY2FudmFzLmVsZW1lbnQuaGVpZ2h0IC8gMik7XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICB0aGlzLmNhbnZhcy5jb250ZXh0LnN0cm9rZSgpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY29ubmVjdDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIEVxdWl2YWxlbnQgdG8gXCJwYXRjaGluZyBpblwiIGFuIGF1ZGlvIG5vZGUgdG8gdmlzdWFsaXplLiBOT1RFOiBZb3UgY2Fubm90IGNvbm5lY3QgYXVkaW8gbm9kZXMgYWNyb3NzIHR3byBkaWZmZXJlbnQgYXVkaW8gY29udGV4dHMuIE5leHVzVUkgcnVucyBpdHMgYXVkaW8gYW5hbHlzaXMgb24gaXRzIG93biBhdWRpbyBjb250ZXh0LCBOZXh1cy5jb250ZXh0LiBJZiB0aGUgYXVkaW8gbm9kZSB5b3UgYXJlIHZpc3VhbGl6aW5nIGlzIGNyZWF0ZWQgb24gYSBkaWZmZXJlbnQgYXVkaW8gY29udGV4dCwgeW91IHdpbGwgbmVlZCB0byB0ZWxsIE5leHVzVUkgdG8gdXNlIHRoYXQgY29udGV4dCBpbnN0ZWFkOiBpLmUuIE5leHVzLmNvbnRleHQgPSBZb3VyQXVkaW9Db250ZXh0TmFtZS4gRm9yIGV4YW1wbGUsIGluIFRvbmVKUyBwcm9qZWN0cywgdGhlIGxpbmUgd291bGQgYmU6IE5leHVzLmNvbnRleHQgPSBUb25lLmNvbnRleHQgLiBXZSByZWNvbW1lbmQgdGhhdCB5b3Ugd3JpdGUgdGhhdCBsaW5lIG9mIGNvZGUgb25seSBvbmNlIGF0IHRoZSBiZWdpbm5pbmcgb2YgeW91ciBwcm9qZWN0LlxuXHQgICAgICBAcGFyYW0gbm9kZSB7QXVkaW9Ob2RlfSBUaGUgYXVkaW8gbm9kZSB0byB2aXN1YWxpemVcblx0ICAgICAgQGV4YW1wbGUgTmV4dXMuY29udGV4dCA9IFRvbmUuY29udGV4dCAvLyBvciBhbm90aGVyIGF1ZGlvIGNvbnRleHQgeW91IGhhdmUgY3JlYXRlZFxuXHQgICAgICBvc2NpbGxvc2NvcGUuY29ubmVjdCggVG9uZS5NYXN0ZXIgKTtcblx0ICAgICAgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb25uZWN0KG5vZGUpIHtcblx0XG5cdCAgICAgICAgaWYgKHRoaXMuc291cmNlKSB7XG5cdCAgICAgICAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHRoaXMuc291cmNlID0gbm9kZTtcblx0ICAgICAgICB0aGlzLnNvdXJjZS5jb25uZWN0KHRoaXMuYW5hbHlzZXIpO1xuXHRcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgZGlzY29ubmVjdDoge1xuXHRcblx0ICAgICAgLyoqXG5cdCAgICAgIFN0b3AgdmlzdWFsaXppbmcgdGhlIHNvdXJjZSBub2RlIGFuZCBkaXNjb25uZWN0IGl0LlxuXHQgICAgICAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRpc2Nvbm5lY3QoKSB7XG5cdCAgICAgICAgaWYgKHRoaXMuc291cmNlKSB7XG5cdCAgICAgICAgICB0aGlzLnNvdXJjZS5kaXNjb25uZWN0KHRoaXMuYW5hbHlzZXIpO1xuXHQgICAgICAgICAgdGhpcy5zb3VyY2UgPSBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNsaWNrOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjbGljaygpIHtcblx0ICAgICAgICB0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcblx0ICAgICAgICB0aGlzLnJlbmRlcigpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY3VzdG9tRGVzdHJveToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY3VzdG9tRGVzdHJveSgpIHtcblx0ICAgICAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSk7XG5cdFxuXHQgIHJldHVybiBPc2NpbGxvc2NvcGU7XG5cdH0pKEludGVyZmFjZSk7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IE9zY2lsbG9zY29wZTtcblxuLyoqKi8gfSksXG4vKiAzOCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9pbnRlcm9wUmVxdWlyZSA9IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9ialtcImRlZmF1bHRcIl0gOiBvYmo7IH07XG5cdFxuXHR2YXIgX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQgPSBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IFwiZGVmYXVsdFwiOiBvYmogfTsgfTtcblx0XG5cdHZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIga2V5IGluIHByb3BzKSB7IHZhciBwcm9wID0gcHJvcHNba2V5XTsgcHJvcC5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAocHJvcC52YWx1ZSkgcHJvcC53cml0YWJsZSA9IHRydWU7IH0gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcyk7IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblx0XG5cdC8qXG5cdE1haW4gY29uY2VwdDpcblx0c3ludGggPSBuZXcgTmV4dXMuUmFjaygnZWxlbWVudElEJyk7XG5cdFxuXHRUcmFuc2Zvcm0gYWxsIGVsZW1lbnRzIGluc2lkZSB0aGUgZGl2XG5cdHN5bnRoLmVsZW1lbnRJRCB3aWxsIGhvbGQgdGhlIGZpcnN0IHNsaWRlciBpbnRlcmZhY2Vcblx0XG5cdDIpIEluIGZ1dHVyZSwgcG90ZW50aWFsbHkgd3JpdGluZyBhIHJhY2sgdGhhdCBpcyByZS11c2FibGU/XG5cdENvdWxkIGFsc28gdGFrZSBKU09OXG5cdFxuXHRuZXcgTmV4dXMuUmFjaygnI3RhcmdldCcse1xuXHQgIHByZTogKCkgPT4ge1xuXHQgICAgY3JlYXRlIHNvbWUgZGl2cyBoZXJlLCBvciBzb21lIGF1ZGlvIGNvZGVcblx0ICB9LFxuXHQgIGludGVyZmFjZToge1xuXHQgICAgc2xpZGVyMTogTmV4dXMuYWRkLnNsaWRlcih7XG5cdCAgICAgIHRvcDoxMCxcblx0ICAgICAgbGVmdDoxMCxcblx0ICAgICAgd2lkdGg6NTAsXG5cdCAgICAgIGhlaWdodDoxMDAsXG5cdCAgICAgIG1pbjogMCxcblx0ICAgICAgbWF4OiAxMDAsXG5cdCAgICAgIHN0ZXA6IDFcblx0ICAgIH0pLFxuXHQgICAgd2F2ZTE6IE5leHVzLmFkZC53YXZlZm9ybSh7XG5cdCAgICAgIGZpbGU6ICcuL3BhdGgvdG8vZmlsZS5tcDMnLFxuXHQgICAgICB3aWR0aDo1MDAsXG5cdCAgICAgIGhlaWdodDoxMDAsXG5cdCAgICAgIG1vZGU6ICdyYW5nZSdcblx0ICAgIH0pXG5cdCAgfSxcblx0ICBpbml0OiAoKSA9PiB7XG5cdCAgICAvLyBzb21lIGF1ZGlvIGluaXQgY29kZSBnb2VzIGhlcmUuLi5cblx0ICB9XG5cdH0pO1xuXHRcblx0Ki9cblx0XG5cdHZhciB0cmFuc2Zvcm0gPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfX3dlYnBhY2tfcmVxdWlyZV9fKDM5KSk7XG5cdFxuXHR2YXIgZG9tID0gX2ludGVyb3BSZXF1aXJlKF9fd2VicGFja19yZXF1aXJlX18oNykpO1xuXHRcblx0dmFyIGNvbG9ycyA9IF9fd2VicGFja19yZXF1aXJlX18oMSkuY29sb3JzO1xuXHRcblx0dmFyIFJhY2sgPSAoZnVuY3Rpb24gKCkge1xuXHQgIGZ1bmN0aW9uIFJhY2sodGFyZ2V0LCBzZXR0aW5ncykge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFJhY2spO1xuXHRcblx0ICAgIHRoaXMubWV0YSA9IHt9O1xuXHQgICAgdGhpcy5tZXRhLnRhcmdldCA9IHRhcmdldDtcblx0ICAgIHRoaXMubWV0YS5wYXJlbnQgPSBkb20ucGFyc2VFbGVtZW50KHRhcmdldCk7IC8vIHNob3VsZCBiZSBhIGdlbmVyaWMgZnVuY3Rpb24gZm9yIHBhcnNpbmcgYSAndGFyZ2V0JyBhcmd1bWVudCB0aGF0IGNoZWNrcyBmb3Igc3RyaW5nL0RPTS9qUVVFUllcblx0ICAgIHRoaXMubWV0YS5jb2xvcnMgPSB7fTtcblx0XG5cdCAgICBpZiAoc2V0dGluZ3MpIHtcblx0ICAgICAgdGhpcy5tZXRhLmF0dHJpYnV0ZSA9IHNldHRpbmdzLmF0dHJpYnV0ZSB8fCBcIm5leHVzLXVpXCI7XG5cdCAgICAgIHRoaXMubWV0YS50aXRsZSA9IHNldHRpbmdzLm5hbWUgfHwgZmFsc2U7XG5cdCAgICAgIHRoaXMubWV0YS5vcGVuID0gc2V0dGluZ3Mub3BlbiB8fCBmYWxzZTtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIHRoaXMubWV0YS5hdHRyaWJ1dGUgPSBcIm5leHVzLXVpXCI7XG5cdCAgICAgIHRoaXMubWV0YS50aXRsZSA9IGZhbHNlO1xuXHQgICAgICB0aGlzLm1ldGEub3BlbiA9IGZhbHNlO1xuXHQgICAgfVxuXHRcblx0ICAgIHZhciBkZWZhdWx0Q29sb3JzID0gY29sb3JzKCk7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuXHQgICAgdGhpcy5tZXRhLmNvbG9ycy5hY2NlbnQgPSBkZWZhdWx0Q29sb3JzLmFjY2VudDtcblx0ICAgIHRoaXMubWV0YS5jb2xvcnMuZmlsbCA9IGRlZmF1bHRDb2xvcnMuZmlsbDtcblx0ICAgIHRoaXMubWV0YS5jb2xvcnMubGlnaHQgPSBkZWZhdWx0Q29sb3JzLmxpZ2h0O1xuXHQgICAgdGhpcy5tZXRhLmNvbG9ycy5kYXJrID0gZGVmYXVsdENvbG9ycy5kYXJrO1xuXHQgICAgdGhpcy5tZXRhLmNvbG9ycy5tZWRpdW1MaWdodCA9IGRlZmF1bHRDb2xvcnMubWVkaXVtTGlnaHQ7XG5cdCAgICB0aGlzLm1ldGEuY29sb3JzLm1lZGl1bURhcmsgPSBkZWZhdWx0Q29sb3JzLm1lZGl1bURhcms7XG5cdCAgICB0aGlzLmJ1aWxkSW50ZXJmYWNlKCk7XG5cdCAgICB0aGlzLmNvbG9ySW50ZXJmYWNlKCk7XG5cdCAgfVxuXHRcblx0ICBfY3JlYXRlQ2xhc3MoUmFjaywge1xuXHQgICAgYnVpbGRJbnRlcmZhY2U6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJ1aWxkSW50ZXJmYWNlKCkge1xuXHQgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgICAgIHRoaXMubWV0YS5wYXJlbnQuc3R5bGUuYm94U2l6aW5nID0gXCJib3JkZXItYm94XCI7XG5cdCAgICAgICAgdGhpcy5tZXRhLnBhcmVudC5zdHlsZS51c2VyU2VsZWN0ID0gXCJub25lXCI7XG5cdCAgICAgICAgdGhpcy5tZXRhLnBhcmVudC5zdHlsZS5tb3pVc2VyU2VsZWN0ID0gXCJub25lXCI7XG5cdCAgICAgICAgdGhpcy5tZXRhLnBhcmVudC5zdHlsZS53ZWJraXRVc2VyU2VsZWN0ID0gXCJub25lXCI7XG5cdFxuXHQgICAgICAgIHRoaXMubWV0YS5jb250ZW50cyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cdFxuXHQgICAgICAgIHdoaWxlICh0aGlzLm1ldGEucGFyZW50LmNoaWxkTm9kZXMubGVuZ3RoID4gMCkge1xuXHQgICAgICAgICAgdGhpcy5tZXRhLmNvbnRlbnRzLmFwcGVuZENoaWxkKHRoaXMubWV0YS5wYXJlbnQuY2hpbGROb2Rlc1swXSk7XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICB0aGlzLm1ldGEuY29udGVudHMuc3R5bGUucGFkZGluZyA9IFwiMHB4XCI7XG5cdCAgICAgICAgdGhpcy5tZXRhLmNvbnRlbnRzLnN0eWxlLmJveFNpemluZyA9IFwiYm9yZGVyLWJveFwiO1xuXHRcblx0ICAgICAgICBpZiAodGhpcy5tZXRhLnRpdGxlKSB7XG5cdCAgICAgICAgICB0aGlzLm1ldGEudGl0bGVCYXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXHQgICAgICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLmlubmVySFRNTCA9IHRoaXMubWV0YS50aXRsZTtcblx0ICAgICAgICAgIHRoaXMubWV0YS50aXRsZUJhci5zdHlsZS5mb250RmFtaWx5ID0gXCJhcmlhbFwiO1xuXHQgICAgICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuXHQgICAgICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLnN0eWxlLmNvbG9yID0gXCIjODg4XCI7XG5cdCAgICAgICAgICB0aGlzLm1ldGEudGl0bGVCYXIuc3R5bGUucGFkZGluZyA9IFwiN3B4XCI7XG5cdCAgICAgICAgICB0aGlzLm1ldGEudGl0bGVCYXIuc3R5bGUuZm9udFNpemUgPSBcIjEycHhcIjtcblx0XG5cdCAgICAgICAgICB0aGlzLm1ldGEuYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcblx0ICAgICAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG5cdCAgICAgICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLnRvcCA9IFwiNXB4XCI7XG5cdCAgICAgICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLnJpZ2h0ID0gXCI1cHhcIjtcblx0ICAgICAgICAgIHRoaXMubWV0YS5idXR0b24uaW5uZXJIVE1MID0gXCItXCI7XG5cdCAgICAgICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLnBhZGRpbmcgPSBcIjBweCA1cHggMnB4XCI7XG5cdCAgICAgICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLmxpbmVIZWlnaHQgPSBcIjEycHhcIjtcblx0ICAgICAgICAgIHRoaXMubWV0YS5idXR0b24uc3R5bGUuZm9udFNpemUgPSBcIjE1cHhcIjtcblx0XG5cdCAgICAgICAgICB0aGlzLm1ldGEuYnV0dG9uLnN0eWxlLmN1cnNvciA9IFwicG9pbnRlclwiO1xuXHRcblx0ICAgICAgICAgIHRoaXMubWV0YS5idXR0b24uYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlb3ZlclwiLCBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIF90aGlzLm1ldGEuYnV0dG9uLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IF90aGlzLm1ldGEuY29sb3JzLm1lZGl1bURhcms7XG5cdCAgICAgICAgICB9KTtcblx0ICAgICAgICAgIHRoaXMubWV0YS5idXR0b24uYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlbGVhdmVcIiwgZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBfdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBfdGhpcy5tZXRhLmNvbG9ycy5tZWRpdW1MaWdodDtcblx0ICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBpZiAoX3RoaXMubWV0YS5vcGVuKSB7XG5cdCAgICAgICAgICAgICAgX3RoaXMuaGlkZSgpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgIF90aGlzLnNob3coKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgfSk7XG5cdFxuXHQgICAgICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLmFwcGVuZENoaWxkKHRoaXMubWV0YS5idXR0b24pO1xuXHRcblx0ICAgICAgICAgIHRoaXMubWV0YS5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5tZXRhLnRpdGxlQmFyKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5tZXRhLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLm1ldGEuY29udGVudHMpO1xuXHRcblx0ICAgICAgICAvLyAgdmFyIHdpZHRoID0gdGhpcy5tZXRhLnBhcmVudC5zdHlsZS53aWR0aCA9IGdldENvbXB1dGVkU3R5bGUodGhpcy5tZXRhLnBhcmVudCkuZ2V0UHJvcGVydHlWYWx1ZSgnd2lkdGgnKTtcblx0ICAgICAgICAvLyAgICB0aGlzLm1ldGEucGFyZW50LnN0eWxlLndpZHRoID0gd2lkdGg7XG5cdFxuXHQgICAgICAgIHZhciB1aSA9IHRyYW5zZm9ybS5zZWN0aW9uKHRoaXMubWV0YS50YXJnZXQsIHRoaXMubWV0YS5hdHRyaWJ1dGUpO1xuXHQgICAgICAgIGZvciAodmFyIGtleSBpbiB1aSkge1xuXHQgICAgICAgICAgdGhpc1trZXldID0gdWlba2V5XTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjb2xvckludGVyZmFjZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY29sb3JJbnRlcmZhY2UoKSB7XG5cdCAgICAgICAgaWYgKHRoaXMubWV0YS50aXRsZSkge1xuXHQgICAgICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLm1lZGl1bUxpZ2h0O1xuXHQgICAgICAgICAgdGhpcy5tZXRhLmJ1dHRvbi5zdHlsZS5ib3JkZXIgPSBcInNvbGlkIDBweCBcIiArIHRoaXMubWV0YS5jb2xvcnMuZmlsbDtcblx0ICAgICAgICAgIHRoaXMubWV0YS5wYXJlbnQuc3R5bGUuYm9yZGVyID0gXCJzb2xpZCAxcHggXCIgKyB0aGlzLm1ldGEuY29sb3JzLm1lZGl1bUxpZ2h0O1xuXHQgICAgICAgICAgdGhpcy5tZXRhLnBhcmVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm1ldGEuY29sb3JzLmxpZ2h0O1xuXHQgICAgICAgICAgdGhpcy5tZXRhLnRpdGxlQmFyLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMubWV0YS5jb2xvcnMuZmlsbDtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzaG93OiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBzaG93KCkge1xuXHQgICAgICAgIHRoaXMubWV0YS5jb250ZW50cy5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuXHQgICAgICAgIHRoaXMubWV0YS5vcGVuID0gdHJ1ZTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGhpZGU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGhpZGUoKSB7XG5cdCAgICAgICAgdGhpcy5tZXRhLmNvbnRlbnRzLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcblx0ICAgICAgICB0aGlzLm1ldGEub3BlbiA9IGZhbHNlO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY29sb3JpemU6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbG9yaXplKHR5cGUsIGNvbG9yKSB7XG5cdCAgICAgICAgZm9yICh2YXIga2V5IGluIHRoaXMpIHtcblx0ICAgICAgICAgIGlmICh0aGlzW2tleV0uY29sb3JpemUpIHtcblx0ICAgICAgICAgICAgdGhpc1trZXldLmNvbG9yaXplKHR5cGUsIGNvbG9yKTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5tZXRhLmNvbG9yc1t0eXBlXSA9IGNvbG9yO1xuXHQgICAgICAgIHRoaXMuY29sb3JJbnRlcmZhY2UoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGVtcHR5OiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBlbXB0eSgpIHtcblx0ICAgICAgICBmb3IgKHZhciBrZXkgaW4gdGhpcykge1xuXHQgICAgICAgICAgaWYgKHRoaXNba2V5XS5kZXN0cm95KSB7XG5cdCAgICAgICAgICAgIHRoaXNba2V5XS5kZXN0cm95KCk7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSk7XG5cdFxuXHQgIHJldHVybiBSYWNrO1xuXHR9KSgpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBSYWNrO1xuXG4vKioqLyB9KSxcbi8qIDM5ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgX2ludGVyb3BSZXF1aXJlID0gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqW1wiZGVmYXVsdFwiXSA6IG9iajsgfTtcblx0XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBkb20gPSBfaW50ZXJvcFJlcXVpcmUoX193ZWJwYWNrX3JlcXVpcmVfXyg3KSk7XG5cdFxuXHR2YXIgSW50ZXJmYWNlcyA9IF9pbnRlcm9wUmVxdWlyZShfX3dlYnBhY2tfcmVxdWlyZV9fKDIpKTtcblx0XG5cdHZhciBjcmVhdGVJbnRlcmZhY2VJRCA9IGZ1bmN0aW9uICh3aWRnZXQsIGludGVyZmFjZUlEcykge1xuXHQgIHZhciB0eXBlID0gd2lkZ2V0LnR5cGU7XG5cdCAgaWYgKGludGVyZmFjZUlEc1t0eXBlXSkge1xuXHQgICAgaW50ZXJmYWNlSURzW3R5cGVdKys7XG5cdCAgfSBlbHNlIHtcblx0ICAgIGludGVyZmFjZUlEc1t0eXBlXSA9IDE7XG5cdCAgfVxuXHQgIHJldHVybiB0eXBlICsgaW50ZXJmYWNlSURzW3R5cGVdO1xuXHR9O1xuXHRcblx0dmFyIGVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCwgdHlwZSwgb3B0aW9ucykge1xuXHQgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXHQgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxlbWVudC5hdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICB2YXIgYXR0ID0gZWxlbWVudC5hdHRyaWJ1dGVzW2ldO1xuXHQgICAgLy8gIHRyeSB7XG5cdCAgICAvLyAgICBvcHRpb25zW2F0dC5ub2RlTmFtZV0gPSBldmFsKGF0dC5ub2RlVmFsdWUpO1xuXHQgICAgLy8gIH0gY2F0Y2goZSkge1xuXHQgICAgb3B0aW9uc1thdHQubm9kZU5hbWVdID0gYXR0Lm5vZGVWYWx1ZTtcblx0ICAgIC8vICB9XG5cdCAgfVxuXHQgIHR5cGUgPSB0eXBlWzBdLnRvVXBwZXJDYXNlKCkgKyB0eXBlLnNsaWNlKDEpO1xuXHQgIHZhciB3aWRnZXQgPSBuZXcgSW50ZXJmYWNlc1t0eXBlXShlbGVtZW50LCBvcHRpb25zKTtcblx0ICB3aWRnZXQuaWQgPSBlbGVtZW50LmlkO1xuXHQgIHJldHVybiB3aWRnZXQ7XG5cdH07XG5cdFxuXHR2YXIgc2VjdGlvbiA9IGZ1bmN0aW9uIChwYXJlbnQsIGtleXdvcmQpIHtcblx0XG5cdCAga2V5d29yZCA9IGtleXdvcmQgfHwgXCJuZXh1cy11aVwiO1xuXHRcblx0ICB2YXIgaW50ZXJmYWNlSURzID0ge307XG5cdFxuXHQgIHZhciBjb250YWluZXIgPSBkb20ucGFyc2VFbGVtZW50KHBhcmVudCk7XG5cdFxuXHQgIHZhciB1aSA9IHt9O1xuXHRcblx0ICB2YXIgaHRtbEVsZW1lbnRzID0gY29udGFpbmVyLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiKlwiKTtcblx0ICB2YXIgZWxlbWVudHMgPSBbXTtcblx0ICBmb3IgKHZhciBpID0gMDsgaSA8IGh0bWxFbGVtZW50cy5sZW5ndGg7IGkrKykge1xuXHQgICAgZWxlbWVudHMucHVzaChodG1sRWxlbWVudHNbaV0pO1xuXHQgIH1cblx0ICBmb3IgKHZhciBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICB2YXIgdHlwZSA9IGVsZW1lbnRzW2ldLmdldEF0dHJpYnV0ZShrZXl3b3JkKTtcblx0ICAgIGlmICh0eXBlKSB7XG5cdCAgICAgIHZhciBmb3JtYXR0ZWRUeXBlID0gZmFsc2U7XG5cdCAgICAgIGZvciAodmFyIGtleSBpbiBJbnRlcmZhY2VzKSB7XG5cdCAgICAgICAgaWYgKHR5cGUudG9Mb3dlckNhc2UoKSA9PT0ga2V5LnRvTG93ZXJDYXNlKCkpIHtcblx0ICAgICAgICAgIGZvcm1hdHRlZFR5cGUgPSBrZXk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICAgIGNvbnNvbGUubG9nKGZvcm1hdHRlZFR5cGUpO1xuXHQgICAgICB2YXIgd2lkZ2V0ID0gZWxlbWVudChlbGVtZW50c1tpXSwgZm9ybWF0dGVkVHlwZSk7XG5cdCAgICAgIGlmICh3aWRnZXQuaWQpIHtcblx0ICAgICAgICB1aVt3aWRnZXQuaWRdID0gd2lkZ2V0O1xuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIHZhciBpZCA9IGNyZWF0ZUludGVyZmFjZUlEKHdpZGdldCwgaW50ZXJmYWNlSURzKTtcblx0ICAgICAgICB1aVtpZF0gPSB3aWRnZXQ7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9XG5cdFxuXHQgIHJldHVybiB1aTtcblx0fTtcblx0XG5cdHZhciBhZGQgPSBmdW5jdGlvbiAodHlwZSwgcGFyZW50LCBvcHRpb25zKSB7XG5cdCAgdmFyIHRhcmdldCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cdCAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cdCAgaWYgKHBhcmVudCkge1xuXHQgICAgcGFyZW50ID0gZG9tLnBhcnNlRWxlbWVudChwYXJlbnQpO1xuXHQgIH0gZWxzZSB7XG5cdCAgICBwYXJlbnQgPSBkb2N1bWVudC5ib2R5O1xuXHQgIH1cblx0ICBwYXJlbnQuYXBwZW5kQ2hpbGQodGFyZ2V0KTtcblx0ICBvcHRpb25zLnRhcmdldCA9IHRhcmdldDtcblx0ICBpZiAob3B0aW9ucy5zaXplKSB7XG5cdCAgICB0YXJnZXQuc3R5bGUud2lkdGggPSBvcHRpb25zLnNpemVbMF0gKyBcInB4XCI7XG5cdCAgICB0YXJnZXQuc3R5bGUuaGVpZ2h0ID0gb3B0aW9ucy5zaXplWzFdICsgXCJweFwiO1xuXHQgIH1cblx0ICByZXR1cm4gZWxlbWVudCh0YXJnZXQsIHR5cGUsIG9wdGlvbnMpO1xuXHR9O1xuXHRcblx0ZXhwb3J0cy5lbGVtZW50ID0gZWxlbWVudDtcblx0ZXhwb3J0cy5zZWN0aW9uID0gc2VjdGlvbjtcblx0ZXhwb3J0cy5hZGQgPSBhZGQ7XG5cbi8qKiovIH0pLFxuLyogNDAgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBfaW50ZXJvcFJlcXVpcmUgPSBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmpbXCJkZWZhdWx0XCJdIDogb2JqOyB9O1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIG1hdGggPSBfaW50ZXJvcFJlcXVpcmUoX193ZWJwYWNrX3JlcXVpcmVfXyg1KSk7XG5cdFxuXHR2YXIgVHVuZSA9IChmdW5jdGlvbiAoKSB7XG5cdCAgZnVuY3Rpb24gVHVuZSgpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUdW5lKTtcblx0XG5cdCAgICAvLyB0aGUgc2NhbGUgYXMgcmF0aW9zXG5cdCAgICB0aGlzLnNjYWxlID0gW107XG5cdFxuXHQgICAgLy8gaS9vIG1vZGVzXG5cdCAgICB0aGlzLm1vZGUgPSB7XG5cdCAgICAgIG91dHB1dDogXCJmcmVxdWVuY3lcIixcblx0ICAgICAgaW5wdXQ6IFwic3RlcFwiXG5cdCAgICB9O1xuXHRcblx0ICAgIC8vIEVUIG1ham9yXG5cdCAgICB0aGlzLmV0bWFqb3IgPSBbMjYxLjYyNTU4LCAyOTMuNjY0NzY0LCAzMjkuNjI3NTYzLCAzNDkuMjI4MjQxLCAzOTEuOTk1NDIyLCA0NDAsIDQ5My44ODMzMDEsIDUyMy4yNTExNl07XG5cdFxuXHQgICAgLy8gUm9vdCBmcmVxdWVuY3kuXG5cdCAgICB0aGlzLnJvb3QgPSBtYXRoLm10b2YoNjApOyAvLyAqIE1hdGgucG93KDIsKDYwLTY5KS8xMik7XG5cdFxuXHQgICAgLy8gZGVmYXVsdCBpcyBhIG1ham9yIHNjYWxlXG5cdCAgICB0aGlzLmNyZWF0ZVNjYWxlKDAsIDIsIDQsIDUsIDcsIDksIDExKTtcblx0ICB9XG5cdFxuXHQgIF9jcmVhdGVDbGFzcyhUdW5lLCB7XG5cdCAgICBub3RlOiB7XG5cdFxuXHQgICAgICAvKiBSZXR1cm4gZGF0YSBpbiB0aGUgbW9kZSB5b3UgYXJlIGluIChmcmVxLCByYXRpbywgb3IgbWlkaSkgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBub3RlKGlucHV0LCBvY3RhdmUpIHtcblx0XG5cdCAgICAgICAgdmFyIG5ld3ZhbHVlID0gdW5kZWZpbmVkO1xuXHRcblx0ICAgICAgICBpZiAodGhpcy5tb2RlLm91dHB1dCA9PT0gXCJmcmVxdWVuY3lcIikge1xuXHQgICAgICAgICAgbmV3dmFsdWUgPSB0aGlzLmZyZXF1ZW5jeShpbnB1dCwgb2N0YXZlKTtcblx0ICAgICAgICB9IGVsc2UgaWYgKHRoaXMubW9kZS5vdXRwdXQgPT09IFwicmF0aW9cIikge1xuXHQgICAgICAgICAgbmV3dmFsdWUgPSB0aGlzLnJhdGlvKGlucHV0LCBvY3RhdmUpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlLm91dHB1dCA9PT0gXCJNSURJXCIpIHtcblx0ICAgICAgICAgIG5ld3ZhbHVlID0gdGhpcy5NSURJKGlucHV0LCBvY3RhdmUpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBuZXd2YWx1ZSA9IHRoaXMuZnJlcXVlbmN5KGlucHV0LCBvY3RhdmUpO1xuXHQgICAgICAgIH1cblx0XG5cdCAgICAgICAgcmV0dXJuIG5ld3ZhbHVlO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgZnJlcXVlbmN5OiB7XG5cdFxuXHQgICAgICAvKiBSZXR1cm4gZnJlcSBkYXRhICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gZnJlcXVlbmN5KHN0ZXBJbiwgb2N0YXZlSW4pIHtcblx0XG5cdCAgICAgICAgaWYgKHRoaXMubW9kZS5pbnB1dCA9PT0gXCJtaWRpXCIgfHwgdGhpcy5tb2RlLmlucHV0ID09PSBcIk1JRElcIikge1xuXHQgICAgICAgICAgdGhpcy5zdGVwSW4gKz0gNjA7XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICAvLyB3aGF0IG9jdGF2ZSBpcyBvdXIgaW5wdXRcblx0ICAgICAgICB2YXIgb2N0YXZlID0gTWF0aC5mbG9vcihzdGVwSW4gLyB0aGlzLnNjYWxlLmxlbmd0aCk7XG5cdFxuXHQgICAgICAgIGlmIChvY3RhdmVJbikge1xuXHQgICAgICAgICAgb2N0YXZlICs9IG9jdGF2ZUluO1xuXHQgICAgICAgIH1cblx0XG5cdCAgICAgICAgLy8gd2hpY2ggc2NhbGUgZGVncmVlICgwIC0gc2NhbGUgbGVuZ3RoKSBpcyBvdXIgaW5wdXRcblx0ICAgICAgICB2YXIgc2NhbGVEZWdyZWUgPSBzdGVwSW4gJSB0aGlzLnNjYWxlLmxlbmd0aDtcblx0XG5cdCAgICAgICAgd2hpbGUgKHNjYWxlRGVncmVlIDwgMCkge1xuXHQgICAgICAgICAgc2NhbGVEZWdyZWUgKz0gdGhpcy5zY2FsZS5sZW5ndGg7XG5cdCAgICAgICAgfVxuXHRcblx0ICAgICAgICB2YXIgcmF0aW8gPSB0aGlzLnNjYWxlW3NjYWxlRGVncmVlXTtcblx0XG5cdCAgICAgICAgdmFyIGZyZXEgPSB0aGlzLnJvb3QgKiByYXRpbztcblx0XG5cdCAgICAgICAgZnJlcSA9IGZyZXEgKiBNYXRoLnBvdygyLCBvY3RhdmUpO1xuXHRcblx0ICAgICAgICAvLyB0cnVuY2F0ZSBpcnJhdGlvbmFsIG51bWJlcnNcblx0ICAgICAgICBmcmVxID0gTWF0aC5mbG9vcihmcmVxICogMTAwMDAwMDAwMDAwKSAvIDEwMDAwMDAwMDAwMDtcblx0XG5cdCAgICAgICAgcmV0dXJuIGZyZXE7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICByYXRpbzoge1xuXHRcblx0ICAgICAgLyogRm9yY2UgcmV0dXJuIHJhdGlvIGRhdGEgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiByYXRpbyhzdGVwSW4sIG9jdGF2ZUluKSB7XG5cdFxuXHQgICAgICAgIGlmICh0aGlzLm1vZGUuaW5wdXQgPT09IFwibWlkaVwiIHx8IHRoaXMubW9kZS5pbnB1dCA9PT0gXCJNSURJXCIpIHtcblx0ICAgICAgICAgIHRoaXMuc3RlcEluICs9IDYwO1xuXHQgICAgICAgIH1cblx0XG5cdCAgICAgICAgLy8gd2hhdCBvY3RhdmUgaXMgb3VyIGlucHV0XG5cdCAgICAgICAgdmFyIG9jdGF2ZSA9IE1hdGguZmxvb3Ioc3RlcEluIC8gdGhpcy5zY2FsZS5sZW5ndGgpO1xuXHRcblx0ICAgICAgICBpZiAob2N0YXZlSW4pIHtcblx0ICAgICAgICAgIG9jdGF2ZSArPSBvY3RhdmVJbjtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIC8vIHdoaWNoIHNjYWxlIGRlZ3JlZSAoMCAtIHNjYWxlIGxlbmd0aCkgaXMgb3VyIGlucHV0XG5cdCAgICAgICAgdmFyIHNjYWxlRGVncmVlID0gc3RlcEluICUgdGhpcy5zY2FsZS5sZW5ndGg7XG5cdFxuXHQgICAgICAgIC8vIHdoYXQgcmF0aW8gaXMgb3VyIGlucHV0IHRvIG91ciBrZXlcblx0ICAgICAgICB2YXIgcmF0aW8gPSBNYXRoLnBvdygyLCBvY3RhdmUpICogdGhpcy5zY2FsZVtzY2FsZURlZ3JlZV07XG5cdFxuXHQgICAgICAgIHJhdGlvID0gTWF0aC5mbG9vcihyYXRpbyAqIDEwMDAwMDAwMDAwMCkgLyAxMDAwMDAwMDAwMDA7XG5cdFxuXHQgICAgICAgIHJldHVybiByYXRpbztcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIE1JREk6IHtcblx0XG5cdCAgICAgIC8qIEZvcmNlIHJldHVybiBhZGp1c3RlZCBNSURJIGRhdGEgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBNSURJKHN0ZXBJbiwgb2N0YXZlSW4pIHtcblx0XG5cdCAgICAgICAgdmFyIG5ld3ZhbHVlID0gdGhpcy5mcmVxdWVuY3koc3RlcEluLCBvY3RhdmVJbik7XG5cdFxuXHQgICAgICAgIHZhciBuID0gNjkgKyAxMiAqIE1hdGgubG9nKG5ld3ZhbHVlIC8gNDQwKSAvIE1hdGgubG9nKDIpO1xuXHRcblx0ICAgICAgICBuID0gTWF0aC5mbG9vcihuICogMTAwMDAwMDAwMCkgLyAxMDAwMDAwMDAwO1xuXHRcblx0ICAgICAgICByZXR1cm4gbjtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNyZWF0ZVNjYWxlOiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBjcmVhdGVTY2FsZSgpIHtcblx0ICAgICAgICB2YXIgbmV3U2NhbGUgPSBbXTtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgbmV3U2NhbGUucHVzaChtYXRoLm10b2YoNjAgKyBhcmd1bWVudHNbaV0pKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5sb2FkU2NhbGVGcm9tRnJlcXVlbmNpZXMobmV3U2NhbGUpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgY3JlYXRlSklTY2FsZToge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlSklTY2FsZSgpIHtcblx0ICAgICAgICB0aGlzLnNjYWxlID0gW107XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgIHRoaXMuc2NhbGUucHVzaChhcmd1bWVudHNbaV0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGxvYWRTY2FsZUZyb21GcmVxdWVuY2llczoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gbG9hZFNjYWxlRnJvbUZyZXF1ZW5jaWVzKGZyZXFzKSB7XG5cdCAgICAgICAgdGhpcy5zY2FsZSA9IFtdO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZnJlcXMubGVuZ3RoIC0gMTsgaSsrKSB7XG5cdCAgICAgICAgICB0aGlzLnNjYWxlLnB1c2goZnJlcXNbaV0gLyBmcmVxc1swXSk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbG9hZFNjYWxlOiB7XG5cdFxuXHQgICAgICAvKiBMb2FkIGEgbmV3IHNjYWxlICovXG5cdFxuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gbG9hZFNjYWxlKG5hbWUpIHtcblx0XG5cdCAgICAgICAgLyogbG9hZCB0aGUgc2NhbGUgKi9cblx0ICAgICAgICB2YXIgZnJlcXMgPSB0aGlzLnNjYWxlc1tuYW1lXS5mcmVxdWVuY2llcztcblx0ICAgICAgICB0aGlzLmxvYWRTY2FsZUZyb21GcmVxdWVuY2llcyhmcmVxcyk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzZWFyY2g6IHtcblx0XG5cdCAgICAgIC8qIFNlYXJjaCB0aGUgbmFtZXMgb2YgdHVuaW5nc1xuXHQgICAgICBcdCBSZXR1cm5zIGFuIGFycmF5IG9mIG5hbWVzIG9mIHR1bmluZ3MgKi9cblx0XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZWFyY2gobGV0dGVycykge1xuXHQgICAgICAgIHZhciBwb3NzaWJsZSA9IFtdO1xuXHQgICAgICAgIGZvciAodmFyIGtleSBpbiB0aGlzLnNjYWxlcykge1xuXHQgICAgICAgICAgaWYgKGtleS50b0xvd2VyQ2FzZSgpLmluZGV4T2YobGV0dGVycy50b0xvd2VyQ2FzZSgpKSAhPT0gLTEpIHtcblx0ICAgICAgICAgICAgcG9zc2libGUucHVzaChrZXkpO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gcG9zc2libGU7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBjaG9yZDoge1xuXHRcblx0ICAgICAgLyogUmV0dXJuIGEgY29sbGVjdGlvbiBvZiBub3RlcyBhcyBhbiBhcnJheSAqL1xuXHRcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNob3JkKG1pZGlzKSB7XG5cdCAgICAgICAgdmFyIG91dHB1dCA9IFtdO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWlkaXMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgIG91dHB1dC5wdXNoKHRoaXMubm90ZShtaWRpc1tpXSkpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gb3V0cHV0O1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSk7XG5cdFxuXHQgIHJldHVybiBUdW5lO1xuXHR9KSgpO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBUdW5lO1xuXG4vKioqLyB9KSxcbi8qIDQxICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHR2YXIgX2NyZWF0ZUNsYXNzID0gKGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGtleSBpbiBwcm9wcykgeyB2YXIgcHJvcCA9IHByb3BzW2tleV07IHByb3AuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKHByb3AudmFsdWUpIHByb3Aud3JpdGFibGUgPSB0cnVlOyB9IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpOyB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cdFxuXHR2YXIgX2NsYXNzQ2FsbENoZWNrID0gZnVuY3Rpb24gKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH07XG5cdFxuXHQvL0Rpc2FibGUganNoaW50IHdhcm5pbmcgY29uY2VybmluZyB0cmFpbGluZyByZWd1bGFyIHBhcmFtc1xuXHQvKmpzaGludCAtVzEzOCAqL1xuXHRcblx0dmFyIFJhZGlvID0gKGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vaWYgbm9uLWV4aXN0ZW50IGJ1dHRvbnMgYXJlIHN3aXRjaGVkLCB0aGV5IGFyZSBpZ25vcmVkXG5cdFxuXHQgICAgZnVuY3Rpb24gUmFkaW8oKSB7XG5cdCAgICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIG9uVmFscyA9IEFycmF5KF9sZW4gPiAxID8gX2xlbiAtIDEgOiAwKSwgX2tleSA9IDE7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcblx0ICAgICAgICAgICAgb25WYWxzW19rZXkgLSAxXSA9IGFyZ3VtZW50c1tfa2V5XTtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IDMgOiBhcmd1bWVudHNbMF07XG5cdFxuXHQgICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBSYWRpbyk7XG5cdFxuXHQgICAgICAgIC8vZWFjaCBvcHRpb25hbCAnb25WYWxzJyBhcmd1bWVudCBzd2l0Y2hlcyBvbiB0aGF0IHZhbHVlIGluIHRoZSBSYWRpbyBpZiBpdCBleGlzdHNcblx0ICAgICAgICAvL0luIHRoZSBleGFtcGxlIGJlbG93LCBhIDMtYnV0dG9uIHJhZGlvIGlzIGNyZWF0ZWQsIGluZGV4IDAgaXMgc3dpdGNoZWQgb24sIGluZGV4IDEgaXMgc3dpdGNoZWQgb24gdGhlbiB0aGVuIGF0dGVtcHRlZCBhZ2FpbiBwcm9kdWNpbmcgYW4gd2FybmluZywgYW5kIHRoZSBmaW5hbCBhcmd1bWVudCBwcm9kdWNlcyBhIHdhcm5pbmcgYmVjYXVzZSB0aGUgaW5kZXggdmFsdWUgZG9lcyBub3QgZXhpc3QuXG5cdCAgICAgICAgLy9FeGFtcGxlOlxuXHQgICAgICAgIC8vYCAgcmFkaW8gPSBuZXcgUmFkaW8oMywgMCwgMSwgMSwgMyk7XG5cdCAgICAgICAgLy/igKYgIFsxLDEsMF1cblx0XG5cdCAgICAgICAgaWYgKGxlbmd0aCA8IDApIHtcblx0ICAgICAgICAgICAgbGVuZ3RoID0gMTtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoO1xuXHQgICAgICAgIHRoaXMub25WYWxzID0gb25WYWxzO1xuXHQgICAgICAgIHRoaXMuYXJyYXkgPSBuZXcgQXJyYXkobGVuZ3RoKS5maWxsKDApO1xuXHRcblx0ICAgICAgICBpZiAob25WYWxzLmxlbmd0aCA+IDApIHtcblx0ICAgICAgICAgICAgdGhpcy5vbi5hcHBseSh0aGlzLCBvblZhbHMpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0XG5cdCAgICBfY3JlYXRlQ2xhc3MoUmFkaW8sIHtcblx0ICAgICAgICBzZWxlY3Q6IHtcblx0ICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNlbGVjdCh2YWx1ZSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5hcnJheS5maWxsKDApO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5hcnJheVt2YWx1ZV0gPSAxO1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYXJyYXk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXHQgICAgICAgIGZsaXA6IHtcblx0ICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZsaXAoKSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgdmFsdWVzID0gQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFsdWVzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuXHQgICAgICAgICAgICAgICAgfVxuXHRcblx0ICAgICAgICAgICAgICAgIC8vZmxpcHMgdGhlIHNwZWNpZmllZCB2YWx1ZXMuIGlmIG5vIHZhbHVlIGlzIHNwZWNpZmllZCwgZmxpcHMgYWxsIGJ1dHRvbnNcblx0ICAgICAgICAgICAgICAgIHZhciBhID0gdGhpcy5hcnJheTtcblx0ICAgICAgICAgICAgICAgIGlmICh2YWx1ZXMubGVuZ3RoID4gMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2ID4gYS5sZW5ndGggLSAxKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXCJXYXJuaW5nOiBBbm9uUmFkaW9bXCIgKyB2ICsgXCJdIGRvZXMgbm90IGV4aXN0XCIpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVt2XSA9IGFbdl0gPyAwIDogMTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICBhLmZvckVhY2goZnVuY3Rpb24gKHYsIGksIGFycikge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBhcnJbaV0gPSB2ID8gMCA6IDE7XG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gYTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgb246IHtcblx0ICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIG9uKCkge1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIHZhbHVlcyA9IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhbHVlc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcblx0ICAgICAgICAgICAgICAgIH1cblx0XG5cdCAgICAgICAgICAgICAgICAvL3N3aXRjaCBvbiB0aGUgc3BlY2lmaWVkIHZhbHVlcy4gaWYgbm8gdmFsdWUgc3BlY2lmaWVkLCBmbGlwcyBvbiBhbGwgYnV0dG9uc1xuXHQgICAgICAgICAgICAgICAgdmFyIGEgPSB0aGlzLmFycmF5O1xuXHQgICAgICAgICAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPiAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFsdWVzLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHYgPiBhLmxlbmd0aCAtIDEpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIldhcm5pbmc6IEFub25SYWRpb1tcIiArIHYgKyBcIl0gZXhjZWVkcyBzaXplIG9mIG9iamVjdFwiKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhW3ZdID09PSAxKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiV2FybmluZzogQW5vblJhZGlvW1wiICsgdiArIFwiXSB3YXMgYWxyZWFkeSBvbi5cIik7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBhW3ZdID0gMTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICBhLmZpbGwoMSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gYTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgb2ZmOiB7XG5cdCAgICAgICAgICAgIHZhbHVlOiBmdW5jdGlvbiBvZmYoKSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgdmFsdWVzID0gQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFsdWVzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuXHQgICAgICAgICAgICAgICAgfVxuXHRcblx0ICAgICAgICAgICAgICAgIC8vc3dpdGNoIG9mZiB0aGUgc3BlY2lmaWVkIHZhbHVlcy4gaWYgbm8gdmFsdWUgc3BlY2lmaWVkLCBmbGlwcyBvZmYgYWxsIGJ1dHRvbnNcblx0ICAgICAgICAgICAgICAgIHZhciBhID0gdGhpcy5hcnJheTtcblx0ICAgICAgICAgICAgICAgIGlmICh2YWx1ZXMubGVuZ3RoID4gMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGFbdl0gPSAwO1xuXHQgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICBhLmZpbGwoMCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gYTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXHRcblx0ICAgIHJldHVybiBSYWRpbztcblx0fSkoKTtcblx0XG5cdG1vZHVsZS5leHBvcnRzID0gUmFkaW87XG5cbi8qKiovIH0pLFxuLyogNDIgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHR2YXIgV0FBQ2xvY2sgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQzKVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBXQUFDbG9ja1xuXHRpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHdpbmRvdy5XQUFDbG9jayA9IFdBQUNsb2NrXG5cblxuLyoqKi8gfSksXG4vKiA0MyAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdC8qIFdFQlBBQ0sgVkFSIElOSkVDVElPTiAqLyhmdW5jdGlvbihwcm9jZXNzKSB7dmFyIGlzQnJvd3NlciA9ICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJylcblx0XG5cdHZhciBDTE9DS19ERUZBVUxUUyA9IHtcblx0ICB0b2xlcmFuY2VMYXRlOiAwLjEwLFxuXHQgIHRvbGVyYW5jZUVhcmx5OiAwLjAwMVxuXHR9XG5cdFxuXHQvLyA9PT09PT09PT09PT09PT09PT09PSBFdmVudCA9PT09PT09PT09PT09PT09PT09PSAvL1xuXHR2YXIgRXZlbnQgPSBmdW5jdGlvbihjbG9jaywgZGVhZGxpbmUsIGZ1bmMpIHtcblx0ICB0aGlzLmNsb2NrID0gY2xvY2tcblx0ICB0aGlzLmZ1bmMgPSBmdW5jXG5cdCAgdGhpcy5fY2xlYXJlZCA9IGZhbHNlIC8vIEZsYWcgdXNlZCB0byBjbGVhciBhbiBldmVudCBpbnNpZGUgY2FsbGJhY2tcblx0XG5cdCAgdGhpcy50b2xlcmFuY2VMYXRlID0gY2xvY2sudG9sZXJhbmNlTGF0ZVxuXHQgIHRoaXMudG9sZXJhbmNlRWFybHkgPSBjbG9jay50b2xlcmFuY2VFYXJseVxuXHQgIHRoaXMuX2xhdGVzdFRpbWUgPSBudWxsXG5cdCAgdGhpcy5fZWFybGllc3RUaW1lID0gbnVsbFxuXHQgIHRoaXMuZGVhZGxpbmUgPSBudWxsXG5cdCAgdGhpcy5yZXBlYXRUaW1lID0gbnVsbFxuXHRcblx0ICB0aGlzLnNjaGVkdWxlKGRlYWRsaW5lKVxuXHR9XG5cdFxuXHQvLyBVbnNjaGVkdWxlcyB0aGUgZXZlbnRcblx0RXZlbnQucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XG5cdCAgdGhpcy5jbG9jay5fcmVtb3ZlRXZlbnQodGhpcylcblx0ICB0aGlzLl9jbGVhcmVkID0gdHJ1ZVxuXHQgIHJldHVybiB0aGlzXG5cdH1cblx0XG5cdC8vIFNldHMgdGhlIGV2ZW50IHRvIHJlcGVhdCBldmVyeSBgdGltZWAgc2Vjb25kcy5cblx0RXZlbnQucHJvdG90eXBlLnJlcGVhdCA9IGZ1bmN0aW9uKHRpbWUpIHtcblx0ICBpZiAodGltZSA9PT0gMClcblx0ICAgIHRocm93IG5ldyBFcnJvcignZGVsYXkgY2Fubm90IGJlIDAnKVxuXHQgIHRoaXMucmVwZWF0VGltZSA9IHRpbWVcblx0ICBpZiAoIXRoaXMuY2xvY2suX2hhc0V2ZW50KHRoaXMpKVxuXHQgICAgdGhpcy5zY2hlZHVsZSh0aGlzLmRlYWRsaW5lICsgdGhpcy5yZXBlYXRUaW1lKVxuXHQgIHJldHVybiB0aGlzXG5cdH1cblx0XG5cdC8vIFNldHMgdGhlIHRpbWUgdG9sZXJhbmNlIG9mIHRoZSBldmVudC5cblx0Ly8gVGhlIGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQgaW4gdGhlIGludGVydmFsIGBbZGVhZGxpbmUgLSBlYXJseSwgZGVhZGxpbmUgKyBsYXRlXWBcblx0Ly8gSWYgdGhlIGNsb2NrIGZhaWxzIHRvIGV4ZWN1dGUgdGhlIGV2ZW50IGluIHRpbWUsIHRoZSBldmVudCB3aWxsIGJlIGRyb3BwZWQuXG5cdEV2ZW50LnByb3RvdHlwZS50b2xlcmFuY2UgPSBmdW5jdGlvbih2YWx1ZXMpIHtcblx0ICBpZiAodHlwZW9mIHZhbHVlcy5sYXRlID09PSAnbnVtYmVyJylcblx0ICAgIHRoaXMudG9sZXJhbmNlTGF0ZSA9IHZhbHVlcy5sYXRlXG5cdCAgaWYgKHR5cGVvZiB2YWx1ZXMuZWFybHkgPT09ICdudW1iZXInKVxuXHQgICAgdGhpcy50b2xlcmFuY2VFYXJseSA9IHZhbHVlcy5lYXJseVxuXHQgIHRoaXMuX3JlZnJlc2hFYXJseUxhdGVEYXRlcygpXG5cdCAgaWYgKHRoaXMuY2xvY2suX2hhc0V2ZW50KHRoaXMpKSB7XG5cdCAgICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuXHQgICAgdGhpcy5jbG9jay5faW5zZXJ0RXZlbnQodGhpcylcblx0ICB9XG5cdCAgcmV0dXJuIHRoaXNcblx0fVxuXHRcblx0Ly8gUmV0dXJucyB0cnVlIGlmIHRoZSBldmVudCBpcyByZXBlYXRlZCwgZmFsc2Ugb3RoZXJ3aXNlXG5cdEV2ZW50LnByb3RvdHlwZS5pc1JlcGVhdGVkID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLnJlcGVhdFRpbWUgIT09IG51bGwgfVxuXHRcblx0Ly8gU2NoZWR1bGVzIHRoZSBldmVudCB0byBiZSByYW4gYmVmb3JlIGBkZWFkbGluZWAuXG5cdC8vIElmIHRoZSB0aW1lIGlzIHdpdGhpbiB0aGUgZXZlbnQgdG9sZXJhbmNlLCB3ZSBoYW5kbGUgdGhlIGV2ZW50IGltbWVkaWF0ZWx5LlxuXHQvLyBJZiB0aGUgZXZlbnQgd2FzIGFscmVhZHkgc2NoZWR1bGVkIGF0IGEgZGlmZmVyZW50IHRpbWUsIGl0IGlzIHJlc2NoZWR1bGVkLlxuXHRFdmVudC5wcm90b3R5cGUuc2NoZWR1bGUgPSBmdW5jdGlvbihkZWFkbGluZSkge1xuXHQgIHRoaXMuX2NsZWFyZWQgPSBmYWxzZVxuXHQgIHRoaXMuZGVhZGxpbmUgPSBkZWFkbGluZVxuXHQgIHRoaXMuX3JlZnJlc2hFYXJseUxhdGVEYXRlcygpXG5cdFxuXHQgIGlmICh0aGlzLmNsb2NrLmNvbnRleHQuY3VycmVudFRpbWUgPj0gdGhpcy5fZWFybGllc3RUaW1lKSB7XG5cdCAgICB0aGlzLl9leGVjdXRlKClcblx0ICBcblx0ICB9IGVsc2UgaWYgKHRoaXMuY2xvY2suX2hhc0V2ZW50KHRoaXMpKSB7XG5cdCAgICB0aGlzLmNsb2NrLl9yZW1vdmVFdmVudCh0aGlzKVxuXHQgICAgdGhpcy5jbG9jay5faW5zZXJ0RXZlbnQodGhpcylcblx0ICBcblx0ICB9IGVsc2UgdGhpcy5jbG9jay5faW5zZXJ0RXZlbnQodGhpcylcblx0fVxuXHRcblx0RXZlbnQucHJvdG90eXBlLnRpbWVTdHJldGNoID0gZnVuY3Rpb24odFJlZiwgcmF0aW8pIHtcblx0ICBpZiAodGhpcy5pc1JlcGVhdGVkKCkpXG5cdCAgICB0aGlzLnJlcGVhdFRpbWUgPSB0aGlzLnJlcGVhdFRpbWUgKiByYXRpb1xuXHRcblx0ICB2YXIgZGVhZGxpbmUgPSB0UmVmICsgcmF0aW8gKiAodGhpcy5kZWFkbGluZSAtIHRSZWYpXG5cdCAgLy8gSWYgdGhlIGRlYWRsaW5lIGlzIHRvbyBjbG9zZSBvciBwYXN0LCBhbmQgdGhlIGV2ZW50IGhhcyBhIHJlcGVhdCxcblx0ICAvLyB3ZSBjYWxjdWxhdGUgdGhlIG5leHQgcmVwZWF0IHBvc3NpYmxlIGluIHRoZSBzdHJldGNoZWQgc3BhY2UuXG5cdCAgaWYgKHRoaXMuaXNSZXBlYXRlZCgpKSB7XG5cdCAgICB3aGlsZSAodGhpcy5jbG9jay5jb250ZXh0LmN1cnJlbnRUaW1lID49IGRlYWRsaW5lIC0gdGhpcy50b2xlcmFuY2VFYXJseSlcblx0ICAgICAgZGVhZGxpbmUgKz0gdGhpcy5yZXBlYXRUaW1lXG5cdCAgfVxuXHQgIHRoaXMuc2NoZWR1bGUoZGVhZGxpbmUpXG5cdH1cblx0XG5cdC8vIEV4ZWN1dGVzIHRoZSBldmVudFxuXHRFdmVudC5wcm90b3R5cGUuX2V4ZWN1dGUgPSBmdW5jdGlvbigpIHtcblx0ICBpZiAodGhpcy5jbG9jay5fc3RhcnRlZCA9PT0gZmFsc2UpIHJldHVyblxuXHQgIHRoaXMuY2xvY2suX3JlbW92ZUV2ZW50KHRoaXMpXG5cdFxuXHQgIGlmICh0aGlzLmNsb2NrLmNvbnRleHQuY3VycmVudFRpbWUgPCB0aGlzLl9sYXRlc3RUaW1lKVxuXHQgICAgdGhpcy5mdW5jKHRoaXMpXG5cdCAgZWxzZSB7XG5cdCAgICBpZiAodGhpcy5vbmV4cGlyZWQpIHRoaXMub25leHBpcmVkKHRoaXMpXG5cdCAgICBjb25zb2xlLndhcm4oJ2V2ZW50IGV4cGlyZWQnKVxuXHQgIH1cblx0ICAvLyBJbiB0aGUgY2FzZSBgc2NoZWR1bGVgIGlzIGNhbGxlZCBpbnNpZGUgYGZ1bmNgLCB3ZSBuZWVkIHRvIGF2b2lkXG5cdCAgLy8gb3ZlcnJ3cml0aW5nIHdpdGggeWV0IGFub3RoZXIgYHNjaGVkdWxlYC5cblx0ICBpZiAoIXRoaXMuY2xvY2suX2hhc0V2ZW50KHRoaXMpICYmIHRoaXMuaXNSZXBlYXRlZCgpICYmICF0aGlzLl9jbGVhcmVkKVxuXHQgICAgdGhpcy5zY2hlZHVsZSh0aGlzLmRlYWRsaW5lICsgdGhpcy5yZXBlYXRUaW1lKSBcblx0fVxuXHRcblx0Ly8gVXBkYXRlcyBjYWNoZWQgdGltZXNcblx0RXZlbnQucHJvdG90eXBlLl9yZWZyZXNoRWFybHlMYXRlRGF0ZXMgPSBmdW5jdGlvbigpIHtcblx0ICB0aGlzLl9sYXRlc3RUaW1lID0gdGhpcy5kZWFkbGluZSArIHRoaXMudG9sZXJhbmNlTGF0ZVxuXHQgIHRoaXMuX2VhcmxpZXN0VGltZSA9IHRoaXMuZGVhZGxpbmUgLSB0aGlzLnRvbGVyYW5jZUVhcmx5XG5cdH1cblx0XG5cdC8vID09PT09PT09PT09PT09PT09PT09IFdBQUNsb2NrID09PT09PT09PT09PT09PT09PT09IC8vXG5cdHZhciBXQUFDbG9jayA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oY29udGV4dCwgb3B0cykge1xuXHQgIHZhciBzZWxmID0gdGhpc1xuXHQgIG9wdHMgPSBvcHRzIHx8IHt9XG5cdCAgdGhpcy50aWNrTWV0aG9kID0gb3B0cy50aWNrTWV0aG9kIHx8ICdTY3JpcHRQcm9jZXNzb3JOb2RlJ1xuXHQgIHRoaXMudG9sZXJhbmNlRWFybHkgPSBvcHRzLnRvbGVyYW5jZUVhcmx5IHx8IENMT0NLX0RFRkFVTFRTLnRvbGVyYW5jZUVhcmx5XG5cdCAgdGhpcy50b2xlcmFuY2VMYXRlID0gb3B0cy50b2xlcmFuY2VMYXRlIHx8IENMT0NLX0RFRkFVTFRTLnRvbGVyYW5jZUxhdGVcblx0ICB0aGlzLmNvbnRleHQgPSBjb250ZXh0XG5cdCAgdGhpcy5fZXZlbnRzID0gW11cblx0ICB0aGlzLl9zdGFydGVkID0gZmFsc2Vcblx0fVxuXHRcblx0Ly8gLS0tLS0tLS0tLSBQdWJsaWMgQVBJIC0tLS0tLS0tLS0gLy9cblx0Ly8gU2NoZWR1bGVzIGBmdW5jYCB0byBydW4gYWZ0ZXIgYGRlbGF5YCBzZWNvbmRzLlxuXHRXQUFDbG9jay5wcm90b3R5cGUuc2V0VGltZW91dCA9IGZ1bmN0aW9uKGZ1bmMsIGRlbGF5KSB7XG5cdCAgcmV0dXJuIHRoaXMuX2NyZWF0ZUV2ZW50KGZ1bmMsIHRoaXMuX2Fic1RpbWUoZGVsYXkpKVxuXHR9XG5cdFxuXHQvLyBTY2hlZHVsZXMgYGZ1bmNgIHRvIHJ1biBiZWZvcmUgYGRlYWRsaW5lYC5cblx0V0FBQ2xvY2sucHJvdG90eXBlLmNhbGxiYWNrQXRUaW1lID0gZnVuY3Rpb24oZnVuYywgZGVhZGxpbmUpIHtcblx0ICByZXR1cm4gdGhpcy5fY3JlYXRlRXZlbnQoZnVuYywgZGVhZGxpbmUpXG5cdH1cblx0XG5cdC8vIFN0cmV0Y2hlcyBgZGVhZGxpbmVgIGFuZCBgcmVwZWF0YCBvZiBhbGwgc2NoZWR1bGVkIGBldmVudHNgIGJ5IGByYXRpb2AsIGtlZXBpbmdcblx0Ly8gdGhlaXIgcmVsYXRpdmUgZGlzdGFuY2UgdG8gYHRSZWZgLiBJbiBmYWN0IHRoaXMgaXMgZXF1aXZhbGVudCB0byBjaGFuZ2luZyB0aGUgdGVtcG8uXG5cdFdBQUNsb2NrLnByb3RvdHlwZS50aW1lU3RyZXRjaCA9IGZ1bmN0aW9uKHRSZWYsIGV2ZW50cywgcmF0aW8pIHtcblx0ICBldmVudHMuZm9yRWFjaChmdW5jdGlvbihldmVudCkgeyBldmVudC50aW1lU3RyZXRjaCh0UmVmLCByYXRpbykgfSlcblx0ICByZXR1cm4gZXZlbnRzXG5cdH1cblx0XG5cdC8vIFJlbW92ZXMgYWxsIHNjaGVkdWxlZCBldmVudHMgYW5kIHN0YXJ0cyB0aGUgY2xvY2sgXG5cdFdBQUNsb2NrLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uKCkge1xuXHQgIGlmICh0aGlzLl9zdGFydGVkID09PSBmYWxzZSkge1xuXHQgICAgdmFyIHNlbGYgPSB0aGlzXG5cdCAgICB0aGlzLl9zdGFydGVkID0gdHJ1ZVxuXHQgICAgdGhpcy5fZXZlbnRzID0gW11cblx0XG5cdCAgICBpZiAodGhpcy50aWNrTWV0aG9kID09PSAnU2NyaXB0UHJvY2Vzc29yTm9kZScpIHtcblx0ICAgICAgdmFyIGJ1ZmZlclNpemUgPSAyNTZcblx0ICAgICAgLy8gV2UgaGF2ZSB0byBrZWVwIGEgcmVmZXJlbmNlIHRvIHRoZSBub2RlIHRvIGF2b2lkIGdhcmJhZ2UgY29sbGVjdGlvblxuXHQgICAgICB0aGlzLl9jbG9ja05vZGUgPSB0aGlzLmNvbnRleHQuY3JlYXRlU2NyaXB0UHJvY2Vzc29yKGJ1ZmZlclNpemUsIDEsIDEpXG5cdCAgICAgIHRoaXMuX2Nsb2NrTm9kZS5jb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbilcblx0ICAgICAgdGhpcy5fY2xvY2tOb2RlLm9uYXVkaW9wcm9jZXNzID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24oKSB7IHNlbGYuX3RpY2soKSB9KVxuXHQgICAgICB9XG5cdCAgICB9IGVsc2UgaWYgKHRoaXMudGlja01ldGhvZCA9PT0gJ21hbnVhbCcpIG51bGwgLy8gX3RpY2sgaXMgY2FsbGVkIG1hbnVhbGx5XG5cdFxuXHQgICAgZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgdGlja01ldGhvZCAnICsgdGhpcy50aWNrTWV0aG9kKVxuXHQgIH1cblx0fVxuXHRcblx0Ly8gU3RvcHMgdGhlIGNsb2NrXG5cdFdBQUNsb2NrLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7XG5cdCAgaWYgKHRoaXMuX3N0YXJ0ZWQgPT09IHRydWUpIHtcblx0ICAgIHRoaXMuX3N0YXJ0ZWQgPSBmYWxzZVxuXHQgICAgdGhpcy5fY2xvY2tOb2RlLmRpc2Nvbm5lY3QoKVxuXHQgIH0gIFxuXHR9XG5cdFxuXHQvLyAtLS0tLS0tLS0tIFByaXZhdGUgLS0tLS0tLS0tLSAvL1xuXHRcblx0Ly8gVGhpcyBmdW5jdGlvbiBpcyByYW4gcGVyaW9kaWNhbGx5LCBhbmQgYXQgZWFjaCB0aWNrIGl0IGV4ZWN1dGVzXG5cdC8vIGV2ZW50cyBmb3Igd2hpY2ggYGN1cnJlbnRUaW1lYCBpcyBpbmNsdWRlZCBpbiB0aGVpciB0b2xlcmFuY2UgaW50ZXJ2YWwuXG5cdFdBQUNsb2NrLnByb3RvdHlwZS5fdGljayA9IGZ1bmN0aW9uKCkge1xuXHQgIHZhciBldmVudCA9IHRoaXMuX2V2ZW50cy5zaGlmdCgpXG5cdFxuXHQgIHdoaWxlKGV2ZW50ICYmIGV2ZW50Ll9lYXJsaWVzdFRpbWUgPD0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lKSB7XG5cdCAgICBldmVudC5fZXhlY3V0ZSgpXG5cdCAgICBldmVudCA9IHRoaXMuX2V2ZW50cy5zaGlmdCgpXG5cdCAgfVxuXHRcblx0ICAvLyBQdXQgYmFjayB0aGUgbGFzdCBldmVudFxuXHQgIGlmKGV2ZW50KSB0aGlzLl9ldmVudHMudW5zaGlmdChldmVudClcblx0fVxuXHRcblx0Ly8gQ3JlYXRlcyBhbiBldmVudCBhbmQgaW5zZXJ0IGl0IHRvIHRoZSBsaXN0XG5cdFdBQUNsb2NrLnByb3RvdHlwZS5fY3JlYXRlRXZlbnQgPSBmdW5jdGlvbihmdW5jLCBkZWFkbGluZSkge1xuXHQgIHJldHVybiBuZXcgRXZlbnQodGhpcywgZGVhZGxpbmUsIGZ1bmMpXG5cdH1cblx0XG5cdC8vIEluc2VydHMgYW4gZXZlbnQgdG8gdGhlIGxpc3Rcblx0V0FBQ2xvY2sucHJvdG90eXBlLl9pbnNlcnRFdmVudCA9IGZ1bmN0aW9uKGV2ZW50KSB7XG5cdCAgdGhpcy5fZXZlbnRzLnNwbGljZSh0aGlzLl9pbmRleEJ5VGltZShldmVudC5fZWFybGllc3RUaW1lKSwgMCwgZXZlbnQpXG5cdH1cblx0XG5cdC8vIFJlbW92ZXMgYW4gZXZlbnQgZnJvbSB0aGUgbGlzdFxuXHRXQUFDbG9jay5wcm90b3R5cGUuX3JlbW92ZUV2ZW50ID0gZnVuY3Rpb24oZXZlbnQpIHtcblx0ICB2YXIgaW5kID0gdGhpcy5fZXZlbnRzLmluZGV4T2YoZXZlbnQpXG5cdCAgaWYgKGluZCAhPT0gLTEpIHRoaXMuX2V2ZW50cy5zcGxpY2UoaW5kLCAxKVxuXHR9XG5cdFxuXHQvLyBSZXR1cm5zIHRydWUgaWYgYGV2ZW50YCBpcyBpbiBxdWV1ZSwgZmFsc2Ugb3RoZXJ3aXNlXG5cdFdBQUNsb2NrLnByb3RvdHlwZS5faGFzRXZlbnQgPSBmdW5jdGlvbihldmVudCkge1xuXHQgcmV0dXJuIHRoaXMuX2V2ZW50cy5pbmRleE9mKGV2ZW50KSAhPT0gLTFcblx0fVxuXHRcblx0Ly8gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGV2ZW50IHdob3NlIGRlYWRsaW5lIGlzID49IHRvIGBkZWFkbGluZWBcblx0V0FBQ2xvY2sucHJvdG90eXBlLl9pbmRleEJ5VGltZSA9IGZ1bmN0aW9uKGRlYWRsaW5lKSB7XG5cdCAgLy8gcGVyZm9ybXMgYSBiaW5hcnkgc2VhcmNoXG5cdCAgdmFyIGxvdyA9IDBcblx0ICAgICwgaGlnaCA9IHRoaXMuX2V2ZW50cy5sZW5ndGhcblx0ICAgICwgbWlkXG5cdCAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcblx0ICAgIG1pZCA9IE1hdGguZmxvb3IoKGxvdyArIGhpZ2gpIC8gMilcblx0ICAgIGlmICh0aGlzLl9ldmVudHNbbWlkXS5fZWFybGllc3RUaW1lIDwgZGVhZGxpbmUpXG5cdCAgICAgIGxvdyA9IG1pZCArIDFcblx0ICAgIGVsc2UgaGlnaCA9IG1pZFxuXHQgIH1cblx0ICByZXR1cm4gbG93XG5cdH1cblx0XG5cdC8vIENvbnZlcnRzIGZyb20gcmVsYXRpdmUgdGltZSB0byBhYnNvbHV0ZSB0aW1lXG5cdFdBQUNsb2NrLnByb3RvdHlwZS5fYWJzVGltZSA9IGZ1bmN0aW9uKHJlbFRpbWUpIHtcblx0ICByZXR1cm4gcmVsVGltZSArIHRoaXMuY29udGV4dC5jdXJyZW50VGltZVxuXHR9XG5cdFxuXHQvLyBDb252ZXJ0cyBmcm9tIGFic29sdXRlIHRpbWUgdG8gcmVsYXRpdmUgdGltZSBcblx0V0FBQ2xvY2sucHJvdG90eXBlLl9yZWxUaW1lID0gZnVuY3Rpb24oYWJzVGltZSkge1xuXHQgIHJldHVybiBhYnNUaW1lIC0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lXG5cdH1cblx0LyogV0VCUEFDSyBWQVIgSU5KRUNUSU9OICovfS5jYWxsKGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18oNDQpKSlcblxuLyoqKi8gfSksXG4vKiA0NCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdC8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXHR2YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cdFxuXHQvLyBjYWNoZWQgZnJvbSB3aGF0ZXZlciBnbG9iYWwgaXMgcHJlc2VudCBzbyB0aGF0IHRlc3QgcnVubmVycyB0aGF0IHN0dWIgaXRcblx0Ly8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG5cdC8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcblx0Ly8gZnVuY3Rpb24gYmVjYXVzZSB0cnkvY2F0Y2hlcyBkZW9wdGltaXplIGluIGNlcnRhaW4gZW5naW5lcy5cblx0XG5cdHZhciBjYWNoZWRTZXRUaW1lb3V0O1xuXHR2YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O1xuXHRcblx0ZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcblx0ICAgIHRocm93IG5ldyBFcnJvcignc2V0VGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xuXHR9XG5cdGZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuXHQgICAgdGhyb3cgbmV3IEVycm9yKCdjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcblx0fVxuXHQoZnVuY3Rpb24gKCkge1xuXHQgICAgdHJ5IHtcblx0ICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcblx0ICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG5cdCAgICAgICAgfVxuXHQgICAgfSBjYXRjaCAoZSkge1xuXHQgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuXHQgICAgfVxuXHQgICAgdHJ5IHtcblx0ICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcblx0ICAgICAgICB9XG5cdCAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcblx0ICAgIH1cblx0fSAoKSlcblx0ZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcblx0ICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG5cdCAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG5cdCAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcblx0ICAgIH1cblx0ICAgIC8vIGlmIHNldFRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG5cdCAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcblx0ICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcblx0ICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuXHQgICAgfVxuXHQgICAgdHJ5IHtcblx0ICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG5cdCAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcblx0ICAgIH0gY2F0Y2goZSl7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG5cdCAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcblx0ICAgICAgICB9IGNhdGNoKGUpe1xuXHQgICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuXHQgICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHRcblx0XG5cdH1cblx0ZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuXHQgICAgaWYgKGNhY2hlZENsZWFyVGltZW91dCA9PT0gY2xlYXJUaW1lb3V0KSB7XG5cdCAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG5cdCAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuXHQgICAgfVxuXHQgICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuXHQgICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG5cdCAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuXHQgICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcblx0ICAgIH1cblx0ICAgIHRyeSB7XG5cdCAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuXHQgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcblx0ICAgIH0gY2F0Y2ggKGUpe1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcblx0ICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKG51bGwsIG1hcmtlcik7XG5cdCAgICAgICAgfSBjYXRjaCAoZSl7XG5cdCAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuXHQgICAgICAgICAgICAvLyBTb21lIHZlcnNpb25zIG9mIEkuRS4gaGF2ZSBkaWZmZXJlbnQgcnVsZXMgZm9yIGNsZWFyVGltZW91dCB2cyBzZXRUaW1lb3V0XG5cdCAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0XG5cdFxuXHRcblx0fVxuXHR2YXIgcXVldWUgPSBbXTtcblx0dmFyIGRyYWluaW5nID0gZmFsc2U7XG5cdHZhciBjdXJyZW50UXVldWU7XG5cdHZhciBxdWV1ZUluZGV4ID0gLTE7XG5cdFxuXHRmdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG5cdCAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcblx0ICAgICAgICByZXR1cm47XG5cdCAgICB9XG5cdCAgICBkcmFpbmluZyA9IGZhbHNlO1xuXHQgICAgaWYgKGN1cnJlbnRRdWV1ZS5sZW5ndGgpIHtcblx0ICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG5cdCAgICB9XG5cdCAgICBpZiAocXVldWUubGVuZ3RoKSB7XG5cdCAgICAgICAgZHJhaW5RdWV1ZSgpO1xuXHQgICAgfVxuXHR9XG5cdFxuXHRmdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuXHQgICAgaWYgKGRyYWluaW5nKSB7XG5cdCAgICAgICAgcmV0dXJuO1xuXHQgICAgfVxuXHQgICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG5cdCAgICBkcmFpbmluZyA9IHRydWU7XG5cdFxuXHQgICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcblx0ICAgIHdoaWxlKGxlbikge1xuXHQgICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuXHQgICAgICAgIHF1ZXVlID0gW107XG5cdCAgICAgICAgd2hpbGUgKCsrcXVldWVJbmRleCA8IGxlbikge1xuXHQgICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG5cdCAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuXHQgICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcblx0ICAgIH1cblx0ICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG5cdCAgICBkcmFpbmluZyA9IGZhbHNlO1xuXHQgICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXHR9XG5cdFxuXHRwcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuXHQgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuXHQgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcblx0ICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG5cdCAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcblx0ICAgIH1cblx0fTtcblx0XG5cdC8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcblx0ZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG5cdCAgICB0aGlzLmZ1biA9IGZ1bjtcblx0ICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcblx0fVxuXHRJdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG5cdCAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcblx0fTtcblx0cHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcblx0cHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcblx0cHJvY2Vzcy5lbnYgPSB7fTtcblx0cHJvY2Vzcy5hcmd2ID0gW107XG5cdHByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xuXHRwcm9jZXNzLnZlcnNpb25zID0ge307XG5cdFxuXHRmdW5jdGlvbiBub29wKCkge31cblx0XG5cdHByb2Nlc3Mub24gPSBub29wO1xuXHRwcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcblx0cHJvY2Vzcy5vbmNlID0gbm9vcDtcblx0cHJvY2Vzcy5vZmYgPSBub29wO1xuXHRwcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcblx0cHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xuXHRwcm9jZXNzLmVtaXQgPSBub29wO1xuXHRwcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5cdHByb2Nlc3MucHJlcGVuZE9uY2VMaXN0ZW5lciA9IG5vb3A7XG5cdFxuXHRwcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cdFxuXHRwcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuXHQgICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xuXHR9O1xuXHRcblx0cHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcblx0cHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcblx0ICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG5cdH07XG5cdHByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG5cblxuLyoqKi8gfSksXG4vKiA0NSAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHsgdmFyIHByb3AgPSBwcm9wc1trZXldOyBwcm9wLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChwcm9wLnZhbHVlKSBwcm9wLndyaXRhYmxlID0gdHJ1ZTsgfSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKTsgfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXHRcblx0dmFyIF9jbGFzc0NhbGxDaGVjayA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9O1xuXHRcblx0dmFyIGNsb2NrID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKS5jbG9jaztcblx0XG5cdHZhciBJbnRlcnZhbCA9IChmdW5jdGlvbiAoKSB7XG5cdCAgZnVuY3Rpb24gSW50ZXJ2YWwocmF0ZSwgZnVuYywgb24pIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBJbnRlcnZhbCk7XG5cdFxuXHQgICAgdGhpcy5yYXRlID0gcmF0ZTtcblx0ICAgIHRoaXMub24gPSBvbjtcblx0ICAgIHRoaXMuY2xvY2sgPSBjbG9jaygpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblx0XG5cdCAgICB0aGlzLnBhdHRlcm4gPSBbMV07XG5cdCAgICB0aGlzLmluZGV4ID0gMDtcblx0XG5cdCAgICB0aGlzLmV2ZW50ID0gZnVuYyA/IGZ1bmMgOiBmdW5jdGlvbiAoKSB7fTtcblx0XG5cdCAgICBpZiAodGhpcy5vbikge1xuXHQgICAgICB0aGlzLnN0YXJ0KCk7XG5cdCAgICB9XG5cdCAgfVxuXHRcblx0ICBfY3JlYXRlQ2xhc3MoSW50ZXJ2YWwsIHtcblx0ICAgIF9ldmVudDoge1xuXHQgICAgICB2YWx1ZTogZnVuY3Rpb24gX2V2ZW50KGUpIHtcblx0ICAgICAgICAvLyAgaWYgKHRoaXMucGF0dGVyblt0aGlzLmluZGV4JXRoaXMucGF0dGVybi5sZW5ndGhdKSB7XG5cdCAgICAgICAgdGhpcy5ldmVudChlKTtcblx0ICAgICAgICAvLyAgfVxuXHQgICAgICAgIHRoaXMuaW5kZXgrKztcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHN0b3A6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIHN0b3AoKSB7XG5cdCAgICAgICAgdGhpcy5vbiA9IGZhbHNlO1xuXHQgICAgICAgIHRoaXMuaW50ZXJ2YWwuY2xlYXIoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHN0YXJ0OiB7XG5cdCAgICAgIHZhbHVlOiBmdW5jdGlvbiBzdGFydCgpIHtcblx0ICAgICAgICB0aGlzLm9uID0gdHJ1ZTtcblx0ICAgICAgICB0aGlzLmludGVydmFsID0gdGhpcy5jbG9jay5jYWxsYmFja0F0VGltZSh0aGlzLl9ldmVudC5iaW5kKHRoaXMpLCB0aGlzLmNsb2NrLmNvbnRleHQuY3VycmVudFRpbWUpLnJlcGVhdCh0aGlzLnJhdGUgLyAxMDAwKS50b2xlcmFuY2UoeyBlYXJseTogMC4xLCBsYXRlOiAxIH0pO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgbXM6IHtcblx0ICAgICAgdmFsdWU6IGZ1bmN0aW9uIG1zKG5ld3JhdGUpIHtcblx0ICAgICAgICBpZiAodGhpcy5vbikge1xuXHQgICAgICAgICAgdmFyIHJhdGlvID0gbmV3cmF0ZSAvIHRoaXMucmF0ZTtcblx0ICAgICAgICAgIHRoaXMucmF0ZSA9IG5ld3JhdGU7XG5cdCAgICAgICAgICB0aGlzLmNsb2NrLnRpbWVTdHJldGNoKHRoaXMuY2xvY2suY29udGV4dC5jdXJyZW50VGltZSwgW3RoaXMuaW50ZXJ2YWxdLCByYXRpbyk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMucmF0ZSA9IG5ld3JhdGU7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSk7XG5cdFxuXHQgIHJldHVybiBJbnRlcnZhbDtcblx0fSkoKTtcblx0XG5cdG1vZHVsZS5leHBvcnRzID0gSW50ZXJ2YWw7XG5cbi8qKiovIH0pXG4vKioqKioqLyBdKVxufSk7XG47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbmRsWW5CaFkyczZMeTh2ZDJWaWNHRmpheTkxYm1sMlpYSnpZV3hOYjJSMWJHVkVaV1pwYm1sMGFXOXVJaXdpZDJWaWNHRmphem92THk5M1pXSndZV05yTDJKdmIzUnpkSEpoY0NCaU1qWTVZV05sWmpoallXUmhOekE0TkRVd01pSXNJbmRsWW5CaFkyczZMeTh2TGk5cGJtUmxlQzVxY3lJc0luZGxZbkJoWTJzNkx5OHZMaTlzYVdJdmJXRnBiaTVxY3lJc0luZGxZbkJoWTJzNkx5OHZMaTlzYVdJdmFXNTBaWEptWVdObGN5OXBibVJsZUM1cWN5SXNJbmRsWW5CaFkyczZMeTh2TGk5c2FXSXZhVzUwWlhKbVlXTmxjeTl3YjNOcGRHbHZiaTVxY3lJc0luZGxZbkJoWTJzNkx5OHZMaTlzYVdJdmRYUnBiQzl6ZG1jdWFuTWlMQ0ozWldKd1lXTnJPaTh2THk0dmJHbGlMM1YwYVd3dmJXRjBhQzVxY3lJc0luZGxZbkJoWTJzNkx5OHZMaTlzYVdJdlkyOXlaUzlwYm5SbGNtWmhZMlV1YW5NaUxDSjNaV0p3WVdOck9pOHZMeTR2YkdsaUwzVjBhV3d2Wkc5dExtcHpJaXdpZDJWaWNHRmphem92THk4dUwyeHBZaTkxZEdsc0wzVjBhV3d1YW5NaUxDSjNaV0p3WVdOck9pOHZMeTR2YkdsaUwzVjBhV3d2ZEc5MVkyZ3Vhbk1pTENKM1pXSndZV05yT2k4dkx5NHZmaTlsZG1WdWRITXZaWFpsYm5SekxtcHpJaXdpZDJWaWNHRmphem92THk4dUwyeHBZaTl0YjJSbGJITXZjM1JsY0M1cWN5SXNJbmRsWW5CaFkyczZMeTh2TGk5c2FXSXZkWFJwYkM5cGJuUmxjbUZqZEdsdmJpNXFjeUlzSW5kbFluQmhZMnM2THk4dkxpOXNhV0l2Ylc5a1pXeHpMM1J2WjJkc1pTNXFjeUlzSW5kbFluQmhZMnM2THk4dkxpOXNhV0l2YVc1MFpYSm1ZV05sY3k5emJHbGtaWEl1YW5NaUxDSjNaV0p3WVdOck9pOHZMeTR2YkdsaUwybHVkR1Z5Wm1GalpYTXZkRzluWjJ4bExtcHpJaXdpZDJWaWNHRmphem92THk4dUwyeHBZaTlwYm5SbGNtWmhZMlZ6TDJKMWRIUnZiaTVxY3lJc0luZGxZbkJoWTJzNkx5OHZMaTlzYVdJdlkyOXRjRzl1Wlc1MGN5OWlkWFIwYjI1MFpXMXdiR0YwWlM1cWN5SXNJbmRsWW5CaFkyczZMeTh2TGk5c2FXSXZhVzUwWlhKbVlXTmxjeTkwWlhoMFluVjBkRzl1TG1weklpd2lkMlZpY0dGamF6b3ZMeTh1TDJ4cFlpOXBiblJsY21aaFkyVnpMM0poWkdsdlluVjBkRzl1TG1weklpd2lkMlZpY0dGamF6b3ZMeTh1TDJ4cFlpOXBiblJsY21aaFkyVnpMMjUxYldKbGNpNXFjeUlzSW5kbFluQmhZMnM2THk4dkxpOXNhV0l2YVc1MFpYSm1ZV05sY3k5elpXeGxZM1F1YW5NaUxDSjNaV0p3WVdOck9pOHZMeTR2YkdsaUwybHVkR1Z5Wm1GalpYTXZaR2xoYkM1cWN5SXNJbmRsWW5CaFkyczZMeTh2TGk5c2FXSXZhVzUwWlhKbVlXTmxjeTl3YVdGdWJ5NXFjeUlzSW5kbFluQmhZMnM2THk4dkxpOXNhV0l2YVc1MFpYSm1ZV05sY3k5elpYRjFaVzVqWlhJdWFuTWlMQ0ozWldKd1lXTnJPaTh2THk0dmJHbGlMMjF2WkdWc2N5OXRZWFJ5YVhndWFuTWlMQ0ozWldKd1lXTnJPaTh2THk0dmJHbGlMMjF2WkdWc2N5OXpaWEYxWlc1alpTNXFjeUlzSW5kbFluQmhZMnM2THk4dkxpOXNhV0l2Ylc5a1pXeHpMMlJ5ZFc1ckxtcHpJaXdpZDJWaWNHRmphem92THk4dUwyeHBZaTl0YjJSbGJITXZZMjkxYm5SbGNpNXFjeUlzSW5kbFluQmhZMnM2THk4dkxpOXNhV0l2YVc1MFpYSm1ZV05sY3k5d1lXNHlaQzVxY3lJc0luZGxZbkJoWTJzNkx5OHZMaTlzYVdJdmFXNTBaWEptWVdObGN5OTBhV3gwTG1weklpd2lkMlZpY0dGamF6b3ZMeTh1TDJ4cFlpOXBiblJsY21aaFkyVnpMMjExYkhScGMyeHBaR1Z5TG1weklpd2lkMlZpY0dGamF6b3ZMeTh1TDJ4cFlpOWpiMjF3YjI1bGJuUnpMM05zYVdSbGNuUmxiWEJzWVhSbExtcHpJaXdpZDJWaWNHRmphem92THk4dUwyeHBZaTlwYm5SbGNtWmhZMlZ6TDNCaGJpNXFjeUlzSW5kbFluQmhZMnM2THk4dkxpOXNhV0l2YVc1MFpYSm1ZV05sY3k5bGJuWmxiRzl3WlM1cWN5SXNJbmRsWW5CaFkyczZMeTh2TGk5c2FXSXZhVzUwWlhKbVlXTmxjeTl6Y0dWamRISnZaM0poYlM1cWN5SXNJbmRsWW5CaFkyczZMeTh2TGk5c2FXSXZhVzUwWlhKbVlXTmxjeTl0WlhSbGNpNXFjeUlzSW5kbFluQmhZMnM2THk4dkxpOXNhV0l2YVc1MFpYSm1ZV05sY3k5dmMyTnBiR3h2YzJOdmNHVXVhbk1pTENKM1pXSndZV05yT2k4dkx5NHZiR2xpTDJOdmNtVXZjbUZqYXk1cWN5SXNJbmRsWW5CaFkyczZMeTh2TGk5c2FXSXZkWFJwYkM5MGNtRnVjMlp2Y20wdWFuTWlMQ0ozWldKd1lXTnJPaTh2THk0dmJHbGlMM1IxYm1sdVp5OTBkVzVwYm1jdWFuTWlMQ0ozWldKd1lXTnJPaTh2THk0dmJHbGlMMjF2WkdWc2N5OXlZV1JwYnk1cWN5SXNJbmRsWW5CaFkyczZMeTh2TGk5K0wzZGhZV05zYjJOckwybHVaR1Y0TG1weklpd2lkMlZpY0dGamF6b3ZMeTh1TDM0dmQyRmhZMnh2WTJzdmJHbGlMMWRCUVVOc2IyTnJMbXB6SWl3aWQyVmljR0ZqYXpvdkx5OHVMMzR2Y0hKdlkyVnpjeTlpY205M2MyVnlMbXB6SWl3aWQyVmljR0ZqYXpvdkx5OHVMMnhwWWk5MGFXMWxMMmx1ZEdWeWRtRnNMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUpCUVVGQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQkxFTkJRVU03UVVGRFJDeFBPMEZEVmtFN1FVRkRRVHM3UVVGRlFUdEJRVU5CT3p0QlFVVkJPMEZCUTBFN1FVRkRRVHM3UVVGRlFUdEJRVU5CTzBGQlEwRXNkVUpCUVdVN1FVRkRaanRCUVVOQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVRzN1FVRkZRVHRCUVVOQk96dEJRVVZCTzBGQlEwRTdRVUZEUVRzN08wRkJSMEU3UVVGRFFUczdRVUZGUVR0QlFVTkJPenRCUVVWQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVRzN096czdPenRCUTNSRFFTeGhRVUZaTEVOQlFVTTdPenM3UzBGRlRpeFBRVUZQTEhWRFFVRk5MRU5CUVZrN08ydENRVVZxUWl4UFFVRlBMRU03T3pzN096czdPenM3T3pzN096czdVME50U0U0c1RVRkJUU3hIUVVGT0xFMUJRVTA3VTBGSFRpeFBRVUZQTEVkQlFWQXNUMEZCVHp0VFFVZFFMRXRCUVVzc1IwRkJUQ3hMUVVGTE96czdPMEZCTjBoeVFpeGhRVUZaTEVOQlFVTTdPMHRCUlU0c1ZVRkJWU3gxUTBGQlRTeERRVUZsT3p0TFFVTXZRaXhKUVVGSkxIVkRRVUZOTEVOQlFXRTdPMHRCUTNaQ0xFbEJRVWtzZFVOQlFVMHNSVUZCWVRzN1MwRkRka0lzU1VGQlNTeDFRMEZCVFN4RlFVRnBRanM3UzBGRGRFSXNVMEZCVXl3clEwRkJUU3hGUVVGclFqczdRVUZGTjBNc1MwRkJTU3hQUVVGUExFZEJRVWNzYlVKQlFVOHNRMEZCUXl4RlFVRnJRaXhEUVVGRExFTkJRVU03UVVGRE1VTXNTMEZCU1N4TFFVRkxMRWRCUVVjc2JVSkJRVThzUTBGQlF5eEZRVUZuUWl4RFFVRkRMRU5CUVVNN1FVRkRkRU1zUzBGQlNTeExRVUZMTEVkQlFVY3NiVUpCUVU4c1EwRkJReXhGUVVGblFpeERRVUZETEVOQlFVTTdRVUZEZEVNc1MwRkJTU3hSUVVGUkxFZEJRVWNzYlVKQlFVOHNRMEZCUXl4RlFVRnRRaXhEUVVGRExFTkJRVU03UVVGRE5VTXNTMEZCU1N4TlFVRk5MRWRCUVVjc2JVSkJRVThzUTBGQlF5eEZRVUZwUWl4RFFVRkRMRU5CUVVNN08wdEJSV3BETEZGQlFWRXNkVU5CUVUwc1JVRkJWVHM3UzBGRGVFSXNVVUZCVVN4MVEwRkJUU3hGUVVGcFFqczdPenM3TzB0QlQyaERMRTlCUVU4N1FVRkZSU3haUVVaVUxFOUJRVThzUTBGRlJ5eFBRVUZQTEVWQlFVVTdNa0pCUm01Q0xFOUJRVTg3TzBGQlNVd3NWVUZCU3l4SlFVRkpMRWRCUVVjc1NVRkJTU3hWUVVGVkxFVkJRVVU3UVVGRGVFSXNWMEZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhIUVVGSExGVkJRVlVzUTBGQlF5eEhRVUZITEVOQlFVTXNRMEZCUXp0TlFVTXZRanM3UVVGRlJDeFZRVUZMTEVsQlFVa3NSMEZCUnl4SlFVRkpMRWxCUVVrc1JVRkJSVHRCUVVOc1FpeFhRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eERRVUZETzAxQlEzcENPenRCUVVWRUxGTkJRVWtzU1VGQlNTeEhRVUZITzBGQlExUXNZVUZCVVN4SlFVRkpPMDFCUTJJc1EwRkJRenM3UVVGRlJpeFRRVUZKTEUxQlFVMHNSMEZCUnp0QlFVTllMR2RDUVVGWExFOUJRVTg3UVVGRGJFSXNZMEZCVXl4TFFVRkxPMEZCUTJRc1kwRkJVeXhMUVVGTE8wRkJRMlFzYVVKQlFWa3NVVUZCVVR0QlFVTndRaXhsUVVGVkxFMUJRVTA3VFVGRGFrSXNRMEZCUXpzN1FVRkZSaXhWUVVGTExFbEJRVWtzUjBGQlJ5eEpRVUZKTEUxQlFVMHNSVUZCUlR0QlFVTjBRaXhYUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEVkQlFVY3NUVUZCVFN4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE8wMUJRM3BDT3p0QlFVVkVMRlZCUVVzc1NVRkJTU3hIUVVGSExFbEJRVWtzU1VGQlNTeEZRVUZGTzBGQlEzQkNMRmRCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zUjBGQlJ5eEpRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNN1RVRkRka0k3TzBGQlJVUXNVMEZCU1N4alFVRmpMRWRCUVVjc1RVRkJUU3hEUVVGRExGbEJRVmtzU1VGQlNTeE5RVUZOTEVOQlFVTXNhMEpCUVd0Q0xFTkJRVU03UVVGRGRFVXNVMEZCU1N4RFFVRkRMRkZCUVZFc1IwRkJSeXhQUVVGUExFbEJRVWtzU1VGQlNTeGpRVUZqTEVWQlFVVXNRMEZCUXpzN1FVRkZhRVFzVTBGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4SlFVRkpMRWxCUVVrc1JVRkJSU3hEUVVGRE8wRkJRM1pDTEZOQlFVa3NRMEZCUXl4SlFVRkpMRWRCUVVjc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUTBGQlF6czdRVUZGTTBNc1UwRkJTU3hEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEZGQlFWRXNRMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU03UVVGRGVrTXNVMEZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhMUVVGTExFVkJRVVVzUTBGQlF6dEJRVU51UWl4VFFVRkpMRU5CUVVNc1VVRkJVU3hIUVVGSExGRkJRVkVzUTBGQlF6czdRVUZGZWtJc1UwRkJTU3hEUVVGRExFMUJRVTBzUjBGQlJ6dEJRVU5hTEdGQlFVMHNSVUZCUlN4TlFVRk5PMEZCUTJRc1YwRkJTU3hGUVVGRkxFMUJRVTA3UVVGRFdpeFpRVUZMTEVWQlFVVXNUVUZCVFR0QlFVTmlMRmRCUVVrc1JVRkJSU3hOUVVGTk8wRkJRMW9zYTBKQlFWY3NSVUZCUlN4TlFVRk5PMEZCUTI1Q0xHbENRVUZWTEVWQlFVVXNUVUZCVFR0TlFVTnVRaXhEUVVGRE96dEJRVVZHTEZOQlFVa3NRMEZCUXl4VFFVRlRMRWRCUVVjc1UwRkJVeXhEUVVGRE8wRkJRek5DTEZOQlFVa3NRMEZCUXl4SFFVRkhMRWRCUVVjc1UwRkJVeXhEUVVGRExFZEJRVWNzUTBGQlF6czdRVUZIZWtJc1UwRkJTU3hEUVVGRExFZEJRVWNzUjBGQlJ5eEZRVUZGTEVOQlFVTTdRVUZEWkN4VlFVRkxMRWxCUVVrc1IwRkJSeXhKUVVGSkxGVkJRVlVzUlVGQlJUdEJRVU14UWl4WFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExFZEJRVWNzUTBGQlF5eEhRVUZITEZOQlFWTXNRMEZCUXl4SFFVRkhMRU5CUVVNc1NVRkJTU3hEUVVGRExFbEJRVWtzUlVGQlF5eEhRVUZITEVOQlFVTXNRMEZCUXp0TlFVTTVRenM3T3p0QlFVOUVMRk5CUVVrc2JVSkJRVzFDTEVkQlFVY3NVVUZCVVN4RFFVRkRMRzlDUVVGdlFpeERRVUZETEU5QlFVOHNRMEZCUXl4RFFVRkRPMEZCUTJwRkxGTkJRVWtzYzBKQlFYTkNMRWRCUVVjc2QwTkJRWGRETEVOQlFVTTdRVUZEZEVVc1UwRkJTU3huUWtGQlowSXNSMEZCUnl4UlFVRlJMRU5CUVVNc1lVRkJZU3hEUVVGRExFOUJRVThzUTBGQlF5eERRVUZETzBGQlEzWkVMSEZDUVVGblFpeERRVUZETEVsQlFVa3NSMEZCUnl4VlFVRlZMRU5CUVVNN1FVRkRia01zY1VKQlFXZENMRU5CUVVNc1UwRkJVeXhIUVVGSExITkNRVUZ6UWl4RFFVRkRPMEZCUTNCRUxGTkJRVWtzYlVKQlFXMUNMRU5CUVVNc1RVRkJUU3hIUVVGSExFTkJRVU1zUlVGQlJUdEJRVU5zUXl4WFFVRkpMRTFCUVUwc1IwRkJSeXh0UWtGQmJVSXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhWUVVGVk8wRkJRemxETEdGQlFVMHNRMEZCUXl4WlFVRlpMRU5CUVVVc1owSkJRV2RDTEVWQlFVVXNiVUpCUVcxQ0xFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdUVUZETDBRc1RVRkJUVHRCUVVOTUxHVkJRVkVzUTBGQlF5eExRVUZMTEVOQlFVTXNVMEZCVXl4SFFVRkRMSE5DUVVGelFpeEhRVUZETEZWQlFWY3NRMEZCUXl4RFFVRkRPMDFCUXpsRU96dEpRVWRLTzBGQlNFazdaMEpCTTBWSUxFOUJRVTg3UVVGdlJrd3NXVUZCVHp0WlFVcEJMRmxCUVVjN1FVRkRXaXhuUWtGQlR5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRPMUZCUTNSQ08xbEJSVlVzVlVGQlF5eEhRVUZITEVWQlFVVTdRVUZEWml4aFFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFbEJRVWtzUlVGQlJTeERRVUZETzBGQlEyeENMR0ZCUVVrc1EwRkJReXhSUVVGUkxFZEJRVWNzUjBGQlJ5eERRVUZETzBGQlEzQkNMR0ZCUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzU1VGQlNTeFJRVUZSTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRE8wRkJRM2hETEdGQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1MwRkJTeXhGUVVGRkxFTkJRVU03VVVGRGNFSTdPenM3VlVGNlJrTXNUMEZCVHpzN08wRkJLMFppTEV0QlFVa3NTMEZCU3l4SFFVRkhMRWxCUVVrc1QwRkJUeXhGUVVGRkxFTkJRVU03TzBGQlJXNUNMRlZCUVZNc1RVRkJUU3hIUVVGSE8wRkJRM0pDTEZWQlFVOHNTMEZCU3l4RFFVRkRMRTFCUVUwc1EwRkJRenRGUVVOMlFqczdRVUZEVFN4VlFVRlRMRTlCUVU4c1IwRkJSenRCUVVOMFFpeFZRVUZQTEV0QlFVc3NRMEZCUXl4UFFVRlBMRU5CUVVNN1JVRkRlRUk3TzBGQlEwMHNWVUZCVXl4TFFVRkxMRWRCUVVjN1FVRkRjRUlzVlVGQlR5eExRVUZMTEVOQlFVTXNTMEZCU3l4RFFVRkRPMFZCUTNSQ096dHpRa0ZGWXl4TFFVRkxMRU03T3pzN096czdPMnRDUTJwSlREdEJRVU5pTEZkQlFWRXNSVUZCUlN4dFFrRkJUeXhEUVVGRExFTkJRVmtzUTBGQlF6dEJRVU12UWl4VFFVRk5MRVZCUVVVc2JVSkJRVThzUTBGQlF5eEZRVUZWTEVOQlFVTTdRVUZETTBJc1UwRkJUU3hGUVVGRkxHMUNRVUZQTEVOQlFVTXNSVUZCVlN4RFFVRkRPenM3UVVGSE0wSXNVMEZCVFN4RlFVRkZMRzFDUVVGUExFTkJRVU1zUlVGQlZTeERRVUZETzBGQlF6TkNMR0ZCUVZVc1JVRkJSU3h0UWtGQlR5eERRVUZETEVWQlFXTXNRMEZCUXp0QlFVTnVReXhqUVVGWExFVkJRVVVzYlVKQlFVOHNRMEZCUXl4RlFVRmxMRU5CUVVNN1FVRkRja01zVTBGQlRTeEZRVUZGTEcxQ1FVRlBMRU5CUVVNc1JVRkJWU3hEUVVGRE8wRkJRek5DTEZOQlFVMHNSVUZCUlN4dFFrRkJUeXhEUVVGRExFVkJRVlVzUTBGQlF6dEJRVU16UWl4UFFVRkpMRVZCUVVVc2JVSkJRVThzUTBGQlF5eEZRVUZSTEVOQlFVTTdRVUZEZGtJc1VVRkJTeXhGUVVGRkxHMUNRVUZQTEVOQlFVTXNSVUZCVXl4RFFVRkRPMEZCUTNwQ0xGbEJRVk1zUlVGQlJTeHRRa0ZCVHl4RFFVRkRMRVZCUVdFc1EwRkJRenRCUVVOcVF5eFJRVUZMTEVWQlFVVXNiVUpCUVU4c1EwRkJReXhGUVVGVExFTkJRVU03UVVGRGVrSXNUMEZCU1N4RlFVRkZMRzFDUVVGUExFTkJRVU1zUlVGQlVTeERRVUZETzBGQlEzWkNMR05CUVZjc1JVRkJSU3h0UWtGQlR5eERRVUZETEVWQlFXVXNRMEZCUXp0QlFVTnlReXhOUVVGSExFVkJRVVVzYlVKQlFVOHNRMEZCUXl4RlFVRlBMRU5CUVVNN1FVRkRja0lzVjBGQlVTeEZRVUZGTEcxQ1FVRlBMRU5CUVVNc1JVRkJXU3hEUVVGRE8wRkJReTlDTEdOQlFWY3NSVUZCUlN4dFFrRkJUeXhEUVVGRExFVkJRV1VzUTBGQlF6dEJRVU55UXl4UlFVRkxMRVZCUVVVc2JVSkJRVThzUTBGQlF5eEZRVUZUTEVOQlFVTTdRVUZEZWtJc1pVRkJXU3hGUVVGRkxHMUNRVUZQTEVOQlFVTXNSVUZCWjBJc1EwRkJRenRGUVVONFF5eERPenM3T3pzN08wRkRja0pFTEdGQlFWa3NRMEZCUXpzN096czdPenM3T3pzN08wRkJSV0lzUzBGQlNTeEhRVUZITEVkQlFVY3NiVUpCUVU4c1EwRkJReXhEUVVGaExFTkJRVU1zUTBGQlF6dEJRVU5xUXl4TFFVRkpMRk5CUVZNc1IwRkJSeXh0UWtGQlR5eERRVUZETEVOQlFXMUNMRU5CUVVNc1EwRkJRenRCUVVNM1F5eExRVUZKTEVsQlFVa3NSMEZCUnl4dFFrRkJUeXhEUVVGRExFVkJRV2RDTEVOQlFVTXNRMEZCUXpzN1MwRkRla0lzVjBGQlZ5d3JRMEZCVFN4RlFVRnhRanM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3TzB0QmRVTTNRaXhSUVVGUk8wRkJSV2hDTEZsQlJsRXNVVUZCVVN4SFFVVmlPekpDUVVaTExGRkJRVkU3TzBGQlNYcENMRk5CUVVrc1QwRkJUeXhIUVVGSExFTkJRVU1zVDBGQlR5eERRVUZETEVOQlFVTTdPMEZCUlhoQ0xGTkJRVWtzVVVGQlVTeEhRVUZITzBGQlEySXNZVUZCVVN4RFFVRkRMRWRCUVVjc1JVRkJReXhIUVVGSExFTkJRVU03UVVGRGFrSXNZVUZCVVN4VlFVRlZPMEZCUTJ4Q0xHRkJRVkVzUTBGQlF6dEJRVU5VTEdGQlFWRXNRMEZCUXp0QlFVTlVMR05CUVZNc1EwRkJRenRCUVVOV0xGVkJRVXNzUjBGQlJ6dEJRVU5TTEdGQlFWRXNRMEZCUXp0QlFVTlVMR0ZCUVZFc1EwRkJRenRCUVVOVUxHTkJRVk1zUTBGQlF6dEJRVU5XTEZWQlFVc3NSMEZCUnp0TlFVTlVMRU5CUVVNN08wRkJSVVlzWjBOQmJrSnBRaXhSUVVGUkxEWkRRVzFDYmtJc1UwRkJVeXhGUVVGRExFOUJRVThzUlVGQlF5eFJRVUZSTEVWQlFVVTdPMEZCUjJ4RExGTkJRVWtzUTBGQlF5eEZRVUZGTEVkQlFVY3NTVUZCU1N4SlFVRkpMRU5CUVVVc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eEpRVUZKTEVWQlFVVXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhKUVVGSkxFVkJRVVVzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4TFFVRkxMRVZCUVVVc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVVXNRMEZCUXp0QlFVTnVSeXhUUVVGSkxFTkJRVU1zUlVGQlJTeEhRVUZITEVsQlFVa3NTVUZCU1N4RFFVRkZMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zU1VGQlNTeEZRVUZGTEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1NVRkJTU3hGUVVGRkxFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNTMEZCU3l4RlFVRkZMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF5eERRVUZGTEVOQlFVTTdPMEZCUlc1SExGTkJRVWtzUTBGQlF5eFJRVUZSTEVkQlFVYzdRVUZEWkN4UlFVRkRMRVZCUVVVc1NVRkJTU3hYUVVGWExFTkJRVU1zVFVGQlRTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1NVRkJTU3hGUVVGRExGbEJRVmtzUlVGQlF5eERRVUZETEVOQlFVTXNSVUZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFVkJRVU1zUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRM3BHTEZGQlFVTXNSVUZCUlN4SlFVRkpMRmRCUVZjc1EwRkJReXhOUVVGTkxFTkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4SlFVRkpMRVZCUVVNc1ZVRkJWU3hGUVVGRExFTkJRVU1zUTBGQlF5eEZRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1JVRkJReXhEUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1RVRkRlRVlzUTBGQlF6dEJRVU5HTEZOQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJReXhEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNSVUZCUlN4RFFVRkRMRlZCUVZVc1EwRkJRenRCUVVNelF5eFRRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNc1EwRkJReXhMUVVGTExFZEJRVWNzU1VGQlNTeERRVUZETEVWQlFVVXNRMEZCUXl4VlFVRlZMRU5CUVVNN08wRkJSVE5ETEZOQlFVa3NRMEZCUXl4SlFVRkpMRVZCUVVVc1EwRkJRenRCUVVOYUxGTkJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXp0SlFVVm1PenRoUVc1RGEwSXNVVUZCVVRzN1owSkJRVklzVVVGQlVUdEJRWEZETTBJc2JVSkJRV003WTBGQlFTd3dRa0ZCUnpzN1FVRkZaaXhoUVVGSkxFTkJRVU1zU1VGQlNTeEhRVUZITEVkQlFVY3NRMEZCUXl4TlFVRk5MRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU03UVVGRGFrTXNZVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhYUVVGWExFTkJRVU1zU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4RFFVRkRPMUZCUlhKRE96dEJRVVZFTEd0Q1FVRmhPMk5CUVVFc2VVSkJRVWM3TzBGQlJWb3NZVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRExFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTXNRMEZCUXl4RlFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUlVGQlF5eERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRVZCUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU4yUkN4aFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU1zUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXl4RFFVRkRMRVZCUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eEZRVUZETEVOQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZET3p0QlFVVjJSQ3hoUVVGSkxFTkJRVU1zWVVGQllTeEhRVUZITEVsQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUlVGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN08wRkJSWFJFTEdGQlFVa3NRMEZCUXl4VlFVRlZMRWRCUVVjN1FVRkRhRUlzWTBGQlJ5eEZRVUZGTEVWQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1lVRkJZU3hIUVVGRExFZEJRVWNzUTBGQlF5eEhRVUZITEVOQlFVTXNSMEZCUnl4RFFVRkRMRVZCUTNoRExFTkJRVU03UVVGRFJpeGhRVUZKTEVOQlFVTXNWVUZCVlN4RFFVRkRMRVZCUVVVc1IwRkJSeXhKUVVGSkxFTkJRVU1zVlVGQlZTeERRVUZETEVkQlFVY3NSMEZCUnl4RFFVRkRMRU5CUVVNN08wRkJSVGRETEdGQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1dVRkJXU3hEUVVGRExFbEJRVWtzUlVGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRekZETEdGQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1dVRkJXU3hEUVVGRExFbEJRVWtzUlVGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4SFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRek5ETEdGQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1dVRkJXU3hEUVVGRExFZEJRVWNzUlVGQlF5eEpRVUZKTEVOQlFVTXNWVUZCVlN4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE8xRkJRMjVFT3p0QlFVVkVMRzFDUVVGak8yTkJRVUVzTUVKQlFVYzdRVUZEWWl4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFdEJRVXNzUTBGQlF5eGxRVUZsTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhKUVVGSkxFTkJRVU03UVVGRGRFUXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhaUVVGWkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03VVVGRGRFUTdPMEZCUlVRc1YwRkJUVHRqUVVGQkxHdENRVUZITzBGQlExQXNZVUZCU1N4SlFVRkpMRU5CUVVNc1QwRkJUeXhGUVVGRk96dEJRVVZvUWl4bFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGbEJRVmtzUTBGQlF5eEhRVUZITEVWQlFVTXNTVUZCU1N4RFFVRkRMRlZCUVZVc1EwRkJReXhGUVVGRkxFTkJRVU1zUTBGQlF6dFZRVU5vUkN4TlFVRk5PenRCUVVWTUxHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWRCUVVjc1JVRkJReXhKUVVGSkxFTkJRVU1zVlVGQlZTeERRVUZETEVkQlFVY3NRMEZCUXl4RFFVRkRPMVZCUTJwRU96dEJRVVZFTEdGQlFVa3NRMEZCUXl4bFFVRmxMRWRCUVVjN1FVRkRja0lzV1VGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4RlFVRkZMRU5CUVVNc1ZVRkJWU3hIUVVGSExFbEJRVWtzUTBGQlF5eExRVUZMTzBGQlEyeERMRmxCUVVNc1JVRkJSU3hKUVVGSkxFTkJRVU1zVFVGQlRTeEhRVUZITEVsQlFVa3NRMEZCUXl4RlFVRkZMRU5CUVVNc1ZVRkJWU3hIUVVGSExFbEJRVWtzUTBGQlF5eE5RVUZOTzFWQlEyeEVMRU5CUVVNN08wRkJSVVlzWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hGUVVGRExFbEJRVWtzUTBGQlF5eGxRVUZsTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRjRVFzWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hGUVVGRExFbEJRVWtzUTBGQlF5eGxRVUZsTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1VVRkRja1E3TzBGQlIwUXNWVUZCU3p0alFVRkJMR2xDUVVGSE8wRkJRMDRzWVVGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRU5CUVVNc1RVRkJUU3hIUVVGSExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTTdRVUZEY0VNc1lVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVTXNUVUZCVFN4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU03UVVGRGNFTXNZVUZCU1N4RFFVRkRMRWxCUVVrc1JVRkJSU3hEUVVGRE8xRkJRMkk3TzBGQlJVUXNVMEZCU1R0alFVRkJMR2RDUVVGSE8wRkJRMHdzWVVGQlNTeEpRVUZKTEVOQlFVTXNUMEZCVHl4RlFVRkZPMEZCUTJoQ0xHVkJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXl4RFFVRkRMRTFCUVUwc1EwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZEYmtNc1pVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dEJRVU51UXl4bFFVRkpMRU5CUVVNc1JVRkJSU3hEUVVGRExGbEJRVmtzUTBGQlJTeEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNc1EwRkJReXhMUVVGTExFTkJRVVVzUTBGQlF6dEJRVU01UXl4bFFVRkpMRU5CUVVNc1JVRkJSU3hEUVVGRExGbEJRVmtzUTBGQlJTeEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNc1EwRkJReXhMUVVGTExFTkJRVVVzUTBGQlF6dEJRVU01UXl4bFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUlVGQlF6dEJRVU5xUWl4alFVRkRMRVZCUVVVc1NVRkJTU3hEUVVGRExFVkJRVVVzUTBGQlF5eExRVUZMTzBGQlEyaENMR05CUVVNc1JVRkJSU3hKUVVGSkxFTkJRVU1zUlVGQlJTeERRVUZETEV0QlFVczdXVUZEYWtJc1EwRkJReXhEUVVGRE8wRkJRMGdzWlVGQlNTeERRVUZETEUxQlFVMHNSVUZCUlN4RFFVRkRPMVZCUTJZN1VVRkRSanM3UVVGRlJDeFpRVUZQTzJOQlFVRXNiVUpCUVVjN1FVRkRVaXhoUVVGSkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVOQlFVTTdVVUZEWmpzN1FVRlpSeXhOUVVGRE96czdPenM3T3p0WlFVcEJMRmxCUVVjN1FVRkRUaXhuUWtGQlR5eEpRVUZKTEVOQlFVTXNSVUZCUlN4RFFVRkRMRXRCUVVzc1EwRkJRenRSUVVOMFFqdFpRVVZKTEZWQlFVTXNTMEZCU3l4RlFVRkZPMEZCUTFnc1lVRkJTU3hEUVVGRExFVkJRVVVzUTBGQlF5eE5RVUZOTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1FVRkRkRUlzWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRVZCUVVNN1FVRkRha0lzV1VGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4RlFVRkZMRU5CUVVNc1MwRkJTenRCUVVOb1FpeFpRVUZETEVWQlFVVXNTVUZCU1N4RFFVRkRMRVZCUVVVc1EwRkJReXhMUVVGTE8xVkJRMnBDTEVOQlFVTXNRMEZCUXp0QlFVTklMR0ZCUVVrc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF6dFJRVU5tT3p0QlFWbEhMRTFCUVVNN096czdPenM3TzFsQlNrRXNXVUZCUnp0QlFVTk9MR2RDUVVGUExFbEJRVWtzUTBGQlF5eEZRVUZGTEVOQlFVTXNTMEZCU3l4RFFVRkRPMUZCUTNSQ08xbEJSVWtzVlVGQlF5eExRVUZMTEVWQlFVVTdRVUZEV0N4aFFVRkpMRU5CUVVNc1JVRkJSU3hEUVVGRExFMUJRVTBzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0QlFVTjBRaXhoUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNSVUZCUXp0QlFVTnFRaXhaUVVGRExFVkJRVVVzU1VGQlNTeERRVUZETEVWQlFVVXNRMEZCUXl4TFFVRkxPMEZCUTJoQ0xGbEJRVU1zUlVGQlJTeEpRVUZKTEVOQlFVTXNSVUZCUlN4RFFVRkRMRXRCUVVzN1ZVRkRha0lzUTBGQlF5eERRVUZETzBGQlEwZ3NZVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE8xRkJRMlk3TzBGQlNVY3NaVUZCVlR0WlFVRkJMRmxCUVVjN1FVRkRaaXhuUWtGQlR6dEJRVU5NTEZsQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1JVRkJSU3hEUVVGRExGVkJRVlU3UVVGRGNrSXNXVUZCUXl4RlFVRkZMRWxCUVVrc1EwRkJReXhGUVVGRkxFTkJRVU1zVlVGQlZUdFZRVU4wUWl4RFFVRkRPMUZCUTBnN08wRkJWVWNzVTBGQlNUczdPenM3T3p0WlFVcEJMRmxCUVVjN1FVRkRWQ3huUWtGQlR5eEpRVUZKTEVOQlFVTXNSVUZCUlN4RFFVRkRMRWRCUVVjc1EwRkJRenRSUVVOd1FqdFpRVVZQTEZWQlFVTXNRMEZCUXl4RlFVRkZPMEZCUTFZc1lVRkJTU3hEUVVGRExFVkJRVVVzUTBGQlF5eEhRVUZITEVkQlFVY3NRMEZCUXl4RFFVRkRPMEZCUTJoQ0xHRkJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXp0UlFVTm1PenRCUVZWSExGTkJRVWs3T3pzN096czdXVUZLUVN4WlFVRkhPMEZCUTFRc1owSkJRVThzU1VGQlNTeERRVUZETEVWQlFVVXNRMEZCUXl4SFFVRkhMRU5CUVVNN1VVRkRjRUk3V1VGRlR5eFZRVUZETEVOQlFVTXNSVUZCUlR0QlFVTldMR0ZCUVVrc1EwRkJReXhGUVVGRkxFTkJRVU1zUjBGQlJ5eEhRVUZITEVOQlFVTXNRMEZCUXp0QlFVTm9RaXhoUVVGSkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVOQlFVTTdVVUZEWmpzN1FVRlhSeXhUUVVGSk96czdPenM3TzFsQlNrRXNXVUZCUnp0QlFVTlVMR2RDUVVGUExFbEJRVWtzUTBGQlF5eEZRVUZGTEVOQlFVTXNSMEZCUnl4RFFVRkRPMUZCUTNCQ08xbEJSVThzVlVGQlF5eERRVUZETEVWQlFVVTdRVUZEVml4aFFVRkpMRU5CUVVNc1JVRkJSU3hEUVVGRExFZEJRVWNzUjBGQlJ5eERRVUZETEVOQlFVTTdRVUZEYUVJc1lVRkJTU3hEUVVGRExFMUJRVTBzUlVGQlJTeERRVUZETzFGQlEyWTdPMEZCVjBjc1UwRkJTVHM3T3pzN096dFpRVXBCTEZsQlFVYzdRVUZEVkN4blFrRkJUeXhKUVVGSkxFTkJRVU1zUlVGQlJTeERRVUZETEVkQlFVY3NRMEZCUXp0UlFVTndRanRaUVVWUExGVkJRVU1zUTBGQlF5eEZRVUZGTzBGQlExWXNZVUZCU1N4RFFVRkRMRVZCUVVVc1EwRkJReXhIUVVGSExFZEJRVWNzUTBGQlF5eERRVUZETzBGQlEyaENMR0ZCUVVrc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF6dFJRVU5tT3p0QlFWZEhMRlZCUVVzN096czdPenM3V1VGS1FTeFpRVUZITzBGQlExWXNaMEpCUVU4c1NVRkJTU3hEUVVGRExFVkJRVVVzUTBGQlF5eEpRVUZKTEVOQlFVTTdVVUZEY2tJN1dVRkZVU3hWUVVGRExFTkJRVU1zUlVGQlJUdEJRVU5ZTEdGQlFVa3NRMEZCUXl4RlFVRkZMRU5CUVVNc1NVRkJTU3hIUVVGSExFTkJRVU1zUTBGQlF6dEJRVU5xUWl4aFFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRkxFTkJRVU03VVVGRFpqczdRVUZYUnl4VlFVRkxPenM3T3pzN08xbEJTa0VzV1VGQlJ6dEJRVU5XTEdkQ1FVRlBMRWxCUVVrc1EwRkJReXhGUVVGRkxFTkJRVU1zU1VGQlNTeERRVUZETzFGQlEzSkNPMWxCUlZFc1ZVRkJReXhEUVVGRExFVkJRVVU3UVVGRFdDeGhRVUZKTEVOQlFVTXNSVUZCUlN4RFFVRkRMRWxCUVVrc1IwRkJSeXhEUVVGRExFTkJRVU03UVVGRGFrSXNZVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE8xRkJRMlk3TzBGQlYwY3NVMEZCU1RzN096czdPenM3V1VGSVFTeFpRVUZITzBGQlExUXNaMEpCUVU4c1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVTXNTVUZCU1N4RFFVRkRPMUZCUXpkQ08xbEJRMDhzVlVGQlF5eERRVUZETEVWQlFVVTdRVUZEVml4aFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU1zUTBGQlF5eEpRVUZKTEVkQlFVY3NRMEZCUXl4RFFVRkRPMEZCUTNwQ0xHRkJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXl4RFFVRkRMRWxCUVVrc1IwRkJSeXhEUVVGRExFTkJRVU03VVVGRE1VSTdPenM3VlVFeFVHdENMRkZCUVZFN1NVRkJVeXhUUVVGVE96dHJRa0ZCTVVJc1VVRkJVU3hET3pzN096czdRVU0zUXpkQ0xHRkJRVmtzUTBGQlF6czdRVUZGWWl4TFFVRkpMRWxCUVVrc1IwRkJSeXh0UWtGQlR5eERRVUZETEVOQlFXTXNRMEZCUXl4RFFVRkRPenRyUWtGRmNFSTdPMEZCUldJc1UwRkJUU3hGUVVGRkxGVkJRVU1zU1VGQlNTeEZRVUZMTzBGQlEyaENMRmxCUVU4c1VVRkJVU3hEUVVGRExHVkJRV1VzUTBGQlF5dzBRa0ZCTkVJc1JVRkJSU3hKUVVGSkxFTkJRVU1zUTBGQlF6dEpRVU55UlRzN1FVRkZSQ3hOUVVGSExFVkJRVVVzVlVGQlF5eERRVUZETEVWQlFVVXNRMEZCUXl4RlFVRkZMRTFCUVUwc1JVRkJSU3hWUVVGVkxFVkJRVVVzVVVGQlVTeEZRVUZMT3p0QlFVVXpReXhUUVVGSkxFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNWMEZCVnl4RFFVRkRMRTFCUVUwc1JVRkJSU3hSUVVGUkxFTkJRVU1zUTBGQlF6dEJRVU12UXl4VFFVRkpMRWRCUVVjc1IwRkJSeXhKUVVGSkxFTkJRVU1zVjBGQlZ5eERRVUZETEUxQlFVMHNSVUZCUlN4VlFVRlZMRU5CUVVNc1EwRkJRenM3UVVGRkwwTXNVMEZCU1N4WlFVRlpMRWRCUVVjc1VVRkJVU3hIUVVGSExGVkJRVlVzU1VGQlNTeEhRVUZITEVkQlFVY3NSMEZCUnl4SFFVRkhMRWRCUVVjc1EwRkJRenM3UVVGRk5VUXNVMEZCU1N4RFFVRkRMRWRCUVVjc1EwRkRTaXhIUVVGSExFVkJRVVVzUzBGQlN5eERRVUZETEVOQlFVTXNSMEZCUXl4RFFVRkRMRVZCUVVVc1MwRkJTeXhEUVVGRExFTkJRVU1zUjBGQlF5eERRVUZETEVWQlEzcENMRWRCUVVjc1JVRkJSU3hOUVVGTkxFVkJRVVVzVFVGQlRTeEZRVUZGTEVOQlFVTXNSVUZCUlN4WlFVRlpMRVZCUVVVc1EwRkJReXhGUVVGRkxFZEJRVWNzUTBGQlF5eERRVUZETEVkQlFVTXNRMEZCUXl4RlFVRkZMRWRCUVVjc1EwRkJReXhEUVVGRExFZEJRVU1zUTBGQlF5eERRVU0xUkN4RFFVRkRMRWxCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zUTBGQlF6czdRVUZGV2l4WlFVRlBMRU5CUVVNc1EwRkJRenRKUVVOV096dEJRVVZFTEdsQ1FVRmpMRVZCUVVVc1ZVRkJReXhKUVVGSkxFVkJRVU1zWVVGQllTeEZRVUZMT3p0QlFVVjBReXhUUVVGSkxFVkJRVVVzUjBGQlJ5eFZRVUZWTEVkQlFVY3NTVUZCU1N4RFFVRkRMRVZCUVVVc1EwRkJReXhaUVVGWkxFTkJRVU1zUTBGQlF6dEJRVU0xUXl4VFFVRkpMRXRCUVVzc1IwRkJSeXhGUVVGRkxFTkJRVU03TzBGQlJXWXNVMEZCU1N4UlFVRlJMRWRCUVVjc1VVRkJVU3hEUVVGRExHVkJRV1VzUTBGQlF5dzBRa0ZCTkVJc1JVRkJSU3huUWtGQlowSXNRMEZCUXl4RFFVRkRPMEZCUTNoR0xHRkJRVkVzUTBGQlF5eFpRVUZaTEVOQlFVTXNTVUZCU1N4RlFVRkZMRVZCUVVVc1EwRkJReXhEUVVGRE8wRkJRMmhETEdGQlFWRXNRMEZCUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hGUVVGRkxFdEJRVXNzUTBGQlF5eERRVUZETzBGQlEyNURMR0ZCUVZFc1EwRkJReXhaUVVGWkxFTkJRVU1zU1VGQlNTeEZRVUZGTEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTI1RExHRkJRVkVzUTBGQlF5eFpRVUZaTEVOQlFVTXNSMEZCUnl4RlFVRkZMRXRCUVVzc1EwRkJReXhEUVVGRE96dEJRVVZzUXl4VFFVRkpMRU5CUVVNc1YwRkJWeXhEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZET3p0QlFVVXpRaXhWUVVGTExFbEJRVWtzUTBGQlF5eEhRVUZETEVOQlFVTXNSVUZCUXl4RFFVRkRMRWRCUVVNc1lVRkJZU3hGUVVGRExFTkJRVU1zUlVGQlJTeEZRVUZGTzBGQlEyaERMRmRCUVVrc1MwRkJTU3hIUVVGSExGRkJRVkVzUTBGQlF5eGxRVUZsTEVOQlFVTXNORUpCUVRSQ0xFVkJRVVVzVFVGQlRTeERRVUZETEVOQlFVTTdRVUZETVVVc1dVRkJTU3hEUVVGRExGbEJRVmtzUTBGQlF5eEpRVUZKTEVWQlFVVXNUVUZCVFN4SFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE96czdRVUZIYkVNc1pVRkJVU3hEUVVGRExGZEJRVmNzUTBGQlF5eExRVUZKTEVOQlFVTXNRMEZCUXp0QlFVTXpRaXhaUVVGTExFTkJRVU1zU1VGQlNTeERRVUZETEV0QlFVa3NRMEZCUXl4RFFVRkRPMDFCUTJ4Q096dEJRVVZFTEZsQlFVODdRVUZEVEN4VFFVRkZMRVZCUVVVc1JVRkJSVHRCUVVOT0xGbEJRVXNzUlVGQlJTeExRVUZMTzBGQlExb3NZMEZCVHl4RlFVRkZMRkZCUVZFN1RVRkRiRUlzUTBGQlF6dEpRVVZJT3p0RlFVVkdMRU03T3pzN096dEJRM1pFUkN4aFFVRlpMRU5CUVVNN096czdPenM3T3pzN096czdPMEZCWTJJc1VVRkJUeXhEUVVGRExFbEJRVWtzUjBGQlJ5eFZRVUZETEV0QlFVc3NSVUZCUXl4SFFVRkhMRVZCUVVNc1IwRkJSeXhGUVVGTE8wRkJRMmhETEZWQlFVOHNTVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhKUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEV0QlFVc3NSVUZCUXl4SFFVRkhMRU5CUVVNc1JVRkJReXhIUVVGSExFTkJRVU1zUTBGQlF6dEZRVU14UXl4RFFVRkRPenRCUVVWR0xGRkJRVThzUTBGQlF5eFRRVUZUTEVkQlFVY3NWVUZCUXl4TFFVRkxMRVZCUVVNc1IwRkJSeXhGUVVGRExFZEJRVWNzUlVGQlN6dEJRVU55UXl4VlFVRlRMRU5CUVVNc1MwRkJTeXhIUVVGRExFZEJRVWNzUzBGQlN5eEhRVUZITEVkQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVjN1JVRkRjRU1zUTBGQlF6czdPenM3T3pzN096czdPenM3UVVGalJpeFJRVUZQTEVOQlFVTXNTMEZCU3l4SFFVRkhMRlZCUVVNc1MwRkJTeXhGUVVGRkxFdEJRVXNzUlVGQlJTeExRVUZMTEVWQlFVVXNUVUZCVFN4RlFVRkZMRTFCUVUwc1JVRkJTenRCUVVOMlJDeFBRVUZKTEV0QlFVc3NTMEZCU3l4TFFVRkxMRVZCUVVVN1FVRkRia0lzV1VGQlR5eE5RVUZOTEVOQlFVTTdTVUZEWmp0QlFVTkVMRlZCUVZNc1EwRkJReXhMUVVGTExFZEJRVWNzUzBGQlN5eExRVUZMTEUxQlFVMHNSMEZCUnl4TlFVRk5MRU5CUVVNc1NVRkJTeXhMUVVGTExFZEJRVWNzUzBGQlN5eERRVUZETEVkQlFVa3NUVUZCVFN4RFFVRkRPMFZCUXpORkxFTkJRVU03TzBGQlJVWXNVVUZCVHl4RFFVRkRMRTlCUVU4c1IwRkJSeXhWUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVWQlFVczdRVUZEZWtJc1QwRkJTU3hEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4RFFVRkRMRWRCUVVNc1EwRkJReXhIUVVGSExFTkJRVU1zUjBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXpzN1FVRkZOMElzVDBGQlNTeExRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRExFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZETlVJc1QwRkJTU3hMUVVGTExFZEJRVWNzUTBGQlF5eEZRVUZGTzBGQlEySXNWVUZCU3l4SFFVRkhMRXRCUVVzc1IwRkJTU3hEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETEVWQlFVY3NRMEZCUXp0SlFVTXZRanRCUVVORUxGVkJRVThzUlVGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXl4RlFVRkZMRXRCUVVzc1JVRkJSU3hMUVVGTExFVkJRVU1zUTBGQlF6dEZRVU5zUXl4RFFVRkRPenRCUVVWR0xGRkJRVThzUTBGQlF5eFhRVUZYTEVkQlFVY3NWVUZCVXl4TlFVRk5MRVZCUVVVc1MwRkJTeXhGUVVGRE8wRkJRek5ETEU5QlFVa3NSMEZCUnl4SFFVRkhMRWxCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZETVVJc1QwRkJTU3hIUVVGSExFZEJRVWNzU1VGQlNTeERRVUZETEVkQlFVY3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenRCUVVNeFFpeFZRVUZQTEVWQlFVTXNRMEZCUXl4RlFVRkZMRTFCUVUwc1IwRkJReXhIUVVGSExFVkJRVVVzUTBGQlF5eEZRVUZGTEUxQlFVMHNSMEZCUXl4SFFVRkhMRWRCUVVNc1EwRkJReXhEUVVGRExFVkJRVU1zUTBGQlF6dEZRVU14UXl4RFFVRkRPenM3T3pzN096czdPenRCUVdGR0xGRkJRVThzUTBGQlF5eExRVUZMTEVkQlFVY3NWVUZCVXl4SlFVRkpMRVZCUVVVc1MwRkJTeXhGUVVGRk8wRkJRM0JETEZWQlFVOHNWVUZCVlN4RFFVRkRMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTXNRMEZCUXp0RlFVTjRReXhEUVVGRE96dEJRVVZHTEZGQlFVOHNRMEZCUXl4TlFVRk5MRWRCUVVjc1ZVRkJWU3hMUVVGTExFVkJRVVU3UVVGRGFFTXNWVUZCVHl4UFFVRlBMRU5CUVVNc1MwRkJTeXhEUVVGRExFdEJRVXNzUlVGQlJTeERRVUZETEVWQlFVVXNRMEZCUXl4RlFVRkZMRU5CUVVNc1JVRkJSU3hEUVVGRExFTkJRVU1zUTBGQlF6dEZRVU42UXl4RFFVRkRPenM3T3pzN096czdRVUZUUml4UlFVRlBMRU5CUVVNc1NVRkJTU3hIUVVGSExGVkJRVk1zU1VGQlNTeEZRVUZGTzBGQlF6VkNMRlZCUVU4c1NVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eERRVUZETEVWQlFVY3NRMEZCUXl4SlFVRkpMRWRCUVVNc1JVRkJSU3hKUVVGRkxFVkJRVVVzUTBGQlJTeEhRVUZITEVkQlFVY3NRMEZCUXp0RlFVTXhReXhEUVVGRE96czdPenM3T3pzN096czdRVUZaUml4UlFVRlBMRU5CUVVNc1RVRkJUU3hIUVVGSExGVkJRVk1zUjBGQlJ5eEZRVUZETEVkQlFVY3NSVUZCUXl4SFFVRkhMRVZCUVVVN1FVRkRja01zVlVGQlR5eEhRVUZITEVsQlFVa3NSMEZCUnl4SFFVRkhMRWRCUVVjc1EwRkJReXhIUVVGSExFZEJRVWNzUTBGQlF6dEZRVU5vUXl4RFFVRkRPenM3T3pzN096czdRVUZUUml4UlFVRlBMRU5CUVVNc1NVRkJTU3hIUVVGSExGbEJRVmM3UVVGRGVFSXNWVUZCVHl4VFFVRlRMRU5CUVVNc1JVRkJReXhGUVVGRkxFbEJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVXNSMEZCUXl4VFFVRlRMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU1zUTBGQlF6dEZRVU4wUkN4RFFVRkRPenM3T3pzN096czdPenM3UVVGWlJpeFJRVUZQTEVOQlFVTXNUVUZCVFN4SFFVRkhMRlZCUVZNc1IwRkJSeXhGUVVGRk8wRkJRemRDTEZWQlFVOHNTVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRExFVkJRVU1zUjBGQlJ5eERRVUZETEVOQlFVTTdSVUZEZUVJc1EwRkJRenM3T3pzN096czdPenM3UVVGWFJpeFJRVUZQTEVOQlFVTXNSVUZCUlN4SFFVRkhMRlZCUVZNc1RVRkJUU3hGUVVGRExFMUJRVTBzUlVGQlJUdEJRVU51UXl4UFFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRk8wRkJRMWdzVjBGQlRTeEhRVUZITEUxQlFVMHNRMEZCUXp0QlFVTm9RaXhYUVVGTkxFZEJRVWNzUTBGQlF5eERRVUZETzBsQlExbzdRVUZEUkN4UFFVRkpMRWRCUVVjc1IwRkJSeXhKUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEUxQlFVMHNSVUZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVOc1F5eFBRVUZKTEVsQlFVa3NSMEZCUnl4SlFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExFMUJRVTBzUlVGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0QlFVTnVReXhWUVVGUExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hKUVVGRkxFbEJRVWtzUjBGQlF5eEhRVUZITEVOQlFVTXNSMEZCUXl4SFFVRkhMRU5CUVVNc1EwRkJRenRGUVVOcVJDeERRVUZET3pzN096czdPenM3T3p0QlFWZEdMRkZCUVU4c1EwRkJReXhGUVVGRkxFZEJRVWNzVlVGQlV5eE5RVUZOTEVWQlFVTXNUVUZCVFN4RlFVRkZPMEZCUTI1RExFOUJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVTdRVUZEV0N4WFFVRk5MRWRCUVVjc1RVRkJUU3hEUVVGRE8wRkJRMmhDTEZkQlFVMHNSMEZCUnl4RFFVRkRMRU5CUVVNN1NVRkRXanRCUVVORUxFOUJRVWtzUjBGQlJ5eEhRVUZITEVsQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1RVRkJUU3hGUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETzBGQlEyeERMRTlCUVVrc1NVRkJTU3hIUVVGSExFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNUVUZCVFN4RlFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRE8wRkJRMjVETEZWQlFVOHNTVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hKUVVGRkxFbEJRVWtzUjBGQlF5eEhRVUZITEVOQlFVTXNSMEZCUXl4SFFVRkhMRU5CUVVNN1JVRkRja01zUTBGQlF6czdRVUZIUml4UlFVRlBMRU5CUVVNc1MwRkJTeXhIUVVGSExGVkJRVk1zUzBGQlN5eEZRVUZETEVkQlFVY3NSVUZCUXl4SFFVRkhMRVZCUVVVN1FVRkRkRU1zVVVGQlN5eEZRVUZGTEVOQlFVTTdRVUZEVWl4UFFVRkpMRXRCUVVzc1NVRkJTU3hIUVVGSExFVkJRVVU3UVVGRGFFSXNWVUZCU3l4SFFVRkhMRWRCUVVjc1EwRkJRenRKUVVOaU8wRkJRMFFzVlVGQlR5eExRVUZMTEVOQlFVTTdSVUZEWkN4RFFVRkRPenM3T3pzN096czdRVUZUUml4UlFVRlBMRU5CUVVNc1QwRkJUeXhIUVVGSExGVkJRVk1zU1VGQlNTeEZRVUZGTzBGQlF5OUNMRTlCUVVrc1MwRkJTeXhIUVVGSExFTkJRVU1zUTBGQlF6dEJRVU5rTEZGQlFVc3NTVUZCU1N4RFFVRkRMRWRCUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUjBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkRMRU5CUVVNc1JVRkJSU3hGUVVGRk8wRkJRemxDTEZWQlFVc3NTVUZCU1N4SlFVRkpMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU03U1VGRGJFSTdRVUZEUkN4VlFVRlBMRXRCUVVzc1IwRkJSeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETzBWQlF6VkNMRU5CUVVNN096czdPenM3T3pzN096dEJRVmxHTEZGQlFVOHNRMEZCUXl4UlFVRlJMRWRCUVVjc1ZVRkJVeXhGUVVGRkxFVkJRVU1zUlVGQlJTeEZRVUZETEVWQlFVVXNSVUZCUXl4RlFVRkZMRVZCUVVVN1FVRkRka01zVDBGQlNTeERRVUZETEVkQlFVY3NSVUZCUlN4SFFVRkhMRVZCUVVVc1EwRkJRenRCUVVOb1FpeFBRVUZKTEVOQlFVTXNSMEZCUnl4RlFVRkZMRWRCUVVjc1JVRkJSU3hEUVVGRE8wRkJRMmhDTEZWQlFVOHNTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJSU3hEUVVGRExFZEJRVU1zUTBGQlF5eEhRVUZITEVOQlFVTXNSMEZCUXl4RFFVRkRMRU5CUVVVc1EwRkJRenRGUVVNdlFpeERRVUZET3p0QlFVVkdMRkZCUVU4c1EwRkJReXhSUVVGUkxFZEJRVWNzVlVGQlV5eEpRVUZKTEVWQlFVVTdRVUZEYUVNc1ZVRkJUeXhGUVVGRkxFZEJRVWNzU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4SlFVRkpMRU5CUVVNc1EwRkJRenRGUVVNNVFpeERRVUZET3pzN096czdPenM3UVVGVFJpeFJRVUZQTEVOQlFVTXNTVUZCU1N4SFFVRkhMRmxCUVcxQ08wOUJRVllzU1VGQlNTeG5RMEZCUXl4SFFVRkhPenRCUVVNNVFpeFBRVUZKTEU5QlFVOHNRMEZCUXl4RlFVRkZMRU5CUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUTBGQlF5eEhRVUZITEVsQlFVa3NSVUZCUlR0QlFVTXhRaXhaUVVGUExFTkJRVU1zUTBGQlF6dEpRVU5XTEUxQlFVMDdRVUZEVEN4WlFVRlBMRU5CUVVNc1EwRkJRenRKUVVOV08wVkJRMFlzUXpzN096czdPMEZETjA1RUxHRkJRVmtzUTBGQlF6czdPenM3T3pzN096dEJRVVZpTEV0QlFVa3NSMEZCUnl4SFFVRkhMRzFDUVVGUExFTkJRVU1zUTBGQllTeERRVUZETEVOQlFVTTdRVUZEYWtNc1MwRkJTU3hIUVVGSExFZEJRVWNzYlVKQlFVOHNRMEZCUXl4RFFVRmhMRU5CUVVNc1EwRkJRenRCUVVOcVF5eExRVUZKTEVsQlFVa3NSMEZCUnl4dFFrRkJUeXhEUVVGRExFTkJRV01zUTBGQlF5eERRVUZETzBGQlEyNURMRXRCUVVrc1MwRkJTeXhIUVVGSExHMUNRVUZQTEVOQlFVTXNRMEZCWlN4RFFVRkRMRU5CUVVNN1FVRkRja01zUzBGQlRTeFpRVUZaTEVkQlFVY3NiVUpCUVU4c1EwRkJReXhGUVVGUkxFTkJRVU1zUTBGQlF6czdTMEZGT1VJc1RVRkJUU3gxUWtGQlVTeERRVUZUTEVWQlFYWkNMRTFCUVUwN096czdPenRMUVV0TkxGTkJRVk03UVVGRmFrSXNXVUZHVVN4VFFVRlRMRU5CUldoQ0xFbEJRVWtzUlVGQlF5eFBRVUZQTEVWQlFVTXNVVUZCVVN4RlFVRkZPekpDUVVab1FpeFRRVUZUT3p0QlFVY3hRaXhuUTBGSWFVSXNVMEZCVXl3MlEwRkhiRUk3UVVGRFVpeFRRVUZKTEVOQlFVTXNTVUZCU1N4SFFVRkhMRWxCUVVrc1EwRkJReXhYUVVGWExFTkJRVU1zU1VGQlNTeERRVUZETzBGQlEyeERMRk5CUVVrc1EwRkJReXhSUVVGUkxFZEJRVWNzU1VGQlNTeERRVUZETEdGQlFXRXNRMEZCUXl4SlFVRkpMRVZCUVVNc1QwRkJUeXhGUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETzBGQlF6RkVMRk5CUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzUlVGQlJTeERRVUZETzBGQlEyaENMRk5CUVVrc1EwRkJReXhKUVVGSkxFZEJRVWNzUzBGQlN5eERRVUZETzBGQlEyeENMRk5CUVVrc1EwRkJReXhOUVVGTkxFZEJRVWNzUlVGQlJTeERRVUZETzBGQlEycENMRk5CUVVrc1lVRkJZU3hIUVVGSExFMUJRVTBzUlVGQlJTeERRVUZETzBGQlF6ZENMRk5CUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVFVGQlRTeEhRVUZITEdGQlFXRXNRMEZCUXl4TlFVRk5MRU5CUVVNN1FVRkRNVU1zVTBGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SlFVRkpMRWRCUVVjc1lVRkJZU3hEUVVGRExFbEJRVWtzUTBGQlF6dEJRVU4wUXl4VFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFdEJRVXNzUjBGQlJ5eGhRVUZoTEVOQlFVTXNTMEZCU3l4RFFVRkRPMEZCUTNoRExGTkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTVUZCU1N4SFFVRkhMR0ZCUVdFc1EwRkJReXhKUVVGSkxFTkJRVU03UVVGRGRFTXNVMEZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhYUVVGWExFZEJRVWNzWVVGQllTeERRVUZETEZkQlFWY3NRMEZCUXp0QlFVTndSQ3hUUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEZWQlFWVXNSMEZCUnl4aFFVRmhMRU5CUVVNc1ZVRkJWU3hEUVVGRE8wbEJRMjVFT3p0aFFXaENhMElzVTBGQlV6czdaMEpCUVZRc1UwRkJVenRCUVd0Q05VSXNhMEpCUVdFN1kwRkJRU3gxUWtGQlF5eEpRVUZKTEVWQlFVTXNUMEZCVHl4RlFVRkRMRkZCUVZFc1JVRkJSVHM3UVVGRmJrTXNaMEpCUVU4c1EwRkJReXhQUVVGUExFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTTdRVUZETVVJc2FVSkJRVkVzUTBGQlF5eFhRVUZYTEVkQlFVY3NVVUZCVVN4RFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF5eEZRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUTJwRUxHbENRVUZSTEVOQlFVTXNTVUZCU1N4SFFVRkhMRXRCUVVzc1EwRkJRenM3UVVGRmRFSXNZVUZCU1N4UlFVRlJMRWRCUVVjN1FVRkRZaXh0UWtGQlZTeFJRVUZSTEVOQlFVTXNTVUZCU1R0QlFVTjJRaXh0UWtGQlZTeEZRVUZGTzBGQlExb3NNa0pCUVd0Q0xFbEJRVWs3UVVGRGRFSXNhMEpCUVZNc2FVSkJRVmNzUlVGQlJUdEJRVU4wUWl4elFrRkJZU3hMUVVGTE8xVkJRMjVDTEVOQlFVTTdPMEZCUlVZc1kwRkJTeXhKUVVGSkxFZEJRVWNzU1VGQlNTeFJRVUZSTEVWQlFVVTdRVUZEZUVJc2JVSkJRVkVzUTBGQlF5eEhRVUZITEVOQlFVTXNSMEZCUnl4UlFVRlJMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU03VlVGREwwSTdPMEZCUlVRc1kwRkJTeXhKUVVGSkxFTkJRVU1zUjBGQlF5eERRVUZETEVWQlFVVXNRMEZCUXl4SFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF5eEZRVUZGTEVWQlFVVTdPMEZCUldoRExHVkJRVWtzVDBGQlR5eEhRVUZITEVsQlFVa3NRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenM3UVVGRmRFSXNaVUZCU3l4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFOUJRVThzUTBGQlF5eEZRVUZITzBGQlF6VkNMR3RDUVVGTkxFbEJRVWtzUjBGQlJ5eEpRVUZKTEU5QlFVOHNSVUZCUnp0QlFVTjZRaXgxUWtGQlVTeERRVUZETEVkQlFVY3NRMEZCUXl4SFFVRkhMRTlCUVU4c1EwRkJReXhIUVVGSExFTkJRVU1zUTBGQlF6dGpRVU01UWpzN1FVRkJRU3haUVVWR0xFMUJRVTBzU1VGQlNTeFBRVUZQTEU5QlFVOHNTMEZCU3l4VlFVRlZMRVZCUVVVN1FVRkRlRU1zY1VKQlFWRXNRMEZCUXl4TFFVRkxMRWRCUVVjc1QwRkJUeXhEUVVGRE96dFpRVVV4UWl4TlFVRk5MRWxCUVVrc1QwRkJUeXhEUVVGRExFMUJRVTBzU1VGQlJTeERRVUZETEVWQlFVVTdPMEZCUlRWQ0xHbENRVUZKTEVkQlFVY3NSMEZCUnl4UFFVRlBMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOcVF5eHhRa0ZCVVN4RFFVRkRMRWRCUVVjc1EwRkJReXhIUVVGSExFOUJRVThzUTBGQlF6dFpRVU42UWp0VlFVTkdPenM3T3p0QlFVdEVMR0ZCUVVrc1EwRkJReXhOUVVGTkxFZEJRVWNzUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03T3p0QlFVZG9SQ3hoUVVGSkxFbEJRVWtzUTBGQlF5eE5RVUZOTEVsQlFVa3NTVUZCU1N4RFFVRkRMRTFCUVUwc1dVRkJXU3hYUVVGWExFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNVMEZCVXl4RlFVRkZPMEZCUXpWRkxHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRmxCUVZrc1EwRkJReXhWUVVGVkxFTkJRVU1zUlVGQlJUdEJRVU42UXl4cFFrRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eFpRVUZaTEVOQlFVTXNWVUZCVlN4RlFVRkRMRVZCUVVVc1EwRkJReXhEUVVGRE8xbEJRM3BETzFWQlEwWTdPenM3UVVGSlJDeGhRVUZKTEZGQlFWRXNRMEZCUXl4SlFVRkpMRWxCUVVrc1MwRkJTeXhEUVVGRExFOUJRVThzUTBGQlF5eFJRVUZSTEVOQlFVTXNTVUZCU1N4RFFVRkRMRWxCUVVrc1VVRkJVU3hEUVVGRExHTkJRV01zUlVGQlJUdEJRVU0xUlN4bFFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExGRkJRVkVzUTBGQlF5eEpRVUZKTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRPVUlzWlVGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4UlFVRlJMRU5CUVVNc1NVRkJTU3hEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzBGQlF5OUNMR1ZCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUzBGQlN5eERRVUZETEV0QlFVc3NSMEZCUnl4SlFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF6dEJRVU0xUXl4bFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFdEJRVXNzUTBGQlF5eE5RVUZOTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1IwRkJSeXhKUVVGSkxFTkJRVU03VlVGREwwTXNUVUZCVFN4SlFVRkpMRkZCUVZFc1EwRkJReXhqUVVGakxFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNVMEZCVXl4RlFVRkZPenRCUVVWNlJDeGxRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRlZCUVZVc1EwRkJReXhOUVVGTkxFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUlVGQlJTeEpRVUZKTEVOQlFVTXNRMEZCUXl4blFrRkJaMElzUTBGQlF5eFBRVUZQTEVOQlFVTXNRMEZCUXl4UFFVRlBMRU5CUVVNc1NVRkJTU3hGUVVGRExFVkJRVVVzUTBGQlF5eERRVUZETEVOQlFVTTdRVUZETDBjc1pVRkJTU3hEUVVGRExFMUJRVTBzUjBGQlJ5eFZRVUZWTEVOQlFVTXNUVUZCVFN4RFFVRkRMR2RDUVVGblFpeERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRVZCUVVVc1NVRkJTU3hEUVVGRExFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU1zVDBGQlR5eERRVUZETEVsQlFVa3NSVUZCUXl4RlFVRkZMRU5CUVVNc1EwRkJReXhEUVVGRE96dEJRVVZxU0N4bFFVRkpMRWxCUVVrc1EwRkJReXhMUVVGTExFbEJRVVVzU1VGQlNTeEZRVUZGTzBGQlEzQkNMR2xDUVVGSkxFTkJRVU1zUzBGQlN5eEhRVUZITEZGQlFWRXNRMEZCUXl4WFFVRlhMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRGNrTXNhVUpCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUzBGQlN5eERRVUZETEV0QlFVc3NSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJRenRaUVVOcVJUdEJRVU5FTEdWQlFVa3NTVUZCU1N4RFFVRkRMRTFCUVUwc1NVRkJSU3hKUVVGSkxFVkJRVVU3UVVGRGNrSXNhVUpCUVVrc1EwRkJReXhOUVVGTkxFZEJRVWNzVVVGQlVTeERRVUZETEZkQlFWY3NRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOMFF5eHBRa0ZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhMUVVGTExFTkJRVU1zVFVGQlRTeEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1RVRkJUU3hIUVVGSExFbEJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVY3NTVUZCU1N4RFFVRkRPMWxCUTNCRk8xVkJSVVlzVFVGQlRUdEJRVU5NTEcxQ1FVRlJMRU5CUVVNc1NVRkJTU3hIUVVGSExGRkJRVkVzUTBGQlF5eFhRVUZYTEVOQlFVTTdRVUZEY2tNc1pVRkJTU3hEUVVGRExFdEJRVXNzUjBGQlJ5eFJRVUZSTEVOQlFVTXNTVUZCU1N4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRemxDTEdWQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1VVRkJVU3hEUVVGRExFbEJRVWtzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0VlFVTm9RenM3TzBGQlIwUXNZVUZCU1N4UlFVRlJMRU5CUVVNc1MwRkJTeXhGUVVGRk8wRkJRMnhDTEdWQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExFVkJRVVVzUTBGQlF5eFJRVUZSTEVWQlFVVXNVVUZCVVN4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8xVkJRMmhFTEUxQlFVMDdRVUZEVEN4bFFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFdEJRVXNzUTBGQlF6dFZRVU53UWpzN1FVRkZSQ3huUWtGQlR5eFJRVUZSTEVOQlFVTTdVVUZGYWtJN08wRkJSVVFzVTBGQlNUdGpRVUZCTEdkQ1FVRkhPMEZCUTB3c1lVRkJTU3hEUVVGRExGVkJRVlVzUlVGQlJTeERRVUZETzBGQlEyeENMR0ZCUVVrc1EwRkJReXhqUVVGakxFVkJRVVVzUTBGQlF6dEJRVU4wUWl4aFFVRkpMRU5CUVVNc1lVRkJZU3hGUVVGRkxFTkJRVU03UVVGRGNrSXNZVUZCU1N4RFFVRkRMR1ZCUVdVc1JVRkJSU3hEUVVGRE8wRkJRM1pDTEdGQlFVa3NRMEZCUXl4alFVRmpMRVZCUVVVc1EwRkJRenRCUVVOMFFpeGhRVUZKTEVOQlFVTXNXVUZCV1N4RlFVRkZMRU5CUVVNN1VVRkRja0k3TzBGQlJVUXNaVUZCVlR0alFVRkJMSE5DUVVGSE8wRkJRMWdzWVVGQlNTeERRVUZETEU5QlFVOHNSMEZCUnl4SFFVRkhMRU5CUVVNc1RVRkJUU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzBGQlEycERMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zV1VGQldTeERRVUZETEU5QlFVOHNSVUZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03UVVGRE9VTXNZVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhaUVVGWkxFTkJRVU1zVVVGQlVTeEZRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVOb1JDeGhRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRmRCUVZjc1EwRkJReXhKUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEVOQlFVTTdVVUZEZGtNN08wRkJSVVFzYlVKQlFXTTdZMEZCUVN3d1FrRkJSeXhGUVVGRk96dEJRVU51UWl4clFrRkJZVHRqUVVGQkxIbENRVUZITEVWQlFVVTdPMEZCUTJ4Q0xHMUNRVUZqTzJOQlFVRXNNRUpCUVVjc1JVRkJSVHM3UVVGRmJrSXNiMEpCUVdVN1kwRkJRU3d5UWtGQlJ6czdPMEZCUldoQ0xHRkJRVWtzUTBGQlF5eHBRa0ZCYVVJc1IwRkJSeXhKUVVGSkxFTkJRVU1zYVVKQlFXbENMRWxCUVVrc1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF6czdPMEZCUjJoRkxHRkJRVWtzUzBGQlN5eERRVUZETEUxQlFVMHNSVUZCUlR0QlFVTm9RaXhsUVVGSkxFTkJRVU1zYVVKQlFXbENMRU5CUVVNc1owSkJRV2RDTEVOQlFVTXNXVUZCV1N4RlFVRkZMR0ZCUVVjN2IwSkJRVWtzVFVGQlN5eFJRVUZSTEVOQlFVTXNSMEZCUnl4RFFVRkRPMWxCUVVFc1EwRkJReXhEUVVGRE8wRkJRMnBHTEdWQlFVa3NRMEZCUXl4cFFrRkJhVUlzUTBGQlF5eG5Ra0ZCWjBJc1EwRkJReXhYUVVGWExFVkJRVVVzWVVGQlJ6dHZRa0ZCU1N4TlFVRkxMRmxCUVZrc1EwRkJReXhIUVVGSExFTkJRVU03V1VGQlFTeERRVUZETEVOQlFVTTdRVUZEY0VZc1pVRkJTU3hEUVVGRExHbENRVUZwUWl4RFFVRkRMR2RDUVVGblFpeERRVUZETEZWQlFWVXNSVUZCUlN4aFFVRkhPMjlDUVVGSkxFMUJRVXNzWlVGQlpTeERRVUZETEVkQlFVY3NRMEZCUXp0WlFVRkJMRU5CUVVNc1EwRkJRenRWUVVOMlJqdEJRVU5FTEdGQlFVa3NRMEZCUXl4WlFVRlpMRWRCUVVjc1lVRkJSenRyUWtGQlNTeE5RVUZMTEU5QlFVOHNRMEZCUXl4SFFVRkhMRU5CUVVNN1ZVRkJRU3hEUVVGRE8wRkJRemRETEdGQlFVa3NRMEZCUXl4bFFVRmxMRWRCUVVjc1lVRkJSenRyUWtGQlNTeE5RVUZMTEZWQlFWVXNRMEZCUXl4SFFVRkhMRU5CUVVNN1ZVRkJRU3hEUVVGRE8wRkJRMjVFTEdGQlFVa3NRMEZCUXl4cFFrRkJhVUlzUTBGQlF5eG5Ra0ZCWjBJc1EwRkJReXhYUVVGWExFVkJRVVVzWVVGQlJ6dHJRa0ZCU1N4TlFVRkxMRkZCUVZFc1EwRkJReXhIUVVGSExFTkJRVU03VlVGQlFTeERRVUZETEVOQlFVTTdVVUZEYWtZN08wRkJSVVFzYVVKQlFWazdZMEZCUVN4M1FrRkJSenRCUVVOaUxHRkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNTMEZCU3l4RFFVRkRMRTFCUVUwc1IwRkJSeXhUUVVGVExFTkJRVU03VVVGRGRrTTdPMEZCUlVRc1lVRkJVVHRqUVVGQkxHdENRVUZETEVOQlFVTXNSVUZCUlRzN08wRkJSMVlzWVVGQlNTeEpRVUZKTEVOQlFVTXNUMEZCVHl4WlFVRlpMRmRCUVZjc1JVRkJSVHRCUVVOMlF5eGxRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRTFCUVUwc1EwRkJReXhuUWtGQlowSXNRMEZCUXl4SlFVRkpMRU5CUVVNc1QwRkJUeXhGUVVGRkxFbEJRVWtzUTBGQlF5eERRVUZETEdkQ1FVRm5RaXhEUVVGRExFOUJRVThzUTBGQlF5eERRVUZETEU5QlFVOHNRMEZCUXl4SlFVRkpMRVZCUVVNc1JVRkJSU3hEUVVGRExFTkJRVU03VlVGRGNrYzdPenRCUVVkRUxHRkJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVY3NSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhKUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEVOQlFVTTdRVUZETjBNc1lVRkJTU3hEUVVGRExFdEJRVXNzUjBGQlJ5eEhRVUZITEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdRVUZETlVNc1lVRkJTU3hEUVVGRExFOUJRVThzUjBGQlJ5eEpRVUZKTEVOQlFVTTdRVUZEY0VJc1lVRkJTU3hEUVVGRExFdEJRVXNzUlVGQlJTeERRVUZETzBGQlEySXNZVUZCU1N4RFFVRkRMRk5CUVZNc1IwRkJSeXhSUVVGUkxFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1YwRkJWeXhGUVVGRkxFbEJRVWtzUTBGQlF5eFpRVUZaTEVOQlFVTXNRMEZCUXp0QlFVTXpSU3hoUVVGSkxFTkJRVU1zV1VGQldTeEhRVUZITEZGQlFWRXNRMEZCUXl4blFrRkJaMElzUTBGQlF5eFRRVUZUTEVWQlFVVXNTVUZCU1N4RFFVRkRMR1ZCUVdVc1EwRkJReXhEUVVGRE8wRkJReTlGTEdGQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFTkJRVU03UVVGRGJrSXNWVUZCUXl4RFFVRkRMR05CUVdNc1JVRkJSU3hEUVVGRE8wRkJRMjVDTEZWQlFVTXNRMEZCUXl4bFFVRmxMRVZCUVVVc1EwRkJRenRSUVVOeVFqczdRVUZGUkN4WlFVRlBPMk5CUVVFc2FVSkJRVU1zUTBGQlF5eEZRVUZGT3pzN1FVRkRWQ3hoUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEVsQlFVa3NSVUZCUlR0QlFVTmtMR1ZCUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzUjBGQlJ5eERRVUZETEZkQlFWY3NRMEZCUXl4RFFVRkRMRVZCUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETzBGQlF6VkRMR1ZCUVVrc1EwRkJReXhKUVVGSkxFVkJRVVVzUTBGQlF6dEJRVU5hTEdWQlFVa3NRMEZCUXl4SlFVRkpMRWRCUVVjc1NVRkJTU3hEUVVGRE8wRkJRMnBDTEhGQ1FVRlZMRU5CUVVNc1dVRkJUVHRCUVVGRkxHMUNRVUZMTEVsQlFVa3NSMEZCUnl4TFFVRkxMRU5CUVVNN1dVRkJSU3hGUVVGRExFVkJRVVVzUTBGQlF5eERRVUZETzFWQlF6ZERPMEZCUTBRc1ZVRkJReXhEUVVGRExHTkJRV01zUlVGQlJTeERRVUZETzBGQlEyNUNMRlZCUVVNc1EwRkJReXhsUVVGbExFVkJRVVVzUTBGQlF6dFJRVU55UWpzN1FVRkZSQ3hsUVVGVk8yTkJRVUVzYjBKQlFVTXNRMEZCUXl4RlFVRkZPMEZCUTFvc1lVRkJTU3hEUVVGRExFdEJRVXNzUjBGQlJ5eEhRVUZITEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdRVUZETlVNc1lVRkJTU3hEUVVGRExFOUJRVThzUjBGQlJ5eExRVUZMTEVOQlFVTTdRVUZEY2tJc1lVRkJTU3hEUVVGRExFOUJRVThzUlVGQlJTeERRVUZETzBGQlEyWXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhUUVVGVExFTkJRVU1zUTBGQlF6dEJRVU55UWl4cFFrRkJVU3hEUVVGRExHMUNRVUZ0UWl4RFFVRkRMRmRCUVZjc1JVRkJReXhKUVVGSkxFTkJRVU1zV1VGQldTeERRVUZETEVOQlFVTTdRVUZETlVRc2FVSkJRVkVzUTBGQlF5eHRRa0ZCYlVJc1EwRkJReXhUUVVGVExFVkJRVU1zU1VGQlNTeERRVUZETEdWQlFXVXNRMEZCUXl4RFFVRkRPMEZCUXpkRUxGVkJRVU1zUTBGQlF5eGpRVUZqTEVWQlFVVXNRMEZCUXp0QlFVTnVRaXhWUVVGRExFTkJRVU1zWlVGQlpTeEZRVUZGTEVOQlFVTTdVVUZEY2tJN08wRkJSVVFzVlVGQlN6dGpRVUZCTEdsQ1FVRkhMRVZCUlZBN08wRkJSVVFzVTBGQlNUdGpRVUZCTEdkQ1FVRkhMRVZCUlU0N08wRkJSVVFzV1VGQlR6dGpRVUZCTEcxQ1FVRkhMRVZCUlZRN08wRkJTMFFzWVVGQlVUczdPenRqUVVGQkxHdENRVUZETEVOQlFVTXNSVUZCUlR0QlFVTldMR0ZCUVVrc1NVRkJTU3hEUVVGRExFOUJRVThzV1VGQldTeFhRVUZYTEVWQlFVVTdRVUZEZGtNc1pVRkJTU3hEUVVGRExFdEJRVXNzUjBGQlJ5eE5RVUZOTEVOQlFVTXNaMEpCUVdkQ0xFTkJRVU1zU1VGQlNTeERRVUZETEU5QlFVOHNSVUZCUlN4SlFVRkpMRU5CUVVNc1EwRkJReXhuUWtGQlowSXNRMEZCUXl4UFFVRlBMRU5CUVVNc1EwRkJReXhQUVVGUExFTkJRVU1zU1VGQlNTeEZRVUZETEVWQlFVVXNRMEZCUXl4RFFVRkRPMVZCUTNKSE8wRkJRMFFzWVVGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFbEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNRMEZCUXp0QlFVTTNReXhoUVVGSkxFTkJRVU1zUzBGQlN5eEhRVUZITEVkQlFVY3NRMEZCUXl4WFFVRlhMRU5CUVVNc1EwRkJReXhGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0QlFVTTFReXhoUVVGSkxFTkJRVU1zVDBGQlR5eEhRVUZITEVsQlFVa3NRMEZCUXp0QlFVTndRaXhoUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUTJRc1lVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNRMEZCUXp0QlFVTnVRaXhWUVVGRExFTkJRVU1zWTBGQll5eEZRVUZGTEVOQlFVTTdRVUZEYmtJc1ZVRkJReXhEUVVGRExHVkJRV1VzUlVGQlJTeERRVUZETzFGQlEzSkNPenRCUVVWRUxHbENRVUZaTzJOQlFVRXNjMEpCUVVNc1EwRkJReXhGUVVGRk8wRkJRMlFzWVVGQlNTeEpRVUZKTEVOQlFVTXNUMEZCVHl4RlFVRkZPMEZCUTJoQ0xHVkJRVWtzUTBGQlF5eExRVUZMTEVkQlFVY3NSMEZCUnl4RFFVRkRMRmRCUVZjc1EwRkJReXhEUVVGRExFVkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRPMEZCUXpWRExHVkJRVWtzUTBGQlF5eFRRVUZUTEVWQlFVVXNRMEZCUXp0QlFVTnFRaXhaUVVGRExFTkJRVU1zWTBGQll5eEZRVUZGTEVOQlFVTTdRVUZEYmtJc1dVRkJReXhEUVVGRExHVkJRV1VzUlVGQlJTeERRVUZETzFWQlEzSkNPMUZCUTBZN08wRkJSVVFzYjBKQlFXVTdZMEZCUVN4NVFrRkJReXhEUVVGRExFVkJRVVU3UVVGRGFrSXNZVUZCU1N4RFFVRkRMRXRCUVVzc1IwRkJSeXhIUVVGSExFTkJRVU1zVjBGQlZ5eERRVUZETEVOQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03UVVGRE4wTXNZVUZCU1N4RFFVRkRMRTlCUVU4c1IwRkJSeXhMUVVGTExFTkJRVU03UVVGRGNrSXNZVUZCU1N4RFFVRkRMRmxCUVZrc1JVRkJSU3hEUVVGRE8wRkJRM0JDTEdGQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1UwRkJVeXhEUVVGRExFTkJRVU03UVVGRGNrSXNWVUZCUXl4RFFVRkRMR05CUVdNc1JVRkJSU3hEUVVGRE8wRkJRMjVDTEZWQlFVTXNRMEZCUXl4bFFVRmxMRVZCUVVVc1EwRkJRenRSUVVOeVFqczdRVUZGUkN4VlFVRkxPMk5CUVVFc2FVSkJRVWM3UVVGRFRpeGhRVUZKTEVOQlFVTXNTMEZCU3l4RlFVRkZMRU5CUVVNN1VVRkRaRHM3UVVGRlJDeGpRVUZUTzJOQlFVRXNjVUpCUVVjN1FVRkRWaXhoUVVGSkxFTkJRVU1zU1VGQlNTeEZRVUZGTEVOQlFVTTdVVUZEWWpzN1FVRkZSQ3hwUWtGQldUdGpRVUZCTEhkQ1FVRkhPMEZCUTJJc1lVRkJTU3hEUVVGRExFOUJRVThzUlVGQlJTeERRVUZETzFGQlEyaENPenRCUVZWRUxGZEJRVTA3T3pzN096czdPenM3TzJOQlFVRXNaMEpCUVVNc1MwRkJTeXhGUVVGRExFMUJRVTBzUlVGQlJUdEJRVU51UWl4aFFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFdEJRVXNzUTBGQlF6dEJRVU51UWl4aFFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFMUJRVTBzUTBGQlF6dEJRVU55UWl4aFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFdEJRVXNzUTBGQlF5eExRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMRXRCUVVzc1IwRkJReXhKUVVGSkxFTkJRVU03UVVGRE1VTXNZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhMUVVGTExFTkJRVU1zVFVGQlRTeEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVNc1NVRkJTU3hEUVVGRE8wRkJRelZETEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1dVRkJXU3hEUVVGRExFOUJRVThzUlVGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1FVRkRPVU1zWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0QlFVTm9SQ3hoUVVGSkxFTkJRVU1zWVVGQllTeEZRVUZGTEVOQlFVTTdVVUZEZEVJN08wRkJSVVFzVlVGQlN6dGpRVUZCTEdsQ1FVRkhPMEZCUTA0c1owSkJRVThzU1VGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4VFFVRlRMRVZCUVVVN1FVRkROMElzWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WFFVRlhMRU5CUVVNc1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eFRRVUZUTEVOQlFVTXNRMEZCUXp0VlFVTnNSRHRSUVVOR096dEJRVkZFTEZsQlFVODdPenM3T3pzN096dGpRVUZCTEcxQ1FVRkhPMEZCUTFJc1lVRkJTU3hEUVVGRExFdEJRVXNzUlVGQlJTeERRVUZETzBGQlEySXNZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhYUVVGWExFTkJRVU1zU1VGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4RFFVRkRPMEZCUTNSRExHRkJRVWtzUTBGQlF5eHJRa0ZCYTBJc1JVRkJSU3hEUVVGRE8wRkJRekZDTEdGQlFVa3NTVUZCU1N4RFFVRkRMRlZCUVZVc1JVRkJSVHRCUVVOdVFpeHJRa0ZCVHl4SlFVRkpMRU5CUVVNc1ZVRkJWU3hEUVVGRExFbEJRVWtzUTBGQlF5eEZRVUZGTEVOQlFVTXNRMEZCUXp0VlFVTnFRenRCUVVORUxHRkJRVWtzUTBGQlF5eGhRVUZoTEVWQlFVVXNRMEZCUXp0UlFVTjBRanM3UVVGRlJDeHJRa0ZCWVR0alFVRkJMSGxDUVVGSExFVkJSV1k3TzBGQlJVUXNZVUZCVVR0alFVRkJMR3RDUVVGRExFbEJRVWtzUlVGQlF5eExRVUZMTEVWQlFVVTdRVUZEYmtJc1lVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eEpRVUZKTEVOQlFVTXNSMEZCUnl4TFFVRkxMRU5CUVVNN1FVRkRNVUlzWVVGQlNTeERRVUZETEdOQlFXTXNSVUZCUlN4RFFVRkRPMUZCUTNaQ096czdPMVZCYkZOclFpeFRRVUZUTzBsQlFWTXNXVUZCV1RzN2EwSkJRVGxDTEZOQlFWTXNRenM3T3pzN08wRkRZamxDTEdGQlFWa3NRMEZCUXpzN1FVRkZZaXhSUVVGUExFTkJRVU1zV1VGQldTeEhRVUZITEZWQlFVTXNSVUZCUlN4RlFVRkxPMEZCUXpkQ0xFOUJRVWtzWTBGQll5eEhRVUZITEVWQlFVVXNRMEZCUXl4eFFrRkJjVUlzUlVGQlJTeERRVUZETzBGQlEyaEVMRTlCUVVrc1IwRkJSeXhIUVVGSExHTkJRV01zUTBGQlF5eEhRVUZITEVkQlFVY3NUVUZCVFN4RFFVRkRMRTlCUVU4c1EwRkJRenRCUVVNNVF5eFBRVUZKTEVsQlFVa3NSMEZCUnl4alFVRmpMRU5CUVVNc1NVRkJTU3hIUVVGSExFMUJRVTBzUTBGQlF5eFBRVUZQTEVOQlFVTTdRVUZEYUVRc1ZVRkJUeXhGUVVGRExFZEJRVWNzUlVGQlNDeEhRVUZITEVWQlFVTXNTVUZCU1N4RlFVRktMRWxCUVVrc1JVRkJReXhEUVVGRE8wVkJRMjVDTEVOQlFVTTdPMEZCUlVZc1VVRkJUeXhEUVVGRExGbEJRVmtzUjBGQlJ5eFZRVUZETEUxQlFVMHNSVUZCU3p0QlFVTnFReXhQUVVGSkxFOUJRVThzVFVGQlRTeExRVUZMTEZGQlFWRXNSVUZCUlR0QlFVTTVRaXhYUVVGTkxFZEJRVWNzVVVGQlVTeERRVUZETEdOQlFXTXNRMEZCUXl4TlFVRk5MRU5CUVVNc1QwRkJUeXhEUVVGRExFZEJRVWNzUlVGQlF5eEZRVUZGTEVOQlFVTXNRMEZCUXl4RFFVRkRPMGxCUXpGRU96dEJRVVZFTEU5QlFVa3NUVUZCVFN4WlFVRlpMRmRCUVZjc1NVRkJTU3hOUVVGTkxGbEJRVmtzVlVGQlZTeEZRVUZETzBGQlEyaEZMRmxCUVU4c1RVRkJUU3hEUVVGRE8wbEJRMllzVFVGQlRUdEJRVU5NTEZsQlFVOHNNRUpCUVRCQ0xFTkJRVU03U1VGRGJrTTdSVUZEUml4RFFVRkRPenRCUVVWR0xGRkJRVThzUTBGQlF5eFhRVUZYTEVkQlFVY3NWVUZCUXl4RFFVRkRMRVZCUVVNc1RVRkJUU3hGUVVGTE8wRkJRMnhETEZWQlFVODdRVUZEVEN4TlFVRkRMRVZCUVVVc1EwRkJReXhEUVVGRExFdEJRVXNzUjBGQlJ5eE5RVUZOTEVOQlFVTXNTVUZCU1R0QlFVTjRRaXhOUVVGRExFVkJRVVVzUTBGQlF5eERRVUZETEV0QlFVc3NSMEZCUnl4TlFVRk5MRU5CUVVNc1IwRkJSenRKUVVONFFpeERRVUZETzBWQlEwZ3NRMEZCUXpzN1FVRkZSaXhSUVVGUExFTkJRVU1zVjBGQlZ5eEhRVUZITEZWQlFVTXNRMEZCUXl4RlFVRkRMRTFCUVUwc1JVRkJTenRCUVVOc1F5eFZRVUZQTzBGQlEwd3NUVUZCUXl4RlFVRkZMRU5CUVVNc1EwRkJReXhoUVVGaExFTkJRVU1zVFVGQlRTeEhRVUZITEVOQlFVTXNRMEZCUXl4aFFVRmhMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zUzBGQlN5eEhRVUZITEUxQlFVMHNRMEZCUXl4SlFVRkpMRWRCUVVjc1MwRkJTenRCUVVNeFJTeE5RVUZETEVWQlFVVXNRMEZCUXl4RFFVRkRMR0ZCUVdFc1EwRkJReXhOUVVGTkxFZEJRVWNzUTBGQlF5eERRVUZETEdGQlFXRXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhMUVVGTExFZEJRVWNzVFVGQlRTeERRVUZETEVkQlFVY3NSMEZCUnl4TFFVRkxPMGxCUXpGRkxFTkJRVU03UlVGRFNDeERRVUZET3p0QlFVVkdMRkZCUVU4c1EwRkJReXhYUVVGWExFZEJRVWNzVlVGQlV5eE5RVUZOTEVWQlFVVTdPenRCUVVWeVF5eFBRVUZKTEVOQlFVTXNUMEZCVHl4SFFVRkhMRkZCUVZFc1EwRkJReXhoUVVGaExFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTTdRVUZEYUVRc1QwRkJTU3hEUVVGRExFOUJRVThzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRlZCUVZVc1EwRkJReXhKUVVGSkxFTkJRVU1zUTBGQlF6dEJRVU0zUXl4VFFVRk5MRU5CUVVNc1YwRkJWeXhEUVVGRExFbEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNRMEZCUXpzN1FVRkZha01zVDBGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4VlFVRkRMRU5CUVVNc1JVRkJReXhEUVVGRExFVkJRVXM3UVVGRGNrSXNWMEZCU3l4UFFVRlBMRU5CUVVNc1MwRkJTeXhIUVVGSExFTkJRVU1zUjBGQlF5eERRVUZETEVOQlFVTTdRVUZEZWtJc1YwRkJTeXhQUVVGUExFTkJRVU1zVFVGQlRTeEhRVUZITEVOQlFVTXNSMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRNVUlzVjBGQlN5eFBRVUZQTEVOQlFVTXNTMEZCU3l4RFFVRkRMRXRCUVVzc1IwRkJSeXhEUVVGRExFZEJRVU1zU1VGQlNTeERRVUZETzBGQlEyeERMRmRCUVVzc1QwRkJUeXhEUVVGRExFdEJRVXNzUTBGQlF5eE5RVUZOTEVkQlFVY3NRMEZCUXl4SFFVRkRMRWxCUVVrc1EwRkJRenRKUVVOd1F5eERRVUZETzBWQlJVZ3NRenM3T3pzN08wRkRhRVJFTEdGQlFWa3NRMEZCUXpzN1FVRkZZaXhSUVVGUExFTkJRVU1zVVVGQlVTeEhRVUZITEZWQlFVTXNSMEZCUnl4RlFVRkxPMEZCUXpGQ0xFOUJRVWtzVDBGQlR5eEhRVUZITEV0QlFVc3NVVUZCVVN4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFOUJRVThzUTBGQlF5eEhRVUZITEVOQlFVTXNTVUZCU1N4SFFVRkhMRXRCUVVzc1NVRkJTU3hKUVVGSkxFZEJRVWNzV1VGQldTeFZRVUZWTEV0QlFVc3NTMEZCU3l4SlFVRkpMRWRCUVVjc1dVRkJXU3hYUVVGWExFdEJRVXNzUzBGQlN5eEZRVUZITzBGQlEyeEtMRmxCUVU4c1NVRkJTU3hEUVVGRE8wbEJRMklzVFVGQlRUdEJRVU5NTEZsQlFVOHNTMEZCU3l4RFFVRkRPMGxCUTJRN1JVRkRSaXhET3pzN096czdRVU5TUkN4aFFVRlpMRU5CUVVNN08wRkJSV0lzVVVGQlR5eERRVUZETEUxQlFVMHNSMEZCU1N4alFVRmpMRWxCUVVrc1VVRkJVU3hEUVVGRExHVkJRV2RDTEVNN096czdPenRCUTBZM1JEdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CT3p0QlFVVkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVRzN1FVRkZRVHRCUVVOQk96dEJRVVZCTzBGQlEwRTdRVUZEUVRzN1FVRkZRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPenRCUVVWQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVRzN1FVRkZRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVN4clFrRkJhVUk3UVVGRGFrSXNVVUZCVHp0QlFVTlFPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CT3p0QlFVVkJPenRCUVVWQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTEVsQlFVYzdRVUZEU0R0QlFVTkJPMEZCUTBFN1FVRkRRU3huUWtGQlpTeFRRVUZUTzBGQlEzaENPMEZCUTBFN08wRkJSVUU3UVVGRFFUczdRVUZGUVR0QlFVTkJPenRCUVVWQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVRzN1FVRkZRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdPMEZCUlVFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPenRCUVVWQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRXNUVUZCU3p0QlFVTk1PMEZCUTBFN08wRkJSVUU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CT3p0QlFVVkJPMEZCUTBFN08wRkJSVUU3TzBGQlJVRTdRVUZEUVR0QlFVTkJPenRCUVVWQk96dEJRVVZCTzBGQlEwRTdPMEZCUlVFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUczdRVUZGUVR0QlFVTkJPenRCUVVWQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVR0QlFVTkJPenRCUVVWQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVRzN1FVRkZRVHRCUVVOQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHM3UVVGRlFTeEpRVUZITzBGQlEwZ3NjVUpCUVc5Q0xGTkJRVk03UVVGRE4wSTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk96dEJRVVZCTzBGQlEwRTdPMEZCUlVFN1FVRkRRVHRCUVVOQk8wRkJRMEVzVFVGQlN6dEJRVU5NTzBGQlEwRTdPMEZCUlVFN1FVRkRRVHRCUVVOQk96dEJRVVZCTzBGQlEwRTdPMEZCUlVFN1FVRkRRVHM3UVVGRlFUdEJRVU5CT3p0QlFVVkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdPMEZCUlVFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN08wRkJSVUU3TzBGQlJVRTdRVUZEUVR0QlFVTkJMRWxCUVVjN1FVRkRTRHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CT3p0QlFVVkJPMEZCUTBFN08wRkJSVUU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVR0QlFVTkJPenRCUVVWQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPenRCUVVWQk8wRkJRMEU3UVVGRFFUczdRVUZGUVR0QlFVTkJPMEZCUTBFN08wRkJSVUU3UVVGRFFUdEJRVU5CT3p0QlFVVkJPMEZCUTBFN1FVRkRRVHM3UVVGRlFUdEJRVU5CTzBGQlEwRTdPenM3T3pzN1FVTTNVMEVzWVVGQldTeERRVUZET3pzN096czdRVUZGWWl4TFFVRkpMRWxCUVVrc1IwRkJSeXh0UWtGQlR5eERRVUZETEVOQlFXTXNRMEZCUXl4RFFVRkRPenM3T3pzN096czdPenRMUVZka0xFbEJRVWs3UVVGRldpeFpRVVpSTEVsQlFVa3NSMEZGZVVJN1UwRkJjRU1zUjBGQlJ5eG5RMEZCUnl4RFFVRkRPMU5CUVVNc1IwRkJSeXhuUTBGQlJ5eERRVUZETzFOQlFVTXNTVUZCU1N4blEwRkJSeXhEUVVGRE8xTkJRVU1zUzBGQlN5eG5RMEZCUnl4RFFVRkRPenN5UWtGR00wSXNTVUZCU1RzN096czdRVUZOY2tJc1UwRkJTU3hEUVVGRExFZEJRVWNzUjBGQlJ5eEhRVUZITEVOQlFVTTdRVUZEWml4VFFVRkpMRU5CUVVNc1IwRkJSeXhIUVVGSExFZEJRVWNzUTBGQlF6dEJRVU5tTEZOQlFVa3NRMEZCUXl4SlFVRkpMRWRCUVVjc1NVRkJTU3hEUVVGRE8wRkJRMnBDTEZOQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1MwRkJTeXhEUVVGRE8wRkJRMjVDTEZOQlFVa3NRMEZCUXl4UFFVRlBMRWRCUVVjc1MwRkJTeXhEUVVGRE8wRkJRM0pDTEZOQlFVa3NRMEZCUXl4UlFVRlJMRWRCUVVjc1MwRkJTeXhEUVVGRE8wRkJRM1JDTEZOQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzBsQlEzcENPenRuUWtGaWEwSXNTVUZCU1R0QlFXOUNka0lzVjBGQlRUczdPenM3T3p0alFVRkJMR2RDUVVGRExFdEJRVXNzUlVGQlJUdEJRVU5hTEdGQlFVa3NTVUZCU1N4RFFVRkRMRWxCUVVrc1JVRkJSVHM3UVVGRllpeGxRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRMRXRCUVVzc1IwRkJReXhKUVVGSkxFTkJRVU1zUjBGQlJ5eEpRVUZMTEVsQlFVa3NRMEZCUXl4SlFVRkxMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zU1VGQlNTeEhRVUZITEVsQlFVa3NRMEZCUXl4SFFVRkhMRVZCUVVVc1NVRkJTU3hEUVVGRExFZEJRVWNzUlVGQlF5eEpRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNN1ZVRkRPVWNzVFVGQlRUdEJRVU5NTEdWQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVWQlFVTXNTVUZCU1N4RFFVRkRMRWRCUVVjc1JVRkJReXhKUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEVOQlFVTTdWVUZEYWtRN1FVRkRSQ3hoUVVGSkxFbEJRVWtzUTBGQlF5eFJRVUZSTEV0QlFVc3NTVUZCU1N4RFFVRkRMRXRCUVVzc1JVRkJSVHRCUVVOb1F5eGxRVUZKTEVOQlFVTXNVVUZCVVN4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU03UVVGRE0wSXNaVUZCU1N4RFFVRkRMRTlCUVU4c1IwRkJSeXhKUVVGSkxFTkJRVU03VlVGRGNrSXNUVUZCVFR0QlFVTk1MR1ZCUVVrc1EwRkJReXhQUVVGUExFZEJRVWNzUzBGQlN5eERRVUZETzFWQlEzUkNPMEZCUTBRc1owSkJRVThzU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXp0UlFVTnVRanM3UVVGTlJDeHBRa0ZCV1RzN096czdPenRqUVVGQkxITkNRVUZETEV0QlFVc3NSVUZCUlR0QlFVTnNRaXhoUVVGSkxFTkJRVU1zUzBGQlN5eEhRVUZITEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1MwRkJTeXhGUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVWQlFVTXNTVUZCU1N4RFFVRkRMRWRCUVVjc1JVRkJReXhKUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEVOQlFVTTdRVUZEY2tRc1owSkJRVThzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03VVVGRGFFTTdPMEZCUzBjc1pVRkJWVHM3T3pzN08xbEJRVUVzV1VGQlJ6dEJRVU5tTEdkQ1FVRlBMRWxCUVVrc1EwRkJReXhUUVVGVExFTkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NSVUZCUXl4SlFVRkpMRU5CUVVNc1IwRkJSeXhGUVVGRExFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNRMEZCUXp0UlFVTnlSRHM3T3p0VlFXeEVhMElzU1VGQlNUczdPMnRDUVVGS0xFbEJRVWtzUXpzN096czdPenM3T3pzN096czdPenM3UVVOaWVrSXNZVUZCV1N4RFFVRkRPenRMUVVWT0xFbEJRVWtzZFVOQlFVMHNRMEZCWXpzN1MwRkRlRUlzVjBGQlZ5eDFRMEZCVFN4RlFVRnJRanM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096dExRVzFETjBJc1RVRkJUU3hYUVVGT0xFMUJRVTA3UVVGRlRpeFpRVVpCTEUxQlFVMHNSMEZGSzBRN1UwRkJjRVVzU1VGQlNTeG5RMEZCUXl4VlFVRlZPMU5CUVVNc1UwRkJVeXhuUTBGQlF5eFZRVUZWTzFOQlFVTXNUVUZCVFN4blEwRkJReXhEUVVGRExFTkJRVU1zUlVGQlF5eEhRVUZITEVOQlFVTTdVMEZCUXl4TlFVRk5MR2REUVVGRExFTkJRVU1zUTBGQlF5eEZRVUZETEVkQlFVY3NRMEZCUXpzN01rSkJSbTVGTEUxQlFVMDdPMEZCUjJZc1UwRkJTU3hEUVVGRExFbEJRVWtzUjBGQlJ5eEpRVUZKTEVOQlFVTTdRVUZEYWtJc1UwRkJTU3hEUVVGRExGTkJRVk1zUjBGQlJ5eFRRVUZUTEVOQlFVTTdRVUZETTBJc1UwRkJTU3hEUVVGRExGRkJRVkVzUjBGQlJ5eERRVUZETEVOQlFVTTdRVUZEYkVJc1UwRkJTU3hEUVVGRExFdEJRVXNzUjBGQlJ5eERRVUZETEVOQlFVTTdRVUZEWml4VFFVRkpMRU5CUVVNc1YwRkJWeXhIUVVGSExFTkJRVU1zUTBGQlF6dEJRVU55UWl4VFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFMUJRVTBzUlVGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0SlFVTTFRanM3WjBKQlZGVXNUVUZCVFR0QlFWZHFRaXhYUVVGTk8yTkJRVUVzWjBKQlFVTXNUVUZCVFN4RlFVRkRMRTFCUVUwc1JVRkJSVHRCUVVOd1FpeGhRVUZKTEVOQlFVTXNVVUZCVVN4SFFVRkhPMEZCUTJRc1kwRkJSeXhGUVVGRk8wRkJRMGdzWTBGQlF5eEZRVUZGTEUxQlFVMHNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRXaXhqUVVGRExFVkJRVVVzVFVGQlRTeERRVUZETEVOQlFVTXNRMEZCUXp0WlFVTmlPMEZCUTBRc1kwRkJSeXhGUVVGRk8wRkJRMGdzWTBGQlF5eEZRVUZGTEUxQlFVMHNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRXaXhqUVVGRExFVkJRVVVzVFVGQlRTeERRVUZETEVOQlFVTXNRMEZCUXp0WlFVTmlPMEZCUTBRc2FVSkJRVTBzUlVGQlJUdEJRVU5PTEdOQlFVTXNSVUZCUlN4RFFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRExFTkJRVU1zUjBGQlJ5eE5RVUZOTEVOQlFVTXNRMEZCUXl4RFFVRkRMRWxCUVVVc1EwRkJReXhIUVVGSExFMUJRVTBzUTBGQlF5eERRVUZETEVOQlFVTTdRVUZEZUVNc1kwRkJReXhGUVVGRkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTXNRMEZCUXl4SFFVRkhMRTFCUVUwc1EwRkJReXhEUVVGRExFTkJRVU1zU1VGQlJTeERRVUZETEVkQlFVY3NUVUZCVFN4RFFVRkRMRU5CUVVNc1EwRkJRenRaUVVONlF6dFZRVU5HTEVOQlFVTTdVVUZEU0RzN1FVRk5SeXhYUVVGTk8xbEJTa0VzVlVGQlF5eExRVUZMTEVWQlFVVTdRVUZEYUVJc1lVRkJTU3hEUVVGRExFOUJRVThzUjBGQlJ5eEpRVUZKTEVOQlFVTXNjMEpCUVhOQ0xFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdVVUZEYmtRN1dVRkZVeXhaUVVGSE8wRkJRMWdzWjBKQlFVOHNTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJRenRSUVVOeVFqczdRVUZIUkN4WFFVRk5PMk5CUVVFc1owSkJRVU1zUzBGQlN5eEZRVUZGTzBGQlExb3NZVUZCU1N4SlFVRkpMRU5CUVVNc1NVRkJTU3hMUVVGSExGVkJRVlVzUlVGQlJUdEJRVU14UWl4bFFVRkpMRk5CUVZNc1IwRkJSeXhKUVVGSkxFTkJRVU1zYzBKQlFYTkNMRU5CUVVNc1MwRkJTeXhEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXp0QlFVTnFSU3hsUVVGSkxFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNVMEZCVXl4RFFVRkRMRWRCUVVjc1IwRkJSeXhGUVVGRk8wRkJRVVVzYzBKQlFWTXNSMEZCUnl4RFFVRkRMRU5CUVVNN1dVRkJSVHRCUVVOcVJDeGxRVUZKTEVOQlFVTXNUVUZCVFN4SFFVRkhMRXRCUVVzc1EwRkJRenRCUVVOd1FpeGxRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzVTBGQlV5eEhRVUZITEVsQlFVa3NRMEZCUXl4WFFVRlhMRU5CUVVNN1ZVRkRlRVFzVFVGQlRUdEJRVU5NTEdWQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExITkNRVUZ6UWl4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8xVkJRMnBFTzBGQlEwUXNZVUZCU1N4RFFVRkRMRXRCUVVzc1IwRkJSeXhKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRVZCUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzFGQlEzaERPenRCUVVWRUxESkNRVUZ6UWp0alFVRkJMR2REUVVGRExFOUJRVThzUlVGQlJUdEJRVU01UWl4cFFrRkJUeXhKUVVGSkxFTkJRVU1zVTBGQlV6dEJRVU51UWl4blFrRkJTeXhSUVVGUk8wRkJRMWdzYVVKQlFVa3NVVUZCVVN4SFFVRkhMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zVDBGQlR5eERRVUZETEVOQlFVTXNSMEZCUnl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETEVWQlFVVXNUMEZCVHl4RFFVRkRMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOd1J5eHhRa0ZCVVN4SFFVRkhMRkZCUVZFc1EwRkJReXhMUVVGTExFbEJRVWtzU1VGQlNTeERRVUZETEVWQlFVVXNSMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVONFF5eHhRa0ZCVVN4SFFVRkhMRU5CUVVVc1VVRkJVU3hIUVVGSExFbEJRVWtzUjBGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4RFFVRkRPMEZCUTNaRExHOUNRVUZQTEZGQlFWRXNRMEZCUXp0QlFVTnNRaXhuUWtGQlN5eFZRVUZWTzBGQlEySXNiMEpCUVU4c1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eFBRVUZQTEVOQlFVTXNRMEZCUXl4RlFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUjBGQlJ5eERRVUZETEVOQlFVTXNSVUZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFZEJRVWNzUTBGQlF5eERRVUZETEVWQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRek5GTEdkQ1FVRkxMRmxCUVZrN1FVRkRaaXh2UWtGQlR5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRExFVkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4SFFVRkhMRU5CUVVNc1EwRkJReXhGUVVGRExFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNc1JVRkJReXhEUVVGRExFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZCUVN4VlFVTTFSVHRSUVVOR096czdPMVZCTjBSVkxFMUJRVTA3T3p0TFFXdEZUaXhOUVVGTkxGZEJRVTRzVFVGQlRUdEJRVVZPTEZsQlJrRXNUVUZCVFN4SFFVVlZPMU5CUVdZc1NVRkJTU3huUTBGQlF5eFJRVUZST3pzeVFrRkdaQ3hOUVVGTk96dEJRVWRtTEZOQlFVa3NRMEZCUXl4SlFVRkpMRWRCUVVjc1NVRkJTU3hEUVVGRE8wRkJRMnBDTEZOQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hYUVVGWExFVkJRVVVzUTBGQlF6dEJRVU12UWl4VFFVRkpMRU5CUVVNc1ZVRkJWU3hIUVVGSExFdEJRVXNzUTBGQlF6dEpRVU42UWpzN1owSkJUbFVzVFVGQlRUdEJRVkZxUWl4VlFVRkxPMk5CUVVFc2FVSkJRVWM3UVVGRFRpeHBRa0ZCVVN4SlFVRkpMRU5CUVVNc1NVRkJTVHRCUVVObUxHZENRVUZMTEZOQlFWTTdRVUZEV2l4cFFrRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVXNRMEZCUXp0QlFVTm9RaXhwUWtGQlNTeEpRVUZKTEVOQlFVTXNUMEZCVHl4RlFVRkZPMEZCUTJoQ0xESkNRVUZaTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRE8yTkJRelZDTzBGQlEwUXNhVUpCUVVrc1EwRkJReXhQUVVGUExFZEJRVWNzVlVGQlZTeERRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1IwRkJSeXhEUVVGRExFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNSVUZCUXl4RlFVRkZMRU5CUVVNc1EwRkJRenRCUVVONFJDeHBRa0ZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFVkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUXk5Q0xHMUNRVUZOTzBGQlExSXNaMEpCUVVzc1VVRkJVVHRCUVVOWUxHbENRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1FVRkRaQ3hwUWtGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRVZCUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzBGQlF5OUNMRzFDUVVGTk8wRkJRMUlzWjBKQlFVc3NXVUZCV1R0QlFVTm1MR2xDUVVGSkxFTkJRVU1zVVVGQlVTeEhRVUZITzBGQlEyUXNaMEpCUVVNc1JVRkJSU3hKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJReXhIUVVGSExFbEJRVWtzUTBGQlF5eExRVUZMTEVWQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1EwRkJRenRCUVVNelF5eG5Ra0ZCUXl4RlFVRkZMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUTBGQlF5eEhRVUZITEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJReXhIUVVGSExFbEJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1EwRkJRenRqUVVOcVJDeERRVUZETzBGQlEwWXNhVUpCUVVrc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF6dEJRVU5rTEdsQ1FVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUlVGQlF6dEJRVU5xUWl4dlFrRkJTeXhGUVVGRkxFbEJRVWtzUTBGQlF5eExRVUZMTzBGQlEycENMR2RDUVVGRExFVkJRVVVzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRPMEZCUTJ4Q0xHZENRVUZETEVWQlFVVXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRExFVkJRMjVDTEVOQlFVTXNRMEZCUXp0QlFVTklMRzFDUVVGTk8wRkJRMUlzWjBKQlFVc3NVVUZCVVR0QlFVTllMR2xDUVVGSkxFTkJRVU1zU1VGQlNTeEZRVUZGTEVOQlFVTTdRVUZEV2l4cFFrRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eFJRVUZSTEVWQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8wRkJReTlDTEcxQ1FVRk5PMEZCUVVFc1ZVRkRWRHRSUVVWR096dEJRVVZFTEZOQlFVazdZMEZCUVN4blFrRkJSenRCUVVOTUxHRkJRVWtzU1VGQlNTeERRVUZETEVsQlFVa3NTMEZCUnl4WlFVRlpMRVZCUVVVN1FVRkROVUlzWlVGQlNTeERRVUZETEZGQlFWRXNSMEZCUnp0QlFVTmtMR05CUVVNc1JVRkJSU3hKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJReXhIUVVGSExFbEJRVWtzUTBGQlF5eExRVUZMTEVWQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1EwRkJRenRCUVVNelF5eGpRVUZETEVWQlFVVXNTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRExFMUJRVTBzUlVGQlF5eERRVUZETEVWQlFVTXNRMEZCUXl4RFFVRkRPMWxCUTJwRUxFTkJRVU03UVVGRFJpeGxRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1JVRkJRenRCUVVOcVFpeHJRa0ZCU3l4RlFVRkZMRWxCUVVrc1EwRkJReXhMUVVGTE8wRkJRMnBDTEdOQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU03UVVGRGJFSXNZMEZCUXl4RlFVRkZMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF5eEZRVU51UWl4RFFVRkRMRU5CUVVNN1FVRkRTQ3hsUVVGSkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVOQlFVTTdWVUZEWmp0UlFVTkdPenRCUVVWRUxGbEJRVTg3WTBGQlFTeHRRa0ZCUnp0QlFVTlNMR2xDUVVGUkxFbEJRVWtzUTBGQlF5eEpRVUZKTzBGQlEyWXNaMEpCUVVzc1VVRkJVVHRCUVVOWUxHbENRVUZKTEVOQlFVTXNUMEZCVHl4RlFVRkZMRU5CUVVNN1FVRkRaaXhwUWtGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRVZCUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzBGQlF5OUNMRzFDUVVGTk8wRkJRMUlzWjBKQlFVc3NXVUZCV1R0QlFVTm1MR2xDUVVGSkxFTkJRVU1zVDBGQlR5eEZRVUZGTEVOQlFVTTdRVUZEWml4cFFrRkJTU3hEUVVGRExGRkJRVkVzUjBGQlJ6dEJRVU5rTEdkQ1FVRkRMRVZCUVVVc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETEVkQlFVY3NTVUZCU1N4RFFVRkRMRXRCUVVzN1FVRkROVUlzWjBKQlFVTXNSVUZCUlN4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwN1kwRkRiRU1zUTBGQlF6dEJRVU5HTEdsQ1FVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUlVGQlF6dEJRVU5xUWl4dlFrRkJTeXhGUVVGRkxFbEJRVWtzUTBGQlF5eExRVUZMTzBGQlEycENMR2RDUVVGRExFVkJRVVVzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRPMEZCUTJ4Q0xHZENRVUZETEVWQlFVVXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRExFVkJRMjVDTEVOQlFVTXNRMEZCUXp0QlFVTklMRzFDUVVGTk8wRkJRVUVzVlVGRFZEdFJRVU5HT3pzN08xVkJOVVZWTEUxQlFVMDdPenM3T3pzN1FVTjRSMjVDTEdGQlFWa3NRMEZCUXpzN096czdPMHRCUlZFc1RVRkJUVHRCUVVWa0xGbEJSbEVzVFVGQlRTeERRVVZpTEV0QlFVc3NSVUZCUlRzeVFrRkdRU3hOUVVGTk96dEJRVWQyUWl4VFFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFdEJRVXNzU1VGQlNTeExRVUZMTEVOQlFVTTdTVUZETjBJN08yZENRVXByUWl4TlFVRk5PMEZCVFhwQ0xGTkJRVWs3WTBGQlFTeGpRVUZETEV0QlFVc3NSVUZCUlR0QlFVTldMR0ZCUVVrc1MwRkJTeXhKUVVGSkxFdEJRVXNzUzBGQlN5eExRVUZMTEVWQlFVVTdRVUZETlVJc1pVRkJTU3hEUVVGRExFdEJRVXNzUjBGQlJ5eExRVUZMTEVOQlFVTTdWVUZEY0VJc1RVRkJUVHRCUVVOTUxHVkJRVWtzUTBGQlF5eExRVUZMTEVkQlFVY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRE8xVkJRekZDTzFGQlEwWTdPMEZCUlVRc1QwRkJSVHRqUVVGQkxHTkJRVWM3UVVGRFNDeGhRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJRenRSUVVOdVFqczdRVUZGUkN4UlFVRkhPMk5CUVVFc1pVRkJSenRCUVVOS0xHRkJRVWtzUTBGQlF5eExRVUZMTEVkQlFVY3NTMEZCU3l4RFFVRkRPMUZCUTNCQ096czdPMVZCY0VKclFpeE5RVUZOT3pzN2EwSkJRVTRzVFVGQlRTeERPenM3T3pzN1FVTkdNMElzWVVGQldTeERRVUZET3pzN096czdPenM3T3pzN1FVRkZZaXhMUVVGSkxFZEJRVWNzUjBGQlJ5eHRRa0ZCVHl4RFFVRkRMRU5CUVdFc1EwRkJReXhEUVVGRE8wRkJRMnBETEV0QlFVa3NVMEZCVXl4SFFVRkhMRzFDUVVGUExFTkJRVU1zUTBGQmJVSXNRMEZCUXl4RFFVRkRPMEZCUXpkRExFdEJRVWtzU1VGQlNTeEhRVUZITEcxQ1FVRlBMRU5CUVVNc1JVRkJaMElzUTBGQlF5eERRVUZET3p0TFFVTjZRaXhYUVVGWExDdERRVUZOTEVWQlFYRkNPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096dExRVzFETjBJc1RVRkJUVHRCUVVWa0xGbEJSbEVzVFVGQlRTeEhRVVZZT3pKQ1FVWkxMRTFCUVUwN08wRkJTWFpDTEZOQlFVa3NUMEZCVHl4SFFVRkhMRU5CUVVNc1MwRkJTeXhGUVVGRExFdEJRVXNzUlVGQlF5eFBRVUZQTEVOQlFVTXNRMEZCUXpzN1FVRkZjRU1zVTBGQlNTeFJRVUZSTEVkQlFVYzdRVUZEWWl4aFFVRlJMRU5CUVVNc1IwRkJSeXhGUVVGRExFVkJRVVVzUTBGQlF6dEJRVU5vUWl4aFFVRlJMRlZCUVZVN1FVRkRiRUlzV1VGQlR5eERRVUZETzBGQlExSXNXVUZCVHl4RFFVRkRPMEZCUTFJc1lVRkJVU3hEUVVGRE8wRkJRMVFzWTBGQlV5eERRVUZETzAxQlExZ3NRMEZCUXpzN1FVRkZSaXhuUTBGbWFVSXNUVUZCVFN3MlEwRmxha0lzVTBGQlV5eEZRVUZETEU5QlFVOHNSVUZCUXl4UlFVRlJMRVZCUVVVN08wRkJSV3hETEZOQlFVa3NRMEZCUXl4WFFVRlhMRWRCUVVjc1ZVRkJWU3hEUVVGRE96dEJRVVU1UWl4VFFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFbEJRVWtzU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1IwRkJSeXhGUVVGRkxFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNSMEZCUnl4RlFVRkZMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zU1VGQlNTeEZRVUZGTEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03TzBGQlJYUkhMRk5CUVVrc1EwRkJReXhSUVVGUkxFZEJRVWNzU1VGQlNTeFhRVUZYTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zU1VGQlNTeEZRVUZETEVsQlFVa3NRMEZCUXl4WFFVRlhMRVZCUVVNc1EwRkJReXhEUVVGRExFVkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RlFVRkRMRU5CUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUlVGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXpOSExGTkJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVlVGQlZTeERRVUZET3p0QlFVVTNReXhUUVVGSkxFTkJRVU1zU1VGQlNTeEZRVUZGTEVOQlFVTTdPMEZCUlZvc1UwRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eFRRVUZUTEVkQlFVY3NTVUZCU1N4RFFVRkRMRmRCUVZjc1EwRkJRenM3UVVGRk0wTXNVMEZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFVkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMGxCUldoRE96dGhRVGxDYTBJc1RVRkJUVHM3WjBKQlFVNHNUVUZCVFR0QlFXZERla0lzYlVKQlFXTTdZMEZCUVN3d1FrRkJSenM3UVVGRlppeGhRVUZKTEVOQlFVTXNSMEZCUnl4SFFVRkhMRWRCUVVjc1EwRkJReXhOUVVGTkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdRVUZET1VJc1lVRkJTU3hEUVVGRExFOUJRVThzUjBGQlJ5eEhRVUZITEVOQlFVTXNUVUZCVFN4RFFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRE8wRkJRMnhETEdGQlFVa3NRMEZCUXl4SlFVRkpMRWRCUVVjc1IwRkJSeXhEUVVGRExFMUJRVTBzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXpzN1FVRkZha01zWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WFFVRlhMRU5CUVVNc1NVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eERRVUZETzBGQlEyNURMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zVjBGQlZ5eERRVUZETEVsQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1EwRkJRenRCUVVOMlF5eGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmRCUVZjc1EwRkJReXhKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEVOQlFVTTdVVUZGY2tNN08wRkJSVVFzYTBKQlFXRTdZMEZCUVN4NVFrRkJSenM3UVVGRlpDeGhRVUZKTEVsQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExFMUJRVTBzUlVGQlJUdEJRVU0xUWl4bFFVRkpMRU5CUVVNc1YwRkJWeXhIUVVGSExGVkJRVlVzUTBGQlF6dFZRVU12UWl4TlFVRk5PMEZCUTB3c1pVRkJTU3hEUVVGRExGZEJRVmNzUjBGQlJ5eFpRVUZaTEVOQlFVTTdWVUZEYWtNN08wRkJSVVFzWVVGQlNTeEpRVUZKTEVOQlFVTXNVVUZCVVN4RlFVRkZPMEZCUTJwQ0xHVkJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNc1EwRkJReXhGUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNSVUZCUXl4RFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0VlFVTjBSRHM3UVVGRlJDeGhRVUZKTEVOQlFVTTdZVUZCUlN4RFFVRkRPMkZCUVVVc1EwRkJRenRoUVVGRkxFTkJRVU03WVVGQlJTeFRRVUZUTzJGQlFVVXNXVUZCV1N4aFFVRkRPMEZCUTNoRExHRkJRVWtzUTBGQlF5eFJRVUZSTEVkQlFVYzdRVUZEWkN4blFrRkJTeXhGUVVGRkxFTkJRVU03UVVGRFVpeFpRVUZETEVWQlFVVXNRMEZCUXp0VlFVTk1MRU5CUVVNN08wRkJSVVlzWVVGQlNTeEpRVUZKTEVOQlFVTXNWMEZCVnl4TFFVRkxMRlZCUVZVc1JVRkJSVHRCUVVOdVF5eGxRVUZKTEVOQlFVTXNVMEZCVXl4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzUTBGQlF5eERRVUZETzBGQlEycERMRmxCUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eEhRVUZETEVOQlFVTXNRMEZCUXp0QlFVTnFRaXhaUVVGRExFZEJRVWNzUTBGQlF5eERRVUZETzBGQlEwNHNXVUZCUXl4SFFVRkhMRWxCUVVrc1EwRkJReXhUUVVGVExFTkJRVU03UVVGRGJrSXNXVUZCUXl4SFFVRkhMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU03UVVGRFppeGxRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zVTBGQlV5eEhRVUZITEVkQlFVY3NRMEZCUXp0QlFVTjRReXhsUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEV0QlFVc3NSMEZCUnl4RFFVRkRMRWRCUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVkQlFVTXNTVUZCU1N4RFFVRkRMRlZCUVZVc1NVRkJSU3hEUVVGRExFZEJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRWRCUVVNc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRE4wVXNiMEpCUVZNc1IwRkJSeXhaUVVGWkxFZEJRVU1zU1VGQlNTeERRVUZETEZOQlFWTXNSMEZCUlN4RFFVRkRMRU5CUVVVc1IwRkJReXhEUVVGRExFZEJRVU1zUzBGQlN5eERRVUZETzBGQlEzSkVMSFZDUVVGWkxFZEJRVWNzUTBGQlF5eEhRVUZETEVOQlFVTXNRMEZCUXp0VlFVTndRaXhOUVVGTk8wRkJRMHdzWlVGQlNTeERRVUZETEZOQlFWTXNSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFTkJRVU1zUTBGQlF6dEJRVU5zUXl4WlFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE8wRkJRMDRzV1VGQlF5eEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVNc1EwRkJReXhEUVVGRE8wRkJRMnhDTEZsQlFVTXNSMEZCUnl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRE8wRkJRMllzV1VGQlF5eEhRVUZITEVsQlFVa3NRMEZCUXl4VFFVRlRMRU5CUVVNN1FVRkRiRUlzWlVGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRExGTkJRVk1zUjBGQlJ5eEhRVUZITEVOQlFVTTdRVUZEZUVNc1pVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eExRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMRlZCUVZVc1NVRkJSU3hEUVVGRExFZEJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRWRCUVVNc1EwRkJReXhEUVVGRExFZEJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRNMFVzYjBKQlFWTXNSMEZCUnl4alFVRmpMRWRCUVVNc1NVRkJTU3hEUVVGRExGTkJRVk1zUjBGQlJTeERRVUZETEVOQlFVVXNSMEZCUXl4RFFVRkRMRWRCUVVNc1IwRkJSeXhEUVVGRE8wRkJRM0pFTEhWQ1FVRlpMRWRCUVVjc1EwRkJReXhIUVVGRExFTkJRVU1zUTBGQlF6dFZRVU53UWpzN1FVRkZSQ3hoUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4SFFVRkhMRVZCUVVNc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRE4wSXNZVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhaUVVGWkxFTkJRVU1zUjBGQlJ5eEZRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXpkQ0xHRkJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNXVUZCV1N4RFFVRkRMRmRCUVZjc1JVRkJReXhUUVVGVExFTkJRVU1zUTBGQlF6dEJRVU0zUXl4aFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eEpRVUZKTEVWQlFVTXNXVUZCV1N4RFFVRkRMRU5CUVVNN1FVRkRla01zWVVGQlNTeERRVUZETEVkQlFVY3NRMEZCUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hGUVVGRExGbEJRVmtzUTBGQlF5eERRVUZETzBGQlEzcERMR0ZCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zV1VGQldTeERRVUZETEU5QlFVOHNSVUZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOcVF5eGhRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhSUVVGUkxFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdPMEZCUld4RExHRkJRVWtzU1VGQlNTeERRVUZETEZkQlFWY3NTMEZCU3l4VlFVRlZMRVZCUVVVN1FVRkRia01zWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1IwRkJSeXhGUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzBGQlEycERMR1ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zV1VGQldTeERRVUZETEVkQlFVY3NSVUZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzBGQlEyNUVMR1ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zV1VGQldTeERRVUZETEU5QlFVOHNSVUZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOeVF5eGxRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmxCUVZrc1EwRkJReXhSUVVGUkxFVkJRVU1zUTBGQlF5eEhRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03VlVGRE0wUXNUVUZCVFR0QlFVTk1MR1ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zV1VGQldTeERRVUZETEVkQlFVY3NSVUZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOcVF5eGxRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmxCUVZrc1EwRkJReXhIUVVGSExFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZEYWtNc1pVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eFpRVUZaTEVOQlFVTXNUMEZCVHl4RlFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZEZGtRc1pVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eFpRVUZaTEVOQlFVTXNVVUZCVVN4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8xVkJRM1pETzBGQlEwUXNZVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhaUVVGWkxFTkJRVU1zVjBGQlZ5eEZRVUZETEZOQlFWTXNRMEZCUXl4RFFVRkRPMEZCUTJwRUxHRkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWxCUVVrc1JVRkJReXhaUVVGWkxFTkJRVU1zUTBGQlF6dEJRVU0zUXl4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExGbEJRVmtzUTBGQlF5eEpRVUZKTEVWQlFVTXNXVUZCV1N4RFFVRkRMRU5CUVVNN08wRkJSVGRETEdGQlFVa3NTVUZCU1N4RFFVRkRMRmRCUVZjc1MwRkJTeXhWUVVGVkxFVkJRVVU3UVVGRGJrTXNaVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhaUVVGWkxFTkJRVU1zU1VGQlNTeEZRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXk5Q0xHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWxCUVVrc1JVRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMVZCUTJ4RUxFMUJRVTA3UVVGRFRDeGxRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRmxCUVZrc1EwRkJReXhKUVVGSkxFVkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenRCUVVOcVJDeGxRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRmxCUVZrc1EwRkJReXhKUVVGSkxFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdWVUZEYUVNN1FVRkRSQ3hoUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZsQlFWa3NRMEZCUXl4SFFVRkhMRVZCUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0UlFVVTNRenM3UVVGRlJDeHRRa0ZCWXp0alFVRkJMREJDUVVGSE8wRkJRMllzWVVGQlNTeERRVUZETEVkQlFVY3NRMEZCUXl4WlFVRlpMRU5CUVVNc1RVRkJUU3hGUVVGRkxFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTVUZCU1N4RFFVRkRMRU5CUVVNN1FVRkRhRVFzWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1RVRkJUU3hGUVVGRkxFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN1FVRkRkRVFzWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1RVRkJUU3hGUVVGRkxFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN1VVRkRjRVE3TzBGQlIwUXNWMEZCVFR0alFVRkJMR3RDUVVGSE8wRkJRMUFzWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UFFVRlBMRVZCUVVVN1FVRkRha0lzWlVGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRExGTkJRVk1zUjBGQlF5eEpRVUZKTEVOQlFVTTdWVUZEZGtNN1FVRkRSQ3hoUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZsQlFWa3NRMEZCUXl4SFFVRkhMRVZCUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXpzN1FVRkZOVU1zWVVGQlNTeEpRVUZKTEVOQlFVTXNWMEZCVnl4TFFVRkxMRlZCUVZVc1JVRkJSVHRCUVVOdVF5eGxRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRXRCUVVzc1IwRkJSeXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTXNSMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExGVkJRVlVzU1VGQlJTeEpRVUZKTEVOQlFVTXNUVUZCVFN4SFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF5eEhRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXpWR0xHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWxCUVVrc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeEhRVUZITEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03UVVGREwwUXNaVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhaUVVGWkxFTkJRVU1zUjBGQlJ5eEZRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0QlFVTnFSU3hsUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZsQlFWa3NRMEZCUXl4UlFVRlJMRVZCUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0VlFVTXhSQ3hOUVVGTk8wRkJRMHdzWlVGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eFZRVUZWTEVsQlFVVXNTVUZCU1N4RFFVRkRMRXRCUVVzc1IwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTXNSMEZCUXl4RFFVRkRMRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTXNRMEZCUXp0QlFVTXpSaXhsUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZsQlFWa3NRMEZCUXl4SlFVRkpMRVZCUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0QlFVTnFSQ3hsUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZsQlFWa3NRMEZCUXl4SFFVRkhMRVZCUVVNc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRGFrTXNaVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhaUVVGWkxFTkJRVU1zVDBGQlR5eEZRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03VlVGRGVrUTdVVUZEUmpzN1FVRkhSQ3hWUVVGTE8yTkJRVUVzYVVKQlFVYzdRVUZEVGl4aFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU1zUjBGQlJ5eEpRVUZKTEVOQlFVTXNVMEZCVXl4SFFVRkRMRWRCUVVjc1EwRkJRenRCUVVOeVF5eGhRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRTFCUVUwc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETzBGQlEyeERMR0ZCUVVrc1EwRkJReXhKUVVGSkxFVkJRVVVzUTBGQlF6dFJRVU5pT3p0QlFVVkVMRk5CUVVrN1kwRkJRU3huUWtGQlJ6dEJRVU5NTEdGQlFVa3NTVUZCU1N4RFFVRkRMRTlCUVU4c1JVRkJSVHRCUVVOb1FpeGxRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRTFCUVUwc1EwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZEYWtNc1pVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eFpRVUZaTEVOQlFVVXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhMUVVGTExFTkJRVVVzUTBGQlF6dEJRVU5vUkN4bFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUlVGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8wRkJRM1JETEdWQlFVa3NRMEZCUXl4TlFVRk5MRVZCUVVVc1EwRkJRenRWUVVWbU8xRkJRMFk3TzBGQlJVUXNXVUZCVHp0alFVRkJMRzFDUVVGSE8wRkJRMUlzWVVGQlNTeERRVUZETEUxQlFVMHNSVUZCUlN4RFFVRkRPMUZCUTJZN08wRkJSVWNzWlVGQlZUdFpRVUZCTEZsQlFVYzdRVUZEWml4blFrRkJUeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEZWQlFWVXNRMEZCUXp0UlFVTXZRanM3UVVGVlJ5eFZRVUZMT3pzN096czdPenRaUVVoQkxGbEJRVWM3UVVGRFZpeG5Ra0ZCVHl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFdEJRVXNzUTBGQlF6dFJRVU14UWp0WlFVTlJMRlZCUVVNc1EwRkJReXhGUVVGRk8wRkJRMWdzWVVGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRGRFSXNZVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhMUVVGTExFZEJRVWNzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4VlFVRlZMRU5CUVVNN1FVRkROME1zWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRVZCUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0QlFVTjBReXhoUVVGSkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVOQlFVTTdVVUZEWmpzN1FVRlZSeXhSUVVGSE96czdPenM3T3p0WlFVaEJMRmxCUVVjN1FVRkRVaXhuUWtGQlR5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWRCUVVjc1EwRkJRenRSUVVONFFqdFpRVU5OTEZWQlFVTXNRMEZCUXl4RlFVRkZPMEZCUTFRc1lVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eEhRVUZITEVkQlFVY3NRMEZCUXl4RFFVRkRPMUZCUTNKQ096dEJRVlZITEZGQlFVYzdPenM3T3pzN08xbEJTRUVzV1VGQlJ6dEJRVU5TTEdkQ1FVRlBMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUjBGQlJ5eERRVUZETzFGQlEzaENPMWxCUTAwc1ZVRkJReXhEUVVGRExFVkJRVVU3UVVGRFZDeGhRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWRCUVVjc1IwRkJSeXhEUVVGRExFTkJRVU03VVVGRGNrSTdPMEZCVlVjc1UwRkJTVHM3T3pzN096czdXVUZJUVN4WlFVRkhPMEZCUTFRc1owSkJRVThzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SlFVRkpMRU5CUVVNN1VVRkRla0k3V1VGRFR5eFZRVUZETEVOQlFVTXNSVUZCUlR0QlFVTldMR0ZCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zU1VGQlNTeEhRVUZITEVOQlFVTXNRMEZCUXp0UlFVTjBRanM3UVVGVlJ5eFRRVUZKT3pzN096czdPenRaUVVoQkxGbEJRVWM3UVVGRFZDeG5Ra0ZCVHl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFbEJRVWtzUTBGQlF6dFJRVU16UWp0WlFVTlBMRlZCUVVNc1EwRkJReXhGUVVGRk8wRkJRMVlzWVVGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4SlFVRkpMRWRCUVVjc1EwRkJReXhEUVVGRE8xRkJRM2hDT3pzN08xVkJkRTlyUWl4TlFVRk5PMGxCUVZNc1UwRkJVenM3YTBKQlFYaENMRTFCUVUwc1F6czdPenM3TzBGRGVFTXpRaXhoUVVGWkxFTkJRVU03T3pzN096czdPenM3UVVGRllpeExRVUZKTEVkQlFVY3NSMEZCUnl4dFFrRkJUeXhEUVVGRExFTkJRV0VzUTBGQlF5eERRVUZETzBGQlEycERMRXRCUVVrc1YwRkJWeXhIUVVGSExHMUNRVUZQTEVOQlFVTXNSVUZCYTBJc1EwRkJReXhEUVVGRE8wRkJRemxETEV0QlFVa3NVMEZCVXl4SFFVRkhMRzFDUVVGUExFTkJRVU1zUTBGQmJVSXNRMEZCUXl4RFFVRkRPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3TzB0Qk9FSjRRaXhOUVVGTk8wRkJSV1FzV1VGR1VTeE5RVUZOTEVkQlJWZzdNa0pCUmtzc1RVRkJUVHM3UVVGSmRrSXNVMEZCU1N4UFFVRlBMRWRCUVVjc1EwRkJReXhQUVVGUExFTkJRVU1zUTBGQlF6czdRVUZGZUVJc1UwRkJTU3hSUVVGUkxFZEJRVWM3UVVGRFlpeGhRVUZSTEVOQlFVTXNSVUZCUlN4RlFVRkRMRVZCUVVVc1EwRkJRenRCUVVObUxHVkJRVlVzUzBGQlN6dEJRVU5tTEdOQlFWTXNTMEZCU3p0TlFVTm1MRU5CUVVNN08wRkJSVVlzWjBOQldtbENMRTFCUVUwc05rTkJXV3BDTEZOQlFWTXNSVUZCUXl4UFFVRlBMRVZCUVVNc1VVRkJVU3hGUVVGRk96dEJRVVZzUXl4VFFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFbEJRVWtzVjBGQlZ5eERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03TzBGQlJXNUVMRk5CUVVrc1EwRkJReXhKUVVGSkxFVkJRVVVzUTBGQlF6dEpRVVZpT3p0aFFXeENhMElzVFVGQlRUczdaMEpCUVU0c1RVRkJUVHRCUVc5Q2VrSXNiVUpCUVdNN1kwRkJRU3d3UWtGQlJ6czdRVUZGWml4aFFVRkpMRU5CUVVNc1IwRkJSeXhIUVVGSExFZEJRVWNzUTBGQlF5eE5RVUZOTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN1FVRkRPVUlzWVVGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4SFFVRkhMRU5CUVVNc1RVRkJUU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETzBGQlEycERMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zVjBGQlZ5eERRVUZETEVsQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1EwRkJRenRCUVVOdVF5eGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmRCUVZjc1EwRkJReXhKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEVOQlFVTTdVVUZGY2tNN08wRkJSVVFzYTBKQlFXRTdZMEZCUVN4NVFrRkJSenM3UVVGRlpDeGhRVUZKTEVsQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1NVRkJTU3hEUVVGRExFdEJRVXNzUjBGQlF5eERRVUZETEVWQlFVVTdRVUZET1VJc1pVRkJTU3hEUVVGRExGRkJRVkVzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4SFFVRkRMRU5CUVVNc1EwRkJRenRWUVVNdlFpeE5RVUZOTzBGQlEwd3NaVUZCU1N4RFFVRkRMRkZCUVZFc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eEhRVUZETEVOQlFVTXNRMEZCUXp0VlFVTTVRanM3UVVGRlJDeGhRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhIUVVGSExFVkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NSMEZCUXl4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRExGRkJRVkVzUjBGQlF5eEhRVUZITEVOQlFVTXNRMEZCUXp0QlFVTTFSQ3hoUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4SFFVRkhMRVZCUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUjBGQlF5eERRVUZETEVkQlFVY3NTVUZCU1N4RFFVRkRMRkZCUVZFc1IwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU16UkN4aFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eEpRVUZKTEVWQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1IwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU0xUXl4aFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eEpRVUZKTEVWQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1IwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU0xUXl4aFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eFBRVUZQTEVWQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1IwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU12UXl4aFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eFJRVUZSTEVWQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRE96dEJRVVU1UXl4aFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGbEJRVmtzUTBGQlF5eEpRVUZKTEVWQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1IwRkJReXhEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRPMEZCUXpGRUxHRkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWxCUVVrc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeEhRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXpORExHRkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWRCUVVjc1JVRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTTdVVUZGTTBNN08wRkJSVVFzYlVKQlFXTTdZMEZCUVN3d1FrRkJSenRCUVVObUxHRkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRPMEZCUTI1RUxHRkJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXp0UlFVTm1PenRCUVVWRUxGZEJRVTA3WTBGQlFTeHJRa0ZCUnp0QlFVTlFMR0ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eEZRVUZGTzBGQlEyWXNaVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhaUVVGWkxFTkJRVU1zU1VGQlNTeEZRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVNc1EwRkJReXhIUVVGSExFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXp0QlFVTXhSQ3hsUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4TlFVRk5MRVZCUVVVc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eEpRVUZKTEVOQlFVTXNRMEZCUXp0VlFVTnFSQ3hOUVVGTk8wRkJRMHdzWlVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hGUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVkQlFVTXNRMEZCUXl4SFFVRkhMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF6dEJRVU14UkN4bFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eE5RVUZOTEVWQlFVVXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dFZRVU51UkR0UlFVTkdPenRCUVVWRUxGVkJRVXM3WTBGQlFTeHBRa0ZCUnp0QlFVTk9MR0ZCUVVrc1EwRkJReXhKUVVGSkxFVkJRVVVzUTBGQlF6dEJRVU5hTEdGQlFVa3NRMEZCUXl4TlFVRk5MRVZCUVVVc1EwRkJRenRCUVVOa0xHRkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RlFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dFJRVU5vUXpzN1FVRlZSeXhWUVVGTE96czdPenM3T3p0WlFVaEJMRmxCUVVjN1FVRkRWaXhuUWtGQlR5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRXRCUVVzc1EwRkJRenRSUVVNeFFqdFpRVU5STEZWQlFVTXNTMEZCU3l4RlFVRkZPMEZCUTJZc1lVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1FVRkRlRUlzWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRVZCUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzBGQlF5OUNMR0ZCUVVrc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF6dFJRVU5tT3p0QlFWRkVMRk5CUVVrN096czdPenM3TzJOQlFVRXNaMEpCUVVjN1FVRkRUQ3hoUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVsQlFVa3NSVUZCUlN4RFFVRkRPMEZCUTI1Q0xHRkJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXp0UlFVTm1PenM3TzFWQk9VWnJRaXhOUVVGTk8wbEJRVk1zVTBGQlV6czdhMEpCUVhoQ0xFMUJRVTBzUXpzN096czdPMEZEYkVNelFpeGhRVUZaTEVOQlFVTTdPenM3T3pzN096czdRVUZGWWl4TFFVRkpMRWRCUVVjc1IwRkJSeXh0UWtGQlR5eERRVUZETEVOQlFXRXNRMEZCUXl4RFFVRkRPMEZCUTJwRExFdEJRVWtzWTBGQll5eEhRVUZITEcxQ1FVRlBMRU5CUVVNc1JVRkJPRUlzUTBGQlF5eERRVUZET3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdTMEZwUTNoRExFMUJRVTA3UVVGRlpDeFpRVVpSTEUxQlFVMHNSMEZGV0RzeVFrRkdTeXhOUVVGTk96dEJRVWwyUWl4VFFVRkpMRTlCUVU4c1IwRkJSeXhEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZET3p0QlFVZDJRaXhUUVVGSkxGRkJRVkVzUjBGQlJ6dEJRVU5pTEdGQlFWRXNRMEZCUXl4RlFVRkZMRVZCUVVNc1JVRkJSU3hEUVVGRE8wRkJRMllzWVVGQlVTeFpRVUZaTzBGQlEzQkNMR05CUVZNc1MwRkJTenROUVVObUxFTkJRVU03TzBGQlJVWXNaME5CWW1sQ0xFMUJRVTBzTmtOQllXcENMRk5CUVZNc1JVRkJReXhQUVVGUExFVkJRVU1zVVVGQlVTeEZRVUZGT3pzN096czdPMEZCVVd4RExGTkJRVWtzUTBGQlF5eEpRVUZKTEVkQlFVY3NTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhKUVVGSkxFTkJRVU03TzBGQlJTOUNMRk5CUVVrc1EwRkJReXhKUVVGSkxFVkJRVVVzUTBGQlF6dEJRVU5hTEZOQlFVa3NRMEZCUXl4TlFVRk5MRVZCUVVVc1EwRkJRenRKUVVWbU96dGhRVEZDYTBJc1RVRkJUVHM3WjBKQlFVNHNUVUZCVFR0QlFUUkNla0lzYlVKQlFXTTdZMEZCUVN3d1FrRkJSenRCUVVObUxHRkJRVWtzUTBGQlF5eEhRVUZITEVkQlFVY3NSMEZCUnl4RFFVRkRMRTFCUVUwc1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF6dEJRVU5vUXl4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExGZEJRVmNzUTBGQlF5eEpRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNN08wRkJSVzVETEdGQlFVa3NRMEZCUXl4cFFrRkJhVUlzUjBGQlJ5eEpRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRPenM3UVVGSGJFTXNZVUZCU1N4RFFVRkRMRWxCUVVrc1IwRkJSeXhIUVVGSExFTkJRVU1zVFVGQlRTeERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRPMEZCUXk5Q0xHRkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNWMEZCVnl4RFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUTBGQlF6czdRVUZGY0VNc1lVRkJTU3hEUVVGRExGRkJRVkVzUjBGQlJ5eEhRVUZITEVOQlFVTXNZMEZCWXl4RFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdPMEZCUldoRUxHRkJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExGbEJRVmtzUTBGQlF5eFJRVUZSTEVWQlFVVXNTMEZCU3l4RFFVRkRMRU5CUVVNN08wRkJSWEpFTEdGQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEZsQlFWa3NRMEZCUXl4UlFVRlJMRVZCUVVVc1RVRkJUU3hEUVVGRExFTkJRVU03VVVGRmRrUTdPMEZCUlVRc2EwSkJRV0U3WTBGQlFTeDVRa0ZCUnpzN1FVRkZaQ3hoUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4SlFVRkpMRVZCUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUjBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0QlFVTjZReXhoUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4SlFVRkpMRVZCUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUjBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0QlFVTXhReXhoUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4SFFVRkhMRVZCUVVVc1NVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RlFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUjBGQlJ5eERRVUZETEVkQlFVY3NTVUZCU1N4RFFVRkRMRXRCUVVzc1IwRkJReXhGUVVGRkxFTkJRVU1zUTBGQlF6dEJRVU5xUml4aFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eGpRVUZqTEVWQlFVVXNTVUZCU1N4RFFVRkRMRXRCUVVzc1IwRkJReXhGUVVGRkxFTkJRVU1zUTBGQlF6dFJRVU4wUkRzN1FVRkZSQ3h0UWtGQll6dGpRVUZCTERCQ1FVRkhPenRCUVVWbUxHRkJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExGbEJRVmtzUTBGQlF5eFpRVUZaTEVWQlFVVXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dEJRVU4wUlN4aFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4WlFVRlpMRU5CUVVNc1dVRkJXU3hGUVVGRkxFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTVUZCU1N4RFFVRkRMRU5CUVVNN1FVRkRjRVVzWVVGQlNTeERRVUZETEUxQlFVMHNSVUZCUlN4RFFVRkRPMUZCUTJZN08wRkJVVVFzVjBGQlRUczdPenM3T3pzN08yTkJRVUVzYTBKQlFVYzdRVUZEVUN4aFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUlVGQlJUdEJRVU5tTEdWQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFMUJRVTBzUlVGQlJTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1EwRkJReXhEUVVGRE8wRkJRMmhFTEdWQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExGRkJRVkVzUlVGQlJTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRmRCUVZjc1EwRkJReXhEUVVGRE8xVkJRekZFTEUxQlFVMDdRVUZEVEN4bFFVRkpMRWxCUVVrc1EwRkJReXhKUVVGSkxFdEJRVWNzV1VGQldTeEZRVUZGTzBGQlF6VkNMR2xDUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4UlFVRlJMRVZCUVVVc1QwRkJUeXhIUVVGRExFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNSVUZCUlN4SFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE8wRkJRemxFTEdsQ1FVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFOUJRVThzUTBGQlF5eFpRVUZaTEVOQlFVTXNTVUZCU1N4RlFVRkhMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF5eEhRVUZETEVkQlFVY3NSMEZCUlN4SFFVRkhMRU5CUVVNc1EwRkJRenRCUVVOd1JTeHBRa0ZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhQUVVGUExFTkJRVU1zV1VGQldTeERRVUZETEVsQlFVa3NSVUZCUnl4RFFVRkRMRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTXNTVUZCUlN4SFFVRkhMRWRCUVVVc1IwRkJSeXhEUVVGRExFTkJRVU03V1VGRGVrVXNUVUZCVFR0QlFVTk1MR2xDUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4UlFVRlJMRVZCUVVVc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0WlFVTnlSRHRCUVVORUxHVkJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNXVUZCV1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRPMVZCUTI1RU8xRkJRMFk3T3pzN1ZVRnFSbXRDTEUxQlFVMDdTVUZCVXl4alFVRmpPenRyUWtGQk4wSXNUVUZCVFN4RE96czdPenM3UVVOd1F6TkNMR0ZCUVZrc1EwRkJRenM3T3pzN096czdPenRCUVVWaUxFdEJRVWtzUjBGQlJ5eEhRVUZITEcxQ1FVRlBMRU5CUVVNc1EwRkJZU3hEUVVGRExFTkJRVU03UVVGRGFrTXNTMEZCU1N4SlFVRkpMRWRCUVVjc2JVSkJRVThzUTBGQlF5eERRVUZqTEVOQlFVTXNRMEZCUXp0QlFVTnVReXhMUVVGSkxGZEJRVmNzUjBGQlJ5eHRRa0ZCVHl4RFFVRkRMRVZCUVd0Q0xFTkJRVU1zUTBGQlF6dEJRVU01UXl4TFFVRkpMRk5CUVZNc1IwRkJSeXh0UWtGQlR5eERRVUZETEVOQlFXMUNMRU5CUVVNc1EwRkJRenM3T3pzN08wdEJUWGhDTEdOQlFXTTdRVUZGZEVJc1dVRkdVU3hqUVVGakxFTkJSWEpDTEVsQlFVa3NSVUZCUXl4UFFVRlBMRVZCUVVNc1VVRkJVU3hGUVVGRk96SkNRVVpvUWl4alFVRmpPenRCUVVrdlFpeG5RMEZLYVVJc1kwRkJZeXcyUTBGSmVrSXNTVUZCU1N4RlFVRkRMRTlCUVU4c1JVRkJReXhSUVVGUkxFVkJRVVU3TzBGQlJUZENMRk5CUVVrc1EwRkJReXhKUVVGSkxFZEJRVWNzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4SlFVRkpMRWxCUVVrc1VVRkJVU3hEUVVGRE96dEJRVVV6UXl4VFFVRkpMRU5CUVVNc1VVRkJVU3hIUVVGSE8wRkJRMlFzVVVGQlF5eEZRVUZGTEVOQlFVTTdRVUZEU2l4UlFVRkRMRVZCUVVVc1EwRkJRenROUVVOTUxFTkJRVU03TzBGQlJVWXNVMEZCU1N4RFFVRkRMRTFCUVUwc1IwRkJSeXhKUVVGSkxGZEJRVmNzUTBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8wbEJSWEJFT3p0aFFXWnJRaXhqUVVGak96dG5Ra0ZCWkN4alFVRmpPMEZCYVVKcVF5eHRRa0ZCWXp0alFVRkJMREJDUVVGSE8wRkJRMllzWVVGQlNTeERRVUZETEVkQlFVY3NSMEZCUnl4SFFVRkhMRU5CUVVNc1RVRkJUU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETzBGQlEyaERMR0ZCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zV1VGQldTeERRVUZETEUxQlFVMHNSVUZCUlN4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVOMFF5eGhRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhSUVVGUkxFVkJRVVVzVFVGQlRTeERRVUZETEVOQlFVTTdRVUZEZUVNc1lVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eFpRVUZaTEVOQlFVTXNZMEZCWXl4RlFVRkZMRU5CUVVNc1EwRkJReXhEUVVGRE96dEJRVVY2UXl4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExGZEJRVmNzUTBGQlF5eEpRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNN08wRkJSVzVETEdGQlFVa3NRMEZCUXl4cFFrRkJhVUlzUjBGQlJ5eEpRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRPenRCUVVWc1F5eGhRVUZKTEVOQlFVTXNZVUZCWVN4RlFVRkZMRU5CUVVNN1VVRkRkRUk3TzBGQlJVUXNhMEpCUVdFN1kwRkJRU3g1UWtGQlJ6dEJRVU5rTEdGQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFbEJRVWtzUlVGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRM3BETEdGQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFbEJRVWtzUlVGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4SFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRekZETEdGQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFZEJRVWNzUlVGQlJTeEpRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFVkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SFFVRkhMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU1zUTBGQlF6dFJRVU4wUlRzN1FVRkZSQ3hYUVVGTk8yTkJRVUVzYTBKQlFVYzdRVUZEVUN4aFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUlVGQlJUdEJRVU5tTEdWQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFMUJRVTBzUlVGQlJTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1EwRkJReXhEUVVGRE8wRkJRMmhFTEdWQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExGRkJRVkVzUlVGQlJTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRmRCUVZjc1EwRkJReXhEUVVGRE8xVkJRekZFTEUxQlFVMDdRVUZEVEN4bFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eE5RVUZOTEVWQlFVVXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dEJRVU5zUkN4bFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eFJRVUZSTEVWQlFVVXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dFZRVU55UkR0UlFVTkdPenRCUVVWRUxGTkJRVWs3WTBGQlFTeGpRVUZETEZWQlFWVXNSVUZCUlR0QlFVTm1MR2xDUVVGUkxFbEJRVWtzUTBGQlF5eEpRVUZKTzBGQlEyWXNaMEpCUVVzc1UwRkJVenRCUVVOYUxHbENRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1FVRkRaQ3hwUWtGQlNTeEpRVUZKTEVOQlFVTXNUMEZCVHl4RlFVRkZPMEZCUTJoQ0xESkNRVUZaTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRE8yTkJRelZDTzBGQlEwUXNhVUpCUVVrc1EwRkJReXhQUVVGUExFZEJRVWNzVlVGQlZTeERRVUZETEVsQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eEZRVUZETEVWQlFVVXNRMEZCUXl4RFFVRkRPenRCUVVWMFJDeHRRa0ZCVFR0QlFVTlNMR2RDUVVGTExGRkJRVkU3UVVGRFdDeHBRa0ZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE96dEJRVVZrTEcxQ1FVRk5PMEZCUTFJc1owSkJRVXNzV1VGQldUdEJRVU5tTEdsQ1FVRkpMRU5CUVVNc1VVRkJVU3hIUVVGSE8wRkJRMlFzWjBKQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFVkJRVU1zUTBGQlF5eEZRVUZETEVOQlFVTXNRMEZCUXp0QlFVTXpReXhuUWtGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1EwRkJReXhIUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4SFFVRkhMRWxCUVVrc1EwRkJReXhOUVVGTkxFVkJRVU1zUTBGQlF5eEZRVUZETEVOQlFVTXNRMEZCUXp0alFVTXZReXhEUVVGRE8wRkJRMFlzYVVKQlFVa3NRMEZCUXl4TlFVRk5MRVZCUVVVc1EwRkJRenM3T3pzN08wRkJUV1FzYlVKQlFVMDdRVUZEVWl4blFrRkJTeXhSUVVGUk8wRkJRMWdzYVVKQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1ZVRkJWU3hEUVVGRExFTkJRVU03TzBGQlJYUkNMRzFDUVVGTk8wRkJRVUVzVlVGRFZEdFJRVVZHT3p0QlFVVkVMRk5CUVVrN1kwRkJRU3hqUVVGRExFdEJRVXNzUlVGQlJUdEJRVU5XTEdGQlFVa3NTVUZCU1N4RFFVRkRMRWxCUVVrc1MwRkJSeXhaUVVGWkxFVkJRVVU3UVVGRE5VSXNaVUZCU1N4RFFVRkRMRXRCUVVzc1IwRkJSeXhMUVVGTExFbEJRVWtzU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXp0QlFVTnFReXhsUVVGSkxFTkJRVU1zVVVGQlVTeEhRVUZITzBGQlEyUXNZMEZCUXl4RlFVRkZMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRExFdEJRVXNzUlVGQlF5eERRVUZETEVWQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXpORExHTkJRVU1zUlVGQlJTeEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTXNSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVOQlFVTTdXVUZEYWtRc1EwRkJRenRCUVVOR0xHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RlFVRkRPMEZCUTJwQ0xHdENRVUZMTEVWQlFVVXNTVUZCU1N4RFFVRkRMRXRCUVVzN1FVRkRha0lzWTBGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJRenRCUVVOc1FpeGpRVUZETEVWQlFVVXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRExFVkJRMjVDTEVOQlFVTXNRMEZCUXp0QlFVTklMR1ZCUVVrc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF6dFZRVU5tTzFGQlEwWTdPMEZCUlVRc1QwRkJSVHRqUVVGQkxHTkJRVWM3UVVGRFNDeHBRa0ZCVVN4SlFVRkpMRU5CUVVNc1NVRkJTVHRCUVVObUxHZENRVUZMTEZGQlFWRTdRVUZEV0N4cFFrRkJTU3hEUVVGRExFOUJRVThzUlVGQlJTeERRVUZET3p0QlFVVm1MRzFDUVVGTk8wRkJRMUlzWjBKQlFVc3NXVUZCV1R0QlFVTm1MR2xDUVVGSkxFTkJRVU1zVDBGQlR5eEZRVUZGTEVOQlFVTTdRVUZEWml4cFFrRkJTU3hEUVVGRExGRkJRVkVzUjBGQlJ6dEJRVU5rTEdkQ1FVRkRMRVZCUVVVc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eEZRVUZETEVOQlFVTXNSVUZCUXl4RFFVRkRMRU5CUVVNN1FVRkRNME1zWjBKQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFTkJRVU1zUjBGQlJ5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zVFVGQlRTeEZRVUZETEVOQlFVTXNSVUZCUXl4RFFVRkRMRU5CUVVNN1kwRkRha1FzUTBGQlF6czdPenM3TzBGQlRVWXNiVUpCUVUwN1FVRkJRU3hWUVVOVU8xRkJRMFk3TzBGQlNVUXNWVUZCU3pzN096dGpRVUZCTEdsQ1FVRkhPMEZCUTA0c1lVRkJTU3hEUVVGRExFbEJRVWtzUlVGQlJTeERRVUZETzFGQlEySTdPMEZCUTBRc1UwRkJTVHRqUVVGQkxHZENRVUZITzBGQlEwd3NZVUZCU1N4RFFVRkRMRWxCUVVrc1JVRkJSU3hEUVVGRE8xRkJRMkk3TzBGQlEwUXNXVUZCVHp0alFVRkJMRzFDUVVGSE8wRkJRMUlzWVVGQlNTeERRVUZETEVWQlFVVXNSVUZCUlN4RFFVRkRPMUZCUTFnN08wRkJWVWNzVlVGQlN6czdPenM3T3pzN1dVRklRU3haUVVGSE8wRkJRMVlzWjBKQlFVOHNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhMUVVGTExFTkJRVU03VVVGRE1VSTdXVUZEVVN4VlFVRkRMRXRCUVVzc1JVRkJSVHRCUVVObUxHRkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8wRkJRM2hDTEdGQlFVa3NTVUZCU1N4RFFVRkRMRWxCUVVrc1MwRkJSeXhaUVVGWkxFVkJRVVU3UVVGRE5VSXNaVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFVkJRVU03UVVGRGFrSXNhMEpCUVVzc1JVRkJSU3hKUVVGSkxFTkJRVU1zUzBGQlN6dEJRVU5xUWl4alFVRkRMRVZCUVVVc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETzBGQlEyeENMR05CUVVNc1JVRkJSU3hKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTXNSVUZEYmtJc1EwRkJReXhEUVVGRE8xVkJRMG9zVFVGQlRUdEJRVU5NTEdWQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0VlFVTm9RenRCUVVORUxHRkJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXp0UlFVTm1PenRCUVU5RUxGTkJRVWs3T3pzN096czdPMk5CUVVFc1kwRkJReXhMUVVGTExFVkJRVVU3UVVGRFZpeGhRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dEJRVU40UWl4aFFVRkpMRWxCUVVrc1EwRkJReXhKUVVGSkxFdEJRVWNzV1VGQldTeEZRVUZGTzBGQlF6VkNMR1ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeEZRVUZETzBGQlEycENMR3RDUVVGTExFVkJRVVVzU1VGQlNTeERRVUZETEV0QlFVczdRVUZEYWtJc1kwRkJReXhGUVVGRkxFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXp0QlFVTnNRaXhqUVVGRExFVkJRVVVzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRVZCUTI1Q0xFTkJRVU1zUTBGQlF6dFZRVU5LTEUxQlFVMDdRVUZEVEN4bFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUlVGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1ZVRkRhRU03UVVGRFJDeGhRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1VVRkRaanM3UVVGTlJDeFhRVUZOT3pzN096czdPMk5CUVVFc1owSkJRVU1zVVVGQlVTeEZRVUZGTzBGQlEyWXNZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhGUVVGRkxFVkJRVVVzUTBGQlF6dEJRVU5xUWl4aFFVRkpMRkZCUVZFc1MwRkJSeXhMUVVGTExFVkJRVVU3UVVGRGNFSXNaVUZCU1N4SlFVRkpMRU5CUVVNc1NVRkJTU3hMUVVGSExGbEJRVmtzUlVGQlJUdEJRVU0xUWl4cFFrRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eFJRVUZSTEVWQlFVTTdRVUZEYWtJc2IwSkJRVXNzUlVGQlJTeEpRVUZKTEVOQlFVTXNTMEZCU3p0QlFVTnFRaXhuUWtGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJRenRCUVVOc1FpeG5Ra0ZCUXl4RlFVRkZMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF5eEZRVU51UWl4RFFVRkRMRU5CUVVNN1dVRkRTaXhOUVVGTk8wRkJRMHdzYVVKQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0WlFVTm9RenRWUVVOR08wRkJRMFFzWVVGQlNTeERRVUZETEUxQlFVMHNSVUZCUlN4RFFVRkRPMUZCUTJZN08wRkJUVVFzV1VGQlR6czdPenM3T3p0alFVRkJMR2xDUVVGRExGRkJRVkVzUlVGQlJUdEJRVU5vUWl4aFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFZEJRVWNzUlVGQlJTeERRVUZETzBGQlEyeENMR0ZCUVVrc1VVRkJVU3hMUVVGSExFdEJRVXNzUlVGQlJUdEJRVU53UWl4bFFVRkpMRWxCUVVrc1EwRkJReXhKUVVGSkxFdEJRVWNzV1VGQldTeEZRVUZGTzBGQlF6VkNMR2xDUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNSVUZCUXp0QlFVTnFRaXh2UWtGQlN5eEZRVUZGTEVsQlFVa3NRMEZCUXl4TFFVRkxPMEZCUTJwQ0xHZENRVUZETEVWQlFVVXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRE8wRkJRMnhDTEdkQ1FVRkRMRVZCUVVVc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVWQlEyNUNMRU5CUVVNc1EwRkJRenRaUVVOS0xFMUJRVTA3UVVGRFRDeHBRa0ZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFVkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMWxCUTJoRE8xVkJRMFk3UVVGRFJDeGhRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1VVRkRaanM3T3p0VlFXaE9hMElzWTBGQll6dEpRVUZUTEZOQlFWTTdPMnRDUVVGb1F5eGpRVUZqTEVNN096czdPenRCUTFodVF5eGhRVUZaTEVOQlFVTTdPenM3T3pzN096czdRVUZGWWl4TFFVRkpMR05CUVdNc1IwRkJSeXh0UWtGQlR5eERRVUZETEVWQlFUaENMRU5CUVVNc1EwRkJRenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN1MwRm5RM2hETEZWQlFWVTdRVUZGYkVJc1dVRkdVU3hWUVVGVkxFZEJSV1k3TWtKQlJrc3NWVUZCVlRzN1FVRkpNMElzVTBGQlNTeFBRVUZQTEVkQlFVY3NRMEZCUXl4UFFVRlBMRU5CUVVNc1EwRkJRenM3UVVGRmVFSXNVMEZCU1N4UlFVRlJMRWRCUVVjN1FVRkRZaXhoUVVGUkxFTkJRVU1zUjBGQlJ5eEZRVUZETEVWQlFVVXNRMEZCUXp0QlFVTm9RaXhqUVVGVExFdEJRVXM3UVVGRFpDeGhRVUZSTEUxQlFVMDdUVUZEWml4RFFVRkRPenRCUVVWR0xHZERRVnBwUWl4VlFVRlZMRFpEUVZseVFpeFRRVUZUTEVWQlFVTXNUMEZCVHl4RlFVRkRMRkZCUVZFc1JVRkJSVHM3UVVGRmJFTXNVMEZCU1N4RFFVRkRMRXRCUVVzc1IwRkJSeXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVsQlFVa3NRMEZCUXpzN1FVRkZhRU1zVTBGQlJ5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRk5CUVZNc1JVRkJRenM3UVVGRGVrSXNWMEZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhoUVVGaExFZEJRVWNzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4VFFVRlRMRU5CUVVNN1FVRkRkRVFzWTBGQlR5eERRVUZETEVsQlFVa3NRMEZCUXl4dFJVRkJiVVVzUTBGQlF5eERRVUZETzAxQlEyNUdPMEZCUTBRc1UwRkJTU3hEUVVGRExHTkJRV01zUjBGQlJ5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMR0ZCUVdFc1EwRkJRenRCUVVOc1JDeFRRVUZKTEVOQlFVTXNTVUZCU1N4SFFVRkpMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zWVVGQllTeEhRVUZKTEZGQlFWRXNSMEZCUnl4UlFVRlJMRU5CUVVNN1FVRkRhRVVzVTBGQlNTeERRVUZETEVsQlFVa3NSVUZCUlN4RFFVRkRPMEZCUTFvc1UwRkJTU3hEUVVGRExFMUJRVTBzUlVGQlJTeERRVUZET3p0QlFVVmtMRk5CUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4TFFVRkxMRU5CUVVNN1NVRkZiRU03TzJGQk0wSnJRaXhWUVVGVk96dG5Ra0ZCVml4VlFVRlZPMEZCTmtJM1FpeGxRVUZWTzJOQlFVRXNjMEpCUVVjN08wRkJSVmdzWVVGQlNTeERRVUZETEU5QlFVOHNSMEZCUnl4UlFVRlJMRU5CUVVNc1lVRkJZU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzBGQlF6ZERMR0ZCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVjBGQlZ5eERRVUZETEVsQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1EwRkJRenM3UVVGRmRFTXNZVUZCU1N4RFFVRkRMRmRCUVZjc1IwRkJSeXhSUVVGUkxFTkJRVU1zWVVGQllTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTJwRUxHRkJRVWtzUTBGQlF5eFhRVUZYTEVOQlFVTXNVMEZCVXl4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU03UVVGRGVFTXNZVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhYUVVGWExFTkJRVU1zU1VGQlNTeERRVUZETEZkQlFWY3NRMEZCUXl4RFFVRkRPMUZCUXpWRE96dEJRVVZFTEcxQ1FVRmpPMk5CUVVFc01FSkJRVWNzUlVGRmFFSTdPMEZCUlVRc2JVSkJRV003WTBGQlFTd3dRa0ZCUnp0QlFVTm1MR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eERRVUZETEV0QlFVc3NSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFbEJRVWtzUTBGQlF6dEJRVU0xUXl4aFFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRkxFTkJRVU03VVVGRFpqczdRVUZGUkN4clFrRkJZVHRqUVVGQkxIbENRVUZITzBGQlExb3NZVUZCU1N4UlFVRlJMRWRCUVVjc1NVRkJTU3hEUVVGRExFMUJRVTBzUjBGQlF5eERRVUZETEVOQlFVTTdRVUZETjBJc1lVRkJTU3hUUVVGVExFZEJRVWtzU1VGQlNTeERRVUZETEV0QlFVc3NTVUZCU1N4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFMUJRVTBzUjBGQlJ5eERRVUZETEVOQlFVY3NRMEZCUXp0QlFVTjRSQ3hwUWtGQlVTeEhRVUZITEVsQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1VVRkJVU3hGUVVGRExGTkJRVk1zUTBGQlF5eERRVUZETzBGQlEzaERMR0ZCUVVrc1NVRkJTU3hEUVVGRExHRkJRV0VzUlVGQlJUdEJRVU4wUWl4bFFVRkpMRk5CUVZNc1IwRkJTU3hKUVVGSkxFTkJRVU1zUzBGQlN5eEpRVUZKTEVsQlFVa3NRMEZCUXl4aFFVRmhMRU5CUVVNc1RVRkJUU3hIUVVGSExFTkJRVU1zUTBGQlJ5eERRVUZETzBGQlEyaEZMRzFDUVVGUkxFZEJRVWNzU1VGQlNTeERRVUZETEVkQlFVY3NRMEZCUXl4UlFVRlJMRVZCUVVNc1UwRkJVeXhEUVVGRExFTkJRVU03VlVGRGVrTTdRVUZEUkN4aFFVRkpMRTFCUVUwc1IwRkJSeXhUUVVGVExFZEJRVWNzU1VGQlNTeERRVUZETEV0QlFVc3NSMEZCUnl4TFFVRkxMRU5CUVVNN1FVRkROVU1zWlVGQlRTeEpRVUZKTEZWQlFWVXNSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFdEJRVXNzUTBGQlF6dEJRVU16UXl4bFFVRk5MRWxCUVVrc1YwRkJWeXhIUVVGRExFTkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNSMEZCUXl4UlFVRlJMRWxCUVVVc1EwRkJReXhIUVVGRExGTkJRVk1zUTBGQlF6dEJRVU42UkN4bFFVRk5MRWxCUVVrc2VVSkJRWGxDTEVOQlFVTTdRVUZEY0VNc1pVRkJUU3hKUVVGSkxIRkNRVUZ4UWl4RFFVRkRPMEZCUTJoRExHVkJRVTBzU1VGQlNTeDFRa0ZCZFVJc1EwRkJRenRCUVVOc1F5eGxRVUZOTEVsQlFVa3NiVUpCUVcxQ0xFTkJRVU03UVVGRE9VSXNaVUZCVFN4SlFVRkpMR0ZCUVdFc1EwRkJRenRCUVVONFFpeGxRVUZOTEVsQlFVa3NXVUZCV1N4SFFVRkhMRkZCUVZFc1IwRkJSeXhMUVVGTExFTkJRVU03UVVGRE1VTXNZVUZCU1N4RFFVRkRMRmRCUVZjc1EwRkJReXhMUVVGTExFTkJRVU1zVDBGQlR5eEhRVUZITEUxQlFVMHNRMEZCUXp0QlFVTjRReXhoUVVGSkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVOQlFVTTdVVUZEYWtJN08wRkJSVVFzVjBGQlRUdGpRVUZCTEd0Q1FVRkhPMEZCUTFBc1lVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVWQlFVVTdRVUZEWml4bFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFdEJRVXNzUTBGQlF5eGxRVUZsTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhKUVVGSkxFTkJRVU03UVVGRGRFUXNaVUZCU1N4RFFVRkRMRmRCUVZjc1EwRkJReXhMUVVGTExFTkJRVU1zUzBGQlN5eEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1NVRkJTU3hEUVVGRE8wRkJRMmhFTEdWQlFVa3NRMEZCUXl4WFFVRlhMRU5CUVVNc1UwRkJVeXhIUVVGSExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTTdWVUZEZWtNc1RVRkJUVHRCUVVOTUxHVkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNTMEZCU3l4RFFVRkRMR1ZCUVdVc1IwRkJSeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEUxQlFVMHNRMEZCUXp0QlFVTjRSQ3hsUVVGSkxFTkJRVU1zVjBGQlZ5eERRVUZETEV0QlFVc3NRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eEpRVUZKTEVOQlFVTTdRVUZEYUVRc1pVRkJTU3hKUVVGSkxFTkJRVU1zWVVGQllTeEZRVUZGTzBGQlEzUkNMR2xDUVVGSkxFTkJRVU1zVjBGQlZ5eERRVUZETEZOQlFWTXNSMEZCUnl4SlFVRkpMRU5CUVVNc1kwRkJZeXhEUVVGRE8xbEJRMnhFTEUxQlFVMDdRVUZEVEN4cFFrRkJTU3hEUVVGRExGZEJRVmNzUTBGQlF5eFRRVUZUTEVkQlFVY3NTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJRenRaUVVONlF6dFZRVU5HTzFGQlEwWTdPMEZCVlVjc2EwSkJRV0U3T3pzN096czdXVUZLUVN4WlFVRkhPMEZCUTJ4Q0xHZENRVUZQTEVsQlFVa3NRMEZCUXl4alFVRmpMRU5CUVVNN1VVRkROVUk3V1VGRlowSXNWVUZCUXl4SlFVRkpMRVZCUVVVN1FVRkRkRUlzWVVGQlNTeEpRVUZKTEVWQlFVVTdRVUZEVWl4bFFVRkpMRU5CUVVNc1NVRkJTU3hIUVVGSExGRkJRVkVzUTBGQlF6dFZRVU4wUWl4TlFVRk5PMEZCUTB3c1pVRkJTU3hEUVVGRExFbEJRVWtzUjBGQlJ5eFJRVUZSTEVOQlFVTTdWVUZEZEVJN1FVRkRSQ3hoUVVGSkxFTkJRVU1zWTBGQll5eEhRVUZITEVsQlFVa3NRMEZCUXp0QlFVTXpRaXhoUVVGSkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVOQlFVTTdVVUZEWmpzN1FVRlhSeXhUUVVGSk96czdPenM3TzFsQlNrRXNXVUZCUnp0QlFVTlVMR2RDUVVGUExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTTdVVUZEYmtJN1dVRkZUeXhWUVVGRExFbEJRVWtzUlVGQlJUdEJRVU5pTEdGQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRE8wRkJRMnhDTEdGQlFVa3NRMEZCUXl4aFFVRmhMRVZCUVVVc1EwRkJRenRCUVVOeVFpeGhRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1VVRkRaanM3T3p0VlFYQklhMElzVlVGQlZUdEpRVUZUTEdOQlFXTTdPMnRDUVVGcVF5eFZRVUZWTEVNN096czdPenRCUTJ4REwwSXNZVUZCV1N4RFFVRkRPenM3T3pzN096czdPenRCUVVkaUxFdEJRVWtzVTBGQlV5eEhRVUZITEcxQ1FVRlBMRU5CUVVNc1EwRkJiVUlzUTBGQlF5eERRVUZETzBGQlF6ZERMRXRCUVVrc1RVRkJUU3hIUVVGSExHMUNRVUZQTEVOQlFVTXNSVUZCYzBJc1EwRkJReXhEUVVGRE96czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPMHRCSzBKNFFpeFhRVUZYTzBGQlJXNUNMRmxCUmxFc1YwRkJWeXhIUVVWb1Fqc3lRa0ZHU3l4WFFVRlhPenRCUVVrMVFpeFRRVUZKTEU5QlFVOHNSMEZCUnl4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRE96dEJRVVY0UWl4VFFVRkpMRkZCUVZFc1IwRkJSenRCUVVOaUxHRkJRVkVzUTBGQlF5eEhRVUZITEVWQlFVTXNSVUZCUlN4RFFVRkRPMEZCUTJoQ0xIZENRVUZ0UWl4RFFVRkRPMEZCUTNCQ0xHVkJRVlVzUTBGQlF5eERRVUZETzAxQlEySXNRMEZCUXpzN1FVRkZSaXhuUTBGYWFVSXNWMEZCVnl3MlEwRlpkRUlzVTBGQlV5eEZRVUZETEU5QlFVOHNSVUZCUXl4UlFVRlJMRVZCUVVVN08wRkJSV3hETEZOQlFVa3NRMEZCUXl4UFFVRlBMRWRCUVVjc1JVRkJSU3hEUVVGRE8wRkJRMnhDTEZOQlFVa3NRMEZCUXl4blFrRkJaMElzUjBGQlJ5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMR1ZCUVdVc1EwRkJRenRCUVVOMFJDeFRRVUZKTEVOQlFVTXNUVUZCVFN4SFFVRkhMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zVFVGQlRTeERRVUZET3p0QlFVVnVReXhUUVVGSkxFTkJRVU1zU1VGQlNTeEZRVUZGTEVOQlFVTTdRVUZEV2l4VFFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRkxFTkJRVU03U1VGRlpqczdZVUZ5UW10Q0xGZEJRVmM3TzJkQ1FVRllMRmRCUVZjN1FVRjFRamxDTEdWQlFWVTdZMEZCUVN4elFrRkJSenRCUVVOWUxHRkJRVWtzUTBGQlF5eFBRVUZQTEVkQlFVY3NVVUZCVVN4RFFVRkRMR0ZCUVdFc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dEJRVU0zUXl4aFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExGZEJRVmNzUTBGQlF5eEpRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRU5CUVVNN1VVRkRka003TzBGQlJVUXNiVUpCUVdNN1kwRkJRU3d3UWtGQlJ6czdRVUZGWml4alFVRkxMRWxCUVVrc1EwRkJReXhIUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVkQlFVTXNTVUZCU1N4RFFVRkRMR2RDUVVGblFpeEZRVUZETEVOQlFVTXNSVUZCUlN4RlFVRkZPMEZCUTNoRExHVkJRVWtzVTBGQlV5eEhRVUZITEZGQlFWRXNRMEZCUXl4aFFVRmhMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03TzBGQlJTOURMR1ZCUVVrc1RVRkJUU3hIUVVGSExFbEJRVWtzVFVGQlRTeERRVUZETEZOQlFWTXNSVUZCUlR0QlFVTXZRaXhwUWtGQlNTeEZRVUZGTEZGQlFWRTdRVUZEWkN4elFrRkJVeXhGUVVGRkxFbEJRVWtzUlVGRGFFSXNSVUZCUlN4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFbEJRVWtzUTBGQlF5eEpRVUZKTEVWQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenM3UVVGRkwwSXNaVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdRVUZETVVJc1pVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eFhRVUZYTEVOQlFVTXNVMEZCVXl4RFFVRkRMRU5CUVVNN1ZVRkRja003VVVGRlJqczdRVUZGUkN4clFrRkJZVHRqUVVGQkxIbENRVUZIT3p0QlFVVmtMR0ZCUVVrc1YwRkJWeXhIUVVGSExFbEJRVWtzUTBGQlF5eExRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMR2RDUVVGblFpeERRVUZETzBGQlEzSkVMR0ZCUVVrc1dVRkJXU3hIUVVGSExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTTdPMEZCUlM5Q0xHTkJRVXNzU1VGQlNTeERRVUZETEVkQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zWjBKQlFXZENMRVZCUVVNc1EwRkJReXhGUVVGRkxFVkJRVVU3UVVGRGVFTXNaVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RlFVRkRMRmxCUVZrc1EwRkJReXhEUVVGRE8xVkJRMnhFTzFGQlJVWTdPMEZCUlVRc2JVSkJRV003WTBGQlFTd3dRa0ZCUnp0QlFVTm1MR05CUVVzc1NVRkJTU3hEUVVGRExFZEJRVU1zUTBGQlF5eEZRVUZETEVOQlFVTXNSMEZCUXl4SlFVRkpMRU5CUVVNc1owSkJRV2RDTEVWQlFVTXNRMEZCUXl4RlFVRkZMRVZCUVVVN1FVRkRlRU1zWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhOUVVGTkxFZEJRVWNzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXp0QlFVTnlReXhsUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE8xVkJRekZDTzFGQlEwWTdPMEZCUlVRc1YwRkJUVHRqUVVGQkxHZENRVUZETEV0QlFVc3NSVUZCUlR0QlFVTmFMR0ZCUVVrc1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4TFFVRkxMRVZCUVVVN1FVRkROMElzWlVGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenRWUVVOd1FpeE5RVUZOTzBGQlEwd3NaVUZCU1N4RFFVRkRMRkZCUVZFc1JVRkJSU3hEUVVGRE8xVkJRMnBDT3p0QlFVRkJMRkZCUlVZN08wRkJSVVFzVjBGQlRUdGpRVUZCTEd0Q1FVRkhPMEZCUTFBc1kwRkJTeXhKUVVGSkxFTkJRVU1zUjBGQlF5eERRVUZETEVWQlFVTXNRMEZCUXl4SFFVRkRMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zVFVGQlRTeEZRVUZETEVOQlFVTXNSVUZCUlN4RlFVRkZPMEZCUTNSRExHVkJRVWtzUTBGQlF5eExRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRVZCUVVVN1FVRkRia0lzYVVKQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMWxCUXk5Q0xFMUJRVTA3UVVGRFRDeHBRa0ZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eFBRVUZQTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1dVRkRhRU03VlVGRFJqdFJRVU5HT3p0QlFVMUVMRmRCUVUwN096czdPenM3WTBGQlFTeG5Ra0ZCUXl4TFFVRkxMRVZCUVVVN1FVRkRXaXhoUVVGSkxFdEJRVXNzU1VGQlJTeERRVUZETEVsQlFVa3NTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zVFVGQlRTeEZRVUZGTzBGQlF6TkRMR1ZCUVVrc1EwRkJReXhOUVVGTkxFZEJRVWNzUzBGQlN5eERRVUZETzBGQlEzQkNMR1ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeEZRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVOb1F5eGxRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1ZVRkRaanRSUVVOR096dEJRVXRFTEdGQlFWRTdPenM3T3p0alFVRkJMRzlDUVVGSE8wRkJRMVFzWVVGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOcVFpeGhRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdRVUZEYUVNc1lVRkJTU3hEUVVGRExFMUJRVTBzUlVGQlJTeERRVUZETzFGQlEyWTdPMEZCVlVjc2IwSkJRV1U3V1VGU1FTeFpRVUZITzBGQlEzQkNMR2RDUVVGUExFbEJRVWtzUTBGQlF5eG5Ra0ZCWjBJc1EwRkJRenRSUVVNNVFqczdPenM3TzFsQlRXdENMRlZCUVVNc1QwRkJUeXhGUVVGRk8wRkJRek5DTEdGQlFVa3NRMEZCUXl4blFrRkJaMElzUjBGQlJ5eFBRVUZQTEVOQlFVTTdRVUZEYUVNc1kwRkJTeXhKUVVGSkxFTkJRVU1zUjBGQlF5eERRVUZETEVWQlFVTXNRMEZCUXl4SFFVRkRMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zVFVGQlRTeEZRVUZETEVOQlFVTXNSVUZCUlN4RlFVRkZPMEZCUTNSRExHVkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1QwRkJUeXhGUVVGRkxFTkJRVU03VlVGRE0wSTdRVUZEUkN4aFFVRkpMRU5CUVVNc1QwRkJUeXhIUVVGSExFVkJRVVVzUTBGQlF6czdPenRCUVVsc1FpeGhRVUZKTEVOQlFVTXNTMEZCU3l4RlFVRkZMRU5CUVVNN1FVRkRZaXhoUVVGSkxFTkJRVU1zWTBGQll5eEZRVUZGTEVOQlFVTTdVVUZEZGtJN096czdWVUY2U0d0Q0xGZEJRVmM3U1VGQlV5eFRRVUZUT3p0clFrRkJOMElzVjBGQlZ5eERPenM3T3pzN1FVTnVRMmhETEdGQlFWa3NRMEZCUXpzN096czdPenM3T3p0QlFVVmlMRXRCUVVrc1UwRkJVeXhIUVVGSExHMUNRVUZQTEVOQlFVTXNRMEZCYlVJc1EwRkJReXhEUVVGRE8wRkJRemRETEV0QlFVa3NTVUZCU1N4SFFVRkhMRzFDUVVGUExFTkJRVU1zUlVGQlowSXNRMEZCUXl4RFFVRkRPMEZCUTNKRExFdEJRVWtzU1VGQlNTeEhRVUZITEcxQ1FVRlBMRU5CUVVNc1EwRkJZeXhEUVVGRExFTkJRVU03T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdTMEZ0UTJRc1RVRkJUVHRCUVVWa0xGbEJSbEVzVFVGQlRTeEhRVVZZT3pKQ1FVWkxMRTFCUVUwN08wRkJTWFpDTEZOQlFVa3NUMEZCVHl4SFFVRkhMRU5CUVVNc1QwRkJUeXhEUVVGRExFTkJRVU03TzBGQlJYaENMRk5CUVVrc1VVRkJVU3hIUVVGSE8wRkJRMklzWVVGQlVTeERRVUZETEVWQlFVVXNSVUZCUXl4RlFVRkZMRU5CUVVNN1FVRkRaaXhqUVVGVExFTkJRVU03UVVGRFZpeFpRVUZQTEVOQlFVTTdRVUZEVWl4WlFVRlBMRXRCUVVzN1FVRkRXaXhoUVVGUkxFTkJRVU03VFVGRFZpeERRVUZET3p0QlFVVkdMR2REUVdScFFpeE5RVUZOTERaRFFXTnFRaXhUUVVGVExFVkJRVU1zVDBGQlR5eEZRVUZETEZGQlFWRXNSVUZCUlRzN1FVRkZiRU1zVTBGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4SlFVRkpMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVkQlFVY3NSVUZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFZEJRVWNzUlVGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRWxCUVVrc1JVRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPenM3T3pzN08wRkJUMjVITEZOQlFVa3NRMEZCUXl4aFFVRmhMRWRCUVVjc1EwRkJReXhEUVVGRE8wRkJRM1pDTEZOQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1EwRkJReXhEUVVGRE96dEJRVVZvUWl4VFFVRkpMRU5CUVVNc1IwRkJSeXhIUVVGSExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNSMEZCUnl4RFFVRkRPenRCUVVVelFpeFRRVUZKTEVOQlFVTXNSMEZCUnl4SFFVRkhMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUjBGQlJ5eERRVUZET3p0QlFVVXpRaXhUUVVGSkxFTkJRVU1zU1VGQlNTeEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1NVRkJTU3hEUVVGRE96dEJRVVUzUWl4VFFVRkpMRU5CUVVNc1NVRkJTU3hGUVVGRkxFTkJRVU03UVVGRFdpeFRRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1NVRkZaanM3WVVGdVEydENMRTFCUVUwN08yZENRVUZPTEUxQlFVMDdRVUZ4UTNwQ0xHVkJRVlU3WTBGQlFTeHpRa0ZCUnp0QlFVTllMR0ZCUVVrc1EwRkJReXhQUVVGUExFZEJRVWNzVVVGQlVTeERRVUZETEdGQlFXRXNRMEZCUXl4UFFVRlBMRU5CUVVNc1EwRkJRenRCUVVNdlF5eGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRWxCUVVrc1IwRkJSeXhOUVVGTkxFTkJRVU03TzBGQlJUTkNMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1RVRkJUU3hGUVVGRkxHRkJRVms3UVVGRGFrUXNaVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhMUVVGTExFTkJRVU1zWlVGQlpTeEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1NVRkJTU3hEUVVGRE8wRkJRM1JFTEdWQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1MwRkJTeXhEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1EwRkJRenRCUVVNMVF5eGxRVUZKTEVsQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1MwRkJTeXhMUVVGTExFbEJRVWtzUTBGQlF5eExRVUZMTEVWQlFVVTdRVUZEY0VNc2FVSkJRVWtzUTBGQlF5eExRVUZMTEVkQlFVY3NWVUZCVlN4RFFVRkRMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZETlVNc2FVSkJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXp0WlFVTm9RanRWUVVOR0xFVkJRVU1zU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4RFFVRkRMRU5CUVVNN08wRkJSMklzWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4blFrRkJaMElzUTBGQlF5eFRRVUZUTEVWQlFVVXNWMEZCVlN4RFFVRkRMRVZCUVVVN1FVRkRja1FzWlVGQlNTeERRVUZETEVOQlFVTXNTMEZCU3l4SFFVRkhMRVZCUVVVc1NVRkJTU3hEUVVGRExFTkJRVU1zUzBGQlN5eEhRVUZITEVWQlFVVXNSVUZCUlR0QlFVTnFReXhwUWtGQlNTeERRVUZETEVOQlFVTXNTMEZCU3l4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExFTkJRVU1zUzBGQlN5eExRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMRU5CUVVNc1MwRkJTeXhMUVVGTExFTkJRVU1zUlVGQlJUdEJRVU40UkN4blFrRkJReXhEUVVGRExHTkJRV01zUlVGQlJTeERRVUZETzJOQlEyNUNPMWxCUTBRN1FVRkRSQ3hsUVVGSkxFTkJRVU1zUTBGQlF5eExRVUZMTEV0QlFVY3NSVUZCUlN4RlFVRkZPMEZCUTJwQ0xHbENRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRWxCUVVrc1JVRkJSU3hEUVVGRE8wRkJRMnhDTEdsQ1FVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNTMEZCU3l4RFFVRkRPMEZCUTJoRExHbENRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZETDBJc2FVSkJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXp0WlFVTm9RanRWUVVOR0xFVkJRVU1zU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4RFFVRkRMRU5CUVVNN08wRkJSV0lzWVVGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4WFFVRlhMRU5CUVVNc1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eERRVUZETzFGQlJYWkRPenRCUVVWRUxHdENRVUZoTzJOQlFVRXNlVUpCUVVjN08wRkJSV1FzWVVGQlNTeERRVUZETEdGQlFXRXNSMEZCUnl4SlFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVWQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRE96dEJRVVYwUkN4aFFVRkpMRTFCUVUwc1IwRkJSeXhUUVVGVExFZEJRVWNzU1VGQlNTeERRVUZETEV0QlFVc3NSMEZCUnl4TFFVRkxMRU5CUVVNN1FVRkROVU1zWlVGQlRTeEpRVUZKTEZWQlFWVXNSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFdEJRVXNzUTBGQlF6dEJRVU16UXl4bFFVRk5MRWxCUVVrc05FSkJRVFJDTEVOQlFVTTdRVUZEZGtNc1pVRkJUU3hKUVVGSkxHTkJRV01zUTBGQlF6dEJRVU42UWl4bFFVRk5MRWxCUVVrc2NVSkJRWEZDTEVOQlFVTTdRVUZEYUVNc1pVRkJUU3hKUVVGSkxHMUNRVUZ0UWl4RFFVRkRPMEZCUXpsQ0xHVkJRVTBzU1VGQlNTeFpRVUZaTEVkQlFVY3NTVUZCU1N4RFFVRkRMR0ZCUVdFc1IwRkJReXhEUVVGRExFZEJRVWNzUzBGQlN5eERRVUZET3p0QlFVVjBSQ3hsUVVGTkxFbEJRVWtzWlVGQlpTeERRVUZETzBGQlF6RkNMR1ZCUVUwc1NVRkJTU3huUWtGQlowSXNRMEZCUXp0QlFVTXpRaXhsUVVGTkxFbEJRVWtzVjBGQlZ5eEhRVUZETEVsQlFVa3NRMEZCUXl4aFFVRmhMRWRCUVVNc1EwRkJReXhIUVVGRExFdEJRVXNzUjBGQlF5eEpRVUZKTEVOQlFVTXNZVUZCWVN4SFFVRkRMRU5CUVVNc1IwRkJReXhMUVVGTExFTkJRVU03UVVGRE5VVXNaVUZCVFN4SlFVRkpMSGxDUVVGNVFpeERRVUZETzBGQlEzQkRMR1ZCUVUwc1NVRkJTU3h0UWtGQmJVSXNRMEZCUXp0QlFVTTVRaXhsUVVGTkxFbEJRVWtzYzBKQlFYTkNMRU5CUVVNN1FVRkRha01zWlVGQlRTeEpRVUZKTEhsQ1FVRjVRaXhEUVVGRE8wRkJRM0JETEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1MwRkJTeXhEUVVGRExFOUJRVThzU1VGQlNTeE5RVUZOTEVOQlFVTTdPenM3TzBGQlMzSkRMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eEhRVUZITEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNN1VVRkZha003TzBGQlJVUXNiVUpCUVdNN1kwRkJRU3d3UWtGQlJ6dEJRVU5pTEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1MwRkJTeXhEUVVGRExHVkJRV1VzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1EwRkJRenRCUVVOMFJDeGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1EwRkJReXhMUVVGTExFZEJRVWNzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SlFVRkpMRU5CUVVNN1VVRkRMME03TzBGQlJVUXNWMEZCVFR0alFVRkJMR3RDUVVGSE96dEJRVVZRTEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1JVRkJReXhKUVVGSkxFTkJRVU1zWVVGQllTeERRVUZETEVOQlFVTTdVVUZGYUVVN08wRkJSVVFzVlVGQlN6dGpRVUZCTEdsQ1FVRkhPMEZCUTA0c1lVRkJTU3hEUVVGRExGRkJRVkVzUjBGQlJ5eExRVUZMTEVOQlFVTTdRVUZEZEVJc1lVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eFJRVUZSTEVkQlFVY3NTVUZCU1N4RFFVRkRPMEZCUXpsQ0xHRkJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVY3NTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJRenRCUVVONFFpeGhRVUZKTEVOQlFVTXNUMEZCVHl4SFFVRkhMRVZCUVVVc1EwRkJReXhGUVVGRkxFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4RlFVRkZMRU5CUVVNN1FVRkRia01zWVVGQlNTeERRVUZETEZsQlFWa3NSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRkxFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVVVzUTBGQlF6dEJRVU0zUkN4blFrRkJUeXhEUVVGRExFZEJRVWNzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRU5CUVVNN1VVRkRhRU03TzBGQlJVUXNVMEZCU1R0alFVRkJMR2RDUVVGSE8wRkJRMHdzWVVGQlNTeERRVUZETEZGQlFWRXNSMEZCUnl4SlFVRkpMRU5CUVVNN1FVRkRja0lzWVVGQlNTeEpRVUZKTEVOQlFVTXNUMEZCVHl4RlFVRkZPenRCUVVWb1FpeGxRVUZKTEZGQlFWRXNSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFTkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eERRVUZETEV0QlFVMHNTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJSU3hKUVVGSkxFTkJRVU1zUjBGQlJ5eEhRVUZETEVsQlFVa3NRMEZCUXl4SFFVRkhMRVZCUVVVc1EwRkJReXhGUVVGRkxFbEJRVWtzUTBGQlJTeEhRVUZITEVkQlFVY3NRMEZCUlN4SFFVRkhMRWxCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zU1VGQlNTeERRVUZETEZsQlFWa3NSVUZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOcVNpeGxRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRkZCUVZFc1EwRkJRenM3UVVGRmVFSXNaVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE8wRkJRMW9zWlVGQlNTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTlCUVU4c1JVRkJSVHRCUVVOMlFpeHBRa0ZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFVkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMWxCUTJoRE8xVkJSVWc3VVVGRFJEczdRVUZGUkN4WlFVRlBPMk5CUVVFc2JVSkJRVWM3UVVGRFVpeGhRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1JVRkJSVHRCUVVOc1FpeGxRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRkZCUVZFc1IwRkJSeXhMUVVGTExFTkJRVU03UVVGRGFFTXNaVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhMUVVGTExFVkJRVVVzUTBGQlF6dEJRVU55UWl4bFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExHbENRVUZwUWl4RFFVRkRMRU5CUVVNc1JVRkJSU3hKUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEV0QlFVc3NRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVNM1JDeGxRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1EwRkJReXhsUVVGbExFZEJRVWNzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNN1FVRkRlRVFzWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4TFFVRkxMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTMEZCU3l4RFFVRkRPMVZCUXpWRExFMUJRVTA3UVVGRFRDeHRRa0ZCVVN4RFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFVkJRVVVzUTBGQlF6dFZRVU4yUWp0UlFVTkdPenRCUVU5RUxGTkJRVWs3T3pzN096czdPMk5CUVVFc1kwRkJReXhYUVVGWExFVkJRVVU3T3p0QlFVTm9RaXhoUVVGSkxFTkJRVU1zUjBGQlJ5eEhRVUZITEZkQlFWY3NRMEZCUXl4SFFVRkhMRU5CUVVNN1FVRkRNMElzWVVGQlNTeERRVUZETEVkQlFVY3NSMEZCUnl4WFFVRlhMRU5CUVVNc1IwRkJSeXhEUVVGRE8wRkJRek5DTEdGQlFVa3NRMEZCUXl4SlFVRkpMRWRCUVVjc1YwRkJWeXhEUVVGRExFbEJRVWtzUTBGQlF6dEJRVU0zUWl4dlFrRkJWeXhEUVVGRExFVkJRVVVzUTBGQlF5eFJRVUZSTEVWQlFVTXNWVUZCUXl4RFFVRkRMRVZCUVVzN1FVRkROMElzYVVKQlFVc3NZVUZCWVN4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8xVkJRM1pDTEVOQlFVTXNRMEZCUXp0QlFVTklMR0ZCUVVrc1EwRkJReXhGUVVGRkxFTkJRVU1zVVVGQlVTeEZRVUZETEZWQlFVTXNRMEZCUXl4RlFVRkxPMEZCUTNSQ0xITkNRVUZYTEVOQlFVTXNTMEZCU3l4SFFVRkhMRU5CUVVNc1EwRkJRenRWUVVOMlFpeERRVUZETEVOQlFVTTdRVUZEU0N4aFFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExGZEJRVmNzUTBGQlF5eExRVUZMTEVOQlFVTTdPenM3T3pzN096dFJRVk5vUXpzN1FVRkZSQ3hyUWtGQllUdGpRVUZCTEhWQ1FVRkRMRU5CUVVNc1JVRkJSVHRCUVVObUxHRkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRM1JDTEdGQlFVa3NRMEZCUXl4TlFVRk5MRVZCUVVVc1EwRkJRenRSUVVObU96dEJRVlZITEZWQlFVczdPenM3T3pzN08xbEJTRUVzV1VGQlJ6dEJRVU5XTEdkQ1FVRlBMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUzBGQlN5eERRVUZETzFGQlF6RkNPMWxCUTFFc1ZVRkJReXhEUVVGRExFVkJRVVU3UVVGRFdDeGhRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU4wUWl4aFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUlVGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1FVRkRMMElzWVVGQlNTeERRVUZETEUxQlFVMHNSVUZCUlN4RFFVRkRPMUZCUTJZN08wRkJWVWNzVVVGQlJ6czdPenM3T3pzN1dVRklRU3haUVVGSE8wRkJRMUlzWjBKQlFVOHNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhIUVVGSExFTkJRVU03VVVGRGVFSTdXVUZEVFN4VlFVRkRMRU5CUVVNc1JVRkJSVHRCUVVOVUxHRkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNSMEZCUnl4SFFVRkhMRU5CUVVNc1EwRkJRenRSUVVOeVFqczdRVUZWUnl4UlFVRkhPenM3T3pzN096dFpRVWhCTEZsQlFVYzdRVUZEVWl4blFrRkJUeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVkQlFVY3NRMEZCUXp0UlFVTjRRanRaUVVOTkxGVkJRVU1zUTBGQlF5eEZRVUZGTzBGQlExUXNZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhIUVVGSExFZEJRVWNzUTBGQlF5eERRVUZETzFGQlEzSkNPenRCUVZWSExGTkJRVWs3T3pzN096czdPMWxCU0VFc1dVRkJSenRCUVVOVUxHZENRVUZQTEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1NVRkJTU3hEUVVGRE8xRkJRM3BDTzFsQlEwOHNWVUZCUXl4RFFVRkRMRVZCUVVVN1FVRkRWaXhoUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVsQlFVa3NSMEZCUnl4RFFVRkRMRU5CUVVNN1VVRkRkRUk3T3pzN1ZVRXZUbXRDTEUxQlFVMDdTVUZCVXl4VFFVRlRPenRyUWtGQmVFSXNUVUZCVFN4RE96czdPenM3UVVOMlF6TkNMR0ZCUVZrc1EwRkJRenM3T3pzN096czdPenRCUVVWaUxFdEJRVWtzVTBGQlV5eEhRVUZITEcxQ1FVRlBMRU5CUVVNc1EwRkJiVUlzUTBGQlF5eERRVUZET3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN08wdEJaME40UWl4TlFVRk5PMEZCUldRc1dVRkdVU3hOUVVGTkxFZEJSVmc3TWtKQlJrc3NUVUZCVFRzN1FVRkpka0lzVTBGQlNTeFBRVUZQTEVkQlFVY3NRMEZCUXl4UFFVRlBMRU5CUVVNc1EwRkJRenM3UVVGRmVFSXNVMEZCU1N4UlFVRlJMRWRCUVVjN1FVRkRXaXhoUVVGUkxFTkJRVU1zUjBGQlJ5eEZRVUZETEVWQlFVVXNRMEZCUXp0QlFVTm9RaXhuUWtGQlZ5eERRVUZETEZOQlFWTXNSVUZCUXl4VFFVRlRMRU5CUVVNN1RVRkRiRU1zUTBGQlF6czdRVUZGUml4blEwRllhVUlzVFVGQlRTdzJRMEZYYWtJc1UwRkJVeXhGUVVGRExFOUJRVThzUlVGQlF5eFJRVUZSTEVWQlFVVTdPMEZCUld4RExGTkJRVWtzUTBGQlF5eGpRVUZqTEVkQlFVY3NRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRla0lzVTBGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4TFFVRkxMRU5CUVVNN08wRkJSWEJDTEZOQlFVa3NRMEZCUXl4UlFVRlJMRWRCUVVjc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eFBRVUZQTEVOQlFVTTdPMEZCUlhSRExGTkJRVWtzUTBGQlF5eEpRVUZKTEVWQlFVVXNRMEZCUXp0QlFVTmFMRk5CUVVrc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF6dEpRVVZtT3p0aFFYSkNhMElzVFVGQlRUczdaMEpCUVU0c1RVRkJUVHRCUVhWQ2VrSXNaVUZCVlR0alFVRkJMSE5DUVVGSE8wRkJRMWdzWVVGQlNTeERRVUZETEU5QlFVOHNSMEZCUnl4UlFVRlJMRU5CUVVNc1lVRkJZU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETzBGQlEyaEVMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eERRVUZETEZGQlFWRXNSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGRExFTkJRVU1zUjBGQlF5eEpRVUZKTEVOQlFVTTdRVUZEYWtRc1lVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eExRVUZMTEVOQlFVTXNUMEZCVHl4SFFVRkhMRTFCUVUwc1EwRkJRenRCUVVOd1F5eGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1EwRkJReXhUUVVGVExFZEJRVWNzVFVGQlRTeERRVUZETzBGQlEzUkRMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eERRVUZETEV0QlFVc3NSMEZCUnl4SlFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGRExFbEJRVWtzUTBGQlF6dEJRVU16UXl4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFdEJRVXNzUTBGQlF5eE5RVUZOTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1IwRkJReXhKUVVGSkxFTkJRVU03TzBGQlJUZERMR0ZCUVVrc1EwRkJReXhYUVVGWExFZEJRVWNzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SlFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFTkJRVU03TzBGQlJURkRMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1VVRkJVU3hGUVVGRkxFbEJRVWtzUTBGQlF5eFhRVUZYTEVOQlFVTXNRMEZCUXpzN1FVRkZNVVFzWVVGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4WFFVRlhMRU5CUVVNc1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eERRVUZETzFGQlJYWkRPenRCUVVWRUxHOUNRVUZsTzJOQlFVRXNNa0pCUVVjc1JVRkZha0k3TzBGQlJVUXNiVUpCUVdNN1kwRkJRU3d3UWtGQlJ6czdRVUZGWml4aFFVRkpMRU5CUVVNc1lVRkJZU3hGUVVGRkxFTkJRVU03VVVGRmRFSTdPMEZCUlVRc2JVSkJRV003WTBGQlFTd3dRa0ZCUnp0QlFVTm1MR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eERRVUZETEdWQlFXVXNSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFbEJRVWtzUTBGQlF6dEJRVU4wUkN4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFdEJRVXNzUTBGQlF5eExRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhKUVVGSkxFTkJRVU03UVVGRE5VTXNZVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhMUVVGTExFTkJRVU1zVFVGQlRTeEhRVUZITEZsQlFWa3NSMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExGZEJRVmNzUTBGQlF6dFJRVU5zUlRzN1FVRkZSQ3hYUVVGTk8yTkJRVUVzYTBKQlFVYzdPMEZCUlZBc1lVRkJTU3hEUVVGRExFMUJRVTBzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRTlCUVU4c1EwRkJReXhKUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEdGQlFXRXNRMEZCUXl4RFFVRkRMRWxCUVVrc1EwRkJRenRCUVVOd1JTeGhRVUZKTEVOQlFVTXNZMEZCWXl4SFFVRkhMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zWVVGQllTeERRVUZETzBGQlEycEVMR0ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeEZRVUZETzBGQlEycENMR2RDUVVGTExFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMDdRVUZEYkVJc1owSkJRVXNzUlVGQlJTeEpRVUZKTEVOQlFVTXNZMEZCWXp0VlFVTXpRaXhEUVVGRExFTkJRVU03VVVGRlNqczdRVUZGUkN4VlFVRkxPMk5CUVVFc2FVSkJRVWNzUlVGRlVEczdRVUZGUkN4VFFVRkpPMk5CUVVFc1owSkJRVWNzUlVGRlRqczdRVUZGUkN4WlFVRlBPMk5CUVVFc2JVSkJRVWNzUlVGRlZEczdRVUZQUkN4clFrRkJZVHM3T3pzN096dGpRVUZCTEhWQ1FVRkRMRTlCUVU4c1JVRkJSVHM3T3pzN096czdPenM3T3p0QlFXTnlRaXhoUVVGSkxFOUJRVThzUlVGQlJUdEJRVU5ZTEdWQlFVa3NRMEZCUXl4UlFVRlJMRWRCUVVjc1QwRkJUeXhEUVVGRE8xVkJRM3BDT3p0QlFVVkVMR05CUVVrc1NVRkJTU3hEUVVGRExFZEJRVU1zU1VGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4UFFVRlBMRU5CUVVNc1RVRkJUU3hIUVVGRExFTkJRVU1zUlVGQlJTeERRVUZETEVsQlFVa3NRMEZCUXl4RlFVRkZMRU5CUVVNc1JVRkJSU3hGUVVGRk8wRkJRM0JFTEdWQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzFWQlEzaENPenRCUVVWRUxHTkJRVWtzU1VGQlNTeERRVUZETEVkQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEUxQlFVMHNSVUZCUXl4RFFVRkRMRVZCUVVVc1JVRkJSVHRCUVVOMFF5eGxRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRTlCUVU4c1EwRkJReXhIUVVGSExFTkJRVU1zU1VGQlNTeE5RVUZOTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRExFTkJRVU1zUlVGQlJTeERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMVZCUXpORU8xRkJSVVk3TzBGQlYwY3NWVUZCU3pzN096czdPenM3V1VGSVFTeFpRVUZITzBGQlExWXNaMEpCUVU4c1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF6dFJRVU53UWp0WlFVTlJMRlZCUVVNc1EwRkJReXhGUVVGRk8wRkJRMWdzWVVGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4RFFVRkRMRU5CUVVNN1FVRkRhRUlzWTBGQlNTeEpRVUZKTEVOQlFVTXNSMEZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhIUVVGRExFbEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNUMEZCVHl4RFFVRkRMRTFCUVUwc1JVRkJReXhEUVVGRExFVkJRVVVzUlVGQlJUdEJRVU0zUXl4bFFVRkpMRU5CUVVNc1MwRkJTeXhKUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEU5QlFVOHNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhKUVVGSkxFVkJRVVU3UVVGRGRFTXNhVUpCUVVrc1EwRkJReXhoUVVGaExFZEJRVWNzUTBGQlF5eERRVUZETzBGQlEzWkNMRzFDUVVGTk8xbEJRMUE3VlVGRFJqdFJRVU5HT3p0QlFWZEhMR3RDUVVGaE96czdPenM3T3p0WlFVaEJMRmxCUVVjN1FVRkRiRUlzWjBKQlFVOHNTVUZCU1N4RFFVRkRMR05CUVdNc1EwRkJRenRSUVVNMVFqdFpRVU5uUWl4VlFVRkRMRU5CUVVNc1JVRkJSVHRCUVVOdVFpeGhRVUZKTEVOQlFVTXNZMEZCWXl4SFFVRkhMRU5CUVVNc1EwRkJRenRCUVVONFFpeGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMR0ZCUVdFc1IwRkJSeXhEUVVGRExFTkJRVU03UVVGREwwSXNZVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE8xRkJRMlk3TzBGQlJVUXNhMEpCUVdFN1kwRkJRU3g1UWtGQlJ6dEJRVU5rTEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc2JVSkJRVzFDTEVOQlFVTXNVVUZCVVN4RlFVRkZMRWxCUVVrc1EwRkJReXhYUVVGWExFTkJRVU1zUTBGQlF6dFJRVU01UkRzN096dFZRVzVLYTBJc1RVRkJUVHRKUVVGVExGTkJRVk03TzJ0Q1FVRjRRaXhOUVVGTkxFTTdPenM3T3p0QlEyeERNMElzWVVGQldTeERRVUZET3pzN096czdPenM3T3pzN1FVRkZZaXhMUVVGSkxFZEJRVWNzUjBGQlJ5eHRRa0ZCVHl4RFFVRkRMRU5CUVdFc1EwRkJReXhEUVVGRE8wRkJRMnBETEV0QlFVa3NTVUZCU1N4SFFVRkhMRzFDUVVGUExFTkJRVU1zUTBGQll5eERRVUZETEVOQlFVTTdRVUZEYmtNc1MwRkJTU3hUUVVGVExFZEJRVWNzYlVKQlFVOHNRMEZCUXl4RFFVRnRRaXhEUVVGRExFTkJRVU03UVVGRE4wTXNTMEZCU1N4SlFVRkpMRWRCUVVjc2JVSkJRVThzUTBGQlF5eEZRVUZuUWl4RFFVRkRMRU5CUVVNN08wdEJRM3BDTEZkQlFWY3NLME5CUVUwc1JVRkJjVUk3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN1MwRjNRemRDTEVsQlFVazdRVUZGV2l4WlFVWlJMRWxCUVVrc1IwRkZWRHN5UWtGR1N5eEpRVUZKT3p0QlFVbHlRaXhUUVVGSkxFOUJRVThzUjBGQlJ5eERRVUZETEV0QlFVc3NSVUZCUXl4TFFVRkxMRVZCUVVNc1QwRkJUeXhEUVVGRExFTkJRVU03TzBGQlJYQkRMRk5CUVVrc1VVRkJVU3hIUVVGSE8wRkJRMklzWVVGQlVTeERRVUZETEVWQlFVVXNSVUZCUXl4RlFVRkZMRU5CUVVNN1FVRkRaaXh2UWtGQlpTeFJRVUZSTzBGQlEzWkNMR0ZCUVZFc1ZVRkJWVHRCUVVOc1FpeFpRVUZQTEVOQlFVTTdRVUZEVWl4WlFVRlBMRU5CUVVNN1FVRkRVaXhoUVVGUkxFTkJRVU03UVVGRFZDeGpRVUZUTEVOQlFVTTdUVUZEV0N4RFFVRkRPenRCUVVWR0xHZERRV2hDYVVJc1NVRkJTU3cyUTBGblFtWXNVMEZCVXl4RlFVRkRMRTlCUVU4c1JVRkJReXhSUVVGUkxFVkJRVVU3TzBGQlJXeERMRk5CUVVrc1EwRkJReXhYUVVGWExFZEJRVWNzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4WFFVRlhMRU5CUVVNN08wRkJSVGRETEZOQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1NVRkJTU3hKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4SFFVRkhMRVZCUVVVc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eEhRVUZITEVWQlFVVXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhKUVVGSkxFVkJRVVVzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenM3UVVGRmRFY3NVMEZCU1N4RFFVRkRMRkZCUVZFc1IwRkJSeXhKUVVGSkxGZEJRVmNzUTBGQlF5eE5RVUZOTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhKUVVGSkxFVkJRVU1zU1VGQlNTeERRVUZETEZkQlFWY3NSVUZCUXl4RFFVRkRMRU5CUVVNc1JVRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVWQlFVTXNRMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdPMEZCUlROSExGTkJRVWtzUTBGQlF5eEpRVUZKTEVWQlFVVXNRMEZCUXpzN1FVRkZXaXhUUVVGSkxFTkJRVU1zUzBGQlN5eEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1MwRkJTeXhEUVVGRE96dEJRVVV2UWl4VFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRlZCUVZVc1EwRkJRenM3UVVGRk4wTXNVMEZCU1N4RFFVRkRMR0ZCUVdFc1IwRkJSeXhMUVVGTExFTkJRVU03TzBGQlJUTkNMRk5CUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeEZRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenRKUVVWb1F6czdZVUZzUTJ0Q0xFbEJRVWs3TzJkQ1FVRktMRWxCUVVrN1FVRnZRM1pDTEcxQ1FVRmpPMk5CUVVFc01FSkJRVWM3TzBGQlJXWXNZVUZCU1N4RFFVRkRMRlZCUVZVc1IwRkJSeXhIUVVGSExFTkJRVU1zVFVGQlRTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRPMEZCUTNaRExHRkJRVWtzUTBGQlF5eExRVUZMTEVkQlFVY3NSMEZCUnl4RFFVRkRMRTFCUVUwc1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF6dEJRVU5zUXl4aFFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFZEJRVWNzUTBGQlF5eE5RVUZOTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN1FVRkRha01zWVVGQlNTeERRVUZETEU5QlFVOHNSMEZCUnl4SFFVRkhMRU5CUVVNc1RVRkJUU3hEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETzBGQlEyeERMR0ZCUVVrc1EwRkJReXhWUVVGVkxFZEJRVWNzUjBGQlJ5eERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVOeVF5eGhRVUZKTEVOQlFVTXNWMEZCVnl4SFFVRkhMRWRCUVVjc1EwRkJReXhOUVVGTkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdRVUZEZEVNc1lVRkJTU3hEUVVGRExGVkJRVlVzUjBGQlJ5eEhRVUZITEVOQlFVTXNUVUZCVFN4RFFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRE96dEJRVVZ5UXl4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExGZEJRVmNzUTBGQlF5eEpRVUZKTEVOQlFVTXNWVUZCVlN4RFFVRkRMRU5CUVVNN1FVRkRNVU1zWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WFFVRlhMRU5CUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETzBGQlEzUkRMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zVjBGQlZ5eERRVUZETEVsQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1EwRkJRenRCUVVOMlF5eGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmRCUVZjc1EwRkJReXhKUVVGSkxFTkJRVU1zVlVGQlZTeERRVUZETEVOQlFVTTdRVUZETVVNc1lVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eFhRVUZYTEVOQlFVTXNTVUZCU1N4RFFVRkRMRmRCUVZjc1EwRkJReXhEUVVGRE8wRkJRek5ETEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1YwRkJWeXhEUVVGRExFbEJRVWtzUTBGQlF5eFZRVUZWTEVOQlFVTXNRMEZCUXp0QlFVTXhReXhoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZkQlFWY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03VVVGRmRFTTdPMEZCUjBRc2EwSkJRV0U3WTBGQlFTeDVRa0ZCUnpzN1FVRkZaQ3hoUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRMRU5CUVVNc1JVRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVWQlFVTXNRMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdPMEZCUlhKRUxHRkJRVWtzVFVGQlRTeEhRVUZITzBGQlExZ3NXVUZCUXl4RlFVRkZMRWxCUVVrc1EwRkJReXhMUVVGTExFZEJRVU1zUTBGQlF6dEJRVU5tTEZsQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGRExFTkJRVU03VlVGRGFrSXNRMEZCUXpzN1FVRkZSaXhoUVVGSkxGRkJRVkVzUjBGQlJ5eEpRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFVkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRPenRCUVVWb1JDeGhRVUZKTEVOQlFVTXNWVUZCVlN4RFFVRkRMRmxCUVZrc1EwRkJReXhKUVVGSkxFVkJRVVVzVFVGQlRTeERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXpkRExHRkJRVWtzUTBGQlF5eFZRVUZWTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWxCUVVrc1JVRkJSU3hOUVVGTkxFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZETjBNc1lVRkJTU3hEUVVGRExGVkJRVlVzUTBGQlF5eFpRVUZaTEVOQlFVTXNSMEZCUnl4RlFVRkZMRkZCUVZFc1IwRkJReXhEUVVGRExFZEJRVU1zVVVGQlVTeEhRVUZETEVWQlFVVXNRMEZCUXl4RFFVRkRPenRCUVVVeFJDeGhRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRmxCUVZrc1EwRkJReXhKUVVGSkxFVkJRVVVzVFVGQlRTeERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUTNoRExHRkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWxCUVVrc1JVRkJSU3hOUVVGTkxFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZEZUVNc1lVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eFpRVUZaTEVOQlFVTXNSMEZCUnl4RlFVRkZMRkZCUVZFc1IwRkJReXhGUVVGRkxFTkJRVU1zUTBGQlF6czdRVUZGTVVNc1lVRkJTU3hMUVVGTExFZEJRVWNzU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXpzN1FVRkZka0lzWVVGQlNTeFpRVUZaTEVkQlFVYzdRVUZEYWtJc1owSkJRVXNzUlVGQlJTeEpRVUZKTEVOQlFVTXNSVUZCUlN4SFFVRkRMRWRCUVVjN1FVRkRiRUlzWTBGQlJ5eEZRVUZGTEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVVc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eExRVUZMTEVWQlFVTXNRMEZCUXl4RlFVRkRMRWRCUVVjc1JVRkJReXhKUVVGSkxFTkJRVU1zUlVGQlJTeEhRVUZETEVkQlFVY3NSVUZCUXl4SlFVRkpMRU5CUVVNc1JVRkJSU3hIUVVGRExFZEJRVWNzUTBGQlF5eEZRVUZITEVsQlFVa3NRMEZCUXl4RlFVRkZMRWRCUVVNc1IwRkJSeXhGUVVGRkxFbEJRVWtzUTBGQlF5eEZRVUZGTEVkQlFVTXNSMEZCUnl4RFFVRkZPMVZCUXpkR0xFTkJRVU03UVVGRFJpeGhRVUZKTEdGQlFXRXNSMEZCUnp0QlFVTnNRaXhuUWtGQlN5eEZRVUZGTEVsQlFVa3NRMEZCUXl4RlFVRkZMRWRCUVVNc1IwRkJSenRCUVVOc1FpeGpRVUZITEVWQlFVVXNTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJSU3hKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEV0QlFVc3NSVUZCUXl4SFFVRkhMRVZCUVVNc1EwRkJReXhGUVVGRExFbEJRVWtzUTBGQlF5eEZRVUZGTEVkQlFVTXNSMEZCUnl4RlFVRkRMRWxCUVVrc1EwRkJReXhGUVVGRkxFZEJRVU1zUjBGQlJ5eERRVUZETEVWQlFVY3NTVUZCU1N4RFFVRkRMRVZCUVVVc1IwRkJReXhIUVVGSExFVkJRVVVzU1VGQlNTeERRVUZETEVWQlFVVXNSMEZCUXl4SFFVRkhMRU5CUVVVN1ZVRkROMFlzUTBGQlF6czdRVUZGUml4aFFVRkpMRlZCUVZVc1IwRkJSeXhIUVVGSExFTkJRVU1zUjBGQlJ5eERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRMRVZCUVVVc1RVRkJUU3hEUVVGRExFTkJRVU1zUlVGQlJTeFJRVUZSTEVkQlFVTXNRMEZCUXl4SFFVRkRMRkZCUVZFc1IwRkJReXhGUVVGRkxFVkJRVVVzV1VGQldTeERRVUZETEV0QlFVc3NSVUZCUlN4WlFVRlpMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU03UVVGRE0wY3NZVUZCU1N4WFFVRlhMRWRCUVVjc1IwRkJSeXhEUVVGRExFZEJRVWNzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXl4RlFVRkZMRTFCUVUwc1EwRkJReXhEUVVGRExFVkJRVVVzVVVGQlVTeEhRVUZETEVOQlFVTXNSMEZCUXl4UlFVRlJMRWRCUVVNc1JVRkJSU3hGUVVGRkxHRkJRV0VzUTBGQlF5eExRVUZMTEVWQlFVVXNZVUZCWVN4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE96dEJRVVU1Unl4aFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExGbEJRVmtzUTBGQlF5eEhRVUZITEVWQlFVTXNWVUZCVlN4RFFVRkRMRU5CUVVNN1FVRkRla01zWVVGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4WlFVRlpMRU5CUVVNc1kwRkJZeXhGUVVGRkxGRkJRVkVzUjBGQlF5eEZRVUZGTEVOQlFVTXNRMEZCUXp0QlFVTjBSQ3hoUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEZsQlFWa3NRMEZCUXl4TlFVRk5MRVZCUVVVc1RVRkJUU3hEUVVGRExFTkJRVU03TzBGQlJYcERMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zV1VGQldTeERRVUZETEVkQlFVY3NSVUZCUXl4WFFVRlhMRU5CUVVNc1EwRkJRenRCUVVNelF5eGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmxCUVZrc1EwRkJReXhqUVVGakxFVkJRVVVzVVVGQlVTeEhRVUZETEVWQlFVVXNRMEZCUXl4RFFVRkRPMEZCUTNaRUxHRkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hOUVVGTkxFTkJRVU1zUTBGQlF6czdRVUZGTVVNc2JVSkJRVlVzU1VGQlNTeExRVUZMTEVkQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNc1IwRkJReXhIUVVGSExFZEJRVU1zVFVGQlRTeERRVUZETEVOQlFVTXNRMEZCUXpzN1FVRkZNVU1zWVVGQlNTeERRVUZETEZWQlFWVXNRMEZCUXl4WlFVRlpMRU5CUVVNc1IwRkJSeXhGUVVGRExGVkJRVlVzUTBGQlF5eERRVUZETzBGQlF6ZERMR0ZCUVVrc1EwRkJReXhWUVVGVkxFTkJRVU1zV1VGQldTeERRVUZETEdOQlFXTXNSVUZCUlN4TFFVRkxMRU5CUVVNc1EwRkJRenM3UVVGRmNFUXNiMEpCUVZjc1NVRkJTU3hMUVVGTExFZEJRVU1zVFVGQlRTeERRVUZETEVOQlFVTXNSMEZCUXl4SFFVRkhMRWRCUVVNc1RVRkJUU3hEUVVGRExFTkJRVU1zUTBGQlF6czdRVUZGTTBNc1lVRkJTU3hEUVVGRExGZEJRVmNzUTBGQlF5eFpRVUZaTEVOQlFVTXNSMEZCUnl4RlFVRkRMRmRCUVZjc1EwRkJReXhEUVVGRE8wRkJReTlETEdGQlFVa3NRMEZCUXl4WFFVRlhMRU5CUVVNc1dVRkJXU3hEUVVGRExHTkJRV01zUlVGQlJTeExRVUZMTEVOQlFVTXNRMEZCUXpzN1FVRkZja1FzWVVGQlNTeFZRVUZWTEdGQlFVTTdRVUZEWml4aFFVRkpMRXRCUVVzc1IwRkJSeXhIUVVGSExFVkJRVVU3UVVGRFppeHhRa0ZCVlN4SFFVRkhMRmxCUVZrc1EwRkJReXhIUVVGSExFTkJRVU03VlVGREwwSXNUVUZCVFR0QlFVTk1MSEZDUVVGVkxFZEJRVWNzWVVGQllTeERRVUZETEVkQlFVY3NRMEZCUXp0VlFVTm9RenM3UVVGRlJDeGhRVUZKTEZWQlFWVXNSMEZCUnl4TlFVRk5MRU5CUVVNc1EwRkJReXhIUVVGSExFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNWVUZCVlN4RFFVRkRMRWxCUVVrc1VVRkJVU3hIUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzBGQlEyaEZMR0ZCUVVrc1ZVRkJWU3hIUVVGSExFMUJRVTBzUTBGQlF5eERRVUZETEVkQlFVY3NTVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhWUVVGVkxFTkJRVU1zU1VGQlNTeFJRVUZSTEVkQlFVTXNRMEZCUXl4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRExFTkJRVU03TzBGQlJYSkZMR0ZCUVVrc1EwRkJReXhWUVVGVkxFTkJRVU1zV1VGQldTeERRVUZETEVkQlFVY3NSVUZCUXl4SlFVRkpMRWRCUVVNc1RVRkJUU3hEUVVGRExFTkJRVU1zUjBGQlF5eEhRVUZITEVkQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNc1IwRkJReXhMUVVGTExFZEJRVU1zVlVGQlZTeEhRVUZETEVkQlFVY3NSMEZCUXl4VlFVRlZMRU5CUVVNc1EwRkJRenRCUVVNM1JpeGhRVUZKTEVOQlFVTXNWVUZCVlN4RFFVRkRMRmxCUVZrc1EwRkJReXhqUVVGakxFVkJRVVVzVVVGQlVTeEhRVUZETEVWQlFVVXNRMEZCUXl4RFFVRkRPMUZCUlRORU96dEJRVVZFTEcxQ1FVRmpPMk5CUVVFc01FSkJRVWM3UVVGRFppeGhRVUZKTEVOQlFVTXNWVUZCVlN4RFFVRkRMRmxCUVZrc1EwRkJReXhOUVVGTkxFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SlFVRkpMRU5CUVVNc1EwRkJRenRCUVVOMlJDeGhRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRmxCUVZrc1EwRkJReXhOUVVGTkxFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVOd1JDeGhRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRmxCUVZrc1EwRkJReXhSUVVGUkxFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVOMlJDeGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmxCUVZrc1EwRkJReXhSUVVGUkxFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVONFJDeGhRVUZKTEVOQlFVTXNWVUZCVlN4RFFVRkRMRmxCUVZrc1EwRkJReXhOUVVGTkxFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVONlJDeGhRVUZKTEVOQlFVTXNWMEZCVnl4RFFVRkRMRmxCUVZrc1EwRkJReXhOUVVGTkxFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVNeFJDeGhRVUZKTEVOQlFVTXNWVUZCVlN4RFFVRkRMRmxCUVZrc1EwRkJReXhSUVVGUkxFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRSUVVVMVJEczdRVUZGUkN4WFFVRk5PMk5CUVVFc2EwSkJRVWM3UVVGRFVDeGhRVUZKTEV0QlFVc3NSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExGVkJRVlVzUTBGQlF6czdRVUZGYmtNc1lVRkJTU3hOUVVGTkxFZEJRVWM3UVVGRFdDeFpRVUZETEVWQlFVVXNTVUZCU1N4RFFVRkRMRXRCUVVzc1IwRkJReXhEUVVGRE8wRkJRMllzV1VGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVNc1EwRkJRenRWUVVOcVFpeERRVUZET3p0QlFVVkdMR0ZCUVVrc1VVRkJVU3hIUVVGSExFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdPMEZCUldoRUxHRkJRVWtzV1VGQldTeEhRVUZITzBGQlEycENMR2RDUVVGTExFVkJRVVVzU1VGQlNTeERRVUZETEVWQlFVVXNSMEZCUXl4SFFVRkhPMEZCUTJ4Q0xHTkJRVWNzUlVGQlJTeEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkZMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUzBGQlN5eEZRVUZETEVOQlFVTXNSVUZCUXl4SFFVRkhMRVZCUVVNc1NVRkJTU3hEUVVGRExFVkJRVVVzUjBGQlF5eEhRVUZITEVWQlFVTXNTVUZCU1N4RFFVRkRMRVZCUVVVc1IwRkJReXhIUVVGSExFTkJRVU1zUlVGQlJ5eEpRVUZKTEVOQlFVTXNSVUZCUlN4SFFVRkRMRWRCUVVjc1JVRkJSU3hKUVVGSkxFTkJRVU1zUlVGQlJTeEhRVUZETEVkQlFVY3NRMEZCUlR0VlFVTTNSaXhEUVVGRE8wRkJRMFlzWVVGQlNTeGhRVUZoTEVkQlFVYzdRVUZEYkVJc1owSkJRVXNzUlVGQlJTeEpRVUZKTEVOQlFVTXNSVUZCUlN4SFFVRkZMRWRCUVVjN1FVRkRia0lzWTBGQlJ5eEZRVUZGTEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVVc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eExRVUZMTEVWQlFVTXNSMEZCUnl4RlFVRkRMRU5CUVVNc1JVRkJReXhKUVVGSkxFTkJRVU1zUlVGQlJTeEhRVUZETEVkQlFVY3NSVUZCUXl4SlFVRkpMRU5CUVVNc1JVRkJSU3hIUVVGRExFZEJRVWNzUTBGQlF5eEZRVUZITEVsQlFVa3NRMEZCUXl4RlFVRkZMRWRCUVVNc1IwRkJSeXhGUVVGRkxFbEJRVWtzUTBGQlF5eEZRVUZGTEVkQlFVTXNSMEZCUnl4RFFVRkZPMVZCUXpkR0xFTkJRVU03TzBGQlJVWXNZVUZCU1N4VlFVRlZMRWRCUVVjc1IwRkJSeXhEUVVGRExFZEJRVWNzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXl4RlFVRkZMRTFCUVUwc1EwRkJReXhEUVVGRExFVkJRVVVzVVVGQlVTeEhRVUZETEVOQlFVTXNSMEZCUXl4UlFVRlJMRWRCUVVNc1JVRkJSU3hGUVVGRkxGbEJRVmtzUTBGQlF5eExRVUZMTEVWQlFVVXNXVUZCV1N4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE8wRkJRek5ITEdGQlFVa3NWMEZCVnl4SFFVRkhMRWRCUVVjc1EwRkJReXhIUVVGSExFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTXNSVUZCUlN4TlFVRk5MRU5CUVVNc1EwRkJReXhGUVVGRkxGRkJRVkVzUjBGQlF5eERRVUZETEVkQlFVTXNVVUZCVVN4SFFVRkRMRVZCUVVVc1JVRkJSU3hoUVVGaExFTkJRVU1zUzBGQlN5eEZRVUZGTEdGQlFXRXNRMEZCUXl4SFFVRkhMRU5CUVVNc1EwRkJRenM3UVVGRk9VY3NZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhaUVVGWkxFTkJRVU1zUjBGQlJ5eEZRVUZETEZWQlFWVXNRMEZCUXl4RFFVRkRPMEZCUTNwRExHRkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWRCUVVjc1JVRkJReXhYUVVGWExFTkJRVU1zUTBGQlF6czdRVUZITTBNc2JVSkJRVlVzU1VGQlNTeExRVUZMTEVkQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNc1IwRkJReXhIUVVGSExFZEJRVU1zVFVGQlRTeERRVUZETEVOQlFVTXNRMEZCUXpzN1FVRkZNVU1zWVVGQlNTeERRVUZETEZWQlFWVXNRMEZCUXl4WlFVRlpMRU5CUVVNc1IwRkJSeXhGUVVGRExGVkJRVlVzUTBGQlF5eERRVUZET3p0QlFVVTNReXh2UWtGQlZ5eEpRVUZKTEV0QlFVc3NSMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJReXhIUVVGRExFZEJRVWNzUjBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXl4RFFVRkRPenRCUVVVelF5eGhRVUZKTEVOQlFVTXNWMEZCVnl4RFFVRkRMRmxCUVZrc1EwRkJReXhIUVVGSExFVkJRVU1zVjBGQlZ5eERRVUZETEVOQlFVTTdPMEZCUlM5RExHRkJRVWtzVlVGQlZTeGhRVUZETzBGQlEyWXNZVUZCU1N4TFFVRkxMRWxCUVVrc1IwRkJSeXhGUVVGRk8wRkJRMmhDTEhGQ1FVRlZMRWRCUVVjc1dVRkJXU3hEUVVGRExFZEJRVWNzUTBGQlF6dFZRVU12UWl4TlFVRk5PMEZCUTB3c2NVSkJRVlVzUjBGQlJ5eGhRVUZoTEVOQlFVTXNSMEZCUnl4RFFVRkRPMVZCUTJoRE96dEJRVVZFTEdGQlFVa3NWVUZCVlN4SFFVRkhMRTFCUVUwc1EwRkJReXhEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETEVkQlFVY3NRMEZCUXl4VlFVRlZMRU5CUVVNc1NVRkJTU3hSUVVGUkxFZEJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZEYUVVc1lVRkJTU3hWUVVGVkxFZEJRVWNzVFVGQlRTeERRVUZETEVOQlFVTXNSMEZCUnl4SlFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGVkJRVlVzUTBGQlF5eEpRVUZKTEZGQlFWRXNSMEZCUXl4RFFVRkRMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU1zUTBGQlF6czdRVUZGY2tVc1lVRkJTU3hEUVVGRExGVkJRVlVzUTBGQlF5eFpRVUZaTEVOQlFVTXNSMEZCUnl4RlFVRkRMRWxCUVVrc1IwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF5eEhRVUZETEVkQlFVY3NSMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJReXhIUVVGRExFdEJRVXNzUjBGQlF5eFZRVUZWTEVkQlFVTXNSMEZCUnl4SFFVRkRMRlZCUVZVc1EwRkJReXhEUVVGRE8xRkJSVGxHT3p0QlFVZEVMRlZCUVVzN1kwRkJRU3hwUWtGQlJ6dEJRVU5PTEdGQlFVa3NTVUZCU1N4RFFVRkRMRWxCUVVrc1MwRkJSeXhWUVVGVkxFVkJRVVU3UVVGRE1VSXNaVUZCU1N4RFFVRkRMR0ZCUVdFc1IwRkJSeXhMUVVGTExFTkJRVU03VlVGRE5VSTdRVUZEUkN4aFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFMUJRVTBzUjBGQlJ5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRPMEZCUTJ4RExHRkJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVlVGQlZTeERRVUZETzBGQlF6ZERMR0ZCUVVrc1EwRkJReXhKUVVGSkxFVkJRVVVzUTBGQlF6dFJRVU5hT3p0QlFVVkdMRk5CUVVrN1kwRkJRU3huUWtGQlJ6dEJRVU5NTEdGQlFVa3NTVUZCU1N4RFFVRkRMRTlCUVU4c1JVRkJSVHM3UVVGRmFFSXNaVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhOUVVGTkxFTkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPenRCUVVWcVF5eGxRVUZKTEV0QlFVc3NSMEZCUnl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUjBGQlF5eEpRVUZKTEVOQlFVTXNSVUZCUlN4SFFVRkRMRU5CUVVNc1EwRkJRenM3UVVGRk1VTXNaVUZCU1N4TFFVRkxMRWRCUVVjc1EwRkJReXhGUVVGSE8wRkJRVVVzYTBKQlFVc3NTVUZCU3l4SlFVRkpMRU5CUVVNc1JVRkJSU3hIUVVGRExFTkJRVVVzUTBGQlF6dFpRVUZGT3p0QlFVVjZReXhsUVVGSkxFbEJRVWtzUTBGQlF5eEpRVUZKTEV0QlFVc3NWVUZCVlN4RlFVRkZPMEZCUXpWQ0xHbENRVUZKTEVsQlFVa3NRMEZCUXl4aFFVRmhMRXRCUVVzc1MwRkJTeXhKUVVGSkxFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNTVUZCU1N4RFFVRkRMR0ZCUVdFc1IwRkJSeXhMUVVGTExFTkJRVU1zUjBGQlJ5eERRVUZETEVWQlFVVTdRVUZETlVVc2JVSkJRVWtzU1VGQlNTeERRVUZETEdGQlFXRXNSMEZCUnl4RFFVRkRMRVZCUVVVN1FVRkRNVUlzYzBKQlFVc3NSMEZCUnl4SlFVRkpMRU5CUVVNc1JVRkJSU3hIUVVGRExFTkJRVU1zUTBGQlF6dG5Ra0ZEYmtJc1RVRkJUVHRCUVVOTUxITkNRVUZMTEVkQlFVY3NRMEZCUXl4RFFVRkRPMmRDUVVOWU8yTkJRMFk3V1VGRFJqczdPenM3T3pzN08wRkJVMFFzWlVGQlNTeERRVUZETEdGQlFXRXNSMEZCUnl4TFFVRkxMRU5CUVVNN08wRkJSVE5DTEdWQlFVa3NVMEZCVXl4SFFVRkhMRXRCUVVzc1NVRkJTU3hKUVVGSkxFTkJRVU1zUlVGQlJTeEhRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPenRCUVVWd1F5eGxRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zV1VGQldTeERRVUZGTEZOQlFWTXNRMEZCUlN4RFFVRkRPenRCUVVWdVJDeGxRVUZKTEVsQlFVa3NRMEZCUXl4SlFVRkpMRXRCUVVzc1ZVRkJWU3hGUVVGRk8wRkJRelZDTEdsQ1FVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUjBGQlJ5eFRRVUZUTEVOQlFVTTdXVUZEYWtNN08wRkJSVVFzWlVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRVZCUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXpzN1FVRkZkRU1zWlVGQlNTeERRVUZETEUxQlFVMHNSVUZCUlN4RFFVRkRPMVZCUldZN1VVRkRSanM3UVVGRlJDeFpRVUZQTzJOQlFVRXNiVUpCUVVjc1JVRkRWRHM3UVVFd1Frc3NWVUZCU3pzN096czdPenM3T3pzN096czdPenM3T3pzN096dFpRVWhCTEZsQlFVYzdRVUZEVml4blFrRkJUeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXp0UlFVTXhRanRaUVVOUkxGVkJRVU1zUTBGQlF5eEZRVUZGTzBGQlExZ3NZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZEZEVJc1lVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eExRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhWUVVGVkxFTkJRVU03UVVGRE4wTXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFVkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenRCUVVOMFF5eGhRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1VVRkRaanM3UVVGVlJ5eFJRVUZIT3pzN096czdPenRaUVVoQkxGbEJRVWM3UVVGRFVpeG5Ra0ZCVHl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFZEJRVWNzUTBGQlF6dFJRVU40UWp0WlFVTk5MRlZCUVVNc1EwRkJReXhGUVVGRk8wRkJRMVFzWVVGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SFFVRkhMRWRCUVVjc1EwRkJReXhEUVVGRE8xRkJRM0pDT3p0QlFWVkhMRkZCUVVjN096czdPenM3TzFsQlNFRXNXVUZCUnp0QlFVTlNMR2RDUVVGUExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNSMEZCUnl4RFFVRkRPMUZCUTNoQ08xbEJRMDBzVlVGQlF5eERRVUZETEVWQlFVVTdRVUZEVkN4aFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFZEJRVWNzUjBGQlJ5eERRVUZETEVOQlFVTTdVVUZEY2tJN08wRkJWVWNzVTBGQlNUczdPenM3T3pzN1dVRklRU3haUVVGSE8wRkJRMVFzWjBKQlFVOHNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhKUVVGSkxFTkJRVU03VVVGRGVrSTdXVUZEVHl4VlFVRkRMRU5CUVVNc1JVRkJSVHRCUVVOV0xHRkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTVUZCU1N4SFFVRkhMRU5CUVVNc1EwRkJRenRSUVVOMFFqczdRVUZWUnl4VFFVRkpPenM3T3pzN096dFpRVWhCTEZsQlFVYzdRVUZEVkN4blFrRkJUeXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVsQlFVa3NRMEZCUXp0UlFVTXpRanRaUVVOUExGVkJRVU1zUTBGQlF5eEZRVUZGTzBGQlExWXNZVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhKUVVGSkxFZEJRVWNzUTBGQlF5eERRVUZETzFGQlEzaENPenRCUVZsRExHVkJRVlU3T3pzN096czdPMWxCU2tFc1dVRkJSenRCUVVObUxHZENRVUZQTEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1ZVRkJWU3hEUVVGRE8xRkJReTlDTzFsQlJXRXNWVUZCUXl4RFFVRkRMRVZCUVVVN1FVRkRhRUlzWVVGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4WlFVRlpMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRE5VSXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFVkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMUZCUTJoRE96czdPMVZCTVZWclFpeEpRVUZKTzBsQlFWTXNVMEZCVXpzN2EwSkJRWFJDTEVsQlFVa3NRenM3T3pzN08wRkRPVU42UWl4aFFVRlpMRU5CUVVNN096czdPenM3T3pzN1FVRkZZaXhMUVVGSkxFZEJRVWNzUjBGQlJ5eHRRa0ZCVHl4RFFVRkRMRU5CUVdFc1EwRkJReXhEUVVGRE8wRkJRMnBETEV0QlFVa3NVMEZCVXl4SFFVRkhMRzFDUVVGUExFTkJRVU1zUTBGQmJVSXNRMEZCUXl4RFFVRkRPMEZCUXpkRExFdEJRVWtzWTBGQll5eEhRVUZITEcxQ1FVRlBMRU5CUVVNc1JVRkJPRUlzUTBGQlF5eERRVUZETzBGQlF6ZEVMRXRCUVVrc1MwRkJTeXhIUVVGSExHMUNRVUZQTEVOQlFVTXNRMEZCWlN4RFFVRkRMRU5CUVVNN08wdEJSUzlDTEZGQlFWRTdRVUZGUkN4WlFVWlFMRkZCUVZFc1IwRkZSVHN5UWtGR1ZpeFJRVUZST3p0QlFVbFdMRk5CUVVrc1QwRkJUeXhIUVVGSExFTkJRVU1zVDBGQlR5eEZRVUZETEUxQlFVMHNSVUZCUXl4UFFVRlBMRU5CUVVNc1EwRkJRenM3UVVGRmRrTXNVMEZCU1N4UlFVRlJMRWRCUVVjN1FVRkRZaXhoUVVGUkxFTkJRVU1zUlVGQlJTeEZRVUZETEVWQlFVVXNRMEZCUXp0QlFVTm1MR1ZCUVZVc1MwRkJTenRCUVVObUxHRkJRVkVzVVVGQlVUdEJRVU5vUWl4alFVRlRMRU5CUVVNN1RVRkRXQ3hEUVVGRE96dEJRVVZHTEdkRFFXSkZMRkZCUVZFc05rTkJZVW9zVTBGQlV5eEZRVUZETEU5QlFVOHNSVUZCUXl4UlFVRlJMRVZCUVVVN08wRkJSV3hETEZOQlFVa3NRMEZCUXl4SlFVRkpMRWRCUVVjc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eEpRVUZKTEVOQlFVTTdRVUZETDBJc1UwRkJTU3hEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRXRCUVVzc1EwRkJRenM3UVVGRmFrTXNVMEZCU1N4RFFVRkRMRTFCUVUwc1IwRkJSenRCUVVOYUxGVkJRVXNzVFVGQlRUdEJRVU5ZTEZWQlFVc3NUVUZCVFN4RlFVTmFMRU5CUVVNN08wRkJSVVlzVTBGQlNTeERRVUZETEVsQlFVa3NSVUZCUlN4RFFVRkRPMEZCUTFvc1UwRkJTU3hEUVVGRExFMUJRVTBzUlVGQlJTeERRVUZETzBsQlJXWTdPMkZCTVVKSExGRkJRVkU3TzJkQ1FVRlNMRkZCUVZFN1FVRTBRbG9zWlVGQlZUdGpRVUZCTEhOQ1FVRkhPMEZCUTFnc1lVRkJTU3hEUVVGRExFOUJRVThzUjBGQlJ5eEhRVUZITEVOQlFVTXNUVUZCVFN4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8wRkJRMnBETEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1dVRkJXU3hEUVVGRExFOUJRVThzUlVGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1FVRkRPVU1zWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0QlFVTm9SQ3hoUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEZkQlFWY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFTkJRVU03VVVGRGRrTTdPMEZCUlVRc2JVSkJRV003WTBGQlFTd3dRa0ZCUnpzN08wRkJSV1lzWVVGQlNTeERRVUZETEVkQlFVY3NSMEZCUnl4SFFVRkhMRU5CUVVNc1RVRkJUU3hEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZET3p0QlFVVTVRaXhoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZkQlFWY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU03TzBGQlJXNURMR0ZCUVVrc1EwRkJReXhwUWtGQmFVSXNSMEZCUnl4SlFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRE96czdPMEZCU1d4RExHRkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNUVUZCVFN4RlFVRkZPenRCUVVWcVFpeGxRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRmxCUVUwN08wRkJSV3BDTEcxQ1FVRkxMRXRCUVVzc1EwRkJReXhYUVVGWExFZEJRVWNzU1VGQlNTeERRVUZETzBGQlF6bENMRzFDUVVGTExFdEJRVXNzUTBGQlF5eFZRVUZWTEVkQlFVY3NRMEZCUXl4TlFVRkxMRXRCUVVzc1EwRkJRenRCUVVOd1F5eHRRa0ZCU3l4SlFVRkpMRU5CUVVNc1RVRkJTeXhMUVVGTExFTkJRVU1zVlVGQlZTeERRVUZETEVOQlFVTTdXVUZEYkVNc1EwRkJRenM3UVVGRlJpeGxRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMR2RDUVVGblFpeERRVUZETEZkQlFWY3NSVUZCUlN4WlFVRk5PMEZCUXpORExHbENRVUZKTEUxQlFVc3NTMEZCU3l4RFFVRkRMRmRCUVZjc1JVRkJSVHM3UVVGRk1VSXNjVUpCUVVzc1NVRkJTU3hEUVVGRExFMUJRVXNzUzBGQlN5eERRVUZETEZWQlFWVXNRMEZCUXl4RFFVRkRPMk5CUTJ4RE8xbEJRMFlzUTBGQlF5eERRVUZET3p0QlFVZElMR1ZCUVVrc1EwRkJReXhKUVVGSkxFZEJRVWNzV1VGQlRUdEJRVU5vUWl4cFFrRkJTU3hOUVVGTExFdEJRVXNzUTBGQlF5eFhRVUZYTEVWQlFVVTdPMEZCUlRGQ0xIRkNRVUZMTEVsQlFVa3NSVUZCUlN4RFFVRkRPMk5CUTJJN1dVRkRSaXhEUVVGRE96dEJRVWRHTEdWQlFVa3NRMEZCUXl4UFFVRlBMRWRCUVVjc1dVRkJUVHRCUVVOdVFpeHRRa0ZCU3l4TFFVRkxMRU5CUVVNc1YwRkJWeXhIUVVGSExFdEJRVXNzUTBGQlF6czdPMWxCUjJoRExFTkJRVU03UVVGRFJpeGxRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMR2RDUVVGblFpeERRVUZETEZOQlFWTXNSVUZCUlN4WlFVRk5PMEZCUTNwRExHbENRVUZKTEUxQlFVc3NTMEZCU3l4RFFVRkRMRmRCUVZjc1JVRkJSVHM3UVVGRk1VSXNjVUpCUVVzc1JVRkJSU3hGUVVGRkxFTkJRVU03WTBGRFdEdFpRVU5HTEVOQlFVTXNRMEZCUXp0QlFVTklMR1ZCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1ZVRkJWU3hGUVVGRkxGbEJRVTA3UVVGRE1VTXNhVUpCUVVrc1RVRkJTeXhMUVVGTExFTkJRVU1zVjBGQlZ5eEZRVUZGT3p0QlFVVXhRaXh4UWtGQlN5eEZRVUZGTEVWQlFVVXNRMEZCUXp0alFVTllPMWxCUTBZc1EwRkJReXhEUVVGRE8xVkJSVW83VVVGRlJqczdRVUZGUkN4clFrRkJZVHRqUVVGQkxIbENRVUZIT3pzN1FVRkhWaXhoUVVGSkxFMUJRVTBzUjBGQlJ5eERRVUZETEVOQlFVTTdPMEZCUldZc1lVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eFpRVUZaTEVOQlFVTXNSMEZCUnl4RlFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE8wRkJReTlDTEdGQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFZEJRVWNzUlVGQlF5eEhRVUZITEVOQlFVTXNRMEZCUXp0QlFVTXZRaXhoUVVGSkxFbEJRVWtzUTBGQlF5eExRVUZMTEVkQlFVY3NRMEZCUXl4RlFVRkZPMEZCUTJ4Q0xHVkJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNXVUZCV1N4RFFVRkRMRTlCUVU4c1JVRkJSU3hKUVVGSkxFTkJRVU1zUzBGQlN5eEhRVUZITEVOQlFVTXNRMEZCUXl4RFFVRkRPMVZCUTJoRUxFMUJRVTA3UVVGRFRDeGxRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhQUVVGUExFVkJRVVVzU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMVZCUXpWRE8wRkJRMFFzWVVGQlNTeEpRVUZKTEVOQlFVTXNUVUZCVFN4SFFVRkhMRU5CUVVNc1JVRkJSVHRCUVVOdVFpeGxRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhSUVVGUkxFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRPMVZCUXpsRExFMUJRVTA3UVVGRFRDeGxRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhSUVVGUkxFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRPMVZCUXpsRE8wRkJRMFFzWVVGQlNTeERRVUZETEVkQlFVY3NRMEZCUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hGUVVGRkxFMUJRVTBzUTBGQlF5eERRVUZETzBGQlEzQkRMR0ZCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zV1VGQldTeERRVUZETEVsQlFVa3NSVUZCUlN4TlFVRk5MRU5CUVVNc1EwRkJRenRSUVVWNlF6czdRVUZGUkN4WFFVRk5PMk5CUVVFc2EwSkJRVWM3UVVGRFVDeGhRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1JVRkJSVHRCUVVObUxHVkJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNXVUZCV1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJReXhEUVVGRE8xVkJRM2hFTEUxQlFVMDdRVUZEVEN4bFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eE5RVUZOTEVWQlFVVXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dFZRVU51UkR0UlFVTkdPenM3TzFWQmVFaEhMRkZCUVZFN1NVRkJVeXhqUVVGak96czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenRMUVRCS2FFSXNTMEZCU3p0QlFVVmlMRmxCUmxFc1MwRkJTeXhIUVVWV096SkNRVVpMTEV0QlFVczdPMEZCU1hSQ0xGTkJRVWtzVDBGQlR5eEhRVUZITEVOQlFVTXNUMEZCVHl4RFFVRkRMRU5CUVVNN08wRkJSWGhDTEZOQlFVa3NVVUZCVVN4SFFVRkhPMEZCUTJJc1lVRkJVU3hEUVVGRExFZEJRVWNzUlVGQlF5eEhRVUZITEVOQlFVTTdRVUZEYWtJc1owSkJRVmNzUlVGQlJUdEJRVU5pTEdsQ1FVRlpMRVZCUVVVN1FVRkRaQ3hoUVVGUkxGRkJRVkU3VFVGRGFrSXNRMEZCUXpzN1FVRkZSaXhuUTBGaWFVSXNTMEZCU3l3MlEwRmhhRUlzVTBGQlV5eEZRVUZETEU5QlFVOHNSVUZCUXl4UlFVRlJMRVZCUVVVN08wRkJSV3hETEZOQlFVa3NRMEZCUXl4VlFVRlZMRWRCUVVjc1EwRkJReXhIUVVGSExFVkJRVU1zUjBGQlJ5eEZRVUZETEVkQlFVY3NSVUZCUXl4SFFVRkhMRVZCUVVNc1IwRkJSeXhGUVVGRExFZEJRVWNzUlVGQlF5eEhRVUZITEVWQlFVTXNSMEZCUnl4RlFVRkRMRWRCUVVjc1JVRkJReXhIUVVGSExFVkJRVU1zUjBGQlJ5eEZRVUZETEVkQlFVY3NRMEZCUXl4RFFVRkRPenRCUVVWd1JTeFRRVUZKTEVOQlFVTXNWVUZCVlN4SFFVRkhMRXRCUVVzc1EwRkJRenM3UVVGRmVFSXNVMEZCU1N4RFFVRkRMRWxCUVVrc1IwRkJSeXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVsQlFVa3NRMEZCUXpzN1FVRkZMMElzVTBGQlNTeERRVUZETEV0QlFVc3NSMEZCUnp0QlFVTllMRlZCUVVjc1JVRkJSU3hKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEU5QlFVODdRVUZETVVJc1YwRkJTU3hGUVVGRkxFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNVVUZCVVR0TlFVTTNRaXhEUVVGRE96dEJRVVZHTEZOQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1NVRkJTU3hIUVVGSExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNTVUZCU1N4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUjBGQlJ5eERRVUZET3p0QlFVVnVSQ3hUUVVGSkxFTkJRVU1zU1VGQlNTeEhRVUZITEVWQlFVVXNRMEZCUXpzN1FVRkZaaXhUUVVGSkxFTkJRVU1zVVVGQlVTeEhRVUZITEV0QlFVc3NRMEZCUXpzN1FVRkZkRUlzVTBGQlNTeERRVUZETEVsQlFVa3NSVUZCUlN4RFFVRkRPMEZCUTFvc1UwRkJTU3hEUVVGRExFMUJRVTBzUlVGQlJTeERRVUZETzBsQlJXWTdPMkZCYmtOclFpeExRVUZMT3p0blFrRkJUQ3hMUVVGTE8wRkJjVU40UWl4bFFVRlZPMk5CUVVFc2MwSkJRVWM3UVVGRFdDeGhRVUZKTEVOQlFVTXNUMEZCVHl4SFFVRkhMRkZCUVZFc1EwRkJReXhoUVVGaExFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZETjBNc1lVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eExRVUZMTEVOQlFVTXNVVUZCVVN4SFFVRkhMRlZCUVZVc1EwRkJRenRCUVVONlF5eGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1EwRkJReXhaUVVGWkxFZEJRVWNzUzBGQlN5eERRVUZETzBGQlEzaERMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eERRVUZETEU5QlFVOHNSMEZCUnl4UFFVRlBMRU5CUVVNN1FVRkRja01zWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4TFFVRkxMRU5CUVVNc1MwRkJTeXhIUVVGSExFMUJRVTBzUTBGQlF6dEJRVU5zUXl4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFdEJRVXNzUTBGQlF5eE5RVUZOTEVkQlFVY3NUVUZCVFN4RFFVRkRPMEZCUTI1RExHRkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUTBGQlF6dFJRVU4yUXpzN1FVRkZSQ3h0UWtGQll6dGpRVUZCTERCQ1FVRkhPenRCUVVWbUxHRkJRVWtzUTBGQlF5eEpRVUZKTEVkQlFVY3NSVUZCUlN4RFFVRkRPenRCUVVWbUxHTkJRVXNzU1VGQlNTeERRVUZETEVkQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVsQlFVa3NSMEZCUnl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFZEJRVWNzUlVGQlF5eERRVUZETEVWQlFVVXNSVUZCUlRzN1FVRkZia1FzWlVGQlNTeFRRVUZUTEVkQlFVY3NVVUZCVVN4RFFVRkRMR0ZCUVdFc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dEJRVU12UXl4bFFVRkpMRlZCUVZVc1IwRkJSeXhEUVVGRExFTkJRVU1zUjBGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRWRCUVVjc1NVRkJTU3hKUVVGSkxFTkJRVU1zVlVGQlZTeERRVUZETEUxQlFVMHNRMEZCUXpzN1FVRkZOMFFzWlVGQlNTeEhRVUZITEVkQlFVY3NTVUZCU1N4UlFVRlJMRU5CUVVNc1UwRkJVeXhGUVVGRk8wRkJRemxDTEhOQ1FVRlRMRVZCUVVVc1NVRkJTVHRCUVVObUxHbENRVUZKTEVWQlFVVXNRMEZCUXl4SFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUjBGQlJ6dEJRVU4wUWl4clFrRkJTeXhGUVVGRkxFbEJRVWtzUTBGQlF5eFZRVUZWTEVOQlFVTXNWVUZCVlN4RFFVRkRPMEZCUTJ4RExHbENRVUZKTEVWQlFVVXNTVUZCU1N4RFFVRkRMRWxCUVVrN1dVRkRhRUlzUlVGQlJTeEpRVUZKTEVOQlFVTXNVMEZCVXl4RFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFVkJRVU1zUTBGQlF5eEhRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU1zUTBGQlF6czdRVUZGYWtRc1kwRkJSeXhEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTTdPMEZCUldwQ0xHVkJRVWtzUzBGQlN5eERRVUZETEUxQlFVMHNSVUZCUlR0QlFVTm9RaXhuUWtGQlJ5eERRVUZETEVkQlFVY3NRMEZCUXl4TFFVRkxMRWRCUVVjc1EwRkJReXhEUVVGRE8wRkJRMnhDTEdkQ1FVRkhMRU5CUVVNc1VVRkJVU3hIUVVGSExFZEJRVWNzUTBGQlF5eFBRVUZQTEVkQlFVY3NSMEZCUnl4RFFVRkRMRlZCUVZVc1IwRkJSeXhaUVVGTkxFVkJRVVVzUTBGQlF6dEJRVU4yUkN4blFrRkJSeXhEUVVGRExFdEJRVXNzUjBGQlJ5eEhRVUZITEVOQlFVTXNTVUZCU1N4SFFVRkhMRWRCUVVjc1EwRkJReXhQUVVGUExFZEJRVWNzV1VGQlRTeEZRVUZGTEVOQlFVTTdRVUZET1VNc1owSkJRVWNzUTBGQlF5eFJRVUZSTEVkQlFVY3NSMEZCUnl4RFFVRkRMRmxCUVZrc1IwRkJSeXhIUVVGSExFTkJRVU1zWlVGQlpTeEhRVUZITEZsQlFVMHNSVUZCUlN4RFFVRkRPMEZCUTJwRkxHZENRVUZITEVOQlFVTXNTMEZCU3l4SFFVRkhMRWRCUVVjc1EwRkJReXhUUVVGVExFZEJRVWNzUjBGQlJ5eERRVUZETEZsQlFWa3NSMEZCUnl4WlFVRk5MRVZCUVVVc1EwRkJRenRaUVVONlJEczdRVUZGUkN4bFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNRMEZCUXp0QlFVTndRaXhsUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZkQlFWY3NRMEZCUXl4VFFVRlRMRU5CUVVNc1EwRkJRenRWUVVWeVF6dEJRVU5FTEdGQlFVa3NTMEZCU3l4RFFVRkRMRTFCUVUwc1JVRkJSVHRCUVVOb1FpeGxRVUZKTEVOQlFVTXNhVUpCUVdsQ0xFVkJRVVVzUTBGQlF6dFZRVU14UWp0UlFVVkdPenRCUVVWRUxHdENRVUZoTzJOQlFVRXNlVUpCUVVjN08wRkJSV1FzWVVGQlNTeEpRVUZKTEVkQlFVY3NRMEZCUXl4RFFVRkRPenRCUVVWaUxHRkJRVWtzV1VGQldTeEhRVUZITEVWQlFVVXNRMEZCUXpzN1FVRkZkRUlzWTBGQlN5eEpRVUZKTEVOQlFVTXNSMEZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhIUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNTVUZCU1N4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUjBGQlJ5eEZRVUZETEVOQlFVTXNSVUZCUlN4RlFVRkZPenRCUVVWdVJDeDFRa0ZCV1N4RFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUTBGQlF6czdRVUZGZUVJc1pVRkJTU3hWUVVGVkxFZEJRVWNzUTBGQlF5eERRVUZETEVkQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhIUVVGSExFbEJRVWtzU1VGQlNTeERRVUZETEZWQlFWVXNRMEZCUXl4TlFVRk5MRU5CUVVNN1FVRkROMFFzWlVGQlNTeGpRVUZqTEVkQlFVY3NRMEZCUXl4RFFVRkRMRWRCUVVNc1EwRkJReXhIUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNSMEZCUnl4SlFVRkpMRWxCUVVrc1EwRkJReXhWUVVGVkxFTkJRVU1zVFVGQlRTeERRVUZETzBGQlEyNUZMR1ZCUVVrc1EwRkJReXhIUVVGRExFTkJRVU1zUjBGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRWRCUVVjc1NVRkJTU3hKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVsQlFVa3NSVUZCUlR0QlFVTjZReXhwUWtGQlNTeEpRVUZKTEVOQlFVTXNRMEZCUXp0WlFVTllMRTFCUVUwc1NVRkJTU3hKUVVGSkxFTkJRVU1zVlVGQlZTeERRVUZETEZWQlFWVXNRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hKUVVGSkxFTkJRVU1zVlVGQlZTeERRVUZETEdOQlFXTXNRMEZCUXl4TFFVRkxMRWRCUVVjc1JVRkJSVHRCUVVONlJpeHBRa0ZCU1N4SlFVRkpMRU5CUVVNc1EwRkJRenRaUVVOWUxFMUJRVTA3UVVGRFRDeHBRa0ZCU1N4SlFVRkpMRWRCUVVjc1EwRkJRenRaUVVOaU8xVkJRMFk3UVVGRFJDeGhRVUZKTEZGQlFWRXNSMEZCUnl4SlFVRkpMRU5CUVVNN096dEJRVWx3UWl4aFFVRkpMRTlCUVU4c1IwRkJSeXhEUVVGRExFTkJRVU03UVVGRGFFSXNZVUZCU1N4WFFVRlhMRWRCUVVjc1EwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eEhRVUZETEU5QlFVOHNSMEZCUXl4RFFVRkRMRWxCUVVrc1VVRkJVU3hEUVVGRE8wRkJRM0JFTEdGQlFVa3NXVUZCV1N4SFFVRkhMRU5CUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUjBGQlF5eFBRVUZQTEVkQlFVTXNRMEZCUXl4SlFVRkpMRU5CUVVNc1EwRkJRenM3UVVGRkwwTXNZMEZCU3l4SlFVRkpMRU5CUVVNc1IwRkJReXhEUVVGRExFVkJRVU1zUTBGQlF5eEhRVUZETEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRExFTkJRVU1zUlVGQlJTeEZRVUZGT3p0QlFVVnVReXhsUVVGSkxGTkJRVk1zUjBGQlJ5eEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExFMUJRVTBzUTBGQlF6dEJRVU53UXl4dlFrRkJVeXhEUVVGRExFdEJRVXNzUTBGQlF5eFJRVUZSTEVkQlFVY3NWVUZCVlN4RFFVRkRPMEZCUTNSRExHOUNRVUZUTEVOQlFVTXNTMEZCU3l4RFFVRkRMRWxCUVVrc1IwRkJTU3haUVVGWkxFTkJRVU1zUTBGQlF5eERRVUZETEVkQlFVTXNWMEZCVnl4SFFVRkRMRTlCUVU4c1IwRkJTU3hKUVVGSkxFTkJRVU03UVVGRGNFVXNaVUZCU1N4SlFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEV0QlFVc3NTMEZCU3l4SFFVRkhMRVZCUVVVN1FVRkRPVUlzYzBKQlFWTXNRMEZCUXl4TFFVRkxMRU5CUVVNc1IwRkJSeXhIUVVGSkxFOUJRVThzUjBGQlNTeEpRVUZKTEVOQlFVTTdRVUZEZGtNc2FVSkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1RVRkJUU3hEUVVGRExGZEJRVmNzUlVGQlJTeFpRVUZaTEVkQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1dVRkRiRVFzVFVGQlRUdEJRVU5NTEhOQ1FVRlRMRU5CUVVNc1MwRkJTeXhEUVVGRExFMUJRVTBzUjBGQlJ5eERRVUZETEVOQlFVTTdRVUZETTBJc2MwSkJRVk1zUTBGQlF5eExRVUZMTEVOQlFVTXNSMEZCUnl4SFFVRkhMRTlCUVU4c1IwRkJReXhKUVVGSkxFTkJRVU03UVVGRGJrTXNhVUpCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNUVUZCVFN4RFFVRkRMRmRCUVZjc1JVRkJSU3haUVVGWkxFZEJRVU1zUjBGQlJ5eERRVUZETEVOQlFVTTdXVUZEY0VRN1ZVRkZSanRSUVVWR096dEJRVVZFTEcxQ1FVRmpPMk5CUVVFc01FSkJRVWM3T3pzN1FVRkpaaXhoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEV0QlFVc3NRMEZCUXl4bFFVRmxMRWRCUVVjc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eFhRVUZYTEVOQlFVTTdPMEZCUlRkRUxHTkJRVXNzU1VGQlNTeERRVUZETEVkQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNSVUZCUXl4RFFVRkRMRVZCUVVVc1JVRkJSVHRCUVVOdVF5eGxRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExFMUJRVTBzUjBGQlJ6dEJRVU53UWl4blFrRkJTeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVczdRVUZEZEVJc1owSkJRVXNzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SlFVRkpPMEZCUTNKQ0xIRkNRVUZWTEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1RVRkJUVHRCUVVNMVFpeHhRa0ZCVlN4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExGZEJRVmM3V1VGRGJFTXNRMEZCUXp0QlFVTkdMR1ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNZMEZCWXl4RlFVRkZMRU5CUVVNN1FVRkRPVUlzWlVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF6dFZRVU4yUWp0UlFVZEdPenRCUVVWRUxHTkJRVk03WTBGQlFTeHRRa0ZCUXl4SlFVRkpMRVZCUVVNc1JVRkJSU3hGUVVGRk96czdPenRCUVV0cVFpeGhRVUZKTEVsQlFVa3NSMEZCUnp0QlFVTlVMR1ZCUVVrc1JVRkJSU3hKUVVGSk8xVkJRMWdzUTBGQlF6dEJRVU5HTEdGQlFVa3NUMEZCVHl4RlFVRkZMRXRCUVVzc1VVRkJVU3hGUVVGRk8wRkJRekZDTEdWQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1JVRkJSU3hEUVVGRExFdEJRVXNzUTBGQlF6czdPMVZCUjNaQ0xFMUJRVTA3UVVGRFRDeGxRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRVZCUVVVc1EwRkJRenRWUVVOcVFqdEJRVU5FTEdGQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eERRVUZETzFGQlF6RkNPenRCUVZORUxGZEJRVTA3T3pzN096czdPenRqUVVGQkxHdENRVUZITEVWQlJWSTdPMEZCUjBRc2MwSkJRV2xDTzJOQlFVRXNOa0pCUVVjN096dEJRVVZzUWl4aFFVRkpMRU5CUVVNc1VVRkJVU3hIUVVGSExFbEJRVWtzUTBGQlF5eFBRVUZQTEVkQlFVY3NTVUZCU1N4RFFVRkRMRlZCUVZVc1IwRkJSeXhaUVVGTkxFVkJRVVVzUTBGQlF6dEJRVU14UkN4aFFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eEpRVUZKTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTlCUVU4c1IwRkJSeXhaUVVGTkxFVkJRVVVzUTBGQlF6dEJRVU5xUkN4aFFVRkpMRU5CUVVNc1VVRkJVU3hIUVVGSExFbEJRVWtzUTBGQlF5eFpRVUZaTEVkQlFVY3NTVUZCU1N4RFFVRkRMR1ZCUVdVc1IwRkJSeXhaUVVGTkxFVkJRVVVzUTBGQlF6dEJRVU53UlN4aFFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eFRRVUZUTEVkQlFVY3NTVUZCU1N4RFFVRkRMRmxCUVZrc1IwRkJSeXhaUVVGTkxFVkJRVVVzUTBGQlF6czdRVUZGTTBRc1lVRkJTU3hEUVVGRExHTkJRV01zUjBGQlJ5eExRVUZMTEVOQlFVTTdPMEZCUlRWQ0xHRkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNaMEpCUVdkQ0xFTkJRVU1zV1VGQldTeEZRVUZGTEZWQlFVTXNRMEZCUXl4RlFVRkxPMEZCUTJwRUxHdENRVUZQTEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhEUVVGRE8wRkJRekZDTEdWQlFVa3NUMEZCVHl4SFFVRkhMRkZCUVZFc1EwRkJReXhuUWtGQlowSXNRMEZCUXl4RFFVRkRMRU5CUVVNc1lVRkJZU3hEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEU5QlFVOHNSVUZCUXl4RFFVRkRMRU5CUVVNc1lVRkJZU3hEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEU5QlFVOHNRMEZCUXl4RFFVRkRPMEZCUXk5R0xHVkJRVWtzUjBGQlJ5eEhRVUZITEUxQlFVc3NTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dEJRVU51UXl4cFFrRkJTeXhWUVVGVkxFZEJRVWNzUTBGQlF5eEhRVUZITEVOQlFVTXNTMEZCU3l4RFFVRkRPMEZCUXpkQ0xHTkJRVWNzUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCU3l4VlFVRlZMRU5CUVVNc1EwRkJRenRCUVVNeFFpeHBRa0ZCU3l4alFVRmpMRWRCUVVjc1QwRkJUeXhEUVVGRExFdEJRVXNzUTBGQlF6dEJRVU53UXl4WlFVRkRMRU5CUVVNc1kwRkJZeXhGUVVGRkxFTkJRVU03UVVGRGJrSXNXVUZCUXl4RFFVRkRMR1ZCUVdVc1JVRkJSU3hEUVVGRE8xVkJRM0pDTEVOQlFVTXNRMEZCUXpzN1FVRkZTQ3hoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEdkQ1FVRm5RaXhEUVVGRExGZEJRVmNzUlVGQlJTeFZRVUZETEVOQlFVTXNSVUZCU3p0QlFVTm9SQ3hsUVVGSkxFOUJRVThzUjBGQlJ5eFJRVUZSTEVOQlFVTXNaMEpCUVdkQ0xFTkJRVU1zUTBGQlF5eERRVUZETEdGQlFXRXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhQUVVGUExFVkJRVU1zUTBGQlF5eERRVUZETEdGQlFXRXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhQUVVGUExFTkJRVU1zUTBGQlF6dEJRVU12Uml4bFFVRkpMRWRCUVVjc1IwRkJSeXhOUVVGTExFbEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1FVRkRia01zWlVGQlNTeFBRVUZQTEVOQlFVTXNTMEZCU3l4TFFVRkhMRTFCUVVzc1kwRkJZeXhGUVVGRk8wRkJRM1pETEdsQ1FVRkpMRTFCUVVzc1kwRkJZeXhGUVVGRk8wRkJRM1pDTEcxQ1FVRkpMRTlCUVU4c1IwRkJSeXhOUVVGTExFbEJRVWtzUTBGQlF5eE5RVUZMTEdOQlFXTXNRMEZCUXl4RFFVRkRPMEZCUXpkRExITkNRVUZQTEVOQlFVTXNSVUZCUlN4RlFVRkZMRU5CUVVNN1kwRkRaRHRCUVVORUxHZENRVUZITEVOQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVVzc1ZVRkJWU3hEUVVGRExFTkJRVU03V1VGRE0wSXNUVUZCVFR0QlFVTk1MR2RDUVVGSExFTkJRVU1zU1VGQlNTeEZRVUZGTEVOQlFVTTdXVUZEV2p0QlFVTkVMR2xDUVVGTExHTkJRV01zUjBGQlJ5eFBRVUZQTEVOQlFVTXNTMEZCU3l4RFFVRkRPMEZCUTNCRExGbEJRVU1zUTBGQlF5eGpRVUZqTEVWQlFVVXNRMEZCUXp0QlFVTnVRaXhaUVVGRExFTkJRVU1zWlVGQlpTeEZRVUZGTEVOQlFVTTdWVUZEY2tJc1EwRkJReXhEUVVGRE96dEJRVVZJTEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1owSkJRV2RDTEVOQlFVTXNWVUZCVlN4RlFVRkZMRlZCUVVNc1EwRkJReXhGUVVGTE96dEJRVVV2UXl4bFFVRkpMRWRCUVVjc1IwRkJSeXhOUVVGTExFbEJRVWtzUTBGQlF5eE5RVUZMTEdOQlFXTXNRMEZCUXl4RFFVRkRPMEZCUTNwRExHTkJRVWNzUTBGQlF5eEZRVUZGTEVWQlFVVXNRMEZCUXp0QlFVTlVMR2xDUVVGTExGZEJRVmNzUjBGQlJ5eExRVUZMTEVOQlFVTTdRVUZEZWtJc2FVSkJRVXNzWTBGQll5eEhRVUZITEV0QlFVc3NRMEZCUXp0QlFVTTFRaXhaUVVGRExFTkJRVU1zWTBGQll5eEZRVUZGTEVOQlFVTTdRVUZEYmtJc1dVRkJReXhEUVVGRExHVkJRV1VzUlVGQlJTeERRVUZETzFWQlEzSkNMRU5CUVVNc1EwRkJRenRSUVVWS096dEJRVTlFTEdGQlFWRTdPenM3T3pzN08yTkJRVUVzYTBKQlFVTXNSMEZCUnl4RlFVRkRMRWxCUVVrc1JVRkJSVHRCUVVOcVFpeGhRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRWRCUVVjc1IwRkJSeXhIUVVGSExFTkJRVU03UVVGRGNrSXNZVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhKUVVGSkxFZEJRVWNzU1VGQlNTeERRVUZETzBGQlEzWkNMR0ZCUVVrc1EwRkJReXhMUVVGTExFVkJRVVVzUTBGQlF6dEJRVU5pTEdGQlFVa3NRMEZCUXl4alFVRmpMRVZCUVVVc1EwRkJRenRSUVVOMlFqczdRVUZQUkN4alFVRlRPenM3T3pzN096dGpRVUZCTEcxQ1FVRkRMRWxCUVVrc1JVRkJSU3hGUVVGRkxFVkJRVVU3UVVGRGJFSXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFZEJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4SFFVRkhMRU5CUVVNc1EwRkJReXhKUVVGSkxFTkJRVU1zUlVGQlJTeERRVUZETEVOQlFVTTdVVUZEZWtNN08wRkJUMFFzWjBKQlFWYzdPenM3T3pzN08yTkJRVUVzY1VKQlFVTXNTMEZCU3l4RlFVRkZMRVZCUVVVc1JVRkJSVHRCUVVOeVFpeGhRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRExFbEJRVWtzUTBGQlF5eEZRVUZGTEVOQlFVTXNRMEZCUXp0UlFVTXpRanM3T3p0VlFXaFJhMElzUzBGQlN6dEpRVUZUTEZOQlFWTTdPMnRDUVVGMlFpeExRVUZMT3pzN096czdPenRCUTJwTE1VSXNZVUZCV1N4RFFVRkRPenM3T3pzN096czdPMEZCUldJc1MwRkJTU3hIUVVGSExFZEJRVWNzYlVKQlFVOHNRMEZCUXl4RFFVRmhMRU5CUVVNc1EwRkJRenRCUVVOcVF5eExRVUZKTEVkQlFVY3NSMEZCUnl4dFFrRkJUeXhEUVVGRExFTkJRV0VzUTBGQlF5eERRVUZETzBGQlEycERMRXRCUVVrc1UwRkJVeXhIUVVGSExHMUNRVUZQTEVOQlFVTXNRMEZCYlVJc1EwRkJReXhEUVVGRE8wRkJRemRETEV0QlFVa3NZMEZCWXl4SFFVRkhMRzFDUVVGUExFTkJRVU1zUlVGQk9FSXNRMEZCUXl4RFFVRkRPMEZCUXpkRUxFdEJRVWtzVjBGQlZ5eEhRVUZITEcxQ1FVRlBMRU5CUVVNc1JVRkJhMElzUTBGQlF5eERRVUZETzBGQlF6bERMRXRCUVVrc1dVRkJXU3hIUVVGSExHMUNRVUZQTEVOQlFVTXNSVUZCYlVJc1EwRkJReXhEUVVGRE8wRkJRMmhFTEV0QlFVa3NTMEZCU3l4SFFVRkhMRzFDUVVGUExFTkJRVU1zUTBGQlpTeERRVUZETEVOQlFVTTdPMHRCU1M5Q0xGVkJRVlU3UVVGRlNDeFpRVVpRTEZWQlFWVXNSMEZGUVRzeVFrRkdWaXhWUVVGVk96dEJRVWxhTEZOQlFVa3NUMEZCVHl4SFFVRkhMRU5CUVVNc1QwRkJUeXhEUVVGRkxFTkJRVU03TzBGQlJYcENMRk5CUVVrc1VVRkJVU3hIUVVGSE8wRkJRMklzWVVGQlVTeERRVUZETEVWQlFVVXNSVUZCUXl4RlFVRkZMRU5CUVVNN1FVRkRaaXhsUVVGVkxFdEJRVXM3UVVGRFppeGhRVUZSTEZGQlFWRTdRVUZEYUVJc1kwRkJVeXhEUVVGRE8wMUJRMWdzUTBGQlF6czdRVUZGUml4blEwRmlSU3hWUVVGVkxEWkRRV0ZPTEZOQlFWTXNSVUZCUXl4UFFVRlBMRVZCUVVNc1VVRkJVU3hGUVVGRk96dEJRVVZzUXl4VFFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNTMEZCU3l4RFFVRkRPMEZCUTJwRExGTkJRVWtzUTBGQlF5eEhRVUZITEVkQlFVY3NTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhIUVVGSExFTkJRVU03UVVGRE4wSXNVMEZCU1N4RFFVRkRMRTFCUVUwc1IwRkJSeXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEUxQlFVMHNRMEZCUXpzN1FVRkZia01zVTBGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFMUJRVTBzUTBGQlF6czdRVUZGYmtNc1UwRkJTU3hEUVVGRExGZEJRVmNzUjBGQlJ5eExRVUZMTEVOQlFVTTdRVUZEZWtJc1UwRkJTU3hEUVVGRExGVkJRVlVzUjBGQlJ5eExRVUZMTEVOQlFVTTdPMEZCUlhoQ0xGTkJRVWtzUTBGQlF5eEpRVUZKTEVWQlFVVXNRMEZCUXp0QlFVTmFMRk5CUVVrc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF6dEpRVVZtT3p0aFFUTkNSeXhWUVVGVk96dG5Ra0ZCVml4VlFVRlZPMEZCTmtKa0xHVkJRVlU3WTBGQlFTeHpRa0ZCUnp0QlFVTllMR0ZCUVVrc1EwRkJReXhQUVVGUExFZEJRVWNzUjBGQlJ5eERRVUZETEUxQlFVMHNRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenRCUVVOcVF5eGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmxCUVZrc1EwRkJReXhQUVVGUExFVkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUXpsRExHRkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdRVUZEYUVRc1lVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eExRVUZMTEVOQlFVTXNSMEZCUnl4SFFVRkhMRXRCUVVzc1EwRkJRenRCUVVNdlFpeGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1EwRkJReXhKUVVGSkxFZEJRVWNzUzBGQlN5eERRVUZETzBGQlEyaERMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eERRVUZETEZGQlFWRXNSMEZCUnl4VlFVRlZMRU5CUVVNN1FVRkRla01zWVVGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4WFFVRlhMRU5CUVVNc1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eERRVUZETzFGQlEzWkRPenRCUVVWRUxHMUNRVUZqTzJOQlFVRXNNRUpCUVVjN096dEJRVVZtTEdGQlFVa3NRMEZCUXl4SFFVRkhMRWRCUVVjc1IwRkJSeXhEUVVGRExFMUJRVTBzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0QlFVTTVRaXhoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZkQlFWY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU03TzBGQlJXNURMR0ZCUVVrc1EwRkJReXhwUWtGQmFVSXNSMEZCUnl4SlFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRE96czdPMEZCU1d4RExHRkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNUVUZCVFN4RlFVRkZPenRCUVVWcVFpeGxRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRmxCUVUwN1FVRkRha0lzYlVKQlFVc3NUVUZCVFN4RFFVRkRMRmRCUVZjc1IwRkJSeXhKUVVGSkxFTkJRVU03UVVGREwwSXNiVUpCUVVzc1RVRkJUU3hEUVVGRExGVkJRVlVzUjBGQlJ5eERRVUZETEUxQlFVc3NTMEZCU3l4RFFVRkRPMEZCUTNKRExHMUNRVUZMTEVsQlFVa3NRMEZCUXl4TlFVRkxMRTFCUVUwc1EwRkJReXhWUVVGVkxFTkJRVU1zUTBGQlF6dFpRVU51UXl4RFFVRkRPMEZCUTBZc1pVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eG5Ra0ZCWjBJc1EwRkJReXhYUVVGWExFVkJRVVVzV1VGQlRUdEJRVU16UXl4cFFrRkJTU3hOUVVGTExFMUJRVTBzUTBGQlF5eFhRVUZYTEVWQlFVVTdRVUZETTBJc2NVSkJRVXNzU1VGQlNTeERRVUZETEUxQlFVc3NUVUZCVFN4RFFVRkRMRlZCUVZVc1EwRkJReXhEUVVGRE8yTkJRMjVETzFsQlEwWXNRMEZCUXl4RFFVRkRPenRCUVVkSUxHVkJRVWtzUTBGQlF5eEpRVUZKTEVkQlFVY3NXVUZCVFN4RlFVTnFRaXhEUVVGRE8wRkJRMFlzWlVGQlNTeERRVUZETEVkQlFVY3NRMEZCUXl4blFrRkJaMElzUTBGQlF5eFhRVUZYTEVWQlFVVXNWVUZCUXl4RFFVRkRMRVZCUVVzN1FVRkROVU1zYVVKQlFVa3NUVUZCU3l4TlFVRk5MRU5CUVVNc1YwRkJWeXhGUVVGRk8wRkJRek5DTEcxQ1FVRkpMRU5CUVVNc1RVRkJTeXhOUVVGTkxFVkJRVVU3UVVGRGFFSXNkVUpCUVVzc1RVRkJUU3hIUVVGSExFZEJRVWNzUTBGQlF5eFpRVUZaTEVOQlFVTXNUVUZCU3l4UFFVRlBMRU5CUVVNc1EwRkJRenRuUWtGRE9VTTdRVUZEUkN4eFFrRkJTeXhMUVVGTExFZEJRVWNzUjBGQlJ5eERRVUZETEZkQlFWY3NRMEZCUXl4RFFVRkRMRVZCUVVNc1RVRkJTeXhOUVVGTkxFTkJRVU1zUTBGQlF6dEJRVU0xUXl4eFFrRkJTeXhKUVVGSkxFVkJRVVVzUTBGQlF6dGpRVU5pTzFsQlEwWXNRMEZCUXl4RFFVRkRPenRCUVVkSUxHVkJRVWtzUTBGQlF5eFBRVUZQTEVkQlFVY3NXVUZCVFR0QlFVTnVRaXh0UWtGQlN5eE5RVUZOTEVOQlFVTXNWMEZCVnl4SFFVRkhMRXRCUVVzc1EwRkJRenRaUVVOcVF5eERRVUZETzBGQlEwWXNaVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhuUWtGQlowSXNRMEZCUXl4VFFVRlRMRVZCUVVVc1dVRkJUVHRCUVVONlF5eHBRa0ZCU1N4TlFVRkxMRTFCUVUwc1EwRkJReXhYUVVGWExFVkJRVVU3UVVGRE0wSXNjVUpCUVVzc1JVRkJSU3hGUVVGRkxFTkJRVU03WTBGRFdEdFpRVU5HTEVOQlFVTXNRMEZCUXp0QlFVTklMR1ZCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1ZVRkJWU3hGUVVGRkxGbEJRVTA3UVVGRE1VTXNhVUpCUVVrc1RVRkJTeXhOUVVGTkxFTkJRVU1zVjBGQlZ5eEZRVUZGTzBGQlF6TkNMSEZDUVVGTExFVkJRVVVzUlVGQlJTeERRVUZETzJOQlExZzdXVUZEUml4RFFVRkRMRU5CUVVNN1ZVRkRTanRSUVVWR096dEJRVVZFTEd0Q1FVRmhPMk5CUVVFc2VVSkJRVWM3TzBGQlJXUXNZVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhaUVVGWkxFTkJRVU1zUjBGQlJ5eEZRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXpkQ0xHRkJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNXVUZCV1N4RFFVRkRMRWRCUVVjc1JVRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU0zUWl4aFFVRkpMRWxCUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzUTBGQlF5eEZRVUZGTzBGQlEyeENMR1ZCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zV1VGQldTeERRVUZETEU5QlFVOHNSVUZCUlN4SlFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFTkJRVU1zUTBGQlF5eERRVUZETzFWQlEyaEVMRTFCUVUwN1FVRkRUQ3hsUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4UFFVRlBMRVZCUVVVc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzFWQlF6VkRPMEZCUTBRc1lVRkJTU3hKUVVGSkxFTkJRVU1zVFVGQlRTeEhRVUZITEVOQlFVTXNSVUZCUlR0QlFVTnVRaXhsUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4UlFVRlJMRVZCUVVVc1NVRkJTU3hEUVVGRExFMUJRVTBzUjBGQlJ5eERRVUZETEVOQlFVTXNRMEZCUXp0VlFVTnNSQ3hOUVVGTk8wRkJRMHdzWlVGQlNTeERRVUZETEVkQlFVY3NRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRkxFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0VlFVTTVRenM3UVVGRlJDeGhRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhOUVVGTkxFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1NVRkJTU3hEUVVGRExFTkJRVU03VVVGRmVFUTdPMEZCUlVRc1YwRkJUVHRqUVVGQkxHdENRVUZITzBGQlExQXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFVkJRVVU3UVVGRFppeGxRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhOUVVGTkxFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1NVRkJTU3hEUVVGRExFTkJRVU03VlVGRGVFUXNUVUZCVFR0QlFVTk1MR1ZCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zV1VGQldTeERRVUZETEUxQlFVMHNSVUZCUlN4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFMUJRVTBzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0VlFVTXhSRHRSUVVOR096czdPMVZCY2toSExGVkJRVlU3U1VGQlV5eGpRVUZqT3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096dExRV2RMYkVJc1UwRkJVenRCUVVWcVFpeFpRVVpSTEZOQlFWTXNSMEZGWkRzeVFrRkdTeXhUUVVGVE96dEJRVWt4UWl4VFFVRkpMRTlCUVU4c1IwRkJSeXhEUVVGRExFOUJRVThzUTBGQlF5eERRVUZET3p0QlFVVjRRaXhUUVVGSkxGRkJRVkVzUjBGQlJ6dEJRVU5pTEdGQlFWRXNRMEZCUXl4SFFVRkhMRVZCUVVNc1IwRkJSeXhEUVVGRE8wRkJRMnBDTEdGQlFWRXNVVUZCVVR0QlFVTm9RaXhoUVVGUkxFTkJRVU03UVVGRFZDeG5Ra0ZCVnl4RlFVRkZPMDFCUTJRc1EwRkJRenM3UVVGRlJpeG5RMEZpYVVJc1UwRkJVeXcyUTBGaGNFSXNVMEZCVXl4RlFVRkRMRTlCUVU4c1JVRkJReXhSUVVGUkxFVkJRVVU3TzBGQlJXeERMRk5CUVVrc1EwRkJReXhOUVVGTkxFZEJRVWNzUTBGQlF5eERRVUZETEVOQlFVTTdPenM3T3pzN1FVRlBha0lzVTBGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFbEJRVWtzUTBGQlF6czdPenM3TzBGQlRTOUNMRk5CUVVrc1EwRkJReXhSUVVGUkxFZEJRVWNzU1VGQlNTeExRVUZMTEVOQlFVTXNVVUZCVVN4RFFVRkRMRWRCUVVjc1JVRkJReXhaUVVGWExFVkJRVVVzUlVGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXpzN096czdPMEZCVFRWRUxGTkJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVY3NTVUZCU1N4WFFVRlhMRU5CUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eEpRVUZKTEVWQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhQUVVGUExFTkJRVU1zUTBGQlF6dEJRVU40UlN4VFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFVkJRVVVzUjBGQlJ5eEpRVUZKTEVOQlFVTTdPenM3T3p0QlFVMTBRaXhUUVVGSkxFTkJRVU1zVDBGQlR5eEhRVUZITEVsQlFVa3NXVUZCV1N4RFFVRkRMRU5CUVVNc1JVRkJReXhKUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEVOQlFVTTdPMEZCUldoRUxGTkJRVWtzUTBGQlF5eEpRVUZKTEVWQlFVVXNRMEZCUXp0SlFVVmlPenRoUVRkRGEwSXNVMEZCVXpzN1owSkJRVlFzVTBGQlV6dEJRU3RETlVJc1pVRkJWVHRqUVVGQkxITkNRVUZITzBGQlExZ3NZVUZCU1N4RFFVRkRMRTlCUVU4c1IwRkJSeXhSUVVGUkxFTkJRVU1zWVVGQllTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUXpkRExHRkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNTMEZCU3l4RFFVRkRMRkZCUVZFc1IwRkJSeXhWUVVGVkxFTkJRVU03UVVGRGVrTXNZVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhMUVVGTExFTkJRVU1zVDBGQlR5eEhRVUZITEU5QlFVOHNRMEZCUXp0QlFVTnlReXhoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEV0QlFVc3NRMEZCUXl4TFFVRkxMRWRCUVVjc1RVRkJUU3hEUVVGRE8wRkJRMnhETEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1MwRkJTeXhEUVVGRExFMUJRVTBzUjBGQlJ5eE5RVUZOTEVOQlFVTTdRVUZEYmtNc1lVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eFhRVUZYTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRE8wRkJRM1JETEdGQlFVa3NTMEZCU3l4RFFVRkRMRTFCUVUwc1JVRkJSVHRCUVVOb1FpeGxRVUZKTEVOQlFVTXNhVUpCUVdsQ0xFVkJRVVVzUTBGQlF6dFZRVU14UWp0UlFVTkdPenRCUVVWRUxHMUNRVUZqTzJOQlFVRXNNRUpCUVVjN08wRkJSV1lzWVVGQlNTeERRVUZETEV0QlFVc3NSMEZCUnl4RlFVRkZMRU5CUVVNN1FVRkRhRUlzWTBGQlN5eEpRVUZKTEVOQlFVTXNSMEZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhIUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUVUZCVFN4RlFVRkRMRU5CUVVNc1JVRkJSU3hGUVVGRk96dEJRVVZ5UXl4bFFVRkpMRk5CUVZFc1IwRkJSeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenM3TzBGQlIzSkRMR1ZCUVVrc1UwRkJVeXhIUVVGSExGRkJRVkVzUTBGQlF5eGhRVUZoTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN1FVRkRMME1zYjBKQlFWTXNRMEZCUXl4TFFVRkxMRU5CUVVNc1VVRkJVU3hIUVVGSExGVkJRVlVzUTBGQlF6czdRVUZIZEVNc1pVRkJTU3hKUVVGSkxFZEJRVWNzU1VGQlNTeFZRVUZWTEVOQlFVTXNVMEZCVXl4RlFVRkZPMEZCUTJwRExITkNRVUZUTEVWQlFVVXNTVUZCU1R0QlFVTm1MR3RDUVVGTExFVkJRVVVzUTBGQlF6dEJRVU5TTEdkQ1FVRkhMRVZCUVVVc1UwRkJVU3hEUVVGRExFZEJRVWM3UVVGRGFrSXNiVUpCUVUwc1JVRkJSU3hUUVVGUkxFTkJRVU1zVFVGQlRUdEJRVU4yUWl4cFFrRkJTU3hGUVVGRkxFbEJRVWtzUTBGQlF5eEpRVUZKTzBGQlEyWXNiVUpCUVUwc1JVRkJSU3hKUVVGSk8xbEJRMklzUlVGQlJTeEpRVUZKTEVOQlFVTXNVMEZCVXl4RFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXpzN08wRkJSMnhETEdWQlFVa3NTMEZCU3l4RFFVRkRMRTFCUVUwc1JVRkJSVHRCUVVOb1FpeHBRa0ZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhMUVVGTExFZEJRVWNzUTBGQlF5eERRVUZETzBGQlEyNUNMR2xDUVVGSkxFTkJRVU1zVVVGQlVTeEhRVUZITEVsQlFVa3NRMEZCUXl4UFFVRlBMRWRCUVVjc1NVRkJTU3hEUVVGRExGVkJRVlVzUjBGQlJ5eFpRVUZOTEVWQlFVVXNRMEZCUXp0QlFVTXhSQ3hwUWtGQlNTeERRVUZETEV0QlFVc3NSMEZCUnl4SlFVRkpMRU5CUVVNc1NVRkJTU3hIUVVGSExFbEJRVWtzUTBGQlF5eFBRVUZQTEVkQlFVY3NXVUZCVFN4RlFVRkZMRU5CUVVNN1FVRkRha1FzYVVKQlFVa3NRMEZCUXl4UlFVRlJMRWRCUVVjc1NVRkJTU3hEUVVGRExGbEJRVmtzUjBGQlJ5eEpRVUZKTEVOQlFVTXNaVUZCWlN4SFFVRkhMRmxCUVUwc1JVRkJSU3hEUVVGRE8wRkJRM0JGTEdsQ1FVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eFRRVUZUTEVkQlFVY3NTVUZCU1N4RFFVRkRMRmxCUVZrc1IwRkJSeXhaUVVGTkxFVkJRVVVzUTBGQlF6dFpRVU0xUkRzN1FVRkZSQ3hsUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1EwRkJRenRCUVVOMFFpeGxRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmRCUVZjc1EwRkJReXhUUVVGVExFTkJRVU1zUTBGQlF6dFZRVVZ5UXp0QlFVTkVMR0ZCUVVrc1EwRkJReXhoUVVGaExFVkJRVVVzUTBGQlF6dFJRVU4wUWpzN1FVRkZSQ3hyUWtGQllUdGpRVUZCTEhsQ1FVRkhPenRCUVVWa0xHRkJRVWtzVTBGQlV5eEhRVUZITEVsQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF6dEJRVU14UXl4aFFVRkpMRlZCUVZVc1IwRkJSeXhKUVVGSkxFTkJRVU1zVFVGQlRTeEhRVUZITEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNN08wRkJSWHBETEdOQlFVc3NTVUZCU1N4RFFVRkRMRWRCUVVNc1EwRkJReXhGUVVGRkxFTkJRVU1zUjBGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRExFVkJRVVVzUlVGQlJUdEJRVU4wUXl4bFFVRkpMRk5CUVZNc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRTFCUVUwc1EwRkJRenRCUVVOeVF5eHZRa0ZCVXl4RFFVRkRMRXRCUVVzc1EwRkJReXhKUVVGSkxFZEJRVWNzU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhOUVVGTkxFZEJRVWNzVTBGQlV5eEhRVUZITEVsQlFVa3NRMEZCUXp0QlFVTXZSQ3h2UWtGQlV5eERRVUZETEV0QlFVc3NRMEZCUXl4SFFVRkhMRWRCUVVjc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4SFFVRkhMRWRCUVVjc1ZVRkJWU3hIUVVGSExFbEJRVWtzUTBGQlF6dEJRVU0xUkN4bFFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEUxQlFVMHNRMEZCUXl4VFFVRlRMRVZCUVVNc1ZVRkJWU3hEUVVGRExFTkJRVU03VlVGRE5VTTdVVUZIUmpzN1FVRkZSQ3h0UWtGQll6dGpRVUZCTERCQ1FVRkhPMEZCUTJZc1kwRkJTeXhKUVVGSkxFTkJRVU1zUjBGQlF5eERRVUZETEVWQlFVVXNRMEZCUXl4SFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zVFVGQlRTeEZRVUZGTEVOQlFVTXNSVUZCUlN4RlFVRkZPMEZCUTNSRExHVkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1RVRkJUU3hGUVVGRkxFTkJRVU03VlVGRGVFSTdVVUZEUmpzN1FVRkZSQ3hYUVVGTk8yTkJRVUVzYTBKQlFVYzdPenM3TzBGQlIxQXNZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhQUVVGUExFTkJRVU1zVlVGQlF5eERRVUZETEVWQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1JVRkJTenM3UVVGRk4wSXNaVUZCU1N4TlFVRkxMRTFCUVUwc1EwRkJReXhQUVVGUExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRXRCUVVzc1RVRkJTeXhMUVVGTExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNTMEZCU3l4RlFVRkZPMEZCUTNKRUxHbENRVUZKTEUxQlFVc3NUVUZCVFN4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNSMEZCUnl4RFFVRkRMRVZCUVVVN1FVRkRha01zY1VKQlFVc3NTMEZCU3l4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExFMUJRVTBzUlVGQlJTeERRVUZETzJOQlEzaENMRTFCUVUwN1FVRkRUQ3h4UWtGQlN5eExRVUZMTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1QwRkJUeXhGUVVGRkxFTkJRVU03WTBGRGVrSTdXVUZEUmp0VlFVTkdMRU5CUVVNc1EwRkJRenRSUVVOS096dEJRVk5FTEdOQlFWTTdPenM3T3pzN096dGpRVUZCTEcxQ1FVRkRMRWxCUVVrc1JVRkJReXhGUVVGRkxFVkJRVVU3T3pzN1FVRkpha0lzWVVGQlNTeEpRVUZKTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFTkJRVU1zU1VGQlNTeERRVUZETEVOQlFVTTdPMEZCUlhCRExHRkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUMEZCVHl4RFFVRkRMRWxCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWRCUVVjc1JVRkJSU3hEUVVGRE8wRkJRMmhFTEdGQlFVa3NTVUZCU1N4SFFVRkhPMEZCUTFRc1kwRkJSeXhGUVVGRkxFbEJRVWtzUTBGQlF5eEhRVUZITzBGQlEySXNhVUpCUVUwc1JVRkJSU3hKUVVGSkxFTkJRVU1zVFVGQlRUdEJRVU51UWl4blFrRkJTeXhGUVVGRkxFVkJRVVU3VlVGRFZpeERRVUZETzBGQlEwWXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFVkJRVU1zU1VGQlNTeERRVUZETEVOQlFVTTdVVUZETVVJN08wRkJSVVFzVjBGQlRUdGpRVUZCTEd0Q1FVRkhPenM3UVVGRFVDeGhRVUZKTEVsQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1MwRkJTeXhKUVVGSkxFTkJRVU1zUlVGQlJUdEJRVU16UWl4bFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFOUJRVThzUTBGQlF5eFZRVUZETEVOQlFVTXNSVUZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhGUVVGTE8wRkJRemRDTEdsQ1FVRkpMRU5CUVVNc1MwRkJSeXhOUVVGTExFOUJRVThzUTBGQlF5eExRVUZMTEVWQlFVVTdRVUZETVVJc2NVSkJRVXNzUzBGQlN5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRWRCUVVjc1EwRkJReXhaUVVGWkxFTkJRVU1zVVVGQlVTeEZRVUZETEUxQlFVc3NUVUZCVFN4RFFVRkRMRmRCUVZjc1EwRkJReXhEUVVGRE8wRkJRMnBGTEhGQ1FVRkxMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eEhRVUZITEVOQlFVTXNXVUZCV1N4RFFVRkRMR05CUVdNc1JVRkJReXhIUVVGSExFTkJRVU1zUTBGQlF6dEJRVU51UkN4eFFrRkJTeXhMUVVGTExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhuUWtGQlowSXNSVUZCUXl4SFFVRkhMRU5CUVVNc1EwRkJRenRqUVVOMFJDeE5RVUZOTzBGQlEwd3NjVUpCUVVzc1MwRkJTeXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEVkQlFVY3NRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETzJOQlEycEVPMWxCUTBZc1EwRkJReXhEUVVGRE8xVkJRMG83VVVGRFJqczdRVUZOUkN4VlFVRkxPenM3T3pzN08yTkJRVUVzWlVGQlF5eEZRVUZGTEVWQlFVVTdRVUZEVWl4aFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUTBGQlF6dEJRVU16UXl4aFFVRkpMRVZCUVVVc1JVRkJSVHRCUVVOT0xHVkJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNSVUZCUlN4RFFVRkRMRVZCUVVVc1EwRkJReXhEUVVGRE8xVkJRM1JDTzBGQlEwUXNZVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhMUVVGTExFVkJRVVVzUTBGQlF6dFJRVU4yUWpzN1FVRkxSQ3hUUVVGSk96czdPenM3WTBGQlFTeG5Ra0ZCUnp0QlFVTk1MR0ZCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zU1VGQlNTeEZRVUZGTEVOQlFVTTdVVUZEZEVJN08wRkJTMFFzVTBGQlNUczdPenM3TzJOQlFVRXNaMEpCUVVjN1FVRkRUQ3hoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEVsQlFVa3NSVUZCUlN4RFFVRkRPMEZCUTNCQ0xHRkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVFVGQlRTeERRVUZETEVsQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU1zVDBGQlR5eEZRVUZGTEVOQlFVTXNRMEZCUXp0QlFVTnVSU3hoUVVGSkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVOQlFVTTdVVUZEWmpzN1FVRkZSQ3h6UWtGQmFVSTdZMEZCUVN3MlFrRkJSenM3TzBGQlJXeENMR0ZCUVVrc1EwRkJReXhSUVVGUkxFZEJRVWNzU1VGQlNTeERRVUZETEU5QlFVOHNSMEZCUnl4SlFVRkpMRU5CUVVNc1ZVRkJWU3hIUVVGSExGbEJRVTBzUlVGQlJTeERRVUZETzBGQlF6RkVMR0ZCUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzU1VGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4SlFVRkpMRU5CUVVNc1QwRkJUeXhIUVVGSExGbEJRVTBzUlVGQlJTeERRVUZETzBGQlEycEVMR0ZCUVVrc1EwRkJReXhSUVVGUkxFZEJRVWNzU1VGQlNTeERRVUZETEZsQlFWa3NSMEZCUnl4SlFVRkpMRU5CUVVNc1pVRkJaU3hIUVVGSExGbEJRVTBzUlVGQlJTeERRVUZETzBGQlEzQkZMR0ZCUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzU1VGQlNTeERRVUZETEZOQlFWTXNSMEZCUnl4SlFVRkpMRU5CUVVNc1dVRkJXU3hIUVVGSExGbEJRVTBzUlVGQlJTeERRVUZET3p0QlFVVXpSQ3hoUVVGSkxFTkJRVU1zWTBGQll5eEhRVUZITEV0QlFVc3NRMEZCUXpzN1FVRkZOVUlzWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4blFrRkJaMElzUTBGQlF5eFpRVUZaTEVWQlFVVXNWVUZCUXl4RFFVRkRMRVZCUVVzN1FVRkRha1FzWlVGQlNTeFBRVUZQTEVkQlFVY3NVVUZCVVN4RFFVRkRMR2RDUVVGblFpeERRVUZETEVOQlFVTXNRMEZCUXl4aFFVRmhMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zVDBGQlR5eEZRVUZETEVOQlFVTXNRMEZCUXl4aFFVRmhMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zVDBGQlR5eERRVUZETEVOQlFVTTdRVUZETDBZc1pVRkJTU3hKUVVGSkxFZEJRVWNzVFVGQlN5eExRVUZMTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8wRkJRM0pETEdsQ1FVRkxMRlZCUVZVc1IwRkJSeXhEUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTTdRVUZET1VJc1pVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZMTEZWQlFWVXNRMEZCUXl4RFFVRkRPMEZCUXpOQ0xHbENRVUZMTEdOQlFXTXNSMEZCUnl4UFFVRlBMRU5CUVVNc1MwRkJTeXhEUVVGRE8wRkJRM0JETEZsQlFVTXNRMEZCUXl4alFVRmpMRVZCUVVVc1EwRkJRenRCUVVOdVFpeFpRVUZETEVOQlFVTXNaVUZCWlN4RlFVRkZMRU5CUVVNN1ZVRkRja0lzUTBGQlF5eERRVUZET3p0QlFVVklMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1YwRkJWeXhGUVVGRkxGVkJRVU1zUTBGQlF5eEZRVUZMTzBGQlEyaEVMR1ZCUVVrc1QwRkJUeXhIUVVGSExGRkJRVkVzUTBGQlF5eG5Ra0ZCWjBJc1EwRkJReXhEUVVGRExFTkJRVU1zWVVGQllTeERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRTlCUVU4c1JVRkJReXhEUVVGRExFTkJRVU1zWVVGQllTeERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRE8wRkJReTlHTEdWQlFVa3NTVUZCU1N4SFFVRkhMRTFCUVVzc1MwRkJTeXhEUVVGRExFOUJRVThzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0QlFVTnlReXhsUVVGSkxFOUJRVThzUTBGQlF5eExRVUZMTEV0QlFVY3NUVUZCU3l4alFVRmpMRVZCUVVVN1FVRkRka01zYVVKQlFVa3NUVUZCU3l4alFVRmpMRWxCUVVrc1EwRkJReXhGUVVGRk8wRkJRelZDTEcxQ1FVRkpMRkZCUVZFc1IwRkJSeXhOUVVGTExFdEJRVXNzUTBGQlF5eE5RVUZMTEdOQlFXTXNRMEZCUXl4RFFVRkRPMEZCUXk5RExIVkNRVUZSTEVOQlFVTXNSVUZCUlN4RlFVRkZMRU5CUVVNN1kwRkRaanRCUVVORUxHbENRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVVzc1ZVRkJWU3hEUVVGRExFTkJRVU03V1VGRE5VSXNUVUZCVFR0QlFVTk1MR2xDUVVGSkxFTkJRVU1zU1VGQlNTeEZRVUZGTEVOQlFVTTdXVUZEWWp0QlFVTkVMR2xDUVVGTExHTkJRV01zUjBGQlJ5eFBRVUZQTEVOQlFVTXNTMEZCU3l4RFFVRkRPMEZCUTNCRExGbEJRVU1zUTBGQlF5eGpRVUZqTEVWQlFVVXNRMEZCUXp0QlFVTnVRaXhaUVVGRExFTkJRVU1zWlVGQlpTeEZRVUZGTEVOQlFVTTdWVUZEY2tJc1EwRkJReXhEUVVGRE96dEJRVVZJTEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1owSkJRV2RDTEVOQlFVTXNWVUZCVlN4RlFVRkZMRlZCUVVNc1EwRkJReXhGUVVGTE96dEJRVVV2UXl4bFFVRkpMRWxCUVVrc1IwRkJSeXhOUVVGTExFdEJRVXNzUTBGQlF5eE5RVUZMTEdOQlFXTXNRMEZCUXl4RFFVRkRPMEZCUXpORExHVkJRVWtzUTBGQlF5eEZRVUZGTEVWQlFVVXNRMEZCUXp0QlFVTldMR2xDUVVGTExGZEJRVmNzUjBGQlJ5eExRVUZMTEVOQlFVTTdRVUZEZWtJc2FVSkJRVXNzWTBGQll5eEhRVUZITEV0QlFVc3NRMEZCUXp0QlFVTTFRaXhaUVVGRExFTkJRVU1zWTBGQll5eEZRVUZGTEVOQlFVTTdRVUZEYmtJc1dVRkJReXhEUVVGRExHVkJRV1VzUlVGQlJTeERRVUZETzFWQlEzSkNMRU5CUVVNc1EwRkJRenRSUVVWS096dEJRVlZITEZOQlFVazdPenM3T3pzN1dVRktRU3haUVVGSE8wRkJRMVFzWjBKQlFVOHNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhKUVVGSkxFTkJRVU03VVVGRGVrSTdXVUZGVHl4VlFVRkRMRU5CUVVNc1JVRkJSVHRCUVVOV0xHRkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTVUZCU1N4SFFVRkhMRU5CUVVNc1EwRkJRenRCUVVOeVFpeGhRVUZKTEVOQlFVTXNTMEZCU3l4RlFVRkZMRU5CUVVNN1FVRkRZaXhoUVVGSkxFTkJRVU1zWTBGQll5eEZRVUZGTEVOQlFVTTdRVUZEZEVJc1lVRkJTU3hEUVVGRExFMUJRVTBzUlVGQlJTeERRVUZETzFGQlEyWTdPMEZCVlVjc1dVRkJUenM3T3pzN096dFpRVXBCTEZsQlFVYzdRVUZEV2l4blFrRkJUeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEU5QlFVOHNRMEZCUXp0UlFVTTFRanRaUVVWVkxGVkJRVU1zUTBGQlF5eEZRVUZGTzBGQlEySXNZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhQUVVGUExFZEJRVWNzUTBGQlF5eERRVUZETzBGQlEzaENMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUjBGQlJ5eEhRVUZITEVOQlFVTXNRMEZCUXp0QlFVTnlRaXhoUVVGSkxFTkJRVU1zUzBGQlN5eEZRVUZGTEVOQlFVTTdRVUZEWWl4aFFVRkpMRU5CUVVNc1kwRkJZeXhGUVVGRkxFTkJRVU03UVVGRGRFSXNZVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE8xRkJRMlk3T3pzN1ZVRnFVbXRDTEZOQlFWTTdTVUZCVXl4VFFVRlRPenRyUWtGQk0wSXNVMEZCVXl4RE96czdPenM3UVVNMVN6bENMR0ZCUVZrc1EwRkJRenM3T3pzN096czdTMEZGVGl4SlFVRkpMSFZEUVVGTkxFTkJRV003TzB0QlEzaENMRkZCUVZFc2RVTkJRVTBzUlVGQmIwSTdPenM3T3pzN096czdPenM3T3pzN096czdPenM3UzBGMVFuQkNMRTFCUVUwN1FVRkZaQ3haUVVaUkxFMUJRVTBzUTBGRllpeEpRVUZKTEVWQlFVTXNUMEZCVHl4RlFVRkZPenM3TWtKQlJsQXNUVUZCVFRzN08wRkJTWFpDTEZOQlFVa3NRMEZCUXl4UFFVRlBMRWRCUVVjc1JVRkJSU3hEUVVGRE8wRkJRMnhDTEZOQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1NVRkJTU3hGUVVGRExFOUJRVThzUTBGQlF5eERRVUZET3p0QlFVVXhRaXhUUVVGSkxFTkJRVU1zVFVGQlRTeEhRVUZITzBGQlExb3NWMEZCU1N4RlFVRkZMRlZCUVVNc1RVRkJUU3hGUVVGRkxFZEJRVWNzUlVGQlN6dEJRVU55UWl4bFFVRkxMRTlCUVU4c1EwRkJReXhIUVVGSExFTkJRVU1zUTBGQlF5eE5RVUZOTEVOQlFVTXNSMEZCUnl4RFFVRkRMRTFCUVVzc1QwRkJUeXhEUVVGRExFZEJRVWNzUTBGQlF5eERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRPMEZCUTNaRUxHRkJRVWtzVFVGQlN5eEZRVUZGTEVWQlFVVTdRVUZCUlN4cFFrRkJTeXhGUVVGRkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVOQlFVTTdWVUZCUlR0QlFVTnNReXhuUWtGQlR5eE5RVUZMTEU5QlFVOHNRMEZCUXl4SFFVRkhMRU5CUVVNc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dFJRVU5zUXp0QlFVTkVMRlZCUVVjc1JVRkJSU3haUVVGTk8wRkJRMVFzWlVGQlN5eFBRVUZQTEVOQlFVTXNWVUZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhGUVVGTE8wRkJRVVVzYVVKQlFVc3NUVUZCVFN4RFFVRkRMRWxCUVVrc1EwRkJReXhEUVVGRExFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdWVUZCUlN4RFFVRkRMRU5CUVVNN1FVRkRiRVFzWVVGQlNTeE5RVUZMTEVWQlFVVXNSVUZCUlR0QlFVRkZMR2xDUVVGTExFVkJRVVVzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXp0VlFVRkZPMUZCUTI1RE8wRkJRMFFzVlVGQlJ5eEZRVUZGTEZWQlFVTXNSMEZCUnl4RlFVRkxPMEZCUTFvc1kwRkJTeXhKUVVGSkxFTkJRVU1zUjBGQlF5eERRVUZETEVWQlFVVXNRMEZCUXl4SFFVRkRMRTFCUVVzc1QwRkJUeXhGUVVGRkxFTkJRVU1zUlVGQlJTeEZRVUZGTzBGQlEycERMR2xDUVVGTExFMUJRVTBzUTBGQlF5eEpRVUZKTEVOQlFVTXNRMEZCUXl4RlFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE8xVkJRM3BDTzBGQlEwUXNZVUZCU1N4TlFVRkxMRVZCUVVVc1JVRkJSVHRCUVVGRkxHbENRVUZMTEVWQlFVVXNRMEZCUXl4TlFVRk5MRVZCUVVVc1EwRkJRenRWUVVGRk8xRkJRMjVETzBGQlEwUXNZVUZCVFN4RlFVRkZMRlZCUVVNc1RVRkJUU3hGUVVGTE8wRkJRMnhDTEdOQlFVc3NTVUZCU1N4RFFVRkRMRWRCUVVNc1EwRkJReXhGUVVGRkxFTkJRVU1zUjBGQlF5eE5RVUZMTEVsQlFVa3NSVUZCUlN4RFFVRkRMRVZCUVVVc1JVRkJSVHRCUVVNNVFpeHBRa0ZCU3l4TlFVRk5MRU5CUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUlVGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0VlFVTTFRanRCUVVORUxHRkJRVWtzVFVGQlN5eEZRVUZGTEVWQlFVVTdRVUZCUlN4cFFrRkJTeXhGUVVGRkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVOQlFVTTdWVUZCUlR0UlFVTnVRenROUVVOR0xFTkJRVU03TzBGQlJVWXNVMEZCU1N4RFFVRkRMRWRCUVVjc1IwRkJSenRCUVVOVUxGZEJRVWtzUlVGQlJTeFZRVUZETEUxQlFVMHNSVUZCUlN4SFFVRkhMRVZCUVVVc1MwRkJTeXhGUVVGTE8wRkJRelZDTEdWQlFVc3NUMEZCVHl4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRExFMUJRVTBzUTBGQlF5eEhRVUZITEV0QlFVc3NRMEZCUXp0QlFVTnNReXhoUVVGSkxFMUJRVXNzUlVGQlJTeEZRVUZGTzBGQlFVVXNhVUpCUVVzc1JVRkJSU3hEUVVGRExFMUJRVTBzUlVGQlJTeERRVUZETzFWQlFVVTdVVUZEYmtNN1FVRkRSQ3hWUVVGSExFVkJRVVVzVlVGQlF5eE5RVUZOTEVWQlFVczdPenRCUVVkbUxHVkJRVXNzVDBGQlR5eEhRVUZITEUxQlFVMHNRMEZCUXp0QlFVTjBRaXhoUVVGSkxFMUJRVXNzUlVGQlJTeEZRVUZGTzBGQlFVVXNhVUpCUVVzc1JVRkJSU3hEUVVGRExFMUJRVTBzUlVGQlJTeERRVUZETzFWQlFVVTdVVUZEYmtNN1FVRkRSQ3hWUVVGSExFVkJRVVVzVlVGQlF5eEhRVUZITEVWQlFVTXNUVUZCVFN4RlFVRkxPenRCUVVWdVFpeGxRVUZMTEU5QlFVOHNRMEZCUXl4SFFVRkhMRU5CUVVNc1IwRkJSeXhOUVVGTkxFTkJRVU03UVVGRE0wSXNZVUZCU1N4TlFVRkxMRVZCUVVVc1JVRkJSVHRCUVVGRkxHbENRVUZMTEVWQlFVVXNRMEZCUXl4TlFVRk5MRVZCUVVVc1EwRkJRenRWUVVGRk8xRkJRMjVETzBGQlEwUXNZVUZCVFN4RlFVRkZMRlZCUVVNc1RVRkJUU3hGUVVGRExFMUJRVTBzUlVGQlN6czdRVUZGZWtJc1pVRkJTeXhQUVVGUExFTkJRVU1zVDBGQlR5eERRVUZETEZWQlFVTXNSMEZCUnl4RlFVRkRMRU5CUVVNc1JVRkJTenRCUVVNNVFpeHBRa0ZCU3l4UFFVRlBMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zVFVGQlRTeERRVUZETEVkQlFVY3NUVUZCVFN4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8xVkJRM0pETEVOQlFVTXNRMEZCUXp0QlFVTklMR0ZCUVVrc1RVRkJTeXhGUVVGRkxFVkJRVVU3UVVGQlJTeHBRa0ZCU3l4RlFVRkZMRU5CUVVNc1RVRkJUU3hGUVVGRkxFTkJRVU03VlVGQlJUdFJRVU51UXp0TlFVTkdMRU5CUVVNN08wRkJSVVlzVTBGQlNTeERRVUZETEUxQlFVMHNSMEZCUnpzN08wRkJSMW9zVlVGQlJ5eEZRVUZGTEZWQlFVTXNUVUZCVFN4RlFVRkxPMEZCUTJZc1lVRkJTU3hEUVVGRExFMUJRVTBzU1VGQlNTeE5RVUZOTEV0QlFVY3NRMEZCUXl4RlFVRkZPMEZCUTNwQ0xHbENRVUZOTEVkQlFVY3NRMEZCUXl4RFFVRkRPMVZCUTFvN1FVRkRSQ3hsUVVGTkxFbEJRVWtzVFVGQlN5eFBRVUZQTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1RVRkJUU3hEUVVGRE8wRkJRMnBETEdGQlFVa3NUVUZCVFN4SFFVRkhMRU5CUVVNc1JVRkJSVHRCUVVOa0xHbENRVUZOTEVkQlFVY3NUVUZCU3l4UFFVRlBMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zVFVGQlRTeEhRVUZITEUxQlFVMHNRMEZCUXp0VlFVTXhRenRCUVVORUxHTkJRVXNzU1VGQlNTeERRVUZETEVkQlFVTXNRMEZCUXl4RlFVRkZMRU5CUVVNc1IwRkJReXhOUVVGTExFbEJRVWtzUlVGQlJTeERRVUZETEVWQlFVVXNSVUZCUlR0QlFVTTVRaXhsUVVGSkxFZEJRVWNzUjBGQlJ5eE5RVUZMTEU5QlFVOHNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhOUVVGTkxFTkJRVVVzVFVGQlN5eFBRVUZQTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1RVRkJUU3hIUVVGSExFMUJRVTBzUlVGQlJTeE5RVUZOTEVOQlFVVXNRMEZCUXp0QlFVTTFSU3hwUWtGQlN5eFBRVUZQTEVOQlFVTXNRMEZCUXl4RFFVRkRMRWRCUVVjc1IwRkJSeXhEUVVGRExFMUJRVTBzUTBGQlJTeE5RVUZMTEU5QlFVOHNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJSU3hEUVVGRE8xVkJRMnBFTzBGQlEwUXNZVUZCU1N4TlFVRkxMRVZCUVVVc1JVRkJSVHRCUVVGRkxHbENRVUZMTEVWQlFVVXNRMEZCUXl4TlFVRk5MRVZCUVVVc1EwRkJRenRWUVVGRk8xRkJRMjVETzBGQlEwUXNWVUZCUnl4RlFVRkZMRlZCUVVNc1IwRkJSeXhGUVVGRExFMUJRVTBzUlVGQlN6dEJRVU51UWl4aFFVRkpMRU5CUVVNc1RVRkJUU3hKUVVGSkxFMUJRVTBzUzBGQlJ5eERRVUZETEVWQlFVVTdRVUZEZWtJc2FVSkJRVTBzUjBGQlJ5eERRVUZETEVOQlFVTTdWVUZEV2p0QlFVTkVMR1ZCUVUwc1NVRkJTU3hOUVVGTExFOUJRVThzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4TlFVRk5MRU5CUVVNN1FVRkRha01zWVVGQlNTeE5RVUZOTEVkQlFVY3NRMEZCUXl4RlFVRkZPMEZCUTJRc2FVSkJRVTBzUjBGQlJ5eE5RVUZMTEU5QlFVOHNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhOUVVGTkxFZEJRVWNzVFVGQlRTeERRVUZETzFWQlF6RkRPMEZCUTBRc1lVRkJTU3hIUVVGSExFZEJRVWNzVFVGQlN5eFBRVUZQTEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNc1RVRkJUU3hEUVVGRkxFMUJRVXNzVDBGQlR5eERRVUZETEVkQlFVY3NRMEZCUXl4RFFVRkRMRTFCUVUwc1IwRkJSeXhOUVVGTkxFVkJRVVVzVFVGQlRTeERRVUZGTEVOQlFVTTdRVUZEYUVZc1pVRkJTeXhQUVVGUExFTkJRVU1zUjBGQlJ5eERRVUZETEVkQlFVY3NSMEZCUnl4RFFVRkRMRTFCUVUwc1EwRkJSU3hOUVVGTExFOUJRVThzUTBGQlF5eEhRVUZITEVOQlFVTXNRMEZCUlN4RFFVRkRPMEZCUTNCRUxHRkJRVWtzVFVGQlN5eEZRVUZGTEVWQlFVVTdRVUZCUlN4cFFrRkJTeXhGUVVGRkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVOQlFVTTdWVUZCUlR0UlFVTnVRenRCUVVORUxHRkJRVTBzUlVGQlJTeFZRVUZETEUxQlFVMHNSVUZCUlN4TlFVRk5MRVZCUVVzN1FVRkRNVUlzWVVGQlNTeERRVUZETEUxQlFVMHNTVUZCU1N4TlFVRk5MRXRCUVVjc1EwRkJReXhGUVVGRk8wRkJRM3BDTEdsQ1FVRk5MRWRCUVVjc1EwRkJReXhEUVVGRE8xVkJRMW83UVVGRFJDeGxRVUZOTEVsQlFVa3NUVUZCU3l4UFFVRlBMRU5CUVVNc1RVRkJUU3hEUVVGRE8wRkJRemxDTEdGQlFVa3NUVUZCVFN4SFFVRkhMRU5CUVVNc1JVRkJSVHRCUVVOa0xHbENRVUZOTEVkQlFVY3NUVUZCU3l4UFFVRlBMRU5CUVVNc1RVRkJUU3hIUVVGSExFMUJRVTBzUTBGQlF6dFZRVU4yUXp0QlFVTkVMR0ZCUVVrc1MwRkJTeXhIUVVGSExFVkJRVVVzUTBGQlF6dEJRVU5tTEdWQlFVc3NUMEZCVHl4RFFVRkRMRTlCUVU4c1EwRkJReXhWUVVGRExFZEJRVWNzUlVGQlN6dEJRVU0xUWl4blFrRkJTeXhEUVVGRExFbEJRVWtzUTBGQlJTeEhRVUZITEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVVc1EwRkJRenRWUVVNelFpeERRVUZETEVOQlFVTTdRVUZEU0N4aFFVRkpMRWRCUVVjc1IwRkJSeXhMUVVGTExFTkJRVU1zVFVGQlRTeERRVUZGTEV0QlFVc3NRMEZCUXl4TlFVRk5MRWRCUVVjc1RVRkJUU3hGUVVGRkxFMUJRVTBzUTBGQlJTeERRVUZETzBGQlEzaEVMR05CUVVzc1IwRkJSeXhIUVVGSExFTkJRVU1zVFVGQlRTeERRVUZGTEV0QlFVc3NRMEZCUlN4RFFVRkRPMEZCUXpWQ0xHVkJRVXNzVDBGQlR5eERRVUZETEU5QlFVOHNRMEZCUXl4VlFVRkRMRWRCUVVjc1JVRkJReXhEUVVGRExFVkJRVXM3UVVGRE9VSXNZMEZCUnl4RFFVRkRMRTFCUVUwc1EwRkJReXhIUVVGSExFdEJRVXNzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0VlFVTjRRaXhEUVVGRExFTkJRVU03UVVGRFNDeGhRVUZKTEUxQlFVc3NSVUZCUlN4RlFVRkZPMEZCUVVVc2FVSkJRVXNzUlVGQlJTeERRVUZETEUxQlFVMHNSVUZCUlN4RFFVRkRPMVZCUVVVN1VVRkRia003VFVGRFJpeERRVUZET3pzN096dEJRVXRHTEZOQlFVa3NRMEZCUXl4UlFVRlJMRWRCUVVjN1FVRkRaQ3hWUVVGSExFVkJRVVVzVlVGQlF5eEpRVUZKTEVWQlFVczdRVUZEWWl4aFFVRkpMRmxCUVZrc1IwRkJSeXhKUVVGSkxGRkJRVkVzUTBGQlF5eEpRVUZKTEVOQlFVTXNRMEZCUXp0QlFVTjBReXhsUVVGTExFOUJRVThzUTBGQlF5eFZRVUZETEVOQlFVTXNSVUZCUXl4RFFVRkRMRVZCUVVzN1FVRkRjRUlzYVVKQlFVc3NUMEZCVHl4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eEhRVUZITEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1dVRkJXU3hEUVVGRExFbEJRVWtzUlVGQlJTeERRVUZETEVOQlFVTTdWVUZEY2tRc1EwRkJReXhEUVVGRE96czdPenRCUVV0SUxHRkJRVWtzVFVGQlN5eEZRVUZGTEVWQlFVVTdRVUZCUlN4cFFrRkJTeXhGUVVGRkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVOQlFVTTdWVUZCUlR0UlFVTnVRenRCUVVORUxGVkJRVWNzUlVGQlJTeFpRVUZyUWp0aFFVRnFRaXhIUVVGSExHZERRVUZETEVOQlFVTTdZVUZCUXl4SlFVRkpMR2REUVVGRExFTkJRVU03TzBGQlEyaENMR0ZCUVVrc1dVRkJXU3hIUVVGSExFbEJRVWtzVVVGQlVTeERRVUZETEVsQlFVa3NRMEZCUXl4RFFVRkRPMEZCUTNSRExHVkJRVXNzVDBGQlR5eERRVUZETEVkQlFVY3NRMEZCUXl4RFFVRkRMRTlCUVU4c1EwRkJReXhWUVVGRExFbEJRVWtzUlVGQlF5eERRVUZETEVWQlFVczdRVUZEY0VNc2FVSkJRVXNzVDBGQlR5eERRVUZETEVkQlFVY3NRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhIUVVGSExFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWxCUVVrc1JVRkJSU3hEUVVGRExFTkJRVU03VlVGRGRrUXNRMEZCUXl4RFFVRkRPMEZCUTBnc1lVRkJTU3hOUVVGTExFVkJRVVVzUlVGQlJUdEJRVUZGTEdsQ1FVRkxMRVZCUVVVc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF6dFZRVUZGTzFGQlEyNURPMEZCUTBRc1lVRkJUU3hGUVVGRkxGbEJRWEZDTzJGQlFYQkNMRTFCUVUwc1owTkJRVU1zUTBGQlF6dGhRVUZETEVsQlFVa3NaME5CUVVNc1EwRkJRenM3UVVGRGRFSXNZVUZCU1N4WlFVRlpMRWRCUVVjc1NVRkJTU3hSUVVGUkxFTkJRVU1zU1VGQlNTeERRVUZETEVOQlFVTTdRVUZEZEVNc1pVRkJTeXhQUVVGUExFTkJRVU1zVDBGQlR5eERRVUZETEZWQlFVTXNSMEZCUnl4RlFVRkRMRU5CUVVNc1JVRkJTenRCUVVNNVFpeHBRa0ZCU3l4UFFVRlBMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zVFVGQlRTeERRVUZETEVkQlFVY3NTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhaUVVGWkxFTkJRVU1zU1VGQlNTeEZRVUZGTEVOQlFVTXNRMEZCUXp0VlFVTXhSQ3hEUVVGRExFTkJRVU03UVVGRFNDeGhRVUZKTEUxQlFVc3NSVUZCUlN4RlFVRkZPMEZCUVVVc2FVSkJRVXNzUlVGQlJTeERRVUZETEUxQlFVMHNSVUZCUlN4RFFVRkRPMVZCUVVVN1VVRkRia003VFVGRFJpeERRVUZET3pzN1FVRkhSaXhUUVVGSkxFTkJRVU1zUzBGQlN5eEhRVUZITzBGQlExZ3NWVUZCUnl4RlFVRkZMRmxCUVUwN1FVRkRWQ3hsUVVGTExFZEJRVWNzUTBGQlF5eEhRVUZITEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1VVRkRha0k3UVVGRFJDeFZRVUZITEVWQlFVVXNWVUZCUXl4SFFVRkhMRVZCUVVzN1FVRkRXaXhsUVVGTExFZEJRVWNzUTBGQlF5eEhRVUZITEVOQlFVTXNSMEZCUnl4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8xRkJRM0pDTzBGQlEwUXNZVUZCVFN4RlFVRkZMRlZCUVVNc1RVRkJUU3hGUVVGTE8wRkJRMnhDTEdWQlFVc3NSMEZCUnl4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdVVUZETTBJN1RVRkRSaXhEUVVGRE96czdTVUZIU0RzN1owSkJka3ByUWl4TlFVRk5PMEZCTUVwNlFpeFhRVUZOTzJOQlFVRXNaMEpCUVVNc1NVRkJTU3hGUVVGRExFOUJRVThzUlVGQlJUczdPMEZCUTI1Q0xHRkJRVWtzUTBGQlF5eFBRVUZQTEVkQlFVY3NSVUZCUlN4RFFVRkRPMEZCUTJ4Q0xHTkJRVTBzU1VGQlNTeEhRVUZITEVkQlFVTXNRMEZCUXl4RlFVRkZMRWRCUVVjc1IwRkJSeXhKUVVGSkxFVkJRVVVzUjBGQlJ5eEZRVUZGTEVWQlFVYzdRVUZEYmtNc1pVRkJTU3hIUVVGSExFZEJRVWNzU1VGQlNTeExRVUZMTEVOQlFVTXNUMEZCVHl4RFFVRkRMRU5CUVVNN1FVRkROMElzWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4SlFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU03VlVGRGVFSTdRVUZEUkN4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExGVkJRVU1zUTBGQlF5eEZRVUZETEVOQlFVTXNSVUZCU3p0QlFVRkZMR2xDUVVGTExFOUJRVThzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1IwRkJSeXhMUVVGTExFTkJRVU03VlVGQlJTeERRVUZETEVOQlFVTTdVVUZEZUVRN08wRkJSVVFzV1VGQlR6dGpRVUZCTEdsQ1FVRkRMRU5CUVVNc1JVRkJSU3hGUVVGRkxFVkJRVVU3UVVGRFlpeGhRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNN1FVRkRWaXhqUVVGTkxFbEJRVWtzUjBGQlJ5eEhRVUZETEVOQlFVTXNSVUZCUlN4SFFVRkhMRWRCUVVjc1NVRkJTU3hEUVVGRExFbEJRVWtzUlVGQlJTeEhRVUZITEVWQlFVVXNSVUZCUnp0QlFVTjRReXhsUVVGSkxFVkJRVVVzUlVGQlJUdEJRVUZGTEdWQlFVVXNRMEZCUXl4SFFVRkhMRU5CUVVNc1EwRkJRenRaUVVGRk8wRkJRM0JDTEdkQ1FVRk5MRWxCUVVrc1RVRkJUU3hIUVVGRExFTkJRVU1zUlVGQlJTeE5RVUZOTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTlCUVU4c1JVRkJSU3hOUVVGTkxFVkJRVVVzUlVGQlJ6dEJRVU53UkN4alFVRkRMRU5CUVVNc1IwRkJSeXhGUVVGRExFMUJRVTBzUlVGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0QlFVTm9RaXhqUVVGRExFVkJRVVVzUTBGQlF6dFpRVU5NTzFWQlEwWTdVVUZEUmpzN1FVRkZSQ3hwUWtGQldUdGpRVUZCTEhkQ1FVRkhPenM3UVVGRFlpeGhRVUZKTEdGQlFXRXNSMEZCUnl4RlFVRkZMRU5CUVVNN1FVRkRka0lzWVVGQlNTeERRVUZETEU5QlFVOHNRMEZEVml4VlFVRkRMRU5CUVVNc1JVRkJReXhEUVVGRExFVkJRVXM3UVVGQlJTeDNRa0ZCWVN4SlFVRkpMRU5CUVVNc1RVRkJTeXhQUVVGUExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRWRCUVVjc1EwRkJReXhIUVVGSExFTkJRVU1zU1VGQlNTeEhRVUZITEVOQlFVTTdWVUZCUlN4RlFVTnFSU3haUVVGTk8wRkJRVVVzZDBKQlFXRXNTVUZCU1N4SlFVRkpMRU5CUVVNN1ZVRkJSU3hEUVVOcVF5eERRVUZETzBGQlEwWXNaMEpCUVU4c1lVRkJZU3hEUVVGRE8xRkJRM1JDT3p0QlFVVkVMRkZCUVVjN1kwRkJRU3hsUVVGSE8wRkJRMG9zWjBKQlFVOHNRMEZCUXl4SFFVRkhMRU5CUVVNc1NVRkJTU3hEUVVGRExGbEJRVmtzUlVGQlJTeERRVUZETEVOQlFVTTdVVUZEYkVNN08wRkJSVVFzVjBGQlRUdGpRVUZCTEdkQ1FVRkRMRTlCUVU4c1JVRkJSVHRCUVVOa0xHRkJRVWtzUTBGQlF5eFBRVUZQTEVkQlFVY3NUMEZCVHl4SlFVRkpMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU03VVVGRGVFTTdPMEZCUlVjc1YwRkJUVHRaUVVGQkxGbEJRVWM3UVVGRFdDeG5Ra0ZCVHl4SlFVRkpMRU5CUVVNc1NVRkJTU3hIUVVGRExFbEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTTdVVUZETDBJN08wRkJSVVFzVjBGQlRUdGpRVUZCTEdkQ1FVRkRMRXRCUVVzc1JVRkJSVHM3UVVGRldpeG5Ra0ZCVHp0QlFVTk1MR05CUVVjc1JVRkJSU3hGUVVGRExFVkJRVWNzUzBGQlN5eEhRVUZITEVsQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVVN1FVRkRMMElzYVVKQlFVMHNSVUZCUlN4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExFOUJRVTg3VlVGRE4wSXNRMEZCUXp0UlFVTklPenRCUVVWRUxGbEJRVTg3WTBGQlFTeHBRa0ZCUXl4SFFVRkhMRVZCUVVNc1RVRkJUU3hGUVVGRk8wRkJRMnhDTEdkQ1FVRlBMRTFCUVUwc1IwRkJSeXhIUVVGSExFZEJRVWNzU1VGQlNTeERRVUZETEU5QlFVOHNRMEZCUXpzN1VVRkZjRU03TzBGQlJVUXNVVUZCUnpzN096czdPenM3T3pzN1ZVRkJRU3hWUVVGRExFZEJRVWNzUlVGQlJUdEJRVU5RTEdGQlFVa3NTVUZCU1N4SFFVRkhMRVZCUVVVc1EwRkJRenRCUVVOa0xHTkJRVXNzU1VGQlNTeERRVUZETEVkQlFVTXNRMEZCUXl4RlFVRkZMRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zVDBGQlR5eEZRVUZGTEVOQlFVTXNSVUZCUlN4RlFVRkZPMEZCUTJwRExHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhIUVVGSExFTkJRVU1zUjBGQlJ5eERRVUZETEVkQlFVY3NRMEZCUXl4RFFVRkRMRU5CUVVNN1ZVRkRkRU03UVVGRFJDeG5Ra0ZCVHl4SlFVRkpMRU5CUVVNN1VVRkRZanM3UVVGRlJDeFhRVUZOT3pzN096czdPenM3T3p0VlFVRkJMRlZCUVVNc1RVRkJUU3hGUVVGRk8wRkJRMklzWVVGQlNTeEpRVUZKTEVkQlFVY3NSVUZCUlN4RFFVRkRPMEZCUTJRc1kwRkJTeXhKUVVGSkxFTkJRVU1zUjBGQlF5eERRVUZETEVWQlFVVXNRMEZCUXl4SFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFVkJRVVVzUTBGQlF5eEZRVUZGTEVWQlFVVTdRVUZET1VJc1pVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExFMUJRVTBzUTBGQlF5eEhRVUZITEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNc1EwRkJRenRWUVVNMVF6dEJRVU5FTEdkQ1FVRlBMRWxCUVVrc1EwRkJRenRSUVVOaU96dEJRVXRITEZOQlFVazdXVUZJUVN4WlFVRkhPMEZCUTFRc1owSkJRVThzU1VGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4TlFVRk5MRU5CUVVNN1VVRkROVUk3V1VGRFR5eFZRVUZETEVOQlFVTXNSVUZCUlRzN08wRkJRMVlzWVVGQlNTeFJRVUZSTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZEY2tNc1lVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETEVWQlFVTXNTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRE8wRkJRelZDTEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1ZVRkJReXhEUVVGRExFVkJRVU1zUTBGQlF5eEZRVUZMTzBGQlEzQkNMR1ZCUVVrc1VVRkJVU3hEUVVGRExFTkJRVU1zUTBGQlF5eEpRVUZKTEZGQlFWRXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zUlVGQlJUdEJRVU5xUXl4dFFrRkJTeXhQUVVGUExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRWRCUVVjc1VVRkJVU3hEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMWxCUTNKRE8xVkJRMFlzUTBGQlF5eERRVUZETzFGQlEwbzdPMEZCUzBjc1dVRkJUenRaUVVoQkxGbEJRVWM3UVVGRFdpeG5Ra0ZCVHl4SlFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEUxQlFVMHNRMEZCUXp0UlFVTXZRanRaUVVOVkxGVkJRVU1zUTBGQlF5eEZRVUZGT3pzN1FVRkRZaXhoUVVGSkxGRkJRVkVzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU55UXl4aFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFbEJRVWtzUTBGQlF5eEpRVUZKTEVWQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRla0lzWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4VlFVRkRMRU5CUVVNc1JVRkJReXhEUVVGRExFVkJRVXM3UVVGRGNFSXNaVUZCU1N4UlFVRlJMRU5CUVVNc1EwRkJReXhEUVVGRExFbEJRVWtzVVVGQlVTeERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhGUVVGRk8wRkJRMnBETEcxQ1FVRkxMRTlCUVU4c1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNSMEZCUnl4UlFVRlJMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdXVUZEY2tNN1ZVRkRSaXhEUVVGRExFTkJRVU03VVVGRFNqczdPenRWUVhoUWEwSXNUVUZCVFRzN08ydENRVUZPTEUxQlFVMHNRenM3T3pzN08wRkRNVUl6UWl4aFFVRlpMRU5CUVVNN096czdPenM3TzB0QlJVNHNTVUZCU1N4MVEwRkJUU3hEUVVGak96dExRVU40UWl4TFFVRkxMSFZEUVVGTkxFVkJRVk03TzB0QlJVNHNVVUZCVVR0QlFVVmtMRmxCUmswc1VVRkJVU3hIUVVWMVF6dFRRVUZ3UkN4UlFVRlJMR2REUVVGSExFTkJRVU1zUTBGQlF5eEZRVUZETEVWQlFVVXNSVUZCUXl4RlFVRkZMRVZCUVVNc1JVRkJSU3hEUVVGRE8xTkJRVVVzU1VGQlNTeG5RMEZCUXl4SlFVRkpPMU5CUVVVc1VVRkJVU3huUTBGQlF5eExRVUZMT3pzeVFrRkdOME1zVVVGQlVUczdRVUZIY2tJc1UwRkJTU3hEUVVGRExFMUJRVTBzUjBGQlJ5eFJRVUZSTEVOQlFVTTdRVUZEZGtJc1UwRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eFBRVUZQTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhGUVVGRk8wRkJReTlDTEZkQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1EwRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdUVUZETjBJN1FVRkRSQ3hUUVVGSkxFTkJRVU1zUzBGQlN5eEhRVUZITEVsQlFVa3NRMEZCUXp0QlFVTnNRaXhUUVVGSkxFTkJRVU1zVVVGQlVTeEhRVUZITEZGQlFWRXNRMEZCUXpzN1FVRkZla0lzVTBGQlNTeERRVUZETEZOQlFWTXNSMEZCUnl4SlFVRkpMRXRCUVVzc1EwRkJReXhEUVVGRExFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRWRCUVVjc1EwRkJReXhEUVVGRExFTkJRVU03TzBGQlJYUkVMRk5CUVVrc1EwRkJReXhYUVVGWExFZEJRVWM3UVVGRGFrSXNWMEZCVFN4RFFVRkRPMEZCUTFBc1lVRkJVU3hKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEUxQlFVMHNSMEZCUnl4RFFVRkRPMEZCUXpsQ0xHTkJRVk1zUlVGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1RVRkJUU3hIUVVGRExFTkJRVU1zUTBGQlF6dEJRVU5xUXl4bFFVRlZMRWxCUVVrc1EwRkJReXhGUVVGRkxFTkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNN1RVRkRkRU1zUTBGQlF6czdRVUZGUml4VFFVRkpMRWxCUVVrc1EwRkJReXhSUVVGUkxFdEJRVWNzUzBGQlN5eEZRVUZGTzBGQlEzcENMRmRCUVVrc1EwRkJReXhKUVVGSkxFZEJRVWNzU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenROUVVNNVFpeE5RVUZOTzBGQlEwd3NWMEZCU1N4RFFVRkRMRWxCUVVrc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETzAxQlEzaENPMGxCUjBvN08yZENRVEZDWjBJc1VVRkJVVHRCUVdkRGNrSXNVMEZCU1R0WlFVcEJMRmxCUVVjN1FVRkRWQ3huUWtGQlR5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRPMUZCUTI1Q08xbEJSVThzVlVGQlF5eEpRVUZKTEVWQlFVVTdRVUZEV0N4aFFVRkpMRVZCUVVVc1NVRkJTU3hMUVVGTExFbEJRVWtzU1VGQlNTeEpRVUZKTEV0QlFVc3NUVUZCVFN4SlFVRkpMRWxCUVVrc1MwRkJTeXhSUVVGUkxFbEJRVWtzU1VGQlNTeExRVUZMTEU5QlFVOHNRMEZCUXl4RlFVRkZPMEZCUXpsRkxHdENRVUZQTEVOQlFVTXNTMEZCU3l4RFFVRkRMQ3RFUVVFclJDeERRVUZETEVOQlFVTTdRVUZETDBVc2EwSkJRVTg3VlVGRFZqdEJRVU5FTEdGQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRE8wRkJRMnhDTEdGQlFVa3NTVUZCU1N4RFFVRkRMRkZCUVZFc1JVRkJSVHRCUVVOcVFpeGxRVUZKTEVOQlFVTXNTVUZCU1N4SFFVRkhMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdWVUZET1VJN1VVRkRTanM3UVVGTlJ5eFZRVUZMTzFsQlNrRXNXVUZCUnp0QlFVTldMR2RDUVVGUExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRE8xRkJRMjVETzFsQlJWRXNWVUZCUXl4RFFVRkRMRVZCUVVVN1FVRkRXQ3hoUVVGSkxFTkJRVU1zVVVGQlVTeEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1QwRkJUeXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzFGQlEzaERPenRCUVVWRUxGVkJRVXM3WTBGQlFTeHBRa0ZCUnp0QlFVTk9MR0ZCUVVrc1NVRkJTU3hEUVVGRExGRkJRVkVzUzBGQlJ5eExRVUZMTEVWQlFVVTdRVUZEZWtJc1pVRkJTU3hEUVVGRExFbEJRVWtzUjBGQlJ5eEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8wRkJRemRDTEd0Q1FVRlBMRWxCUVVrc1EwRkJReXhKUVVGSkxFVkJRVVVzUTBGQlF6dFZRVU53UWp0QlFVTkVMR0ZCUVVrc1EwRkJReXhSUVVGUkxFZEJRVWNzU1VGQlNTeERRVUZETEZkQlFWY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03UVVGRE4wTXNZVUZCU1N4RFFVRkRMRWxCUVVrc1IwRkJSeXhKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUXpkQ0xHZENRVUZQTEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNN1VVRkRia0k3TzBGQlJVUXNUMEZCUlR0alFVRkJMR05CUVVjN1FVRkRTQ3hoUVVGSkxFTkJRVU1zVVVGQlVTeEZRVUZGTEVOQlFVTTdRVUZEYUVJc1lVRkJTU3hEUVVGRExGRkJRVkVzU1VGQlNTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTFCUVUwc1EwRkJRenRCUVVOd1F5eG5Ra0ZCVHl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRE8xRkJRMjVDT3p0QlFVVkVMRk5CUVVrN1kwRkJRU3huUWtGQlJ6dEJRVU5NTEdGQlFVa3NRMEZCUXl4UlFVRlJMRVZCUVVVc1EwRkJRenRCUVVOb1FpeGhRVUZKTEVsQlFVa3NRMEZCUXl4UlFVRlJMRWRCUVVjc1EwRkJReXhGUVVGRk8wRkJRM0pDTEdWQlFVa3NRMEZCUXl4UlFVRlJMRWRCUVVjc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1RVRkJUU3hKUVVGSkxFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUVUZCVFN4RFFVRkRPMVZCUXpORk8wRkJRMFFzWjBKQlFVOHNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJRenRSUVVOdVFqczdRVUZGUkN4WFFVRk5PMk5CUVVFc2EwSkJRVWM3UVVGRFVDeGhRVUZKTEVOQlFVTXNVVUZCVVN4SFFVRkhMRWxCUVVrc1EwRkJReXhGUVVGRkxFTkJRVU1zUTBGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03UVVGREwwTXNaMEpCUVU4c1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF6dFJRVU51UWpzN1FVRkZSQ3hWUVVGTE8yTkJRVUVzYVVKQlFVYzdRVUZEVGl4aFFVRkpMRU5CUVVNc1UwRkJVeXhEUVVGRExFZEJRVWNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTFCUVUwc1EwRkJRenRCUVVONFF5eGhRVUZKTEVOQlFVTXNVMEZCVXl4RFFVRkRMRXRCUVVzc1IwRkJSeXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETzBGQlEzSkRMR0ZCUVVrc1EwRkJReXhSUVVGUkxFZEJRVWNzU1VGQlNTeERRVUZETEZOQlFWTXNRMEZCUXl4SlFVRkpMRVZCUVVVc1EwRkJRenRCUVVOMFF5eG5Ra0ZCVHl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRE8xRkJRMjVDT3pzN096czdPMEZCUVVFN096czdWVUZ5Um1kQ0xGRkJRVkU3T3p0clFrRkJVaXhSUVVGUkxFTTdPenM3T3p0QlEwdzNRaXhoUVVGWkxFTkJRVU03T3pzN096czdPMHRCUlU0c1NVRkJTU3gxUTBGQlRTeERRVUZqT3p0TFFVVldMRXRCUVVzN1FVRkZXQ3hqUVVaTkxFdEJRVXNzUjBGRmMwTTdZVUZCYUVRc1IwRkJSeXhuUTBGQlF5eERRVUZETzJGQlFVVXNSMEZCUnl4blEwRkJReXhEUVVGRE8yRkJRVVVzUzBGQlN5eG5RMEZCUXl4RFFVRkRPMkZCUVVVc1UwRkJVeXhuUTBGQlF5eERRVUZETzJGQlFVVXNTVUZCU1N4blEwRkJReXhMUVVGTE96c3JRa0ZHZWtNc1MwRkJTenM3UVVGSGJFSXNZVUZCU1N4RFFVRkRMRWRCUVVjc1IwRkJSeXhIUVVGSExFTkJRVU03UVVGRFppeGhRVUZKTEVOQlFVTXNSMEZCUnl4SFFVRkhMRWRCUVVjc1EwRkJRenRCUVVObUxHRkJRVWtzUTBGQlF5eExRVUZMTEVkQlFVY3NTMEZCU3l4RFFVRkRPMEZCUTI1Q0xHRkJRVWtzUTBGQlF5eFRRVUZUTEVkQlFVY3NVMEZCVXl4RFFVRkRPMEZCUXpOQ0xHRkJRVWtzUTBGQlF5eEpRVUZKTEVkQlFVY3NTVUZCU1N4RFFVRkRPMDFCUTNCQ096dHJRa0ZTWjBJc1MwRkJTenRCUVZWMFFpeGhRVUZKTzI5Q1FVRkJMR2RDUVVGSE8wRkJRMGdzY1VKQlFVa3NRMEZCUXl4TFFVRkxMRWxCUVVrc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eERRVUZETEVOQlFVTXNSMEZCUnl4SlFVRkpMRU5CUVVNc1UwRkJVeXhGUVVGRkxFbEJRVWtzUTBGQlF5eFRRVUZUTEVOQlFVTXNRMEZCUXp0QlFVTTNSQ3h4UWtGQlNTeEpRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhIUVVGSExFVkJRVVU3UVVGRGRrSXNlVUpCUVVrc1NVRkJTU3hEUVVGRExFbEJRVWtzUlVGQlJUdEJRVU5ZTERaQ1FVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTTdjMEpCUTNwQ0xFMUJRVTA3UVVGRFNDdzJRa0ZCU1N4RFFVRkRMRXRCUVVzc1IwRkJSeXhKUVVGSkxFTkJRVU1zUjBGQlJ5eEhRVUZITEVsQlFVa3NRMEZCUXl4VFFVRlRMRU5CUVVNN2MwSkJRekZETzJ0Q1FVTktPenRCUVVWRUxIRkNRVUZKTEVsQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExFZEJRVWNzUlVGQlJUdEJRVU4yUWl4NVFrRkJTU3hKUVVGSkxFTkJRVU1zU1VGQlNTeEZRVUZGTzBGQlExZ3NOa0pCUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzU1VGQlNTeERRVUZETEVkQlFVY3NRMEZCUXp0elFrRkRla0lzVFVGQlRUdEJRVU5JTERaQ1FVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eEhRVUZITEVkQlFVY3NTVUZCU1N4RFFVRkRMRk5CUVZNc1EwRkJRenR6UWtGRE1VTTdhMEpCUTBvN1FVRkRSQ3gzUWtGQlR5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRPMk5CUTNKQ096czdPMWxCTlVKblFpeExRVUZMT3pzN2EwSkJRVXdzUzBGQlN5eERPenM3T3pzN1FVTktNVUlzWVVGQldTeERRVUZET3pzN096czdPenRMUVVWT0xFbEJRVWtzZFVOQlFVMHNRMEZCWXpzN1MwRkRlRUlzUzBGQlN5eDFRMEZCVFN4RlFVRlRPenRMUVVWT0xFOUJRVTg3UVVGRllpeGpRVVpOTEU5QlFVOHNSMEZGTWtJN1lVRkJka01zUjBGQlJ5eG5RMEZCUXl4RFFVRkRPMkZCUVVVc1IwRkJSeXhuUTBGQlF5eEZRVUZGTzJGQlFVVXNTVUZCU1N4blEwRkJReXhKUVVGSk8yRkJRVVVzUzBGQlN5eG5RMEZCUXl4TFFVRkxPenNyUWtGR2FFTXNUMEZCVHpzN1FVRkhjRUlzWVVGQlNTeERRVUZETEVkQlFVY3NSMEZCUnl4SFFVRkhMRU5CUVVNN1FVRkRaaXhoUVVGSkxFTkJRVU1zUjBGQlJ5eEhRVUZITEVkQlFVY3NRMEZCUXp0QlFVTm1MR0ZCUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzUzBGQlN5eERRVUZETzBGQlEyNUNMR0ZCUVVrc1EwRkJReXhKUVVGSkxFZEJRVWNzU1VGQlNTeERRVUZETzBGQlEycENMR0ZCUVVrc1EwRkJReXhUUVVGVExFZEJRVWNzU1VGQlNTeExRVUZMTEVOQlFVTXNTVUZCU1N4RFFVRkRMRWRCUVVjc1JVRkJSU3hKUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEVOQlFVTTdRVUZETDBNc1lVRkJTU3hKUVVGSkxFTkJRVU1zUzBGQlN5eExRVUZITEV0QlFVc3NSVUZCUlR0QlFVTjBRaXhwUWtGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4SlFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzFWQlF6bENMRTFCUVUwN1FVRkRUQ3hwUWtGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRE8xVkJRM2hDTzAxQlEwbzdPMnRDUVdKblFpeFBRVUZQTzBGQk1FSndRaXhoUVVGSk8ydENRVmhCTEZWQlFVTXNTVUZCU1N4RlFVRkZPMEZCUTFnc2NVSkJRVWtzUlVGQlJTeEpRVUZKTEV0QlFVc3NTVUZCU1N4SlFVRkpMRWxCUVVrc1MwRkJTeXhOUVVGTkxFbEJRVWtzU1VGQlNTeExRVUZMTEZGQlFWRXNTVUZCU1N4SlFVRkpMRXRCUVVzc1QwRkJUeXhEUVVGRExFVkJRVVU3UVVGRE9VVXNORUpCUVU4c1EwRkJReXhMUVVGTExFTkJRVU1zSzBSQlFTdEVMRU5CUVVNc1EwRkJRenRCUVVNdlJTdzBRa0ZCVHp0clFrRkRWanRCUVVORUxIRkNRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJRenRCUVVOc1FpeHhRa0ZCU1N4SlFVRkpMRU5CUVVNc1MwRkJTeXhGUVVGRk8wRkJRMlFzZVVKQlFVa3NRMEZCUXl4SlFVRkpMRWRCUVVjc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0clFrRkRPVUk3WTBGRFNqdHJRa0ZGVHl4WlFVRkhPMEZCUTFBc2QwSkJRVThzU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXp0alFVTnlRanM3UVVGRlJDeGpRVUZMTzI5Q1FVRkJMR2xDUVVGSE8wRkJRMDRzY1VKQlFVa3NTVUZCU1N4RFFVRkRMRXRCUVVzc1MwRkJSeXhMUVVGTExFVkJRVVU3UVVGRGRFSXNlVUpCUVVrc1EwRkJReXhKUVVGSkxFZEJRVWNzU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenRCUVVNM1FpdzBRa0ZCVHl4SlFVRkpMRU5CUVVNc1NVRkJTU3hGUVVGRkxFTkJRVU03YTBKQlEzQkNPMEZCUTBRc2NVSkJRVWtzUTBGQlF5eFhRVUZYTEVkQlFVYzdRVUZEYWtJc2VVSkJRVTBzU1VGQlNTeERRVUZETEVkQlFVYzdRVUZEWkN3eVFrRkJVU3hKUVVGSkxFTkJRVU1zUjBGQlJ6dEJRVU5vUWl3MFFrRkJVeXhGUVVGRExFTkJRVU1zU1VGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4SlFVRkpMRU5CUVVNc1IwRkJSeXhGUVVGRExFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTTdRVUZETVVNc05rSkJRVlVzU1VGQlNTeERRVUZETEVWQlFVVXNRMEZCUXl4SlFVRkpMRU5CUVVNc1IwRkJSeXhGUVVGRExFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTTdhMEpCUTNKRExFTkJRVU03UVVGRFJpeHhRa0ZCU1N4RFFVRkRMRXRCUVVzc1IwRkJSeXhKUVVGSkxFTkJRVU1zVjBGQlZ5eERRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenRCUVVNeFF5eHhRa0ZCU1N4RFFVRkRMRWxCUVVrc1IwRkJSeXhKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUXpkQ0xIZENRVUZQTEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNN1kwRkRia0k3TzBGQlJVUXNWMEZCUlR0dlFrRkJRU3hqUVVGSE8wRkJRMFFzY1VKQlFVa3NRMEZCUXl4TFFVRkxMRVZCUVVVc1EwRkJRenRCUVVOaUxIRkNRVUZKTEVsQlFVa3NRMEZCUXl4TFFVRkxMRWxCUVVrc1NVRkJTU3hEUVVGRExFZEJRVWNzUlVGQlJUdEJRVU40UWl4NVFrRkJTU3hEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRPMnRDUVVONlFqdEJRVU5FTEhkQ1FVRlBMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU03WTBGRGNrSTdPMEZCUlVRc1lVRkJTVHR2UWtGQlFTeG5Ra0ZCUnp0QlFVTklMSEZDUVVGSkxFTkJRVU1zUzBGQlN5eEZRVUZGTEVOQlFVTTdRVUZEWWl4eFFrRkJTU3hKUVVGSkxFTkJRVU1zUzBGQlN5eEhRVUZITEVsQlFVa3NRMEZCUXl4SFFVRkhMRVZCUVVVN1FVRkRka0lzZVVKQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF6dHJRa0ZEZWtJN1FVRkRSQ3gzUWtGQlR5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRPMk5CUTNKQ096dEJRVVZFTEdWQlFVMDdiMEpCUVVFc2EwSkJRVWM3UVVGRFRDeHhRa0ZCU1N4RFFVRkRMRXRCUVVzc1IwRkJSeXhKUVVGSkxFTkJRVU1zUlVGQlJTeERRVUZETEVsQlFVa3NRMEZCUXl4SFFVRkhMRVZCUVVVc1NVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eERRVUZETzBGQlEzcERMSGRDUVVGUExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTTdZMEZEY2tJN08wRkJSVVFzWTBGQlN6dHZRa0ZCUVN4cFFrRkJSenRCUVVOS0xIRkNRVUZKTEVOQlFVTXNVMEZCVXl4RFFVRkRMRWRCUVVjc1IwRkJSeXhKUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETzBGQlF6bENMSEZDUVVGSkxFTkJRVU1zVTBGQlV5eERRVUZETEVkQlFVY3NSMEZCUnl4SlFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRE8wRkJRemxDTEhGQ1FVRkpMRU5CUVVNc1UwRkJVeXhEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRPMEZCUTJ4RExIRkNRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhUUVVGVExFTkJRVU1zU1VGQlNTeEZRVUZGTEVOQlFVTTdRVUZEYmtNc2QwSkJRVThzU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXp0alFVTnlRanM3T3p0WlFYcEZaMElzVDBGQlR6czdPMnRDUVVGUUxFOUJRVThzUXpzN096czdPMEZEVERWQ0xHRkJRVmtzUTBGQlF6czdPenM3T3pzN096czdPMEZCUldJc1MwRkJTU3hIUVVGSExFZEJRVWNzYlVKQlFVOHNRMEZCUXl4RFFVRmhMRU5CUVVNc1EwRkJRenRCUVVOcVF5eExRVUZKTEVsQlFVa3NSMEZCUnl4dFFrRkJUeXhEUVVGRExFTkJRV01zUTBGQlF5eERRVUZETzBGQlEyNURMRXRCUVVrc1UwRkJVeXhIUVVGSExHMUNRVUZQTEVOQlFVTXNRMEZCYlVJc1EwRkJReXhEUVVGRE8wRkJRemRETEV0QlFVa3NTVUZCU1N4SFFVRkhMRzFDUVVGUExFTkJRVU1zUlVGQlowSXNRMEZCUXl4RFFVRkRPenRMUVVONlFpeFhRVUZYTEN0RFFVRk5MRVZCUVhGQ096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenRMUVhsRE4wSXNTMEZCU3p0QlFVVmlMRmxCUmxFc1MwRkJTeXhIUVVWV096SkNRVVpMTEV0QlFVczdPMEZCU1hSQ0xGTkJRVWtzVDBGQlR5eEhRVUZITEVOQlFVTXNUMEZCVHl4RFFVRkRMRU5CUVVNN08wRkJSWGhDTEZOQlFVa3NVVUZCVVN4SFFVRkhPMEZCUTJJc1lVRkJVU3hEUVVGRExFZEJRVWNzUlVGQlF5eEhRVUZITEVOQlFVTTdRVUZEYWtJc1kwRkJVeXhIUVVGSE8wRkJRMW9zWVVGQlVTeFZRVUZWTzBGQlEyeENMR2xDUVVGWkxFTkJRMVlzUTBGQlF5eEhRVUZITEVWQlFVTXNSMEZCUnl4RFFVRkRMRVZCUTFRc1EwRkJReXhKUVVGSkxFVkJRVU1zU1VGQlNTeERRVUZETEVWQlExZ3NRMEZCUXl4SFFVRkhMRVZCUVVNc1IwRkJSeXhEUVVGRExFVkJRMVFzUTBGQlF5eEpRVUZKTEVWQlFVTXNTVUZCU1N4RFFVRkRMRVZCUTFnc1EwRkJReXhIUVVGSExFVkJRVU1zUjBGQlJ5eERRVUZETEVWQlExUXNRMEZCUXl4SlFVRkpMRVZCUVVNc1NVRkJTU3hEUVVGRExFVkJRMWdzUTBGQlF5eEhRVUZITEVWQlFVTXNSMEZCUnl4RFFVRkRMRVZCUTFRc1EwRkJReXhKUVVGSkxFVkJRVU1zU1VGQlNTeERRVUZETEVOQlExbzdUVUZEUml4RFFVRkRPenRCUVVWR0xHZERRWFJDYVVJc1MwRkJTeXcyUTBGelFtaENMRk5CUVZNc1JVRkJReXhQUVVGUExFVkJRVU1zVVVGQlVTeEZRVUZGT3p0QlFVVnNReXhUUVVGSkxFTkJRVU1zUzBGQlN5eEhRVUZITzBGQlExZ3NVVUZCUXl4RlFVRkZMRWxCUVVrc1NVRkJTU3hEUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVWQlFVTXNRMEZCUXl4RlFVRkRMRWRCUVVjc1EwRkJRenRCUVVOMFFpeFJRVUZETEVWQlFVVXNTVUZCU1N4SlFVRkpMRU5CUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVWQlFVTXNSMEZCUnl4RFFVRkRPMDFCUTNaQ0xFTkJRVU03T3pzN08wRkJTMFlzVTBGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFbEJRVWtzUTBGQlF6czdRVUZGTDBJc1UwRkJTU3hEUVVGRExGRkJRVkVzUjBGQlJ6dEJRVU5rTEZGQlFVTXNSVUZCUlN4SlFVRkpMRmRCUVZjc1EwRkJReXhOUVVGTkxFTkJRVU1zU1VGQlNTeERRVUZETEVsQlFVa3NSVUZCUXl4WlFVRlpMRVZCUVVNc1EwRkJReXhEUVVGRExFVkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RlFVRkRMRU5CUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUlVGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0QlFVTm9SaXhSUVVGRExFVkJRVVVzU1VGQlNTeFhRVUZYTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFVkJRVU1zVlVGQlZTeEZRVUZETEVOQlFVTXNRMEZCUXl4RlFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUlVGQlF5eERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRVZCUVVNc1EwRkJReXhEUVVGRExFTkJRVU03VFVGREwwVXNRMEZCUXp0QlFVTkdMRk5CUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF5eERRVUZETEV0QlFVc3NSMEZCUnl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU1zUTBGQlF5eFZRVUZWTEVOQlFVTTdRVUZEYUVRc1UwRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF5eERRVUZETEZWQlFWVXNRMEZCUXpzN096czdRVUZMYUVRc1UwRkJTU3hEUVVGRExGRkJRVkVzUjBGQlJ5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRkZCUVZFc1EwRkJRenM3T3pzN1FVRkxka01zVTBGQlNTeERRVUZETEV0QlFVc3NSMEZCUnl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUTBGQlF6czdPenM3UVVGTGFrTXNVMEZCU1N4RFFVRkRMRTFCUVUwc1IwRkJSeXhGUVVGRkxFTkJRVU03TzBGQlJXcENMRk5CUVVrc1EwRkJReXhKUVVGSkxFVkJRVVVzUTBGQlF6czdRVUZGV2l4VFFVRkpMRU5CUVVNc1pVRkJaU3hGUVVGRkxFTkJRVU03UVVGRGRrSXNVMEZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE8wbEJSV1k3TzJGQk4wUnJRaXhMUVVGTE96dG5Ra0ZCVEN4TFFVRkxPMEZCSzBSNFFpeHRRa0ZCWXp0alFVRkJMREJDUVVGSE96dEJRVVZtTEdGQlFVa3NRMEZCUXl4SlFVRkpMRWRCUVVjc1IwRkJSeXhEUVVGRExFMUJRVTBzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXpzN1FVRkhha01zWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WFFVRlhMRU5CUVVNc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eERRVUZET3pzN1FVRkpjRU1zWVVGQlNTeERRVUZETEdWQlFXVXNSMEZCUnl4RlFVRkZMRU5CUVVNN08wRkJSVEZDTEdOQlFVc3NTVUZCU1N4RFFVRkRMRWRCUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUjBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRTFCUVUwc1JVRkJReXhEUVVGRExFVkJRVVVzUlVGQlJUdEJRVU4yUXl4bFFVRkpMR05CUVdNc1IwRkJSeXhIUVVGSExFTkJRVU1zVFVGQlRTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRPenRCUVVVeFF5eGxRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmRCUVZjc1EwRkJReXhqUVVGakxFTkJRVU1zUTBGQlF6czdRVUZGZWtNc1pVRkJTU3hEUVVGRExHVkJRV1VzUTBGQlF5eEpRVUZKTEVOQlFVTXNZMEZCWXl4RFFVRkRMRU5CUVVNN1ZVRkRNME03VVVGRlJqczdRVUZGUkN4clFrRkJZVHRqUVVGQkxIbENRVUZIT3p0QlFVVldMR0ZCUVVrc1EwRkJReXhoUVVGaExFZEJRVWNzU1VGQlNTeERRVUZETEVkQlFVY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXpzN1FVRkZkRVFzWVVGQlNTeERRVUZETEZWQlFWVXNSMEZCUnp0QlFVTm9RaXhqUVVGSExFVkJRVVVzUlVGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4aFFVRmhMRWRCUVVNc1IwRkJSeXhEUVVGRExFZEJRVWNzUTBGQlF5eEhRVUZITEVOQlFVTXNSVUZEZUVNc1EwRkJRenRCUVVOR0xHRkJRVWtzUTBGQlF5eFZRVUZWTEVOQlFVTXNSVUZCUlN4SFFVRkhMRWxCUVVrc1EwRkJReXhWUVVGVkxFTkJRVU1zUjBGQlJ5eEhRVUZITEVOQlFVTXNRMEZCUXpzN1FVRkZOME1zWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hGUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVkQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRNVU1zWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRNME1zWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1IwRkJSeXhGUVVGRExFbEJRVWtzUTBGQlF5eFZRVUZWTEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNN08wRkJSV2hFTEdOQlFVc3NTVUZCU1N4RFFVRkRMRWRCUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUjBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRTFCUVUwc1JVRkJReXhEUVVGRExFVkJRVVVzUlVGQlJUdEJRVU4yUXl4bFFVRkpMR05CUVdNc1IwRkJSeXhKUVVGSkxFTkJRVU1zWlVGQlpTeERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXpkRExHVkJRVWtzVDBGQlR5eEhRVUZITEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU03UVVGREwwSXNlVUpCUVdNc1EwRkJReXhaUVVGWkxFTkJRVU1zU1VGQlNTeEZRVUZETEU5QlFVOHNRMEZCUXl4RFFVRkRMRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZEZUVRc2VVSkJRV01zUTBGQlF5eFpRVUZaTEVOQlFVTXNTVUZCU1N4RlFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRExFTkJRVU1zUjBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN1FVRkRla1FzZVVKQlFXTXNRMEZCUXl4WlFVRlpMRU5CUVVNc1IwRkJSeXhGUVVGRExFbEJRVWtzUTBGQlF5eGhRVUZoTEVkQlFVTXNSVUZCUlN4SFFVRkhMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRek5FTEhsQ1FVRmpMRU5CUVVNc1dVRkJXU3hEUVVGRExHTkJRV01zUlVGQlJTeEhRVUZITEVOQlFVTXNRMEZCUXp0VlFVTnNSRHM3UVVGRlNDeGhRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF5eERRVUZETEVWQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhGUVVGRExFTkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNSVUZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRM1pFTEdGQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJReXhEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETEVOQlFVTXNSVUZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFVkJRVU1zUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU03T3pzN08wRkJTM1pFTEdGQlFVa3NRMEZCUXl4bFFVRmxMRVZCUVVVc1EwRkJRenRCUVVOMlFpeGhRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1VVRkZha0k3TzBGQlJVUXNiVUpCUVdNN1kwRkJRU3d3UWtGQlJ6czdRVUZGWml4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFdEJRVXNzUTBGQlF5eGxRVUZsTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhKUVVGSkxFTkJRVU03UVVGRGRFUXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhaUVVGWkxFTkJRVU1zVFVGQlRTeEZRVUZGTEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1YwRkJWeXhEUVVGRExFTkJRVU03TzBGQlJYaEVMR05CUVVzc1NVRkJTU3hEUVVGRExFZEJRVU1zUTBGQlF5eEZRVUZETEVOQlFVTXNSMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFMUJRVTBzUlVGQlF5eERRVUZETEVWQlFVVXNSVUZCUlR0QlFVTjJReXhsUVVGSkxHTkJRV01zUjBGQlJ5eEpRVUZKTEVOQlFVTXNaVUZCWlN4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRemRETEhsQ1FVRmpMRU5CUVVNc1dVRkJXU3hEUVVGRExFMUJRVTBzUlVGQlJTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRE8wRkJRM2hFTEhsQ1FVRmpMRU5CUVVNc1dVRkJXU3hEUVVGRExGRkJRVkVzUlVGQlJTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRE8xVkJRek5FTzFGQlJVWTdPMEZCUlVRc1YwRkJUVHRqUVVGQkxHdENRVUZITzBGQlExQXNZVUZCU1N4RFFVRkRMR1ZCUVdVc1IwRkJSenRCUVVOeVFpeFpRVUZETEVWQlFVVXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRVU1zVlVGQlZTeEhRVUZITEVsQlFVa3NRMEZCUXl4TFFVRkxPMEZCUTNaRExGbEJRVU1zUlVGQlJTeEpRVUZKTEVOQlFVTXNUVUZCVFN4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF5eERRVUZETEZWQlFWVXNSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUVHRWUVVOMlJDeERRVUZET3p0QlFVVkdMR0ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zV1VGQldTeERRVUZETEVsQlFVa3NSVUZCUXl4SlFVRkpMRU5CUVVNc1pVRkJaU3hEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzBGQlEzQkVMR0ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zV1VGQldTeERRVUZETEVsQlFVa3NSVUZCUXl4SlFVRkpMRU5CUVVNc1pVRkJaU3hEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzFGQlEzSkVPenRCUVVkRUxGVkJRVXM3WTBGQlFTeHBRa0ZCUnp0QlFVTk9MR0ZCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF5eERRVUZETEUxQlFVMHNSMEZCUnl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRE8wRkJRM0JETEdGQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJReXhEUVVGRExFMUJRVTBzUjBGQlJ5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRPMEZCUTNCRExHRkJRVWtzUTBGQlF5eEpRVUZKTEVWQlFVVXNRMEZCUXp0UlFVTmlPenRCUVVWRUxGTkJRVWs3WTBGQlFTeG5Ra0ZCUnp0QlFVTk1MR0ZCUVVrc1NVRkJTU3hEUVVGRExFOUJRVThzUlVGQlJUdEJRVU5vUWl4bFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU1zUTBGQlF5eE5RVUZOTEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8wRkJRMjVETEdWQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJReXhEUVVGRExFMUJRVTBzUTBGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN096czdPMEZCUzI1RExHVkJRVWtzUTBGQlF5eGxRVUZsTEVWQlFVVXNRMEZCUXp0QlFVTjJRaXhsUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNSVUZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03UVVGRGFFTXNaVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE8xVkJRMlk3VVVGRFJqczdRVUZGUkN4WlFVRlBPMk5CUVVFc2JVSkJRVWM3UVVGRFVpeGhRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1VVRkRaanM3UVVGRlJ5eGxRVUZWTzFsQlFVRXNXVUZCUnp0QlFVTm1MR2RDUVVGUE8wRkJRMHdzV1VGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJReXhEUVVGRExGVkJRVlU3UVVGRE1VSXNXVUZCUXl4RlFVRkZMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF5eERRVUZETEZWQlFWVTdWVUZETTBJc1EwRkJRenRSUVVOSU96dEJRVVZFTEc5Q1FVRmxPMk5CUVVFc01rSkJRVWM3T3p0QlFVTm9RaXhoUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTXNRMEZCUXl4WlFVRlpMRU5CUVVVc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVTXNTMEZCU3l4RFFVRkZMRU5CUVVNN1FVRkRia1FzWVVGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRMRU5CUVVNc1dVRkJXU3hEUVVGRkxFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXl4RFFVRkRMRXRCUVVzc1EwRkJSU3hEUVVGRE8wRkJRMjVFTEdGQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1JVRkJSU3hEUVVGRE8wRkJRMnBDTEdGQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1QwRkJUeXhEUVVGRExGVkJRVU1zUTBGQlF5eEZRVUZETEVOQlFVTXNSVUZCU3p0QlFVTTNRaXhsUVVGSkxGRkJRVkVzUjBGQlJ5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zUjBGQlF5eE5RVUZMTEV0QlFVc3NSVUZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExFZEJRVU1zVFVGQlN5eE5RVUZOTEVWQlFVTXNUVUZCU3l4UlFVRlJMRU5CUVVNc1EwRkJReXhEUVVGRExFdEJRVXNzUjBGQlF5eE5RVUZMTEV0QlFVc3NSVUZCUXl4RFFVRkRMRU5CUVVNc1IwRkJReXhOUVVGTExGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVTXNTMEZCU3l4SlFVRkZMRTFCUVVzc1RVRkJUU3hEUVVGRExFTkJRVU03UVVGRGRFa3NaVUZCU1N4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eERRVUZETEVkQlFVTXNVVUZCVVN4SlFVRkZMRTFCUVVzc1MwRkJTeXhIUVVGRExFMUJRVXNzUzBGQlN5eERRVUZETEVWQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRemxFTEdsQ1FVRkxMRTFCUVUwc1EwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZEZUVJc2FVSkJRVXNzWlVGQlpTeERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRmxCUVZrc1EwRkJReXhqUVVGakxFVkJRVVVzUzBGQlN5eERRVUZETEVOQlFVTTdWVUZETjBRc1EwRkJReXhEUVVGRE8xRkJRMG83TzBGQlQwUXNaVUZCVlRzN096czdPenM3WTBGQlFTeHZRa0ZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhGUVVGRk8wRkJRMlFzWVVGQlNTeFJRVUZSTEVkQlFVYzdRVUZEWWl4WlFVRkRMRVZCUVVVc1EwRkJReXhIUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTzBGQlEyWXNXVUZCUXl4RlFVRkZMRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRUdFZRVU5xUWl4RFFVRkRPMEZCUTBZc1lVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVTXNUVUZCVFN4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRE8wRkJRMnBETEdGQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJReXhEUVVGRExFMUJRVTBzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXp0QlFVTnFReXhoUVVGSkxFTkJRVU1zWlVGQlpTeEZRVUZGTEVOQlFVTTdRVUZEZGtJc1lVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eFJRVUZSTEVWQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRE8wRkJRMmhETEdGQlFVa3NRMEZCUXl4TlFVRk5MRVZCUVVVc1EwRkJRenRSUVVObU96dEJRVkZFTEdkQ1FVRlhPenM3T3pzN096czdZMEZCUVN4eFFrRkJReXhMUVVGTExFVkJRVU1zUTBGQlF5eEZRVUZETEVOQlFVTXNSVUZCUlRzN1FVRkZja0lzWVVGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4TFFVRkxMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0QlFVTTNRaXhoUVVGSkxFTkJRVU1zWlVGQlpTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRMRmxCUVZrc1EwRkJReXhKUVVGSkxFVkJRVVVzUTBGQlF5eEhRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenRCUVVNM1JDeGhRVUZKTEVOQlFVTXNaVUZCWlN4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRExGbEJRVmtzUTBGQlF5eEpRVUZKTEVWQlFVVXNRMEZCUXl4SFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dEJRVU01UkN4aFFVRkpMRU5CUVVNc1pVRkJaU3hGUVVGRkxFTkJRVU03UVVGRGRrSXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFVkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRPMEZCUTJoRExHRkJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXp0UlFVVm1PenM3T3pzN096czdRVUZCUVRzN08xVkJlRTVyUWl4TFFVRkxPMGxCUVZNc1UwRkJVenM3YTBKQlFYWkNMRXRCUVVzc1F6czdPenM3TzBGREwwTXhRaXhoUVVGWkxFTkJRVU03T3pzN096czdPenM3UVVGRllpeExRVUZKTEVsQlFVa3NSMEZCUnl4dFFrRkJUeXhEUVVGRExFTkJRV01zUTBGQlF5eERRVUZETzBGQlEyNURMRXRCUVVrc1IwRkJSeXhIUVVGSExHMUNRVUZQTEVOQlFVTXNRMEZCWVN4RFFVRkRMRU5CUVVNN1FVRkRha01zUzBGQlNTeFRRVUZUTEVkQlFVY3NiVUpCUVU4c1EwRkJReXhEUVVGdFFpeERRVUZETEVOQlFVTTdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN1MwRjVRbmhDTEVsQlFVazdRVUZGV2l4WlFVWlJMRWxCUVVrc1IwRkZWRHN5UWtGR1N5eEpRVUZKT3p0QlFVbHlRaXhUUVVGSkxFOUJRVThzUjBGQlJ5eERRVUZETEU5QlFVOHNRMEZCUXl4RFFVRkRPenRCUVVWNFFpeFRRVUZKTEZGQlFWRXNSMEZCUnp0QlFVTmlMR0ZCUVZFc1EwRkJReXhGUVVGRkxFVkJRVU1zUlVGQlJTeERRVUZETzAxQlEyaENMRU5CUVVNN08wRkJSVVlzWjBOQlZtbENMRWxCUVVrc05rTkJWV1lzVTBGQlV5eEZRVUZETEU5QlFVOHNSVUZCUXl4UlFVRlJMRVZCUVVVN08wRkJSV3hETEZOQlFVa3NRMEZCUXl4UFFVRlBMRWRCUVVjc1NVRkJTU3hEUVVGRE96dEJRVVZ3UWl4VFFVRkpMRU5CUVVNc1NVRkJTU3hGUVVGRkxFTkJRVU03T3pzN1FVRkpZaXhUUVVGSkxFTkJRVU1zVjBGQlZ5eEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eERRVUZET3pzN1FVRkhNVU1zVTBGQlNTeE5RVUZOTEVOQlFVTXNjMEpCUVhOQ0xFVkJRVVU3UVVGRGJFTXNWMEZCU1N4RFFVRkRMRzFDUVVGdFFpeEhRVUZITEUxQlFVMHNRMEZCUXl4blFrRkJaMElzUTBGQlF5eHRRa0ZCYlVJc1JVRkJSU3hKUVVGSkxFTkJRVU1zVjBGQlZ5eEZRVUZGTEV0QlFVc3NRMEZCUXl4RFFVRkRPMDFCUTJwSExFMUJRVTA3UVVGRFNpeFhRVUZKTEVOQlFVTXNUMEZCVHl4SFFVRkhMRXRCUVVzc1EwRkJRenRCUVVOeVFpeFhRVUZKTEVOQlFVTXNZMEZCWXl4RlFVRkZMRU5CUVVNN1RVRkRka0k3T3pzN096czdTVUZYUmp0QlFWaEZPMkZCTVVKblFpeEpRVUZKT3p0blFrRkJTaXhKUVVGSk8wRkJkME4yUWl4dFFrRkJZenRqUVVGQkxEQkNRVUZIT3p0QlFVVm1MR0ZCUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzUjBGQlJ5eERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVOb1F5eGhRVUZKTEVOQlFVTXNUMEZCVHl4SFFVRkhMRWRCUVVjc1EwRkJReXhOUVVGTkxFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTTdRVUZEY0VNc1lVRkJTU3hEUVVGRExFOUJRVThzUjBGQlJ5eEhRVUZITEVOQlFVTXNUVUZCVFN4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRE8wRkJRM0JETEdGQlFVa3NRMEZCUXl4UFFVRlBMRWRCUVVjc1IwRkJSeXhEUVVGRExFMUJRVTBzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXpzN1FVRkZjRU1zWVVGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4SFFVRkhMRU5CUVVNc1RVRkJUU3hEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETzBGQlF5OUNMR0ZCUVVrc1EwRkJReXhKUVVGSkxFZEJRVWNzUjBGQlJ5eERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVNdlFpeGhRVUZKTEVOQlFVTXNTVUZCU1N4SFFVRkhMRWRCUVVjc1EwRkJReXhOUVVGTkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdPMEZCUlM5Q0xHRkJRVWtzUTBGQlF5eExRVUZMTEVkQlFVY3NSMEZCUnl4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dEJRVU5vUXl4aFFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFZEJRVWNzUTBGQlF5eE5RVUZOTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN1FVRkRhRU1zWVVGQlNTeERRVUZETEV0QlFVc3NSMEZCUnl4SFFVRkhMRU5CUVVNc1RVRkJUU3hEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZET3p0QlFVVm9ReXhoUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZsQlFWa3NRMEZCUXl4VFFVRlRMRVZCUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03UVVGRGVFTXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhaUVVGWkxFTkJRVU1zVTBGQlV5eEZRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTNoRExHRkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRk5CUVZNc1JVRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dEJRVU40UXl4aFFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExGbEJRVmtzUTBGQlF5eFRRVUZUTEVWQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1FVRkRla01zWVVGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4WlFVRlpMRU5CUVVNc1UwRkJVeXhGUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzBGQlEzcERMR0ZCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zV1VGQldTeERRVUZETEZOQlFWTXNSVUZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenM3UVVGRmVrTXNZVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhaUVVGWkxFTkJRVU1zU1VGQlNTeEZRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVNc1EwRkJReXhIUVVGRExFVkJRVVVzUTBGQlF5eERRVUZETzBGQlEyaEVMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zV1VGQldTeERRVUZETEVsQlFVa3NSVUZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGRExFTkJRVU1zUjBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0QlFVTm9SQ3hoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZsQlFWa3NRMEZCUXl4SFFVRkhMRVZCUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUjBGQlF5eEZRVUZGTEVOQlFVTXNRMEZCUXp0QlFVTTVReXhoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZsQlFWa3NRMEZCUXl4VFFVRlRMRVZCUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03TzBGQlJUTkRMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zV1VGQldTeERRVUZETEVsQlFVa3NSVUZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGRExFTkJRVU1zUjBGQlF5eEZRVUZGTEVOQlFVTXNRMEZCUXp0QlFVTm9SQ3hoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZsQlFWa3NRMEZCUXl4SlFVRkpMRVZCUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUjBGQlF5eERRVUZETEVkQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRhRVFzWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1IwRkJSeXhGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVTXNSVUZCUlN4RFFVRkRMRU5CUVVNN1FVRkRPVU1zWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1UwRkJVeXhGUVVGRExFdEJRVXNzUTBGQlF5eERRVUZET3p0QlFVVXpReXhoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZsQlFWa3NRMEZCUXl4SlFVRkpMRVZCUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUjBGQlF5eERRVUZETEVkQlFVTXNSVUZCUlN4RFFVRkRMRU5CUVVNN1FVRkRhRVFzWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVTXNRMEZCUXl4SFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRMmhFTEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1dVRkJXU3hEUVVGRExFZEJRVWNzUlVGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4SFFVRkRMRVZCUVVVc1EwRkJReXhEUVVGRE8wRkJRemxETEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1dVRkJXU3hEUVVGRExGTkJRVk1zUlVGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXpzN1FVRkhNME1zWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1kwRkJZeXhGUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1IwRkJReXhGUVVGRkxFTkJRVU1zUTBGQlF5eERRVUZETzBGQlEyeEZMR0ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zV1VGQldTeERRVUZETEdOQlFXTXNSVUZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVTXNSVUZCUlN4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOc1JTeGhRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRmxCUVZrc1EwRkJReXhqUVVGakxFVkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGRExFVkJRVVVzUTBGQlF5eERRVUZETEVOQlFVTTdPMEZCUld4RkxHRkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hOUVVGTkxFTkJRVU1zUTBGQlF6dEJRVU4yUXl4aFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGbEJRVmtzUTBGQlF5eE5RVUZOTEVWQlFVVXNUVUZCVFN4RFFVRkRMRU5CUVVNN1FVRkRka01zWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1RVRkJUU3hGUVVGRkxFMUJRVTBzUTBGQlF5eERRVUZET3p0QlFVVjJReXhoUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEZsQlFWa3NRMEZCUXl4alFVRmpMRVZCUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4SFFVRkRMRVZCUVVVc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRGJrVXNZVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhaUVVGWkxFTkJRVU1zWTBGQll5eEZRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUjBGQlF5eEZRVUZGTEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUTI1RkxHRkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNXVUZCV1N4RFFVRkRMR05CUVdNc1JVRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVNc1JVRkJSU3hEUVVGRExFTkJRVU1zUTBGQlF6czdRVUZGYmtVc1lVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eFpRVUZaTEVOQlFVTXNUVUZCVFN4RlFVRkZMRTFCUVUwc1EwRkJReXhEUVVGRE8wRkJRM2hETEdGQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1dVRkJXU3hEUVVGRExFMUJRVTBzUlVGQlJTeE5RVUZOTEVOQlFVTXNRMEZCUXp0QlFVTjRReXhoUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEZsQlFWa3NRMEZCUXl4TlFVRk5MRVZCUVVVc1RVRkJUU3hEUVVGRExFTkJRVU03TzBGQlIzaERMR0ZCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zV1VGQldTeERRVUZETEVkQlFVY3NSVUZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzBGQlF6RkRMR0ZCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zV1VGQldTeERRVUZETEVkQlFVY3NSVUZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGRExFTkJRVU1zUjBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0QlFVTTNReXhoUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEZsQlFWa3NRMEZCUXl4WFFVRlhMRVZCUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03UVVGRE5VTXNZVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhaUVVGWkxFTkJRVU1zWVVGQllTeEZRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRPMEZCUXpsRExHRkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNXVUZCV1N4RFFVRkRMR2RDUVVGblFpeEZRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTJoRUxHRkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNXVUZCV1N4RFFVRkRMRk5CUVZNc1JVRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dEJRVU42UXl4aFFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExGbEJRVmtzUTBGQlF5eGhRVUZoTEVWQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNN1FVRkRhRVFzWVVGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4WFFVRlhMRWRCUVVjc1RVRkJUU3hEUVVGRE96dEJRVWRvUXl4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExGZEJRVmNzUTBGQlF5eEpRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRU5CUVVNN1FVRkRka01zWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WFFVRlhMRU5CUVVNc1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eERRVUZETzBGQlEzWkRMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zVjBGQlZ5eERRVUZETEVsQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1EwRkJRenM3UVVGRmRrTXNZVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhYUVVGWExFTkJRVU1zU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4RFFVRkRPMEZCUTNCRExHRkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNWMEZCVnl4RFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUTBGQlF6dEJRVU53UXl4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExGZEJRVmNzUTBGQlF5eEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRU5CUVVNN08wRkJSWEJETEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1YwRkJWeXhEUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0QlFVTnlReXhoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZkQlFWY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03UVVGRGNrTXNZVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhYUVVGWExFTkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPenRCUVVWeVF5eGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmRCUVZjc1EwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdVVUZGZEVNN08wRkJSVVFzYlVKQlFXTTdZMEZCUVN3d1FrRkJSenM3UVVGRlppeGhRVUZKTEVsQlFVa3NRMEZCUXl4UFFVRlBMRVZCUVVVN1FVRkRhRUlzWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4TFFVRkxMRU5CUVVNc1pVRkJaU3hIUVVGSExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUVUZCVFN4RFFVRkRPMEZCUTNoRUxHVkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRTFCUVUwc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTNCRUxHVkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRTFCUVUwc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTNCRUxHVkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRTFCUVUwc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTNCRUxHVkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTNSRUxHVkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTNSRUxHVkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTNSRUxHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTI1RUxHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTI1RUxHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTI1RUxHVkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNXVUZCV1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTNCRUxHVkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNXVUZCV1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTNCRUxHVkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNXVUZCV1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTNCRUxHVkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNXVUZCV1N4RFFVRkRMRTFCUVUwc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMVZCUTI1RUxFMUJRVTA3UVVGRFRDeGxRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1EwRkJReXhsUVVGbExFZEJRVWNzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SlFVRkpMRU5CUVVNN1FVRkRkRVFzWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1RVRkJUU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1FVRkRNVVFzWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1RVRkJUU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1FVRkRNVVFzWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1RVRkJUU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1FVRkRNVVFzWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1FVRkROVVFzWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1FVRkROVVFzWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1FVRkROVVFzWlVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1FVRkRla1FzWlVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1FVRkRla1FzWlVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1FVRkRla1FzWlVGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1FVRkRNVVFzWlVGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1FVRkRNVVFzWlVGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1FVRkRNVVFzWlVGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4WlFVRlpMRU5CUVVNc1RVRkJUU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVNN1ZVRkRla1E3VVVGRlJqczdRVUZGUkN4WFFVRk5PMk5CUVVFc1owSkJRVU1zUTBGQlF5eEZRVUZGTzBGQlExSXNZVUZCU1N4SlFVRkpMRU5CUVVNc1QwRkJUeXhGUVVGRE96dEJRVVZtTEdWQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1EwRkJReXhKUVVGSkxFTkJRVU03UVVGRFppeGxRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNc1MwRkJTeXhEUVVGRE8wRkJRMmhDTEdWQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1EwRkJReXhMUVVGTExFTkJRVU03T3p0QlFVZG9RaXhaUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhGUVVGRkxFVkJRVU1zUlVGQlJTeEZRVUZETEVOQlFVTXNSVUZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVNM1FpeFpRVUZETEVkQlFVY3NTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRExFVkJRVU1zUTBGQlF5eEZRVUZGTEVWQlFVTXNSVUZCUlN4RlFVRkRMRU5CUVVNc1JVRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU0zUWl4WlFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETEVWQlFVTXNRMEZCUXl4RlFVRkRMRWRCUVVjc1JVRkJReXhEUVVGRExFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdPMEZCUnpWQ0xHVkJRVWtzV1VGQldTeEhRVUZITzBGQlEycENMR3RDUVVGTExFVkJRVVVzU1VGQlNTeERRVUZETEVWQlFVVXNSMEZCUXl4SFFVRkhPMEZCUTJ4Q0xHZENRVUZITEVWQlFVVXNTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJSU3hKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTXNSVUZCUXl4RFFVRkRMRVZCUVVNc1IwRkJSeXhGUVVGRExFbEJRVWtzUTBGQlF5eEZRVUZGTEVkQlFVTXNSMEZCUnl4RlFVRkRMRWxCUVVrc1EwRkJReXhGUVVGRkxFZEJRVU1zUjBGQlJ5eERRVUZETEVWQlFVY3NTVUZCU1N4RFFVRkRMRVZCUVVVc1IwRkJReXhIUVVGSExFVkJRVVVzU1VGQlNTeERRVUZETEVWQlFVVXNSMEZCUXl4SFFVRkhMRU5CUVVVN1dVRkRla1lzUTBGQlF6dEJRVU5HTEdWQlFVa3NZVUZCWVN4SFFVRkhPMEZCUTJ4Q0xHdENRVUZMTEVWQlFVVXNTVUZCU1N4RFFVRkRMRVZCUVVVc1IwRkJReXhIUVVGSE8wRkJRMnhDTEdkQ1FVRkhMRVZCUVVVc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlJTeEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNc1JVRkJReXhIUVVGSExFVkJRVU1zUTBGQlF5eEZRVUZETEVsQlFVa3NRMEZCUXl4RlFVRkZMRWRCUVVNc1IwRkJSeXhGUVVGRExFbEJRVWtzUTBGQlF5eEZRVUZGTEVkQlFVTXNSMEZCUnl4RFFVRkRMRVZCUVVjc1NVRkJTU3hEUVVGRExFVkJRVVVzUjBGQlF5eEhRVUZITEVWQlFVVXNTVUZCU1N4RFFVRkRMRVZCUVVVc1IwRkJReXhIUVVGSExFTkJRVVU3V1VGRGVrWXNRMEZCUXpzN1FVRkZSaXhsUVVGSkxGVkJRVlVzUjBGQlJ5eEhRVUZITEVOQlFVTXNSMEZCUnl4RFFVRkRMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUlVGQlJTeERRVUZETEU5QlFVOHNRMEZCUXl4TFFVRkxMRVZCUVVVc1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eEZRVUZGTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1JVRkJSU3hKUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEVOQlFVTXNRMEZCUXl4UFFVRlBMRU5CUVVNc1MwRkJTeXhGUVVGRkxGbEJRVmtzUTBGQlF5eExRVUZMTEVWQlFVVXNXVUZCV1N4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE8wRkJRek5LTEdWQlFVa3NWMEZCVnl4SFFVRkhMRWRCUVVjc1EwRkJReXhIUVVGSExFTkJRVU1zU1VGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4RlFVRkZMRU5CUVVNc1QwRkJUeXhEUVVGRExFdEJRVXNzUlVGQlJTeEpRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRVZCUVVVc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eEZRVUZGTEVsQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1EwRkJReXhEUVVGRExFOUJRVThzUTBGQlF5eExRVUZMTEVWQlFVVXNZVUZCWVN4RFFVRkRMRXRCUVVzc1JVRkJSU3hoUVVGaExFTkJRVU1zUjBGQlJ5eERRVUZETEVOQlFVTTdPMEZCUlRsS0xHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWRCUVVjc1JVRkJSU3hWUVVGVkxFTkJRVU1zUTBGQlF6dEJRVU40UXl4bFFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExGbEJRVmtzUTBGQlF5eEhRVUZITEVWQlFVVXNWMEZCVnl4RFFVRkRMRU5CUVVNN08wRkJUVEZETEhWQ1FVRlpMRWRCUVVjN1FVRkRZaXhyUWtGQlN5eEZRVUZGTEVsQlFVa3NRMEZCUXl4RlFVRkZMRWRCUVVNc1IwRkJSenRCUVVOc1FpeG5Ra0ZCUnl4RlFVRkZMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVVVzU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhGUVVGRExFZEJRVWNzUlVGQlF5eEpRVUZKTEVOQlFVTXNSVUZCUlN4SFFVRkRMRWRCUVVjc1JVRkJReXhKUVVGSkxFTkJRVU1zUlVGQlJTeEhRVUZETEVkQlFVY3NRMEZCUXl4RlFVRkhMRWxCUVVrc1EwRkJReXhGUVVGRkxFZEJRVU1zUjBGQlJ5eEZRVUZGTEVsQlFVa3NRMEZCUXl4RlFVRkZMRWRCUVVNc1IwRkJSeXhEUVVGRk8xbEJRM3BHTEVOQlFVTTdRVUZEUml4M1FrRkJZU3hIUVVGSE8wRkJRMlFzYTBKQlFVc3NSVUZCUlN4SlFVRkpMRU5CUVVNc1JVRkJSU3hIUVVGRExFZEJRVWM3UVVGRGJFSXNaMEpCUVVjc1JVRkJSU3hKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZGTEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJReXhGUVVGRExFZEJRVWNzUlVGQlF5eERRVUZETEVWQlFVTXNTVUZCU1N4RFFVRkRMRVZCUVVVc1IwRkJReXhIUVVGSExFVkJRVU1zU1VGQlNTeERRVUZETEVWQlFVVXNSMEZCUXl4SFFVRkhMRU5CUVVNc1JVRkJSeXhKUVVGSkxFTkJRVU1zUlVGQlJTeEhRVUZETEVkQlFVY3NSVUZCUlN4SlFVRkpMRU5CUVVNc1JVRkJSU3hIUVVGRExFZEJRVWNzUTBGQlJUdFpRVU42Uml4RFFVRkRPenRCUVVWR0xIRkNRVUZWTEVkQlFVY3NSMEZCUnl4RFFVRkRMRWRCUVVjc1EwRkJReXhKUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEVWQlFVVXNRMEZCUXl4UFFVRlBMRU5CUVVNc1MwRkJTeXhGUVVGRkxFbEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNSVUZCUlN4RFFVRkRMRTlCUVU4c1EwRkJReXhMUVVGTExFVkJRVVVzU1VGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4RFFVRkRMRU5CUVVNc1QwRkJUeXhEUVVGRExFdEJRVXNzUlVGQlJTeFpRVUZaTEVOQlFVTXNTMEZCU3l4RlFVRkZMRmxCUVZrc1EwRkJReXhIUVVGSExFTkJRVU1zUTBGQlF6dEJRVU4yU2l4elFrRkJWeXhIUVVGSExFZEJRVWNzUTBGQlF5eEhRVUZITEVOQlFVTXNTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhGUVVGRkxFTkJRVU1zVDBGQlR5eERRVUZETEV0QlFVc3NSVUZCUlN4SlFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFVkJRVVVzUTBGQlF5eFBRVUZQTEVOQlFVTXNTMEZCU3l4RlFVRkZMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUTBGQlF5eERRVUZETEU5QlFVOHNRMEZCUXl4TFFVRkxMRVZCUVVVc1lVRkJZU3hEUVVGRExFdEJRVXNzUlVGQlJTeGhRVUZoTEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNN08wRkJSVEZLTEdWQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1dVRkJXU3hEUVVGRExFZEJRVWNzUlVGQlJTeFZRVUZWTEVOQlFVTXNRMEZCUXp0QlFVTjRReXhsUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEZsQlFWa3NRMEZCUXl4SFFVRkhMRVZCUVVVc1YwRkJWeXhEUVVGRExFTkJRVU03TzBGQlR6RkRMSFZDUVVGWkxFZEJRVWM3UVVGRFlpeHJRa0ZCU3l4RlFVRkZMRWxCUVVrc1EwRkJReXhGUVVGRkxFZEJRVU1zUjBGQlJ6dEJRVU5zUWl4blFrRkJSeXhGUVVGRkxFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVVXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRExFVkJRVU1zUTBGQlF5eEZRVUZETEVkQlFVY3NSVUZCUXl4SlFVRkpMRU5CUVVNc1JVRkJSU3hIUVVGRExFZEJRVWNzUlVGQlF5eEpRVUZKTEVOQlFVTXNSVUZCUlN4SFFVRkRMRWRCUVVjc1EwRkJReXhGUVVGSExFbEJRVWtzUTBGQlF5eEZRVUZGTEVkQlFVTXNSMEZCUnl4RlFVRkZMRWxCUVVrc1EwRkJReXhGUVVGRkxFZEJRVU1zUjBGQlJ5eERRVUZGTzFsQlEzcEdMRU5CUVVNN1FVRkRSaXgzUWtGQllTeEhRVUZITzBGQlEyUXNhMEpCUVVzc1JVRkJSU3hKUVVGSkxFTkJRVU1zUlVGQlJTeEhRVUZETEVkQlFVYzdRVUZEYkVJc1owSkJRVWNzUlVGQlJTeEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkZMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF5eEZRVUZETEVkQlFVY3NSVUZCUXl4RFFVRkRMRVZCUVVNc1NVRkJTU3hEUVVGRExFVkJRVVVzUjBGQlF5eEhRVUZITEVWQlFVTXNTVUZCU1N4RFFVRkRMRVZCUVVVc1IwRkJReXhIUVVGSExFTkJRVU1zUlVGQlJ5eEpRVUZKTEVOQlFVTXNSVUZCUlN4SFFVRkRMRWRCUVVjc1JVRkJSU3hKUVVGSkxFTkJRVU1zUlVGQlJTeEhRVUZETEVkQlFVY3NRMEZCUlR0WlFVTjZSaXhEUVVGRE96dEJRVVZHTEhGQ1FVRlZMRWRCUVVjc1IwRkJSeXhEUVVGRExFZEJRVWNzUTBGQlF5eEpRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRVZCUVVVc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eEZRVUZGTEVsQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1JVRkJSU3hEUVVGRExFOUJRVThzUTBGQlF5eExRVUZMTEVWQlFVVXNTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRExFTkJRVU1zVDBGQlR5eERRVUZETEV0QlFVc3NSVUZCUlN4WlFVRlpMRU5CUVVNc1MwRkJTeXhGUVVGRkxGbEJRVmtzUTBGQlF5eEhRVUZITEVOQlFVTXNRMEZCUXp0QlFVTjJTaXh6UWtGQlZ5eEhRVUZITEVkQlFVY3NRMEZCUXl4SFFVRkhMRU5CUVVNc1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eEZRVUZGTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1JVRkJSU3hKUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEVWQlFVVXNRMEZCUXl4UFFVRlBMRU5CUVVNc1MwRkJTeXhGUVVGRkxFbEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNRMEZCUXl4RFFVRkRMRTlCUVU4c1EwRkJReXhMUVVGTExFVkJRVVVzWVVGQllTeERRVUZETEV0QlFVc3NSVUZCUlN4aFFVRmhMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU03TzBGQlJURktMR1ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zV1VGQldTeERRVUZETEVkQlFVY3NSVUZCUlN4VlFVRlZMRU5CUVVNc1EwRkJRenRCUVVONFF5eGxRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRmxCUVZrc1EwRkJReXhIUVVGSExFVkJRVVVzVjBGQlZ5eERRVUZETEVOQlFVTTdPenM3T3pzN096czdPenM3T3pzN096dEJRWFZDTVVNc1pVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eFJRVUZSTEVWQlFVVTdRVUZEYkVJc1kwRkJReXhGUVVGRkxFTkJRVU03UVVGRFNpeGpRVUZETEVWQlFVVXNRMEZCUXp0QlFVTktMR05CUVVNc1JVRkJSU3hEUVVGRE8xbEJRMHdzUTBGQlF5eERRVUZETzFWQlJVbzdVVUZGUmpzN1FVRkZSQ3hWUVVGTE8yTkJRVUVzYVVKQlFVYzdRVUZEVGl4aFFVRkpMRTFCUVUwc1EwRkJReXh6UWtGQmMwSXNSVUZCUlR0QlFVTnFReXhsUVVGSkxFTkJRVU1zVFVGQlRTeEhRVUZITEVOQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJRenRWUVVNMVFqdFJRVU5HT3p0QlFWZEhMRmRCUVUwN096czdPenM3V1VGS1FTeFpRVUZITzBGQlExZ3NaMEpCUVU4c1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF6dFJRVU55UWp0WlFVVlRMRlZCUVVNc1JVRkJSU3hGUVVGRk8wRkJRMklzWVVGQlNTeERRVUZETEU5QlFVOHNSMEZCUnl4RlFVRkZMRU5CUVVNN1FVRkRiRUlzWVVGQlNTeERRVUZETEdOQlFXTXNSVUZCUlN4RFFVRkRPMUZCUTNaQ096dEJRVVZFTEd0Q1FVRmhPMk5CUVVFc2VVSkJRVWM3UVVGRFpDeGxRVUZOTEVOQlFVTXNiVUpCUVcxQ0xFTkJRVU1zYlVKQlFXMUNMRVZCUVVVc1NVRkJTU3hEUVVGRExGZEJRVmNzUlVGQlJTeExRVUZMTEVOQlFVTXNRMEZCUXp0UlFVTXhSVHM3T3p0VlFYSlNhMElzU1VGQlNUdEpRVUZUTEZOQlFWTTdPMnRDUVVGMFFpeEpRVUZKTEVNN096czdPenRCUXpkQ2VrSXNZVUZCV1N4RFFVRkRPenM3T3pzN096czdPMEZCUldJc1MwRkJTU3hIUVVGSExFZEJRVWNzYlVKQlFVOHNRMEZCUXl4RFFVRmhMRU5CUVVNc1EwRkJRenRCUVVOcVF5eExRVUZKTEVsQlFVa3NSMEZCUnl4dFFrRkJUeXhEUVVGRExFTkJRV01zUTBGQlF5eERRVUZETzBGQlEyNURMRXRCUVVrc1UwRkJVeXhIUVVGSExHMUNRVUZQTEVOQlFVTXNRMEZCYlVJc1EwRkJReXhEUVVGRE8wRkJRemRETEV0QlFVa3NZMEZCWXl4SFFVRkhMRzFDUVVGUExFTkJRVU1zUlVGQk9FSXNRMEZCUXl4RFFVRkRPMEZCUXpkRUxFdEJRVWtzUzBGQlN5eEhRVUZITEcxQ1FVRlBMRU5CUVVNc1EwRkJaU3hEUVVGRExFTkJRVU03TzB0QlNTOUNMRmxCUVZrN1FVRkZUQ3haUVVaUUxGbEJRVmtzUjBGRlJqczdPekpDUVVaV0xGbEJRVms3TzBGQlNXUXNVMEZCU1N4UFFVRlBMRWRCUVVjc1EwRkJReXhQUVVGUExFVkJRVU1zVDBGQlR5eERRVUZETEVOQlFVTTdPMEZCUldoRExGTkJRVWtzVVVGQlVTeEhRVUZITzBGQlEySXNZVUZCVVN4RFFVRkRMRWRCUVVjc1JVRkJReXhGUVVGRkxFTkJRVU03UVVGRGFFSXNiMEpCUVdVc1ZVRkJWVHRCUVVONlFpeGhRVUZSTEZWQlFWVTdRVUZEYkVJc1kwRkJVeXhEUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVOQlFVTTdRVUZEWkN4aFFVRlJMRU5CUVVNN1FVRkRWQ3hqUVVGVExFTkJRVU03UVVGRFZpeG5Ra0ZCVnl4SlFVRkpPMDFCUTJoQ0xFTkJRVU03TzBGQlJVWXNaME5CYUVKRkxGbEJRVmtzTmtOQlowSlNMRk5CUVZNc1JVRkJReXhQUVVGUExFVkJRVU1zVVVGQlVTeEZRVUZGT3pzN08wRkJTMnhETEZOQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1RVRkJUU3hGUVVGRk96dEJRVVZxUWl4WFFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExGbEJRVTA3UVVGRGFrSXNaVUZCU3l4WFFVRlhMRU5CUVVNc1YwRkJWeXhIUVVGSExFbEJRVWtzUTBGQlF6dEJRVU53UXl4bFFVRkxMRmRCUVZjc1EwRkJReXhoUVVGaExFZEJRVWM3UVVGREwwSXNaMEpCUVVzc1JVRkJSU3hOUVVGTExFdEJRVXM3UVVGRGFrSXNaMEpCUVVzc1JVRkJSU3hOUVVGTExFdEJRVXM3VlVGRGJFSXNRMEZCUXp0QlFVTkdMR1ZCUVVzc1NVRkJTU3hGUVVGRkxFTkJRVU03UVVGRFdpeGxRVUZMTEZkQlFWY3NRMEZCUXl4TlFVRk5MRU5CUVVNc1RVRkJTeXhMUVVGTExFTkJRVU1zUjBGQlJ5eE5RVUZMTEV0QlFVc3NRMEZCUXp0UlFVTnNSQ3hEUVVGRE8wRkJRMFlzVjBGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4blFrRkJaMElzUTBGQlF5eFhRVUZYTEVWQlFVVXNWVUZCUXl4RFFVRkRMRVZCUVVzN1FVRkRhRVFzWVVGQlNTeE5RVUZMTEZkQlFWY3NRMEZCUXl4WFFVRlhMRVZCUVVVN1FVRkRhRU1zWlVGQlNTeERRVUZETEUxQlFVc3NUVUZCVFN4RlFVRkZPMEZCUTJoQ0xHMUNRVUZMTEUxQlFVMHNSMEZCUnl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFMUJRVXNzVDBGQlR5eERRVUZETEVOQlFVTTdXVUZET1VNN1FVRkRSQ3hwUWtGQlN5eExRVUZMTEVkQlFVY3NSMEZCUnl4RFFVRkRMRmRCUVZjc1EwRkJReXhEUVVGRExFVkJRVU1zVFVGQlN5eE5RVUZOTEVOQlFVTXNRMEZCUXp0QlFVTTFReXhwUWtGQlN5eEpRVUZKTEVWQlFVVXNRMEZCUXp0QlFVTmFMR2xDUVVGTExGZEJRVmNzUTBGQlF5eE5RVUZOTEVOQlFVTXNUVUZCU3l4TFFVRkxMRU5CUVVNc1IwRkJSeXhOUVVGTExFdEJRVXNzUTBGQlF6dEJRVU5xUkN4bFFVRkpMRTFCUVVzc1YwRkJWeXhEUVVGRExHRkJRV0VzUlVGQlJUdEJRVU5zUXl4cFFrRkJTU3hSUVVGUkxFZEJRVWNzU1VGQlNTeERRVUZETEVkQlFVY3NRMEZCUXl4TlFVRkxMRmRCUVZjc1EwRkJReXhoUVVGaExFTkJRVU1zUzBGQlN5eEhRVUZETEUxQlFVc3NTMEZCU3l4RFFVRkRMRU5CUVVNN1FVRkRla1VzYVVKQlFVc3NVVUZCVVN4SFFVRkhMRU5CUVVNc1JVRkJSenRCUVVOc1FpeHRRa0ZCU1N4SFFVRkhMRWRCUVVjc1NVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eE5RVUZMTEZkQlFWY3NRMEZCUXl4aFFVRmhMRU5CUVVNc1MwRkJTeXhGUVVGRExFMUJRVXNzUzBGQlN5eERRVUZETEVOQlFVTTdRVUZEY0VVc2JVSkJRVWtzU1VGQlNTeEhRVUZITEVsQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1RVRkJTeXhYUVVGWExFTkJRVU1zWVVGQllTeERRVUZETEV0QlFVc3NSVUZCUXl4TlFVRkxMRXRCUVVzc1EwRkJReXhEUVVGRE8wRkJRM0pGTEcxQ1FVRkpMRkZCUVZFc1IwRkJSeXhOUVVGTExGZEJRVmNzUTBGQlF5eFBRVUZQTEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNc1MwRkJTeXhEUVVGRE8wRkJRMjVFTEcxQ1FVRkpMRk5CUVZNc1IwRkJSeXhOUVVGTExGZEJRVmNzUTBGQlF5eFBRVUZQTEVOQlFVTXNTVUZCU1N4RFFVRkRMRU5CUVVNc1MwRkJTeXhEUVVGRE8wRkJRM0pFTEc5Q1FVRkxMRWxCUVVrc1EwRkJReXhIUVVGRExFZEJRVWNzUlVGQlF5eERRVUZETEVkQlFVTXNTVUZCU1N4RlFVRkRMRU5CUVVNc1JVRkJSU3hGUVVGRk8wRkJRM3BDTEhWQ1FVRkxMRmRCUVZjc1EwRkJReXhQUVVGUExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVVVzUTBGQlF5eERRVUZETEVkQlFVTXNSMEZCUnl4SlFVRkZMRkZCUVZFc1JVRkJSU3hSUVVGUkxFVkJRVVVzVTBGQlV5eERRVUZGTEVOQlFVTTdRVUZEZWtZc2NVSkJRVWtzWVVGQllTeEhRVUZITEUxQlFVc3NWMEZCVnl4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eExRVUZMTEVOQlFVTTdRVUZEZEVRc2RVSkJRVXNzVjBGQlZ5eERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRMRU5CUVVNc1IwRkJSeXhoUVVGaExFTkJRVU03UVVGRE0wTXNkVUpCUVVzc1YwRkJWeXhEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETEVWQlFVTXNZVUZCWVN4RFFVRkRMRU5CUVVNN1owSkJRekZETzJOQlEwWTdXVUZEUmpzN1FVRkZSQ3hwUWtGQlN5eFhRVUZYTEVOQlFVTXNZVUZCWVN4SFFVRkhPMEZCUXk5Q0xHdENRVUZMTEVWQlFVVXNUVUZCU3l4TFFVRkxPMEZCUTJwQ0xHdENRVUZMTEVWQlFVVXNUVUZCU3l4TFFVRkxPMWxCUTJ4Q0xFTkJRVU03VlVGRFNEdFJRVU5HTEVOQlFVTXNRMEZCUXpzN1FVRkhTQ3hYUVVGSkxFTkJRVU1zU1VGQlNTeEhRVUZITEZsQlFVMHNSVUZEYWtJc1EwRkJRenRCUVVOR0xGZEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNaMEpCUVdkQ0xFTkJRVU1zVjBGQlZ5eEZRVUZGTEZWQlFVTXNRMEZCUXl4RlFVRkxPMEZCUTJoRUxHRkJRVWtzVFVGQlN5eFhRVUZYTEVOQlFVTXNWMEZCVnl4RlFVRkZPMEZCUTJoRExHVkJRVWtzUTBGQlF5eE5RVUZMTEUxQlFVMHNSVUZCUlR0QlFVTm9RaXh0UWtGQlN5eE5RVUZOTEVkQlFVY3NSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhOUVVGTExFOUJRVThzUTBGQlF5eERRVUZETzFsQlF6bERPMEZCUTBRc2FVSkJRVXNzUzBGQlN5eEhRVUZITEVkQlFVY3NRMEZCUXl4WFFVRlhMRU5CUVVNc1EwRkJReXhGUVVGRExFMUJRVXNzVFVGQlRTeERRVUZETEVOQlFVTTdRVUZETlVNc2FVSkJRVXNzUzBGQlN5eEZRVUZGTEVOQlFVTTdRVUZEWWl4cFFrRkJTeXhYUVVGWExFTkJRVU1zVFVGQlRTeERRVUZETEUxQlFVc3NTMEZCU3l4RFFVRkRMRWRCUVVjc1RVRkJTeXhMUVVGTExFTkJRVU03VlVGRGJFUTdVVUZEUml4RFFVRkRMRU5CUVVNN08wRkJSMGdzVjBGQlNTeERRVUZETEU5QlFVOHNSMEZCUnl4WlFVRk5PMEZCUTI1Q0xHVkJRVXNzVjBGQlZ5eERRVUZETEZkQlFWY3NSMEZCUnl4TFFVRkxMRU5CUVVNN1FVRkRja01zWlVGQlN5eFhRVUZYTEVOQlFVTXNZVUZCWVN4SFFVRkhMRXRCUVVzc1EwRkJRenRSUVVONFF5eERRVUZETzBGQlEwWXNWMEZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhuUWtGQlowSXNRMEZCUXl4VFFVRlRMRVZCUVVVc1dVRkJUVHRCUVVNM1F5eGhRVUZKTEUxQlFVc3NWMEZCVnl4RFFVRkRMRmRCUVZjc1JVRkJSVHRCUVVOb1F5eHBRa0ZCU3l4RlFVRkZMRVZCUVVVc1EwRkJRenRCUVVOV0xHbENRVUZMTEZkQlFWY3NRMEZCUXl4aFFVRmhMRWRCUVVjc1MwRkJTeXhEUVVGRE8wRkJRM1pETEdsQ1FVRkxMRmRCUVZjc1EwRkJReXhOUVVGTkxFTkJRVU1zVFVGQlN5eExRVUZMTEVOQlFVTXNSMEZCUnl4TlFVRkxMRXRCUVVzc1EwRkJRenRWUVVOc1JEdFJRVU5HTEVOQlFVTXNRMEZCUXp0QlFVTklMRmRCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1ZVRkJWU3hGUVVGRkxGbEJRVTA3UVVGRE9VTXNZVUZCU1N4TlFVRkxMRmRCUVZjc1EwRkJReXhYUVVGWExFVkJRVVU3UVVGRGFFTXNhVUpCUVVzc1JVRkJSU3hGUVVGRkxFTkJRVU03UVVGRFZpeHBRa0ZCU3l4WFFVRlhMRU5CUVVNc1RVRkJUU3hEUVVGRExFMUJRVXNzUzBGQlN5eERRVUZETEVkQlFVY3NUVUZCU3l4TFFVRkxMRU5CUVVNN1ZVRkRiRVE3VVVGRFJpeERRVUZETEVOQlFVTTdUVUZGU2pzN1FVRkZSQ3hUUVVGSkxFTkJRVU1zVjBGQlZ5eEZRVUZGTEVOQlFVTTdTVUZEY0VJN08yRkJia2RITEZsQlFWazdPMmRDUVVGYUxGbEJRVms3UVVGeFIyaENMR2RDUVVGWE8yTkJRVUVzZFVKQlFVYzdPenM3UVVGSldpeGhRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhIUVVGSExFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZETjBJc1lVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eFpRVUZaTEVOQlFVTXNWMEZCVnl4RlFVRkRMR2RDUVVGblFpeERRVUZETEVOQlFVTTdRVUZEY0VRc1lVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eFpRVUZaTEVOQlFVTXNTVUZCU1N4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRemxDTEdGQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFbEJRVWtzUlVGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0QlFVTTVRaXhoUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4UFFVRlBMRVZCUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzBGQlF6RkRMR0ZCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zV1VGQldTeERRVUZETEZGQlFWRXNSVUZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03TzBGQlJUVkRMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zV1VGQldTeERRVUZETEVkQlFVY3NSVUZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOcVF5eGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmxCUVZrc1EwRkJReXhYUVVGWExFVkJRVU1zWjBKQlFXZENMRU5CUVVNc1EwRkJRenRCUVVONFJDeGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmxCUVZrc1EwRkJReXhKUVVGSkxFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZEYkVNc1lVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eFpRVUZaTEVOQlFVTXNTVUZCU1N4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRMnhETEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1dVRkJXU3hEUVVGRExFOUJRVThzUlVGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1FVRkRPVU1zWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0UlFVVnFSRHM3T3p0VlFYWklSeXhaUVVGWk8wbEJRVk1zWTBGQll6czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenRMUVdsTGNFSXNWMEZCVnp0QlFVVnVRaXhaUVVaUkxGZEJRVmNzUjBGRmFFSTdNa0pCUmtzc1YwRkJWenM3UVVGSk5VSXNVMEZCU1N4UFFVRlBMRWRCUVVjc1EwRkJReXhQUVVGUExFTkJRVU1zUTBGQlF6czdRVUZGZUVJc1UwRkJTU3hSUVVGUkxFZEJRVWM3UVVGRFlpeGhRVUZSTEVOQlFVTXNSMEZCUnl4RlFVRkRMRWRCUVVjc1EwRkJRenRCUVVOcVFpeDNRa0ZCYlVJc1EwRkJRenRCUVVOd1FpeFpRVUZQTEVOQlFVTTdRVUZEVWl4WlFVRlBMRU5CUVVNN1FVRkRVaXhoUVVGUkxFTkJRVU03UVVGRFZDeGxRVUZWTEVOQlFVTXNSMEZCUnl4RlFVRkRMRWRCUVVjc1JVRkJReXhIUVVGSExFVkJRVU1zUjBGQlJ5eEZRVUZETEVkQlFVY3NRMEZCUXp0TlFVTm9ReXhEUVVGRE96dEJRVVZHTEdkRFFXWnBRaXhYUVVGWExEWkRRV1YwUWl4VFFVRlRMRVZCUVVNc1QwRkJUeXhGUVVGRExGRkJRVkVzUlVGQlJUczdRVUZGYkVNc1UwRkJTU3hEUVVGRExHZENRVUZuUWl4SFFVRkhMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zWlVGQlpTeERRVUZETzBGQlEzUkVMRk5CUVVrc1EwRkJReXhOUVVGTkxFZEJRVWNzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4TlFVRk5MRU5CUVVNN08wRkJSVzVETEZOQlFVa3NRMEZCUXl4UFFVRlBMRWRCUVVjc1JVRkJSU3hEUVVGRE96dEJRVVZzUWl4VFFVRkpMRU5CUVVNc1YwRkJWeXhIUVVGSExFdEJRVXNzUTBGQlF6czdRVUZGZWtJc1UwRkJTU3hEUVVGRExFbEJRVWtzUlVGQlJTeERRVUZETzBsQlJXSTdPMkZCTVVKclFpeFhRVUZYT3p0blFrRkJXQ3hYUVVGWE8wRkJORUk1UWl4bFFVRlZPMk5CUVVFc2MwSkJRVWM3UVVGRFdDeGhRVUZKTEVOQlFVTXNUMEZCVHl4SFFVRkhMRkZCUVZFc1EwRkJReXhoUVVGaExFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZETjBNc1lVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eFhRVUZYTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRE8xRkJRM1pET3p0QlFVVkVMRzFDUVVGak8yTkJRVUVzTUVKQlFVYzdPMEZCUldZc1lVRkJTU3hIUVVGSExFZEJRVWNzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4SFFVRkhMRU5CUVVNN1FVRkROVUlzWVVGQlNTeEhRVUZITEVkQlFVY3NTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhIUVVGSExFTkJRVU03UVVGRE5VSXNZVUZCU1N4SlFVRkpMRWRCUVVjc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eEpRVUZKTEVOQlFVTTdPMEZCUlRsQ0xHRkJRVWtzU1VGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4TlFVRk5MRVZCUVVVN1FVRkRka0lzWTBGQlJ5eEhRVUZITEVsQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zUjBGQlJ5eERRVUZETzBGQlF6RkNMR05CUVVjc1IwRkJSeXhKUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRWRCUVVjc1EwRkJRenRCUVVNeFFpeGxRVUZKTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eEpRVUZKTEVOQlFVTTdWVUZETjBJN08wRkJSVVFzWVVGQlNTeERRVUZETEU5QlFVOHNSMEZCUnl4RlFVRkZMRU5CUVVNN08wRkJSV3hDTEdOQlFVc3NTVUZCU1N4RFFVRkRMRWRCUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUjBGQlF5eEpRVUZKTEVOQlFVTXNaMEpCUVdkQ0xFVkJRVU1zUTBGQlF5eEZRVUZGTEVWQlFVVTdRVUZEZUVNc1pVRkJTU3hUUVVGVExFZEJRVWNzVVVGQlVTeERRVUZETEdGQlFXRXNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenM3UVVGRkwwTXNaVUZCU1N4TlFVRk5MRWRCUVVjc1NVRkJTU3haUVVGWkxFTkJRVU1zVTBGQlV5eEZRVUZGTzBGQlEzSkRMR3RDUVVGTExFVkJRVVVzUTBGQlF5eEhRVUZITEVWQlFVTXNSMEZCUnl4RFFVRkRPMEZCUTJoQ0xHbENRVUZKTEVWQlFVVXNTVUZCU1R0QlFVTldMR2xDUVVGSkxFVkJRVVVzVlVGQlZUdEJRVU5vUWl4M1FrRkJWeXhGUVVGRkxGVkJRVlU3UVVGRGRrSXNhMEpCUVVzc1JVRkJSU3hKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTXNRMEZCUXp0QlFVTnlRaXh2UWtGQlR5eEZRVUZGTEV0QlFVczdRVUZEWkN4elFrRkJVeXhGUVVGRkxFbEJRVWtzUlVGRGFFSXNSVUZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFbEJRVWtzUTBGQlF5eEpRVUZKTEVWQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVNNVFpeHBRa0ZCVFN4RFFVRkRMRmRCUVZjc1IwRkJSeXhKUVVGSkxFTkJRVU03TzBGQlJURkNMR2xDUVVGTkxFTkJRVU1zUzBGQlN5eEhRVUZITEVOQlFVTXNRMEZCUXp0QlFVTnFRaXhsUVVGSkxFdEJRVXNzUTBGQlF5eE5RVUZOTEVWQlFVVTdRVUZEYUVJc2JVSkJRVTBzUTBGQlF5eEhRVUZITEVOQlFVTXNTMEZCU3l4SFFVRkhMRU5CUVVNc1EwRkJRenRCUVVOeVFpeHRRa0ZCVFN4RFFVRkRMRTlCUVU4c1EwRkJReXhMUVVGTExFZEJRVWNzUTBGQlF5eERRVUZETzBGQlEzcENMRzFDUVVGTkxFTkJRVU1zVVVGQlVTeEhRVUZITEUxQlFVMHNRMEZCUXl4UFFVRlBMRWRCUVVjc1RVRkJUU3hEUVVGRExGVkJRVlVzUjBGQlJ5eFpRVUZOTEVWQlFVVXNRMEZCUXp0QlFVTm9SU3h0UWtGQlRTeERRVUZETEV0QlFVc3NSMEZCUnl4TlFVRk5MRU5CUVVNc1NVRkJTU3hIUVVGSExFMUJRVTBzUTBGQlF5eFBRVUZQTEVkQlFVY3NXVUZCVFN4RlFVRkZMRU5CUVVNN1FVRkRka1FzYlVKQlFVMHNRMEZCUXl4UlFVRlJMRWRCUVVjc1RVRkJUU3hEUVVGRExGbEJRVmtzUjBGQlJ5eE5RVUZOTEVOQlFVTXNaVUZCWlN4SFFVRkhMRmxCUVUwc1JVRkJSU3hEUVVGRE8wRkJRekZGTEcxQ1FVRk5MRU5CUVVNc1MwRkJTeXhIUVVGSExFMUJRVTBzUTBGQlF5eFRRVUZUTEVkQlFVY3NUVUZCVFN4RFFVRkRMRmxCUVZrc1IwRkJSeXhaUVVGTkxFVkJRVVVzUTBGQlF6dFpRVU5zUlRzN1FVRkZSQ3hsUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVNeFFpeGxRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmRCUVZjc1EwRkJReXhUUVVGVExFTkJRVU1zUTBGQlF6dFZRVVZ5UXp0QlFVTkVMR0ZCUVVrc1MwRkJTeXhEUVVGRExFMUJRVTBzUlVGQlJUdEJRVU5vUWl4bFFVRkpMRU5CUVVNc2FVSkJRV2xDTEVWQlFVVXNRMEZCUXp0VlFVTXhRanRSUVVWR096dEJRVVZFTEcxQ1FVRmpPMk5CUVVFc01FSkJRVWM3UVVGRFppeGpRVUZMTEVsQlFVa3NRMEZCUXl4SFFVRkRMRU5CUVVNc1JVRkJReXhEUVVGRExFZEJRVU1zU1VGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4TlFVRk5MRVZCUVVNc1EwRkJReXhGUVVGRkxFVkJRVVU3UVVGRGRFTXNaVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eE5RVUZOTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJRenRCUVVOeVF5eGxRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExHTkJRV01zUlVGQlJTeERRVUZETzFWQlEyeERPMUZCUTBZN08wRkJSVVFzYTBKQlFXRTdZMEZCUVN4NVFrRkJSenM3UVVGRlpDeGhRVUZKTEZkQlFWY3NSMEZCUnl4SlFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNUVUZCVFN4RFFVRkRPMEZCUTI1RUxHRkJRVWtzV1VGQldTeEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNN08wRkJSUzlDTEdOQlFVc3NTVUZCU1N4RFFVRkRMRWRCUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUjBGQlF5eEpRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRTFCUVUwc1JVRkJReXhEUVVGRExFVkJRVVVzUlVGQlJUdEJRVU4wUXl4bFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEUxQlFVMHNRMEZCUXl4WFFVRlhMRVZCUVVNc1dVRkJXU3hEUVVGRExFTkJRVU03UVVGRGFrUXNaVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eFhRVUZYTEVWQlFVVXNRMEZCUXp0VlFVTXZRanRSUVVkR096dEJRVVZFTEZkQlFVMDdZMEZCUVN4blFrRkJReXhMUVVGTExFVkJRVU1zUzBGQlN5eEZRVUZGTzBGQlEyeENMR0ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeEZRVUZETzBGQlEycENMR3RDUVVGVExFdEJRVXM3UVVGRFpDeHJRa0ZCVXl4TFFVRkxPMVZCUTJZc1EwRkJReXhEUVVGRE8xRkJRMG83TzBGQlJVUXNjMEpCUVdsQ08yTkJRVUVzTmtKQlFVYzdPenRCUVVWc1FpeGhRVUZKTEVOQlFVTXNVVUZCVVN4SFFVRkhMRWxCUVVrc1EwRkJReXhQUVVGUExFZEJRVWNzU1VGQlNTeERRVUZETEZWQlFWVXNSMEZCUnl4WlFVRk5MRVZCUVVVc1EwRkJRenRCUVVNeFJDeGhRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhKUVVGSkxFZEJRVWNzU1VGQlNTeERRVUZETEU5QlFVOHNSMEZCUnl4WlFVRk5MRVZCUVVVc1EwRkJRenRCUVVOcVJDeGhRVUZKTEVOQlFVTXNVVUZCVVN4SFFVRkhMRWxCUVVrc1EwRkJReXhaUVVGWkxFZEJRVWNzU1VGQlNTeERRVUZETEdWQlFXVXNSMEZCUnl4WlFVRk5MRVZCUVVVc1EwRkJRenRCUVVOd1JTeGhRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhUUVVGVExFZEJRVWNzU1VGQlNTeERRVUZETEZsQlFWa3NSMEZCUnl4WlFVRk5MRVZCUVVVc1EwRkJRenM3UVVGRk0wUXNZVUZCU1N4RFFVRkRMR05CUVdNc1IwRkJSeXhMUVVGTExFTkJRVU03TzBGQlJUVkNMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1dVRkJXU3hGUVVGRkxGVkJRVU1zUTBGQlF5eEZRVUZMTzBGQlEycEVMR1ZCUVVrc1QwRkJUeXhIUVVGSExGRkJRVkVzUTBGQlF5eG5Ra0ZCWjBJc1EwRkJReXhEUVVGRExFTkJRVU1zWVVGQllTeERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRTlCUVU4c1JVRkJReXhEUVVGRExFTkJRVU1zWVVGQllTeERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRE8wRkJReTlHTEdWQlFVa3NUVUZCVFN4SFFVRkhMRTFCUVVzc1QwRkJUeXhEUVVGRExFOUJRVThzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0QlFVTjZReXhsUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEUxQlFVMHNSVUZCUlR0QlFVTnNRaXh0UWtGQlRTeERRVUZETEUxQlFVMHNSMEZCUnl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFMUJRVTBzUTBGQlF5eFBRVUZQTEVOQlFVTXNRMEZCUXp0WlFVTnNSRHRCUVVORUxHbENRVUZOTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWRCUVVjc1EwRkJReXhYUVVGWExFTkJRVU1zUTBGQlF5eEZRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVOb1JDeHBRa0ZCVFN4RFFVRkRMRWxCUVVrc1JVRkJSU3hEUVVGRE8wRkJRMlFzYVVKQlFVc3NZMEZCWXl4SFFVRkhMRTlCUVU4c1EwRkJReXhMUVVGTExFTkJRVU03UVVGRGNFTXNXVUZCUXl4RFFVRkRMR05CUVdNc1JVRkJSU3hEUVVGRE8wRkJRMjVDTEZsQlFVTXNRMEZCUXl4bFFVRmxMRVZCUVVVc1EwRkJRenRWUVVOeVFpeERRVUZETEVOQlFVTTdPMEZCUlVnc1lVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eG5Ra0ZCWjBJc1EwRkJReXhYUVVGWExFVkJRVVVzVlVGQlF5eERRVUZETEVWQlFVczdRVUZEYUVRc1pVRkJTU3hQUVVGUExFZEJRVWNzVVVGQlVTeERRVUZETEdkQ1FVRm5RaXhEUVVGRExFTkJRVU1zUTBGQlF5eGhRVUZoTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1QwRkJUeXhGUVVGRExFTkJRVU1zUTBGQlF5eGhRVUZoTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1QwRkJUeXhEUVVGRExFTkJRVU03UVVGREwwWXNaVUZCU1N4TlFVRk5MRWRCUVVjc1RVRkJTeXhQUVVGUExFTkJRVU1zVDBGQlR5eERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTNwRExHVkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUVUZCVFN4RlFVRkZPMEZCUTJ4Q0xHMUNRVUZOTEVOQlFVTXNUVUZCVFN4SFFVRkhMRWRCUVVjc1EwRkJReXhaUVVGWkxFTkJRVU1zVFVGQlRTeERRVUZETEU5QlFVOHNRMEZCUXl4RFFVRkRPMWxCUTJ4RU8wRkJRMFFzYVVKQlFVMHNRMEZCUXl4TFFVRkxMRWRCUVVjc1IwRkJSeXhEUVVGRExGZEJRVmNzUTBGQlF5eERRVUZETEVWQlFVTXNUVUZCVFN4RFFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRE8wRkJRMmhFTEdWQlFVa3NUMEZCVHl4RFFVRkRMRXRCUVVzc1MwRkJSeXhOUVVGTExHTkJRV01zUlVGQlJUdEJRVU4yUXl4cFFrRkJTU3hOUVVGTExHTkJRV01zU1VGQlNTeERRVUZETEVWQlFVVTdRVUZETlVJc2JVSkJRVWtzVlVGQlZTeEhRVUZITEUxQlFVc3NUMEZCVHl4RFFVRkRMRTFCUVVzc1kwRkJZeXhEUVVGRExFTkJRVU03UVVGRGJrUXNlVUpCUVZVc1EwRkJReXhGUVVGRkxFVkJRVVVzUTBGQlF6dGpRVU5xUWp0QlFVTkVMRzFDUVVGTkxFTkJRVU1zU1VGQlNTeEZRVUZGTEVOQlFVTTdXVUZEWml4TlFVRk5PMEZCUTB3c2JVSkJRVTBzUTBGQlF5eExRVUZMTEVWQlFVVXNRMEZCUXp0WlFVTm9RanRCUVVORUxHbENRVUZMTEdOQlFXTXNSMEZCUnl4UFFVRlBMRU5CUVVNc1MwRkJTeXhEUVVGRE8wRkJRM0JETEZsQlFVTXNRMEZCUXl4alFVRmpMRVZCUVVVc1EwRkJRenRCUVVOdVFpeFpRVUZETEVOQlFVTXNaVUZCWlN4RlFVRkZMRU5CUVVNN1ZVRkRja0lzUTBGQlF5eERRVUZET3p0QlFVVklMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1ZVRkJWU3hGUVVGRkxGVkJRVU1zUTBGQlF5eEZRVUZMT3p0QlFVVXZReXhsUVVGSkxFMUJRVTBzUjBGQlJ5eE5RVUZMTEU5QlFVOHNRMEZCUXl4TlFVRkxMR05CUVdNc1EwRkJReXhEUVVGRE8wRkJReTlETEdsQ1FVRk5MRU5CUVVNc1JVRkJSU3hGUVVGRkxFTkJRVU03UVVGRFdpeHBRa0ZCU3l4WFFVRlhMRWRCUVVjc1MwRkJTeXhEUVVGRE8wRkJRM3BDTEdsQ1FVRkxMR05CUVdNc1IwRkJSeXhMUVVGTExFTkJRVU03UVVGRE5VSXNXVUZCUXl4RFFVRkRMR05CUVdNc1JVRkJSU3hEUVVGRE8wRkJRMjVDTEZsQlFVTXNRMEZCUXl4bFFVRmxMRVZCUVVVc1EwRkJRenRWUVVOeVFpeERRVUZETEVOQlFVTTdVVUZGU2pzN1FVRlZSeXh2UWtGQlpUczdPenM3T3p0WlFVcEJMRmxCUVVjN1FVRkRjRUlzWjBKQlFVOHNTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhOUVVGTkxFTkJRVU03VVVGRE5VSTdXVUZGYTBJc1ZVRkJReXhEUVVGRExFVkJRVVU3UVVGRGNrSXNZVUZCU1N4RFFVRkRMRXRCUVVjc1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eE5RVUZOTEVWQlFVVTdRVUZETTBJc2EwSkJRVTg3VlVGRFVqdEJRVU5FTEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1QwRkJUeXhEUVVGRExGVkJRVU1zVFVGQlRTeEZRVUZITzBGQlF6ZENMR2xDUVVGTkxFTkJRVU1zVDBGQlR5eEZRVUZGTEVOQlFVTTdWVUZEYkVJc1EwRkJReXhEUVVGRE8wRkJRMGdzWVVGQlNTeERRVUZETEV0QlFVc3NSVUZCUlN4RFFVRkRPMEZCUTJJc1lVRkJTU3hEUVVGRExHZENRVUZuUWl4SFFVRkhMRU5CUVVNc1EwRkJRenRCUVVNeFFpeGhRVUZKTEVOQlFVTXNZMEZCWXl4RlFVRkZMRU5CUVVNN1VVRkRka0k3TzBGQldVY3NVVUZCUnpzN096czdPenM3V1VGSVFTeFpRVUZITzBGQlExSXNaMEpCUVU4c1NVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4SFFVRkhMRU5CUVVNN1VVRkROVUk3V1VGRFRTeFZRVUZETEVOQlFVTXNSVUZCUlR0QlFVTlVMR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zVDBGQlR5eERRVUZETEZWQlFVTXNUVUZCVFN4RlFVRkhPMEZCUXpkQ0xHbENRVUZOTEVOQlFVTXNSMEZCUnl4SFFVRkhMRU5CUVVNc1EwRkJRenRWUVVOb1FpeERRVUZETEVOQlFVTTdVVUZEU2pzN1FVRlZSeXhSUVVGSE96czdPenM3T3p0WlFVaEJMRmxCUVVjN1FVRkRVaXhuUWtGQlR5eEpRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExFZEJRVWNzUTBGQlF6dFJRVU0xUWp0WlFVTk5MRlZCUVVNc1EwRkJReXhGUVVGRk8wRkJRMVFzWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4UFFVRlBMRU5CUVVNc1ZVRkJReXhOUVVGTkxFVkJRVWM3UVVGRE4wSXNhVUpCUVUwc1EwRkJReXhIUVVGSExFZEJRVWNzUTBGQlF5eERRVUZETzFWQlEyaENMRU5CUVVNc1EwRkJRenRSUVVOS096dEJRVlZITEZOQlFVazdPenM3T3pzN08xbEJTRUVzV1VGQlJ6dEJRVU5VTEdkQ1FVRlBMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNTVUZCU1N4RFFVRkRPMUZCUXpkQ08xbEJRMDhzVlVGQlF5eERRVUZETEVWQlFVVTdRVUZEVml4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFOUJRVThzUTBGQlF5eFZRVUZETEUxQlFVMHNSVUZCUnp0QlFVTTNRaXhwUWtGQlRTeERRVUZETEVsQlFVa3NSMEZCUnl4RFFVRkRMRU5CUVVNN1ZVRkRha0lzUTBGQlF5eERRVUZETzFGQlEwbzdPMEZCVlVRc1kwRkJVenM3T3pzN096czdPenM3WTBGQlFTeHRRa0ZCUXl4TFFVRkxMRVZCUVVNc1MwRkJTeXhGUVVGRk8wRkJRM0pDTEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU1zUzBGQlN5eEhRVUZITEV0QlFVc3NRMEZCUXp0QlFVTnNReXhoUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNSVUZCUXp0QlFVTnFRaXhyUWtGQlV5eExRVUZMTzBGQlEyUXNhMEpCUVZNc1MwRkJTenRWUVVObUxFTkJRVU1zUTBGQlF6dFJRVU5LT3p0QlFWRkVMR3RDUVVGaE96czdPenM3T3pzN1kwRkJRU3gxUWtGQlF5eE5RVUZOTEVWQlFVVTdPenRCUVVOd1FpeGhRVUZKTEVOQlFVTXNUVUZCVFN4SFFVRkhMRTFCUVUwc1EwRkJRenRCUVVOeVFpeGhRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRTlCUVU4c1EwRkJReXhWUVVGRExFMUJRVTBzUlVGQlF5eERRVUZETEVWQlFVYzdRVUZETDBJc2FVSkJRVTBzUTBGQlF5eExRVUZMTEVkQlFVY3NUVUZCVFN4RFFVRkRMRU5CUVVNc1IwRkJReXhOUVVGTkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdRVUZEZGtNc2FVSkJRVXNzU1VGQlNTeERRVUZETEZGQlFWRXNSVUZCUXp0QlFVTnFRaXh2UWtGQlV5eERRVUZETzBGQlExWXNiMEpCUVZNc1RVRkJUU3hEUVVGRExFdEJRVXM3V1VGRGRFSXNRMEZCUXl4RFFVRkRPMVZCUTBvc1EwRkJReXhEUVVGRE8xRkJRMG83T3pzN1ZVRnNVV3RDTEZkQlFWYzdTVUZCVXl4VFFVRlRPenRyUWtGQk4wSXNWMEZCVnl4RE96czdPenM3UVVNelMyaERMR0ZCUVZrc1EwRkJRenM3T3pzN096czdPenM3TzBGQlJXSXNTMEZCU1N4SFFVRkhMRWRCUVVjc2JVSkJRVThzUTBGQlF5eERRVUZoTEVOQlFVTXNRMEZCUXp0QlFVTnFReXhMUVVGSkxGTkJRVk1zUjBGQlJ5eHRRa0ZCVHl4RFFVRkRMRU5CUVcxQ0xFTkJRVU1zUTBGQlF6dEJRVU0zUXl4TFFVRkpMRWxCUVVrc1IwRkJSeXh0UWtGQlR5eERRVUZETEVWQlFXZENMRU5CUVVNc1EwRkJRenM3UzBGRGVrSXNWMEZCVnl3clEwRkJUU3hGUVVGeFFqczdTMEZGTjBJc1kwRkJZenRCUVVWMFFpeFpRVVpSTEdOQlFXTXNRMEZGY2tJc1NVRkJTU3hGUVVGRExFOUJRVThzUlVGQlF5eFJRVUZSTEVWQlFVVTdNa0pCUm1oQ0xHTkJRV003TzBGQlNTOUNMR2REUVVwcFFpeGpRVUZqTERaRFFVbDZRaXhKUVVGSkxFVkJRVU1zVDBGQlR5eEZRVUZETEZGQlFWRXNSVUZCUlRzN1FVRkZOMElzVTBGQlNTeERRVUZETEZkQlFWY3NSMEZCUnl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExGZEJRVmNzUTBGQlF6czdPenRCUVVrM1F5eFRRVUZKTEVOQlFVTXNUMEZCVHl4SFFVRkhMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zVDBGQlR5eERRVUZET3pzN096czdRVUZOY2tNc1UwRkJTU3hEUVVGRExFMUJRVTBzUjBGQlJ5eEpRVUZKTEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETEVOQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETEVOQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFbEJRVWtzUlVGQlJTeEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE96dEJRVVZvU0N4VFFVRkpMRU5CUVVNc1NVRkJTU3hGUVVGRkxFTkJRVU03TzBGQlJWb3NVMEZCU1N4RFFVRkRMRkZCUVZFc1IwRkJSeXhKUVVGSkxGZEJRVmNzUTBGQlF5eE5RVUZOTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhKUVVGSkxFVkJRVU1zU1VGQlNTeERRVUZETEZkQlFWY3NSVUZCUXl4RFFVRkRMRU5CUVVNc1JVRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVWQlFVTXNRMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZETTBjc1UwRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eExRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhWUVVGVkxFTkJRVU03TzBGQlJUZERMRk5CUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TFFVRkxMRU5CUVVNN08wRkJSUzlDTEZOQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hGUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0SlFVVm9RenM3WVVFelFtdENMR05CUVdNN08yZENRVUZrTEdOQlFXTTdRVUUyUW1wRExHMUNRVUZqTzJOQlFVRXNNRUpCUVVjN08wRkJSV1lzWVVGQlNTeERRVUZETEVkQlFVY3NSMEZCUnl4SFFVRkhMRU5CUVVNc1RVRkJUU3hEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETzBGQlF6bENMR0ZCUVVrc1EwRkJReXhQUVVGUExFZEJRVWNzUjBGQlJ5eERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVOc1F5eGhRVUZKTEVOQlFVTXNTVUZCU1N4SFFVRkhMRWRCUVVjc1EwRkJReXhOUVVGTkxFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTTdPMEZCUldwRExHRkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNWMEZCVnl4RFFVRkRMRWxCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zUTBGQlF6dEJRVU51UXl4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExGZEJRVmNzUTBGQlF5eEpRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRU5CUVVNN1FVRkRka01zWVVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WFFVRlhMRU5CUVVNc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eERRVUZET3p0QlFVVndReXhoUVVGSkxFTkJRVU1zWVVGQllTeEZRVUZGTEVOQlFVTTdVVUZKZEVJN08wRkJSVVFzYTBKQlFXRTdZMEZCUVN4NVFrRkJSenM3UVVGSFpDeGhRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhYUVVGWExFVkJRVVU3UVVGRE9VSXNaVUZCU1N4SlFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVTdRVUZETlVJc2FVSkJRVWtzUTBGQlF5eFhRVUZYTEVkQlFVY3NWVUZCVlN4RFFVRkRPMWxCUXk5Q0xFMUJRVTA3UVVGRFRDeHBRa0ZCU1N4RFFVRkRMRmRCUVZjc1IwRkJSeXhaUVVGWkxFTkJRVU03V1VGRGFrTTdWVUZEUmpzN1FVRkZSQ3hoUVVGSkxFTkJRVU03WVVGQlJTeERRVUZETzJGQlFVVXNRMEZCUXp0aFFVRkZMRU5CUVVNN1lVRkJSU3hUUVVGVE8yRkJRVVVzV1VGQldTeGhRVUZETzBGQlEzaERMR0ZCUVVrc1EwRkJReXhSUVVGUkxFZEJRVWM3UVVGRFpDeG5Ra0ZCU3l4RlFVRkZMRU5CUVVNN1FVRkRVaXhaUVVGRExFVkJRVVVzUTBGQlF6dFZRVU5NTEVOQlFVTTdPMEZCUlVZc1lVRkJTU3hKUVVGSkxFTkJRVU1zVjBGQlZ5eExRVUZMTEZWQlFWVXNSVUZCUlR0QlFVTnVReXhsUVVGSkxFTkJRVU1zVTBGQlV5eEhRVUZITEVsQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1EwRkJReXhEUVVGRE8wRkJRMnBETEZsQlFVTXNSMEZCUnl4SlFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGRExFTkJRVU1zUTBGQlF6dEJRVU5xUWl4WlFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE8wRkJRMDRzV1VGQlF5eEhRVUZITEVsQlFVa3NRMEZCUXl4VFFVRlRMRU5CUVVNN1FVRkRia0lzV1VGQlF5eEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNN1FVRkRaaXhsUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTXNSMEZCUnl4SlFVRkpMRU5CUVVNc1UwRkJVeXhIUVVGSExFZEJRVWNzUTBGQlF6dEJRVU40UXl4bFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUjBGQlJ5eERRVUZETEVkQlFVTXNTVUZCU1N4RFFVRkRMRlZCUVZVc1IwRkJReXhEUVVGRExFTkJRVU03UVVGRGVrTXNiMEpCUVZNc1IwRkJSeXhaUVVGWkxFZEJRVU1zU1VGQlNTeERRVUZETEZOQlFWTXNSMEZCUlN4RFFVRkRMRU5CUVVVc1IwRkJReXhEUVVGRExFZEJRVU1zUzBGQlN5eERRVUZETzBGQlEzSkVMSFZDUVVGWkxFZEJRVWNzUTBGQlF5eEhRVUZETEVOQlFVTXNRMEZCUXp0VlFVTndRaXhOUVVGTk8wRkJRMHdzWlVGQlNTeERRVUZETEZOQlFWTXNSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFTkJRVU1zUTBGQlF6dEJRVU5zUXl4WlFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE8wRkJRMDRzV1VGQlF5eEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVNc1EwRkJReXhEUVVGRE8wRkJRMnhDTEZsQlFVTXNSMEZCUnl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRE8wRkJRMllzV1VGQlF5eEhRVUZITEVsQlFVa3NRMEZCUXl4VFFVRlRMRU5CUVVNN1FVRkRiRUlzWlVGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRExGTkJRVk1zUjBGQlJ5eEhRVUZITEVOQlFVTTdRVUZEZUVNc1pVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eExRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMRlZCUVZVc1IwRkJReXhEUVVGRExFTkJRVU03UVVGRGRrTXNiMEpCUVZNc1IwRkJSeXhqUVVGakxFZEJRVU1zU1VGQlNTeERRVUZETEZOQlFWTXNSMEZCUlN4RFFVRkRMRU5CUVVVc1IwRkJReXhEUVVGRExFZEJRVU1zUjBGQlJ5eERRVUZETzBGQlEzSkVMSFZDUVVGWkxFZEJRVWNzUTBGQlF5eEhRVUZETEVOQlFVTXNRMEZCUXp0VlFVTndRanM3UVVGRlJDeGhRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhIUVVGSExFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZETjBJc1lVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eFpRVUZaTEVOQlFVTXNSMEZCUnl4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRemRDTEdGQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExGZEJRVmNzUlVGQlF5eFRRVUZUTEVOQlFVTXNRMEZCUXp0QlFVTTNReXhoUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4SlFVRkpMRVZCUVVNc1dVRkJXU3hEUVVGRExFTkJRVU03UVVGRGVrTXNZVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhaUVVGWkxFTkJRVU1zU1VGQlNTeEZRVUZETEZsQlFWa3NRMEZCUXl4RFFVRkRPMEZCUTNwRExHRkJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNXVUZCV1N4RFFVRkRMRTlCUVU4c1JVRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU5xUXl4aFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eFJRVUZSTEVWQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN08wRkJSV3hETEdGQlFVa3NTVUZCU1N4RFFVRkRMRmRCUVZjc1MwRkJTeXhWUVVGVkxFVkJRVVU3UVVGRGJrTXNaVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhaUVVGWkxFTkJRVU1zUjBGQlJ5eEZRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUTJwRExHVkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWRCUVVjc1JVRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUTI1RUxHVkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRTlCUVU4c1JVRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU55UXl4bFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExGbEJRVmtzUTBGQlF5eFJRVUZSTEVWQlFVTXNRMEZCUXl4SFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdWVUZETTBRc1RVRkJUVHRCUVVOTUxHVkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWRCUVVjc1JVRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU5xUXl4bFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExGbEJRVmtzUTBGQlF5eEhRVUZITEVWQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRha01zWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1QwRkJUeXhGUVVGRExFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1FVRkRka1FzWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1VVRkJVU3hGUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzFWQlEzWkRPMEZCUTBRc1lVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eFpRVUZaTEVOQlFVTXNWMEZCVnl4RlFVRkRMRk5CUVZNc1EwRkJReXhEUVVGRE8wRkJRMnBFTEdGQlFVa3NRMEZCUXl4UFFVRlBMRU5CUVVNc1dVRkJXU3hEUVVGRExFbEJRVWtzUlVGQlF5eFpRVUZaTEVOQlFVTXNRMEZCUXp0QlFVTTNReXhoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZsQlFWa3NRMEZCUXl4SlFVRkpMRVZCUVVNc1dVRkJXU3hEUVVGRExFTkJRVU03TzBGQlJUZERMR0ZCUVVrc1NVRkJTU3hEUVVGRExGZEJRVmNzUzBGQlN5eFZRVUZWTEVWQlFVVTdRVUZEYmtNc1pVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eFpRVUZaTEVOQlFVTXNTVUZCU1N4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJReTlDTEdWQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1dVRkJXU3hEUVVGRExFbEJRVWtzUlVGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8xVkJRMnhFTEUxQlFVMDdRVUZEVEN4bFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGbEJRVmtzUTBGQlF5eEpRVUZKTEVWQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dEJRVU5xUkN4bFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGbEJRVmtzUTBGQlF5eEpRVUZKTEVWQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1ZVRkRhRU03UVVGRFJDeGhRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRmxCUVZrc1EwRkJReXhIUVVGSExFVkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenM3UVVGSE5VTXNZVUZCU1N4SlFVRkpMRU5CUVVNc1VVRkJVU3hGUVVGRk8wRkJRMnBDTEdWQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU1zUTBGQlF5eEZRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1JVRkJReXhEUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRWUVVOMFJEdFJRVVZHT3p0QlFVVkVMRzFDUVVGak8yTkJRVUVzTUVKQlFVYzdPMEZCUldZc1lVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eFpRVUZaTEVOQlFVTXNUVUZCVFN4RlFVRkZMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zU1VGQlNTeERRVUZETEVOQlFVTTdRVUZEYUVRc1lVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eFpRVUZaTEVOQlFVTXNUVUZCVFN4RlFVRkZMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdRVUZEZEVRc1lVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eFpRVUZaTEVOQlFVTXNUVUZCVFN4RlFVRkZMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdRVUZEYmtRc1lVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eFBRVUZQTEVWQlFVVTdRVUZEYWtJc1pVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eFpRVUZaTEVOQlFVTXNUVUZCVFN4RlFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRE8xVkJRM1pETzFGQlJVWTdPMEZCUlVRc1YwRkJUVHRqUVVGQkxHdENRVUZITzBGQlExQXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhQUVVGUExFVkJRVVU3UVVGRGFrSXNaVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETEZOQlFWTXNSMEZCUXl4SlFVRkpMRU5CUVVNN1ZVRkRka003UVVGRFJDeGhRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRmxCUVZrc1EwRkJReXhIUVVGSExFVkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRenM3UVVGRk5VTXNZVUZCU1N4SlFVRkpMRU5CUVVNc1YwRkJWeXhMUVVGTExGVkJRVlVzUlVGQlJUdEJRVU5zUXl4bFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRlZCUVZVc1IwRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETzBGQlEzcEVMR1ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zV1VGQldTeERRVUZETEVsQlFVa3NSVUZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1FVRkRMMFFzWlVGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1IwRkJSeXhGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVY3NTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dEJRVU5xUlN4bFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExGbEJRVmtzUTBGQlF5eFJRVUZSTEVWQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dFZRVU14UkN4TlFVRk5PMEZCUTBvc1pVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eExRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhWUVVGVkxFZEJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXp0QlFVTjRSQ3hsUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZsQlFWa3NRMEZCUXl4SlFVRkpMRVZCUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXp0QlFVTnFSQ3hsUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZsQlFWa3NRMEZCUXl4SFFVRkhMRVZCUVVNc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRGFrTXNaVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhaUVVGWkxFTkJRVU1zVDBGQlR5eEZRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03VlVGRGVrUTdVVUZEUmpzN1FVRkZSQ3hUUVVGSk8yTkJRVUVzWjBKQlFVYzdRVUZEVEN4aFFVRkpMRU5CUVVNc1QwRkJUeXhIUVVGSExFbEJRVWtzUTBGQlF6dEJRVU53UWl4aFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU1zUjBGQlJ5eEpRVUZKTEVOQlFVTXNVMEZCVXl4SFFVRkRMRWRCUVVjc1EwRkJRenRCUVVOeVF5eGhRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRTFCUVUwc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETzBGQlEyeERMR0ZCUVVrc1EwRkJReXhMUVVGTExFVkJRVVVzUTBGQlF6dFJRVU5rT3p0QlFVVkVMRlZCUVVzN1kwRkJRU3hwUWtGQlJ6dEJRVU5PTEdGQlFVa3NTVUZCU1N4RFFVRkRMRTlCUVU4c1JVRkJSVHRCUVVOb1FpeGxRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRTFCUVUwc1EwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZEYWtNc1pVRkJTU3hEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRmxCUVZrc1EwRkJSU3hKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEV0QlFVc3NRMEZCUlN4RFFVRkRPMEZCUXpkRUxHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RlFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dFZRVU5vUXp0UlFVTkdPenRCUVVWRUxFOUJRVVU3WTBGQlFTeGpRVUZITzBGQlEwZ3NZVUZCU1N4RFFVRkRMRTlCUVU4c1IwRkJSeXhMUVVGTExFTkJRVU03UVVGRGNrSXNZVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE8xRkJRMlk3TzBGQlJVY3NaVUZCVlR0WlFVRkJMRmxCUVVjN1FVRkRaaXhuUWtGQlR5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRlZCUVZVc1EwRkJRenRSUVVNdlFqczdRVUZWUnl4VlFVRkxPenM3T3pzN096dFpRVWhCTEZsQlFVYzdRVUZEVml4blFrRkJUeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXp0UlFVTXhRanRaUVVOUkxGVkJRVU1zUTBGQlF5eEZRVUZGTzBGQlExZ3NZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZEZEVJc1lVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eExRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhWUVVGVkxFTkJRVU03UVVGRE4wTXNZVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE8xRkJRMlk3TzBGQlZVY3NVVUZCUnpzN096czdPenM3V1VGSVFTeFpRVUZITzBGQlExSXNaMEpCUVU4c1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eEhRVUZITEVOQlFVTTdVVUZEZUVJN1dVRkRUU3hWUVVGRExFTkJRVU1zUlVGQlJUdEJRVU5VTEdGQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1IwRkJSeXhIUVVGSExFTkJRVU1zUTBGQlF6dFJRVU55UWpzN1FVRlZSeXhSUVVGSE96czdPenM3T3p0WlFVaEJMRmxCUVVjN1FVRkRVaXhuUWtGQlR5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWRCUVVjc1EwRkJRenRSUVVONFFqdFpRVU5OTEZWQlFVTXNRMEZCUXl4RlFVRkZPMEZCUTFRc1lVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eEhRVUZITEVkQlFVY3NRMEZCUXl4RFFVRkRPMUZCUTNKQ096dEJRVlZITEZOQlFVazdPenM3T3pzN08xbEJTRUVzV1VGQlJ6dEJRVU5VTEdkQ1FVRlBMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zU1VGQlNTeERRVUZETzFGQlEzcENPMWxCUTA4c1ZVRkJReXhEUVVGRExFVkJRVVU3UVVGRFZpeGhRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1IwRkJSeXhEUVVGRExFTkJRVU03VVVGRGRFSTdPMEZCVlVjc1UwRkJTVHM3T3pzN096czdXVUZJUVN4WlFVRkhPMEZCUTFRc1owSkJRVThzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4SlFVRkpMRU5CUVVNN1VVRkRNMEk3V1VGRFR5eFZRVUZETEVOQlFVTXNSVUZCUlR0QlFVTldMR0ZCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zU1VGQlNTeEhRVUZITEVOQlFVTXNRMEZCUXp0UlFVTjRRanM3T3p0VlFUZFBhMElzWTBGQll6dEpRVUZUTEZOQlFWTTdPMnRDUVVGb1F5eGpRVUZqTEVNN096czdPenRCUTFCdVF5eGhRVUZaTEVOQlFVTTdPenM3T3pzN096czdPenRCUVVWaUxFdEJRVWtzUjBGQlJ5eEhRVUZITEcxQ1FVRlBMRU5CUVVNc1EwRkJZU3hEUVVGRExFTkJRVU03UVVGRGFrTXNTMEZCU1N4SlFVRkpMRWRCUVVjc2JVSkJRVThzUTBGQlF5eERRVUZqTEVOQlFVTXNRMEZCUXp0QlFVTnVReXhMUVVGSkxGTkJRVk1zUjBGQlJ5eHRRa0ZCVHl4RFFVRkRMRU5CUVcxQ0xFTkJRVU1zUTBGQlF6dEJRVU0zUXl4TFFVRkpMRWxCUVVrc1IwRkJSeXh0UWtGQlR5eERRVUZETEVWQlFXZENMRU5CUVVNc1EwRkJRenM3UzBGRGVrSXNWMEZCVnl3clEwRkJUU3hGUVVGeFFqczdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3p0TFFYbENOMElzUjBGQlJ6dEJRVVZZTEZsQlJsRXNSMEZCUnl4SFFVVlNPekpDUVVaTExFZEJRVWM3TzBGQlNYQkNMRk5CUVVrc1QwRkJUeXhIUVVGSExFTkJRVU1zVDBGQlR5eEZRVUZETEU5QlFVOHNRMEZCUXl4RFFVRkRPenRCUVVWb1F5eFRRVUZKTEZGQlFWRXNSMEZCUnp0QlFVTmlMR0ZCUVZFc1EwRkJReXhIUVVGSExFVkJRVU1zUlVGQlJTeERRVUZETzBGQlEyaENMRzlDUVVGbExGbEJRVms3UVVGRE0wSXNZVUZCVVN4VlFVRlZPMEZCUTJ4Q0xHTkJRVk1zUTBGQlF5eERRVUZETEVOQlFVTXNSVUZCUXl4RFFVRkRMRU5CUVVNN1FVRkRaaXhoUVVGUkxFTkJRVU03UVVGRFZDeGpRVUZUTEVOQlFVTTdRVUZEVml4blFrRkJWeXhKUVVGSk8wMUJRMmhDTEVOQlFVTTdPMEZCUlVZc1owTkJhRUpwUWl4SFFVRkhMRFpEUVdkQ1pDeFRRVUZUTEVWQlFVTXNUMEZCVHl4RlFVRkRMRkZCUVZFc1JVRkJSVHM3UVVGRmJFTXNVMEZCU1N4RFFVRkRMRmRCUVZjc1IwRkJSeXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEZkQlFWY3NRMEZCUXpzN1FVRkZOME1zVTBGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFbEJRVWtzUTBGQlF6czdRVUZGTDBJc1UwRkJTU3hEUVVGRExFOUJRVThzUjBGQlJ5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRTlCUVU4c1EwRkJRenM3T3p0QlFVbHlReXhUUVVGSkxFTkJRVU1zU1VGQlNTeEhRVUZITEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1NVRkJTU3hEUVVGRE96dEJRVVV2UWl4VFFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFbEJRVWtzU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU1zUTBGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU1zUTBGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1NVRkJTU3hGUVVGRkxFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN08wRkJSV2hJTEZOQlFVa3NRMEZCUXl4SlFVRkpMRVZCUVVVc1EwRkJRenM3UVVGRldpeFRRVUZKTEVOQlFVTXNVVUZCVVN4SFFVRkhMRWxCUVVrc1YwRkJWeXhEUVVGRExFMUJRVTBzUTBGQlF5eEpRVUZKTEVOQlFVTXNTVUZCU1N4RlFVRkRMRWxCUVVrc1EwRkJReXhYUVVGWExFVkJRVU1zUTBGQlF5eERRVUZETEVWQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhGUVVGRExFTkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNSVUZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRMnhITEZOQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNWVUZCVlN4RFFVRkRPenRCUVVVM1F5eFRRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUzBGQlN5eERRVUZET3p0QlFVVXZRaXhUUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNSVUZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03U1VGRmFFTTdPMkZCZGtOclFpeEhRVUZIT3p0blFrRkJTQ3hIUVVGSE8wRkJlVU4wUWl4dFFrRkJZenRqUVVGQkxEQkNRVUZIT3p0QlFVVm1MR0ZCUVVrc1EwRkJReXhIUVVGSExFZEJRVWNzUjBGQlJ5eERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVNNVFpeGhRVUZKTEVOQlFVTXNTVUZCU1N4SFFVRkhMRWRCUVVjc1EwRkJReXhOUVVGTkxFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTTdPMEZCUldwRExHRkJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNWMEZCVnl4RFFVRkRMRWxCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zUTBGQlF6dEJRVU51UXl4aFFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExGZEJRVmNzUTBGQlF5eEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRU5CUVVNN1VVRkZja003TzBGQlJVUXNhMEpCUVdFN1kwRkJRU3g1UWtGQlJ6czdRVUZGWkN4aFFVRkpMRWxCUVVrc1EwRkJReXhSUVVGUkxFVkJRVVU3UVVGRGFrSXNaVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF5eERRVUZETEVWQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhGUVVGRExFTkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNSVUZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8xVkJRM1JFT3p0QlFVVkVMR0ZCUVVrc1NVRkJTU3hEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZPMEZCUXpWQ0xHVkJRVWtzUTBGQlF5eFhRVUZYTEVkQlFVY3NWVUZCVlN4RFFVRkRPMVZCUXk5Q0xFMUJRVTA3UVVGRFRDeGxRVUZKTEVOQlFVTXNWMEZCVnl4SFFVRkhMRmxCUVZrc1EwRkJRenRWUVVOcVF6czdRVUZGUkN4aFFVRkpMRU5CUVVNN1lVRkJSU3hEUVVGRE8yRkJRVVVzUTBGQlF6dGhRVUZGTEVOQlFVTTdZVUZCUlN4VFFVRlRPMkZCUVVVc1dVRkJXU3hoUVVGRE8wRkJRM2hETEdGQlFVa3NRMEZCUXl4UlFVRlJMRWRCUVVjN1FVRkRaQ3huUWtGQlN5eEZRVUZGTEVOQlFVTTdRVUZEVWl4WlFVRkRMRVZCUVVVc1EwRkJRenRWUVVOTUxFTkJRVU03TzBGQlJVWXNZVUZCU1N4SlFVRkpMRU5CUVVNc1YwRkJWeXhMUVVGTExGVkJRVlVzUlVGQlJUdEJRVU51UXl4bFFVRkpMRU5CUVVNc1UwRkJVeXhIUVVGSExFbEJRVWtzUTBGQlF5eExRVUZMTEVkQlFVY3NRMEZCUXl4RFFVRkRPMEZCUTJwRExGbEJRVU1zUjBGQlJ5eEpRVUZKTEVOQlFVTXNTMEZCU3l4SFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOcVFpeFpRVUZETEVkQlFVY3NRMEZCUXl4RFFVRkRPMEZCUTA0c1dVRkJReXhIUVVGSExFbEJRVWtzUTBGQlF5eFRRVUZUTEVOQlFVTTdRVUZEYmtJc1dVRkJReXhIUVVGSExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTTdRVUZEWml4bFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU1zUjBGQlJ5eEpRVUZKTEVOQlFVTXNVMEZCVXl4SFFVRkhMRWRCUVVjc1EwRkJRenRCUVVONFF5eGxRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRXRCUVVzc1IwRkJSeXhEUVVGRExFZEJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRWRCUVVNc1NVRkJTU3hEUVVGRExGVkJRVlVzU1VGQlJTeERRVUZETEVkQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRExFZEJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZETjBVc2IwSkJRVk1zUjBGQlJ5eFpRVUZaTEVkQlFVTXNTVUZCU1N4RFFVRkRMRk5CUVZNc1IwRkJSU3hEUVVGRExFTkJRVVVzUjBGQlF5eERRVUZETEVkQlFVTXNTMEZCU3l4RFFVRkRPMEZCUTNKRUxIVkNRVUZaTEVkQlFVY3NRMEZCUXl4SFFVRkRMRU5CUVVNc1EwRkJRenRWUVVOd1FpeE5RVUZOTzBGQlEwd3NaVUZCU1N4RFFVRkRMRk5CUVZNc1IwRkJSeXhKUVVGSkxFTkJRVU1zVFVGQlRTeEhRVUZITEVOQlFVTXNRMEZCUXp0QlFVTnNReXhaUVVGRExFZEJRVWNzUTBGQlF5eERRVUZETzBGQlEwNHNXVUZCUXl4SFFVRkhMRWxCUVVrc1EwRkJReXhOUVVGTkxFZEJRVU1zUTBGQlF5eERRVUZETzBGQlEyeENMRmxCUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETzBGQlEyWXNXVUZCUXl4SFFVRkhMRWxCUVVrc1EwRkJReXhUUVVGVExFTkJRVU03UVVGRGJFSXNaVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETEZOQlFWTXNSMEZCUnl4SFFVRkhMRU5CUVVNN1FVRkRlRU1zWlVGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExGVkJRVlVzU1VGQlJTeERRVUZETEVkQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRExFZEJRVU1zUTBGQlF5eERRVUZETEVkQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRE0wVXNiMEpCUVZNc1IwRkJSeXhqUVVGakxFZEJRVU1zU1VGQlNTeERRVUZETEZOQlFWTXNSMEZCUlN4RFFVRkRMRU5CUVVVc1IwRkJReXhEUVVGRExFZEJRVU1zUjBGQlJ5eERRVUZETzBGQlEzSkVMSFZDUVVGWkxFZEJRVWNzUTBGQlF5eEhRVUZETEVOQlFVTXNRMEZCUXp0VlFVTndRanM3UVVGRlJDeGhRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhIUVVGSExFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdRVUZETjBJc1lVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eFpRVUZaTEVOQlFVTXNSMEZCUnl4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRemRDTEdGQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExGZEJRVmNzUlVGQlF5eFRRVUZUTEVOQlFVTXNRMEZCUXp0QlFVTTNReXhoUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZsQlFWa3NRMEZCUXl4SlFVRkpMRVZCUVVNc1dVRkJXU3hEUVVGRExFTkJRVU03UVVGRGVrTXNZVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhaUVVGWkxFTkJRVU1zU1VGQlNTeEZRVUZETEZsQlFWa3NRMEZCUXl4RFFVRkRPMEZCUTNwRExHRkJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNXVUZCV1N4RFFVRkRMRTlCUVU4c1JVRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU5xUXl4aFFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eFJRVUZSTEVWQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN08wRkJSV3hETEdGQlFVa3NTVUZCU1N4RFFVRkRMRmRCUVZjc1MwRkJTeXhWUVVGVkxFVkJRVVU3UVVGRGJrTXNaVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhaUVVGWkxFTkJRVU1zU1VGQlNTeEZRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXk5Q0xHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWxCUVVrc1JVRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMVZCUTJ4RUxFMUJRVTA3UVVGRFRDeGxRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRmxCUVZrc1EwRkJReXhKUVVGSkxFVkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJRenRCUVVOcVJDeGxRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRmxCUVZrc1EwRkJReXhKUVVGSkxFVkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdWVUZEYUVNN1FVRkRSQ3hoUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZsQlFWa3NRMEZCUXl4SFFVRkhMRVZCUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0UlFVVTNRenM3UVVGRlJDeHRRa0ZCWXp0alFVRkJMREJDUVVGSE96dEJRVVZtTEdGQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFMUJRVTBzUlVGQlJTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1EwRkJReXhEUVVGRE8wRkJRMmhFTEdGQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1dVRkJXU3hEUVVGRExFMUJRVTBzUlVGQlJTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRE96dEJRVVZ1UkN4aFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFOUJRVThzUlVGQlJUdEJRVU5xUWl4bFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGbEJRVmtzUTBGQlF5eE5RVUZOTEVWQlFVTXNZVUZCWVN4RFFVRkRMRU5CUVVNN1ZVRkRPVU03VVVGRlJqczdRVUZGUkN4WFFVRk5PMk5CUVVFc2EwSkJRVWM3UVVGRFVDeGhRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTlCUVU4c1JVRkJSVHRCUVVOcVFpeGxRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zVTBGQlV5eEhRVUZETEVsQlFVa3NRMEZCUXp0VlFVTjJRenRCUVVORUxHRkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRWRCUVVjc1JVRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPenRCUVVVMVF5eGhRVUZKTEVsQlFVa3NRMEZCUXl4WFFVRlhMRXRCUVVzc1ZVRkJWU3hGUVVGRk8wRkJRMjVETEdWQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXl4SFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVlVGQlZTeEpRVUZGTEVsQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eERRVUZETEVkQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkROVVlzWlVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hGUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVY3NTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dFZRVU5xUlN4TlFVRk5PMEZCUTB3c1pVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eExRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhWUVVGVkxFbEJRVVVzU1VGQlNTeERRVUZETEV0QlFVc3NSMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU1zUjBGQlF5eERRVUZETEVOQlFVTXNSMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU16Uml4bFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGbEJRVmtzUTBGQlF5eEpRVUZKTEVWQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dFZRVU51UkR0UlFVTkdPenRCUVVkRUxGVkJRVXM3WTBGQlFTeHBRa0ZCUnp0QlFVTk9MR0ZCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF5eEhRVUZITEVsQlFVa3NRMEZCUXl4VFFVRlRMRWRCUVVNc1IwRkJSeXhEUVVGRE8wRkJRM0pETEdGQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1RVRkJUU3hIUVVGSExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTTdRVUZEYkVNc1lVRkJTU3hEUVVGRExFbEJRVWtzUlVGQlJTeERRVUZETzFGQlEySTdPMEZCUlVRc1UwRkJTVHRqUVVGQkxHZENRVUZITzBGQlEwd3NZVUZCU1N4SlFVRkpMRU5CUVVNc1QwRkJUeXhGUVVGRk8wRkJRMmhDTEdWQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1RVRkJUU3hEUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXpzN1FVRkZha01zWlVGQlNTeERRVUZETEV0QlFVc3NSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExGbEJRVmtzUTBGQlJTeEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRXRCUVVzc1EwRkJSU3hEUVVGRE96dEJRVVUzUkN4bFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUlVGQlF6dEJRVU5xUWl4clFrRkJTeXhGUVVGRkxFbEJRVWtzUTBGQlF5eExRVUZMTzBGQlEycENMR05CUVVNc1JVRkJSU3hKUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZGTEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUlVGQlF5eERRVUZETEVOQlFVTXNSVUZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUTBGQlF5eEZRVUZGTEVOQlFVTXNRMEZCUXp0QlFVTm9SQ3hqUVVGRExFVkJRVVVzU1VGQlNTeERRVUZETEVkQlFVY3NRMEZCUlN4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVWQlFVTXNRMEZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVOQlFVTXNSVUZCUlN4RFFVRkRMRU5CUVVNN1dVRkRha1FzUTBGQlF5eERRVUZETzFWQlJVbzdVVUZEUmpzN1FVRkZSQ3haUVVGUE8yTkJRVUVzYlVKQlFVYzdRVUZEVWl4aFFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRkxFTkJRVU03VVVGRFpqczdRVUZWUnl4VlFVRkxPenM3T3pzN08xbEJTa0VzV1VGQlJ6dEJRVU5XTEdkQ1FVRlBMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUzBGQlN5eERRVUZETzFGQlF6RkNPMWxCUlZFc1ZVRkJReXhMUVVGTExFVkJRVVU3UVVGRFppeGhRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTFCUVUwc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF6dEJRVU14UWl4aFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRlZCUVZVc1EwRkJRenRCUVVNM1F5eGhRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1JVRkJRenRCUVVOcVFpeG5Ra0ZCU3l4RlFVRkZMRWxCUVVrc1EwRkJReXhMUVVGTE8wRkJRMnBDTEZsQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRkxFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1JVRkJReXhEUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVWQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1EwRkJReXhGUVVGRkxFTkJRVU1zUTBGQlF6dEJRVU5vUkN4WlFVRkRMRVZCUVVVc1NVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlJTeEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFVkJRVU1zUTBGQlF5eERRVUZETEVWQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1JVRkJReXhEUVVGRExFTkJRVU1zUlVGQlJTeERRVUZETEVOQlFVTTdWVUZEYWtRc1EwRkJReXhEUVVGRE8wRkJRMGdzWVVGQlNTeERRVUZETEUxQlFVMHNSVUZCUlN4RFFVRkRPMUZCUTJZN08wRkJSVWNzWlVGQlZUdFpRVUZCTEZsQlFVYzdRVUZEWml4blFrRkJUeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEZWQlFWVXNRMEZCUXp0UlFVTXZRanM3T3p0VlFYWk1hMElzUjBGQlJ6dEpRVUZUTEZOQlFWTTdPMnRDUVVGeVFpeEhRVUZITEVNN096czdPenRCUXk5Q2VFSXNZVUZCV1N4RFFVRkRPenM3T3pzN096czdPMEZCUldJc1MwRkJTU3hKUVVGSkxFZEJRVWNzYlVKQlFVOHNRMEZCUXl4RFFVRmpMRU5CUVVNc1EwRkJRenRCUVVOdVF5eExRVUZKTEVkQlFVY3NSMEZCUnl4dFFrRkJUeXhEUVVGRExFTkJRV0VzUTBGQlF5eERRVUZETzBGQlEycERMRXRCUVVrc1UwRkJVeXhIUVVGSExHMUNRVUZQTEVOQlFVTXNRMEZCYlVJc1EwRkJReXhEUVVGRE96dEJRVWMzUXl4TFFVRkpMRXRCUVVzc1IwRkJSeXhsUVVGVExFdEJRVXNzUlVGQlF5eFJRVUZSTEVWQlFVVTdPMEZCUlc1RExFOUJRVWtzUTBGQlF5eERRVUZETEVkQlFVY3NTMEZCU3l4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOcVFpeFBRVUZKTEVOQlFVTXNRMEZCUXl4SFFVRkhMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRGFrSXNUMEZCU1N4RFFVRkRMRkZCUVZFc1IwRkJSeXhSUVVGUkxFTkJRVU03TzBGQlJYcENMRTlCUVVrc1EwRkJReXhQUVVGUExFZEJRVWNzUjBGQlJ5eERRVUZETEUxQlFVMHNRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJRenRCUVVOd1F5eFBRVUZKTEVOQlFVTXNUMEZCVHl4RFFVRkRMRmxCUVZrc1EwRkJReXhOUVVGTkxFVkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4TlFVRk5MRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03TzBGQlJUbEVMRTlCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zVDBGQlR5eERRVUZETEZkQlFWY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExFTkJRVU03TzBGQlJXaEVMRTlCUVVrc1EwRkJReXhOUVVGTkxFZEJRVWNzV1VGQlZ6dEJRVU4yUWl4VFFVRkpMRU5CUVVNc1IwRkJSeXhGUVVGRExFVkJRVVVzU1VGQlNTeERRVUZETEVkQlFVY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUlVGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRTFCUVUwc1EwRkJReXhIUVVGRExFVkJRVVVzUTBGQlF5eEhRVUZETEVOQlFVTXNRMEZCUXp0QlFVTndSU3hUUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZsQlFWa3NRMEZCUXl4SFFVRkhMRVZCUVVNc1EwRkJReXhEUVVGRExFTkJRVU03U1VGRGJFTXNRMEZCUXpzN1FVRkZSaXhQUVVGSkxFTkJRVU1zU1VGQlNTeEhRVUZITEZWQlFWTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1JVRkJSVHM3UVVGRmVFSXNVMEZCU1N4RFFVRkRMRU5CUVVNc1IwRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eExRVUZITEVOQlFVTXNSMEZCU1N4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRExFTkJRVU1zUTBGQlF6dEJRVU51UXl4VFFVRkpMRU5CUVVNc1EwRkJReXhIUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEV0QlFVY3NRMEZCUXl4SFFVRkpMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zUTBGQlF5eERRVUZET3p0QlFVVnVReXhUUVVGSkxFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNTMEZCU3l4RFFVRkRMRTlCUVU4c1EwRkJReXhKUVVGSkxFTkJRVU1zU1VGQlJTeERRVUZETEVWQlFVVTdPMEZCUlhoRExGZEJRVWtzVTBGQlV5eEhRVUZITEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFOUJRVThzUTBGQlF5eEpRVUZKTEVOQlFVTXNSMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRjRVFzVjBGQlNTeFRRVUZUTEVkQlFVY3NTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhMUVVGTExFTkJRVU1zVDBGQlR5eERRVUZETEVsQlFVa3NRMEZCUXl4SFFVRkRMRU5CUVVNc1EwRkJRenM3UVVGRmNFUXNWMEZCU1N4UlFVRlJMRWRCUVVjc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eExRVUZMTEVOQlFVTXNVMEZCVXl4RFFVRkRMRU5CUVVNN1FVRkRPVU1zVjBGQlNTeFJRVUZSTEVkQlFVY3NTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhMUVVGTExFTkJRVU1zVTBGQlV5eERRVUZETEVOQlFVTTdPMEZCUlRsRExGZEJRVWtzU1VGQlNTeEhRVUZITEZOQlFWTXNTVUZCU1N4RFFVRkRMRWRCUVVjc1VVRkJVU3hEUVVGRExFTkJRVU1zUjBGQlJ5eERRVUZETEVOQlFVTTdRVUZETTBNc1YwRkJTU3hMUVVGTExFZEJRVWNzVTBGQlV5eEhRVUZITEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFMUJRVTBzUjBGQlJ5eFJRVUZSTEVOQlFVTXNRMEZCUXl4SFFVRkhMRU5CUVVNc1EwRkJRenM3UVVGRmNFVXNWMEZCU1N4SlFVRkpMRU5CUVVNc1EwRkJReXhIUVVGSExFbEJRVWtzUlVGQlJUdEJRVUZGTEdGQlFVa3NRMEZCUXl4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRE8xRkJRVVU3UVVGRGNrTXNWMEZCU1N4SlFVRkpMRU5CUVVNc1EwRkJReXhIUVVGSExFdEJRVXNzUlVGQlJUdEJRVUZGTEdGQlFVa3NRMEZCUXl4RFFVRkRMRWRCUVVjc1MwRkJTeXhEUVVGRE8xRkJRVVU3VFVGRmVFTTdPMEZCUlVRc1UwRkJTU3hEUVVGRExGRkJRVkVzUjBGQlJ5eEpRVUZKTEVOQlFVTXNZMEZCWXl4RlFVRkZMRU5CUVVNN1FVRkRkRU1zVTBGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hGUVVGRkxFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRha1FzVTBGQlNTeERRVUZETEU5QlFVOHNRMEZCUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hGUVVGRkxFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1NVRkRiRVFzUTBGQlF6czdRVUZGUml4UFFVRkpMRU5CUVVNc1kwRkJZeXhIUVVGSExGbEJRVmM3UVVGREwwSXNXVUZCVHp0QlFVTk1MRkZCUVVNc1JVRkJSU3hKUVVGSkxFTkJRVU1zUTBGQlF5eEhRVUZITEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTenRCUVVNdlFpeFJRVUZETEVWQlFVVXNRMEZCUXl4RFFVRkRMRWRCUVVNc1NVRkJTU3hEUVVGRExFTkJRVU1zU1VGQlNTeEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRTFCUVUwN1RVRkRja01zUTBGQlF6dEpRVU5JTEVOQlFVTTdPMEZCUlVZc1QwRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNRMEZCUXl4RlFVRkRMRWxCUVVrc1EwRkJReXhEUVVGRExFVkJRVU1zU1VGQlNTeERRVUZETEVOQlFVTTdRVUZET1VJc1QwRkJTU3hEUVVGRExFMUJRVTBzUlVGQlJTeERRVUZET3p0QlFVVmtMRTlCUVVrc1EwRkJReXhQUVVGUExFZEJRVWNzV1VGQlZ6dEJRVU40UWl4VFFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFOUJRVThzUTBGQlF5eFhRVUZYTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRE8wRkJRMmhFTEZOQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFMUJRVTBzUTBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRXRCUVVzc1EwRkJReXhQUVVGUExFTkJRVU1zU1VGQlNTeERRVUZETEVWQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1NVRkRha1VzUTBGQlF6dEZRVWRJTEVOQlFVTTdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPMHRCWjBSdFFpeFJRVUZSTzBGQlJXaENMRmxCUmxFc1VVRkJVU3hIUVVWaU96SkNRVVpMTEZGQlFWRTdPMEZCU1hwQ0xGTkJRVWtzVDBGQlR5eEhRVUZITEVOQlFVTXNUMEZCVHl4RFFVRkRMRU5CUVVNN08wRkJSWGhDTEZOQlFVa3NVVUZCVVN4SFFVRkhPMEZCUTJJc1lVRkJVU3hEUVVGRExFZEJRVWNzUlVGQlF5eEhRVUZITEVOQlFVTTdRVUZEYWtJc1pVRkJWU3hEUVVOWU8wRkJRME1zVlVGQlF5eEZRVUZGTEVkQlFVYzdRVUZEVGl4VlFVRkRMRVZCUVVVc1IwRkJSenRSUVVOT0xFVkJRMFE3UVVGRFF5eFZRVUZETEVWQlFVVXNTVUZCU1R0QlFVTlFMRlZCUVVNc1JVRkJSU3hIUVVGSE8xRkJRMDRzUlVGRFJEdEJRVU5ETEZWQlFVTXNSVUZCUlN4SlFVRkpPMEZCUTFBc1ZVRkJReXhGUVVGRkxFZEJRVWM3VVVGRFRpeEZRVU5FTzBGQlEwTXNWVUZCUXl4RlFVRkZMRWRCUVVjN1FVRkRUaXhWUVVGRExFVkJRVVVzUjBGQlJ6dFJRVU5PTEVOQlEwUTdUVUZEUVN4RFFVRkRPenRCUVVWR0xHZERRVFZDYVVJc1VVRkJVU3cyUTBFMFFtNUNMRk5CUVZNc1JVRkJReXhQUVVGUExFVkJRVU1zVVVGQlVTeEZRVUZGT3p0QlFVVnNReXhUUVVGSkxFTkJRVU1zVFVGQlRTeEhRVUZITEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1RVRkJUU3hEUVVGRE96dEJRVVZ1UXl4VFFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFVkJRVVVzUTBGQlF6czdRVUZGYUVJc1UwRkJTU3hEUVVGRExGRkJRVkVzUjBGQlJ5eExRVUZMTEVOQlFVTTdPMEZCUlhSQ0xGTkJRVWtzUTBGQlF5eEpRVUZKTEVWQlFVVXNRMEZCUXp0SlFVZGlPenRoUVhaRGEwSXNVVUZCVVRzN1owSkJRVklzVVVGQlVUdEJRWGxETTBJc2JVSkJRV003WTBGQlFTd3dRa0ZCUnpzN08wRkJSMllzWVVGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4UFFVRlBMRU5CUVVNc1ZVRkJReXhMUVVGTExFVkJRVXM3UVVGRE4wSXNaVUZCU1N4SlFVRkpMRWRCUVVjc1NVRkJTU3hMUVVGTExFTkJRVU1zUzBGQlN5eFJRVUZOTEVOQlFVTTdRVUZEYWtNc2FVSkJRVXNzUzBGQlN5eERRVUZETEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1EwRkJRenRWUVVOMlFpeERRVUZETEVOQlFVTTdPMEZCUlVnc1lVRkJTU3hEUVVGRExGVkJRVlVzUlVGQlJTeERRVUZET3p0QlFVVnNRaXhoUVVGSkxFTkJRVU1zU1VGQlNTeEhRVUZITEVkQlFVY3NRMEZCUXl4TlFVRk5MRU5CUVVNc1ZVRkJWU3hEUVVGRExFTkJRVU03UVVGRGJrTXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhaUVVGWkxFTkJRVU1zWTBGQll5eEZRVUZGTEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXpGRExHRkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hOUVVGTkxFTkJRVU1zUTBGQlF6czdRVUZGZGtNc1lVRkJTU3hEUVVGRExFOUJRVThzUTBGQlF5eFhRVUZYTEVOQlFVTXNTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhEUVVGRE96dEJRVVZ3UXl4aFFVRkpMRU5CUVVNc1NVRkJTU3hIUVVGSExFZEJRVWNzUTBGQlF5eE5RVUZOTEVOQlFVTXNWVUZCVlN4RFFVRkRMRU5CUVVNN1FVRkRia01zWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4WlFVRlpMRU5CUVVNc1kwRkJZeXhGUVVGRkxFdEJRVXNzUTBGQlF5eERRVUZET3p0QlFVVTVReXhoUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZkQlFWY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFTkJRVU03VVVGRmNrTTdPMEZCUlVRc2EwSkJRV0U3WTBGQlFTeDVRa0ZCUnpzN1FVRkZaQ3hqUVVGTExFbEJRVWtzUTBGQlF5eEhRVUZETEVOQlFVTXNSVUZCUlN4RFFVRkRMRWRCUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXl4RlFVRkZMRVZCUVVVN1FVRkRkRU1zWlVGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF6dEJRVU4yUWl4bFFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEVsQlFVa3NSVUZCUlN4RFFVRkRPMVZCUTNSQ096dEJRVVZFTEdGQlFVa3NRMEZCUXl4TlFVRk5MRVZCUVVVc1EwRkJRenRSUVVWbU96dEJRVVZFTEcxQ1FVRmpPMk5CUVVFc01FSkJRVWM3T3p0QlFVVm1MR0ZCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eERRVUZETEdWQlFXVXNSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFbEJRVWtzUTBGQlF6dEJRVU4wUkN4aFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGbEJRVmtzUTBGQlF5eFJRVUZSTEVWQlFVVXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dEJRVU55UkN4aFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGbEJRVmtzUTBGQlF5eE5RVUZOTEVWQlFVVXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dEJRVU51UkN4aFFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFOUJRVThzUTBGQlF5eFZRVUZETEVsQlFVa3NSVUZCU3p0QlFVTXpRaXhsUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEZsQlFWa3NRMEZCUXl4TlFVRk5MRVZCUVVNc1RVRkJTeXhOUVVGTkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdWVUZEZEVRc1EwRkJReXhEUVVGRE8xRkJSVW83TzBGQlJVUXNWMEZCVFR0alFVRkJMR3RDUVVGSE96dEJRVVZRTEdGQlFVa3NRMEZCUXl4aFFVRmhMRVZCUVVVc1EwRkJRenRSUVVOMFFqczdRVUZGUkN4dlFrRkJaVHRqUVVGQkxESkNRVUZIT3pzN1FVRkRhRUlzWVVGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4RlFVRkZMRU5CUVVNN1FVRkRha0lzWVVGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4UFFVRlBMRU5CUVVNc1ZVRkJReXhKUVVGSkxFVkJRVXM3UVVGRE0wSXNhVUpCUVVzc1RVRkJUU3hEUVVGRExFbEJRVWtzUTBGQlF5eEZRVUZGTEVOQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1EwRkJReXhGUVVGRkxFTkJRVU1zUlVGQlJTeEpRVUZKTEVOQlFVTXNRMEZCUXl4RlFVRkZMRU5CUVVNc1EwRkJRenRWUVVNMVF5eERRVUZETEVOQlFVTTdVVUZEU2pzN1FVRkZSQ3hyUWtGQllUdGpRVUZCTEhsQ1FVRkhPenM3UVVGSFpDeGhRVUZKTEVsQlFVa3NSMEZCUnl4SlFVRkpMRWRCUVVVc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJReXhIUVVGRExFbEJRVWtzUTBGQlF6czdPenM3UVVGTEwwTXNZVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhQUVVGUExFTkJRVU1zVlVGQlF5eEpRVUZKTEVWQlFVczdPMEZCUlROQ0xHVkJRVWtzU1VGQlNTeEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNc1IwRkJSeXhIUVVGSExFZEJRVWNzU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRE8xVkJRM2hFTEVOQlFVTXNRMEZCUXpzN08wRkJTVWdzWVVGQlNTeEpRVUZKTEVsQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1IwRkJSeXhIUVVGRkxFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhOUVVGTkxFZEJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNc1EwRkJRenM3UVVGRmNrVXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhaUVVGWkxFTkJRVU1zVVVGQlVTeEZRVUZGTEVsQlFVa3NRMEZCUXl4RFFVRkRPenM3T3p0QlFVdDJReXhoUVVGSkxFbEJRVWtzU1VGQlNTeEhRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVVc1IwRkJSeXhIUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVTXNTVUZCU1N4RFFVRkRPMEZCUXpsRExHRkJRVWtzU1VGQlNTeEpRVUZKTEVkQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJRenM3UVVGRmVrSXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhaUVVGWkxFTkJRVU1zVVVGQlVTeEZRVUZGTEVsQlFVa3NRMEZCUXl4RFFVRkRPMUZCUlhoRE96dEJRVWxFTEZWQlFVczdZMEZCUVN4cFFrRkJSenM3UVVGRlRpeGhRVUZKTEVOQlFVTXNVVUZCVVN4SFFVRkhMRXRCUVVzc1EwRkJRenRCUVVOMlFpeGhRVUZKTEVOQlFVTXNVVUZCVVN4SFFVRkhMRWxCUVVrc1EwRkJReXhsUVVGbExFVkJRVVVzUTBGQlF6czdRVUZGZEVNc1lVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4SFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFVkJRVU1zUTBGQlF5eEhRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJReXhIUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0QlFVTnVSaXhoUVVGSkxFTkJRVU1zVTBGQlV5eERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJRenM3TzBGQlJ6bENMR0ZCUVVrc1EwRkJReXhsUVVGbExFVkJRVVVzUTBGQlF6dEJRVU4yUWl4aFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUlVGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN1FVRkRha01zWVVGQlNTeERRVUZETEUxQlFVMHNSVUZCUlN4RFFVRkRPMUZCUTJRN08wRkJSVVFzVTBGQlNUdGpRVUZCTEdkQ1FVRkhPMEZCUTA0c1lVRkJTU3hKUVVGSkxFTkJRVU1zVDBGQlR5eEZRVUZGTzBGQlEyWXNaVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVWQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8wRkJRM0JFTEdWQlFVa3NRMEZCUXl4UlFVRlJMRWRCUVVjc1NVRkJTU3hEUVVGRE96dEJRVVZ5UWl4bFFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXl4SlFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETEVkQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1JVRkJReXhEUVVGRExFZEJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRMRWRCUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETzBGQlEzQkdMR1ZCUVVrc1EwRkJReXhUUVVGVExFTkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRPenRCUVVVM1FpeGxRVUZKTEVOQlFVTXNaVUZCWlN4RlFVRkZMRU5CUVVNN1FVRkRla0lzWlVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRVZCUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZETzBGQlEyaERMR1ZCUVVrc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF6dFZRVU5rTzFGQlEwUTdPMEZCUlVRc1dVRkJUenRqUVVGQkxHMUNRVUZIT3p0QlFVVlVMR0ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeEZRVUZGTzBGQlEycENMR1ZCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRTlCUVU4c1JVRkJSU3hEUVVGRE8xVkJRM1JET3p0QlFVVkJMR0ZCUVVrc1EwRkJReXhsUVVGbExFVkJRVVVzUTBGQlF6dEJRVU4yUWl4aFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUlVGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN1FVRkRha01zWVVGQlNTeERRVUZETEUxQlFVMHNSVUZCUlN4RFFVRkRPenM3UVVGSFpDeGhRVUZKTEVOQlFVTXNVVUZCVVN4SFFVRkhMRWxCUVVrc1EwRkJRenRSUVVOeVFqczdRVUZIUkN4dlFrRkJaVHRqUVVGQkxESkNRVUZITzBGQlEycENMR0ZCUVVrc1dVRkJXU3hIUVVGSExFbEJRVWtzUTBGQlF6czdRVUZGZUVJc1lVRkJTU3hYUVVGWExFZEJRVWNzUzBGQlN5eERRVUZETzBGQlEzaENMR0ZCUVVrc1RVRkJUU3hIUVVGSExFdEJRVXNzUTBGQlF6dEJRVU5zUWl4aFFVRkpMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTXNSMEZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRE8wRkJRMmhETEdGQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTXNSMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRE8wRkJRMjVETEdGQlFVa3NTMEZCU3l4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU03UVVGRGVFSXNZMEZCU3l4SlFVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExFVkJRVVVzUTBGQlF5eEhRVUZETEV0QlFVc3NRMEZCUXl4TlFVRk5MRVZCUVVVc1EwRkJReXhGUVVGRkxFVkJRVVU3T3p0QlFVZHdReXhsUVVGSkxGRkJRVkVzUjBGQlJ5eEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkhMRWxCUVVrc1EwRkJReXhIUVVGSExFTkJRVWNzUzBGQlN5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1IwRkJSeXhEUVVGRExFVkJRVWNzUTBGQlF5eERRVUZETEVkQlFVY3NTVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJSU3hMUVVGTExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4SFFVRkhMRU5CUVVNc1JVRkJSeXhEUVVGRExFTkJRVU1zUTBGQlJTeERRVUZET3pzN1FVRkhOVVlzWlVGQlNTeFJRVUZSTEVkQlFVY3NWMEZCVnl4RlFVRkZPMEZCUXpOQ0xIZENRVUZYTEVkQlFVY3NVVUZCVVN4RFFVRkRPMEZCUTNaQ0xIbENRVUZaTEVkQlFVY3NRMEZCUXl4RFFVRkRPMEZCUTJwQ0xHMUNRVUZOTEVkQlFVY3NRMEZCUXl4SFFVRkhMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdXVUZEZUVJN1ZVRkZSRHM3TzBGQlIwUXNZVUZCU1N4WFFVRlhMRWRCUVVNc1NVRkJTU3hGUVVGRk96dEJRVVZ1UWl4MVFrRkJXU3hIUVVGSExFbEJRVWtzUTBGQlF5eGhRVUZoTEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRExFZEJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPenRCUVVVM1JDeGxRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRTFCUVUwc1EwRkJReXhaUVVGWkxFVkJRVU1zUTBGQlF5eEZRVUZGTEVsQlFVa3NTMEZCU3l4RFFVRkRPMEZCUXpORExHTkJRVU1zUlVGQlJTeEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN6dEJRVU14UWl4alFVRkRMRVZCUVVVc1EwRkJReXhIUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4SFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTk8xbEJRemRDTEVWQlFVVXNTVUZCU1N4RFFVRkRMRU5CUVVNc1EwRkJRenRCUVVOU0xHVkJRVWtzUTBGQlF5eFJRVUZSTEVkQlFVY3NTVUZCU1N4RFFVRkRPMVZCUlhaQ096dEJRVVZFTEdkQ1FVRlBMRmxCUVZrc1EwRkJRenRSUVVOd1FqczdRVUZGUkN4clFrRkJZVHRqUVVGQkxIVkNRVUZETEVOQlFVTXNSVUZCUlRzN08wRkJRMllzWVVGQlNTeExRVUZMTEVkQlFVY3NRMEZCUXl4RFFVRkRPMEZCUTJRc1lVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eFBRVUZQTEVOQlFVTXNWVUZCUXl4SlFVRkpMRVZCUVVNc1EwRkJReXhGUVVGTE8wRkJRemRDTEdWQlFVa3NUVUZCU3l4TFFVRkxMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eEpRVUZKTEVOQlFVTXNSVUZCUlR0QlFVTjRRaXhyUWtGQlN5eEhRVUZITEVOQlFVTXNSMEZCUXl4RFFVRkRMRU5CUVVNN1dVRkRZanRWUVVOR0xFTkJRVU1zUTBGQlF6dEJRVU5JTEdkQ1FVRlBMRXRCUVVzc1EwRkJRenRSUVVOa096dEJRVVZFTEdOQlFWTTdZMEZCUVN4dFFrRkJReXhEUVVGRExFVkJRVVU3TzBGQlJWb3NZVUZCU1N4UlFVRlJMRWRCUVVjc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zUlVGQlJTeERRVUZETEVWQlFVVXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRhRVFzWVVGQlNTeFJRVUZSTEVkQlFVY3NTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1JVRkJSU3hEUVVGRExFVkJRVVVzUTBGQlF5eERRVUZETEVOQlFVTTdPMEZCUlM5RExHRkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1NVRkJTU3hEUVVGRkxGRkJRVkVzUlVGQlJTeFJRVUZSTEVOQlFVVXNRMEZCUXp0UlFVVXhRenM3UVVGTFJDeGxRVUZWT3pzN096czdZMEZCUVN4elFrRkJSenRCUVVOWUxHRkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNTVUZCU1N4RFFVRkRMRlZCUVZNc1EwRkJReXhGUVVGRkxFTkJRVU1zUlVGQlF6dEJRVU0xUWl4clFrRkJUeXhEUVVGRExFTkJRVU1zUTBGQlF5eEhRVUZITEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1ZVRkRiRUlzUTBGQlF5eERRVUZETzFGQlEwbzdPMEZCVVVRc1lVRkJVVHM3T3pzN096czdZMEZCUVN4clFrRkJReXhEUVVGRExFVkJRVU1zUTBGQlF5eEZRVUZGTzBGQlExb3NZVUZCU1N4TFFVRkxMRWRCUVVjc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eE5RVUZOTEVOQlFVTTdPMEZCUlRsQ0xHRkJRVWtzUTBGQlF5eFZRVUZWTEVWQlFVVXNRMEZCUXpzN1FVRkZiRUlzWTBGQlN5eEpRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRVZCUVVVc1EwRkJReXhIUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNc1JVRkJSU3hGUVVGRk8wRkJRM2hETEdWQlFVa3NRMEZCUXl4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4RlFVRkZPMEZCUTNaQ0xHdENRVUZMTEVkQlFVY3NRMEZCUXl4RFFVRkRPMEZCUTFZc2JVSkJRVTA3V1VGRFVEdFZRVU5JT3p0QlFVVkJMR0ZCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NSVUZCUlN4RFFVRkRMRVZCUVVVc1NVRkJTU3hMUVVGTExFTkJRVU03UVVGRGNFTXNXVUZCUXl4RlFVRkZMRU5CUVVNN1FVRkRTaXhaUVVGRExFVkJRVVVzUTBGQlF6dFZRVU5NTEVWQlFVVXNTVUZCU1N4RFFVRkRMRU5CUVVNc1EwRkJRenM3UVVGRlZpeGhRVUZKTEVOQlFVTXNVMEZCVXl4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE96dEJRVVYwUWl4aFFVRkpMRU5CUVVNc1pVRkJaU3hGUVVGRkxFTkJRVU03UVVGRGRrSXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFVkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRPenRCUVVWb1F5eGhRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1VVRkRaanM3UVVGUFJDeFRRVUZKT3pzN096czdPMk5CUVVFc1kwRkJReXhEUVVGRExFVkJRVVU3TzBGQlJVNHNZVUZCU1N4VFFVRlRMRWRCUVVjc1NVRkJTU3hEUVVGRExHRkJRV0VzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0QlFVTjBReXhoUVVGSkxGVkJRVlVzUjBGQlJ5eFRRVUZUTEVkQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXpkQ0xHRkJRVWtzVlVGQlZTeEhRVUZITEVOQlFVTXNSVUZCUlR0QlFVTnNRaXh4UWtGQlZTeEhRVUZITEVOQlFVTXNRMEZCUXp0VlFVTm9RanRCUVVORUxHRkJRVWtzVTBGQlV5eEpRVUZKTEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1RVRkJUU3hGUVVGRk8wRkJRMnhETEc5Q1FVRlRMRWRCUVVjc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eE5RVUZOTEVkQlFVTXNRMEZCUXl4RFFVRkRPMVZCUTJwRE8wRkJRMFFzWVVGQlNTeFZRVUZWTEVkQlFVY3NTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhWUVVGVkxFTkJRVU1zUTBGQlF6dEJRVU40UXl4aFFVRkpMRk5CUVZNc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEZOQlFWTXNRMEZCUXl4RFFVRkRPMEZCUTNSRExHRkJRVWtzUjBGQlJ5eEhRVUZITEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJReXhGUVVGRExGVkJRVlVzUTBGQlF5eERRVUZETEVWQlFVVXNVMEZCVXl4RFFVRkRMRU5CUVVNc1JVRkJSU3hEUVVGRExFVkJRVVVzUTBGQlF5eERRVUZETEVOQlFVTTdRVUZEZUVRc1lVRkJTU3hMUVVGTExFZEJRVWNzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SFFVRkhMRVZCUVVNc1ZVRkJWU3hEUVVGRExFTkJRVU1zUlVGQlF5eFRRVUZUTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRkRVFzWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRVZCUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03UVVGRGVFSXNaMEpCUVU4c1MwRkJTeXhEUVVGRE8xRkJRMlE3TzBGQlUwUXNZMEZCVXpzN096czdPenM3TzJOQlFVRXNiVUpCUVVNc1MwRkJTeXhGUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVWQlFVVTdRVUZEYmtJc1lVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4SlFVRkpMRU5CUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzBGQlF6VkNMR0ZCUVVrc1EwRkJReXhUUVVGVExFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZEZEVJc1lVRkJTU3hEUVVGRExHVkJRV1VzUlVGQlJTeERRVUZETzBGQlEzWkNMR0ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeEZRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVOb1F5eGhRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1VVRkRaanM3UVVGVFJDeG5Ra0ZCVnpzN096czdPenM3TzJOQlFVRXNjVUpCUVVNc1MwRkJTeXhGUVVGRExFOUJRVThzUlVGQlF5eFBRVUZQTEVWQlFVVTdRVUZEYWtNc1lVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4SlFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4RFFVRkRMRWRCUVVNc1QwRkJUeXhGUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNc1EwRkJReXhIUVVGRExFOUJRVThzUTBGQlF5eERRVUZETzBGQlEyaEdMR0ZCUVVrc1EwRkJReXhUUVVGVExFTkJRVU1zUzBGQlN5eERRVUZETEVOQlFVTTdRVUZEZEVJc1lVRkJTU3hEUVVGRExHVkJRV1VzUlVGQlJTeERRVUZETzBGQlEzWkNMR0ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeEZRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRCUVVOb1F5eGhRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1VVRkRaanM3UVVGUFJDeHBRa0ZCV1RzN096czdPenRqUVVGQkxITkNRVUZETEV0QlFVc3NSVUZCUlR0QlFVTnNRaXhoUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRMRTlCUVU4c1JVRkJSU3hEUVVGRE8wRkJRelZDTEdGQlFVa3NRMEZCUXl4bFFVRmxMRVZCUVVVc1EwRkJRenRCUVVOMlFpeGhRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdRVUZEYUVNc1lVRkJTU3hEUVVGRExFMUJRVTBzUlVGQlJTeERRVUZETzFGQlEyWTdPMEZCVDBRc1kwRkJVenM3T3pzN096dGpRVUZCTEcxQ1FVRkRMRk5CUVZNc1JVRkJSVHM3TzBGQlEyNUNMR2RDUVVGUExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNUVUZCVFN4RlFVRkZPMEZCUTNoQ0xHVkJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1QwRkJUeXhGUVVGRkxFTkJRVU03VlVGRGVrSTdRVUZEUkN4clFrRkJVeXhEUVVGRExFOUJRVThzUTBGQlF5eFZRVUZETEV0QlFVc3NSVUZCU3p0QlFVTXpRaXhwUWtGQlN5eFJRVUZSTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNc1JVRkJReXhMUVVGTExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdWVUZEYUVNc1EwRkJReXhEUVVGRE8wRkJRMGdzWVVGQlNTeERRVUZETEdWQlFXVXNSVUZCUlN4RFFVRkRPMEZCUTNaQ0xHRkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RlFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dEJRVU5vUXl4aFFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRkxFTkJRVU03VVVGRFpqczdPenRWUVRkV2EwSXNVVUZCVVR0SlFVRlRMRk5CUVZNN08ydENRVUV4UWl4UlFVRlJMRU03T3pzN096dEJRMnBJTjBJc1lVRkJXU3hEUVVGRE96czdPenM3T3pzN08wRkJSV0lzUzBGQlNTeEhRVUZITEVkQlFVY3NiVUpCUVU4c1EwRkJReXhEUVVGaExFTkJRVU1zUTBGQlF6czdRVUZGYWtNc1MwRkJTU3hUUVVGVExFZEJRVWNzYlVKQlFVOHNRMEZCUXl4RFFVRnRRaXhEUVVGRExFTkJRVU03T3pzN096czdPenM3T3pzN096czdPenM3T3pzN08wdEJkVUp3UXl4UFFVRlBMSFZDUVVGUkxFTkJRVk1zUlVGQmVFSXNUMEZCVHpzN1MwRkZTeXhYUVVGWE8wRkJSVzVDTEZsQlJsRXNWMEZCVnl4SFFVVm9RanN5UWtGR1N5eFhRVUZYT3p0QlFVazFRaXhUUVVGSkxFOUJRVThzUjBGQlJ5eERRVUZETEU5QlFVOHNSVUZCUXl4UFFVRlBMRU5CUVVNc1EwRkJRenM3UVVGRmFFTXNVMEZCU1N4UlFVRlJMRWRCUVVjN1FVRkRZaXhoUVVGUkxFTkJRVU1zUjBGQlJ5eEZRVUZETEVkQlFVY3NRMEZCUXp0TlFVTnNRaXhEUVVGRE96dEJRVVZHTEdkRFFWWnBRaXhYUVVGWExEWkRRVlYwUWl4VFFVRlRMRVZCUVVNc1QwRkJUeXhGUVVGRExGRkJRVkVzUlVGQlJUczdRVUZGYkVNc1UwRkJTU3hEUVVGRExFOUJRVThzUjBGQlJ5eFBRVUZQTEVWQlFVVXNRMEZCUXpzN1FVRkZla0lzVTBGQlNTeERRVUZETEZGQlFWRXNSMEZCUnl4SlFVRkpMRU5CUVVNc1QwRkJUeXhEUVVGRExHTkJRV01zUlVGQlJTeERRVUZETzBGQlF6bERMRk5CUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zVDBGQlR5eEhRVUZITEVsQlFVa3NRMEZCUXp0QlFVTTNRaXhUUVVGSkxFTkJRVU1zV1VGQldTeEhRVUZITEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc2FVSkJRV2xDTEVOQlFVTTdRVUZEY0VRc1UwRkJTU3hEUVVGRExGTkJRVk1zUjBGQlJ5eEpRVUZKTEZWQlFWVXNRMEZCUXl4SlFVRkpMRU5CUVVNc1dVRkJXU3hEUVVGRExFTkJRVU03TzBGQlJXNUVMRk5CUVVrc1EwRkJReXhOUVVGTkxFZEJRVWNzU1VGQlNTeERRVUZET3p0QlFVVnVRaXhUUVVGSkxFTkJRVU1zVFVGQlRTeEhRVUZITEV0QlFVc3NRMEZCUXpzN1FVRkZjRUlzVTBGQlNTeERRVUZETEVsQlFVa3NSVUZCUlN4RFFVRkRPMGxCUldJN08yRkJla0pyUWl4WFFVRlhPenRuUWtGQldDeFhRVUZYTzBGQk1rSTVRaXhsUVVGVk8yTkJRVUVzYzBKQlFVYzdRVUZEV0N4aFFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFbEJRVWtzUjBGQlJ5eERRVUZETEZkQlFWY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03UVVGREwwTXNZVUZCU1N4RFFVRkRMRTlCUVU4c1IwRkJSeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEU5QlFVOHNRMEZCUXp0UlFVTndRenM3UVVGRlJDeHJRa0ZCWVR0alFVRkJMSGxDUVVGSE8wRkJRMlFzWVVGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TlFVRk5MRU5CUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUlVGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN1VVRkROVU03TzBGQlJVUXNiVUpCUVdNN1kwRkJRU3d3UWtGQlJ6dEJRVU5tTEdGQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1QwRkJUeXhEUVVGRExFdEJRVXNzUTBGQlF5eGxRVUZsTEVkQlFVY3NTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhKUVVGSkxFTkJRVU03VVVGRE9VUTdPMEZCUlVRc1YwRkJUVHRqUVVGQkxHdENRVUZIT3p0QlFVVlFMR0ZCUVVrc1NVRkJTU3hEUVVGRExFMUJRVTBzUlVGQlJUdEJRVU5tTEdkRFFVRnhRaXhEUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhEUVVGRExFTkJRVU03VlVGREwwTTdPMEZCUlVRc1lVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eHZRa0ZCYjBJc1EwRkJReXhKUVVGSkxFTkJRVU1zVTBGQlV5eERRVUZETEVOQlFVTTdPMEZCUlc1RUxHRkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUMEZCVHl4RFFVRkRMRk5CUVZNc1IwRkJSeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVsQlFVa3NRMEZCUXp0QlFVTnFSQ3hoUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEU5QlFVOHNRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJReXhGUVVGRkxFTkJRVU1zUlVGQlJTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTlCUVU4c1EwRkJReXhMUVVGTExFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4UFFVRlBMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03TzBGQlJURkdMR0ZCUVVrc1NVRkJTU3hEUVVGRExFMUJRVTBzU1VGQlNTeEpRVUZKTEVOQlFVTXNVMEZCVXl4RlFVRkZPenM3TzBGQlNXcERMR1ZCUVVrc1VVRkJVU3hIUVVGSkxFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1IwRkJSeXhKUVVGSkxFTkJRVU1zV1VGQllTeERRVUZETzBGQlF5OUVMR1ZCUVVrc1UwRkJVeXhoUVVGRE8wRkJRMlFzWlVGQlNTeERRVUZETEVkQlFVY3NRMEZCUXl4RFFVRkRPenRCUVVWV0xHVkJRVWtzVlVGQlZTeEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1QwRkJUeXhEUVVGRExFdEJRVXNzUjBGQlF5eEZRVUZGTEVOQlFVTTdPMEZCUlRsRExHZENRVUZMTEVsQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1JVRkJSU3hEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETEZsQlFWa3NSVUZCUlN4RFFVRkRMRWRCUVVjc1EwRkJReXhIUVVGRExGVkJRVlVzUlVGQlJUdEJRVU4yUkN4elFrRkJVeXhIUVVGSExFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNTMEZCU3l4RFFVRkRMRWxCUVVrc1JVRkJSU3hKUVVGSkxFTkJRVU1zVTBGQlV5eERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhIUVVGRExGVkJRVlVzUTBGQlF5eERRVUZETEVOQlFVTTdRVUZETVVVc2MwSkJRVk1zU1VGQlNTeEhRVUZITEVOQlFVTTdRVUZEYWtJc2MwSkJRVk1zU1VGQlNTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTlCUVU4c1EwRkJReXhOUVVGTkxFTkJRVU03TzBGQlJYaERMR2xDUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEU5QlFVOHNRMEZCUXl4VFFVRlRMRWRCUVVjc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eE5RVUZOTEVOQlFVTTdRVUZEYmtRc2FVSkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUMEZCVHl4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRExFVkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4UFFVRlBMRU5CUVVNc1RVRkJUU3hIUVVGRExGTkJRVk1zUlVGQlF5eFJRVUZSTEVkQlFVTXNWVUZCVlN4RlFVRkRMRk5CUVZNc1EwRkJReXhEUVVGRE96dEJRVVZ1Unl4alFVRkRMRWxCUVVzc1VVRkJVU3hIUVVGRExGVkJRVmNzUTBGQlF6dFpRVU0xUWp0VlFVTkdPMUZCUTBZN08wRkJVVVFzV1VGQlR6czdPenM3T3pzN08yTkJRVUVzYVVKQlFVTXNTVUZCU1N4RlFVRkZPMEZCUTFvc1lVRkJTU3hKUVVGSkxFTkJRVU1zVFVGQlRTeEZRVUZGTzBGQlEyWXNaVUZCU1N4RFFVRkRMRlZCUVZVc1JVRkJSU3hEUVVGRE8xVkJRMjVDTzBGQlEwUXNZVUZCU1N4RFFVRkRMRTFCUVUwc1IwRkJSeXhKUVVGSkxFTkJRVU03UVVGRGJrSXNZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhQUVVGUExFTkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRPMEZCUTI1RExHRkJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXp0UlFVTm1PenRCUVV0RUxHVkJRVlU3T3pzN096dGpRVUZCTEhOQ1FVRkhPMEZCUTFnc1lVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eFZRVUZWTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRE8wRkJRM1JETEdGQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1NVRkJTU3hEUVVGRE8xRkJRM0JDT3p0QlFVVkVMRlZCUVVzN1kwRkJRU3hwUWtGQlJ6dEJRVU5PTEdGQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1EwRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETzBGQlF6TkNMR0ZCUVVrc1EwRkJReXhOUVVGTkxFVkJRVVVzUTBGQlF6dFJRVU5tT3p0QlFVVkVMR3RDUVVGaE8yTkJRVUVzZVVKQlFVYzdRVUZEWkN4aFFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFdEJRVXNzUTBGQlF6dFJRVU55UWpzN096dFZRWGhIYTBJc1YwRkJWenRKUVVGVExGTkJRVk03TzJ0Q1FVRTNRaXhYUVVGWExFTTdPenM3T3p0QlF6ZENhRU1zWVVGQldTeERRVUZET3pzN096czdPenM3TzBGQlJXSXNTMEZCU1N4SFFVRkhMRWRCUVVjc2JVSkJRVThzUTBGQlF5eERRVUZoTEVOQlFVTXNRMEZCUXp0QlFVTnFReXhMUVVGSkxFbEJRVWtzUjBGQlJ5eHRRa0ZCVHl4RFFVRkRMRU5CUVdNc1EwRkJReXhEUVVGRE8wRkJRMjVETEV0QlFVa3NVMEZCVXl4SFFVRkhMRzFDUVVGUExFTkJRVU1zUTBGQmJVSXNRMEZCUXl4RFFVRkRPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3p0TFFYZENjRU1zVDBGQlR5eDFRa0ZCVVN4RFFVRlRMRVZCUVhoQ0xFOUJRVTg3TzB0QlJVc3NTMEZCU3p0QlFVVmlMRmxCUmxFc1MwRkJTeXhIUVVWV096SkNRVVpMTEV0QlFVczdPMEZCU1hSQ0xGTkJRVWtzVDBGQlR5eEhRVUZITEVOQlFVTXNUMEZCVHl4RlFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRE96dEJRVVZvUXl4VFFVRkpMRkZCUVZFc1IwRkJSenRCUVVOaUxHRkJRVkVzUTBGQlF5eEZRVUZGTEVWQlFVTXNSMEZCUnl4RFFVRkRPMDFCUTJwQ0xFTkJRVU03TzBGQlJVWXNaME5CVm1sQ0xFdEJRVXNzTmtOQlZXaENMRk5CUVZNc1JVRkJReXhQUVVGUExFVkJRVU1zVVVGQlVTeEZRVUZGT3p0QlFVVnNReXhUUVVGSkxFTkJRVU1zVDBGQlR5eEhRVUZITEU5QlFVOHNSVUZCUlN4RFFVRkRPenRCUVVWNlFpeFRRVUZKTEVOQlFVTXNVVUZCVVN4SFFVRkhMRU5CUVVNc1EwRkJRenM3UVVGRmJFSXNVMEZCU1N4RFFVRkRMRkZCUVZFc1IwRkJSeXhKUVVGSkxFTkJRVU1zVDBGQlR5eERRVUZETEhGQ1FVRnhRaXhEUVVGRkxFbEJRVWtzUTBGQlF5eFJRVUZSTEVOQlFVVXNRMEZCUXpzN1FVRkZjRVVzVTBGQlNTeERRVUZETEZOQlFWTXNSMEZCUnl4RlFVRkZMRU5CUVVNN08wRkJSWEJDTEZWQlFVc3NTVUZCU1N4RFFVRkRMRWRCUVVNc1EwRkJReXhGUVVGRkxFTkJRVU1zUjBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RlFVRkZMRU5CUVVNc1JVRkJSU3hGUVVGRk8wRkJRMnhETEZkQlFVa3NVVUZCVVN4SFFVRkhMRWxCUVVrc1EwRkJReXhQUVVGUExFTkJRVU1zWTBGQll5eEZRVUZGTEVOQlFVTTdRVUZETjBNc1YwRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eFBRVUZQTEVOQlFVTXNVVUZCVVN4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRMnhETEdWQlFWRXNRMEZCUXl4UFFVRlBMRWRCUVVjc1NVRkJTU3hEUVVGRE8wRkJRM2hDTEdWQlFWRXNRMEZCUXl4eFFrRkJjVUlzUjBGQlJ5eERRVUZETEVOQlFVTTdRVUZEYmtNc1YwRkJTU3hEUVVGRExGTkJRVk1zUTBGQlF5eEpRVUZKTEVOQlFVVXNVVUZCVVN4RFFVRkZMRU5CUVVNN1RVRkRha003UVVGRFJDeFRRVUZKTEVOQlFVTXNXVUZCV1N4SFFVRkhMRWxCUVVrc1EwRkJReXhUUVVGVExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNhVUpCUVdsQ0xFTkJRVU03UVVGRGVFUXNVMEZCU1N4RFFVRkRMRk5CUVZNc1IwRkJSeXhKUVVGSkxGbEJRVmtzUTBGQlF5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RFFVRkRMRU5CUVVNN096czdPenM3T3pzN096czdRVUZoY2tRc1UwRkJTU3hEUVVGRExFMUJRVTBzUjBGQlJ5eEpRVUZKTEVOQlFVTTdPMEZCUlc1Q0xGTkJRVWtzUTBGQlF5eEZRVUZGTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNN08wRkJSWEJDTEZOQlFVa3NRMEZCUXl4SlFVRkpMRVZCUVVVc1EwRkJRenM3UVVGRldpeFRRVUZKTEVOQlFVTXNWVUZCVlN4SFFVRkhMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVDBGQlR5eERRVUZETEV0QlFVc3NSMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRE96dEJRVVV4UkN4VFFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRkxFTkJRVU03U1VGRlpqczdZVUZ1Ukd0Q0xFdEJRVXM3TzJkQ1FVRk1MRXRCUVVzN1FVRnhSSGhDTEdWQlFWVTdZMEZCUVN4elFrRkJSenRCUVVOWUxHRkJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVY3NTVUZCU1N4SFFVRkhMRU5CUVVNc1YwRkJWeXhEUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0QlFVTXZReXhoUVVGSkxFTkJRVU1zVDBGQlR5eEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1QwRkJUeXhEUVVGRE8xRkJRM0JET3p0QlFVVkVMR3RDUVVGaE8yTkJRVUVzZVVKQlFVYzdRVUZEWkN4aFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFMUJRVTBzUTBGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RlFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dFJRVU0xUXpzN1FVRkZSQ3h0UWtGQll6dGpRVUZCTERCQ1FVRkhPMEZCUTJZc1lVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eFBRVUZQTEVOQlFVTXNTMEZCU3l4RFFVRkRMR1ZCUVdVc1IwRkJSeXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVsQlFVa3NRMEZCUXp0UlFVTTVSRHM3UVVGRlJDeFhRVUZOTzJOQlFVRXNhMEpCUVVjN08wRkJSVkFzWVVGQlNTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZPMEZCUTJZc1owTkJRWEZDTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEVOQlFVTXNRMEZCUXp0VlFVTXZRenM3UVVGRlJDeGhRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTlCUVU4c1EwRkJReXhUUVVGVExFZEJRVWNzU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SlFVRkpMRU5CUVVNN1FVRkRha1FzWVVGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4UFFVRlBMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU1zUlVGQlJTeERRVUZETEVWQlFVVXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhQUVVGUExFTkJRVU1zUzBGQlN5eEZRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1QwRkJUeXhEUVVGRExFMUJRVTBzUTBGQlF5eERRVUZET3p0QlFVVXpSaXhqUVVGTExFbEJRVWtzUTBGQlF5eEhRVUZETEVOQlFVTXNSVUZCUXl4RFFVRkRMRWRCUVVNc1NVRkJTU3hEUVVGRExGTkJRVk1zUTBGQlF5eE5RVUZOTEVWQlFVTXNRMEZCUXl4RlFVRkZMRVZCUVVVN08wRkJSWGhETEdWQlFVa3NTVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSVHM3UVVGRlppeHBRa0ZCU1N4RFFVRkRMRk5CUVZNc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eHpRa0ZCYzBJc1EwRkJReXhKUVVGSkxFTkJRVU1zVTBGQlV5eERRVUZETEVOQlFVTTdPMEZCUlhwRUxHbENRVUZKTEVkQlFVY3NSMEZCUnl4RFFVRkRMRU5CUVVNN08wRkJSVm9zYTBKQlFVc3NTVUZCU1N4RlFVRkRMRWRCUVVjc1EwRkJReXhGUVVGRkxFVkJRVU1zUjBGQlJ5eEpRVUZKTEVOQlFVTXNVMEZCVXl4RFFVRkRMRTFCUVUwc1JVRkJSU3hGUVVGRExFVkJRVVVzUlVGQlF6dEJRVU14UXl4clFrRkJSeXhKUVVGTExFbEJRVWtzUTBGQlF5eFRRVUZUTEVOQlFVTXNSVUZCUXl4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRExGTkJRVk1zUTBGQlF5eEZRVUZETEVOQlFVVXNRMEZCUXp0alFVTnVSRHM3UVVGRlJDeG5Ra0ZCUnl4SFFVRkhMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUjBGQlJ5eEhRVUZITEVsQlFVa3NRMEZCUXl4VFFVRlRMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03TzBGQlJUZERMR2xDUVVGSkxFTkJRVU1zUlVGQlJTeEhRVUZITEVWQlFVVXNSMEZCUnl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFZEJRVWNzUTBGQlF5eERRVUZETzFsQlJXaERMRTFCUVUwc1NVRkJTU3hKUVVGSkxFTkJRVU1zUlVGQlJTeEhRVUZITEVOQlFVTXNSMEZCUnl4SlFVRkpMRWxCUVVrc1EwRkJReXhGUVVGRkxFdEJRVXNzUTBGQlF5eFJRVUZSTEVWQlFVVTdRVUZEYkVRc2FVSkJRVWtzUTBGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4RFFVRkRPMWxCUTJRc1RVRkJUVHRCUVVOTUxHbENRVUZKTEVOQlFVTXNSVUZCUlN4SFFVRkhMRU5CUVVNc1VVRkJVU3hEUVVGRE8xbEJRM0pDT3pzN08wRkJTMFFzWlVGQlNTeEpRVUZKTEVOQlFVTXNSVUZCUlN4SFFVRkhMRU5CUVVNc1JVRkJSU3hGUVVGRk96dEJRVVZxUWl4cFFrRkJTU3hOUVVGTkxFZEJRVWNzU1VGQlNTeERRVUZETEZOQlFWTXNRMEZCUXl4SlFVRkpMRU5CUVVNc1JVRkJSU3hGUVVGRExFTkJRVU1zUlVGQlJTeEZRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMEZCUXpORExHbENRVUZKTEVkQlFVY3NSMEZCUnl4TlFVRk5MRWRCUVVjc1RVRkJUU3hEUVVGRE8wRkJRekZDTEdsQ1FVRkpMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEVkQlFVY3NSVUZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhGUVVGRExFbEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNUVUZCVFN4RlFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE96dEJRVVZzUkN4cFFrRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eFBRVUZQTEVOQlFVTXNVMEZCVXl4SFFVRkhMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVFVGQlRTeERRVUZETzBGQlEyNUVMR2xDUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEU5QlFVOHNRMEZCUXl4UlFVRlJMRU5CUVVNc1NVRkJTU3hEUVVGRExGVkJRVlVzUjBGQlF5eERRVUZETEVWQlFVTXNRMEZCUXl4RlFVRkRMRWxCUVVrc1EwRkJReXhWUVVGVkxFVkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4UFFVRlBMRU5CUVVNc1RVRkJUU3hIUVVGSExFTkJRVU1zUTBGQlF5eERRVUZET3pzN1dVRkpiRWM3VlVGRlJqdFJRVVZHT3p0QlFWVkVMRmxCUVU4N096czdPenM3T3pzN1kwRkJRU3hwUWtGQlF5eEpRVUZKTEVWQlFVTXNVVUZCVVN4RlFVRkZPMEZCUTNKQ0xHRkJRVWtzU1VGQlNTeERRVUZETEUxQlFVMHNSVUZCUlR0QlFVTm1MR1ZCUVVrc1EwRkJReXhWUVVGVkxFVkJRVVVzUTBGQlF6dFZRVU51UWpzN08wRkJSMFFzWVVGQlNTeFJRVUZSTEVWQlFVVTdRVUZEV2l4bFFVRkpMRU5CUVVNc1VVRkJVU3hIUVVGSExGRkJRVkVzUTBGQlF6dFZRVU14UWl4TlFVRk5MRWxCUVVrc1NVRkJTU3hEUVVGRExGbEJRVmtzUlVGQlJUdEJRVU0xUWl4bFFVRkpMRU5CUVVNc1VVRkJVU3hIUVVGSExFbEJRVWtzUTBGQlF5eFpRVUZaTEVOQlFVTTdWVUZEYmtNc1RVRkJUVHRCUVVOTUxHVkJRVWtzUTBGQlF5eFJRVUZSTEVkQlFVY3NRMEZCUXl4RFFVRkRPMVZCUTI1Q08wRkJRMFFzWVVGQlNTeERRVUZETEZWQlFWVXNSMEZCUnl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFOUJRVThzUTBGQlF5eExRVUZMTEVkQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJRenM3UVVGRk1VUXNZVUZCU1N4RFFVRkRMRTFCUVUwc1IwRkJSeXhKUVVGSkxFTkJRVU03UVVGRGJrSXNZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhQUVVGUExFTkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRPenM3VVVGSGNFTTdPMEZCUzBRc1pVRkJWVHM3T3pzN08yTkJRVUVzYzBKQlFVYzdPMEZCUlZnc1lVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eFZRVUZWTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRE8wRkJRM1JETEdGQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1MwRkJTeXhEUVVGRE96dEJRVVZ3UWl4aFFVRkpMRU5CUVVNc1ZVRkJWU3hIUVVGSExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1IwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETzFGQlJUTkVPenRCUVVWRUxGVkJRVXM3WTBGQlFTeHBRa0ZCUnp0QlFVTk9MR0ZCUVVrc1EwRkJReXhOUVVGTkxFZEJRVWNzUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRPMEZCUXpOQ0xHRkJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXp0UlFVTm1PenRCUVVWRUxHdENRVUZoTzJOQlFVRXNlVUpCUVVjN1FVRkRaQ3hoUVVGSkxFTkJRVU1zVFVGQlRTeEhRVUZITEV0QlFVc3NRMEZCUXp0UlFVTnlRanM3T3p0VlFYSkxhMElzUzBGQlN6dEpRVUZUTEZOQlFWTTdPMnRDUVVGMlFpeExRVUZMTEVNN096czdPenRCUXpsQ01VSXNZVUZCV1N4RFFVRkRPenM3T3pzN096czdPMEZCUldJc1MwRkJTU3hIUVVGSExFZEJRVWNzYlVKQlFVOHNRMEZCUXl4RFFVRmhMRU5CUVVNc1EwRkJRenRCUVVOcVF5eExRVUZKTEZOQlFWTXNSMEZCUnl4dFFrRkJUeXhEUVVGRExFTkJRVzFDTEVOQlFVTXNRMEZCUXpzN096czdPenM3T3pzN096czdPenM3T3pzN096czdTMEYxUW5CRExFOUJRVThzZFVKQlFWRXNRMEZCVXl4RlFVRjRRaXhQUVVGUE96dExRVVZMTEZsQlFWazdRVUZGY0VJc1dVRkdVU3haUVVGWkxFZEJSV3BDT3pKQ1FVWkxMRmxCUVZrN08wRkJTVGRDTEZOQlFVa3NUMEZCVHl4SFFVRkhMRU5CUVVNc1QwRkJUeXhGUVVGRExFOUJRVThzUTBGQlF5eERRVUZET3p0QlFVVm9ReXhUUVVGSkxGRkJRVkVzUjBGQlJ6dEJRVU5pTEdGQlFWRXNRMEZCUXl4SFFVRkhMRVZCUVVNc1IwRkJSeXhEUVVGRE8wMUJRMnhDTEVOQlFVTTdPMEZCUlVZc1owTkJWbWxDTEZsQlFWa3NOa05CVlhaQ0xGTkJRVk1zUlVGQlF5eFBRVUZQTEVWQlFVTXNVVUZCVVN4RlFVRkZPenRCUVVWc1F5eFRRVUZKTEVOQlFVTXNUMEZCVHl4SFFVRkhMRTlCUVU4c1JVRkJSU3hEUVVGRE96dEJRVVY2UWl4VFFVRkpMRU5CUVVNc1VVRkJVU3hIUVVGSExFbEJRVWtzUTBGQlF5eFBRVUZQTEVOQlFVTXNZMEZCWXl4RlFVRkZMRU5CUVVNN1FVRkRPVU1zVTBGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4UFFVRlBMRWRCUVVjc1NVRkJTU3hEUVVGRE8wRkJRemRDTEZOQlFVa3NRMEZCUXl4WlFVRlpMRWRCUVVjc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eHBRa0ZCYVVJc1EwRkJRenRCUVVOd1JDeFRRVUZKTEVOQlFVTXNVMEZCVXl4SFFVRkhMRWxCUVVrc1ZVRkJWU3hEUVVGRExFbEJRVWtzUTBGQlF5eFpRVUZaTEVOQlFVTXNRMEZCUXp0QlFVTnVSQ3hUUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEhGQ1FVRnhRaXhEUVVGRExFbEJRVWtzUTBGQlF5eFRRVUZUTEVOQlFVTXNRMEZCUXpzN1FVRkZjRVFzVTBGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4SlFVRkpMRU5CUVVNN08wRkJSVzVDTEZOQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1MwRkJTeXhEUVVGRE96dEJRVVZ3UWl4VFFVRkpMRU5CUVVNc1NVRkJTU3hGUVVGRkxFTkJRVU03TzBGQlJWb3NVMEZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE8wbEJRMlk3TzJGQk0wSnJRaXhaUVVGWk96dG5Ra0ZCV2l4WlFVRlpPMEZCTmtJdlFpeGxRVUZWTzJOQlFVRXNjMEpCUVVjN1FVRkRXQ3hoUVVGSkxFTkJRVU1zVFVGQlRTeEhRVUZITEVsQlFVa3NSMEZCUnl4RFFVRkRMRmRCUVZjc1EwRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdRVUZETDBNc1lVRkJTU3hEUVVGRExFOUJRVThzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTlCUVU4c1EwRkJRenRSUVVOd1F6czdRVUZGUkN4clFrRkJZVHRqUVVGQkxIbENRVUZITzBGQlEyUXNZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhOUVVGTkxFTkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NSVUZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03VVVGRE5VTTdPMEZCUlVRc2JVSkJRV003WTBGQlFTd3dRa0ZCUnp0QlFVTm1MR0ZCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVDBGQlR5eERRVUZETEV0QlFVc3NRMEZCUXl4bFFVRmxMRWRCUVVjc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eEpRVUZKTEVOQlFVTTdVVUZET1VRN08wRkJSVVFzVjBGQlRUdGpRVUZCTEd0Q1FVRkhPenRCUVVWUUxHRkJRVWtzU1VGQlNTeERRVUZETEUxQlFVMHNSVUZCUlR0QlFVTm1MR2REUVVGeFFpeERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eERRVUZETEVOQlFVTTdWVUZETDBNN08wRkJSVVFzWVVGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4eFFrRkJjVUlzUTBGQlF5eEpRVUZKTEVOQlFVTXNVMEZCVXl4RFFVRkRMRU5CUVVNN08wRkJSWEJFTEdGQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1QwRkJUeXhEUVVGRExGTkJRVk1zUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1EwRkJRenRCUVVOcVJDeGhRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTlCUVU4c1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF5eEZRVUZGTEVOQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFOUJRVThzUTBGQlF5eExRVUZMTEVWQlFVVXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhQUVVGUExFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTTdPMEZCUlRGR0xHRkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUMEZCVHl4RFFVRkRMRk5CUVZNc1IwRkJSeXhGUVVGRExFVkJRVVVzU1VGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4SFFVRkhMRWRCUVVjc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRE1VUXNZVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhQUVVGUExFTkJRVU1zVjBGQlZ5eEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1RVRkJUU3hEUVVGRE96dEJRVVZ5UkN4aFFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFOUJRVThzUTBGQlF5eFRRVUZUTEVWQlFVVXNRMEZCUXpzN1FVRkZhRU1zWVVGQlNTeEpRVUZKTEVOQlFVTXNUVUZCVFN4RlFVRkZPenRCUVVWbUxHVkJRVWtzVlVGQlZTeEhRVUZITEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1QwRkJUeXhEUVVGRExFdEJRVXNzUjBGQlJ5eERRVUZITEVkQlFVY3NTVUZCU1N4RFFVRkRMRmxCUVZrc1EwRkJRenRCUVVOeVJTeGxRVUZKTEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNN08wRkJSVllzWjBKQlFVc3NTVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhGUVVGRkxFTkJRVU1zUjBGQlJ5eEpRVUZKTEVOQlFVTXNXVUZCV1N4RlFVRkZMRU5CUVVNc1JVRkJSU3hGUVVGRk96dEJRVVV4UXl4cFFrRkJTU3hEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETEZOQlFWTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1IwRkJSeXhIUVVGTExFTkJRVU03UVVGRGJFTXNhVUpCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTlCUVU4c1EwRkJReXhOUVVGTkxFZEJRVWNzUTBGQlF5eERRVUZET3p0QlFVVXpReXhwUWtGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4RlFVRkZPMEZCUTFnc2JVSkJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUMEZCVHl4RFFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRExFVkJRVVVzUTBGQlF5eERRVUZETEVOQlFVTTdZMEZEYkVNc1RVRkJUVHRCUVVOTUxHMUNRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTlCUVU4c1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF5eEZRVUZGTEVOQlFVTXNRMEZCUXl4RFFVRkRPMk5CUTJ4RE96dEJRVVZFTEdOQlFVTXNTVUZCU1N4VlFVRlZMRU5CUVVNN1dVRkRha0k3VlVGRFJpeE5RVUZOTzBGQlEwZ3NaVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhQUVVGUExFTkJRVU1zVFVGQlRTeERRVUZETEVOQlFVTXNSVUZCUlN4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFOUJRVThzUTBGQlF5eE5RVUZOTEVkQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkROVVFzWlVGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4UFFVRlBMRU5CUVVNc1RVRkJUU3hEUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNUMEZCVHl4RFFVRkRMRXRCUVVzc1JVRkJSU3hKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEU5QlFVOHNRMEZCUXl4TlFVRk5MRWRCUVVNc1EwRkJReXhEUVVGRExFTkJRVU03VlVGRGRrWTdPMEZCUlVRc1lVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eFBRVUZQTEVOQlFVTXNUVUZCVFN4RlFVRkZMRU5CUVVNN1VVRkRPVUk3TzBGQlUwUXNXVUZCVHpzN096czdPenM3TzJOQlFVRXNhVUpCUVVNc1NVRkJTU3hGUVVGRk96dEJRVVZhTEdGQlFVa3NTVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSVHRCUVVObUxHVkJRVWtzUTBGQlF5eFZRVUZWTEVWQlFVVXNRMEZCUXp0VlFVTnVRanM3UVVGRlJDeGhRVUZKTEVOQlFVTXNUVUZCVFN4SFFVRkhMRWxCUVVrc1EwRkJRenRCUVVOdVFpeGhRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTlCUVU4c1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTTdPMEZCUlc1RExHRkJRVWtzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXp0UlFVTm1PenRCUVV0RUxHVkJRVlU3T3pzN096dGpRVUZCTEhOQ1FVRkhPMEZCUTFnc1lVRkJTU3hKUVVGSkxFTkJRVU1zVFVGQlRTeEZRVUZGTzBGQlEyWXNaVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhWUVVGVkxFTkJRVU1zU1VGQlNTeERRVUZETEZGQlFWRXNRMEZCUXl4RFFVRkRPMEZCUTNSRExHVkJRVWtzUTBGQlF5eE5RVUZOTEVkQlFVY3NTVUZCU1N4RFFVRkRPMVZCUTNCQ08xRkJSVVk3TzBGQlJVUXNWVUZCU3p0alFVRkJMR2xDUVVGSE8wRkJRMDRzWVVGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4RFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU03UVVGRE0wSXNZVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hEUVVGRE8xRkJRMlk3TzBGQlJVUXNhMEpCUVdFN1kwRkJRU3g1UWtGQlJ6dEJRVU5rTEdGQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1MwRkJTeXhEUVVGRE8xRkJRM0pDT3pzN08xVkJla2hyUWl4WlFVRlpPMGxCUVZNc1UwRkJVenM3YTBKQlFUbENMRmxCUVZrc1F6czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN08wdERWWEpDTEZOQlFWTXNLME5CUVUwc1JVRkJiVUk3TzB0QlEzWkRMRWRCUVVjc2RVTkJRVTBzUTBGQllUczdTMEZGY0VJc1RVRkJUU3gxUWtGQlVTeERRVUZUTEVWQlFYWkNMRTFCUVUwN08wdEJSVTBzU1VGQlNUdEJRVVZhTEZsQlJsRXNTVUZCU1N4RFFVVllMRTFCUVUwc1JVRkJSU3hSUVVGUkxFVkJRVVU3TWtKQlJsZ3NTVUZCU1RzN1FVRkpja0lzVTBGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4RlFVRkZMRU5CUVVNN1FVRkRaaXhUUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4TlFVRk5MRU5CUVVNN1FVRkRNVUlzVTBGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRWRCUVVjc1IwRkJSeXhEUVVGRExGbEJRVmtzUTBGQlF5eE5RVUZOTEVOQlFVTXNRMEZCUXp0QlFVTTFReXhUUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4RlFVRkZMRU5CUVVNN08wRkJSWFJDTEZOQlFVa3NVVUZCVVN4RlFVRkZPMEZCUTFvc1YwRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eFRRVUZUTEVkQlFVY3NVVUZCVVN4RFFVRkRMRk5CUVZNc1NVRkJTU3hWUVVGVkxFTkJRVU03UVVGRGRrUXNWMEZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFZEJRVWNzVVVGQlVTeERRVUZETEVsQlFVa3NTVUZCU1N4TFFVRkxMRU5CUVVNN1FVRkRla01zVjBGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4SlFVRkpMRWRCUVVjc1VVRkJVU3hEUVVGRExFbEJRVWtzU1VGQlNTeExRVUZMTEVOQlFVTTdUVUZEZWtNc1RVRkJUVHRCUVVOTUxGZEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNVMEZCVXl4SFFVRkhMRlZCUVZVc1EwRkJRenRCUVVOcVF5eFhRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1IwRkJSeXhMUVVGTExFTkJRVU03UVVGRGVFSXNWMEZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFZEJRVWNzUzBGQlN5eERRVUZETzAxQlEzaENPenRCUVVWRUxGTkJRVWtzWVVGQllTeEhRVUZITEUxQlFVMHNSVUZCUlN4RFFVRkRPMEZCUXpkQ0xGTkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRTFCUVUwc1IwRkJSeXhoUVVGaExFTkJRVU1zVFVGQlRTeERRVUZETzBGQlF5OURMRk5CUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEVsQlFVa3NSMEZCUnl4aFFVRmhMRU5CUVVNc1NVRkJTU3hEUVVGRE8wRkJRek5ETEZOQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFdEJRVXNzUjBGQlJ5eGhRVUZoTEVOQlFVTXNTMEZCU3l4RFFVRkRPMEZCUXpkRExGTkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1IwRkJSeXhoUVVGaExFTkJRVU1zU1VGQlNTeERRVUZETzBGQlF6TkRMRk5CUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEZkQlFWY3NSMEZCUnl4aFFVRmhMRU5CUVVNc1YwRkJWeXhEUVVGRE8wRkJRM3BFTEZOQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExGVkJRVlVzUjBGQlJ5eGhRVUZoTEVOQlFVTXNWVUZCVlN4RFFVRkRPMEZCUTNaRUxGTkJRVWtzUTBGQlF5eGpRVUZqTEVWQlFVVXNRMEZCUXp0QlFVTjBRaXhUUVVGSkxFTkJRVU1zWTBGQll5eEZRVUZGTEVOQlFVTTdTVUZEZGtJN08yZENRVFZDYTBJc1NVRkJTVHRCUVRoQ2RrSXNiVUpCUVdNN1kwRkJRU3d3UWtGQlJ6czdPMEZCUTJZc1lVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTMEZCU3l4RFFVRkRMRk5CUVZNc1IwRkJSeXhaUVVGWkxFTkJRVU03UVVGRGFFUXNZVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUzBGQlN5eERRVUZETEZWQlFWVXNSMEZCUnl4TlFVRk5MRU5CUVVNN1FVRkRNME1zWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1MwRkJTeXhEUVVGRExHRkJRV0VzUjBGQlJ5eE5RVUZOTEVOQlFVTTdRVUZET1VNc1lVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTMEZCU3l4RFFVRkRMR2RDUVVGblFpeEhRVUZITEUxQlFVMHNRMEZCUXpzN1FVRkZha1FzWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRWRCUVVjc1VVRkJVU3hEUVVGRExHRkJRV0VzUTBGQlF5eExRVUZMTEVOQlFVTXNRMEZCUXpzN1FVRkZia1FzWjBKQlFVOHNTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVlVGQlZTeERRVUZETEUxQlFVMHNSMEZCUnl4RFFVRkRMRVZCUVVVN1FVRkRNME1zWlVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1YwRkJWeXhEUVVGRExFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRlZCUVZVc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzFWQlEyeEZPenRCUVVWRUxHRkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRXRCUVVzc1EwRkJReXhQUVVGUExFZEJRVWNzUzBGQlN5eERRVUZETzBGQlEzcERMR0ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEV0QlFVc3NRMEZCUXl4VFFVRlRMRWRCUVVjc1dVRkJXU3hEUVVGRE96dEJRVVZzUkN4aFFVRkpMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eEZRVUZGTzBGQlEyNUNMR1ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeEhRVUZITEZGQlFWRXNRMEZCUXl4aFFVRmhMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU03UVVGRGJrUXNaVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zVTBGQlV5eEhRVUZITEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRE8wRkJReTlETEdWQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUTBGQlF5eFZRVUZWTEVkQlFVY3NUMEZCVHl4RFFVRkRPMEZCUXpsRExHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRXRCUVVzc1EwRkJReXhSUVVGUkxFZEJRVWNzVlVGQlZTeERRVUZETzBGQlF5OURMR1ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEV0QlFVc3NRMEZCUXl4TFFVRkxMRWRCUVVjc1RVRkJUU3hEUVVGRE8wRkJRM2hETEdWQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFdEJRVXNzUTBGQlF5eFBRVUZQTEVkQlFVY3NTMEZCU3l4RFFVRkRPMEZCUTNwRExHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRXRCUVVzc1EwRkJReXhSUVVGUkxFZEJRVWNzVFVGQlRTeERRVUZET3p0QlFVVXpReXhsUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNSMEZCUnl4UlFVRlJMRU5CUVVNc1lVRkJZU3hEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzBGQlEycEVMR1ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEV0QlFVc3NRMEZCUXl4UlFVRlJMRWRCUVVjc1ZVRkJWU3hEUVVGRE8wRkJRemRETEdWQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFdEJRVXNzUTBGQlF5eEhRVUZITEVkQlFVY3NTMEZCU3l4RFFVRkZPMEZCUTNCRExHVkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRXRCUVVzc1EwRkJReXhMUVVGTExFZEJRVWNzUzBGQlN5eERRVUZGTzBGQlEzUkRMR1ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVFVGQlRTeERRVUZETEZOQlFWTXNSMEZCUnl4SFFVRkhMRU5CUVVNN1FVRkRha01zWlVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1MwRkJTeXhEUVVGRExFOUJRVThzUjBGQlJ5eGhRVUZoTEVOQlFVTTdRVUZETDBNc1pVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTMEZCU3l4RFFVRkRMRlZCUVZVc1IwRkJSeXhOUVVGTkxFTkJRVU03UVVGRE0wTXNaVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUzBGQlN5eERRVUZETEZGQlFWRXNSMEZCUnl4TlFVRk5MRU5CUVVNN08wRkJSWHBETEdWQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFdEJRVXNzUTBGQlF5eE5RVUZOTEVkQlFVY3NVMEZCVXl4RFFVRkRPenRCUVVVeFF5eGxRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhuUWtGQlowSXNRMEZCUXl4WFFVRlhMRVZCUVVVc1dVRkJUVHRCUVVOdVJDeHRRa0ZCU3l4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFdEJRVXNzUTBGQlF5eGxRVUZsTEVkQlFVY3NUVUZCU3l4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExGVkJRVlVzUTBGQlF6dFpRVU4wUlN4RFFVRkRMRU5CUVVNN1FVRkRTQ3hsUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4blFrRkJaMElzUTBGQlF5eFpRVUZaTEVWQlFVVXNXVUZCVFR0QlFVTndSQ3h0UWtGQlN5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRXRCUVVzc1EwRkJReXhsUVVGbExFZEJRVWNzVFVGQlN5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRmRCUVZjc1EwRkJRenRaUVVOMlJTeERRVUZETEVOQlFVTTdRVUZEU0N4bFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eG5Ra0ZCWjBJc1EwRkJReXhQUVVGUExFVkJRVVVzV1VGQlRUdEJRVU12UXl4cFFrRkJTU3hOUVVGTExFbEJRVWtzUTBGQlF5eEpRVUZKTEVWQlFVVTdRVUZEYkVJc2NVSkJRVXNzU1VGQlNTeEZRVUZGTEVOQlFVTTdZMEZEWWl4TlFVRk5PMEZCUTB3c2NVSkJRVXNzU1VGQlNTeEZRVUZGTEVOQlFVTTdZMEZEWWp0WlFVTkdMRU5CUVVNc1EwRkJRenM3UVVGSFNDeGxRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRkZCUVZFc1EwRkJReXhYUVVGWExFTkJRVU1zU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenM3UVVGRmFrUXNaVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zVjBGQlZ5eERRVUZETEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU03VlVGRGJFUTdRVUZEUkN4aFFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eFhRVUZYTEVOQlFVTXNTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhSUVVGUkxFTkJRVU1zUTBGQlF6czdPenM3UVVGTGFrUXNZVUZCU1N4RlFVRkZMRWRCUVVjc1UwRkJVeXhEUVVGRExFOUJRVThzUTBGQlF5eEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEZOQlFWTXNRMEZCUXl4RFFVRkRPMEZCUTJ4RkxHTkJRVXNzU1VGQlNTeEhRVUZITEVsQlFVa3NSVUZCUlN4RlFVRkZPMEZCUTJ4Q0xHVkJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNSMEZCUnl4RlFVRkZMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU03VlVGRGNrSTdVVUZEUmpzN1FVRkZSQ3h0UWtGQll6dGpRVUZCTERCQ1FVRkhPMEZCUTJZc1lVRkJTU3hKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEV0QlFVc3NSVUZCUlR0QlFVTnVRaXhsUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4TFFVRkxMRU5CUVVNc1pVRkJaU3hIUVVGSExFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRmRCUVZjc1EwRkJRenRCUVVOMFJTeGxRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1EwRkJReXhMUVVGTExFTkJRVU1zVFVGQlRTeEhRVUZITEZsQlFWa3NSMEZCUXl4SlFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFMUJRVTBzUTBGQlF5eEpRVUZKTEVOQlFVTTdRVUZEYmtVc1pVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTMEZCU3l4RFFVRkRMRTFCUVUwc1IwRkJSeXhaUVVGWkxFZEJRVU1zU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1YwRkJWeXhEUVVGRE8wRkJRekZGTEdWQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1RVRkJUU3hEUVVGRExFdEJRVXNzUTBGQlF5eGxRVUZsTEVkQlFVY3NTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFTkJRVU1zUzBGQlN5eERRVUZETzBGQlEyaEZMR1ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zVVVGQlVTeERRVUZETEV0QlFVc3NRMEZCUXl4bFFVRmxMRWRCUVVjc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eE5RVUZOTEVOQlFVTXNTVUZCU1N4RFFVRkRPMVZCUTJ4Rk8xRkJRMFk3TzBGQlJVUXNVMEZCU1R0alFVRkJMR2RDUVVGSE8wRkJRMHdzWVVGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhEUVVGRExFOUJRVThzUjBGQlJ5eFBRVUZQTEVOQlFVTTdRVUZETTBNc1lVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eEpRVUZKTEVkQlFVY3NTVUZCU1N4RFFVRkRPMUZCUTNaQ096dEJRVVZFTEZOQlFVazdZMEZCUVN4blFrRkJSenRCUVVOTUxHRkJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNVVUZCVVN4RFFVRkRMRXRCUVVzc1EwRkJReXhQUVVGUExFZEJRVWNzVFVGQlRTeERRVUZETzBGQlF6RkRMR0ZCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU1zU1VGQlNTeEhRVUZITEV0QlFVc3NRMEZCUXp0UlFVTjRRanM3UVVGRlJDeGhRVUZSTzJOQlFVRXNhMEpCUVVNc1NVRkJTU3hGUVVGRExFdEJRVXNzUlVGQlJUdEJRVU51UWl4alFVRkxMRWxCUVVrc1IwRkJSeXhKUVVGSkxFbEJRVWtzUlVGQlJUdEJRVU53UWl4bFFVRkpMRWxCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zUTBGQlF5eFJRVUZSTEVWQlFVVTdRVUZEZEVJc2FVSkJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNRMEZCUXl4UlFVRlJMRU5CUVVNc1NVRkJTU3hGUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzFsQlEyaERPMVZCUTBZN1FVRkRSQ3hoUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETEUxQlFVMHNRMEZCUXl4SlFVRkpMRU5CUVVNc1IwRkJSeXhMUVVGTExFTkJRVU03UVVGREwwSXNZVUZCU1N4RFFVRkRMR05CUVdNc1JVRkJSU3hEUVVGRE8xRkJRM1pDT3p0QlFVVkVMRlZCUVVzN1kwRkJRU3hwUWtGQlJ6dEJRVU5PTEdOQlFVc3NTVUZCU1N4SFFVRkhMRWxCUVVrc1NVRkJTU3hGUVVGRk8wRkJRM0JDTEdWQlFVa3NTVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRExFOUJRVThzUlVGQlJUdEJRVU55UWl4cFFrRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eERRVUZETEU5QlFVOHNSVUZCUlN4RFFVRkRPMWxCUTNKQ08xVkJRMFk3VVVGRFJqczdPenRWUVc1SmEwSXNTVUZCU1RzN08ydENRVUZLTEVsQlFVa3NRenM3T3pzN096czdPenM3T3p0QlF6TkRla0lzWVVGQldTeERRVUZET3p0TFFVVk9MRWRCUVVjc2RVTkJRVTBzUTBGQllUczdTMEZEZEVJc1ZVRkJWU3gxUTBGQlRTeERRVUZuUWpzN1FVRkZka01zUzBGQlNTeHBRa0ZCYVVJc1IwRkJSeXhWUVVGRExFMUJRVTBzUlVGQlF5eFpRVUZaTEVWQlFVczdRVUZETDBNc1QwRkJTU3hKUVVGSkxFZEJRVWNzVFVGQlRTeERRVUZETEVsQlFVa3NRMEZCUXp0QlFVTjJRaXhQUVVGSkxGbEJRVmtzUTBGQlF5eEpRVUZKTEVOQlFVTXNSVUZCUlR0QlFVTjBRaXhwUWtGQldTeERRVUZETEVsQlFVa3NRMEZCUXl4RlFVRkZMRU5CUVVNN1NVRkRkRUlzVFVGQlRUdEJRVU5NTEdsQ1FVRlpMRU5CUVVNc1NVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eERRVUZETzBsQlEzaENPMEZCUTBRc1ZVRkJVeXhKUVVGSkxFZEJRVWNzV1VGQldTeERRVUZETEVsQlFVa3NRMEZCUXl4RFFVRkhPMFZCUTNSRExFTkJRVU03TzBGQlJVWXNTMEZCU1N4UFFVRlBMRWRCUVVjc1ZVRkJReXhQUVVGUExFVkJRVU1zU1VGQlNTeEZRVUZETEU5QlFVOHNSVUZCU3p0QlFVTjBReXhWUVVGUExFZEJRVWNzVDBGQlR5eEpRVUZKTEVWQlFVVXNRMEZCUXp0QlFVTjRRaXhSUVVGTExFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNSVUZCUlN4RFFVRkRMRWRCUVVjc1QwRkJUeXhEUVVGRExGVkJRVlVzUTBGQlF5eE5RVUZOTEVWQlFVVXNRMEZCUXl4RlFVRkZMRVZCUVVNN1FVRkRha1FzVTBGQlNTeEhRVUZITEVkQlFVY3NUMEZCVHl4RFFVRkRMRlZCUVZVc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6czdPenRCUVVrNVFpeFpRVUZQTEVOQlFVTXNSMEZCUnl4RFFVRkRMRkZCUVZFc1EwRkJReXhIUVVGSExFZEJRVWNzUTBGQlF5eFRRVUZUTEVOQlFVTTdPMGxCUlhwRE8wRkJRMFFzVDBGQlNTeEhRVUZITEVsQlFVa3NRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhYUVVGWExFVkJRVVVzUjBGQlJ5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRemRETEU5QlFVa3NUVUZCVFN4SFFVRkhMRWxCUVVrc1ZVRkJWU3hEUVVGRExFbEJRVWtzUTBGQlF5eERRVUZETEU5QlFVOHNSVUZCUXl4UFFVRlBMRU5CUVVNc1EwRkJRenRCUVVOdVJDeFRRVUZOTEVOQlFVTXNSVUZCUlN4SFFVRkhMRTlCUVU4c1EwRkJReXhGUVVGRkxFTkJRVU03UVVGRGRrSXNWVUZCVHl4TlFVRk5MRU5CUVVNN1JVRkRaaXhEUVVGRE96dEJRVWRHTEV0QlFVa3NUMEZCVHl4SFFVRkhMRlZCUVVNc1RVRkJUU3hGUVVGRExFOUJRVThzUlVGQlN6czdRVUZGYUVNc1ZVRkJUeXhIUVVGSExFOUJRVThzU1VGQlNTeFZRVUZWTEVOQlFVTTdPMEZCUldoRExFOUJRVWtzV1VGQldTeEhRVUZITEVWQlFVVXNRMEZCUXpzN1FVRkZkRUlzVDBGQlNTeFRRVUZUTEVkQlFVY3NSMEZCUnl4RFFVRkRMRmxCUVZrc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6czdRVUZGZWtNc1QwRkJTU3hGUVVGRkxFZEJRVWNzUlVGQlJTeERRVUZET3p0QlFVVmFMRTlCUVVrc1dVRkJXU3hIUVVGSExGTkJRVk1zUTBGQlF5eHZRa0ZCYjBJc1EwRkJReXhIUVVGSExFTkJRVU1zUTBGQlF6dEJRVU4yUkN4UFFVRkpMRkZCUVZFc1IwRkJSeXhGUVVGRkxFTkJRVU03UVVGRGJFSXNVVUZCU3l4SlFVRkpMRU5CUVVNc1IwRkJReXhEUVVGRExFVkJRVVVzUTBGQlF5eEhRVUZETEZsQlFWa3NRMEZCUXl4TlFVRk5MRVZCUVVVc1EwRkJReXhGUVVGRkxFVkJRVVU3UVVGRGVFTXNZVUZCVVN4RFFVRkRMRWxCUVVrc1EwRkJReXhaUVVGWkxFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0SlFVTm9RenRCUVVORUxGRkJRVXNzU1VGQlNTeERRVUZETEVkQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1IwRkJReXhSUVVGUkxFTkJRVU1zVFVGQlRTeEZRVUZETEVOQlFVTXNSVUZCUlN4RlFVRkZPMEZCUTJ4RExGTkJRVWtzU1VGQlNTeEhRVUZITEZGQlFWRXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhaUVVGWkxFTkJRVU1zVDBGQlR5eERRVUZETEVOQlFVTTdRVUZETjBNc1UwRkJTU3hKUVVGSkxFVkJRVVU3UVVGRFVpeFhRVUZKTEdGQlFXRXNSMEZCUnl4TFFVRkxMRU5CUVVNN1FVRkRNVUlzV1VGQlN5eEpRVUZKTEVkQlFVY3NTVUZCU1N4VlFVRlZMRVZCUVVVN1FVRkRNVUlzWVVGQlNTeEpRVUZKTEVOQlFVTXNWMEZCVnl4RlFVRkZMRXRCUVVjc1IwRkJSeXhEUVVGRExGZEJRVmNzUlVGQlJTeEZRVUZGTzBGQlF6RkRMSGRDUVVGaExFZEJRVWNzUjBGQlJ5eERRVUZETzFWQlEzSkNPMUZCUTBZN1FVRkRSQ3hqUVVGUExFTkJRVU1zUjBGQlJ5eERRVUZETEdGQlFXRXNRMEZCUXl4RFFVRkRPMEZCUXpOQ0xGZEJRVWtzVFVGQlRTeEhRVUZITEU5QlFVOHNRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJReXhEUVVGRExFVkJRVU1zWVVGQllTeERRVUZETEVOQlFVTTdRVUZEYUVRc1YwRkJTU3hOUVVGTkxFTkJRVU1zUlVGQlJTeEZRVUZGTzBGQlEySXNWMEZCUlN4RFFVRkRMRTFCUVUwc1EwRkJReXhGUVVGRkxFTkJRVU1zUjBGQlJ5eE5RVUZOTEVOQlFVTTdVVUZEZUVJc1RVRkJUVHRCUVVOTUxHRkJRVWtzUlVGQlJTeEhRVUZITEdsQ1FVRnBRaXhEUVVGRExFMUJRVTBzUlVGQlF5eFpRVUZaTEVOQlFVTXNRMEZCUXp0QlFVTm9SQ3hYUVVGRkxFTkJRVU1zUlVGQlJTeERRVUZETEVkQlFVY3NUVUZCVFN4RFFVRkRPMUZCUTJwQ08wMUJRMFk3U1VGRFJqczdRVUZGUkN4VlFVRlBMRVZCUVVVc1EwRkJRenRGUVVWWUxFTkJRVU03TzBGQlJVWXNTMEZCU1N4SFFVRkhMRWRCUVVjc1ZVRkJReXhKUVVGSkxFVkJRVU1zVFVGQlRTeEZRVUZETEU5QlFVOHNSVUZCU3p0QlFVTnFReXhQUVVGSkxFMUJRVTBzUjBGQlJ5eFJRVUZSTEVOQlFVTXNZVUZCWVN4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8wRkJRek5ETEZWQlFVOHNSMEZCUnl4UFFVRlBMRWxCUVVrc1JVRkJSU3hEUVVGRE8wRkJRM2hDTEU5QlFVa3NUVUZCVFN4RlFVRkZPMEZCUTFZc1YwRkJUU3hIUVVGSExFZEJRVWNzUTBGQlF5eFpRVUZaTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN1NVRkRia01zVFVGQlRUdEJRVU5NTEZkQlFVMHNSMEZCUnl4UlFVRlJMRU5CUVVNc1NVRkJTU3hEUVVGRE8wbEJRM2hDTzBGQlEwUXNVMEZCVFN4RFFVRkRMRmRCUVZjc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dEJRVU16UWl4VlFVRlBMRU5CUVVNc1RVRkJUU3hIUVVGSExFMUJRVTBzUTBGQlF6dEJRVU40UWl4UFFVRkpMRTlCUVU4c1EwRkJReXhKUVVGSkxFVkJRVVU3UVVGRGFFSXNWMEZCVFN4RFFVRkRMRXRCUVVzc1EwRkJReXhMUVVGTExFZEJRVWNzVDBGQlR5eERRVUZETEVsQlFVa3NRMEZCUXl4RFFVRkRMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU03UVVGRE5VTXNWMEZCVFN4RFFVRkRMRXRCUVVzc1EwRkJReXhOUVVGTkxFZEJRVWNzVDBGQlR5eERRVUZETEVsQlFVa3NRMEZCUXl4RFFVRkRMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU03U1VGRE9VTTdRVUZEUkN4VlFVRlBMRTlCUVU4c1EwRkJReXhOUVVGTkxFVkJRVU1zU1VGQlNTeEZRVUZETEU5QlFVOHNRMEZCUXl4RFFVRkRPMFZCUTNKRExFTkJRVU03TzFOQlJVOHNUMEZCVHl4SFFVRlFMRTlCUVU4N1UwRkRVQ3hQUVVGUExFZEJRVkFzVDBGQlR6dFRRVU5RTEVkQlFVY3NSMEZCU0N4SFFVRkhMRU03T3pzN096dEJRekZHV2l4aFFVRlpMRU5CUVVNN096czdPenM3TzB0QlJVNHNTVUZCU1N4MVEwRkJUU3hEUVVGak96dExRVVZXTEVsQlFVazdRVUZGV2l4WlFVWlJMRWxCUVVrc1IwRkZWRHN5UWtGR1N5eEpRVUZKT3pzN1FVRkxkRUlzVTBGQlNTeERRVUZETEV0QlFVc3NSMEZCUnl4RlFVRkZMRU5CUVVNN096dEJRVWRvUWl4VFFVRkpMRU5CUVVNc1NVRkJTU3hIUVVGSE8wRkJRMWdzWVVGQlRTeEZRVUZGTEZkQlFWYzdRVUZEYmtJc1dVRkJTeXhGUVVGRkxFMUJRVTA3VFVGRFlpeERRVUZET3pzN1FVRkhSaXhUUVVGSkxFTkJRVU1zVDBGQlR5eEhRVUZITEVOQlFVVXNVMEZCVXl4RlFVTjZRaXhWUVVGVkxFVkJRMVlzVlVGQlZTeEZRVU5XTEZWQlFWVXNSVUZEVml4VlFVRlZMRVZCUTFZc1IwRkJSeXhGUVVOSUxGVkJRVlVzUlVGRFZpeFRRVUZUTEVOQlExUXNRMEZCUXpzN08wRkJSMFlzVTBGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4SlFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFVkJRVVVzUTBGQlF5eERRVUZET3pzN1FVRkhla0lzVTBGQlNTeERRVUZETEZkQlFWY3NRMEZCUXl4RFFVRkRMRVZCUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVWQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1JVRkJReXhGUVVGRkxFTkJRVU1zUTBGQlF6dEpRVVZzUXpzN1owSkJPVUpyUWl4SlFVRkpPMEZCYVVOMlFpeFRRVUZKT3pzN08yTkJRVUVzWTBGQlF5eExRVUZMTEVWQlFVTXNUVUZCVFN4RlFVRkZPenRCUVVWc1FpeGhRVUZKTEZGQlFWRXNZVUZCUXpzN1FVRkZZaXhoUVVGSkxFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNUVUZCVFN4TFFVRkxMRmRCUVZjc1JVRkJSVHRCUVVOeVF5eHRRa0ZCVVN4SFFVRkhMRWxCUVVrc1EwRkJReXhUUVVGVExFTkJRVU1zUzBGQlN5eEZRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRPMVZCUTNoRExFMUJRVTBzU1VGQlNTeEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1MwRkJTeXhQUVVGUExFVkJRVVU3UVVGRGVFTXNiVUpCUVZFc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEV0QlFVc3NSVUZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenRWUVVOd1F5eE5RVUZOTEVsQlFVa3NTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhOUVVGTkxFdEJRVXNzVFVGQlRTeEZRVUZGTzBGQlEzWkRMRzFDUVVGUkxFZEJRVWNzU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXl4TFFVRkxMRVZCUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03VlVGRGJrTXNUVUZCVFR0QlFVTk9MRzFDUVVGUkxFZEJRVWNzU1VGQlNTeERRVUZETEZOQlFWTXNRMEZCUXl4TFFVRkxMRVZCUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03VlVGRGVFTTdPMEZCUlVRc1owSkJRVThzVVVGQlVTeERRVUZETzFGQlJXaENPenRCUVVsRUxHTkJRVk03T3pzN1kwRkJRU3h0UWtGQlF5eE5RVUZOTEVWQlFVVXNVVUZCVVN4RlFVRkZPenRCUVVVelFpeGhRVUZKTEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNc1MwRkJTeXhMUVVGTExFMUJRVTBzU1VGQlNTeEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1MwRkJTeXhOUVVGTkxFVkJRVWM3UVVGRE9VUXNaVUZCU1N4RFFVRkRMRTFCUVUwc1NVRkJTU3hGUVVGRkxFTkJRVU03VlVGRGJFSTdPenRCUVVkRUxHRkJRVWtzVFVGQlRTeEhRVUZITEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1RVRkJUU3hIUVVGRExFbEJRVWtzUTBGQlF5eExRVUZMTEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN08wRkJSV3hFTEdGQlFVa3NVVUZCVVN4RlFVRkZPMEZCUTJJc2FVSkJRVTBzU1VGQlNTeFJRVUZSTEVOQlFVTTdWVUZEYmtJN096dEJRVWRFTEdGQlFVa3NWMEZCVnl4SFFVRkhMRTFCUVUwc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEUxQlFVMHNRMEZCUXpzN1FVRkZOME1zWjBKQlFVOHNWMEZCVnl4SFFVRkhMRU5CUVVNc1JVRkJSVHRCUVVOMlFpeHpRa0ZCVnl4SlFVRkpMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zVFVGQlRTeERRVUZETzFWQlEycERPenRCUVVWQkxHRkJRVWtzUzBGQlN5eEhRVUZITEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1YwRkJWeXhEUVVGRExFTkJRVU03TzBGQlJYSkRMR0ZCUVVrc1NVRkJTU3hIUVVGSExFbEJRVWtzUTBGQlF5eEpRVUZKTEVkQlFVY3NTMEZCU3l4RFFVRkRPenRCUVVVM1FpeGhRVUZKTEVkQlFVY3NTVUZCU1N4SFFVRkZMRWxCUVVrc1EwRkJReXhIUVVGSExFTkJRVU1zUTBGQlF5eEZRVUZETEUxQlFVMHNRMEZCUlN4RFFVRkRPenM3UVVGSGFrTXNZVUZCU1N4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zU1VGQlNTeEhRVUZETEZsQlFWa3NRMEZCUXl4SFFVRkRMRmxCUVZrc1EwRkJRenM3UVVGRmJFUXNaMEpCUVU4c1NVRkJTU3hEUVVGRE8xRkJSVm83TzBGQlNVUXNWVUZCU3pzN096dGpRVUZCTEdWQlFVTXNUVUZCVFN4RlFVRkZMRkZCUVZFc1JVRkJSVHM3UVVGRmRrSXNZVUZCU1N4SlFVRkpMRU5CUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUzBGQlN5eE5RVUZOTEVsQlFVa3NTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFdEJRVXNzVFVGQlRTeEZRVUZITzBGQlF6bEVMR1ZCUVVrc1EwRkJReXhOUVVGTkxFbEJRVWtzUlVGQlJTeERRVUZETzFWQlEyeENPenM3UVVGSFJDeGhRVUZKTEUxQlFVMHNSMEZCUnl4SlFVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFMUJRVTBzUjBGQlF5eEpRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRTFCUVUwc1EwRkJReXhEUVVGRE96dEJRVVZzUkN4aFFVRkpMRkZCUVZFc1JVRkJSVHRCUVVOaUxHbENRVUZOTEVsQlFVa3NVVUZCVVN4RFFVRkRPMVZCUTI1Q096czdRVUZIUkN4aFFVRkpMRmRCUVZjc1IwRkJSeXhOUVVGTkxFZEJRVWNzU1VGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4TlFVRk5MRU5CUVVNN096dEJRVWMzUXl4aFFVRkpMRXRCUVVzc1IwRkJSeXhKUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEVOQlFVTXNSVUZCUXl4TlFVRk5MRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETEZkQlFWY3NRMEZCUXl4RFFVRkRPenRCUVVWMlJDeGpRVUZMTEVkQlFVY3NTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhMUVVGTExFZEJRVU1zV1VGQldTeERRVUZETEVkQlFVTXNXVUZCV1N4RFFVRkRPenRCUVVWd1JDeG5Ra0ZCVHl4TFFVRkxMRU5CUVVNN1VVRkZZanM3UVVGSlJDeFRRVUZKT3pzN08yTkJRVUVzWTBGQlF5eE5RVUZOTEVWQlFVTXNVVUZCVVN4RlFVRkZPenRCUVVWeVFpeGhRVUZKTEZGQlFWRXNSMEZCUnl4SlFVRkpMRU5CUVVNc1UwRkJVeXhEUVVGRExFMUJRVTBzUlVGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXpzN1FVRkZMME1zWVVGQlNTeERRVUZETEVkQlFVY3NSVUZCUlN4SFFVRkhMRVZCUVVVc1IwRkJReXhKUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEZGQlFWRXNSMEZCUXl4SFFVRkhMRU5CUVVNc1IwRkJReXhKUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPenRCUVVWdVJDeFZRVUZETEVkQlFVY3NTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRExFZEJRVU1zVlVGQlZTeERRVUZETEVkQlFVTXNWVUZCVlN4RFFVRkRPenRCUVVWNFF5eG5Ra0ZCVHl4RFFVRkRMRU5CUVVNN1VVRkZWRHM3UVVGRlJDeG5Ra0ZCVnp0alFVRkJMSFZDUVVGSE8wRkJRMW9zWVVGQlNTeFJRVUZSTEVkQlFVY3NSVUZCUlN4RFFVRkRPMEZCUTJ4Q0xHTkJRVXNzU1VGQlNTeERRVUZETEVkQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1IwRkJReXhUUVVGVExFTkJRVU1zVFVGQlRTeEZRVUZETEVOQlFVTXNSVUZCUlN4RlFVRkZPMEZCUTI1RExHMUNRVUZSTEVOQlFVTXNTVUZCU1N4RFFVRkZMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVVVzUlVGQlJTeEhRVUZITEZOQlFWTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJSU3hEUVVGRkxFTkJRVU03VlVGRGFrUTdRVUZEUkN4aFFVRkpMRU5CUVVNc2QwSkJRWGRDTEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNN1VVRkRla003TzBGQlJVUXNhMEpCUVdFN1kwRkJRU3g1UWtGQlJ6dEJRVU5rTEdGQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1JVRkJSU3hEUVVGRE8wRkJRMmhDTEdOQlFVc3NTVUZCU1N4RFFVRkRMRWRCUVVNc1EwRkJReXhGUVVGRExFTkJRVU1zUjBGQlF5eFRRVUZUTEVOQlFVTXNUVUZCVFN4RlFVRkRMRU5CUVVNc1JVRkJSU3hGUVVGRk8wRkJRMjVETEdWQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1NVRkJTU3hEUVVGRExGTkJRVk1zUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMVZCUXk5Q08xRkJRMFk3TzBGQlJVUXNOa0pCUVhkQ08yTkJRVUVzYTBOQlFVTXNTMEZCU3l4RlFVRkZPMEZCUXpsQ0xHRkJRVWtzUTBGQlF5eExRVUZMTEVkQlFVY3NSVUZCUlN4RFFVRkRPMEZCUTJoQ0xHTkJRVXNzU1VGQlNTeERRVUZETEVkQlFVTXNRMEZCUXl4RlFVRkRMRU5CUVVNc1IwRkJReXhMUVVGTExFTkJRVU1zVFVGQlRTeEhRVUZETEVOQlFVTXNSVUZCUXl4RFFVRkRMRVZCUVVVc1JVRkJSVHRCUVVOcVF5eGxRVUZKTEVOQlFVTXNTMEZCU3l4RFFVRkRMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zUTBGQlF5eERRVUZETEVkQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU03VlVGRGNFTTdVVUZEUmpzN1FVRkpSQ3hqUVVGVE96czdPMk5CUVVFc2JVSkJRVU1zU1VGQlNTeEZRVUZET3pzN1FVRkhaQ3hoUVVGSkxFdEJRVXNzUjBGQlJ5eEpRVUZKTEVOQlFVTXNUVUZCVFN4RFFVRkRMRWxCUVVrc1EwRkJReXhEUVVGRExGZEJRVmNzUTBGQlF6dEJRVU42UXl4aFFVRkpMRU5CUVVNc2QwSkJRWGRDTEVOQlFVTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1VVRkZkRU03TzBGQlMwUXNWMEZCVFRzN096czdZMEZCUVN4blFrRkJReXhQUVVGUExFVkJRVVU3UVVGRFppeGhRVUZKTEZGQlFWRXNSMEZCUnl4RlFVRkZMRU5CUVVNN1FVRkRiRUlzWTBGQlN5eEpRVUZKTEVkQlFVY3NTVUZCU1N4SlFVRkpMRU5CUVVNc1RVRkJUU3hGUVVGRk8wRkJRelZDTEdWQlFVa3NSMEZCUnl4RFFVRkRMRmRCUVZjc1JVRkJSU3hEUVVGRExFOUJRVThzUTBGQlF5eFBRVUZQTEVOQlFVTXNWMEZCVnl4RlFVRkZMRU5CUVVNc1MwRkJTeXhEUVVGRExFTkJRVU1zUlVGQlJUdEJRVU0xUkN4eFFrRkJVU3hEUVVGRExFbEJRVWtzUTBGQlF5eEhRVUZITEVOQlFVTXNRMEZCUXp0WlFVTnVRanRWUVVORU8wRkJRMFFzWjBKQlFVOHNVVUZCVVN4RFFVRkRPMUZCUTJoQ096dEJRVWxFTEZWQlFVczdPenM3WTBGQlFTeGxRVUZETEV0QlFVc3NSVUZCUlR0QlFVTmFMR0ZCUVVrc1RVRkJUU3hIUVVGSExFVkJRVVVzUTBGQlF6dEJRVU5vUWl4alFVRkxMRWxCUVVrc1EwRkJReXhIUVVGRExFTkJRVU1zUlVGQlF5eERRVUZETEVkQlFVTXNTMEZCU3l4RFFVRkRMRTFCUVUwc1JVRkJReXhEUVVGRExFVkJRVVVzUlVGQlJUdEJRVU5vUXl4cFFrRkJUU3hEUVVGRExFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdWVUZEYWtNN1FVRkRSQ3huUWtGQlR5eE5RVUZOTEVOQlFVTTdVVUZEWkRzN096dFZRWEJNYTBJc1NVRkJTVHM3TzJ0Q1FVRktMRWxCUVVrc1F6czdPenM3TzBGRFNucENMR0ZCUVZrc1EwRkJRenM3T3pzN096czdPMHRCUzFFc1MwRkJTenM3TzBGQlIxZ3NZMEZJVFN4TFFVRkxMRWRCUjJFN01rTkJRVklzVFVGQlRUdEJRVUZPTEcxQ1FVRk5PenM3WVVGQmNrSXNUVUZCVFN4blEwRkJSeXhEUVVGRE96c3JRa0ZJVEN4TFFVRkxPenM3T3pzN096dEJRVlZzUWl4aFFVRkpMRTFCUVUwc1IwRkJSeXhEUVVGRExFVkJRVVU3UVVGQlJTeHRRa0ZCVFN4SFFVRkhMRU5CUVVNc1EwRkJRenRWUVVGRk96dEJRVVV2UWl4aFFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFMUJRVTBzUTBGQlF6dEJRVU55UWl4aFFVRkpMRU5CUVVNc1RVRkJUU3hIUVVGSExFMUJRVTBzUTBGQlF6dEJRVU55UWl4aFFVRkpMRU5CUVVNc1MwRkJTeXhIUVVGSExFbEJRVWtzUzBGQlN5eERRVUZETEUxQlFVMHNRMEZCUXl4RFFVRkRMRWxCUVVrc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6czdRVUZGZGtNc1lVRkJTU3hOUVVGTkxFTkJRVU1zVFVGQlRTeEhRVUZITEVOQlFVTXNSVUZCUlR0QlFVTnVRaXhwUWtGQlNTeERRVUZETEVWQlFVVXNUMEZCVUN4SlFVRkpMRVZCUVU4c1RVRkJUU3hEUVVGRExFTkJRVU03VlVGRGRFSTdUVUZEU2pzN2EwSkJia0puUWl4TFFVRkxPMEZCY1VKMFFpeGxRVUZOTzI5Q1FVRkJMR2RDUVVGRExFdEJRVXNzUlVGQlJUdEJRVU5XTEhGQ1FVRkpMRU5CUVVNc1MwRkJTeXhEUVVGRExFbEJRVWtzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0QlFVTnVRaXh4UWtGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4TFFVRkxMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU03UVVGRGRFSXNkMEpCUVU4c1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF6dGpRVU55UWpzN1FVRkZSQ3hoUVVGSk8yOUNRVUZCTEdkQ1FVRlpPMjFFUVVGU0xFMUJRVTA3UVVGQlRpd3lRa0ZCVFRzN096dEJRVVZXTEhGQ1FVRkpMRU5CUVVNc1IwRkJSeXhKUVVGSkxFTkJRVU1zUzBGQlN5eERRVUZETzBGQlEyNUNMSEZDUVVGSkxFMUJRVTBzUTBGQlF5eE5RVUZOTEVkQlFVY3NRMEZCUXl4RlFVRkZPMEZCUTI1Q0xESkNRVUZOTEVOQlFVTXNUMEZCVHl4RFFVRkRMRlZCUVZNc1EwRkJReXhGUVVGRk8wRkJRM1pDTERaQ1FVRkpMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU1zVFVGQlRTeEhRVUZITEVOQlFVTXNSVUZCUlR0QlFVTnNRaXh2UTBGQlR5eERRVUZETEVsQlFVa3NRMEZCUXl4eFFrRkJjVUlzUjBGQlJ5eERRVUZETEVkQlFVY3NhMEpCUVd0Q0xFTkJRVU1zUTBGQlF6c3dRa0ZEYUVVc1RVRkJUVHRCUVVOSUxEaENRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRWRCUVVrc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eEhRVUZITEVOQlFVTXNSMEZCUnl4RFFVRkZMRU5CUVVNN01FSkJRM3BDTzNOQ1FVTktMRU5CUVVNc1EwRkJRenRyUWtGRFRpeE5RVUZOTzBGQlEwZ3NjMEpCUVVNc1EwRkJReXhQUVVGUExFTkJRVU1zVlVGQlV5eERRVUZETEVWQlFVVXNRMEZCUXl4RlFVRkZMRWRCUVVjc1JVRkJSVHRCUVVNeFFpdzBRa0ZCUnl4RFFVRkRMRU5CUVVNc1EwRkJReXhIUVVGSkxFTkJRVU1zUjBGQlJ5eERRVUZETEVkQlFVY3NRMEZCUlN4RFFVRkRPM05DUVVONFFpeERRVUZETEVOQlFVTTdhMEpCUTA0N1FVRkRSQ3gzUWtGQlR5eERRVUZETEVOQlFVTTdZMEZEV2pzN1FVRkZSQ3hYUVVGRk8yOUNRVUZCTEdOQlFWazdiVVJCUVZJc1RVRkJUVHRCUVVGT0xESkNRVUZOT3pzN08wRkJSVklzY1VKQlFVa3NRMEZCUXl4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU03UVVGRGJrSXNjVUpCUVVrc1RVRkJUU3hEUVVGRExFMUJRVTBzUjBGQlJ5eERRVUZETEVWQlFVVTdRVUZEYmtJc01rSkJRVTBzUTBGQlF5eFBRVUZQTEVOQlFVTXNWVUZCVXl4RFFVRkRMRVZCUVVVN1FVRkRka0lzTmtKQlFVa3NRMEZCUXl4SFFVRkhMRU5CUVVNc1EwRkJReXhOUVVGTkxFZEJRVWNzUTBGQlF5eEZRVUZGTzBGQlEyeENMRzlEUVVGUExFTkJRVU1zU1VGQlNTeERRVUZETEhGQ1FVRnhRaXhIUVVGSExFTkJRVU1zUjBGQlJ5d3dRa0ZCTUVJc1EwRkJReXhEUVVGRE96QkNRVU40UlN4TlFVRk5PMEZCUTBnc2FVTkJRVWtzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4TFFVRkxMRU5CUVVNc1JVRkJSVHRCUVVGRkxIZERRVUZQTEVOQlFVTXNTVUZCU1N4RFFVRkRMSEZDUVVGeFFpeEhRVUZITEVOQlFVTXNSMEZCUnl4dFFrRkJiVUlzUTBGQlF5eERRVUZET3poQ1FVRkZPMEZCUTJ4R0xEaENRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE96QkNRVU5hTzNOQ1FVTktMRU5CUVVNc1EwRkJRenRyUWtGRFRpeE5RVUZOTzBGQlEwZ3NjMEpCUVVNc1EwRkJReXhKUVVGSkxFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTTdhMEpCUTJJN1FVRkRSQ3gzUWtGQlR5eERRVUZETEVOQlFVTTdZMEZEV2pzN1FVRkZSQ3haUVVGSE8yOUNRVUZCTEdWQlFWazdiVVJCUVZJc1RVRkJUVHRCUVVGT0xESkNRVUZOT3pzN08wRkJSVlFzY1VKQlFVa3NRMEZCUXl4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU03UVVGRGJrSXNjVUpCUVVrc1RVRkJUU3hEUVVGRExFMUJRVTBzUjBGQlJ5eERRVUZETEVWQlFVVTdRVUZEYmtJc01rSkJRVTBzUTBGQlF5eFBRVUZQTEVOQlFVTXNWVUZCVXl4RFFVRkRMRVZCUVVVN1FVRkRka0lzTUVKQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU03YzBKQlExb3NRMEZCUXl4RFFVRkRPMnRDUVVOT0xFMUJRVTA3UVVGRFNDeHpRa0ZCUXl4RFFVRkRMRWxCUVVrc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6dHJRa0ZEWWp0QlFVTkVMSGRDUVVGUExFTkJRVU1zUTBGQlF6dGpRVU5hT3pzN08xbEJNMFZuUWl4TFFVRkxPenM3YTBKQlFVd3NTMEZCU3l4RE96czdPenM3UVVOTU1VSTdPMEZCUlVFN1FVRkRRVHM3T3pzN096dEJRMGhCT3p0QlFVVkJPMEZCUTBFN1FVRkRRVHRCUVVOQk96dEJRVVZCTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN08wRkJSVUU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPenRCUVVWQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk96dEJRVVZCTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUczdRVUZGUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVN3d1EwRkJlVU03TzBGQlJYcERPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CT3p0QlFVVkJPMEZCUTBFN08wRkJSVUVzU1VGQlJ6dEJRVU5JTzBGQlEwRTdPMEZCUlVFc1NVRkJSenRCUVVOSU96dEJRVVZCTzBGQlEwRTdRVUZEUVRzN1FVRkZRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN08wRkJSVUU3UVVGRFFUdEJRVU5CTzBGQlEwRTdPMEZCUlVFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHM3UVVGRlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPenRCUVVWQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHM3UVVGRlFUdEJRVU5CTzBGQlEwRTdRVUZEUVRzN1FVRkZRVHRCUVVOQk8wRkJRMEU3UVVGRFFTeHRRMEZCYTBNc2FVTkJRV2xETzBGQlEyNUZPMEZCUTBFN08wRkJSVUU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPenRCUVVWQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJMSE5EUVVGeFF5eGxRVUZsTzBGQlEzQkVPMEZCUTBFc1RVRkJTenM3UVVGRlREdEJRVU5CTzBGQlEwRTdPMEZCUlVFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTEVrN1FVRkRRVHM3UVVGRlFUczdRVUZGUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHM3UVVGRlFUdEJRVU5CTzBGQlEwRTdRVUZEUVRzN1FVRkZRVHRCUVVOQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVR0QlFVTkJPMEZCUTBFN08wRkJSVUU3UVVGRFFUdEJRVU5CTzBGQlEwRTdPMEZCUlVFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUczdRVUZGUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHM3UVVGRlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPenRCUVVWQk8wRkJRMEU3UVVGRFFUdEJRVU5CT3p0QlFVVkJPMEZCUTBFN1FVRkRRVHRCUVVOQkxFVTdPenM3T3pzN1FVTjZUMEU3UVVGRFFUczdRVUZGUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHM3UVVGRlFUdEJRVU5CT3p0QlFVVkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFc1ZVRkJVenRCUVVOVU8wRkJRMEU3UVVGRFFTeE5RVUZMTzBGQlEwdzdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQkxGVkJRVk03UVVGRFZEdEJRVU5CTzBGQlEwRXNUVUZCU3p0QlFVTk1PMEZCUTBFN1FVRkRRU3hGUVVGRE8wRkJRMFE3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVN4TlFVRkxPMEZCUTB3N1FVRkRRVHRCUVVOQk8wRkJRMEVzVlVGQlV6dEJRVU5VTzBGQlEwRTdRVUZEUVR0QlFVTkJPenM3UVVGSFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFc1RVRkJTenRCUVVOTU8wRkJRMEU3UVVGRFFUdEJRVU5CTEZWQlFWTTdRVUZEVkR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk96czdPMEZCU1VFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUczdRVUZGUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTEUxQlFVczdRVUZEVER0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3TzBGQlJVRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk96dEJRVVZCTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk96dEJRVVZCTzBGQlEwRTdRVUZEUVR0QlFVTkJMSGRDUVVGMVFpeHpRa0ZCYzBJN1FVRkROME03UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHM3UVVGRlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVN4elFrRkJjVUk3UVVGRGNrSTdPMEZCUlVFN08wRkJSVUU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk96dEJRVVZCTEhORFFVRnhRenM3UVVGRmNrTTdRVUZEUVR0QlFVTkJPenRCUVVWQkxEUkNRVUV5UWp0QlFVTXpRanRCUVVOQk8wRkJRMEU3UVVGRFFTdzJRa0ZCTkVJc1ZVRkJWVHM3T3pzN096dEJRM1pNZEVNc1lVRkJXU3hEUVVGRE96czdPenM3UzBGRlNpeExRVUZMTEhWQ1FVRlJMRU5CUVZNc1JVRkJkRUlzUzBGQlN6czdTMEZGVHl4UlFVRlJPMEZCUldoQ0xGbEJSbEVzVVVGQlVTeERRVVZtTEVsQlFVa3NSVUZCUXl4SlFVRkpMRVZCUVVNc1JVRkJSU3hGUVVGRk96SkNRVVpRTEZGQlFWRTdPMEZCU1hwQ0xGTkJRVWtzUTBGQlF5eEpRVUZKTEVkQlFVY3NTVUZCU1N4RFFVRkRPMEZCUTJwQ0xGTkJRVWtzUTBGQlF5eEZRVUZGTEVkQlFVY3NSVUZCUlN4RFFVRkRPMEZCUTJJc1UwRkJTU3hEUVVGRExFdEJRVXNzUjBGQlJ5eExRVUZMTEVWQlFVVXNRMEZCUXpzN1FVRkZja0lzVTBGQlNTeERRVUZETEU5QlFVOHNSMEZCUnl4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wRkJRMjVDTEZOQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1EwRkJReXhEUVVGRE96dEJRVVZtTEZOQlFVa3NRMEZCUXl4TFFVRkxMRWRCUVVjc1NVRkJTU3hIUVVGSExFbEJRVWtzUjBGQlJ5eFpRVUZYTEVWQlFVY3NRMEZCUXpzN1FVRkZNVU1zVTBGQlNTeEpRVUZKTEVOQlFVTXNSVUZCUlN4RlFVRkZPMEZCUTFnc1YwRkJTU3hEUVVGRExFdEJRVXNzUlVGQlJTeERRVUZETzAxQlEyUTdTVUZGUmpzN1owSkJha0pyUWl4UlFVRlJPMEZCYlVJelFpeFhRVUZOTzJOQlFVRXNaMEpCUVVNc1EwRkJReXhGUVVGRk96dEJRVVZPTEdGQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU03TzBGQlJXaENMR0ZCUVVrc1EwRkJReXhMUVVGTExFVkJRVVVzUTBGQlF6dFJRVU5rT3p0QlFVVkVMRk5CUVVrN1kwRkJRU3huUWtGQlJ6dEJRVU5NTEdGQlFVa3NRMEZCUXl4RlFVRkZMRWRCUVVjc1MwRkJTeXhEUVVGRE8wRkJRMmhDTEdGQlFVa3NRMEZCUXl4UlFVRlJMRU5CUVVNc1MwRkJTeXhGUVVGRkxFTkJRVU03VVVGRGRrSTdPMEZCUlVRc1ZVRkJTenRqUVVGQkxHbENRVUZITzBGQlEwNHNZVUZCU1N4RFFVRkRMRVZCUVVVc1IwRkJSeXhKUVVGSkxFTkJRVU03UVVGRFppeGhRVUZKTEVOQlFVTXNVVUZCVVN4SFFVRkhMRWxCUVVrc1EwRkJReXhMUVVGTExFTkJRVU1zWTBGQll5eERRVUZETEVsQlFVa3NRMEZCUXl4TlFVRk5MRU5CUVVNc1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF5eEZRVUZGTEVsQlFVa3NRMEZCUXl4TFFVRkxMRU5CUVVNc1QwRkJUeXhEUVVGRExGZEJRVmNzUTBGQlF5eERRVUZETEUxQlFVMHNRMEZCUXl4SlFVRkpMRU5CUVVNc1NVRkJTU3hIUVVGRExFbEJRVWtzUTBGQlF5eERRVUZETEZOQlFWTXNRMEZCUXl4RlFVRkRMRXRCUVVzc1JVRkJSU3hIUVVGSExFVkJRVVVzU1VGQlNTeEZRVUZETEVOQlFVTXNSVUZCUXl4RFFVRkRMRU5CUVVNN1VVRkRNVW83TzBGQlJVUXNUMEZCUlR0alFVRkJMRmxCUVVNc1QwRkJUeXhGUVVGRk8wRkJRMVlzWVVGQlNTeEpRVUZKTEVOQlFVTXNSVUZCUlN4RlFVRkZPMEZCUTFnc1pVRkJTU3hMUVVGTExFZEJRVWNzVDBGQlR5eEhRVUZETEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNN1FVRkRPVUlzWlVGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4UFFVRlBMRU5CUVVNN1FVRkRjRUlzWlVGQlNTeERRVUZETEV0QlFVc3NRMEZCUXl4WFFVRlhMRU5CUVVNc1NVRkJTU3hEUVVGRExFdEJRVXNzUTBGQlF5eFBRVUZQTEVOQlFVTXNWMEZCVnl4RlFVRkZMRU5CUVVNc1NVRkJTU3hEUVVGRExGRkJRVkVzUTBGQlF5eEZRVUZGTEV0QlFVc3NRMEZCUXl4RFFVRkRPMVZCUTJoR0xFMUJRVTA3UVVGRFRDeGxRVUZKTEVOQlFVTXNTVUZCU1N4SFFVRkhMRTlCUVU4c1EwRkJRenRWUVVOeVFqdFJRVU5HT3pzN08xVkJOVU5yUWl4UlFVRlJPenM3YTBKQlFWSXNVVUZCVVN4RElpd2labWxzWlNJNklpNHZaR2x6ZEM5T1pYaDFjMVZKTG1weklpd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sc2lLR1oxYm1OMGFXOXVJSGRsWW5CaFkydFZibWwyWlhKellXeE5iMlIxYkdWRVpXWnBibWwwYVc5dUtISnZiM1FzSUdaaFkzUnZjbmtwSUh0Y2JseDBhV1lvZEhsd1pXOW1JR1Y0Y0c5eWRITWdQVDA5SUNkdlltcGxZM1FuSUNZbUlIUjVjR1Z2WmlCdGIyUjFiR1VnUFQwOUlDZHZZbXBsWTNRbktWeHVYSFJjZEcxdlpIVnNaUzVsZUhCdmNuUnpJRDBnWm1GamRHOXllU2dwTzF4dVhIUmxiSE5sSUdsbUtIUjVjR1Z2WmlCa1pXWnBibVVnUFQwOUlDZG1kVzVqZEdsdmJpY2dKaVlnWkdWbWFXNWxMbUZ0WkNsY2JseDBYSFJrWldacGJtVW9XMTBzSUdaaFkzUnZjbmtwTzF4dVhIUmxiSE5sSUdsbUtIUjVjR1Z2WmlCbGVIQnZjblJ6SUQwOVBTQW5iMkpxWldOMEp5bGNibHgwWEhSbGVIQnZjblJ6VzF3aVRtVjRkWE5jSWwwZ1BTQm1ZV04wYjNKNUtDazdYRzVjZEdWc2MyVmNibHgwWEhSeWIyOTBXMXdpVG1WNGRYTmNJbDBnUFNCbVlXTjBiM0o1S0NrN1hHNTlLU2gwYUdsekxDQm1kVzVqZEdsdmJpZ3BJSHRjYm5KbGRIVnliaUJjYmx4dVhHNHZMeUJYUlVKUVFVTkxJRVpQVDFSRlVpQXZMMXh1THk4Z2QyVmljR0ZqYXk5MWJtbDJaWEp6WVd4TmIyUjFiR1ZFWldacGJtbDBhVzl1SWl3aUlGeDBMeThnVkdobElHMXZaSFZzWlNCallXTm9aVnh1SUZ4MGRtRnlJR2x1YzNSaGJHeGxaRTF2WkhWc1pYTWdQU0I3ZlR0Y2JseHVJRngwTHk4Z1ZHaGxJSEpsY1hWcGNtVWdablZ1WTNScGIyNWNiaUJjZEdaMWJtTjBhVzl1SUY5ZmQyVmljR0ZqYTE5eVpYRjFhWEpsWDE4b2JXOWtkV3hsU1dRcElIdGNibHh1SUZ4MFhIUXZMeUJEYUdWamF5QnBaaUJ0YjJSMWJHVWdhWE1nYVc0Z1kyRmphR1ZjYmlCY2RGeDBhV1lvYVc1emRHRnNiR1ZrVFc5a2RXeGxjMXR0YjJSMWJHVkpaRjBwWEc0Z1hIUmNkRngwY21WMGRYSnVJR2x1YzNSaGJHeGxaRTF2WkhWc1pYTmJiVzlrZFd4bFNXUmRMbVY0Y0c5eWRITTdYRzVjYmlCY2RGeDBMeThnUTNKbFlYUmxJR0VnYm1WM0lHMXZaSFZzWlNBb1lXNWtJSEIxZENCcGRDQnBiblJ2SUhSb1pTQmpZV05vWlNsY2JpQmNkRngwZG1GeUlHMXZaSFZzWlNBOUlHbHVjM1JoYkd4bFpFMXZaSFZzWlhOYmJXOWtkV3hsU1dSZElEMGdlMXh1SUZ4MFhIUmNkR1Y0Y0c5eWRITTZJSHQ5TEZ4dUlGeDBYSFJjZEdsa09pQnRiMlIxYkdWSlpDeGNiaUJjZEZ4MFhIUnNiMkZrWldRNklHWmhiSE5sWEc0Z1hIUmNkSDA3WEc1Y2JpQmNkRngwTHk4Z1JYaGxZM1YwWlNCMGFHVWdiVzlrZFd4bElHWjFibU4wYVc5dVhHNGdYSFJjZEcxdlpIVnNaWE5iYlc5a2RXeGxTV1JkTG1OaGJHd29iVzlrZFd4bExtVjRjRzl5ZEhNc0lHMXZaSFZzWlN3Z2JXOWtkV3hsTG1WNGNHOXlkSE1zSUY5ZmQyVmljR0ZqYTE5eVpYRjFhWEpsWDE4cE8xeHVYRzRnWEhSY2RDOHZJRVpzWVdjZ2RHaGxJRzF2WkhWc1pTQmhjeUJzYjJGa1pXUmNiaUJjZEZ4MGJXOWtkV3hsTG14dllXUmxaQ0E5SUhSeWRXVTdYRzVjYmlCY2RGeDBMeThnVW1WMGRYSnVJSFJvWlNCbGVIQnZjblJ6SUc5bUlIUm9aU0J0YjJSMWJHVmNiaUJjZEZ4MGNtVjBkWEp1SUcxdlpIVnNaUzVsZUhCdmNuUnpPMXh1SUZ4MGZWeHVYRzVjYmlCY2RDOHZJR1Y0Y0c5elpTQjBhR1VnYlc5a2RXeGxjeUJ2WW1wbFkzUWdLRjlmZDJWaWNHRmphMTl0YjJSMWJHVnpYMThwWEc0Z1hIUmZYM2RsWW5CaFkydGZjbVZ4ZFdseVpWOWZMbTBnUFNCdGIyUjFiR1Z6TzF4dVhHNGdYSFF2THlCbGVIQnZjMlVnZEdobElHMXZaSFZzWlNCallXTm9aVnh1SUZ4MFgxOTNaV0p3WVdOclgzSmxjWFZwY21WZlh5NWpJRDBnYVc1emRHRnNiR1ZrVFc5a2RXeGxjenRjYmx4dUlGeDBMeThnWDE5M1pXSndZV05yWDNCMVlteHBZMTl3WVhSb1gxOWNiaUJjZEY5ZmQyVmljR0ZqYTE5eVpYRjFhWEpsWDE4dWNDQTlJRndpWENJN1hHNWNiaUJjZEM4dklFeHZZV1FnWlc1MGNua2diVzlrZFd4bElHRnVaQ0J5WlhSMWNtNGdaWGh3YjNKMGMxeHVJRngwY21WMGRYSnVJRjlmZDJWaWNHRmphMTl5WlhGMWFYSmxYMThvTUNrN1hHNWNibHh1WEc0dkx5QlhSVUpRUVVOTElFWlBUMVJGVWlBdkwxeHVMeThnZDJWaWNHRmpheTlpYjI5MGMzUnlZWEFnWWpJMk9XRmpaV1k0WTJGa1lUY3dPRFExTURJaUxDSW5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JtbHRjRzl5ZENCT1pYaDFjMVZKSUdaeWIyMGdKeTR2YkdsaUwyMWhhVzRuTzF4dVhHNWxlSEJ2Y25RZ1pHVm1ZWFZzZENCT1pYaDFjMVZKTzF4dVhHNWNibHh1THk4Z1YwVkNVRUZEU3lCR1QwOVVSVklnTHk5Y2JpOHZJQzR2Zmk5cWMyaHBiblF0Ykc5aFpHVnlJUzR2YVc1a1pYZ3Vhbk1pTENJbmRYTmxJSE4wY21samRDYzdYRzVjYm1sdGNHOXlkQ0JKYm5SbGNtWmhZMlZ6SUdaeWIyMGdKeTR2YVc1MFpYSm1ZV05sY3k4bk8xeHVhVzF3YjNKMElHMWhkR2dnWm5KdmJTQW5MaTkxZEdsc0wyMWhkR2duTzF4dWFXMXdiM0owSUZKaFkyc2dabkp2YlNBbkxpOWpiM0psTDNKaFkyc25PMXh1YVcxd2IzSjBJRlIxYm1VZ1puSnZiU0FuTGk5MGRXNXBibWN2ZEhWdWFXNW5KenRjYm1sdGNHOXlkQ0FxSUdGeklGUnlZVzV6Wm05eWJTQm1jbTl0SUNjdUwzVjBhV3d2ZEhKaGJuTm1iM0p0Snp0Y2JseHViR1YwSUVOdmRXNTBaWElnUFNCeVpYRjFhWEpsS0NjdUwyMXZaR1ZzY3k5amIzVnVkR1Z5SnlrN1hHNXNaWFFnVW1Ga2FXOGdQU0J5WlhGMWFYSmxLQ2N1TDIxdlpHVnNjeTl5WVdScGJ5Y3BPMXh1YkdWMElFUnlkVzVySUQwZ2NtVnhkV2x5WlNnbkxpOXRiMlJsYkhNdlpISjFibXNuS1R0Y2JteGxkQ0JUWlhGMVpXNWpaU0E5SUhKbGNYVnBjbVVvSnk0dmJXOWtaV3h6TDNObGNYVmxibU5sSnlrN1hHNXNaWFFnVFdGMGNtbDRJRDBnY21WeGRXbHlaU2duTGk5dGIyUmxiSE12YldGMGNtbDRKeWs3WEc1Y2JtbHRjRzl5ZENCWFFVRkRiRzlqYXlCbWNtOXRJQ2QzWVdGamJHOWpheWM3WEc1cGJYQnZjblFnU1c1MFpYSjJZV3dnWm5KdmJTQW5MaTkwYVcxbEwybHVkR1Z5ZG1Gc0p6dGNibHh1WEc0dktpcGNiazVsZUhWelZVa2dQVDRnWTNKbFlYUmxaQ0JoY3lCT1pYaDFjMXh1S2k5Y2JseHVZMnhoYzNNZ1RtVjRkWE5WU1NCN1hHNWNiaUFnSUNCamIyNXpkSEoxWTNSdmNpaGpiMjUwWlhoMEtTQjdYRzVjYmlBZ0lDQWdJQ0FnWm05eUlDaHNaWFFnYTJWNUlHbHVJRWx1ZEdWeVptRmpaWE1wSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhOYmEyVjVYU0E5SUVsdWRHVnlabUZqWlhOYmEyVjVYVHRjYmlBZ0lDQWdJQ0FnZlZ4dVhHNGdJQ0FnSUNBZ0lHWnZjaUFvYkdWMElHdGxlU0JwYmlCdFlYUm9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBhR2x6VzJ0bGVWMGdQU0J0WVhSb1cydGxlVjA3WEc0Z0lDQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ0lDQnNaWFFnUTI5eVpTQTlJSHRjYmlBZ0lDQWdJQ0FnSUNBblVtRmpheWM2SUZKaFkydGNiaUFnSUNBZ0lDQWdmVHRjYmx4dUlDQWdJQ0FnSUNCc1pYUWdUVzlrWld4eklEMGdlMXh1SUNBZ0lDQWdJQ0FnSUNkRGIzVnVkR1Z5SnpvZ1EyOTFiblJsY2l4Y2JpQWdJQ0FnSUNBZ0lDQW5VbUZrYVc4bk9pQlNZV1JwYnl4Y2JpQWdJQ0FnSUNBZ0lDQW5SSEoxYm1zbk9pQkVjblZ1YXl4Y2JpQWdJQ0FnSUNBZ0lDQW5VMlZ4ZFdWdVkyVW5PaUJUWlhGMVpXNWpaU3hjYmlBZ0lDQWdJQ0FnSUNBblRXRjBjbWw0SnpvZ1RXRjBjbWw0WEc0Z0lDQWdJQ0FnSUgwN1hHNWNiaUFnSUNBZ0lDQWdabTl5SUNoc1pYUWdhMlY1SUdsdUlFMXZaR1ZzY3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJSFJvYVhOYmEyVjVYU0E5SUUxdlpHVnNjMXRyWlhsZE8xeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnWm05eUlDaHNaWFFnYTJWNUlHbHVJRU52Y21VcElIdGNiaUFnSUNBZ0lDQWdJQ0IwYUdselcydGxlVjBnUFNCRGIzSmxXMnRsZVYwN1hHNGdJQ0FnSUNBZ0lIMWNibHh1SUNBZ0lDQWdJQ0JzWlhRZ1JHVm1ZWFZzZEVOdmJuUmxlSFFnUFNCM2FXNWtiM2N1UVhWa2FXOURiMjUwWlhoMElIeDhJSGRwYm1SdmR5NTNaV0pyYVhSQmRXUnBiME52Ym5SbGVIUTdYRzRnSUNBZ0lDQWdJSFJvYVhNdVgyTnZiblJsZUhRZ1BTQmpiMjUwWlhoMElIeDhJRzVsZHlCRVpXWmhkV3gwUTI5dWRHVjRkQ2dwTzF4dVhHNGdJQ0FnSUNBZ0lIUm9hWE11ZEhWdVpTQTlJRzVsZHlCVWRXNWxLQ2s3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVibTkwWlNBOUlIUm9hWE11ZEhWdVpTNXViM1JsTG1KcGJtUW9kR2hwY3k1MGRXNWxLVHRjYmx4dUlDQWdJQ0FnSUNCMGFHbHpMbU5zYjJOcklEMGdibVYzSUZkQlFVTnNiMk5yS0hSb2FYTXVYMk52Ym5SbGVIUXBPMXh1SUNBZ0lDQWdJQ0IwYUdsekxtTnNiMk5yTG5OMFlYSjBLQ2s3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVTVzUwWlhKMllXd2dQU0JKYm5SbGNuWmhiRHRjYmx4dUlDQWdJQ0FnSUNCMGFHbHpMbU52Ykc5eWN5QTlJSHRjYmlBZ0lDQWdJQ0FnSUNCaFkyTmxiblE2SUNjak1tSmlKeXhjYmlBZ0lDQWdJQ0FnSUNCbWFXeHNPaUFuSTJWbFpTY3NYRzRnSUNBZ0lDQWdJQ0FnYkdsbmFIUTZJQ2NqWm1abUp5eGNiaUFnSUNBZ0lDQWdJQ0JrWVhKck9pQW5Jek16TXljc1hHNGdJQ0FnSUNBZ0lDQWdiV1ZrYVhWdFRHbG5hSFE2SUNjalkyTmpKeXhjYmlBZ0lDQWdJQ0FnSUNCdFpXUnBkVzFFWVhKck9pQW5JelkyTmlkY2JpQWdJQ0FnSUNBZ2ZUdGNibHh1SUNBZ0lDQWdJQ0IwYUdsekxuUnlZVzV6Wm05eWJTQTlJRlJ5WVc1elptOXliVHRjYmlBZ0lDQWdJQ0FnZEdocGN5NWhaR1FnUFNCVWNtRnVjMlp2Y20wdVlXUmtPMXh1WEc1Y2JpQWdJQ0FnSUNBZ2RHaHBjeTVCWkdRZ1BTQjdmVHRjYmlBZ0lDQWdJQ0FnWm05eUlDaHNaWFFnYTJWNUlHbHVJRWx1ZEdWeVptRmpaWE1wSUh0Y2JpQWdJQ0FnSUNBZ0lDQjBhR2x6TGtGa1pGdHJaWGxkSUQwZ1ZISmhibk5tYjNKdExtRmtaQzVpYVc1a0tIUm9hWE1zYTJWNUtUdGNiaUFnSUNBZ0lDQWdmVnh1WEc1Y2JseHVYRzRnSUNBZ0lDQWdJQzhxSUdOeVpXRjBaU0JrWldaaGRXeDBJR052YlhCdmJtVnVkQ0J6YVhwbElDb3ZYRzRnSUNBZ0lDQWdJQzhxSUdwemFHbHVkQ0JwWjI1dmNtVTZjM1JoY25RZ0tpOWNiaUFnSUNBZ0lDQWdkbUZ5SUdWNGFYTjBhVzVuVTNSNWJHVnphR1ZsZEhNZ1BTQmtiMk4xYldWdWRDNW5aWFJGYkdWdFpXNTBjMEo1VkdGblRtRnRaU2hjSW5OMGVXeGxYQ0lwTzF4dUlDQWdJQ0FnSUNCMllYSWdaR1ZtWVhWc2RGTnBlbVZFWldOc1lYSmhkR2x2YmlBOUlDZGJibVY0ZFhNdGRXbGRlMmhsYVdkb2REbzFNREF3Y0hnN2QybGtkR2c2TlRBd01IQjRmU2M3WEc0Z0lDQWdJQ0FnSUhaaGNpQmtaV1poZFd4MFUzUjViR1ZPYjJSbElEMGdaRzlqZFcxbGJuUXVZM0psWVhSbFJXeGxiV1Z1ZENnbmMzUjViR1VuS1R0Y2JpQWdJQ0FnSUNBZ1pHVm1ZWFZzZEZOMGVXeGxUbTlrWlM1MGVYQmxJRDBnSjNSbGVIUXZZM056Snp0Y2JpQWdJQ0FnSUNBZ1pHVm1ZWFZzZEZOMGVXeGxUbTlrWlM1cGJtNWxja2hVVFV3Z1BTQmtaV1poZFd4MFUybDZaVVJsWTJ4aGNtRjBhVzl1TzF4dUlDQWdJQ0FnSUNCcFppQW9aWGhwYzNScGJtZFRkSGxzWlhOb1pXVjBjeTVzWlc1bmRHZ2dQaUF3S1NCN1hHNGdJQ0FnSUNBZ0lDQWdkbUZ5SUhCaGNtVnVkQ0E5SUdWNGFYTjBhVzVuVTNSNWJHVnphR1ZsZEhOYk1GMHVjR0Z5Wlc1MFRtOWtaVnh1SUNBZ0lDQWdJQ0FnSUhCaGNtVnVkQzVwYm5ObGNuUkNaV1p2Y21Vb0lHUmxabUYxYkhSVGRIbHNaVTV2WkdVc0lHVjRhWE4wYVc1blUzUjViR1Z6YUdWbGRITmJNRjBwWEc0Z0lDQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ1pHOWpkVzFsYm5RdWQzSnBkR1VvSnp4emRIbHNaVDRuSzJSbFptRjFiSFJUYVhwbFJHVmpiR0Z5WVhScGIyNHJKenhjWEM5emRIbHNaVDRuS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQXZLaUJxYzJocGJuUWdhV2R1YjNKbE9tVnVaQ0FxTDF4dVhHNGdJQ0FnZlZ4dVhHNGdJQ0FnWjJWMElHTnZiblJsZUhRb0tTQjdYRzRnSUNBZ0lDQnlaWFIxY200Z2RHaHBjeTVmWTI5dWRHVjRkRHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQnpaWFFnWTI5dWRHVjRkQ2hqZEhncElIdGNiaUFnSUNBZ0lIUm9hWE11WTJ4dlkyc3VjM1J2Y0NncE8xeHVJQ0FnSUNBZ2RHaHBjeTVmWTI5dWRHVjRkQ0E5SUdOMGVEdGNiaUFnSUNBZ0lIUm9hWE11WTJ4dlkyc2dQU0J1WlhjZ1YwRkJRMnh2WTJzb2RHaHBjeTVqYjI1MFpYaDBLVHRjYmlBZ0lDQWdJSFJvYVhNdVkyeHZZMnN1YzNSaGNuUW9LVHRjYmlBZ0lDQjlYRzVjYmx4dVhHNTlYRzVjYm14bGRDQk9aWGgxY3lBOUlHNWxkeUJPWlhoMWMxVkpLQ2s3WEc1Y2JtVjRjRzl5ZENCbWRXNWpkR2x2YmlCamIyeHZjbk1vS1NCN1hHNGdJQ0FnY21WMGRYSnVJRTVsZUhWekxtTnZiRzl5Y3p0Y2JuMWNibVY0Y0c5eWRDQm1kVzVqZEdsdmJpQmpiMjUwWlhoMEtDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCT1pYaDFjeTVqYjI1MFpYaDBPMXh1ZlZ4dVpYaHdiM0owSUdaMWJtTjBhVzl1SUdOc2IyTnJLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQk9aWGgxY3k1amJHOWphenRjYm4xY2JseHVaWGh3YjNKMElHUmxabUYxYkhRZ1RtVjRkWE03WEc1Y2JseHVYRzR2THlCWFJVSlFRVU5MSUVaUFQxUkZVaUF2TDF4dUx5OGdMaTkrTDJwemFHbHVkQzFzYjJGa1pYSWhMaTlzYVdJdmJXRnBiaTVxY3lJc0ltVjRjRzl5ZENCa1pXWmhkV3gwSUh0Y2JpQWdVRzl6YVhScGIyNDZJSEpsY1hWcGNtVW9KeTR2Y0c5emFYUnBiMjRuS1N4Y2JpQWdVMnhwWkdWeU9pQnlaWEYxYVhKbEtDY3VMM05zYVdSbGNpY3BMRnh1SUNCVWIyZG5iR1U2SUhKbGNYVnBjbVVvSnk0dmRHOW5aMnhsSnlrc1hHNHZLaUFnVW1GdVoyVTZJSEpsY1hWcGNtVW9KeTR2Y21GdVoyVnpiR2xrWlhJbktTeGNiaUFnVjJGMlpXWnZjbTA2SUhKbGNYVnBjbVVvSnk0dmQyRjJaV1p2Y20wbktTd2dLaTljYmlBZ1FuVjBkRzl1T2lCeVpYRjFhWEpsS0NjdUwySjFkSFJ2YmljcExGeHVJQ0JVWlhoMFFuVjBkRzl1T2lCeVpYRjFhWEpsS0NjdUwzUmxlSFJpZFhSMGIyNG5LU3hjYmlBZ1VtRmthVzlDZFhSMGIyNDZJSEpsY1hWcGNtVW9KeTR2Y21Ga2FXOWlkWFIwYjI0bktTeGNiaUFnVG5WdFltVnlPaUJ5WlhGMWFYSmxLQ2N1TDI1MWJXSmxjaWNwTEZ4dUlDQlRaV3hsWTNRNklISmxjWFZwY21Vb0p5NHZjMlZzWldOMEp5a3NYRzRnSUVScFlXdzZJSEpsY1hWcGNtVW9KeTR2WkdsaGJDY3BMRnh1SUNCUWFXRnViem9nY21WeGRXbHlaU2duTGk5d2FXRnVieWNwTEZ4dUlDQlRaWEYxWlc1alpYSTZJSEpsY1hWcGNtVW9KeTR2YzJWeGRXVnVZMlZ5Snlrc1hHNGdJRkJoYmpKRU9pQnlaWEYxYVhKbEtDY3VMM0JoYmpKa0p5a3NYRzRnSUZScGJIUTZJSEpsY1hWcGNtVW9KeTR2ZEdsc2RDY3BMRnh1SUNCTmRXeDBhWE5zYVdSbGNqb2djbVZ4ZFdseVpTZ25MaTl0ZFd4MGFYTnNhV1JsY2ljcExGeHVJQ0JRWVc0NklISmxjWFZwY21Vb0p5NHZjR0Z1Snlrc1hHNGdJRVZ1ZG1Wc2IzQmxPaUJ5WlhGMWFYSmxLQ2N1TDJWdWRtVnNiM0JsSnlrc1hHNGdJRk53WldOMGNtOW5jbUZ0T2lCeVpYRjFhWEpsS0NjdUwzTndaV04wY205bmNtRnRKeWtzWEc0Z0lFMWxkR1Z5T2lCeVpYRjFhWEpsS0NjdUwyMWxkR1Z5Snlrc1hHNGdJRTl6WTJsc2JHOXpZMjl3WlRvZ2NtVnhkV2x5WlNnbkxpOXZjMk5wYkd4dmMyTnZjR1VuS1Z4dWZUdGNibHh1WEc1Y2JpOHZJRmRGUWxCQlEwc2dSazlQVkVWU0lDOHZYRzR2THlBdUwzNHZhbk5vYVc1MExXeHZZV1JsY2lFdUwyeHBZaTlwYm5SbGNtWmhZMlZ6TDJsdVpHVjRMbXB6SWl3aVhHNG5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JteGxkQ0J6ZG1jZ1BTQnlaWEYxYVhKbEtDY3VMaTkxZEdsc0wzTjJaeWNwTzF4dWJHVjBJRWx1ZEdWeVptRmpaU0E5SUhKbGNYVnBjbVVvSnk0dUwyTnZjbVV2YVc1MFpYSm1ZV05sSnlrN1hHNXNaWFFnVTNSbGNDQTlJSEpsY1hWcGNtVW9KeTR1TDIxdlpHVnNjeTl6ZEdWd0p5azdYRzVwYlhCdmNuUWdLaUJoY3lCSmJuUmxjbUZqZEdsdmJpQm1jbTl0SUNjdUxpOTFkR2xzTDJsdWRHVnlZV04wYVc5dUp6dGNibHh1THlvcVhHNHFJRkJ2YzJsMGFXOXVYRzRxWEc0cUlFQmtaWE5qY21sd2RHbHZiaUJVZDI4dFpHbHRaVzV6YVc5dVlXd2dkRzkxWTJnZ2MyeHBaR1Z5TGx4dUtseHVLaUJBWkdWdGJ5QThjM0JoYmlCdVpYaDFjeTExYVQxY0luQnZjMmwwYVc5dVhDSStQQzl6Y0dGdVBseHVLbHh1S2lCQVpYaGhiWEJzWlZ4dUtpQjJZWElnY0c5emFYUnBiMjRnUFNCdVpYY2dUbVY0ZFhNdVVHOXphWFJwYjI0b0p5TjBZWEpuWlhRbktWeHVLbHh1S2lCQVpYaGhiWEJzWlZ4dUtpQjJZWElnY0c5emFYUnBiMjRnUFNCdVpYY2dUbVY0ZFhNdVVHOXphWFJwYjI0b0p5TjBZWEpuWlhRbkxIdGNiaW9nSUNBbmMybDZaU2M2SUZzeU1EQXNNakF3WFN4Y2Jpb2dJQ0FuYlc5a1pTYzZJQ2RoWW5OdmJIVjBaU2NzSUNBdkx5QmNJbUZpYzI5c2RYUmxYQ0lnYjNJZ1hDSnlaV3hoZEdsMlpWd2lYRzRxSUNBZ0ozZ25PaUF3TGpVc0lDQXZMeUJwYm1sMGFXRnNJSGdnZG1Gc2RXVmNiaW9nSUNBbmJXbHVXQ2M2SURBc1hHNHFJQ0FnSjIxaGVGZ25PaUF4TEZ4dUtpQWdJQ2R6ZEdWd1dDYzZJREFzWEc0cUlDQWdKM2tuT2lBd0xqVXNJQ0F2THlCcGJtbDBhV0ZzSUhrZ2RtRnNkV1ZjYmlvZ0lDQW5iV2x1V1NjNklEQXNYRzRxSUNBZ0oyMWhlRmtuT2lBeExGeHVLaUFnSUNkemRHVndXU2M2SURCY2Jpb2dmU2xjYmlwY2Jpb2dRRzkxZEhCMWRGeHVLaUJqYUdGdVoyVmNiaW9nUm1seVpYTWdZVzU1SUhScGJXVWdkR2hsSUdsdWRHVnlabUZqWlNkeklIWmhiSFZsSUdOb1lXNW5aWE11SUR4aWNqNWNiaW9nVkdobElHVjJaVzUwSUdSaGRHRWdhWE1nWVc0Z2IySnFaV04wSUhkcGRHZ2dlQ0JoYm1RZ2VTQndjbTl3WlhKMGFXVnpJR052Ym5SaGFXNXBibWNnZEdobElIZ2dZVzVrSUhrZ2RtRnNkV1Z6SUc5bUlIUm9aU0JwYm5SbGNtWmhZMlV1WEc0cVhHNHFJRUJ2ZFhSd2RYUmxlR0Z0Y0d4bFhHNHFJSEJ2YzJsMGFXOXVMbTl1S0NkamFHRnVaMlVuTEdaMWJtTjBhVzl1S0hZcElIdGNiaW9nSUNCamIyNXpiMnhsTG14dlp5aDJLVHRjYmlvZ2ZTbGNiaXBjYmlwY2Jpb3ZYRzVjYm1WNGNHOXlkQ0JrWldaaGRXeDBJR05zWVhOeklGQnZjMmwwYVc5dUlHVjRkR1Z1WkhNZ1NXNTBaWEptWVdObElIdGNibHh1SUNCamIyNXpkSEoxWTNSdmNpZ3BJSHRjYmx4dUlDQWdJR3hsZENCdmNIUnBiMjV6SUQwZ1d5ZDJZV3gxWlNkZE8xeHVYRzRnSUNBZ2JHVjBJR1JsWm1GMWJIUnpJRDBnZTF4dUlDQWdJQ0FnSjNOcGVtVW5PaUJiTWpBd0xESXdNRjBzWEc0Z0lDQWdJQ0FuYlc5a1pTYzZJQ2RoWW5OdmJIVjBaU2NzWEc0Z0lDQWdJQ0FuYldsdVdDYzZJREFzWEc0Z0lDQWdJQ0FuYldGNFdDYzZJREVzWEc0Z0lDQWdJQ0FuYzNSbGNGZ25PaUF3TEZ4dUlDQWdJQ0FnSjNnbk9pQXdMalVzWEc0Z0lDQWdJQ0FuYldsdVdTYzZJREFzWEc0Z0lDQWdJQ0FuYldGNFdTYzZJREVzWEc0Z0lDQWdJQ0FuYzNSbGNGa25PaUF3TEZ4dUlDQWdJQ0FnSjNrbk9pQXdMalZjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdjM1Z3WlhJb1lYSm5kVzFsYm5SekxHOXdkR2x2Ym5Nc1pHVm1ZWFZzZEhNcE8xeHVYRzVjYmlBZ0lDQjBhR2x6TGw5NElEMGdibVYzSUZOMFpYQW9JSFJvYVhNdWMyVjBkR2x1WjNNdWJXbHVXQ3dnZEdocGN5NXpaWFIwYVc1bmN5NXRZWGhZTENCMGFHbHpMbk5sZEhScGJtZHpMbk4wWlhCWUxDQjBhR2x6TG5ObGRIUnBibWR6TG5nZ0tUdGNiaUFnSUNCMGFHbHpMbDk1SUQwZ2JtVjNJRk4wWlhBb0lIUm9hWE11YzJWMGRHbHVaM011YldsdVdTd2dkR2hwY3k1elpYUjBhVzVuY3k1dFlYaFpMQ0IwYUdsekxuTmxkSFJwYm1kekxuTjBaWEJaTENCMGFHbHpMbk5sZEhScGJtZHpMbmtnS1R0Y2JseHVJQ0FnSUhSb2FYTXVjRzl6YVhScGIyNGdQU0I3WEc0Z0lDQWdJQ0I0T2lCdVpYY2dTVzUwWlhKaFkzUnBiMjR1U0dGdVpHeGxLSFJvYVhNdWMyVjBkR2x1WjNNdWJXOWtaU3duYUc5eWFYcHZiblJoYkNjc1d6QXNkR2hwY3k1M2FXUjBhRjBzVzNSb2FYTXVhR1ZwWjJoMExEQmRLU3hjYmlBZ0lDQWdJSGs2SUc1bGR5QkpiblJsY21GamRHbHZiaTVJWVc1a2JHVW9kR2hwY3k1elpYUjBhVzVuY3k1dGIyUmxMQ2QyWlhKMGFXTmhiQ2NzV3pBc2RHaHBjeTUzYVdSMGFGMHNXM1JvYVhNdWFHVnBaMmgwTERCZEtWeHVJQ0FnSUgwN1hHNGdJQ0FnZEdocGN5NXdiM05wZEdsdmJpNTRMblpoYkhWbElEMGdkR2hwY3k1ZmVDNXViM0p0WVd4cGVtVmtPMXh1SUNBZ0lIUm9hWE11Y0c5emFYUnBiMjR1ZVM1MllXeDFaU0E5SUhSb2FYTXVYM2t1Ym05eWJXRnNhWHBsWkR0Y2JseHVJQ0FnSUhSb2FYTXVhVzVwZENncE8xeHVJQ0FnSUhSb2FYTXVjbVZ1WkdWeUtDazdYRzVjYmlBZ2ZWeHVYRzRnSUdKMWFXeGtTVzUwWlhKbVlXTmxLQ2tnZTF4dVhHNGdJQ0FnZEdocGN5NXJibTlpSUQwZ2MzWm5MbU55WldGMFpTZ25ZMmx5WTJ4bEp5azdYRzRnSUNBZ2RHaHBjeTVsYkdWdFpXNTBMbUZ3Y0dWdVpFTm9hV3hrS0hSb2FYTXVhMjV2WWlrN1hHNGdJQ0FnWEc0Z0lIMWNibHh1SUNCemFYcGxTVzUwWlhKbVlXTmxLQ2tnZTF4dVhHNGdJQ0FnSUNCMGFHbHpMbkJ2YzJsMGFXOXVMbmd1Y21WemFYcGxLRnN3TEhSb2FYTXVkMmxrZEdoZExGdDBhR2x6TG1obGFXZG9kQ3d3WFNrN1hHNGdJQ0FnSUNCMGFHbHpMbkJ2YzJsMGFXOXVMbmt1Y21WemFYcGxLRnN3TEhSb2FYTXVkMmxrZEdoZExGdDBhR2x6TG1obGFXZG9kQ3d3WFNrN1hHNWNiaUFnSUNBZ0lIUm9hWE11WDIxcGJrUnBiV1Z1YzJsdmJpQTlJRTFoZEdndWJXbHVLSFJvYVhNdWQybGtkR2dzZEdocGN5NW9aV2xuYUhRcE8xeHVYRzRnSUNBZ0lDQjBhR2x6TG10dWIySlNZV1JwZFhNZ1BTQjdYRzRnSUNBZ0lDQWdJRzltWmpvZ2ZuNG9kR2hwY3k1ZmJXbHVSR2x0Wlc1emFXOXVMekV3TUNrZ0tpQTFJQ3NnTlN4Y2JpQWdJQ0FnSUgwN1hHNGdJQ0FnSUNCMGFHbHpMbXR1YjJKU1lXUnBkWE11YjI0Z1BTQjBhR2x6TG10dWIySlNZV1JwZFhNdWIyWm1JQ29nTWp0Y2JseHVJQ0FnSUNBZ2RHaHBjeTVyYm05aUxuTmxkRUYwZEhKcFluVjBaU2duWTNnbkxIUm9hWE11ZDJsa2RHZ3ZNaWs3WEc0Z0lDQWdJQ0IwYUdsekxtdHViMkl1YzJWMFFYUjBjbWxpZFhSbEtDZGplU2NzZEdocGN5NW9aV2xuYUhRdk1pazdYRzRnSUNBZ0lDQjBhR2x6TG10dWIySXVjMlYwUVhSMGNtbGlkWFJsS0NkeUp5eDBhR2x6TG10dWIySlNZV1JwZFhNdWIyWm1LVHRjYmlBZ2ZWeHVYRzRnSUdOdmJHOXlTVzUwWlhKbVlXTmxLQ2tnZTF4dUlDQWdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExuTjBlV3hsTG1KaFkydG5jbTkxYm1SRGIyeHZjaUE5SUhSb2FYTXVZMjlzYjNKekxtWnBiR3c3WEc0Z0lDQWdJQ0IwYUdsekxtdHViMkl1YzJWMFFYUjBjbWxpZFhSbEtDZG1hV3hzSnl3Z2RHaHBjeTVqYjJ4dmNuTXVZV05qWlc1MEtUdGNiaUFnZlZ4dVhHNGdJSEpsYm1SbGNpZ3BJSHRjYmlBZ0lDQnBaaUFvZEdocGN5NWpiR2xqYTJWa0tTQjdYRzRnSUNBZ0x5OGdJSFJvYVhNdWEyNXZZbEpoWkdsMWN5QTlJRE13TzF4dUlDQWdJQ0FnZEdocGN5NXJibTlpTG5ObGRFRjBkSEpwWW5WMFpTZ25jaWNzZEdocGN5NXJibTlpVW1Ga2FYVnpMbTl1S1R0Y2JpQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDOHZJQ0IwYUdsekxtdHViMkpTWVdScGRYTWdQU0F4TlR0Y2JpQWdJQ0FnSUhSb2FYTXVhMjV2WWk1elpYUkJkSFJ5YVdKMWRHVW9KM0luTEhSb2FYTXVhMjV2WWxKaFpHbDFjeTV2Wm1ZcE8xeHVJQ0FnSUgxY2JseHVJQ0FnSUhSb2FYTXVhMjV2WWtOdmIzSmthVzVoZEdWeklEMGdlMXh1SUNBZ0lDQWdlRG9nZEdocGN5NWZlQzV1YjNKdFlXeHBlbVZrSUNvZ2RHaHBjeTUzYVdSMGFDeGNiaUFnSUNBZ0lIazZJSFJvYVhNdWFHVnBaMmgwSUMwZ2RHaHBjeTVmZVM1dWIzSnRZV3hwZW1Wa0lDb2dkR2hwY3k1b1pXbG5hSFJjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdkR2hwY3k1cmJtOWlMbk5sZEVGMGRISnBZblYwWlNnblkzZ25MSFJvYVhNdWEyNXZZa052YjNKa2FXNWhkR1Z6TG5ncE8xeHVJQ0FnSUhSb2FYTXVhMjV2WWk1elpYUkJkSFJ5YVdKMWRHVW9KMk41Snl4MGFHbHpMbXR1YjJKRGIyOXlaR2x1WVhSbGN5NTVLVHRjYmlBZ2ZWeHVYRzVjYmlBZ1kyeHBZMnNvS1NCN1hHNGdJQ0FnZEdocGN5NXdiM05wZEdsdmJpNTRMbUZ1WTJodmNpQTlJSFJvYVhNdWJXOTFjMlU3WEc0Z0lDQWdkR2hwY3k1d2IzTnBkR2x2Ymk1NUxtRnVZMmh2Y2lBOUlIUm9hWE11Ylc5MWMyVTdYRzRnSUNBZ2RHaHBjeTV0YjNabEtDazdYRzRnSUgxY2JseHVJQ0J0YjNabEtDa2dlMXh1SUNBZ0lHbG1JQ2gwYUdsekxtTnNhV05yWldRcElIdGNiaUFnSUNBZ0lIUm9hWE11Y0c5emFYUnBiMjR1ZUM1MWNHUmhkR1VvZEdocGN5NXRiM1Z6WlNrN1hHNGdJQ0FnSUNCMGFHbHpMbkJ2YzJsMGFXOXVMbmt1ZFhCa1lYUmxLSFJvYVhNdWJXOTFjMlVwTzF4dUlDQWdJQ0FnZEdocGN5NWZlQzUxY0dSaGRHVk9iM0p0WVd3b0lIUm9hWE11Y0c5emFYUnBiMjR1ZUM1MllXeDFaU0FwTzF4dUlDQWdJQ0FnZEdocGN5NWZlUzUxY0dSaGRHVk9iM0p0WVd3b0lIUm9hWE11Y0c5emFYUnBiMjR1ZVM1MllXeDFaU0FwTzF4dUlDQWdJQ0FnZEdocGN5NWxiV2wwS0NkamFHRnVaMlVuTEh0Y2JpQWdJQ0FnSUNBZ2VEb2dkR2hwY3k1ZmVDNTJZV3gxWlN4Y2JpQWdJQ0FnSUNBZ2VUb2dkR2hwY3k1ZmVTNTJZV3gxWlZ4dUlDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNCMGFHbHpMbkpsYm1SbGNpZ3BPMXh1SUNBZ0lIMWNiaUFnZlZ4dVhHNGdJSEpsYkdWaGMyVW9LU0I3WEc0Z0lDQWdkR2hwY3k1eVpXNWtaWElvS1R0Y2JpQWdmVnh1WEc0Z0lDOHFLbHh1SUNBcUlGUm9aU0JwYm5SbGNtWmhZMlVuY3lCNElIWmhiSFZsTGlCWGFHVnVJSE5sZEN3Z2FYUWdkMmxzYkNCaGRYUnZiV0YwYVdOaGJHeDVJR0ZrYW5WemRDQjBieUJtYVhRZ2JXbHVMMjFoZUM5emRHVndJSE5sZEhScGJtZHpJRzltSUhSb1pTQnBiblJsY21aaFkyVXVYRzRnSUNvZ1FIUjVjR1VnZTI5aWFtVmpkSDFjYmlBZ0tpQkFaWGhoYlhCc1pTQndiM05wZEdsdmJpNTRJRDBnTUM0MU8xeHVJQ0FxTDF4dVhHNGdJR2RsZENCNEtDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbDk0TG5aaGJIVmxPMXh1SUNCOVhHNWNiaUFnYzJWMElIZ29kbUZzZFdVcElIdGNiaUFnSUNCMGFHbHpMbDk0TG5Wd1pHRjBaU2gyWVd4MVpTazdYRzRnSUNBZ2RHaHBjeTVsYldsMEtDZGphR0Z1WjJVbkxIdGNiaUFnSUNBZ0lIZzZJSFJvYVhNdVgzZ3VkbUZzZFdVc1hHNGdJQ0FnSUNCNU9pQjBhR2x6TGw5NUxuWmhiSFZsWEc0Z0lDQWdmU2s3WEc0Z0lDQWdkR2hwY3k1eVpXNWtaWElvS1R0Y2JpQWdmVnh1WEc0Z0lDOHFLbHh1SUNBcUlGUm9aU0JwYm5SbGNtWmhZMlVuY3lCNUlIWmhiSFZsY3k0Z1YyaGxiaUJ6WlhRc0lHbDBJSGRwYkd3Z1lYVjBiMjFoZEdsallXeHNlU0JoWkdwMWMzUWdkRzhnWm1sMElHMXBiaTl0WVhndmMzUmxjQ0J6WlhSMGFXNW5jeUJ2WmlCMGFHVWdhVzUwWlhKbVlXTmxMbHh1SUNBcUlFQjBlWEJsSUh0dlltcGxZM1I5WEc0Z0lDb2dRR1Y0WVcxd2JHVWdjRzl6YVhScGIyNHVlQ0E5SURBdU5UdGNiaUFnS2k5Y2JseHVJQ0JuWlhRZ2VTZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVmZVM1MllXeDFaVHRjYmlBZ2ZWeHVYRzRnSUhObGRDQjVLSFpoYkhWbEtTQjdYRzRnSUNBZ2RHaHBjeTVmZVM1MWNHUmhkR1VvZG1Gc2RXVXBPMXh1SUNBZ0lIUm9hWE11WlcxcGRDZ25ZMmhoYm1kbEp5eDdYRzRnSUNBZ0lDQjRPaUIwYUdsekxsOTRMblpoYkhWbExGeHVJQ0FnSUNBZ2VUb2dkR2hwY3k1ZmVTNTJZV3gxWlZ4dUlDQWdJSDBwTzF4dUlDQWdJSFJvYVhNdWNtVnVaR1Z5S0NrN1hHNGdJSDFjYmx4dVhHNWNiaUFnWjJWMElHNXZjbTFoYkdsNlpXUW9LU0I3WEc0Z0lDQWdjbVYwZFhKdUlIdGNiaUFnSUNBZ0lIZzZJSFJvYVhNdVgzZ3VibTl5YldGc2FYcGxaQ3hjYmlBZ0lDQWdJSGs2SUhSb2FYTXVYM2t1Ym05eWJXRnNhWHBsWkZ4dUlDQWdJSDA3WEc0Z0lIMWNibHh1SUNBdktpcGNiaUFnS2lCVWFHVWdiRzkzWlhJZ2JHbHRhWFFnYjJZZ2RtRnNkV1VnYjI0Z2RHaGxJSGdnWVhocGMxeHVJQ0FxSUVCMGVYQmxJSHR2WW1wbFkzUjlYRzRnSUNvdlhHNGdJR2RsZENCdGFXNVlLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TGw5NExtMXBianRjYmlBZ2ZWeHVYRzRnSUhObGRDQnRhVzVZS0hZcElIdGNiaUFnSUNCMGFHbHpMbDk0TG0xcGJpQTlJSFk3WEc0Z0lDQWdkR2hwY3k1eVpXNWtaWElvS1R0Y2JpQWdmVnh1WEc0Z0lDOHFLbHh1SUNBcUlGUm9aU0JzYjNkbGNpQnNhVzFwZENCdlppQjJZV3gxWlNCdmJpQjBhR1VnZVNCaGVHbHpYRzRnSUNvZ1FIUjVjR1VnZTI5aWFtVmpkSDFjYmlBZ0tpOWNiaUFnWjJWMElHMXBibGtvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdVgza3ViV2x1TzF4dUlDQjlYRzVjYmlBZ2MyVjBJRzFwYmxrb2Rpa2dlMXh1SUNBZ0lIUm9hWE11WDNrdWJXbHVJRDBnZGp0Y2JpQWdJQ0IwYUdsekxuSmxibVJsY2lncE8xeHVJQ0I5WEc1Y2JseHVJQ0F2S2lwY2JpQWdLaUJVYUdVZ2RYQndaWElnYkdsdGFYUWdiMllnZG1Gc2RXVWdiMjRnZEdobElIZ2dZWGhwYzF4dUlDQXFJRUIwZVhCbElIdHZZbXBsWTNSOVhHNGdJQ292WEc0Z0lHZGxkQ0J0WVhoWUtDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbDk0TG0xaGVEdGNiaUFnZlZ4dVhHNGdJSE5sZENCdFlYaFlLSFlwSUh0Y2JpQWdJQ0IwYUdsekxsOTRMbTFoZUNBOUlIWTdYRzRnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmlBZ2ZWeHVYRzVjYmlBZ0x5b3FYRzRnSUNvZ1ZHaGxJSFZ3Y0dWeUlHeHBiV2wwSUc5bUlIWmhiSFZsSUc5dUlIUm9aU0I1SUdGNGFYTmNiaUFnS2lCQWRIbHdaU0I3YjJKcVpXTjBmVnh1SUNBcUwxeHVJQ0JuWlhRZ2JXRjRXU2dwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1ZmVTNXRZWGc3WEc0Z0lIMWNibHh1SUNCelpYUWdiV0Y0V1NoMktTQjdYRzRnSUNBZ2RHaHBjeTVmZVM1dFlYZ2dQU0IyTzF4dUlDQWdJSFJvYVhNdWNtVnVaR1Z5S0NrN1hHNGdJSDFjYmx4dVhHNGdJQzhxS2x4dUlDQXFJRlJvWlNCcGJtTnlaVzFsYm5SaGJDQnpkR1Z3SUc5bUlIWmhiSFZsY3lCdmJpQjBhR1VnZUNCaGVHbHpYRzRnSUNvZ1FIUjVjR1VnZTI5aWFtVmpkSDFjYmlBZ0tpOWNiaUFnWjJWMElITjBaWEJZS0NrZ2UxeHVJQ0FnSUhKbGRIVnliaUIwYUdsekxsOTRMbk4wWlhBN1hHNGdJSDFjYmx4dUlDQnpaWFFnYzNSbGNGZ29kaWtnZTF4dUlDQWdJSFJvYVhNdVgzZ3VjM1JsY0NBOUlIWTdYRzRnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmlBZ2ZWeHVYRzVjYmlBZ0x5b3FYRzRnSUNvZ1ZHaGxJR2x1WTNKbGJXVnVkR0ZzSUhOMFpYQWdiMllnZG1Gc2RXVnpJRzl1SUhSb1pTQjVJR0Y0YVhOY2JpQWdLaUJBZEhsd1pTQjdiMkpxWldOMGZWeHVJQ0FxTDF4dUlDQm5aWFFnYzNSbGNGa29LU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11WDNrdWMzUmxjRHRjYmlBZ2ZWeHVYRzRnSUhObGRDQnpkR1Z3V1NoMktTQjdYRzRnSUNBZ2RHaHBjeTVmZVM1emRHVndJRDBnZGp0Y2JpQWdJQ0IwYUdsekxuSmxibVJsY2lncE8xeHVJQ0I5WEc1Y2JseHVJQ0F2S2lwY2JpQWdRV0p6YjJ4MWRHVWdiVzlrWlNBb2NHOXphWFJwYjI0bmN5QjJZV3gxWlNCcWRXMXdjeUIwYnlCdGIzVnpaU0JqYkdsamF5QndiM05wZEdsdmJpa2diM0lnY21Wc1lYUnBkbVVnYlc5a1pTQW9iVzkxYzJVZ1pISmhaeUJqYUdGdVoyVnpJSFpoYkhWbElISmxiR0YwYVhabElIUnZJR2wwY3lCamRYSnlaVzUwSUhCdmMybDBhVzl1S1M0Z1JHVm1ZWFZzZERvZ1hDSmhZbk52YkhWMFpWd2lMbHh1SUNCQWRIbHdaU0I3YzNSeWFXNW5mVnh1SUNCQVpYaGhiWEJzWlNCd2IzTnBkR2x2Ymk1dGIyUmxJRDBnWENKeVpXeGhkR2wyWlZ3aU8xeHVJQ0FxTDF4dUlDQm5aWFFnYlc5a1pTZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTV3YjNOcGRHbHZiaTU0TG0xdlpHVTdYRzRnSUgxY2JpQWdjMlYwSUcxdlpHVW9kaWtnZTF4dUlDQWdJSFJvYVhNdWNHOXphWFJwYjI0dWVDNXRiMlJsSUQwZ2RqdGNiaUFnSUNCMGFHbHpMbkJ2YzJsMGFXOXVMbmt1Ylc5a1pTQTlJSFk3WEc0Z0lIMWNibHh1WEc1Y2JseHVmVnh1WEc1Y2JseHVMeThnVjBWQ1VFRkRTeUJHVDA5VVJWSWdMeTljYmk4dklDNHZmaTlxYzJocGJuUXRiRzloWkdWeUlTNHZiR2xpTDJsdWRHVnlabUZqWlhNdmNHOXphWFJwYjI0dWFuTWlMQ0luZFhObElITjBjbWxqZENjN1hHNWNibXhsZENCdFlYUm9JRDBnY21WeGRXbHlaU2duTGk0dmRYUnBiQzl0WVhSb0p5azdYRzVjYm1WNGNHOXlkQ0JrWldaaGRXeDBJSHRjYmx4dUlDQmpjbVZoZEdVNklDaDBlWEJsS1NBOVBpQjdYRzRnSUNBZ2NtVjBkWEp1SUdSdlkzVnRaVzUwTG1OeVpXRjBaVVZzWlcxbGJuUk9VeWduYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNuTENCMGVYQmxLVHRjYmlBZ2ZTeGNibHh1SUNCaGNtTTZJQ2g0TENCNUxDQnlZV1JwZFhNc0lITjBZWEowUVc1bmJHVXNJR1Z1WkVGdVoyeGxLU0E5UGlCN1hHNWNiaUFnSUNCMllYSWdjM1JoY25RZ1BTQnRZWFJvTG5SdlEyRnlkR1Z6YVdGdUtISmhaR2wxY3l3Z1pXNWtRVzVuYkdVcE8xeHVJQ0FnSUhaaGNpQmxibVFnUFNCdFlYUm9MblJ2UTJGeWRHVnphV0Z1S0hKaFpHbDFjeXdnYzNSaGNuUkJibWRzWlNrN1hHNWNiaUFnSUNCMllYSWdiR0Z5WjJWQmNtTkdiR0ZuSUQwZ1pXNWtRVzVuYkdVZ0xTQnpkR0Z5ZEVGdVoyeGxJRHc5SURFNE1DQS9JQ2N3SnlBNklDY3hKenRjYmx4dUlDQWdJSFpoY2lCa0lEMGdXMXh1SUNBZ0lDQWdJQ0FuVFNjc0lITjBZWEowTG5ncmVDd2djM1JoY25RdWVTdDVMRnh1SUNBZ0lDQWdJQ0FuUVNjc0lISmhaR2wxY3l3Z2NtRmthWFZ6TENBd0xDQnNZWEpuWlVGeVkwWnNZV2NzSURBc0lHVnVaQzU0SzNnc0lHVnVaQzU1SzNsY2JpQWdJQ0JkTG1wdmFXNG9KeUFuS1R0Y2JseHVJQ0FnSUhKbGRIVnliaUJrTzF4dUlDQjlMRnh1WEc0Z0lISmhaR2xoYkVkeVlXUnBaVzUwT2lBb1pHVm1jeXh1ZFcxaVpYSlBabE4wYjNCektTQTlQaUI3WEc1Y2JpQWdJQ0JzWlhRZ2FXUWdQU0FuWjNKaFpHbGxiblFuSUNzZ2JXRjBhQzV5YVNneE1EQXdNREF3TURBd01EQXBPMXh1SUNBZ0lHeGxkQ0J6ZEc5d2N5QTlJRnRkTzF4dVhHNGdJQ0FnYkdWMElHZHlZV1JwWlc1MElEMGdaRzlqZFcxbGJuUXVZM0psWVhSbFJXeGxiV1Z1ZEU1VEtDZG9kSFJ3T2k4dmQzZDNMbmN6TG05eVp5OHlNREF3TDNOMlp5Y3NJQ2R5WVdScFlXeEhjbUZrYVdWdWRDY3BPMXh1SUNBZ0lHZHlZV1JwWlc1MExuTmxkRUYwZEhKcFluVjBaU2duYVdRbkxDQnBaQ2s3WEc0Z0lDQWdaM0poWkdsbGJuUXVjMlYwUVhSMGNtbGlkWFJsS0NkamVDY3NJQ2MxTUNVbktUdGNiaUFnSUNCbmNtRmthV1Z1ZEM1elpYUkJkSFJ5YVdKMWRHVW9KMk41Snl3Z0p6VXdKU2NwTzF4dUlDQWdJR2R5WVdScFpXNTBMbk5sZEVGMGRISnBZblYwWlNnbmNpY3NJQ2MxTUNVbktUdGNibHh1SUNBZ0lHUmxabk11WVhCd1pXNWtRMmhwYkdRb1ozSmhaR2xsYm5RcE8xeHVYRzRnSUNBZ1ptOXlJQ2hzWlhRZ2FUMHdPMms4Ym5WdFltVnlUMlpUZEc5d2N6dHBLeXNwSUh0Y2JpQWdJQ0FnSUd4bGRDQnpkRzl3SUQwZ1pHOWpkVzFsYm5RdVkzSmxZWFJsUld4bGJXVnVkRTVUS0Nkb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnljc0lDZHpkRzl3SnlrN1hHNGdJQ0FnSUNCemRHOXdMbk5sZEVGMGRISnBZblYwWlNnbmFXUW5MQ0FuYzNSdmNDY3JhU2s3WEc0Z0lDQWdJQ0F2TDNOMGIzQXVjMlYwUVhSMGNtbGlkWFJsS0NkdlptWnpaWFFuTENBbk56QWxKeWs3WEc0Z0lDQWdJQ0F2TDNOMGIzQXVjMlYwUVhSMGNtbGlkWFJsS0NkemRHOXdMV052Ykc5eUp5d2dKMWRvYVhSbEp5azdYRzRnSUNBZ0lDQm5jbUZrYVdWdWRDNWhjSEJsYm1SRGFHbHNaQ2h6ZEc5d0tUdGNiaUFnSUNBZ0lITjBiM0J6TG5CMWMyZ29jM1J2Y0NrN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnY21WMGRYSnVJSHRjYmlBZ0lDQWdJR2xrT2lCcFpDeGNiaUFnSUNBZ0lITjBiM0J6T2lCemRHOXdjeXhjYmlBZ0lDQWdJR1ZzWlcxbGJuUTZJR2R5WVdScFpXNTBYRzRnSUNBZ2ZUdGNibHh1SUNCOVhHNWNibjA3WEc1Y2JseHVYRzR2THlCWFJVSlFRVU5MSUVaUFQxUkZVaUF2TDF4dUx5OGdMaTkrTDJwemFHbHVkQzFzYjJGa1pYSWhMaTlzYVdJdmRYUnBiQzl6ZG1jdWFuTWlMQ0luZFhObElITjBjbWxqZENjN1hHNWNiaThxS2x4dUlDb2dUR2x0YVhRZ1lTQnVkVzFpWlhJZ2RHOGdkMmwwYUdsdUlHRWdiV2x1YVcxMWJTQmhibVFnYldGNGFXMTFiVnh1SUNvZ1FIQmhjbUZ0SUNCN2JuVnRZbVZ5ZlNCMllXeDFaU0JKYm5CMWRDQjJZV3gxWlZ4dUlDb2dRSEJoY21GdElDQjdiblZ0WW1WeWZTQnRhVzRnSUNCTWIzZGxjaUJzYVcxcGRGeHVJQ29nUUhCaGNtRnRJQ0I3Ym5WdFltVnlmU0J0WVhnZ0lDQlZjSEJsY2lCc2FXMXBkRnh1SUNvZ1FISmxkSFZ5YmlCN2JuVnRZbVZ5ZlNBZ0lDQWdJQ0JVYUdVZ2FXNXdkWFFnZG1Gc2RXVWdZMjl1YzNSeVlXbHVaV1FnZDJsMGFHbHVJSFJvWlNCc2IzZGxjaUJoYm1RZ2RYQndaWElnYkdsdGFYUnpYRzRnS2lCQVpYaGhiWEJzWlZ4dUlDb2dUbVY0ZFhNdVkyeHBjQ2d4TVN3d0xERXdLU0FnSUM4dklISmxkSFZ5Ym5NZ01UQmNiaUFxSUU1bGVIVnpMbU5zYVhBb0xURXNNQ3d4TUNrZ0lDQXZMeUJ5WlhSMWNtNXpJREJjYmlBcUlFNWxlSFZ6TG1Oc2FYQW9OU3d3TERFd0tTQWdJQ0F2THlCeVpYUjFjbTV6SURWY2JpQXFMMXh1WEc1bGVIQnZjblJ6TG1Oc2FYQWdQU0FvZG1Gc2RXVXNiV2x1TEcxaGVDa2dQVDRnZTF4dUlDQnlaWFIxY200Z1RXRjBhQzV0YVc0b1RXRjBhQzV0WVhnb2RtRnNkV1VzYldsdUtTeHRZWGdwTzF4dWZUdGNibHh1Wlhod2IzSjBjeTV1YjNKdFlXeHBlbVVnUFNBb2RtRnNkV1VzYldsdUxHMWhlQ2tnUFQ0Z2UxeHVJQ0J5WlhSMWNtNGdLQ0FvZG1Gc2RXVXRiV2x1S1NBdklDaHRZWGd0YldsdUtTQXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlRZMkZzWlNCaElIWmhiSFZsSUdaeWIyMGdiMjVsSUhKaGJtZGxJSFJ2SUdGdWIzUm9aWElnY21GdVoyVXVYRzRnS2lCQWNHRnlZVzBnSUh0dWRXMWlaWEo5SUdsdVRuVnRJQ0JKYm5CMWRDQjJZV3gxWlZ4dUlDb2dRSEJoY21GdElDQjdiblZ0WW1WeWZTQnBiazFwYmlBZ1NXNXdkWFFnY21GdVoyVWdiV2x1YVcxMWJWeHVJQ29nUUhCaGNtRnRJQ0I3Ym5WdFltVnlmU0JwYmsxaGVDQWdTVzV3ZFhRZ2NtRnVaMlVnYldGNGFXMTFiVnh1SUNvZ1FIQmhjbUZ0SUNCN2JuVnRZbVZ5ZlNCdmRYUk5hVzRnVDNWMGNIVjBJSEpoYm1kbElHMXBibWx0ZFcxY2JpQXFJRUJ3WVhKaGJTQWdlMjUxYldKbGNuMGdiM1YwVFdGNElFOTFkSEIxZENCeVlXNW5aU0J0WVhocGJYVnRYRzRnS2lCQWNtVjBkWEp1SUh0dWRXMWlaWEo5SUNBZ0lDQWdJQ0JVYUdVZ2FXNXdkWFFnZG1Gc2RXVWdjMk5oYkdWa0lIUnZJR2wwY3lCdVpYY2djbUZ1WjJWY2JpQXFJRUJsZUdGdGNHeGxYRzRnS2lCT1pYaDFjeTV6WTJGc1pTZ3dMalVzTUN3eExEQXNNVEFwSUNBZ0x5OGdjbVYwZFhKdWN5QTFYRzRnS2lCT1pYaDFjeTV6WTJGc1pTZ3dMamtzTUN3eExERXNNQ2tnSUNBZ0x5OGdjbVYwZFhKdWN5QXdMakZjYmlBcUwxeHVaWGh3YjNKMGN5NXpZMkZzWlNBOUlDaHBiazUxYlN3Z2FXNU5hVzRzSUdsdVRXRjRMQ0J2ZFhSTmFXNHNJRzkxZEUxaGVDa2dQVDRnZTF4dUlDQnBaaUFvYVc1TmFXNGdQVDA5SUdsdVRXRjRLU0I3WEc0Z0lDQWdjbVYwZFhKdUlHOTFkRTFwYmp0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnS0Nnb2FXNU9kVzBnTFNCcGJrMXBiaWtnS2lBb2IzVjBUV0Y0SUMwZ2IzVjBUV2x1S1NrZ0x5QW9hVzVOWVhnZ0xTQnBiazFwYmlrcElDc2diM1YwVFdsdU8xeHVmVHRjYmx4dVpYaHdiM0owY3k1MGIxQnZiR0Z5SUQwZ0tIZ3NlU2tnUFQ0Z2UxeHVJQ0IyWVhJZ2NpQTlJRTFoZEdndWMzRnlkQ2g0S25nZ0t5QjVLbmtwTzF4dVhHNGdJSFpoY2lCMGFHVjBZU0E5SUUxaGRHZ3VZWFJoYmpJb2VTeDRLVHRjYmlBZ2FXWWdLSFJvWlhSaElEd2dNQ2tnZTF4dUlDQWdJSFJvWlhSaElEMGdkR2hsZEdFZ0t5QW9NaUFxSUUxaGRHZ3VVRWtwTzF4dUlDQjlYRzRnSUhKbGRIVnliaUI3Y21Ga2FYVnpPaUJ5TENCaGJtZHNaVG9nZEdobGRHRjlPMXh1ZlR0Y2JseHVaWGh3YjNKMGN5NTBiME5oY25SbGMybGhiaUE5SUdaMWJtTjBhVzl1S0hKaFpHbDFjeXdnWVc1bmJHVXBlMXh1SUNCMllYSWdZMjl6SUQwZ1RXRjBhQzVqYjNNb1lXNW5iR1VwTzF4dUlDQjJZWElnYzJsdUlEMGdUV0YwYUM1emFXNG9ZVzVuYkdVcE8xeHVJQ0J5WlhSMWNtNGdlM2c2SUhKaFpHbDFjeXBqYjNNc0lIazZJSEpoWkdsMWN5cHphVzRxTFRGOU8xeHVmVHRjYmk4cVhHNWxlSEJ2Y25SekxuQnZiR0Z5Vkc5RFlYSjBaWE5wWVc0b1kyVnVkR1Z5V0N3Z1kyVnVkR1Z5V1N3Z2NtRmthWFZ6TENCaGJtZHNaVWx1UkdWbmNtVmxjeWtnZTF4dUlDQjJZWElnWVc1bmJHVkpibEpoWkdsaGJuTWdQU0FvWVc1bmJHVkpia1JsWjNKbFpYTXRPVEFwSUNvZ1RXRjBhQzVRU1NBdklERTRNQzR3TzF4dVhHNGdJSEpsZEhWeWJpQjdYRzRnSUNBZ2VEb2dZMlZ1ZEdWeVdDQXJJQ2h5WVdScGRYTWdLaUJOWVhSb0xtTnZjeWhoYm1kc1pVbHVVbUZrYVdGdWN5a3BMRnh1SUNBZ0lIazZJR05sYm5SbGNsa2dLeUFvY21Ga2FYVnpJQ29nVFdGMGFDNXphVzRvWVc1bmJHVkpibEpoWkdsaGJuTXBLVnh1SUNCOU8xeHVmU0FnS2k5Y2JseHVYRzVjYm1WNGNHOXlkSE11Y0hKMWJtVWdQU0JtZFc1amRHbHZiaWhrWVhSaExDQnpZMkZzWlNrZ2UxeHVJQ0J5WlhSMWNtNGdjR0Z5YzJWR2JHOWhkQ2hrWVhSaExuUnZSbWw0WldRb2MyTmhiR1VwS1R0Y2JuMDdYRzVjYm1WNGNHOXlkSE11YVc1MlpYSjBJRDBnWm5WdVkzUnBiMjRnS0dsdVRuVnRLU0I3WEc0Z0lISmxkSFZ5YmlCbGVIQnZjblJ6TG5OallXeGxLR2x1VG5WdExDQXhMQ0F3TENBd0xDQXhLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dRMjl1ZG1WeWRDQmhJRTFKUkdrZ2JtOTBaU0J1ZFcxaVpYSWdkRzhnWVNCbWNtVnhkV1Z1WTNrZ2RtRnNkV1VnYVc0Z1pYRjFZV3dnZEdWdGNHVnlZVzFsYm5RdVhHNGdLaUJBY0dGeVlXMGdJSHR1ZFcxaVpYSjlJRzFwWkdrZ1RVbEVTU0J1YjNSbElIWmhiSFZsWEc0Z0tpQkFjbVYwZFhKdUlIdHVkVzFpWlhKOUlDQWdJQ0FnUm5KbGNYVmxibU5sSUhaaGJIVmxYRzRnS2lCQVpYaGhiWEJzWlZ4dUlDb2dUbVY0ZFhNdWJYUnZaaWcyTUNrZ0lDOHZJSEpsZEhWeWJuTWdkR2hsSUdaeVpYRjFaVzVqZVNCdWRXMWlaWElnYjJZZ1RXbGtaR3hsSUVOY2JpQXFMMXh1Wlhod2IzSjBjeTV0ZEc5bUlEMGdablZ1WTNScGIyNG9iV2xrYVNrZ2UxeHVJQ0J5WlhSMWNtNGdUV0YwYUM1d2IzY29NaXdnS0NodGFXUnBMVFk1S1M4eE1pa3BJQ29nTkRRd08xeHVmVHRjYmx4dUx5b3FYRzRnS2lCSmJuUmxjbkJ2YkdGMFpTQmlaWFIzWldWdUlIUjNieUJ1ZFcxaVpYSnpYRzRnS2lCQWNHRnlZVzBnSUh0dWRXMWlaWEo5SUd4dll5QkpiblJsY25CdmJHRjBhVzl1SUdsdVpHVjRJQ2d3TFRFcFhHNGdLaUJBY0dGeVlXMGdJSHR1ZFcxaVpYSjlJRzFwYmlCTWIzZGxjaUIyWVd4MVpWeHVJQ29nUUhCaGNtRnRJQ0I3Ym5WdFltVnlmU0J0WVhnZ1ZYQndaWElnZG1Gc2RXVmNiaUFxSUVCeVpYUjFjbTRnZTI1MWJXSmxjbjBnSUNBZ0lFbHVkR1Z5Y0c5c1lYUmxaQ0IyWVd4MVpWeHVJQ29nUUdWNFlXMXdiR1ZjYmlBcUlFNWxlSFZ6TG1sdWRHVnljQ2d3TGpVc01pdzBLU0FnSUM4dklISmxkSFZ5Ym5NZ00xeHVJQ29nVG1WNGRYTXVhVzUwWlhKd0tEQXVNU3d3TERFd0tTQWdJQ0FnTHk4Z2NtVjBkWEp1Y3lBeFhHNGdLaTljYm1WNGNHOXlkSE11YVc1MFpYSndJRDBnWm5WdVkzUnBiMjRvYkc5akxHMXBiaXh0WVhncElIdGNiaUFnY21WMGRYSnVJR3h2WXlBcUlDaHRZWGdnTFNCdGFXNHBJQ3NnYldsdU8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCU1pYUjFjbTRnWVNCeVlXNWtiMjBnWTJodmFXTmxJR1p5YjIwZ1lTQnNhWE4wSUc5bUlHRnlaM1Z0Wlc1MGMxeHVJQ29nUUhKbGRIVnliaUI3ZG1GeWFXOTFjMzBnVDI1bElISmhibVJ2YlNCaGNtZDFiV1Z1ZEZ4dUlDb2dRR1Y0WVcxd2JHVmNiaUFxSUU1bGVIVnpMbkJwWTJzb01Td3lMRE1zTkNrZ0lDQXZMeUJ5WlhSMWNtNXpJREVzSURJc0lETXNJRzl5SURSY2JpQXFJRTVsZUhWekxuQnBZMnNvWm5WdVkzUnBiMjR4TEdaMWJtTjBhVzl1TWlrZ0lDQXZMeUJ5WlhSMWNtNXpJR1ZwZEdobGNpQm1kVzVqZEdsdmJqRWdiM0lnWm5WdVkzUnBiMjR5WEc0Z0tpOWNibVY0Y0c5eWRITXVjR2xqYXlBOUlHWjFibU4wYVc5dUtDa2dlMXh1SUNCeVpYUjFjbTRnWVhKbmRXMWxiblJ6VzM1K0tFMWhkR2d1Y21GdVpHOXRLQ2txWVhKbmRXMWxiblJ6TG14bGJtZDBhQ2xkTzF4dWZUdGNibHh1THlvcVhHNGdLaUJTWlhSMWNtNXpJR0Z1SUc5amRHRjJaU0J0ZFd4MGFYQnNhV1Z5SUdadmNpQm1jbVZ4ZFdWdVkza2dkbUZzZFdWelhHNGdLaUJBY0dGeVlXMGdJSHR1ZFcxaVpYSjlJRzUxYlNCU1pXeGhkR2wyWlNCdlkzUmhkbVVnYm5WdFltVnlJQ2hsTG1jdUlDMHhJR1p2Y2lCdmJtVWdiMk4wWVhabElHUnZkMjRzSURFZ1ptOXlJRzl1WlNCdlkzUmhkbVVnZFhBcFhHNGdLaUJBY21WMGRYSnVJSHR1ZFcxaVpYSjlJQ0FnSUNCUFkzUmhkbVVnYlhWc2RHbHdiR2xsY2x4dUlDb2dRR1Y0WVcxd2JHVmNiaUFxSUU1bGVIVnpMbTlqZEdGMlpTZ3RNU2tnSUM4dklISmxkSFZ5Ym5NZ01DNDFYRzRnS2lCT1pYaDFjeTV2WTNSaGRtVW9NQ2tnSUNBdkx5QnlaWFIxY201eklERmNiaUFxSUU1bGVIVnpMbTlqZEdGMlpTZ3hLU0FnSUM4dklISmxkSFZ5Ym5NZ01seHVJQ29nVG1WNGRYTXViMk4wWVhabEtESXBJQ0FnTHk4Z2NtVjBkWEp1Y3lBMFhHNGdLaTljYm1WNGNHOXlkSE11YjJOMFlYWmxJRDBnWm5WdVkzUnBiMjRvYm5WdEtTQjdYRzRnSUhKbGRIVnliaUJOWVhSb0xuQnZkeWd5TEc1MWJTazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmhibVJ2YlNCcGJuUmxaMlZ5SUdkbGJtVnlZWFJ2Y2k0Z1NXWWdibThnYzJWamIyNWtJR0Z5WjNWdFpXNTBJR2x6SUdkcGRtVnVMQ0IzYVd4c0lISmxkSFZ5YmlCeVlXNWtiMjBnYVc1MFpXZGxjaUJtY205dElEQWdkRzhnWW05MWJtUXhMbHh1SUNvZ1FIQmhjbUZ0SUNCN2JuVnRZbVZ5ZlNCaWIzVnVaREVnVFdsdWFXMTFiU0J5WVc1a2IyMGdkbUZzZFdWY2JpQXFJRUJ3WVhKaGJTQWdlMjUxYldKbGNuMGdZbTkxYm1ReUlFMWhlR2x0ZFcwZ2NtRnVaRzl0SUhaaGJIVmxYRzRnS2lCQWNtVjBkWEp1SUh0dWRXMWlaWEo5SUNBZ0lDQWdJQ0JTWVc1a2IyMGdhVzUwWldkbGNpQmlaWFIzWldWdUlHeHZkMlZ5SUdGdVpDQjFjSEJsY2lCaWIzVnVaR0Z5ZVZ4dUlDb2dRR1Y0WVcxd2JHVmNiaUFxSUU1bGVIVnpMbkpwS0RFd0tTQWdJQ0F2THlCeVpYUjFjbTV6SUhKaGJtUnZiU0JwYm5RZ1puSnZiU0F3SUhSdklERXdYRzRnS2lCT1pYaDFjeTV5YVNneU1Dd3lNREF3S1NBdkx5QnlaWFIxY201eklISmhibVJ2YlNCcGJuUWdabkp2YlNBeU1DQjBieUF5TURBd1hHNGdLaTljYm1WNGNHOXlkSE11Y21rZ1BTQm1kVzVqZEdsdmJpaGliM1Z1WkRFc1ltOTFibVF5S1NCN1hHNGdJR2xtSUNnaFltOTFibVF5S1NCN1hHNGdJQ0FnWW05MWJtUXlJRDBnWW05MWJtUXhPMXh1SUNBZ0lHSnZkVzVrTVNBOUlEQTdYRzRnSUgxY2JpQWdkbUZ5SUd4dmR5QTlJRTFoZEdndWJXbHVLR0p2ZFc1a01TeGliM1Z1WkRJcE8xeHVJQ0IyWVhJZ2FHbG5hQ0E5SUUxaGRHZ3ViV0Y0S0dKdmRXNWtNU3hpYjNWdVpESXBPMXh1SUNCeVpYUjFjbTRnVFdGMGFDNW1iRzl2Y2loTllYUm9MbkpoYm1SdmJTZ3BLaWhvYVdkb0xXeHZkeWtyYkc5M0tUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1VtRnVaRzl0SUdac2IyRjBJRzUxYldKbGNpQm5aVzVsY21GMGIzSXVJRWxtSUc1dklITmxZMjl1WkNCaGNtZDFiV1Z1ZENCcGN5Qm5hWFpsYml3Z2QybHNiQ0J5WlhSMWNtNGdjbUZ1Wkc5dElHWnNiMkYwSUdaeWIyMGdNQ0IwYnlCaWIzVnVaREV1WEc0Z0tpQkFjR0Z5WVcwZ0lIdHVkVzFpWlhKOUlHSnZkVzVrTVNCTmFXNXBiWFZ0SUhKaGJtUnZiU0IyWVd4MVpWeHVJQ29nUUhCaGNtRnRJQ0I3Ym5WdFltVnlmU0JpYjNWdVpESWdUV0Y0YVcxMWJTQnlZVzVrYjIwZ2RtRnNkV1ZjYmlBcUlFQnlaWFIxY200Z2UyNTFiV0psY24wZ0lDQWdJQ0FnSUZKaGJtUnZiU0JtYkc5aGRDQmlaWFIzWldWdUlHeHZkMlZ5SUdGdVpDQjFjSEJsY2lCaWIzVnVaR0Z5ZVZ4dUlDb2dRR1Y0WVcxd2JHVmNiaUFxSUU1bGVIVnpMbkptS0RFcElDQWdJQzh2SUhKbGRIVnlibk1nY21GdVpHOXRJR1pzYjJGMElHWnliMjBnTUNCMGJ5QXhYRzRnS2lCT1pYaDFjeTV5WmlneExESXBJQzh2SUhKbGRIVnlibk1nY21GdVpHOXRJR1pzYjJGMElHWnliMjBnTVNCMGJ5QXlYRzRnS2k5Y2JtVjRjRzl5ZEhNdWNtWWdQU0JtZFc1amRHbHZiaWhpYjNWdVpERXNZbTkxYm1ReUtTQjdYRzRnSUdsbUlDZ2hZbTkxYm1ReUtTQjdYRzRnSUNBZ1ltOTFibVF5SUQwZ1ltOTFibVF4TzF4dUlDQWdJR0p2ZFc1a01TQTlJREE3WEc0Z0lIMWNiaUFnZG1GeUlHeHZkeUE5SUUxaGRHZ3ViV2x1S0dKdmRXNWtNU3hpYjNWdVpESXBPMXh1SUNCMllYSWdhR2xuYUNBOUlFMWhkR2d1YldGNEtHSnZkVzVrTVN4aWIzVnVaRElwTzF4dUlDQnlaWFIxY200Z1RXRjBhQzV5WVc1a2IyMG9LU29vYUdsbmFDMXNiM2NwSzJ4dmR6dGNibjA3WEc1Y2JseHVaWGh3YjNKMGN5NWplV05zWlNBOUlHWjFibU4wYVc5dUtHbHVjSFYwTEcxcGJpeHRZWGdwSUh0Y2JpQWdhVzV3ZFhRckt6dGNiaUFnYVdZZ0tHbHVjSFYwSUQ0OUlHMWhlQ2tnZTF4dUlDQWdJR2x1Y0hWMElEMGdiV2x1TzF4dUlDQjlYRzRnSUhKbGRIVnliaUJwYm5CMWREdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1FYWmxjbUZuWlNCaGJpQmhjbkpoZVNCdlppQnVkVzFpWlhKelhHNGdLaUJBY0dGeVlXMGdJSHRCY25KaGVYMGdaR0YwWVNCQmNuSmhlU0J2WmlCdWRXMWlaWEp6SUhSdklHRjJaWEpoWjJWY2JpQXFJRUJ5WlhSMWNtNGdlMjUxYldKbGNuMGdJQ0FnSUNCQmRtVnlZV2RsSUc5bUlIUm9aU0JwYm5CMWRDQmtZWFJoWEc0Z0tpQkFaWGhoYlhCc1pWeHVJQ29nVG1WNGRYTXVZWFpsY21GblpTaGJNQ3d5TERRc05pdzRMREV3WFNrZ0lDQXZMeUJ5WlhSMWNtNXpJRFZjYmlBcUwxeHVaWGh3YjNKMGN5NWhkbVZ5WVdkbElEMGdablZ1WTNScGIyNG9aR0YwWVNrZ2UxeHVJQ0JzWlhRZ2RHOTBZV3dnUFNBd08xeHVJQ0JtYjNJZ0tIWmhjaUJwUFRBN2FUeGtZWFJoTG14bGJtZDBhRHRwS3lzcElIdGNiaUFnSUNCMGIzUmhiQ0FyUFNCa1lYUmhXMmxkTzF4dUlDQjlYRzRnSUhKbGRIVnliaUIwYjNSaGJDQXZJR1JoZEdFdWJHVnVaM1JvTzF4dWZUdGNibHh1THlvcVhHNGdLaUJIWlhRZ2RHaGxJR1JwYzNSaGJtTmxJR1p5YjIwZ2IyNWxJQ2g0TEhrcElIQnZhVzUwSUhSdklHRnViM1JvWlhJZ0tIZ3NlU2tnY0c5cGJuUmNiaUFxSUVCd1lYSmhiU0FnZTI1MWJXSmxjbjBnZURFZ2VDQnZaaUJtYVhKemRDQndiMmx1ZEZ4dUlDb2dRSEJoY21GdElDQjdiblZ0WW1WeWZTQjVNU0I1SUc5bUlHWnBjbk4wSUhCdmFXNTBYRzRnS2lCQWNHRnlZVzBnSUh0dWRXMWlaWEo5SUhneUlIZ2diMllnYzJWamIyNWtJSEJ2YVc1MFhHNGdLaUJBY0dGeVlXMGdJSHR1ZFcxaVpYSjlJSGt5SUhrZ2IyWWdjMlZqYjI1a0lIQnZhVzU1WEc0Z0tpQkFjbVYwZFhKdUlIdHVkVzFpWlhKOUlDQWdJRVJwYzNSaGJtTmxYRzRnS2lCQVpYaGhiWEJzWlZ4dUlDb2dUbVY0ZFhNdVpHbHpkR0Z1WTJVb01Dd3dMRE1zTkNrZ0lDQXZMeUJ5WlhSMWNtNXpJRFZjYmlBcUwxeHVaWGh3YjNKMGN5NWthWE4wWVc1alpTQTlJR1oxYm1OMGFXOXVLSGd4TEhreExIZ3lMSGt5S1NCN1hHNGdJR3hsZENCaElEMGdlREVnTFNCNE1qdGNiaUFnYkdWMElHSWdQU0I1TVNBdElIa3lPMXh1SUNCeVpYUjFjbTRnVFdGMGFDNXpjWEowS0NCaEttRWdLeUJpS21JZ0tUdGNibjA3WEc1Y2JtVjRjRzl5ZEhNdVoyRnBibFJ2UkVJZ1BTQm1kVzVqZEdsdmJpaG5ZV2x1S1NCN1hHNGdJSEpsZEhWeWJpQXlNQ0FxSUUxaGRHZ3ViRzluTVRBb1oyRnBiaWs3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRVpzYVhBZ1lTQmpiMmx1TENCeVpYUjFjbTVwYm1jZ1pXbDBhR1Z5SURBZ2IzSWdNU0JoWTJOdmNtUnBibWNnZEc4Z1lTQndjbTlpWVdKcGJHbDBlVnh1SUNvZ1FIQmhjbUZ0SUNCN2JuVnRZbVZ5ZlNCYmIyUmtjejB3TGpWZElFeHBhMlZzYVdodmIyUWdiMllnY21WMGRYSnVhVzVuSURGY2JpQXFJRUJ5WlhSMWNtNGdlMjUxYldKbGNuMGdJQ0FnSUNBZ0lDQWdJQ0F4SUc5eUlEQmNiaUFxSUVCbGVHRnRjR3hsWEc0Z0tpQk9aWGgxY3k1amIybHVLREF1TVNrZ0lDQXZMeUJ5WlhSMWNtNXpJREVnS0RFd0pTQnZaaUIwYUdVZ2RHbHRaU2tnYjNJZ01DQW9PVEFsSUc5bUlIUm9aU0IwYVcxbEtWeHVJQ292WEc1bGVIQnZjblJ6TG1OdmFXNGdQU0JtZFc1amRHbHZiaWh2WkdSelBUQXVOU2tnZTF4dUlDQnBaaUFvWlhod2IzSjBjeTV5Wmlnd0xERXBJRHdnYjJSa2N5a2dlMXh1SUNBZ0lISmxkSFZ5YmlBeE8xeHVJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lISmxkSFZ5YmlBd08xeHVJQ0I5WEc1OU8xeHVYRzVjYmx4dUx5OGdWMFZDVUVGRFN5QkdUMDlVUlZJZ0x5OWNiaTh2SUM0dmZpOXFjMmhwYm5RdGJHOWhaR1Z5SVM0dmJHbGlMM1YwYVd3dmJXRjBhQzVxY3lJc0lpZDFjMlVnYzNSeWFXTjBKenRjYmx4dWJHVjBJSE4yWnlBOUlISmxjWFZwY21Vb0p5NHVMM1YwYVd3dmMzWm5KeWs3WEc1c1pYUWdaRzl0SUQwZ2NtVnhkV2x5WlNnbkxpNHZkWFJwYkM5a2IyMG5LVHRjYm14bGRDQjFkR2xzSUQwZ2NtVnhkV2x5WlNnbkxpNHZkWFJwYkM5MWRHbHNKeWs3WEc1c1pYUWdkRzkxWTJnZ1BTQnlaWEYxYVhKbEtDY3VMaTkxZEdsc0wzUnZkV05vSnlrN1hHNWpiMjV6ZENCRmRtVnVkRVZ0YVhSMFpYSWdQU0J5WlhGMWFYSmxLQ2RsZG1WdWRITW5LVHRjYmx4dWFXMXdiM0owSUhzZ1kyOXNiM0p6SUgwZ1puSnZiU0FuTGk0dmJXRnBiaWM3WEc1Y2JpOHFLbHh1U1c1MFpYSm1ZV05sWEc0cUwxeHVaWGh3YjNKMElHUmxabUYxYkhRZ1kyeGhjM01nU1c1MFpYSm1ZV05sSUdWNGRHVnVaSE1nUlhabGJuUkZiV2wwZEdWeUlIdGNibHh1SUNCamIyNXpkSEoxWTNSdmNpaGhjbWR6TEc5d2RHbHZibk1zWkdWbVlYVnNkSE1wSUh0Y2JpQWdJQ0J6ZFhCbGNpZ3BPMXh1SUNBZ0lIUm9hWE11ZEhsd1pTQTlJSFJvYVhNdVkyOXVjM1J5ZFdOMGIzSXVibUZ0WlR0Y2JpQWdJQ0IwYUdsekxuTmxkSFJwYm1keklEMGdkR2hwY3k1d1lYSnpaVk5sZEhScGJtZHpLR0Z5WjNNc2IzQjBhVzl1Y3l4a1pXWmhkV3gwY3lrN1hHNGdJQ0FnZEdocGN5NXRiM1Z6WlNBOUlIdDlPMXh1SUNBZ0lIUm9hWE11ZDJGcGRDQTlJR1poYkhObE8xeHVJQ0FnSUhSb2FYTXVZMjlzYjNKeklEMGdlMzA3WEc0Z0lDQWdiR1YwSUdSbFptRjFiSFJEYjJ4dmNuTWdQU0JqYjJ4dmNuTW9LVHNnTHk4Z2FuTm9hVzUwSUdsbmJtOXlaVHBzYVc1bFhHNGdJQ0FnZEdocGN5NWpiMnh2Y25NdVlXTmpaVzUwSUQwZ1pHVm1ZWFZzZEVOdmJHOXljeTVoWTJObGJuUTdYRzRnSUNBZ2RHaHBjeTVqYjJ4dmNuTXVabWxzYkNBOUlHUmxabUYxYkhSRGIyeHZjbk11Wm1sc2JEdGNiaUFnSUNCMGFHbHpMbU52Ykc5eWN5NXNhV2RvZENBOUlHUmxabUYxYkhSRGIyeHZjbk11YkdsbmFIUTdYRzRnSUNBZ2RHaHBjeTVqYjJ4dmNuTXVaR0Z5YXlBOUlHUmxabUYxYkhSRGIyeHZjbk11WkdGeWF6dGNiaUFnSUNCMGFHbHpMbU52Ykc5eWN5NXRaV1JwZFcxTWFXZG9kQ0E5SUdSbFptRjFiSFJEYjJ4dmNuTXViV1ZrYVhWdFRHbG5hSFE3WEc0Z0lDQWdkR2hwY3k1amIyeHZjbk11YldWa2FYVnRSR0Z5YXlBOUlHUmxabUYxYkhSRGIyeHZjbk11YldWa2FYVnRSR0Z5YXp0Y2JpQWdmVnh1WEc0Z0lIQmhjbk5sVTJWMGRHbHVaM01vWVhKbmN5eHZjSFJwYjI1ekxHUmxabUYxYkhSektTQjdYRzVjYmlBZ0lDQnZjSFJwYjI1ekxuVnVjMmhwWm5Rb0ozUmhjbWRsZENjcE8xeHVJQ0FnSUdSbFptRjFiSFJ6TG1SbFptRjFiSFJUYVhwbElEMGdaR1ZtWVhWc2RITXVjMmw2WlM1emNHeHBZMlVvTUN3eUtUdGNiaUFnSUNCa1pXWmhkV3gwY3k1emFYcGxJRDBnWm1Gc2MyVTdYRzVjYmlBZ0lDQnNaWFFnYzJWMGRHbHVaM01nUFNCN1hHNGdJQ0FnSUNBbmRHRnlaMlYwSnpvZ1pHOWpkVzFsYm5RdVltOWtlU3hjYmlBZ0lDQWdJQ2RqYjJ4dmNuTW5PaUI3ZlN3Z0x5OGdjMmh2ZFd4a0lHbHVhR1Z5YVhRZ1puSnZiU0JoSUdOdmJHOXljeUJ0YjJSMWJHVXNYRzRnSUNBZ0lDQW5jMjVoY0ZkcGRHaFFZWEpsYm5Rbk9pQjBjblZsTEZ4dUlDQWdJQ0FnSjJWMlpXNTBKem9nWm5WdVkzUnBiMjRvS1NCN2ZTeGNiaUFnSUNBZ0lDZGpiMjF3YjI1bGJuUW5PaUJtWVd4elpWeHVJQ0FnSUgwN1hHNWNiaUFnSUNCbWIzSWdLR3hsZENCclpYa2dhVzRnWkdWbVlYVnNkSE1wSUh0Y2JpQWdJQ0FnSUhObGRIUnBibWR6VzJ0bGVWMGdQU0JrWldaaGRXeDBjMXRyWlhsZE8xeHVJQ0FnSUgxY2JseHVJQ0FnSUdadmNpQW9iR1YwSUdrOU1Ec2dhVHhoY21kekxteGxibWQwYURzZ2FTc3JLU0I3WEc0Z0lDQWdJQ0F2THlCbmNtRmljeUIwYUdVZ2JtVjRkQ0JoY21kMWJXVnVkRnh1SUNBZ0lDQWdiR1YwSUhObGRIUnBibWNnUFNCaGNtZHpXMmxkTzF4dUlDQWdJQ0FnTHk4Z2FXWWdhWFFuY3lCaGJpQnZZbXBsWTNRc0lHbDBJRzExYzNRZ1ltVWdkR2hsSUhObGRIUnBibWR6SUc5aWFtVmpkRnh1SUNBZ0lDQWdhV1lnS0NCMWRHbHNMbWx6VDJKcVpXTjBLSE5sZEhScGJtY3BJQ2tnZTF4dUlDQWdJQ0FnSUNCbWIzSWdLQ0JzWlhRZ2EyVjVJR2x1SUhObGRIUnBibWNnS1NCN1hHNGdJQ0FnSUNBZ0lDQWdjMlYwZEdsdVozTmJhMlY1WFNBOUlITmxkSFJwYm1kYmEyVjVYVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnTHk4Z2FXWWdhWFFuY3lCaElHWjFibU4wYVc5dUxDQnBkQ0J0ZFhOMElHSmxJSFJvWlNCbGRtVnVkQ0J6WlhSMGFXNW5YRzRnSUNBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQnpaWFIwYVc1bklEMDlQU0FuWm5WdVkzUnBiMjRuS1NCN1hHNGdJQ0FnSUNBZ0lITmxkSFJwYm1kekxtVjJaVzUwSUQwZ2MyVjBkR2x1Wnp0Y2JpQWdJQ0FnSUM4dklHOTBhR1Z5ZDJselpTd2dZMjl1YzJsa1pYSWdhWFFnYjI1bElHOW1JSFJvWlNCM2FXUm5aWFFuY3lCamRYTjBiMjBnYjNCMGFXOXVjMXh1SUNBZ0lDQWdmU0JsYkhObElHbG1JQ2h2Y0hScGIyNXpMbXhsYm1kMGFENDlNU2tnZTF4dUlDQWdJQ0FnSUNBdkx5Qm5jbUZpSUhSb1pTQm1hWEp6ZENCdmNIUnBiMjRnTFMwZ2FTNWxMaUFuZEdGeVoyVjBKMXh1SUNBZ0lDQWdJQ0JzWlhRZ2EyVjVJRDBnYjNCMGFXOXVjeTV6Y0d4cFkyVW9NQ3d4S1Zzd1hUdGNiaUFnSUNBZ0lDQWdjMlYwZEdsdVozTmJhMlY1WFNBOUlITmxkSFJwYm1jN1hHNGdJQ0FnSUNCOVhHNGdJQ0FnZlZ4dVhHNGdJQ0FnTHlvZ0lHaGhibVJzWlNCamIyMXRiMjRnYzJWMGRHbHVaM01nSUNvdlhHNWNiaUFnSUNBdkx5QjBZWEpuWlhSY2JpQWdJQ0IwYUdsekxuQmhjbVZ1ZENBOUlHUnZiUzV3WVhKelpVVnNaVzFsYm5Rb2MyVjBkR2x1WjNNdWRHRnlaMlYwS1R0Y2JseHVJQ0FnSUM4dklHNWxlSFZ6TFhWcElHRjBkSEpwWW5WMFpWeHVJQ0FnSUdsbUlDaDBhR2x6TG5CaGNtVnVkQ0FtSmlCMGFHbHpMbkJoY21WdWRDQnBibk4wWVc1alpXOW1JRWhVVFV4RmJHVnRaVzUwSUNZbUlDRnpaWFIwYVc1bmN5NWpiMjF3YjI1bGJuUXBJSHRjYmlBZ0lDQWdJR2xtSUNnaGRHaHBjeTV3WVhKbGJuUXVhR0Z6UVhSMGNtbGlkWFJsS0NkdVpYaDFjeTExYVNjcEtTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWNHRnlaVzUwTG5ObGRFRjBkSEpwWW5WMFpTZ25ibVY0ZFhNdGRXa25MQ2NuS1R0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc1Y2JpQWdJQ0F2THlCemFYcGxYRzVjYmlBZ0lDQnBaaUFvYzJWMGRHbHVaM011YzJsNlpTQW1KaUJCY25KaGVTNXBjMEZ5Y21GNUtITmxkSFJwYm1kekxuTnBlbVVwSUNZbUlITmxkSFJwYm1kekxuTnVZWEJYYVhSb1VHRnlaVzUwS1NCN1hHNGdJQ0FnSUNCMGFHbHpMbmRwWkhSb0lEMGdjMlYwZEdsdVozTXVjMmw2WlZzd1hUdGNiaUFnSUNBZ0lIUm9hWE11YUdWcFoyaDBJRDBnYzJWMGRHbHVaM011YzJsNlpWc3hYVHRjYmlBZ0lDQWdJSFJvYVhNdWNHRnlaVzUwTG5OMGVXeGxMbmRwWkhSb0lEMGdkR2hwY3k1M2FXUjBhQ0FySUNkd2VDYzdYRzRnSUNBZ0lDQjBhR2x6TG5CaGNtVnVkQzV6ZEhsc1pTNW9aV2xuYUhRZ1BTQjBhR2x6TG1obGFXZG9kQ0FySUNkd2VDYzdYRzRnSUNBZ2ZTQmxiSE5sSUdsbUlDaHpaWFIwYVc1bmN5NXpibUZ3VjJsMGFGQmhjbVZ1ZENBbUppQWhjMlYwZEdsdVozTXVZMjl0Y0c5dVpXNTBLU0I3WEc1Y2JpQWdJQ0FnSUhSb2FYTXVkMmxrZEdnZ1BTQndZWEp6WlVac2IyRjBLSGRwYm1SdmR5NW5aWFJEYjIxd2RYUmxaRk4wZVd4bEtIUm9hWE11Y0dGeVpXNTBMQ0J1ZFd4c0tTNW5aWFJRY205d1pYSjBlVlpoYkhWbEtDZDNhV1IwYUNjcExuSmxjR3hoWTJVb0ozQjRKeXduSnlrcE8xeHVJQ0FnSUNBZ2RHaHBjeTVvWldsbmFIUWdQU0J3WVhKelpVWnNiMkYwS0hkcGJtUnZkeTVuWlhSRGIyMXdkWFJsWkZOMGVXeGxLSFJvYVhNdWNHRnlaVzUwTENCdWRXeHNLUzVuWlhSUWNtOXdaWEowZVZaaGJIVmxLQ2RvWldsbmFIUW5LUzV5WlhCc1lXTmxLQ2R3ZUNjc0p5Y3BLVHRjYmx4dUlDQWdJQ0FnYVdZZ0tIUm9hWE11ZDJsa2RHZzlQVFV3TURBcElIdGNiaUFnSUNBZ0lDQWdkR2hwY3k1M2FXUjBhQ0E5SUhObGRIUnBibWR6TG1SbFptRjFiSFJUYVhwbFd6QmRPMXh1SUNBZ0lDQWdJQ0IwYUdsekxuQmhjbVZ1ZEM1emRIbHNaUzUzYVdSMGFDQTlJSFJvYVhNdWNHRnlaVzUwTG5kcFpIUm9JRDBnZEdocGN5NTNhV1IwYUNBcklDZHdlQ2M3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdJQ0JwWmlBb2RHaHBjeTVvWldsbmFIUTlQVFV3TURBcElIdGNiaUFnSUNBZ0lDQWdkR2hwY3k1b1pXbG5hSFFnUFNCelpYUjBhVzVuY3k1a1pXWmhkV3gwVTJsNlpWc3hYVHRjYmlBZ0lDQWdJQ0FnZEdocGN5NXdZWEpsYm5RdWMzUjViR1V1YUdWcFoyaDBJRDBnZEdocGN5NXdZWEpsYm5RdWFHVnBaMmgwSUQwZ2RHaHBjeTVvWldsbmFIUWdLeUFuY0hnbk8xeHVJQ0FnSUNBZ2ZWeHVYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUhObGRIUnBibWR6TG5OcGVtVWdQU0J6WlhSMGFXNW5jeTVrWldaaGRXeDBVMmw2WlR0Y2JpQWdJQ0FnSUhSb2FYTXVkMmxrZEdnZ1BTQnpaWFIwYVc1bmN5NXphWHBsV3pCZE8xeHVJQ0FnSUNBZ2RHaHBjeTVvWldsbmFIUWdQU0J6WlhSMGFXNW5jeTV6YVhwbFd6RmRPMXh1SUNBZ0lIMWNibHh1SUNBZ0lDOHZJR1YyWlc1MFhHNGdJQ0FnYVdZZ0tITmxkSFJwYm1kekxtVjJaVzUwS1NCN1hHNGdJQ0FnSUNCMGFHbHpMbVYyWlc1MElEMGdkR2hwY3k1dmJpZ25ZMmhoYm1kbEp5d2djMlYwZEdsdVozTXVaWFpsYm5RcE8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0IwYUdsekxtVjJaVzUwSUQwZ1ptRnNjMlU3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdjbVYwZFhKdUlITmxkSFJwYm1kek8xeHVYRzRnSUgxY2JseHVJQ0JwYm1sMEtDa2dlMXh1SUNBZ0lIUm9hWE11WW5WcGJHUkdjbUZ0WlNncE8xeHVJQ0FnSUhSb2FYTXVZblZwYkdSSmJuUmxjbVpoWTJVb0tUdGNiaUFnSUNCMGFHbHpMbk5wZW1WSmJuUmxjbVpoWTJVb0tUdGNiaUFnSUNCMGFHbHpMbUYwZEdGamFFeHBjM1JsYm1WeWN5Z3BPMXh1SUNBZ0lIUm9hWE11WTI5c2IzSkpiblJsY21aaFkyVW9LVHRjYmlBZ0lDQjBhR2x6TG1acGJtRnNWRzkxWTJobGN5Z3BPMXh1SUNCOVhHNWNiaUFnWW5WcGJHUkdjbUZ0WlNncElIdGNiaUFnSUNCMGFHbHpMbVZzWlcxbGJuUWdQU0J6ZG1jdVkzSmxZWFJsS0NkemRtY25LVHRjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1YzJWMFFYUjBjbWxpZFhSbEtDZDNhV1IwYUNjc2RHaHBjeTUzYVdSMGFDazdYRzRnSUNBZ2RHaHBjeTVsYkdWdFpXNTBMbk5sZEVGMGRISnBZblYwWlNnbmFHVnBaMmgwSnl4MGFHbHpMbWhsYVdkb2RDazdYRzRnSUNBZ2RHaHBjeTV3WVhKbGJuUXVZWEJ3Wlc1a1EyaHBiR1FvZEdocGN5NWxiR1Z0Wlc1MEtUdGNiaUFnZlZ4dVhHNGdJR0oxYVd4a1NXNTBaWEptWVdObEtDa2dlMzFjYmlBZ2MybDZaVWx1ZEdWeVptRmpaU2dwSUh0OVhHNGdJR052Ykc5eVNXNTBaWEptWVdObEtDa2dlMzFjYmx4dUlDQmhkSFJoWTJoTWFYTjBaVzVsY25Nb0tTQjdYRzVjYmlBZ0lDQjBhR2x6TG1sdWRHVnlZV04wYVc5dVZHRnlaMlYwSUQwZ2RHaHBjeTVwYm5SbGNtRmpkR2x2YmxSaGNtZGxkQ0I4ZkNCMGFHbHpMbVZzWlcxbGJuUTdYRzVjYmlBZ0lDQXZMeUJUWlhSMWNDQnBiblJsY21GamRHbHZibHh1SUNBZ0lHbG1JQ2gwYjNWamFDNWxlR2x6ZEhNcElIdGNiaUFnSUNBZ0lIUm9hWE11YVc1MFpYSmhZM1JwYjI1VVlYSm5aWFF1WVdSa1JYWmxiblJNYVhOMFpXNWxjaWduZEc5MVkyaHpkR0Z5ZENjc0lHVjJkQ0E5UGlCMGFHbHpMbkJ5WlZSdmRXTm9LR1YyZENrcE8xeHVJQ0FnSUNBZ2RHaHBjeTVwYm5SbGNtRmpkR2x2YmxSaGNtZGxkQzVoWkdSRmRtVnVkRXhwYzNSbGJtVnlLQ2QwYjNWamFHMXZkbVVuTENCbGRuUWdQVDRnZEdocGN5NXdjbVZVYjNWamFFMXZkbVVvWlhaMEtTazdYRzRnSUNBZ0lDQjBhR2x6TG1sdWRHVnlZV04wYVc5dVZHRnlaMlYwTG1Ga1pFVjJaVzUwVEdsemRHVnVaWElvSjNSdmRXTm9aVzVrSnl3Z1pYWjBJRDArSUhSb2FYTXVjSEpsVkc5MVkyaFNaV3hsWVhObEtHVjJkQ2twTzF4dUlDQWdJSDFjYmlBZ0lDQjBhR2x6TG1KdmRXNWtVSEpsVFc5MlpTQTlJR1YyZENBOVBpQjBhR2x6TG5CeVpVMXZkbVVvWlhaMEtUdGNiaUFnSUNCMGFHbHpMbUp2ZFc1a1VISmxVbVZzWldGelpTQTlJR1YyZENBOVBpQjBhR2x6TG5CeVpWSmxiR1ZoYzJVb1pYWjBLVHRjYmlBZ0lDQjBhR2x6TG1sdWRHVnlZV04wYVc5dVZHRnlaMlYwTG1Ga1pFVjJaVzUwVEdsemRHVnVaWElvSjIxdmRYTmxaRzkzYmljc0lHVjJkQ0E5UGlCMGFHbHpMbkJ5WlVOc2FXTnJLR1YyZENrcE8xeHVJQ0I5WEc1Y2JpQWdabWx1WVd4VWIzVmphR1Z6S0NrZ2UxeHVJQ0FnSUhSb2FYTXVaV3hsYldWdWRDNXpkSGxzWlM1amRYSnpiM0lnUFNBbmNHOXBiblJsY2ljN1hHNGdJSDFjYmx4dUlDQndjbVZEYkdsamF5aGxLU0I3WEc0Z0lDQWdMeThnTVRBd01EQWdaMlYwUTI5dGNIVjBaV1JUZEhsc1pTQmpZV3hzY3lCMFlXdGxjeUF4TURBZ2JYTXVYRzRnSUNBZ0x5OGdMam91SUc5dVpTQjBZV3RsY3lCaFltOTFkQ0F1TURGdGMxeHVJQ0FnSUdsbUlDaDBhR2x6TG1Wc1pXMWxiblFnYVc1emRHRnVZMlZ2WmlCSVZFMU1SV3hsYldWdWRDa2dlMXh1SUNBZ0lDQWdkR2hwY3k1M2FXUjBhQ0E5SUhkcGJtUnZkeTVuWlhSRGIyMXdkWFJsWkZOMGVXeGxLSFJvYVhNdVpXeGxiV1Z1ZEN3Z2JuVnNiQ2t1WjJWMFVISnZjR1Z5ZEhsV1lXeDFaU2duZDJsa2RHZ25LUzV5WlhCc1lXTmxLQ2R3ZUNjc0p5Y3BPMXh1SUNBZ0lIMWNiaUFnSUNBdkx5QXhNREF3TUNCblpYUkRiMjF3ZFhSbFpGTjBlV3hsSUdOaGJHeHpJSFJoYTJWeklEUXdJRzF6TGx4dUlDQWdJQzh2SUM0NkxpQnZibVVnZEdGclpYTWdZV0p2ZFhRZ0xqQXdORzF6WEc0Z0lDQWdkR2hwY3k1dlptWnpaWFFnUFNCa2IyMHVabWx1WkZCdmMybDBhVzl1S0hSb2FYTXVaV3hsYldWdWRDazdYRzRnSUNBZ2RHaHBjeTV0YjNWelpTQTlJR1J2YlM1c2IyTmhkR1ZOYjNWelpTaGxMSFJvYVhNdWIyWm1jMlYwS1R0Y2JpQWdJQ0IwYUdsekxtTnNhV05yWldRZ1BTQjBjblZsTzF4dUlDQWdJSFJvYVhNdVkyeHBZMnNvS1R0Y2JpQWdJQ0IwYUdsekxtMXZkbVZGZG1WdWRDQTlJR1J2WTNWdFpXNTBMbUZrWkVWMlpXNTBUR2x6ZEdWdVpYSW9KMjF2ZFhObGJXOTJaU2NzSUhSb2FYTXVZbTkxYm1SUWNtVk5iM1psS1R0Y2JpQWdJQ0IwYUdsekxuSmxiR1ZoYzJWRmRtVnVkQ0E5SUdSdlkzVnRaVzUwTG1Ga1pFVjJaVzUwVEdsemRHVnVaWElvSjIxdmRYTmxkWEFuTENCMGFHbHpMbUp2ZFc1a1VISmxVbVZzWldGelpTazdYRzRnSUNBZ2RHaHBjeTVsYldsMEtDZGpiR2xqYXljcE8xeHVJQ0FnSUdVdWNISmxkbVZ1ZEVSbFptRjFiSFFvS1R0Y2JpQWdJQ0JsTG5OMGIzQlFjbTl3WVdkaGRHbHZiaWdwTzF4dUlDQjlYRzVjYmlBZ2NISmxUVzkyWlNobEtTQjdYRzRnSUNBZ2FXWWdLQ0YwYUdsekxuZGhhWFFwSUh0Y2JpQWdJQ0FnSUhSb2FYTXViVzkxYzJVZ1BTQmtiMjB1Ykc5allYUmxUVzkxYzJVb1pTeDBhR2x6TG05bVpuTmxkQ2s3WEc0Z0lDQWdJQ0IwYUdsekxtMXZkbVVvS1R0Y2JpQWdJQ0FnSUhSb2FYTXVkMkZwZENBOUlIUnlkV1U3WEc0Z0lDQWdJQ0J6WlhSVWFXMWxiM1YwS0NncElEMCtJSHNnZEdocGN5NTNZV2wwSUQwZ1ptRnNjMlU3SUgwc01qVXBPMXh1SUNBZ0lIMWNiaUFnSUNCbExuQnlaWFpsYm5SRVpXWmhkV3gwS0NrN1hHNGdJQ0FnWlM1emRHOXdVSEp2Y0dGbllYUnBiMjRvS1R0Y2JpQWdmVnh1WEc0Z0lIQnlaVkpsYkdWaGMyVW9aU2tnZTF4dUlDQWdJSFJvYVhNdWJXOTFjMlVnUFNCa2IyMHViRzlqWVhSbFRXOTFjMlVvWlN4MGFHbHpMbTltWm5ObGRDazdYRzRnSUNBZ2RHaHBjeTVqYkdsamEyVmtJRDBnWm1Gc2MyVTdYRzRnSUNBZ2RHaHBjeTV5Wld4bFlYTmxLQ2s3WEc0Z0lDQWdkR2hwY3k1bGJXbDBLQ2R5Wld4bFlYTmxKeWs3WEc0Z0lDQWdaRzlqZFcxbGJuUXVjbVZ0YjNabFJYWmxiblJNYVhOMFpXNWxjaWduYlc5MWMyVnRiM1psSnl4MGFHbHpMbUp2ZFc1a1VISmxUVzkyWlNrN1hHNGdJQ0FnWkc5amRXMWxiblF1Y21WdGIzWmxSWFpsYm5STWFYTjBaVzVsY2lnbmJXOTFjMlYxY0Njc2RHaHBjeTVpYjNWdVpGQnlaVkpsYkdWaGMyVXBPMXh1SUNBZ0lHVXVjSEpsZG1WdWRFUmxabUYxYkhRb0tUdGNiaUFnSUNCbExuTjBiM0JRY205d1lXZGhkR2x2YmlncE8xeHVJQ0I5WEc1Y2JpQWdZMnhwWTJzb0tTQjdYRzVjYmlBZ2ZWeHVYRzRnSUcxdmRtVW9LU0I3WEc1Y2JpQWdmVnh1WEc0Z0lISmxiR1ZoYzJVb0tTQjdYRzVjYmlBZ2ZWeHVYRzVjYmlBZ0x5b2dkRzkxWTJnZ0tpOWNibHh1SUNCd2NtVlViM1ZqYUNobEtTQjdYRzRnSUNBZ2FXWWdLSFJvYVhNdVpXeGxiV1Z1ZENCcGJuTjBZVzVqWlc5bUlFaFVUVXhGYkdWdFpXNTBLU0I3WEc0Z0lDQWdJQ0IwYUdsekxuZHBaSFJvSUQwZ2QybHVaRzkzTG1kbGRFTnZiWEIxZEdWa1UzUjViR1VvZEdocGN5NWxiR1Z0Wlc1MExDQnVkV3hzS1M1blpYUlFjbTl3WlhKMGVWWmhiSFZsS0NkM2FXUjBhQ2NwTG5KbGNHeGhZMlVvSjNCNEp5d25KeWs3WEc0Z0lDQWdmVnh1SUNBZ0lIUm9hWE11YjJabWMyVjBJRDBnWkc5dExtWnBibVJRYjNOcGRHbHZiaWgwYUdsekxtVnNaVzFsYm5RcE8xeHVJQ0FnSUhSb2FYTXViVzkxYzJVZ1BTQmtiMjB1Ykc5allYUmxWRzkxWTJnb1pTeDBhR2x6TG05bVpuTmxkQ2s3WEc0Z0lDQWdkR2hwY3k1amJHbGphMlZrSUQwZ2RISjFaVHRjYmlBZ0lDQjBhR2x6TG5SdmRXTm9LR1VwTzF4dUlDQWdJSFJvYVhNdVpXMXBkQ2duWTJ4cFkyc25LVHRjYmlBZ0lDQmxMbkJ5WlhabGJuUkVaV1poZFd4MEtDazdYRzRnSUNBZ1pTNXpkRzl3VUhKdmNHRm5ZWFJwYjI0b0tUdGNiaUFnZlZ4dVhHNGdJSEJ5WlZSdmRXTm9UVzkyWlNobEtTQjdYRzRnSUNBZ2FXWWdLSFJvYVhNdVkyeHBZMnRsWkNrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTV0YjNWelpTQTlJR1J2YlM1c2IyTmhkR1ZVYjNWamFDaGxMSFJvYVhNdWIyWm1jMlYwS1R0Y2JpQWdJQ0FnSUhSb2FYTXVkRzkxWTJoTmIzWmxLQ2s3WEc0Z0lDQWdJQ0JsTG5CeVpYWmxiblJFWldaaGRXeDBLQ2s3WEc0Z0lDQWdJQ0JsTG5OMGIzQlFjbTl3WVdkaGRHbHZiaWdwTzF4dUlDQWdJSDFjYmlBZ2ZWeHVYRzRnSUhCeVpWUnZkV05vVW1Wc1pXRnpaU2hsS1NCN1hHNGdJQ0FnZEdocGN5NXRiM1Z6WlNBOUlHUnZiUzVzYjJOaGRHVlViM1ZqYUNobExDQjBhR2x6TG05bVpuTmxkQ2s3WEc0Z0lDQWdkR2hwY3k1amJHbGphMlZrSUQwZ1ptRnNjMlU3WEc0Z0lDQWdkR2hwY3k1MGIzVmphRkpsYkdWaGMyVW9LVHRjYmlBZ0lDQjBhR2x6TG1WdGFYUW9KM0psYkdWaGMyVW5LVHRjYmlBZ0lDQmxMbkJ5WlhabGJuUkVaV1poZFd4MEtDazdYRzRnSUNBZ1pTNXpkRzl3VUhKdmNHRm5ZWFJwYjI0b0tUdGNiaUFnZlZ4dVhHNGdJSFJ2ZFdOb0tDa2dlMXh1SUNBZ0lIUm9hWE11WTJ4cFkyc29LVHRjYmlBZ2ZWeHVYRzRnSUhSdmRXTm9UVzkyWlNncElIdGNiaUFnSUNCMGFHbHpMbTF2ZG1Vb0tUdGNiaUFnZlZ4dVhHNGdJSFJ2ZFdOb1VtVnNaV0Z6WlNncElIdGNiaUFnSUNCMGFHbHpMbkpsYkdWaGMyVW9LVHRjYmlBZ2ZWeHVYRzRnSUM4cUtseHVJQ0FxSUZKbGMybDZaU0IwYUdVZ2FXNTBaWEptWVdObFhHNGdJQ29nUUhCaGNtRnRJSGRwWkhSb0lIdHVkVzFpWlhKOUlFNWxkeUIzYVdSMGFDQnBiaUJ3YVhobGJITmNiaUFnS2lCQWNHRnlZVzBnYUdWcFoyaDBJSHR1ZFcxaVpYSjlJRTVsZHlCb1pXbG5hSFFnYVc0Z2NHbDRaV3h6WEc0Z0lDcGNiaUFnS2lCQVpYaGhiWEJzWlZ4dUlDQXFJR0oxZEhSdmJpNXlaWE5wZW1Vb01UQXdMREV3TUNrN1hHNGdJQ292WEc0Z0lISmxjMmw2WlNoM2FXUjBhQ3hvWldsbmFIUXBJSHRjYmlBZ0lDQjBhR2x6TG5kcFpIUm9JRDBnZDJsa2RHZzdYRzRnSUNBZ2RHaHBjeTVvWldsbmFIUWdQU0JvWldsbmFIUTdYRzRnSUNBZ2RHaHBjeTV3WVhKbGJuUXVjM1I1YkdVdWQybGtkR2dnUFNCMGFHbHpMbmRwWkhSb0t5ZHdlQ2M3WEc0Z0lDQWdkR2hwY3k1d1lYSmxiblF1YzNSNWJHVXVhR1ZwWjJoMElEMGdkR2hwY3k1b1pXbG5hSFFySjNCNEp6dGNiaUFnSUNCMGFHbHpMbVZzWlcxbGJuUXVjMlYwUVhSMGNtbGlkWFJsS0NkM2FXUjBhQ2NzZEdocGN5NTNhV1IwYUNrN1hHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExuTmxkRUYwZEhKcFluVjBaU2duYUdWcFoyaDBKeXgwYUdsekxtaGxhV2RvZENrN1hHNGdJQ0FnZEdocGN5NXphWHBsU1c1MFpYSm1ZV05sS0NrN1hHNGdJSDFjYmx4dUlDQmxiWEIwZVNncElIdGNiaUFnSUNCM2FHbHNaU0FvZEdocGN5NWxiR1Z0Wlc1MExteGhjM1JEYUdsc1pDa2dlMXh1SUNBZ0lDQWdkR2hwY3k1bGJHVnRaVzUwTG5KbGJXOTJaVU5vYVd4a0tIUm9hWE11Wld4bGJXVnVkQzVzWVhOMFEyaHBiR1FwTzF4dUlDQWdJSDFjYmlBZ2ZWeHVYRzRnSUM4cUtseHVJQ0FxSUZKbGJXOTJaU0IwYUdVZ2FXNTBaWEptWVdObElHWnliMjBnZEdobElIQmhaMlVnWVc1a0lHTmhibU5sYkNCcGRITWdaWFpsYm5RZ2JHbHpkR1Z1WlhJb2N5a3VYRzRnSUNwY2JpQWdLaUJBWlhoaGJYQnNaVnh1SUNBcUlHSjFkSFJ2Ymk1a1pYTjBjbTk1S0NrN1hHNGdJQ292WEc0Z0lHUmxjM1J5YjNrb0tTQjdYRzRnSUNBZ2RHaHBjeTVsYlhCMGVTZ3BPMXh1SUNBZ0lIUm9hWE11Y0dGeVpXNTBMbkpsYlc5MlpVTm9hV3hrS0hSb2FYTXVaV3hsYldWdWRDazdYRzRnSUNBZ2RHaHBjeTV5WlcxdmRtVkJiR3hNYVhOMFpXNWxjbk1vS1R0Y2JpQWdJQ0JwWmlBb2RHaHBjeTVwYm5OMGNuVnRaVzUwS1NCN1hHNGdJQ0FnSUNCa1pXeGxkR1VnZEdocGN5NXBibk4wY25WdFpXNTBXM1JvYVhNdWFXUmRPMXh1SUNBZ0lIMWNiaUFnSUNCMGFHbHpMbU4xYzNSdmJVUmxjM1J5YjNrb0tUdGNiaUFnZlZ4dVhHNGdJR04xYzNSdmJVUmxjM1J5YjNrb0tTQjdYRzVjYmlBZ2ZWeHVYRzRnSUdOdmJHOXlhWHBsS0hSNWNHVXNZMjlzYjNJcElIdGNiaUFnSUNCMGFHbHpMbU52Ykc5eWMxdDBlWEJsWFNBOUlHTnZiRzl5TzF4dUlDQWdJSFJvYVhNdVkyOXNiM0pKYm5SbGNtWmhZMlVvS1R0Y2JpQWdmVnh1WEc1OVhHNWNibHh1WEc0dkx5QlhSVUpRUVVOTElFWlBUMVJGVWlBdkwxeHVMeThnTGk5K0wycHphR2x1ZEMxc2IyRmtaWEloTGk5c2FXSXZZMjl5WlM5cGJuUmxjbVpoWTJVdWFuTWlMQ0luZFhObElITjBjbWxqZENjN1hHNWNibVY0Y0c5eWRITXVabWx1WkZCdmMybDBhVzl1SUQwZ0tHVnNLU0E5UGlCN1hHNGdJR3hsZENCMmFXVjNjRzl5ZEU5bVpuTmxkQ0E5SUdWc0xtZGxkRUp2ZFc1a2FXNW5RMnhwWlc1MFVtVmpkQ2dwTzF4dUlDQnNaWFFnZEc5d0lEMGdkbWxsZDNCdmNuUlBabVp6WlhRdWRHOXdJQ3NnZDJsdVpHOTNMbk5qY205c2JGazdYRzRnSUd4bGRDQnNaV1owSUQwZ2RtbGxkM0J2Y25SUFptWnpaWFF1YkdWbWRDQXJJSGRwYm1SdmR5NXpZM0p2Ykd4WU8xeHVJQ0J5WlhSMWNtNGdlM1J2Y0N4c1pXWjBmVHRjYm4wN1hHNWNibVY0Y0c5eWRITXVjR0Z5YzJWRmJHVnRaVzUwSUQwZ0tIQmhjbVZ1ZENrZ1BUNGdlMXh1SUNCcFppQW9kSGx3Wlc5bUlIQmhjbVZ1ZENBOVBUMGdKM04wY21sdVp5Y3BJSHRjYmlBZ0lDQndZWEpsYm5RZ1BTQmtiMk4xYldWdWRDNW5aWFJGYkdWdFpXNTBRbmxKWkNod1lYSmxiblF1Y21Wd2JHRmpaU2duSXljc0p5Y3BLVHRjYmlBZ2ZWeHVYRzRnSUdsbUlDaHdZWEpsYm5RZ2FXNXpkR0Z1WTJWdlppQklWRTFNUld4bGJXVnVkQ0I4ZkNCd1lYSmxiblFnYVc1emRHRnVZMlZ2WmlCVFZrZEZiR1Z0Wlc1MEtYdGNiaUFnSUNCeVpYUjFjbTRnY0dGeVpXNTBPMXh1SUNCOUlHVnNjMlVnZTF4dUlDQWdJSEpsZEhWeWJpQW5UbThnZG1Gc2FXUWdjR0Z5Wlc1MElHRnlaM1Z0Wlc1MEp6dGNiaUFnZlZ4dWZUdGNibHh1Wlhod2IzSjBjeTVzYjJOaGRHVk5iM1Z6WlNBOUlDaGxMRzltWm5ObGRDa2dQVDRnZTF4dUlDQnlaWFIxY200Z2UxeHVJQ0FnSUhnNklHVXVjR0ZuWlZnZ0xTQnZabVp6WlhRdWJHVm1kQ3hjYmlBZ0lDQjVPaUJsTG5CaFoyVlpJQzBnYjJabWMyVjBMblJ2Y0Z4dUlDQjlPMXh1ZlR0Y2JseHVaWGh3YjNKMGN5NXNiMk5oZEdWVWIzVmphQ0E5SUNobExHOW1abk5sZENrZ1BUNGdlMXh1SUNCeVpYUjFjbTRnZTF4dUlDQWdJSGc2SUdVdWRHRnlaMlYwVkc5MVkyaGxjeTVzWlc1bmRHZ2dQeUJsTG5SaGNtZGxkRlJ2ZFdOb1pYTmJNRjB1Y0dGblpWZ2dMU0J2Wm1aelpYUXViR1ZtZENBNklHWmhiSE5sTEZ4dUlDQWdJSGs2SUdVdWRHRnlaMlYwVkc5MVkyaGxjeTVzWlc1bmRHZ2dQeUJsTG5SaGNtZGxkRlJ2ZFdOb1pYTmJNRjB1Y0dGblpWa2dMU0J2Wm1aelpYUXVkRzl3SURvZ1ptRnNjMlZjYmlBZ2ZUdGNibjA3WEc1Y2JtVjRjRzl5ZEhNdVUyMWhjblJEWVc1MllYTWdQU0JtZFc1amRHbHZiaWh3WVhKbGJuUXBJSHRjYmx4dUlDQjBhR2x6TG1Wc1pXMWxiblFnUFNCa2IyTjFiV1Z1ZEM1amNtVmhkR1ZGYkdWdFpXNTBLQ2RqWVc1MllYTW5LVHRjYmlBZ2RHaHBjeTVqYjI1MFpYaDBJRDBnZEdocGN5NWxiR1Z0Wlc1MExtZGxkRU52Ym5SbGVIUW9KekprSnlrN1hHNGdJSEJoY21WdWRDNWhjSEJsYm1SRGFHbHNaQ2gwYUdsekxtVnNaVzFsYm5RcE8xeHVYRzRnSUhSb2FYTXVjbVZ6YVhwbElEMGdLSGNzYUNrZ1BUNGdlMXh1SUNBZ0lIUm9hWE11Wld4bGJXVnVkQzUzYVdSMGFDQTlJSGNxTWp0Y2JpQWdJQ0IwYUdsekxtVnNaVzFsYm5RdWFHVnBaMmgwSUQwZ2FDb3lPMXh1SUNBZ0lIUm9hWE11Wld4bGJXVnVkQzV6ZEhsc1pTNTNhV1IwYUNBOUlIY3JKM0I0Snp0Y2JpQWdJQ0IwYUdsekxtVnNaVzFsYm5RdWMzUjViR1V1YUdWcFoyaDBJRDBnYUNzbmNIZ25PMXh1SUNCOU8xeHVYRzU5TzF4dVhHNWNibHh1THk4Z1YwVkNVRUZEU3lCR1QwOVVSVklnTHk5Y2JpOHZJQzR2Zmk5cWMyaHBiblF0Ykc5aFpHVnlJUzR2YkdsaUwzVjBhV3d2Wkc5dExtcHpJaXdpSjNWelpTQnpkSEpwWTNRbk8xeHVYRzVsZUhCdmNuUnpMbWx6VDJKcVpXTjBJRDBnS0c5aWFpa2dQVDRnZTF4dUlDQnBaaUFvZEhsd1pXOW1JRzlpYWlBOVBUMGdKMjlpYW1WamRDY2dKaVlnSVVGeWNtRjVMbWx6UVhKeVlYa29iMkpxS1NBbUppQnZZbW9nSVQwOUlHNTFiR3dnSmlZZ2IySnFJR2x1YzNSaGJtTmxiMllnVTFaSFJXeGxiV1Z1ZENBOVBUMGdabUZzYzJVZ0ppWWdiMkpxSUdsdWMzUmhibU5sYjJZZ1NGUk5URVZzWlcxbGJuUWdQVDA5SUdaaGJITmxJQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBjblZsTzF4dUlDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUhKbGRIVnliaUJtWVd4elpUdGNiaUFnZlZ4dWZUdGNibHh1WEc1Y2JpOHZJRmRGUWxCQlEwc2dSazlQVkVWU0lDOHZYRzR2THlBdUwzNHZhbk5vYVc1MExXeHZZV1JsY2lFdUwyeHBZaTkxZEdsc0wzVjBhV3d1YW5NaUxDSW5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JtVjRjRzl5ZEhNdVpYaHBjM1J6SUQwZ0tDZHZiblJ2ZFdOb2MzUmhjblFuSUdsdUlHUnZZM1Z0Wlc1MExtUnZZM1Z0Wlc1MFJXeGxiV1Z1ZENrN1hHNWNibHh1WEc0dkx5QlhSVUpRUVVOTElFWlBUMVJGVWlBdkwxeHVMeThnTGk5K0wycHphR2x1ZEMxc2IyRmtaWEloTGk5c2FXSXZkWFJwYkM5MGIzVmphQzVxY3lJc0lpOHZJRU52Y0hseWFXZG9kQ0JLYjNsbGJuUXNJRWx1WXk0Z1lXNWtJRzkwYUdWeUlFNXZaR1VnWTI5dWRISnBZblYwYjNKekxseHVMeTljYmk4dklGQmxjbTFwYzNOcGIyNGdhWE1nYUdWeVpXSjVJR2R5WVc1MFpXUXNJR1p5WldVZ2IyWWdZMmhoY21kbExDQjBieUJoYm5rZ2NHVnljMjl1SUc5aWRHRnBibWx1WnlCaFhHNHZMeUJqYjNCNUlHOW1JSFJvYVhNZ2MyOW1kSGRoY21VZ1lXNWtJR0Z6YzI5amFXRjBaV1FnWkc5amRXMWxiblJoZEdsdmJpQm1hV3hsY3lBb2RHaGxYRzR2THlCY0lsTnZablIzWVhKbFhDSXBMQ0IwYnlCa1pXRnNJR2x1SUhSb1pTQlRiMlowZDJGeVpTQjNhWFJvYjNWMElISmxjM1J5YVdOMGFXOXVMQ0JwYm1Oc2RXUnBibWRjYmk4dklIZHBkR2h2ZFhRZ2JHbHRhWFJoZEdsdmJpQjBhR1VnY21sbmFIUnpJSFJ2SUhWelpTd2dZMjl3ZVN3Z2JXOWthV1o1TENCdFpYSm5aU3dnY0hWaWJHbHphQ3hjYmk4dklHUnBjM1J5YVdKMWRHVXNJSE4xWW14cFkyVnVjMlVzSUdGdVpDOXZjaUJ6Wld4c0lHTnZjR2xsY3lCdlppQjBhR1VnVTI5bWRIZGhjbVVzSUdGdVpDQjBieUJ3WlhKdGFYUmNiaTh2SUhCbGNuTnZibk1nZEc4Z2QyaHZiU0IwYUdVZ1UyOW1kSGRoY21VZ2FYTWdablZ5Ym1semFHVmtJSFJ2SUdSdklITnZMQ0J6ZFdKcVpXTjBJSFJ2SUhSb1pWeHVMeThnWm05c2JHOTNhVzVuSUdOdmJtUnBkR2x2Ym5NNlhHNHZMMXh1THk4Z1ZHaGxJR0ZpYjNabElHTnZjSGx5YVdkb2RDQnViM1JwWTJVZ1lXNWtJSFJvYVhNZ2NHVnliV2x6YzJsdmJpQnViM1JwWTJVZ2MyaGhiR3dnWW1VZ2FXNWpiSFZrWldSY2JpOHZJR2x1SUdGc2JDQmpiM0JwWlhNZ2IzSWdjM1ZpYzNSaGJuUnBZV3dnY0c5eWRHbHZibk1nYjJZZ2RHaGxJRk52Wm5SM1lYSmxMbHh1THk5Y2JpOHZJRlJJUlNCVFQwWlVWMEZTUlNCSlV5QlFVazlXU1VSRlJDQmNJa0ZUSUVsVFhDSXNJRmRKVkVoUFZWUWdWMEZTVWtGT1ZGa2dUMFlnUVU1WklFdEpUa1FzSUVWWVVGSkZVMU5jYmk4dklFOVNJRWxOVUV4SlJVUXNJRWxPUTB4VlJFbE9SeUJDVlZRZ1RrOVVJRXhKVFVsVVJVUWdWRThnVkVoRklGZEJVbEpCVGxSSlJWTWdUMFpjYmk4dklFMUZVa05JUVU1VVFVSkpURWxVV1N3Z1JrbFVUa1ZUVXlCR1QxSWdRU0JRUVZKVVNVTlZURUZTSUZCVlVsQlBVMFVnUVU1RUlFNVBUa2xPUmxKSlRrZEZUVVZPVkM0Z1NVNWNiaTh2SUU1UElFVldSVTVVSUZOSVFVeE1JRlJJUlNCQlZWUklUMUpUSUU5U0lFTlBVRmxTU1VkSVZDQklUMHhFUlZKVElFSkZJRXhKUVVKTVJTQkdUMUlnUVU1WklFTk1RVWxOTEZ4dUx5OGdSRUZOUVVkRlV5QlBVaUJQVkVoRlVpQk1TVUZDU1V4SlZGa3NJRmRJUlZSSVJWSWdTVTRnUVU0Z1FVTlVTVTlPSUU5R0lFTlBUbFJTUVVOVUxDQlVUMUpVSUU5U1hHNHZMeUJQVkVoRlVsZEpVMFVzSUVGU1NWTkpUa2NnUmxKUFRTd2dUMVZVSUU5R0lFOVNJRWxPSUVOUFRrNUZRMVJKVDA0Z1YwbFVTQ0JVU0VVZ1UwOUdWRmRCVWtVZ1QxSWdWRWhGWEc0dkx5QlZVMFVnVDFJZ1QxUklSVklnUkVWQlRFbE9SMU1nU1U0Z1ZFaEZJRk5QUmxSWFFWSkZMbHh1WEc1bWRXNWpkR2x2YmlCRmRtVnVkRVZ0YVhSMFpYSW9LU0I3WEc0Z0lIUm9hWE11WDJWMlpXNTBjeUE5SUhSb2FYTXVYMlYyWlc1MGN5QjhmQ0I3ZlR0Y2JpQWdkR2hwY3k1ZmJXRjRUR2x6ZEdWdVpYSnpJRDBnZEdocGN5NWZiV0Y0VEdsemRHVnVaWEp6SUh4OElIVnVaR1ZtYVc1bFpEdGNibjFjYm0xdlpIVnNaUzVsZUhCdmNuUnpJRDBnUlhabGJuUkZiV2wwZEdWeU8xeHVYRzR2THlCQ1lXTnJkMkZ5WkhNdFkyOXRjR0YwSUhkcGRHZ2dibTlrWlNBd0xqRXdMbmhjYmtWMlpXNTBSVzFwZEhSbGNpNUZkbVZ1ZEVWdGFYUjBaWElnUFNCRmRtVnVkRVZ0YVhSMFpYSTdYRzVjYmtWMlpXNTBSVzFwZEhSbGNpNXdjbTkwYjNSNWNHVXVYMlYyWlc1MGN5QTlJSFZ1WkdWbWFXNWxaRHRjYmtWMlpXNTBSVzFwZEhSbGNpNXdjbTkwYjNSNWNHVXVYMjFoZUV4cGMzUmxibVZ5Y3lBOUlIVnVaR1ZtYVc1bFpEdGNibHh1THk4Z1Fua2daR1ZtWVhWc2RDQkZkbVZ1ZEVWdGFYUjBaWEp6SUhkcGJHd2djSEpwYm5RZ1lTQjNZWEp1YVc1bklHbG1JRzF2Y21VZ2RHaGhiaUF4TUNCc2FYTjBaVzVsY25NZ1lYSmxYRzR2THlCaFpHUmxaQ0IwYnlCcGRDNGdWR2hwY3lCcGN5QmhJSFZ6WldaMWJDQmtaV1poZFd4MElIZG9hV05vSUdobGJIQnpJR1pwYm1ScGJtY2diV1Z0YjNKNUlHeGxZV3R6TGx4dVJYWmxiblJGYldsMGRHVnlMbVJsWm1GMWJIUk5ZWGhNYVhOMFpXNWxjbk1nUFNBeE1EdGNibHh1THk4Z1QySjJhVzkxYzJ4NUlHNXZkQ0JoYkd3Z1JXMXBkSFJsY25NZ2MyaHZkV3hrSUdKbElHeHBiV2wwWldRZ2RHOGdNVEF1SUZSb2FYTWdablZ1WTNScGIyNGdZV3hzYjNkelhHNHZMeUIwYUdGMElIUnZJR0psSUdsdVkzSmxZWE5sWkM0Z1UyVjBJSFJ2SUhwbGNtOGdabTl5SUhWdWJHbHRhWFJsWkM1Y2JrVjJaVzUwUlcxcGRIUmxjaTV3Y205MGIzUjVjR1V1YzJWMFRXRjRUR2x6ZEdWdVpYSnpJRDBnWm5WdVkzUnBiMjRvYmlrZ2UxeHVJQ0JwWmlBb0lXbHpUblZ0WW1WeUtHNHBJSHg4SUc0Z1BDQXdJSHg4SUdselRtRk9LRzRwS1Z4dUlDQWdJSFJvY205M0lGUjVjR1ZGY25KdmNpZ25iaUJ0ZFhOMElHSmxJR0VnY0c5emFYUnBkbVVnYm5WdFltVnlKeWs3WEc0Z0lIUm9hWE11WDIxaGVFeHBjM1JsYm1WeWN5QTlJRzQ3WEc0Z0lISmxkSFZ5YmlCMGFHbHpPMXh1ZlR0Y2JseHVSWFpsYm5SRmJXbDBkR1Z5TG5CeWIzUnZkSGx3WlM1bGJXbDBJRDBnWm5WdVkzUnBiMjRvZEhsd1pTa2dlMXh1SUNCMllYSWdaWElzSUdoaGJtUnNaWElzSUd4bGJpd2dZWEpuY3l3Z2FTd2diR2x6ZEdWdVpYSnpPMXh1WEc0Z0lHbG1JQ2doZEdocGN5NWZaWFpsYm5SektWeHVJQ0FnSUhSb2FYTXVYMlYyWlc1MGN5QTlJSHQ5TzF4dVhHNGdJQzh2SUVsbUlIUm9aWEpsSUdseklHNXZJQ2RsY25KdmNpY2daWFpsYm5RZ2JHbHpkR1Z1WlhJZ2RHaGxiaUIwYUhKdmR5NWNiaUFnYVdZZ0tIUjVjR1VnUFQwOUlDZGxjbkp2Y2ljcElIdGNiaUFnSUNCcFppQW9JWFJvYVhNdVgyVjJaVzUwY3k1bGNuSnZjaUI4ZkZ4dUlDQWdJQ0FnSUNBb2FYTlBZbXBsWTNRb2RHaHBjeTVmWlhabGJuUnpMbVZ5Y205eUtTQW1KaUFoZEdocGN5NWZaWFpsYm5SekxtVnljbTl5TG14bGJtZDBhQ2twSUh0Y2JpQWdJQ0FnSUdWeUlEMGdZWEpuZFcxbGJuUnpXekZkTzF4dUlDQWdJQ0FnYVdZZ0tHVnlJR2x1YzNSaGJtTmxiMllnUlhKeWIzSXBJSHRjYmlBZ0lDQWdJQ0FnZEdoeWIzY2daWEk3SUM4dklGVnVhR0Z1Wkd4bFpDQW5aWEp5YjNJbklHVjJaVzUwWEc0Z0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0F2THlCQmRDQnNaV0Z6ZENCbmFYWmxJSE52YldVZ2EybHVaQ0J2WmlCamIyNTBaWGgwSUhSdklIUm9aU0IxYzJWeVhHNGdJQ0FnSUNBZ0lIWmhjaUJsY25JZ1BTQnVaWGNnUlhKeWIzSW9KMVZ1WTJGMVoyaDBMQ0IxYm5Od1pXTnBabWxsWkNCY0ltVnljbTl5WENJZ1pYWmxiblF1SUNnbklDc2daWElnS3lBbktTY3BPMXh1SUNBZ0lDQWdJQ0JsY25JdVkyOXVkR1Y0ZENBOUlHVnlPMXh1SUNBZ0lDQWdJQ0IwYUhKdmR5Qmxjbkk3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdmVnh1SUNCOVhHNWNiaUFnYUdGdVpHeGxjaUE5SUhSb2FYTXVYMlYyWlc1MGMxdDBlWEJsWFR0Y2JseHVJQ0JwWmlBb2FYTlZibVJsWm1sdVpXUW9hR0Z1Wkd4bGNpa3BYRzRnSUNBZ2NtVjBkWEp1SUdaaGJITmxPMXh1WEc0Z0lHbG1JQ2hwYzBaMWJtTjBhVzl1S0doaGJtUnNaWElwS1NCN1hHNGdJQ0FnYzNkcGRHTm9JQ2hoY21kMWJXVnVkSE11YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0F2THlCbVlYTjBJR05oYzJWelhHNGdJQ0FnSUNCallYTmxJREU2WEc0Z0lDQWdJQ0FnSUdoaGJtUnNaWEl1WTJGc2JDaDBhR2x6S1R0Y2JpQWdJQ0FnSUNBZ1luSmxZV3M3WEc0Z0lDQWdJQ0JqWVhObElESTZYRzRnSUNBZ0lDQWdJR2hoYm1Sc1pYSXVZMkZzYkNoMGFHbHpMQ0JoY21kMWJXVnVkSE5iTVYwcE8xeHVJQ0FnSUNBZ0lDQmljbVZoYXp0Y2JpQWdJQ0FnSUdOaGMyVWdNenBjYmlBZ0lDQWdJQ0FnYUdGdVpHeGxjaTVqWVd4c0tIUm9hWE1zSUdGeVozVnRaVzUwYzFzeFhTd2dZWEpuZFcxbGJuUnpXekpkS1R0Y2JpQWdJQ0FnSUNBZ1luSmxZV3M3WEc0Z0lDQWdJQ0F2THlCemJHOTNaWEpjYmlBZ0lDQWdJR1JsWm1GMWJIUTZYRzRnSUNBZ0lDQWdJR0Z5WjNNZ1BTQkJjbkpoZVM1d2NtOTBiM1I1Y0dVdWMyeHBZMlV1WTJGc2JDaGhjbWQxYldWdWRITXNJREVwTzF4dUlDQWdJQ0FnSUNCb1lXNWtiR1Z5TG1Gd2NHeDVLSFJvYVhNc0lHRnlaM01wTzF4dUlDQWdJSDFjYmlBZ2ZTQmxiSE5sSUdsbUlDaHBjMDlpYW1WamRDaG9ZVzVrYkdWeUtTa2dlMXh1SUNBZ0lHRnlaM01nUFNCQmNuSmhlUzV3Y205MGIzUjVjR1V1YzJ4cFkyVXVZMkZzYkNoaGNtZDFiV1Z1ZEhNc0lERXBPMXh1SUNBZ0lHeHBjM1JsYm1WeWN5QTlJR2hoYm1Sc1pYSXVjMnhwWTJVb0tUdGNiaUFnSUNCc1pXNGdQU0JzYVhOMFpXNWxjbk11YkdWdVozUm9PMXh1SUNBZ0lHWnZjaUFvYVNBOUlEQTdJR2tnUENCc1pXNDdJR2tyS3lsY2JpQWdJQ0FnSUd4cGMzUmxibVZ5YzF0cFhTNWhjSEJzZVNoMGFHbHpMQ0JoY21kektUdGNiaUFnZlZ4dVhHNGdJSEpsZEhWeWJpQjBjblZsTzF4dWZUdGNibHh1UlhabGJuUkZiV2wwZEdWeUxuQnliM1J2ZEhsd1pTNWhaR1JNYVhOMFpXNWxjaUE5SUdaMWJtTjBhVzl1S0hSNWNHVXNJR3hwYzNSbGJtVnlLU0I3WEc0Z0lIWmhjaUJ0TzF4dVhHNGdJR2xtSUNnaGFYTkdkVzVqZEdsdmJpaHNhWE4wWlc1bGNpa3BYRzRnSUNBZ2RHaHliM2NnVkhsd1pVVnljbTl5S0Nkc2FYTjBaVzVsY2lCdGRYTjBJR0psSUdFZ1puVnVZM1JwYjI0bktUdGNibHh1SUNCcFppQW9JWFJvYVhNdVgyVjJaVzUwY3lsY2JpQWdJQ0IwYUdsekxsOWxkbVZ1ZEhNZ1BTQjdmVHRjYmx4dUlDQXZMeUJVYnlCaGRtOXBaQ0J5WldOMWNuTnBiMjRnYVc0Z2RHaGxJR05oYzJVZ2RHaGhkQ0IwZVhCbElEMDlQU0JjSW01bGQweHBjM1JsYm1WeVhDSWhJRUpsWm05eVpWeHVJQ0F2THlCaFpHUnBibWNnYVhRZ2RHOGdkR2hsSUd4cGMzUmxibVZ5Y3l3Z1ptbHljM1FnWlcxcGRDQmNJbTVsZDB4cGMzUmxibVZ5WENJdVhHNGdJR2xtSUNoMGFHbHpMbDlsZG1WdWRITXVibVYzVEdsemRHVnVaWElwWEc0Z0lDQWdkR2hwY3k1bGJXbDBLQ2R1WlhkTWFYTjBaVzVsY2ljc0lIUjVjR1VzWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJR2x6Um5WdVkzUnBiMjRvYkdsemRHVnVaWEl1YkdsemRHVnVaWElwSUQ5Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnYkdsemRHVnVaWEl1YkdsemRHVnVaWElnT2lCc2FYTjBaVzVsY2lrN1hHNWNiaUFnYVdZZ0tDRjBhR2x6TGw5bGRtVnVkSE5iZEhsd1pWMHBYRzRnSUNBZ0x5OGdUM0IwYVcxcGVtVWdkR2hsSUdOaGMyVWdiMllnYjI1bElHeHBjM1JsYm1WeUxpQkViMjRuZENCdVpXVmtJSFJvWlNCbGVIUnlZU0JoY25KaGVTQnZZbXBsWTNRdVhHNGdJQ0FnZEdocGN5NWZaWFpsYm5SelczUjVjR1ZkSUQwZ2JHbHpkR1Z1WlhJN1hHNGdJR1ZzYzJVZ2FXWWdLR2x6VDJKcVpXTjBLSFJvYVhNdVgyVjJaVzUwYzF0MGVYQmxYU2twWEc0Z0lDQWdMeThnU1dZZ2QyVW5kbVVnWVd4eVpXRmtlU0JuYjNRZ1lXNGdZWEp5WVhrc0lHcDFjM1FnWVhCd1pXNWtMbHh1SUNBZ0lIUm9hWE11WDJWMlpXNTBjMXQwZVhCbFhTNXdkWE5vS0d4cGMzUmxibVZ5S1R0Y2JpQWdaV3h6WlZ4dUlDQWdJQzh2SUVGa1pHbHVaeUIwYUdVZ2MyVmpiMjVrSUdWc1pXMWxiblFzSUc1bFpXUWdkRzhnWTJoaGJtZGxJSFJ2SUdGeWNtRjVMbHh1SUNBZ0lIUm9hWE11WDJWMlpXNTBjMXQwZVhCbFhTQTlJRnQwYUdsekxsOWxkbVZ1ZEhOYmRIbHdaVjBzSUd4cGMzUmxibVZ5WFR0Y2JseHVJQ0F2THlCRGFHVmpheUJtYjNJZ2JHbHpkR1Z1WlhJZ2JHVmhhMXh1SUNCcFppQW9hWE5QWW1wbFkzUW9kR2hwY3k1ZlpYWmxiblJ6VzNSNWNHVmRLU0FtSmlBaGRHaHBjeTVmWlhabGJuUnpXM1I1Y0dWZExuZGhjbTVsWkNrZ2UxeHVJQ0FnSUdsbUlDZ2hhWE5WYm1SbFptbHVaV1FvZEdocGN5NWZiV0Y0VEdsemRHVnVaWEp6S1NrZ2UxeHVJQ0FnSUNBZ2JTQTlJSFJvYVhNdVgyMWhlRXhwYzNSbGJtVnljenRjYmlBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ2JTQTlJRVYyWlc1MFJXMXBkSFJsY2k1a1pXWmhkV3gwVFdGNFRHbHpkR1Z1WlhKek8xeHVJQ0FnSUgxY2JseHVJQ0FnSUdsbUlDaHRJQ1ltSUcwZ1BpQXdJQ1ltSUhSb2FYTXVYMlYyWlc1MGMxdDBlWEJsWFM1c1pXNW5kR2dnUGlCdEtTQjdYRzRnSUNBZ0lDQjBhR2x6TGw5bGRtVnVkSE5iZEhsd1pWMHVkMkZ5Ym1Wa0lEMGdkSEoxWlR0Y2JpQWdJQ0FnSUdOdmJuTnZiR1V1WlhKeWIzSW9KeWh1YjJSbEtTQjNZWEp1YVc1bk9pQndiM056YVdKc1pTQkZkbVZ1ZEVWdGFYUjBaWElnYldWdGIzSjVJQ2NnSzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQW5iR1ZoYXlCa1pYUmxZM1JsWkM0Z0pXUWdiR2x6ZEdWdVpYSnpJR0ZrWkdWa0xpQW5JQ3RjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0oxVnpaU0JsYldsMGRHVnlMbk5sZEUxaGVFeHBjM1JsYm1WeWN5Z3BJSFJ2SUdsdVkzSmxZWE5sSUd4cGJXbDBMaWNzWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIUm9hWE11WDJWMlpXNTBjMXQwZVhCbFhTNXNaVzVuZEdncE8xeHVJQ0FnSUNBZ2FXWWdLSFI1Y0dWdlppQmpiMjV6YjJ4bExuUnlZV05sSUQwOVBTQW5ablZ1WTNScGIyNG5LU0I3WEc0Z0lDQWdJQ0FnSUM4dklHNXZkQ0J6ZFhCd2IzSjBaV1FnYVc0Z1NVVWdNVEJjYmlBZ0lDQWdJQ0FnWTI5dWMyOXNaUzUwY21GalpTZ3BPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lIMWNiaUFnZlZ4dVhHNGdJSEpsZEhWeWJpQjBhR2x6TzF4dWZUdGNibHh1UlhabGJuUkZiV2wwZEdWeUxuQnliM1J2ZEhsd1pTNXZiaUE5SUVWMlpXNTBSVzFwZEhSbGNpNXdjbTkwYjNSNWNHVXVZV1JrVEdsemRHVnVaWEk3WEc1Y2JrVjJaVzUwUlcxcGRIUmxjaTV3Y205MGIzUjVjR1V1YjI1alpTQTlJR1oxYm1OMGFXOXVLSFI1Y0dVc0lHeHBjM1JsYm1WeUtTQjdYRzRnSUdsbUlDZ2hhWE5HZFc1amRHbHZiaWhzYVhOMFpXNWxjaWtwWEc0Z0lDQWdkR2h5YjNjZ1ZIbHdaVVZ5Y205eUtDZHNhWE4wWlc1bGNpQnRkWE4wSUdKbElHRWdablZ1WTNScGIyNG5LVHRjYmx4dUlDQjJZWElnWm1seVpXUWdQU0JtWVd4elpUdGNibHh1SUNCbWRXNWpkR2x2YmlCbktDa2dlMXh1SUNBZ0lIUm9hWE11Y21WdGIzWmxUR2x6ZEdWdVpYSW9kSGx3WlN3Z1p5azdYRzVjYmlBZ0lDQnBaaUFvSVdacGNtVmtLU0I3WEc0Z0lDQWdJQ0JtYVhKbFpDQTlJSFJ5ZFdVN1hHNGdJQ0FnSUNCc2FYTjBaVzVsY2k1aGNIQnNlU2gwYUdsekxDQmhjbWQxYldWdWRITXBPMXh1SUNBZ0lIMWNiaUFnZlZ4dVhHNGdJR2N1YkdsemRHVnVaWElnUFNCc2FYTjBaVzVsY2p0Y2JpQWdkR2hwY3k1dmJpaDBlWEJsTENCbktUdGNibHh1SUNCeVpYUjFjbTRnZEdocGN6dGNibjA3WEc1Y2JpOHZJR1Z0YVhSeklHRWdKM0psYlc5MlpVeHBjM1JsYm1WeUp5QmxkbVZ1ZENCcFptWWdkR2hsSUd4cGMzUmxibVZ5SUhkaGN5QnlaVzF2ZG1Wa1hHNUZkbVZ1ZEVWdGFYUjBaWEl1Y0hKdmRHOTBlWEJsTG5KbGJXOTJaVXhwYzNSbGJtVnlJRDBnWm5WdVkzUnBiMjRvZEhsd1pTd2diR2x6ZEdWdVpYSXBJSHRjYmlBZ2RtRnlJR3hwYzNRc0lIQnZjMmwwYVc5dUxDQnNaVzVuZEdnc0lHazdYRzVjYmlBZ2FXWWdLQ0ZwYzBaMWJtTjBhVzl1S0d4cGMzUmxibVZ5S1NsY2JpQWdJQ0IwYUhKdmR5QlVlWEJsUlhKeWIzSW9KMnhwYzNSbGJtVnlJRzExYzNRZ1ltVWdZU0JtZFc1amRHbHZiaWNwTzF4dVhHNGdJR2xtSUNnaGRHaHBjeTVmWlhabGJuUnpJSHg4SUNGMGFHbHpMbDlsZG1WdWRITmJkSGx3WlYwcFhHNGdJQ0FnY21WMGRYSnVJSFJvYVhNN1hHNWNiaUFnYkdsemRDQTlJSFJvYVhNdVgyVjJaVzUwYzF0MGVYQmxYVHRjYmlBZ2JHVnVaM1JvSUQwZ2JHbHpkQzVzWlc1bmRHZzdYRzRnSUhCdmMybDBhVzl1SUQwZ0xURTdYRzVjYmlBZ2FXWWdLR3hwYzNRZ1BUMDlJR3hwYzNSbGJtVnlJSHg4WEc0Z0lDQWdJQ0FvYVhOR2RXNWpkR2x2Ymloc2FYTjBMbXhwYzNSbGJtVnlLU0FtSmlCc2FYTjBMbXhwYzNSbGJtVnlJRDA5UFNCc2FYTjBaVzVsY2lrcElIdGNiaUFnSUNCa1pXeGxkR1VnZEdocGN5NWZaWFpsYm5SelczUjVjR1ZkTzF4dUlDQWdJR2xtSUNoMGFHbHpMbDlsZG1WdWRITXVjbVZ0YjNabFRHbHpkR1Z1WlhJcFhHNGdJQ0FnSUNCMGFHbHpMbVZ0YVhRb0ozSmxiVzkyWlV4cGMzUmxibVZ5Snl3Z2RIbHdaU3dnYkdsemRHVnVaWElwTzF4dVhHNGdJSDBnWld4elpTQnBaaUFvYVhOUFltcGxZM1FvYkdsemRDa3BJSHRjYmlBZ0lDQm1iM0lnS0drZ1BTQnNaVzVuZEdnN0lHa3RMU0ErSURBN0tTQjdYRzRnSUNBZ0lDQnBaaUFvYkdsemRGdHBYU0E5UFQwZ2JHbHpkR1Z1WlhJZ2ZIeGNiaUFnSUNBZ0lDQWdJQ0FvYkdsemRGdHBYUzVzYVhOMFpXNWxjaUFtSmlCc2FYTjBXMmxkTG14cGMzUmxibVZ5SUQwOVBTQnNhWE4wWlc1bGNpa3BJSHRjYmlBZ0lDQWdJQ0FnY0c5emFYUnBiMjRnUFNCcE8xeHVJQ0FnSUNBZ0lDQmljbVZoYXp0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc1Y2JpQWdJQ0JwWmlBb2NHOXphWFJwYjI0Z1BDQXdLVnh1SUNBZ0lDQWdjbVYwZFhKdUlIUm9hWE03WEc1Y2JpQWdJQ0JwWmlBb2JHbHpkQzVzWlc1bmRHZ2dQVDA5SURFcElIdGNiaUFnSUNBZ0lHeHBjM1F1YkdWdVozUm9JRDBnTUR0Y2JpQWdJQ0FnSUdSbGJHVjBaU0IwYUdsekxsOWxkbVZ1ZEhOYmRIbHdaVjA3WEc0Z0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lHeHBjM1F1YzNCc2FXTmxLSEJ2YzJsMGFXOXVMQ0F4S1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0JwWmlBb2RHaHBjeTVmWlhabGJuUnpMbkpsYlc5MlpVeHBjM1JsYm1WeUtWeHVJQ0FnSUNBZ2RHaHBjeTVsYldsMEtDZHlaVzF2ZG1WTWFYTjBaVzVsY2ljc0lIUjVjR1VzSUd4cGMzUmxibVZ5S1R0Y2JpQWdmVnh1WEc0Z0lISmxkSFZ5YmlCMGFHbHpPMXh1ZlR0Y2JseHVSWFpsYm5SRmJXbDBkR1Z5TG5CeWIzUnZkSGx3WlM1eVpXMXZkbVZCYkd4TWFYTjBaVzVsY25NZ1BTQm1kVzVqZEdsdmJpaDBlWEJsS1NCN1hHNGdJSFpoY2lCclpYa3NJR3hwYzNSbGJtVnljenRjYmx4dUlDQnBaaUFvSVhSb2FYTXVYMlYyWlc1MGN5bGNiaUFnSUNCeVpYUjFjbTRnZEdocGN6dGNibHh1SUNBdkx5QnViM1FnYkdsemRHVnVhVzVuSUdadmNpQnlaVzF2ZG1WTWFYTjBaVzVsY2l3Z2JtOGdibVZsWkNCMGJ5QmxiV2wwWEc0Z0lHbG1JQ2doZEdocGN5NWZaWFpsYm5SekxuSmxiVzkyWlV4cGMzUmxibVZ5S1NCN1hHNGdJQ0FnYVdZZ0tHRnlaM1Z0Wlc1MGN5NXNaVzVuZEdnZ1BUMDlJREFwWEc0Z0lDQWdJQ0IwYUdsekxsOWxkbVZ1ZEhNZ1BTQjdmVHRjYmlBZ0lDQmxiSE5sSUdsbUlDaDBhR2x6TGw5bGRtVnVkSE5iZEhsd1pWMHBYRzRnSUNBZ0lDQmtaV3hsZEdVZ2RHaHBjeTVmWlhabGJuUnpXM1I1Y0dWZE8xeHVJQ0FnSUhKbGRIVnliaUIwYUdsek8xeHVJQ0I5WEc1Y2JpQWdMeThnWlcxcGRDQnlaVzF2ZG1WTWFYTjBaVzVsY2lCbWIzSWdZV3hzSUd4cGMzUmxibVZ5Y3lCdmJpQmhiR3dnWlhabGJuUnpYRzRnSUdsbUlDaGhjbWQxYldWdWRITXViR1Z1WjNSb0lEMDlQU0F3S1NCN1hHNGdJQ0FnWm05eUlDaHJaWGtnYVc0Z2RHaHBjeTVmWlhabGJuUnpLU0I3WEc0Z0lDQWdJQ0JwWmlBb2EyVjVJRDA5UFNBbmNtVnRiM1psVEdsemRHVnVaWEluS1NCamIyNTBhVzUxWlR0Y2JpQWdJQ0FnSUhSb2FYTXVjbVZ0YjNabFFXeHNUR2x6ZEdWdVpYSnpLR3RsZVNrN1hHNGdJQ0FnZlZ4dUlDQWdJSFJvYVhNdWNtVnRiM1psUVd4c1RHbHpkR1Z1WlhKektDZHlaVzF2ZG1WTWFYTjBaVzVsY2ljcE8xeHVJQ0FnSUhSb2FYTXVYMlYyWlc1MGN5QTlJSHQ5TzF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TzF4dUlDQjlYRzVjYmlBZ2JHbHpkR1Z1WlhKeklEMGdkR2hwY3k1ZlpYWmxiblJ6VzNSNWNHVmRPMXh1WEc0Z0lHbG1JQ2hwYzBaMWJtTjBhVzl1S0d4cGMzUmxibVZ5Y3lrcElIdGNiaUFnSUNCMGFHbHpMbkpsYlc5MlpVeHBjM1JsYm1WeUtIUjVjR1VzSUd4cGMzUmxibVZ5Y3lrN1hHNGdJSDBnWld4elpTQnBaaUFvYkdsemRHVnVaWEp6S1NCN1hHNGdJQ0FnTHk4Z1RFbEdUeUJ2Y21SbGNseHVJQ0FnSUhkb2FXeGxJQ2hzYVhOMFpXNWxjbk11YkdWdVozUm9LVnh1SUNBZ0lDQWdkR2hwY3k1eVpXMXZkbVZNYVhOMFpXNWxjaWgwZVhCbExDQnNhWE4wWlc1bGNuTmJiR2x6ZEdWdVpYSnpMbXhsYm1kMGFDQXRJREZkS1R0Y2JpQWdmVnh1SUNCa1pXeGxkR1VnZEdocGN5NWZaWFpsYm5SelczUjVjR1ZkTzF4dVhHNGdJSEpsZEhWeWJpQjBhR2x6TzF4dWZUdGNibHh1UlhabGJuUkZiV2wwZEdWeUxuQnliM1J2ZEhsd1pTNXNhWE4wWlc1bGNuTWdQU0JtZFc1amRHbHZiaWgwZVhCbEtTQjdYRzRnSUhaaGNpQnlaWFE3WEc0Z0lHbG1JQ2doZEdocGN5NWZaWFpsYm5SeklIeDhJQ0YwYUdsekxsOWxkbVZ1ZEhOYmRIbHdaVjBwWEc0Z0lDQWdjbVYwSUQwZ1cxMDdYRzRnSUdWc2MyVWdhV1lnS0dselJuVnVZM1JwYjI0b2RHaHBjeTVmWlhabGJuUnpXM1I1Y0dWZEtTbGNiaUFnSUNCeVpYUWdQU0JiZEdocGN5NWZaWFpsYm5SelczUjVjR1ZkWFR0Y2JpQWdaV3h6WlZ4dUlDQWdJSEpsZENBOUlIUm9hWE11WDJWMlpXNTBjMXQwZVhCbFhTNXpiR2xqWlNncE8xeHVJQ0J5WlhSMWNtNGdjbVYwTzF4dWZUdGNibHh1UlhabGJuUkZiV2wwZEdWeUxuQnliM1J2ZEhsd1pTNXNhWE4wWlc1bGNrTnZkVzUwSUQwZ1puVnVZM1JwYjI0b2RIbHdaU2tnZTF4dUlDQnBaaUFvZEdocGN5NWZaWFpsYm5SektTQjdYRzRnSUNBZ2RtRnlJR1YyYkdsemRHVnVaWElnUFNCMGFHbHpMbDlsZG1WdWRITmJkSGx3WlYwN1hHNWNiaUFnSUNCcFppQW9hWE5HZFc1amRHbHZiaWhsZG14cGMzUmxibVZ5S1NsY2JpQWdJQ0FnSUhKbGRIVnliaUF4TzF4dUlDQWdJR1ZzYzJVZ2FXWWdLR1YyYkdsemRHVnVaWElwWEc0Z0lDQWdJQ0J5WlhSMWNtNGdaWFpzYVhOMFpXNWxjaTVzWlc1bmRHZzdYRzRnSUgxY2JpQWdjbVYwZFhKdUlEQTdYRzU5TzF4dVhHNUZkbVZ1ZEVWdGFYUjBaWEl1YkdsemRHVnVaWEpEYjNWdWRDQTlJR1oxYm1OMGFXOXVLR1Z0YVhSMFpYSXNJSFI1Y0dVcElIdGNiaUFnY21WMGRYSnVJR1Z0YVhSMFpYSXViR2x6ZEdWdVpYSkRiM1Z1ZENoMGVYQmxLVHRjYm4wN1hHNWNibVoxYm1OMGFXOXVJR2x6Um5WdVkzUnBiMjRvWVhKbktTQjdYRzRnSUhKbGRIVnliaUIwZVhCbGIyWWdZWEpuSUQwOVBTQW5ablZ1WTNScGIyNG5PMXh1ZlZ4dVhHNW1kVzVqZEdsdmJpQnBjMDUxYldKbGNpaGhjbWNwSUh0Y2JpQWdjbVYwZFhKdUlIUjVjR1Z2WmlCaGNtY2dQVDA5SUNkdWRXMWlaWEluTzF4dWZWeHVYRzVtZFc1amRHbHZiaUJwYzA5aWFtVmpkQ2hoY21jcElIdGNiaUFnY21WMGRYSnVJSFI1Y0dWdlppQmhjbWNnUFQwOUlDZHZZbXBsWTNRbklDWW1JR0Z5WnlBaFBUMGdiblZzYkR0Y2JuMWNibHh1Wm5WdVkzUnBiMjRnYVhOVmJtUmxabWx1WldRb1lYSm5LU0I3WEc0Z0lISmxkSFZ5YmlCaGNtY2dQVDA5SUhadmFXUWdNRHRjYm4xY2JseHVYRzVjYmk4dkx5OHZMeTh2THk4dkx5OHZMeTh2TDF4dUx5OGdWMFZDVUVGRFN5QkdUMDlVUlZKY2JpOHZJQzR2Zmk5bGRtVnVkSE12WlhabGJuUnpMbXB6WEc0dkx5QnRiMlIxYkdVZ2FXUWdQU0F4TUZ4dUx5OGdiVzlrZFd4bElHTm9kVzVyY3lBOUlEQWlMQ0luZFhObElITjBjbWxqZENjN1hHNWNibXhsZENCdFlYUm9JRDBnY21WeGRXbHlaU2duTGk0dmRYUnBiQzl0WVhSb0p5azdYRzVjYmk4cUtseHVJQ0JEY21WaGRHVnpJR0VnYzNSbGNIQmhZbXhsSUhaaGJIVmxJSGRwZEdnZ2JXbHVhVzExYlN3Z2JXRjRhVzExYlN3Z1lXNWtJSE4wWlhBZ2MybDZaUzRnVkdocGN5QnBjeUIxYzJWa0lHbHVJRzFoYm5rZ2FXNTBaWEptWVdObGN5QjBieUJqYjI1emRISnBZM1FnZEdobGFYSWdkbUZzZFdWeklIUnZJR05sY25SaGFXNGdjbUZ1WjJWekxseHVJQ0JBY0dGeVlXMGdlMjUxYldKbGNuMGdXMjFwYmowd1hTQnRhVzVwYlhWdFhHNGdJRUJ3WVhKaGJTQjdiblZ0WW1WeWZTQmJiV0Y0UFRGZElHMWhlR2x0ZFcxY2JpQWdRSEJoY21GdElIdHVkVzFpWlhKOUlGdHpkR1Z3UFRCZFhHNGdJRUJ3WVhKaGJTQjdiblZ0WW1WeWZTQmJkbUZzZFdVOU1GMGdhVzVwZEdsaGJDQjJZV3gxWlZ4dUlDQkFjbVYwZFhKdWN5QjdUMkpxWldOMGZTQlRkR1Z3WEc0cUwxeHVYRzVsZUhCdmNuUWdaR1ZtWVhWc2RDQmpiR0Z6Y3lCVGRHVndJSHRjYmx4dUlDQmpiMjV6ZEhKMVkzUnZjaWh0YVc0Z1BTQXdMRzFoZUNBOUlERXNjM1JsY0NBOUlEQXNkbUZzZFdVZ1BTQXdLU0I3WEc0Z0lDQWdMeTlQWW1wbFkzUXVZWE56YVdkdUtIUm9hWE1zZTIxcGJpeHRZWGdzYzNSbGNIMHBPMXh1SUNBZ0lDOHZRMkZ1Ym05MElIVnpaU0JQWW1wbFkzUXVZWE56YVdkdUlHSmxZMkYxYzJVZ2JtOTBJSE4xY0hCdmNuUmxaQ0JwYmlCVFlXWmhjbWt1WEc0Z0lDQWdMeTlKSUhkdmRXeGtJR1Y0Y0dWamRDQm1iM0lnUW1GaVpXd2dkRzhnZEdGclpTQmpZWEpsSUc5bUlIUm9hWE1nWW5WMElHbDBJR2x6SUc1dmRDNWNiaUFnSUNCMGFHbHpMbTFwYmlBOUlHMXBianRjYmlBZ0lDQjBhR2x6TG0xaGVDQTlJRzFoZUR0Y2JpQWdJQ0IwYUdsekxuTjBaWEFnUFNCemRHVndPMXh1SUNBZ0lIUm9hWE11ZG1Gc2RXVWdQU0IyWVd4MVpUdGNiaUFnSUNCMGFHbHpMbU5vWVc1blpXUWdQU0JtWVd4elpUdGNiaUFnSUNCMGFHbHpMbTlzWkZaaGJIVmxJRDBnWm1Gc2MyVTdYRzRnSUNBZ2RHaHBjeTUxY0dSaGRHVW9kR2hwY3k1MllXeDFaU2s3WEc0Z0lIMWNibHh1SUNBdktpcGNiaUFnSUNCVmNHUmhkR1VnZDJsMGFDQmhJRzVsZHlCMllXeDFaUzRnVkdobElIWmhiSFZsSUhkcGJHd2dZbVVnWVhWMGJ5MWhaR3AxYzNSbFpDQjBieUJtYVhRZ2RHaGxJRzFwYmk5dFlYZ3ZjM1JsY0M1Y2JpQWdJQ0JBY0dGeVlXMGdlMjUxYldKbGNuMGdkbUZzZFdWY2JpQWdLaTljYmx4dUlDQjFjR1JoZEdVb2RtRnNkV1VwSUh0Y2JpQWdJQ0JwWmlBb2RHaHBjeTV6ZEdWd0tTQjdYRzRnSUNBZ0lDQXZMeUIwYUdsekxuWmhiSFZsSUQwZ2JXRjBhQzVqYkdsd0tFMWhkR2d1Y205MWJtUW9kbUZzZFdVZ0x5QW9kR2hwY3k1emRHVndLU2tnS2lCMGFHbHpMbk4wWlhBc0lIUm9hWE11YldsdUxIUm9hWE11YldGNEtUdGNiaUFnSUNBZ0lIUm9hWE11ZG1Gc2RXVWdQU0J0WVhSb0xtTnNhWEFvVFdGMGFDNXliM1Z1WkNnb2RtRnNkV1V0ZEdocGN5NXRhVzRwSUM4Z0tIUm9hWE11YzNSbGNDa3BJQ29nZEdocGN5NXpkR1Z3SUNzZ2RHaHBjeTV0YVc0c0lIUm9hWE11YldsdUxIUm9hWE11YldGNEtUdGNiaUFnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnZEdocGN5NTJZV3gxWlNBOUlHMWhkR2d1WTJ4cGNDaDJZV3gxWlN4MGFHbHpMbTFwYml4MGFHbHpMbTFoZUNrN1hHNGdJQ0FnZlZ4dUlDQWdJR2xtSUNoMGFHbHpMbTlzWkZaaGJIVmxJQ0U5UFNCMGFHbHpMblpoYkhWbEtTQjdYRzRnSUNBZ0lDQjBhR2x6TG05c1pGWmhiSFZsSUQwZ2RHaHBjeTUyWVd4MVpUdGNiaUFnSUNBZ0lIUm9hWE11WTJoaGJtZGxaQ0E5SUhSeWRXVTdYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUhSb2FYTXVZMmhoYm1kbFpDQTlJR1poYkhObE8xeHVJQ0FnSUgxY2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1MllXeDFaVHRjYmlBZ2ZWeHVYRzRnSUM4cUtseHVJQ0FnSUZWd1pHRjBaU0IzYVhSb0lHRWdibTl5YldGc2FYcGxaQ0IyWVd4MVpTQXdMVEV1WEc0Z0lDQWdRSEJoY21GdElIdHVkVzFpWlhKOUlIWmhiSFZsWEc0Z0lDb3ZYRzRnSUhWd1pHRjBaVTV2Y20xaGJDaDJZV3gxWlNrZ2UxeHVJQ0FnSUhSb2FYTXVkbUZzZFdVZ1BTQnRZWFJvTG5OallXeGxLSFpoYkhWbExEQXNNU3gwYUdsekxtMXBiaXgwYUdsekxtMWhlQ2s3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZFhCa1lYUmxLSFJvYVhNdWRtRnNkV1VwTzF4dUlDQjlYRzVjYmlBZ0x5b3FYRzRnSUNBZ1IyVjBJR0VnYm05eWJXRnNhWHBsWkNCMlpYSnphVzl1SUc5bUlIUm9hWE11ZG1Gc2RXVWdMaUJPYjNRZ2MyVjBkR0ZpYkdVdVhHNGdJQ292WEc0Z0lHZGxkQ0J1YjNKdFlXeHBlbVZrS0NrZ2UxeHVJQ0FnSUhKbGRIVnliaUJ0WVhSb0xtNXZjbTFoYkdsNlpTaDBhR2x6TG5aaGJIVmxMSFJvYVhNdWJXbHVMSFJvYVhNdWJXRjRLVHRjYmlBZ2ZWeHVYRzU5WEc1Y2JseHVYRzR2THlCWFJVSlFRVU5MSUVaUFQxUkZVaUF2TDF4dUx5OGdMaTkrTDJwemFHbHVkQzFzYjJGa1pYSWhMaTlzYVdJdmJXOWtaV3h6TDNOMFpYQXVhbk1pTENJbmRYTmxJSE4wY21samRDYzdYRzVjYm1sdGNHOXlkQ0J0WVhSb0lHWnliMjBnSnk0dUwzVjBhV3d2YldGMGFDYzdYRzVwYlhCdmNuUWdWRzluWjJ4bFRXOWtaV3dnWm5KdmJTQW5MaTR2Ylc5a1pXeHpMM1J2WjJkc1pTYzdYRzVjYmx4dUx5cGNibWh2ZHlCMGJ5QjFjMlVnT2x4dVhHNWthV0ZzTG1sdWRHVnlZV04wYVc5dUlEMGdibVYzSUVoaGJtUnNaU2duY21Ga2FXRnNKeXduY21Wc1lYUnBkbVVuTEhSb2FYTXVkMmxrZEdnc2RHaHBjeTVvWldsbmFIUXBPMXh1THk4Z1pHbGhiQzVwYm5SbGNtRmpkR2x2Ymk1dGIyUmxJRDBnSjNKbGJHRjBhWFpsSjF4dUx5OGdaR2xoYkM1cGJuUmxjbUZqZEdsdmJpNWthWEpsWTNScGIyNGdQU0FuY21Ga2FXRnNKMXh1WEc1dmJpQmpiR2xqYXpwY2JtUnBZV3d1YVc1MFpYSmhZM1JwYjI0dVlXNWphRzl5SUQwZ2RHaHBjeTV0YjNWelpUdGNibHh1YjI0Z2JXOTJaVHBjYm1ScFlXd3VhVzUwWlhKaFkzUnBiMjR1ZFhCa1lYUmxLSFJvYVhNdWJXOTFjMlVwTzF4dVhHNWpiMjV6YjJ4bExteHZaeWdnWkdsaGJDNXBiblJsY21GamRHbHZiaTUyWVd4MVpTQXBPeUJ6YUc5MWJHUWdZbVVnWVNCdWIzSnRZV3hwZW1Wa0lIWmhiSFZsTGx4dVhHNHFMMXh1WEc0dktseHVJQ0JoWW5OdmJIVjBaUzl5Wld4aGRHbDJaU0JoY21VZ2NISnZjR1Z5ZEhrNklHMXZaR1ZjYmlBZ2NtRmthV0ZzTDNabGNuUnBZMkZzTDJodmNtbDZiMjUwWVd3dk1tUWdZWEpsSUhCeWIzQmxjblI1T2lCa2FYSmxZM1JwYjI1Y2JseHVJQ0J3YkdGdUlEcGNibHh1SUNCcFppQnlaV3hoZEdsMlpTQXRMVnh1SUNCT1R5QnZiaUJqYkdsamF5d2daMlYwSUhaaGJIVmxJRzltWm5ObGRDQmlaWFIzWldWdUlHTjFjbkpsYm5RZ2RtRnNkV1VnWVc1a0lHTnNhV05ySUhaaGJIVmxMbHh1SUNCT1R5QnZiaUJ0YjNabExDQjFjMlVnWTJ4cFkyc2dkbUZzZFdVZ0xTQnZabVp6WlhSY2JpQWdTVTVUVkVWQlJGeHVJQ0IxYzJVZ1pHVnNkR0VnTFMwZ1ltTWdkbVZ5ZEdsallXd2diVzkwYVc5dUlHOXVJR1JwWVd3Z2FYTWdhVzF3YjNOemFXSnNaU0J2ZEdobGNuZHBjMlZjYmlBZ1lXeHpieUJoYkd4dmR5QjBieUJ6WlhRZ2MyVnVjMmwwYVhacGRIbGNibHh1S2k5Y2JseHVaWGh3YjNKMElHTnNZWE56SUVoaGJtUnNaU0I3WEc1Y2JpQWdZMjl1YzNSeWRXTjBiM0lvYlc5a1pUMG5ZV0p6YjJ4MWRHVW5MR1JwY21WamRHbHZiajBuZG1WeWRHbGpZV3duTEhoaWIzVnVaRDFiTUN3eE1EQmRMSGxpYjNWdVpEMWJNQ3d4TURCZEtTQjdYRzRnSUNBZ2RHaHBjeTV0YjJSbElEMGdiVzlrWlR0Y2JpQWdJQ0IwYUdsekxtUnBjbVZqZEdsdmJpQTlJR1JwY21WamRHbHZianRjYmlBZ0lDQjBhR2x6TG5CeVpYWnBiM1Z6SUQwZ01EdGNiaUFnSUNCMGFHbHpMblpoYkhWbElEMGdNRHRjYmlBZ0lDQjBhR2x6TG5ObGJuTnBkR2wyYVhSNUlEMGdNVHRjYmlBZ0lDQjBhR2x6TG5KbGMybDZaU2g0WW05MWJtUXNlV0p2ZFc1a0tUdGNiaUFnZlZ4dVhHNGdJSEpsYzJsNlpTaDRZbTkxYm1Rc2VXSnZkVzVrS1NCN1hHNGdJQ0FnZEdocGN5NWliM1Z1WkdGeWVTQTlJSHRjYmlBZ0lDQWdJRzFwYmpvZ2UxeHVJQ0FnSUNBZ0lDQjRPaUI0WW05MWJtUmJNRjBzWEc0Z0lDQWdJQ0FnSUhrNklIbGliM1Z1WkZzd1hWeHVJQ0FnSUNBZ2ZTeGNiaUFnSUNBZ0lHMWhlRG9nZTF4dUlDQWdJQ0FnSUNCNE9pQjRZbTkxYm1SYk1WMHNYRzRnSUNBZ0lDQWdJSGs2SUhsaWIzVnVaRnN4WFZ4dUlDQWdJQ0FnZlN4Y2JpQWdJQ0FnSUdObGJuUmxjam9nZTF4dUlDQWdJQ0FnSUNCNE9pQW9lR0p2ZFc1a1d6RmRJQzBnZUdKdmRXNWtXekJkS1M4eUlDc2dlR0p2ZFc1a1d6QmRMRnh1SUNBZ0lDQWdJQ0I1T2lBb2VXSnZkVzVrV3pGZElDMGdlV0p2ZFc1a1d6QmRLUzh5SUNzZ2VXSnZkVzVrV3pCZFhHNGdJQ0FnSUNCOVhHNGdJQ0FnZlR0Y2JpQWdmVnh1WEc0Z0lITmxkQ0JoYm1Ob2IzSW9iVzkxYzJVcElIdGNiaUFnSUNCMGFHbHpMbDloYm1Ob2IzSWdQU0IwYUdsekxtTnZiblpsY25SUWIzTnBkR2x2YmxSdlZtRnNkV1VvYlc5MWMyVXBPMXh1SUNCOVhHNWNiaUFnWjJWMElHRnVZMmh2Y2lncElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWZZVzVqYUc5eU8xeHVJQ0I5WEc1Y2JseHVJQ0IxY0dSaGRHVW9iVzkxYzJVcElIdGNiaUFnSUNCcFppQW9kR2hwY3k1dGIyUmxQVDA5SjNKbGJHRjBhWFpsSnlrZ2UxeHVJQ0FnSUNBZ2JHVjBJR2x1WTNKbGJXVnVkQ0E5SUhSb2FYTXVZMjl1ZG1WeWRGQnZjMmwwYVc5dVZHOVdZV3gxWlNodGIzVnpaU2tnTFNCMGFHbHpMbUZ1WTJodmNqdGNiaUFnSUNBZ0lHbG1JQ2hOWVhSb0xtRmljeWhwYm1OeVpXMWxiblFwSUQ0Z01DNDFLU0I3SUdsdVkzSmxiV1Z1ZENBOUlEQTdJSDFjYmlBZ0lDQWdJSFJvYVhNdVlXNWphRzl5SUQwZ2JXOTFjMlU3WEc0Z0lDQWdJQ0IwYUdsekxuWmhiSFZsSUQwZ2RHaHBjeTUyWVd4MVpTQXJJR2x1WTNKbGJXVnVkQ0FxSUhSb2FYTXVjMlZ1YzJsMGFYWnBkSGs3WEc0Z0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lIUm9hWE11ZG1Gc2RXVWdQU0IwYUdsekxtTnZiblpsY25SUWIzTnBkR2x2YmxSdlZtRnNkV1VvYlc5MWMyVXBPMXh1SUNBZ0lIMWNiaUFnSUNCMGFHbHpMblpoYkhWbElEMGdiV0YwYUM1amJHbHdLSFJvYVhNdWRtRnNkV1VzTUN3eEtUdGNiaUFnZlZ4dVhHNGdJR052Ym5abGNuUlFiM05wZEdsdmJsUnZWbUZzZFdVb1kzVnljbVZ1ZENrZ2UxeHVJQ0FnSUhOM2FYUmphQ2gwYUdsekxtUnBjbVZqZEdsdmJpa2dlMXh1SUNBZ0lDQWdZMkZ6WlNBbmNtRmthV0ZzSnpwY2JpQWdJQ0FnSUNBZ2JHVjBJSEJ2YzJsMGFXOXVJRDBnYldGMGFDNTBiMUJ2YkdGeUtHTjFjbkpsYm5RdWVDQXRJSFJvYVhNdVltOTFibVJoY25rdVkyVnVkR1Z5TG5nc0lHTjFjbkpsYm5RdWVTQXRJSFJvYVhNdVltOTFibVJoY25rdVkyVnVkR1Z5TG5rcE8xeHVJQ0FnSUNBZ0lDQndiM05wZEdsdmJpQTlJSEJ2YzJsMGFXOXVMbUZ1WjJ4bElDOGdLRTFoZEdndVVFa3FNaWs3WEc0Z0lDQWdJQ0FnSUhCdmMybDBhVzl1SUQwZ0tDaHdiM05wZEdsdmJpQXRJREF1TWpVcElDc2dNU2tnSlNBeE8xeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2NHOXphWFJwYjI0N1hHNGdJQ0FnSUNCallYTmxJQ2QyWlhKMGFXTmhiQ2M2WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJ0WVhSb0xuTmpZV3hsS0dOMWNuSmxiblF1ZVN4MGFHbHpMbUp2ZFc1a1lYSjVMbTFwYmk1NUxIUm9hWE11WW05MWJtUmhjbmt1YldGNExua3NNQ3d4S1R0Y2JpQWdJQ0FnSUdOaGMyVWdKMmh2Y21sNmIyNTBZV3duT2x4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnYldGMGFDNXpZMkZzWlNoamRYSnlaVzUwTG5nc2RHaHBjeTVpYjNWdVpHRnllUzV0YVc0dWVDeDBhR2x6TG1KdmRXNWtZWEo1TG0xaGVDNTRMREFzTVNrN1hHNGdJQ0FnZlZ4dUlDQjlYRzVjYm4xY2JseHVYRzVsZUhCdmNuUWdZMnhoYzNNZ1FuVjBkRzl1SUh0Y2JseHVJQ0JqYjI1emRISjFZM1J2Y2lodGIyUmxQU2RpZFhSMGIyNG5LU0I3WEc0Z0lDQWdkR2hwY3k1dGIyUmxJRDBnYlc5a1pUdGNiaUFnSUNCMGFHbHpMbk4wWVhSbElEMGdibVYzSUZSdloyZHNaVTF2WkdWc0tDazdYRzRnSUNBZ2RHaHBjeTV3WVdsdWRHSnlkWE5vSUQwZ1ptRnNjMlU3WEc0Z0lIMWNibHh1SUNCamJHbGpheWdwSUh0Y2JpQWdJQ0J6ZDJsMFkyZ2dLSFJvYVhNdWJXOWtaU2tnZTF4dUlDQWdJQ0FnWTJGelpTQW5hVzF3ZFd4elpTYzZYRzRnSUNBZ0lDQWdJSFJvYVhNdWMzUmhkR1V1YjI0b0tUdGNiaUFnSUNBZ0lDQWdhV1lnS0hSb2FYTXVkR2x0Wlc5MWRDa2dlMXh1SUNBZ0lDQWdJQ0FnSUdOc1pXRnlWR2x0Wlc5MWRDaDBhR2x6TG5ScGJXVnZkWFFwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lIUm9hWE11ZEdsdFpXOTFkQ0E5SUhObGRGUnBiV1Z2ZFhRb2RHaHBjeTV6ZEdGMFpTNXZabVl1WW1sdVpDaDBhR2x6S1N3ek1DazdYRzRnSUNBZ0lDQWdJSFJvYVhNdVpXMXBkQ2duWTJoaGJtZGxKeXgwYUdsekxuTjBZWFJsS1R0Y2JpQWdJQ0FnSUNBZ1luSmxZV3M3WEc0Z0lDQWdJQ0JqWVhObElDZGlkWFIwYjI0bk9seHVJQ0FnSUNBZ0lDQjBhR2x6TG5SMWNtNVBiaWdwTzF4dUlDQWdJQ0FnSUNCMGFHbHpMbVZ0YVhRb0oyTm9ZVzVuWlNjc2RHaHBjeTV6ZEdGMFpTazdYRzRnSUNBZ0lDQWdJR0p5WldGck8xeHVJQ0FnSUNBZ1kyRnpaU0FuWVdaMFpYSjBiM1ZqYUNjNlhHNGdJQ0FnSUNBZ0lIUm9hWE11Y0c5emFYUnBiMjRnUFNCN1hHNGdJQ0FnSUNBZ0lDQWdlRG9nYldGMGFDNWpiR2x3S0hSb2FYTXViVzkxYzJVdWVDQXZJSFJvYVhNdWQybGtkR2dzTUN3eEtTeGNiaUFnSUNBZ0lDQWdJQ0I1T2lCdFlYUm9MbU5zYVhBb01TQXRJSFJvYVhNdWJXOTFjMlV1ZVNBdklIUm9hWE11YUdWcFoyaDBMREFzTVNsY2JpQWdJQ0FnSUNBZ2ZUdGNiaUFnSUNBZ0lDQWdkR2hwY3k1MGRYSnVUMjRvS1R0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTVsYldsMEtDZGphR0Z1WjJVbkxIdGNiaUFnSUNBZ0lDQWdJQ0J6ZEdGMFpUb2dkR2hwY3k1emRHRjBaU3hjYmlBZ0lDQWdJQ0FnSUNCNE9pQjBhR2x6TG5CdmMybDBhVzl1TG5nc1hHNGdJQ0FnSUNBZ0lDQWdlVG9nZEdocGN5NXdiM05wZEdsdmJpNTVMRnh1SUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0FnSUNBZ1luSmxZV3M3WEc0Z0lDQWdJQ0JqWVhObElDZDBiMmRuYkdVbk9seHVJQ0FnSUNBZ0lDQjBhR2x6TG1ac2FYQW9LVHRjYmlBZ0lDQWdJQ0FnZEdocGN5NWxiV2wwS0NkamFHRnVaMlVuTEhSb2FYTXVjM1JoZEdVcE8xeHVJQ0FnSUNBZ0lDQmljbVZoYXp0Y2JpQWdJQ0I5WEc1Y2JpQWdmVnh1WEc0Z0lHMXZkbVVvS1NCN1hHNGdJQ0FnYVdZZ0tIUm9hWE11Ylc5a1pUMDlQU2RoWm5SbGNuUnZkV05vSnlrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTV3YjNOcGRHbHZiaUE5SUh0Y2JpQWdJQ0FnSUNBZ2VEb2diV0YwYUM1amJHbHdLSFJvYVhNdWJXOTFjMlV1ZUNBdklIUm9hWE11ZDJsa2RHZ3NNQ3d4S1N4Y2JpQWdJQ0FnSUNBZ2VUb2diV0YwYUM1amJHbHdLREVnTFNCMGFHbHpMbTF2ZFhObExua2dMeUIwYUdsekxtaGxhV2RvZEN3d0xERXBYRzRnSUNBZ0lDQjlPMXh1SUNBZ0lDQWdkR2hwY3k1bGJXbDBLQ2RqYUdGdVoyVW5MSHRjYmlBZ0lDQWdJQ0FnYzNSaGRHVTZJSFJvYVhNdWMzUmhkR1VzWEc0Z0lDQWdJQ0FnSUhnNklIUm9hWE11Y0c5emFYUnBiMjR1ZUN4Y2JpQWdJQ0FnSUNBZ2VUb2dkR2hwY3k1d2IzTnBkR2x2Ymk1NUxGeHVJQ0FnSUNBZ2ZTazdYRzRnSUNBZ0lDQjBhR2x6TG5KbGJtUmxjaWdwTzF4dUlDQWdJSDFjYmlBZ2ZWeHVYRzRnSUhKbGJHVmhjMlVvS1NCN1hHNGdJQ0FnYzNkcGRHTm9JQ2gwYUdsekxtMXZaR1VwSUh0Y2JpQWdJQ0FnSUdOaGMyVWdKMkoxZEhSdmJpYzZYRzRnSUNBZ0lDQWdJSFJvYVhNdWRIVnliazltWmlncE8xeHVJQ0FnSUNBZ0lDQjBhR2x6TG1WdGFYUW9KMk5vWVc1blpTY3NkR2hwY3k1emRHRjBaU2s3WEc0Z0lDQWdJQ0FnSUdKeVpXRnJPMXh1SUNBZ0lDQWdZMkZ6WlNBbllXWjBaWEowYjNWamFDYzZYRzRnSUNBZ0lDQWdJSFJvYVhNdWRIVnliazltWmlncE8xeHVJQ0FnSUNBZ0lDQjBhR2x6TG5CdmMybDBhVzl1SUQwZ2UxeHVJQ0FnSUNBZ0lDQWdJSGc2SUhSb2FYTXViVzkxYzJVdWVDQXZJSFJvYVhNdWQybGtkR2dzWEc0Z0lDQWdJQ0FnSUNBZ2VUb2dNU0F0SUhSb2FYTXViVzkxYzJVdWVTQXZJSFJvYVhNdWFHVnBaMmgwWEc0Z0lDQWdJQ0FnSUgwN1hHNGdJQ0FnSUNBZ0lIUm9hWE11WlcxcGRDZ25ZMmhoYm1kbEp5eDdYRzRnSUNBZ0lDQWdJQ0FnYzNSaGRHVTZJSFJvYVhNdWMzUmhkR1VzWEc0Z0lDQWdJQ0FnSUNBZ2VEb2dkR2hwY3k1d2IzTnBkR2x2Ymk1NExGeHVJQ0FnSUNBZ0lDQWdJSGs2SUhSb2FYTXVjRzl6YVhScGIyNHVlU3hjYmlBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lHSnlaV0ZyTzF4dUlDQWdJSDFjYmlBZ2ZWeHVmVnh1WEc1Y2JseHVMeThnVjBWQ1VFRkRTeUJHVDA5VVJWSWdMeTljYmk4dklDNHZmaTlxYzJocGJuUXRiRzloWkdWeUlTNHZiR2xpTDNWMGFXd3ZhVzUwWlhKaFkzUnBiMjR1YW5NaUxDSW5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JtVjRjRzl5ZENCa1pXWmhkV3gwSUdOc1lYTnpJRlJ2WjJkc1pTQjdYRzVjYmlBZ1kyOXVjM1J5ZFdOMGIzSW9jM1JoZEdVcElIdGNiaUFnSUNCMGFHbHpMbk4wWVhSbElEMGdjM1JoZEdVZ2ZId2dabUZzYzJVN1hHNGdJSDFjYmx4dUlDQm1iR2x3S0hOMFlYUmxLU0I3WEc0Z0lDQWdhV1lnS0hOMFlYUmxJSHg4SUhOMFlYUmxJRDA5UFNCbVlXeHpaU2tnZTF4dUlDQWdJQ0FnZEdocGN5NXpkR0YwWlNBOUlITjBZWFJsTzF4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQjBhR2x6TG5OMFlYUmxJRDBnSVhSb2FYTXVjM1JoZEdVN1hHNGdJQ0FnZlZ4dUlDQjlYRzVjYmlBZ2IyNG9LU0I3WEc0Z0lDQWdkR2hwY3k1emRHRjBaU0E5SUhSeWRXVTdYRzRnSUgxY2JseHVJQ0J2Wm1Zb0tTQjdYRzRnSUNBZ2RHaHBjeTV6ZEdGMFpTQTlJR1poYkhObE8xeHVJQ0I5WEc1Y2JuMWNibHh1WEc1Y2JpOHZJRmRGUWxCQlEwc2dSazlQVkVWU0lDOHZYRzR2THlBdUwzNHZhbk5vYVc1MExXeHZZV1JsY2lFdUwyeHBZaTl0YjJSbGJITXZkRzluWjJ4bExtcHpJaXdpSjNWelpTQnpkSEpwWTNRbk8xeHVYRzVzWlhRZ2MzWm5JRDBnY21WeGRXbHlaU2duTGk0dmRYUnBiQzl6ZG1jbktUdGNibXhsZENCSmJuUmxjbVpoWTJVZ1BTQnlaWEYxYVhKbEtDY3VMaTlqYjNKbEwybHVkR1Z5Wm1GalpTY3BPMXh1YkdWMElGTjBaWEFnUFNCeVpYRjFhWEpsS0NjdUxpOXRiMlJsYkhNdmMzUmxjQ2NwTzF4dWFXMXdiM0owSUNvZ1lYTWdTVzUwWlhKaFkzUnBiMjRnWm5KdmJTQW5MaTR2ZFhScGJDOXBiblJsY21GamRHbHZiaWM3WEc1Y2JpOHFLbHh1S2lCVGJHbGtaWEpjYmlwY2Jpb2dRR1JsYzJOeWFYQjBhVzl1SUVodmNtbDZiMjUwWVd3Z2IzSWdkbVZ5ZEdsallXd2djMnhwWkdWeUlIZHBkR2dnYzJWMGRHRmliR1VnYVc1MFpYSmhZM1JwYjI0Z2JXOWtaWE11WEc0cVhHNHFJRUJrWlcxdklEeHpjR0Z1SUc1bGVIVnpMWFZwUFZ3aWMyeHBaR1Z5WENJZ2MzUmxjRDB3TGpJK1BDOXpjR0Z1UGx4dUtseHVLaUJBWlhoaGJYQnNaVnh1S2lCMllYSWdjMnhwWkdWeUlEMGdibVYzSUU1bGVIVnpMbE5zYVdSbGNpZ25JM1JoY21kbGRDY3BYRzRxWEc0cUlFQmxlR0Z0Y0d4bFhHNHFJSFpoY2lCemJHbGtaWElnUFNCdVpYY2dUbVY0ZFhNdVUyeHBaR1Z5S0NjamRHRnlaMlYwSnl4N1hHNHFJQ0FnSUNBbmMybDZaU2M2SUZzeE1qQXNNakJkTEZ4dUtpQWdJQ0FnSjIxdlpHVW5PaUFuY21Wc1lYUnBkbVVuTENBZ0x5OGdKM0psYkdGMGFYWmxKeUJ2Y2lBbllXSnpiMngxZEdVblhHNHFJQ0FnSUNBbmJXbHVKem9nTUN4Y2Jpb2dJQ0FnSUNkdFlYZ25PaUF4TEZ4dUtpQWdJQ0FnSjNOMFpYQW5PaUF3TEZ4dUtpQWdJQ0FnSjNaaGJIVmxKem9nTUZ4dUtpQjlLVnh1S2x4dUtpQkFiM1YwY0hWMFhHNHFJR05vWVc1blpWeHVLaUJHYVhKbGN5QjNhR1Z1SUhSb1pTQnBiblJsY21aaFkyVW5jeUIyWVd4MVpTQmphR0Z1WjJWekxpQThZbkkrWEc0cUlFVjJaVzUwSUdSaGRHRTZJRHhwUG01MWJXSmxjand2YVQ0Z1ZHaGxJRzUxYldKbGNpQjJZV3gxWlNCdlppQjBhR1VnYVc1MFpYSm1ZV05sTGx4dUtseHVLaUJBYjNWMGNIVjBaWGhoYlhCc1pWeHVLaUJ6Ykdsa1pYSXViMjRvSjJOb1lXNW5aU2NzWm5WdVkzUnBiMjRvZGlrZ2UxeHVLaUFnSUdOdmJuTnZiR1V1Ykc5bktIWXBPMXh1S2lCOUtWeHVLbHh1S2x4dUtpOWNibHh1Wlhod2IzSjBJR1JsWm1GMWJIUWdZMnhoYzNNZ1UyeHBaR1Z5SUdWNGRHVnVaSE1nU1c1MFpYSm1ZV05sSUh0Y2JseHVJQ0JqYjI1emRISjFZM1J2Y2lncElIdGNibHh1SUNBZ0lHeGxkQ0J2Y0hScGIyNXpJRDBnV3lkdGFXNG5MQ2R0WVhnbkxDZDJZV3gxWlNkZE8xeHVYRzRnSUNBZ2JHVjBJR1JsWm1GMWJIUnpJRDBnZTF4dUlDQWdJQ0FnSjNOcGVtVW5PaUJiTVRJd0xESXdYU3hjYmlBZ0lDQWdJQ2R0YjJSbEp6b2dKM0psYkdGMGFYWmxKeXdnSUM4dklDZHlaV3hoZEdsMlpTY2diM0lnSjJGaWMyOXNkWFJsSjF4dUlDQWdJQ0FnSjIxcGJpYzZJREFzWEc0Z0lDQWdJQ0FuYldGNEp6b2dNU3hjYmlBZ0lDQWdJQ2R6ZEdWd0p6b2dNQ3hjYmlBZ0lDQWdJQ2QyWVd4MVpTYzZJREJjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdjM1Z3WlhJb1lYSm5kVzFsYm5SekxHOXdkR2x2Ym5Nc1pHVm1ZWFZzZEhNcE8xeHVYRzRnSUNBZ2RHaHBjeTV2Y21sbGJuUmhkR2x2YmlBOUlDZDJaWEowYVdOaGJDYzdJQzh2SUZSb2FYTWdkMmxzYkNCamFHRnVaMlVnWVhWMGIyMWhkR2xqWVd4c2VTQjBieUFuYUc5eWFYcHZiblJoYkNkcFppQjBhR1VnYVc1MFpYSm1ZV05sSUdseklIZHBaR1Z5SUhSb1lXNGdhWFFnYVhNZ2RHRnNiQzVjYmx4dUlDQWdJSFJvYVhNdVgzWmhiSFZsSUQwZ2JtVjNJRk4wWlhBb2RHaHBjeTV6WlhSMGFXNW5jeTV0YVc0c0lIUm9hWE11YzJWMGRHbHVaM011YldGNExDQjBhR2x6TG5ObGRIUnBibWR6TG5OMFpYQXNJSFJvYVhNdWMyVjBkR2x1WjNNdWRtRnNkV1VwTzF4dVhHNGdJQ0FnZEdocGN5NXdiM05wZEdsdmJpQTlJRzVsZHlCSmJuUmxjbUZqZEdsdmJpNUlZVzVrYkdVb2RHaHBjeTV6WlhSMGFXNW5jeTV0YjJSbExIUm9hWE11YjNKcFpXNTBZWFJwYjI0c1d6QXNkR2hwY3k1M2FXUjBhRjBzVzNSb2FYTXVhR1ZwWjJoMExEQmRLVHRjYmlBZ0lDQjBhR2x6TG5CdmMybDBhVzl1TG5aaGJIVmxJRDBnZEdocGN5NWZkbUZzZFdVdWJtOXliV0ZzYVhwbFpEdGNibHh1SUNBZ0lIUm9hWE11YVc1cGRDZ3BPMXh1WEc0Z0lDQWdkR2hwY3k1d2IzTnBkR2x2Ymk1a2FYSmxZM1JwYjI0Z1BTQjBhR2x6TG05eWFXVnVkR0YwYVc5dU8xeHVYRzRnSUNBZ2RHaHBjeTVsYldsMEtDZGphR0Z1WjJVbkxIUm9hWE11ZG1Gc2RXVXBPMXh1WEc0Z0lIMWNibHh1SUNCaWRXbHNaRWx1ZEdWeVptRmpaU2dwSUh0Y2JseHVJQ0FnSUhSb2FYTXVZbUZ5SUQwZ2MzWm5MbU55WldGMFpTZ25jbVZqZENjcE8xeHVJQ0FnSUhSb2FYTXVabWxzYkdKaGNpQTlJSE4yWnk1amNtVmhkR1VvSjNKbFkzUW5LVHRjYmlBZ0lDQjBhR2x6TG10dWIySWdQU0J6ZG1jdVkzSmxZWFJsS0NkamFYSmpiR1VuS1R0Y2JseHVJQ0FnSUhSb2FYTXVaV3hsYldWdWRDNWhjSEJsYm1SRGFHbHNaQ2gwYUdsekxtSmhjaWs3WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG1Gd2NHVnVaRU5vYVd4a0tIUm9hWE11Wm1sc2JHSmhjaWs3WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG1Gd2NHVnVaRU5vYVd4a0tIUm9hWE11YTI1dllpazdYRzVjYmlBZ2ZWeHVYRzRnSUhOcGVtVkpiblJsY21aaFkyVW9LU0I3WEc1Y2JpQWdJQ0JwWmlBb2RHaHBjeTUzYVdSMGFDQThJSFJvYVhNdWFHVnBaMmgwS1NCN1hHNGdJQ0FnSUNCMGFHbHpMbTl5YVdWdWRHRjBhVzl1SUQwZ0ozWmxjblJwWTJGc0p6dGNiaUFnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnZEdocGN5NXZjbWxsYm5SaGRHbHZiaUE5SUNkb2IzSnBlbTl1ZEdGc0p6dGNiaUFnSUNCOVhHNWNiaUFnSUNCcFppQW9kR2hwY3k1d2IzTnBkR2x2YmlrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTV3YjNOcGRHbHZiaTV5WlhOcGVtVW9XekFzZEdocGN5NTNhV1IwYUYwc1czUm9hWE11YUdWcFoyaDBMREJkS1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0JzWlhRZ2VDd2dlU3dnZHl3Z2FDd2dZbUZ5VDJabWMyVjBMQ0JqYjNKdVpYSlNZV1JwZFhNN1hHNGdJQ0FnZEdocGN5NXJibTlpUkdGMFlTQTlJSHRjYmlBZ0lDQWdJR3hsZG1Wc09pQXdMRnh1SUNBZ0lDQWdjam9nTUZ4dUlDQWdJSDA3WEc1Y2JpQWdJQ0JwWmlBb2RHaHBjeTV2Y21sbGJuUmhkR2x2YmlBOVBUMGdKM1psY25ScFkyRnNKeWtnZTF4dUlDQWdJQ0FnZEdocGN5NTBhR2xqYTI1bGMzTWdQU0IwYUdsekxuZHBaSFJvSUM4Z01qdGNiaUFnSUNCY2RIZ2dQU0IwYUdsekxuZHBaSFJvTHpJN1hHNGdJQ0FnWEhSNUlEMGdNRHRjYmlBZ0lDQmNkSGNnUFNCMGFHbHpMblJvYVdOcmJtVnpjenRjYmlBZ0lDQmNkR2dnUFNCMGFHbHpMbWhsYVdkb2REdGNiaUFnSUNBZ0lIUm9hWE11YTI1dllrUmhkR0V1Y2lBOUlIUm9hWE11ZEdocFkydHVaWE56SUNvZ01DNDRPMXh1SUNBZ0lGeDBkR2hwY3k1cmJtOWlSR0YwWVM1c1pYWmxiQ0E5SUdndGRHaHBjeTVyYm05aVJHRjBZUzV5TFhSb2FYTXVibTl5YldGc2FYcGxaQ29vYUMxMGFHbHpMbXR1YjJKRVlYUmhMbklxTWlrN1hHNGdJQ0FnSUNCaVlYSlBabVp6WlhRZ1BTQW5kSEpoYm5Oc1lYUmxLQ2NyZEdocGN5NTBhR2xqYTI1bGMzTXFLQzB4S1M4eUt5Y3NNQ2tuTzF4dUlDQWdJQ0FnWTI5eWJtVnlVbUZrYVhWeklEMGdkeTh5TzF4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQjBhR2x6TG5Sb2FXTnJibVZ6Y3lBOUlIUm9hWE11YUdWcFoyaDBJQzhnTWp0Y2JpQWdJQ0JjZEhnZ1BTQXdPMXh1SUNBZ0lGeDBlU0E5SUhSb2FYTXVhR1ZwWjJoMEx6STdYRzRnSUNBZ1hIUjNJRDBnZEdocGN5NTNhV1IwYUR0Y2JpQWdJQ0JjZEdnZ1BTQjBhR2x6TG5Sb2FXTnJibVZ6Y3p0Y2JpQWdJQ0FnSUhSb2FYTXVhMjV2WWtSaGRHRXVjaUE5SUhSb2FYTXVkR2hwWTJ0dVpYTnpJQ29nTUM0NE8xeHVJQ0FnSUZ4MGRHaHBjeTVyYm05aVJHRjBZUzVzWlhabGJDQTlJSFJvYVhNdWJtOXliV0ZzYVhwbFpDb29keTEwYUdsekxtdHViMkpFWVhSaExuSXFNaWtyZEdocGN5NXJibTlpUkdGMFlTNXlPMXh1SUNBZ0lDQWdZbUZ5VDJabWMyVjBJRDBnSjNSeVlXNXpiR0YwWlNnd0xDY3JkR2hwY3k1MGFHbGphMjVsYzNNcUtDMHhLUzh5S3ljcEp6dGNiaUFnSUNBZ0lHTnZjbTVsY2xKaFpHbDFjeUE5SUdndk1qdGNiaUFnSUNCOVhHNWNiaUFnSUNCMGFHbHpMbUpoY2k1elpYUkJkSFJ5YVdKMWRHVW9KM2duTEhncE8xeHVJQ0FnSUhSb2FYTXVZbUZ5TG5ObGRFRjBkSEpwWW5WMFpTZ25lU2NzZVNrN1hHNGdJQ0FnZEdocGN5NWlZWEl1YzJWMFFYUjBjbWxpZFhSbEtDZDBjbUZ1YzJadmNtMG5MR0poY2s5bVpuTmxkQ2s3WEc0Z0lDQWdkR2hwY3k1aVlYSXVjMlYwUVhSMGNtbGlkWFJsS0NkeWVDY3NZMjl5Ym1WeVVtRmthWFZ6S1RzZ0x5OGdZMjl5Ym1WeUlISmhaR2wxYzF4dUlDQWdJSFJvYVhNdVltRnlMbk5sZEVGMGRISnBZblYwWlNnbmNua25MR052Y201bGNsSmhaR2wxY3lrN1hHNGdJQ0FnZEdocGN5NWlZWEl1YzJWMFFYUjBjbWxpZFhSbEtDZDNhV1IwYUNjc2R5azdYRzRnSUNBZ2RHaHBjeTVpWVhJdWMyVjBRWFIwY21saWRYUmxLQ2RvWldsbmFIUW5MR2dwTzF4dVhHNGdJQ0FnYVdZZ0tIUm9hWE11YjNKcFpXNTBZWFJwYjI0Z1BUMDlJQ2QyWlhKMGFXTmhiQ2NwSUh0Y2JpQWdJQ0FnSUhSb2FYTXVabWxzYkdKaGNpNXpaWFJCZEhSeWFXSjFkR1VvSjNnbkxIZ3BPMXh1SUNBZ0lDQWdkR2hwY3k1bWFXeHNZbUZ5TG5ObGRFRjBkSEpwWW5WMFpTZ25lU2NzZEdocGN5NXJibTlpUkdGMFlTNXNaWFpsYkNrN1hHNGdJQ0FnSUNCMGFHbHpMbVpwYkd4aVlYSXVjMlYwUVhSMGNtbGlkWFJsS0NkM2FXUjBhQ2NzZHlrN1hHNGdJQ0FnSUNCMGFHbHpMbVpwYkd4aVlYSXVjMlYwUVhSMGNtbGlkWFJsS0Nkb1pXbG5hSFFuTEdndGRHaHBjeTVyYm05aVJHRjBZUzVzWlhabGJDazdYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUhSb2FYTXVabWxzYkdKaGNpNXpaWFJCZEhSeWFXSjFkR1VvSjNnbkxEQXBPMXh1SUNBZ0lDQWdkR2hwY3k1bWFXeHNZbUZ5TG5ObGRFRjBkSEpwWW5WMFpTZ25lU2NzZVNrN1hHNGdJQ0FnSUNCMGFHbHpMbVpwYkd4aVlYSXVjMlYwUVhSMGNtbGlkWFJsS0NkM2FXUjBhQ2NzZEdocGN5NXJibTlpUkdGMFlTNXNaWFpsYkNrN1hHNGdJQ0FnSUNCMGFHbHpMbVpwYkd4aVlYSXVjMlYwUVhSMGNtbGlkWFJsS0Nkb1pXbG5hSFFuTEdncE8xeHVJQ0FnSUgxY2JpQWdJQ0IwYUdsekxtWnBiR3hpWVhJdWMyVjBRWFIwY21saWRYUmxLQ2QwY21GdWMyWnZjbTBuTEdKaGNrOW1abk5sZENrN1hHNGdJQ0FnZEdocGN5NW1hV3hzWW1GeUxuTmxkRUYwZEhKcFluVjBaU2duY25nbkxHTnZjbTVsY2xKaFpHbDFjeWs3WEc0Z0lDQWdkR2hwY3k1bWFXeHNZbUZ5TG5ObGRFRjBkSEpwWW5WMFpTZ25jbmtuTEdOdmNtNWxjbEpoWkdsMWN5azdYRzVjYmlBZ0lDQnBaaUFvZEdocGN5NXZjbWxsYm5SaGRHbHZiaUE5UFQwZ0ozWmxjblJwWTJGc0p5a2dlMXh1SUNBZ0lDQWdkR2hwY3k1cmJtOWlMbk5sZEVGMGRISnBZblYwWlNnblkzZ25MSGdwTzF4dUlDQWdJQ0FnZEdocGN5NXJibTlpTG5ObGRFRjBkSEpwWW5WMFpTZ25ZM2tuTEhSb2FYTXVhMjV2WWtSaGRHRXViR1YyWld3cE8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0IwYUdsekxtdHViMkl1YzJWMFFYUjBjbWxpZFhSbEtDZGplQ2NzZEdocGN5NXJibTlpUkdGMFlTNXNaWFpsYkNrN1hHNGdJQ0FnSUNCMGFHbHpMbXR1YjJJdWMyVjBRWFIwY21saWRYUmxLQ2RqZVNjc2VTazdYRzRnSUNBZ2ZWeHVJQ0FnSUhSb2FYTXVhMjV2WWk1elpYUkJkSFJ5YVdKMWRHVW9KM0luTEhSb2FYTXVhMjV2WWtSaGRHRXVjaWs3WEc1Y2JpQWdmVnh1WEc0Z0lHTnZiRzl5U1c1MFpYSm1ZV05sS0NrZ2UxeHVJQ0FnSUhSb2FYTXVZbUZ5TG5ObGRFRjBkSEpwWW5WMFpTZ25abWxzYkNjc0lIUm9hWE11WTI5c2IzSnpMbVpwYkd3cE8xeHVJQ0FnSUhSb2FYTXVabWxzYkdKaGNpNXpaWFJCZEhSeWFXSjFkR1VvSjJacGJHd25MQ0IwYUdsekxtTnZiRzl5Y3k1aFkyTmxiblFwTzF4dUlDQWdJSFJvYVhNdWEyNXZZaTV6WlhSQmRIUnlhV0oxZEdVb0oyWnBiR3duTENCMGFHbHpMbU52Ykc5eWN5NWhZMk5sYm5RcE8xeHVJQ0I5WEc1Y2JseHVJQ0J5Wlc1a1pYSW9LU0I3WEc0Z0lDQWdhV1lnS0NGMGFHbHpMbU5zYVdOclpXUXBJSHRjYmlBZ0lDQWdJSFJvYVhNdWEyNXZZa1JoZEdFdWNpQTlJSFJvYVhNdWRHaHBZMnR1WlhOektqQXVOelU3WEc0Z0lDQWdmVnh1SUNBZ0lIUm9hWE11YTI1dllpNXpaWFJCZEhSeWFXSjFkR1VvSjNJbkxIUm9hWE11YTI1dllrUmhkR0V1Y2lrN1hHNWNiaUFnSUNCcFppQW9kR2hwY3k1dmNtbGxiblJoZEdsdmJpQTlQVDBnSjNabGNuUnBZMkZzSnlrZ2UxeHVJQ0JjZENBZ0lIUm9hWE11YTI1dllrUmhkR0V1YkdWMlpXd2dQU0IwYUdsekxtdHViMkpFWVhSaExuSXJkR2hwY3k1ZmRtRnNkV1V1Ym05eWJXRnNhWHBsWkNvb2RHaHBjeTVvWldsbmFIUXRkR2hwY3k1cmJtOWlSR0YwWVM1eUtqSXBPMXh1SUNBZ0lDQWdJSFJvYVhNdWEyNXZZaTV6WlhSQmRIUnlhV0oxZEdVb0oyTjVKeXgwYUdsekxtaGxhV2RvZENBdElIUm9hWE11YTI1dllrUmhkR0V1YkdWMlpXd3BPMXh1SUNBZ0lDQWdJSFJvYVhNdVptbHNiR0poY2k1elpYUkJkSFJ5YVdKMWRHVW9KM2tuTEhSb2FYTXVhR1ZwWjJoMElDMGdkR2hwY3k1cmJtOWlSR0YwWVM1c1pYWmxiQ2s3WEc0Z0lDQWdJQ0FnZEdocGN5NW1hV3hzWW1GeUxuTmxkRUYwZEhKcFluVjBaU2duYUdWcFoyaDBKeXgwYUdsekxtdHViMkpFWVhSaExteGxkbVZzS1R0Y2JpQWdJQ0I5SUdWc2MyVWdlMXh1SUNCY2RDQWdJSFJvYVhNdWEyNXZZa1JoZEdFdWJHVjJaV3dnUFNCMGFHbHpMbDkyWVd4MVpTNXViM0p0WVd4cGVtVmtLaWgwYUdsekxuZHBaSFJvTFhSb2FYTXVhMjV2WWtSaGRHRXVjaW95S1N0MGFHbHpMbXR1YjJKRVlYUmhMbkk3WEc0Z0lDQWdJQ0FnZEdocGN5NXJibTlpTG5ObGRFRjBkSEpwWW5WMFpTZ25ZM2duTEhSb2FYTXVhMjV2WWtSaGRHRXViR1YyWld3cE8xeHVJQ0FnSUNBZ0lIUm9hWE11Wm1sc2JHSmhjaTV6WlhSQmRIUnlhV0oxZEdVb0ozZ25MREFwTzF4dUlDQWdJQ0FnSUhSb2FYTXVabWxzYkdKaGNpNXpaWFJCZEhSeWFXSjFkR1VvSjNkcFpIUm9KeXgwYUdsekxtdHViMkpFWVhSaExteGxkbVZzS1R0Y2JpQWdJQ0I5WEc0Z0lIMWNibHh1WEc0Z0lHTnNhV05yS0NrZ2UxeHVJQ0FnSUhSb2FYTXVhMjV2WWtSaGRHRXVjaUE5SUhSb2FYTXVkR2hwWTJ0dVpYTnpLakF1T1R0Y2JpQWdJQ0IwYUdsekxuQnZjMmwwYVc5dUxtRnVZMmh2Y2lBOUlIUm9hWE11Ylc5MWMyVTdYRzRnSUNBZ2RHaHBjeTV0YjNabEtDazdYRzRnSUgxY2JseHVJQ0J0YjNabEtDa2dlMXh1SUNBZ0lHbG1JQ2gwYUdsekxtTnNhV05yWldRcElIdGNiaUFnSUNBZ0lIUm9hWE11Y0c5emFYUnBiMjR1ZFhCa1lYUmxLSFJvYVhNdWJXOTFjMlVwTzF4dUlDQWdJQ0FnZEdocGN5NWZkbUZzZFdVdWRYQmtZWFJsVG05eWJXRnNLQ0IwYUdsekxuQnZjMmwwYVc5dUxuWmhiSFZsSUNrN1hHNGdJQ0FnSUNCMGFHbHpMbVZ0YVhRb0oyTm9ZVzVuWlNjc2RHaHBjeTVmZG1Gc2RXVXVkbUZzZFdVcE8xeHVJQ0FnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmx4dUlDQWdJSDFjYmlBZ2ZWeHVYRzRnSUhKbGJHVmhjMlVvS1NCN1hHNGdJQ0FnZEdocGN5NXlaVzVrWlhJb0tUdGNiaUFnZlZ4dVhHNGdJR2RsZENCdWIzSnRZV3hwZW1Wa0tDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbDkyWVd4MVpTNXViM0p0WVd4cGVtVmtPMXh1SUNCOVhHNWNiaUFnTHlvcVhHNGdJRlJvWlNCemJHbGtaWEluY3lCamRYSnlaVzUwSUhaaGJIVmxMaUJKWmlCelpYUWdiV0Z1ZFdGc2JIa3NJSGRwYkd3Z2RYQmtZWFJsSUhSb1pTQnBiblJsY21aaFkyVWdZVzVrSUhSeWFXZG5aWElnZEdobElHOTFkSEIxZENCbGRtVnVkQzVjYmlBZ1FIUjVjR1VnZTI1MWJXSmxjbjFjYmlBZ1FHVjRZVzF3YkdVZ2MyeHBaR1Z5TG5aaGJIVmxJRDBnTVRBN1hHNGdJQ292WEc0Z0lHZGxkQ0IyWVd4MVpTZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVmZG1Gc2RXVXVkbUZzZFdVN1hHNGdJSDFjYmlBZ2MyVjBJSFpoYkhWbEtIWXBJSHRjYmlBZ0lDQjBhR2x6TGw5MllXeDFaUzUxY0dSaGRHVW9kaWs3WEc0Z0lDQWdkR2hwY3k1d2IzTnBkR2x2Ymk1MllXeDFaU0E5SUhSb2FYTXVYM1poYkhWbExtNXZjbTFoYkdsNlpXUTdYRzRnSUNBZ2RHaHBjeTVsYldsMEtDZGphR0Z1WjJVbkxIUm9hWE11WDNaaGJIVmxMblpoYkhWbEtUdGNiaUFnSUNCMGFHbHpMbkpsYm1SbGNpZ3BPMXh1SUNCOVhHNWNiaUFnTHlvcVhHNGdJRXh2ZDJWeUlHeHBiV2wwSUc5bUlIUm9aU0J6Ykdsa1pYSnpKM01nYjNWMGNIVjBJSEpoYm1kbFhHNGdJRUIwZVhCbElIdHVkVzFpWlhKOVhHNGdJRUJsZUdGdGNHeGxJSE5zYVdSbGNpNXRhVzRnUFNBeE1EQXdPMXh1SUNBcUwxeHVJQ0JuWlhRZ2JXbHVLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TGw5MllXeDFaUzV0YVc0N1hHNGdJSDFjYmlBZ2MyVjBJRzFwYmloMktTQjdYRzRnSUNBZ2RHaHBjeTVmZG1Gc2RXVXViV2x1SUQwZ2RqdGNiaUFnZlZ4dVhHNGdJQzhxS2x4dUlDQlZjSEJsY2lCc2FXMXBkQ0J2WmlCMGFHVWdjMnhwWkdWeUozTWdiM1YwY0hWMElISmhibWRsWEc0Z0lFQjBlWEJsSUh0dWRXMWlaWEo5WEc0Z0lFQmxlR0Z0Y0d4bElITnNhV1JsY2k1dFlYZ2dQU0F4TURBd08xeHVJQ0FxTDF4dUlDQm5aWFFnYldGNEtDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbDkyWVd4MVpTNXRZWGc3WEc0Z0lIMWNiaUFnYzJWMElHMWhlQ2gyS1NCN1hHNGdJQ0FnZEdocGN5NWZkbUZzZFdVdWJXRjRJRDBnZGp0Y2JpQWdmVnh1WEc0Z0lDOHFLbHh1SUNCVWFHVWdhVzVqY21WdFpXNTBJSFJvWVhRZ2RHaGxJSE5zYVdSbGNpZHpJSFpoYkhWbElHTm9ZVzVuWlhNZ1lua3VYRzRnSUVCMGVYQmxJSHR1ZFcxaVpYSjlYRzRnSUVCbGVHRnRjR3hsSUhOc2FXUmxjaTV6ZEdWd0lEMGdOVHRjYmlBZ0tpOWNiaUFnWjJWMElITjBaWEFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdVgzWmhiSFZsTG5OMFpYQTdYRzRnSUgxY2JpQWdjMlYwSUhOMFpYQW9kaWtnZTF4dUlDQWdJSFJvYVhNdVgzWmhiSFZsTG5OMFpYQWdQU0IyTzF4dUlDQjlYRzVjYmlBZ0x5b3FYRzRnSUVGaWMyOXNkWFJsSUcxdlpHVWdLSE5zYVdSbGNpZHpJSFpoYkhWbElHcDFiWEJ6SUhSdklHMXZkWE5sSUdOc2FXTnJJSEJ2YzJsMGFXOXVLU0J2Y2lCeVpXeGhkR2wyWlNCdGIyUmxJQ2h0YjNWelpTQmtjbUZuSUdOb1lXNW5aWE1nZG1Gc2RXVWdjbVZzWVhScGRtVWdkRzhnYVhSeklHTjFjbkpsYm5RZ2NHOXphWFJwYjI0cExpQkVaV1poZFd4ME9pQmNJbkpsYkdGMGFYWmxYQ0l1WEc0Z0lFQjBlWEJsSUh0emRISnBibWQ5WEc0Z0lFQmxlR0Z0Y0d4bElITnNhV1JsY2k1dGIyUmxJRDBnWENKeVpXeGhkR2wyWlZ3aU8xeHVJQ0FxTDF4dUlDQm5aWFFnYlc5a1pTZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTV3YjNOcGRHbHZiaTV0YjJSbE8xeHVJQ0I5WEc0Z0lITmxkQ0J0YjJSbEtIWXBJSHRjYmlBZ0lDQjBhR2x6TG5CdmMybDBhVzl1TG0xdlpHVWdQU0IyTzF4dUlDQjlYRzVjYmx4dVhHNTlYRzVjYmx4dVhHNHZMeUJYUlVKUVFVTkxJRVpQVDFSRlVpQXZMMXh1THk4Z0xpOStMMnB6YUdsdWRDMXNiMkZrWlhJaExpOXNhV0l2YVc1MFpYSm1ZV05sY3k5emJHbGtaWEl1YW5NaUxDSW5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JteGxkQ0J6ZG1jZ1BTQnlaWEYxYVhKbEtDY3VMaTkxZEdsc0wzTjJaeWNwTzF4dWJHVjBJRlJ2WjJkc1pVMXZaR1ZzSUQwZ2NtVnhkV2x5WlNnbkxpNHZiVzlrWld4ekwzUnZaMmRzWlNjcE8xeHViR1YwSUVsdWRHVnlabUZqWlNBOUlISmxjWFZwY21Vb0p5NHVMMk52Y21VdmFXNTBaWEptWVdObEp5azdYRzVjYmk4cUtseHVLaUJVYjJkbmJHVmNiaXBjYmlvZ1FHUmxjMk55YVhCMGFXOXVJRUpwYm1GeWVTQnpkMmwwWTJoY2JpcGNiaW9nUUdSbGJXOGdQSE53WVc0Z2JtVjRkWE10ZFdrOVhDSjBiMmRuYkdWY0lqNDhMM053WVc0K1hHNHFYRzRxSUVCbGVHRnRjR3hsWEc0cUlIWmhjaUIwYjJkbmJHVWdQU0J1WlhjZ1RtVjRkWE11Vkc5bloyeGxLQ2NqZEdGeVoyVjBKeWxjYmlwY2Jpb2dRR1Y0WVcxd2JHVmNiaW9nZG1GeUlIUnZaMmRzWlNBOUlHNWxkeUJPWlhoMWN5NVViMmRuYkdVb0p5TjBZWEpuWlhRbkxIdGNiaW9nSUNBZ0lDZHphWHBsSnpvZ1d6UXdMREl3WFN4Y2Jpb2dJQ0FnSUNkemRHRjBaU2M2SUdaaGJITmxYRzRxSUgwcFhHNHFYRzRxSUVCdmRYUndkWFJjYmlvZ1kyaGhibWRsWEc0cUlFWnBjbVZ6SUdGdWVTQjBhVzFsSUhSb1pTQnBiblJsY21aaFkyVW5jeUIyWVd4MVpTQmphR0Z1WjJWekxpQThZbkkrWEc0cUlGQmhjbUZ0WlhSbGNqb2dWR2hsSUdKdmIyeGxZVzRnYzNSaGRHVWdiMllnZEdobElHbHVkR1Z5Wm1GalpTNWNiaXBjYmlvZ1FHOTFkSEIxZEdWNFlXMXdiR1ZjYmlvZ2RHOW5aMnhsTG05dUtDZGphR0Z1WjJVbkxHWjFibU4wYVc5dUtIWXBJSHRjYmlvZ0lDQmpiMjV6YjJ4bExteHZaeWgyS1R0Y2Jpb2dmU2xjYmlwY2JpcGNiaW92WEc1bGVIQnZjblFnWkdWbVlYVnNkQ0JqYkdGemN5QlViMmRuYkdVZ1pYaDBaVzVrY3lCSmJuUmxjbVpoWTJVZ2UxeHVYRzRnSUdOdmJuTjBjblZqZEc5eUtDa2dlMXh1WEc0Z0lDQWdiR1YwSUc5d2RHbHZibk1nUFNCYkozWmhiSFZsSjEwN1hHNWNiaUFnSUNCc1pYUWdaR1ZtWVhWc2RITWdQU0I3WEc0Z0lDQWdJQ0FuYzJsNlpTYzZJRnMwTUN3eU1GMHNYRzRnSUNBZ0lDQW5kR0Z5WjJWMEp6b2dabUZzYzJVc1hHNGdJQ0FnSUNBbmMzUmhkR1VuT2lCbVlXeHpaVnh1SUNBZ0lIMDdYRzVjYmlBZ0lDQnpkWEJsY2loaGNtZDFiV1Z1ZEhNc2IzQjBhVzl1Y3l4a1pXWmhkV3gwY3lrN1hHNWNiaUFnSUNCMGFHbHpMbDl6ZEdGMFpTQTlJRzVsZHlCVWIyZG5iR1ZOYjJSbGJDaDBhR2x6TG5ObGRIUnBibWR6TG5OMFlYUmxLVHRjYmx4dUlDQWdJSFJvYVhNdWFXNXBkQ2dwTzF4dVhHNGdJSDFjYmx4dUlDQmlkV2xzWkVsdWRHVnlabUZqWlNncElIdGNibHh1SUNBZ0lIUm9hWE11WW1GeUlEMGdjM1puTG1OeVpXRjBaU2duY21WamRDY3BPMXh1SUNBZ0lIUm9hWE11YTI1dllpQTlJSE4yWnk1amNtVmhkR1VvSjJOcGNtTnNaU2NwTzF4dUlDQWdJSFJvYVhNdVpXeGxiV1Z1ZEM1aGNIQmxibVJEYUdsc1pDaDBhR2x6TG1KaGNpazdYRzRnSUNBZ2RHaHBjeTVsYkdWdFpXNTBMbUZ3Y0dWdVpFTm9hV3hrS0hSb2FYTXVhMjV2WWlrN1hHNWNiaUFnZlZ4dVhHNGdJSE5wZW1WSmJuUmxjbVpoWTJVb0tTQjdYRzVjYmlBZ0lDQnBaaUFvZEdocGN5NW9aV2xuYUhRZ1BDQjBhR2x6TG5kcFpIUm9MeklwSUh0Y2JpQWdJQ0FnSUhSb2FYTXVhMjV2WWxOcGVtVWdQU0IwYUdsekxtaGxhV2RvZEM4eU8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0IwYUdsekxtdHViMkpUYVhwbElEMGdkR2hwY3k1M2FXUjBhQzgwTzF4dUlDQWdJSDFjYmx4dUlDQWdJSFJvYVhNdVltRnlMbk5sZEVGMGRISnBZblYwWlNnbmVDY3NkR2hwY3k1M2FXUjBhQzh5SUMwZ2RHaHBjeTVyYm05aVUybDZaU294TGpVcE8xeHVJQ0FnSUhSb2FYTXVZbUZ5TG5ObGRFRjBkSEpwWW5WMFpTZ25lU2NzZEdocGN5NW9aV2xuYUhRdk1pQXRJSFJvYVhNdWEyNXZZbE5wZW1Vdk1pazdYRzRnSUNBZ2RHaHBjeTVpWVhJdWMyVjBRWFIwY21saWRYUmxLQ2R5ZUNjc2RHaHBjeTVyYm05aVUybDZaUzh5S1R0Y2JpQWdJQ0IwYUdsekxtSmhjaTV6WlhSQmRIUnlhV0oxZEdVb0ozSjVKeXgwYUdsekxtdHViMkpUYVhwbEx6SXBPMXh1SUNBZ0lIUm9hWE11WW1GeUxuTmxkRUYwZEhKcFluVjBaU2duZDJsa2RHZ25MSFJvYVhNdWEyNXZZbE5wZW1VcU15azdYRzRnSUNBZ2RHaHBjeTVpWVhJdWMyVjBRWFIwY21saWRYUmxLQ2RvWldsbmFIUW5MSFJvYVhNdWEyNXZZbE5wZW1VcE8xeHVYRzRnSUNBZ2RHaHBjeTVyYm05aUxuTmxkRUYwZEhKcFluVjBaU2duWTNnbkxIUm9hWE11ZDJsa2RHZ3ZNaUF0SUhSb2FYTXVhMjV2WWxOcGVtVXBPMXh1SUNBZ0lIUm9hWE11YTI1dllpNXpaWFJCZEhSeWFXSjFkR1VvSjJONUp5eDBhR2x6TG1obGFXZG9kQzh5S1R0Y2JpQWdJQ0IwYUdsekxtdHViMkl1YzJWMFFYUjBjbWxpZFhSbEtDZHlKeXgwYUdsekxtdHViMkpUYVhwbEtUdGNibHh1SUNCOVhHNWNiaUFnWTI5c2IzSkpiblJsY21aaFkyVW9LU0I3WEc0Z0lDQWdkR2hwY3k1cmJtOWlMbk5sZEVGMGRISnBZblYwWlNnblptbHNiQ2NzSUhSb2FYTXVZMjlzYjNKekxtRmpZMlZ1ZENrN1hHNGdJQ0FnZEdocGN5NXlaVzVrWlhJb0tUdGNiaUFnZlZ4dVhHNGdJSEpsYm1SbGNpZ3BJSHRjYmlBZ0lDQnBaaUFvSVhSb2FYTXVjM1JoZEdVcElIdGNiaUFnSUNBZ0lIUm9hWE11YTI1dllpNXpaWFJCZEhSeWFXSjFkR1VvSjJONEp5eDBhR2x6TG5kcFpIUm9MeklnTFNCMGFHbHpMbXR1YjJKVGFYcGxLVHRjYmlBZ0lDQWdJSFJvYVhNdVltRnlMbk5sZEVGMGRISnBZblYwWlNnblptbHNiQ2NzSUhSb2FYTXVZMjlzYjNKekxtWnBiR3dwTzF4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQjBhR2x6TG10dWIySXVjMlYwUVhSMGNtbGlkWFJsS0NkamVDY3NkR2hwY3k1M2FXUjBhQzh5SUNzZ2RHaHBjeTVyYm05aVUybDZaU2s3WEc0Z0lDQWdJQ0IwYUdsekxtSmhjaTV6WlhSQmRIUnlhV0oxZEdVb0oyWnBiR3duTENCMGFHbHpMbU52Ykc5eWN5NWhZMk5sYm5RcE8xeHVJQ0FnSUgxY2JpQWdmVnh1WEc0Z0lHTnNhV05yS0NrZ2UxeHVJQ0FnSUhSb2FYTXVabXhwY0NncE8xeHVJQ0FnSUhSb2FYTXVjbVZ1WkdWeUtDazdYRzRnSUNBZ2RHaHBjeTVsYldsMEtDZGphR0Z1WjJVbkxIUm9hWE11YzNSaGRHVXBPMXh1SUNCOVhHNWNiaUFnTHlvcVhHNGdJRmRvWlhSb1pYSWdkR2hsSUhSdloyZHNaU0JwY3lCamRYSnlaVzUwYkhrZ2IyNGdiM0lnYjJabUxpQlRaWFIwYVc1bklIUm9hWE1nY0hKdmNHVnlkSGtnZDJsc2JDQjFjR1JoZEdVZ2RHaGxJSFJ2WjJkc1pTQnBiblJsY21aaFkyVWdZVzVrSUhSeWFXZG5aWElnZEdobElHOTFkSEIxZENCbGRtVnVkQzVjYmlBZ1FIUjVjR1VnZTJKdmIyeGxZVzU5WEc0Z0lFQmxlR0Z0Y0d4bElIUnZaMmRzWlM1emRHRjBaU0E5SUdaaGJITmxPMXh1SUNBcUwxeHVJQ0JuWlhRZ2MzUmhkR1VvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdVgzTjBZWFJsTG5OMFlYUmxPMXh1SUNCOVhHNGdJSE5sZENCemRHRjBaU2gyWVd4MVpTa2dlMXh1SUNBZ0lIUm9hWE11WDNOMFlYUmxMbVpzYVhBb2RtRnNkV1VwTzF4dUlDQWdJSFJvYVhNdVpXMXBkQ2duWTJoaGJtZGxKeXgwYUdsekxuTjBZWFJsS1R0Y2JpQWdJQ0IwYUdsekxuSmxibVJsY2lncE8xeHVJQ0I5WEc1Y2JseHVJQ0F2S2lwY2JpQWdLaUJUZDJsMFkyZ2dkR2hsSUhSdloyZHNaU0J6ZEdGMFpTQjBieUJwZEhNZ2IzQndiM05wZEdVZ2MzUmhkR1ZjYmlBZ0tpQkFaWGhoYlhCc1pWeHVJQ0FxSUhSdloyZHNaUzVtYkdsd0tDazdYRzRnSUNvdlhHNGdJR1pzYVhBb0tTQjdYRzRnSUNBZ2RHaHBjeTVmYzNSaGRHVXVabXhwY0NncE8xeHVJQ0FnSUhSb2FYTXVjbVZ1WkdWeUtDazdYRzRnSUgxY2JseHVmVnh1WEc1Y2JseHVMeThnVjBWQ1VFRkRTeUJHVDA5VVJWSWdMeTljYmk4dklDNHZmaTlxYzJocGJuUXRiRzloWkdWeUlTNHZiR2xpTDJsdWRHVnlabUZqWlhNdmRHOW5aMnhsTG1weklpd2lKM1Z6WlNCemRISnBZM1FuTzF4dVhHNXNaWFFnYzNabklEMGdjbVZ4ZFdseVpTZ25MaTR2ZFhScGJDOXpkbWNuS1R0Y2JteGxkQ0JDZFhSMGIyNVVaVzF3YkdGMFpTQTlJSEpsY1hWcGNtVW9KeTR1TDJOdmJYQnZibVZ1ZEhNdlluVjBkRzl1ZEdWdGNHeGhkR1VuS1R0Y2JseHVMeW9xWEc0cUlFSjFkSFJ2Ymx4dUtseHVLaUJBWkdWelkzSnBjSFJwYjI0Z1EybHlZM1ZzWVhJZ1luVjBkRzl1SUhkcGRHZ2diM0IwYVc5dVlXd2dZV1owWlhKMGIzVmphQzVjYmlwY2Jpb2dRR1JsYlc4Z1BITndZVzRnYm1WNGRYTXRkV2s5WENKaWRYUjBiMjVjSWo0OEwzTndZVzQrWEc0cVhHNHFJRUJsZUdGdGNHeGxYRzRxSUhaaGNpQmlkWFIwYjI0Z1BTQnVaWGNnVG1WNGRYTXVRblYwZEc5dUtDY2pkR0Z5WjJWMEp5bGNiaXBjYmlvZ1FHVjRZVzF3YkdWY2Jpb2dkbUZ5SUdKMWRIUnZiaUE5SUc1bGR5Qk9aWGgxY3k1Q2RYUjBiMjRvSnlOMFlYSm5aWFFuTEh0Y2Jpb2dJQ0FuYzJsNlpTYzZJRnM0TUN3NE1GMHNYRzRxSUNBZ0oyMXZaR1VuT2lBbllXWjBaWEowYjNWamFDY3NYRzRxSUNBZ0ozTjBZWFJsSnpvZ1ptRnNjMlZjYmlvZ2ZTbGNiaXBjYmlvZ1FHOTFkSEIxZEZ4dUtpQmphR0Z1WjJWY2Jpb2dSbWx5WlhNZ1lXNTVJSFJwYldVZ2RHaGxJR2x1ZEdWeVptRmpaU2R6SUhaaGJIVmxJR05vWVc1blpYTXVJRHhpY2o1Y2Jpb2dTVzRnUEdJK1luVjBkRzl1SUcxdlpHVThMMkkrTENBOFlqNTBiMmRuYkdVZ2JXOWtaVHd2WWo0c0lHRnVaQ0E4WWo1cGJYQjFiSE5sSUcxdlpHVThMMkkrTENCMGFHVWdiM1YwY0hWMElHUmhkR0VnYVhNZ1lTQmliMjlzWldGdUlHUmxjMk55YVdKcGJtY2dkR2hsSUhOMFlYUmxJRzltSUhSb1pTQmlkWFIwYjI0dVBHSnlQbHh1S2lCSmJpQThZajVoWm5SbGNuUnZkV05vSUcxdlpHVThMMkkrTENCMGFHVWdiM1YwY0hWMElHUmhkR0VnYVhNZ1lXNGdiMkpxWldOMElHTnZiblJoYVc1cGJtY2dlQ0FvTUMweEtTQmhibVFnZVNBb01DMHhLU0J3YjNOcGRHbHZibk1nYjJZZ1lXWjBaWEowYjNWamFDNWNiaXBjYmlvZ1FHOTFkSEIxZEdWNFlXMXdiR1ZjYmlvZ1luVjBkRzl1TG05dUtDZGphR0Z1WjJVbkxHWjFibU4wYVc5dUtIWXBJSHRjYmlvZ0lDQXZMeUIySUdseklIUm9aU0IyWVd4MVpTQnZaaUIwYUdVZ1luVjBkRzl1WEc0cUlDQWdZMjl1YzI5c1pTNXNiMmNvZGlrN1hHNHFJSDBwWEc0cVhHNHFMMXh1WEc1bGVIQnZjblFnWkdWbVlYVnNkQ0JqYkdGemN5QkNkWFIwYjI0Z1pYaDBaVzVrY3lCQ2RYUjBiMjVVWlcxd2JHRjBaU0I3WEc1Y2JpQWdZMjl1YzNSeWRXTjBiM0lvS1NCN1hHNWNiaUFnSUNCc1pYUWdiM0IwYVc5dWN5QTlJRnNuYlc5a1pTZGRPMXh1WEc1Y2JpQWdJQ0JzWlhRZ1pHVm1ZWFZzZEhNZ1BTQjdYRzRnSUNBZ0lDQW5jMmw2WlNjNklGczRNQ3c0TUYwc1hHNGdJQ0FnSUNBbmJXOWtaU2M2SUNkaFpuUmxjblJ2ZFdOb0p5d2dMeThnWW5WMGRHOXVMQ0JoWm5SbGNuUnZkV05vTENCcGJYQjFiSE5sTENCMGIyZG5iR1ZjYmlBZ0lDQWdJQ2R6ZEdGMFpTYzZJR1poYkhObFhHNGdJQ0FnZlR0Y2JseHVJQ0FnSUhOMWNHVnlLR0Z5WjNWdFpXNTBjeXh2Y0hScGIyNXpMR1JsWm1GMWJIUnpLVHRjYmx4dVhHNGdJQ0FnTHlvcVhHNGdJQ0FnS2lCSmJuUmxjbUZqZEdsdmJpQnRiMlJsT2lCemRYQndiM0owY3lCY0ltSjFkSFJ2Ymx3aUxDQmNJbUZtZEdWeWRHOTFZMmhjSWl3Z1hDSnBiWEIxYkhObFhDSXNJRzl5SUZ3aWRHOW5aMnhsWENKY2JpQWdJQ0FxSUVCMGVYQmxJSHR6ZEhKcGJtZDlYRzRnSUNBZ0tpQkFaWGhoYlhCc1pTQmlkWFIwYjI0dWJXOWtaU0E5SUNkMGIyZG5iR1VuTzF4dUlDQWdJQ292WEc0Z0lDQWdkR2hwY3k1dGIyUmxJRDBnZEdocGN5NXpaWFIwYVc1bmN5NXRiMlJsTzF4dVhHNGdJQ0FnZEdocGN5NXBibWwwS0NrN1hHNGdJQ0FnZEdocGN5NXlaVzVrWlhJb0tUdGNibHh1SUNCOVhHNWNiaUFnWW5WcGJHUkpiblJsY21aaFkyVW9LU0I3WEc0Z0lDQWdkR2hwY3k1d1lXUWdQU0J6ZG1jdVkzSmxZWFJsS0NkamFYSmpiR1VuS1R0Y2JpQWdJQ0IwYUdsekxtVnNaVzFsYm5RdVlYQndaVzVrUTJocGJHUW9kR2hwY3k1d1lXUXBPMXh1WEc0Z0lDQWdkR2hwY3k1cGJuUmxjbUZqZEdsdmJsUmhjbWRsZENBOUlIUm9hWE11Y0dGa08xeHVYRzRnSUNBZ0x5OGdiMjVzZVNCMWMyVmtJR2xtSUdsdUlDZGhablJsY25SdmRXTm9KeUJ0YjJSbFhHNGdJQ0FnZEdocGN5NWtaV1p6SUQwZ2MzWm5MbU55WldGMFpTZ25aR1ZtY3ljcE8xeHVJQ0FnSUhSb2FYTXVaV3hsYldWdWRDNWhjSEJsYm1SRGFHbHNaQ2gwYUdsekxtUmxabk1wTzF4dVhHNGdJQ0FnZEdocGN5NW5jbUZrYVdWdWRDQTlJSE4yWnk1eVlXUnBZV3hIY21Ga2FXVnVkQ2gwYUdsekxtUmxabk1zTWlrN1hHNWNiaUFnSUNCMGFHbHpMbWR5WVdScFpXNTBMbk4wYjNCeld6QmRMbk5sZEVGMGRISnBZblYwWlNnbmIyWm1jMlYwSnl3Z0p6TXdKU2NwTzF4dVhHNGdJQ0FnZEdocGN5NW5jbUZrYVdWdWRDNXpkRzl3YzFzeFhTNXpaWFJCZEhSeWFXSjFkR1VvSjI5bVpuTmxkQ2NzSUNjeE1EQWxKeWs3WEc1Y2JpQWdmVnh1WEc0Z0lITnBlbVZKYm5SbGNtWmhZMlVvS1NCN1hHNWNiaUFnSUNCMGFHbHpMbkJoWkM1elpYUkJkSFJ5YVdKMWRHVW9KMk40Snl4MGFHbHpMbmRwWkhSb0x6SXBPMXh1SUNBZ0lIUm9hWE11Y0dGa0xuTmxkRUYwZEhKcFluVjBaU2duWTNrbkxIUm9hWE11YUdWcFoyaDBMeklwTzF4dUlDQWdJSFJvYVhNdWNHRmtMbk5sZEVGMGRISnBZblYwWlNnbmNpY3NJRTFoZEdndWJXbHVLSFJvYVhNdWQybGtkR2dzZEdocGN5NW9aV2xuYUhRcElDOGdNaUF0SUhSb2FYTXVkMmxrZEdndk5EQXBPMXh1SUNBZ0lIUm9hWE11Y0dGa0xuTmxkRUYwZEhKcFluVjBaU2duYzNSeWIydGxMWGRwWkhSb0p5d2dkR2hwY3k1M2FXUjBhQzh5TUNrN1hHNGdJSDFjYmx4dUlDQmpiMnh2Y2tsdWRHVnlabUZqWlNncElIdGNibHh1SUNBZ0lIUm9hWE11WjNKaFpHbGxiblF1YzNSdmNITmJNRjB1YzJWMFFYUjBjbWxpZFhSbEtDZHpkRzl3TFdOdmJHOXlKeXdnZEdocGN5NWpiMnh2Y25NdVlXTmpaVzUwS1R0Y2JpQWdJQ0IwYUdsekxtZHlZV1JwWlc1MExuTjBiM0J6V3pGZExuTmxkRUYwZEhKcFluVjBaU2duYzNSdmNDMWpiMnh2Y2ljc0lIUm9hWE11WTI5c2IzSnpMbVpwYkd3cE8xeHVJQ0FnSUhSb2FYTXVjbVZ1WkdWeUtDazdYRzRnSUgxY2JseHVJQ0F2S2x4dUlDQXFJRlZ3WkdGMFpTQjBhR1VnZG1semRXRnNJR2x1ZEdWeVptRmpaU0IxYzJsdVp5QnBkSE1nWTNWeWNtVnVkQ0J6ZEdGMFpWeHVJQ0FxWEc0Z0lDb2dRR1Y0WVcxd2JHVmNiaUFnS2lCaWRYUjBiMjR1Y21WdVpHVnlLQ2s3WEc0Z0lDb3ZYRzRnSUhKbGJtUmxjaWdwSUh0Y2JpQWdJQ0JwWmlBb0lYUm9hWE11YzNSaGRHVXBJSHRjYmlBZ0lDQWdJSFJvYVhNdWNHRmtMbk5sZEVGMGRISnBZblYwWlNnblptbHNiQ2NzSUhSb2FYTXVZMjlzYjNKekxtWnBiR3dwTzF4dUlDQWdJQ0FnZEdocGN5NXdZV1F1YzJWMFFYUjBjbWxpZFhSbEtDZHpkSEp2YTJVbkxDQjBhR2x6TG1OdmJHOXljeTV0WldScGRXMU1hV2RvZENrN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJR2xtSUNoMGFHbHpMbTF2WkdVOVBUMG5ZV1owWlhKMGIzVmphQ2NwSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTV3WVdRdWMyVjBRWFIwY21saWRYUmxLQ2R6ZEhKdmEyVW5MQ0FuZFhKc0tDTW5LM1JvYVhNdVozSmhaR2xsYm5RdWFXUXJKeWtuS1R0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTVuY21Ga2FXVnVkQzVsYkdWdFpXNTBMbk5sZEVGMGRISnBZblYwWlNnblkzZ25MQ0FvZEdocGN5NXdiM05wZEdsdmJpNTRLakV3TUNrckp5VW5LVHRjYmlBZ0lDQWdJQ0FnZEdocGN5NW5jbUZrYVdWdWRDNWxiR1Z0Wlc1MExuTmxkRUYwZEhKcFluVjBaU2duWTNrbkxDQW9LREV0ZEdocGN5NXdiM05wZEdsdmJpNTVLU294TURBcEt5Y2xKeWs3WEc0Z0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0IwYUdsekxuQmhaQzV6WlhSQmRIUnlhV0oxZEdVb0ozTjBjbTlyWlNjc0lIUm9hWE11WTI5c2IzSnpMbUZqWTJWdWRDazdYRzRnSUNBZ0lDQjlYRzRnSUNBZ0lDQjBhR2x6TG5CaFpDNXpaWFJCZEhSeWFXSjFkR1VvSjJacGJHd25MQ0IwYUdsekxtTnZiRzl5Y3k1aFkyTmxiblFwTzF4dUlDQWdJSDFjYmlBZ2ZWeHVYRzU5WEc1Y2JseHVYRzR2THlCWFJVSlFRVU5MSUVaUFQxUkZVaUF2TDF4dUx5OGdMaTkrTDJwemFHbHVkQzFzYjJGa1pYSWhMaTlzYVdJdmFXNTBaWEptWVdObGN5OWlkWFIwYjI0dWFuTWlMQ0luZFhObElITjBjbWxqZENjN1hHNWNibXhsZENCemRtY2dQU0J5WlhGMWFYSmxLQ2N1TGk5MWRHbHNMM04yWnljcE8xeHViR1YwSUcxaGRHZ2dQU0J5WlhGMWFYSmxLQ2N1TGk5MWRHbHNMMjFoZEdnbktUdGNibXhsZENCVWIyZG5iR1ZOYjJSbGJDQTlJSEpsY1hWcGNtVW9KeTR1TDIxdlpHVnNjeTkwYjJkbmJHVW5LVHRjYm14bGRDQkpiblJsY21aaFkyVWdQU0J5WlhGMWFYSmxLQ2N1TGk5amIzSmxMMmx1ZEdWeVptRmpaU2NwTzF4dVhHNHZLaXBjYmtKMWRIUnZiaUJVWlcxd2JHRjBaVnh1S2k5Y2JseHVaWGh3YjNKMElHUmxabUYxYkhRZ1kyeGhjM01nUW5WMGRHOXVWR1Z0Y0d4aGRHVWdaWGgwWlc1a2N5QkpiblJsY21aaFkyVWdlMXh1WEc0Z0lHTnZibk4wY25WamRHOXlLR0Z5WjNNc2IzQjBhVzl1Y3l4a1pXWmhkV3gwY3lrZ2UxeHVYRzRnSUNBZ2MzVndaWElvWVhKbmN5eHZjSFJwYjI1ekxHUmxabUYxYkhSektUdGNibHh1SUNBZ0lIUm9hWE11Ylc5a1pTQTlJSFJvYVhNdWMyVjBkR2x1WjNNdWJXOWtaU0I4ZkNBblluVjBkRzl1Snp0Y2JseHVJQ0FnSUhSb2FYTXVjRzl6YVhScGIyNGdQU0I3WEc0Z0lDQWdJQ0I0T2lBd0xGeHVJQ0FnSUNBZ2VUb2dNRnh1SUNBZ0lIMDdYRzVjYmlBZ0lDQjBhR2x6TGw5emRHRjBaU0E5SUc1bGR5QlViMmRuYkdWTmIyUmxiQ2gwYUdsekxuTmxkSFJwYm1kekxuTjBZWFJsS1R0Y2JseHVJQ0I5WEc1Y2JpQWdZblZwYkdSSmJuUmxjbVpoWTJVb0tTQjdYRzRnSUNBZ2RHaHBjeTV3WVdRZ1BTQnpkbWN1WTNKbFlYUmxLQ2RqYVhKamJHVW5LVHRjYmlBZ0lDQjBhR2x6TG5CaFpDNXpaWFJCZEhSeWFXSjFkR1VvSjJacGJHd25MQ0FuSTJReE9DY3BPMXh1SUNBZ0lIUm9hWE11Y0dGa0xuTmxkRUYwZEhKcFluVjBaU2duYzNSeWIydGxKeXdnSnlOa01UZ25LVHRjYmlBZ0lDQjBhR2x6TG5CaFpDNXpaWFJCZEhSeWFXSjFkR1VvSjNOMGNtOXJaUzEzYVdSMGFDY3NJRFFwTzF4dVhHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExtRndjR1Z1WkVOb2FXeGtLSFJvYVhNdWNHRmtLVHRjYmx4dUlDQWdJSFJvYVhNdWFXNTBaWEpoWTNScGIyNVVZWEpuWlhRZ1BTQjBhR2x6TG5CaFpEdGNibHh1SUNBZ0lIUm9hWE11YzJsNlpVbHVkR1Z5Wm1GalpTZ3BPMXh1SUNCOVhHNWNiaUFnYzJsNlpVbHVkR1Z5Wm1GalpTZ3BJSHRjYmlBZ0lDQjBhR2x6TG5CaFpDNXpaWFJCZEhSeWFXSjFkR1VvSjJONEp5eDBhR2x6TG5kcFpIUm9MeklwTzF4dUlDQWdJSFJvYVhNdWNHRmtMbk5sZEVGMGRISnBZblYwWlNnblkza25MSFJvYVhNdWFHVnBaMmgwTHpJcE8xeHVJQ0FnSUhSb2FYTXVjR0ZrTG5ObGRFRjBkSEpwWW5WMFpTZ25jaWNzSUUxaGRHZ3ViV2x1S0hSb2FYTXVkMmxrZEdnc2RHaHBjeTVvWldsbmFIUXBJQzhnTWlBdElESXBPMXh1SUNCOVhHNWNiaUFnY21WdVpHVnlLQ2tnZTF4dUlDQWdJR2xtSUNnaGRHaHBjeTV6ZEdGMFpTa2dlMXh1SUNBZ0lDQWdkR2hwY3k1d1lXUXVjMlYwUVhSMGNtbGlkWFJsS0NkbWFXeHNKeXdnZEdocGN5NWpiMnh2Y25NdVptbHNiQ2s3WEc0Z0lDQWdJQ0IwYUdsekxuQmhaQzV6WlhSQmRIUnlhV0oxZEdVb0ozTjBjbTlyWlNjc0lIUm9hWE11WTI5c2IzSnpMbTFsWkdsMWJVeHBaMmgwS1R0Y2JpQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdkR2hwY3k1d1lXUXVjMlYwUVhSMGNtbGlkWFJsS0NkbWFXeHNKeXdnZEdocGN5NWpiMnh2Y25NdVlXTmpaVzUwS1R0Y2JpQWdJQ0FnSUhSb2FYTXVjR0ZrTG5ObGRFRjBkSEpwWW5WMFpTZ25jM1J5YjJ0bEp5d2dkR2hwY3k1amIyeHZjbk11WVdOalpXNTBLVHRjYmlBZ0lDQjlYRzRnSUgxY2JseHVJQ0JrYjNkdUtIQmhhVzUwWW5KMWMyZ3BJSHRjYmlBZ0lDQnpkMmwwWTJnZ0tIUm9hWE11Ylc5a1pTa2dlMXh1SUNBZ0lDQWdZMkZ6WlNBbmFXMXdkV3h6WlNjNlhHNGdJQ0FnSUNBZ0lIUm9hWE11ZEhWeWJrOXVLQ2s3WEc0Z0lDQWdJQ0FnSUdsbUlDaDBhR2x6TG5ScGJXVnZkWFFwSUh0Y2JpQWdJQ0FnSUNBZ0lDQmpiR1ZoY2xScGJXVnZkWFFvZEdocGN5NTBhVzFsYjNWMEtUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0IwYUdsekxuUnBiV1Z2ZFhRZ1BTQnpaWFJVYVcxbGIzVjBLSFJvYVhNdWRIVnliazltWmk1aWFXNWtLSFJvYVhNcExETXdLVHRjYmlBZ0lDQXZMeUFnSUNCMGFHbHpMbVZ0YVhRb0oyTm9ZVzVuWlNjc2RHaHBjeTV6ZEdGMFpTazdYRzRnSUNBZ0lDQWdJR0p5WldGck8xeHVJQ0FnSUNBZ1kyRnpaU0FuWW5WMGRHOXVKenBjYmlBZ0lDQWdJQ0FnZEdocGN5NTBkWEp1VDI0b0tUdGNiaUFnSUNBdkx5QWdJQ0IwYUdsekxtVnRhWFFvSjJOb1lXNW5aU2NzZEdocGN5NXpkR0YwWlNrN1hHNGdJQ0FnSUNBZ0lHSnlaV0ZyTzF4dUlDQWdJQ0FnWTJGelpTQW5ZV1owWlhKMGIzVmphQ2M2WEc0Z0lDQWdJQ0FnSUhSb2FYTXVjRzl6YVhScGIyNGdQU0I3WEc0Z0lDQWdJQ0FnSUNBZ2VEb2diV0YwYUM1amJHbHdLSFJvYVhNdWJXOTFjMlV1ZUNBdklIUm9hWE11ZDJsa2RHZ3NNQ3d4S1N4Y2JpQWdJQ0FnSUNBZ0lDQjVPaUJ0WVhSb0xtTnNhWEFvTVMxMGFHbHpMbTF2ZFhObExua2dMeUIwYUdsekxtaGxhV2RvZEN3d0xERXBYRzRnSUNBZ0lDQWdJSDA3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVkSFZ5Yms5dUtDazdYRzRnSUNBZ0x5OGdJQ0FnZEdocGN5NWxiV2wwS0NkamFHRnVaMlVuTEh0Y2JpQWdJQ0F2THlBZ0lDQWdJSE4wWVhSbE9pQjBhR2x6TG5OMFlYUmxMRnh1SUNBZ0lDOHZJQ0FnSUNBZ2VEb2dkR2hwY3k1d2IzTnBkR2x2Ymk1NExGeHVJQ0FnSUM4dklDQWdJQ0FnZVRvZ2RHaHBjeTV3YjNOcGRHbHZiaTU1TEZ4dUlDQWdJQzh2SUNBZ0lIMHBPMXh1SUNBZ0lDQWdJQ0JpY21WaGF6dGNiaUFnSUNBZ0lHTmhjMlVnSjNSdloyZHNaU2M2WEc0Z0lDQWdJQ0FnSUhSb2FYTXVabXhwY0Nod1lXbHVkR0p5ZFhOb0tUdGNiaUFnSUNBdkx5QWdJQ0IwYUdsekxtVnRhWFFvSjJOb1lXNW5aU2NzZEdocGN5NXpkR0YwWlNrN1hHNGdJQ0FnSUNBZ0lHSnlaV0ZyTzF4dUlDQWdJSDFjYmx4dUlDQjlYRzVjYmlBZ1ltVnVaQ2h0YjNWelpTa2dlMXh1SUNBZ0lHbG1JQ2gwYUdsekxtMXZaR1U5UFQwbllXWjBaWEowYjNWamFDY3BJSHRjYmlBZ0lDQWdJSFJvYVhNdWJXOTFjMlVnUFNCdGIzVnpaU0I4ZkNCMGFHbHpMbTF2ZFhObE8xeHVJQ0FnSUNBZ2RHaHBjeTV3YjNOcGRHbHZiaUE5SUh0Y2JpQWdJQ0FnSUNBZ2VEb2diV0YwYUM1amJHbHdLSFJvYVhNdWJXOTFjMlV1ZUNBdklIUm9hWE11ZDJsa2RHZ3NNQ3d4S1N4Y2JpQWdJQ0FnSUNBZ2VUb2diV0YwYUM1amJHbHdLREVnTFNCMGFHbHpMbTF2ZFhObExua2dMeUIwYUdsekxtaGxhV2RvZEN3d0xERXBYRzRnSUNBZ0lDQjlPMXh1SUNBZ0lDQWdkR2hwY3k1bGJXbDBLQ2RqYUdGdVoyVW5MSHRjYmlBZ0lDQWdJQ0FnYzNSaGRHVTZJSFJvYVhNdWMzUmhkR1VzWEc0Z0lDQWdJQ0FnSUhnNklIUm9hWE11Y0c5emFYUnBiMjR1ZUN4Y2JpQWdJQ0FnSUNBZ2VUb2dkR2hwY3k1d2IzTnBkR2x2Ymk1NUxGeHVJQ0FnSUNBZ2ZTazdYRzRnSUNBZ0lDQjBhR2x6TG5KbGJtUmxjaWdwTzF4dUlDQWdJSDFjYmlBZ2ZWeHVYRzRnSUhWd0tDa2dlMXh1SUNBZ0lITjNhWFJqYUNBb2RHaHBjeTV0YjJSbEtTQjdYRzRnSUNBZ0lDQmpZWE5sSUNkaWRYUjBiMjRuT2x4dUlDQWdJQ0FnSUNCMGFHbHpMblIxY201UFptWW9LVHRjYmlBZ0lDQWdJQzh2SUNCMGFHbHpMbVZ0YVhRb0oyTm9ZVzVuWlNjc2RHaHBjeTV6ZEdGMFpTazdYRzRnSUNBZ0lDQWdJR0p5WldGck8xeHVJQ0FnSUNBZ1kyRnpaU0FuWVdaMFpYSjBiM1ZqYUNjNlhHNGdJQ0FnSUNBZ0lIUm9hWE11ZEhWeWJrOW1aaWdwTzF4dUlDQWdJQ0FnSUNCMGFHbHpMbkJ2YzJsMGFXOXVJRDBnZTF4dUlDQWdJQ0FnSUNBZ0lIZzZJRzFoZEdndVkyeHBjQ2gwYUdsekxtMXZkWE5sTG5nZ0x5QjBhR2x6TG5kcFpIUm9MREFzTVNrc1hHNGdJQ0FnSUNBZ0lDQWdlVG9nYldGMGFDNWpiR2x3S0RFZ0xTQjBhR2x6TG0xdmRYTmxMbmtnTHlCMGFHbHpMbWhsYVdkb2RDd3dMREVwWEc0Z0lDQWdJQ0FnSUgwN1hHNGdJQ0FnSUNBdkx5QWdkR2hwY3k1bGJXbDBLQ2RqYUdGdVoyVW5MSHRjYmlBZ0lDQWdJQzh2SUNBZ0lITjBZWFJsT2lCMGFHbHpMbk4wWVhSbExGeHVJQ0FnSUNBZ0x5OGdJQ0FnZURvZ2RHaHBjeTV3YjNOcGRHbHZiaTU0TEZ4dUlDQWdJQ0FnTHk4Z0lDQWdlVG9nZEdocGN5NXdiM05wZEdsdmJpNTVMRnh1SUNBZ0lDQWdMeThnSUgwcE8xeHVJQ0FnSUNBZ0lDQmljbVZoYXp0Y2JpQWdJQ0I5WEc0Z0lIMWNibHh1SUNBdktpQnZkbVZ5ZDNKcGRHRmliR1VnYVc1MFpYSmhZM1JwYjI0Z2FHRnVaR3hsY25NZ0tpOWNibHh1SUNCamJHbGpheWdwSUh0Y2JpQWdJQ0IwYUdsekxtUnZkMjRvS1R0Y2JpQWdmVnh1SUNCdGIzWmxLQ2tnZTF4dUlDQWdJSFJvYVhNdVltVnVaQ2dwTzF4dUlDQjlYRzRnSUhKbGJHVmhjMlVvS1NCN1hHNGdJQ0FnZEdocGN5NTFjQ2dwTzF4dUlDQjlYRzVjYmlBZ0x5b3FYRzRnSUZkb1pYUm9aWElnZEdobElHSjFkSFJ2YmlCcGN5QnZiaUFvY0hKbGMzTmxaQ2tnYjNJZ2IyWm1JQ2h1YjNRZ2NISmxjM05sWkNsY2JpQWdRSFI1Y0dVZ2UySnZiMnhsWVc1OVhHNGdJRUJsZUdGdGNHeGxJR0oxZEhSdmJpNXpkR0YwWlNBOUlIUnlkV1U3WEc0Z0lDb3ZYRzRnSUdkbGRDQnpkR0YwWlNncElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWZjM1JoZEdVdWMzUmhkR1U3WEc0Z0lIMWNiaUFnYzJWMElITjBZWFJsS0haaGJIVmxLU0I3WEc0Z0lDQWdkR2hwY3k1ZmMzUmhkR1V1Wm14cGNDaDJZV3gxWlNrN1hHNGdJQ0FnYVdZZ0tIUm9hWE11Ylc5a1pUMDlQU2RoWm5SbGNuUnZkV05vSnlrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTVsYldsMEtDZGphR0Z1WjJVbkxIdGNiaUFnSUNBZ0lDQWdjM1JoZEdVNklIUm9hWE11YzNSaGRHVXNYRzRnSUNBZ0lDQWdJSGc2SUhSb2FYTXVjRzl6YVhScGIyNHVlQ3hjYmlBZ0lDQWdJQ0FnZVRvZ2RHaHBjeTV3YjNOcGRHbHZiaTU1TEZ4dUlDQWdJQ0FnZlNrN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJSFJvYVhNdVpXMXBkQ2duWTJoaGJtZGxKeXgwYUdsekxuTjBZWFJsS1R0Y2JpQWdJQ0I5WEc0Z0lDQWdkR2hwY3k1eVpXNWtaWElvS1R0Y2JpQWdmVnh1WEc0Z0lDOHFLbHh1SUNCRGFHRnVaMlVnZEdobElHSjFkSFJ2YmlCMGJ5QnBkSE1nWVd4MFpYSnVZWFJsSUhOMFlYUmxJQ2h2Wm1ZOVBtOXVMQ0J2YmowK2IyWm1LU3dnYjNJZ1pteHBjQ0JwZENCMGJ5QmhJSE53WldOcFptbGxaQ0J6ZEdGMFpTNWNiaUFnUUhCaGNtRnRJSFpoYkhWbElIdGliMjlzWldGdWZTQW9UM0IwYVc5dVlXd3BJRk4wWVhSbElIUnZJR1pzYVhBZ2RHOHVYRzRnSUVCbGVHRnRjR3hsSUdKMWRIUnZiaTVtYkdsd0tDazdYRzRnSUNvdlhHNGdJR1pzYVhBb2RtRnNkV1VwSUh0Y2JpQWdJQ0IwYUdsekxsOXpkR0YwWlM1bWJHbHdLSFpoYkhWbEtUdGNiaUFnSUNCcFppQW9kR2hwY3k1dGIyUmxQVDA5SjJGbWRHVnlkRzkxWTJnbktTQjdYRzRnSUNBZ0lDQjBhR2x6TG1WdGFYUW9KMk5vWVc1blpTY3NlMXh1SUNBZ0lDQWdJQ0J6ZEdGMFpUb2dkR2hwY3k1emRHRjBaU3hjYmlBZ0lDQWdJQ0FnZURvZ2RHaHBjeTV3YjNOcGRHbHZiaTU0TEZ4dUlDQWdJQ0FnSUNCNU9pQjBhR2x6TG5CdmMybDBhVzl1TG5rc1hHNGdJQ0FnSUNCOUtUdGNiaUFnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnZEdocGN5NWxiV2wwS0NkamFHRnVaMlVuTEhSb2FYTXVjM1JoZEdVcE8xeHVJQ0FnSUgxY2JpQWdJQ0IwYUdsekxuSmxibVJsY2lncE8xeHVJQ0I5WEc1Y2JpQWdMeW9xWEc0Z0lGUjFjbTRnZEdobElHSjFkSFJ2YmlkeklITjBZWFJsSUhSdklIUnlkV1V1WEc0Z0lFQmxlR0Z0Y0d4bElHSjFkSFJ2Ymk1MGRYSnVUMjRvS1R0Y2JpQWdLaTljYmlBZ2RIVnliazl1S0dWdGFYUjBhVzVuS1NCN1hHNGdJQ0FnZEdocGN5NWZjM1JoZEdVdWIyNG9LVHRjYmlBZ0lDQnBaaUFvWlcxcGRIUnBibWNoUFQxbVlXeHpaU2tnZTF4dUlDQWdJQ0FnYVdZZ0tIUm9hWE11Ylc5a1pUMDlQU2RoWm5SbGNuUnZkV05vSnlrZ2UxeHVJQ0FnSUNBZ0lDQjBhR2x6TG1WdGFYUW9KMk5vWVc1blpTY3NlMXh1SUNBZ0lDQWdJQ0FnSUhOMFlYUmxPaUIwYUdsekxuTjBZWFJsTEZ4dUlDQWdJQ0FnSUNBZ0lIZzZJSFJvYVhNdWNHOXphWFJwYjI0dWVDeGNiaUFnSUNBZ0lDQWdJQ0I1T2lCMGFHbHpMbkJ2YzJsMGFXOXVMbmtzWEc0Z0lDQWdJQ0FnSUgwcE8xeHVJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTVsYldsMEtDZGphR0Z1WjJVbkxIUm9hWE11YzNSaGRHVXBPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lIMWNiaUFnSUNCMGFHbHpMbkpsYm1SbGNpZ3BPMXh1SUNCOVhHNWNiaUFnTHlvcVhHNGdJRlIxY200Z2RHaGxJR0oxZEhSdmJpZHpJSE4wWVhSbElIUnZJR1poYkhObExseHVJQ0JBWlhoaGJYQnNaU0JpZFhSMGIyNHVkSFZ5Yms5bVppZ3BPMXh1SUNBcUwxeHVJQ0IwZFhKdVQyWm1LR1Z0YVhSMGFXNW5LU0I3WEc0Z0lDQWdkR2hwY3k1ZmMzUmhkR1V1YjJabUtDazdYRzRnSUNBZ2FXWWdLR1Z0YVhSMGFXNW5JVDA5Wm1Gc2MyVXBJSHRjYmlBZ0lDQWdJR2xtSUNoMGFHbHpMbTF2WkdVOVBUMG5ZV1owWlhKMGIzVmphQ2NwSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTVsYldsMEtDZGphR0Z1WjJVbkxIdGNiaUFnSUNBZ0lDQWdJQ0J6ZEdGMFpUb2dkR2hwY3k1emRHRjBaU3hjYmlBZ0lDQWdJQ0FnSUNCNE9pQjBhR2x6TG5CdmMybDBhVzl1TG5nc1hHNGdJQ0FnSUNBZ0lDQWdlVG9nZEdocGN5NXdiM05wZEdsdmJpNTVMRnh1SUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVaVzFwZENnblkyaGhibWRsSnl4MGFHbHpMbk4wWVhSbEtUdGNiaUFnSUNBZ0lIMWNiaUFnSUNCOVhHNGdJQ0FnZEdocGN5NXlaVzVrWlhJb0tUdGNiaUFnZlZ4dVhHNTlYRzVjYmx4dVhHNHZMeUJYUlVKUVFVTkxJRVpQVDFSRlVpQXZMMXh1THk4Z0xpOStMMnB6YUdsdWRDMXNiMkZrWlhJaExpOXNhV0l2WTI5dGNHOXVaVzUwY3k5aWRYUjBiMjUwWlcxd2JHRjBaUzVxY3lJc0lpZDFjMlVnYzNSeWFXTjBKenRjYmx4dWJHVjBJRUoxZEhSdmJsUmxiWEJzWVhSbElEMGdjbVZ4ZFdseVpTZ25MaTR2WTI5dGNHOXVaVzUwY3k5aWRYUjBiMjUwWlcxd2JHRjBaU2NwTzF4dVhHNHZLaXBjYmlvZ1ZHVjRkRUoxZEhSdmJseHVLbHh1S2lCQVpHVnpZM0pwY0hScGIyNGdWR1Y0ZENCaWRYUjBiMjVjYmlwY2Jpb2dRR1JsYlc4Z1BITndZVzRnYm1WNGRYTXRkV2s5WENKMFpYaDBRblYwZEc5dVhDSStQQzl6Y0dGdVBseHVLbHh1S2lCQVpYaGhiWEJzWlZ4dUtpQjJZWElnZEdWNGRHSjFkSFJ2YmlBOUlHNWxkeUJPWlhoMWN5NVVaWGgwUW5WMGRHOXVLQ2NqZEdGeVoyVjBKeWxjYmlwY2Jpb2dRR1Y0WVcxd2JHVmNiaW9nZG1GeUlIUmxlSFJpZFhSMGIyNGdQU0J1WlhjZ1RtVjRkWE11VkdWNGRFSjFkSFJ2YmlnbkkzUmhjbWRsZENjc2UxeHVLaUFnSUNBZ0ozTnBlbVVuT2lCYk1UVXdMRFV3WFN4Y2Jpb2dJQ0FnSUNkemRHRjBaU2M2SUdaaGJITmxMRnh1S2lBZ0lDQWdKM1JsZUhRbk9pQW5VR3hoZVNjc1hHNHFJQ0FnSUNBbllXeDBaWEp1WVhSbFZHVjRkQ2M2SUNkVGRHOXdKMXh1S2lCOUtWeHVLbHh1S2lCQWIzVjBjSFYwWEc0cUlHTm9ZVzVuWlZ4dUtpQkdhWEpsY3lCaGJua2dkR2x0WlNCMGFHVWdhVzUwWlhKbVlXTmxKM01nZG1Gc2RXVWdZMmhoYm1kbGN5NGdQR0p5UGx4dUtpQlVhR1VnWlhabGJuUWdaR0YwWVNCcGN5QmhJRHhwUG5OMGNtbHVaend2YVQ0Z2IyWWdkR2hsSUhSbGVIUWdiMjRnZEdobElHSjFkSFJ2YmlCaGRDQjBhR1VnYlc5dFpXNTBJR2wwSUhkaGN5QmpiR2xqYTJWa0xseHVLbHh1S2lCQWIzVjBjSFYwWlhoaGJYQnNaVnh1S2lCMFpYaDBZblYwZEc5dUxtOXVLQ2RqYUdGdVoyVW5MR1oxYm1OMGFXOXVLSFlwSUh0Y2Jpb2dJQ0JqYjI1emIyeGxMbXh2WnloMktUdGNiaW9nZlNsY2JpcGNiaW92WEc1Y2JtVjRjRzl5ZENCa1pXWmhkV3gwSUdOc1lYTnpJRlJsZUhSQ2RYUjBiMjRnWlhoMFpXNWtjeUJDZFhSMGIyNVVaVzF3YkdGMFpTQjdYRzVjYmlBZ1kyOXVjM1J5ZFdOMGIzSW9LU0I3WEc1Y2JpQWdJQ0JzWlhRZ2IzQjBhVzl1Y3lBOUlGc25kbUZzZFdVblhUdGNibHh1SUNBZ0lHeGxkQ0JrWldaaGRXeDBjeUE5SUh0Y2JpQWdJQ0FnSUNkemFYcGxKem9nV3pFMU1DdzFNRjBzWEc0Z0lDQWdJQ0FuYzNSaGRHVW5PaUJtWVd4elpTeGNiaUFnSUNBZ0lDZDBaWGgwSnpvZ0oxQnNZWGtuWEc0Z0lDQWdmVHRjYmx4dUlDQWdJSE4xY0dWeUtHRnlaM1Z0Wlc1MGN5eHZjSFJwYjI1ekxHUmxabUYxYkhSektUdGNibHh1SUNBZ0lIUm9hWE11WDNSbGVIUWdQU0IwYUdsekxuTmxkSFJwYm1kekxuUmxlSFE3WEc1Y2JpQWdJQ0JwWmloMGFHbHpMbk5sZEhScGJtZHpMbUZzZEdWeWJtRjBaU2w3SUM4dlZFOUVUem9nVW1WdGIzWmxJSFJvYVhNZ1kyOXVaR2wwYVc5dVlXd2dhVzRnWVNCaWNtVmhhMmx1WnkxamFHRnVaMlZ6SUhKbGJHVmhjMlZjYmlBZ0lDQWdJSFJvYVhNdWMyVjBkR2x1WjNNdVlXeDBaWEp1WVhSbFZHVjRkQ0E5SUhSb2FYTXVjMlYwZEdsdVozTXVZV3gwWlhKdVlYUmxPMXh1SUNBZ0lDQWdZMjl1YzI5c1pTNTNZWEp1S0Z3aUoyRnNkR1Z5Ym1GMFpTY2dhVzVwZEdsaGRHOXlJR2x6SUdSbGNISmxZMkYwWldRdUlGVnpaU0FuWVd4MFpYSnVZWFJsVkdWNGRDY2dhVzV6ZEdWaFpDNWNJaWs3WEc0Z0lDQWdmVnh1SUNBZ0lIUm9hWE11WDJGc2RHVnlibUYwWlZSbGVIUWdQU0IwYUdsekxuTmxkSFJwYm1kekxtRnNkR1Z5Ym1GMFpWUmxlSFE3WEc0Z0lDQWdkR2hwY3k1dGIyUmxJRDBnS0hSb2FYTXVjMlYwZEdsdVozTXVZV3gwWlhKdVlYUmxWR1Y0ZENrZ1B5QW5kRzluWjJ4bEp5QTZJQ2RpZFhSMGIyNG5PMXh1SUNBZ0lIUm9hWE11YVc1cGRDZ3BPMXh1SUNBZ0lIUm9hWE11Y21WdVpHVnlLQ2s3WEc1Y2JpQWdJQ0IwYUdsekxuTjBZWFJsSUQwZ2RHaHBjeTV6WlhSMGFXNW5jeTV6ZEdGMFpUdGNibHh1SUNCOVhHNWNiaUFnWW5WcGJHUkdjbUZ0WlNncElIdGNibHh1SUNBZ0lIUm9hWE11Wld4bGJXVnVkQ0E5SUdSdlkzVnRaVzUwTG1OeVpXRjBaVVZzWlcxbGJuUW9KMlJwZGljcE8xeHVJQ0FnSUhSb2FYTXVjR0Z5Wlc1MExtRndjR1Z1WkVOb2FXeGtLSFJvYVhNdVpXeGxiV1Z1ZENrN1hHNWNiaUFnSUNCMGFHbHpMblJsZUhSRmJHVnRaVzUwSUQwZ1pHOWpkVzFsYm5RdVkzSmxZWFJsUld4bGJXVnVkQ2duWkdsMkp5azdYRzRnSUNBZ2RHaHBjeTUwWlhoMFJXeGxiV1Z1ZEM1cGJtNWxja2hVVFV3Z1BTQjBhR2x6TGw5MFpYaDBPMXh1SUNBZ0lIUm9hWE11Wld4bGJXVnVkQzVoY0hCbGJtUkRhR2xzWkNoMGFHbHpMblJsZUhSRmJHVnRaVzUwS1R0Y2JpQWdmVnh1WEc0Z0lHSjFhV3hrU1c1MFpYSm1ZV05sS0NrZ2UxeHVYRzRnSUgxY2JseHVJQ0JqYjJ4dmNrbHVkR1Z5Wm1GalpTZ3BJSHRjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1YzNSNWJHVXVZMjlzYjNJZ1BTQjBhR2x6TG1OdmJHOXljeTVrWVhKck8xeHVJQ0FnSUhSb2FYTXVjbVZ1WkdWeUtDazdYRzRnSUgxY2JseHVJQ0J6YVhwbFNXNTBaWEptWVdObEtDa2dlMXh1SUNBZ0lDQWdiR1YwSUhSbGVIUnphWHBsSUQwZ2RHaHBjeTVvWldsbmFIUXZNenRjYmlBZ0lDQWdJR3hsZENCMFpYaDBjMmw2WlRJZ1BTQW9kR2hwY3k1M2FXUjBhQ0F2SUNoMGFHbHpMbDkwWlhoMExteGxibWQwYUNBcklESXBJQ2s3WEc0Z0lDQWdJQ0IwWlhoMGMybDZaU0E5SUUxaGRHZ3ViV2x1S0hSbGVIUnphWHBsTEhSbGVIUnphWHBsTWlrN1hHNGdJQ0FnSUNCcFppQW9kR2hwY3k1aGJIUmxjbTVoZEdWVVpYaDBLU0I3WEc0Z0lDQWdJQ0FnSUd4bGRDQjBaWGgwYzJsNlpUTWdQU0FvZEdocGN5NTNhV1IwYUNBdklDaDBhR2x6TG1Gc2RHVnlibUYwWlZSbGVIUXViR1Z1WjNSb0lDc2dNaWtnS1R0Y2JpQWdJQ0FnSUNBZ2RHVjRkSE5wZW1VZ1BTQk5ZWFJvTG0xcGJpaDBaWGgwYzJsNlpTeDBaWGgwYzJsNlpUTXBPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdiR1YwSUhOMGVXeGxjeUE5SUNkM2FXUjBhRG9nSnlBcklIUm9hWE11ZDJsa2RHZ2dLeUFuY0hnN0p6dGNiaUFnSUNBZ0lITjBlV3hsY3lBclBTQW5hR1ZwWjJoME9pQW5JQ3NnZEdocGN5NW9aV2xuYUhRZ0t5QW5jSGc3Snp0Y2JpQWdJQ0FnSUhOMGVXeGxjeUFyUFNBbmNHRmtaR2x1WnpvZ0p5c29kR2hwY3k1b1pXbG5hSFF0ZEdWNGRITnBlbVVwTHpJckozQjRJREJ3ZURzbk8xeHVJQ0FnSUNBZ2MzUjViR1Z6SUNzOUlDZGliM2d0YzJsNmFXNW5PaUJpYjNKa1pYSXRZbTk0T3ljN1hHNGdJQ0FnSUNCemRIbHNaWE1nS3owZ0ozUmxlSFF0WVd4cFoyNDZJR05sYm5SbGNqc25PMXh1SUNBZ0lDQWdjM1I1YkdWeklDczlJQ2RtYjI1MExXWmhiV2xzZVRvZ2FXNW9aWEpwZERzbk8xeHVJQ0FnSUNBZ2MzUjViR1Z6SUNzOUlDZG1iMjUwTFhkbGFXZG9kRG9nTnpBd095YzdYRzRnSUNBZ0lDQnpkSGxzWlhNZ0t6MGdKMjl3WVdOcGRIazZJREU3Snp0Y2JpQWdJQ0FnSUhOMGVXeGxjeUFyUFNBblptOXVkQzF6YVhwbE9pY2dLeUIwWlhoMGMybDZaU0FySUNkd2VEc25PMXh1SUNBZ0lDQWdkR2hwY3k1MFpYaDBSV3hsYldWdWRDNXpkSGxzWlM1amMzTlVaWGgwSUQwZ2MzUjViR1Z6TzF4dUlDQWdJQ0FnZEdocGN5NXlaVzVrWlhJb0tUdGNiaUFnZlZ4dVhHNGdJSEpsYm1SbGNpZ3BJSHRjYmlBZ0lDQnBaaUFvSVhSb2FYTXVjM1JoZEdVcElIdGNiaUFnSUNBZ0lIUm9hWE11Wld4bGJXVnVkQzV6ZEhsc1pTNWlZV05yWjNKdmRXNWtRMjlzYjNJZ1BTQjBhR2x6TG1OdmJHOXljeTVtYVd4c08xeHVJQ0FnSUNBZ2RHaHBjeTUwWlhoMFJXeGxiV1Z1ZEM1emRIbHNaUzVqYjJ4dmNpQTlJSFJvYVhNdVkyOXNiM0p6TG1SaGNtczdYRzRnSUNBZ0lDQjBhR2x6TG5SbGVIUkZiR1Z0Wlc1MExtbHVibVZ5U0ZSTlRDQTlJSFJvYVhNdVgzUmxlSFE3WEc0Z0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lIUm9hWE11Wld4bGJXVnVkQzV6ZEhsc1pTNWlZV05yWjNKdmRXNWtRMjlzYjNJZ1BTQjBhR2x6TG1OdmJHOXljeTVoWTJObGJuUTdYRzRnSUNBZ0lDQjBhR2x6TG5SbGVIUkZiR1Z0Wlc1MExuTjBlV3hsTG1OdmJHOXlJRDBnZEdocGN5NWpiMnh2Y25NdVptbHNiRHRjYmlBZ0lDQWdJR2xtSUNoMGFHbHpMbUZzZEdWeWJtRjBaVlJsZUhRcElIdGNiaUFnSUNBZ0lDQWdkR2hwY3k1MFpYaDBSV3hsYldWdWRDNXBibTVsY2toVVRVd2dQU0IwYUdsekxsOWhiSFJsY201aGRHVlVaWGgwTzF4dUlDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnZEdocGN5NTBaWGgwUld4bGJXVnVkQzVwYm01bGNraFVUVXdnUFNCMGFHbHpMbDkwWlhoME8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUgxY2JpQWdmVnh1WEc0Z0lDOHFLbHh1SUNCVWFHVWdkR1Y0ZENCMGJ5QmthWE53YkdGNUlIZG9aVzRnZEdobElHSjFkSFJ2YmlCcGN5QnBiaUJwZEhNZ1hDSnZibHdpSUhOMFlYUmxMaUJKWmlCelpYUXNJSFJvYVhNZ2NIVjBjeUIwYUdVZ1luVjBkRzl1SUdsdUlGd2lkRzluWjJ4bFhDSWdiVzlrWlM1Y2JpQWdRSFI1Y0dVZ2UxTjBjbWx1WjMxY2JpQWdLaTljYmlBZ1oyVjBJR0ZzZEdWeWJtRjBaVlJsZUhRb0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVYMkZzZEdWeWJtRjBaVlJsZUhRN1hHNGdJSDFjYmx4dUlDQnpaWFFnWVd4MFpYSnVZWFJsVkdWNGRDaDBaWGgwS1NCN1hHNGdJQ0FnYVdZZ0tIUmxlSFFwSUh0Y2JpQWdJQ0FnSUhSb2FYTXViVzlrWlNBOUlDZDBiMmRuYkdVbk8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0IwYUdsekxtMXZaR1VnUFNBblluVjBkRzl1Snp0Y2JpQWdJQ0I5WEc0Z0lDQWdkR2hwY3k1ZllXeDBaWEp1WVhSbFZHVjRkQ0E5SUhSbGVIUTdYRzRnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmlBZ2ZWeHVYRzVjYmlBZ0x5b3FYRzRnSUZSb1pTQjBaWGgwSUhSdklHUnBjM0JzWVhrdUlDaEpaaUF1WVd4MFpYSnVZWFJsVkdWNGRDQmxlR2x6ZEhNc0lIUm9aVzRnZEdocGN5QXVkR1Y0ZENCM2FXeHNJRzl1YkhrZ1ltVWdaR2x6Y0d4aGVXVmtJSGRvWlc0Z2RHaGxJR0oxZEhSdmJpQnBjeUJwYmlCcGRITWdYQ0p2Wm1aY0lpQnpkR0YwWlM0cFhHNGdJRUIwZVhCbElIdFRkSEpwYm1kOVhHNGdJQ292WEc0Z0lHZGxkQ0IwWlhoMEtDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbDkwWlhoME8xeHVJQ0I5WEc1Y2JpQWdjMlYwSUhSbGVIUW9kR1Y0ZENrZ2UxeHVJQ0FnSUhSb2FYTXVYM1JsZUhRZ1BTQjBaWGgwTzF4dUlDQWdJSFJvYVhNdWMybDZaVWx1ZEdWeVptRmpaU2dwTzF4dUlDQWdJSFJvYVhNdWNtVnVaR1Z5S0NrN1hHNGdJSDFjYmx4dVhHNTlYRzVjYmx4dVhHNHZMeUJYUlVKUVFVTkxJRVpQVDFSRlVpQXZMMXh1THk4Z0xpOStMMnB6YUdsdWRDMXNiMkZrWlhJaExpOXNhV0l2YVc1MFpYSm1ZV05sY3k5MFpYaDBZblYwZEc5dUxtcHpJaXdpSjNWelpTQnpkSEpwWTNRbk8xeHVYRzR2TDJ4bGRDQnpkbWNnUFNCeVpYRjFhWEpsS0NjdUxpOTFkR2xzTDNOMlp5Y3BPMXh1YkdWMElFbHVkR1Z5Wm1GalpTQTlJSEpsY1hWcGNtVW9KeTR1TDJOdmNtVXZhVzUwWlhKbVlXTmxKeWs3WEc1c1pYUWdRblYwZEc5dUlEMGdjbVZ4ZFdseVpTZ25MaTR2YVc1MFpYSm1ZV05sY3k5aWRYUjBiMjRuS1R0Y2JseHVMeW9xWEc0cUlGSmhaR2x2UW5WMGRHOXVYRzRxWEc0cUlFQmtaWE5qY21sd2RHbHZiaUJCYmlCaGNuSmhlU0J2WmlCaWRYUjBiMjV6TGlCQ2VTQmtaV1poZFd4MExDQnpaV3hsWTNScGJtY2diMjVsSUdKMWRIUnZiaUIzYVd4c0lHUmxjMlZzWldOMElHRnNiQ0J2ZEdobGNpQmlkWFIwYjI1ekxDQmlkWFFnZEdocGN5QmpZVzRnWW1VZ1kzVnpkRzl0YVhwbFpDQjFjMmx1WnlCMGFHVWdRVkJKSUdKbGJHOTNMbHh1S2x4dUtpQkFaR1Z0YnlBOFpHbDJJRzVsZUhWekxYVnBQVndpVW1Ga2FXOUNkWFIwYjI1Y0lqNDhMMlJwZGo1Y2JpcGNiaW9nUUdWNFlXMXdiR1ZjYmlvZ2RtRnlJSEpoWkdsdlluVjBkRzl1SUQwZ2JtVjNJRTVsZUhWekxsSmhaR2x2UW5WMGRHOXVLQ2NqZEdGeVoyVjBKeWxjYmlwY2Jpb2dRR1Y0WVcxd2JHVmNiaW9nZG1GeUlISmhaR2x2WW5WMGRHOXVJRDBnYm1WM0lFNWxlSFZ6TGxKaFpHbHZRblYwZEc5dUtDY2pkR0Z5WjJWMEp5eDdYRzRxSUNBZ0ozTnBlbVVuT2lCYk1USXdMREkxWFN4Y2Jpb2dJQ0FuYm5WdFltVnlUMlpDZFhSMGIyNXpKem9nTkN4Y2Jpb2dJQ0FuWVdOMGFYWmxKem9nTFRGY2Jpb2dmU2xjYmlwY2Jpb2dRRzkxZEhCMWRGeHVLaUJqYUdGdVoyVmNiaW9nUm1seVpYTWdZVzU1SUhScGJXVWdkR2hsSUdsdWRHVnlabUZqWlNkeklIWmhiSFZsSUdOb1lXNW5aWE11SUR4aWNqNWNiaW9nVkdobElHVjJaVzUwSUdSaGRHRWdZVzRnUEdrK2FXNTBaV2RsY2p3dmFUNHNJSFJvWlNCcGJtUmxlQ0J2WmlCMGFHVWdZblYwZEc5dUlIUm9ZWFFnYVhNZ1kzVnljbVZ1ZEd4NUlHOXVMaUJKWmlCdWJ5QmlkWFIwYjI0Z2FYTWdjMlZzWldOMFpXUXNJSFJvWlNCMllXeDFaU0IzYVd4c0lHSmxJQzB4TGx4dUtseHVLaUJBYjNWMGNIVjBaWGhoYlhCc1pWeHVLaUJ5WVdScGIySjFkSFJ2Ymk1dmJpZ25ZMmhoYm1kbEp5eG1kVzVqZEdsdmJpaDJLU0I3WEc0cUlDQWdZMjl1YzI5c1pTNXNiMmNvZGlrN1hHNHFJSDBwWEc0cVhHNHFMMXh1WEc1bGVIQnZjblFnWkdWbVlYVnNkQ0JqYkdGemN5QlNZV1JwYjBKMWRIUnZiaUJsZUhSbGJtUnpJRWx1ZEdWeVptRmpaU0I3WEc1Y2JpQWdZMjl1YzNSeWRXTjBiM0lvS1NCN1hHNWNiaUFnSUNCc1pYUWdiM0IwYVc5dWN5QTlJRnNuZG1Gc2RXVW5YVHRjYmx4dUlDQWdJR3hsZENCa1pXWmhkV3gwY3lBOUlIdGNiaUFnSUNBZ0lDZHphWHBsSnpvZ1d6RXlNQ3d5TlYwc1hHNGdJQ0FnSUNBbmJuVnRZbVZ5VDJaQ2RYUjBiMjV6SnpvZ05DeGNiaUFnSUNBZ0lDZGhZM1JwZG1Vbk9pQXRNVnh1SUNBZ0lIMDdYRzVjYmlBZ0lDQnpkWEJsY2loaGNtZDFiV1Z1ZEhNc2IzQjBhVzl1Y3l4a1pXWmhkV3gwY3lrN1hHNWNiaUFnSUNCMGFHbHpMbUoxZEhSdmJuTWdQU0JiWFR0Y2JpQWdJQ0IwYUdsekxsOXVkVzFpWlhKUFprSjFkSFJ2Ym5NZ1BTQjBhR2x6TG5ObGRIUnBibWR6TG01MWJXSmxjazltUW5WMGRHOXVjenRjYmlBZ0lDQjBhR2x6TG1GamRHbDJaU0E5SUhSb2FYTXVjMlYwZEdsdVozTXVZV04wYVhabE8xeHVYRzRnSUNBZ2RHaHBjeTVwYm1sMEtDazdYRzRnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmx4dUlDQjlYRzVjYmlBZ1luVnBiR1JHY21GdFpTZ3BJSHRjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblFnUFNCa2IyTjFiV1Z1ZEM1amNtVmhkR1ZGYkdWdFpXNTBLQ2RrYVhZbktUdGNiaUFnSUNCMGFHbHpMbkJoY21WdWRDNWhjSEJsYm1SRGFHbHNaQ2gwYUdsekxtVnNaVzFsYm5RcE8xeHVJQ0I5WEc1Y2JpQWdZblZwYkdSSmJuUmxjbVpoWTJVb0tTQjdYRzVjYmlBZ0lDQm1iM0lnS0d4bGRDQnBQVEE3YVR4MGFHbHpMbDl1ZFcxaVpYSlBaa0oxZEhSdmJuTTdhU3NyS1NCN1hHNGdJQ0FnSUNCc1pYUWdZMjl1ZEdGcGJtVnlJRDBnWkc5amRXMWxiblF1WTNKbFlYUmxSV3hsYldWdWRDZ25jM0JoYmljcE8xeHVYRzRnSUNBZ0lDQnNaWFFnWW5WMGRHOXVJRDBnYm1WM0lFSjFkSFJ2YmloamIyNTBZV2x1WlhJc0lIdGNiaUFnSUNBZ0lDQWdJQ0J0YjJSbE9pQW5kRzluWjJ4bEp5eGNiaUFnSUNBZ0lDQWdJQ0JqYjIxd2IyNWxiblE2SUhSeWRXVXNYRzRnSUNBZ0lDQWdJSDBzSUhSb2FYTXVkWEJrWVhSbExtSnBibVFvZEdocGN5eHBLU2s3WEc1Y2JpQWdJQ0FnSUhSb2FYTXVZblYwZEc5dWN5NXdkWE5vS0dKMWRIUnZiaWs3WEc0Z0lDQWdJQ0IwYUdsekxtVnNaVzFsYm5RdVlYQndaVzVrUTJocGJHUW9ZMjl1ZEdGcGJtVnlLVHRjYmlBZ0lDQjlYRzVjYmlBZ2ZWeHVYRzRnSUhOcGVtVkpiblJsY21aaFkyVW9LU0I3WEc1Y2JpQWdJQ0JzWlhRZ1luVjBkRzl1VjJsa2RHZ2dQU0IwYUdsekxuZHBaSFJvSUM4Z2RHaHBjeTVmYm5WdFltVnlUMlpDZFhSMGIyNXpPMXh1SUNBZ0lHeGxkQ0JpZFhSMGIyNUlaV2xuYUhRZ1BTQjBhR2x6TG1obGFXZG9kRHRjYmx4dUlDQWdJR1p2Y2lBb2JHVjBJR2s5TUR0cFBIUm9hWE11WDI1MWJXSmxjazltUW5WMGRHOXVjenRwS3lzcElIdGNiaUFnSUNBZ0lIUm9hWE11WW5WMGRHOXVjMXRwWFM1eVpYTnBlbVVvWW5WMGRHOXVWMmxrZEdnc1luVjBkRzl1U0dWcFoyaDBLVHRjYmlBZ0lDQjlYRzVjYmlBZ2ZWeHVYRzRnSUdOdmJHOXlTVzUwWlhKbVlXTmxLQ2tnZTF4dUlDQWdJR1p2Y2lBb2JHVjBJR2s5TUR0cFBIUm9hWE11WDI1MWJXSmxjazltUW5WMGRHOXVjenRwS3lzcElIdGNiaUFnSUNBZ0lIUm9hWE11WW5WMGRHOXVjMXRwWFM1amIyeHZjbk1nUFNCMGFHbHpMbU52Ykc5eWN6dGNiaUFnSUNBZ0lIUm9hWE11WW5WMGRHOXVjMXRwWFM1eVpXNWtaWElvS1R0Y2JpQWdJQ0I5WEc0Z0lIMWNibHh1SUNCMWNHUmhkR1VvYVc1a1pYZ3BJSHRjYmlBZ0lDQnBaaUFvZEdocGN5NWlkWFIwYjI1elcybHVaR1Y0WFM1emRHRjBaU2tnZTF4dUlDQWdJQ0FnZEdocGN5NXpaV3hsWTNRb2FXNWtaWGdwTzF4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQjBhR2x6TG1SbGMyVnNaV04wS0NrN1hHNGdJQ0FnZlZ4dUlDQXZMeUFnZEdocGN5NXlaVzVrWlhJb0tUdGNiaUFnZlZ4dVhHNGdJSEpsYm1SbGNpZ3BJSHRjYmlBZ0lDQm1iM0lnS0d4bGRDQnBQVEE3YVR4MGFHbHpMbUoxZEhSdmJuTXViR1Z1WjNSb08ya3JLeWtnZTF4dUlDQWdJQ0FnYVdZZ0tHazlQVDEwYUdsekxtRmpkR2wyWlNrZ2UxeHVJQ0FnSUNBZ0lDQjBhR2x6TG1KMWRIUnZibk5iYVYwdWRIVnliazl1S0daaGJITmxLVHRjYmlBZ0lDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdVluVjBkRzl1YzF0cFhTNTBkWEp1VDJabUtHWmhiSE5sS1R0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lIMWNibHh1SUNBdktpcGNiaUFnVTJWc1pXTjBJRzl1WlNCaWRYUjBiMjRnWVc1a0lHUmxjMlZzWldOMElHRnNiQ0J2ZEdobGNpQmlkWFIwYjI1ekxseHVJQ0JBY0dGeVlXMGdhVzVrWlhnZ2UyNTFiV0psY24wZ1ZHaGxJR2x1WkdWNElHOW1JSFJvWlNCaWRYUjBiMjRnZEc4Z2MyVnNaV04wWEc0Z0lDb3ZYRzRnSUhObGJHVmpkQ2hwYm1SbGVDa2dlMXh1SUNBZ0lHbG1JQ2hwYm1SbGVENDlNQ0FtSmlCcGJtUmxlQ0E4SUhSb2FYTXVZblYwZEc5dWN5NXNaVzVuZEdncElIdGNiaUFnSUNBZ0lIUm9hWE11WVdOMGFYWmxJRDBnYVc1a1pYZzdYRzRnSUNBZ0lDQjBhR2x6TG1WdGFYUW9KMk5vWVc1blpTY3NkR2hwY3k1aFkzUnBkbVVwTzF4dUlDQWdJQ0FnZEdocGN5NXlaVzVrWlhJb0tUdGNiaUFnSUNCOVhHNGdJSDFjYmx4dUlDQXZLaXBjYmlBZ1JHVnpaV3hsWTNRZ1lXeHNJR0oxZEhSdmJuTXVYRzRnSUNvdlhHNGdJR1JsYzJWc1pXTjBLQ2tnZTF4dUlDQWdJSFJvYVhNdVlXTjBhWFpsSUQwZ0xURTdYRzRnSUNBZ2RHaHBjeTVsYldsMEtDZGphR0Z1WjJVbkxIUm9hWE11WVdOMGFYWmxLVHRjYmlBZ0lDQjBhR2x6TG5KbGJtUmxjaWdwTzF4dUlDQjlYRzVjYmlBZ1oyVjBJRzUxYldKbGNrOW1RblYwZEc5dWN5Z3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVmYm5WdFltVnlUMlpDZFhSMGIyNXpPMXh1SUNCOVhHNWNiaUFnTHlvcVhHNGdJQ0FxSUZWd1pHRjBaU0JvYjNjZ2JXRnVlU0JpZFhSMGIyNXpJR0Z5WlNCcGJpQjBhR1VnYVc1MFpYSm1ZV05sWEc0Z0lDQXFJRUJ3WVhKaGJTQWdlMjUxYldKbGNuMGdZblYwZEc5dWN5QkliM2NnYldGdWVTQmlkWFIwYjI1eklHRnlaU0JwYmlCMGFHVWdhVzUwWlhKbVlXTmxYRzRnSUNBcUwxeHVJQ0J6WlhRZ2JuVnRZbVZ5VDJaQ2RYUjBiMjV6S0dKMWRIUnZibk1wSUh0Y2JpQWdJQ0IwYUdsekxsOXVkVzFpWlhKUFprSjFkSFJ2Ym5NZ1BTQmlkWFIwYjI1ek8xeHVJQ0FnSUdadmNpQW9iR1YwSUdrOU1EdHBQSFJvYVhNdVluVjBkRzl1Y3k1c1pXNW5kR2c3YVNzcktTQjdYRzRnSUNBZ0lDQjBhR2x6TG1KMWRIUnZibk5iYVYwdVpHVnpkSEp2ZVNncE8xeHVJQ0FnSUgxY2JpQWdJQ0IwYUdsekxtSjFkSFJ2Ym5NZ1BTQmJYVHRjYmlBZ0x5OGdJR1p2Y2lBb2JHVjBJR2s5TUR0cFBIUm9hWE11WW5WMGRHOXVjeTVzWlc1bmRHZzdhU3NyS1NCN1hHNGdJQzh2SUNBZ0lIUm9hWE11WW5WMGRHOXVjMXRwWFM1a1pYTjBjbTk1S0NrN1hHNGdJQzh2SUNCOVhHNGdJQ0FnZEdocGN5NWxiWEIwZVNncE8xeHVJQ0FnSUhSb2FYTXVZblZwYkdSSmJuUmxjbVpoWTJVb0tUdGNiaUFnZlZ4dVhHNTlYRzVjYmx4dVhHNHZMeUJYUlVKUVFVTkxJRVpQVDFSRlVpQXZMMXh1THk4Z0xpOStMMnB6YUdsdWRDMXNiMkZrWlhJaExpOXNhV0l2YVc1MFpYSm1ZV05sY3k5eVlXUnBiMkoxZEhSdmJpNXFjeUlzSWlkMWMyVWdjM1J5YVdOMEp6dGNibHh1YkdWMElFbHVkR1Z5Wm1GalpTQTlJSEpsY1hWcGNtVW9KeTR1TDJOdmNtVXZhVzUwWlhKbVlXTmxKeWs3WEc1c1pYUWdVM1JsY0NBOUlISmxjWFZwY21Vb0p5NHVMMjF2WkdWc2N5OXpkR1Z3SnlrN1hHNXNaWFFnYldGMGFDQTlJSEpsY1hWcGNtVW9KeTR1TDNWMGFXd3ZiV0YwYUNjcE8xeHVYRzR2S2lwY2Jpb2dUblZ0WW1WeVhHNHFYRzRxSUVCa1pYTmpjbWx3ZEdsdmJpQk9kVzFpWlhJZ2FXNTBaWEptWVdObElIZG9hV05vSUdseklHTnZiblJ5YjJ4c1lXSnNaU0JpZVNCa2NtRm5aMmx1WnlCdmNpQjBlWEJwYm1jdVhHNHFYRzRxSUVCa1pXMXZJRHh6Y0dGdUlHNWxlSFZ6TFhWcFBWd2liblZ0WW1WeVhDSStQQzl6Y0dGdVBseHVLbHh1S2lCQVpYaGhiWEJzWlZ4dUtpQjJZWElnYm5WdFltVnlJRDBnYm1WM0lFNWxlSFZ6TGs1MWJXSmxjaWduSTNSaGNtZGxkQ2NwWEc0cVhHNHFJRUJsZUdGdGNHeGxYRzRxSUhaaGNpQnVkVzFpWlhJZ1BTQnVaWGNnVG1WNGRYTXVUblZ0WW1WeUtDY2pkR0Z5WjJWMEp5eDdYRzRxSUNBZ0ozTnBlbVVuT2lCYk5qQXNNekJkTEZ4dUtpQWdJQ2QyWVd4MVpTYzZJREFzWEc0cUlDQWdKMjFwYmljNklEQXNYRzRxSUNBZ0oyMWhlQ2M2SURJd01EQXdMRnh1S2lBZ0lDZHpkR1Z3SnpvZ01WeHVLaUI5S1Z4dUtseHVLaUJBYjNWMGNIVjBYRzRxSUdOb1lXNW5aVnh1S2lCR2FYSmxjeUJoYm5rZ2RHbHRaU0IwYUdVZ2FXNTBaWEptWVdObEozTWdkbUZzZFdVZ1kyaGhibWRsY3k0Z1BHSnlQbHh1S2lCVWFHVWdaWFpsYm5RZ1pHRjBZU0JwY3lCMGFHVWdiblZ0WW1WeUlIWmhiSFZsSUc5bUlIUm9aU0JwYm5SbGNtWmhZMlV1WEc0cVhHNHFJRUJ2ZFhSd2RYUmxlR0Z0Y0d4bFhHNHFJRzUxYldKbGNpNXZiaWduWTJoaGJtZGxKeXhtZFc1amRHbHZiaWgyS1NCN1hHNHFJQ0FnWTI5dWMyOXNaUzVzYjJjb2RpazdYRzRxSUgwcFhHNHFYRzRxWEc0cUwxeHVYRzVjYm1WNGNHOXlkQ0JrWldaaGRXeDBJR05zWVhOeklFNTFiV0psY2lCbGVIUmxibVJ6SUVsdWRHVnlabUZqWlNCN1hHNWNiaUFnWTI5dWMzUnlkV04wYjNJb0tTQjdYRzVjYmlBZ0lDQnNaWFFnYjNCMGFXOXVjeUE5SUZzbmRtRnNkV1VuWFR0Y2JseHVJQ0FnSUd4bGRDQmtaV1poZFd4MGN5QTlJSHRjYmlBZ0lDQWdJQ2R6YVhwbEp6b2dXell3TERNd1hTeGNiaUFnSUNBZ0lDZDJZV3gxWlNjNklEQXNYRzRnSUNBZ0lDQW5iV2x1SnpvZ01DeGNiaUFnSUNBZ0lDZHRZWGduT2lBeU1EQXdNQ3hjYmlBZ0lDQWdJQ2R6ZEdWd0p6b2dNVnh1SUNBZ0lIMDdYRzVjYmlBZ0lDQnpkWEJsY2loaGNtZDFiV1Z1ZEhNc2IzQjBhVzl1Y3l4a1pXWmhkV3gwY3lrN1hHNWNiaUFnSUNCMGFHbHpMbDkyWVd4MVpTQTlJRzVsZHlCVGRHVndLSFJvYVhNdWMyVjBkR2x1WjNNdWJXbHVMSFJvYVhNdWMyVjBkR2x1WjNNdWJXRjRMSFJvYVhNdWMyVjBkR2x1WjNNdWMzUmxjQ3gwYUdsekxuTmxkSFJwYm1kekxuWmhiSFZsS1R0Y2JseHVJQ0FnSUM4cVhHNGdJQ0FnUkdWbVlYVnNkRG9nTWk0Z1NHOTNJRzFoYm5rZ1pHVmphVzFoYkNCd2JHRmpaWE1nZEc4Z1kyeHBjQ0IwYUdVZ2JuVnRZbVZ5SjNNZ2RtbHpkV0ZzSUhKbGJtUmxjbWx1WnlCMGJ5NGdWR2hwY3lCa2IyVnpJRzV2ZENCaFptWmxZM1FnYm5WdFltVnlKM01nWVdOMGRXRnNJSFpoYkhWbElHOTFkSEIxZENBdExTQm1iM0lnZEdoaGRDd2djMlYwSUhSb1pTQnpkR1Z3SUhCeWIzQmxjblI1SUhSdklDNHdNU3dnTGpFc0lHOXlJREV1WEc0Z0lDQWdRSFI1Y0dVZ2UyNTFiV0psY24xY2JpQWdJQ0JBWlhoaGJYQnNaU0J1ZFcxaVpYSXVaR1ZqYVcxaGJGQnNZV05sY3lBOUlESTdYRzRnSUNBZ0tpOWNiaUFnSUNCMGFHbHpMbVJsWTJsdFlXeFFiR0ZqWlhNZ1BTQXlPMXh1SUNBZ0lIUm9hWE11WVdOMGRXRnNJRDBnTUR0Y2JseHVJQ0FnSUhSb2FYTXViV0Y0SUQwZ2RHaHBjeTVmZG1Gc2RXVXViV0Y0TzF4dVhHNGdJQ0FnZEdocGN5NXRhVzRnUFNCMGFHbHpMbDkyWVd4MVpTNXRhVzQ3WEc1Y2JpQWdJQ0IwYUdsekxuTjBaWEFnUFNCMGFHbHpMbDkyWVd4MVpTNXpkR1Z3TzF4dVhHNGdJQ0FnZEdocGN5NXBibWwwS0NrN1hHNGdJQ0FnZEdocGN5NXlaVzVrWlhJb0tUdGNibHh1SUNCOVhHNWNiaUFnWW5WcGJHUkdjbUZ0WlNncElIdGNiaUFnSUNCMGFHbHpMbVZzWlcxbGJuUWdQU0JrYjJOMWJXVnVkQzVqY21WaGRHVkZiR1Z0Wlc1MEtDZHBibkIxZENjcE8xeHVJQ0FnSUhSb2FYTXVaV3hsYldWdWRDNTBlWEJsSUQwZ0ozUmxlSFFuTzF4dVhHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExtRmtaRVYyWlc1MFRHbHpkR1Z1WlhJb0oySnNkWEluTENCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUZ4MElDQjBhR2x6TG1Wc1pXMWxiblF1YzNSNWJHVXVZbUZqYTJkeWIzVnVaRU52Ykc5eUlEMGdkR2hwY3k1amIyeHZjbk11Wm1sc2JEdGNiaUFnWEhRZ0lIUm9hWE11Wld4bGJXVnVkQzV6ZEhsc1pTNWpiMnh2Y2lBOUlIUm9hWE11WTI5c2IzSnpMbVJoY21zN1hHNGdJRngwSUNCcFppQW9kR2hwY3k1bGJHVnRaVzUwTG5aaGJIVmxJQ0U5UFNCMGFHbHpMblpoYkhWbEtTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWRtRnNkV1VnUFNCd1lYSnpaVVpzYjJGMEtIUm9hWE11Wld4bGJXVnVkQzUyWVd4MVpTazdYRzRnSUNBZ0lDQWdJSFJvYVhNdWNtVnVaR1Z5S0NrN1hHNGdJRngwSUNCOVhHNGdJRngwZlM1aWFXNWtLSFJvYVhNcEtUdGNibHh1WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG1Ga1pFVjJaVzUwVEdsemRHVnVaWElvSjJ0bGVXUnZkMjRuTENCbWRXNWpkR2x2YmlBb1pTa2dlMXh1SUNCY2RDQWdhV1lnS0dVdWQyaHBZMmdnUENBME9DQjhmQ0JsTG5kb2FXTm9JRDRnTlRjcElIdGNiaUFnWEhRZ0lGeDBhV1lnS0dVdWQyaHBZMmdnSVQwOUlERTRPU0FtSmlCbExuZG9hV05vSUNFOVBTQXhPVEFnSmlZZ1pTNTNhR2xqYUNBaFBUMGdPQ2tnZTF4dUlDQmNkQ0FnWEhSY2RHVXVjSEpsZG1WdWRFUmxabUYxYkhRb0tUdGNiaUFnWEhRZ0lGeDBmVnh1SUNCY2RDQWdmVnh1SUNCY2RDQWdhV1lnS0dVdWQyaHBZMmc5UFQweE15a2dlMXh1SUNCY2RDQWdYSFIwYUdsekxtVnNaVzFsYm5RdVlteDFjaWdwTzF4dUlDQWdJQ0FnSUNCMGFHbHpMblpoYkhWbElEMGdkR2hwY3k1bGJHVnRaVzUwTG5aaGJIVmxPMXh1SUNBZ0lDQWdJQ0IwYUdsekxtVnRhWFFvSjJOb1lXNW5aU2NzZEdocGN5NTJZV3gxWlNrN1hHNGdJQ0FnSUNBZ0lIUm9hWE11Y21WdVpHVnlLQ2s3WEc0Z0lGeDBJQ0I5WEc0Z0lGeDBmUzVpYVc1a0tIUm9hWE1wS1R0Y2JseHVJQ0FnSUhSb2FYTXVjR0Z5Wlc1MExtRndjR1Z1WkVOb2FXeGtLSFJvYVhNdVpXeGxiV1Z1ZENrN1hHNWNiaUFnZlZ4dVhHNGdJSE5wZW1WSmJuUmxjbVpoWTJVb0tTQjdYRzVjYmlBZ0lDQjBhR2x6TGw5dGFXNUVhVzFsYm5OcGIyNGdQU0JOWVhSb0xtMXBiaWgwYUdsekxuZHBaSFJvTEhSb2FYTXVhR1ZwWjJoMEtUdGNibHh1SUNBZ0lHeGxkQ0J6ZEhsc1pYTWdQU0FuZDJsa2RHZzZJQ2NnS3lCMGFHbHpMbmRwWkhSb0lDc2dKM0I0T3ljN1hHNGdJQ0FnYzNSNWJHVnpJQ3M5SUNkb1pXbG5hSFE2SUNjZ0t5QjBhR2x6TG1obGFXZG9kQ0FySUNkd2VEc25PMXh1SUNBZ0lITjBlV3hsY3lBclBTQW5ZbUZqYTJkeWIzVnVaQzFqYjJ4dmNqb2dJMlUzWlRkbE56c25PMXh1SUNBZ0lITjBlV3hsY3lBclBTQW5ZMjlzYjNJNklDTXpNek03Snp0Y2JpQWdJQ0J6ZEhsc1pYTWdLejBnSjJadmJuUXRabUZ0YVd4NU9pQmhjbWxoYkRzbk8xeHVJQ0FnSUhOMGVXeGxjeUFyUFNBblptOXVkQzEzWldsbmFIUTZJRFV3TURzbk8xeHVJQ0FnSUhOMGVXeGxjeUFyUFNBblptOXVkQzF6YVhwbE9pY2dLeUIwYUdsekxsOXRhVzVFYVcxbGJuTnBiMjR2TWlBcklDZHdlRHNuTzF4dUlDQXZMeUFnYzNSNWJHVnpJQ3M5SUNkb2FXZG9iR2xuYUhRNklDTmtNVGc3Snp0Y2JpQWdJQ0J6ZEhsc1pYTWdLejBnSjJKdmNtUmxjam9nYm05dVpUc25PMXh1SUNBZ0lITjBlV3hsY3lBclBTQW5iM1YwYkdsdVpUb2dibTl1WlRzbk8xeHVJQ0FnSUhOMGVXeGxjeUFyUFNBbmNHRmtaR2x1WnpvZ0p5dDBhR2x6TGw5dGFXNUVhVzFsYm5OcGIyNHZOQ3NuY0hnZ0p5dDBhR2x6TGw5dGFXNUVhVzFsYm5OcGIyNHZOQ3NuY0hnN0p6dGNiaUFnSUNCemRIbHNaWE1nS3owZ0oySnZlQzF6YVhwcGJtYzZJR0p2Y21SbGNpMWliM2c3Snp0Y2JpQWdJQ0J6ZEhsc1pYTWdLejBnSjNWelpYSlRaV3hsWTNRNklIUmxlSFE3Snp0Y2JpQWdJQ0J6ZEhsc1pYTWdLejBnSjIxdmVsVnpaWEpUWld4bFkzUTZJSFJsZUhRN0p6dGNiaUFnSUNCemRIbHNaWE1nS3owZ0ozZGxZbXRwZEZWelpYSlRaV3hsWTNRNklIUmxlSFE3Snp0Y2JpQWdJQ0IwYUdsekxtVnNaVzFsYm5RdWMzUjViR1V1WTNOelZHVjRkQ0FyUFNCemRIbHNaWE03WEc1Y2JpQWdJQ0F2THlCMGJ5QmhaR1FnWlhabGJuUjFZV3hzZVZ4dUlDQWdJQzh2SUhaaGNpQmpjM01nUFNBbkl5Y3JkR2hwY3k1bGJHVnRaVzUwU1VRckp6bzZjMlZzWldOMGFXOXVleUJpWVdOclozSnZkVzVrTFdOdmJHOXlPaUIwY21GdWMzQmhjbVZ1ZENCOUp6dGNibHh1SUNBZ0lIUm9hWE11Wld4bGJXVnVkQzUyWVd4MVpTQTlJSFJvYVhNdWRtRnNkV1U3WEc1Y2JpQWdmVnh1WEc0Z0lHTnZiRzl5U1c1MFpYSm1ZV05sS0NrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTVsYkdWdFpXNTBMbk4wZVd4bExtSmhZMnRuY205MWJtUkRiMnh2Y2lBOUlIUm9hWE11WTI5c2IzSnpMbVpwYkd3N1hHNGdJQ0FnSUNCMGFHbHpMbVZzWlcxbGJuUXVjM1I1YkdVdVkyOXNiM0lnUFNCMGFHbHpMbU52Ykc5eWN5NWtZWEpyTzF4dUlDQjlYRzVjYmlBZ2NtVnVaR1Z5S0NrZ2UxeHVYRzRnSUNBZ2RHaHBjeTVsYkdWdFpXNTBMblpoYkhWbElEMGdiV0YwYUM1d2NuVnVaU2gwYUdsekxuWmhiSFZsTEhSb2FYTXVaR1ZqYVcxaGJGQnNZV05sY3lrN1hHNWNiaUFnZlZ4dVhHNGdJR05zYVdOcktDa2dlMXh1SUNBZ0lIUm9hWE11YUdGelRXOTJaV1FnUFNCbVlXeHpaVHRjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1Y21WaFpFOXViSGtnUFNCMGNuVmxPMXh1WEhRZ0lIUm9hWE11WVdOMGRXRnNJRDBnZEdocGN5NTJZV3gxWlR0Y2JpQWdJQ0IwYUdsekxtbHVhWFJwWVd3Z1BTQjdJSGs2SUhSb2FYTXViVzkxYzJVdWVTQjlPMXh1SUNBZ0lIUm9hWE11WTJoaGJtZGxSbUZqZEc5eUlEMGdiV0YwYUM1cGJuWmxjblFvSUhSb2FYTXViVzkxYzJVdWVDQXZJSFJvYVhNdWQybGtkR2dnS1R0Y2JpQWdJQ0JqYjI1emIyeGxMbXh2WnloMGFHbHpMbU5vWVc1blpVWmhZM1J2Y2lrN1hHNGdJSDFjYmx4dUlDQnRiM1psS0NrZ2UxeHVJQ0FnSUhSb2FYTXVhR0Z6VFc5MlpXUWdQU0IwY25WbE8xeHVJQ0FnSUdsbUlDaDBhR2x6TG1Oc2FXTnJaV1FwSUh0Y2JseHVJQ0FnSUNBZ2JHVjBJRzVsZDNaaGJIVmxJRDBnZEdocGN5NWhZM1IxWVd3Z0xTQW9kR2hwY3k1dGIzVnpaUzU1SUMwZ2RHaHBjeTVwYm1sMGFXRnNMbmtwSUNvZ0tDQnRZWFJvTG1Oc2FYQW9JSFJvYVhNdWJXRjRMWFJvYVhNdWJXbHVMQ0F3TENBeE1EQXdJQ2tnTHlBeU1EQWdLU0FxSUUxaGRHZ3VjRzkzS0hSb2FYTXVZMmhoYm1kbFJtRmpkRzl5TERJcE8xeHVJQ0FnSUNBZ2RHaHBjeTUyWVd4MVpTQTlJRzVsZDNaaGJIVmxPMXh1WEc0Z0lGeDBYSFIwYUdsekxuSmxibVJsY2lncE8xeHVJQ0FnSUNBZ2FXWWdLSFJvYVhNdVgzWmhiSFZsTG1Ob1lXNW5aV1FwSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTVsYldsMEtDZGphR0Z1WjJVbkxIUm9hWE11ZG1Gc2RXVXBPMXh1SUNBZ0lDQWdmVnh1WEc0Z0lGeDBmVnh1SUNCOVhHNWNiaUFnY21Wc1pXRnpaU2dwSUh0Y2JpQWdJQ0JwWmlBb0lYUm9hWE11YUdGelRXOTJaV1FwSUh0Y2JpQWdJQ0FnSUhSb2FYTXVaV3hsYldWdWRDNXlaV0ZrVDI1c2VTQTlJR1poYkhObE8xeHVJQ0JjZEZ4MGRHaHBjeTVsYkdWdFpXNTBMbVp2WTNWektDazdYRzRnSUZ4MFhIUjBhR2x6TG1Wc1pXMWxiblF1YzJWMFUyVnNaV04wYVc5dVVtRnVaMlVvTUN3Z2RHaHBjeTVsYkdWdFpXNTBMblpoYkhWbExteGxibWQwYUNrN1hHNGdJRngwWEhSMGFHbHpMbVZzWlcxbGJuUXVjM1I1YkdVdVltRmphMmR5YjNWdVpFTnZiRzl5SUQwZ2RHaHBjeTVqYjJ4dmNuTXVZV05qWlc1ME8xeHVJQ0JjZEZ4MGRHaHBjeTVsYkdWdFpXNTBMbk4wZVd4bExtTnZiRzl5SUQwZ2RHaHBjeTVqYjJ4dmNuTXViR2xuYUhRN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJR1J2WTNWdFpXNTBMbUp2WkhrdVptOWpkWE1vS1R0Y2JpQWdJQ0I5WEc0Z0lIMWNibHh1SUNBdktpcGNiaUFnUTI5dWJtVmpkQ0IwYUdseklHNTFiV0psY2lCcGJuUmxjbVpoWTJVZ2RHOGdZU0JrYVdGc0lHOXlJSE5zYVdSbGNseHVJQ0JBY0dGeVlXMGdlMGx1ZEdWeVptRmpaWDBnWld4bGJXVnVkQ0JGYkdWdFpXNTBJSFJ2SUdOdmJtNWxZM1FnZEc4dVhHNGdJRUJsZUdGdGNHeGxJRzUxYldKbGNpNXNhVzVyS0hOc2FXUmxjaWxjYmlBZ0tpOWNiaUFnYkdsdWF5aGtaWE4wYVc1aGRHbHZiaWtnZTF4dUlDQWdJSFJvYVhNdWJXbHVJRDBnWkdWemRHbHVZWFJwYjI0dWJXbHVPMXh1SUNBZ0lIUm9hWE11YldGNElEMGdaR1Z6ZEdsdVlYUnBiMjR1YldGNE8xeHVJQ0FnSUhSb2FYTXVjM1JsY0NBOUlHUmxjM1JwYm1GMGFXOXVMbk4wWlhBN1hHNGdJQ0FnWkdWemRHbHVZWFJwYjI0dWIyNG9KMk5vWVc1blpTY3NLSFlwSUQwK0lIdGNiaUFnSUNBZ0lIUm9hWE11Y0dGemMybDJaVlZ3WkdGMFpTaDJLVHRjYmlBZ0lDQjlLVHRjYmlBZ0lDQjBhR2x6TG05dUtDZGphR0Z1WjJVbkxDaDJLU0E5UGlCN1hHNGdJQ0FnSUNCa1pYTjBhVzVoZEdsdmJpNTJZV3gxWlNBOUlIWTdYRzRnSUNBZ2ZTazdYRzRnSUNBZ2RHaHBjeTUyWVd4MVpTQTlJR1JsYzNScGJtRjBhVzl1TG5aaGJIVmxPMXh1SUNBdktpQWdjbVYwZFhKdUlIdGNiaUFnSUNBZ0lHeHBjM1JsYm1WeU1Ub2diR2x6ZEdWdVpYSXhMRnh1SUNBZ0lDQWdiR2x6ZEdWdVpYSXlPaUJzYVhOMFpXNWxjaklzWEc0Z0lDQWdJQ0JrWlhOMGNtOTVPaUFvS1NBOVBpQjdYRzRnSUNBZ0lDQWdJR3hwYzNSbGJtVnlNUzV5WlcxdmRtVW9LU0FvYjNJZ2MybHRhV3hoY2lsY2JpQWdJQ0FnSUNBZ2JHbHpkR1Z1WlhJeUxuSmxiVzkyWlNncElDaHZjaUJ6YVcxcGJHRnlLVnh1SUNBZ0lDQWdmVnh1SUNBZ0lIMGdLaTljYmlBZ2ZWeHVYRzRnSUhCaGMzTnBkbVZWY0dSaGRHVW9kaWtnZTF4dUlDQWdJSFJvYVhNdVgzWmhiSFZsTG5Wd1pHRjBaU2gyS1R0Y2JpQWdJQ0IwYUdsekxuSmxibVJsY2lncE8xeHVJQ0I5WEc1Y2JpQWdMeW9xWEc0Z0lGUm9aU0JwYm5SbGNtWmhZMlVuY3lCamRYSnlaVzUwSUhaaGJIVmxMaUJKWmlCelpYUWdiV0Z1ZFdGc2JIa3NJSGRwYkd3Z2RYQmtZWFJsSUhSb1pTQnBiblJsY21aaFkyVWdZVzVrSUhSeWFXZG5aWElnZEdobElHOTFkSEIxZENCbGRtVnVkQzVjYmlBZ1FIUjVjR1VnZTI1MWJXSmxjbjFjYmlBZ1FHVjRZVzF3YkdVZ2JuVnRZbVZ5TG5aaGJIVmxJRDBnTVRBN1hHNGdJQ292WEc0Z0lHZGxkQ0IyWVd4MVpTZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVmZG1Gc2RXVXVkbUZzZFdVN1hHNGdJSDFjYmlBZ2MyVjBJSFpoYkhWbEtIWXBJSHRjYmlBZ0lDQjBhR2x6TGw5MllXeDFaUzUxY0dSaGRHVW9kaWs3WEc0Z0lDQWdkR2hwY3k1bGJXbDBLQ2RqYUdGdVoyVW5MSFJvYVhNdWRtRnNkV1VwTzF4dUlDQWdJSFJvYVhNdWNtVnVaR1Z5S0NrN1hHNGdJSDFjYmx4dUlDQXZLaXBjYmlBZ1RHOTNaWElnYkdsdGFYUWdiMllnZEdobElHNTFiV0psY2lkeklHOTFkSEIxZENCeVlXNW5aVnh1SUNCQWRIbHdaU0I3Ym5WdFltVnlmVnh1SUNCQVpYaGhiWEJzWlNCdWRXMWlaWEl1YldsdUlEMGdNVEF3TUR0Y2JpQWdLaTljYmlBZ1oyVjBJRzFwYmlncElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWZkbUZzZFdVdWJXbHVPMXh1SUNCOVhHNGdJSE5sZENCdGFXNG9kaWtnZTF4dUlDQWdJSFJvYVhNdVgzWmhiSFZsTG0xcGJpQTlJSFk3WEc0Z0lIMWNibHh1SUNBdktpcGNiaUFnVlhCd1pYSWdiR2x0YVhRZ2IyWWdkR2hsSUc1MWJXSmxjaWR6SUc5MWRIQjFkQ0J5WVc1blpWeHVJQ0JBZEhsd1pTQjdiblZ0WW1WeWZWeHVJQ0JBWlhoaGJYQnNaU0J1ZFcxaVpYSXViV0Y0SUQwZ01UQXdNRHRjYmlBZ0tpOWNiaUFnWjJWMElHMWhlQ2dwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1ZmRtRnNkV1V1YldGNE8xeHVJQ0I5WEc0Z0lITmxkQ0J0WVhnb2Rpa2dlMXh1SUNBZ0lIUm9hWE11WDNaaGJIVmxMbTFoZUNBOUlIWTdYRzRnSUgxY2JseHVJQ0F2S2lwY2JpQWdWR2hsSUdsdVkzSmxiV1Z1ZENCMGFHRjBJSFJvWlNCdWRXMWlaWEluY3lCMllXeDFaU0JqYUdGdVoyVnpJR0o1TGx4dUlDQkFkSGx3WlNCN2JuVnRZbVZ5ZlZ4dUlDQkFaWGhoYlhCc1pTQnVkVzFpWlhJdWMzUmxjQ0E5SURVN1hHNGdJQ292WEc0Z0lHZGxkQ0J6ZEdWd0tDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbDkyWVd4MVpTNXpkR1Z3TzF4dUlDQjlYRzRnSUhObGRDQnpkR1Z3S0hZcElIdGNiaUFnSUNCMGFHbHpMbDkyWVd4MVpTNXpkR1Z3SUQwZ2RqdGNiaUFnZlZ4dVhHNTlYRzVjYmx4dVhHNHZMeUJYUlVKUVFVTkxJRVpQVDFSRlVpQXZMMXh1THk4Z0xpOStMMnB6YUdsdWRDMXNiMkZrWlhJaExpOXNhV0l2YVc1MFpYSm1ZV05sY3k5dWRXMWlaWEl1YW5NaUxDSW5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JteGxkQ0JKYm5SbGNtWmhZMlVnUFNCeVpYRjFhWEpsS0NjdUxpOWpiM0psTDJsdWRHVnlabUZqWlNjcE8xeHVYRzR2S2lwY2Jpb2dVMlZzWldOMFhHNHFYRzRxSUVCa1pYTmpjbWx3ZEdsdmJpQkVjbTl3Wkc5M2JpQnRaVzUxWEc0cVhHNHFJRUJrWlcxdklEeHpjR0Z1SUc1bGVIVnpMWFZwUFZ3aWMyVnNaV04wWENJK1BDOXpjR0Z1UGx4dUtseHVLaUJBWlhoaGJYQnNaVnh1S2lCMllYSWdjMlZzWldOMElEMGdibVYzSUU1bGVIVnpMbE5sYkdWamRDZ25JM1JoY21kbGRDY3BYRzRxWEc0cUlFQmxlR0Z0Y0d4bFhHNHFJSFpoY2lCelpXeGxZM1FnUFNCdVpYY2dUbVY0ZFhNdVUyVnNaV04wS0NjamRHRnlaMlYwSnl4N1hHNHFJQ0FnSjNOcGVtVW5PaUJiTVRBd0xETXdYU3hjYmlvZ0lDQW5iM0IwYVc5dWN5YzZJRnNuWkdWbVlYVnNkQ2NzSjI5d2RHbHZibk1uWFZ4dUtpQjlLVnh1S2x4dUtpQkFiM1YwY0hWMFhHNHFJR05vWVc1blpWeHVLaUJHYVhKbGN5QmhibmtnZEdsdFpTQjBhR1VnYVc1MFpYSm1ZV05sSjNNZ2RtRnNkV1VnWTJoaGJtZGxjeTRnUEdKeVBseHVLaUJVYUdVZ1pYWmxiblFnWkdGMFlTQnBjeUJoYmlCdlltcGxZM1FnWTI5dWRHRnBibWx1WnlCMGFHVWdkR1Y0ZENCMllXeDFaU0J2WmlCMGFHVWdjMlZzWldOMFpXUWdiM0IwYVc5dUxDQmhjeUIzWld4c0lHRnpJSFJvWlNCdWRXMWxjbWxqSUdsdVpHVjRJRzltSUhSb1pTQnpaV3hsWTNScGIyNHVYRzRxWEc0cUlFQnZkWFJ3ZFhSbGVHRnRjR3hsWEc0cUlITmxiR1ZqZEM1dmJpZ25ZMmhoYm1kbEp5eG1kVzVqZEdsdmJpaDJLU0I3WEc0cUlDQWdZMjl1YzI5c1pTNXNiMmNvZGlrN1hHNHFJSDBwWEc0cVhHNHFYRzRxTDF4dVhHNWNibVY0Y0c5eWRDQmtaV1poZFd4MElHTnNZWE56SUZObGJHVmpkQ0JsZUhSbGJtUnpJRWx1ZEdWeVptRmpaU0I3WEc1Y2JpQWdZMjl1YzNSeWRXTjBiM0lvS1NCN1hHNWNiaUFnSUNCc1pYUWdiM0IwYVc5dWN5QTlJRnNuZG1Gc2RXVW5YVHRjYmx4dUlDQWdJR3hsZENCa1pXWmhkV3gwY3lBOUlIdGNiaUFnSUNBZ0lDQW5jMmw2WlNjNklGc3hNREFzTXpCZExGeHVJQ0FnSUNBZ0lDZHZjSFJwYjI1ekp6b2dXeWRrWldaaGRXeDBKeXduYjNCMGFXOXVjeWRkWEc0Z0lDQWdmVHRjYmx4dUlDQWdJSE4xY0dWeUtHRnlaM1Z0Wlc1MGN5eHZjSFJwYjI1ekxHUmxabUYxYkhSektUdGNibHh1SUNBZ0lIUm9hWE11WDNObGJHVmpkR1ZrU1c1a1pYZ2dQU0F0TVR0Y2JpQWdJQ0IwYUdsekxsOTJZV3gxWlNBOUlHWmhiSE5sTzF4dVhHNGdJQ0FnZEdocGN5NWZiM0IwYVc5dWN5QTlJSFJvYVhNdWMyVjBkR2x1WjNNdWIzQjBhVzl1Y3p0Y2JseHVJQ0FnSUhSb2FYTXVhVzVwZENncE8xeHVJQ0FnSUhSb2FYTXVjbVZ1WkdWeUtDazdYRzVjYmlBZ2ZWeHVYRzRnSUdKMWFXeGtSbkpoYldVb0tTQjdYRzRnSUNBZ2RHaHBjeTVsYkdWdFpXNTBJRDBnWkc5amRXMWxiblF1WTNKbFlYUmxSV3hsYldWdWRDZ25jMlZzWldOMEp5azdYRzRnSUNBZ2RHaHBjeTVsYkdWdFpXNTBMbk4wZVd4bExtWnZiblJUYVhwbElEMGdkR2hwY3k1b1pXbG5hSFF2TWlzbmNIZ25PMXh1SUNBZ0lIUm9hWE11Wld4bGJXVnVkQzV6ZEhsc1pTNXZkWFJzYVc1bElEMGdKMjV2Ym1Vbk8xeHVJQ0FnSUhSb2FYTXVaV3hsYldWdWRDNXpkSGxzWlM1b2FXZG9iR2xuYUhRZ1BTQW5ibTl1WlNjN1hHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExuTjBlV3hsTG5kcFpIUm9JRDBnZEdocGN5NTNhV1IwYUNzbmNIZ25PMXh1SUNBZ0lIUm9hWE11Wld4bGJXVnVkQzV6ZEhsc1pTNW9aV2xuYUhRZ1BTQjBhR2x6TG1obGFXZG9kQ3NuY0hnbk8xeHVYRzRnSUNBZ2RHaHBjeTVpYjNWdVpGSmxibVJsY2lBOUlIUm9hWE11Y21WdVpHVnlMbUpwYm1Rb2RHaHBjeWs3WEc1Y2JpQWdJQ0IwYUdsekxtVnNaVzFsYm5RdVlXUmtSWFpsYm5STWFYTjBaVzVsY2lnblkyaGhibWRsSnl3Z2RHaHBjeTVpYjNWdVpGSmxibVJsY2lrN1hHNWNiaUFnSUNCMGFHbHpMbkJoY21WdWRDNWhjSEJsYm1SRGFHbHNaQ2gwYUdsekxtVnNaVzFsYm5RcE8xeHVYRzRnSUgxY2JseHVJQ0JoZEhSaFkyaE1hWE4wWlc1bGNuTW9LU0I3WEc1Y2JpQWdmVnh1WEc0Z0lHSjFhV3hrU1c1MFpYSm1ZV05sS0NrZ2UxeHVYRzRnSUNBZ2RHaHBjeTVrWldacGJtVlBjSFJwYjI1ektDazdYRzVjYmlBZ2ZWeHVYRzRnSUdOdmJHOXlTVzUwWlhKbVlXTmxLQ2tnZTF4dUlDQWdJSFJvYVhNdVpXeGxiV1Z1ZEM1emRIbHNaUzVpWVdOclozSnZkVzVrUTI5c2IzSWdQU0IwYUdsekxtTnZiRzl5Y3k1bWFXeHNPMXh1SUNBZ0lIUm9hWE11Wld4bGJXVnVkQzV6ZEhsc1pTNWpiMnh2Y2lBOUlIUm9hWE11WTI5c2IzSnpMbVJoY21zN1hHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExuTjBlV3hsTG1KdmNtUmxjaUE5SUNkemIyeHBaQ0F3Y0hnZ0p5dDBhR2x6TG1OdmJHOXljeTV0WldScGRXMU1hV2RvZER0Y2JpQWdmVnh1WEc0Z0lISmxibVJsY2lncElIdGNibHh1SUNBZ0lIUm9hWE11WDNaaGJIVmxJRDBnZEdocGN5NWxiR1Z0Wlc1MExtOXdkR2x2Ym5OYmRHaHBjeTVsYkdWdFpXNTBMbk5sYkdWamRHVmtTVzVrWlhoZExuUmxlSFE3WEc0Z0lDQWdkR2hwY3k1ZmMyVnNaV04wWldSSmJtUmxlQ0E5SUhSb2FYTXVaV3hsYldWdWRDNXpaV3hsWTNSbFpFbHVaR1Y0TzF4dUlDQWdJSFJvYVhNdVpXMXBkQ2duWTJoaGJtZGxKeXg3WEc0Z0lDQWdJQ0IyWVd4MVpUb2dkR2hwY3k1ZmRtRnNkV1VzWEc0Z0lDQWdJQ0JwYm1SbGVEb2dkR2hwY3k1ZmMyVnNaV04wWldSSmJtUmxlRnh1SUNBZ0lIMHBPMXh1WEc0Z0lIMWNibHh1SUNCamJHbGpheWdwSUh0Y2JseHVJQ0I5WEc1Y2JpQWdiVzkyWlNncElIdGNibHh1SUNCOVhHNWNiaUFnY21Wc1pXRnpaU2dwSUh0Y2JseHVJQ0I5WEc1Y2JpQWdMeW9xWEc0Z0lDQXFJRlZ3WkdGMFpTQjBhR1VnYkdsemRDQnZaaUJ2Y0hScGIyNXpMaUJVYUdseklISmxiVzkyWlhNZ1lXeHNJR1Y0YVhOMGFXNW5JRzl3ZEdsdmJuTWdZVzVrSUdOeVpXRjBaWE1nWVNCdVpYY2diR2x6ZENCdlppQnZjSFJwYjI1ekxseHVJQ0FnS2lCQWNHRnlZVzBnSUh0aGNuSmhlWDBnYjNCMGFXOXVjeUJPWlhjZ1lYSnlZWGtnYjJZZ2IzQjBhVzl1YzF4dUlDQWdLaTljYmx4dUlDQmtaV1pwYm1WUGNIUnBiMjV6S0c5d2RHbHZibk1wSUh0Y2JseHVJQ0F2S2lBZ1puVnVZM1JwYjI0Z2NtVnRiM1psVDNCMGFXOXVjeWh6Wld4bFkzUmliM2dwWEc0Z0lDQWdlMXh1SUNBZ0lDQWdJQ0IyWVhJZ2FUdGNiaUFnSUNBZ0lDQWdabTl5S0drZ1BTQnpaV3hsWTNSaWIzZ3ViM0IwYVc5dWN5NXNaVzVuZEdnZ0xTQXhJRHNnYVNBK1BTQXdJRHNnYVMwdEtWeHVJQ0FnSUNBZ0lDQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCelpXeGxZM1JpYjNndWNtVnRiM1psS0drcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZWeHVJQ0FnSUM4dmRYTnBibWNnZEdobElHWjFibU4wYVc5dU9seHVJQ0FnSUhKbGJXOTJaVTl3ZEdsdmJuTW9aRzlqZFcxbGJuUXVaMlYwUld4bGJXVnVkRUo1U1dRb1hDSnRlVk5sYkdWamRFOWlhbVZqZEZ3aUtTazdJQ292WEc1Y2JseHVJQ0FnSUdsbUlDaHZjSFJwYjI1ektTQjdYRzRnSUNBZ0lDQjBhR2x6TGw5dmNIUnBiMjV6SUQwZ2IzQjBhVzl1Y3p0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0JtYjNJb2JHVjBJR2s5ZEdocGN5NWxiR1Z0Wlc1MExtOXdkR2x2Ym5NdWJHVnVaM1JvTFRFN0lHa2dQajBnTURzZ2FTMHRLU0I3WEc0Z0lDQWdJQ0IwYUdsekxtVnNaVzFsYm5RdWNtVnRiM1psS0drcE8xeHVJQ0FnSUgxY2JseHVJQ0FnSUdadmNpaHNaWFFnYVQwd08yazhkR2hwY3k1ZmIzQjBhVzl1Y3k1c1pXNW5kR2c3YVNzcktTQjdYRzRnSUNBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1YjNCMGFXOXVjeTVoWkdRb2JtVjNJRTl3ZEdsdmJpaDBhR2x6TGw5dmNIUnBiMjV6VzJsZExDQnBLU2s3WEc0Z0lDQWdmVnh1WEc0Z0lIMWNibHh1WEc0Z0lDOHFLbHh1SUNCVWFHVWdkR1Y0ZENCdlppQjBhR1VnYjNCMGFXOXVJSFJvWVhRZ2FYTWdZM1Z5Y21WdWRHeDVJSE5sYkdWamRHVmtMaUJKWmlCelpYUXNJSGRwYkd3Z2RYQmtZWFJsSUhSb1pTQnBiblJsY21aaFkyVWdZVzVrSUhSeWFXZG5aWElnZEdobElHOTFkSEIxZENCbGRtVnVkQzVjYmlBZ1FIUjVjR1VnZTFOMGNtbHVaMzFjYmlBZ1FHVjRZVzF3YkdVZ2MyVnNaV04wTG5aaGJIVmxJRDBnWENKellYZDBiMjkwYUZ3aU8xeHVJQ0FxTDF4dUlDQm5aWFFnZG1Gc2RXVW9LU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11WDNaaGJIVmxPMXh1SUNCOVhHNGdJSE5sZENCMllXeDFaU2gyS1NCN1hHNGdJQ0FnZEdocGN5NWZkbUZzZFdVZ1BTQjJPMXh1SUNBZ0lHWnZjaWhzWlhRZ2FUMHdPMms4ZEdocGN5NWxiR1Z0Wlc1MExtOXdkR2x2Ym5NdWJHVnVaM1JvTzJrckt5a2dlMXh1SUNBZ0lDQWdhV1lnS0hZZ1BUMDlJSFJvYVhNdVpXeGxiV1Z1ZEM1dmNIUnBiMjV6VzJsZExuUmxlSFFwSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTV6Wld4bFkzUmxaRWx1WkdWNElEMGdhVHRjYmlBZ0lDQWdJQ0FnWW5KbFlXczdYRzRnSUNBZ0lDQjlYRzRnSUNBZ2ZWeHVJQ0I5WEc1Y2JseHVJQ0F2S2lwY2JpQWdWR2hsSUc1MWJXVnlhV01nYVc1a1pYZ2diMllnZEdobElHOXdkR2x2YmlCMGFHRjBJR2x6SUdOMWNuSmxiblJzZVNCelpXeGxZM1JsWkM0Z1NXWWdjMlYwTENCM2FXeHNJSFZ3WkdGMFpTQjBhR1VnYVc1MFpYSm1ZV05sSUdGdVpDQjBjbWxuWjJWeUlIUm9aU0J2ZFhSd2RYUWdaWFpsYm5RdVhHNGdJRUIwZVhCbElIdHVkVzFpWlhKOVhHNGdJRUJsZUdGdGNHeGxJSE5sYkdWamRDNXpaV3hsWTNSbFpFbHVaR1Y0SUQwZ01qdGNiaUFnS2k5Y2JpQWdaMlYwSUhObGJHVmpkR1ZrU1c1a1pYZ29LU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11WDNObGJHVmpkR1ZrU1c1a1pYZzdYRzRnSUgxY2JpQWdjMlYwSUhObGJHVmpkR1ZrU1c1a1pYZ29kaWtnZTF4dUlDQWdJSFJvYVhNdVgzTmxiR1ZqZEdWa1NXNWtaWGdnUFNCMk8xeHVJQ0FnSUhSb2FYTXVaV3hsYldWdWRDNXpaV3hsWTNSbFpFbHVaR1Y0SUQwZ2RqdGNiaUFnSUNCMGFHbHpMbkpsYm1SbGNpZ3BPMXh1SUNCOVhHNWNiaUFnWTNWemRHOXRSR1Z6ZEhKdmVTZ3BJSHRjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1Y21WdGIzWmxSWFpsYm5STWFYTjBaVzVsY2lnblkyaGhibWRsSnl3Z2RHaHBjeTVpYjNWdVpGSmxibVJsY2lrN1hHNGdJSDFjYmx4dVhHNTlYRzVjYmx4dVhHNHZMeUJYUlVKUVFVTkxJRVpQVDFSRlVpQXZMMXh1THk4Z0xpOStMMnB6YUdsdWRDMXNiMkZrWlhJaExpOXNhV0l2YVc1MFpYSm1ZV05sY3k5elpXeGxZM1F1YW5NaUxDSW5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JteGxkQ0J6ZG1jZ1BTQnlaWEYxYVhKbEtDY3VMaTkxZEdsc0wzTjJaeWNwTzF4dWJHVjBJRzFoZEdnZ1BTQnlaWEYxYVhKbEtDY3VMaTkxZEdsc0wyMWhkR2duS1R0Y2JteGxkQ0JKYm5SbGNtWmhZMlVnUFNCeVpYRjFhWEpsS0NjdUxpOWpiM0psTDJsdWRHVnlabUZqWlNjcE8xeHViR1YwSUZOMFpYQWdQU0J5WlhGMWFYSmxLQ2N1TGk5dGIyUmxiSE12YzNSbGNDY3BPMXh1YVcxd2IzSjBJQ29nWVhNZ1NXNTBaWEpoWTNScGIyNGdabkp2YlNBbkxpNHZkWFJwYkM5cGJuUmxjbUZqZEdsdmJpYzdYRzVjYmk4cUtseHVLaUJFYVdGc1hHNHFYRzRxWEc0cUlFQmtaWE5qY21sd2RHbHZiaUJFYVdGc0lIZHBkR2dnY21Ga2FXRnNJRzl5SUd4cGJtVmhjaUJwYm5SbGNtRmpkR2x2Ymk1Y2JpcGNiaW9nUUdSbGJXOGdQSE53WVc0Z2JtVjRkWE10ZFdrOVhDSmthV0ZzWENJK1BDOXpjR0Z1UGx4dUtseHVLaUJBWlhoaGJYQnNaVnh1S2lCMllYSWdaR2xoYkNBOUlHNWxkeUJPWlhoMWN5NUVhV0ZzS0NjamRHRnlaMlYwSnlsY2JpcGNiaW9nUUdWNFlXMXdiR1ZjYmlvZ2RtRnlJR1JwWVd3Z1BTQnVaWGNnVG1WNGRYTXVSR2xoYkNnbkkzUmhjbWRsZENjc2UxeHVLaUFnSUNkemFYcGxKem9nV3pjMUxEYzFYU3hjYmlvZ0lDQW5hVzUwWlhKaFkzUnBiMjRuT2lBbmNtRmthV0ZzSnl3Z0x5OGdYQ0p5WVdScFlXeGNJaXdnWENKMlpYSjBhV05oYkZ3aUxDQnZjaUJjSW1odmNtbDZiMjUwWVd4Y0lseHVLaUFnSUNkdGIyUmxKem9nSjNKbGJHRjBhWFpsSnl3Z0x5OGdYQ0poWW5OdmJIVjBaVndpSUc5eUlGd2ljbVZzWVhScGRtVmNJbHh1S2lBZ0lDZHRhVzRuT2lBd0xGeHVLaUFnSUNkdFlYZ25PaUF4TEZ4dUtpQWdJQ2R6ZEdWd0p6b2dNQ3hjYmlvZ0lDQW5kbUZzZFdVbk9pQXdYRzRxSUgwcFhHNHFYRzRxSUVCdmRYUndkWFJjYmlvZ1kyaGhibWRsWEc0cUlFWnBjbVZ6SUdGdWVTQjBhVzFsSUhSb1pTQnBiblJsY21aaFkyVW5jeUIyWVd4MVpTQmphR0Z1WjJWekxpQThZbkkrWEc0cUlGUm9aU0JsZG1WdWRDQmtZWFJoSUdseklIUm9aU0J1ZFcxaVpYSWdkbUZzZFdVZ2IyWWdkR2hsSUdsdWRHVnlabUZqWlM1Y2JpcGNiaW9nUUc5MWRIQjFkR1Y0WVcxd2JHVmNiaW9nWkdsaGJDNXZiaWduWTJoaGJtZGxKeXhtZFc1amRHbHZiaWgyS1NCN1hHNHFJQ0FnWTI5dWMyOXNaUzVzYjJjb2RpazdYRzRxSUgwcFhHNHFYRzRxSUVCMGRYUnZjbWxoYkZ4dUtpQkVhV0ZzWEc0cUlIbG5SMDE0Y1Z4dUtseHVLaTljYmx4dVpYaHdiM0owSUdSbFptRjFiSFFnWTJ4aGMzTWdSR2xoYkNCbGVIUmxibVJ6SUVsdWRHVnlabUZqWlNCN1hHNWNiaUFnWTI5dWMzUnlkV04wYjNJb0tTQjdYRzVjYmlBZ0lDQnNaWFFnYjNCMGFXOXVjeUE5SUZzbmJXbHVKeXduYldGNEp5d25kbUZzZFdVblhUdGNibHh1SUNBZ0lHeGxkQ0JrWldaaGRXeDBjeUE5SUh0Y2JpQWdJQ0FnSUNkemFYcGxKem9nV3pjMUxEYzFYU3hjYmlBZ0lDQWdJQ2RwYm5SbGNtRmpkR2x2YmljNklDZHlZV1JwWVd3bkxDQXZMeUJ5WVdScFlXd3NJSFpsY25ScFkyRnNMQ0JvYjNKcGVtOXVkR0ZzWEc0Z0lDQWdJQ0FuYlc5a1pTYzZJQ2R5Wld4aGRHbDJaU2NzSUM4dklHRmljMjlzZFhSbExDQnlaV3hoZEdsMlpWeHVJQ0FnSUNBZ0oyMXBiaWM2SURBc1hHNGdJQ0FnSUNBbmJXRjRKem9nTVN4Y2JpQWdJQ0FnSUNkemRHVndKem9nTUN4Y2JpQWdJQ0FnSUNkMllXeDFaU2M2SURCY2JpQWdJQ0I5TzF4dVhHNGdJQ0FnYzNWd1pYSW9ZWEpuZFcxbGJuUnpMRzl3ZEdsdmJuTXNaR1ZtWVhWc2RITXBPMXh1WEc0Z0lDQWdkR2hwY3k1cGJuUmxjbUZqZEdsdmJpQTlJSFJvYVhNdWMyVjBkR2x1WjNNdWFXNTBaWEpoWTNScGIyNDdYRzVjYmlBZ0lDQjBhR2x6TGw5MllXeDFaU0E5SUc1bGR5QlRkR1Z3S0hSb2FYTXVjMlYwZEdsdVozTXViV2x1TENCMGFHbHpMbk5sZEhScGJtZHpMbTFoZUN3Z2RHaHBjeTV6WlhSMGFXNW5jeTV6ZEdWd0xDQjBhR2x6TG5ObGRIUnBibWR6TG5aaGJIVmxLVHRjYmx4dUlDQWdJSFJvYVhNdWNHOXphWFJwYjI0Z1BTQnVaWGNnU1c1MFpYSmhZM1JwYjI0dVNHRnVaR3hsS0hSb2FYTXVjMlYwZEdsdVozTXViVzlrWlN4MGFHbHpMbWx1ZEdWeVlXTjBhVzl1TEZzd0xIUm9hWE11ZDJsa2RHaGRMRnQwYUdsekxtaGxhV2RvZEN3d1hTazdYRzVjYmlBZ0lDQjBhR2x6TG1sdWFYUW9LVHRjYmx4dUlDQWdJSFJvYVhNdWRtRnNkV1VnUFNCMGFHbHpMbDkyWVd4MVpTNTJZV3gxWlR0Y2JseHVJQ0FnSUhSb2FYTXVjRzl6YVhScGIyNHVkbUZzZFdVZ1BTQjBhR2x6TGw5MllXeDFaUzV1YjNKdFlXeHBlbVZrTzF4dVhHNGdJQ0FnZEdocGN5NXdjbVYyYVc5MWMwRnVaMnhsSUQwZ1ptRnNjMlU3WEc1Y2JpQWdJQ0IwYUdsekxtVnRhWFFvSjJOb1lXNW5aU2NzZEdocGN5NTJZV3gxWlNrN1hHNWNiaUFnZlZ4dVhHNGdJR0oxYVd4a1NXNTBaWEptWVdObEtDa2dlMXh1WEc0Z0lDQWdkR2hwY3k1aVlXTnJaM0p2ZFc1a0lEMGdjM1puTG1OeVpXRjBaU2duWTJseVkyeGxKeWs3WEc0Z0lDQWdkR2hwY3k1elkzSmxkeUE5SUhOMlp5NWpjbVZoZEdVb0oyTnBjbU5zWlNjcE8xeHVJQ0FnSUhSb2FYTXVhR0Z1Wkd4bElEMGdjM1puTG1OeVpXRjBaU2duY0dGMGFDY3BPMXh1SUNBZ0lIUm9hWE11YUdGdVpHeGxNaUE5SUhOMlp5NWpjbVZoZEdVb0ozQmhkR2duS1R0Y2JpQWdJQ0IwYUdsekxtaGhibVJzWlVacGJHd2dQU0J6ZG1jdVkzSmxZWFJsS0Nkd1lYUm9KeWs3WEc0Z0lDQWdkR2hwY3k1b1lXNWtiR1V5Um1sc2JDQTlJSE4yWnk1amNtVmhkR1VvSjNCaGRHZ25LVHRjYmlBZ0lDQjBhR2x6TG1oaGJtUnNaVXhwYm1VZ1BTQnpkbWN1WTNKbFlYUmxLQ2R3WVhSb0p5azdYRzVjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1WVhCd1pXNWtRMmhwYkdRb2RHaHBjeTVpWVdOclozSnZkVzVrS1R0Y2JpQWdJQ0IwYUdsekxtVnNaVzFsYm5RdVlYQndaVzVrUTJocGJHUW9kR2hwY3k1b1lXNWtiR1VwTzF4dUlDQWdJSFJvYVhNdVpXeGxiV1Z1ZEM1aGNIQmxibVJEYUdsc1pDaDBhR2x6TG1oaGJtUnNaVElwTzF4dUlDQWdJSFJvYVhNdVpXeGxiV1Z1ZEM1aGNIQmxibVJEYUdsc1pDaDBhR2x6TG1oaGJtUnNaVVpwYkd3cE8xeHVJQ0FnSUhSb2FYTXVaV3hsYldWdWRDNWhjSEJsYm1SRGFHbHNaQ2gwYUdsekxtaGhibVJzWlRKR2FXeHNLVHRjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1WVhCd1pXNWtRMmhwYkdRb2RHaHBjeTVvWVc1a2JHVk1hVzVsS1R0Y2JpQWdJQ0IwYUdsekxtVnNaVzFsYm5RdVlYQndaVzVrUTJocGJHUW9kR2hwY3k1elkzSmxkeWs3WEc1Y2JpQWdmVnh1WEc1Y2JpQWdjMmw2WlVsdWRHVnlabUZqWlNncElIdGNibHh1SUNBZ0lIUm9hWE11Y0c5emFYUnBiMjR1Y21WemFYcGxLRnN3TEhSb2FYTXVkMmxrZEdoZExGdDBhR2x6TG1obGFXZG9kQ3d3WFNrN1hHNWNiaUFnSUNCc1pYUWdZMlZ1ZEdWeUlEMGdlMXh1SUNBZ0lDQWdlRG9nZEdocGN5NTNhV1IwYUM4eUxGeHVJQ0FnSUNBZ2VUb2dkR2hwY3k1b1pXbG5hSFF2TWx4dUlDQWdJSDA3WEc1Y2JpQWdJQ0JzWlhRZ1pHbGhiV1YwWlhJZ1BTQk5ZWFJvTG0xcGJpaDBhR2x6TG5kcFpIUm9MSFJvYVhNdWFHVnBaMmgwS1R0Y2JseHVJQ0FnSUhSb2FYTXVZbUZqYTJkeWIzVnVaQzV6WlhSQmRIUnlhV0oxZEdVb0oyTjRKeXdnWTJWdWRHVnlMbmdwTzF4dUlDQWdJSFJvYVhNdVltRmphMmR5YjNWdVpDNXpaWFJCZEhSeWFXSjFkR1VvSjJONUp5d2dZMlZ1ZEdWeUxua3BPMXh1SUNBZ0lIUm9hWE11WW1GamEyZHliM1Z1WkM1elpYUkJkSFJ5YVdKMWRHVW9KM0luTENCa2FXRnRaWFJsY2k4eUxXUnBZVzFsZEdWeUx6UXdLVHRjYmx4dUlDQWdJSFJvYVhNdWMyTnlaWGN1YzJWMFFYUjBjbWxpZFhSbEtDZGplQ2NzSUdObGJuUmxjaTU0S1R0Y2JpQWdJQ0IwYUdsekxuTmpjbVYzTG5ObGRFRjBkSEpwWW5WMFpTZ25ZM2tuTENCalpXNTBaWEl1ZVNrN1hHNGdJQ0FnZEdocGN5NXpZM0psZHk1elpYUkJkSFJ5YVdKMWRHVW9KM0luTENCa2FXRnRaWFJsY2k4eE1pazdYRzVjYmlBZ0lDQnNaWFFnZG1Gc2RXVWdQU0IwYUdsekxuWmhiSFZsTzF4dVhHNGdJQ0FnYkdWMElHaGhibVJzWlZCdmFXNTBjeUE5SUh0Y2JpQWdJQ0FnSUhOMFlYSjBPaUJOWVhSb0xsQkpLakV1TlN4Y2JpQWdJQ0FnSUdWdVpEb2diV0YwYUM1amJHbHdLQ0J0WVhSb0xuTmpZV3hsS0haaGJIVmxMREFzTUM0MUxFMWhkR2d1VUVrcU1TNDFMRTFoZEdndVVFa3FNQzQxS1NBc0lFMWhkR2d1VUVrcU1DNDFMQ0JOWVhSb0xsQkpLakV1TlNBcFhHNGdJQ0FnZlR0Y2JpQWdJQ0JzWlhRZ2FHRnVaR3hsTWxCdmFXNTBjeUE5SUh0Y2JpQWdJQ0FnSUhOMFlYSjBPaUJOWVhSb0xsQkpLakl1TlN4Y2JpQWdJQ0FnSUdWdVpEb2diV0YwYUM1amJHbHdLQ0J0WVhSb0xuTmpZV3hsS0haaGJIVmxMREF1TlN3eExFMWhkR2d1VUVrcU1pNDFMRTFoZEdndVVFa3FNUzQxS1NBc0lFMWhkR2d1VUVrcU1TNDFMQ0JOWVhSb0xsQkpLakl1TlNBcFhHNGdJQ0FnZlR0Y2JseHVJQ0FnSUd4bGRDQm9ZVzVrYkdWUVlYUm9JRDBnYzNabkxtRnlZeWhqWlc1MFpYSXVlQ3dnWTJWdWRHVnlMbmtzSUdScFlXMWxkR1Z5THpJdFpHbGhiV1YwWlhJdk5EQXNJR2hoYm1Sc1pWQnZhVzUwY3k1emRHRnlkQ3dnYUdGdVpHeGxVRzlwYm5SekxtVnVaQ2s3WEc0Z0lDQWdiR1YwSUdoaGJtUnNaVEpRWVhSb0lEMGdjM1puTG1GeVl5aGpaVzUwWlhJdWVDd2dZMlZ1ZEdWeUxua3NJR1JwWVcxbGRHVnlMekl0WkdsaGJXVjBaWEl2TkRBc0lHaGhibVJzWlRKUWIybHVkSE11YzNSaGNuUXNJR2hoYm1Sc1pUSlFiMmx1ZEhNdVpXNWtLVHRjYmx4dUlDQWdJSFJvYVhNdWFHRnVaR3hsTG5ObGRFRjBkSEpwWW5WMFpTZ25aQ2NzYUdGdVpHeGxVR0YwYUNrN1hHNGdJQ0FnZEdocGN5NW9ZVzVrYkdVdWMyVjBRWFIwY21saWRYUmxLQ2R6ZEhKdmEyVXRkMmxrZEdnbkxDQmthV0Z0WlhSbGNpOHlNQ2s3WEc0Z0lDQWdkR2hwY3k1b1lXNWtiR1V1YzJWMFFYUjBjbWxpZFhSbEtDZG1hV3hzSnl3Z0oyNXZibVVuS1R0Y2JseHVJQ0FnSUhSb2FYTXVhR0Z1Wkd4bE1pNXpaWFJCZEhSeWFXSjFkR1VvSjJRbkxHaGhibVJzWlRKUVlYUm9LVHRjYmlBZ0lDQjBhR2x6TG1oaGJtUnNaVEl1YzJWMFFYUjBjbWxpZFhSbEtDZHpkSEp2YTJVdGQybGtkR2duTENCa2FXRnRaWFJsY2k4eU1DazdYRzRnSUNBZ2RHaHBjeTVvWVc1a2JHVXlMbk5sZEVGMGRISnBZblYwWlNnblptbHNiQ2NzSUNkdWIyNWxKeWs3WEc1Y2JpQWdJQ0JvWVc1a2JHVlFZWFJvSUNzOUlDY2dUQ0FuSzJObGJuUmxjaTU0S3ljZ0p5dGpaVzUwWlhJdWVUdGNibHh1SUNBZ0lIUm9hWE11YUdGdVpHeGxSbWxzYkM1elpYUkJkSFJ5YVdKMWRHVW9KMlFuTEdoaGJtUnNaVkJoZEdncE8xeHVJQ0FnSUhSb2FYTXVhR0Z1Wkd4bFJtbHNiQzV6WlhSQmRIUnlhV0oxZEdVb0oyWnBiR3d0YjNCaFkybDBlU2NzSUNjd0xqTW5LVHRjYmx4dUlDQWdJR2hoYm1Sc1pUSlFZWFJvSUNzOUlDY2dUQ0FuSzJObGJuUmxjaTU0S3ljZ0p5dGpaVzUwWlhJdWVUdGNibHh1SUNBZ0lIUm9hWE11YUdGdVpHeGxNa1pwYkd3dWMyVjBRWFIwY21saWRYUmxLQ2RrSnl4b1lXNWtiR1V5VUdGMGFDazdYRzRnSUNBZ2RHaHBjeTVvWVc1a2JHVXlSbWxzYkM1elpYUkJkSFJ5YVdKMWRHVW9KMlpwYkd3dGIzQmhZMmwwZVNjc0lDY3dMak1uS1R0Y2JseHVJQ0FnSUd4bGRDQmhjbU5GYm1ScGJtZEJPMXh1SUNBZ0lHbG1JQ2gyWVd4MVpTQThJREF1TlNrZ2UxeHVJQ0FnSUNBZ1lYSmpSVzVrYVc1blFTQTlJR2hoYm1Sc1pWQnZhVzUwY3k1bGJtUTdYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUdGeVkwVnVaR2x1WjBFZ1BTQm9ZVzVrYkdVeVVHOXBiblJ6TG1WdVpEdGNiaUFnSUNCOVhHNWNiaUFnSUNCc1pYUWdZWEpqUlc1a2FXNW5XQ0E5SUdObGJuUmxjaTU0SUNzZ1RXRjBhQzVqYjNNb1lYSmpSVzVrYVc1blFTa2dLaUFvWkdsaGJXVjBaWEl2TWlrN1hHNGdJQ0FnYkdWMElHRnlZMFZ1WkdsdVoxa2dQU0JqWlc1MFpYSXVlU0FySUUxaGRHZ3VjMmx1S0dGeVkwVnVaR2x1WjBFcElDb2dLR1JwWVcxbGRHVnlMeklwSUNvZ0xURTdYRzVjYmlBZ0lDQjBhR2x6TG1oaGJtUnNaVXhwYm1VdWMyVjBRWFIwY21saWRYUmxLQ2RrSnl3blRTQW5LMk5sYm5SbGNpNTRLeWNnSnl0alpXNTBaWEl1ZVNzbklFd2dKeXRoY21ORmJtUnBibWRZS3ljZ0p5dGhjbU5GYm1ScGJtZFpLVHRjYmlBZ0lDQjBhR2x6TG1oaGJtUnNaVXhwYm1VdWMyVjBRWFIwY21saWRYUmxLQ2R6ZEhKdmEyVXRkMmxrZEdnbkxDQmthV0Z0WlhSbGNpOHlNQ2s3WEc1Y2JpQWdmVnh1WEc0Z0lHTnZiRzl5U1c1MFpYSm1ZV05sS0NrZ2UxeHVJQ0FnSUhSb2FYTXVZbUZqYTJkeWIzVnVaQzV6WlhSQmRIUnlhV0oxZEdVb0oyWnBiR3duTENCMGFHbHpMbU52Ykc5eWN5NW1hV3hzS1R0Y2JpQWdJQ0IwYUdsekxuTmpjbVYzTG5ObGRFRjBkSEpwWW5WMFpTZ25abWxzYkNjc0lIUm9hWE11WTI5c2IzSnpMbUZqWTJWdWRDazdYRzRnSUNBZ2RHaHBjeTVvWVc1a2JHVXVjMlYwUVhSMGNtbGlkWFJsS0NkemRISnZhMlVuTENCMGFHbHpMbU52Ykc5eWN5NWhZMk5sYm5RcE8xeHVJQ0FnSUhSb2FYTXVhR0Z1Wkd4bE1pNXpaWFJCZEhSeWFXSjFkR1VvSjNOMGNtOXJaU2NzSUhSb2FYTXVZMjlzYjNKekxtRmpZMlZ1ZENrN1hHNGdJQ0FnZEdocGN5NW9ZVzVrYkdWR2FXeHNMbk5sZEVGMGRISnBZblYwWlNnblptbHNiQ2NzSUhSb2FYTXVZMjlzYjNKekxtRmpZMlZ1ZENrN1hHNGdJQ0FnZEdocGN5NW9ZVzVrYkdVeVJtbHNiQzV6WlhSQmRIUnlhV0oxZEdVb0oyWnBiR3duTENCMGFHbHpMbU52Ykc5eWN5NWhZMk5sYm5RcE8xeHVJQ0FnSUhSb2FYTXVhR0Z1Wkd4bFRHbHVaUzV6WlhSQmRIUnlhV0oxZEdVb0ozTjBjbTlyWlNjc0lIUm9hWE11WTI5c2IzSnpMbUZqWTJWdWRDazdYRzVjYmlBZ2ZWeHVYRzRnSUhKbGJtUmxjaWdwSUh0Y2JpQWdJQ0JzWlhRZ2RtRnNkV1VnUFNCMGFHbHpMbDkyWVd4MVpTNXViM0p0WVd4cGVtVmtPMXh1WEc0Z0lDQWdiR1YwSUdObGJuUmxjaUE5SUh0Y2JpQWdJQ0FnSUhnNklIUm9hWE11ZDJsa2RHZ3ZNaXhjYmlBZ0lDQWdJSGs2SUhSb2FYTXVhR1ZwWjJoMEx6SmNiaUFnSUNCOU8xeHVYRzRnSUNBZ2JHVjBJR1JwWVcxbGRHVnlJRDBnVFdGMGFDNXRhVzRvZEdocGN5NTNhV1IwYUN4MGFHbHpMbWhsYVdkb2RDazdYRzVjYmlBZ0lDQnNaWFFnYUdGdVpHeGxVRzlwYm5SeklEMGdlMXh1SUNBZ0lDQWdjM1JoY25RNklFMWhkR2d1VUVrcU1TNDFMRnh1SUNBZ0lDQWdaVzVrT2lCdFlYUm9MbU5zYVhBb0lHMWhkR2d1YzJOaGJHVW9kbUZzZFdVc01Dd3dMalVzVFdGMGFDNVFTU294TGpVc1RXRjBhQzVRU1Nvd0xqVXBJQ3dnVFdGMGFDNVFTU293TGpVc0lFMWhkR2d1VUVrcU1TNDFJQ2xjYmlBZ0lDQjlPMXh1SUNBZ0lHeGxkQ0JvWVc1a2JHVXlVRzlwYm5SeklEMGdlMXh1SUNBZ0lDQWdjM1JoY25RNklFMWhkR2d1VUVrZ0tqSXVOU3hjYmlBZ0lDQWdJR1Z1WkRvZ2JXRjBhQzVqYkdsd0tDQnRZWFJvTG5OallXeGxLSFpoYkhWbExEQXVOU3d4TEUxaGRHZ3VVRWtxTWk0MUxFMWhkR2d1VUVrcU1TNDFLU0FzSUUxaGRHZ3VVRWtxTVM0MUxDQk5ZWFJvTGxCSktqSXVOU0FwWEc0Z0lDQWdmVHRjYmx4dUlDQWdJR3hsZENCb1lXNWtiR1ZRWVhSb0lEMGdjM1puTG1GeVl5aGpaVzUwWlhJdWVDd2dZMlZ1ZEdWeUxua3NJR1JwWVcxbGRHVnlMekl0WkdsaGJXVjBaWEl2TkRBc0lHaGhibVJzWlZCdmFXNTBjeTV6ZEdGeWRDd2dhR0Z1Wkd4bFVHOXBiblJ6TG1WdVpDazdYRzRnSUNBZ2JHVjBJR2hoYm1Sc1pUSlFZWFJvSUQwZ2MzWm5MbUZ5WXloalpXNTBaWEl1ZUN3Z1kyVnVkR1Z5TG5rc0lHUnBZVzFsZEdWeUx6SXRaR2xoYldWMFpYSXZOREFzSUdoaGJtUnNaVEpRYjJsdWRITXVjM1JoY25Rc0lHaGhibVJzWlRKUWIybHVkSE11Wlc1a0tUdGNibHh1SUNBZ0lIUm9hWE11YUdGdVpHeGxMbk5sZEVGMGRISnBZblYwWlNnblpDY3NhR0Z1Wkd4bFVHRjBhQ2s3WEc0Z0lDQWdkR2hwY3k1b1lXNWtiR1V5TG5ObGRFRjBkSEpwWW5WMFpTZ25aQ2NzYUdGdVpHeGxNbEJoZEdncE8xeHVYRzVjYmlBZ0lDQm9ZVzVrYkdWUVlYUm9JQ3M5SUNjZ1RDQW5LMk5sYm5SbGNpNTRLeWNnSnl0alpXNTBaWEl1ZVR0Y2JseHVJQ0FnSUhSb2FYTXVhR0Z1Wkd4bFJtbHNiQzV6WlhSQmRIUnlhV0oxZEdVb0oyUW5MR2hoYm1Sc1pWQmhkR2dwTzF4dVhHNGdJQ0FnYUdGdVpHeGxNbEJoZEdnZ0t6MGdKeUJNSUNjclkyVnVkR1Z5TG5nckp5QW5LMk5sYm5SbGNpNTVPMXh1WEc0Z0lDQWdkR2hwY3k1b1lXNWtiR1V5Um1sc2JDNXpaWFJCZEhSeWFXSjFkR1VvSjJRbkxHaGhibVJzWlRKUVlYUm9LVHRjYmx4dUlDQWdJR3hsZENCaGNtTkZibVJwYm1kQk8xeHVJQ0FnSUdsbUlDaDJZV3gxWlNBOFBTQXdMalVwSUh0Y2JpQWdJQ0FnSUdGeVkwVnVaR2x1WjBFZ1BTQm9ZVzVrYkdWUWIybHVkSE11Wlc1a08xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0JoY21ORmJtUnBibWRCSUQwZ2FHRnVaR3hsTWxCdmFXNTBjeTVsYm1RN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnYkdWMElHRnlZMFZ1WkdsdVoxZ2dQU0JqWlc1MFpYSXVlQ0FySUUxaGRHZ3VZMjl6S0dGeVkwVnVaR2x1WjBFcElDb2dLR1JwWVcxbGRHVnlMeklwTzF4dUlDQWdJR3hsZENCaGNtTkZibVJwYm1kWklEMGdZMlZ1ZEdWeUxua2dLeUJOWVhSb0xuTnBiaWhoY21ORmJtUnBibWRCS1NBcUlDaGthV0Z0WlhSbGNpOHlLU0FxSUMweE8xeHVYRzRnSUNBZ2RHaHBjeTVvWVc1a2JHVk1hVzVsTG5ObGRFRjBkSEpwWW5WMFpTZ25aQ2NzSjAwZ0p5dGpaVzUwWlhJdWVDc25JQ2NyWTJWdWRHVnlMbmtySnlCTUlDY3JZWEpqUlc1a2FXNW5XQ3NuSUNjcllYSmpSVzVrYVc1bldTazdYRzVjYmlBZ2ZWeHVYRzVjYmlBZ1kyeHBZMnNvS1NCN1hHNGdJQ0FnYVdZZ0tIUm9hWE11Ylc5a1pUMDlQU2R5Wld4aGRHbDJaU2NwSUh0Y2JpQWdJQ0FnSUhSb2FYTXVjSEpsZG1sdmRYTkJibWRzWlNBOUlHWmhiSE5sTzF4dUlDQWdJSDFjYmlBZ0lDQjBhR2x6TG5CdmMybDBhVzl1TG1GdVkyaHZjaUE5SUhSb2FYTXViVzkxYzJVN1hHNGdJQ0FnZEdocGN5NXdiM05wZEdsdmJpNTJZV3gxWlNBOUlIUm9hWE11WDNaaGJIVmxMbTV2Y20xaGJHbDZaV1E3WEc0Z0lDQWdkR2hwY3k1dGIzWmxLQ2s3WEc0Z0lDQjlYRzVjYmlBZ2JXOTJaU2dwSUh0Y2JpQWdJQ0JwWmlBb2RHaHBjeTVqYkdsamEyVmtLU0I3WEc1Y2JpQWdJQ0FnSUhSb2FYTXVjRzl6YVhScGIyNHVkWEJrWVhSbEtIUm9hWE11Ylc5MWMyVXBPMXh1WEc0Z0lDQWdJQ0JzWlhRZ1lXNW5iR1VnUFNCMGFHbHpMbkJ2YzJsMGFXOXVMblpoYkhWbEtrMWhkR2d1VUVrcU1qdGNibHh1SUNBZ0lDQWdhV1lnS0dGdVoyeGxJRHdnTUNBcElIc2dZVzVuYkdVZ0t6MGdLRTFoZEdndVVFa3FNaWs3SUgxY2JseHVJQ0FnSUNBZ2FXWWdLSFJvYVhNdWJXOWtaU0E5UFQwZ0ozSmxiR0YwYVhabEp5a2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2RHaHBjeTV3Y21WMmFXOTFjMEZ1WjJ4bElDRTlQU0JtWVd4elpTQW1KaUJOWVhSb0xtRmljeWgwYUdsekxuQnlaWFpwYjNWelFXNW5iR1VnTFNCaGJtZHNaU2tnUGlBeUtTQjdYRzRnSUNBZ0lDQWdJQ0FnYVdZZ0tIUm9hWE11Y0hKbGRtbHZkWE5CYm1kc1pTQStJRE1wSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR0Z1WjJ4bElEMGdUV0YwYUM1UVNTb3lPMXh1SUNBZ0lDQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQmhibWRzWlNBOUlEQTdYRzRnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNCOUlDOHFJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvZEdocGN5NXdjbVYyYVc5MWMwRnVaMnhsSUNFOVBTQm1ZV3h6WlNBbUppQk5ZWFJvTG1GaWN5aDBhR2x6TG5CeVpYWnBiM1Z6UVc1bmJHVWdMU0JoYm1kc1pTa2dQaUF5S1NCN1hHNGdJQ0FnSUNBZ0lDQWdhV1lnS0hSb2FYTXVjSEpsZG1sdmRYTkJibWRzWlNBK0lETXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHRnVaMnhsSUQwZ1RXRjBhQzVRU1NveU8xeHVJQ0FnSUNBZ0lDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCaGJtZHNaU0E5SURBN1hHNGdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0I5SUNvdlhHNGdJQ0FnSUNCMGFHbHpMbkJ5WlhacGIzVnpRVzVuYkdVZ1BTQmhibWRzWlR0Y2JseHVJQ0FnSUNBZ2JHVjBJSEpsWVd4V1lXeDFaU0E5SUdGdVoyeGxJQzhnS0UxaGRHZ3VVRWtxTWlrN1hHNWNiaUFnSUNBZ0lIUm9hWE11ZG1Gc2RXVWdQU0IwYUdsekxsOTJZV3gxWlM1MWNHUmhkR1ZPYjNKdFlXd29JSEpsWVd4V1lXeDFaU0FwTzF4dVhHNGdJQ0FnSUNCcFppQW9kR2hwY3k1dGIyUmxJRDA5UFNBbmNtVnNZWFJwZG1VbktTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWNHOXphWFJwYjI0dWRtRnNkV1VnUFNCeVpXRnNWbUZzZFdVN1hHNGdJQ0FnSUNCOVhHNWNiaUFnSUNBZ0lIUm9hWE11WlcxcGRDZ25ZMmhoYm1kbEp5eDBhR2x6TGw5MllXeDFaUzUyWVd4MVpTazdYRzVjYmlBZ0lDQWdJSFJvYVhNdWNtVnVaR1Z5S0NrN1hHNWNiaUFnSUNCOVhHNGdJSDFjYmx4dUlDQnlaV3hsWVhObEtDa2dlMXh1SUNCOVhHNWNiaUFnTHlwY2JpQWdSR2xoYkNkeklIWmhiSFZsTGlCWGFHVnVJSE5sZEN3Z2FYUWdkMmxzYkNCaGRYUnZiV0YwYVdOaGJHeDVJR0psSUdGa2FuVnpkQ0IwYnlCbWFYUWdiV2x1TDIxaGVDOXpkR1Z3SUhObGRIUnBibWR6SUc5bUlIUm9aU0JwYm5SbGNtWmhZMlV1WEc0Z0lFQjBlWEJsSUh0dWRXMWlaWEo5WEc0Z0lFQmxlR0Z0Y0d4bElHUnBZV3d1ZG1Gc2RXVWdQU0F4TUR0Y2JseHVJQ0JuWlhRZ2RtRnNkV1VvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdVgzWmhiSFZsTG5aaGJIVmxPMXh1SUNCOVhHNWNiaUFnYzJWMElIWmhiSFZsS0haaGJIVmxLU0I3WEc0Z0lDQWdkR2hwY3k1ZmRtRnNkV1V1ZFhCa1lYUmxLSFpoYkhWbEtUdGNiaUFnSUNCMGFHbHpMbVZ0YVhRb0oyTm9ZVzVuWlNjc2RHaHBjeTUyWVd4MVpTazdYRzRnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmlBZ2ZWeHVLaTljYmx4dUlDQWdJQzhxS2x4dUlDQWdJRVJwWVd3bmN5QjJZV3gxWlM0Z1YyaGxiaUJ6WlhRc0lHbDBJSGRwYkd3Z1lYVjBiMjFoZEdsallXeHNlU0JpWlNCaFpHcDFjM1FnZEc4Z1ptbDBJRzFwYmk5dFlYZ3ZjM1JsY0NCelpYUjBhVzVuY3lCdlppQjBhR1VnYVc1MFpYSm1ZV05sTGx4dUlDQWdJRUIwZVhCbElIdHVkVzFpWlhKOVhHNGdJQ0FnUUdWNFlXMXdiR1VnWkdsaGJDNTJZV3gxWlNBOUlERXdPMXh1SUNBZ0lDb3ZYRzRnSUNBZ1oyVjBJSFpoYkhWbEtDa2dlMXh1SUNBZ0lDQWdjbVYwZFhKdUlIUm9hWE11WDNaaGJIVmxMblpoYkhWbE8xeHVJQ0FnSUgxY2JpQWdJQ0J6WlhRZ2RtRnNkV1VvZGlrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTVmZG1Gc2RXVXVkWEJrWVhSbEtIWXBPMXh1SUNBZ0lDQWdkR2hwY3k1d2IzTnBkR2x2Ymk1MllXeDFaU0E5SUhSb2FYTXVYM1poYkhWbExtNXZjbTFoYkdsNlpXUTdYRzRnSUNBZ0lDQjBhR2x6TG1WdGFYUW9KMk5vWVc1blpTY3NkR2hwY3k1ZmRtRnNkV1V1ZG1Gc2RXVXBPMXh1SUNBZ0lDQWdkR2hwY3k1eVpXNWtaWElvS1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0F2S2lwY2JpQWdJQ0JNYjNkbGNpQnNhVzFwZENCdlppQjBhR1VnWkdsaGJDZHpJRzkxZEhCMWRDQnlZVzVuWlZ4dUlDQWdJRUIwZVhCbElIdHVkVzFpWlhKOVhHNGdJQ0FnUUdWNFlXMXdiR1VnWkdsaGJDNXRhVzRnUFNBeE1EQXdPMXh1SUNBZ0lDb3ZYRzRnSUNBZ1oyVjBJRzFwYmlncElIdGNiaUFnSUNBZ0lISmxkSFZ5YmlCMGFHbHpMbDkyWVd4MVpTNXRhVzQ3WEc0Z0lDQWdmVnh1SUNBZ0lITmxkQ0J0YVc0b2Rpa2dlMXh1SUNBZ0lDQWdkR2hwY3k1ZmRtRnNkV1V1YldsdUlEMGdkanRjYmlBZ0lDQjlYRzVjYmlBZ0lDQXZLaXBjYmlBZ0lDQlZjSEJsY2lCc2FXMXBkQ0J2WmlCMGFHVWdaR2xoYkNkeklHOTFkSEIxZENCeVlXNW5aVnh1SUNBZ0lFQjBlWEJsSUh0dWRXMWlaWEo5WEc0Z0lDQWdRR1Y0WVcxd2JHVWdaR2xoYkM1dFlYZ2dQU0F4TURBd08xeHVJQ0FnSUNvdlhHNGdJQ0FnWjJWMElHMWhlQ2dwSUh0Y2JpQWdJQ0FnSUhKbGRIVnliaUIwYUdsekxsOTJZV3gxWlM1dFlYZzdYRzRnSUNBZ2ZWeHVJQ0FnSUhObGRDQnRZWGdvZGlrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTVmZG1Gc2RXVXViV0Y0SUQwZ2RqdGNiaUFnSUNCOVhHNWNiaUFnSUNBdktpcGNiaUFnSUNCVWFHVWdhVzVqY21WdFpXNTBJSFJvWVhRZ2RHaGxJR1JwWVd3bmN5QjJZV3gxWlNCamFHRnVaMlZ6SUdKNUxseHVJQ0FnSUVCMGVYQmxJSHR1ZFcxaVpYSjlYRzRnSUNBZ1FHVjRZVzF3YkdVZ1pHbGhiQzV6ZEdWd0lEMGdOVHRjYmlBZ0lDQXFMMXh1SUNBZ0lHZGxkQ0J6ZEdWd0tDa2dlMXh1SUNBZ0lDQWdjbVYwZFhKdUlIUm9hWE11WDNaaGJIVmxMbk4wWlhBN1hHNGdJQ0FnZlZ4dUlDQWdJSE5sZENCemRHVndLSFlwSUh0Y2JpQWdJQ0FnSUhSb2FYTXVYM1poYkhWbExuTjBaWEFnUFNCMk8xeHVJQ0FnSUgxY2JseHVJQ0FnSUM4cUtseHVJQ0FnSUVGaWMyOXNkWFJsSUcxdlpHVWdLR1JwWVd3bmN5QjJZV3gxWlNCcWRXMXdjeUIwYnlCdGIzVnpaU0JqYkdsamF5QndiM05wZEdsdmJpa2diM0lnY21Wc1lYUnBkbVVnYlc5a1pTQW9iVzkxYzJVZ1pISmhaeUJqYUdGdVoyVnpJSFpoYkhWbElISmxiR0YwYVhabElIUnZJR2wwY3lCamRYSnlaVzUwSUhCdmMybDBhVzl1S1M0Z1JHVm1ZWFZzZERvZ1hDSnlaV3hoZEdsMlpWd2lMbHh1SUNBZ0lFQjBlWEJsSUh0emRISnBibWQ5WEc0Z0lDQWdRR1Y0WVcxd2JHVWdaR2xoYkM1dGIyUmxJRDBnWENKeVpXeGhkR2wyWlZ3aU8xeHVJQ0FnSUNvdlhHNGdJQ0FnWjJWMElHMXZaR1VvS1NCN1hHNGdJQ0FnSUNCeVpYUjFjbTRnZEdocGN5NXdiM05wZEdsdmJpNXRiMlJsTzF4dUlDQWdJSDFjYmlBZ0lDQnpaWFFnYlc5a1pTaDJLU0I3WEc0Z0lDQWdJQ0IwYUdsekxuQnZjMmwwYVc5dUxtMXZaR1VnUFNCMk8xeHVJQ0FnSUgxY2JseHVYRzRnSUM4cUtseHVJQ0JPYjNKdFlXeHBlbVZrSUhaaGJIVmxJRzltSUhSb1pTQmthV0ZzTGx4dUlDQkFkSGx3WlNCN2JuVnRZbVZ5ZlZ4dUlDQkFaWGhoYlhCc1pTQmthV0ZzTG01dmNtMWhiR2w2WldRZ1BTQXdMalU3WEc0Z0lDb3ZYRzRnSUdkbGRDQnViM0p0WVd4cGVtVmtLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TGw5MllXeDFaUzV1YjNKdFlXeHBlbVZrTzF4dUlDQjlYRzVjYmlBZ2MyVjBJRzV2Y20xaGJHbDZaV1FvZGlrZ2UxeHVJQ0FnSUhSb2FYTXVYM1poYkhWbExuVndaR0YwWlU1dmNtMWhiQ2gyS1R0Y2JpQWdJQ0IwYUdsekxtVnRhWFFvSjJOb1lXNW5aU2NzZEdocGN5NTJZV3gxWlNrN1hHNGdJSDFjYmx4dWZWeHVYRzVjYmx4dUx5OGdWMFZDVUVGRFN5QkdUMDlVUlZJZ0x5OWNiaTh2SUM0dmZpOXFjMmhwYm5RdGJHOWhaR1Z5SVM0dmJHbGlMMmx1ZEdWeVptRmpaWE12WkdsaGJDNXFjeUlzSWlkMWMyVWdjM1J5YVdOMEp6dGNibHh1YkdWMElITjJaeUE5SUhKbGNYVnBjbVVvSnk0dUwzVjBhV3d2YzNabkp5azdYRzVzWlhRZ1NXNTBaWEptWVdObElEMGdjbVZ4ZFdseVpTZ25MaTR2WTI5eVpTOXBiblJsY21aaFkyVW5LVHRjYm14bGRDQkNkWFIwYjI1VVpXMXdiR0YwWlNBOUlISmxjWFZwY21Vb0p5NHVMMk52YlhCdmJtVnVkSE12WW5WMGRHOXVkR1Z0Y0d4aGRHVW5LVHRjYm14bGRDQjBiM1ZqYUNBOUlISmxjWFZwY21Vb0p5NHVMM1YwYVd3dmRHOTFZMmduS1R0Y2JseHVZMnhoYzNNZ1VHbGhibTlMWlhrZ1pYaDBaVzVrY3lCQ2RYUjBiMjVVWlcxd2JHRjBaU0I3WEc1Y2JpQWdZMjl1YzNSeWRXTjBiM0lvS1NCN1hHNWNiaUFnSUNCc1pYUWdiM0IwYVc5dWN5QTlJRnNuZG1Gc2RXVW5MQ2R1YjNSbEp5d25ZMjlzYjNJblhUdGNibHh1SUNBZ0lHeGxkQ0JrWldaaGRXeDBjeUE5SUh0Y2JpQWdJQ0FnSUNkemFYcGxKem9nV3pnd0xEZ3dYU3hjYmlBZ0lDQWdJQ2QwWVhKblpYUW5PaUJtWVd4elpTeGNiaUFnSUNBZ0lDZHRiMlJsSnpvZ0oySjFkSFJ2Ymljc1hHNGdJQ0FnSUNBbmRtRnNkV1VuT2lBd1hHNGdJQ0FnZlR0Y2JseHVJQ0FnSUhOMWNHVnlLR0Z5WjNWdFpXNTBjeXh2Y0hScGIyNXpMR1JsWm1GMWJIUnpLVHRjYmx4dUlDQWdJSFJvYVhNdWJtOTBaU0E5SUhSb2FYTXVjMlYwZEdsdVozTXVibTkwWlR0Y2JpQWdJQ0IwYUdsekxtTnZiRzl5SUQwZ2RHaHBjeTV6WlhSMGFXNW5jeTVqYjJ4dmNqdGNibHh1SUNBZ0lIUm9hWE11WTI5c2IzSnpJRDBnZTF4dUlDQWdJQ0FnSjNjbk9pQW5JMlptWmljc1hHNGdJQ0FnSUNBbllpYzZJQ2NqTmpZMkp5eGNiaUFnSUNCOU8xeHVYRzRnSUNBZ2RHaHBjeTVwYm1sMEtDazdYRzRnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmx4dUlDQjlYRzVjYmlBZ1luVnBiR1JHY21GdFpTZ3BJSHRjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblFnUFNCemRtY3VZM0psWVhSbEtDZHpkbWNuS1R0Y2JpQWdJQ0IwYUdsekxtVnNaVzFsYm5RdWMyVjBRWFIwY21saWRYUmxLQ2QzYVdSMGFDY3NkR2hwY3k1M2FXUjBhQ2s3WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG5ObGRFRjBkSEpwWW5WMFpTZ25hR1ZwWjJoMEp5eDBhR2x6TG1obGFXZG9kQ2s3WEc0Z0lDQWdkR2hwY3k1d1lYSmxiblF1WVhCd1pXNWtRMmhwYkdRb2RHaHBjeTVsYkdWdFpXNTBLVHRjYmlBZ2ZWeHVYRzRnSUdKMWFXeGtTVzUwWlhKbVlXTmxLQ2tnZTF4dVhHNGdJQ0FnZEdocGN5NXdZV1FnUFNCemRtY3VZM0psWVhSbEtDZHlaV04wSnlrN1hHNWNiaUFnSUNCMGFHbHpMbVZzWlcxbGJuUXVZWEJ3Wlc1a1EyaHBiR1FvZEdocGN5NXdZV1FwTzF4dVhHNGdJQ0FnZEdocGN5NXBiblJsY21GamRHbHZibFJoY21kbGRDQTlJSFJvYVhNdWNHRmtPMXh1WEc0Z0lDQWdMeW9nWlhabGJuUnpJQ292WEc1Y2JpQWdJQ0JwWmlBb0lYUnZkV05vTG1WNGFYTjBjeWtnZTF4dVhHNGdJQ0FnSUNCMGFHbHpMbU5zYVdOcklEMGdLQ2tnUFQ0Z2UxeHVJQ0FnSUNBZ0x5OGdJR052Ym5OdmJHVXViRzluS0NkamJHbGpheWNwTzF4dUlDQWdJQ0FnSUNCMGFHbHpMbkJwWVc1dkxtbHVkR1Z5WVdOMGFXNW5JRDBnZEhKMVpUdGNiaUFnSUNBZ0lDQWdkR2hwY3k1d2FXRnVieTV3WVdsdWRHSnlkWE5vSUQwZ0lYUm9hWE11YzNSaGRHVTdYRzRnSUNBZ0lDQWdJSFJvYVhNdVpHOTNiaWgwYUdsekxuQnBZVzV2TG5CaGFXNTBZbkoxYzJncE8xeHVJQ0FnSUNBZ2ZUdGNibHh1SUNBZ0lDQWdkR2hwY3k1d1lXUXVZV1JrUlhabGJuUk1hWE4wWlc1bGNpZ25iVzkxYzJWdmRtVnlKeXdnS0NrZ1BUNGdlMXh1SUNBZ0lDQWdJQ0JwWmlBb2RHaHBjeTV3YVdGdWJ5NXBiblJsY21GamRHbHVaeWtnZTF4dUlDQWdJQ0FnTHk4Z0lDQWdZMjl1YzI5c1pTNXNiMmNvSjIxdmRYTmxiM1psY2ljcE8xeHVJQ0FnSUNBZ0lDQWdJSFJvYVhNdVpHOTNiaWgwYUdsekxuQnBZVzV2TG5CaGFXNTBZbkoxYzJncE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQjlLVHRjYmx4dVhHNGdJQ0FnSUNCMGFHbHpMbTF2ZG1VZ1BTQW9LU0E5UGlCN1hHNGdJQ0FnSUNBZ0lHbG1JQ2gwYUdsekxuQnBZVzV2TG1sdWRHVnlZV04wYVc1bktTQjdYRzRnSUNBZ0lDQWdJQzh2SUNCamIyNXpiMnhsTG14dlp5Z25iVzkyWlNjcE8xeHVJQ0FnSUNBZ0lDQWdJSFJvYVhNdVltVnVaQ2dwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNCOU8xeHVYRzVjYmlBZ0lDQWdJSFJvYVhNdWNtVnNaV0Z6WlNBOUlDZ3BJRDArSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTV3YVdGdWJ5NXBiblJsY21GamRHbHVaeUE5SUdaaGJITmxPMXh1SUNBZ0lDQWdMeThnSUdOdmJuTnZiR1V1Ykc5bktDZHlaV3hsWVhObEp5azdYRzRnSUNBZ0lDQXZMeUFnZEdocGN5NTFjQ2dwTzF4dUlDQWdJQ0FnZlR0Y2JpQWdJQ0FnSUhSb2FYTXVjR0ZrTG1Ga1pFVjJaVzUwVEdsemRHVnVaWElvSjIxdmRYTmxkWEFuTENBb0tTQTlQaUI3WEc0Z0lDQWdJQ0FnSUdsbUlDaDBhR2x6TG5CcFlXNXZMbWx1ZEdWeVlXTjBhVzVuS1NCN1hHNGdJQ0FnSUNBZ0lDOHZJQ0JqYjI1emIyeGxMbXh2WnlnbmJXOTFjMlYxY0NjcE8xeHVJQ0FnSUNBZ0lDQWdJSFJvYVhNdWRYQW9LVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNCMGFHbHpMbkJoWkM1aFpHUkZkbVZ1ZEV4cGMzUmxibVZ5S0NkdGIzVnpaVzkxZENjc0lDZ3BJRDArSUh0Y2JpQWdJQ0FnSUNBZ2FXWWdLSFJvYVhNdWNHbGhibTh1YVc1MFpYSmhZM1JwYm1jcElIdGNiaUFnSUNBZ0lDQWdMeThnSUdOdmJuTnZiR1V1Ykc5bktDZHRiM1Z6Wlc5MWRDY3BPMXh1SUNBZ0lDQWdJQ0FnSUhSb2FYTXVkWEFvS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2ZTazdYRzVjYmlBZ0lDQjlYRzVjYmlBZ2ZWeHVYRzRnSUhOcGVtVkpiblJsY21aaFkyVW9LU0I3WEc1Y2JpQWdJQ0FnSUNBZ0x5OXNaWFFnY21Ga2FYVnpJRDBnVFdGMGFDNXRhVzRvZEdocGN5NTNhV1IwYUN4MGFHbHpMbWhsYVdkb2RDa2dMeUExTzF4dUlDQWdJQ0FnSUNCc1pYUWdjbUZrYVhWeklEMGdNRHRjYmx4dUlDQWdJQ0FnSUNCMGFHbHpMbkJoWkM1elpYUkJkSFJ5YVdKMWRHVW9KM2duTERBdU5TazdYRzRnSUNBZ0lDQWdJSFJvYVhNdWNHRmtMbk5sZEVGMGRISnBZblYwWlNnbmVTY3NNQzQxS1R0Y2JpQWdJQ0FnSUNBZ2FXWWdLSFJvYVhNdWQybGtkR2dnUGlBeUtTQjdYRzRnSUNBZ0lDQWdJQ0FnZEdocGN5NXdZV1F1YzJWMFFYUjBjbWxpZFhSbEtDZDNhV1IwYUNjc0lIUm9hWE11ZDJsa2RHZ2dMU0F4S1R0Y2JpQWdJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ0lDQjBhR2x6TG5CaFpDNXpaWFJCZEhSeWFXSjFkR1VvSjNkcFpIUm9KeXdnZEdocGN5NTNhV1IwYUNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdhV1lnS0hSb2FYTXVhR1ZwWjJoMElENGdNaWtnZTF4dUlDQWdJQ0FnSUNBZ0lIUm9hWE11Y0dGa0xuTmxkRUYwZEhKcFluVjBaU2duYUdWcFoyaDBKeXdnZEdocGN5NW9aV2xuYUhRcE8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJSFJvYVhNdWNHRmtMbk5sZEVGMGRISnBZblYwWlNnbmFHVnBaMmgwSnl3Z2RHaHBjeTVvWldsbmFIUXBPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhSb2FYTXVjR0ZrTG5ObGRFRjBkSEpwWW5WMFpTZ25jbmduTENCeVlXUnBkWE1wTzF4dUlDQWdJQ0FnSUNCMGFHbHpMbkJoWkM1elpYUkJkSFJ5YVdKMWRHVW9KM0o1Snl3Z2NtRmthWFZ6S1R0Y2JseHVJQ0I5WEc1Y2JpQWdjbVZ1WkdWeUtDa2dlMXh1SUNBZ0lHbG1JQ2doZEdocGN5NXpkR0YwWlNrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTV3WVdRdWMyVjBRWFIwY21saWRYUmxLQ2RtYVd4c0p5d2dkR2hwY3k1amIyeHZjbk5iZEdocGN5NWpiMnh2Y2wwcE8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0IwYUdsekxuQmhaQzV6WlhSQmRIUnlhV0oxZEdVb0oyWnBiR3duTENCMGFHbHpMbU52Ykc5eWN5NWhZMk5sYm5RcE8xeHVJQ0FnSUgxY2JpQWdmVnh1WEc1OVhHNWNiaThxS2x4dUtpQlFhV0Z1YjF4dUtseHVLaUJBWkdWelkzSnBjSFJwYjI0Z1VHbGhibThnYTJWNVltOWhjbVFnYVc1MFpYSm1ZV05sWEc0cVhHNHFJRUJrWlcxdklEeGthWFlnYm1WNGRYTXRkV2s5WENKd2FXRnViMXdpUGp3dlpHbDJQbHh1S2x4dUtpQkFaWGhoYlhCc1pWeHVLaUIyWVhJZ2NHbGhibThnUFNCdVpYY2dUbVY0ZFhNdVVHbGhibThvSnlOMFlYSm5aWFFuS1Z4dUtseHVLaUJBWlhoaGJYQnNaVnh1S2lCMllYSWdjR2xoYm04Z1BTQnVaWGNnVG1WNGRYTXVVR2xoYm04b0p5TjBZWEpuWlhRbkxIdGNiaW9nSUNBZ0lDZHphWHBsSnpvZ1d6VXdNQ3d4TWpWZExGeHVLaUFnSUNBZ0oyMXZaR1VuT2lBblluVjBkRzl1Snl3Z0lDOHZJQ2RpZFhSMGIyNG5MQ0FuZEc5bloyeGxKeXdnYjNJZ0oybHRjSFZzYzJVblhHNHFJQ0FnSUNBbmJHOTNUbTkwWlNjNklESTBMRnh1S2lBZ0lDQWdKMmhwWjJoT2IzUmxKem9nTmpCY2Jpb2dmU2xjYmlwY2Jpb2dRRzkxZEhCMWRGeHVLaUJqYUdGdVoyVmNiaW9nUm1seVpYTWdZVzU1SUhScGJXVWdZU0J1WlhjZ2EyVjVJR2x6SUhCeVpYTnpaV1FnYjNJZ2NtVnNaV0Z6WldRZ1BHSnlQbHh1S2lCVWFHVWdaWFpsYm5RZ1pHRjBZU0JwY3lCaGJpQnZZbXBsWTNRZ1kyOXVkR0ZwYm1sdVp5QThhVDV1YjNSbFBDOXBQaUJoYm1RZ1BHaytjM1JoZEdVOEwyaytJSEJ5YjNCbGNuUnBaWE11WEc0cVhHNHFJRUJ2ZFhSd2RYUmxlR0Z0Y0d4bFhHNHFJSEJwWVc1dkxtOXVLQ2RqYUdGdVoyVW5MR1oxYm1OMGFXOXVLSFlwSUh0Y2Jpb2dJQ0JqYjI1emIyeGxMbXh2WnloMktUdGNiaW9nZlNsY2JpcGNiaW92WEc1Y2JtVjRjRzl5ZENCa1pXWmhkV3gwSUdOc1lYTnpJRkJwWVc1dklHVjRkR1Z1WkhNZ1NXNTBaWEptWVdObElIdGNibHh1SUNCamIyNXpkSEoxWTNSdmNpZ3BJSHRjYmx4dUlDQWdJR3hsZENCdmNIUnBiMjV6SUQwZ1d5ZDJZV3gxWlNkZE8xeHVYRzRnSUNBZ2JHVjBJR1JsWm1GMWJIUnpJRDBnZTF4dUlDQWdJQ0FnSjNOcGVtVW5PaUJiTlRBd0xERXlOVjBzWEc0Z0lDQWdJQ0FuYkc5M1RtOTBaU2M2SURJMExGeHVJQ0FnSUNBZ0oyaHBaMmhPYjNSbEp6b2dOakFzWEc0Z0lDQWdJQ0FuYlc5a1pTYzZJQ2RpZFhSMGIyNG5YRzRnSUNBZ2ZUdGNibHh1SUNBZ0lITjFjR1Z5S0dGeVozVnRaVzUwY3l4dmNIUnBiMjV6TEdSbFptRjFiSFJ6S1R0Y2JseHVJQ0FnSUhSb2FYTXVhMlY1VUdGMGRHVnliaUE5SUZzbmR5Y3NKMkluTENkM0p5d25ZaWNzSjNjbkxDZDNKeXduWWljc0ozY25MQ2RpSnl3bmR5Y3NKMkluTENkM0oxMDdYRzVjYmlBZ0lDQjBhR2x6TG5CaGFXNTBZbkoxYzJnZ1BTQm1ZV3h6WlR0Y2JseHVJQ0FnSUhSb2FYTXViVzlrWlNBOUlIUm9hWE11YzJWMGRHbHVaM011Ylc5a1pUdGNibHh1SUNBZ0lIUm9hWE11Y21GdVoyVWdQU0I3WEc0Z0lDQWdJQ0JzYjNjNklIUm9hWE11YzJWMGRHbHVaM011Ykc5M1RtOTBaU3hjYmlBZ0lDQWdJR2hwWjJnNklIUm9hWE11YzJWMGRHbHVaM011YUdsbmFFNXZkR1ZjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdkR2hwY3k1eVlXNW5aUzV6YVhwbElEMGdkR2hwY3k1eVlXNW5aUzVvYVdkb0lDMGdkR2hwY3k1eVlXNW5aUzVzYjNjN1hHNWNiaUFnSUNCMGFHbHpMbXRsZVhNZ1BTQmJYVHRjYmx4dUlDQWdJSFJvYVhNdWRHOW5aMnhsVkc4Z1BTQm1ZV3h6WlR0Y2JseHVJQ0FnSUhSb2FYTXVhVzVwZENncE8xeHVJQ0FnSUhSb2FYTXVjbVZ1WkdWeUtDazdYRzVjYmlBZ2ZWeHVYRzRnSUdKMWFXeGtSbkpoYldVb0tTQjdYRzRnSUNBZ2RHaHBjeTVsYkdWdFpXNTBJRDBnWkc5amRXMWxiblF1WTNKbFlYUmxSV3hsYldWdWRDZ25aR2wySnlrN1hHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExuTjBlV3hsTG5CdmMybDBhVzl1SUQwZ0ozSmxiR0YwYVhabEp6dGNiaUFnSUNCMGFHbHpMbVZzWlcxbGJuUXVjM1I1YkdVdVltOXlaR1Z5VW1Ga2FYVnpJRDBnSnpCd2VDYzdYRzRnSUNBZ2RHaHBjeTVsYkdWdFpXNTBMbk4wZVd4bExtUnBjM0JzWVhrZ1BTQW5ZbXh2WTJzbk8xeHVJQ0FnSUhSb2FYTXVaV3hsYldWdWRDNXpkSGxzWlM1M2FXUjBhQ0E5SUNjeE1EQWxKenRjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1YzNSNWJHVXVhR1ZwWjJoMElEMGdKekV3TUNVbk8xeHVJQ0FnSUhSb2FYTXVjR0Z5Wlc1MExtRndjR1Z1WkVOb2FXeGtLSFJvYVhNdVpXeGxiV1Z1ZENrN1hHNGdJSDFjYmx4dUlDQmlkV2xzWkVsdWRHVnlabUZqWlNncElIdGNibHh1SUNBZ0lIUm9hWE11YTJWNWN5QTlJRnRkTzF4dVhHNGdJQ0FnWm05eUlDaHNaWFFnYVQwd08yazhkR2hwY3k1eVlXNW5aUzVvYVdkb0lDMGdkR2hwY3k1eVlXNW5aUzVzYjNjN2FTc3JLU0I3WEc1Y2JpQWdJQ0FnSUd4bGRDQmpiMjUwWVdsdVpYSWdQU0JrYjJOMWJXVnVkQzVqY21WaGRHVkZiR1Z0Wlc1MEtDZHpjR0Z1SnlrN1hHNGdJQ0FnSUNCc1pYUWdjMk5oYkdWSmJtUmxlQ0E5SUNocEszUm9hWE11Y21GdVoyVXViRzkzS1NBbElIUm9hWE11YTJWNVVHRjBkR1Z5Ymk1c1pXNW5kR2c3WEc1Y2JpQWdJQ0FnSUd4bGRDQnJaWGtnUFNCdVpYY2dVR2xoYm05TFpYa29ZMjl1ZEdGcGJtVnlMQ0I3WEc0Z0lDQWdJQ0FnSUNBZ1kyOXRjRzl1Wlc1ME9pQjBjblZsTEZ4dUlDQWdJQ0FnSUNBZ0lHNXZkR1U2SUdrcmRHaHBjeTV5WVc1blpTNXNiM2NzWEc0Z0lDQWdJQ0FnSUNBZ1kyOXNiM0k2SUhSb2FYTXVhMlY1VUdGMGRHVnlibHR6WTJGc1pVbHVaR1Y0WFN4Y2JpQWdJQ0FnSUNBZ0lDQnRiMlJsT2lCMGFHbHpMbTF2WkdWY2JpQWdJQ0FnSUNBZ2ZTd2dkR2hwY3k1clpYbERhR0Z1WjJVdVltbHVaQ2gwYUdsekxHa3JkR2hwY3k1eVlXNW5aUzVzYjNjcEtUdGNibHh1SUNBZ0lDQWdhMlY1TG5CcFlXNXZJRDBnZEdocGN6dGNibHh1SUNBZ0lDQWdhV1lnS0hSdmRXTm9MbVY0YVhOMGN5a2dlMXh1SUNBZ0lDQWdJQ0JyWlhrdWNHRmtMbWx1WkdWNElEMGdhVHRjYmlBZ0lDQWdJQ0FnYTJWNUxuQnlaVU5zYVdOcklEMGdhMlY1TG5CeVpVMXZkbVVnUFNCclpYa3VjSEpsVW1Wc1pXRnpaU0E5SUNncElEMCtJSHQ5TzF4dUlDQWdJQ0FnSUNCclpYa3VZMnhwWTJzZ1BTQnJaWGt1Ylc5MlpTQTlJR3RsZVM1eVpXeGxZWE5sSUQwZ0tDa2dQVDRnZTMwN1hHNGdJQ0FnSUNBZ0lHdGxlUzV3Y21WVWIzVmphQ0E5SUd0bGVTNXdjbVZVYjNWamFFMXZkbVVnUFNCclpYa3VjSEpsVkc5MVkyaFNaV3hsWVhObElEMGdLQ2tnUFQ0Z2UzMDdYRzRnSUNBZ0lDQWdJR3RsZVM1MGIzVmphQ0E5SUd0bGVTNTBiM1ZqYUUxdmRtVWdQU0JyWlhrdWRHOTFZMmhTWld4bFlYTmxJRDBnS0NrZ1BUNGdlMzA3WEc0Z0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUhSb2FYTXVhMlY1Y3k1d2RYTm9LR3RsZVNrN1hHNGdJQ0FnSUNCMGFHbHpMbVZzWlcxbGJuUXVZWEJ3Wlc1a1EyaHBiR1FvWTI5dWRHRnBibVZ5S1R0Y2JseHVJQ0FnSUgxY2JpQWdJQ0JwWmlBb2RHOTFZMmd1WlhocGMzUnpLU0I3WEc0Z0lDQWdJQ0IwYUdsekxtRmtaRlJ2ZFdOb1RHbHpkR1Z1WlhKektDazdYRzRnSUNBZ2ZWeHVYRzRnSUgxY2JseHVJQ0J6YVhwbFNXNTBaWEptWVdObEtDa2dlMXh1WEc0Z0lDQWdiR1YwSUd0bGVWZ2dQU0F3TzF4dVhHNGdJQ0FnYkdWMElHdGxlVkJ2YzJsMGFXOXVjeUE5SUZ0ZE8xeHVYRzRnSUNBZ1ptOXlJQ2hzWlhRZ2FUMHdPMms4ZEdocGN5NXlZVzVuWlM1b2FXZG9JQzBnZEdocGN5NXlZVzVuWlM1c2IzYzdhU3NyS1NCN1hHNWNiaUFnSUNBZ0lHdGxlVkJ2YzJsMGFXOXVjeTV3ZFhOb0tHdGxlVmdwTzF4dVhHNGdJQ0FnSUNCc1pYUWdjMk5oYkdWSmJtUmxlQ0E5SUNocEszUm9hWE11Y21GdVoyVXViRzkzS1NBbElIUm9hWE11YTJWNVVHRjBkR1Z5Ymk1c1pXNW5kR2c3WEc0Z0lDQWdJQ0JzWlhRZ2JtVjRkRk5qWVd4bFNXNWtaWGdnUFNBb2FTc3hLM1JvYVhNdWNtRnVaMlV1Ykc5M0tTQWxJSFJvYVhNdWEyVjVVR0YwZEdWeWJpNXNaVzVuZEdnN1hHNGdJQ0FnSUNCcFppQW9hU3N4SzNSb2FYTXVjbUZ1WjJVdWJHOTNJRDQ5SUhSb2FYTXVjbUZ1WjJVdWFHbG5hQ2tnZTF4dUlDQWdJQ0FnSUNCclpYbFlJQ3M5SURFN1hHNGdJQ0FnSUNCOUlHVnNjMlVnYVdZZ0tIUm9hWE11YTJWNVVHRjBkR1Z5Ymx0elkyRnNaVWx1WkdWNFhTQTlQVDBnSjNjbklDWW1JSFJvYVhNdWEyVjVVR0YwZEdWeWJsdHVaWGgwVTJOaGJHVkpibVJsZUYwZ1BUMDlJQ2QzSnlrZ2UxeHVJQ0FnSUNBZ0lDQnJaWGxZSUNzOUlERTdYRzRnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQnJaWGxZSUNzOUlEQXVOVHRjYmlBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUNBZ2JHVjBJR3RsZVhOWGFXUmxJRDBnYTJWNVdEdGNibHh1WEc0Z0lDOHZJQ0JzWlhRZ2NHRmtaR2x1WnlBOUlIUm9hWE11ZDJsa2RHZ2dMeUF4TWpBN1hHNGdJQ0FnYkdWMElIQmhaR1JwYm1jZ1BTQXhPMXh1SUNBZ0lHeGxkQ0JpZFhSMGIyNVhhV1IwYUNBOUlDaDBhR2x6TG5kcFpIUm9MWEJoWkdScGJtY3FNaWtnTHlCclpYbHpWMmxrWlR0Y2JpQWdJQ0JzWlhRZ1luVjBkRzl1U0dWcFoyaDBJRDBnS0hSb2FYTXVhR1ZwWjJoMExYQmhaR1JwYm1jcU1pa2dMeUF5TzF4dVhHNGdJQ0FnWm05eUlDaHNaWFFnYVQwd08yazhkR2hwY3k1clpYbHpMbXhsYm1kMGFEdHBLeXNwSUh0Y2JseHVJQ0FnSUNBZ2JHVjBJR052Ym5SaGFXNWxjaUE5SUhSb2FYTXVhMlY1YzF0cFhTNXdZWEpsYm5RN1hHNGdJQ0FnSUNCamIyNTBZV2x1WlhJdWMzUjViR1V1Y0c5emFYUnBiMjRnUFNBbllXSnpiMngxZEdVbk8xeHVJQ0FnSUNBZ1kyOXVkR0ZwYm1WeUxuTjBlV3hsTG14bFpuUWdQU0FvYTJWNVVHOXphWFJwYjI1elcybGRLbUoxZEhSdmJsZHBaSFJvSzNCaFpHUnBibWNwSUNzZ0ozQjRKenRjYmlBZ0lDQWdJR2xtSUNoMGFHbHpMbXRsZVhOYmFWMHVZMjlzYjNJZ1BUMDlJQ2QzSnlrZ2UxeHVJQ0FnSUNBZ0lDQmpiMjUwWVdsdVpYSXVjM1I1YkdVdWRHOXdJRDBnS0hCaFpHUnBibWNwSUNzZ0ozQjRKenRjYmlBZ0lDQWdJQ0FnZEdocGN5NXJaWGx6VzJsZExuSmxjMmw2WlNoaWRYUjBiMjVYYVdSMGFDd2dZblYwZEc5dVNHVnBaMmgwS2pJcE8xeHVJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ1kyOXVkR0ZwYm1WeUxuTjBlV3hsTG5wSmJtUmxlQ0E5SURFN1hHNGdJQ0FnSUNBZ0lHTnZiblJoYVc1bGNpNXpkSGxzWlM1MGIzQWdQU0J3WVdSa2FXNW5LeWR3ZUNjN1hHNGdJQ0FnSUNBZ0lIUm9hWE11YTJWNWMxdHBYUzV5WlhOcGVtVW9ZblYwZEc5dVYybGtkR2dzSUdKMWRIUnZia2hsYVdkb2RDb3hMakVwTzF4dUlDQWdJQ0FnZlZ4dVhHNGdJQ0FnZlZ4dVhHNGdJSDFjYmx4dUlDQmpiMnh2Y2tsdWRHVnlabUZqWlNncElIdGNibHh1SUNBZ0lDOHZJRkJwWVc1dklHdGxlWE1nWkc5dUozUWdZV04wZFdGc2JIa2dhR0YyWlNCaElITjBjbTlyWlNCaWIzSmtaWEpjYmlBZ0lDQXZMeUJVYUdWNUlHaGhkbVVnYzNCaFkyVWdZbVYwZDJWbGJpQjBhR1Z0TENCM2FHbGphQ0J6YUc5M2N5QjBhR1VnVUdsaGJtOGdZbWNnWTI5c2IzSmNiaUFnSUNCMGFHbHpMbVZzWlcxbGJuUXVjM1I1YkdVdVltRmphMmR5YjNWdVpFTnZiRzl5SUQwZ2RHaHBjeTVqYjJ4dmNuTXViV1ZrYVhWdFRHbG5hSFE3WEc1Y2JpQWdJQ0JtYjNJZ0tHeGxkQ0JwUFRBN2FUeDBhR2x6TG10bGVYTXViR1Z1WjNSb08ya3JLeWtnZTF4dUlDQWdJQ0FnZEdocGN5NXJaWGx6VzJsZExtTnZiRzl5Y3lBOUlIdGNiaUFnSUNBZ0lDQWdKM2NuT2lCMGFHbHpMbU52Ykc5eWN5NXNhV2RvZEN4Y2JpQWdJQ0FnSUNBZ0oySW5PaUIwYUdsekxtTnZiRzl5Y3k1a1lYSnJMRnh1SUNBZ0lDQWdJQ0FuWVdOalpXNTBKem9nZEdocGN5NWpiMnh2Y25NdVlXTmpaVzUwTEZ4dUlDQWdJQ0FnSUNBblltOXlaR1Z5SnpvZ2RHaHBjeTVqYjJ4dmNuTXViV1ZrYVhWdFRHbG5hSFJjYmlBZ0lDQWdJSDA3WEc0Z0lDQWdJQ0IwYUdsekxtdGxlWE5iYVYwdVkyOXNiM0pKYm5SbGNtWmhZMlVvS1R0Y2JpQWdJQ0FnSUhSb2FYTXVhMlY1YzF0cFhTNXlaVzVrWlhJb0tUdGNiaUFnSUNCOVhHNWNibHh1SUNCOVhHNWNiaUFnYTJWNVEyaGhibWRsS0c1dmRHVXNiMjRwSUh0Y2JpQWdJQ0F2THlCbGJXbDBJR1JoZEdFZ1ptOXlJR0Z1ZVNCclpYa2dkSFZ5Ym1sdVp5QnZiaTl2Wm1aY2JpQWdJQ0F2THlCY0ltNXZkR1ZjSWlCcGN5QjBhR1VnYm05MFpTQjJZV3gxWlZ4dUlDQWdJQzh2SUZ3aWIyNWNJaUJwY3lCaElHSnZiMnhsWVc0Z2QyaGxkR2hsY2lCcGRDQnBjeUJ2YmlCdmNpQnZabVpjYmlBZ0lDQXZMeUJwYmlCaFpuUmxjblJ2ZFdOb0lHMXZaR1VzSUZ3aWIyNDZJR2x6SUdGdUlHOWlhbVZqZENCM2FYUm9JSE4wWVhSbEwzZ3ZlU0J3Y205d1pYSjBhV1Z6WEc0Z0lDQWdkbUZ5SUdSaGRHRWdQU0I3WEc0Z0lDQWdJQ0J1YjNSbE9pQnViM1JsWEc0Z0lDQWdmVHRjYmlBZ0lDQnBaaUFvZEhsd1pXOW1JRzl1SUQwOVBTQW5iMkpxWldOMEp5a2dlMXh1SUNBZ0lDQWdaR0YwWVM1emRHRjBaU0E5SUc5dUxuTjBZWFJsTzF4dUlDQWdJQzh2SUNCa1lYUmhMbmdnUFNCdmJpNTRYRzRnSUNBZ0x5OGdJR1JoZEdFdWVTQTlJRzl1TG5sY2JpQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdaR0YwWVM1emRHRjBaU0E5SUc5dU8xeHVJQ0FnSUgxY2JpQWdJQ0IwYUdsekxtVnRhWFFvSjJOb1lXNW5aU2NzWkdGMFlTazdYRzRnSUgxY2JseHVJQ0F2S2lCa2NtRm5LRzV2ZEdVc2IyNHBJSHRjYmlBZ0lDQjBhR2x6TG1WdGFYUW9KMk5vWVc1blpTY3NlMXh1SUNBZ0lDQWdibTkwWlRvZ2JtOTBaU3hjYmlBZ0lDQWdJSE4wWVhSbE9pQnZibHh1SUNBZ0lIMHBPMXh1SUNCOUlDb3ZYRzVjYmlBZ2NtVnVaR1Z5S0NrZ2UxeHVJQ0FnSUM4dklHeHZiM0FnZEdoeWIzVm5hQ0JoYm1RZ2NtVnVaR1Z5SUhSb1pTQnJaWGx6UDF4dUlDQjlYRzVjYmx4dUlDQmhaR1JVYjNWamFFeHBjM1JsYm1WeWN5Z3BJSHRjYmx4dUlDQWdJSFJvYVhNdWNISmxRMnhwWTJzZ1BTQjBhR2x6TG5CeVpVMXZkbVVnUFNCMGFHbHpMbkJ5WlZKbGJHVmhjMlVnUFNBb0tTQTlQaUI3ZlR0Y2JpQWdJQ0IwYUdsekxtTnNhV05ySUQwZ2RHaHBjeTV0YjNabElEMGdkR2hwY3k1eVpXeGxZWE5sSUQwZ0tDa2dQVDRnZTMwN1hHNGdJQ0FnZEdocGN5NXdjbVZVYjNWamFDQTlJSFJvYVhNdWNISmxWRzkxWTJoTmIzWmxJRDBnZEdocGN5NXdjbVZVYjNWamFGSmxiR1ZoYzJVZ1BTQW9LU0E5UGlCN2ZUdGNiaUFnSUNCMGFHbHpMblJ2ZFdOb0lEMGdkR2hwY3k1MGIzVmphRTF2ZG1VZ1BTQjBhR2x6TG5SdmRXTm9VbVZzWldGelpTQTlJQ2dwSUQwK0lIdDlPMXh1WEc0Z0lDQWdkR2hwY3k1amRYSnlaVzUwUld4bGJXVnVkQ0E5SUdaaGJITmxPMXh1WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG1Ga1pFVjJaVzUwVEdsemRHVnVaWElvSjNSdmRXTm9jM1JoY25RbkxDQW9aU2tnUFQ0Z2UxeHVJQ0FnSUNBZ1kyOXVjMjlzWlM1c2IyY29KM1J2ZFdOb2MzUmhjblFuS1R0Y2JpQWdJQ0FnSUd4bGRDQmxiR1Z0Wlc1MElEMGdaRzlqZFcxbGJuUXVaV3hsYldWdWRFWnliMjFRYjJsdWRDaGxMblJoY21kbGRGUnZkV05vWlhOYk1GMHVZMnhwWlc1MFdDeGxMblJoY21kbGRGUnZkV05vWlhOYk1GMHVZMnhwWlc1MFdTazdYRzRnSUNBZ0lDQnNaWFFnYTJWNUlEMGdkR2hwY3k1clpYbHpXMlZzWlcxbGJuUXVhVzVrWlhoZE8xeHVJQ0FnSUNBZ2RHaHBjeTV3WVdsdWRHSnlkWE5vSUQwZ0lXdGxlUzV6ZEdGMFpUdGNiaUFnSUNBZ0lHdGxlUzVrYjNkdUtIUm9hWE11Y0dGcGJuUmljblZ6YUNrN1hHNGdJQ0FnSUNCMGFHbHpMbU4xY25KbGJuUkZiR1Z0Wlc1MElEMGdaV3hsYldWdWRDNXBibVJsZUR0Y2JpQWdJQ0FnSUdVdWNISmxkbVZ1ZEVSbFptRjFiSFFvS1R0Y2JpQWdJQ0FnSUdVdWMzUnZjRkJ5YjNCaFoyRjBhVzl1S0NrN1hHNGdJQ0FnZlNrN1hHNWNiaUFnSUNCMGFHbHpMbVZzWlcxbGJuUXVZV1JrUlhabGJuUk1hWE4wWlc1bGNpZ25kRzkxWTJodGIzWmxKeXdnS0dVcElEMCtJSHRjYmlBZ0lDQWdJR3hsZENCbGJHVnRaVzUwSUQwZ1pHOWpkVzFsYm5RdVpXeGxiV1Z1ZEVaeWIyMVFiMmx1ZENobExuUmhjbWRsZEZSdmRXTm9aWE5iTUYwdVkyeHBaVzUwV0N4bExuUmhjbWRsZEZSdmRXTm9aWE5iTUYwdVkyeHBaVzUwV1NrN1hHNGdJQ0FnSUNCc1pYUWdhMlY1SUQwZ2RHaHBjeTVyWlhselcyVnNaVzFsYm5RdWFXNWtaWGhkTzF4dUlDQWdJQ0FnYVdZZ0tHVnNaVzFsYm5RdWFXNWtaWGdoUFQxMGFHbHpMbU4xY25KbGJuUkZiR1Z0Wlc1MEtTQjdYRzRnSUNBZ0lDQWdJR2xtSUNoMGFHbHpMbU4xY25KbGJuUkZiR1Z0Wlc1MEtTQjdYRzRnSUNBZ0lDQWdJQ0FnYkdWMElIQmhjM1JMWlhrZ1BTQjBhR2x6TG10bGVYTmJkR2hwY3k1amRYSnlaVzUwUld4bGJXVnVkRjA3WEc0Z0lDQWdJQ0FnSUNBZ2NHRnpkRXRsZVM1MWNDZ3BPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUd0bGVTNWtiM2R1S0hSb2FYTXVjR0ZwYm5SaWNuVnphQ2s3WEc0Z0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0JyWlhrdVltVnVaQ2dwTzF4dUlDQWdJQ0FnZlZ4dUlDQWdJQ0FnZEdocGN5NWpkWEp5Wlc1MFJXeGxiV1Z1ZENBOUlHVnNaVzFsYm5RdWFXNWtaWGc3WEc0Z0lDQWdJQ0JsTG5CeVpYWmxiblJFWldaaGRXeDBLQ2s3WEc0Z0lDQWdJQ0JsTG5OMGIzQlFjbTl3WVdkaGRHbHZiaWdwTzF4dUlDQWdJSDBwTzF4dVhHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExtRmtaRVYyWlc1MFRHbHpkR1Z1WlhJb0ozUnZkV05vWlc1a0p5d2dLR1VwSUQwK0lIdGNiaUFnSUNBZ0lDOHZJRzV2SUhSdmRXTm9aWE1nZEc4Z1kyRnNZM1ZzWVhSbElHSmxZMkYxYzJVZ2JtOXVaU0J5WlcxaGFXNXBibWRjYmlBZ0lDQWdJR3hsZENCclpYa2dQU0IwYUdsekxtdGxlWE5iZEdocGN5NWpkWEp5Wlc1MFJXeGxiV1Z1ZEYwN1hHNGdJQ0FnSUNCclpYa3VkWEFvS1R0Y2JpQWdJQ0FnSUhSb2FYTXVhVzUwWlhKaFkzUnBibWNnUFNCbVlXeHpaVHRjYmlBZ0lDQWdJSFJvYVhNdVkzVnljbVZ1ZEVWc1pXMWxiblFnUFNCbVlXeHpaVHRjYmlBZ0lDQWdJR1V1Y0hKbGRtVnVkRVJsWm1GMWJIUW9LVHRjYmlBZ0lDQWdJR1V1YzNSdmNGQnliM0JoWjJGMGFXOXVLQ2s3WEc0Z0lDQWdmU2s3WEc1Y2JpQWdmVnh1WEc0Z0lDOHFLbHh1SUNCRVpXWnBibVVnZEdobElIQnBkR05vSUhKaGJtZGxJQ2hzYjNkbGMzUWdZVzVrSUdocFoyaGxjM1FnYm05MFpTa2diMllnZEdobElIQnBZVzV2SUd0bGVXSnZZWEprTGx4dUlDQkFjR0Z5WVcwZ2JHOTNJSHR1ZFcxaVpYSjlJRTFKUkVrZ2JtOTBaU0IyWVd4MVpTQnZaaUIwYUdVZ2JHOTNaWE4wSUc1dmRHVWdiMjRnZEdobElHdGxlV0p2WVhKa1hHNGdJRUJ3WVhKaGJTQm9hV2RvSUh0dWRXMWlaWEo5SUUxSlJFa2dibTkwWlNCMllXeDFaU0J2WmlCMGFHVWdhR2xuYUdWemRDQnViM1JsSUc5dUlIUm9aU0JyWlhsaWIyRnlaRnh1SUNBcUwxeHVJQ0J6WlhSU1lXNW5aU2hzYjNjc2FHbG5hQ2tnZTF4dUlDQWdJSFJvYVhNdWNtRnVaMlV1Ykc5M0lEMGdiRzkzTzF4dUlDQWdJSFJvYVhNdWNtRnVaMlV1YUdsbmFDQTlJR2hwWjJnN1hHNGdJQ0FnZEdocGN5NWxiWEIwZVNncE8xeHVJQ0FnSUhSb2FYTXVZblZwYkdSSmJuUmxjbVpoWTJVb0tUdGNiaUFnZlZ4dVhHNGdJQzhxS2x4dUlDQlVkWEp1SUdFZ2EyVjVJRzl1SUc5eUlHOW1aaUIxYzJsdVp5QnBkSE1nVFVsRVNTQnViM1JsSUhaaGJIVmxPMXh1SUNCQWNHRnlZVzBnYm05MFpTQjdiblZ0WW1WeWZTQk5TVVJKSUc1dmRHVWdkbUZzZFdVZ2IyWWdkR2hsSUd0bGVTQjBieUJqYUdGdVoyVmNiaUFnUUhCaGNtRnRJRzl1SUh0aWIyOXNaV0Z1ZlNCWGFHVjBhR1Z5SUhSb1pTQnViM1JsSUhOb2IzVnNaQ0IwZFhKdUlHOXVJRzl5SUc5bVpseHVJQ0FxTDF4dUlDQjBiMmRuYkdWTFpYa29ibTkwWlN3Z2IyNHBJSHRjYmlBZ0lDQjBhR2x6TG10bGVYTmJibTkwWlMxMGFHbHpMbkpoYm1kbExteHZkMTB1Wm14cGNDaHZiaWs3WEc0Z0lIMWNibHh1SUNBdktpcGNiaUFnVkhWeWJpQmhJR3RsZVNCdmJpQnZjaUJ2Wm1ZZ2RYTnBibWNnYVhSeklHdGxlU0JwYm1SbGVDQnZiaUIwYUdVZ2NHbGhibThnYVc1MFpYSm1ZV05sTGx4dUlDQkFjR0Z5WVcwZ2FXNWtaWGdnZTI1MWJXSmxjbjBnU1c1a1pYZ2diMllnZEdobElHdGxlU0IwYnlCamFHRnVaMlZjYmlBZ1FIQmhjbUZ0SUc5dUlIdGliMjlzWldGdWZTQlhhR1YwYUdWeUlIUm9aU0J1YjNSbElITm9iM1ZzWkNCMGRYSnVJRzl1SUc5eUlHOW1abHh1SUNBcUwxeHVJQ0IwYjJkbmJHVkpibVJsZUNocGJtUmxlQ3dnYjI0cElIdGNiaUFnSUNCMGFHbHpMbXRsZVhOYmFXNWtaWGhkTG1ac2FYQW9iMjRwTzF4dUlDQjlYRzVjYm4xY2JseHVYRzVjYmk4dklGZEZRbEJCUTBzZ1JrOVBWRVZTSUM4dlhHNHZMeUF1TDM0dmFuTm9hVzUwTFd4dllXUmxjaUV1TDJ4cFlpOXBiblJsY21aaFkyVnpMM0JwWVc1dkxtcHpJaXdpSjNWelpTQnpkSEpwWTNRbk8xeHVYRzVzWlhRZ2MzWm5JRDBnY21WeGRXbHlaU2duTGk0dmRYUnBiQzl6ZG1jbktUdGNibXhsZENCa2IyMGdQU0J5WlhGMWFYSmxLQ2N1TGk5MWRHbHNMMlJ2YlNjcE8xeHViR1YwSUVsdWRHVnlabUZqWlNBOUlISmxjWFZwY21Vb0p5NHVMMk52Y21VdmFXNTBaWEptWVdObEp5azdYRzVzWlhRZ1FuVjBkRzl1VkdWdGNHeGhkR1VnUFNCeVpYRjFhWEpsS0NjdUxpOWpiMjF3YjI1bGJuUnpMMkoxZEhSdmJuUmxiWEJzWVhSbEp5azdYRzVzWlhRZ1RXRjBjbWw0VFc5a1pXd2dQU0J5WlhGMWFYSmxLQ2N1TGk5dGIyUmxiSE12YldGMGNtbDRKeWs3WEc1c1pYUWdRMjkxYm5SbGNrMXZaR1ZzSUQwZ2NtVnhkV2x5WlNnbkxpNHZiVzlrWld4ekwyTnZkVzUwWlhJbktUdGNibXhsZENCMGIzVmphQ0E5SUhKbGNYVnBjbVVvSnk0dUwzVjBhV3d2ZEc5MVkyZ25LVHRjYmx4dVhHNWNibU5zWVhOeklFMWhkSEpwZUVObGJHd2daWGgwWlc1a2N5QkNkWFIwYjI1VVpXMXdiR0YwWlNCN1hHNWNiaUFnWTI5dWMzUnlkV04wYjNJb0tTQjdYRzVjYmlBZ0lDQnNaWFFnYjNCMGFXOXVjeUE5SUZzbmRtRnNkV1VuTEYwN1hHNWNiaUFnSUNCc1pYUWdaR1ZtWVhWc2RITWdQU0I3WEc0Z0lDQWdJQ0FuYzJsNlpTYzZJRnM0TUN3NE1GMHNYRzRnSUNBZ0lDQW5kR0Z5WjJWMEp6b2dabUZzYzJVc1hHNGdJQ0FnSUNBbmJXOWtaU2M2SUNkMGIyZG5iR1VuTEZ4dUlDQWdJQ0FnSjNaaGJIVmxKem9nTUZ4dUlDQWdJSDA3WEc1Y2JpQWdJQ0J6ZFhCbGNpaGhjbWQxYldWdWRITXNiM0IwYVc5dWN5eGtaV1poZFd4MGN5azdYRzVjYmlBZ0lDQjBhR2x6TG1sdVpHVjRJRDBnZEdocGN5NXpaWFIwYVc1bmN5NXBibVJsZUR0Y2JpQWdJQ0IwYUdsekxuSnZkeUE5SUhSb2FYTXVjMlYwZEdsdVozTXVjbTkzTzF4dUlDQWdJSFJvYVhNdVkyOXNkVzF1SUQwZ2RHaHBjeTV6WlhSMGFXNW5jeTVqYjJ4MWJXNDdYRzVjYmlBZ0lDQjBhR2x6TG0xaGRISnBlQ0E5SUhSb2FYTXVjMlYwZEdsdVozTXViV0YwY21sNE8xeHVYRzRnSUNBZ2RHaHBjeTVwYm5SbGNtRmpkR2x1WnlBOUlHWmhiSE5sTzF4dUlDQWdJSFJvYVhNdWNHRnBiblJpY25WemFDQTlJR1poYkhObE8xeHVYRzRnSUNBZ2RHaHBjeTVwYm1sMEtDazdYRzRnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmx4dUlDQjlYRzVjYmlBZ1luVnBiR1JHY21GdFpTZ3BJSHRjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblFnUFNCemRtY3VZM0psWVhSbEtDZHpkbWNuS1R0Y2JpQWdJQ0IwYUdsekxtVnNaVzFsYm5RdWMyVjBRWFIwY21saWRYUmxLQ2QzYVdSMGFDY3NkR2hwY3k1M2FXUjBhQ2s3WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG5ObGRFRjBkSEpwWW5WMFpTZ25hR1ZwWjJoMEp5eDBhR2x6TG1obGFXZG9kQ2s3WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG5OMGVXeGxMblJ2Y0NBOUlDY3djSGduTzF4dUlDQWdJSFJvYVhNdVpXeGxiV1Z1ZEM1emRIbHNaUzVzWldaMElEMGdKekJ3ZUNjN1hHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExuTjBlV3hsTG5CdmMybDBhVzl1SUQwZ0oyRmljMjlzZFhSbEp6dGNiaUFnSUNCMGFHbHpMbkJoY21WdWRDNWhjSEJsYm1SRGFHbHNaQ2gwYUdsekxtVnNaVzFsYm5RcE8xeHVJQ0I5WEc1Y2JpQWdZblZwYkdSSmJuUmxjbVpoWTJVb0tTQjdYRzVjYmlBZ0lDQjBhR2x6TG5CaFpDQTlJSE4yWnk1amNtVmhkR1VvSjNKbFkzUW5LVHRjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1WVhCd1pXNWtRMmhwYkdRb2RHaHBjeTV3WVdRcE8xeHVYRzRnSUNBZ2RHaHBjeTVwYm5SbGNtRmpkR2x2YmxSaGNtZGxkQ0E5SUhSb2FYTXVjR0ZrTzF4dVhHNGdJQ0FnTHlvZ1pYWmxiblJ6SUNvdlhHNWNiaUFnSUNCcFppQW9JWFJ2ZFdOb0xtVjRhWE4wY3lrZ2UxeHVYRzRnSUNBZ0lDQjBhR2x6TG1Oc2FXTnJJRDBnS0NrZ1BUNGdlMXh1SUNBZ0lDQWdJQ0IwYUdsekxtMWhkSEpwZUM1cGJuUmxjbUZqZEdsdVp5QTlJSFJ5ZFdVN1hHNGdJQ0FnSUNBZ0lIUm9hWE11YldGMGNtbDRMbkJoYVc1MFluSjFjMmdnUFNBaGRHaHBjeTV6ZEdGMFpUdGNiaUFnSUNBZ0lDQWdkR2hwY3k1a2IzZHVLSFJvYVhNdWJXRjBjbWw0TG5CaGFXNTBZbkoxYzJncE8xeHVJQ0FnSUNBZ2ZUdGNiaUFnSUNBZ0lIUm9hWE11Y0dGa0xtRmtaRVYyWlc1MFRHbHpkR1Z1WlhJb0oyMXZkWE5sYjNabGNpY3NJQ2dwSUQwK0lIdGNiaUFnSUNBZ0lDQWdhV1lnS0hSb2FYTXViV0YwY21sNExtbHVkR1Z5WVdOMGFXNW5LU0I3WEc0Z0lDQWdJQ0FnSUNBZ2RHaHBjeTVrYjNkdUtIUm9hWE11YldGMGNtbDRMbkJoYVc1MFluSjFjMmdwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNCOUtUdGNibHh1WEc0Z0lDQWdJQ0IwYUdsekxtMXZkbVVnUFNBb0tTQTlQaUI3WEc0Z0lDQWdJQ0I5TzF4dUlDQWdJQ0FnZEdocGN5NXdZV1F1WVdSa1JYWmxiblJNYVhOMFpXNWxjaWduYlc5MWMyVnRiM1psSnl3Z0tHVXBJRDArSUh0Y2JpQWdJQ0FnSUNBZ2FXWWdLSFJvYVhNdWJXRjBjbWw0TG1sdWRHVnlZV04wYVc1bktTQjdYRzRnSUNBZ0lDQWdJQ0FnYVdZZ0tDRjBhR2x6TG05bVpuTmxkQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdkR2hwY3k1dlptWnpaWFFnUFNCa2IyMHVabWx1WkZCdmMybDBhVzl1S0hSb2FYTXVaV3hsYldWdWRDazdYRzRnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lIUm9hWE11Ylc5MWMyVWdQU0JrYjIwdWJHOWpZWFJsVFc5MWMyVW9aU3gwYUdsekxtOW1abk5sZENrN1hHNGdJQ0FnSUNBZ0lDQWdkR2hwY3k1aVpXNWtLQ2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUgwcE8xeHVYRzVjYmlBZ0lDQWdJSFJvYVhNdWNtVnNaV0Z6WlNBOUlDZ3BJRDArSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTV0WVhSeWFYZ3VhVzUwWlhKaFkzUnBibWNnUFNCbVlXeHpaVHRjYmlBZ0lDQWdJSDA3WEc0Z0lDQWdJQ0IwYUdsekxuQmhaQzVoWkdSRmRtVnVkRXhwYzNSbGJtVnlLQ2R0YjNWelpYVndKeXdnS0NrZ1BUNGdlMXh1SUNBZ0lDQWdJQ0JwWmlBb2RHaHBjeTV0WVhSeWFYZ3VhVzUwWlhKaFkzUnBibWNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQjBhR2x6TG5Wd0tDazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJSDBwTzF4dUlDQWdJQ0FnZEdocGN5NXdZV1F1WVdSa1JYWmxiblJNYVhOMFpXNWxjaWduYlc5MWMyVnZkWFFuTENBb0tTQTlQaUI3WEc0Z0lDQWdJQ0FnSUdsbUlDaDBhR2x6TG0xaGRISnBlQzVwYm5SbGNtRmpkR2x1WnlrZ2UxeHVJQ0FnSUNBZ0lDQWdJSFJvYVhNdWRYQW9LVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnZlNrN1hHNGdJQ0FnZlZ4dVhHNGdJSDFjYmx4dUlDQnphWHBsU1c1MFpYSm1ZV05sS0NrZ2UxeHVYRzRnSUNBZ2RHaHBjeTV3WVdRdWMyVjBRWFIwY21saWRYUmxLQ2Q0Snl3eEtUdGNiaUFnSUNCMGFHbHpMbkJoWkM1elpYUkJkSFJ5YVdKMWRHVW9KM2tuTERFcE8xeHVJQ0FnSUdsbUlDaDBhR2x6TG5kcFpIUm9JRDRnTWlrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTV3WVdRdWMyVjBRWFIwY21saWRYUmxLQ2QzYVdSMGFDY3NJSFJvYVhNdWQybGtkR2dnTFNBeUtUdGNiaUFnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnZEdocGN5NXdZV1F1YzJWMFFYUjBjbWxpZFhSbEtDZDNhV1IwYUNjc0lIUm9hWE11ZDJsa2RHZ3BPMXh1SUNBZ0lIMWNiaUFnSUNCcFppQW9kR2hwY3k1b1pXbG5hSFFnUGlBeUtTQjdYRzRnSUNBZ0lDQjBhR2x6TG5CaFpDNXpaWFJCZEhSeWFXSjFkR1VvSjJobGFXZG9kQ2NzSUhSb2FYTXVhR1ZwWjJoMElDMGdNaWs3WEc0Z0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lIUm9hWE11Y0dGa0xuTmxkRUYwZEhKcFluVjBaU2duYUdWcFoyaDBKeXdnZEdocGN5NW9aV2xuYUhRcE8xeHVJQ0FnSUgxY2JpQWdJQ0F2TDNSb2FYTXVjR0ZrTG5ObGRFRjBkSEpwWW5WMFpTZ25hR1ZwWjJoMEp5d2dkR2hwY3k1b1pXbG5hSFFnTFNBeUtUdGNiaUFnSUNCMGFHbHpMbkJoWkM1elpYUkJkSFJ5YVdKMWRHVW9KMlpwYkd3bkxDQjBhR2x6TG0xaGRISnBlQzVqYjJ4dmNuTXVabWxzYkNrN1hHNWNiaUFnZlZ4dVhHNGdJSEpsYm1SbGNpZ3BJSHRjYmlBZ0lDQnBaaUFvSVhSb2FYTXVjM1JoZEdVcElIdGNiaUFnSUNBZ0lIUm9hWE11Y0dGa0xuTmxkRUYwZEhKcFluVjBaU2duWm1sc2JDY3NJSFJvYVhNdWJXRjBjbWw0TG1OdmJHOXljeTVtYVd4c0tUdGNiaUFnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnZEdocGN5NXdZV1F1YzJWMFFYUjBjbWxpZFhSbEtDZG1hV3hzSnl3Z2RHaHBjeTV0WVhSeWFYZ3VZMjlzYjNKekxtRmpZMlZ1ZENrN1hHNGdJQ0FnZlZ4dUlDQjlYRzVjYm4xY2JseHVMeW9xWEc0cUlGTmxjWFZsYm1ObGNseHVLbHh1S2lCQVpHVnpZM0pwY0hScGIyNGdSM0pwWkNCdlppQmlkWFIwYjI1eklIZHBkR2dnWW5WcGJIUXRhVzRnYzNSbGNDQnpaWEYxWlc1alpYSXVYRzRxWEc0cUlFQmtaVzF2SUR4a2FYWWdibVY0ZFhNdGRXazlYQ0p6WlhGMVpXNWpaWEpjSWlCemRIbHNaVDFjSW5kcFpIUm9PalF3TUhCNE8yaGxhV2RvZERveU1EQndlRHRjSWo0OEwyUnBkajVjYmlwY2Jpb2dRR1Y0WVcxd2JHVmNiaW9nZG1GeUlITmxjWFZsYm1ObGNpQTlJRzVsZHlCT1pYaDFjeTVUWlhGMVpXNWpaWElvSnlOMFlYSm5aWFFuS1Z4dUtseHVLaUJBWlhoaGJYQnNaVnh1S2lCMllYSWdjMlZ4ZFdWdVkyVnlJRDBnYm1WM0lFNWxlSFZ6TGxObGNYVmxibU5sY2lnbkkzUmhjbWRsZENjc2UxeHVLaUFnSjNOcGVtVW5PaUJiTkRBd0xESXdNRjBzWEc0cUlDQW5iVzlrWlNjNklDZDBiMmRuYkdVbkxGeHVLaUFnSjNKdmQzTW5PaUExTEZ4dUtpQWdKMk52YkhWdGJuTW5PaUF4TUZ4dUtuMHBYRzRxWEc0cUlFQnZkWFJ3ZFhSY2Jpb2dZMmhoYm1kbFhHNHFJRVpwY21WeklHRnVlU0IwYVcxbElIUm9aU0JwYm5SbGNtWmhZMlVuY3lCdFlYUnlhWGdnWTJoaGJtZGxjeTRnUEdKeVBseHVLaUJVYUdVZ1pYWmxiblFnWkdGMFlTQnBjeUJoYmlCdlltcGxZM1FnWTI5dWRHRnBibWx1WnlBOGFUNXliM2M4TDJrK0lDaHVkVzFpWlhJcExDQThhVDVqYjJ4MWJXNDhMMmsrSUNodWRXMWlaWElwTENCaGJtUWdQR2srYzNSaGRHVThMMmsrSUNoaWIyOXNaV0Z1S1NCd2NtOXdaWEowYVdWekxseHVLbHh1S2lCQWIzVjBjSFYwWlhoaGJYQnNaVnh1S2lCelpYRjFaVzVqWlhJdWIyNG9KMk5vWVc1blpTY3NablZ1WTNScGIyNG9kaWtnZTF4dUtpQWdJR052Ym5OdmJHVXViRzluS0hZcE8xeHVLaUI5S1Z4dUtseHVLaUJBYjNWMGNIVjBYRzRxSUhOMFpYQmNiaW9nUm1seVpYTWdZVzU1SUhScGJXVWdkR2hsSUhObGNYVmxibU5sY2lCemRHVndjeUIwYnlCMGFHVWdibVY0ZENCamIyeDFiVzRzSUdsdUlITmxjWFZsWTJVZ2JXOWtaUzRnUEdKeVBseHVLaUJVYUdVZ1pYWmxiblFnWkdGMFlTQnBjeUJoYmlBOGFUNWhjbkpoZVR3dmFUNGdZMjl1ZEdGcGJtbHVaeUJoYkd3Z2RtRnNkV1Z6SUdsdUlIUm9aU0JqYjJ4MWJXNHNJRHhwUG1KdmRIUnZiU0J5YjNjZ1ptbHljM1E4TDJrK0xseHVLbHh1S2lCQWIzVjBjSFYwWlhoaGJYQnNaVnh1S2lCelpYRjFaVzVqWlhJdWIyNG9KM04wWlhBbkxHWjFibU4wYVc5dUtIWXBJSHRjYmlvZ0lDQmpiMjV6YjJ4bExteHZaeWgyS1R0Y2Jpb2dmU2xjYmlvdlhHNWNibVY0Y0c5eWRDQmtaV1poZFd4MElHTnNZWE56SUZObGNYVmxibU5sY2lCbGVIUmxibVJ6SUVsdWRHVnlabUZqWlNCN1hHNWNiaUFnWTI5dWMzUnlkV04wYjNJb0tTQjdYRzVjYmlBZ0lDQnNaWFFnYjNCMGFXOXVjeUE5SUZzbmRtRnNkV1VuWFR0Y2JseHVJQ0FnSUd4bGRDQmtaV1poZFd4MGN5QTlJSHRjYmlBZ0lDQWdJQ2R6YVhwbEp6b2dXelF3TUN3eU1EQmRMRnh1SUNBZ0lDQWdKMjF2WkdVbk9pQW5kRzluWjJ4bEp5eGNiaUFnSUNBZ0lDZHliM2R6SnpvZ05TeGNiaUFnSUNBZ0lDZGpiMngxYlc1ekp6b2dNVEJjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdjM1Z3WlhJb1lYSm5kVzFsYm5SekxHOXdkR2x2Ym5Nc1pHVm1ZWFZzZEhNcE8xeHVYRzRnSUNBZ2RHaHBjeTVoWTNScGRtVWdQU0F0TVR0Y2JseHVJQ0FnSUM4cUtseHVJQ0FnSUNvZ1FuVjBkRzl1SUdsdWRHVnlZV04wYVc5dUlHMXZaR1U2SUhObFpTQkNkWFIwYjI1Y2JpQWdJQ0FxSUVCMGVYQmxJSHR6ZEhKcGJtZDlYRzRnSUNBZ0tpQkFaWGhoYlhCc1pTQmlkWFIwYjI0dWJXOWtaU0E5SUNkMGIyZG5iR1VuTzF4dUlDQWdJQ292WEc0Z0lDQWdkR2hwY3k1dGIyUmxJRDBnZEdocGN5NXpaWFIwYVc1bmN5NXRiMlJsTzF4dVhHNGdJQ0FnTHlvcVhHNGdJQ0FnS2lCVWFHVWdhVzUwWlhKMllXd2diMkpxWldOMElIZG9hV05vSUdOdmJuUnliMnh6SUhScGJXbHVaeUJoYm1RZ2MyVnhkV1Z1WTJVZ2MyTm9aV1IxYkdsdVp5NWNiaUFnSUNBcUlFQjBlWEJsSUh0cGJuUmxjblpoYkgxY2JpQWdJQ0FxTDF4dUlDQWdJSFJvYVhNdWFXNTBaWEoyWVd3Z1BTQnVaWGNnVG1WNGRYTXVTVzUwWlhKMllXd29NakF3TEdaMWJtTjBhVzl1S0NrZ2UzMHNabUZzYzJVcE95QXZMeUJxYzJocGJuUWdhV2R1YjNKbE9teHBibVZjYmx4dUlDQWdJQzhxS2x4dUlDQWdJQ29nUVNCTllYUnlhWGdnYlc5a1pXd2dZMjl1ZEdGcGJtbHVaeUJ0WlhSb2IyUnpJR1p2Y2lCdFlXNXBjSFZzWVhScGJtY2dkR2hsSUhObGNYVmxibU5sY2lkeklHRnljbUY1SUc5bUlIWmhiSFZsY3k0Z1ZHOGdiR1ZoY200Z2FHOTNJSFJ2SUcxaGJtbHdkV3hoZEdVZ2RHaGxJRzFoZEhKcGVDd2djbVZoWkNCaFltOTFkQ0IwYUdVZ2JXRjBjbWw0SUcxdlpHVnNMbHh1SUNBZ0lDb2dRSFI1Y0dVZ2UyMWhkSEpwZUgxY2JpQWdJQ0FxTDF4dUlDQWdJSFJvYVhNdWJXRjBjbWw0SUQwZ2JtVjNJRTFoZEhKcGVFMXZaR1ZzS0hSb2FYTXVjMlYwZEdsdVozTXVjbTkzY3l4MGFHbHpMbk5sZEhScGJtZHpMbU52YkhWdGJuTXBPMXh1SUNBZ0lIUm9hWE11YldGMGNtbDRMblZwSUQwZ2RHaHBjenRjYmx4dUlDQWdJQzhxS2x4dUlDQWdJQ29nUVNCRGIzVnVkR1Z5SUcxdlpHVnNJSGRvYVdOb0lIUm9aU0J6WlhGMVpXNWpaWElnYzNSbGNITWdkR2h5YjNWbmFDNGdSbTl5SUdWNFlXMXdiR1VzSUhsdmRTQmpiM1ZzWkNCMWMyVWdkR2hwY3lCdGIyUmxiQ0IwYnlCemRHVndJSFJvY205MVoyZ2dkR2hsSUhObGNYVmxibU5sY2lCcGJpQnlaWFpsY25ObExDQnlZVzVrYjIxc2VTd2diM0lnYVc0Z1lTQmtjblZ1YXlCM1lXeHJMbHh1SUNBZ0lDb2dRSFI1Y0dVZ2UyTnZkVzUwWlhKOVhHNGdJQ0FnS2k5Y2JpQWdJQ0IwYUdsekxuTjBaWEJ3WlhJZ1BTQnVaWGNnUTI5MWJuUmxjazF2WkdWc0tEQXNkR2hwY3k1amIyeDFiVzV6S1R0Y2JseHVJQ0FnSUhSb2FYTXVhVzVwZENncE8xeHVYRzRnSUgxY2JseHVJQ0JpZFdsc1pFWnlZVzFsS0NrZ2UxeHVJQ0FnSUhSb2FYTXVaV3hsYldWdWRDQTlJR1J2WTNWdFpXNTBMbU55WldGMFpVVnNaVzFsYm5Rb0oyUnBkaWNwTzF4dUlDQWdJSFJvYVhNdVpXeGxiV1Z1ZEM1emRIbHNaUzV3YjNOcGRHbHZiaUE5SUNkeVpXeGhkR2wyWlNjN1hHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExuTjBlV3hsTG1ScGMzQnNZWGtnUFNBbllteHZZMnNuTzF4dUlDQWdJSFJvYVhNdVpXeGxiV1Z1ZEM1emRIbHNaUzUzYVdSMGFDQTlJQ2N4TURBbEp6dGNiaUFnSUNCMGFHbHpMbVZzWlcxbGJuUXVjM1I1YkdVdWFHVnBaMmgwSUQwZ0p6RXdNQ1VuTzF4dUlDQWdJSFJvYVhNdWNHRnlaVzUwTG1Gd2NHVnVaRU5vYVd4a0tIUm9hWE11Wld4bGJXVnVkQ2s3WEc0Z0lDQWdhV1lnS0hSdmRXTm9MbVY0YVhOMGN5a2dlMXh1SUNBZ0lDQWdkR2hwY3k1aFpHUlViM1ZqYUV4cGMzUmxibVZ5Y3lncE8xeHVJQ0FnSUgxY2JpQWdmVnh1WEc0Z0lHSjFhV3hrU1c1MFpYSm1ZV05sS0NrZ2UxeHVYRzRnSUNBZ2RHaHBjeTVqWld4c2N5QTlJRnRkTzF4dUlDQWdJR1p2Y2lBb2JHVjBJR2s5TUR0cFBIUm9hWE11YldGMGNtbDRMbXhsYm1kMGFEdHBLeXNwSUh0Y2JseHVJQ0FnSUNBZ2JHVjBJR3h2WTJGMGFXOXVJRDBnZEdocGN5NXRZWFJ5YVhndWJHOWpZWFJsS0drcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnTHk4Z2NtVjBkWEp1Y3lCN2NtOTNMR052YkgxY2JseHVJQ0FnSUNBZ2JHVjBJR052Ym5SaGFXNWxjaUE5SUdSdlkzVnRaVzUwTG1OeVpXRjBaVVZzWlcxbGJuUW9KM053WVc0bktUdGNiaUFnSUNBZ0lHTnZiblJoYVc1bGNpNXpkSGxzWlM1d2IzTnBkR2x2YmlBOUlDZGhZbk52YkhWMFpTYzdYRzVjYmx4dUlDQWdJQ0FnYkdWMElHTmxiR3dnUFNCdVpYY2dUV0YwY21sNFEyVnNiQ2hqYjI1MFlXbHVaWElzSUh0Y2JpQWdJQ0FnSUNBZ0lDQmpiMjF3YjI1bGJuUTZJSFJ5ZFdVc1hHNGdJQ0FnSUNBZ0lDQWdhVzVrWlhnNklHa3NYRzRnSUNBZ0lDQWdJQ0FnY205M09pQnNiMk5oZEdsdmJpNXliM2NzWEc0Z0lDQWdJQ0FnSUNBZ1kyOXNkVzF1T2lCc2IyTmhkR2x2Ymk1amIyeDFiVzRzWEc0Z0lDQWdJQ0FnSUNBZ2JXOWtaVG9nZEdocGN5NXRiMlJsTEZ4dUlDQWdJQ0FnSUNBZ0lHMWhkSEpwZURvZ2RHaHBjMXh1SUNBZ0lDQWdJQ0I5TENCMGFHbHpMbXRsZVVOb1lXNW5aUzVpYVc1a0tIUm9hWE1zYVNrcE8xeHVYRzRnSUNBZ0x5OGdJR05sYkd3dWJXRjBjbWw0SUQwZ2RHaHBjenRjYmlBZ0lDQWdJR2xtSUNoMGIzVmphQzVsZUdsemRITXBJSHRjYmlBZ0lDQWdJQ0FnWTJWc2JDNXdZV1F1YVc1a1pYZ2dQU0JwTzF4dUlDQWdJQ0FnSUNCalpXeHNMbkJ5WlVOc2FXTnJJRDBnWTJWc2JDNXdjbVZOYjNabElEMGdZMlZzYkM1d2NtVlNaV3hsWVhObElEMGdLQ2tnUFQ0Z2UzMDdYRzRnSUNBZ0lDQWdJR05sYkd3dVkyeHBZMnNnUFNCalpXeHNMbTF2ZG1VZ1BTQmpaV3hzTG5KbGJHVmhjMlVnUFNBb0tTQTlQaUI3ZlR0Y2JpQWdJQ0FnSUNBZ1kyVnNiQzV3Y21WVWIzVmphQ0E5SUdObGJHd3VjSEpsVkc5MVkyaE5iM1psSUQwZ1kyVnNiQzV3Y21WVWIzVmphRkpsYkdWaGMyVWdQU0FvS1NBOVBpQjdmVHRjYmlBZ0lDQWdJQ0FnWTJWc2JDNTBiM1ZqYUNBOUlHTmxiR3d1ZEc5MVkyaE5iM1psSUQwZ1kyVnNiQzUwYjNWamFGSmxiR1ZoYzJVZ1BTQW9LU0E5UGlCN2ZUdGNiaUFnSUNBZ0lIMWNibHh1SUNBZ0lDQWdkR2hwY3k1alpXeHNjeTV3ZFhOb0tHTmxiR3dwTzF4dUlDQWdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExtRndjR1Z1WkVOb2FXeGtLR052Ym5SaGFXNWxjaWs3WEc1Y2JpQWdJQ0I5WEc0Z0lDQWdkR2hwY3k1emFYcGxTVzUwWlhKbVlXTmxLQ2s3WEc0Z0lIMWNibHh1SUNCemFYcGxTVzUwWlhKbVlXTmxLQ2tnZTF4dVhHNGdJQ0FnYkdWMElHTmxiR3hYYVdSMGFDQTlJSFJvYVhNdWQybGtkR2dnTHlCMGFHbHpMbU52YkhWdGJuTTdYRzRnSUNBZ2JHVjBJR05sYkd4SVpXbG5hSFFnUFNCMGFHbHpMbWhsYVdkb2RDQXZJSFJvYVhNdWNtOTNjenRjYmx4dUlDQWdJR1p2Y2lBb2JHVjBJR2s5TURzZ2FUeDBhR2x6TG1ObGJHeHpMbXhsYm1kMGFEc2dhU3NyS1NCN1hHNGdJQ0FnSUNCc1pYUWdZMjl1ZEdGcGJtVnlJRDBnZEdocGN5NWpaV3hzYzF0cFhTNXdZWEpsYm5RN1hHNGdJQ0FnSUNCamIyNTBZV2x1WlhJdWMzUjViR1V1YkdWbWRDQTlJSFJvYVhNdVkyVnNiSE5iYVYwdVkyOXNkVzF1SUNvZ1kyVnNiRmRwWkhSb0lDc2dKM0I0Snp0Y2JpQWdJQ0FnSUdOdmJuUmhhVzVsY2k1emRIbHNaUzUwYjNBZ1BTQjBhR2x6TG1ObGJHeHpXMmxkTG5KdmR5QXFJR05sYkd4SVpXbG5hSFFnS3lBbmNIZ25PMXh1SUNBZ0lDQWdkR2hwY3k1alpXeHNjMXRwWFM1eVpYTnBlbVVvWTJWc2JGZHBaSFJvTEdObGJHeElaV2xuYUhRcE8xeHVJQ0FnSUgxY2JseHVYRzRnSUgxY2JseHVJQ0JqYjJ4dmNrbHVkR1Z5Wm1GalpTZ3BJSHRjYmlBZ0lDQm1iM0lnS0haaGNpQnBQVEE3SUdrOGRHaHBjeTVqWld4c2N5NXNaVzVuZEdnN0lHa3JLeWtnZTF4dUlDQWdJQ0FnZEdocGN5NWpaV3hzYzF0cFhTNXlaVzVrWlhJb0tUdGNiaUFnSUNCOVhHNGdJSDFjYmx4dUlDQjFjR1JoZEdVb0tTQjdYRzRnSUM4dklDQmpiMjV6YjJ4bExteHZaeWhjSW5Wd1pHRjBhVzVuTGk0dVhDSXBYRzRnSUNBZ0x5OXZiaUE5SUc5dUlIeDhJR1poYkhObE8xeHVJQ0FnSUhSb2FYTXViV0YwY21sNExtbDBaWEpoZEdVb0tISXNZeXhwS1NBOVBpQjdYRzRnSUNBZ0lDQXZMeUFnWTI5dWMyOXNaUzVzYjJjb2RHaHBjeTV0WVhSeWFYZ3VjR0YwZEdWeWJsdHlYVnRqWFN3Z2RHaHBjeTVqWld4c2MxdHBYUzV6ZEdGMFpTazdYRzRnSUNBZ0lDQnBaaUFvZEdocGN5NXRZWFJ5YVhndWNHRjBkR1Z5Ymx0eVhWdGpYU0FoUFQwZ2RHaHBjeTVqWld4c2MxdHBYUzV6ZEdGMFpTa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2RHaHBjeTV0WVhSeWFYZ3VjR0YwZEdWeWJsdHlYVnRqWFNBK0lEQXBJSHRjYmlBZ0lDQWdJQ0FnSUNCMGFHbHpMbU5sYkd4elcybGRMblIxY201UGJpZ3BPMXh1SUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUhSb2FYTXVZMlZzYkhOYmFWMHVkSFZ5Yms5bVppZ3BPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdmU2s3WEc0Z0lIMWNibHh1THk4Z2RYQmtZWFJsSUQwK0lHTmxiR3d1ZEhWeWJrOXVJRDArSUdObGJHd3VaVzFwZENBOVBpQnJaWGxEYUdGdVoyVWdLSE5sY1M1bGJXbDBLU0E5UGlCdFlYUnlhWGd1YzJWMExtTmxiR3dnUFQ0Z2RYQmtZWFJsWEc0dkwxeHVMeThnYVc1MFpYSmhZM1JwYjI0Z1BUNGdhMlY1UTJoaGJtZGxJRDArSUcxaGRISnBlQzV6WlhRdVkyVnNiQ0E5UGlCMWNHUmhkR1VnUFQ0Z1kyVnNiQzUwZFhKdVQyNWNiaTh2SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnUFQ0Z1pXMXBkRnh1THk5Y2JpOHZJSE5sZEM1alpXeHNJRDArSUhWd1pHRjBaU0E5UGlCdVpXVmtjeUIwYnlCbGJXbDBMbHh1WEc0Z0lHdGxlVU5vWVc1blpTaHViM1JsTEc5dUtTQjdYRzRnSUNBZ0x5OGdaVzFwZENCa1lYUmhJR1p2Y2lCaGJua2dhMlY1SUhSMWNtNXBibWNnYjI0dmIyWm1YRzRnSUNBZ0x5OGdhU0JwY3lCMGFHVWdibTkwWlNCcGJtUmxlRnh1SUNBZ0lDOHZJSFlnYVhNZ2QyaGxkR2hsY2lCcGRDQnBjeUJ2YmlCdmNpQnZabVpjYmlBZ0lDQnNaWFFnWTJWc2JDQTlJSFJvYVhNdWJXRjBjbWw0TG14dlkyRjBaU2h1YjNSbEtUdGNiaUFnTHk4Z0lIUm9hWE11YldGMGNtbDRMbk5sZEM1alpXeHNLR05sYkd3dVkyOXNkVzF1TEdObGJHd3VjbTkzTEc5dUtUdGNiaUFnSUNCMGFHbHpMbTFoZEhKcGVDNXdZWFIwWlhKdVcyTmxiR3d1Y205M1hWdGpaV3hzTG1OdmJIVnRibDBnUFNCdmJqdGNiaUFnSUNCMllYSWdaR0YwWVNBOUlIdGNiaUFnSUNBZ0lISnZkem9nWTJWc2JDNXliM2NzWEc0Z0lDQWdJQ0JqYjJ4MWJXNDZJR05sYkd3dVkyOXNkVzF1TEZ4dUlDQWdJQ0FnYzNSaGRHVTZJRzl1WEc0Z0lDQWdmVHRjYmlBZ0lDQjBhR2x6TG1WdGFYUW9KMk5vWVc1blpTY3NaR0YwWVNrN1hHNGdJSDFjYmx4dUlDQnlaVzVrWlhJb0tTQjdYRzRnSUNBZ2FXWWdLSFJvYVhNdWMzUmxjSEJsY2k1MllXeDFaU0ErUFNBd0tTQjdYRzRnSUNBZ0lDQjBhR2x6TG0xaGRISnBlQzVwZEdWeVlYUmxLQ2h5TEdNc2FTa2dQVDRnZTF4dUlDQWdJQ0FnSUNCcFppQW9ZejA5UFhSb2FYTXVjM1JsY0hCbGNpNTJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJSFJvYVhNdVkyVnNiSE5iYVYwdWNHRmtMbk5sZEVGMGRISnBZblYwWlNnbmMzUnliMnRsSnl4MGFHbHpMbU52Ykc5eWN5NXRaV1JwZFcxTWFXZG9kQ2s3WEc0Z0lDQWdJQ0FnSUNBZ2RHaHBjeTVqWld4c2MxdHBYUzV3WVdRdWMyVjBRWFIwY21saWRYUmxLQ2R6ZEhKdmEyVXRkMmxrZEdnbkxDY3hKeWs3WEc0Z0lDQWdJQ0FnSUNBZ2RHaHBjeTVqWld4c2MxdHBYUzV3WVdRdWMyVjBRWFIwY21saWRYUmxLQ2R6ZEhKdmEyVXRiM0JoWTJsMGVTY3NKekVuS1R0Y2JpQWdJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ0lDQjBhR2x6TG1ObGJHeHpXMmxkTG5CaFpDNXpaWFJCZEhSeWFXSjFkR1VvSjNOMGNtOXJaU2NzSjI1dmJtVW5LVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnZlNrN1hHNGdJQ0FnZlZ4dUlDQjlYRzVjYmlBZ0x5b3FYRzRnSUNBcUlGTjBZWEowSUhObGNYVmxibU5wYm1kY2JpQWdJQ29nUUhCaGNtRnRJQ0I3Ym5WdFltVnlmU0J0Y3lCQ1pXRjBJSFJsYlhCdklHbHVJRzFwYkd4cGMyVmpiMjVrYzF4dUlDQWdLaTljYmlBZ2MzUmhjblFvYlhNcElIdGNiaUFnSUNCMGFHbHpMbWx1ZEdWeWRtRnNMbVYyWlc1MElEMGdkR2hwY3k1dVpYaDBMbUpwYm1Rb2RHaHBjeWs3WEc0Z0lDQWdhV1lnS0cxektTQjdYRzRnSUNBZ0lDQjBhR2x6TG1sdWRHVnlkbUZzTG0xektHMXpLVHRjYmlBZ0lDQjlYRzRnSUNBZ2RHaHBjeTVwYm5SbGNuWmhiQzV6ZEdGeWRDZ3BPMXh1SUNCOVhHNWNiaUFnTHlvcVhHNGdJRk4wYjNBZ2MyVnhkV1Z1WTJsdVoxeHVJQ0FxTDF4dUlDQnpkRzl3S0NrZ2UxeHVJQ0FnSUhSb2FYTXVhVzUwWlhKMllXd3VjM1J2Y0NncE8xeHVJQ0I5WEc1Y2JpQWdMeW9xWEc0Z0lFMWhiblZoYkd4NUlHcDFiWEFnZEc4Z2RHaGxJRzVsZUhRZ1kyOXNkVzF1SUdGdVpDQjBjbWxuWjJWeUlIUm9aU0FuWTJoaGJtZGxKeUJsZG1WdWRDNGdWR2hsSUZ3aWJtVjRkRndpSUdOdmJIVnRiaUJwY3lCa1pYUmxjbTFwYm1Wa0lHSjVJSGx2ZFhJZ2JXOWtaU0J2WmlCelpYRjFaVzVqYVc1bkxseHVJQ0FxTDF4dUlDQnVaWGgwS0NrZ2UxeHVJQ0FnSUhSb2FYTXVjM1JsY0hCbGNpNXVaWGgwS0NrN1hHNGdJQ0FnZEdocGN5NWxiV2wwS0NkemRHVndKeXgwYUdsekxtMWhkSEpwZUM1amIyeDFiVzRvZEdocGN5NXpkR1Z3Y0dWeUxuWmhiSFZsS1M1eVpYWmxjbk5sS0NrcE8xeHVJQ0FnSUhSb2FYTXVjbVZ1WkdWeUtDazdYRzRnSUgxY2JseHVJQ0JoWkdSVWIzVmphRXhwYzNSbGJtVnljeWdwSUh0Y2JseHVJQ0FnSUhSb2FYTXVjSEpsUTJ4cFkyc2dQU0IwYUdsekxuQnlaVTF2ZG1VZ1BTQjBhR2x6TG5CeVpWSmxiR1ZoYzJVZ1BTQW9LU0E5UGlCN2ZUdGNiaUFnSUNCMGFHbHpMbU5zYVdOcklEMGdkR2hwY3k1dGIzWmxJRDBnZEdocGN5NXlaV3hsWVhObElEMGdLQ2tnUFQ0Z2UzMDdYRzRnSUNBZ2RHaHBjeTV3Y21WVWIzVmphQ0E5SUhSb2FYTXVjSEpsVkc5MVkyaE5iM1psSUQwZ2RHaHBjeTV3Y21WVWIzVmphRkpsYkdWaGMyVWdQU0FvS1NBOVBpQjdmVHRjYmlBZ0lDQjBhR2x6TG5SdmRXTm9JRDBnZEdocGN5NTBiM1ZqYUUxdmRtVWdQU0IwYUdsekxuUnZkV05vVW1Wc1pXRnpaU0E5SUNncElEMCtJSHQ5TzF4dVhHNGdJQ0FnZEdocGN5NWpkWEp5Wlc1MFJXeGxiV1Z1ZENBOUlHWmhiSE5sTzF4dVhHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExtRmtaRVYyWlc1MFRHbHpkR1Z1WlhJb0ozUnZkV05vYzNSaGNuUW5MQ0FvWlNrZ1BUNGdlMXh1SUNBZ0lDQWdiR1YwSUdWc1pXMWxiblFnUFNCa2IyTjFiV1Z1ZEM1bGJHVnRaVzUwUm5KdmJWQnZhVzUwS0dVdWRHRnlaMlYwVkc5MVkyaGxjMXN3WFM1amJHbGxiblJZTEdVdWRHRnlaMlYwVkc5MVkyaGxjMXN3WFM1amJHbGxiblJaS1R0Y2JpQWdJQ0FnSUd4bGRDQmpaV3hzSUQwZ2RHaHBjeTVqWld4c2MxdGxiR1Z0Wlc1MExtbHVaR1Y0WFR0Y2JpQWdJQ0FnSUhSb2FYTXVjR0ZwYm5SaWNuVnphQ0E5SUNGalpXeHNMbk4wWVhSbE8xeHVJQ0FnSUNBZ1kyVnNiQzVrYjNkdUtIUm9hWE11Y0dGcGJuUmljblZ6YUNrN1hHNGdJQ0FnSUNCMGFHbHpMbU4xY25KbGJuUkZiR1Z0Wlc1MElEMGdaV3hsYldWdWRDNXBibVJsZUR0Y2JpQWdJQ0FnSUdVdWNISmxkbVZ1ZEVSbFptRjFiSFFvS1R0Y2JpQWdJQ0FnSUdVdWMzUnZjRkJ5YjNCaFoyRjBhVzl1S0NrN1hHNGdJQ0FnZlNrN1hHNWNiaUFnSUNCMGFHbHpMbVZzWlcxbGJuUXVZV1JrUlhabGJuUk1hWE4wWlc1bGNpZ25kRzkxWTJodGIzWmxKeXdnS0dVcElEMCtJSHRjYmlBZ0lDQWdJR3hsZENCbGJHVnRaVzUwSUQwZ1pHOWpkVzFsYm5RdVpXeGxiV1Z1ZEVaeWIyMVFiMmx1ZENobExuUmhjbWRsZEZSdmRXTm9aWE5iTUYwdVkyeHBaVzUwV0N4bExuUmhjbWRsZEZSdmRXTm9aWE5iTUYwdVkyeHBaVzUwV1NrN1hHNGdJQ0FnSUNCc1pYUWdZMlZzYkNBOUlIUm9hWE11WTJWc2JITmJaV3hsYldWdWRDNXBibVJsZUYwN1hHNGdJQ0FnSUNCcFppQW9aV3hsYldWdWRDNXBibVJsZUNFOVBYUm9hWE11WTNWeWNtVnVkRVZzWlcxbGJuUXBJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tIUm9hWE11WTNWeWNtVnVkRVZzWlcxbGJuUWdQajBnTUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJR3hsZENCd1lYTjBRMlZzYkNBOUlIUm9hWE11WTJWc2JITmJkR2hwY3k1amRYSnlaVzUwUld4bGJXVnVkRjA3WEc0Z0lDQWdJQ0FnSUNBZ2NHRnpkRU5sYkd3dWRYQW9LVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCalpXeHNMbVJ2ZDI0b2RHaHBjeTV3WVdsdWRHSnlkWE5vS1R0Y2JpQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUdObGJHd3VZbVZ1WkNncE8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2RHaHBjeTVqZFhKeVpXNTBSV3hsYldWdWRDQTlJR1ZzWlcxbGJuUXVhVzVrWlhnN1hHNGdJQ0FnSUNCbExuQnlaWFpsYm5SRVpXWmhkV3gwS0NrN1hHNGdJQ0FnSUNCbExuTjBiM0JRY205d1lXZGhkR2x2YmlncE8xeHVJQ0FnSUgwcE8xeHVYRzRnSUNBZ2RHaHBjeTVsYkdWdFpXNTBMbUZrWkVWMlpXNTBUR2x6ZEdWdVpYSW9KM1J2ZFdOb1pXNWtKeXdnS0dVcElEMCtJSHRjYmlBZ0lDQWdJQzh2SUc1dklIUnZkV05vWlhNZ2RHOGdZMkZzWTNWc1lYUmxJR0psWTJGMWMyVWdibTl1WlNCeVpXMWhhVzVwYm1kY2JpQWdJQ0FnSUd4bGRDQmpaV3hzSUQwZ2RHaHBjeTVqWld4c2MxdDBhR2x6TG1OMWNuSmxiblJGYkdWdFpXNTBYVHRjYmlBZ0lDQWdJR05sYkd3dWRYQW9LVHRjYmlBZ0lDQWdJSFJvYVhNdWFXNTBaWEpoWTNScGJtY2dQU0JtWVd4elpUdGNiaUFnSUNBZ0lIUm9hWE11WTNWeWNtVnVkRVZzWlcxbGJuUWdQU0JtWVd4elpUdGNiaUFnSUNBZ0lHVXVjSEpsZG1WdWRFUmxabUYxYkhRb0tUdGNiaUFnSUNBZ0lHVXVjM1J2Y0ZCeWIzQmhaMkYwYVc5dUtDazdYRzRnSUNBZ2ZTazdYRzVjYmlBZ2ZWeHVYRzRnSUM4cUtseHVJQ0JPZFcxaVpYSWdiMllnY205M2N5QnBiaUIwYUdVZ2MyVnhkV1Z1WTJWeVhHNGdJRUIwZVhCbElIdHVkVzFpWlhKOVhHNGdJQ292WEc0Z0lHZGxkQ0J5YjNkektDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbTFoZEhKcGVDNXliM2R6TzF4dUlDQjlYRzVjYmlBZ2MyVjBJSEp2ZDNNb2Rpa2dlMXh1SUNBZ0lIUm9hWE11YldGMGNtbDRMbkp2ZDNNZ1BTQjJPMXh1SUNBZ0lIUm9hWE11Wlcxd2RIa29LVHRjYmlBZ0lDQjBhR2x6TG1KMWFXeGtTVzUwWlhKbVlXTmxLQ2s3WEc0Z0lDQWdkR2hwY3k1MWNHUmhkR1VvS1R0Y2JpQWdmVnh1WEc0Z0lDOHFLbHh1SUNCT2RXMWlaWElnYjJZZ1kyOXNkVzF1Y3lCcGJpQjBhR1VnYzJWeGRXVnVZMlZ5WEc0Z0lFQjBlWEJsSUh0dWRXMWlaWEo5WEc0Z0lDb3ZYRzRnSUdkbGRDQmpiMngxYlc1ektDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbTFoZEhKcGVDNWpiMngxYlc1ek8xeHVJQ0I5WEc1Y2JpQWdjMlYwSUdOdmJIVnRibk1vZGlrZ2UxeHVJQ0FnSUhSb2FYTXViV0YwY21sNExtTnZiSFZ0Ym5NZ1BTQjJPMXh1SUNBZ0lIUm9hWE11YzNSbGNIQmxjaTV0WVhnZ1BTQjJPMXh1SUNBZ0lIUm9hWE11Wlcxd2RIa29LVHRjYmlBZ0lDQjBhR2x6TG1KMWFXeGtTVzUwWlhKbVlXTmxLQ2s3WEc0Z0lDQWdkR2hwY3k1MWNHUmhkR1VvS1R0Y2JpQWdmVnh1WEc1OVhHNWNibHh1WEc0dkx5QlhSVUpRUVVOTElFWlBUMVJGVWlBdkwxeHVMeThnTGk5K0wycHphR2x1ZEMxc2IyRmtaWEloTGk5c2FXSXZhVzUwWlhKbVlXTmxjeTl6WlhGMVpXNWpaWEl1YW5NaUxDSW5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JtbHRjRzl5ZENCdFlYUm9JR1p5YjIwZ0p5NHVMM1YwYVd3dmJXRjBhQ2M3WEc1cGJYQnZjblFnVTJWeGRXVnVZMlVnWm5KdmJTQW5MaTR2Ylc5a1pXeHpMM05sY1hWbGJtTmxKenRjYmx4dUx5OGdSbTl5SUhSb1pTQjBkWFJ2Y21saGJDd2diRzl2YTJsdVp5QmhkRnh1WEc0dkwxQmhkSFJsY200Z2MyVmpkR2x2YmpwY2JpOHZJQzVqY21WaGRHVW9LU3dnTG5KdmQzTXNJQzVqYjJ4MWJXNXpMRnh1THk4Z0xuQmhkSFJsY200c0lDNXNaVzVuZEdnc0lDNW1iM0p0WVhSQmMxUmxlSFFvS1N3Z0xteHZaeWdwTEZ4dUx5OGdMbXh2WTJGMFpTaHBLU3dnTG1sdVpHVjRUMllvWXl4eUtWeHVMeThnY205M0tDa3NJR052YkhWdGJpZ3BJQ2h5WlhSMWNtNXpJR052Ym5SbGJuUnpJRzltSUhKdmR5QnZjaUJqYjJ4MWJTbGNibHh1THk5RGIyNTBjbTlzSUhObFkzUnBiMjQ2WEc0dkx5QjBiMmRuYkdVZ2VETmNiaTh2SUhObGRDQjRORnh1THk4Z2NtOTBZWFJsSUhnelhHNHZMeUJ3YjNCMWJHRjBaU0I0TTF4dUx5OGdaWEpoYzJVZ2VETmNibHh1WEc0dkx5QnphRzkxYkdRZ2MyOXRaU0IyWlhKemFXOXVJRzltSUhSb2FYTWdhR0YyWlNCaElHWnNiMkYwSUhaaGJIVmxJR1p2Y2lCbFlXTm9JR05sYkd3L1hHNHZMeUJqYjNWc1pDQmlaU0JzYVd0bElHRWdiV2x5Y205eUlDNXdZWFIwWlhKdUlIUm9ZWFFnYUdGeklIWmhiSFZsY3k0Z1lua2daR1ZtWVhWc2RDd2daWFpsY25sMGFHbHVaeUJwY3lBeExDQmlkWFFnWTI5MWJHUWdZbVVnYzJWMExpNHVYRzR2THlCdWIzUWdZU0JuYjI5a0lIZGhlU0IwYnlCa2J5QjBhR0YwSUc5dUlHbHVkR1Z5Wm1GalpTd2dZblYwSUdGeklHRWdiVzlrWld3Z2FYUWdkMjkxYkdRZ1ltVWdibWxqWlM0dUxseHVMeThnWm05eUlDNW1iM0p0WVhSQmMxUmxlSFFvS1N3Z1kyOTFiR1FnYlhWc2RHbHdiSGtnWW5rZ01UQXdJR0Z1WkNCbWJHOXZjaXdnYzI4Z1pXRmphQ0JqWld4c0lHbHpJR0Z1SUdsdWRDQm1jbTl0SURBZ2RHOGdPVnh1WEc1bGVIQnZjblFnWkdWbVlYVnNkQ0JqYkdGemN5Qk5ZWFJ5YVhnZ2UxeHVYRzRnSUdOdmJuTjBjblZqZEc5eUtISnZkM01zWTI5c2RXMXVjeWtnZTF4dUlDQWdJQzh2SUhOb2IzVnNaQ0JoYkhOdklHaGhkbVVnWVdKcGJHbDBlU0IwYnlCamNtVmhkR1VnZFhOcGJtY2dZVzRnWlhocGMzUnBibWNnYldGMGNtbDRJQ2d5WkNCaGNuSmhlU2xjYmlBZ0lDQjBhR2x6TG5CaGRIUmxjbTRnUFNCYlhUdGNiaUFnSUNCMGFHbHpMbU55WldGMFpTaHliM2R6TEdOdmJIVnRibk1wTzF4dVhHNGdJQ0FnZEdocGN5NTBiMmRuYkdVZ1BTQjdYRzRnSUNBZ0lDQmpaV3hzT2lBb1kyOXNkVzF1TENCeWIzY3BJRDArSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTV3WVhSMFpYSnVXM0p2ZDExYlkyOXNkVzF1WFNBOUlDRjBhR2x6TG5CaGRIUmxjbTViY205M1hWdGpiMngxYlc1ZE95QXZMeUJ0WVhSb0xtbHVkbVZ5ZENoMGFHbHpMbkJoZEhSbGNtNWJjbTkzWFZ0amIyeDFiVzVkS1R0Y2JpQWdJQ0FnSUNBZ2FXWWdLSFJvYVhNdWRXa3BJSHNnZEdocGN5NTFhUzUxY0dSaGRHVW9LVHNnZlZ4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZEdocGN5NXdZWFIwWlhKdVczSnZkMTFiWTI5c2RXMXVYVHRjYmlBZ0lDQWdJSDBzWEc0Z0lDQWdJQ0JoYkd3NklDZ3BJRDArSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTVwZEdWeVlYUmxLQ2h5TEdNcElEMCtJSHNnZEdocGN5NTBiMmRuYkdVdVkyVnNiQ2hqTEhJcE95QjlLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tIUm9hWE11ZFdrcElIc2dkR2hwY3k1MWFTNTFjR1JoZEdVb0tUc2dmVnh1SUNBZ0lDQWdmU3hjYmlBZ0lDQWdJSEp2ZHpvZ0tISnZkeWtnUFQ0Z2UxeHVJQ0FnSUNBZ0lDQm1iM0lnS0d4bGRDQnBQVEE3SUdrOGRHaHBjeTVqYjJ4MWJXNXpPeUJwS3lzcElIdGNiaUFnSUNBZ0lDQWdJQ0IwYUdsekxuUnZaMmRzWlM1alpXeHNLR2tzY205M0tUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0JwWmlBb2RHaHBjeTUxYVNrZ2V5QjBhR2x6TG5WcExuVndaR0YwWlNncE95QjlYRzRnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdZMjlzZFcxdU9pQW9ZMjlzZFcxdUtTQTlQaUI3WEc0Z0lDQWdJQ0FnSUdadmNpQW9iR1YwSUdrOU1Ec2dhVHgwYUdsekxuSnZkM003SUdrckt5a2dlMXh1SUNBZ0lDQWdJQ0FnSUhSb2FYTXVkRzluWjJ4bExtTmxiR3dvWTI5c2RXMXVMR2twTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lHbG1JQ2gwYUdsekxuVnBLU0I3SUhSb2FYTXVkV2t1ZFhCa1lYUmxLQ2s3SUgxY2JpQWdJQ0FnSUgxY2JpQWdJQ0I5TzF4dVhHNGdJQ0FnZEdocGN5NXpaWFFnUFNCN1hHNGdJQ0FnSUNCalpXeHNPaUFvWTI5c2RXMXVMQ0J5YjNjc0lIWmhiSFZsS1NBOVBpQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWNHRjBkR1Z5Ymx0eWIzZGRXMk52YkhWdGJsMGdQU0IyWVd4MVpUdGNiaUFnSUNBZ0lDQWdhV1lnS0hSb2FYTXVkV2twSUhzZ2RHaHBjeTUxYVM1MWNHUmhkR1VvS1RzZ2ZWeHVJQ0FnSUNBZ2ZTeGNiaUFnSUNBZ0lHRnNiRG9nS0haaGJIVmxjeWtnUFQ0Z2UxeHVJQ0FnSUNBZ0lDQXZMeUJ6WlhRZ2RHaGxJSGRvYjJ4bElHMWhkSEpwZUNCMWMybHVaeUJoSURKa0lHRnljbUY1SUdGeklHbHVjSFYwWEc0Z0lDQWdJQ0FnSUM4dklIUm9hWE1nYzJodmRXeGtJR0ZzYzI4Z2NtVnphWHBsSUhSb1pTQmhjbkpoZVQ5Y2JpQWdJQ0FnSUNBZ2RHaHBjeTV3WVhSMFpYSnVJRDBnZG1Gc2RXVnpPMXh1SUNBZ0lDQWdJQ0JwWmlBb2RHaHBjeTUxYVNrZ2V5QjBhR2x6TG5WcExuVndaR0YwWlNncE95QjlYRzRnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdjbTkzT2lBb2NtOTNMSFpoYkhWbGN5a2dQVDRnZTF4dUlDQWdJQ0FnSUNBdkx5QnpaWFFnWVNCeWIzY2dkWE5wYm1jZ1lXNGdZWEp5WVhrZ1lYTWdhVzV3ZFhSY2JpQWdJQ0FnSUNBZ2RHaHBjeTV3WVhSMFpYSnVXM0p2ZDEwZ1BTQjJZV3gxWlhNN1hHNGdJQ0FnSUNBZ0lHbG1JQ2gwYUdsekxuVnBLU0I3SUhSb2FYTXVkV2t1ZFhCa1lYUmxLQ2s3SUgxY2JpQWdJQ0FnSUgwc1hHNGdJQ0FnSUNCamIyeDFiVzQ2SUNoamIyeDFiVzRzZG1Gc2RXVnpLU0E5UGlCN1hHNGdJQ0FnSUNBZ0lDOHZJSE5sZENCaElHTnZiSFZ0YmlCMWMybHVaeUJoYmlCaGNuSmhlU0JoY3lCcGJuQjFkRnh1SUNBZ0lDQWdJQ0IwYUdsekxuQmhkSFJsY200dVptOXlSV0ZqYUNnb2NtOTNMR2twSUQwK0lIdGNiaUFnSUNBZ0lDQWdJQ0IwYUdsekxuQmhkSFJsY201YmFWMWJZMjlzZFcxdVhTQTlJSFpoYkhWbGMxdHBYVHRjYmlBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lHbG1JQ2gwYUdsekxuVnBLU0I3SUhSb2FYTXVkV2t1ZFhCa1lYUmxLQ2s3SUgxY2JpQWdJQ0FnSUgxY2JpQWdJQ0I5TzF4dVhHNGdJQ0FnZEdocGN5NXliM1JoZEdVZ1BTQjdYRzRnSUNBZ0lDQXZMM05vYjNWc1pDQmxkbVZ1ZEhWaGJHeDVJR1J2SUNoaGJXOTFiblJZTENCaGJXOTFiblJaS1NCb1pYSmxYRzRnSUNBZ0lDQXZMeUJqYjNWc1pDQnFkWE4wSUhWelpTQmhJR3h2YjNBZ1lXNWtJSFJvYVhNdWNtOTBZWFJsTG5KdmR5aHBMR0Z0YjNWdWRGZ3BPMXh1SUNBZ0lDQWdZV3hzT2lBb1lXMXZkVzUwS1NBOVBpQjdYRzRnSUNBZ0lDQWdJR2xtSUNnaFlXMXZkVzUwSUNZbUlHRnRiM1Z1ZENFOVBUQXBJSHRjYmlBZ0lDQWdJQ0FnSUNCaGJXOTFiblFnUFNBeE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJR0Z0YjNWdWRDQWxQU0IwYUdsekxuQmhkSFJsY201Yk1GMHViR1Z1WjNSb08xeHVJQ0FnSUNBZ0lDQnBaaUFvWVcxdmRXNTBJRHdnTUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJR0Z0YjNWdWRDQTlJSFJvYVhNdWNHRjBkR1Z5Ymxzd1hTNXNaVzVuZEdnZ0t5QmhiVzkxYm5RN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdabTl5SUNoc1pYUWdhVDB3T3lCcFBIUm9hWE11Y205M2N6c2dhU3NyS1NCN1hHNGdJQ0FnSUNBZ0lDQWdiR1YwSUdOMWRDQTlJSFJvYVhNdWNHRjBkR1Z5Ymx0cFhTNXpjR3hwWTJVb0lIUm9hWE11Y0dGMGRHVnlibHRwWFM1c1pXNW5kR2dnTFNCaGJXOTFiblFzSUdGdGIzVnVkQ0FwTzF4dUlDQWdJQ0FnSUNBZ0lIUm9hWE11Y0dGMGRHVnlibHRwWFNBOUlHTjFkQzVqYjI1allYUW9JSFJvYVhNdWNHRjBkR1Z5Ymx0cFhTQXBPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUdsbUlDaDBhR2x6TG5WcEtTQjdJSFJvYVhNdWRXa3VkWEJrWVhSbEtDazdJSDFjYmlBZ0lDQWdJSDBzWEc0Z0lDQWdJQ0J5YjNjNklDaHliM2NzWVcxdmRXNTBLU0E5UGlCN1hHNGdJQ0FnSUNBZ0lHbG1JQ2doWVcxdmRXNTBJQ1ltSUdGdGIzVnVkQ0U5UFRBcElIdGNiaUFnSUNBZ0lDQWdJQ0JoYlc5MWJuUWdQU0F4TzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lHRnRiM1Z1ZENBbFBTQjBhR2x6TG5CaGRIUmxjbTViTUYwdWJHVnVaM1JvTzF4dUlDQWdJQ0FnSUNCcFppQW9ZVzF2ZFc1MElEd2dNQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lHRnRiM1Z1ZENBOUlIUm9hWE11Y0dGMGRHVnlibHN3WFM1c1pXNW5kR2dnS3lCaGJXOTFiblE3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2JHVjBJR04xZENBOUlIUm9hWE11Y0dGMGRHVnlibHR5YjNkZExuTndiR2xqWlNnZ2RHaHBjeTV3WVhSMFpYSnVXM0p2ZDEwdWJHVnVaM1JvSUMwZ1lXMXZkVzUwTENCaGJXOTFiblFnS1R0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTV3WVhSMFpYSnVXM0p2ZDEwZ1BTQmpkWFF1WTI5dVkyRjBLQ0IwYUdsekxuQmhkSFJsY201YmNtOTNYU0FwTzF4dUlDQWdJQ0FnSUNCcFppQW9kR2hwY3k1MWFTa2dleUIwYUdsekxuVnBMblZ3WkdGMFpTZ3BPeUI5WEc0Z0lDQWdJQ0I5TEZ4dUlDQWdJQ0FnWTI5c2RXMXVPaUFvWTI5c2RXMXVMQ0JoYlc5MWJuUXBJRDArSUh0Y2JpQWdJQ0FnSUNBZ2FXWWdLQ0ZoYlc5MWJuUWdKaVlnWVcxdmRXNTBJVDA5TUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJR0Z0YjNWdWRDQTlJREU3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ1lXMXZkVzUwSUNVOUlIUm9hWE11Y0dGMGRHVnliaTVzWlc1bmRHZzdYRzRnSUNBZ0lDQWdJR2xtSUNoaGJXOTFiblFnUENBd0tTQjdYRzRnSUNBZ0lDQWdJQ0FnWVcxdmRXNTBJRDBnZEdocGN5NXdZWFIwWlhKdUxteGxibWQwYUNBcklHRnRiM1Z1ZER0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnNaWFFnY0hKdmVIa2dQU0JiWFR0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTV3WVhSMFpYSnVMbVp2Y2tWaFkyZ29LSEp2ZHlrZ1BUNGdlMXh1SUNBZ0lDQWdJQ0FnSUhCeWIzaDVMbkIxYzJnb0lISnZkMXRqYjJ4MWJXNWRJQ2s3WEc0Z0lDQWdJQ0FnSUgwcE8xeHVJQ0FnSUNBZ0lDQnNaWFFnWTNWMElEMGdjSEp2ZUhrdWMzQnNhV05sS0NCd2NtOTRlUzVzWlc1bmRHZ2dMU0JoYlc5MWJuUXNJR0Z0YjNWdWRDQXBPMXh1SUNBZ0lDQWdJQ0J3Y205NGVTQTlJR04xZEM1amIyNWpZWFFvSUhCeWIzaDVJQ2s3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVjR0YwZEdWeWJpNW1iM0pGWVdOb0tDaHliM2NzYVNrZ1BUNGdlMXh1SUNBZ0lDQWdJQ0FnSUhKdmQxdGpiMngxYlc1ZElEMGdjSEp2ZUhsYmFWMDdYRzRnSUNBZ0lDQWdJSDBwTzF4dUlDQWdJQ0FnSUNCcFppQW9kR2hwY3k1MWFTa2dleUIwYUdsekxuVnBMblZ3WkdGMFpTZ3BPeUI5WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdmVHRjYmx4dUlDQWdJQzh2SUhSb1pTQnBaR1ZoSUdKbGFHbHVaQ0J3YjNCMWJHRjBaU0JwY3lCMGJ5QmlaU0JoWW14bElIUnZJSE5sZENCaElIZG9iMnhsSUhKdmR5QnZjaUJqYjJ4MWJXNGdkRzhnTUNCdmNpQXhYRzRnSUNBZ0x5OGdTVVlnZEdobElIWmhiSFZsSUdseklHRWdabXh2WVhRc0lITjFZMmdnWVhNZ01DNDNMQ0IwYUdWdUlHbDBJSGR2ZFd4a0lHSmxZMjl0WlNCaElIQnliMkpoWW1sc2FYUjVYRzRnSUNBZ0x5OGdjMjhnY0c5d2RXeGhkR1VvTUM0M0tTQjNiM1ZzWkNCbmFYWmxJR1ZoWTJnZ1kyVnNiQ0JoSURjd0pTQmphR0Z1WTJVZ2IyWWdZbVZwYm1jZ01WeHVJQ0FnSUhSb2FYTXVjRzl3ZFd4aGRHVWdQU0I3WEc0Z0lDQWdJQ0JoYkd3NklDaHZaR1J6S1NBOVBpQjdYRzRnSUNBZ0lDQWdJR3hsZENCdlpHUnpVMlZ4ZFdWdVkyVWdQU0J1WlhjZ1UyVnhkV1Z1WTJVb2IyUmtjeWs3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVhWFJsY21GMFpTZ29jaXhqS1NBOVBpQjdYRzRnSUNBZ0lDQWdJQ0FnZEdocGN5NXdZWFIwWlhKdVczSmRXMk5kSUQwZ2JXRjBhQzVqYjJsdUtHOWtaSE5UWlhGMVpXNWpaUzV1WlhoMEtDa3BPMXh1SUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0FnSUNBZ0x5OGdWR2hwY3lCamIzVnNaQ0JpWlNCMWMyVmtJSE52SUhSb1lYUWdaV0ZqYUNCeWIzY2dhR0Z6SUhOaGJXVWdiMlJrY3lCd1lYUjBaWEp1TENCbGRtVnVJR2xtSUhKdmR5QnNaVzVuZEdnZ2FYTWdibTkwSUdScGRtbHphV0pzZVNCaWVTQnpaWEYxWlc1alpTQnNaVzVuZEdndVhHNGdJQ0FnSUNBZ0lDOHZMQ2dwSUQwK0lIdGNiaUFnSUNBZ0lDQWdMeThnSUc5a1pITXVjRzl6SUQwZ0xURTdYRzRnSUNBZ0lDQWdJQzh2SUgxY2JpQWdJQ0FnSUNBZ2FXWWdLSFJvYVhNdWRXa3BJSHNnZEdocGN5NTFhUzUxY0dSaGRHVW9LVHNnZlZ4dUlDQWdJQ0FnZlN4Y2JpQWdJQ0FnSUhKdmR6b2dLSEp2ZHowd0xHOWtaSE05TVNrZ1BUNGdlMXh1SUNBZ0lDQWdJQ0JzWlhRZ2IyUmtjMU5sY1hWbGJtTmxJRDBnYm1WM0lGTmxjWFZsYm1ObEtHOWtaSE1wTzF4dUlDQWdJQ0FnSUNCMGFHbHpMbkJoZEhSbGNtNWJjbTkzWFM1bWIzSkZZV05vS0NoalpXeHNMR2twSUQwK0lIdGNiaUFnSUNBZ0lDQWdJQ0IwYUdsekxuQmhkSFJsY201YmNtOTNYVnRwWFNBOUlHMWhkR2d1WTI5cGJpaHZaR1J6VTJWeGRXVnVZMlV1Ym1WNGRDZ3BLVHRjYmlBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lHbG1JQ2gwYUdsekxuVnBLU0I3SUhSb2FYTXVkV2t1ZFhCa1lYUmxLQ2s3SUgxY2JpQWdJQ0FnSUgwc1hHNGdJQ0FnSUNCamIyeDFiVzQ2SUNoamIyeDFiVzQ5TUN4dlpHUnpQVEVwSUQwK0lIdGNiaUFnSUNBZ0lDQWdiR1YwSUc5a1pITlRaWEYxWlc1alpTQTlJRzVsZHlCVFpYRjFaVzVqWlNodlpHUnpLVHRjYmlBZ0lDQWdJQ0FnZEdocGN5NXdZWFIwWlhKdUxtWnZja1ZoWTJnb0tISnZkeXhwS1NBOVBpQjdYRzRnSUNBZ0lDQWdJQ0FnZEdocGN5NXdZWFIwWlhKdVcybGRXMk52YkhWdGJsMGdQU0J0WVhSb0xtTnZhVzRvYjJSa2MxTmxjWFZsYm1ObExtNWxlSFFvS1NrN1hHNGdJQ0FnSUNBZ0lIMHBPMXh1SUNBZ0lDQWdJQ0JwWmlBb2RHaHBjeTUxYVNrZ2V5QjBhR2x6TG5WcExuVndaR0YwWlNncE95QjlYRzRnSUNBZ0lDQjlYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lDOHZJR1Z6YzJWdWRHbGhiR3dnY0c5d2RXeGhkR1VvTUNrZ2MyOGdhU2R0SUc1dmRDQnpkWEpsSUdsbUlIUm9hWE1nYVhNZ2JtVmpaWE56WVhKNUlHSjFkQ0JwY3lCdWFXTmxYRzRnSUNBZ2RHaHBjeTVsY21GelpTQTlJSHRjYmlBZ0lDQWdJR0ZzYkRvZ0tDa2dQVDRnZTF4dUlDQWdJQ0FnSUNCMGFHbHpMbk5sZEM1aGJHd29NQ2s3WEc0Z0lDQWdJQ0I5TEZ4dUlDQWdJQ0FnY205M09pQW9jbTkzS1NBOVBpQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWMyVjBMbkp2ZHloeWIzY3NNQ2s3WEc0Z0lDQWdJQ0I5TEZ4dUlDQWdJQ0FnWTI5c2RXMXVPaUFvWTI5c2RXMXVLU0E5UGlCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11YzJWMExtTnZiSFZ0YmloamIyeDFiVzRzTUNrN1hHNGdJQ0FnSUNCOVhHNGdJQ0FnZlR0Y2JseHVJQ0F2THlCbGJtUWdZMjl1YzNSeWRXTjBiM0pjYmlBZ2ZWeHVYRzVjYmlBZ1kzSmxZWFJsS0hKdmQzTXNZMjlzZFcxdWN5a2dlMXh1SUNBZ0lIUm9hWE11Y0dGMGRHVnliaUE5SUZ0ZE8xeHVJQ0FnSUdadmNpQW9JR3hsZENCeWIzYzlNRHNnY205M0lEd2djbTkzY3pzZ2NtOTNLeXNnS1NCN1hHNGdJQ0FnSUNCc1pYUWdZWEp5SUQwZ2JtVjNJRUZ5Y21GNUtHTnZiSFZ0Ym5NcE8xeHVJQ0FnSUNBZ2RHaHBjeTV3WVhSMFpYSnVMbkIxYzJnb1lYSnlLVHRjYmlBZ0lDQjlYRzRnSUNBZ2RHaHBjeTVwZEdWeVlYUmxLQ2h5TEdNcElEMCtJSHNnZEdocGN5NXdZWFIwWlhKdVczSmRXMk5kSUQwZ1ptRnNjMlU3SUgwcE8xeHVJQ0I5WEc1Y2JpQWdhWFJsY21GMFpTaG1MQ0JtTWlrZ2UxeHVJQ0FnSUd4bGRDQnBJRDBnTUR0Y2JpQWdJQ0JtYjNJZ0tDQnNaWFFnY205M1BUQTdJSEp2ZHlBOElIUm9hWE11Y205M2N6c2djbTkzS3lzZ0tTQjdYRzRnSUNBZ0lDQnBaaUFvWmpJcElIc2daaklvY205M0tUc2dmVnh1SUNBZ0lDQWdabTl5SUNnZ2JHVjBJR052YkhWdGJqMHdPeUJqYjJ4MWJXNGdQQ0IwYUdsekxtTnZiSFZ0Ym5NN0lHTnZiSFZ0YmlzcklDa2dlMXh1SUNBZ0lDQWdJQ0JtS0hKdmR5eGpiMngxYlc0c2FTazdYRzRnSUNBZ0lDQWdJR2tyS3p0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lIMWNibHh1SUNCbWIzSnRZWFJCYzFSbGVIUW9LU0I3WEc0Z0lDQWdiR1YwSUhCaGRIUmxjbTVUZEhKcGJtY2dQU0FuSnp0Y2JpQWdJQ0IwYUdsekxtbDBaWEpoZEdVb1hHNGdJQ0FnSUNBb2NpeGpLU0E5UGlCN0lIQmhkSFJsY201VGRISnBibWNnS3owZ0tIUm9hWE11Y0dGMGRHVnlibHR5WFZ0alhTQS9JREVnT2lBd0tTQXJJQ2NnSnpzZ2ZTeGNiaUFnSUNBZ0lDZ3BJRDArSUhzZ2NHRjBkR1Z5YmxOMGNtbHVaeUFyUFNBblhGeHVKenNnZlZ4dUlDQWdJQ2s3WEc0Z0lDQWdjbVYwZFhKdUlIQmhkSFJsY201VGRISnBibWM3WEc0Z0lIMWNibHh1SUNCc2IyY29LU0I3WEc0Z0lDQWdZMjl1YzI5c1pTNXNiMmNvZEdocGN5NW1iM0p0WVhSQmMxUmxlSFFvS1NrN1hHNGdJSDFjYmx4dUlDQjFjR1JoZEdVb2NHRjBkR1Z5YmlrZ2UxeHVJQ0FnSUhSb2FYTXVjR0YwZEdWeWJpQTlJSEJoZEhSbGNtNGdmSHdnZEdocGN5NXdZWFIwWlhKdU8xeHVJQ0I5WEc1Y2JpQWdaMlYwSUd4bGJtZDBhQ2dwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1eWIzZHpLblJvYVhNdVkyOXNkVzF1Y3p0Y2JpQWdmVnh1WEc0Z0lHeHZZMkYwWlNocGJtUmxlQ2tnZTF4dUlDQWdJQzh2SUhKbGRIVnlibk1nY205M0lHRnVaQ0JqYjJ4MWJXNGdiMllnWTJWc2JDQmllU0JwYm1SbGVGeHVJQ0FnSUhKbGRIVnliaUI3WEc0Z0lDQWdJQ0J5YjNjNklINStLQ0JwYm1SbGVDQXZJSFJvYVhNdVkyOXNkVzF1Y3lBcExGeHVJQ0FnSUNBZ1kyOXNkVzF1T2lCcGJtUmxlQ0FsSUhSb2FYTXVZMjlzZFcxdWMxeHVJQ0FnSUgwN1hHNGdJSDFjYmx4dUlDQnBibVJsZUU5bUtISnZkeXhqYjJ4MWJXNHBJSHRjYmlBZ0lDQnlaWFIxY200Z1kyOXNkVzF1SUNzZ2NtOTNJQ29nZEdocGN5NWpiMngxYlc1ek8xeHVJQ0FnSUM4dklISmxkSFZ5Ym5NZ2FXNWtaWGdnYjJZZ1kyVnNiQ0JpZVNCeWIzY2dZVzVrSUdOdmJIVnRibHh1SUNCOVhHNWNiaUFnY205M0tISnZkeWtnZTF4dUlDQWdJR3hsZENCa1lYUmhJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaHNaWFFnYVQwd095QnBQSFJvYVhNdVkyOXNkVzF1Y3pzZ2FTc3JLU0I3WEc0Z0lDQWdJQ0JrWVhSaExuQjFjMmdvZEdocGN5NXdZWFIwWlhKdVczSnZkMTBnUHlBeElEb2dNQ2s3WEc0Z0lDQWdmVnh1SUNBZ0lISmxkSFZ5YmlCa1lYUmhPMXh1SUNCOVhHNWNiaUFnWTI5c2RXMXVLR052YkhWdGJpa2dlMXh1SUNBZ0lHeGxkQ0JrWVhSaElEMGdXMTA3WEc0Z0lDQWdabTl5SUNoc1pYUWdhVDB3T3lCcFBIUm9hWE11Y205M2N6c2dhU3NyS1NCN1hHNGdJQ0FnSUNCa1lYUmhMbkIxYzJnb2RHaHBjeTV3WVhSMFpYSnVXMmxkVzJOdmJIVnRibDBnUHlBeElEb2dNQ2s3WEc0Z0lDQWdmVnh1SUNBZ0lISmxkSFZ5YmlCa1lYUmhPMXh1SUNCOVhHNWNiaUFnWjJWMElISnZkM01vS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWNHRjBkR1Z5Ymk1c1pXNW5kR2c3WEc0Z0lIMWNiaUFnYzJWMElISnZkM01vZGlrZ2UxeHVJQ0FnSUd4bGRDQndjbVYyYVc5MWN5QTlJSFJvYVhNdWNHRjBkR1Z5Ymk1emJHbGpaU2d3S1R0Y2JpQWdJQ0IwYUdsekxtTnlaV0YwWlNoMkxIUm9hWE11WTI5c2RXMXVjeWs3WEc0Z0lDQWdkR2hwY3k1cGRHVnlZWFJsS0NoeUxHTXBJRDArSUh0Y2JpQWdJQ0FnSUdsbUlDaHdjbVYyYVc5MWMxdHlYU0FtSmlCd2NtVjJhVzkxYzF0eVhWdGpYU2tnZTF4dUlDQWdJQ0FnSUNCMGFHbHpMbkJoZEhSbGNtNWJjbDFiWTEwZ1BTQndjbVYyYVc5MWMxdHlYVnRqWFR0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5S1R0Y2JpQWdmVnh1WEc0Z0lHZGxkQ0JqYjJ4MWJXNXpLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG5CaGRIUmxjbTViTUYwdWJHVnVaM1JvTzF4dUlDQjlYRzRnSUhObGRDQmpiMngxYlc1ektIWXBJSHRjYmlBZ0lDQnNaWFFnY0hKbGRtbHZkWE1nUFNCMGFHbHpMbkJoZEhSbGNtNHVjMnhwWTJVb01DazdYRzRnSUNBZ2RHaHBjeTVqY21WaGRHVW9kR2hwY3k1eWIzZHpMSFlwTzF4dUlDQWdJSFJvYVhNdWFYUmxjbUYwWlNnb2NpeGpLU0E5UGlCN1hHNGdJQ0FnSUNCcFppQW9jSEpsZG1sdmRYTmJjbDBnSmlZZ2NISmxkbWx2ZFhOYmNsMWJZMTBwSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTV3WVhSMFpYSnVXM0pkVzJOZElEMGdjSEpsZG1sdmRYTmJjbDFiWTEwN1hHNGdJQ0FnSUNCOVhHNGdJQ0FnZlNrN1hHNGdJSDFjYmx4dWZWeHVYRzVjYmx4dUx5OGdWMFZDVUVGRFN5QkdUMDlVUlZJZ0x5OWNiaTh2SUM0dmZpOXFjMmhwYm5RdGJHOWhaR1Z5SVM0dmJHbGlMMjF2WkdWc2N5OXRZWFJ5YVhndWFuTWlMQ0luZFhObElITjBjbWxqZENjN1hISmNibHh5WEc1cGJYQnZjblFnYldGMGFDQm1jbTl0SUNjdUxpOTFkR2xzTDIxaGRHZ25PMXh5WEc1cGJYQnZjblFnUkhKMWJtc2dabkp2YlNBbkxpOWtjblZ1YXljN1hISmNibHh5WEc1bGVIQnZjblFnWkdWbVlYVnNkQ0JqYkdGemN5QlRaWEYxWlc1alpTQjdYSEpjYmx4eVhHNGdJQ0FnWTI5dWMzUnlkV04wYjNJb2MyVnhkV1Z1WTJVZ1BTQmJNQ3d4TUN3eU1Dd3pNRjBzSUcxdlpHVTlKM1Z3Snl3Z2NHOXphWFJwYjI0OVptRnNjMlVwSUh0Y2NseHVJQ0FnSUNBZ0lDQjBhR2x6TG5aaGJIVmxjeUE5SUhObGNYVmxibU5sTzF4eVhHNGdJQ0FnSUNBZ0lHbG1JQ2doUVhKeVlYa3VhWE5CY25KaGVTaDBhR2x6TG5aaGJIVmxjeWtwSUh0Y2NseHVJQ0FnSUNBZ0lDQWdJSFJvYVhNdWRtRnNkV1Z6SUQwZ1czUm9hWE11ZG1Gc2RXVnpYVHRjY2x4dUlDQWdJQ0FnSUNCOVhISmNiaUFnSUNBZ0lDQWdkR2hwY3k1ZmJXOWtaU0E5SUcxdlpHVTdYSEpjYmlBZ0lDQWdJQ0FnZEdocGN5NXdiM05wZEdsdmJpQTlJSEJ2YzJsMGFXOXVPMXh5WEc1Y2NseHVJQ0FnSUNBZ0lDQjBhR2x6TG1SeWRXNXJWMkZzYXlBOUlHNWxkeUJFY25WdWF5Z3dMQ0IwYUdsekxuWmhiSFZsY3k1c1pXNW5kR2dnTFNBeEtUdGNjbHh1WEhKY2JpQWdJQ0FnSUNBZ2RHaHBjeTV6ZEdGeWRGWmhiSFZsY3lBOUlIdGNjbHh1SUNBZ0lDQWdJQ0FnSUNkMWNDYzZJREFzWEhKY2JpQWdJQ0FnSUNBZ0lDQW5aRzkzYmljNklIUm9hWE11ZG1Gc2RXVnpMbXhsYm1kMGFDQXRJREVzWEhKY2JpQWdJQ0FnSUNBZ0lDQW5aSEoxYm1zbk9pQitmaWgwYUdsekxuWmhiSFZsY3k1c1pXNW5kR2d2TWlrc1hISmNiaUFnSUNBZ0lDQWdJQ0FuY21GdVpHOXRKem9nYldGMGFDNXlhU2gwYUdsekxuWmhiSFZsY3k1c1pXNW5kR2dwWEhKY2JpQWdJQ0FnSUNBZ2ZUdGNjbHh1WEhKY2JpQWdJQ0FnSUNBZ2FXWWdLSFJvYVhNdWNHOXphWFJwYjI0aFBUMW1ZV3h6WlNrZ2UxeHlYRzRnSUNBZ0lDQWdJQ0FnZEdocGN5NXVaWGgwSUQwZ2RHaHBjMXQwYUdsekxsOXRiMlJsWFR0Y2NseHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHlYRzRnSUNBZ0lDQWdJQ0FnZEdocGN5NXVaWGgwSUQwZ2RHaHBjeTVtYVhKemREdGNjbHh1SUNBZ0lDQWdJQ0I5WEhKY2JseHlYRzVjY2x4dUlDQWdJSDFjY2x4dVhISmNiaUFnSUNCblpYUWdiVzlrWlNncElIdGNjbHh1SUNBZ0lDQWdjbVYwZFhKdUlIUm9hWE11WDIxdlpHVTdYSEpjYmlBZ0lDQjlYSEpjYmx4eVhHNGdJQ0FnYzJWMElHMXZaR1VvYlc5a1pTa2dlMXh5WEc0Z0lDQWdJQ0FnSUdsbUlDZ2hLRzF2WkdVZ1BUMDlJQ2QxY0NjZ2ZId2diVzlrWlNBOVBUMGdKMlJ2ZDI0bklIeDhJRzF2WkdVZ1BUMDlJQ2R5WVc1a2IyMG5JSHg4SUcxdlpHVWdQVDA5SUNka2NuVnVheWNwS1NCN1hISmNiaUFnSUNBZ0lDQWdJQ0FnSUdOdmJuTnZiR1V1WlhKeWIzSW9KMVJvWlNCdmJteDVJRzF2WkdWeklHTjFjbkpsYm5Sc2VTQmhiR3h2ZDJWa0lHRnlaVG9nZFhBc0lHUnZkMjRzSUhKaGJtUnZiU3dnWkhKMWJtc25LVHRjY2x4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdU8xeHlYRzRnSUNBZ0lDQWdJSDFjY2x4dUlDQWdJQ0FnSUNCMGFHbHpMbDl0YjJSbElEMGdiVzlrWlR0Y2NseHVJQ0FnSUNBZ0lDQnBaaUFvZEdocGN5NXdiM05wZEdsdmJpa2dlMXh5WEc0Z0lDQWdJQ0FnSUNBZ2RHaHBjeTV1WlhoMElEMGdkR2hwYzF0MGFHbHpMbDl0YjJSbFhUdGNjbHh1SUNBZ0lDQWdJQ0I5WEhKY2JpQWdJQ0I5WEhKY2JseHlYRzRnSUNBZ1oyVjBJSFpoYkhWbEtDa2dlMXh5WEc0Z0lDQWdJQ0J5WlhSMWNtNGdkR2hwY3k1MllXeDFaWE5iZEdocGN5NXdiM05wZEdsdmJsMDdYSEpjYmlBZ0lDQjlYSEpjYmx4eVhHNGdJQ0FnYzJWMElIWmhiSFZsS0hZcElIdGNjbHh1SUNBZ0lDQWdkR2hwY3k1d2IzTnBkR2x2YmlBOUlIUm9hWE11ZG1Gc2RXVnpMbWx1WkdWNFQyWW9kaWs3WEhKY2JpQWdJQ0I5WEhKY2JseHlYRzRnSUNBZ1ptbHljM1FvS1NCN1hISmNiaUFnSUNBZ0lHbG1JQ2gwYUdsekxuQnZjMmwwYVc5dUlUMDlabUZzYzJVcElIdGNjbHh1SUNBZ0lDQWdJQ0IwYUdsekxtNWxlSFFnUFNCMGFHbHpXM1JvYVhNdVgyMXZaR1ZkTzF4eVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCMGFHbHpMbTVsZUhRb0tUdGNjbHh1SUNBZ0lDQWdmVnh5WEc0Z0lDQWdJQ0IwYUdsekxuQnZjMmwwYVc5dUlEMGdkR2hwY3k1emRHRnlkRlpoYkhWbGMxdDBhR2x6TGw5dGIyUmxYVHRjY2x4dUlDQWdJQ0FnZEdocGN5NXVaWGgwSUQwZ2RHaHBjMXQwYUdsekxsOXRiMlJsWFR0Y2NseHVJQ0FnSUNBZ2NtVjBkWEp1SUhSb2FYTXVkbUZzZFdVN1hISmNiaUFnSUNCOVhISmNibHh5WEc0Z0lDQWdkWEFvS1NCN1hISmNiaUFnSUNBZ0lIUm9hWE11Y0c5emFYUnBiMjRyS3p0Y2NseHVJQ0FnSUNBZ2RHaHBjeTV3YjNOcGRHbHZiaUFsUFNCMGFHbHpMblpoYkhWbGN5NXNaVzVuZEdnN1hISmNiaUFnSUNBZ0lISmxkSFZ5YmlCMGFHbHpMblpoYkhWbE8xeHlYRzRnSUNBZ2ZWeHlYRzVjY2x4dUlDQWdJR1J2ZDI0b0tTQjdYSEpjYmlBZ0lDQWdJSFJvYVhNdWNHOXphWFJwYjI0dExUdGNjbHh1SUNBZ0lDQWdhV1lnS0hSb2FYTXVjRzl6YVhScGIyNGdQQ0F3S1NCN1hISmNiaUFnSUNBZ0lDQWdkR2hwY3k1d2IzTnBkR2x2YmlBOUlDaDBhR2x6TG5CdmMybDBhVzl1SUNzZ2RHaHBjeTUyWVd4MVpYTXViR1Z1WjNSb0tTQWxJSFJvYVhNdWRtRnNkV1Z6TG14bGJtZDBhRHRjY2x4dUlDQWdJQ0FnZlZ4eVhHNGdJQ0FnSUNCeVpYUjFjbTRnZEdocGN5NTJZV3gxWlR0Y2NseHVJQ0FnSUgxY2NseHVYSEpjYmlBZ0lDQnlZVzVrYjIwb0tTQjdYSEpjYmlBZ0lDQWdJSFJvYVhNdWNHOXphWFJwYjI0Z1BTQnRZWFJvTG5KcEtEQXNJSFJvYVhNdWRtRnNkV1Z6TG14bGJtZDBhQ2s3WEhKY2JpQWdJQ0FnSUhKbGRIVnliaUIwYUdsekxuWmhiSFZsTzF4eVhHNGdJQ0FnZlZ4eVhHNWNjbHh1SUNBZ0lHUnlkVzVyS0NrZ2UxeHlYRzRnSUNBZ0lDQjBhR2x6TG1SeWRXNXJWMkZzYXk1dFlYZ2dQU0IwYUdsekxuWmhiSFZsY3k1c1pXNW5kR2c3WEhKY2JpQWdJQ0FnSUhSb2FYTXVaSEoxYm10WFlXeHJMblpoYkhWbElEMGdkR2hwY3k1d2IzTnBkR2x2Ymp0Y2NseHVJQ0FnSUNBZ2RHaHBjeTV3YjNOcGRHbHZiaUE5SUhSb2FYTXVaSEoxYm10WFlXeHJMbTVsZUhRb0tUdGNjbHh1SUNBZ0lDQWdjbVYwZFhKdUlIUm9hWE11ZG1Gc2RXVTdYSEpjYmlBZ0lDQjlYSEpjYmx4eVhHNGdJQ0FnTHlvZ1puVjBkWEpsSUcxbGRHaHZaSE5jY2x4dUlDQWdJQzVuY205MWNDaHpkR0Z5ZEN4emRHOXdLU0F0TFNCdmRYUndkWFJ6SUdFZ1ozSnZkWEFnYjJZZ2JpQnBkR1Z0Y3lCbWNtOXRJSFJvWlNCc2FYTjBMQ0IzYVhSb0lIZHlZWEJ3YVc1blhISmNiaUFnSUNBdWJHOXZjQ2h6ZEdGeWRDeHpkRzl3S1NBdExTQmpiMjVtYVc1bGN5QnpaWEYxWlc1amFXNW5JSFJ2SUdFZ2MzVmljMlYwSUc5bUlIUm9aU0IyWVd4MVpYTmNjbHh1SUNBZ0lDQWdJQ0FvWTI5MWJHUWdaWFpsYmlCb1lYWmxJR0VnWkdsemRHbHVZM1JwYjI0Z1ltVjBkMlZsYmlBdWIzSnBaMmx1WVd4V1lXeDFaWE1nWVc1a0lIUm9aU0JoY25KaGVTQnZaaUIyWVd4MVpYTWdZbVZwYm1jZ2RYTmxaQ2xjY2x4dUlDQWdJQ292WEhKY2JuMWNjbHh1WEc1Y2JseHVMeThnVjBWQ1VFRkRTeUJHVDA5VVJWSWdMeTljYmk4dklDNHZmaTlxYzJocGJuUXRiRzloWkdWeUlTNHZiR2xpTDIxdlpHVnNjeTl6WlhGMVpXNWpaUzVxY3lJc0lpZDFjMlVnYzNSeWFXTjBKenRjYmx4dWFXMXdiM0owSUcxaGRHZ2dabkp2YlNBbkxpNHZkWFJwYkM5dFlYUm9KenRjYmx4dVpYaHdiM0owSUdSbFptRjFiSFFnWTJ4aGMzTWdSSEoxYm1zZ2UxeHVYRzRnSUNBZ1kyOXVjM1J5ZFdOMGIzSW9iV2x1UFRBc0lHMWhlRDA1TENCMllXeDFaVDB3TENCcGJtTnlaVzFsYm5ROU1Td2diRzl2Y0QxbVlXeHpaU2tnZTF4dUlDQWdJQ0FnSUNCMGFHbHpMbTFwYmlBOUlHMXBianRjYmlBZ0lDQWdJQ0FnZEdocGN5NXRZWGdnUFNCdFlYZzdYRzRnSUNBZ0lDQWdJSFJvYVhNdWRtRnNkV1VnUFNCMllXeDFaVHRjYmlBZ0lDQWdJQ0FnZEdocGN5NXBibU55WlcxbGJuUWdQU0JwYm1OeVpXMWxiblE3WEc0Z0lDQWdJQ0FnSUhSb2FYTXViRzl2Y0NBOUlHeHZiM0E3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdibVY0ZENncElIdGNiaUFnSUNBZ0lDQWdkR2hwY3k1MllXeDFaU0FyUFNCdFlYUm9MbkJwWTJzb0xURWdLaUIwYUdsekxtbHVZM0psYldWdWRDd2dkR2hwY3k1cGJtTnlaVzFsYm5RcE8xeHVJQ0FnSUNBZ0lDQnBaaUFvZEdocGN5NTJZV3gxWlNBK0lIUm9hWE11YldGNEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCcFppQW9kR2hwY3k1c2IyOXdLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZEdocGN5NTJZV3gxWlNBOUlIUm9hWE11YldsdU8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IwYUdsekxuWmhiSFZsSUQwZ2RHaHBjeTV0WVhnZ0xTQjBhR2x6TG1sdVkzSmxiV1Z1ZER0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZlZ4dVhHNGdJQ0FnSUNBZ0lHbG1JQ2gwYUdsekxuWmhiSFZsSUR3Z2RHaHBjeTV0YVc0cElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaDBhR2x6TG14dmIzQXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IwYUdsekxuWmhiSFZsSUQwZ2RHaHBjeTV0WVhnN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNdWRtRnNkV1VnUFNCMGFHbHpMbTFwYmlBcklIUm9hWE11YVc1amNtVnRaVzUwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUIwYUdsekxuWmhiSFZsTzF4dUlDQWdJSDFjYm4xY2JseHVYRzVjYmk4dklGZEZRbEJCUTBzZ1JrOVBWRVZTSUM4dlhHNHZMeUF1TDM0dmFuTm9hVzUwTFd4dllXUmxjaUV1TDJ4cFlpOXRiMlJsYkhNdlpISjFibXN1YW5NaUxDSW5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JtbHRjRzl5ZENCdFlYUm9JR1p5YjIwZ0p5NHVMM1YwYVd3dmJXRjBhQ2M3WEc1cGJYQnZjblFnUkhKMWJtc2dabkp2YlNBbkxpOWtjblZ1YXljN1hHNWNibVY0Y0c5eWRDQmtaV1poZFd4MElHTnNZWE56SUVOdmRXNTBaWElnZTF4dVhHNGdJQ0FnWTI5dWMzUnlkV04wYjNJb2JXbHVQVEFzSUcxaGVEMHhNQ3dnYlc5a1pUMG5kWEFuTENCMllXeDFaVDFtWVd4elpTa2dlMXh1SUNBZ0lDQWdJQ0IwYUdsekxtMXBiaUE5SUcxcGJqdGNiaUFnSUNBZ0lDQWdkR2hwY3k1dFlYZ2dQU0J0WVhnN1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZG1Gc2RXVWdQU0IyWVd4MVpUdGNiaUFnSUNBZ0lDQWdkR2hwY3k1dGIyUmxJRDBnYlc5a1pUdGNiaUFnSUNBZ0lDQWdkR2hwY3k1a2NuVnVhMWRoYkdzZ1BTQnVaWGNnUkhKMWJtc29kR2hwY3k1dGFXNHNJSFJvYVhNdWJXRjRLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tIUm9hWE11ZG1Gc2RXVWhQVDFtWVd4elpTa2dlMXh1SUNBZ0lDQWdJQ0FnSUhSb2FYTXVibVY0ZENBOUlIUm9hWE5iZEdocGN5NWZiVzlrWlYwN1hHNGdJQ0FnSUNBZ0lIMGdaV3h6WlNCN1hHNGdJQ0FnSUNBZ0lDQWdkR2hwY3k1dVpYaDBJRDBnZEdocGN5NW1hWEp6ZER0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgxY2JseHVJQ0FnSUhObGRDQnRiMlJsS0cxdlpHVXBJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tDRW9iVzlrWlNBOVBUMGdKM1Z3SnlCOGZDQnRiMlJsSUQwOVBTQW5aRzkzYmljZ2ZId2diVzlrWlNBOVBUMGdKM0poYm1SdmJTY2dmSHdnYlc5a1pTQTlQVDBnSjJSeWRXNXJKeWtwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR052Ym5OdmJHVXVaWEp5YjNJb0oxUm9aU0J2Ym14NUlHMXZaR1Z6SUdOMWNuSmxiblJzZVNCaGJHeHZkMlZrSUdGeVpUb2dkWEFzSUdSdmQyNHNJSEpoYm1SdmJTd2daSEoxYm1zbktUdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnlianRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCMGFHbHpMbDl0YjJSbElEMGdiVzlrWlR0Y2JpQWdJQ0FnSUNBZ2FXWWdLSFJvYVhNdWRtRnNkV1VwSUh0Y2JpQWdJQ0FnSUNBZ0lDQjBhR2x6TG01bGVIUWdQU0IwYUdselczUm9hWE11WDIxdlpHVmRPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdmVnh1WEc0Z0lDQWdaMlYwSUcxdlpHVW9LU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUIwYUdsekxsOXRiMlJsTzF4dUlDQWdJSDFjYmx4dUlDQWdJR1pwY25OMEtDa2dlMXh1SUNBZ0lDQWdhV1lnS0hSb2FYTXVkbUZzZFdVaFBUMW1ZV3h6WlNrZ2UxeHVJQ0FnSUNBZ0lDQjBhR2x6TG01bGVIUWdQU0IwYUdselczUm9hWE11WDIxdlpHVmRPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdkR2hwY3k1dVpYaDBLQ2s3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdJQ0IwYUdsekxuTjBZWEowVm1Gc2RXVnpJRDBnZTF4dUlDQWdJQ0FnSUNBbmRYQW5PaUIwYUdsekxtMXBiaXhjYmlBZ0lDQWdJQ0FnSjJSdmQyNG5PaUIwYUdsekxtMWhlQ3hjYmlBZ0lDQWdJQ0FnSjJSeWRXNXJKem9nZm41dFlYUm9MbUYyWlhKaFoyVW9kR2hwY3k1dGFXNHNkR2hwY3k1dFlYZ3BMRnh1SUNBZ0lDQWdJQ0FuY21GdVpHOXRKem9nYldGMGFDNXlhU2gwYUdsekxtMXBiaXgwYUdsekxtMWhlQ2xjYmlBZ0lDQWdJSDA3WEc0Z0lDQWdJQ0IwYUdsekxuWmhiSFZsSUQwZ2RHaHBjeTV6ZEdGeWRGWmhiSFZsYzF0MGFHbHpMbDl0YjJSbFhUdGNiaUFnSUNBZ0lIUm9hWE11Ym1WNGRDQTlJSFJvYVhOYmRHaHBjeTVmYlc5a1pWMDdYRzRnSUNBZ0lDQnlaWFIxY200Z2RHaHBjeTUyWVd4MVpUdGNiaUFnSUNCOVhHNWNiaUFnSUNCMWNDZ3BJSHRjYmlBZ0lDQWdJQ0FnZEdocGN5NTJZV3gxWlNzck8xeHVJQ0FnSUNBZ0lDQnBaaUFvZEdocGN5NTJZV3gxWlNBK1BTQjBhR2x6TG0xaGVDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2RHaHBjeTUyWVd4MVpTQTlJSFJvYVhNdWJXbHVPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUIwYUdsekxuWmhiSFZsTzF4dUlDQWdJSDFjYmx4dUlDQWdJR1J2ZDI0b0tTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWRtRnNkV1V0TFR0Y2JpQWdJQ0FnSUNBZ2FXWWdLSFJvYVhNdWRtRnNkV1VnUENCMGFHbHpMbTFwYmlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnZEdocGN5NTJZV3gxWlNBOUlIUm9hWE11YldGNE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQjBhR2x6TG5aaGJIVmxPMXh1SUNBZ0lIMWNibHh1SUNBZ0lISmhibVJ2YlNncElIdGNiaUFnSUNBZ0lDQWdkR2hwY3k1MllXeDFaU0E5SUcxaGRHZ3VjbWtvZEdocGN5NXRhVzRzSUhSb2FYTXViV0Y0S1R0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhSb2FYTXVkbUZzZFdVN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnWkhKMWJtc29LU0I3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVaSEoxYm10WFlXeHJMbTFwYmlBOUlIUm9hWE11YldsdU8xeHVJQ0FnSUNBZ0lDQjBhR2x6TG1SeWRXNXJWMkZzYXk1dFlYZ2dQU0IwYUdsekxtMWhlRHRjYmlBZ0lDQWdJQ0FnZEdocGN5NWtjblZ1YTFkaGJHc3VkbUZzZFdVZ1BTQjBhR2x6TG5aaGJIVmxPMXh1SUNBZ0lDQWdJQ0IwYUdsekxuWmhiSFZsSUQwZ2RHaHBjeTVrY25WdWExZGhiR3N1Ym1WNGRDZ3BPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdkR2hwY3k1MllXeDFaVHRjYmlBZ0lDQjlYRzU5WEc1Y2JseHVYRzR2THlCWFJVSlFRVU5MSUVaUFQxUkZVaUF2TDF4dUx5OGdMaTkrTDJwemFHbHVkQzFzYjJGa1pYSWhMaTlzYVdJdmJXOWtaV3h6TDJOdmRXNTBaWEl1YW5NaUxDSW5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JteGxkQ0J6ZG1jZ1BTQnlaWEYxYVhKbEtDY3VMaTkxZEdsc0wzTjJaeWNwTzF4dWJHVjBJRzFoZEdnZ1BTQnlaWEYxYVhKbEtDY3VMaTkxZEdsc0wyMWhkR2duS1R0Y2JteGxkQ0JKYm5SbGNtWmhZMlVnUFNCeVpYRjFhWEpsS0NjdUxpOWpiM0psTDJsdWRHVnlabUZqWlNjcE8xeHViR1YwSUZOMFpYQWdQU0J5WlhGMWFYSmxLQ2N1TGk5dGIyUmxiSE12YzNSbGNDY3BPMXh1YVcxd2IzSjBJQ29nWVhNZ1NXNTBaWEpoWTNScGIyNGdabkp2YlNBbkxpNHZkWFJwYkM5cGJuUmxjbUZqZEdsdmJpYzdYRzVjYmk4cUtseHVLaUJRWVc0eVJGeHVLbHh1S2lCQVpHVnpZM0pwY0hScGIyNGdTVzUwWlhKbVlXTmxJR1p2Y2lCdGIzWnBibWNnWVNCemIzVnVaQ0JoY205MWJtUWdZVzRnWVhKeVlYa2diMllnYzNCbFlXdGxjbk11SUZOd1pXRnJaWElnYkc5allYUnBiMjV6SUdOaGJpQmlaU0JqZFhOMGIyMXBlbVZrTGlCVWFHVWdhVzUwWlhKbVlXTmxJR05oYkdOMWJHRjBaWE1nZEdobElHTnNiM05sYm1WemN5QnZaaUIwYUdVZ2MyOTFibVFnYzI5MWNtTmxJSFJ2SUdWaFkyZ2djM0JsWVd0bGNpQmhibVFnY21WMGRYSnVjeUIwYUdGMElHUnBjM1JoYm1ObElHRnpJR0VnYm5WdFpYSnBZeUIyWVd4MVpTNWNiaXBjYmlvZ1FHUmxiVzhnUEhOd1lXNGdibVY0ZFhNdGRXazlYQ0p3WVc0eVJGd2lQand2YzNCaGJqNWNiaXBjYmlvZ1FHVjRZVzF3YkdWY2Jpb2dkbUZ5SUhCaGJqSmtJRDBnYm1WM0lFNWxlSFZ6TGxCaGJqSmtLQ2NqZEdGeVoyVjBKeWxjYmlwY2Jpb2dRR1Y0WVcxd2JHVmNiaW9nZG1GeUlIQmhiakprSUQwZ2JtVjNJRTVsZUhWekxsQmhiakpFS0NjamRHRnlaMlYwSnl4N1hHNHFJQ0FnSjNOcGVtVW5PaUJiTWpBd0xESXdNRjBzWEc0cUlDQWdKM0poYm1kbEp6b2dNQzQxTENBZ0x5OGdaR1YwWldOMGFXOXVJSEpoWkdsMWN5QnZaaUJsWVdOb0lITndaV0ZyWlhKY2Jpb2dJQ0FuYlc5a1pTYzZJQ2RoWW5OdmJIVjBaU2NzSUNBZ0x5OGdKMkZpYzI5c2RYUmxKeUJ2Y2lBbmNtVnNZWFJwZG1VbklITnZkVzVrSUcxdmRtVnRaVzUwWEc0cUlDQWdKM053WldGclpYSnpKem9nV3lBZ0x5OGdkR2hsSUhOd1pXRnJaWElnVzNnc2VWMGdjRzl6YVhScGIyNXpYRzRxSUNBZ0lDQWdJRnN3TGpVc01DNHlYU3hjYmlvZ0lDQWdJQ0FnV3pBdU56VXNNQzR5TlYwc1hHNHFJQ0FnSUNBZ0lGc3dMamdzTUM0MVhTeGNiaW9nSUNBZ0lDQWdXekF1TnpVc01DNDNOVjBzWEc0cUlDQWdJQ0FnSUZzd0xqVXNNQzQ0WFN4Y2Jpb2dJQ0FnSUNBZ1d6QXVNalVzTUM0M05WMWNiaW9nSUNBZ0lDQWdXekF1TWl3d0xqVmRMRnh1S2lBZ0lDQWdJQ0JiTUM0eU5Td3dMakkxWFZ4dUtpQWdJRjFjYmlvZ2ZTbGNiaXBjYmlvZ1FHOTFkSEIxZEZ4dUtpQmphR0Z1WjJWY2Jpb2dSbWx5WlhNZ1lXNTVJSFJwYldVZ2RHaGxJRndpYzI5MWNtTmxYQ0lnYm05a1pTZHpJSEJ2YzJsMGFXOXVJR05vWVc1blpYTXVJRHhpY2o1Y2Jpb2dWR2hsSUdWMlpXNTBJR1JoZEdFZ2FYTWdZVzRnWVhKeVlYa2diMllnZEdobElHRnRjR3hwZEhWa1pYTWdLREF0TVNrc0lISmxjSEpsYzJWdWRHbHVaeUIwYUdVZ2JHVjJaV3dnYjJZZ1pXRmphQ0J6Y0dWaGEyVnlJQ2hoY3lCallXeGpkV3hoZEdWa0lHSjVJR2wwY3lCa2FYTjBZVzVqWlNCMGJ5QjBhR1VnWVhWa2FXOGdjMjkxY21ObEtTNWNiaXBjYmlvZ1FHOTFkSEIxZEdWNFlXMXdiR1ZjYmlvZ2NHRnVNbVF1YjI0b0oyTm9ZVzVuWlNjc1puVnVZM1JwYjI0b2Rpa2dlMXh1S2lBZ0lHTnZibk52YkdVdWJHOW5LSFlwTzF4dUtpQjlLVnh1S2x4dUtpOWNibHh1Wlhod2IzSjBJR1JsWm1GMWJIUWdZMnhoYzNNZ1VHRnVNa1FnWlhoMFpXNWtjeUJKYm5SbGNtWmhZMlVnZTF4dVhHNGdJR052Ym5OMGNuVmpkRzl5S0NrZ2UxeHVYRzRnSUNBZ2JHVjBJRzl3ZEdsdmJuTWdQU0JiSjNKaGJtZGxKMTA3WEc1Y2JpQWdJQ0JzWlhRZ1pHVm1ZWFZzZEhNZ1BTQjdYRzRnSUNBZ0lDQW5jMmw2WlNjNklGc3lNREFzTWpBd1hTeGNiaUFnSUNBZ0lDZHlZVzVuWlNjNklEQXVOU3hjYmlBZ0lDQWdJQ2R0YjJSbEp6b2dKMkZpYzI5c2RYUmxKeXhjYmlBZ0lDQWdJQ2R6Y0dWaGEyVnljeWM2SUZ0Y2JpQWdJQ0FnSUNBZ1d6QXVOU3d3TGpKZExGeHVJQ0FnSUNBZ0lDQmJNQzQzTlN3d0xqSTFYU3hjYmlBZ0lDQWdJQ0FnV3pBdU9Dd3dMalZkTEZ4dUlDQWdJQ0FnSUNCYk1DNDNOU3d3TGpjMVhTeGNiaUFnSUNBZ0lDQWdXekF1TlN3d0xqaGRMRnh1SUNBZ0lDQWdJQ0JiTUM0eU5Td3dMamMxWFN4Y2JpQWdJQ0FnSUNBZ1d6QXVNaXd3TGpWZExGeHVJQ0FnSUNBZ0lDQmJNQzR5TlN3d0xqSTFYVnh1SUNBZ0lDQWdYVnh1SUNBZ0lIMDdYRzVjYmlBZ0lDQnpkWEJsY2loaGNtZDFiV1Z1ZEhNc2IzQjBhVzl1Y3l4a1pXWmhkV3gwY3lrN1hHNWNiaUFnSUNCMGFHbHpMblpoYkhWbElEMGdlMXh1SUNBZ0lDQWdlRG9nYm1WM0lGTjBaWEFvTUN3eExEQXNNQzQxS1N4Y2JpQWdJQ0FnSUhrNklHNWxkeUJUZEdWd0tEQXNNU3d3TERBdU5TbGNiaUFnSUNCOU8xeHVYRzRnSUNBZ0x5b3FYRzRnSUNBZ1FXSnpiMngxZEdVZ2IzSWdjbVZzWVhScGRtVWdiVzkxYzJVZ2FXNTBaWEpoWTNScGIyNHVJRWx1SUZ3aVlXSnpiMngxZEdWY0lpQnRiMlJsTENCMGFHVWdjMjkxY21ObElHNXZaR1VnZDJsc2JDQnFkVzF3SUhSdklIbHZkWElnYlc5MWMyVWdjRzl6YVhScGIyNGdiMjRnYlc5MWMyVWdZMnhwWTJzdUlFbHVJRndpY21Wc1lYUnBkbVZjSWlCdGIyUmxMQ0JwZENCa2IyVnpJRzV2ZEM1Y2JpQWdJQ0FxTDF4dUlDQWdJSFJvYVhNdWJXOWtaU0E5SUhSb2FYTXVjMlYwZEdsdVozTXViVzlrWlR0Y2JseHVJQ0FnSUhSb2FYTXVjRzl6YVhScGIyNGdQU0I3WEc0Z0lDQWdJQ0I0T2lCdVpYY2dTVzUwWlhKaFkzUnBiMjR1U0dGdVpHeGxLSFJvYVhNdWJXOWtaU3duYUc5eWFYcHZiblJoYkNjc1d6QXNkR2hwY3k1M2FXUjBhRjBzVzNSb2FYTXVhR1ZwWjJoMExEQmRLU3hjYmlBZ0lDQWdJSGs2SUc1bGR5QkpiblJsY21GamRHbHZiaTVJWVc1a2JHVW9kR2hwY3k1dGIyUmxMQ2QyWlhKMGFXTmhiQ2NzV3pBc2RHaHBjeTUzYVdSMGFGMHNXM1JvYVhNdWFHVnBaMmgwTERCZEtWeHVJQ0FnSUgwN1hHNGdJQ0FnZEdocGN5NXdiM05wZEdsdmJpNTRMblpoYkhWbElEMGdkR2hwY3k1MllXeDFaUzU0TG01dmNtMWhiR2w2WldRN1hHNGdJQ0FnZEdocGN5NXdiM05wZEdsdmJpNTVMblpoYkhWbElEMGdkR2hwY3k1MllXeDFaUzU1TG01dmNtMWhiR2w2WldRN1hHNWNiaUFnSUNBdktpcGNiaUFnSUNCQmJpQmhjbkpoZVNCdlppQnpjR1ZoYTJWeUlHeHZZMkYwYVc5dWN5NGdWWEJrWVhSbElIUm9hWE1nZDJsMGFDQXViVzkyWlZOd1pXRnJaWElvS1NCdmNpQXViVzkyWlVGc2JGTndaV0ZyWlhKektDbGNiaUFnSUNBcUwxeHVJQ0FnSUhSb2FYTXVjM0JsWVd0bGNuTWdQU0IwYUdsekxuTmxkSFJwYm1kekxuTndaV0ZyWlhKek8xeHVYRzRnSUNBZ0x5b3FYRzRnSUNBZ1VtVjNjbWwwWlRvZ1ZHaGxJRzFoZUdsdGRXMGdaR2x6ZEdGdVkyVWdabkp2YlNCaElITndaV0ZyWlhJZ2RHaGhkQ0IwYUdVZ2MyOTFjbU5sSUc1dlpHVWdZMkZ1SUdKbElHWnZjaUJwZENCMGJ5QmlaU0JvWldGeVpDQm1jbTl0SUhSb1lYUWdjM0JsWVd0bGNpNGdRU0JzYjNjZ2NtRnVaMlVnS0RBdU1Ta2dkMmxzYkNCeVpYTjFiSFFnYVc0Z2MzQmxZV3RsY25NZ2IyNXNlU0J3YkdGNWFXNW5JSGRvWlc0Z2RHaGxJSE52ZFc1a0lHbHpJSFpsY25rZ1kyeHZjMlVnYVhRdUlFUmxabUYxYkhRZ2FYTWdNQzQxSUNob1lXeG1JRzltSUhSb1pTQnBiblJsY21aaFkyVXBMbHh1SUNBZ0lDb3ZYRzRnSUNBZ2RHaHBjeTV5WVc1blpTQTlJSFJvYVhNdWMyVjBkR2x1WjNNdWNtRnVaMlU3WEc1Y2JpQWdJQ0F2S2lwY2JpQWdJQ0JVYUdVZ1kzVnljbVZ1ZENCc1pYWmxiSE1nWm05eUlHVmhZMmdnYzNCbFlXdGxjaTRnVkdocGN5QnBjeUJqWVd4amRXeGhkR1ZrSUhkb1pXNGdZU0J6YjNWeVkyVWdibTlrWlNCdmNpQnpjR1ZoYTJWeUlHNXZaR1VnYVhNZ2JXOTJaV1FnZEdoeWIzVm5hQ0JwYm5SbGNtRmpkR2x2YmlCdmNpQndjbTluY21GdFlYUnBZMkZzYkhrdVhHNGdJQ0FnS2k5Y2JpQWdJQ0IwYUdsekxteGxkbVZzY3lBOUlGdGRPMXh1WEc0Z0lDQWdkR2hwY3k1cGJtbDBLQ2s3WEc1Y2JpQWdJQ0IwYUdsekxtTmhiR04xYkdGMFpVeGxkbVZzY3lncE8xeHVJQ0FnSUhSb2FYTXVjbVZ1WkdWeUtDazdYRzVjYmlBZ2ZWeHVYRzRnSUdKMWFXeGtTVzUwWlhKbVlXTmxLQ2tnZTF4dVhHNGdJQ0FnZEdocGN5NXJibTlpSUQwZ2MzWm5MbU55WldGMFpTZ25ZMmx5WTJ4bEp5azdYRzVjYmx4dUlDQWdJSFJvYVhNdVpXeGxiV1Z1ZEM1aGNIQmxibVJEYUdsc1pDaDBhR2x6TG10dWIySXBPMXh1WEc1Y2JpQWdJQ0F2THlCaFpHUWdjM0JsWVd0bGNuTmNiaUFnSUNCMGFHbHpMbk53WldGclpYSkZiR1Z0Wlc1MGN5QTlJRnRkTzF4dVhHNGdJQ0FnWm05eUlDaHNaWFFnYVQwd08yazhkR2hwY3k1emNHVmhhMlZ5Y3k1c1pXNW5kR2c3YVNzcktTQjdYRzRnSUNBZ0lDQnNaWFFnYzNCbFlXdGxja1ZzWlcxbGJuUWdQU0J6ZG1jdVkzSmxZWFJsS0NkamFYSmpiR1VuS1R0Y2JseHVJQ0FnSUNBZ2RHaHBjeTVsYkdWdFpXNTBMbUZ3Y0dWdVpFTm9hV3hrS0hOd1pXRnJaWEpGYkdWdFpXNTBLVHRjYmx4dUlDQWdJQ0FnZEdocGN5NXpjR1ZoYTJWeVJXeGxiV1Z1ZEhNdWNIVnphQ2h6Y0dWaGEyVnlSV3hsYldWdWRDazdYRzRnSUNBZ2ZWeHVYRzRnSUgxY2JseHVJQ0J6YVhwbFNXNTBaWEptWVdObEtDa2dlMXh1WEc0Z0lDQWdJQ0FnSUhSb2FYTXVYMjFwYmtScGJXVnVjMmx2YmlBOUlFMWhkR2d1YldsdUtIUm9hWE11ZDJsa2RHZ3NkR2hwY3k1b1pXbG5hSFFwTzF4dVhHNGdJQ0FnSUNBZ0lIUm9hWE11YTI1dllsSmhaR2wxY3lBOUlIdGNiaUFnSUNBZ0lDQWdJQ0J2Wm1ZNklINStLSFJvYVhNdVgyMXBia1JwYldWdWMybHZiaTh4TURBcElDb2dNeUFySURVc1hHNGdJQ0FnSUNBZ0lIMDdYRzRnSUNBZ0lDQWdJSFJvYVhNdWEyNXZZbEpoWkdsMWN5NXZiaUE5SUhSb2FYTXVhMjV2WWxKaFpHbDFjeTV2Wm1ZZ0tpQXlPMXh1WEc0Z0lDQWdJQ0FnSUhSb2FYTXVhMjV2WWk1elpYUkJkSFJ5YVdKMWRHVW9KMk40Snl4MGFHbHpMbmRwWkhSb0x6SXBPMXh1SUNBZ0lDQWdJQ0IwYUdsekxtdHViMkl1YzJWMFFYUjBjbWxpZFhSbEtDZGplU2NzZEdocGN5NW9aV2xuYUhRdk1pazdYRzRnSUNBZ0lDQWdJSFJvYVhNdWEyNXZZaTV6WlhSQmRIUnlhV0oxZEdVb0ozSW5MSFJvYVhNdWEyNXZZbEpoWkdsMWN5NXZabVlwTzF4dVhHNGdJQ0FnSUNBZ0lHWnZjaUFvYkdWMElHazlNRHRwUEhSb2FYTXVjM0JsWVd0bGNuTXViR1Z1WjNSb08ya3JLeWtnZTF4dUlDQWdJQ0FnSUNBZ0lHeGxkQ0J6Y0dWaGEyVnlSV3hsYldWdWRDQTlJSFJvYVhNdWMzQmxZV3RsY2tWc1pXMWxiblJ6VzJsZE8xeHVJQ0FnSUNBZ0lDQWdJR3hsZENCemNHVmhhMlZ5SUQwZ2RHaHBjeTV6Y0dWaGEyVnljMXRwWFR0Y2JpQWdJQ0FnSUNBZ0lDQnpjR1ZoYTJWeVJXeGxiV1Z1ZEM1elpYUkJkSFJ5YVdKMWRHVW9KMk40Snl4emNHVmhhMlZ5V3pCZEtuUm9hWE11ZDJsa2RHZ3BPMXh1SUNBZ0lDQWdJQ0FnSUhOd1pXRnJaWEpGYkdWdFpXNTBMbk5sZEVGMGRISnBZblYwWlNnblkza25MSE53WldGclpYSmJNVjBxZEdocGN5NW9aV2xuYUhRcE8xeHVJQ0FnSUNBZ0lDQWdJSE53WldGclpYSkZiR1Z0Wlc1MExuTmxkRUYwZEhKcFluVjBaU2duY2ljc2RHaHBjeTVmYldsdVJHbHRaVzV6YVc5dUx6SXdJQ3NnTlNrN1hHNGdJQ0FnSUNBZ0lDQWdjM0JsWVd0bGNrVnNaVzFsYm5RdWMyVjBRWFIwY21saWRYUmxLQ2RtYVd4c0xXOXdZV05wZEhrbkxDQW5NQ2NwTzF4dUlDQWdJQ0FnSUNCOVhHNWNiaUFnSUNBZ0lIUm9hWE11Y0c5emFYUnBiMjR1ZUM1eVpYTnBlbVVvV3pBc2RHaHBjeTUzYVdSMGFGMHNXM1JvYVhNdWFHVnBaMmgwTERCZEtUdGNiaUFnSUNBZ0lIUm9hWE11Y0c5emFYUnBiMjR1ZVM1eVpYTnBlbVVvV3pBc2RHaHBjeTUzYVdSMGFGMHNXM1JvYVhNdWFHVnBaMmgwTERCZEtUdGNibHh1SUNBZ0lDQWdJQ0F2THlCdVpYaDBMQ0J1WldWa0lIUnZYRzRnSUNBZ0lDQWdJQzh2SUhKbGMybDZaU0J3YjNOcGRHbHZibk5jYmlBZ0lDQWdJQ0FnTHk4Z1kyRnNZM1ZzWVhSbElITndaV0ZyWlhJZ1pHbHpkR0Z1WTJWelhHNGdJQ0FnSUNCMGFHbHpMbU5oYkdOMWJHRjBaVXhsZG1Wc2N5Z3BPMXh1SUNBZ0lDQWdkR2hwY3k1eVpXNWtaWElvS1R0Y2JseHVJQ0I5WEc1Y2JpQWdZMjlzYjNKSmJuUmxjbVpoWTJVb0tTQjdYRzVjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1YzNSNWJHVXVZbUZqYTJkeWIzVnVaRU52Ykc5eUlEMGdkR2hwY3k1amIyeHZjbk11Wm1sc2JEdGNiaUFnSUNCMGFHbHpMbXR1YjJJdWMyVjBRWFIwY21saWRYUmxLQ2RtYVd4c0p5d2dkR2hwY3k1amIyeHZjbk11YldWa2FYVnRUR2xuYUhRcE8xeHVYRzRnSUNBZ1ptOXlJQ2hzWlhRZ2FUMHdPMms4ZEdocGN5NXpjR1ZoYTJWeWN5NXNaVzVuZEdnN2FTc3JLU0I3WEc0Z0lDQWdJQ0JzWlhRZ2MzQmxZV3RsY2tWc1pXMWxiblFnUFNCMGFHbHpMbk53WldGclpYSkZiR1Z0Wlc1MGMxdHBYVHRjYmlBZ0lDQWdJSE53WldGclpYSkZiR1Z0Wlc1MExuTmxkRUYwZEhKcFluVjBaU2duWm1sc2JDY3NJSFJvYVhNdVkyOXNiM0p6TG1GalkyVnVkQ2s3WEc0Z0lDQWdJQ0J6Y0dWaGEyVnlSV3hsYldWdWRDNXpaWFJCZEhSeWFXSjFkR1VvSjNOMGNtOXJaU2NzSUhSb2FYTXVZMjlzYjNKekxtRmpZMlZ1ZENrN1hHNGdJQ0FnZlZ4dVhHNGdJSDFjYmx4dUlDQnlaVzVrWlhJb0tTQjdYRzRnSUNBZ2RHaHBjeTVyYm05aVEyOXZjbVJwYm1GMFpYTWdQU0I3WEc0Z0lDQWdJQ0I0T2lCMGFHbHpMblpoYkhWbExuZ3VibTl5YldGc2FYcGxaQ0FxSUhSb2FYTXVkMmxrZEdnc1hHNGdJQ0FnSUNCNU9pQjBhR2x6TG1obGFXZG9kQ0F0SUhSb2FYTXVkbUZzZFdVdWVTNXViM0p0WVd4cGVtVmtJQ29nZEdocGN5NW9aV2xuYUhSY2JpQWdJQ0I5TzF4dVhHNGdJQ0FnZEdocGN5NXJibTlpTG5ObGRFRjBkSEpwWW5WMFpTZ25ZM2duTEhSb2FYTXVhMjV2WWtOdmIzSmthVzVoZEdWekxuZ3BPMXh1SUNBZ0lIUm9hWE11YTI1dllpNXpaWFJCZEhSeWFXSjFkR1VvSjJONUp5eDBhR2x6TG10dWIySkRiMjl5WkdsdVlYUmxjeTU1S1R0Y2JpQWdmVnh1WEc1Y2JpQWdZMnhwWTJzb0tTQjdYRzRnSUNBZ2RHaHBjeTV3YjNOcGRHbHZiaTU0TG1GdVkyaHZjaUE5SUhSb2FYTXViVzkxYzJVN1hHNGdJQ0FnZEdocGN5NXdiM05wZEdsdmJpNTVMbUZ1WTJodmNpQTlJSFJvYVhNdWJXOTFjMlU3WEc0Z0lDQWdkR2hwY3k1dGIzWmxLQ2s3WEc0Z0lIMWNibHh1SUNCdGIzWmxLQ2tnZTF4dUlDQWdJR2xtSUNoMGFHbHpMbU5zYVdOclpXUXBJSHRjYmlBZ0lDQWdJSFJvYVhNdWNHOXphWFJwYjI0dWVDNTFjR1JoZEdVb2RHaHBjeTV0YjNWelpTazdYRzRnSUNBZ0lDQjBhR2x6TG5CdmMybDBhVzl1TG5rdWRYQmtZWFJsS0hSb2FYTXViVzkxYzJVcE8xeHVJQ0FnSUNBZ0x5OGdjRzl6YVhScGIyNHVlQ0JoYm1RZ2NHOXphWFJwYjI0dWVTQmhjbVVnYm05eWJXRnNhWHBsWkZ4dUlDQWdJQ0FnTHk4Z2MyOGdZWEpsSUhSb1pTQnNaWFpsYkhOY2JpQWdJQ0FnSUM4dklHeHBhMlZzZVNCa2IyNG5kQ0J1WldWa0lIUm9hWE11ZG1Gc2RXVWdZWFFnWVd4c0lDMHRJRzl1YkhrZ2RYTmxaQ0JtYjNJZ1pISmhkMmx1WjF4dUlDQWdJQ0FnTHk4Z2JtOTBJR2R2YVc1bklIUnZJR0psSUdFZ0ozTjBaWEFuSUc5eUlDZHRhVzRuSUdGdVpDQW5iV0Y0SnlCcGJpQjBhR2x6SUc5dVpTNWNiaUFnSUNBZ0lIUm9hWE11WTJGc1kzVnNZWFJsVEdWMlpXeHpLQ2s3WEc0Z0lDQWdJQ0IwYUdsekxtVnRhWFFvSjJOb1lXNW5aU2NzZEdocGN5NXNaWFpsYkhNcE8xeHVJQ0FnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmlBZ0lDQjlYRzRnSUgxY2JseHVJQ0J5Wld4bFlYTmxLQ2tnZTF4dUlDQWdJSFJvYVhNdWNtVnVaR1Z5S0NrN1hHNGdJSDFjYmx4dUlDQm5aWFFnYm05eWJXRnNhWHBsWkNncElIdGNiaUFnSUNCeVpYUjFjbTRnZTF4dUlDQWdJQ0FnZURvZ2RHaHBjeTUyWVd4MVpTNTRMbTV2Y20xaGJHbDZaV1FzWEc0Z0lDQWdJQ0I1T2lCMGFHbHpMblpoYkhWbExua3VibTl5YldGc2FYcGxaRnh1SUNBZ0lIMDdYRzRnSUgxY2JseHVJQ0JqWVd4amRXeGhkR1ZNWlhabGJITW9LU0I3WEc0Z0lDQWdkR2hwY3k1MllXeDFaUzU0TG5Wd1pHRjBaVTV2Y20xaGJDZ2dkR2hwY3k1d2IzTnBkR2x2Ymk1NExuWmhiSFZsSUNrN1hHNGdJQ0FnZEdocGN5NTJZV3gxWlM1NUxuVndaR0YwWlU1dmNtMWhiQ2dnZEdocGN5NXdiM05wZEdsdmJpNTVMblpoYkhWbElDazdYRzRnSUNBZ2RHaHBjeTVzWlhabGJITWdQU0JiWFR0Y2JpQWdJQ0IwYUdsekxuTndaV0ZyWlhKekxtWnZja1ZoWTJnb0tITXNhU2tnUFQ0Z2UxeHVJQ0FnSUNBZ2JHVjBJR1JwYzNSaGJtTmxJRDBnYldGMGFDNWthWE4wWVc1alpTaHpXekJkS25Sb2FYTXVkMmxrZEdnc2Mxc3hYU3AwYUdsekxtaGxhV2RvZEN4MGFHbHpMbkJ2YzJsMGFXOXVMbmd1ZG1Gc2RXVXFkR2hwY3k1M2FXUjBhQ3dvTVMxMGFHbHpMbkJ2YzJsMGFXOXVMbmt1ZG1Gc2RXVXBLblJvYVhNdWFHVnBaMmgwS1R0Y2JpQWdJQ0FnSUd4bGRDQnNaWFpsYkNBOUlHMWhkR2d1WTJ4cGNDZ3hMV1JwYzNSaGJtTmxMeWgwYUdsekxuSmhibWRsS25Sb2FYTXVkMmxrZEdncExEQXNNU2s3WEc0Z0lDQWdJQ0IwYUdsekxteGxkbVZzY3k1d2RYTm9LR3hsZG1Wc0tUdGNiaUFnSUNBZ0lIUm9hWE11YzNCbFlXdGxja1ZzWlcxbGJuUnpXMmxkTG5ObGRFRjBkSEpwWW5WMFpTZ25abWxzYkMxdmNHRmphWFI1Snl3Z2JHVjJaV3dwTzF4dUlDQWdJSDBwTzF4dUlDQjlYRzVjYmlBZ0x5b3FYRzRnSUUxdmRtVWdkR2hsSUdGMVpHbHZJSE52ZFhKalpTQnViMlJsSUdGdVpDQjBjbWxuWjJWeUlIUm9aU0J2ZFhSd2RYUWdaWFpsYm5RdVhHNGdJRUJ3WVhKaGJTQjRJSHR1ZFcxaVpYSjlJRTVsZHlCNElHeHZZMkYwYVc5dUxDQnViM0p0WVd4cGVtVmtJREF0TVZ4dUlDQkFjR0Z5WVcwZ2VTQjdiblZ0WW1WeWZTQk9aWGNnZVNCc2IyTmhkR2x2Yml3Z2JtOXliV0ZzYVhwbFpDQXdMVEZjYmlBZ0tpOWNiaUFnYlc5MlpWTnZkWEpqWlNoNExIa3BJSHRjYmlBZ0lDQnNaWFFnYkc5allYUnBiMjRnUFNCN1hHNGdJQ0FnSUNCNE9pQjRLblJvYVhNdWQybGtkR2dzWEc0Z0lDQWdJQ0I1T2lCNUtuUm9hWE11YUdWcFoyaDBYRzRnSUNBZ2ZUdGNiaUFnSUNCMGFHbHpMbkJ2YzJsMGFXOXVMbmd1ZFhCa1lYUmxLR3h2WTJGMGFXOXVLVHRjYmlBZ0lDQjBhR2x6TG5CdmMybDBhVzl1TG5rdWRYQmtZWFJsS0d4dlkyRjBhVzl1S1R0Y2JpQWdJQ0IwYUdsekxtTmhiR04xYkdGMFpVeGxkbVZzY3lncE8xeHVJQ0FnSUhSb2FYTXVaVzFwZENnblkyaGhibWRsSnl4MGFHbHpMbXhsZG1Wc2N5azdYRzRnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmlBZ2ZWeHVYRzRnSUM4cUtseHVJQ0JOYjNabElHRWdjM0JsWVd0bGNpQnViMlJsSUdGdVpDQjBjbWxuWjJWeUlIUm9aU0J2ZFhSd2RYUWdaWFpsYm5RdVhHNGdJRUJ3WVhKaGJTQnBibVJsZUNCN2JuVnRZbVZ5ZlNCSmJtUmxlQ0J2WmlCMGFHVWdjM0JsWVd0bGNpQjBieUJ0YjNabFhHNGdJRUJ3WVhKaGJTQjRJSHR1ZFcxaVpYSjlJRTVsZHlCNElHeHZZMkYwYVc5dUxDQnViM0p0WVd4cGVtVmtJREF0TVZ4dUlDQkFjR0Z5WVcwZ2VTQjdiblZ0WW1WeWZTQk9aWGNnZVNCc2IyTmhkR2x2Yml3Z2JtOXliV0ZzYVhwbFpDQXdMVEZjYmlBZ0tpOWNiaUFnYlc5MlpWTndaV0ZyWlhJb2FXNWtaWGdzZUN4NUtTQjdYRzVjYmlBZ0lDQjBhR2x6TG5Od1pXRnJaWEp6VzJsdVpHVjRYU0E5SUZ0NExIbGRPMXh1SUNBZ0lIUm9hWE11YzNCbFlXdGxja1ZzWlcxbGJuUnpXMmx1WkdWNFhTNXpaWFJCZEhSeWFXSjFkR1VvSjJONEp5d2dlQ3AwYUdsekxuZHBaSFJvS1R0Y2JpQWdJQ0IwYUdsekxuTndaV0ZyWlhKRmJHVnRaVzUwYzF0cGJtUmxlRjB1YzJWMFFYUjBjbWxpZFhSbEtDZGplU2NzSUhrcWRHaHBjeTVvWldsbmFIUXBPMXh1SUNBZ0lIUm9hWE11WTJGc1kzVnNZWFJsVEdWMlpXeHpLQ2s3WEc0Z0lDQWdkR2hwY3k1bGJXbDBLQ2RqYUdGdVoyVW5MSFJvYVhNdWJHVjJaV3h6S1R0Y2JpQWdJQ0IwYUdsekxuSmxibVJsY2lncE8xeHVYRzRnSUgxY2JseHVJQ0F2S2lwY2JpQWdVMlYwSUdGc2JDQnpjR1ZoYTJWeUlHeHZZMkYwYVc5dWMxeHVJQ0JBY0dGeVlXMGdiRzlqWVhScGIyNXpJSHRCY25KaGVYMGdRWEp5WVhrZ2IyWWdjM0JsWVd0bGNpQnNiMk5oZEdsdmJuTXVJRVZoWTJnZ2FYUmxiU0JwYmlCMGFHVWdZWEp5WVhrZ2MyaHZkV3hrSUdKbElHRnVJR0Z5Y21GNUlHOW1JRzV2Y20xaGJHbDZaV1FnZUNCaGJtUWdlU0JqYjI5eVpHbHVZWFJsY3k1Y2JseHVJQ0J6WlhSVGNHVmhhMlZ5Y3loc2IyTmhkR2x2Ym5NcElIdGNibHh1SUNCOVhHNGdJQ292WEc1Y2JuMWNibHh1WEc1Y2JpOHZJRmRGUWxCQlEwc2dSazlQVkVWU0lDOHZYRzR2THlBdUwzNHZhbk5vYVc1MExXeHZZV1JsY2lFdUwyeHBZaTlwYm5SbGNtWmhZMlZ6TDNCaGJqSmtMbXB6SWl3aUozVnpaU0J6ZEhKcFkzUW5PMXh1WEc1c1pYUWdiV0YwYUNBOUlISmxjWFZwY21Vb0p5NHVMM1YwYVd3dmJXRjBhQ2NwTzF4dWJHVjBJSE4yWnlBOUlISmxjWFZwY21Vb0p5NHVMM1YwYVd3dmMzWm5KeWs3WEc1c1pYUWdTVzUwWlhKbVlXTmxJRDBnY21WeGRXbHlaU2duTGk0dlkyOXlaUzlwYm5SbGNtWmhZMlVuS1R0Y2JseHVMeW9xWEc0cUlGUnBiSFJjYmlwY2Jpb2dRR1JsYzJOeWFYQjBhVzl1SUVSbGRtbGpaU0IwYVd4MElITmxibk52Y2lCM2FYUm9JRElnYjNJZ015QmhlR1Z6SUNoa1pYQmxibVJwYm1jZ2IyNGdlVzkxY2lCa1pYWnBZMlVnWVc1a0lHSnliM2R6WlhJcExseHVLbHh1S2lCQVpHVnRieUE4YzNCaGJpQnVaWGgxY3kxMWFUMG5kR2xzZENjK1BDOXpjR0Z1UGx4dUtseHVLaUJBWlhoaGJYQnNaVnh1S2lCMllYSWdkR2xzZENBOUlHNWxkeUJPWlhoMWN5NVVhV3gwS0NjamRHRnlaMlYwSnlsY2JpcGNiaW9nUUc5MWRIQjFkRnh1S2lCamFHRnVaMlZjYmlvZ1JtbHlaWE1nWVhRZ1lTQnlaV2QxYkdGeUlHbHVkR1Z5ZG1Gc0xDQmhjeUJzYjI1bklHRnpJSFJvYVhNZ2FXNTBaWEptWVdObElHbHpJR0ZqZEdsMlpTQW9jMlZsSUhSb1pTQnBiblJsY21aaFkyVW5jeUE4YVQ0dVlXTjBhWFpsUEM5cFBpQndjbTl3WlhKMGVTazhZbkkrWEc0cUlGUm9aU0JsZG1WdWRDQmtZWFJoSUdseklHRnVJRHhwUG05aWFtVmpkRHd2YVQ0Z1kyOXVkR0ZwYm1sdVp5QjRJQ2h1ZFcxaVpYSXBJR0Z1WkNCNUlDaHVkVzFpWlhJcElIQnliM0JsY25ScFpYTWdkMmhwWTJnZ2NtVndjbVZ6Wlc1MElIUm9aU0JqZFhKeVpXNTBJSFJwYkhRZ2MzUmhkR1VnYjJZZ2RHaGxJR1JsZG1salpTNWNiaXBjYmlvZ1FHOTFkSEIxZEdWNFlXMXdiR1ZjYmlvZ2RHbHNkQzV2YmlnblkyaGhibWRsSnl4bWRXNWpkR2x2YmloMktTQjdYRzRxSUNBZ1kyOXVjMjlzWlM1c2IyY29kaWs3WEc0cUlIMHBYRzRxWEc0cVhHNHFMMXh1WEc1bGVIQnZjblFnWkdWbVlYVnNkQ0JqYkdGemN5QlVhV3gwSUdWNGRHVnVaSE1nU1c1MFpYSm1ZV05sSUh0Y2JseHVJQ0JqYjI1emRISjFZM1J2Y2lncElIdGNibHh1SUNBZ0lHeGxkQ0J2Y0hScGIyNXpJRDBnV3lkMllXeDFaU2RkTzF4dVhHNGdJQ0FnYkdWMElHUmxabUYxYkhSeklEMGdlMXh1SUNBZ0lDQWdKM05wZW1Vbk9pQmJPREFzT0RCZFhHNGdJQ0FnZlR0Y2JseHVJQ0FnSUhOMWNHVnlLR0Z5WjNWdFpXNTBjeXh2Y0hScGIyNXpMR1JsWm1GMWJIUnpLVHRjYmx4dUlDQWdJSFJvYVhNdVgyRmpkR2wyWlNBOUlIUnlkV1U3WEc1Y2JpQWdJQ0IwYUdsekxtbHVhWFFvS1R0Y2JseHVJQ0FnSUM4dklHRmtaQ0JsZG1WdWRDQnNhWE4wWlc1bGNpQm1iM0lnWkdWMmFXTmxJRzl5YVdWdWRHRjBhVzl1WEc1Y2JpQWdYSFIwYUdsekxtSnZkVzVrVlhCa1lYUmxJRDBnZEdocGN5NTFjR1JoZEdVdVltbHVaQ2gwYUdsektUdGNiaUFnTHk5Y2RIUm9hWE11WW05MWJtUk5iM3BVYVd4MElEMGdkR2hwY3k1dGIzcFVhV3gwTG1KcGJtUW9kR2hwY3lsY2JseHVJQ0JjZEdsbUlDaDNhVzVrYjNjdVJHVjJhV05sVDNKcFpXNTBZWFJwYjI1RmRtVnVkQ2tnZTF4dUlDQmNkRngwZEdocGN5NXZjbWxsYm5SaGRHbHZia3hwYzNSbGJtVnlJRDBnZDJsdVpHOTNMbUZrWkVWMlpXNTBUR2x6ZEdWdVpYSW9KMlJsZG1salpXOXlhV1Z1ZEdGMGFXOXVKeXdnZEdocGN5NWliM1Z1WkZWd1pHRjBaU3dnWm1Gc2MyVXBPMXh1SUNCY2RIMGdaV3h6WlNCN1hHNGdJQ0FnSUNCMGFHbHpMbDloWTNScGRtVWdQU0JtWVd4elpUdGNiaUFnSUNBZ0lIUm9hWE11WTI5c2IzSkpiblJsY21aaFkyVW9LVHRjYmlBZ0lDQjlYRzVjYmx4dVhHNGdJQ0FnSUNBdkttVnNjMlVnYVdZZ0tIZHBibVJ2ZHk1UGNtbGxiblJoZEdsdmJrVjJaVzUwS1NCN1hHNGdJQzh2WEhRZ0lGeDBkMmx1Wkc5M0xtRmtaRVYyWlc1MFRHbHpkR1Z1WlhJb0owMXZlazl5YVdWdWRHRjBhVzl1Snl3Z2RHaHBjeTVpYjNWdVpFMXZlbFJwYkhRc0lHWmhiSE5sS1R0Y2JpQWdYSFI5SUdWc2MyVWdlMXh1SUNCY2RDQWdYSFJqYjI1emIyeGxMbXh2WnlnblRtOTBJSE4xY0hCdmNuUmxaQ0J2YmlCNWIzVnlJR1JsZG1salpTQnZjaUJpY205M2MyVnlMaWNwTzF4dUlDQmNkSDBnS2k5Y2JseHVYRzRnSUgxY2JseHVYRzRnSUdKMWFXeGtTVzUwWlhKbVlXTmxLQ2tnZTF4dVhHNGdJQ0FnZEdocGN5NTBhWFJzWlNBOUlITjJaeTVqY21WaGRHVW9KM1JsZUhRbktUdGNiaUFnSUNCMGFHbHpMbU5wY21Oc1pWZ2dQU0J6ZG1jdVkzSmxZWFJsS0NkamFYSmpiR1VuS1R0Y2JpQWdJQ0IwYUdsekxtTnBjbU5zWlZrZ1BTQnpkbWN1WTNKbFlYUmxLQ2RqYVhKamJHVW5LVHRjYmlBZ0lDQjBhR2x6TG1OcGNtTnNaVm9nUFNCemRtY3VZM0psWVhSbEtDZGphWEpqYkdVbktUdGNibHh1SUNBZ0lIUm9hWE11WW1GeVdDQTlJSE4yWnk1amNtVmhkR1VvSjNCaGRHZ25LVHRjYmlBZ0lDQjBhR2x6TG1KaGNsa2dQU0J6ZG1jdVkzSmxZWFJsS0Nkd1lYUm9KeWs3WEc0Z0lDQWdkR2hwY3k1aVlYSmFJRDBnYzNabkxtTnlaV0YwWlNnbmNHRjBhQ2NwTzF4dVhHNGdJQ0FnZEdocGN5NWlZWEpZTWlBOUlITjJaeTVqY21WaGRHVW9KM0JoZEdnbktUdGNiaUFnSUNCMGFHbHpMbUpoY2xreUlEMGdjM1puTG1OeVpXRjBaU2duY0dGMGFDY3BPMXh1SUNBZ0lIUm9hWE11WW1GeVdqSWdQU0J6ZG1jdVkzSmxZWFJsS0Nkd1lYUm9KeWs3WEc1Y2JpQWdJQ0IwYUdsekxtSmhjbGd1YzJWMFFYUjBjbWxpZFhSbEtDZHZjR0ZqYVhSNUp5d25NQzQ0SnlrN1hHNGdJQ0FnZEdocGN5NWlZWEpaTG5ObGRFRjBkSEpwWW5WMFpTZ25iM0JoWTJsMGVTY3NKekF1T0NjcE8xeHVJQ0FnSUhSb2FYTXVZbUZ5V2k1elpYUkJkSFJ5YVdKMWRHVW9KMjl3WVdOcGRIa25MQ2N3TGpnbktUdGNiaUFnSUNCMGFHbHpMbUpoY2xneUxuTmxkRUYwZEhKcFluVjBaU2duYjNCaFkybDBlU2NzSnpBdU9DY3BPMXh1SUNBZ0lIUm9hWE11WW1GeVdUSXVjMlYwUVhSMGNtbGlkWFJsS0NkdmNHRmphWFI1Snl3bk1DNDRKeWs3WEc0Z0lDQWdkR2hwY3k1aVlYSmFNaTV6WlhSQmRIUnlhV0oxZEdVb0oyOXdZV05wZEhrbkxDY3dMamduS1R0Y2JseHVJQ0FnSUhSb2FYTXVZMmx5WTJ4bFdDNXpaWFJCZEhSeWFXSjFkR1VvSjJONEp5eDBhR2x6TG5kcFpIUm9Lak12TVRJcE8xeHVJQ0FnSUhSb2FYTXVZMmx5WTJ4bFdDNXpaWFJCZEhSeWFXSjFkR1VvSjJONUp5eDBhR2x6TG1obGFXZG9kQ296THpRcE8xeHVJQ0FnSUhSb2FYTXVZMmx5WTJ4bFdDNXpaWFJCZEhSeWFXSjFkR1VvSjNJbkxIUm9hWE11YUdWcFoyaDBMekV3S1R0Y2JpQWdJQ0IwYUdsekxtTnBjbU5zWlZndWMyVjBRWFIwY21saWRYUmxLQ2R2Y0dGamFYUjVKeXduTUM0MEp5azdYRzVjYmlBZ0lDQjBhR2x6TG1OcGNtTnNaVmt1YzJWMFFYUjBjbWxpZFhSbEtDZGplQ2NzZEdocGN5NTNhV1IwYUNvMkx6RXlLVHRjYmlBZ0lDQjBhR2x6TG1OcGNtTnNaVmt1YzJWMFFYUjBjbWxpZFhSbEtDZGplU2NzZEdocGN5NW9aV2xuYUhRcU15ODBLVHRjYmlBZ0lDQjBhR2x6TG1OcGNtTnNaVmt1YzJWMFFYUjBjbWxpZFhSbEtDZHlKeXgwYUdsekxtaGxhV2RvZEM4eE1DazdYRzRnSUNBZ2RHaHBjeTVqYVhKamJHVlpMbk5sZEVGMGRISnBZblYwWlNnbmIzQmhZMmwwZVNjc0p6QXVOQ2NwTzF4dVhHNGdJQ0FnZEdocGN5NWphWEpqYkdWYUxuTmxkRUYwZEhKcFluVjBaU2duWTNnbkxIUm9hWE11ZDJsa2RHZ3FPUzh4TWlrN1hHNGdJQ0FnZEdocGN5NWphWEpqYkdWYUxuTmxkRUYwZEhKcFluVjBaU2duWTNrbkxIUm9hWE11YUdWcFoyaDBLak12TkNrN1hHNGdJQ0FnZEdocGN5NWphWEpqYkdWYUxuTmxkRUYwZEhKcFluVjBaU2duY2ljc2RHaHBjeTVvWldsbmFIUXZNVEFwTzF4dUlDQWdJSFJvYVhNdVkybHlZMnhsV2k1elpYUkJkSFJ5YVdKMWRHVW9KMjl3WVdOcGRIa25MQ2N3TGpRbktUdGNibHh1WEc0Z0lDQWdkR2hwY3k1aVlYSllMbk5sZEVGMGRISnBZblYwWlNnbmMzUnliMnRsTFhkcFpIUm9KeXhOWVhSb0xuSnZkVzVrS0hSb2FYTXVhR1ZwWjJoMEx6TXdLU2s3WEc0Z0lDQWdkR2hwY3k1aVlYSlpMbk5sZEVGMGRISnBZblYwWlNnbmMzUnliMnRsTFhkcFpIUm9KeXhOWVhSb0xuSnZkVzVrS0hSb2FYTXVhR1ZwWjJoMEx6TXdLU2s3WEc0Z0lDQWdkR2hwY3k1aVlYSmFMbk5sZEVGMGRISnBZblYwWlNnbmMzUnliMnRsTFhkcFpIUm9KeXhOWVhSb0xuSnZkVzVrS0hSb2FYTXVhR1ZwWjJoMEx6TXdLU2s3WEc1Y2JpQWdJQ0IwYUdsekxtSmhjbGd1YzJWMFFYUjBjbWxpZFhSbEtDZG1hV3hzSnl3Z0oyNXZibVVuS1R0Y2JpQWdJQ0IwYUdsekxtSmhjbGt1YzJWMFFYUjBjbWxpZFhSbEtDZG1hV3hzSnl3Z0oyNXZibVVuS1R0Y2JpQWdJQ0IwYUdsekxtSmhjbG91YzJWMFFYUjBjbWxpZFhSbEtDZG1hV3hzSnl3Z0oyNXZibVVuS1R0Y2JseHVJQ0FnSUhSb2FYTXVZbUZ5V0RJdWMyVjBRWFIwY21saWRYUmxLQ2R6ZEhKdmEyVXRkMmxrZEdnbkxFMWhkR2d1Y205MWJtUW9kR2hwY3k1b1pXbG5hSFF2TXpBcEtUdGNiaUFnSUNCMGFHbHpMbUpoY2xreUxuTmxkRUYwZEhKcFluVjBaU2duYzNSeWIydGxMWGRwWkhSb0p5eE5ZWFJvTG5KdmRXNWtLSFJvYVhNdWFHVnBaMmgwTHpNd0tTazdYRzRnSUNBZ2RHaHBjeTVpWVhKYU1pNXpaWFJCZEhSeWFXSjFkR1VvSjNOMGNtOXJaUzEzYVdSMGFDY3NUV0YwYUM1eWIzVnVaQ2gwYUdsekxtaGxhV2RvZEM4ek1Da3BPMXh1WEc0Z0lDQWdkR2hwY3k1aVlYSllNaTV6WlhSQmRIUnlhV0oxZEdVb0oyWnBiR3duTENBbmJtOXVaU2NwTzF4dUlDQWdJSFJvYVhNdVltRnlXVEl1YzJWMFFYUjBjbWxpZFhSbEtDZG1hV3hzSnl3Z0oyNXZibVVuS1R0Y2JpQWdJQ0IwYUdsekxtSmhjbG95TG5ObGRFRjBkSEpwWW5WMFpTZ25abWxzYkNjc0lDZHViMjVsSnlrN1hHNWNibHh1SUNBZ0lIUm9hWE11ZEdsMGJHVXVjMlYwUVhSMGNtbGlkWFJsS0NkNEp5eDBhR2x6TG5kcFpIUm9MeklwTzF4dUlDQWdJSFJvYVhNdWRHbDBiR1V1YzJWMFFYUjBjbWxpZFhSbEtDZDVKeXgwYUdsekxtaGxhV2RvZEM4ekt6Y3BPMXh1SUNBZ0lIUm9hWE11ZEdsMGJHVXVjMlYwUVhSMGNtbGlkWFJsS0NkbWIyNTBMWE5wZW1VbkxDY3hOWEI0SnlrN1hHNGdJQ0FnZEdocGN5NTBhWFJzWlM1elpYUkJkSFJ5YVdKMWRHVW9KMlp2Ym5RdGQyVnBaMmgwSnl3blltOXNaQ2NwTzF4dUlDQWdJSFJvYVhNdWRHbDBiR1V1YzJWMFFYUjBjbWxpZFhSbEtDZHNaWFIwWlhJdGMzQmhZMmx1Wnljc0p6SndlQ2NwTzF4dUlDQWdJSFJvYVhNdWRHbDBiR1V1YzJWMFFYUjBjbWxpZFhSbEtDZHZjR0ZqYVhSNUp5d25NQzQzSnlrN1hHNGdJQ0FnZEdocGN5NTBhWFJzWlM1elpYUkJkSFJ5YVdKMWRHVW9KM1JsZUhRdFlXNWphRzl5Snl3bmJXbGtaR3hsSnlrN1hHNGdJQ0FnZEdocGN5NTBhWFJzWlM1MFpYaDBRMjl1ZEdWdWRDQTlJQ2RVU1V4VUp6dGNibHh1WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG1Gd2NHVnVaRU5vYVd4a0tIUm9hWE11WTJseVkyeGxXQ2s3WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG1Gd2NHVnVaRU5vYVd4a0tIUm9hWE11WTJseVkyeGxXU2s3WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG1Gd2NHVnVaRU5vYVd4a0tIUm9hWE11WTJseVkyeGxXaWs3WEc1Y2JpQWdJQ0IwYUdsekxtVnNaVzFsYm5RdVlYQndaVzVrUTJocGJHUW9kR2hwY3k1aVlYSllLVHRjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1WVhCd1pXNWtRMmhwYkdRb2RHaHBjeTVpWVhKWktUdGNiaUFnSUNCMGFHbHpMbVZzWlcxbGJuUXVZWEJ3Wlc1a1EyaHBiR1FvZEdocGN5NWlZWEphS1R0Y2JseHVJQ0FnSUhSb2FYTXVaV3hsYldWdWRDNWhjSEJsYm1SRGFHbHNaQ2gwYUdsekxtSmhjbGd5S1R0Y2JpQWdJQ0IwYUdsekxtVnNaVzFsYm5RdVlYQndaVzVrUTJocGJHUW9kR2hwY3k1aVlYSlpNaWs3WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG1Gd2NHVnVaRU5vYVd4a0tIUm9hWE11WW1GeVdqSXBPMXh1WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG1Gd2NHVnVaRU5vYVd4a0tIUm9hWE11ZEdsMGJHVXBPMXh1WEc0Z0lIMWNibHh1SUNCamIyeHZja2x1ZEdWeVptRmpaU2dwSUh0Y2JseHVJQ0FnSUdsbUlDaDBhR2x6TGw5aFkzUnBkbVVwSUh0Y2JpQWdJQ0FnSUhSb2FYTXVaV3hsYldWdWRDNXpkSGxzWlM1aVlXTnJaM0p2ZFc1a1EyOXNiM0lnUFNCMGFHbHpMbU52Ykc5eWN5NWhZMk5sYm5RN1hHNGdJQ0FnSUNCMGFHbHpMbU5wY21Oc1pWZ3VjMlYwUVhSMGNtbGlkWFJsS0NkbWFXeHNKeXgwYUdsekxtTnZiRzl5Y3k1c2FXZG9kQ2s3WEc0Z0lDQWdJQ0IwYUdsekxtTnBjbU5zWlZrdWMyVjBRWFIwY21saWRYUmxLQ2RtYVd4c0p5eDBhR2x6TG1OdmJHOXljeTVzYVdkb2RDazdYRzRnSUNBZ0lDQjBhR2x6TG1OcGNtTnNaVm91YzJWMFFYUjBjbWxpZFhSbEtDZG1hV3hzSnl4MGFHbHpMbU52Ykc5eWN5NXNhV2RvZENrN1hHNGdJQ0FnSUNCMGFHbHpMbU5wY21Oc1pWZ3VjMlYwUVhSMGNtbGlkWFJsS0NkemRISnZhMlVuTEhSb2FYTXVZMjlzYjNKekxteHBaMmgwS1R0Y2JpQWdJQ0FnSUhSb2FYTXVZMmx5WTJ4bFdTNXpaWFJCZEhSeWFXSjFkR1VvSjNOMGNtOXJaU2NzZEdocGN5NWpiMnh2Y25NdWJHbG5hSFFwTzF4dUlDQWdJQ0FnZEdocGN5NWphWEpqYkdWYUxuTmxkRUYwZEhKcFluVjBaU2duYzNSeWIydGxKeXgwYUdsekxtTnZiRzl5Y3k1c2FXZG9kQ2s3WEc0Z0lDQWdJQ0IwYUdsekxtSmhjbGd1YzJWMFFYUjBjbWxpZFhSbEtDZHpkSEp2YTJVbkxIUm9hWE11WTI5c2IzSnpMbXhwWjJoMEtUdGNiaUFnSUNBZ0lIUm9hWE11WW1GeVdTNXpaWFJCZEhSeWFXSjFkR1VvSjNOMGNtOXJaU2NzZEdocGN5NWpiMnh2Y25NdWJHbG5hSFFwTzF4dUlDQWdJQ0FnZEdocGN5NWlZWEphTG5ObGRFRjBkSEpwWW5WMFpTZ25jM1J5YjJ0bEp5eDBhR2x6TG1OdmJHOXljeTVzYVdkb2RDazdYRzRnSUNBZ0lDQjBhR2x6TG1KaGNsZ3lMbk5sZEVGMGRISnBZblYwWlNnbmMzUnliMnRsSnl4MGFHbHpMbU52Ykc5eWN5NXNhV2RvZENrN1hHNGdJQ0FnSUNCMGFHbHpMbUpoY2xreUxuTmxkRUYwZEhKcFluVjBaU2duYzNSeWIydGxKeXgwYUdsekxtTnZiRzl5Y3k1c2FXZG9kQ2s3WEc0Z0lDQWdJQ0IwYUdsekxtSmhjbG95TG5ObGRFRjBkSEpwWW5WMFpTZ25jM1J5YjJ0bEp5eDBhR2x6TG1OdmJHOXljeTVzYVdkb2RDazdYRzRnSUNBZ0lDQjBhR2x6TG5ScGRHeGxMbk5sZEVGMGRISnBZblYwWlNnblptbHNiQ2NzZEdocGN5NWpiMnh2Y25NdWJHbG5hSFFwTzF4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1YzNSNWJHVXVZbUZqYTJkeWIzVnVaRU52Ykc5eUlEMGdkR2hwY3k1amIyeHZjbk11Wm1sc2JEdGNiaUFnSUNBZ0lIUm9hWE11WTJseVkyeGxXQzV6WlhSQmRIUnlhV0oxZEdVb0oyWnBiR3duTEhSb2FYTXVZMjlzYjNKekxtMWxaR2wxYlV4cFoyaDBLVHRjYmlBZ0lDQWdJSFJvYVhNdVkybHlZMnhsV1M1elpYUkJkSFJ5YVdKMWRHVW9KMlpwYkd3bkxIUm9hWE11WTI5c2IzSnpMbTFsWkdsMWJVeHBaMmgwS1R0Y2JpQWdJQ0FnSUhSb2FYTXVZMmx5WTJ4bFdpNXpaWFJCZEhSeWFXSjFkR1VvSjJacGJHd25MSFJvYVhNdVkyOXNiM0p6TG0xbFpHbDFiVXhwWjJoMEtUdGNiaUFnSUNBZ0lIUm9hWE11WTJseVkyeGxXQzV6WlhSQmRIUnlhV0oxZEdVb0ozTjBjbTlyWlNjc2RHaHBjeTVqYjJ4dmNuTXViV1ZrYVhWdFRHbG5hSFFwTzF4dUlDQWdJQ0FnZEdocGN5NWphWEpqYkdWWkxuTmxkRUYwZEhKcFluVjBaU2duYzNSeWIydGxKeXgwYUdsekxtTnZiRzl5Y3k1dFpXUnBkVzFNYVdkb2RDazdYRzRnSUNBZ0lDQjBhR2x6TG1OcGNtTnNaVm91YzJWMFFYUjBjbWxpZFhSbEtDZHpkSEp2YTJVbkxIUm9hWE11WTI5c2IzSnpMbTFsWkdsMWJVeHBaMmgwS1R0Y2JpQWdJQ0FnSUhSb2FYTXVZbUZ5V0M1elpYUkJkSFJ5YVdKMWRHVW9KM04wY205clpTY3NkR2hwY3k1amIyeHZjbk11YldWa2FYVnRUR2xuYUhRcE8xeHVJQ0FnSUNBZ2RHaHBjeTVpWVhKWkxuTmxkRUYwZEhKcFluVjBaU2duYzNSeWIydGxKeXgwYUdsekxtTnZiRzl5Y3k1dFpXUnBkVzFNYVdkb2RDazdYRzRnSUNBZ0lDQjBhR2x6TG1KaGNsb3VjMlYwUVhSMGNtbGlkWFJsS0NkemRISnZhMlVuTEhSb2FYTXVZMjlzYjNKekxtMWxaR2wxYlV4cFoyaDBLVHRjYmlBZ0lDQWdJSFJvYVhNdVltRnlXREl1YzJWMFFYUjBjbWxpZFhSbEtDZHpkSEp2YTJVbkxIUm9hWE11WTI5c2IzSnpMbTFsWkdsMWJVeHBaMmgwS1R0Y2JpQWdJQ0FnSUhSb2FYTXVZbUZ5V1RJdWMyVjBRWFIwY21saWRYUmxLQ2R6ZEhKdmEyVW5MSFJvYVhNdVkyOXNiM0p6TG0xbFpHbDFiVXhwWjJoMEtUdGNiaUFnSUNBZ0lIUm9hWE11WW1GeVdqSXVjMlYwUVhSMGNtbGlkWFJsS0NkemRISnZhMlVuTEhSb2FYTXVZMjlzYjNKekxtMWxaR2wxYlV4cFoyaDBLVHRjYmlBZ0lDQWdJSFJvYVhNdWRHbDBiR1V1YzJWMFFYUjBjbWxpZFhSbEtDZG1hV3hzSnl4MGFHbHpMbU52Ykc5eWN5NXRaV1JwZFcxTWFXZG9kQ2s3WEc0Z0lDQWdmVnh1WEc0Z0lIMWNibHh1SUNCMWNHUmhkR1VvZGlrZ2UxeHVJQ0FnSUdsbUlDaDBhR2x6TGw5aFkzUnBkbVVwZTF4dVhHNGdJQ0FnSUNCc1pYUWdlU0E5SUhZdVltVjBZVHRjYmlBZ0lDQWdJR3hsZENCNElEMGdkaTVuWVcxdFlUdGNiaUFnSUNBZ0lHeGxkQ0I2SUQwZ2RpNWhiSEJvWVR0Y2JseHVJQ0FnSUNBZ0x5OGdkR0ZyWlNCMGFHVWdiM0pwWjJsdVlXd2dMVGt3SUhSdklEa3dJSE5qWVd4bElHRnVaQ0J1YjNKdFlXeHBlbVVnYVhRZ01DMHhYRzRnSUNBZ0lDQjRJRDBnYldGMGFDNXpZMkZzWlNoNExDMDVNQ3c1TUN3d0xERXBPMXh1SUNBZ0lDQWdlU0E5SUcxaGRHZ3VjMk5oYkdVb2VTd3RPVEFzT1RBc01Dd3hLVHRjYmlBZ0lDQWdJSG9nUFNCdFlYUm9Mbk5qWVd4bEtIb3NNQ3d6TmpBc01Dd3hLVHRjYmx4dVhHNGdJQ0FnSUNCc1pYUWdhR0Z1Wkd4bFVHOXBiblJ6SUQwZ2UxeHVJQ0FnSUNBZ0lDQnpkR0Z5ZERvZ1RXRjBhQzVRU1NveExqVXNYRzRnSUNBZ0lDQWdJR1Z1WkRvZ2JXRjBhQzVqYkdsd0tDQnRZWFJvTG5OallXeGxLSGdzTUN3d0xqVXNUV0YwYUM1UVNTb3hMalVzVFdGMGFDNVFTU293TGpVcElDd2dUV0YwYUM1UVNTb3dMalVzSUUxaGRHZ3VVRWtxTVM0MUlDbGNiaUFnSUNBZ0lIMDdYRzRnSUNBZ0lDQnNaWFFnYUdGdVpHeGxNbEJ2YVc1MGN5QTlJSHRjYmlBZ0lDQWdJQ0FnYzNSaGNuUTZJRTFoZEdndVVFa3FNaTQxTEZ4dUlDQWdJQ0FnSUNCbGJtUTZJRzFoZEdndVkyeHBjQ2dnYldGMGFDNXpZMkZzWlNoNExEQXVOU3d4TEUxaGRHZ3VVRWtxTWk0MUxFMWhkR2d1VUVrcU1TNDFLU0FzSUUxaGRHZ3VVRWtxTVM0MUxDQk5ZWFJvTGxCSktqSXVOU0FwWEc0Z0lDQWdJQ0I5TzF4dVhHNGdJQ0FnSUNCc1pYUWdhR0Z1Wkd4bFVHRjBhQ0E5SUhOMlp5NWhjbU1vZEdocGN5NWphWEpqYkdWWUxtTjRMbUpoYzJWV1lXd3VkbUZzZFdVc0lIUm9hWE11WTJseVkyeGxXQzVqZVM1aVlYTmxWbUZzTG5aaGJIVmxMQ0IwYUdsekxtTnBjbU5zWlZndWNpNWlZWE5sVm1Gc0xuWmhiSFZsTENCb1lXNWtiR1ZRYjJsdWRITXVjM1JoY25Rc0lHaGhibVJzWlZCdmFXNTBjeTVsYm1RcE8xeHVJQ0FnSUNBZ2JHVjBJR2hoYm1Sc1pUSlFZWFJvSUQwZ2MzWm5MbUZ5WXloMGFHbHpMbU5wY21Oc1pWZ3VZM2d1WW1GelpWWmhiQzUyWVd4MVpTd2dkR2hwY3k1amFYSmpiR1ZZTG1ONUxtSmhjMlZXWVd3dWRtRnNkV1VzSUhSb2FYTXVZMmx5WTJ4bFdDNXlMbUpoYzJWV1lXd3VkbUZzZFdVc0lHaGhibVJzWlRKUWIybHVkSE11YzNSaGNuUXNJR2hoYm1Sc1pUSlFiMmx1ZEhNdVpXNWtLVHRjYmx4dUlDQWdJQ0FnZEdocGN5NWlZWEpZTG5ObGRFRjBkSEpwWW5WMFpTZ25aQ2NzSUdoaGJtUnNaVkJoZEdncE8xeHVJQ0FnSUNBZ2RHaHBjeTVpWVhKWU1pNXpaWFJCZEhSeWFXSjFkR1VvSjJRbkxDQm9ZVzVrYkdVeVVHRjBhQ2s3WEc1Y2JseHVYRzVjYmx4dUlDQWdJQ0FnYUdGdVpHeGxVRzlwYm5SeklEMGdlMXh1SUNBZ0lDQWdJQ0J6ZEdGeWREb2dUV0YwYUM1UVNTb3hMalVzWEc0Z0lDQWdJQ0FnSUdWdVpEb2diV0YwYUM1amJHbHdLQ0J0WVhSb0xuTmpZV3hsS0hrc01Dd3dMalVzVFdGMGFDNVFTU294TGpVc1RXRjBhQzVRU1Nvd0xqVXBJQ3dnVFdGMGFDNVFTU293TGpVc0lFMWhkR2d1VUVrcU1TNDFJQ2xjYmlBZ0lDQWdJSDA3WEc0Z0lDQWdJQ0JvWVc1a2JHVXlVRzlwYm5SeklEMGdlMXh1SUNBZ0lDQWdJQ0J6ZEdGeWREb2dUV0YwYUM1UVNTb3lMalVzWEc0Z0lDQWdJQ0FnSUdWdVpEb2diV0YwYUM1amJHbHdLQ0J0WVhSb0xuTmpZV3hsS0hrc01DNDFMREVzVFdGMGFDNVFTU295TGpVc1RXRjBhQzVRU1NveExqVXBJQ3dnVFdGMGFDNVFTU294TGpVc0lFMWhkR2d1VUVrcU1pNDFJQ2xjYmlBZ0lDQWdJSDA3WEc1Y2JpQWdJQ0FnSUdoaGJtUnNaVkJoZEdnZ1BTQnpkbWN1WVhKaktIUm9hWE11WTJseVkyeGxXUzVqZUM1aVlYTmxWbUZzTG5aaGJIVmxMQ0IwYUdsekxtTnBjbU5zWlZrdVkza3VZbUZ6WlZaaGJDNTJZV3gxWlN3Z2RHaHBjeTVqYVhKamJHVlpMbkl1WW1GelpWWmhiQzUyWVd4MVpTd2dhR0Z1Wkd4bFVHOXBiblJ6TG5OMFlYSjBMQ0JvWVc1a2JHVlFiMmx1ZEhNdVpXNWtLVHRjYmlBZ0lDQWdJR2hoYm1Sc1pUSlFZWFJvSUQwZ2MzWm5MbUZ5WXloMGFHbHpMbU5wY21Oc1pWa3VZM2d1WW1GelpWWmhiQzUyWVd4MVpTd2dkR2hwY3k1amFYSmpiR1ZaTG1ONUxtSmhjMlZXWVd3dWRtRnNkV1VzSUhSb2FYTXVZMmx5WTJ4bFdTNXlMbUpoYzJWV1lXd3VkbUZzZFdVc0lHaGhibVJzWlRKUWIybHVkSE11YzNSaGNuUXNJR2hoYm1Sc1pUSlFiMmx1ZEhNdVpXNWtLVHRjYmx4dUlDQWdJQ0FnZEdocGN5NWlZWEpaTG5ObGRFRjBkSEpwWW5WMFpTZ25aQ2NzSUdoaGJtUnNaVkJoZEdncE8xeHVJQ0FnSUNBZ2RHaHBjeTVpWVhKWk1pNXpaWFJCZEhSeWFXSjFkR1VvSjJRbkxDQm9ZVzVrYkdVeVVHRjBhQ2s3WEc1Y2JseHVYRzVjYmx4dVhHNGdJQ0FnSUNCb1lXNWtiR1ZRYjJsdWRITWdQU0I3WEc0Z0lDQWdJQ0FnSUhOMFlYSjBPaUJOWVhSb0xsQkpLakV1TlN4Y2JpQWdJQ0FnSUNBZ1pXNWtPaUJ0WVhSb0xtTnNhWEFvSUcxaGRHZ3VjMk5oYkdVb2Vpd3dMREF1TlN4TllYUm9MbEJKS2pFdU5TeE5ZWFJvTGxCSktqQXVOU2tnTENCTllYUm9MbEJKS2pBdU5Td2dUV0YwYUM1UVNTb3hMalVnS1Z4dUlDQWdJQ0FnZlR0Y2JpQWdJQ0FnSUdoaGJtUnNaVEpRYjJsdWRITWdQU0I3WEc0Z0lDQWdJQ0FnSUhOMFlYSjBPaUJOWVhSb0xsQkpLakl1TlN4Y2JpQWdJQ0FnSUNBZ1pXNWtPaUJ0WVhSb0xtTnNhWEFvSUcxaGRHZ3VjMk5oYkdVb2Vpd3dMalVzTVN4TllYUm9MbEJKS2pJdU5TeE5ZWFJvTGxCSktqRXVOU2tnTENCTllYUm9MbEJKS2pFdU5Td2dUV0YwYUM1UVNTb3lMalVnS1Z4dUlDQWdJQ0FnZlR0Y2JseHVJQ0FnSUNBZ2FHRnVaR3hsVUdGMGFDQTlJSE4yWnk1aGNtTW9kR2hwY3k1amFYSmpiR1ZhTG1ONExtSmhjMlZXWVd3dWRtRnNkV1VzSUhSb2FYTXVZMmx5WTJ4bFdpNWplUzVpWVhObFZtRnNMblpoYkhWbExDQjBhR2x6TG1OcGNtTnNaVm91Y2k1aVlYTmxWbUZzTG5aaGJIVmxMQ0JvWVc1a2JHVlFiMmx1ZEhNdWMzUmhjblFzSUdoaGJtUnNaVkJ2YVc1MGN5NWxibVFwTzF4dUlDQWdJQ0FnYUdGdVpHeGxNbEJoZEdnZ1BTQnpkbWN1WVhKaktIUm9hWE11WTJseVkyeGxXaTVqZUM1aVlYTmxWbUZzTG5aaGJIVmxMQ0IwYUdsekxtTnBjbU5zWlZvdVkza3VZbUZ6WlZaaGJDNTJZV3gxWlN3Z2RHaHBjeTVqYVhKamJHVmFMbkl1WW1GelpWWmhiQzUyWVd4MVpTd2dhR0Z1Wkd4bE1sQnZhVzUwY3k1emRHRnlkQ3dnYUdGdVpHeGxNbEJ2YVc1MGN5NWxibVFwTzF4dVhHNGdJQ0FnSUNCMGFHbHpMbUpoY2xvdWMyVjBRWFIwY21saWRYUmxLQ2RrSnl3Z2FHRnVaR3hsVUdGMGFDazdYRzRnSUNBZ0lDQjBhR2x6TG1KaGNsb3lMbk5sZEVGMGRISnBZblYwWlNnblpDY3NJR2hoYm1Sc1pUSlFZWFJvS1R0Y2JseHVYRzRnSUNBZ0lDQXZLbHh1WEc0Z0lDQWdJQ0JzWlhRZ2NHOXBiblJ6V0NBOUlIdGNiaUFnSUNBZ0lDQWdjM1JoY25RNklEQXNYRzRnSUNBZ0lDQWdJR1Z1WkRvZ2JXRjBhQzV6WTJGc1pTZ2dlQ3dnTUN3Z01Td2dNQ3dnVFdGMGFDNVFTU295SUNsY2JpQWdJQ0FnSUgwN1hHNWNiaUFnSUNBdkx5QWdZMjl1YzI5c1pTNXNiMmNvZEdocGN5NWphWEpqYkdWWUxtTjRMbUpoYzJWV1lXd3VkbUZzZFdVcE8xeHVYRzRnSUNBZ0lDQnNaWFFnY0dGMGFGZ2dQU0J6ZG1jdVlYSmpLSFJvYVhNdVkybHlZMnhsV0M1amVDNWlZWE5sVm1Gc0xuWmhiSFZsTENCMGFHbHpMbU5wY21Oc1pWZ3VZM2t1WW1GelpWWmhiQzUyWVd4MVpTd2dkR2hwY3k1amFYSmpiR1ZZTG5JdVltRnpaVlpoYkM1MllXeDFaU295TENCd2IybHVkSE5ZTG5OMFlYSjBMQ0J3YjJsdWRITllMbVZ1WkNrN1hHNWNiaUFnSUNBZ0lIUm9hWE11WW1GeVdDNXpaWFJCZEhSeWFXSjFkR1VvSjJRbkxIQmhkR2hZS1RzZ0tpOWNibHh1SUNBZ0lDQWdMeTkwYUdsekxuUmxlSFJJTG5SbGVIUkRiMjUwWlc1MElEMGdiV0YwYUM1d2NuVnVaU2g0TERJcE8xeHVJQ0FnSUNBZ0x5OTBhR2x6TG5SbGVIUldMblJsZUhSRGIyNTBaVzUwSUQwZ2JXRjBhQzV3Y25WdVpTaDVMRElwTzF4dUlDQWdJQ0FnTHk5Y2JpQWdJQ0F2THlBZ2RHaHBjeTVqYVhKamJHVllMbk5sZEVGMGRISnBZblYwWlNnbmIzQmhZMmwwZVNjc2VDazdYRzRnSUNBZ0x5OGdJSFJvYVhNdVkybHlZMnhsV1M1elpYUkJkSFJ5YVdKMWRHVW9KMjl3WVdOcGRIa25MSGtwTzF4dUlDQWdJQzh2SUNCMGFHbHpMbU5wY21Oc1pWb3VjMlYwUVhSMGNtbGlkWFJsS0NkdmNHRmphWFI1Snl4NktUdGNibHh1SUNBZ0lDQWdkR2hwY3k1bGJXbDBLQ2RqYUdGdVoyVW5MQ0I3WEc0Z0lDQWdJQ0FnSUhnNklIZ3NYRzRnSUNBZ0lDQWdJSGs2SUhrc1hHNGdJQ0FnSUNBZ0lIbzZJSHBjYmlBZ0lDQWdJSDBwTzF4dVhHNGdJQ0FnZlZ4dVhHNGdJSDFjYmx4dUlDQmpiR2xqYXlncElIdGNiaUFnSUNCcFppQW9kMmx1Wkc5M0xrUmxkbWxqWlU5eWFXVnVkR0YwYVc5dVJYWmxiblFwSUh0Y2JpQWdJQ0FnSUhSb2FYTXVZV04wYVhabElEMGdJWFJvYVhNdVlXTjBhWFpsTzF4dUlDQWdJSDFjYmlBZ2ZWeHVYRzRnSUM4cUtseHVJQ0JYYUdWMGFHVnlJSFJvWlNCcGJuUmxjbVpoWTJVZ2FYTWdiMjRnS0dWdGFYUjBhVzVuSUhaaGJIVmxjeWtnYjNJZ2IyWm1JQ2h3WVhWelpXUWdKaUJ1YjNRZ1pXMXBkSFJwYm1jZ2RtRnNkV1Z6S1M0Z1UyVjBkR2x1WnlCMGFHbHpJSEJ5YjNCbGNuUjVJSGRwYkd3Z2RYQmtZWFJsSUdsMExseHVJQ0JBZEhsd1pTQjdZbTl2YkdWaGJuMWNiaUFnS2k5Y2JseHVJQ0JuWlhRZ1lXTjBhWFpsS0NrZ2UxeHVJQ0FnSUhKbGRIVnliaUIwYUdsekxsOWhZM1JwZG1VN1hHNGdJSDFjYmx4dUlDQnpaWFFnWVdOMGFYWmxLRzl1S1NCN1hHNGdJQ0FnZEdocGN5NWZZV04wYVhabElEMGdiMjQ3WEc0Z0lDQWdkR2hwY3k1amIyeHZja2x1ZEdWeVptRmpaU2dwTzF4dUlDQjlYRzVjYmlBZ1kzVnpkRzl0UkdWemRISnZlU2dwSUh0Y2JpQWdJQ0IzYVc1a2IzY3VjbVZ0YjNabFJYWmxiblJNYVhOMFpXNWxjaWduWkdWMmFXTmxiM0pwWlc1MFlYUnBiMjRuTENCMGFHbHpMbUp2ZFc1a1ZYQmtZWFJsTENCbVlXeHpaU2s3WEc0Z0lIMWNibHh1ZlZ4dVhHNWNibHh1THk4Z1YwVkNVRUZEU3lCR1QwOVVSVklnTHk5Y2JpOHZJQzR2Zmk5cWMyaHBiblF0Ykc5aFpHVnlJUzR2YkdsaUwybHVkR1Z5Wm1GalpYTXZkR2xzZEM1cWN5SXNJaWQxYzJVZ2MzUnlhV04wSnp0Y2JseHViR1YwSUdSdmJTQTlJSEpsY1hWcGNtVW9KeTR1TDNWMGFXd3ZaRzl0SnlrN1hHNXNaWFFnYldGMGFDQTlJSEpsY1hWcGNtVW9KeTR1TDNWMGFXd3ZiV0YwYUNjcE8xeHViR1YwSUVsdWRHVnlabUZqWlNBOUlISmxjWFZwY21Vb0p5NHVMMk52Y21VdmFXNTBaWEptWVdObEp5azdYRzVzWlhRZ1UyeHBaR1Z5VkdWdGNHeGhkR1VnUFNCeVpYRjFhWEpsS0NjdUxpOWpiMjF3YjI1bGJuUnpMM05zYVdSbGNuUmxiWEJzWVhSbEp5azdYRzVzWlhRZ2RHOTFZMmdnUFNCeVpYRjFhWEpsS0NjdUxpOTFkR2xzTDNSdmRXTm9KeWs3WEc1Y2JseHVYRzVqYkdGemN5QlRhVzVuYkdWVGJHbGtaWElnWlhoMFpXNWtjeUJUYkdsa1pYSlVaVzF3YkdGMFpTQjdYRzVjYmlBZ1kyOXVjM1J5ZFdOMGIzSW9LU0I3WEc1Y2JpQWdJQ0JzWlhRZ2IzQjBhVzl1Y3lBOUlGc25jMk5oYkdVbkxDZDJZV3gxWlNkZE8xeHVYRzRnSUNBZ2JHVjBJR1JsWm1GMWJIUnpJRDBnZTF4dUlDQWdJQ0FnSjNOcGVtVW5PaUJiTVRJd0xESXdYU3hjYmlBZ0lDQWdJQ2R2Y21sbGJuUmhkR2x2YmljNklDZDJaWEowYVdOaGJDY3NYRzRnSUNBZ0lDQW5iVzlrWlNjNklDZGhZbk52YkhWMFpTY3NYRzRnSUNBZ0lDQW5jMk5oYkdVbk9pQmJNQ3d4WFN4Y2JpQWdJQ0FnSUNkemRHVndKem9nTUN4Y2JpQWdJQ0FnSUNkMllXeDFaU2M2SURBc1hHNGdJQ0FnSUNBbmFHRnpTMjV2WWljNklIUnlkV1ZjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdjM1Z3WlhJb1lYSm5kVzFsYm5SekxHOXdkR2x2Ym5Nc1pHVm1ZWFZzZEhNcE8xeHVYRzVjYmlBZ0lDQXZLaUJsZG1WdWRITWdLaTljYmx4dUlDQWdJR2xtSUNnaGRHOTFZMmd1WlhocGMzUnpLU0I3WEc1Y2JpQWdJQ0FnSUhSb2FYTXVZMnhwWTJzZ1BTQW9LU0E5UGlCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11YlhWc2RHbHpiR2xrWlhJdWFXNTBaWEpoWTNScGJtY2dQU0IwY25WbE8xeHVJQ0FnSUNBZ0lDQjBhR2x6TG0xMWJIUnBjMnhwWkdWeUxtbHVkR1Z5Y0c5c1lYUnBiMjRnUFNCN1hHNGdJQ0FnSUNBZ0lDQWdhVzVrWlhnNklIUm9hWE11YVc1a1pYZ3NYRzRnSUNBZ0lDQWdJQ0FnZG1Gc2RXVTZJSFJvYVhNdWRtRnNkV1ZjYmlBZ0lDQWdJQ0FnZlR0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTVrYjNkdUtDazdYRzRnSUNBZ0lDQWdJSFJvYVhNdWJYVnNkR2x6Ykdsa1pYSXVkbUZzZFdWelczUm9hWE11YVc1a1pYaGRJRDBnZEdocGN5NTJZV3gxWlR0Y2JpQWdJQ0FnSUgwN1hHNGdJQ0FnSUNCMGFHbHpMbVZzWlcxbGJuUXVZV1JrUlhabGJuUk1hWE4wWlc1bGNpZ25iVzkxYzJWdmRtVnlKeXdnS0dVcElEMCtJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tIUm9hWE11YlhWc2RHbHpiR2xrWlhJdWFXNTBaWEpoWTNScGJtY3BJSHRjYmlBZ0lDQWdJQ0FnSUNCcFppQW9JWFJvYVhNdWIyWm1jMlYwS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0IwYUdsekxtOW1abk5sZENBOUlHUnZiUzVtYVc1a1VHOXphWFJwYjI0b2RHaHBjeTVsYkdWdFpXNTBLVHRjYmlBZ0lDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lDQWdkR2hwY3k1dGIzVnpaU0E5SUdSdmJTNXNiMk5oZEdWTmIzVnpaU2hsTEhSb2FYTXViMlptYzJWMEtUdGNiaUFnSUNBZ0lDQWdJQ0IwYUdsekxtUnZkMjRvS1R0Y2JpQWdJQ0FnSUNBZ0lDQjBhR2x6TG0xMWJIUnBjMnhwWkdWeUxuWmhiSFZsYzF0MGFHbHpMbWx1WkdWNFhTQTlJSFJvYVhNdWRtRnNkV1U3WEc0Z0lDQWdJQ0FnSUNBZ2FXWWdLSFJvYVhNdWJYVnNkR2x6Ykdsa1pYSXVhVzUwWlhKd2IyeGhkR2x2YmlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYkdWMElHUnBjM1JoYm1ObElEMGdUV0YwYUM1aFluTW9kR2hwY3k1dGRXeDBhWE5zYVdSbGNpNXBiblJsY25CdmJHRjBhVzl1TG1sdVpHVjRMWFJvYVhNdWFXNWtaWGdwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0NCa2FYTjBZVzVqWlNBK0lERWdLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJR3hsZENCc2IzY2dQU0JOWVhSb0xtMXBiaWgwYUdsekxtMTFiSFJwYzJ4cFpHVnlMbWx1ZEdWeWNHOXNZWFJwYjI0dWFXNWtaWGdzZEdocGN5NXBibVJsZUNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUd4bGRDQm9hV2RvSUQwZ1RXRjBhQzV0WVhnb2RHaHBjeTV0ZFd4MGFYTnNhV1JsY2k1cGJuUmxjbkJ2YkdGMGFXOXVMbWx1WkdWNExIUm9hWE11YVc1a1pYZ3BPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQnNaWFFnYkc5M1ZtRnNkV1VnUFNCMGFHbHpMbTExYkhScGMyeHBaR1Z5TG5Oc2FXUmxjbk5iYkc5M1hTNTJZV3gxWlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnYkdWMElHaHBaMmhXWVd4MVpTQTlJSFJvYVhNdWJYVnNkR2x6Ykdsa1pYSXVjMnhwWkdWeWMxdG9hV2RvWFM1MllXeDFaVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdabTl5SUNoc1pYUWdhVDFzYjNjN2FUeG9hV2RvTzJrckt5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNdWJYVnNkR2x6Ykdsa1pYSXVjMnhwWkdWeWMxdHBYUzUyWVd4MVpTQTlJRzFoZEdndWFXNTBaWEp3S0NBb2FTMXNiM2NwTDJScGMzUmhibU5sTENCc2IzZFdZV3gxWlN3Z2FHbG5hRlpoYkhWbElDazdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdiR1YwSUhOdGIyOTBhR1ZrVm1Gc2RXVWdQU0IwYUdsekxtMTFiSFJwYzJ4cFpHVnlMbk5zYVdSbGNuTmJhVjB1ZG1Gc2RXVTdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdkR2hwY3k1dGRXeDBhWE5zYVdSbGNpNTJZV3gxWlhOYmFWMGdQU0J6Ylc5dmRHaGxaRlpoYkhWbE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIUm9hWE11YlhWc2RHbHpiR2xrWlhJdWRYQmtZWFJsS0drc2MyMXZiM1JvWldSV1lXeDFaU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUNBZ0lDQjBhR2x6TG0xMWJIUnBjMnhwWkdWeUxtbHVkR1Z5Y0c5c1lYUnBiMjRnUFNCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwYm1SbGVEb2dkR2hwY3k1cGJtUmxlQ3hjYmlBZ0lDQWdJQ0FnSUNBZ0lIWmhiSFZsT2lCMGFHbHpMblpoYkhWbFhHNGdJQ0FnSUNBZ0lDQWdmVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnZlNrN1hHNWNibHh1SUNBZ0lDQWdkR2hwY3k1dGIzWmxJRDBnS0NrZ1BUNGdlMXh1SUNBZ0lDQWdmVHRjYmlBZ0lDQWdJSFJvYVhNdVpXeGxiV1Z1ZEM1aFpHUkZkbVZ1ZEV4cGMzUmxibVZ5S0NkdGIzVnpaVzF2ZG1VbkxDQW9aU2tnUFQ0Z2UxeHVJQ0FnSUNBZ0lDQnBaaUFvZEdocGN5NXRkV3gwYVhOc2FXUmxjaTVwYm5SbGNtRmpkR2x1WnlrZ2UxeHVJQ0FnSUNBZ0lDQWdJR2xtSUNnaGRHaHBjeTV2Wm1aelpYUXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9hWE11YjJabWMyVjBJRDBnWkc5dExtWnBibVJRYjNOcGRHbHZiaWgwYUdsekxtVnNaVzFsYm5RcE8xeHVJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnSUNCMGFHbHpMbTF2ZFhObElEMGdaRzl0TG14dlkyRjBaVTF2ZFhObEtHVXNkR2hwY3k1dlptWnpaWFFwTzF4dUlDQWdJQ0FnSUNBZ0lIUm9hWE11YzJ4cFpHVW9LVHRjYmlBZ0lDQWdJQ0FnSUNCMGFHbHpMbTExYkhScGMyeHBaR1Z5TG5aaGJIVmxjMXQwYUdsekxtbHVaR1Y0WFNBOUlIUm9hWE11ZG1Gc2RXVTdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJSDBwTzF4dVhHNWNiaUFnSUNBZ0lIUm9hWE11Y21Wc1pXRnpaU0E5SUNncElEMCtJSHRjYmlBZ0lDQWdJQ0FnZEdocGN5NXRkV3gwYVhOc2FXUmxjaTVwYm5SbGNtRmpkR2x1WnlBOUlHWmhiSE5sTzF4dUlDQWdJQ0FnSUNCMGFHbHpMbTExYkhScGMyeHBaR1Z5TG1sdWRHVnljRzlzWVhScGIyNGdQU0JtWVd4elpUdGNiaUFnSUNBZ0lIMDdYRzRnSUNBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1WVdSa1JYWmxiblJNYVhOMFpXNWxjaWduYlc5MWMyVjFjQ2NzSUNncElEMCtJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tIUm9hWE11YlhWc2RHbHpiR2xrWlhJdWFXNTBaWEpoWTNScGJtY3BJSHRjYmlBZ0lDQWdJQ0FnSUNCMGFHbHpMblZ3S0NrN1hHNGdJQ0FnSUNBZ0lDQWdkR2hwY3k1dGRXeDBhWE5zYVdSbGNpNXBiblJsY25CdmJHRjBhVzl1SUQwZ1ptRnNjMlU3WEc0Z0lDQWdJQ0FnSUNBZ2RHaHBjeTV0ZFd4MGFYTnNhV1JsY2k1MllXeDFaWE5iZEdocGN5NXBibVJsZUYwZ1BTQjBhR2x6TG5aaGJIVmxPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0I5S1R0Y2JpQWdJQ0FnSUhSb2FYTXVaV3hsYldWdWRDNWhaR1JGZG1WdWRFeHBjM1JsYm1WeUtDZHRiM1Z6Wlc5MWRDY3NJQ2dwSUQwK0lIdGNiaUFnSUNBZ0lDQWdhV1lnS0hSb2FYTXViWFZzZEdsemJHbGtaWEl1YVc1MFpYSmhZM1JwYm1jcElIdGNiaUFnSUNBZ0lDQWdJQ0IwYUdsekxuVndLQ2s3WEc0Z0lDQWdJQ0FnSUNBZ2RHaHBjeTV0ZFd4MGFYTnNhV1JsY2k1MllXeDFaWE5iZEdocGN5NXBibVJsZUYwZ1BTQjBhR2x6TG5aaGJIVmxPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0I5S1R0Y2JseHVJQ0FnSUgxY2JseHVJQ0FnSUhSb2FYTXVZM1Z6ZEc5dFUzUjViR1VvS1R0Y2JpQWdmVnh1WEc0Z0lHTjFjM1J2YlZOMGVXeGxLQ2tnZTF4dVhHNGdJQ0FnTHlvZ2MzUjViR1VnWTJoaGJtZGxjeUFxTDF4dVhHNGdJQ0FnZEdocGN5NWlZWEl1YzJWMFFYUjBjbWxpZFhSbEtDZDRKeXd3S1R0Y2JpQWdJQ0IwYUdsekxtSmhjaTV6WlhSQmRIUnlhV0oxZEdVb0ozUnlZVzV6Wm05eWJTY3NKM1J5WVc1emJHRjBaU2d3TERBcEp5azdYRzRnSUNBZ2RHaHBjeTVpWVhJdWMyVjBRWFIwY21saWRYUmxLQ2R5ZUNjc01DazdJQzh2SUdOdmNtNWxjaUJ5WVdScGRYTmNiaUFnSUNCMGFHbHpMbUpoY2k1elpYUkJkSFJ5YVdKMWRHVW9KM0o1Snl3d0tUdGNiaUFnSUNCMGFHbHpMbUpoY2k1elpYUkJkSFJ5YVdKMWRHVW9KM2RwWkhSb0p5eDBhR2x6TG5kcFpIUm9LVHRjYmlBZ0lDQjBhR2x6TG1KaGNpNXpaWFJCZEhSeWFXSjFkR1VvSjJobGFXZG9kQ2NzZEdocGN5NW9aV2xuYUhRcE8xeHVYRzRnSUNBZ2RHaHBjeTVtYVd4c1ltRnlMbk5sZEVGMGRISnBZblYwWlNnbmVDY3NNQ2s3WEc0Z0lDQWdkR2hwY3k1bWFXeHNZbUZ5TG5ObGRFRjBkSEpwWW5WMFpTZ25kSEpoYm5ObWIzSnRKeXduZEhKaGJuTnNZWFJsS0RBc01Da25LVHRjYmlBZ0lDQjBhR2x6TG1acGJHeGlZWEl1YzJWMFFYUjBjbWxpZFhSbEtDZHllQ2NzTUNrN0lDOHZJR052Y201bGNpQnlZV1JwZFhOY2JpQWdJQ0IwYUdsekxtWnBiR3hpWVhJdWMyVjBRWFIwY21saWRYUmxLQ2R5ZVNjc01DazdYRzRnSUNBZ2RHaHBjeTVtYVd4c1ltRnlMbk5sZEVGMGRISnBZblYwWlNnbmQybGtkR2duTEhSb2FYTXVkMmxrZEdncE8xeHVJQ0FnSUhSb2FYTXVabWxzYkdKaGNpNXpaWFJCZEhSeWFXSjFkR1VvSjJobGFXZG9kQ2NzZEdocGN5NW9aV2xuYUhRcE8xeHVYRzRnSUgxY2JseHVmVnh1WEc0dktpcGNiaW9nVFhWc2RHbHpiR2xrWlhKY2JpcGNiaW9nUUdSbGMyTnlhWEIwYVc5dUlFMTFiSFJwYzJ4cFpHVnlYRzRxWEc0cUlFQmtaVzF2SUR4emNHRnVJRzVsZUhWekxYVnBQVndpYlhWc2RHbHpiR2xrWlhKY0lqNDhMM053WVc0K1hHNHFYRzRxSUVCbGVHRnRjR3hsWEc0cUlIWmhjaUJ0ZFd4MGFYTnNhV1JsY2lBOUlHNWxkeUJPWlhoMWN5NU5kV3gwYVhOc2FXUmxjaWduSTNSaGNtZGxkQ2NwWEc0cVhHNHFJRUJsZUdGdGNHeGxYRzRxSUhaaGNpQnRkV3gwYVhOc2FXUmxjaUE5SUc1bGR5Qk9aWGgxY3k1TmRXeDBhWE5zYVdSbGNpZ25JM1JoY21kbGRDY3NlMXh1S2lBZ0ozTnBlbVVuT2lCYk1qQXdMREV3TUYwc1hHNHFJQ0FuYm5WdFltVnlUMlpUYkdsa1pYSnpKem9nTlN4Y2Jpb2dJQ2R0YVc0bk9pQXdMRnh1S2lBZ0oyMWhlQ2M2SURFc1hHNHFJQ0FuYzNSbGNDYzZJREFzWEc0cUlDQW5kbUZzZFdWekp6b2dXekF1Tnl3d0xqY3NNQzQzTERBdU55d3dMamRkWEc0cUlIMHBYRzRxWEc0cUlFQnZkWFJ3ZFhSY2Jpb2dZMmhoYm1kbFhHNHFJRVpwY21WeklHRnVlU0IwYVcxbElIUm9aU0JwYm5SbGNtWmhZMlVuY3lCMllXeDFaU0JqYUdGdVoyVnpMaUE4WW5JK1hHNHFJRlJvWlNCbGRtVnVkQ0JrWVhSaElHRnVJRzlpYW1WamRDQmpiMjUwWVdsdWFXNW5JRHhwUG1sdVpHVjRQQzlwUGlCaGJtUWdQR2srZG1Gc2RXVThMMmsrSUhCeWIzQmxjblJwWlhOY2JpcGNiaW9nUUc5MWRIQjFkR1Y0WVcxd2JHVmNiaW9nYlhWc2RHbHpiR2xrWlhJdWIyNG9KMk5vWVc1blpTY3NablZ1WTNScGIyNG9kaWtnZTF4dUtpQWdJR052Ym5OdmJHVXViRzluS0hZcE8xeHVLaUI5S1Z4dUtseHVLaTljYmx4dUx5cGNibEJ5YjNCbGNuUnBaWE5jYmk1MllXeDFaWE5jYmx4dUtpOWNibHh1Wlhod2IzSjBJR1JsWm1GMWJIUWdZMnhoYzNNZ1RYVnNkR2x6Ykdsa1pYSWdaWGgwWlc1a2N5QkpiblJsY21aaFkyVWdlMXh1WEc0Z0lHTnZibk4wY25WamRHOXlLQ2tnZTF4dVhHNGdJQ0FnYkdWMElHOXdkR2x2Ym5NZ1BTQmJKM1poYkhWbEoxMDdYRzVjYmlBZ0lDQnNaWFFnWkdWbVlYVnNkSE1nUFNCN1hHNGdJQ0FnSUNBbmMybDZaU2M2SUZzeU1EQXNNVEF3WFN4Y2JpQWdJQ0FnSUNkdWRXMWlaWEpQWmxOc2FXUmxjbk1uT2lBMUxGeHVJQ0FnSUNBZ0oyMXBiaWM2SURBc1hHNGdJQ0FnSUNBbmJXRjRKem9nTVN4Y2JpQWdJQ0FnSUNkemRHVndKem9nTUN4Y2JpQWdJQ0FnSUNkMllXeDFaWE1uT2lCYk1DNDNMREF1Tnl3d0xqY3NNQzQzTERBdU4xMWNiaUFnSUNCOU8xeHVYRzRnSUNBZ2MzVndaWElvWVhKbmRXMWxiblJ6TEc5d2RHbHZibk1zWkdWbVlYVnNkSE1wTzF4dVhHNGdJQ0FnZEdocGN5NWZiblZ0WW1WeVQyWlRiR2xrWlhKeklEMGdkR2hwY3k1elpYUjBhVzVuY3k1dWRXMWlaWEpQWmxOc2FXUmxjbk03WEc0Z0lDQWdkR2hwY3k1MllXeDFaWE1nUFNCMGFHbHpMbk5sZEhScGJtZHpMblpoYkhWbGN6dGNibHh1SUNBZ0lIUm9hWE11YzJ4cFpHVnljeUE5SUZ0ZE8xeHVYRzRnSUNBZ2RHaHBjeTVwYm5SbGNtRmpkR2x1WnlBOUlHWmhiSE5sTzF4dVhHNGdJQ0FnZEdocGN5NXBibWwwS0NrN1hHNWNiaUFnZlZ4dVhHNGdJR0oxYVd4a1JuSmhiV1VvS1NCN1hHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MElEMGdaRzlqZFcxbGJuUXVZM0psWVhSbFJXeGxiV1Z1ZENnblpHbDJKeWs3WEc0Z0lDQWdkR2hwY3k1d1lYSmxiblF1WVhCd1pXNWtRMmhwYkdRb2RHaHBjeTVsYkdWdFpXNTBLVHRjYmlBZ2ZWeHVYRzRnSUdKMWFXeGtTVzUwWlhKbVlXTmxLQ2tnZTF4dVhHNGdJQ0FnYkdWMElHMXBiaUE5SUhSb2FYTXVjMlYwZEdsdVozTXViV2x1TzF4dUlDQWdJR3hsZENCdFlYZ2dQU0IwYUdsekxuTmxkSFJwYm1kekxtMWhlRHRjYmlBZ0lDQnNaWFFnYzNSbGNDQTlJSFJvYVhNdWMyVjBkR2x1WjNNdWMzUmxjRHRjYmx4dUlDQWdJR2xtSUNoMGFHbHpMbk5zYVdSbGNuTXViR1Z1WjNSb0tTQjdYRzRnSUNBZ0lDQnRhVzRnUFNCMGFHbHpMbk5zYVdSbGNuTmJNRjB1YldsdU8xeHVJQ0FnSUNBZ2JXRjRJRDBnZEdocGN5NXpiR2xrWlhKeld6QmRMbTFoZUR0Y2JpQWdJQ0FnSUhOMFpYQWdQU0IwYUdsekxuTnNhV1JsY25OYk1GMHVjM1JsY0R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0IwYUdsekxuTnNhV1JsY25NZ1BTQmJYVHRjYmx4dUlDQWdJR1p2Y2lBb2JHVjBJR2s5TUR0cFBIUm9hWE11WDI1MWJXSmxjazltVTJ4cFpHVnljenRwS3lzcElIdGNiaUFnSUNBZ0lHeGxkQ0JqYjI1MFlXbHVaWElnUFNCa2IyTjFiV1Z1ZEM1amNtVmhkR1ZGYkdWdFpXNTBLQ2R6Y0dGdUp5azdYRzVjYmlBZ0lDQWdJR3hsZENCemJHbGtaWElnUFNCdVpYY2dVMmx1WjJ4bFUyeHBaR1Z5S0dOdmJuUmhhVzVsY2l3Z2UxeHVJQ0FnSUNBZ0lDQWdJSE5qWVd4bE9pQmJiV2x1TEcxaGVGMHNYRzRnSUNBZ0lDQWdJQ0FnYzNSbGNEb2djM1JsY0N4Y2JpQWdJQ0FnSUNBZ0lDQnRiMlJsT2lBbllXSnpiMngxZEdVbkxGeHVJQ0FnSUNBZ0lDQWdJRzl5YVdWdWRHRjBhVzl1T2lBbmRtVnlkR2xqWVd3bkxGeHVJQ0FnSUNBZ0lDQWdJSFpoYkhWbE9pQjBhR2x6TG5aaGJIVmxjMXRwWFN4Y2JpQWdJQ0FnSUNBZ0lDQm9ZWE5MYm05aU9pQm1ZV3h6WlN4Y2JpQWdJQ0FnSUNBZ0lDQmpiMjF3YjI1bGJuUTZJSFJ5ZFdVc1hHNGdJQ0FnSUNBZ0lIMHNkR2hwY3k1MWNHUmhkR1V1WW1sdVpDaDBhR2x6TEdrcEtUdGNiaUFnSUNBZ0lITnNhV1JsY2k1dGRXeDBhWE5zYVdSbGNpQTlJSFJvYVhNN1hHNWNiaUFnSUNBZ0lITnNhV1JsY2k1cGJtUmxlQ0E5SUdrN1hHNGdJQ0FnSUNCcFppQW9kRzkxWTJndVpYaHBjM1J6S1NCN1hHNGdJQ0FnSUNBZ0lITnNhV1JsY2k1aVlYSXVhVzVrWlhnZ1BTQnBPMXh1SUNBZ0lDQWdJQ0J6Ykdsa1pYSXVabWxzYkdKaGNpNXBibVJsZUNBOUlHazdYRzRnSUNBZ0lDQWdJSE5zYVdSbGNpNXdjbVZEYkdsamF5QTlJSE5zYVdSbGNpNXdjbVZOYjNabElEMGdjMnhwWkdWeUxuQnlaVkpsYkdWaGMyVWdQU0FvS1NBOVBpQjdmVHRjYmlBZ0lDQWdJQ0FnYzJ4cFpHVnlMbU5zYVdOcklEMGdjMnhwWkdWeUxtMXZkbVVnUFNCemJHbGtaWEl1Y21Wc1pXRnpaU0E5SUNncElEMCtJSHQ5TzF4dUlDQWdJQ0FnSUNCemJHbGtaWEl1Y0hKbFZHOTFZMmdnUFNCemJHbGtaWEl1Y0hKbFZHOTFZMmhOYjNabElEMGdjMnhwWkdWeUxuQnlaVlJ2ZFdOb1VtVnNaV0Z6WlNBOUlDZ3BJRDArSUh0OU8xeHVJQ0FnSUNBZ0lDQnpiR2xrWlhJdWRHOTFZMmdnUFNCemJHbGtaWEl1ZEc5MVkyaE5iM1psSUQwZ2MyeHBaR1Z5TG5SdmRXTm9VbVZzWldGelpTQTlJQ2dwSUQwK0lIdDlPMXh1SUNBZ0lDQWdmVnh1WEc0Z0lDQWdJQ0IwYUdsekxuTnNhV1JsY25NdWNIVnphQ2h6Ykdsa1pYSXBPMXh1SUNBZ0lDQWdkR2hwY3k1bGJHVnRaVzUwTG1Gd2NHVnVaRU5vYVd4a0tHTnZiblJoYVc1bGNpazdYRzVjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSFJ2ZFdOb0xtVjRhWE4wY3lrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTVoWkdSVWIzVmphRXhwYzNSbGJtVnljeWdwTzF4dUlDQWdJSDFjYmx4dUlDQjlYRzVjYmlBZ1kyOXNiM0pKYm5SbGNtWmhZMlVvS1NCN1hHNGdJQ0FnWm05eUlDaHNaWFFnYVQwd08yazhkR2hwY3k1emJHbGtaWEp6TG14bGJtZDBhRHRwS3lzcElIdGNiaUFnSUNBZ0lIUm9hWE11YzJ4cFpHVnljMXRwWFM1amIyeHZjbk1nUFNCMGFHbHpMbU52Ykc5eWN6dGNiaUFnSUNBZ0lIUm9hWE11YzJ4cFpHVnljMXRwWFM1amIyeHZja2x1ZEdWeVptRmpaU2dwTzF4dUlDQWdJSDFjYmlBZ2ZWeHVYRzRnSUhOcGVtVkpiblJsY21aaFkyVW9LU0I3WEc1Y2JpQWdJQ0JzWlhRZ2MyeHBaR1Z5VjJsa2RHZ2dQU0IwYUdsekxuZHBaSFJvSUM4Z2RHaHBjeTV6Ykdsa1pYSnpMbXhsYm1kMGFEdGNiaUFnSUNCc1pYUWdjMnhwWkdWeVNHVnBaMmgwSUQwZ2RHaHBjeTVvWldsbmFIUTdYRzVjYmlBZ0lDQm1iM0lnS0d4bGRDQnBQVEE3YVR4MGFHbHpMbk5zYVdSbGNuTXViR1Z1WjNSb08ya3JLeWtnZTF4dUlDQWdJQ0FnZEdocGN5NXpiR2xrWlhKelcybGRMbkpsYzJsNlpTaHpiR2xrWlhKWGFXUjBhQ3h6Ykdsa1pYSklaV2xuYUhRcE8xeHVJQ0FnSUNBZ2RHaHBjeTV6Ykdsa1pYSnpXMmxkTG1OMWMzUnZiVk4wZVd4bEtDazdYRzRnSUNBZ2ZWeHVYRzVjYmlBZ2ZWeHVYRzRnSUhWd1pHRjBaU2hwYm1SbGVDeDJZV3gxWlNrZ2UxeHVJQ0FnSUhSb2FYTXVaVzFwZENnblkyaGhibWRsSnl4N1hHNGdJQ0FnSUNBbmFXNWtaWGduT2lCcGJtUmxlQ3hjYmlBZ0lDQWdJQ2QyWVd4MVpTYzZJSFpoYkhWbFhHNGdJQ0FnZlNrN1hHNGdJSDFjYmx4dUlDQmhaR1JVYjNWamFFeHBjM1JsYm1WeWN5Z3BJSHRjYmx4dUlDQWdJSFJvYVhNdWNISmxRMnhwWTJzZ1BTQjBhR2x6TG5CeVpVMXZkbVVnUFNCMGFHbHpMbkJ5WlZKbGJHVmhjMlVnUFNBb0tTQTlQaUI3ZlR0Y2JpQWdJQ0IwYUdsekxtTnNhV05ySUQwZ2RHaHBjeTV0YjNabElEMGdkR2hwY3k1eVpXeGxZWE5sSUQwZ0tDa2dQVDRnZTMwN1hHNGdJQ0FnZEdocGN5NXdjbVZVYjNWamFDQTlJSFJvYVhNdWNISmxWRzkxWTJoTmIzWmxJRDBnZEdocGN5NXdjbVZVYjNWamFGSmxiR1ZoYzJVZ1BTQW9LU0E5UGlCN2ZUdGNiaUFnSUNCMGFHbHpMblJ2ZFdOb0lEMGdkR2hwY3k1MGIzVmphRTF2ZG1VZ1BTQjBhR2x6TG5SdmRXTm9VbVZzWldGelpTQTlJQ2dwSUQwK0lIdDlPMXh1WEc0Z0lDQWdkR2hwY3k1amRYSnlaVzUwUld4bGJXVnVkQ0E5SUdaaGJITmxPMXh1WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG1Ga1pFVjJaVzUwVEdsemRHVnVaWElvSjNSdmRXTm9jM1JoY25RbkxDQW9aU2tnUFQ0Z2UxeHVJQ0FnSUNBZ2JHVjBJR1ZzWlcxbGJuUWdQU0JrYjJOMWJXVnVkQzVsYkdWdFpXNTBSbkp2YlZCdmFXNTBLR1V1ZEdGeVoyVjBWRzkxWTJobGMxc3dYUzVqYkdsbGJuUllMR1V1ZEdGeVoyVjBWRzkxWTJobGMxc3dYUzVqYkdsbGJuUlpLVHRjYmlBZ0lDQWdJR3hsZENCemJHbGtaWElnUFNCMGFHbHpMbk5zYVdSbGNuTmJaV3hsYldWdWRDNXBibVJsZUYwN1hHNGdJQ0FnSUNCcFppQW9JWE5zYVdSbGNpNXZabVp6WlhRcElIdGNiaUFnSUNBZ0lDQWdjMnhwWkdWeUxtOW1abk5sZENBOUlHUnZiUzVtYVc1a1VHOXphWFJwYjI0b2MyeHBaR1Z5TG1Wc1pXMWxiblFwTzF4dUlDQWdJQ0FnZlZ4dUlDQWdJQ0FnYzJ4cFpHVnlMbTF2ZFhObElEMGdaRzl0TG14dlkyRjBaVTF2ZFhObEtHVXNjMnhwWkdWeUxtOW1abk5sZENrN1hHNGdJQ0FnSUNCemJHbGtaWEl1Wkc5M2JpZ3BPMXh1SUNBZ0lDQWdkR2hwY3k1amRYSnlaVzUwUld4bGJXVnVkQ0E5SUdWc1pXMWxiblF1YVc1a1pYZzdYRzRnSUNBZ0lDQmxMbkJ5WlhabGJuUkVaV1poZFd4MEtDazdYRzRnSUNBZ0lDQmxMbk4wYjNCUWNtOXdZV2RoZEdsdmJpZ3BPMXh1SUNBZ0lIMHBPMXh1WEc0Z0lDQWdkR2hwY3k1bGJHVnRaVzUwTG1Ga1pFVjJaVzUwVEdsemRHVnVaWElvSjNSdmRXTm9iVzkyWlNjc0lDaGxLU0E5UGlCN1hHNGdJQ0FnSUNCc1pYUWdaV3hsYldWdWRDQTlJR1J2WTNWdFpXNTBMbVZzWlcxbGJuUkdjbTl0VUc5cGJuUW9aUzUwWVhKblpYUlViM1ZqYUdWeld6QmRMbU5zYVdWdWRGZ3NaUzUwWVhKblpYUlViM1ZqYUdWeld6QmRMbU5zYVdWdWRGa3BPMXh1SUNBZ0lDQWdiR1YwSUhOc2FXUmxjaUE5SUhSb2FYTXVjMnhwWkdWeWMxdGxiR1Z0Wlc1MExtbHVaR1Y0WFR0Y2JpQWdJQ0FnSUdsbUlDZ2hjMnhwWkdWeUxtOW1abk5sZENrZ2UxeHVJQ0FnSUNBZ0lDQnpiR2xrWlhJdWIyWm1jMlYwSUQwZ1pHOXRMbVpwYm1SUWIzTnBkR2x2YmloemJHbGtaWEl1Wld4bGJXVnVkQ2s3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdJQ0J6Ykdsa1pYSXViVzkxYzJVZ1BTQmtiMjB1Ykc5allYUmxUVzkxYzJVb1pTeHpiR2xrWlhJdWIyWm1jMlYwS1R0Y2JpQWdJQ0FnSUdsbUlDaGxiR1Z0Wlc1MExtbHVaR1Y0SVQwOWRHaHBjeTVqZFhKeVpXNTBSV3hsYldWdWRDa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2RHaHBjeTVqZFhKeVpXNTBSV3hsYldWdWRDQStQU0F3S1NCN1hHNGdJQ0FnSUNBZ0lDQWdiR1YwSUhCaGMzUnpiR2xrWlhJZ1BTQjBhR2x6TG5Oc2FXUmxjbk5iZEdocGN5NWpkWEp5Wlc1MFJXeGxiV1Z1ZEYwN1hHNGdJQ0FnSUNBZ0lDQWdjR0Z6ZEhOc2FXUmxjaTUxY0NncE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSE5zYVdSbGNpNWtiM2R1S0NrN1hHNGdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNCemJHbGtaWEl1YzJ4cFpHVW9LVHRjYmlBZ0lDQWdJSDFjYmlBZ0lDQWdJSFJvYVhNdVkzVnljbVZ1ZEVWc1pXMWxiblFnUFNCbGJHVnRaVzUwTG1sdVpHVjRPMXh1SUNBZ0lDQWdaUzV3Y21WMlpXNTBSR1ZtWVhWc2RDZ3BPMXh1SUNBZ0lDQWdaUzV6ZEc5d1VISnZjR0ZuWVhScGIyNG9LVHRjYmlBZ0lDQjlLVHRjYmx4dUlDQWdJSFJvYVhNdVpXeGxiV1Z1ZEM1aFpHUkZkbVZ1ZEV4cGMzUmxibVZ5S0NkMGIzVmphR1Z1WkNjc0lDaGxLU0E5UGlCN1hHNGdJQ0FnSUNBdkx5QnVieUIwYjNWamFHVnpJSFJ2SUdOaGJHTjFiR0YwWlNCaVpXTmhkWE5sSUc1dmJtVWdjbVZ0WVdsdWFXNW5YRzRnSUNBZ0lDQnNaWFFnYzJ4cFpHVnlJRDBnZEdocGN5NXpiR2xrWlhKelczUm9hWE11WTNWeWNtVnVkRVZzWlcxbGJuUmRPMXh1SUNBZ0lDQWdjMnhwWkdWeUxuVndLQ2s3WEc0Z0lDQWdJQ0IwYUdsekxtbHVkR1Z5WVdOMGFXNW5JRDBnWm1Gc2MyVTdYRzRnSUNBZ0lDQjBhR2x6TG1OMWNuSmxiblJGYkdWdFpXNTBJRDBnWm1Gc2MyVTdYRzRnSUNBZ0lDQmxMbkJ5WlhabGJuUkVaV1poZFd4MEtDazdYRzRnSUNBZ0lDQmxMbk4wYjNCUWNtOXdZV2RoZEdsdmJpZ3BPMXh1SUNBZ0lIMHBPMXh1WEc0Z0lIMWNibHh1SUNBdktpcGNiaUFnUjJWMElHOXlJSE5sZENCMGFHVWdiblZ0WW1WeUlHOW1JSE5zYVdSbGNuTmNiaUFnUUhSNWNHVWdlMDUxYldKbGNuMWNiaUFnS2k5Y2JpQWdaMlYwSUc1MWJXSmxjazltVTJ4cFpHVnljeWdwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1emJHbGtaWEp6TG14bGJtZDBhRHRjYmlBZ2ZWeHVYRzRnSUhObGRDQnVkVzFpWlhKUFpsTnNhV1JsY25Nb2Rpa2dlMXh1SUNBZ0lHbG1JQ2gyUFQwOWRHaHBjeTV6Ykdsa1pYSnpMbXhsYm1kMGFDa2dlMXh1SUNBZ0lDQWdjbVYwZFhKdU8xeHVJQ0FnSUgxY2JpQWdJQ0IwYUdsekxuTnNhV1JsY25NdVptOXlSV0ZqYUNnb2MyeHBaR1Z5S1QwK2UxeHVJQ0FnSUNBZ2MyeHBaR1Z5TG1SbGMzUnliM2tvS1R0Y2JpQWdJQ0I5S1R0Y2JpQWdJQ0IwYUdsekxtVnRjSFI1S0NrN1hHNGdJQ0FnZEdocGN5NWZiblZ0WW1WeVQyWlRiR2xrWlhKeklEMGdkanRjYmlBZ0lDQjBhR2x6TG1KMWFXeGtTVzUwWlhKbVlXTmxLQ2s3WEc0Z0lIMWNibHh1WEc1Y2JpQWdMeW9xWEc0Z0lFeHZkMlZ5SUd4cGJXbDBJRzltSUhSb1pTQnRkV3gwYVhOc2FXUmxjaWR6SUc5MWRIQjFkQ0J5WVc1blpWeHVJQ0JBZEhsd1pTQjdiblZ0WW1WeWZWeHVJQ0JBWlhoaGJYQnNaU0J0ZFd4MGFYTnNhV1JsY2k1dGFXNGdQU0F4TURBd08xeHVJQ0FxTDF4dUlDQm5aWFFnYldsdUtDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbk5zYVdSbGNuTmJNRjB1YldsdU8xeHVJQ0I5WEc0Z0lITmxkQ0J0YVc0b2Rpa2dlMXh1SUNBZ0lIUm9hWE11YzJ4cFpHVnljeTVtYjNKRllXTm9LQ2h6Ykdsa1pYSXBQVDU3WEc0Z0lDQWdJQ0J6Ykdsa1pYSXViV2x1SUQwZ2RqdGNiaUFnSUNCOUtUdGNiaUFnZlZ4dVhHNGdJQzhxS2x4dUlDQlZjSEJsY2lCc2FXMXBkQ0J2WmlCMGFHVWdiWFZzZEdsemJHbGtaWEluY3lCdmRYUndkWFFnY21GdVoyVmNiaUFnUUhSNWNHVWdlMjUxYldKbGNuMWNiaUFnUUdWNFlXMXdiR1VnYlhWc2RHbHpiR2xrWlhJdWJXRjRJRDBnTVRBd01EdGNiaUFnS2k5Y2JpQWdaMlYwSUcxaGVDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTV6Ykdsa1pYSnpXekJkTG0xaGVEdGNiaUFnZlZ4dUlDQnpaWFFnYldGNEtIWXBJSHRjYmlBZ0lDQjBhR2x6TG5Oc2FXUmxjbk11Wm05eVJXRmphQ2dvYzJ4cFpHVnlLVDArZTF4dUlDQWdJQ0FnYzJ4cFpHVnlMbTFoZUNBOUlIWTdYRzRnSUNBZ2ZTazdYRzRnSUgxY2JseHVJQ0F2S2lwY2JpQWdWR2hsSUdsdVkzSmxiV1Z1ZENCMGFHRjBJSFJvWlNCdGRXeDBhWE5zYVdSbGNpZHpJSFpoYkhWbElHTm9ZVzVuWlhNZ1lua3VYRzRnSUVCMGVYQmxJSHR1ZFcxaVpYSjlYRzRnSUVCbGVHRnRjR3hsSUcxMWJIUnBjMnhwWkdWeUxuTjBaWEFnUFNBMU8xeHVJQ0FxTDF4dUlDQm5aWFFnYzNSbGNDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTV6Ykdsa1pYSnpXekJkTG5OMFpYQTdYRzRnSUgxY2JpQWdjMlYwSUhOMFpYQW9kaWtnZTF4dUlDQWdJSFJvYVhNdWMyeHBaR1Z5Y3k1bWIzSkZZV05vS0NoemJHbGtaWElwUFQ1N1hHNGdJQ0FnSUNCemJHbGtaWEl1YzNSbGNDQTlJSFk3WEc0Z0lDQWdmU2s3WEc0Z0lIMWNibHh1SUNBdktpcGNiaUFnVTJWMElIUm9aU0IyWVd4MVpTQnZaaUJoYmlCcGJtUnBkbWxrZFdGc0lITnNhV1JsY2x4dUlDQkFjR0Z5WVcwZ2FXNWtaWGdnZTI1MWJXSmxjbjBnVTJ4cFpHVnlJR2x1WkdWNFhHNGdJRUJ3WVhKaGJTQjJZV3gxWlNCN2JuVnRZbVZ5ZlNCT1pYY2djMnhwWkdWeUlIWmhiSFZsWEc0Z0lFQmxlR0Z0Y0d4bFhHNGdJQzh2SUZObGRDQjBhR1VnWm1seWMzUWdjMnhwWkdWeUlIUnZJSFpoYkhWbElEQXVOVnh1SUNCdGRXeDBhWE5zYVdSbGNpNXpaWFJUYkdsa1pYSW9NQ3d3TGpVcFhHNGdJQ292WEc0Z0lITmxkRk5zYVdSbGNpaHBibVJsZUN4MllXeDFaU2tnZTF4dUlDQWdJSFJvYVhNdWMyeHBaR1Z5YzF0cGJtUmxlRjB1ZG1Gc2RXVWdQU0IyWVd4MVpUdGNiaUFnSUNCMGFHbHpMbVZ0YVhRb0oyTm9ZVzVuWlNjc2UxeHVJQ0FnSUNBZ0oybHVaR1Y0SnpvZ2FXNWtaWGdzWEc0Z0lDQWdJQ0FuZG1Gc2RXVW5PaUIyWVd4MVpWeHVJQ0FnSUgwcE8xeHVJQ0I5WEc1Y2JpQWdMeW9xWEc0Z0lGTmxkQ0IwYUdVZ2RtRnNkV1VnYjJZZ1lXeHNJSE5zYVdSbGNuTWdZWFFnYjI1alpTNGdTV1lnZEdobElITnBlbVVnYjJZZ2RHaGxJR2x1Y0hWMElHRnljbUY1SUdSdlpYTWdibTkwSUcxaGRHTm9JSFJvWlNCamRYSnlaVzUwSUc1MWJXSmxjaUJ2WmlCemJHbGtaWEp6TENCMGFHVWdkbUZzZFdVZ1lYSnlZWGtnZDJsc2JDQnlaWEJsWVhRZ2RXNTBhV3dnWVd4c0lITnNhV1JsY25NZ2FHRjJaU0JpWldWdUlITmxkQzRnU1M1bExpQmhiaUJwYm5CMWRDQmhjbkpoZVNCdlppQnNaVzVuZEdnZ01TQjNhV3hzSUhObGRDQmhiR3dnYzJ4cFpHVnljeUIwYnlCMGFHRjBJSFpoYkhWbExseHVJQ0JBY0dGeVlXMGdkbUZzZFdWeklIdEJjbkpoZVgwZ1FXeHNJSE5zYVdSbGNpQjJZV3gxWlhOY2JpQWdRR1Y0WVcxd2JHVmNiaUFnYlhWc2RHbHpiR2xrWlhJdWMyVjBRV3hzVTJ4cFpHVnljeWhiTUM0eUxEQXVNeXd3TGpRc01DNDFMREF1TmwwcFhHNGdJQ292WEc0Z0lITmxkRUZzYkZOc2FXUmxjbk1vZG1Gc2RXVnpLU0I3WEc0Z0lDQWdkR2hwY3k1MllXeDFaWE1nUFNCMllXeDFaWE03WEc0Z0lDQWdkR2hwY3k1emJHbGtaWEp6TG1admNrVmhZMmdvS0hOc2FXUmxjaXhwS1QwK2UxeHVJQ0FnSUNBZ2MyeHBaR1Z5TG5aaGJIVmxJRDBnZG1Gc2RXVnpXMmtsZG1Gc2RXVnpMbXhsYm1kMGFGMDdYRzRnSUNBZ0lDQjBhR2x6TG1WdGFYUW9KMk5vWVc1blpTY3NlMXh1SUNBZ0lDQWdJQ0FuYVc1a1pYZ25PaUJwTEZ4dUlDQWdJQ0FnSUNBbmRtRnNkV1VuT2lCemJHbGtaWEl1ZG1Gc2RXVmNiaUFnSUNBZ0lIMHBPMXh1SUNBZ0lIMHBPMXh1SUNCOVhHNWNibjFjYmx4dVhHNWNiaTh2SUZkRlFsQkJRMHNnUms5UFZFVlNJQzh2WEc0dkx5QXVMMzR2YW5Ob2FXNTBMV3h2WVdSbGNpRXVMMnhwWWk5cGJuUmxjbVpoWTJWekwyMTFiSFJwYzJ4cFpHVnlMbXB6SWl3aUozVnpaU0J6ZEhKcFkzUW5PMXh1WEc1c1pYUWdjM1puSUQwZ2NtVnhkV2x5WlNnbkxpNHZkWFJwYkM5emRtY25LVHRjYm14bGRDQkpiblJsY21aaFkyVWdQU0J5WlhGMWFYSmxLQ2N1TGk5amIzSmxMMmx1ZEdWeVptRmpaU2NwTzF4dWJHVjBJRk4wWlhBZ1BTQnlaWEYxYVhKbEtDY3VMaTl0YjJSbGJITXZjM1JsY0NjcE8xeHVhVzF3YjNKMElDb2dZWE1nU1c1MFpYSmhZM1JwYjI0Z1puSnZiU0FuTGk0dmRYUnBiQzlwYm5SbGNtRmpkR2x2YmljN1hHNWNibVY0Y0c5eWRDQmtaV1poZFd4MElHTnNZWE56SUZOc2FXUmxjbFJsYlhCc1lYUmxJR1Y0ZEdWdVpITWdTVzUwWlhKbVlXTmxJSHRjYmx4dUlDQmpiMjV6ZEhKMVkzUnZjaWhoY21kekxHOXdkR2x2Ym5Nc1pHVm1ZWFZzZEhNcElIdGNibHh1SUNBZ0lITjFjR1Z5S0dGeVozTXNiM0IwYVc5dWN5eGtaV1poZFd4MGN5azdYRzVjYmlBZ0lDQjBhR2x6TG05eWFXVnVkR0YwYVc5dUlEMGdkR2hwY3k1elpYUjBhVzVuY3k1dmNtbGxiblJoZEdsdmJqdGNibHh1SUNBdkx5QWdkR2hwY3k1dGIyUmxJRDBnZEdocGN5NXpaWFIwYVc1bmN5NXRiMlJsTzF4dVhHNGdJQ0FnZEdocGN5NW9ZWE5MYm05aUlEMGdkR2hwY3k1elpYUjBhVzVuY3k1b1lYTkxibTlpTzF4dVhHNGdJQ0FnTHk4Z2RHaHBjeTV6ZEdWd0lITm9iM1ZzWkNCbGRtVnVkSFZoYkd4NUlHSmxJR2RsZEM5elpYUmNiaUFnSUNBdkx5QjFjR1JoZEdsdVp5QnBkQ0IzYVd4c0lIVndaR0YwWlNCMGFHVWdYM1poYkhWbElITjBaWEFnYlc5a1pXeGNiaUFnTHk4Z0lIUm9hWE11YzNSbGNDQTlJSFJvYVhNdWMyVjBkR2x1WjNNdWMzUmxjRHNnTHk4Z1pteHZZWFJjYmx4dUlDQWdJSFJvYVhNdVgzWmhiSFZsSUQwZ2JtVjNJRk4wWlhBb2RHaHBjeTV6WlhSMGFXNW5jeTV6WTJGc1pWc3dYU3dnZEdocGN5NXpaWFIwYVc1bmN5NXpZMkZzWlZzeFhTd2dkR2hwY3k1elpYUjBhVzVuY3k1emRHVndMQ0IwYUdsekxuTmxkSFJwYm1kekxuWmhiSFZsS1R0Y2JseHVJQ0FnSUhSb2FYTXVhVzVwZENncE8xeHVYRzRnSUNBZ2RHaHBjeTV3YjNOcGRHbHZiaUE5SUc1bGR5QkpiblJsY21GamRHbHZiaTVJWVc1a2JHVW9kR2hwY3k1elpYUjBhVzVuY3k1dGIyUmxMSFJvYVhNdWIzSnBaVzUwWVhScGIyNHNXekFzZEdocGN5NTNhV1IwYUYwc1czUm9hWE11YUdWcFoyaDBMREJkS1R0Y2JpQWdJQ0IwYUdsekxuQnZjMmwwYVc5dUxuWmhiSFZsSUQwZ2RHaHBjeTVmZG1Gc2RXVXVibTl5YldGc2FYcGxaRHRjYmx4dUlDQWdJSFJvYVhNdWRtRnNkV1VnUFNCMGFHbHpMbDkyWVd4MVpTNTJZV3gxWlR0Y2JseHVJQ0FnSUhSb2FYTXVaVzFwZENnblkyaGhibWRsSnl4MGFHbHpMblpoYkhWbEtUdGNibHh1SUNCOVhHNWNiaUFnWW5WcGJHUkpiblJsY21aaFkyVW9LU0I3WEc1Y2JpQWdJQ0IwYUdsekxtSmhjaUE5SUhOMlp5NWpjbVZoZEdVb0ozSmxZM1FuS1R0Y2JpQWdJQ0IwYUdsekxtWnBiR3hpWVhJZ1BTQnpkbWN1WTNKbFlYUmxLQ2R5WldOMEp5azdYRzRnSUNBZ2RHaHBjeTVyYm05aUlEMGdjM1puTG1OeVpXRjBaU2duWTJseVkyeGxKeWs3WEc1Y2JpQWdJQ0IwYUdsekxtVnNaVzFsYm5RdVlYQndaVzVrUTJocGJHUW9kR2hwY3k1aVlYSXBPMXh1SUNBZ0lIUm9hWE11Wld4bGJXVnVkQzVoY0hCbGJtUkRhR2xzWkNoMGFHbHpMbVpwYkd4aVlYSXBPMXh1SUNBZ0lIUm9hWE11Wld4bGJXVnVkQzVoY0hCbGJtUkRhR2xzWkNoMGFHbHpMbXR1YjJJcE8xeHVYRzRnSUNBZ2RHaHBjeTV6YVhwbFNXNTBaWEptWVdObEtDazdYRzVjYmx4dVhHNGdJSDFjYmx4dUlDQnphWHBsU1c1MFpYSm1ZV05sS0NrZ2UxeHVYRzVjYmlBZ0lDQnBaaUFvSVhSb2FYTXVjMlYwZEdsdVozTXViM0pwWlc1MFlYUnBiMjRwSUh0Y2JpQWdJQ0FnSUdsbUlDaDBhR2x6TG5kcFpIUm9JRHdnZEdocGN5NW9aV2xuYUhRcElIdGNiaUFnSUNBZ0lDQWdkR2hwY3k1dmNtbGxiblJoZEdsdmJpQTlJQ2QyWlhKMGFXTmhiQ2M3WEc0Z0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0IwYUdsekxtOXlhV1Z1ZEdGMGFXOXVJRDBnSjJodmNtbDZiMjUwWVd3bk8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUgxY2JseHVJQ0FnSUd4bGRDQjRMQ0I1TENCM0xDQm9MQ0JpWVhKUFptWnpaWFFzSUdOdmNtNWxjbEpoWkdsMWN6dGNiaUFnSUNCMGFHbHpMbXR1YjJKRVlYUmhJRDBnZTF4dUlDQWdJQ0FnYkdWMlpXdzZJREFzWEc0Z0lDQWdJQ0J5T2lBd1hHNGdJQ0FnZlR0Y2JseHVJQ0FnSUdsbUlDaDBhR2x6TG05eWFXVnVkR0YwYVc5dUlEMDlQU0FuZG1WeWRHbGpZV3duS1NCN1hHNGdJQ0FnSUNCMGFHbHpMblJvYVdOcmJtVnpjeUE5SUhSb2FYTXVkMmxrZEdnZ0x5QXlPMXh1SUNBZ0lGeDBlQ0E5SUhSb2FYTXVkMmxrZEdndk1qdGNiaUFnSUNCY2RIa2dQU0F3TzF4dUlDQWdJRngwZHlBOUlIUm9hWE11ZEdocFkydHVaWE56TzF4dUlDQWdJRngwYUNBOUlIUm9hWE11YUdWcFoyaDBPMXh1SUNBZ0lDQWdkR2hwY3k1cmJtOWlSR0YwWVM1eUlEMGdkR2hwY3k1MGFHbGphMjVsYzNNZ0tpQXdMamc3WEc0Z0lDQWdYSFIwYUdsekxtdHViMkpFWVhSaExteGxkbVZzSUQwZ2FDMTBhR2x6TG01dmNtMWhiR2w2WldRcWFEdGNiaUFnSUNBZ0lHSmhjazltWm5ObGRDQTlJQ2QwY21GdWMyeGhkR1VvSnl0MGFHbHpMblJvYVdOcmJtVnpjeW9vTFRFcEx6SXJKeXd3S1NjN1hHNGdJQ0FnSUNCamIzSnVaWEpTWVdScGRYTWdQU0IzTHpJN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJSFJvYVhNdWRHaHBZMnR1WlhOeklEMGdkR2hwY3k1b1pXbG5hSFFnTHlBeU8xeHVJQ0FnSUZ4MGVDQTlJREE3WEc0Z0lDQWdYSFI1SUQwZ2RHaHBjeTVvWldsbmFIUXZNanRjYmlBZ0lDQmNkSGNnUFNCMGFHbHpMbmRwWkhSb08xeHVJQ0FnSUZ4MGFDQTlJSFJvYVhNdWRHaHBZMnR1WlhOek8xeHVJQ0FnSUNBZ2RHaHBjeTVyYm05aVJHRjBZUzV5SUQwZ2RHaHBjeTUwYUdsamEyNWxjM01nS2lBd0xqZzdYRzRnSUNBZ1hIUjBhR2x6TG10dWIySkVZWFJoTG14bGRtVnNJRDBnZEdocGN5NXViM0p0WVd4cGVtVmtLbmM3WEc0Z0lDQWdJQ0JpWVhKUFptWnpaWFFnUFNBbmRISmhibk5zWVhSbEtEQXNKeXQwYUdsekxuUm9hV05yYm1WemN5b29MVEVwTHpJckp5a25PMXh1SUNBZ0lDQWdZMjl5Ym1WeVVtRmthWFZ6SUQwZ2FDOHlPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIUm9hWE11WW1GeUxuTmxkRUYwZEhKcFluVjBaU2duZUNjc2VDazdYRzRnSUNBZ2RHaHBjeTVpWVhJdWMyVjBRWFIwY21saWRYUmxLQ2Q1Snl4NUtUdGNiaUFnSUNCMGFHbHpMbUpoY2k1elpYUkJkSFJ5YVdKMWRHVW9KM1J5WVc1elptOXliU2NzWW1GeVQyWm1jMlYwS1R0Y2JpQWdJQ0IwYUdsekxtSmhjaTV6WlhSQmRIUnlhV0oxZEdVb0ozSjRKeXhqYjNKdVpYSlNZV1JwZFhNcE95QXZMeUJqYjNKdVpYSWdjbUZrYVhWelhHNGdJQ0FnZEdocGN5NWlZWEl1YzJWMFFYUjBjbWxpZFhSbEtDZHllU2NzWTI5eWJtVnlVbUZrYVhWektUdGNiaUFnSUNCMGFHbHpMbUpoY2k1elpYUkJkSFJ5YVdKMWRHVW9KM2RwWkhSb0p5eDNLVHRjYmlBZ0lDQjBhR2x6TG1KaGNpNXpaWFJCZEhSeWFXSjFkR1VvSjJobGFXZG9kQ2NzYUNrN1hHNWNiaUFnSUNCcFppQW9kR2hwY3k1dmNtbGxiblJoZEdsdmJpQTlQVDBnSjNabGNuUnBZMkZzSnlrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTVtYVd4c1ltRnlMbk5sZEVGMGRISnBZblYwWlNnbmVDY3NlQ2s3WEc0Z0lDQWdJQ0IwYUdsekxtWnBiR3hpWVhJdWMyVjBRWFIwY21saWRYUmxLQ2Q1Snl4MGFHbHpMbXR1YjJKRVlYUmhMbXhsZG1Wc0tUdGNiaUFnSUNBZ0lIUm9hWE11Wm1sc2JHSmhjaTV6WlhSQmRIUnlhV0oxZEdVb0ozZHBaSFJvSnl4M0tUdGNiaUFnSUNBZ0lIUm9hWE11Wm1sc2JHSmhjaTV6WlhSQmRIUnlhV0oxZEdVb0oyaGxhV2RvZENjc2FDMTBhR2x6TG10dWIySkVZWFJoTG14bGRtVnNLVHRjYmlBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ2RHaHBjeTVtYVd4c1ltRnlMbk5sZEVGMGRISnBZblYwWlNnbmVDY3NNQ2s3WEc0Z0lDQWdJQ0IwYUdsekxtWnBiR3hpWVhJdWMyVjBRWFIwY21saWRYUmxLQ2Q1Snl4NUtUdGNiaUFnSUNBZ0lIUm9hWE11Wm1sc2JHSmhjaTV6WlhSQmRIUnlhV0oxZEdVb0ozZHBaSFJvSnl4MGFHbHpMbXR1YjJKRVlYUmhMbXhsZG1Wc0tUdGNiaUFnSUNBZ0lIUm9hWE11Wm1sc2JHSmhjaTV6WlhSQmRIUnlhV0oxZEdVb0oyaGxhV2RvZENjc2FDazdYRzRnSUNBZ2ZWeHVJQ0FnSUhSb2FYTXVabWxzYkdKaGNpNXpaWFJCZEhSeWFXSjFkR1VvSjNSeVlXNXpabTl5YlNjc1ltRnlUMlptYzJWMEtUdGNiaUFnSUNCMGFHbHpMbVpwYkd4aVlYSXVjMlYwUVhSMGNtbGlkWFJsS0NkeWVDY3NZMjl5Ym1WeVVtRmthWFZ6S1R0Y2JpQWdJQ0IwYUdsekxtWnBiR3hpWVhJdWMyVjBRWFIwY21saWRYUmxLQ2R5ZVNjc1kyOXlibVZ5VW1Ga2FYVnpLVHRjYmx4dUlDQWdJR2xtSUNoMGFHbHpMbTl5YVdWdWRHRjBhVzl1SUQwOVBTQW5kbVZ5ZEdsallXd25LU0I3WEc0Z0lDQWdJQ0IwYUdsekxtdHViMkl1YzJWMFFYUjBjbWxpZFhSbEtDZGplQ2NzZUNrN1hHNGdJQ0FnSUNCMGFHbHpMbXR1YjJJdWMyVjBRWFIwY21saWRYUmxLQ2RqZVNjc2RHaHBjeTVyYm05aVJHRjBZUzVzWlhabGJDazdYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUhSb2FYTXVhMjV2WWk1elpYUkJkSFJ5YVdKMWRHVW9KMk40Snl4MGFHbHpMbXR1YjJKRVlYUmhMbXhsZG1Wc0tUdGNiaUFnSUNBZ0lIUm9hWE11YTI1dllpNXpaWFJCZEhSeWFXSjFkR1VvSjJONUp5eDVLVHRjYmlBZ0lDQjlYRzRnSUNBZ2RHaHBjeTVyYm05aUxuTmxkRUYwZEhKcFluVjBaU2duY2ljc2RHaHBjeTVyYm05aVJHRjBZUzV5S1R0Y2JseHVYRzRnSUNBZ2FXWWdLSFJvYVhNdWNHOXphWFJwYjI0cElIdGNiaUFnSUNBZ0lIUm9hWE11Y0c5emFYUnBiMjR1Y21WemFYcGxLRnN3TEhSb2FYTXVkMmxrZEdoZExGdDBhR2x6TG1obGFXZG9kQ3d3WFNrN1hHNGdJQ0FnZlZ4dVhHNGdJSDFjYmx4dUlDQmpiMnh2Y2tsdWRHVnlabUZqWlNncElIdGNibHh1SUNBZ0lIUm9hWE11WW1GeUxuTmxkRUYwZEhKcFluVjBaU2duWm1sc2JDY3NJSFJvYVhNdVkyOXNiM0p6TG1acGJHd3BPMXh1SUNBZ0lIUm9hWE11Wm1sc2JHSmhjaTV6WlhSQmRIUnlhV0oxZEdVb0oyWnBiR3duTENCMGFHbHpMbU52Ykc5eWN5NWhZMk5sYm5RcE8xeHVJQ0FnSUhSb2FYTXVhMjV2WWk1elpYUkJkSFJ5YVdKMWRHVW9KMlpwYkd3bkxDQjBhR2x6TG1OdmJHOXljeTVoWTJObGJuUXBPMXh1SUNBZ0lHbG1JQ2doZEdocGN5NW9ZWE5MYm05aUtTQjdYRzRnSUNBZ0lDQjBhR2x6TG10dWIySXVjMlYwUVhSMGNtbGlkWFJsS0NkbWFXeHNKeXduYm05dVpTY3BPMXh1SUNBZ0lIMWNibHh1SUNCOVhHNWNiaUFnY21WdVpHVnlLQ2tnZTF4dUlDQWdJR2xtSUNnaGRHaHBjeTVqYkdsamEyVmtLU0I3WEc0Z0lDQWdJQ0IwYUdsekxtdHViMkpFWVhSaExuSWdQU0IwYUdsekxuUm9hV05yYm1WemN5b3dMamMxTzF4dUlDQWdJSDFjYmlBZ0lDQjBhR2x6TG10dWIySXVjMlYwUVhSMGNtbGlkWFJsS0NkeUp5eDBhR2x6TG10dWIySkVZWFJoTG5JcE8xeHVYRzRnSUNBZ2FXWWdLSFJvYVhNdWIzSnBaVzUwWVhScGIyNGdQVDA5SUNkMlpYSjBhV05oYkNjcElIdGNiaUFnSUNBZ0lDQjBhR2x6TG10dWIySkVZWFJoTG14bGRtVnNJRDBnZEdocGN5NWZkbUZzZFdVdWJtOXliV0ZzYVhwbFpDcDBhR2x6TG1obGFXZG9kRHRjYmlBZ0lDQWdJQ0IwYUdsekxtdHViMkl1YzJWMFFYUjBjbWxpZFhSbEtDZGplU2NzZEdocGN5NW9aV2xuYUhRZ0xTQjBhR2x6TG10dWIySkVZWFJoTG14bGRtVnNLVHRjYmlBZ0lDQWdJQ0IwYUdsekxtWnBiR3hpWVhJdWMyVjBRWFIwY21saWRYUmxLQ2Q1Snl4MGFHbHpMbWhsYVdkb2RDQXRJSFJvYVhNdWEyNXZZa1JoZEdFdWJHVjJaV3dwTzF4dUlDQWdJQ0FnSUhSb2FYTXVabWxzYkdKaGNpNXpaWFJCZEhSeWFXSjFkR1VvSjJobGFXZG9kQ2NzZEdocGN5NXJibTlpUkdGMFlTNXNaWFpsYkNrN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0IwYUdsekxtdHViMkpFWVhSaExteGxkbVZzSUQwZ2RHaHBjeTVmZG1Gc2RXVXVibTl5YldGc2FYcGxaQ3AwYUdsekxuZHBaSFJvTzF4dUlDQWdJQ0FnSUhSb2FYTXVhMjV2WWk1elpYUkJkSFJ5YVdKMWRHVW9KMk40Snl4MGFHbHpMbXR1YjJKRVlYUmhMbXhsZG1Wc0tUdGNiaUFnSUNBZ0lDQjBhR2x6TG1acGJHeGlZWEl1YzJWMFFYUjBjbWxpZFhSbEtDZDRKeXd3S1R0Y2JpQWdJQ0FnSUNCMGFHbHpMbVpwYkd4aVlYSXVjMlYwUVhSMGNtbGlkWFJsS0NkM2FXUjBhQ2NzZEdocGN5NXJibTlpUkdGMFlTNXNaWFpsYkNrN1hHNGdJQ0FnZlZ4dUlDQjlYRzVjYmlBZ1pHOTNiaWdwSUh0Y2JpQWdJQ0IwYUdsekxtTnNhV05yWldRZ1BTQjBjblZsTzF4dUlDQWdJSFJvYVhNdWEyNXZZa1JoZEdFdWNpQTlJSFJvYVhNdWRHaHBZMnR1WlhOektqQXVPVHRjYmlBZ0lDQjBhR2x6TG5CdmMybDBhVzl1TG1GdVkyaHZjaUE5SUhSb2FYTXViVzkxYzJVN1hHNGdJQ0FnZEdocGN5NXpiR2xrWlNncE8xeHVJQ0I5WEc1Y2JpQWdjMnhwWkdVb0tTQjdYRzRnSUNBZ2FXWWdLSFJvYVhNdVkyeHBZMnRsWkNrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTV3YjNOcGRHbHZiaTUxY0dSaGRHVW9kR2hwY3k1dGIzVnpaU2s3WEc0Z0lDQWdJQ0IwYUdsekxuWmhiSFZsSUQwZ2RHaHBjeTVmZG1Gc2RXVXVkWEJrWVhSbFRtOXliV0ZzS0NCMGFHbHpMbkJ2YzJsMGFXOXVMblpoYkhWbElDazdYRzRnSUNBZ0lDQjBhR2x6TG1WdGFYUW9KMk5vWVc1blpTY3NkR2hwY3k1MllXeDFaU2s3WEc0Z0lDQWdmVnh1SUNCOVhHNWNiaUFnZFhBb0tTQjdYRzRnSUNBZ2RHaHBjeTVqYkdsamEyVmtJRDBnWm1Gc2MyVTdYRzRnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmlBZ2ZWeHVYRzRnSUdkbGRDQnViM0p0WVd4cGVtVmtLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TGw5MllXeDFaUzV1YjNKdFlXeHBlbVZrTzF4dUlDQjlYRzVjYmlBZ0x5b3FYRzRnSUZSb1pTQnpiR2xrWlhJbmN5QmpkWEp5Wlc1MElIWmhiSFZsTGlCSlppQnpaWFFnYldGdWRXRnNiSGtzSUhkcGJHd2dkWEJrWVhSbElIUm9aU0JwYm5SbGNtWmhZMlVnWVc1a0lIUnlhV2RuWlhJZ2RHaGxJRzkxZEhCMWRDQmxkbVZ1ZEM1Y2JpQWdRSFI1Y0dVZ2UyNTFiV0psY24xY2JpQWdRR1Y0WVcxd2JHVWdjMnhwWkdWeUxuWmhiSFZsSUQwZ01UQTdYRzRnSUNvdlhHNGdJR2RsZENCMllXeDFaU2dwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1ZmRtRnNkV1V1ZG1Gc2RXVTdYRzRnSUgxY2JpQWdjMlYwSUhaaGJIVmxLSFlwSUh0Y2JpQWdJQ0IwYUdsekxsOTJZV3gxWlM1MWNHUmhkR1VvZGlrN1hHNGdJQ0FnZEdocGN5NXdiM05wZEdsdmJpNTJZV3gxWlNBOUlIUm9hWE11WDNaaGJIVmxMbTV2Y20xaGJHbDZaV1E3WEc0Z0lDQWdkR2hwY3k1eVpXNWtaWElvS1R0Y2JpQWdmVnh1WEc0Z0lDOHFLbHh1SUNCTWIzZGxjaUJzYVcxcGRDQnZaaUIwYUdVZ2MyeHBaR1Z5Y3lkeklHOTFkSEIxZENCeVlXNW5aVnh1SUNCQWRIbHdaU0I3Ym5WdFltVnlmVnh1SUNCQVpYaGhiWEJzWlNCemJHbGtaWEl1YldsdUlEMGdNVEF3TUR0Y2JpQWdLaTljYmlBZ1oyVjBJRzFwYmlncElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWZkbUZzZFdVdWJXbHVPMXh1SUNCOVhHNGdJSE5sZENCdGFXNG9kaWtnZTF4dUlDQWdJSFJvYVhNdVgzWmhiSFZsTG0xcGJpQTlJSFk3WEc0Z0lIMWNibHh1SUNBdktpcGNiaUFnVlhCd1pYSWdiR2x0YVhRZ2IyWWdkR2hsSUhOc2FXUmxjaWR6SUc5MWRIQjFkQ0J5WVc1blpWeHVJQ0JBZEhsd1pTQjdiblZ0WW1WeWZWeHVJQ0JBWlhoaGJYQnNaU0J6Ykdsa1pYSXViV0Y0SUQwZ01UQXdNRHRjYmlBZ0tpOWNiaUFnWjJWMElHMWhlQ2dwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1ZmRtRnNkV1V1YldGNE8xeHVJQ0I5WEc0Z0lITmxkQ0J0WVhnb2Rpa2dlMXh1SUNBZ0lIUm9hWE11WDNaaGJIVmxMbTFoZUNBOUlIWTdYRzRnSUgxY2JseHVJQ0F2S2lwY2JpQWdWR2hsSUdsdVkzSmxiV1Z1ZENCMGFHRjBJSFJvWlNCemJHbGtaWEluY3lCMllXeDFaU0JqYUdGdVoyVnpJR0o1TGx4dUlDQkFkSGx3WlNCN2JuVnRZbVZ5ZlZ4dUlDQkFaWGhoYlhCc1pTQnpiR2xrWlhJdWMzUmxjQ0E5SURVN1hHNGdJQ292WEc0Z0lHZGxkQ0J6ZEdWd0tDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbDkyWVd4MVpTNXpkR1Z3TzF4dUlDQjlYRzRnSUhObGRDQnpkR1Z3S0hZcElIdGNiaUFnSUNCMGFHbHpMbDkyWVd4MVpTNXpkR1Z3SUQwZ2RqdGNiaUFnZlZ4dVhHNGdJQzhxS2x4dUlDQkJZbk52YkhWMFpTQnRiMlJsSUNoemJHbGtaWEluY3lCMllXeDFaU0JxZFcxd2N5QjBieUJ0YjNWelpTQmpiR2xqYXlCd2IzTnBkR2x2YmlrZ2IzSWdjbVZzWVhScGRtVWdiVzlrWlNBb2JXOTFjMlVnWkhKaFp5QmphR0Z1WjJWeklIWmhiSFZsSUhKbGJHRjBhWFpsSUhSdklHbDBjeUJqZFhKeVpXNTBJSEJ2YzJsMGFXOXVLUzRnUkdWbVlYVnNkRG9nWENKeVpXeGhkR2wyWlZ3aUxseHVJQ0JBZEhsd1pTQjdjM1J5YVc1bmZWeHVJQ0JBWlhoaGJYQnNaU0J6Ykdsa1pYSXViVzlrWlNBOUlGd2ljbVZzWVhScGRtVmNJanRjYmlBZ0tpOWNiaUFnWjJWMElHMXZaR1VvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWNHOXphWFJwYjI0dWJXOWtaVHRjYmlBZ2ZWeHVJQ0J6WlhRZ2JXOWtaU2gyS1NCN1hHNGdJQ0FnZEdocGN5NXdiM05wZEdsdmJpNXRiMlJsSUQwZ2RqdGNiaUFnZlZ4dVhHNWNibjFjYmx4dVhHNWNiaTh2SUZkRlFsQkJRMHNnUms5UFZFVlNJQzh2WEc0dkx5QXVMMzR2YW5Ob2FXNTBMV3h2WVdSbGNpRXVMMnhwWWk5amIyMXdiMjVsYm5SekwzTnNhV1JsY25SbGJYQnNZWFJsTG1weklpd2lKM1Z6WlNCemRISnBZM1FuTzF4dVhHNXNaWFFnYzNabklEMGdjbVZ4ZFdseVpTZ25MaTR2ZFhScGJDOXpkbWNuS1R0Y2JteGxkQ0J0WVhSb0lEMGdjbVZ4ZFdseVpTZ25MaTR2ZFhScGJDOXRZWFJvSnlrN1hHNXNaWFFnU1c1MFpYSm1ZV05sSUQwZ2NtVnhkV2x5WlNnbkxpNHZZMjl5WlM5cGJuUmxjbVpoWTJVbktUdGNibXhsZENCVGRHVndJRDBnY21WeGRXbHlaU2duTGk0dmJXOWtaV3h6TDNOMFpYQW5LVHRjYm1sdGNHOXlkQ0FxSUdGeklFbHVkR1Z5WVdOMGFXOXVJR1p5YjIwZ0p5NHVMM1YwYVd3dmFXNTBaWEpoWTNScGIyNG5PMXh1WEc0dktpcGNiaW9nVUdGdVhHNHFYRzRxSUVCa1pYTmpjbWx3ZEdsdmJpQlRkR1Z5Wlc4Z1kzSnZjM05tWVdSbGNpNWNiaXBjYmlvZ1FHUmxiVzhnUEhOd1lXNGdibVY0ZFhNdGRXazlYQ0p3WVc1Y0lqNDhMM053WVc0K1hHNHFYRzRxSUVCbGVHRnRjR3hsWEc0cUlIWmhjaUJ3WVc0Z1BTQnVaWGNnVG1WNGRYTXVVR0Z1S0NjamRHRnlaMlYwSnlsY2JpcGNiaW9nUUc5MWRIQjFkRnh1S2lCamFHRnVaMlZjYmlvZ1JtbHlaWE1nWVc1NUlIUnBiV1VnZEdobElHbHVkR1Z5Wm1GalpTZHpJSFpoYkhWbElHTm9ZVzVuWlhNdUlEeGljajVjYmlvZ1ZHaGxJR1YyWlc1MElHUmhkR0VnYVhNZ1lXNGdiMkpxWldOMElHTnZiblJoYVc1cGJtY2dkR2hsSUdsdWRHVnlabUZqWlNkeklEeHBQblpoYkhWbFBDOXBQaUFvTFRFZ2RHOGdNU2tzSUdGeklIZGxiR3dnWVhNZ1BHaytURHd2YVQ0Z1lXNWtJRHhwUGxJOEwyaytJR0Z0Y0d4cGRIVmtaU0IyWVd4MVpYTWdLREF0TVNrZ1ptOXlJR3hsWm5RZ1lXNWtJSEpwWjJoMElITndaV0ZyWlhKekxDQmpZV3hqZFd4aGRHVmtJR0o1SUdFZ2MzRjFZWEpsTFhKdmIzUWdZM0p2YzNObVlXUmxJR0ZzWjI5eWFYUm9iUzVjYmlwY2Jpb2dRRzkxZEhCMWRHVjRZVzF3YkdWY2Jpb2djR0Z1TG05dUtDZGphR0Z1WjJVbkxHWjFibU4wYVc5dUtIWXBJSHRjYmlvZ0lDQmpiMjV6YjJ4bExteHZaeWgyS1R0Y2Jpb2dmU2xjYmlwY2JpcGNiaW92WEc1Y2JtVjRjRzl5ZENCa1pXWmhkV3gwSUdOc1lYTnpJRkJoYmlCbGVIUmxibVJ6SUVsdWRHVnlabUZqWlNCN1hHNWNiaUFnWTI5dWMzUnlkV04wYjNJb0tTQjdYRzVjYmlBZ0lDQnNaWFFnYjNCMGFXOXVjeUE5SUZzbmMyTmhiR1VuTENkMllXeDFaU2RkTzF4dVhHNGdJQ0FnYkdWMElHUmxabUYxYkhSeklEMGdlMXh1SUNBZ0lDQWdKM05wZW1Vbk9pQmJNVEl3TERJd1hTeGNiaUFnSUNBZ0lDZHZjbWxsYm5SaGRHbHZiaWM2SUNkb2IzSnBlbTl1ZEdGc0p5eGNiaUFnSUNBZ0lDZHRiMlJsSnpvZ0ozSmxiR0YwYVhabEp5eGNiaUFnSUNBZ0lDZHpZMkZzWlNjNklGc3RNU3d4WFN4Y2JpQWdJQ0FnSUNkemRHVndKem9nTUN4Y2JpQWdJQ0FnSUNkMllXeDFaU2M2SURBc1hHNGdJQ0FnSUNBbmFHRnpTMjV2WWljNklIUnlkV1ZjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdjM1Z3WlhJb1lYSm5kVzFsYm5SekxHOXdkR2x2Ym5Nc1pHVm1ZWFZzZEhNcE8xeHVYRzRnSUNBZ2RHaHBjeTV2Y21sbGJuUmhkR2x2YmlBOUlIUm9hWE11YzJWMGRHbHVaM011YjNKcFpXNTBZWFJwYjI0N1hHNWNiaUFnSUNCMGFHbHpMbTF2WkdVZ1BTQjBhR2x6TG5ObGRIUnBibWR6TG0xdlpHVTdYRzVjYmlBZ0lDQjBhR2x6TG1oaGMwdHViMklnUFNCMGFHbHpMbk5sZEhScGJtZHpMbWhoYzB0dWIySTdYRzVjYmlBZ0lDQXZMeUIwYUdsekxuTjBaWEFnYzJodmRXeGtJR1YyWlc1MGRXRnNiSGtnWW1VZ1oyVjBMM05sZEZ4dUlDQWdJQzh2SUhWd1pHRjBhVzVuSUdsMElIZHBiR3dnZFhCa1lYUmxJSFJvWlNCZmRtRnNkV1VnYzNSbGNDQnRiMlJsYkZ4dUlDQWdJSFJvYVhNdWMzUmxjQ0E5SUhSb2FYTXVjMlYwZEdsdVozTXVjM1JsY0RzZ0x5OGdabXh2WVhSY2JseHVJQ0FnSUhSb2FYTXVYM1poYkhWbElEMGdibVYzSUZOMFpYQW9kR2hwY3k1elpYUjBhVzVuY3k1elkyRnNaVnN3WFN3Z2RHaHBjeTV6WlhSMGFXNW5jeTV6WTJGc1pWc3hYU3dnZEdocGN5NXpaWFIwYVc1bmN5NXpkR1Z3TENCMGFHbHpMbk5sZEhScGJtZHpMblpoYkhWbEtUdGNibHh1SUNBZ0lIUm9hWE11YVc1cGRDZ3BPMXh1WEc0Z0lDQWdkR2hwY3k1d2IzTnBkR2x2YmlBOUlHNWxkeUJKYm5SbGNtRmpkR2x2Ymk1SVlXNWtiR1VvZEdocGN5NXRiMlJsTEhSb2FYTXViM0pwWlc1MFlYUnBiMjRzV3pBc2RHaHBjeTUzYVdSMGFGMHNXM1JvYVhNdWFHVnBaMmgwTERCZEtUdGNiaUFnSUNCMGFHbHpMbkJ2YzJsMGFXOXVMblpoYkhWbElEMGdkR2hwY3k1ZmRtRnNkV1V1Ym05eWJXRnNhWHBsWkR0Y2JseHVJQ0FnSUhSb2FYTXVkbUZzZFdVZ1BTQjBhR2x6TGw5MllXeDFaUzUyWVd4MVpUdGNibHh1SUNBZ0lIUm9hWE11WlcxcGRDZ25ZMmhoYm1kbEp5eDBhR2x6TG5aaGJIVmxLVHRjYmx4dUlDQjlYRzVjYmlBZ1luVnBiR1JKYm5SbGNtWmhZMlVvS1NCN1hHNWNiaUFnSUNCMGFHbHpMbUpoY2lBOUlITjJaeTVqY21WaGRHVW9KM0psWTNRbktUdGNiaUFnSUNCMGFHbHpMbXR1YjJJZ1BTQnpkbWN1WTNKbFlYUmxLQ2RqYVhKamJHVW5LVHRjYmx4dUlDQWdJSFJvYVhNdVpXeGxiV1Z1ZEM1aGNIQmxibVJEYUdsc1pDaDBhR2x6TG1KaGNpazdYRzRnSUNBZ2RHaHBjeTVsYkdWdFpXNTBMbUZ3Y0dWdVpFTm9hV3hrS0hSb2FYTXVhMjV2WWlrN1hHNWNiaUFnZlZ4dVhHNGdJSE5wZW1WSmJuUmxjbVpoWTJVb0tTQjdYRzVjYmlBZ0lDQnBaaUFvZEdocGN5NXdiM05wZEdsdmJpa2dlMXh1SUNBZ0lDQWdkR2hwY3k1d2IzTnBkR2x2Ymk1eVpYTnBlbVVvV3pBc2RHaHBjeTUzYVdSMGFGMHNXM1JvYVhNdWFHVnBaMmgwTERCZEtUdGNiaUFnSUNCOVhHNWNiaUFnSUNCcFppQW9kR2hwY3k1M2FXUjBhQ0E4SUhSb2FYTXVhR1ZwWjJoMEtTQjdYRzRnSUNBZ0lDQjBhR2x6TG05eWFXVnVkR0YwYVc5dUlEMGdKM1psY25ScFkyRnNKenRjYmlBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ2RHaHBjeTV2Y21sbGJuUmhkR2x2YmlBOUlDZG9iM0pwZW05dWRHRnNKenRjYmlBZ0lDQjlYRzVjYmlBZ0lDQnNaWFFnZUN3Z2VTd2dkeXdnYUN3Z1ltRnlUMlptYzJWMExDQmpiM0p1WlhKU1lXUnBkWE03WEc0Z0lDQWdkR2hwY3k1cmJtOWlSR0YwWVNBOUlIdGNiaUFnSUNBZ0lHeGxkbVZzT2lBd0xGeHVJQ0FnSUNBZ2Nqb2dNRnh1SUNBZ0lIMDdYRzVjYmlBZ0lDQnBaaUFvZEdocGN5NXZjbWxsYm5SaGRHbHZiaUE5UFQwZ0ozWmxjblJwWTJGc0p5a2dlMXh1SUNBZ0lDQWdkR2hwY3k1MGFHbGphMjVsYzNNZ1BTQjBhR2x6TG5kcFpIUm9JQzhnTWp0Y2JpQWdJQ0JjZEhnZ1BTQjBhR2x6TG5kcFpIUm9Mekk3WEc0Z0lDQWdYSFI1SUQwZ01EdGNiaUFnSUNCY2RIY2dQU0IwYUdsekxuUm9hV05yYm1WemN6dGNiaUFnSUNCY2RHZ2dQU0IwYUdsekxtaGxhV2RvZER0Y2JpQWdJQ0FnSUhSb2FYTXVhMjV2WWtSaGRHRXVjaUE5SUhSb2FYTXVkR2hwWTJ0dVpYTnpJQ29nTUM0NE8xeHVJQ0FnSUZ4MGRHaHBjeTVyYm05aVJHRjBZUzVzWlhabGJDQTlJR2d0ZEdocGN5NXJibTlpUkdGMFlTNXlMWFJvYVhNdWJtOXliV0ZzYVhwbFpDb29hQzEwYUdsekxtdHViMkpFWVhSaExuSXFNaWs3WEc0Z0lDQWdJQ0JpWVhKUFptWnpaWFFnUFNBbmRISmhibk5zWVhSbEtDY3JkR2hwY3k1MGFHbGphMjVsYzNNcUtDMHhLUzh5S3ljc01Da25PMXh1SUNBZ0lDQWdZMjl5Ym1WeVVtRmthWFZ6SUQwZ2R5OHlPMXh1SUNBZ0lIMGdaV3h6WlNCN1hHNGdJQ0FnSUNCMGFHbHpMblJvYVdOcmJtVnpjeUE5SUhSb2FYTXVhR1ZwWjJoMElDOGdNanRjYmlBZ0lDQmNkSGdnUFNBd08xeHVJQ0FnSUZ4MGVTQTlJSFJvYVhNdWFHVnBaMmgwTHpJN1hHNGdJQ0FnWEhSM0lEMGdkR2hwY3k1M2FXUjBhRHRjYmlBZ0lDQmNkR2dnUFNCMGFHbHpMblJvYVdOcmJtVnpjenRjYmlBZ0lDQWdJSFJvYVhNdWEyNXZZa1JoZEdFdWNpQTlJSFJvYVhNdWRHaHBZMnR1WlhOeklDb2dNQzQ0TzF4dUlDQWdJRngwZEdocGN5NXJibTlpUkdGMFlTNXNaWFpsYkNBOUlIUm9hWE11Ym05eWJXRnNhWHBsWkNvb2R5MTBhR2x6TG10dWIySkVZWFJoTG5JcU1pa3JkR2hwY3k1cmJtOWlSR0YwWVM1eU8xeHVJQ0FnSUNBZ1ltRnlUMlptYzJWMElEMGdKM1J5WVc1emJHRjBaU2d3TENjcmRHaHBjeTUwYUdsamEyNWxjM01xS0MweEtTOHlLeWNwSnp0Y2JpQWdJQ0FnSUdOdmNtNWxjbEpoWkdsMWN5QTlJR2d2TWp0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0IwYUdsekxtSmhjaTV6WlhSQmRIUnlhV0oxZEdVb0ozZ25MSGdwTzF4dUlDQWdJSFJvYVhNdVltRnlMbk5sZEVGMGRISnBZblYwWlNnbmVTY3NlU2s3WEc0Z0lDQWdkR2hwY3k1aVlYSXVjMlYwUVhSMGNtbGlkWFJsS0NkMGNtRnVjMlp2Y20wbkxHSmhjazltWm5ObGRDazdYRzRnSUNBZ2RHaHBjeTVpWVhJdWMyVjBRWFIwY21saWRYUmxLQ2R5ZUNjc1kyOXlibVZ5VW1Ga2FYVnpLVHNnTHk4Z1kyOXlibVZ5SUhKaFpHbDFjMXh1SUNBZ0lIUm9hWE11WW1GeUxuTmxkRUYwZEhKcFluVjBaU2duY25rbkxHTnZjbTVsY2xKaFpHbDFjeWs3WEc0Z0lDQWdkR2hwY3k1aVlYSXVjMlYwUVhSMGNtbGlkWFJsS0NkM2FXUjBhQ2NzZHlrN1hHNGdJQ0FnZEdocGN5NWlZWEl1YzJWMFFYUjBjbWxpZFhSbEtDZG9aV2xuYUhRbkxHZ3BPMXh1WEc0Z0lDQWdhV1lnS0hSb2FYTXViM0pwWlc1MFlYUnBiMjRnUFQwOUlDZDJaWEowYVdOaGJDY3BJSHRjYmlBZ0lDQWdJSFJvYVhNdWEyNXZZaTV6WlhSQmRIUnlhV0oxZEdVb0oyTjRKeXg0S1R0Y2JpQWdJQ0FnSUhSb2FYTXVhMjV2WWk1elpYUkJkSFJ5YVdKMWRHVW9KMk41Snl4MGFHbHpMbXR1YjJKRVlYUmhMbXhsZG1Wc0tUdGNiaUFnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnZEdocGN5NXJibTlpTG5ObGRFRjBkSEpwWW5WMFpTZ25ZM2duTEhSb2FYTXVhMjV2WWtSaGRHRXViR1YyWld3cE8xeHVJQ0FnSUNBZ2RHaHBjeTVyYm05aUxuTmxkRUYwZEhKcFluVjBaU2duWTNrbkxIa3BPMXh1SUNBZ0lIMWNiaUFnSUNCMGFHbHpMbXR1YjJJdWMyVjBRWFIwY21saWRYUmxLQ2R5Snl4MGFHbHpMbXR1YjJKRVlYUmhMbklwTzF4dVhHNGdJSDFjYmx4dUlDQmpiMnh2Y2tsdWRHVnlabUZqWlNncElIdGNibHh1SUNBZ0lIUm9hWE11WW1GeUxuTmxkRUYwZEhKcFluVjBaU2duWm1sc2JDY3NJSFJvYVhNdVkyOXNiM0p6TG1acGJHd3BPMXh1SUNBZ0lIUm9hWE11YTI1dllpNXpaWFJCZEhSeWFXSjFkR1VvSjJacGJHd25MQ0IwYUdsekxtTnZiRzl5Y3k1aFkyTmxiblFwTzF4dVhHNGdJQ0FnYVdZZ0tDRjBhR2x6TG1oaGMwdHViMklwSUh0Y2JpQWdJQ0FnSUhSb2FYTXVhMjV2WWk1elpYUkJkSFJ5YVdKMWRHVW9KMlpwYkd3bkxDZDBjbUZ1YzNCaGNtVnVkQ2NwTzF4dUlDQWdJSDFjYmx4dUlDQjlYRzVjYmlBZ2NtVnVaR1Z5S0NrZ2UxeHVJQ0FnSUdsbUlDZ2hkR2hwY3k1amJHbGphMlZrS1NCN1hHNGdJQ0FnSUNCMGFHbHpMbXR1YjJKRVlYUmhMbklnUFNCMGFHbHpMblJvYVdOcmJtVnpjeW93TGpjMU8xeHVJQ0FnSUgxY2JpQWdJQ0IwYUdsekxtdHViMkl1YzJWMFFYUjBjbWxpZFhSbEtDZHlKeXgwYUdsekxtdHViMkpFWVhSaExuSXBPMXh1WEc0Z0lDQWdhV1lnS0hSb2FYTXViM0pwWlc1MFlYUnBiMjRnUFQwOUlDZDJaWEowYVdOaGJDY3BJSHRjYmlBZ1hIUWdJQ0IwYUdsekxtdHViMkpFWVhSaExteGxkbVZzSUQwZ2RHaHBjeTVyYm05aVJHRjBZUzV5SzNSb2FYTXVYM1poYkhWbExtNXZjbTFoYkdsNlpXUXFLSFJvYVhNdWFHVnBaMmgwTFhSb2FYTXVhMjV2WWtSaGRHRXVjaW95S1R0Y2JpQWdJQ0FnSUNCMGFHbHpMbXR1YjJJdWMyVjBRWFIwY21saWRYUmxLQ2RqZVNjc2RHaHBjeTVvWldsbmFIUWdMU0IwYUdsekxtdHViMkpFWVhSaExteGxkbVZzS1R0Y2JpQWdJQ0I5SUdWc2MyVWdlMXh1SUNCY2RDQWdJSFJvYVhNdWEyNXZZa1JoZEdFdWJHVjJaV3dnUFNCMGFHbHpMbDkyWVd4MVpTNXViM0p0WVd4cGVtVmtLaWgwYUdsekxuZHBaSFJvTFhSb2FYTXVhMjV2WWtSaGRHRXVjaW95S1N0MGFHbHpMbXR1YjJKRVlYUmhMbkk3WEc0Z0lDQWdJQ0FnZEdocGN5NXJibTlpTG5ObGRFRjBkSEpwWW5WMFpTZ25ZM2duTEhSb2FYTXVhMjV2WWtSaGRHRXViR1YyWld3cE8xeHVJQ0FnSUgxY2JpQWdmVnh1WEc1Y2JpQWdZMnhwWTJzb0tTQjdYRzRnSUNBZ2RHaHBjeTVyYm05aVJHRjBZUzV5SUQwZ2RHaHBjeTUwYUdsamEyNWxjM01xTUM0NU8xeHVJQ0FnSUhSb2FYTXVjRzl6YVhScGIyNHVZVzVqYUc5eUlEMGdkR2hwY3k1dGIzVnpaVHRjYmlBZ0lDQjBhR2x6TG0xdmRtVW9LVHRjYmlBZ2ZWeHVYRzRnSUcxdmRtVW9LU0I3WEc0Z0lDQWdhV1lnS0hSb2FYTXVZMnhwWTJ0bFpDa2dlMXh1SUNBZ0lDQWdkR2hwY3k1d2IzTnBkR2x2Ymk1MWNHUmhkR1VvZEdocGN5NXRiM1Z6WlNrN1hHNWNiaUFnSUNBZ0lIUm9hWE11ZG1Gc2RXVWdQU0IwYUdsekxsOTJZV3gxWlM1MWNHUmhkR1ZPYjNKdFlXd29JSFJvYVhNdWNHOXphWFJwYjI0dWRtRnNkV1VnS1R0Y2JseHVJQ0FnSUNBZ2RHaHBjeTVsYldsMEtDZGphR0Z1WjJVbkxIdGNiaUFnSUNBZ0lDQWdkbUZzZFdVNklIUm9hWE11ZG1Gc2RXVXNYRzRnSUNBZ0lDQWdJRXc2SUUxaGRHZ3VjRzkzS0NCdFlYUm9Mbk5qWVd4bEtIUm9hWE11ZG1Gc2RXVXNMVEVzTVN3eExEQXBMQ0F5S1N4Y2JpQWdJQ0FnSUNBZ1Vqb2dUV0YwYUM1d2IzY29JRzFoZEdndWMyTmhiR1VvZEdocGN5NTJZV3gxWlN3dE1Td3hMREFzTVNrc0lESXBYRzRnSUNBZ0lDQjlLVHRjYmx4dUlDQWdJSDFjYmlBZ2ZWeHVYRzRnSUhKbGJHVmhjMlVvS1NCN1hHNGdJQ0FnZEdocGN5NXlaVzVrWlhJb0tUdGNiaUFnZlZ4dVhHNGdJQzhxS2x4dUlDQlVhR1VnY0c5emFYUnBiMjRnYjJZZ1kzSnZjM05tWVdSbGNpd2dabkp2YlNBdE1TQW9iR1ZtZENrZ2RHOGdNU0FvY21sbmFIUXBMaUJUWlhSMGFXNW5JSFJvYVhNZ2RtRnNkV1VnZFhCa1lYUmxjeUIwYUdVZ2FXNTBaWEptWVdObElHRnVaQ0IwY21sbloyVnljeUIwYUdVZ2IzVjBjSFYwSUdWMlpXNTBMbHh1SUNCQWRIbHdaU0I3Ym5WdFltVnlmVnh1SUNBcUwxeHVJQ0JuWlhRZ2RtRnNkV1VvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdVgzWmhiSFZsTG5aaGJIVmxPMXh1SUNCOVhHNWNiaUFnYzJWMElIWmhiSFZsS0haaGJIVmxLU0I3WEc0Z0lDQWdkR2hwY3k1ZmRtRnNkV1V1ZFhCa1lYUmxLSFpoYkhWbEtUdGNiaUFnSUNCMGFHbHpMbkJ2YzJsMGFXOXVMblpoYkhWbElEMGdkR2hwY3k1ZmRtRnNkV1V1Ym05eWJXRnNhWHBsWkR0Y2JpQWdJQ0IwYUdsekxtVnRhWFFvSjJOb1lXNW5aU2NzZTF4dUlDQWdJQ0FnZG1Gc2RXVTZJSFJvYVhNdWRtRnNkV1VzWEc0Z0lDQWdJQ0JNT2lCTllYUm9MbkJ2ZHlnZ2JXRjBhQzV6WTJGc1pTaDBhR2x6TG5aaGJIVmxMQzB4TERFc01Td3dLU3dnTWlrc1hHNGdJQ0FnSUNCU09pQk5ZWFJvTG5CdmR5Z2diV0YwYUM1elkyRnNaU2gwYUdsekxuWmhiSFZsTEMweExERXNNQ3d4S1N3Z01pbGNiaUFnSUNCOUtUdGNiaUFnSUNCMGFHbHpMbkpsYm1SbGNpZ3BPMXh1SUNCOVhHNWNiaUFnWjJWMElHNXZjbTFoYkdsNlpXUW9LU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11WDNaaGJIVmxMbTV2Y20xaGJHbDZaV1E3WEc0Z0lIMWNibHh1ZlZ4dVhHNWNibHh1THk4Z1YwVkNVRUZEU3lCR1QwOVVSVklnTHk5Y2JpOHZJQzR2Zmk5cWMyaHBiblF0Ykc5aFpHVnlJUzR2YkdsaUwybHVkR1Z5Wm1GalpYTXZjR0Z1TG1weklpd2lKM1Z6WlNCemRISnBZM1FuTzF4dVhHNXNaWFFnYldGMGFDQTlJSEpsY1hWcGNtVW9KeTR1TDNWMGFXd3ZiV0YwYUNjcE8xeHViR1YwSUhOMlp5QTlJSEpsY1hWcGNtVW9KeTR1TDNWMGFXd3ZjM1puSnlrN1hHNXNaWFFnU1c1MFpYSm1ZV05sSUQwZ2NtVnhkV2x5WlNnbkxpNHZZMjl5WlM5cGJuUmxjbVpoWTJVbktUdGNibHh1WEc1c1pYUWdVRzlwYm5RZ1BTQm1kVzVqZEdsdmJpaHdiMmx1ZEN4bGJuWmxiRzl3WlNrZ2UxeHVYRzRnSUhSb2FYTXVlQ0E5SUhCdmFXNTBMbmc3WEc0Z0lIUm9hWE11ZVNBOUlIQnZhVzUwTG5rN1hHNGdJSFJvYVhNdVpXNTJaV3h2Y0dVZ1BTQmxiblpsYkc5d1pUdGNibHh1SUNCMGFHbHpMbVZzWlcxbGJuUWdQU0J6ZG1jdVkzSmxZWFJsS0NkamFYSmpiR1VuS1R0Y2JpQWdkR2hwY3k1bGJHVnRaVzUwTG5ObGRFRjBkSEpwWW5WMFpTZ25abWxzYkNjc2RHaHBjeTVsYm5abGJHOXdaUzVqYjJ4dmNuTXVZV05qWlc1MEtUdGNibHh1SUNCMGFHbHpMbVZ1ZG1Wc2IzQmxMbVZzWlcxbGJuUXVZWEJ3Wlc1a1EyaHBiR1FvZEdocGN5NWxiR1Z0Wlc1MEtUdGNibHh1SUNCMGFHbHpMbkpsYzJsNlpTQTlJR1oxYm1OMGFXOXVLQ2tnZTF4dUlDQWdJR3hsZENCeUlEMGdmbjRvVFdGMGFDNXRhVzRvZEdocGN5NWxiblpsYkc5d1pTNTNhV1IwYUN4MGFHbHpMbVZ1ZG1Wc2IzQmxMbWhsYVdkb2RDa3ZOVEFwS3pJN1hHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExuTmxkRUYwZEhKcFluVjBaU2duY2ljc2NpazdYRzRnSUgwN1hHNWNiaUFnZEdocGN5NXRiM1psSUQwZ1puVnVZM1JwYjI0b2VDeDVLU0I3WEc1Y2JpQWdJQ0IwYUdsekxuZ2dQU0FvZUNCOGZDQjRQVDA5TUNrZ1B5QjRJRG9nZEdocGN5NTRPMXh1SUNBZ0lIUm9hWE11ZVNBOUlDaDVJSHg4SUhrOVBUMHdLU0EvSUhrZ09pQjBhR2x6TG5rN1hHNWNiaUFnSUNCcFppQW9kR2hwY3k1bGJuWmxiRzl3WlM1dWIyUmxjeTVwYm1SbGVFOW1LSFJvYVhNcFBqMHdLU0I3WEc1Y2JpQWdJQ0FnSUd4bGRDQndjbVYyU1c1a1pYZ2dQU0IwYUdsekxtVnVkbVZzYjNCbExtNXZaR1Z6TG1sdVpHVjRUMllvZEdocGN5a3RNVHRjYmlBZ0lDQWdJR3hsZENCdVpYaDBTVzVrWlhnZ1BTQjBhR2x6TG1WdWRtVnNiM0JsTG01dlpHVnpMbWx1WkdWNFQyWW9kR2hwY3lrck1UdGNibHh1SUNBZ0lDQWdiR1YwSUhCeVpYWk9iMlJsSUQwZ2RHaHBjeTVsYm5abGJHOXdaUzV1YjJSbGMxdHdjbVYyU1c1a1pYaGRPMXh1SUNBZ0lDQWdiR1YwSUc1bGVIUk9iMlJsSUQwZ2RHaHBjeTVsYm5abGJHOXdaUzV1YjJSbGMxdHVaWGgwU1c1a1pYaGRPMXh1WEc0Z0lDQWdJQ0JzWlhRZ2JHOTNXQ0E5SUhCeVpYWkpibVJsZUNBK1BTQXdJRDhnY0hKbGRrNXZaR1V1ZUNBNklEQTdYRzRnSUNBZ0lDQnNaWFFnYUdsbmFGZ2dQU0J1WlhoMFNXNWtaWGdnUENCMGFHbHpMbVZ1ZG1Wc2IzQmxMbTV2WkdWekxteGxibWQwYUNBL0lHNWxlSFJPYjJSbExuZ2dPaUF4TzF4dVhHNGdJQ0FnSUNCcFppQW9kR2hwY3k1NElEd2diRzkzV0NrZ2V5QjBhR2x6TG5nZ1BTQnNiM2RZT3lCOVhHNGdJQ0FnSUNCcFppQW9kR2hwY3k1NElENGdhR2xuYUZncElIc2dkR2hwY3k1NElEMGdhR2xuYUZnN0lIMWNibHh1SUNBZ0lIMWNibHh1SUNBZ0lIUm9hWE11Ykc5allYUnBiMjRnUFNCMGFHbHpMbWRsZEVOdmIzSmthVzVoZEdWektDazdYRzRnSUNBZ2RHaHBjeTVsYkdWdFpXNTBMbk5sZEVGMGRISnBZblYwWlNnblkzZ25MQ0IwYUdsekxteHZZMkYwYVc5dUxuZ3BPMXh1SUNBZ0lIUm9hWE11Wld4bGJXVnVkQzV6WlhSQmRIUnlhV0oxZEdVb0oyTjVKeXdnZEdocGN5NXNiMk5oZEdsdmJpNTVLVHRjYmlBZ2ZUdGNibHh1SUNCMGFHbHpMbWRsZEVOdmIzSmthVzVoZEdWeklEMGdablZ1WTNScGIyNG9LU0I3WEc0Z0lDQWdjbVYwZFhKdUlIdGNiaUFnSUNBZ0lIZzZJSFJvYVhNdWVDQXFJSFJvYVhNdVpXNTJaV3h2Y0dVdWQybGtkR2dzWEc0Z0lDQWdJQ0I1T2lBb01TMTBhR2x6TG5rcElDb2dkR2hwY3k1bGJuWmxiRzl3WlM1b1pXbG5hSFJjYmlBZ0lDQjlPMXh1SUNCOU8xeHVYRzRnSUhSb2FYTXViVzkyWlNoMGFHbHpMbmdzZEdocGN5NTVMSFJ5ZFdVcE8xeHVJQ0IwYUdsekxuSmxjMmw2WlNncE8xeHVYRzRnSUhSb2FYTXVaR1Z6ZEhKdmVTQTlJR1oxYm1OMGFXOXVLQ2tnZTF4dUlDQWdJSFJvYVhNdVpXNTJaV3h2Y0dVdVpXeGxiV1Z1ZEM1eVpXMXZkbVZEYUdsc1pDaDBhR2x6TG1Wc1pXMWxiblFwTzF4dUlDQWdJSFJvYVhNdVpXNTJaV3h2Y0dVdWJtOWtaWE11YzNCc2FXTmxLSFJvYVhNdVpXNTJaV3h2Y0dVdWJtOWtaWE11YVc1a1pYaFBaaWgwYUdsektTd3hLVHRjYmlBZ2ZUdGNibHh1WEc1OU8xeHVYRzVjYmk4cUtseHVLaUJGYm5abGJHOXdaVnh1S2x4dUtpQkFaR1Z6WTNKcGNIUnBiMjRnU1c1MFpYSmhZM1JwZG1VZ2JHbHVaV0Z5SUhKaGJYQWdkbWx6ZFdGc2FYcGhkR2x2Ymk1Y2JpcGNiaW9nUUdSbGJXOGdQSE53WVc0Z2JtVjRkWE10ZFdrOVhDSmxiblpsYkc5d1pWd2lQand2YzNCaGJqNWNiaXBjYmlvZ1FHVjRZVzF3YkdWY2Jpb2dkbUZ5SUdWdWRtVnNiM0JsSUQwZ2JtVjNJRTVsZUhWekxrVnVkbVZzYjNCbEtDY2pkR0Z5WjJWMEp5bGNiaXBjYmlvZ1FHVjRZVzF3YkdWY2Jpb2dkbUZ5SUdWdWRtVnNiM0JsSUQwZ2JtVjNJRTVsZUhWekxrVnVkbVZzYjNCbEtDY2pkR0Z5WjJWMEp5eDdYRzRxSUNBZ0ozTnBlbVVuT2lCYk16QXdMREUxTUYwc1hHNHFJQ0FnSjNCdmFXNTBjeWM2SUZ0Y2Jpb2dJQ0FnSUh0Y2Jpb2dJQ0FnSUNBZ2VEb2dNQzR4TEZ4dUtpQWdJQ0FnSUNCNU9pQXdMalJjYmlvZ0lDQWdJSDBzWEc0cUlDQWdJQ0I3WEc0cUlDQWdJQ0FnSUhnNklEQXVNelVzWEc0cUlDQWdJQ0FnSUhrNklEQXVObHh1S2lBZ0lDQWdmU3hjYmlvZ0lDQWdJSHRjYmlvZ0lDQWdJQ0FnZURvZ01DNDJOU3hjYmlvZ0lDQWdJQ0FnZVRvZ01DNHlYRzRxSUNBZ0lDQjlMRnh1S2lBZ0lDQWdlMXh1S2lBZ0lDQWdJQ0I0T2lBd0xqa3NYRzRxSUNBZ0lDQWdJSGs2SURBdU5GeHVLaUFnSUNBZ2ZTeGNiaW9nSUNCZFhHNHFJSDBwWEc0cVhHNHFJRUJ2ZFhSd2RYUmNiaW9nWTJoaGJtZGxYRzRxSUVacGNtVnpJR0Z1ZVNCMGFXMWxJR0VnYm05a1pTQnBjeUJ0YjNabFpDNGdQR0p5UGx4dUtpQlVhR1VnWlhabGJuUWdaR0YwWVNCcGN5QmhiaUJoY25KaGVTQnZaaUJ3YjJsdWRDQnNiMk5oZEdsdmJuTXVJRVZoWTJnZ2FYUmxiU0JwYmlCMGFHVWdZWEp5WVhrZ2FYTWdZVzRnYjJKcVpXTjBJR052Ym5SaGFXNXBibWNnUEdrK2VEd3ZhVDRnWVc1a0lEeHBQbms4TDJrK0lIQnliM0JsY25ScFpYTWdaR1Z6WTNKcFltbHVaeUIwYUdVZ2JHOWpZWFJwYjI0Z2IyWWdZU0J3YjJsdWRDQnZiaUIwYUdVZ1pXNTJaV3h2Y0dVdVhHNHFYRzRxSUVCdmRYUndkWFJsZUdGdGNHeGxYRzRxSUdWdWRtVnNiM0JsTG05dUtDZGphR0Z1WjJVbkxHWjFibU4wYVc5dUtIWXBJSHRjYmlvZ0lDQmpiMjV6YjJ4bExteHZaeWgyS1R0Y2Jpb2dmU2xjYmlwY2Jpb3ZYRzVjYm1WNGNHOXlkQ0JrWldaaGRXeDBJR05zWVhOeklFVnVkbVZzYjNCbElHVjRkR1Z1WkhNZ1NXNTBaWEptWVdObElIdGNibHh1SUNCamIyNXpkSEoxWTNSdmNpZ3BJSHRjYmx4dUlDQWdJR3hsZENCdmNIUnBiMjV6SUQwZ1d5ZDJZV3gxWlNkZE8xeHVYRzRnSUNBZ2JHVjBJR1JsWm1GMWJIUnpJRDBnZTF4dUlDQWdJQ0FnSjNOcGVtVW5PaUJiTXpBd0xERTFNRjBzWEc0Z0lDQWdJQ0FuY0c5cGJuUnpKem9nVzF4dUlDQmNkRngwWEhSN1hHNGdJRngwWEhSY2RGeDBlRG9nTUM0eExGeHVJQ0JjZEZ4MFhIUmNkSGs2SURBdU5GeHVJQ0JjZEZ4MFhIUjlMRnh1SUNCY2RGeDBYSFI3WEc0Z0lGeDBYSFJjZEZ4MGVEb2dNQzR6TlN4Y2JpQWdYSFJjZEZ4MFhIUjVPaUF3TGpaY2JpQWdYSFJjZEZ4MGZTeGNiaUFnWEhSY2RGeDBlMXh1SUNCY2RGeDBYSFJjZEhnNklEQXVOalVzWEc0Z0lGeDBYSFJjZEZ4MGVUb2dNQzR5WEc0Z0lGeDBYSFJjZEgwc1hHNGdJRngwWEhSY2RIdGNiaUFnWEhSY2RGeDBYSFI0T2lBd0xqa3NYRzRnSUZ4MFhIUmNkRngwZVRvZ01DNDBYRzRnSUZ4MFhIUmNkSDFjYmlBZ1hIUmNkRjFjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdjM1Z3WlhJb1lYSm5kVzFsYm5SekxHOXdkR2x2Ym5Nc1pHVm1ZWFZzZEhNcE8xeHVYRzRnSUNBZ2RHaHBjeTV3YjJsdWRITWdQU0IwYUdsekxuTmxkSFJwYm1kekxuQnZhVzUwY3p0Y2JseHVJQ0FnSUhSb2FYTXVibTlrWlhNZ1BTQmJYVHRjYmx4dUlDQWdJSFJvYVhNdWMyVnNaV04wWldRZ1BTQm1ZV3h6WlR0Y2JseHVJQ0FnSUhSb2FYTXVhVzVwZENncE8xeHVYRzVjYmlBZ2ZWeHVYRzRnSUdKMWFXeGtTVzUwWlhKbVlXTmxLQ2tnZTF4dVhHNWNiaUFnSUNCMGFHbHpMbkJ2YVc1MGN5NW1iM0pGWVdOb0tDaHdiMmx1ZENrZ1BUNGdlMXh1SUNBZ0lDQWdiR1YwSUc1dlpHVWdQU0J1WlhjZ1VHOXBiblFvY0c5cGJuUXNkR2hwY3lrN1hHNGdJQ0FnSUNCMGFHbHpMbTV2WkdWekxuQjFjMmdvYm05a1pTazdYRzRnSUNBZ2ZTazdYRzVjYmlBZ0lDQjBhR2x6TG5OdmNuUlFiMmx1ZEhNb0tUdGNibHh1SUNBZ0lIUm9hWE11YkdsdVpTQTlJSE4yWnk1amNtVmhkR1VvSjNCdmJIbHNhVzVsSnlrN1hHNGdJQ0FnZEdocGN5NXNhVzVsTG5ObGRFRjBkSEpwWW5WMFpTZ25jM1J5YjJ0bExYZHBaSFJvSnl3Z01pazdYRzRnSUNBZ2RHaHBjeTVzYVc1bExuTmxkRUYwZEhKcFluVjBaU2duWm1sc2JDY3NJQ2R1YjI1bEp5azdYRzVjYmlBZ0lDQjBhR2x6TG1Wc1pXMWxiblF1WVhCd1pXNWtRMmhwYkdRb2RHaHBjeTVzYVc1bEtUdGNibHh1SUNBZ0lIUm9hWE11Wm1sc2JDQTlJSE4yWnk1amNtVmhkR1VvSjNCdmJIbHNhVzVsSnlrN1hHNGdJQ0FnZEdocGN5NW1hV3hzTG5ObGRFRjBkSEpwWW5WMFpTZ25abWxzYkMxdmNHRmphWFI1Snl3Z0p6QXVNaWNwTzF4dVhHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExtRndjR1Z1WkVOb2FXeGtLSFJvYVhNdVptbHNiQ2s3WEc1Y2JpQWdmVnh1WEc0Z0lITnBlbVZKYm5SbGNtWmhZMlVvS1NCN1hHNWNiaUFnSUNCbWIzSWdLR3hsZENCcFBUQTdJR2s4ZEdocGN5NXViMlJsY3k1c1pXNW5kR2c3SUdrckt5a2dlMXh1SUNBZ0lDQWdkR2hwY3k1dWIyUmxjMXRwWFM1eVpYTnBlbVVvS1R0Y2JpQWdJQ0FnSUhSb2FYTXVibTlrWlhOYmFWMHViVzkyWlNncE8xeHVJQ0FnSUgxY2JseHVJQ0FnSUhSb2FYTXVjbVZ1WkdWeUtDazdYRzVjYmlBZ2ZWeHVYRzRnSUdOdmJHOXlTVzUwWlhKbVlXTmxLQ2tnZTF4dVhHNGdJQ0FnZEdocGN5NWxiR1Z0Wlc1MExuTjBlV3hsTG1KaFkydG5jbTkxYm1SRGIyeHZjaUE5SUhSb2FYTXVZMjlzYjNKekxtWnBiR3c3WEc0Z0lDQWdkR2hwY3k1c2FXNWxMbk5sZEVGMGRISnBZblYwWlNnbmMzUnliMnRsSnl3Z2RHaHBjeTVqYjJ4dmNuTXVZV05qWlc1MEtUdGNiaUFnSUNCMGFHbHpMbVpwYkd3dWMyVjBRWFIwY21saWRYUmxLQ2RtYVd4c0p5d2dkR2hwY3k1amIyeHZjbk11WVdOalpXNTBLVHRjYmlBZ0lDQjBhR2x6TG01dlpHVnpMbVp2Y2tWaFkyZ29LRzV2WkdVcElEMCtJSHRjYmlBZ0lDQWdJRzV2WkdVdVpXeGxiV1Z1ZEM1elpYUkJkSFJ5YVdKMWRHVW9KMlpwYkd3bkxIUm9hWE11WTI5c2IzSnpMbUZqWTJWdWRDazdYRzRnSUNBZ2ZTazdYRzVjYmlBZ2ZWeHVYRzRnSUhKbGJtUmxjaWdwSUh0Y2JpQWdMeThnSUhSb2FYTXVibTlrWlhOYmRHaHBjeTV6Wld4bFkzUmxaRjB1Ylc5MlpTZ2dkR2hwY3k1d2IybHVkSE1nS1Z4dUlDQWdJSFJvYVhNdVkyRnNZM1ZzWVhSbFVHRjBhQ2dwTzF4dUlDQjlYRzVjYmlBZ1kyRnNZM1ZzWVhSbFVHOXBiblJ6S0NrZ2UxeHVJQ0FnSUhSb2FYTXVjRzlwYm5SeklEMGdXMTA3WEc0Z0lDQWdkR2hwY3k1dWIyUmxjeTVtYjNKRllXTm9LQ2h1YjJSbEtTQTlQaUI3WEc0Z0lDQWdJQ0IwYUdsekxuQnZhVzUwY3k1d2RYTm9LSHNnZURvZ2JtOWtaUzU0TENCNU9pQnViMlJsTG5rZ2ZTazdYRzRnSUNBZ2ZTazdYRzRnSUgxY2JseHVJQ0JqWVd4amRXeGhkR1ZRWVhSb0tDa2dlMXh1WEc0Z0lDQWdMeTl6ZEhKdmEyVWdaR0YwWVZ4dUlDQWdJR3hsZENCa1lYUmhJRDBnSnpBZ0p5c2dkR2hwY3k1dWIyUmxjMXN3WFM1c2IyTmhkR2x2Ymk1NUt5Y3NJQ2M3WEc1Y2JpQWdJQ0F2THlCa1lYUmhJSE5vYjNWc1pDQmlaU0J5WlMxdmNtUmxjbVZrSUdKaGMyVmtJRzl1SUhnZ2JHOWpZWFJwYjI0dVhHNGdJQ0FnTHk4Z2QyaGhkR1YyWlhJZ1puVnVZM1JwYjI0Z1lXUmtjeUJoSUc1dlpHVWdjMmh2ZFd4a0lHRmtaQ0JwZENCaGRDQjBhR1VnY21sbmFIUWdhVzVrWlhoY2JseHVJQ0FnSUhSb2FYTXVibTlrWlhNdVptOXlSV0ZqYUNnb2JtOWtaU2tnUFQ0Z2UxeHVJQ0FnSUM4dklDQnNaWFFnYkc5allYUnBiMjRnUFNCdWIyUmxMbWRsZEVOdmIzSmthVzVoZEdWektDazdYRzRnSUNBZ0lDQmtZWFJoSUNzOUlHNXZaR1V1Ykc5allYUnBiMjR1ZUNBcklDY2dKeUFySUc1dlpHVXViRzlqWVhScGIyNHVlU0FySUNjc0lDYzdYRzRnSUNBZ2ZTazdYRzVjYmx4dUlDQXZMeUFnWkdGMFlTQXJQU0J3YjJsdWRDNTRLblJvYVhNdWQybGtkR2dySnlBbkt5QndiMmx1ZEM1NUtuUm9hWE11YUdWcFoyaDBLeWNzSUNjN1hHNGdJQ0FnWkdGMFlTQXJQU0IwYUdsekxuZHBaSFJvSUNzZ0p5QW5LeUIwYUdsekxtNXZaR1Z6VzNSb2FYTXVibTlrWlhNdWJHVnVaM1JvTFRGZExteHZZMkYwYVc5dUxuazdYRzVjYmlBZ0lDQjBhR2x6TG14cGJtVXVjMlYwUVhSMGNtbGlkWFJsS0Nkd2IybHVkSE1uTENCa1lYUmhLVHRjYmx4dUlDQWdJQzh2SUdacGJHd2daR0YwWVZ4dUlDQWdJQzh2SUdGa1pDQmliM1IwYjIwZ1kyOXlibVZ5YzF4dVhHNGdJQ0FnWkdGMFlTQXJQU0FuTENBbkszUm9hWE11ZDJsa2RHZ2dLeWNnSnl0MGFHbHpMbWhsYVdkb2RDc25MQ0FuTzF4dUlDQWdJR1JoZEdFZ0t6MGdKekFnSnl0MGFHbHpMbWhsYVdkb2REdGNibHh1SUNBZ0lIUm9hWE11Wm1sc2JDNXpaWFJCZEhSeWFXSjFkR1VvSjNCdmFXNTBjeWNzSUdSaGRHRXBPMXh1WEc0Z0lIMWNibHh1WEc1Y2JpQWdZMnhwWTJzb0tTQjdYRzRnSUZ4MEx5OGdabWx1WkNCdVpXRnlaWE4wSUc1dlpHVWdZVzVrSUhObGRDQjBhR2x6TG5ObGJHVmpkR1ZrSUNocGJtUmxlQ2xjYmlBZ0lDQjBhR2x6TG1oaGMwMXZkbVZrSUQwZ1ptRnNjMlU3WEc0Z0lGeDBkR2hwY3k1elpXeGxZM1JsWkNBOUlIUm9hWE11Wm1sdVpFNWxZWEpsYzNST2IyUmxLQ2s3WEc1Y2JpQWdJQ0IwYUdsekxtNXZaR1Z6VzNSb2FYTXVjMlZzWldOMFpXUmRMbTF2ZG1Vb2RHaHBjeTV0YjNWelpTNTRMM1JvYVhNdWQybGtkR2dzTVMxMGFHbHpMbTF2ZFhObExua3ZkR2hwY3k1b1pXbG5hSFFwTzF4dUlDQWdJSFJvYVhNdWMyTmhiR1ZPYjJSbEtIUm9hWE11YzJWc1pXTjBaV1FwTzF4dVhHNGdJQ0FnTHk4Z2JYVnpkQ0JrYnlCMGFHbHpJR0l2WXlCdVpYY2dibTlrWlNCdFlYa2dhR0YyWlNCaVpXVnVJR055WldGMFpXUmNiaUFnSUNCMGFHbHpMbU5oYkdOMWJHRjBaVkJ2YVc1MGN5Z3BPMXh1SUNBZ0lIUm9hWE11WlcxcGRDZ25ZMmhoYm1kbEp5eDBhR2x6TG5CdmFXNTBjeWs3WEc0Z0lGeDBkR2hwY3k1eVpXNWtaWElvS1R0Y2JpQWdmVnh1WEc0Z0lHMXZkbVVvS1NCN1hHNGdJRngwYVdZZ0tIUm9hWE11WTJ4cFkydGxaQ2tnZTF4dUlDQWdJQ0FnZEdocGN5NXRiM1Z6WlM1NElEMGdiV0YwYUM1amJHbHdLSFJvYVhNdWJXOTFjMlV1ZUN3d0xIUm9hWE11ZDJsa2RHZ3BPMXh1SUNBZ0lDQWdkR2hwY3k1b1lYTk5iM1psWkNBOUlIUnlkV1U3WEc1Y2JpQWdJQ0FnSUhSb2FYTXVibTlrWlhOYmRHaHBjeTV6Wld4bFkzUmxaRjB1Ylc5MlpTaDBhR2x6TG0xdmRYTmxMbmd2ZEdocGN5NTNhV1IwYUN3eExYUm9hWE11Ylc5MWMyVXVlUzkwYUdsekxtaGxhV2RvZENrN1hHNGdJQ0FnWEhSMGFHbHpMbk5qWVd4bFRtOWtaU2gwYUdsekxuTmxiR1ZqZEdWa0tUdGNibHh1SUNBZ0lDQWdkR2hwY3k1allXeGpkV3hoZEdWUWIybHVkSE1vS1R0Y2JpQWdYSFJjZEhSb2FYTXVaVzFwZENnblkyaGhibWRsSnl4MGFHbHpMbkJ2YVc1MGN5azdYRzRnSUZ4MFhIUjBhR2x6TG5KbGJtUmxjaWdwTzF4dUlDQmNkSDFjYmlBZ2ZWeHVYRzRnSUhKbGJHVmhjMlVvS1NCN1hHNWNiaUFnWEhScFppQW9JWFJvYVhNdWFHRnpUVzkyWldRcElIdGNiaUFnSUNBZ0lIUm9hWE11Ym05a1pYTmJkR2hwY3k1elpXeGxZM1JsWkYwdVpHVnpkSEp2ZVNncE8xeHVJQ0JjZEgxY2JseHVJQ0FnSUhSb2FYTXVZMkZzWTNWc1lYUmxVRzlwYm5SektDazdYRzRnSUNBZ2RHaHBjeTVsYldsMEtDZGphR0Z1WjJVbkxIUm9hWE11Y0c5cGJuUnpLVHRjYmlBZ1hIUjBhR2x6TG5KbGJtUmxjaWdwTzF4dVhHNGdJRngwTHk4Z2NtVnpaWFFnZEdocGN5NXpaV3hsWTNSbFpGeHVJQ0JjZEhSb2FYTXVjMlZzWldOMFpXUWdQU0J1ZFd4c08xeHVJQ0I5WEc1Y2JseHVJQ0JtYVc1a1RtVmhjbVZ6ZEU1dlpHVW9LU0I3WEc0Z0lGeDBkbUZ5SUc1bFlYSmxjM1JKYm1SbGVDQTlJRzUxYkd3N1hHNGdJQ0FnTHk4Z2MyVjBJSFJvYVhNZ2RXNXlaV0Z6YjI1aFlteDVJR2hwWjJnZ2MyOGdkR2hoZENCbGRtVnllU0JrYVhOMFlXNWpaU0IzYVd4c0lHSmxJR3h2ZDJWeUlIUm9ZVzRnYVhRdVhHNGdJRngwZG1GeUlHNWxZWEpsYzNSRWFYTjBJRDBnTVRBd01EQTdYRzRnSUZ4MGRtRnlJR0psWm05eVpTQTlJR1poYkhObE8xeHVJQ0FnSUd4bGRDQjRJRDBnZEdocGN5NXRiM1Z6WlM1NEwzUm9hWE11ZDJsa2RHZzdYRzRnSUNBZ2JHVjBJSGtnUFNBeExYUm9hWE11Ylc5MWMyVXVlUzkwYUdsekxtaGxhV2RvZER0Y2JpQWdJQ0JzWlhRZ2JtOWtaWE1nUFNCMGFHbHpMbTV2WkdWek8xeHVJQ0JjZEdadmNpQW9iR1YwSUdrZ1BTQXdPeUJwUEc1dlpHVnpMbXhsYm1kMGFEc2dhU3NyS1NCN1hHNWNiaUFnSUNBZ0lDOHZJR05oYkdOMWJHRjBaU0IwYUdVZ1pHbHpkR0Z1WTJVZ1puSnZiU0J0YjNWelpTQjBieUIwYUdseklHNXZaR1VnZFhOcGJtY2djSGwwYUdGbmIzSmxZVzRnZEdobGIzSmxiVnh1SUNCY2RGeDBkbUZ5SUdScGMzUmhibU5sSUQwZ1RXRjBhQzV6Y1hKMEtDQWdUV0YwYUM1d2IzY29JQ2h1YjJSbGMxdHBYUzU0SUMwZ2VDa3NJRElwSUNzZ1RXRjBhQzV3YjNjb0tHNXZaR1Z6VzJsZExua2dMU0I1S1N3Z01pa2dLVHRjYmx4dUlDQWdJQ0FnTHk4Z2FXWWdkR2hwY3lCa2FYTjBZVzVqWlNCcGN5QnNaWE56SUhSb1lXNGdkR2hsSUhCeVpYWnBiM1Z6SUhOb2IzSjBaWE4wSUdScGMzUmhibU5sTENCMWMyVWdkR2hwY3lCcGJtUmxlRnh1SUNCY2RGeDBhV1lnS0dScGMzUmhibU5sSUR3Z2JtVmhjbVZ6ZEVScGMzUXBJSHRjYmlBZ1hIUmNkRngwYm1WaGNtVnpkRVJwYzNRZ1BTQmthWE4wWVc1alpUdGNiaUFnWEhSY2RGeDBibVZoY21WemRFbHVaR1Y0SUQwZ2FUdGNiaUFnWEhSY2RGeDBZbVZtYjNKbElEMGdlQ0ErSUc1dlpHVnpXMmxkTG5nN1hHNGdJRngwWEhSOVhHNWNiaUFnWEhSOVhHNWNiaUFnSUNBdkx5QnBaaUJ1YjNRZ2RtVnllU0JqYkc5elpTQjBieUJoYm5rZ2JtOWtaU3dnWTNKbFlYUmxJR0VnYm05a1pWeHVJQ0JjZEdsbUlDaHVaV0Z5WlhOMFJHbHpkRDR3TGpBM0tTQjdYRzVjYmlBZ0lDQWdJRzVsWVhKbGMzUkpibVJsZUNBOUlIUm9hWE11WjJWMFNXNWtaWGhHY205dFdDaDBhR2x6TG0xdmRYTmxMbmd2ZEdocGN5NTNhV1IwYUNrN1hHNWNiaUFnWEhSY2RIUm9hWE11Ym05a1pYTXVjM0JzYVdObEtHNWxZWEpsYzNSSmJtUmxlQ3d3TENCdVpYY2dVRzlwYm5Rb2UxeHVJQ0JjZEZ4MFhIUjRPaUIwYUdsekxtMXZkWE5sTG5ndmRHaHBjeTUzYVdSMGFDeGNiaUFnWEhSY2RGeDBlVG9nTVMxMGFHbHpMbTF2ZFhObExua3ZkR2hwY3k1b1pXbG5hSFJjYmlBZ1hIUmNkSDBzSUhSb2FYTXBLVHRjYmlBZ0lDQWdJSFJvYVhNdWFHRnpUVzkyWldRZ1BTQjBjblZsTzF4dVhHNGdJRngwZlZ4dVhHNGdJRngwY21WMGRYSnVJRzVsWVhKbGMzUkpibVJsZUR0Y2JpQWdmVnh1WEc0Z0lHZGxkRWx1WkdWNFJuSnZiVmdvZUNrZ2UxeHVJQ0FnSUd4bGRDQnBibVJsZUNBOUlEQTdYRzRnSUNBZ2RHaHBjeTV1YjJSbGN5NW1iM0pGWVdOb0tDaHViMlJsTEdrcElEMCtJSHRjYmlBZ0lDQWdJR2xtSUNoMGFHbHpMbTV2WkdWelcybGRMbmdnUEQwZ2VDa2dlMXh1SUNBZ0lDQWdJQ0JwYm1SbGVDQTlJR2tyTVR0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5S1R0Y2JpQWdJQ0J5WlhSMWNtNGdhVzVrWlhnN1hHNGdJSDFjYmx4dUlDQnpZMkZzWlU1dlpHVW9hU2tnZTF4dVhHNGdJRngwYkdWMElHTnNhWEJ3WldSWUlEMGdiV0YwYUM1amJHbHdLSFJvYVhNdWJtOWtaWE5iYVYwdWVDd2dNQ3dnTVNrN1hHNGdJRngwYkdWMElHTnNhWEJ3WldSWklEMGdiV0YwYUM1amJHbHdLSFJvYVhNdWJtOWtaWE5iYVYwdWVTd2dNQ3dnTVNrN1hHNWNiaUFnSUNCMGFHbHpMbTV2WkdWelcybGRMbTF2ZG1Vb0lHTnNhWEJ3WldSWUxDQmpiR2x3Y0dWa1dTQXBPMXh1WEc0Z0lIMWNibHh1SUNBdktpcGNiaUFnVTI5eWRDQjBhR1VnZEdocGN5NXdiMmx1ZEhNZ1lYSnlZWGtnWm5KdmJTQnNaV1owTFcxdmMzUWdjRzlwYm5RZ2RHOGdjbWxuYUhRdGJXOXpkQ0J3YjJsdWRDNGdXVzkxSUhOb2IzVnNaQ0J1YjNRZ2NtVm5kV3hoY214NUlHNWxaV1FnZEc4Z2RYTmxJSFJvYVhNc0lHaHZkMlYyWlhJZ2FYUWdiV0Y1SUdKbElIVnpaV1oxYkNCcFppQjBhR1VnY0c5cGJuUnpJR2RsZENCMWJtOXlaR1Z5WldRdVhHNGdJQ292WEc0Z0lITnZjblJRYjJsdWRITW9LU0I3WEc0Z0lDQWdkR2hwY3k1dWIyUmxjeTV6YjNKMEtHWjFibU4wYVc5dUtHRXNJR0lwZTF4dUlDQWdJQ0FnY21WMGRYSnVJR0V1ZUNBK0lHSXVlRHRjYmlBZ0lDQjlLVHRjYmlBZ2ZWeHVYRzVjYmlBZ0x5b3FYRzRnSUVGa1pDQmhJR0p5WldGcmNHOXBiblFnYjI0Z2RHaGxJR1Z1ZG1Wc2IzQmxMbHh1SUNCQWNHRnlZVzBnZUNCN2JuVnRZbVZ5ZlNCNElHeHZZMkYwYVc5dUlHOW1JSFJvWlNCd2IybHVkQ3dnYm05eWJXRnNhWHBsWkNBb01DMHhLVnh1SUNCQWNHRnlZVzBnZVNCN2JuVnRZbVZ5ZlNCNUlHeHZZMkYwYVc5dUlHOW1JSFJvWlNCd2IybHVkQ3dnYm05eWJXRnNhWHBsWkNBb01DMHhLVnh1SUNBcUwxeHVJQ0JoWkdSUWIybHVkQ2g0TEhrcElIdGNiaUFnSUNCc1pYUWdhVzVrWlhnZ1BTQjBhR2x6TG01dlpHVnpMbXhsYm1kMGFEdGNibHh1SUNBZ0lIUm9hWE11YzI5eWRGQnZhVzUwY3lncE8xeHVYRzRnSUNBZ1ptOXlJQ2hzWlhRZ2FTQTlJREE3SUdrOGRHaHBjeTV1YjJSbGN5NXNaVzVuZEdnN0lHa3JLeWtnZTF4dUlDQWdJQ0FnYVdZZ0tIZ2dQQ0IwYUdsekxtNXZaR1Z6VzJsZExuZ3BJSHRjYmlBZ0lDQWdJQ0FnYVc1a1pYZ2dQU0JwTzF4dUlDQWdJQ0FnSUNCaWNtVmhhenRjYmlBZ0lDQWdJSDFjYmlBZ1hIUjlYRzVjYmlBZ0lDQjBhR2x6TG01dlpHVnpMbk53YkdsalpTaHBibVJsZUN3Z01Dd2dibVYzSUZCdmFXNTBLSHRjYmlBZ0lDQWdJSGc2SUhnc1hHNGdJQ0FnSUNCNU9pQjVYRzRnSUNBZ2ZTd2dkR2hwY3lrcE8xeHVYRzRnSUNBZ2RHaHBjeTV6WTJGc1pVNXZaR1VvYVc1a1pYZ3BPMXh1WEc0Z0lDQWdkR2hwY3k1allXeGpkV3hoZEdWUWIybHVkSE1vS1R0Y2JpQWdJQ0IwYUdsekxtVnRhWFFvSjJOb1lXNW5aU2NzZEdocGN5NXdiMmx1ZEhNcE8xeHVYRzRnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmlBZ2ZWeHVYRzVjYmlBZ0x5b3FYRzRnSUVacGJtUWdkR2hsSUd4bGRtVnNJR0YwSUdFZ1kyVnlkR0ZwYmlCNElHeHZZMkYwYVc5dUlHOXVJSFJvWlNCbGJuWmxiRzl3WlM1Y2JpQWdRSEJoY21GdElIZ2dlMjUxYldKbGNuMGdWR2hsSUhnZ2JHOWpZWFJwYjI0Z2RHOGdabWx1WkNCMGFHVWdiR1YyWld3Z2IyWXNJRzV2Y20xaGJHbDZaV1FnTUMweFhHNGdJQ292WEc0Z0lITmpZVzRvZUNrZ2UxeHVJQ0FnSUM4dklHWnBibVFnYzNWeWNtOTFibVJwYm1jZ2NHOXBiblJ6WEc0Z0lDQWdiR1YwSUc1bGVIUkpibVJsZUNBOUlIUm9hWE11WjJWMFNXNWtaWGhHY205dFdDaDRLVHRjYmlBZ0lDQnNaWFFnY0hKcGIzSkpibVJsZUNBOUlHNWxlSFJKYm1SbGVDMHhPMXh1SUNBZ0lHbG1JQ2h3Y21sdmNrbHVaR1Y0SUR3Z01Da2dlMXh1SUNBZ0lDQWdjSEpwYjNKSmJtUmxlQ0E5SURBN1hHNGdJQ0FnZlZ4dUlDQWdJR2xtSUNodVpYaDBTVzVrWlhnZ1BqMGdkR2hwY3k1dWIyUmxjeTVzWlc1bmRHZ3BJSHRjYmlBZ0lDQWdJRzVsZUhSSmJtUmxlQ0E5SUhSb2FYTXVibTlrWlhNdWJHVnVaM1JvTFRFN1hHNGdJQ0FnZlZ4dUlDQWdJR3hsZENCd2NtbHZjbEJ2YVc1MElEMGdkR2hwY3k1dWIyUmxjMXR3Y21sdmNrbHVaR1Y0WFR0Y2JpQWdJQ0JzWlhRZ2JtVjRkRkJ2YVc1MElEMGdkR2hwY3k1dWIyUmxjMXR1WlhoMFNXNWtaWGhkTzF4dUlDQWdJR3hsZENCc2IyTWdQU0J0WVhSb0xuTmpZV3hsS0hnc2NISnBiM0pRYjJsdWRDNTRMQ0J1WlhoMFVHOXBiblF1ZUN3Z01Dd2dNU2s3WEc0Z0lDQWdiR1YwSUhaaGJIVmxJRDBnYldGMGFDNXBiblJsY25Bb2JHOWpMSEJ5YVc5eVVHOXBiblF1ZVN4dVpYaDBVRzlwYm5RdWVTazdYRzRnSUNBZ2RHaHBjeTVsYldsMEtDZHpZMkZ1Snl4MllXeDFaU2s3WEc0Z0lDQWdjbVYwZFhKdUlIWmhiSFZsTzF4dUlDQjlYRzVjYmx4dUlDQXZLaXBjYmlBZ1RXOTJaU0JoSUdKeVpXRnJjRzlwYm5RZ2IyNGdkR2hsSUdWdWRtVnNiM0JsTGx4dUlDQkFjR0Z5WVcwZ2FXNWtaWGdnZTI1MWJXSmxjbjBnVkdobElHbHVaR1Y0SUc5bUlIUm9aU0JpY21WaGEzQnZhVzUwSUhSdklHMXZkbVZjYmlBZ1FIQmhjbUZ0SUhnZ2UyNTFiV0psY24wZ1RtVjNJSGdnYkc5allYUnBiMjRzSUc1dmNtMWhiR2w2WldRZ01DMHhYRzRnSUVCd1lYSmhiU0I1SUh0dWRXMWlaWEo5SUU1bGR5QjVJR3h2WTJGMGFXOXVMQ0J1YjNKdFlXeHBlbVZrSURBdE1WeHVJQ0FxTDF4dUlDQnRiM1psVUc5cGJuUW9hVzVrWlhnc2VDeDVLU0I3WEc0Z0lDQWdkR2hwY3k1dWIyUmxjMXRwYm1SbGVGMHViVzkyWlNoNExIa3BPMXh1SUNBZ0lIUm9hWE11YzJOaGJHVk9iMlJsS0dsdVpHVjRLVHRjYmlBZ0lDQjBhR2x6TG1OaGJHTjFiR0YwWlZCdmFXNTBjeWdwTzF4dUlDQWdJSFJvYVhNdVpXMXBkQ2duWTJoaGJtZGxKeXgwYUdsekxuQnZhVzUwY3lrN1hHNGdJQ0FnZEdocGN5NXlaVzVrWlhJb0tUdGNiaUFnZlZ4dVhHNWNiaUFnTHlvcVhHNGdJRTF2ZG1VZ1lTQmljbVZoYTNCdmFXNTBJRzl1SUhSb1pTQmxiblpsYkc5d1pTQmllU0JoSUdObGNuUmhhVzRnWVcxdmRXNTBMbHh1SUNCQWNHRnlZVzBnYVc1a1pYZ2dlMjUxYldKbGNuMGdWR2hsSUdsdVpHVjRJRzltSUhSb1pTQmljbVZoYTNCdmFXNTBJSFJ2SUcxdmRtVmNiaUFnUUhCaGNtRnRJSGhQWm1aelpYUWdlMjUxYldKbGNuMGdXQ0JrYVhOd2JHRmpaVzFsYm5Rc0lHNXZjbTFoYkdsNlpXUWdNQzB4WEc0Z0lFQndZWEpoYlNCNVQyWm1jMlYwSUh0dWRXMWlaWEo5SUZrZ1pHbHpjR3hoWTJWdFpXNTBMQ0J1YjNKdFlXeHBlbVZrSURBdE1WeHVJQ0FxTDF4dUlDQmhaR3AxYzNSUWIybHVkQ2hwYm1SbGVDeDRUMlptYzJWMExIbFBabVp6WlhRcElIdGNiaUFnSUNCMGFHbHpMbTV2WkdWelcybHVaR1Y0WFM1dGIzWmxLSFJvYVhNdWJtOWtaWE5iYVc1a1pYaGRMbmdyZUU5bVpuTmxkQ3gwYUdsekxtNXZaR1Z6VzJsdVpHVjRYUzU1SzNsUFptWnpaWFFwTzF4dUlDQWdJSFJvYVhNdWMyTmhiR1ZPYjJSbEtHbHVaR1Y0S1R0Y2JpQWdJQ0IwYUdsekxtTmhiR04xYkdGMFpWQnZhVzUwY3lncE8xeHVJQ0FnSUhSb2FYTXVaVzFwZENnblkyaGhibWRsSnl4MGFHbHpMbkJ2YVc1MGN5azdYRzRnSUNBZ2RHaHBjeTV5Wlc1a1pYSW9LVHRjYmlBZ2ZWeHVYRzVjYmlBZ0x5b3FYRzRnSUZKbGJXOTJaU0JoSUdKeVpXRnJjRzlwYm5RZ1puSnZiU0IwYUdVZ1pXNTJaV3h2Y0dVdVhHNGdJRUJ3WVhKaGJTQnBibVJsZUNCN2JuVnRZbVZ5ZlNCSmJtUmxlQ0J2WmlCMGFHVWdZbkpsWVd0d2IybHVkQ0IwYnlCeVpXMXZkbVZjYmlBZ0tpOWNiaUFnWkdWemRISnZlVkJ2YVc1MEtHbHVaR1Y0S1NCN1hHNGdJQ0FnZEdocGN5NXViMlJsYzF0cGJtUmxlRjB1WkdWemRISnZlU2dwTzF4dUlDQWdJSFJvYVhNdVkyRnNZM1ZzWVhSbFVHOXBiblJ6S0NrN1hHNGdJQ0FnZEdocGN5NWxiV2wwS0NkamFHRnVaMlVuTEhSb2FYTXVjRzlwYm5SektUdGNiaUFnSUNCMGFHbHpMbkpsYm1SbGNpZ3BPMXh1SUNCOVhHNWNibHh1SUNBdktpcGNiaUFnVW1WdGIzWmxJR0ZzYkNCbGVHbHpkR2x1WnlCaWNtVmhhM0J2YVc1MGN5QmhibVFnWVdSa0lHRnVJR1Z1ZEdseVpXeDVJRzVsZHlCelpYUWdiMllnWW5KbFlXdHdiMmx1ZEhNdVhHNGdJRUJ3WVhKaGJTQmhiR3hRYjJsdWRITWdlMkZ5Y21GNWZTQkJiaUJoY25KaGVTQnZaaUJ2WW1wbFkzUnpJSGRwZEdnZ2VDOTVJSEJ5YjNCbGNuUnBaWE1nS0c1dmNtMWhiR2w2WldRZ01DMHhLUzRnUldGamFDQnZZbXBsWTNRZ2FXNGdkR2hsSUdGeWNtRjVJSE53WldOcFptbGpaWE1nZEdobElIZ3ZlU0JzYjJOaGRHbHZiaUJ2WmlCaElHNWxkeUJpY21WaGEzQnZhVzUwSUhSdklHSmxJR0ZrWkdWa0xseHVJQ0FxTDF4dUlDQnpaWFJRYjJsdWRITW9ZV3hzVUc5cGJuUnpLU0I3WEc0Z0lDQWdkMmhwYkdVZ0tIUm9hWE11Ym05a1pYTXViR1Z1WjNSb0tTQjdYRzRnSUNBZ0lDQjBhR2x6TG01dlpHVnpXekJkTG1SbGMzUnliM2tvS1R0Y2JpQWdJQ0I5WEc0Z0lDQWdZV3hzVUc5cGJuUnpMbVp2Y2tWaFkyZ29LSEJ2YVc1MEtTQTlQaUI3WEc0Z0lDQWdJQ0IwYUdsekxtRmtaRkJ2YVc1MEtIQnZhVzUwTG5nc2NHOXBiblF1ZVNrN1hHNGdJQ0FnZlNrN1hHNGdJQ0FnZEdocGN5NWpZV3hqZFd4aGRHVlFiMmx1ZEhNb0tUdGNiaUFnSUNCMGFHbHpMbVZ0YVhRb0oyTm9ZVzVuWlNjc2RHaHBjeTV3YjJsdWRITXBPMXh1SUNBZ0lIUm9hWE11Y21WdVpHVnlLQ2s3WEc0Z0lIMWNibHh1ZlZ4dVhHNWNibHh1THk4Z1YwVkNVRUZEU3lCR1QwOVVSVklnTHk5Y2JpOHZJQzR2Zmk5cWMyaHBiblF0Ykc5aFpHVnlJUzR2YkdsaUwybHVkR1Z5Wm1GalpYTXZaVzUyWld4dmNHVXVhbk1pTENJbmRYTmxJSE4wY21samRDYzdYRzVjYm14bGRDQmtiMjBnUFNCeVpYRjFhWEpsS0NjdUxpOTFkR2xzTDJSdmJTY3BPMXh1THk5c1pYUWdiV0YwYUNBOUlISmxjWFZwY21Vb0p5NHVMM1YwYVd3dmJXRjBhQ2NwTzF4dWJHVjBJRWx1ZEdWeVptRmpaU0E5SUhKbGNYVnBjbVVvSnk0dUwyTnZjbVV2YVc1MFpYSm1ZV05sSnlrN1hHNWNiaThxS2x4dUtpQlRjR1ZqZEhKdlozSmhiVnh1S2x4dUtpQkFaR1Z6WTNKcGNIUnBiMjRnUVhWa2FXOGdjM0JsWTNSeWRXMGdkbWx6ZFdGc2FYcGhkR2x2Ymx4dUtseHVLaUJBWkdWdGJ5QThjM0JoYmlCdVpYaDFjeTExYVQxY0luTndaV04wY205bmNtRnRYQ0krUEM5emNHRnVQbHh1S2x4dUtpQkFaWGhoYlhCc1pWeHVLaUIyWVhJZ2MzQmxZM1J5YjJkeVlXMGdQU0J1WlhjZ1RtVjRkWE11VTNCbFkzUnliMmR5WVcwb0p5TjBZWEpuWlhRbktWeHVLbHh1S2lCQVpYaGhiWEJzWlZ4dUtpQjJZWElnYzNCbFkzUnliMmR5WVcwZ1BTQnVaWGNnVG1WNGRYTXVVM0JsWTNSeWIyZHlZVzBvSnlOMFlYSm5aWFFuTEh0Y2Jpb2dJQ0FuYzJsNlpTYzZJRnN6TURBc01UVXdYVnh1S2lCOUtWeHVLbHh1S2lCQWIzVjBjSFYwWEc0cUlDWnVZbk53TzF4dUtpQk9ieUJsZG1WdWRITmNiaXBjYmlvdlhHNWNibWx0Y0c5eWRDQjdJR052Ym5SbGVIUWdmU0JtY205dElDY3VMaTl0WVdsdUp6dGNibHh1Wlhod2IzSjBJR1JsWm1GMWJIUWdZMnhoYzNNZ1UzQmxZM1J5YjJkeVlXMGdaWGgwWlc1a2N5QkpiblJsY21aaFkyVWdlMXh1WEc0Z0lHTnZibk4wY25WamRHOXlLQ2tnZTF4dVhHNGdJQ0FnYkdWMElHOXdkR2x2Ym5NZ1BTQmJKM05qWVd4bEp5d25kbUZzZFdVblhUdGNibHh1SUNBZ0lHeGxkQ0JrWldaaGRXeDBjeUE5SUh0Y2JpQWdJQ0FnSUNkemFYcGxKem9nV3pNd01Dd3hOVEJkWEc0Z0lDQWdmVHRjYmx4dUlDQWdJSE4xY0dWeUtHRnlaM1Z0Wlc1MGN5eHZjSFJwYjI1ekxHUmxabUYxYkhSektUdGNibHh1SUNBZ0lIUm9hWE11WTI5dWRHVjRkQ0E5SUdOdmJuUmxlSFFvS1RzZ0x5OGdhbk5vYVc1MElHbG5ibTl5WlRwc2FXNWxYRzVjYmlBZ0lDQjBhR2x6TG1GdVlXeDVjMlZ5SUQwZ2RHaHBjeTVqYjI1MFpYaDBMbU55WldGMFpVRnVZV3g1YzJWeUtDazdYRzRnSUNBZ2RHaHBjeTVoYm1Gc2VYTmxjaTVtWm5SVGFYcGxJRDBnTWpBME9EdGNiaUFnSUNCMGFHbHpMbUoxWm1abGNreGxibWQwYUNBOUlIUm9hWE11WVc1aGJIbHpaWEl1Wm5KbGNYVmxibU41UW1sdVEyOTFiblE3WEc0Z0lDQWdkR2hwY3k1a1lYUmhRWEp5WVhrZ1BTQnVaWGNnVldsdWREaEJjbkpoZVNoMGFHbHpMbUoxWm1abGNreGxibWQwYUNrN1hHNWNiaUFnSUNCMGFHbHpMbUZqZEdsMlpTQTlJSFJ5ZFdVN1hHNWNiaUFnSUNCMGFHbHpMbk52ZFhKalpTQTlJR1poYkhObE8xeHVYRzRnSUNBZ2RHaHBjeTVwYm1sMEtDazdYRzVjYmlBZ2ZWeHVYRzRnSUdKMWFXeGtSbkpoYldVb0tTQjdYRzRnSUNBZ2RHaHBjeTVqWVc1MllYTWdQU0J1WlhjZ1pHOXRMbE50WVhKMFEyRnVkbUZ6S0hSb2FYTXVjR0Z5Wlc1MEtUdGNiaUFnSUNCMGFHbHpMbVZzWlcxbGJuUWdQU0IwYUdsekxtTmhiblpoY3k1bGJHVnRaVzUwTzF4dUlDQjlYRzVjYmlBZ2MybDZaVWx1ZEdWeVptRmpaU2dwSUh0Y2JpQWdJQ0IwYUdsekxtTmhiblpoY3k1eVpYTnBlbVVvZEdocGN5NTNhV1IwYUN4MGFHbHpMbWhsYVdkb2RDazdYRzRnSUgxY2JseHVJQ0JqYjJ4dmNrbHVkR1Z5Wm1GalpTZ3BJSHRjYmlBZ0lDQjBhR2x6TG1OaGJuWmhjeTVsYkdWdFpXNTBMbk4wZVd4bExtSmhZMnRuY205MWJtUkRiMnh2Y2lBOUlIUm9hWE11WTI5c2IzSnpMbVpwYkd3N1hHNGdJSDFjYmx4dUlDQnlaVzVrWlhJb0tTQjdYRzVjYmlBZ0lDQnBaaUFvZEdocGN5NWhZM1JwZG1VcElIdGNiaUFnSUNBZ0lISmxjWFZsYzNSQmJtbHRZWFJwYjI1R2NtRnRaU2gwYUdsekxuSmxibVJsY2k1aWFXNWtLSFJvYVhNcEtUdGNiaUFnSUNCOVhHNWNiaUFnSUNCMGFHbHpMbUZ1WVd4NWMyVnlMbWRsZEVKNWRHVkdjbVZ4ZFdWdVkzbEVZWFJoS0hSb2FYTXVaR0YwWVVGeWNtRjVLVHRjYmx4dUlDQWdJSFJvYVhNdVkyRnVkbUZ6TG1OdmJuUmxlSFF1Wm1sc2JGTjBlV3hsSUQwZ2RHaHBjeTVqYjJ4dmNuTXVabWxzYkR0Y2JpQWdJQ0IwYUdsekxtTmhiblpoY3k1amIyNTBaWGgwTG1acGJHeFNaV04wS0RBc0lEQXNJSFJvYVhNdVkyRnVkbUZ6TG1Wc1pXMWxiblF1ZDJsa2RHZ3NJSFJvYVhNdVkyRnVkbUZ6TG1Wc1pXMWxiblF1YUdWcFoyaDBLVHRjYmx4dUlDQWdJR2xtSUNoMGFHbHpMbk52ZFhKalpTQW1KaUIwYUdsekxtUmhkR0ZCY25KaGVTa2dlMXh1WEc0Z0lDQWdJQ0F2TDJOdmJuTnZiR1V1Ykc5bktIUm9hWE11WkdGMFlVRnljbUY1S1R0Y2JseHVJQ0FnSUNBZ2JHVjBJR0poY2xkcFpIUm9JRDBnS0hSb2FYTXVZMkZ1ZG1GekxtVnNaVzFsYm5RdWQybGtkR2dnTHlCMGFHbHpMbUoxWm1abGNreGxibWQwYUNrN1hHNGdJQ0FnSUNCc1pYUWdZbUZ5U0dWcFoyaDBPMXh1SUNBZ0lDQWdiR1YwSUhnZ1BTQXdPMXh1WEc0Z0lDQWdJQ0JzWlhRZ1pHVm1hVzVwZEdsdmJpQTlJSFJvYVhNdVkyRnVkbUZ6TG1Wc1pXMWxiblF1ZDJsa2RHZ3ZOVEE3WEc1Y2JpQWdJQ0FnSUdadmNpQW9iR1YwSUdrZ1BTQXdPeUJwSUR3Z2RHaHBjeTVpZFdabVpYSk1aVzVuZEdnN0lHa2dQU0JwSzJSbFptbHVhWFJwYjI0cElIdGNiaUFnSUNBZ0lDQWdZbUZ5U0dWcFoyaDBJRDBnVFdGMGFDNXRZWGd1WVhCd2JIa29iblZzYkN3Z2RHaHBjeTVrWVhSaFFYSnlZWGt1YzNWaVlYSnlZWGtvYVN4cEsyUmxabWx1YVhScGIyNHBLVHRjYmlBZ0lDQWdJQ0FnWW1GeVNHVnBaMmgwSUM4OUlESTFOVHRjYmlBZ0lDQWdJQ0FnWW1GeVNHVnBaMmgwSUNvOUlIUm9hWE11WTJGdWRtRnpMbVZzWlcxbGJuUXVhR1ZwWjJoME8xeHVYRzRnSUNBZ0lDQWdJSFJvYVhNdVkyRnVkbUZ6TG1OdmJuUmxlSFF1Wm1sc2JGTjBlV3hsSUQwZ2RHaHBjeTVqYjJ4dmNuTXVZV05qWlc1ME8xeHVJQ0FnSUNBZ0lDQjBhR2x6TG1OaGJuWmhjeTVqYjI1MFpYaDBMbVpwYkd4U1pXTjBLSGdzZEdocGN5NWpZVzUyWVhNdVpXeGxiV1Z1ZEM1b1pXbG5hSFF0WW1GeVNHVnBaMmgwTEdKaGNsZHBaSFJvS21SbFptbHVhWFJwYjI0c1ltRnlTR1ZwWjJoMEtUdGNibHh1SUNBZ0lDQWdJQ0I0SUNzOUlDaGlZWEpYYVdSMGFDcGtaV1pwYm1sMGFXOXVLVHRjYmlBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUgxY2JseHVJQ0F2S2lwY2JpQWdSWEYxYVhaaGJHVnVkQ0IwYnlCY0luQmhkR05vYVc1bklHbHVYQ0lnWVc0Z1lYVmthVzhnYm05a1pTQjBieUIyYVhOMVlXeHBlbVV1SUU1UFZFVTZJRmx2ZFNCallXNXViM1FnWTI5dWJtVmpkQ0JoZFdScGJ5QnViMlJsY3lCaFkzSnZjM01nZEhkdklHUnBabVpsY21WdWRDQmhkV1JwYnlCamIyNTBaWGgwY3k0Z1RtVjRkWE5WU1NCeWRXNXpJR2wwY3lCaGRXUnBieUJoYm1Gc2VYTnBjeUJ2YmlCcGRITWdiM2R1SUdGMVpHbHZJR052Ym5SbGVIUXNJRTVsZUhWekxtTnZiblJsZUhRdUlFbG1JSFJvWlNCaGRXUnBieUJ1YjJSbElIbHZkU0JoY21VZ2RtbHpkV0ZzYVhwcGJtY2dhWE1nWTNKbFlYUmxaQ0J2YmlCaElHUnBabVpsY21WdWRDQmhkV1JwYnlCamIyNTBaWGgwTENCNWIzVWdkMmxzYkNCdVpXVmtJSFJ2SUhSbGJHd2dUbVY0ZFhOVlNTQjBieUIxYzJVZ2RHaGhkQ0JqYjI1MFpYaDBJR2x1YzNSbFlXUTZJR2t1WlM0Z1RtVjRkWE11WTI5dWRHVjRkQ0E5SUZsdmRYSkJkV1JwYjBOdmJuUmxlSFJPWVcxbExpQkdiM0lnWlhoaGJYQnNaU3dnYVc0Z1ZHOXVaVXBUSUhCeWIycGxZM1J6TENCMGFHVWdiR2x1WlNCM2IzVnNaQ0JpWlRvZ1RtVjRkWE11WTI5dWRHVjRkQ0E5SUZSdmJtVXVZMjl1ZEdWNGRDQXVJRmRsSUhKbFkyOXRiV1Z1WkNCMGFHRjBJSGx2ZFNCM2NtbDBaU0IwYUdGMElHeHBibVVnYjJZZ1kyOWtaU0J2Ym14NUlHOXVZMlVnWVhRZ2RHaGxJR0psWjJsdWJtbHVaeUJ2WmlCNWIzVnlJSEJ5YjJwbFkzUXVYRzRnSUVCd1lYSmhiU0J1YjJSbElIdEJkV1JwYjA1dlpHVjlJRlJvWlNCaGRXUnBieUJ1YjJSbElIUnZJSFpwYzNWaGJHbDZaVnh1SUNCQVpYaGhiWEJzWlNCT1pYaDFjeTVqYjI1MFpYaDBJRDBnVkc5dVpTNWpiMjUwWlhoMElDOHZJRzl5SUdGdWIzUm9aWElnWVhWa2FXOGdZMjl1ZEdWNGRDQjViM1VnYUdGMlpTQmpjbVZoZEdWa1hHNGdJSE53WldOMGNtOW5jbUZ0TG1OdmJtNWxZM1FvSUZSdmJtVXVUV0Z6ZEdWeUlDazdYRzRnSUNvdlhHNGdJR052Ym01bFkzUW9ibTlrWlNrZ2UxeHVJQ0FnSUdsbUlDaDBhR2x6TG5OdmRYSmpaU2tnZTF4dUlDQWdJQ0FnZEdocGN5NWthWE5qYjI1dVpXTjBLQ2s3WEc0Z0lDQWdmVnh1SUNBZ0lIUm9hWE11YzI5MWNtTmxJRDBnYm05a1pUdGNiaUFnSUNCMGFHbHpMbk52ZFhKalpTNWpiMjV1WldOMEtIUm9hWE11WVc1aGJIbHpaWElwTzF4dUlDQWdJSFJvYVhNdWNtVnVaR1Z5S0NrN1hHNGdJSDFjYmx4dUlDQXZLaXBjYmlBZ1UzUnZjQ0IyYVhOMVlXeHBlbWx1WnlCMGFHVWdjMjkxY21ObElHNXZaR1VnWVc1a0lHUnBjMk52Ym01bFkzUWdhWFF1WEc0Z0lDb3ZYRzRnSUdScGMyTnZibTVsWTNRb0tTQjdYRzRnSUNBZ2RHaHBjeTV6YjNWeVkyVXVaR2x6WTI5dWJtVmpkQ2gwYUdsekxtRnVZV3g1YzJWeUtUdGNiaUFnSUNCMGFHbHpMbk52ZFhKalpTQTlJRzUxYkd3N1hHNGdJSDFjYmx4dUlDQmpiR2xqYXlncElIdGNiaUFnSUNCMGFHbHpMbUZqZEdsMlpTQTlJQ0YwYUdsekxtRmpkR2wyWlR0Y2JpQWdJQ0IwYUdsekxuSmxibVJsY2lncE8xeHVJQ0I5WEc1Y2JpQWdZM1Z6ZEc5dFJHVnpkSEp2ZVNncElIdGNiaUFnSUNCMGFHbHpMbUZqZEdsMlpTQTlJR1poYkhObE8xeHVJQ0I5WEc1Y2JuMWNibHh1WEc1Y2JpOHZJRmRGUWxCQlEwc2dSazlQVkVWU0lDOHZYRzR2THlBdUwzNHZhbk5vYVc1MExXeHZZV1JsY2lFdUwyeHBZaTlwYm5SbGNtWmhZMlZ6TDNOd1pXTjBjbTluY21GdExtcHpJaXdpSjNWelpTQnpkSEpwWTNRbk8xeHVYRzVzWlhRZ1pHOXRJRDBnY21WeGRXbHlaU2duTGk0dmRYUnBiQzlrYjIwbktUdGNibXhsZENCdFlYUm9JRDBnY21WeGRXbHlaU2duTGk0dmRYUnBiQzl0WVhSb0p5azdYRzVzWlhRZ1NXNTBaWEptWVdObElEMGdjbVZ4ZFdseVpTZ25MaTR2WTI5eVpTOXBiblJsY21aaFkyVW5LVHRjYmx4dVhHNHZLaXBjYmlvZ1RXVjBaWEpjYmlwY2Jpb2dRR1JsYzJOeWFYQjBhVzl1SUZOMFpYSmxieUJrWldOcFltVnNJRzFsZEdWeVhHNHFYRzRxSUVCa1pXMXZJRHh6Y0dGdUlHNWxlSFZ6TFhWcFBWd2liV1YwWlhKY0lqNDhMM053WVc0K1hHNHFYRzRxSUVCbGVHRnRjR3hsWEc0cUlIWmhjaUJ0WlhSbGNpQTlJRzVsZHlCT1pYaDFjeTVOWlhSbGNpZ25JM1JoY21kbGRDY3BYRzRxWEc0cUlFQmxlR0Z0Y0d4bFhHNHFJSFpoY2lCdFpYUmxjaUE5SUc1bGR5Qk9aWGgxY3k1TlpYUmxjaWduSTNSaGNtZGxkQ2NzZTF4dUtpQWdJSE5wZW1VNklGczNOU3czTlYxY2Jpb2dmU2xjYmlwY2Jpb2dRRzkxZEhCMWRGeHVLaUFtYm1KemNEdGNiaW9nVG04Z1pYWmxiblJ6WEc0cVhHNHFMMXh1WEc1cGJYQnZjblFnZXlCamIyNTBaWGgwSUgwZ1puSnZiU0FuTGk0dmJXRnBiaWM3WEc1Y2JtVjRjRzl5ZENCa1pXWmhkV3gwSUdOc1lYTnpJRTFsZEdWeUlHVjRkR1Z1WkhNZ1NXNTBaWEptWVdObElIdGNibHh1SUNCamIyNXpkSEoxWTNSdmNpZ3BJSHRjYmx4dUlDQWdJR3hsZENCdmNIUnBiMjV6SUQwZ1d5ZHpZMkZzWlNjc0ozWmhiSFZsSjEwN1hHNWNiaUFnSUNCc1pYUWdaR1ZtWVhWc2RITWdQU0I3WEc0Z0lDQWdJQ0FuYzJsNlpTYzZJRnN6TUN3eE1EQmRYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lITjFjR1Z5S0dGeVozVnRaVzUwY3l4dmNIUnBiMjV6TEdSbFptRjFiSFJ6S1R0Y2JseHVJQ0FnSUhSb2FYTXVZMjl1ZEdWNGRDQTlJR052Ym5SbGVIUW9LVHNnTHk4Z2FuTm9hVzUwSUdsbmJtOXlaVHBzYVc1bFhHNWNiaUFnSUNCMGFHbHpMbU5vWVc1dVpXeHpJRDBnTWp0Y2JseHVJQ0FnSUhSb2FYTXVjM0JzYVhSMFpYSWdQU0IwYUdsekxtTnZiblJsZUhRdVkzSmxZWFJsUTJoaGJtNWxiRk53YkdsMGRHVnlLQ0IwYUdsekxtTm9ZVzV1Wld4eklDazdYRzVjYmlBZ0lDQjBhR2x6TG1GdVlXeDVjMlZ5Y3lBOUlGdGRPMXh1WEc0Z0lDQWdabTl5SUNoc1pYUWdhVDB3T3lCcFBIUm9hWE11WTJoaGJtNWxiSE03SUdrckt5a2dlMXh1SUNBZ0lDQWdiR1YwSUdGdVlXeDVjMlZ5SUQwZ2RHaHBjeTVqYjI1MFpYaDBMbU55WldGMFpVRnVZV3g1YzJWeUtDazdYRzRnSUNBZ0lDQjBhR2x6TG5Od2JHbDBkR1Z5TG1OdmJtNWxZM1FvWVc1aGJIbHpaWElzYVNrN1hHNGdJQ0FnSUNCaGJtRnNlWE5sY2k1bVpuUlRhWHBsSUQwZ01UQXlORHRjYmlBZ0lDQWdJR0Z1WVd4NWMyVnlMbk50YjI5MGFHbHVaMVJwYldWRGIyNXpkR0Z1ZENBOUlERTdYRzRnSUNBZ0lDQjBhR2x6TG1GdVlXeDVjMlZ5Y3k1d2RYTm9LQ0JoYm1Gc2VYTmxjaUFwTzF4dUlDQWdJSDFjYmlBZ0lDQjBhR2x6TG1KMVptWmxja3hsYm1kMGFDQTlJSFJvYVhNdVlXNWhiSGx6WlhKeld6QmRMbVp5WlhGMVpXNWplVUpwYmtOdmRXNTBPMXh1SUNBZ0lIUm9hWE11WkdGMFlVRnljbUY1SUQwZ2JtVjNJRVpzYjJGME16SkJjbkpoZVNoMGFHbHpMbUoxWm1abGNreGxibWQwYUNrN1hHNWNiaThxWEc0Z0lDQWdMeThnWVdSa0lHeHBibVZoY2lCbmNtRmthV1Z1ZEZ4dUlDQWdJSFpoY2lCbmNtUWdQU0JqWVc1MllYTkRkSGd1WTNKbFlYUmxUR2x1WldGeVIzSmhaR2xsYm5Rb01Dd2dNQ3dnTUN3Z1kyRnVkbUZ6TG1obGFXZG9kQ2s3WEc0Z0lDQWdMeThnYkdsbmFIUWdZbXgxWlZ4dUlDQWdJR2R5WkM1aFpHUkRiMnh2Y2xOMGIzQW9NQ3dnSnlNd01EQW5LVHRjYmlBZ0lDQm5jbVF1WVdSa1EyOXNiM0pUZEc5d0tEQXVNaXdnSnlOaVltSW5LVHRjYmlBZ0lDQm5jbVF1WVdSa1EyOXNiM0pUZEc5d0tEQXVOQ3dnSnlOa01UZ25LVHRjYmlBZ0lDQXZMeUJrWVhKcklHSnNkV1ZjYmlBZ0lDQm5jbVF1WVdSa1EyOXNiM0pUZEc5d0tERXNJQ2NqWkRFNEp5azdYRzRnSUNBZ1kyRnVkbUZ6UTNSNExtWnBiR3hUZEhsc1pTQTlJR2R5WkRzZ0tpOWNibHh1SUNBZ0lIUm9hWE11WVdOMGFYWmxJRDBnZEhKMVpUdGNibHh1SUNBZ0lIUm9hWE11WkdJZ1BTQXRTVzVtYVc1cGRIazdYRzVjYmlBZ0lDQjBhR2x6TG1sdWFYUW9LVHRjYmx4dUlDQWdJSFJvYVhNdWJXVjBaWEpYYVdSMGFDQTlJSFJvYVhNdVkyRnVkbUZ6TG1Wc1pXMWxiblF1ZDJsa2RHZ3ZkR2hwY3k1amFHRnVibVZzY3p0Y2JseHVJQ0FnSUhSb2FYTXVjbVZ1WkdWeUtDazdYRzVjYmlBZ2ZWeHVYRzRnSUdKMWFXeGtSbkpoYldVb0tTQjdYRzRnSUNBZ2RHaHBjeTVqWVc1MllYTWdQU0J1WlhjZ1pHOXRMbE50WVhKMFEyRnVkbUZ6S0hSb2FYTXVjR0Z5Wlc1MEtUdGNiaUFnSUNCMGFHbHpMbVZzWlcxbGJuUWdQU0IwYUdsekxtTmhiblpoY3k1bGJHVnRaVzUwTzF4dUlDQjlYRzVjYmlBZ2MybDZaVWx1ZEdWeVptRmpaU2dwSUh0Y2JpQWdJQ0IwYUdsekxtTmhiblpoY3k1eVpYTnBlbVVvZEdocGN5NTNhV1IwYUN4MGFHbHpMbWhsYVdkb2RDazdYRzRnSUgxY2JseHVJQ0JqYjJ4dmNrbHVkR1Z5Wm1GalpTZ3BJSHRjYmlBZ0lDQjBhR2x6TG1OaGJuWmhjeTVsYkdWdFpXNTBMbk4wZVd4bExtSmhZMnRuY205MWJtUkRiMnh2Y2lBOUlIUm9hWE11WTI5c2IzSnpMbVpwYkd3N1hHNGdJSDFjYmx4dUlDQnlaVzVrWlhJb0tTQjdYRzVjYmlBZ0lDQnBaaUFvZEdocGN5NWhZM1JwZG1VcElIdGNiaUFnSUNBZ0lISmxjWFZsYzNSQmJtbHRZWFJwYjI1R2NtRnRaU2gwYUdsekxuSmxibVJsY2k1aWFXNWtLSFJvYVhNcEtUdGNiaUFnSUNCOVhHNWNiaUFnSUNCMGFHbHpMbU5oYm5aaGN5NWpiMjUwWlhoMExtWnBiR3hUZEhsc1pTQTlJSFJvYVhNdVkyOXNiM0p6TG1acGJHdzdYRzRnSUNBZ2RHaHBjeTVqWVc1MllYTXVZMjl1ZEdWNGRDNW1hV3hzVW1WamRDZ3dMQ0F3TENCMGFHbHpMbU5oYm5aaGN5NWxiR1Z0Wlc1MExuZHBaSFJvSUN3Z2RHaHBjeTVqWVc1MllYTXVaV3hsYldWdWRDNW9aV2xuYUhRcE8xeHVYRzRnSUNBZ1ptOXlJQ2hzWlhRZ2FUMHdPMms4ZEdocGN5NWhibUZzZVhObGNuTXViR1Z1WjNSb08ya3JLeWtnZTF4dVhHNGdJQ0FnSUNCcFppQW9kR2hwY3k1emIzVnlZMlVwSUh0Y2JseHVJQ0FnSUNBZ0lDQjBhR2x6TG1GdVlXeDVjMlZ5YzF0cFhTNW5aWFJHYkc5aGRGUnBiV1ZFYjIxaGFXNUVZWFJoS0hSb2FYTXVaR0YwWVVGeWNtRjVLVHRjYmx4dUlDQWdJQ0FnSUNCc1pYUWdjbTF6SUQwZ01EdGNibHh1SUNBZ0lDQWdJQ0JtYjNJZ0tHeGxkQ0JwSUQwZ01Ec2dhU0E4SUhSb2FYTXVaR0YwWVVGeWNtRjVMbXhsYm1kMGFEc2dhU3NyS1h0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0J5YlhNZ0t6MGdLSFJvYVhNdVpHRjBZVUZ5Y21GNVcybGRJQ29nZEdocGN5NWtZWFJoUVhKeVlYbGJhVjBwTzF4dUlDQWdJQ0FnSUNCOVhHNWNiaUFnSUNBZ0lDQWdjbTF6SUQwZ1RXRjBhQzV6Y1hKMEtISnRjeUF2SUhSb2FYTXVaR0YwWVVGeWNtRjVMbXhsYm1kMGFDazdYRzVjYmlBZ0lDQWdJQ0FnZEdocGN5NWtZaUE5SURJd0lDb2dUV0YwYUM1c2IyY3hNQ2h5YlhNcE8xeHVYRzRnSUNBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFJvYVhNdVpHSWdQaUF0TWpBd0lDWW1JSFJvYVhNdVpHSWdJVDA5SUMxSmJtWnBibWwwZVNrZ2UxeHVJQ0FnSUNBZ0lDQjBhR2x6TG1SaUlDMDlJREU3WEc0Z0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0IwYUdsekxtUmlJRDBnTFVsdVptbHVhWFI1TzF4dUlDQWdJQ0FnZlZ4dVhHNWNiaUFnSUNBZ0lDOHZZMjl1YzI5c1pTNXNiMmNvWkdJcFhHNWNiaUFnSUNBZ0lHbG1JQ2gwYUdsekxtUmlJRDRnTFRjd0tTQjdYRzVjYmlBZ0lDQWdJQ0FnYkdWMElHeHBibVZoY2lBOUlHMWhkR2d1Ym05eWJXRnNhWHBsS0hSb2FYTXVaR0lzTFRjd0xEVXBPMXh1SUNBZ0lDQWdJQ0JzWlhRZ1pYaHdJRDBnYkdsdVpXRnlJQ29nYkdsdVpXRnlPMXh1SUNBZ0lDQWdJQ0JzWlhRZ2VTQTlJRzFoZEdndWMyTmhiR1VvWlhod0xEQXNNU3gwYUdsekxtVnNaVzFsYm5RdWFHVnBaMmgwTERBcE8xeHVYRzRnSUNBZ0lDQWdJSFJvYVhNdVkyRnVkbUZ6TG1OdmJuUmxlSFF1Wm1sc2JGTjBlV3hsSUQwZ2RHaHBjeTVqYjJ4dmNuTXVZV05qWlc1ME8xeHVJQ0FnSUNBZ0lDQjBhR2x6TG1OaGJuWmhjeTVqYjI1MFpYaDBMbVpwYkd4U1pXTjBLSFJvYVhNdWJXVjBaWEpYYVdSMGFDcHBMSGtzZEdocGN5NXRaWFJsY2xkcFpIUm9MSFJvYVhNdVkyRnVkbUZ6TG1Wc1pXMWxiblF1YUdWcFoyaDBJQzBnZVNrN1hHNWNiaUFnSUNBZ0lDQWdMeTlqYjI1emIyeGxMbXh2WnloY0luSmxibVJsY21sdVp5NHVMbHdpS1Z4dVhHNGdJQ0FnSUNCOVhHNWNiaUFnSUNCOVhHNWNiaUFnZlZ4dVhHNGdJQzhxS2x4dUlDQkZjWFZwZG1Gc1pXNTBJSFJ2SUZ3aWNHRjBZMmhwYm1jZ2FXNWNJaUJoYmlCaGRXUnBieUJ1YjJSbElIUnZJSFpwYzNWaGJHbDZaUzRnVGs5VVJUb2dXVzkxSUdOaGJtNXZkQ0JqYjI1dVpXTjBJR0YxWkdsdklHNXZaR1Z6SUdGamNtOXpjeUIwZDI4Z1pHbG1abVZ5Wlc1MElHRjFaR2x2SUdOdmJuUmxlSFJ6TGlCT1pYaDFjMVZKSUhKMWJuTWdhWFJ6SUdGMVpHbHZJR0Z1WVd4NWMybHpJRzl1SUdsMGN5QnZkMjRnWVhWa2FXOGdZMjl1ZEdWNGRDd2dUbVY0ZFhNdVkyOXVkR1Y0ZEM0Z1NXWWdkR2hsSUdGMVpHbHZJRzV2WkdVZ2VXOTFJR0Z5WlNCMmFYTjFZV3hwZW1sdVp5QnBjeUJqY21WaGRHVmtJRzl1SUdFZ1pHbG1abVZ5Wlc1MElHRjFaR2x2SUdOdmJuUmxlSFFzSUhsdmRTQjNhV3hzSUc1bFpXUWdkRzhnZEdWc2JDQk9aWGgxYzFWSklIUnZJSFZ6WlNCMGFHRjBJR052Ym5SbGVIUWdhVzV6ZEdWaFpEb2dhUzVsTGlCT1pYaDFjeTVqYjI1MFpYaDBJRDBnV1c5MWNrRjFaR2x2UTI5dWRHVjRkRTVoYldVdUlFWnZjaUJsZUdGdGNHeGxMQ0JwYmlCVWIyNWxTbE1nY0hKdmFtVmpkSE1zSUhSb1pTQnNhVzVsSUhkdmRXeGtJR0psT2lCT1pYaDFjeTVqYjI1MFpYaDBJRDBnVkc5dVpTNWpiMjUwWlhoMElDNGdWMlVnY21WamIyMXRaVzVrSUhSb1lYUWdlVzkxSUhkeWFYUmxJSFJvWVhRZ2JHbHVaU0J2WmlCamIyUmxJRzl1YkhrZ2IyNWpaU0JoZENCMGFHVWdZbVZuYVc1dWFXNW5JRzltSUhsdmRYSWdjSEp2YW1WamRDNWNiaUFnUUhCaGNtRnRJRzV2WkdVZ2UwRjFaR2x2VG05a1pYMGdWR2hsSUdGMVpHbHZJRzV2WkdVZ2RHOGdkbWx6ZFdGc2FYcGxYRzRnSUVCd1lYSmhiU0JqYUdGdWJtVnNjeUI3Ym5WdFltVnlmU0FvYjNCMGFXOXVZV3dwSUZSb1pTQnVkVzFpWlhJZ2IyWWdZMmhoYm01bGJITWdhVzRnZEdobElITnZkWEpqWlNCdWIyUmxJSFJ2SUhkaGRHTm9MaUJKWmlCdWIzUWdjM0JsWTJsbWFXVmtMQ0IwYUdVZ2FXNTBaWEptWVdObElIZHBiR3dnYkc5dmF5Qm1iM0lnWVNBdVkyaGhibTVsYkVOdmRXNTBJSEJ5YjNCbGNuUjVJRzl1SUhSb1pTQnBibkIxZENCdWIyUmxMaUJKWmlCcGRDQmtiMlZ6SUc1dmRDQmxlR2x6ZEN3Z2RHaGxJR2x1ZEdWeVptRmpaU0IzYVd4c0lHUmxabUYxYkhRZ2RHOGdNU0JqYUdGdWJtVnNMbHh1SUNCQVpYaGhiWEJzWlNCT1pYaDFjeTVqYjI1MFpYaDBJRDBnVkc5dVpTNWpiMjUwWlhoMElDOHZJRzl5SUdGdWIzUm9aWElnWVhWa2FXOGdZMjl1ZEdWNGRDQjViM1VnYUdGMlpTQmpjbVZoZEdWa1hHNGdJRzFsZEdWeUxtTnZibTVsWTNRb0lGUnZibVV1VFdGemRHVnlMQ0F5SUNrN1hHNGdJQ292WEc1Y2JpQWdZMjl1Ym1WamRDaHViMlJsTEdOb1lXNXVaV3h6S1NCN1hHNGdJQ0FnYVdZZ0tIUm9hWE11YzI5MWNtTmxLU0I3WEc0Z0lDQWdJQ0IwYUdsekxtUnBjMk52Ym01bFkzUW9LVHRjYmlBZ0lDQjlYRzRnSUNBZ0x5OTBhR2x6TG1SMWJXMTVMbVJwYzJOdmJtNWxZM1FvZEdocGN5NXpjR3hwZEhSbGNpazdYRzVjYmlBZ0lDQnBaaUFvWTJoaGJtNWxiSE1wSUh0Y2JpQWdJQ0FnSUhSb2FYTXVZMmhoYm01bGJITWdQU0JqYUdGdWJtVnNjenRjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLRzV2WkdVdVkyaGhibTVsYkVOdmRXNTBLU0I3WEc0Z0lDQWdJQ0IwYUdsekxtTm9ZVzV1Wld4eklEMGdibTlrWlM1amFHRnVibVZzUTI5MWJuUTdYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUhSb2FYTXVZMmhoYm01bGJITWdQU0F5TzF4dUlDQWdJSDFjYmlBZ0lDQjBhR2x6TG0xbGRHVnlWMmxrZEdnZ1BTQjBhR2x6TG1OaGJuWmhjeTVsYkdWdFpXNTBMbmRwWkhSb0wzUm9hWE11WTJoaGJtNWxiSE03WEc1Y2JpQWdJQ0IwYUdsekxuTnZkWEpqWlNBOUlHNXZaR1U3WEc0Z0lDQWdkR2hwY3k1emIzVnlZMlV1WTI5dWJtVmpkQ2gwYUdsekxuTndiR2wwZEdWeUtUdGNibHh1SUNBdkx5QWdkR2hwY3k1eVpXNWtaWElvS1R0Y2JpQWdmVnh1WEc0Z0lDOHFLbHh1SUNCVGRHOXdJSFpwYzNWaGJHbDZhVzVuSUhSb1pTQnpiM1Z5WTJVZ2JtOWtaU0JoYm1RZ1pHbHpZMjl1Ym1WamRDQnBkQzVjYmlBZ0tpOWNiaUFnWkdselkyOXVibVZqZENncElIdGNibHh1SUNBZ0lIUm9hWE11YzI5MWNtTmxMbVJwYzJOdmJtNWxZM1FvZEdocGN5NXpjR3hwZEhSbGNpazdYRzRnSUNBZ2RHaHBjeTV6YjNWeVkyVWdQU0JtWVd4elpUdGNiaUFnTHk4Z0lIUm9hWE11WkhWdGJYa3VZMjl1Ym1WamRDaDBhR2x6TG5Od2JHbDBkR1Z5S1R0Y2JpQWdJQ0IwYUdsekxtMWxkR1Z5VjJsa2RHZ2dQU0IwYUdsekxtTmhiblpoY3k1bGJHVnRaVzUwTG5kcFpIUm9MM1JvYVhNdVkyaGhibTVsYkhNN1hHNWNiaUFnZlZ4dVhHNGdJR05zYVdOcktDa2dlMXh1SUNBZ0lIUm9hWE11WVdOMGFYWmxJRDBnSVhSb2FYTXVZV04wYVhabE8xeHVJQ0FnSUhSb2FYTXVjbVZ1WkdWeUtDazdYRzRnSUgxY2JseHVJQ0JqZFhOMGIyMUVaWE4wY205NUtDa2dlMXh1SUNBZ0lIUm9hWE11WVdOMGFYWmxJRDBnWm1Gc2MyVTdYRzRnSUgxY2JseHVmVnh1WEc1Y2JseHVMeThnVjBWQ1VFRkRTeUJHVDA5VVJWSWdMeTljYmk4dklDNHZmaTlxYzJocGJuUXRiRzloWkdWeUlTNHZiR2xpTDJsdWRHVnlabUZqWlhNdmJXVjBaWEl1YW5NaUxDSW5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JteGxkQ0JrYjIwZ1BTQnlaWEYxYVhKbEtDY3VMaTkxZEdsc0wyUnZiU2NwTzF4dWJHVjBJRWx1ZEdWeVptRmpaU0E5SUhKbGNYVnBjbVVvSnk0dUwyTnZjbVV2YVc1MFpYSm1ZV05sSnlrN1hHNWNiaThxS2x4dUtpQlBjMk5wYkd4dmMyTnZjR1ZjYmlwY2Jpb2dRR1JsYzJOeWFYQjBhVzl1SUZacGMzVmhiR2w2WlhNZ1lTQjNZWFpsWm05eWJTZHpJSE4wY21WaGJTQnZaaUIyWVd4MVpYTXVYRzRxWEc0cUlFQmtaVzF2SUR4emNHRnVJRzVsZUhWekxYVnBQVndpYjNOamFXeHNiM05qYjNCbFhDSStQQzl6Y0dGdVBseHVLbHh1S2lCQVpYaGhiWEJzWlZ4dUtpQjJZWElnYjNOamFXeHNiM05qYjNCbElEMGdibVYzSUU1bGVIVnpMazl6WTJsc2JHOXpZMjl3WlNnbkkzUmhjbWRsZENjcFhHNHFYRzRxSUVCbGVHRnRjR3hsWEc0cUlIWmhjaUJ2YzJOcGJHeHZjMk52Y0dVZ1BTQnVaWGNnVG1WNGRYTXVUM05qYVd4c2IzTmpiM0JsS0NjamRHRnlaMlYwSnl4N1hHNHFJQ0FnSjNOcGVtVW5PaUJiTXpBd0xERTFNRjFjYmlvZ2ZTbGNiaXBjYmlvZ1FHOTFkSEIxZEZ4dUtpQW1ibUp6Y0R0Y2Jpb2dUbThnWlhabGJuUnpYRzRxWEc0cUwxeHVYRzVwYlhCdmNuUWdleUJqYjI1MFpYaDBJSDBnWm5KdmJTQW5MaTR2YldGcGJpYzdYRzVjYm1WNGNHOXlkQ0JrWldaaGRXeDBJR05zWVhOeklFOXpZMmxzYkc5elkyOXdaU0JsZUhSbGJtUnpJRWx1ZEdWeVptRmpaU0I3WEc1Y2JpQWdZMjl1YzNSeWRXTjBiM0lvS1NCN1hHNWNiaUFnSUNCc1pYUWdiM0IwYVc5dWN5QTlJRnNuYzJOaGJHVW5MQ2QyWVd4MVpTZGRPMXh1WEc0Z0lDQWdiR1YwSUdSbFptRjFiSFJ6SUQwZ2UxeHVJQ0FnSUNBZ0ozTnBlbVVuT2lCYk16QXdMREUxTUYxY2JpQWdJQ0I5TzF4dVhHNGdJQ0FnYzNWd1pYSW9ZWEpuZFcxbGJuUnpMRzl3ZEdsdmJuTXNaR1ZtWVhWc2RITXBPMXh1WEc0Z0lDQWdkR2hwY3k1amIyNTBaWGgwSUQwZ1kyOXVkR1Y0ZENncE95QXZMeUJxYzJocGJuUWdhV2R1YjNKbE9teHBibVZjYmx4dUlDQWdJSFJvYVhNdVlXNWhiSGx6WlhJZ1BTQjBhR2x6TG1OdmJuUmxlSFF1WTNKbFlYUmxRVzVoYkhselpYSW9LVHRjYmlBZ0lDQjBhR2x6TG1GdVlXeDVjMlZ5TG1abWRGTnBlbVVnUFNBeU1EUTRPMXh1SUNBZ0lIUm9hWE11WW5WbVptVnlUR1Z1WjNSb0lEMGdkR2hwY3k1aGJtRnNlWE5sY2k1bWNtVnhkV1Z1WTNsQ2FXNURiM1Z1ZER0Y2JpQWdJQ0IwYUdsekxtUmhkR0ZCY25KaGVTQTlJRzVsZHlCVmFXNTBPRUZ5Y21GNUtIUm9hWE11WW5WbVptVnlUR1Z1WjNSb0tUdGNiaUFnSUNCMGFHbHpMbUZ1WVd4NWMyVnlMbWRsZEVKNWRHVlVhVzFsUkc5dFlXbHVSR0YwWVNoMGFHbHpMbVJoZEdGQmNuSmhlU2s3WEc1Y2JpQWdJQ0IwYUdsekxtRmpkR2wyWlNBOUlIUnlkV1U3WEc1Y2JpQWdJQ0IwYUdsekxuTnZkWEpqWlNBOUlHWmhiSE5sTzF4dVhHNGdJQ0FnZEdocGN5NXBibWwwS0NrN1hHNWNiaUFnSUNCMGFHbHpMbkpsYm1SbGNpZ3BPMXh1SUNCOVhHNWNiaUFnWW5WcGJHUkdjbUZ0WlNncElIdGNiaUFnSUNCMGFHbHpMbU5oYm5aaGN5QTlJRzVsZHlCa2IyMHVVMjFoY25SRFlXNTJZWE1vZEdocGN5NXdZWEpsYm5RcE8xeHVJQ0FnSUhSb2FYTXVaV3hsYldWdWRDQTlJSFJvYVhNdVkyRnVkbUZ6TG1Wc1pXMWxiblE3WEc0Z0lIMWNibHh1SUNCemFYcGxTVzUwWlhKbVlXTmxLQ2tnZTF4dUlDQWdJSFJvYVhNdVkyRnVkbUZ6TG5KbGMybDZaU2gwYUdsekxuZHBaSFJvTEhSb2FYTXVhR1ZwWjJoMEtUdGNiaUFnZlZ4dVhHNGdJR052Ykc5eVNXNTBaWEptWVdObEtDa2dlMXh1SUNBZ0lIUm9hWE11WTJGdWRtRnpMbVZzWlcxbGJuUXVjM1I1YkdVdVltRmphMmR5YjNWdVpFTnZiRzl5SUQwZ2RHaHBjeTVqYjJ4dmNuTXVabWxzYkR0Y2JpQWdmVnh1WEc0Z0lISmxibVJsY2lncElIdGNibHh1SUNBZ0lHbG1JQ2gwYUdsekxtRmpkR2wyWlNrZ2UxeHVJQ0FnSUNBZ2NtVnhkV1Z6ZEVGdWFXMWhkR2x2YmtaeVlXMWxLSFJvYVhNdWNtVnVaR1Z5TG1KcGJtUW9kR2hwY3lrcE8xeHVJQ0FnSUgxY2JseHVJQ0FnSUhSb2FYTXVZVzVoYkhselpYSXVaMlYwUW5sMFpWUnBiV1ZFYjIxaGFXNUVZWFJoS0hSb2FYTXVaR0YwWVVGeWNtRjVLVHRjYmx4dUlDQWdJSFJvYVhNdVkyRnVkbUZ6TG1OdmJuUmxlSFF1Wm1sc2JGTjBlV3hsSUQwZ2RHaHBjeTVqYjJ4dmNuTXVabWxzYkR0Y2JpQWdJQ0IwYUdsekxtTmhiblpoY3k1amIyNTBaWGgwTG1acGJHeFNaV04wS0RBc0lEQXNJSFJvYVhNdVkyRnVkbUZ6TG1Wc1pXMWxiblF1ZDJsa2RHZ3NJSFJvYVhNdVkyRnVkbUZ6TG1Wc1pXMWxiblF1YUdWcFoyaDBLVHRjYmx4dUlDQWdJSFJvYVhNdVkyRnVkbUZ6TG1OdmJuUmxlSFF1YkdsdVpWZHBaSFJvSUQwZ2ZuNG9kR2hwY3k1b1pXbG5hSFFnTHlBeE1EQWdLeUF5S1R0Y2JpQWdJQ0IwYUdsekxtTmhiblpoY3k1amIyNTBaWGgwTG5OMGNtOXJaVk4wZVd4bElEMGdkR2hwY3k1amIyeHZjbk11WVdOalpXNTBPMXh1WEc0Z0lDQWdkR2hwY3k1allXNTJZWE11WTI5dWRHVjRkQzVpWldkcGJsQmhkR2dvS1R0Y2JseHVJQ0FnSUdsbUlDaDBhR2x6TG5OdmRYSmpaU2tnZTF4dVhHNGdJQ0FnSUNCMllYSWdjMnhwWTJWWGFXUjBhQ0E5SUhSb2FYTXVZMkZ1ZG1GekxtVnNaVzFsYm5RdWQybGtkR2dnS2lBeExqQWdMeUIwYUdsekxtSjFabVpsY2t4bGJtZDBhRHRjYmlBZ0lDQWdJSFpoY2lCNElEMGdNRHRjYmx4dUlDQWdJQ0FnWm05eUlDaDJZWElnYVNBOUlEQTdJR2tnUENCMGFHbHpMbUoxWm1abGNreGxibWQwYURzZ2FTc3JLU0I3WEc1Y2JpQWdJQ0FnSUNBZ2RtRnlJSFlnUFNCMGFHbHpMbVJoZEdGQmNuSmhlVnRwWFNBdklERXlPQzR3TzF4dUlDQWdJQ0FnSUNCMllYSWdlU0E5SUhZZ0tpQjBhR2x6TG1OaGJuWmhjeTVsYkdWdFpXNTBMbWhsYVdkb2RDQXZJREk3WEc1Y2JpQWdJQ0FnSUNBZ2FXWWdLR2tnUFQwOUlEQXBJSHRjYmlBZ0lDQWdJQ0FnSUNCMGFHbHpMbU5oYm5aaGN5NWpiMjUwWlhoMExtMXZkbVZVYnloNExDQjVLVHRjYmlBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNCMGFHbHpMbU5oYm5aaGN5NWpiMjUwWlhoMExteHBibVZVYnloNExDQjVLVHRjYmlBZ0lDQWdJQ0FnZlZ4dVhHNGdJQ0FnSUNBZ0lIZ2dLejBnYzJ4cFkyVlhhV1IwYUR0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0IwYUdsekxtTmhiblpoY3k1amIyNTBaWGgwTG0xdmRtVlVieWd3TENCMGFHbHpMbU5oYm5aaGN5NWxiR1Z0Wlc1MExtaGxhV2RvZEM4eUtUdGNiaUFnSUNBZ0lDQWdkR2hwY3k1allXNTJZWE11WTI5dWRHVjRkQzVzYVc1bFZHOG9kR2hwY3k1allXNTJZWE11Wld4bGJXVnVkQzUzYVdSMGFDd2dkR2hwY3k1allXNTJZWE11Wld4bGJXVnVkQzVvWldsbmFIUXZNaWs3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdkR2hwY3k1allXNTJZWE11WTI5dWRHVjRkQzV6ZEhKdmEyVW9LVHRjYmlBZ2ZWeHVYRzRnSUM4cUtseHVJQ0JGY1hWcGRtRnNaVzUwSUhSdklGd2ljR0YwWTJocGJtY2dhVzVjSWlCaGJpQmhkV1JwYnlCdWIyUmxJSFJ2SUhacGMzVmhiR2w2WlM0Z1RrOVVSVG9nV1c5MUlHTmhibTV2ZENCamIyNXVaV04wSUdGMVpHbHZJRzV2WkdWeklHRmpjbTl6Y3lCMGQyOGdaR2xtWm1WeVpXNTBJR0YxWkdsdklHTnZiblJsZUhSekxpQk9aWGgxYzFWSklISjFibk1nYVhSeklHRjFaR2x2SUdGdVlXeDVjMmx6SUc5dUlHbDBjeUJ2ZDI0Z1lYVmthVzhnWTI5dWRHVjRkQ3dnVG1WNGRYTXVZMjl1ZEdWNGRDNGdTV1lnZEdobElHRjFaR2x2SUc1dlpHVWdlVzkxSUdGeVpTQjJhWE4xWVd4cGVtbHVaeUJwY3lCamNtVmhkR1ZrSUc5dUlHRWdaR2xtWm1WeVpXNTBJR0YxWkdsdklHTnZiblJsZUhRc0lIbHZkU0IzYVd4c0lHNWxaV1FnZEc4Z2RHVnNiQ0JPWlhoMWMxVkpJSFJ2SUhWelpTQjBhR0YwSUdOdmJuUmxlSFFnYVc1emRHVmhaRG9nYVM1bExpQk9aWGgxY3k1amIyNTBaWGgwSUQwZ1dXOTFja0YxWkdsdlEyOXVkR1Y0ZEU1aGJXVXVJRVp2Y2lCbGVHRnRjR3hsTENCcGJpQlViMjVsU2xNZ2NISnZhbVZqZEhNc0lIUm9aU0JzYVc1bElIZHZkV3hrSUdKbE9pQk9aWGgxY3k1amIyNTBaWGgwSUQwZ1ZHOXVaUzVqYjI1MFpYaDBJQzRnVjJVZ2NtVmpiMjF0Wlc1a0lIUm9ZWFFnZVc5MUlIZHlhWFJsSUhSb1lYUWdiR2x1WlNCdlppQmpiMlJsSUc5dWJIa2diMjVqWlNCaGRDQjBhR1VnWW1WbmFXNXVhVzVuSUc5bUlIbHZkWElnY0hKdmFtVmpkQzVjYmlBZ1FIQmhjbUZ0SUc1dlpHVWdlMEYxWkdsdlRtOWtaWDBnVkdobElHRjFaR2x2SUc1dlpHVWdkRzhnZG1semRXRnNhWHBsWEc0Z0lFQmxlR0Z0Y0d4bElFNWxlSFZ6TG1OdmJuUmxlSFFnUFNCVWIyNWxMbU52Ym5SbGVIUWdMeThnYjNJZ1lXNXZkR2hsY2lCaGRXUnBieUJqYjI1MFpYaDBJSGx2ZFNCb1lYWmxJR055WldGMFpXUmNiaUFnYjNOamFXeHNiM05qYjNCbExtTnZibTVsWTNRb0lGUnZibVV1VFdGemRHVnlJQ2s3WEc0Z0lDb3ZYRzVjYmlBZ1kyOXVibVZqZENodWIyUmxLU0I3WEc1Y2JpQWdJQ0JwWmlBb2RHaHBjeTV6YjNWeVkyVXBJSHRjYmlBZ0lDQWdJSFJvYVhNdVpHbHpZMjl1Ym1WamRDZ3BPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIUm9hWE11YzI5MWNtTmxJRDBnYm05a1pUdGNiaUFnSUNCMGFHbHpMbk52ZFhKalpTNWpiMjV1WldOMEtIUm9hWE11WVc1aGJIbHpaWElwTzF4dVhHNGdJQ0FnZEdocGN5NXlaVzVrWlhJb0tUdGNiaUFnZlZ4dVhHNGdJQzhxS2x4dUlDQlRkRzl3SUhacGMzVmhiR2w2YVc1bklIUm9aU0J6YjNWeVkyVWdibTlrWlNCaGJtUWdaR2x6WTI5dWJtVmpkQ0JwZEM1Y2JpQWdLaTljYmlBZ1pHbHpZMjl1Ym1WamRDZ3BJSHRjYmlBZ0lDQnBaaUFvZEdocGN5NXpiM1Z5WTJVcElIdGNiaUFnSUNBZ0lIUm9hWE11YzI5MWNtTmxMbVJwYzJOdmJtNWxZM1FvZEdocGN5NWhibUZzZVhObGNpazdYRzRnSUNBZ0lDQjBhR2x6TG5OdmRYSmpaU0E5SUc1MWJHdzdYRzRnSUNBZ2ZWeHVYRzRnSUgxY2JseHVJQ0JqYkdsamF5Z3BJSHRjYmlBZ0lDQjBhR2x6TG1GamRHbDJaU0E5SUNGMGFHbHpMbUZqZEdsMlpUdGNiaUFnSUNCMGFHbHpMbkpsYm1SbGNpZ3BPMXh1SUNCOVhHNWNiaUFnWTNWemRHOXRSR1Z6ZEhKdmVTZ3BJSHRjYmlBZ0lDQjBhR2x6TG1GamRHbDJaU0E5SUdaaGJITmxPMXh1SUNCOVhHNWNibjFjYmx4dVhHNWNiaTh2SUZkRlFsQkJRMHNnUms5UFZFVlNJQzh2WEc0dkx5QXVMMzR2YW5Ob2FXNTBMV3h2WVdSbGNpRXVMMnhwWWk5cGJuUmxjbVpoWTJWekwyOXpZMmxzYkc5elkyOXdaUzVxY3lJc0lpOHFYRzVOWVdsdUlHTnZibU5sY0hRNlhHNXplVzUwYUNBOUlHNWxkeUJPWlhoMWN5NVNZV05yS0NkbGJHVnRaVzUwU1VRbktUdGNibHh1VkhKaGJuTm1iM0p0SUdGc2JDQmxiR1Z0Wlc1MGN5QnBibk5wWkdVZ2RHaGxJR1JwZGx4dWMzbHVkR2d1Wld4bGJXVnVkRWxFSUhkcGJHd2dhRzlzWkNCMGFHVWdabWx5YzNRZ2MyeHBaR1Z5SUdsdWRHVnlabUZqWlZ4dVhHNHlLU0JKYmlCbWRYUjFjbVVzSUhCdmRHVnVkR2xoYkd4NUlIZHlhWFJwYm1jZ1lTQnlZV05ySUhSb1lYUWdhWE1nY21VdGRYTmhZbXhsUDF4dVEyOTFiR1FnWVd4emJ5QjBZV3RsSUVwVFQwNWNibHh1Ym1WM0lFNWxlSFZ6TGxKaFkyc29KeU4wWVhKblpYUW5MSHRjYmlBZ2NISmxPaUFvS1NBOVBpQjdYRzRnSUNBZ1kzSmxZWFJsSUhOdmJXVWdaR2wyY3lCb1pYSmxMQ0J2Y2lCemIyMWxJR0YxWkdsdklHTnZaR1ZjYmlBZ2ZTeGNiaUFnYVc1MFpYSm1ZV05sT2lCN1hHNGdJQ0FnYzJ4cFpHVnlNVG9nVG1WNGRYTXVZV1JrTG5Oc2FXUmxjaWg3WEc0Z0lDQWdJQ0IwYjNBNk1UQXNYRzRnSUNBZ0lDQnNaV1owT2pFd0xGeHVJQ0FnSUNBZ2QybGtkR2c2TlRBc1hHNGdJQ0FnSUNCb1pXbG5hSFE2TVRBd0xGeHVJQ0FnSUNBZ2JXbHVPaUF3TEZ4dUlDQWdJQ0FnYldGNE9pQXhNREFzWEc0Z0lDQWdJQ0J6ZEdWd09pQXhYRzRnSUNBZ2ZTa3NYRzRnSUNBZ2QyRjJaVEU2SUU1bGVIVnpMbUZrWkM1M1lYWmxabTl5YlNoN1hHNGdJQ0FnSUNCbWFXeGxPaUFuTGk5d1lYUm9MM1J2TDJacGJHVXViWEF6Snl4Y2JpQWdJQ0FnSUhkcFpIUm9PalV3TUN4Y2JpQWdJQ0FnSUdobGFXZG9kRG94TURBc1hHNGdJQ0FnSUNCdGIyUmxPaUFuY21GdVoyVW5YRzRnSUNBZ2ZTbGNiaUFnZlN4Y2JpQWdhVzVwZERvZ0tDa2dQVDRnZTF4dUlDQWdJQzh2SUhOdmJXVWdZWFZrYVc4Z2FXNXBkQ0JqYjJSbElHZHZaWE1nYUdWeVpTNHVMbHh1SUNCOVhHNTlLVHRjYmx4dUtpOWNibHh1YVcxd2IzSjBJQ29nWVhNZ2RISmhibk5tYjNKdElHWnliMjBnSnk0dUwzVjBhV3d2ZEhKaGJuTm1iM0p0Snp0Y2JtbHRjRzl5ZENCa2IyMGdabkp2YlNBbkxpNHZkWFJwYkM5a2IyMG5PMXh1WEc1cGJYQnZjblFnZXlCamIyeHZjbk1nZlNCbWNtOXRJQ2N1TGk5dFlXbHVKenRjYmx4dVpYaHdiM0owSUdSbFptRjFiSFFnWTJ4aGMzTWdVbUZqYXlCN1hHNWNiaUFnWTI5dWMzUnlkV04wYjNJb2RHRnlaMlYwTENCelpYUjBhVzVuY3lrZ2UxeHVYRzRnSUNBZ2RHaHBjeTV0WlhSaElEMGdlMzA3WEc0Z0lDQWdkR2hwY3k1dFpYUmhMblJoY21kbGRDQTlJSFJoY21kbGREdGNiaUFnSUNCMGFHbHpMbTFsZEdFdWNHRnlaVzUwSUQwZ1pHOXRMbkJoY25ObFJXeGxiV1Z1ZENoMFlYSm5aWFFwT3lBdkx5QnphRzkxYkdRZ1ltVWdZU0JuWlc1bGNtbGpJR1oxYm1OMGFXOXVJR1p2Y2lCd1lYSnphVzVuSUdFZ0ozUmhjbWRsZENjZ1lYSm5kVzFsYm5RZ2RHaGhkQ0JqYUdWamEzTWdabTl5SUhOMGNtbHVaeTlFVDAwdmFsRlZSVkpaWEc0Z0lDQWdkR2hwY3k1dFpYUmhMbU52Ykc5eWN5QTlJSHQ5TzF4dVhHNGdJQ0FnYVdZZ0tITmxkSFJwYm1kektTQjdYRzRnSUNBZ0lDQjBhR2x6TG0xbGRHRXVZWFIwY21saWRYUmxJRDBnYzJWMGRHbHVaM011WVhSMGNtbGlkWFJsSUh4OElDZHVaWGgxY3kxMWFTYzdYRzRnSUNBZ0lDQjBhR2x6TG0xbGRHRXVkR2wwYkdVZ1BTQnpaWFIwYVc1bmN5NXVZVzFsSUh4OElHWmhiSE5sTzF4dUlDQWdJQ0FnZEdocGN5NXRaWFJoTG05d1pXNGdQU0J6WlhSMGFXNW5jeTV2Y0dWdUlIeDhJR1poYkhObE8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0IwYUdsekxtMWxkR0V1WVhSMGNtbGlkWFJsSUQwZ0oyNWxlSFZ6TFhWcEp6dGNiaUFnSUNBZ0lIUm9hWE11YldWMFlTNTBhWFJzWlNBOUlHWmhiSE5sTzF4dUlDQWdJQ0FnZEdocGN5NXRaWFJoTG05d1pXNGdQU0JtWVd4elpUdGNiaUFnSUNCOVhHNWNiaUFnSUNCc1pYUWdaR1ZtWVhWc2RFTnZiRzl5Y3lBOUlHTnZiRzl5Y3lncE95QXZMeUJxYzJocGJuUWdhV2R1YjNKbE9teHBibVZjYmlBZ0lDQjBhR2x6TG0xbGRHRXVZMjlzYjNKekxtRmpZMlZ1ZENBOUlHUmxabUYxYkhSRGIyeHZjbk11WVdOalpXNTBPMXh1SUNBZ0lIUm9hWE11YldWMFlTNWpiMnh2Y25NdVptbHNiQ0E5SUdSbFptRjFiSFJEYjJ4dmNuTXVabWxzYkR0Y2JpQWdJQ0IwYUdsekxtMWxkR0V1WTI5c2IzSnpMbXhwWjJoMElEMGdaR1ZtWVhWc2RFTnZiRzl5Y3k1c2FXZG9kRHRjYmlBZ0lDQjBhR2x6TG0xbGRHRXVZMjlzYjNKekxtUmhjbXNnUFNCa1pXWmhkV3gwUTI5c2IzSnpMbVJoY21zN1hHNGdJQ0FnZEdocGN5NXRaWFJoTG1OdmJHOXljeTV0WldScGRXMU1hV2RvZENBOUlHUmxabUYxYkhSRGIyeHZjbk11YldWa2FYVnRUR2xuYUhRN1hHNGdJQ0FnZEdocGN5NXRaWFJoTG1OdmJHOXljeTV0WldScGRXMUVZWEpySUQwZ1pHVm1ZWFZzZEVOdmJHOXljeTV0WldScGRXMUVZWEpyTzF4dUlDQWdJSFJvYVhNdVluVnBiR1JKYm5SbGNtWmhZMlVvS1R0Y2JpQWdJQ0IwYUdsekxtTnZiRzl5U1c1MFpYSm1ZV05sS0NrN1hHNGdJSDFjYmx4dUlDQmlkV2xzWkVsdWRHVnlabUZqWlNncElIdGNiaUFnSUNCMGFHbHpMbTFsZEdFdWNHRnlaVzUwTG5OMGVXeGxMbUp2ZUZOcGVtbHVaeUE5SUNkaWIzSmtaWEl0WW05NEp6dGNiaUFnSUNCMGFHbHpMbTFsZEdFdWNHRnlaVzUwTG5OMGVXeGxMblZ6WlhKVFpXeGxZM1FnUFNBbmJtOXVaU2M3WEc0Z0lDQWdkR2hwY3k1dFpYUmhMbkJoY21WdWRDNXpkSGxzWlM1dGIzcFZjMlZ5VTJWc1pXTjBJRDBnSjI1dmJtVW5PMXh1SUNBZ0lIUm9hWE11YldWMFlTNXdZWEpsYm5RdWMzUjViR1V1ZDJWaWEybDBWWE5sY2xObGJHVmpkQ0E5SUNkdWIyNWxKenRjYmx4dUlDQWdJSFJvYVhNdWJXVjBZUzVqYjI1MFpXNTBjeUE5SUdSdlkzVnRaVzUwTG1OeVpXRjBaVVZzWlcxbGJuUW9KMlJwZGljcE8xeHVYRzRnSUNBZ2QyaHBiR1VnS0hSb2FYTXViV1YwWVM1d1lYSmxiblF1WTJocGJHUk9iMlJsY3k1c1pXNW5kR2dnUGlBd0tTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWJXVjBZUzVqYjI1MFpXNTBjeTVoY0hCbGJtUkRhR2xzWkNoMGFHbHpMbTFsZEdFdWNHRnlaVzUwTG1Ob2FXeGtUbTlrWlhOYk1GMHBPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIUm9hWE11YldWMFlTNWpiMjUwWlc1MGN5NXpkSGxzWlM1d1lXUmthVzVuSUQwZ0p6QndlQ2M3WEc0Z0lDQWdkR2hwY3k1dFpYUmhMbU52Ym5SbGJuUnpMbk4wZVd4bExtSnZlRk5wZW1sdVp5QTlJQ2RpYjNKa1pYSXRZbTk0Snp0Y2JseHVJQ0FnSUdsbUlDaDBhR2x6TG0xbGRHRXVkR2wwYkdVcElIdGNiaUFnSUNBZ0lIUm9hWE11YldWMFlTNTBhWFJzWlVKaGNpQTlJR1J2WTNWdFpXNTBMbU55WldGMFpVVnNaVzFsYm5Rb0oyUnBkaWNwTzF4dUlDQWdJQ0FnZEdocGN5NXRaWFJoTG5ScGRHeGxRbUZ5TG1sdWJtVnlTRlJOVENBOUlIUm9hWE11YldWMFlTNTBhWFJzWlR0Y2JpQWdJQ0FnSUhSb2FYTXViV1YwWVM1MGFYUnNaVUpoY2k1emRIbHNaUzVtYjI1MFJtRnRhV3g1SUQwZ0oyRnlhV0ZzSnp0Y2JpQWdJQ0FnSUhSb2FYTXViV1YwWVM1MGFYUnNaVUpoY2k1emRIbHNaUzV3YjNOcGRHbHZiaUE5SUNkeVpXeGhkR2wyWlNjN1hHNGdJQ0FnSUNCMGFHbHpMbTFsZEdFdWRHbDBiR1ZDWVhJdWMzUjViR1V1WTI5c2IzSWdQU0FuSXpnNE9DYzdYRzRnSUNBZ0lDQjBhR2x6TG0xbGRHRXVkR2wwYkdWQ1lYSXVjM1I1YkdVdWNHRmtaR2x1WnlBOUlDYzNjSGduTzF4dUlDQWdJQ0FnZEdocGN5NXRaWFJoTG5ScGRHeGxRbUZ5TG5OMGVXeGxMbVp2Ym5SVGFYcGxJRDBnSnpFeWNIZ25PMXh1WEc0Z0lDQWdJQ0IwYUdsekxtMWxkR0V1WW5WMGRHOXVJRDBnWkc5amRXMWxiblF1WTNKbFlYUmxSV3hsYldWdWRDZ25aR2wySnlrN1hHNGdJQ0FnSUNCMGFHbHpMbTFsZEdFdVluVjBkRzl1TG5OMGVXeGxMbkJ2YzJsMGFXOXVJRDBnSjJGaWMyOXNkWFJsSnp0Y2JpQWdJQ0FnSUhSb2FYTXViV1YwWVM1aWRYUjBiMjR1YzNSNWJHVXVkRzl3SUQwZ0p6VndlQ2NnTzF4dUlDQWdJQ0FnZEdocGN5NXRaWFJoTG1KMWRIUnZiaTV6ZEhsc1pTNXlhV2RvZENBOUlDYzFjSGduSUR0Y2JpQWdJQ0FnSUhSb2FYTXViV1YwWVM1aWRYUjBiMjR1YVc1dVpYSklWRTFNSUQwZ0p5MG5PMXh1SUNBZ0lDQWdkR2hwY3k1dFpYUmhMbUoxZEhSdmJpNXpkSGxzWlM1d1lXUmthVzVuSUQwZ0p6QndlQ0ExY0hnZ01uQjRKenRjYmlBZ0lDQWdJSFJvYVhNdWJXVjBZUzVpZFhSMGIyNHVjM1I1YkdVdWJHbHVaVWhsYVdkb2RDQTlJQ2N4TW5CNEp6dGNiaUFnSUNBZ0lIUm9hWE11YldWMFlTNWlkWFIwYjI0dWMzUjViR1V1Wm05dWRGTnBlbVVnUFNBbk1UVndlQ2M3WEc1Y2JpQWdJQ0FnSUhSb2FYTXViV1YwWVM1aWRYUjBiMjR1YzNSNWJHVXVZM1Z5YzI5eUlEMGdKM0J2YVc1MFpYSW5PMXh1WEc0Z0lDQWdJQ0IwYUdsekxtMWxkR0V1WW5WMGRHOXVMbUZrWkVWMlpXNTBUR2x6ZEdWdVpYSW9KMjF2ZFhObGIzWmxjaWNzSUNncElEMCtJSHRjYmlBZ0lDQWdJQ0FnZEdocGN5NXRaWFJoTG1KMWRIUnZiaTV6ZEhsc1pTNWlZV05yWjNKdmRXNWtRMjlzYjNJZ1BTQjBhR2x6TG0xbGRHRXVZMjlzYjNKekxtMWxaR2wxYlVSaGNtczdYRzRnSUNBZ0lDQjlLVHRjYmlBZ0lDQWdJSFJvYVhNdWJXVjBZUzVpZFhSMGIyNHVZV1JrUlhabGJuUk1hWE4wWlc1bGNpZ25iVzkxYzJWc1pXRjJaU2NzSUNncElEMCtJSHRjYmlBZ0lDQWdJQ0FnZEdocGN5NXRaWFJoTG1KMWRIUnZiaTV6ZEhsc1pTNWlZV05yWjNKdmRXNWtRMjlzYjNJZ1BTQjBhR2x6TG0xbGRHRXVZMjlzYjNKekxtMWxaR2wxYlV4cFoyaDBPMXh1SUNBZ0lDQWdmU2s3WEc0Z0lDQWdJQ0IwYUdsekxtMWxkR0V1WW5WMGRHOXVMbUZrWkVWMlpXNTBUR2x6ZEdWdVpYSW9KMk5zYVdOckp5d2dLQ2tnUFQ0Z2UxeHVJQ0FnSUNBZ0lDQnBaaUFvZEdocGN5NXRaWFJoTG05d1pXNHBJSHRjYmlBZ0lDQWdJQ0FnSUNCMGFHbHpMbWhwWkdVb0tUdGNiaUFnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0IwYUdsekxuTm9iM2NvS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2ZTazdYRzVjYmx4dUlDQWdJQ0FnZEdocGN5NXRaWFJoTG5ScGRHeGxRbUZ5TG1Gd2NHVnVaRU5vYVd4a0tIUm9hWE11YldWMFlTNWlkWFIwYjI0cE8xeHVYRzRnSUNBZ0lDQjBhR2x6TG0xbGRHRXVjR0Z5Wlc1MExtRndjR1Z1WkVOb2FXeGtLSFJvYVhNdWJXVjBZUzUwYVhSc1pVSmhjaWs3WEc0Z0lDQWdmVnh1SUNBZ0lIUm9hWE11YldWMFlTNXdZWEpsYm5RdVlYQndaVzVrUTJocGJHUW9kR2hwY3k1dFpYUmhMbU52Ym5SbGJuUnpLVHRjYmx4dUlDQXZMeUFnZG1GeUlIZHBaSFJvSUQwZ2RHaHBjeTV0WlhSaExuQmhjbVZ1ZEM1emRIbHNaUzUzYVdSMGFDQTlJR2RsZEVOdmJYQjFkR1ZrVTNSNWJHVW9kR2hwY3k1dFpYUmhMbkJoY21WdWRDa3VaMlYwVUhKdmNHVnlkSGxXWVd4MVpTZ25kMmxrZEdnbktUdGNiaTh2SUNBZ0lIUm9hWE11YldWMFlTNXdZWEpsYm5RdWMzUjViR1V1ZDJsa2RHZ2dQU0IzYVdSMGFEdGNibHh1SUNBZ0lHeGxkQ0IxYVNBOUlIUnlZVzV6Wm05eWJTNXpaV04wYVc5dUtIUm9hWE11YldWMFlTNTBZWEpuWlhRc0lIUm9hWE11YldWMFlTNWhkSFJ5YVdKMWRHVXBPMXh1SUNBZ0lHWnZjaUFvZG1GeUlHdGxlU0JwYmlCMWFTa2dlMXh1SUNBZ0lDQWdkR2hwYzF0clpYbGRJRDBnZFdsYmEyVjVYVHRjYmlBZ0lDQjlYRzRnSUgxY2JseHVJQ0JqYjJ4dmNrbHVkR1Z5Wm1GalpTZ3BJSHRjYmlBZ0lDQnBaaUFvZEdocGN5NXRaWFJoTG5ScGRHeGxLU0I3WEc0Z0lDQWdJQ0IwYUdsekxtMWxkR0V1WW5WMGRHOXVMbk4wZVd4bExtSmhZMnRuY205MWJtUkRiMnh2Y2lBOUlIUm9hWE11YldWMFlTNWpiMnh2Y25NdWJXVmthWFZ0VEdsbmFIUTdYRzRnSUNBZ0lDQjBhR2x6TG0xbGRHRXVZblYwZEc5dUxuTjBlV3hsTG1KdmNtUmxjaUE5SUNkemIyeHBaQ0F3Y0hnZ0p5dDBhR2x6TG0xbGRHRXVZMjlzYjNKekxtWnBiR3c3WEc0Z0lDQWdJQ0IwYUdsekxtMWxkR0V1Y0dGeVpXNTBMbk4wZVd4bExtSnZjbVJsY2lBOUlDZHpiMnhwWkNBeGNIZ2dKeXQwYUdsekxtMWxkR0V1WTI5c2IzSnpMbTFsWkdsMWJVeHBaMmgwTzF4dUlDQWdJQ0FnZEdocGN5NXRaWFJoTG5CaGNtVnVkQzV6ZEhsc1pTNWlZV05yWjNKdmRXNWtRMjlzYjNJZ1BTQjBhR2x6TG0xbGRHRXVZMjlzYjNKekxteHBaMmgwTzF4dUlDQWdJQ0FnZEdocGN5NXRaWFJoTG5ScGRHeGxRbUZ5TG5OMGVXeGxMbUpoWTJ0bmNtOTFibVJEYjJ4dmNpQTlJSFJvYVhNdWJXVjBZUzVqYjJ4dmNuTXVabWxzYkR0Y2JpQWdJQ0I5WEc0Z0lIMWNibHh1SUNCemFHOTNLQ2tnZTF4dUlDQWdJSFJvYVhNdWJXVjBZUzVqYjI1MFpXNTBjeTV6ZEhsc1pTNWthWE53YkdGNUlEMGdKMkpzYjJOckp6dGNiaUFnSUNCMGFHbHpMbTFsZEdFdWIzQmxiaUE5SUhSeWRXVTdYRzRnSUgxY2JseHVJQ0JvYVdSbEtDa2dlMXh1SUNBZ0lIUm9hWE11YldWMFlTNWpiMjUwWlc1MGN5NXpkSGxzWlM1a2FYTndiR0Y1SUQwZ0oyNXZibVVuTzF4dUlDQWdJSFJvYVhNdWJXVjBZUzV2Y0dWdUlEMGdabUZzYzJVN1hHNGdJSDFjYmx4dUlDQmpiMnh2Y21sNlpTaDBlWEJsTEdOdmJHOXlLU0I3WEc0Z0lDQWdabTl5SUNoMllYSWdhMlY1SUdsdUlIUm9hWE1wSUh0Y2JpQWdJQ0FnSUdsbUlDaDBhR2x6VzJ0bGVWMHVZMjlzYjNKcGVtVXBJSHRjYmlBZ0lDQWdJQ0FnZEdocGMxdHJaWGxkTG1OdmJHOXlhWHBsS0hSNWNHVXNZMjlzYjNJcE8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUgxY2JpQWdJQ0IwYUdsekxtMWxkR0V1WTI5c2IzSnpXM1I1Y0dWZElEMGdZMjlzYjNJN1hHNGdJQ0FnZEdocGN5NWpiMnh2Y2tsdWRHVnlabUZqWlNncE8xeHVJQ0I5WEc1Y2JpQWdaVzF3ZEhrb0tTQjdYRzRnSUNBZ1ptOXlJQ2gyWVhJZ2EyVjVJR2x1SUhSb2FYTXBJSHRjYmlBZ0lDQWdJR2xtSUNoMGFHbHpXMnRsZVYwdVpHVnpkSEp2ZVNrZ2UxeHVJQ0FnSUNBZ0lDQjBhR2x6VzJ0bGVWMHVaR1Z6ZEhKdmVTZ3BPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lIMWNiaUFnZlZ4dVhHNTlYRzVjYmx4dVhHNHZMeUJYUlVKUVFVTkxJRVpQVDFSRlVpQXZMMXh1THk4Z0xpOStMMnB6YUdsdWRDMXNiMkZrWlhJaExpOXNhV0l2WTI5eVpTOXlZV05yTG1weklpd2lKM1Z6WlNCemRISnBZM1FuTzF4dVhHNXBiWEJ2Y25RZ1pHOXRJR1p5YjIwZ0p5NHVMM1YwYVd3dlpHOXRKenRjYm1sdGNHOXlkQ0JKYm5SbGNtWmhZMlZ6SUdaeWIyMGdKeTR1TDJsdWRHVnlabUZqWlhNdkp6dGNibHh1YkdWMElHTnlaV0YwWlVsdWRHVnlabUZqWlVsRUlEMGdLSGRwWkdkbGRDeHBiblJsY21aaFkyVkpSSE1wSUQwK0lIdGNiaUFnYkdWMElIUjVjR1VnUFNCM2FXUm5aWFF1ZEhsd1pUdGNiaUFnYVdZZ0tHbHVkR1Z5Wm1GalpVbEVjMXQwZVhCbFhTa2dlMXh1SUNBZ0lHbHVkR1Z5Wm1GalpVbEVjMXQwZVhCbFhTc3JPMXh1SUNCOUlHVnNjMlVnZTF4dUlDQWdJR2x1ZEdWeVptRmpaVWxFYzF0MGVYQmxYU0E5SURFN1hHNGdJSDFjYmlBZ2NtVjBkWEp1SUNnZ2RIbHdaU0FySUdsdWRHVnlabUZqWlVsRWMxdDBlWEJsWFNBcE8xeHVmVHRjYmx4dWJHVjBJR1ZzWlcxbGJuUWdQU0FvWld4bGJXVnVkQ3gwZVhCbExHOXdkR2x2Ym5NcElEMCtJSHRjYmlBZ2IzQjBhVzl1Y3lBOUlHOXdkR2x2Ym5NZ2ZId2dlMzA3WEc0Z0lHWnZjaUFvYkdWMElHa2dQU0F3T3lCcElEd2daV3hsYldWdWRDNWhkSFJ5YVdKMWRHVnpMbXhsYm1kMGFEc2dhU3NyS1h0Y2JpQWdJQ0JzWlhRZ1lYUjBJRDBnWld4bGJXVnVkQzVoZEhSeWFXSjFkR1Z6VzJsZE8xeHVJQ0F2THlBZ2RISjVJSHRjYmlBZ0x5OGdJQ0FnYjNCMGFXOXVjMXRoZEhRdWJtOWtaVTVoYldWZElEMGdaWFpoYkNoaGRIUXVibTlrWlZaaGJIVmxLVHRjYmlBZ0x5OGdJSDBnWTJGMFkyZ29aU2tnZTF4dUlDQWdJQ0FnYjNCMGFXOXVjMXRoZEhRdWJtOWtaVTVoYldWZElEMGdZWFIwTG01dlpHVldZV3gxWlR0Y2JpQWdMeThnSUgxY2JpQWdmVnh1SUNCMGVYQmxJRDBnZEhsd1pWc3dYUzUwYjFWd2NHVnlRMkZ6WlNncElDc2dkSGx3WlM1emJHbGpaU2d4S1R0Y2JpQWdiR1YwSUhkcFpHZGxkQ0E5SUc1bGR5QkpiblJsY21aaFkyVnpXM1I1Y0dWZEtHVnNaVzFsYm5Rc2IzQjBhVzl1Y3lrN1hHNGdJSGRwWkdkbGRDNXBaQ0E5SUdWc1pXMWxiblF1YVdRN1hHNGdJSEpsZEhWeWJpQjNhV1JuWlhRN1hHNTlPMXh1WEc1Y2JteGxkQ0J6WldOMGFXOXVJRDBnS0hCaGNtVnVkQ3hyWlhsM2IzSmtLU0E5UGlCN1hHNWNiaUFnYTJWNWQyOXlaQ0E5SUd0bGVYZHZjbVFnZkh3Z0oyNWxlSFZ6TFhWcEp6dGNibHh1SUNCc1pYUWdhVzUwWlhKbVlXTmxTVVJ6SUQwZ2UzMDdYRzVjYmlBZ2JHVjBJR052Ym5SaGFXNWxjaUE5SUdSdmJTNXdZWEp6WlVWc1pXMWxiblFvY0dGeVpXNTBLVHRjYmx4dUlDQnNaWFFnZFdrZ1BTQjdmVHRjYmx4dUlDQnNaWFFnYUhSdGJFVnNaVzFsYm5SeklEMGdZMjl1ZEdGcGJtVnlMbWRsZEVWc1pXMWxiblJ6UW5sVVlXZE9ZVzFsS0NjcUp5azdYRzRnSUd4bGRDQmxiR1Z0Wlc1MGN5QTlJRnRkTzF4dUlDQm1iM0lnS0d4bGRDQnBQVEE3SUdrOGFIUnRiRVZzWlcxbGJuUnpMbXhsYm1kMGFEc2dhU3NyS1NCN1hHNGdJQ0FnWld4bGJXVnVkSE11Y0hWemFDaG9kRzFzUld4bGJXVnVkSE5iYVYwcE8xeHVJQ0I5WEc0Z0lHWnZjaUFvYkdWMElHazlNRHRwUEdWc1pXMWxiblJ6TG14bGJtZDBhRHRwS3lzcElIdGNiaUFnSUNCc1pYUWdkSGx3WlNBOUlHVnNaVzFsYm5SelcybGRMbWRsZEVGMGRISnBZblYwWlNoclpYbDNiM0prS1R0Y2JpQWdJQ0JwWmlBb2RIbHdaU2tnZTF4dUlDQWdJQ0FnYkdWMElHWnZjbTFoZEhSbFpGUjVjR1VnUFNCbVlXeHpaVHRjYmlBZ0lDQWdJR1p2Y2lBb2JHVjBJR3RsZVNCcGJpQkpiblJsY21aaFkyVnpLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaDBlWEJsTG5SdlRHOTNaWEpEWVhObEtDazlQVDFyWlhrdWRHOU1iM2RsY2tOaGMyVW9LU2tnZTF4dUlDQWdJQ0FnSUNBZ0lHWnZjbTFoZEhSbFpGUjVjR1VnUFNCclpYazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJSDFjYmlBZ0lDQWdJR052Ym5OdmJHVXViRzluS0dadmNtMWhkSFJsWkZSNWNHVXBPMXh1SUNBZ0lDQWdiR1YwSUhkcFpHZGxkQ0E5SUdWc1pXMWxiblFvWld4bGJXVnVkSE5iYVYwc1ptOXliV0YwZEdWa1ZIbHdaU2s3WEc0Z0lDQWdJQ0JwWmlBb2QybGtaMlYwTG1sa0tTQjdYRzRnSUNBZ0lDQWdJSFZwVzNkcFpHZGxkQzVwWkYwZ1BTQjNhV1JuWlhRN1hHNGdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNCc1pYUWdhV1FnUFNCamNtVmhkR1ZKYm5SbGNtWmhZMlZKUkNoM2FXUm5aWFFzYVc1MFpYSm1ZV05sU1VSektUdGNiaUFnSUNBZ0lDQWdkV2xiYVdSZElEMGdkMmxrWjJWME8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUgxY2JpQWdmVnh1WEc0Z0lISmxkSFZ5YmlCMWFUdGNibHh1ZlR0Y2JseHViR1YwSUdGa1pDQTlJQ2gwZVhCbExIQmhjbVZ1ZEN4dmNIUnBiMjV6S1NBOVBpQjdYRzRnSUd4bGRDQjBZWEpuWlhRZ1BTQmtiMk4xYldWdWRDNWpjbVZoZEdWRmJHVnRaVzUwS0Nka2FYWW5LVHRjYmlBZ2IzQjBhVzl1Y3lBOUlHOXdkR2x2Ym5NZ2ZId2dlMzA3WEc0Z0lHbG1JQ2h3WVhKbGJuUXBJSHRjYmlBZ0lDQndZWEpsYm5RZ1BTQmtiMjB1Y0dGeWMyVkZiR1Z0Wlc1MEtIQmhjbVZ1ZENrN1hHNGdJSDBnWld4elpTQjdYRzRnSUNBZ2NHRnlaVzUwSUQwZ1pHOWpkVzFsYm5RdVltOWtlVHRjYmlBZ2ZWeHVJQ0J3WVhKbGJuUXVZWEJ3Wlc1a1EyaHBiR1FvZEdGeVoyVjBLVHRjYmlBZ2IzQjBhVzl1Y3k1MFlYSm5aWFFnUFNCMFlYSm5aWFE3WEc0Z0lHbG1JQ2h2Y0hScGIyNXpMbk5wZW1VcElIdGNiaUFnSUNCMFlYSm5aWFF1YzNSNWJHVXVkMmxrZEdnZ1BTQnZjSFJwYjI1ekxuTnBlbVZiTUYwZ0t5QW5jSGduTzF4dUlDQWdJSFJoY21kbGRDNXpkSGxzWlM1b1pXbG5hSFFnUFNCdmNIUnBiMjV6TG5OcGVtVmJNVjBnS3lBbmNIZ25PMXh1SUNCOVhHNGdJSEpsZEhWeWJpQmxiR1Z0Wlc1MEtIUmhjbWRsZEN4MGVYQmxMRzl3ZEdsdmJuTXBPMXh1ZlR0Y2JseHVaWGh3YjNKMElIc2daV3hsYldWdWRDQjlPMXh1Wlhod2IzSjBJSHNnYzJWamRHbHZiaUI5TzF4dVpYaHdiM0owSUhzZ1lXUmtJSDA3WEc1Y2JseHVYRzR2THlCWFJVSlFRVU5MSUVaUFQxUkZVaUF2TDF4dUx5OGdMaTkrTDJwemFHbHVkQzFzYjJGa1pYSWhMaTlzYVdJdmRYUnBiQzkwY21GdWMyWnZjbTB1YW5NaUxDSW5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JtbHRjRzl5ZENCdFlYUm9JR1p5YjIwZ0p5NHVMM1YwYVd3dmJXRjBhQ2M3WEc1Y2JtVjRjRzl5ZENCa1pXWmhkV3gwSUdOc1lYTnpJRlIxYm1VZ2UxeHVYRzRnSUdOdmJuTjBjblZqZEc5eUtDa2dlMXh1WEc0Z0lGeDBMeThnZEdobElITmpZV3hsSUdGeklISmhkR2x2YzF4dUlDQmNkSFJvYVhNdWMyTmhiR1VnUFNCYlhUdGNibHh1SUNCY2RDOHZJR2t2YnlCdGIyUmxjMXh1SUNCY2RIUm9hWE11Ylc5a1pTQTlJSHRjYmlBZ1hIUmNkRzkxZEhCMWREb2dKMlp5WlhGMVpXNWplU2NzWEc0Z0lGeDBYSFJwYm5CMWREb2dKM04wWlhBblhHNGdJRngwZlR0Y2JseHVJQ0JjZEM4dklFVlVJRzFoYW05eVhHNGdJRngwZEdocGN5NWxkRzFoYW05eUlEMGdXeUF5TmpFdU5qSTFOVGdzWEc0Z0lGeDBYSFF5T1RNdU5qWTBOelkwTEZ4dUlDQmNkRngwTXpJNUxqWXlOelUyTXl4Y2JpQWdYSFJjZERNME9TNHlNamd5TkRFc1hHNGdJRngwWEhRek9URXVPVGsxTkRJeUxGeHVJQ0JjZEZ4ME5EUXdMRnh1SUNCY2RGeDBORGt6TGpnNE16TXdNU3hjYmlBZ1hIUmNkRFV5TXk0eU5URXhObHh1SUNCY2RGMDdYRzVjYmlBZ1hIUXZMeUJTYjI5MElHWnlaWEYxWlc1amVTNWNiaUFnWEhSMGFHbHpMbkp2YjNRZ1BTQnRZWFJvTG0xMGIyWW9OakFwT3lBZ0lDQWdMeThnS2lCTllYUm9MbkJ2ZHlneUxDZzJNQzAyT1Nrdk1USXBPMXh1WEc0Z0lDQWdMeThnWkdWbVlYVnNkQ0JwY3lCaElHMWhhbTl5SUhOallXeGxYRzRnSUNBZ2RHaHBjeTVqY21WaGRHVlRZMkZzWlNnd0xESXNOQ3cxTERjc09Td3hNU2s3WEc1Y2JpQWdmVnh1WEc0Z0lDOHFJRkpsZEhWeWJpQmtZWFJoSUdsdUlIUm9aU0J0YjJSbElIbHZkU0JoY21VZ2FXNGdLR1p5WlhFc0lISmhkR2x2TENCdmNpQnRhV1JwS1NBcUwxeHVJQ0J1YjNSbEtHbHVjSFYwTEc5amRHRjJaU2tnZTF4dVhHNGdJRngwYkdWMElHNWxkM1poYkhWbE8xeHVYRzRnSUZ4MGFXWWdLSFJvYVhNdWJXOWtaUzV2ZFhSd2RYUWdQVDA5SUNkbWNtVnhkV1Z1WTNrbktTQjdYRzRnSUZ4MFhIUnVaWGQyWVd4MVpTQTlJSFJvYVhNdVpuSmxjWFZsYm1ONUtHbHVjSFYwTEc5amRHRjJaU2s3WEc0Z0lGeDBmU0JsYkhObElHbG1JQ2gwYUdsekxtMXZaR1V1YjNWMGNIVjBJRDA5UFNBbmNtRjBhVzhuS1NCN1hHNGdJRngwWEhSdVpYZDJZV3gxWlNBOUlIUm9hWE11Y21GMGFXOG9hVzV3ZFhRc2IyTjBZWFpsS1R0Y2JpQWdYSFI5SUdWc2MyVWdhV1lnS0hSb2FYTXViVzlrWlM1dmRYUndkWFFnUFQwOUlDZE5TVVJKSnlrZ2UxeHVJQ0JjZEZ4MGJtVjNkbUZzZFdVZ1BTQjBhR2x6TGsxSlJFa29hVzV3ZFhRc2IyTjBZWFpsS1R0Y2JpQWdYSFI5SUdWc2MyVWdlMXh1SUNCY2RGeDBibVYzZG1Gc2RXVWdQU0IwYUdsekxtWnlaWEYxWlc1amVTaHBibkIxZEN4dlkzUmhkbVVwTzF4dUlDQmNkSDFjYmx4dUlDQmNkSEpsZEhWeWJpQnVaWGQyWVd4MVpUdGNibHh1SUNCOVhHNWNibHh1SUNBdktpQlNaWFIxY200Z1puSmxjU0JrWVhSaElDb3ZYRzRnSUdaeVpYRjFaVzVqZVNoemRHVndTVzRzSUc5amRHRjJaVWx1S1NCN1hHNWNiaUFnWEhScFppQW9kR2hwY3k1dGIyUmxMbWx1Y0hWMElEMDlQU0FuYldsa2FTY2dmSHdnZEdocGN5NXRiMlJsTG1sdWNIVjBJRDA5UFNBblRVbEVTU2NnS1NCN1hHNGdJRngwWEhSMGFHbHpMbk4wWlhCSmJpQXJQU0EyTUR0Y2JpQWdYSFI5WEc1Y2JpQWdYSFF2THlCM2FHRjBJRzlqZEdGMlpTQnBjeUJ2ZFhJZ2FXNXdkWFJjYmlBZ1hIUnNaWFFnYjJOMFlYWmxJRDBnVFdGMGFDNW1iRzl2Y2loemRHVndTVzR2ZEdocGN5NXpZMkZzWlM1c1pXNW5kR2dwTzF4dVhHNGdJRngwYVdZZ0tHOWpkR0YyWlVsdUtTQjdYRzRnSUZ4MFhIUnZZM1JoZG1VZ0t6MGdiMk4wWVhabFNXNDdYRzRnSUZ4MGZWeHVYRzRnSUZ4MEx5OGdkMmhwWTJnZ2MyTmhiR1VnWkdWbmNtVmxJQ2d3SUMwZ2MyTmhiR1VnYkdWdVozUm9LU0JwY3lCdmRYSWdhVzV3ZFhSY2JpQWdYSFJzWlhRZ2MyTmhiR1ZFWldkeVpXVWdQU0J6ZEdWd1NXNGdKU0IwYUdsekxuTmpZV3hsTG14bGJtZDBhRHRjYmx4dUlDQmNkSGRvYVd4bElDaHpZMkZzWlVSbFozSmxaU0E4SURBcElIdGNiaUFnWEhSY2RITmpZV3hsUkdWbmNtVmxJQ3M5SUhSb2FYTXVjMk5oYkdVdWJHVnVaM1JvTzF4dUlDQmNkSDFjYmx4dUlDQWdJR3hsZENCeVlYUnBieUE5SUhSb2FYTXVjMk5oYkdWYmMyTmhiR1ZFWldkeVpXVmRPMXh1WEc0Z0lGeDBiR1YwSUdaeVpYRWdQU0IwYUdsekxuSnZiM1FnS2lCeVlYUnBienRjYmx4dUlDQmNkR1p5WlhFZ1BTQm1jbVZ4S2loTllYUm9MbkJ2ZHlneUxHOWpkR0YyWlNrcE8xeHVYRzRnSUZ4MEx5OGdkSEoxYm1OaGRHVWdhWEp5WVhScGIyNWhiQ0J1ZFcxaVpYSnpYRzRnSUZ4MFpuSmxjU0E5SUUxaGRHZ3VabXh2YjNJb1puSmxjU294TURBd01EQXdNREF3TURBcEx6RXdNREF3TURBd01EQXdNRHRjYmx4dUlDQmNkSEpsZEhWeWJpQm1jbVZ4TzF4dVhHNGdJSDFjYmx4dUlDQXZLaUJHYjNKalpTQnlaWFIxY200Z2NtRjBhVzhnWkdGMFlTQXFMMXh1WEc0Z0lISmhkR2x2S0hOMFpYQkpiaXdnYjJOMFlYWmxTVzRwSUh0Y2JseHVJQ0JjZEdsbUlDaDBhR2x6TG0xdlpHVXVhVzV3ZFhRZ1BUMDlJQ2R0YVdScEp5QjhmQ0IwYUdsekxtMXZaR1V1YVc1d2RYUWdQVDA5SUNkTlNVUkpKeUFwSUh0Y2JpQWdYSFJjZEhSb2FYTXVjM1JsY0VsdUlDczlJRFl3TzF4dUlDQmNkSDFjYmx4dUlDQmNkQzh2SUhkb1lYUWdiMk4wWVhabElHbHpJRzkxY2lCcGJuQjFkRnh1SUNCY2RHeGxkQ0J2WTNSaGRtVWdQU0JOWVhSb0xtWnNiMjl5S0hOMFpYQkpiaTkwYUdsekxuTmpZV3hsTG14bGJtZDBhQ2s3WEc1Y2JpQWdYSFJwWmlBb2IyTjBZWFpsU1c0cElIdGNiaUFnWEhSY2RHOWpkR0YyWlNBclBTQnZZM1JoZG1WSmJqdGNiaUFnWEhSOVhHNWNiaUFnWEhRdkx5QjNhR2xqYUNCelkyRnNaU0JrWldkeVpXVWdLREFnTFNCelkyRnNaU0JzWlc1bmRHZ3BJR2x6SUc5MWNpQnBibkIxZEZ4dUlDQmNkR3hsZENCelkyRnNaVVJsWjNKbFpTQTlJSE4wWlhCSmJpQWxJSFJvYVhNdWMyTmhiR1V1YkdWdVozUm9PMXh1WEc0Z0lGeDBMeThnZDJoaGRDQnlZWFJwYnlCcGN5QnZkWElnYVc1d2RYUWdkRzhnYjNWeUlHdGxlVnh1SUNCY2RHeGxkQ0J5WVhScGJ5QTlJRTFoZEdndWNHOTNLRElzYjJOMFlYWmxLU3AwYUdsekxuTmpZV3hsVzNOallXeGxSR1ZuY21WbFhUdGNibHh1SUNCY2RISmhkR2x2SUQwZ1RXRjBhQzVtYkc5dmNpaHlZWFJwYnlveE1EQXdNREF3TURBd01EQXBMekV3TURBd01EQXdNREF3TUR0Y2JseHVJQ0JjZEhKbGRIVnliaUJ5WVhScGJ6dGNibHh1SUNCOVhHNWNiaUFnTHlvZ1JtOXlZMlVnY21WMGRYSnVJR0ZrYW5WemRHVmtJRTFKUkVrZ1pHRjBZU0FxTDF4dVhHNGdJRTFKUkVrb2MzUmxjRWx1TEc5amRHRjJaVWx1S1NCN1hHNWNiaUFnWEhSc1pYUWdibVYzZG1Gc2RXVWdQU0IwYUdsekxtWnlaWEYxWlc1amVTaHpkR1Z3U1c0c2IyTjBZWFpsU1c0cE8xeHVYRzRnSUZ4MGJHVjBJRzRnUFNBMk9TQXJJREV5S2sxaGRHZ3ViRzluS0c1bGQzWmhiSFZsTHpRME1Da3ZUV0YwYUM1c2IyY29NaWs3WEc1Y2JpQWdYSFJ1SUQwZ1RXRjBhQzVtYkc5dmNpaHVLakV3TURBd01EQXdNREFwTHpFd01EQXdNREF3TURBN1hHNWNiaUFnWEhSeVpYUjFjbTRnYmp0Y2JseHVJQ0I5WEc1Y2JpQWdZM0psWVhSbFUyTmhiR1VvS1NCN1hHNGdJQ0FnYkdWMElHNWxkMU5qWVd4bElEMGdXMTA3WEc0Z0lDQWdabTl5SUNoc1pYUWdhVDB3TzJrOFlYSm5kVzFsYm5SekxteGxibWQwYUR0cEt5c3BJSHRjYmlBZ0lDQWdJRzVsZDFOallXeGxMbkIxYzJnb0lHMWhkR2d1YlhSdlppZ2dOakFnS3lCaGNtZDFiV1Z1ZEhOYmFWMGdLU0FwTzF4dUlDQWdJSDFjYmlBZ0lDQjBhR2x6TG14dllXUlRZMkZzWlVaeWIyMUdjbVZ4ZFdWdVkybGxjeWh1WlhkVFkyRnNaU2s3WEc0Z0lIMWNibHh1SUNCamNtVmhkR1ZLU1ZOallXeGxLQ2tnZTF4dUlDQWdJSFJvYVhNdWMyTmhiR1VnUFNCYlhUdGNiaUFnSUNCbWIzSWdLR3hsZENCcFBUQTdhVHhoY21kMWJXVnVkSE11YkdWdVozUm9PMmtyS3lrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTV6WTJGc1pTNXdkWE5vS0dGeVozVnRaVzUwYzF0cFhTazdYRzRnSUNBZ2ZWeHVJQ0I5WEc1Y2JpQWdiRzloWkZOallXeGxSbkp2YlVaeVpYRjFaVzVqYVdWektHWnlaWEZ6S1NCN1hHNGdJQ0FnZEdocGN5NXpZMkZzWlNBOUlGdGRPMXh1SUNBZ0lHWnZjaUFvYkdWMElHazlNRHRwUEdaeVpYRnpMbXhsYm1kMGFDMHhPMmtyS3lrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTV6WTJGc1pTNXdkWE5vS0daeVpYRnpXMmxkTDJaeVpYRnpXekJkS1R0Y2JpQWdJQ0I5WEc0Z0lIMWNibHh1SUNBdktpQk1iMkZrSUdFZ2JtVjNJSE5qWVd4bElDb3ZYRzVjYmlBZ2JHOWhaRk5qWVd4bEtHNWhiV1VwZTF4dVhHNGdJRngwTHlvZ2JHOWhaQ0IwYUdVZ2MyTmhiR1VnS2k5Y2JpQWdYSFJzWlhRZ1puSmxjWE1nUFNCMGFHbHpMbk5qWVd4bGMxdHVZVzFsWFM1bWNtVnhkV1Z1WTJsbGN6dGNiaUFnSUNCMGFHbHpMbXh2WVdSVFkyRnNaVVp5YjIxR2NtVnhkV1Z1WTJsbGN5aG1jbVZ4Y3lrN1hHNWNiaUFnZlZ4dVhHNGdJQzhxSUZObFlYSmphQ0IwYUdVZ2JtRnRaWE1nYjJZZ2RIVnVhVzVuYzF4dUlDQmNkQ0JTWlhSMWNtNXpJR0Z1SUdGeWNtRjVJRzltSUc1aGJXVnpJRzltSUhSMWJtbHVaM01nS2k5Y2JseHVJQ0J6WldGeVkyZ29iR1YwZEdWeWN5a2dlMXh1SUNCY2RHeGxkQ0J3YjNOemFXSnNaU0E5SUZ0ZE8xeHVJQ0JjZEdadmNpQW9iR1YwSUd0bGVTQnBiaUIwYUdsekxuTmpZV3hsY3lrZ2UxeHVJQ0JjZEZ4MGFXWWdLR3RsZVM1MGIweHZkMlZ5UTJGelpTZ3BMbWx1WkdWNFQyWW9iR1YwZEdWeWN5NTBiMHh2ZDJWeVEyRnpaU2dwS1NBaFBUMGdMVEVwSUh0Y2JpQWdYSFJjZEZ4MGNHOXpjMmxpYkdVdWNIVnphQ2hyWlhrcE8xeHVJQ0JjZEZ4MGZWeHVJQ0JjZEgxY2JpQWdYSFJ5WlhSMWNtNGdjRzl6YzJsaWJHVTdYRzRnSUgxY2JseHVJQ0F2S2lCU1pYUjFjbTRnWVNCamIyeHNaV04wYVc5dUlHOW1JRzV2ZEdWeklHRnpJR0Z1SUdGeWNtRjVJQ292WEc1Y2JpQWdZMmh2Y21Rb2JXbGthWE1wSUh0Y2JpQWdYSFJzWlhRZ2IzVjBjSFYwSUQwZ1cxMDdYRzRnSUZ4MFptOXlJQ2hzWlhRZ2FUMHdPMms4Yldsa2FYTXViR1Z1WjNSb08ya3JLeWtnZTF4dUlDQmNkRngwYjNWMGNIVjBMbkIxYzJnb2RHaHBjeTV1YjNSbEtHMXBaR2x6VzJsZEtTazdYRzRnSUZ4MGZWeHVJQ0JjZEhKbGRIVnliaUJ2ZFhSd2RYUTdYRzRnSUgxY2JseHVmVnh1WEc1Y2JseHVMeThnVjBWQ1VFRkRTeUJHVDA5VVJWSWdMeTljYmk4dklDNHZmaTlxYzJocGJuUXRiRzloWkdWeUlTNHZiR2xpTDNSMWJtbHVaeTkwZFc1cGJtY3Vhbk1pTENJbmRYTmxJSE4wY21samRDYzdYRzVjYmk4dlJHbHpZV0pzWlNCcWMyaHBiblFnZDJGeWJtbHVaeUJqYjI1alpYSnVhVzVuSUhSeVlXbHNhVzVuSUhKbFozVnNZWElnY0dGeVlXMXpYRzR2S21wemFHbHVkQ0F0VnpFek9DQXFMMXh1WEc1bGVIQnZjblFnWkdWbVlYVnNkQ0JqYkdGemN5QlNZV1JwYnlCN1hHNGdJQ0FnTHk5cFppQnViMjR0WlhocGMzUmxiblFnWW5WMGRHOXVjeUJoY21VZ2MzZHBkR05vWldRc0lIUm9aWGtnWVhKbElHbG5ibTl5WldSY2JseHVJQ0FnSUdOdmJuTjBjblZqZEc5eUtHeGxibWQwYUNBOUlETXNJQzR1TG05dVZtRnNjeWtnZTF4dUlDQWdJQ0FnSUNBdkwyVmhZMmdnYjNCMGFXOXVZV3dnSjI5dVZtRnNjeWNnWVhKbmRXMWxiblFnYzNkcGRHTm9aWE1nYjI0Z2RHaGhkQ0IyWVd4MVpTQnBiaUIwYUdVZ1VtRmthVzhnYVdZZ2FYUWdaWGhwYzNSelhHNGdJQ0FnSUNBZ0lDOHZTVzRnZEdobElHVjRZVzF3YkdVZ1ltVnNiM2NzSUdFZ015MWlkWFIwYjI0Z2NtRmthVzhnYVhNZ1kzSmxZWFJsWkN3Z2FXNWtaWGdnTUNCcGN5QnpkMmwwWTJobFpDQnZiaXdnYVc1a1pYZ2dNU0JwY3lCemQybDBZMmhsWkNCdmJpQjBhR1Z1SUhSb1pXNGdZWFIwWlcxd2RHVmtJR0ZuWVdsdUlIQnliMlIxWTJsdVp5QmhiaUIzWVhKdWFXNW5MQ0JoYm1RZ2RHaGxJR1pwYm1Gc0lHRnlaM1Z0Wlc1MElIQnliMlIxWTJWeklHRWdkMkZ5Ym1sdVp5QmlaV05oZFhObElIUm9aU0JwYm1SbGVDQjJZV3gxWlNCa2IyVnpJRzV2ZENCbGVHbHpkQzVjYmlBZ0lDQWdJQ0FnTHk5RmVHRnRjR3hsT2x4dUlDQWdJQ0FnSUNBdkwyQWdJSEpoWkdsdklEMGdibVYzSUZKaFpHbHZLRE1zSURBc0lERXNJREVzSURNcE8xeHVJQ0FnSUNBZ0lDQXZMK0tBcGlBZ1d6RXNNU3d3WFZ4dVhHNGdJQ0FnSUNBZ0lHbG1JQ2hzWlc1bmRHZ2dQQ0F3S1NCN0lHeGxibWQwYUNBOUlERTdJSDFjYmx4dUlDQWdJQ0FnSUNCMGFHbHpMbXhsYm1kMGFDQTlJR3hsYm1kMGFEdGNiaUFnSUNBZ0lDQWdkR2hwY3k1dmJsWmhiSE1nUFNCdmJsWmhiSE03WEc0Z0lDQWdJQ0FnSUhSb2FYTXVZWEp5WVhrZ1BTQnVaWGNnUVhKeVlYa29iR1Z1WjNSb0tTNW1hV3hzS0RBcE8xeHVYRzRnSUNBZ0lDQWdJR2xtSUNodmJsWmhiSE11YkdWdVozUm9JRDRnTUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnZEdocGN5NXZiaWd1TGk1dmJsWmhiSE1wTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnZlZ4dVhHNGdJQ0FnYzJWc1pXTjBLSFpoYkhWbEtTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdVlYSnlZWGt1Wm1sc2JDZ3dLVHRjYmlBZ0lDQWdJQ0FnZEdocGN5NWhjbkpoZVZ0MllXeDFaVjBnUFNBeE8xeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2RHaHBjeTVoY25KaGVUdGNiaUFnSUNCOVhHNWNiaUFnSUNCbWJHbHdLQzR1TG5aaGJIVmxjeWtnZTF4dUlDQWdJQ0FnSUNBdkwyWnNhWEJ6SUhSb1pTQnpjR1ZqYVdacFpXUWdkbUZzZFdWekxpQnBaaUJ1YnlCMllXeDFaU0JwY3lCemNHVmphV1pwWldRc0lHWnNhWEJ6SUdGc2JDQmlkWFIwYjI1elhHNGdJQ0FnSUNBZ0lHeGxkQ0JoSUQwZ2RHaHBjeTVoY25KaGVUdGNiaUFnSUNBZ0lDQWdhV1lnS0haaGJIVmxjeTVzWlc1bmRHZ2dQaUF3S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0IyWVd4MVpYTXVabTl5UldGamFDaG1kVzVqZEdsdmJpaDJLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tIWWdQaUJoTG14bGJtZDBhQ0F0SURFcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWTI5dWMyOXNaUzUzWVhKdUtDZFhZWEp1YVc1bk9pQkJibTl1VW1Ga2FXOWJKeUFySUhZZ0t5QW5YU0JrYjJWeklHNXZkQ0JsZUdsemRDY3BPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdGYmRsMGdQU0FvWVZ0MlhTQS9JREFnT2lBeEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNCOUtUdGNiaUFnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdFdVptOXlSV0ZqYUNobWRXNWpkR2x2YmloMkxDQnBMQ0JoY25JcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmhjbkpiYVYwZ1BTQW9kaUEvSURBZ09pQXhLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIMHBPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJoTzF4dUlDQWdJSDFjYmx4dUlDQWdJRzl1S0M0dUxuWmhiSFZsY3lrZ2UxeHVJQ0FnSUNBZ0lDQXZMM04zYVhSamFDQnZiaUIwYUdVZ2MzQmxZMmxtYVdWa0lIWmhiSFZsY3k0Z2FXWWdibThnZG1Gc2RXVWdjM0JsWTJsbWFXVmtMQ0JtYkdsd2N5QnZiaUJoYkd3Z1luVjBkRzl1YzF4dUlDQWdJQ0FnSUNCc1pYUWdZU0E5SUhSb2FYTXVZWEp5WVhrN1hHNGdJQ0FnSUNBZ0lHbG1JQ2gyWVd4MVpYTXViR1Z1WjNSb0lENGdNQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdkbUZzZFdWekxtWnZja1ZoWTJnb1puVnVZM1JwYjI0b2Rpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoMklENGdZUzVzWlc1bmRHZ2dMU0F4S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR052Ym5OdmJHVXVkMkZ5YmlnblYyRnlibWx1WnpvZ1FXNXZibEpoWkdsdld5Y2dLeUIySUNzZ0oxMGdaWGhqWldWa2N5QnphWHBsSUc5bUlHOWlhbVZqZENjcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIMGdaV3h6WlNCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoaFczWmRJRDA5UFNBeEtTQjdJR052Ym5OdmJHVXVkMkZ5YmlnblYyRnlibWx1WnpvZ1FXNXZibEpoWkdsdld5Y2dLeUIySUNzZ0oxMGdkMkZ6SUdGc2NtVmhaSGtnYjI0dUp5azdJSDFjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1lWdDJYU0E5SURFN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMGdaV3h6WlNCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JoTG1acGJHd29NU2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdFN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnYjJabUtDNHVMblpoYkhWbGN5a2dlMXh1SUNBZ0lDQWdJQ0F2TDNOM2FYUmphQ0J2Wm1ZZ2RHaGxJSE53WldOcFptbGxaQ0IyWVd4MVpYTXVJR2xtSUc1dklIWmhiSFZsSUhOd1pXTnBabWxsWkN3Z1pteHBjSE1nYjJabUlHRnNiQ0JpZFhSMGIyNXpYRzRnSUNBZ0lDQWdJR3hsZENCaElEMGdkR2hwY3k1aGNuSmhlVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tIWmhiSFZsY3k1c1pXNW5kR2dnUGlBd0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMllXeDFaWE11Wm05eVJXRmphQ2htZFc1amRHbHZiaWgyS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1lWdDJYU0E5SURBN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR0V1Wm1sc2JDZ3dLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWVR0Y2JpQWdJQ0I5WEc1OVhHNWNibHh1WEc0dkx5QlhSVUpRUVVOTElFWlBUMVJGVWlBdkwxeHVMeThnTGk5K0wycHphR2x1ZEMxc2IyRmtaWEloTGk5c2FXSXZiVzlrWld4ekwzSmhaR2x2TG1weklpd2lkbUZ5SUZkQlFVTnNiMk5ySUQwZ2NtVnhkV2x5WlNnbkxpOXNhV0l2VjBGQlEyeHZZMnNuS1Z4dVhHNXRiMlIxYkdVdVpYaHdiM0owY3lBOUlGZEJRVU5zYjJOclhHNXBaaUFvZEhsd1pXOW1JSGRwYm1SdmR5QWhQVDBnSjNWdVpHVm1hVzVsWkNjcElIZHBibVJ2ZHk1WFFVRkRiRzlqYXlBOUlGZEJRVU5zYjJOclhHNWNibHh1WEc0dkx5OHZMeTh2THk4dkx5OHZMeTh2THk5Y2JpOHZJRmRGUWxCQlEwc2dSazlQVkVWU1hHNHZMeUF1TDM0dmQyRmhZMnh2WTJzdmFXNWtaWGd1YW5OY2JpOHZJRzF2WkhWc1pTQnBaQ0E5SURReVhHNHZMeUJ0YjJSMWJHVWdZMmgxYm10eklEMGdNQ0lzSW5aaGNpQnBjMEp5YjNkelpYSWdQU0FvZEhsd1pXOW1JSGRwYm1SdmR5QWhQVDBnSjNWdVpHVm1hVzVsWkNjcFhHNWNiblpoY2lCRFRFOURTMTlFUlVaQlZVeFVVeUE5SUh0Y2JpQWdkRzlzWlhKaGJtTmxUR0YwWlRvZ01DNHhNQ3hjYmlBZ2RHOXNaWEpoYm1ObFJXRnliSGs2SURBdU1EQXhYRzU5WEc1Y2JpOHZJRDA5UFQwOVBUMDlQVDA5UFQwOVBUMDlQVDA5SUVWMlpXNTBJRDA5UFQwOVBUMDlQVDA5UFQwOVBUMDlQVDA5SUM4dlhHNTJZWElnUlhabGJuUWdQU0JtZFc1amRHbHZiaWhqYkc5amF5d2daR1ZoWkd4cGJtVXNJR1oxYm1NcElIdGNiaUFnZEdocGN5NWpiRzlqYXlBOUlHTnNiMk5yWEc0Z0lIUm9hWE11Wm5WdVl5QTlJR1oxYm1OY2JpQWdkR2hwY3k1ZlkyeGxZWEpsWkNBOUlHWmhiSE5sSUM4dklFWnNZV2NnZFhObFpDQjBieUJqYkdWaGNpQmhiaUJsZG1WdWRDQnBibk5wWkdVZ1kyRnNiR0poWTJ0Y2JseHVJQ0IwYUdsekxuUnZiR1Z5WVc1alpVeGhkR1VnUFNCamJHOWpheTUwYjJ4bGNtRnVZMlZNWVhSbFhHNGdJSFJvYVhNdWRHOXNaWEpoYm1ObFJXRnliSGtnUFNCamJHOWpheTUwYjJ4bGNtRnVZMlZGWVhKc2VWeHVJQ0IwYUdsekxsOXNZWFJsYzNSVWFXMWxJRDBnYm5Wc2JGeHVJQ0IwYUdsekxsOWxZWEpzYVdWemRGUnBiV1VnUFNCdWRXeHNYRzRnSUhSb2FYTXVaR1ZoWkd4cGJtVWdQU0J1ZFd4c1hHNGdJSFJvYVhNdWNtVndaV0YwVkdsdFpTQTlJRzUxYkd4Y2JseHVJQ0IwYUdsekxuTmphR1ZrZFd4bEtHUmxZV1JzYVc1bEtWeHVmVnh1WEc0dkx5QlZibk5qYUdWa2RXeGxjeUIwYUdVZ1pYWmxiblJjYmtWMlpXNTBMbkJ5YjNSdmRIbHdaUzVqYkdWaGNpQTlJR1oxYm1OMGFXOXVLQ2tnZTF4dUlDQjBhR2x6TG1Oc2IyTnJMbDl5WlcxdmRtVkZkbVZ1ZENoMGFHbHpLVnh1SUNCMGFHbHpMbDlqYkdWaGNtVmtJRDBnZEhKMVpWeHVJQ0J5WlhSMWNtNGdkR2hwYzF4dWZWeHVYRzR2THlCVFpYUnpJSFJvWlNCbGRtVnVkQ0IwYnlCeVpYQmxZWFFnWlhabGNua2dZSFJwYldWZ0lITmxZMjl1WkhNdVhHNUZkbVZ1ZEM1d2NtOTBiM1I1Y0dVdWNtVndaV0YwSUQwZ1puVnVZM1JwYjI0b2RHbHRaU2tnZTF4dUlDQnBaaUFvZEdsdFpTQTlQVDBnTUNsY2JpQWdJQ0IwYUhKdmR5QnVaWGNnUlhKeWIzSW9KMlJsYkdGNUlHTmhibTV2ZENCaVpTQXdKeWxjYmlBZ2RHaHBjeTV5WlhCbFlYUlVhVzFsSUQwZ2RHbHRaVnh1SUNCcFppQW9JWFJvYVhNdVkyeHZZMnN1WDJoaGMwVjJaVzUwS0hSb2FYTXBLVnh1SUNBZ0lIUm9hWE11YzJOb1pXUjFiR1VvZEdocGN5NWtaV0ZrYkdsdVpTQXJJSFJvYVhNdWNtVndaV0YwVkdsdFpTbGNiaUFnY21WMGRYSnVJSFJvYVhOY2JuMWNibHh1THk4Z1UyVjBjeUIwYUdVZ2RHbHRaU0IwYjJ4bGNtRnVZMlVnYjJZZ2RHaGxJR1YyWlc1MExseHVMeThnVkdobElHVjJaVzUwSUhkcGJHd2dZbVVnWlhobFkzVjBaV1FnYVc0Z2RHaGxJR2x1ZEdWeWRtRnNJR0JiWkdWaFpHeHBibVVnTFNCbFlYSnNlU3dnWkdWaFpHeHBibVVnS3lCc1lYUmxYV0JjYmk4dklFbG1JSFJvWlNCamJHOWpheUJtWVdsc2N5QjBieUJsZUdWamRYUmxJSFJvWlNCbGRtVnVkQ0JwYmlCMGFXMWxMQ0IwYUdVZ1pYWmxiblFnZDJsc2JDQmlaU0JrY205d2NHVmtMbHh1UlhabGJuUXVjSEp2ZEc5MGVYQmxMblJ2YkdWeVlXNWpaU0E5SUdaMWJtTjBhVzl1S0haaGJIVmxjeWtnZTF4dUlDQnBaaUFvZEhsd1pXOW1JSFpoYkhWbGN5NXNZWFJsSUQwOVBTQW5iblZ0WW1WeUp5bGNiaUFnSUNCMGFHbHpMblJ2YkdWeVlXNWpaVXhoZEdVZ1BTQjJZV3gxWlhNdWJHRjBaVnh1SUNCcFppQW9kSGx3Wlc5bUlIWmhiSFZsY3k1bFlYSnNlU0E5UFQwZ0oyNTFiV0psY2ljcFhHNGdJQ0FnZEdocGN5NTBiMnhsY21GdVkyVkZZWEpzZVNBOUlIWmhiSFZsY3k1bFlYSnNlVnh1SUNCMGFHbHpMbDl5WldaeVpYTm9SV0Z5YkhsTVlYUmxSR0YwWlhNb0tWeHVJQ0JwWmlBb2RHaHBjeTVqYkc5amF5NWZhR0Z6UlhabGJuUW9kR2hwY3lrcElIdGNiaUFnSUNCMGFHbHpMbU5zYjJOckxsOXlaVzF2ZG1WRmRtVnVkQ2gwYUdsektWeHVJQ0FnSUhSb2FYTXVZMnh2WTJzdVgybHVjMlZ5ZEVWMlpXNTBLSFJvYVhNcFhHNGdJSDFjYmlBZ2NtVjBkWEp1SUhSb2FYTmNibjFjYmx4dUx5OGdVbVYwZFhKdWN5QjBjblZsSUdsbUlIUm9aU0JsZG1WdWRDQnBjeUJ5WlhCbFlYUmxaQ3dnWm1Gc2MyVWdiM1JvWlhKM2FYTmxYRzVGZG1WdWRDNXdjbTkwYjNSNWNHVXVhWE5TWlhCbFlYUmxaQ0E5SUdaMWJtTjBhVzl1S0NrZ2V5QnlaWFIxY200Z2RHaHBjeTV5WlhCbFlYUlVhVzFsSUNFOVBTQnVkV3hzSUgxY2JseHVMeThnVTJOb1pXUjFiR1Z6SUhSb1pTQmxkbVZ1ZENCMGJ5QmlaU0J5WVc0Z1ltVm1iM0psSUdCa1pXRmtiR2x1WldBdVhHNHZMeUJKWmlCMGFHVWdkR2x0WlNCcGN5QjNhWFJvYVc0Z2RHaGxJR1YyWlc1MElIUnZiR1Z5WVc1alpTd2dkMlVnYUdGdVpHeGxJSFJvWlNCbGRtVnVkQ0JwYlcxbFpHbGhkR1ZzZVM1Y2JpOHZJRWxtSUhSb1pTQmxkbVZ1ZENCM1lYTWdZV3h5WldGa2VTQnpZMmhsWkhWc1pXUWdZWFFnWVNCa2FXWm1aWEpsYm5RZ2RHbHRaU3dnYVhRZ2FYTWdjbVZ6WTJobFpIVnNaV1F1WEc1RmRtVnVkQzV3Y205MGIzUjVjR1V1YzJOb1pXUjFiR1VnUFNCbWRXNWpkR2x2Ymloa1pXRmtiR2x1WlNrZ2UxeHVJQ0IwYUdsekxsOWpiR1ZoY21Wa0lEMGdabUZzYzJWY2JpQWdkR2hwY3k1a1pXRmtiR2x1WlNBOUlHUmxZV1JzYVc1bFhHNGdJSFJvYVhNdVgzSmxabkpsYzJoRllYSnNlVXhoZEdWRVlYUmxjeWdwWEc1Y2JpQWdhV1lnS0hSb2FYTXVZMnh2WTJzdVkyOXVkR1Y0ZEM1amRYSnlaVzUwVkdsdFpTQStQU0IwYUdsekxsOWxZWEpzYVdWemRGUnBiV1VwSUh0Y2JpQWdJQ0IwYUdsekxsOWxlR1ZqZFhSbEtDbGNiaUFnWEc0Z0lIMGdaV3h6WlNCcFppQW9kR2hwY3k1amJHOWpheTVmYUdGelJYWmxiblFvZEdocGN5a3BJSHRjYmlBZ0lDQjBhR2x6TG1Oc2IyTnJMbDl5WlcxdmRtVkZkbVZ1ZENoMGFHbHpLVnh1SUNBZ0lIUm9hWE11WTJ4dlkyc3VYMmx1YzJWeWRFVjJaVzUwS0hSb2FYTXBYRzRnSUZ4dUlDQjlJR1ZzYzJVZ2RHaHBjeTVqYkc5amF5NWZhVzV6WlhKMFJYWmxiblFvZEdocGN5bGNibjFjYmx4dVJYWmxiblF1Y0hKdmRHOTBlWEJsTG5ScGJXVlRkSEpsZEdOb0lEMGdablZ1WTNScGIyNG9kRkpsWml3Z2NtRjBhVzhwSUh0Y2JpQWdhV1lnS0hSb2FYTXVhWE5TWlhCbFlYUmxaQ2dwS1Z4dUlDQWdJSFJvYVhNdWNtVndaV0YwVkdsdFpTQTlJSFJvYVhNdWNtVndaV0YwVkdsdFpTQXFJSEpoZEdsdlhHNWNiaUFnZG1GeUlHUmxZV1JzYVc1bElEMGdkRkpsWmlBcklISmhkR2x2SUNvZ0tIUm9hWE11WkdWaFpHeHBibVVnTFNCMFVtVm1LVnh1SUNBdkx5QkpaaUIwYUdVZ1pHVmhaR3hwYm1VZ2FYTWdkRzl2SUdOc2IzTmxJRzl5SUhCaGMzUXNJR0Z1WkNCMGFHVWdaWFpsYm5RZ2FHRnpJR0VnY21Wd1pXRjBMRnh1SUNBdkx5QjNaU0JqWVd4amRXeGhkR1VnZEdobElHNWxlSFFnY21Wd1pXRjBJSEJ2YzNOcFlteGxJR2x1SUhSb1pTQnpkSEpsZEdOb1pXUWdjM0JoWTJVdVhHNGdJR2xtSUNoMGFHbHpMbWx6VW1Wd1pXRjBaV1FvS1NrZ2UxeHVJQ0FnSUhkb2FXeGxJQ2gwYUdsekxtTnNiMk5yTG1OdmJuUmxlSFF1WTNWeWNtVnVkRlJwYldVZ1BqMGdaR1ZoWkd4cGJtVWdMU0IwYUdsekxuUnZiR1Z5WVc1alpVVmhjbXg1S1Z4dUlDQWdJQ0FnWkdWaFpHeHBibVVnS3owZ2RHaHBjeTV5WlhCbFlYUlVhVzFsWEc0Z0lIMWNiaUFnZEdocGN5NXpZMmhsWkhWc1pTaGtaV0ZrYkdsdVpTbGNibjFjYmx4dUx5OGdSWGhsWTNWMFpYTWdkR2hsSUdWMlpXNTBYRzVGZG1WdWRDNXdjbTkwYjNSNWNHVXVYMlY0WldOMWRHVWdQU0JtZFc1amRHbHZiaWdwSUh0Y2JpQWdhV1lnS0hSb2FYTXVZMnh2WTJzdVgzTjBZWEowWldRZ1BUMDlJR1poYkhObEtTQnlaWFIxY201Y2JpQWdkR2hwY3k1amJHOWpheTVmY21WdGIzWmxSWFpsYm5Rb2RHaHBjeWxjYmx4dUlDQnBaaUFvZEdocGN5NWpiRzlqYXk1amIyNTBaWGgwTG1OMWNuSmxiblJVYVcxbElEd2dkR2hwY3k1ZmJHRjBaWE4wVkdsdFpTbGNiaUFnSUNCMGFHbHpMbVoxYm1Nb2RHaHBjeWxjYmlBZ1pXeHpaU0I3WEc0Z0lDQWdhV1lnS0hSb2FYTXViMjVsZUhCcGNtVmtLU0IwYUdsekxtOXVaWGh3YVhKbFpDaDBhR2x6S1Z4dUlDQWdJR052Ym5OdmJHVXVkMkZ5YmlnblpYWmxiblFnWlhod2FYSmxaQ2NwWEc0Z0lIMWNiaUFnTHk4Z1NXNGdkR2hsSUdOaGMyVWdZSE5qYUdWa2RXeGxZQ0JwY3lCallXeHNaV1FnYVc1emFXUmxJR0JtZFc1allDd2dkMlVnYm1WbFpDQjBieUJoZG05cFpGeHVJQ0F2THlCdmRtVnljbmR5YVhScGJtY2dkMmwwYUNCNVpYUWdZVzV2ZEdobGNpQmdjMk5vWldSMWJHVmdMbHh1SUNCcFppQW9JWFJvYVhNdVkyeHZZMnN1WDJoaGMwVjJaVzUwS0hSb2FYTXBJQ1ltSUhSb2FYTXVhWE5TWlhCbFlYUmxaQ2dwSUNZbUlDRjBhR2x6TGw5amJHVmhjbVZrS1Z4dUlDQWdJSFJvYVhNdWMyTm9aV1IxYkdVb2RHaHBjeTVrWldGa2JHbHVaU0FySUhSb2FYTXVjbVZ3WldGMFZHbHRaU2tnWEc1OVhHNWNiaTh2SUZWd1pHRjBaWE1nWTJGamFHVmtJSFJwYldWelhHNUZkbVZ1ZEM1d2NtOTBiM1I1Y0dVdVgzSmxabkpsYzJoRllYSnNlVXhoZEdWRVlYUmxjeUE5SUdaMWJtTjBhVzl1S0NrZ2UxeHVJQ0IwYUdsekxsOXNZWFJsYzNSVWFXMWxJRDBnZEdocGN5NWtaV0ZrYkdsdVpTQXJJSFJvYVhNdWRHOXNaWEpoYm1ObFRHRjBaVnh1SUNCMGFHbHpMbDlsWVhKc2FXVnpkRlJwYldVZ1BTQjBhR2x6TG1SbFlXUnNhVzVsSUMwZ2RHaHBjeTUwYjJ4bGNtRnVZMlZGWVhKc2VWeHVmVnh1WEc0dkx5QTlQVDA5UFQwOVBUMDlQVDA5UFQwOVBUMDlQU0JYUVVGRGJHOWpheUE5UFQwOVBUMDlQVDA5UFQwOVBUMDlQVDA5UFNBdkwxeHVkbUZ5SUZkQlFVTnNiMk5ySUQwZ2JXOWtkV3hsTG1WNGNHOXlkSE1nUFNCbWRXNWpkR2x2YmloamIyNTBaWGgwTENCdmNIUnpLU0I3WEc0Z0lIWmhjaUJ6Wld4bUlEMGdkR2hwYzF4dUlDQnZjSFJ6SUQwZ2IzQjBjeUI4ZkNCN2ZWeHVJQ0IwYUdsekxuUnBZMnROWlhSb2IyUWdQU0J2Y0hSekxuUnBZMnROWlhSb2IyUWdmSHdnSjFOamNtbHdkRkJ5YjJObGMzTnZjazV2WkdVblhHNGdJSFJvYVhNdWRHOXNaWEpoYm1ObFJXRnliSGtnUFNCdmNIUnpMblJ2YkdWeVlXNWpaVVZoY214NUlIeDhJRU5NVDBOTFgwUkZSa0ZWVEZSVExuUnZiR1Z5WVc1alpVVmhjbXg1WEc0Z0lIUm9hWE11ZEc5c1pYSmhibU5sVEdGMFpTQTlJRzl3ZEhNdWRHOXNaWEpoYm1ObFRHRjBaU0I4ZkNCRFRFOURTMTlFUlVaQlZVeFVVeTUwYjJ4bGNtRnVZMlZNWVhSbFhHNGdJSFJvYVhNdVkyOXVkR1Y0ZENBOUlHTnZiblJsZUhSY2JpQWdkR2hwY3k1ZlpYWmxiblJ6SUQwZ1cxMWNiaUFnZEdocGN5NWZjM1JoY25SbFpDQTlJR1poYkhObFhHNTlYRzVjYmk4dklDMHRMUzB0TFMwdExTMGdVSFZpYkdsaklFRlFTU0F0TFMwdExTMHRMUzB0SUM4dlhHNHZMeUJUWTJobFpIVnNaWE1nWUdaMWJtTmdJSFJ2SUhKMWJpQmhablJsY2lCZ1pHVnNZWGxnSUhObFkyOXVaSE11WEc1WFFVRkRiRzlqYXk1d2NtOTBiM1I1Y0dVdWMyVjBWR2x0Wlc5MWRDQTlJR1oxYm1OMGFXOXVLR1oxYm1Nc0lHUmxiR0Y1S1NCN1hHNGdJSEpsZEhWeWJpQjBhR2x6TGw5amNtVmhkR1ZGZG1WdWRDaG1kVzVqTENCMGFHbHpMbDloWW5OVWFXMWxLR1JsYkdGNUtTbGNibjFjYmx4dUx5OGdVMk5vWldSMWJHVnpJR0JtZFc1allDQjBieUJ5ZFc0Z1ltVm1iM0psSUdCa1pXRmtiR2x1WldBdVhHNVhRVUZEYkc5amF5NXdjbTkwYjNSNWNHVXVZMkZzYkdKaFkydEJkRlJwYldVZ1BTQm1kVzVqZEdsdmJpaG1kVzVqTENCa1pXRmtiR2x1WlNrZ2UxeHVJQ0J5WlhSMWNtNGdkR2hwY3k1ZlkzSmxZWFJsUlhabGJuUW9ablZ1WXl3Z1pHVmhaR3hwYm1VcFhHNTlYRzVjYmk4dklGTjBjbVYwWTJobGN5QmdaR1ZoWkd4cGJtVmdJR0Z1WkNCZ2NtVndaV0YwWUNCdlppQmhiR3dnYzJOb1pXUjFiR1ZrSUdCbGRtVnVkSE5nSUdKNUlHQnlZWFJwYjJBc0lHdGxaWEJwYm1kY2JpOHZJSFJvWldseUlISmxiR0YwYVhabElHUnBjM1JoYm1ObElIUnZJR0IwVW1WbVlDNGdTVzRnWm1GamRDQjBhR2x6SUdseklHVnhkV2wyWVd4bGJuUWdkRzhnWTJoaGJtZHBibWNnZEdobElIUmxiWEJ2TGx4dVYwRkJRMnh2WTJzdWNISnZkRzkwZVhCbExuUnBiV1ZUZEhKbGRHTm9JRDBnWm5WdVkzUnBiMjRvZEZKbFppd2daWFpsYm5SekxDQnlZWFJwYnlrZ2UxeHVJQ0JsZG1WdWRITXVabTl5UldGamFDaG1kVzVqZEdsdmJpaGxkbVZ1ZENrZ2V5QmxkbVZ1ZEM1MGFXMWxVM1J5WlhSamFDaDBVbVZtTENCeVlYUnBieWtnZlNsY2JpQWdjbVYwZFhKdUlHVjJaVzUwYzF4dWZWeHVYRzR2THlCU1pXMXZkbVZ6SUdGc2JDQnpZMmhsWkhWc1pXUWdaWFpsYm5SeklHRnVaQ0J6ZEdGeWRITWdkR2hsSUdOc2IyTnJJRnh1VjBGQlEyeHZZMnN1Y0hKdmRHOTBlWEJsTG5OMFlYSjBJRDBnWm5WdVkzUnBiMjRvS1NCN1hHNGdJR2xtSUNoMGFHbHpMbDl6ZEdGeWRHVmtJRDA5UFNCbVlXeHpaU2tnZTF4dUlDQWdJSFpoY2lCelpXeG1JRDBnZEdocGMxeHVJQ0FnSUhSb2FYTXVYM04wWVhKMFpXUWdQU0IwY25WbFhHNGdJQ0FnZEdocGN5NWZaWFpsYm5SeklEMGdXMTFjYmx4dUlDQWdJR2xtSUNoMGFHbHpMblJwWTJ0TlpYUm9iMlFnUFQwOUlDZFRZM0pwY0hSUWNtOWpaWE56YjNKT2IyUmxKeWtnZTF4dUlDQWdJQ0FnZG1GeUlHSjFabVpsY2xOcGVtVWdQU0F5TlRaY2JpQWdJQ0FnSUM4dklGZGxJR2hoZG1VZ2RHOGdhMlZsY0NCaElISmxabVZ5Wlc1alpTQjBieUIwYUdVZ2JtOWtaU0IwYnlCaGRtOXBaQ0JuWVhKaVlXZGxJR052Ykd4bFkzUnBiMjVjYmlBZ0lDQWdJSFJvYVhNdVgyTnNiMk5yVG05a1pTQTlJSFJvYVhNdVkyOXVkR1Y0ZEM1amNtVmhkR1ZUWTNKcGNIUlFjbTlqWlhOemIzSW9ZblZtWm1WeVUybDZaU3dnTVN3Z01TbGNiaUFnSUNBZ0lIUm9hWE11WDJOc2IyTnJUbTlrWlM1amIyNXVaV04wS0hSb2FYTXVZMjl1ZEdWNGRDNWtaWE4wYVc1aGRHbHZiaWxjYmlBZ0lDQWdJSFJvYVhNdVgyTnNiMk5yVG05a1pTNXZibUYxWkdsdmNISnZZMlZ6Y3lBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnY0hKdlkyVnpjeTV1WlhoMFZHbGpheWhtZFc1amRHbHZiaWdwSUhzZ2MyVnNaaTVmZEdsamF5Z3BJSDBwWEc0Z0lDQWdJQ0I5WEc0Z0lDQWdmU0JsYkhObElHbG1JQ2gwYUdsekxuUnBZMnROWlhSb2IyUWdQVDA5SUNkdFlXNTFZV3duS1NCdWRXeHNJQzh2SUY5MGFXTnJJR2x6SUdOaGJHeGxaQ0J0WVc1MVlXeHNlVnh1WEc0Z0lDQWdaV3h6WlNCMGFISnZkeUJ1WlhjZ1JYSnliM0lvSjJsdWRtRnNhV1FnZEdsamEwMWxkR2h2WkNBbklDc2dkR2hwY3k1MGFXTnJUV1YwYUc5a0tWeHVJQ0I5WEc1OVhHNWNiaTh2SUZOMGIzQnpJSFJvWlNCamJHOWphMXh1VjBGQlEyeHZZMnN1Y0hKdmRHOTBlWEJsTG5OMGIzQWdQU0JtZFc1amRHbHZiaWdwSUh0Y2JpQWdhV1lnS0hSb2FYTXVYM04wWVhKMFpXUWdQVDA5SUhSeWRXVXBJSHRjYmlBZ0lDQjBhR2x6TGw5emRHRnlkR1ZrSUQwZ1ptRnNjMlZjYmlBZ0lDQjBhR2x6TGw5amJHOWphMDV2WkdVdVpHbHpZMjl1Ym1WamRDZ3BYRzRnSUgwZ0lGeHVmVnh1WEc0dkx5QXRMUzB0TFMwdExTMHRJRkJ5YVhaaGRHVWdMUzB0TFMwdExTMHRMU0F2TDF4dVhHNHZMeUJVYUdseklHWjFibU4wYVc5dUlHbHpJSEpoYmlCd1pYSnBiMlJwWTJGc2JIa3NJR0Z1WkNCaGRDQmxZV05vSUhScFkyc2dhWFFnWlhobFkzVjBaWE5jYmk4dklHVjJaVzUwY3lCbWIzSWdkMmhwWTJnZ1lHTjFjbkpsYm5SVWFXMWxZQ0JwY3lCcGJtTnNkV1JsWkNCcGJpQjBhR1ZwY2lCMGIyeGxjbUZ1WTJVZ2FXNTBaWEoyWVd3dVhHNVhRVUZEYkc5amF5NXdjbTkwYjNSNWNHVXVYM1JwWTJzZ1BTQm1kVzVqZEdsdmJpZ3BJSHRjYmlBZ2RtRnlJR1YyWlc1MElEMGdkR2hwY3k1ZlpYWmxiblJ6TG5Ob2FXWjBLQ2xjYmx4dUlDQjNhR2xzWlNobGRtVnVkQ0FtSmlCbGRtVnVkQzVmWldGeWJHbGxjM1JVYVcxbElEdzlJSFJvYVhNdVkyOXVkR1Y0ZEM1amRYSnlaVzUwVkdsdFpTa2dlMXh1SUNBZ0lHVjJaVzUwTGw5bGVHVmpkWFJsS0NsY2JpQWdJQ0JsZG1WdWRDQTlJSFJvYVhNdVgyVjJaVzUwY3k1emFHbG1kQ2dwWEc0Z0lIMWNibHh1SUNBdkx5QlFkWFFnWW1GamF5QjBhR1VnYkdGemRDQmxkbVZ1ZEZ4dUlDQnBaaWhsZG1WdWRDa2dkR2hwY3k1ZlpYWmxiblJ6TG5WdWMyaHBablFvWlhabGJuUXBYRzU5WEc1Y2JpOHZJRU55WldGMFpYTWdZVzRnWlhabGJuUWdZVzVrSUdsdWMyVnlkQ0JwZENCMGJ5QjBhR1VnYkdsemRGeHVWMEZCUTJ4dlkyc3VjSEp2ZEc5MGVYQmxMbDlqY21WaGRHVkZkbVZ1ZENBOUlHWjFibU4wYVc5dUtHWjFibU1zSUdSbFlXUnNhVzVsS1NCN1hHNGdJSEpsZEhWeWJpQnVaWGNnUlhabGJuUW9kR2hwY3l3Z1pHVmhaR3hwYm1Vc0lHWjFibU1wWEc1OVhHNWNiaTh2SUVsdWMyVnlkSE1nWVc0Z1pYWmxiblFnZEc4Z2RHaGxJR3hwYzNSY2JsZEJRVU5zYjJOckxuQnliM1J2ZEhsd1pTNWZhVzV6WlhKMFJYWmxiblFnUFNCbWRXNWpkR2x2YmlobGRtVnVkQ2tnZTF4dUlDQjBhR2x6TGw5bGRtVnVkSE11YzNCc2FXTmxLSFJvYVhNdVgybHVaR1Y0UW5sVWFXMWxLR1YyWlc1MExsOWxZWEpzYVdWemRGUnBiV1VwTENBd0xDQmxkbVZ1ZENsY2JuMWNibHh1THk4Z1VtVnRiM1psY3lCaGJpQmxkbVZ1ZENCbWNtOXRJSFJvWlNCc2FYTjBYRzVYUVVGRGJHOWpheTV3Y205MGIzUjVjR1V1WDNKbGJXOTJaVVYyWlc1MElEMGdablZ1WTNScGIyNG9aWFpsYm5RcElIdGNiaUFnZG1GeUlHbHVaQ0E5SUhSb2FYTXVYMlYyWlc1MGN5NXBibVJsZUU5bUtHVjJaVzUwS1Z4dUlDQnBaaUFvYVc1a0lDRTlQU0F0TVNrZ2RHaHBjeTVmWlhabGJuUnpMbk53YkdsalpTaHBibVFzSURFcFhHNTlYRzVjYmk4dklGSmxkSFZ5Ym5NZ2RISjFaU0JwWmlCZ1pYWmxiblJnSUdseklHbHVJSEYxWlhWbExDQm1ZV3h6WlNCdmRHaGxjbmRwYzJWY2JsZEJRVU5zYjJOckxuQnliM1J2ZEhsd1pTNWZhR0Z6UlhabGJuUWdQU0JtZFc1amRHbHZiaWhsZG1WdWRDa2dlMXh1SUhKbGRIVnliaUIwYUdsekxsOWxkbVZ1ZEhNdWFXNWtaWGhQWmlobGRtVnVkQ2tnSVQwOUlDMHhYRzU5WEc1Y2JpOHZJRkpsZEhWeWJuTWdkR2hsSUdsdVpHVjRJRzltSUhSb1pTQm1hWEp6ZENCbGRtVnVkQ0IzYUc5elpTQmtaV0ZrYkdsdVpTQnBjeUErUFNCMGJ5QmdaR1ZoWkd4cGJtVmdYRzVYUVVGRGJHOWpheTV3Y205MGIzUjVjR1V1WDJsdVpHVjRRbmxVYVcxbElEMGdablZ1WTNScGIyNG9aR1ZoWkd4cGJtVXBJSHRjYmlBZ0x5OGdjR1Z5Wm05eWJYTWdZU0JpYVc1aGNua2djMlZoY21Ob1hHNGdJSFpoY2lCc2IzY2dQU0F3WEc0Z0lDQWdMQ0JvYVdkb0lEMGdkR2hwY3k1ZlpYWmxiblJ6TG14bGJtZDBhRnh1SUNBZ0lDd2diV2xrWEc0Z0lIZG9hV3hsSUNoc2IzY2dQQ0JvYVdkb0tTQjdYRzRnSUNBZ2JXbGtJRDBnVFdGMGFDNW1iRzl2Y2lnb2JHOTNJQ3NnYUdsbmFDa2dMeUF5S1Z4dUlDQWdJR2xtSUNoMGFHbHpMbDlsZG1WdWRITmJiV2xrWFM1ZlpXRnliR2xsYzNSVWFXMWxJRHdnWkdWaFpHeHBibVVwWEc0Z0lDQWdJQ0JzYjNjZ1BTQnRhV1FnS3lBeFhHNGdJQ0FnWld4elpTQm9hV2RvSUQwZ2JXbGtYRzRnSUgxY2JpQWdjbVYwZFhKdUlHeHZkMXh1ZlZ4dVhHNHZMeUJEYjI1MlpYSjBjeUJtY205dElISmxiR0YwYVhabElIUnBiV1VnZEc4Z1lXSnpiMngxZEdVZ2RHbHRaVnh1VjBGQlEyeHZZMnN1Y0hKdmRHOTBlWEJsTGw5aFluTlVhVzFsSUQwZ1puVnVZM1JwYjI0b2NtVnNWR2x0WlNrZ2UxeHVJQ0J5WlhSMWNtNGdjbVZzVkdsdFpTQXJJSFJvYVhNdVkyOXVkR1Y0ZEM1amRYSnlaVzUwVkdsdFpWeHVmVnh1WEc0dkx5QkRiMjUyWlhKMGN5Qm1jbTl0SUdGaWMyOXNkWFJsSUhScGJXVWdkRzhnY21Wc1lYUnBkbVVnZEdsdFpTQmNibGRCUVVOc2IyTnJMbkJ5YjNSdmRIbHdaUzVmY21Wc1ZHbHRaU0E5SUdaMWJtTjBhVzl1S0dGaWMxUnBiV1VwSUh0Y2JpQWdjbVYwZFhKdUlHRmljMVJwYldVZ0xTQjBhR2x6TG1OdmJuUmxlSFF1WTNWeWNtVnVkRlJwYldWY2JuMWNibHh1WEc0dkx5OHZMeTh2THk4dkx5OHZMeTh2THk5Y2JpOHZJRmRGUWxCQlEwc2dSazlQVkVWU1hHNHZMeUF1TDM0dmQyRmhZMnh2WTJzdmJHbGlMMWRCUVVOc2IyTnJMbXB6WEc0dkx5QnRiMlIxYkdVZ2FXUWdQU0EwTTF4dUx5OGdiVzlrZFd4bElHTm9kVzVyY3lBOUlEQWlMQ0l2THlCemFHbHRJR1p2Y2lCMWMybHVaeUJ3Y205alpYTnpJR2x1SUdKeWIzZHpaWEpjYm5aaGNpQndjbTlqWlhOeklEMGdiVzlrZFd4bExtVjRjRzl5ZEhNZ1BTQjdmVHRjYmx4dUx5OGdZMkZqYUdWa0lHWnliMjBnZDJoaGRHVjJaWElnWjJ4dlltRnNJR2x6SUhCeVpYTmxiblFnYzI4Z2RHaGhkQ0IwWlhOMElISjFibTVsY25NZ2RHaGhkQ0J6ZEhWaUlHbDBYRzR2THlCa2IyNG5kQ0JpY21WaGF5QjBhR2x1WjNNdUlDQkNkWFFnZDJVZ2JtVmxaQ0IwYnlCM2NtRndJR2wwSUdsdUlHRWdkSEo1SUdOaGRHTm9JR2x1SUdOaGMyVWdhWFFnYVhOY2JpOHZJSGR5WVhCd1pXUWdhVzRnYzNSeWFXTjBJRzF2WkdVZ1kyOWtaU0IzYUdsamFDQmtiMlZ6YmlkMElHUmxabWx1WlNCaGJua2daMnh2WW1Gc2N5NGdJRWwwSjNNZ2FXNXphV1JsSUdGY2JpOHZJR1oxYm1OMGFXOXVJR0psWTJGMWMyVWdkSEo1TDJOaGRHTm9aWE1nWkdWdmNIUnBiV2w2WlNCcGJpQmpaWEowWVdsdUlHVnVaMmx1WlhNdVhHNWNiblpoY2lCallXTm9aV1JUWlhSVWFXMWxiM1YwTzF4dWRtRnlJR05oWTJobFpFTnNaV0Z5VkdsdFpXOTFkRHRjYmx4dVpuVnVZM1JwYjI0Z1pHVm1ZWFZzZEZObGRGUnBiVzkxZENncElIdGNiaUFnSUNCMGFISnZkeUJ1WlhjZ1JYSnliM0lvSjNObGRGUnBiV1Z2ZFhRZ2FHRnpJRzV2ZENCaVpXVnVJR1JsWm1sdVpXUW5LVHRjYm4xY2JtWjFibU4wYVc5dUlHUmxabUYxYkhSRGJHVmhjbFJwYldWdmRYUWdLQ2tnZTF4dUlDQWdJSFJvY205M0lHNWxkeUJGY25KdmNpZ25ZMnhsWVhKVWFXMWxiM1YwSUdoaGN5QnViM1FnWW1WbGJpQmtaV1pwYm1Wa0p5azdYRzU5WEc0b1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lIUnllU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaDBlWEJsYjJZZ2MyVjBWR2x0Wlc5MWRDQTlQVDBnSjJaMWJtTjBhVzl1SnlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWTJGamFHVmtVMlYwVkdsdFpXOTFkQ0E5SUhObGRGUnBiV1Z2ZFhRN1hHNGdJQ0FnSUNBZ0lIMGdaV3h6WlNCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JqWVdOb1pXUlRaWFJVYVcxbGIzVjBJRDBnWkdWbVlYVnNkRk5sZEZScGJXOTFkRHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDBnWTJGMFkyZ2dLR1VwSUh0Y2JpQWdJQ0FnSUNBZ1kyRmphR1ZrVTJWMFZHbHRaVzkxZENBOUlHUmxabUYxYkhSVFpYUlVhVzF2ZFhRN1hHNGdJQ0FnZlZ4dUlDQWdJSFJ5ZVNCN1hHNGdJQ0FnSUNBZ0lHbG1JQ2gwZVhCbGIyWWdZMnhsWVhKVWFXMWxiM1YwSUQwOVBTQW5ablZ1WTNScGIyNG5LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQmpZV05vWldSRGJHVmhjbFJwYldWdmRYUWdQU0JqYkdWaGNsUnBiV1Z2ZFhRN1hHNGdJQ0FnSUNBZ0lIMGdaV3h6WlNCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JqWVdOb1pXUkRiR1ZoY2xScGJXVnZkWFFnUFNCa1pXWmhkV3gwUTJ4bFlYSlVhVzFsYjNWME8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZTQmpZWFJqYUNBb1pTa2dlMXh1SUNBZ0lDQWdJQ0JqWVdOb1pXUkRiR1ZoY2xScGJXVnZkWFFnUFNCa1pXWmhkV3gwUTJ4bFlYSlVhVzFsYjNWME8xeHVJQ0FnSUgxY2JuMGdLQ2twWEc1bWRXNWpkR2x2YmlCeWRXNVVhVzFsYjNWMEtHWjFiaWtnZTF4dUlDQWdJR2xtSUNoallXTm9aV1JUWlhSVWFXMWxiM1YwSUQwOVBTQnpaWFJVYVcxbGIzVjBLU0I3WEc0Z0lDQWdJQ0FnSUM4dmJtOXliV0ZzSUdWdWRtbHliMjFsYm5SeklHbHVJSE5oYm1VZ2MybDBkV0YwYVc5dWMxeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2MyVjBWR2x0Wlc5MWRDaG1kVzRzSURBcE8xeHVJQ0FnSUgxY2JpQWdJQ0F2THlCcFppQnpaWFJVYVcxbGIzVjBJSGRoYzI0bmRDQmhkbUZwYkdGaWJHVWdZblYwSUhkaGN5QnNZWFIwWlhJZ1pHVm1hVzVsWkZ4dUlDQWdJR2xtSUNnb1kyRmphR1ZrVTJWMFZHbHRaVzkxZENBOVBUMGdaR1ZtWVhWc2RGTmxkRlJwYlc5MWRDQjhmQ0FoWTJGamFHVmtVMlYwVkdsdFpXOTFkQ2tnSmlZZ2MyVjBWR2x0Wlc5MWRDa2dlMXh1SUNBZ0lDQWdJQ0JqWVdOb1pXUlRaWFJVYVcxbGIzVjBJRDBnYzJWMFZHbHRaVzkxZER0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhObGRGUnBiV1Z2ZFhRb1puVnVMQ0F3S1R0Y2JpQWdJQ0I5WEc0Z0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0x5OGdkMmhsYmlCM2FHVnVJSE52YldWaWIyUjVJR2hoY3lCelkzSmxkMlZrSUhkcGRHZ2djMlYwVkdsdFpXOTFkQ0JpZFhRZ2JtOGdTUzVGTGlCdFlXUmtibVZ6YzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWTJGamFHVmtVMlYwVkdsdFpXOTFkQ2htZFc0c0lEQXBPMXh1SUNBZ0lIMGdZMkYwWTJnb1pTbDdYRzRnSUNBZ0lDQWdJSFJ5ZVNCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCWGFHVnVJSGRsSUdGeVpTQnBiaUJKTGtVdUlHSjFkQ0IwYUdVZ2MyTnlhWEIwSUdoaGN5QmlaV1Z1SUdWMllXeGxaQ0J6YnlCSkxrVXVJR1J2WlhOdUozUWdkSEoxYzNRZ2RHaGxJR2RzYjJKaGJDQnZZbXBsWTNRZ2QyaGxiaUJqWVd4c1pXUWdibTl5YldGc2JIbGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJqWVdOb1pXUlRaWFJVYVcxbGIzVjBMbU5oYkd3b2JuVnNiQ3dnWm5WdUxDQXdLVHRjYmlBZ0lDQWdJQ0FnZlNCallYUmphQ2hsS1h0Y2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUhOaGJXVWdZWE1nWVdKdmRtVWdZblYwSUhkb1pXNGdhWFFuY3lCaElIWmxjbk5wYjI0Z2IyWWdTUzVGTGlCMGFHRjBJRzExYzNRZ2FHRjJaU0IwYUdVZ1oyeHZZbUZzSUc5aWFtVmpkQ0JtYjNJZ0ozUm9hWE1uTENCb2IzQm1kV3hzZVNCdmRYSWdZMjl1ZEdWNGRDQmpiM0p5WldOMElHOTBhR1Z5ZDJselpTQnBkQ0IzYVd4c0lIUm9jbTkzSUdFZ1oyeHZZbUZzSUdWeWNtOXlYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnWTJGamFHVmtVMlYwVkdsdFpXOTFkQzVqWVd4c0tIUm9hWE1zSUdaMWJpd2dNQ2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5WEc1Y2JseHVmVnh1Wm5WdVkzUnBiMjRnY25WdVEyeGxZWEpVYVcxbGIzVjBLRzFoY210bGNpa2dlMXh1SUNBZ0lHbG1JQ2hqWVdOb1pXUkRiR1ZoY2xScGJXVnZkWFFnUFQwOUlHTnNaV0Z5VkdsdFpXOTFkQ2tnZTF4dUlDQWdJQ0FnSUNBdkwyNXZjbTFoYkNCbGJuWnBjbTl0Wlc1MGN5QnBiaUJ6WVc1bElITnBkSFZoZEdsdmJuTmNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTnNaV0Z5VkdsdFpXOTFkQ2h0WVhKclpYSXBPMXh1SUNBZ0lIMWNiaUFnSUNBdkx5QnBaaUJqYkdWaGNsUnBiV1Z2ZFhRZ2QyRnpiaWQwSUdGMllXbHNZV0pzWlNCaWRYUWdkMkZ6SUd4aGRIUmxjaUJrWldacGJtVmtYRzRnSUNBZ2FXWWdLQ2hqWVdOb1pXUkRiR1ZoY2xScGJXVnZkWFFnUFQwOUlHUmxabUYxYkhSRGJHVmhjbFJwYldWdmRYUWdmSHdnSVdOaFkyaGxaRU5zWldGeVZHbHRaVzkxZENrZ0ppWWdZMnhsWVhKVWFXMWxiM1YwS1NCN1hHNGdJQ0FnSUNBZ0lHTmhZMmhsWkVOc1pXRnlWR2x0Wlc5MWRDQTlJR05zWldGeVZHbHRaVzkxZER0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOc1pXRnlWR2x0Wlc5MWRDaHRZWEpyWlhJcE8xeHVJQ0FnSUgxY2JpQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQXZMeUIzYUdWdUlIZG9aVzRnYzI5dFpXSnZaSGtnYUdGeklITmpjbVYzWldRZ2QybDBhQ0J6WlhSVWFXMWxiM1YwSUdKMWRDQnVieUJKTGtVdUlHMWhaR1J1WlhOelhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCallXTm9aV1JEYkdWaGNsUnBiV1Z2ZFhRb2JXRnlhMlZ5S1R0Y2JpQWdJQ0I5SUdOaGRHTm9JQ2hsS1h0Y2JpQWdJQ0FnSUNBZ2RISjVJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRmRvWlc0Z2QyVWdZWEpsSUdsdUlFa3VSUzRnWW5WMElIUm9aU0J6WTNKcGNIUWdhR0Z6SUdKbFpXNGdaWFpoYkdWa0lITnZJRWt1UlM0Z1pHOWxjMjRuZENBZ2RISjFjM1FnZEdobElHZHNiMkpoYkNCdlltcGxZM1FnZDJobGJpQmpZV3hzWldRZ2JtOXliV0ZzYkhsY2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQmpZV05vWldSRGJHVmhjbFJwYldWdmRYUXVZMkZzYkNodWRXeHNMQ0J0WVhKclpYSXBPMXh1SUNBZ0lDQWdJQ0I5SUdOaGRHTm9JQ2hsS1h0Y2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUhOaGJXVWdZWE1nWVdKdmRtVWdZblYwSUhkb1pXNGdhWFFuY3lCaElIWmxjbk5wYjI0Z2IyWWdTUzVGTGlCMGFHRjBJRzExYzNRZ2FHRjJaU0IwYUdVZ1oyeHZZbUZzSUc5aWFtVmpkQ0JtYjNJZ0ozUm9hWE1uTENCb2IzQm1kV3hzZVNCdmRYSWdZMjl1ZEdWNGRDQmpiM0p5WldOMElHOTBhR1Z5ZDJselpTQnBkQ0IzYVd4c0lIUm9jbTkzSUdFZ1oyeHZZbUZzSUdWeWNtOXlMbHh1SUNBZ0lDQWdJQ0FnSUNBZ0x5OGdVMjl0WlNCMlpYSnphVzl1Y3lCdlppQkpMa1V1SUdoaGRtVWdaR2xtWm1WeVpXNTBJSEoxYkdWeklHWnZjaUJqYkdWaGNsUnBiV1Z2ZFhRZ2RuTWdjMlYwVkdsdFpXOTFkRnh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOaFkyaGxaRU5zWldGeVZHbHRaVzkxZEM1allXeHNLSFJvYVhNc0lHMWhjbXRsY2lrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNCOVhHNWNibHh1WEc1OVhHNTJZWElnY1hWbGRXVWdQU0JiWFR0Y2JuWmhjaUJrY21GcGJtbHVaeUE5SUdaaGJITmxPMXh1ZG1GeUlHTjFjbkpsYm5SUmRXVjFaVHRjYm5aaGNpQnhkV1YxWlVsdVpHVjRJRDBnTFRFN1hHNWNibVoxYm1OMGFXOXVJR05zWldGdVZYQk9aWGgwVkdsamF5Z3BJSHRjYmlBZ0lDQnBaaUFvSVdSeVlXbHVhVzVuSUh4OElDRmpkWEp5Wlc1MFVYVmxkV1VwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1TzF4dUlDQWdJSDFjYmlBZ0lDQmtjbUZwYm1sdVp5QTlJR1poYkhObE8xeHVJQ0FnSUdsbUlDaGpkWEp5Wlc1MFVYVmxkV1V1YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0FnSUhGMVpYVmxJRDBnWTNWeWNtVnVkRkYxWlhWbExtTnZibU5oZENoeGRXVjFaU2s3WEc0Z0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdjWFZsZFdWSmJtUmxlQ0E5SUMweE8xeHVJQ0FnSUgxY2JpQWdJQ0JwWmlBb2NYVmxkV1V1YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0FnSUdSeVlXbHVVWFZsZFdVb0tUdGNiaUFnSUNCOVhHNTlYRzVjYm1aMWJtTjBhVzl1SUdSeVlXbHVVWFZsZFdVb0tTQjdYRzRnSUNBZ2FXWWdLR1J5WVdsdWFXNW5LU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnlianRjYmlBZ0lDQjlYRzRnSUNBZ2RtRnlJSFJwYldWdmRYUWdQU0J5ZFc1VWFXMWxiM1YwS0dOc1pXRnVWWEJPWlhoMFZHbGpheWs3WEc0Z0lDQWdaSEpoYVc1cGJtY2dQU0IwY25WbE8xeHVYRzRnSUNBZ2RtRnlJR3hsYmlBOUlIRjFaWFZsTG14bGJtZDBhRHRjYmlBZ0lDQjNhR2xzWlNoc1pXNHBJSHRjYmlBZ0lDQWdJQ0FnWTNWeWNtVnVkRkYxWlhWbElEMGdjWFZsZFdVN1hHNGdJQ0FnSUNBZ0lIRjFaWFZsSUQwZ1cxMDdYRzRnSUNBZ0lDQWdJSGRvYVd4bElDZ3JLM0YxWlhWbFNXNWtaWGdnUENCc1pXNHBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2hqZFhKeVpXNTBVWFZsZFdVcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmpkWEp5Wlc1MFVYVmxkV1ZiY1hWbGRXVkpibVJsZUYwdWNuVnVLQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnY1hWbGRXVkpibVJsZUNBOUlDMHhPMXh1SUNBZ0lDQWdJQ0JzWlc0Z1BTQnhkV1YxWlM1c1pXNW5kR2c3WEc0Z0lDQWdmVnh1SUNBZ0lHTjFjbkpsYm5SUmRXVjFaU0E5SUc1MWJHdzdYRzRnSUNBZ1pISmhhVzVwYm1jZ1BTQm1ZV3h6WlR0Y2JpQWdJQ0J5ZFc1RGJHVmhjbFJwYldWdmRYUW9kR2x0Wlc5MWRDazdYRzU5WEc1Y2JuQnliMk5sYzNNdWJtVjRkRlJwWTJzZ1BTQm1kVzVqZEdsdmJpQW9ablZ1S1NCN1hHNGdJQ0FnZG1GeUlHRnlaM01nUFNCdVpYY2dRWEp5WVhrb1lYSm5kVzFsYm5SekxteGxibWQwYUNBdElERXBPMXh1SUNBZ0lHbG1JQ2hoY21kMWJXVnVkSE11YkdWdVozUm9JRDRnTVNrZ2UxeHVJQ0FnSUNBZ0lDQm1iM0lnS0haaGNpQnBJRDBnTVRzZ2FTQThJR0Z5WjNWdFpXNTBjeTVzWlc1bmRHZzdJR2tyS3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWVhKbmMxdHBJQzBnTVYwZ1BTQmhjbWQxYldWdWRITmJhVjA3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lDQWdjWFZsZFdVdWNIVnphQ2h1WlhjZ1NYUmxiU2htZFc0c0lHRnlaM01wS1R0Y2JpQWdJQ0JwWmlBb2NYVmxkV1V1YkdWdVozUm9JRDA5UFNBeElDWW1JQ0ZrY21GcGJtbHVaeWtnZTF4dUlDQWdJQ0FnSUNCeWRXNVVhVzFsYjNWMEtHUnlZV2x1VVhWbGRXVXBPMXh1SUNBZ0lIMWNibjA3WEc1Y2JpOHZJSFk0SUd4cGEyVnpJSEJ5WldScFkzUnBZbXhsSUc5aWFtVmpkSE5jYm1aMWJtTjBhVzl1SUVsMFpXMG9ablZ1TENCaGNuSmhlU2tnZTF4dUlDQWdJSFJvYVhNdVpuVnVJRDBnWm5WdU8xeHVJQ0FnSUhSb2FYTXVZWEp5WVhrZ1BTQmhjbkpoZVR0Y2JuMWNia2wwWlcwdWNISnZkRzkwZVhCbExuSjFiaUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNCMGFHbHpMbVoxYmk1aGNIQnNlU2h1ZFd4c0xDQjBhR2x6TG1GeWNtRjVLVHRjYm4wN1hHNXdjbTlqWlhOekxuUnBkR3hsSUQwZ0oySnliM2R6WlhJbk8xeHVjSEp2WTJWemN5NWljbTkzYzJWeUlEMGdkSEoxWlR0Y2JuQnliMk5sYzNNdVpXNTJJRDBnZTMwN1hHNXdjbTlqWlhOekxtRnlaM1lnUFNCYlhUdGNibkJ5YjJObGMzTXVkbVZ5YzJsdmJpQTlJQ2NuT3lBdkx5QmxiWEIwZVNCemRISnBibWNnZEc4Z1lYWnZhV1FnY21WblpYaHdJR2x6YzNWbGMxeHVjSEp2WTJWemN5NTJaWEp6YVc5dWN5QTlJSHQ5TzF4dVhHNW1kVzVqZEdsdmJpQnViMjl3S0NrZ2UzMWNibHh1Y0hKdlkyVnpjeTV2YmlBOUlHNXZiM0E3WEc1d2NtOWpaWE56TG1Ga1pFeHBjM1JsYm1WeUlEMGdibTl2Y0R0Y2JuQnliMk5sYzNNdWIyNWpaU0E5SUc1dmIzQTdYRzV3Y205alpYTnpMbTltWmlBOUlHNXZiM0E3WEc1d2NtOWpaWE56TG5KbGJXOTJaVXhwYzNSbGJtVnlJRDBnYm05dmNEdGNibkJ5YjJObGMzTXVjbVZ0YjNabFFXeHNUR2x6ZEdWdVpYSnpJRDBnYm05dmNEdGNibkJ5YjJObGMzTXVaVzFwZENBOUlHNXZiM0E3WEc1d2NtOWpaWE56TG5CeVpYQmxibVJNYVhOMFpXNWxjaUE5SUc1dmIzQTdYRzV3Y205alpYTnpMbkJ5WlhCbGJtUlBibU5sVEdsemRHVnVaWElnUFNCdWIyOXdPMXh1WEc1d2NtOWpaWE56TG14cGMzUmxibVZ5Y3lBOUlHWjFibU4wYVc5dUlDaHVZVzFsS1NCN0lISmxkSFZ5YmlCYlhTQjlYRzVjYm5CeWIyTmxjM011WW1sdVpHbHVaeUE5SUdaMWJtTjBhVzl1SUNodVlXMWxLU0I3WEc0Z0lDQWdkR2h5YjNjZ2JtVjNJRVZ5Y205eUtDZHdjbTlqWlhOekxtSnBibVJwYm1jZ2FYTWdibTkwSUhOMWNIQnZjblJsWkNjcE8xeHVmVHRjYmx4dWNISnZZMlZ6Y3k1amQyUWdQU0JtZFc1amRHbHZiaUFvS1NCN0lISmxkSFZ5YmlBbkx5Y2dmVHRjYm5CeWIyTmxjM011WTJoa2FYSWdQU0JtZFc1amRHbHZiaUFvWkdseUtTQjdYRzRnSUNBZ2RHaHliM2NnYm1WM0lFVnljbTl5S0Nkd2NtOWpaWE56TG1Ob1pHbHlJR2x6SUc1dmRDQnpkWEJ3YjNKMFpXUW5LVHRjYm4wN1hHNXdjbTlqWlhOekxuVnRZWE5ySUQwZ1puVnVZM1JwYjI0b0tTQjdJSEpsZEhWeWJpQXdPeUI5TzF4dVhHNWNibHh1THk4dkx5OHZMeTh2THk4dkx5OHZMeTh2WEc0dkx5QlhSVUpRUVVOTElFWlBUMVJGVWx4dUx5OGdMaTkrTDNCeWIyTmxjM012WW5KdmQzTmxjaTVxYzF4dUx5OGdiVzlrZFd4bElHbGtJRDBnTkRSY2JpOHZJRzF2WkhWc1pTQmphSFZ1YTNNZ1BTQXdJaXdpSjNWelpTQnpkSEpwWTNRbk8xeHVYRzVwYlhCdmNuUWdleUJqYkc5amF5QjlJR1p5YjIwZ0p5NHVMMjFoYVc0bk8xeHVYRzVsZUhCdmNuUWdaR1ZtWVhWc2RDQmpiR0Z6Y3lCSmJuUmxjblpoYkNCN1hHNWNiaUFnWTI5dWMzUnlkV04wYjNJb2NtRjBaU3htZFc1akxHOXVLU0I3WEc1Y2JpQWdJQ0IwYUdsekxuSmhkR1VnUFNCeVlYUmxPMXh1SUNBZ0lIUm9hWE11YjI0Z1BTQnZianRjYmlBZ0lDQjBhR2x6TG1Oc2IyTnJJRDBnWTJ4dlkyc29LVHNnTHk4Z2FuTm9hVzUwSUdsbmJtOXlaVHBzYVc1bFhHNWNiaUFnSUNCMGFHbHpMbkJoZEhSbGNtNGdQU0JiTVYwN1hHNGdJQ0FnZEdocGN5NXBibVJsZUNBOUlEQTdYRzVjYmlBZ0lDQjBhR2x6TG1WMlpXNTBJRDBnWm5WdVl5QS9JR1oxYm1NZ09pQm1kVzVqZEdsdmJpZ3BJSHNnZlR0Y2JseHVJQ0FnSUdsbUlDaDBhR2x6TG05dUtTQjdYRzRnSUNBZ0lDQjBhR2x6TG5OMFlYSjBLQ2s3WEc0Z0lDQWdmVnh1WEc0Z0lIMWNibHh1SUNCZlpYWmxiblFvWlNrZ2UxeHVJQ0F2THlBZ2FXWWdLSFJvYVhNdWNHRjBkR1Z5Ymx0MGFHbHpMbWx1WkdWNEpYUm9hWE11Y0dGMGRHVnliaTVzWlc1bmRHaGRLU0I3WEc0Z0lDQWdJQ0IwYUdsekxtVjJaVzUwS0dVcE8xeHVJQ0F2THlBZ2ZWeHVJQ0FnSUhSb2FYTXVhVzVrWlhnckt6dGNiaUFnZlZ4dVhHNGdJSE4wYjNBb0tTQjdYRzRnSUNBZ2RHaHBjeTV2YmlBOUlHWmhiSE5sTzF4dUlDQWdJSFJvYVhNdWFXNTBaWEoyWVd3dVkyeGxZWElvS1R0Y2JpQWdmVnh1WEc0Z0lITjBZWEowS0NrZ2UxeHVJQ0FnSUhSb2FYTXViMjRnUFNCMGNuVmxPMXh1SUNBZ0lIUm9hWE11YVc1MFpYSjJZV3dnUFNCMGFHbHpMbU5zYjJOckxtTmhiR3hpWVdOclFYUlVhVzFsS0hSb2FYTXVYMlYyWlc1MExtSnBibVFvZEdocGN5a3NJSFJvYVhNdVkyeHZZMnN1WTI5dWRHVjRkQzVqZFhKeVpXNTBWR2x0WlNrdWNtVndaV0YwS0hSb2FYTXVjbUYwWlM4eE1EQXdLUzUwYjJ4bGNtRnVZMlVvZTJWaGNteDVPaUF3TGpFc0lHeGhkR1U2TVgwcE8xeHVJQ0I5WEc1Y2JpQWdiWE1vYm1WM2NtRjBaU2tnZTF4dUlDQWdJR2xtSUNoMGFHbHpMbTl1S1NCN1hHNGdJQ0FnSUNCMllYSWdjbUYwYVc4Z1BTQnVaWGR5WVhSbEwzUm9hWE11Y21GMFpUdGNiaUFnSUNBZ0lIUm9hWE11Y21GMFpTQTlJRzVsZDNKaGRHVTdYRzRnSUNBZ0lDQjBhR2x6TG1Oc2IyTnJMblJwYldWVGRISmxkR05vS0hSb2FYTXVZMnh2WTJzdVkyOXVkR1Y0ZEM1amRYSnlaVzUwVkdsdFpTd2dXM1JvYVhNdWFXNTBaWEoyWVd4ZExDQnlZWFJwYnlrN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJSFJvYVhNdWNtRjBaU0E5SUc1bGQzSmhkR1U3WEc0Z0lDQWdmVnh1SUNCOVhHNWNibjFjYmx4dVhHNWNiaTh2SUZkRlFsQkJRMHNnUms5UFZFVlNJQzh2WEc0dkx5QXVMMzR2YW5Ob2FXNTBMV3h2WVdSbGNpRXVMMnhwWWk5MGFXMWxMMmx1ZEdWeWRtRnNMbXB6SWwwc0luTnZkWEpqWlZKdmIzUWlPaUlpZlE9PVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9uZXh1c3VpL2Rpc3QvTmV4dXNVSS5qc1xuLy8gbW9kdWxlIGlkID0gNTZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSB7IFwiZGVmYXVsdFwiOiByZXF1aXJlKFwiY29yZS1qcy9saWJyYXJ5L2ZuL29iamVjdC9hc3NpZ25cIiksIF9fZXNNb2R1bGU6IHRydWUgfTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vYmFiZWwtcnVudGltZS9jb3JlLWpzL29iamVjdC9hc3NpZ24uanNcbi8vIG1vZHVsZSBpZCA9IDU3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuZG9jdW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9faHRtbC5qc1xuLy8gbW9kdWxlIGlkID0gNThcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbigpe1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKSgnZGl2JyksICdhJywge2dldDogZnVuY3Rpb24oKXsgcmV0dXJuIDc7IH19KS5hICE9IDc7XG59KTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2llOC1kb20tZGVmaW5lLmpzXG4vLyBtb2R1bGUgaWQgPSA1OVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBmYWxsYmFjayBmb3Igbm9uLWFycmF5LWxpa2UgRVMzIGFuZCBub24tZW51bWVyYWJsZSBvbGQgVjggc3RyaW5nc1xudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QoJ3onKS5wcm9wZXJ0eUlzRW51bWVyYWJsZSgwKSA/IE9iamVjdCA6IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIGNvZihpdCkgPT0gJ1N0cmluZycgPyBpdC5zcGxpdCgnJykgOiBPYmplY3QoaXQpO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2lvYmplY3QuanNcbi8vIG1vZHVsZSBpZCA9IDYwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIGNoZWNrIG9uIGRlZmF1bHQgQXJyYXkgaXRlcmF0b3JcbnZhciBJdGVyYXRvcnMgID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJylcbiAgLCBJVEVSQVRPUiAgID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJylcbiAgLCBBcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIGl0ICE9PSB1bmRlZmluZWQgJiYgKEl0ZXJhdG9ycy5BcnJheSA9PT0gaXQgfHwgQXJyYXlQcm90b1tJVEVSQVRPUl0gPT09IGl0KTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pcy1hcnJheS1pdGVyLmpzXG4vLyBtb2R1bGUgaWQgPSA2MVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBjYWxsIHNvbWV0aGluZyBvbiBpdGVyYXRvciBzdGVwIHdpdGggc2FmZSBjbG9zaW5nIG9uIGVycm9yXG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXRlcmF0b3IsIGZuLCB2YWx1ZSwgZW50cmllcyl7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGVudHJpZXMgPyBmbihhbk9iamVjdCh2YWx1ZSlbMF0sIHZhbHVlWzFdKSA6IGZuKHZhbHVlKTtcbiAgLy8gNy40LjYgSXRlcmF0b3JDbG9zZShpdGVyYXRvciwgY29tcGxldGlvbilcbiAgfSBjYXRjaChlKXtcbiAgICB2YXIgcmV0ID0gaXRlcmF0b3JbJ3JldHVybiddO1xuICAgIGlmKHJldCAhPT0gdW5kZWZpbmVkKWFuT2JqZWN0KHJldC5jYWxsKGl0ZXJhdG9yKSk7XG4gICAgdGhyb3cgZTtcbiAgfVxufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2l0ZXItY2FsbC5qc1xuLy8gbW9kdWxlIGlkID0gNjJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiJ3VzZSBzdHJpY3QnO1xudmFyIExJQlJBUlkgICAgICAgID0gcmVxdWlyZSgnLi9fbGlicmFyeScpXG4gICwgJGV4cG9ydCAgICAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIHJlZGVmaW5lICAgICAgID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKVxuICAsIGhpZGUgICAgICAgICAgID0gcmVxdWlyZSgnLi9faGlkZScpXG4gICwgaGFzICAgICAgICAgICAgPSByZXF1aXJlKCcuL19oYXMnKVxuICAsIEl0ZXJhdG9ycyAgICAgID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJylcbiAgLCAkaXRlckNyZWF0ZSAgICA9IHJlcXVpcmUoJy4vX2l0ZXItY3JlYXRlJylcbiAgLCBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJylcbiAgLCBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKVxuICAsIElURVJBVE9SICAgICAgID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJylcbiAgLCBCVUdHWSAgICAgICAgICA9ICEoW10ua2V5cyAmJiAnbmV4dCcgaW4gW10ua2V5cygpKSAvLyBTYWZhcmkgaGFzIGJ1Z2d5IGl0ZXJhdG9ycyB3L28gYG5leHRgXG4gICwgRkZfSVRFUkFUT1IgICAgPSAnQEBpdGVyYXRvcidcbiAgLCBLRVlTICAgICAgICAgICA9ICdrZXlzJ1xuICAsIFZBTFVFUyAgICAgICAgID0gJ3ZhbHVlcyc7XG5cbnZhciByZXR1cm5UaGlzID0gZnVuY3Rpb24oKXsgcmV0dXJuIHRoaXM7IH07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oQmFzZSwgTkFNRSwgQ29uc3RydWN0b3IsIG5leHQsIERFRkFVTFQsIElTX1NFVCwgRk9SQ0VEKXtcbiAgJGl0ZXJDcmVhdGUoQ29uc3RydWN0b3IsIE5BTUUsIG5leHQpO1xuICB2YXIgZ2V0TWV0aG9kID0gZnVuY3Rpb24oa2luZCl7XG4gICAgaWYoIUJVR0dZICYmIGtpbmQgaW4gcHJvdG8pcmV0dXJuIHByb3RvW2tpbmRdO1xuICAgIHN3aXRjaChraW5kKXtcbiAgICAgIGNhc2UgS0VZUzogcmV0dXJuIGZ1bmN0aW9uIGtleXMoKXsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgICAgIGNhc2UgVkFMVUVTOiByZXR1cm4gZnVuY3Rpb24gdmFsdWVzKCl7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gICAgfSByZXR1cm4gZnVuY3Rpb24gZW50cmllcygpeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICB9O1xuICB2YXIgVEFHICAgICAgICA9IE5BTUUgKyAnIEl0ZXJhdG9yJ1xuICAgICwgREVGX1ZBTFVFUyA9IERFRkFVTFQgPT0gVkFMVUVTXG4gICAgLCBWQUxVRVNfQlVHID0gZmFsc2VcbiAgICAsIHByb3RvICAgICAgPSBCYXNlLnByb3RvdHlwZVxuICAgICwgJG5hdGl2ZSAgICA9IHByb3RvW0lURVJBVE9SXSB8fCBwcm90b1tGRl9JVEVSQVRPUl0gfHwgREVGQVVMVCAmJiBwcm90b1tERUZBVUxUXVxuICAgICwgJGRlZmF1bHQgICA9ICRuYXRpdmUgfHwgZ2V0TWV0aG9kKERFRkFVTFQpXG4gICAgLCAkZW50cmllcyAgID0gREVGQVVMVCA/ICFERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoJ2VudHJpZXMnKSA6IHVuZGVmaW5lZFxuICAgICwgJGFueU5hdGl2ZSA9IE5BTUUgPT0gJ0FycmF5JyA/IHByb3RvLmVudHJpZXMgfHwgJG5hdGl2ZSA6ICRuYXRpdmVcbiAgICAsIG1ldGhvZHMsIGtleSwgSXRlcmF0b3JQcm90b3R5cGU7XG4gIC8vIEZpeCBuYXRpdmVcbiAgaWYoJGFueU5hdGl2ZSl7XG4gICAgSXRlcmF0b3JQcm90b3R5cGUgPSBnZXRQcm90b3R5cGVPZigkYW55TmF0aXZlLmNhbGwobmV3IEJhc2UpKTtcbiAgICBpZihJdGVyYXRvclByb3RvdHlwZSAhPT0gT2JqZWN0LnByb3RvdHlwZSl7XG4gICAgICAvLyBTZXQgQEB0b1N0cmluZ1RhZyB0byBuYXRpdmUgaXRlcmF0b3JzXG4gICAgICBzZXRUb1N0cmluZ1RhZyhJdGVyYXRvclByb3RvdHlwZSwgVEFHLCB0cnVlKTtcbiAgICAgIC8vIGZpeCBmb3Igc29tZSBvbGQgZW5naW5lc1xuICAgICAgaWYoIUxJQlJBUlkgJiYgIWhhcyhJdGVyYXRvclByb3RvdHlwZSwgSVRFUkFUT1IpKWhpZGUoSXRlcmF0b3JQcm90b3R5cGUsIElURVJBVE9SLCByZXR1cm5UaGlzKTtcbiAgICB9XG4gIH1cbiAgLy8gZml4IEFycmF5I3t2YWx1ZXMsIEBAaXRlcmF0b3J9Lm5hbWUgaW4gVjggLyBGRlxuICBpZihERUZfVkFMVUVTICYmICRuYXRpdmUgJiYgJG5hdGl2ZS5uYW1lICE9PSBWQUxVRVMpe1xuICAgIFZBTFVFU19CVUcgPSB0cnVlO1xuICAgICRkZWZhdWx0ID0gZnVuY3Rpb24gdmFsdWVzKCl7IHJldHVybiAkbmF0aXZlLmNhbGwodGhpcyk7IH07XG4gIH1cbiAgLy8gRGVmaW5lIGl0ZXJhdG9yXG4gIGlmKCghTElCUkFSWSB8fCBGT1JDRUQpICYmIChCVUdHWSB8fCBWQUxVRVNfQlVHIHx8ICFwcm90b1tJVEVSQVRPUl0pKXtcbiAgICBoaWRlKHByb3RvLCBJVEVSQVRPUiwgJGRlZmF1bHQpO1xuICB9XG4gIC8vIFBsdWcgZm9yIGxpYnJhcnlcbiAgSXRlcmF0b3JzW05BTUVdID0gJGRlZmF1bHQ7XG4gIEl0ZXJhdG9yc1tUQUddICA9IHJldHVyblRoaXM7XG4gIGlmKERFRkFVTFQpe1xuICAgIG1ldGhvZHMgPSB7XG4gICAgICB2YWx1ZXM6ICBERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoVkFMVUVTKSxcbiAgICAgIGtleXM6ICAgIElTX1NFVCAgICAgPyAkZGVmYXVsdCA6IGdldE1ldGhvZChLRVlTKSxcbiAgICAgIGVudHJpZXM6ICRlbnRyaWVzXG4gICAgfTtcbiAgICBpZihGT1JDRUQpZm9yKGtleSBpbiBtZXRob2RzKXtcbiAgICAgIGlmKCEoa2V5IGluIHByb3RvKSlyZWRlZmluZShwcm90bywga2V5LCBtZXRob2RzW2tleV0pO1xuICAgIH0gZWxzZSAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChCVUdHWSB8fCBWQUxVRVNfQlVHKSwgTkFNRSwgbWV0aG9kcyk7XG4gIH1cbiAgcmV0dXJuIG1ldGhvZHM7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9faXRlci1kZWZpbmUuanNcbi8vIG1vZHVsZSBpZCA9IDYzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBJVEVSQVRPUiAgICAgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKVxuICAsIFNBRkVfQ0xPU0lORyA9IGZhbHNlO1xuXG50cnkge1xuICB2YXIgcml0ZXIgPSBbN11bSVRFUkFUT1JdKCk7XG4gIHJpdGVyWydyZXR1cm4nXSA9IGZ1bmN0aW9uKCl7IFNBRkVfQ0xPU0lORyA9IHRydWU7IH07XG4gIEFycmF5LmZyb20ocml0ZXIsIGZ1bmN0aW9uKCl7IHRocm93IDI7IH0pO1xufSBjYXRjaChlKXsgLyogZW1wdHkgKi8gfVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGV4ZWMsIHNraXBDbG9zaW5nKXtcbiAgaWYoIXNraXBDbG9zaW5nICYmICFTQUZFX0NMT1NJTkcpcmV0dXJuIGZhbHNlO1xuICB2YXIgc2FmZSA9IGZhbHNlO1xuICB0cnkge1xuICAgIHZhciBhcnIgID0gWzddXG4gICAgICAsIGl0ZXIgPSBhcnJbSVRFUkFUT1JdKCk7XG4gICAgaXRlci5uZXh0ID0gZnVuY3Rpb24oKXsgcmV0dXJuIHtkb25lOiBzYWZlID0gdHJ1ZX07IH07XG4gICAgYXJyW0lURVJBVE9SXSA9IGZ1bmN0aW9uKCl7IHJldHVybiBpdGVyOyB9O1xuICAgIGV4ZWMoYXJyKTtcbiAgfSBjYXRjaChlKXsgLyogZW1wdHkgKi8gfVxuICByZXR1cm4gc2FmZTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pdGVyLWRldGVjdC5qc1xuLy8gbW9kdWxlIGlkID0gNjRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gMTkuMS4yLjIgLyAxNS4yLjMuNSBPYmplY3QuY3JlYXRlKE8gWywgUHJvcGVydGllc10pXG52YXIgYW5PYmplY3QgICAgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKVxuICAsIGRQcyAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwcycpXG4gICwgZW51bUJ1Z0tleXMgPSByZXF1aXJlKCcuL19lbnVtLWJ1Zy1rZXlzJylcbiAgLCBJRV9QUk9UTyAgICA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKVxuICAsIEVtcHR5ICAgICAgID0gZnVuY3Rpb24oKXsgLyogZW1wdHkgKi8gfVxuICAsIFBST1RPVFlQRSAgID0gJ3Byb3RvdHlwZSc7XG5cbi8vIENyZWF0ZSBvYmplY3Qgd2l0aCBmYWtlIGBudWxsYCBwcm90b3R5cGU6IHVzZSBpZnJhbWUgT2JqZWN0IHdpdGggY2xlYXJlZCBwcm90b3R5cGVcbnZhciBjcmVhdGVEaWN0ID0gZnVuY3Rpb24oKXtcbiAgLy8gVGhyYXNoLCB3YXN0ZSBhbmQgc29kb215OiBJRSBHQyBidWdcbiAgdmFyIGlmcmFtZSA9IHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKSgnaWZyYW1lJylcbiAgICAsIGkgICAgICA9IGVudW1CdWdLZXlzLmxlbmd0aFxuICAgICwgbHQgICAgID0gJzwnXG4gICAgLCBndCAgICAgPSAnPidcbiAgICAsIGlmcmFtZURvY3VtZW50O1xuICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgcmVxdWlyZSgnLi9faHRtbCcpLmFwcGVuZENoaWxkKGlmcmFtZSk7XG4gIGlmcmFtZS5zcmMgPSAnamF2YXNjcmlwdDonOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNjcmlwdC11cmxcbiAgLy8gY3JlYXRlRGljdCA9IGlmcmFtZS5jb250ZW50V2luZG93Lk9iamVjdDtcbiAgLy8gaHRtbC5yZW1vdmVDaGlsZChpZnJhbWUpO1xuICBpZnJhbWVEb2N1bWVudCA9IGlmcmFtZS5jb250ZW50V2luZG93LmRvY3VtZW50O1xuICBpZnJhbWVEb2N1bWVudC5vcGVuKCk7XG4gIGlmcmFtZURvY3VtZW50LndyaXRlKGx0ICsgJ3NjcmlwdCcgKyBndCArICdkb2N1bWVudC5GPU9iamVjdCcgKyBsdCArICcvc2NyaXB0JyArIGd0KTtcbiAgaWZyYW1lRG9jdW1lbnQuY2xvc2UoKTtcbiAgY3JlYXRlRGljdCA9IGlmcmFtZURvY3VtZW50LkY7XG4gIHdoaWxlKGktLSlkZWxldGUgY3JlYXRlRGljdFtQUk9UT1RZUEVdW2VudW1CdWdLZXlzW2ldXTtcbiAgcmV0dXJuIGNyZWF0ZURpY3QoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmNyZWF0ZSB8fCBmdW5jdGlvbiBjcmVhdGUoTywgUHJvcGVydGllcyl7XG4gIHZhciByZXN1bHQ7XG4gIGlmKE8gIT09IG51bGwpe1xuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBhbk9iamVjdChPKTtcbiAgICByZXN1bHQgPSBuZXcgRW1wdHk7XG4gICAgRW1wdHlbUFJPVE9UWVBFXSA9IG51bGw7XG4gICAgLy8gYWRkIFwiX19wcm90b19fXCIgZm9yIE9iamVjdC5nZXRQcm90b3R5cGVPZiBwb2x5ZmlsbFxuICAgIHJlc3VsdFtJRV9QUk9UT10gPSBPO1xuICB9IGVsc2UgcmVzdWx0ID0gY3JlYXRlRGljdCgpO1xuICByZXR1cm4gUHJvcGVydGllcyA9PT0gdW5kZWZpbmVkID8gcmVzdWx0IDogZFBzKHJlc3VsdCwgUHJvcGVydGllcyk7XG59O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzXG4vLyBtb2R1bGUgaWQgPSA2NVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyAxOS4xLjIuNyAvIDE1LjIuMy40IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKE8pXG52YXIgJGtleXMgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzLWludGVybmFsJylcbiAgLCBoaWRkZW5LZXlzID0gcmVxdWlyZSgnLi9fZW51bS1idWcta2V5cycpLmNvbmNhdCgnbGVuZ3RoJywgJ3Byb3RvdHlwZScpO1xuXG5leHBvcnRzLmYgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB8fCBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eU5hbWVzKE8pe1xuICByZXR1cm4gJGtleXMoTywgaGlkZGVuS2V5cyk7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fb2JqZWN0LWdvcG4uanNcbi8vIG1vZHVsZSBpZCA9IDY2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBoYXMgICAgICAgICAgPSByZXF1aXJlKCcuL19oYXMnKVxuICAsIHRvSU9iamVjdCAgICA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKVxuICAsIGFycmF5SW5kZXhPZiA9IHJlcXVpcmUoJy4vX2FycmF5LWluY2x1ZGVzJykoZmFsc2UpXG4gICwgSUVfUFJPVE8gICAgID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9iamVjdCwgbmFtZXMpe1xuICB2YXIgTyAgICAgID0gdG9JT2JqZWN0KG9iamVjdClcbiAgICAsIGkgICAgICA9IDBcbiAgICAsIHJlc3VsdCA9IFtdXG4gICAgLCBrZXk7XG4gIGZvcihrZXkgaW4gTylpZihrZXkgIT0gSUVfUFJPVE8paGFzKE8sIGtleSkgJiYgcmVzdWx0LnB1c2goa2V5KTtcbiAgLy8gRG9uJ3QgZW51bSBidWcgJiBoaWRkZW4ga2V5c1xuICB3aGlsZShuYW1lcy5sZW5ndGggPiBpKWlmKGhhcyhPLCBrZXkgPSBuYW1lc1tpKytdKSl7XG4gICAgfmFycmF5SW5kZXhPZihyZXN1bHQsIGtleSkgfHwgcmVzdWx0LnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX29iamVjdC1rZXlzLWludGVybmFsLmpzXG4vLyBtb2R1bGUgaWQgPSA2N1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3JlZGVmaW5lLmpzXG4vLyBtb2R1bGUgaWQgPSA2OFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgY3R4ICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fY3R4JylcbiAgLCBpbnZva2UgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19pbnZva2UnKVxuICAsIGh0bWwgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2h0bWwnKVxuICAsIGNlbCAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKVxuICAsIGdsb2JhbCAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgcHJvY2VzcyAgICAgICAgICAgID0gZ2xvYmFsLnByb2Nlc3NcbiAgLCBzZXRUYXNrICAgICAgICAgICAgPSBnbG9iYWwuc2V0SW1tZWRpYXRlXG4gICwgY2xlYXJUYXNrICAgICAgICAgID0gZ2xvYmFsLmNsZWFySW1tZWRpYXRlXG4gICwgTWVzc2FnZUNoYW5uZWwgICAgID0gZ2xvYmFsLk1lc3NhZ2VDaGFubmVsXG4gICwgY291bnRlciAgICAgICAgICAgID0gMFxuICAsIHF1ZXVlICAgICAgICAgICAgICA9IHt9XG4gICwgT05SRUFEWVNUQVRFQ0hBTkdFID0gJ29ucmVhZHlzdGF0ZWNoYW5nZSdcbiAgLCBkZWZlciwgY2hhbm5lbCwgcG9ydDtcbnZhciBydW4gPSBmdW5jdGlvbigpe1xuICB2YXIgaWQgPSArdGhpcztcbiAgaWYocXVldWUuaGFzT3duUHJvcGVydHkoaWQpKXtcbiAgICB2YXIgZm4gPSBxdWV1ZVtpZF07XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgICBmbigpO1xuICB9XG59O1xudmFyIGxpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQpe1xuICBydW4uY2FsbChldmVudC5kYXRhKTtcbn07XG4vLyBOb2RlLmpzIDAuOSsgJiBJRTEwKyBoYXMgc2V0SW1tZWRpYXRlLCBvdGhlcndpc2U6XG5pZighc2V0VGFzayB8fCAhY2xlYXJUYXNrKXtcbiAgc2V0VGFzayA9IGZ1bmN0aW9uIHNldEltbWVkaWF0ZShmbil7XG4gICAgdmFyIGFyZ3MgPSBbXSwgaSA9IDE7XG4gICAgd2hpbGUoYXJndW1lbnRzLmxlbmd0aCA+IGkpYXJncy5wdXNoKGFyZ3VtZW50c1tpKytdKTtcbiAgICBxdWV1ZVsrK2NvdW50ZXJdID0gZnVuY3Rpb24oKXtcbiAgICAgIGludm9rZSh0eXBlb2YgZm4gPT0gJ2Z1bmN0aW9uJyA/IGZuIDogRnVuY3Rpb24oZm4pLCBhcmdzKTtcbiAgICB9O1xuICAgIGRlZmVyKGNvdW50ZXIpO1xuICAgIHJldHVybiBjb3VudGVyO1xuICB9O1xuICBjbGVhclRhc2sgPSBmdW5jdGlvbiBjbGVhckltbWVkaWF0ZShpZCl7XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgfTtcbiAgLy8gTm9kZS5qcyAwLjgtXG4gIGlmKHJlcXVpcmUoJy4vX2NvZicpKHByb2Nlc3MpID09ICdwcm9jZXNzJyl7XG4gICAgZGVmZXIgPSBmdW5jdGlvbihpZCl7XG4gICAgICBwcm9jZXNzLm5leHRUaWNrKGN0eChydW4sIGlkLCAxKSk7XG4gICAgfTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBNZXNzYWdlQ2hhbm5lbCwgaW5jbHVkZXMgV2ViV29ya2Vyc1xuICB9IGVsc2UgaWYoTWVzc2FnZUNoYW5uZWwpe1xuICAgIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWw7XG4gICAgcG9ydCAgICA9IGNoYW5uZWwucG9ydDI7XG4gICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBsaXN0ZW5lcjtcbiAgICBkZWZlciA9IGN0eChwb3J0LnBvc3RNZXNzYWdlLCBwb3J0LCAxKTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBwb3N0TWVzc2FnZSwgc2tpcCBXZWJXb3JrZXJzXG4gIC8vIElFOCBoYXMgcG9zdE1lc3NhZ2UsIGJ1dCBpdCdzIHN5bmMgJiB0eXBlb2YgaXRzIHBvc3RNZXNzYWdlIGlzICdvYmplY3QnXG4gIH0gZWxzZSBpZihnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lciAmJiB0eXBlb2YgcG9zdE1lc3NhZ2UgPT0gJ2Z1bmN0aW9uJyAmJiAhZ2xvYmFsLmltcG9ydFNjcmlwdHMpe1xuICAgIGRlZmVyID0gZnVuY3Rpb24oaWQpe1xuICAgICAgZ2xvYmFsLnBvc3RNZXNzYWdlKGlkICsgJycsICcqJyk7XG4gICAgfTtcbiAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGxpc3RlbmVyLCBmYWxzZSk7XG4gIC8vIElFOC1cbiAgfSBlbHNlIGlmKE9OUkVBRFlTVEFURUNIQU5HRSBpbiBjZWwoJ3NjcmlwdCcpKXtcbiAgICBkZWZlciA9IGZ1bmN0aW9uKGlkKXtcbiAgICAgIGh0bWwuYXBwZW5kQ2hpbGQoY2VsKCdzY3JpcHQnKSlbT05SRUFEWVNUQVRFQ0hBTkdFXSA9IGZ1bmN0aW9uKCl7XG4gICAgICAgIGh0bWwucmVtb3ZlQ2hpbGQodGhpcyk7XG4gICAgICAgIHJ1bi5jYWxsKGlkKTtcbiAgICAgIH07XG4gICAgfTtcbiAgLy8gUmVzdCBvbGQgYnJvd3NlcnNcbiAgfSBlbHNlIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uKGlkKXtcbiAgICAgIHNldFRpbWVvdXQoY3R4KHJ1biwgaWQsIDEpLCAwKTtcbiAgICB9O1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2V0OiAgIHNldFRhc2ssXG4gIGNsZWFyOiBjbGVhclRhc2tcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL190YXNrLmpzXG4vLyBtb2R1bGUgaWQgPSA2OVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChhcnIpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9pc2FycmF5L2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSA3MVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhZGFibGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgcHJvY2Vzc05leHRUaWNrID0gcmVxdWlyZSgncHJvY2Vzcy1uZXh0aWNrLWFyZ3MnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5Jyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBEdXBsZXg7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuUmVhZGFibGUuUmVhZGFibGVTdGF0ZSA9IFJlYWRhYmxlU3RhdGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgRUUgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG5cbnZhciBFRWxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbiAoZW1pdHRlciwgdHlwZSkge1xuICByZXR1cm4gZW1pdHRlci5saXN0ZW5lcnModHlwZSkubGVuZ3RoO1xufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0nKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBidWZmZXJTaGltID0gcmVxdWlyZSgnYnVmZmVyLXNoaW1zJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGRlYnVnVXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBkZWJ1ZyA9IHZvaWQgMDtcbmlmIChkZWJ1Z1V0aWwgJiYgZGVidWdVdGlsLmRlYnVnbG9nKSB7XG4gIGRlYnVnID0gZGVidWdVdGlsLmRlYnVnbG9nKCdzdHJlYW0nKTtcbn0gZWxzZSB7XG4gIGRlYnVnID0gZnVuY3Rpb24gKCkge307XG59XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvQnVmZmVyTGlzdCcpO1xudmFyIFN0cmluZ0RlY29kZXI7XG5cbnV0aWwuaW5oZXJpdHMoUmVhZGFibGUsIFN0cmVhbSk7XG5cbnZhciBrUHJveHlFdmVudHMgPSBbJ2Vycm9yJywgJ2Nsb3NlJywgJ2Rlc3Ryb3knLCAncGF1c2UnLCAncmVzdW1lJ107XG5cbmZ1bmN0aW9uIHByZXBlbmRMaXN0ZW5lcihlbWl0dGVyLCBldmVudCwgZm4pIHtcbiAgLy8gU2FkbHkgdGhpcyBpcyBub3QgY2FjaGVhYmxlIGFzIHNvbWUgbGlicmFyaWVzIGJ1bmRsZSB0aGVpciBvd25cbiAgLy8gZXZlbnQgZW1pdHRlciBpbXBsZW1lbnRhdGlvbiB3aXRoIHRoZW0uXG4gIGlmICh0eXBlb2YgZW1pdHRlci5wcmVwZW5kTGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZW1pdHRlci5wcmVwZW5kTGlzdGVuZXIoZXZlbnQsIGZuKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBUaGlzIGlzIGEgaGFjayB0byBtYWtlIHN1cmUgdGhhdCBvdXIgZXJyb3IgaGFuZGxlciBpcyBhdHRhY2hlZCBiZWZvcmUgYW55XG4gICAgLy8gdXNlcmxhbmQgb25lcy4gIE5FVkVSIERPIFRISVMuIFRoaXMgaXMgaGVyZSBvbmx5IGJlY2F1c2UgdGhpcyBjb2RlIG5lZWRzXG4gICAgLy8gdG8gY29udGludWUgdG8gd29yayB3aXRoIG9sZGVyIHZlcnNpb25zIG9mIE5vZGUuanMgdGhhdCBkbyBub3QgaW5jbHVkZVxuICAgIC8vIHRoZSBwcmVwZW5kTGlzdGVuZXIoKSBtZXRob2QuIFRoZSBnb2FsIGlzIHRvIGV2ZW50dWFsbHkgcmVtb3ZlIHRoaXMgaGFjay5cbiAgICBpZiAoIWVtaXR0ZXIuX2V2ZW50cyB8fCAhZW1pdHRlci5fZXZlbnRzW2V2ZW50XSkgZW1pdHRlci5vbihldmVudCwgZm4pO2Vsc2UgaWYgKGlzQXJyYXkoZW1pdHRlci5fZXZlbnRzW2V2ZW50XSkpIGVtaXR0ZXIuX2V2ZW50c1tldmVudF0udW5zaGlmdChmbik7ZWxzZSBlbWl0dGVyLl9ldmVudHNbZXZlbnRdID0gW2ZuLCBlbWl0dGVyLl9ldmVudHNbZXZlbnRdXTtcbiAgfVxufVxuXG5mdW5jdGlvbiBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZy4gVXNlZCB0byBtYWtlIHJlYWQobikgaWdub3JlIG4gYW5kIHRvXG4gIC8vIG1ha2UgYWxsIHRoZSBidWZmZXIgbWVyZ2luZyBhbmQgbGVuZ3RoIGNoZWNrcyBnbyBhd2F5XG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXgpIHRoaXMub2JqZWN0TW9kZSA9IHRoaXMub2JqZWN0TW9kZSB8fCAhIW9wdGlvbnMucmVhZGFibGVPYmplY3RNb2RlO1xuXG4gIC8vIHRoZSBwb2ludCBhdCB3aGljaCBpdCBzdG9wcyBjYWxsaW5nIF9yZWFkKCkgdG8gZmlsbCB0aGUgYnVmZmVyXG4gIC8vIE5vdGU6IDAgaXMgYSB2YWxpZCB2YWx1ZSwgbWVhbnMgXCJkb24ndCBjYWxsIF9yZWFkIHByZWVtcHRpdmVseSBldmVyXCJcbiAgdmFyIGh3bSA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgdmFyIGRlZmF1bHRId20gPSB0aGlzLm9iamVjdE1vZGUgPyAxNiA6IDE2ICogMTAyNDtcbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gaHdtIHx8IGh3bSA9PT0gMCA/IGh3bSA6IGRlZmF1bHRId207XG5cbiAgLy8gY2FzdCB0byBpbnRzLlxuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSB+fnRoaXMuaGlnaFdhdGVyTWFyaztcblxuICAvLyBBIGxpbmtlZCBsaXN0IGlzIHVzZWQgdG8gc3RvcmUgZGF0YSBjaHVua3MgaW5zdGVhZCBvZiBhbiBhcnJheSBiZWNhdXNlIHRoZVxuICAvLyBsaW5rZWQgbGlzdCBjYW4gcmVtb3ZlIGVsZW1lbnRzIGZyb20gdGhlIGJlZ2lubmluZyBmYXN0ZXIgdGhhblxuICAvLyBhcnJheS5zaGlmdCgpXG4gIHRoaXMuYnVmZmVyID0gbmV3IEJ1ZmZlckxpc3QoKTtcbiAgdGhpcy5sZW5ndGggPSAwO1xuICB0aGlzLnBpcGVzID0gbnVsbDtcbiAgdGhpcy5waXBlc0NvdW50ID0gMDtcbiAgdGhpcy5mbG93aW5nID0gbnVsbDtcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICB0aGlzLmVuZEVtaXR0ZWQgPSBmYWxzZTtcbiAgdGhpcy5yZWFkaW5nID0gZmFsc2U7XG5cbiAgLy8gYSBmbGFnIHRvIGJlIGFibGUgdG8gdGVsbCBpZiB0aGUgb253cml0ZSBjYiBpcyBjYWxsZWQgaW1tZWRpYXRlbHksXG4gIC8vIG9yIG9uIGEgbGF0ZXIgdGljay4gIFdlIHNldCB0aGlzIHRvIHRydWUgYXQgZmlyc3QsIGJlY2F1c2UgYW55XG4gIC8vIGFjdGlvbnMgdGhhdCBzaG91bGRuJ3QgaGFwcGVuIHVudGlsIFwibGF0ZXJcIiBzaG91bGQgZ2VuZXJhbGx5IGFsc29cbiAgLy8gbm90IGhhcHBlbiBiZWZvcmUgdGhlIGZpcnN0IHdyaXRlIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gd2hlbmV2ZXIgd2UgcmV0dXJuIG51bGwsIHRoZW4gd2Ugc2V0IGEgZmxhZyB0byBzYXlcbiAgLy8gdGhhdCB3ZSdyZSBhd2FpdGluZyBhICdyZWFkYWJsZScgZXZlbnQgZW1pc3Npb24uXG4gIHRoaXMubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMucmVhZGFibGVMaXN0ZW5pbmcgPSBmYWxzZTtcbiAgdGhpcy5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyB3aGVuIHBpcGluZywgd2Ugb25seSBjYXJlIGFib3V0ICdyZWFkYWJsZScgZXZlbnRzIHRoYXQgaGFwcGVuXG4gIC8vIGFmdGVyIHJlYWQoKWluZyBhbGwgdGhlIGJ5dGVzIGFuZCBub3QgZ2V0dGluZyBhbnkgcHVzaGJhY2suXG4gIHRoaXMucmFuT3V0ID0gZmFsc2U7XG5cbiAgLy8gdGhlIG51bWJlciBvZiB3cml0ZXJzIHRoYXQgYXJlIGF3YWl0aW5nIGEgZHJhaW4gZXZlbnQgaW4gLnBpcGUoKXNcbiAgdGhpcy5hd2FpdERyYWluID0gMDtcblxuICAvLyBpZiB0cnVlLCBhIG1heWJlUmVhZE1vcmUgaGFzIGJlZW4gc2NoZWR1bGVkXG4gIHRoaXMucmVhZGluZ01vcmUgPSBmYWxzZTtcblxuICB0aGlzLmRlY29kZXIgPSBudWxsO1xuICB0aGlzLmVuY29kaW5nID0gbnVsbDtcbiAgaWYgKG9wdGlvbnMuZW5jb2RpbmcpIHtcbiAgICBpZiAoIVN0cmluZ0RlY29kZXIpIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2Rlci8nKS5TdHJpbmdEZWNvZGVyO1xuICAgIHRoaXMuZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKG9wdGlvbnMuZW5jb2RpbmcpO1xuICAgIHRoaXMuZW5jb2RpbmcgPSBvcHRpb25zLmVuY29kaW5nO1xuICB9XG59XG5cbmZ1bmN0aW9uIFJlYWRhYmxlKG9wdGlvbnMpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmVhZGFibGUpKSByZXR1cm4gbmV3IFJlYWRhYmxlKG9wdGlvbnMpO1xuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUgPSBuZXcgUmVhZGFibGVTdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyBsZWdhY3lcbiAgdGhpcy5yZWFkYWJsZSA9IHRydWU7XG5cbiAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMucmVhZCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fcmVhZCA9IG9wdGlvbnMucmVhZDtcblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuLy8gTWFudWFsbHkgc2hvdmUgc29tZXRoaW5nIGludG8gdGhlIHJlYWQoKSBidWZmZXIuXG4vLyBUaGlzIHJldHVybnMgdHJ1ZSBpZiB0aGUgaGlnaFdhdGVyTWFyayBoYXMgbm90IGJlZW4gaGl0IHlldCxcbi8vIHNpbWlsYXIgdG8gaG93IFdyaXRhYmxlLndyaXRlKCkgcmV0dXJucyB0cnVlIGlmIHlvdSBzaG91bGRcbi8vIHdyaXRlKCkgc29tZSBtb3JlLlxuUmVhZGFibGUucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmIHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGVuY29kaW5nIHx8IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcbiAgICBpZiAoZW5jb2RpbmcgIT09IHN0YXRlLmVuY29kaW5nKSB7XG4gICAgICBjaHVuayA9IGJ1ZmZlclNoaW0uZnJvbShjaHVuaywgZW5jb2RpbmcpO1xuICAgICAgZW5jb2RpbmcgPSAnJztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBmYWxzZSk7XG59O1xuXG4vLyBVbnNoaWZ0IHNob3VsZCAqYWx3YXlzKiBiZSBzb21ldGhpbmcgZGlyZWN0bHkgb3V0IG9mIHJlYWQoKVxuUmVhZGFibGUucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCAnJywgdHJ1ZSk7XG59O1xuXG5SZWFkYWJsZS5wcm90b3R5cGUuaXNQYXVzZWQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPT09IGZhbHNlO1xufTtcblxuZnVuY3Rpb24gcmVhZGFibGVBZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGFkZFRvRnJvbnQpIHtcbiAgdmFyIGVyID0gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuayk7XG4gIGlmIChlcikge1xuICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfSBlbHNlIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpO1xuICB9IGVsc2UgaWYgKHN0YXRlLm9iamVjdE1vZGUgfHwgY2h1bmsgJiYgY2h1bmsubGVuZ3RoID4gMCkge1xuICAgIGlmIChzdGF0ZS5lbmRlZCAmJiAhYWRkVG9Gcm9udCkge1xuICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoJ3N0cmVhbS5wdXNoKCkgYWZ0ZXIgRU9GJyk7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlKTtcbiAgICB9IGVsc2UgaWYgKHN0YXRlLmVuZEVtaXR0ZWQgJiYgYWRkVG9Gcm9udCkge1xuICAgICAgdmFyIF9lID0gbmV3IEVycm9yKCdzdHJlYW0udW5zaGlmdCgpIGFmdGVyIGVuZCBldmVudCcpO1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgX2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgc2tpcEFkZDtcbiAgICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFhZGRUb0Zyb250ICYmICFlbmNvZGluZykge1xuICAgICAgICBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuICAgICAgICBza2lwQWRkID0gIXN0YXRlLm9iamVjdE1vZGUgJiYgY2h1bmsubGVuZ3RoID09PSAwO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWFkZFRvRnJvbnQpIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcblxuICAgICAgLy8gRG9uJ3QgYWRkIHRvIHRoZSBidWZmZXIgaWYgd2UndmUgZGVjb2RlZCB0byBhbiBlbXB0eSBzdHJpbmcgY2h1bmsgYW5kXG4gICAgICAvLyB3ZSdyZSBub3QgaW4gb2JqZWN0IG1vZGVcbiAgICAgIGlmICghc2tpcEFkZCkge1xuICAgICAgICAvLyBpZiB3ZSB3YW50IHRoZSBkYXRhIG5vdywganVzdCBlbWl0IGl0LlxuICAgICAgICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgIXN0YXRlLnN5bmMpIHtcbiAgICAgICAgICBzdHJlYW0uZW1pdCgnZGF0YScsIGNodW5rKTtcbiAgICAgICAgICBzdHJlYW0ucmVhZCgwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyB1cGRhdGUgdGhlIGJ1ZmZlciBpbmZvLlxuICAgICAgICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICAgICAgICBpZiAoYWRkVG9Gcm9udCkgc3RhdGUuYnVmZmVyLnVuc2hpZnQoY2h1bmspO2Vsc2Ugc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuXG4gICAgICAgICAgaWYgKHN0YXRlLm5lZWRSZWFkYWJsZSkgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIWFkZFRvRnJvbnQpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gbmVlZE1vcmVEYXRhKHN0YXRlKTtcbn1cblxuLy8gaWYgaXQncyBwYXN0IHRoZSBoaWdoIHdhdGVyIG1hcmssIHdlIGNhbiBwdXNoIGluIHNvbWUgbW9yZS5cbi8vIEFsc28sIGlmIHdlIGhhdmUgbm8gZGF0YSB5ZXQsIHdlIGNhbiBzdGFuZCBzb21lXG4vLyBtb3JlIGJ5dGVzLiAgVGhpcyBpcyB0byB3b3JrIGFyb3VuZCBjYXNlcyB3aGVyZSBod209MCxcbi8vIHN1Y2ggYXMgdGhlIHJlcGwuICBBbHNvLCBpZiB0aGUgcHVzaCgpIHRyaWdnZXJlZCBhXG4vLyByZWFkYWJsZSBldmVudCwgYW5kIHRoZSB1c2VyIGNhbGxlZCByZWFkKGxhcmdlTnVtYmVyKSBzdWNoIHRoYXRcbi8vIG5lZWRSZWFkYWJsZSB3YXMgc2V0LCB0aGVuIHdlIG91Z2h0IHRvIHB1c2ggbW9yZSwgc28gdGhhdCBhbm90aGVyXG4vLyAncmVhZGFibGUnIGV2ZW50IHdpbGwgYmUgdHJpZ2dlcmVkLlxuZnVuY3Rpb24gbmVlZE1vcmVEYXRhKHN0YXRlKSB7XG4gIHJldHVybiAhc3RhdGUuZW5kZWQgJiYgKHN0YXRlLm5lZWRSZWFkYWJsZSB8fCBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmxlbmd0aCA9PT0gMCk7XG59XG5cbi8vIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuUmVhZGFibGUucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24gKGVuYykge1xuICBpZiAoIVN0cmluZ0RlY29kZXIpIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2Rlci8nKS5TdHJpbmdEZWNvZGVyO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihlbmMpO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmVuY29kaW5nID0gZW5jO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIERvbid0IHJhaXNlIHRoZSBod20gPiA4TUJcbnZhciBNQVhfSFdNID0gMHg4MDAwMDA7XG5mdW5jdGlvbiBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKSB7XG4gIGlmIChuID49IE1BWF9IV00pIHtcbiAgICBuID0gTUFYX0hXTTtcbiAgfSBlbHNlIHtcbiAgICAvLyBHZXQgdGhlIG5leHQgaGlnaGVzdCBwb3dlciBvZiAyIHRvIHByZXZlbnQgaW5jcmVhc2luZyBod20gZXhjZXNzaXZlbHkgaW5cbiAgICAvLyB0aW55IGFtb3VudHNcbiAgICBuLS07XG4gICAgbiB8PSBuID4+PiAxO1xuICAgIG4gfD0gbiA+Pj4gMjtcbiAgICBuIHw9IG4gPj4+IDQ7XG4gICAgbiB8PSBuID4+PiA4O1xuICAgIG4gfD0gbiA+Pj4gMTY7XG4gICAgbisrO1xuICB9XG4gIHJldHVybiBuO1xufVxuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGhvd011Y2hUb1JlYWQobiwgc3RhdGUpIHtcbiAgaWYgKG4gPD0gMCB8fCBzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpIHJldHVybiAwO1xuICBpZiAoc3RhdGUub2JqZWN0TW9kZSkgcmV0dXJuIDE7XG4gIGlmIChuICE9PSBuKSB7XG4gICAgLy8gT25seSBmbG93IG9uZSBidWZmZXIgYXQgYSB0aW1lXG4gICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoKSByZXR1cm4gc3RhdGUuYnVmZmVyLmhlYWQuZGF0YS5sZW5ndGg7ZWxzZSByZXR1cm4gc3RhdGUubGVuZ3RoO1xuICB9XG4gIC8vIElmIHdlJ3JlIGFza2luZyBmb3IgbW9yZSB0aGFuIHRoZSBjdXJyZW50IGh3bSwgdGhlbiByYWlzZSB0aGUgaHdtLlxuICBpZiAobiA+IHN0YXRlLmhpZ2hXYXRlck1hcmspIHN0YXRlLmhpZ2hXYXRlck1hcmsgPSBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKTtcbiAgaWYgKG4gPD0gc3RhdGUubGVuZ3RoKSByZXR1cm4gbjtcbiAgLy8gRG9uJ3QgaGF2ZSBlbm91Z2hcbiAgaWYgKCFzdGF0ZS5lbmRlZCkge1xuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbn1cblxuLy8geW91IGNhbiBvdmVycmlkZSBlaXRoZXIgdGhpcyBtZXRob2QsIG9yIHRoZSBhc3luYyBfcmVhZChuKSBiZWxvdy5cblJlYWRhYmxlLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgZGVidWcoJ3JlYWQnLCBuKTtcbiAgbiA9IHBhcnNlSW50KG4sIDEwKTtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIG5PcmlnID0gbjtcblxuICBpZiAobiAhPT0gMCkgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG5cbiAgLy8gaWYgd2UncmUgZG9pbmcgcmVhZCgwKSB0byB0cmlnZ2VyIGEgcmVhZGFibGUgZXZlbnQsIGJ1dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYSBidW5jaCBvZiBkYXRhIGluIHRoZSBidWZmZXIsIHRoZW4ganVzdCB0cmlnZ2VyXG4gIC8vIHRoZSAncmVhZGFibGUnIGV2ZW50IGFuZCBtb3ZlIG9uLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5uZWVkUmVhZGFibGUgJiYgKHN0YXRlLmxlbmd0aCA+PSBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmVuZGVkKSkge1xuICAgIGRlYnVnKCdyZWFkOiBlbWl0UmVhZGFibGUnLCBzdGF0ZS5sZW5ndGgsIHN0YXRlLmVuZGVkKTtcbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKSBlbmRSZWFkYWJsZSh0aGlzKTtlbHNlIGVtaXRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIG4gPSBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKTtcblxuICAvLyBpZiB3ZSd2ZSBlbmRlZCwgYW5kIHdlJ3JlIG5vdyBjbGVhciwgdGhlbiBmaW5pc2ggaXQgdXAuXG4gIGlmIChuID09PSAwICYmIHN0YXRlLmVuZGVkKSB7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgZW5kUmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBBbGwgdGhlIGFjdHVhbCBjaHVuayBnZW5lcmF0aW9uIGxvZ2ljIG5lZWRzIHRvIGJlXG4gIC8vICpiZWxvdyogdGhlIGNhbGwgdG8gX3JlYWQuICBUaGUgcmVhc29uIGlzIHRoYXQgaW4gY2VydGFpblxuICAvLyBzeW50aGV0aWMgc3RyZWFtIGNhc2VzLCBzdWNoIGFzIHBhc3N0aHJvdWdoIHN0cmVhbXMsIF9yZWFkXG4gIC8vIG1heSBiZSBhIGNvbXBsZXRlbHkgc3luY2hyb25vdXMgb3BlcmF0aW9uIHdoaWNoIG1heSBjaGFuZ2VcbiAgLy8gdGhlIHN0YXRlIG9mIHRoZSByZWFkIGJ1ZmZlciwgcHJvdmlkaW5nIGVub3VnaCBkYXRhIHdoZW5cbiAgLy8gYmVmb3JlIHRoZXJlIHdhcyAqbm90KiBlbm91Z2guXG4gIC8vXG4gIC8vIFNvLCB0aGUgc3RlcHMgYXJlOlxuICAvLyAxLiBGaWd1cmUgb3V0IHdoYXQgdGhlIHN0YXRlIG9mIHRoaW5ncyB3aWxsIGJlIGFmdGVyIHdlIGRvXG4gIC8vIGEgcmVhZCBmcm9tIHRoZSBidWZmZXIuXG4gIC8vXG4gIC8vIDIuIElmIHRoYXQgcmVzdWx0aW5nIHN0YXRlIHdpbGwgdHJpZ2dlciBhIF9yZWFkLCB0aGVuIGNhbGwgX3JlYWQuXG4gIC8vIE5vdGUgdGhhdCB0aGlzIG1heSBiZSBhc3luY2hyb25vdXMsIG9yIHN5bmNocm9ub3VzLiAgWWVzLCBpdCBpc1xuICAvLyBkZWVwbHkgdWdseSB0byB3cml0ZSBBUElzIHRoaXMgd2F5LCBidXQgdGhhdCBzdGlsbCBkb2Vzbid0IG1lYW5cbiAgLy8gdGhhdCB0aGUgUmVhZGFibGUgY2xhc3Mgc2hvdWxkIGJlaGF2ZSBpbXByb3Blcmx5LCBhcyBzdHJlYW1zIGFyZVxuICAvLyBkZXNpZ25lZCB0byBiZSBzeW5jL2FzeW5jIGFnbm9zdGljLlxuICAvLyBUYWtlIG5vdGUgaWYgdGhlIF9yZWFkIGNhbGwgaXMgc3luYyBvciBhc3luYyAoaWUsIGlmIHRoZSByZWFkIGNhbGxcbiAgLy8gaGFzIHJldHVybmVkIHlldCksIHNvIHRoYXQgd2Uga25vdyB3aGV0aGVyIG9yIG5vdCBpdCdzIHNhZmUgdG8gZW1pdFxuICAvLyAncmVhZGFibGUnIGV0Yy5cbiAgLy9cbiAgLy8gMy4gQWN0dWFsbHkgcHVsbCB0aGUgcmVxdWVzdGVkIGNodW5rcyBvdXQgb2YgdGhlIGJ1ZmZlciBhbmQgcmV0dXJuLlxuXG4gIC8vIGlmIHdlIG5lZWQgYSByZWFkYWJsZSBldmVudCwgdGhlbiB3ZSBuZWVkIHRvIGRvIHNvbWUgcmVhZGluZy5cbiAgdmFyIGRvUmVhZCA9IHN0YXRlLm5lZWRSZWFkYWJsZTtcbiAgZGVidWcoJ25lZWQgcmVhZGFibGUnLCBkb1JlYWQpO1xuXG4gIC8vIGlmIHdlIGN1cnJlbnRseSBoYXZlIGxlc3MgdGhhbiB0aGUgaGlnaFdhdGVyTWFyaywgdGhlbiBhbHNvIHJlYWQgc29tZVxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwIHx8IHN0YXRlLmxlbmd0aCAtIG4gPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgZG9SZWFkID0gdHJ1ZTtcbiAgICBkZWJ1ZygnbGVuZ3RoIGxlc3MgdGhhbiB3YXRlcm1hcmsnLCBkb1JlYWQpO1xuICB9XG5cbiAgLy8gaG93ZXZlciwgaWYgd2UndmUgZW5kZWQsIHRoZW4gdGhlcmUncyBubyBwb2ludCwgYW5kIGlmIHdlJ3JlIGFscmVhZHlcbiAgLy8gcmVhZGluZywgdGhlbiBpdCdzIHVubmVjZXNzYXJ5LlxuICBpZiAoc3RhdGUuZW5kZWQgfHwgc3RhdGUucmVhZGluZykge1xuICAgIGRvUmVhZCA9IGZhbHNlO1xuICAgIGRlYnVnKCdyZWFkaW5nIG9yIGVuZGVkJywgZG9SZWFkKTtcbiAgfSBlbHNlIGlmIChkb1JlYWQpIHtcbiAgICBkZWJ1ZygnZG8gcmVhZCcpO1xuICAgIHN0YXRlLnJlYWRpbmcgPSB0cnVlO1xuICAgIHN0YXRlLnN5bmMgPSB0cnVlO1xuICAgIC8vIGlmIHRoZSBsZW5ndGggaXMgY3VycmVudGx5IHplcm8sIHRoZW4gd2UgKm5lZWQqIGEgcmVhZGFibGUgZXZlbnQuXG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAvLyBjYWxsIGludGVybmFsIHJlYWQgbWV0aG9kXG4gICAgdGhpcy5fcmVhZChzdGF0ZS5oaWdoV2F0ZXJNYXJrKTtcbiAgICBzdGF0ZS5zeW5jID0gZmFsc2U7XG4gICAgLy8gSWYgX3JlYWQgcHVzaGVkIGRhdGEgc3luY2hyb25vdXNseSwgdGhlbiBgcmVhZGluZ2Agd2lsbCBiZSBmYWxzZSxcbiAgICAvLyBhbmQgd2UgbmVlZCB0byByZS1ldmFsdWF0ZSBob3cgbXVjaCBkYXRhIHdlIGNhbiByZXR1cm4gdG8gdGhlIHVzZXIuXG4gICAgaWYgKCFzdGF0ZS5yZWFkaW5nKSBuID0gaG93TXVjaFRvUmVhZChuT3JpZywgc3RhdGUpO1xuICB9XG5cbiAgdmFyIHJldDtcbiAgaWYgKG4gPiAwKSByZXQgPSBmcm9tTGlzdChuLCBzdGF0ZSk7ZWxzZSByZXQgPSBudWxsO1xuXG4gIGlmIChyZXQgPT09IG51bGwpIHtcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIG4gPSAwO1xuICB9IGVsc2Uge1xuICAgIHN0YXRlLmxlbmd0aCAtPSBuO1xuICB9XG5cbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIElmIHdlIGhhdmUgbm90aGluZyBpbiB0aGUgYnVmZmVyLCB0aGVuIHdlIHdhbnQgdG8ga25vd1xuICAgIC8vIGFzIHNvb24gYXMgd2UgKmRvKiBnZXQgc29tZXRoaW5nIGludG8gdGhlIGJ1ZmZlci5cbiAgICBpZiAoIXN0YXRlLmVuZGVkKSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gICAgLy8gSWYgd2UgdHJpZWQgdG8gcmVhZCgpIHBhc3QgdGhlIEVPRiwgdGhlbiBlbWl0IGVuZCBvbiB0aGUgbmV4dCB0aWNrLlxuICAgIGlmIChuT3JpZyAhPT0gbiAmJiBzdGF0ZS5lbmRlZCkgZW5kUmVhZGFibGUodGhpcyk7XG4gIH1cblxuICBpZiAocmV0ICE9PSBudWxsKSB0aGlzLmVtaXQoJ2RhdGEnLCByZXQpO1xuXG4gIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBjaHVua0ludmFsaWQoc3RhdGUsIGNodW5rKSB7XG4gIHZhciBlciA9IG51bGw7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGNodW5rKSAmJiB0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmIGNodW5rICE9PSBudWxsICYmIGNodW5rICE9PSB1bmRlZmluZWQgJiYgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICBlciA9IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmsnKTtcbiAgfVxuICByZXR1cm4gZXI7XG59XG5cbmZ1bmN0aW9uIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUuZW5kZWQpIHJldHVybjtcbiAgaWYgKHN0YXRlLmRlY29kZXIpIHtcbiAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgIGlmIChjaHVuayAmJiBjaHVuay5sZW5ndGgpIHtcbiAgICAgIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcbiAgICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICB9XG4gIH1cbiAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuXG4gIC8vIGVtaXQgJ3JlYWRhYmxlJyBub3cgdG8gbWFrZSBzdXJlIGl0IGdldHMgcGlja2VkIHVwLlxuICBlbWl0UmVhZGFibGUoc3RyZWFtKTtcbn1cblxuLy8gRG9uJ3QgZW1pdCByZWFkYWJsZSByaWdodCBhd2F5IGluIHN5bmMgbW9kZSwgYmVjYXVzZSB0aGlzIGNhbiB0cmlnZ2VyXG4vLyBhbm90aGVyIHJlYWQoKSBjYWxsID0+IHN0YWNrIG92ZXJmbG93LiAgVGhpcyB3YXksIGl0IG1pZ2h0IHRyaWdnZXJcbi8vIGEgbmV4dFRpY2sgcmVjdXJzaW9uIHdhcm5pbmcsIGJ1dCB0aGF0J3Mgbm90IHNvIGJhZC5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZShzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBzdGF0ZS5uZWVkUmVhZGFibGUgPSBmYWxzZTtcbiAgaWYgKCFzdGF0ZS5lbWl0dGVkUmVhZGFibGUpIHtcbiAgICBkZWJ1ZygnZW1pdFJlYWRhYmxlJywgc3RhdGUuZmxvd2luZyk7XG4gICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICBpZiAoc3RhdGUuc3luYykgcHJvY2Vzc05leHRUaWNrKGVtaXRSZWFkYWJsZV8sIHN0cmVhbSk7ZWxzZSBlbWl0UmVhZGFibGVfKHN0cmVhbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdFJlYWRhYmxlXyhzdHJlYW0pIHtcbiAgZGVidWcoJ2VtaXQgcmVhZGFibGUnKTtcbiAgc3RyZWFtLmVtaXQoJ3JlYWRhYmxlJyk7XG4gIGZsb3coc3RyZWFtKTtcbn1cblxuLy8gYXQgdGhpcyBwb2ludCwgdGhlIHVzZXIgaGFzIHByZXN1bWFibHkgc2VlbiB0aGUgJ3JlYWRhYmxlJyBldmVudCxcbi8vIGFuZCBjYWxsZWQgcmVhZCgpIHRvIGNvbnN1bWUgc29tZSBkYXRhLiAgdGhhdCBtYXkgaGF2ZSB0cmlnZ2VyZWRcbi8vIGluIHR1cm4gYW5vdGhlciBfcmVhZChuKSBjYWxsLCBpbiB3aGljaCBjYXNlIHJlYWRpbmcgPSB0cnVlIGlmXG4vLyBpdCdzIGluIHByb2dyZXNzLlxuLy8gSG93ZXZlciwgaWYgd2UncmUgbm90IGVuZGVkLCBvciByZWFkaW5nLCBhbmQgdGhlIGxlbmd0aCA8IGh3bSxcbi8vIHRoZW4gZ28gYWhlYWQgYW5kIHRyeSB0byByZWFkIHNvbWUgbW9yZSBwcmVlbXB0aXZlbHkuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZWFkaW5nTW9yZSkge1xuICAgIHN0YXRlLnJlYWRpbmdNb3JlID0gdHJ1ZTtcbiAgICBwcm9jZXNzTmV4dFRpY2sobWF5YmVSZWFkTW9yZV8sIHN0cmVhbSwgc3RhdGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1heWJlUmVhZE1vcmVfKHN0cmVhbSwgc3RhdGUpIHtcbiAgdmFyIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgd2hpbGUgKCFzdGF0ZS5yZWFkaW5nICYmICFzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5lbmRlZCAmJiBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgZGVidWcoJ21heWJlUmVhZE1vcmUgcmVhZCAwJyk7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gICAgaWYgKGxlbiA9PT0gc3RhdGUubGVuZ3RoKVxuICAgICAgLy8gZGlkbid0IGdldCBhbnkgZGF0YSwgc3RvcCBzcGlubmluZy5cbiAgICAgIGJyZWFrO2Vsc2UgbGVuID0gc3RhdGUubGVuZ3RoO1xuICB9XG4gIHN0YXRlLnJlYWRpbmdNb3JlID0gZmFsc2U7XG59XG5cbi8vIGFic3RyYWN0IG1ldGhvZC4gIHRvIGJlIG92ZXJyaWRkZW4gaW4gc3BlY2lmaWMgaW1wbGVtZW50YXRpb24gY2xhc3Nlcy5cbi8vIGNhbGwgY2IoZXIsIGRhdGEpIHdoZXJlIGRhdGEgaXMgPD0gbiBpbiBsZW5ndGguXG4vLyBmb3IgdmlydHVhbCAobm9uLXN0cmluZywgbm9uLWJ1ZmZlcikgc3RyZWFtcywgXCJsZW5ndGhcIiBpcyBzb21ld2hhdFxuLy8gYXJiaXRyYXJ5LCBhbmQgcGVyaGFwcyBub3QgdmVyeSBtZWFuaW5nZnVsLlxuUmVhZGFibGUucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignX3JlYWQoKSBpcyBub3QgaW1wbGVtZW50ZWQnKSk7XG59O1xuXG5SZWFkYWJsZS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uIChkZXN0LCBwaXBlT3B0cykge1xuICB2YXIgc3JjID0gdGhpcztcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICBzd2l0Y2ggKHN0YXRlLnBpcGVzQ291bnQpIHtcbiAgICBjYXNlIDA6XG4gICAgICBzdGF0ZS5waXBlcyA9IGRlc3Q7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDE6XG4gICAgICBzdGF0ZS5waXBlcyA9IFtzdGF0ZS5waXBlcywgZGVzdF07XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgc3RhdGUucGlwZXMucHVzaChkZXN0KTtcbiAgICAgIGJyZWFrO1xuICB9XG4gIHN0YXRlLnBpcGVzQ291bnQgKz0gMTtcbiAgZGVidWcoJ3BpcGUgY291bnQ9JWQgb3B0cz0laicsIHN0YXRlLnBpcGVzQ291bnQsIHBpcGVPcHRzKTtcblxuICB2YXIgZG9FbmQgPSAoIXBpcGVPcHRzIHx8IHBpcGVPcHRzLmVuZCAhPT0gZmFsc2UpICYmIGRlc3QgIT09IHByb2Nlc3Muc3Rkb3V0ICYmIGRlc3QgIT09IHByb2Nlc3Muc3RkZXJyO1xuXG4gIHZhciBlbmRGbiA9IGRvRW5kID8gb25lbmQgOiBjbGVhbnVwO1xuICBpZiAoc3RhdGUuZW5kRW1pdHRlZCkgcHJvY2Vzc05leHRUaWNrKGVuZEZuKTtlbHNlIHNyYy5vbmNlKCdlbmQnLCBlbmRGbik7XG5cbiAgZGVzdC5vbigndW5waXBlJywgb251bnBpcGUpO1xuICBmdW5jdGlvbiBvbnVucGlwZShyZWFkYWJsZSkge1xuICAgIGRlYnVnKCdvbnVucGlwZScpO1xuICAgIGlmIChyZWFkYWJsZSA9PT0gc3JjKSB7XG4gICAgICBjbGVhbnVwKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25lbmQoKSB7XG4gICAgZGVidWcoJ29uZW5kJyk7XG4gICAgZGVzdC5lbmQoKTtcbiAgfVxuXG4gIC8vIHdoZW4gdGhlIGRlc3QgZHJhaW5zLCBpdCByZWR1Y2VzIHRoZSBhd2FpdERyYWluIGNvdW50ZXJcbiAgLy8gb24gdGhlIHNvdXJjZS4gIFRoaXMgd291bGQgYmUgbW9yZSBlbGVnYW50IHdpdGggYSAub25jZSgpXG4gIC8vIGhhbmRsZXIgaW4gZmxvdygpLCBidXQgYWRkaW5nIGFuZCByZW1vdmluZyByZXBlYXRlZGx5IGlzXG4gIC8vIHRvbyBzbG93LlxuICB2YXIgb25kcmFpbiA9IHBpcGVPbkRyYWluKHNyYyk7XG4gIGRlc3Qub24oJ2RyYWluJywgb25kcmFpbik7XG5cbiAgdmFyIGNsZWFuZWRVcCA9IGZhbHNlO1xuICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgIGRlYnVnKCdjbGVhbnVwJyk7XG4gICAgLy8gY2xlYW51cCBldmVudCBoYW5kbGVycyBvbmNlIHRoZSBwaXBlIGlzIGJyb2tlblxuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCd1bnBpcGUnLCBvbnVucGlwZSk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBjbGVhbnVwKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCBvbmRhdGEpO1xuXG4gICAgY2xlYW5lZFVwID0gdHJ1ZTtcblxuICAgIC8vIGlmIHRoZSByZWFkZXIgaXMgd2FpdGluZyBmb3IgYSBkcmFpbiBldmVudCBmcm9tIHRoaXNcbiAgICAvLyBzcGVjaWZpYyB3cml0ZXIsIHRoZW4gaXQgd291bGQgY2F1c2UgaXQgdG8gbmV2ZXIgc3RhcnRcbiAgICAvLyBmbG93aW5nIGFnYWluLlxuICAgIC8vIFNvLCBpZiB0aGlzIGlzIGF3YWl0aW5nIGEgZHJhaW4sIHRoZW4gd2UganVzdCBjYWxsIGl0IG5vdy5cbiAgICAvLyBJZiB3ZSBkb24ndCBrbm93LCB0aGVuIGFzc3VtZSB0aGF0IHdlIGFyZSB3YWl0aW5nIGZvciBvbmUuXG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gJiYgKCFkZXN0Ll93cml0YWJsZVN0YXRlIHx8IGRlc3QuX3dyaXRhYmxlU3RhdGUubmVlZERyYWluKSkgb25kcmFpbigpO1xuICB9XG5cbiAgLy8gSWYgdGhlIHVzZXIgcHVzaGVzIG1vcmUgZGF0YSB3aGlsZSB3ZSdyZSB3cml0aW5nIHRvIGRlc3QgdGhlbiB3ZSdsbCBlbmQgdXBcbiAgLy8gaW4gb25kYXRhIGFnYWluLiBIb3dldmVyLCB3ZSBvbmx5IHdhbnQgdG8gaW5jcmVhc2UgYXdhaXREcmFpbiBvbmNlIGJlY2F1c2VcbiAgLy8gZGVzdCB3aWxsIG9ubHkgZW1pdCBvbmUgJ2RyYWluJyBldmVudCBmb3IgdGhlIG11bHRpcGxlIHdyaXRlcy5cbiAgLy8gPT4gSW50cm9kdWNlIGEgZ3VhcmQgb24gaW5jcmVhc2luZyBhd2FpdERyYWluLlxuICB2YXIgaW5jcmVhc2VkQXdhaXREcmFpbiA9IGZhbHNlO1xuICBzcmMub24oJ2RhdGEnLCBvbmRhdGEpO1xuICBmdW5jdGlvbiBvbmRhdGEoY2h1bmspIHtcbiAgICBkZWJ1Zygnb25kYXRhJyk7XG4gICAgaW5jcmVhc2VkQXdhaXREcmFpbiA9IGZhbHNlO1xuICAgIHZhciByZXQgPSBkZXN0LndyaXRlKGNodW5rKTtcbiAgICBpZiAoZmFsc2UgPT09IHJldCAmJiAhaW5jcmVhc2VkQXdhaXREcmFpbikge1xuICAgICAgLy8gSWYgdGhlIHVzZXIgdW5waXBlZCBkdXJpbmcgYGRlc3Qud3JpdGUoKWAsIGl0IGlzIHBvc3NpYmxlXG4gICAgICAvLyB0byBnZXQgc3R1Y2sgaW4gYSBwZXJtYW5lbnRseSBwYXVzZWQgc3RhdGUgaWYgdGhhdCB3cml0ZVxuICAgICAgLy8gYWxzbyByZXR1cm5lZCBmYWxzZS5cbiAgICAgIC8vID0+IENoZWNrIHdoZXRoZXIgYGRlc3RgIGlzIHN0aWxsIGEgcGlwaW5nIGRlc3RpbmF0aW9uLlxuICAgICAgaWYgKChzdGF0ZS5waXBlc0NvdW50ID09PSAxICYmIHN0YXRlLnBpcGVzID09PSBkZXN0IHx8IHN0YXRlLnBpcGVzQ291bnQgPiAxICYmIGluZGV4T2Yoc3RhdGUucGlwZXMsIGRlc3QpICE9PSAtMSkgJiYgIWNsZWFuZWRVcCkge1xuICAgICAgICBkZWJ1ZygnZmFsc2Ugd3JpdGUgcmVzcG9uc2UsIHBhdXNlJywgc3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4pO1xuICAgICAgICBzcmMuX3JlYWRhYmxlU3RhdGUuYXdhaXREcmFpbisrO1xuICAgICAgICBpbmNyZWFzZWRBd2FpdERyYWluID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHNyYy5wYXVzZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZSBkZXN0IGhhcyBhbiBlcnJvciwgdGhlbiBzdG9wIHBpcGluZyBpbnRvIGl0LlxuICAvLyBob3dldmVyLCBkb24ndCBzdXBwcmVzcyB0aGUgdGhyb3dpbmcgYmVoYXZpb3IgZm9yIHRoaXMuXG4gIGZ1bmN0aW9uIG9uZXJyb3IoZXIpIHtcbiAgICBkZWJ1Zygnb25lcnJvcicsIGVyKTtcbiAgICB1bnBpcGUoKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGlmIChFRWxpc3RlbmVyQ291bnQoZGVzdCwgJ2Vycm9yJykgPT09IDApIGRlc3QuZW1pdCgnZXJyb3InLCBlcik7XG4gIH1cblxuICAvLyBNYWtlIHN1cmUgb3VyIGVycm9yIGhhbmRsZXIgaXMgYXR0YWNoZWQgYmVmb3JlIHVzZXJsYW5kIG9uZXMuXG4gIHByZXBlbmRMaXN0ZW5lcihkZXN0LCAnZXJyb3InLCBvbmVycm9yKTtcblxuICAvLyBCb3RoIGNsb3NlIGFuZCBmaW5pc2ggc2hvdWxkIHRyaWdnZXIgdW5waXBlLCBidXQgb25seSBvbmNlLlxuICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgICB1bnBpcGUoKTtcbiAgfVxuICBkZXN0Lm9uY2UoJ2Nsb3NlJywgb25jbG9zZSk7XG4gIGZ1bmN0aW9uIG9uZmluaXNoKCkge1xuICAgIGRlYnVnKCdvbmZpbmlzaCcpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG5cbiAgZnVuY3Rpb24gdW5waXBlKCkge1xuICAgIGRlYnVnKCd1bnBpcGUnKTtcbiAgICBzcmMudW5waXBlKGRlc3QpO1xuICB9XG5cbiAgLy8gdGVsbCB0aGUgZGVzdCB0aGF0IGl0J3MgYmVpbmcgcGlwZWQgdG9cbiAgZGVzdC5lbWl0KCdwaXBlJywgc3JjKTtcblxuICAvLyBzdGFydCB0aGUgZmxvdyBpZiBpdCBoYXNuJ3QgYmVlbiBzdGFydGVkIGFscmVhZHkuXG4gIGlmICghc3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdwaXBlIHJlc3VtZScpO1xuICAgIHNyYy5yZXN1bWUoKTtcbiAgfVxuXG4gIHJldHVybiBkZXN0O1xufTtcblxuZnVuY3Rpb24gcGlwZU9uRHJhaW4oc3JjKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0YXRlID0gc3JjLl9yZWFkYWJsZVN0YXRlO1xuICAgIGRlYnVnKCdwaXBlT25EcmFpbicsIHN0YXRlLmF3YWl0RHJhaW4pO1xuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluKSBzdGF0ZS5hd2FpdERyYWluLS07XG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gPT09IDAgJiYgRUVsaXN0ZW5lckNvdW50KHNyYywgJ2RhdGEnKSkge1xuICAgICAgc3RhdGUuZmxvd2luZyA9IHRydWU7XG4gICAgICBmbG93KHNyYyk7XG4gICAgfVxuICB9O1xufVxuXG5SZWFkYWJsZS5wcm90b3R5cGUudW5waXBlID0gZnVuY3Rpb24gKGRlc3QpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICAvLyBpZiB3ZSdyZSBub3QgcGlwaW5nIGFueXdoZXJlLCB0aGVuIGRvIG5vdGhpbmcuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAwKSByZXR1cm4gdGhpcztcblxuICAvLyBqdXN0IG9uZSBkZXN0aW5hdGlvbi4gIG1vc3QgY29tbW9uIGNhc2UuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSB7XG4gICAgLy8gcGFzc2VkIGluIG9uZSwgYnV0IGl0J3Mgbm90IHRoZSByaWdodCBvbmUuXG4gICAgaWYgKGRlc3QgJiYgZGVzdCAhPT0gc3RhdGUucGlwZXMpIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKCFkZXN0KSBkZXN0ID0gc3RhdGUucGlwZXM7XG5cbiAgICAvLyBnb3QgYSBtYXRjaC5cbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgIGlmIChkZXN0KSBkZXN0LmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gc2xvdyBjYXNlLiBtdWx0aXBsZSBwaXBlIGRlc3RpbmF0aW9ucy5cblxuICBpZiAoIWRlc3QpIHtcbiAgICAvLyByZW1vdmUgYWxsLlxuICAgIHZhciBkZXN0cyA9IHN0YXRlLnBpcGVzO1xuICAgIHZhciBsZW4gPSBzdGF0ZS5waXBlc0NvdW50O1xuICAgIHN0YXRlLnBpcGVzID0gbnVsbDtcbiAgICBzdGF0ZS5waXBlc0NvdW50ID0gMDtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBkZXN0c1tpXS5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcbiAgICB9cmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyB0cnkgdG8gZmluZCB0aGUgcmlnaHQgb25lLlxuICB2YXIgaW5kZXggPSBpbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KTtcbiAgaWYgKGluZGV4ID09PSAtMSkgcmV0dXJuIHRoaXM7XG5cbiAgc3RhdGUucGlwZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgc3RhdGUucGlwZXNDb3VudCAtPSAxO1xuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSkgc3RhdGUucGlwZXMgPSBzdGF0ZS5waXBlc1swXTtcblxuICBkZXN0LmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gc2V0IHVwIGRhdGEgZXZlbnRzIGlmIHRoZXkgYXJlIGFza2VkIGZvclxuLy8gRW5zdXJlIHJlYWRhYmxlIGxpc3RlbmVycyBldmVudHVhbGx5IGdldCBzb21ldGhpbmdcblJlYWRhYmxlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldiwgZm4pIHtcbiAgdmFyIHJlcyA9IFN0cmVhbS5wcm90b3R5cGUub24uY2FsbCh0aGlzLCBldiwgZm4pO1xuXG4gIGlmIChldiA9PT0gJ2RhdGEnKSB7XG4gICAgLy8gU3RhcnQgZmxvd2luZyBvbiBuZXh0IHRpY2sgaWYgc3RyZWFtIGlzbid0IGV4cGxpY2l0bHkgcGF1c2VkXG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyAhPT0gZmFsc2UpIHRoaXMucmVzdW1lKCk7XG4gIH0gZWxzZSBpZiAoZXYgPT09ICdyZWFkYWJsZScpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICAgIGlmICghc3RhdGUuZW5kRW1pdHRlZCAmJiAhc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcpIHtcbiAgICAgIHN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nID0gc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICAgICAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgICAgIHByb2Nlc3NOZXh0VGljayhuUmVhZGluZ05leHRUaWNrLCB0aGlzKTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGVuZ3RoKSB7XG4gICAgICAgIGVtaXRSZWFkYWJsZSh0aGlzLCBzdGF0ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG5SZWFkYWJsZS5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBSZWFkYWJsZS5wcm90b3R5cGUub247XG5cbmZ1bmN0aW9uIG5SZWFkaW5nTmV4dFRpY2soc2VsZikge1xuICBkZWJ1ZygncmVhZGFibGUgbmV4dHRpY2sgcmVhZCAwJyk7XG4gIHNlbGYucmVhZCgwKTtcbn1cblxuLy8gcGF1c2UoKSBhbmQgcmVzdW1lKCkgYXJlIHJlbW5hbnRzIG9mIHRoZSBsZWdhY3kgcmVhZGFibGUgc3RyZWFtIEFQSVxuLy8gSWYgdGhlIHVzZXIgdXNlcyB0aGVtLCB0aGVuIHN3aXRjaCBpbnRvIG9sZCBtb2RlLlxuUmVhZGFibGUucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgaWYgKCFzdGF0ZS5mbG93aW5nKSB7XG4gICAgZGVidWcoJ3Jlc3VtZScpO1xuICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgIHJlc3VtZSh0aGlzLCBzdGF0ZSk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiByZXN1bWUoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnJlc3VtZVNjaGVkdWxlZCkge1xuICAgIHN0YXRlLnJlc3VtZVNjaGVkdWxlZCA9IHRydWU7XG4gICAgcHJvY2Vzc05leHRUaWNrKHJlc3VtZV8sIHN0cmVhbSwgc3RhdGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc3VtZV8oc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICBkZWJ1ZygncmVzdW1lIHJlYWQgMCcpO1xuICAgIHN0cmVhbS5yZWFkKDApO1xuICB9XG5cbiAgc3RhdGUucmVzdW1lU2NoZWR1bGVkID0gZmFsc2U7XG4gIHN0YXRlLmF3YWl0RHJhaW4gPSAwO1xuICBzdHJlYW0uZW1pdCgncmVzdW1lJyk7XG4gIGZsb3coc3RyZWFtKTtcbiAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgIXN0YXRlLnJlYWRpbmcpIHN0cmVhbS5yZWFkKDApO1xufVxuXG5SZWFkYWJsZS5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCdjYWxsIHBhdXNlIGZsb3dpbmc9JWonLCB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpO1xuICBpZiAoZmFsc2UgIT09IHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdwYXVzZScpO1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgIHRoaXMuZW1pdCgncGF1c2UnKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGZsb3coc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgZGVidWcoJ2Zsb3cnLCBzdGF0ZS5mbG93aW5nKTtcbiAgd2hpbGUgKHN0YXRlLmZsb3dpbmcgJiYgc3RyZWFtLnJlYWQoKSAhPT0gbnVsbCkge31cbn1cblxuLy8gd3JhcCBhbiBvbGQtc3R5bGUgc3RyZWFtIGFzIHRoZSBhc3luYyBkYXRhIHNvdXJjZS5cbi8vIFRoaXMgaXMgKm5vdCogcGFydCBvZiB0aGUgcmVhZGFibGUgc3RyZWFtIGludGVyZmFjZS5cbi8vIEl0IGlzIGFuIHVnbHkgdW5mb3J0dW5hdGUgbWVzcyBvZiBoaXN0b3J5LlxuUmVhZGFibGUucHJvdG90eXBlLndyYXAgPSBmdW5jdGlvbiAoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBwYXVzZWQgPSBmYWxzZTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHN0cmVhbS5vbignZW5kJywgZnVuY3Rpb24gKCkge1xuICAgIGRlYnVnKCd3cmFwcGVkIGVuZCcpO1xuICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFzdGF0ZS5lbmRlZCkge1xuICAgICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICAgIGlmIChjaHVuayAmJiBjaHVuay5sZW5ndGgpIHNlbGYucHVzaChjaHVuayk7XG4gICAgfVxuXG4gICAgc2VsZi5wdXNoKG51bGwpO1xuICB9KTtcblxuICBzdHJlYW0ub24oJ2RhdGEnLCBmdW5jdGlvbiAoY2h1bmspIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBkYXRhJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG5cbiAgICAvLyBkb24ndCBza2lwIG92ZXIgZmFsc3kgdmFsdWVzIGluIG9iamVjdE1vZGVcbiAgICBpZiAoc3RhdGUub2JqZWN0TW9kZSAmJiAoY2h1bmsgPT09IG51bGwgfHwgY2h1bmsgPT09IHVuZGVmaW5lZCkpIHJldHVybjtlbHNlIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiAoIWNodW5rIHx8ICFjaHVuay5sZW5ndGgpKSByZXR1cm47XG5cbiAgICB2YXIgcmV0ID0gc2VsZi5wdXNoKGNodW5rKTtcbiAgICBpZiAoIXJldCkge1xuICAgICAgcGF1c2VkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5wYXVzZSgpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gcHJveHkgYWxsIHRoZSBvdGhlciBtZXRob2RzLlxuICAvLyBpbXBvcnRhbnQgd2hlbiB3cmFwcGluZyBmaWx0ZXJzIGFuZCBkdXBsZXhlcy5cbiAgZm9yICh2YXIgaSBpbiBzdHJlYW0pIHtcbiAgICBpZiAodGhpc1tpXSA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBzdHJlYW1baV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXNbaV0gPSBmdW5jdGlvbiAobWV0aG9kKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIHN0cmVhbVttZXRob2RdLmFwcGx5KHN0cmVhbSwgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICAgIH0oaSk7XG4gICAgfVxuICB9XG5cbiAgLy8gcHJveHkgY2VydGFpbiBpbXBvcnRhbnQgZXZlbnRzLlxuICBmb3IgKHZhciBuID0gMDsgbiA8IGtQcm94eUV2ZW50cy5sZW5ndGg7IG4rKykge1xuICAgIHN0cmVhbS5vbihrUHJveHlFdmVudHNbbl0sIHNlbGYuZW1pdC5iaW5kKHNlbGYsIGtQcm94eUV2ZW50c1tuXSkpO1xuICB9XG5cbiAgLy8gd2hlbiB3ZSB0cnkgdG8gY29uc3VtZSBzb21lIG1vcmUgYnl0ZXMsIHNpbXBseSB1bnBhdXNlIHRoZVxuICAvLyB1bmRlcmx5aW5nIHN0cmVhbS5cbiAgc2VsZi5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgX3JlYWQnLCBuKTtcbiAgICBpZiAocGF1c2VkKSB7XG4gICAgICBwYXVzZWQgPSBmYWxzZTtcbiAgICAgIHN0cmVhbS5yZXN1bWUoKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHNlbGY7XG59O1xuXG4vLyBleHBvc2VkIGZvciB0ZXN0aW5nIHB1cnBvc2VzIG9ubHkuXG5SZWFkYWJsZS5fZnJvbUxpc3QgPSBmcm9tTGlzdDtcblxuLy8gUGx1Y2sgb2ZmIG4gYnl0ZXMgZnJvbSBhbiBhcnJheSBvZiBidWZmZXJzLlxuLy8gTGVuZ3RoIGlzIHRoZSBjb21iaW5lZCBsZW5ndGhzIG9mIGFsbCB0aGUgYnVmZmVycyBpbiB0aGUgbGlzdC5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gZnJvbUxpc3Qobiwgc3RhdGUpIHtcbiAgLy8gbm90aGluZyBidWZmZXJlZFxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcblxuICB2YXIgcmV0O1xuICBpZiAoc3RhdGUub2JqZWN0TW9kZSkgcmV0ID0gc3RhdGUuYnVmZmVyLnNoaWZ0KCk7ZWxzZSBpZiAoIW4gfHwgbiA+PSBzdGF0ZS5sZW5ndGgpIHtcbiAgICAvLyByZWFkIGl0IGFsbCwgdHJ1bmNhdGUgdGhlIGxpc3RcbiAgICBpZiAoc3RhdGUuZGVjb2RlcikgcmV0ID0gc3RhdGUuYnVmZmVyLmpvaW4oJycpO2Vsc2UgaWYgKHN0YXRlLmJ1ZmZlci5sZW5ndGggPT09IDEpIHJldCA9IHN0YXRlLmJ1ZmZlci5oZWFkLmRhdGE7ZWxzZSByZXQgPSBzdGF0ZS5idWZmZXIuY29uY2F0KHN0YXRlLmxlbmd0aCk7XG4gICAgc3RhdGUuYnVmZmVyLmNsZWFyKCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcmVhZCBwYXJ0IG9mIGxpc3RcbiAgICByZXQgPSBmcm9tTGlzdFBhcnRpYWwobiwgc3RhdGUuYnVmZmVyLCBzdGF0ZS5kZWNvZGVyKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbi8vIEV4dHJhY3RzIG9ubHkgZW5vdWdoIGJ1ZmZlcmVkIGRhdGEgdG8gc2F0aXNmeSB0aGUgYW1vdW50IHJlcXVlc3RlZC5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gZnJvbUxpc3RQYXJ0aWFsKG4sIGxpc3QsIGhhc1N0cmluZ3MpIHtcbiAgdmFyIHJldDtcbiAgaWYgKG4gPCBsaXN0LmhlYWQuZGF0YS5sZW5ndGgpIHtcbiAgICAvLyBzbGljZSBpcyB0aGUgc2FtZSBmb3IgYnVmZmVycyBhbmQgc3RyaW5nc1xuICAgIHJldCA9IGxpc3QuaGVhZC5kYXRhLnNsaWNlKDAsIG4pO1xuICAgIGxpc3QuaGVhZC5kYXRhID0gbGlzdC5oZWFkLmRhdGEuc2xpY2Uobik7XG4gIH0gZWxzZSBpZiAobiA9PT0gbGlzdC5oZWFkLmRhdGEubGVuZ3RoKSB7XG4gICAgLy8gZmlyc3QgY2h1bmsgaXMgYSBwZXJmZWN0IG1hdGNoXG4gICAgcmV0ID0gbGlzdC5zaGlmdCgpO1xuICB9IGVsc2Uge1xuICAgIC8vIHJlc3VsdCBzcGFucyBtb3JlIHRoYW4gb25lIGJ1ZmZlclxuICAgIHJldCA9IGhhc1N0cmluZ3MgPyBjb3B5RnJvbUJ1ZmZlclN0cmluZyhuLCBsaXN0KSA6IGNvcHlGcm9tQnVmZmVyKG4sIGxpc3QpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbi8vIENvcGllcyBhIHNwZWNpZmllZCBhbW91bnQgb2YgY2hhcmFjdGVycyBmcm9tIHRoZSBsaXN0IG9mIGJ1ZmZlcmVkIGRhdGFcbi8vIGNodW5rcy5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gY29weUZyb21CdWZmZXJTdHJpbmcobiwgbGlzdCkge1xuICB2YXIgcCA9IGxpc3QuaGVhZDtcbiAgdmFyIGMgPSAxO1xuICB2YXIgcmV0ID0gcC5kYXRhO1xuICBuIC09IHJldC5sZW5ndGg7XG4gIHdoaWxlIChwID0gcC5uZXh0KSB7XG4gICAgdmFyIHN0ciA9IHAuZGF0YTtcbiAgICB2YXIgbmIgPSBuID4gc3RyLmxlbmd0aCA/IHN0ci5sZW5ndGggOiBuO1xuICAgIGlmIChuYiA9PT0gc3RyLmxlbmd0aCkgcmV0ICs9IHN0cjtlbHNlIHJldCArPSBzdHIuc2xpY2UoMCwgbik7XG4gICAgbiAtPSBuYjtcbiAgICBpZiAobiA9PT0gMCkge1xuICAgICAgaWYgKG5iID09PSBzdHIubGVuZ3RoKSB7XG4gICAgICAgICsrYztcbiAgICAgICAgaWYgKHAubmV4dCkgbGlzdC5oZWFkID0gcC5uZXh0O2Vsc2UgbGlzdC5oZWFkID0gbGlzdC50YWlsID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpc3QuaGVhZCA9IHA7XG4gICAgICAgIHAuZGF0YSA9IHN0ci5zbGljZShuYik7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgKytjO1xuICB9XG4gIGxpc3QubGVuZ3RoIC09IGM7XG4gIHJldHVybiByZXQ7XG59XG5cbi8vIENvcGllcyBhIHNwZWNpZmllZCBhbW91bnQgb2YgYnl0ZXMgZnJvbSB0aGUgbGlzdCBvZiBidWZmZXJlZCBkYXRhIGNodW5rcy5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gY29weUZyb21CdWZmZXIobiwgbGlzdCkge1xuICB2YXIgcmV0ID0gYnVmZmVyU2hpbS5hbGxvY1Vuc2FmZShuKTtcbiAgdmFyIHAgPSBsaXN0LmhlYWQ7XG4gIHZhciBjID0gMTtcbiAgcC5kYXRhLmNvcHkocmV0KTtcbiAgbiAtPSBwLmRhdGEubGVuZ3RoO1xuICB3aGlsZSAocCA9IHAubmV4dCkge1xuICAgIHZhciBidWYgPSBwLmRhdGE7XG4gICAgdmFyIG5iID0gbiA+IGJ1Zi5sZW5ndGggPyBidWYubGVuZ3RoIDogbjtcbiAgICBidWYuY29weShyZXQsIHJldC5sZW5ndGggLSBuLCAwLCBuYik7XG4gICAgbiAtPSBuYjtcbiAgICBpZiAobiA9PT0gMCkge1xuICAgICAgaWYgKG5iID09PSBidWYubGVuZ3RoKSB7XG4gICAgICAgICsrYztcbiAgICAgICAgaWYgKHAubmV4dCkgbGlzdC5oZWFkID0gcC5uZXh0O2Vsc2UgbGlzdC5oZWFkID0gbGlzdC50YWlsID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpc3QuaGVhZCA9IHA7XG4gICAgICAgIHAuZGF0YSA9IGJ1Zi5zbGljZShuYik7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgKytjO1xuICB9XG4gIGxpc3QubGVuZ3RoIC09IGM7XG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGVuZFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG5cbiAgLy8gSWYgd2UgZ2V0IGhlcmUgYmVmb3JlIGNvbnN1bWluZyBhbGwgdGhlIGJ5dGVzLCB0aGVuIHRoYXQgaXMgYVxuICAvLyBidWcgaW4gbm9kZS4gIFNob3VsZCBuZXZlciBoYXBwZW4uXG4gIGlmIChzdGF0ZS5sZW5ndGggPiAwKSB0aHJvdyBuZXcgRXJyb3IoJ1wiZW5kUmVhZGFibGUoKVwiIGNhbGxlZCBvbiBub24tZW1wdHkgc3RyZWFtJyk7XG5cbiAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkKSB7XG4gICAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuICAgIHByb2Nlc3NOZXh0VGljayhlbmRSZWFkYWJsZU5ULCBzdGF0ZSwgc3RyZWFtKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbmRSZWFkYWJsZU5UKHN0YXRlLCBzdHJlYW0pIHtcbiAgLy8gQ2hlY2sgdGhhdCB3ZSBkaWRuJ3QgZ2V0IG9uZSBsYXN0IHVuc2hpZnQuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCAmJiBzdGF0ZS5sZW5ndGggPT09IDApIHtcbiAgICBzdGF0ZS5lbmRFbWl0dGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0ucmVhZGFibGUgPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZW5kJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZm9yRWFjaCh4cywgZikge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGYoeHNbaV0sIGkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBpZiAoeHNbaV0gPT09IHgpIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzXG4vLyBtb2R1bGUgaWQgPSA3MlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBhIHRyYW5zZm9ybSBzdHJlYW0gaXMgYSByZWFkYWJsZS93cml0YWJsZSBzdHJlYW0gd2hlcmUgeW91IGRvXG4vLyBzb21ldGhpbmcgd2l0aCB0aGUgZGF0YS4gIFNvbWV0aW1lcyBpdCdzIGNhbGxlZCBhIFwiZmlsdGVyXCIsXG4vLyBidXQgdGhhdCdzIG5vdCBhIGdyZWF0IG5hbWUgZm9yIGl0LCBzaW5jZSB0aGF0IGltcGxpZXMgYSB0aGluZyB3aGVyZVxuLy8gc29tZSBiaXRzIHBhc3MgdGhyb3VnaCwgYW5kIG90aGVycyBhcmUgc2ltcGx5IGlnbm9yZWQuICAoVGhhdCB3b3VsZFxuLy8gYmUgYSB2YWxpZCBleGFtcGxlIG9mIGEgdHJhbnNmb3JtLCBvZiBjb3Vyc2UuKVxuLy9cbi8vIFdoaWxlIHRoZSBvdXRwdXQgaXMgY2F1c2FsbHkgcmVsYXRlZCB0byB0aGUgaW5wdXQsIGl0J3Mgbm90IGFcbi8vIG5lY2Vzc2FyaWx5IHN5bW1ldHJpYyBvciBzeW5jaHJvbm91cyB0cmFuc2Zvcm1hdGlvbi4gIEZvciBleGFtcGxlLFxuLy8gYSB6bGliIHN0cmVhbSBtaWdodCB0YWtlIG11bHRpcGxlIHBsYWluLXRleHQgd3JpdGVzKCksIGFuZCB0aGVuXG4vLyBlbWl0IGEgc2luZ2xlIGNvbXByZXNzZWQgY2h1bmsgc29tZSB0aW1lIGluIHRoZSBmdXR1cmUuXG4vL1xuLy8gSGVyZSdzIGhvdyB0aGlzIHdvcmtzOlxuLy9cbi8vIFRoZSBUcmFuc2Zvcm0gc3RyZWFtIGhhcyBhbGwgdGhlIGFzcGVjdHMgb2YgdGhlIHJlYWRhYmxlIGFuZCB3cml0YWJsZVxuLy8gc3RyZWFtIGNsYXNzZXMuICBXaGVuIHlvdSB3cml0ZShjaHVuayksIHRoYXQgY2FsbHMgX3dyaXRlKGNodW5rLGNiKVxuLy8gaW50ZXJuYWxseSwgYW5kIHJldHVybnMgZmFsc2UgaWYgdGhlcmUncyBhIGxvdCBvZiBwZW5kaW5nIHdyaXRlc1xuLy8gYnVmZmVyZWQgdXAuICBXaGVuIHlvdSBjYWxsIHJlYWQoKSwgdGhhdCBjYWxscyBfcmVhZChuKSB1bnRpbFxuLy8gdGhlcmUncyBlbm91Z2ggcGVuZGluZyByZWFkYWJsZSBkYXRhIGJ1ZmZlcmVkIHVwLlxuLy9cbi8vIEluIGEgdHJhbnNmb3JtIHN0cmVhbSwgdGhlIHdyaXR0ZW4gZGF0YSBpcyBwbGFjZWQgaW4gYSBidWZmZXIuICBXaGVuXG4vLyBfcmVhZChuKSBpcyBjYWxsZWQsIGl0IHRyYW5zZm9ybXMgdGhlIHF1ZXVlZCB1cCBkYXRhLCBjYWxsaW5nIHRoZVxuLy8gYnVmZmVyZWQgX3dyaXRlIGNiJ3MgYXMgaXQgY29uc3VtZXMgY2h1bmtzLiAgSWYgY29uc3VtaW5nIGEgc2luZ2xlXG4vLyB3cml0dGVuIGNodW5rIHdvdWxkIHJlc3VsdCBpbiBtdWx0aXBsZSBvdXRwdXQgY2h1bmtzLCB0aGVuIHRoZSBmaXJzdFxuLy8gb3V0cHV0dGVkIGJpdCBjYWxscyB0aGUgcmVhZGNiLCBhbmQgc3Vic2VxdWVudCBjaHVua3MganVzdCBnbyBpbnRvXG4vLyB0aGUgcmVhZCBidWZmZXIsIGFuZCB3aWxsIGNhdXNlIGl0IHRvIGVtaXQgJ3JlYWRhYmxlJyBpZiBuZWNlc3NhcnkuXG4vL1xuLy8gVGhpcyB3YXksIGJhY2stcHJlc3N1cmUgaXMgYWN0dWFsbHkgZGV0ZXJtaW5lZCBieSB0aGUgcmVhZGluZyBzaWRlLFxuLy8gc2luY2UgX3JlYWQgaGFzIHRvIGJlIGNhbGxlZCB0byBzdGFydCBwcm9jZXNzaW5nIGEgbmV3IGNodW5rLiAgSG93ZXZlcixcbi8vIGEgcGF0aG9sb2dpY2FsIGluZmxhdGUgdHlwZSBvZiB0cmFuc2Zvcm0gY2FuIGNhdXNlIGV4Y2Vzc2l2ZSBidWZmZXJpbmdcbi8vIGhlcmUuICBGb3IgZXhhbXBsZSwgaW1hZ2luZSBhIHN0cmVhbSB3aGVyZSBldmVyeSBieXRlIG9mIGlucHV0IGlzXG4vLyBpbnRlcnByZXRlZCBhcyBhbiBpbnRlZ2VyIGZyb20gMC0yNTUsIGFuZCB0aGVuIHJlc3VsdHMgaW4gdGhhdCBtYW55XG4vLyBieXRlcyBvZiBvdXRwdXQuICBXcml0aW5nIHRoZSA0IGJ5dGVzIHtmZixmZixmZixmZn0gd291bGQgcmVzdWx0IGluXG4vLyAxa2Igb2YgZGF0YSBiZWluZyBvdXRwdXQuICBJbiB0aGlzIGNhc2UsIHlvdSBjb3VsZCB3cml0ZSBhIHZlcnkgc21hbGxcbi8vIGFtb3VudCBvZiBpbnB1dCwgYW5kIGVuZCB1cCB3aXRoIGEgdmVyeSBsYXJnZSBhbW91bnQgb2Ygb3V0cHV0LiAgSW5cbi8vIHN1Y2ggYSBwYXRob2xvZ2ljYWwgaW5mbGF0aW5nIG1lY2hhbmlzbSwgdGhlcmUnZCBiZSBubyB3YXkgdG8gdGVsbFxuLy8gdGhlIHN5c3RlbSB0byBzdG9wIGRvaW5nIHRoZSB0cmFuc2Zvcm0uICBBIHNpbmdsZSA0TUIgd3JpdGUgY291bGRcbi8vIGNhdXNlIHRoZSBzeXN0ZW0gdG8gcnVuIG91dCBvZiBtZW1vcnkuXG4vL1xuLy8gSG93ZXZlciwgZXZlbiBpbiBzdWNoIGEgcGF0aG9sb2dpY2FsIGNhc2UsIG9ubHkgYSBzaW5nbGUgd3JpdHRlbiBjaHVua1xuLy8gd291bGQgYmUgY29uc3VtZWQsIGFuZCB0aGVuIHRoZSByZXN0IHdvdWxkIHdhaXQgKHVuLXRyYW5zZm9ybWVkKSB1bnRpbFxuLy8gdGhlIHJlc3VsdHMgb2YgdGhlIHByZXZpb3VzIHRyYW5zZm9ybWVkIGNodW5rIHdlcmUgY29uc3VtZWQuXG5cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc2Zvcm07XG5cbnZhciBEdXBsZXggPSByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhUcmFuc2Zvcm0sIER1cGxleCk7XG5cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0YXRlKHN0cmVhbSkge1xuICB0aGlzLmFmdGVyVHJhbnNmb3JtID0gZnVuY3Rpb24gKGVyLCBkYXRhKSB7XG4gICAgcmV0dXJuIGFmdGVyVHJhbnNmb3JtKHN0cmVhbSwgZXIsIGRhdGEpO1xuICB9O1xuXG4gIHRoaXMubmVlZFRyYW5zZm9ybSA9IGZhbHNlO1xuICB0aGlzLnRyYW5zZm9ybWluZyA9IGZhbHNlO1xuICB0aGlzLndyaXRlY2IgPSBudWxsO1xuICB0aGlzLndyaXRlY2h1bmsgPSBudWxsO1xuICB0aGlzLndyaXRlZW5jb2RpbmcgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBhZnRlclRyYW5zZm9ybShzdHJlYW0sIGVyLCBkYXRhKSB7XG4gIHZhciB0cyA9IHN0cmVhbS5fdHJhbnNmb3JtU3RhdGU7XG4gIHRzLnRyYW5zZm9ybWluZyA9IGZhbHNlO1xuXG4gIHZhciBjYiA9IHRzLndyaXRlY2I7XG5cbiAgaWYgKCFjYikgcmV0dXJuIHN0cmVhbS5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignbm8gd3JpdGVjYiBpbiBUcmFuc2Zvcm0gY2xhc3MnKSk7XG5cbiAgdHMud3JpdGVjaHVuayA9IG51bGw7XG4gIHRzLndyaXRlY2IgPSBudWxsO1xuXG4gIGlmIChkYXRhICE9PSBudWxsICYmIGRhdGEgIT09IHVuZGVmaW5lZCkgc3RyZWFtLnB1c2goZGF0YSk7XG5cbiAgY2IoZXIpO1xuXG4gIHZhciBycyA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgcnMucmVhZGluZyA9IGZhbHNlO1xuICBpZiAocnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHtcbiAgICBzdHJlYW0uX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn1cblxuZnVuY3Rpb24gVHJhbnNmb3JtKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFRyYW5zZm9ybSkpIHJldHVybiBuZXcgVHJhbnNmb3JtKG9wdGlvbnMpO1xuXG4gIER1cGxleC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlID0gbmV3IFRyYW5zZm9ybVN0YXRlKHRoaXMpO1xuXG4gIHZhciBzdHJlYW0gPSB0aGlzO1xuXG4gIC8vIHN0YXJ0IG91dCBhc2tpbmcgZm9yIGEgcmVhZGFibGUgZXZlbnQgb25jZSBkYXRhIGlzIHRyYW5zZm9ybWVkLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG5cbiAgLy8gd2UgaGF2ZSBpbXBsZW1lbnRlZCB0aGUgX3JlYWQgbWV0aG9kLCBhbmQgZG9uZSB0aGUgb3RoZXIgdGhpbmdzXG4gIC8vIHRoYXQgUmVhZGFibGUgd2FudHMgYmVmb3JlIHRoZSBmaXJzdCBfcmVhZCBjYWxsLCBzbyB1bnNldCB0aGVcbiAgLy8gc3luYyBndWFyZCBmbGFnLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLnN5bmMgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy50cmFuc2Zvcm0gPT09ICdmdW5jdGlvbicpIHRoaXMuX3RyYW5zZm9ybSA9IG9wdGlvbnMudHJhbnNmb3JtO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmZsdXNoID09PSAnZnVuY3Rpb24nKSB0aGlzLl9mbHVzaCA9IG9wdGlvbnMuZmx1c2g7XG4gIH1cblxuICAvLyBXaGVuIHRoZSB3cml0YWJsZSBzaWRlIGZpbmlzaGVzLCB0aGVuIGZsdXNoIG91dCBhbnl0aGluZyByZW1haW5pbmcuXG4gIHRoaXMub25jZSgncHJlZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fZmx1c2ggPT09ICdmdW5jdGlvbicpIHRoaXMuX2ZsdXNoKGZ1bmN0aW9uIChlciwgZGF0YSkge1xuICAgICAgZG9uZShzdHJlYW0sIGVyLCBkYXRhKTtcbiAgICB9KTtlbHNlIGRvbmUoc3RyZWFtKTtcbiAgfSk7XG59XG5cblRyYW5zZm9ybS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcpIHtcbiAgdGhpcy5fdHJhbnNmb3JtU3RhdGUubmVlZFRyYW5zZm9ybSA9IGZhbHNlO1xuICByZXR1cm4gRHVwbGV4LnByb3RvdHlwZS5wdXNoLmNhbGwodGhpcywgY2h1bmssIGVuY29kaW5nKTtcbn07XG5cbi8vIFRoaXMgaXMgdGhlIHBhcnQgd2hlcmUgeW91IGRvIHN0dWZmIVxuLy8gb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiBpbiBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLlxuLy8gJ2NodW5rJyBpcyBhbiBpbnB1dCBjaHVuay5cbi8vXG4vLyBDYWxsIGBwdXNoKG5ld0NodW5rKWAgdG8gcGFzcyBhbG9uZyB0cmFuc2Zvcm1lZCBvdXRwdXRcbi8vIHRvIHRoZSByZWFkYWJsZSBzaWRlLiAgWW91IG1heSBjYWxsICdwdXNoJyB6ZXJvIG9yIG1vcmUgdGltZXMuXG4vL1xuLy8gQ2FsbCBgY2IoZXJyKWAgd2hlbiB5b3UgYXJlIGRvbmUgd2l0aCB0aGlzIGNodW5rLiAgSWYgeW91IHBhc3Ncbi8vIGFuIGVycm9yLCB0aGVuIHRoYXQnbGwgcHV0IHRoZSBodXJ0IG9uIHRoZSB3aG9sZSBvcGVyYXRpb24uICBJZiB5b3Vcbi8vIG5ldmVyIGNhbGwgY2IoKSwgdGhlbiB5b3UnbGwgbmV2ZXIgZ2V0IGFub3RoZXIgY2h1bmsuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aHJvdyBuZXcgRXJyb3IoJ190cmFuc2Zvcm0oKSBpcyBub3QgaW1wbGVtZW50ZWQnKTtcbn07XG5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGU7XG4gIHRzLndyaXRlY2IgPSBjYjtcbiAgdHMud3JpdGVjaHVuayA9IGNodW5rO1xuICB0cy53cml0ZWVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIGlmICghdHMudHJhbnNmb3JtaW5nKSB7XG4gICAgdmFyIHJzID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgICBpZiAodHMubmVlZFRyYW5zZm9ybSB8fCBycy5uZWVkUmVhZGFibGUgfHwgcnMubGVuZ3RoIDwgcnMuaGlnaFdhdGVyTWFyaykgdGhpcy5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKTtcbiAgfVxufTtcblxuLy8gRG9lc24ndCBtYXR0ZXIgd2hhdCB0aGUgYXJncyBhcmUgaGVyZS5cbi8vIF90cmFuc2Zvcm0gZG9lcyBhbGwgdGhlIHdvcmsuXG4vLyBUaGF0IHdlIGdvdCBoZXJlIG1lYW5zIHRoYXQgdGhlIHJlYWRhYmxlIHNpZGUgd2FudHMgbW9yZSBkYXRhLlxuVHJhbnNmb3JtLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuXG4gIGlmICh0cy53cml0ZWNodW5rICE9PSBudWxsICYmIHRzLndyaXRlY2IgJiYgIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHRzLnRyYW5zZm9ybWluZyA9IHRydWU7XG4gICAgdGhpcy5fdHJhbnNmb3JtKHRzLndyaXRlY2h1bmssIHRzLndyaXRlZW5jb2RpbmcsIHRzLmFmdGVyVHJhbnNmb3JtKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBtYXJrIHRoYXQgd2UgbmVlZCBhIHRyYW5zZm9ybSwgc28gdGhhdCBhbnkgZGF0YSB0aGF0IGNvbWVzIGluXG4gICAgLy8gd2lsbCBnZXQgcHJvY2Vzc2VkLCBub3cgdGhhdCB3ZSd2ZSBhc2tlZCBmb3IgaXQuXG4gICAgdHMubmVlZFRyYW5zZm9ybSA9IHRydWU7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGRvbmUoc3RyZWFtLCBlciwgZGF0YSkge1xuICBpZiAoZXIpIHJldHVybiBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG5cbiAgaWYgKGRhdGEgIT09IG51bGwgJiYgZGF0YSAhPT0gdW5kZWZpbmVkKSBzdHJlYW0ucHVzaChkYXRhKTtcblxuICAvLyBpZiB0aGVyZSdzIG5vdGhpbmcgaW4gdGhlIHdyaXRlIGJ1ZmZlciwgdGhlbiB0aGF0IG1lYW5zXG4gIC8vIHRoYXQgbm90aGluZyBtb3JlIHdpbGwgZXZlciBiZSBwcm92aWRlZFxuICB2YXIgd3MgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciB0cyA9IHN0cmVhbS5fdHJhbnNmb3JtU3RhdGU7XG5cbiAgaWYgKHdzLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdDYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gd3MubGVuZ3RoICE9IDAnKTtcblxuICBpZiAodHMudHJhbnNmb3JtaW5nKSB0aHJvdyBuZXcgRXJyb3IoJ0NhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiBzdGlsbCB0cmFuc2Zvcm1pbmcnKTtcblxuICByZXR1cm4gc3RyZWFtLnB1c2gobnVsbCk7XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanNcbi8vIG1vZHVsZSBpZCA9IDczXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0tYnJvd3Nlci5qc1xuLy8gbW9kdWxlIGlkID0gNzRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGFwcGx5ID0gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5O1xuXG4vLyBET00gQVBJcywgZm9yIGNvbXBsZXRlbmVzc1xuXG5leHBvcnRzLnNldFRpbWVvdXQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIG5ldyBUaW1lb3V0KGFwcGx5LmNhbGwoc2V0VGltZW91dCwgd2luZG93LCBhcmd1bWVudHMpLCBjbGVhclRpbWVvdXQpO1xufTtcbmV4cG9ydHMuc2V0SW50ZXJ2YWwgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIG5ldyBUaW1lb3V0KGFwcGx5LmNhbGwoc2V0SW50ZXJ2YWwsIHdpbmRvdywgYXJndW1lbnRzKSwgY2xlYXJJbnRlcnZhbCk7XG59O1xuZXhwb3J0cy5jbGVhclRpbWVvdXQgPVxuZXhwb3J0cy5jbGVhckludGVydmFsID0gZnVuY3Rpb24odGltZW91dCkge1xuICBpZiAodGltZW91dCkge1xuICAgIHRpbWVvdXQuY2xvc2UoKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gVGltZW91dChpZCwgY2xlYXJGbikge1xuICB0aGlzLl9pZCA9IGlkO1xuICB0aGlzLl9jbGVhckZuID0gY2xlYXJGbjtcbn1cblRpbWVvdXQucHJvdG90eXBlLnVucmVmID0gVGltZW91dC5wcm90b3R5cGUucmVmID0gZnVuY3Rpb24oKSB7fTtcblRpbWVvdXQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX2NsZWFyRm4uY2FsbCh3aW5kb3csIHRoaXMuX2lkKTtcbn07XG5cbi8vIERvZXMgbm90IHN0YXJ0IHRoZSB0aW1lLCBqdXN0IHNldHMgdXAgdGhlIG1lbWJlcnMgbmVlZGVkLlxuZXhwb3J0cy5lbnJvbGwgPSBmdW5jdGlvbihpdGVtLCBtc2Vjcykge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gbXNlY3M7XG59O1xuXG5leHBvcnRzLnVuZW5yb2xsID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gLTE7XG59O1xuXG5leHBvcnRzLl91bnJlZkFjdGl2ZSA9IGV4cG9ydHMuYWN0aXZlID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG5cbiAgdmFyIG1zZWNzID0gaXRlbS5faWRsZVRpbWVvdXQ7XG4gIGlmIChtc2VjcyA+PSAwKSB7XG4gICAgaXRlbS5faWRsZVRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gb25UaW1lb3V0KCkge1xuICAgICAgaWYgKGl0ZW0uX29uVGltZW91dClcbiAgICAgICAgaXRlbS5fb25UaW1lb3V0KCk7XG4gICAgfSwgbXNlY3MpO1xuICB9XG59O1xuXG4vLyBzZXRpbW1lZGlhdGUgYXR0YWNoZXMgaXRzZWxmIHRvIHRoZSBnbG9iYWwgb2JqZWN0XG5yZXF1aXJlKFwic2V0aW1tZWRpYXRlXCIpO1xuZXhwb3J0cy5zZXRJbW1lZGlhdGUgPSBzZXRJbW1lZGlhdGU7XG5leHBvcnRzLmNsZWFySW1tZWRpYXRlID0gY2xlYXJJbW1lZGlhdGU7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vdGltZXJzLWJyb3dzZXJpZnkvbWFpbi5qc1xuLy8gbW9kdWxlIGlkID0gNzVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgZmlsZXMgPSBbXG4gIC8vIFwiZ3VuX3Zpb2xlbmNlXCIsXG4gIFwibWFzc19zaG9vdGluZ3NfbGl0ZVwiLFxuICBcImd1bl92aW9sZW5jZV9ieV9tb250aFwiLFxuXVxuY29uc3QgcGFyc2UgPSByZXF1aXJlKCdjc3YtcGFyc2UnKVxuXG5jb25zdCBkYXRhUHJvbWlzZXMgPSBmaWxlcy5tYXAobmFtZSA9PiB7XG4gIHJldHVybiBmZXRjaCgnLi9kYXRhLycgKyBuYW1lICsgJy5jc3YnKS50aGVuKHJvd3MgPT4ge1xuICAgIHJldHVybiByb3dzLnRleHQoKVxuICB9KS50aGVuKHRleHQgPT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBwYXJzZSh0ZXh0LCB7fSwgKF8sIGxpbmVzKSA9PiByZXNvbHZlKGxpbmVzKSlcbiAgICB9KVxuICB9KS50aGVuKGxpbmVzID0+IHtcbiAgICAvLyBjb25zb2xlLmxvZyhuYW1lLCBsaW5lcylcbiAgICBjb25zdCBoID0gbGluZXMuc2hpZnQoKVxuICAgIHJldHVybiB7XG4gICAgICBuYW1lLFxuICAgICAgaCxcbiAgICAgIGxpbmVzOiBsaW5lcy5maWx0ZXIocyA9PiAhIXMpXG4gICAgfVxuICB9KVxufSlcbmNvbnN0IGFsbFByb21pc2VzID0gUHJvbWlzZS5hbGwoZGF0YVByb21pc2VzKS50aGVuKGRhdGEgPT4ge1xuICByZXR1cm4gZGF0YS5yZWR1Y2UoKGEsYikgPT4ge1xuICAgIC8vIGNvbnNvbGUubG9nKGIpXG4gICAgYVtiLm5hbWVdID0gYlxuICAgIHJldHVybiBhXG4gIH0sIHt9KVxufSlcbmNvbnN0IGxvYWQgPSAoKSA9PiB7XG4gIHJldHVybiBhbGxQcm9taXNlc1xufVxuXG5leHBvcnQgeyBsb2FkIH1cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvZGF0YS5qcyIsImNvbnN0IGtleXMgPSB7fVxuY29uc3Qga2V5X251bWJlcnMgPSB7fVxuY29uc3QgbGV0dGVycyA9IFwienhjdmJubWFzZGZnaGprbHF3ZXJ0eXVpb3BcIlxuY29uc3QgbnVtYmVycyA9IFwiMTIzNDU2Nzg5MFwiXG5cbmxldCBjYWxsYmFjayA9IGZ1bmN0aW9uKCl7fVxuXG5sZXR0ZXJzLnRvVXBwZXJDYXNlKCkuc3BsaXQoXCJcIikubWFwKGZ1bmN0aW9uKGssaSl7XG4gIGtleXNbay5jaGFyQ29kZUF0KDApXSA9IGlcbn0pXG5cbm51bWJlcnMuc3BsaXQoXCJcIikubWFwKGZ1bmN0aW9uKGssaSl7XG4gIGtleXNbay5jaGFyQ29kZUF0KDApXSA9IGkrbGV0dGVycy5sZW5ndGhcbiAga2V5X251bWJlcnNbay5jaGFyQ29kZUF0KDApXSA9IHRydWVcbn0pXG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLCBrZXlkb3duLCB0cnVlKVxuZnVuY3Rpb24ga2V5ZG93biAoZSkge1xuICBpZiAoZS5hbHRLZXkgfHwgZS5jdHJsS2V5IHx8IGUubWV0YUtleSkge1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQgJiZcbiAgICAgIChlLmtleUNvZGUgaW4ga2V5X251bWJlcnMpKSB7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuICAgIHJldHVyblxuICB9XG4gIGlmICghIChlLmtleUNvZGUgaW4ga2V5cykpIHJldHVyblxuICB2YXIgaW5kZXggPSBrZXlzW2Uua2V5Q29kZV1cbiAgaWYgKGUuc2hpZnRLZXkpIGluZGV4ICs9IGxldHRlcnMubGVuZ3RoXG4gIGluZGV4IC09IDdcbiAgY2FsbGJhY2soaW5kZXgpXG59XG5cbmZ1bmN0aW9uIGxpc3RlbiAoZm4pIHtcbiAgY2FsbGJhY2sgPSBmblxufVxuXG5leHBvcnQgZGVmYXVsdCB7IGxpc3RlbiB9XG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2xpYi9rZXlzLmpzIiwiaW1wb3J0IFRvbmUgZnJvbSAndG9uZSdcbmltcG9ydCBXZWJNaWRpIGZyb20gJ3dlYm1pZGknXG5pbXBvcnQgc2NhbGVzIGZyb20gJy4vc2NhbGVzJ1xuaW1wb3J0IHsgZnRvbSwgbm9ybSwgZGF0YVVSSXRvQmxvYiB9IGZyb20gJy4vdXRpbCdcbmltcG9ydCBrYWxpbWJhIGZyb20gJy4va2FsaW1iYSdcbmltcG9ydCB7IHNhdmVBcyB9IGZyb20gJ2ZpbGUtc2F2ZXIvRmlsZVNhdmVyJ1xuXG5pbXBvcnQgeyBueCB9IGZyb20gJy4vdWknXG5cbmxldCBtaWRpRGV2aWNlXG5sZXQgc2VuZFBpdGNoQmVuZCA9IGZhbHNlXG5cbmV4cG9ydCBjb25zdCBNaWRpV3JpdGVyID0gcmVxdWlyZSgnbWlkaS13cml0ZXItanMnKVxuXG5leHBvcnQgY29uc3Qgbm90ZV92YWx1ZXMgPSBbXG4gIFs4LCAnOCBtZWFzdXJlcycsIDggKiA1MTJdLFxuICBbNCwgJzQgbWVhc3VyZXMnLCA0ICogNTEyXSxcbiAgWzIsICcyIG1lYXN1cmVzJywgMiAqIDUxMl0sXG4gIFsxLCAnd2hvbGUgbm90ZScsIDUxMl0sXG4gIFsxLzIsICdoYWxmIG5vdGUnLCAyNTZdLFxuICBbMS8zLCAndGhpcmQgbm90ZScsIFsxNzAsIDE3MCwgMTcxXV0sXG4gIFsxLzQsICdxdWFydGVyIG5vdGUnLCAxMjhdLFxuICBbMS81LCAnZmlmdGggbm90ZScsIFs1MSw1MSw1MSw1MSw1Ml1dLFxuICBbMS82LCAnc2l4dGggbm90ZScsIFs4NSwgODUsIDg2LCA4NSwgODUsIDg2XV0sXG4gIFsxLzgsICdlaWdodGggbm90ZScsIDY0XSxcbiAgWzEvMTAsICd0ZW50aCBub3RlJywgWzI1LDI2LDI2LDI1LDI2LDI1LDI2LDI2LDI1LDI2XV0sXG4gIFsxLzEyLCAndHdlbGZ0aCBub3RlJywgWzIxLDIxLDIyLCAyMSwyMSwyMiwgMjEsMjEsMjIsIDIxLDIxLDIyXV0sXG4gIFsxLzE2LCAnc2l4dGVlbnRoIG5vdGUnLCAzMl0sXG4gIFsxLzMyLCAndGhpcnR5c2Vjb25kIG5vdGUnLCAxNl0sXG5dXG5cbmV4cG9ydCBmdW5jdGlvbiBtaWRpX2luaXQoKSB7XG4gIFdlYk1pZGkuZW5hYmxlKG1pZGlfcmVhZHkpXG4gIGZ1bmN0aW9uIG1pZGlfcmVhZHkoZXJyKSB7XG4gICAgaWYgKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcignd2VibWlkaSBmYWlsZWQgdG8gaW5pdGlhbGl6ZScpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKCFXZWJNaWRpLm91dHB1dHMubGVuZ3RoKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdubyBNSURJIG91dHB1dCBmb3VuZCcpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgY29uc29sZS5sb2coV2ViTWlkaS5pbnB1dHMpXG4gICAgY29uc29sZS5sb2coV2ViTWlkaS5vdXRwdXRzKVxuICAgIGlmIChXZWJNaWRpLm91dHB1dHMubGVuZ3RoID4gMSkge1xuICAgICAgY29uc3QgZmlsdGVyZWQgPSBXZWJNaWRpLm91dHB1dHMuZmlsdGVyKG91dHB1dCA9PiBvdXRwdXQubmFtZS5tYXRjaCgvcHJvZGlwZS9pKSlcbiAgICAgIGlmIChmaWx0ZXJlZC5sZW5ndGgpIHtcbiAgICAgICAgLy8gbWlkaURldmljZSA9IGZpbHRlcmVkWzBdXG4gICAgICB9XG4gICAgfVxuICAgIC8vIG1pZGlEZXZpY2UgPSBtaWRpRGV2aWNlIHx8IFdlYk1pZGkub3V0cHV0c1swXVxuICAgIC8vIGNvbnNvbGUubG9nKG1pZGlEZXZpY2UubmFtZSlcbiAgfVxufVxuXG4vKiBwbGF5IGEgc2luZ2xlIG5vdGUgKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHBsYXlfbm90ZShpbmRleCwgZHVyYXRpb24sIGNoYW5uZWw9XCJhbGxcIiwgZXhwb3J0aW5nPWZhbHNlLCByZXN0PTAsIGRlZmVyPTApe1xuICAvLyBjb25zb2xlLmxvZyhpbmRleClcbiAgY29uc3Qgc2NhbGUgPSBzY2FsZXMuY3VycmVudCgpXG4gIGNvbnN0IGZyZXEgPSBzY2FsZS5pbmRleChpbmRleCArIE1hdGgucm91bmQobngub2Zmc2V0LnZhbHVlKSwgbngub2N0YXZlLnZhbHVlKVxuICBsZXQgbWlkaV9ub3RlID0gZnRvbShmcmVxKVxuICBsZXQgY2VudHMgPSBtaWRpX25vdGUgJSAxXG4gIGlmIChjZW50cyA+IDAuNSkge1xuICAgIG1pZGlfbm90ZSArPSAxXG4gICAgY2VudHMgLT0gMVxuICB9XG4gIGNlbnRzICo9IDJcbiAgbWlkaV9ub3RlID0gTWF0aC5mbG9vcihtaWRpX25vdGUpXG4gIGlmICgobWlkaURldmljZSB8fCBleHBvcnRpbmcpICYmIG1pZGlfbm90ZSA+IDEyNykgcmV0dXJuIDBcbiAgY29uc3Qgbm90ZSA9IFRvbmUuRnJlcXVlbmN5KE1hdGguZmxvb3IobWlkaV9ub3RlKSwgXCJtaWRpXCIpLnRvTm90ZSgpXG4gIGNvbnN0IGRlZmVyX3RpbWUgPSAzMDAwMCAvIFRvbmUuVHJhbnNwb3J0LmJwbS52YWx1ZSAqIGRlZmVyIC8gMTI4XG4gIGNvbnNvbGUubG9nKGRlZmVyLCBkZWZlcl90aW1lKVxuICBpZiAoZXhwb3J0aW5nKSB7XG4gICAgcmV0dXJuIG5vdGVcbiAgfVxuICBpZiAobWlkaURldmljZSkge1xuICAgIGR1cmF0aW9uID0gZHVyYXRpb24gfHwgNjAwMDAgLyBUb25lLlRyYW5zcG9ydC5icG0udmFsdWVcbiAgICBpZiAoISBleHBvcnRpbmcpIHtcbiAgICAgIGlmIChkZWZlcikge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBwbGF5X21pZGlfbm90ZShub3RlLCBjZW50cywgY2hhbm5lbCwgZHVyYXRpb24pXG4gICAgICAgIH0sIGRlZmVyKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGxheV9taWRpX25vdGUobm90ZSwgY2VudHMsIGNoYW5uZWwsIGR1cmF0aW9uKVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIGlmIChkZWZlcikge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAga2FsaW1iYS5wbGF5KGZyZXEpXG4gICAgfSwgZGVmZXJfdGltZSlcbiAgfSBlbHNlIHtcbiAgICBrYWxpbWJhLnBsYXkoZnJlcSlcbiAgfVxuICByZXR1cm4gbm90ZVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcGxheV9taWRpX25vdGUobm90ZSwgY2VudHMsIGNoYW5uZWwsIGR1cmF0aW9uKSB7XG4gIG1pZGlEZXZpY2UucGxheU5vdGUobm90ZSwgY2hhbm5lbCwgeyBkdXJhdGlvbiB9KVxuICBpZiAoc2VuZFBpdGNoQmVuZCkge1xuICAgIG1pZGlEZXZpY2Uuc2VuZFBpdGNoQmVuZChjZW50cywgY2hhbm5lbClcbiAgfVxufVxuXG4vKiBwbGF5IHRoZSBuZXh0IG5vdGUgaW4gc2VxdWVuY2UgKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHBsYXlfc2VxdWVuY2UoaSwgYm91bmRzLCBkaWZmLCBub3RlX3RpbWUsIGNoYW5uZWw9XCJhbGxcIiwgZXhwb3J0aW5nKSB7XG4gIGNvbnN0IHsgcm93cywgbWluLCBtYXggfSA9IGJvdW5kc1xuICBjb25zdCBjb3VudCA9IHJvd3MubGVuZ3RoICogcm93c1swXS5sZW5ndGhcbiAgaWYgKGkgPj0gY291bnQpIGkgPSAwXG4gIGNvbnN0IHkgPSBNYXRoLmZsb29yKGkgLyByb3dzWzBdLmxlbmd0aClcbiAgY29uc3QgeCA9IGkgJSByb3dzWzBdLmxlbmd0aFxuICAvLyBpZiAoIXgpIGNvbnNvbGUubG9nKHkpXG4gIGNvbnN0IG4gPSByb3dzW3ldW3hdXG4gIGkgKz0gMVxuICBpZiAoaSA+PSBjb3VudCkgaSA9IDBcbiAgY29uc3QgbWlkaV9ub3RlID0gcGxheV9ub3RlKCBub3JtKG4sIG1pbiwgbWF4KSAqIG54Lm11bHRpcGx5LnZhbHVlLCBub3RlX3RpbWUsIGNoYW5uZWwsIGV4cG9ydGluZylcbiAgcmV0dXJuIFtpLCBbbWlkaV9ub3RlXV1cbn1cblxuLyogcGxheSB0aGUgbmV4dCByb3cgYXMgYW4gaW50ZXJ2YWwgKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHBsYXlfaW50ZXJ2YWxfc2VxdWVuY2UoaSwgYm91bmRzLCBkaWZmLCBub3RlX3RpbWUsIGNoYW5uZWw9XCJhbGxcIiwgZXhwb3J0aW5nKSB7XG4gIGNvbnN0IHsgcm93cywgbWluLCBtYXggfSA9IGJvdW5kc1xuICBjb25zdCBjb3VudCA9IHJvd3MubGVuZ3RoXG4gIGlmIChpID49IGNvdW50KSBpID0gMFxuICBjb25zdCB5ID0gaSAlIGNvdW50XG4gIGNvbnN0IHJvdyA9IHJvd3NbeV1cbiAgaWYgKCEgcm93KSB7IGkgPSAwOyByZXR1cm4gfVxuICBjb25zdCByb3dfbWluID0gTWF0aC5taW4uYXBwbHkoTWF0aCwgcm93KVxuICAvLyBjb25zdCByb3dfbWF4ID0gTWF0aC5tYXguYXBwbHkoTWF0aCwgcm93KVxuICBjb25zdCByb3dfZjAgPSBub3JtKHJvd19taW4sIG1pbiwgbWF4KVxuICBjb25zdCByb3dfcm9vdCA9IHJvd19mMCAqIG54Lm11bHRpcGx5LnZhbHVlXG4gIGNvbnN0IG5vdGVzID0gcm93Lm1hcChuID0+IHtcbiAgICBjb25zdCBub3RlID0gcm93X3Jvb3QgKyBub3JtKG4gLSByb3dfbWluLCBkaWZmLm1pbiwgZGlmZi5tYXgpICogbnguaW50ZXJ2YWwudmFsdWVcbiAgICBwbGF5X25vdGUobm90ZSwgbm90ZV90aW1lLCBjaGFubmVsLCBleHBvcnRpbmcpXG4gIH0pXG4gIGkgKz0gMVxuICByZXR1cm4gW2ksIG5vdGVzXVxufVxuXG4vKiBnZW5lcmF0ZSBhIDEtdHJhY2sgbWlkaSBmaWxlIGJ5IGNhbGxpbmcgdGhlIHBsYXkgZnVuY3Rpb24gcmVwZWF0ZWRseSAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXhwb3J0X3BhdHRlcm5fYXNfbWlkaShkYXRhc2V0TmFtZSwgYm91bmRzLCBkaWZmLCB0ZW1wbywgdGltaW5nSW5kZXgsIHBsYXlfZm4pIHtcbiAgLy8gY29uc3QgYmVoYXZpb3IgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmVoYXZpb3InKS52YWx1ZVxuICBjb25zdCB7IHJvd3MgfSA9IGJvdW5kc1xuICAvLyBsZXQgY291bnQgPSBiZWhhdmlvciA9PT0gJ3NlcXVlbmNlJyA/IHJvd3NbMF0ubGVuZ3RoICogcm93cy5sZW5ndGggOiByb3dzLmxlbmd0aFxuICBsZXQgY291bnQgPSByb3dzWzBdLmxlbmd0aFxuICBsZXQgbm90ZXMsIHRpbWluZ3MsIHdhaXRcbiAgbGV0IG5vdGVfdGltZVxuICAvLyBsZXQgdGltaW5nID0gbm90ZV92YWx1ZXNbdGltaW5nSW5kZXhdWzJdXG4gIGxldCBtaWRpX3RyYWNrID0gbmV3IE1pZGlXcml0ZXIuVHJhY2soKVxuICBtaWRpX3RyYWNrLnNldFRlbXBvKHRlbXBvKVxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gY291bnQ7IGkgPCBsZW47IGkrKykge1xuICAgIFtpLCBub3RlcywgdGltaW5ncywgd2FpdF0gPSBwbGF5X2ZuKGksIGJvdW5kcywgbm90ZV90aW1lLCBcImFsbFwiLCB0cnVlKVxuICAgIC8vIGlmICh0aW1pbmcubGVuZ3RoKSB7XG4gICAgLy8gICBub3RlX3RpbWUgPSB0aW1pbmdbaSAlIHRpbWluZy5sZW5ndGhdXG4gICAgLy8gfSBlbHNlIHtcbiAgICAvLyAgIG5vdGVfdGltZSA9IHRpbWluZ1xuICAgIC8vIH1cbiAgICAvLyBtaWRpX3RyYWNrLmFkZEV2ZW50KG5ldyBNaWRpV3JpdGVyLk5vdGVFdmVudCh7IHBpdGNoOiBub3RlcywgZHVyYXRpb246ICd0JyArIG5vdGVfdGltZSB9KSlcbiAgICBjb25zb2xlLmxvZyhpLCBub3RlcywgdGltaW5ncywgd2FpdClcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IG5vdGVzLmxlbmd0aDsgaisrKSB7XG4gICAgICBtaWRpX3RyYWNrLmFkZEV2ZW50KG5ldyBNaWRpV3JpdGVyLk5vdGVFdmVudCh7XG4gICAgICAgIHBpdGNoOiBub3Rlc1tqXSxcbiAgICAgICAgZHVyYXRpb246ICd0JyArIHRpbWluZ3Nbal0sXG4gICAgICAgIHdhaXQ6IChqID09PSAwKSA/IHdhaXQgOiAwLFxuICAgICAgfSkpXG4gICAgfVxuICB9XG4gIGNvbnN0IHdyaXRlciA9IG5ldyBNaWRpV3JpdGVyLldyaXRlcihbbWlkaV90cmFja10pXG4gIGNvbnN0IGJsb2IgPSBkYXRhVVJJdG9CbG9iKHdyaXRlci5kYXRhVXJpKCkpXG4gIHNhdmVBcyhibG9iLCAnUmVjb3JkaW5nIC0gJyArIGRhdGFzZXROYW1lICsgJy5taWQnKVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2xpYi9taWRpLmpzIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZnJvbSA9IHJlcXVpcmUoXCIuLi9jb3JlLWpzL2FycmF5L2Zyb21cIik7XG5cbnZhciBfZnJvbTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9mcm9tKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZXhwb3J0cy5kZWZhdWx0ID0gZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShhcnIpID8gYXJyIDogKDAsIF9mcm9tMi5kZWZhdWx0KShhcnIpO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vYmFiZWwtcnVudGltZS9oZWxwZXJzL3RvQXJyYXkuanNcbi8vIG1vZHVsZSBpZCA9IDc5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImltcG9ydCBUb25lIGZyb20gJ3RvbmUnXG5pbXBvcnQgTmV4dXMgZnJvbSAnbmV4dXN1aSdcblxuaW1wb3J0IGtleXMgZnJvbSAnLi9saWIva2V5cydcbmltcG9ydCBzY2FsZXMgZnJvbSAnLi9saWIvc2NhbGVzJ1xuaW1wb3J0IGthbGltYmEgZnJvbSAnLi9saWIva2FsaW1iYSdcbmltcG9ydCB7XG4gIG1pZGlfaW5pdCxcbiAgcGxheV9ub3RlLFxuICBwbGF5X3NlcXVlbmNlLFxuICBleHBvcnRfcGF0dGVybl9hc19taWRpLFxuICBub3RlX3ZhbHVlcyxcbiAgTWlkaVdyaXRlcixcbn0gZnJvbSAnLi9saWIvbWlkaSdcbmltcG9ydCB7XG4gIHJlcXVlc3RBdWRpb0NvbnRleHQsIG5vcm0sIGRhdGFVUkl0b0Jsb2IsXG4gIGdldF9ib3VuZHMsIGdldF9kaWZmX2JvdW5kcyxcbiAgdHJhbnNwb3NlLFxufSBmcm9tICcuL2xpYi91dGlsJ1xuaW1wb3J0IHtcbiAgdXBkYXRlX3ZhbHVlX29uX2NoYW5nZSxcbiAgdXBkYXRlX3JhZGlvX3ZhbHVlX29uX2NoYW5nZSxcbiAgYnVpbGRfb3B0aW9ucyxcbiAgbnhcbn0gZnJvbSAnLi9saWIvdWknXG5cbmltcG9ydCAqIGFzIGRhdGEgZnJvbSAnLi9kYXRhJ1xuXG5jb25zdCBERUZBVUxUX0JQTSA9IDYwXG5cbmxldCByZWNvcmRlciA9IG51bGxcbmxldCByZWNvcmRpbmcgPSBmYWxzZVxuXG5taWRpX2luaXQoKVxuXG4vKiBpbml0aWFsaXphdGlvbiAqL1xuXG5jb25zdCBtYXNzX2ZpZWxkcyA9IFtcbiAgXCJkYXRlXCIsIFwidGltZXN0YW1wXCIsXG4gIFwiZmF0YWxpdGllc1wiLCBcImluanVyZWRcIiwgXCJ0b3RhbF92aWN0aW1zXCIsXG4gIFwiYWdlXCIsIFwiY2FzZVwiLCBcIndlYXBvbl90eXBlXCIsIFwid2VhcG9uX2RldGFpbHNcIlxuXS5yZWR1Y2UoKGEsYixpKSA9PiB7XG4gIGFbYl0gPSBpXG4gIHJldHVybiBhXG59LCB7fSlcblxubGV0IGkgPSAwLCBtYXNzX2kgPSAwLCBkYXRhc2V0cyA9IHt9LCBkYXRhc2V0ID0ge30sIGJvdW5kcyA9IHt9LCBkaWZmID0gW11cbmxldCBwbGF5X2ZuID0gcGxheV9zZXF1ZW5jZVxuZGF0YS5sb2FkKCkudGhlbihsaXN0cyA9PiB7XG4gIGNvbnNvbGUubG9nKGxpc3RzKVxuICB0cmFuc3Bvc2UobGlzdHMuZ3VuX3Zpb2xlbmNlX2J5X21vbnRoLmxpbmVzKS5mb3JFYWNoKChyb3csIGkpID0+IHtcbiAgICBjb25zdCBuYW1lID0gbGlzdHMuZ3VuX3Zpb2xlbmNlX2J5X21vbnRoLmhbaV1cbiAgICBpZiAobmFtZSA9PT0gJ0RhdGUnKSByZXR1cm5cbiAgICBjb25zb2xlLmxvZyhuYW1lLCByb3cpXG4gICAgZGF0YXNldHNbbmFtZV0gPSB7XG4gICAgICBuYW1lLFxuICAgICAgaDogW25hbWVdLFxuICAgICAgbGluZXM6IFtyb3cubWFwKG4gPT4gcGFyc2VJbnQobikpXSxcbiAgICAgIHBsYXlfZm46IHBsYXlfc2VxdWVuY2UsXG4gICAgfVxuICB9KVxuICBkYXRhc2V0c1tcIk1hc3MgU2hvb3RpbmdzXCJdID0gbGlzdHMubWFzc19zaG9vdGluZ3NfbGl0ZVxuICBkYXRhc2V0c1tcIk1hc3MgU2hvb3RpbmdzXCJdLm5hbWUgPSBcIk1hc3MgU2hvb3RpbmdzXCJcbiAgZGF0YXNldHNbXCJNYXNzIFNob290aW5nc1wiXS5wbGF5X2ZuID0gcGxheV9tYXNzX3Nob290aW5nc1xuICBjb25zdCBsaW5lcyA9IGRhdGFzZXRzW1wiTWFzcyBTaG9vdGluZ3NcIl0ubGluZXMucmV2ZXJzZSgpXG4gIGNvbnN0IFttaW5feSwgLi4ucmVzdF0gPSBsaW5lc1swXVttYXNzX2ZpZWxkcy5kYXRlXS5zcGxpdCgnLycpXG5cbiAgZGF0YXNldHNbXCJNYXNzIFNob290aW5nc1wiXS5kYXRlcyA9IGxpbmVzLm1hcChyb3cgPT4ge1xuICAgIGNvbnN0IFt5LCBtLCBkXSA9IHJvd1ttYXNzX2ZpZWxkcy5kYXRlXS5zcGxpdCgnLycpXG4gICAgcmV0dXJuIChwYXJzZUludCh5KSAtIHBhcnNlSW50KG1pbl95KSkgKiAxMiArIHBhcnNlSW50KG0pXG4gIH0pXG4gIGRhdGFzZXRzW1wiTWFzcyBTaG9vdGluZ3NcIl0uZGF0YSA9IGxpbmVzXG4gIGRhdGFzZXRzW1wiTWFzcyBTaG9vdGluZ3NcIl0ubGluZXMgPSBbbGluZXMubWFwKHJvdyA9PiByb3dbbWFzc19maWVsZHMudG90YWxfdmljdGltc10pXVxuICByZXF1ZXN0QXVkaW9Db250ZXh0KHJlYWR5KVxufSlcblxuLyogcGxheSBmdW5jdGlvbiBmb3IgbWFzcyBzaG9vdGluZyBkYXRhIHcvIGN1c3RvbSB0aW1pbmcgKi9cblxubGV0IG1hc3NfcmVzdCA9IDBcblxuLy8gZXhwb3J0IGNvbnN0IG5vdGVfdmFsdWVzID0gW1xuLy8gICBbOCwgJzggbWVhc3VyZXMnLCA4ICogNTEyXSxcbi8vICAgWzQsICc0IG1lYXN1cmVzJywgNCAqIDUxMl0sXG4vLyAgIFsyLCAnMiBtZWFzdXJlcycsIDIgKiA1MTJdLFxuLy8gICBbMSwgJ3dob2xlIG5vdGUnLCA1MTJdLFxuLy8gICBbMS8yLCAnaGFsZiBub3RlJywgMjU2XSxcbi8vICAgWzEvMywgJ3RoaXJkIG5vdGUnLCBbMTcwLCAxNzAsIDE3MV1dLFxuLy8gICBbMS80LCAncXVhcnRlciBub3RlJywgMTI4XSxcbi8vICAgWzEvNSwgJ2ZpZnRoIG5vdGUnLCBbNTEsNTEsNTEsNTEsNTJdXSxcbi8vICAgWzEvNiwgJ3NpeHRoIG5vdGUnLCBbODUsIDg1LCA4NiwgODUsIDg1LCA4Nl1dLFxuLy8gICBbMS84LCAnZWlnaHRoIG5vdGUnLCA2NF0sXG4vLyAgIFsxLzEwLCAndGVudGggbm90ZScsIFsyNSwyNiwyNiwyNSwyNiwyNSwyNiwyNiwyNSwyNl1dLFxuLy8gICBbMS8xMiwgJ3R3ZWxmdGggbm90ZScsIFsyMSwyMSwyMiwgMjEsMjEsMjIsIDIxLDIxLDIyLCAyMSwyMSwyMl1dLFxuLy8gICBbMS8xNiwgJ3NpeHRlZW50aCBub3RlJywgMzJdLFxuLy8gICBbMS8zMiwgJ3RoaXJ0eXNlY29uZCBub3RlJywgMTZdLFxuLy8gXVxuXG5mdW5jdGlvbiBwbGF5X21hc3Nfc2hvb3RpbmdzKGksIGJvdW5kcywgZGlmZiwgbm90ZV90aW1lLCBjaGFubmVsPVwiYWxsXCIsIGV4cG9ydGluZykge1xuICBjb25zdCB7IHJvd3MsIG1pbiwgbWF4IH0gPSBib3VuZHNcbiAgY29uc3QgeSA9IDBcbiAgY29uc3QgeCA9IGkgJSByb3dzWzBdLmxlbmd0aFxuICBjb25zdCBuID0gcm93c1t5XVt4XVxuICBjb25zdCB0b3RhbCA9IGRhdGFzZXQuZGF0ZXMubGVuZ3RoXG4gIGxldCBub3RlcyA9IFtdLCBtaWRpX25vdGVzID0gW10sIGNhc2VzID0gW10sIHRpbWluZ3NcbiAgY29uc29sZS5sb2coaSwgbWFzc19pLCBkYXRhc2V0LmRhdGVzW21hc3NfaV0pXG4gIHdoaWxlIChpID49IGRhdGFzZXQuZGF0ZXNbbWFzc19pXSAmJiBtYXNzX2kgPCB0b3RhbCkge1xuICAgIG5vdGVzLnB1c2goZGF0YXNldC5saW5lc1swXVttYXNzX2ldKVxuICAgIGNhc2VzLnB1c2goZGF0YXNldC5kYXRhW21hc3NfaV1bbWFzc19maWVsZHMuZGF0ZV0gKyAnICcgKyBkYXRhc2V0LmRhdGFbbWFzc19pXVttYXNzX2ZpZWxkcy5jYXNlXSArXG4gICAgICBcIiwgXCIgKyBkYXRhc2V0LmRhdGFbbWFzc19pXVttYXNzX2ZpZWxkcy5mYXRhbGl0aWVzXSArICcgZGVhZCwgJyArIGRhdGFzZXQuZGF0YVttYXNzX2ldW21hc3NfZmllbGRzLmluanVyZWRdICsgJyBpbmp1cmVkJylcbiAgICBjb25zb2xlLmxvZygncHVzaCBjYXNlJywgZGF0YXNldC5kYXRhW21hc3NfaV1bbWFzc19maWVsZHMuZGF0ZV0gKyAnICcgKyBkYXRhc2V0LmRhdGFbbWFzc19pXVttYXNzX2ZpZWxkcy5jYXNlXSlcbiAgICBtYXNzX2kgKz0gMVxuICB9XG4gIHN3aXRjaCAobm90ZXMubGVuZ3RoKSB7XG4gICAgZGVmYXVsdDpcbiAgICBjYXNlIDA6XG4gICAgICBtYXNzX3Jlc3QgKz0gMVxuICAgICAgYnJlYWtcbiAgICBjYXNlIDE6XG4gICAgICBtaWRpX25vdGVzLnB1c2gocGxheV9ub3RlKCBub3JtKG5vdGVzWzBdLCBtaW4sIG1heCkgKiBueC5tdWx0aXBseS52YWx1ZSwgMTI4LCBjaGFubmVsLCBleHBvcnRpbmcsIG1hc3NfcmVzdCwgMCkpXG4gICAgICB0aW1pbmdzID0gWzEyOF1cbiAgICAgIGJyZWFrXG4gICAgY2FzZSAyOlxuICAgICAgbWlkaV9ub3Rlcy5wdXNoKHBsYXlfbm90ZSggbm9ybShub3Rlc1swXSwgbWluLCBtYXgpICogbngubXVsdGlwbHkudmFsdWUsIDY0LCBjaGFubmVsLCBleHBvcnRpbmcsIG1hc3NfcmVzdCwgMCkpXG4gICAgICBtaWRpX25vdGVzLnB1c2gocGxheV9ub3RlKCBub3JtKG5vdGVzWzFdLCBtaW4sIG1heCkgKiBueC5tdWx0aXBseS52YWx1ZSwgNjQsIGNoYW5uZWwsIGV4cG9ydGluZywgMCwgNjQpKVxuICAgICAgdGltaW5ncyA9IFs2NCwgNjRdXG4gICAgICBicmVha1xuICAgIGNhc2UgMzpcbiAgICAgIG1pZGlfbm90ZXMucHVzaChwbGF5X25vdGUoIG5vcm0obm90ZXNbMF0sIG1pbiwgbWF4KSAqIG54Lm11bHRpcGx5LnZhbHVlLCA0MywgY2hhbm5lbCwgZXhwb3J0aW5nLCBtYXNzX3Jlc3QsIDApKVxuICAgICAgbWlkaV9ub3Rlcy5wdXNoKHBsYXlfbm90ZSggbm9ybShub3Rlc1sxXSwgbWluLCBtYXgpICogbngubXVsdGlwbHkudmFsdWUsIDQzLCBjaGFubmVsLCBleHBvcnRpbmcsIDAsIDQzKSlcbiAgICAgIG1pZGlfbm90ZXMucHVzaChwbGF5X25vdGUoIG5vcm0obm90ZXNbMl0sIG1pbiwgbWF4KSAqIG54Lm11bHRpcGx5LnZhbHVlLCA0MiwgY2hhbm5lbCwgZXhwb3J0aW5nLCAwLCA4NSkpXG4gICAgICB0aW1pbmdzID0gWzQzLCA0MyAsNDJdXG4gICAgICBicmVha1xuICAgIGNhc2UgNDpcbiAgICAgIG1pZGlfbm90ZXMucHVzaChwbGF5X25vdGUoIG5vcm0obm90ZXNbMF0sIG1pbiwgbWF4KSAqIG54Lm11bHRpcGx5LnZhbHVlLCAzMiwgY2hhbm5lbCwgZXhwb3J0aW5nLCBtYXNzX3Jlc3QsIDApKVxuICAgICAgbWlkaV9ub3Rlcy5wdXNoKHBsYXlfbm90ZSggbm9ybShub3Rlc1sxXSwgbWluLCBtYXgpICogbngubXVsdGlwbHkudmFsdWUsIDMyLCBjaGFubmVsLCBleHBvcnRpbmcsIDAsIDMyKSlcbiAgICAgIG1pZGlfbm90ZXMucHVzaChwbGF5X25vdGUoIG5vcm0obm90ZXNbMl0sIG1pbiwgbWF4KSAqIG54Lm11bHRpcGx5LnZhbHVlLCAzMiwgY2hhbm5lbCwgZXhwb3J0aW5nLCAwLCA2NCkpXG4gICAgICBtaWRpX25vdGVzLnB1c2gocGxheV9ub3RlKCBub3JtKG5vdGVzWzNdLCBtaW4sIG1heCkgKiBueC5tdWx0aXBseS52YWx1ZSwgMzIsIGNoYW5uZWwsIGV4cG9ydGluZywgMCwgOTYpKVxuICAgICAgdGltaW5ncyA9IFszMiwgMzIsIDMyLCAzMl1cbiAgICAgIGJyZWFrXG4gIH1cbiAgaWYgKGNhc2VzLmxlbmd0aCkge1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNjYXNlcycpLmlubmVySFRNTCA9IGNhc2VzLmpvaW4oJzxicj4nKVxuICB9XG4gIGlmICh0b3RhbCA8PSBtYXNzX2kpIHtcbiAgICBtYXNzX3Jlc3QgPSAwXG4gICAgbWFzc19pID0gMFxuICAgIGkgPSAwXG4gIH0gZWxzZSB7XG4gICAgaSArPSAxXG4gIH1cbiAga2FsaW1iYS5wbGF5KDIyMCwgLTEyKVxuICBpZiAobm90ZXMubGVuZ3RoKSB7XG4gICAgbWFzc19yZXN0ID0gMFxuICAgIHJldHVybiBbaSwgbWlkaV9ub3RlcywgdGltaW5ncywgbWFzc19yZXN0XVxuICB9XG4gIG1hc3NfcmVzdCArPSAxMjhcbiAgcmV0dXJuIFtpLCBbXSwgW10sIDBdXG59XG5cbi8qIHBsYXkgbmV4dCBub3RlIGFjY29yZGluZyB0byBzb25pZmljYXRpb24gKi9cblxuZnVuY3Rpb24gcGxheV9uZXh0KCl7XG4gIGxldCBub3RlX3RpbWUgPSAxMjAwMDAgLyBUb25lLlRyYW5zcG9ydC5icG0udmFsdWUgKiBub3RlX3ZhbHVlc1tueC50aW1pbmcuYWN0aXZlXVswXVxuICBzZXRUaW1lb3V0KHBsYXlfbmV4dCwgbm90ZV90aW1lKVxuICBsZXQgW25ld19pLCBub3RlcywgdGltaW5nc10gPSBwbGF5X2ZuKGksIGJvdW5kcywgZGlmZiwgbm90ZV90aW1lKVxuICBpID0gbmV3X2lcbiAgaWYgKHJlY29yZGluZykge1xuICAgIGxldCB0aW1pbmcgPSBub3RlX3ZhbHVlc1tueC50aW1pbmcuYWN0aXZlXVsyXVxuICAgIGlmICh0aW1pbmcubGVuZ3RoKSB0aW1pbmcgPSB0aW1pbmdbaSAlIHRpbWluZy5sZW5ndGhdXG4gICAgcmVjb3JkZXIuYWRkRXZlbnQobmV3IE1pZGlXcml0ZXIuTm90ZUV2ZW50KHsgcGl0Y2g6IG5vdGVzLCBkdXJhdGlvbjogJ3QnICsgdGltaW5nIH0pKVxuICB9XG59XG5cbi8qIGJpbmQgc2VsZWN0cyAqL1xuXG5mdW5jdGlvbiBwaWNrX2RhdGFzZXQoa2V5KXtcbiAgY29uc29sZS5sb2coJ3BpY2sgZGF0YXNldDonLCBrZXksIGRhdGFzZXRzW2tleV0pXG4gIGkgPSAwXG4gIG1hc3NfaSA9IDBcbiAgbWFzc19yZXN0ID0gMFxuICBkYXRhc2V0ID0gZGF0YXNldHNba2V5XVxuICBib3VuZHMgPSBnZXRfYm91bmRzKGRhdGFzZXQpXG4gIGRpZmYgPSBnZXRfZGlmZl9ib3VuZHMoYm91bmRzLnJvd3MpXG4gIHBsYXlfZm4gPSBkYXRhc2V0LnBsYXlfZm5cbn1cblxuLyogYnVpbGQgYW5kIGJpbmQgdGhlIFVJICovXG5cbmZ1bmN0aW9uIHJlYWR5KCkge1xuICBzY2FsZXMuYnVpbGRfb3B0aW9ucyhkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2NhbGUnKSlcbiAgYnVpbGRfb3B0aW9ucyhkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZGF0YXNldCcpLCBkYXRhc2V0cywgcGlja19kYXRhc2V0KVxuXG4gIGNvbnN0IGRpYWxfc2l6ZSA9IFs1MCwgNTBdXG5cblx0VG9uZS5UcmFuc3BvcnQuYnBtLnZhbHVlID0gREVGQVVMVF9CUE1cbiAgbngudGVtcG8gPSBuZXcgTmV4dXMuRGlhbCgnI3RlbXBvJywge1xuICAgIHNpemU6IGRpYWxfc2l6ZSxcbiAgICBtaW46IDEwLFxuICAgIG1heDogMzAwLFxuICAgIHN0ZXA6IDEsXG4gICAgdmFsdWU6IERFRkFVTFRfQlBNLFxuICB9KVxuICB1cGRhdGVfdmFsdWVfb25fY2hhbmdlKG54LnRlbXBvLCAnI3RlbXBvJywgdHJ1ZSwgdiA9PiBUb25lLlRyYW5zcG9ydC5icG0udmFsdWUgPSB2KVxuXG4gIG54LnRpbWluZyA9IG5ldyBOZXh1cy5SYWRpb0J1dHRvbignI3RpbWluZycsIHtcbiAgICBzaXplOiBbNDAwLDI1XSxcbiAgICBudW1iZXJPZkJ1dHRvbnM6IG5vdGVfdmFsdWVzLmxlbmd0aCxcbiAgICBhY3RpdmU6IDYsXG4gIH0pXG4gIHVwZGF0ZV9yYWRpb192YWx1ZV9vbl9jaGFuZ2UobngudGltaW5nLCAnI3RpbWluZycsIG5vdGVfdmFsdWVzKVxuXG4gIG54LmR1cmF0aW9uID0gbmV3IE5leHVzLkRpYWwoJyNkdXJhdGlvbicsIHtcbiAgICBzaXplOiBkaWFsX3NpemUsXG4gICAgbWluOiAwLFxuICAgIG1heDogMixcbiAgICBzdGVwOiAwLjAxLFxuICAgIHZhbHVlOiAwLjgsXG4gIH0pXG4gIHVwZGF0ZV92YWx1ZV9vbl9jaGFuZ2UobnguZHVyYXRpb24sICcjZHVyYXRpb24nLCBmYWxzZSlcblxuICBueC5vZmZzZXQgPSBuZXcgTmV4dXMuRGlhbCgnI29mZnNldCcsIHtcbiAgICBzaXplOiBkaWFsX3NpemUsXG4gICAgbWluOiAtMjQsXG4gICAgbWF4OiAyNCxcbiAgICBzdGVwOiAxLFxuICAgIHZhbHVlOiAtNSxcbiAgfSlcbiAgdXBkYXRlX3ZhbHVlX29uX2NoYW5nZShueC5vZmZzZXQsICcjb2Zmc2V0JywgdHJ1ZSlcblxuICBueC5vY3RhdmUgPSBuZXcgTmV4dXMuRGlhbCgnI29jdGF2ZScsIHtcbiAgICBzaXplOiBkaWFsX3NpemUsXG4gICAgbWluOiAtNCxcbiAgICBtYXg6IDQsXG4gICAgc3RlcDogMSxcbiAgICB2YWx1ZTogMCxcbiAgfSlcbiAgdXBkYXRlX3ZhbHVlX29uX2NoYW5nZShueC5vY3RhdmUsICcjb2N0YXZlJywgdHJ1ZSlcblxuICBueC5tdWx0aXBseSA9IG5ldyBOZXh1cy5EaWFsKCcjbXVsdGlwbHknLCB7XG4gICAgc2l6ZTogZGlhbF9zaXplLFxuICAgIG1pbjogLTY0LFxuICAgIG1heDogNjQsXG4gICAgc3RlcDogMSxcbiAgICB2YWx1ZTogMTcsXG4gIH0pXG4gIHVwZGF0ZV92YWx1ZV9vbl9jaGFuZ2UobngubXVsdGlwbHksICcjbXVsdGlwbHknLCB0cnVlKVxuXG4gIG54LmludGVydmFsID0gbmV3IE5leHVzLkRpYWwoJyNpbnRlcnZhbCcsIHtcbiAgICBzaXplOiBkaWFsX3NpemUsXG4gICAgbWluOiAtNjQsXG4gICAgbWF4OiA2NCxcbiAgICBzdGVwOiAxLFxuICAgIHZhbHVlOiAxMCxcbiAgfSlcbiAgdXBkYXRlX3ZhbHVlX29uX2NoYW5nZShueC5pbnRlcnZhbCwgJyNpbnRlcnZhbCcsIHRydWUpXG5cbiAgY29uc3QgZXhwb3J0X21pZGlfYnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2V4cG9ydF9taWRpJylcbiAgZXhwb3J0X21pZGlfYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIGV4cG9ydF9wYXR0ZXJuX2FzX21pZGkoZGF0YXNldC5uYW1lLCBib3VuZHMsIGRpZmYsIG54LnRlbXBvLnZhbHVlLCBueC50aW1pbmcuYWN0aXZlLCBwbGF5X2ZuKVxuICB9KVxuXG4gIGNvbnN0IHJlY29yZF9taWRpX2J1dHRvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNyZWNvcmRfbWlkaScpXG4gIHJlY29yZF9taWRpX2J1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBpZiAocmVjb3JkaW5nKSB7XG4gICAgICByZWNvcmRfbWlkaV9idXR0b24uaW5uZXJIVE1MID0gJ1JlY29yZCBNSURJJ1xuICAgICAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdyZWNvcmRpbmcnKVxuICAgICAgcmVjb3JkaW5nID0gZmFsc2VcbiAgICAgIGNvbnN0IHdyaXRlciA9IG5ldyBNaWRpV3JpdGVyLldyaXRlcihbcmVjb3JkZXJdKVxuICAgICAgY29uc3QgYmxvYiA9IGRhdGFVUkl0b0Jsb2Iod3JpdGVyLmRhdGFVcmkoKSlcbiAgICAgIHNhdmVBcyhibG9iLCAnUmVjb3JkaW5nIC0gJyArIGRhdGFzZXQubmFtZSArICcubWlkJylcbiAgICB9IGVsc2Uge1xuICAgICAgcmVjb3JkX21pZGlfYnV0dG9uLmlubmVySFRNTCA9ICdTYXZlIFJlY29yZGluZydcbiAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgncmVjb3JkaW5nJylcbiAgICAgIHJlY29yZGluZyA9IHRydWVcbiAgICAgIHJlY29yZGVyID0gbmV3IE1pZGlXcml0ZXIuVHJhY2soKVxuICAgICAgcmVjb3JkZXIuc2V0VGVtcG8obngudGVtcG8udmFsdWUpXG4gICAgfVxuICB9KVxuXG4gIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5sb2FkaW5nJykuY2xhc3NMaXN0LnJlbW92ZSgnbG9hZGluZycpXG5cbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2RhdGFzZXQnKS52YWx1ZSA9ICdNYXNzIFNob290aW5ncydcbiAgcGlja19kYXRhc2V0KCdNYXNzIFNob290aW5ncycpXG5cbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3NjYWxlJykudmFsdWUgPSAnMTQnXG4gIHNjYWxlcy5waWNrKDE0KVxuXG4gIHBsYXlfbmV4dCgpXG59XG5cbi8qIGtleXMgKi9cblxua2V5cy5saXN0ZW4oaW5kZXggPT4ge1xuICBueC5vZmZzZXQudmFsdWUgPSBpbmRleFxuICBueC5vZmZzZXQudXBkYXRlKGluZGV4KVxufSlcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9pbmRleC5qcyIsIm1vZHVsZS5leHBvcnRzID0gKGZ1bmN0aW9uKCl7XG4gIHZhciBJbnRvbmF0aW9uID0gZnVuY3Rpb24ob3B0KXtcbiAgICBvcHQgPSB0aGlzLm9wdCA9IE9iamVjdC5hc3NpZ24oe1xuICAgICAgbmFtZTogXCJcIixcbiAgICAgIHJvb3Q6IDQ0MCxcbiAgICAgIG9jdGF2ZTogMCxcbiAgICAgIGludGVydmFsOiAyLFxuICAgICAgdGV0OiAwLFxuICAgICAgaW50ZXJ2YWxzOiBudWxsLFxuICAgIH0sIG9wdCB8fCB7fSlcbiAgICB0aGlzLmdlbmVyYXRlKClcbiAgfVxuICBJbnRvbmF0aW9uLnByb3RvdHlwZS5nZW5lcmF0ZSA9IGZ1bmN0aW9uKG9wdCl7XG4gICAgb3B0ID0gT2JqZWN0LmFzc2lnbih0aGlzLm9wdCwgb3B0IHx8IHt9KVxuICAgIGlmIChvcHQuc2NsKSB7XG4gICAgICB0aGlzLmdlbmVyYXRlX3NjbCgpXG4gICAgfVxuICAgIGVsc2UgaWYgKG9wdC50ZXQpIHtcbiAgICAgIHRoaXMuZ2VuZXJhdGVfdGV0KClcbiAgICB9XG4gICAgZWxzZSBpZiAob3B0LmludGVydmFscykge1xuICAgICAgdGhpcy5nZW5lcmF0ZV9pbnRlcnZhbHMoKVxuICAgIH1cbiAgfVxuICBJbnRvbmF0aW9uLnByb3RvdHlwZS5nZW5lcmF0ZV9pbnRlcnZhbHMgPSBmdW5jdGlvbigpe1xuICAgIHZhciByb290ID0gdGhpcy5vcHQucm9vdFxuICAgIHZhciBpbnRlcnZhbF9saXN0ID0gdGhpcy5vcHQuaW50ZXJ2YWxzXG4gICAgaWYgKHR5cGVvZiBpbnRlcnZhbF9saXN0ID09IFwic3RyaW5nXCIpIHtcbiAgICAgIGludGVydmFsX2xpc3QgPSBpbnRlcnZhbF9saXN0LnNwbGl0KFwiIFwiKVxuICAgIH1cbiAgICB0aGlzLm5hbWUgPSB0aGlzLm9wdC5uYW1lIHx8IFwiaW50ZXJ2YWwgbGlzdFwiXG4gICAgdGhpcy5pbnRlcnZhbHMgPSBpbnRlcnZhbF9saXN0XG4gICAgdGhpcy5pbnRlcnZhbCA9IHRoaXMub3B0LmludGVydmFsID0gcGFyc2VJbnRlcnZhbC5jYWxsKHRoaXMsIGludGVydmFsX2xpc3QucG9wKCkgKVxuICAgIHRoaXMuc2NhbGUgPSBpbnRlcnZhbF9saXN0Lm1hcCggcGFyc2VJbnRlcnZhbFN0cmluZy5iaW5kKHRoaXMpICkuZmlsdGVyKGZ1bmN0aW9uKHYpe1xuICAgICAgcmV0dXJuICEhIHZcbiAgICB9KVxuICB9XG4gIEludG9uYXRpb24ucHJvdG90eXBlLmdlbmVyYXRlX3RldCA9IGZ1bmN0aW9uKCl7XG4gICAgdmFyIHNjYWxlID0gdGhpcy5zY2FsZSA9IFtdXG4gICAgdmFyIHJvb3QgPSB0aGlzLm9wdC5yb290XG4gICAgdmFyIHRldCA9IHRoaXMub3B0LnRldFxuICAgIHZhciBpbnRlcnZhbCA9IHRoaXMuaW50ZXJ2YWwgPSB0aGlzLm9wdC5pbnRlcnZhbFxuICAgIHZhciByYXRpbyA9IE1hdGgucG93KCBpbnRlcnZhbCwgMS90ZXQgKVxuICAgIHZhciBuID0gcm9vdFxuICAgIHNjYWxlLnB1c2gobilcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRldC0xOyBpKyspIHtcbiAgICAgIG4gKj0gcmF0aW9cbiAgICAgIHNjYWxlLnB1c2gobilcbiAgICB9XG4gICAgdGhpcy5uYW1lID0gdGhpcy5vcHQubmFtZSB8fCB0ZXQgKyBcIi10b25lIGVxdWFsIHRlbXBlcmFtZW50XCJcbiAgICB0aGlzLmludGVydmFscyA9IG51bGxcbiAgfVxuICBJbnRvbmF0aW9uLnByb3RvdHlwZS5nZW5lcmF0ZV9zY2wgPSBmdW5jdGlvbigpe1xuICAgIHZhciByb290ID0gdGhpcy5vcHQucm9vdFxuICAgIHZhciBzY2wgPSB0aGlzLnBhcnNlX3NjbCggdGhpcy5vcHQuc2NsIClcbiAgICB0aGlzLmludGVydmFscyA9IHNjbC5ub3Rlc1xuICAgIHRoaXMuaW50ZXJ2YWwgPSBzY2wubm90ZXMucG9wKClcbiAgICB0aGlzLm5hbWUgPSB0aGlzLm9wdC5uYW1lIHx8IHNjbC5kZXNjcmlwdGlvblxuICAgIHRoaXMuc2NhbGUgPSBzY2wubm90ZXMubWFwKGZ1bmN0aW9uKHYpe1xuICAgICAgcmV0dXJuIHYgKiByb290XG4gICAgfSlcbiAgfVxuICBJbnRvbmF0aW9uLnByb3RvdHlwZS5wYXJzZV9zY2wgPSBmdW5jdGlvbihzKXtcbiAgICB2YXIgc2NsID0ge31cbiAgICBzY2wuY29tbWVudHMgPSBbXVxuICAgIHNjbC5ub3RlcyA9IFtdXG4gICAgcy50cmltKCkuc3BsaXQoXCJcXG5cIikuZm9yRWFjaChmdW5jdGlvbihsaW5lKXtcbiAgICAgIC8vIExpbmVzIGJlZ2lubmluZyB3aXRoIGFuIGV4Y2xhbWF0aW9uIG1hcmsgYXJlIHJlZ2FyZGVkIGFzIGNvbW1lbnRzXG4gICAgICAvLyBhbmQgYXJlIHRvIGJlIGlnbm9yZWQuXG4gICAgICBpZiAoIGxpbmUuaW5kZXhPZihcIiFcIikgIT09IC0xICkge1xuICAgICAgICBzY2wuY29tbWVudHMucHVzaChsaW5lKVxuICAgICAgfVxuICAgICAgLy8gVGhlIGZpcnN0IChub24gY29tbWVudCkgbGluZSBjb250YWlucyBhIHNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSBzY2FsZS5cbiAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGRlc2NyaXB0aW9uLCB0aGVyZSBzaG91bGQgYmUgYW4gZW1wdHkgbGluZS4gKG5iOiB3aGljaCBpcyBmYWxzZXkpXG4gICAgICBlbHNlIGlmICggISAoJ2Rlc2NyaXB0aW9uJyBpbiBzY2wpICkge1xuICAgICAgICBzY2wuZGVzY3JpcHRpb24gPSBsaW5lXG4gICAgICB9XG4gICAgICAvLyBUaGUgc2Vjb25kIGxpbmUgY29udGFpbnMgdGhlIG51bWJlciBvZiBub3Rlcy5cbiAgICAgIC8vIFRoZSBmaXJzdCBub3RlIG9mIDEvMSBvciAwLjAgY2VudHMgaXMgaW1wbGljaXQgYW5kIG5vdCBpbiB0aGUgZmlsZXMuXG4gICAgICBlbHNlIGlmICggISBzY2wubm90ZXMubGVuZ3RoKSB7XG4gICAgICAgIHNjbC5ub3Rlcy5wdXNoKDEpXG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy8gSWYgdGhlIHZhbHVlIGNvbnRhaW5zIGEgcGVyaW9kLCBpdCBpcyBhIGNlbnRzIHZhbHVlLCBvdGhlcndpc2UgYSByYXRpby5cbiAgICAgICAgdmFyIG5vdGUgPSBsaW5lLnJlcGxhY2UoL15bXi1cXC4wLTldKy8sXCJcIikucmVwbGFjZSgvW14tXFwvXFwuMC05XSskLyxcIlwiKVxuICAgICAgICBpZiAoIG5vdGUuaW5kZXhPZihcIi5cIikgIT09IC0xICkge1xuICAgICAgICAgIG5vdGUgPSBNYXRoLnBvdyggMiwgKHBhcnNlRmxvYXQobm90ZSkgLyAxMjAwKSApXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgbm90ZSA9IHBhcnNlSW50ZXJ2YWwobm90ZSlcbiAgICAgICAgfVxuICAgICAgICBpZiAobm90ZSkge1xuICAgICAgICAgIHNjbC5ub3Rlcy5wdXNoKG5vdGUpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiBzY2xcbiAgfVxuICBJbnRvbmF0aW9uLnByb3RvdHlwZS5pbmRleCA9IGZ1bmN0aW9uKGksIG9jdGF2ZSl7XG4gICAgb2N0YXZlID0gb2N0YXZlIHx8IHRoaXMub3B0Lm9jdGF2ZVxuICAgIHZhciBmID0gdGhpcy5zY2FsZVsgbW9kKGksIHRoaXMuc2NhbGUubGVuZ3RoKXwwIF1cbiAgICB2YXIgcG93ID0gTWF0aC5mbG9vcihub3JtKGksIDAsIHRoaXMuc2NhbGUubGVuZ3RoKSkgKyBvY3RhdmVcbiAgICBmICo9IE1hdGgucG93KHRoaXMuaW50ZXJ2YWwsIHBvdylcbiAgICByZXR1cm4gZlxuICB9XG4gIEludG9uYXRpb24ucHJvdG90eXBlLnJhbmdlID0gZnVuY3Rpb24obWluLCBtYXgpe1xuICAgIHZhciBhID0gW11cbiAgICBmb3IgKHZhciBpID0gbWluOyBpIDwgbWF4OyBpKyspIHtcbiAgICAgIGEucHVzaCggdGhpcy5pbmRleChpKSApXG4gICAgfVxuICAgIHJldHVybiBhXG4gIH1cbiAgSW50b25hdGlvbi5wcm90b3R5cGUuc2V0X3Jvb3QgPSBmdW5jdGlvbihmKXtcbiAgICB0aGlzLm9wdC5yb290ID0gZlxuICAgIHRoaXMuZ2VuZXJhdGUoKVxuICB9XG4gIEludG9uYXRpb24ucHJvdG90eXBlLnF1YW50aXplX2ZyZXF1ZW5jeSA9IGZ1bmN0aW9uKGYpe1xuICAgIGlmIChmID09IDApIHJldHVybiAwXG4gICAgdmFyIHNjYWxlX2YgPSBmXG4gICAgdmFyIHBvdyA9IDBcbiAgICB2YXIgaW50ZXJ2YWwgPSB0aGlzLmludGVydmFsXG4gICAgdmFyIHNjYWxlID0gdGhpcy5zY2FsZVxuICAgIHdoaWxlIChzY2FsZV9mIDwgcm9vdCkge1xuICAgICAgc2NhbGVfZiAqPSBpbnRlcnZhbFxuICAgICAgcG93IC09IDFcbiAgICB9XG4gICAgd2hpbGUgKHNjYWxlX2YgPiByb290ICogaW50ZXJ2YWwpIHtcbiAgICAgIHNjYWxlX2YgLz0gaW50ZXJ2YWxcbiAgICAgIHBvdyArPSAxXG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2NhbGUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChzY2FsZV9mID4gc2NhbGVbaV0pIGNvbnRpbnVlXG4gICAgICBzY2FsZV9mID0gc2NhbGVbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICAgIHNjYWxlX2YgKj0gTWF0aC5wb3coMiwgcG93KVxuICAgIHJldHVybiBzY2FsZV9mXG4gIH1cbiAgSW50b25hdGlvbi5wcm90b3R5cGUucXVhbnRpemVfaW5kZXggPSBmdW5jdGlvbihpKXtcbiAgICByZXR1cm4gbW9kKGluZGV4LTEsIHRoaXMuc2NhbGUubGVuZ3RoKXwwXG4gIH1cbiAgdmFyIHBhcnNlSW50ZXJ2YWwgPSBJbnRvbmF0aW9uLnByb3RvdHlwZS5wYXJzZV9pbnRlcnZhbCA9IGZ1bmN0aW9uIChzKSB7XG4gICAgaWYgKHR5cGVvZiBzID09IFwibnVtYmVyXCIpIHJldHVybiBzXG4gICAgaWYgKCEgcy5pbmRleE9mKFwiL1wiKSA9PSAtMSkgcmV0dXJuIHBhcnNlSW50KHMpXG4gICAgdmFyIHBwID0gcy5zcGxpdChcIi9cIilcbiAgICB2YXIgbnVtID0gcGFyc2VJbnQocHBbMF0pXG4gICAgdmFyIGRlbiA9IHBhcnNlSW50KHBwWzFdKVxuICAgIGlmIChpc05hTihudW0pKSByZXR1cm4gMVxuICAgIGlmIChpc05hTihkZW4pIHx8IGRlbiA9PSAwKSByZXR1cm4gbnVtXG4gICAgaWYgKG51bSA9PSBkZW4pIHJldHVybiAxXG4gICAgcmV0dXJuIG51bSAvIGRlblxuICB9XG4gIHZhciBwYXJzZUludGVydmFsU3RyaW5nID0gSW50b25hdGlvbi5wcm90b3R5cGUucGFyc2VfaW50ZXJ2YWxfc3RyaW5nID0gZnVuY3Rpb24ocyl7XG4gICAgaWYgKHMuaW5kZXhPZihcIi9cIikgIT09IC0xKSByZXR1cm4gcGFyc2VJbnRlcnZhbChzKSAqIHRoaXMub3B0LnJvb3QgLy8gaW50ZXJ2YWxzXG4gICAgaWYgKHMuaW5kZXhPZihcImZcIikgIT09IC0xKSByZXR1cm4gcGFyc2VGbG9hdChzKSAgICAvLyBwdXJlIGZyZXF1ZW5jaWVzXG4gICAgcmV0dXJuIHBhcnNlRmxvYXQocylcbiAgfVxuICBmdW5jdGlvbiBub3JtKG4sYSxiKXsgcmV0dXJuIChuLWEpIC8gKGItYSkgfVxuICBmdW5jdGlvbiBtb2QobixtKXsgcmV0dXJuIG4tKG0gKiBNYXRoLmZsb29yKG4vbSkpIH1cblxuICByZXR1cm4gSW50b25hdGlvblxufSkoKVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2xpYi9pbnRvbmF0aW9uLmpzIiwiLyoqXG4gKiAgU3RhcnRBdWRpb0NvbnRleHQuanNcbiAqICBAYXV0aG9yIFlvdGFtIE1hbm5cbiAqICBAbGljZW5zZSBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUIE1JVCBMaWNlbnNlXG4gKiAgQGNvcHlyaWdodCAyMDE2IFlvdGFtIE1hbm5cbiAqL1xuKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgIGRlZmluZShbXSwgZmFjdG9yeSk7XG4gICB9IGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuICB9IGVsc2Uge1xuICAgIHJvb3QuU3RhcnRBdWRpb0NvbnRleHQgPSBmYWN0b3J5KCk7XG4gIH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuXG4gIC8qKlxuICAgKiBUaGUgU3RhcnRBdWRpb0NvbnRleHQgb2JqZWN0XG4gICAqL1xuICB2YXIgU3RhcnRBdWRpb0NvbnRleHQgPSB7XG4gICAgLyoqXG4gICAgICogVGhlIGF1ZGlvIGNvbnRleHQgcGFzc2VkIGluIGJ5IHRoZSB1c2VyXG4gICAgICogQHR5cGUge0F1ZGlvQ29udGV4dH1cbiAgICAgKi9cbiAgICBjb250ZXh0IDogbnVsbCxcbiAgICAvKipcbiAgICAgKiBUaGUgVGFwTGlzdGVuZXJzIGJvdW5kIHRvIHRoZSBlbGVtZW50c1xuICAgICAqIEB0eXBlIHtBcnJheX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF90YXBMaXN0ZW5lcnMgOiBbXSxcbiAgICAvKipcbiAgICAgKiBDYWxsYmFja3MgdG8gaW52b2tlIHdoZW4gdGhlIGF1ZGlvIGNvbnRleHQgaXMgc3RhcnRlZFxuICAgICAqIEB0eXBlIHtBcnJheX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9vblN0YXJ0ZWQgOiBbXSxcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGNvbnRleHRcbiAgICogQHBhcmFtIHtBdWRpb0NvbnRleHR9IGN0eFxuICAgKiBAcmV0dXJucyB7U3RhcnRBdWRpb0NvbnRleHR9XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5zZXRDb250ZXh0ID0gZnVuY3Rpb24oY3R4KXtcbiAgICBTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0ID0gY3R4O1xuICAgIHJldHVybiBTdGFydEF1ZGlvQ29udGV4dDtcbiAgfTtcblxuICAvKipcbiAgICogQWRkIGEgdGFwIGxpc3RlbmVyIHRvIHRoZSBhdWRpbyBjb250ZXh0XG4gICAqIEBwYXJhbSAge0FycmF5fEVsZW1lbnR8U3RyaW5nfGpRdWVyeX0gZWxlbWVudFxuICAgKiBAcmV0dXJucyB7U3RhcnRBdWRpb0NvbnRleHR9XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5vbiA9IGZ1bmN0aW9uKGVsZW1lbnQpe1xuICAgIGlmIChBcnJheS5pc0FycmF5KGVsZW1lbnQpIHx8IChOb2RlTGlzdCAmJiBlbGVtZW50IGluc3RhbmNlb2YgTm9kZUxpc3QpKXtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxlbWVudC5sZW5ndGg7IGkrKyl7XG4gICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Lm9uKGVsZW1lbnRbaV0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVsZW1lbnQgPT09IFwic3RyaW5nXCIpe1xuICAgICAgU3RhcnRBdWRpb0NvbnRleHQub24oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChlbGVtZW50KSk7XG4gICAgfSBlbHNlIGlmIChlbGVtZW50LmpxdWVyeSAmJiB0eXBlb2YgZWxlbWVudC50b0FycmF5ID09PSBcImZ1bmN0aW9uXCIpe1xuICAgICAgU3RhcnRBdWRpb0NvbnRleHQub24oZWxlbWVudC50b0FycmF5KCkpO1xuICAgIH0gZWxzZSBpZiAoRWxlbWVudCAmJiBlbGVtZW50IGluc3RhbmNlb2YgRWxlbWVudCl7XG4gICAgICAvL2lmIGl0J3MgYW4gZWxlbWVudCwgY3JlYXRlIGEgVGFwTGlzdGVuZXJcbiAgICAgIHZhciB0YXAgPSBuZXcgVGFwTGlzdGVuZXIoZWxlbWVudCwgb25UYXApO1xuICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVycy5wdXNoKHRhcCk7XG4gICAgfSBcbiAgICByZXR1cm4gU3RhcnRBdWRpb0NvbnRleHQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIEJpbmQgYSBjYWxsYmFjayB0byB3aGVuIHRoZSBhdWRpbyBjb250ZXh0IGlzIHN0YXJ0ZWQuIFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYlxuICAgKiBAcmV0dXJuIHtTdGFydEF1ZGlvQ29udGV4dH1cbiAgICovXG4gIFN0YXJ0QXVkaW9Db250ZXh0Lm9uU3RhcnRlZCA9IGZ1bmN0aW9uKGNiKXtcbiAgICAvL2lmIGl0J3MgYWxyZWFkeSBzdGFydGVkLCBpbnZva2UgdGhlIGNhbGxiYWNrXG4gICAgaWYgKFN0YXJ0QXVkaW9Db250ZXh0LmlzU3RhcnRlZCgpKXtcbiAgICAgIGNiKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Ll9vblN0YXJ0ZWQucHVzaChjYik7XG4gICAgfVxuICAgIHJldHVybiBTdGFydEF1ZGlvQ29udGV4dDtcbiAgfTtcblxuICAvKipcbiAgICogcmV0dXJucyB0cnVlIGlmIHRoZSBjb250ZXh0IGlzIHN0YXJ0ZWRcbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIFN0YXJ0QXVkaW9Db250ZXh0LmlzU3RhcnRlZCA9IGZ1bmN0aW9uKCl7XG4gICAgcmV0dXJuIChTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0ICE9PSBudWxsICYmIFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQuc3RhdGUgPT09IFwicnVubmluZ1wiKTtcbiAgfTtcblxuICAvKipcbiAgICogQGNsYXNzICBMaXN0ZW5zIGZvciBub24tZHJhZ2dpbmcgdGFwIGVuZHMgb24gdGhlIGdpdmVuIGVsZW1lbnRcbiAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgdmFyIFRhcExpc3RlbmVyID0gZnVuY3Rpb24oZWxlbWVudCl7XG5cbiAgICB0aGlzLl9kcmFnZ2VkID0gZmFsc2U7XG5cbiAgICB0aGlzLl9lbGVtZW50ID0gZWxlbWVudDtcblxuICAgIHRoaXMuX2JpbmRlZE1vdmUgPSB0aGlzLl9tb3ZlZC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX2JpbmRlZEVuZCA9IHRoaXMuX2VuZGVkLmJpbmQodGhpcyk7XG5cbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgdGhpcy5fYmluZGVkTW92ZSk7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdGhpcy5fYmluZGVkRW5kKTtcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMuX2JpbmRlZEVuZCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIGRyYWcgbW92ZSBldmVudFxuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLl9tb3ZlZCA9IGZ1bmN0aW9uKGUpe1xuICAgIHRoaXMuX2RyYWdnZWQgPSB0cnVlO1xuICB9O1xuXG4gIC8qKlxuICAgKiB0YXAgZW5kZWQgbGlzdGVuZXJcbiAgICovXG4gIFRhcExpc3RlbmVyLnByb3RvdHlwZS5fZW5kZWQgPSBmdW5jdGlvbihlKXtcbiAgICBpZiAoIXRoaXMuX2RyYWdnZWQpe1xuICAgICAgb25UYXAoKTtcbiAgICB9XG4gICAgdGhpcy5fZHJhZ2dlZCA9IGZhbHNlO1xuICB9O1xuXG4gIC8qKlxuICAgKiByZW1vdmUgYWxsIHRoZSBib3VuZCBldmVudHNcbiAgICovXG4gIFRhcExpc3RlbmVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24oKXtcbiAgICB0aGlzLl9lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgdGhpcy5fYmluZGVkTW92ZSk7XG4gICAgdGhpcy5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdGhpcy5fYmluZGVkRW5kKTtcbiAgICB0aGlzLl9lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMuX2JpbmRlZEVuZCk7XG4gICAgdGhpcy5fYmluZGVkTW92ZSA9IG51bGw7XG4gICAgdGhpcy5fYmluZGVkRW5kID0gbnVsbDtcbiAgICB0aGlzLl9lbGVtZW50ID0gbnVsbDtcbiAgfTtcblxuICAvKipcbiAgICogSW52b2tlZCB0aGUgZmlyc3QgdGltZSBvZiB0aGUgZWxlbWVudHMgaXMgdGFwcGVkLlxuICAgKiBDcmVhdGVzIGEgc2lsZW50IG9zY2lsbGF0b3Igd2hlbiBhIG5vbi1kcmFnZ2luZyB0b3VjaGVuZCBcbiAgICogZXZlbnQgaGFzIGJlZW4gdHJpZ2dlcmVkLlxuICAgKi9cbiAgZnVuY3Rpb24gb25UYXAoKXtcbiAgICAvL3N0YXJ0IHRoZSBhdWRpbyBjb250ZXh0IHdpdGggYSBzaWxlbnQgb3NjaWxsYXRvclxuICAgIGlmIChTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0ICYmICFTdGFydEF1ZGlvQ29udGV4dC5pc1N0YXJ0ZWQoKSl7XG4gICAgICB2YXIgb3NjID0gU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgICB2YXIgc2lsZW50ID0gU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICBzaWxlbnQuZ2Fpbi52YWx1ZSA9IDA7XG4gICAgICBvc2MuY29ubmVjdChzaWxlbnQpO1xuICAgICAgc2lsZW50LmNvbm5lY3QoU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICB2YXIgbm93ID0gU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5jdXJyZW50VGltZTtcbiAgICAgIG9zYy5zdGFydChub3cpO1xuICAgICAgb3NjLnN0b3Aobm93KzAuNSk7XG4gICAgfVxuXG4gICAgLy9kaXNwb3NlIGFsbCB0aGUgdGFwIGxpc3RlbmVyc1xuICAgIGlmIChTdGFydEF1ZGlvQ29udGV4dC5fdGFwTGlzdGVuZXJzKXtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVycy5sZW5ndGg7IGkrKyl7XG4gICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Ll90YXBMaXN0ZW5lcnNbaV0uZGlzcG9zZSgpO1xuICAgICAgfVxuICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVycyA9IG51bGw7XG4gICAgfVxuICAgIC8vdGhlIG9uc3RhcnRlZCBjYWxsYmFja3NcbiAgICBpZiAoU3RhcnRBdWRpb0NvbnRleHQuX29uU3RhcnRlZCl7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IFN0YXJ0QXVkaW9Db250ZXh0Ll9vblN0YXJ0ZWQubGVuZ3RoOyBqKyspe1xuICAgICAgICBTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkW2pdKCk7XG4gICAgICB9XG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gU3RhcnRBdWRpb0NvbnRleHQ7XG59KSk7XG5cblxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2xpYi9zdGFydEF1ZGlvQ29udGV4dC5qcyIsIm1vZHVsZS5leHBvcnRzID0geyBcImRlZmF1bHRcIjogcmVxdWlyZShcImNvcmUtanMvbGlicmFyeS9mbi9hcnJheS9mcm9tXCIpLCBfX2VzTW9kdWxlOiB0cnVlIH07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2JhYmVsLXJ1bnRpbWUvY29yZS1qcy9hcnJheS9mcm9tLmpzXG4vLyBtb2R1bGUgaWQgPSA4M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHsgXCJkZWZhdWx0XCI6IHJlcXVpcmUoXCJjb3JlLWpzL2xpYnJhcnkvZm4vZ2V0LWl0ZXJhdG9yXCIpLCBfX2VzTW9kdWxlOiB0cnVlIH07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2JhYmVsLXJ1bnRpbWUvY29yZS1qcy9nZXQtaXRlcmF0b3IuanNcbi8vIG1vZHVsZSBpZCA9IDg0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0geyBcImRlZmF1bHRcIjogcmVxdWlyZShcImNvcmUtanMvbGlicmFyeS9mbi9pcy1pdGVyYWJsZVwiKSwgX19lc01vZHVsZTogdHJ1ZSB9O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9iYWJlbC1ydW50aW1lL2NvcmUtanMvaXMtaXRlcmFibGUuanNcbi8vIG1vZHVsZSBpZCA9IDg1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0geyBcImRlZmF1bHRcIjogcmVxdWlyZShcImNvcmUtanMvbGlicmFyeS9mbi9tYXRoL2xvZzJcIiksIF9fZXNNb2R1bGU6IHRydWUgfTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vYmFiZWwtcnVudGltZS9jb3JlLWpzL21hdGgvbG9nMi5qc1xuLy8gbW9kdWxlIGlkID0gODZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSB7IFwiZGVmYXVsdFwiOiByZXF1aXJlKFwiY29yZS1qcy9saWJyYXJ5L2ZuL29iamVjdC9rZXlzXCIpLCBfX2VzTW9kdWxlOiB0cnVlIH07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2JhYmVsLXJ1bnRpbWUvY29yZS1qcy9vYmplY3Qva2V5cy5qc1xuLy8gbW9kdWxlIGlkID0gODdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSB7IFwiZGVmYXVsdFwiOiByZXF1aXJlKFwiY29yZS1qcy9saWJyYXJ5L2ZuL3Byb21pc2VcIiksIF9fZXNNb2R1bGU6IHRydWUgfTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vYmFiZWwtcnVudGltZS9jb3JlLWpzL3Byb21pc2UuanNcbi8vIG1vZHVsZSBpZCA9IDg4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0geyBcImRlZmF1bHRcIjogcmVxdWlyZShcImNvcmUtanMvbGlicmFyeS9mbi9zeW1ib2xcIiksIF9fZXNNb2R1bGU6IHRydWUgfTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vYmFiZWwtcnVudGltZS9jb3JlLWpzL3N5bWJvbC5qc1xuLy8gbW9kdWxlIGlkID0gODlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSB7IFwiZGVmYXVsdFwiOiByZXF1aXJlKFwiY29yZS1qcy9saWJyYXJ5L2ZuL3N5bWJvbC9pdGVyYXRvclwiKSwgX19lc01vZHVsZTogdHJ1ZSB9O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9iYWJlbC1ydW50aW1lL2NvcmUtanMvc3ltYm9sL2l0ZXJhdG9yLmpzXG4vLyBtb2R1bGUgaWQgPSA5MFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9pdGVyYXRvciA9IHJlcXVpcmUoXCIuLi9jb3JlLWpzL3N5bWJvbC9pdGVyYXRvclwiKTtcblxudmFyIF9pdGVyYXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pdGVyYXRvcik7XG5cbnZhciBfc3ltYm9sID0gcmVxdWlyZShcIi4uL2NvcmUtanMvc3ltYm9sXCIpO1xuXG52YXIgX3N5bWJvbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zeW1ib2wpO1xuXG52YXIgX3R5cGVvZiA9IHR5cGVvZiBfc3ltYm9sMi5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIF9pdGVyYXRvcjIuZGVmYXVsdCA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIF9zeW1ib2wyLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IF9zeW1ib2wyLmRlZmF1bHQgJiYgb2JqICE9PSBfc3ltYm9sMi5kZWZhdWx0LnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5leHBvcnRzLmRlZmF1bHQgPSB0eXBlb2YgX3N5bWJvbDIuZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiICYmIF90eXBlb2YoX2l0ZXJhdG9yMi5kZWZhdWx0KSA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHtcbiAgcmV0dXJuIHR5cGVvZiBvYmogPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZihvYmopO1xufSA6IGZ1bmN0aW9uIChvYmopIHtcbiAgcmV0dXJuIG9iaiAmJiB0eXBlb2YgX3N5bWJvbDIuZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gX3N5bWJvbDIuZGVmYXVsdCAmJiBvYmogIT09IF9zeW1ib2wyLmRlZmF1bHQucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmogPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZihvYmopO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vYmFiZWwtcnVudGltZS9oZWxwZXJzL3R5cGVvZi5qc1xuLy8gbW9kdWxlIGlkID0gOTFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiJ3VzZSBzdHJpY3QnXG5cbmV4cG9ydHMuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcbmV4cG9ydHMudG9CeXRlQXJyYXkgPSB0b0J5dGVBcnJheVxuZXhwb3J0cy5mcm9tQnl0ZUFycmF5ID0gZnJvbUJ5dGVBcnJheVxuXG52YXIgbG9va3VwID0gW11cbnZhciByZXZMb29rdXAgPSBbXVxudmFyIEFyciA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyA/IFVpbnQ4QXJyYXkgOiBBcnJheVxuXG52YXIgY29kZSA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJ1xuZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNvZGUubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgbG9va3VwW2ldID0gY29kZVtpXVxuICByZXZMb29rdXBbY29kZS5jaGFyQ29kZUF0KGkpXSA9IGlcbn1cblxucmV2TG9va3VwWyctJy5jaGFyQ29kZUF0KDApXSA9IDYyXG5yZXZMb29rdXBbJ18nLmNoYXJDb2RlQXQoMCldID0gNjNcblxuZnVuY3Rpb24gcGxhY2VIb2xkZXJzQ291bnQgKGI2NCkge1xuICB2YXIgbGVuID0gYjY0Lmxlbmd0aFxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gdGhlIG51bWJlciBvZiBlcXVhbCBzaWducyAocGxhY2UgaG9sZGVycylcbiAgLy8gaWYgdGhlcmUgYXJlIHR3byBwbGFjZWhvbGRlcnMsIHRoYW4gdGhlIHR3byBjaGFyYWN0ZXJzIGJlZm9yZSBpdFxuICAvLyByZXByZXNlbnQgb25lIGJ5dGVcbiAgLy8gaWYgdGhlcmUgaXMgb25seSBvbmUsIHRoZW4gdGhlIHRocmVlIGNoYXJhY3RlcnMgYmVmb3JlIGl0IHJlcHJlc2VudCAyIGJ5dGVzXG4gIC8vIHRoaXMgaXMganVzdCBhIGNoZWFwIGhhY2sgdG8gbm90IGRvIGluZGV4T2YgdHdpY2VcbiAgcmV0dXJuIGI2NFtsZW4gLSAyXSA9PT0gJz0nID8gMiA6IGI2NFtsZW4gLSAxXSA9PT0gJz0nID8gMSA6IDBcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoYjY0KSB7XG4gIC8vIGJhc2U2NCBpcyA0LzMgKyB1cCB0byB0d28gY2hhcmFjdGVycyBvZiB0aGUgb3JpZ2luYWwgZGF0YVxuICByZXR1cm4gYjY0Lmxlbmd0aCAqIDMgLyA0IC0gcGxhY2VIb2xkZXJzQ291bnQoYjY0KVxufVxuXG5mdW5jdGlvbiB0b0J5dGVBcnJheSAoYjY0KSB7XG4gIHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyXG4gIHZhciBsZW4gPSBiNjQubGVuZ3RoXG4gIHBsYWNlSG9sZGVycyA9IHBsYWNlSG9sZGVyc0NvdW50KGI2NClcblxuICBhcnIgPSBuZXcgQXJyKGxlbiAqIDMgLyA0IC0gcGxhY2VIb2xkZXJzKVxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgbCA9IHBsYWNlSG9sZGVycyA+IDAgPyBsZW4gLSA0IDogbGVuXG5cbiAgdmFyIEwgPSAwXG5cbiAgZm9yIChpID0gMCwgaiA9IDA7IGkgPCBsOyBpICs9IDQsIGogKz0gMykge1xuICAgIHRtcCA9IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDE4KSB8IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCAxMikgfCAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPDwgNikgfCByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDMpXVxuICAgIGFycltMKytdID0gKHRtcCA+PiAxNikgJiAweEZGXG4gICAgYXJyW0wrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltMKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVycyA9PT0gMikge1xuICAgIHRtcCA9IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDIpIHwgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldID4+IDQpXG4gICAgYXJyW0wrK10gPSB0bXAgJiAweEZGXG4gIH0gZWxzZSBpZiAocGxhY2VIb2xkZXJzID09PSAxKSB7XG4gICAgdG1wID0gKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTApIHwgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDQpIHwgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildID4+IDIpXG4gICAgYXJyW0wrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltMKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIGFyclxufVxuXG5mdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuICByZXR1cm4gbG9va3VwW251bSA+PiAxOCAmIDB4M0ZdICsgbG9va3VwW251bSA+PiAxMiAmIDB4M0ZdICsgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gKyBsb29rdXBbbnVtICYgMHgzRl1cbn1cblxuZnVuY3Rpb24gZW5jb2RlQ2h1bmsgKHVpbnQ4LCBzdGFydCwgZW5kKSB7XG4gIHZhciB0bXBcbiAgdmFyIG91dHB1dCA9IFtdXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSArPSAzKSB7XG4gICAgdG1wID0gKHVpbnQ4W2ldIDw8IDE2KSArICh1aW50OFtpICsgMV0gPDwgOCkgKyAodWludDhbaSArIDJdKVxuICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKVxuICB9XG4gIHJldHVybiBvdXRwdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgb3V0cHV0ID0gJydcbiAgdmFyIHBhcnRzID0gW11cbiAgdmFyIG1heENodW5rTGVuZ3RoID0gMTYzODMgLy8gbXVzdCBiZSBtdWx0aXBsZSBvZiAzXG5cbiAgLy8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuICBmb3IgKHZhciBpID0gMCwgbGVuMiA9IGxlbiAtIGV4dHJhQnl0ZXM7IGkgPCBsZW4yOyBpICs9IG1heENodW5rTGVuZ3RoKSB7XG4gICAgcGFydHMucHVzaChlbmNvZGVDaHVuayh1aW50OCwgaSwgKGkgKyBtYXhDaHVua0xlbmd0aCkgPiBsZW4yID8gbGVuMiA6IChpICsgbWF4Q2h1bmtMZW5ndGgpKSlcbiAgfVxuXG4gIC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcbiAgaWYgKGV4dHJhQnl0ZXMgPT09IDEpIHtcbiAgICB0bXAgPSB1aW50OFtsZW4gLSAxXVxuICAgIG91dHB1dCArPSBsb29rdXBbdG1wID4+IDJdXG4gICAgb3V0cHV0ICs9IGxvb2t1cFsodG1wIDw8IDQpICYgMHgzRl1cbiAgICBvdXRwdXQgKz0gJz09J1xuICB9IGVsc2UgaWYgKGV4dHJhQnl0ZXMgPT09IDIpIHtcbiAgICB0bXAgPSAodWludDhbbGVuIC0gMl0gPDwgOCkgKyAodWludDhbbGVuIC0gMV0pXG4gICAgb3V0cHV0ICs9IGxvb2t1cFt0bXAgPj4gMTBdXG4gICAgb3V0cHV0ICs9IGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl1cbiAgICBvdXRwdXQgKz0gbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXVxuICAgIG91dHB1dCArPSAnPSdcbiAgfVxuXG4gIHBhcnRzLnB1c2gob3V0cHV0KVxuXG4gIHJldHVybiBwYXJ0cy5qb2luKCcnKVxufVxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2Jhc2U2NC1qcy9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gOTJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5hcnJheS5mcm9tJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5BcnJheS5mcm9tO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvZm4vYXJyYXkvZnJvbS5qc1xuLy8gbW9kdWxlIGlkID0gOTNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwicmVxdWlyZSgnLi4vbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3InKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vbW9kdWxlcy9jb3JlLmdldC1pdGVyYXRvcicpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvZm4vZ2V0LWl0ZXJhdG9yLmpzXG4vLyBtb2R1bGUgaWQgPSA5NFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJyZXF1aXJlKCcuLi9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5pdGVyYXRvcicpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi9tb2R1bGVzL2NvcmUuaXMtaXRlcmFibGUnKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L2ZuL2lzLWl0ZXJhYmxlLmpzXG4vLyBtb2R1bGUgaWQgPSA5NVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5tYXRoLmxvZzInKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fY29yZScpLk1hdGgubG9nMjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L2ZuL21hdGgvbG9nMi5qc1xuLy8gbW9kdWxlIGlkID0gOTZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczYub2JqZWN0LmFzc2lnbicpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL19jb3JlJykuT2JqZWN0LmFzc2lnbjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L2ZuL29iamVjdC9hc3NpZ24uanNcbi8vIG1vZHVsZSBpZCA9IDk3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM2Lm9iamVjdC5rZXlzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5PYmplY3Qua2V5cztcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L2ZuL29iamVjdC9rZXlzLmpzXG4vLyBtb2R1bGUgaWQgPSA5OFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJyZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QudG8tc3RyaW5nJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3InKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvd2ViLmRvbS5pdGVyYWJsZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucHJvbWlzZScpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi9tb2R1bGVzL19jb3JlJykuUHJvbWlzZTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L2ZuL3Byb21pc2UuanNcbi8vIG1vZHVsZSBpZCA9IDk5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM2LnN5bWJvbCcpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczcuc3ltYm9sLmFzeW5jLWl0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNy5zeW1ib2wub2JzZXJ2YWJsZScpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL19jb3JlJykuU3ltYm9sO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvZm4vc3ltYm9sL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAxMDBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fd2tzLWV4dCcpLmYoJ2l0ZXJhdG9yJyk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9mbi9zeW1ib2wvaXRlcmF0b3IuanNcbi8vIG1vZHVsZSBpZCA9IDEwMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCl7IC8qIGVtcHR5ICovIH07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19hZGQtdG8tdW5zY29wYWJsZXMuanNcbi8vIG1vZHVsZSBpZCA9IDEwMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCBDb25zdHJ1Y3RvciwgbmFtZSwgZm9yYmlkZGVuRmllbGQpe1xuICBpZighKGl0IGluc3RhbmNlb2YgQ29uc3RydWN0b3IpIHx8IChmb3JiaWRkZW5GaWVsZCAhPT0gdW5kZWZpbmVkICYmIGZvcmJpZGRlbkZpZWxkIGluIGl0KSl7XG4gICAgdGhyb3cgVHlwZUVycm9yKG5hbWUgKyAnOiBpbmNvcnJlY3QgaW52b2NhdGlvbiEnKTtcbiAgfSByZXR1cm4gaXQ7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fYW4taW5zdGFuY2UuanNcbi8vIG1vZHVsZSBpZCA9IDEwM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBmYWxzZSAtPiBBcnJheSNpbmRleE9mXG4vLyB0cnVlICAtPiBBcnJheSNpbmNsdWRlc1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKVxuICAsIHRvTGVuZ3RoICA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpXG4gICwgdG9JbmRleCAgID0gcmVxdWlyZSgnLi9fdG8taW5kZXgnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oSVNfSU5DTFVERVMpe1xuICByZXR1cm4gZnVuY3Rpb24oJHRoaXMsIGVsLCBmcm9tSW5kZXgpe1xuICAgIHZhciBPICAgICAgPSB0b0lPYmplY3QoJHRoaXMpXG4gICAgICAsIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKVxuICAgICAgLCBpbmRleCAgPSB0b0luZGV4KGZyb21JbmRleCwgbGVuZ3RoKVxuICAgICAgLCB2YWx1ZTtcbiAgICAvLyBBcnJheSNpbmNsdWRlcyB1c2VzIFNhbWVWYWx1ZVplcm8gZXF1YWxpdHkgYWxnb3JpdGhtXG4gICAgaWYoSVNfSU5DTFVERVMgJiYgZWwgIT0gZWwpd2hpbGUobGVuZ3RoID4gaW5kZXgpe1xuICAgICAgdmFsdWUgPSBPW2luZGV4KytdO1xuICAgICAgaWYodmFsdWUgIT0gdmFsdWUpcmV0dXJuIHRydWU7XG4gICAgLy8gQXJyYXkjdG9JbmRleCBpZ25vcmVzIGhvbGVzLCBBcnJheSNpbmNsdWRlcyAtIG5vdFxuICAgIH0gZWxzZSBmb3IoO2xlbmd0aCA+IGluZGV4OyBpbmRleCsrKWlmKElTX0lOQ0xVREVTIHx8IGluZGV4IGluIE8pe1xuICAgICAgaWYoT1tpbmRleF0gPT09IGVsKXJldHVybiBJU19JTkNMVURFUyB8fCBpbmRleCB8fCAwO1xuICAgIH0gcmV0dXJuICFJU19JTkNMVURFUyAmJiAtMTtcbiAgfTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19hcnJheS1pbmNsdWRlcy5qc1xuLy8gbW9kdWxlIGlkID0gMTA0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIid1c2Ugc3RyaWN0JztcbnZhciAkZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKVxuICAsIGNyZWF0ZURlc2MgICAgICA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvYmplY3QsIGluZGV4LCB2YWx1ZSl7XG4gIGlmKGluZGV4IGluIG9iamVjdCkkZGVmaW5lUHJvcGVydHkuZihvYmplY3QsIGluZGV4LCBjcmVhdGVEZXNjKDAsIHZhbHVlKSk7XG4gIGVsc2Ugb2JqZWN0W2luZGV4XSA9IHZhbHVlO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2NyZWF0ZS1wcm9wZXJ0eS5qc1xuLy8gbW9kdWxlIGlkID0gMTA1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIGFsbCBlbnVtZXJhYmxlIG9iamVjdCBrZXlzLCBpbmNsdWRlcyBzeW1ib2xzXG52YXIgZ2V0S2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJylcbiAgLCBnT1BTICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKVxuICAsIHBJRSAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgdmFyIHJlc3VsdCAgICAgPSBnZXRLZXlzKGl0KVxuICAgICwgZ2V0U3ltYm9scyA9IGdPUFMuZjtcbiAgaWYoZ2V0U3ltYm9scyl7XG4gICAgdmFyIHN5bWJvbHMgPSBnZXRTeW1ib2xzKGl0KVxuICAgICAgLCBpc0VudW0gID0gcElFLmZcbiAgICAgICwgaSAgICAgICA9IDBcbiAgICAgICwga2V5O1xuICAgIHdoaWxlKHN5bWJvbHMubGVuZ3RoID4gaSlpZihpc0VudW0uY2FsbChpdCwga2V5ID0gc3ltYm9sc1tpKytdKSlyZXN1bHQucHVzaChrZXkpO1xuICB9IHJldHVybiByZXN1bHQ7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fZW51bS1rZXlzLmpzXG4vLyBtb2R1bGUgaWQgPSAxMDZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGN0eCAgICAgICAgID0gcmVxdWlyZSgnLi9fY3R4JylcbiAgLCBjYWxsICAgICAgICA9IHJlcXVpcmUoJy4vX2l0ZXItY2FsbCcpXG4gICwgaXNBcnJheUl0ZXIgPSByZXF1aXJlKCcuL19pcy1hcnJheS1pdGVyJylcbiAgLCBhbk9iamVjdCAgICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgdG9MZW5ndGggICAgPSByZXF1aXJlKCcuL190by1sZW5ndGgnKVxuICAsIGdldEl0ZXJGbiAgID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKVxuICAsIEJSRUFLICAgICAgID0ge31cbiAgLCBSRVRVUk4gICAgICA9IHt9O1xudmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0ZXJhYmxlLCBlbnRyaWVzLCBmbiwgdGhhdCwgSVRFUkFUT1Ipe1xuICB2YXIgaXRlckZuID0gSVRFUkFUT1IgPyBmdW5jdGlvbigpeyByZXR1cm4gaXRlcmFibGU7IH0gOiBnZXRJdGVyRm4oaXRlcmFibGUpXG4gICAgLCBmICAgICAgPSBjdHgoZm4sIHRoYXQsIGVudHJpZXMgPyAyIDogMSlcbiAgICAsIGluZGV4ICA9IDBcbiAgICAsIGxlbmd0aCwgc3RlcCwgaXRlcmF0b3IsIHJlc3VsdDtcbiAgaWYodHlwZW9mIGl0ZXJGbiAhPSAnZnVuY3Rpb24nKXRocm93IFR5cGVFcnJvcihpdGVyYWJsZSArICcgaXMgbm90IGl0ZXJhYmxlIScpO1xuICAvLyBmYXN0IGNhc2UgZm9yIGFycmF5cyB3aXRoIGRlZmF1bHQgaXRlcmF0b3JcbiAgaWYoaXNBcnJheUl0ZXIoaXRlckZuKSlmb3IobGVuZ3RoID0gdG9MZW5ndGgoaXRlcmFibGUubGVuZ3RoKTsgbGVuZ3RoID4gaW5kZXg7IGluZGV4Kyspe1xuICAgIHJlc3VsdCA9IGVudHJpZXMgPyBmKGFuT2JqZWN0KHN0ZXAgPSBpdGVyYWJsZVtpbmRleF0pWzBdLCBzdGVwWzFdKSA6IGYoaXRlcmFibGVbaW5kZXhdKTtcbiAgICBpZihyZXN1bHQgPT09IEJSRUFLIHx8IHJlc3VsdCA9PT0gUkVUVVJOKXJldHVybiByZXN1bHQ7XG4gIH0gZWxzZSBmb3IoaXRlcmF0b3IgPSBpdGVyRm4uY2FsbChpdGVyYWJsZSk7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTsgKXtcbiAgICByZXN1bHQgPSBjYWxsKGl0ZXJhdG9yLCBmLCBzdGVwLnZhbHVlLCBlbnRyaWVzKTtcbiAgICBpZihyZXN1bHQgPT09IEJSRUFLIHx8IHJlc3VsdCA9PT0gUkVUVVJOKXJldHVybiByZXN1bHQ7XG4gIH1cbn07XG5leHBvcnRzLkJSRUFLICA9IEJSRUFLO1xuZXhwb3J0cy5SRVRVUk4gPSBSRVRVUk47XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19mb3Itb2YuanNcbi8vIG1vZHVsZSBpZCA9IDEwN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBmYXN0IGFwcGx5LCBodHRwOi8vanNwZXJmLmxua2l0LmNvbS9mYXN0LWFwcGx5LzVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm4sIGFyZ3MsIHRoYXQpe1xuICB2YXIgdW4gPSB0aGF0ID09PSB1bmRlZmluZWQ7XG4gIHN3aXRjaChhcmdzLmxlbmd0aCl7XG4gICAgY2FzZSAwOiByZXR1cm4gdW4gPyBmbigpXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQpO1xuICAgIGNhc2UgMTogcmV0dXJuIHVuID8gZm4oYXJnc1swXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSk7XG4gICAgY2FzZSAyOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICBjYXNlIDM6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgIGNhc2UgNDogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSk7XG4gIH0gcmV0dXJuICAgICAgICAgICAgICBmbi5hcHBseSh0aGF0LCBhcmdzKTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pbnZva2UuanNcbi8vIG1vZHVsZSBpZCA9IDEwOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyA3LjIuMiBJc0FycmF5KGFyZ3VtZW50KVxudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIGlzQXJyYXkoYXJnKXtcbiAgcmV0dXJuIGNvZihhcmcpID09ICdBcnJheSc7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9faXMtYXJyYXkuanNcbi8vIG1vZHVsZSBpZCA9IDEwOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG52YXIgY3JlYXRlICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtY3JlYXRlJylcbiAgLCBkZXNjcmlwdG9yICAgICA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKVxuICAsIHNldFRvU3RyaW5nVGFnID0gcmVxdWlyZSgnLi9fc2V0LXRvLXN0cmluZy10YWcnKVxuICAsIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XG5cbi8vIDI1LjEuMi4xLjEgJUl0ZXJhdG9yUHJvdG90eXBlJVtAQGl0ZXJhdG9yXSgpXG5yZXF1aXJlKCcuL19oaWRlJykoSXRlcmF0b3JQcm90b3R5cGUsIHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpLCBmdW5jdGlvbigpeyByZXR1cm4gdGhpczsgfSk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oQ29uc3RydWN0b3IsIE5BTUUsIG5leHQpe1xuICBDb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBjcmVhdGUoSXRlcmF0b3JQcm90b3R5cGUsIHtuZXh0OiBkZXNjcmlwdG9yKDEsIG5leHQpfSk7XG4gIHNldFRvU3RyaW5nVGFnKENvbnN0cnVjdG9yLCBOQU1FICsgJyBJdGVyYXRvcicpO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2l0ZXItY3JlYXRlLmpzXG4vLyBtb2R1bGUgaWQgPSAxMTBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihkb25lLCB2YWx1ZSl7XG4gIHJldHVybiB7dmFsdWU6IHZhbHVlLCBkb25lOiAhIWRvbmV9O1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2l0ZXItc3RlcC5qc1xuLy8gbW9kdWxlIGlkID0gMTExXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBnZXRLZXlzICAgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpXG4gICwgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvYmplY3QsIGVsKXtcbiAgdmFyIE8gICAgICA9IHRvSU9iamVjdChvYmplY3QpXG4gICAgLCBrZXlzICAgPSBnZXRLZXlzKE8pXG4gICAgLCBsZW5ndGggPSBrZXlzLmxlbmd0aFxuICAgICwgaW5kZXggID0gMFxuICAgICwga2V5O1xuICB3aGlsZShsZW5ndGggPiBpbmRleClpZihPW2tleSA9IGtleXNbaW5kZXgrK11dID09PSBlbClyZXR1cm4ga2V5O1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2tleW9mLmpzXG4vLyBtb2R1bGUgaWQgPSAxMTJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIE1FVEEgICAgID0gcmVxdWlyZSgnLi9fdWlkJykoJ21ldGEnKVxuICAsIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0JylcbiAgLCBoYXMgICAgICA9IHJlcXVpcmUoJy4vX2hhcycpXG4gICwgc2V0RGVzYyAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mXG4gICwgaWQgICAgICAgPSAwO1xudmFyIGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGUgfHwgZnVuY3Rpb24oKXtcbiAgcmV0dXJuIHRydWU7XG59O1xudmFyIEZSRUVaRSA9ICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uKCl7XG4gIHJldHVybiBpc0V4dGVuc2libGUoT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKHt9KSk7XG59KTtcbnZhciBzZXRNZXRhID0gZnVuY3Rpb24oaXQpe1xuICBzZXREZXNjKGl0LCBNRVRBLCB7dmFsdWU6IHtcbiAgICBpOiAnTycgKyArK2lkLCAvLyBvYmplY3QgSURcbiAgICB3OiB7fSAgICAgICAgICAvLyB3ZWFrIGNvbGxlY3Rpb25zIElEc1xuICB9fSk7XG59O1xudmFyIGZhc3RLZXkgPSBmdW5jdGlvbihpdCwgY3JlYXRlKXtcbiAgLy8gcmV0dXJuIHByaW1pdGl2ZSB3aXRoIHByZWZpeFxuICBpZighaXNPYmplY3QoaXQpKXJldHVybiB0eXBlb2YgaXQgPT0gJ3N5bWJvbCcgPyBpdCA6ICh0eXBlb2YgaXQgPT0gJ3N0cmluZycgPyAnUycgOiAnUCcpICsgaXQ7XG4gIGlmKCFoYXMoaXQsIE1FVEEpKXtcbiAgICAvLyBjYW4ndCBzZXQgbWV0YWRhdGEgdG8gdW5jYXVnaHQgZnJvemVuIG9iamVjdFxuICAgIGlmKCFpc0V4dGVuc2libGUoaXQpKXJldHVybiAnRic7XG4gICAgLy8gbm90IG5lY2Vzc2FyeSB0byBhZGQgbWV0YWRhdGFcbiAgICBpZighY3JlYXRlKXJldHVybiAnRSc7XG4gICAgLy8gYWRkIG1pc3NpbmcgbWV0YWRhdGFcbiAgICBzZXRNZXRhKGl0KTtcbiAgLy8gcmV0dXJuIG9iamVjdCBJRFxuICB9IHJldHVybiBpdFtNRVRBXS5pO1xufTtcbnZhciBnZXRXZWFrID0gZnVuY3Rpb24oaXQsIGNyZWF0ZSl7XG4gIGlmKCFoYXMoaXQsIE1FVEEpKXtcbiAgICAvLyBjYW4ndCBzZXQgbWV0YWRhdGEgdG8gdW5jYXVnaHQgZnJvemVuIG9iamVjdFxuICAgIGlmKCFpc0V4dGVuc2libGUoaXQpKXJldHVybiB0cnVlO1xuICAgIC8vIG5vdCBuZWNlc3NhcnkgdG8gYWRkIG1ldGFkYXRhXG4gICAgaWYoIWNyZWF0ZSlyZXR1cm4gZmFsc2U7XG4gICAgLy8gYWRkIG1pc3NpbmcgbWV0YWRhdGFcbiAgICBzZXRNZXRhKGl0KTtcbiAgLy8gcmV0dXJuIGhhc2ggd2VhayBjb2xsZWN0aW9ucyBJRHNcbiAgfSByZXR1cm4gaXRbTUVUQV0udztcbn07XG4vLyBhZGQgbWV0YWRhdGEgb24gZnJlZXplLWZhbWlseSBtZXRob2RzIGNhbGxpbmdcbnZhciBvbkZyZWV6ZSA9IGZ1bmN0aW9uKGl0KXtcbiAgaWYoRlJFRVpFICYmIG1ldGEuTkVFRCAmJiBpc0V4dGVuc2libGUoaXQpICYmICFoYXMoaXQsIE1FVEEpKXNldE1ldGEoaXQpO1xuICByZXR1cm4gaXQ7XG59O1xudmFyIG1ldGEgPSBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgS0VZOiAgICAgIE1FVEEsXG4gIE5FRUQ6ICAgICBmYWxzZSxcbiAgZmFzdEtleTogIGZhc3RLZXksXG4gIGdldFdlYWs6ICBnZXRXZWFrLFxuICBvbkZyZWV6ZTogb25GcmVlemVcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19tZXRhLmpzXG4vLyBtb2R1bGUgaWQgPSAxMTNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGdsb2JhbCAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgbWFjcm90YXNrID0gcmVxdWlyZSgnLi9fdGFzaycpLnNldFxuICAsIE9ic2VydmVyICA9IGdsb2JhbC5NdXRhdGlvbk9ic2VydmVyIHx8IGdsb2JhbC5XZWJLaXRNdXRhdGlvbk9ic2VydmVyXG4gICwgcHJvY2VzcyAgID0gZ2xvYmFsLnByb2Nlc3NcbiAgLCBQcm9taXNlICAgPSBnbG9iYWwuUHJvbWlzZVxuICAsIGlzTm9kZSAgICA9IHJlcXVpcmUoJy4vX2NvZicpKHByb2Nlc3MpID09ICdwcm9jZXNzJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpe1xuICB2YXIgaGVhZCwgbGFzdCwgbm90aWZ5O1xuXG4gIHZhciBmbHVzaCA9IGZ1bmN0aW9uKCl7XG4gICAgdmFyIHBhcmVudCwgZm47XG4gICAgaWYoaXNOb2RlICYmIChwYXJlbnQgPSBwcm9jZXNzLmRvbWFpbikpcGFyZW50LmV4aXQoKTtcbiAgICB3aGlsZShoZWFkKXtcbiAgICAgIGZuICAgPSBoZWFkLmZuO1xuICAgICAgaGVhZCA9IGhlYWQubmV4dDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGZuKCk7XG4gICAgICB9IGNhdGNoKGUpe1xuICAgICAgICBpZihoZWFkKW5vdGlmeSgpO1xuICAgICAgICBlbHNlIGxhc3QgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgfSBsYXN0ID0gdW5kZWZpbmVkO1xuICAgIGlmKHBhcmVudClwYXJlbnQuZW50ZXIoKTtcbiAgfTtcblxuICAvLyBOb2RlLmpzXG4gIGlmKGlzTm9kZSl7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24oKXtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soZmx1c2gpO1xuICAgIH07XG4gIC8vIGJyb3dzZXJzIHdpdGggTXV0YXRpb25PYnNlcnZlclxuICB9IGVsc2UgaWYoT2JzZXJ2ZXIpe1xuICAgIHZhciB0b2dnbGUgPSB0cnVlXG4gICAgICAsIG5vZGUgICA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcnKTtcbiAgICBuZXcgT2JzZXJ2ZXIoZmx1c2gpLm9ic2VydmUobm9kZSwge2NoYXJhY3RlckRhdGE6IHRydWV9KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICBub3RpZnkgPSBmdW5jdGlvbigpe1xuICAgICAgbm9kZS5kYXRhID0gdG9nZ2xlID0gIXRvZ2dsZTtcbiAgICB9O1xuICAvLyBlbnZpcm9ubWVudHMgd2l0aCBtYXliZSBub24tY29tcGxldGVseSBjb3JyZWN0LCBidXQgZXhpc3RlbnQgUHJvbWlzZVxuICB9IGVsc2UgaWYoUHJvbWlzZSAmJiBQcm9taXNlLnJlc29sdmUpe1xuICAgIHZhciBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24oKXtcbiAgICAgIHByb21pc2UudGhlbihmbHVzaCk7XG4gICAgfTtcbiAgLy8gZm9yIG90aGVyIGVudmlyb25tZW50cyAtIG1hY3JvdGFzayBiYXNlZCBvbjpcbiAgLy8gLSBzZXRJbW1lZGlhdGVcbiAgLy8gLSBNZXNzYWdlQ2hhbm5lbFxuICAvLyAtIHdpbmRvdy5wb3N0TWVzc2FnXG4gIC8vIC0gb25yZWFkeXN0YXRlY2hhbmdlXG4gIC8vIC0gc2V0VGltZW91dFxuICB9IGVsc2Uge1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uKCl7XG4gICAgICAvLyBzdHJhbmdlIElFICsgd2VicGFjayBkZXYgc2VydmVyIGJ1ZyAtIHVzZSAuY2FsbChnbG9iYWwpXG4gICAgICBtYWNyb3Rhc2suY2FsbChnbG9iYWwsIGZsdXNoKTtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGZuKXtcbiAgICB2YXIgdGFzayA9IHtmbjogZm4sIG5leHQ6IHVuZGVmaW5lZH07XG4gICAgaWYobGFzdClsYXN0Lm5leHQgPSB0YXNrO1xuICAgIGlmKCFoZWFkKXtcbiAgICAgIGhlYWQgPSB0YXNrO1xuICAgICAgbm90aWZ5KCk7XG4gICAgfSBsYXN0ID0gdGFzaztcbiAgfTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19taWNyb3Rhc2suanNcbi8vIG1vZHVsZSBpZCA9IDExNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG4vLyAxOS4xLjIuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlLCAuLi4pXG52YXIgZ2V0S2V5cyAgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpXG4gICwgZ09QUyAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wcycpXG4gICwgcElFICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJylcbiAgLCB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpXG4gICwgSU9iamVjdCAgPSByZXF1aXJlKCcuL19pb2JqZWN0JylcbiAgLCAkYXNzaWduICA9IE9iamVjdC5hc3NpZ247XG5cbi8vIHNob3VsZCB3b3JrIHdpdGggc3ltYm9scyBhbmQgc2hvdWxkIGhhdmUgZGV0ZXJtaW5pc3RpYyBwcm9wZXJ0eSBvcmRlciAoVjggYnVnKVxubW9kdWxlLmV4cG9ydHMgPSAhJGFzc2lnbiB8fCByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uKCl7XG4gIHZhciBBID0ge31cbiAgICAsIEIgPSB7fVxuICAgICwgUyA9IFN5bWJvbCgpXG4gICAgLCBLID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0JztcbiAgQVtTXSA9IDc7XG4gIEsuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24oayl7IEJba10gPSBrOyB9KTtcbiAgcmV0dXJuICRhc3NpZ24oe30sIEEpW1NdICE9IDcgfHwgT2JqZWN0LmtleXMoJGFzc2lnbih7fSwgQikpLmpvaW4oJycpICE9IEs7XG59KSA/IGZ1bmN0aW9uIGFzc2lnbih0YXJnZXQsIHNvdXJjZSl7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgdmFyIFQgICAgID0gdG9PYmplY3QodGFyZ2V0KVxuICAgICwgYUxlbiAgPSBhcmd1bWVudHMubGVuZ3RoXG4gICAgLCBpbmRleCA9IDFcbiAgICAsIGdldFN5bWJvbHMgPSBnT1BTLmZcbiAgICAsIGlzRW51bSAgICAgPSBwSUUuZjtcbiAgd2hpbGUoYUxlbiA+IGluZGV4KXtcbiAgICB2YXIgUyAgICAgID0gSU9iamVjdChhcmd1bWVudHNbaW5kZXgrK10pXG4gICAgICAsIGtleXMgICA9IGdldFN5bWJvbHMgPyBnZXRLZXlzKFMpLmNvbmNhdChnZXRTeW1ib2xzKFMpKSA6IGdldEtleXMoUylcbiAgICAgICwgbGVuZ3RoID0ga2V5cy5sZW5ndGhcbiAgICAgICwgaiAgICAgID0gMFxuICAgICAgLCBrZXk7XG4gICAgd2hpbGUobGVuZ3RoID4gailpZihpc0VudW0uY2FsbChTLCBrZXkgPSBrZXlzW2orK10pKVRba2V5XSA9IFNba2V5XTtcbiAgfSByZXR1cm4gVDtcbn0gOiAkYXNzaWduO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fb2JqZWN0LWFzc2lnbi5qc1xuLy8gbW9kdWxlIGlkID0gMTE1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBkUCAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpXG4gICwgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKVxuICAsIGdldEtleXMgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gT2JqZWN0LmRlZmluZVByb3BlcnRpZXMgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpe1xuICBhbk9iamVjdChPKTtcbiAgdmFyIGtleXMgICA9IGdldEtleXMoUHJvcGVydGllcylcbiAgICAsIGxlbmd0aCA9IGtleXMubGVuZ3RoXG4gICAgLCBpID0gMFxuICAgICwgUDtcbiAgd2hpbGUobGVuZ3RoID4gaSlkUC5mKE8sIFAgPSBrZXlzW2krK10sIFByb3BlcnRpZXNbUF0pO1xuICByZXR1cm4gTztcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19vYmplY3QtZHBzLmpzXG4vLyBtb2R1bGUgaWQgPSAxMTZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIHBJRSAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpXG4gICwgY3JlYXRlRGVzYyAgICAgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJylcbiAgLCB0b0lPYmplY3QgICAgICA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKVxuICAsIHRvUHJpbWl0aXZlICAgID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJylcbiAgLCBoYXMgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2hhcycpXG4gICwgSUU4X0RPTV9ERUZJTkUgPSByZXF1aXJlKCcuL19pZTgtZG9tLWRlZmluZScpXG4gICwgZ09QRCAgICAgICAgICAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xuXG5leHBvcnRzLmYgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gZ09QRCA6IGZ1bmN0aW9uIGdldE93blByb3BlcnR5RGVzY3JpcHRvcihPLCBQKXtcbiAgTyA9IHRvSU9iamVjdChPKTtcbiAgUCA9IHRvUHJpbWl0aXZlKFAsIHRydWUpO1xuICBpZihJRThfRE9NX0RFRklORSl0cnkge1xuICAgIHJldHVybiBnT1BEKE8sIFApO1xuICB9IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XG4gIGlmKGhhcyhPLCBQKSlyZXR1cm4gY3JlYXRlRGVzYyghcElFLmYuY2FsbChPLCBQKSwgT1tQXSk7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fb2JqZWN0LWdvcGQuanNcbi8vIG1vZHVsZSBpZCA9IDExN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBmYWxsYmFjayBmb3IgSUUxMSBidWdneSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB3aXRoIGlmcmFtZSBhbmQgd2luZG93XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpXG4gICwgZ09QTiAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKS5mXG4gICwgdG9TdHJpbmcgID0ge30udG9TdHJpbmc7XG5cbnZhciB3aW5kb3dOYW1lcyA9IHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCcgJiYgd2luZG93ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzXG4gID8gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMod2luZG93KSA6IFtdO1xuXG52YXIgZ2V0V2luZG93TmFtZXMgPSBmdW5jdGlvbihpdCl7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGdPUE4oaXQpO1xuICB9IGNhdGNoKGUpe1xuICAgIHJldHVybiB3aW5kb3dOYW1lcy5zbGljZSgpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5mID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhpdCl7XG4gIHJldHVybiB3aW5kb3dOYW1lcyAmJiB0b1N0cmluZy5jYWxsKGl0KSA9PSAnW29iamVjdCBXaW5kb3ddJyA/IGdldFdpbmRvd05hbWVzKGl0KSA6IGdPUE4odG9JT2JqZWN0KGl0KSk7XG59O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19vYmplY3QtZ29wbi1leHQuanNcbi8vIG1vZHVsZSBpZCA9IDExOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyAxOS4xLjIuOSAvIDE1LjIuMy4yIE9iamVjdC5nZXRQcm90b3R5cGVPZihPKVxudmFyIGhhcyAgICAgICAgID0gcmVxdWlyZSgnLi9faGFzJylcbiAgLCB0b09iamVjdCAgICA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpXG4gICwgSUVfUFJPVE8gICAgPSByZXF1aXJlKCcuL19zaGFyZWQta2V5JykoJ0lFX1BST1RPJylcbiAgLCBPYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmdldFByb3RvdHlwZU9mIHx8IGZ1bmN0aW9uKE8pe1xuICBPID0gdG9PYmplY3QoTyk7XG4gIGlmKGhhcyhPLCBJRV9QUk9UTykpcmV0dXJuIE9bSUVfUFJPVE9dO1xuICBpZih0eXBlb2YgTy5jb25zdHJ1Y3RvciA9PSAnZnVuY3Rpb24nICYmIE8gaW5zdGFuY2VvZiBPLmNvbnN0cnVjdG9yKXtcbiAgICByZXR1cm4gTy5jb25zdHJ1Y3Rvci5wcm90b3R5cGU7XG4gIH0gcmV0dXJuIE8gaW5zdGFuY2VvZiBPYmplY3QgPyBPYmplY3RQcm90byA6IG51bGw7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fb2JqZWN0LWdwby5qc1xuLy8gbW9kdWxlIGlkID0gMTE5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIG1vc3QgT2JqZWN0IG1ldGhvZHMgYnkgRVM2IHNob3VsZCBhY2NlcHQgcHJpbWl0aXZlc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIGNvcmUgICAgPSByZXF1aXJlKCcuL19jb3JlJylcbiAgLCBmYWlscyAgID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oS0VZLCBleGVjKXtcbiAgdmFyIGZuICA9IChjb3JlLk9iamVjdCB8fCB7fSlbS0VZXSB8fCBPYmplY3RbS0VZXVxuICAgICwgZXhwID0ge307XG4gIGV4cFtLRVldID0gZXhlYyhmbik7XG4gICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogZmFpbHMoZnVuY3Rpb24oKXsgZm4oMSk7IH0pLCAnT2JqZWN0JywgZXhwKTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19vYmplY3Qtc2FwLmpzXG4vLyBtb2R1bGUgaWQgPSAxMjBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHRhcmdldCwgc3JjLCBzYWZlKXtcbiAgZm9yKHZhciBrZXkgaW4gc3JjKXtcbiAgICBpZihzYWZlICYmIHRhcmdldFtrZXldKXRhcmdldFtrZXldID0gc3JjW2tleV07XG4gICAgZWxzZSBoaWRlKHRhcmdldCwga2V5LCBzcmNba2V5XSk7XG4gIH0gcmV0dXJuIHRhcmdldDtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19yZWRlZmluZS1hbGwuanNcbi8vIG1vZHVsZSBpZCA9IDEyMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsICAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIGNvcmUgICAgICAgID0gcmVxdWlyZSgnLi9fY29yZScpXG4gICwgZFAgICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKVxuICAsIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKVxuICAsIFNQRUNJRVMgICAgID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihLRVkpe1xuICB2YXIgQyA9IHR5cGVvZiBjb3JlW0tFWV0gPT0gJ2Z1bmN0aW9uJyA/IGNvcmVbS0VZXSA6IGdsb2JhbFtLRVldO1xuICBpZihERVNDUklQVE9SUyAmJiBDICYmICFDW1NQRUNJRVNdKWRQLmYoQywgU1BFQ0lFUywge1xuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzOyB9XG4gIH0pO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3NldC1zcGVjaWVzLmpzXG4vLyBtb2R1bGUgaWQgPSAxMjJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gNy4zLjIwIFNwZWNpZXNDb25zdHJ1Y3RvcihPLCBkZWZhdWx0Q29uc3RydWN0b3IpXG52YXIgYW5PYmplY3QgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJylcbiAgLCBTUEVDSUVTICAgPSByZXF1aXJlKCcuL193a3MnKSgnc3BlY2llcycpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihPLCBEKXtcbiAgdmFyIEMgPSBhbk9iamVjdChPKS5jb25zdHJ1Y3RvciwgUztcbiAgcmV0dXJuIEMgPT09IHVuZGVmaW5lZCB8fCAoUyA9IGFuT2JqZWN0KEMpW1NQRUNJRVNdKSA9PSB1bmRlZmluZWQgPyBEIDogYUZ1bmN0aW9uKFMpO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3NwZWNpZXMtY29uc3RydWN0b3IuanNcbi8vIG1vZHVsZSBpZCA9IDEyM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpXG4gICwgZGVmaW5lZCAgID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuLy8gdHJ1ZSAgLT4gU3RyaW5nI2F0XG4vLyBmYWxzZSAtPiBTdHJpbmcjY29kZVBvaW50QXRcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oVE9fU1RSSU5HKXtcbiAgcmV0dXJuIGZ1bmN0aW9uKHRoYXQsIHBvcyl7XG4gICAgdmFyIHMgPSBTdHJpbmcoZGVmaW5lZCh0aGF0KSlcbiAgICAgICwgaSA9IHRvSW50ZWdlcihwb3MpXG4gICAgICAsIGwgPSBzLmxlbmd0aFxuICAgICAgLCBhLCBiO1xuICAgIGlmKGkgPCAwIHx8IGkgPj0gbClyZXR1cm4gVE9fU1RSSU5HID8gJycgOiB1bmRlZmluZWQ7XG4gICAgYSA9IHMuY2hhckNvZGVBdChpKTtcbiAgICByZXR1cm4gYSA8IDB4ZDgwMCB8fCBhID4gMHhkYmZmIHx8IGkgKyAxID09PSBsIHx8IChiID0gcy5jaGFyQ29kZUF0KGkgKyAxKSkgPCAweGRjMDAgfHwgYiA+IDB4ZGZmZlxuICAgICAgPyBUT19TVFJJTkcgPyBzLmNoYXJBdChpKSA6IGFcbiAgICAgIDogVE9fU1RSSU5HID8gcy5zbGljZShpLCBpICsgMikgOiAoYSAtIDB4ZDgwMCA8PCAxMCkgKyAoYiAtIDB4ZGMwMCkgKyAweDEwMDAwO1xuICB9O1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX3N0cmluZy1hdC5qc1xuLy8gbW9kdWxlIGlkID0gMTI0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJylcbiAgLCBtYXggICAgICAgPSBNYXRoLm1heFxuICAsIG1pbiAgICAgICA9IE1hdGgubWluO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpbmRleCwgbGVuZ3RoKXtcbiAgaW5kZXggPSB0b0ludGVnZXIoaW5kZXgpO1xuICByZXR1cm4gaW5kZXggPCAwID8gbWF4KGluZGV4ICsgbGVuZ3RoLCAwKSA6IG1pbihpbmRleCwgbGVuZ3RoKTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL190by1pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gMTI1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgZ2V0ICAgICAgPSByZXF1aXJlKCcuL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZCcpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19jb3JlJykuZ2V0SXRlcmF0b3IgPSBmdW5jdGlvbihpdCl7XG4gIHZhciBpdGVyRm4gPSBnZXQoaXQpO1xuICBpZih0eXBlb2YgaXRlckZuICE9ICdmdW5jdGlvbicpdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgaXRlcmFibGUhJyk7XG4gIHJldHVybiBhbk9iamVjdChpdGVyRm4uY2FsbChpdCkpO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvY29yZS5nZXQtaXRlcmF0b3IuanNcbi8vIG1vZHVsZSBpZCA9IDEyNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgY2xhc3NvZiAgID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpXG4gICwgSVRFUkFUT1IgID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJylcbiAgLCBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29yZScpLmlzSXRlcmFibGUgPSBmdW5jdGlvbihpdCl7XG4gIHZhciBPID0gT2JqZWN0KGl0KTtcbiAgcmV0dXJuIE9bSVRFUkFUT1JdICE9PSB1bmRlZmluZWRcbiAgICB8fCAnQEBpdGVyYXRvcicgaW4gT1xuICAgIHx8IEl0ZXJhdG9ycy5oYXNPd25Qcm9wZXJ0eShjbGFzc29mKE8pKTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2NvcmUuaXMtaXRlcmFibGUuanNcbi8vIG1vZHVsZSBpZCA9IDEyN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG52YXIgY3R4ICAgICAgICAgICAgPSByZXF1aXJlKCcuL19jdHgnKVxuICAsICRleHBvcnQgICAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCB0b09iamVjdCAgICAgICA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpXG4gICwgY2FsbCAgICAgICAgICAgPSByZXF1aXJlKCcuL19pdGVyLWNhbGwnKVxuICAsIGlzQXJyYXlJdGVyICAgID0gcmVxdWlyZSgnLi9faXMtYXJyYXktaXRlcicpXG4gICwgdG9MZW5ndGggICAgICAgPSByZXF1aXJlKCcuL190by1sZW5ndGgnKVxuICAsIGNyZWF0ZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fY3JlYXRlLXByb3BlcnR5JylcbiAgLCBnZXRJdGVyRm4gICAgICA9IHJlcXVpcmUoJy4vY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX2l0ZXItZGV0ZWN0JykoZnVuY3Rpb24oaXRlcil7IEFycmF5LmZyb20oaXRlcik7IH0pLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMi4xIEFycmF5LmZyb20oYXJyYXlMaWtlLCBtYXBmbiA9IHVuZGVmaW5lZCwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbiAgZnJvbTogZnVuY3Rpb24gZnJvbShhcnJheUxpa2UvKiwgbWFwZm4gPSB1bmRlZmluZWQsIHRoaXNBcmcgPSB1bmRlZmluZWQqLyl7XG4gICAgdmFyIE8gICAgICAgPSB0b09iamVjdChhcnJheUxpa2UpXG4gICAgICAsIEMgICAgICAgPSB0eXBlb2YgdGhpcyA9PSAnZnVuY3Rpb24nID8gdGhpcyA6IEFycmF5XG4gICAgICAsIGFMZW4gICAgPSBhcmd1bWVudHMubGVuZ3RoXG4gICAgICAsIG1hcGZuICAgPSBhTGVuID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZFxuICAgICAgLCBtYXBwaW5nID0gbWFwZm4gIT09IHVuZGVmaW5lZFxuICAgICAgLCBpbmRleCAgID0gMFxuICAgICAgLCBpdGVyRm4gID0gZ2V0SXRlckZuKE8pXG4gICAgICAsIGxlbmd0aCwgcmVzdWx0LCBzdGVwLCBpdGVyYXRvcjtcbiAgICBpZihtYXBwaW5nKW1hcGZuID0gY3R4KG1hcGZuLCBhTGVuID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZCwgMik7XG4gICAgLy8gaWYgb2JqZWN0IGlzbid0IGl0ZXJhYmxlIG9yIGl0J3MgYXJyYXkgd2l0aCBkZWZhdWx0IGl0ZXJhdG9yIC0gdXNlIHNpbXBsZSBjYXNlXG4gICAgaWYoaXRlckZuICE9IHVuZGVmaW5lZCAmJiAhKEMgPT0gQXJyYXkgJiYgaXNBcnJheUl0ZXIoaXRlckZuKSkpe1xuICAgICAgZm9yKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoTyksIHJlc3VsdCA9IG5ldyBDOyAhKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmU7IGluZGV4Kyspe1xuICAgICAgICBjcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGluZGV4LCBtYXBwaW5nID8gY2FsbChpdGVyYXRvciwgbWFwZm4sIFtzdGVwLnZhbHVlLCBpbmRleF0sIHRydWUpIDogc3RlcC52YWx1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgICAgIGZvcihyZXN1bHQgPSBuZXcgQyhsZW5ndGgpOyBsZW5ndGggPiBpbmRleDsgaW5kZXgrKyl7XG4gICAgICAgIGNyZWF0ZVByb3BlcnR5KHJlc3VsdCwgaW5kZXgsIG1hcHBpbmcgPyBtYXBmbihPW2luZGV4XSwgaW5kZXgpIDogT1tpbmRleF0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXN1bHQubGVuZ3RoID0gaW5kZXg7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufSk7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM2LmFycmF5LmZyb20uanNcbi8vIG1vZHVsZSBpZCA9IDEyOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG52YXIgYWRkVG9VbnNjb3BhYmxlcyA9IHJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpXG4gICwgc3RlcCAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2l0ZXItc3RlcCcpXG4gICwgSXRlcmF0b3JzICAgICAgICA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpXG4gICwgdG9JT2JqZWN0ICAgICAgICA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcblxuLy8gMjIuMS4zLjQgQXJyYXkucHJvdG90eXBlLmVudHJpZXMoKVxuLy8gMjIuMS4zLjEzIEFycmF5LnByb3RvdHlwZS5rZXlzKClcbi8vIDIyLjEuMy4yOSBBcnJheS5wcm90b3R5cGUudmFsdWVzKClcbi8vIDIyLjEuMy4zMCBBcnJheS5wcm90b3R5cGVbQEBpdGVyYXRvcl0oKVxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19pdGVyLWRlZmluZScpKEFycmF5LCAnQXJyYXknLCBmdW5jdGlvbihpdGVyYXRlZCwga2luZCl7XG4gIHRoaXMuX3QgPSB0b0lPYmplY3QoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbiAgdGhpcy5fayA9IGtpbmQ7ICAgICAgICAgICAgICAgIC8vIGtpbmRcbi8vIDIyLjEuNS4yLjEgJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlLm5leHQoKVxufSwgZnVuY3Rpb24oKXtcbiAgdmFyIE8gICAgID0gdGhpcy5fdFxuICAgICwga2luZCAgPSB0aGlzLl9rXG4gICAgLCBpbmRleCA9IHRoaXMuX2krKztcbiAgaWYoIU8gfHwgaW5kZXggPj0gTy5sZW5ndGgpe1xuICAgIHRoaXMuX3QgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHN0ZXAoMSk7XG4gIH1cbiAgaWYoa2luZCA9PSAna2V5cycgIClyZXR1cm4gc3RlcCgwLCBpbmRleCk7XG4gIGlmKGtpbmQgPT0gJ3ZhbHVlcycpcmV0dXJuIHN0ZXAoMCwgT1tpbmRleF0pO1xuICByZXR1cm4gc3RlcCgwLCBbaW5kZXgsIE9baW5kZXhdXSk7XG59LCAndmFsdWVzJyk7XG5cbi8vIGFyZ3VtZW50c0xpc3RbQEBpdGVyYXRvcl0gaXMgJUFycmF5UHJvdG9fdmFsdWVzJSAoOS40LjQuNiwgOS40LjQuNylcbkl0ZXJhdG9ycy5Bcmd1bWVudHMgPSBJdGVyYXRvcnMuQXJyYXk7XG5cbmFkZFRvVW5zY29wYWJsZXMoJ2tleXMnKTtcbmFkZFRvVW5zY29wYWJsZXMoJ3ZhbHVlcycpO1xuYWRkVG9VbnNjb3BhYmxlcygnZW50cmllcycpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYuYXJyYXkuaXRlcmF0b3IuanNcbi8vIG1vZHVsZSBpZCA9IDEyOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyAyMC4yLjIuMjIgTWF0aC5sb2cyKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGxvZzI6IGZ1bmN0aW9uIGxvZzIoeCl7XG4gICAgcmV0dXJuIE1hdGgubG9nKHgpIC8gTWF0aC5MTjI7XG4gIH1cbn0pO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYubWF0aC5sb2cyLmpzXG4vLyBtb2R1bGUgaWQgPSAxMzBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gMTkuMS4zLjEgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHNvdXJjZSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GLCAnT2JqZWN0Jywge2Fzc2lnbjogcmVxdWlyZSgnLi9fb2JqZWN0LWFzc2lnbicpfSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5vYmplY3QuYXNzaWduLmpzXG4vLyBtb2R1bGUgaWQgPSAxMzFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gMTkuMS4yLjE0IE9iamVjdC5rZXlzKE8pXG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKVxuICAsICRrZXlzICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcblxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdrZXlzJywgZnVuY3Rpb24oKXtcbiAgcmV0dXJuIGZ1bmN0aW9uIGtleXMoaXQpe1xuICAgIHJldHVybiAka2V5cyh0b09iamVjdChpdCkpO1xuICB9O1xufSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5vYmplY3Qua2V5cy5qc1xuLy8gbW9kdWxlIGlkID0gMTMyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIid1c2Ugc3RyaWN0JztcbnZhciBMSUJSQVJZICAgICAgICAgICAgPSByZXF1aXJlKCcuL19saWJyYXJ5JylcbiAgLCBnbG9iYWwgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIGN0eCAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2N0eCcpXG4gICwgY2xhc3NvZiAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpXG4gICwgJGV4cG9ydCAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCBpc09iamVjdCAgICAgICAgICAgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIGFGdW5jdGlvbiAgICAgICAgICA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKVxuICAsIGFuSW5zdGFuY2UgICAgICAgICA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJylcbiAgLCBmb3JPZiAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19mb3Itb2YnKVxuICAsIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4vX3NwZWNpZXMtY29uc3RydWN0b3InKVxuICAsIHRhc2sgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX3Rhc2snKS5zZXRcbiAgLCBtaWNyb3Rhc2sgICAgICAgICAgPSByZXF1aXJlKCcuL19taWNyb3Rhc2snKSgpXG4gICwgUFJPTUlTRSAgICAgICAgICAgID0gJ1Byb21pc2UnXG4gICwgVHlwZUVycm9yICAgICAgICAgID0gZ2xvYmFsLlR5cGVFcnJvclxuICAsIHByb2Nlc3MgICAgICAgICAgICA9IGdsb2JhbC5wcm9jZXNzXG4gICwgJFByb21pc2UgICAgICAgICAgID0gZ2xvYmFsW1BST01JU0VdXG4gICwgcHJvY2VzcyAgICAgICAgICAgID0gZ2xvYmFsLnByb2Nlc3NcbiAgLCBpc05vZGUgICAgICAgICAgICAgPSBjbGFzc29mKHByb2Nlc3MpID09ICdwcm9jZXNzJ1xuICAsIGVtcHR5ICAgICAgICAgICAgICA9IGZ1bmN0aW9uKCl7IC8qIGVtcHR5ICovIH1cbiAgLCBJbnRlcm5hbCwgR2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5LCBXcmFwcGVyO1xuXG52YXIgVVNFX05BVElWRSA9ICEhZnVuY3Rpb24oKXtcbiAgdHJ5IHtcbiAgICAvLyBjb3JyZWN0IHN1YmNsYXNzaW5nIHdpdGggQEBzcGVjaWVzIHN1cHBvcnRcbiAgICB2YXIgcHJvbWlzZSAgICAgPSAkUHJvbWlzZS5yZXNvbHZlKDEpXG4gICAgICAsIEZha2VQcm9taXNlID0gKHByb21pc2UuY29uc3RydWN0b3IgPSB7fSlbcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKV0gPSBmdW5jdGlvbihleGVjKXsgZXhlYyhlbXB0eSwgZW1wdHkpOyB9O1xuICAgIC8vIHVuaGFuZGxlZCByZWplY3Rpb25zIHRyYWNraW5nIHN1cHBvcnQsIE5vZGVKUyBQcm9taXNlIHdpdGhvdXQgaXQgZmFpbHMgQEBzcGVjaWVzIHRlc3RcbiAgICByZXR1cm4gKGlzTm9kZSB8fCB0eXBlb2YgUHJvbWlzZVJlamVjdGlvbkV2ZW50ID09ICdmdW5jdGlvbicpICYmIHByb21pc2UudGhlbihlbXB0eSkgaW5zdGFuY2VvZiBGYWtlUHJvbWlzZTtcbiAgfSBjYXRjaChlKXsgLyogZW1wdHkgKi8gfVxufSgpO1xuXG4vLyBoZWxwZXJzXG52YXIgc2FtZUNvbnN0cnVjdG9yID0gZnVuY3Rpb24oYSwgYil7XG4gIC8vIHdpdGggbGlicmFyeSB3cmFwcGVyIHNwZWNpYWwgY2FzZVxuICByZXR1cm4gYSA9PT0gYiB8fCBhID09PSAkUHJvbWlzZSAmJiBiID09PSBXcmFwcGVyO1xufTtcbnZhciBpc1RoZW5hYmxlID0gZnVuY3Rpb24oaXQpe1xuICB2YXIgdGhlbjtcbiAgcmV0dXJuIGlzT2JqZWN0KGl0KSAmJiB0eXBlb2YgKHRoZW4gPSBpdC50aGVuKSA9PSAnZnVuY3Rpb24nID8gdGhlbiA6IGZhbHNlO1xufTtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uKEMpe1xuICByZXR1cm4gc2FtZUNvbnN0cnVjdG9yKCRQcm9taXNlLCBDKVxuICAgID8gbmV3IFByb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgOiBuZXcgR2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5KEMpO1xufTtcbnZhciBQcm9taXNlQ2FwYWJpbGl0eSA9IEdlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uKEMpe1xuICB2YXIgcmVzb2x2ZSwgcmVqZWN0O1xuICB0aGlzLnByb21pc2UgPSBuZXcgQyhmdW5jdGlvbigkJHJlc29sdmUsICQkcmVqZWN0KXtcbiAgICBpZihyZXNvbHZlICE9PSB1bmRlZmluZWQgfHwgcmVqZWN0ICE9PSB1bmRlZmluZWQpdGhyb3cgVHlwZUVycm9yKCdCYWQgUHJvbWlzZSBjb25zdHJ1Y3RvcicpO1xuICAgIHJlc29sdmUgPSAkJHJlc29sdmU7XG4gICAgcmVqZWN0ICA9ICQkcmVqZWN0O1xuICB9KTtcbiAgdGhpcy5yZXNvbHZlID0gYUZ1bmN0aW9uKHJlc29sdmUpO1xuICB0aGlzLnJlamVjdCAgPSBhRnVuY3Rpb24ocmVqZWN0KTtcbn07XG52YXIgcGVyZm9ybSA9IGZ1bmN0aW9uKGV4ZWMpe1xuICB0cnkge1xuICAgIGV4ZWMoKTtcbiAgfSBjYXRjaChlKXtcbiAgICByZXR1cm4ge2Vycm9yOiBlfTtcbiAgfVxufTtcbnZhciBub3RpZnkgPSBmdW5jdGlvbihwcm9taXNlLCBpc1JlamVjdCl7XG4gIGlmKHByb21pc2UuX24pcmV0dXJuO1xuICBwcm9taXNlLl9uID0gdHJ1ZTtcbiAgdmFyIGNoYWluID0gcHJvbWlzZS5fYztcbiAgbWljcm90YXNrKGZ1bmN0aW9uKCl7XG4gICAgdmFyIHZhbHVlID0gcHJvbWlzZS5fdlxuICAgICAgLCBvayAgICA9IHByb21pc2UuX3MgPT0gMVxuICAgICAgLCBpICAgICA9IDA7XG4gICAgdmFyIHJ1biA9IGZ1bmN0aW9uKHJlYWN0aW9uKXtcbiAgICAgIHZhciBoYW5kbGVyID0gb2sgPyByZWFjdGlvbi5vayA6IHJlYWN0aW9uLmZhaWxcbiAgICAgICAgLCByZXNvbHZlID0gcmVhY3Rpb24ucmVzb2x2ZVxuICAgICAgICAsIHJlamVjdCAgPSByZWFjdGlvbi5yZWplY3RcbiAgICAgICAgLCBkb21haW4gID0gcmVhY3Rpb24uZG9tYWluXG4gICAgICAgICwgcmVzdWx0LCB0aGVuO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYoaGFuZGxlcil7XG4gICAgICAgICAgaWYoIW9rKXtcbiAgICAgICAgICAgIGlmKHByb21pc2UuX2ggPT0gMilvbkhhbmRsZVVuaGFuZGxlZChwcm9taXNlKTtcbiAgICAgICAgICAgIHByb21pc2UuX2ggPSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZihoYW5kbGVyID09PSB0cnVlKXJlc3VsdCA9IHZhbHVlO1xuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYoZG9tYWluKWRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgcmVzdWx0ID0gaGFuZGxlcih2YWx1ZSk7XG4gICAgICAgICAgICBpZihkb21haW4pZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYocmVzdWx0ID09PSByZWFjdGlvbi5wcm9taXNlKXtcbiAgICAgICAgICAgIHJlamVjdChUeXBlRXJyb3IoJ1Byb21pc2UtY2hhaW4gY3ljbGUnKSk7XG4gICAgICAgICAgfSBlbHNlIGlmKHRoZW4gPSBpc1RoZW5hYmxlKHJlc3VsdCkpe1xuICAgICAgICAgICAgdGhlbi5jYWxsKHJlc3VsdCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICB9IGVsc2UgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGVsc2UgcmVqZWN0KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHdoaWxlKGNoYWluLmxlbmd0aCA+IGkpcnVuKGNoYWluW2krK10pOyAvLyB2YXJpYWJsZSBsZW5ndGggLSBjYW4ndCB1c2UgZm9yRWFjaFxuICAgIHByb21pc2UuX2MgPSBbXTtcbiAgICBwcm9taXNlLl9uID0gZmFsc2U7XG4gICAgaWYoaXNSZWplY3QgJiYgIXByb21pc2UuX2gpb25VbmhhbmRsZWQocHJvbWlzZSk7XG4gIH0pO1xufTtcbnZhciBvblVuaGFuZGxlZCA9IGZ1bmN0aW9uKHByb21pc2Upe1xuICB0YXNrLmNhbGwoZ2xvYmFsLCBmdW5jdGlvbigpe1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3ZcbiAgICAgICwgYWJydXB0LCBoYW5kbGVyLCBjb25zb2xlO1xuICAgIGlmKGlzVW5oYW5kbGVkKHByb21pc2UpKXtcbiAgICAgIGFicnVwdCA9IHBlcmZvcm0oZnVuY3Rpb24oKXtcbiAgICAgICAgaWYoaXNOb2RlKXtcbiAgICAgICAgICBwcm9jZXNzLmVtaXQoJ3VuaGFuZGxlZFJlamVjdGlvbicsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGlmKGhhbmRsZXIgPSBnbG9iYWwub251bmhhbmRsZWRyZWplY3Rpb24pe1xuICAgICAgICAgIGhhbmRsZXIoe3Byb21pc2U6IHByb21pc2UsIHJlYXNvbjogdmFsdWV9KTtcbiAgICAgICAgfSBlbHNlIGlmKChjb25zb2xlID0gZ2xvYmFsLmNvbnNvbGUpICYmIGNvbnNvbGUuZXJyb3Ipe1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1VuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbicsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBCcm93c2VycyBzaG91bGQgbm90IHRyaWdnZXIgYHJlamVjdGlvbkhhbmRsZWRgIGV2ZW50IGlmIGl0IHdhcyBoYW5kbGVkIGhlcmUsIE5vZGVKUyAtIHNob3VsZFxuICAgICAgcHJvbWlzZS5faCA9IGlzTm9kZSB8fCBpc1VuaGFuZGxlZChwcm9taXNlKSA/IDIgOiAxO1xuICAgIH0gcHJvbWlzZS5fYSA9IHVuZGVmaW5lZDtcbiAgICBpZihhYnJ1cHQpdGhyb3cgYWJydXB0LmVycm9yO1xuICB9KTtcbn07XG52YXIgaXNVbmhhbmRsZWQgPSBmdW5jdGlvbihwcm9taXNlKXtcbiAgaWYocHJvbWlzZS5faCA9PSAxKXJldHVybiBmYWxzZTtcbiAgdmFyIGNoYWluID0gcHJvbWlzZS5fYSB8fCBwcm9taXNlLl9jXG4gICAgLCBpICAgICA9IDBcbiAgICAsIHJlYWN0aW9uO1xuICB3aGlsZShjaGFpbi5sZW5ndGggPiBpKXtcbiAgICByZWFjdGlvbiA9IGNoYWluW2krK107XG4gICAgaWYocmVhY3Rpb24uZmFpbCB8fCAhaXNVbmhhbmRsZWQocmVhY3Rpb24ucHJvbWlzZSkpcmV0dXJuIGZhbHNlO1xuICB9IHJldHVybiB0cnVlO1xufTtcbnZhciBvbkhhbmRsZVVuaGFuZGxlZCA9IGZ1bmN0aW9uKHByb21pc2Upe1xuICB0YXNrLmNhbGwoZ2xvYmFsLCBmdW5jdGlvbigpe1xuICAgIHZhciBoYW5kbGVyO1xuICAgIGlmKGlzTm9kZSl7XG4gICAgICBwcm9jZXNzLmVtaXQoJ3JlamVjdGlvbkhhbmRsZWQnLCBwcm9taXNlKTtcbiAgICB9IGVsc2UgaWYoaGFuZGxlciA9IGdsb2JhbC5vbnJlamVjdGlvbmhhbmRsZWQpe1xuICAgICAgaGFuZGxlcih7cHJvbWlzZTogcHJvbWlzZSwgcmVhc29uOiBwcm9taXNlLl92fSk7XG4gICAgfVxuICB9KTtcbn07XG52YXIgJHJlamVjdCA9IGZ1bmN0aW9uKHZhbHVlKXtcbiAgdmFyIHByb21pc2UgPSB0aGlzO1xuICBpZihwcm9taXNlLl9kKXJldHVybjtcbiAgcHJvbWlzZS5fZCA9IHRydWU7XG4gIHByb21pc2UgPSBwcm9taXNlLl93IHx8IHByb21pc2U7IC8vIHVud3JhcFxuICBwcm9taXNlLl92ID0gdmFsdWU7XG4gIHByb21pc2UuX3MgPSAyO1xuICBpZighcHJvbWlzZS5fYSlwcm9taXNlLl9hID0gcHJvbWlzZS5fYy5zbGljZSgpO1xuICBub3RpZnkocHJvbWlzZSwgdHJ1ZSk7XG59O1xudmFyICRyZXNvbHZlID0gZnVuY3Rpb24odmFsdWUpe1xuICB2YXIgcHJvbWlzZSA9IHRoaXNcbiAgICAsIHRoZW47XG4gIGlmKHByb21pc2UuX2QpcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHRyeSB7XG4gICAgaWYocHJvbWlzZSA9PT0gdmFsdWUpdGhyb3cgVHlwZUVycm9yKFwiUHJvbWlzZSBjYW4ndCBiZSByZXNvbHZlZCBpdHNlbGZcIik7XG4gICAgaWYodGhlbiA9IGlzVGhlbmFibGUodmFsdWUpKXtcbiAgICAgIG1pY3JvdGFzayhmdW5jdGlvbigpe1xuICAgICAgICB2YXIgd3JhcHBlciA9IHtfdzogcHJvbWlzZSwgX2Q6IGZhbHNlfTsgLy8gd3JhcFxuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoZW4uY2FsbCh2YWx1ZSwgY3R4KCRyZXNvbHZlLCB3cmFwcGVyLCAxKSwgY3R4KCRyZWplY3QsIHdyYXBwZXIsIDEpKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAkcmVqZWN0LmNhbGwod3JhcHBlciwgZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9taXNlLl92ID0gdmFsdWU7XG4gICAgICBwcm9taXNlLl9zID0gMTtcbiAgICAgIG5vdGlmeShwcm9taXNlLCBmYWxzZSk7XG4gICAgfVxuICB9IGNhdGNoKGUpe1xuICAgICRyZWplY3QuY2FsbCh7X3c6IHByb21pc2UsIF9kOiBmYWxzZX0sIGUpOyAvLyB3cmFwXG4gIH1cbn07XG5cbi8vIGNvbnN0cnVjdG9yIHBvbHlmaWxsXG5pZighVVNFX05BVElWRSl7XG4gIC8vIDI1LjQuMy4xIFByb21pc2UoZXhlY3V0b3IpXG4gICRQcm9taXNlID0gZnVuY3Rpb24gUHJvbWlzZShleGVjdXRvcil7XG4gICAgYW5JbnN0YW5jZSh0aGlzLCAkUHJvbWlzZSwgUFJPTUlTRSwgJ19oJyk7XG4gICAgYUZ1bmN0aW9uKGV4ZWN1dG9yKTtcbiAgICBJbnRlcm5hbC5jYWxsKHRoaXMpO1xuICAgIHRyeSB7XG4gICAgICBleGVjdXRvcihjdHgoJHJlc29sdmUsIHRoaXMsIDEpLCBjdHgoJHJlamVjdCwgdGhpcywgMSkpO1xuICAgIH0gY2F0Y2goZXJyKXtcbiAgICAgICRyZWplY3QuY2FsbCh0aGlzLCBlcnIpO1xuICAgIH1cbiAgfTtcbiAgSW50ZXJuYWwgPSBmdW5jdGlvbiBQcm9taXNlKGV4ZWN1dG9yKXtcbiAgICB0aGlzLl9jID0gW107ICAgICAgICAgICAgIC8vIDwtIGF3YWl0aW5nIHJlYWN0aW9uc1xuICAgIHRoaXMuX2EgPSB1bmRlZmluZWQ7ICAgICAgLy8gPC0gY2hlY2tlZCBpbiBpc1VuaGFuZGxlZCByZWFjdGlvbnNcbiAgICB0aGlzLl9zID0gMDsgICAgICAgICAgICAgIC8vIDwtIHN0YXRlXG4gICAgdGhpcy5fZCA9IGZhbHNlOyAgICAgICAgICAvLyA8LSBkb25lXG4gICAgdGhpcy5fdiA9IHVuZGVmaW5lZDsgICAgICAvLyA8LSB2YWx1ZVxuICAgIHRoaXMuX2ggPSAwOyAgICAgICAgICAgICAgLy8gPC0gcmVqZWN0aW9uIHN0YXRlLCAwIC0gZGVmYXVsdCwgMSAtIGhhbmRsZWQsIDIgLSB1bmhhbmRsZWRcbiAgICB0aGlzLl9uID0gZmFsc2U7ICAgICAgICAgIC8vIDwtIG5vdGlmeVxuICB9O1xuICBJbnRlcm5hbC5wcm90b3R5cGUgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKSgkUHJvbWlzZS5wcm90b3R5cGUsIHtcbiAgICAvLyAyNS40LjUuMyBQcm9taXNlLnByb3RvdHlwZS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKVxuICAgIHRoZW46IGZ1bmN0aW9uIHRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpe1xuICAgICAgdmFyIHJlYWN0aW9uICAgID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkoc3BlY2llc0NvbnN0cnVjdG9yKHRoaXMsICRQcm9taXNlKSk7XG4gICAgICByZWFjdGlvbi5vayAgICAgPSB0eXBlb2Ygb25GdWxmaWxsZWQgPT0gJ2Z1bmN0aW9uJyA/IG9uRnVsZmlsbGVkIDogdHJ1ZTtcbiAgICAgIHJlYWN0aW9uLmZhaWwgICA9IHR5cGVvZiBvblJlamVjdGVkID09ICdmdW5jdGlvbicgJiYgb25SZWplY3RlZDtcbiAgICAgIHJlYWN0aW9uLmRvbWFpbiA9IGlzTm9kZSA/IHByb2Nlc3MuZG9tYWluIDogdW5kZWZpbmVkO1xuICAgICAgdGhpcy5fYy5wdXNoKHJlYWN0aW9uKTtcbiAgICAgIGlmKHRoaXMuX2EpdGhpcy5fYS5wdXNoKHJlYWN0aW9uKTtcbiAgICAgIGlmKHRoaXMuX3Mpbm90aWZ5KHRoaXMsIGZhbHNlKTtcbiAgICAgIHJldHVybiByZWFjdGlvbi5wcm9taXNlO1xuICAgIH0sXG4gICAgLy8gMjUuNC41LjEgUHJvbWlzZS5wcm90b3R5cGUuY2F0Y2gob25SZWplY3RlZClcbiAgICAnY2F0Y2gnOiBmdW5jdGlvbihvblJlamVjdGVkKXtcbiAgICAgIHJldHVybiB0aGlzLnRoZW4odW5kZWZpbmVkLCBvblJlamVjdGVkKTtcbiAgICB9XG4gIH0pO1xuICBQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uKCl7XG4gICAgdmFyIHByb21pc2UgID0gbmV3IEludGVybmFsO1xuICAgIHRoaXMucHJvbWlzZSA9IHByb21pc2U7XG4gICAgdGhpcy5yZXNvbHZlID0gY3R4KCRyZXNvbHZlLCBwcm9taXNlLCAxKTtcbiAgICB0aGlzLnJlamVjdCAgPSBjdHgoJHJlamVjdCwgcHJvbWlzZSwgMSk7XG4gIH07XG59XG5cbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIHtQcm9taXNlOiAkUHJvbWlzZX0pO1xucmVxdWlyZSgnLi9fc2V0LXRvLXN0cmluZy10YWcnKSgkUHJvbWlzZSwgUFJPTUlTRSk7XG5yZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKFBST01JU0UpO1xuV3JhcHBlciA9IHJlcXVpcmUoJy4vX2NvcmUnKVtQUk9NSVNFXTtcblxuLy8gc3RhdGljc1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgUFJPTUlTRSwge1xuICAvLyAyNS40LjQuNSBQcm9taXNlLnJlamVjdChyKVxuICByZWplY3Q6IGZ1bmN0aW9uIHJlamVjdChyKXtcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KHRoaXMpXG4gICAgICAsICQkcmVqZWN0ICAgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICAkJHJlamVjdChyKTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG59KTtcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKExJQlJBUlkgfHwgIVVTRV9OQVRJVkUpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC42IFByb21pc2UucmVzb2x2ZSh4KVxuICByZXNvbHZlOiBmdW5jdGlvbiByZXNvbHZlKHgpe1xuICAgIC8vIGluc3RhbmNlb2YgaW5zdGVhZCBvZiBpbnRlcm5hbCBzbG90IGNoZWNrIGJlY2F1c2Ugd2Ugc2hvdWxkIGZpeCBpdCB3aXRob3V0IHJlcGxhY2VtZW50IG5hdGl2ZSBQcm9taXNlIGNvcmVcbiAgICBpZih4IGluc3RhbmNlb2YgJFByb21pc2UgJiYgc2FtZUNvbnN0cnVjdG9yKHguY29uc3RydWN0b3IsIHRoaXMpKXJldHVybiB4O1xuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkodGhpcylcbiAgICAgICwgJCRyZXNvbHZlICA9IGNhcGFiaWxpdHkucmVzb2x2ZTtcbiAgICAkJHJlc29sdmUoeCk7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICEoVVNFX05BVElWRSAmJiByZXF1aXJlKCcuL19pdGVyLWRldGVjdCcpKGZ1bmN0aW9uKGl0ZXIpe1xuICAkUHJvbWlzZS5hbGwoaXRlcilbJ2NhdGNoJ10oZW1wdHkpO1xufSkpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC4xIFByb21pc2UuYWxsKGl0ZXJhYmxlKVxuICBhbGw6IGZ1bmN0aW9uIGFsbChpdGVyYWJsZSl7XG4gICAgdmFyIEMgICAgICAgICAgPSB0aGlzXG4gICAgICAsIGNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShDKVxuICAgICAgLCByZXNvbHZlICAgID0gY2FwYWJpbGl0eS5yZXNvbHZlXG4gICAgICAsIHJlamVjdCAgICAgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICB2YXIgYWJydXB0ID0gcGVyZm9ybShmdW5jdGlvbigpe1xuICAgICAgdmFyIHZhbHVlcyAgICA9IFtdXG4gICAgICAgICwgaW5kZXggICAgID0gMFxuICAgICAgICAsIHJlbWFpbmluZyA9IDE7XG4gICAgICBmb3JPZihpdGVyYWJsZSwgZmFsc2UsIGZ1bmN0aW9uKHByb21pc2Upe1xuICAgICAgICB2YXIgJGluZGV4ICAgICAgICA9IGluZGV4KytcbiAgICAgICAgICAsIGFscmVhZHlDYWxsZWQgPSBmYWxzZTtcbiAgICAgICAgdmFsdWVzLnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgcmVtYWluaW5nKys7XG4gICAgICAgIEMucmVzb2x2ZShwcm9taXNlKS50aGVuKGZ1bmN0aW9uKHZhbHVlKXtcbiAgICAgICAgICBpZihhbHJlYWR5Q2FsbGVkKXJldHVybjtcbiAgICAgICAgICBhbHJlYWR5Q2FsbGVkICA9IHRydWU7XG4gICAgICAgICAgdmFsdWVzWyRpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAtLXJlbWFpbmluZyB8fCByZXNvbHZlKHZhbHVlcyk7XG4gICAgICAgIH0sIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICAgIC0tcmVtYWluaW5nIHx8IHJlc29sdmUodmFsdWVzKTtcbiAgICB9KTtcbiAgICBpZihhYnJ1cHQpcmVqZWN0KGFicnVwdC5lcnJvcik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfSxcbiAgLy8gMjUuNC40LjQgUHJvbWlzZS5yYWNlKGl0ZXJhYmxlKVxuICByYWNlOiBmdW5jdGlvbiByYWNlKGl0ZXJhYmxlKXtcbiAgICB2YXIgQyAgICAgICAgICA9IHRoaXNcbiAgICAgICwgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgICAsIHJlamVjdCAgICAgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICB2YXIgYWJydXB0ID0gcGVyZm9ybShmdW5jdGlvbigpe1xuICAgICAgZm9yT2YoaXRlcmFibGUsIGZhbHNlLCBmdW5jdGlvbihwcm9taXNlKXtcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oY2FwYWJpbGl0eS5yZXNvbHZlLCByZWplY3QpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaWYoYWJydXB0KXJlamVjdChhYnJ1cHQuZXJyb3IpO1xuICAgIHJldHVybiBjYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cbn0pO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYucHJvbWlzZS5qc1xuLy8gbW9kdWxlIGlkID0gMTMzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIid1c2Ugc3RyaWN0Jztcbi8vIEVDTUFTY3JpcHQgNiBzeW1ib2xzIHNoaW1cbnZhciBnbG9iYWwgICAgICAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgaGFzICAgICAgICAgICAgPSByZXF1aXJlKCcuL19oYXMnKVxuICAsIERFU0NSSVBUT1JTICAgID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKVxuICAsICRleHBvcnQgICAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCByZWRlZmluZSAgICAgICA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJylcbiAgLCBNRVRBICAgICAgICAgICA9IHJlcXVpcmUoJy4vX21ldGEnKS5LRVlcbiAgLCAkZmFpbHMgICAgICAgICA9IHJlcXVpcmUoJy4vX2ZhaWxzJylcbiAgLCBzaGFyZWQgICAgICAgICA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpXG4gICwgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpXG4gICwgdWlkICAgICAgICAgICAgPSByZXF1aXJlKCcuL191aWQnKVxuICAsIHdrcyAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fd2tzJylcbiAgLCB3a3NFeHQgICAgICAgICA9IHJlcXVpcmUoJy4vX3drcy1leHQnKVxuICAsIHdrc0RlZmluZSAgICAgID0gcmVxdWlyZSgnLi9fd2tzLWRlZmluZScpXG4gICwga2V5T2YgICAgICAgICAgPSByZXF1aXJlKCcuL19rZXlvZicpXG4gICwgZW51bUtleXMgICAgICAgPSByZXF1aXJlKCcuL19lbnVtLWtleXMnKVxuICAsIGlzQXJyYXkgICAgICAgID0gcmVxdWlyZSgnLi9faXMtYXJyYXknKVxuICAsIGFuT2JqZWN0ICAgICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCB0b0lPYmplY3QgICAgICA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKVxuICAsIHRvUHJpbWl0aXZlICAgID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJylcbiAgLCBjcmVhdGVEZXNjICAgICA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKVxuICAsIF9jcmVhdGUgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpXG4gICwgZ09QTkV4dCAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wbi1leHQnKVxuICAsICRHT1BEICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKVxuICAsICREUCAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJylcbiAgLCAka2V5cyAgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJylcbiAgLCBnT1BEICAgICAgICAgICA9ICRHT1BELmZcbiAgLCBkUCAgICAgICAgICAgICA9ICREUC5mXG4gICwgZ09QTiAgICAgICAgICAgPSBnT1BORXh0LmZcbiAgLCAkU3ltYm9sICAgICAgICA9IGdsb2JhbC5TeW1ib2xcbiAgLCAkSlNPTiAgICAgICAgICA9IGdsb2JhbC5KU09OXG4gICwgX3N0cmluZ2lmeSAgICAgPSAkSlNPTiAmJiAkSlNPTi5zdHJpbmdpZnlcbiAgLCBQUk9UT1RZUEUgICAgICA9ICdwcm90b3R5cGUnXG4gICwgSElEREVOICAgICAgICAgPSB3a3MoJ19oaWRkZW4nKVxuICAsIFRPX1BSSU1JVElWRSAgID0gd2tzKCd0b1ByaW1pdGl2ZScpXG4gICwgaXNFbnVtICAgICAgICAgPSB7fS5wcm9wZXJ0eUlzRW51bWVyYWJsZVxuICAsIFN5bWJvbFJlZ2lzdHJ5ID0gc2hhcmVkKCdzeW1ib2wtcmVnaXN0cnknKVxuICAsIEFsbFN5bWJvbHMgICAgID0gc2hhcmVkKCdzeW1ib2xzJylcbiAgLCBPUFN5bWJvbHMgICAgICA9IHNoYXJlZCgnb3Atc3ltYm9scycpXG4gICwgT2JqZWN0UHJvdG8gICAgPSBPYmplY3RbUFJPVE9UWVBFXVxuICAsIFVTRV9OQVRJVkUgICAgID0gdHlwZW9mICRTeW1ib2wgPT0gJ2Z1bmN0aW9uJ1xuICAsIFFPYmplY3QgICAgICAgID0gZ2xvYmFsLlFPYmplY3Q7XG4vLyBEb24ndCB1c2Ugc2V0dGVycyBpbiBRdCBTY3JpcHQsIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8xNzNcbnZhciBzZXR0ZXIgPSAhUU9iamVjdCB8fCAhUU9iamVjdFtQUk9UT1RZUEVdIHx8ICFRT2JqZWN0W1BST1RPVFlQRV0uZmluZENoaWxkO1xuXG4vLyBmYWxsYmFjayBmb3Igb2xkIEFuZHJvaWQsIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD02ODdcbnZhciBzZXRTeW1ib2xEZXNjID0gREVTQ1JJUFRPUlMgJiYgJGZhaWxzKGZ1bmN0aW9uKCl7XG4gIHJldHVybiBfY3JlYXRlKGRQKHt9LCAnYScsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uKCl7IHJldHVybiBkUCh0aGlzLCAnYScsIHt2YWx1ZTogN30pLmE7IH1cbiAgfSkpLmEgIT0gNztcbn0pID8gZnVuY3Rpb24oaXQsIGtleSwgRCl7XG4gIHZhciBwcm90b0Rlc2MgPSBnT1BEKE9iamVjdFByb3RvLCBrZXkpO1xuICBpZihwcm90b0Rlc2MpZGVsZXRlIE9iamVjdFByb3RvW2tleV07XG4gIGRQKGl0LCBrZXksIEQpO1xuICBpZihwcm90b0Rlc2MgJiYgaXQgIT09IE9iamVjdFByb3RvKWRQKE9iamVjdFByb3RvLCBrZXksIHByb3RvRGVzYyk7XG59IDogZFA7XG5cbnZhciB3cmFwID0gZnVuY3Rpb24odGFnKXtcbiAgdmFyIHN5bSA9IEFsbFN5bWJvbHNbdGFnXSA9IF9jcmVhdGUoJFN5bWJvbFtQUk9UT1RZUEVdKTtcbiAgc3ltLl9rID0gdGFnO1xuICByZXR1cm4gc3ltO1xufTtcblxudmFyIGlzU3ltYm9sID0gVVNFX05BVElWRSAmJiB0eXBlb2YgJFN5bWJvbC5pdGVyYXRvciA9PSAnc3ltYm9sJyA/IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIHR5cGVvZiBpdCA9PSAnc3ltYm9sJztcbn0gOiBmdW5jdGlvbihpdCl7XG4gIHJldHVybiBpdCBpbnN0YW5jZW9mICRTeW1ib2w7XG59O1xuXG52YXIgJGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkoaXQsIGtleSwgRCl7XG4gIGlmKGl0ID09PSBPYmplY3RQcm90bykkZGVmaW5lUHJvcGVydHkoT1BTeW1ib2xzLCBrZXksIEQpO1xuICBhbk9iamVjdChpdCk7XG4gIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSk7XG4gIGFuT2JqZWN0KEQpO1xuICBpZihoYXMoQWxsU3ltYm9scywga2V5KSl7XG4gICAgaWYoIUQuZW51bWVyYWJsZSl7XG4gICAgICBpZighaGFzKGl0LCBISURERU4pKWRQKGl0LCBISURERU4sIGNyZWF0ZURlc2MoMSwge30pKTtcbiAgICAgIGl0W0hJRERFTl1ba2V5XSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmKGhhcyhpdCwgSElEREVOKSAmJiBpdFtISURERU5dW2tleV0paXRbSElEREVOXVtrZXldID0gZmFsc2U7XG4gICAgICBEID0gX2NyZWF0ZShELCB7ZW51bWVyYWJsZTogY3JlYXRlRGVzYygwLCBmYWxzZSl9KTtcbiAgICB9IHJldHVybiBzZXRTeW1ib2xEZXNjKGl0LCBrZXksIEQpO1xuICB9IHJldHVybiBkUChpdCwga2V5LCBEKTtcbn07XG52YXIgJGRlZmluZVByb3BlcnRpZXMgPSBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKGl0LCBQKXtcbiAgYW5PYmplY3QoaXQpO1xuICB2YXIga2V5cyA9IGVudW1LZXlzKFAgPSB0b0lPYmplY3QoUCkpXG4gICAgLCBpICAgID0gMFxuICAgICwgbCA9IGtleXMubGVuZ3RoXG4gICAgLCBrZXk7XG4gIHdoaWxlKGwgPiBpKSRkZWZpbmVQcm9wZXJ0eShpdCwga2V5ID0ga2V5c1tpKytdLCBQW2tleV0pO1xuICByZXR1cm4gaXQ7XG59O1xudmFyICRjcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUoaXQsIFApe1xuICByZXR1cm4gUCA9PT0gdW5kZWZpbmVkID8gX2NyZWF0ZShpdCkgOiAkZGVmaW5lUHJvcGVydGllcyhfY3JlYXRlKGl0KSwgUCk7XG59O1xudmFyICRwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IGZ1bmN0aW9uIHByb3BlcnR5SXNFbnVtZXJhYmxlKGtleSl7XG4gIHZhciBFID0gaXNFbnVtLmNhbGwodGhpcywga2V5ID0gdG9QcmltaXRpdmUoa2V5LCB0cnVlKSk7XG4gIGlmKHRoaXMgPT09IE9iamVjdFByb3RvICYmIGhhcyhBbGxTeW1ib2xzLCBrZXkpICYmICFoYXMoT1BTeW1ib2xzLCBrZXkpKXJldHVybiBmYWxzZTtcbiAgcmV0dXJuIEUgfHwgIWhhcyh0aGlzLCBrZXkpIHx8ICFoYXMoQWxsU3ltYm9scywga2V5KSB8fCBoYXModGhpcywgSElEREVOKSAmJiB0aGlzW0hJRERFTl1ba2V5XSA/IEUgOiB0cnVlO1xufTtcbnZhciAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGl0LCBrZXkpe1xuICBpdCAgPSB0b0lPYmplY3QoaXQpO1xuICBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpO1xuICBpZihpdCA9PT0gT2JqZWN0UHJvdG8gJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIWhhcyhPUFN5bWJvbHMsIGtleSkpcmV0dXJuO1xuICB2YXIgRCA9IGdPUEQoaXQsIGtleSk7XG4gIGlmKEQgJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIShoYXMoaXQsIEhJRERFTikgJiYgaXRbSElEREVOXVtrZXldKSlELmVudW1lcmFibGUgPSB0cnVlO1xuICByZXR1cm4gRDtcbn07XG52YXIgJGdldE93blByb3BlcnR5TmFtZXMgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eU5hbWVzKGl0KXtcbiAgdmFyIG5hbWVzICA9IGdPUE4odG9JT2JqZWN0KGl0KSlcbiAgICAsIHJlc3VsdCA9IFtdXG4gICAgLCBpICAgICAgPSAwXG4gICAgLCBrZXk7XG4gIHdoaWxlKG5hbWVzLmxlbmd0aCA+IGkpe1xuICAgIGlmKCFoYXMoQWxsU3ltYm9scywga2V5ID0gbmFtZXNbaSsrXSkgJiYga2V5ICE9IEhJRERFTiAmJiBrZXkgIT0gTUVUQSlyZXN1bHQucHVzaChrZXkpO1xuICB9IHJldHVybiByZXN1bHQ7XG59O1xudmFyICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMoaXQpe1xuICB2YXIgSVNfT1AgID0gaXQgPT09IE9iamVjdFByb3RvXG4gICAgLCBuYW1lcyAgPSBnT1BOKElTX09QID8gT1BTeW1ib2xzIDogdG9JT2JqZWN0KGl0KSlcbiAgICAsIHJlc3VsdCA9IFtdXG4gICAgLCBpICAgICAgPSAwXG4gICAgLCBrZXk7XG4gIHdoaWxlKG5hbWVzLmxlbmd0aCA+IGkpe1xuICAgIGlmKGhhcyhBbGxTeW1ib2xzLCBrZXkgPSBuYW1lc1tpKytdKSAmJiAoSVNfT1AgPyBoYXMoT2JqZWN0UHJvdG8sIGtleSkgOiB0cnVlKSlyZXN1bHQucHVzaChBbGxTeW1ib2xzW2tleV0pO1xuICB9IHJldHVybiByZXN1bHQ7XG59O1xuXG4vLyAxOS40LjEuMSBTeW1ib2woW2Rlc2NyaXB0aW9uXSlcbmlmKCFVU0VfTkFUSVZFKXtcbiAgJFN5bWJvbCA9IGZ1bmN0aW9uIFN5bWJvbCgpe1xuICAgIGlmKHRoaXMgaW5zdGFuY2VvZiAkU3ltYm9sKXRocm93IFR5cGVFcnJvcignU3ltYm9sIGlzIG5vdCBhIGNvbnN0cnVjdG9yIScpO1xuICAgIHZhciB0YWcgPSB1aWQoYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpO1xuICAgIHZhciAkc2V0ID0gZnVuY3Rpb24odmFsdWUpe1xuICAgICAgaWYodGhpcyA9PT0gT2JqZWN0UHJvdG8pJHNldC5jYWxsKE9QU3ltYm9scywgdmFsdWUpO1xuICAgICAgaWYoaGFzKHRoaXMsIEhJRERFTikgJiYgaGFzKHRoaXNbSElEREVOXSwgdGFnKSl0aGlzW0hJRERFTl1bdGFnXSA9IGZhbHNlO1xuICAgICAgc2V0U3ltYm9sRGVzYyh0aGlzLCB0YWcsIGNyZWF0ZURlc2MoMSwgdmFsdWUpKTtcbiAgICB9O1xuICAgIGlmKERFU0NSSVBUT1JTICYmIHNldHRlcilzZXRTeW1ib2xEZXNjKE9iamVjdFByb3RvLCB0YWcsIHtjb25maWd1cmFibGU6IHRydWUsIHNldDogJHNldH0pO1xuICAgIHJldHVybiB3cmFwKHRhZyk7XG4gIH07XG4gIHJlZGVmaW5lKCRTeW1ib2xbUFJPVE9UWVBFXSwgJ3RvU3RyaW5nJywgZnVuY3Rpb24gdG9TdHJpbmcoKXtcbiAgICByZXR1cm4gdGhpcy5faztcbiAgfSk7XG5cbiAgJEdPUEQuZiA9ICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG4gICREUC5mICAgPSAkZGVmaW5lUHJvcGVydHk7XG4gIHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZiA9IGdPUE5FeHQuZiA9ICRnZXRPd25Qcm9wZXJ0eU5hbWVzO1xuICByZXF1aXJlKCcuL19vYmplY3QtcGllJykuZiAgPSAkcHJvcGVydHlJc0VudW1lcmFibGU7XG4gIHJlcXVpcmUoJy4vX29iamVjdC1nb3BzJykuZiA9ICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cbiAgaWYoREVTQ1JJUFRPUlMgJiYgIXJlcXVpcmUoJy4vX2xpYnJhcnknKSl7XG4gICAgcmVkZWZpbmUoT2JqZWN0UHJvdG8sICdwcm9wZXJ0eUlzRW51bWVyYWJsZScsICRwcm9wZXJ0eUlzRW51bWVyYWJsZSwgdHJ1ZSk7XG4gIH1cblxuICB3a3NFeHQuZiA9IGZ1bmN0aW9uKG5hbWUpe1xuICAgIHJldHVybiB3cmFwKHdrcyhuYW1lKSk7XG4gIH1cbn1cblxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwge1N5bWJvbDogJFN5bWJvbH0pO1xuXG5mb3IodmFyIHN5bWJvbHMgPSAoXG4gIC8vIDE5LjQuMi4yLCAxOS40LjIuMywgMTkuNC4yLjQsIDE5LjQuMi42LCAxOS40LjIuOCwgMTkuNC4yLjksIDE5LjQuMi4xMCwgMTkuNC4yLjExLCAxOS40LjIuMTIsIDE5LjQuMi4xMywgMTkuNC4yLjE0XG4gICdoYXNJbnN0YW5jZSxpc0NvbmNhdFNwcmVhZGFibGUsaXRlcmF0b3IsbWF0Y2gscmVwbGFjZSxzZWFyY2gsc3BlY2llcyxzcGxpdCx0b1ByaW1pdGl2ZSx0b1N0cmluZ1RhZyx1bnNjb3BhYmxlcydcbikuc3BsaXQoJywnKSwgaSA9IDA7IHN5bWJvbHMubGVuZ3RoID4gaTsgKXdrcyhzeW1ib2xzW2krK10pO1xuXG5mb3IodmFyIHN5bWJvbHMgPSAka2V5cyh3a3Muc3RvcmUpLCBpID0gMDsgc3ltYm9scy5sZW5ndGggPiBpOyApd2tzRGVmaW5lKHN5bWJvbHNbaSsrXSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsICdTeW1ib2wnLCB7XG4gIC8vIDE5LjQuMi4xIFN5bWJvbC5mb3Ioa2V5KVxuICAnZm9yJzogZnVuY3Rpb24oa2V5KXtcbiAgICByZXR1cm4gaGFzKFN5bWJvbFJlZ2lzdHJ5LCBrZXkgKz0gJycpXG4gICAgICA/IFN5bWJvbFJlZ2lzdHJ5W2tleV1cbiAgICAgIDogU3ltYm9sUmVnaXN0cnlba2V5XSA9ICRTeW1ib2woa2V5KTtcbiAgfSxcbiAgLy8gMTkuNC4yLjUgU3ltYm9sLmtleUZvcihzeW0pXG4gIGtleUZvcjogZnVuY3Rpb24ga2V5Rm9yKGtleSl7XG4gICAgaWYoaXNTeW1ib2woa2V5KSlyZXR1cm4ga2V5T2YoU3ltYm9sUmVnaXN0cnksIGtleSk7XG4gICAgdGhyb3cgVHlwZUVycm9yKGtleSArICcgaXMgbm90IGEgc3ltYm9sIScpO1xuICB9LFxuICB1c2VTZXR0ZXI6IGZ1bmN0aW9uKCl7IHNldHRlciA9IHRydWU7IH0sXG4gIHVzZVNpbXBsZTogZnVuY3Rpb24oKXsgc2V0dGVyID0gZmFsc2U7IH1cbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCAnT2JqZWN0Jywge1xuICAvLyAxOS4xLjIuMiBPYmplY3QuY3JlYXRlKE8gWywgUHJvcGVydGllc10pXG4gIGNyZWF0ZTogJGNyZWF0ZSxcbiAgLy8gMTkuMS4yLjQgT2JqZWN0LmRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpXG4gIGRlZmluZVByb3BlcnR5OiAkZGVmaW5lUHJvcGVydHksXG4gIC8vIDE5LjEuMi4zIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpXG4gIGRlZmluZVByb3BlcnRpZXM6ICRkZWZpbmVQcm9wZXJ0aWVzLFxuICAvLyAxOS4xLjIuNiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApXG4gIGdldE93blByb3BlcnR5RGVzY3JpcHRvcjogJGdldE93blByb3BlcnR5RGVzY3JpcHRvcixcbiAgLy8gMTkuMS4yLjcgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoTylcbiAgZ2V0T3duUHJvcGVydHlOYW1lczogJGdldE93blByb3BlcnR5TmFtZXMsXG4gIC8vIDE5LjEuMi44IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoTylcbiAgZ2V0T3duUHJvcGVydHlTeW1ib2xzOiAkZ2V0T3duUHJvcGVydHlTeW1ib2xzXG59KTtcblxuLy8gMjQuMy4yIEpTT04uc3RyaW5naWZ5KHZhbHVlIFssIHJlcGxhY2VyIFssIHNwYWNlXV0pXG4kSlNPTiAmJiAkZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICghVVNFX05BVElWRSB8fCAkZmFpbHMoZnVuY3Rpb24oKXtcbiAgdmFyIFMgPSAkU3ltYm9sKCk7XG4gIC8vIE1TIEVkZ2UgY29udmVydHMgc3ltYm9sIHZhbHVlcyB0byBKU09OIGFzIHt9XG4gIC8vIFdlYktpdCBjb252ZXJ0cyBzeW1ib2wgdmFsdWVzIHRvIEpTT04gYXMgbnVsbFxuICAvLyBWOCB0aHJvd3Mgb24gYm94ZWQgc3ltYm9sc1xuICByZXR1cm4gX3N0cmluZ2lmeShbU10pICE9ICdbbnVsbF0nIHx8IF9zdHJpbmdpZnkoe2E6IFN9KSAhPSAne30nIHx8IF9zdHJpbmdpZnkoT2JqZWN0KFMpKSAhPSAne30nO1xufSkpLCAnSlNPTicsIHtcbiAgc3RyaW5naWZ5OiBmdW5jdGlvbiBzdHJpbmdpZnkoaXQpe1xuICAgIGlmKGl0ID09PSB1bmRlZmluZWQgfHwgaXNTeW1ib2woaXQpKXJldHVybjsgLy8gSUU4IHJldHVybnMgc3RyaW5nIG9uIHVuZGVmaW5lZFxuICAgIHZhciBhcmdzID0gW2l0XVxuICAgICAgLCBpICAgID0gMVxuICAgICAgLCByZXBsYWNlciwgJHJlcGxhY2VyO1xuICAgIHdoaWxlKGFyZ3VtZW50cy5sZW5ndGggPiBpKWFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XG4gICAgcmVwbGFjZXIgPSBhcmdzWzFdO1xuICAgIGlmKHR5cGVvZiByZXBsYWNlciA9PSAnZnVuY3Rpb24nKSRyZXBsYWNlciA9IHJlcGxhY2VyO1xuICAgIGlmKCRyZXBsYWNlciB8fCAhaXNBcnJheShyZXBsYWNlcikpcmVwbGFjZXIgPSBmdW5jdGlvbihrZXksIHZhbHVlKXtcbiAgICAgIGlmKCRyZXBsYWNlcil2YWx1ZSA9ICRyZXBsYWNlci5jYWxsKHRoaXMsIGtleSwgdmFsdWUpO1xuICAgICAgaWYoIWlzU3ltYm9sKHZhbHVlKSlyZXR1cm4gdmFsdWU7XG4gICAgfTtcbiAgICBhcmdzWzFdID0gcmVwbGFjZXI7XG4gICAgcmV0dXJuIF9zdHJpbmdpZnkuYXBwbHkoJEpTT04sIGFyZ3MpO1xuICB9XG59KTtcblxuLy8gMTkuNC4zLjQgU3ltYm9sLnByb3RvdHlwZVtAQHRvUHJpbWl0aXZlXShoaW50KVxuJFN5bWJvbFtQUk9UT1RZUEVdW1RPX1BSSU1JVElWRV0gfHwgcmVxdWlyZSgnLi9faGlkZScpKCRTeW1ib2xbUFJPVE9UWVBFXSwgVE9fUFJJTUlUSVZFLCAkU3ltYm9sW1BST1RPVFlQRV0udmFsdWVPZik7XG4vLyAxOS40LjMuNSBTeW1ib2wucHJvdG90eXBlW0BAdG9TdHJpbmdUYWddXG5zZXRUb1N0cmluZ1RhZygkU3ltYm9sLCAnU3ltYm9sJyk7XG4vLyAyMC4yLjEuOSBNYXRoW0BAdG9TdHJpbmdUYWddXG5zZXRUb1N0cmluZ1RhZyhNYXRoLCAnTWF0aCcsIHRydWUpO1xuLy8gMjQuMy4zIEpTT05bQEB0b1N0cmluZ1RhZ11cbnNldFRvU3RyaW5nVGFnKGdsb2JhbC5KU09OLCAnSlNPTicsIHRydWUpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYuc3ltYm9sLmpzXG4vLyBtb2R1bGUgaWQgPSAxMzRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwicmVxdWlyZSgnLi9fd2tzLWRlZmluZScpKCdhc3luY0l0ZXJhdG9yJyk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNy5zeW1ib2wuYXN5bmMtaXRlcmF0b3IuanNcbi8vIG1vZHVsZSBpZCA9IDEzNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJyZXF1aXJlKCcuL193a3MtZGVmaW5lJykoJ29ic2VydmFibGUnKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM3LnN5bWJvbC5vYnNlcnZhYmxlLmpzXG4vLyBtb2R1bGUgaWQgPSAxMzZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAyLjMuMVxuLy8gIyBDU1YgUGFyc2VyXG5cbi8vIFRoaXMgbW9kdWxlIHByb3ZpZGVzIGEgQ1NWIHBhcnNlciB0ZXN0ZWQgYW5kIHVzZWQgYWdhaW5zdCBsYXJnZSBkYXRhc2V0cy4gT3ZlclxuLy8gdGhlIHllYXIsIGl0IGhhcyBiZWVuIGVuaGFuY2UgYW5kIGlzIG5vdyBmdWxsIG9mIHVzZWZ1bCBvcHRpb25zLlxuXG4vLyBQbGVhc2UgbG9vayBhdCB0aGUgW1JFQURNRV0sIHRoZSBbcHJvamVjdCB3ZWJzaXRlXVtzaXRlXSB0aGUgW3NhbXBsZXNdIGFuZCB0aGVcbi8vIFt0ZXN0c10gZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24uXG52YXIgUGFyc2VyLCBTdHJpbmdEZWNvZGVyLCBpc09iakxpdGVyYWwsIHN0cmVhbSwgdXRpbDtcblxuc3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJyk7XG5cbnV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cblN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXI7XG5cbi8vICMjIFVzYWdlXG5cbi8vIENhbGxiYWNrIGFwcHJvYWNoLCBmb3IgZWFzZSBvZiB1c2U6ICAgXG5cbi8vIGBwYXJzZShkYXRhLCBbb3B0aW9uc10sIGNhbGxiYWNrKWAgICAgIFxuXG4vLyBbTm9kZS5qcyBTdHJlYW0gQVBJXVtzdHJlYW1dLCBmb3IgbWF4aW11bSBvZiBwb3dlcjogICBcblxuLy8gYHBhcnNlKFtvcHRpb25zXSwgW2NhbGxiYWNrXSlgICAgXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY2FsbGJhY2ssIGNhbGxlZCwgY2h1bmtzLCBkYXRhLCBlcnIsIG9wdGlvbnMsIHBhcnNlcjtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICBkYXRhID0gYXJndW1lbnRzWzBdO1xuICAgIG9wdGlvbnMgPSBhcmd1bWVudHNbMV07XG4gICAgY2FsbGJhY2sgPSBhcmd1bWVudHNbMl07XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhyb3cgRXJyb3IoYEludmFsaWQgY2FsbGJhY2sgYXJndW1lbnQ6ICR7SlNPTi5zdHJpbmdpZnkoY2FsbGJhY2spfWApO1xuICAgIH1cbiAgICBpZiAoISh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycgfHwgQnVmZmVyLmlzQnVmZmVyKGFyZ3VtZW50c1swXSkpKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soRXJyb3IoYEludmFsaWQgZGF0YSBhcmd1bWVudDogJHtKU09OLnN0cmluZ2lmeShkYXRhKX1gKSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIHtcbiAgICAvLyAxc3QgYXJnIGlzIGRhdGE6c3RyaW5nIG9yIG9wdGlvbnM6b2JqZWN0XG4gICAgaWYgKHR5cGVvZiBhcmd1bWVudHNbMF0gPT09ICdzdHJpbmcnIHx8IEJ1ZmZlci5pc0J1ZmZlcihhcmd1bWVudHNbMF0pKSB7XG4gICAgICBkYXRhID0gYXJndW1lbnRzWzBdO1xuICAgIH0gZWxzZSBpZiAoaXNPYmpMaXRlcmFsKGFyZ3VtZW50c1swXSkpIHtcbiAgICAgIG9wdGlvbnMgPSBhcmd1bWVudHNbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGVyciA9IGBJbnZhbGlkIGZpcnN0IGFyZ3VtZW50OiAke0pTT04uc3RyaW5naWZ5KGFyZ3VtZW50c1swXSl9YDtcbiAgICB9XG4gICAgLy8gMm5kIGFyZyBpcyBvcHRpb25zOm9iamVjdCBvciBjYWxsYmFjazpmdW5jdGlvblxuICAgIGlmICh0eXBlb2YgYXJndW1lbnRzWzFdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjYWxsYmFjayA9IGFyZ3VtZW50c1sxXTtcbiAgICB9IGVsc2UgaWYgKGlzT2JqTGl0ZXJhbChhcmd1bWVudHNbMV0pKSB7XG4gICAgICBpZiAob3B0aW9ucykge1xuICAgICAgICBlcnIgPSAnSW52YWxpZCBhcmd1bWVudHM6IGdvdCBvcHRpb25zIHR3aWNlIGFzIGZpcnN0IGFuZCBzZWNvbmQgYXJndW1lbnRzJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9wdGlvbnMgPSBhcmd1bWVudHNbMV07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGVyciA9IGBJbnZhbGlkIGZpcnN0IGFyZ3VtZW50OiAke0pTT04uc3RyaW5naWZ5KGFyZ3VtZW50c1sxXSl9YDtcbiAgICB9XG4gICAgaWYgKGVycikge1xuICAgICAgaWYgKCFjYWxsYmFjaykge1xuICAgICAgICB0aHJvdyBFcnJvcihlcnIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKEVycm9yKGVycikpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgaWYgKHR5cGVvZiBhcmd1bWVudHNbMF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNhbGxiYWNrID0gYXJndW1lbnRzWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBvcHRpb25zID0gYXJndW1lbnRzWzBdO1xuICAgIH1cbiAgfVxuICBpZiAob3B0aW9ucyA9PSBudWxsKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIHBhcnNlciA9IG5ldyBQYXJzZXIob3B0aW9ucyk7XG4gIGlmIChkYXRhICE9IG51bGwpIHtcbiAgICBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uKCkge1xuICAgICAgcGFyc2VyLndyaXRlKGRhdGEpO1xuICAgICAgcmV0dXJuIHBhcnNlci5lbmQoKTtcbiAgICB9KTtcbiAgfVxuICBpZiAoY2FsbGJhY2spIHtcbiAgICBjYWxsZWQgPSBmYWxzZTtcbiAgICBjaHVua3MgPSBvcHRpb25zLm9iam5hbWUgPyB7fSA6IFtdO1xuICAgIHBhcnNlci5vbigncmVhZGFibGUnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBjaHVuaywgcmVzdWx0cztcbiAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgIHdoaWxlIChjaHVuayA9IHBhcnNlci5yZWFkKCkpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMub2JqbmFtZSkge1xuICAgICAgICAgIHJlc3VsdHMucHVzaChjaHVua3NbY2h1bmtbMF1dID0gY2h1bmtbMV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdHMucHVzaChjaHVua3MucHVzaChjaHVuaykpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9KTtcbiAgICBwYXJzZXIub24oJ2Vycm9yJywgZnVuY3Rpb24oZXJyKSB7XG4gICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgfSk7XG4gICAgcGFyc2VyLm9uKCdlbmQnLCBmdW5jdGlvbigpIHtcbiAgICAgIGlmICghY2FsbGVkKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBjaHVua3MpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIHJldHVybiBwYXJzZXI7XG59O1xuXG4vLyAjIyBgUGFyc2VyKFtvcHRpb25zXSlgXG5cbi8vIE9wdGlvbnMgYXJlIGRvY3VtZW50ZWQgW2hlcmVdKGh0dHA6Ly9jc3YuYWRhbHRhcy5jb20vcGFyc2UvKS5cblBhcnNlciA9IGZ1bmN0aW9uKG9wdGlvbnMgPSB7fSkge1xuICB2YXIgYmFzZSwgYmFzZTEsIGJhc2UxMCwgYmFzZTExLCBiYXNlMTIsIGJhc2UxMywgYmFzZTE0LCBiYXNlMTUsIGJhc2UxNiwgYmFzZTE3LCBiYXNlMiwgYmFzZTMsIGJhc2U0LCBiYXNlNSwgYmFzZTYsIGJhc2U3LCBiYXNlOCwgYmFzZTksIGssIHY7XG4gIC8vIEBvcHRpb25zID0gb3B0aW9uc1xuICB0aGlzLm9wdGlvbnMgPSB7fTtcbiAgZm9yIChrIGluIG9wdGlvbnMpIHtcbiAgICB2ID0gb3B0aW9uc1trXTtcbiAgICB0aGlzLm9wdGlvbnNba10gPSB2O1xuICB9XG4gIHRoaXMub3B0aW9ucy5vYmplY3RNb2RlID0gdHJ1ZTtcbiAgc3RyZWFtLlRyYW5zZm9ybS5jYWxsKHRoaXMsIHRoaXMub3B0aW9ucyk7XG4gIGlmICgoYmFzZSA9IHRoaXMub3B0aW9ucykucm93RGVsaW1pdGVyID09IG51bGwpIHtcbiAgICBiYXNlLnJvd0RlbGltaXRlciA9IG51bGw7XG4gIH1cbiAgaWYgKHR5cGVvZiB0aGlzLm9wdGlvbnMucm93RGVsaW1pdGVyID09PSAnc3RyaW5nJykge1xuICAgIHRoaXMub3B0aW9ucy5yb3dEZWxpbWl0ZXIgPSBbdGhpcy5vcHRpb25zLnJvd0RlbGltaXRlcl07XG4gIH1cbiAgaWYgKChiYXNlMSA9IHRoaXMub3B0aW9ucykuZGVsaW1pdGVyID09IG51bGwpIHtcbiAgICBiYXNlMS5kZWxpbWl0ZXIgPSAnLCc7XG4gIH1cbiAgaWYgKHRoaXMub3B0aW9ucy5xdW90ZSAhPT0gdm9pZCAwICYmICF0aGlzLm9wdGlvbnMucXVvdGUpIHtcbiAgICB0aGlzLm9wdGlvbnMucXVvdGUgPSAnJztcbiAgfVxuICBpZiAoKGJhc2UyID0gdGhpcy5vcHRpb25zKS5xdW90ZSA9PSBudWxsKSB7XG4gICAgYmFzZTIucXVvdGUgPSAnXCInO1xuICB9XG4gIGlmICgoYmFzZTMgPSB0aGlzLm9wdGlvbnMpLmVzY2FwZSA9PSBudWxsKSB7XG4gICAgYmFzZTMuZXNjYXBlID0gJ1wiJztcbiAgfVxuICBpZiAoKGJhc2U0ID0gdGhpcy5vcHRpb25zKS5jb2x1bW5zID09IG51bGwpIHtcbiAgICBiYXNlNC5jb2x1bW5zID0gbnVsbDtcbiAgfVxuICBpZiAoKGJhc2U1ID0gdGhpcy5vcHRpb25zKS5jb21tZW50ID09IG51bGwpIHtcbiAgICBiYXNlNS5jb21tZW50ID0gJyc7XG4gIH1cbiAgaWYgKChiYXNlNiA9IHRoaXMub3B0aW9ucykub2JqbmFtZSA9PSBudWxsKSB7XG4gICAgYmFzZTYub2JqbmFtZSA9IGZhbHNlO1xuICB9XG4gIGlmICgoYmFzZTcgPSB0aGlzLm9wdGlvbnMpLnRyaW0gPT0gbnVsbCkge1xuICAgIGJhc2U3LnRyaW0gPSBmYWxzZTtcbiAgfVxuICBpZiAoKGJhc2U4ID0gdGhpcy5vcHRpb25zKS5sdHJpbSA9PSBudWxsKSB7XG4gICAgYmFzZTgubHRyaW0gPSBmYWxzZTtcbiAgfVxuICBpZiAoKGJhc2U5ID0gdGhpcy5vcHRpb25zKS5ydHJpbSA9PSBudWxsKSB7XG4gICAgYmFzZTkucnRyaW0gPSBmYWxzZTtcbiAgfVxuICBpZiAodGhpcy5vcHRpb25zLmF1dG9fcGFyc2UgIT0gbnVsbCkge1xuICAgIHRoaXMub3B0aW9ucy5jYXN0ID0gdGhpcy5vcHRpb25zLmF1dG9fcGFyc2U7XG4gIH1cbiAgaWYgKChiYXNlMTAgPSB0aGlzLm9wdGlvbnMpLmNhc3QgPT0gbnVsbCkge1xuICAgIGJhc2UxMC5jYXN0ID0gZmFsc2U7XG4gIH1cbiAgaWYgKHRoaXMub3B0aW9ucy5hdXRvX3BhcnNlX2RhdGUgIT0gbnVsbCkge1xuICAgIHRoaXMub3B0aW9ucy5jYXN0X2RhdGUgPSB0aGlzLm9wdGlvbnMuYXV0b19wYXJzZV9kYXRlO1xuICB9XG4gIGlmICgoYmFzZTExID0gdGhpcy5vcHRpb25zKS5jYXN0X2RhdGUgPT0gbnVsbCkge1xuICAgIGJhc2UxMS5jYXN0X2RhdGUgPSBmYWxzZTtcbiAgfVxuICBpZiAodGhpcy5vcHRpb25zLmNhc3RfZGF0ZSA9PT0gdHJ1ZSkge1xuICAgIHRoaXMub3B0aW9ucy5jYXN0X2RhdGUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgdmFyIG07XG4gICAgICBtID0gRGF0ZS5wYXJzZSh2YWx1ZSk7XG4gICAgICBpZiAoIWlzTmFOKG0pKSB7XG4gICAgICAgIHZhbHVlID0gbmV3IERhdGUobSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfTtcbiAgfVxuICBpZiAoKGJhc2UxMiA9IHRoaXMub3B0aW9ucykucmVsYXggPT0gbnVsbCkge1xuICAgIGJhc2UxMi5yZWxheCA9IGZhbHNlO1xuICB9XG4gIGlmICgoYmFzZTEzID0gdGhpcy5vcHRpb25zKS5yZWxheF9jb2x1bW5fY291bnQgPT0gbnVsbCkge1xuICAgIGJhc2UxMy5yZWxheF9jb2x1bW5fY291bnQgPSBmYWxzZTtcbiAgfVxuICBpZiAoKGJhc2UxNCA9IHRoaXMub3B0aW9ucykuc2tpcF9lbXB0eV9saW5lcyA9PSBudWxsKSB7XG4gICAgYmFzZTE0LnNraXBfZW1wdHlfbGluZXMgPSBmYWxzZTtcbiAgfVxuICBpZiAoKGJhc2UxNSA9IHRoaXMub3B0aW9ucykubWF4X2xpbWl0X29uX2RhdGFfcmVhZCA9PSBudWxsKSB7XG4gICAgYmFzZTE1Lm1heF9saW1pdF9vbl9kYXRhX3JlYWQgPSAxMjgwMDA7XG4gIH1cbiAgaWYgKChiYXNlMTYgPSB0aGlzLm9wdGlvbnMpLnNraXBfbGluZXNfd2l0aF9lbXB0eV92YWx1ZXMgPT0gbnVsbCkge1xuICAgIGJhc2UxNi5za2lwX2xpbmVzX3dpdGhfZW1wdHlfdmFsdWVzID0gZmFsc2U7XG4gIH1cbiAgaWYgKChiYXNlMTcgPSB0aGlzLm9wdGlvbnMpLnNraXBfbGluZXNfd2l0aF9lcnJvciA9PSBudWxsKSB7XG4gICAgYmFzZTE3LnNraXBfbGluZXNfd2l0aF9lcnJvciA9IGZhbHNlO1xuICB9XG4gIC8vIENvdW50ZXJzXG4gIC8vIGxpbmVzID0gY291bnQgKyBza2lwcGVkX2xpbmVfY291bnQgKyBlbXB0eV9saW5lX2NvdW50XG4gIHRoaXMubGluZXMgPSAwOyAvLyBOdW1iZXIgb2YgbGluZXMgZW5jb3VudGVyZWQgaW4gdGhlIHNvdXJjZSBkYXRhc2V0XG4gIHRoaXMuY291bnQgPSAwOyAvLyBOdW1iZXIgb2YgcmVjb3JkcyBiZWluZyBwcm9jZXNzZWRcbiAgdGhpcy5za2lwcGVkX2xpbmVfY291bnQgPSAwOyAvLyBOdW1iZXIgb2YgcmVjb3JkcyBza2lwcGVkIGR1ZSB0byBlcnJvcnNcbiAgdGhpcy5lbXB0eV9saW5lX2NvdW50ID0gMDsgLy8gTnVtYmVyIG9mIGVtcHR5IGxpbmVzXG4gIC8vIENvbnN0YW50c1xuICB0aGlzLmlzX2ludCA9IC9eKFxcLXxcXCspPyhbMS05XStbMC05XSopJC87XG4gIC8vIEBpc19mbG9hdCA9IC9eKFxcLXxcXCspPyhbMC05XSsoXFwuWzAtOV0rKShbZUVdWzAtOV0rKT98SW5maW5pdHkpJC9cbiAgLy8gQGlzX2Zsb2F0ID0gL14oXFwtfFxcKyk/KCgoWzAtOV0pfChbMS05XStbMC05XSopKShcXC5bMC05XSspKFtlRV1bMC05XSspP3xJbmZpbml0eSkkL1xuICB0aGlzLmlzX2Zsb2F0ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gKHZhbHVlIC0gcGFyc2VGbG9hdCh2YWx1ZSkgKyAxKSA+PSAwOyAvLyBCb3Jyb3dlZCBmcm9tIGpxdWVyeVxuICB9O1xuICAvLyBJbnRlcm5hbCBzdGF0ZVxuICB0aGlzLl8gPSB7XG4gICAgZGVjb2RlcjogbmV3IFN0cmluZ0RlY29kZXIoKSxcbiAgICBxdW90aW5nOiBmYWxzZSxcbiAgICBjb21tZW50aW5nOiBmYWxzZSxcbiAgICBmaWVsZDogbnVsbCxcbiAgICBuZXh0Q2hhcjogbnVsbCxcbiAgICBjbG9zaW5nUXVvdGU6IDAsXG4gICAgbGluZTogW10sXG4gICAgY2h1bmtzOiBbXSxcbiAgICByYXdCdWY6ICcnLFxuICAgIGJ1ZjogJycsXG4gICAgcm93RGVsaW1pdGVyTGVuZ3RoOiB0aGlzLm9wdGlvbnMucm93RGVsaW1pdGVyID8gTWF0aC5tYXgoLi4udGhpcy5vcHRpb25zLnJvd0RlbGltaXRlci5tYXAoZnVuY3Rpb24odikge1xuICAgICAgcmV0dXJuIHYubGVuZ3RoO1xuICAgIH0pKSA6IHZvaWQgMCxcbiAgICBsaW5lSGFzRXJyb3I6IGZhbHNlLFxuICAgIGlzRW5kZWQ6IGZhbHNlXG4gIH07XG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gIyMgSW50ZXJuYWwgQVBJXG5cbi8vIFRoZSBQYXJzZXIgaW1wbGVtZW50IGEgW2BzdHJlYW0uVHJhbnNmb3JtYCBjbGFzc11bdHJhbnNmb3JtXS5cblxuLy8gIyMjIEV2ZW50c1xuXG4vLyBUaGUgbGlicmFyeSBleHRlbmRzIE5vZGUgW0V2ZW50RW1pdHRlcl1bZXZlbnRdIGNsYXNzIGFuZCBlbWl0IGFsbFxuLy8gdGhlIGV2ZW50cyBvZiB0aGUgV3JpdGFibGUgYW5kIFJlYWRhYmxlIFtTdHJlYW0gQVBJXVtzdHJlYW1dLiBcbnV0aWwuaW5oZXJpdHMoUGFyc2VyLCBzdHJlYW0uVHJhbnNmb3JtKTtcblxuLy8gRm9yIGV4dHJhIGZsZXhpYmlsaXR5LCB5b3UgY2FuIGdldCBhY2Nlc3MgdG8gdGhlIG9yaWdpbmFsIFBhcnNlclxuLy8gY2xhc3M6IGByZXF1aXJlKCdjc3YtcGFyc2UnKS5QYXJzZXJgLlxubW9kdWxlLmV4cG9ydHMuUGFyc2VyID0gUGFyc2VyO1xuXG4vLyAjIyMgYF90cmFuc2Zvcm0oY2h1bmssIGVuY29kaW5nLCBjYWxsYmFjaylgXG5cbi8vICogICBgY2h1bmtgIEJ1ZmZlciB8IFN0cmluZyAgIFxuLy8gICAgIFRoZSBjaHVuayB0byBiZSB0cmFuc2Zvcm1lZC4gV2lsbCBhbHdheXMgYmUgYSBidWZmZXIgdW5sZXNzIHRoZSBkZWNvZGVTdHJpbmdzIG9wdGlvbiB3YXMgc2V0IHRvIGZhbHNlLlxuLy8gKiAgIGBlbmNvZGluZ2AgU3RyaW5nICAgXG4vLyAgICAgSWYgdGhlIGNodW5rIGlzIGEgc3RyaW5nLCB0aGVuIHRoaXMgaXMgdGhlIGVuY29kaW5nIHR5cGUuIChJZ25vcmUgaWYgZGVjb2RlU3RyaW5ncyBjaHVuayBpcyBhIGJ1ZmZlci4pXG4vLyAqICAgYGNhbGxiYWNrYCBGdW5jdGlvbiAgIFxuLy8gICAgIENhbGwgdGhpcyBmdW5jdGlvbiAob3B0aW9uYWxseSB3aXRoIGFuIGVycm9yIGFyZ3VtZW50KSB3aGVuIHlvdSBhcmUgZG9uZSBwcm9jZXNzaW5nIHRoZSBzdXBwbGllZCBjaHVuay5cblxuLy8gSW1wbGVtZW50YXRpb24gb2YgdGhlIFtgc3RyZWFtLlRyYW5zZm9ybWAgQVBJXVt0cmFuc2Zvcm1dXG5QYXJzZXIucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNhbGxiYWNrKSB7XG4gIHJldHVybiBzZXRJbW1lZGlhdGUoKCkgPT4ge1xuICAgIHZhciBlcnI7XG4gICAgaWYgKGNodW5rIGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICBjaHVuayA9IHRoaXMuXy5kZWNvZGVyLndyaXRlKGNodW5rKTtcbiAgICB9XG4gICAgZXJyID0gdGhpcy5fX3dyaXRlKGNodW5rLCBmYWxzZSk7XG4gICAgaWYgKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgIH1cbiAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgfSk7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9mbHVzaCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gIHJldHVybiBjYWxsYmFjayh0aGlzLl9fZmx1c2goKSk7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9fZmx1c2ggPSBmdW5jdGlvbigpIHtcbiAgdmFyIGVycjtcbiAgZXJyID0gdGhpcy5fX3dyaXRlKHRoaXMuXy5kZWNvZGVyLmVuZCgpLCB0cnVlKTtcbiAgaWYgKGVycikge1xuICAgIHJldHVybiBlcnI7XG4gIH1cbiAgaWYgKHRoaXMuXy5xdW90aW5nKSB7XG4gICAgZXJyID0gdGhpcy5lcnJvcihgUXVvdGVkIGZpZWxkIG5vdCB0ZXJtaW5hdGVkIGF0IGxpbmUgJHt0aGlzLmxpbmVzICsgMX1gKTtcbiAgICByZXR1cm4gZXJyO1xuICB9XG4gIGlmICh0aGlzLl8ubGluZS5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHRoaXMuX19wdXNoKHRoaXMuXy5saW5lKTtcbiAgfVxufTtcblxuUGFyc2VyLnByb3RvdHlwZS5fX3B1c2ggPSBmdW5jdGlvbihsaW5lKSB7XG4gIHZhciBjYWxsX2NvbHVtbl91ZGYsIGNvbHVtbnMsIGVyciwgZmllbGQsIGksIGosIGxlbiwgbGluZUFzQ29sdW1ucywgcmVjb3JkO1xuICBpZiAodGhpcy5fLmlzRW5kZWQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHRoaXMub3B0aW9ucy5za2lwX2xpbmVzX3dpdGhfZW1wdHlfdmFsdWVzICYmIGxpbmUuam9pbignJykudHJpbSgpID09PSAnJykge1xuICAgIHJldHVybjtcbiAgfVxuICByZWNvcmQgPSBudWxsO1xuICBpZiAodGhpcy5vcHRpb25zLmNvbHVtbnMgPT09IHRydWUpIHtcbiAgICB0aGlzLm9wdGlvbnMuY29sdW1ucyA9IGxpbmU7XG4gICAgcmV0dXJuO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLm9wdGlvbnMuY29sdW1ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxfY29sdW1uX3VkZiA9IGZ1bmN0aW9uKGZuLCBsaW5lKSB7XG4gICAgICB2YXIgY29sdW1ucywgZXJyO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29sdW1ucyA9IGZuLmNhbGwobnVsbCwgbGluZSk7XG4gICAgICAgIHJldHVybiBbbnVsbCwgY29sdW1uc107XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBlcnIgPSBlcnJvcjtcbiAgICAgICAgcmV0dXJuIFtlcnJdO1xuICAgICAgfVxuICAgIH07XG4gICAgW2VyciwgY29sdW1uc10gPSBjYWxsX2NvbHVtbl91ZGYodGhpcy5vcHRpb25zLmNvbHVtbnMsIGxpbmUpO1xuICAgIGlmIChlcnIpIHtcbiAgICAgIHJldHVybiBlcnI7XG4gICAgfVxuICAgIHRoaXMub3B0aW9ucy5jb2x1bW5zID0gY29sdW1ucztcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKCF0aGlzLl8ubGluZV9sZW5ndGggJiYgbGluZS5sZW5ndGggPiAwKSB7XG4gICAgdGhpcy5fLmxpbmVfbGVuZ3RoID0gdGhpcy5vcHRpb25zLmNvbHVtbnMgPyB0aGlzLm9wdGlvbnMuY29sdW1ucy5sZW5ndGggOiBsaW5lLmxlbmd0aDtcbiAgfVxuICAvLyBEb250IGNoZWNrIGNvbHVtbiBjb3VudCBvbiBlbXB0eSBsaW5lc1xuICBpZiAobGluZS5sZW5ndGggPT09IDEgJiYgbGluZVswXSA9PT0gJycpIHtcbiAgICB0aGlzLmVtcHR5X2xpbmVfY291bnQrKztcbiAgfSBlbHNlIGlmIChsaW5lLmxlbmd0aCAhPT0gdGhpcy5fLmxpbmVfbGVuZ3RoKSB7XG4gICAgLy8gRG9udCBjaGVjayBjb2x1bW4gY291bnQgd2l0aCByZWxheF9jb2x1bW5fY291bnRcbiAgICBpZiAodGhpcy5vcHRpb25zLnJlbGF4X2NvbHVtbl9jb3VudCkge1xuICAgICAgdGhpcy5jb3VudCsrO1xuICAgICAgdGhpcy5za2lwcGVkX2xpbmVfY291bnQrKztcbiAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9ucy5jb2x1bW5zICE9IG51bGwpIHtcbiAgICAgIC8vIFN1Z2dlc3Q6IEluY29uc2lzdGVudCBoZWFkZXIgYW5kIGNvbHVtbiBudW1iZXJzOiBoZWFkZXIgaXMgMSBhbmQgbnVtYmVyIG9mIGNvbHVtbnMgaXMgMSBvbiBsaW5lIDFcbiAgICAgIGVyciA9IHRoaXMuZXJyb3IoYE51bWJlciBvZiBjb2x1bW5zIG9uIGxpbmUgJHt0aGlzLmxpbmVzfSBkb2VzIG5vdCBtYXRjaCBoZWFkZXJgKTtcbiAgICAgIHJldHVybiBlcnI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVyciA9IHRoaXMuZXJyb3IoYE51bWJlciBvZiBjb2x1bW5zIGlzIGluY29uc2lzdGVudCBvbiBsaW5lICR7dGhpcy5saW5lc31gKTtcbiAgICAgIHJldHVybiBlcnI7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRoaXMuY291bnQrKztcbiAgfVxuICBpZiAodGhpcy5vcHRpb25zLmNvbHVtbnMgIT0gbnVsbCkge1xuICAgIGxpbmVBc0NvbHVtbnMgPSB7fTtcbiAgICBmb3IgKGkgPSBqID0gMCwgbGVuID0gbGluZS5sZW5ndGg7IGogPCBsZW47IGkgPSArK2opIHtcbiAgICAgIGZpZWxkID0gbGluZVtpXTtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuY29sdW1uc1tpXSA9PT0gZmFsc2UpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBsaW5lQXNDb2x1bW5zW3RoaXMub3B0aW9ucy5jb2x1bW5zW2ldXSA9IGZpZWxkO1xuICAgIH1cbiAgICBpZiAodGhpcy5vcHRpb25zLm9iam5hbWUpIHtcbiAgICAgIHJlY29yZCA9IFtsaW5lQXNDb2x1bW5zW3RoaXMub3B0aW9ucy5vYmpuYW1lXSwgbGluZUFzQ29sdW1uc107XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlY29yZCA9IGxpbmVBc0NvbHVtbnM7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJlY29yZCA9IGxpbmU7XG4gIH1cbiAgaWYgKHRoaXMuY291bnQgPCB0aGlzLm9wdGlvbnMuZnJvbSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAodGhpcy5vcHRpb25zLnJhdykge1xuICAgIHRoaXMucHVzaCh7XG4gICAgICByYXc6IHRoaXMuXy5yYXdCdWYsXG4gICAgICByb3c6IHJlY29yZFxuICAgIH0pO1xuICAgIHRoaXMuXy5yYXdCdWYgPSAnJztcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnB1c2gocmVjb3JkKTtcbiAgfVxuICBpZiAodGhpcy5saXN0ZW5lckNvdW50KCdyZWNvcmQnKSkge1xuICAgIHRoaXMuZW1pdCgncmVjb3JkJywgcmVjb3JkKTtcbiAgfVxuICAvLyBXaGVuIHRvIGlzIHJlYWNoZWQgc2V0IGlnbm9yZSBhbnkgZnV0dXJlIGNhbGxzXG4gIGlmICh0aGlzLmNvdW50ID49IHRoaXMub3B0aW9ucy50bykge1xuICAgIHRoaXMuXy5pc0VuZGVkID0gdHJ1ZTtcbiAgICByZXR1cm4gdGhpcy5wdXNoKG51bGwpO1xuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5fX3dyaXRlID0gZnVuY3Rpb24oY2hhcnMsIGVuZCkge1xuICB2YXIgYXJlTmV4dENoYXJzRGVsaW1pdGVyLCBhcmVOZXh0Q2hhcnNSb3dEZWxpbWl0ZXJzLCBjYXN0LCBjaGFyLCBlcnIsIGVzY2FwZUlzUXVvdGUsIGksIGlzRGVsaW1pdGVyLCBpc0VzY2FwZSwgaXNOZXh0Q2hhckFDb21tZW50LCBpc05leHRDaGFyVHJpbWFibGUsIGlzUXVvdGUsIGlzUm93RGVsaW1pdGVyLCBpc1Jvd0RlbGltaXRlckxlbmd0aCwgaXNfZmxvYXQsIGlzX2ludCwgbCwgbHRyaW0sIG5leHRDaGFyUG9zLCByZWYsIHJlZjEsIHJlZjIsIHJlZjMsIHJlZjQsIHJlZjUsIHJlZjYsIHJlbWFpbmluZ0J1ZmZlciwgcm93RGVsaW1pdGVyLCBydHJpbSwgd2FzQ29tbWVudGluZztcbiAgaXNfaW50ID0gKHZhbHVlKSA9PiB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLmlzX2ludCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIHRoaXMuaXNfaW50KHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuaXNfaW50LnRlc3QodmFsdWUpO1xuICAgIH1cbiAgfTtcbiAgaXNfZmxvYXQgPSAodmFsdWUpID0+IHtcbiAgICBpZiAodHlwZW9mIHRoaXMuaXNfZmxvYXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiB0aGlzLmlzX2Zsb2F0KHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuaXNfZmxvYXQudGVzdCh2YWx1ZSk7XG4gICAgfVxuICB9O1xuICBjYXN0ID0gKHZhbHVlLCBjb250ZXh0ID0ge30pID0+IHtcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5jYXN0KSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIGlmIChjb250ZXh0LnF1b3RpbmcgPT0gbnVsbCkge1xuICAgICAgY29udGV4dC5xdW90aW5nID0gISF0aGlzLl8uY2xvc2luZ1F1b3RlO1xuICAgIH1cbiAgICBpZiAoY29udGV4dC5saW5lcyA9PSBudWxsKSB7XG4gICAgICBjb250ZXh0LmxpbmVzID0gdGhpcy5saW5lcztcbiAgICB9XG4gICAgaWYgKGNvbnRleHQuY291bnQgPT0gbnVsbCkge1xuICAgICAgY29udGV4dC5jb3VudCA9IHRoaXMuY291bnQ7XG4gICAgfVxuICAgIGlmIChjb250ZXh0LmluZGV4ID09IG51bGwpIHtcbiAgICAgIGNvbnRleHQuaW5kZXggPSB0aGlzLl8ubGluZS5sZW5ndGg7XG4gICAgfVxuICAgIC8vIGNvbnRleHQuaGVhZGVyID89IGlmIEBvcHRpb25zLmNvbHVtbiBhbmQgQGxpbmVzIGlzIDEgYW5kIEBjb3VudCBpcyAwIHRoZW4gdHJ1ZSBlbHNlIGZhbHNlXG4gICAgaWYgKGNvbnRleHQuaGVhZGVyID09IG51bGwpIHtcbiAgICAgIGNvbnRleHQuaGVhZGVyID0gdGhpcy5vcHRpb25zLmNvbHVtbnMgPT09IHRydWU7XG4gICAgfVxuICAgIGlmIChjb250ZXh0LmNvbHVtbiA9PSBudWxsKSB7XG4gICAgICBjb250ZXh0LmNvbHVtbiA9IEFycmF5LmlzQXJyYXkodGhpcy5vcHRpb25zLmNvbHVtbnMpID8gdGhpcy5vcHRpb25zLmNvbHVtbnNbY29udGV4dC5pbmRleF0gOiBjb250ZXh0LmluZGV4O1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHRoaXMub3B0aW9ucy5jYXN0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmNhc3QodmFsdWUsIGNvbnRleHQpO1xuICAgIH1cbiAgICBpZiAoaXNfaW50KHZhbHVlKSkge1xuICAgICAgdmFsdWUgPSBwYXJzZUludCh2YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChpc19mbG9hdCh2YWx1ZSkpIHtcbiAgICAgIHZhbHVlID0gcGFyc2VGbG9hdCh2YWx1ZSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbnMuY2FzdF9kYXRlKSB7XG4gICAgICB2YWx1ZSA9IHRoaXMub3B0aW9ucy5jYXN0X2RhdGUodmFsdWUsIGNvbnRleHQpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH07XG4gIGx0cmltID0gdGhpcy5vcHRpb25zLnRyaW0gfHwgdGhpcy5vcHRpb25zLmx0cmltO1xuICBydHJpbSA9IHRoaXMub3B0aW9ucy50cmltIHx8IHRoaXMub3B0aW9ucy5ydHJpbTtcbiAgY2hhcnMgPSB0aGlzLl8uYnVmICsgY2hhcnM7XG4gIGwgPSBjaGFycy5sZW5ndGg7XG4gIGkgPSAwO1xuICBpZiAodGhpcy5saW5lcyA9PT0gMCAmJiAweEZFRkYgPT09IGNoYXJzLmNoYXJDb2RlQXQoMCkpIHtcbiAgICAvLyBTdHJpcCBCT00gaGVhZGVyXG4gICAgaSsrO1xuICB9XG4gIHdoaWxlIChpIDwgbCkge1xuICAgIC8vIEVuc3VyZSB3ZSBnZXQgZW5vdWdoIHNwYWNlIHRvIGxvb2sgYWhlYWRcbiAgICBpZiAoIWVuZCkge1xuICAgICAgcmVtYWluaW5nQnVmZmVyID0gY2hhcnMuc3Vic3RyKGksIGwgLSBpKTtcbiAgICAgIC8vIChpKzEwMDAgPj0gbCkgb3JcbiAgICAgIC8vIFNraXAgaWYgdGhlIHJlbWFpbmluZyBidWZmZXIgY2FuIGJlIGNvbW1lbnRcbiAgICAgIC8vIFNraXAgaWYgdGhlIHJlbWFpbmluZyBidWZmZXIgY2FuIGJlIHJvdyBkZWxpbWl0ZXJcbiAgICAgIGlmICgoIXRoaXMub3B0aW9ucy5yb3dEZWxpbWl0ZXIgJiYgaSArIDMgPiBsKSB8fCAoIXRoaXMuXy5jb21tZW50aW5nICYmIGwgLSBpIDwgdGhpcy5vcHRpb25zLmNvbW1lbnQubGVuZ3RoICYmIHRoaXMub3B0aW9ucy5jb21tZW50LnN1YnN0cigwLCBsIC0gaSkgPT09IHJlbWFpbmluZ0J1ZmZlcikgfHwgKHRoaXMub3B0aW9ucy5yb3dEZWxpbWl0ZXIgJiYgbCAtIGkgPCB0aGlzLl8ucm93RGVsaW1pdGVyTGVuZ3RoICYmIHRoaXMub3B0aW9ucy5yb3dEZWxpbWl0ZXIuc29tZShmdW5jdGlvbihyZCkge1xuICAgICAgICByZXR1cm4gcmQuc3Vic3RyKDAsIGwgLSBpKSA9PT0gcmVtYWluaW5nQnVmZmVyO1xuICAgICAgLy8gU2tpcCBpZiB0aGUgcmVtYWluaW5nIGJ1ZmZlciBjYW4gYmUgcm93IGRlbGltaXRlciBmb2xsb3dpbmcgdGhlIGNsb3NpbmcgcXVvdGVcbiAgICAgIH0pKSB8fCAodGhpcy5vcHRpb25zLnJvd0RlbGltaXRlciAmJiB0aGlzLl8ucXVvdGluZyAmJiBsIC0gaSA8ICh0aGlzLm9wdGlvbnMucXVvdGUubGVuZ3RoICsgdGhpcy5fLnJvd0RlbGltaXRlckxlbmd0aCkgJiYgdGhpcy5vcHRpb25zLnJvd0RlbGltaXRlci5zb21lKChyZCkgPT4ge1xuICAgICAgICByZXR1cm4gKHRoaXMub3B0aW9ucy5xdW90ZSArIHJkKS5zdWJzdHIoMCwgbCAtIGkpID09PSByZW1haW5pbmdCdWZmZXI7XG4gICAgICAvLyBTa2lwIGlmIHRoZSByZW1haW5pbmcgYnVmZmVyIGNhbiBiZSBkZWxpbWl0ZXJcbiAgICAgIC8vIFNraXAgaWYgdGhlIHJlbWFpbmluZyBidWZmZXIgY2FuIGJlIGVzY2FwZSBzZXF1ZW5jZVxuICAgICAgfSkpIHx8IChsIC0gaSA8PSB0aGlzLm9wdGlvbnMuZGVsaW1pdGVyLmxlbmd0aCAmJiB0aGlzLm9wdGlvbnMuZGVsaW1pdGVyLnN1YnN0cigwLCBsIC0gaSkgPT09IHJlbWFpbmluZ0J1ZmZlcikgfHwgKGwgLSBpIDw9IHRoaXMub3B0aW9ucy5lc2NhcGUubGVuZ3RoICYmIHRoaXMub3B0aW9ucy5lc2NhcGUuc3Vic3RyKDAsIGwgLSBpKSA9PT0gcmVtYWluaW5nQnVmZmVyKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgY2hhciA9IHRoaXMuXy5uZXh0Q2hhciA/IHRoaXMuXy5uZXh0Q2hhciA6IGNoYXJzLmNoYXJBdChpKTtcbiAgICB0aGlzLl8ubmV4dENoYXIgPSBsID4gaSArIDEgPyBjaGFycy5jaGFyQXQoaSArIDEpIDogbnVsbDtcbiAgICBpZiAodGhpcy5vcHRpb25zLnJhdykge1xuICAgICAgdGhpcy5fLnJhd0J1ZiArPSBjaGFyO1xuICAgIH1cbiAgICAvLyBBdXRvIGRpc2NvdmVyeSBvZiByb3dEZWxpbWl0ZXIsIHVuaXgsIG1hYyBhbmQgd2luZG93cyBzdXBwb3J0ZWRcbiAgICBpZiAodGhpcy5vcHRpb25zLnJvd0RlbGltaXRlciA9PSBudWxsKSB7XG4gICAgICBuZXh0Q2hhclBvcyA9IGk7XG4gICAgICByb3dEZWxpbWl0ZXIgPSBudWxsO1xuICAgICAgLy8gRmlyc3QgZW1wdHkgbGluZVxuICAgICAgaWYgKCF0aGlzLl8ucXVvdGluZyAmJiAoY2hhciA9PT0gJ1xcbicgfHwgY2hhciA9PT0gJ1xccicpKSB7XG4gICAgICAgIHJvd0RlbGltaXRlciA9IGNoYXI7XG4gICAgICAgIG5leHRDaGFyUG9zICs9IDE7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuXy5xdW90aW5nICYmIGNoYXIgPT09IHRoaXMub3B0aW9ucy5xdW90ZSAmJiAoKHJlZiA9IHRoaXMuXy5uZXh0Q2hhcikgPT09ICdcXG4nIHx8IHJlZiA9PT0gJ1xccicpKSB7XG4gICAgICAgIHJvd0RlbGltaXRlciA9IHRoaXMuXy5uZXh0Q2hhcjtcbiAgICAgICAgbmV4dENoYXJQb3MgKz0gMjtcbiAgICAgIH1cbiAgICAgIGlmIChyb3dEZWxpbWl0ZXIpIHtcbiAgICAgICAgaWYgKHJvd0RlbGltaXRlciA9PT0gJ1xccicgJiYgY2hhcnMuY2hhckF0KG5leHRDaGFyUG9zKSA9PT0gJ1xcbicpIHtcbiAgICAgICAgICByb3dEZWxpbWl0ZXIgKz0gJ1xcbic7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcHRpb25zLnJvd0RlbGltaXRlciA9IFtyb3dEZWxpbWl0ZXJdO1xuICAgICAgICB0aGlzLl8ucm93RGVsaW1pdGVyTGVuZ3RoID0gcm93RGVsaW1pdGVyLmxlbmd0aDtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gUGFyc2UgdGhhdCBkYW1uIGNoYXJcbiAgICAvLyBOb3RlLCBzaG91bGRuJ3Qgd2UgaGF2ZSBzdGggbGlrZSBjaGFycy5zdWJzdHIoaSwgQG9wdGlvbnMuZXNjYXBlLmxlbmd0aClcbiAgICBpZiAoIXRoaXMuXy5jb21tZW50aW5nICYmIGNoYXIgPT09IHRoaXMub3B0aW9ucy5lc2NhcGUpIHtcbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgZXNjYXBlIGlzIHJlYWxseSBoZXJlIGZvciBlc2NhcGluZzpcbiAgICAgIC8vIElmIGVzY2FwZSBpcyBzYW1lIGFzIHF1b3RlLCBhbmQgZXNjYXBlIGlzIGZpcnN0IGNoYXIgb2YgYSBmaWVsZCBcbiAgICAgIC8vIGFuZCBpdCdzIG5vdCBxdW90ZWQsIHRoZW4gaXQgaXMgYSBxdW90ZVxuICAgICAgLy8gTmV4dCBjaGFyIHNob3VsZCBiZSBhbiBlc2NhcGUgb3IgYSBxdW90ZVxuICAgICAgZXNjYXBlSXNRdW90ZSA9IHRoaXMub3B0aW9ucy5lc2NhcGUgPT09IHRoaXMub3B0aW9ucy5xdW90ZTtcbiAgICAgIGlzRXNjYXBlID0gdGhpcy5fLm5leHRDaGFyID09PSB0aGlzLm9wdGlvbnMuZXNjYXBlO1xuICAgICAgaXNRdW90ZSA9IHRoaXMuXy5uZXh0Q2hhciA9PT0gdGhpcy5vcHRpb25zLnF1b3RlO1xuICAgICAgaWYgKCEoZXNjYXBlSXNRdW90ZSAmJiAhdGhpcy5fLmZpZWxkICYmICF0aGlzLl8ucXVvdGluZykgJiYgKGlzRXNjYXBlIHx8IGlzUXVvdGUpKSB7XG4gICAgICAgIGkrKztcbiAgICAgICAgY2hhciA9IHRoaXMuXy5uZXh0Q2hhcjtcbiAgICAgICAgdGhpcy5fLm5leHRDaGFyID0gY2hhcnMuY2hhckF0KGkgKyAxKTtcbiAgICAgICAgaWYgKHRoaXMuXy5maWVsZCA9PSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5fLmZpZWxkID0gJyc7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fLmZpZWxkICs9IGNoYXI7XG4gICAgICAgIC8vIFNpbmNlIHdlJ3JlIHNraXBwaW5nIHRoZSBuZXh0IG9uZSwgYmV0dGVyIGFkZCBpdCBub3cgaWYgaW4gcmF3IG1vZGUuXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMucmF3KSB7XG4gICAgICAgICAgdGhpcy5fLnJhd0J1ZiArPSBjaGFyO1xuICAgICAgICB9XG4gICAgICAgIGkrKztcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENoYXIgbWF0Y2ggcXVvdGVcbiAgICBpZiAoIXRoaXMuXy5jb21tZW50aW5nICYmIGNoYXIgPT09IHRoaXMub3B0aW9ucy5xdW90ZSkge1xuICAgICAgaWYgKHRoaXMuXy5hY2NlcHRPbmx5RW1wdHlDaGFycyAmJiAoY2hhciAhPT0gJyAnICYmIGNoYXIgIT09ICdcXHQnKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5lcnJvcignT25seSB0cmltYWJsZSBjaGFyYWN0ZXJzIGFyZSBhY2NlcHRlZCBhZnRlciBxdW90ZXMnKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl8ucXVvdGluZykge1xuICAgICAgICAvLyBNYWtlIHN1cmUgYSBjbG9zaW5nIHF1b3RlIGlzIGZvbGxvd2VkIGJ5IGEgZGVsaW1pdGVyXG4gICAgICAgIC8vIElmIHdlIGhhdmUgYSBuZXh0IGNoYXJhY3RlciBhbmQgXG4gICAgICAgIC8vIGl0IGlzbnQgYSByb3dEZWxpbWl0ZXIgYW5kIFxuICAgICAgICAvLyBpdCBpc250IGFuIGNvbHVtbiBkZWxpbWl0ZXIgYW5kXG4gICAgICAgIC8vIGl0IGlzbnQgdGhlIGJlZ2luaW5nIG9mIGEgY29tbWVudFxuICAgICAgICAvLyBPdGhlcndpc2UsIGlmIHRoaXMgaXMgbm90IFwicmVsYXhcIiBtb2RlLCB0aHJvdyBhbiBlcnJvclxuICAgICAgICBpc05leHRDaGFyVHJpbWFibGUgPSBydHJpbSAmJiAoKHJlZjEgPSB0aGlzLl8ubmV4dENoYXIpID09PSAnICcgfHwgcmVmMSA9PT0gJ1xcdCcpO1xuICAgICAgICBhcmVOZXh0Q2hhcnNSb3dEZWxpbWl0ZXJzID0gdGhpcy5vcHRpb25zLnJvd0RlbGltaXRlciAmJiB0aGlzLm9wdGlvbnMucm93RGVsaW1pdGVyLnNvbWUoZnVuY3Rpb24ocmQpIHtcbiAgICAgICAgICByZXR1cm4gY2hhcnMuc3Vic3RyKGkgKyAxLCByZC5sZW5ndGgpID09PSByZDtcbiAgICAgICAgfSk7XG4gICAgICAgIGFyZU5leHRDaGFyc0RlbGltaXRlciA9IGNoYXJzLnN1YnN0cihpICsgMSwgdGhpcy5vcHRpb25zLmRlbGltaXRlci5sZW5ndGgpID09PSB0aGlzLm9wdGlvbnMuZGVsaW1pdGVyO1xuICAgICAgICBpc05leHRDaGFyQUNvbW1lbnQgPSB0aGlzLl8ubmV4dENoYXIgPT09IHRoaXMub3B0aW9ucy5jb21tZW50O1xuICAgICAgICBpZiAoKHRoaXMuXy5uZXh0Q2hhciAhPSBudWxsKSAmJiAhaXNOZXh0Q2hhclRyaW1hYmxlICYmICFhcmVOZXh0Q2hhcnNSb3dEZWxpbWl0ZXJzICYmICFhcmVOZXh0Q2hhcnNEZWxpbWl0ZXIgJiYgIWlzTmV4dENoYXJBQ29tbWVudCkge1xuICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMucmVsYXgpIHtcbiAgICAgICAgICAgIHRoaXMuXy5xdW90aW5nID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAodGhpcy5fLmZpZWxkKSB7XG4gICAgICAgICAgICAgIHRoaXMuXy5maWVsZCA9IGAke3RoaXMub3B0aW9ucy5xdW90ZX0ke3RoaXMuXy5maWVsZH1gO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoZXJyID0gdGhpcy5lcnJvcihgSW52YWxpZCBjbG9zaW5nIHF1b3RlIGF0IGxpbmUgJHt0aGlzLmxpbmVzICsgMX07IGZvdW5kICR7SlNPTi5zdHJpbmdpZnkodGhpcy5fLm5leHRDaGFyKX0gaW5zdGVhZCBvZiBkZWxpbWl0ZXIgJHtKU09OLnN0cmluZ2lmeSh0aGlzLm9wdGlvbnMuZGVsaW1pdGVyKX1gKSkge1xuICAgICAgICAgICAgICByZXR1cm4gZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICgodGhpcy5fLm5leHRDaGFyICE9IG51bGwpICYmIGlzTmV4dENoYXJUcmltYWJsZSkge1xuICAgICAgICAgIGkrKztcbiAgICAgICAgICB0aGlzLl8ucXVvdGluZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMuXy5jbG9zaW5nUXVvdGUgPSB0aGlzLm9wdGlvbnMucXVvdGUubGVuZ3RoO1xuICAgICAgICAgIHRoaXMuXy5hY2NlcHRPbmx5RW1wdHlDaGFycyA9IHRydWU7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaSsrO1xuICAgICAgICAgIHRoaXMuXy5xdW90aW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5fLmNsb3NpbmdRdW90ZSA9IHRoaXMub3B0aW9ucy5xdW90ZS5sZW5ndGg7XG4gICAgICAgICAgaWYgKGVuZCAmJiBpID09PSBsKSB7XG4gICAgICAgICAgICB0aGlzLl8ubGluZS5wdXNoKGNhc3QodGhpcy5fLmZpZWxkIHx8ICcnKSk7XG4gICAgICAgICAgICB0aGlzLl8uZmllbGQgPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghdGhpcy5fLmZpZWxkKSB7XG4gICAgICAgIHRoaXMuXy5xdW90aW5nID0gdHJ1ZTtcbiAgICAgICAgaSsrO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH0gZWxzZSBpZiAoKHRoaXMuXy5maWVsZCAhPSBudWxsKSAmJiAhdGhpcy5vcHRpb25zLnJlbGF4KSB7XG4gICAgICAgIGlmIChlcnIgPSB0aGlzLmVycm9yKGBJbnZhbGlkIG9wZW5pbmcgcXVvdGUgYXQgbGluZSAke3RoaXMubGluZXMgKyAxfWApKSB7XG4gICAgICAgICAgcmV0dXJuIGVycjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBPdGhlcndpc2UsIHRyZWF0IHF1b3RlIGFzIGEgcmVndWxhciBjaGFyYWN0ZXJcbiAgICBpc1Jvd0RlbGltaXRlciA9IHRoaXMub3B0aW9ucy5yb3dEZWxpbWl0ZXIgJiYgdGhpcy5vcHRpb25zLnJvd0RlbGltaXRlci5zb21lKGZ1bmN0aW9uKHJkKSB7XG4gICAgICByZXR1cm4gY2hhcnMuc3Vic3RyKGksIHJkLmxlbmd0aCkgPT09IHJkO1xuICAgIH0pO1xuICAgIGlmIChpc1Jvd0RlbGltaXRlciB8fCAoZW5kICYmIGkgPT09IGwgLSAxKSkge1xuICAgICAgdGhpcy5saW5lcysrO1xuICAgIH1cbiAgICAvLyBTZXQgdGhlIGNvbW1lbnRpbmcgZmxhZ1xuICAgIHdhc0NvbW1lbnRpbmcgPSBmYWxzZTtcbiAgICBpZiAoIXRoaXMuXy5jb21tZW50aW5nICYmICF0aGlzLl8ucXVvdGluZyAmJiB0aGlzLm9wdGlvbnMuY29tbWVudCAmJiBjaGFycy5zdWJzdHIoaSwgdGhpcy5vcHRpb25zLmNvbW1lbnQubGVuZ3RoKSA9PT0gdGhpcy5vcHRpb25zLmNvbW1lbnQpIHtcbiAgICAgIHRoaXMuXy5jb21tZW50aW5nID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuXy5jb21tZW50aW5nICYmIGlzUm93RGVsaW1pdGVyKSB7XG4gICAgICB3YXNDb21tZW50aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuXy5jb21tZW50aW5nID0gZmFsc2U7XG4gICAgfVxuICAgIGlzRGVsaW1pdGVyID0gY2hhcnMuc3Vic3RyKGksIHRoaXMub3B0aW9ucy5kZWxpbWl0ZXIubGVuZ3RoKSA9PT0gdGhpcy5vcHRpb25zLmRlbGltaXRlcjtcbiAgICBpZiAodGhpcy5fLmFjY2VwdE9ubHlFbXB0eUNoYXJzKSB7XG4gICAgICBpZiAoaXNEZWxpbWl0ZXIgfHwgaXNSb3dEZWxpbWl0ZXIpIHtcbiAgICAgICAgdGhpcy5fLmFjY2VwdE9ubHlFbXB0eUNoYXJzID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoY2hhciA9PT0gJyAnIHx8IGNoYXIgPT09ICdcXHQnKSB7XG4gICAgICAgICAgaSsrO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVycm9yKCdPbmx5IHRyaW1hYmxlIGNoYXJhY3RlcnMgYXJlIGFjY2VwdGVkIGFmdGVyIHF1b3RlcycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghdGhpcy5fLmNvbW1lbnRpbmcgJiYgIXRoaXMuXy5xdW90aW5nICYmIChpc0RlbGltaXRlciB8fCBpc1Jvd0RlbGltaXRlcikpIHtcbiAgICAgIGlmIChpc1Jvd0RlbGltaXRlcikge1xuICAgICAgICBpc1Jvd0RlbGltaXRlckxlbmd0aCA9IHRoaXMub3B0aW9ucy5yb3dEZWxpbWl0ZXIuZmlsdGVyKGZ1bmN0aW9uKHJkKSB7XG4gICAgICAgICAgcmV0dXJuIGNoYXJzLnN1YnN0cihpLCByZC5sZW5ndGgpID09PSByZDtcbiAgICAgICAgfSlbMF0ubGVuZ3RoO1xuICAgICAgfVxuICAgICAgLy8gRW1wdHkgbGluZXNcbiAgICAgIGlmIChpc1Jvd0RlbGltaXRlciAmJiB0aGlzLl8ubGluZS5sZW5ndGggPT09IDAgJiYgKHRoaXMuXy5maWVsZCA9PSBudWxsKSkge1xuICAgICAgICBpZiAod2FzQ29tbWVudGluZyB8fCB0aGlzLm9wdGlvbnMuc2tpcF9lbXB0eV9saW5lcykge1xuICAgICAgICAgIGkgKz0gaXNSb3dEZWxpbWl0ZXJMZW5ndGg7XG4gICAgICAgICAgdGhpcy5fLm5leHRDaGFyID0gY2hhcnMuY2hhckF0KGkpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAocnRyaW0pIHtcbiAgICAgICAgaWYgKCF0aGlzLl8uY2xvc2luZ1F1b3RlKSB7XG4gICAgICAgICAgdGhpcy5fLmZpZWxkID0gKHJlZjIgPSB0aGlzLl8uZmllbGQpICE9IG51bGwgPyByZWYyLnRyaW1SaWdodCgpIDogdm9pZCAwO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLl8ubGluZS5wdXNoKGNhc3QodGhpcy5fLmZpZWxkIHx8ICcnKSk7XG4gICAgICB0aGlzLl8uY2xvc2luZ1F1b3RlID0gMDtcbiAgICAgIHRoaXMuXy5maWVsZCA9IG51bGw7XG4gICAgICBpZiAoaXNEZWxpbWl0ZXIpIHsgLy8gRW5kIG9mIGZpZWxkXG4gICAgICAgIGkgKz0gdGhpcy5vcHRpb25zLmRlbGltaXRlci5sZW5ndGg7XG4gICAgICAgIHRoaXMuXy5uZXh0Q2hhciA9IGNoYXJzLmNoYXJBdChpKTtcbiAgICAgICAgaWYgKGVuZCAmJiAhdGhpcy5fLm5leHRDaGFyKSB7XG4gICAgICAgICAgaXNSb3dEZWxpbWl0ZXIgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuXy5saW5lLnB1c2goJycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaXNSb3dEZWxpbWl0ZXIpIHsgLy8gRW5kIG9mIHJlY29yZFxuICAgICAgICBpZiAoIXRoaXMuXy5saW5lSGFzRXJyb3IpIHtcbiAgICAgICAgICBlcnIgPSB0aGlzLl9fcHVzaCh0aGlzLl8ubGluZSk7XG4gICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgcmV0dXJuIGVycjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuXy5saW5lSGFzRXJyb3IpIHtcbiAgICAgICAgICB0aGlzLl8ubGluZUhhc0Vycm9yID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU29tZSBjbGVhbnVwIGZvciB0aGUgbmV4dCByZWNvcmRcbiAgICAgICAgdGhpcy5fLmxpbmUgPSBbXTtcbiAgICAgICAgaSArPSBpc1Jvd0RlbGltaXRlckxlbmd0aDtcbiAgICAgICAgdGhpcy5fLm5leHRDaGFyID0gY2hhcnMuY2hhckF0KGkpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCF0aGlzLl8uY29tbWVudGluZyAmJiAhdGhpcy5fLnF1b3RpbmcgJiYgKGNoYXIgPT09ICcgJyB8fCBjaGFyID09PSAnXFx0JykpIHtcbiAgICAgIGlmICh0aGlzLl8uZmllbGQgPT0gbnVsbCkge1xuICAgICAgICAvLyBMZWZ0IHRyaW0gdW5sZXNzIHdlIGFyZSBxdW90aW5nIG9yIGZpZWxkIGFscmVhZHkgZmlsbGVkXG4gICAgICAgIHRoaXMuXy5maWVsZCA9ICcnO1xuICAgICAgfVxuICAgICAgaWYgKCEobHRyaW0gJiYgIXRoaXMuXy5maWVsZCkpIHtcbiAgICAgICAgdGhpcy5fLmZpZWxkICs9IGNoYXI7XG4gICAgICB9XG4gICAgICBpKys7XG4gICAgfSBlbHNlIGlmICghdGhpcy5fLmNvbW1lbnRpbmcpIHtcbiAgICAgIGlmICh0aGlzLl8uZmllbGQgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLl8uZmllbGQgPSAnJztcbiAgICAgIH1cbiAgICAgIHRoaXMuXy5maWVsZCArPSBjaGFyO1xuICAgICAgaSsrO1xuICAgIH0gZWxzZSB7XG4gICAgICBpKys7XG4gICAgfVxuICAgIGlmICghdGhpcy5fLmNvbW1lbnRpbmcgJiYgKChyZWYzID0gdGhpcy5fLmZpZWxkKSAhPSBudWxsID8gcmVmMy5sZW5ndGggOiB2b2lkIDApID4gdGhpcy5vcHRpb25zLm1heF9saW1pdF9vbl9kYXRhX3JlYWQpIHtcbiAgICAgIHJldHVybiBFcnJvcihgRmllbGQgZXhjZWVkcyBtYXhfbGltaXRfb25fZGF0YV9yZWFkIHNldHRpbmcgKCR7dGhpcy5vcHRpb25zLm1heF9saW1pdF9vbl9kYXRhX3JlYWR9KSAke0pTT04uc3RyaW5naWZ5KHRoaXMub3B0aW9ucy5kZWxpbWl0ZXIpfWApO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuXy5jb21tZW50aW5nICYmICgocmVmNCA9IHRoaXMuXy5saW5lKSAhPSBudWxsID8gcmVmNC5sZW5ndGggOiB2b2lkIDApID4gdGhpcy5vcHRpb25zLm1heF9saW1pdF9vbl9kYXRhX3JlYWQpIHtcbiAgICAgIHJldHVybiBFcnJvcihgUm93IGRlbGltaXRlciBub3QgZm91bmQgaW4gdGhlIGZpbGUgJHtKU09OLnN0cmluZ2lmeSh0aGlzLm9wdGlvbnMucm93RGVsaW1pdGVyKX1gKTtcbiAgICB9XG4gIH1cbiAgLy8gRmx1c2ggcmVtYWluaW5nIGZpZWxkcyBhbmQgbGluZXNcbiAgaWYgKGVuZCkge1xuICAgIGlmIChsID09PSAwKSB7XG4gICAgICB0aGlzLmxpbmVzKys7XG4gICAgfVxuICAgIGlmICh0aGlzLl8uZmllbGQgIT0gbnVsbCkge1xuICAgICAgaWYgKHJ0cmltKSB7XG4gICAgICAgIGlmICghdGhpcy5fLmNsb3NpbmdRdW90ZSkge1xuICAgICAgICAgIHRoaXMuXy5maWVsZCA9IChyZWY1ID0gdGhpcy5fLmZpZWxkKSAhPSBudWxsID8gcmVmNS50cmltUmlnaHQoKSA6IHZvaWQgMDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5fLmxpbmUucHVzaChjYXN0KHRoaXMuXy5maWVsZCB8fCAnJykpO1xuICAgICAgdGhpcy5fLmZpZWxkID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKCgocmVmNiA9IHRoaXMuXy5maWVsZCkgIT0gbnVsbCA/IHJlZjYubGVuZ3RoIDogdm9pZCAwKSA+IHRoaXMub3B0aW9ucy5tYXhfbGltaXRfb25fZGF0YV9yZWFkKSB7XG4gICAgICByZXR1cm4gRXJyb3IoYERlbGltaXRlciBub3QgZm91bmQgaW4gdGhlIGZpbGUgJHtKU09OLnN0cmluZ2lmeSh0aGlzLm9wdGlvbnMuZGVsaW1pdGVyKX1gKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuXy5saW5lLmxlbmd0aCA+IHRoaXMub3B0aW9ucy5tYXhfbGltaXRfb25fZGF0YV9yZWFkKSB7XG4gICAgICByZXR1cm4gRXJyb3IoYFJvdyBkZWxpbWl0ZXIgbm90IGZvdW5kIGluIHRoZSBmaWxlICR7SlNPTi5zdHJpbmdpZnkodGhpcy5vcHRpb25zLnJvd0RlbGltaXRlcil9YCk7XG4gICAgfVxuICB9XG4gIC8vIFN0b3JlIHVuLXBhcnNlZCBjaGFycyBmb3IgbmV4dCBjYWxsXG4gIHRoaXMuXy5idWYgPSBjaGFycy5zdWJzdHIoaSk7XG4gIHJldHVybiBudWxsO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5lcnJvciA9IGZ1bmN0aW9uKG1zZykge1xuICB2YXIgZXJyO1xuICBlcnIgPSBFcnJvcihtc2cpO1xuICBpZiAoIXRoaXMub3B0aW9ucy5za2lwX2xpbmVzX3dpdGhfZXJyb3IpIHtcbiAgICByZXR1cm4gZXJyO1xuICB9IGVsc2Uge1xuICAgIGlmICghdGhpcy5fLmxpbmVIYXNFcnJvcikge1xuICAgICAgdGhpcy5fLmxpbmVIYXNFcnJvciA9IHRydWU7XG4gICAgICB0aGlzLmVtaXQoJ3NraXAnLCBlcnIpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn07XG5cbi8vICMjIFV0aWxzXG5pc09iakxpdGVyYWwgPSBmdW5jdGlvbihfb2JqKSB7XG4gIHZhciBfdGVzdDtcbiAgX3Rlc3QgPSBfb2JqO1xuICBpZiAodHlwZW9mIF9vYmogIT09ICdvYmplY3QnIHx8IF9vYmogPT09IG51bGwgfHwgQXJyYXkuaXNBcnJheShfb2JqKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gKGZ1bmN0aW9uKCkge1xuICAgICAgd2hpbGUgKCFmYWxzZSkge1xuICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKF90ZXN0ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKF90ZXN0KSkgPT09IG51bGwpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIE9iamVjdC5nZXRQcm90b3R5cGVPZihfb2JqID09PSBfdGVzdCk7XG4gICAgfSkoKTtcbiAgfVxufTtcblxuLy8gW3JlYWRtZV06IGh0dHBzOi8vZ2l0aHViLmNvbS93ZGF2aWR3L25vZGUtY3N2LXBhcnNlXG4vLyBbc2l0ZV06IGh0dHA6Ly9jc3YuYWRhbHRhcy5jb20vcGFyc2UvXG4vLyBbc2FtcGxlc106IGh0dHBzOi8vZ2l0aHViLmNvbS93ZGF2aWR3L25vZGUtY3N2LXBhcnNlL3RyZWUvbWFzdGVyL3NhbXBsZXNcbi8vIFt0ZXN0c106IGh0dHBzOi8vZ2l0aHViLmNvbS93ZGF2aWR3L25vZGUtY3N2LXBhcnNlL3RyZWUvbWFzdGVyL3Rlc3Rcbi8vIFtzdHJlYW1dOiAoaHR0cDovL25vZGVqcy5vcmcvYXBpL3N0cmVhbS5odG1sXG4vLyBbdHJhbnNmb3JtXTogKGh0dHA6Ly9ub2RlanMub3JnL2FwaS9zdHJlYW0uaHRtbCNzdHJlYW1fY2xhc3Nfc3RyZWFtX3RyYW5zZm9ybV8xKVxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2Nzdi1wYXJzZS9saWIvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDEzN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiBGaWxlU2F2ZXIuanNcbiAqIEEgc2F2ZUFzKCkgRmlsZVNhdmVyIGltcGxlbWVudGF0aW9uLlxuICogMS4zLjJcbiAqIDIwMTYtMDYtMTYgMTg6MjU6MTlcbiAqXG4gKiBCeSBFbGkgR3JleSwgaHR0cDovL2VsaWdyZXkuY29tXG4gKiBMaWNlbnNlOiBNSVRcbiAqICAgU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9lbGlncmV5L0ZpbGVTYXZlci5qcy9ibG9iL21hc3Rlci9MSUNFTlNFLm1kXG4gKi9cblxuLypnbG9iYWwgc2VsZiAqL1xuLypqc2xpbnQgYml0d2lzZTogdHJ1ZSwgaW5kZW50OiA0LCBsYXhicmVhazogdHJ1ZSwgbGF4Y29tbWE6IHRydWUsIHNtYXJ0dGFiczogdHJ1ZSwgcGx1c3BsdXM6IHRydWUgKi9cblxuLyohIEBzb3VyY2UgaHR0cDovL3B1cmwuZWxpZ3JleS5jb20vZ2l0aHViL0ZpbGVTYXZlci5qcy9ibG9iL21hc3Rlci9GaWxlU2F2ZXIuanMgKi9cblxudmFyIHNhdmVBcyA9IHNhdmVBcyB8fCAoZnVuY3Rpb24odmlldykge1xuXHRcInVzZSBzdHJpY3RcIjtcblx0Ly8gSUUgPDEwIGlzIGV4cGxpY2l0bHkgdW5zdXBwb3J0ZWRcblx0aWYgKHR5cGVvZiB2aWV3ID09PSBcInVuZGVmaW5lZFwiIHx8IHR5cGVvZiBuYXZpZ2F0b3IgIT09IFwidW5kZWZpbmVkXCIgJiYgL01TSUUgWzEtOV1cXC4vLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHtcblx0XHRyZXR1cm47XG5cdH1cblx0dmFyXG5cdFx0ICBkb2MgPSB2aWV3LmRvY3VtZW50XG5cdFx0ICAvLyBvbmx5IGdldCBVUkwgd2hlbiBuZWNlc3NhcnkgaW4gY2FzZSBCbG9iLmpzIGhhc24ndCBvdmVycmlkZGVuIGl0IHlldFxuXHRcdCwgZ2V0X1VSTCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHZpZXcuVVJMIHx8IHZpZXcud2Via2l0VVJMIHx8IHZpZXc7XG5cdFx0fVxuXHRcdCwgc2F2ZV9saW5rID0gZG9jLmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIiwgXCJhXCIpXG5cdFx0LCBjYW5fdXNlX3NhdmVfbGluayA9IFwiZG93bmxvYWRcIiBpbiBzYXZlX2xpbmtcblx0XHQsIGNsaWNrID0gZnVuY3Rpb24obm9kZSkge1xuXHRcdFx0dmFyIGV2ZW50ID0gbmV3IE1vdXNlRXZlbnQoXCJjbGlja1wiKTtcblx0XHRcdG5vZGUuZGlzcGF0Y2hFdmVudChldmVudCk7XG5cdFx0fVxuXHRcdCwgaXNfc2FmYXJpID0gL2NvbnN0cnVjdG9yL2kudGVzdCh2aWV3LkhUTUxFbGVtZW50KSB8fCB2aWV3LnNhZmFyaVxuXHRcdCwgaXNfY2hyb21lX2lvcyA9L0NyaU9TXFwvW1xcZF0rLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpXG5cdFx0LCB0aHJvd19vdXRzaWRlID0gZnVuY3Rpb24oZXgpIHtcblx0XHRcdCh2aWV3LnNldEltbWVkaWF0ZSB8fCB2aWV3LnNldFRpbWVvdXQpKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR0aHJvdyBleDtcblx0XHRcdH0sIDApO1xuXHRcdH1cblx0XHQsIGZvcmNlX3NhdmVhYmxlX3R5cGUgPSBcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiXG5cdFx0Ly8gdGhlIEJsb2IgQVBJIGlzIGZ1bmRhbWVudGFsbHkgYnJva2VuIGFzIHRoZXJlIGlzIG5vIFwiZG93bmxvYWRmaW5pc2hlZFwiIGV2ZW50IHRvIHN1YnNjcmliZSB0b1xuXHRcdCwgYXJiaXRyYXJ5X3Jldm9rZV90aW1lb3V0ID0gMTAwMCAqIDQwIC8vIGluIG1zXG5cdFx0LCByZXZva2UgPSBmdW5jdGlvbihmaWxlKSB7XG5cdFx0XHR2YXIgcmV2b2tlciA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAodHlwZW9mIGZpbGUgPT09IFwic3RyaW5nXCIpIHsgLy8gZmlsZSBpcyBhbiBvYmplY3QgVVJMXG5cdFx0XHRcdFx0Z2V0X1VSTCgpLnJldm9rZU9iamVjdFVSTChmaWxlKTtcblx0XHRcdFx0fSBlbHNlIHsgLy8gZmlsZSBpcyBhIEZpbGVcblx0XHRcdFx0XHRmaWxlLnJlbW92ZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdFx0c2V0VGltZW91dChyZXZva2VyLCBhcmJpdHJhcnlfcmV2b2tlX3RpbWVvdXQpO1xuXHRcdH1cblx0XHQsIGRpc3BhdGNoID0gZnVuY3Rpb24oZmlsZXNhdmVyLCBldmVudF90eXBlcywgZXZlbnQpIHtcblx0XHRcdGV2ZW50X3R5cGVzID0gW10uY29uY2F0KGV2ZW50X3R5cGVzKTtcblx0XHRcdHZhciBpID0gZXZlbnRfdHlwZXMubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0XHR2YXIgbGlzdGVuZXIgPSBmaWxlc2F2ZXJbXCJvblwiICsgZXZlbnRfdHlwZXNbaV1dO1xuXHRcdFx0XHRpZiAodHlwZW9mIGxpc3RlbmVyID09PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0bGlzdGVuZXIuY2FsbChmaWxlc2F2ZXIsIGV2ZW50IHx8IGZpbGVzYXZlcik7XG5cdFx0XHRcdFx0fSBjYXRjaCAoZXgpIHtcblx0XHRcdFx0XHRcdHRocm93X291dHNpZGUoZXgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHQsIGF1dG9fYm9tID0gZnVuY3Rpb24oYmxvYikge1xuXHRcdFx0Ly8gcHJlcGVuZCBCT00gZm9yIFVURi04IFhNTCBhbmQgdGV4dC8qIHR5cGVzIChpbmNsdWRpbmcgSFRNTClcblx0XHRcdC8vIG5vdGU6IHlvdXIgYnJvd3NlciB3aWxsIGF1dG9tYXRpY2FsbHkgY29udmVydCBVVEYtMTYgVStGRUZGIHRvIEVGIEJCIEJGXG5cdFx0XHRpZiAoL15cXHMqKD86dGV4dFxcL1xcUyp8YXBwbGljYXRpb25cXC94bWx8XFxTKlxcL1xcUypcXCt4bWwpXFxzKjsuKmNoYXJzZXRcXHMqPVxccyp1dGYtOC9pLnRlc3QoYmxvYi50eXBlKSkge1xuXHRcdFx0XHRyZXR1cm4gbmV3IEJsb2IoW1N0cmluZy5mcm9tQ2hhckNvZGUoMHhGRUZGKSwgYmxvYl0sIHt0eXBlOiBibG9iLnR5cGV9KTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBibG9iO1xuXHRcdH1cblx0XHQsIEZpbGVTYXZlciA9IGZ1bmN0aW9uKGJsb2IsIG5hbWUsIG5vX2F1dG9fYm9tKSB7XG5cdFx0XHRpZiAoIW5vX2F1dG9fYm9tKSB7XG5cdFx0XHRcdGJsb2IgPSBhdXRvX2JvbShibG9iKTtcblx0XHRcdH1cblx0XHRcdC8vIEZpcnN0IHRyeSBhLmRvd25sb2FkLCB0aGVuIHdlYiBmaWxlc3lzdGVtLCB0aGVuIG9iamVjdCBVUkxzXG5cdFx0XHR2YXJcblx0XHRcdFx0ICBmaWxlc2F2ZXIgPSB0aGlzXG5cdFx0XHRcdCwgdHlwZSA9IGJsb2IudHlwZVxuXHRcdFx0XHQsIGZvcmNlID0gdHlwZSA9PT0gZm9yY2Vfc2F2ZWFibGVfdHlwZVxuXHRcdFx0XHQsIG9iamVjdF91cmxcblx0XHRcdFx0LCBkaXNwYXRjaF9hbGwgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRkaXNwYXRjaChmaWxlc2F2ZXIsIFwid3JpdGVzdGFydCBwcm9ncmVzcyB3cml0ZSB3cml0ZWVuZFwiLnNwbGl0KFwiIFwiKSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Ly8gb24gYW55IGZpbGVzeXMgZXJyb3JzIHJldmVydCB0byBzYXZpbmcgd2l0aCBvYmplY3QgVVJMc1xuXHRcdFx0XHQsIGZzX2Vycm9yID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0aWYgKChpc19jaHJvbWVfaW9zIHx8IChmb3JjZSAmJiBpc19zYWZhcmkpKSAmJiB2aWV3LkZpbGVSZWFkZXIpIHtcblx0XHRcdFx0XHRcdC8vIFNhZmFyaSBkb2Vzbid0IGFsbG93IGRvd25sb2FkaW5nIG9mIGJsb2IgdXJsc1xuXHRcdFx0XHRcdFx0dmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG5cdFx0XHRcdFx0XHRyZWFkZXIub25sb2FkZW5kID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdHZhciB1cmwgPSBpc19jaHJvbWVfaW9zID8gcmVhZGVyLnJlc3VsdCA6IHJlYWRlci5yZXN1bHQucmVwbGFjZSgvXmRhdGE6W147XSo7LywgJ2RhdGE6YXR0YWNobWVudC9maWxlOycpO1xuXHRcdFx0XHRcdFx0XHR2YXIgcG9wdXAgPSB2aWV3Lm9wZW4odXJsLCAnX2JsYW5rJyk7XG5cdFx0XHRcdFx0XHRcdGlmKCFwb3B1cCkgdmlldy5sb2NhdGlvbi5ocmVmID0gdXJsO1xuXHRcdFx0XHRcdFx0XHR1cmw9dW5kZWZpbmVkOyAvLyByZWxlYXNlIHJlZmVyZW5jZSBiZWZvcmUgZGlzcGF0Y2hpbmdcblx0XHRcdFx0XHRcdFx0ZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTtcblx0XHRcdFx0XHRcdFx0ZGlzcGF0Y2hfYWxsKCk7XG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0cmVhZGVyLnJlYWRBc0RhdGFVUkwoYmxvYik7XG5cdFx0XHRcdFx0XHRmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5JTklUO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHQvLyBkb24ndCBjcmVhdGUgbW9yZSBvYmplY3QgVVJMcyB0aGFuIG5lZWRlZFxuXHRcdFx0XHRcdGlmICghb2JqZWN0X3VybCkge1xuXHRcdFx0XHRcdFx0b2JqZWN0X3VybCA9IGdldF9VUkwoKS5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmIChmb3JjZSkge1xuXHRcdFx0XHRcdFx0dmlldy5sb2NhdGlvbi5ocmVmID0gb2JqZWN0X3VybDtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0dmFyIG9wZW5lZCA9IHZpZXcub3BlbihvYmplY3RfdXJsLCBcIl9ibGFua1wiKTtcblx0XHRcdFx0XHRcdGlmICghb3BlbmVkKSB7XG5cdFx0XHRcdFx0XHRcdC8vIEFwcGxlIGRvZXMgbm90IGFsbG93IHdpbmRvdy5vcGVuLCBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIuYXBwbGUuY29tL2xpYnJhcnkvc2FmYXJpL2RvY3VtZW50YXRpb24vVG9vbHMvQ29uY2VwdHVhbC9TYWZhcmlFeHRlbnNpb25HdWlkZS9Xb3JraW5nd2l0aFdpbmRvd3NhbmRUYWJzL1dvcmtpbmd3aXRoV2luZG93c2FuZFRhYnMuaHRtbFxuXHRcdFx0XHRcdFx0XHR2aWV3LmxvY2F0aW9uLmhyZWYgPSBvYmplY3RfdXJsO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5ET05FO1xuXHRcdFx0XHRcdGRpc3BhdGNoX2FsbCgpO1xuXHRcdFx0XHRcdHJldm9rZShvYmplY3RfdXJsKTtcblx0XHRcdFx0fVxuXHRcdFx0O1xuXHRcdFx0ZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuSU5JVDtcblxuXHRcdFx0aWYgKGNhbl91c2Vfc2F2ZV9saW5rKSB7XG5cdFx0XHRcdG9iamVjdF91cmwgPSBnZXRfVVJMKCkuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuXHRcdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHNhdmVfbGluay5ocmVmID0gb2JqZWN0X3VybDtcblx0XHRcdFx0XHRzYXZlX2xpbmsuZG93bmxvYWQgPSBuYW1lO1xuXHRcdFx0XHRcdGNsaWNrKHNhdmVfbGluayk7XG5cdFx0XHRcdFx0ZGlzcGF0Y2hfYWxsKCk7XG5cdFx0XHRcdFx0cmV2b2tlKG9iamVjdF91cmwpO1xuXHRcdFx0XHRcdGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLkRPTkU7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGZzX2Vycm9yKCk7XG5cdFx0fVxuXHRcdCwgRlNfcHJvdG8gPSBGaWxlU2F2ZXIucHJvdG90eXBlXG5cdFx0LCBzYXZlQXMgPSBmdW5jdGlvbihibG9iLCBuYW1lLCBub19hdXRvX2JvbSkge1xuXHRcdFx0cmV0dXJuIG5ldyBGaWxlU2F2ZXIoYmxvYiwgbmFtZSB8fCBibG9iLm5hbWUgfHwgXCJkb3dubG9hZFwiLCBub19hdXRvX2JvbSk7XG5cdFx0fVxuXHQ7XG5cdC8vIElFIDEwKyAobmF0aXZlIHNhdmVBcylcblx0aWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT09IFwidW5kZWZpbmVkXCIgJiYgbmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IpIHtcblx0XHRyZXR1cm4gZnVuY3Rpb24oYmxvYiwgbmFtZSwgbm9fYXV0b19ib20pIHtcblx0XHRcdG5hbWUgPSBuYW1lIHx8IGJsb2IubmFtZSB8fCBcImRvd25sb2FkXCI7XG5cblx0XHRcdGlmICghbm9fYXV0b19ib20pIHtcblx0XHRcdFx0YmxvYiA9IGF1dG9fYm9tKGJsb2IpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iKGJsb2IsIG5hbWUpO1xuXHRcdH07XG5cdH1cblxuXHRGU19wcm90by5hYm9ydCA9IGZ1bmN0aW9uKCl7fTtcblx0RlNfcHJvdG8ucmVhZHlTdGF0ZSA9IEZTX3Byb3RvLklOSVQgPSAwO1xuXHRGU19wcm90by5XUklUSU5HID0gMTtcblx0RlNfcHJvdG8uRE9ORSA9IDI7XG5cblx0RlNfcHJvdG8uZXJyb3IgPVxuXHRGU19wcm90by5vbndyaXRlc3RhcnQgPVxuXHRGU19wcm90by5vbnByb2dyZXNzID1cblx0RlNfcHJvdG8ub253cml0ZSA9XG5cdEZTX3Byb3RvLm9uYWJvcnQgPVxuXHRGU19wcm90by5vbmVycm9yID1cblx0RlNfcHJvdG8ub253cml0ZWVuZCA9XG5cdFx0bnVsbDtcblxuXHRyZXR1cm4gc2F2ZUFzO1xufShcblx0ICAgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgJiYgc2VsZlxuXHR8fCB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIHdpbmRvd1xuXHR8fCB0aGlzLmNvbnRlbnRcbikpO1xuLy8gYHNlbGZgIGlzIHVuZGVmaW5lZCBpbiBGaXJlZm94IGZvciBBbmRyb2lkIGNvbnRlbnQgc2NyaXB0IGNvbnRleHRcbi8vIHdoaWxlIGB0aGlzYCBpcyBuc0lDb250ZW50RnJhbWVNZXNzYWdlTWFuYWdlclxuLy8gd2l0aCBhbiBhdHRyaWJ1dGUgYGNvbnRlbnRgIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHdpbmRvd1xuXG5pZiAodHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUuZXhwb3J0cykge1xuICBtb2R1bGUuZXhwb3J0cy5zYXZlQXMgPSBzYXZlQXM7XG59IGVsc2UgaWYgKCh0eXBlb2YgZGVmaW5lICE9PSBcInVuZGVmaW5lZFwiICYmIGRlZmluZSAhPT0gbnVsbCkgJiYgKGRlZmluZS5hbWQgIT09IG51bGwpKSB7XG4gIGRlZmluZShcIkZpbGVTYXZlci5qc1wiLCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gc2F2ZUFzO1xuICB9KTtcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9maWxlLXNhdmVyL0ZpbGVTYXZlci5qc1xuLy8gbW9kdWxlIGlkID0gMTM4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSBtICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2llZWU3NTQvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDEzOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuXHR2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLldyaXRlciA9IGV4cG9ydHMuVmV4RmxvdyA9IGV4cG9ydHMuVXRpbHMgPSBleHBvcnRzLlRyYWNrID0gZXhwb3J0cy5Qcm9ncmFtQ2hhbmdlRXZlbnQgPSBleHBvcnRzLk5vdGVPbkV2ZW50ID0gZXhwb3J0cy5Ob3RlT2ZmRXZlbnQgPSBleHBvcnRzLk5vdGVFdmVudCA9IGV4cG9ydHMuTWV0YUV2ZW50ID0gZXhwb3J0cy5Db250cm9sbGVyQ2hhbmdlRXZlbnQgPSBleHBvcnRzLkNvbnN0YW50cyA9IGV4cG9ydHMuQ2h1bmsgPSB1bmRlZmluZWQ7XG5cbnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTtcblxudmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTtcblxudmFyIF90b25hbE1pZGkgPSByZXF1aXJlKCd0b25hbC1taWRpJyk7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbi8qKlxuICogT2JqZWN0IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjaHVuayBzZWN0aW9uIG9mIGEgTUlESSBmaWxlLlxuICogQHBhcmFtIHtvYmplY3R9IGZpZWxkcyAtIHt0eXBlOiBudW1iZXIsIGRhdGE6IGFycmF5LCBzaXplOiBhcnJheX1cbiAqIEByZXR1cm4ge0NodW5rfVxuICovXG52YXIgQ2h1bmsgPSBmdW5jdGlvbiBDaHVuayhmaWVsZHMpIHtcblx0X2NsYXNzQ2FsbENoZWNrKHRoaXMsIENodW5rKTtcblxuXHR0aGlzLnR5cGUgPSBmaWVsZHMudHlwZTtcblx0dGhpcy5kYXRhID0gZmllbGRzLmRhdGE7XG5cdHRoaXMuc2l6ZSA9IFswLCAwLCAwLCBmaWVsZHMuZGF0YS5sZW5ndGhdO1xufTtcblxuZXhwb3J0cy5DaHVuayA9IENodW5rO1xuLyoqXG4gKiBNSURJIGZpbGUgZm9ybWF0IGNvbnN0YW50cywgaW5jbHVkaW5nIG5vdGUgLT4gTUlESSBudW1iZXIgdHJhbnNsYXRpb24uXG4gKiBAcmV0dXJuIHtDb25zdGFudHN9XG4gKi9cblxudmFyIENvbnN0YW50cyA9IHtcblx0VkVSU0lPTjogJzEuNS4yJyxcblx0SEVBREVSX0NIVU5LX1RZUEU6IFsweDRkLCAweDU0LCAweDY4LCAweDY0XSwgLy8gTXRoZFxuXHRIRUFERVJfQ0hVTktfTEVOR1RIOiBbMHgwMCwgMHgwMCwgMHgwMCwgMHgwNl0sIC8vIEhlYWRlciBzaXplIGZvciBTTUZcblx0SEVBREVSX0NIVU5LX0ZPUk1BVDA6IFsweDAwLCAweDAwXSwgLy8gTWlkaSBUeXBlIDAgaWRcblx0SEVBREVSX0NIVU5LX0ZPUk1BVDE6IFsweDAwLCAweDAxXSwgLy8gTWlkaSBUeXBlIDEgaWRcblx0SEVBREVSX0NIVU5LX0RJVklTSU9OOiBbMHgwMCwgMHg4MF0sIC8vIERlZmF1bHRzIHRvIDEyOCB0aWNrcyBwZXIgYmVhdFxuXHRUUkFDS19DSFVOS19UWVBFOiBbMHg0ZCwgMHg1NCwgMHg3MiwgMHg2Yl0sIC8vIE1UcmssXG5cdE1FVEFfRVZFTlRfSUQ6IDB4RkYsXG5cdE1FVEFfVEVYVF9JRDogMHgwMSxcblx0TUVUQV9DT1BZUklHSFRfSUQ6IDB4MDIsXG5cdE1FVEFfVFJBQ0tfTkFNRV9JRDogMHgwMyxcblx0TUVUQV9JTlNUUlVNRU5UX05BTUVfSUQ6IDB4MDQsXG5cdE1FVEFfTFlSSUNfSUQ6IDB4MDUsXG5cdE1FVEFfTUFSS0VSX0lEOiAweDA2LFxuXHRNRVRBX0NVRV9QT0lOVDogMHgwNyxcblx0TUVUQV9URU1QT19JRDogMHg1MSxcblx0TUVUQV9TTVRQRV9PRkZTRVQ6IDB4NTQsXG5cdE1FVEFfVElNRV9TSUdOQVRVUkVfSUQ6IDB4NTgsXG5cdE1FVEFfS0VZX1NJR05BVFVSRV9JRDogMHg1OSxcblx0TUVUQV9FTkRfT0ZfVFJBQ0tfSUQ6IFsweDJGLCAweDAwXSxcblx0Q09OVFJPTExFUl9DSEFOR0VfU1RBVFVTOiAweEIwLCAvLyBpbmNsdWRlcyBjaGFubmVsIG51bWJlciAoMClcblx0UFJPR1JBTV9DSEFOR0VfU1RBVFVTOiAweEMwIC8vIGluY2x1ZGVzIGNoYW5uZWwgbnVtYmVyICgwKVxufTtcblxuZXhwb3J0cy5Db25zdGFudHMgPSBDb25zdGFudHM7XG4vKipcbiAqIEhvbGRzIGFsbCBkYXRhIGZvciBhIFwiY29udHJvbGxlciBjaGFuZ2VcIiBNSURJIGV2ZW50XG4gKiBAcGFyYW0ge29iamVjdH0gZmllbGRzIHtjb250cm9sbGVyTnVtYmVyOiBpbnRlZ2VyLCBjb250cm9sbGVyVmFsdWU6IGludGVnZXJ9XG4gKiBAcmV0dXJuIHtDb250cm9sbGVyQ2hhbmdlRXZlbnR9XG4gKi9cblxudmFyIENvbnRyb2xsZXJDaGFuZ2VFdmVudCA9IGZ1bmN0aW9uIENvbnRyb2xsZXJDaGFuZ2VFdmVudChmaWVsZHMpIHtcblx0X2NsYXNzQ2FsbENoZWNrKHRoaXMsIENvbnRyb2xsZXJDaGFuZ2VFdmVudCk7XG5cblx0dGhpcy50eXBlID0gJ2NvbnRyb2xsZXInO1xuXHQvLyBkZWx0YSB0aW1lIGRlZmF1bHRzIHRvIDAuXG5cdHRoaXMuZGF0YSA9IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoMHgwMCkuY29uY2F0KENvbnN0YW50cy5DT05UUk9MTEVSX0NIQU5HRV9TVEFUVVMsIGZpZWxkcy5jb250cm9sbGVyTnVtYmVyLCBmaWVsZHMuY29udHJvbGxlclZhbHVlKTtcbn07XG5cbmV4cG9ydHMuQ29udHJvbGxlckNoYW5nZUV2ZW50ID0gQ29udHJvbGxlckNoYW5nZUV2ZW50O1xuLyoqXG4gKiBPYmplY3QgcmVwcmVzZW50YXRpb24gb2YgYSBtZXRhIGV2ZW50LlxuICogQHBhcmFtIHtvYmplY3R9IGZpZWxkcyAtIHR5cGUsIGRhdGFcbiAqIEByZXR1cm4ge01ldGFFdmVudH1cbiAqL1xuXG52YXIgTWV0YUV2ZW50ID0gZnVuY3Rpb24gTWV0YUV2ZW50KGZpZWxkcykge1xuXHRfY2xhc3NDYWxsQ2hlY2sodGhpcywgTWV0YUV2ZW50KTtcblxuXHR0aGlzLnR5cGUgPSAnbWV0YSc7XG5cdHRoaXMuZGF0YSA9IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoMHgwMCk7IC8vIFN0YXJ0IHdpdGggemVybyB0aW1lIGRlbHRhXG5cdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQoQ29uc3RhbnRzLk1FVEFfRVZFTlRfSUQsIGZpZWxkcy5kYXRhKTtcbn07XG5cbmV4cG9ydHMuTWV0YUV2ZW50ID0gTWV0YUV2ZW50O1xuLyoqXG4gKiBXcmFwcGVyIGZvciBub3RlT25FdmVudC9ub3RlT2ZmRXZlbnQgb2JqZWN0cyB0aGF0IGJ1aWxkcyBib3RoIGV2ZW50cy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZHMgLSB7cGl0Y2g6ICdbQzRdJywgZHVyYXRpb246ICc0Jywgd2FpdDogJzQnLCB2ZWxvY2l0eTogMS0xMDB9XG4gKiBAcmV0dXJuIHtOb3RlRXZlbnR9XG4gKi9cblxudmFyIE5vdGVFdmVudCA9IGZ1bmN0aW9uICgpIHtcblx0ZnVuY3Rpb24gTm90ZUV2ZW50KGZpZWxkcykge1xuXHRcdF9jbGFzc0NhbGxDaGVjayh0aGlzLCBOb3RlRXZlbnQpO1xuXG5cdFx0dGhpcy50eXBlID0gJ25vdGUnO1xuXHRcdHRoaXMucGl0Y2ggPSBVdGlscy50b0FycmF5KGZpZWxkcy5waXRjaCk7XG5cdFx0dGhpcy53YWl0ID0gZmllbGRzLndhaXQgfHwgMDtcblx0XHR0aGlzLmR1cmF0aW9uID0gZmllbGRzLmR1cmF0aW9uO1xuXHRcdHRoaXMuc2VxdWVudGlhbCA9IGZpZWxkcy5zZXF1ZW50aWFsIHx8IGZhbHNlO1xuXHRcdHRoaXMudmVsb2NpdHkgPSBmaWVsZHMudmVsb2NpdHkgfHwgNTA7XG5cdFx0dGhpcy5jaGFubmVsID0gZmllbGRzLmNoYW5uZWwgfHwgMTtcblx0XHR0aGlzLnJlcGVhdCA9IGZpZWxkcy5yZXBlYXQgfHwgMTtcblx0XHR0aGlzLnZlbG9jaXR5ID0gdGhpcy5jb252ZXJ0VmVsb2NpdHkodGhpcy52ZWxvY2l0eSk7XG5cdFx0dGhpcy5ncmFjZSA9IGZpZWxkcy5ncmFjZTtcblx0XHR0aGlzLmJ1aWxkRGF0YSgpO1xuXHR9XG5cblx0LyoqXG4gICogQnVpbGRzIGludCBhcnJheSBmb3IgdGhpcyBldmVudC5cbiAgKiBAcmV0dXJuIHtOb3RlRXZlbnR9XG4gICovXG5cblxuXHRfY3JlYXRlQ2xhc3MoTm90ZUV2ZW50LCBbe1xuXHRcdGtleTogJ2J1aWxkRGF0YScsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIGJ1aWxkRGF0YSgpIHtcblx0XHRcdHRoaXMuZGF0YSA9IFtdO1xuXG5cdFx0XHR2YXIgdGlja0R1cmF0aW9uID0gdGhpcy5nZXRUaWNrRHVyYXRpb24odGhpcy5kdXJhdGlvbiwgJ25vdGUnKTtcblx0XHRcdHZhciByZXN0RHVyYXRpb24gPSB0aGlzLmdldFRpY2tEdXJhdGlvbih0aGlzLndhaXQsICdyZXN0Jyk7XG5cblx0XHRcdC8vIEFwcGx5IGdyYWNlIG5vdGUocykgYW5kIHN1YnRyYWN0IHRpY2tzIChjdXJyZW50bHkgMSB0aWNrIHBlciBncmFjZSBub3RlKSBmcm9tIHRpY2tEdXJhdGlvbiBzbyBuZXQgdmFsdWUgaXMgdGhlIHNhbWVcblx0XHRcdGlmICh0aGlzLmdyYWNlKSB7XG5cdFx0XHRcdHZhciBncmFjZUR1cmF0aW9uID0gMTtcblx0XHRcdFx0dGhpcy5ncmFjZSA9IFV0aWxzLnRvQXJyYXkodGhpcy5ncmFjZSk7XG5cdFx0XHRcdHRoaXMuZ3JhY2UuZm9yRWFjaChmdW5jdGlvbiAocGl0Y2gpIHtcblx0XHRcdFx0XHR2YXIgbm90ZUV2ZW50ID0gbmV3IE5vdGVFdmVudCh7IHBpdGNoOiB0aGlzLmdyYWNlLCBkdXJhdGlvbjogJ1QnICsgZ3JhY2VEdXJhdGlvbiB9KTtcblx0XHRcdFx0XHR0aGlzLmRhdGEgPSB0aGlzLmRhdGEuY29uY2F0KG5vdGVFdmVudC5kYXRhKTtcblxuXHRcdFx0XHRcdHRpY2tEdXJhdGlvbiAtPSBncmFjZUR1cmF0aW9uO1xuXHRcdFx0XHR9LCB0aGlzKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gZmllbGRzLnBpdGNoIGNvdWxkIGJlIGFuIGFycmF5IG9mIHBpdGNoZXMuXG5cdFx0XHQvLyBJZiBzbyBjcmVhdGUgbm90ZSBldmVudHMgZm9yIGVhY2ggYW5kIGFwcGx5IHRoZSBzYW1lIGR1cmF0aW9uLlxuXHRcdFx0dmFyIG5vdGVPbiwgbm90ZU9mZjtcblx0XHRcdGlmIChBcnJheS5pc0FycmF5KHRoaXMucGl0Y2gpKSB7XG5cdFx0XHRcdC8vIEJ5IGRlZmF1bHQgdGhpcyBpcyBhIGNob3JkIGlmIGl0J3MgYW4gYXJyYXkgb2Ygbm90ZXMgdGhhdCByZXF1aXJlcyBvbmUgTm90ZU9uRXZlbnQuXG5cdFx0XHRcdC8vIElmIHRoaXMuc2VxdWVudGlhbCA9PT0gdHJ1ZSB0aGVuIGl0J3MgYSBzZXF1ZW50aWFsIHN0cmluZyBvZiBub3RlcyB0aGF0IHJlcXVpcmVzIHNlcGFyYXRlIE5vdGVPbkV2ZW50cy5cblx0XHRcdFx0aWYgKCF0aGlzLnNlcXVlbnRpYWwpIHtcblx0XHRcdFx0XHQvLyBIYW5kbGUgcmVwZWF0XG5cdFx0XHRcdFx0Zm9yICh2YXIgaiA9IDA7IGogPCB0aGlzLnJlcGVhdDsgaisrKSB7XG5cdFx0XHRcdFx0XHQvLyBOb3RlIG9uXG5cdFx0XHRcdFx0XHR0aGlzLnBpdGNoLmZvckVhY2goZnVuY3Rpb24gKHAsIGkpIHtcblx0XHRcdFx0XHRcdFx0aWYgKGkgPT0gMCkge1xuXHRcdFx0XHRcdFx0XHRcdG5vdGVPbiA9IG5ldyBOb3RlT25FdmVudCh7IGRhdGE6IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgocmVzdER1cmF0aW9uKS5jb25jYXQodGhpcy5nZXROb3RlT25TdGF0dXMoKSwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHkpIH0pO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdC8vIFJ1bm5pbmcgc3RhdHVzIChjYW4gb21taXQgdGhlIG5vdGUgb24gc3RhdHVzKVxuXHRcdFx0XHRcdFx0XHRcdG5vdGVPbiA9IG5ldyBOb3RlT25FdmVudCh7IGRhdGE6IFswLCBVdGlscy5nZXRQaXRjaChwKSwgdGhpcy52ZWxvY2l0eV0gfSk7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHR0aGlzLmRhdGEgPSB0aGlzLmRhdGEuY29uY2F0KG5vdGVPbi5kYXRhKTtcblx0XHRcdFx0XHRcdH0sIHRoaXMpO1xuXG5cdFx0XHRcdFx0XHQvLyBOb3RlIG9mZlxuXHRcdFx0XHRcdFx0dGhpcy5waXRjaC5mb3JFYWNoKGZ1bmN0aW9uIChwLCBpKSB7XG5cdFx0XHRcdFx0XHRcdGlmIChpID09IDApIHtcblx0XHRcdFx0XHRcdFx0XHRub3RlT2ZmID0gbmV3IE5vdGVPZmZFdmVudCh7IGRhdGE6IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgodGlja0R1cmF0aW9uKS5jb25jYXQodGhpcy5nZXROb3RlT2ZmU3RhdHVzKCksIFV0aWxzLmdldFBpdGNoKHApLCB0aGlzLnZlbG9jaXR5KSB9KTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHQvLyBSdW5uaW5nIHN0YXR1cyAoY2FuIG9tbWl0IHRoZSBub3RlIG9mZiBzdGF0dXMpXG5cdFx0XHRcdFx0XHRcdFx0bm90ZU9mZiA9IG5ldyBOb3RlT2ZmRXZlbnQoeyBkYXRhOiBbMCwgVXRpbHMuZ2V0UGl0Y2gocCksIHRoaXMudmVsb2NpdHldIH0pO1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0dGhpcy5kYXRhID0gdGhpcy5kYXRhLmNvbmNhdChub3RlT2ZmLmRhdGEpO1xuXHRcdFx0XHRcdFx0fSwgdGhpcyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIEhhbmRsZSByZXBlYXRcblx0XHRcdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMucmVwZWF0OyBqKyspIHtcblx0XHRcdFx0XHRcdHRoaXMucGl0Y2guZm9yRWFjaChmdW5jdGlvbiAocCwgaSkge1xuXHRcdFx0XHRcdFx0XHQvLyByZXN0RHVyYXRpb24gb25seSBhcHBsaWVzIHRvIGZpcnN0IG5vdGVcblx0XHRcdFx0XHRcdFx0aWYgKGkgPiAwKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmVzdER1cmF0aW9uID0gMDtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdC8vIElmIGR1cmF0aW9uIGlzIDh0aCB0cmlwbGV0cyB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSB0b3RhbCB0aWNrcyA9PSBxdWFydGVyIG5vdGUuXG5cdFx0XHRcdFx0XHRcdC8vIFNvLCB0aGUgbGFzdCBvbmUgd2lsbCBuZWVkIHRvIGJlIHRoZSByZW1haW5kZXJcblx0XHRcdFx0XHRcdFx0aWYgKHRoaXMuZHVyYXRpb24gPT09ICc4dCcgJiYgaSA9PSB0aGlzLnBpdGNoLmxlbmd0aCAtIDEpIHtcblx0XHRcdFx0XHRcdFx0XHR2YXIgcXVhcnRlclRpY2tzID0gVXRpbHMubnVtYmVyRnJvbUJ5dGVzKENvbnN0YW50cy5IRUFERVJfQ0hVTktfRElWSVNJT04pO1xuXHRcdFx0XHRcdFx0XHRcdHRpY2tEdXJhdGlvbiA9IHF1YXJ0ZXJUaWNrcyAtIHRpY2tEdXJhdGlvbiAqIDI7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRub3RlT24gPSBuZXcgTm90ZU9uRXZlbnQoeyBkYXRhOiBVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKHJlc3REdXJhdGlvbikuY29uY2F0KFt0aGlzLmdldE5vdGVPblN0YXR1cygpLCBVdGlscy5nZXRQaXRjaChwKSwgdGhpcy52ZWxvY2l0eV0pIH0pO1xuXHRcdFx0XHRcdFx0XHRub3RlT2ZmID0gbmV3IE5vdGVPZmZFdmVudCh7IGRhdGE6IFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgodGlja0R1cmF0aW9uKS5jb25jYXQoW3RoaXMuZ2V0Tm90ZU9mZlN0YXR1cygpLCBVdGlscy5nZXRQaXRjaChwKSwgdGhpcy52ZWxvY2l0eV0pIH0pO1xuXG5cdFx0XHRcdFx0XHRcdHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5jb25jYXQobm90ZU9uLmRhdGEsIG5vdGVPZmYuZGF0YSk7XG5cdFx0XHRcdFx0XHR9LCB0aGlzKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH1cblxuXHRcdFx0dGhyb3cgJ3BpdGNoIG11c3QgYmUgYW4gYXJyYXkuJztcblx0XHR9XG5cdH0sIHtcblx0XHRrZXk6ICdjb252ZXJ0VmVsb2NpdHknLFxuXG5cblx0XHQvKipcbiAgICogQ29udmVydHMgdmVsb2NpdHkgdG8gdmFsdWUgMC0xMjdcbiAgICogQHBhcmFtIHtudW1iZXJ9IHZlbG9jaXR5IC0gVmVsb2NpdHkgdmFsdWUgMS0xMDBcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cblx0XHR2YWx1ZTogZnVuY3Rpb24gY29udmVydFZlbG9jaXR5KHZlbG9jaXR5KSB7XG5cdFx0XHQvLyBNYXggcGFzc2VkIHZhbHVlIGxpbWl0ZWQgdG8gMTAwXG5cdFx0XHR2ZWxvY2l0eSA9IHZlbG9jaXR5ID4gMTAwID8gMTAwIDogdmVsb2NpdHk7XG5cdFx0XHRyZXR1cm4gTWF0aC5yb3VuZCh2ZWxvY2l0eSAvIDEwMCAqIDEyNyk7XG5cdFx0fVxuXHR9LCB7XG5cdFx0a2V5OiAnZ2V0VGlja0R1cmF0aW9uJyxcblxuXG5cdFx0LyoqXG4gICAqIEdldHMgdGhlIHRvdGFsIG51bWJlciBvZiB0aWNrcyBiYXNlZCBvbiBwYXNzZWQgZHVyYXRpb24uXG4gICAqIE5vdGU6IHR5cGU9PSdub3RlJyBkZWZhdWx0cyB0byBxdWFydGVyIG5vdGUsIHR5cGU9PT0ncmVzdCcgZGVmYXVsdHMgdG8gMFxuICAgKiBAcGFyYW0geyhzdHJpbmd8YXJyYXkpfSBkdXJhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBbJ25vdGUnLCAncmVzdCddXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIGdldFRpY2tEdXJhdGlvbihkdXJhdGlvbiwgdHlwZSkge1xuXHRcdFx0aWYgKEFycmF5LmlzQXJyYXkoZHVyYXRpb24pKSB7XG5cdFx0XHRcdC8vIFJlY3Vyc2l2ZWx5IGV4ZWN1dGUgdGhpcyBtZXRob2QgZm9yIGVhY2ggaXRlbSBpbiB0aGUgYXJyYXkgYW5kIHJldHVybiB0aGUgc3VtIG9mIHRpY2sgZHVyYXRpb25zLlxuXHRcdFx0XHRyZXR1cm4gZHVyYXRpb24ubWFwKGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLmdldFRpY2tEdXJhdGlvbih2YWx1ZSwgdHlwZSk7XG5cdFx0XHRcdH0sIHRoaXMpLnJlZHVjZShmdW5jdGlvbiAoYSwgYikge1xuXHRcdFx0XHRcdHJldHVybiBhICsgYjtcblx0XHRcdFx0fSwgMCk7XG5cdFx0XHR9XG5cblx0XHRcdGR1cmF0aW9uID0gZHVyYXRpb24udG9TdHJpbmcoKTtcblxuXHRcdFx0aWYgKGR1cmF0aW9uLnRvTG93ZXJDYXNlKCkuY2hhckF0KDApID09PSAndCcpIHtcblx0XHRcdFx0Ly8gSWYgZHVyYXRpb24gc3RhcnRzIHdpdGggJ3QnIHRoZW4gdGhlIG51bWJlciB0aGF0IGZvbGxvd3MgaXMgYW4gZXhwbGljaXQgdGljayBjb3VudFxuXHRcdFx0XHRyZXR1cm4gcGFyc2VJbnQoZHVyYXRpb24uc3Vic3RyaW5nKDEpKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTmVlZCB0byBhcHBseSBkdXJhdGlvbiBoZXJlLiAgUXVhcnRlciBub3RlID09IENvbnN0YW50cy5IRUFERVJfQ0hVTktfRElWSVNJT05cblx0XHRcdC8vIFJvdW5kaW5nIG9ubHkgYXBwbGllcyB0byB0cmlwbGV0cywgd2hpY2ggdGhlIHJlbWFpbmRlciBpcyBoYW5kbGVkIGJlbG93XG5cdFx0XHR2YXIgcXVhcnRlclRpY2tzID0gVXRpbHMubnVtYmVyRnJvbUJ5dGVzKENvbnN0YW50cy5IRUFERVJfQ0hVTktfRElWSVNJT04pO1xuXHRcdFx0cmV0dXJuIE1hdGgucm91bmQocXVhcnRlclRpY2tzICogdGhpcy5nZXREdXJhdGlvbk11bHRpcGxpZXIoZHVyYXRpb24sIHR5cGUpKTtcblx0XHR9XG5cblx0XHQvKipcbiAgICogR2V0cyB3aGF0IHRvIG11bHRpcGxlIHRpY2tzL3F1YXJ0ZXIgbm90ZSBieSB0byBnZXQgdGhlIHNwZWNpZmllZCBkdXJhdGlvbi5cbiAgICogTm90ZTogdHlwZT09J25vdGUnIGRlZmF1bHRzIHRvIHF1YXJ0ZXIgbm90ZSwgdHlwZT09PSdyZXN0JyBkZWZhdWx0cyB0byAwXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkdXJhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBbJ25vdGUnLCdyZXN0J11cbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cblxuXHR9LCB7XG5cdFx0a2V5OiAnZ2V0RHVyYXRpb25NdWx0aXBsaWVyJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gZ2V0RHVyYXRpb25NdWx0aXBsaWVyKGR1cmF0aW9uLCB0eXBlKSB7XG5cdFx0XHQvLyBOZWVkIHRvIGFwcGx5IGR1cmF0aW9uIGhlcmUuICBRdWFydGVyIG5vdGUgPT0gQ29uc3RhbnRzLkhFQURFUl9DSFVOS19ESVZJU0lPTlxuXHRcdFx0c3dpdGNoIChkdXJhdGlvbikge1xuXHRcdFx0XHRjYXNlICcwJzpcblx0XHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdFx0Y2FzZSAnMSc6XG5cdFx0XHRcdFx0cmV0dXJuIDQ7XG5cdFx0XHRcdGNhc2UgJzInOlxuXHRcdFx0XHRcdHJldHVybiAyO1xuXHRcdFx0XHRjYXNlICdkMic6XG5cdFx0XHRcdFx0cmV0dXJuIDM7XG5cdFx0XHRcdGNhc2UgJzQnOlxuXHRcdFx0XHRcdHJldHVybiAxO1xuXHRcdFx0XHRjYXNlICc0dCc6XG5cdFx0XHRcdFx0cmV0dXJuIDAuNjY2O1xuXHRcdFx0XHRjYXNlICdkNCc6XG5cdFx0XHRcdFx0cmV0dXJuIDEuNTtcblx0XHRcdFx0Y2FzZSAnOCc6XG5cdFx0XHRcdFx0cmV0dXJuIDAuNTtcblx0XHRcdFx0Y2FzZSAnOHQnOlxuXHRcdFx0XHRcdC8vIEZvciA4dGggdHJpcGxldHMsIGxldCdzIGRpdmlkZSBhIHF1YXJ0ZXIgYnkgMywgcm91bmQgdG8gdGhlIG5lYXJlc3QgaW50LCBhbmQgc3Vic3RyYWN0IHRoZSByZW1haW5kZXIgdG8gdGhlIGxhc3Qgb25lLlxuXHRcdFx0XHRcdHJldHVybiAwLjMzO1xuXHRcdFx0XHRjYXNlICdkOCc6XG5cdFx0XHRcdFx0cmV0dXJuIDAuNzU7XG5cdFx0XHRcdGNhc2UgJzE2Jzpcblx0XHRcdFx0XHRyZXR1cm4gMC4yNTtcblx0XHRcdFx0Y2FzZSAnMTZ0Jzpcblx0XHRcdFx0XHRyZXR1cm4gMC4xNjY7XG5cdFx0XHRcdGNhc2UgJzMyJzpcblx0XHRcdFx0XHRyZXR1cm4gMC4xMjU7XG5cdFx0XHRcdGNhc2UgJzY0Jzpcblx0XHRcdFx0XHRyZXR1cm4gMC4wNjI1O1xuXHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHQvLyBOb3RlcyBkZWZhdWx0IHRvIGEgcXVhcnRlciwgcmVzdHMgZGVmYXVsdCB0byAwXG5cdFx0XHRcdC8vcmV0dXJuIHR5cGUgPT09ICdub3RlJyA/IDEgOiAwO1xuXHRcdFx0fVxuXG5cdFx0XHR0aHJvdyBkdXJhdGlvbiArICcgaXMgbm90IGEgdmFsaWQgZHVyYXRpb24uJztcblx0XHR9XG5cdH0sIHtcblx0XHRrZXk6ICdnZXROb3RlT25TdGF0dXMnLFxuXG5cblx0XHQvKipcbiAgICogR2V0cyB0aGUgbm90ZSBvbiBzdGF0dXMgY29kZSBiYXNlZCBvbiB0aGUgc2VsZWN0ZWQgY2hhbm5lbC4gMHg5ezAtRn1cbiAgICogTm90ZSBvbiBhdCBjaGFubmVsIDAgaXMgMHg5MCAoMTQ0KVxuICAgKiAwID0gQ2ggMVxuICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAqL1xuXHRcdHZhbHVlOiBmdW5jdGlvbiBnZXROb3RlT25TdGF0dXMoKSB7XG5cdFx0XHRyZXR1cm4gMTQ0ICsgdGhpcy5jaGFubmVsIC0gMTtcblx0XHR9XG5cblx0XHQvKipcbiAgICogR2V0cyB0aGUgbm90ZSBvZmYgc3RhdHVzIGNvZGUgYmFzZWQgb24gdGhlIHNlbGVjdGVkIGNoYW5uZWwuIDB4OHswLUZ9XG4gICAqIE5vdGUgb2ZmIGF0IGNoYW5uZWwgMCBpcyAweDgwICgxMjgpXG4gICAqIDAgPSBDaCAxXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG5cblx0fSwge1xuXHRcdGtleTogJ2dldE5vdGVPZmZTdGF0dXMnLFxuXHRcdHZhbHVlOiBmdW5jdGlvbiBnZXROb3RlT2ZmU3RhdHVzKCkge1xuXHRcdFx0cmV0dXJuIDEyOCArIHRoaXMuY2hhbm5lbCAtIDE7XG5cdFx0fVxuXHR9XSk7XG5cblx0cmV0dXJuIE5vdGVFdmVudDtcbn0oKTtcblxuZXhwb3J0cy5Ob3RlRXZlbnQgPSBOb3RlRXZlbnQ7XG4vKipcbiAqIEhvbGRzIGFsbCBkYXRhIGZvciBhIFwibm90ZSBvZmZcIiBNSURJIGV2ZW50XG4gKiBAcGFyYW0ge29iamVjdH0gZmllbGRzIHtkYXRhOiBbXX1cbiAqIEByZXR1cm4ge05vdGVPZmZFdmVudH1cbiAqL1xuXG52YXIgTm90ZU9mZkV2ZW50ID0gZnVuY3Rpb24gTm90ZU9mZkV2ZW50KGZpZWxkcykge1xuXHRfY2xhc3NDYWxsQ2hlY2sodGhpcywgTm90ZU9mZkV2ZW50KTtcblxuXHR0aGlzLmRhdGEgPSBmaWVsZHMuZGF0YTtcbn07XG5cbmV4cG9ydHMuTm90ZU9mZkV2ZW50ID0gTm90ZU9mZkV2ZW50O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSBcIm5vdGUgb25cIiBNSURJIGV2ZW50XG4gKiBAcGFyYW0ge29iamVjdH0gZmllbGRzIHtkYXRhOiBbXX1cbiAqIEByZXR1cm4ge05vdGVPbkV2ZW50fVxuICovXG5cbnZhciBOb3RlT25FdmVudCA9IGZ1bmN0aW9uIE5vdGVPbkV2ZW50KGZpZWxkcykge1xuXHRfY2xhc3NDYWxsQ2hlY2sodGhpcywgTm90ZU9uRXZlbnQpO1xuXG5cdHRoaXMuZGF0YSA9IGZpZWxkcy5kYXRhO1xufTtcblxuZXhwb3J0cy5Ob3RlT25FdmVudCA9IE5vdGVPbkV2ZW50O1xuLyoqXG4gKiBIb2xkcyBhbGwgZGF0YSBmb3IgYSBcInByb2dyYW0gY2hhbmdlXCIgTUlESSBldmVudFxuICogQHBhcmFtIHtvYmplY3R9IGZpZWxkcyB7aW5zdHJ1bWVudDogaW50ZWdlcn1cbiAqIEByZXR1cm4ge1Byb2dyYW1DaGFuZ2VFdmVudH1cbiAqL1xuXG52YXIgUHJvZ3JhbUNoYW5nZUV2ZW50ID0gZnVuY3Rpb24gUHJvZ3JhbUNoYW5nZUV2ZW50KGZpZWxkcykge1xuXHRfY2xhc3NDYWxsQ2hlY2sodGhpcywgUHJvZ3JhbUNoYW5nZUV2ZW50KTtcblxuXHR0aGlzLnR5cGUgPSAncHJvZ3JhbSc7XG5cdC8vIGRlbHRhIHRpbWUgZGVmYXVsdHMgdG8gMC5cblx0dGhpcy5kYXRhID0gVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aCgweDAwKS5jb25jYXQoQ29uc3RhbnRzLlBST0dSQU1fQ0hBTkdFX1NUQVRVUywgZmllbGRzLmluc3RydW1lbnQpO1xufTtcblxuZXhwb3J0cy5Qcm9ncmFtQ2hhbmdlRXZlbnQgPSBQcm9ncmFtQ2hhbmdlRXZlbnQ7XG4vKipcbiAqIEhvbGRzIGFsbCBkYXRhIGZvciBhIHRyYWNrLlxuICogQHBhcmFtIHtvYmplY3R9IGZpZWxkcyB7dHlwZTogbnVtYmVyLCBkYXRhOiBhcnJheSwgc2l6ZTogYXJyYXksIGV2ZW50czogYXJyYXl9XG4gKiBAcmV0dXJuIHtUcmFja31cbiAqL1xuXG52YXIgVHJhY2sgPSBmdW5jdGlvbiAoKSB7XG5cdGZ1bmN0aW9uIFRyYWNrKCkge1xuXHRcdF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUcmFjayk7XG5cblx0XHR0aGlzLnR5cGUgPSBDb25zdGFudHMuVFJBQ0tfQ0hVTktfVFlQRTtcblx0XHR0aGlzLmRhdGEgPSBbXTtcblx0XHR0aGlzLnNpemUgPSBbXTtcblx0XHR0aGlzLmV2ZW50cyA9IFtdO1xuXHR9XG5cblx0LyoqXG4gICogQWRkcyBhbnkgZXZlbnQgdHlwZSB0byB0aGUgdHJhY2suXG4gICogQHBhcmFtIHsoTm90ZUV2ZW50fE1ldGFFdmVudHxQcm9ncmFtQ2hhbmdlRXZlbnQpfSBldmVudCAtIEV2ZW50IG9iamVjdC5cbiAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBtYXBGdW5jdGlvbiAtIENhbGxiYWNrIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGFwcGx5IHNwZWNpZmljIHByb3BlcnRpZXMgdG8gYWxsIGV2ZW50cy4gXG4gICogQHJldHVybiB7VHJhY2t9XG4gICovXG5cblxuXHRfY3JlYXRlQ2xhc3MoVHJhY2ssIFt7XG5cdFx0a2V5OiAnYWRkRXZlbnQnLFxuXHRcdHZhbHVlOiBmdW5jdGlvbiBhZGRFdmVudChldmVudCwgbWFwRnVuY3Rpb24pIHtcblx0XHRcdGlmIChBcnJheS5pc0FycmF5KGV2ZW50KSkge1xuXHRcdFx0XHRldmVudC5mb3JFYWNoKGZ1bmN0aW9uIChlLCBpKSB7XG5cdFx0XHRcdFx0Ly8gSGFuZGxlIG1hcCBmdW5jdGlvbiBpZiBwcm92aWRlZFxuXHRcdFx0XHRcdGlmICh0eXBlb2YgbWFwRnVuY3Rpb24gPT09ICdmdW5jdGlvbicgJiYgZS50eXBlID09PSAnbm90ZScpIHtcblx0XHRcdFx0XHRcdHZhciBwcm9wZXJ0aWVzID0gbWFwRnVuY3Rpb24oaSwgZSk7XG5cblx0XHRcdFx0XHRcdGlmICgodHlwZW9mIHByb3BlcnRpZXMgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHByb3BlcnRpZXMpKSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHRcdFx0Zm9yICh2YXIgaiBpbiBwcm9wZXJ0aWVzKSB7XG5cdFx0XHRcdFx0XHRcdFx0c3dpdGNoIChqKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjYXNlICdkdXJhdGlvbic6XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGUuZHVyYXRpb24gPSBwcm9wZXJ0aWVzW2pdO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHRcdGNhc2UgJ3NlcXVlbnRpYWwnOlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRlLnNlcXVlbnRpYWwgPSBwcm9wZXJ0aWVzW2pdO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHRcdGNhc2UgJ3ZlbG9jaXR5Jzpcblx0XHRcdFx0XHRcdFx0XHRcdFx0ZS52ZWxvY2l0eSA9IGUuY29udmVydFZlbG9jaXR5KHByb3BlcnRpZXNbal0pO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHQvLyBHb3R0YSBidWlsZCB0aGF0IGRhdGFcblx0XHRcdFx0XHRcdFx0ZS5idWlsZERhdGEoKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR0aGlzLmRhdGEgPSB0aGlzLmRhdGEuY29uY2F0KGUuZGF0YSk7XG5cdFx0XHRcdFx0dGhpcy5zaXplID0gVXRpbHMubnVtYmVyVG9CeXRlcyh0aGlzLmRhdGEubGVuZ3RoLCA0KTsgLy8gNCBieXRlcyBsb25nXG5cdFx0XHRcdFx0dGhpcy5ldmVudHMucHVzaChlKTtcblx0XHRcdFx0fSwgdGhpcyk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLmRhdGEgPSB0aGlzLmRhdGEuY29uY2F0KGV2ZW50LmRhdGEpO1xuXHRcdFx0XHR0aGlzLnNpemUgPSBVdGlscy5udW1iZXJUb0J5dGVzKHRoaXMuZGF0YS5sZW5ndGgsIDQpOyAvLyA0IGJ5dGVzIGxvbmdcblx0XHRcdFx0dGhpcy5ldmVudHMucHVzaChldmVudCk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdC8qKlxuICAgKiBTZXRzIHRlbXBvIG9mIHRoZSBNSURJIGZpbGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBicG0gLSBUZW1wbyBpbiBiZWF0cyBwZXIgbWludXRlLlxuICAgKiBAcmV0dXJuIHtUcmFja31cbiAgICovXG5cblx0fSwge1xuXHRcdGtleTogJ3NldFRlbXBvJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gc2V0VGVtcG8oYnBtKSB7XG5cdFx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHsgZGF0YTogW0NvbnN0YW50cy5NRVRBX1RFTVBPX0lEXSB9KTtcblx0XHRcdGV2ZW50LmRhdGEucHVzaCgweDAzKTsgLy8gU2l6ZVxuXHRcdFx0dmFyIHRlbXBvID0gTWF0aC5yb3VuZCg2MDAwMDAwMCAvIGJwbSk7XG5cdFx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9CeXRlcyh0ZW1wbywgMykpOyAvLyBUZW1wbywgMyBieXRlc1xuXHRcdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHRcdH1cblxuXHRcdC8qKlxuICAgKiBTZXRzIHRpbWUgc2lnbmF0dXJlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gbnVtZXJhdG9yIC0gVG9wIG51bWJlciBvZiB0aGUgdGltZSBzaWduYXR1cmUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZW5vbWluYXRvciAtIEJvdHRvbSBudW1iZXIgb2YgdGhlIHRpbWUgc2lnbmF0dXJlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWlkaWNsb2Nrc3BlcnRpY2sgLSBEZWZhdWx0cyB0byAyNC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG5vdGVzcGVybWlkaWNsb2NrIC0gRGVmYXVsdHMgdG8gOC5cbiAgICogQHJldHVybiB7VHJhY2t9XG4gICAqL1xuXG5cdH0sIHtcblx0XHRrZXk6ICdzZXRUaW1lU2lnbmF0dXJlJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gc2V0VGltZVNpZ25hdHVyZShudW1lcmF0b3IsIGRlbm9taW5hdG9yLCBtaWRpY2xvY2tzcGVydGljaywgbm90ZXNwZXJtaWRpY2xvY2spIHtcblx0XHRcdG1pZGljbG9ja3NwZXJ0aWNrID0gbWlkaWNsb2Nrc3BlcnRpY2sgfHwgMjQ7XG5cdFx0XHRub3Rlc3Blcm1pZGljbG9jayA9IG5vdGVzcGVybWlkaWNsb2NrIHx8IDg7XG5cblx0XHRcdHZhciBldmVudCA9IG5ldyBNZXRhRXZlbnQoeyBkYXRhOiBbQ29uc3RhbnRzLk1FVEFfVElNRV9TSUdOQVRVUkVfSURdIH0pO1xuXHRcdFx0ZXZlbnQuZGF0YS5wdXNoKDB4MDQpOyAvLyBTaXplXG5cdFx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9CeXRlcyhudW1lcmF0b3IsIDEpKTsgLy8gTnVtZXJhdG9yLCAxIGJ5dGVzXG5cblx0XHRcdHZhciBfZGVub21pbmF0b3IgPSBNYXRoLmxvZzIoZGVub21pbmF0b3IpOyAvLyBEZW5vbWluYXRvciBpcyBleHByZXNzZWQgYXMgcG93IG9mIDJcblx0XHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKF9kZW5vbWluYXRvciwgMSkpOyAvLyBEZW5vbWluYXRvciwgMSBieXRlc1xuXHRcdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvQnl0ZXMobWlkaWNsb2Nrc3BlcnRpY2ssIDEpKTsgLy8gTUlESSBDbG9ja3MgcGVyIHRpY2ssIDEgYnl0ZXNcblx0XHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKG5vdGVzcGVybWlkaWNsb2NrLCAxKSk7IC8vIE51bWJlciBvZiAxLzMyIG5vdGVzIHBlciBNSURJIGNsb2NrcywgMSBieXRlc1xuXHRcdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHRcdH1cblxuXHRcdC8qKlxuICAgKiBTZXRzIGtleSBzaWduYXR1cmUuXG4gICAqIEBwYXJhbSB7Kn0gc2YgLSBcbiAgICogQHBhcmFtIHsqfSBtaSAtXG4gICAqIEByZXR1cm4ge1RyYWNrfVxuICAgKi9cblxuXHR9LCB7XG5cdFx0a2V5OiAnc2V0S2V5U2lnbmF0dXJlJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gc2V0S2V5U2lnbmF0dXJlKHNmLCBtaSkge1xuXHRcdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7IGRhdGE6IFtDb25zdGFudHMuTUVUQV9LRVlfU0lHTkFUVVJFX0lEXSB9KTtcblx0XHRcdGV2ZW50LmRhdGEucHVzaCgweDAyKTsgLy8gU2l6ZVxuXG5cdFx0XHR2YXIgbW9kZSA9IG1pIHx8IDA7XG5cdFx0XHRzZiA9IHNmIHx8IDA7XG5cblx0XHRcdC8vXHRGdW5jdGlvbiBjYWxsZWQgd2l0aCBzdHJpbmcgbm90YXRpb25cblx0XHRcdGlmICh0eXBlb2YgbWkgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdHZhciBmaWZ0aHMgPSBbWydDYicsICdHYicsICdEYicsICdBYicsICdFYicsICdCYicsICdGJywgJ0MnLCAnRycsICdEJywgJ0EnLCAnRScsICdCJywgJ0YjJywgJ0MjJ10sIFsnYWInLCAnZWInLCAnYmInLCAnZicsICdjJywgJ2cnLCAnZCcsICdhJywgJ2UnLCAnYicsICdmIycsICdjIycsICdnIycsICdkIycsICdhIyddXTtcblx0XHRcdFx0dmFyIF9zZmxlbiA9IHNmLmxlbmd0aDtcblx0XHRcdFx0dmFyIG5vdGUgPSBzZiB8fCAnQyc7XG5cblx0XHRcdFx0aWYgKHNmWzBdID09PSBzZlswXS50b0xvd2VyQ2FzZSgpKSBtb2RlID0gMTtcblxuXHRcdFx0XHRpZiAoX3NmbGVuID4gMSkge1xuXHRcdFx0XHRcdHN3aXRjaCAoc2YuY2hhckF0KF9zZmxlbiAtIDEpKSB7XG5cdFx0XHRcdFx0XHRjYXNlICdtJzpcblx0XHRcdFx0XHRcdFx0bW9kZSA9IDE7XG5cdFx0XHRcdFx0XHRcdG5vdGUgPSBzZi5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSAnLSc6XG5cdFx0XHRcdFx0XHRcdG1vZGUgPSAxO1xuXHRcdFx0XHRcdFx0XHRub3RlID0gc2YuY2hhckF0KDApLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0XHRcdG5vdGUgPSBub3RlLmNvbmNhdChzZi5zdWJzdHJpbmcoMSwgX3NmbGVuIC0gMSkpO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgJ00nOlxuXHRcdFx0XHRcdFx0XHRtb2RlID0gMDtcblx0XHRcdFx0XHRcdFx0bm90ZSA9IHNmLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0XHRub3RlID0gbm90ZS5jb25jYXQoc2Yuc3Vic3RyaW5nKDEsIF9zZmxlbiAtIDEpKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlICcrJzpcblx0XHRcdFx0XHRcdFx0bW9kZSA9IDA7XG5cdFx0XHRcdFx0XHRcdG5vdGUgPSBzZi5jaGFyQXQoMCkudG9VcHBlckNhc2UoKTtcblx0XHRcdFx0XHRcdFx0bm90ZSA9IG5vdGUuY29uY2F0KHNmLnN1YnN0cmluZygxLCBfc2ZsZW4gLSAxKSk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHZhciBmaWZ0aGluZGV4ID0gZmlmdGhzW21vZGVdLmluZGV4T2Yobm90ZSk7XG5cdFx0XHRcdHNmID0gZmlmdGhpbmRleCA9PT0gLTEgPyAwIDogZmlmdGhpbmRleCAtIDc7XG5cdFx0XHR9XG5cblx0XHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb0J5dGVzKHNmLCAxKSk7IC8vIE51bWJlciBvZiBzaGFycCBvciBmbGF0cyAoIDwgMCBmbGF0OyA+IDAgc2hhcnApXG5cdFx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9CeXRlcyhtb2RlLCAxKSk7IC8vIE1vZGU6IDAgbWFqb3IsIDEgbWlub3Jcblx0XHRcdHJldHVybiB0aGlzLmFkZEV2ZW50KGV2ZW50KTtcblx0XHR9XG5cblx0XHQvKipcbiAgICogQWRkcyB0ZXh0IHRvIE1JREkgZmlsZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUZXh0IHRvIGFkZC5cbiAgICogQHJldHVybiB7VHJhY2t9XG4gICAqL1xuXG5cdH0sIHtcblx0XHRrZXk6ICdhZGRUZXh0Jyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gYWRkVGV4dCh0ZXh0KSB7XG5cdFx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHsgZGF0YTogW0NvbnN0YW50cy5NRVRBX1RFWFRfSURdIH0pO1xuXHRcdFx0dmFyIHN0cmluZ0J5dGVzID0gVXRpbHMuc3RyaW5nVG9CeXRlcyh0ZXh0KTtcblx0XHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKHN0cmluZ0J5dGVzLmxlbmd0aCkpOyAvLyBTaXplXG5cdFx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdFx0fVxuXG5cdFx0LyoqXG4gICAqIEFkZHMgY29weXJpZ2h0IHRvIE1JREkgZmlsZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUZXh0IG9mIGNvcHlyaWdodCBsaW5lLlxuICAgKiBAcmV0dXJuIHtUcmFja31cbiAgICovXG5cblx0fSwge1xuXHRcdGtleTogJ2FkZENvcHlyaWdodCcsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIGFkZENvcHlyaWdodCh0ZXh0KSB7XG5cdFx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHsgZGF0YTogW0NvbnN0YW50cy5NRVRBX0NPUFlSSUdIVF9JRF0gfSk7XG5cdFx0XHR2YXIgc3RyaW5nQnl0ZXMgPSBVdGlscy5zdHJpbmdUb0J5dGVzKHRleHQpO1xuXHRcdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIFRleHRcblx0XHRcdHJldHVybiB0aGlzLmFkZEV2ZW50KGV2ZW50KTtcblx0XHR9XG5cblx0XHQvKipcbiAgICogQWRkcyBTZXF1ZW5jZS9UcmFjayBOYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRleHQgb2YgdHJhY2sgbmFtZS5cbiAgICogQHJldHVybiB7VHJhY2t9XG4gICAqL1xuXG5cdH0sIHtcblx0XHRrZXk6ICdhZGRUcmFja05hbWUnLFxuXHRcdHZhbHVlOiBmdW5jdGlvbiBhZGRUcmFja05hbWUodGV4dCkge1xuXHRcdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7IGRhdGE6IFtDb25zdGFudHMuTUVUQV9UUkFDS19OQU1FX0lEXSB9KTtcblx0XHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cdFx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoVXRpbHMubnVtYmVyVG9WYXJpYWJsZUxlbmd0aChzdHJpbmdCeXRlcy5sZW5ndGgpKTsgLy8gU2l6ZVxuXHRcdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KHN0cmluZ0J5dGVzKTsgLy8gVGV4dFxuXHRcdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHRcdH1cblxuXHRcdC8qKlxuICAgKiBTZXRzIGluc3RydW1lbnQgbmFtZSBvZiB0cmFjay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBOYW1lIG9mIGluc3RydW1lbnQuXG4gICAqIEByZXR1cm4ge1RyYWNrfVxuICAgKi9cblxuXHR9LCB7XG5cdFx0a2V5OiAnYWRkSW5zdHJ1bWVudE5hbWUnLFxuXHRcdHZhbHVlOiBmdW5jdGlvbiBhZGRJbnN0cnVtZW50TmFtZSh0ZXh0KSB7XG5cdFx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHsgZGF0YTogW0NvbnN0YW50cy5NRVRBX0lOU1RSVU1FTlRfTkFNRV9JRF0gfSk7XG5cdFx0XHR2YXIgc3RyaW5nQnl0ZXMgPSBVdGlscy5zdHJpbmdUb0J5dGVzKHRleHQpO1xuXHRcdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIFRleHRcblx0XHRcdHJldHVybiB0aGlzLmFkZEV2ZW50KGV2ZW50KTtcblx0XHR9XG5cblx0XHQvKipcbiAgICogQWRkcyBtYXJrZXIgdG8gTUlESSBmaWxlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIE1hcmtlciB0ZXh0LlxuICAgKiBAcmV0dXJuIHtUcmFja31cbiAgICovXG5cblx0fSwge1xuXHRcdGtleTogJ2FkZE1hcmtlcicsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIGFkZE1hcmtlcih0ZXh0KSB7XG5cdFx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHsgZGF0YTogW0NvbnN0YW50cy5NRVRBX01BUktFUl9JRF0gfSk7XG5cdFx0XHR2YXIgc3RyaW5nQnl0ZXMgPSBVdGlscy5zdHJpbmdUb0J5dGVzKHRleHQpO1xuXHRcdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIFRleHRcblx0XHRcdHJldHVybiB0aGlzLmFkZEV2ZW50KGV2ZW50KTtcblx0XHR9XG5cblx0XHQvKipcbiAgICogQWRkcyBjdWUgcG9pbnQgdG8gTUlESSBmaWxlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRleHQgb2YgY3VlIHBvaW50LlxuICAgKiBAcmV0dXJuIHtUcmFja31cbiAgICovXG5cblx0fSwge1xuXHRcdGtleTogJ2FkZEN1ZVBvaW50Jyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gYWRkQ3VlUG9pbnQodGV4dCkge1xuXHRcdFx0dmFyIGV2ZW50ID0gbmV3IE1ldGFFdmVudCh7IGRhdGE6IFtDb25zdGFudHMuTUVUQV9DVUVfUE9JTlRdIH0pO1xuXHRcdFx0dmFyIHN0cmluZ0J5dGVzID0gVXRpbHMuc3RyaW5nVG9CeXRlcyh0ZXh0KTtcblx0XHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChVdGlscy5udW1iZXJUb1ZhcmlhYmxlTGVuZ3RoKHN0cmluZ0J5dGVzLmxlbmd0aCkpOyAvLyBTaXplXG5cdFx0XHRldmVudC5kYXRhID0gZXZlbnQuZGF0YS5jb25jYXQoc3RyaW5nQnl0ZXMpOyAvLyBUZXh0XG5cdFx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdFx0fVxuXG5cdFx0LyoqXG4gICAqIEFkZHMgbHlyaWMgdG8gTUlESSBmaWxlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbHlyaWMgLSBMeXJpYyB0ZXh0IHRvIGFkZC5cbiAgICogQHJldHVybiB7VHJhY2t9XG4gICAqL1xuXG5cdH0sIHtcblx0XHRrZXk6ICdhZGRMeXJpYycsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIGFkZEx5cmljKGx5cmljKSB7XG5cdFx0XHR2YXIgZXZlbnQgPSBuZXcgTWV0YUV2ZW50KHsgZGF0YTogW0NvbnN0YW50cy5NRVRBX0xZUklDX0lEXSB9KTtcblx0XHRcdHZhciBzdHJpbmdCeXRlcyA9IFV0aWxzLnN0cmluZ1RvQnl0ZXMobHlyaWMpO1xuXHRcdFx0ZXZlbnQuZGF0YSA9IGV2ZW50LmRhdGEuY29uY2F0KFV0aWxzLm51bWJlclRvVmFyaWFibGVMZW5ndGgoc3RyaW5nQnl0ZXMubGVuZ3RoKSk7IC8vIFNpemVcblx0XHRcdGV2ZW50LmRhdGEgPSBldmVudC5kYXRhLmNvbmNhdChzdHJpbmdCeXRlcyk7IC8vIEx5cmljXG5cdFx0XHRyZXR1cm4gdGhpcy5hZGRFdmVudChldmVudCk7XG5cdFx0fVxuXG5cdFx0LyoqXG4gICAqIENoYW5uZWwgbW9kZSBtZXNzYWdlc1xuICAgKiBAcmV0dXJuIHtUcmFja31cbiAgICovXG5cblx0fSwge1xuXHRcdGtleTogJ3BvbHlNb2RlT24nLFxuXHRcdHZhbHVlOiBmdW5jdGlvbiBwb2x5TW9kZU9uKCkge1xuXHRcdFx0dmFyIGV2ZW50ID0gbmV3IE5vdGVPbkV2ZW50KHsgZGF0YTogWzB4MDAsIDB4QjAsIDB4N0UsIDB4MDBdIH0pO1xuXHRcdFx0cmV0dXJuIHRoaXMuYWRkRXZlbnQoZXZlbnQpO1xuXHRcdH1cblx0fV0pO1xuXG5cdHJldHVybiBUcmFjaztcbn0oKTtcblxuZXhwb3J0cy5UcmFjayA9IFRyYWNrO1xuXG4vKipcbiAqIFN0YXRpYyB1dGlsaXR5IGZ1bmN0aW9ucyB1c2VkIHRocm91Z2hvdXQgdGhlIGxpYnJhcnkuXG4gKi9cbnZhciBVdGlscyA9IGZ1bmN0aW9uICgpIHtcblx0ZnVuY3Rpb24gVXRpbHMoKSB7XG5cdFx0X2NsYXNzQ2FsbENoZWNrKHRoaXMsIFV0aWxzKTtcblx0fVxuXG5cdF9jcmVhdGVDbGFzcyhVdGlscywgbnVsbCwgW3tcblx0XHRrZXk6ICd2ZXJzaW9uJyxcblxuXG5cdFx0LyoqXG4gICAqIEdldHMgTWlkaVdyaXRlckpTIHZlcnNpb24gbnVtYmVyLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuXHRcdHZhbHVlOiBmdW5jdGlvbiB2ZXJzaW9uKCkge1xuXHRcdFx0cmV0dXJuIENvbnN0YW50cy5WRVJTSU9OO1xuXHRcdH1cblxuXHRcdC8qKlxuICAgKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGFuIGFycmF5IG9mIGJ5dGVzXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmdcbiAgICogQHJldHVybiB7YXJyYXl9XG4gICAqL1xuXG5cdH0sIHtcblx0XHRrZXk6ICdzdHJpbmdUb0J5dGVzJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gc3RyaW5nVG9CeXRlcyhzdHJpbmcpIHtcblx0XHRcdHJldHVybiBzdHJpbmcuc3BsaXQoJycpLm1hcChmdW5jdGlvbiAoY2hhcikge1xuXHRcdFx0XHRyZXR1cm4gY2hhci5jaGFyQ29kZUF0KCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHQvKipcbiAgICogQ2hlY2tzIGlmIGFyZ3VtZW50IGlzIGEgdmFsaWQgbnVtYmVyLlxuICAgKiBAcGFyYW0geyp9IG4gLSBWYWx1ZSB0byBjaGVja1xuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cblxuXHR9LCB7XG5cdFx0a2V5OiAnaXNOdW1lcmljJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gaXNOdW1lcmljKG4pIHtcblx0XHRcdHJldHVybiAhaXNOYU4ocGFyc2VGbG9hdChuKSkgJiYgaXNGaW5pdGUobik7XG5cdFx0fVxuXG5cdFx0LyoqXG4gICAgICAqIFJldHVybnMgdGhlIGNvcnJlY3QgTUlESSBudW1iZXIgZm9yIHRoZSBzcGVjaWZpZWQgcGl0Y2guXG4gICAgICAqIFVzZXMgVG9uYWwgTWlkaSAtIGh0dHBzOi8vZ2l0aHViLmNvbS9kYW5pZ2IvdG9uYWwvdHJlZS9tYXN0ZXIvcGFja2FnZXMvbWlkaVxuICAgICAgKiBAcGFyYW0geyhzdHJpbmd8bnVtYmVyKX0gcGl0Y2ggLSAnQyM0JyBvciBtaWRpIG5vdGUgY29kZVxuICAgICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAgICAqL1xuXG5cdH0sIHtcblx0XHRrZXk6ICdnZXRQaXRjaCcsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIGdldFBpdGNoKHBpdGNoKSB7XG5cdFx0XHRyZXR1cm4gKDAsIF90b25hbE1pZGkudG9NaWRpKShwaXRjaCk7XG5cdFx0fVxuXG5cdFx0LyoqXG4gICAqIFRyYW5zbGF0ZXMgbnVtYmVyIG9mIHRpY2tzIHRvIE1JREkgdGltZXN0YW1wIGZvcm1hdCwgcmV0dXJuaW5nIGFuIGFycmF5IG9mXG4gICAqIGhleCBzdHJpbmdzIHdpdGggdGhlIHRpbWUgdmFsdWVzLiBNaWRpIGhhcyBhIHZlcnkgcGFydGljdWxhciB0aW1lIHRvIGV4cHJlc3MgdGltZSxcbiAgICogdGFrZSBhIGdvb2QgbG9vayBhdCB0aGUgc3BlYyBiZWZvcmUgZXZlciB0b3VjaGluZyB0aGlzIGZ1bmN0aW9uLlxuICAgKiBUaGFua3MgdG8gaHR0cHM6Ly9naXRodWIuY29tL3NlcmdpL2pzbWlkaVxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gdGlja3MgLSBOdW1iZXIgb2YgdGlja3MgdG8gYmUgdHJhbnNsYXRlZFxuICAgKiBAcmV0dXJuIHthcnJheX0gLSBCeXRlcyB0aGF0IGZvcm0gdGhlIE1JREkgdGltZSB2YWx1ZVxuICAgKi9cblxuXHR9LCB7XG5cdFx0a2V5OiAnbnVtYmVyVG9WYXJpYWJsZUxlbmd0aCcsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIG51bWJlclRvVmFyaWFibGVMZW5ndGgodGlja3MpIHtcblx0XHRcdHZhciBidWZmZXIgPSB0aWNrcyAmIDB4N0Y7XG5cblx0XHRcdHdoaWxlICh0aWNrcyA9IHRpY2tzID4+IDcpIHtcblx0XHRcdFx0YnVmZmVyIDw8PSA4O1xuXHRcdFx0XHRidWZmZXIgfD0gdGlja3MgJiAweDdGIHwgMHg4MDtcblx0XHRcdH1cblxuXHRcdFx0dmFyIGJMaXN0ID0gW107XG5cdFx0XHR3aGlsZSAodHJ1ZSkge1xuXHRcdFx0XHRiTGlzdC5wdXNoKGJ1ZmZlciAmIDB4ZmYpO1xuXG5cdFx0XHRcdGlmIChidWZmZXIgJiAweDgwKSBidWZmZXIgPj49IDg7ZWxzZSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGJMaXN0O1xuXHRcdH1cblxuXHRcdC8qKlxuICAgKiBDb3VudHMgbnVtYmVyIG9mIGJ5dGVzIGluIHN0cmluZ1xuICAgKiBAcGFyYW0ge3N0cmluZ30gc1xuICAgKiBAcmV0dXJuIHthcnJheX1cbiAgICovXG5cblx0fSwge1xuXHRcdGtleTogJ3N0cmluZ0J5dGVDb3VudCcsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIHN0cmluZ0J5dGVDb3VudChzKSB7XG5cdFx0XHRyZXR1cm4gZW5jb2RlVVJJKHMpLnNwbGl0KC8lLi58Li8pLmxlbmd0aCAtIDE7XG5cdFx0fVxuXG5cdFx0LyoqXG4gICAqIEdldCBhbiBpbnQgZnJvbSBhbiBhcnJheSBvZiBieXRlcy5cbiAgICogQHBhcmFtIHthcnJheX0gYnl0ZXNcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cblxuXHR9LCB7XG5cdFx0a2V5OiAnbnVtYmVyRnJvbUJ5dGVzJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gbnVtYmVyRnJvbUJ5dGVzKGJ5dGVzKSB7XG5cdFx0XHR2YXIgaGV4ID0gJyc7XG5cdFx0XHR2YXIgc3RyaW5nUmVzdWx0O1xuXG5cdFx0XHRieXRlcy5mb3JFYWNoKGZ1bmN0aW9uIChieXRlKSB7XG5cdFx0XHRcdHN0cmluZ1Jlc3VsdCA9IGJ5dGUudG9TdHJpbmcoMTYpO1xuXG5cdFx0XHRcdC8vIGVuc3VyZSBzdHJpbmcgaXMgMiBjaGFyc1xuXHRcdFx0XHRpZiAoc3RyaW5nUmVzdWx0Lmxlbmd0aCA9PSAxKSBzdHJpbmdSZXN1bHQgPSBcIjBcIiArIHN0cmluZ1Jlc3VsdDtcblxuXHRcdFx0XHRoZXggKz0gc3RyaW5nUmVzdWx0O1xuXHRcdFx0fSk7XG5cblx0XHRcdHJldHVybiBwYXJzZUludChoZXgsIDE2KTtcblx0XHR9XG5cblx0XHQvKipcbiAgICogVGFrZXMgYSBudW1iZXIgYW5kIHNwbGl0cyBpdCB1cCBpbnRvIGFuIGFycmF5IG9mIGJ5dGVzLiAgQ2FuIGJlIHBhZGRlZCBieSBwYXNzaW5nIGEgbnVtYmVyIHRvIGJ5dGVzTmVlZGVkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXJcbiAgICogQHBhcmFtIHtudW1iZXJ9IGJ5dGVzTmVlZGVkXG4gICAqIEByZXR1cm4ge2FycmF5fSAtIEFycmF5IG9mIGJ5dGVzXG4gICAqL1xuXG5cdH0sIHtcblx0XHRrZXk6ICdudW1iZXJUb0J5dGVzJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gbnVtYmVyVG9CeXRlcyhudW1iZXIsIGJ5dGVzTmVlZGVkKSB7XG5cdFx0XHRieXRlc05lZWRlZCA9IGJ5dGVzTmVlZGVkIHx8IDE7XG5cblx0XHRcdHZhciBoZXhTdHJpbmcgPSBudW1iZXIudG9TdHJpbmcoMTYpO1xuXG5cdFx0XHRpZiAoaGV4U3RyaW5nLmxlbmd0aCAmIDEpIHtcblx0XHRcdFx0Ly8gTWFrZSBzdXJlIGhleCBzdHJpbmcgaXMgZXZlbiBudW1iZXIgb2YgY2hhcnNcblx0XHRcdFx0aGV4U3RyaW5nID0gJzAnICsgaGV4U3RyaW5nO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTcGxpdCBoZXggc3RyaW5nIGludG8gYW4gYXJyYXkgb2YgdHdvIGNoYXIgZWxlbWVudHNcblx0XHRcdHZhciBoZXhBcnJheSA9IGhleFN0cmluZy5tYXRjaCgvLnsyfS9nKTtcblxuXHRcdFx0Ly8gTm93IHBhcnNlIHRoZW0gb3V0IGFzIGludGVnZXJzXG5cdFx0XHRoZXhBcnJheSA9IGhleEFycmF5Lm1hcChmdW5jdGlvbiAoaXRlbSkge1xuXHRcdFx0XHRyZXR1cm4gcGFyc2VJbnQoaXRlbSwgMTYpO1xuXHRcdFx0fSk7XG5cblx0XHRcdC8vIFByZXBlbmQgZW1wdHkgYnl0ZXMgaWYgd2UgZG9uJ3QgaGF2ZSBlbm91Z2hcblx0XHRcdGlmIChoZXhBcnJheS5sZW5ndGggPCBieXRlc05lZWRlZCkge1xuXHRcdFx0XHR3aGlsZSAoYnl0ZXNOZWVkZWQgLSBoZXhBcnJheS5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0aGV4QXJyYXkudW5zaGlmdCgwKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gaGV4QXJyYXk7XG5cdFx0fVxuXG5cdFx0LyoqXHRcbiAgICogQ29udmVydHMgdmFsdWUgdG8gYXJyYXkgaWYgbmVlZGVkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHJldHVybiB7YXJyYXl9XG4gICAqL1xuXG5cdH0sIHtcblx0XHRrZXk6ICd0b0FycmF5Jyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gdG9BcnJheSh2YWx1ZSkge1xuXHRcdFx0aWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gdmFsdWU7XG5cdFx0XHRyZXR1cm4gW3ZhbHVlXTtcblx0XHR9XG5cdH1dKTtcblxuXHRyZXR1cm4gVXRpbHM7XG59KCk7XG5cbmV4cG9ydHMuVXRpbHMgPSBVdGlscztcblxudmFyIFZleEZsb3cgPSBmdW5jdGlvbiAoKSB7XG5cdGZ1bmN0aW9uIFZleEZsb3coKSB7XG5cdFx0X2NsYXNzQ2FsbENoZWNrKHRoaXMsIFZleEZsb3cpO1xuXHR9XG5cdC8vIGNvZGUuLi5cblxuXG5cdC8qKlxuICAqIFN1cHBvcnQgZm9yIGNvbnZlcnRpbmcgVmV4RmxvdyB2b2ljZSBpbnRvIE1pZGlXcml0ZXJKUyB0cmFja1xuICAqIEByZXR1cm4gTWlkaVdyaXRpZXIuVHJhY2sgb2JqZWN0XG4gICovXG5cblxuXHRfY3JlYXRlQ2xhc3MoVmV4RmxvdywgW3tcblx0XHRrZXk6ICd0cmFja0Zyb21Wb2ljZScsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIHRyYWNrRnJvbVZvaWNlKHZvaWNlKSB7XG5cdFx0XHR2YXIgdHJhY2sgPSBuZXcgVHJhY2soKTtcblx0XHRcdHZhciB3YWl0O1xuXHRcdFx0dmFyIHBpdGNoZXMgPSBbXTtcblxuXHRcdFx0dm9pY2UudGlja2FibGVzLmZvckVhY2goZnVuY3Rpb24gKHRpY2thYmxlKSB7XG5cdFx0XHRcdHBpdGNoZXMgPSBbXTtcblxuXHRcdFx0XHRpZiAodGlja2FibGUubm90ZVR5cGUgPT09ICduJykge1xuXHRcdFx0XHRcdHRpY2thYmxlLmtleXMuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRcdFx0XHQvLyBidWlsZCBhcnJheSBvZiBwaXRjaGVzXG5cdFx0XHRcdFx0XHRwaXRjaGVzLnB1c2godGhpcy5jb252ZXJ0UGl0Y2goa2V5KSk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAodGlja2FibGUubm90ZVR5cGUgPT09ICdyJykge1xuXHRcdFx0XHRcdC8vIG1vdmUgb24gdG8gdGhlIG5leHQgdGlja2FibGUgYW5kIHVzZSB0aGlzIHJlc3QgYXMgYSBgd2FpdGAgcHJvcGVydHkgZm9yIHRoZSBuZXh0IGV2ZW50XG5cdFx0XHRcdFx0d2FpdCA9IHRoaXMuY29udmVydER1cmF0aW9uKHRpY2thYmxlKTtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0cmFjay5hZGRFdmVudChuZXcgTm90ZUV2ZW50KHsgcGl0Y2g6IHBpdGNoZXMsIGR1cmF0aW9uOiB0aGlzLmNvbnZlcnREdXJhdGlvbih0aWNrYWJsZSksIHdhaXQ6IHdhaXQgfSkpO1xuXG5cdFx0XHRcdC8vIHJlc2V0IHdhaXRcblx0XHRcdFx0d2FpdCA9IDA7XG5cdFx0XHR9KTtcblxuXHRcdFx0cmV0dXJuIHRyYWNrO1xuXHRcdH1cblxuXHRcdC8qKlxuICAgKiBDb252ZXJ0cyBWZXhGbG93IHBpdGNoIHN5bnRheCB0byBNaWRpV3JpdGVySlMgc3ludGF4XG4gICAqIEBwYXJhbSBwaXRjaCBzdHJpbmdcbiAgICovXG5cblx0fSwge1xuXHRcdGtleTogJ2NvbnZlcnRQaXRjaCcsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIGNvbnZlcnRQaXRjaChwaXRjaCkge1xuXHRcdFx0cmV0dXJuIHBpdGNoLnJlcGxhY2UoJy8nLCAnJyk7XG5cdFx0fVxuXG5cdFx0LyoqXG4gICAqIENvbnZlcnRzIFZleEZsb3cgZHVyYXRpb24gc3ludGF4IHRvIE1pZGlXcml0ZXJKUyBzeW50YXhcbiAgICogQHBhcmFtIG5vdGUgc3RydWN0IGZyb20gVmV4Rmxvd1xuICAgKi9cblxuXHR9LCB7XG5cdFx0a2V5OiAnY29udmVydER1cmF0aW9uJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gY29udmVydER1cmF0aW9uKG5vdGUpIHtcblx0XHRcdHN3aXRjaCAobm90ZS5kdXJhdGlvbikge1xuXHRcdFx0XHRjYXNlICd3Jzpcblx0XHRcdFx0XHRyZXR1cm4gJzEnO1xuXHRcdFx0XHRjYXNlICdoJzpcblx0XHRcdFx0XHRyZXR1cm4gbm90ZS5pc0RvdHRlZCgpID8gJ2QyJyA6ICcyJztcblx0XHRcdFx0Y2FzZSAncSc6XG5cdFx0XHRcdFx0cmV0dXJuIG5vdGUuaXNEb3R0ZWQoKSA/ICdkNCcgOiAnNCc7XG5cdFx0XHRcdGNhc2UgJzgnOlxuXHRcdFx0XHRcdHJldHVybiBub3RlLmlzRG90dGVkKCkgPyAnZDgnIDogJzgnO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbm90ZS5kdXJhdGlvbjtcblx0XHR9XG5cdH1dKTtcblxuXHRyZXR1cm4gVmV4Rmxvdztcbn0oKTtcblxuZXhwb3J0cy5WZXhGbG93ID0gVmV4Rmxvdztcbi8qKlxuICogT2JqZWN0IHRoYXQgcHV0cyB0b2dldGhlciB0cmFja3MgYW5kIHByb3ZpZGVzIG1ldGhvZHMgZm9yIGZpbGUgb3V0cHV0LlxuICogQHBhcmFtIHthcnJheX0gdHJhY2tzIC0gQW4gYXJyYXkgb2Yge1RyYWNrfSBvYmplY3RzLlxuICogQHJldHVybiB7V3JpdGVyfVxuICovXG5cbnZhciBXcml0ZXIgPSBmdW5jdGlvbiAoKSB7XG5cdGZ1bmN0aW9uIFdyaXRlcih0cmFja3MpIHtcblx0XHRfY2xhc3NDYWxsQ2hlY2sodGhpcywgV3JpdGVyKTtcblxuXHRcdHRoaXMuZGF0YSA9IFtdO1xuXG5cdFx0dmFyIHRyYWNrVHlwZSA9IHRyYWNrcy5sZW5ndGggPiAxID8gQ29uc3RhbnRzLkhFQURFUl9DSFVOS19GT1JNQVQxIDogQ29uc3RhbnRzLkhFQURFUl9DSFVOS19GT1JNQVQwO1xuXHRcdHZhciBudW1iZXJPZlRyYWNrcyA9IFV0aWxzLm51bWJlclRvQnl0ZXModHJhY2tzLmxlbmd0aCwgMik7IC8vIHR3byBieXRlcyBsb25nXG5cblx0XHQvLyBIZWFkZXIgY2h1bmtcblx0XHR0aGlzLmRhdGEucHVzaChuZXcgQ2h1bmsoe1xuXHRcdFx0dHlwZTogQ29uc3RhbnRzLkhFQURFUl9DSFVOS19UWVBFLFxuXHRcdFx0ZGF0YTogdHJhY2tUeXBlLmNvbmNhdChudW1iZXJPZlRyYWNrcywgQ29uc3RhbnRzLkhFQURFUl9DSFVOS19ESVZJU0lPTikgfSkpO1xuXG5cdFx0Ly8gVHJhY2sgY2h1bmtzXG5cdFx0dHJhY2tzLmZvckVhY2goZnVuY3Rpb24gKHRyYWNrLCBpKSB7XG5cdFx0XHR0cmFjay5hZGRFdmVudChuZXcgTWV0YUV2ZW50KHsgZGF0YTogQ29uc3RhbnRzLk1FVEFfRU5EX09GX1RSQUNLX0lEIH0pKTtcblx0XHRcdHRoaXMuZGF0YS5wdXNoKHRyYWNrKTtcblx0XHR9LCB0aGlzKTtcblx0fVxuXG5cdC8qKlxuICAqIEJ1aWxkcyB0aGUgZmlsZSBpbnRvIGEgVWludDhBcnJheVxuICAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9XG4gICovXG5cblxuXHRfY3JlYXRlQ2xhc3MoV3JpdGVyLCBbe1xuXHRcdGtleTogJ2J1aWxkRmlsZScsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIGJ1aWxkRmlsZSgpIHtcblx0XHRcdHZhciBidWlsZCA9IFtdO1xuXG5cdFx0XHQvLyBEYXRhIGNvbnNpc3RzIG9mIGNodW5rcyB3aGljaCBjb25zaXN0cyBvZiBkYXRhXG5cdFx0XHR0aGlzLmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuXHRcdFx0XHRyZXR1cm4gYnVpbGQgPSBidWlsZC5jb25jYXQoZC50eXBlLCBkLnNpemUsIGQuZGF0YSk7XG5cdFx0XHR9KTtcblxuXHRcdFx0cmV0dXJuIG5ldyBVaW50OEFycmF5KGJ1aWxkKTtcblx0XHR9XG5cblx0XHQvKipcbiAgICogQ29udmVydCBmaWxlIGJ1ZmZlciB0byBhIGJhc2U2NCBzdHJpbmcuICBEaWZmZXJlbnQgbWV0aG9kcyBkZXBlbmRpbmcgb24gaWYgYnJvd3NlciBvciBub2RlLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuXG5cdH0sIHtcblx0XHRrZXk6ICdiYXNlNjQnLFxuXHRcdHZhbHVlOiBmdW5jdGlvbiBiYXNlNjQoKSB7XG5cdFx0XHRpZiAodHlwZW9mIGJ0b2EgPT09ICdmdW5jdGlvbicpIHJldHVybiBidG9hKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgdGhpcy5idWlsZEZpbGUoKSkpO1xuXHRcdFx0cmV0dXJuIG5ldyBCdWZmZXIodGhpcy5idWlsZEZpbGUoKSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuXHRcdH1cblxuXHRcdC8qKlxuICAgKiBHZXQgdGhlIGRhdGEgVVJJLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuXG5cdH0sIHtcblx0XHRrZXk6ICdkYXRhVXJpJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gZGF0YVVyaSgpIHtcblx0XHRcdHJldHVybiAnZGF0YTphdWRpby9taWRpO2Jhc2U2NCwnICsgdGhpcy5iYXNlNjQoKTtcblx0XHR9XG5cblx0XHQvKipcbiAgICogT3V0cHV0IHRvIHN0ZG91dFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuXG5cdH0sIHtcblx0XHRrZXk6ICdzdGRvdXQnLFxuXHRcdHZhbHVlOiBmdW5jdGlvbiBzdGRvdXQoKSB7XG5cdFx0XHRyZXR1cm4gcHJvY2Vzcy5zdGRvdXQud3JpdGUobmV3IEJ1ZmZlcih0aGlzLmJ1aWxkRmlsZSgpKSk7XG5cdFx0fVxuXG5cdFx0LyoqXG4gICAqIFNhdmUgdG8gTUlESSBmaWxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZVxuICAgKi9cblxuXHR9LCB7XG5cdFx0a2V5OiAnc2F2ZU1JREknLFxuXHRcdHZhbHVlOiBmdW5jdGlvbiBzYXZlTUlESShmaWxlbmFtZSkge1xuXHRcdFx0dmFyIGJ1ZmZlciA9IG5ldyBCdWZmZXIodGhpcy5idWlsZEZpbGUoKSk7XG5cdFx0XHRmcy53cml0ZUZpbGUoZmlsZW5hbWUgKyAnLm1pZCcsIGJ1ZmZlciwgZnVuY3Rpb24gKGVycikge1xuXHRcdFx0XHRpZiAoZXJyKSByZXR1cm4gY29uc29sZS5sb2coZXJyKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fV0pO1xuXG5cdHJldHVybiBXcml0ZXI7XG59KCk7XG5cbmV4cG9ydHMuV3JpdGVyID0gV3JpdGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW1sdVpHVjRMbXB6SWwwc0ltNWhiV1Z6SWpwYklrTm9kVzVySWl3aVptbGxiR1J6SWl3aWRIbHdaU0lzSW1SaGRHRWlMQ0p6YVhwbElpd2liR1Z1WjNSb0lpd2lRMjl1YzNSaGJuUnpJaXdpVmtWU1UwbFBUaUlzSWtoRlFVUkZVbDlEU0ZWT1MxOVVXVkJGSWl3aVNFVkJSRVZTWDBOSVZVNUxYMHhGVGtkVVNDSXNJa2hGUVVSRlVsOURTRlZPUzE5R1QxSk5RVlF3SWl3aVNFVkJSRVZTWDBOSVZVNUxYMFpQVWsxQlZERWlMQ0pJUlVGRVJWSmZRMGhWVGt0ZlJFbFdTVk5KVDA0aUxDSlVVa0ZEUzE5RFNGVk9TMTlVV1ZCRklpd2lUVVZVUVY5RlZrVk9WRjlKUkNJc0lrMUZWRUZmVkVWWVZGOUpSQ0lzSWsxRlZFRmZRMDlRV1ZKSlIwaFVYMGxFSWl3aVRVVlVRVjlVVWtGRFMxOU9RVTFGWDBsRUlpd2lUVVZVUVY5SlRsTlVVbFZOUlU1VVgwNUJUVVZmU1VRaUxDSk5SVlJCWDB4WlVrbERYMGxFSWl3aVRVVlVRVjlOUVZKTFJWSmZTVVFpTENKTlJWUkJYME5WUlY5UVQwbE9WQ0lzSWsxRlZFRmZWRVZOVUU5ZlNVUWlMQ0pOUlZSQlgxTk5WRkJGWDA5R1JsTkZWQ0lzSWsxRlZFRmZWRWxOUlY5VFNVZE9RVlJWVWtWZlNVUWlMQ0pOUlZSQlgwdEZXVjlUU1VkT1FWUlZVa1ZmU1VRaUxDSk5SVlJCWDBWT1JGOVBSbDlVVWtGRFMxOUpSQ0lzSWtOUFRsUlNUMHhNUlZKZlEwaEJUa2RGWDFOVVFWUlZVeUlzSWxCU1QwZFNRVTFmUTBoQlRrZEZYMU5VUVZSVlV5SXNJa052Ym5SeWIyeHNaWEpEYUdGdVoyVkZkbVZ1ZENJc0lsVjBhV3h6SWl3aWJuVnRZbVZ5Vkc5V1lYSnBZV0pzWlV4bGJtZDBhQ0lzSW1OdmJtTmhkQ0lzSW1OdmJuUnliMnhzWlhKT2RXMWlaWElpTENKamIyNTBjbTlzYkdWeVZtRnNkV1VpTENKTlpYUmhSWFpsYm5RaUxDSk9iM1JsUlhabGJuUWlMQ0p3YVhSamFDSXNJblJ2UVhKeVlYa2lMQ0ozWVdsMElpd2laSFZ5WVhScGIyNGlMQ0p6WlhGMVpXNTBhV0ZzSWl3aWRtVnNiMk5wZEhraUxDSmphR0Z1Ym1Wc0lpd2ljbVZ3WldGMElpd2lZMjl1ZG1WeWRGWmxiRzlqYVhSNUlpd2laM0poWTJVaUxDSmlkV2xzWkVSaGRHRWlMQ0owYVdOclJIVnlZWFJwYjI0aUxDSm5aWFJVYVdOclJIVnlZWFJwYjI0aUxDSnlaWE4wUkhWeVlYUnBiMjRpTENKbmNtRmpaVVIxY21GMGFXOXVJaXdpWm05eVJXRmphQ0lzSW01dmRHVkZkbVZ1ZENJc0ltNXZkR1ZQYmlJc0ltNXZkR1ZQWm1ZaUxDSkJjbkpoZVNJc0ltbHpRWEp5WVhraUxDSnFJaXdpY0NJc0lta2lMQ0pPYjNSbFQyNUZkbVZ1ZENJc0ltZGxkRTV2ZEdWUGJsTjBZWFIxY3lJc0ltZGxkRkJwZEdOb0lpd2lUbTkwWlU5bVprVjJaVzUwSWl3aVoyVjBUbTkwWlU5bVpsTjBZWFIxY3lJc0luRjFZWEowWlhKVWFXTnJjeUlzSW01MWJXSmxja1p5YjIxQ2VYUmxjeUlzSWsxaGRHZ2lMQ0p5YjNWdVpDSXNJbTFoY0NJc0luWmhiSFZsSWl3aWNtVmtkV05sSWl3aVlTSXNJbUlpTENKMGIxTjBjbWx1WnlJc0luUnZURzkzWlhKRFlYTmxJaXdpWTJoaGNrRjBJaXdpY0dGeWMyVkpiblFpTENKemRXSnpkSEpwYm1jaUxDSm5aWFJFZFhKaGRHbHZiazExYkhScGNHeHBaWElpTENKUWNtOW5jbUZ0UTJoaGJtZGxSWFpsYm5RaUxDSnBibk4wY25WdFpXNTBJaXdpVkhKaFkyc2lMQ0psZG1WdWRITWlMQ0psZG1WdWRDSXNJbTFoY0VaMWJtTjBhVzl1SWl3aVpTSXNJbkJ5YjNCbGNuUnBaWE1pTENKdWRXMWlaWEpVYjBKNWRHVnpJaXdpY0hWemFDSXNJbUp3YlNJc0luUmxiWEJ2SWl3aVlXUmtSWFpsYm5RaUxDSnVkVzFsY21GMGIzSWlMQ0prWlc1dmJXbHVZWFJ2Y2lJc0ltMXBaR2xqYkc5amEzTndaWEowYVdOcklpd2libTkwWlhOd1pYSnRhV1JwWTJ4dlkyc2lMQ0pmWkdWdWIyMXBibUYwYjNJaUxDSnNiMmN5SWl3aWMyWWlMQ0p0YVNJc0ltMXZaR1VpTENKbWFXWjBhSE1pTENKZmMyWnNaVzRpTENKdWIzUmxJaXdpZEc5VmNIQmxja05oYzJVaUxDSm1hV1owYUdsdVpHVjRJaXdpYVc1a1pYaFBaaUlzSW5SbGVIUWlMQ0p6ZEhKcGJtZENlWFJsY3lJc0luTjBjbWx1WjFSdlFubDBaWE1pTENKc2VYSnBZeUlzSW5OMGNtbHVaeUlzSW5Od2JHbDBJaXdpWTJoaGNpSXNJbU5vWVhKRGIyUmxRWFFpTENKdUlpd2lhWE5PWVU0aUxDSndZWEp6WlVac2IyRjBJaXdpYVhOR2FXNXBkR1VpTENKMGFXTnJjeUlzSW1KMVptWmxjaUlzSW1KTWFYTjBJaXdpY3lJc0ltVnVZMjlrWlZWU1NTSXNJbUo1ZEdWeklpd2lhR1Y0SWl3aWMzUnlhVzVuVW1WemRXeDBJaXdpWW5sMFpTSXNJbTUxYldKbGNpSXNJbUo1ZEdWelRtVmxaR1ZrSWl3aWFHVjRVM1J5YVc1bklpd2lhR1Y0UVhKeVlYa2lMQ0p0WVhSamFDSXNJbWwwWlcwaUxDSjFibk5vYVdaMElpd2lWbVY0Um14dmR5SXNJblp2YVdObElpd2lkSEpoWTJzaUxDSndhWFJqYUdWeklpd2lkR2xqYTJGaWJHVnpJaXdpZEdsamEyRmliR1VpTENKdWIzUmxWSGx3WlNJc0ltdGxlWE1pTENKclpYa2lMQ0pqYjI1MlpYSjBVR2wwWTJnaUxDSmpiMjUyWlhKMFJIVnlZWFJwYjI0aUxDSnlaWEJzWVdObElpd2lhWE5FYjNSMFpXUWlMQ0pYY21sMFpYSWlMQ0owY21GamEzTWlMQ0owY21GamExUjVjR1VpTENKdWRXMWlaWEpQWmxSeVlXTnJjeUlzSW1KMWFXeGtJaXdpWkNJc0lsVnBiblE0UVhKeVlYa2lMQ0ppZEc5aElpd2lVM1J5YVc1bklpd2labkp2YlVOb1lYSkRiMlJsSWl3aVlYQndiSGtpTENKaWRXbHNaRVpwYkdVaUxDSkNkV1ptWlhJaUxDSmlZWE5sTmpRaUxDSndjbTlqWlhOeklpd2ljM1JrYjNWMElpd2lkM0pwZEdVaUxDSm1hV3hsYm1GdFpTSXNJbVp6SWl3aWQzSnBkR1ZHYVd4bElpd2laWEp5SWl3aVkyOXVjMjlzWlNJc0lteHZaeUpkTENKdFlYQndhVzVuY3lJNklqczdPenM3T3pzN096czdRVUZ6YTBKQk96czdPMEZCZEd0Q1FUczdPenM3U1VGTFRVRXNTeXhIUVVOTUxHVkJRVmxETEUxQlFWb3NSVUZCYjBJN1FVRkJRVHM3UVVGRGJrSXNUVUZCUzBNc1NVRkJUQ3hIUVVGWlJDeFBRVUZQUXl4SlFVRnVRanRCUVVOQkxFMUJRVXRETEVsQlFVd3NSMEZCV1VZc1QwRkJUMFVzU1VGQmJrSTdRVUZEUVN4TlFVRkxReXhKUVVGTUxFZEJRVmtzUTBGQlF5eERRVUZFTEVWQlFVa3NRMEZCU2l4RlFVRlBMRU5CUVZBc1JVRkJWVWdzVDBGQlQwVXNTVUZCVUN4RFFVRlpSU3hOUVVGMFFpeERRVUZhTzBGQlEwRXNRenM3VVVGSFRVd3NTeXhIUVVGQlFTeExPMEZCUTFJN096czdPMEZCUzBFc1NVRkJTVTBzV1VGQldUdEJRVU5tUXl4VlFVRmpMRTlCUkVNN1FVRkZaa01zYjBKQlFYVkNMRU5CUVVNc1NVRkJSQ3hGUVVGUExFbEJRVkFzUlVGQllTeEpRVUZpTEVWQlFXMUNMRWxCUVc1Q0xFTkJSbElzUlVGRmEwTTdRVUZEYWtSRExITkNRVUYzUWl4RFFVRkRMRWxCUVVRc1JVRkJUeXhKUVVGUUxFVkJRV0VzU1VGQllpeEZRVUZ0UWl4SlFVRnVRaXhEUVVoVUxFVkJSMjFETzBGQlEyeEVReXgxUWtGQk1FSXNRMEZCUXl4SlFVRkVMRVZCUVU4c1NVRkJVQ3hEUVVwWUxFVkJTWGxDTzBGQlEzaERReXgxUWtGQk1FSXNRMEZCUXl4SlFVRkVMRVZCUVU4c1NVRkJVQ3hEUVV4WUxFVkJTM2xDTzBGQlEzaERReXgzUWtGQk1FSXNRMEZCUXl4SlFVRkVMRVZCUVU4c1NVRkJVQ3hEUVU1WUxFVkJUWGxDTzBGQlEzaERReXh0UWtGQmIwSXNRMEZCUXl4SlFVRkVMRVZCUVU4c1NVRkJVQ3hGUVVGaExFbEJRV0lzUlVGQmJVSXNTVUZCYmtJc1EwRlFUQ3hGUVU4clFqdEJRVU01UTBNc1owSkJRV3RDTEVsQlVrZzdRVUZUWmtNc1pVRkJhVUlzU1VGVVJqdEJRVlZtUXl4dlFrRkJjVUlzU1VGV1RqdEJRVmRtUXl4eFFrRkJjMElzU1VGWVVEdEJRVmxtUXl3d1FrRkJNRUlzU1VGYVdEdEJRV0ZtUXl4blFrRkJhMElzU1VGaVNEdEJRV05tUXl4cFFrRkJiVUlzU1VGa1NqdEJRV1ZtUXl4cFFrRkJiVUlzU1VGbVNqdEJRV2RDWmtNc1owSkJRV3RDTEVsQmFFSklPMEZCYVVKbVF5eHZRa0ZCY1VJc1NVRnFRazQ3UVVGclFtWkRMSGxDUVVGNVFpeEpRV3hDVmp0QlFXMUNaa01zZDBKQlFYZENMRWxCYmtKVU8wRkJiMEptUXl4MVFrRkJkVUlzUTBGQlF5eEpRVUZFTEVWQlFVOHNTVUZCVUN4RFFYQkNVanRCUVhGQ1prTXNNa0pCUVRCQ0xFbEJja0pZTEVWQmNVSnBRanRCUVVOb1EwTXNkMEpCUVhkQ0xFbEJkRUpVTEVOQmMwSmxPMEZCZEVKbUxFTkJRV2hDT3p0UlFYbENVWFJDTEZNc1IwRkJRVUVzVXp0QlFVTlNPenM3T3pzN1NVRkxUWFZDTEhGQ0xFZEJRMHdzSzBKQlFWazFRaXhOUVVGYUxFVkJRVzlDTzBGQlFVRTdPMEZCUTI1Q0xFMUJRVXRETEVsQlFVd3NSMEZCV1N4WlFVRmFPMEZCUTBFN1FVRkRRU3hOUVVGTFF5eEpRVUZNTEVkQlFWa3lRaXhOUVVGTlF5eHpRa0ZCVGl4RFFVRTJRaXhKUVVFM1FpeEZRVUZ0UTBNc1RVRkJia01zUTBGQk1FTXhRaXhWUVVGVmNVSXNkMEpCUVhCRUxFVkJRVGhGTVVJc1QwRkJUMmRETEdkQ1FVRnlSaXhGUVVGMVIyaERMRTlCUVU5cFF5eGxRVUU1Unl4RFFVRmFPMEZCUTBFc1F6czdVVUZIVFV3c2NVSXNSMEZCUVVFc2NVSTdRVUZEVWpzN096czdPMGxCUzAxTkxGTXNSMEZEVEN4dFFrRkJXV3hETEUxQlFWb3NSVUZCYjBJN1FVRkJRVHM3UVVGRGJrSXNUVUZCUzBNc1NVRkJUQ3hIUVVGWkxFMUJRVm83UVVGRFFTeE5RVUZMUXl4SlFVRk1MRWRCUVZreVFpeE5RVUZOUXl4elFrRkJUaXhEUVVFMlFpeEpRVUUzUWl4RFFVRmFMRU5CUm0xQ0xFTkJSVFJDTzBGQlF5OURMRTFCUVVzMVFpeEpRVUZNTEVkQlFWa3NTMEZCUzBFc1NVRkJUQ3hEUVVGVk5rSXNUVUZCVml4RFFVRnBRakZDTEZWQlFWVlJMR0ZCUVROQ0xFVkJRVEJEWWl4UFFVRlBSU3hKUVVGcVJDeERRVUZhTzBGQlEwRXNRenM3VVVGSFRXZERMRk1zUjBGQlFVRXNVenRCUVVOU096czdPenM3U1VGTFRVTXNVenRCUVVOTUxHOUNRVUZaYmtNc1RVRkJXaXhGUVVGdlFqdEJRVUZCT3p0QlFVTnVRaXhQUVVGTFF5eEpRVUZNTEVkQlFXTXNUVUZCWkR0QlFVTkJMRTlCUVV0dFF5eExRVUZNTEVkQlFXVlFMRTFCUVUxUkxFOUJRVTRzUTBGQlkzSkRMRTlCUVU5dlF5eExRVUZ5UWl4RFFVRm1PMEZCUTBFc1QwRkJTMFVzU1VGQlRDeEhRVUZqZEVNc1QwRkJUM05ETEVsQlFWQXNTVUZCWlN4RFFVRTNRanRCUVVOQkxFOUJRVXRETEZGQlFVd3NSMEZCYVVKMlF5eFBRVUZQZFVNc1VVRkJlRUk3UVVGRFFTeFBRVUZMUXl4VlFVRk1MRWRCUVd0Q2VFTXNUMEZCVDNkRExGVkJRVkFzU1VGQmNVSXNTMEZCZGtNN1FVRkRRU3hQUVVGTFF5eFJRVUZNTEVkQlFXbENla01zVDBGQlQzbERMRkZCUVZBc1NVRkJiVUlzUlVGQmNFTTdRVUZEUVN4UFFVRkxReXhQUVVGTUxFZEJRV2RDTVVNc1QwRkJUekJETEU5QlFWQXNTVUZCYTBJc1EwRkJiRU03UVVGRFFTeFBRVUZMUXl4TlFVRk1MRWRCUVdVelF5eFBRVUZQTWtNc1RVRkJVQ3hKUVVGcFFpeERRVUZvUXp0QlFVTkJMRTlCUVV0R0xGRkJRVXdzUjBGQmFVSXNTMEZCUzBjc1pVRkJUQ3hEUVVGeFFpeExRVUZMU0N4UlFVRXhRaXhEUVVGcVFqdEJRVU5CTEU5QlFVdEpMRXRCUVV3c1IwRkJZemRETEU5QlFVODJReXhMUVVGeVFqdEJRVU5CTEU5QlFVdERMRk5CUVV3N1FVRkRRVHM3UVVGRlJEczdPenM3T3pzN09FSkJTVms3UVVGRFdDeFJRVUZMTlVNc1NVRkJUQ3hIUVVGWkxFVkJRVm83TzBGQlJVRXNUMEZCU1RaRExHVkJRV1VzUzBGQlMwTXNaVUZCVEN4RFFVRnhRaXhMUVVGTFZDeFJRVUV4UWl4RlFVRnZReXhOUVVGd1F5eERRVUZ1UWp0QlFVTkJMRTlCUVVsVkxHVkJRV1VzUzBGQlMwUXNaVUZCVEN4RFFVRnhRaXhMUVVGTFZpeEpRVUV4UWl4RlFVRm5ReXhOUVVGb1F5eERRVUZ1UWpzN1FVRkZRVHRCUVVOQkxFOUJRVWtzUzBGQlMwOHNTMEZCVkN4RlFVRm5RanRCUVVObUxGRkJRVWxMTEdkQ1FVRm5RaXhEUVVGd1FqdEJRVU5CTEZOQlFVdE1MRXRCUVV3c1IwRkJZV2hDTEUxQlFVMVJMRTlCUVU0c1EwRkJZeXhMUVVGTFVTeExRVUZ1UWl4RFFVRmlPMEZCUTBFc1UwRkJTMEVzUzBGQlRDeERRVUZYVFN4UFFVRllMRU5CUVcxQ0xGVkJRVk5tTEV0QlFWUXNSVUZCWjBJN1FVRkRiRU1zVTBGQlNXZENMRmxCUVZrc1NVRkJTV3BDTEZOQlFVb3NRMEZCWXl4RlFVRkRReXhQUVVGTkxFdEJRVXRUTEV0QlFWb3NSVUZCYlVKT0xGVkJRVk1zVFVGQlRWY3NZVUZCYkVNc1JVRkJaQ3hEUVVGb1FqdEJRVU5CTEZWQlFVdG9SQ3hKUVVGTUxFZEJRVmtzUzBGQlMwRXNTVUZCVEN4RFFVRlZOa0lzVFVGQlZpeERRVUZwUW5GQ0xGVkJRVlZzUkN4SlFVRXpRaXhEUVVGYU96dEJRVVZCTmtNc2NVSkJRV2RDUnl4aFFVRm9RanRCUVVOQkxFdEJURVFzUlVGTFJ5eEpRVXhJTzBGQlRVRTdPMEZCUlVRN1FVRkRRVHRCUVVOQkxFOUJRVWxITEUxQlFVb3NSVUZCV1VNc1QwRkJXanRCUVVOQkxFOUJRVWxETEUxQlFVMURMRTlCUVU0c1EwRkJZeXhMUVVGTGNFSXNTMEZCYmtJc1EwRkJTaXhGUVVFclFqdEJRVU01UWp0QlFVTkJPMEZCUTBFc1VVRkJTeXhEUVVGRkxFdEJRVXRKTEZWQlFWb3NSVUZCZDBJN1FVRkRka0k3UVVGRFFTeFZRVUZMTEVsQlFVbHBRaXhKUVVGSkxFTkJRV0lzUlVGQlowSkJMRWxCUVVrc1MwRkJTMlFzVFVGQmVrSXNSVUZCYVVOakxFZEJRV3BETEVWQlFYTkRPMEZCUTNKRE8wRkJRMEVzVjBGQlMzSkNMRXRCUVV3c1EwRkJWMlVzVDBGQldDeERRVUZ0UWl4VlFVRlRUeXhEUVVGVUxFVkJRVmxETEVOQlFWb3NSVUZCWlR0QlFVTnFReXhYUVVGSlFTeExRVUZMTEVOQlFWUXNSVUZCV1R0QlFVTllUaXhwUWtGQlV5eEpRVUZKVHl4WFFVRktMRU5CUVdkQ0xFVkJRVU14UkN4TlFVRk5Na0lzVFVGQlRVTXNjMEpCUVU0c1EwRkJOa0p0UWl4WlFVRTNRaXhGUVVFeVEyeENMRTFCUVRORExFTkJRV3RFTEV0QlFVczRRaXhsUVVGTUxFVkJRV3hFTEVWQlFUQkZhRU1zVFVGQlRXbERMRkZCUVU0c1EwRkJaVW9zUTBGQlppeERRVUV4UlN4RlFVRTJSaXhMUVVGTGFrSXNVVUZCYkVjc1EwRkJVQ3hGUVVGb1FpeERRVUZVTzBGQlJVRXNVVUZJUkN4TlFVZFBPMEZCUTA0N1FVRkRRVmtzYVVKQlFWTXNTVUZCU1U4c1YwRkJTaXhEUVVGblFpeEZRVUZETVVRc1RVRkJUU3hEUVVGRExFTkJRVVFzUlVGQlNUSkNMRTFCUVUxcFF5eFJRVUZPTEVOQlFXVktMRU5CUVdZc1EwRkJTaXhGUVVGMVFpeExRVUZMYWtJc1VVRkJOVUlzUTBGQlVDeEZRVUZvUWl4RFFVRlVPMEZCUTBFN08wRkJSVVFzV1VGQlMzWkRMRWxCUVV3c1IwRkJXU3hMUVVGTFFTeEpRVUZNTEVOQlFWVTJRaXhOUVVGV0xFTkJRV2xDYzBJc1QwRkJUMjVFTEVsQlFYaENMRU5CUVZvN1FVRkRRU3hQUVZaRUxFVkJWVWNzU1VGV1NEczdRVUZaUVR0QlFVTkJMRmRCUVV0clF5eExRVUZNTEVOQlFWZGxMRTlCUVZnc1EwRkJiVUlzVlVGQlUwOHNRMEZCVkN4RlFVRlpReXhEUVVGYUxFVkJRV1U3UVVGRGFrTXNWMEZCU1VFc1MwRkJTeXhEUVVGVUxFVkJRVms3UVVGRFdFd3NhMEpCUVZVc1NVRkJTVk1zV1VGQlNpeERRVUZwUWl4RlFVRkROMFFzVFVGQlRUSkNMRTFCUVUxRExITkNRVUZPTEVOQlFUWkNhVUlzV1VGQk4wSXNSVUZCTWtOb1FpeE5RVUV6UXl4RFFVRnJSQ3hMUVVGTGFVTXNaMEpCUVV3c1JVRkJiRVFzUlVGQk1rVnVReXhOUVVGTmFVTXNVVUZCVGl4RFFVRmxTaXhEUVVGbUxFTkJRVE5GTEVWQlFUaEdMRXRCUVV0cVFpeFJRVUZ1Unl4RFFVRlFMRVZCUVdwQ0xFTkJRVlk3UVVGRlFTeFJRVWhFTEUxQlIwODdRVUZEVGp0QlFVTkJZU3hyUWtGQlZTeEpRVUZKVXl4WlFVRktMRU5CUVdsQ0xFVkJRVU0zUkN4TlFVRk5MRU5CUVVNc1EwRkJSQ3hGUVVGSk1rSXNUVUZCVFdsRExGRkJRVTRzUTBGQlpVb3NRMEZCWml4RFFVRktMRVZCUVhWQ0xFdEJRVXRxUWl4UlFVRTFRaXhEUVVGUUxFVkJRV3BDTEVOQlFWWTdRVUZEUVRzN1FVRkZSQ3haUVVGTGRrTXNTVUZCVEN4SFFVRlpMRXRCUVV0QkxFbEJRVXdzUTBGQlZUWkNMRTFCUVZZc1EwRkJhVUoxUWl4UlFVRlJjRVFzU1VGQmVrSXNRMEZCV2p0QlFVTkJMRTlCVmtRc1JVRlZSeXhKUVZaSU8wRkJWMEU3UVVGRlJDeExRVGxDUkN4TlFUaENUenRCUVVOT08wRkJRMEVzVlVGQlN5eEpRVUZKZFVRc1NVRkJTU3hEUVVGaUxFVkJRV2RDUVN4SlFVRkpMRXRCUVV0a0xFMUJRWHBDTEVWQlFXbERZeXhIUVVGcVF5eEZRVUZ6UXp0QlFVTnlReXhYUVVGTGNrSXNTMEZCVEN4RFFVRlhaU3hQUVVGWUxFTkJRVzFDTEZWQlFWTlBMRU5CUVZRc1JVRkJXVU1zUTBGQldpeEZRVUZsTzBGQlEycERPMEZCUTBFc1YwRkJTVUVzU1VGQlNTeERRVUZTTEVWQlFWYzdRVUZEVmxZc2RVSkJRV1VzUTBGQlpqdEJRVU5CT3p0QlFVVkVPMEZCUTBFN1FVRkRRU3hYUVVGSkxFdEJRVXRXTEZGQlFVd3NTMEZCYTBJc1NVRkJiRUlzU1VGQk1FSnZRaXhMUVVGTExFdEJRVXQyUWl4TFFVRk1MRU5CUVZkb1F5eE5RVUZZTEVkQlFXOUNMRU5CUVhaRUxFVkJRVEJFTzBGQlEzcEVMRmxCUVVrMlJDeGxRVUZsY0VNc1RVRkJUWEZETEdWQlFVNHNRMEZCYzBJM1JDeFZRVUZWVFN4eFFrRkJhRU1zUTBGQmJrSTdRVUZEUVc5RExIVkNRVUZsYTBJc1pVRkJaMEpzUWl4bFFVRmxMRU5CUVRsRE8wRkJRMEU3TzBGQlJVUk5MR2RDUVVGVExFbEJRVWxQTEZkQlFVb3NRMEZCWjBJc1JVRkJRekZFTEUxQlFVMHlRaXhOUVVGTlF5eHpRa0ZCVGl4RFFVRTJRbTFDTEZsQlFUZENMRVZCUVRKRGJFSXNUVUZCTTBNc1EwRkJhMFFzUTBGQlF5eExRVUZMT0VJc1pVRkJUQ3hGUVVGRUxFVkJRWGxDYUVNc1RVRkJUV2xETEZGQlFVNHNRMEZCWlVvc1EwRkJaaXhEUVVGNlFpeEZRVUUwUXl4TFFVRkxha0lzVVVGQmFrUXNRMEZCYkVRc1EwRkJVQ3hGUVVGb1FpeERRVUZVTzBGQlEwRmhMR2xDUVVGVkxFbEJRVWxUTEZsQlFVb3NRMEZCYVVJc1JVRkJRemRFTEUxQlFVMHlRaXhOUVVGTlF5eHpRa0ZCVGl4RFFVRTJRbWxDTEZsQlFUZENMRVZCUVRKRGFFSXNUVUZCTTBNc1EwRkJhMFFzUTBGQlF5eExRVUZMYVVNc1owSkJRVXdzUlVGQlJDeEZRVUV3UW01RExFMUJRVTFwUXl4UlFVRk9MRU5CUVdWS0xFTkJRV1lzUTBGQk1VSXNSVUZCTmtNc1MwRkJTMnBDTEZGQlFXeEVMRU5CUVd4RUxFTkJRVkFzUlVGQmFrSXNRMEZCVmpzN1FVRkZRU3haUVVGTGRrTXNTVUZCVEN4SFFVRlpMRXRCUVV0QkxFbEJRVXdzUTBGQlZUWkNMRTFCUVZZc1EwRkJhVUp6UWl4UFFVRlBia1FzU1VGQmVFSXNSVUZCT0VKdlJDeFJRVUZSY0VRc1NVRkJkRU1zUTBGQldqdEJRVU5CTEU5QmFrSkVMRVZCYVVKSExFbEJha0pJTzBGQmEwSkJPMEZCUTBRN08wRkJSVVFzVjBGQlR5eEpRVUZRTzBGQlEwRTdPMEZCUlVRc1UwRkJUU3g1UWtGQlRqdEJRVU5CT3pzN096dEJRVVZFT3pzN096dHJRMEZMWjBKMVF5eFJMRVZCUVZVN1FVRkRla0k3UVVGRFFVRXNZMEZCVjBFc1YwRkJWeXhIUVVGWUxFZEJRV2xDTEVkQlFXcENMRWRCUVhWQ1FTeFJRVUZzUXp0QlFVTkJMRlZCUVU4d1FpeExRVUZMUXl4TFFVRk1MRU5CUVZjelFpeFhRVUZYTEVkQlFWZ3NSMEZCYVVJc1IwRkJOVUlzUTBGQlVEdEJRVU5CT3pzN096dEJRVVZFT3pzN096czdPMnREUVU5blFrWXNVU3hGUVVGVmRFTXNTU3hGUVVGTk8wRkJReTlDTEU5QlFVbHpSQ3hOUVVGTlF5eFBRVUZPTEVOQlFXTnFRaXhSUVVGa0xFTkJRVW9zUlVGQk5rSTdRVUZETlVJN1FVRkRRU3hYUVVGUFFTeFRRVUZUT0VJc1IwRkJWQ3hEUVVGaExGVkJRVk5ETEV0QlFWUXNSVUZCWjBJN1FVRkRia01zV1VGQlR5eExRVUZMZEVJc1pVRkJUQ3hEUVVGeFFuTkNMRXRCUVhKQ0xFVkJRVFJDY2tVc1NVRkJOVUlzUTBGQlVEdEJRVU5CTEV0QlJrMHNSVUZGU2l4SlFVWkpMRVZCUlVWelJTeE5RVVpHTEVOQlJWTXNWVUZCVTBNc1EwRkJWQ3hGUVVGWlF5eERRVUZhTEVWQlFXVTdRVUZET1VJc1dVRkJUMFFzU1VGQlNVTXNRMEZCV0R0QlFVTkJMRXRCU2swc1JVRkpTaXhEUVVwSkxFTkJRVkE3UVVGTFFUczdRVUZGUkd4RExHTkJRVmRCTEZOQlFWTnRReXhSUVVGVUxFVkJRVmc3TzBGQlJVRXNUMEZCU1c1RExGTkJRVk52UXl4WFFVRlVMRWRCUVhWQ1F5eE5RVUYyUWl4RFFVRTRRaXhEUVVFNVFpeE5RVUZ4UXl4SFFVRjZReXhGUVVFNFF6dEJRVU0zUXp0QlFVTkJMRmRCUVU5RExGTkJRVk4wUXl4VFFVRlRkVU1zVTBGQlZDeERRVUZ0UWl4RFFVRnVRaXhEUVVGVUxFTkJRVkE3UVVGRFFUczdRVUZGUkR0QlFVTkJPMEZCUTBFc1QwRkJTV0lzWlVGQlpYQkRMRTFCUVUxeFF5eGxRVUZPTEVOQlFYTkNOMFFzVlVGQlZVMHNjVUpCUVdoRExFTkJRVzVDTzBGQlEwRXNWVUZCVDNkRUxFdEJRVXRETEV0QlFVd3NRMEZCVjBnc1pVRkJaU3hMUVVGTFl5eHhRa0ZCVEN4RFFVRXlRbmhETEZGQlFUTkNMRVZCUVhGRGRFTXNTVUZCY2tNc1EwRkJNVUlzUTBGQlVEdEJRVU5CT3p0QlFVVkVPenM3T3pzN096czdPM2REUVU5elFuTkRMRkVzUlVGQlZYUkRMRWtzUlVGQlRUdEJRVU55UXp0QlFVTkJMRmRCUVZGelF5eFJRVUZTTzBGQlEwTXNVMEZCU3l4SFFVRk1PMEZCUTBNc1dVRkJUeXhEUVVGUU8wRkJRMFFzVTBGQlN5eEhRVUZNTzBGQlEwTXNXVUZCVHl4RFFVRlFPMEZCUTBRc1UwRkJTeXhIUVVGTU8wRkJRME1zV1VGQlR5eERRVUZRTzBGQlEwUXNVMEZCU3l4SlFVRk1PMEZCUTBNc1dVRkJUeXhEUVVGUU8wRkJRMFFzVTBGQlN5eEhRVUZNTzBGQlEwTXNXVUZCVHl4RFFVRlFPMEZCUTBRc1UwRkJTeXhKUVVGTU8wRkJRME1zV1VGQlR5eExRVUZRTzBGQlEwUXNVMEZCU3l4SlFVRk1PMEZCUTBNc1dVRkJUeXhIUVVGUU8wRkJRMFFzVTBGQlN5eEhRVUZNTzBGQlEwTXNXVUZCVHl4SFFVRlFPMEZCUTBRc1UwRkJTeXhKUVVGTU8wRkJRME03UVVGRFFTeFpRVUZQTEVsQlFWQTdRVUZEUkN4VFFVRkxMRWxCUVV3N1FVRkRReXhaUVVGUExFbEJRVkE3UVVGRFJDeFRRVUZMTEVsQlFVdzdRVUZEUXl4WlFVRlBMRWxCUVZBN1FVRkRSQ3hUUVVGTExFdEJRVXc3UVVGRFF5eFpRVUZQTEV0QlFWQTdRVUZEUkN4VFFVRkxMRWxCUVV3N1FVRkRReXhaUVVGUExFdEJRVkE3UVVGRFJDeFRRVUZMTEVsQlFVdzdRVUZEUXl4WlFVRlBMRTFCUVZBN1FVRkRSRHRCUVVORE8wRkJRMEU3UVVGb1EwWTdPMEZCYlVOQkxGTkJRVTFCTEZkQlFWY3NNa0pCUVdwQ08wRkJRMEU3T3pzN08wRkJSVVE3T3pzN096dHZRMEZOYTBJN1FVRkJReXhWUVVGUExFMUJRVTBzUzBGQlMwY3NUMEZCV0N4SFFVRnhRaXhEUVVFMVFqdEJRVUU0UWpzN1FVRkZha1E3T3pzN096czdPenR4UTBGTmJVSTdRVUZCUXl4VlFVRlBMRTFCUVUwc1MwRkJTMEVzVDBGQldDeEhRVUZ4UWl4RFFVRTFRanRCUVVFNFFqczdPenM3TzFGQlJ6TkRVQ3hUTEVkQlFVRkJMRk03UVVGRFVqczdPenM3TzBsQlMwMDBRaXhaTEVkQlEwd3NjMEpCUVZrdlJDeE5RVUZhTEVWQlFXOUNPMEZCUVVFN08wRkJRMjVDTEUxQlFVdEZMRWxCUVV3c1IwRkJXVVlzVDBGQlQwVXNTVUZCYmtJN1FVRkRRU3hET3p0UlFVZE5Oa1FzV1N4SFFVRkJRU3haTzBGQlExSTdPenM3T3p0SlFVdE5TQ3hYTEVkQlEwd3NjVUpCUVZrMVJDeE5RVUZhTEVWQlFXOUNPMEZCUVVFN08wRkJRMjVDTEUxQlFVdEZMRWxCUVV3c1IwRkJXVVlzVDBGQlQwVXNTVUZCYmtJN1FVRkRRU3hET3p0UlFVZE5NRVFzVnl4SFFVRkJRU3hYTzBGQlExSTdPenM3T3p0SlFVdE5iMElzYTBJc1IwRkRUQ3cwUWtGQldXaEdMRTFCUVZvc1JVRkJiMEk3UVVGQlFUczdRVUZEYmtJc1RVRkJTME1zU1VGQlRDeEhRVUZaTEZOQlFWbzdRVUZEUVR0QlFVTkJMRTFCUVV0RExFbEJRVXdzUjBGQldUSkNMRTFCUVUxRExITkNRVUZPTEVOQlFUWkNMRWxCUVRkQ0xFVkJRVzFEUXl4TlFVRnVReXhEUVVFd1F6RkNMRlZCUVZWelFpeHhRa0ZCY0VRc1JVRkJNa1V6UWl4UFFVRlBhVVlzVlVGQmJFWXNRMEZCV2p0QlFVTkJMRU03TzFGQlIwMUVMR3RDTEVkQlFVRkJMR3RDTzBGQlExSTdPenM3T3p0SlFVdE5SU3hMTzBGQlEwd3NhMEpCUVdNN1FVRkJRVHM3UVVGRFlpeFBRVUZMYWtZc1NVRkJUQ3hIUVVGWlNTeFZRVUZWVHl4blFrRkJkRUk3UVVGRFFTeFBRVUZMVml4SlFVRk1MRWRCUVZrc1JVRkJXanRCUVVOQkxFOUJRVXRETEVsQlFVd3NSMEZCV1N4RlFVRmFPMEZCUTBFc1QwRkJTMmRHTEUxQlFVd3NSMEZCWXl4RlFVRmtPMEZCUTBFN08wRkJSVVE3T3pzN096czdPenM3TWtKQlRWTkRMRXNzUlVGQlQwTXNWeXhGUVVGaE8wRkJRelZDTEU5QlFVazVRaXhOUVVGTlF5eFBRVUZPTEVOQlFXTTBRaXhMUVVGa0xFTkJRVW9zUlVGQk1FSTdRVUZEZWtKQkxGVkJRVTFxUXl4UFFVRk9MRU5CUVdNc1ZVRkJVMjFETEVOQlFWUXNSVUZCV1ROQ0xFTkJRVm9zUlVGQlpUdEJRVU0xUWp0QlFVTkJMRk5CUVVrc1QwRkJUekJDTEZkQlFWQXNTMEZCZFVJc1ZVRkJka0lzU1VGQmNVTkRMRVZCUVVWeVJpeEpRVUZHTEV0QlFWY3NUVUZCY0VRc1JVRkJORVE3UVVGRE0wUXNWVUZCU1hOR0xHRkJRV0ZHTEZsQlFWa3hRaXhEUVVGYUxFVkJRV1V5UWl4RFFVRm1MRU5CUVdwQ096dEJRVVZCTEZWQlFVa3NVVUZCVDBNc1ZVRkJVQ3g1UTBGQlQwRXNWVUZCVUN4UFFVRnpRaXhSUVVFeFFpeEZRVUZ2UXp0QlFVTnVReXhaUVVGTExFbEJRVWs1UWl4RFFVRlVMRWxCUVdNNFFpeFZRVUZrTEVWQlFUQkNPMEZCUTNwQ0xHZENRVUZQT1VJc1EwRkJVRHRCUVVORExHTkJRVXNzVlVGQlREdEJRVU5ETmtJc1dVRkJSUzlETEZGQlFVWXNSMEZCWVdkRUxGZEJRVmM1UWl4RFFVRllMRU5CUVdJN1FVRkRRVHRCUVVORUxHTkJRVXNzV1VGQlREdEJRVU5ETmtJc1dVRkJSVGxETEZWQlFVWXNSMEZCWlN0RExGZEJRVmM1UWl4RFFVRllMRU5CUVdZN1FVRkRRVHRCUVVORUxHTkJRVXNzVlVGQlREdEJRVU5ETmtJc1dVRkJSVGRETEZGQlFVWXNSMEZCWVRaRExFVkJRVVV4UXl4bFFVRkdMRU5CUVd0Q01rTXNWMEZCVnpsQ0xFTkJRVmdzUTBGQmJFSXNRMEZCWWp0QlFVTkJPMEZCVkVZN1FVRlhRVHM3UVVGRlJEdEJRVU5CTmtJc1UwRkJSWGhETEZOQlFVWTdRVUZEUVR0QlFVTkVPenRCUVVWRUxGVkJRVXMxUXl4SlFVRk1MRWRCUVZrc1MwRkJTMEVzU1VGQlRDeERRVUZWTmtJc1RVRkJWaXhEUVVGcFFuVkVMRVZCUVVWd1JpeEpRVUZ1UWl4RFFVRmFPMEZCUTBFc1ZVRkJTME1zU1VGQlRDeEhRVUZaTUVJc1RVRkJUVEpFTEdGQlFVNHNRMEZCYjBJc1MwRkJTM1JHTEVsQlFVd3NRMEZCVlVVc1RVRkJPVUlzUlVGQmMwTXNRMEZCZEVNc1EwRkJXaXhEUVRGQ05FSXNRMEV3UWpCQ08wRkJRM1JFTEZWQlFVc3JSU3hOUVVGTUxFTkJRVmxOTEVsQlFWb3NRMEZCYVVKSUxFTkJRV3BDTzBGQlEwRXNTMEUxUWtRc1JVRTBRa2NzU1VFMVFrZzdRVUU0UWtFc1NVRXZRa1FzVFVFclFrODdRVUZEVGl4VFFVRkxjRVlzU1VGQlRDeEhRVUZaTEV0QlFVdEJMRWxCUVV3c1EwRkJWVFpDTEUxQlFWWXNRMEZCYVVKeFJDeE5RVUZOYkVZc1NVRkJka0lzUTBGQldqdEJRVU5CTEZOQlFVdERMRWxCUVV3c1IwRkJXVEJDTEUxQlFVMHlSQ3hoUVVGT0xFTkJRVzlDTEV0QlFVdDBSaXhKUVVGTUxFTkJRVlZGTEUxQlFUbENMRVZCUVhORExFTkJRWFJETEVOQlFWb3NRMEZHVFN4RFFVVm5SRHRCUVVOMFJDeFRRVUZMSzBVc1RVRkJUQ3hEUVVGWlRTeEpRVUZhTEVOQlFXbENUQ3hMUVVGcVFqdEJRVU5CT3p0QlFVVkVMRlZCUVU4c1NVRkJVRHRCUVVOQk96dEJRVVZFT3pzN096czdPenN5UWtGTFUwMHNSeXhGUVVGTE8wRkJRMklzVDBGQlNVNHNVVUZCVVN4SlFVRkpiRVFzVTBGQlNpeERRVUZqTEVWQlFVTm9ReXhOUVVGTkxFTkJRVU5ITEZWQlFWVm5RaXhoUVVGWUxFTkJRVkFzUlVGQlpDeERRVUZhTzBGQlEwRXJSQ3hUUVVGTmJFWXNTVUZCVGl4RFFVRlhkVVlzU1VGQldDeERRVUZuUWl4SlFVRm9RaXhGUVVaaExFTkJSVlU3UVVGRGRrSXNUMEZCU1VVc1VVRkJVWGhDTEV0QlFVdERMRXRCUVV3c1EwRkJWeXhYUVVGWGMwSXNSMEZCZEVJc1EwRkJXanRCUVVOQlRpeFRRVUZOYkVZc1NVRkJUaXhIUVVGaGEwWXNUVUZCVFd4R0xFbEJRVTRzUTBGQlZ6WkNMRTFCUVZnc1EwRkJhMEpHTEUxQlFVMHlSQ3hoUVVGT0xFTkJRVzlDUnl4TFFVRndRaXhGUVVFeVFpeERRVUV6UWl4RFFVRnNRaXhEUVVGaUxFTkJTbUVzUTBGSmEwUTdRVUZETDBRc1ZVRkJUeXhMUVVGTFF5eFJRVUZNTEVOQlFXTlNMRXRCUVdRc1EwRkJVRHRCUVVOQk96dEJRVVZFT3pzN096czdPenM3T3p0dFEwRlJhVUpUTEZNc1JVRkJWME1zVnl4RlFVRmhReXhwUWl4RlFVRnRRa01zYVVJc1JVRkJiVUk3UVVGRE9VVkVMSFZDUVVGdlFrRXNjVUpCUVhGQ0xFVkJRWHBETzBGQlEwRkRMSFZDUVVGdlFrRXNjVUpCUVhGQ0xFTkJRWHBET3p0QlFVVkJMRTlCUVVsYUxGRkJRVkVzU1VGQlNXeEVMRk5CUVVvc1EwRkJZeXhGUVVGRGFFTXNUVUZCVFN4RFFVRkRSeXhWUVVGVmEwSXNjMEpCUVZnc1EwRkJVQ3hGUVVGa0xFTkJRVm83UVVGRFFUWkVMRk5CUVUxc1JpeEpRVUZPTEVOQlFWZDFSaXhKUVVGWUxFTkJRV2RDTEVsQlFXaENMRVZCVERoRkxFTkJTM1pFTzBGQlEzWkNUQ3hUUVVGTmJFWXNTVUZCVGl4SFFVRmhhMFlzVFVGQlRXeEdMRWxCUVU0c1EwRkJWelpDTEUxQlFWZ3NRMEZCYTBKR0xFMUJRVTB5UkN4aFFVRk9MRU5CUVc5Q1N5eFRRVUZ3UWl4RlFVRXJRaXhEUVVFdlFpeERRVUZzUWl4RFFVRmlMRU5CVGpoRkxFTkJUVmc3TzBGQlJXNUZMRTlCUVVsSkxHVkJRV1U1UWl4TFFVRkxLMElzU1VGQlRDeERRVUZWU2l4WFFVRldMRU5CUVc1Q0xFTkJVamhGTEVOQlVXNURPMEZCUXpORFZpeFRRVUZOYkVZc1NVRkJUaXhIUVVGaGEwWXNUVUZCVFd4R0xFbEJRVTRzUTBGQlZ6WkNMRTFCUVZnc1EwRkJhMEpHTEUxQlFVMHlSQ3hoUVVGT0xFTkJRVzlDVXl4WlFVRndRaXhGUVVGclF5eERRVUZzUXl4RFFVRnNRaXhEUVVGaUxFTkJWRGhGTEVOQlUxSTdRVUZEZEVWaUxGTkJRVTFzUml4SlFVRk9MRWRCUVdGclJpeE5RVUZOYkVZc1NVRkJUaXhEUVVGWE5rSXNUVUZCV0N4RFFVRnJRa1lzVFVGQlRUSkVMR0ZCUVU0c1EwRkJiMEpQTEdsQ1FVRndRaXhGUVVGMVF5eERRVUYyUXl4RFFVRnNRaXhEUVVGaUxFTkJWamhGTEVOQlZVZzdRVUZETTBWWUxGTkJRVTFzUml4SlFVRk9MRWRCUVdGclJpeE5RVUZOYkVZc1NVRkJUaXhEUVVGWE5rSXNUVUZCV0N4RFFVRnJRa1lzVFVGQlRUSkVMR0ZCUVU0c1EwRkJiMEpSTEdsQ1FVRndRaXhGUVVGMVF5eERRVUYyUXl4RFFVRnNRaXhEUVVGaUxFTkJXRGhGTEVOQlYwZzdRVUZETTBVc1ZVRkJUeXhMUVVGTFNpeFJRVUZNTEVOQlFXTlNMRXRCUVdRc1EwRkJVRHRCUVVOQk96dEJRVVZFT3pzN096czdPenM3YTBOQlRXZENaU3hGTEVWQlFVbERMRVVzUlVGQlNUdEJRVU4yUWl4UFFVRkphRUlzVVVGQlVTeEpRVUZKYkVRc1UwRkJTaXhEUVVGakxFVkJRVU5vUXl4TlFVRk5MRU5CUVVOSExGVkJRVlZ0UWl4eFFrRkJXQ3hEUVVGUUxFVkJRV1FzUTBGQldqdEJRVU5CTkVRc1UwRkJUV3hHTEVsQlFVNHNRMEZCVjNWR0xFbEJRVmdzUTBGQlowSXNTVUZCYUVJc1JVRkdkVUlzUTBGRlFUczdRVUZGZGtJc1QwRkJTVmtzVDBGQlQwUXNUVUZCVFN4RFFVRnFRanRCUVVOQlJDeFJRVUZMUVN4TlFVRk5MRU5CUVZnN08wRkJSVUU3UVVGRFFTeFBRVUZKTEU5QlFVOURMRVZCUVZBc1MwRkJZeXhYUVVGc1FpeEZRVUVyUWp0QlFVTTVRaXhSUVVGSlJTeFRRVUZUTEVOQlExb3NRMEZCUXl4SlFVRkVMRVZCUVU4c1NVRkJVQ3hGUVVGaExFbEJRV0lzUlVGQmJVSXNTVUZCYmtJc1JVRkJlVUlzU1VGQmVrSXNSVUZCSzBJc1NVRkJMMElzUlVGQmNVTXNSMEZCY2tNc1JVRkJNRU1zUjBGQk1VTXNSVUZCSzBNc1IwRkJMME1zUlVGQmIwUXNSMEZCY0VRc1JVRkJlVVFzUjBGQmVrUXNSVUZCT0VRc1IwRkJPVVFzUlVGQmJVVXNSMEZCYmtVc1JVRkJkMFVzU1VGQmVFVXNSVUZCT0VVc1NVRkJPVVVzUTBGRVdTeEZRVVZhTEVOQlFVTXNTVUZCUkN4RlFVRlBMRWxCUVZBc1JVRkJZU3hKUVVGaUxFVkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFZEJRWGhDTEVWQlFUWkNMRWRCUVRkQ0xFVkJRV3RETEVkQlFXeERMRVZCUVhWRExFZEJRWFpETEVWQlFUUkRMRWRCUVRWRExFVkJRV2xFTEVkQlFXcEVMRVZCUVhORUxFbEJRWFJFTEVWQlFUUkVMRWxCUVRWRUxFVkJRV3RGTEVsQlFXeEZMRVZCUVhkRkxFbEJRWGhGTEVWQlFUaEZMRWxCUVRsRkxFTkJSbGtzUTBGQllqdEJRVWxCTEZGQlFVbERMRk5CUVZOS0xFZEJRVWN2Uml4TlFVRm9RanRCUVVOQkxGRkJRVWx2Unl4UFFVRlBUQ3hOUVVGTkxFZEJRV3BDT3p0QlFVVkJMRkZCUVVsQkxFZEJRVWNzUTBGQlNDeE5RVUZWUVN4SFFVRkhMRU5CUVVnc1JVRkJUWGhDTEZkQlFVNHNSVUZCWkN4RlFVRnRRekJDTEU5QlFVOHNRMEZCVURzN1FVRkZia01zVVVGQlNVVXNVMEZCVXl4RFFVRmlMRVZCUVdkQ08wRkJRMllzWVVGQlVVb3NSMEZCUjNaQ0xFMUJRVWdzUTBGQlZUSkNMRk5CUVZNc1EwRkJia0lzUTBGQlVqdEJRVU5ETEZkQlFVc3NSMEZCVER0QlFVTkRSaXhqUVVGUExFTkJRVkE3UVVGRFFVY3NZMEZCVDB3c1IwRkJSM1pDTEUxQlFVZ3NRMEZCVlN4RFFVRldMRVZCUVdGRUxGZEJRV0lzUlVGQlVEdEJRVU5CTmtJc1kwRkJUMEVzUzBGQlMzcEZMRTFCUVV3c1EwRkJXVzlGTEVkQlFVZHlRaXhUUVVGSUxFTkJRV0VzUTBGQllpeEZRVUZuUW5sQ0xGTkJRVk1zUTBGQmVrSXNRMEZCV2l4RFFVRlFPMEZCUTBFN1FVRkRSQ3hYUVVGTExFZEJRVXc3UVVGRFEwWXNZMEZCVHl4RFFVRlFPMEZCUTBGSExHTkJRVTlNTEVkQlFVZDJRaXhOUVVGSUxFTkJRVlVzUTBGQlZpeEZRVUZoUkN4WFFVRmlMRVZCUVZBN1FVRkRRVFpDTEdOQlFVOUJMRXRCUVV0NlJTeE5RVUZNTEVOQlFWbHZSU3hIUVVGSGNrSXNVMEZCU0N4RFFVRmhMRU5CUVdJc1JVRkJaMEo1UWl4VFFVRlRMRU5CUVhwQ0xFTkJRVm9zUTBGQlVEdEJRVU5CTzBGQlEwUXNWMEZCU3l4SFFVRk1PMEZCUTBOR0xHTkJRVThzUTBGQlVEdEJRVU5CUnl4alFVRlBUQ3hIUVVGSGRrSXNUVUZCU0N4RFFVRlZMRU5CUVZZc1JVRkJZVFpDTEZkQlFXSXNSVUZCVUR0QlFVTkJSQ3hqUVVGUFFTeExRVUZMZWtVc1RVRkJUQ3hEUVVGWmIwVXNSMEZCUjNKQ0xGTkJRVWdzUTBGQllTeERRVUZpTEVWQlFXZENlVUlzVTBGQlV5eERRVUY2UWl4RFFVRmFMRU5CUVZBN1FVRkRRVHRCUVVORUxGZEJRVXNzUjBGQlREdEJRVU5EUml4alFVRlBMRU5CUVZBN1FVRkRRVWNzWTBGQlQwd3NSMEZCUjNaQ0xFMUJRVWdzUTBGQlZTeERRVUZXTEVWQlFXRTJRaXhYUVVGaUxFVkJRVkE3UVVGRFFVUXNZMEZCVDBFc1MwRkJTM3BGTEUxQlFVd3NRMEZCV1c5RkxFZEJRVWR5UWl4VFFVRklMRU5CUVdFc1EwRkJZaXhGUVVGblFubENMRk5CUVZNc1EwRkJla0lzUTBGQldpeERRVUZRTzBGQlEwRTdRVUZ3UWtZN1FVRnpRa0U3TzBGQlJVUXNVVUZCU1Vjc1lVRkJZVW9zVDBGQlQwUXNTVUZCVUN4RlFVRmhUU3hQUVVGaUxFTkJRWEZDU0N4SlFVRnlRaXhEUVVGcVFqdEJRVU5CVEN4VFFVRkxUeXhsUVVGbExFTkJRVU1zUTBGQmFFSXNSMEZCYjBJc1EwRkJjRUlzUjBGQmQwSkJMR0ZCUVdFc1EwRkJNVU03UVVGRFFUczdRVUZGUkhSQ0xGTkJRVTFzUml4SlFVRk9MRWRCUVdGclJpeE5RVUZOYkVZc1NVRkJUaXhEUVVGWE5rSXNUVUZCV0N4RFFVRnJRa1lzVFVGQlRUSkVMR0ZCUVU0c1EwRkJiMEpYTEVWQlFYQkNMRVZCUVhkQ0xFTkJRWGhDTEVOQlFXeENMRU5CUVdJc1EwRXZRM1ZDTEVOQkswTnhRenRCUVVNMVJHWXNVMEZCVFd4R0xFbEJRVTRzUjBGQllXdEdMRTFCUVUxc1JpeEpRVUZPTEVOQlFWYzJRaXhOUVVGWUxFTkJRV3RDUml4TlFVRk5Na1FzWVVGQlRpeERRVUZ2UW1Fc1NVRkJjRUlzUlVGQk1FSXNRMEZCTVVJc1EwRkJiRUlzUTBGQllpeERRV2hFZFVJc1EwRm5SSFZETzBGQlF6bEVMRlZCUVU4c1MwRkJTMVFzVVVGQlRDeERRVUZqVWl4TFFVRmtMRU5CUVZBN1FVRkRRVHM3UVVGRlJEczdPenM3T3pzN01FSkJTMUYzUWl4SkxFVkJRVTA3UVVGRFlpeFBRVUZKZUVJc1VVRkJVU3hKUVVGSmJFUXNVMEZCU2l4RFFVRmpMRVZCUVVOb1F5eE5RVUZOTEVOQlFVTkhMRlZCUVZWVExGbEJRVmdzUTBGQlVDeEZRVUZrTEVOQlFWbzdRVUZEUVN4UFFVRkpLMFlzWTBGQlkyaEdMRTFCUVUxcFJpeGhRVUZPTEVOQlFXOUNSaXhKUVVGd1FpeERRVUZzUWp0QlFVTkJlRUlzVTBGQlRXeEdMRWxCUVU0c1IwRkJZV3RHTEUxQlFVMXNSaXhKUVVGT0xFTkJRVmMyUWl4TlFVRllMRU5CUVd0Q1JpeE5RVUZOUXl4elFrRkJUaXhEUVVFMlFpdEZMRmxCUVZsNlJ5eE5RVUY2UXl4RFFVRnNRaXhEUVVGaUxFTkJTR0VzUTBGSGNVVTdRVUZEYkVablJpeFRRVUZOYkVZc1NVRkJUaXhIUVVGaGEwWXNUVUZCVFd4R0xFbEJRVTRzUTBGQlZ6WkNMRTFCUVZnc1EwRkJhMEk0UlN4WFFVRnNRaXhEUVVGaUxFTkJTbUVzUTBGSlowTTdRVUZETjBNc1ZVRkJUeXhMUVVGTGFrSXNVVUZCVEN4RFFVRmpVaXhMUVVGa0xFTkJRVkE3UVVGRFFUczdRVUZGUkRzN096czdPenM3SzBKQlMyRjNRaXhKTEVWQlFVMDdRVUZEYkVJc1QwRkJTWGhDTEZGQlFWRXNTVUZCU1d4RUxGTkJRVW9zUTBGQll5eEZRVUZEYUVNc1RVRkJUU3hEUVVGRFJ5eFZRVUZWVlN4cFFrRkJXQ3hEUVVGUUxFVkJRV1FzUTBGQldqdEJRVU5CTEU5QlFVazRSaXhqUVVGamFFWXNUVUZCVFdsR0xHRkJRVTRzUTBGQmIwSkdMRWxCUVhCQ0xFTkJRV3hDTzBGQlEwRjRRaXhUUVVGTmJFWXNTVUZCVGl4SFFVRmhhMFlzVFVGQlRXeEdMRWxCUVU0c1EwRkJWelpDTEUxQlFWZ3NRMEZCYTBKR0xFMUJRVTFETEhOQ1FVRk9MRU5CUVRaQ0swVXNXVUZCV1hwSExFMUJRWHBETEVOQlFXeENMRU5CUVdJc1EwRklhMElzUTBGSFowVTdRVUZEYkVablJpeFRRVUZOYkVZc1NVRkJUaXhIUVVGaGEwWXNUVUZCVFd4R0xFbEJRVTRzUTBGQlZ6WkNMRTFCUVZnc1EwRkJhMEk0UlN4WFFVRnNRaXhEUVVGaUxFTkJTbXRDTEVOQlNUSkNPMEZCUXpkRExGVkJRVThzUzBGQlMycENMRkZCUVV3c1EwRkJZMUlzUzBGQlpDeERRVUZRTzBGQlEwRTdPMEZCUlVRN096czdPenM3T3l0Q1FVdGhkMElzU1N4RlFVRk5PMEZCUTJ4Q0xFOUJRVWw0UWl4UlFVRlJMRWxCUVVsc1JDeFRRVUZLTEVOQlFXTXNSVUZCUTJoRExFMUJRVTBzUTBGQlEwY3NWVUZCVlZjc2EwSkJRVmdzUTBGQlVDeEZRVUZrTEVOQlFWbzdRVUZEUVN4UFFVRkpOa1lzWTBGQlkyaEdMRTFCUVUxcFJpeGhRVUZPTEVOQlFXOUNSaXhKUVVGd1FpeERRVUZzUWp0QlFVTkJlRUlzVTBGQlRXeEdMRWxCUVU0c1IwRkJZV3RHTEUxQlFVMXNSaXhKUVVGT0xFTkJRVmMyUWl4TlFVRllMRU5CUVd0Q1JpeE5RVUZOUXl4elFrRkJUaXhEUVVFMlFpdEZMRmxCUVZsNlJ5eE5RVUY2UXl4RFFVRnNRaXhEUVVGaUxFTkJTR3RDTEVOQlIyZEZPMEZCUTJ4R1owWXNVMEZCVFd4R0xFbEJRVTRzUjBGQllXdEdMRTFCUVUxc1JpeEpRVUZPTEVOQlFWYzJRaXhOUVVGWUxFTkJRV3RDT0VVc1YwRkJiRUlzUTBGQllpeERRVXByUWl4RFFVa3lRanRCUVVNM1F5eFZRVUZQTEV0QlFVdHFRaXhSUVVGTUxFTkJRV05TTEV0QlFXUXNRMEZCVUR0QlFVTkJPenRCUVVWRU96czdPenM3T3p0dlEwRkxhMEozUWl4SkxFVkJRVTA3UVVGRGRrSXNUMEZCU1hoQ0xGRkJRVkVzU1VGQlNXeEVMRk5CUVVvc1EwRkJZeXhGUVVGRGFFTXNUVUZCVFN4RFFVRkRSeXhWUVVGVldTeDFRa0ZCV0N4RFFVRlFMRVZCUVdRc1EwRkJXanRCUVVOQkxFOUJRVWswUml4alFVRmphRVlzVFVGQlRXbEdMR0ZCUVU0c1EwRkJiMEpHTEVsQlFYQkNMRU5CUVd4Q08wRkJRMEY0UWl4VFFVRk5iRVlzU1VGQlRpeEhRVUZoYTBZc1RVRkJUV3hHTEVsQlFVNHNRMEZCVnpaQ0xFMUJRVmdzUTBGQmEwSkdMRTFCUVUxRExITkNRVUZPTEVOQlFUWkNLMFVzV1VGQldYcEhMRTFCUVhwRExFTkJRV3hDTEVOQlFXSXNRMEZJZFVJc1EwRkhNa1E3UVVGRGJFWm5SaXhUUVVGTmJFWXNTVUZCVGl4SFFVRmhhMFlzVFVGQlRXeEdMRWxCUVU0c1EwRkJWelpDTEUxQlFWZ3NRMEZCYTBJNFJTeFhRVUZzUWl4RFFVRmlMRU5CU25WQ0xFTkJTWE5DTzBGQlF6ZERMRlZCUVU4c1MwRkJTMnBDTEZGQlFVd3NRMEZCWTFJc1MwRkJaQ3hEUVVGUU8wRkJRMEU3TzBGQlJVUTdPenM3T3pzN096UkNRVXRWZDBJc1NTeEZRVUZOTzBGQlEyWXNUMEZCU1hoQ0xGRkJRVkVzU1VGQlNXeEVMRk5CUVVvc1EwRkJZeXhGUVVGRGFFTXNUVUZCVFN4RFFVRkRSeXhWUVVGVll5eGpRVUZZTEVOQlFWQXNSVUZCWkN4RFFVRmFPMEZCUTBFc1QwRkJTVEJHTEdOQlFXTm9SaXhOUVVGTmFVWXNZVUZCVGl4RFFVRnZRa1lzU1VGQmNFSXNRMEZCYkVJN1FVRkRRWGhDTEZOQlFVMXNSaXhKUVVGT0xFZEJRV0ZyUml4TlFVRk5iRVlzU1VGQlRpeERRVUZYTmtJc1RVRkJXQ3hEUVVGclFrWXNUVUZCVFVNc2MwSkJRVTRzUTBGQk5rSXJSU3haUVVGWmVrY3NUVUZCZWtNc1EwRkJiRUlzUTBGQllpeERRVWhsTEVOQlIyMUZPMEZCUTJ4R1owWXNVMEZCVFd4R0xFbEJRVTRzUjBGQllXdEdMRTFCUVUxc1JpeEpRVUZPTEVOQlFWYzJRaXhOUVVGWUxFTkJRV3RDT0VVc1YwRkJiRUlzUTBGQllpeERRVXBsTEVOQlNUaENPMEZCUXpkRExGVkJRVThzUzBGQlMycENMRkZCUVV3c1EwRkJZMUlzUzBGQlpDeERRVUZRTzBGQlEwRTdPMEZCUlVRN096czdPenM3T3poQ1FVdFpkMElzU1N4RlFVRk5PMEZCUTJwQ0xFOUJRVWw0UWl4UlFVRlJMRWxCUVVsc1JDeFRRVUZLTEVOQlFXTXNSVUZCUTJoRExFMUJRVTBzUTBGQlEwY3NWVUZCVldVc1kwRkJXQ3hEUVVGUUxFVkJRV1FzUTBGQldqdEJRVU5CTEU5QlFVbDVSaXhqUVVGamFFWXNUVUZCVFdsR0xHRkJRVTRzUTBGQmIwSkdMRWxCUVhCQ0xFTkJRV3hDTzBGQlEwRjRRaXhUUVVGTmJFWXNTVUZCVGl4SFFVRmhhMFlzVFVGQlRXeEdMRWxCUVU0c1EwRkJWelpDTEUxQlFWZ3NRMEZCYTBKR0xFMUJRVTFETEhOQ1FVRk9MRU5CUVRaQ0swVXNXVUZCV1hwSExFMUJRWHBETEVOQlFXeENMRU5CUVdJc1EwRklhVUlzUTBGSGFVVTdRVUZEYkVablJpeFRRVUZOYkVZc1NVRkJUaXhIUVVGaGEwWXNUVUZCVFd4R0xFbEJRVTRzUTBGQlZ6WkNMRTFCUVZnc1EwRkJhMEk0UlN4WFFVRnNRaXhEUVVGaUxFTkJTbWxDTEVOQlNUUkNPMEZCUXpkRExGVkJRVThzUzBGQlMycENMRkZCUVV3c1EwRkJZMUlzUzBGQlpDeERRVUZRTzBGQlEwRTdPMEZCUlVRN096czdPenM3T3pKQ1FVdFRNa0lzU3l4RlFVRlBPMEZCUTJZc1QwRkJTVE5DTEZGQlFWRXNTVUZCU1d4RUxGTkJRVW9zUTBGQll5eEZRVUZEYUVNc1RVRkJUU3hEUVVGRFJ5eFZRVUZWWVN4aFFVRllMRU5CUVZBc1JVRkJaQ3hEUVVGYU8wRkJRMEVzVDBGQlNUSkdMR05CUVdOb1JpeE5RVUZOYVVZc1lVRkJUaXhEUVVGdlFrTXNTMEZCY0VJc1EwRkJiRUk3UVVGRFFUTkNMRk5CUVUxc1JpeEpRVUZPTEVkQlFXRnJSaXhOUVVGTmJFWXNTVUZCVGl4RFFVRlhOa0lzVFVGQldDeERRVUZyUWtZc1RVRkJUVU1zYzBKQlFVNHNRMEZCTmtJclJTeFpRVUZaZWtjc1RVRkJla01zUTBGQmJFSXNRMEZCWWl4RFFVaGxMRU5CUjIxRk8wRkJRMnhHWjBZc1UwRkJUV3hHTEVsQlFVNHNSMEZCWVd0R0xFMUJRVTFzUml4SlFVRk9MRU5CUVZjMlFpeE5RVUZZTEVOQlFXdENPRVVzVjBGQmJFSXNRMEZCWWl4RFFVcGxMRU5CU1RoQ08wRkJRemRETEZWQlFVOHNTMEZCUzJwQ0xGRkJRVXdzUTBGQlkxSXNTMEZCWkN4RFFVRlFPMEZCUTBFN08wRkJSVVE3T3pzN096czdLMEpCU1dFN1FVRkRXaXhQUVVGSlFTeFJRVUZSTEVsQlFVbDRRaXhYUVVGS0xFTkJRV2RDTEVWQlFVTXhSQ3hOUVVGTkxFTkJRVU1zU1VGQlJDeEZRVUZQTEVsQlFWQXNSVUZCWVN4SlFVRmlMRVZCUVcxQ0xFbEJRVzVDTEVOQlFWQXNSVUZCYUVJc1EwRkJXanRCUVVOQkxGVkJRVThzUzBGQlN6QkdMRkZCUVV3c1EwRkJZMUlzUzBGQlpDeERRVUZRTzBGQlEwRTdPenM3T3p0UlFVbE5SaXhMTEVkQlFVRkJMRXM3TzBGQlIxSTdPenRKUVVkTmNrUXNTenM3T3pzN096czdPMEZCUlV3N096czdORUpCU1dsQ08wRkJRMmhDTEZWQlFVOTRRaXhWUVVGVlF5eFBRVUZxUWp0QlFVTkJPenRCUVVWRU96czdPenM3T3p0blEwRkxjVUl3Unl4TkxFVkJRVkU3UVVGRE5VSXNWVUZCVDBFc1QwRkJUME1zUzBGQlVDeERRVUZoTEVWQlFXSXNSVUZCYVVJMVF5eEhRVUZxUWl4RFFVRnhRanRCUVVGQkxGZEJRVkUyUXl4TFFVRkxReXhWUVVGTUxFVkJRVkk3UVVGQlFTeEpRVUZ5UWl4RFFVRlFPMEZCUTBFN08wRkJSVVE3T3pzN096czdPelJDUVV0cFFrTXNReXhGUVVGSE8wRkJRMjVDTEZWQlFVOHNRMEZCUTBNc1RVRkJUVU1zVjBGQlYwWXNRMEZCV0N4RFFVRk9MRU5CUVVRc1NVRkJlVUpITEZOQlFWTklMRU5CUVZRc1EwRkJhRU03UVVGRFFUczdRVUZGUkRzN096czdPenM3T3pKQ1FVMXZRbWhHTEVzc1JVRkJUenRCUVVOMFFpeFZRVUZQTEhWQ1FVRlBRU3hMUVVGUUxFTkJRVkE3UVVGRFFUczdRVUZGVERzN096czdPenM3T3pzN08zbERRVk00UW05R0xFc3NSVUZCVHp0QlFVTnFReXhQUVVGSlF5eFRRVUZUUkN4UlFVRlJMRWxCUVhKQ096dEJRVVZCTEZWQlFVOUJMRkZCUVZGQkxGTkJRVk1zUTBGQmVFSXNSVUZCTWtJN1FVRkRka0pETEdWQlFWY3NRMEZCV0R0QlFVTkJRU3hqUVVGWlJDeFJRVUZSTEVsQlFWUXNSMEZCYVVJc1NVRkJOVUk3UVVGRFNEczdRVUZGUkN4UFFVRkpSU3hSUVVGUkxFVkJRVm83UVVGRFFTeFZRVUZQTEVsQlFWQXNSVUZCWVR0QlFVTlVRU3hWUVVGTmFrTXNTVUZCVGl4RFFVRlhaME1zVTBGQlV5eEpRVUZ3UWpzN1FVRkZRU3hSUVVGSlFTeFRRVUZUTEVsQlFXSXNSVUZCYlVKQkxGZEJRVmNzUTBGQldDeERRVUZ1UWl4TFFVTkxPMEZCUVVVN1FVRkJVVHRCUVVOc1FqczdRVUZGUkN4VlFVRlBReXhMUVVGUU8wRkJRMGc3TzBGQlJVUTdPenM3T3pzN08ydERRVXQxUWtNc1F5eEZRVUZITzBGQlEzcENMRlZCUVU5RExGVkJRVlZFTEVOQlFWWXNSVUZCWVZZc1MwRkJZaXhEUVVGdFFpeFBRVUZ1UWl4RlFVRTBRamRITEUxQlFUVkNMRWRCUVhGRExFTkJRVFZETzBGQlEwRTdPMEZCUlVRN096czdPenM3TzJ0RFFVdDFRbmxJTEVzc1JVRkJUenRCUVVNM1FpeFBRVUZKUXl4TlFVRk5MRVZCUVZZN1FVRkRRU3hQUVVGSlF5eFpRVUZLT3p0QlFVVkJSaXhUUVVGTk1VVXNUMEZCVGl4RFFVRmpMRlZCUVZNMlJTeEpRVUZVTEVWQlFXVTdRVUZETlVKRUxHMUNRVUZsUXl4TFFVRkxkRVFzVVVGQlRDeERRVUZqTEVWQlFXUXNRMEZCWmpzN1FVRkZRVHRCUVVOQkxGRkJRVWx4UkN4aFFVRmhNMGdzVFVGQllpeEpRVUYxUWl4RFFVRXpRaXhGUVVFNFFqSklMR1ZCUVdVc1RVRkJUVUVzV1VGQmNrSTdPMEZCUlRsQ1JDeFhRVUZQUXl4WlFVRlFPMEZCUTBFc1NVRlFSRHM3UVVGVFFTeFZRVUZQYkVRc1UwRkJVMmxFTEVkQlFWUXNSVUZCWXl4RlFVRmtMRU5CUVZBN1FVRkRRVHM3UVVGRlJEczdPenM3T3pzN08yZERRVTF4UWtjc1RTeEZRVUZSUXl4WExFVkJRV0U3UVVGRGVrTkJMR2xDUVVGalFTeGxRVUZsTEVOQlFUZENPenRCUVVWQkxFOUJRVWxETEZsQlFWbEdMRTlCUVU5MlJDeFJRVUZRTEVOQlFXZENMRVZCUVdoQ0xFTkJRV2hDT3p0QlFVVkJMRTlCUVVsNVJDeFZRVUZWTDBnc1RVRkJWaXhIUVVGdFFpeERRVUYyUWl4RlFVRXdRanRCUVVGRk8wRkJRek5DSzBnc1owSkJRVmtzVFVGQlRVRXNVMEZCYkVJN1FVRkRRVHM3UVVGRlJEdEJRVU5CTEU5QlFVbERMRmRCUVZkRUxGVkJRVlZGTEV0QlFWWXNRMEZCWjBJc1QwRkJhRUlzUTBGQlpqczdRVUZGUVR0QlFVTkJSQ3hqUVVGWFFTeFRRVUZUTDBRc1IwRkJWQ3hEUVVGaE8wRkJRVUVzVjBGQlVWRXNVMEZCVTNsRUxFbEJRVlFzUlVGQlpTeEZRVUZtTEVOQlFWSTdRVUZCUVN4SlFVRmlMRU5CUVZnN08wRkJSVUU3UVVGRFFTeFBRVUZKUml4VFFVRlRhRWtzVFVGQlZDeEhRVUZyUWpoSUxGZEJRWFJDTEVWQlFXMURPMEZCUTJ4RExGZEJRVTlCTEdOQlFXTkZMRk5CUVZOb1NTeE5RVUYyUWl4SFFVRm5ReXhEUVVGMlF5eEZRVUV3UXp0QlFVTjZRMmRKTEdOQlFWTkhMRTlCUVZRc1EwRkJhVUlzUTBGQmFrSTdRVUZEUVR0QlFVTkVPenRCUVVWRUxGVkJRVTlJTEZGQlFWQTdRVUZEUVRzN1FVRkZSRHM3T3pzN096czdNRUpCUzJVNVJDeExMRVZCUVU4N1FVRkRja0lzVDBGQlNXWXNUVUZCVFVNc1QwRkJUaXhEUVVGall5eExRVUZrTEVOQlFVb3NSVUZCTUVJc1QwRkJUMEVzUzBGQlVEdEJRVU14UWl4VlFVRlBMRU5CUVVOQkxFdEJRVVFzUTBGQlVEdEJRVU5CT3pzN096czdVVUZIVFhwRExFc3NSMEZCUVVFc1N6czdTVUZEUmpKSExFODdRVUZGVEN4dlFrRkJZenRCUVVGQk8wRkJSV0k3UVVGRVFUczdPMEZCUjBRN096czdPenM3TzJsRFFVbGxReXhMTEVWQlFVODdRVUZEY2tJc1QwRkJTVU1zVVVGQlVTeEpRVUZKZUVRc1MwRkJTaXhGUVVGYU8wRkJRMEVzVDBGQlNUVkRMRWxCUVVvN1FVRkRRU3hQUVVGSmNVY3NWVUZCVlN4RlFVRmtPenRCUVVWQlJpeFRRVUZOUnl4VFFVRk9MRU5CUVdkQ2VrWXNUMEZCYUVJc1EwRkJkMElzVlVGQlV6QkdMRkZCUVZRc1JVRkJiVUk3UVVGRE1VTkdMR05CUVZVc1JVRkJWanM3UVVGRlFTeFJRVUZKUlN4VFFVRlRReXhSUVVGVUxFdEJRWE5DTEVkQlFURkNMRVZCUVN0Q08wRkJRemxDUkN4alFVRlRSU3hKUVVGVUxFTkJRV00xUml4UFFVRmtMRU5CUVhOQ0xGVkJRVk0yUml4SFFVRlVMRVZCUVdNN1FVRkRia003UVVGRFFVd3NZMEZCVVd4RUxFbEJRVklzUTBGQllTeExRVUZMZDBRc1dVRkJUQ3hEUVVGclFrUXNSMEZCYkVJc1EwRkJZanRCUVVOQkxFMUJTRVE3UVVGTFFTeExRVTVFTEUxQlRVOHNTVUZCU1Vnc1UwRkJVME1zVVVGQlZDeExRVUZ6UWl4SFFVRXhRaXhGUVVFclFqdEJRVU55UXp0QlFVTkJlRWNzV1VGQlR5eExRVUZMTkVjc1pVRkJUQ3hEUVVGeFFrd3NVVUZCY2tJc1EwRkJVRHRCUVVOQk8wRkJRMEU3TzBGQlJVUklMRlZCUVUwNVF5eFJRVUZPTEVOQlFXVXNTVUZCU1hwRUxGTkJRVW9zUTBGQll5eEZRVUZEUXl4UFFVRlBkVWNzVDBGQlVpeEZRVUZwUW5CSExGVkJRVlVzUzBGQlN6SkhMR1ZCUVV3c1EwRkJjVUpNTEZGQlFYSkNMRU5CUVROQ0xFVkJRVEpFZGtjc1RVRkJUVUVzU1VGQmFrVXNSVUZCWkN4RFFVRm1PenRCUVVWQk8wRkJRMEZCTEZkQlFVOHNRMEZCVUR0QlFVTkJMRWxCYmtKRU96dEJRWEZDUVN4VlFVRlBiMGNzUzBGQlVEdEJRVU5CT3p0QlFVZEVPenM3T3pzN095dENRVWxoZEVjc1N5eEZRVUZQTzBGQlEyNUNMRlZCUVU5QkxFMUJRVTByUnl4UFFVRk9MRU5CUVdNc1IwRkJaQ3hGUVVGdFFpeEZRVUZ1UWl4RFFVRlFPMEZCUTBFN08wRkJSMFE3T3pzN096czdhME5CU1dkQ00wTXNTU3hGUVVGTk8wRkJRM0pDTEZkQlFWRkJMRXRCUVV0cVJTeFJRVUZpTzBGQlEwTXNVMEZCU3l4SFFVRk1PMEZCUTBNc1dVRkJUeXhIUVVGUU8wRkJRMFFzVTBGQlN5eEhRVUZNTzBGQlEwTXNXVUZCVDJsRkxFdEJRVXMwUXl4UlFVRk1MRXRCUVd0Q0xFbEJRV3hDTEVkQlFYbENMRWRCUVdoRE8wRkJRMFFzVTBGQlN5eEhRVUZNTzBGQlEwTXNXVUZCVHpWRExFdEJRVXMwUXl4UlFVRk1MRXRCUVd0Q0xFbEJRV3hDTEVkQlFYbENMRWRCUVdoRE8wRkJRMFFzVTBGQlN5eEhRVUZNTzBGQlEwTXNXVUZCVHpWRExFdEJRVXMwUXl4UlFVRk1MRXRCUVd0Q0xFbEJRV3hDTEVkQlFYbENMRWRCUVdoRE8wRkJVa1k3TzBGQlYwRXNWVUZCVHpWRExFdEJRVXRxUlN4UlFVRmFPMEZCUTBFN096czdPenRSUVVkTmFVY3NUeXhIUVVGQlFTeFBPMEZCUTFJN096czdPenRKUVV0TllTeE5PMEZCUTB3c2FVSkJRVmxETEUxQlFWb3NSVUZCYjBJN1FVRkJRVHM3UVVGRGJrSXNUMEZCUzNCS0xFbEJRVXdzUjBGQldTeEZRVUZhT3p0QlFVVkJMRTFCUVVseFNpeFpRVUZaUkN4UFFVRlBiRW9zVFVGQlVDeEhRVUZuUWl4RFFVRm9RaXhIUVVGdlFrTXNWVUZCVlVzc2IwSkJRVGxDTEVkQlFYRkVUQ3hWUVVGVlNTeHZRa0ZCTDBVN1FVRkRRU3hOUVVGSkswa3NhVUpCUVdsQ00wZ3NUVUZCVFRKRUxHRkJRVTRzUTBGQmIwSTRSQ3hQUVVGUGJFb3NUVUZCTTBJc1JVRkJiVU1zUTBGQmJrTXNRMEZCY2tJc1EwRktiVUlzUTBGSmVVTTdPMEZCUlRWRU8wRkJRMEVzVDBGQlMwWXNTVUZCVEN4RFFVRlZkVVlzU1VGQlZpeERRVUZsTEVsQlFVa3hSaXhMUVVGS0xFTkJRVlU3UVVGRGJrSkZMRk5CUVUxSkxGVkJRVlZGTEdsQ1FVUkhPMEZCUlc1Q1RDeFRRVUZOY1Vvc1ZVRkJWWGhJTEUxQlFWWXNRMEZCYVVKNVNDeGpRVUZxUWl4RlFVRnBRMjVLTEZWQlFWVk5MSEZDUVVFelF5eERRVVpoTEVWQlFWWXNRMEZCWmpzN1FVRkpRVHRCUVVOQk1ra3NVMEZCVDI1SExFOUJRVkFzUTBGQlpTeFZRVUZUZFVZc1MwRkJWQ3hGUVVGblFpOUZMRU5CUVdoQ0xFVkJRVzFDTzBGQlEycERLMFVzVTBGQlRUbERMRkZCUVU0c1EwRkJaU3hKUVVGSk1VUXNVMEZCU2l4RFFVRmpMRVZCUVVOb1F5eE5RVUZOUnl4VlFVRlZiMElzYjBKQlFXcENMRVZCUVdRc1EwRkJaanRCUVVOQkxGRkJRVXQyUWl4SlFVRk1MRU5CUVZWMVJpeEpRVUZXTEVOQlFXVnBSQ3hMUVVGbU8wRkJRMEVzUjBGSVJDeEZRVWRITEVsQlNFZzdRVUZKUVRzN1FVRkZSRHM3T3pzN096czdPRUpCU1ZrN1FVRkRXQ3hQUVVGSlpTeFJRVUZSTEVWQlFWbzdPMEZCUlVFN1FVRkRRU3hSUVVGTGRrb3NTVUZCVEN4RFFVRlZhVVFzVDBGQlZpeERRVUZyUWl4VlFVRkRkVWNzUTBGQlJEdEJRVUZCTEZkQlFVOUVMRkZCUVZGQkxFMUJRVTB4U0N4TlFVRk9MRU5CUVdFeVNDeEZRVUZGZWtvc1NVRkJaaXhGUVVGeFFubEtMRVZCUVVWMlNpeEpRVUYyUWl4RlFVRTJRblZLTEVWQlFVVjRTaXhKUVVFdlFpeERRVUZtTzBGQlFVRXNTVUZCYkVJN08wRkJSVUVzVlVGQlR5eEpRVUZKZVVvc1ZVRkJTaXhEUVVGbFJpeExRVUZtTEVOQlFWQTdRVUZEUVRzN1FVRkZSRHM3T3pzN096c3lRa0ZKVXp0QlFVTlNMRTlCUVVrc1QwRkJUMGNzU1VGQlVDeExRVUZuUWl4VlFVRndRaXhGUVVGblF5eFBRVUZQUVN4TFFVRkxReXhQUVVGUFF5eFpRVUZRTEVOQlFXOUNReXhMUVVGd1FpeERRVUV3UWl4SlFVRXhRaXhGUVVGblF5eExRVUZMUXl4VFFVRk1MRVZCUVdoRExFTkJRVXdzUTBGQlVEdEJRVU5vUXl4VlFVRlBMRWxCUVVsRExFMUJRVW9zUTBGQlZ5eExRVUZMUkN4VFFVRk1MRVZCUVZnc1JVRkJOa0owUml4UlFVRTNRaXhEUVVGelF5eFJRVUYwUXl4RFFVRlFPMEZCUTBFN08wRkJSVVU3T3pzN096czdORUpCU1ZVN1FVRkRWQ3hWUVVGUExEUkNRVUUwUWl4TFFVRkxkMFlzVFVGQlRDeEZRVUZ1UXp0QlFVTkJPenRCUVVWS096czdPenM3T3pKQ1FVbFpPMEZCUTFJc1ZVRkJUME1zVVVGQlVVTXNUVUZCVWl4RFFVRmxReXhMUVVGbUxFTkJRWEZDTEVsQlFVbEtMRTFCUVVvc1EwRkJWeXhMUVVGTFJDeFRRVUZNTEVWQlFWZ3NRMEZCY2tJc1EwRkJVRHRCUVVOQk96dEJRVVZLT3pzN096czdPekpDUVVsVFRTeFJMRVZCUVZVN1FVRkRiRUlzVDBGQlNUZERMRk5CUVZNc1NVRkJTWGRETEUxQlFVb3NRMEZCVnl4TFFVRkxSQ3hUUVVGTUxFVkJRVmdzUTBGQllqdEJRVU5CVHl4TlFVRkhReXhUUVVGSUxFTkJRV0ZHTEZkQlFWY3NUVUZCZUVJc1JVRkJaME0zUXl4TlFVRm9ReXhGUVVGM1F5eFZRVUZWWjBRc1IwRkJWaXhGUVVGbE8wRkJRM1JFTEZGQlFVZEJMRWRCUVVnc1JVRkJVU3hQUVVGUFF5eFJRVUZSUXl4SFFVRlNMRU5CUVZsR0xFZEJRVm9zUTBGQlVEdEJRVU5TTEVsQlJrUTdRVUZIUVRzN096czdPMUZCUjAxd1FpeE5MRWRCUVVGQkxFMGlMQ0ptYVd4bElqb2lhVzVrWlhndWFuTWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUl2S2lwY2JpQXFJRTlpYW1WamRDQnlaWEJ5WlhObGJuUmhkR2x2YmlCdlppQjBhR1VnWTJoMWJtc2djMlZqZEdsdmJpQnZaaUJoSUUxSlJFa2dabWxzWlM1Y2JpQXFJRUJ3WVhKaGJTQjdiMkpxWldOMGZTQm1hV1ZzWkhNZ0xTQjdkSGx3WlRvZ2JuVnRZbVZ5TENCa1lYUmhPaUJoY25KaGVTd2djMmw2WlRvZ1lYSnlZWGw5WEc0Z0tpQkFjbVYwZFhKdUlIdERhSFZ1YTMxY2JpQXFMMXh1WTJ4aGMzTWdRMmgxYm1zZ2UxeHVYSFJqYjI1emRISjFZM1J2Y2lobWFXVnNaSE1wSUh0Y2JseDBYSFIwYUdsekxuUjVjR1VnUFNCbWFXVnNaSE11ZEhsd1pUdGNibHgwWEhSMGFHbHpMbVJoZEdFZ1BTQm1hV1ZzWkhNdVpHRjBZVHRjYmx4MFhIUjBhR2x6TG5OcGVtVWdQU0JiTUN3Z01Dd2dNQ3dnWm1sbGJHUnpMbVJoZEdFdWJHVnVaM1JvWFR0Y2JseDBmVnh1ZlZ4dVhHNWxlSEJ2Y25RZ2UwTm9kVzVyZlR0Y2JpOHFLbHh1SUNvZ1RVbEVTU0JtYVd4bElHWnZjbTFoZENCamIyNXpkR0Z1ZEhNc0lHbHVZMngxWkdsdVp5QnViM1JsSUMwK0lFMUpSRWtnYm5WdFltVnlJSFJ5WVc1emJHRjBhVzl1TGx4dUlDb2dRSEpsZEhWeWJpQjdRMjl1YzNSaGJuUnpmVnh1SUNvdlhHNWNiblpoY2lCRGIyNXpkR0Z1ZEhNZ1BTQjdYRzVjZEZaRlVsTkpUMDVjZEZ4MFhIUmNkRngwT2lBbk1TNDFMakluTEZ4dVhIUklSVUZFUlZKZlEwaFZUa3RmVkZsUVJTQWdYSFJjZERvZ1d6QjROR1FzSURCNE5UUXNJREI0Tmpnc0lEQjROalJkTENBdkx5Qk5kR2hrWEc1Y2RFaEZRVVJGVWw5RFNGVk9TMTlNUlU1SFZFZ2dJRngwT2lCYk1IZ3dNQ3dnTUhnd01Dd2dNSGd3TUN3Z01IZ3dObDBzSUM4dklFaGxZV1JsY2lCemFYcGxJR1p2Y2lCVFRVWmNibHgwU0VWQlJFVlNYME5JVlU1TFgwWlBVazFCVkRBZ0lDQWdPaUJiTUhnd01Dd2dNSGd3TUYwc0lDOHZJRTFwWkdrZ1ZIbHdaU0F3SUdsa1hHNWNkRWhGUVVSRlVsOURTRlZPUzE5R1QxSk5RVlF4SUNBZ0lEb2dXekI0TURBc0lEQjRNREZkTENBdkx5Qk5hV1JwSUZSNWNHVWdNU0JwWkZ4dVhIUklSVUZFUlZKZlEwaFZUa3RmUkVsV1NWTkpUMDRnSUNBNklGc3dlREF3TENBd2VEZ3dYU3dnTHk4Z1JHVm1ZWFZzZEhNZ2RHOGdNVEk0SUhScFkydHpJSEJsY2lCaVpXRjBYRzVjZEZSU1FVTkxYME5JVlU1TFgxUlpVRVZjZEZ4ME9pQmJNSGcwWkN3Z01IZzFOQ3dnTUhnM01pd2dNSGcyWWwwc0lDOHZJRTFVY21zc1hHNWNkRTFGVkVGZlJWWkZUbFJmU1VSY2RGeDBYSFE2SURCNFJrWXNYRzVjZEUxRlZFRmZWRVZZVkY5SlJGeDBYSFJjZERvZ01IZ3dNU3hjYmx4MFRVVlVRVjlEVDFCWlVrbEhTRlJmU1VSY2RGeDBPaUF3ZURBeUxGeHVYSFJOUlZSQlgxUlNRVU5MWDA1QlRVVmZTVVJjZEZ4ME9pQXdlREF6TEZ4dVhIUk5SVlJCWDBsT1UxUlNWVTFGVGxSZlRrRk5SVjlKUkNBNklEQjRNRFFzWEc1Y2RFMUZWRUZmVEZsU1NVTmZTVVJjZEZ4MFhIUTZJREI0TURVc1hHNWNkRTFGVkVGZlRVRlNTMFZTWDBsRVhIUmNkRngwT2lBd2VEQTJMRnh1WEhSTlJWUkJYME5WUlY5UVQwbE9WRngwWEhSY2REb2dNSGd3Tnl4Y2JseDBUVVZVUVY5VVJVMVFUMTlKUkZ4MFhIUmNkRG9nTUhnMU1TeGNibHgwVFVWVVFWOVRUVlJRUlY5UFJrWlRSVlJjZEZ4ME9pQXdlRFUwTEZ4dVhIUk5SVlJCWDFSSlRVVmZVMGxIVGtGVVZWSkZYMGxFWEhRNklEQjROVGdzWEc1Y2RFMUZWRUZmUzBWWlgxTkpSMDVCVkZWU1JWOUpSRngwT2lBd2VEVTVMRnh1WEhSTlJWUkJYMFZPUkY5UFJsOVVVa0ZEUzE5SlJGeDBPaUJiTUhneVJpd2dNSGd3TUYwc1hHNWNkRU5QVGxSU1QweE1SVkpmUTBoQlRrZEZYMU5VUVZSVlV6b2dNSGhDTUN3Z0x5OGdhVzVqYkhWa1pYTWdZMmhoYm01bGJDQnVkVzFpWlhJZ0tEQXBYRzVjZEZCU1QwZFNRVTFmUTBoQlRrZEZYMU5VUVZSVlUxeDBPaUF3ZUVNd0xDQXZMeUJwYm1Oc2RXUmxjeUJqYUdGdWJtVnNJRzUxYldKbGNpQW9NQ2xjYm4wN1hHNWNibVY0Y0c5eWRDQjdRMjl1YzNSaGJuUnpmVHRjYmk4cUtseHVJQ29nU0c5c1pITWdZV3hzSUdSaGRHRWdabTl5SUdFZ1hDSmpiMjUwY205c2JHVnlJR05vWVc1blpWd2lJRTFKUkVrZ1pYWmxiblJjYmlBcUlFQndZWEpoYlNCN2IySnFaV04wZlNCbWFXVnNaSE1nZTJOdmJuUnliMnhzWlhKT2RXMWlaWEk2SUdsdWRHVm5aWElzSUdOdmJuUnliMnhzWlhKV1lXeDFaVG9nYVc1MFpXZGxjbjFjYmlBcUlFQnlaWFIxY200Z2UwTnZiblJ5YjJ4c1pYSkRhR0Z1WjJWRmRtVnVkSDFjYmlBcUwxeHVZMnhoYzNNZ1EyOXVkSEp2Ykd4bGNrTm9ZVzVuWlVWMlpXNTBJSHRjYmx4MFkyOXVjM1J5ZFdOMGIzSW9abWxsYkdSektTQjdYRzVjZEZ4MGRHaHBjeTUwZVhCbElEMGdKMk52Ym5SeWIyeHNaWEluTzF4dVhIUmNkQzh2SUdSbGJIUmhJSFJwYldVZ1pHVm1ZWFZzZEhNZ2RHOGdNQzVjYmx4MFhIUjBhR2x6TG1SaGRHRWdQU0JWZEdsc2N5NXVkVzFpWlhKVWIxWmhjbWxoWW14bFRHVnVaM1JvS0RCNE1EQXBMbU52Ym1OaGRDaERiMjV6ZEdGdWRITXVRMDlPVkZKUFRFeEZVbDlEU0VGT1IwVmZVMVJCVkZWVExDQm1hV1ZzWkhNdVkyOXVkSEp2Ykd4bGNrNTFiV0psY2l3Z1ptbGxiR1J6TG1OdmJuUnliMnhzWlhKV1lXeDFaU2s3WEc1Y2RIMWNibjFjYmx4dVpYaHdiM0owSUh0RGIyNTBjbTlzYkdWeVEyaGhibWRsUlhabGJuUjlPMXh1THlvcVhHNGdLaUJQWW1wbFkzUWdjbVZ3Y21WelpXNTBZWFJwYjI0Z2IyWWdZU0J0WlhSaElHVjJaVzUwTGx4dUlDb2dRSEJoY21GdElIdHZZbXBsWTNSOUlHWnBaV3hrY3lBdElIUjVjR1VzSUdSaGRHRmNiaUFxSUVCeVpYUjFjbTRnZTAxbGRHRkZkbVZ1ZEgxY2JpQXFMMXh1WTJ4aGMzTWdUV1YwWVVWMlpXNTBJSHRjYmx4MFkyOXVjM1J5ZFdOMGIzSW9abWxsYkdSektTQjdYRzVjZEZ4MGRHaHBjeTUwZVhCbElEMGdKMjFsZEdFbk8xeHVYSFJjZEhSb2FYTXVaR0YwWVNBOUlGVjBhV3h6TG01MWJXSmxjbFJ2Vm1GeWFXRmliR1ZNWlc1bmRHZ29NSGd3TUNrN0x5OGdVM1JoY25RZ2QybDBhQ0I2WlhKdklIUnBiV1VnWkdWc2RHRmNibHgwWEhSMGFHbHpMbVJoZEdFZ1BTQjBhR2x6TG1SaGRHRXVZMjl1WTJGMEtFTnZibk4wWVc1MGN5NU5SVlJCWDBWV1JVNVVYMGxFTENCbWFXVnNaSE11WkdGMFlTazdYRzVjZEgxY2JuMWNibHh1Wlhod2IzSjBJSHROWlhSaFJYWmxiblI5TzF4dUx5b3FYRzRnS2lCWGNtRndjR1Z5SUdadmNpQnViM1JsVDI1RmRtVnVkQzl1YjNSbFQyWm1SWFpsYm5RZ2IySnFaV04wY3lCMGFHRjBJR0oxYVd4a2N5QmliM1JvSUdWMlpXNTBjeTVjYmlBcUlFQndZWEpoYlNCN2IySnFaV04wZlNCbWFXVnNaSE1nTFNCN2NHbDBZMmc2SUNkYlF6UmRKeXdnWkhWeVlYUnBiMjQ2SUNjMEp5d2dkMkZwZERvZ0p6UW5MQ0IyWld4dlkybDBlVG9nTVMweE1EQjlYRzRnS2lCQWNtVjBkWEp1SUh0T2IzUmxSWFpsYm5SOVhHNGdLaTljYm1Oc1lYTnpJRTV2ZEdWRmRtVnVkQ0I3WEc1Y2RHTnZibk4wY25WamRHOXlLR1pwWld4a2N5a2dlMXh1WEhSY2RIUm9hWE11ZEhsd1pTQmNkRngwUFNBbmJtOTBaU2M3WEc1Y2RGeDBkR2hwY3k1d2FYUmphQ0JjZEZ4MFBTQlZkR2xzY3k1MGIwRnljbUY1S0dacFpXeGtjeTV3YVhSamFDazdYRzVjZEZ4MGRHaHBjeTUzWVdsMElGeDBYSFE5SUdacFpXeGtjeTUzWVdsMElIeDhJREE3WEc1Y2RGeDBkR2hwY3k1a2RYSmhkR2x2YmlCY2REMGdabWxsYkdSekxtUjFjbUYwYVc5dU8xeHVYSFJjZEhSb2FYTXVjMlZ4ZFdWdWRHbGhiQ0E5SUdacFpXeGtjeTV6WlhGMVpXNTBhV0ZzSUh4OElHWmhiSE5sTzF4dVhIUmNkSFJvYVhNdWRtVnNiMk5wZEhrZ1hIUTlJR1pwWld4a2N5NTJaV3h2WTJsMGVTQjhmQ0ExTUR0Y2JseDBYSFIwYUdsekxtTm9ZVzV1Wld3Z1hIUTlJR1pwWld4a2N5NWphR0Z1Ym1Wc0lIeDhJREU3WEc1Y2RGeDBkR2hwY3k1eVpYQmxZWFFnWEhROUlHWnBaV3hrY3k1eVpYQmxZWFFnZkh3Z01UdGNibHgwWEhSMGFHbHpMblpsYkc5amFYUjVJRngwUFNCMGFHbHpMbU52Ym5abGNuUldaV3h2WTJsMGVTaDBhR2x6TG5abGJHOWphWFI1S1R0Y2JseDBYSFIwYUdsekxtZHlZV05sWEhSY2REMGdabWxsYkdSekxtZHlZV05sTzF4dVhIUmNkSFJvYVhNdVluVnBiR1JFWVhSaEtDazdYRzVjZEgxY2JseHVYSFF2S2lwY2JseDBJQ29nUW5WcGJHUnpJR2x1ZENCaGNuSmhlU0JtYjNJZ2RHaHBjeUJsZG1WdWRDNWNibHgwSUNvZ1FISmxkSFZ5YmlCN1RtOTBaVVYyWlc1MGZWeHVYSFFnS2k5Y2JseDBZblZwYkdSRVlYUmhLQ2tnZTF4dVhIUmNkSFJvYVhNdVpHRjBZU0E5SUZ0ZE8xeHVYRzVjZEZ4MGRtRnlJSFJwWTJ0RWRYSmhkR2x2YmlBOUlIUm9hWE11WjJWMFZHbGphMFIxY21GMGFXOXVLSFJvYVhNdVpIVnlZWFJwYjI0c0lDZHViM1JsSnlrN1hHNWNkRngwZG1GeUlISmxjM1JFZFhKaGRHbHZiaUE5SUhSb2FYTXVaMlYwVkdsamEwUjFjbUYwYVc5dUtIUm9hWE11ZDJGcGRDd2dKM0psYzNRbktUdGNibHh1WEhSY2RDOHZJRUZ3Y0d4NUlHZHlZV05sSUc1dmRHVW9jeWtnWVc1a0lITjFZblJ5WVdOMElIUnBZMnR6SUNoamRYSnlaVzUwYkhrZ01TQjBhV05ySUhCbGNpQm5jbUZqWlNCdWIzUmxLU0JtY205dElIUnBZMnRFZFhKaGRHbHZiaUJ6YnlCdVpYUWdkbUZzZFdVZ2FYTWdkR2hsSUhOaGJXVmNibHgwWEhScFppQW9kR2hwY3k1bmNtRmpaU2tnZTF4dVhIUmNkRngwYkdWMElHZHlZV05sUkhWeVlYUnBiMjRnUFNBeE8xeHVYSFJjZEZ4MGRHaHBjeTVuY21GalpTQTlJRlYwYVd4ekxuUnZRWEp5WVhrb2RHaHBjeTVuY21GalpTazdYRzVjZEZ4MFhIUjBhR2x6TG1keVlXTmxMbVp2Y2tWaFkyZ29ablZ1WTNScGIyNG9jR2wwWTJncElIdGNibHgwWEhSY2RGeDBiR1YwSUc1dmRHVkZkbVZ1ZENBOUlHNWxkeUJPYjNSbFJYWmxiblFvZTNCcGRHTm9PblJvYVhNdVozSmhZMlVzSUdSMWNtRjBhVzl1T2lkVUp5QXJJR2R5WVdObFJIVnlZWFJwYjI1OUtUdGNibHgwWEhSY2RGeDBkR2hwY3k1a1lYUmhJRDBnZEdocGN5NWtZWFJoTG1OdmJtTmhkQ2h1YjNSbFJYWmxiblF1WkdGMFlTbGNibHh1WEhSY2RGeDBYSFIwYVdOclJIVnlZWFJwYjI0Z0xUMGdaM0poWTJWRWRYSmhkR2x2Ymp0Y2JseDBYSFJjZEgwc0lIUm9hWE1wTzF4dVhIUmNkSDFjYmx4dVhIUmNkQzh2SUdacFpXeGtjeTV3YVhSamFDQmpiM1ZzWkNCaVpTQmhiaUJoY25KaGVTQnZaaUJ3YVhSamFHVnpMbHh1WEhSY2RDOHZJRWxtSUhOdklHTnlaV0YwWlNCdWIzUmxJR1YyWlc1MGN5Qm1iM0lnWldGamFDQmhibVFnWVhCd2JIa2dkR2hsSUhOaGJXVWdaSFZ5WVhScGIyNHVYRzVjZEZ4MGRtRnlJRzV2ZEdWUGJpd2dibTkwWlU5bVpqdGNibHgwWEhScFppQW9RWEp5WVhrdWFYTkJjbkpoZVNoMGFHbHpMbkJwZEdOb0tTa2dlMXh1WEhSY2RGeDBMeThnUW5rZ1pHVm1ZWFZzZENCMGFHbHpJR2x6SUdFZ1kyaHZjbVFnYVdZZ2FYUW5jeUJoYmlCaGNuSmhlU0J2WmlCdWIzUmxjeUIwYUdGMElISmxjWFZwY21WeklHOXVaU0JPYjNSbFQyNUZkbVZ1ZEM1Y2JseDBYSFJjZEM4dklFbG1JSFJvYVhNdWMyVnhkV1Z1ZEdsaGJDQTlQVDBnZEhKMVpTQjBhR1Z1SUdsMEozTWdZU0J6WlhGMVpXNTBhV0ZzSUhOMGNtbHVaeUJ2WmlCdWIzUmxjeUIwYUdGMElISmxjWFZwY21WeklITmxjR0Z5WVhSbElFNXZkR1ZQYmtWMlpXNTBjeTVjYmx4MFhIUmNkR2xtSUNnZ0lTQjBhR2x6TG5ObGNYVmxiblJwWVd3cElIdGNibHgwWEhSY2RGeDBMeThnU0dGdVpHeGxJSEpsY0dWaGRGeHVYSFJjZEZ4MFhIUm1iM0lnS0haaGNpQnFJRDBnTURzZ2FpQThJSFJvYVhNdWNtVndaV0YwT3lCcUt5c3BJSHRjYmx4MFhIUmNkRngwWEhRdkx5Qk9iM1JsSUc5dVhHNWNkRngwWEhSY2RGeDBkR2hwY3k1d2FYUmphQzVtYjNKRllXTm9LR1oxYm1OMGFXOXVLSEFzSUdrcElIdGNibHgwWEhSY2RGeDBYSFJjZEdsbUlDaHBJRDA5SURBcElIdGNibHgwWEhSY2RGeDBYSFJjZEZ4MGJtOTBaVTl1SUQwZ2JtVjNJRTV2ZEdWUGJrVjJaVzUwS0h0a1lYUmhPaUJWZEdsc2N5NXVkVzFpWlhKVWIxWmhjbWxoWW14bFRHVnVaM1JvS0hKbGMzUkVkWEpoZEdsdmJpa3VZMjl1WTJGMEtIUm9hWE11WjJWMFRtOTBaVTl1VTNSaGRIVnpLQ2tzSUZWMGFXeHpMbWRsZEZCcGRHTm9LSEFwTENCMGFHbHpMblpsYkc5amFYUjVLWDBwTzF4dVhHNWNkRngwWEhSY2RGeDBYSFI5SUdWc2MyVWdlMXh1WEhSY2RGeDBYSFJjZEZ4MFhIUXZMeUJTZFc1dWFXNW5JSE4wWVhSMWN5QW9ZMkZ1SUc5dGJXbDBJSFJvWlNCdWIzUmxJRzl1SUhOMFlYUjFjeWxjYmx4MFhIUmNkRngwWEhSY2RGeDBibTkwWlU5dUlEMGdibVYzSUU1dmRHVlBia1YyWlc1MEtIdGtZWFJoT2lCYk1Dd2dWWFJwYkhNdVoyVjBVR2wwWTJnb2NDa3NJSFJvYVhNdWRtVnNiMk5wZEhsZGZTazdYRzVjZEZ4MFhIUmNkRngwWEhSOVhHNWNibHgwWEhSY2RGeDBYSFJjZEhSb2FYTXVaR0YwWVNBOUlIUm9hWE11WkdGMFlTNWpiMjVqWVhRb2JtOTBaVTl1TG1SaGRHRXBPMXh1WEhSY2RGeDBYSFJjZEgwc0lIUm9hWE1wTzF4dVhHNWNkRngwWEhSY2RGeDBMeThnVG05MFpTQnZabVpjYmx4MFhIUmNkRngwWEhSMGFHbHpMbkJwZEdOb0xtWnZja1ZoWTJnb1puVnVZM1JwYjI0b2NDd2dhU2tnZTF4dVhIUmNkRngwWEhSY2RGeDBhV1lnS0drZ1BUMGdNQ2tnZTF4dVhIUmNkRngwWEhSY2RGeDBYSFJ1YjNSbFQyWm1JRDBnYm1WM0lFNXZkR1ZQWm1aRmRtVnVkQ2g3WkdGMFlUb2dWWFJwYkhNdWJuVnRZbVZ5Vkc5V1lYSnBZV0pzWlV4bGJtZDBhQ2gwYVdOclJIVnlZWFJwYjI0cExtTnZibU5oZENoMGFHbHpMbWRsZEU1dmRHVlBabVpUZEdGMGRYTW9LU3dnVlhScGJITXVaMlYwVUdsMFkyZ29jQ2tzSUhSb2FYTXVkbVZzYjJOcGRIa3BmU2s3WEc1Y2JseDBYSFJjZEZ4MFhIUmNkSDBnWld4elpTQjdYRzVjZEZ4MFhIUmNkRngwWEhSY2RDOHZJRkoxYm01cGJtY2djM1JoZEhWeklDaGpZVzRnYjIxdGFYUWdkR2hsSUc1dmRHVWdiMlptSUhOMFlYUjFjeWxjYmx4MFhIUmNkRngwWEhSY2RGeDBibTkwWlU5bVppQTlJRzVsZHlCT2IzUmxUMlptUlhabGJuUW9lMlJoZEdFNklGc3dMQ0JWZEdsc2N5NW5aWFJRYVhSamFDaHdLU3dnZEdocGN5NTJaV3h2WTJsMGVWMTlLVHRjYmx4MFhIUmNkRngwWEhSY2RIMWNibHh1WEhSY2RGeDBYSFJjZEZ4MGRHaHBjeTVrWVhSaElEMGdkR2hwY3k1a1lYUmhMbU52Ym1OaGRDaHViM1JsVDJabUxtUmhkR0VwTzF4dVhIUmNkRngwWEhSY2RIMHNJSFJvYVhNcE8xeHVYSFJjZEZ4MFhIUjlYRzVjYmx4MFhIUmNkSDBnWld4elpTQjdYRzVjZEZ4MFhIUmNkQzh2SUVoaGJtUnNaU0J5WlhCbFlYUmNibHgwWEhSY2RGeDBabTl5SUNoMllYSWdhaUE5SURBN0lHb2dQQ0IwYUdsekxuSmxjR1ZoZERzZ2Fpc3JLU0I3WEc1Y2RGeDBYSFJjZEZ4MGRHaHBjeTV3YVhSamFDNW1iM0pGWVdOb0tHWjFibU4wYVc5dUtIQXNJR2twSUh0Y2JseDBYSFJjZEZ4MFhIUmNkQzh2SUhKbGMzUkVkWEpoZEdsdmJpQnZibXg1SUdGd2NHeHBaWE1nZEc4Z1ptbHljM1FnYm05MFpWeHVYSFJjZEZ4MFhIUmNkRngwYVdZZ0tHa2dQaUF3S1NCN1hHNWNkRngwWEhSY2RGeDBYSFJjZEhKbGMzUkVkWEpoZEdsdmJpQTlJREE3WEc1Y2RGeDBYSFJjZEZ4MFhIUjlYRzVjYmx4MFhIUmNkRngwWEhSY2RDOHZJRWxtSUdSMWNtRjBhVzl1SUdseklEaDBhQ0IwY21sd2JHVjBjeUIzWlNCdVpXVmtJSFJ2SUcxaGEyVWdjM1Z5WlNCMGFHRjBJSFJvWlNCMGIzUmhiQ0IwYVdOcmN5QTlQU0J4ZFdGeWRHVnlJRzV2ZEdVdVhHNWNkRngwWEhSY2RGeDBYSFF2THlCVGJ5d2dkR2hsSUd4aGMzUWdiMjVsSUhkcGJHd2dibVZsWkNCMGJ5QmlaU0IwYUdVZ2NtVnRZV2x1WkdWeVhHNWNkRngwWEhSY2RGeDBYSFJwWmlBb2RHaHBjeTVrZFhKaGRHbHZiaUE5UFQwZ0p6aDBKeUFtSmlCcElEMDlJSFJvYVhNdWNHbDBZMmd1YkdWdVozUm9JQzBnTVNrZ2UxeHVYSFJjZEZ4MFhIUmNkRngwWEhSc1pYUWdjWFZoY25SbGNsUnBZMnR6SUQwZ1ZYUnBiSE11Ym5WdFltVnlSbkp2YlVKNWRHVnpLRU52Ym5OMFlXNTBjeTVJUlVGRVJWSmZRMGhWVGt0ZlJFbFdTVk5KVDA0cE8xeHVYSFJjZEZ4MFhIUmNkRngwWEhSMGFXTnJSSFZ5WVhScGIyNGdQU0J4ZFdGeWRHVnlWR2xqYTNNZ0xTQW9kR2xqYTBSMWNtRjBhVzl1SUNvZ01pazdYRzVjZEZ4MFhIUmNkRngwWEhSOVhHNWNibHgwWEhSY2RGeDBYSFJjZEc1dmRHVlBiaUE5SUc1bGR5Qk9iM1JsVDI1RmRtVnVkQ2g3WkdGMFlUb2dWWFJwYkhNdWJuVnRZbVZ5Vkc5V1lYSnBZV0pzWlV4bGJtZDBhQ2h5WlhOMFJIVnlZWFJwYjI0cExtTnZibU5oZENoYmRHaHBjeTVuWlhST2IzUmxUMjVUZEdGMGRYTW9LU3dnVlhScGJITXVaMlYwVUdsMFkyZ29jQ2tzSUhSb2FYTXVkbVZzYjJOcGRIbGRLWDBwTzF4dVhIUmNkRngwWEhSY2RGeDBibTkwWlU5bVppQTlJRzVsZHlCT2IzUmxUMlptUlhabGJuUW9lMlJoZEdFNklGVjBhV3h6TG01MWJXSmxjbFJ2Vm1GeWFXRmliR1ZNWlc1bmRHZ29kR2xqYTBSMWNtRjBhVzl1S1M1amIyNWpZWFFvVzNSb2FYTXVaMlYwVG05MFpVOW1abE4wWVhSMWN5Z3BMQ0JWZEdsc2N5NW5aWFJRYVhSamFDaHdLU3dnZEdocGN5NTJaV3h2WTJsMGVWMHBmU2s3WEc1Y2JseDBYSFJjZEZ4MFhIUmNkSFJvYVhNdVpHRjBZU0E5SUhSb2FYTXVaR0YwWVM1amIyNWpZWFFvYm05MFpVOXVMbVJoZEdFc0lHNXZkR1ZQWm1ZdVpHRjBZU2s3WEc1Y2RGeDBYSFJjZEZ4MGZTd2dkR2hwY3lrN1hHNWNkRngwWEhSY2RIMWNibHgwWEhSY2RIMWNibHh1WEhSY2RGeDBjbVYwZFhKdUlIUm9hWE03WEc1Y2RGeDBmVnh1WEc1Y2RGeDBkR2h5YjNjZ0ozQnBkR05vSUcxMWMzUWdZbVVnWVc0Z1lYSnlZWGt1Snp0Y2JseDBmVHRjYmx4dVhIUXZLaXBjYmx4MElDb2dRMjl1ZG1WeWRITWdkbVZzYjJOcGRIa2dkRzhnZG1Gc2RXVWdNQzB4TWpkY2JseDBJQ29nUUhCaGNtRnRJSHR1ZFcxaVpYSjlJSFpsYkc5amFYUjVJQzBnVm1Wc2IyTnBkSGtnZG1Gc2RXVWdNUzB4TURCY2JseDBJQ29nUUhKbGRIVnliaUI3Ym5WdFltVnlmVnh1WEhRZ0tpOWNibHgwWTI5dWRtVnlkRlpsYkc5amFYUjVLSFpsYkc5amFYUjVLU0I3WEc1Y2RGeDBMeThnVFdGNElIQmhjM05sWkNCMllXeDFaU0JzYVcxcGRHVmtJSFJ2SURFd01GeHVYSFJjZEhabGJHOWphWFI1SUQwZ2RtVnNiMk5wZEhrZ1BpQXhNREFnUHlBeE1EQWdPaUIyWld4dlkybDBlVHRjYmx4MFhIUnlaWFIxY200Z1RXRjBhQzV5YjNWdVpDaDJaV3h2WTJsMGVTQXZJREV3TUNBcUlERXlOeWs3WEc1Y2RIMDdYRzVjYmx4MEx5b3FYRzVjZENBcUlFZGxkSE1nZEdobElIUnZkR0ZzSUc1MWJXSmxjaUJ2WmlCMGFXTnJjeUJpWVhObFpDQnZiaUJ3WVhOelpXUWdaSFZ5WVhScGIyNHVYRzVjZENBcUlFNXZkR1U2SUhSNWNHVTlQU2R1YjNSbEp5QmtaV1poZFd4MGN5QjBieUJ4ZFdGeWRHVnlJRzV2ZEdVc0lIUjVjR1U5UFQwbmNtVnpkQ2NnWkdWbVlYVnNkSE1nZEc4Z01GeHVYSFFnS2lCQWNHRnlZVzBnZXloemRISnBibWQ4WVhKeVlYa3BmU0JrZFhKaGRHbHZibHh1WEhRZ0tpQkFjR0Z5WVcwZ2UzTjBjbWx1WjMwZ2RIbHdaU0JiSjI1dmRHVW5MQ0FuY21WemRDZGRYRzVjZENBcUlFQnlaWFIxY200Z2UyNTFiV0psY24xY2JseDBJQ292WEc1Y2RHZGxkRlJwWTJ0RWRYSmhkR2x2Ymloa2RYSmhkR2x2Yml3Z2RIbHdaU2tnZTF4dVhIUmNkR2xtSUNoQmNuSmhlUzVwYzBGeWNtRjVLR1IxY21GMGFXOXVLU2tnZTF4dVhIUmNkRngwTHk4Z1VtVmpkWEp6YVhabGJIa2daWGhsWTNWMFpTQjBhR2x6SUcxbGRHaHZaQ0JtYjNJZ1pXRmphQ0JwZEdWdElHbHVJSFJvWlNCaGNuSmhlU0JoYm1RZ2NtVjBkWEp1SUhSb1pTQnpkVzBnYjJZZ2RHbGpheUJrZFhKaGRHbHZibk11WEc1Y2RGeDBYSFJ5WlhSMWNtNGdaSFZ5WVhScGIyNHViV0Z3S0daMWJtTjBhVzl1S0haaGJIVmxLU0I3WEc1Y2RGeDBYSFJjZEhKbGRIVnliaUIwYUdsekxtZGxkRlJwWTJ0RWRYSmhkR2x2YmloMllXeDFaU3dnZEhsd1pTazdYRzVjZEZ4MFhIUjlMQ0IwYUdsektTNXlaV1IxWTJVb1puVnVZM1JwYjI0b1lTd2dZaWtnZTF4dVhIUmNkRngwWEhSeVpYUjFjbTRnWVNBcklHSTdYRzVjZEZ4MFhIUjlMQ0F3S1R0Y2JseDBYSFI5WEc1Y2JseDBYSFJrZFhKaGRHbHZiaUE5SUdSMWNtRjBhVzl1TG5SdlUzUnlhVzVuS0NrN1hHNWNibHgwWEhScFppQW9aSFZ5WVhScGIyNHVkRzlNYjNkbGNrTmhjMlVvS1M1amFHRnlRWFFvTUNrZ1BUMDlJQ2QwSnlrZ2UxeHVYSFJjZEZ4MEx5OGdTV1lnWkhWeVlYUnBiMjRnYzNSaGNuUnpJSGRwZEdnZ0ozUW5JSFJvWlc0Z2RHaGxJRzUxYldKbGNpQjBhR0YwSUdadmJHeHZkM01nYVhNZ1lXNGdaWGh3YkdsamFYUWdkR2xqYXlCamIzVnVkRnh1WEhSY2RGeDBjbVYwZFhKdUlIQmhjbk5sU1c1MEtHUjFjbUYwYVc5dUxuTjFZbk4wY21sdVp5Z3hLU2s3WEc1Y2RGeDBmVnh1WEc1Y2RGeDBMeThnVG1WbFpDQjBieUJoY0hCc2VTQmtkWEpoZEdsdmJpQm9aWEpsTGlBZ1VYVmhjblJsY2lCdWIzUmxJRDA5SUVOdmJuTjBZVzUwY3k1SVJVRkVSVkpmUTBoVlRrdGZSRWxXU1ZOSlQwNWNibHgwWEhRdkx5QlNiM1Z1WkdsdVp5QnZibXg1SUdGd2NHeHBaWE1nZEc4Z2RISnBjR3hsZEhNc0lIZG9hV05vSUhSb1pTQnlaVzFoYVc1a1pYSWdhWE1nYUdGdVpHeGxaQ0JpWld4dmQxeHVYSFJjZEhaaGNpQnhkV0Z5ZEdWeVZHbGphM01nUFNCVmRHbHNjeTV1ZFcxaVpYSkdjbTl0UW5sMFpYTW9RMjl1YzNSaGJuUnpMa2hGUVVSRlVsOURTRlZPUzE5RVNWWkpVMGxQVGlrN1hHNWNkRngwY21WMGRYSnVJRTFoZEdndWNtOTFibVFvY1hWaGNuUmxjbFJwWTJ0eklDb2dkR2hwY3k1blpYUkVkWEpoZEdsdmJrMTFiSFJwY0d4cFpYSW9aSFZ5WVhScGIyNHNJSFI1Y0dVcEtUdGNibHgwZlZ4dVhHNWNkQzhxS2x4dVhIUWdLaUJIWlhSeklIZG9ZWFFnZEc4Z2JYVnNkR2x3YkdVZ2RHbGphM012Y1hWaGNuUmxjaUJ1YjNSbElHSjVJSFJ2SUdkbGRDQjBhR1VnYzNCbFkybG1hV1ZrSUdSMWNtRjBhVzl1TGx4dVhIUWdLaUJPYjNSbE9pQjBlWEJsUFQwbmJtOTBaU2NnWkdWbVlYVnNkSE1nZEc4Z2NYVmhjblJsY2lCdWIzUmxMQ0IwZVhCbFBUMDlKM0psYzNRbklHUmxabUYxYkhSeklIUnZJREJjYmx4MElDb2dRSEJoY21GdElIdHpkSEpwYm1kOUlHUjFjbUYwYVc5dVhHNWNkQ0FxSUVCd1lYSmhiU0I3YzNSeWFXNW5mU0IwZVhCbElGc25ibTkwWlNjc0ozSmxjM1FuWFZ4dVhIUWdLaUJBY21WMGRYSnVJSHR1ZFcxaVpYSjlYRzVjZENBcUwxeHVYSFJuWlhSRWRYSmhkR2x2YmsxMWJIUnBjR3hwWlhJb1pIVnlZWFJwYjI0c0lIUjVjR1VwSUh0Y2JseDBYSFF2THlCT1pXVmtJSFJ2SUdGd2NHeDVJR1IxY21GMGFXOXVJR2hsY21VdUlDQlJkV0Z5ZEdWeUlHNXZkR1VnUFQwZ1EyOXVjM1JoYm5SekxraEZRVVJGVWw5RFNGVk9TMTlFU1ZaSlUwbFBUbHh1WEhSY2RITjNhWFJqYUNBb1pIVnlZWFJwYjI0cElIdGNibHgwWEhSY2RHTmhjMlVnSnpBbk9seHVYSFJjZEZ4MFhIUnlaWFIxY200Z01EdGNibHgwWEhSY2RHTmhjMlVnSnpFbk9seHVYSFJjZEZ4MFhIUnlaWFIxY200Z05EdGNibHgwWEhSY2RHTmhjMlVnSnpJbk9seHVYSFJjZEZ4MFhIUnlaWFIxY200Z01qdGNibHgwWEhSY2RHTmhjMlVnSjJReUp6cGNibHgwWEhSY2RGeDBjbVYwZFhKdUlETTdYRzVjZEZ4MFhIUmpZWE5sSUNjMEp6cGNibHgwWEhSY2RGeDBjbVYwZFhKdUlERTdYRzVjZEZ4MFhIUmpZWE5sSUNjMGRDYzZYRzVjZEZ4MFhIUmNkSEpsZEhWeWJpQXdMalkyTmp0Y2JseDBYSFJjZEdOaGMyVWdKMlEwSnpwY2JseDBYSFJjZEZ4MGNtVjBkWEp1SURFdU5UdGNibHgwWEhSY2RHTmhjMlVnSnpnbk9seHVYSFJjZEZ4MFhIUnlaWFIxY200Z01DNDFPMXh1WEhSY2RGeDBZMkZ6WlNBbk9IUW5PbHh1WEhSY2RGeDBYSFF2THlCR2IzSWdPSFJvSUhSeWFYQnNaWFJ6TENCc1pYUW5jeUJrYVhacFpHVWdZU0J4ZFdGeWRHVnlJR0o1SURNc0lISnZkVzVrSUhSdklIUm9aU0J1WldGeVpYTjBJR2x1ZEN3Z1lXNWtJSE4xWW5OMGNtRmpkQ0IwYUdVZ2NtVnRZV2x1WkdWeUlIUnZJSFJvWlNCc1lYTjBJRzl1WlM1Y2JseDBYSFJjZEZ4MGNtVjBkWEp1SURBdU16TTdYRzVjZEZ4MFhIUmpZWE5sSUNka09DYzZYRzVjZEZ4MFhIUmNkSEpsZEhWeWJpQXdMamMxTzF4dVhIUmNkRngwWTJGelpTQW5NVFluT2x4dVhIUmNkRngwWEhSeVpYUjFjbTRnTUM0eU5UdGNibHgwWEhSY2RHTmhjMlVnSnpFMmRDYzZYRzVjZEZ4MFhIUmNkSEpsZEhWeWJpQXdMakUyTmp0Y2JseDBYSFJjZEdOaGMyVWdKek15SnpwY2JseDBYSFJjZEZ4MGNtVjBkWEp1SURBdU1USTFPMXh1WEhSY2RGeDBZMkZ6WlNBbk5qUW5PbHh1WEhSY2RGeDBYSFJ5WlhSMWNtNGdNQzR3TmpJMU8xeHVYSFJjZEZ4MFpHVm1ZWFZzZERwY2JseDBYSFJjZEZ4MEx5OGdUbTkwWlhNZ1pHVm1ZWFZzZENCMGJ5QmhJSEYxWVhKMFpYSXNJSEpsYzNSeklHUmxabUYxYkhRZ2RHOGdNRnh1WEhSY2RGeDBYSFF2TDNKbGRIVnliaUIwZVhCbElEMDlQU0FuYm05MFpTY2dQeUF4SURvZ01EdGNibHgwWEhSOVhHNWNibHgwWEhSMGFISnZkeUJrZFhKaGRHbHZiaUFySUNjZ2FYTWdibTkwSUdFZ2RtRnNhV1FnWkhWeVlYUnBiMjR1Snp0Y2JseDBmVHRjYmx4dVhIUXZLaXBjYmx4MElDb2dSMlYwY3lCMGFHVWdibTkwWlNCdmJpQnpkR0YwZFhNZ1kyOWtaU0JpWVhObFpDQnZiaUIwYUdVZ2MyVnNaV04wWldRZ1kyaGhibTVsYkM0Z01IZzVlekF0Um4xY2JseDBJQ29nVG05MFpTQnZiaUJoZENCamFHRnVibVZzSURBZ2FYTWdNSGc1TUNBb01UUTBLVnh1WEhRZ0tpQXdJRDBnUTJnZ01WeHVYSFFnS2lCQWNtVjBkWEp1SUh0dWRXMWlaWEo5WEc1Y2RDQXFMMXh1WEhSblpYUk9iM1JsVDI1VGRHRjBkWE1vS1NCN2NtVjBkWEp1SURFME5DQXJJSFJvYVhNdVkyaGhibTVsYkNBdElERjlYRzVjYmx4MEx5b3FYRzVjZENBcUlFZGxkSE1nZEdobElHNXZkR1VnYjJabUlITjBZWFIxY3lCamIyUmxJR0poYzJWa0lHOXVJSFJvWlNCelpXeGxZM1JsWkNCamFHRnVibVZzTGlBd2VEaDdNQzFHZlZ4dVhIUWdLaUJPYjNSbElHOW1aaUJoZENCamFHRnVibVZzSURBZ2FYTWdNSGc0TUNBb01USTRLVnh1WEhRZ0tpQXdJRDBnUTJnZ01WeHVYSFFnS2lCQWNtVjBkWEp1SUh0dWRXMWlaWEo5WEc1Y2RDQXFMMXh1WEhSblpYUk9iM1JsVDJabVUzUmhkSFZ6S0NrZ2UzSmxkSFZ5YmlBeE1qZ2dLeUIwYUdsekxtTm9ZVzV1Wld3Z0xTQXhmVnh1ZlZ4dVhHNWxlSEJ2Y25RZ2UwNXZkR1ZGZG1WdWRIMDdYRzR2S2lwY2JpQXFJRWh2YkdSeklHRnNiQ0JrWVhSaElHWnZjaUJoSUZ3aWJtOTBaU0J2Wm1aY0lpQk5TVVJKSUdWMlpXNTBYRzRnS2lCQWNHRnlZVzBnZTI5aWFtVmpkSDBnWm1sbGJHUnpJSHRrWVhSaE9pQmJYWDFjYmlBcUlFQnlaWFIxY200Z2UwNXZkR1ZQWm1aRmRtVnVkSDFjYmlBcUwxeHVZMnhoYzNNZ1RtOTBaVTltWmtWMlpXNTBJSHRjYmx4MFkyOXVjM1J5ZFdOMGIzSW9abWxsYkdSektTQjdYRzVjZEZ4MGRHaHBjeTVrWVhSaElEMGdabWxsYkdSekxtUmhkR0U3WEc1Y2RIMWNibjFjYmx4dVpYaHdiM0owSUh0T2IzUmxUMlptUlhabGJuUjlPMXh1THlvcVhHNGdLaUJJYjJ4a2N5QmhiR3dnWkdGMFlTQm1iM0lnWVNCY0ltNXZkR1VnYjI1Y0lpQk5TVVJKSUdWMlpXNTBYRzRnS2lCQWNHRnlZVzBnZTI5aWFtVmpkSDBnWm1sbGJHUnpJSHRrWVhSaE9pQmJYWDFjYmlBcUlFQnlaWFIxY200Z2UwNXZkR1ZQYmtWMlpXNTBmVnh1SUNvdlhHNWpiR0Z6Y3lCT2IzUmxUMjVGZG1WdWRDQjdYRzVjZEdOdmJuTjBjblZqZEc5eUtHWnBaV3hrY3lrZ2UxeHVYSFJjZEhSb2FYTXVaR0YwWVNBOUlHWnBaV3hrY3k1a1lYUmhPMXh1WEhSOVhHNTlYRzVjYm1WNGNHOXlkQ0I3VG05MFpVOXVSWFpsYm5SOU8xeHVMeW9xWEc0Z0tpQkliMnhrY3lCaGJHd2daR0YwWVNCbWIzSWdZU0JjSW5CeWIyZHlZVzBnWTJoaGJtZGxYQ0lnVFVsRVNTQmxkbVZ1ZEZ4dUlDb2dRSEJoY21GdElIdHZZbXBsWTNSOUlHWnBaV3hrY3lCN2FXNXpkSEoxYldWdWREb2dhVzUwWldkbGNuMWNiaUFxSUVCeVpYUjFjbTRnZTFCeWIyZHlZVzFEYUdGdVoyVkZkbVZ1ZEgxY2JpQXFMMXh1WTJ4aGMzTWdVSEp2WjNKaGJVTm9ZVzVuWlVWMlpXNTBJSHRjYmx4MFkyOXVjM1J5ZFdOMGIzSW9abWxsYkdSektTQjdYRzVjZEZ4MGRHaHBjeTUwZVhCbElEMGdKM0J5YjJkeVlXMG5PMXh1WEhSY2RDOHZJR1JsYkhSaElIUnBiV1VnWkdWbVlYVnNkSE1nZEc4Z01DNWNibHgwWEhSMGFHbHpMbVJoZEdFZ1BTQlZkR2xzY3k1dWRXMWlaWEpVYjFaaGNtbGhZbXhsVEdWdVozUm9LREI0TURBcExtTnZibU5oZENoRGIyNXpkR0Z1ZEhNdVVGSlBSMUpCVFY5RFNFRk9SMFZmVTFSQlZGVlRMQ0JtYVdWc1pITXVhVzV6ZEhKMWJXVnVkQ2s3WEc1Y2RIMWNibjFjYmx4dVpYaHdiM0owSUh0UWNtOW5jbUZ0UTJoaGJtZGxSWFpsYm5SOU8xeHVMeW9xWEc0Z0tpQkliMnhrY3lCaGJHd2daR0YwWVNCbWIzSWdZU0IwY21GamF5NWNiaUFxSUVCd1lYSmhiU0I3YjJKcVpXTjBmU0JtYVdWc1pITWdlM1I1Y0dVNklHNTFiV0psY2l3Z1pHRjBZVG9nWVhKeVlYa3NJSE5wZW1VNklHRnljbUY1TENCbGRtVnVkSE02SUdGeWNtRjVmVnh1SUNvZ1FISmxkSFZ5YmlCN1ZISmhZMnQ5WEc0Z0tpOWNibU5zWVhOeklGUnlZV05ySUh0Y2JseDBZMjl1YzNSeWRXTjBiM0lvS1NCN1hHNWNkRngwZEdocGN5NTBlWEJsSUQwZ1EyOXVjM1JoYm5SekxsUlNRVU5MWDBOSVZVNUxYMVJaVUVVN1hHNWNkRngwZEdocGN5NWtZWFJoSUQwZ1cxMDdYRzVjZEZ4MGRHaHBjeTV6YVhwbElEMGdXMTA3WEc1Y2RGeDBkR2hwY3k1bGRtVnVkSE1nUFNCYlhUdGNibHgwZlZ4dVhHNWNkQzhxS2x4dVhIUWdLaUJCWkdSeklHRnVlU0JsZG1WdWRDQjBlWEJsSUhSdklIUm9aU0IwY21GamF5NWNibHgwSUNvZ1FIQmhjbUZ0SUhzb1RtOTBaVVYyWlc1MGZFMWxkR0ZGZG1WdWRIeFFjbTluY21GdFEyaGhibWRsUlhabGJuUXBmU0JsZG1WdWRDQXRJRVYyWlc1MElHOWlhbVZqZEM1Y2JseDBJQ29nUUhCaGNtRnRJSHRtZFc1amRHbHZibjBnYldGd1JuVnVZM1JwYjI0Z0xTQkRZV3hzWW1GamF5QjNhR2xqYUNCallXNGdZbVVnZFhObFpDQjBieUJoY0hCc2VTQnpjR1ZqYVdacFl5QndjbTl3WlhKMGFXVnpJSFJ2SUdGc2JDQmxkbVZ1ZEhNdUlGeHVYSFFnS2lCQWNtVjBkWEp1SUh0VWNtRmphMzFjYmx4MElDb3ZYRzVjZEdGa1pFVjJaVzUwS0dWMlpXNTBMQ0J0WVhCR2RXNWpkR2x2YmlrZ2UxeHVYSFJjZEdsbUlDaEJjbkpoZVM1cGMwRnljbUY1S0dWMlpXNTBLU2tnZTF4dVhIUmNkRngwWlhabGJuUXVabTl5UldGamFDaG1kVzVqZEdsdmJpaGxMQ0JwS1NCN1hHNWNkRngwWEhSY2RDOHZJRWhoYm1Sc1pTQnRZWEFnWm5WdVkzUnBiMjRnYVdZZ2NISnZkbWxrWldSY2JseDBYSFJjZEZ4MGFXWWdLSFI1Y0dWdlppQnRZWEJHZFc1amRHbHZiaUE5UFQwZ0oyWjFibU4wYVc5dUp5QW1KaUJsTG5SNWNHVWdQVDA5SUNkdWIzUmxKeWtnZTF4dVhIUmNkRngwWEhSY2RIWmhjaUJ3Y205d1pYSjBhV1Z6SUQwZ2JXRndSblZ1WTNScGIyNG9hU3dnWlNrN1hHNWNibHgwWEhSY2RGeDBYSFJwWmlBb2RIbHdaVzltSUhCeWIzQmxjblJwWlhNZ1BUMDlJQ2R2WW1wbFkzUW5LU0I3WEc1Y2RGeDBYSFJjZEZ4MFhIUm1iM0lnS0haaGNpQnFJR2x1SUhCeWIzQmxjblJwWlhNcElIdGNibHgwWEhSY2RGeDBYSFJjZEZ4MGMzZHBkR05vS0dvcElIdGNibHgwWEhSY2RGeDBYSFJjZEZ4MFhIUmpZWE5sSUNka2RYSmhkR2x2YmljNlhHNWNkRngwWEhSY2RGeDBYSFJjZEZ4MFhIUmxMbVIxY21GMGFXOXVJRDBnY0hKdmNHVnlkR2xsYzF0cVhUdGNibHgwWEhSY2RGeDBYSFJjZEZ4MFhIUmNkR0p5WldGck8xeHVYSFJjZEZ4MFhIUmNkRngwWEhSY2RHTmhjMlVnSjNObGNYVmxiblJwWVd3bk9seHVYSFJjZEZ4MFhIUmNkRngwWEhSY2RGeDBaUzV6WlhGMVpXNTBhV0ZzSUQwZ2NISnZjR1Z5ZEdsbGMxdHFYVHRjYmx4MFhIUmNkRngwWEhSY2RGeDBYSFJjZEdKeVpXRnJPMXh1WEhSY2RGeDBYSFJjZEZ4MFhIUmNkR05oYzJVZ0ozWmxiRzlqYVhSNUp6cGNibHgwWEhSY2RGeDBYSFJjZEZ4MFhIUmNkR1V1ZG1Wc2IyTnBkSGtnUFNCbExtTnZiblpsY25SV1pXeHZZMmwwZVNod2NtOXdaWEowYVdWelcycGRLVHRjYmx4MFhIUmNkRngwWEhSY2RGeDBYSFJjZEdKeVpXRnJPMXh1WEhSY2RGeDBYSFJjZEZ4MFhIUjlYRzVjZEZ4MFhIUmNkRngwWEhSOVhIUmNkRnh1WEc1Y2RGeDBYSFJjZEZ4MFhIUXZMeUJIYjNSMFlTQmlkV2xzWkNCMGFHRjBJR1JoZEdGY2JseDBYSFJjZEZ4MFhIUmNkR1V1WW5WcGJHUkVZWFJoS0NrN1hHNWNkRngwWEhSY2RGeDBmVnh1WEhSY2RGeDBYSFI5WEc1Y2JseDBYSFJjZEZ4MGRHaHBjeTVrWVhSaElEMGdkR2hwY3k1a1lYUmhMbU52Ym1OaGRDaGxMbVJoZEdFcE8xeHVYSFJjZEZ4MFhIUjBhR2x6TG5OcGVtVWdQU0JWZEdsc2N5NXVkVzFpWlhKVWIwSjVkR1Z6S0hSb2FYTXVaR0YwWVM1c1pXNW5kR2dzSURRcE95QXZMeUEwSUdKNWRHVnpJR3h2Ym1kY2JseDBYSFJjZEZ4MGRHaHBjeTVsZG1WdWRITXVjSFZ6YUNobEtUdGNibHgwWEhSY2RIMHNJSFJvYVhNcE8xeHVYRzVjZEZ4MGZTQmxiSE5sSUh0Y2JseDBYSFJjZEhSb2FYTXVaR0YwWVNBOUlIUm9hWE11WkdGMFlTNWpiMjVqWVhRb1pYWmxiblF1WkdGMFlTazdYRzVjZEZ4MFhIUjBhR2x6TG5OcGVtVWdQU0JWZEdsc2N5NXVkVzFpWlhKVWIwSjVkR1Z6S0hSb2FYTXVaR0YwWVM1c1pXNW5kR2dzSURRcE95QXZMeUEwSUdKNWRHVnpJR3h2Ym1kY2JseDBYSFJjZEhSb2FYTXVaWFpsYm5SekxuQjFjMmdvWlhabGJuUXBPMXh1WEhSY2RIMWNibHh1WEhSY2RISmxkSFZ5YmlCMGFHbHpPMXh1WEhSOVhHNWNibHgwTHlvcVhHNWNkQ0FxSUZObGRITWdkR1Z0Y0c4Z2IyWWdkR2hsSUUxSlJFa2dabWxzWlM1Y2JseDBJQ29nUUhCaGNtRnRJSHR1ZFcxaVpYSjlJR0p3YlNBdElGUmxiWEJ2SUdsdUlHSmxZWFJ6SUhCbGNpQnRhVzUxZEdVdVhHNWNkQ0FxSUVCeVpYUjFjbTRnZTFSeVlXTnJmVnh1WEhRZ0tpOWNibHgwYzJWMFZHVnRjRzhvWW5CdEtTQjdYRzVjZEZ4MGRtRnlJR1YyWlc1MElEMGdibVYzSUUxbGRHRkZkbVZ1ZENoN1pHRjBZVG9nVzBOdmJuTjBZVzUwY3k1TlJWUkJYMVJGVFZCUFgwbEVYWDBwTzF4dVhIUmNkR1YyWlc1MExtUmhkR0V1Y0hWemFDZ3dlREF6S1RzZ0x5OGdVMmw2WlZ4dVhIUmNkSFpoY2lCMFpXMXdieUE5SUUxaGRHZ3VjbTkxYm1Rb05qQXdNREF3TURBZ0x5QmljRzBwTzF4dVhIUmNkR1YyWlc1MExtUmhkR0VnUFNCbGRtVnVkQzVrWVhSaExtTnZibU5oZENoVmRHbHNjeTV1ZFcxaVpYSlViMEo1ZEdWektIUmxiWEJ2TENBektTazdJQzh2SUZSbGJYQnZMQ0F6SUdKNWRHVnpYRzVjZEZ4MGNtVjBkWEp1SUhSb2FYTXVZV1JrUlhabGJuUW9aWFpsYm5RcE8xeHVYSFI5WEc1Y2JseDBMeW9xWEc1Y2RDQXFJRk5sZEhNZ2RHbHRaU0J6YVdkdVlYUjFjbVV1WEc1Y2RDQXFJRUJ3WVhKaGJTQjdiblZ0WW1WeWZTQnVkVzFsY21GMGIzSWdMU0JVYjNBZ2JuVnRZbVZ5SUc5bUlIUm9aU0IwYVcxbElITnBaMjVoZEhWeVpTNWNibHgwSUNvZ1FIQmhjbUZ0SUh0dWRXMWlaWEo5SUdSbGJtOXRhVzVoZEc5eUlDMGdRbTkwZEc5dElHNTFiV0psY2lCdlppQjBhR1VnZEdsdFpTQnphV2R1WVhSMWNtVXVYRzVjZENBcUlFQndZWEpoYlNCN2JuVnRZbVZ5ZlNCdGFXUnBZMnh2WTJ0emNHVnlkR2xqYXlBdElFUmxabUYxYkhSeklIUnZJREkwTGx4dVhIUWdLaUJBY0dGeVlXMGdlMjUxYldKbGNuMGdibTkwWlhOd1pYSnRhV1JwWTJ4dlkyc2dMU0JFWldaaGRXeDBjeUIwYnlBNExseHVYSFFnS2lCQWNtVjBkWEp1SUh0VWNtRmphMzFjYmx4MElDb3ZYRzVjZEhObGRGUnBiV1ZUYVdkdVlYUjFjbVVvYm5WdFpYSmhkRzl5TENCa1pXNXZiV2x1WVhSdmNpd2diV2xrYVdOc2IyTnJjM0JsY25ScFkyc3NJRzV2ZEdWemNHVnliV2xrYVdOc2IyTnJLU0I3WEc1Y2RGeDBiV2xrYVdOc2IyTnJjM0JsY25ScFkyc2dQU0J0YVdScFkyeHZZMnR6Y0dWeWRHbGpheUI4ZkNBeU5EdGNibHgwWEhSdWIzUmxjM0JsY20xcFpHbGpiRzlqYXlBOUlHNXZkR1Z6Y0dWeWJXbGthV05zYjJOcklIeDhJRGc3WEc1Y2RGeDBYRzVjZEZ4MGRtRnlJR1YyWlc1MElEMGdibVYzSUUxbGRHRkZkbVZ1ZENoN1pHRjBZVG9nVzBOdmJuTjBZVzUwY3k1TlJWUkJYMVJKVFVWZlUwbEhUa0ZVVlZKRlgwbEVYWDBwTzF4dVhIUmNkR1YyWlc1MExtUmhkR0V1Y0hWemFDZ3dlREEwS1RzZ0x5OGdVMmw2WlZ4dVhIUmNkR1YyWlc1MExtUmhkR0VnUFNCbGRtVnVkQzVrWVhSaExtTnZibU5oZENoVmRHbHNjeTV1ZFcxaVpYSlViMEo1ZEdWektHNTFiV1Z5WVhSdmNpd2dNU2twT3lBdkx5Qk9kVzFsY21GMGIzSXNJREVnWW5sMFpYTmNibHgwWEhSY2JseDBYSFIyWVhJZ1gyUmxibTl0YVc1aGRHOXlJRDBnVFdGMGFDNXNiMmN5S0dSbGJtOXRhVzVoZEc5eUtUdGNkQzh2SUVSbGJtOXRhVzVoZEc5eUlHbHpJR1Y0Y0hKbGMzTmxaQ0JoY3lCd2IzY2diMllnTWx4dVhIUmNkR1YyWlc1MExtUmhkR0VnUFNCbGRtVnVkQzVrWVhSaExtTnZibU5oZENoVmRHbHNjeTV1ZFcxaVpYSlViMEo1ZEdWektGOWtaVzV2YldsdVlYUnZjaXdnTVNrcE95QXZMeUJFWlc1dmJXbHVZWFJ2Y2l3Z01TQmllWFJsYzF4dVhIUmNkR1YyWlc1MExtUmhkR0VnUFNCbGRtVnVkQzVrWVhSaExtTnZibU5oZENoVmRHbHNjeTV1ZFcxaVpYSlViMEo1ZEdWektHMXBaR2xqYkc5amEzTndaWEowYVdOckxDQXhLU2s3SUM4dklFMUpSRWtnUTJ4dlkydHpJSEJsY2lCMGFXTnJMQ0F4SUdKNWRHVnpYRzVjZEZ4MFpYWmxiblF1WkdGMFlTQTlJR1YyWlc1MExtUmhkR0V1WTI5dVkyRjBLRlYwYVd4ekxtNTFiV0psY2xSdlFubDBaWE1vYm05MFpYTndaWEp0YVdScFkyeHZZMnNzSURFcEtUc2dMeThnVG5WdFltVnlJRzltSURFdk16SWdibTkwWlhNZ2NHVnlJRTFKUkVrZ1kyeHZZMnR6TENBeElHSjVkR1Z6WEc1Y2RGeDBjbVYwZFhKdUlIUm9hWE11WVdSa1JYWmxiblFvWlhabGJuUXBPMXh1WEhSOVhHNWNibHgwTHlvcVhHNWNkQ0FxSUZObGRITWdhMlY1SUhOcFoyNWhkSFZ5WlM1Y2JseDBJQ29nUUhCaGNtRnRJSHNxZlNCelppQXRJRnh1WEhRZ0tpQkFjR0Z5WVcwZ2V5cDlJRzFwSUMxY2JseDBJQ29nUUhKbGRIVnliaUI3VkhKaFkydDlYRzVjZENBcUwxeHVYSFJ6WlhSTFpYbFRhV2R1WVhSMWNtVW9jMllzSUcxcEtTQjdYRzVjZEZ4MGRtRnlJR1YyWlc1MElEMGdibVYzSUUxbGRHRkZkbVZ1ZENoN1pHRjBZVG9nVzBOdmJuTjBZVzUwY3k1TlJWUkJYMHRGV1Y5VFNVZE9RVlJWVWtWZlNVUmRmU2s3WEc1Y2RGeDBaWFpsYm5RdVpHRjBZUzV3ZFhOb0tEQjRNRElwT3lBdkx5QlRhWHBsWEc1Y2JseDBYSFIyWVhJZ2JXOWtaU0E5SUcxcElIeDhJREE3WEc1Y2RGeDBjMllnUFNCelppQjhmQ0F3TzF4dVhHNWNkRngwTHk5Y2RFWjFibU4wYVc5dUlHTmhiR3hsWkNCM2FYUm9JSE4wY21sdVp5QnViM1JoZEdsdmJseHVYSFJjZEdsbUlDaDBlWEJsYjJZZ2JXa2dQVDA5SUNkMWJtUmxabWx1WldRbktTQjdYRzVjZEZ4MFhIUjJZWElnWm1sbWRHaHpJRDBnVzF4dVhIUmNkRngwWEhSYkowTmlKeXdnSjBkaUp5d2dKMFJpSnl3Z0owRmlKeXdnSjBWaUp5d2dKMEppSnl3Z0owWW5MQ0FuUXljc0lDZEhKeXdnSjBRbkxDQW5RU2NzSUNkRkp5d2dKMEluTENBblJpTW5MQ0FuUXlNblhTeGNibHgwWEhSY2RGeDBXeWRoWWljc0lDZGxZaWNzSUNkaVlpY3NJQ2RtSnl3Z0oyTW5MQ0FuWnljc0lDZGtKeXdnSjJFbkxDQW5aU2NzSUNkaUp5d2dKMllqSnl3Z0oyTWpKeXdnSjJjakp5d2dKMlFqSnl3Z0oyRWpKMTFjYmx4MFhIUmNkRjA3WEc1Y2RGeDBYSFIyWVhJZ1gzTm1iR1Z1SUQwZ2MyWXViR1Z1WjNSb08xeHVYSFJjZEZ4MGRtRnlJRzV2ZEdVZ1BTQnpaaUI4ZkNBblF5YzdYRzVjYmx4MFhIUmNkR2xtSUNoelpsc3dYU0E5UFQwZ2MyWmJNRjB1ZEc5TWIzZGxja05oYzJVb0tTa2diVzlrWlNBOUlERmNibHh1WEhSY2RGeDBhV1lnS0Y5elpteGxiaUErSURFcElIdGNibHgwWEhSY2RGeDBjM2RwZEdOb0lDaHpaaTVqYUdGeVFYUW9YM05tYkdWdUlDMGdNU2twSUh0Y2JseDBYSFJjZEZ4MFhIUmpZWE5sSUNkdEp6cGNibHgwWEhSY2RGeDBYSFJjZEcxdlpHVWdQU0F4TzF4dVhIUmNkRngwWEhSY2RGeDBibTkwWlNBOUlITm1MbU5vWVhKQmRDZ3dLUzUwYjB4dmQyVnlRMkZ6WlNncE8xeHVYSFJjZEZ4MFhIUmNkRngwYm05MFpTQTlJRzV2ZEdVdVkyOXVZMkYwS0hObUxuTjFZbk4wY21sdVp5Z3hMQ0JmYzJac1pXNGdMU0F4S1NrN1hHNWNkRngwWEhSY2RGeDBYSFJpY21WaGF6dGNibHgwWEhSY2RGeDBYSFJqWVhObElDY3RKenBjYmx4MFhIUmNkRngwWEhSY2RHMXZaR1VnUFNBeE8xeHVYSFJjZEZ4MFhIUmNkRngwYm05MFpTQTlJSE5tTG1Ob1lYSkJkQ2d3S1M1MGIweHZkMlZ5UTJGelpTZ3BPMXh1WEhSY2RGeDBYSFJjZEZ4MGJtOTBaU0E5SUc1dmRHVXVZMjl1WTJGMEtITm1Mbk4xWW5OMGNtbHVaeWd4TENCZmMyWnNaVzRnTFNBeEtTazdYRzVjZEZ4MFhIUmNkRngwWEhSaWNtVmhhenRjYmx4MFhIUmNkRngwWEhSallYTmxJQ2ROSnpwY2JseDBYSFJjZEZ4MFhIUmNkRzF2WkdVZ1BTQXdPMXh1WEhSY2RGeDBYSFJjZEZ4MGJtOTBaU0E5SUhObUxtTm9ZWEpCZENnd0tTNTBiMVZ3Y0dWeVEyRnpaU2dwTzF4dVhIUmNkRngwWEhSY2RGeDBibTkwWlNBOUlHNXZkR1V1WTI5dVkyRjBLSE5tTG5OMVluTjBjbWx1WnlneExDQmZjMlpzWlc0Z0xTQXhLU2s3WEc1Y2RGeDBYSFJjZEZ4MFhIUmljbVZoYXp0Y2JseDBYSFJjZEZ4MFhIUmpZWE5sSUNjckp6cGNibHgwWEhSY2RGeDBYSFJjZEcxdlpHVWdQU0F3TzF4dVhIUmNkRngwWEhSY2RGeDBibTkwWlNBOUlITm1MbU5vWVhKQmRDZ3dLUzUwYjFWd2NHVnlRMkZ6WlNncE8xeHVYSFJjZEZ4MFhIUmNkRngwYm05MFpTQTlJRzV2ZEdVdVkyOXVZMkYwS0hObUxuTjFZbk4wY21sdVp5Z3hMQ0JmYzJac1pXNGdMU0F4S1NrN1hHNWNkRngwWEhSY2RGeDBYSFJpY21WaGF6dGNibHgwWEhSY2RGeDBmVnh1WEhSY2RGeDBmVnh1WEc1Y2RGeDBYSFIyWVhJZ1ptbG1kR2hwYm1SbGVDQTlJR1pwWm5Sb2MxdHRiMlJsWFM1cGJtUmxlRTltS0c1dmRHVXBPMXh1WEhSY2RGeDBjMllnUFNCbWFXWjBhR2x1WkdWNElEMDlQU0F0TVNBL0lEQWdPaUJtYVdaMGFHbHVaR1Y0SUMwZ056dGNibHgwWEhSOVhHNWNibHgwWEhSbGRtVnVkQzVrWVhSaElEMGdaWFpsYm5RdVpHRjBZUzVqYjI1allYUW9WWFJwYkhNdWJuVnRZbVZ5Vkc5Q2VYUmxjeWh6Wml3Z01Ta3BPeUF2THlCT2RXMWlaWElnYjJZZ2MyaGhjbkFnYjNJZ1pteGhkSE1nS0NBOElEQWdabXhoZERzZ1BpQXdJSE5vWVhKd0tWeHVYSFJjZEdWMlpXNTBMbVJoZEdFZ1BTQmxkbVZ1ZEM1a1lYUmhMbU52Ym1OaGRDaFZkR2xzY3k1dWRXMWlaWEpVYjBKNWRHVnpLRzF2WkdVc0lERXBLVHNnTHk4Z1RXOWtaVG9nTUNCdFlXcHZjaXdnTVNCdGFXNXZjbHh1WEhSY2RISmxkSFZ5YmlCMGFHbHpMbUZrWkVWMlpXNTBLR1YyWlc1MEtUdGNibHgwZlZ4dVhHNWNkQzhxS2x4dVhIUWdLaUJCWkdSeklIUmxlSFFnZEc4Z1RVbEVTU0JtYVd4bExseHVYSFFnS2lCQWNHRnlZVzBnZTNOMGNtbHVaMzBnZEdWNGRDQXRJRlJsZUhRZ2RHOGdZV1JrTGx4dVhIUWdLaUJBY21WMGRYSnVJSHRVY21GamEzMWNibHgwSUNvdlhHNWNkR0ZrWkZSbGVIUW9kR1Y0ZENrZ2UxeHVYSFJjZEhaaGNpQmxkbVZ1ZENBOUlHNWxkeUJOWlhSaFJYWmxiblFvZTJSaGRHRTZJRnREYjI1emRHRnVkSE11VFVWVVFWOVVSVmhVWDBsRVhYMHBPMXh1WEhSY2RIWmhjaUJ6ZEhKcGJtZENlWFJsY3lBOUlGVjBhV3h6TG5OMGNtbHVaMVJ2UW5sMFpYTW9kR1Y0ZENrN1hHNWNkRngwWlhabGJuUXVaR0YwWVNBOUlHVjJaVzUwTG1SaGRHRXVZMjl1WTJGMEtGVjBhV3h6TG01MWJXSmxjbFJ2Vm1GeWFXRmliR1ZNWlc1bmRHZ29jM1J5YVc1blFubDBaWE11YkdWdVozUm9LU2s3SUM4dklGTnBlbVZjYmx4MFhIUmxkbVZ1ZEM1a1lYUmhJRDBnWlhabGJuUXVaR0YwWVM1amIyNWpZWFFvYzNSeWFXNW5RbmwwWlhNcE95QXZMeUJVWlhoMFhHNWNkRngwY21WMGRYSnVJSFJvYVhNdVlXUmtSWFpsYm5Rb1pYWmxiblFwTzF4dVhIUjlYRzVjYmx4MEx5b3FYRzVjZENBcUlFRmtaSE1nWTI5d2VYSnBaMmgwSUhSdklFMUpSRWtnWm1sc1pTNWNibHgwSUNvZ1FIQmhjbUZ0SUh0emRISnBibWQ5SUhSbGVIUWdMU0JVWlhoMElHOW1JR052Y0hseWFXZG9kQ0JzYVc1bExseHVYSFFnS2lCQWNtVjBkWEp1SUh0VWNtRmphMzFjYmx4MElDb3ZYRzVjZEdGa1pFTnZjSGx5YVdkb2RDaDBaWGgwS1NCN1hHNWNkRngwZG1GeUlHVjJaVzUwSUQwZ2JtVjNJRTFsZEdGRmRtVnVkQ2g3WkdGMFlUb2dXME52Ym5OMFlXNTBjeTVOUlZSQlgwTlBVRmxTU1VkSVZGOUpSRjE5S1R0Y2JseDBYSFIyWVhJZ2MzUnlhVzVuUW5sMFpYTWdQU0JWZEdsc2N5NXpkSEpwYm1kVWIwSjVkR1Z6S0hSbGVIUXBPMXh1WEhSY2RHVjJaVzUwTG1SaGRHRWdQU0JsZG1WdWRDNWtZWFJoTG1OdmJtTmhkQ2hWZEdsc2N5NXVkVzFpWlhKVWIxWmhjbWxoWW14bFRHVnVaM1JvS0hOMGNtbHVaMEo1ZEdWekxteGxibWQwYUNrcE95QXZMeUJUYVhwbFhHNWNkRngwWlhabGJuUXVaR0YwWVNBOUlHVjJaVzUwTG1SaGRHRXVZMjl1WTJGMEtITjBjbWx1WjBKNWRHVnpLVHNnTHk4Z1ZHVjRkRnh1WEhSY2RISmxkSFZ5YmlCMGFHbHpMbUZrWkVWMlpXNTBLR1YyWlc1MEtUdGNibHgwZlZ4dVhHNWNkQzhxS2x4dVhIUWdLaUJCWkdSeklGTmxjWFZsYm1ObEwxUnlZV05ySUU1aGJXVXVYRzVjZENBcUlFQndZWEpoYlNCN2MzUnlhVzVuZlNCMFpYaDBJQzBnVkdWNGRDQnZaaUIwY21GamF5QnVZVzFsTGx4dVhIUWdLaUJBY21WMGRYSnVJSHRVY21GamEzMWNibHgwSUNvdlhHNWNkR0ZrWkZSeVlXTnJUbUZ0WlNoMFpYaDBLU0I3WEc1Y2RGeDBkbUZ5SUdWMlpXNTBJRDBnYm1WM0lFMWxkR0ZGZG1WdWRDaDdaR0YwWVRvZ1cwTnZibk4wWVc1MGN5NU5SVlJCWDFSU1FVTkxYMDVCVFVWZlNVUmRmU2s3WEc1Y2RGeDBkbUZ5SUhOMGNtbHVaMEo1ZEdWeklEMGdWWFJwYkhNdWMzUnlhVzVuVkc5Q2VYUmxjeWgwWlhoMEtUdGNibHgwWEhSbGRtVnVkQzVrWVhSaElEMGdaWFpsYm5RdVpHRjBZUzVqYjI1allYUW9WWFJwYkhNdWJuVnRZbVZ5Vkc5V1lYSnBZV0pzWlV4bGJtZDBhQ2h6ZEhKcGJtZENlWFJsY3k1c1pXNW5kR2dwS1RzZ0x5OGdVMmw2WlZ4dVhIUmNkR1YyWlc1MExtUmhkR0VnUFNCbGRtVnVkQzVrWVhSaExtTnZibU5oZENoemRISnBibWRDZVhSbGN5azdJQzh2SUZSbGVIUmNibHgwWEhSeVpYUjFjbTRnZEdocGN5NWhaR1JGZG1WdWRDaGxkbVZ1ZENrN1hHNWNkSDFjYmx4dVhIUXZLaXBjYmx4MElDb2dVMlYwY3lCcGJuTjBjblZ0Wlc1MElHNWhiV1VnYjJZZ2RISmhZMnN1WEc1Y2RDQXFJRUJ3WVhKaGJTQjdjM1J5YVc1bmZTQjBaWGgwSUMwZ1RtRnRaU0J2WmlCcGJuTjBjblZ0Wlc1MExseHVYSFFnS2lCQWNtVjBkWEp1SUh0VWNtRmphMzFjYmx4MElDb3ZYRzVjZEdGa1pFbHVjM1J5ZFcxbGJuUk9ZVzFsS0hSbGVIUXBJSHRjYmx4MFhIUjJZWElnWlhabGJuUWdQU0J1WlhjZ1RXVjBZVVYyWlc1MEtIdGtZWFJoT2lCYlEyOXVjM1JoYm5SekxrMUZWRUZmU1U1VFZGSlZUVVZPVkY5T1FVMUZYMGxFWFgwcE8xeHVYSFJjZEhaaGNpQnpkSEpwYm1kQ2VYUmxjeUE5SUZWMGFXeHpMbk4wY21sdVoxUnZRbmwwWlhNb2RHVjRkQ2s3WEc1Y2RGeDBaWFpsYm5RdVpHRjBZU0E5SUdWMlpXNTBMbVJoZEdFdVkyOXVZMkYwS0ZWMGFXeHpMbTUxYldKbGNsUnZWbUZ5YVdGaWJHVk1aVzVuZEdnb2MzUnlhVzVuUW5sMFpYTXViR1Z1WjNSb0tTazdJQzh2SUZOcGVtVmNibHgwWEhSbGRtVnVkQzVrWVhSaElEMGdaWFpsYm5RdVpHRjBZUzVqYjI1allYUW9jM1J5YVc1blFubDBaWE1wT3lBdkx5QlVaWGgwWEc1Y2RGeDBjbVYwZFhKdUlIUm9hWE11WVdSa1JYWmxiblFvWlhabGJuUXBPMXh1WEhSOVhHNWNibHgwTHlvcVhHNWNkQ0FxSUVGa1pITWdiV0Z5YTJWeUlIUnZJRTFKUkVrZ1ptbHNaUzVjYmx4MElDb2dRSEJoY21GdElIdHpkSEpwYm1kOUlIUmxlSFFnTFNCTllYSnJaWElnZEdWNGRDNWNibHgwSUNvZ1FISmxkSFZ5YmlCN1ZISmhZMnQ5WEc1Y2RDQXFMMXh1WEhSaFpHUk5ZWEpyWlhJb2RHVjRkQ2tnZTF4dVhIUmNkSFpoY2lCbGRtVnVkQ0E5SUc1bGR5Qk5aWFJoUlhabGJuUW9lMlJoZEdFNklGdERiMjV6ZEdGdWRITXVUVVZVUVY5TlFWSkxSVkpmU1VSZGZTazdYRzVjZEZ4MGRtRnlJSE4wY21sdVowSjVkR1Z6SUQwZ1ZYUnBiSE11YzNSeWFXNW5WRzlDZVhSbGN5aDBaWGgwS1R0Y2JseDBYSFJsZG1WdWRDNWtZWFJoSUQwZ1pYWmxiblF1WkdGMFlTNWpiMjVqWVhRb1ZYUnBiSE11Ym5WdFltVnlWRzlXWVhKcFlXSnNaVXhsYm1kMGFDaHpkSEpwYm1kQ2VYUmxjeTVzWlc1bmRHZ3BLVHNnTHk4Z1UybDZaVnh1WEhSY2RHVjJaVzUwTG1SaGRHRWdQU0JsZG1WdWRDNWtZWFJoTG1OdmJtTmhkQ2h6ZEhKcGJtZENlWFJsY3lrN0lDOHZJRlJsZUhSY2JseDBYSFJ5WlhSMWNtNGdkR2hwY3k1aFpHUkZkbVZ1ZENobGRtVnVkQ2s3WEc1Y2RIMWNibHh1WEhRdktpcGNibHgwSUNvZ1FXUmtjeUJqZFdVZ2NHOXBiblFnZEc4Z1RVbEVTU0JtYVd4bExseHVYSFFnS2lCQWNHRnlZVzBnZTNOMGNtbHVaMzBnZEdWNGRDQXRJRlJsZUhRZ2IyWWdZM1ZsSUhCdmFXNTBMbHh1WEhRZ0tpQkFjbVYwZFhKdUlIdFVjbUZqYTMxY2JseDBJQ292WEc1Y2RHRmtaRU4xWlZCdmFXNTBLSFJsZUhRcElIdGNibHgwWEhSMllYSWdaWFpsYm5RZ1BTQnVaWGNnVFdWMFlVVjJaVzUwS0h0a1lYUmhPaUJiUTI5dWMzUmhiblJ6TGsxRlZFRmZRMVZGWDFCUFNVNVVYWDBwTzF4dVhIUmNkSFpoY2lCemRISnBibWRDZVhSbGN5QTlJRlYwYVd4ekxuTjBjbWx1WjFSdlFubDBaWE1vZEdWNGRDazdYRzVjZEZ4MFpYWmxiblF1WkdGMFlTQTlJR1YyWlc1MExtUmhkR0V1WTI5dVkyRjBLRlYwYVd4ekxtNTFiV0psY2xSdlZtRnlhV0ZpYkdWTVpXNW5kR2dvYzNSeWFXNW5RbmwwWlhNdWJHVnVaM1JvS1NrN0lDOHZJRk5wZW1WY2JseDBYSFJsZG1WdWRDNWtZWFJoSUQwZ1pYWmxiblF1WkdGMFlTNWpiMjVqWVhRb2MzUnlhVzVuUW5sMFpYTXBPeUF2THlCVVpYaDBYRzVjZEZ4MGNtVjBkWEp1SUhSb2FYTXVZV1JrUlhabGJuUW9aWFpsYm5RcE8xeHVYSFI5WEc1Y2JseDBMeW9xWEc1Y2RDQXFJRUZrWkhNZ2JIbHlhV01nZEc4Z1RVbEVTU0JtYVd4bExseHVYSFFnS2lCQWNHRnlZVzBnZTNOMGNtbHVaMzBnYkhseWFXTWdMU0JNZVhKcFl5QjBaWGgwSUhSdklHRmtaQzVjYmx4MElDb2dRSEpsZEhWeWJpQjdWSEpoWTJ0OVhHNWNkQ0FxTDF4dVhIUmhaR1JNZVhKcFl5aHNlWEpwWXlrZ2UxeHVYSFJjZEhaaGNpQmxkbVZ1ZENBOUlHNWxkeUJOWlhSaFJYWmxiblFvZTJSaGRHRTZJRnREYjI1emRHRnVkSE11VFVWVVFWOU1XVkpKUTE5SlJGMTlLVHRjYmx4MFhIUjJZWElnYzNSeWFXNW5RbmwwWlhNZ1BTQlZkR2xzY3k1emRISnBibWRVYjBKNWRHVnpLR3g1Y21saktUdGNibHgwWEhSbGRtVnVkQzVrWVhSaElEMGdaWFpsYm5RdVpHRjBZUzVqYjI1allYUW9WWFJwYkhNdWJuVnRZbVZ5Vkc5V1lYSnBZV0pzWlV4bGJtZDBhQ2h6ZEhKcGJtZENlWFJsY3k1c1pXNW5kR2dwS1RzZ0x5OGdVMmw2WlZ4dVhIUmNkR1YyWlc1MExtUmhkR0VnUFNCbGRtVnVkQzVrWVhSaExtTnZibU5oZENoemRISnBibWRDZVhSbGN5azdJQzh2SUV4NWNtbGpYRzVjZEZ4MGNtVjBkWEp1SUhSb2FYTXVZV1JrUlhabGJuUW9aWFpsYm5RcE8xeHVYSFI5WEc1Y2JseDBMeW9xWEc1Y2RDQXFJRU5vWVc1dVpXd2diVzlrWlNCdFpYTnpZV2RsYzF4dVhIUWdLaUJBY21WMGRYSnVJSHRVY21GamEzMWNibHgwSUNvdlhHNWNkSEJ2YkhsTmIyUmxUMjRvS1NCN1hHNWNkRngwZG1GeUlHVjJaVzUwSUQwZ2JtVjNJRTV2ZEdWUGJrVjJaVzUwS0h0a1lYUmhPaUJiTUhnd01Dd2dNSGhDTUN3Z01IZzNSU3dnTUhnd01GMTlLVHRjYmx4MFhIUnlaWFIxY200Z2RHaHBjeTVoWkdSRmRtVnVkQ2hsZG1WdWRDazdYRzVjZEgxY2JseHVmVnh1WEc1bGVIQnZjblFnZTFSeVlXTnJmVHRjYm1sdGNHOXlkQ0I3ZEc5TmFXUnBmU0JtY205dElDZDBiMjVoYkMxdGFXUnBKenRjYmx4dUx5b3FYRzRnS2lCVGRHRjBhV01nZFhScGJHbDBlU0JtZFc1amRHbHZibk1nZFhObFpDQjBhSEp2ZFdkb2IzVjBJSFJvWlNCc2FXSnlZWEo1TGx4dUlDb3ZYRzVqYkdGemN5QlZkR2xzY3lCN1hHNWNibHgwTHlvcVhHNWNkQ0FxSUVkbGRITWdUV2xrYVZkeWFYUmxja3BUSUhabGNuTnBiMjRnYm5WdFltVnlMbHh1WEhRZ0tpQkFjbVYwZFhKdUlIdHpkSEpwYm1kOVhHNWNkQ0FxTDF4dVhIUnpkR0YwYVdNZ2RtVnljMmx2YmlncElIdGNibHgwWEhSeVpYUjFjbTRnUTI5dWMzUmhiblJ6TGxaRlVsTkpUMDQ3WEc1Y2RIMWNibHh1WEhRdktpcGNibHgwSUNvZ1EyOXVkbVZ5ZENCaElITjBjbWx1WnlCMGJ5QmhiaUJoY25KaGVTQnZaaUJpZVhSbGMxeHVYSFFnS2lCQWNHRnlZVzBnZTNOMGNtbHVaMzBnYzNSeWFXNW5YRzVjZENBcUlFQnlaWFIxY200Z2UyRnljbUY1ZlZ4dVhIUWdLaTljYmx4MGMzUmhkR2xqSUhOMGNtbHVaMVJ2UW5sMFpYTW9jM1J5YVc1bktTQjdYRzVjZEZ4MGNtVjBkWEp1SUhOMGNtbHVaeTV6Y0d4cGRDZ25KeWt1YldGd0tHTm9ZWElnUFQ0Z1kyaGhjaTVqYUdGeVEyOWtaVUYwS0NrcFhHNWNkSDFjYmx4dVhIUXZLaXBjYmx4MElDb2dRMmhsWTJ0eklHbG1JR0Z5WjNWdFpXNTBJR2x6SUdFZ2RtRnNhV1FnYm5WdFltVnlMbHh1WEhRZ0tpQkFjR0Z5WVcwZ2V5cDlJRzRnTFNCV1lXeDFaU0IwYnlCamFHVmphMXh1WEhRZ0tpQkFjbVYwZFhKdUlIdGliMjlzWldGdWZWeHVYSFFnS2k5Y2JseDBjM1JoZEdsaklHbHpUblZ0WlhKcFl5aHVLU0I3WEc1Y2RGeDBjbVYwZFhKdUlDRnBjMDVoVGlod1lYSnpaVVpzYjJGMEtHNHBLU0FtSmlCcGMwWnBibWwwWlNodUtWeHVYSFI5WEc1Y2JseDBMeW9xWEc0Z0lDQWdJQ29nVW1WMGRYSnVjeUIwYUdVZ1kyOXljbVZqZENCTlNVUkpJRzUxYldKbGNpQm1iM0lnZEdobElITndaV05wWm1sbFpDQndhWFJqYUM1Y2JpQWdJQ0FnS2lCVmMyVnpJRlJ2Ym1Gc0lFMXBaR2tnTFNCb2RIUndjem92TDJkcGRHaDFZaTVqYjIwdlpHRnVhV2RpTDNSdmJtRnNMM1J5WldVdmJXRnpkR1Z5TDNCaFkydGhaMlZ6TDIxcFpHbGNiaUFnSUNBZ0tpQkFjR0Z5WVcwZ2V5aHpkSEpwYm1kOGJuVnRZbVZ5S1gwZ2NHbDBZMmdnTFNBblF5TTBKeUJ2Y2lCdGFXUnBJRzV2ZEdVZ1kyOWtaVnh1SUNBZ0lDQXFJRUJ5WlhSMWNtNGdlMjUxYldKbGNuMWNiaUFnSUNBZ0tpOWNiaUFnSUNBZ2MzUmhkR2xqSUdkbGRGQnBkR05vS0hCcGRHTm9LU0I3WEc0Z0lDQWdJRngwY21WMGRYSnVJSFJ2VFdsa2FTaHdhWFJqYUNrN1hHNGdJQ0FnSUgxY2JseHVYSFF2S2lwY2JseDBJQ29nVkhKaGJuTnNZWFJsY3lCdWRXMWlaWElnYjJZZ2RHbGphM01nZEc4Z1RVbEVTU0IwYVcxbGMzUmhiWEFnWm05eWJXRjBMQ0J5WlhSMWNtNXBibWNnWVc0Z1lYSnlZWGtnYjJaY2JseDBJQ29nYUdWNElITjBjbWx1WjNNZ2QybDBhQ0IwYUdVZ2RHbHRaU0IyWVd4MVpYTXVJRTFwWkdrZ2FHRnpJR0VnZG1WeWVTQndZWEowYVdOMWJHRnlJSFJwYldVZ2RHOGdaWGh3Y21WemN5QjBhVzFsTEZ4dVhIUWdLaUIwWVd0bElHRWdaMjl2WkNCc2IyOXJJR0YwSUhSb1pTQnpjR1ZqSUdKbFptOXlaU0JsZG1WeUlIUnZkV05vYVc1bklIUm9hWE1nWm5WdVkzUnBiMjR1WEc1Y2RDQXFJRlJvWVc1cmN5QjBieUJvZEhSd2N6b3ZMMmRwZEdoMVlpNWpiMjB2YzJWeVoya3Zhbk50YVdScFhHNWNkQ0FxWEc1Y2RDQXFJRUJ3WVhKaGJTQjdiblZ0WW1WeWZTQjBhV05yY3lBdElFNTFiV0psY2lCdlppQjBhV05yY3lCMGJ5QmlaU0IwY21GdWMyeGhkR1ZrWEc1Y2RDQXFJRUJ5WlhSMWNtNGdlMkZ5Y21GNWZTQXRJRUo1ZEdWeklIUm9ZWFFnWm05eWJTQjBhR1VnVFVsRVNTQjBhVzFsSUhaaGJIVmxYRzVjZENBcUwxeHVYSFJ6ZEdGMGFXTWdiblZ0WW1WeVZHOVdZWEpwWVdKc1pVeGxibWQwYUNoMGFXTnJjeWtnZTF4dVhIUWdJQ0FnZG1GeUlHSjFabVpsY2lBOUlIUnBZMnR6SUNZZ01IZzNSanRjYmx4dVhIUWdJQ0FnZDJocGJHVWdLSFJwWTJ0eklEMGdkR2xqYTNNZ1BqNGdOeWtnZTF4dVhIUWdJQ0FnSUNBZ0lHSjFabVpsY2lBOFBEMGdPRHRjYmx4MElDQWdJQ0FnSUNCaWRXWm1aWElnZkQwZ0tDaDBhV05yY3lBbUlEQjROMFlwSUh3Z01IZzRNQ2s3WEc1Y2RDQWdJQ0I5WEc1Y2JseDBJQ0FnSUhaaGNpQmlUR2x6ZENBOUlGdGRPMXh1WEhRZ0lDQWdkMmhwYkdVZ0tIUnlkV1VwSUh0Y2JseDBJQ0FnSUNBZ0lDQmlUR2x6ZEM1d2RYTm9LR0oxWm1abGNpQW1JREI0Wm1ZcE8xeHVYRzVjZENBZ0lDQWdJQ0FnYVdZZ0tHSjFabVpsY2lBbUlEQjRPREFwSUdKMVptWmxjaUErUGowZ09GeHVYSFFnSUNBZ0lDQWdJR1ZzYzJVZ2V5QmljbVZoYXpzZ2ZWeHVYSFFnSUNBZ2ZWeHVYRzVjZENBZ0lDQnlaWFIxY200Z1lreHBjM1E3WEc1Y2RIMWNibHh1WEhRdktpcGNibHgwSUNvZ1EyOTFiblJ6SUc1MWJXSmxjaUJ2WmlCaWVYUmxjeUJwYmlCemRISnBibWRjYmx4MElDb2dRSEJoY21GdElIdHpkSEpwYm1kOUlITmNibHgwSUNvZ1FISmxkSFZ5YmlCN1lYSnlZWGw5WEc1Y2RDQXFMMXh1WEhSemRHRjBhV01nYzNSeWFXNW5RbmwwWlVOdmRXNTBLSE1wSUh0Y2JseDBYSFJ5WlhSMWNtNGdaVzVqYjJSbFZWSkpLSE1wTG5Od2JHbDBLQzhsTGk1OExpOHBMbXhsYm1kMGFDQXRJREZjYmx4MGZWeHVYRzVjZEM4cUtseHVYSFFnS2lCSFpYUWdZVzRnYVc1MElHWnliMjBnWVc0Z1lYSnlZWGtnYjJZZ1lubDBaWE11WEc1Y2RDQXFJRUJ3WVhKaGJTQjdZWEp5WVhsOUlHSjVkR1Z6WEc1Y2RDQXFJRUJ5WlhSMWNtNGdlMjUxYldKbGNuMWNibHgwSUNvdlhHNWNkSE4wWVhScFl5QnVkVzFpWlhKR2NtOXRRbmwwWlhNb1lubDBaWE1wSUh0Y2JseDBYSFIyWVhJZ2FHVjRJRDBnSnljN1hHNWNkRngwZG1GeUlITjBjbWx1WjFKbGMzVnNkRHRjYmx4dVhIUmNkR0o1ZEdWekxtWnZja1ZoWTJnb1puVnVZM1JwYjI0b1lubDBaU2tnZTF4dVhIUmNkRngwYzNSeWFXNW5VbVZ6ZFd4MElEMGdZbmwwWlM1MGIxTjBjbWx1WnlneE5pazdYRzVjYmx4MFhIUmNkQzh2SUdWdWMzVnlaU0J6ZEhKcGJtY2dhWE1nTWlCamFHRnljMXh1WEhSY2RGeDBhV1lnS0hOMGNtbHVaMUpsYzNWc2RDNXNaVzVuZEdnZ1BUMGdNU2tnYzNSeWFXNW5VbVZ6ZFd4MElEMGdYQ0l3WENJZ0t5QnpkSEpwYm1kU1pYTjFiSFJjYmx4dVhIUmNkRngwYUdWNElDczlJSE4wY21sdVoxSmxjM1ZzZER0Y2JseDBYSFI5S1R0Y2JseHVYSFJjZEhKbGRIVnliaUJ3WVhKelpVbHVkQ2hvWlhnc0lERTJLVHRjYmx4MGZWeHVYRzVjZEM4cUtseHVYSFFnS2lCVVlXdGxjeUJoSUc1MWJXSmxjaUJoYm1RZ2MzQnNhWFJ6SUdsMElIVndJR2x1ZEc4Z1lXNGdZWEp5WVhrZ2IyWWdZbmwwWlhNdUlDQkRZVzRnWW1VZ2NHRmtaR1ZrSUdKNUlIQmhjM05wYm1jZ1lTQnVkVzFpWlhJZ2RHOGdZbmwwWlhOT1pXVmtaV1JjYmx4MElDb2dRSEJoY21GdElIdHVkVzFpWlhKOUlHNTFiV0psY2x4dVhIUWdLaUJBY0dGeVlXMGdlMjUxYldKbGNuMGdZbmwwWlhOT1pXVmtaV1JjYmx4MElDb2dRSEpsZEhWeWJpQjdZWEp5WVhsOUlDMGdRWEp5WVhrZ2IyWWdZbmwwWlhOY2JseDBJQ292WEc1Y2RITjBZWFJwWXlCdWRXMWlaWEpVYjBKNWRHVnpLRzUxYldKbGNpd2dZbmwwWlhOT1pXVmtaV1FwSUh0Y2JseDBYSFJpZVhSbGMwNWxaV1JsWkNBOUlHSjVkR1Z6VG1WbFpHVmtJSHg4SURFN1hHNWNibHgwWEhSMllYSWdhR1Y0VTNSeWFXNW5JRDBnYm5WdFltVnlMblJ2VTNSeWFXNW5LREUyS1R0Y2JseHVYSFJjZEdsbUlDaG9aWGhUZEhKcGJtY3ViR1Z1WjNSb0lDWWdNU2tnZXlBdkx5Qk5ZV3RsSUhOMWNtVWdhR1Y0SUhOMGNtbHVaeUJwY3lCbGRtVnVJRzUxYldKbGNpQnZaaUJqYUdGeWMxeHVYSFJjZEZ4MGFHVjRVM1J5YVc1bklEMGdKekFuSUNzZ2FHVjRVM1J5YVc1bk8xeHVYSFJjZEgxY2JseHVYSFJjZEM4dklGTndiR2wwSUdobGVDQnpkSEpwYm1jZ2FXNTBieUJoYmlCaGNuSmhlU0J2WmlCMGQyOGdZMmhoY2lCbGJHVnRaVzUwYzF4dVhIUmNkSFpoY2lCb1pYaEJjbkpoZVNBOUlHaGxlRk4wY21sdVp5NXRZWFJqYUNndkxuc3lmUzluS1R0Y2JseHVYSFJjZEM4dklFNXZkeUJ3WVhKelpTQjBhR1Z0SUc5MWRDQmhjeUJwYm5SbFoyVnljMXh1WEhSY2RHaGxlRUZ5Y21GNUlEMGdhR1Y0UVhKeVlYa3ViV0Z3S0dsMFpXMGdQVDRnY0dGeWMyVkpiblFvYVhSbGJTd2dNVFlwS1Z4dVhHNWNkRngwTHk4Z1VISmxjR1Z1WkNCbGJYQjBlU0JpZVhSbGN5QnBaaUIzWlNCa2IyNG5kQ0JvWVhabElHVnViM1ZuYUZ4dVhIUmNkR2xtSUNob1pYaEJjbkpoZVM1c1pXNW5kR2dnUENCaWVYUmxjMDVsWldSbFpDa2dlMXh1WEhSY2RGeDBkMmhwYkdVZ0tHSjVkR1Z6VG1WbFpHVmtJQzBnYUdWNFFYSnlZWGt1YkdWdVozUm9JRDRnTUNrZ2UxeHVYSFJjZEZ4MFhIUm9aWGhCY25KaGVTNTFibk5vYVdaMEtEQXBPMXh1WEhSY2RGeDBmVnh1WEhSY2RIMWNibHh1WEhSY2RISmxkSFZ5YmlCb1pYaEJjbkpoZVR0Y2JseDBmVnh1WEc1Y2RDOHFLbHgwWEc1Y2RDQXFJRU52Ym5abGNuUnpJSFpoYkhWbElIUnZJR0Z5Y21GNUlHbG1JRzVsWldSbFpDNWNibHgwSUNvZ1FIQmhjbUZ0SUh0emRISnBibWQ5SUhaaGJIVmxYRzVjZENBcUlFQnlaWFIxY200Z2UyRnljbUY1ZlZ4dVhIUWdLaTljYmx4MGMzUmhkR2xqSUhSdlFYSnlZWGtvZG1Gc2RXVXBJSHRjYmx4MFhIUnBaaUFvUVhKeVlYa3VhWE5CY25KaGVTaDJZV3gxWlNrcElISmxkSFZ5YmlCMllXeDFaVHRjYmx4MFhIUnlaWFIxY200Z1czWmhiSFZsWFR0Y2JseDBmVnh1ZlZ4dVhHNWxlSEJ2Y25RZ2UxVjBhV3h6ZlR0Y2JtTnNZWE56SUZabGVFWnNiM2NnZTF4dVhIUmNibHgwWTI5dWMzUnlkV04wYjNJb0tTQjdYRzVjZEZ4MEx5OGdZMjlrWlM0dUxseHVYSFI5WEc1Y2JseDBMeW9xWEc1Y2RDQXFJRk4xY0hCdmNuUWdabTl5SUdOdmJuWmxjblJwYm1jZ1ZtVjRSbXh2ZHlCMmIybGpaU0JwYm5SdklFMXBaR2xYY21sMFpYSktVeUIwY21GamExeHVYSFFnS2lCQWNtVjBkWEp1SUUxcFpHbFhjbWwwYVdWeUxsUnlZV05ySUc5aWFtVmpkRnh1WEhRZ0tpOWNibHgwZEhKaFkydEdjbTl0Vm05cFkyVW9kbTlwWTJVcElIdGNibHgwWEhSMllYSWdkSEpoWTJzZ1BTQnVaWGNnVkhKaFkyc29LVHRjYmx4MFhIUjJZWElnZDJGcGREdGNibHgwWEhSMllYSWdjR2wwWTJobGN5QTlJRnRkTzF4dVhHNWNkRngwZG05cFkyVXVkR2xqYTJGaWJHVnpMbVp2Y2tWaFkyZ29ablZ1WTNScGIyNG9kR2xqYTJGaWJHVXBJSHRjYmx4MFhIUmNkSEJwZEdOb1pYTWdQU0JiWFR0Y2JseHVYSFJjZEZ4MGFXWWdLSFJwWTJ0aFlteGxMbTV2ZEdWVWVYQmxJRDA5UFNBbmJpY3BJSHRjYmx4MFhIUmNkRngwZEdsamEyRmliR1V1YTJWNWN5NW1iM0pGWVdOb0tHWjFibU4wYVc5dUtHdGxlU2tnZTF4dVhIUmNkRngwWEhSY2RDOHZJR0oxYVd4a0lHRnljbUY1SUc5bUlIQnBkR05vWlhOY2JseDBYSFJjZEZ4MFhIUndhWFJqYUdWekxuQjFjMmdvZEdocGN5NWpiMjUyWlhKMFVHbDBZMmdvYTJWNUtTazdYRzVjZEZ4MFhIUmNkSDBwTzF4dVhHNWNkRngwWEhSOUlHVnNjMlVnYVdZZ0tIUnBZMnRoWW14bExtNXZkR1ZVZVhCbElEMDlQU0FuY2ljcElIdGNibHgwWEhSY2RGeDBMeThnYlc5MlpTQnZiaUIwYnlCMGFHVWdibVY0ZENCMGFXTnJZV0pzWlNCaGJtUWdkWE5sSUhSb2FYTWdjbVZ6ZENCaGN5QmhJR0IzWVdsMFlDQndjbTl3WlhKMGVTQm1iM0lnZEdobElHNWxlSFFnWlhabGJuUmNibHgwWEhSY2RGeDBkMkZwZENBOUlIUm9hWE11WTI5dWRtVnlkRVIxY21GMGFXOXVLSFJwWTJ0aFlteGxLVHRjYmx4MFhIUmNkRngwY21WMGRYSnVPMXh1WEhSY2RGeDBmVnh1WEc1Y2RGeDBYSFIwY21GamF5NWhaR1JGZG1WdWRDaHVaWGNnVG05MFpVVjJaVzUwS0h0d2FYUmphRG9nY0dsMFkyaGxjeXdnWkhWeVlYUnBiMjQ2SUhSb2FYTXVZMjl1ZG1WeWRFUjFjbUYwYVc5dUtIUnBZMnRoWW14bEtTd2dkMkZwZERvZ2QyRnBkSDBwS1R0Y2JseDBYSFJjZEZ4dVhIUmNkRngwTHk4Z2NtVnpaWFFnZDJGcGRGeHVYSFJjZEZ4MGQyRnBkQ0E5SURBN1hHNWNkRngwZlNrN1hHNWNibHgwWEhSeVpYUjFjbTRnZEhKaFkyczdYRzVjZEgxY2JseHVYRzVjZEM4cUtseHVYSFFnS2lCRGIyNTJaWEowY3lCV1pYaEdiRzkzSUhCcGRHTm9JSE41Ym5SaGVDQjBieUJOYVdScFYzSnBkR1Z5U2xNZ2MzbHVkR0Y0WEc1Y2RDQXFJRUJ3WVhKaGJTQndhWFJqYUNCemRISnBibWRjYmx4MElDb3ZYRzVjZEdOdmJuWmxjblJRYVhSamFDaHdhWFJqYUNrZ2UxeHVYSFJjZEhKbGRIVnliaUJ3YVhSamFDNXlaWEJzWVdObEtDY3ZKeXdnSnljcE8xeHVYSFI5SUZ4dVhHNWNibHgwTHlvcVhHNWNkQ0FxSUVOdmJuWmxjblJ6SUZabGVFWnNiM2NnWkhWeVlYUnBiMjRnYzNsdWRHRjRJSFJ2SUUxcFpHbFhjbWwwWlhKS1V5QnplVzUwWVhoY2JseDBJQ29nUUhCaGNtRnRJRzV2ZEdVZ2MzUnlkV04wSUdaeWIyMGdWbVY0Um14dmQxeHVYSFFnS2k5Y2JseDBZMjl1ZG1WeWRFUjFjbUYwYVc5dUtHNXZkR1VwSUh0Y2JseDBYSFJ6ZDJsMFkyZ2dLRzV2ZEdVdVpIVnlZWFJwYjI0cElIdGNibHgwWEhSY2RHTmhjMlVnSjNjbk9seHVYSFJjZEZ4MFhIUnlaWFIxY200Z0p6RW5PMXh1WEhSY2RGeDBZMkZ6WlNBbmFDYzZYRzVjZEZ4MFhIUmNkSEpsZEhWeWJpQnViM1JsTG1selJHOTBkR1ZrS0NrZ1B5QW5aREluSURvZ0p6SW5PMXh1WEhSY2RGeDBZMkZ6WlNBbmNTYzZYRzVjZEZ4MFhIUmNkSEpsZEhWeWJpQnViM1JsTG1selJHOTBkR1ZrS0NrZ1B5QW5aRFFuSURvZ0p6UW5PMXh1WEhSY2RGeDBZMkZ6WlNBbk9DYzZYRzVjZEZ4MFhIUmNkSEpsZEhWeWJpQnViM1JsTG1selJHOTBkR1ZrS0NrZ1B5QW5aRGduSURvZ0p6Z25PMXh1WEhSY2RIMWNibHh1WEhSY2RISmxkSFZ5YmlCdWIzUmxMbVIxY21GMGFXOXVPMXh1WEhSOU8xeHVmVnh1WEc1bGVIQnZjblFnZTFabGVFWnNiM2Q5TzF4dUx5b3FYRzRnS2lCUFltcGxZM1FnZEdoaGRDQndkWFJ6SUhSdloyVjBhR1Z5SUhSeVlXTnJjeUJoYm1RZ2NISnZkbWxrWlhNZ2JXVjBhRzlrY3lCbWIzSWdabWxzWlNCdmRYUndkWFF1WEc0Z0tpQkFjR0Z5WVcwZ2UyRnljbUY1ZlNCMGNtRmphM01nTFNCQmJpQmhjbkpoZVNCdlppQjdWSEpoWTJ0OUlHOWlhbVZqZEhNdVhHNGdLaUJBY21WMGRYSnVJSHRYY21sMFpYSjlYRzRnS2k5Y2JtTnNZWE56SUZkeWFYUmxjaUI3WEc1Y2RHTnZibk4wY25WamRHOXlLSFJ5WVdOcmN5a2dlMXh1WEhSY2RIUm9hWE11WkdGMFlTQTlJRnRkTzF4dVhHNWNkRngwZG1GeUlIUnlZV05yVkhsd1pTQTlJSFJ5WVdOcmN5NXNaVzVuZEdnZ1BpQXhJRDhnUTI5dWMzUmhiblJ6TGtoRlFVUkZVbDlEU0ZWT1MxOUdUMUpOUVZReElEb2dRMjl1YzNSaGJuUnpMa2hGUVVSRlVsOURTRlZPUzE5R1QxSk5RVlF3TzF4dVhIUmNkSFpoY2lCdWRXMWlaWEpQWmxSeVlXTnJjeUE5SUZWMGFXeHpMbTUxYldKbGNsUnZRbmwwWlhNb2RISmhZMnR6TG14bGJtZDBhQ3dnTWlrN0lDOHZJSFIzYnlCaWVYUmxjeUJzYjI1blhHNWNibHgwWEhRdkx5QklaV0ZrWlhJZ1kyaDFibXRjYmx4MFhIUjBhR2x6TG1SaGRHRXVjSFZ6YUNodVpYY2dRMmgxYm1zb2UxeHVYSFJjZEZ4MFhIUmNkRngwWEhSY2RIUjVjR1U2SUVOdmJuTjBZVzUwY3k1SVJVRkVSVkpmUTBoVlRrdGZWRmxRUlN4Y2JseDBYSFJjZEZ4MFhIUmNkRngwWEhSa1lYUmhPaUIwY21GamExUjVjR1V1WTI5dVkyRjBLRzUxYldKbGNrOW1WSEpoWTJ0ekxDQkRiMjV6ZEdGdWRITXVTRVZCUkVWU1gwTklWVTVMWDBSSlZrbFRTVTlPS1gwcEtUdGNibHh1WEhSY2RDOHZJRlJ5WVdOcklHTm9kVzVyYzF4dVhIUmNkSFJ5WVdOcmN5NW1iM0pGWVdOb0tHWjFibU4wYVc5dUtIUnlZV05yTENCcEtTQjdYRzVjZEZ4MFhIUjBjbUZqYXk1aFpHUkZkbVZ1ZENodVpYY2dUV1YwWVVWMlpXNTBLSHRrWVhSaE9pQkRiMjV6ZEdGdWRITXVUVVZVUVY5RlRrUmZUMFpmVkZKQlEwdGZTVVI5S1NrN1hHNWNkRngwWEhSMGFHbHpMbVJoZEdFdWNIVnphQ2gwY21GamF5azdYRzVjZEZ4MGZTd2dkR2hwY3lrN1hHNWNkSDFjYmx4dVhIUXZLaXBjYmx4MElDb2dRblZwYkdSeklIUm9aU0JtYVd4bElHbHVkRzhnWVNCVmFXNTBPRUZ5Y21GNVhHNWNkQ0FxSUVCeVpYUjFjbTRnZTFWcGJuUTRRWEp5WVhsOVhHNWNkQ0FxTDF4dVhIUmlkV2xzWkVacGJHVW9LU0I3WEc1Y2RGeDBkbUZ5SUdKMWFXeGtJRDBnVzEwN1hHNWNibHgwWEhRdkx5QkVZWFJoSUdOdmJuTnBjM1J6SUc5bUlHTm9kVzVyY3lCM2FHbGphQ0JqYjI1emFYTjBjeUJ2WmlCa1lYUmhYRzVjZEZ4MGRHaHBjeTVrWVhSaExtWnZja1ZoWTJnb0tHUXBJRDArSUdKMWFXeGtJRDBnWW5WcGJHUXVZMjl1WTJGMEtHUXVkSGx3WlN3Z1pDNXphWHBsTENCa0xtUmhkR0VwS1R0Y2JseHVYSFJjZEhKbGRIVnliaUJ1WlhjZ1ZXbHVkRGhCY25KaGVTaGlkV2xzWkNrN1hHNWNkSDFjYmx4dVhIUXZLaXBjYmx4MElDb2dRMjl1ZG1WeWRDQm1hV3hsSUdKMVptWmxjaUIwYnlCaElHSmhjMlUyTkNCemRISnBibWN1SUNCRWFXWm1aWEpsYm5RZ2JXVjBhRzlrY3lCa1pYQmxibVJwYm1jZ2IyNGdhV1lnWW5KdmQzTmxjaUJ2Y2lCdWIyUmxMbHh1WEhRZ0tpQkFjbVYwZFhKdUlIdHpkSEpwYm1kOVhHNWNkQ0FxTDF4dVhIUmlZWE5sTmpRb0tTQjdYRzVjZEZ4MGFXWWdLSFI1Y0dWdlppQmlkRzloSUQwOVBTQW5ablZ1WTNScGIyNG5LU0J5WlhSMWNtNGdZblJ2WVNoVGRISnBibWN1Wm5KdmJVTm9ZWEpEYjJSbExtRndjR3g1S0c1MWJHd3NJSFJvYVhNdVluVnBiR1JHYVd4bEtDa3BLVHRjYmx4MFhIUnlaWFIxY200Z2JtVjNJRUoxWm1abGNpaDBhR2x6TG1KMWFXeGtSbWxzWlNncEtTNTBiMU4wY21sdVp5Z25ZbUZ6WlRZMEp5azdYRzVjZEgxY2JseHVJQ0FnSUM4cUtseHVJQ0FnSUNBcUlFZGxkQ0IwYUdVZ1pHRjBZU0JWVWtrdVhHNGdJQ0FnSUNvZ1FISmxkSFZ5YmlCN2MzUnlhVzVuZlZ4dUlDQWdJQ0FxTDF4dUlDQWdJR1JoZEdGVmNta29LU0I3WEc0Z0lDQWdYSFJ5WlhSMWNtNGdKMlJoZEdFNllYVmthVzh2Yldsa2FUdGlZWE5sTmpRc0p5QXJJSFJvYVhNdVltRnpaVFkwS0NrN1hHNGdJQ0FnZlZ4dVhHNWNkQzhxS2x4dVhIUWdLaUJQZFhSd2RYUWdkRzhnYzNSa2IzVjBYRzVjZENBcUlFQnlaWFIxY200Z2UzTjBjbWx1WjMxY2JseDBJQ292WEc0Z0lDQWdjM1JrYjNWMEtDa2dlMXh1SUNBZ0lGeDBjbVYwZFhKdUlIQnliMk5sYzNNdWMzUmtiM1YwTG5keWFYUmxLRzVsZHlCQ2RXWm1aWElvZEdocGN5NWlkV2xzWkVacGJHVW9LU2twTzF4dUlDQWdJSDFjYmx4dVhIUXZLaXBjYmx4MElDb2dVMkYyWlNCMGJ5Qk5TVVJKSUdacGJHVmNibHgwSUNvZ1FIQmhjbUZ0SUh0emRISnBibWQ5SUdacGJHVnVZVzFsWEc1Y2RDQXFMMXh1WEhSellYWmxUVWxFU1NobWFXeGxibUZ0WlNrZ2UxeHVYSFJjZEhaaGNpQmlkV1ptWlhJZ1BTQnVaWGNnUW5WbVptVnlLSFJvYVhNdVluVnBiR1JHYVd4bEtDa3BPMXh1WEhSY2RHWnpMbmR5YVhSbFJtbHNaU2htYVd4bGJtRnRaU0FySUNjdWJXbGtKeXdnWW5WbVptVnlMQ0JtZFc1amRHbHZiaUFvWlhKeUtTQjdYRzVjZEZ4MFhIUnBaaWhsY25JcElISmxkSFZ5YmlCamIyNXpiMnhsTG14dlp5aGxjbklwTzF4dVhIUmNkSDBwTzF4dVhIUjlYRzU5WEc1Y2JtVjRjRzl5ZENCN1YzSnBkR1Z5ZlR0Y2JpSmRmUT09XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vbWlkaS13cml0ZXItanMvYnVpbGQvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDE0MFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCdcblxuLy8gdXRpbFxuZnVuY3Rpb24gZmlsbFN0ciAocywgbnVtKSB7IHJldHVybiBBcnJheShudW0gKyAxKS5qb2luKHMpIH1cbmZ1bmN0aW9uIGlzTnVtICh4KSB7IHJldHVybiB0eXBlb2YgeCA9PT0gJ251bWJlcicgfVxuZnVuY3Rpb24gaXNTdHIgKHgpIHsgcmV0dXJuIHR5cGVvZiB4ID09PSAnc3RyaW5nJyB9XG5mdW5jdGlvbiBpc0RlZiAoeCkgeyByZXR1cm4gdHlwZW9mIHggIT09ICd1bmRlZmluZWQnIH1cbmZ1bmN0aW9uIG1pZGlUb0ZyZXEgKG1pZGksIHR1bmluZykge1xuICByZXR1cm4gTWF0aC5wb3coMiwgKG1pZGkgLSA2OSkgLyAxMikgKiAodHVuaW5nIHx8IDQ0MClcbn1cblxudmFyIFJFR0VYID0gL14oW2EtZ0EtR10pKCN7MSx9fGJ7MSx9fHh7MSx9fCkoLT9cXGQqKVxccyooLiopXFxzKiQvXG4vKipcbiAqIEEgcmVnZXggZm9yIG1hdGNoaW5nIG5vdGUgc3RyaW5ncyBpbiBzY2llbnRpZmljIG5vdGF0aW9uLlxuICpcbiAqIEBuYW1lIHJlZ2V4XG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm4ge1JlZ0V4cH0gdGhlIHJlZ2V4cCB1c2VkIHRvIHBhcnNlIHRoZSBub3RlIG5hbWVcbiAqXG4gKiBUaGUgbm90ZSBzdHJpbmcgc2hvdWxkIGhhdmUgdGhlIGZvcm0gYGxldHRlclthY2NpZGVudGFsc11bb2N0YXZlXVtlbGVtZW50XWBcbiAqIHdoZXJlOlxuICpcbiAqIC0gbGV0dGVyOiAoUmVxdWlyZWQpIGlzIGEgbGV0dGVyIGZyb20gQSB0byBHIGVpdGhlciB1cHBlciBvciBsb3dlciBjYXNlXG4gKiAtIGFjY2lkZW50YWxzOiAoT3B0aW9uYWwpIGNhbiBiZSBvbmUgb3IgbW9yZSBgYmAgKGZsYXRzKSwgYCNgIChzaGFycHMpIG9yIGB4YCAoZG91YmxlIHNoYXJwcykuXG4gKiBUaGV5IGNhbiBOT1QgYmUgbWl4ZWQuXG4gKiAtIG9jdGF2ZTogKE9wdGlvbmFsKSBhIHBvc2l0aXZlIG9yIG5lZ2F0aXZlIGludGVnZXJcbiAqIC0gZWxlbWVudDogKE9wdGlvbmFsKSBhZGRpdGlvbmFsbHkgYW55dGhpbmcgYWZ0ZXIgdGhlIGR1cmF0aW9uIGlzIGNvbnNpZGVyZWQgdG9cbiAqIGJlIHRoZSBlbGVtZW50IG5hbWUgKGZvciBleGFtcGxlOiAnQzIgZG9yaWFuJylcbiAqXG4gKiBUaGUgZXhlY3V0ZWQgcmVnZXggY29udGFpbnMgKGJ5IGFycmF5IGluZGV4KTpcbiAqXG4gKiAtIDA6IHRoZSBjb21wbGV0ZSBzdHJpbmdcbiAqIC0gMTogdGhlIG5vdGUgbGV0dGVyXG4gKiAtIDI6IHRoZSBvcHRpb25hbCBhY2NpZGVudGFsc1xuICogLSAzOiB0aGUgb3B0aW9uYWwgb2N0YXZlXG4gKiAtIDQ6IHRoZSByZXN0IG9mIHRoZSBzdHJpbmcgKHRyaW1tZWQpXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBwYXJzZXIgPSByZXF1aXJlKCdub3RlLXBhcnNlcicpXG4gKiBwYXJzZXIucmVnZXguZXhlYygnYyM0JylcbiAqIC8vID0+IFsnYyM0JywgJ2MnLCAnIycsICc0JywgJyddXG4gKiBwYXJzZXIucmVnZXguZXhlYygnYyM0IG1ham9yJylcbiAqIC8vID0+IFsnYyM0bWFqb3InLCAnYycsICcjJywgJzQnLCAnbWFqb3InXVxuICogcGFyc2VyLnJlZ2V4KCkuZXhlYygnQ01hajcnKVxuICogLy8gPT4gWydDTWFqNycsICdDJywgJycsICcnLCAnTWFqNyddXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdleCAoKSB7IHJldHVybiBSRUdFWCB9XG5cbnZhciBTRU1JVE9ORVMgPSBbMCwgMiwgNCwgNSwgNywgOSwgMTFdXG4vKipcbiAqIFBhcnNlIGEgbm90ZSBuYW1lIGluIHNjaWVudGlmaWMgbm90YXRpb24gYW4gcmV0dXJuIGl0J3MgY29tcG9uZW50cyxcbiAqIGFuZCBzb21lIG51bWVyaWMgcHJvcGVydGllcyBpbmNsdWRpbmcgbWlkaSBudW1iZXIgYW5kIGZyZXF1ZW5jeS5cbiAqXG4gKiBAbmFtZSBwYXJzZVxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1N0cmluZ30gbm90ZSAtIHRoZSBub3RlIHN0cmluZyB0byBiZSBwYXJzZWRcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNUb25pYyAtIHRydWUgdGhlIHN0cmluZ3MgaXQncyBzdXBwb3NlZCB0byBjb250YWluIGEgbm90ZSBudW1iZXJcbiAqIGFuZCBzb21lIGNhdGVnb3J5IChmb3IgZXhhbXBsZSBhbiBzY2FsZTogJ0MjIG1ham9yJykuIEl0J3MgZmFsc2UgYnkgZGVmYXVsdCxcbiAqIGJ1dCB3aGVuIHRydWUsIGVuIGV4dHJhIHRvbmljT2YgcHJvcGVydHkgaXMgcmV0dXJuZWQgd2l0aCB0aGUgY2F0ZWdvcnkgKCdtYWpvcicpXG4gKiBAcGFyYW0ge0Zsb2F0fSB0dW5uaW5nIC0gVGhlIGZyZXF1ZW5jeSBvZiBBNCBub3RlIHRvIGNhbGN1bGF0ZSBmcmVxdWVuY2llcy5cbiAqIEJ5IGRlZmF1bHQgaXQgNDQwLlxuICogQHJldHVybiB7T2JqZWN0fSB0aGUgcGFyc2VkIG5vdGUgbmFtZSBvciBudWxsIGlmIG5vdCBhIHZhbGlkIG5vdGVcbiAqXG4gKiBUaGUgcGFyc2VkIG5vdGUgbmFtZSBvYmplY3Qgd2lsbCBBTFdBWVMgY29udGFpbnM6XG4gKiAtIGxldHRlcjogdGhlIHVwcGVyY2FzZSBsZXR0ZXIgb2YgdGhlIG5vdGVcbiAqIC0gYWNjOiB0aGUgYWNjaWRlbnRhbHMgb2YgdGhlIG5vdGUgKG9ubHkgc2hhcnBzIG9yIGZsYXRzKVxuICogLSBwYzogdGhlIHBpdGNoIGNsYXNzIChsZXR0ZXIgKyBhY2MpXG4gKiAtIHN0ZXA6IHMgYSBudW1lcmljIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBsZXR0ZXIuIEl0J3MgYW4gaW50ZWdlciBmcm9tIDAgdG8gNlxuICogd2hlcmUgMCA9IEMsIDEgPSBEIC4uLiA2ID0gQlxuICogLSBhbHQ6IGEgbnVtZXJpYyByZXByZXNlbnRhdGlvbiBvZiB0aGUgYWNjaWRlbnRhbHMuIDAgbWVhbnMgbm8gYWx0ZXJhdGlvbixcbiAqIHBvc2l0aXZlIG51bWJlcnMgYXJlIGZvciBzaGFycHMgYW5kIG5lZ2F0aXZlIGZvciBmbGF0c1xuICogLSBjaHJvbWE6IGEgbnVtZXJpYyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGl0Y2ggY2xhc3MuIEl0J3MgbGlrZSBtaWRpIGZvclxuICogcGl0Y2ggY2xhc3Nlcy4gMCA9IEMsIDEgPSBDIywgMiA9IEQgLi4uIDExID0gQi4gQ2FuIGJlIHVzZWQgdG8gZmluZCBlbmhhcm1vbmljc1xuICogc2luY2UsIGZvciBleGFtcGxlLCBjaHJvbWEgb2YgJ0NiJyBhbmQgJ0InIGFyZSBib3RoIDExXG4gKlxuICogSWYgdGhlIG5vdGUgaGFzIG9jdGF2ZSwgdGhlIHBhcnNlciBvYmplY3Qgd2lsbCBjb250YWluOlxuICogLSBvY3Q6IHRoZSBvY3RhdmUgbnVtYmVyIChhcyBpbnRlZ2VyKVxuICogLSBtaWRpOiB0aGUgbWlkaSBudW1iZXJcbiAqIC0gZnJlcTogdGhlIGZyZXF1ZW5jeSAodXNpbmcgdHVuaW5nIHBhcmFtZXRlciBhcyBiYXNlKVxuICpcbiAqIElmIHRoZSBwYXJhbWV0ZXIgYGlzVG9uaWNgIGlzIHNldCB0byB0cnVlLCB0aGUgcGFyc2VkIG9iamVjdCB3aWxsIGNvbnRhaW46XG4gKiAtIHRvbmljT2Y6IHRoZSByZXN0IG9mIHRoZSBzdHJpbmcgdGhhdCBmb2xsb3dzIG5vdGUgbmFtZSAobGVmdCBhbmQgcmlnaHQgdHJpbW1lZClcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIHBhcnNlID0gcmVxdWlyZSgnbm90ZS1wYXJzZXInKS5wYXJzZVxuICogcGFyc2UoJ0NiNCcpXG4gKiAvLyA9PiB7IGxldHRlcjogJ0MnLCBhY2M6ICdiJywgcGM6ICdDYicsIHN0ZXA6IDAsIGFsdDogLTEsIGNocm9tYTogLTEsXG4gKiAgICAgICAgIG9jdDogNCwgbWlkaTogNTksIGZyZXE6IDI0Ni45NDE2NTA2MjgwNjIwNiB9XG4gKiAvLyBpZiBubyBvY3RhdmUsIG5vIG1pZGksIG5vIGZyZXFcbiAqIHBhcnNlKCdmeCcpXG4gKiAvLyA9PiB7IGxldHRlcjogJ0YnLCBhY2M6ICcjIycsIHBjOiAnRiMjJywgc3RlcDogMywgYWx0OiAyLCBjaHJvbWE6IDcgfSlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlIChzdHIsIGlzVG9uaWMsIHR1bmluZykge1xuICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpIHJldHVybiBudWxsXG4gIHZhciBtID0gUkVHRVguZXhlYyhzdHIpXG4gIGlmICghbSB8fCAoIWlzVG9uaWMgJiYgbVs0XSkpIHJldHVybiBudWxsXG5cbiAgdmFyIHAgPSB7IGxldHRlcjogbVsxXS50b1VwcGVyQ2FzZSgpLCBhY2M6IG1bMl0ucmVwbGFjZSgveC9nLCAnIyMnKSB9XG4gIHAucGMgPSBwLmxldHRlciArIHAuYWNjXG4gIHAuc3RlcCA9IChwLmxldHRlci5jaGFyQ29kZUF0KDApICsgMykgJSA3XG4gIHAuYWx0ID0gcC5hY2NbMF0gPT09ICdiJyA/IC1wLmFjYy5sZW5ndGggOiBwLmFjYy5sZW5ndGhcbiAgdmFyIHBvcyA9IFNFTUlUT05FU1twLnN0ZXBdICsgcC5hbHRcbiAgcC5jaHJvbWEgPSBwb3MgPCAwID8gMTIgKyBwb3MgOiBwb3MgJSAxMlxuICBpZiAobVszXSkgeyAvLyBoYXMgb2N0YXZlXG4gICAgcC5vY3QgPSArbVszXVxuICAgIHAubWlkaSA9IHBvcyArIDEyICogKHAub2N0ICsgMSlcbiAgICBwLmZyZXEgPSBtaWRpVG9GcmVxKHAubWlkaSwgdHVuaW5nKVxuICB9XG4gIGlmIChpc1RvbmljKSBwLnRvbmljT2YgPSBtWzRdXG4gIHJldHVybiBwXG59XG5cbnZhciBMRVRURVJTID0gJ0NERUZHQUInXG5mdW5jdGlvbiBhY2NTdHIgKG4pIHsgcmV0dXJuICFpc051bShuKSA/ICcnIDogbiA8IDAgPyBmaWxsU3RyKCdiJywgLW4pIDogZmlsbFN0cignIycsIG4pIH1cbmZ1bmN0aW9uIG9jdFN0ciAobikgeyByZXR1cm4gIWlzTnVtKG4pID8gJycgOiAnJyArIG4gfVxuXG4vKipcbiAqIENyZWF0ZSBhIHN0cmluZyBmcm9tIGEgcGFyc2VkIG9iamVjdCBvciBgc3RlcCwgYWx0ZXJhdGlvbiwgb2N0YXZlYCBwYXJhbWV0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIC0gdGhlIHBhcnNlZCBkYXRhIG9iamVjdFxuICogQHJldHVybiB7U3RyaW5nfSBhIG5vdGUgc3RyaW5nIG9yIG51bGwgaWYgbm90IHZhbGlkIHBhcmFtZXRlcnNcbiAqIEBzaW5jZSAxLjJcbiAqIEBleGFtcGxlXG4gKiBwYXJzZXIuYnVpbGQocGFyc2VyLnBhcnNlKCdjYjInKSkgLy8gPT4gJ0NiMidcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gaXQgYWNjZXB0cyAoc3RlcCwgYWx0ZXJhdGlvbiwgb2N0YXZlKSBwYXJhbWV0ZXJzOlxuICogcGFyc2VyLmJ1aWxkKDMpIC8vID0+ICdGJ1xuICogcGFyc2VyLmJ1aWxkKDMsIC0xKSAvLyA9PiAnRmInXG4gKiBwYXJzZXIuYnVpbGQoMywgLTEsIDQpIC8vID0+ICdGYjQnXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZCAocywgYSwgbykge1xuICBpZiAocyA9PT0gbnVsbCB8fCB0eXBlb2YgcyA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiBudWxsXG4gIGlmIChzLnN0ZXApIHJldHVybiBidWlsZChzLnN0ZXAsIHMuYWx0LCBzLm9jdClcbiAgaWYgKHMgPCAwIHx8IHMgPiA2KSByZXR1cm4gbnVsbFxuICByZXR1cm4gTEVUVEVSUy5jaGFyQXQocykgKyBhY2NTdHIoYSkgKyBvY3RTdHIobylcbn1cblxuLyoqXG4gKiBHZXQgbWlkaSBvZiBhIG5vdGVcbiAqXG4gKiBAbmFtZSBtaWRpXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7U3RyaW5nfEludGVnZXJ9IG5vdGUgLSB0aGUgbm90ZSBuYW1lIG9yIG1pZGkgbnVtYmVyXG4gKiBAcmV0dXJuIHtJbnRlZ2VyfSB0aGUgbWlkaSBudW1iZXIgb2YgdGhlIG5vdGUgb3IgbnVsbCBpZiBub3QgYSB2YWxpZCBub3RlXG4gKiBvciB0aGUgbm90ZSBkb2VzIE5PVCBjb250YWlucyBvY3RhdmVcbiAqIEBleGFtcGxlXG4gKiB2YXIgcGFyc2VyID0gcmVxdWlyZSgnbm90ZS1wYXJzZXInKVxuICogcGFyc2VyLm1pZGkoJ0E0JykgLy8gPT4gNjlcbiAqIHBhcnNlci5taWRpKCdBJykgLy8gPT4gbnVsbFxuICogQGV4YW1wbGVcbiAqIC8vIG1pZGkgbnVtYmVycyBhcmUgYnlwYXNzZWQgKGV2ZW4gYXMgc3RyaW5ncylcbiAqIHBhcnNlci5taWRpKDYwKSAvLyA9PiA2MFxuICogcGFyc2VyLm1pZGkoJzYwJykgLy8gPT4gNjBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1pZGkgKG5vdGUpIHtcbiAgaWYgKChpc051bShub3RlKSB8fCBpc1N0cihub3RlKSkgJiYgbm90ZSA+PSAwICYmIG5vdGUgPCAxMjgpIHJldHVybiArbm90ZVxuICB2YXIgcCA9IHBhcnNlKG5vdGUpXG4gIHJldHVybiBwICYmIGlzRGVmKHAubWlkaSkgPyBwLm1pZGkgOiBudWxsXG59XG5cbi8qKlxuICogR2V0IGZyZXEgb2YgYSBub3RlIGluIGhlcnR6cyAoaW4gYSB3ZWxsIHRlbXBlcmVkIDQ0MEh6IEE0KVxuICpcbiAqIEBuYW1lIGZyZXFcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtTdHJpbmd9IG5vdGUgLSB0aGUgbm90ZSBuYW1lIG9yIG5vdGUgbWlkaSBudW1iZXJcbiAqIEBwYXJhbSB7U3RyaW5nfSB0dW5pbmcgLSAoT3B0aW9uYWwpIHRoZSBBNCBmcmVxdWVuY3kgKDQ0MCBieSBkZWZhdWx0KVxuICogQHJldHVybiB7RmxvYXR9IHRoZSBmcmVxIG9mIHRoZSBudW1iZXIgaWYgaGVydHpzIG9yIG51bGwgaWYgbm90IHZhbGlkIG5vdGVcbiAqIEBleGFtcGxlXG4gKiB2YXIgcGFyc2VyID0gcmVxdWlyZSgnbm90ZS1wYXJzZXInKVxuICogcGFyc2VyLmZyZXEoJ0E0JykgLy8gPT4gNDQwXG4gKiBwYXJzZXIuZnJlcSgnQScpIC8vID0+IG51bGxcbiAqIEBleGFtcGxlXG4gKiAvLyBjYW4gY2hhbmdlIHR1bmluZyAoNDQwIGJ5IGRlZmF1bHQpXG4gKiBwYXJzZXIuZnJlcSgnQTQnLCA0NDQpIC8vID0+IDQ0NFxuICogcGFyc2VyLmZyZXEoJ0EzJywgNDQ0KSAvLyA9PiAyMjJcbiAqIEBleGFtcGxlXG4gKiAvLyBpdCBhY2NlcHRzIG1pZGkgbnVtYmVycyAoYXMgbnVtYmVycyBhbmQgYXMgc3RyaW5ncylcbiAqIHBhcnNlci5mcmVxKDY5KSAvLyA9PiA0NDBcbiAqIHBhcnNlci5mcmVxKCc2OScsIDQ0MikgLy8gPT4gNDQyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmcmVxIChub3RlLCB0dW5pbmcpIHtcbiAgdmFyIG0gPSBtaWRpKG5vdGUpXG4gIHJldHVybiBtID09PSBudWxsID8gbnVsbCA6IG1pZGlUb0ZyZXEobSwgdHVuaW5nKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbGV0dGVyIChzcmMpIHsgcmV0dXJuIChwYXJzZShzcmMpIHx8IHt9KS5sZXR0ZXIgfVxuZXhwb3J0IGZ1bmN0aW9uIGFjYyAoc3JjKSB7IHJldHVybiAocGFyc2Uoc3JjKSB8fCB7fSkuYWNjIH1cbmV4cG9ydCBmdW5jdGlvbiBwYyAoc3JjKSB7IHJldHVybiAocGFyc2Uoc3JjKSB8fCB7fSkucGMgfVxuZXhwb3J0IGZ1bmN0aW9uIHN0ZXAgKHNyYykgeyByZXR1cm4gKHBhcnNlKHNyYykgfHwge30pLnN0ZXAgfVxuZXhwb3J0IGZ1bmN0aW9uIGFsdCAoc3JjKSB7IHJldHVybiAocGFyc2Uoc3JjKSB8fCB7fSkuYWx0IH1cbmV4cG9ydCBmdW5jdGlvbiBjaHJvbWEgKHNyYykgeyByZXR1cm4gKHBhcnNlKHNyYykgfHwge30pLmNocm9tYSB9XG5leHBvcnQgZnVuY3Rpb24gb2N0IChzcmMpIHsgcmV0dXJuIChwYXJzZShzcmMpIHx8IHt9KS5vY3QgfVxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L25vdGUtcGFyc2VyL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAxNDFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX2R1cGxleC5qcycpO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWRhYmxlLXN0cmVhbS9kdXBsZXgtYnJvd3Nlci5qc1xuLy8gbW9kdWxlIGlkID0gMTQyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIGEgcGFzc3Rocm91Z2ggc3RyZWFtLlxuLy8gYmFzaWNhbGx5IGp1c3QgdGhlIG1vc3QgbWluaW1hbCBzb3J0IG9mIFRyYW5zZm9ybSBzdHJlYW0uXG4vLyBFdmVyeSB3cml0dGVuIGNodW5rIGdldHMgb3V0cHV0IGFzLWlzLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUGFzc1Rocm91Z2g7XG5cbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL19zdHJlYW1fdHJhbnNmb3JtJyk7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhQYXNzVGhyb3VnaCwgVHJhbnNmb3JtKTtcblxuZnVuY3Rpb24gUGFzc1Rocm91Z2gob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUGFzc1Rocm91Z2gpKSByZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1xuXG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xufVxuXG5QYXNzVGhyb3VnaC5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG51bGwsIGNodW5rKTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qc1xuLy8gbW9kdWxlIGlkID0gMTQzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIid1c2Ugc3RyaWN0JztcblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbi8qPHJlcGxhY2VtZW50PiovXG52YXIgYnVmZmVyU2hpbSA9IHJlcXVpcmUoJ2J1ZmZlci1zaGltcycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbm1vZHVsZS5leHBvcnRzID0gQnVmZmVyTGlzdDtcblxuZnVuY3Rpb24gQnVmZmVyTGlzdCgpIHtcbiAgdGhpcy5oZWFkID0gbnVsbDtcbiAgdGhpcy50YWlsID0gbnVsbDtcbiAgdGhpcy5sZW5ndGggPSAwO1xufVxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKHYpIHtcbiAgdmFyIGVudHJ5ID0geyBkYXRhOiB2LCBuZXh0OiBudWxsIH07XG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHRoaXMudGFpbC5uZXh0ID0gZW50cnk7ZWxzZSB0aGlzLmhlYWQgPSBlbnRyeTtcbiAgdGhpcy50YWlsID0gZW50cnk7XG4gICsrdGhpcy5sZW5ndGg7XG59O1xuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS51bnNoaWZ0ID0gZnVuY3Rpb24gKHYpIHtcbiAgdmFyIGVudHJ5ID0geyBkYXRhOiB2LCBuZXh0OiB0aGlzLmhlYWQgfTtcbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSB0aGlzLnRhaWwgPSBlbnRyeTtcbiAgdGhpcy5oZWFkID0gZW50cnk7XG4gICsrdGhpcy5sZW5ndGg7XG59O1xuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5zaGlmdCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gIHZhciByZXQgPSB0aGlzLmhlYWQuZGF0YTtcbiAgaWYgKHRoaXMubGVuZ3RoID09PSAxKSB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBudWxsO2Vsc2UgdGhpcy5oZWFkID0gdGhpcy5oZWFkLm5leHQ7XG4gIC0tdGhpcy5sZW5ndGg7XG4gIHJldHVybiByZXQ7XG59O1xuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbnVsbDtcbiAgdGhpcy5sZW5ndGggPSAwO1xufTtcblxuQnVmZmVyTGlzdC5wcm90b3R5cGUuam9pbiA9IGZ1bmN0aW9uIChzKSB7XG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcnO1xuICB2YXIgcCA9IHRoaXMuaGVhZDtcbiAgdmFyIHJldCA9ICcnICsgcC5kYXRhO1xuICB3aGlsZSAocCA9IHAubmV4dCkge1xuICAgIHJldCArPSBzICsgcC5kYXRhO1xuICB9cmV0dXJuIHJldDtcbn07XG5cbkJ1ZmZlckxpc3QucHJvdG90eXBlLmNvbmNhdCA9IGZ1bmN0aW9uIChuKSB7XG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGJ1ZmZlclNoaW0uYWxsb2MoMCk7XG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHRoaXMuaGVhZC5kYXRhO1xuICB2YXIgcmV0ID0gYnVmZmVyU2hpbS5hbGxvY1Vuc2FmZShuID4+PiAwKTtcbiAgdmFyIHAgPSB0aGlzLmhlYWQ7XG4gIHZhciBpID0gMDtcbiAgd2hpbGUgKHApIHtcbiAgICBwLmRhdGEuY29weShyZXQsIGkpO1xuICAgIGkgKz0gcC5kYXRhLmxlbmd0aDtcbiAgICBwID0gcC5uZXh0O1xuICB9XG4gIHJldHVybiByZXQ7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9yZWFkYWJsZS1zdHJlYW0vbGliL2ludGVybmFsL3N0cmVhbXMvQnVmZmVyTGlzdC5qc1xuLy8gbW9kdWxlIGlkID0gMTQ0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9yZWFkYWJsZScpLlBhc3NUaHJvdWdoXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vcmVhZGFibGUtc3RyZWFtL3Bhc3N0aHJvdWdoLmpzXG4vLyBtb2R1bGUgaWQgPSAxNDVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL3JlYWRhYmxlJykuVHJhbnNmb3JtXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vcmVhZGFibGUtc3RyZWFtL3RyYW5zZm9ybS5qc1xuLy8gbW9kdWxlIGlkID0gMTQ2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV93cml0YWJsZS5qcycpO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWRhYmxlLXN0cmVhbS93cml0YWJsZS1icm93c2VyLmpzXG4vLyBtb2R1bGUgaWQgPSAxNDdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiKGZ1bmN0aW9uIChnbG9iYWwsIHVuZGVmaW5lZCkge1xuICAgIFwidXNlIHN0cmljdFwiO1xuXG4gICAgaWYgKGdsb2JhbC5zZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBuZXh0SGFuZGxlID0gMTsgLy8gU3BlYyBzYXlzIGdyZWF0ZXIgdGhhbiB6ZXJvXG4gICAgdmFyIHRhc2tzQnlIYW5kbGUgPSB7fTtcbiAgICB2YXIgY3VycmVudGx5UnVubmluZ0FUYXNrID0gZmFsc2U7XG4gICAgdmFyIGRvYyA9IGdsb2JhbC5kb2N1bWVudDtcbiAgICB2YXIgcmVnaXN0ZXJJbW1lZGlhdGU7XG5cbiAgICBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoY2FsbGJhY2spIHtcbiAgICAgIC8vIENhbGxiYWNrIGNhbiBlaXRoZXIgYmUgYSBmdW5jdGlvbiBvciBhIHN0cmluZ1xuICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGNhbGxiYWNrID0gbmV3IEZ1bmN0aW9uKFwiXCIgKyBjYWxsYmFjayk7XG4gICAgICB9XG4gICAgICAvLyBDb3B5IGZ1bmN0aW9uIGFyZ3VtZW50c1xuICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpICsgMV07XG4gICAgICB9XG4gICAgICAvLyBTdG9yZSBhbmQgcmVnaXN0ZXIgdGhlIHRhc2tcbiAgICAgIHZhciB0YXNrID0geyBjYWxsYmFjazogY2FsbGJhY2ssIGFyZ3M6IGFyZ3MgfTtcbiAgICAgIHRhc2tzQnlIYW5kbGVbbmV4dEhhbmRsZV0gPSB0YXNrO1xuICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUobmV4dEhhbmRsZSk7XG4gICAgICByZXR1cm4gbmV4dEhhbmRsZSsrO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKGhhbmRsZSkge1xuICAgICAgICBkZWxldGUgdGFza3NCeUhhbmRsZVtoYW5kbGVdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJ1bih0YXNrKSB7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IHRhc2suY2FsbGJhY2s7XG4gICAgICAgIHZhciBhcmdzID0gdGFzay5hcmdzO1xuICAgICAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgY2FsbGJhY2soYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgY2FsbGJhY2soYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgY2FsbGJhY2soYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJ1bklmUHJlc2VudChoYW5kbGUpIHtcbiAgICAgICAgLy8gRnJvbSB0aGUgc3BlYzogXCJXYWl0IHVudGlsIGFueSBpbnZvY2F0aW9ucyBvZiB0aGlzIGFsZ29yaXRobSBzdGFydGVkIGJlZm9yZSB0aGlzIG9uZSBoYXZlIGNvbXBsZXRlZC5cIlxuICAgICAgICAvLyBTbyBpZiB3ZSdyZSBjdXJyZW50bHkgcnVubmluZyBhIHRhc2ssIHdlJ2xsIG5lZWQgdG8gZGVsYXkgdGhpcyBpbnZvY2F0aW9uLlxuICAgICAgICBpZiAoY3VycmVudGx5UnVubmluZ0FUYXNrKSB7XG4gICAgICAgICAgICAvLyBEZWxheSBieSBkb2luZyBhIHNldFRpbWVvdXQuIHNldEltbWVkaWF0ZSB3YXMgdHJpZWQgaW5zdGVhZCwgYnV0IGluIEZpcmVmb3ggNyBpdCBnZW5lcmF0ZWQgYVxuICAgICAgICAgICAgLy8gXCJ0b28gbXVjaCByZWN1cnNpb25cIiBlcnJvci5cbiAgICAgICAgICAgIHNldFRpbWVvdXQocnVuSWZQcmVzZW50LCAwLCBoYW5kbGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIHRhc2sgPSB0YXNrc0J5SGFuZGxlW2hhbmRsZV07XG4gICAgICAgICAgICBpZiAodGFzaykge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IHRydWU7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcnVuKHRhc2spO1xuICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFySW1tZWRpYXRlKGhhbmRsZSk7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxOZXh0VGlja0ltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICByZWdpc3RlckltbWVkaWF0ZSA9IGZ1bmN0aW9uKGhhbmRsZSkge1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7IHJ1bklmUHJlc2VudChoYW5kbGUpOyB9KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYW5Vc2VQb3N0TWVzc2FnZSgpIHtcbiAgICAgICAgLy8gVGhlIHRlc3QgYWdhaW5zdCBgaW1wb3J0U2NyaXB0c2AgcHJldmVudHMgdGhpcyBpbXBsZW1lbnRhdGlvbiBmcm9tIGJlaW5nIGluc3RhbGxlZCBpbnNpZGUgYSB3ZWIgd29ya2VyLFxuICAgICAgICAvLyB3aGVyZSBgZ2xvYmFsLnBvc3RNZXNzYWdlYCBtZWFucyBzb21ldGhpbmcgY29tcGxldGVseSBkaWZmZXJlbnQgYW5kIGNhbid0IGJlIHVzZWQgZm9yIHRoaXMgcHVycG9zZS5cbiAgICAgICAgaWYgKGdsb2JhbC5wb3N0TWVzc2FnZSAmJiAhZ2xvYmFsLmltcG9ydFNjcmlwdHMpIHtcbiAgICAgICAgICAgIHZhciBwb3N0TWVzc2FnZUlzQXN5bmNocm9ub3VzID0gdHJ1ZTtcbiAgICAgICAgICAgIHZhciBvbGRPbk1lc3NhZ2UgPSBnbG9iYWwub25tZXNzYWdlO1xuICAgICAgICAgICAgZ2xvYmFsLm9ubWVzc2FnZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlSXNBc3luY2hyb25vdXMgPSBmYWxzZTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBnbG9iYWwucG9zdE1lc3NhZ2UoXCJcIiwgXCIqXCIpO1xuICAgICAgICAgICAgZ2xvYmFsLm9ubWVzc2FnZSA9IG9sZE9uTWVzc2FnZTtcbiAgICAgICAgICAgIHJldHVybiBwb3N0TWVzc2FnZUlzQXN5bmNocm9ub3VzO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbFBvc3RNZXNzYWdlSW1wbGVtZW50YXRpb24oKSB7XG4gICAgICAgIC8vIEluc3RhbGxzIGFuIGV2ZW50IGhhbmRsZXIgb24gYGdsb2JhbGAgZm9yIHRoZSBgbWVzc2FnZWAgZXZlbnQ6IHNlZVxuICAgICAgICAvLyAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0RPTS93aW5kb3cucG9zdE1lc3NhZ2VcbiAgICAgICAgLy8gKiBodHRwOi8vd3d3LndoYXR3Zy5vcmcvc3BlY3Mvd2ViLWFwcHMvY3VycmVudC13b3JrL211bHRpcGFnZS9jb21tcy5odG1sI2Nyb3NzRG9jdW1lbnRNZXNzYWdlc1xuXG4gICAgICAgIHZhciBtZXNzYWdlUHJlZml4ID0gXCJzZXRJbW1lZGlhdGUkXCIgKyBNYXRoLnJhbmRvbSgpICsgXCIkXCI7XG4gICAgICAgIHZhciBvbkdsb2JhbE1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LnNvdXJjZSA9PT0gZ2xvYmFsICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIGV2ZW50LmRhdGEgPT09IFwic3RyaW5nXCIgJiZcbiAgICAgICAgICAgICAgICBldmVudC5kYXRhLmluZGV4T2YobWVzc2FnZVByZWZpeCkgPT09IDApIHtcbiAgICAgICAgICAgICAgICBydW5JZlByZXNlbnQoK2V2ZW50LmRhdGEuc2xpY2UobWVzc2FnZVByZWZpeC5sZW5ndGgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKFwibWVzc2FnZVwiLCBvbkdsb2JhbE1lc3NhZ2UsIGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsb2JhbC5hdHRhY2hFdmVudChcIm9ubWVzc2FnZVwiLCBvbkdsb2JhbE1lc3NhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICAgICAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShtZXNzYWdlUHJlZml4ICsgaGFuZGxlLCBcIipcIik7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbE1lc3NhZ2VDaGFubmVsSW1wbGVtZW50YXRpb24oKSB7XG4gICAgICAgIHZhciBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIHZhciBoYW5kbGUgPSBldmVudC5kYXRhO1xuICAgICAgICAgICAgcnVuSWZQcmVzZW50KGhhbmRsZSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoaGFuZGxlKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnN0YWxsUmVhZHlTdGF0ZUNoYW5nZUltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICB2YXIgaHRtbCA9IGRvYy5kb2N1bWVudEVsZW1lbnQ7XG4gICAgICAgIHJlZ2lzdGVySW1tZWRpYXRlID0gZnVuY3Rpb24oaGFuZGxlKSB7XG4gICAgICAgICAgICAvLyBDcmVhdGUgYSA8c2NyaXB0PiBlbGVtZW50OyBpdHMgcmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aWxsIGJlIGZpcmVkIGFzeW5jaHJvbm91c2x5IG9uY2UgaXQgaXMgaW5zZXJ0ZWRcbiAgICAgICAgICAgIC8vIGludG8gdGhlIGRvY3VtZW50LiBEbyBzbywgdGh1cyBxdWV1aW5nIHVwIHRoZSB0YXNrLiBSZW1lbWJlciB0byBjbGVhbiB1cCBvbmNlIGl0J3MgYmVlbiBjYWxsZWQuXG4gICAgICAgICAgICB2YXIgc2NyaXB0ID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIik7XG4gICAgICAgICAgICBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJ1bklmUHJlc2VudChoYW5kbGUpO1xuICAgICAgICAgICAgICAgIHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xuICAgICAgICAgICAgICAgIGh0bWwucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgICAgICAgICBzY3JpcHQgPSBudWxsO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGh0bWwuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnN0YWxsU2V0VGltZW91dEltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICByZWdpc3RlckltbWVkaWF0ZSA9IGZ1bmN0aW9uKGhhbmRsZSkge1xuICAgICAgICAgICAgc2V0VGltZW91dChydW5JZlByZXNlbnQsIDAsIGhhbmRsZSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gSWYgc3VwcG9ydGVkLCB3ZSBzaG91bGQgYXR0YWNoIHRvIHRoZSBwcm90b3R5cGUgb2YgZ2xvYmFsLCBzaW5jZSB0aGF0IGlzIHdoZXJlIHNldFRpbWVvdXQgZXQgYWwuIGxpdmUuXG4gICAgdmFyIGF0dGFjaFRvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihnbG9iYWwpO1xuICAgIGF0dGFjaFRvID0gYXR0YWNoVG8gJiYgYXR0YWNoVG8uc2V0VGltZW91dCA/IGF0dGFjaFRvIDogZ2xvYmFsO1xuXG4gICAgLy8gRG9uJ3QgZ2V0IGZvb2xlZCBieSBlLmcuIGJyb3dzZXJpZnkgZW52aXJvbm1lbnRzLlxuICAgIGlmICh7fS50b1N0cmluZy5jYWxsKGdsb2JhbC5wcm9jZXNzKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCIpIHtcbiAgICAgICAgLy8gRm9yIE5vZGUuanMgYmVmb3JlIDAuOVxuICAgICAgICBpbnN0YWxsTmV4dFRpY2tJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIGlmIChjYW5Vc2VQb3N0TWVzc2FnZSgpKSB7XG4gICAgICAgIC8vIEZvciBub24tSUUxMCBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgaW5zdGFsbFBvc3RNZXNzYWdlSW1wbGVtZW50YXRpb24oKTtcblxuICAgIH0gZWxzZSBpZiAoZ2xvYmFsLk1lc3NhZ2VDaGFubmVsKSB7XG4gICAgICAgIC8vIEZvciB3ZWIgd29ya2Vycywgd2hlcmUgc3VwcG9ydGVkXG4gICAgICAgIGluc3RhbGxNZXNzYWdlQ2hhbm5lbEltcGxlbWVudGF0aW9uKCk7XG5cbiAgICB9IGVsc2UgaWYgKGRvYyAmJiBcIm9ucmVhZHlzdGF0ZWNoYW5nZVwiIGluIGRvYy5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpKSB7XG4gICAgICAgIC8vIEZvciBJRSA24oCTOFxuICAgICAgICBpbnN0YWxsUmVhZHlTdGF0ZUNoYW5nZUltcGxlbWVudGF0aW9uKCk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBGb3Igb2xkZXIgYnJvd3NlcnNcbiAgICAgICAgaW5zdGFsbFNldFRpbWVvdXRJbXBsZW1lbnRhdGlvbigpO1xuICAgIH1cblxuICAgIGF0dGFjaFRvLnNldEltbWVkaWF0ZSA9IHNldEltbWVkaWF0ZTtcbiAgICBhdHRhY2hUby5jbGVhckltbWVkaWF0ZSA9IGNsZWFySW1tZWRpYXRlO1xufSh0eXBlb2Ygc2VsZiA9PT0gXCJ1bmRlZmluZWRcIiA/IHR5cGVvZiBnbG9iYWwgPT09IFwidW5kZWZpbmVkXCIgPyB0aGlzIDogZ2xvYmFsIDogc2VsZikpO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3NldGltbWVkaWF0ZS9zZXRJbW1lZGlhdGUuanNcbi8vIG1vZHVsZSBpZCA9IDE0OFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmluaGVyaXRzKFN0cmVhbSwgRUUpO1xuU3RyZWFtLlJlYWRhYmxlID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzJyk7XG5TdHJlYW0uV3JpdGFibGUgPSByZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUuanMnKTtcblN0cmVhbS5EdXBsZXggPSByZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzJyk7XG5TdHJlYW0uVHJhbnNmb3JtID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3RyYW5zZm9ybS5qcycpO1xuU3RyZWFtLlBhc3NUaHJvdWdoID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3Bhc3N0aHJvdWdoLmpzJyk7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuNC54XG5TdHJlYW0uU3RyZWFtID0gU3RyZWFtO1xuXG5cblxuLy8gb2xkLXN0eWxlIHN0cmVhbXMuICBOb3RlIHRoYXQgdGhlIHBpcGUgbWV0aG9kICh0aGUgb25seSByZWxldmFudFxuLy8gcGFydCBvZiB0aGlzIGNsYXNzKSBpcyBvdmVycmlkZGVuIGluIHRoZSBSZWFkYWJsZSBjbGFzcy5cblxuZnVuY3Rpb24gU3RyZWFtKCkge1xuICBFRS5jYWxsKHRoaXMpO1xufVxuXG5TdHJlYW0ucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbihkZXN0LCBvcHRpb25zKSB7XG4gIHZhciBzb3VyY2UgPSB0aGlzO1xuXG4gIGZ1bmN0aW9uIG9uZGF0YShjaHVuaykge1xuICAgIGlmIChkZXN0LndyaXRhYmxlKSB7XG4gICAgICBpZiAoZmFsc2UgPT09IGRlc3Qud3JpdGUoY2h1bmspICYmIHNvdXJjZS5wYXVzZSkge1xuICAgICAgICBzb3VyY2UucGF1c2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzb3VyY2Uub24oJ2RhdGEnLCBvbmRhdGEpO1xuXG4gIGZ1bmN0aW9uIG9uZHJhaW4oKSB7XG4gICAgaWYgKHNvdXJjZS5yZWFkYWJsZSAmJiBzb3VyY2UucmVzdW1lKSB7XG4gICAgICBzb3VyY2UucmVzdW1lKCk7XG4gICAgfVxuICB9XG5cbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcblxuICAvLyBJZiB0aGUgJ2VuZCcgb3B0aW9uIGlzIG5vdCBzdXBwbGllZCwgZGVzdC5lbmQoKSB3aWxsIGJlIGNhbGxlZCB3aGVuXG4gIC8vIHNvdXJjZSBnZXRzIHRoZSAnZW5kJyBvciAnY2xvc2UnIGV2ZW50cy4gIE9ubHkgZGVzdC5lbmQoKSBvbmNlLlxuICBpZiAoIWRlc3QuX2lzU3RkaW8gJiYgKCFvcHRpb25zIHx8IG9wdGlvbnMuZW5kICE9PSBmYWxzZSkpIHtcbiAgICBzb3VyY2Uub24oJ2VuZCcsIG9uZW5kKTtcbiAgICBzb3VyY2Uub24oJ2Nsb3NlJywgb25jbG9zZSk7XG4gIH1cblxuICB2YXIgZGlkT25FbmQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gb25lbmQoKSB7XG4gICAgaWYgKGRpZE9uRW5kKSByZXR1cm47XG4gICAgZGlkT25FbmQgPSB0cnVlO1xuXG4gICAgZGVzdC5lbmQoKTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBpZiAoZGlkT25FbmQpIHJldHVybjtcbiAgICBkaWRPbkVuZCA9IHRydWU7XG5cbiAgICBpZiAodHlwZW9mIGRlc3QuZGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykgZGVzdC5kZXN0cm95KCk7XG4gIH1cblxuICAvLyBkb24ndCBsZWF2ZSBkYW5nbGluZyBwaXBlcyB3aGVuIHRoZXJlIGFyZSBlcnJvcnMuXG4gIGZ1bmN0aW9uIG9uZXJyb3IoZXIpIHtcbiAgICBjbGVhbnVwKCk7XG4gICAgaWYgKEVFLmxpc3RlbmVyQ291bnQodGhpcywgJ2Vycm9yJykgPT09IDApIHtcbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgc3RyZWFtIGVycm9yIGluIHBpcGUuXG4gICAgfVxuICB9XG5cbiAgc291cmNlLm9uKCdlcnJvcicsIG9uZXJyb3IpO1xuICBkZXN0Lm9uKCdlcnJvcicsIG9uZXJyb3IpO1xuXG4gIC8vIHJlbW92ZSBhbGwgdGhlIGV2ZW50IGxpc3RlbmVycyB0aGF0IHdlcmUgYWRkZWQuXG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgb25kYXRhKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIGNsZWFudXApO1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBjbGVhbnVwKTtcblxuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgY2xlYW51cCk7XG4gIH1cblxuICBzb3VyY2Uub24oJ2VuZCcsIGNsZWFudXApO1xuICBzb3VyY2Uub24oJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgZGVzdC5vbignY2xvc2UnLCBjbGVhbnVwKTtcblxuICBkZXN0LmVtaXQoJ3BpcGUnLCBzb3VyY2UpO1xuXG4gIC8vIEFsbG93IGZvciB1bml4LWxpa2UgdXNhZ2U6IEEucGlwZShCKS5waXBlKEMpXG4gIHJldHVybiBkZXN0O1xufTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9zdHJlYW0tYnJvd3NlcmlmeS9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gMTQ5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qKlxuICogQSBtaWRpIG5vdGUgbnVtYmVyIGlzIGEgbnVtYmVyIHJlcHJlc2VudGF0aW9uIG9mIGEgbm90ZSBwaXRjaC4gSXQgY2FuIGJlXG4gKiBpbnRlZ2VycyBzbyBpdCdzIGVxdWFsIHRlbXBlcmVkIHR1bmVkLCBvciBmbG9hdCB0byBpbmRpY2F0ZSBpdCdzIG5vdFxuICogdHVuZWQgaW50byBlcXVhbCB0ZW1lcGVyZWQgc2NhbGUuXG4gKlxuICogVGhpcyBtb2R1bGUgY29udGFpbnMgZnVuY3Rpb25zIHRvIGNvbnZlcnQgdG8gYW5kIGZyb20gbWlkaSBub3Rlcy5cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG1pZGkgPSByZXF1aXJlKCd0b25hbC1taWRpJylcbiAqIG1pZGkudG9NaWRpKCdBNCcpIC8vID0+IDY5XG4gKiBtaWRpLm5vdGUoNjkpIC8vID0+ICdBNCdcbiAqIG1pZGkubm90ZSg2MSkgLy8gPT4gJ0RiNCdcbiAqIG1pZGkubm90ZSg2MSwgdHJ1ZSkgLy8gPT4gJ0MjNCdcbiAqXG4gKiBAbW9kdWxlIG1pZGlcbiAqL1xuXG5pbXBvcnQgeyBtaWRpIH0gZnJvbSAnbm90ZS1wYXJzZXInXG5cbi8qKlxuICogQ29udmVydCB0aGUgZ2l2ZW4gbm90ZSB0byBhIG1pZGkgbm90ZSBudW1iZXIuIElmIHlvdSBwYXNzIGEgbWlkaSBudW1iZXIgaXRcbiAqIHdpbGwgcmV0dXJuZWQgYXMgaXMuXG4gKlxuICogQHBhcmFtIHtBcnJheXxTdHJpbmd8TnVtYmVyfSBub3RlIC0gdGhlIG5vdGUgdG8gZ2V0IHRoZSBtaWRpIG51bWJlciBmcm9tXG4gKiBAcmV0dXJuIHtJbnRlZ2VyfSB0aGUgbWlkaSBudW1iZXIgb3IgbnVsbCBpZiBub3QgdmFsaWQgcGl0Y2hcbiAqIEBleGFtcGxlXG4gKiBtaWRpLnRvTWlkaSgnQzQnKSAvLyA9PiA2MFxuICogbWlkaS50b01pZGkoNjApIC8vID0+IDYwXG4gKiBtaWRpLnRvTWlkaSgnNjAnKSAvLyA9PiA2MFxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9NaWRpICh2YWwpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsKSAmJiB2YWwubGVuZ3RoID09PSAyKSByZXR1cm4gdmFsWzBdICogNyArIHZhbFsxXSAqIDEyICsgMTJcbiAgcmV0dXJuIG1pZGkodmFsKVxufVxuXG52YXIgRkxBVFMgPSAnQyBEYiBEIEViIEUgRiBHYiBHIEFiIEEgQmIgQicuc3BsaXQoJyAnKVxudmFyIFNIQVJQUyA9ICdDIEMjIEQgRCMgRSBGIEYjIEcgRyMgQSBBIyBCJy5zcGxpdCgnICcpXG5cbi8qKlxuICogR2l2ZW4gYSBtaWRpIG51bWJlciwgcmV0dXJucyBhIG5vdGUgbmFtZS4gVGhlIGFsdGVyZWQgbm90ZXMgd2lsbCBoYXZlXG4gKiBmbGF0cyB1bmxlc3MgZXhwbGljaXRseSBzZXQgd2l0aCB0aGUgb3B0aW9uYWwgYHVzZVNoYXJwc2AgcGFyYW1ldGVyLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtJbnRlZ2VyfSBtaWRpIC0gdGhlIG1pZGkgbm90ZSBudW1iZXJcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gdXNlU2hhcnBzIC0gKE9wdGlvbmFsKSBzZXQgdG8gdHJ1ZSB0byB1c2Ugc2hhcnBzIGluc3RlYWQgb2YgZmxhdHNcbiAqIEByZXR1cm4ge1N0cmluZ30gdGhlIG5vdGUgbmFtZVxuICogQGV4YW1wbGVcbiAqIHZhciBtaWRpID0gcmVxdWlyZSgndG9uYWwtbWlkaScpXG4gKiBtaWRpLm5vdGUoNjEpIC8vID0+ICdEYjQnXG4gKiBtaWRpLm5vdGUoNjEsIHRydWUpIC8vID0+ICdDIzQnXG4gKiAvLyBpdCByb3VuZHMgdG8gbmVhcmVzdCBub3RlXG4gKiBtaWRpLm5vdGUoNjEuNykgLy8gPT4gJ0Q0J1xuICovXG5leHBvcnQgZnVuY3Rpb24gbm90ZSAobnVtLCBzaGFycHMpIHtcbiAgaWYgKG51bSA9PT0gdHJ1ZSB8fCBudW0gPT09IGZhbHNlKSByZXR1cm4gZnVuY3Rpb24gKG0pIHsgcmV0dXJuIG5vdGUobSwgbnVtKSB9XG4gIG51bSA9IE1hdGgucm91bmQobnVtKVxuICB2YXIgcGNzID0gc2hhcnBzID09PSB0cnVlID8gU0hBUlBTIDogRkxBVFNcbiAgdmFyIHBjID0gcGNzW251bSAlIDEyXVxuICB2YXIgbyA9IE1hdGguZmxvb3IobnVtIC8gMTIpIC0gMVxuICByZXR1cm4gcGMgKyBvXG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vdG9uYWwtbWlkaS9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gMTUwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlcHJlY2F0ZTtcblxuLyoqXG4gKiBNYXJrIHRoYXQgYSBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLlxuICogUmV0dXJucyBhIG1vZGlmaWVkIGZ1bmN0aW9uIHdoaWNoIHdhcm5zIG9uY2UgYnkgZGVmYXVsdC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLm5vRGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLnRocm93RGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gZGVwcmVjYXRlZCBmdW5jdGlvbnNcbiAqIHdpbGwgdGhyb3cgYW4gRXJyb3Igd2hlbiBpbnZva2VkLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudHJhY2VEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCBpbnZva2UgYGNvbnNvbGUudHJhY2UoKWAgaW5zdGVhZCBvZiBgY29uc29sZS5lcnJvcigpYC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0byBkZXByZWNhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgLSB0aGUgc3RyaW5nIHRvIHByaW50IHRvIHRoZSBjb25zb2xlIHdoZW4gYGZuYCBpcyBpbnZva2VkXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IGEgbmV3IFwiZGVwcmVjYXRlZFwiIHZlcnNpb24gb2YgYGZuYFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkZXByZWNhdGUgKGZuLCBtc2cpIHtcbiAgaWYgKGNvbmZpZygnbm9EZXByZWNhdGlvbicpKSB7XG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBkZXByZWNhdGVkKCkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICBpZiAoY29uZmlnKCd0aHJvd0RlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKGNvbmZpZygndHJhY2VEZXByZWNhdGlvbicpKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2Fybihtc2cpO1xuICAgICAgfVxuICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICByZXR1cm4gZGVwcmVjYXRlZDtcbn1cblxuLyoqXG4gKiBDaGVja3MgYGxvY2FsU3RvcmFnZWAgZm9yIGJvb2xlYW4gdmFsdWVzIGZvciB0aGUgZ2l2ZW4gYG5hbWVgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGNvbmZpZyAobmFtZSkge1xuICAvLyBhY2Nlc3NpbmcgZ2xvYmFsLmxvY2FsU3RvcmFnZSBjYW4gdHJpZ2dlciBhIERPTUV4Y2VwdGlvbiBpbiBzYW5kYm94ZWQgaWZyYW1lc1xuICB0cnkge1xuICAgIGlmICghZ2xvYmFsLmxvY2FsU3RvcmFnZSkgcmV0dXJuIGZhbHNlO1xuICB9IGNhdGNoIChfKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB2YWwgPSBnbG9iYWwubG9jYWxTdG9yYWdlW25hbWVdO1xuICBpZiAobnVsbCA9PSB2YWwpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIFN0cmluZyh2YWwpLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJztcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi91dGlsLWRlcHJlY2F0ZS9icm93c2VyLmpzXG4vLyBtb2R1bGUgaWQgPSAxNTFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICB9XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vdXRpbC9+L2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanNcbi8vIG1vZHVsZSBpZCA9IDE1MlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzQnVmZmVyKGFyZykge1xuICByZXR1cm4gYXJnICYmIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnXG4gICAgJiYgdHlwZW9mIGFyZy5jb3B5ID09PSAnZnVuY3Rpb24nXG4gICAgJiYgdHlwZW9mIGFyZy5maWxsID09PSAnZnVuY3Rpb24nXG4gICAgJiYgdHlwZW9mIGFyZy5yZWFkVUludDggPT09ICdmdW5jdGlvbic7XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3V0aWwvc3VwcG9ydC9pc0J1ZmZlckJyb3dzZXIuanNcbi8vIG1vZHVsZSBpZCA9IDE1M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIGZvcm1hdFJlZ0V4cCA9IC8lW3NkaiVdL2c7XG5leHBvcnRzLmZvcm1hdCA9IGZ1bmN0aW9uKGYpIHtcbiAgaWYgKCFpc1N0cmluZyhmKSkge1xuICAgIHZhciBvYmplY3RzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG9iamVjdHMucHVzaChpbnNwZWN0KGFyZ3VtZW50c1tpXSkpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0cy5qb2luKCcgJyk7XG4gIH1cblxuICB2YXIgaSA9IDE7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICB2YXIgbGVuID0gYXJncy5sZW5ndGg7XG4gIHZhciBzdHIgPSBTdHJpbmcoZikucmVwbGFjZShmb3JtYXRSZWdFeHAsIGZ1bmN0aW9uKHgpIHtcbiAgICBpZiAoeCA9PT0gJyUlJykgcmV0dXJuICclJztcbiAgICBpZiAoaSA+PSBsZW4pIHJldHVybiB4O1xuICAgIHN3aXRjaCAoeCkge1xuICAgICAgY2FzZSAnJXMnOiByZXR1cm4gU3RyaW5nKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclZCc6IHJldHVybiBOdW1iZXIoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVqJzpcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoYXJnc1tpKytdKTtcbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgIHJldHVybiAnW0NpcmN1bGFyXSc7XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB4O1xuICAgIH1cbiAgfSk7XG4gIGZvciAodmFyIHggPSBhcmdzW2ldOyBpIDwgbGVuOyB4ID0gYXJnc1srK2ldKSB7XG4gICAgaWYgKGlzTnVsbCh4KSB8fCAhaXNPYmplY3QoeCkpIHtcbiAgICAgIHN0ciArPSAnICcgKyB4O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgKz0gJyAnICsgaW5zcGVjdCh4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn07XG5cblxuLy8gTWFyayB0aGF0IGEgbWV0aG9kIHNob3VsZCBub3QgYmUgdXNlZC5cbi8vIFJldHVybnMgYSBtb2RpZmllZCBmdW5jdGlvbiB3aGljaCB3YXJucyBvbmNlIGJ5IGRlZmF1bHQuXG4vLyBJZiAtLW5vLWRlcHJlY2F0aW9uIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuZXhwb3J0cy5kZXByZWNhdGUgPSBmdW5jdGlvbihmbiwgbXNnKSB7XG4gIC8vIEFsbG93IGZvciBkZXByZWNhdGluZyB0aGluZ3MgaW4gdGhlIHByb2Nlc3Mgb2Ygc3RhcnRpbmcgdXAuXG4gIGlmIChpc1VuZGVmaW5lZChnbG9iYWwucHJvY2VzcykpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZXhwb3J0cy5kZXByZWNhdGUoZm4sIG1zZykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG5cbiAgaWYgKHByb2Nlc3Mubm9EZXByZWNhdGlvbiA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBmbjtcbiAgfVxuXG4gIHZhciB3YXJuZWQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gZGVwcmVjYXRlZCgpIHtcbiAgICBpZiAoIXdhcm5lZCkge1xuICAgICAgaWYgKHByb2Nlc3MudGhyb3dEZXByZWNhdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy50cmFjZURlcHJlY2F0aW9uKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobXNnKTtcbiAgICAgIH1cbiAgICAgIHdhcm5lZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgcmV0dXJuIGRlcHJlY2F0ZWQ7XG59O1xuXG5cbnZhciBkZWJ1Z3MgPSB7fTtcbnZhciBkZWJ1Z0Vudmlyb247XG5leHBvcnRzLmRlYnVnbG9nID0gZnVuY3Rpb24oc2V0KSB7XG4gIGlmIChpc1VuZGVmaW5lZChkZWJ1Z0Vudmlyb24pKVxuICAgIGRlYnVnRW52aXJvbiA9IHByb2Nlc3MuZW52Lk5PREVfREVCVUcgfHwgJyc7XG4gIHNldCA9IHNldC50b1VwcGVyQ2FzZSgpO1xuICBpZiAoIWRlYnVnc1tzZXRdKSB7XG4gICAgaWYgKG5ldyBSZWdFeHAoJ1xcXFxiJyArIHNldCArICdcXFxcYicsICdpJykudGVzdChkZWJ1Z0Vudmlyb24pKSB7XG4gICAgICB2YXIgcGlkID0gcHJvY2Vzcy5waWQ7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbXNnID0gZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignJXMgJWQ6ICVzJywgc2V0LCBwaWQsIG1zZyk7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge307XG4gICAgfVxuICB9XG4gIHJldHVybiBkZWJ1Z3Nbc2V0XTtcbn07XG5cblxuLyoqXG4gKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG4gKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QgdGhhdCBhbHRlcnMgdGhlIG91dHB1dC5cbiAqL1xuLyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCBvcHRpb25zXG4gIHZhciBjdHggPSB7XG4gICAgc2VlbjogW10sXG4gICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3JcbiAgfTtcbiAgLy8gbGVnYWN5Li4uXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNCkgY3R4LmNvbG9ycyA9IGFyZ3VtZW50c1szXTtcbiAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuICAgIC8vIGxlZ2FjeS4uLlxuICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcbiAgfSBlbHNlIGlmIChvcHRzKSB7XG4gICAgLy8gZ290IGFuIFwib3B0aW9uc1wiIG9iamVjdFxuICAgIGV4cG9ydHMuX2V4dGVuZChjdHgsIG9wdHMpO1xuICB9XG4gIC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY29sb3JzKSkgY3R4LmNvbG9ycyA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG4gIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG4gIHJldHVybiBmb3JtYXRWYWx1ZShjdHgsIG9iaiwgY3R4LmRlcHRoKTtcbn1cbmV4cG9ydHMuaW5zcGVjdCA9IGluc3BlY3Q7XG5cblxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5pbnNwZWN0LmNvbG9ycyA9IHtcbiAgJ2JvbGQnIDogWzEsIDIyXSxcbiAgJ2l0YWxpYycgOiBbMywgMjNdLFxuICAndW5kZXJsaW5lJyA6IFs0LCAyNF0sXG4gICdpbnZlcnNlJyA6IFs3LCAyN10sXG4gICd3aGl0ZScgOiBbMzcsIDM5XSxcbiAgJ2dyZXknIDogWzkwLCAzOV0sXG4gICdibGFjaycgOiBbMzAsIDM5XSxcbiAgJ2JsdWUnIDogWzM0LCAzOV0sXG4gICdjeWFuJyA6IFszNiwgMzldLFxuICAnZ3JlZW4nIDogWzMyLCAzOV0sXG4gICdtYWdlbnRhJyA6IFszNSwgMzldLFxuICAncmVkJyA6IFszMSwgMzldLFxuICAneWVsbG93JyA6IFszMywgMzldXG59O1xuXG4vLyBEb24ndCB1c2UgJ2JsdWUnIG5vdCB2aXNpYmxlIG9uIGNtZC5leGVcbmluc3BlY3Quc3R5bGVzID0ge1xuICAnc3BlY2lhbCc6ICdjeWFuJyxcbiAgJ251bWJlcic6ICd5ZWxsb3cnLFxuICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuICAndW5kZWZpbmVkJzogJ2dyZXknLFxuICAnbnVsbCc6ICdib2xkJyxcbiAgJ3N0cmluZyc6ICdncmVlbicsXG4gICdkYXRlJzogJ21hZ2VudGEnLFxuICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuICAncmVnZXhwJzogJ3JlZCdcbn07XG5cblxuZnVuY3Rpb24gc3R5bGl6ZVdpdGhDb2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG4gIGlmIChzdHlsZSkge1xuICAgIHJldHVybiAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzBdICsgJ20nICsgc3RyICtcbiAgICAgICAgICAgJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVsxXSArICdtJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59XG5cblxuZnVuY3Rpb24gc3R5bGl6ZU5vQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgcmV0dXJuIHN0cjtcbn1cblxuXG5mdW5jdGlvbiBhcnJheVRvSGFzaChhcnJheSkge1xuICB2YXIgaGFzaCA9IHt9O1xuXG4gIGFycmF5LmZvckVhY2goZnVuY3Rpb24odmFsLCBpZHgpIHtcbiAgICBoYXNoW3ZhbF0gPSB0cnVlO1xuICB9KTtcblxuICByZXR1cm4gaGFzaDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKGN0eC5jdXN0b21JbnNwZWN0ICYmXG4gICAgICB2YWx1ZSAmJlxuICAgICAgaXNGdW5jdGlvbih2YWx1ZS5pbnNwZWN0KSAmJlxuICAgICAgLy8gRmlsdGVyIG91dCB0aGUgdXRpbCBtb2R1bGUsIGl0J3MgaW5zcGVjdCBmdW5jdGlvbiBpcyBzcGVjaWFsXG4gICAgICB2YWx1ZS5pbnNwZWN0ICE9PSBleHBvcnRzLmluc3BlY3QgJiZcbiAgICAgIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuICAgICAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcywgY3R4KTtcbiAgICBpZiAoIWlzU3RyaW5nKHJldCkpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuICB2YXIgdmlzaWJsZUtleXMgPSBhcnJheVRvSGFzaChrZXlzKTtcblxuICBpZiAoY3R4LnNob3dIaWRkZW4pIHtcbiAgICBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuICB9XG5cbiAgLy8gSUUgZG9lc24ndCBtYWtlIGVycm9yIGZpZWxkcyBub24tZW51bWVyYWJsZVxuICAvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvZHd3NTJzYnQodj12cy45NCkuYXNweFxuICBpZiAoaXNFcnJvcih2YWx1ZSlcbiAgICAgICYmIChrZXlzLmluZGV4T2YoJ21lc3NhZ2UnKSA+PSAwIHx8IGtleXMuaW5kZXhPZignZGVzY3JpcHRpb24nKSA+PSAwKSkge1xuICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICAvLyBTb21lIHR5cGUgb2Ygb2JqZWN0IHdpdGhvdXQgcHJvcGVydGllcyBjYW4gYmUgc2hvcnRjdXR0ZWQuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgICAgdmFyIG5hbWUgPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW0Z1bmN0aW9uJyArIG5hbWUgKyAnXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfVxuICAgIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdkYXRlJyk7XG4gICAgfVxuICAgIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB2YXIgYmFzZSA9ICcnLCBhcnJheSA9IGZhbHNlLCBicmFjZXMgPSBbJ3snLCAnfSddO1xuXG4gIC8vIE1ha2UgQXJyYXkgc2F5IHRoYXQgdGhleSBhcmUgQXJyYXlcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgYXJyYXkgPSB0cnVlO1xuICAgIGJyYWNlcyA9IFsnWycsICddJ107XG4gIH1cblxuICAvLyBNYWtlIGZ1bmN0aW9ucyBzYXkgdGhhdCB0aGV5IGFyZSBmdW5jdGlvbnNcbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgdmFyIG4gPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICBiYXNlID0gJyBbRnVuY3Rpb24nICsgbiArICddJztcbiAgfVxuXG4gIC8vIE1ha2UgUmVnRXhwcyBzYXkgdGhhdCB0aGV5IGFyZSBSZWdFeHBzXG4gIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZGF0ZXMgd2l0aCBwcm9wZXJ0aWVzIGZpcnN0IHNheSB0aGUgZGF0ZVxuICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZXJyb3Igd2l0aCBtZXNzYWdlIGZpcnN0IHNheSB0aGUgZXJyb3JcbiAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCAmJiAoIWFycmF5IHx8IHZhbHVlLmxlbmd0aCA9PSAwKSkge1xuICAgIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgYnJhY2VzWzFdO1xuICB9XG5cbiAgaWYgKHJlY3Vyc2VUaW1lcyA8IDApIHtcbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tPYmplY3RdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cblxuICBjdHguc2Vlbi5wdXNoKHZhbHVlKTtcblxuICB2YXIgb3V0cHV0O1xuICBpZiAoYXJyYXkpIHtcbiAgICBvdXRwdXQgPSBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKTtcbiAgfSBlbHNlIHtcbiAgICBvdXRwdXQgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KTtcbiAgICB9KTtcbiAgfVxuXG4gIGN0eC5zZWVuLnBvcCgpO1xuXG4gIHJldHVybiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBzaW1wbGUgPSAnXFwnJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC9eXCJ8XCIkL2csICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuICAgIHJldHVybiBjdHguc3R5bGl6ZShzaW1wbGUsICdzdHJpbmcnKTtcbiAgfVxuICBpZiAoaXNOdW1iZXIodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG4gIGlmIChpc0Jvb2xlYW4odmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpO1xuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmIChpc051bGwodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IodmFsdWUpIHtcbiAgcmV0dXJuICdbJyArIEVycm9yLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSArICddJztcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKSB7XG4gIHZhciBvdXRwdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkodmFsdWUsIFN0cmluZyhpKSkpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAgU3RyaW5nKGkpLCB0cnVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICB9XG4gIH1cbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0ciwgZGVzYztcbiAgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodmFsdWUsIGtleSkgfHwgeyB2YWx1ZTogdmFsdWVba2V5XSB9O1xuICBpZiAoZGVzYy5nZXQpIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmICghaGFzT3duUHJvcGVydHkodmlzaWJsZUtleXMsIGtleSkpIHtcbiAgICBuYW1lID0gJ1snICsga2V5ICsgJ10nO1xuICB9XG4gIGlmICghc3RyKSB7XG4gICAgaWYgKGN0eC5zZWVuLmluZGV4T2YoZGVzYy52YWx1ZSkgPCAwKSB7XG4gICAgICBpZiAoaXNOdWxsKHJlY3Vyc2VUaW1lcykpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpLnN1YnN0cigyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cblxuZnVuY3Rpb24gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpIHtcbiAgdmFyIG51bUxpbmVzRXN0ID0gMDtcbiAgdmFyIGxlbmd0aCA9IG91dHB1dC5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgY3VyKSB7XG4gICAgbnVtTGluZXNFc3QrKztcbiAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIG51bUxpbmVzRXN0Kys7XG4gICAgcmV0dXJuIHByZXYgKyBjdXIucmVwbGFjZSgvXFx1MDAxYlxcW1xcZFxcZD9tL2csICcnKS5sZW5ndGggKyAxO1xuICB9LCAwKTtcblxuICBpZiAobGVuZ3RoID4gNjApIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICtcbiAgICAgICAgICAgKGJhc2UgPT09ICcnID8gJycgOiBiYXNlICsgJ1xcbiAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIG91dHB1dC5qb2luKCcsXFxuICAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIGJyYWNlc1sxXTtcbiAgfVxuXG4gIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgJyAnICsgb3V0cHV0LmpvaW4oJywgJykgKyAnICcgKyBicmFjZXNbMV07XG59XG5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cbmZ1bmN0aW9uIGlzQXJyYXkoYXIpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXIpO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gaXNPYmplY3QocmUpICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gaXNPYmplY3QoZCkgJiYgb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGUpICYmXG4gICAgICAob2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXScgfHwgZSBpbnN0YW5jZW9mIEVycm9yKTtcbn1cbmV4cG9ydHMuaXNFcnJvciA9IGlzRXJyb3I7XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGwgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3ltYm9sJyB8fCAgLy8gRVM2IHN5bWJvbFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3VuZGVmaW5lZCc7XG59XG5leHBvcnRzLmlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmU7XG5cbmV4cG9ydHMuaXNCdWZmZXIgPSByZXF1aXJlKCcuL3N1cHBvcnQvaXNCdWZmZXInKTtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuXG5cbmZ1bmN0aW9uIHBhZChuKSB7XG4gIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuLnRvU3RyaW5nKDEwKSA6IG4udG9TdHJpbmcoMTApO1xufVxuXG5cbnZhciBtb250aHMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJyxcbiAgICAgICAgICAgICAgJ09jdCcsICdOb3YnLCAnRGVjJ107XG5cbi8vIDI2IEZlYiAxNjoxOTozNFxuZnVuY3Rpb24gdGltZXN0YW1wKCkge1xuICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gIHZhciB0aW1lID0gW3BhZChkLmdldEhvdXJzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRNaW51dGVzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRTZWNvbmRzKCkpXS5qb2luKCc6Jyk7XG4gIHJldHVybiBbZC5nZXREYXRlKCksIG1vbnRoc1tkLmdldE1vbnRoKCldLCB0aW1lXS5qb2luKCcgJyk7XG59XG5cblxuLy8gbG9nIGlzIGp1c3QgYSB0aGluIHdyYXBwZXIgdG8gY29uc29sZS5sb2cgdGhhdCBwcmVwZW5kcyBhIHRpbWVzdGFtcFxuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgY29uc29sZS5sb2coJyVzIC0gJXMnLCB0aW1lc3RhbXAoKSwgZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKSk7XG59O1xuXG5cbi8qKlxuICogSW5oZXJpdCB0aGUgcHJvdG90eXBlIG1ldGhvZHMgZnJvbSBvbmUgY29uc3RydWN0b3IgaW50byBhbm90aGVyLlxuICpcbiAqIFRoZSBGdW5jdGlvbi5wcm90b3R5cGUuaW5oZXJpdHMgZnJvbSBsYW5nLmpzIHJld3JpdHRlbiBhcyBhIHN0YW5kYWxvbmVcbiAqIGZ1bmN0aW9uIChub3Qgb24gRnVuY3Rpb24ucHJvdG90eXBlKS4gTk9URTogSWYgdGhpcyBmaWxlIGlzIHRvIGJlIGxvYWRlZFxuICogZHVyaW5nIGJvb3RzdHJhcHBpbmcgdGhpcyBmdW5jdGlvbiBuZWVkcyB0byBiZSByZXdyaXR0ZW4gdXNpbmcgc29tZSBuYXRpdmVcbiAqIGZ1bmN0aW9ucyBhcyBwcm90b3R5cGUgc2V0dXAgdXNpbmcgbm9ybWFsIEphdmFTY3JpcHQgZG9lcyBub3Qgd29yayBhc1xuICogZXhwZWN0ZWQgZHVyaW5nIGJvb3RzdHJhcHBpbmcgKHNlZSBtaXJyb3IuanMgaW4gcjExNDkwMykuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB3aGljaCBuZWVkcyB0byBpbmhlcml0IHRoZVxuICogICAgIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHN1cGVyQ3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB0byBpbmhlcml0IHByb3RvdHlwZSBmcm9tLlxuICovXG5leHBvcnRzLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuZXhwb3J0cy5fZXh0ZW5kID0gZnVuY3Rpb24ob3JpZ2luLCBhZGQpIHtcbiAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgYWRkIGlzbid0IGFuIG9iamVjdFxuICBpZiAoIWFkZCB8fCAhaXNPYmplY3QoYWRkKSkgcmV0dXJuIG9yaWdpbjtcblxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGFkZCk7XG4gIHZhciBpID0ga2V5cy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBvcmlnaW5ba2V5c1tpXV0gPSBhZGRba2V5c1tpXV07XG4gIH1cbiAgcmV0dXJuIG9yaWdpbjtcbn07XG5cbmZ1bmN0aW9uIGhhc093blByb3BlcnR5KG9iaiwgcHJvcCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vdXRpbC91dGlsLmpzXG4vLyBtb2R1bGUgaWQgPSAxNTRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLypcblxuV2ViTWlkaSB2Mi4yLjBcblxuV2ViTWlkaS5qcyBoZWxwcyB5b3UgdGFtZSB0aGUgV2ViIE1JREkgQVBJLiBTZW5kIGFuZCByZWNlaXZlIE1JREkgbWVzc2FnZXMgd2l0aCBlYXNlLiBDb250cm9sIGluc3RydW1lbnRzIHdpdGggdXNlci1mcmllbmRseSBmdW5jdGlvbnMgKHBsYXlOb3RlLCBzZW5kUGl0Y2hCZW5kLCBldGMuKS4gUmVhY3QgdG8gTUlESSBpbnB1dCB3aXRoIHNpbXBsZSBldmVudCBsaXN0ZW5lcnMgKG5vdGVvbiwgcGl0Y2hiZW5kLCBjb250cm9sY2hhbmdlLCBldGMuKS5cbmh0dHBzOi8vZ2l0aHViLmNvbS9kamlwY28vd2VibWlkaVxuXG5cblRoZSBNSVQgTGljZW5zZSAoTUlUKVxuXG5Db3B5cmlnaHQgKGMpIDIwMTUtMjAxOCwgSmVhbi1QaGlsaXBwZSBDw7R0w6lcblxuUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZFxuYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbixcbmluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsXG5zdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbmZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cblRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWxcbnBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUXG5OT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORFxuTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFU1xuT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOXG5DT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4qL1xuXG4hZnVuY3Rpb24oc2NvcGUpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIFdlYk1pZGkoKXtpZihXZWJNaWRpLnByb3RvdHlwZS5fc2luZ2xldG9uKXRocm93IG5ldyBFcnJvcihcIldlYk1pZGkgaXMgYSBzaW5nbGV0b24sIGl0IGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQgZGlyZWN0bHkuXCIpO1dlYk1pZGkucHJvdG90eXBlLl9zaW5nbGV0b249dGhpcyx0aGlzLl9pbnB1dHM9W10sdGhpcy5fb3V0cHV0cz1bXSx0aGlzLl91c2VySGFuZGxlcnM9e30sdGhpcy5fc3RhdGVDaGFuZ2VRdWV1ZT1bXSx0aGlzLl9wcm9jZXNzaW5nU3RhdGVDaGFuZ2U9ITEsdGhpcy5fbWlkaUludGVyZmFjZUV2ZW50cz1bXCJjb25uZWN0ZWRcIixcImRpc2Nvbm5lY3RlZFwiXSx0aGlzLl9ub3Rlcz1bXCJDXCIsXCJDI1wiLFwiRFwiLFwiRCNcIixcIkVcIixcIkZcIixcIkYjXCIsXCJHXCIsXCJHI1wiLFwiQVwiLFwiQSNcIixcIkJcIl0sdGhpcy5fc2VtaXRvbmVzPXtDOjAsRDoyLEU6NCxGOjUsRzo3LEE6OSxCOjExfSxPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0aGlzLHtNSURJX1NZU1RFTV9NRVNTQUdFUzp7dmFsdWU6e3N5c2V4OjI0MCx0aW1lY29kZToyNDEsc29uZ3Bvc2l0aW9uOjI0Mixzb25nc2VsZWN0OjI0Myx0dW5pbmdyZXF1ZXN0OjI0NixzeXNleGVuZDoyNDcsY2xvY2s6MjQ4LHN0YXJ0OjI1MCxcImNvbnRpbnVlXCI6MjUxLHN0b3A6MjUyLGFjdGl2ZXNlbnNpbmc6MjU0LHJlc2V0OjI1NSxtaWRpbWVzc2FnZTowLHVua25vd25zeXN0ZW1tZXNzYWdlOi0xfSx3cml0YWJsZTohMSxlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMX0sTUlESV9DSEFOTkVMX01FU1NBR0VTOnt2YWx1ZTp7bm90ZW9mZjo4LG5vdGVvbjo5LGtleWFmdGVydG91Y2g6MTAsY29udHJvbGNoYW5nZToxMSxjaGFubmVsbW9kZToxMSxwcm9ncmFtY2hhbmdlOjEyLGNoYW5uZWxhZnRlcnRvdWNoOjEzLHBpdGNoYmVuZDoxNH0sd3JpdGFibGU6ITEsZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITF9LE1JRElfUkVHSVNURVJFRF9QQVJBTUVURVI6e3ZhbHVlOntwaXRjaGJlbmRyYW5nZTpbMCwwXSxjaGFubmVsZmluZXR1bmluZzpbMCwxXSxjaGFubmVsY29hcnNldHVuaW5nOlswLDJdLHR1bmluZ3Byb2dyYW06WzAsM10sdHVuaW5nYmFuazpbMCw0XSxtb2R1bGF0aW9ucmFuZ2U6WzAsNV0sYXppbXV0aGFuZ2xlOls2MSwwXSxlbGV2YXRpb25hbmdsZTpbNjEsMV0sZ2FpbjpbNjEsMl0sZGlzdGFuY2VyYXRpbzpbNjEsM10sbWF4aW11bWRpc3RhbmNlOls2MSw0XSxtYXhpbXVtZGlzdGFuY2VnYWluOls2MSw1XSxyZWZlcmVuY2VkaXN0YW5jZXJhdGlvOls2MSw2XSxwYW5zcHJlYWRhbmdsZTpbNjEsN10scm9sbGFuZ2xlOls2MSw4XX0sd3JpdGFibGU6ITEsZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITF9LE1JRElfQ09OVFJPTF9DSEFOR0VfTUVTU0FHRVM6e3ZhbHVlOntiYW5rc2VsZWN0Y29hcnNlOjAsbW9kdWxhdGlvbndoZWVsY29hcnNlOjEsYnJlYXRoY29udHJvbGxlcmNvYXJzZToyLGZvb3Rjb250cm9sbGVyY29hcnNlOjQscG9ydGFtZW50b3RpbWVjb2Fyc2U6NSxkYXRhZW50cnljb2Fyc2U6Nix2b2x1bWVjb2Fyc2U6NyxiYWxhbmNlY29hcnNlOjgscGFuY29hcnNlOjEwLGV4cHJlc3Npb25jb2Fyc2U6MTEsZWZmZWN0Y29udHJvbDFjb2Fyc2U6MTIsZWZmZWN0Y29udHJvbDJjb2Fyc2U6MTMsZ2VuZXJhbHB1cnBvc2VzbGlkZXIxOjE2LGdlbmVyYWxwdXJwb3Nlc2xpZGVyMjoxNyxnZW5lcmFscHVycG9zZXNsaWRlcjM6MTgsZ2VuZXJhbHB1cnBvc2VzbGlkZXI0OjE5LGJhbmtzZWxlY3RmaW5lOjMyLG1vZHVsYXRpb253aGVlbGZpbmU6MzMsYnJlYXRoY29udHJvbGxlcmZpbmU6MzQsZm9vdGNvbnRyb2xsZXJmaW5lOjM2LHBvcnRhbWVudG90aW1lZmluZTozNyxkYXRhZW50cnlmaW5lOjM4LHZvbHVtZWZpbmU6MzksYmFsYW5jZWZpbmU6NDAscGFuZmluZTo0MixleHByZXNzaW9uZmluZTo0MyxlZmZlY3Rjb250cm9sMWZpbmU6NDQsZWZmZWN0Y29udHJvbDJmaW5lOjQ1LGhvbGRwZWRhbDo2NCxwb3J0YW1lbnRvOjY1LHN1c3RlbnV0b3BlZGFsOjY2LHNvZnRwZWRhbDo2NyxsZWdhdG9wZWRhbDo2OCxob2xkMnBlZGFsOjY5LHNvdW5kdmFyaWF0aW9uOjcwLHJlc29uYW5jZTo3MSxzb3VuZHJlbGVhc2V0aW1lOjcyLHNvdW5kYXR0YWNrdGltZTo3MyxicmlnaHRuZXNzOjc0LHNvdW5kY29udHJvbDY6NzUsc291bmRjb250cm9sNzo3Nixzb3VuZGNvbnRyb2w4Ojc3LHNvdW5kY29udHJvbDk6Nzgsc291bmRjb250cm9sMTA6NzksZ2VuZXJhbHB1cnBvc2VidXR0b24xOjgwLGdlbmVyYWxwdXJwb3NlYnV0dG9uMjo4MSxnZW5lcmFscHVycG9zZWJ1dHRvbjM6ODIsZ2VuZXJhbHB1cnBvc2VidXR0b240OjgzLHJldmVyYmxldmVsOjkxLHRyZW1vbG9sZXZlbDo5MixjaG9ydXNsZXZlbDo5MyxjZWxlc3RlbGV2ZWw6OTQscGhhc2VybGV2ZWw6OTUsZGF0YWJ1dHRvbmluY3JlbWVudDo5NixkYXRhYnV0dG9uZGVjcmVtZW50Ojk3LG5vbnJlZ2lzdGVyZWRwYXJhbWV0ZXJjb2Fyc2U6OTgsbm9ucmVnaXN0ZXJlZHBhcmFtZXRlcmZpbmU6OTkscmVnaXN0ZXJlZHBhcmFtZXRlcmNvYXJzZToxMDAscmVnaXN0ZXJlZHBhcmFtZXRlcmZpbmU6MTAxfSx3cml0YWJsZTohMSxlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMX0sTUlESV9DSEFOTkVMX01PREVfTUVTU0FHRVM6e3ZhbHVlOnthbGxzb3VuZG9mZjoxMjAscmVzZXRhbGxjb250cm9sbGVyczoxMjEsbG9jYWxjb250cm9sOjEyMixhbGxub3Rlc29mZjoxMjMsb21uaW1vZGVvZmY6MTI0LG9tbmltb2Rlb246MTI1LG1vbm9tb2Rlb246MTI2LHBvbHltb2Rlb246MTI3fSx3cml0YWJsZTohMSxlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMX0sb2N0YXZlT2Zmc2V0Ont2YWx1ZTowLHdyaXRhYmxlOiEwLGVudW1lcmFibGU6ITAsY29uZmlndXJhYmxlOiExfX0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMse3N1cHBvcnRlZDp7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm5cInJlcXVlc3RNSURJQWNjZXNzXCJpbiBuYXZpZ2F0b3J9fSxlbmFibGVkOntlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB2b2lkIDAhPT10aGlzW1wiaW50ZXJmYWNlXCJdfS5iaW5kKHRoaXMpfSxpbnB1dHM6e2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX2lucHV0c30uYmluZCh0aGlzKX0sb3V0cHV0czp7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fb3V0cHV0c30uYmluZCh0aGlzKX0sc3lzZXhFbmFibGVkOntlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiEoIXRoaXNbXCJpbnRlcmZhY2VcIl18fCF0aGlzW1wiaW50ZXJmYWNlXCJdLnN5c2V4RW5hYmxlZCl9LmJpbmQodGhpcyl9LHRpbWU6e2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHBlcmZvcm1hbmNlLm5vdygpfX19KX1mdW5jdGlvbiBJbnB1dChtaWRpSW5wdXQpe3ZhciB0aGF0PXRoaXM7dGhpcy5fdXNlckhhbmRsZXJzPXtjaGFubmVsOnt9LHN5c3RlbTp7fX0sdGhpcy5fbWlkaUlucHV0PW1pZGlJbnB1dCxPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0aGlzLHtjb25uZWN0aW9uOntlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0aGF0Ll9taWRpSW5wdXQuY29ubmVjdGlvbn19LGlkOntlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0aGF0Ll9taWRpSW5wdXQuaWR9fSxtYW51ZmFjdHVyZXI6e2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoYXQuX21pZGlJbnB1dC5tYW51ZmFjdHVyZXJ9fSxuYW1lOntlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0aGF0Ll9taWRpSW5wdXQubmFtZX19LHN0YXRlOntlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0aGF0Ll9taWRpSW5wdXQuc3RhdGV9fSx0eXBlOntlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0aGF0Ll9taWRpSW5wdXQudHlwZX19fSksdGhpcy5faW5pdGlhbGl6ZVVzZXJIYW5kbGVycygpLHRoaXMuX21pZGlJbnB1dC5vbm1pZGltZXNzYWdlPXRoaXMuX29uTWlkaU1lc3NhZ2UuYmluZCh0aGlzKX1mdW5jdGlvbiBPdXRwdXQobWlkaU91dHB1dCl7dmFyIHRoYXQ9dGhpczt0aGlzLl9taWRpT3V0cHV0PW1pZGlPdXRwdXQsT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcyx7Y29ubmVjdGlvbjp7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhhdC5fbWlkaU91dHB1dC5jb25uZWN0aW9ufX0saWQ6e2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoYXQuX21pZGlPdXRwdXQuaWR9fSxtYW51ZmFjdHVyZXI6e2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoYXQuX21pZGlPdXRwdXQubWFudWZhY3R1cmVyfX0sbmFtZTp7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhhdC5fbWlkaU91dHB1dC5uYW1lfX0sc3RhdGU6e2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoYXQuX21pZGlPdXRwdXQuc3RhdGV9fSx0eXBlOntlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0aGF0Ll9taWRpT3V0cHV0LnR5cGV9fX0pfXZhciB3bT1uZXcgV2ViTWlkaTtXZWJNaWRpLnByb3RvdHlwZS5lbmFibGU9ZnVuY3Rpb24oY2FsbGJhY2ssc3lzZXgpe3JldHVybiB0aGlzLmVuYWJsZWQ/dm9pZCAwOnRoaXMuc3VwcG9ydGVkP3ZvaWQgbmF2aWdhdG9yLnJlcXVlc3RNSURJQWNjZXNzKHtzeXNleDpzeXNleH0pLnRoZW4oZnVuY3Rpb24obWlkaUFjY2Vzcyl7ZnVuY3Rpb24gb25Qb3J0c09wZW4oKXtjbGVhclRpbWVvdXQocHJvbWlzZVRpbWVvdXQpLHRoaXMuX3VwZGF0ZUlucHV0c0FuZE91dHB1dHMoKSx0aGlzW1wiaW50ZXJmYWNlXCJdLm9uc3RhdGVjaGFuZ2U9dGhpcy5fb25JbnRlcmZhY2VTdGF0ZUNoYW5nZS5iaW5kKHRoaXMpLFwiZnVuY3Rpb25cIj09dHlwZW9mIGNhbGxiYWNrJiZjYWxsYmFjay5jYWxsKHRoaXMpLGV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGV2ZW50KXt0aGlzLl9vbkludGVyZmFjZVN0YXRlQ2hhbmdlKGV2ZW50KX0uYmluZCh0aGlzKSl9dmFyIHByb21pc2VUaW1lb3V0LGV2ZW50cz1bXSxwcm9taXNlcz1bXTt0aGlzW1wiaW50ZXJmYWNlXCJdPW1pZGlBY2Nlc3MsdGhpcy5fcmVzZXRJbnRlcmZhY2VVc2VySGFuZGxlcnMoKSx0aGlzW1wiaW50ZXJmYWNlXCJdLm9uc3RhdGVjaGFuZ2U9ZnVuY3Rpb24oZSl7ZXZlbnRzLnB1c2goZSl9O2Zvcih2YXIgaW5wdXRzPW1pZGlBY2Nlc3MuaW5wdXRzLnZhbHVlcygpLGlucHV0PWlucHV0cy5uZXh0KCk7aW5wdXQmJiFpbnB1dC5kb25lO2lucHV0PWlucHV0cy5uZXh0KCkpcHJvbWlzZXMucHVzaChpbnB1dC52YWx1ZS5vcGVuKCkpO2Zvcih2YXIgb3V0cHV0cz1taWRpQWNjZXNzLm91dHB1dHMudmFsdWVzKCksb3V0cHV0PW91dHB1dHMubmV4dCgpO291dHB1dCYmIW91dHB1dC5kb25lO291dHB1dD1vdXRwdXRzLm5leHQoKSlwcm9taXNlcy5wdXNoKG91dHB1dC52YWx1ZS5vcGVuKCkpO3Byb21pc2VUaW1lb3V0PXNldFRpbWVvdXQob25Qb3J0c09wZW4uYmluZCh0aGlzKSwyMDApLFByb21pc2UmJlByb21pc2UuYWxsKHByb21pc2VzKVtcImNhdGNoXCJdKGZ1bmN0aW9uKGVycil7fSkudGhlbihvblBvcnRzT3Blbi5iaW5kKHRoaXMpKX0uYmluZCh0aGlzKSxmdW5jdGlvbihlcnIpe1wiZnVuY3Rpb25cIj09dHlwZW9mIGNhbGxiYWNrJiZjYWxsYmFjay5jYWxsKHRoaXMsZXJyKX0uYmluZCh0aGlzKSk6dm9pZChcImZ1bmN0aW9uXCI9PXR5cGVvZiBjYWxsYmFjayYmY2FsbGJhY2sobmV3IEVycm9yKFwiVGhlIFdlYiBNSURJIEFQSSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHlvdXIgYnJvd3Nlci5cIikpKX0sV2ViTWlkaS5wcm90b3R5cGUuZGlzYWJsZT1mdW5jdGlvbigpe2lmKCF0aGlzLnN1cHBvcnRlZCl0aHJvdyBuZXcgRXJyb3IoXCJUaGUgV2ViIE1JREkgQVBJIGlzIG5vdCBzdXBwb3J0ZWQgYnkgeW91ciBicm93c2VyLlwiKTt0aGlzW1wiaW50ZXJmYWNlXCJdJiYodGhpc1tcImludGVyZmFjZVwiXS5vbnN0YXRlY2hhbmdlPXZvaWQgMCksdGhpc1tcImludGVyZmFjZVwiXT12b2lkIDAsdGhpcy5faW5wdXRzPVtdLHRoaXMuX291dHB1dHM9W10sdGhpcy5fcmVzZXRJbnRlcmZhY2VVc2VySGFuZGxlcnMoKX0sV2ViTWlkaS5wcm90b3R5cGUuYWRkTGlzdGVuZXI9ZnVuY3Rpb24odHlwZSxsaXN0ZW5lcil7aWYoIXRoaXMuZW5hYmxlZCl0aHJvdyBuZXcgRXJyb3IoXCJXZWJNaWRpIG11c3QgYmUgZW5hYmxlZCBiZWZvcmUgYWRkaW5nIGV2ZW50IGxpc3RlbmVycy5cIik7aWYoXCJmdW5jdGlvblwiIT10eXBlb2YgbGlzdGVuZXIpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlRoZSAnbGlzdGVuZXInIHBhcmFtZXRlciBtdXN0IGJlIGEgZnVuY3Rpb24uXCIpO2lmKCEodGhpcy5fbWlkaUludGVyZmFjZUV2ZW50cy5pbmRleE9mKHR5cGUpPj0wKSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiVGhlIHNwZWNpZmllZCBldmVudCB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQuXCIpO3JldHVybiB0aGlzLl91c2VySGFuZGxlcnNbdHlwZV0ucHVzaChsaXN0ZW5lciksdGhpc30sV2ViTWlkaS5wcm90b3R5cGUuaGFzTGlzdGVuZXI9ZnVuY3Rpb24odHlwZSxsaXN0ZW5lcil7aWYoIXRoaXMuZW5hYmxlZCl0aHJvdyBuZXcgRXJyb3IoXCJXZWJNaWRpIG11c3QgYmUgZW5hYmxlZCBiZWZvcmUgY2hlY2tpbmcgZXZlbnQgbGlzdGVuZXJzLlwiKTtpZihcImZ1bmN0aW9uXCIhPXR5cGVvZiBsaXN0ZW5lcil0aHJvdyBuZXcgVHlwZUVycm9yKFwiVGhlICdsaXN0ZW5lcicgcGFyYW1ldGVyIG11c3QgYmUgYSBmdW5jdGlvbi5cIik7aWYoISh0aGlzLl9taWRpSW50ZXJmYWNlRXZlbnRzLmluZGV4T2YodHlwZSk+PTApKXRocm93IG5ldyBUeXBlRXJyb3IoXCJUaGUgc3BlY2lmaWVkIGV2ZW50IHR5cGUgaXMgbm90IHN1cHBvcnRlZC5cIik7Zm9yKHZhciBvPTA7bzx0aGlzLl91c2VySGFuZGxlcnNbdHlwZV0ubGVuZ3RoO28rKylpZih0aGlzLl91c2VySGFuZGxlcnNbdHlwZV1bb109PT1saXN0ZW5lcilyZXR1cm4hMDtyZXR1cm4hMX0sV2ViTWlkaS5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXI9ZnVuY3Rpb24odHlwZSxsaXN0ZW5lcil7aWYoIXRoaXMuZW5hYmxlZCl0aHJvdyBuZXcgRXJyb3IoXCJXZWJNaWRpIG11c3QgYmUgZW5hYmxlZCBiZWZvcmUgcmVtb3ZpbmcgZXZlbnQgbGlzdGVuZXJzLlwiKTtpZih2b2lkIDAhPT1saXN0ZW5lciYmXCJmdW5jdGlvblwiIT10eXBlb2YgbGlzdGVuZXIpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlRoZSAnbGlzdGVuZXInIHBhcmFtZXRlciBtdXN0IGJlIGEgZnVuY3Rpb24uXCIpO2lmKHRoaXMuX21pZGlJbnRlcmZhY2VFdmVudHMuaW5kZXhPZih0eXBlKT49MClpZihsaXN0ZW5lcilmb3IodmFyIG89MDtvPHRoaXMuX3VzZXJIYW5kbGVyc1t0eXBlXS5sZW5ndGg7bysrKXRoaXMuX3VzZXJIYW5kbGVyc1t0eXBlXVtvXT09PWxpc3RlbmVyJiZ0aGlzLl91c2VySGFuZGxlcnNbdHlwZV0uc3BsaWNlKG8sMSk7ZWxzZSB0aGlzLl91c2VySGFuZGxlcnNbdHlwZV09W107ZWxzZXtpZih2b2lkIDAhPT10eXBlKXRocm93IG5ldyBUeXBlRXJyb3IoXCJUaGUgc3BlY2lmaWVkIGV2ZW50IHR5cGUgaXMgbm90IHN1cHBvcnRlZC5cIik7dGhpcy5fcmVzZXRJbnRlcmZhY2VVc2VySGFuZGxlcnMoKX1yZXR1cm4gdGhpc30sV2ViTWlkaS5wcm90b3R5cGUudG9NSURJQ2hhbm5lbHM9ZnVuY3Rpb24oY2hhbm5lbCl7dmFyIGNoYW5uZWxzO3JldHVybiBjaGFubmVscz1cImFsbFwiPT09Y2hhbm5lbHx8dm9pZCAwPT09Y2hhbm5lbD9bXCJhbGxcIl06QXJyYXkuaXNBcnJheShjaGFubmVsKT9jaGFubmVsOltjaGFubmVsXSxjaGFubmVscy5pbmRleE9mKFwiYWxsXCIpPi0xJiYoY2hhbm5lbHM9WzEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2XSksY2hhbm5lbHMubWFwKGZ1bmN0aW9uKGNoKXtyZXR1cm4gcGFyc2VJbnQoY2gpfSkuZmlsdGVyKGZ1bmN0aW9uKGNoKXtyZXR1cm4gY2g+PTEmJjE2Pj1jaH0pfSxXZWJNaWRpLnByb3RvdHlwZS5nZXRJbnB1dEJ5SWQ9ZnVuY3Rpb24oaWQpe2lmKCF0aGlzLmVuYWJsZWQpdGhyb3cgbmV3IEVycm9yKFwiV2ViTWlkaSBpcyBub3QgZW5hYmxlZC5cIik7Zm9yKHZhciBpPTA7aTx0aGlzLmlucHV0cy5sZW5ndGg7aSsrKWlmKHRoaXMuaW5wdXRzW2ldLmlkPT09aWQpcmV0dXJuIHRoaXMuaW5wdXRzW2ldO3JldHVybiExfSxXZWJNaWRpLnByb3RvdHlwZS5nZXRPdXRwdXRCeUlkPWZ1bmN0aW9uKGlkKXtpZighdGhpcy5lbmFibGVkKXRocm93IG5ldyBFcnJvcihcIldlYk1pZGkgaXMgbm90IGVuYWJsZWQuXCIpO2Zvcih2YXIgaT0wO2k8dGhpcy5vdXRwdXRzLmxlbmd0aDtpKyspaWYodGhpcy5vdXRwdXRzW2ldLmlkPT09aWQpcmV0dXJuIHRoaXMub3V0cHV0c1tpXTtyZXR1cm4hMX0sV2ViTWlkaS5wcm90b3R5cGUuZ2V0SW5wdXRCeU5hbWU9ZnVuY3Rpb24obmFtZSl7aWYoIXRoaXMuZW5hYmxlZCl0aHJvdyBuZXcgRXJyb3IoXCJXZWJNaWRpIGlzIG5vdCBlbmFibGVkLlwiKTtmb3IodmFyIGk9MDtpPHRoaXMuaW5wdXRzLmxlbmd0aDtpKyspaWYofnRoaXMuaW5wdXRzW2ldLm5hbWUuaW5kZXhPZihuYW1lKSlyZXR1cm4gdGhpcy5pbnB1dHNbaV07cmV0dXJuITF9LFdlYk1pZGkucHJvdG90eXBlLmdldE9jdGF2ZT1mdW5jdGlvbihudW1iZXIpe3JldHVybiBudWxsIT1udW1iZXImJm51bWJlcj49MCYmMTI3Pj1udW1iZXI/TWF0aC5mbG9vcihNYXRoLmZsb29yKG51bWJlcikvMTItMSkrTWF0aC5mbG9vcih3bS5vY3RhdmVPZmZzZXQpOnZvaWQgMH0sV2ViTWlkaS5wcm90b3R5cGUuZ2V0T3V0cHV0QnlOYW1lPWZ1bmN0aW9uKG5hbWUpe2lmKCF0aGlzLmVuYWJsZWQpdGhyb3cgbmV3IEVycm9yKFwiV2ViTWlkaSBpcyBub3QgZW5hYmxlZC5cIik7Zm9yKHZhciBpPTA7aTx0aGlzLm91dHB1dHMubGVuZ3RoO2krKylpZih+dGhpcy5vdXRwdXRzW2ldLm5hbWUuaW5kZXhPZihuYW1lKSlyZXR1cm4gdGhpcy5vdXRwdXRzW2ldO3JldHVybiExfSxXZWJNaWRpLnByb3RvdHlwZS5ndWVzc05vdGVOdW1iZXI9ZnVuY3Rpb24oaW5wdXQpe3ZhciBvdXRwdXQ9ITE7aWYoaW5wdXQmJmlucHV0LnRvRml4ZWQmJmlucHV0Pj0wJiYxMjc+PWlucHV0P291dHB1dD1NYXRoLnJvdW5kKGlucHV0KTpwYXJzZUludChpbnB1dCk+PTAmJnBhcnNlSW50KGlucHV0KTw9MTI3P291dHB1dD1wYXJzZUludChpbnB1dCk6KFwic3RyaW5nXCI9PXR5cGVvZiBpbnB1dHx8aW5wdXQgaW5zdGFuY2VvZiBTdHJpbmcpJiYob3V0cHV0PXRoaXMubm90ZU5hbWVUb051bWJlcihpbnB1dCkpLG91dHB1dD09PSExKXRocm93IG5ldyBFcnJvcihcIkludmFsaWQgaW5wdXQgdmFsdWUgKFwiK2lucHV0K1wiKS5cIik7cmV0dXJuIG91dHB1dH0sV2ViTWlkaS5wcm90b3R5cGUubm90ZU5hbWVUb051bWJlcj1mdW5jdGlvbihuYW1lKXtcInN0cmluZ1wiIT10eXBlb2YgbmFtZSYmKG5hbWU9XCJcIik7dmFyIG1hdGNoZXM9bmFtZS5tYXRjaCgvKFtDREVGR0FCXSkoI3swLDJ9fGJ7MCwyfSkoLT9cXGQrKS9pKTtpZighbWF0Y2hlcyl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgbm90ZSBuYW1lLlwiKTt2YXIgc2VtaXRvbmVzPXdtLl9zZW1pdG9uZXNbbWF0Y2hlc1sxXS50b1VwcGVyQ2FzZSgpXSxvY3RhdmU9cGFyc2VJbnQobWF0Y2hlc1szXSkscmVzdWx0PTEyKihvY3RhdmUrMS1NYXRoLmZsb29yKHdtLm9jdGF2ZU9mZnNldCkpK3NlbWl0b25lcztpZihtYXRjaGVzWzJdLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihcImJcIik+LTE/cmVzdWx0LT1tYXRjaGVzWzJdLmxlbmd0aDptYXRjaGVzWzJdLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihcIiNcIik+LTEmJihyZXN1bHQrPW1hdGNoZXNbMl0ubGVuZ3RoKSwwPnJlc3VsdHx8cmVzdWx0PjEyNyl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgbm90ZSBuYW1lIG9yIG5vdGUgb3V0c2lkZSB2YWxpZCByYW5nZS5cIik7cmV0dXJuIHJlc3VsdH0sV2ViTWlkaS5wcm90b3R5cGUuX3VwZGF0ZUlucHV0c0FuZE91dHB1dHM9ZnVuY3Rpb24oKXt0aGlzLl91cGRhdGVJbnB1dHMoKSx0aGlzLl91cGRhdGVPdXRwdXRzKCl9LFdlYk1pZGkucHJvdG90eXBlLl91cGRhdGVJbnB1dHM9ZnVuY3Rpb24oKXtmb3IodmFyIGk9MDtpPHRoaXMuX2lucHV0cy5sZW5ndGg7aSsrKXtmb3IodmFyIHJlbW92ZT0hMCx1cGRhdGVkPXRoaXNbXCJpbnRlcmZhY2VcIl0uaW5wdXRzLnZhbHVlcygpLGlucHV0PXVwZGF0ZWQubmV4dCgpO2lucHV0JiYhaW5wdXQuZG9uZTtpbnB1dD11cGRhdGVkLm5leHQoKSlpZih0aGlzLl9pbnB1dHNbaV0uX21pZGlJbnB1dD09PWlucHV0LnZhbHVlKXtyZW1vdmU9ITE7YnJlYWt9cmVtb3ZlJiZ0aGlzLl9pbnB1dHMuc3BsaWNlKGksMSl9dGhpc1tcImludGVyZmFjZVwiXSYmdGhpc1tcImludGVyZmFjZVwiXS5pbnB1dHMuZm9yRWFjaChmdW5jdGlvbihuSW5wdXQpe2Zvcih2YXIgYWRkPSEwLGo9MDtqPHRoaXMuX2lucHV0cy5sZW5ndGg7aisrKXRoaXMuX2lucHV0c1tqXS5fbWlkaUlucHV0PT09bklucHV0JiYoYWRkPSExKTthZGQmJnRoaXMuX2lucHV0cy5wdXNoKG5ldyBJbnB1dChuSW5wdXQpKX0uYmluZCh0aGlzKSl9LFdlYk1pZGkucHJvdG90eXBlLl91cGRhdGVPdXRwdXRzPWZ1bmN0aW9uKCl7Zm9yKHZhciBpPTA7aTx0aGlzLl9vdXRwdXRzLmxlbmd0aDtpKyspe2Zvcih2YXIgcmVtb3ZlPSEwLHVwZGF0ZWQ9dGhpc1tcImludGVyZmFjZVwiXS5vdXRwdXRzLnZhbHVlcygpLG91dHB1dD11cGRhdGVkLm5leHQoKTtvdXRwdXQmJiFvdXRwdXQuZG9uZTtvdXRwdXQ9dXBkYXRlZC5uZXh0KCkpaWYodGhpcy5fb3V0cHV0c1tpXS5fbWlkaU91dHB1dD09PW91dHB1dC52YWx1ZSl7cmVtb3ZlPSExO2JyZWFrfXJlbW92ZSYmdGhpcy5fb3V0cHV0cy5zcGxpY2UoaSwxKX10aGlzW1wiaW50ZXJmYWNlXCJdJiZ0aGlzW1wiaW50ZXJmYWNlXCJdLm91dHB1dHMuZm9yRWFjaChmdW5jdGlvbihuT3V0cHV0KXtmb3IodmFyIGFkZD0hMCxqPTA7ajx0aGlzLl9vdXRwdXRzLmxlbmd0aDtqKyspdGhpcy5fb3V0cHV0c1tqXS5fbWlkaU91dHB1dD09PW5PdXRwdXQmJihhZGQ9ITEpO2FkZCYmdGhpcy5fb3V0cHV0cy5wdXNoKG5ldyBPdXRwdXQobk91dHB1dCkpfS5iaW5kKHRoaXMpKX0sV2ViTWlkaS5wcm90b3R5cGUuX29uSW50ZXJmYWNlU3RhdGVDaGFuZ2U9ZnVuY3Rpb24oZSl7dGhpcy5fdXBkYXRlSW5wdXRzQW5kT3V0cHV0cygpO3ZhciBldmVudD17dGltZXN0YW1wOmUudGltZVN0YW1wLHR5cGU6ZS5wb3J0LnN0YXRlfTt0aGlzW1wiaW50ZXJmYWNlXCJdJiZcImNvbm5lY3RlZFwiPT09ZS5wb3J0LnN0YXRlP1wib3V0cHV0XCI9PT1lLnBvcnQudHlwZT9ldmVudC5wb3J0PXRoaXMuZ2V0T3V0cHV0QnlJZChlLnBvcnQuaWQpOlwiaW5wdXRcIj09PWUucG9ydC50eXBlJiYoZXZlbnQucG9ydD10aGlzLmdldElucHV0QnlJZChlLnBvcnQuaWQpKTpldmVudC5wb3J0PXtjb25uZWN0aW9uOlwiY2xvc2VkXCIsaWQ6ZS5wb3J0LmlkLG1hbnVmYWN0dXJlcjplLnBvcnQubWFudWZhY3R1cmVyLG5hbWU6ZS5wb3J0Lm5hbWUsc3RhdGU6ZS5wb3J0LnN0YXRlLHR5cGU6ZS5wb3J0LnR5cGV9LHRoaXMuX3VzZXJIYW5kbGVyc1tlLnBvcnQuc3RhdGVdLmZvckVhY2goZnVuY3Rpb24oaGFuZGxlcil7aGFuZGxlcihldmVudCl9KX0sV2ViTWlkaS5wcm90b3R5cGUuX3Jlc2V0SW50ZXJmYWNlVXNlckhhbmRsZXJzPWZ1bmN0aW9uKCl7Zm9yKHZhciBpPTA7aTx0aGlzLl9taWRpSW50ZXJmYWNlRXZlbnRzLmxlbmd0aDtpKyspdGhpcy5fdXNlckhhbmRsZXJzW3RoaXMuX21pZGlJbnRlcmZhY2VFdmVudHNbaV1dPVtdfSxJbnB1dC5wcm90b3R5cGUuYWRkTGlzdGVuZXI9ZnVuY3Rpb24odHlwZSxjaGFubmVsLGxpc3RlbmVyKXt2YXIgdGhhdD10aGlzO2lmKHZvaWQgMD09PWNoYW5uZWwmJihjaGFubmVsPVwiYWxsXCIpLEFycmF5LmlzQXJyYXkoY2hhbm5lbCl8fChjaGFubmVsPVtjaGFubmVsXSksY2hhbm5lbC5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0pe2lmKFwiYWxsXCIhPT1pdGVtJiYhKGl0ZW0+PTEmJjE2Pj1pdGVtKSl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlRoZSAnY2hhbm5lbCcgcGFyYW1ldGVyIGlzIGludmFsaWQuXCIpfSksXCJmdW5jdGlvblwiIT10eXBlb2YgbGlzdGVuZXIpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlRoZSAnbGlzdGVuZXInIHBhcmFtZXRlciBtdXN0IGJlIGEgZnVuY3Rpb24uXCIpO2lmKHZvaWQgMCE9PXdtLk1JRElfU1lTVEVNX01FU1NBR0VTW3R5cGVdKXRoaXMuX3VzZXJIYW5kbGVycy5zeXN0ZW1bdHlwZV18fCh0aGlzLl91c2VySGFuZGxlcnMuc3lzdGVtW3R5cGVdPVtdKSx0aGlzLl91c2VySGFuZGxlcnMuc3lzdGVtW3R5cGVdLnB1c2gobGlzdGVuZXIpO2Vsc2V7aWYodm9pZCAwPT09d20uTUlESV9DSEFOTkVMX01FU1NBR0VTW3R5cGVdKXRocm93IG5ldyBUeXBlRXJyb3IoXCJUaGUgc3BlY2lmaWVkIGV2ZW50IHR5cGUgaXMgbm90IHN1cHBvcnRlZC5cIik7aWYoY2hhbm5lbC5pbmRleE9mKFwiYWxsXCIpPi0xKXtjaGFubmVsPVtdO2Zvcih2YXIgaj0xOzE2Pj1qO2orKyljaGFubmVsLnB1c2goail9dGhpcy5fdXNlckhhbmRsZXJzLmNoYW5uZWxbdHlwZV18fCh0aGlzLl91c2VySGFuZGxlcnMuY2hhbm5lbFt0eXBlXT1bXSksY2hhbm5lbC5mb3JFYWNoKGZ1bmN0aW9uKGNoKXt0aGF0Ll91c2VySGFuZGxlcnMuY2hhbm5lbFt0eXBlXVtjaF18fCh0aGF0Ll91c2VySGFuZGxlcnMuY2hhbm5lbFt0eXBlXVtjaF09W10pLHRoYXQuX3VzZXJIYW5kbGVycy5jaGFubmVsW3R5cGVdW2NoXS5wdXNoKGxpc3RlbmVyKX0pfXJldHVybiB0aGlzfSxJbnB1dC5wcm90b3R5cGUub249SW5wdXQucHJvdG90eXBlLmFkZExpc3RlbmVyLElucHV0LnByb3RvdHlwZS5oYXNMaXN0ZW5lcj1mdW5jdGlvbih0eXBlLGNoYW5uZWwsbGlzdGVuZXIpe3ZhciB0aGF0PXRoaXM7aWYoXCJmdW5jdGlvblwiIT10eXBlb2YgbGlzdGVuZXIpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlRoZSAnbGlzdGVuZXInIHBhcmFtZXRlciBtdXN0IGJlIGEgZnVuY3Rpb24uXCIpO2lmKHZvaWQgMD09PWNoYW5uZWwmJihjaGFubmVsPVwiYWxsXCIpLGNoYW5uZWwuY29uc3RydWN0b3IhPT1BcnJheSYmKGNoYW5uZWw9W2NoYW5uZWxdKSx2b2lkIDAhPT13bS5NSURJX1NZU1RFTV9NRVNTQUdFU1t0eXBlXSl7Zm9yKHZhciBvPTA7bzx0aGlzLl91c2VySGFuZGxlcnMuc3lzdGVtW3R5cGVdLmxlbmd0aDtvKyspaWYodGhpcy5fdXNlckhhbmRsZXJzLnN5c3RlbVt0eXBlXVtvXT09PWxpc3RlbmVyKXJldHVybiEwfWVsc2UgaWYodm9pZCAwIT09d20uTUlESV9DSEFOTkVMX01FU1NBR0VTW3R5cGVdKXtpZihjaGFubmVsLmluZGV4T2YoXCJhbGxcIik+LTEpe2NoYW5uZWw9W107Zm9yKHZhciBqPTE7MTY+PWo7aisrKWNoYW5uZWwucHVzaChqKX1yZXR1cm4gdGhpcy5fdXNlckhhbmRsZXJzLmNoYW5uZWxbdHlwZV0/Y2hhbm5lbC5ldmVyeShmdW5jdGlvbihjaE51bSl7dmFyIGxpc3RlbmVycz10aGF0Ll91c2VySGFuZGxlcnMuY2hhbm5lbFt0eXBlXVtjaE51bV07cmV0dXJuIGxpc3RlbmVycyYmbGlzdGVuZXJzLmluZGV4T2YobGlzdGVuZXIpPi0xfSk6ITF9cmV0dXJuITF9LElucHV0LnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lcj1mdW5jdGlvbih0eXBlLGNoYW5uZWwsbGlzdGVuZXIpe3ZhciB0aGF0PXRoaXM7aWYodm9pZCAwIT09bGlzdGVuZXImJlwiZnVuY3Rpb25cIiE9dHlwZW9mIGxpc3RlbmVyKXRocm93IG5ldyBUeXBlRXJyb3IoXCJUaGUgJ2xpc3RlbmVyJyBwYXJhbWV0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uLlwiKTtpZih2b2lkIDA9PT1jaGFubmVsJiYoY2hhbm5lbD1cImFsbFwiKSxjaGFubmVsLmNvbnN0cnVjdG9yIT09QXJyYXkmJihjaGFubmVsPVtjaGFubmVsXSksdm9pZCAwIT09d20uTUlESV9TWVNURU1fTUVTU0FHRVNbdHlwZV0paWYodm9pZCAwPT09bGlzdGVuZXIpdGhpcy5fdXNlckhhbmRsZXJzLnN5c3RlbVt0eXBlXT1bXTtlbHNlIGZvcih2YXIgbz0wO288dGhpcy5fdXNlckhhbmRsZXJzLnN5c3RlbVt0eXBlXS5sZW5ndGg7bysrKXRoaXMuX3VzZXJIYW5kbGVycy5zeXN0ZW1bdHlwZV1bb109PT1saXN0ZW5lciYmdGhpcy5fdXNlckhhbmRsZXJzLnN5c3RlbVt0eXBlXS5zcGxpY2UobywxKTtlbHNlIGlmKHZvaWQgMCE9PXdtLk1JRElfQ0hBTk5FTF9NRVNTQUdFU1t0eXBlXSl7aWYoY2hhbm5lbC5pbmRleE9mKFwiYWxsXCIpPi0xKXtjaGFubmVsPVtdO2Zvcih2YXIgaj0xOzE2Pj1qO2orKyljaGFubmVsLnB1c2goail9aWYoIXRoaXMuX3VzZXJIYW5kbGVycy5jaGFubmVsW3R5cGVdKXJldHVybiB0aGlzO2NoYW5uZWwuZm9yRWFjaChmdW5jdGlvbihjaE51bSl7dmFyIGxpc3RlbmVycz10aGF0Ll91c2VySGFuZGxlcnMuY2hhbm5lbFt0eXBlXVtjaE51bV07aWYobGlzdGVuZXJzKWlmKHZvaWQgMD09PWxpc3RlbmVyKXRoYXQuX3VzZXJIYW5kbGVycy5jaGFubmVsW3R5cGVdW2NoTnVtXT1bXTtlbHNlIGZvcih2YXIgbD0wO2w8bGlzdGVuZXJzLmxlbmd0aDtsKyspbGlzdGVuZXJzW2xdPT09bGlzdGVuZXImJmxpc3RlbmVycy5zcGxpY2UobCwxKX0pfWVsc2V7aWYodm9pZCAwIT09dHlwZSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiVGhlIHNwZWNpZmllZCBldmVudCB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQuXCIpO3RoaXMuX2luaXRpYWxpemVVc2VySGFuZGxlcnMoKX1yZXR1cm4gdGhpc30sSW5wdXQucHJvdG90eXBlLl9pbml0aWFsaXplVXNlckhhbmRsZXJzPWZ1bmN0aW9uKCl7Zm9yKHZhciBwcm9wMSBpbiB3bS5NSURJX0NIQU5ORUxfTUVTU0FHRVMpd20uTUlESV9DSEFOTkVMX01FU1NBR0VTLmhhc093blByb3BlcnR5KHByb3AxKSYmKHRoaXMuX3VzZXJIYW5kbGVycy5jaGFubmVsW3Byb3AxXT17fSk7Zm9yKHZhciBwcm9wMiBpbiB3bS5NSURJX1NZU1RFTV9NRVNTQUdFUyl3bS5NSURJX1NZU1RFTV9NRVNTQUdFUy5oYXNPd25Qcm9wZXJ0eShwcm9wMikmJih0aGlzLl91c2VySGFuZGxlcnMuc3lzdGVtW3Byb3AyXT1bXSl9LElucHV0LnByb3RvdHlwZS5fb25NaWRpTWVzc2FnZT1mdW5jdGlvbihlKXtpZih0aGlzLl91c2VySGFuZGxlcnMuc3lzdGVtLm1pZGltZXNzYWdlLmxlbmd0aD4wKXt2YXIgZXZlbnQ9e3RhcmdldDp0aGlzLGRhdGE6ZS5kYXRhLHRpbWVzdGFtcDplLnRpbWVTdGFtcCx0eXBlOlwibWlkaW1lc3NhZ2VcIn07dGhpcy5fdXNlckhhbmRsZXJzLnN5c3RlbS5taWRpbWVzc2FnZS5mb3JFYWNoKGZ1bmN0aW9uKGNhbGxiYWNrKXtjYWxsYmFjayhldmVudCl9KX1lLmRhdGFbMF08MjQwP3RoaXMuX3BhcnNlQ2hhbm5lbEV2ZW50KGUpOmUuZGF0YVswXTw9MjU1JiZ0aGlzLl9wYXJzZVN5c3RlbUV2ZW50KGUpfSxJbnB1dC5wcm90b3R5cGUuX3BhcnNlQ2hhbm5lbEV2ZW50PWZ1bmN0aW9uKGUpe3ZhciBkYXRhMSxkYXRhMixjb21tYW5kPWUuZGF0YVswXT4+NCxjaGFubmVsPSgxNSZlLmRhdGFbMF0pKzE7ZS5kYXRhLmxlbmd0aD4xJiYoZGF0YTE9ZS5kYXRhWzFdLGRhdGEyPWUuZGF0YS5sZW5ndGg+Mj9lLmRhdGFbMl06dm9pZCAwKTt2YXIgZXZlbnQ9e3RhcmdldDp0aGlzLGRhdGE6ZS5kYXRhLHRpbWVzdGFtcDplLnRpbWVTdGFtcCxjaGFubmVsOmNoYW5uZWx9O2NvbW1hbmQ9PT13bS5NSURJX0NIQU5ORUxfTUVTU0FHRVMubm90ZW9mZnx8Y29tbWFuZD09PXdtLk1JRElfQ0hBTk5FTF9NRVNTQUdFUy5ub3Rlb24mJjA9PT1kYXRhMj8oZXZlbnQudHlwZT1cIm5vdGVvZmZcIixldmVudC5ub3RlPXtudW1iZXI6ZGF0YTEsbmFtZTp3bS5fbm90ZXNbZGF0YTElMTJdLG9jdGF2ZTp3bS5nZXRPY3RhdmUoZGF0YTEpfSxldmVudC52ZWxvY2l0eT1kYXRhMi8xMjcsZXZlbnQucmF3VmVsb2NpdHk9ZGF0YTIpOmNvbW1hbmQ9PT13bS5NSURJX0NIQU5ORUxfTUVTU0FHRVMubm90ZW9uPyhldmVudC50eXBlPVwibm90ZW9uXCIsZXZlbnQubm90ZT17bnVtYmVyOmRhdGExLG5hbWU6d20uX25vdGVzW2RhdGExJTEyXSxvY3RhdmU6d20uZ2V0T2N0YXZlKGRhdGExKX0sZXZlbnQudmVsb2NpdHk9ZGF0YTIvMTI3LGV2ZW50LnJhd1ZlbG9jaXR5PWRhdGEyKTpjb21tYW5kPT09d20uTUlESV9DSEFOTkVMX01FU1NBR0VTLmtleWFmdGVydG91Y2g/KGV2ZW50LnR5cGU9XCJrZXlhZnRlcnRvdWNoXCIsZXZlbnQubm90ZT17bnVtYmVyOmRhdGExLG5hbWU6d20uX25vdGVzW2RhdGExJTEyXSxvY3RhdmU6d20uZ2V0T2N0YXZlKGRhdGExKX0sZXZlbnQudmFsdWU9ZGF0YTIvMTI3KTpjb21tYW5kPT09d20uTUlESV9DSEFOTkVMX01FU1NBR0VTLmNvbnRyb2xjaGFuZ2UmJmRhdGExPj0wJiYxMTk+PWRhdGExPyhldmVudC50eXBlPVwiY29udHJvbGNoYW5nZVwiLGV2ZW50LmNvbnRyb2xsZXI9e251bWJlcjpkYXRhMSxuYW1lOnRoaXMuZ2V0Q2NOYW1lQnlOdW1iZXIoZGF0YTEpfSxldmVudC52YWx1ZT1kYXRhMik6Y29tbWFuZD09PXdtLk1JRElfQ0hBTk5FTF9NRVNTQUdFUy5jaGFubmVsbW9kZSYmZGF0YTE+PTEyMCYmMTI3Pj1kYXRhMT8oZXZlbnQudHlwZT1cImNoYW5uZWxtb2RlXCIsZXZlbnQuY29udHJvbGxlcj17bnVtYmVyOmRhdGExLG5hbWU6dGhpcy5nZXRDaGFubmVsTW9kZUJ5TnVtYmVyKGRhdGExKX0sZXZlbnQudmFsdWU9ZGF0YTIpOmNvbW1hbmQ9PT13bS5NSURJX0NIQU5ORUxfTUVTU0FHRVMucHJvZ3JhbWNoYW5nZT8oZXZlbnQudHlwZT1cInByb2dyYW1jaGFuZ2VcIixldmVudC52YWx1ZT1kYXRhMSk6Y29tbWFuZD09PXdtLk1JRElfQ0hBTk5FTF9NRVNTQUdFUy5jaGFubmVsYWZ0ZXJ0b3VjaD8oZXZlbnQudHlwZT1cImNoYW5uZWxhZnRlcnRvdWNoXCIsZXZlbnQudmFsdWU9ZGF0YTEvMTI3KTpjb21tYW5kPT09d20uTUlESV9DSEFOTkVMX01FU1NBR0VTLnBpdGNoYmVuZD8oZXZlbnQudHlwZT1cInBpdGNoYmVuZFwiLGV2ZW50LnZhbHVlPSgoZGF0YTI8PDcpK2RhdGExLTgxOTIpLzgxOTIpOmV2ZW50LnR5cGU9XCJ1bmtub3duY2hhbm5lbG1lc3NhZ2VcIix0aGlzLl91c2VySGFuZGxlcnMuY2hhbm5lbFtldmVudC50eXBlXSYmdGhpcy5fdXNlckhhbmRsZXJzLmNoYW5uZWxbZXZlbnQudHlwZV1bY2hhbm5lbF0mJnRoaXMuX3VzZXJIYW5kbGVycy5jaGFubmVsW2V2ZW50LnR5cGVdW2NoYW5uZWxdLmZvckVhY2goZnVuY3Rpb24oY2FsbGJhY2spe2NhbGxiYWNrKGV2ZW50KX0pfSxJbnB1dC5wcm90b3R5cGUuZ2V0Q2NOYW1lQnlOdW1iZXI9ZnVuY3Rpb24obnVtYmVyKXtpZihudW1iZXI9TWF0aC5mbG9vcihudW1iZXIpLCEobnVtYmVyPj0wJiYxMTk+PW51bWJlcikpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgY29udHJvbCBjaGFuZ2UgbnVtYmVyIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxMTkuXCIpO2Zvcih2YXIgY2MgaW4gd20uTUlESV9DT05UUk9MX0NIQU5HRV9NRVNTQUdFUylpZih3bS5NSURJX0NPTlRST0xfQ0hBTkdFX01FU1NBR0VTLmhhc093blByb3BlcnR5KGNjKSYmbnVtYmVyPT09d20uTUlESV9DT05UUk9MX0NIQU5HRV9NRVNTQUdFU1tjY10pcmV0dXJuIGNjO3JldHVybiB2b2lkIDB9LElucHV0LnByb3RvdHlwZS5nZXRDaGFubmVsTW9kZUJ5TnVtYmVyPWZ1bmN0aW9uKG51bWJlcil7aWYobnVtYmVyPU1hdGguZmxvb3IobnVtYmVyKSwhKG51bWJlcj49MTIwJiZzdGF0dXM8PTEyNykpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgY29udHJvbCBjaGFuZ2UgbnVtYmVyIG11c3QgYmUgYmV0d2VlbiAxMjAgYW5kIDEyNy5cIik7Zm9yKHZhciBjbSBpbiB3bS5NSURJX0NIQU5ORUxfTU9ERV9NRVNTQUdFUylpZih3bS5NSURJX0NIQU5ORUxfTU9ERV9NRVNTQUdFUy5oYXNPd25Qcm9wZXJ0eShjbSkmJm51bWJlcj09PXdtLk1JRElfQ0hBTk5FTF9NT0RFX01FU1NBR0VTW2NtXSlyZXR1cm4gY219LElucHV0LnByb3RvdHlwZS5fcGFyc2VTeXN0ZW1FdmVudD1mdW5jdGlvbihlKXt2YXIgY29tbWFuZD1lLmRhdGFbMF0sZXZlbnQ9e3RhcmdldDp0aGlzLGRhdGE6ZS5kYXRhLHRpbWVzdGFtcDplLnRpbWVTdGFtcH07Y29tbWFuZD09PXdtLk1JRElfU1lTVEVNX01FU1NBR0VTLnN5c2V4P2V2ZW50LnR5cGU9XCJzeXNleFwiOmNvbW1hbmQ9PT13bS5NSURJX1NZU1RFTV9NRVNTQUdFUy50aW1lY29kZT9ldmVudC50eXBlPVwidGltZWNvZGVcIjpjb21tYW5kPT09d20uTUlESV9TWVNURU1fTUVTU0FHRVMuc29uZ3Bvc2l0aW9uP2V2ZW50LnR5cGU9XCJzb25ncG9zaXRpb25cIjpjb21tYW5kPT09d20uTUlESV9TWVNURU1fTUVTU0FHRVMuc29uZ3NlbGVjdD8oZXZlbnQudHlwZT1cInNvbmdzZWxlY3RcIixldmVudC5zb25nPWUuZGF0YVsxXSk6Y29tbWFuZD09PXdtLk1JRElfU1lTVEVNX01FU1NBR0VTLnR1bmluZ3JlcXVlc3Q/ZXZlbnQudHlwZT1cInR1bmluZ3JlcXVlc3RcIjpjb21tYW5kPT09d20uTUlESV9TWVNURU1fTUVTU0FHRVMuY2xvY2s/ZXZlbnQudHlwZT1cImNsb2NrXCI6Y29tbWFuZD09PXdtLk1JRElfU1lTVEVNX01FU1NBR0VTLnN0YXJ0P2V2ZW50LnR5cGU9XCJzdGFydFwiOmNvbW1hbmQ9PT13bS5NSURJX1NZU1RFTV9NRVNTQUdFU1tcImNvbnRpbnVlXCJdP2V2ZW50LnR5cGU9XCJjb250aW51ZVwiOmNvbW1hbmQ9PT13bS5NSURJX1NZU1RFTV9NRVNTQUdFUy5zdG9wP2V2ZW50LnR5cGU9XCJzdG9wXCI6Y29tbWFuZD09PXdtLk1JRElfU1lTVEVNX01FU1NBR0VTLmFjdGl2ZXNlbnNpbmc/ZXZlbnQudHlwZT1cImFjdGl2ZXNlbnNpbmdcIjpjb21tYW5kPT09d20uTUlESV9TWVNURU1fTUVTU0FHRVMucmVzZXQ/ZXZlbnQudHlwZT1cInJlc2V0XCI6ZXZlbnQudHlwZT1cInVua25vd25zeXN0ZW1tZXNzYWdlXCIsdGhpcy5fdXNlckhhbmRsZXJzLnN5c3RlbVtldmVudC50eXBlXSYmdGhpcy5fdXNlckhhbmRsZXJzLnN5c3RlbVtldmVudC50eXBlXS5mb3JFYWNoKGZ1bmN0aW9uKGNhbGxiYWNrKXtjYWxsYmFjayhldmVudCl9KX0sT3V0cHV0LnByb3RvdHlwZS5zZW5kPWZ1bmN0aW9uKHN0YXR1cyxkYXRhLHRpbWVzdGFtcCl7aWYoIShzdGF0dXM+PTEyOCYmMjU1Pj1zdGF0dXMpKXRocm93IG5ldyBSYW5nZUVycm9yKFwiVGhlIHN0YXR1cyBieXRlIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEyOCAoMHg4MCkgYW5kIDI1NSAoMHhGRikuXCIpO3ZvaWQgMD09PWRhdGEmJihkYXRhPVtdKSxBcnJheS5pc0FycmF5KGRhdGEpfHwoZGF0YT1bZGF0YV0pO3ZhciBtZXNzYWdlPVtdO3JldHVybiBkYXRhLmZvckVhY2goZnVuY3Rpb24oaXRlbSxpbmRleCl7dmFyIHBhcnNlZD1NYXRoLmZsb29yKGl0ZW0pO2lmKCEocGFyc2VkPj0wJiYyNTU+PXBhcnNlZCkpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJEYXRhIGJ5dGVzIG11c3QgYmUgaW50ZWdlcnMgYmV0d2VlbiAwICgweDAwKSBhbmQgMjU1ICgweEZGKS5cIik7bWVzc2FnZS5wdXNoKHBhcnNlZCl9KSx0aGlzLl9taWRpT3V0cHV0LnNlbmQoW3N0YXR1c10uY29uY2F0KG1lc3NhZ2UpLHBhcnNlRmxvYXQodGltZXN0YW1wKXx8MCksdGhpc30sT3V0cHV0LnByb3RvdHlwZS5zZW5kU3lzZXg9ZnVuY3Rpb24obWFudWZhY3R1cmVyLGRhdGEsb3B0aW9ucyl7aWYoIXdtLnN5c2V4RW5hYmxlZCl0aHJvdyBuZXcgRXJyb3IoXCJTeXNleCBtZXNzYWdlIHN1cHBvcnQgbXVzdCBmaXJzdCBiZSBhY3RpdmF0ZWQuXCIpO3JldHVybiBvcHRpb25zPW9wdGlvbnN8fHt9LG1hbnVmYWN0dXJlcj1bXS5jb25jYXQobWFudWZhY3R1cmVyKSxkYXRhLmZvckVhY2goZnVuY3Rpb24oaXRlbSl7aWYoMD5pdGVtfHxpdGVtPjEyNyl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlRoZSBkYXRhIGJ5dGVzIG9mIGEgc3lzZXggbWVzc2FnZSBtdXN0IGJlIGludGVnZXJzIGJldHdlZW4gMCAoMHgwMCkgYW5kIDEyNyAoMHg3RikuXCIpfSksZGF0YT1tYW51ZmFjdHVyZXIuY29uY2F0KGRhdGEsd20uTUlESV9TWVNURU1fTUVTU0FHRVMuc3lzZXhlbmQpLHRoaXMuc2VuZCh3bS5NSURJX1NZU1RFTV9NRVNTQUdFUy5zeXNleCxkYXRhLHRoaXMuX3BhcnNlVGltZVBhcmFtZXRlcihvcHRpb25zLnRpbWUpKSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLnNlbmRUaW1lY29kZVF1YXJ0ZXJGcmFtZT1mdW5jdGlvbih2YWx1ZSxvcHRpb25zKXtyZXR1cm4gb3B0aW9ucz1vcHRpb25zfHx7fSx0aGlzLnNlbmQod20uTUlESV9TWVNURU1fTUVTU0FHRVMudGltZWNvZGUsdmFsdWUsdGhpcy5fcGFyc2VUaW1lUGFyYW1ldGVyKG9wdGlvbnMudGltZSkpLHRoaXN9LE91dHB1dC5wcm90b3R5cGUuc2VuZFNvbmdQb3NpdGlvbj1mdW5jdGlvbih2YWx1ZSxvcHRpb25zKXt2YWx1ZT1NYXRoLmZsb29yKHZhbHVlKXx8MCxvcHRpb25zPW9wdGlvbnN8fHt9O3ZhciBtc2I9dmFsdWU+PjcmMTI3LGxzYj0xMjcmdmFsdWU7cmV0dXJuIHRoaXMuc2VuZCh3bS5NSURJX1NZU1RFTV9NRVNTQUdFUy5zb25ncG9zaXRpb24sW21zYixsc2JdLHRoaXMuX3BhcnNlVGltZVBhcmFtZXRlcihvcHRpb25zLnRpbWUpKSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLnNlbmRTb25nU2VsZWN0PWZ1bmN0aW9uKHZhbHVlLG9wdGlvbnMpe2lmKHZhbHVlPU1hdGguZmxvb3IodmFsdWUpLG9wdGlvbnM9b3B0aW9uc3x8e30sISh2YWx1ZT49MCYmMTI3Pj12YWx1ZSkpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgc29uZyBudW1iZXIgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEyNy5cIik7cmV0dXJuIHRoaXMuc2VuZCh3bS5NSURJX1NZU1RFTV9NRVNTQUdFUy5zb25nc2VsZWN0LFt2YWx1ZV0sdGhpcy5fcGFyc2VUaW1lUGFyYW1ldGVyKG9wdGlvbnMudGltZSkpLHRoaXN9LE91dHB1dC5wcm90b3R5cGUuc2VuZFR1bmluZ1JlcXVlc3Q9ZnVuY3Rpb24ob3B0aW9ucyl7cmV0dXJuIG9wdGlvbnM9b3B0aW9uc3x8e30sdGhpcy5zZW5kKHdtLk1JRElfU1lTVEVNX01FU1NBR0VTLnR1bmluZ3JlcXVlc3Qsdm9pZCAwLHRoaXMuX3BhcnNlVGltZVBhcmFtZXRlcihvcHRpb25zLnRpbWUpKSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLnNlbmRDbG9jaz1mdW5jdGlvbihvcHRpb25zKXtyZXR1cm4gb3B0aW9ucz1vcHRpb25zfHx7fSx0aGlzLnNlbmQod20uTUlESV9TWVNURU1fTUVTU0FHRVMuY2xvY2ssdm9pZCAwLHRoaXMuX3BhcnNlVGltZVBhcmFtZXRlcihvcHRpb25zLnRpbWUpKSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLnNlbmRTdGFydD1mdW5jdGlvbihvcHRpb25zKXtyZXR1cm4gb3B0aW9ucz1vcHRpb25zfHx7fSx0aGlzLnNlbmQod20uTUlESV9TWVNURU1fTUVTU0FHRVMuc3RhcnQsdm9pZCAwLHRoaXMuX3BhcnNlVGltZVBhcmFtZXRlcihvcHRpb25zLnRpbWUpKSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLnNlbmRDb250aW51ZT1mdW5jdGlvbihvcHRpb25zKXtyZXR1cm4gb3B0aW9ucz1vcHRpb25zfHx7fSx0aGlzLnNlbmQod20uTUlESV9TWVNURU1fTUVTU0FHRVNbXCJjb250aW51ZVwiXSx2b2lkIDAsdGhpcy5fcGFyc2VUaW1lUGFyYW1ldGVyKG9wdGlvbnMudGltZSkpLHRoaXN9LE91dHB1dC5wcm90b3R5cGUuc2VuZFN0b3A9ZnVuY3Rpb24ob3B0aW9ucyl7cmV0dXJuIG9wdGlvbnM9b3B0aW9uc3x8e30sdGhpcy5zZW5kKHdtLk1JRElfU1lTVEVNX01FU1NBR0VTLnN0b3Asdm9pZCAwLHRoaXMuX3BhcnNlVGltZVBhcmFtZXRlcihvcHRpb25zLnRpbWUpKSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLnNlbmRBY3RpdmVTZW5zaW5nPWZ1bmN0aW9uKG9wdGlvbnMpe3JldHVybiBvcHRpb25zPW9wdGlvbnN8fHt9LHRoaXMuc2VuZCh3bS5NSURJX1NZU1RFTV9NRVNTQUdFUy5hY3RpdmVzZW5zaW5nLFtdLHRoaXMuX3BhcnNlVGltZVBhcmFtZXRlcihvcHRpb25zLnRpbWUpKSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLnNlbmRSZXNldD1mdW5jdGlvbihvcHRpb25zKXtyZXR1cm4gb3B0aW9ucz1vcHRpb25zfHx7fSx0aGlzLnNlbmQod20uTUlESV9TWVNURU1fTUVTU0FHRVMucmVzZXQsdm9pZCAwLHRoaXMuX3BhcnNlVGltZVBhcmFtZXRlcihvcHRpb25zLnRpbWUpKSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLnN0b3BOb3RlPWZ1bmN0aW9uKG5vdGUsY2hhbm5lbCxvcHRpb25zKXtpZihcImFsbFwiPT09bm90ZSlyZXR1cm4gdGhpcy5zZW5kQ2hhbm5lbE1vZGUoXCJhbGxub3Rlc29mZlwiLDAsY2hhbm5lbCxvcHRpb25zKTt2YXIgblZlbG9jaXR5PTY0O3JldHVybiBvcHRpb25zPW9wdGlvbnN8fHt9LG9wdGlvbnMucmF3VmVsb2NpdHk/IWlzTmFOKG9wdGlvbnMudmVsb2NpdHkpJiZvcHRpb25zLnZlbG9jaXR5Pj0wJiZvcHRpb25zLnZlbG9jaXR5PD0xMjcmJihuVmVsb2NpdHk9b3B0aW9ucy52ZWxvY2l0eSk6IWlzTmFOKG9wdGlvbnMudmVsb2NpdHkpJiZvcHRpb25zLnZlbG9jaXR5Pj0wJiZvcHRpb25zLnZlbG9jaXR5PD0xJiYoblZlbG9jaXR5PTEyNypvcHRpb25zLnZlbG9jaXR5KSx0aGlzLl9jb252ZXJ0Tm90ZVRvQXJyYXkobm90ZSkuZm9yRWFjaChmdW5jdGlvbihpdGVtKXt3bS50b01JRElDaGFubmVscyhjaGFubmVsKS5mb3JFYWNoKGZ1bmN0aW9uKGNoKXt0aGlzLnNlbmQoKHdtLk1JRElfQ0hBTk5FTF9NRVNTQUdFUy5ub3Rlb2ZmPDw0KSsoY2gtMSksW2l0ZW0sTWF0aC5yb3VuZChuVmVsb2NpdHkpXSx0aGlzLl9wYXJzZVRpbWVQYXJhbWV0ZXIob3B0aW9ucy50aW1lKSl9LmJpbmQodGhpcykpfS5iaW5kKHRoaXMpKSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLnBsYXlOb3RlPWZ1bmN0aW9uKG5vdGUsY2hhbm5lbCxvcHRpb25zKXt2YXIgblZlbG9jaXR5PTY0O2lmKG9wdGlvbnM9b3B0aW9uc3x8e30sb3B0aW9ucy5yYXdWZWxvY2l0eT8haXNOYU4ob3B0aW9ucy52ZWxvY2l0eSkmJm9wdGlvbnMudmVsb2NpdHk+PTAmJm9wdGlvbnMudmVsb2NpdHk8PTEyNyYmKG5WZWxvY2l0eT1vcHRpb25zLnZlbG9jaXR5KTohaXNOYU4ob3B0aW9ucy52ZWxvY2l0eSkmJm9wdGlvbnMudmVsb2NpdHk+PTAmJm9wdGlvbnMudmVsb2NpdHk8PTEmJihuVmVsb2NpdHk9MTI3Km9wdGlvbnMudmVsb2NpdHkpLG9wdGlvbnMudGltZT10aGlzLl9wYXJzZVRpbWVQYXJhbWV0ZXIob3B0aW9ucy50aW1lKSx0aGlzLl9jb252ZXJ0Tm90ZVRvQXJyYXkobm90ZSkuZm9yRWFjaChmdW5jdGlvbihpdGVtKXt3bS50b01JRElDaGFubmVscyhjaGFubmVsKS5mb3JFYWNoKGZ1bmN0aW9uKGNoKXt0aGlzLnNlbmQoKHdtLk1JRElfQ0hBTk5FTF9NRVNTQUdFUy5ub3Rlb248PDQpKyhjaC0xKSxbaXRlbSxNYXRoLnJvdW5kKG5WZWxvY2l0eSldLG9wdGlvbnMudGltZSl9LmJpbmQodGhpcykpfS5iaW5kKHRoaXMpKSwhaXNOYU4ob3B0aW9ucy5kdXJhdGlvbikpe29wdGlvbnMuZHVyYXRpb248PTAmJihvcHRpb25zLmR1cmF0aW9uPTApO3ZhciBuUmVsZWFzZT02NDtvcHRpb25zLnJhd1ZlbG9jaXR5PyFpc05hTihvcHRpb25zLnJlbGVhc2UpJiZvcHRpb25zLnJlbGVhc2U+PTAmJm9wdGlvbnMucmVsZWFzZTw9MTI3JiYoblJlbGVhc2U9b3B0aW9ucy5yZWxlYXNlKTohaXNOYU4ob3B0aW9ucy5yZWxlYXNlKSYmb3B0aW9ucy5yZWxlYXNlPj0wJiZvcHRpb25zLnJlbGVhc2U8PTEmJihuUmVsZWFzZT0xMjcqb3B0aW9ucy5yZWxlYXNlKSx0aGlzLl9jb252ZXJ0Tm90ZVRvQXJyYXkobm90ZSkuZm9yRWFjaChmdW5jdGlvbihpdGVtKXt3bS50b01JRElDaGFubmVscyhjaGFubmVsKS5mb3JFYWNoKGZ1bmN0aW9uKGNoKXt0aGlzLnNlbmQoKHdtLk1JRElfQ0hBTk5FTF9NRVNTQUdFUy5ub3Rlb2ZmPDw0KSsoY2gtMSksW2l0ZW0sTWF0aC5yb3VuZChuUmVsZWFzZSldLChvcHRpb25zLnRpbWV8fHdtLnRpbWUpK29wdGlvbnMuZHVyYXRpb24pfS5iaW5kKHRoaXMpKX0uYmluZCh0aGlzKSl9cmV0dXJuIHRoaXN9LE91dHB1dC5wcm90b3R5cGUuc2VuZEtleUFmdGVydG91Y2g9ZnVuY3Rpb24obm90ZSxjaGFubmVsLHByZXNzdXJlLG9wdGlvbnMpe3ZhciB0aGF0PXRoaXM7aWYob3B0aW9ucz1vcHRpb25zfHx7fSwxPmNoYW5uZWx8fGNoYW5uZWw+MTYpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgY2hhbm5lbCBtdXN0IGJlIGJldHdlZW4gMSBhbmQgMTYuXCIpOyhpc05hTihwcmVzc3VyZSl8fDA+cHJlc3N1cmV8fHByZXNzdXJlPjEpJiYocHJlc3N1cmU9LjUpO3ZhciBuUHJlc3N1cmU9TWF0aC5yb3VuZCgxMjcqcHJlc3N1cmUpO3JldHVybiB0aGlzLl9jb252ZXJ0Tm90ZVRvQXJyYXkobm90ZSkuZm9yRWFjaChmdW5jdGlvbihpdGVtKXt3bS50b01JRElDaGFubmVscyhjaGFubmVsKS5mb3JFYWNoKGZ1bmN0aW9uKGNoKXt0aGF0LnNlbmQoKHdtLk1JRElfQ0hBTk5FTF9NRVNTQUdFUy5rZXlhZnRlcnRvdWNoPDw0KSsoY2gtMSksW2l0ZW0sblByZXNzdXJlXSx0aGF0Ll9wYXJzZVRpbWVQYXJhbWV0ZXIob3B0aW9ucy50aW1lKSl9KX0pLHRoaXN9LE91dHB1dC5wcm90b3R5cGUuc2VuZENvbnRyb2xDaGFuZ2U9ZnVuY3Rpb24oY29udHJvbGxlcix2YWx1ZSxjaGFubmVsLG9wdGlvbnMpe2lmKG9wdGlvbnM9b3B0aW9uc3x8e30sXCJzdHJpbmdcIj09dHlwZW9mIGNvbnRyb2xsZXIpe2lmKGNvbnRyb2xsZXI9d20uTUlESV9DT05UUk9MX0NIQU5HRV9NRVNTQUdFU1tjb250cm9sbGVyXSwhY29udHJvbGxlcil0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBjb250cm9sbGVyIG5hbWUuXCIpfWVsc2UgaWYoY29udHJvbGxlcj1NYXRoLmZsb29yKGNvbnRyb2xsZXIpLCEoY29udHJvbGxlcj49MCYmMTE5Pj1jb250cm9sbGVyKSl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkNvbnRyb2xsZXIgbnVtYmVycyBtdXN0IGJlIGJldHdlZW4gMCBhbmQgMTE5LlwiKTtpZih2YWx1ZT1NYXRoLmZsb29yKHZhbHVlKXx8MCwhKHZhbHVlPj0wJiYxMjc+PXZhbHVlKSl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkNvbnRyb2xsZXIgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEyNy5cIik7cmV0dXJuIHdtLnRvTUlESUNoYW5uZWxzKGNoYW5uZWwpLmZvckVhY2goZnVuY3Rpb24oY2gpe3RoaXMuc2VuZCgod20uTUlESV9DSEFOTkVMX01FU1NBR0VTLmNvbnRyb2xjaGFuZ2U8PDQpKyhjaC0xKSxbY29udHJvbGxlcix2YWx1ZV0sdGhpcy5fcGFyc2VUaW1lUGFyYW1ldGVyKG9wdGlvbnMudGltZSkpfS5iaW5kKHRoaXMpKSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLl9zZWxlY3RSZWdpc3RlcmVkUGFyYW1ldGVyPWZ1bmN0aW9uKHBhcmFtZXRlcixjaGFubmVsLHRpbWUpe3ZhciB0aGF0PXRoaXM7aWYocGFyYW1ldGVyWzBdPU1hdGguZmxvb3IocGFyYW1ldGVyWzBdKSwhKHBhcmFtZXRlclswXT49MCYmcGFyYW1ldGVyWzBdPD0xMjcpKXRocm93IG5ldyBSYW5nZUVycm9yKFwiVGhlIGNvbnRyb2w2NSB2YWx1ZSBtdXN0IGJlIGJldHdlZW4gMCBhbmQgMTI3XCIpO2lmKHBhcmFtZXRlclsxXT1NYXRoLmZsb29yKHBhcmFtZXRlclsxXSksIShwYXJhbWV0ZXJbMV0+PTAmJnBhcmFtZXRlclsxXTw9MTI3KSl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlRoZSBjb250cm9sNjQgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEyN1wiKTtyZXR1cm4gd20udG9NSURJQ2hhbm5lbHMoY2hhbm5lbCkuZm9yRWFjaChmdW5jdGlvbihjaCl7dGhhdC5zZW5kQ29udHJvbENoYW5nZSgxMDEscGFyYW1ldGVyWzBdLGNoYW5uZWwse3RpbWU6dGltZX0pLHRoYXQuc2VuZENvbnRyb2xDaGFuZ2UoMTAwLHBhcmFtZXRlclsxXSxjaGFubmVsLHt0aW1lOnRpbWV9KX0pLHRoaXN9LE91dHB1dC5wcm90b3R5cGUuX3NlbGVjdE5vblJlZ2lzdGVyZWRQYXJhbWV0ZXI9ZnVuY3Rpb24ocGFyYW1ldGVyLGNoYW5uZWwsdGltZSl7dmFyIHRoYXQ9dGhpcztpZihwYXJhbWV0ZXJbMF09TWF0aC5mbG9vcihwYXJhbWV0ZXJbMF0pLCEocGFyYW1ldGVyWzBdPj0wJiZwYXJhbWV0ZXJbMF08PTEyNykpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgY29udHJvbDYzIHZhbHVlIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxMjdcIik7aWYocGFyYW1ldGVyWzFdPU1hdGguZmxvb3IocGFyYW1ldGVyWzFdKSwhKHBhcmFtZXRlclsxXT49MCYmcGFyYW1ldGVyWzFdPD0xMjcpKXRocm93IG5ldyBSYW5nZUVycm9yKFwiVGhlIGNvbnRyb2w2MiB2YWx1ZSBtdXN0IGJlIGJldHdlZW4gMCBhbmQgMTI3XCIpO3JldHVybiB3bS50b01JRElDaGFubmVscyhjaGFubmVsKS5mb3JFYWNoKGZ1bmN0aW9uKGNoKXt0aGF0LnNlbmRDb250cm9sQ2hhbmdlKDk5LHBhcmFtZXRlclswXSxjaGFubmVsLHt0aW1lOnRpbWV9KSx0aGF0LnNlbmRDb250cm9sQ2hhbmdlKDk4LHBhcmFtZXRlclsxXSxjaGFubmVsLHt0aW1lOnRpbWV9KX0pLHRoaXN9LE91dHB1dC5wcm90b3R5cGUuX3NldEN1cnJlbnRSZWdpc3RlcmVkUGFyYW1ldGVyPWZ1bmN0aW9uKGRhdGEsY2hhbm5lbCx0aW1lKXt2YXIgdGhhdD10aGlzO2lmKGRhdGE9W10uY29uY2F0KGRhdGEpLGRhdGFbMF09TWF0aC5mbG9vcihkYXRhWzBdKSwhKGRhdGFbMF0+PTAmJmRhdGFbMF08PTEyNykpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgbXNiIHZhbHVlIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxMjdcIik7cmV0dXJuIHdtLnRvTUlESUNoYW5uZWxzKGNoYW5uZWwpLmZvckVhY2goZnVuY3Rpb24oY2gpe3RoYXQuc2VuZENvbnRyb2xDaGFuZ2UoNixkYXRhWzBdLGNoYW5uZWwse3RpbWU6dGltZX0pfSksZGF0YVsxXT1NYXRoLmZsb29yKGRhdGFbMV0pLGRhdGFbMV0+PTAmJmRhdGFbMV08PTEyNyYmd20udG9NSURJQ2hhbm5lbHMoY2hhbm5lbCkuZm9yRWFjaChmdW5jdGlvbihjaCl7dGhhdC5zZW5kQ29udHJvbENoYW5nZSgzOCxkYXRhWzFdLGNoYW5uZWwse3RpbWU6dGltZX0pfSksdGhpc30sT3V0cHV0LnByb3RvdHlwZS5fZGVzZWxlY3RSZWdpc3RlcmVkUGFyYW1ldGVyPWZ1bmN0aW9uKGNoYW5uZWwsdGltZSl7dmFyIHRoYXQ9dGhpcztyZXR1cm4gd20udG9NSURJQ2hhbm5lbHMoY2hhbm5lbCkuZm9yRWFjaChmdW5jdGlvbihjaCl7dGhhdC5zZW5kQ29udHJvbENoYW5nZSgxMDEsMTI3LGNoYW5uZWwse3RpbWU6dGltZX0pLHRoYXQuc2VuZENvbnRyb2xDaGFuZ2UoMTAwLDEyNyxjaGFubmVsLHt0aW1lOnRpbWV9KX0pLHRoaXN9LE91dHB1dC5wcm90b3R5cGUuc2V0UmVnaXN0ZXJlZFBhcmFtZXRlcj1mdW5jdGlvbihwYXJhbWV0ZXIsZGF0YSxjaGFubmVsLG9wdGlvbnMpe3ZhciB0aGF0PXRoaXM7aWYob3B0aW9ucz1vcHRpb25zfHx7fSwhQXJyYXkuaXNBcnJheShwYXJhbWV0ZXIpKXtpZighd20uTUlESV9SRUdJU1RFUkVEX1BBUkFNRVRFUltwYXJhbWV0ZXJdKXRocm93IG5ldyBFcnJvcihcIlRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGlzIG5vdCBhdmFpbGFibGUuXCIpO3BhcmFtZXRlcj13bS5NSURJX1JFR0lTVEVSRURfUEFSQU1FVEVSW3BhcmFtZXRlcl19cmV0dXJuIHdtLnRvTUlESUNoYW5uZWxzKGNoYW5uZWwpLmZvckVhY2goZnVuY3Rpb24oY2gpe3RoYXQuX3NlbGVjdFJlZ2lzdGVyZWRQYXJhbWV0ZXIocGFyYW1ldGVyLGNoYW5uZWwsb3B0aW9ucy50aW1lKSx0aGF0Ll9zZXRDdXJyZW50UmVnaXN0ZXJlZFBhcmFtZXRlcihkYXRhLGNoYW5uZWwsb3B0aW9ucy50aW1lKSx0aGF0Ll9kZXNlbGVjdFJlZ2lzdGVyZWRQYXJhbWV0ZXIoY2hhbm5lbCxvcHRpb25zLnRpbWUpfSksdGhpc30sT3V0cHV0LnByb3RvdHlwZS5zZXROb25SZWdpc3RlcmVkUGFyYW1ldGVyPWZ1bmN0aW9uKHBhcmFtZXRlcixkYXRhLGNoYW5uZWwsb3B0aW9ucyl7dmFyIHRoYXQ9dGhpcztpZihvcHRpb25zPW9wdGlvbnN8fHt9LCEocGFyYW1ldGVyWzBdPj0wJiZwYXJhbWV0ZXJbMF08PTEyNyYmcGFyYW1ldGVyWzFdPj0wJiZwYXJhbWV0ZXJbMV08PTEyNykpdGhyb3cgbmV3IEVycm9yKFwiUG9zaXRpb24gMCBhbmQgMSBvZiB0aGUgMi1wb3NpdGlvbiBwYXJhbWV0ZXIgYXJyYXkgbXVzdCBib3RoIGJlIGJldHdlZW4gMCBhbmQgMTI3LlwiKTtyZXR1cm4gZGF0YT1bXS5jb25jYXQoZGF0YSksd20udG9NSURJQ2hhbm5lbHMoY2hhbm5lbCkuZm9yRWFjaChmdW5jdGlvbihjaCl7dGhhdC5fc2VsZWN0Tm9uUmVnaXN0ZXJlZFBhcmFtZXRlcihwYXJhbWV0ZXIsY2hhbm5lbCxvcHRpb25zLnRpbWUpLHRoYXQuX3NldEN1cnJlbnRSZWdpc3RlcmVkUGFyYW1ldGVyKGRhdGEsY2hhbm5lbCxvcHRpb25zLnRpbWUpLHRoYXQuX2Rlc2VsZWN0UmVnaXN0ZXJlZFBhcmFtZXRlcihjaGFubmVsLG9wdGlvbnMudGltZSl9KSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLmluY3JlbWVudFJlZ2lzdGVyZWRQYXJhbWV0ZXI9ZnVuY3Rpb24ocGFyYW1ldGVyLGNoYW5uZWwsb3B0aW9ucyl7dmFyIHRoYXQ9dGhpcztpZihvcHRpb25zPW9wdGlvbnN8fHt9LCFBcnJheS5pc0FycmF5KHBhcmFtZXRlcikpe2lmKCF3bS5NSURJX1JFR0lTVEVSRURfUEFSQU1FVEVSW3BhcmFtZXRlcl0pdGhyb3cgbmV3IEVycm9yKFwiVGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaXMgbm90IGF2YWlsYWJsZS5cIik7cGFyYW1ldGVyPXdtLk1JRElfUkVHSVNURVJFRF9QQVJBTUVURVJbcGFyYW1ldGVyXX1yZXR1cm4gd20udG9NSURJQ2hhbm5lbHMoY2hhbm5lbCkuZm9yRWFjaChmdW5jdGlvbihjaCl7dGhhdC5fc2VsZWN0UmVnaXN0ZXJlZFBhcmFtZXRlcihwYXJhbWV0ZXIsY2hhbm5lbCxvcHRpb25zLnRpbWUpLHRoYXQuc2VuZENvbnRyb2xDaGFuZ2UoOTYsMCxjaGFubmVsLHt0aW1lOm9wdGlvbnMudGltZX0pLHRoYXQuX2Rlc2VsZWN0UmVnaXN0ZXJlZFBhcmFtZXRlcihjaGFubmVsLG9wdGlvbnMudGltZSl9KSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLmRlY3JlbWVudFJlZ2lzdGVyZWRQYXJhbWV0ZXI9ZnVuY3Rpb24ocGFyYW1ldGVyLGNoYW5uZWwsb3B0aW9ucyl7aWYob3B0aW9ucz1vcHRpb25zfHx7fSwhQXJyYXkuaXNBcnJheShwYXJhbWV0ZXIpKXtpZighd20uTUlESV9SRUdJU1RFUkVEX1BBUkFNRVRFUltwYXJhbWV0ZXJdKXRocm93IG5ldyBUeXBlRXJyb3IoXCJUaGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpcyBub3QgYXZhaWxhYmxlLlwiKTtwYXJhbWV0ZXI9d20uTUlESV9SRUdJU1RFUkVEX1BBUkFNRVRFUltwYXJhbWV0ZXJdfXJldHVybiB3bS50b01JRElDaGFubmVscyhjaGFubmVsKS5mb3JFYWNoKGZ1bmN0aW9uKGNoKXt0aGlzLl9zZWxlY3RSZWdpc3RlcmVkUGFyYW1ldGVyKHBhcmFtZXRlcixjaGFubmVsLG9wdGlvbnMudGltZSksdGhpcy5zZW5kQ29udHJvbENoYW5nZSg5NywwLGNoYW5uZWwse3RpbWU6b3B0aW9ucy50aW1lfSksdGhpcy5fZGVzZWxlY3RSZWdpc3RlcmVkUGFyYW1ldGVyKGNoYW5uZWwsb3B0aW9ucy50aW1lKX0uYmluZCh0aGlzKSksdGhpc30sT3V0cHV0LnByb3RvdHlwZS5zZXRQaXRjaEJlbmRSYW5nZT1mdW5jdGlvbihzZW1pdG9uZXMsY2VudHMsY2hhbm5lbCxvcHRpb25zKXt2YXIgdGhhdD10aGlzO2lmKG9wdGlvbnM9b3B0aW9uc3x8e30sc2VtaXRvbmVzPU1hdGguZmxvb3Ioc2VtaXRvbmVzKXx8MCwhKHNlbWl0b25lcz49MCYmMTI3Pj1zZW1pdG9uZXMpKXRocm93IG5ldyBSYW5nZUVycm9yKFwiVGhlIHNlbWl0b25lcyB2YWx1ZSBtdXN0IGJlIGJldHdlZW4gMCBhbmQgMTI3XCIpO2lmKGNlbnRzPU1hdGguZmxvb3IoY2VudHMpfHwwLCEoY2VudHM+PTAmJjEyNz49Y2VudHMpKXRocm93IG5ldyBSYW5nZUVycm9yKFwiVGhlIGNlbnRzIHZhbHVlIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxMjdcIik7cmV0dXJuIHdtLnRvTUlESUNoYW5uZWxzKGNoYW5uZWwpLmZvckVhY2goZnVuY3Rpb24oY2gpe3RoYXQuc2V0UmVnaXN0ZXJlZFBhcmFtZXRlcihcInBpdGNoYmVuZHJhbmdlXCIsW3NlbWl0b25lcyxjZW50c10sY2hhbm5lbCx7dGltZTpvcHRpb25zLnRpbWV9KX0pLHRoaXN9LE91dHB1dC5wcm90b3R5cGUuc2V0TW9kdWxhdGlvblJhbmdlPWZ1bmN0aW9uKHNlbWl0b25lcyxjZW50cyxjaGFubmVsLG9wdGlvbnMpe3ZhciB0aGF0PXRoaXM7aWYob3B0aW9ucz1vcHRpb25zfHx7fSxzZW1pdG9uZXM9TWF0aC5mbG9vcihzZW1pdG9uZXMpfHwwLCEoc2VtaXRvbmVzPj0wJiYxMjc+PXNlbWl0b25lcykpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgc2VtaXRvbmVzIHZhbHVlIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxMjdcIik7aWYoY2VudHM9TWF0aC5mbG9vcihjZW50cyl8fDAsIShjZW50cz49MCYmMTI3Pj1jZW50cykpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgY2VudHMgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEyN1wiKTtyZXR1cm4gd20udG9NSURJQ2hhbm5lbHMoY2hhbm5lbCkuZm9yRWFjaChmdW5jdGlvbihjaCl7dGhhdC5zZXRSZWdpc3RlcmVkUGFyYW1ldGVyKFwibW9kdWxhdGlvbnJhbmdlXCIsW3NlbWl0b25lcyxjZW50c10sY2hhbm5lbCx7dGltZTpvcHRpb25zLnRpbWV9KX0pLHRoaXN9LE91dHB1dC5wcm90b3R5cGUuc2V0TWFzdGVyVHVuaW5nPWZ1bmN0aW9uKHZhbHVlLGNoYW5uZWwsb3B0aW9ucyl7dmFyIHRoYXQ9dGhpcztpZihvcHRpb25zPW9wdGlvbnN8fHt9LHZhbHVlPXBhcnNlRmxvYXQodmFsdWUpfHwwLC02NT49dmFsdWV8fHZhbHVlPj02NCl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlRoZSB2YWx1ZSBtdXN0IGJlIGEgZGVjaW1hbCBudW1iZXIgbGFyZ2VyIHRoYW4gLTY1IGFuZCBzbWFsbGVyIHRoYW4gNjQuXCIpO3ZhciBjb2Fyc2U9TWF0aC5mbG9vcih2YWx1ZSkrNjQsZmluZT12YWx1ZS1NYXRoLmZsb29yKHZhbHVlKTtmaW5lPU1hdGgucm91bmQoKGZpbmUrMSkvMioxNjM4Myk7dmFyIG1zYj1maW5lPj43JjEyNyxsc2I9MTI3JmZpbmU7cmV0dXJuIHdtLnRvTUlESUNoYW5uZWxzKGNoYW5uZWwpLmZvckVhY2goZnVuY3Rpb24oY2gpe3RoYXQuc2V0UmVnaXN0ZXJlZFBhcmFtZXRlcihcImNoYW5uZWxjb2Fyc2V0dW5pbmdcIixjb2Fyc2UsY2hhbm5lbCx7dGltZTpvcHRpb25zLnRpbWV9KSx0aGF0LnNldFJlZ2lzdGVyZWRQYXJhbWV0ZXIoXCJjaGFubmVsZmluZXR1bmluZ1wiLFttc2IsbHNiXSxjaGFubmVsLHt0aW1lOm9wdGlvbnMudGltZX0pfSksdGhpc30sT3V0cHV0LnByb3RvdHlwZS5zZXRUdW5pbmdQcm9ncmFtPWZ1bmN0aW9uKHZhbHVlLGNoYW5uZWwsb3B0aW9ucyl7dmFyIHRoYXQ9dGhpcztpZihvcHRpb25zPW9wdGlvbnN8fHt9LHZhbHVlPU1hdGguZmxvb3IodmFsdWUpLCEodmFsdWU+PTAmJjEyNz49dmFsdWUpKXRocm93IG5ldyBSYW5nZUVycm9yKFwiVGhlIHByb2dyYW0gdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEyN1wiKTtyZXR1cm4gd20udG9NSURJQ2hhbm5lbHMoY2hhbm5lbCkuZm9yRWFjaChmdW5jdGlvbihjaCl7dGhhdC5zZXRSZWdpc3RlcmVkUGFyYW1ldGVyKFwidHVuaW5ncHJvZ3JhbVwiLHZhbHVlLGNoYW5uZWwse3RpbWU6b3B0aW9ucy50aW1lfSl9KSx0aGlzfSxPdXRwdXQucHJvdG90eXBlLnNldFR1bmluZ0Jhbms9ZnVuY3Rpb24odmFsdWUsY2hhbm5lbCxvcHRpb25zKXt2YXIgdGhhdD10aGlzO2lmKG9wdGlvbnM9b3B0aW9uc3x8e30sdmFsdWU9TWF0aC5mbG9vcih2YWx1ZSl8fDAsISh2YWx1ZT49MCYmMTI3Pj12YWx1ZSkpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgYmFuayB2YWx1ZSBtdXN0IGJlIGJldHdlZW4gMCBhbmQgMTI3XCIpO3JldHVybiB3bS50b01JRElDaGFubmVscyhjaGFubmVsKS5mb3JFYWNoKGZ1bmN0aW9uKGNoKXt0aGF0LnNldFJlZ2lzdGVyZWRQYXJhbWV0ZXIoXCJ0dW5pbmdiYW5rXCIsdmFsdWUsY2hhbm5lbCx7dGltZTpvcHRpb25zLnRpbWV9KX0pLHRoaXN9LE91dHB1dC5wcm90b3R5cGUuc2VuZENoYW5uZWxNb2RlPWZ1bmN0aW9uKGNvbW1hbmQsdmFsdWUsY2hhbm5lbCxvcHRpb25zKXtpZihvcHRpb25zPW9wdGlvbnN8fHt9LFwic3RyaW5nXCI9PXR5cGVvZiBjb21tYW5kKXtpZihjb21tYW5kPXdtLk1JRElfQ0hBTk5FTF9NT0RFX01FU1NBR0VTW2NvbW1hbmRdLCFjb21tYW5kKXRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGNoYW5uZWwgbW9kZSBtZXNzYWdlIG5hbWUuXCIpfWVsc2UgaWYoY29tbWFuZD1NYXRoLmZsb29yKGNvbW1hbmQpLCEoY29tbWFuZD49MTIwJiYxMjc+PWNvbW1hbmQpKXRocm93IG5ldyBSYW5nZUVycm9yKFwiQ2hhbm5lbCBtb2RlIG51bWVyaWNhbCBpZGVudGlmaWVycyBtdXN0IGJlIGJldHdlZW4gMTIwIGFuZCAxMjcuXCIpO2lmKHZhbHVlPU1hdGguZmxvb3IodmFsdWUpfHwwLDA+dmFsdWV8fHZhbHVlPjEyNyl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlZhbHVlIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDAgYW5kIDEyNy5cIik7cmV0dXJuIHdtLnRvTUlESUNoYW5uZWxzKGNoYW5uZWwpLmZvckVhY2goZnVuY3Rpb24oY2gpe3RoaXMuc2VuZCgod20uTUlESV9DSEFOTkVMX01FU1NBR0VTLmNoYW5uZWxtb2RlPDw0KSsoY2gtMSksW2NvbW1hbmQsdmFsdWVdLHRoaXMuX3BhcnNlVGltZVBhcmFtZXRlcihvcHRpb25zLnRpbWUpKX0uYmluZCh0aGlzKSksdGhpc30sT3V0cHV0LnByb3RvdHlwZS5zZW5kUHJvZ3JhbUNoYW5nZT1mdW5jdGlvbihwcm9ncmFtLGNoYW5uZWwsb3B0aW9ucyl7XG52YXIgdGhhdD10aGlzO2lmKG9wdGlvbnM9b3B0aW9uc3x8e30scHJvZ3JhbT1NYXRoLmZsb29yKHByb2dyYW0pLGlzTmFOKHByb2dyYW0pfHwwPnByb2dyYW18fHByb2dyYW0+MTI3KXRocm93IG5ldyBSYW5nZUVycm9yKFwiUHJvZ3JhbSBudW1iZXJzIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxMjcuXCIpO3JldHVybiB3bS50b01JRElDaGFubmVscyhjaGFubmVsKS5mb3JFYWNoKGZ1bmN0aW9uKGNoKXt0aGF0LnNlbmQoKHdtLk1JRElfQ0hBTk5FTF9NRVNTQUdFUy5wcm9ncmFtY2hhbmdlPDw0KSsoY2gtMSksW3Byb2dyYW1dLHRoYXQuX3BhcnNlVGltZVBhcmFtZXRlcihvcHRpb25zLnRpbWUpKX0pLHRoaXN9LE91dHB1dC5wcm90b3R5cGUuc2VuZENoYW5uZWxBZnRlcnRvdWNoPWZ1bmN0aW9uKHByZXNzdXJlLGNoYW5uZWwsb3B0aW9ucyl7dmFyIHRoYXQ9dGhpcztvcHRpb25zPW9wdGlvbnN8fHt9LHByZXNzdXJlPXBhcnNlRmxvYXQocHJlc3N1cmUpLChpc05hTihwcmVzc3VyZSl8fDA+cHJlc3N1cmV8fHByZXNzdXJlPjEpJiYocHJlc3N1cmU9LjUpO3ZhciBuUHJlc3N1cmU9TWF0aC5yb3VuZCgxMjcqcHJlc3N1cmUpO3JldHVybiB3bS50b01JRElDaGFubmVscyhjaGFubmVsKS5mb3JFYWNoKGZ1bmN0aW9uKGNoKXt0aGF0LnNlbmQoKHdtLk1JRElfQ0hBTk5FTF9NRVNTQUdFUy5jaGFubmVsYWZ0ZXJ0b3VjaDw8NCkrKGNoLTEpLFtuUHJlc3N1cmVdLHRoYXQuX3BhcnNlVGltZVBhcmFtZXRlcihvcHRpb25zLnRpbWUpKX0pLHRoaXN9LE91dHB1dC5wcm90b3R5cGUuc2VuZFBpdGNoQmVuZD1mdW5jdGlvbihiZW5kLGNoYW5uZWwsb3B0aW9ucyl7dmFyIHRoYXQ9dGhpcztpZihvcHRpb25zPW9wdGlvbnN8fHt9LGlzTmFOKGJlbmQpfHwtMT5iZW5kfHxiZW5kPjEpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJQaXRjaCBiZW5kIHZhbHVlIG11c3QgYmUgYmV0d2VlbiAtMSBhbmQgMS5cIik7dmFyIG5MZXZlbD1NYXRoLnJvdW5kKChiZW5kKzEpLzIqMTYzODMpLG1zYj1uTGV2ZWw+PjcmMTI3LGxzYj0xMjcmbkxldmVsO3JldHVybiB3bS50b01JRElDaGFubmVscyhjaGFubmVsKS5mb3JFYWNoKGZ1bmN0aW9uKGNoKXt0aGF0LnNlbmQoKHdtLk1JRElfQ0hBTk5FTF9NRVNTQUdFUy5waXRjaGJlbmQ8PDQpKyhjaC0xKSxbbHNiLG1zYl0sdGhhdC5fcGFyc2VUaW1lUGFyYW1ldGVyKG9wdGlvbnMudGltZSkpfSksdGhpc30sT3V0cHV0LnByb3RvdHlwZS5fcGFyc2VUaW1lUGFyYW1ldGVyPWZ1bmN0aW9uKHRpbWUpe3ZhciBwYXJzZWQsdmFsdWU7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIHRpbWUmJlwiK1wiPT09dGltZS5zdWJzdHJpbmcoMCwxKT8ocGFyc2VkPXBhcnNlRmxvYXQodGltZSkscGFyc2VkJiZwYXJzZWQ+MCYmKHZhbHVlPXdtLnRpbWUrcGFyc2VkKSk6KHBhcnNlZD1wYXJzZUZsb2F0KHRpbWUpLHBhcnNlZD53bS50aW1lJiYodmFsdWU9cGFyc2VkKSksdmFsdWV9LE91dHB1dC5wcm90b3R5cGUuX2NvbnZlcnROb3RlVG9BcnJheT1mdW5jdGlvbihub3RlKXt2YXIgbm90ZXM9W107cmV0dXJuIEFycmF5LmlzQXJyYXkobm90ZSl8fChub3RlPVtub3RlXSksbm90ZS5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0pe25vdGVzLnB1c2god20uZ3Vlc3NOb3RlTnVtYmVyKGl0ZW0pKX0pLG5vdGVzfSxcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJlwib2JqZWN0XCI9PXR5cGVvZiBkZWZpbmUuYW1kP2RlZmluZShbXSxmdW5jdGlvbigpe3JldHVybiB3bX0pOlwidW5kZWZpbmVkXCIhPXR5cGVvZiBtb2R1bGUmJm1vZHVsZS5leHBvcnRzP21vZHVsZS5leHBvcnRzPXdtOnNjb3BlLldlYk1pZGl8fChzY29wZS5XZWJNaWRpPXdtKX0odGhpcyk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3dlYm1pZGkvd2VibWlkaS5taW4uanNcbi8vIG1vZHVsZSBpZCA9IDE1NVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xyXG5cdHRocm93IG5ldyBFcnJvcihcImRlZmluZSBjYW5ub3QgYmUgdXNlZCBpbmRpcmVjdFwiKTtcclxufTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gKHdlYnBhY2spL2J1aWxkaW4vYW1kLWRlZmluZS5qc1xuLy8gbW9kdWxlIGlkID0gMTU2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qIGdsb2JhbHMgX193ZWJwYWNrX2FtZF9vcHRpb25zX18gKi9cclxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfYW1kX29wdGlvbnNfXztcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gKHdlYnBhY2spL2J1aWxkaW4vYW1kLW9wdGlvbnMuanNcbi8vIG1vZHVsZSBpZCA9IDE1N1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiAoaWdub3JlZCkgKi9cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyB1dGlsIChpZ25vcmVkKVxuLy8gbW9kdWxlIGlkID0gMTU4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=
\ No newline at end of file @@ -70,7 +70,7 @@ </body> <script> var s = document.createElement('script'); - s.setAttribute('src','bundle.js?' + Date.now()); + s.setAttribute('src', window.location.href.match('asdf') ? './dist/index.js' : './bundle.js?' + Date.now()); document.body.appendChild(s) </script> </html> diff --git a/package-lock.json b/package-lock.json index 5851769..41cd591 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "inequality", + "name": "gun-violence", "version": "1.0.0", "lockfileVersion": 1, "requires": true, @@ -37,6 +37,11 @@ "json-stable-stringify": "^1.0.1" } }, + "ajv-errors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.0.tgz", + "integrity": "sha1-7PAh+hCP0X37Xms4Py3SM+Mf/Fk=" + }, "ajv-keywords": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", @@ -57,14 +62,12 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, "anymatch": { "version": "1.3.2", @@ -76,6 +79,11 @@ "normalize-path": "^2.0.0" } }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, "arr-diff": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", @@ -136,7 +144,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, "requires": { "chalk": "^1.1.3", "esutils": "^2.0.2", @@ -296,6 +303,48 @@ "babel-types": "^6.24.1" } }, + "babel-helper-builder-react-jsx": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", + "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=", + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "esutils": "^2.0.2" + }, + "dependencies": { + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + } + } + }, "babel-helper-call-delegate": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", @@ -371,7 +420,6 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "dev": true, "requires": { "babel-helper-get-function-arity": "^6.24.1", "babel-runtime": "^6.22.0", @@ -384,7 +432,6 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "dev": true, "requires": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" @@ -509,7 +556,6 @@ "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, "requires": { "babel-runtime": "^6.22.0" } @@ -529,12 +575,27 @@ "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", "dev": true }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=" + }, "babel-plugin-syntax-exponentiation-operator": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", "dev": true }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "http://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" + }, "babel-plugin-syntax-trailing-function-commas": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", @@ -552,6 +613,17 @@ "babel-runtime": "^6.22.0" } }, + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, "babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", @@ -869,6 +941,41 @@ "babel-runtime": "^6.22.0" } }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + }, + "dependencies": { + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } + } + }, + "babel-plugin-transform-react-jsx": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", + "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", + "requires": { + "babel-helper-builder-react-jsx": "^6.24.1", + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, "babel-plugin-transform-regenerator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz", @@ -878,6 +985,14 @@ "regenerator-transform": "0.9.11" } }, + "babel-plugin-transform-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", + "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, "babel-plugin-transform-strict-mode": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", @@ -1001,7 +1116,6 @@ "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", - "dev": true, "requires": { "core-js": "^2.4.0", "regenerator-runtime": "^0.10.0" @@ -1011,7 +1125,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, "requires": { "babel-runtime": "^6.26.0", "babel-traverse": "^6.26.0", @@ -1024,7 +1137,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, "requires": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" @@ -1034,7 +1146,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, "requires": { "babel-runtime": "^6.26.0", "esutils": "^2.0.2", @@ -1045,14 +1156,12 @@ "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" } } }, @@ -1060,7 +1169,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, "requires": { "babel-code-frame": "^6.26.0", "babel-messages": "^6.23.0", @@ -1077,7 +1185,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, "requires": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" @@ -1087,7 +1194,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, "requires": { "babel-runtime": "^6.26.0", "esutils": "^2.0.2", @@ -1098,14 +1204,12 @@ "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" } } }, @@ -1113,7 +1217,6 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.24.1.tgz", "integrity": "sha1-oTaHncFbNga9oNkMH8dDBML/CXU=", - "dev": true, "requires": { "babel-runtime": "^6.22.0", "esutils": "^2.0.2", @@ -1124,14 +1227,12 @@ "babylon": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" }, "balanced-match": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", - "dev": true + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" }, "base64-js": { "version": "1.2.0", @@ -1151,6 +1252,11 @@ "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", "dev": true }, + "bluebird": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", + "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==" + }, "bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", @@ -1161,7 +1267,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", - "dev": true, "requires": { "balanced-match": "^0.4.1", "concat-map": "0.0.1" @@ -1274,11 +1379,15 @@ "isarray": "^1.0.0" } }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, "buffer-shims": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", - "dev": true + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" }, "buffer-xor": { "version": "1.0.3", @@ -1298,6 +1407,34 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, + "cacache": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.2.0.tgz", + "integrity": "sha512-IFWl6lfK6wSeYCHUXh+N1lY72UDrpyrYQJNIVQf48paDuWbv5RbAtJYf/4gUQFObTCHZwdZ5sI8Iw7nqwP6nlQ==", + "requires": { + "bluebird": "^3.5.1", + "chownr": "^1.0.1", + "figgy-pudding": "^3.1.0", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "lru-cache": "^4.1.3", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.2", + "ssri": "^6.0.0", + "unique-filename": "^1.1.0", + "y18n": "^4.0.0" + }, + "dependencies": { + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + } + } + }, "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", @@ -1324,7 +1461,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", @@ -1350,6 +1486,11 @@ "readdirp": "^2.0.0" } }, + "chownr": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" + }, "cipher-base": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.3.tgz", @@ -1382,17 +1523,31 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } }, "console-browserify": { "version": "1.1.0", @@ -1415,17 +1570,28 @@ "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", "dev": true }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, "core-js": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", - "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=", - "dev": true + "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=" }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "create-ecdh": { "version": "4.0.0", @@ -1477,34 +1643,15 @@ "randombytes": "^2.0.0" } }, - "csv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/csv/-/csv-3.1.0.tgz", - "integrity": "sha512-SfnePMkhjljB7ehvubZESGjgrnM7V/gBe5ubZWKxeKwgmTl/HtVCdfSaGRgH/i/vG7qJaSLMpP0krNbAuunRBg==", - "requires": { - "csv-generate": "^2.0.2", - "csv-parse": "^2.4.0", - "csv-stringify": "^3.0.0", - "stream-transform": "^1.0.2" - } - }, - "csv-generate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-2.1.0.tgz", - "integrity": "sha512-avXXdQMta14DhePrX3yvzJHV5VEAhJQwBCwgqcZE7xyNTYGpxcUxmYvOSKQw+CisAjdpfn6/ZUNEJa2W6jDzNg==" - }, "csv-parse": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-2.5.0.tgz", "integrity": "sha512-4OcjOJQByI0YDU5COYw9HAqjo8/MOLLmT9EKyMCXUzgvh30vS1SlMK+Ho84IH5exN44cSnrYecw/7Zpu2m4lkA==" }, - "csv-stringify": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-3.1.1.tgz", - "integrity": "sha512-Ni9r/BdQM2cGnWzwAP09zp12LVOAMHLJ86azNHGC7s4OUo2WidGfcM3QwYEjD8c4ELCL/a4AzfIsVCzroeys+g==", - "requires": { - "lodash.get": "~4.4.2" - } + "cyclist": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=" }, "date-now": { "version": "0.1.4", @@ -1516,7 +1663,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -1563,6 +1709,17 @@ "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", "dev": true }, + "duplexify": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", + "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==", + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, "electron-to-chromium": { "version": "1.3.56", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.56.tgz", @@ -1590,6 +1747,14 @@ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "dev": true }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, "enhanced-resolve": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.1.0.tgz", @@ -1623,14 +1788,12 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, "events": { "version": "1.1.1", @@ -1674,6 +1837,21 @@ "is-extglob": "^1.0.0" } }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" + }, "file-saver": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.8.tgz", @@ -1719,6 +1897,15 @@ "pinkie-promise": "^2.0.0" } }, + "flush-write-stream": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", + "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -1734,6 +1921,31 @@ "for-in": "^1.0.1" } }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, "fsevents": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", @@ -2269,6 +2481,29 @@ "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", "dev": true }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, "glob-base": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", @@ -2291,20 +2526,17 @@ "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2363,17 +2595,35 @@ "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", "dev": true }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", "dev": true }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "interpret": { "version": "1.0.3", @@ -2385,7 +2635,6 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, "requires": { "loose-envify": "^1.0.0" } @@ -2510,8 +2759,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isobject": { "version": "2.1.0", @@ -2525,8 +2773,7 @@ "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" }, "jsesc": { "version": "1.3.0", @@ -2540,6 +2787,11 @@ "integrity": "sha1-i6oTZaYy9Yo8RtIBdfxgAsluN94=", "dev": true }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "json-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", @@ -2615,16 +2867,26 @@ "json5": "^0.5.0" } }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + } + } + }, "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" }, "longest": { "version": "1.0.1", @@ -2636,11 +2898,34 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, "math-random": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", @@ -2720,23 +3005,50 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" } }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nan": { "version": "2.10.0", @@ -2837,6 +3149,14 @@ "is-extendable": "^0.1.1" } }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, "os-browserify": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", @@ -2864,12 +3184,43 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "p-limit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", + "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==" + }, "pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", "dev": true }, + "parallel-transform": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", + "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, "parse-asn1": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", @@ -2922,8 +3273,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-type": { "version": "1.1.0", @@ -2996,8 +3346,12 @@ "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" }, "prr": { "version": "0.0.0", @@ -3005,6 +3359,11 @@ "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", "dev": true }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, "public-encrypt": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", @@ -3018,6 +3377,36 @@ "randombytes": "^2.0.1" } }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -3092,7 +3481,6 @@ "version": "2.2.9", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", - "dev": true, "requires": { "buffer-shims": "~1.0.0", "core-util-is": "~1.0.0", @@ -3124,8 +3512,7 @@ "regenerator-runtime": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz", - "integrity": "sha1-jENnqQS1HqYqkIrDEL+Z/5CoKj4=", - "dev": true + "integrity": "sha1-jENnqQS1HqYqkIrDEL+Z/5CoKj4=" }, "regenerator-transform": { "version": "0.9.11", @@ -3229,18 +3616,67 @@ "align-text": "^0.1.1" } }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "^7.0.5" + } + }, "ripemd160": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz", "integrity": "sha1-k6S71JQrxXS2mo+lfHHeEOzKfW4=", "dev": true }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "requires": { + "aproba": "^1.1.1" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "dependencies": { + "ajv": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz", + "integrity": "sha512-4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", + "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=" + } + } + }, "semver": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true }, + "serialize-javascript": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz", + "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==" + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -3316,6 +3752,14 @@ "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", "dev": true }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "requires": { + "figgy-pudding": "^3.5.1" + } + }, "stream-browserify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", @@ -3326,6 +3770,15 @@ "readable-stream": "^2.0.2" } }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, "stream-http": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.0.tgz", @@ -3339,10 +3792,10 @@ "xtend": "^4.0.0" } }, - "stream-transform": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-1.0.2.tgz", - "integrity": "sha512-LNcZSF01PZ+bM0OqwPY7UHPiKoxSmLGHAcqakvh01DCU98ONEslLORdyBPdmTqjTpZSfCiaYLV4sci9y5M47oA==" + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" }, "string-width": { "version": "1.0.2", @@ -3359,7 +3812,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", - "dev": true, "requires": { "buffer-shims": "~1.0.0" } @@ -3368,7 +3820,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3385,8 +3836,7 @@ "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" }, "tapable": { "version": "0.2.6", @@ -3394,6 +3844,15 @@ "integrity": "sha1-IGvo4YiGC1FEJTdebxrom/sB/Y0=", "dev": true }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + }, "timers-browserify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.2.tgz", @@ -3412,8 +3871,7 @@ "to-fast-properties": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.2.tgz", - "integrity": "sha1-8/XAw7pymafvmUJ+RGMyV63kMyA=", - "dev": true + "integrity": "sha1-8/XAw7pymafvmUJ+RGMyV63kMyA=" }, "tonal-midi": { "version": "0.69.7", @@ -3440,6 +3898,11 @@ "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "uglify-js": { "version": "2.8.22", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.22.tgz", @@ -3472,6 +3935,108 @@ "dev": true, "optional": true }, + "uglifyjs-webpack-plugin": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-2.0.1.tgz", + "integrity": "sha512-1HhCHkOB6wRCcv7htcz1QRPVbWPEY074RP9vzt/X0LF4xXm9l4YGd0qja7z88abDixQlnVwBjXsTBs+Xsn/eeQ==", + "requires": { + "cacache": "^11.2.0", + "find-cache-dir": "^2.0.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.4.0", + "source-map": "^0.6.1", + "uglify-js": "^3.0.0", + "webpack-sources": "^1.1.0", + "worker-farm": "^1.5.2" + }, + "dependencies": { + "find-cache-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz", + "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "requires": { + "find-up": "^3.0.0" + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "uglify-js": { + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", + "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + } + }, + "webpack-sources": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", + "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + } + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", + "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + } + } + }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", @@ -3510,8 +4075,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "validate-npm-package-license": { "version": "3.0.1", @@ -3633,6 +4197,29 @@ "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", "dev": true }, + "worker-farm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", + "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", + "requires": { + "errno": "~0.1.7" + }, + "dependencies": { + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "requires": { + "prr": "~1.0.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + } + } + }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", @@ -3643,11 +4230,15 @@ "strip-ansi": "^3.0.1" } }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "y18n": { "version": "3.2.1", @@ -3655,6 +4246,11 @@ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, "yargs": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", diff --git a/package.json b/package.json index c419281..a97b4d7 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,11 @@ "description": "", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "dev": "webpack-dev-server --config ./webpack.config.dev.js --hot --inline", + "deploy": "webpack --config ./webpack.config.prod.js && git add -A && git commit -am 'deploy bundle' && git push" }, "author": "", - "license": "UNLICENSED", + "license": "", "devDependencies": { "babel-core": "^6.26.3", "babel-loader": "^7.0.0", @@ -16,11 +17,16 @@ "webpack": "^2.4.1" }, "dependencies": { + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.26.0", + "babel-plugin-transform-react-jsx": "^6.24.1", + "babel-plugin-transform-runtime": "^6.23.0", "csv-parse": "^2.5.0", "file-saver": "^1.3.8", "midi-writer-js": "^1.5.2", "nexusui": "^2.0.0", "tone": "^0.12.80", + "uglifyjs-webpack-plugin": "^2.0.1", "webfontloader": "^1.6.27", "webmidi": "^2.2.0" } diff --git a/webpack.config.dev.js b/webpack.config.dev.js new file mode 100644 index 0000000..db04777 --- /dev/null +++ b/webpack.config.dev.js @@ -0,0 +1,63 @@ +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const CleanWebpackPlugin = require('clean-webpack-plugin'); +const webpack = require('webpack'); + +let path = require('path'); + +module.exports = { + entry: { + main: './client/index.js' + }, + output: { + path: path.resolve(__dirname, '/dist'), + filename: 'index.js' + }, + devServer: { + port: 9000, + headers: { + 'Access-Control-Allow-Origin': '*', + // 'Access-Control-Allow-Origin': 'http://rinkeby.infura.io' + }, + publicPath: '/dist/', + hot: true, + }, + devtool: 'inline-source-map', + plugins: [ + // new CleanWebpackPlugin(['dist']), + // new HtmlWebpackPlugin({ + // title: 'Meme Lordz', + // meta: { + // name: 'viewport', + // content: 'width=device-width,initial-scale=1.0' + // } + // }) + new webpack.HotModuleReplacementPlugin() + ], + module: { + rules: [ + { + test: /\.css$/, + use: ['style-loader', 'css-loader'] + }, + { + test: /\.js$/, + // include: path.resolve(__dirname, 'client'), + exclude: /(node_modules|bower_components|build)/, + use: { + loader: 'babel-loader', + options: { + presets: ['env'], + plugins: [ + require('babel-plugin-transform-runtime'), + require('babel-plugin-transform-es2015-arrow-functions'), + require('babel-plugin-transform-object-rest-spread'), + require('babel-plugin-transform-class-properties'), + require('babel-plugin-transform-react-jsx'), + require('react-hot-loader/babel') + ] + } + } + } + ] + } +}; diff --git a/webpack.config.prod.js b/webpack.config.prod.js new file mode 100644 index 0000000..e946072 --- /dev/null +++ b/webpack.config.prod.js @@ -0,0 +1,46 @@ +const webpack = require('webpack'); +const path = require('path'); +const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); +// const CleanWebpackPlugin = require('clean-webpack-plugin'); + +module.exports = { + entry: { + main: './client/index.js', + }, + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'index.js', + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + // new UglifyJsPlugin(), + new webpack.optimize.AggressiveMergingPlugin() + ], + devtool: 'inline-source-map', + module: { + rules: [ + { + test: /\.css$/, + use: ['style-loader', 'css-loader'] + }, + { + test: /\.js$/, + include: path.resolve(__dirname, 'client'), + exclude: /(node_modules|bower_components|build)/, + loader: 'babel-loader', + options: { + presets: ['env'], + plugins: [ + require('babel-plugin-transform-runtime'), + require('babel-plugin-transform-es2015-arrow-functions'), + require('babel-plugin-transform-object-rest-spread'), + require('babel-plugin-transform-class-properties'), + require('babel-plugin-transform-react-jsx'), + ] + } + } + ] + }, +}; |
